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
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import os from 'node:os';
|
|
2
1
|
import path from 'node:path';
|
|
3
2
|
import { appendJsonlBounded } from '../fsx.js';
|
|
4
3
|
import { buildCodexExecutionPolicy, buildCodexSdkConfig } from './codex-sdk-config-policy.js';
|
|
@@ -6,7 +5,6 @@ import { buildCodexSdkEnv } from './codex-sdk-env-policy.js';
|
|
|
6
5
|
import { translateCodexSdkEvent } from './codex-event-translator.js';
|
|
7
6
|
import { codexTimeoutClassForRoute } from './codex-reliability-shield.js';
|
|
8
7
|
import { resolveOfficialCodexPackageRuntime } from '../codex-runtime/resolve-codex-runtime.js';
|
|
9
|
-
import { codexLbToolCatalogPath, ensureCodexLbToolCatalog, isCodexLbGpt56Model } from '../codex-lb/codex-lb-tool-catalog.js';
|
|
10
8
|
export async function runRealCodexSdkTask(input, policy) {
|
|
11
9
|
if (codexSdkTurnTimeoutMs(input) <= 0) {
|
|
12
10
|
return {
|
|
@@ -31,30 +29,11 @@ export async function runRealCodexSdkTask(input, policy) {
|
|
|
31
29
|
const Codex = mod.Codex || mod.default?.Codex || mod.default;
|
|
32
30
|
if (typeof Codex !== 'function')
|
|
33
31
|
throw new Error('Codex SDK export Codex not found');
|
|
34
|
-
const toolCatalog = await prepareCodexLbToolCatalog(input, policy);
|
|
35
|
-
if (toolCatalog.required && !toolCatalog.ok) {
|
|
36
|
-
return {
|
|
37
|
-
ok: false,
|
|
38
|
-
sdkThreadId: '',
|
|
39
|
-
sdkRunId: null,
|
|
40
|
-
events: [],
|
|
41
|
-
finalResponse: '',
|
|
42
|
-
structuredOutput: null,
|
|
43
|
-
blockers: [...new Set(['codex_lb_gpt56_tool_catalog_unavailable', ...(toolCatalog.blockers || [])])],
|
|
44
|
-
liveEventsWritten: false,
|
|
45
|
-
runtimeIdentity: runtime.identity,
|
|
46
|
-
executionPolicy: buildCodexExecutionPolicy(input),
|
|
47
|
-
raw: { tool_catalog: toolCatalog }
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
32
|
const executionPolicy = buildCodexExecutionPolicy(input);
|
|
51
|
-
const runtimeConfig = toolCatalog.ok && toolCatalog.path
|
|
52
|
-
? { ...policy.config, model_catalog_json: toolCatalog.path }
|
|
53
|
-
: policy.config;
|
|
54
33
|
const codex = new Codex({
|
|
55
34
|
codexPathOverride: runtime.identity.realpath,
|
|
56
35
|
env: policy.env,
|
|
57
|
-
config:
|
|
36
|
+
config: policy.config
|
|
58
37
|
});
|
|
59
38
|
const threadOptions = {
|
|
60
39
|
workingDirectory: input.cwd,
|
|
@@ -85,7 +64,7 @@ export async function runRealCodexSdkTask(input, policy) {
|
|
|
85
64
|
liveEventsWritten,
|
|
86
65
|
runtimeIdentity: runtime.identity,
|
|
87
66
|
executionPolicy,
|
|
88
|
-
raw: { aborted: true, hard_deadline_exceeded: true
|
|
67
|
+
raw: { aborted: true, hard_deadline_exceeded: true }
|
|
89
68
|
};
|
|
90
69
|
}
|
|
91
70
|
const controller = new AbortController();
|
|
@@ -121,7 +100,7 @@ export async function runRealCodexSdkTask(input, policy) {
|
|
|
121
100
|
liveEventsWritten,
|
|
122
101
|
runtimeIdentity: runtime.identity,
|
|
123
102
|
executionPolicy,
|
|
124
|
-
raw: { timeout_ms: timeoutMs, aborted: true
|
|
103
|
+
raw: { timeout_ms: timeoutMs, aborted: true }
|
|
125
104
|
};
|
|
126
105
|
}
|
|
127
106
|
finally {
|
|
@@ -140,7 +119,7 @@ export async function runRealCodexSdkTask(input, policy) {
|
|
|
140
119
|
liveEventsWritten,
|
|
141
120
|
runtimeIdentity: runtime.identity,
|
|
142
121
|
executionPolicy,
|
|
143
|
-
raw: { failed_event: failed
|
|
122
|
+
raw: { failed_event: failed }
|
|
144
123
|
};
|
|
145
124
|
}
|
|
146
125
|
const structuredOutput = parseStructuredOutput(finalResponse, Boolean(input.outputSchema));
|
|
@@ -155,7 +134,7 @@ export async function runRealCodexSdkTask(input, policy) {
|
|
|
155
134
|
runtimeIdentity: runtime.identity,
|
|
156
135
|
executionPolicy,
|
|
157
136
|
liveEventsWritten,
|
|
158
|
-
raw: { item_count: events.filter((event) => String(event?.type || '').startsWith('item.')).length
|
|
137
|
+
raw: { item_count: events.filter((event) => String(event?.type || '').startsWith('item.')).length }
|
|
159
138
|
};
|
|
160
139
|
}
|
|
161
140
|
export async function resolveCodexSdkRuntime(_input) {
|
|
@@ -166,28 +145,6 @@ export function codexSdkRuntimePolicies(input) {
|
|
|
166
145
|
const config = buildCodexSdkConfig(input);
|
|
167
146
|
return { env, config };
|
|
168
147
|
}
|
|
169
|
-
async function prepareCodexLbToolCatalog(input, policy) {
|
|
170
|
-
const provider = String(policy.config.model_provider || '');
|
|
171
|
-
const model = String(policy.config.model || input.model || '');
|
|
172
|
-
if (provider !== 'codex-lb' || !isCodexLbGpt56Model(model)) {
|
|
173
|
-
return { schema: 'sks.codex-lb-tool-catalog.v1', ok: true, required: false, status: 'not_required', path: null, blockers: [] };
|
|
174
|
-
}
|
|
175
|
-
const providers = policy.config.model_providers;
|
|
176
|
-
const baseUrl = String(providers?.['codex-lb']?.base_url || policy.env.CODEX_LB_BASE_URL || '');
|
|
177
|
-
const apiKey = String(policy.env.CODEX_LB_API_KEY || '');
|
|
178
|
-
const isolatedCodexHome = String(policy.env.CODEX_HOME || '');
|
|
179
|
-
if (!isolatedCodexHome) {
|
|
180
|
-
return { schema: 'sks.codex-lb-tool-catalog.v1', ok: false, required: true, status: 'blocked', path: null, blockers: ['codex_sdk_isolated_codex_home_missing'] };
|
|
181
|
-
}
|
|
182
|
-
const sharedCodexHome = String(process.env.CODEX_HOME || path.join(os.homedir(), '.codex'));
|
|
183
|
-
return ensureCodexLbToolCatalog({
|
|
184
|
-
codexHome: isolatedCodexHome,
|
|
185
|
-
outputPath: codexLbToolCatalogPath(sharedCodexHome),
|
|
186
|
-
baseUrl,
|
|
187
|
-
apiKey,
|
|
188
|
-
timeoutMs: 5000
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
148
|
export function codexSdkTurnTimeoutMs(input, nowMs = Date.now()) {
|
|
192
149
|
const explicit = Number(process.env.SKS_CODEX_SDK_TURN_TIMEOUT_MS);
|
|
193
150
|
const timeoutClass = codexTimeoutClassForRoute(input.route, input.reliabilityPolicy?.timeoutClass || (input.tier === 'orchestrator' ? 'long' : 'standard'));
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { appendJsonlBounded, ensureDir, nowIso, packageRoot, writeJsonAtomic } from '../fsx.js';
|
|
4
|
-
import { writeCodexConfigGuarded } from '../codex/codex-config-guard.js';
|
|
5
4
|
import { validateJsonSchemaRecursive } from '../json-schema-validator.js';
|
|
6
5
|
import { resolveCodexOutputSchema } from './codex-output-schemas.js';
|
|
7
6
|
import { detectCodexSdkCapability } from './codex-sdk-capability.js';
|
|
@@ -18,7 +17,7 @@ import { readLocalModelConfig } from '../agents/ollama-worker-config.js';
|
|
|
18
17
|
import { runLocalLlmTask } from '../local-llm/local-llm-control-adapter.js';
|
|
19
18
|
import { detectPythonCodexSdkCapability, runPythonCodexSdkTask } from './python-codex-sdk-adapter.js';
|
|
20
19
|
import { defaultModelCallBudget, withModelCallSlot } from './model-call-concurrency.js';
|
|
21
|
-
import {
|
|
20
|
+
import { inspectDesktopBridgeSdkLaunchGuard, stripRetiredDirectProviderEnv } from './desktop-bridge-launch-guard.js';
|
|
22
21
|
import { prepareNativeCodexAuthBridge } from './codex-sdk-env-policy.js';
|
|
23
22
|
export async function runCodexTask(input) {
|
|
24
23
|
const root = path.resolve(input.mutationLedgerRoot);
|
|
@@ -35,6 +34,7 @@ export async function runCodexTask(input) {
|
|
|
35
34
|
const capability = await detectCodexSdkCapability();
|
|
36
35
|
const sandbox = mapCodexSdkSandboxPolicy(task);
|
|
37
36
|
const runtime = codexSdkRuntimePolicies(task);
|
|
37
|
+
runtime.env.env = stripRetiredDirectProviderEnv(runtime.env.env);
|
|
38
38
|
const bundledCodex = resolveBundledCodexBinary();
|
|
39
39
|
if (bundledCodex && !runtime.env.env.SKS_PYTHON_CODEX_SDK_CODEX_BIN)
|
|
40
40
|
runtime.env.env.SKS_PYTHON_CODEX_SDK_CODEX_BIN = bundledCodex;
|
|
@@ -48,18 +48,15 @@ export async function runCodexTask(input) {
|
|
|
48
48
|
runtime.env.proof.home = runtime.env.env.HOME;
|
|
49
49
|
runtime.env.proof.codex_home = runtime.env.env.CODEX_HOME;
|
|
50
50
|
}
|
|
51
|
-
const
|
|
51
|
+
const desktopBridgeLaunchGuard = inspectDesktopBridgeSdkLaunchGuard({
|
|
52
52
|
config: runtime.config,
|
|
53
|
-
env: runtime.env.env
|
|
54
|
-
overrideEnv: process.env
|
|
53
|
+
env: runtime.env.env
|
|
55
54
|
});
|
|
56
|
-
if (codexLbToolOutputRecovery.ok)
|
|
57
|
-
await ensurePythonCodexLbConfig(runtime.env.env, runtime.config);
|
|
58
55
|
const blockers = [
|
|
59
56
|
...(capability.ok || fakeAllowed ? [] : capability.blockers),
|
|
60
57
|
...(sandbox.ok ? [] : sandbox.blockers),
|
|
61
58
|
...(nativeCodexAuthBridge.ok ? [] : nativeCodexAuthBridge.blockers),
|
|
62
|
-
...(
|
|
59
|
+
...(desktopBridgeLaunchGuard.ok ? [] : desktopBridgeLaunchGuard.blockers)
|
|
63
60
|
];
|
|
64
61
|
let adapterResult = null;
|
|
65
62
|
let nativeAuthCleanupBlockers = [];
|
|
@@ -149,7 +146,7 @@ export async function runCodexTask(input) {
|
|
|
149
146
|
workerResultPath,
|
|
150
147
|
patchEnvelopePath,
|
|
151
148
|
blockers: finalBlockers,
|
|
152
|
-
|
|
149
|
+
desktop_bridge_launch_guard: desktopBridgeLaunchGuard,
|
|
153
150
|
reliabilityShield: adapterResult?.reliabilityShield || null,
|
|
154
151
|
capacityFallback: adapterResult?.reliabilityShield?.selected_model_capacity_fallback === true,
|
|
155
152
|
modelCapacityRetryCount: Number(adapterResult?.reliabilityShield?.model_capacity_retry_count || 0),
|
|
@@ -185,7 +182,7 @@ export async function runCodexTask(input) {
|
|
|
185
182
|
capacity_fallback_selected: result.capacityFallback === true,
|
|
186
183
|
model_capacity_retry_count: result.modelCapacityRetryCount,
|
|
187
184
|
native_codex_auth_bridge: nativeCodexAuthBridge.proof,
|
|
188
|
-
|
|
185
|
+
desktop_bridge_launch_guard: desktopBridgeLaunchGuard
|
|
189
186
|
},
|
|
190
187
|
config: runtime.config,
|
|
191
188
|
reliabilityShield: adapterResult?.reliabilityShield || null,
|
|
@@ -197,6 +194,7 @@ export async function runCodexTask(input) {
|
|
|
197
194
|
async function runPythonControlTask(root, task, schema, routerDecision) {
|
|
198
195
|
const capability = await detectPythonCodexSdkCapability();
|
|
199
196
|
const runtime = codexSdkRuntimePolicies(task);
|
|
197
|
+
runtime.env.env = stripRetiredDirectProviderEnv(runtime.env.env);
|
|
200
198
|
if (runtime.env.env.HOME)
|
|
201
199
|
await ensureDir(runtime.env.env.HOME);
|
|
202
200
|
if (runtime.env.env.CODEX_HOME)
|
|
@@ -207,15 +205,14 @@ async function runPythonControlTask(root, task, schema, routerDecision) {
|
|
|
207
205
|
runtime.env.proof.home = runtime.env.env.HOME;
|
|
208
206
|
runtime.env.proof.codex_home = runtime.env.env.CODEX_HOME;
|
|
209
207
|
}
|
|
210
|
-
const
|
|
208
|
+
const desktopBridgeLaunchGuard = inspectDesktopBridgeSdkLaunchGuard({
|
|
211
209
|
config: runtime.config,
|
|
212
|
-
env: runtime.env.env
|
|
213
|
-
overrideEnv: process.env
|
|
210
|
+
env: runtime.env.env
|
|
214
211
|
});
|
|
215
212
|
let adapterResult;
|
|
216
213
|
let nativeAuthCleanupBlockers = [];
|
|
217
214
|
try {
|
|
218
|
-
adapterResult =
|
|
215
|
+
adapterResult = desktopBridgeLaunchGuard.ok && nativeCodexAuthBridge.ok && (capability.ok || fakeAllowed)
|
|
219
216
|
? await withModelCallSlot({
|
|
220
217
|
root,
|
|
221
218
|
missionId: task.missionId,
|
|
@@ -234,7 +231,7 @@ async function runPythonControlTask(root, task, schema, routerDecision) {
|
|
|
234
231
|
threadId: '',
|
|
235
232
|
turnId: '',
|
|
236
233
|
blockers: [
|
|
237
|
-
...(
|
|
234
|
+
...(desktopBridgeLaunchGuard.ok ? [] : desktopBridgeLaunchGuard.blockers),
|
|
238
235
|
...(nativeCodexAuthBridge.ok ? [] : nativeCodexAuthBridge.blockers),
|
|
239
236
|
...(capability.ok || fakeAllowed ? [] : capability.blockers)
|
|
240
237
|
],
|
|
@@ -294,7 +291,7 @@ async function runPythonControlTask(root, task, schema, routerDecision) {
|
|
|
294
291
|
structured_output_valid: validation.ok,
|
|
295
292
|
worker_result_path: workerResultPath,
|
|
296
293
|
native_codex_auth_bridge: nativeCodexAuthBridge.proof,
|
|
297
|
-
|
|
294
|
+
desktop_bridge_launch_guard: desktopBridgeLaunchGuard,
|
|
298
295
|
blockers: finalBlockers
|
|
299
296
|
});
|
|
300
297
|
const result = {
|
|
@@ -309,7 +306,7 @@ async function runPythonControlTask(root, task, schema, routerDecision) {
|
|
|
309
306
|
patchEnvelopePath,
|
|
310
307
|
pythonSdkProofPath,
|
|
311
308
|
blockers: finalBlockers,
|
|
312
|
-
|
|
309
|
+
desktop_bridge_launch_guard: desktopBridgeLaunchGuard,
|
|
313
310
|
reliabilityShield: {},
|
|
314
311
|
ultraRouterDecision: routerDecision,
|
|
315
312
|
outputSchemaId: task.outputSchemaId,
|
|
@@ -343,7 +340,7 @@ async function runPythonControlTask(root, task, schema, routerDecision) {
|
|
|
343
340
|
python_bin: capability.python_bin,
|
|
344
341
|
python_version: capability.python_version,
|
|
345
342
|
native_codex_auth_bridge: nativeCodexAuthBridge.proof,
|
|
346
|
-
|
|
343
|
+
desktop_bridge_launch_guard: desktopBridgeLaunchGuard
|
|
347
344
|
},
|
|
348
345
|
config: { ...runtime.config, backend: 'python-codex-sdk', package_name: capability.package_name, import_name: capability.import_name },
|
|
349
346
|
reliabilityShield: null,
|
|
@@ -536,7 +533,7 @@ function isRunFailureBlocker(blockers) {
|
|
|
536
533
|
|| text.startsWith('native_codex_auth_cleanup_failed')
|
|
537
534
|
|| text.startsWith('local_llm_generate_failed')
|
|
538
535
|
|| text.startsWith('local_llm_eligibility_blocked')
|
|
539
|
-
|| text.startsWith('
|
|
536
|
+
|| text.startsWith('desktop_bridge_launch_')
|
|
540
537
|
|| text.endsWith('_adapter_reported_failure')
|
|
541
538
|
|| text === 'codex_reliability_shield_failed'
|
|
542
539
|
|| text === 'codex_reliability_fatal_error_no_retry'
|
|
@@ -578,47 +575,6 @@ function parseStructuredOutput(text) {
|
|
|
578
575
|
return null;
|
|
579
576
|
}
|
|
580
577
|
}
|
|
581
|
-
async function ensurePythonCodexLbConfig(env, config) {
|
|
582
|
-
const codexHome = env.CODEX_HOME;
|
|
583
|
-
const lbBaseUrl = normalizeCodexLbBaseUrl(env.CODEX_LB_BASE_URL);
|
|
584
|
-
if (!codexHome || !lbBaseUrl || !env.CODEX_LB_API_KEY)
|
|
585
|
-
return;
|
|
586
|
-
const model = String(config.model || env.SKS_CODEX_MODEL || env.CODEX_MODEL || '').trim();
|
|
587
|
-
const text = [
|
|
588
|
-
...(model ? [`model = ${tomlQuote(model)}`] : []),
|
|
589
|
-
'model_provider = "codex-lb"',
|
|
590
|
-
'service_tier = "fast"',
|
|
591
|
-
`model_reasoning_effort = ${tomlQuote(String(config.model_reasoning_effort || env.SKS_CODEX_REASONING || env.CODEX_MODEL_REASONING_EFFORT || 'minimal'))}`,
|
|
592
|
-
'approval_policy = "never"',
|
|
593
|
-
'',
|
|
594
|
-
'[model_providers.codex-lb]',
|
|
595
|
-
'name = "codex-lb"',
|
|
596
|
-
`base_url = ${tomlQuote(lbBaseUrl)}`,
|
|
597
|
-
'wire_api = "responses"',
|
|
598
|
-
'env_key = "CODEX_LB_API_KEY"',
|
|
599
|
-
'supports_websockets = true',
|
|
600
|
-
'requires_openai_auth = false',
|
|
601
|
-
''
|
|
602
|
-
].join('\n');
|
|
603
|
-
const configPath = path.join(codexHome, 'config.toml');
|
|
604
|
-
await writeCodexConfigGuarded({
|
|
605
|
-
configPath,
|
|
606
|
-
cause: 'python-codex-lb-config',
|
|
607
|
-
mutate: () => text
|
|
608
|
-
});
|
|
609
|
-
}
|
|
610
|
-
function normalizeCodexLbBaseUrl(value) {
|
|
611
|
-
let host = String(value || '').trim();
|
|
612
|
-
if (!host)
|
|
613
|
-
return '';
|
|
614
|
-
if (!/^[a-z][a-z0-9+.-]*:\/\//i.test(host))
|
|
615
|
-
host = `https://${host}`;
|
|
616
|
-
host = host.replace(/\/+$/, '');
|
|
617
|
-
return /\/backend-api\/codex$/i.test(host) ? host : `${host}/backend-api/codex`;
|
|
618
|
-
}
|
|
619
|
-
function tomlQuote(value) {
|
|
620
|
-
return JSON.stringify(value);
|
|
621
|
-
}
|
|
622
578
|
function resolveBundledCodexBinary() {
|
|
623
579
|
const platform = process.platform;
|
|
624
580
|
const arch = process.arch;
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { parseCodexConfigToml } from '../codex/codex-config-toml.js';
|
|
4
|
+
import { readText } from '../fsx.js';
|
|
5
|
+
export const DESKTOP_BRIDGE_LAUNCH_GUARD_SCHEMA = 'sks.desktop-bridge-launch-guard.v1';
|
|
6
|
+
export const DESKTOP_BRIDGE_DIRECT_PROVIDER_SELECTION_RETIRED = 'desktop_bridge_direct_provider_selection_retired';
|
|
7
|
+
export function inspectDesktopBridgeSdkLaunchGuard(input) {
|
|
8
|
+
return guardForSelectedProvider(stringValue(input.config.model_provider));
|
|
9
|
+
}
|
|
10
|
+
export async function inspectDesktopBridgeCliLaunchGuard(input) {
|
|
11
|
+
const env = input.env || process.env;
|
|
12
|
+
const args = (input.cliArgs || []).map((arg) => String(arg));
|
|
13
|
+
if (args.includes('--oss'))
|
|
14
|
+
return allowedGuard(null);
|
|
15
|
+
const effectiveRoot = effectiveCodexWorkingRoot(input.root, args);
|
|
16
|
+
if (!effectiveRoot.ok) {
|
|
17
|
+
return blockedGuard('working_root_blocked', null, effectiveRoot.blockers);
|
|
18
|
+
}
|
|
19
|
+
const codexHome = path.resolve(String(env.CODEX_HOME || path.join(env.HOME || os.homedir(), '.codex')));
|
|
20
|
+
const ignoreUserConfig = args.includes('--ignore-user-config');
|
|
21
|
+
const profileName = ignoreUserConfig ? null : cliOptionValue(args, ['--profile', '-p', '-P']);
|
|
22
|
+
const profileConfigPath = profileName && safeProfileName(profileName)
|
|
23
|
+
? path.join(codexHome, `${profileName}.config.toml`)
|
|
24
|
+
: null;
|
|
25
|
+
const userConfig = ignoreUserConfig
|
|
26
|
+
? configLayer('', 'user')
|
|
27
|
+
: configLayer(await readText(path.join(codexHome, 'config.toml'), '').catch(() => ''), 'user');
|
|
28
|
+
const profileConfig = profileConfigPath
|
|
29
|
+
? configLayer(await readText(profileConfigPath, '').catch(() => ''), 'profile')
|
|
30
|
+
: configLayer('', 'profile');
|
|
31
|
+
const projectConfigPath = path.join(effectiveRoot.root, '.codex', 'config.toml');
|
|
32
|
+
const projectConfig = path.resolve(projectConfigPath) === path.resolve(path.join(codexHome, 'config.toml'))
|
|
33
|
+
? configLayer('', 'project')
|
|
34
|
+
: configLayer(await readText(projectConfigPath, '').catch(() => ''), 'project');
|
|
35
|
+
const override = cliModelProviderOverride(args);
|
|
36
|
+
const layers = [userConfig, profileConfig, projectConfig];
|
|
37
|
+
const selectedProvider = projectConfig.modelProvider
|
|
38
|
+
?? profileConfig.modelProvider
|
|
39
|
+
?? userConfig.modelProvider
|
|
40
|
+
?? null;
|
|
41
|
+
const parseBlockers = layers
|
|
42
|
+
.filter((layer) => layer.parseFailed && layer.rawSelectsRetiredProvider)
|
|
43
|
+
.map((layer) => `desktop_bridge_launch_config_parse_failed:${layer.source}`);
|
|
44
|
+
if (parseBlockers.length > 0) {
|
|
45
|
+
return blockedGuard('config_parse_blocked', selectedProvider, parseBlockers);
|
|
46
|
+
}
|
|
47
|
+
const historicalSelection = layers
|
|
48
|
+
.map((layer) => layer.modelProvider)
|
|
49
|
+
.find((provider) => provider === 'codex-lb' || provider === 'openrouter');
|
|
50
|
+
if (historicalSelection)
|
|
51
|
+
return guardForSelectedProvider(historicalSelection);
|
|
52
|
+
return guardForSelectedProvider(override ?? selectedProvider);
|
|
53
|
+
}
|
|
54
|
+
export async function withDesktopBridgeCliLaunchGuard(input, launch) {
|
|
55
|
+
const sanitizedEnv = stripRetiredDirectProviderEnv(input.env || process.env);
|
|
56
|
+
const desktopBridgeLaunchGuard = await inspectDesktopBridgeCliLaunchGuard({
|
|
57
|
+
...input,
|
|
58
|
+
env: sanitizedEnv
|
|
59
|
+
});
|
|
60
|
+
if (!desktopBridgeLaunchGuard.ok) {
|
|
61
|
+
return { launched: false, desktopBridgeLaunchGuard, value: null };
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
launched: true,
|
|
65
|
+
desktopBridgeLaunchGuard,
|
|
66
|
+
value: await launch(sanitizedEnv)
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
export function stripRetiredDirectProviderEnv(env) {
|
|
70
|
+
const sanitized = { ...env };
|
|
71
|
+
for (const key of Object.keys(sanitized)) {
|
|
72
|
+
if (/^CODEX_LB_/i.test(key))
|
|
73
|
+
delete sanitized[key];
|
|
74
|
+
}
|
|
75
|
+
return sanitized;
|
|
76
|
+
}
|
|
77
|
+
export function desktopBridgeLaunchBlockedProcessResult(guard) {
|
|
78
|
+
const stderr = desktopBridgeLaunchBlockedMessage(guard);
|
|
79
|
+
return {
|
|
80
|
+
code: 78,
|
|
81
|
+
stdout: '',
|
|
82
|
+
stderr,
|
|
83
|
+
stdoutBytes: 0,
|
|
84
|
+
stderrBytes: Buffer.byteLength(stderr),
|
|
85
|
+
truncated: false,
|
|
86
|
+
timedOut: false,
|
|
87
|
+
desktop_bridge_launch_guard: guard
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
export function desktopBridgeLaunchBlockedMessage(guard) {
|
|
91
|
+
return [
|
|
92
|
+
'Codex launch blocked: direct provider selection is retired; managed routing must use Desktop Bridge.',
|
|
93
|
+
...guard.blockers.map((blocker) => `blocker: ${blocker}`),
|
|
94
|
+
...guard.operator_actions
|
|
95
|
+
].join('\n');
|
|
96
|
+
}
|
|
97
|
+
export function effectiveCodexWorkingRoot(fallbackRoot, args) {
|
|
98
|
+
const base = path.resolve(fallbackRoot);
|
|
99
|
+
let selected = null;
|
|
100
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
101
|
+
const arg = args[index] || '';
|
|
102
|
+
if (arg === '--')
|
|
103
|
+
break;
|
|
104
|
+
if (arg === '-C' || arg === '--cd') {
|
|
105
|
+
const next = String(args[index + 1] || '').trim();
|
|
106
|
+
if (!next || next.startsWith('-')) {
|
|
107
|
+
return { ok: false, root: base, blockers: ['desktop_bridge_launch_working_root_value_missing'] };
|
|
108
|
+
}
|
|
109
|
+
selected = next;
|
|
110
|
+
index += 1;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (arg.startsWith('--cd=') || arg.startsWith('-C=')) {
|
|
114
|
+
const value = arg.slice(arg.indexOf('=') + 1).trim();
|
|
115
|
+
if (!value) {
|
|
116
|
+
return { ok: false, root: base, blockers: ['desktop_bridge_launch_working_root_value_missing'] };
|
|
117
|
+
}
|
|
118
|
+
selected = value;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return { ok: true, root: selected ? path.resolve(base, selected) : base, blockers: [] };
|
|
122
|
+
}
|
|
123
|
+
function configLayer(text, source) {
|
|
124
|
+
const raw = String(text || '');
|
|
125
|
+
if (!raw.trim()) {
|
|
126
|
+
return { source, modelProvider: null, parseFailed: false, rawSelectsRetiredProvider: false };
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
const parsed = parseCodexConfigToml(raw);
|
|
130
|
+
return {
|
|
131
|
+
source,
|
|
132
|
+
modelProvider: stringValue(parsed.model_provider),
|
|
133
|
+
parseFailed: false,
|
|
134
|
+
rawSelectsRetiredProvider: false
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
return {
|
|
139
|
+
source,
|
|
140
|
+
modelProvider: null,
|
|
141
|
+
parseFailed: true,
|
|
142
|
+
rawSelectsRetiredProvider: /^\s*model_provider\s*=\s*(?:"(?:codex-lb|openrouter)"|'(?:codex-lb|openrouter)'|(?:codex-lb|openrouter))\s*(?:#.*)?$/mi.test(raw)
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function cliModelProviderOverride(args) {
|
|
147
|
+
let modelProvider = null;
|
|
148
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
149
|
+
const arg = args[index] || '';
|
|
150
|
+
let override = null;
|
|
151
|
+
if (arg === '-c' || arg === '--config') {
|
|
152
|
+
override = args[index + 1] || '';
|
|
153
|
+
index += 1;
|
|
154
|
+
}
|
|
155
|
+
else if (arg.startsWith('--config='))
|
|
156
|
+
override = arg.slice('--config='.length);
|
|
157
|
+
else if (arg.startsWith('-c='))
|
|
158
|
+
override = arg.slice(3);
|
|
159
|
+
if (!override)
|
|
160
|
+
continue;
|
|
161
|
+
const equals = override.indexOf('=');
|
|
162
|
+
if (equals < 1 || normalizeDottedKey(override.slice(0, equals)) !== 'model_provider')
|
|
163
|
+
continue;
|
|
164
|
+
modelProvider = stringValue(parseCliTomlValue(override.slice(equals + 1)));
|
|
165
|
+
}
|
|
166
|
+
return modelProvider;
|
|
167
|
+
}
|
|
168
|
+
function parseCliTomlValue(raw) {
|
|
169
|
+
try {
|
|
170
|
+
return parseCodexConfigToml(`value = ${raw}\n`).value;
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return String(raw || '').trim();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function guardForSelectedProvider(selectedProvider) {
|
|
177
|
+
if (selectedProvider !== 'codex-lb' && selectedProvider !== 'openrouter') {
|
|
178
|
+
return allowedGuard(selectedProvider);
|
|
179
|
+
}
|
|
180
|
+
return blockedGuard('direct_provider_selection_retired', selectedProvider, [DESKTOP_BRIDGE_DIRECT_PROVIDER_SELECTION_RETIRED]);
|
|
181
|
+
}
|
|
182
|
+
function allowedGuard(selectedProvider) {
|
|
183
|
+
return {
|
|
184
|
+
schema: DESKTOP_BRIDGE_LAUNCH_GUARD_SCHEMA,
|
|
185
|
+
ok: true,
|
|
186
|
+
status: 'allowed',
|
|
187
|
+
selected_provider: selectedProvider,
|
|
188
|
+
blockers: [],
|
|
189
|
+
warnings: [],
|
|
190
|
+
operator_actions: []
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
function blockedGuard(status, selectedProvider, blockers) {
|
|
194
|
+
return {
|
|
195
|
+
schema: DESKTOP_BRIDGE_LAUNCH_GUARD_SCHEMA,
|
|
196
|
+
ok: false,
|
|
197
|
+
status,
|
|
198
|
+
selected_provider: selectedProvider,
|
|
199
|
+
blockers,
|
|
200
|
+
warnings: ['historical_direct_provider_selection_requires_bridge_migration'],
|
|
201
|
+
operator_actions: [
|
|
202
|
+
'Run `sks bridge ensure --json` to migrate SKS-owned routing to the managed Desktop Bridge.',
|
|
203
|
+
'If the direct provider selection is user-owned, review and remove it manually before retrying.'
|
|
204
|
+
]
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function cliOptionValue(args, names) {
|
|
208
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
209
|
+
const arg = args[index] || '';
|
|
210
|
+
if (names.includes(arg))
|
|
211
|
+
return String(args[index + 1] || '').trim() || null;
|
|
212
|
+
for (const name of names) {
|
|
213
|
+
if (arg.startsWith(`${name}=`))
|
|
214
|
+
return arg.slice(name.length + 1).trim() || null;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
function safeProfileName(value) {
|
|
220
|
+
return /^[A-Za-z0-9_.-]{1,128}$/.test(value);
|
|
221
|
+
}
|
|
222
|
+
function normalizeDottedKey(value) {
|
|
223
|
+
return String(value || '').trim().replace(/["']/g, '').replace(/\s+/g, '');
|
|
224
|
+
}
|
|
225
|
+
function stringValue(value) {
|
|
226
|
+
return typeof value === 'string' && value.trim() ? value.trim() : null;
|
|
227
|
+
}
|
|
@@ -3,7 +3,7 @@ import fsp from 'node:fs/promises';
|
|
|
3
3
|
import { ensureDir, exists, packageRoot, readJson, runProcess, which } from './fsx.js';
|
|
4
4
|
import { codexVersionPolicy, compareSemverLike, parseCodexVersionText } from './codex-compat/codex-version-policy.js';
|
|
5
5
|
import { validateJsonSchemaRecursive } from './json-schema-validator.js';
|
|
6
|
-
import {
|
|
6
|
+
import { inspectDesktopBridgeCliLaunchGuard, stripRetiredDirectProviderEnv } from './codex-control/desktop-bridge-launch-guard.js';
|
|
7
7
|
import { prepareCodexAppServerRuntimeEnv } from './codex-control/codex-app-server-runtime-env.js';
|
|
8
8
|
export async function detectCodexExecOutputSchemaSyntax(opts = {}) {
|
|
9
9
|
const codexBin = opts.codexBin || await which('codex').catch(() => null);
|
|
@@ -170,17 +170,15 @@ export async function buildCodexExecResumeOutputSchemaArgs(input) {
|
|
|
170
170
|
}
|
|
171
171
|
export async function runCodexExecResumeWithOutputSchema(input, opts = {}) {
|
|
172
172
|
const root = opts.cwd || packageRoot();
|
|
173
|
-
const env = await (opts.prepareCodexRuntimeEnvImpl || prepareCodexAppServerRuntimeEnv)({
|
|
173
|
+
const env = stripRetiredDirectProviderEnv(await (opts.prepareCodexRuntimeEnvImpl || prepareCodexAppServerRuntimeEnv)({
|
|
174
174
|
env: opts.env || process.env
|
|
175
|
-
});
|
|
176
|
-
const
|
|
175
|
+
}));
|
|
176
|
+
const launchGuard = await inspectDesktopBridgeCliLaunchGuard({
|
|
177
177
|
root,
|
|
178
178
|
env,
|
|
179
|
-
cliArgs: input.extraArgs || []
|
|
180
|
-
...(opts.recoveryFetch ? { fetchImpl: opts.recoveryFetch } : {}),
|
|
181
|
-
...(opts.recoveryTimeoutMs === undefined ? {} : { timeoutMs: opts.recoveryTimeoutMs })
|
|
179
|
+
cliArgs: input.extraArgs || []
|
|
182
180
|
});
|
|
183
|
-
if (!
|
|
181
|
+
if (!launchGuard.ok) {
|
|
184
182
|
return {
|
|
185
183
|
schema: 'sks.codex-exec-output-schema-run.v1',
|
|
186
184
|
ok: false,
|
|
@@ -189,13 +187,13 @@ export async function runCodexExecResumeWithOutputSchema(input, opts = {}) {
|
|
|
189
187
|
codex_bin: opts.codexBin || null,
|
|
190
188
|
output_file: null,
|
|
191
189
|
parsed_json: null,
|
|
192
|
-
blocker: structuredOutputBlocker('
|
|
193
|
-
validation: { ok: false, issues: ['
|
|
190
|
+
blocker: structuredOutputBlocker('desktop_bridge_launch_guard_blocked', launchGuard.blockers.join(', ')),
|
|
191
|
+
validation: { ok: false, issues: ['desktop_bridge_launch_guard_blocked'] },
|
|
194
192
|
stdout_tail: '',
|
|
195
193
|
stderr_tail: '',
|
|
196
194
|
timed_out: false,
|
|
197
195
|
exit_code: null,
|
|
198
|
-
|
|
196
|
+
desktop_bridge_launch_guard: launchGuard
|
|
199
197
|
};
|
|
200
198
|
}
|
|
201
199
|
const availability = await detectCodexExecResumeOutputSchema({ codexBin: opts.codexBin || undefined });
|
|
@@ -215,7 +213,7 @@ export async function runCodexExecResumeWithOutputSchema(input, opts = {}) {
|
|
|
215
213
|
stderr_tail: '',
|
|
216
214
|
timed_out: false,
|
|
217
215
|
exit_code: null,
|
|
218
|
-
|
|
216
|
+
desktop_bridge_launch_guard: launchGuard
|
|
219
217
|
};
|
|
220
218
|
}
|
|
221
219
|
const outputFile = input.outputFile
|
|
@@ -253,7 +251,7 @@ export async function runCodexExecResumeWithOutputSchema(input, opts = {}) {
|
|
|
253
251
|
stderr_tail: redactCodexOutput(result.stderr).slice(-12_000),
|
|
254
252
|
timed_out: result.timedOut,
|
|
255
253
|
exit_code: result.code,
|
|
256
|
-
|
|
254
|
+
desktop_bridge_launch_guard: launchGuard
|
|
257
255
|
};
|
|
258
256
|
}
|
|
259
257
|
export function parseStructuredCodexOutput(text) {
|