sneakoscope 6.0.2 → 6.1.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 +5 -3
- package/config/codex-releases/{rust-v0.142.0.json → rust-v0.144.1.json} +6 -6
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/cli/install-helpers.js +255 -440
- package/dist/cli/router.js +53 -4
- package/dist/commands/codex-app.js +8 -3
- package/dist/commands/codex-lb.js +169 -40
- package/dist/commands/codex.js +6 -5
- package/dist/commands/doctor.js +60 -26
- package/dist/commands/versioning.js +7 -0
- package/dist/config/skills-manifest.json +57 -57
- package/dist/core/agents/agent-central-ledger.js +9 -0
- package/dist/core/agents/agent-cleanup-executor.js +334 -41
- package/dist/core/agents/agent-cleanup.js +20 -1
- package/dist/core/agents/agent-command-surface.js +2 -1
- package/dist/core/agents/agent-effort-policy.js +46 -33
- package/dist/core/agents/agent-janitor.js +9 -10
- package/dist/core/agents/agent-namespace-safety.js +56 -0
- package/dist/core/agents/agent-orchestrator.js +26 -4
- package/dist/core/agents/agent-output-validator.js +1 -1
- package/dist/core/agents/agent-proof-evidence.js +16 -2
- package/dist/core/agents/agent-role-config.js +3 -6
- package/dist/core/agents/agent-roster.js +2 -2
- package/dist/core/agents/agent-runner-codex-exec.js +2 -0
- package/dist/core/agents/agent-runner-process.js +1 -0
- package/dist/core/agents/fast-mode-policy.js +3 -5
- package/dist/core/agents/native-cli-session-swarm.js +18 -1
- package/dist/core/agents/native-worker-backend-router.js +180 -108
- package/dist/core/agents/parallel-write-fixture.js +15 -10
- package/dist/core/agents/runtime-proof-summary.js +21 -3
- package/dist/core/agents/work-partition/repo-inventory.js +68 -7
- package/dist/core/code-structure.js +5 -4
- package/dist/core/codex/codex-config-guard.js +31 -9
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +51 -20
- package/dist/core/codex-app/codex-app-restart.js +38 -8
- package/dist/core/codex-app/codex-app-ui-state-snapshot.js +11 -3
- package/dist/core/codex-app/sks-menubar.js +100 -40
- package/dist/core/codex-app.js +60 -17
- package/dist/core/codex-compat/codex-hook-warning-detector.js +10 -1
- package/dist/core/codex-compat/codex-release-manifest.js +6 -6
- package/dist/core/codex-control/codex-0139-doctor-real-probe.js +7 -1
- package/dist/core/codex-control/codex-0139-image-path-real-probe.js +14 -8
- package/dist/core/codex-control/codex-0139-probe-runner.js +103 -28
- package/dist/core/codex-control/codex-0139-real-probe-summary.js +7 -3
- package/dist/core/codex-control/codex-0139-real-probes.js +21 -6
- package/dist/core/codex-control/codex-0139-sandbox-real-probe.js +39 -13
- package/dist/core/codex-control/codex-0139-web-search-probe.js +11 -8
- package/dist/core/codex-control/{codex-0142-capability.js → codex-0144-capability.js} +22 -22
- package/dist/core/codex-control/codex-0144-collab-agent-real-probe.js +63 -0
- package/dist/core/codex-control/codex-model-metadata.js +8 -4
- package/dist/core/codex-control/codex-multi-agent-event-normalizer.js +5 -1
- package/dist/core/codex-control/codex-reliability-shield.js +4 -1
- package/dist/core/codex-control/codex-sdk-adapter.js +53 -6
- package/dist/core/codex-control/codex-sdk-config-policy.js +2 -1
- package/dist/core/codex-control/codex-sdk-sandbox-policy.js +6 -3
- package/dist/core/codex-lb/codex-lb-env.js +107 -0
- package/dist/core/codex-lb/codex-lb-tool-catalog.js +478 -0
- package/dist/core/codex-native/codex-native-feature-broker.js +22 -22
- package/dist/core/codex-native/codex-native-feature-matrix.js +2 -2
- package/dist/core/codex-native/native-capability-postcheck.js +16 -8
- package/dist/core/codex-native/native-capability-repair-matrix.js +76 -27
- package/dist/core/codex-plugins/codex-plugin-json.js +67 -21
- package/dist/core/codex-plugins/codex-plugin-repair.js +118 -0
- package/dist/core/codex-runtime/codex-desktop-config-policy.js +306 -0
- package/dist/core/commands/agent-command.js +19 -0
- package/dist/core/commands/basic-cli.js +45 -24
- package/dist/core/commands/gc-command.js +27 -4
- package/dist/core/commands/image-ux-review-command.js +55 -24
- package/dist/core/commands/mad-sks-command.js +152 -132
- package/dist/core/commands/naruto-command.js +41 -10
- package/dist/core/commands/pipeline-command.js +1 -0
- package/dist/core/commands/wiki-command.js +179 -83
- package/dist/core/computer-use-live-evidence.js +166 -3
- package/dist/core/computer-use-status.js +5 -2
- package/dist/core/daemon/sksd-hook-daemon-entrypoint.js +2 -2
- package/dist/core/daemon/sksd-hook-daemon.js +171 -28
- package/dist/core/daemon/sksd-hook-dispatch.js +2 -2
- package/dist/core/dfix/verification-selector.js +6 -4
- package/dist/core/doctor/browser-use-repair.js +54 -13
- package/dist/core/doctor/codex-0139-doctor.js +3 -2
- package/dist/core/doctor/computer-use-repair.js +28 -39
- package/dist/core/doctor/doctor-codex-startup-repair.js +19 -9
- package/dist/core/doctor/doctor-context7-repair.js +1 -1
- package/dist/core/doctor/doctor-dirty-planner.js +1 -1
- package/dist/core/doctor/doctor-native-capability-repair.js +74 -3
- package/dist/core/doctor/imagegen-repair.js +47 -12
- package/dist/core/doctor/legacy-global-hook-cleanup.js +179 -0
- package/dist/core/feature-registry.js +25 -31
- package/dist/core/fsx.js +54 -6
- package/dist/core/harness-conflicts.js +1 -1
- package/dist/core/hooks-runtime/code-pack-freshness-preflight.js +5 -4
- package/dist/core/hooks-runtime/hook-invocation-dedupe.js +147 -0
- package/dist/core/hooks-runtime/hook-io.js +6 -0
- package/dist/core/hooks-runtime.js +17 -2
- package/dist/core/image/image-artifact-path-contract.js +8 -6
- package/dist/core/image/image-artifact-registry.js +5 -1
- package/dist/core/image-ux-review/imagegen-adapter.js +5 -2
- package/dist/core/imagegen/imagegen-capability.js +10 -13
- package/dist/core/imagegen/require-imagegen.js +37 -11
- package/dist/core/managed-assets/managed-assets-manifest.js +1 -5
- package/dist/core/naruto/naruto-work-graph.js +70 -4
- package/dist/core/naruto/naruto-write-e2e.js +3 -4
- package/dist/core/ops/reporting.js +3 -0
- package/dist/core/pipeline-internals/runtime-core.js +12 -7
- package/dist/core/pipeline-internals/runtime-gates.js +17 -1
- package/dist/core/ppt/style-tokens.js +1 -1
- package/dist/core/ppt-review/index.js +1 -1
- package/dist/core/ppt-review/slide-exporter.js +23 -17
- package/dist/core/ppt-review/slide-imagegen-review.js +1 -1
- package/dist/core/ppt-review/slide-issue-extraction.js +4 -2
- package/dist/core/product-design-plugin.js +2 -2
- package/dist/core/proof/route-finalizer.js +1 -1
- package/dist/core/proof-field.js +3 -3
- package/dist/core/provider/model-router.js +68 -3
- package/dist/core/release/gate-manifest.js +18 -12
- package/dist/core/release/gate-pack-manifest.js +1 -1
- package/dist/core/release/package-size-budget.js +2 -0
- package/dist/core/release/release-gate-affected-selector.js +1 -1
- package/dist/core/release/release-gate-dag.js +43 -3
- package/dist/core/release/release-gate-hermetic-env.js +28 -17
- package/dist/core/release/release-real-contract.js +416 -0
- package/dist/core/retention/retention-budget.js +25 -6
- package/dist/core/retention.js +980 -101
- package/dist/core/routes/constants.js +1 -1
- package/dist/core/routes/evidence.js +4 -4
- package/dist/core/routes/model-mode-router.js +3 -0
- package/dist/core/routes/ppt-policy.js +1 -1
- package/dist/core/routes.js +11 -12
- package/dist/core/secret-redaction.js +4 -0
- package/dist/core/triwiki/code-pack.js +8 -2
- package/dist/core/triwiki/triwiki-cache-key.js +108 -29
- package/dist/core/triwiki-attention.js +13 -6
- package/dist/core/triwiki-provenance.js +274 -0
- package/dist/core/triwiki-runtime.js +21 -7
- package/dist/core/triwiki-wrongness/wrongness-ledger.js +178 -59
- package/dist/core/triwiki-wrongness/wrongness-retrieval.js +11 -2
- package/dist/core/triwiki-wrongness/wrongness-trust-policy.js +2 -0
- package/dist/core/update/update-migration-state.js +1 -1
- package/dist/core/update/update-notice.js +23 -0
- package/dist/core/update-check.js +69 -25
- package/dist/core/version.js +1 -1
- package/dist/core/wiki-coordinate.js +128 -12
- package/dist/core/work-order-ledger.js +168 -9
- package/dist/core/zellij/zellij-command.js +12 -1
- package/dist/core/zellij/zellij-dashboard-pane.js +3 -3
- package/dist/core/zellij/zellij-launcher.js +15 -14
- package/dist/core/zellij/zellij-pane-proof.js +32 -6
- package/dist/core/zellij/zellij-worker-pane-manager.js +5 -3
- package/dist/scripts/agent-fast-mode-default-check.js +48 -29
- package/dist/scripts/agent-role-config-repair-check.js +25 -4
- package/dist/scripts/agent-wiki-context-proof-check.js +16 -2
- package/dist/scripts/all-feature-deep-completion-check.js +14 -4
- package/dist/scripts/build-dist.js +17 -5
- package/dist/scripts/canonical-test-runner.js +188 -0
- package/dist/scripts/check-command-module-budget.js +38 -16
- package/dist/scripts/check-legacy-free.js +1 -1
- package/dist/scripts/codex-0139-interrupt-agent-check.js +5 -1
- package/dist/scripts/{codex-0142-app-server-v2-check.js → codex-0144-app-server-v2-check.js} +11 -10
- package/dist/scripts/{codex-0142-binary-identity-check.js → codex-0144-binary-identity-check.js} +4 -4
- package/dist/scripts/codex-0144-capability-check.js +21 -0
- package/dist/scripts/{codex-0139-real-probes-check.js → codex-0144-core-real-probes-check.js} +19 -5
- package/dist/scripts/{codex-0142-doctor-wiring-check.js → codex-0144-doctor-wiring-check.js} +6 -6
- package/dist/scripts/{codex-0142-manifest-check.js → codex-0144-manifest-check.js} +11 -3
- package/dist/scripts/{codex-0142-policy-check.js → codex-0144-policy-check.js} +2 -2
- package/dist/scripts/{codex-0142-thread-store-check.js → codex-0144-thread-store-check.js} +3 -3
- package/dist/scripts/codex-app-provider-model-ui-check.js +57 -8
- package/dist/scripts/codex-app-ui-preservation-check.js +35 -4
- package/dist/scripts/codex-control-side-effect-scope-check.js +2 -2
- package/dist/scripts/codex-effort-auto-discovery-check.js +1 -1
- package/dist/scripts/codex-lb-fast-mode-truth-check.js +1 -0
- package/dist/scripts/{codex-lb-gpt55-fast-profile-check.js → codex-lb-gpt56-fast-profile-check.js} +56 -5
- package/dist/scripts/codex-model-metadata-check.js +1 -1
- package/dist/scripts/codex-sdk-sandbox-policy-check.js +5 -1
- package/dist/scripts/codex-sdk-version-compat-check.js +2 -1
- package/dist/scripts/dfix-fixture-check.js +1 -1
- package/dist/scripts/docs-truthfulness-check.js +1 -1
- package/dist/scripts/doctor-codex-startup-repair-check.js +35 -10
- package/dist/scripts/doctor-context7-repair-check.js +2 -1
- package/dist/scripts/doctor-fix-proves-codex-read-check.js +1 -1
- package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +34 -7
- package/dist/scripts/doctor-imagegen-repair-check.js +14 -4
- package/dist/scripts/doctor-startup-config-repair-blackbox.js +1 -1
- package/dist/scripts/doctor-startup-config-repair-check.js +1 -1
- package/dist/scripts/gate-policy-audit-check.js +2 -2
- package/dist/scripts/install-update-preserves-config-check.js +1 -1
- package/dist/scripts/legacy-gate-inventory-check.js +7 -5
- package/dist/scripts/legacy-strong-inventory-check.js +7 -5
- package/dist/scripts/legacy-upgrade-matrix-check.js +5 -5
- package/dist/scripts/lib/native-cli-session-swarm-check-lib.js +175 -14
- package/dist/scripts/mad-sks-app-ui-no-mutation-check.js +166 -6
- package/dist/scripts/mutation-callsite-coverage-check.js +0 -11
- package/dist/scripts/naruto-shadow-clone-swarm-check.js +88 -50
- package/dist/scripts/npm-publish-performance-check.js +2 -1
- package/dist/scripts/package-published-contract-check.js +9 -0
- package/dist/scripts/packlist-performance-check.js +5 -2
- package/dist/scripts/postinstall-safe-side-effects-check.js +8 -3
- package/dist/scripts/ppt-no-mock-as-real-check.js +3 -1
- package/dist/scripts/product-design-plugin-routing-check.js +1 -1
- package/dist/scripts/release-check-stamp.js +182 -2
- package/dist/scripts/release-dag-full-coverage-check.js +7 -7
- package/dist/scripts/release-dynamic-presets-check.js +8 -0
- package/dist/scripts/release-gate-dag-runner-check.js +3 -2
- package/dist/scripts/release-gate-dag-runner.js +24 -11
- package/dist/scripts/release-gate-existence-audit.js +8 -9
- package/dist/scripts/release-gate-script-parity-check.js +1 -1
- package/dist/scripts/release-real-check.js +368 -157
- package/dist/scripts/release-runtime-truth-matrix-check.js +22 -0
- package/dist/scripts/route-proof-artifact-structure-check.js +1 -0
- package/dist/scripts/scheduler-batch-dispatch-check.js +1 -1
- package/dist/scripts/search-visibility-gate-lib.js +1 -1
- package/dist/scripts/seo-geo-route-identity-check.js +30 -4
- package/dist/scripts/sizecheck.js +7 -2
- package/dist/scripts/sks-1-11-gate-lib.js +53 -6
- package/dist/scripts/sks-menubar-install-check.js +7 -0
- package/dist/scripts/sks-uninstall-regression-check.js +1 -1
- package/dist/scripts/sksd-daemon-check.js +16 -6
- package/dist/scripts/update-default-command-check.js +4 -2
- package/dist/scripts/write-build-manifest.js +2 -1
- package/dist/scripts/zellij-layout-valid-check.js +31 -6
- package/dist/scripts/zellij-pane-proof-check.js +33 -2
- package/dist/scripts/zellij-real-session-cleanup-check.js +122 -2
- package/dist/scripts/zellij-real-session-launch-check.js +76 -5
- package/dist/scripts/zellij-slot-pane-renderer-check.js +4 -4
- package/package.json +27 -30
- package/schemas/codex/{app-server-0.142 → app-server-0.144}/codex_app_server_protocol.v2.schemas.json +1146 -781
- package/schemas/codex/codex-0139-real-probe-result.schema.json +39 -5
- package/schemas/codex/ppt-slide-issue-ledger.schema.json +2 -1
- package/dist/core/codex-control/codex-0139-multi-agent-real-probe.js +0 -107
- package/dist/scripts/agent-native-release-gate.js +0 -274
- package/dist/scripts/codex-0142-capability-check.js +0 -21
- package/dist/scripts/command-performance-scorecard-check.js +0 -204
- package/dist/scripts/config-managed-merge-callsite-coverage-check.js +0 -212
- package/dist/scripts/dollar-performance-scorecard-check.js +0 -257
- package/dist/scripts/gate-timing-check.js +0 -16
- package/dist/scripts/ops-maturity-scorecard-check.js +0 -12
- package/dist/scripts/performance-baseline-check.js +0 -12
- package/dist/scripts/performance-improvement-report-check.js +0 -58
- package/dist/scripts/release-parallel-check.js +0 -389
- package/dist/scripts/release-runner-efficiency-check.js +0 -15
- package/dist/scripts/retention-long-run-smoke-check.js +0 -299
- package/docs/assets/sneakoscope-architecture-pipeline.jpg +0 -0
package/dist/core/codex-app.js
CHANGED
|
@@ -9,7 +9,8 @@ import { PRODUCT_DESIGN_AUTO_INSTALL_ENV, ensureProductDesignPluginInstalled, pr
|
|
|
9
9
|
import { GLM_CODEX_CONFIG_PROVIDER_ID, GLM_CODEX_CONFIG_REASONING_PROFILES } from './codex-app/glm-model-profile.js';
|
|
10
10
|
import { GLM_52_OPENROUTER_MODEL } from './providers/glm/glm-52-settings.js';
|
|
11
11
|
import { resolveOpenRouterApiKey } from './providers/openrouter/openrouter-secret-store.js';
|
|
12
|
-
import { codexLbEnvPath, parseShellEnvValue } from './codex-lb/codex-lb-env.js';
|
|
12
|
+
import { codexLbEnvPath, loadCodexLbEnv, parseShellEnvValue, readCodexLbModelCatalog } from './codex-lb/codex-lb-env.js';
|
|
13
|
+
import { redactString } from './secret-redaction.js';
|
|
13
14
|
export const CODEX_APP_DOCS_URL = 'https://developers.openai.com/codex/app/features';
|
|
14
15
|
export const CODEX_CHANGELOG_URL = 'https://developers.openai.com/codex/changelog';
|
|
15
16
|
export const CODEX_ACCESS_TOKENS_DOCS_URL = 'https://developers.openai.com/codex/enterprise/access-tokens';
|
|
@@ -35,6 +36,8 @@ export function codexAppCandidatePaths(home = os.homedir(), env = process.env) {
|
|
|
35
36
|
if (env.SKS_CODEX_APP_PATH)
|
|
36
37
|
candidates.push(env.SKS_CODEX_APP_PATH);
|
|
37
38
|
if (process.platform === 'darwin') {
|
|
39
|
+
candidates.push('/Applications/ChatGPT.app');
|
|
40
|
+
candidates.push(path.join(home || '', 'Applications', 'ChatGPT.app'));
|
|
38
41
|
candidates.push('/Applications/Codex.app');
|
|
39
42
|
candidates.push(path.join(home || '', 'Applications', 'Codex.app'));
|
|
40
43
|
}
|
|
@@ -96,30 +99,32 @@ export async function codexMcpList(opts = {}) {
|
|
|
96
99
|
const codex = opts.codex || await getCodexInfo().catch(() => EMPTY_CODEX_INFO);
|
|
97
100
|
if (!codex.bin)
|
|
98
101
|
return { ok: false, checked: false, stdout: '', stderr: 'Codex CLI missing.' };
|
|
99
|
-
const
|
|
102
|
+
const execute = opts.runProcess || runProcess;
|
|
103
|
+
const out = await execute(codex.bin, ['mcp', 'list'], {
|
|
100
104
|
timeoutMs: opts.timeoutMs || 10000,
|
|
101
105
|
maxOutputBytes: 64 * 1024
|
|
102
106
|
}).catch((err) => ({ code: 1, stdout: '', stderr: err.message }));
|
|
103
107
|
return {
|
|
104
108
|
ok: out.code === 0,
|
|
105
109
|
checked: true,
|
|
106
|
-
stdout: out.stdout || '',
|
|
107
|
-
stderr: out.stderr || ''
|
|
110
|
+
stdout: redactString(out.stdout || ''),
|
|
111
|
+
stderr: redactString(out.stderr || '')
|
|
108
112
|
};
|
|
109
113
|
}
|
|
110
114
|
export async function codexFeatureList(opts = {}) {
|
|
111
115
|
const codex = opts.codex || await getCodexInfo().catch(() => EMPTY_CODEX_INFO);
|
|
112
116
|
if (!codex.bin)
|
|
113
117
|
return { ok: false, checked: false, stdout: '', stderr: 'Codex CLI missing.' };
|
|
114
|
-
const
|
|
118
|
+
const execute = opts.runProcess || runProcess;
|
|
119
|
+
const out = await execute(codex.bin, ['features', 'list'], {
|
|
115
120
|
timeoutMs: opts.timeoutMs || 10000,
|
|
116
121
|
maxOutputBytes: 64 * 1024
|
|
117
122
|
}).catch((err) => ({ code: 1, stdout: '', stderr: err.message }));
|
|
118
123
|
return {
|
|
119
124
|
ok: out.code === 0,
|
|
120
125
|
checked: true,
|
|
121
|
-
stdout: out.stdout || '',
|
|
122
|
-
stderr: out.stderr || ''
|
|
126
|
+
stdout: redactString(out.stdout || ''),
|
|
127
|
+
stderr: redactString(out.stderr || '')
|
|
123
128
|
};
|
|
124
129
|
}
|
|
125
130
|
export async function codexAppIntegrationStatus(opts = {}) {
|
|
@@ -161,7 +166,8 @@ export async function codexAppIntegrationStatus(opts = {}) {
|
|
|
161
166
|
});
|
|
162
167
|
const pluginPickerReady = requiredFeatureFlags.tool_suggest && requiredFeatureFlags.plugins && requiredFeatureFlags.apps && defaultPlugins.ok && pluginSkillShadows.ok && fastModeConfig.ok;
|
|
163
168
|
const gitActions = codexGitActionReadiness({ requiredFeatureFlags, remoteControl });
|
|
164
|
-
const
|
|
169
|
+
const selectedProviderReady = providerModelUi.selected_provider_ok !== false;
|
|
170
|
+
const ready = appInstalled && Boolean(codex.bin) && mcpList.ok && featureList.ok && requiredFeatureFlagsOk && pluginPickerReady && fastModeConfig.ok && selectedProviderReady && imageGenerationReady && gitActions.ok && computerUseReady && browserToolReady && chromeExtension.ok;
|
|
165
171
|
return {
|
|
166
172
|
ok: ready,
|
|
167
173
|
app: {
|
|
@@ -194,6 +200,7 @@ export async function codexAppIntegrationStatus(opts = {}) {
|
|
|
194
200
|
required_flags_ok: requiredFeatureFlagsOk,
|
|
195
201
|
fast_mode_config: fastModeConfig,
|
|
196
202
|
provider_model_ui: providerModelUi,
|
|
203
|
+
selected_provider_ready: selectedProviderReady,
|
|
197
204
|
git_actions: gitActions,
|
|
198
205
|
image_generation: imageGenerationReady,
|
|
199
206
|
image_generation_source: imageGenerationReady ? 'codex_features_list' : 'missing',
|
|
@@ -545,7 +552,8 @@ export function codexAppGuidance({ appInstalled, codex, mcpList, featureList, re
|
|
|
545
552
|
lines.push(`Run: ${providerModelUi.glm.key_command}; then ${providerModelUi.glm.install_command}; restart Codex App if the model picker was already open.`);
|
|
546
553
|
}
|
|
547
554
|
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) {
|
|
548
|
-
lines.push(`codex-lb key entry path is
|
|
555
|
+
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}.`);
|
|
556
|
+
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.');
|
|
549
557
|
}
|
|
550
558
|
else if (providerModelUi?.codex_lb?.key_entry_visible) {
|
|
551
559
|
lines.push(`codex-lb key entry path is visible, but setup is incomplete: ${providerModelUi.codex_lb.blockers.join(', ') || 'setup required'}.`);
|
|
@@ -938,6 +946,14 @@ export async function codexProviderModelUiStatus(opts = {}) {
|
|
|
938
946
|
&& hasTomlBoolean(codexLbProvider, 'supports_websockets', true)
|
|
939
947
|
&& hasTomlBoolean(codexLbProvider, 'requires_openai_auth', true);
|
|
940
948
|
const codexLbSelectedDefault = /(?:^|\n)\s*model_provider\s*=\s*"codex-lb"\s*(?:#.*)?(?=\n|$)/.test(topLevelToml(globalConfig));
|
|
949
|
+
let codexLbModelCatalog = opts.codexLbModelCatalog || null;
|
|
950
|
+
if (!codexLbModelCatalog && codexLbProviderContractOk && codexLbApiKeySource !== 'missing' && codexLbBaseUrlSource !== 'missing') {
|
|
951
|
+
const loadedEnv = await loadCodexLbEnv({ home, envPath: codexLbEnvFilePath }).catch(() => null);
|
|
952
|
+
codexLbModelCatalog = loadedEnv ? await readCodexLbModelCatalog({ loadedEnv }).catch(() => null) : null;
|
|
953
|
+
}
|
|
954
|
+
const expectedCodexLbModels = ['gpt-5.6-luna', 'gpt-5.6-terra', 'gpt-5.6-sol'];
|
|
955
|
+
const catalogModels = Array.isArray(codexLbModelCatalog?.models) ? codexLbModelCatalog.models.map(String) : [];
|
|
956
|
+
const expectedCodexLbModelsPresent = expectedCodexLbModels.every((model) => catalogModels.includes(model));
|
|
941
957
|
const glmBlockers = [
|
|
942
958
|
...(glmProviderPresent ? [] : ['glm_openrouter_provider_missing']),
|
|
943
959
|
...glmProfileBlockers,
|
|
@@ -947,18 +963,34 @@ export async function codexProviderModelUiStatus(opts = {}) {
|
|
|
947
963
|
...(codexLbProviderPresent ? [] : ['codex_lb_provider_missing']),
|
|
948
964
|
...(codexLbProviderPresent && !codexLbProviderContractOk ? ['codex_lb_provider_contract_drift'] : []),
|
|
949
965
|
...(codexLbApiKeySource !== 'missing' ? [] : ['codex_lb_api_key_missing']),
|
|
950
|
-
...(codexLbBaseUrlSource !== 'missing' ? [] : ['codex_lb_base_url_missing'])
|
|
966
|
+
...(codexLbBaseUrlSource !== 'missing' ? [] : ['codex_lb_base_url_missing']),
|
|
967
|
+
...(codexLbProviderContractOk && codexLbApiKeySource !== 'missing' && codexLbBaseUrlSource !== 'missing' && !expectedCodexLbModelsPresent
|
|
968
|
+
? ['codex_lb_gpt_5_6_catalog_unverified']
|
|
969
|
+
: [])
|
|
951
970
|
];
|
|
952
|
-
const
|
|
971
|
+
const selectedProviderBlockers = codexLbSelectedDefault ? codexLbBlockers : [];
|
|
972
|
+
const optionalProviderBlockers = codexLbSelectedDefault
|
|
973
|
+
? glmBlockers
|
|
974
|
+
: [...glmBlockers, ...codexLbBlockers];
|
|
953
975
|
const keyCommand = 'sks codex-app set-openrouter-key --api-key-stdin';
|
|
954
976
|
const installCommand = 'sks codex-app glm-profile install';
|
|
955
977
|
const setupCommand = 'sks codex-lb setup --host <domain> --api-key-stdin --yes';
|
|
956
978
|
const setKeyCommand = 'sks codex-lb set-key --api-key-stdin';
|
|
957
979
|
return {
|
|
958
980
|
schema: 'sks.codex-app-provider-model-ui.v1',
|
|
959
|
-
|
|
981
|
+
// The top-level readiness contract is intentionally scoped to the active
|
|
982
|
+
// provider. Optional GLM/OpenRouter and codex-lb setup diagnostics remain
|
|
983
|
+
// visible below without making an unrelated provider selection fail.
|
|
984
|
+
ok: selectedProviderBlockers.length === 0,
|
|
985
|
+
selected_provider_ok: selectedProviderBlockers.length === 0,
|
|
986
|
+
selected_provider: codexLbSelectedDefault ? 'codex-lb' : 'oauth',
|
|
987
|
+
selected_provider_blockers: selectedProviderBlockers,
|
|
988
|
+
optional_provider_blockers: optionalProviderBlockers,
|
|
960
989
|
checked: true,
|
|
961
|
-
|
|
990
|
+
verification_scope: 'config_and_provider_catalog',
|
|
991
|
+
desktop_picker_verified: false,
|
|
992
|
+
status: selectedProviderBlockers.length === 0 ? 'ready' : 'setup_required',
|
|
993
|
+
optional_provider_status: optionalProviderBlockers.length === 0 ? 'ready' : 'setup_available',
|
|
962
994
|
config_paths: {
|
|
963
995
|
codex_config: globalConfigPath,
|
|
964
996
|
project_config: projectConfig ? projectConfigPath : null,
|
|
@@ -988,6 +1020,12 @@ export async function codexProviderModelUiStatus(opts = {}) {
|
|
|
988
1020
|
api_key_source: codexLbApiKeySource,
|
|
989
1021
|
base_url_present: codexLbBaseUrlSource !== 'missing',
|
|
990
1022
|
base_url_source: codexLbBaseUrlSource,
|
|
1023
|
+
model_catalog_checked: Boolean(codexLbModelCatalog),
|
|
1024
|
+
model_catalog_ok: codexLbModelCatalog?.ok === true,
|
|
1025
|
+
model_catalog_models: catalogModels,
|
|
1026
|
+
expected_models: expectedCodexLbModels,
|
|
1027
|
+
expected_models_present: expectedCodexLbModelsPresent,
|
|
1028
|
+
model_catalog_blockers: codexLbModelCatalog?.blockers || [],
|
|
991
1029
|
setup_command: setupCommand,
|
|
992
1030
|
set_key_command: setKeyCommand,
|
|
993
1031
|
status_command: 'sks codex-lb status',
|
|
@@ -1000,7 +1038,7 @@ export async function codexProviderModelUiStatus(opts = {}) {
|
|
|
1000
1038
|
setKeyCommand,
|
|
1001
1039
|
'sks codex-app status'
|
|
1002
1040
|
],
|
|
1003
|
-
blockers
|
|
1041
|
+
blockers: selectedProviderBlockers
|
|
1004
1042
|
};
|
|
1005
1043
|
}
|
|
1006
1044
|
async function readTextIfExists(file) {
|
|
@@ -1065,9 +1103,14 @@ function productDesignStatusSummary(status = {}) {
|
|
|
1065
1103
|
function providerModelUiSummary(status = {}) {
|
|
1066
1104
|
if (!status?.checked)
|
|
1067
1105
|
return ' not checked';
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1106
|
+
const selected = status.selected_provider || 'oauth';
|
|
1107
|
+
if (status.ok) {
|
|
1108
|
+
const optionalSetup = (status.optional_provider_blockers || []).length > 0
|
|
1109
|
+
? ', optional providers can be configured'
|
|
1110
|
+
: '';
|
|
1111
|
+
return ` ${selected} ready${optionalSetup} (live picker reload required)`;
|
|
1112
|
+
}
|
|
1113
|
+
return ` ${selected} setup ${(status.selected_provider_blockers || status.blockers || []).join(', ') || 'required'}`;
|
|
1071
1114
|
}
|
|
1072
1115
|
function sksNativeMenuSummary(status = {}) {
|
|
1073
1116
|
if (!status)
|
|
@@ -15,7 +15,8 @@ export async function detectCodexHookOutputWarnings(eventLike, output) {
|
|
|
15
15
|
const issues = [
|
|
16
16
|
...validation.structured_issues,
|
|
17
17
|
...semantic.issues,
|
|
18
|
-
...snakeCaseKeyIssues(output)
|
|
18
|
+
...snakeCaseKeyIssues(output),
|
|
19
|
+
...unknownTopLevelKeyIssues(output)
|
|
19
20
|
];
|
|
20
21
|
for (const key of LEGACY_TOP_LEVEL_KEYS) {
|
|
21
22
|
if (output && typeof output === 'object' && Object.prototype.hasOwnProperty.call(output, key)) {
|
|
@@ -52,6 +53,14 @@ export async function detectCodexHookOutputWarnings(eventLike, output) {
|
|
|
52
53
|
warnings: [...new Set(warnings)]
|
|
53
54
|
};
|
|
54
55
|
}
|
|
56
|
+
function unknownTopLevelKeyIssues(output) {
|
|
57
|
+
if (!output || typeof output !== 'object' || Array.isArray(output))
|
|
58
|
+
return [];
|
|
59
|
+
const allowed = new Set(['continue', 'decision', 'reason', 'hookSpecificOutput']);
|
|
60
|
+
return Object.keys(output)
|
|
61
|
+
.filter((key) => !allowed.has(key))
|
|
62
|
+
.map((key) => makeCodexHookIssue('policy_disallowed', `unknown_field_${key}`, `Unknown top-level hook field is not accepted by the SKS zero-warning contract: ${key}.`, { path: `$.${key}`, upstream_supported: false, sks_disallowed: true }));
|
|
63
|
+
}
|
|
55
64
|
export async function codexHookWarningCheck(root, opts = {}) {
|
|
56
65
|
root ||= await projectRoot();
|
|
57
66
|
const fixtureValidation = await validateCodexFixtureOutputs(root);
|
|
@@ -3,13 +3,13 @@ import { packageRoot, readJson, readText, sha256 } from '../fsx.js';
|
|
|
3
3
|
export const CODEX_RELEASE_MANIFEST_SCHEMA = 'sks.codex-release-manifest.v1';
|
|
4
4
|
export const CURRENT_CODEX_RELEASE_MANIFEST = {
|
|
5
5
|
schema: CODEX_RELEASE_MANIFEST_SCHEMA,
|
|
6
|
-
targetTag: 'rust-v0.
|
|
7
|
-
requiredCliVersion: '0.
|
|
8
|
-
sdkVersion: '0.
|
|
9
|
-
minimumSupportedVersion: '0.
|
|
6
|
+
targetTag: 'rust-v0.144.1',
|
|
7
|
+
requiredCliVersion: '0.144.1',
|
|
8
|
+
sdkVersion: '0.144.1',
|
|
9
|
+
minimumSupportedVersion: '0.144.1',
|
|
10
10
|
protocolMode: 'app-server-v2',
|
|
11
|
-
generatedSchemaSha256: '
|
|
12
|
-
upstreamCommit: 'rust-v0.
|
|
11
|
+
generatedSchemaSha256: '2b3f14fa2e728f77a16385ff39f3a1d85ab255c1020498a85c1c0fb24f3d2f3c',
|
|
12
|
+
upstreamCommit: 'rust-v0.144.1',
|
|
13
13
|
featurePolicies: {
|
|
14
14
|
multiAgentMode: 'probe',
|
|
15
15
|
indexedWebSearch: 'probe',
|
|
@@ -10,8 +10,13 @@ export async function runCodex0139DoctorEnvRealProbe(input) {
|
|
|
10
10
|
return skippedCodex0139Probe('codex_cli_missing');
|
|
11
11
|
const tempDir = path.join(input.root, '.sneakoscope', 'tmp', 'codex-0139-real-probes', `doctor-${Date.now()}`);
|
|
12
12
|
await ensureDir(tempDir);
|
|
13
|
+
const isolatedHome = path.join(tempDir, 'home');
|
|
14
|
+
const isolatedCodexHome = path.join(isolatedHome, '.codex');
|
|
15
|
+
await ensureDir(isolatedCodexHome);
|
|
13
16
|
const env = {
|
|
14
17
|
...process.env,
|
|
18
|
+
HOME: isolatedHome,
|
|
19
|
+
CODEX_HOME: isolatedCodexHome,
|
|
15
20
|
EDITOR: 'vim',
|
|
16
21
|
PAGER: 'less',
|
|
17
22
|
TERM: 'xterm-256color',
|
|
@@ -48,7 +53,8 @@ export async function runCodex0139DoctorEnvRealProbe(input) {
|
|
|
48
53
|
redacted_marker_or_omitted: redactedMarkerOrOmitted,
|
|
49
54
|
redacted_sample_contains_secret: redactedText.includes('sk-test-secret-value') || redactedText.includes('test-secret-token'),
|
|
50
55
|
process_exited_successfully: processExitedSuccessfully,
|
|
51
|
-
process_warning: processExitedSuccessfully ? null : 'codex doctor returned nonzero after emitting the
|
|
56
|
+
process_warning: processExitedSuccessfully ? null : 'codex doctor returned nonzero after emitting the scoped env/redaction evidence.',
|
|
57
|
+
isolated_codex_home: true
|
|
52
58
|
},
|
|
53
59
|
blockers: ok ? [] : ['codex_doctor_env_redaction_real_probe_failed']
|
|
54
60
|
};
|
|
@@ -4,7 +4,7 @@ import { buildCodexExecArgs, findCodexBinary } from '../codex-adapter.js';
|
|
|
4
4
|
import { ensureDir, runProcess, writeBinaryAtomic } from '../fsx.js';
|
|
5
5
|
import { buildImageArtifactPathContract } from '../image/image-artifact-path-contract.js';
|
|
6
6
|
import { codex0139ProbeTail, skippedCodex0139Probe } from './codex-0139-real-probes.js';
|
|
7
|
-
const ONE_BY_ONE_PNG = Buffer.from('
|
|
7
|
+
const ONE_BY_ONE_PNG = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4//8/AAX+Av4N70a4AAAAAElFTkSuQmCC', 'base64');
|
|
8
8
|
export async function runCodex0139ImageReferencedPathRealProbe(input) {
|
|
9
9
|
const started = Date.now();
|
|
10
10
|
const tempDir = path.join(input.root, '.sneakoscope', 'tmp', 'codex-0139-real-probes', `image-path-${Date.now()}`);
|
|
@@ -14,10 +14,10 @@ export async function runCodex0139ImageReferencedPathRealProbe(input) {
|
|
|
14
14
|
await writeBinaryAtomic(inputA, ONE_BY_ONE_PNG);
|
|
15
15
|
await writeBinaryAtomic(inputB, ONE_BY_ONE_PNG);
|
|
16
16
|
const contract = await buildImageArtifactPathContract(input.root, {
|
|
17
|
-
missionId: 'codex-
|
|
17
|
+
missionId: 'codex-0144-image-path-real-probe',
|
|
18
18
|
images: [
|
|
19
|
-
{ id: 'input-a', kind: 'input_attachment', filePath: inputA, route: 'codex-
|
|
20
|
-
{ id: 'input-b', kind: 'input_attachment', filePath: inputB, route: 'codex-
|
|
19
|
+
{ id: 'input-a', kind: 'input_attachment', filePath: inputA, route: 'codex-0144-core-real-probe', stage: 'candidate' },
|
|
20
|
+
{ id: 'input-b', kind: 'input_attachment', filePath: inputB, route: 'codex-0144-core-real-probe', stage: 'referenced' }
|
|
21
21
|
]
|
|
22
22
|
});
|
|
23
23
|
const codexBin = input.codexBin || await findCodexBinary();
|
|
@@ -34,7 +34,7 @@ export async function runCodex0139ImageReferencedPathRealProbe(input) {
|
|
|
34
34
|
artifact_paths: [tempDir]
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
|
-
if (process.env.SKS_CODEX_0139_IMAGE_REAL_PROBE_ALLOW_SKIP === '1') {
|
|
37
|
+
if (process.env.SKS_CODEX_0144_IMAGE_REAL_PROBE_ALLOW_SKIP === '1' || process.env.SKS_CODEX_0139_IMAGE_REAL_PROBE_ALLOW_SKIP === '1') {
|
|
38
38
|
return {
|
|
39
39
|
...skippedCodex0139Probe('codex_image_edit_actual_api_skipped', {
|
|
40
40
|
codex_bin: codexBin,
|
|
@@ -48,12 +48,12 @@ export async function runCodex0139ImageReferencedPathRealProbe(input) {
|
|
|
48
48
|
}
|
|
49
49
|
const outputFile = path.join(tempDir, 'last-message.txt');
|
|
50
50
|
const prompt = [
|
|
51
|
-
'This is a Codex 0.
|
|
51
|
+
'This is a Codex 0.144.1 image path routing probe.',
|
|
52
52
|
`Only the image file named ${path.basename(inputB)} is intentionally referenced.`,
|
|
53
53
|
`Return compact JSON {"referenced_path":"${inputB.replace(/\\/g, '\\\\')}","saw_image":true}.`,
|
|
54
54
|
'Do not edit files and do not reference any other image path.'
|
|
55
55
|
].join(' ');
|
|
56
|
-
const extraArgs = ['--image', inputB, '--skip-git-repo-check', '--ephemeral'];
|
|
56
|
+
const extraArgs = ['-c', 'mcp_servers={}', '--image', inputB, '--skip-git-repo-check', '--ephemeral'];
|
|
57
57
|
const args = buildCodexExecArgs({ root: tempDir, prompt, outputFile, json: true, extraArgs });
|
|
58
58
|
const result = await runProcess(codexBin, args, {
|
|
59
59
|
cwd: tempDir,
|
|
@@ -68,6 +68,7 @@ export async function runCodex0139ImageReferencedPathRealProbe(input) {
|
|
|
68
68
|
const ok = exactReferencedPath
|
|
69
69
|
&& commandReferencesOnlyInputB
|
|
70
70
|
&& outputReferencesInputB
|
|
71
|
+
&& processExitedSuccessfully
|
|
71
72
|
&& contract.blockers.length === 0;
|
|
72
73
|
return {
|
|
73
74
|
ok,
|
|
@@ -88,7 +89,12 @@ export async function runCodex0139ImageReferencedPathRealProbe(input) {
|
|
|
88
89
|
output_file: outputFile,
|
|
89
90
|
contract_blockers: contract.blockers
|
|
90
91
|
},
|
|
91
|
-
blockers: ok ? [] : [
|
|
92
|
+
blockers: ok ? [] : [
|
|
93
|
+
...(processExitedSuccessfully ? [] : ['codex_image_referenced_path_process_failed_or_timed_out']),
|
|
94
|
+
...(!exactReferencedPath || !commandReferencesOnlyInputB || !outputReferencesInputB || contract.blockers.length > 0
|
|
95
|
+
? ['codex_image_referenced_path_actual_cli_probe_failed']
|
|
96
|
+
: [])
|
|
97
|
+
]
|
|
92
98
|
};
|
|
93
99
|
}
|
|
94
100
|
//# sourceMappingURL=codex-0139-image-path-real-probe.js.map
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { findCodexBinary } from '../codex-adapter.js';
|
|
4
|
-
import {
|
|
4
|
+
import { parseCodexVersionText } from '../codex-compat/codex-version-policy.js';
|
|
5
|
+
import { CURRENT_CODEX_RELEASE_MANIFEST } from '../codex-compat/codex-release-manifest.js';
|
|
5
6
|
import { runProcess } from '../fsx.js';
|
|
6
7
|
import { runCodex0139DoctorEnvRealProbe } from './codex-0139-doctor-real-probe.js';
|
|
7
8
|
import { runCodex0139ImageReferencedPathRealProbe } from './codex-0139-image-path-real-probe.js';
|
|
8
|
-
import {
|
|
9
|
+
import { runCodex0144CollabAgentToolSchemaRealProbe } from './codex-0144-collab-agent-real-probe.js';
|
|
9
10
|
import { runCodex0139MarketplaceSourceRealProbe, runCodex0139PluginCacheRealProbe } from './codex-0139-plugin-real-probes.js';
|
|
10
11
|
import { buildCodex0139RealProbeResult, CODEX_0139_REAL_PROBE_NAMES, skippedCodex0139Probe } from './codex-0139-real-probes.js';
|
|
11
12
|
import { runCodex0139RichSchemaRealProbe } from './codex-0139-rich-schema-real-probe.js';
|
|
@@ -14,34 +15,68 @@ import { runCodex0139WebSearchRealProbe } from './codex-0139-web-search-probe.js
|
|
|
14
15
|
export async function runCodex0139RealProbes(input) {
|
|
15
16
|
const timeoutMs = Math.max(1, Number(input.timeoutMs || 120000) || 120000);
|
|
16
17
|
const requireReal = input.requireReal === true;
|
|
17
|
-
const codexBin = input.codexBin || await
|
|
18
|
+
const codexBin = input.codexBin || await findCurrentCodexRealProbeBinary();
|
|
18
19
|
const versionText = await readCodexVersionText(codexBin, timeoutMs);
|
|
19
20
|
const parsedVersion = parseCodexVersionText(versionText);
|
|
20
|
-
const
|
|
21
|
-
const
|
|
21
|
+
const currentVersion = parsedVersion === CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion;
|
|
22
|
+
const requestedRaw = input.probes?.length ? input.probes : CODEX_0139_REAL_PROBE_NAMES;
|
|
23
|
+
const unknownProbeNames = requestedRaw.filter((name) => !CODEX_0139_REAL_PROBE_NAMES.includes(name));
|
|
24
|
+
const requested = [...new Set(requestedRaw.filter((name) => CODEX_0139_REAL_PROBE_NAMES.includes(name)))];
|
|
22
25
|
const probes = Object.fromEntries(CODEX_0139_REAL_PROBE_NAMES.map((name) => [name, skippedCodex0139Probe('probe_not_requested')]));
|
|
23
|
-
const extraBlockers =
|
|
26
|
+
const extraBlockers = unknownProbeNames.map((name) => `unknown_real_probe:${name}`);
|
|
24
27
|
if (!codexBin)
|
|
25
28
|
extraBlockers.push('codex_cli_missing');
|
|
26
|
-
if (!
|
|
27
|
-
extraBlockers.push('
|
|
28
|
-
if (!codexBin || !
|
|
29
|
+
if (!currentVersion)
|
|
30
|
+
extraBlockers.push(`codex_${CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion.replaceAll('.', '_')}_required`);
|
|
31
|
+
if (!codexBin || !currentVersion) {
|
|
29
32
|
for (const name of requested) {
|
|
30
|
-
probes[name] = skippedCodex0139Probe(!codexBin ? 'codex_cli_missing' : '
|
|
33
|
+
probes[name] = skippedCodex0139Probe(!codexBin ? 'codex_cli_missing' : 'codex_current_release_required', { parsed_version: parsedVersion });
|
|
31
34
|
}
|
|
32
|
-
|
|
35
|
+
const tempCleanup = await cleanupProbeTempRoot(input.root);
|
|
36
|
+
return buildCodex0139RealProbeResult({ codexBin, versionText, parsedVersion, requireReal, timeoutMs, probes, requiredProbeNames: requested, releaseAuthorizing: false, tempCleanup, extraBlockers });
|
|
33
37
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
let rows = [];
|
|
39
|
+
let tempCleanup;
|
|
40
|
+
try {
|
|
41
|
+
rows = await Promise.all(requested.map(async (name) => {
|
|
42
|
+
try {
|
|
43
|
+
const probe = await runOne(name, {
|
|
44
|
+
root: input.root,
|
|
45
|
+
requireReal,
|
|
46
|
+
timeoutMs,
|
|
47
|
+
codexBin,
|
|
48
|
+
allowNetwork: input.allowNetwork,
|
|
49
|
+
allowDesktop: input.allowDesktop
|
|
50
|
+
});
|
|
51
|
+
return [name, surfaceRuntimeWarnings(probe)];
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
const errorClass = err instanceof Error ? err.name : typeof err;
|
|
55
|
+
extraBlockers.push(`codex_real_probe_runner_failed:${name}`);
|
|
56
|
+
return [name, skippedCodex0139Probe('codex_real_probe_runner_failed', { error_class: errorClass })];
|
|
57
|
+
}
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
tempCleanup = await cleanupProbeTempRoot(input.root);
|
|
43
62
|
}
|
|
44
|
-
|
|
63
|
+
for (const [name, probe] of rows)
|
|
64
|
+
probes[name] = probe;
|
|
65
|
+
sanitizeCleanedTempArtifacts(probes, input.root);
|
|
66
|
+
if (!tempCleanup.ok)
|
|
67
|
+
extraBlockers.push('codex_real_probe_temp_cleanup_failed');
|
|
68
|
+
return buildCodex0139RealProbeResult({
|
|
69
|
+
codexBin,
|
|
70
|
+
versionText,
|
|
71
|
+
parsedVersion,
|
|
72
|
+
requireReal,
|
|
73
|
+
timeoutMs,
|
|
74
|
+
probes,
|
|
75
|
+
requiredProbeNames: requested,
|
|
76
|
+
releaseAuthorizing: requireReal && currentVersion,
|
|
77
|
+
tempCleanup,
|
|
78
|
+
extraBlockers
|
|
79
|
+
});
|
|
45
80
|
}
|
|
46
81
|
async function runOne(name, input) {
|
|
47
82
|
switch (name) {
|
|
@@ -57,11 +92,11 @@ async function runOne(name, input) {
|
|
|
57
92
|
return runCodex0139PluginCacheRealProbe(input);
|
|
58
93
|
case 'sandbox_profile_alias':
|
|
59
94
|
return runCodex0139SandboxProfileAliasProbe(input);
|
|
60
|
-
case '
|
|
61
|
-
return
|
|
95
|
+
case 'collab_agent_tool_schema':
|
|
96
|
+
return runCodex0144CollabAgentToolSchemaRealProbe(input);
|
|
62
97
|
case 'image_referenced_path':
|
|
63
98
|
return runCodex0139ImageReferencedPathRealProbe(input);
|
|
64
|
-
case '
|
|
99
|
+
case 'sandbox_proxy_environment':
|
|
65
100
|
return runCodex0139SandboxProxyPreservationProbe(input);
|
|
66
101
|
}
|
|
67
102
|
}
|
|
@@ -76,7 +111,7 @@ async function readCodexVersionText(codexBin, timeoutMs) {
|
|
|
76
111
|
const text = `${result.stdout || ''}${result.stderr || ''}`.trim();
|
|
77
112
|
return text || null;
|
|
78
113
|
}
|
|
79
|
-
export async function
|
|
114
|
+
export async function findCurrentCodexRealProbeBinary() {
|
|
80
115
|
const candidates = await codexBinaryCandidates();
|
|
81
116
|
let firstExisting = null;
|
|
82
117
|
for (const candidate of candidates) {
|
|
@@ -84,18 +119,18 @@ export async function findCodex0139RealProbeBinary() {
|
|
|
84
119
|
firstExisting = candidate;
|
|
85
120
|
const versionText = await readCodexVersionText(candidate, 30000);
|
|
86
121
|
const parsed = parseCodexVersionText(versionText);
|
|
87
|
-
if (parsed
|
|
122
|
+
if (parsed === CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion)
|
|
88
123
|
return candidate;
|
|
89
124
|
}
|
|
90
125
|
return firstExisting || await findCodexBinary();
|
|
91
126
|
}
|
|
92
127
|
async function codexBinaryCandidates() {
|
|
93
128
|
const raw = [
|
|
129
|
+
path.join(process.cwd(), 'node_modules', '.bin', process.platform === 'win32' ? 'codex.cmd' : 'codex'),
|
|
94
130
|
process.env.SKS_CODEX_BIN,
|
|
95
131
|
process.env.DCODEX_CODEX_BIN,
|
|
96
132
|
process.env.CODEX_BIN,
|
|
97
|
-
...pathCandidates('codex')
|
|
98
|
-
path.join(process.cwd(), 'node_modules', '.bin', process.platform === 'win32' ? 'codex.cmd' : 'codex')
|
|
133
|
+
...pathCandidates('codex')
|
|
99
134
|
].filter(Boolean).map(String);
|
|
100
135
|
const out = [];
|
|
101
136
|
for (const candidate of raw) {
|
|
@@ -110,6 +145,46 @@ async function codexBinaryCandidates() {
|
|
|
110
145
|
}
|
|
111
146
|
return out;
|
|
112
147
|
}
|
|
148
|
+
function surfaceRuntimeWarnings(probe) {
|
|
149
|
+
const warnings = [...(probe.warnings || [])];
|
|
150
|
+
const blockers = [...probe.blockers];
|
|
151
|
+
const stderr = String(probe.stderr_tail || '');
|
|
152
|
+
if (/AuthRequired|Auth required|No access token was provided/i.test(stderr)) {
|
|
153
|
+
warnings.push('codex_real_probe_external_mcp_auth_required');
|
|
154
|
+
}
|
|
155
|
+
if (probe.evidence?.process_warning)
|
|
156
|
+
warnings.push('codex_real_probe_process_warning');
|
|
157
|
+
return {
|
|
158
|
+
...probe,
|
|
159
|
+
ok: probe.ok && blockers.length === 0,
|
|
160
|
+
warnings: [...new Set(warnings)],
|
|
161
|
+
blockers: [...new Set(blockers)]
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
async function cleanupProbeTempRoot(root) {
|
|
165
|
+
const tempRoot = path.join(root, '.sneakoscope', 'tmp', 'codex-0139-real-probes');
|
|
166
|
+
await fs.rm(tempRoot, { recursive: true, force: true }).catch(() => undefined);
|
|
167
|
+
const remainingEntries = await fs.readdir(tempRoot).catch(() => []);
|
|
168
|
+
return { root: tempRoot, ok: remainingEntries.length === 0, remaining_entries: remainingEntries };
|
|
169
|
+
}
|
|
170
|
+
function sanitizeCleanedTempArtifacts(probes, root) {
|
|
171
|
+
const tempRoot = path.resolve(root, '.sneakoscope', 'tmp', 'codex-0139-real-probes');
|
|
172
|
+
for (const probe of Object.values(probes)) {
|
|
173
|
+
const tempArtifacts = probe.artifact_paths.filter((artifact) => {
|
|
174
|
+
const resolved = path.resolve(artifact);
|
|
175
|
+
return resolved === tempRoot || resolved.startsWith(`${tempRoot}${path.sep}`);
|
|
176
|
+
});
|
|
177
|
+
if (!tempArtifacts.length)
|
|
178
|
+
continue;
|
|
179
|
+
probe.artifact_paths = probe.artifact_paths.filter((artifact) => !tempArtifacts.includes(artifact));
|
|
180
|
+
probe.evidence = {
|
|
181
|
+
...probe.evidence,
|
|
182
|
+
observed_temp_artifact_count: tempArtifacts.length,
|
|
183
|
+
temp_artifacts_cleaned: true,
|
|
184
|
+
durable_evidence: 'embedded_in_codex_real_probe_report'
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
}
|
|
113
188
|
function pathCandidates(command) {
|
|
114
189
|
const exts = process.platform === 'win32' ? ['.cmd', '.exe', '.bat', ''] : [''];
|
|
115
190
|
return (process.env.PATH || '').split(path.delimiter).flatMap((dir) => exts.map((ext) => path.join(dir, `${command}${ext}`)));
|
|
@@ -3,17 +3,21 @@ import { codex0139ProbeArtifactPath } from './codex-0139-real-probes.js';
|
|
|
3
3
|
import { readJson, writeJsonAtomic } from '../fsx.js';
|
|
4
4
|
export async function buildCodex0139RealProbeSummary(root) {
|
|
5
5
|
const result = await readJson(codex0139ProbeArtifactPath(root));
|
|
6
|
-
const
|
|
6
|
+
const requested = new Set((result.requested_probes?.length ? result.requested_probes : Object.keys(result.probes || {})).map(String));
|
|
7
|
+
const requestedEntries = Object.entries(result.probes || {}).filter(([name]) => requested.has(name));
|
|
8
|
+
const probes = Object.fromEntries(requestedEntries.map(([name, probe]) => [name, {
|
|
7
9
|
ok: probe.ok === true,
|
|
8
10
|
mode: probe.mode,
|
|
9
11
|
blockers: probe.blockers || []
|
|
10
12
|
}]));
|
|
11
|
-
const values =
|
|
13
|
+
const values = requestedEntries.map(([, probe]) => probe);
|
|
12
14
|
const skippedCount = values.filter((probe) => probe.mode === 'skipped').length;
|
|
13
15
|
const failedCount = values.filter((probe) => probe.ok !== true && probe.mode !== 'skipped').length;
|
|
14
16
|
return {
|
|
15
17
|
schema: 'sks.codex-0139-real-probe-summary.v1',
|
|
16
|
-
|
|
18
|
+
target_version: result.target_version,
|
|
19
|
+
compatibility_authority: 'deprecated_non_authoritative_lineage_only',
|
|
20
|
+
ok: result.overall_ok === true,
|
|
17
21
|
require_real: result.require_real,
|
|
18
22
|
codex_bin: result.codex_bin,
|
|
19
23
|
parsed_version: result.parsed_version,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
+
import { CURRENT_CODEX_RELEASE_MANIFEST } from '../codex-compat/codex-release-manifest.js';
|
|
2
3
|
import { nowIso, writeJsonAtomic } from '../fsx.js';
|
|
3
4
|
export const CODEX_0139_REAL_PROBE_NAMES = [
|
|
4
5
|
'code_mode_web_search',
|
|
@@ -7,9 +8,9 @@ export const CODEX_0139_REAL_PROBE_NAMES = [
|
|
|
7
8
|
'marketplace_source_json',
|
|
8
9
|
'plugin_catalog_cache',
|
|
9
10
|
'sandbox_profile_alias',
|
|
10
|
-
'
|
|
11
|
+
'collab_agent_tool_schema',
|
|
11
12
|
'image_referenced_path',
|
|
12
|
-
'
|
|
13
|
+
'sandbox_proxy_environment'
|
|
13
14
|
];
|
|
14
15
|
export function codex0139ProbeArtifactPath(root) {
|
|
15
16
|
return path.join(root, '.sneakoscope', 'codex-0139-real-probes.json');
|
|
@@ -50,24 +51,38 @@ export function codex0139ProbeTail(text, limit = 4000) {
|
|
|
50
51
|
return raw.length <= limit ? raw : raw.slice(raw.length - limit);
|
|
51
52
|
}
|
|
52
53
|
export function buildCodex0139RealProbeResult(input) {
|
|
53
|
-
const
|
|
54
|
-
const
|
|
54
|
+
const requiredProbeNames = input.requiredProbeNames ? [...new Set(input.requiredProbeNames)] : [...CODEX_0139_REAL_PROBE_NAMES];
|
|
55
|
+
const skipped = requiredProbeNames.filter((name) => input.probes[name]?.mode === 'skipped');
|
|
56
|
+
const failed = requiredProbeNames.filter((name) => input.probes[name] && input.probes[name].ok !== true && input.probes[name].mode !== 'skipped');
|
|
55
57
|
const blockers = [
|
|
56
58
|
...(input.extraBlockers || []),
|
|
57
|
-
...
|
|
59
|
+
...requiredProbeNames.flatMap((name) => input.probes[name]?.blockers || []),
|
|
58
60
|
...(input.requireReal && skipped.length ? skipped.map((name) => `require_real_skipped:${name}`) : [])
|
|
59
61
|
];
|
|
62
|
+
const warnings = requiredProbeNames.flatMap((name) => input.probes[name]?.warnings || []);
|
|
63
|
+
const overallOk = input.requireReal ? blockers.length === 0 && failed.length === 0 && skipped.length === 0 : failed.length === 0;
|
|
60
64
|
return {
|
|
61
65
|
schema: 'sks.codex-0139-real-probe-result.v1',
|
|
66
|
+
target_version: CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion,
|
|
67
|
+
compatibility_origin: 'codex-0139-real-probe-result-v1',
|
|
68
|
+
compatibility_authority: 'deprecated_non_authoritative_lineage_only',
|
|
62
69
|
generated_at: nowIso(),
|
|
63
70
|
codex_bin: input.codexBin,
|
|
64
71
|
version_text: input.versionText,
|
|
65
72
|
parsed_version: input.parsedVersion,
|
|
66
73
|
require_real: input.requireReal,
|
|
67
|
-
|
|
74
|
+
release_authorizing: Boolean(input.releaseAuthorizing && overallOk),
|
|
75
|
+
overall_ok: overallOk,
|
|
68
76
|
probe_timeout_ms: input.timeoutMs,
|
|
77
|
+
requested_probes: requiredProbeNames,
|
|
69
78
|
probes: input.probes,
|
|
70
79
|
skipped,
|
|
80
|
+
warnings: [...new Set(warnings)],
|
|
81
|
+
external_integration_status: {
|
|
82
|
+
mcp_auth: warnings.includes('codex_real_probe_external_mcp_auth_required') ? 'authentication_required' : 'not_observed',
|
|
83
|
+
release_authorization_scope: 'codex_core_compatibility_only'
|
|
84
|
+
},
|
|
85
|
+
temp_cleanup: input.tempCleanup || { root: '', ok: false, remaining_entries: [] },
|
|
71
86
|
blockers: [...new Set(blockers)]
|
|
72
87
|
};
|
|
73
88
|
}
|