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,91 +0,0 @@
|
|
|
1
|
-
import { normalizeCodexModelId, readTopLevelTomlString } from './codex-model-catalog.js';
|
|
2
|
-
export const CODEX_PROVIDER_MODE_MARKER_PREFIX = '# sks-managed-provider-mode:';
|
|
3
|
-
export const CODEX_NATIVE_PROVIDER_ID = 'openai';
|
|
4
|
-
const MODES = new Set(['chatgpt-oauth', 'codex-lb', 'openrouter']);
|
|
5
|
-
export function isCodexProviderMode(value) {
|
|
6
|
-
return MODES.has(String(value || '').trim());
|
|
7
|
-
}
|
|
8
|
-
export function readExplicitCodexProviderMode(configText) {
|
|
9
|
-
const values = String(configText || '')
|
|
10
|
-
.split('\n')
|
|
11
|
-
.map((line) => line.trim())
|
|
12
|
-
.filter((line) => line.startsWith(CODEX_PROVIDER_MODE_MARKER_PREFIX))
|
|
13
|
-
.map((line) => line.slice(CODEX_PROVIDER_MODE_MARKER_PREFIX.length).trim());
|
|
14
|
-
if (!values.length)
|
|
15
|
-
return { mode: null, blockers: ['provider_mode_not_explicit'] };
|
|
16
|
-
if (values.length !== 1)
|
|
17
|
-
return { mode: null, blockers: ['provider_mode_marker_conflict'] };
|
|
18
|
-
const mode = values[0];
|
|
19
|
-
if (!isCodexProviderMode(mode))
|
|
20
|
-
return { mode: null, blockers: ['provider_mode_marker_invalid'] };
|
|
21
|
-
return { mode, blockers: [] };
|
|
22
|
-
}
|
|
23
|
-
export function upsertExplicitCodexProviderMode(configText, mode) {
|
|
24
|
-
const lines = String(configText || '').split('\n');
|
|
25
|
-
const filtered = lines.filter((line) => !line.trim().startsWith(CODEX_PROVIDER_MODE_MARKER_PREFIX));
|
|
26
|
-
const marker = `${CODEX_PROVIDER_MODE_MARKER_PREFIX}${mode}`;
|
|
27
|
-
const firstContent = filtered.findIndex((line) => line.trim().length > 0);
|
|
28
|
-
if (firstContent < 0)
|
|
29
|
-
return `${marker}\n`;
|
|
30
|
-
filtered.splice(firstContent, 0, marker);
|
|
31
|
-
return `${filtered.join('\n').replace(/^\n+|\n+$/g, '')}\n`;
|
|
32
|
-
}
|
|
33
|
-
export function codexProviderModeState(configText) {
|
|
34
|
-
const explicit = readExplicitCodexProviderMode(configText);
|
|
35
|
-
const selectedProvider = readTopLevelTomlString(configText, 'model_provider');
|
|
36
|
-
const openAiBaseUrl = readTopLevelTomlString(configText, 'openai_base_url');
|
|
37
|
-
const loopbackConfigured = isLoopbackHttpUrl(openAiBaseUrl);
|
|
38
|
-
const loopbackRequired = explicit.mode === 'codex-lb' || explicit.mode === 'openrouter';
|
|
39
|
-
const blockers = [...explicit.blockers];
|
|
40
|
-
if (explicit.mode && selectedProvider !== CODEX_NATIVE_PROVIDER_ID) {
|
|
41
|
-
blockers.push('provider_mode_requires_builtin_openai');
|
|
42
|
-
}
|
|
43
|
-
if (loopbackRequired && !loopbackConfigured)
|
|
44
|
-
blockers.push('provider_mode_loopback_missing');
|
|
45
|
-
if (explicit.mode === 'chatgpt-oauth' && openAiBaseUrl) {
|
|
46
|
-
blockers.push('chatgpt_oauth_mode_loopback_still_configured');
|
|
47
|
-
}
|
|
48
|
-
return {
|
|
49
|
-
schema: 'sks.codex-provider-mode-state.v1',
|
|
50
|
-
mode: explicit.mode,
|
|
51
|
-
explicit: explicit.blockers.length === 0,
|
|
52
|
-
native_provider_selected: selectedProvider === CODEX_NATIVE_PROVIDER_ID,
|
|
53
|
-
loopback_required: loopbackRequired,
|
|
54
|
-
loopback_configured: loopbackConfigured,
|
|
55
|
-
auxiliary_oauth_required: loopbackRequired,
|
|
56
|
-
blockers: [...new Set(blockers)]
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
export function providerModeOwnsModel(mode, model) {
|
|
60
|
-
const normalized = normalizeCodexModelId(model);
|
|
61
|
-
if (!normalized)
|
|
62
|
-
return false;
|
|
63
|
-
if (mode === 'openrouter')
|
|
64
|
-
return normalized.includes('/');
|
|
65
|
-
return !normalized.includes('/');
|
|
66
|
-
}
|
|
67
|
-
export function assertProviderModeModel(mode, model, allowedModels) {
|
|
68
|
-
const normalized = normalizeCodexModelId(model);
|
|
69
|
-
if (!normalized)
|
|
70
|
-
throw new Error('provider_mode_model_invalid');
|
|
71
|
-
if (!providerModeOwnsModel(mode, normalized))
|
|
72
|
-
throw new Error('provider_mode_model_family_mismatch');
|
|
73
|
-
const allowed = new Set(allowedModels.map(normalizeCodexModelId).filter((entry) => Boolean(entry)));
|
|
74
|
-
if (!allowed.size)
|
|
75
|
-
throw new Error('provider_mode_model_catalog_empty');
|
|
76
|
-
if (!allowed.has(normalized))
|
|
77
|
-
throw new Error('provider_mode_model_not_allowed');
|
|
78
|
-
return normalized;
|
|
79
|
-
}
|
|
80
|
-
function isLoopbackHttpUrl(value) {
|
|
81
|
-
if (!value)
|
|
82
|
-
return false;
|
|
83
|
-
try {
|
|
84
|
-
const parsed = new URL(value);
|
|
85
|
-
const host = parsed.hostname.replace(/^\[|\]$/g, '').toLowerCase();
|
|
86
|
-
return parsed.protocol === 'http:' && (host === '127.0.0.1' || host === '::1' || host === 'localhost');
|
|
87
|
-
}
|
|
88
|
-
catch {
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { assertProviderModeModel } from './provider-mode.js';
|
|
2
|
-
export const PROVIDER_SESSION_SCHEMA = 'sks.provider-session.v1';
|
|
3
|
-
export function createProviderSessionPin(input) {
|
|
4
|
-
const sessionId = validSessionId(input.sessionId);
|
|
5
|
-
if (!sessionId)
|
|
6
|
-
throw new Error('provider_session_id_invalid');
|
|
7
|
-
if (input.parent) {
|
|
8
|
-
if (input.mode !== input.parent.mode)
|
|
9
|
-
throw new Error('provider_session_fork_mode_mismatch');
|
|
10
|
-
if (input.model !== input.parent.model)
|
|
11
|
-
throw new Error('provider_session_fork_model_mismatch');
|
|
12
|
-
if (stableModels(input.allowedModels).join('\0') !== stableModels(input.parent.allowed_models).join('\0')) {
|
|
13
|
-
throw new Error('provider_session_fork_catalog_mismatch');
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
const allowedModels = stableModels(input.allowedModels);
|
|
17
|
-
if (input.mode === 'chatgpt-oauth') {
|
|
18
|
-
if (!allowedModels.includes(input.model))
|
|
19
|
-
throw new Error('provider_session_model_not_allowed');
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
assertProviderModeModel(input.mode, input.model, allowedModels);
|
|
23
|
-
}
|
|
24
|
-
return {
|
|
25
|
-
schema: PROVIDER_SESSION_SCHEMA,
|
|
26
|
-
session_id: sessionId,
|
|
27
|
-
mode: input.mode,
|
|
28
|
-
model: input.model,
|
|
29
|
-
allowed_models: allowedModels,
|
|
30
|
-
created_at: input.createdAt || new Date().toISOString(),
|
|
31
|
-
parent_session_id: input.parent?.session_id || null
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
export function providerSessionStatus(input) {
|
|
35
|
-
if (!input.pin) {
|
|
36
|
-
return {
|
|
37
|
-
schema: 'sks.provider-session-status.v1',
|
|
38
|
-
ok: false,
|
|
39
|
-
status: 'migration_required',
|
|
40
|
-
session_mode: null,
|
|
41
|
-
new_session_default_mode: input.globalDefaultMode,
|
|
42
|
-
mode_changed_since_creation: null,
|
|
43
|
-
blockers: ['legacy_session_provider_mode_selection_required'],
|
|
44
|
-
action: 'Choose a mode explicitly, then start a new session.'
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
const modeChanged = input.pin.mode !== input.globalDefaultMode;
|
|
48
|
-
return {
|
|
49
|
-
schema: 'sks.provider-session-status.v1',
|
|
50
|
-
ok: true,
|
|
51
|
-
status: modeChanged ? 'pinned_while_default_changed' : 'pinned',
|
|
52
|
-
session_mode: input.pin.mode,
|
|
53
|
-
new_session_default_mode: input.globalDefaultMode,
|
|
54
|
-
mode_changed_since_creation: modeChanged,
|
|
55
|
-
blockers: [],
|
|
56
|
-
action: modeChanged
|
|
57
|
-
? `This session continues in ${input.pin.mode}; start a new session to use ${input.globalDefaultMode}.`
|
|
58
|
-
: `This session is pinned to ${input.pin.mode}.`
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
export function assertProviderSessionRequest(pin, input) {
|
|
62
|
-
if (pin.mode !== input.mode)
|
|
63
|
-
throw new Error('provider_session_mode_switch_forbidden');
|
|
64
|
-
if (!pin.allowed_models.includes(input.model))
|
|
65
|
-
throw new Error('provider_session_model_switch_forbidden');
|
|
66
|
-
}
|
|
67
|
-
export function classifyPinnedProviderFailure(status) {
|
|
68
|
-
if (status === 401 || status === 403) {
|
|
69
|
-
return { retry_allowed: false, stop_session: true, blocker: 'provider_session_authentication_failed', action: 'Verify this mode credential, then start a new session.' };
|
|
70
|
-
}
|
|
71
|
-
if (status === 402 || status === 429) {
|
|
72
|
-
return { retry_allowed: false, stop_session: true, blocker: 'provider_session_quota_or_rate_limit', action: 'Do not fail over accounts; resolve quota or start a new session explicitly.' };
|
|
73
|
-
}
|
|
74
|
-
if (status >= 500) {
|
|
75
|
-
return { retry_allowed: false, stop_session: true, blocker: 'provider_session_upstream_failed', action: 'Keep the pinned account and retry only after explicit user action.' };
|
|
76
|
-
}
|
|
77
|
-
return { retry_allowed: true, stop_session: false, blocker: null, action: null };
|
|
78
|
-
}
|
|
79
|
-
function stableModels(models) {
|
|
80
|
-
return [...new Set(models.map((model) => String(model || '').trim()).filter(Boolean))].sort();
|
|
81
|
-
}
|
|
82
|
-
function validSessionId(value) {
|
|
83
|
-
const id = String(value || '').trim();
|
|
84
|
-
return /^[A-Za-z0-9][A-Za-z0-9._:-]{0,199}$/.test(id) ? id : null;
|
|
85
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto';
|
|
2
|
-
import { assertProviderPolicyCompatible, stableArchitectureHash } from '../../architecture-hardening/contracts/contracts.js';
|
|
3
|
-
export function createSessionPin(input) {
|
|
4
|
-
if (!validId(input.sessionId))
|
|
5
|
-
throw new Error('session_pin_id_invalid');
|
|
6
|
-
const model = String(input.model || '').trim();
|
|
7
|
-
if (!input.policy.allowed_models.includes(model))
|
|
8
|
-
throw new Error('session_pin_model_not_allowed');
|
|
9
|
-
if ((input.policy.mode === 'openrouter') !== model.includes('/'))
|
|
10
|
-
throw new Error('session_pin_model_family_mismatch');
|
|
11
|
-
if (input.policy.mode === 'codex-lb' && !input.lbAffinityToken)
|
|
12
|
-
throw new Error('session_pin_lb_affinity_required');
|
|
13
|
-
if (input.policy.mode !== 'codex-lb' && input.lbAffinityToken)
|
|
14
|
-
throw new Error('session_pin_lb_affinity_forbidden');
|
|
15
|
-
return Object.freeze({
|
|
16
|
-
schema: 'sks.session-pin.v1',
|
|
17
|
-
session_id: input.sessionId,
|
|
18
|
-
mode: input.policy.mode,
|
|
19
|
-
model,
|
|
20
|
-
credential_class: input.policy.credential_class,
|
|
21
|
-
allowed_models: Object.freeze([...input.policy.allowed_models]),
|
|
22
|
-
lb_affinity_token_hash: input.lbAffinityToken ? createHash('sha256').update(input.lbAffinityToken).digest('hex') : null,
|
|
23
|
-
child_policy_hash: input.policy.child_policy_hash,
|
|
24
|
-
catalog_version: input.policy.catalog_version,
|
|
25
|
-
parent_session_id: input.parentSessionId || null
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
export function forkSessionPin(parent, sessionId) {
|
|
29
|
-
if (!validId(sessionId))
|
|
30
|
-
throw new Error('session_pin_id_invalid');
|
|
31
|
-
return Object.freeze({ ...parent, session_id: sessionId, parent_session_id: parent.session_id, allowed_models: Object.freeze([...parent.allowed_models]) });
|
|
32
|
-
}
|
|
33
|
-
export function resumeSessionPin(pin, policy) {
|
|
34
|
-
if (!pin)
|
|
35
|
-
return { schema: 'sks.session-resume-decision.v1', ok: false, status: 'migration_required', pin: null, blocker: 'session_pin_metadata_missing' };
|
|
36
|
-
const pinnedPolicy = {
|
|
37
|
-
schema: 'sks.provider-policy-snapshot.v1',
|
|
38
|
-
contract_version: policy.contract_version,
|
|
39
|
-
mode: pin.mode,
|
|
40
|
-
credential_class: pin.credential_class,
|
|
41
|
-
allowed_models: pin.allowed_models,
|
|
42
|
-
child_policy_hash: pin.child_policy_hash,
|
|
43
|
-
catalog_version: pin.catalog_version
|
|
44
|
-
};
|
|
45
|
-
try {
|
|
46
|
-
assertProviderPolicyCompatible(pinnedPolicy, policy);
|
|
47
|
-
}
|
|
48
|
-
catch (error) {
|
|
49
|
-
return { schema: 'sks.session-resume-decision.v1', ok: false, status: 'blocked', pin, blocker: error.message };
|
|
50
|
-
}
|
|
51
|
-
if (!pin.allowed_models.includes(pin.model))
|
|
52
|
-
return { schema: 'sks.session-resume-decision.v1', ok: false, status: 'blocked', pin, blocker: 'session_pin_model_restore_mismatch' };
|
|
53
|
-
return { schema: 'sks.session-resume-decision.v1', ok: true, status: 'resumable', pin, blocker: null };
|
|
54
|
-
}
|
|
55
|
-
export function sessionPinHash(pin) {
|
|
56
|
-
return stableArchitectureHash(pin);
|
|
57
|
-
}
|
|
58
|
-
export function assertSessionRequest(pin, input) {
|
|
59
|
-
if (pin.mode !== input.mode)
|
|
60
|
-
throw new Error('session_pin_mode_switch_forbidden');
|
|
61
|
-
if (pin.model !== input.model)
|
|
62
|
-
throw new Error('session_pin_model_switch_forbidden');
|
|
63
|
-
if (pin.child_policy_hash !== input.childPolicyHash)
|
|
64
|
-
throw new Error('session_pin_child_policy_mismatch');
|
|
65
|
-
}
|
|
66
|
-
function validId(value) {
|
|
67
|
-
return /^[A-Za-z0-9][A-Za-z0-9._:-]{0,199}$/.test(String(value || ''));
|
|
68
|
-
}
|
|
@@ -1,319 +0,0 @@
|
|
|
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
|
-
import { codexLbToolOutputRecoveryNotChecked, codexLbToolOutputRecoveryNotSelected, codexLbToolOutputRecoveryOverrideAcknowledged, probeCodexLbToolOutputRecovery } from '../codex-lb/codex-lb-tool-output-recovery.js';
|
|
6
|
-
import { normalizeCodexLbBaseUrl } from '../codex-lb/codex-lb-env.js';
|
|
7
|
-
export async function inspectCodexLbSdkLaunchRecovery(input) {
|
|
8
|
-
if (String(input.config.model_provider || '') !== 'codex-lb') {
|
|
9
|
-
return codexLbToolOutputRecoveryNotSelected();
|
|
10
|
-
}
|
|
11
|
-
const providers = input.config.model_providers;
|
|
12
|
-
const baseUrl = String(providers?.['codex-lb']?.base_url
|
|
13
|
-
|| input.env.CODEX_LB_BASE_URL
|
|
14
|
-
|| '');
|
|
15
|
-
return probeCodexLbToolOutputRecovery({
|
|
16
|
-
baseUrl,
|
|
17
|
-
...(input.fetchImpl ? { fetchImpl: input.fetchImpl } : {}),
|
|
18
|
-
...(input.timeoutMs === undefined ? {} : { timeoutMs: input.timeoutMs }),
|
|
19
|
-
allowUnverified: codexLbToolOutputRecoveryOverrideAcknowledged({
|
|
20
|
-
env: input.overrideEnv || input.env
|
|
21
|
-
})
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
export async function inspectCodexLbCliLaunchRecovery(input) {
|
|
25
|
-
const env = input.env || process.env;
|
|
26
|
-
const args = (input.cliArgs || []).map((arg) => String(arg));
|
|
27
|
-
const codexHome = path.resolve(String(env.CODEX_HOME || path.join(env.HOME || os.homedir(), '.codex')));
|
|
28
|
-
const userConfigPath = path.join(codexHome, 'config.toml');
|
|
29
|
-
const effectiveRoot = effectiveCodexWorkingRoot(input.root, args);
|
|
30
|
-
if (!effectiveRoot.ok)
|
|
31
|
-
return configParseBlocked(effectiveRoot.blockers);
|
|
32
|
-
const projectConfigPath = path.join(effectiveRoot.root, '.codex', 'config.toml');
|
|
33
|
-
const ignoreUserConfig = args.includes('--ignore-user-config');
|
|
34
|
-
const profileName = ignoreUserConfig ? null : cliOptionValue(args, ['--profile', '-p', '-P']);
|
|
35
|
-
const profileConfigPath = profileName && safeProfileName(profileName)
|
|
36
|
-
? path.join(codexHome, `${profileName}.config.toml`)
|
|
37
|
-
: null;
|
|
38
|
-
const userConfig = ignoreUserConfig
|
|
39
|
-
? configLayer('', 'user')
|
|
40
|
-
: configLayer(await readText(userConfigPath, '').catch(() => ''), 'user');
|
|
41
|
-
const profileConfig = profileConfigPath
|
|
42
|
-
? configLayer(await readText(profileConfigPath, '').catch(() => ''), 'profile')
|
|
43
|
-
: configLayer('', 'profile');
|
|
44
|
-
const projectConfig = path.resolve(projectConfigPath) === path.resolve(userConfigPath)
|
|
45
|
-
? configLayer('', 'project')
|
|
46
|
-
: configLayer(await readText(projectConfigPath, '').catch(() => ''), 'project');
|
|
47
|
-
const overrides = cliConfigOverrides(args);
|
|
48
|
-
const environmentSelectsCodexLb = env.SKS_PROVIDER === 'codex-lb' || env.SKS_USE_CODEX_LB === '1';
|
|
49
|
-
if (cliSelectsLocalProvider(args)) {
|
|
50
|
-
return codexLbToolOutputRecoveryNotSelected();
|
|
51
|
-
}
|
|
52
|
-
const loadedLayers = [userConfig, profileConfig, projectConfig];
|
|
53
|
-
const parseBlockers = loadedLayers
|
|
54
|
-
.filter((layer) => layer.parseFailed && layer.rawSelectsCodexLb)
|
|
55
|
-
.map((layer) => `codex_lb_launch_config_parse_failed:${layer.source}`);
|
|
56
|
-
if (parseBlockers.length > 0)
|
|
57
|
-
return configParseBlocked(parseBlockers);
|
|
58
|
-
if (projectConfig.hasMachineLocalProviderConfig) {
|
|
59
|
-
return projectProviderConfigBlocked();
|
|
60
|
-
}
|
|
61
|
-
if (overrides.modelProvider && overrides.modelProvider !== 'codex-lb') {
|
|
62
|
-
return codexLbToolOutputRecoveryNotSelected();
|
|
63
|
-
}
|
|
64
|
-
const selectedProvider = overrides.modelProvider
|
|
65
|
-
?? (environmentSelectsCodexLb ? 'codex-lb' : null)
|
|
66
|
-
?? profileConfig.modelProvider
|
|
67
|
-
?? userConfig.modelProvider
|
|
68
|
-
?? '';
|
|
69
|
-
if (selectedProvider !== 'codex-lb') {
|
|
70
|
-
return codexLbToolOutputRecoveryNotSelected();
|
|
71
|
-
}
|
|
72
|
-
const codexProcessSelectsCodexLb = overrides.modelProvider === 'codex-lb'
|
|
73
|
-
|| profileConfig.modelProvider === 'codex-lb'
|
|
74
|
-
|| userConfig.modelProvider === 'codex-lb';
|
|
75
|
-
if (environmentSelectsCodexLb && !codexProcessSelectsCodexLb) {
|
|
76
|
-
return environmentSelectionNotForwardedBlocked();
|
|
77
|
-
}
|
|
78
|
-
const baseUrl = overrides.baseUrl
|
|
79
|
-
?? profileConfig.baseUrl
|
|
80
|
-
?? userConfig.baseUrl
|
|
81
|
-
?? String(env.CODEX_LB_BASE_URL || '');
|
|
82
|
-
const verifiedProbe = reusableVerifiedProbeForBase(input.verifiedProbe, baseUrl);
|
|
83
|
-
if (verifiedProbe)
|
|
84
|
-
return verifiedProbe;
|
|
85
|
-
return probeCodexLbToolOutputRecovery({
|
|
86
|
-
baseUrl,
|
|
87
|
-
...(input.fetchImpl ? { fetchImpl: input.fetchImpl } : {}),
|
|
88
|
-
...(input.timeoutMs === undefined ? {} : { timeoutMs: input.timeoutMs }),
|
|
89
|
-
allowUnverified: input.allowUnverified === true
|
|
90
|
-
|| codexLbToolOutputRecoveryOverrideAcknowledged({ args, env })
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
function reusableVerifiedProbeForBase(value, selectedBaseUrl) {
|
|
94
|
-
if (!value || value.schema !== 'sks.codex-lb-tool-output-recovery.v1')
|
|
95
|
-
return null;
|
|
96
|
-
if (value.ok !== true || value.required !== true || value.verified !== true || value.supports_interrupted_tool_output_recovery !== true)
|
|
97
|
-
return null;
|
|
98
|
-
const verifiedBaseUrl = normalizeCodexLbBaseUrl(value.base_url);
|
|
99
|
-
const effectiveBaseUrl = normalizeCodexLbBaseUrl(selectedBaseUrl);
|
|
100
|
-
if (!verifiedBaseUrl || !effectiveBaseUrl || verifiedBaseUrl !== effectiveBaseUrl)
|
|
101
|
-
return null;
|
|
102
|
-
return value;
|
|
103
|
-
}
|
|
104
|
-
export async function withCodexLbCliLaunchRecovery(input, launch) {
|
|
105
|
-
const toolOutputRecovery = await inspectCodexLbCliLaunchRecovery(input);
|
|
106
|
-
if (!toolOutputRecovery.ok) {
|
|
107
|
-
return {
|
|
108
|
-
launched: false,
|
|
109
|
-
toolOutputRecovery,
|
|
110
|
-
value: null
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
return {
|
|
114
|
-
launched: true,
|
|
115
|
-
toolOutputRecovery,
|
|
116
|
-
value: await launch()
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
export function codexLbRecoveryBlockedProcessResult(probe) {
|
|
120
|
-
const stderr = codexLbRecoveryBlockedMessage(probe);
|
|
121
|
-
return {
|
|
122
|
-
code: 78,
|
|
123
|
-
stdout: '',
|
|
124
|
-
stderr,
|
|
125
|
-
stdoutBytes: 0,
|
|
126
|
-
stderrBytes: Buffer.byteLength(stderr),
|
|
127
|
-
truncated: false,
|
|
128
|
-
timedOut: false,
|
|
129
|
-
codexLbToolOutputRecovery: probe
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
export function codexLbRecoveryBlockedMessage(probe) {
|
|
133
|
-
if (probe.blockers.includes('codex_lb_launch_selection_not_forwarded')) {
|
|
134
|
-
return [
|
|
135
|
-
'Codex launch blocked: codex-lb was requested by the SKS environment but was not selected in the Codex process.',
|
|
136
|
-
...probe.blockers.map((blocker) => `blocker: ${blocker}`),
|
|
137
|
-
...probe.operator_actions
|
|
138
|
-
].join('\n');
|
|
139
|
-
}
|
|
140
|
-
return [
|
|
141
|
-
'Codex launch blocked: selected codex-lb interrupted tool-output recovery is not verified.',
|
|
142
|
-
...probe.blockers.map((blocker) => `blocker: ${blocker}`),
|
|
143
|
-
...probe.operator_actions
|
|
144
|
-
].join('\n');
|
|
145
|
-
}
|
|
146
|
-
function configLayer(text, source) {
|
|
147
|
-
const raw = String(text || '');
|
|
148
|
-
if (!raw.trim()) {
|
|
149
|
-
return {
|
|
150
|
-
source,
|
|
151
|
-
modelProvider: null,
|
|
152
|
-
baseUrl: null,
|
|
153
|
-
parseFailed: false,
|
|
154
|
-
rawSelectsCodexLb: false,
|
|
155
|
-
hasMachineLocalProviderConfig: false
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
try {
|
|
159
|
-
const parsed = parseCodexConfigToml(raw);
|
|
160
|
-
return {
|
|
161
|
-
source,
|
|
162
|
-
modelProvider: stringValue(parsed.model_provider),
|
|
163
|
-
baseUrl: stringValue(parsed.model_providers?.['codex-lb']?.base_url),
|
|
164
|
-
parseFailed: false,
|
|
165
|
-
rawSelectsCodexLb: false,
|
|
166
|
-
hasMachineLocalProviderConfig: source === 'project' && Boolean(stringValue(parsed.model_provider)
|
|
167
|
-
|| (parsed.model_providers && typeof parsed.model_providers === 'object' && Object.keys(parsed.model_providers).length)
|
|
168
|
-
|| stringValue(parsed.openai_base_url)
|
|
169
|
-
|| stringValue(parsed.chatgpt_base_url))
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
catch {
|
|
173
|
-
return {
|
|
174
|
-
source,
|
|
175
|
-
modelProvider: null,
|
|
176
|
-
baseUrl: null,
|
|
177
|
-
parseFailed: true,
|
|
178
|
-
rawSelectsCodexLb: /^\s*model_provider\s*=\s*(?:"codex-lb"|'codex-lb'|codex-lb)\s*(?:#.*)?$/mi.test(raw),
|
|
179
|
-
hasMachineLocalProviderConfig: source === 'project' && /^\s*(?:model_provider|openai_base_url|chatgpt_base_url)\s*=|^\s*\[model_providers(?:\.|\])/mi.test(raw)
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
function cliConfigOverrides(args) {
|
|
184
|
-
let modelProvider = null;
|
|
185
|
-
let baseUrl = null;
|
|
186
|
-
for (let index = 0; index < args.length; index += 1) {
|
|
187
|
-
const arg = args[index] || '';
|
|
188
|
-
let override = null;
|
|
189
|
-
if (arg === '-c' || arg === '--config') {
|
|
190
|
-
override = args[index + 1] || '';
|
|
191
|
-
index += 1;
|
|
192
|
-
}
|
|
193
|
-
else if (arg.startsWith('--config=')) {
|
|
194
|
-
override = arg.slice('--config='.length);
|
|
195
|
-
}
|
|
196
|
-
else if (arg.startsWith('-c=')) {
|
|
197
|
-
override = arg.slice(3);
|
|
198
|
-
}
|
|
199
|
-
if (!override)
|
|
200
|
-
continue;
|
|
201
|
-
const equals = override.indexOf('=');
|
|
202
|
-
if (equals < 1)
|
|
203
|
-
continue;
|
|
204
|
-
const key = normalizeDottedKey(override.slice(0, equals));
|
|
205
|
-
const value = parseCliTomlValue(override.slice(equals + 1));
|
|
206
|
-
if (key === 'model_provider')
|
|
207
|
-
modelProvider = stringValue(value);
|
|
208
|
-
if (key === 'model_providers.codex-lb.base_url')
|
|
209
|
-
baseUrl = stringValue(value);
|
|
210
|
-
if (key === 'model_providers.codex-lb' && value && typeof value === 'object') {
|
|
211
|
-
baseUrl = stringValue(value.base_url) ?? baseUrl;
|
|
212
|
-
}
|
|
213
|
-
if (key === 'model_providers' && value && typeof value === 'object') {
|
|
214
|
-
baseUrl = stringValue(value?.['codex-lb']?.base_url) ?? baseUrl;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
return { modelProvider, baseUrl };
|
|
218
|
-
}
|
|
219
|
-
function parseCliTomlValue(raw) {
|
|
220
|
-
try {
|
|
221
|
-
return parseCodexConfigToml(`value = ${raw}\n`).value;
|
|
222
|
-
}
|
|
223
|
-
catch {
|
|
224
|
-
return String(raw || '').trim();
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
function cliOptionValue(args, names) {
|
|
228
|
-
for (let index = 0; index < args.length; index += 1) {
|
|
229
|
-
const arg = args[index] || '';
|
|
230
|
-
if (names.includes(arg))
|
|
231
|
-
return String(args[index + 1] || '').trim() || null;
|
|
232
|
-
for (const name of names) {
|
|
233
|
-
if (arg.startsWith(`${name}=`))
|
|
234
|
-
return arg.slice(name.length + 1).trim() || null;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
return null;
|
|
238
|
-
}
|
|
239
|
-
function cliSelectsLocalProvider(args) {
|
|
240
|
-
return args.includes('--oss');
|
|
241
|
-
}
|
|
242
|
-
export function effectiveCodexWorkingRoot(fallbackRoot, args) {
|
|
243
|
-
const base = path.resolve(fallbackRoot);
|
|
244
|
-
let selected = null;
|
|
245
|
-
for (let index = 0; index < args.length; index += 1) {
|
|
246
|
-
const arg = args[index] || '';
|
|
247
|
-
if (arg === '--')
|
|
248
|
-
break;
|
|
249
|
-
if (arg === '-C' || arg === '--cd') {
|
|
250
|
-
const next = String(args[index + 1] || '').trim();
|
|
251
|
-
if (!next || next.startsWith('-')) {
|
|
252
|
-
return { ok: false, root: base, blockers: ['codex_lb_launch_working_root_value_missing'] };
|
|
253
|
-
}
|
|
254
|
-
selected = next;
|
|
255
|
-
index += 1;
|
|
256
|
-
continue;
|
|
257
|
-
}
|
|
258
|
-
if (arg.startsWith('--cd=') || arg.startsWith('-C=')) {
|
|
259
|
-
const value = arg.slice(arg.indexOf('=') + 1).trim();
|
|
260
|
-
if (!value)
|
|
261
|
-
return { ok: false, root: base, blockers: ['codex_lb_launch_working_root_value_missing'] };
|
|
262
|
-
selected = value;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
return {
|
|
266
|
-
ok: true,
|
|
267
|
-
root: selected ? path.resolve(base, selected) : base,
|
|
268
|
-
blockers: []
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
function safeProfileName(value) {
|
|
272
|
-
return /^[A-Za-z0-9_.-]{1,128}$/.test(value);
|
|
273
|
-
}
|
|
274
|
-
function normalizeDottedKey(value) {
|
|
275
|
-
return String(value || '').trim().replace(/["']/g, '').replace(/\s+/g, '');
|
|
276
|
-
}
|
|
277
|
-
function stringValue(value) {
|
|
278
|
-
return typeof value === 'string' && value.trim() ? value.trim() : null;
|
|
279
|
-
}
|
|
280
|
-
function configParseBlocked(blockers) {
|
|
281
|
-
const base = codexLbToolOutputRecoveryNotChecked(true);
|
|
282
|
-
return {
|
|
283
|
-
...base,
|
|
284
|
-
status: 'version_unverified',
|
|
285
|
-
blockers,
|
|
286
|
-
warnings: ['selected_codex_lb_config_could_not_be_parsed_safely'],
|
|
287
|
-
operator_actions: [
|
|
288
|
-
'Repair the selected Codex config TOML, then rerun `sks codex-lb status`.',
|
|
289
|
-
...base.operator_actions
|
|
290
|
-
]
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
function projectProviderConfigBlocked() {
|
|
294
|
-
const base = codexLbToolOutputRecoveryNotChecked(true);
|
|
295
|
-
return {
|
|
296
|
-
...base,
|
|
297
|
-
status: 'version_unverified',
|
|
298
|
-
blockers: ['codex_lb_launch_project_provider_config_forbidden'],
|
|
299
|
-
warnings: ['machine_local_provider_config_must_live_in_codex_home'],
|
|
300
|
-
operator_actions: [
|
|
301
|
-
'Run `sks doctor --fix` to move or remove machine-local provider settings from the project `.codex/config.toml`.',
|
|
302
|
-
'Rerun `sks codex-lb status` before launching Codex.',
|
|
303
|
-
...base.operator_actions
|
|
304
|
-
]
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
function environmentSelectionNotForwardedBlocked() {
|
|
308
|
-
const base = codexLbToolOutputRecoveryNotChecked(true);
|
|
309
|
-
return {
|
|
310
|
-
...base,
|
|
311
|
-
status: 'version_unverified',
|
|
312
|
-
blockers: ['codex_lb_launch_selection_not_forwarded'],
|
|
313
|
-
warnings: ['sks_provider_environment_does_not_select_the_codex_process_provider'],
|
|
314
|
-
operator_actions: [
|
|
315
|
-
`Launch Codex with \`--config model_provider='"codex-lb"'\`, or select codex-lb in the active Codex profile.`,
|
|
316
|
-
'Rerun `sks codex-lb status` before launching Codex.'
|
|
317
|
-
]
|
|
318
|
-
};
|
|
319
|
-
}
|