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
17 changes: 10 additions & 7 deletions apps/decodex-app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ bundled Rust app helper so account UI stays on the same CLI-owned files even whe
long-running local `decodex serve` is older than the app bundle. On launch the app also
connects to an existing `decodex serve` on the default local endpoint when one is
available; otherwise it starts the bundled Decodex binary as a normal scheduler with
`decodex serve --listen-address 127.0.0.1:8912`. The CLI owns the default scheduler
interval, currently 15 seconds. App-started servers load the enabled project registry
and own the same operator listener as a manually started `decodex serve`. The helper
owns account operations and interactive login flows that need streamed command output:
`decodex serve --allow-unverified-codex --listen-address 127.0.0.1:8912`. The override
only downgrades unverified Codex app-server identity to a warning; other preflight
blockers remain fail-closed. The CLI owns the default scheduler interval, currently
15 seconds. App-started servers load the enabled project registry and own the same
operator listener as a manually started `decodex serve`. The helper owns account
operations and interactive login flows that need streamed command output:

- list accounts without printing token material
- pin future Decodex runs to one account
Expand Down Expand Up @@ -75,9 +77,10 @@ swift run --package-path apps/decodex-app DecodexApp

Use hidden `decodex serve --dev` only when manually testing local account APIs, the app
snapshot API, or dashboard routes while deliberately avoiding scheduler activity. The
normal app fallback is ordinary `decodex serve --listen-address 127.0.0.1:8912`. Do
not use `--dev` to validate project registration, Linear polling, queue intake, or
retained-lane execution; use ordinary `decodex serve` for those paths.
normal app fallback is `decodex serve --allow-unverified-codex --listen-address
127.0.0.1:8912` so development Codex app-server builds can still run through the local
operator surface. Do not use `--dev` to validate project registration, Linear polling,
queue intake, or retained-lane execution; use ordinary `decodex serve` for those paths.

The staging script follows the local Rsnap-style signing path: it writes
`target/decodex-app/Decodex App.app`, signs the bundle with an Apple Development
Expand Down
13 changes: 9 additions & 4 deletions apps/decodex-app/Sources/DecodexApp/DecodexServerBridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,7 @@ actor DecodexServerBridge {
let nullDevice = FileHandle(forWritingAtPath: "/dev/null")

process.executableURL = try decodexExecutableURL()
process.arguments = [
"serve",
"--listen-address", defaultListenAddress,
]
process.arguments = Self.bundledServerArguments(listenAddress: defaultListenAddress)
process.standardOutput = nullDevice
process.standardError = nullDevice

Expand All @@ -237,6 +234,14 @@ actor DecodexServerBridge {
startedProcess = process
}

static func bundledServerArguments(listenAddress: String) -> [String] {
[
"serve",
"--allow-unverified-codex",
"--listen-address", listenAddress,
]
}

private func decodexExecutableURL() throws -> URL {
if let override = ProcessInfo.processInfo.environment["DECODEX_APP_DECODEX"], override.isEmpty == false {
let overrideURL = URL(fileURLWithPath: override)
Expand Down
2 changes: 1 addition & 1 deletion apps/decodex-app/Sources/DecodexApp/Models.swift
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ struct CodexAccount: Decodable, Identifiable, Equatable {
if let recoveryAction = AccountRecoveryAction(rawValue: normalized(recoveryAction)) {
return recoveryAction
}
if !refreshTokenPresent {
if refreshTokenPresent == false {
return .login
}
if normalized(refreshStatus) == "failed" {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@testable import DecodexApp
import XCTest

final class DecodexServerBridgeTests: XCTestCase {
func testBundledServerArgumentsAllowUnverifiedCodex() {
XCTAssertEqual(
DecodexServerBridge.bundledServerArguments(listenAddress: "127.0.0.1:8912"),
[
"serve",
"--allow-unverified-codex",
"--listen-address",
"127.0.0.1:8912",
]
)
}
}