Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Listen to the SwiftASB Codex apps promo clip:

### Status

SwiftASB is actively maintained and supported by Gale. Our current API is v1, and `v1.7.0` is the current and latest release.
SwiftASB is actively maintained and supported by Gale. Our current API is v1, and `v1.7.1` is the current and latest release.

### What This Project Is

Expand All @@ -38,7 +38,7 @@ I built SwiftASB because I saw so many others building and forking existing Apps
Add SwiftASB to your `Package.swift` dependencies:

```swift
.package(url: "https://github.com/gaelic-ghost/SwiftASB", from: "1.7.0"),
.package(url: "https://github.com/gaelic-ghost/SwiftASB", from: "1.7.1"),
```

Then add the library product to your target dependencies:
Expand All @@ -52,7 +52,7 @@ Check your Codex version:
```bash
codex --version
```
*Note: SwiftASB currently supports the latest reviewed Codex CLI minor release, `0.135.x`. This narrow reviewed window will be revised once the app-server schema stabilizes or Codex CLI reaches a v1.x.x release.*
*Note: SwiftASB currently supports the latest reviewed Codex CLI minor release, `0.137.x`. This narrow reviewed window will be revised once the app-server schema stabilizes or Codex CLI reaches a v1.x.x release.*

Add the Socket Marketplace to Codex and enable the SwiftASB Skills Plugin:

Expand Down
178 changes: 151 additions & 27 deletions ROADMAP.md

