sneakoscope 8.2.0 → 8.3.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 +46 -110
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/cli/command-manifest-lite.js +0 -2
- package/dist/cli/command-registry.js +0 -2
- package/dist/commands/codex.js +3 -3
- package/dist/commands/doctor.js +5 -157
- package/dist/config/skills-manifest.json +1 -1
- package/dist/core/codex/codex-cli-syntax-builder.js +0 -8
- package/dist/core/codex-app/codex-models-cache.js +2 -1
- package/dist/core/codex-app/menubar/constants.js +0 -7
- package/dist/core/codex-compat/codex-capability-matrix.js +7 -7
- package/dist/core/codex-compat/codex-compat-report.js +8 -12
- package/dist/core/codex-compat/codex-runtime-contract.js +62 -0
- package/dist/core/codex-compat/codex-version-policy.js +7 -7
- package/dist/core/codex-control/codex-current-app-capability.js +3 -3
- package/dist/core/codex-control/codex-current-capability.js +67 -94
- package/dist/core/codex-control/codex-current-core-capability.js +3 -3
- package/dist/core/codex-control/codex-current-core-probe-runner.js +4 -4
- package/dist/core/codex-control/codex-current-core-real-probes.js +2 -2
- package/dist/core/codex-control/codex-current-feature-capability.js +4 -4
- package/dist/core/codex-control/codex-current-image-path-real-probe.js +1 -1
- package/dist/core/codex-control/codex-current-web-search-probe.js +1 -1
- package/dist/core/codex-control/codex-sdk-capability.js +2 -2
- package/dist/core/commands/remote-command.js +2 -2
- package/dist/core/context7-client.js +5 -2
- package/dist/core/doctor/codex-current-core-probe-doctor.js +2 -2
- package/dist/core/doctor/doctor-dirty-planner.js +1 -1
- package/dist/core/doctor/doctor-readiness-matrix.js +0 -7
- package/dist/core/feature-fixtures.js +0 -4
- package/dist/core/feature-registry.js +0 -1
- package/dist/core/image-ux-review.js +3 -3
- package/dist/core/install/installed-package-smoke.js +2 -3
- package/dist/core/mad-sks/sql-plane/mcp-executor.js +4 -3
- package/dist/core/mcp/modern-protocol.js +36 -0
- package/dist/core/mcp-config/health-check.js +45 -30
- package/dist/core/perf/release-latency-slo.js +1 -2
- package/dist/core/proof/runtime-truth-matrix.js +1 -1
- package/dist/core/release/canonical-test-proof.js +1 -2
- package/dist/core/release/gate-manifest.js +5 -2
- package/dist/core/release/physical-release-gates.js +0 -26
- package/dist/core/release/release-gate-affected-selector.js +2 -1
- package/dist/core/release/release-gate-contract.js +3 -1
- package/dist/core/release/release-pack-receipt.js +0 -1
- package/dist/core/release/stage-publish.js +1 -1
- package/dist/core/version-manager.js +4 -0
- package/dist/core/version.js +1 -1
- package/dist/native/sks-menubar/Sources/AppDelegate.swift +1 -12
- package/dist/native/sks-menubar/Sources/ControlCenterWindowController.swift +2 -6
- package/dist/native/sks-menubar/Sources/RemoteCodingViewController.swift +28 -471
- package/dist/native/sks-menubar/Sources/SecureProcessEnvelope.swift +1 -43
- package/dist/scripts/codex-current-app-server-v2-check.js +9 -8
- package/dist/scripts/codex-current-binary-identity-check.js +2 -2
- package/dist/scripts/codex-current-capability-check.js +9 -7
- package/dist/scripts/codex-current-dependency-check.js +21 -0
- package/dist/scripts/docs-truthfulness-check.js +4 -19
- package/dist/scripts/fast-codex-service-tier-proof-check.js +0 -1
- package/dist/scripts/install-surface-ssot-check.js +2 -2
- package/dist/scripts/latest-version-guidance-check.js +1 -1
- package/dist/scripts/packlist-performance-check.js +0 -1
- package/dist/scripts/release-metadata-check.js +4 -1
- package/dist/scripts/release-version-truth-check.js +149 -0
- package/dist/vendor/openai-codex/latest/hooks/permission-request.command.input.schema.json +6 -0
- package/dist/vendor/openai-codex/latest/hooks/permission-request.command.output.schema.json +2 -16
- package/dist/vendor/openai-codex/latest/hooks/post-compact.command.input.schema.json +6 -0
- package/dist/vendor/openai-codex/latest/hooks/post-tool-use.command.input.schema.json +6 -0
- package/dist/vendor/openai-codex/latest/hooks/post-tool-use.command.output.schema.json +2 -16
- package/dist/vendor/openai-codex/latest/hooks/pre-compact.command.input.schema.json +6 -0
- package/dist/vendor/openai-codex/latest/hooks/pre-tool-use.command.input.schema.json +6 -0
- package/dist/vendor/openai-codex/latest/hooks/pre-tool-use.command.output.schema.json +2 -16
- package/dist/vendor/openai-codex/latest/hooks/session-start.command.output.schema.json +2 -16
- package/dist/vendor/openai-codex/latest/hooks/snapshot-metadata.json +7 -5
- package/dist/vendor/openai-codex/latest/hooks/subagent-start.command.output.schema.json +4 -18
- package/dist/vendor/openai-codex/latest/hooks/user-prompt-submit.command.input.schema.json +6 -0
- package/dist/vendor/openai-codex/latest/hooks/user-prompt-submit.command.output.schema.json +2 -16
- package/package.json +4 -7
- package/release-gates.v2.json +49 -19
- package/config/codex-releases/rust-v0.146.0.json +0 -45
- package/dist/core/agents/agent-runner-codex-exec.js +0 -177
- package/dist/core/codex-compat/codex-release-manifest.js +0 -72
- package/dist/core/commands/telegram-command.js +0 -447
- package/dist/core/telegram/access.js +0 -58
- package/dist/core/telegram/client.js +0 -157
- package/dist/core/telegram/confirmation.js +0 -37
- package/dist/core/telegram/doctor.js +0 -154
- package/dist/core/telegram/index.js +0 -9
- package/dist/core/telegram/keychain.js +0 -317
- package/dist/core/telegram/liveness.js +0 -124
- package/dist/core/telegram/poller.js +0 -90
- package/dist/core/telegram/redaction.js +0 -15
- package/dist/core/telegram/state-lock.js +0 -416
- package/dist/core/telegram/types.js +0 -1
- package/dist/native/sks-menubar/Sources/TelegramPrivateFileStore.swift +0 -498
- package/dist/native/sks-menubar/Sources/TelegramPrivateFileSupport.swift +0 -236
- package/dist/native/sks-menubar/Sources/TelegramProcessGateway.swift +0 -454
- package/dist/native/sks-menubar/Sources/TelegramRuntimeSupport.swift +0 -56
- package/dist/native/sks-menubar/Sources/TelegramStateLock.swift +0 -448
- package/dist/native/sks-menubar/Sources/TelegramSupport.swift +0 -243
- package/dist/native/sks-menubar/Sources/TelegramTransport.swift +0 -499
- package/dist/scripts/codex-current-manifest-check.js +0 -29
- package/schemas/codex/app-server-0.146/codex_app_server_protocol.v2.schemas.json +0 -19858
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { runProcess } from '../fsx.js';
|
|
2
|
-
import {
|
|
2
|
+
import { CURRENT_CODEX_RUNTIME_CONTRACT, NARUTO_REQUIRED_CODEX_VERSION } from './codex-runtime-contract.js';
|
|
3
3
|
import { compareSemverLike, parseCodexVersionText } from './codex-version-policy.js';
|
|
4
4
|
export const CODEX_CAPABILITY_MATRIX_SCHEMA = 'sks.codex-capability-matrix.v1';
|
|
5
5
|
export const SKS_CODEX_CAPABILITY_IDS = [
|
|
@@ -13,10 +13,10 @@ export const SKS_CODEX_CAPABILITY_IDS = [
|
|
|
13
13
|
];
|
|
14
14
|
const UPDATE_CTA = 'Update Codex CLI to the preferred latest: `sks codex update` or Menu Bar / SKS Center → Update Codex CLI Now.';
|
|
15
15
|
export function preferredCodexCliVersion() {
|
|
16
|
-
return
|
|
16
|
+
return CURRENT_CODEX_RUNTIME_CONTRACT.preferredCliVersion || CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion;
|
|
17
17
|
}
|
|
18
18
|
export function softMinimumCodexCliVersion() {
|
|
19
|
-
return
|
|
19
|
+
return CURRENT_CODEX_RUNTIME_CONTRACT.minimumSupportedVersion;
|
|
20
20
|
}
|
|
21
21
|
export function narutoCodexFloorVersion() {
|
|
22
22
|
return NARUTO_REQUIRED_CODEX_VERSION;
|
|
@@ -26,7 +26,7 @@ export function buildCodexCapabilityMatrix(input = {}) {
|
|
|
26
26
|
const help = String(input.helpText || '');
|
|
27
27
|
const config = String(input.configText || '');
|
|
28
28
|
const schema = String(input.schemaText || '');
|
|
29
|
-
const policies =
|
|
29
|
+
const policies = CURRENT_CODEX_RUNTIME_CONTRACT.featurePolicies;
|
|
30
30
|
const warnings = [];
|
|
31
31
|
if (detected && compareSemverLike(detected, preferredCodexCliVersion()) < 0) {
|
|
32
32
|
warnings.push(`detected Codex ${detected} is below preferred ${preferredCodexCliVersion()}; prefer latest via SKS update inducement`);
|
|
@@ -122,8 +122,8 @@ export async function probeNarutoCodexCapability(input) {
|
|
|
122
122
|
return { matrix, naruto: assertNarutoMultiAgentV2Capability(matrix) };
|
|
123
123
|
}
|
|
124
124
|
function resolveMultiAgentV2(input) {
|
|
125
|
-
const policy =
|
|
126
|
-
||
|
|
125
|
+
const policy = CURRENT_CODEX_RUNTIME_CONTRACT.featurePolicies.multiAgentV2
|
|
126
|
+
|| CURRENT_CODEX_RUNTIME_CONTRACT.featurePolicies.multiAgentMode
|
|
127
127
|
|| 'delegate';
|
|
128
128
|
const evidence = [];
|
|
129
129
|
const helpHit = /\bmulti_agent_v2\b/.test(input.help);
|
|
@@ -167,7 +167,7 @@ function resolveMultiAgentV2(input) {
|
|
|
167
167
|
};
|
|
168
168
|
}
|
|
169
169
|
function resolveAgentsConcurrency(input) {
|
|
170
|
-
const policy =
|
|
170
|
+
const policy = CURRENT_CODEX_RUNTIME_CONTRACT.featurePolicies.agentsMaxConcurrentThreads || 'delegate';
|
|
171
171
|
const hit = /max_concurrent_threads_per_session/.test(input.help)
|
|
172
172
|
|| /max_concurrent_threads_per_session/.test(input.config);
|
|
173
173
|
const available = hit || input.multiAgentV2;
|
|
@@ -2,21 +2,18 @@ import { projectRoot } from '../fsx.js';
|
|
|
2
2
|
import { detectCodexCurrentCapability } from '../codex-control/codex-current-capability.js';
|
|
3
3
|
import { codexVersionReport } from './codex-version.js';
|
|
4
4
|
import { CODEX_COMPAT_SCHEMA, CODEX_HOOK_SCHEMA_BASELINE_TAG, CODEX_REQUIRED_BASELINE_TAG } from './codex-version-policy.js';
|
|
5
|
-
import {
|
|
5
|
+
import { CURRENT_CODEX_RUNTIME_CONTRACT } from './codex-runtime-contract.js';
|
|
6
6
|
import { codexSchemaSnapshotReport } from './codex-schema-snapshot.js';
|
|
7
7
|
import { codexHookWarningCheck } from './codex-hook-warning-detector.js';
|
|
8
8
|
export async function codexCompatibilityReport(opts = {}) {
|
|
9
9
|
const root = opts.root || await projectRoot();
|
|
10
10
|
const requiredBaseline = opts.requiredBaseline || opts.require || CODEX_REQUIRED_BASELINE_TAG;
|
|
11
11
|
const version = await codexVersionReport({ ...opts, requiredBaseline });
|
|
12
|
-
const
|
|
13
|
-
ok:
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
manifest_sha256: null,
|
|
18
|
-
error: err?.message || String(err)
|
|
19
|
-
}));
|
|
12
|
+
const releaseContract = {
|
|
13
|
+
ok: true,
|
|
14
|
+
dependency_source: CURRENT_CODEX_RUNTIME_CONTRACT.dependencySource,
|
|
15
|
+
contract: CURRENT_CODEX_RUNTIME_CONTRACT
|
|
16
|
+
};
|
|
20
17
|
const snapshot = await codexSchemaSnapshotReport();
|
|
21
18
|
const hooks = await codexHookWarningCheck(root, { recordWrongness: false });
|
|
22
19
|
const current = await detectCodexCurrentCapability({
|
|
@@ -24,11 +21,11 @@ export async function codexCompatibilityReport(opts = {}) {
|
|
|
24
21
|
codexBin: opts.codexBin || null,
|
|
25
22
|
requireReal: opts.requireReal === true
|
|
26
23
|
});
|
|
27
|
-
const ok = Boolean(version.policy.ok &&
|
|
24
|
+
const ok = Boolean(version.policy.ok && snapshot.ok && hooks.ok && current.ok);
|
|
28
25
|
return {
|
|
29
26
|
schema: CODEX_COMPAT_SCHEMA,
|
|
30
27
|
required_baseline: requiredBaseline,
|
|
31
|
-
|
|
28
|
+
release_contract: releaseContract,
|
|
32
29
|
detected: version.detected,
|
|
33
30
|
current_capability: current,
|
|
34
31
|
capabilities: current.feature_states,
|
|
@@ -58,7 +55,6 @@ export async function codexCompatibilityReport(opts = {}) {
|
|
|
58
55
|
],
|
|
59
56
|
blockers: [
|
|
60
57
|
...(version.policy.ok ? [] : ['codex_version_policy_failed']),
|
|
61
|
-
...(releaseManifest.ok ? [] : ['codex_release_manifest_mismatch']),
|
|
62
58
|
...(snapshot.ok ? [] : ['codex_hook_schema_snapshot_invalid']),
|
|
63
59
|
...(hooks.ok ? [] : ['codex_hook_semantic_warning']),
|
|
64
60
|
...current.blockers
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { packageRoot } from '../fsx.js';
|
|
4
|
+
export const CODEX_RUNTIME_CONTRACT_SCHEMA = 'sks.codex-runtime-contract.v2';
|
|
5
|
+
const sdkVersion = codexSdkDependencyVersion();
|
|
6
|
+
export const CURRENT_CODEX_RUNTIME_CONTRACT = {
|
|
7
|
+
schema: CODEX_RUNTIME_CONTRACT_SCHEMA,
|
|
8
|
+
targetTag: `rust-v${sdkVersion}`,
|
|
9
|
+
requiredCliVersion: sdkVersion,
|
|
10
|
+
preferredCliVersion: sdkVersion,
|
|
11
|
+
sdkVersion,
|
|
12
|
+
minimumSupportedVersion: sdkVersion,
|
|
13
|
+
narutoCapabilityFloorVersion: sdkVersion,
|
|
14
|
+
protocolMode: 'app-server-v2',
|
|
15
|
+
dependencySource: 'package.json#dependencies.@openai/codex-sdk',
|
|
16
|
+
featurePolicies: {
|
|
17
|
+
multiAgentMode: 'delegate',
|
|
18
|
+
multiAgentV2: 'delegate',
|
|
19
|
+
agentsMaxConcurrentThreads: 'delegate',
|
|
20
|
+
indexedWebSearch: 'probe',
|
|
21
|
+
currentTimeRead: 'wrap',
|
|
22
|
+
threadListSearchRead: 'probe',
|
|
23
|
+
pluginCatalogRefresh: 'probe',
|
|
24
|
+
terminalSubagentErrorPropagation: 'probe',
|
|
25
|
+
execMcpTransientRecovery: 'probe',
|
|
26
|
+
remoteNativeEnvironment: 'probe',
|
|
27
|
+
rolloutTokenBudget: 'probe',
|
|
28
|
+
mcpStartupToolTimeouts: 'wrap',
|
|
29
|
+
gpt56TerraLunaSolRouting: 'delegate',
|
|
30
|
+
mcpPaginatedDiscovery: 'wrap',
|
|
31
|
+
portableAgentPlugins: 'delegate',
|
|
32
|
+
automaticApprovalReview: 'delegate'
|
|
33
|
+
},
|
|
34
|
+
requiredRealProbes: [
|
|
35
|
+
'runtime_identity',
|
|
36
|
+
'protocol_schema_generation',
|
|
37
|
+
'multi_agent_mode_schema',
|
|
38
|
+
'indexed_web_search_schema',
|
|
39
|
+
'current_time_read_schema',
|
|
40
|
+
'thread_list_search_schema',
|
|
41
|
+
'terminal_error_schema',
|
|
42
|
+
'rollout_budget_schema'
|
|
43
|
+
],
|
|
44
|
+
supportedPlatforms: [
|
|
45
|
+
'darwin-arm64',
|
|
46
|
+
'darwin-x64',
|
|
47
|
+
'linux-arm64',
|
|
48
|
+
'linux-x64',
|
|
49
|
+
'win32-arm64',
|
|
50
|
+
'win32-x64'
|
|
51
|
+
]
|
|
52
|
+
};
|
|
53
|
+
export const NARUTO_REQUIRED_CODEX_VERSION = CURRENT_CODEX_RUNTIME_CONTRACT.narutoCapabilityFloorVersion;
|
|
54
|
+
export function codexSdkDependencyVersion(root = packageRoot()) {
|
|
55
|
+
const packagePath = path.join(root, 'package.json');
|
|
56
|
+
const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
|
57
|
+
const value = String(pkg.dependencies?.['@openai/codex-sdk'] || '').trim();
|
|
58
|
+
if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(value)) {
|
|
59
|
+
throw new Error(`@openai/codex-sdk must be an exact semver in ${packagePath}`);
|
|
60
|
+
}
|
|
61
|
+
return value;
|
|
62
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CURRENT_CODEX_RUNTIME_CONTRACT } from './codex-runtime-contract.js';
|
|
2
2
|
export const CODEX_COMPAT_SCHEMA = 'sks.codex-compat.v2';
|
|
3
|
-
export const CODEX_REQUIRED_BASELINE_TAG =
|
|
4
|
-
export const CODEX_REQUIRED_VERSION =
|
|
5
|
-
||
|
|
3
|
+
export const CODEX_REQUIRED_BASELINE_TAG = CURRENT_CODEX_RUNTIME_CONTRACT.targetTag;
|
|
4
|
+
export const CODEX_REQUIRED_VERSION = CURRENT_CODEX_RUNTIME_CONTRACT.preferredCliVersion
|
|
5
|
+
|| CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion;
|
|
6
6
|
export const CODEX_PREFERRED_VERSION = CODEX_REQUIRED_VERSION;
|
|
7
|
-
export const CODEX_MINIMUM_SUPPORTED_VERSION =
|
|
8
|
-
export const CODEX_HOOK_SCHEMA_BASELINE_TAG =
|
|
9
|
-
export const CODEX_HOOK_SCHEMA_VERSION =
|
|
7
|
+
export const CODEX_MINIMUM_SUPPORTED_VERSION = CURRENT_CODEX_RUNTIME_CONTRACT.minimumSupportedVersion;
|
|
8
|
+
export const CODEX_HOOK_SCHEMA_BASELINE_TAG = 'latest';
|
|
9
|
+
export const CODEX_HOOK_SCHEMA_VERSION = 'latest';
|
|
10
10
|
const UPDATE_CTA = 'prefer latest Codex CLI via `sks codex update` or Menu Bar / SKS Center → Update Codex CLI Now';
|
|
11
11
|
export function compareSemverLike(a, b) {
|
|
12
12
|
const pa = parseVersionParts(a);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { findCodexBinary } from '../codex-adapter.js';
|
|
3
3
|
import { compareSemverLike, parseCodexVersionText } from '../codex-compat/codex-version-policy.js';
|
|
4
|
-
import {
|
|
4
|
+
import { CURRENT_CODEX_RUNTIME_CONTRACT } from '../codex-compat/codex-runtime-contract.js';
|
|
5
5
|
import { nowIso, runProcess, writeJsonAtomic } from '../fsx.js';
|
|
6
6
|
export async function detectCodexCurrentAppCapability(input = {}) {
|
|
7
7
|
const fake = process.env.SKS_CODEX_CURRENT_APP_FAKE === '1';
|
|
@@ -9,10 +9,10 @@ export async function detectCodexCurrentAppCapability(input = {}) {
|
|
|
9
9
|
? input.codexBin || process.env.CODEX_BIN || 'codex'
|
|
10
10
|
: input.codexBin || process.env.CODEX_BIN || await findCodexBinary();
|
|
11
11
|
const versionText = fake
|
|
12
|
-
? String(process.env.SKS_CODEX_VERSION_FAKE || `codex-cli ${
|
|
12
|
+
? String(process.env.SKS_CODEX_VERSION_FAKE || `codex-cli ${CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion}`)
|
|
13
13
|
: await readCodexVersionText(codexBin);
|
|
14
14
|
const parsed = parseCodexVersion(versionText);
|
|
15
|
-
const currentRelease = Boolean(parsed && semverGte(parsed,
|
|
15
|
+
const currentRelease = Boolean(parsed && semverGte(parsed, CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion));
|
|
16
16
|
const probeMode = process.env.SKS_CODEX_CURRENT_APP_PROBE === '1' ? 'feature-probe' : 'version-only';
|
|
17
17
|
const featureProbeResults = probeMode === 'feature-probe'
|
|
18
18
|
? await probeCodexCurrentAppFeatures(codexBin, { fake })
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import fsp from 'node:fs/promises';
|
|
2
|
-
import os from 'node:os';
|
|
3
2
|
import path from 'node:path';
|
|
4
|
-
import {
|
|
3
|
+
import { CURRENT_CODEX_RUNTIME_CONTRACT } from '../codex-compat/codex-runtime-contract.js';
|
|
5
4
|
import { compareSemverLike } from '../codex-compat/codex-version-policy.js';
|
|
6
|
-
import {
|
|
5
|
+
import { nowIso, packageRoot, readJson, runProcess, sha256, withScratchDir, writeJsonAtomic } from '../fsx.js';
|
|
7
6
|
import { resolveCodexRuntime } from '../codex-runtime/resolve-codex-runtime.js';
|
|
8
7
|
export const CODEX_CURRENT_FEATURE_KEYS = [
|
|
9
8
|
'runtime_identity',
|
|
@@ -30,11 +29,13 @@ export async function detectCodexCurrentCapability(input = {}) {
|
|
|
30
29
|
if (!runtime.identity) {
|
|
31
30
|
return blockedCapability('blocked', null, null, [...runtime.blockers]);
|
|
32
31
|
}
|
|
33
|
-
const versionOk = compareSemverLike(runtime.identity.version,
|
|
34
|
-
const schemaProbe = await
|
|
32
|
+
const versionOk = compareSemverLike(runtime.identity.version, CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion) >= 0;
|
|
33
|
+
const schemaProbe = await generateSchemaProbe(root, runtime.identity, {
|
|
34
|
+
allowCache: input.requireReal !== true
|
|
35
|
+
});
|
|
35
36
|
const implementationRoot = packageRoot();
|
|
36
37
|
const appServerClientText = await fsp.readFile(path.join(implementationRoot, 'src', 'core', 'codex-control', 'codex-app-server-v2-client.ts'), 'utf8').catch(() => '');
|
|
37
|
-
const states = featureStatesFromSchema(schemaProbe.text, schemaProbe.ok, appServerClientText);
|
|
38
|
+
const states = featureStatesFromSchema(schemaProbe.text, schemaProbe.ok, schemaProbe.mode, appServerClientText);
|
|
38
39
|
const blockers = [
|
|
39
40
|
...(versionOk ? [] : ['codex_current_release_required']),
|
|
40
41
|
...(schemaProbe.ok ? [] : ['codex_current_schema_generation_failed']),
|
|
@@ -43,24 +44,21 @@ export async function detectCodexCurrentCapability(input = {}) {
|
|
|
43
44
|
const realEnough = blockers.length === 0
|
|
44
45
|
&& schemaProbe.mode === 'real-schema'
|
|
45
46
|
&& schemaProbe.sha256 !== null
|
|
46
|
-
&& CURRENT_CODEX_RELEASE_MANIFEST.generatedSchemaSha256 !== 'pending-generated-schema'
|
|
47
|
-
&& schemaProbe.sha256 === CURRENT_CODEX_RELEASE_MANIFEST.generatedSchemaSha256
|
|
48
47
|
&& Object.values(states).every((state) => state.certainty === 'actual' || state.certainty === 'discovered');
|
|
49
48
|
return {
|
|
50
49
|
schema: 'sks.codex-current-capability.v1',
|
|
51
50
|
generated_at: nowIso(),
|
|
52
51
|
ok: blockers.length === 0,
|
|
53
52
|
release_authorizing: realEnough,
|
|
54
|
-
target_tag:
|
|
55
|
-
required_version:
|
|
53
|
+
target_tag: CURRENT_CODEX_RUNTIME_CONTRACT.targetTag,
|
|
54
|
+
required_version: CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion,
|
|
56
55
|
runtime_identity: runtime.identity,
|
|
57
56
|
generated_schema_sha256: schemaProbe.sha256,
|
|
58
|
-
manifest_schema_sha256: CURRENT_CODEX_RELEASE_MANIFEST.generatedSchemaSha256,
|
|
59
57
|
probe_mode: schemaProbe.ok ? schemaProbe.mode : 'blocked',
|
|
60
58
|
feature_states: states,
|
|
61
59
|
blockers,
|
|
62
60
|
warnings: [
|
|
63
|
-
...(realEnough ? [] : ['
|
|
61
|
+
...(realEnough ? [] : ['codex_current_not_release_authorizing_until_runtime_schema_and_required_probes_pass']),
|
|
64
62
|
...(input.requireReal && blockers.length ? ['required_real_probe_blocked'] : [])
|
|
65
63
|
]
|
|
66
64
|
};
|
|
@@ -81,14 +79,15 @@ export async function writeCodexCurrentCapabilityArtifacts(root, input = {}) {
|
|
|
81
79
|
}
|
|
82
80
|
return { report, root_artifact: rootArtifact, mission_artifact: missionArtifact };
|
|
83
81
|
}
|
|
84
|
-
function featureStatesFromSchema(schemaText, schemaOk, appServerClientText = '') {
|
|
82
|
+
function featureStatesFromSchema(schemaText, schemaOk, schemaMode, appServerClientText = '') {
|
|
85
83
|
const lower = schemaText.toLowerCase();
|
|
84
|
+
const schemaCertainty = schemaMode === 'real-schema' ? 'actual' : 'discovered';
|
|
86
85
|
const actual = (key, needles) => {
|
|
87
86
|
const found = schemaOk && needles.every((needle) => lower.includes(needle.toLowerCase()));
|
|
88
87
|
return {
|
|
89
88
|
supported: found,
|
|
90
|
-
certainty: found ?
|
|
91
|
-
evidence: found ? needles.map((needle) =>
|
|
89
|
+
certainty: found ? schemaCertainty : schemaOk ? 'unverified' : 'failed',
|
|
90
|
+
evidence: found ? needles.map((needle) => `${schemaMode}_contains:${needle}`) : [],
|
|
92
91
|
blockers: found ? [] : [`codex_current_${key}_not_verified`]
|
|
93
92
|
};
|
|
94
93
|
};
|
|
@@ -101,14 +100,16 @@ function featureStatesFromSchema(schemaText, schemaOk, appServerClientText = '')
|
|
|
101
100
|
},
|
|
102
101
|
protocol_schema_generation: {
|
|
103
102
|
supported: schemaOk,
|
|
104
|
-
certainty: schemaOk ?
|
|
105
|
-
evidence: schemaOk
|
|
103
|
+
certainty: schemaOk ? schemaCertainty : 'failed',
|
|
104
|
+
evidence: schemaOk
|
|
105
|
+
? [schemaMode === 'real-schema' ? 'codex_app_server_generate_json_schema' : 'cached_schema_non_authorizing']
|
|
106
|
+
: [],
|
|
106
107
|
blockers: schemaOk ? [] : ['codex_app_server_schema_generation_failed']
|
|
107
108
|
},
|
|
108
109
|
multi_agent_mode_schema: actual('multi_agent_mode_schema', ['MultiAgentMode']),
|
|
109
110
|
rollout_budget_schema: actual('rollout_budget_schema', ['budgetLimited']),
|
|
110
111
|
indexed_web_search_schema: actual('indexed_web_search_schema', ['indexed']),
|
|
111
|
-
current_time_read_schema: currentTimeState(lower, schemaOk, appServerClientText),
|
|
112
|
+
current_time_read_schema: currentTimeState(lower, schemaOk, schemaMode, appServerClientText),
|
|
112
113
|
native_thread_list_search_schema: actual('native_thread_list_search_schema', ['thread/list', 'ThreadSearchResult', 'thread/read']),
|
|
113
114
|
plugin_catalog_refresh_schema: actual('plugin_catalog_refresh_schema', ['plugin/list', 'plugin/install', 'AppListUpdatedNotification']),
|
|
114
115
|
terminal_subagent_error_schema: actual('terminal_subagent_error_schema', ['subagentStart', 'subagentStop', 'error']),
|
|
@@ -117,13 +118,13 @@ function featureStatesFromSchema(schemaText, schemaOk, appServerClientText = '')
|
|
|
117
118
|
app_server_overload_schema: actual('app_server_overload_schema', ['JSONRPCError'])
|
|
118
119
|
};
|
|
119
120
|
}
|
|
120
|
-
function currentTimeState(schemaTextLower, schemaOk, appServerClientText) {
|
|
121
|
+
function currentTimeState(schemaTextLower, schemaOk, schemaMode, appServerClientText) {
|
|
121
122
|
const schemaHasCurrentTime = schemaOk && schemaTextLower.includes('currenttime') && schemaTextLower.includes('read');
|
|
122
123
|
if (schemaHasCurrentTime) {
|
|
123
124
|
return {
|
|
124
125
|
supported: true,
|
|
125
|
-
certainty: 'actual',
|
|
126
|
-
evidence: [
|
|
126
|
+
certainty: schemaMode === 'real-schema' ? 'actual' : 'discovered',
|
|
127
|
+
evidence: [`${schemaMode}_contains:currentTime/read`],
|
|
127
128
|
blockers: []
|
|
128
129
|
};
|
|
129
130
|
}
|
|
@@ -135,76 +136,50 @@ function currentTimeState(schemaTextLower, schemaOk, appServerClientText) {
|
|
|
135
136
|
blockers: clientHandlesCurrentTime ? [] : ['codex_current_current_time_read_handler_not_verified']
|
|
136
137
|
};
|
|
137
138
|
}
|
|
138
|
-
async function
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
139
|
+
async function generateSchemaProbe(root, runtime, options) {
|
|
140
|
+
const cachePath = codexCurrentSchemaCachePath(root, runtime);
|
|
141
|
+
if (options.allowCache) {
|
|
142
|
+
const cached = await readJson(cachePath, null).catch(() => null);
|
|
143
|
+
if (cached?.ok === true && typeof cached.text === 'string' && cached.sha256) {
|
|
144
|
+
return { ok: true, text: cached.text, sha256: cached.sha256, mode: 'cached-schema' };
|
|
145
|
+
}
|
|
143
146
|
}
|
|
144
|
-
return
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}).catch((err) => ({
|
|
176
|
-
code: 1,
|
|
177
|
-
stdout: '',
|
|
178
|
-
stderr: err instanceof Error ? err.message : String(err),
|
|
179
|
-
stdoutBytes: 0,
|
|
180
|
-
stderrBytes: 0,
|
|
181
|
-
truncated: false,
|
|
182
|
-
timedOut: false
|
|
183
|
-
}));
|
|
184
|
-
if (result.code !== 0)
|
|
185
|
-
return { ok: false, text: `${result.stdout}\n${result.stderr}`, sha256: null, mode: 'real-schema' };
|
|
186
|
-
const files = await listFiles(out);
|
|
187
|
-
const rows = await Promise.all(files.map(async (file) => {
|
|
188
|
-
const text = await fsp.readFile(file, 'utf8');
|
|
189
|
-
return {
|
|
190
|
-
relative: path.relative(out, file),
|
|
191
|
-
text,
|
|
192
|
-
canonicalText: canonicalSchemaContent(file, text)
|
|
193
|
-
};
|
|
194
|
-
}));
|
|
195
|
-
const joined = rows.map((row) => `${row.relative}\n${row.text}`).join('\n');
|
|
196
|
-
const canonicalJoined = rows.map((row) => `${row.relative}\n${row.canonicalText}`).join('\n');
|
|
197
|
-
await fsp.rm(out, { recursive: true, force: true }).catch(() => { });
|
|
198
|
-
const probe = { ok: true, text: joined, sha256: sha256(canonicalJoined), mode: 'real-schema' };
|
|
199
|
-
await writeJsonAtomic(cachePath, probe).catch(() => undefined);
|
|
200
|
-
return probe;
|
|
147
|
+
return withScratchDir('codex-current-schema-', async (out) => {
|
|
148
|
+
const result = await runProcess(runtime.realpath, ['app-server', 'generate-json-schema', '--out', out], {
|
|
149
|
+
cwd: root,
|
|
150
|
+
timeoutMs: 60_000,
|
|
151
|
+
maxOutputBytes: 256 * 1024
|
|
152
|
+
}).catch((err) => ({
|
|
153
|
+
code: 1,
|
|
154
|
+
stdout: '',
|
|
155
|
+
stderr: err instanceof Error ? err.message : String(err),
|
|
156
|
+
stdoutBytes: 0,
|
|
157
|
+
stderrBytes: 0,
|
|
158
|
+
truncated: false,
|
|
159
|
+
timedOut: false
|
|
160
|
+
}));
|
|
161
|
+
if (result.code !== 0)
|
|
162
|
+
return { ok: false, text: `${result.stdout}\n${result.stderr}`, sha256: null, mode: 'real-schema' };
|
|
163
|
+
const files = await listFiles(out);
|
|
164
|
+
const rows = await Promise.all(files.map(async (file) => {
|
|
165
|
+
const text = await fsp.readFile(file, 'utf8');
|
|
166
|
+
return {
|
|
167
|
+
relative: path.relative(out, file),
|
|
168
|
+
text,
|
|
169
|
+
canonicalText: canonicalSchemaContent(file, text)
|
|
170
|
+
};
|
|
171
|
+
}));
|
|
172
|
+
const joined = rows.map((row) => `${row.relative}\n${row.text}`).join('\n');
|
|
173
|
+
const canonicalJoined = rows.map((row) => `${row.relative}\n${row.canonicalText}`).join('\n');
|
|
174
|
+
const probe = { ok: true, text: joined, sha256: sha256(canonicalJoined), mode: 'real-schema' };
|
|
175
|
+
await writeJsonAtomic(cachePath, probe).catch(() => undefined);
|
|
176
|
+
return probe;
|
|
177
|
+
});
|
|
201
178
|
}
|
|
202
|
-
|
|
203
|
-
const realpath = await fsp.realpath(codexBin).catch(() => codexBin);
|
|
179
|
+
export function codexCurrentSchemaCachePath(root, runtime) {
|
|
204
180
|
const key = sha256(JSON.stringify({
|
|
205
|
-
realpath,
|
|
206
|
-
|
|
207
|
-
manifest_schema_sha256: CURRENT_CODEX_RELEASE_MANIFEST.generatedSchemaSha256,
|
|
181
|
+
realpath: runtime.realpath,
|
|
182
|
+
binary_sha256: runtime.sha256,
|
|
208
183
|
platform: process.platform,
|
|
209
184
|
arch: process.arch
|
|
210
185
|
}));
|
|
@@ -251,11 +226,10 @@ function blockedCapability(probeMode, runtime, schemaSha, blockers) {
|
|
|
251
226
|
generated_at: nowIso(),
|
|
252
227
|
ok: false,
|
|
253
228
|
release_authorizing: false,
|
|
254
|
-
target_tag:
|
|
255
|
-
required_version:
|
|
229
|
+
target_tag: CURRENT_CODEX_RUNTIME_CONTRACT.targetTag,
|
|
230
|
+
required_version: CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion,
|
|
256
231
|
runtime_identity: runtime,
|
|
257
232
|
generated_schema_sha256: schemaSha,
|
|
258
|
-
manifest_schema_sha256: CURRENT_CODEX_RELEASE_MANIFEST.generatedSchemaSha256,
|
|
259
233
|
probe_mode: probeMode,
|
|
260
234
|
feature_states: state,
|
|
261
235
|
blockers,
|
|
@@ -274,11 +248,10 @@ function fakeCapability() {
|
|
|
274
248
|
generated_at: nowIso(),
|
|
275
249
|
ok: true,
|
|
276
250
|
release_authorizing: false,
|
|
277
|
-
target_tag:
|
|
278
|
-
required_version:
|
|
251
|
+
target_tag: CURRENT_CODEX_RUNTIME_CONTRACT.targetTag,
|
|
252
|
+
required_version: CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion,
|
|
279
253
|
runtime_identity: null,
|
|
280
254
|
generated_schema_sha256: 'fixture',
|
|
281
|
-
manifest_schema_sha256: CURRENT_CODEX_RELEASE_MANIFEST.generatedSchemaSha256,
|
|
282
255
|
probe_mode: 'hermetic-fixture',
|
|
283
256
|
feature_states: state,
|
|
284
257
|
blockers: [],
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { findCodexBinary } from '../codex-adapter.js';
|
|
3
3
|
import { compareSemverLike, parseCodexVersionText } from '../codex-compat/codex-version-policy.js';
|
|
4
|
-
import {
|
|
4
|
+
import { CURRENT_CODEX_RUNTIME_CONTRACT } from '../codex-compat/codex-runtime-contract.js';
|
|
5
5
|
import { nowIso, runProcess, writeJsonAtomic } from '../fsx.js';
|
|
6
6
|
export async function detectCodexCurrentCoreCapability(input = {}) {
|
|
7
7
|
const fake = process.env.SKS_CODEX_CURRENT_CORE_FAKE === '1';
|
|
@@ -9,10 +9,10 @@ export async function detectCodexCurrentCoreCapability(input = {}) {
|
|
|
9
9
|
? input.codexBin || process.env.CODEX_BIN || 'codex'
|
|
10
10
|
: input.codexBin || process.env.CODEX_BIN || await findCodexBinary();
|
|
11
11
|
const versionText = fake
|
|
12
|
-
? String(process.env.SKS_CODEX_VERSION_FAKE || `codex-cli ${
|
|
12
|
+
? String(process.env.SKS_CODEX_VERSION_FAKE || `codex-cli ${CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion}`)
|
|
13
13
|
: await readCodexVersionText(codexBin);
|
|
14
14
|
const parsed = parseCodexVersionText(versionText);
|
|
15
|
-
const currentRelease = Boolean(parsed && compareSemverLike(parsed,
|
|
15
|
+
const currentRelease = Boolean(parsed && compareSemverLike(parsed, CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion) >= 0);
|
|
16
16
|
const probeMode = process.env.SKS_CODEX_CURRENT_CORE_PROBE === '1' ? 'feature-probe' : 'version-only';
|
|
17
17
|
const probeTimeoutMs = Math.max(1, Number(process.env.SKS_CODEX_CURRENT_CORE_PROBE_TIMEOUT_MS || 3000) || 3000);
|
|
18
18
|
const featureProbeResults = probeMode === 'feature-probe'
|
|
@@ -2,7 +2,7 @@ import fs from 'node:fs/promises';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { findCodexBinary } from '../codex-adapter.js';
|
|
4
4
|
import { parseCodexVersionText } from '../codex-compat/codex-version-policy.js';
|
|
5
|
-
import {
|
|
5
|
+
import { CURRENT_CODEX_RUNTIME_CONTRACT } from '../codex-compat/codex-runtime-contract.js';
|
|
6
6
|
import { runProcess } from '../fsx.js';
|
|
7
7
|
import { runCodexCurrentCoreDoctorEnvRealProbe } from './codex-current-doctor-real-probe.js';
|
|
8
8
|
import { runCodexCurrentCoreImageReferencedPathRealProbe } from './codex-current-image-path-real-probe.js';
|
|
@@ -18,7 +18,7 @@ export async function runCodexCurrentCoreRealProbes(input) {
|
|
|
18
18
|
const codexBin = input.codexBin || await findCurrentCodexRealProbeBinary();
|
|
19
19
|
const versionText = await readCodexVersionText(codexBin, timeoutMs);
|
|
20
20
|
const parsedVersion = parseCodexVersionText(versionText);
|
|
21
|
-
const currentVersion = parsedVersion ===
|
|
21
|
+
const currentVersion = parsedVersion === CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion;
|
|
22
22
|
const requestedRaw = input.probes?.length ? input.probes : CODEX_CURRENT_CORE_REAL_PROBE_NAMES;
|
|
23
23
|
const unknownProbeNames = requestedRaw.filter((name) => !CODEX_CURRENT_CORE_REAL_PROBE_NAMES.includes(name));
|
|
24
24
|
const requested = [...new Set(requestedRaw.filter((name) => CODEX_CURRENT_CORE_REAL_PROBE_NAMES.includes(name)))];
|
|
@@ -27,7 +27,7 @@ export async function runCodexCurrentCoreRealProbes(input) {
|
|
|
27
27
|
if (!codexBin)
|
|
28
28
|
extraBlockers.push('codex_cli_missing');
|
|
29
29
|
if (!currentVersion)
|
|
30
|
-
extraBlockers.push(`codex_${
|
|
30
|
+
extraBlockers.push(`codex_${CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion.replaceAll('.', '_')}_required`);
|
|
31
31
|
if (!codexBin || !currentVersion) {
|
|
32
32
|
for (const name of requested) {
|
|
33
33
|
probes[name] = skippedCodexCurrentCoreProbe(!codexBin ? 'codex_cli_missing' : 'codex_current_release_required', { parsed_version: parsedVersion });
|
|
@@ -119,7 +119,7 @@ export async function findCurrentCodexRealProbeBinary() {
|
|
|
119
119
|
firstExisting = candidate;
|
|
120
120
|
const versionText = await readCodexVersionText(candidate, 30000);
|
|
121
121
|
const parsed = parseCodexVersionText(versionText);
|
|
122
|
-
if (parsed ===
|
|
122
|
+
if (parsed === CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion)
|
|
123
123
|
return candidate;
|
|
124
124
|
}
|
|
125
125
|
return firstExisting || await findCodexBinary();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import {
|
|
2
|
+
import { CURRENT_CODEX_RUNTIME_CONTRACT } from '../codex-compat/codex-runtime-contract.js';
|
|
3
3
|
import { nowIso, writeJsonAtomic } from '../fsx.js';
|
|
4
4
|
export const CODEX_CURRENT_CORE_REAL_PROBE_NAMES = [
|
|
5
5
|
'code_mode_web_search',
|
|
@@ -63,7 +63,7 @@ export function buildCodexCurrentCoreRealProbeResult(input) {
|
|
|
63
63
|
const overallOk = input.requireReal ? blockers.length === 0 && failed.length === 0 && skipped.length === 0 : failed.length === 0;
|
|
64
64
|
return {
|
|
65
65
|
schema: 'sks.codex-current-core-real-probe-result.v1',
|
|
66
|
-
target_version:
|
|
66
|
+
target_version: CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion,
|
|
67
67
|
compatibility_origin: 'codex-current-core-real-probe-result-v1',
|
|
68
68
|
compatibility_authority: 'deprecated_non_authoritative_lineage_only',
|
|
69
69
|
generated_at: nowIso(),
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { findCodexBinary } from '../codex-adapter.js';
|
|
3
3
|
import { compareSemverLike, parseCodexVersionText } from '../codex-compat/codex-version-policy.js';
|
|
4
|
-
import {
|
|
4
|
+
import { CURRENT_CODEX_RUNTIME_CONTRACT } from '../codex-compat/codex-runtime-contract.js';
|
|
5
5
|
import { nowIso, runProcess, writeJsonAtomic } from '../fsx.js';
|
|
6
6
|
import { CODEX_CURRENT_FEATURE_FEATURE_KEYS, probeCodexCurrentFeatureFeatureDetails, probeCodexCurrentFeatureFeatures } from './codex-current-feature-probes.js';
|
|
7
7
|
export async function detectCodexCurrentFeatureCapability(input = {}) {
|
|
8
8
|
const fake = process.env.SKS_CODEX_CURRENT_FEATURE_FAKE === '1';
|
|
9
9
|
const codexBin = fake ? input.codexBin || process.env.CODEX_BIN || 'codex' : input.codexBin || process.env.CODEX_BIN || await findCodexBinary();
|
|
10
|
-
const versionText = fake ? String(process.env.SKS_CODEX_VERSION_FAKE || `codex-cli ${
|
|
10
|
+
const versionText = fake ? String(process.env.SKS_CODEX_VERSION_FAKE || `codex-cli ${CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion}`) : await readCodexVersionText(codexBin);
|
|
11
11
|
const parsed = parseCodexVersionText(versionText);
|
|
12
|
-
const supportsCurrentContract = Boolean(parsed && compareSemverLike(parsed,
|
|
12
|
+
const supportsCurrentContract = Boolean(parsed && compareSemverLike(parsed, CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion) >= 0);
|
|
13
13
|
const probeMode = process.env.SKS_CODEX_CURRENT_FEATURE_PROBE === '1' ? 'feature-probe' : 'version-only';
|
|
14
14
|
const probeTimeoutMs = Number(process.env.SKS_CODEX_CURRENT_FEATURE_PROBE_TIMEOUT_MS || 3000);
|
|
15
15
|
const probeDetails = probeMode === 'feature-probe'
|
|
@@ -77,7 +77,7 @@ function featureStateFor(key, supportsCurrentContract, probeMode, probeDetails)
|
|
|
77
77
|
return {
|
|
78
78
|
supported: true,
|
|
79
79
|
certainty: 'assumed_by_version',
|
|
80
|
-
evidence: [`codex_version>=${
|
|
80
|
+
evidence: [`codex_version>=${CURRENT_CODEX_RUNTIME_CONTRACT.requiredCliVersion}`],
|
|
81
81
|
blockers: []
|
|
82
82
|
};
|
|
83
83
|
}
|
|
@@ -49,7 +49,7 @@ export async function runCodexCurrentCoreImageReferencedPathRealProbe(input) {
|
|
|
49
49
|
}
|
|
50
50
|
const outputFile = path.join(tempDir, 'last-message.txt');
|
|
51
51
|
const prompt = [
|
|
52
|
-
'This is a
|
|
52
|
+
'This is a current Codex image path routing probe.',
|
|
53
53
|
`Only the image file named ${path.basename(inputB)} is intentionally referenced.`,
|
|
54
54
|
`Return compact JSON {"referenced_path":"${inputB.replace(/\\/g, '\\\\')}","saw_image":true}.`,
|
|
55
55
|
'Do not edit files and do not reference any other image path.'
|
|
@@ -15,7 +15,7 @@ export async function runCodexCurrentCoreWebSearchRealProbe(input) {
|
|
|
15
15
|
return skippedCodexCurrentCoreProbe('codex_cli_missing');
|
|
16
16
|
const tempDir = path.join(input.root, '.sneakoscope', 'tmp', 'codex-current-core-real-probes', `web-search-${Date.now()}`);
|
|
17
17
|
await ensureDir(tempDir);
|
|
18
|
-
await writeTextAtomic(path.join(tempDir, 'README.md'), 'Temporary
|
|
18
|
+
await writeTextAtomic(path.join(tempDir, 'README.md'), 'Temporary current Codex web-search real probe workspace.\n');
|
|
19
19
|
const outputFile = path.join(tempDir, 'last-message.txt');
|
|
20
20
|
const prompt = 'In code mode, use standalone web search to find the title of https://example.com. Return JSON {"used_web_search":true,"answer":"...","sources":[...]}.';
|
|
21
21
|
const args = buildCodexExecArgs({ root: tempDir, prompt, outputFile, json: true, extraArgs: ['-c', 'mcp_servers={}'] });
|
|
@@ -2,7 +2,7 @@ import { createRequire } from 'node:module';
|
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
|
-
import {
|
|
5
|
+
import { CURRENT_CODEX_RUNTIME_CONTRACT } from '../codex-compat/codex-runtime-contract.js';
|
|
6
6
|
export async function detectCodexSdkCapability(input = {}) {
|
|
7
7
|
let dynamicImportOk = false;
|
|
8
8
|
let version = null;
|
|
@@ -38,7 +38,7 @@ export async function detectCodexSdkCapability(input = {}) {
|
|
|
38
38
|
node_compatible: nodeCompatible,
|
|
39
39
|
dynamic_import_ok: dynamicImportOk,
|
|
40
40
|
structured_output_fake_smoke: structuredFake,
|
|
41
|
-
setup_action: blockers.includes('codex_sdk_unavailable') ? `npm install @openai/codex-sdk@${
|
|
41
|
+
setup_action: blockers.includes('codex_sdk_unavailable') ? `npm install @openai/codex-sdk@${CURRENT_CODEX_RUNTIME_CONTRACT.sdkVersion}` : null,
|
|
42
42
|
blockers
|
|
43
43
|
};
|
|
44
44
|
}
|
|
@@ -105,8 +105,8 @@ Usage:
|
|
|
105
105
|
sks remote worker --stdio
|
|
106
106
|
|
|
107
107
|
This command manages SKS remote readiness, registered machines, and the JSONL worker transport.
|
|
108
|
-
It does not install a messaging bridge or create remote sessions. For
|
|
109
|
-
|
|
108
|
+
It does not install a messaging bridge or create remote sessions. For mobile-first workflows,
|
|
109
|
+
use a separately installed independent companion such as Paseo.
|
|
110
110
|
`);
|
|
111
111
|
}
|
|
112
112
|
function fail(error, supported, json) {
|