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
package/dist/core/codex-app.js
CHANGED
|
@@ -6,11 +6,6 @@ import { EMPTY_CODEX_INFO, getCodexInfo } from './codex-adapter.js';
|
|
|
6
6
|
import { CODEX_CHROME_EXTENSION_DOC_URL, DEFAULT_CODEX_APP_PLUGINS as DEFAULT_CODEX_APP_PLUGIN_TUPLES, RESERVED_CODEX_PLUGIN_SKILL_NAMES } from './routes.js';
|
|
7
7
|
import { PRODUCT_DESIGN_PLUGIN, normalizeProductDesignPluginEvidence } from './product-design-plugin.js';
|
|
8
8
|
import { PRODUCT_DESIGN_AUTO_INSTALL_ENV, ensureProductDesignPluginInstalled, productDesignAutoInstallRequested } from './product-design-app-server.js';
|
|
9
|
-
import { GLM_CODEX_CONFIG_PROVIDER_ID, GLM_52_OPENROUTER_MODEL, RETIRED_GLM_DESKTOP_CONFIG_PROFILE_IDS } from './codex-app/openrouter-provider.js';
|
|
10
|
-
import { sksOpenRouterCatalogPath } from './codex-app/codex-model-catalog.js';
|
|
11
|
-
import { resolveOpenRouterApiKey } from './providers/openrouter/openrouter-secret-store.js';
|
|
12
|
-
import { codexLbEnvPath, codexLbMetadataPath, loadCodexLbEnv, parseShellEnvValue, readCodexLbModelCatalog } from './codex-lb/codex-lb-env.js';
|
|
13
|
-
import { codexLbToolCatalogPath, inspectCodexLbToolCatalog, shouldBindLocalModelCatalog } from './codex-lb/codex-lb-tool-catalog.js';
|
|
14
9
|
import { isSksOwnedGlobalUiLock } from './codex-app/codex-app-ui-state-snapshot.js';
|
|
15
10
|
import { redactString } from './secret-redaction.js';
|
|
16
11
|
import { escapeRegExp } from './text/regex.js';
|
|
@@ -204,7 +199,7 @@ export async function codexAppIntegrationStatus(opts = {}) {
|
|
|
204
199
|
fast_mode_config: fastModeConfig,
|
|
205
200
|
provider_model_ui: providerModelUi,
|
|
206
201
|
selected_provider_ready: selectedProviderReady,
|
|
207
|
-
|
|
202
|
+
desktop_bridge_capabilities: opts.desktopBridgeCapabilityReport || null,
|
|
208
203
|
git_actions: gitActions,
|
|
209
204
|
image_generation: imageGenerationReady,
|
|
210
205
|
image_generation_source: imageGenerationReady ? 'codex_features_list' : 'missing',
|
|
@@ -473,9 +468,11 @@ function codexNativeSksMenuStatus() {
|
|
|
473
468
|
companion_install_command: 'sks doctor --fix',
|
|
474
469
|
alternatives: [
|
|
475
470
|
'sks doctor --fix',
|
|
476
|
-
'sks
|
|
477
|
-
'sks
|
|
478
|
-
'sks
|
|
471
|
+
'sks bridge provider configure',
|
|
472
|
+
'sks bridge provider validate',
|
|
473
|
+
'sks bridge provider enable',
|
|
474
|
+
'sks bridge catalog sync',
|
|
475
|
+
'sks bridge route set-default',
|
|
479
476
|
'codex://settings'
|
|
480
477
|
],
|
|
481
478
|
evidence: [
|
|
@@ -544,28 +541,12 @@ export function codexAppGuidance({ appInstalled, codex, mcpList, featureList, re
|
|
|
544
541
|
lines.push(`Codex App speed selector can be hidden or locked by config: ${fastModeConfig.blockers.join(', ')}.`);
|
|
545
542
|
lines.push('Run: sks doctor --fix');
|
|
546
543
|
}
|
|
547
|
-
if (providerModelUi?.
|
|
548
|
-
lines.push(`
|
|
544
|
+
if (providerModelUi?.checked && providerModelUi.effective_ready) {
|
|
545
|
+
lines.push(`Desktop bridge routing is ready${providerModelUi.selected_provider ? ` with ${providerModelUi.selected_provider} selected` : ''}.`);
|
|
549
546
|
}
|
|
550
|
-
else if (providerModelUi
|
|
551
|
-
lines.push(`
|
|
552
|
-
lines.push(
|
|
553
|
-
}
|
|
554
|
-
else if (providerModelUi?.glm) {
|
|
555
|
-
lines.push(`OpenRouter provider is not ready yet: ${providerModelUi.glm.blockers.join(', ') || 'provider setup required'}.`);
|
|
556
|
-
lines.push(`Run: ${providerModelUi.glm.key_command}; then ${providerModelUi.glm.install_command}; restart Codex App if the model picker was already open.`);
|
|
557
|
-
}
|
|
558
|
-
if (providerModelUi?.codex_lb?.key_entry_visible && providerModelUi.codex_lb.key_present && providerModelUi.codex_lb.provider_present && providerModelUi.codex_lb.provider_contract_ok && providerModelUi.codex_lb.base_url_present) {
|
|
559
|
-
lines.push(`codex-lb key entry path is configured; provider catalog ${providerModelUi.codex_lb.expected_models_present ? 'contains GPT-5.6 Sol/Terra/Luna' : 'is not verified'}. Update command: ${providerModelUi.codex_lb.set_key_command}.`);
|
|
560
|
-
lines.push('Provider/config readiness does not by itself prove the already-running Desktop picker; auth/profile actions restart ChatGPT/Codex so it reloads model/list.');
|
|
561
|
-
}
|
|
562
|
-
else if (providerModelUi?.codex_lb?.key_entry_visible) {
|
|
563
|
-
lines.push(`codex-lb key entry path is visible, but setup is incomplete: ${providerModelUi.codex_lb.blockers.join(', ') || 'setup required'}.`);
|
|
564
|
-
lines.push(`Run: ${providerModelUi.codex_lb.setup_command} or ${providerModelUi.codex_lb.set_key_command}.`);
|
|
565
|
-
}
|
|
566
|
-
else if (providerModelUi?.codex_lb) {
|
|
567
|
-
lines.push(`codex-lb key entry path is not exposed yet: ${providerModelUi.codex_lb.blockers.join(', ') || 'setup required'}.`);
|
|
568
|
-
lines.push(`Run: ${providerModelUi.codex_lb.setup_command} or ${providerModelUi.codex_lb.set_key_command}.`);
|
|
547
|
+
else if (providerModelUi) {
|
|
548
|
+
lines.push(`Desktop bridge routing is not ready: ${(providerModelUi.selected_provider_blockers || []).join(', ') || providerModelUi.readiness_state || 'status unavailable'}.`);
|
|
549
|
+
lines.push('Run: sks bridge provider configure; sks bridge provider validate; sks bridge provider enable; sks bridge catalog sync; sks bridge route set-default.');
|
|
569
550
|
}
|
|
570
551
|
if (!gitActions?.ok) {
|
|
571
552
|
lines.push(`Codex App git commit/push actions are blocked: ${gitActions?.blockers?.join(', ') || 'git action readiness'}. The app Commit, Push, Commit and Push, and PR flows need codex_git_commit, hooks, and Codex CLI remote-control support.`);
|
|
@@ -620,9 +601,7 @@ export function formatCodexAppStatus(status, { includeRaw = false } = {}) {
|
|
|
620
601
|
`App Flags: ${status.features?.required_flags_ok ? 'ok' : `missing ${missingRequiredFeatureFlags(status.features?.required_flags).join(', ') || 'required flags'}`}`,
|
|
621
602
|
`Fast UI: ${status.features?.fast_mode_config?.ok ? 'ok' : `locked ${(status.features?.fast_mode_config?.blockers || []).join(', ') || 'config'}`}`,
|
|
622
603
|
`SKS Menu: ${sksNativeMenuSummary(status.app?.sks_menu)}`,
|
|
623
|
-
`
|
|
624
|
-
`GLM Model: ${glmModelUiSummary(status.features?.provider_model_ui?.glm)}`,
|
|
625
|
-
`codex-lb Key:${codexLbKeyUiSummary(status.features?.provider_model_ui?.codex_lb)}`,
|
|
604
|
+
`Bridge UI: ${providerModelUiSummary(status.features?.provider_model_ui)}`,
|
|
626
605
|
`Default Plugins:${status.plugins?.default_plugins?.ok ? ' ok' : ` missing ${defaultPluginMissingSummary(status.plugins?.default_plugins) || 'plugin install/config'}`}`,
|
|
627
606
|
`Product Design:${productDesignStatusSummary(status.plugins?.design_product)}`,
|
|
628
607
|
`Plugin Picker:${status.plugins?.picker?.ok ? ' ok' : ` blocked ${pluginPickerBlockers(status).join(', ') || 'config'}`}`,
|
|
@@ -893,262 +872,99 @@ async function codexFastModeConfigStatus(opts = {}) {
|
|
|
893
872
|
};
|
|
894
873
|
}
|
|
895
874
|
export async function codexProviderModelUiStatus(opts = {}) {
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
const globalConfigPath = opts.configPath || path.join(home || '', '.codex', 'config.toml');
|
|
901
|
-
const projectConfigPath = path.join(cwd || '', '.codex', 'config.toml');
|
|
902
|
-
const globalConfig = await readTextIfExists(globalConfigPath);
|
|
903
|
-
const projectConfig = path.resolve(projectConfigPath) === path.resolve(globalConfigPath)
|
|
904
|
-
? ''
|
|
905
|
-
: await readTextIfExists(projectConfigPath);
|
|
906
|
-
const configText = `${globalConfig}\n${projectConfig}`;
|
|
907
|
-
const openRouterKey = await resolveOpenRouterApiKey({ env }).catch((err) => ({
|
|
908
|
-
key: null,
|
|
909
|
-
source: null,
|
|
910
|
-
key_preview: null,
|
|
911
|
-
blockers: ['openrouter_key_lookup_failed'],
|
|
912
|
-
warnings: [err?.message || 'openrouter key lookup failed']
|
|
913
|
-
}));
|
|
914
|
-
const codexLbEnvFilePath = opts.codexLbEnvPath || codexLbEnvPath(home);
|
|
915
|
-
const codexLbEnvText = await readTextIfExists(codexLbEnvFilePath);
|
|
916
|
-
const codexLbApiKeySource = String(env.CODEX_LB_API_KEY || '').trim()
|
|
917
|
-
? 'process.env'
|
|
918
|
-
: parseShellEnvValue(codexLbEnvText, 'CODEX_LB_API_KEY')
|
|
919
|
-
? 'env-file'
|
|
920
|
-
: 'missing';
|
|
921
|
-
const codexLbBaseUrlSource = String(env.CODEX_LB_BASE_URL || '').trim()
|
|
922
|
-
? 'process.env'
|
|
923
|
-
: parseShellEnvValue(codexLbEnvText, 'CODEX_LB_BASE_URL')
|
|
924
|
-
? 'env-file'
|
|
925
|
-
: 'missing';
|
|
926
|
-
const openrouterProvider = tomlTableAny(configText, [
|
|
927
|
-
`model_providers.${GLM_CODEX_CONFIG_PROVIDER_ID}`,
|
|
928
|
-
`model_providers."${GLM_CODEX_CONFIG_PROVIDER_ID}"`
|
|
929
|
-
]);
|
|
930
|
-
const glmProviderPresent = Boolean(openrouterProvider);
|
|
931
|
-
const profilesPresent = [];
|
|
932
|
-
const profilesMissing = [];
|
|
933
|
-
const glmProfileBlockers = [];
|
|
934
|
-
for (const profileId of RETIRED_GLM_DESKTOP_CONFIG_PROFILE_IDS) {
|
|
935
|
-
const body = tomlTableAny(configText, [`profiles.${profileId}`, `profiles."${profileId}"`]);
|
|
936
|
-
if (!body)
|
|
937
|
-
continue;
|
|
938
|
-
profilesPresent.push(profileId);
|
|
939
|
-
glmProfileBlockers.push(`retired_glm_desktop_profile_present:${profileId}`);
|
|
875
|
+
let bridgeStatus;
|
|
876
|
+
try {
|
|
877
|
+
bridgeStatus = opts.desktopBridgeStatus
|
|
878
|
+
|| await (opts.desktopBridgeStatusImpl || currentDesktopBridgeStatus)(opts.desktopBridgeStatusOptions || {});
|
|
940
879
|
}
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
const codexLbCliProviderContractOk = codexLbProviderPresent
|
|
944
|
-
&& hasTomlString(codexLbProvider, 'name', 'codex-lb')
|
|
945
|
-
&& hasTomlString(codexLbProvider, 'wire_api', 'responses')
|
|
946
|
-
&& /(?:^|\n)\s*env_key\s*=\s*"CODEX_LB_API_KEY"\s*(?:#.*)?(?=\n|$)/.test(codexLbProvider)
|
|
947
|
-
&& !/X-Codex-LB-API-Key/.test(codexLbProvider)
|
|
948
|
-
&& hasTomlBoolean(codexLbProvider, 'supports_websockets', true)
|
|
949
|
-
&& hasTomlBoolean(codexLbProvider, 'requires_openai_auth', false);
|
|
950
|
-
const codexLbSelectedDefault = /(?:^|\n)\s*model_provider\s*=\s*"codex-lb"\s*(?:#.*)?(?=\n|$)/.test(topLevelToml(globalConfig));
|
|
951
|
-
const codexLbDesktopMode = opts.codexLbDesktopMode
|
|
952
|
-
|| inferCodexLbDesktopModeForUi(globalConfig);
|
|
953
|
-
const retiredCodexLbCompatConfigured = codexLbDesktopMode === 'desktop-dual-auth-compat';
|
|
954
|
-
const codexLbProviderContractOk = !retiredCodexLbCompatConfigured
|
|
955
|
-
&& codexLbCliProviderContractOk;
|
|
956
|
-
const metadata = await readJsonIfExists(opts.codexLbMetadataPath || codexLbMetadataPath(home));
|
|
957
|
-
const gatewayAuthTransport = normalizeCodexLbGatewayAuthTransportForUi(opts.codexLbGatewayAuthTransport || metadata?.gateway_auth_transport);
|
|
958
|
-
const localCatalogBindingAllowed = shouldBindLocalModelCatalog(codexLbDesktopMode);
|
|
959
|
-
const selectedProviderValue = topLevelToml(globalConfig)
|
|
960
|
-
.match(/(?:^|\n)\s*model_provider\s*=\s*"([^"]+)"\s*(?:#.*)?(?=\n|$)/)?.[1] || null;
|
|
961
|
-
const managedCatalogPath = codexLbToolCatalogPath(path.join(home || '', '.codex'));
|
|
962
|
-
const configuredCatalogPath = topLevelToml(globalConfig).match(/(?:^|\n)\s*model_catalog_json\s*=\s*"([^"]+)"\s*(?:#.*)?(?=\n|$)/)?.[1] || '';
|
|
963
|
-
const managedCatalogConfigured = Boolean(configuredCatalogPath)
|
|
964
|
-
&& path.resolve(configuredCatalogPath) === path.resolve(managedCatalogPath);
|
|
965
|
-
let persistedCatalog = null;
|
|
966
|
-
if (!opts.codexLbModelCatalog && managedCatalogConfigured && localCatalogBindingAllowed) {
|
|
967
|
-
persistedCatalog = await inspectCodexLbToolCatalog(managedCatalogPath).catch(() => null);
|
|
880
|
+
catch {
|
|
881
|
+
return unavailableProviderModelUiStatus('desktop_bridge_status_unavailable');
|
|
968
882
|
}
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
const loadedEnv = await loadCodexLbEnv({ home, envPath: codexLbEnvFilePath }).catch(() => null);
|
|
972
|
-
liveCatalog = loadedEnv
|
|
973
|
-
? await readCodexLbModelCatalog({
|
|
974
|
-
loadedEnv,
|
|
975
|
-
gatewayAuthTransport
|
|
976
|
-
}).catch(() => null)
|
|
977
|
-
: null;
|
|
883
|
+
if (bridgeStatus?.schema !== 'sks.desktop-bridge-status.v3') {
|
|
884
|
+
return unavailableProviderModelUiStatus('desktop_bridge_status_schema_invalid');
|
|
978
885
|
}
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
: persistedCatalog
|
|
990
|
-
? {
|
|
991
|
-
ok: false,
|
|
992
|
-
models: Array.isArray(persistedCatalog.gpt56_models) ? persistedCatalog.gpt56_models : [],
|
|
993
|
-
blockers: persistedCatalog.blockers || ['codex_lb_persisted_catalog_invalid'],
|
|
994
|
-
source: 'persisted_model_catalog_json'
|
|
995
|
-
}
|
|
996
|
-
: null);
|
|
997
|
-
const catalogModels = Array.isArray(codexLbModelCatalog?.models) ? codexLbModelCatalog.models.map(String) : [];
|
|
998
|
-
const advertisedCodexLbModelsPresent = codexLbModelCatalog?.ok === true && catalogModels.length > 0;
|
|
999
|
-
const glmBlockers = [
|
|
1000
|
-
...(glmProviderPresent ? [] : ['glm_openrouter_provider_missing']),
|
|
1001
|
-
...glmProfileBlockers,
|
|
1002
|
-
...(openRouterKey.key ? [] : ['openrouter_key_missing'])
|
|
1003
|
-
];
|
|
1004
|
-
const codexLbBlockers = [
|
|
1005
|
-
...(codexLbProviderPresent ? [] : ['codex_lb_provider_missing']),
|
|
1006
|
-
...(retiredCodexLbCompatConfigured
|
|
1007
|
-
? ['desktop_dual_auth_compat_unavailable']
|
|
1008
|
-
: codexLbProviderPresent && !codexLbProviderContractOk
|
|
1009
|
-
? ['codex_lb_provider_contract_drift']
|
|
1010
|
-
: []),
|
|
1011
|
-
...(codexLbApiKeySource !== 'missing' ? [] : ['codex_lb_api_key_missing']),
|
|
1012
|
-
...(codexLbBaseUrlSource !== 'missing' ? [] : ['codex_lb_base_url_missing']),
|
|
1013
|
-
...(codexLbDesktopMode === 'desktop-native-bridge' && managedCatalogConfigured
|
|
1014
|
-
? ['native_bridge_local_catalog_replacement_forbidden']
|
|
1015
|
-
: []),
|
|
1016
|
-
...(codexLbSelectedDefault && localCatalogBindingAllowed && !managedCatalogConfigured && !advertisedCodexLbModelsPresent
|
|
1017
|
-
? ['codex_lb_model_catalog_json_unselected']
|
|
1018
|
-
: []),
|
|
1019
|
-
...(codexLbProviderContractOk && codexLbApiKeySource !== 'missing' && codexLbBaseUrlSource !== 'missing' && !advertisedCodexLbModelsPresent
|
|
1020
|
-
? ['codex_lb_model_catalog_unverified']
|
|
1021
|
-
: [])
|
|
1022
|
-
];
|
|
1023
|
-
const openRouterSelectedDefault = selectedProviderValue === GLM_CODEX_CONFIG_PROVIDER_ID;
|
|
1024
|
-
const openRouterManagedCatalogPath = sksOpenRouterCatalogPath({ home });
|
|
1025
|
-
const openRouterCatalogBound = Boolean(configuredCatalogPath)
|
|
1026
|
-
&& path.resolve(configuredCatalogPath) === path.resolve(openRouterManagedCatalogPath);
|
|
1027
|
-
const openRouterCatalogDangling = openRouterCatalogBound && !openRouterSelectedDefault;
|
|
1028
|
-
const openRouterSelectedBlockers = openRouterSelectedDefault
|
|
1029
|
-
? [
|
|
1030
|
-
...glmBlockers,
|
|
1031
|
-
...(openRouterCatalogBound ? [] : ['openrouter_model_catalog_json_unselected'])
|
|
1032
|
-
]
|
|
1033
|
-
: [];
|
|
1034
|
-
const selectedProviderBlockers = [
|
|
1035
|
-
...(codexLbSelectedDefault
|
|
1036
|
-
? codexLbBlockers
|
|
1037
|
-
: openRouterSelectedDefault
|
|
1038
|
-
? openRouterSelectedBlockers
|
|
1039
|
-
: []),
|
|
1040
|
-
...(openRouterCatalogDangling ? ['openrouter_model_catalog_json_dangling'] : [])
|
|
1041
|
-
];
|
|
1042
|
-
const optionalProviderBlockers = codexLbSelectedDefault
|
|
1043
|
-
? glmBlockers
|
|
1044
|
-
: openRouterSelectedDefault
|
|
1045
|
-
? codexLbBlockers
|
|
1046
|
-
: [...glmBlockers, ...codexLbBlockers];
|
|
1047
|
-
const keyCommand = 'sks codex-app set-openrouter-key --api-key-stdin';
|
|
1048
|
-
const installCommand = 'sks codex-app use-openrouter --model z-ai/glm-5.2';
|
|
1049
|
-
const setupCommand = 'sks codex-lb setup --host <domain> --api-key-stdin --yes';
|
|
1050
|
-
const setKeyCommand = 'sks codex-lb set-key --api-key-stdin';
|
|
1051
|
-
const desktopPickerEvidence = opts.desktopPickerEvidence
|
|
1052
|
-
|| opts.codexLbCapabilityReport?.model_picker
|
|
1053
|
-
|| opts.codexLbCapabilityReport?.capabilities?.model_picker
|
|
1054
|
-
|| opts.codexLbStatus?.capabilities?.model_picker
|
|
886
|
+
return providerModelUiStatusFromDesktopBridge(bridgeStatus);
|
|
887
|
+
}
|
|
888
|
+
async function currentDesktopBridgeStatus(options) {
|
|
889
|
+
const controller = await import('./codex-lb/desktop-controller.js');
|
|
890
|
+
return controller.desktopBridgeStatusV3(options);
|
|
891
|
+
}
|
|
892
|
+
function providerModelUiStatusFromDesktopBridge(status) {
|
|
893
|
+
const selectedProvider = status.routing.selected_route?.provider_id
|
|
894
|
+
|| status.routing.policy?.default_provider_id
|
|
895
|
+
|| status.routing.session_pin?.provider_id
|
|
1055
896
|
|| null;
|
|
1056
|
-
const
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
897
|
+
const selectedProfile = selectedProvider ? status.providers[selectedProvider] : null;
|
|
898
|
+
const selectedProviderBlockers = uniqueStrings([
|
|
899
|
+
...status.readiness.blockers,
|
|
900
|
+
...status.routing.blockers,
|
|
901
|
+
...(selectedProfile?.credential.blockers || []),
|
|
902
|
+
...(selectedProfile?.catalog.blockers || [])
|
|
903
|
+
]);
|
|
1063
904
|
return {
|
|
1064
|
-
schema: 'sks.codex-app-provider-model-ui.
|
|
1065
|
-
ok:
|
|
1066
|
-
selected_provider_ok:
|
|
1067
|
-
configured:
|
|
1068
|
-
advertised:
|
|
1069
|
-
effective_ready:
|
|
1070
|
-
selected_provider:
|
|
905
|
+
schema: 'sks.codex-app-provider-model-ui.v2',
|
|
906
|
+
ok: status.readiness.ready,
|
|
907
|
+
selected_provider_ok: status.readiness.ready,
|
|
908
|
+
configured: status.management.managed,
|
|
909
|
+
advertised: status.readiness.combined_catalog_ready,
|
|
910
|
+
effective_ready: status.readiness.ready,
|
|
911
|
+
selected_provider: selectedProvider,
|
|
1071
912
|
selected_provider_blockers: selectedProviderBlockers,
|
|
1072
|
-
optional_provider_blockers:
|
|
913
|
+
optional_provider_blockers: status.readiness.warnings,
|
|
1073
914
|
checked: true,
|
|
1074
|
-
verification_scope: '
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
? 'setup_required'
|
|
1084
|
-
: effectiveReady
|
|
1085
|
-
? 'ready'
|
|
1086
|
-
: 'available_unverified',
|
|
1087
|
-
optional_provider_status: optionalProviderBlockers.length === 0 ? 'ready' : 'setup_available',
|
|
1088
|
-
config_paths: {
|
|
1089
|
-
codex_config: globalConfigPath,
|
|
1090
|
-
project_config: projectConfig ? projectConfigPath : null,
|
|
1091
|
-
codex_lb_env: codexLbEnvFilePath
|
|
1092
|
-
},
|
|
1093
|
-
glm: {
|
|
1094
|
-
exposed: glmProviderPresent && glmProfileBlockers.length === 0,
|
|
1095
|
-
provider_present: glmProviderPresent,
|
|
1096
|
-
provider: GLM_CODEX_CONFIG_PROVIDER_ID,
|
|
1097
|
-
model: GLM_52_OPENROUTER_MODEL,
|
|
1098
|
-
profiles_present: profilesPresent,
|
|
1099
|
-
profiles_missing: profilesMissing,
|
|
1100
|
-
openrouter_key_present: Boolean(openRouterKey.key),
|
|
1101
|
-
openrouter_key_source: openRouterKey.source || null,
|
|
1102
|
-
openrouter_key_preview: openRouterKey.key_preview || null,
|
|
1103
|
-
openrouter_selected: openRouterSelectedDefault,
|
|
1104
|
-
model_catalog_json_configured: openRouterCatalogBound,
|
|
1105
|
-
model_catalog_json_path: openRouterManagedCatalogPath,
|
|
1106
|
-
key_command: keyCommand,
|
|
1107
|
-
install_command: installCommand,
|
|
1108
|
-
doctor_command: 'sks codex-app openrouter-status',
|
|
1109
|
-
blockers: glmBlockers
|
|
1110
|
-
},
|
|
1111
|
-
codex_lb: {
|
|
1112
|
-
key_entry_visible: true,
|
|
1113
|
-
provider_present: codexLbProviderPresent,
|
|
1114
|
-
provider_contract_ok: codexLbProviderContractOk,
|
|
1115
|
-
provider_contract: retiredCodexLbCompatConfigured
|
|
1116
|
-
? 'retired-desktop-dual-auth-compat'
|
|
1117
|
-
: 'cli-provider',
|
|
1118
|
-
selected_default: codexLbSelectedDefault,
|
|
1119
|
-
key_present: codexLbApiKeySource !== 'missing',
|
|
1120
|
-
api_key_source: codexLbApiKeySource,
|
|
1121
|
-
base_url_present: codexLbBaseUrlSource !== 'missing',
|
|
1122
|
-
base_url_source: codexLbBaseUrlSource,
|
|
1123
|
-
model_catalog_checked: Boolean(codexLbModelCatalog),
|
|
1124
|
-
model_catalog_ok: codexLbModelCatalog?.ok === true,
|
|
1125
|
-
model_catalog_source: codexLbModelCatalog?.source || null,
|
|
1126
|
-
desktop_mode: codexLbDesktopMode,
|
|
1127
|
-
gateway_auth_transport: gatewayAuthTransport,
|
|
1128
|
-
local_catalog_binding_allowed: localCatalogBindingAllowed,
|
|
1129
|
-
model_catalog_json_configured: managedCatalogConfigured,
|
|
1130
|
-
model_catalog_json_path: managedCatalogConfigured ? managedCatalogPath : configuredCatalogPath || null,
|
|
1131
|
-
model_catalog_models: catalogModels,
|
|
1132
|
-
expected_models: [],
|
|
1133
|
-
expected_models_present: advertisedCodexLbModelsPresent,
|
|
1134
|
-
advertised_models_present: advertisedCodexLbModelsPresent,
|
|
1135
|
-
tools_transport: codexLbModelCatalog?.tools_transport || null,
|
|
1136
|
-
model_catalog_blockers: codexLbModelCatalog?.blockers || [],
|
|
1137
|
-
setup_command: setupCommand,
|
|
1138
|
-
set_key_command: setKeyCommand,
|
|
1139
|
-
status_command: 'sks codex-lb status',
|
|
1140
|
-
blockers: codexLbBlockers
|
|
1141
|
-
},
|
|
915
|
+
verification_scope: 'desktop_bridge_status_v3',
|
|
916
|
+
readiness_state: status.readiness.state,
|
|
917
|
+
status: status.readiness.ready ? 'ready' : status.readiness.state,
|
|
918
|
+
management: status.management,
|
|
919
|
+
service: status.service,
|
|
920
|
+
routing: status.routing,
|
|
921
|
+
catalog_sync: status.catalog_sync,
|
|
922
|
+
providers: status.providers,
|
|
923
|
+
recovery_actions: status.recovery_actions,
|
|
1142
924
|
ui_actions: [
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
'sks
|
|
925
|
+
'sks bridge provider configure',
|
|
926
|
+
'sks bridge provider validate',
|
|
927
|
+
'sks bridge provider enable',
|
|
928
|
+
'sks bridge catalog sync',
|
|
929
|
+
'sks bridge route set-default'
|
|
1148
930
|
],
|
|
1149
931
|
blockers: selectedProviderBlockers
|
|
1150
932
|
};
|
|
1151
933
|
}
|
|
934
|
+
function unavailableProviderModelUiStatus(blocker) {
|
|
935
|
+
return {
|
|
936
|
+
schema: 'sks.codex-app-provider-model-ui.v2',
|
|
937
|
+
ok: false,
|
|
938
|
+
selected_provider_ok: false,
|
|
939
|
+
configured: false,
|
|
940
|
+
advertised: false,
|
|
941
|
+
effective_ready: false,
|
|
942
|
+
selected_provider: null,
|
|
943
|
+
selected_provider_blockers: [blocker],
|
|
944
|
+
optional_provider_blockers: [],
|
|
945
|
+
checked: false,
|
|
946
|
+
verification_scope: 'desktop_bridge_status_v3',
|
|
947
|
+
readiness_state: 'blocked',
|
|
948
|
+
status: 'blocked',
|
|
949
|
+
management: null,
|
|
950
|
+
service: null,
|
|
951
|
+
routing: null,
|
|
952
|
+
catalog_sync: null,
|
|
953
|
+
providers: null,
|
|
954
|
+
recovery_actions: [],
|
|
955
|
+
ui_actions: [
|
|
956
|
+
'sks bridge provider configure',
|
|
957
|
+
'sks bridge provider validate',
|
|
958
|
+
'sks bridge provider enable',
|
|
959
|
+
'sks bridge catalog sync',
|
|
960
|
+
'sks bridge route set-default'
|
|
961
|
+
],
|
|
962
|
+
blockers: [blocker]
|
|
963
|
+
};
|
|
964
|
+
}
|
|
965
|
+
function uniqueStrings(values) {
|
|
966
|
+
return [...new Set(values.map((value) => String(value || '').trim()).filter(Boolean))];
|
|
967
|
+
}
|
|
1152
968
|
async function readTextIfExists(file) {
|
|
1153
969
|
try {
|
|
1154
970
|
return await fsp.readFile(file, 'utf8');
|
|
@@ -1157,38 +973,6 @@ async function readTextIfExists(file) {
|
|
|
1157
973
|
return '';
|
|
1158
974
|
}
|
|
1159
975
|
}
|
|
1160
|
-
async function readJsonIfExists(file) {
|
|
1161
|
-
try {
|
|
1162
|
-
const parsed = JSON.parse(await fsp.readFile(file, 'utf8'));
|
|
1163
|
-
return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
|
|
1164
|
-
? parsed
|
|
1165
|
-
: null;
|
|
1166
|
-
}
|
|
1167
|
-
catch {
|
|
1168
|
-
return null;
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
|
-
function inferCodexLbDesktopModeForUi(config) {
|
|
1172
|
-
const topLevel = topLevelToml(config);
|
|
1173
|
-
const selected = topLevel.match(/(?:^|\n)\s*model_provider\s*=\s*"([^"]+)"\s*(?:#.*)?(?=\n|$)/)?.[1] || '';
|
|
1174
|
-
const openAiBaseUrl = topLevel.match(/(?:^|\n)\s*openai_base_url\s*=\s*"([^"]+)"\s*(?:#.*)?(?=\n|$)/)?.[1] || '';
|
|
1175
|
-
if (config.includes('# sks-codex-lb-managed-desktop-bridge')
|
|
1176
|
-
&& /^http:\/\/(?:127\.0\.0\.1|\[::1\]):\d+\/backend-api\/codex\/?$/i.test(openAiBaseUrl)) {
|
|
1177
|
-
return 'desktop-native-bridge';
|
|
1178
|
-
}
|
|
1179
|
-
if (config.includes('# sks-codex-lb-managed-desktop-compat')
|
|
1180
|
-
&& selected === 'codex-lb') {
|
|
1181
|
-
return 'desktop-dual-auth-compat';
|
|
1182
|
-
}
|
|
1183
|
-
return tomlTableAny(config, ['model_providers.codex-lb', 'model_providers."codex-lb"'])
|
|
1184
|
-
? 'cli-provider'
|
|
1185
|
-
: 'disabled';
|
|
1186
|
-
}
|
|
1187
|
-
function normalizeCodexLbGatewayAuthTransportForUi(value) {
|
|
1188
|
-
return value === 'x-codex-lb-api-key'
|
|
1189
|
-
? 'x-codex-lb-api-key'
|
|
1190
|
-
: 'authorization-bearer-compat';
|
|
1191
|
-
}
|
|
1192
976
|
async function findDefaultPluginSource(plugin, { home, configText }) {
|
|
1193
977
|
const cached = await findPluginCache(plugin.name, { home });
|
|
1194
978
|
if (cached)
|
|
@@ -1243,17 +1027,10 @@ function productDesignStatusSummary(status = {}) {
|
|
|
1243
1027
|
function providerModelUiSummary(status = {}) {
|
|
1244
1028
|
if (!status?.checked)
|
|
1245
1029
|
return ' not checked';
|
|
1246
|
-
const selected = status.selected_provider || '
|
|
1247
|
-
if (status.ok)
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
: '';
|
|
1251
|
-
return ` ${selected} ready${optionalSetup} (live picker reload required)`;
|
|
1252
|
-
}
|
|
1253
|
-
if (status.configured && status.readiness_state === 'available_unverified') {
|
|
1254
|
-
return ` ${selected} configured, Desktop picker unverified`;
|
|
1255
|
-
}
|
|
1256
|
-
return ` ${selected} setup ${(status.selected_provider_blockers || status.blockers || []).join(', ') || 'required'}`;
|
|
1030
|
+
const selected = status.selected_provider || 'no provider selected';
|
|
1031
|
+
if (status.ok)
|
|
1032
|
+
return ` ${selected} ready`;
|
|
1033
|
+
return ` ${selected} ${status.readiness_state || 'blocked'} ${(status.selected_provider_blockers || status.blockers || []).join(', ') || 'bridge setup required'}`;
|
|
1257
1034
|
}
|
|
1258
1035
|
function sksNativeMenuSummary(status = {}) {
|
|
1259
1036
|
if (!status)
|
|
@@ -1262,56 +1039,16 @@ function sksNativeMenuSummary(status = {}) {
|
|
|
1262
1039
|
return 'ok';
|
|
1263
1040
|
return `${status.status || 'unsupported'} (use CLI/settings)`;
|
|
1264
1041
|
}
|
|
1265
|
-
function glmModelUiSummary(status = {}) {
|
|
1266
|
-
if (!status)
|
|
1267
|
-
return 'not checked';
|
|
1268
|
-
if (status.exposed) {
|
|
1269
|
-
const key = status.openrouter_key_present ? `key ${status.openrouter_key_source || 'present'}` : 'key missing';
|
|
1270
|
-
return `ok ${status.model} (${key})`;
|
|
1271
|
-
}
|
|
1272
|
-
return `setup ${(status.blockers || []).join(', ') || 'provider missing'}; run ${status.key_command || 'sks codex-app set-openrouter-key --api-key-stdin'}`;
|
|
1273
|
-
}
|
|
1274
|
-
function codexLbKeyUiSummary(status = {}) {
|
|
1275
|
-
if (!status)
|
|
1276
|
-
return ' not checked';
|
|
1277
|
-
if (status.key_present && status.provider_contract_ok !== false)
|
|
1278
|
-
return ` configured (${status.api_key_source || 'present'})`;
|
|
1279
|
-
if (status.key_present)
|
|
1280
|
-
return ` setup provider drift; run ${status.setup_command || 'sks codex-lb setup --host <domain> --api-key-stdin --yes'}`;
|
|
1281
|
-
return ` missing (input: ${status.setup_command || 'sks codex-lb setup --host <domain> --api-key-stdin --yes'})`;
|
|
1282
|
-
}
|
|
1283
1042
|
function defaultPluginMissingSummary(defaultPlugins = {}) {
|
|
1284
1043
|
return [
|
|
1285
1044
|
...(defaultPlugins?.missing_installed || []),
|
|
1286
1045
|
...(defaultPlugins?.missing_enabled || [])
|
|
1287
1046
|
].join(', ');
|
|
1288
1047
|
}
|
|
1289
|
-
function topLevelToml(text = '') {
|
|
1290
|
-
const lines = String(text || '').split('\n');
|
|
1291
|
-
const firstTable = lines.findIndex((line) => /^\s*\[.+\]\s*$/.test(line));
|
|
1292
|
-
return (firstTable === -1 ? lines : lines.slice(0, firstTable)).join('\n');
|
|
1293
|
-
}
|
|
1294
1048
|
function tomlTable(text = '', table = '') {
|
|
1295
1049
|
const re = new RegExp(`(?:^|\\n)\\[${escapeRegExp(table)}\\]([\\s\\S]*?)(?=\\n\\[[^\\]]+\\]|\\s*$)`);
|
|
1296
1050
|
return String(text || '').match(re)?.[1] || '';
|
|
1297
1051
|
}
|
|
1298
|
-
function tomlTableAny(text = '', tables = []) {
|
|
1299
|
-
for (const table of tables) {
|
|
1300
|
-
const body = tomlTable(text, table);
|
|
1301
|
-
if (body)
|
|
1302
|
-
return body;
|
|
1303
|
-
}
|
|
1304
|
-
return '';
|
|
1305
|
-
}
|
|
1306
|
-
function hasTomlString(text = '', key = '', value = '') {
|
|
1307
|
-
const re = new RegExp(`(?:^|\\n)\\s*${escapeRegExp(key)}\\s*=\\s*"${escapeRegExp(value)}"\\s*(?:#.*)?(?=\\n|$)`);
|
|
1308
|
-
return re.test(String(text || ''));
|
|
1309
|
-
}
|
|
1310
|
-
function hasTomlBoolean(text = '', key = '', value) {
|
|
1311
|
-
const expected = value ? 'true' : 'false';
|
|
1312
|
-
const re = new RegExp(`(?:^|\\n)\\s*${escapeRegExp(key)}\\s*=\\s*${expected}\\s*(?:#.*)?(?=\\n|$)`);
|
|
1313
|
-
return re.test(String(text || ''));
|
|
1314
|
-
}
|
|
1315
1052
|
function remoteControlGuidance(status = {}) {
|
|
1316
1053
|
if (!status.codex_cli?.ok)
|
|
1317
1054
|
return 'Codex remote-control needs a Codex CLI that exposes the app-server entrypoint. Install the official latest stable release: npm i -g @openai/codex@latest';
|
|
@@ -2,8 +2,7 @@ import fsp from 'node:fs/promises';
|
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { readTopLevelTomlString } from '../codex-app/codex-model-catalog.js';
|
|
5
|
-
|
|
6
|
-
export const CODEX_APP_SERVER_PROVIDER_CREDENTIALS_UNAVAILABLE = 'codex_app_server_provider_credentials_unavailable';
|
|
5
|
+
export const CODEX_APP_SERVER_DIRECT_PROVIDER_SELECTION_RETIRED = 'desktop_bridge_direct_provider_selection_retired';
|
|
7
6
|
export const CODEX_APP_SERVER_CONFIG_READ_FAILED = 'codex_app_server_config_read_failed';
|
|
8
7
|
export class CodexAppServerRuntimeEnvError extends Error {
|
|
9
8
|
code;
|
|
@@ -15,11 +14,10 @@ export class CodexAppServerRuntimeEnvError extends Error {
|
|
|
15
14
|
this.name = 'CodexAppServerRuntimeEnvError';
|
|
16
15
|
}
|
|
17
16
|
}
|
|
18
|
-
export function
|
|
17
|
+
export function desktopBridgeMigrationGuidance() {
|
|
19
18
|
return [
|
|
20
|
-
`
|
|
21
|
-
'
|
|
22
|
-
'Alternatively, provide CODEX_LB_API_KEY in the launching environment.'
|
|
19
|
+
'Run `sks bridge ensure --json` to migrate SKS-owned routing to Desktop Bridge.',
|
|
20
|
+
'If the direct provider selection is user-owned, review and remove it manually before retrying.'
|
|
23
21
|
];
|
|
24
22
|
}
|
|
25
23
|
export function codexAppServerExecutablePath(input) {
|
|
@@ -68,28 +66,10 @@ export async function prepareCodexAppServerRuntimeEnv(input = {}) {
|
|
|
68
66
|
...(sourceEnv.PATH === undefined ? {} : { inheritedPath: sourceEnv.PATH })
|
|
69
67
|
})
|
|
70
68
|
};
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
delete env.CODEX_LB_API_KEY;
|
|
70
|
+
delete env.CODEX_LB_BASE_URL;
|
|
71
|
+
if (selectedProvider === 'codex-lb' || selectedProvider === 'openrouter') {
|
|
72
|
+
throw new CodexAppServerRuntimeEnvError(CODEX_APP_SERVER_DIRECT_PROVIDER_SELECTION_RETIRED, desktopBridgeMigrationGuidance());
|
|
75
73
|
}
|
|
76
|
-
const load = input.loadCodexLbEnvImpl || loadCodexLbEnv;
|
|
77
|
-
let loaded = null;
|
|
78
|
-
try {
|
|
79
|
-
loaded = await load({
|
|
80
|
-
home,
|
|
81
|
-
processEnv: {},
|
|
82
|
-
envPath: path.join(codexHome, 'sks-codex-lb.env'),
|
|
83
|
-
metadataPath: path.join(codexHome, 'sks-codex-lb.json')
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
catch {
|
|
87
|
-
throw new CodexAppServerRuntimeEnvError(CODEX_APP_SERVER_PROVIDER_CREDENTIALS_UNAVAILABLE, codexAppServerProviderCredentialGuidance(home));
|
|
88
|
-
}
|
|
89
|
-
if (!loaded?.configured || !loaded.secret_api_key || !loaded.base_url) {
|
|
90
|
-
throw new CodexAppServerRuntimeEnvError(CODEX_APP_SERVER_PROVIDER_CREDENTIALS_UNAVAILABLE, codexAppServerProviderCredentialGuidance(home));
|
|
91
|
-
}
|
|
92
|
-
env.CODEX_LB_API_KEY = loaded.secret_api_key;
|
|
93
|
-
env.CODEX_LB_BASE_URL = loaded.base_url;
|
|
94
74
|
return env;
|
|
95
75
|
}
|
|
@@ -68,7 +68,6 @@ export async function runCodexCurrentCoreImageReferencedPathRealProbe(input) {
|
|
|
68
68
|
maxBufferBytes: 512 * 1024,
|
|
69
69
|
codexBin,
|
|
70
70
|
env: runtimeEnv,
|
|
71
|
-
...(typeof input.recoveryFetch === 'function' ? { recoveryFetch: input.recoveryFetch } : {}),
|
|
72
71
|
...(typeof input.runProcessImpl === 'function' ? { runProcessImpl: input.runProcessImpl } : {})
|
|
73
72
|
}).catch((err) => ({ code: 1, stdout: '', stderr: err?.message || String(err) }));
|
|
74
73
|
const outputText = await fs.readFile(outputFile, 'utf8').catch(() => '');
|
|
@@ -98,12 +97,12 @@ export async function runCodexCurrentCoreImageReferencedPathRealProbe(input) {
|
|
|
98
97
|
process_exited_successfully: processExitedSuccessfully,
|
|
99
98
|
process_warning: processExitedSuccessfully ? null : 'Codex emitted the referenced path evidence before process timeout/nonzero exit.',
|
|
100
99
|
output_file: outputFile,
|
|
101
|
-
|
|
100
|
+
desktop_bridge_launch_guard: result.desktop_bridge_launch_guard || null,
|
|
102
101
|
contract_blockers: contract.blockers
|
|
103
102
|
},
|
|
104
103
|
blockers: ok ? [] : [
|
|
105
104
|
...(processExitedSuccessfully ? [] : ['codex_image_referenced_path_process_failed_or_timed_out']),
|
|
106
|
-
...(result.
|
|
105
|
+
...(result.desktop_bridge_launch_guard?.blockers || []),
|
|
107
106
|
...(!exactReferencedPath || !commandReferencesOnlyInputB || !outputReferencesInputB || contract.blockers.length > 0
|
|
108
107
|
? ['codex_image_referenced_path_actual_cli_probe_failed']
|
|
109
108
|
: [])
|
|
@@ -33,7 +33,6 @@ export async function runCodexCurrentCoreWebSearchRealProbe(input) {
|
|
|
33
33
|
stderrFile: path.join(tempDir, 'codex.stderr.log'),
|
|
34
34
|
codexBin,
|
|
35
35
|
env: runtimeEnv,
|
|
36
|
-
...(typeof input.recoveryFetch === 'function' ? { recoveryFetch: input.recoveryFetch } : {}),
|
|
37
36
|
...(typeof input.runProcessImpl === 'function' ? { runProcessImpl: input.runProcessImpl } : {})
|
|
38
37
|
}).catch((err) => ({
|
|
39
38
|
code: 1,
|
|
@@ -76,11 +75,11 @@ export async function runCodexCurrentCoreWebSearchRealProbe(input) {
|
|
|
76
75
|
process_exited_successfully: processExitedSuccessfully,
|
|
77
76
|
process_warning: processExitedSuccessfully ? null : 'Codex emitted web-search evidence before process timeout/nonzero exit.',
|
|
78
77
|
output_file: outputFile,
|
|
79
|
-
|
|
78
|
+
desktop_bridge_launch_guard: result.desktop_bridge_launch_guard || null
|
|
80
79
|
},
|
|
81
80
|
blockers: ok ? [] : [
|
|
82
81
|
...(processExitedSuccessfully ? [] : ['codex_web_search_process_failed_or_timed_out']),
|
|
83
|
-
...(result.
|
|
82
|
+
...(result.desktop_bridge_launch_guard?.blockers || []),
|
|
84
83
|
...(!sawPlaintextResult || !resultContainsExpectedMarker ? ['codex_web_search_real_probe_failed'] : [])
|
|
85
84
|
]
|
|
86
85
|
};
|