Large diffs are not rendered by default.

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions Sources/SwiftASB/Public/CodexAppServer+WireMapping.swift
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ extension CodexAppServer.ThreadStartRequest {
model: model,
modelProvider: modelProvider,
permissions: permissions?.wireValue,
persistExtendedHistory: nil,
personality: personality?.wireValue,
runtimeWorkspaceRoots: nil,
sandbox: sandboxMode?.wireValue,
Expand Down Expand Up @@ -226,6 +225,7 @@ extension CodexAppServer.TurnStartRequest {
additionalContext: nil,
approvalPolicy: approvalPolicy?.wireValue,
approvalsReviewer: approvalsReviewer?.wireValue,
clientUserMessageID: nil,
collaborationMode: collaborationMode?.wireValue,
cwd: currentDirectoryPath,
effort: effort?.wireValue,
Expand Down Expand Up @@ -920,7 +920,7 @@ extension CodexProtocolThreadTurnsSortDirection {
}
}

extension CodexWireSortDirection {
extension CodexWireRemoteControlClientsListOrder {
init(_ direction: CodexAppServer.ThreadTurnsSortDirection) {
switch direction {
case .asc:
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftASB/Public/CodexAppServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1675,7 +1675,7 @@ public actor CodexAppServer {
params: .init(
cursor: request.cursor,
limit: request.limit,
sortDirection: request.sortDirection.map(CodexWireSortDirection.init),
sortDirection: request.sortDirection.map(CodexWireRemoteControlClientsListOrder.init),
threadID: request.threadID,
turnID: request.turnID
)
Expand Down
9 changes: 8 additions & 1 deletion Sources/SwiftASB/Public/CodexConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public struct CodexConfig: Sendable {
public enum Kind: String, Sendable, Equatable {
case legacyManagedConfigTomlFromFile
case legacyManagedConfigTomlFromMdm
case enterpriseManaged
case mdm
case project
case sessionFlags
Expand All @@ -65,8 +66,10 @@ public struct CodexConfig: Sendable {
public let dotCodexFolder: String?
public let domain: String?
public let file: String?
public let id: String?
public let key: String?
public let kind: Kind
public let name: String?
}

/// Requirements policy currently visible to the app-server.
Expand Down Expand Up @@ -132,15 +135,19 @@ extension CodexConfig.LayerSource {
dotCodexFolder: wireValue.dotCodexFolder,
domain: wireValue.domain,
file: wireValue.file,
id: wireValue.id,
key: wireValue.key,
kind: .init(wireValue: wireValue.type)
kind: .init(wireValue: wireValue.type),
name: wireValue.name
)
}
}

extension CodexConfig.LayerSource.Kind {
init(wireValue: CodexWireConfigLayerSourceType) {
switch wireValue {
case .enterpriseManaged:
self = .enterpriseManaged
case .legacyManagedConfigTomlFromFile:
self = .legacyManagedConfigTomlFromFile
case .legacyManagedConfigTomlFromMdm:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ internal struct CodexCLIExecutableResolver {
internal let patch: Int

private static let regex = try! NSRegularExpression(pattern: #"(\d+)\.(\d+)\.(\d+)"#)
internal static let latestSupportedPublicRelease = Version(major: 0, minor: 135, patch: 0)
internal static let latestSupportedPublicRelease = Version(major: 0, minor: 137, patch: 0)

internal static var documentedWindowDescription: String {
let latest = latestSupportedPublicRelease
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,6 @@ struct CodexAppServerProtocolTests {
model: "gpt-5.4",
modelProvider: "openai",
permissions: ":workspace",
persistExtendedHistory: nil,
personality: .friendly,
runtimeWorkspaceRoots: nil,
sandbox: .workspaceWrite,
Expand Down Expand Up @@ -906,6 +905,7 @@ struct CodexAppServerProtocolTests {
additionalContext: nil,
approvalPolicy: .enumeration(.onFailure),
approvalsReviewer: .guardianSubagent,
clientUserMessageID: nil,
collaborationMode: .init(
mode: .plan,
settings: .init(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,13 +251,18 @@ extension CodexAppServerTests {

let snapshot = try await client.config.read(.init(currentDirectoryPath: "/tmp/project", includeLayers: true))
#expect(snapshot.config == .object(["model": .string("gpt-5.2"), "sandbox_mode": .string("workspace-write")]))
#expect(snapshot.layers?.count == 2)
#expect(snapshot.layers?.count == 3)
#expect(snapshot.layers?.first?.name.kind == .user)
#expect(snapshot.layers?[1].name.kind == .project)
#expect(snapshot.layers?[1].name.dotCodexFolder == "/tmp/project/.codex")
#expect(snapshot.layers?[1].disabledReason == "Project config is disabled for this fixture.")
#expect(snapshot.layers?[2].name.kind == .enterpriseManaged)
#expect(snapshot.layers?[2].name.id == "enterprise-layer-1")
#expect(snapshot.layers?[2].name.name == "Admin Defaults")
#expect(snapshot.origins["model"]?.name.file == "/Users/galew/.codex/config.toml")
#expect(snapshot.origins["sandbox_mode"]?.name.kind == .project)
#expect(snapshot.origins["review_model"]?.name.kind == .enterpriseManaged)
#expect(snapshot.origins["review_model"]?.name.name == "Admin Defaults")

let requirements = try await client.config.readRequirements()
#expect(requirements.requirements == .object([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,6 @@ extension CodexAppServerLiveIntegrationTests {
model: nil,
modelProvider: nil,
permissions: nil,
persistExtendedHistory: nil,
personality: nil,
runtimeWorkspaceRoots: nil,
sandbox: .readOnly,
Expand Down Expand Up @@ -357,6 +356,7 @@ extension CodexAppServerLiveIntegrationTests {
additionalContext: nil,
approvalPolicy: .enumeration(.untrusted),
approvalsReviewer: .user,
clientUserMessageID: nil,
collaborationMode: nil,
cwd: nil,
effort: nil,
Expand Down Expand Up @@ -519,7 +519,6 @@ extension CodexAppServerLiveIntegrationTests {
model: nil,
modelProvider: nil,
permissions: nil,
persistExtendedHistory: nil,
personality: nil,
runtimeWorkspaceRoots: nil,
sandbox: .readOnly,
Expand Down Expand Up @@ -547,6 +546,7 @@ extension CodexAppServerLiveIntegrationTests {
additionalContext: nil,
approvalPolicy: .enumeration(.untrusted),
approvalsReviewer: .user,
clientUserMessageID: nil,
collaborationMode: nil,
cwd: nil,
effort: nil,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ extension CodexAppServerLiveIntegrationTests {
model: nil,
modelProvider: nil,
permissions: nil,
persistExtendedHistory: nil,
personality: nil,
runtimeWorkspaceRoots: nil,
sandbox: .readOnly,
Expand Down Expand Up @@ -125,6 +124,7 @@ extension CodexAppServerLiveIntegrationTests {
additionalContext: nil,
approvalPolicy: .enumeration(.never),
approvalsReviewer: nil,
clientUserMessageID: nil,
collaborationMode: CodexWireCollaborationMode(
mode: .plan,
settings: CodexWireSettings(
Expand Down Expand Up @@ -285,7 +285,6 @@ extension CodexAppServerLiveIntegrationTests {
model: nil,
modelProvider: nil,
permissions: nil,
persistExtendedHistory: nil,
personality: nil,
runtimeWorkspaceRoots: nil,
sandbox: .readOnly,
Expand Down Expand Up @@ -313,6 +312,7 @@ extension CodexAppServerLiveIntegrationTests {
additionalContext: nil,
approvalPolicy: .enumeration(.never),
approvalsReviewer: nil,
clientUserMessageID: nil,
collaborationMode: nil,
cwd: nil,
effort: nil,
Expand Down Expand Up @@ -473,7 +473,6 @@ extension CodexAppServerLiveIntegrationTests {
model: "mock-model",
modelProvider: nil,
permissions: nil,
persistExtendedHistory: nil,
personality: nil,
runtimeWorkspaceRoots: nil,
sandbox: .readOnly,
Expand Down Expand Up @@ -501,6 +500,7 @@ extension CodexAppServerLiveIntegrationTests {
additionalContext: nil,
approvalPolicy: .enumeration(.onRequest),
approvalsReviewer: .user,
clientUserMessageID: nil,
collaborationMode: nil,
cwd: nil,
effort: nil,
Expand Down Expand Up @@ -554,6 +554,7 @@ extension CodexAppServerLiveIntegrationTests {
additionalContext: nil,
approvalPolicy: .enumeration(.onRequest),
approvalsReviewer: .user,
clientUserMessageID: nil,
collaborationMode: nil,
cwd: nil,
effort: nil,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ struct CodexAppServerLiveIntegrationTests {
model: nil,
modelProvider: nil,
permissions: nil,
persistExtendedHistory: nil,
personality: nil,
runtimeWorkspaceRoots: nil,
sandbox: .workspaceWrite,
Expand Down Expand Up @@ -201,7 +200,7 @@ struct CodexAppServerLiveIntegrationTests {
let diagnostics = try await client.cliExecutableDiagnostics()
#expect(diagnostics.resolvedExecutablePath == harness.codexExecutableURL.path)
#expect(diagnostics.versionString.contains("codex-cli"))
#expect(diagnostics.compatibility == .supported(documentedWindow: "0.135.x"))
#expect(diagnostics.compatibility == .supported(documentedWindow: "0.137.x"))

await client.stop()
} catch {
Expand Down Expand Up @@ -296,7 +295,6 @@ struct CodexAppServerLiveIntegrationTests {
model: nil,
modelProvider: nil,
permissions: nil,
persistExtendedHistory: nil,
personality: nil,
runtimeWorkspaceRoots: nil,
sandbox: .workspaceWrite,
Expand Down Expand Up @@ -324,6 +322,7 @@ struct CodexAppServerLiveIntegrationTests {
additionalContext: nil,
approvalPolicy: .enumeration(.never),
approvalsReviewer: nil,
clientUserMessageID: nil,
collaborationMode: nil,
cwd: nil,
effort: nil,
Expand Down
19 changes: 19 additions & 0 deletions Tests/SwiftASBTests/Public/CodexAppServerTestSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,17 @@ actor FakeCodexAppServerTransport: CodexAppServerTransporting {
],
"version": "2",
],
[
"config": [
"review_model": "gpt-5.5",
],
"name": [
"type": "enterpriseManaged",
"id": "enterprise-layer-1",
"name": "Admin Defaults",
],
"version": "3",
],
],
"origins": [
"model": [
Expand All @@ -718,6 +729,14 @@ actor FakeCodexAppServerTransport: CodexAppServerTransporting {
],
"version": "2",
],
"review_model": [
"name": [
"type": "enterpriseManaged",
"id": "enterprise-layer-1",
"name": "Admin Defaults",
],
"version": "3",
],
],
]
)
Expand Down
20 changes: 10 additions & 10 deletions Tests/SwiftASBTests/Public/CodexAppServerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ struct CodexAppServerTests {
launchArgumentsPrefix: [],
resolvedExecutableURL: URL(fileURLWithPath: "/opt/homebrew/bin/codex"),
source: .homebrewAppleSilicon,
versionString: "codex-cli 0.135.0",
compatibility: .supported(documentedWindow: "0.135.x")
versionString: "codex-cli 0.137.0",
compatibility: .supported(documentedWindow: "0.137.x")
)
)
let client = CodexAppServer(transport: transport)
Expand All @@ -94,8 +94,8 @@ struct CodexAppServerTests {
let diagnostics = try await client.cliExecutableDiagnostics()
#expect(diagnostics.source == .homebrewAppleSilicon)
#expect(diagnostics.resolvedExecutablePath == "/opt/homebrew/bin/codex")
#expect(diagnostics.versionString == "codex-cli 0.135.0")
#expect(diagnostics.compatibility == .supported(documentedWindow: "0.135.x"))
#expect(diagnostics.versionString == "codex-cli 0.137.0")
#expect(diagnostics.compatibility == .supported(documentedWindow: "0.137.x"))

await client.stop()
}
Expand All @@ -108,8 +108,8 @@ struct CodexAppServerTests {
launchArgumentsPrefix: [],
resolvedExecutableURL: URL(fileURLWithPath: "/opt/homebrew/bin/codex"),
source: .homebrewAppleSilicon,
versionString: "codex-cli 0.135.0",
compatibility: .supported(documentedWindow: "0.135.x")
versionString: "codex-cli 0.137.0",
compatibility: .supported(documentedWindow: "0.137.x")
)
)
let client = CodexAppServer(transport: transport)
Expand All @@ -124,7 +124,7 @@ struct CodexAppServerTests {
)
)

#expect(startup.cliExecutableDiagnostics.versionString == "codex-cli 0.135.0")
#expect(startup.cliExecutableDiagnostics.versionString == "codex-cli 0.137.0")
#expect(startup.initializeSession.codexHome == "/Users/galew/.codex")
#expect(await transport.recordedMethods == ["initialize", "initialized"])

Expand All @@ -140,7 +140,7 @@ struct CodexAppServerTests {
resolvedExecutableURL: URL(fileURLWithPath: "/opt/homebrew/bin/codex"),
source: .homebrewAppleSilicon,
versionString: "codex-cli 0.128.0",
compatibility: .outsideDocumentedWindow(documentedWindow: "0.135.x")
compatibility: .outsideDocumentedWindow(documentedWindow: "0.137.x")
)
)
let client = CodexAppServer(transport: transport)
Expand All @@ -150,7 +150,7 @@ struct CodexAppServerTests {
source: .homebrewAppleSilicon,
resolvedExecutablePath: "/opt/homebrew/bin/codex",
versionString: "codex-cli 0.128.0",
compatibility: .outsideDocumentedWindow(documentedWindow: "0.135.x")
compatibility: .outsideDocumentedWindow(documentedWindow: "0.137.x")
)
)) {
try await client.start(
Expand All @@ -177,7 +177,7 @@ struct CodexAppServerTests {
resolvedExecutableURL: URL(fileURLWithPath: "/opt/homebrew/bin/codex"),
source: .homebrewAppleSilicon,
versionString: "codex-cli 0.128.0",
compatibility: .outsideDocumentedWindow(documentedWindow: "0.135.x")
compatibility: .outsideDocumentedWindow(documentedWindow: "0.137.x")
)
)
let client = CodexAppServer(transport: transport)
Expand Down
Loading