sneakoscope 3.0.2 → 3.0.4
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 +1 -1
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/crates/sks-core/src/main.rs +1 -1
- package/dist/.sks-build-stamp.json +4 -4
- package/dist/bin/sks.js +1 -1
- package/dist/core/agents/runtime-proof-summary.js +17 -1
- package/dist/core/codex/codex-cli-syntax-builder.js +4 -1
- package/dist/core/codex-control/codex-0139-capability.js +74 -13
- package/dist/core/codex-control/codex-0139-doctor-real-probe.js +64 -0
- package/dist/core/codex-control/codex-0139-image-path-real-probe.js +94 -0
- package/dist/core/codex-control/codex-0139-multi-agent-real-probe.js +107 -0
- package/dist/core/codex-control/codex-0139-plugin-real-probes.js +119 -0
- package/dist/core/codex-control/codex-0139-probe-runner.js +117 -0
- package/dist/core/codex-control/codex-0139-real-probe-summary.js +37 -0
- package/dist/core/codex-control/codex-0139-real-probes.js +74 -0
- package/dist/core/codex-control/codex-0139-rich-schema-real-probe.js +43 -0
- package/dist/core/codex-control/codex-0139-sandbox-real-probe.js +79 -0
- package/dist/core/codex-control/codex-0139-web-search-probe.js +72 -0
- package/dist/core/codex-control/codex-multi-agent-event-normalizer.js +15 -0
- package/dist/core/codex-control/codex-tool-schema-fixtures.js +57 -0
- package/dist/core/doctor/codex-0139-doctor.js +16 -0
- package/dist/core/doctor/doctor-readiness-matrix.js +6 -0
- package/dist/core/fsx.js +25 -1
- package/dist/core/mcp/mcp-0-134-policy.js +3 -0
- package/dist/core/pipeline-internals/runtime-core.js +6 -1
- package/dist/core/version.js +1 -1
- package/dist/core/zellij/zellij-command.js +12 -1
- package/dist/core/zellij/zellij-fake-adapter.js +163 -0
- package/dist/core/zellij/zellij-worker-pane-summary.js +65 -0
- package/dist/scripts/github-release-body-helper.js +23 -1
- package/package.json +28 -2
- package/schemas/codex/codex-0139-real-probe-result.schema.json +85 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { findCodexBinary } from '../codex-adapter.js';
|
|
3
|
+
import { ensureDir, runProcess, writeJsonAtomic } from '../fsx.js';
|
|
4
|
+
import { marketplaceSourcesPresent } from './codex-0139-capability.js';
|
|
5
|
+
import { codex0139ProbeTail, skippedCodex0139Probe } from './codex-0139-real-probes.js';
|
|
6
|
+
export async function runCodex0139MarketplaceSourceRealProbe(input) {
|
|
7
|
+
const started = Date.now();
|
|
8
|
+
const codexBin = input.codexBin || await findCodexBinary();
|
|
9
|
+
if (!codexBin)
|
|
10
|
+
return skippedCodex0139Probe('codex_cli_missing');
|
|
11
|
+
const tempDir = path.join(input.root, '.sneakoscope', 'tmp', 'codex-0139-real-probes', `marketplace-${Date.now()}`);
|
|
12
|
+
await ensureDir(tempDir);
|
|
13
|
+
const result = await runProcess(codexBin, ['plugin', 'marketplace', 'list', '--json'], {
|
|
14
|
+
cwd: tempDir,
|
|
15
|
+
timeoutMs: input.timeoutMs || 60000,
|
|
16
|
+
maxOutputBytes: 512 * 1024
|
|
17
|
+
}).catch((err) => ({ code: 1, stdout: '', stderr: err?.message || String(err) }));
|
|
18
|
+
const rows = parseRows(result.stdout);
|
|
19
|
+
const missingSourceRows = rows
|
|
20
|
+
.map((row, index) => ({ index, name: String(row?.name || row?.id || row?.pluginId || `row-${index + 1}`), keys: Object.keys(row || {}), root: typeof row?.root === 'string' ? row.root : null }))
|
|
21
|
+
.filter((row, index) => !rowHasMarketplaceSourceLocator(rows[index]));
|
|
22
|
+
const ok = result.code === 0 && marketplaceSourcesPresent(result.stdout);
|
|
23
|
+
const artifact = path.join(input.root, '.sneakoscope', 'codex-0139-plugin-marketplace-real.json');
|
|
24
|
+
await writeJsonAtomic(artifact, {
|
|
25
|
+
schema: 'sks.codex-0139-plugin-marketplace-real.v1',
|
|
26
|
+
ok,
|
|
27
|
+
generated_at: new Date().toISOString(),
|
|
28
|
+
command_line: [codexBin, 'plugin', 'marketplace', 'list', '--json'],
|
|
29
|
+
empty_marketplace_list: rows.length === 0,
|
|
30
|
+
row_count: rows.length,
|
|
31
|
+
rows_have_source: rows.every(rowHasMarketplaceSource),
|
|
32
|
+
rows_have_source_locator: rows.every(rowHasMarketplaceSourceLocator),
|
|
33
|
+
missing_source_rows: missingSourceRows,
|
|
34
|
+
stdout_tail: codex0139ProbeTail(result.stdout),
|
|
35
|
+
stderr_tail: codex0139ProbeTail(result.stderr)
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
ok,
|
|
39
|
+
mode: 'actual-cli',
|
|
40
|
+
command_line: [codexBin, 'plugin', 'marketplace', 'list', '--json'],
|
|
41
|
+
duration_ms: Date.now() - started,
|
|
42
|
+
stdout_tail: codex0139ProbeTail(result.stdout),
|
|
43
|
+
stderr_tail: codex0139ProbeTail(result.stderr),
|
|
44
|
+
artifact_paths: [artifact],
|
|
45
|
+
evidence: {
|
|
46
|
+
empty_marketplace_list: rows.length === 0,
|
|
47
|
+
row_count: rows.length,
|
|
48
|
+
rows_have_source: rows.every(rowHasMarketplaceSource),
|
|
49
|
+
rows_have_source_locator: rows.every(rowHasMarketplaceSourceLocator),
|
|
50
|
+
missing_source_rows: missingSourceRows
|
|
51
|
+
},
|
|
52
|
+
blockers: ok ? [] : ['codex_plugin_marketplace_source_real_probe_failed']
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function rowHasMarketplaceSource(row) {
|
|
56
|
+
return typeof row?.source === 'string' && row.source.length > 0
|
|
57
|
+
|| typeof row?.marketplaceSource?.source === 'string' && row.marketplaceSource.source.length > 0;
|
|
58
|
+
}
|
|
59
|
+
function rowHasMarketplaceSourceLocator(row) {
|
|
60
|
+
return rowHasMarketplaceSource(row) || typeof row?.root === 'string' && row.root.length > 0;
|
|
61
|
+
}
|
|
62
|
+
export async function runCodex0139PluginCacheRealProbe(input) {
|
|
63
|
+
const started = Date.now();
|
|
64
|
+
const codexBin = input.codexBin || await findCodexBinary();
|
|
65
|
+
if (!codexBin)
|
|
66
|
+
return skippedCodex0139Probe('codex_cli_missing');
|
|
67
|
+
const tempDir = path.join(input.root, '.sneakoscope', 'tmp', 'codex-0139-real-probes', `plugin-cache-${Date.now()}`);
|
|
68
|
+
await ensureDir(tempDir);
|
|
69
|
+
const firstStarted = Date.now();
|
|
70
|
+
const first = await runProcess(codexBin, ['plugin', 'list', '--json'], {
|
|
71
|
+
cwd: tempDir,
|
|
72
|
+
timeoutMs: input.timeoutMs || 60000,
|
|
73
|
+
maxOutputBytes: 512 * 1024
|
|
74
|
+
}).catch((err) => ({ code: 1, stdout: '', stderr: err?.message || String(err) }));
|
|
75
|
+
const firstMs = Date.now() - firstStarted;
|
|
76
|
+
const secondStarted = Date.now();
|
|
77
|
+
const second = await runProcess(codexBin, ['plugin', 'list', '--json'], {
|
|
78
|
+
cwd: tempDir,
|
|
79
|
+
timeoutMs: input.timeoutMs || 60000,
|
|
80
|
+
maxOutputBytes: 512 * 1024
|
|
81
|
+
}).catch((err) => ({ code: 1, stdout: '', stderr: err?.message || String(err) }));
|
|
82
|
+
const secondMs = Date.now() - secondStarted;
|
|
83
|
+
const marker = /cache|cached|catalog|remote/i.test(`${first.stdout}\n${second.stdout}\n${first.stderr}\n${second.stderr}`);
|
|
84
|
+
const secondNotMuchSlower = secondMs <= Math.max(firstMs * 2, firstMs + 1000);
|
|
85
|
+
const ok = first.code === 0 && second.code === 0 && secondNotMuchSlower;
|
|
86
|
+
return {
|
|
87
|
+
ok,
|
|
88
|
+
mode: 'actual-cli',
|
|
89
|
+
command_line: [codexBin, 'plugin', 'list', '--json'],
|
|
90
|
+
duration_ms: Date.now() - started,
|
|
91
|
+
stdout_tail: codex0139ProbeTail(`${first.stdout || ''}\n${second.stdout || ''}`),
|
|
92
|
+
stderr_tail: codex0139ProbeTail(`${first.stderr || ''}\n${second.stderr || ''}`),
|
|
93
|
+
artifact_paths: [tempDir],
|
|
94
|
+
evidence: {
|
|
95
|
+
first_duration_ms: firstMs,
|
|
96
|
+
second_duration_ms: secondMs,
|
|
97
|
+
second_not_slower_than_2x: secondNotMuchSlower,
|
|
98
|
+
cache_marker_seen: marker,
|
|
99
|
+
cache_marker_warning: marker ? null : 'cache marker unavailable; timing success accepted'
|
|
100
|
+
},
|
|
101
|
+
blockers: ok ? [] : ['codex_plugin_catalog_cache_real_probe_failed']
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function parseRows(stdout) {
|
|
105
|
+
try {
|
|
106
|
+
const parsed = JSON.parse(String(stdout || ''));
|
|
107
|
+
if (Array.isArray(parsed))
|
|
108
|
+
return parsed;
|
|
109
|
+
if (Array.isArray(parsed?.marketplaces))
|
|
110
|
+
return parsed.marketplaces;
|
|
111
|
+
if (Array.isArray(parsed?.items))
|
|
112
|
+
return parsed.items;
|
|
113
|
+
return [];
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=codex-0139-plugin-real-probes.js.map
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { findCodexBinary } from '../codex-adapter.js';
|
|
4
|
+
import { compareSemverLike, parseCodexVersionText } from '../codex-compat/codex-version-policy.js';
|
|
5
|
+
import { runProcess } from '../fsx.js';
|
|
6
|
+
import { runCodex0139DoctorEnvRealProbe } from './codex-0139-doctor-real-probe.js';
|
|
7
|
+
import { runCodex0139ImageReferencedPathRealProbe } from './codex-0139-image-path-real-probe.js';
|
|
8
|
+
import { runCodex0139InterruptAgentRealProbe } from './codex-0139-multi-agent-real-probe.js';
|
|
9
|
+
import { runCodex0139MarketplaceSourceRealProbe, runCodex0139PluginCacheRealProbe } from './codex-0139-plugin-real-probes.js';
|
|
10
|
+
import { buildCodex0139RealProbeResult, CODEX_0139_REAL_PROBE_NAMES, skippedCodex0139Probe } from './codex-0139-real-probes.js';
|
|
11
|
+
import { runCodex0139RichSchemaRealProbe } from './codex-0139-rich-schema-real-probe.js';
|
|
12
|
+
import { runCodex0139SandboxProfileAliasProbe, runCodex0139SandboxProxyPreservationProbe } from './codex-0139-sandbox-real-probe.js';
|
|
13
|
+
import { runCodex0139WebSearchRealProbe } from './codex-0139-web-search-probe.js';
|
|
14
|
+
export async function runCodex0139RealProbes(input) {
|
|
15
|
+
const timeoutMs = Math.max(1, Number(input.timeoutMs || 120000) || 120000);
|
|
16
|
+
const requireReal = input.requireReal === true;
|
|
17
|
+
const codexBin = input.codexBin || await findCodex0139RealProbeBinary();
|
|
18
|
+
const versionText = await readCodexVersionText(codexBin, timeoutMs);
|
|
19
|
+
const parsedVersion = parseCodexVersionText(versionText);
|
|
20
|
+
const atLeast139 = Boolean(parsedVersion && compareSemverLike(parsedVersion, '0.139.0') >= 0);
|
|
21
|
+
const requested = new Set((input.probes?.length ? input.probes : CODEX_0139_REAL_PROBE_NAMES).filter((name) => CODEX_0139_REAL_PROBE_NAMES.includes(name)));
|
|
22
|
+
const probes = Object.fromEntries(CODEX_0139_REAL_PROBE_NAMES.map((name) => [name, skippedCodex0139Probe('probe_not_requested')]));
|
|
23
|
+
const extraBlockers = [];
|
|
24
|
+
if (!codexBin)
|
|
25
|
+
extraBlockers.push('codex_cli_missing');
|
|
26
|
+
if (!atLeast139)
|
|
27
|
+
extraBlockers.push('codex_0_139_required');
|
|
28
|
+
if (!codexBin || !atLeast139) {
|
|
29
|
+
for (const name of requested) {
|
|
30
|
+
probes[name] = skippedCodex0139Probe(!codexBin ? 'codex_cli_missing' : 'codex_0_139_required', { parsed_version: parsedVersion });
|
|
31
|
+
}
|
|
32
|
+
return buildCodex0139RealProbeResult({ codexBin, versionText, parsedVersion, requireReal, timeoutMs, probes, extraBlockers });
|
|
33
|
+
}
|
|
34
|
+
for (const name of requested) {
|
|
35
|
+
probes[name] = await runOne(name, {
|
|
36
|
+
root: input.root,
|
|
37
|
+
requireReal,
|
|
38
|
+
timeoutMs,
|
|
39
|
+
codexBin,
|
|
40
|
+
allowNetwork: input.allowNetwork,
|
|
41
|
+
allowDesktop: input.allowDesktop
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return buildCodex0139RealProbeResult({ codexBin, versionText, parsedVersion, requireReal, timeoutMs, probes, extraBlockers });
|
|
45
|
+
}
|
|
46
|
+
async function runOne(name, input) {
|
|
47
|
+
switch (name) {
|
|
48
|
+
case 'code_mode_web_search':
|
|
49
|
+
return runCodex0139WebSearchRealProbe(input);
|
|
50
|
+
case 'rich_tool_schema':
|
|
51
|
+
return runCodex0139RichSchemaRealProbe(input);
|
|
52
|
+
case 'doctor_env_redaction':
|
|
53
|
+
return runCodex0139DoctorEnvRealProbe(input);
|
|
54
|
+
case 'marketplace_source_json':
|
|
55
|
+
return runCodex0139MarketplaceSourceRealProbe(input);
|
|
56
|
+
case 'plugin_catalog_cache':
|
|
57
|
+
return runCodex0139PluginCacheRealProbe(input);
|
|
58
|
+
case 'sandbox_profile_alias':
|
|
59
|
+
return runCodex0139SandboxProfileAliasProbe(input);
|
|
60
|
+
case 'interrupt_agent_event':
|
|
61
|
+
return runCodex0139InterruptAgentRealProbe(input);
|
|
62
|
+
case 'image_referenced_path':
|
|
63
|
+
return runCodex0139ImageReferencedPathRealProbe(input);
|
|
64
|
+
case 'sandbox_proxy_preservation':
|
|
65
|
+
return runCodex0139SandboxProxyPreservationProbe(input);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async function readCodexVersionText(codexBin, timeoutMs) {
|
|
69
|
+
if (!codexBin)
|
|
70
|
+
return null;
|
|
71
|
+
const result = await runProcess(codexBin, ['--version'], { timeoutMs: Math.min(timeoutMs, 30000), maxOutputBytes: 16 * 1024 }).catch((err) => ({
|
|
72
|
+
code: 1,
|
|
73
|
+
stdout: '',
|
|
74
|
+
stderr: err?.message || String(err)
|
|
75
|
+
}));
|
|
76
|
+
const text = `${result.stdout || ''}${result.stderr || ''}`.trim();
|
|
77
|
+
return text || null;
|
|
78
|
+
}
|
|
79
|
+
export async function findCodex0139RealProbeBinary() {
|
|
80
|
+
const candidates = await codexBinaryCandidates();
|
|
81
|
+
let firstExisting = null;
|
|
82
|
+
for (const candidate of candidates) {
|
|
83
|
+
if (!firstExisting)
|
|
84
|
+
firstExisting = candidate;
|
|
85
|
+
const versionText = await readCodexVersionText(candidate, 30000);
|
|
86
|
+
const parsed = parseCodexVersionText(versionText);
|
|
87
|
+
if (parsed && compareSemverLike(parsed, '0.139.0') >= 0)
|
|
88
|
+
return candidate;
|
|
89
|
+
}
|
|
90
|
+
return firstExisting || await findCodexBinary();
|
|
91
|
+
}
|
|
92
|
+
async function codexBinaryCandidates() {
|
|
93
|
+
const raw = [
|
|
94
|
+
process.env.SKS_CODEX_BIN,
|
|
95
|
+
process.env.DCODEX_CODEX_BIN,
|
|
96
|
+
process.env.CODEX_BIN,
|
|
97
|
+
...pathCandidates('codex'),
|
|
98
|
+
path.join(process.cwd(), 'node_modules', '.bin', process.platform === 'win32' ? 'codex.cmd' : 'codex')
|
|
99
|
+
].filter(Boolean).map(String);
|
|
100
|
+
const out = [];
|
|
101
|
+
for (const candidate of raw) {
|
|
102
|
+
if (out.includes(candidate))
|
|
103
|
+
continue;
|
|
104
|
+
try {
|
|
105
|
+
const st = await fs.stat(candidate);
|
|
106
|
+
if (st.isFile())
|
|
107
|
+
out.push(candidate);
|
|
108
|
+
}
|
|
109
|
+
catch { }
|
|
110
|
+
}
|
|
111
|
+
return out;
|
|
112
|
+
}
|
|
113
|
+
function pathCandidates(command) {
|
|
114
|
+
const exts = process.platform === 'win32' ? ['.cmd', '.exe', '.bat', ''] : [''];
|
|
115
|
+
return (process.env.PATH || '').split(path.delimiter).flatMap((dir) => exts.map((ext) => path.join(dir, `${command}${ext}`)));
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=codex-0139-probe-runner.js.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { codex0139ProbeArtifactPath } from './codex-0139-real-probes.js';
|
|
3
|
+
import { readJson, writeJsonAtomic } from '../fsx.js';
|
|
4
|
+
export async function buildCodex0139RealProbeSummary(root) {
|
|
5
|
+
const result = await readJson(codex0139ProbeArtifactPath(root));
|
|
6
|
+
const probes = Object.fromEntries(Object.entries(result.probes || {}).map(([name, probe]) => [name, {
|
|
7
|
+
ok: probe.ok === true,
|
|
8
|
+
mode: probe.mode,
|
|
9
|
+
blockers: probe.blockers || []
|
|
10
|
+
}]));
|
|
11
|
+
const values = Object.values(result.probes || {});
|
|
12
|
+
const skippedCount = values.filter((probe) => probe.mode === 'skipped').length;
|
|
13
|
+
const failedCount = values.filter((probe) => probe.ok !== true && probe.mode !== 'skipped').length;
|
|
14
|
+
return {
|
|
15
|
+
schema: 'sks.codex-0139-real-probe-summary.v1',
|
|
16
|
+
ok: result.require_real ? skippedCount === 0 && failedCount === 0 : result.overall_ok === true,
|
|
17
|
+
require_real: result.require_real,
|
|
18
|
+
codex_bin: result.codex_bin,
|
|
19
|
+
parsed_version: result.parsed_version,
|
|
20
|
+
actual_cli_probe_count: values.filter((probe) => probe.mode === 'actual-cli').length,
|
|
21
|
+
actual_sdk_probe_count: values.filter((probe) => probe.mode === 'actual-sdk').length,
|
|
22
|
+
actual_app_server_probe_count: values.filter((probe) => probe.mode === 'actual-app-server').length,
|
|
23
|
+
actual_sks_bridge_probe_count: values.filter((probe) => probe.mode === 'actual-sks-bridge').length,
|
|
24
|
+
skipped_count: skippedCount,
|
|
25
|
+
failed_count: failedCount,
|
|
26
|
+
probes
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export async function writeCodex0139RealProbeSummary(root) {
|
|
30
|
+
const summary = await buildCodex0139RealProbeSummary(root);
|
|
31
|
+
const rootArtifact = path.join(root, '.sneakoscope', 'codex-0139-real-probe-summary.json');
|
|
32
|
+
const distArtifact = path.join(root, 'dist', 'codex-0139-real-probe-summary.json');
|
|
33
|
+
await writeJsonAtomic(rootArtifact, summary);
|
|
34
|
+
await writeJsonAtomic(distArtifact, summary);
|
|
35
|
+
return { summary, root_artifact: rootArtifact, dist_artifact: distArtifact };
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=codex-0139-real-probe-summary.js.map
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { nowIso, writeJsonAtomic } from '../fsx.js';
|
|
3
|
+
export const CODEX_0139_REAL_PROBE_NAMES = [
|
|
4
|
+
'code_mode_web_search',
|
|
5
|
+
'rich_tool_schema',
|
|
6
|
+
'doctor_env_redaction',
|
|
7
|
+
'marketplace_source_json',
|
|
8
|
+
'plugin_catalog_cache',
|
|
9
|
+
'sandbox_profile_alias',
|
|
10
|
+
'interrupt_agent_event',
|
|
11
|
+
'image_referenced_path',
|
|
12
|
+
'sandbox_proxy_preservation'
|
|
13
|
+
];
|
|
14
|
+
export function codex0139ProbeArtifactPath(root) {
|
|
15
|
+
return path.join(root, '.sneakoscope', 'codex-0139-real-probes.json');
|
|
16
|
+
}
|
|
17
|
+
export function codex0139MissionProbeArtifactPath(root, missionId) {
|
|
18
|
+
return path.join(root, '.sneakoscope', 'missions', missionId, 'codex-0139-real-probes.json');
|
|
19
|
+
}
|
|
20
|
+
export function codex0139DistProbeArtifactPath(root) {
|
|
21
|
+
return path.join(root, 'dist', 'codex-0139-real-probes.json');
|
|
22
|
+
}
|
|
23
|
+
export async function writeCodex0139RealProbeResult(root, result, opts = {}) {
|
|
24
|
+
const rootArtifact = codex0139ProbeArtifactPath(root);
|
|
25
|
+
await writeJsonAtomic(rootArtifact, result);
|
|
26
|
+
let missionArtifact = null;
|
|
27
|
+
if (opts.missionId) {
|
|
28
|
+
missionArtifact = codex0139MissionProbeArtifactPath(root, opts.missionId);
|
|
29
|
+
await writeJsonAtomic(missionArtifact, result);
|
|
30
|
+
}
|
|
31
|
+
let distArtifact = null;
|
|
32
|
+
if (opts.writeDist !== false) {
|
|
33
|
+
distArtifact = codex0139DistProbeArtifactPath(root);
|
|
34
|
+
await writeJsonAtomic(distArtifact, result);
|
|
35
|
+
}
|
|
36
|
+
return { root_artifact: rootArtifact, mission_artifact: missionArtifact, dist_artifact: distArtifact };
|
|
37
|
+
}
|
|
38
|
+
export function skippedCodex0139Probe(blocker, evidence = {}) {
|
|
39
|
+
return {
|
|
40
|
+
ok: false,
|
|
41
|
+
mode: 'skipped',
|
|
42
|
+
duration_ms: 0,
|
|
43
|
+
artifact_paths: [],
|
|
44
|
+
evidence,
|
|
45
|
+
blockers: [blocker]
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export function codex0139ProbeTail(text, limit = 4000) {
|
|
49
|
+
const raw = String(text || '');
|
|
50
|
+
return raw.length <= limit ? raw : raw.slice(raw.length - limit);
|
|
51
|
+
}
|
|
52
|
+
export function buildCodex0139RealProbeResult(input) {
|
|
53
|
+
const skipped = CODEX_0139_REAL_PROBE_NAMES.filter((name) => input.probes[name]?.mode === 'skipped');
|
|
54
|
+
const failed = CODEX_0139_REAL_PROBE_NAMES.filter((name) => input.probes[name] && input.probes[name].ok !== true && input.probes[name].mode !== 'skipped');
|
|
55
|
+
const blockers = [
|
|
56
|
+
...(input.extraBlockers || []),
|
|
57
|
+
...CODEX_0139_REAL_PROBE_NAMES.flatMap((name) => input.probes[name]?.blockers || []),
|
|
58
|
+
...(input.requireReal && skipped.length ? skipped.map((name) => `require_real_skipped:${name}`) : [])
|
|
59
|
+
];
|
|
60
|
+
return {
|
|
61
|
+
schema: 'sks.codex-0139-real-probe-result.v1',
|
|
62
|
+
generated_at: nowIso(),
|
|
63
|
+
codex_bin: input.codexBin,
|
|
64
|
+
version_text: input.versionText,
|
|
65
|
+
parsed_version: input.parsedVersion,
|
|
66
|
+
require_real: input.requireReal,
|
|
67
|
+
overall_ok: input.requireReal ? blockers.length === 0 && failed.length === 0 && skipped.length === 0 : failed.length === 0,
|
|
68
|
+
probe_timeout_ms: input.timeoutMs,
|
|
69
|
+
probes: input.probes,
|
|
70
|
+
skipped,
|
|
71
|
+
blockers: [...new Set(blockers)]
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=codex-0139-real-probes.js.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { findCodexBinary } from '../codex-adapter.js';
|
|
3
|
+
import { ensureDir, runProcess, writeJsonAtomic } from '../fsx.js';
|
|
4
|
+
import { buildCodex0139RichToolSchemaFixture, evaluateCodex0139RichToolSchemaPreservation } from './codex-tool-schema-fixtures.js';
|
|
5
|
+
import { codex0139ProbeTail, skippedCodex0139Probe } from './codex-0139-real-probes.js';
|
|
6
|
+
export async function runCodex0139RichSchemaRealProbe(input) {
|
|
7
|
+
const started = Date.now();
|
|
8
|
+
const codexBin = input.codexBin || await findCodexBinary();
|
|
9
|
+
if (!codexBin && input.requireReal)
|
|
10
|
+
return skippedCodex0139Probe('codex_cli_missing');
|
|
11
|
+
const tempDir = path.join(input.root, '.sneakoscope', 'tmp', 'codex-0139-real-probes', `rich-schema-${Date.now()}`);
|
|
12
|
+
await ensureDir(tempDir);
|
|
13
|
+
const capturedSchemaPath = path.join(tempDir, 'captured-tool-schema.json');
|
|
14
|
+
const schema = buildCodex0139RichToolSchemaFixture();
|
|
15
|
+
await writeJsonAtomic(capturedSchemaPath, schema);
|
|
16
|
+
const evalResult = evaluateCodex0139RichToolSchemaPreservation(schema);
|
|
17
|
+
const versionRun = codexBin
|
|
18
|
+
? await runProcess(codexBin, ['--version'], { timeoutMs: input.timeoutMs || 30000, maxOutputBytes: 64 * 1024 }).catch((err) => ({ code: 1, stdout: '', stderr: err?.message || String(err) }))
|
|
19
|
+
: { code: 0, stdout: '', stderr: '' };
|
|
20
|
+
const actualBridge = Boolean(codexBin && versionRun.code === 0);
|
|
21
|
+
const ok = evalResult.ok === true && (!input.requireReal || actualBridge);
|
|
22
|
+
const probe = {
|
|
23
|
+
ok,
|
|
24
|
+
mode: actualBridge ? 'actual-sks-bridge' : 'skipped',
|
|
25
|
+
duration_ms: Date.now() - started,
|
|
26
|
+
stdout_tail: codex0139ProbeTail(versionRun.stdout),
|
|
27
|
+
stderr_tail: codex0139ProbeTail(versionRun.stderr),
|
|
28
|
+
artifact_paths: [capturedSchemaPath],
|
|
29
|
+
evidence: {
|
|
30
|
+
captured_schema_path: capturedSchemaPath,
|
|
31
|
+
oneOf_preserved: evalResult.top_level_oneOf_preserved,
|
|
32
|
+
allOf_preserved: evalResult.top_level_allOf_preserved,
|
|
33
|
+
nested_target_preserved: evalResult.nested_structure_preserved,
|
|
34
|
+
required_fields_retained: evalResult.required_fields_retained,
|
|
35
|
+
adapter_path: actualBridge ? 'sks-schema-capture-hook+codex-cli-presence' : 'sks-schema-capture-hook'
|
|
36
|
+
},
|
|
37
|
+
blockers: ok ? [] : ['codex_rich_tool_schema_real_probe_failed']
|
|
38
|
+
};
|
|
39
|
+
if (codexBin)
|
|
40
|
+
probe.command_line = [codexBin, '--version'];
|
|
41
|
+
return probe;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=codex-0139-rich-schema-real-probe.js.map
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { findCodexBinary } from '../codex-adapter.js';
|
|
3
|
+
import { ensureDir, runProcess } from '../fsx.js';
|
|
4
|
+
import { codex0139ProbeTail, skippedCodex0139Probe } from './codex-0139-real-probes.js';
|
|
5
|
+
export async function runCodex0139SandboxProfileAliasProbe(input) {
|
|
6
|
+
const started = Date.now();
|
|
7
|
+
const codexBin = input.codexBin || await findCodexBinary();
|
|
8
|
+
if (!codexBin)
|
|
9
|
+
return skippedCodex0139Probe('codex_cli_missing');
|
|
10
|
+
const help = await runProcess(codexBin, ['--help'], { timeoutMs: input.timeoutMs || 30000, maxOutputBytes: 256 * 1024 }).catch((err) => ({ code: 1, stdout: '', stderr: err?.message || String(err) }));
|
|
11
|
+
const sandboxHelp = await runProcess(codexBin, ['sandbox', '--help'], { timeoutMs: input.timeoutMs || 30000, maxOutputBytes: 256 * 1024 }).catch((err) => ({ code: 1, stdout: '', stderr: err?.message || String(err) }));
|
|
12
|
+
const helpText = `${help.stdout || ''}\n${help.stderr || ''}`;
|
|
13
|
+
const sandboxHelpText = `${sandboxHelp.stdout || ''}\n${sandboxHelp.stderr || ''}`;
|
|
14
|
+
const topLevelHelpMentionsAlias = /(^|\s)-P\b/.test(helpText);
|
|
15
|
+
const sandboxHelpMentionsAlias = /(^|\s)-P,\s+--permissions-profile\b/.test(sandboxHelpText) || /(^|\s)-P\b/.test(sandboxHelpText);
|
|
16
|
+
const dryArgs = sandboxHelpMentionsAlias ? ['sandbox', '-P', ':read-only', '--', 'true'] : ['-P', ':read-only', '--version'];
|
|
17
|
+
const dry = await runProcess(codexBin, dryArgs, { timeoutMs: input.timeoutMs || 30000, maxOutputBytes: 64 * 1024 }).catch((err) => ({ code: 1, stdout: '', stderr: err?.message || String(err) }));
|
|
18
|
+
const dryAccepted = dry.code === 0;
|
|
19
|
+
const ok = topLevelHelpMentionsAlias || sandboxHelpMentionsAlias;
|
|
20
|
+
return {
|
|
21
|
+
ok,
|
|
22
|
+
mode: 'actual-cli',
|
|
23
|
+
command_line: [codexBin, ...(sandboxHelpMentionsAlias ? ['sandbox', '--help'] : ['--help'])],
|
|
24
|
+
duration_ms: Date.now() - started,
|
|
25
|
+
stdout_tail: codex0139ProbeTail(`${help.stdout || ''}\n${sandboxHelp.stdout || ''}\n${dry.stdout || ''}`),
|
|
26
|
+
stderr_tail: codex0139ProbeTail(`${help.stderr || ''}\n${sandboxHelp.stderr || ''}\n${dry.stderr || ''}`),
|
|
27
|
+
artifact_paths: [],
|
|
28
|
+
evidence: {
|
|
29
|
+
help_mentions_P: topLevelHelpMentionsAlias || sandboxHelpMentionsAlias,
|
|
30
|
+
top_level_help_mentions_P: topLevelHelpMentionsAlias,
|
|
31
|
+
sandbox_help_mentions_P: sandboxHelpMentionsAlias,
|
|
32
|
+
dry_command_attempted: true,
|
|
33
|
+
dry_command_line: [codexBin, ...dryArgs],
|
|
34
|
+
dry_command_accepted: dryAccepted,
|
|
35
|
+
dry_command_warning: dryAccepted ? null : 'help proof accepted; dry no-op unsupported in this CLI shape'
|
|
36
|
+
},
|
|
37
|
+
blockers: ok ? [] : ['codex_sandbox_profile_alias_help_missing']
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export async function runCodex0139SandboxProxyPreservationProbe(input) {
|
|
41
|
+
const started = Date.now();
|
|
42
|
+
const codexBin = input.codexBin || await findCodexBinary();
|
|
43
|
+
if (!codexBin)
|
|
44
|
+
return skippedCodex0139Probe('codex_cli_missing');
|
|
45
|
+
const tempDir = path.join(input.root, '.sneakoscope', 'tmp', 'codex-0139-real-probes', `sandbox-proxy-${Date.now()}`);
|
|
46
|
+
await ensureDir(tempDir);
|
|
47
|
+
const args = ['sandbox', '-P', ':read-only', '-C', tempDir, '--', 'true'];
|
|
48
|
+
const result = await runProcess(codexBin, args, {
|
|
49
|
+
cwd: tempDir,
|
|
50
|
+
timeoutMs: input.timeoutMs || 30000,
|
|
51
|
+
maxOutputBytes: 64 * 1024
|
|
52
|
+
}).catch((err) => ({ code: 1, stdout: '', stderr: err?.message || String(err) }));
|
|
53
|
+
const safeNoopRan = result.code === 0;
|
|
54
|
+
const proxyMarkerAvailable = Boolean(process.env.HTTPS_PROXY || process.env.HTTP_PROXY || process.env.ALL_PROXY);
|
|
55
|
+
const approvedEscalationPreservationScriptable = process.env.SKS_CODEX_0139_SANDBOX_PROXY_APPROVED_ESCALATION_RETRY === '1';
|
|
56
|
+
const ok = safeNoopRan && (!input.requireReal || approvedEscalationPreservationScriptable);
|
|
57
|
+
return {
|
|
58
|
+
ok,
|
|
59
|
+
mode: 'actual-cli',
|
|
60
|
+
command_line: [codexBin, ...args],
|
|
61
|
+
duration_ms: Date.now() - started,
|
|
62
|
+
stdout_tail: codex0139ProbeTail(result.stdout),
|
|
63
|
+
stderr_tail: codex0139ProbeTail(result.stderr),
|
|
64
|
+
artifact_paths: [tempDir],
|
|
65
|
+
evidence: {
|
|
66
|
+
safe_noop_ran: safeNoopRan,
|
|
67
|
+
proxy_marker_available: proxyMarkerAvailable,
|
|
68
|
+
proxy_marker_checked: proxyMarkerAvailable,
|
|
69
|
+
approved_escalation_preservation_scriptable: approvedEscalationPreservationScriptable,
|
|
70
|
+
approved_escalation_retry_env: 'SKS_CODEX_0139_SANDBOX_PROXY_APPROVED_ESCALATION_RETRY=1',
|
|
71
|
+
permissions_profile: ':read-only'
|
|
72
|
+
},
|
|
73
|
+
blockers: ok ? [] : [
|
|
74
|
+
...(safeNoopRan ? [] : ['codex_sandbox_proxy_safe_noop_failed']),
|
|
75
|
+
...(input.requireReal && !approvedEscalationPreservationScriptable ? ['codex_sandbox_proxy_escalation_preservation_not_safely_scriptable'] : [])
|
|
76
|
+
]
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=codex-0139-sandbox-real-probe.js.map
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { buildCodexExecArgs, findCodexBinary } from '../codex-adapter.js';
|
|
4
|
+
import { ensureDir, runProcess, writeJsonAtomic, writeTextAtomic } from '../fsx.js';
|
|
5
|
+
import { codex0139ProbeTail, skippedCodex0139Probe } from './codex-0139-real-probes.js';
|
|
6
|
+
export async function runCodex0139WebSearchRealProbe(input) {
|
|
7
|
+
const started = Date.now();
|
|
8
|
+
if (!input.allowNetwork) {
|
|
9
|
+
const skipped = skippedCodex0139Probe('codex_web_search_network_not_allowed', { allow_network: false });
|
|
10
|
+
return input.requireReal ? { ...skipped, blockers: ['codex_web_search_network_not_allowed'] } : skipped;
|
|
11
|
+
}
|
|
12
|
+
const codexBin = input.codexBin || await findCodexBinary();
|
|
13
|
+
if (!codexBin)
|
|
14
|
+
return skippedCodex0139Probe('codex_cli_missing');
|
|
15
|
+
const tempDir = path.join(input.root, '.sneakoscope', 'tmp', 'codex-0139-real-probes', `web-search-${Date.now()}`);
|
|
16
|
+
await ensureDir(tempDir);
|
|
17
|
+
await writeTextAtomic(path.join(tempDir, 'README.md'), 'Temporary Codex 0.139 web-search real probe workspace.\n');
|
|
18
|
+
const outputFile = path.join(tempDir, 'last-message.txt');
|
|
19
|
+
const prompt = 'In code mode, use standalone web search to find the title of https://example.com or OpenAI Codex release 0.139. Return JSON {"used_web_search":true,"answer":"...","sources":[...]}.';
|
|
20
|
+
const args = buildCodexExecArgs({ root: tempDir, prompt, outputFile, json: true, extraArgs: [] });
|
|
21
|
+
const result = await runProcess(codexBin, args, {
|
|
22
|
+
cwd: tempDir,
|
|
23
|
+
timeoutMs: input.timeoutMs || 120000,
|
|
24
|
+
maxOutputBytes: 512 * 1024,
|
|
25
|
+
stdoutFile: path.join(tempDir, 'codex.stdout.log'),
|
|
26
|
+
stderrFile: path.join(tempDir, 'codex.stderr.log')
|
|
27
|
+
}).catch((err) => ({
|
|
28
|
+
code: 1,
|
|
29
|
+
stdout: '',
|
|
30
|
+
stderr: err?.message || String(err)
|
|
31
|
+
}));
|
|
32
|
+
const output = await fs.readFile(outputFile, 'utf8').catch(() => '');
|
|
33
|
+
const combined = `${result.stdout || ''}\n${result.stderr || ''}\n${output}`;
|
|
34
|
+
const sawWebSearchEvent = /\b(web[_ -]?search|search_result|sources?|tool_call|standalone web search)\b/i.test(combined);
|
|
35
|
+
const sawPlaintextResult = /(Example Domain|example\.com|OpenAI|Codex|0\.139)/i.test(combined);
|
|
36
|
+
const resultContainsExpectedMarker = /"used_web_search"\s*:\s*true|used_web_search/i.test(combined) || sawWebSearchEvent;
|
|
37
|
+
const processExitedSuccessfully = result.code === 0;
|
|
38
|
+
const ok = sawPlaintextResult && resultContainsExpectedMarker;
|
|
39
|
+
if (ok) {
|
|
40
|
+
await writeJsonAtomic(path.join(input.root, '.sneakoscope', 'codex-0139-code-mode-web-search-policy.json'), {
|
|
41
|
+
schema: 'sks.codex-0139-code-mode-web-search-policy.v1',
|
|
42
|
+
ok: true,
|
|
43
|
+
generated_at: new Date().toISOString(),
|
|
44
|
+
allow_standalone_web_search_in_code_mode: true,
|
|
45
|
+
real_probe_verified: true,
|
|
46
|
+
evidence: {
|
|
47
|
+
saw_web_search_event: sawWebSearchEvent,
|
|
48
|
+
saw_plaintext_result: sawPlaintextResult,
|
|
49
|
+
result_contains_expected_marker: resultContainsExpectedMarker
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
ok,
|
|
55
|
+
mode: 'actual-cli',
|
|
56
|
+
command_line: [codexBin, ...args],
|
|
57
|
+
duration_ms: Date.now() - started,
|
|
58
|
+
stdout_tail: codex0139ProbeTail(result.stdout),
|
|
59
|
+
stderr_tail: codex0139ProbeTail(result.stderr),
|
|
60
|
+
artifact_paths: [tempDir, outputFile],
|
|
61
|
+
evidence: {
|
|
62
|
+
saw_web_search_event: sawWebSearchEvent,
|
|
63
|
+
saw_plaintext_result: sawPlaintextResult,
|
|
64
|
+
result_contains_expected_marker: resultContainsExpectedMarker,
|
|
65
|
+
process_exited_successfully: processExitedSuccessfully,
|
|
66
|
+
process_warning: processExitedSuccessfully ? null : 'Codex emitted web-search evidence before process timeout/nonzero exit.',
|
|
67
|
+
output_file: outputFile
|
|
68
|
+
},
|
|
69
|
+
blockers: ok ? [] : ['codex_web_search_real_probe_failed']
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=codex-0139-web-search-probe.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function normalizeCodexMultiAgentEventName(name) {
|
|
2
|
+
const sourceName = String(name || '');
|
|
3
|
+
const normalized = sourceName.trim().toLowerCase().replace(/[-.\s]+/g, '_');
|
|
4
|
+
if (normalized === 'start_agent' || normalized === 'spawn_agent' || normalized === 'subagent_start') {
|
|
5
|
+
return { canonical: 'start_agent', stage: 'start', source_name: sourceName };
|
|
6
|
+
}
|
|
7
|
+
if (normalized === 'interrupt_agent') {
|
|
8
|
+
return { canonical: 'interrupt_agent', stage: 'result', source_name: sourceName };
|
|
9
|
+
}
|
|
10
|
+
if (normalized === 'close_agent' || normalized === 'subagent_stop') {
|
|
11
|
+
return { canonical: 'close_agent', stage: 'result', source_name: sourceName };
|
|
12
|
+
}
|
|
13
|
+
return { canonical: 'unknown', stage: 'unknown', source_name: sourceName };
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=codex-multi-agent-event-normalizer.js.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { compactMcpToolSchema } from '../mcp/mcp-0-134-policy.js';
|
|
2
|
+
export function buildCodex0139RichToolSchemaFixture() {
|
|
3
|
+
return {
|
|
4
|
+
type: 'object',
|
|
5
|
+
description: 'Codex 0.139 rich tool schema preservation fixture',
|
|
6
|
+
oneOf: [
|
|
7
|
+
{ required: ['mode'], properties: { mode: { const: 'guided' } } },
|
|
8
|
+
{ required: ['query'], properties: { query: { type: 'string' } } }
|
|
9
|
+
],
|
|
10
|
+
allOf: [
|
|
11
|
+
{ required: ['kind'] },
|
|
12
|
+
{ properties: { kind: { enum: ['search', 'inspect'] } } }
|
|
13
|
+
],
|
|
14
|
+
required: ['kind', 'payload'],
|
|
15
|
+
properties: {
|
|
16
|
+
kind: { enum: ['search', 'inspect'] },
|
|
17
|
+
payload: {
|
|
18
|
+
type: 'object',
|
|
19
|
+
required: ['target'],
|
|
20
|
+
properties: {
|
|
21
|
+
target: { type: 'string' },
|
|
22
|
+
filters: {
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: {
|
|
25
|
+
depth: { enum: ['shallow', 'deep'] }
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function passCodex0139RichToolSchemaThroughBridge(schema = buildCodex0139RichToolSchemaFixture()) {
|
|
34
|
+
return compactMcpToolSchema(schema, 128).schema;
|
|
35
|
+
}
|
|
36
|
+
export function evaluateCodex0139RichToolSchemaPreservation(schema = buildCodex0139RichToolSchemaFixture()) {
|
|
37
|
+
const bridged = passCodex0139RichToolSchemaThroughBridge(schema);
|
|
38
|
+
const required = Array.isArray(bridged?.required) ? bridged.required : [];
|
|
39
|
+
const result = {
|
|
40
|
+
schema: 'sks.codex-0139-rich-tool-schema-preservation.v1',
|
|
41
|
+
ok: Array.isArray(bridged?.oneOf)
|
|
42
|
+
&& Array.isArray(bridged?.allOf)
|
|
43
|
+
&& Boolean(bridged?.properties?.payload?.properties?.target)
|
|
44
|
+
&& required.includes('kind')
|
|
45
|
+
&& required.includes('payload'),
|
|
46
|
+
top_level_oneOf_preserved: Array.isArray(bridged?.oneOf),
|
|
47
|
+
top_level_allOf_preserved: Array.isArray(bridged?.allOf),
|
|
48
|
+
nested_structure_preserved: Boolean(bridged?.properties?.payload?.properties?.target),
|
|
49
|
+
required_fields_retained: required.includes('kind') && required.includes('payload'),
|
|
50
|
+
bridged_schema: bridged
|
|
51
|
+
};
|
|
52
|
+
return {
|
|
53
|
+
...result,
|
|
54
|
+
blockers: result.ok ? [] : ['codex_rich_tool_schema_preservation_failed']
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=codex-tool-schema-fixtures.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { readJson } from '../fsx.js';
|
|
3
|
+
export async function readCodex0139DoctorRealProbeStatus(root) {
|
|
4
|
+
const summary = await readJson(path.join(root, '.sneakoscope', 'codex-0139-real-probe-summary.json'), null);
|
|
5
|
+
const result = await readJson(path.join(root, '.sneakoscope', 'codex-0139-real-probes.json'), null);
|
|
6
|
+
return {
|
|
7
|
+
schema: 'sks.doctor-codex-0139-real-probes.v1',
|
|
8
|
+
codex_cli_version: result?.version_text || null,
|
|
9
|
+
capability_version_flag: Boolean(result?.parsed_version && String(result.parsed_version).startsWith('0.139')),
|
|
10
|
+
real_probes_last_run_status: summary ? (summary.ok ? 'ok' : 'blocked') : 'not_run',
|
|
11
|
+
skipped_probes: result?.skipped || [],
|
|
12
|
+
strict_probe_command: 'npm run codex:0139-real-probes:require-real',
|
|
13
|
+
unsafe_auto_fix: false
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=codex-0139-doctor.js.map
|
|
@@ -58,6 +58,11 @@ export function buildDoctorReadinessMatrix(input = {}) {
|
|
|
58
58
|
warnings.add(blocker);
|
|
59
59
|
for (const warning of normalizeList(codex0138Doctor?.warnings))
|
|
60
60
|
warnings.add(warning);
|
|
61
|
+
const codex0139RealProbes = input.codex_0139_real_probes || null;
|
|
62
|
+
if (codex0139RealProbes?.real_probes_last_run_status === 'blocked')
|
|
63
|
+
warnings.add('codex_0139_real_probes_blocked');
|
|
64
|
+
if (codex0139RealProbes?.real_probes_last_run_status === 'not_run')
|
|
65
|
+
warnings.add('codex_0139_real_probes_not_run');
|
|
61
66
|
for (const warning of normalizeList(input.codex_plugin_app_template_policy?.doctor_warnings))
|
|
62
67
|
warnings.add(warning);
|
|
63
68
|
if (input.codex_lb?.ok === false)
|
|
@@ -116,6 +121,7 @@ export function buildDoctorReadinessMatrix(input = {}) {
|
|
|
116
121
|
},
|
|
117
122
|
codex_doctor: codexDoctor || null,
|
|
118
123
|
codex_0138_doctor: codex0138Doctor,
|
|
124
|
+
codex_0139_real_probes: codex0139RealProbes,
|
|
119
125
|
codex_plugin_inventory: input.codex_plugin_inventory || null,
|
|
120
126
|
codex_plugin_app_template_policy: input.codex_plugin_app_template_policy || null,
|
|
121
127
|
fast_mode_ready: input.fast_mode_ready !== false,
|