sneakoscope 8.1.2 → 8.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +96 -58
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/bin/fast-inline.js +5 -51
- package/dist/cli/command-manifest-lite.js +2 -1
- package/dist/cli/command-registry.js +2 -1
- package/dist/cli/global-mode-router.js +1 -1
- package/dist/cli/install-helpers-codex-lb-config.js +112 -914
- package/dist/cli/install-helpers-codex-lb-shared.js +3 -44
- package/dist/cli/install-helpers-install-support.js +4 -20
- package/dist/cli/install-helpers.js +36 -2716
- package/dist/cli/router.js +9 -9
- package/dist/commands/bridge-command-output.js +111 -0
- package/dist/commands/bridge.js +320 -0
- package/dist/commands/codex-app.js +39 -123
- package/dist/commands/doctor-helpers.js +380 -0
- package/dist/commands/doctor-profile.js +3 -0
- package/dist/commands/doctor.js +114 -873
- package/dist/commands/mad-sks.js +0 -4
- package/dist/config/skills-manifest.json +1 -1
- package/dist/core/agents/agent-effort-policy.js +11 -21
- package/dist/core/agents/agent-recursion-guard.js +26 -0
- package/dist/core/agents/agent-runner-codex-exec.js +7 -9
- package/dist/core/architecture-hardening/contracts/contracts.js +225 -161
- package/dist/core/architecture-hardening/state/state-service.js +49 -13
- package/dist/core/auto-review.js +15 -9
- package/dist/core/codex/codex-config-guard.js +8 -0
- package/dist/core/codex-adapter.js +8 -10
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +7 -29
- package/dist/core/codex-app/codex-app-launcher.js +10 -12
- package/dist/core/codex-app/codex-app-restart.js +10 -12
- package/dist/core/codex-app/menubar/constants.js +2 -5
- package/dist/core/codex-app/menubar/global-install.js +3 -2
- package/dist/core/codex-app/menubar/installer/result.js +23 -0
- package/dist/core/codex-app/menubar/installer/runtime.js +28 -0
- package/dist/core/codex-app/menubar/installer.js +5 -96
- package/dist/core/codex-app/menubar/migration.js +1 -42
- package/dist/core/codex-app/openrouter-provider.js +0 -78
- package/dist/core/codex-app.js +97 -360
- package/dist/core/codex-control/codex-app-server-runtime-env.js +8 -28
- package/dist/core/codex-control/codex-current-image-path-real-probe.js +2 -3
- package/dist/core/codex-control/codex-current-web-search-probe.js +2 -3
- package/dist/core/codex-control/codex-sdk-adapter.js +5 -48
- package/dist/core/codex-control/codex-task-runner.js +16 -60
- package/dist/core/codex-control/desktop-bridge-launch-guard.js +227 -0
- package/dist/core/codex-exec-output-schema.js +11 -13
- package/dist/core/codex-lb/bridge-contracts.js +2 -0
- package/dist/core/codex-lb/bridge-runtime-validation/capability.js +104 -0
- package/dist/core/codex-lb/bridge-runtime-validation/catalog.js +52 -0
- package/dist/core/codex-lb/bridge-runtime-validation/shared.js +109 -0
- package/dist/core/codex-lb/bridge-runtime-validation/status.js +250 -0
- package/dist/core/codex-lb/bridge-runtime-validation.js +106 -0
- package/dist/core/codex-lb/capability-runner.js +505 -201
- package/dist/core/codex-lb/codex-lb-env.js +179 -12
- package/dist/core/codex-lb/combined-catalog/builder.js +86 -0
- package/dist/core/codex-lb/combined-catalog/contracts.js +5 -0
- package/dist/core/codex-lb/combined-catalog/normalize.js +170 -0
- package/dist/core/codex-lb/combined-catalog/persistence.js +207 -0
- package/dist/core/codex-lb/combined-catalog/shared.js +12 -0
- package/dist/core/codex-lb/combined-catalog/storage.js +171 -0
- package/dist/core/codex-lb/combined-catalog.js +12 -0
- package/dist/core/codex-lb/desktop-bridge/client.js +4 -1
- package/dist/core/codex-lb/desktop-bridge/header-policy.js +48 -63
- package/dist/core/codex-lb/desktop-bridge/http-forward.js +115 -83
- package/dist/core/codex-lb/desktop-bridge/launchd.js +20 -13
- package/dist/core/codex-lb/desktop-bridge/location-rewrite.js +4 -1
- package/dist/core/codex-lb/desktop-bridge/security.js +381 -267
- package/dist/core/codex-lb/desktop-bridge/server.js +148 -19
- package/dist/core/codex-lb/desktop-bridge/state.js +56 -70
- package/dist/core/codex-lb/desktop-bridge/types.js +6 -1
- package/dist/core/codex-lb/desktop-bridge/websocket-forward.js +281 -106
- package/dist/core/codex-lb/desktop-bridge-migration/historical-config.js +245 -0
- package/dist/core/codex-lb/desktop-bridge-migration/historical-toml.js +56 -0
- package/dist/core/codex-lb/desktop-bridge-migration/metadata.js +73 -0
- package/dist/core/codex-lb/desktop-bridge-migration/receipt.js +52 -0
- package/dist/core/codex-lb/desktop-bridge-migration/retired-runtime-cleanup.js +106 -0
- package/dist/core/codex-lb/desktop-bridge-migration/types.js +1 -0
- package/dist/core/codex-lb/desktop-bridge-migration.js +238 -0
- package/dist/core/codex-lb/desktop-controller-v3/catalog.js +257 -0
- package/dist/core/codex-lb/desktop-controller-v3/diagnostics.js +62 -0
- package/dist/core/codex-lb/desktop-controller-v3/lifecycle-commands.js +203 -0
- package/dist/core/codex-lb/desktop-controller-v3/live-probes.js +293 -0
- package/dist/core/codex-lb/desktop-controller-v3/preflight-probes.js +144 -0
- package/dist/core/codex-lb/desktop-controller-v3/provider-commands.js +182 -0
- package/dist/core/codex-lb/desktop-controller-v3/shared.js +279 -0
- package/dist/core/codex-lb/desktop-controller-v3/status.js +269 -0
- package/dist/core/codex-lb/desktop-controller-v3/types.js +1 -0
- package/dist/core/codex-lb/desktop-controller-v3/verification.js +89 -0
- package/dist/core/codex-lb/desktop-controller-v3.js +67 -0
- package/dist/core/codex-lb/desktop-controller.js +2 -1730
- package/dist/core/codex-lb/desktop-service.js +462 -627
- package/dist/core/codex-lb/migration-receipt.js +560 -118
- package/dist/core/codex-lb/probes/auxiliary-surfaces-probe.js +37 -53
- package/dist/core/codex-lb/probes/bridge-probe.js +125 -64
- package/dist/core/codex-lb/probes/catalog-probe.js +36 -136
- package/dist/core/codex-lb/probes/computer-use-probe.js +63 -39
- package/dist/core/codex-lb/probes/image-generation-probe.js +98 -41
- package/dist/core/codex-lb/probes/probe-evidence.js +32 -33
- package/dist/core/codex-lb/probes/voice-realtime-probe.js +69 -43
- package/dist/core/codex-lb/provider-credentials/configuration.js +127 -0
- package/dist/core/codex-lb/provider-credentials/locks.js +11 -0
- package/dist/core/codex-lb/provider-credentials/private-snapshot.js +28 -0
- package/dist/core/codex-lb/provider-credentials/removal.js +33 -0
- package/dist/core/codex-lb/provider-credentials/resolution.js +59 -0
- package/dist/core/codex-lb/provider-credentials/runtime.js +55 -0
- package/dist/core/codex-lb/provider-credentials/types.js +1 -0
- package/dist/core/codex-lb/provider-credentials/validation-store.js +137 -0
- package/dist/core/codex-lb/provider-credentials.js +5 -0
- package/dist/core/codex-lb/provider-registry.js +323 -0
- package/dist/core/codex-lb/provider-route-policy.js +118 -0
- package/dist/core/codex-lb/request-route-resolver.js +172 -0
- package/dist/core/codex-lb/route-index.js +148 -0
- package/dist/core/codex-lb/trusted-deep-evidence.js +158 -286
- package/dist/core/commands/basic-cli.js +1 -1
- package/dist/core/commands/check-command.js +3 -10
- package/dist/core/commands/gate-result-contract.js +10 -14
- package/dist/core/commands/intent-normalization/normalizer.js +1 -1
- package/dist/core/commands/mad-sks-command.js +2 -6
- package/dist/core/commands/release-command.js +11 -1
- package/dist/core/commands/telegram-command.js +46 -6
- package/dist/core/doctor/doctor-readiness-matrix.js +9 -7
- package/dist/core/doctor/skill-legacy-surface.js +5 -5
- package/dist/core/evidence/v2/evidence-key.js +30 -3
- package/dist/core/feature-fixtures.js +8 -1
- package/dist/core/feature-registry.js +3 -2
- package/dist/core/hooks-runtime/stop-finalization.js +11 -1
- package/dist/core/hooks-runtime/subagent-context.js +15 -1
- package/dist/core/hooks-runtime/subagent-skill-availability-contract.js +1 -1
- package/dist/core/hooks-runtime/tool-output-quarantine.js +1 -1
- package/dist/core/hooks-runtime.js +73 -87
- package/dist/core/image-ux-review/imagegen-adapter.js +108 -94
- package/dist/core/image-ux-review/real-callout-extractor.js +144 -14
- package/dist/core/imagegen/desktop-bridge-imagegen-target.js +77 -0
- package/dist/core/imagegen/imagegen-capability.js +43 -151
- package/dist/core/init/skills/filesystem.js +89 -0
- package/dist/core/init/skills/inventory.js +97 -0
- package/dist/core/init/skills/manifest.js +151 -0
- package/dist/core/init/skills.js +5 -325
- package/dist/core/init.js +0 -63
- package/dist/core/install/installed-package-smoke.js +1 -1
- package/dist/core/managed-assets/managed-assets-manifest.js +0 -1
- package/dist/core/policy/latest-version-guidance.js +15 -2
- package/dist/core/preflight/parallel-preflight-engine.js +27 -51
- package/dist/core/provider/provider-badge.js +9 -4
- package/dist/core/provider/provider-context.js +57 -107
- package/dist/core/providers/openrouter/openrouter-account.js +3 -1
- package/dist/core/providers/openrouter/openrouter-secret-store.js +91 -22
- package/dist/core/release/desktop-bridge-release-evidence.js +457 -0
- package/dist/core/release/gate-manifest.js +0 -1
- package/dist/core/release/main-push-guard.js +13 -0
- package/dist/core/release/main-push-receipt.js +11 -0
- package/dist/core/release/physical-release-gates.js +664 -61
- package/dist/core/release/publish-preflight.js +3 -3
- package/dist/core/release/release-gate-batch-runner.js +19 -6
- package/dist/core/release/release-gate-dag.js +33 -6
- package/dist/core/release/release-gate-node.js +1 -3
- package/dist/core/release/release-gate-output-contract.js +55 -0
- package/dist/core/release/release-pack-contract.js +1 -1
- package/dist/core/release/release-pack-receipt.js +209 -8
- package/dist/core/release/release-real-contract.js +1 -1
- package/dist/core/release/stage-publish.js +106 -28
- package/dist/core/retention/temp-lease.js +204 -0
- package/dist/core/retention.js +18 -195
- package/dist/core/routes.js +1 -2
- package/dist/core/safety/intent-contract/intent-contract.js +3 -3
- package/dist/core/subagents/naruto-host-credentials.js +6 -1
- package/dist/core/subagents/official-subagent-config.js +27 -9
- package/dist/core/subagents/official-subagent-runner.js +14 -31
- package/dist/core/subagents/wave-lifecycle.js +36 -8
- package/dist/core/subagents/wave-parent-guidance.js +2 -1
- package/dist/core/telegram/doctor.js +2 -2
- package/dist/core/telegram/liveness.js +10 -4
- package/dist/core/triwiki/context-graph/compiler/index.js +18 -18
- package/dist/core/update/update-migration-state/fast-mode-config.js +172 -0
- package/dist/core/update/update-migration-state/session-state-split.js +247 -0
- package/dist/core/update/update-migration-state/simple-stages.js +46 -0
- package/dist/core/update/update-migration-state.js +4 -481
- package/dist/core/version.js +1 -1
- package/dist/native/sks-menubar/Sources/OperationCoordinator.swift +28 -4
- package/dist/native/sks-menubar/Sources/OperationModels.swift +112 -2
- package/dist/native/sks-menubar/Sources/ProviderRouteExplanation.swift +21 -0
- package/dist/native/sks-menubar/Sources/ProvidersBridgeCatalog.swift +140 -0
- package/dist/native/sks-menubar/Sources/ProvidersOpenRouter.swift +107 -470
- package/dist/native/sks-menubar/Sources/ProvidersReliability.swift +27 -197
- package/dist/native/sks-menubar/Sources/ProvidersRoutingTruth.swift +335 -269
- package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +233 -437
- package/dist/native/sks-menubar/Sources/RemoteCodingViewController.swift +16 -7
- package/dist/native/sks-menubar/Sources/SecureProcessEnvelope.swift +39 -9
- package/dist/native/sks-menubar/Sources/TelegramSupport.swift +56 -0
- package/dist/scripts/canonical-test-runner.js +7 -1
- package/dist/scripts/check-runtime-schemas.js +7 -2
- package/dist/scripts/codex-sdk-real-smoke-check.js +3 -1
- package/dist/scripts/desktop-bridge-capabilities-check.js +123 -0
- package/dist/scripts/{codex-lb-desktop-bridge-latency-check.js → desktop-bridge-latency-check.js} +61 -16
- package/dist/scripts/desktop-bridge-real-evidence-check.js +64 -0
- package/dist/scripts/{codex-lb-desktop-bridge-check.js → desktop-bridge-transport-check.js} +92 -155
- package/dist/scripts/desktop-bridge-transport-client.js +116 -0
- package/dist/scripts/desktop-bridge-unification-check.js +276 -0
- package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +12 -8
- package/dist/scripts/gate-policy-audit-check.js +52 -2
- package/dist/scripts/provider-badge-context-check.js +55 -12
- package/dist/scripts/publish-preflight.js +1 -2
- package/dist/scripts/release-affected-selector-check.js +1 -2
- package/dist/scripts/release-aggressive-resource-governor-check.js +1 -1
- package/dist/scripts/release-cache-glob-hashing-check.js +1 -0
- package/dist/scripts/release-cache-version-neutral-fixture-check.js +1 -0
- package/dist/scripts/release-full-parallelism-blackbox.js +1 -1
- package/dist/scripts/release-gate-batch-runner-check.js +9 -0
- package/dist/scripts/release-gate-dag-runner-check.js +6 -0
- package/dist/scripts/release-gate-dag-runner.js +4 -2
- package/dist/scripts/release-metadata-check.js +16 -3
- package/dist/scripts/release-pack-receipt.js +29 -6
- package/dist/scripts/release-physical-gates-check.js +39 -0
- package/dist/scripts/release-real-check.js +7 -5
- package/package.json +6 -8
- package/release-gates.v2.json +156 -157
- package/runtime-required-scripts.json +11 -11
- package/schemas/codex/desktop-bridge-status-v3.schema.json +286 -0
- package/schemas/codex/desktop-capabilities-v3.schema.json +198 -0
- package/schemas/release/release-gate-node.schema.json +2 -3
- package/dist/cli/codex-lb-setup-warning-output.js +0 -17
- package/dist/cli/install-helpers-codex-lb-chain.js +0 -529
- package/dist/commands/codex-lb.js +0 -1232
- package/dist/core/architecture-hardening/migration/migration.js +0 -111
- package/dist/core/codex-app/auxiliary-oauth-policy.js +0 -36
- package/dist/core/codex-app/catalog-compat/catalog-service.js +0 -104
- package/dist/core/codex-app/child-policy/child-policy.js +0 -35
- package/dist/core/codex-app/desktop-routing-snapshot.js +0 -233
- package/dist/core/codex-app/glm-model-profile.js +0 -1
- package/dist/core/codex-app/glm-profile-installer.js +0 -191
- package/dist/core/codex-app/glm-profile-schema.js +0 -42
- package/dist/core/codex-app/multi-provider-router.js +0 -391
- package/dist/core/codex-app/openrouter-activate.js +0 -405
- package/dist/core/codex-app/openrouter-model-catalog.js +0 -217
- package/dist/core/codex-app/provider-child-policy.js +0 -64
- package/dist/core/codex-app/provider-mode.js +0 -91
- package/dist/core/codex-app/provider-session-policy.js +0 -85
- package/dist/core/codex-app/session-policy/session-pinning.js +0 -68
- package/dist/core/codex-control/codex-lb-launch-recovery.js +0 -319
- package/dist/core/codex-lb/codex-lb-setup.js +0 -293
- package/dist/core/codex-lb/codex-lb-tool-catalog.js +0 -456
- package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +0 -290
- package/dist/core/codex-lb/desktop-center-credentials.js +0 -1083
- package/dist/core/codex-lb/desktop-mode.js +0 -32
- package/dist/core/codex-lb/desktop-real-evidence.js +0 -168
- package/dist/core/codex-lb/legacy-migration.js +0 -576
- package/dist/core/codex-lb/native-openai-transport/transport.js +0 -68
- package/dist/core/codex-lb/provider-routing/provider-router.js +0 -58
- package/dist/core/codex-lb/routing-truth.js +0 -327
- package/dist/core/imagegen/codex-lb-imagegen-target.js +0 -92
- package/dist/native/sks-menubar/Sources/ProvidersConnectTest.swift +0 -118
- package/dist/native/sks-menubar/Sources/ProvidersFastMode.swift +0 -17
- package/dist/native/sks-menubar/Sources/ProvidersMultiProvider.swift +0 -331
- package/dist/native/sks-menubar/Sources/ProvidersRoleModels.swift +0 -260
- package/dist/scripts/codex-lb-catalog-passthrough-check.js +0 -120
- package/dist/scripts/codex-lb-desktop-auth-invariant-check.js +0 -169
- package/dist/scripts/codex-lb-desktop-capabilities-check.js +0 -287
- package/dist/scripts/codex-lb-desktop-real-evidence-check.js +0 -123
- package/dist/scripts/codex-lb-fast-mode-truth-check.js +0 -114
- package/dist/scripts/codex-lb-fast-ui-preservation-check.js +0 -152
- package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +0 -231
|
@@ -20,6 +20,114 @@ enum OperationState: String, Codable {
|
|
|
20
20
|
case queued, running, waitingForConfirmation, succeeded, failed, cancelled, terminalUncertain
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
/// Diagnostic commands can complete successfully while reporting that runtime
|
|
24
|
+
/// readiness is not satisfied. This metadata deliberately excludes request
|
|
25
|
+
/// bodies, credentials, endpoint query strings, and secret fingerprints.
|
|
26
|
+
struct DiagnosticOperationMetadata: Codable, Equatable {
|
|
27
|
+
let schema: String
|
|
28
|
+
let executionOK: Bool
|
|
29
|
+
let reportGenerated: Bool
|
|
30
|
+
let requestedLevel: String
|
|
31
|
+
let levelSatisfied: Bool
|
|
32
|
+
let fullFeatureVerified: Bool
|
|
33
|
+
let reportId: String
|
|
34
|
+
let correlationId: String
|
|
35
|
+
let attemptId: Int
|
|
36
|
+
let catalogGeneration: String?
|
|
37
|
+
|
|
38
|
+
enum CodingKeys: String, CodingKey { case schema
|
|
39
|
+
case executionOK = "execution_ok", reportGenerated = "report_generated"
|
|
40
|
+
case requestedLevel = "requested_level", levelSatisfied = "level_satisfied"
|
|
41
|
+
case fullFeatureVerified = "full_feature_verified", reportId = "report_id"
|
|
42
|
+
case correlationId = "correlation_id", attemptId = "attempt_id"
|
|
43
|
+
case catalogGeneration = "catalog_generation"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
struct ProviderResponseIdentity: Equatable {
|
|
47
|
+
let requestGeneration: Int
|
|
48
|
+
let reportId: String
|
|
49
|
+
let correlationId: String
|
|
50
|
+
let attemptId: Int
|
|
51
|
+
let checkedAt: Date
|
|
52
|
+
let catalogGeneration: String?
|
|
53
|
+
}
|
|
54
|
+
struct ProviderResponseGate {
|
|
55
|
+
private(set) var activeRequestGeneration = 0
|
|
56
|
+
private(set) var accepted: ProviderResponseIdentity?
|
|
57
|
+
mutating func begin() -> Int { activeRequestGeneration += 1; return activeRequestGeneration }
|
|
58
|
+
mutating func accept(_ candidate: ProviderResponseIdentity) -> Bool {
|
|
59
|
+
guard candidate.requestGeneration == activeRequestGeneration else { return false }
|
|
60
|
+
if let previous = accepted {
|
|
61
|
+
guard candidate.checkedAt > previous.checkedAt
|
|
62
|
+
|| candidate.checkedAt == previous.checkedAt && candidate.attemptId >= previous.attemptId else { return false }
|
|
63
|
+
}
|
|
64
|
+
accepted = candidate
|
|
65
|
+
return true
|
|
66
|
+
}
|
|
67
|
+
func statusMayMerge(checkedAt: Date, catalogGeneration: String?) -> Bool {
|
|
68
|
+
guard let accepted = accepted else { return true }
|
|
69
|
+
// Ambient status can advance only the explicitly verified generation.
|
|
70
|
+
guard catalogGeneration == accepted.catalogGeneration else { return false }
|
|
71
|
+
return checkedAt >= accepted.checkedAt
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
enum ProviderRecoveryAction: String, CaseIterable {
|
|
76
|
+
case repairBridgeService = "repair_bridge_service"
|
|
77
|
+
case restartBridgeAndRetry = "restart_bridge_and_retry"
|
|
78
|
+
case inspectBridgeLogs = "inspect_bridge_logs_and_retry_transport"
|
|
79
|
+
case updateBridgeProtocol = "update_bridge_or_codex_protocol"
|
|
80
|
+
case configureCodexLb = "configure_codex_lb_credential"
|
|
81
|
+
case rotateCodexLb = "rotate_codex_lb_credential"
|
|
82
|
+
case configureOpenRouter = "configure_openrouter_credential"
|
|
83
|
+
case rotateOpenRouter = "rotate_openrouter_credential"
|
|
84
|
+
case retryCatalog = "retry_catalog_sync"
|
|
85
|
+
case resolveConflict = "resolve_catalog_route_conflict"
|
|
86
|
+
case refreshCatalog = "refresh_catalog_or_select_supported_model"
|
|
87
|
+
case runDeep = "run_deep_verification"
|
|
88
|
+
case updateMenubar = "update_sks_and_rebuild_menubar"
|
|
89
|
+
case reviewConfig = "review_config_manually"
|
|
90
|
+
|
|
91
|
+
var buttonTitle: String {
|
|
92
|
+
switch self {
|
|
93
|
+
case .repairBridgeService, .restartBridgeAndRetry: return "Repair Bridge"
|
|
94
|
+
case .inspectBridgeLogs: return "Open Diagnostics"
|
|
95
|
+
case .updateBridgeProtocol, .updateMenubar: return "Check for Updates"
|
|
96
|
+
case .configureCodexLb, .rotateCodexLb: return "Configure Codex-LB"
|
|
97
|
+
case .configureOpenRouter, .rotateOpenRouter: return "Configure OpenRouter"
|
|
98
|
+
case .retryCatalog, .resolveConflict, .refreshCatalog: return "Refresh Catalog"
|
|
99
|
+
case .runDeep: return "Verify Deep"
|
|
100
|
+
case .reviewConfig: return "Review Config"
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
enum ProviderSecretRedactor {
|
|
105
|
+
private static let patterns = [
|
|
106
|
+
(#"(?i)(authorization\s*:\s*bearer\s+)[^\s,;]+"#, "$1[REDACTED]"),
|
|
107
|
+
(#"(?i)(x-codex-lb-api-key\s*[:=]\s*)[^\s,;]+"#, "$1[REDACTED]"),
|
|
108
|
+
(#"\bsk-(?:clb|or|proj)?-[A-Za-z0-9_-]{6,}\b"#, "[REDACTED]"),
|
|
109
|
+
(#"(?i)(api[_-]?key\s*[:=]\s*)[^\s,;]+"#, "$1[REDACTED]")
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
static func redact(_ value: String) -> String {
|
|
113
|
+
patterns.reduce(value) { output, entry in
|
|
114
|
+
let (pattern, replacement) = entry
|
|
115
|
+
guard let regex = try? NSRegularExpression(pattern: pattern) else { return output }
|
|
116
|
+
return regex.stringByReplacingMatches(in: output, range: NSRange(output.startIndex..., in: output), withTemplate: replacement)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
static func redactEndpoint(_ value: String) -> String {
|
|
121
|
+
let cleaned = redact(value)
|
|
122
|
+
guard var components = URLComponents(string: cleaned), components.scheme != nil else { return cleaned }
|
|
123
|
+
components.user = nil
|
|
124
|
+
components.password = nil
|
|
125
|
+
components.query = nil
|
|
126
|
+
components.fragment = nil
|
|
127
|
+
return components.string ?? "[REDACTED ENDPOINT]"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
23
131
|
enum OperationProgressSignal: String, Codable, CaseIterable {
|
|
24
132
|
case evidence, fileChange, testResult, modelResponse, toolResponse, none
|
|
25
133
|
}
|
|
@@ -299,6 +407,7 @@ struct OperationSnapshot: Codable {
|
|
|
299
407
|
let registry: String?
|
|
300
408
|
let recovery: OperationRecoveryStatus?
|
|
301
409
|
let providerApply: ProviderApplyProjection?
|
|
410
|
+
let diagnostic: DiagnosticOperationMetadata?
|
|
302
411
|
|
|
303
412
|
init(
|
|
304
413
|
schema: String,
|
|
@@ -316,7 +425,8 @@ struct OperationSnapshot: Codable {
|
|
|
316
425
|
projectRoot: String?,
|
|
317
426
|
registry: String?,
|
|
318
427
|
recovery: OperationRecoveryStatus? = nil,
|
|
319
|
-
providerApply: ProviderApplyProjection? = nil
|
|
428
|
+
providerApply: ProviderApplyProjection? = nil,
|
|
429
|
+
diagnostic: DiagnosticOperationMetadata? = nil
|
|
320
430
|
) {
|
|
321
431
|
self.schema = schema
|
|
322
432
|
self.id = id
|
|
@@ -334,6 +444,7 @@ struct OperationSnapshot: Codable {
|
|
|
334
444
|
self.registry = registry
|
|
335
445
|
self.recovery = recovery
|
|
336
446
|
self.providerApply = providerApply
|
|
447
|
+
self.diagnostic = diagnostic
|
|
337
448
|
}
|
|
338
449
|
}
|
|
339
450
|
|
|
@@ -386,4 +497,3 @@ struct UpdateOperationReceiptSnapshot: Codable {
|
|
|
386
497
|
case receiptPath = "receipt_path"
|
|
387
498
|
}
|
|
388
499
|
}
|
|
389
|
-
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
struct ProviderRouteExplanation: Equatable {
|
|
4
|
+
let providerId: String
|
|
5
|
+
let upstreamModel: String
|
|
6
|
+
let fallback: String
|
|
7
|
+
|
|
8
|
+
static func decode(from commandEnvelope: [String: Any]) -> ProviderRouteExplanation? {
|
|
9
|
+
guard let result = commandEnvelope["result"] as? [String: Any],
|
|
10
|
+
let explanation = result["explanation"] as? [String: Any],
|
|
11
|
+
let route = explanation["route"] as? [String: Any],
|
|
12
|
+
let providerId = route["provider_id"] as? String,
|
|
13
|
+
let upstreamModel = route["upstream_model"] as? String,
|
|
14
|
+
let fallback = explanation["fallback"] as? String else { return nil }
|
|
15
|
+
return ProviderRouteExplanation(
|
|
16
|
+
providerId: providerId,
|
|
17
|
+
upstreamModel: upstreamModel,
|
|
18
|
+
fallback: fallback
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import Cocoa
|
|
2
|
+
|
|
3
|
+
extension ProvidersViewController {
|
|
4
|
+
func makeCombinedCatalogCard() -> NSBox {
|
|
5
|
+
let refresh = NativeView.button("Refresh", target: self, action: #selector(refreshCombinedCatalog))
|
|
6
|
+
let report = NativeView.button("Open Report", target: self, action: #selector(openCatalogReport))
|
|
7
|
+
registerProviderAction(refresh, id: "sks-provider-refresh-catalog")
|
|
8
|
+
registerProviderAction(report, id: "sks-provider-open-catalog-report")
|
|
9
|
+
actionButtons += [refresh, report]
|
|
10
|
+
let card = NativeView.card(title: "Combined Model Catalog", subtitle: "Codex-LB and OpenRouter catalogs activate atomically with one explicit route index. A failed build keeps the prior verified generation.", views: [catalogSyncStatus, ControlKit.actionRow([refresh, report])])
|
|
11
|
+
card.setAccessibilityIdentifier("sks-provider-card-combined-catalog")
|
|
12
|
+
return card
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
func makeRoutesCard() -> NSBox {
|
|
16
|
+
let explain = NativeView.button("Explain Route", target: self, action: #selector(explainRoute))
|
|
17
|
+
registerProviderAction(explain, id: "sks-provider-route-explain")
|
|
18
|
+
actionButtons.append(explain)
|
|
19
|
+
let card = NativeView.card(title: "Routes", subtitle: "Routes come only from the canonical model index or a validated session pin. Fallback is always none.", views: [routesStatus, NativeView.row([routeModelField, explain])])
|
|
20
|
+
card.setAccessibilityIdentifier("sks-provider-card-routes")
|
|
21
|
+
return card
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
func renderCombinedCatalog(_ json: [String: Any]) {
|
|
25
|
+
let catalog = json["catalog_sync"] as? [String: Any]
|
|
26
|
+
guard catalog?["schema"] as? String == "sks.combined-catalog-sync.v1",
|
|
27
|
+
let data = try? JSONSerialization.data(withJSONObject: catalog as Any),
|
|
28
|
+
let decoded = try? JSONDecoder().decode(CombinedCatalogSyncStatusV1.self, from: data),
|
|
29
|
+
decoded.providers["codex-lb"]?.schema == "sks.catalog-sync-state.v2",
|
|
30
|
+
decoded.providers["openrouter"]?.schema == "sks.catalog-sync-state.v2" else {
|
|
31
|
+
catalogSyncStatus.stringValue = "Capability schema invalid · catalog_sync missing · capability_schema_invalid"
|
|
32
|
+
catalogSyncStatus.textColor = .systemRed
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
renderCatalogStatus(decoded)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
func renderCatalogStatus(_ catalog: CombinedCatalogSyncStatusV1) {
|
|
39
|
+
func providerText(_ id: String) -> String {
|
|
40
|
+
guard let state = catalog.providers[id] else { return "invalid" }
|
|
41
|
+
return state.modelCount.map(String.init) ?? state.state
|
|
42
|
+
}
|
|
43
|
+
let modelText = catalog.modelCount.map { " · \($0) models" } ?? ""
|
|
44
|
+
let routeText = catalog.routeCount.map { " · \($0) routes" } ?? ""
|
|
45
|
+
let conflictText = catalog.conflictCount > 0 ? " · \(catalog.conflictCount) conflicts" : ""
|
|
46
|
+
let cause = catalog.blockers.first.map { " · \(ProviderSecretRedactor.redact($0))" } ?? ""
|
|
47
|
+
let recovery = catalog.recoveryAction.flatMap(ProviderRecoveryAction.init(rawValue:)).map { " · recovery \($0.buttonTitle)" } ?? ""
|
|
48
|
+
catalogSyncStatus.stringValue = "Combined catalog · \(catalog.state)\(modelText)\(routeText) · Codex-LB \(providerText("codex-lb")) / OpenRouter \(providerText("openrouter"))\(conflictText)\(cause)\(recovery)"
|
|
49
|
+
switch catalog.state {
|
|
50
|
+
case "verified": catalogSyncStatus.textColor = .systemGreen
|
|
51
|
+
case "failed": catalogSyncStatus.textColor = .systemRed
|
|
52
|
+
default: catalogSyncStatus.textColor = .systemOrange
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
func renderRoutes(_ json: [String: Any]) {
|
|
57
|
+
guard let routing = json["routing"] as? [String: Any],
|
|
58
|
+
let policy = routing["policy"] as? [String: Any],
|
|
59
|
+
policy["schema"] as? String == "sks.bridge-routing-policy.v1",
|
|
60
|
+
policy["fallback"] as? String == "none" else {
|
|
61
|
+
routesStatus.stringValue = "Routes · schema invalid or fallback is not none"
|
|
62
|
+
routesStatus.textColor = .systemRed
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
let provider = policy["default_provider_id"] as? String ?? "none"
|
|
66
|
+
let generation = policy["policy_generation"] as? String ?? "unreported"
|
|
67
|
+
let catalogGeneration = policy["catalog_generation"] as? String ?? "unreported"
|
|
68
|
+
let pin = routing["session_pin"] as? [String: Any]
|
|
69
|
+
let pinText = pin.map { "\($0["provider_id"] as? String ?? "invalid") / \($0["public_model"] as? String ?? "invalid")" } ?? "none"
|
|
70
|
+
let selected = routing["selected_route"] as? [String: Any]
|
|
71
|
+
let selectedModel = routing["selected_model"] as? String ?? "unknown"
|
|
72
|
+
let selectedText = selected.map { "\(selectedModel) → \($0["provider_id"] as? String ?? "unknown")" } ?? "none"
|
|
73
|
+
routesStatus.stringValue = "Default provider: \(provider) · selected model: \(selectedText) · session pin: \(pinText) · fallback: none · policy \(generation) · catalog \(catalogGeneration)"
|
|
74
|
+
routesStatus.textColor = .secondaryLabelColor
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@objc func refreshCombinedCatalog() {
|
|
78
|
+
runCatalogCommand(["bridge", "catalog", "sync", "--json"], title: "Refresh combined catalog", mutationGroup: "codex-config")
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@objc func openCatalogReport() {
|
|
82
|
+
runCatalogCommand(["bridge", "catalog", "status", "--json"], title: "Load combined catalog report", mutationGroup: nil)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private func runCatalogCommand(_ args: [String], title: String, mutationGroup: String?) {
|
|
86
|
+
guard !catalogRefreshInFlight, let snapshot = operations.begin(kind: "bridge-catalog", mutationGroup: mutationGroup, summary: title) else { return }
|
|
87
|
+
catalogRefreshInFlight = true
|
|
88
|
+
catalogSyncStatus.stringValue = "Combined catalog · syncing"
|
|
89
|
+
_ = operations.update(snapshot, state: .running, stage: "catalog_sync", progress: nil, summary: title)
|
|
90
|
+
processClient.run(args, timeout: NativeView.mutationTimeout) { [weak self] result in
|
|
91
|
+
guard let self = self else { return }
|
|
92
|
+
self.catalogRefreshInFlight = false
|
|
93
|
+
guard let json = self.json(result.output) else {
|
|
94
|
+
_ = self.operations.update(snapshot, state: .failed, stage: "complete", progress: 1, summary: "Catalog report schema invalid")
|
|
95
|
+
self.catalogSyncStatus.stringValue = "Capability schema invalid · catalog_sync missing · capability_schema_invalid"
|
|
96
|
+
self.catalogSyncStatus.textColor = .systemRed
|
|
97
|
+
return
|
|
98
|
+
}
|
|
99
|
+
guard json["schema"] as? String == "sks.desktop-bridge-command-result.v1",
|
|
100
|
+
["catalog.sync", "catalog.status"].contains(json["operation"] as? String ?? ""),
|
|
101
|
+
let statusJSON = json["status"] as? [String: Any],
|
|
102
|
+
let status = try? DesktopBridgeStatusV3Truth.decode(from: statusJSON) else {
|
|
103
|
+
_ = self.operations.update(snapshot, state: .failed, stage: "complete", progress: 1, summary: "Catalog command envelope invalid")
|
|
104
|
+
self.catalogSyncStatus.stringValue = "Capability schema invalid · current Desktop Bridge status missing"
|
|
105
|
+
self.catalogSyncStatus.textColor = .systemRed
|
|
106
|
+
return
|
|
107
|
+
}
|
|
108
|
+
self.renderCombinedCatalog(status.raw)
|
|
109
|
+
let valid = !self.catalogSyncStatus.stringValue.contains("schema invalid")
|
|
110
|
+
_ = self.operations.update(snapshot, state: valid ? .succeeded : .failed, stage: "complete", progress: 1, summary: valid ? "Catalog report generated" : "Catalog report schema invalid")
|
|
111
|
+
self.refresh()
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
@objc func explainRoute() {
|
|
116
|
+
let model = routeModelField.stringValue.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
117
|
+
guard !model.isEmpty, let snapshot = operations.begin(kind: "bridge-route-explain", mutationGroup: nil, summary: "Explain model route") else {
|
|
118
|
+
routesStatus.stringValue = "Route explain blocked · choose an exact model from the combined catalog."
|
|
119
|
+
routesStatus.textColor = .systemOrange
|
|
120
|
+
return
|
|
121
|
+
}
|
|
122
|
+
routesStatus.stringValue = "Explaining \(model) through the explicit route index…"
|
|
123
|
+
_ = operations.update(snapshot, state: .running, stage: "model_route", progress: nil, summary: "Explain model route")
|
|
124
|
+
processClient.run(["bridge", "route", "explain", model, "--json"], timeout: NativeView.statusTimeout) { [weak self] result in
|
|
125
|
+
guard let self = self else { return }
|
|
126
|
+
let json = self.json(result.output)
|
|
127
|
+
let explanation = json.flatMap(ProviderRouteExplanation.decode(from:))
|
|
128
|
+
let explainedRoute = explanation.flatMap { explanation in
|
|
129
|
+
explanation.fallback == "none"
|
|
130
|
+
? "\(model) → \(explanation.providerId) / \(explanation.upstreamModel) · fallback none"
|
|
131
|
+
: nil
|
|
132
|
+
}
|
|
133
|
+
let valid = explainedRoute != nil
|
|
134
|
+
_ = self.operations.update(snapshot, state: valid ? .succeeded : .failed, stage: "complete", progress: 1, summary: valid ? "Route explained" : "Route unavailable")
|
|
135
|
+
self.routesStatus.stringValue = explainedRoute
|
|
136
|
+
?? "\(model) · route missing or ambiguous · no fallback · \(self.structuredPublicDetail(json, fallback: result.output, fallbackNext: "Refresh catalog or choose a supported model"))"
|
|
137
|
+
self.routesStatus.textColor = valid ? .systemGreen : .systemRed
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|