with one click
build-appkit-app
// Build or refactor an AppKit app feature on top of SwiftASB using explicit application, window, document, thread, and turn ownership with main-actor UI updates and clear runtime diagnostics.
// Build or refactor an AppKit app feature on top of SwiftASB using explicit application, window, document, thread, and turn ownership with main-actor UI updates and clear runtime diagnostics.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | build-appkit-app |
| description | Build or refactor an AppKit app feature on top of SwiftASB using explicit application, window, document, thread, and turn ownership with main-actor UI updates and clear runtime diagnostics. |
| license | Apache-2.0 |
| compatibility | Designed for Codex and compatible Agent Skills clients working with SwiftASB v1.3.1 or newer, Swift 6, SwiftPM, AppKit, Xcode, and local Codex app-server integrations. |
| metadata | {"owner":"gaelic-ghost","repo":"socket","package":"SwiftASB","category":"swiftasb-appkit"} |
| allowed-tools | Read Bash(rg:*) Bash(git:*) Bash(swift:*) Bash(xcodebuild:*) |
Help an AppKit app use SwiftASB to start local Codex work, show thread and turn progress, answer approvals or elicitation requests, list stored threads, archive or unarchive stored threads, inspect app-server-owned worktree, selected Git status, project identity, thread source, filesystem/config/extension/MCP-resource/workspace facts, observe SwiftASB-owned feature operations, and expose recent history from app-owned controllers or models.
The real job is to keep AppKit's app, window, document, and view-controller lifetimes in charge of UI behavior while SwiftASB owns the local Codex subprocess, app-wide library companion, stable worktree groups, repository/worktree filters, selected-worktree Git status, project identity and thread-source facts, app-server-owned worktree snapshots, app-server-routed filesystem/config/extension/MCP-resource reads, workspace permission facts, feature policy, feature-operation events, typed thread and turn handles, events, request responses, diagnostics, and local history.
Before implementing or proposing AppKit structure, read the relevant Apple documentation through Apple Dev Skills or official Apple docs.
Minimum rules to rely on:
NSApplication manages the app's main event loop, windows, menus, events, and app-wide resources.NSApplicationDelegate handles app lifecycle callbacks such as launch, termination, activation, reopen, and window-update behavior.NSWindowController manages a window and often participates in document-based ownership.NSViewController manages a view and has lifecycle methods suitable for window content.NSWindow and many delegate callbacks are main-actor UI surfaces; update AppKit views and controllers from the main actor.Authoritative docs:
swiftasb:choose-integration-shape selects an AppKit, document, window-controller, or menu-bar app shape.Verify current SwiftASB docs and public API before editing:
README.mdSources/SwiftASB/SwiftASB.docc/GettingStartedWithSwiftASB.mdSources/SwiftASB/SwiftASB.docc/HandlingTurnProgressAndApprovals.mdSources/SwiftASB/SwiftASB.docc/ReadingDiagnosticsAndHistory.mdSources/SwiftASB/SwiftASB.docc/ThreadHistoryAndObservables.mdSources/SwiftASB/SwiftASB.docc/CodexFS.mdSources/SwiftASB/SwiftASB.docc/CodexConfig.mdSources/SwiftASB/SwiftASB.docc/CodexExtensions.mdSources/SwiftASB/SwiftASB.docc/CodexWorkspace.mdSources/SwiftASB/SwiftASB.docc/FeaturePermissionPolicy.mdSources/SwiftASB/SwiftASB.docc/ThreadManagement.mdSources/SwiftASB/Public/CodexAppServer+Library.swiftSources/SwiftASB/Public/CodexAppServer+LoadedThreads.swiftSources/SwiftASB/Public/CodexAppServer+CodexExtensions.swiftSources/SwiftASB/Public/CodexAppServer+MCP.swiftSources/SwiftASB/Public/CodexFS.swiftSources/SwiftASB/Public/CodexConfig.swiftSources/SwiftASB/Public/CodexWorkspace.swiftSources/SwiftASB/Public/CodexAppServer+Bootstrap.swiftSources/SwiftASB/Public/CodexAppServer.swiftSources/SwiftASB/Public/CodexDiagnostics.swiftSources/SwiftASB/Public/CodexErrors.swiftSources/SwiftASB/Public/CodexThread.swiftSources/SwiftASB/Public/CodexThread+Dashboard.swiftSources/SwiftASB/Public/CodexTurnHandle.swiftAs of SwiftASB v1.3.1, AppKit-facing integrations should prefer:
CodexAppServer.start(_:) with CodexAppServer.StartupRequest for normal one-call subprocess startup, compatibility validation, initialization, and typed CodexAppServerStartupError failuresCodexAppServer.start(), cliExecutableDiagnostics(), and initialize(_:) only when the app intentionally owns custom diagnostics, compatibility policy, or test setup before initializationCodexAppServer for subprocess ownership, diagnostics, stored-thread operations, MCP resource reads, model capability reads, MCP status reads, feature-operation-event streams, and hook diagnosticsCodexAppServer.makeLibrary(configuration:) for app-wide stored-thread lists, cwd or repository grouping, stable worktree groups, repository/worktree filters, selected worktree or repository context, selected-worktree Git status, library-local selection, CodexWorkspace.ProjectInfo project identity, CodexAppServer.ThreadSource source badges, and model/MCP/hook snapshots that refresh when app-server app/skill/MCP state changesCodexAppServer.fs, CodexAppServer.config, and CodexAppServer.extensions for app-server-owned file metadata, directory/file reads, file discovery with match metadata, effective config, app, skill, plugin, collaboration-mode inventory, plugin detail reads, and already-configured marketplace upgradesCodexAppServer.readMcpResource(_:) for app-wide or thread-scoped MCP resource contentsSwiftASBFeaturePolicy for feature-category defaults and host app authority, with gitObservability, extensionInventory, and extensionMaintenance enabled by default and mutation-oriented categories disabled until the app opts inCodexAppServer.featureOperationEvents() for human-readable SwiftASB-owned mutation records, such as marketplace maintenance attemptsCodexWorkspace for session cwd, app-server-owned worktree snapshots, project identity, Git repository facts, selected Git status snapshots, active permission profile, and runtime filesystem/network permission factsCodexThread for conversation-scoped turn creation, thread events, thread actions, archive/unarchive, thread goals, request responses, and local historyCodexTurnHandle for one active turn, including events, steering, interruption, request responses, minimap state, and completion handoffCodexThread.makeDashboard() and CodexTurnHandle.minimap as UI-friendly current-state mirrorsCodexAppServer.ThreadListQD, CodexFS.FileDiscoveryQD, CodexThread.HistoryWindowQD, CodexThread.RecentFilesQD, and CodexThread.RecentCommandsQD for repeatable sidebar, file-picker, inspector, and history intenthttps://github.com/gaelic-ghost/SwiftASB1.3.1 when using one-call startup with typed startup errors, app-wide library, stable worktree groups, repository/worktree filters, selected-worktree Git status, feature policy, feature-operation events, extension marketplace maintenance, project identity, thread source, filesystem match metadata, MCP resource reads, config warnings, extension inventory, workspace, query-descriptor, thread archive/unarchive, or recent-activity guidance; otherwise verify the support window in SwiftASB's READMESwiftASBCodexAppServer when one runtime serves many windowsCodexAppServer.Library when the UI needs stored-thread lists before a thread is selectedCodexThread when work belongs to one workspace or documentCodexTurnHandle while one turn is runningappServer.start(_:) for normal clients and the lower-level start() plus initialize(_:) sequence only for custom diagnostics or tests.appServer.fs, appServer.config, appServer.extensions, appServer.readMcpResource(_:), CodexWorkspace, and SwiftASBFeaturePolicy when inspectors, preferences, file pickers, MCP panes, or diagnostics need Codex-owned filesystem, config, plugin/skill/app, collaboration-mode, marketplace-maintenance, resource, worktree, selected Git status, project identity, thread source, permission facts, or feature-category choices.CodexTurnHandle or CodexThread.Prefer one AppKit-facing object that makes lifetime visible:
import AppKit
import SwiftASB
@MainActor
final class CodexWorkspaceWindowController: NSWindowController {
private let appServer: CodexAppServer
private var library: CodexAppServer.Library?
private var thread: CodexThread?
private var currentTurn: CodexTurnHandle?
@IBOutlet private var statusField: NSTextField!
init(appServer: CodexAppServer) {
self.appServer = appServer
super.init(window: nil)
}
required init?(coder: NSCoder) {
nil
}
func connect(workspacePath: String) {
Task { @MainActor in
do {
let session = try await appServer.start(
.init(
clientInfo: .init(
name: "ExampleApp",
title: "Example App",
version: "1.0.0"
)
)
)
_ = session.cliExecutableDiagnostics
thread = try await appServer.startThread(
.init(currentDirectoryPath: workspacePath)
)
library = try await appServer.makeLibrary(
configuration: .init(
sortedBy: .turnFinishedNewestFirst,
groupedBy: .repository,
query: .unarchived(limit: 30),
mcpServerStatusRequest: .init(detail: .toolsAndAuthOnly)
)
)
statusField.stringValue = "Codex is ready."
} catch {
statusField.stringValue = "SwiftASB could not start Codex: \(error)"
}
}
}
@IBAction func runSelectedTask(_ sender: Any?) {
guard let thread else {
statusField.stringValue = "SwiftASB cannot start a turn before a thread exists."
return
}
Task { @MainActor in
do {
let turn = try await thread.startTextTurn("Summarize the current workspace.")
currentTurn = turn
for try await event in turn.events {
if case .completed = event {
_ = try await turn.complete()
currentTurn = nil
statusField.stringValue = "Codex turn finished."
return
}
}
} catch {
currentTurn = nil
statusField.stringValue = "SwiftASB turn failed: \(error)"
}
}
}
@IBAction func interruptTurn(_ sender: Any?) {
Task { @MainActor in
do {
try await currentTurn?.interrupt()
statusField.stringValue = "Interrupt sent to Codex."
} catch {
statusField.stringValue = "SwiftASB could not interrupt the turn: \(error)"
}
}
}
}
Use this as a shape, not as a file to paste blindly. Match the app's actual nib/storyboard/programmatic-window setup, document model, and error UI.
CodexAppServerStartupError startup and compatibility failures before enabling menu or toolbar actions.CodexAppServer.Library for source lists, launchers, project browsers, stored-thread selection, selected-worktree Git status, project identity display, thread-source badges, app-wide model capabilities, MCP status, and hook diagnostics.CodexAppServer.fs and CodexFS.FileDiscoveryQD for sandbox-safe file pickers, metadata inspectors, directory browsers, file-byte previews, watches, highlighted matches, and ranking explanations.CodexAppServer.readMcpResource(_:) when the app needs to show text or blob resource contents advertised by a configured MCP server.CodexAppServer.config, CodexAppServer.extensions, and CodexWorkspace for preferences or diagnostics panes that show effective config, requirements, available apps/skills/plugins, collaboration modes, worktree snapshots, selected Git status, project identity, active profile, and filesystem/network permissions.SwiftASBFeaturePolicy to present feature-category toggles only when the app actually lets users change SwiftASB-owned authority. Read-only Git observability and extension inventory are enabled by default; stronger mutation categories should stay deliberate app choices.CodexAppServer.featureOperationEvents() when AppKit needs to show marketplace-upgrade results or future SwiftASB-owned mutation records in a status pane, log view, or inspector.CodexThread.archive() and CodexThread.unarchive() for archive UI actions when the app already owns the selected thread handle.CodexThread.readGoal(), setGoal(_:), clearGoal(), setName(_:), updateMetadata(gitInfo:), compactContext(), and rollbackLastTurns(_:) from explicit menu, toolbar, inspector, or document actions that already own the selected thread.dashboard and minimap state for activity views instead of replaying every raw event into controller-owned arrays.Use the repository's documented Xcode build and test path. For Xcode projects, do not assume SwiftPM validation is enough because scheme, target membership, entitlements, sandboxing, signing, and resources may be Xcode-owned.
Live Codex integration tests should be opt-in, isolated in temporary workspaces, and bounded by hard timeouts.
swiftasb:explain-swiftasb when the user needs adoption tradeoffs before implementation.swiftasb:choose-integration-shape when ownership or app shape is unclear.swiftasb:diagnose-integration when startup, turn, approval, MCP, diagnostics, or history behavior fails.apple-dev-skills:explore-apple-swift-docs for AppKit, SwiftUI, SwiftPM, or Observation documentation.CodexAppServer.CodexWire... models into AppKit controller or view state.CodexAppServerStartupError cases when mapping errors into AppKit status text.