Files
oai-swift/oAI/Models/AgentSkill.swift
T
runeandClaude Sonnet 5 bd686873c4 Update commercial licensing contact URL to oai.pm
Consolidates the mac.oai.pm subdomain references (introduced in the
PolyForm Noncommercial relicense) to the root oai.pm domain, across
the LICENSE file, README, and all Swift source file headers.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-15 11:33:53 +02:00

65 lines
2.5 KiB
Swift

//
// AgentSkill.swift
// oAI
//
// SKILL.md-style behavioral skills — markdown instruction files injected into the system prompt
//
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
// Copyright (C) 2026 Rune Olsen
//
// This file is part of oAI.
//
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
// You may use, study, modify, and share it for any noncommercial
// purpose. Commercial use — including selling oAI or any part of
// it, standalone or bundled into another product or service —
// requires a separate commercial license from the copyright holder.
//
// See the LICENSE file or
// <https://polyformproject.org/licenses/noncommercial/1.0.0> for
// the full license text. For commercial licensing, contact Rune
// Olsen via <https://oai.pm>.
import Foundation
struct AgentSkill: Codable, Identifiable {
var id: UUID
var name: String // display name, e.g. "Code Review"
var skillDescription: String // short summary shown in the list
var content: String // full markdown content (the actual instructions)
var isActive: Bool // when true, injected into the system prompt
var createdAt: Date
var updatedAt: Date
init(id: UUID = UUID(), name: String, skillDescription: String = "", content: String,
isActive: Bool = true, createdAt: Date = Date(), updatedAt: Date = Date()) {
self.id = id
self.name = name
self.skillDescription = skillDescription
self.content = content
self.isActive = isActive
self.createdAt = createdAt
self.updatedAt = updatedAt
}
/// Extract a brief description from the content if skillDescription is empty
var resolvedDescription: String {
guard skillDescription.isEmpty else { return skillDescription }
// Return first non-heading, non-empty line
for line in content.components(separatedBy: .newlines) {
let trimmed = line.trimmingCharacters(in: .whitespaces)
if !trimmed.isEmpty && !trimmed.hasPrefix("#") {
return String(trimmed.prefix(100))
}
}
return name
}
/// Matches the user's "2nd Brain" skill by name — there's no canonical skill ID,
/// so this is the only way to recognize it (used to gate the "always trust" bash setting).
var isSecondBrainSkill: Bool {
name.trimmingCharacters(in: .whitespacesAndNewlines).caseInsensitiveCompare("2nd Brain") == .orderedSame
}
}