sneakoscope 3.1.4 → 3.1.6
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 +8 -36
- 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/cli/command-registry.js +1 -2
- package/dist/cli/install-helpers.js +56 -4
- package/dist/commands/codex-app.js +1 -11
- package/dist/commands/codex-lb.js +12 -9
- package/dist/commands/codex-native.js +68 -0
- package/dist/commands/doctor.js +64 -0
- package/dist/core/codex-app/codex-agent-role-sync.js +69 -11
- package/dist/core/codex-app/codex-agent-type-probe.js +202 -0
- package/dist/core/codex-app/codex-app-execution-profile.js +43 -14
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +7 -4
- package/dist/core/codex-app/codex-app-harness-matrix.js +4 -65
- package/dist/core/codex-app/codex-app-types.js +21 -0
- package/dist/core/codex-app/codex-hook-approval-probe.js +188 -0
- package/dist/core/codex-app/codex-hook-lifecycle.js +34 -10
- package/dist/core/codex-app/codex-init-deep.js +154 -3
- package/dist/core/codex-app/codex-skill-sync.js +84 -9
- package/dist/core/codex-native/codex-native-capability-cache.js +21 -0
- package/dist/core/codex-native/codex-native-feature-broker.js +182 -0
- package/dist/core/codex-native/codex-native-feature-matrix.js +31 -0
- package/dist/core/codex-native/codex-native-harness-compat.js +54 -0
- package/dist/core/codex-native/codex-native-interop-policy.js +58 -0
- package/dist/core/codex-native/codex-native-invocation-router.js +112 -0
- package/dist/core/codex-native/codex-native-pattern-analysis.js +56 -0
- package/dist/core/codex-native/codex-native-reference-evidence.js +2 -0
- package/dist/core/codex-native/codex-native-reference-source.js +110 -0
- package/dist/core/codex-native/codex-native-rename-map.js +25 -0
- package/dist/core/commands/mad-sks-command.js +37 -2
- package/dist/core/commands/qa-loop-command.js +3 -2
- package/dist/core/commands/research-command.js +2 -2
- package/dist/core/doctor/doctor-zellij-repair.js +5 -1
- package/dist/core/feature-fixtures.js +3 -4
- package/dist/core/feature-registry.js +5 -2
- package/dist/core/fsx.js +1 -1
- package/dist/core/image/image-artifact-path-contract.js +18 -1
- package/dist/core/init.js +4 -1
- package/dist/core/loops/loop-continuation-enforcer.js +11 -3
- package/dist/core/loops/loop-owner-inference.js +3 -0
- package/dist/core/loops/loop-planner.js +28 -5
- package/dist/core/loops/loop-worker-runtime.js +52 -8
- package/dist/core/naruto/naruto-loop-worker-router.js +11 -2
- package/dist/core/qa-loop.js +62 -4
- package/dist/core/research/research-cycle-runner.js +1 -0
- package/dist/core/research/research-stage-runner.js +9 -2
- package/dist/core/research.js +68 -1
- package/dist/core/routes.js +2 -3
- package/dist/core/version.js +1 -1
- package/dist/core/zellij/homebrew-policy.js +0 -1
- package/dist/core/zellij/zellij-self-heal-types.js +45 -0
- package/dist/core/zellij/zellij-self-heal.js +69 -8
- package/dist/core/zellij/zellij-update.js +9 -1
- package/dist/scripts/sks-3-1-4-directive-check-lib.js +1 -30
- package/dist/scripts/sks-3-1-5-directive-check-lib.js +318 -0
- package/dist/scripts/sks-3-1-6-directive-check-lib.js +522 -0
- package/package.json +53 -9
- package/dist/cli/hermes-command.js +0 -99
- package/dist/cli/openclaw-command.js +0 -83
- package/dist/commands/hermes.js +0 -5
- package/dist/commands/openclaw.js +0 -3
- package/dist/core/codex-app/lazycodex-analysis.js +0 -51
- package/dist/core/codex-app/lazycodex-interop-policy.js +0 -49
- package/dist/core/hermes.js +0 -192
- package/dist/core/openclaw.js +0 -171
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { findCodexBinary } from '../codex-adapter.js';
|
|
3
|
+
import { codexAppIntegrationStatus } from '../codex-app.js';
|
|
4
|
+
import { syncCodexAgentRoles } from '../codex-app/codex-agent-role-sync.js';
|
|
5
|
+
import { probeCodexAgentTypeSupport } from '../codex-app/codex-agent-type-probe.js';
|
|
6
|
+
import { probeCodexHookApprovalState } from '../codex-app/codex-hook-approval-probe.js';
|
|
7
|
+
import { syncCodexSksSkills } from '../codex-app/codex-skill-sync.js';
|
|
8
|
+
import { detectCodex0138Capability } from '../codex-control/codex-0138-capability.js';
|
|
9
|
+
import { detectCodex0139Capability } from '../codex-control/codex-0139-capability.js';
|
|
10
|
+
import { buildCodexPluginInventory } from '../codex-plugins/codex-plugin-json.js';
|
|
11
|
+
import { nowIso, runProcess, writeJsonAtomic } from '../fsx.js';
|
|
12
|
+
import { buildMcpPluginServerCandidates } from '../mcp/mcp-plugin-inventory.js';
|
|
13
|
+
import { codexNativeFeatureState, computeCodexNativeInvocationDefaults } from './codex-native-feature-matrix.js';
|
|
14
|
+
const REPORT_PATH = '.sneakoscope/reports/codex-native-feature-matrix.json';
|
|
15
|
+
export async function buildCodexNativeFeatureMatrix(input = { root: process.cwd() }) {
|
|
16
|
+
const root = path.resolve(input.root || process.cwd());
|
|
17
|
+
const fixtureMode = process.env.SKS_CODEX_0138_FAKE === '1' || process.env.SKS_CODEX_0139_FAKE === '1' || process.env.SKS_CODEX_PLUGIN_JSON_FAKE === '1';
|
|
18
|
+
const codexBin = fixtureMode ? process.env.CODEX_BIN || 'codex' : await findCodexBinary().catch(() => null);
|
|
19
|
+
const version = codexBin ? await codexVersion(codexBin) : null;
|
|
20
|
+
const cap0138 = await detectCodex0138Capability({ codexBin }).catch((err) => ({ blockers: [messageOf(err)] }));
|
|
21
|
+
const cap0139 = await detectCodex0139Capability({ codexBin }).catch((err) => ({ blockers: [messageOf(err)] }));
|
|
22
|
+
const app = await codexAppIntegrationStatus({ codex: { bin: codexBin, version, available: Boolean(codexBin) } }).catch((err) => ({ ok: false, blockers: [messageOf(err)] }));
|
|
23
|
+
const plugins = await buildCodexPluginInventory().catch((err) => ({
|
|
24
|
+
schema: 'sks.codex-plugin-inventory.v1',
|
|
25
|
+
generated_at: nowIso(),
|
|
26
|
+
codex_0138_capability: null,
|
|
27
|
+
fetch_concurrency: 0,
|
|
28
|
+
detail_fetch_count: 0,
|
|
29
|
+
detail_fetch_failed_count: 0,
|
|
30
|
+
duration_ms: 0,
|
|
31
|
+
plugins: [],
|
|
32
|
+
marketplace_available: false,
|
|
33
|
+
blockers: [messageOf(err)]
|
|
34
|
+
}));
|
|
35
|
+
const mcpCandidates = buildMcpPluginServerCandidates(plugins);
|
|
36
|
+
await writeJsonAtomic(path.join(root, '.sneakoscope', 'codex-plugin-inventory.json'), plugins).catch(() => undefined);
|
|
37
|
+
await writeJsonAtomic(path.join(root, '.sneakoscope', 'mcp-plugin-server-candidates.json'), mcpCandidates).catch(() => undefined);
|
|
38
|
+
const hookApproval = await probeCodexHookApprovalState(root, { codexBin }).catch((err) => ({
|
|
39
|
+
schema: 'sks.codex-hook-approval-probe.v1',
|
|
40
|
+
generated_at: nowIso(),
|
|
41
|
+
ok: false,
|
|
42
|
+
detectable: false,
|
|
43
|
+
approval_state: 'unknown',
|
|
44
|
+
sources_checked: [],
|
|
45
|
+
blockers: [messageOf(err)],
|
|
46
|
+
warnings: ['hook_approval_probe_failed']
|
|
47
|
+
}));
|
|
48
|
+
const agentType = await probeCodexAgentTypeSupport(root, { codexBin }).catch((err) => ({
|
|
49
|
+
schema: 'sks.codex-agent-type-probe.v1',
|
|
50
|
+
generated_at: nowIso(),
|
|
51
|
+
ok: false,
|
|
52
|
+
supported: false,
|
|
53
|
+
source: 'unknown',
|
|
54
|
+
spawn_tool_name: 'unknown',
|
|
55
|
+
schema_path: null,
|
|
56
|
+
evidence: [],
|
|
57
|
+
blockers: [messageOf(err)],
|
|
58
|
+
warnings: ['agent_type_probe_failed_message_role_fallback']
|
|
59
|
+
}));
|
|
60
|
+
const skillSync = await syncCodexSksSkills({ root, apply: input.applyRepairs === true }).catch((err) => ({ ok: false, blockers: [messageOf(err)] }));
|
|
61
|
+
const agentRoles = await syncCodexAgentRoles({ root, apply: input.applyRepairs === true }).catch((err) => ({ ok: false, blockers: [messageOf(err)] }));
|
|
62
|
+
const appRecord = isRecord(app) ? app : {};
|
|
63
|
+
const requiredSkills = isRecord(appRecord.required_skills) ? appRecord.required_skills : {};
|
|
64
|
+
const skills = isRecord(appRecord.skills) ? appRecord.skills : {};
|
|
65
|
+
const skillShadows = isRecord(appRecord.skill_shadows) ? appRecord.skill_shadows : {};
|
|
66
|
+
const skillPickerReady = requiredSkills.ok === true || skills.ok === true || skillShadows.ok !== false;
|
|
67
|
+
const hookApproved = hookApproval.approval_state === 'approved';
|
|
68
|
+
const hookInstalled = hookApproval.approval_state !== 'not_installed';
|
|
69
|
+
const features = {
|
|
70
|
+
plugin_json: boolState(booleanFeature(cap0138, 'supports_plugin_json'), 'actual-probe', '.sneakoscope/codex-0138-capability.json', blockersOf(cap0138)),
|
|
71
|
+
plugin_marketplace: boolState(booleanFeature(cap0139, 'supports_marketplace_source_field') || plugins.marketplace_available, 'plugin-inventory', '.sneakoscope/codex-plugin-inventory.json', blockersOf(plugins)),
|
|
72
|
+
hook_approval: codexNativeFeatureState({
|
|
73
|
+
ok: hookApproved,
|
|
74
|
+
source: 'actual-probe',
|
|
75
|
+
artifact_path: '.sneakoscope/reports/codex-hook-approval-probe.json',
|
|
76
|
+
evidence: [`approval_state:${hookApproval.approval_state}`],
|
|
77
|
+
blockers: hookApproval.approval_state === 'modified_requires_reapproval' ? ['hook_modified_requires_reapproval'] : [],
|
|
78
|
+
warnings: [...hookApproval.warnings, ...(!hookApproved && hookInstalled ? ['hook_derived_evidence_not_counted'] : [])],
|
|
79
|
+
unavailableStatus: hookInstalled ? 'unknown' : 'unavailable'
|
|
80
|
+
}),
|
|
81
|
+
skill_picker: boolState(skillPickerReady, 'config', '.sneakoscope/reports/codex-native-feature-matrix.json', [], skillPickerReady ? [] : ['skill_picker_unverified']),
|
|
82
|
+
skill_sync: boolState(recordOk(skillSync) !== false, 'actual-probe', '.sneakoscope/reports/codex-skill-sync.json', blockersOf(skillSync)),
|
|
83
|
+
agent_roles: boolState(recordOk(agentRoles) !== false, 'actual-probe', '.sneakoscope/reports/codex-agent-role-sync.json', blockersOf(agentRoles)),
|
|
84
|
+
agent_type: codexNativeFeatureState({
|
|
85
|
+
ok: agentType.supported === true,
|
|
86
|
+
source: agentType.source === 'fixture' ? 'fixture' : 'actual-probe',
|
|
87
|
+
artifact_path: '.sneakoscope/reports/codex-agent-type-probe.json',
|
|
88
|
+
evidence: agentType.evidence,
|
|
89
|
+
blockers: [],
|
|
90
|
+
warnings: [...agentType.warnings, ...(agentType.supported ? [] : ['agent_type_unavailable_message_role_fallback'])],
|
|
91
|
+
unavailableStatus: 'fallback'
|
|
92
|
+
}),
|
|
93
|
+
mcp_inventory: codexNativeFeatureState({
|
|
94
|
+
ok: mcpCandidates.candidates.length > 0 || Array.isArray(plugins.plugins),
|
|
95
|
+
source: 'plugin-inventory',
|
|
96
|
+
artifact_path: '.sneakoscope/mcp-plugin-server-candidates.json',
|
|
97
|
+
evidence: [`candidate_count:${mcpCandidates.candidates.length}`],
|
|
98
|
+
blockers: [...plugins.blockers, ...mcpCandidates.blockers],
|
|
99
|
+
warnings: mcpCandidates.candidates.length ? [] : ['mcp_plugin_candidates_empty'],
|
|
100
|
+
unavailableStatus: 'fallback'
|
|
101
|
+
}),
|
|
102
|
+
app_handoff: boolState(booleanFeature(cap0138, 'supports_app_handoff'), 'actual-probe', '.sneakoscope/codex-0138-capability.json', blockersOf(cap0138)),
|
|
103
|
+
image_path_exposure: boolState(booleanFeature(cap0138, 'supports_image_path_exposure'), 'actual-probe', '.sneakoscope/codex-0138-capability.json', blockersOf(cap0138)),
|
|
104
|
+
code_mode_web_search: boolState(booleanFeature(cap0139, 'supports_code_mode_web_search'), 'actual-probe', '.sneakoscope/codex-0139-capability.json', blockersOf(cap0139)),
|
|
105
|
+
slash_command_bridge: boolState(true, 'config', '.sneakoscope/reports/codex-native-feature-matrix.json'),
|
|
106
|
+
project_memory: boolState(true, 'config', '.sneakoscope/context/AGENTS.generated.md')
|
|
107
|
+
};
|
|
108
|
+
const matrixBase = {
|
|
109
|
+
schema: 'sks.codex-native-feature-matrix.v1',
|
|
110
|
+
generated_at: nowIso(),
|
|
111
|
+
ok: false,
|
|
112
|
+
codex_cli: { available: Boolean(codexBin), version, bin: codexBin },
|
|
113
|
+
features,
|
|
114
|
+
probes: {
|
|
115
|
+
codex_0138: cap0138,
|
|
116
|
+
codex_0139: cap0139,
|
|
117
|
+
app,
|
|
118
|
+
plugin_inventory: plugins,
|
|
119
|
+
mcp_candidates: mcpCandidates,
|
|
120
|
+
hook_approval: hookApproval,
|
|
121
|
+
agent_type: agentType,
|
|
122
|
+
skill_sync: skillSync,
|
|
123
|
+
agent_roles: agentRoles
|
|
124
|
+
},
|
|
125
|
+
invocation_defaults: {
|
|
126
|
+
loop_worker_role_strategy: 'message-role',
|
|
127
|
+
qa_visual_review_strategy: 'headless-artifact',
|
|
128
|
+
research_source_strategy: 'local-files',
|
|
129
|
+
image_followup_strategy: 'artifact-path',
|
|
130
|
+
hook_evidence_policy: 'unknown-do-not-count',
|
|
131
|
+
skill_bridge_strategy: 'cli-only'
|
|
132
|
+
},
|
|
133
|
+
blockers: [
|
|
134
|
+
...(!codexBin ? ['codex_cli_missing'] : []),
|
|
135
|
+
...Object.values(features).flatMap((feature) => feature.blockers)
|
|
136
|
+
],
|
|
137
|
+
warnings: Object.values(features).flatMap((feature) => feature.warnings)
|
|
138
|
+
};
|
|
139
|
+
const matrix = {
|
|
140
|
+
...matrixBase,
|
|
141
|
+
ok: matrixBase.blockers.length === 0,
|
|
142
|
+
invocation_defaults: computeCodexNativeInvocationDefaults(matrixBase)
|
|
143
|
+
};
|
|
144
|
+
await writeCodexNativeFeatureMatrix(root, matrix, input.missionDir);
|
|
145
|
+
return matrix;
|
|
146
|
+
}
|
|
147
|
+
export async function writeCodexNativeFeatureMatrix(root, matrix, missionDir) {
|
|
148
|
+
await writeJsonAtomic(path.join(root, REPORT_PATH), matrix);
|
|
149
|
+
if (missionDir)
|
|
150
|
+
await writeJsonAtomic(path.join(missionDir, 'codex-native-feature-matrix.json'), matrix).catch(() => undefined);
|
|
151
|
+
}
|
|
152
|
+
function boolState(ok, source, artifactPath, blockers = [], warnings = []) {
|
|
153
|
+
return codexNativeFeatureState({
|
|
154
|
+
ok,
|
|
155
|
+
source,
|
|
156
|
+
artifact_path: artifactPath,
|
|
157
|
+
blockers: ok ? [] : blockers,
|
|
158
|
+
warnings: ok ? warnings : [...warnings, ...(!blockers.length ? ['feature_unavailable'] : [])]
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
async function codexVersion(bin) {
|
|
162
|
+
const run = await runProcess(bin, ['--version'], { timeoutMs: 5000, maxOutputBytes: 16 * 1024 }).catch(() => null);
|
|
163
|
+
return run?.code === 0 ? `${run.stdout || run.stderr || ''}`.trim() || null : null;
|
|
164
|
+
}
|
|
165
|
+
function booleanFeature(value, key) {
|
|
166
|
+
return isRecord(value) && value[key] === true;
|
|
167
|
+
}
|
|
168
|
+
function blockersOf(value) {
|
|
169
|
+
if (!isRecord(value) || !Array.isArray(value.blockers))
|
|
170
|
+
return [];
|
|
171
|
+
return value.blockers.map((item) => String(item)).filter(Boolean);
|
|
172
|
+
}
|
|
173
|
+
function recordOk(value) {
|
|
174
|
+
return isRecord(value) && typeof value.ok === 'boolean' ? value.ok : undefined;
|
|
175
|
+
}
|
|
176
|
+
function isRecord(value) {
|
|
177
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
178
|
+
}
|
|
179
|
+
function messageOf(err) {
|
|
180
|
+
return err instanceof Error ? err.message : String(err);
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=codex-native-feature-broker.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export function codexNativeFeatureState(input) {
|
|
2
|
+
const blockers = uniq(input.blockers || []);
|
|
3
|
+
return {
|
|
4
|
+
ok: input.ok && blockers.length === 0,
|
|
5
|
+
status: input.ok && blockers.length === 0 ? 'available' : input.unavailableStatus || (blockers.length ? 'blocked' : 'unavailable'),
|
|
6
|
+
source: input.source,
|
|
7
|
+
artifact_path: input.artifact_path ?? null,
|
|
8
|
+
evidence: uniq(input.evidence || []),
|
|
9
|
+
blockers,
|
|
10
|
+
warnings: uniq(input.warnings || [])
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export function computeCodexNativeInvocationDefaults(matrix) {
|
|
14
|
+
const features = matrix.features;
|
|
15
|
+
const hookStatus = features.hook_approval.status;
|
|
16
|
+
return {
|
|
17
|
+
loop_worker_role_strategy: features.agent_type.ok ? 'agent_type' : 'message-role',
|
|
18
|
+
qa_visual_review_strategy: features.app_handoff.ok ? 'app-handoff' : 'headless-artifact',
|
|
19
|
+
research_source_strategy: features.mcp_inventory.ok ? 'mcp-plugin-candidates' : features.code_mode_web_search.ok ? 'web-sources' : 'local-files',
|
|
20
|
+
image_followup_strategy: features.image_path_exposure.ok ? 'model-visible-path' : 'artifact-path',
|
|
21
|
+
hook_evidence_policy: hookStatus === 'available' ? 'approved-only' : hookStatus === 'unavailable' ? 'not-installed' : 'unknown-do-not-count',
|
|
22
|
+
skill_bridge_strategy: features.skill_sync.ok || features.skill_picker.ok ? 'sks-managed-skills' : 'cli-only'
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export function matrixFeatureOk(matrix, key) {
|
|
26
|
+
return matrix.features[key].ok;
|
|
27
|
+
}
|
|
28
|
+
export function uniq(values) {
|
|
29
|
+
return [...new Set(values.map((value) => String(value || '').trim()).filter(Boolean))];
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=codex-native-feature-matrix.js.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { buildCodexNativeFeatureMatrix } from './codex-native-feature-broker.js';
|
|
2
|
+
export async function buildCodexAppHarnessMatrixFromNative(input) {
|
|
3
|
+
const matrix = await buildCodexNativeFeatureMatrix(input);
|
|
4
|
+
return codexAppHarnessMatrixFromNative(matrix);
|
|
5
|
+
}
|
|
6
|
+
export function codexAppHarnessMatrixFromNative(matrix) {
|
|
7
|
+
const hookApproval = probeRecord(matrix.probes.hook_approval);
|
|
8
|
+
const agentType = probeRecord(matrix.probes.agent_type);
|
|
9
|
+
const hookState = typeof hookApproval.approval_state === 'string' ? hookApproval.approval_state : 'unknown';
|
|
10
|
+
return {
|
|
11
|
+
schema: 'sks.codex-app-harness-matrix.v1',
|
|
12
|
+
generated_at: matrix.generated_at,
|
|
13
|
+
ok: matrix.ok,
|
|
14
|
+
codex_cli: {
|
|
15
|
+
available: matrix.codex_cli.available,
|
|
16
|
+
version: matrix.codex_cli.version
|
|
17
|
+
},
|
|
18
|
+
app_features: {
|
|
19
|
+
plugin_json: matrix.features.plugin_json.ok,
|
|
20
|
+
marketplace_add: matrix.features.plugin_marketplace.ok,
|
|
21
|
+
marketplace_upgrade: matrix.features.plugin_marketplace.ok,
|
|
22
|
+
startup_review_detectable: hookState !== 'unknown',
|
|
23
|
+
hook_approval_state_detectable: hookState !== 'unknown',
|
|
24
|
+
hook_approval_state: hookState === 'approved'
|
|
25
|
+
|| hookState === 'pending_review'
|
|
26
|
+
|| hookState === 'modified_requires_reapproval'
|
|
27
|
+
|| hookState === 'not_installed'
|
|
28
|
+
? hookState
|
|
29
|
+
: 'unknown',
|
|
30
|
+
skill_picker_ready: matrix.features.skill_picker.ok,
|
|
31
|
+
agent_type_supported: matrix.features.agent_type.ok,
|
|
32
|
+
mcp_inventory_ready: matrix.features.mcp_inventory.ok,
|
|
33
|
+
app_handoff_ready: matrix.features.app_handoff.ok,
|
|
34
|
+
image_path_exposure_ready: matrix.features.image_path_exposure.ok
|
|
35
|
+
},
|
|
36
|
+
sks_integrations: {
|
|
37
|
+
dollar_skills_synced: matrix.features.skill_sync.ok,
|
|
38
|
+
agent_roles_synced: matrix.features.agent_roles.ok,
|
|
39
|
+
hooks_synced: hookState === 'approved',
|
|
40
|
+
init_deep_available: matrix.features.project_memory.ok,
|
|
41
|
+
loop_mesh_app_profile_available: true
|
|
42
|
+
},
|
|
43
|
+
probes: {
|
|
44
|
+
hook_approval: hookApproval,
|
|
45
|
+
agent_type: agentType
|
|
46
|
+
},
|
|
47
|
+
blockers: matrix.blockers,
|
|
48
|
+
warnings: matrix.warnings
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function probeRecord(value) {
|
|
52
|
+
return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=codex-native-harness-compat.js.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import fs from 'node:fs/promises';
|
|
4
|
+
import { nowIso, writeJsonAtomic } from '../fsx.js';
|
|
5
|
+
import { buildCodexPluginInventory } from '../codex-plugins/codex-plugin-json.js';
|
|
6
|
+
const RESERVED_EXTERNAL_ROUTE_SKILLS = ['ulw-loop', 'ulw-plan', 'start-work'];
|
|
7
|
+
export async function buildCodexNativeInteropPolicy(input) {
|
|
8
|
+
const root = path.resolve(input.root);
|
|
9
|
+
const inventory = normalizeInventory(input.inventory || await buildCodexPluginInventory().catch((err) => ({ plugins: [], blockers: [messageOf(err)] })));
|
|
10
|
+
const codexHome = input.codexHome || process.env.CODEX_HOME || path.join(os.homedir(), '.codex');
|
|
11
|
+
const skillNames = await discoverSkillNames([path.join(root, '.agents', 'skills'), path.join(codexHome, 'skills')]);
|
|
12
|
+
const pluginIds = (inventory.plugins || []).map((plugin) => `${plugin.id || ''} ${plugin.name || ''}`.toLowerCase()).filter(Boolean);
|
|
13
|
+
const preservedSkillNames = RESERVED_EXTERNAL_ROUTE_SKILLS.filter((name) => skillNames.includes(name));
|
|
14
|
+
const report = {
|
|
15
|
+
schema: 'sks.codex-native-interop-policy.v1',
|
|
16
|
+
generated_at: nowIso(),
|
|
17
|
+
ok: true,
|
|
18
|
+
mode: input.mode || 'coexist',
|
|
19
|
+
detection: {
|
|
20
|
+
plugin_inventory_ids: pluginIds,
|
|
21
|
+
skill_names: skillNames,
|
|
22
|
+
preserved_skill_names: preservedSkillNames
|
|
23
|
+
},
|
|
24
|
+
policy: {
|
|
25
|
+
clobber_user_skills: false,
|
|
26
|
+
clobber_external_route_assets: false,
|
|
27
|
+
explicit_handoff_required: true,
|
|
28
|
+
artifact_names_brand_neutral: true
|
|
29
|
+
},
|
|
30
|
+
actions: preservedSkillNames.map((name) => `preserve_existing_skill:${name}`),
|
|
31
|
+
blockers: []
|
|
32
|
+
};
|
|
33
|
+
await writeJsonAtomic(path.join(root, '.sneakoscope', 'reports', 'codex-native-interop-policy.json'), report).catch(() => undefined);
|
|
34
|
+
return report;
|
|
35
|
+
}
|
|
36
|
+
function normalizeInventory(value) {
|
|
37
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
38
|
+
return { plugins: [], blockers: [] };
|
|
39
|
+
const record = value;
|
|
40
|
+
return {
|
|
41
|
+
plugins: Array.isArray(record.plugins) ? record.plugins.map((plugin) => plugin && typeof plugin === 'object' ? plugin : {}) : [],
|
|
42
|
+
blockers: Array.isArray(record.blockers) ? record.blockers.map(String) : []
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function messageOf(err) {
|
|
46
|
+
return err instanceof Error ? err.message : String(err);
|
|
47
|
+
}
|
|
48
|
+
async function discoverSkillNames(roots) {
|
|
49
|
+
const names = new Set();
|
|
50
|
+
for (const root of roots) {
|
|
51
|
+
const entries = await fs.readdir(root, { withFileTypes: true }).catch(() => []);
|
|
52
|
+
for (const entry of entries)
|
|
53
|
+
if (entry.isDirectory())
|
|
54
|
+
names.add(entry.name);
|
|
55
|
+
}
|
|
56
|
+
return [...names].sort();
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=codex-native-interop-policy.js.map
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { nowIso, writeJsonAtomic } from '../fsx.js';
|
|
3
|
+
import { buildCodexNativeFeatureMatrix } from './codex-native-feature-broker.js';
|
|
4
|
+
export async function resolveCodexNativeInvocationPlan(input) {
|
|
5
|
+
const root = path.resolve(input.root || process.cwd());
|
|
6
|
+
const matrix = input.matrix || await buildCodexNativeFeatureMatrix({
|
|
7
|
+
root,
|
|
8
|
+
missionDir: input.missionId ? path.join(root, '.sneakoscope', 'missions', input.missionId) : null
|
|
9
|
+
});
|
|
10
|
+
const plan = planFor(matrix, input.route, input.desiredCapability);
|
|
11
|
+
if (input.missionId) {
|
|
12
|
+
const filename = `codex-native-invocation-plan.${routeSlug(input.route)}.${capabilitySlug(input.desiredCapability)}.json`;
|
|
13
|
+
await writeJsonAtomic(path.join(root, '.sneakoscope', 'missions', input.missionId, filename), plan).catch(() => undefined);
|
|
14
|
+
}
|
|
15
|
+
await writeJsonAtomic(path.join(root, '.sneakoscope', 'reports', 'codex-native-invocation-plan.json'), plan).catch(() => undefined);
|
|
16
|
+
return plan;
|
|
17
|
+
}
|
|
18
|
+
function planFor(matrix, route, capability) {
|
|
19
|
+
const blockers = [];
|
|
20
|
+
const warnings = [];
|
|
21
|
+
let selected = 'sks-managed-artifact';
|
|
22
|
+
const artifacts = ['.sneakoscope/reports/codex-native-feature-matrix.json'];
|
|
23
|
+
const proofPolicy = ['record selected strategy and blockers before counting route evidence'];
|
|
24
|
+
if (capability === 'agent-role') {
|
|
25
|
+
if (matrix.invocation_defaults.loop_worker_role_strategy === 'agent_type') {
|
|
26
|
+
selected = 'codex-app-native';
|
|
27
|
+
proofPolicy.push('include native agent_type payload in worker proof');
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
selected = 'message-role-fallback';
|
|
31
|
+
warnings.push('agent_type unavailable; message-role fallback active');
|
|
32
|
+
proofPolicy.push('include message-role fallback in worker proof');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else if (capability === 'visual-review') {
|
|
36
|
+
if (matrix.invocation_defaults.hook_evidence_policy === 'unknown-do-not-count')
|
|
37
|
+
warnings.push('hook-derived evidence will not count');
|
|
38
|
+
selected = matrix.invocation_defaults.qa_visual_review_strategy === 'app-handoff' ? 'codex-app-native' : 'sks-managed-artifact';
|
|
39
|
+
if (matrix.invocation_defaults.qa_visual_review_strategy === 'blocked') {
|
|
40
|
+
selected = 'blocked';
|
|
41
|
+
blockers.push('qa_visual_review_unavailable');
|
|
42
|
+
}
|
|
43
|
+
proofPolicy.push('do not pass visual review without accepted artifact or app handoff confirmation');
|
|
44
|
+
}
|
|
45
|
+
else if (capability === 'plugin-source' || capability === 'mcp-source') {
|
|
46
|
+
if (matrix.features.mcp_inventory.ok) {
|
|
47
|
+
selected = 'codex-app-native';
|
|
48
|
+
artifacts.push('.sneakoscope/mcp-plugin-server-candidates.json');
|
|
49
|
+
proofPolicy.push('treat remote MCP servers as candidates only until explicitly enabled');
|
|
50
|
+
}
|
|
51
|
+
else if (matrix.features.code_mode_web_search.ok) {
|
|
52
|
+
selected = 'codex-cli-headless';
|
|
53
|
+
warnings.push('plugin inventory unavailable; code/web source fallback selected');
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
selected = 'sks-managed-artifact';
|
|
57
|
+
warnings.push('plugin inventory unavailable; local/source-ledger fallback selected');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else if (capability === 'web-search') {
|
|
61
|
+
selected = matrix.features.code_mode_web_search.ok ? 'codex-cli-headless' : 'sks-managed-artifact';
|
|
62
|
+
if (!matrix.features.code_mode_web_search.ok)
|
|
63
|
+
warnings.push('code-mode web search not verified');
|
|
64
|
+
}
|
|
65
|
+
else if (capability === 'image-followup') {
|
|
66
|
+
selected = matrix.features.image_path_exposure.ok ? 'codex-app-native' : 'sks-managed-artifact';
|
|
67
|
+
proofPolicy.push(matrix.features.image_path_exposure.ok ? 'include model-visible image path' : 'use saved artifact path contract');
|
|
68
|
+
}
|
|
69
|
+
else if (capability === 'hook-evidence') {
|
|
70
|
+
if (matrix.invocation_defaults.hook_evidence_policy !== 'approved-only') {
|
|
71
|
+
selected = 'blocked';
|
|
72
|
+
blockers.push('hook_approval_not_approved');
|
|
73
|
+
warnings.push('hook-derived proof cannot count');
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
selected = 'codex-app-native';
|
|
77
|
+
}
|
|
78
|
+
proofPolicy.push('approved hooks only; unknown hook state does not count');
|
|
79
|
+
}
|
|
80
|
+
else if (capability === 'project-memory') {
|
|
81
|
+
selected = matrix.features.project_memory.ok ? 'sks-managed-artifact' : 'blocked';
|
|
82
|
+
if (!matrix.features.project_memory.ok)
|
|
83
|
+
blockers.push('project_memory_unavailable');
|
|
84
|
+
proofPolicy.push('project memory is guidance only and never expands write scope');
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
schema: 'sks.codex-native-invocation-plan.v1',
|
|
88
|
+
generated_at: nowIso(),
|
|
89
|
+
ok: blockers.length === 0,
|
|
90
|
+
route,
|
|
91
|
+
desired_capability: capability,
|
|
92
|
+
selected_strategy: selected,
|
|
93
|
+
required_artifacts: artifacts,
|
|
94
|
+
proof_policy: proofPolicy,
|
|
95
|
+
env: {
|
|
96
|
+
SKS_CODEX_NATIVE_STRATEGY: selected,
|
|
97
|
+
SKS_CODEX_NATIVE_FEATURE_MATRIX: '.sneakoscope/reports/codex-native-feature-matrix.json',
|
|
98
|
+
SKS_CODEX_NATIVE_AGENT_ROLE_STRATEGY: matrix.invocation_defaults.loop_worker_role_strategy,
|
|
99
|
+
SKS_CODEX_NATIVE_HOOK_EVIDENCE_POLICY: matrix.invocation_defaults.hook_evidence_policy
|
|
100
|
+
},
|
|
101
|
+
blockers,
|
|
102
|
+
warnings,
|
|
103
|
+
feature_matrix_artifact: '.sneakoscope/reports/codex-native-feature-matrix.json'
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function routeSlug(route) {
|
|
107
|
+
return route.replace(/^\$/, '').toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
|
|
108
|
+
}
|
|
109
|
+
function capabilitySlug(capability) {
|
|
110
|
+
return capability.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=codex-native-invocation-router.js.map
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { nowIso, writeJsonAtomic, writeTextAtomic } from '../fsx.js';
|
|
3
|
+
import { analyzeCodexNativeReferenceSource, renderCodexNativeReferenceMarkdown } from './codex-native-reference-source.js';
|
|
4
|
+
const PATTERN_ROWS = [
|
|
5
|
+
row('no-global-optional-tooling', 'Optional tooling stays non-global by default', 'adapt', ['src/core/zellij/zellij-self-heal.ts'], ['Keep optional repair/install paths explicit and proof-backed.']),
|
|
6
|
+
row('plugin-lifecycle-state-separation', 'Plugin install and approval are separate states', 'adopt', ['src/core/codex-native/codex-native-feature-broker.ts'], ['Do not count installed tools as approved evidence.']),
|
|
7
|
+
row('hook-approval-gating', 'Hook approval gates counted evidence', 'adopt', ['src/core/codex-app/codex-hook-lifecycle.ts'], ['Unknown or pending hook approval does not count as proof.']),
|
|
8
|
+
row('skill-picker-route-bridge', 'SKS route skills bridge command picker usage', 'adapt', ['src/core/codex-app/codex-skill-sync.ts'], ['Managed skills expose route purpose, command, proof path, and failure recovery.']),
|
|
9
|
+
row('native-agent-role-probe', 'Native agent role payload is probed before use', 'adopt', ['src/core/codex-app/codex-agent-type-probe.ts'], ['Use agent_type only when the probe supports it.']),
|
|
10
|
+
row('message-role-fallback', 'Message-role fallback is explicit', 'adopt', ['src/core/codex-native/codex-native-invocation-router.ts'], ['Fallback remains valid but must be recorded in proof.']),
|
|
11
|
+
row('directory-local-memory', 'Directory-local memory is guidance', 'adapt', ['src/core/codex-app/codex-init-deep.ts', 'src/core/loops/loop-planner.ts'], ['Memory hints never widen owner scope.']),
|
|
12
|
+
row('plan-work-proof-separation', 'Plan, work, and proof stay separate', 'adopt', ['src/core/loops', 'src/core/naruto'], ['Route artifacts separate planning, execution, and verification.']),
|
|
13
|
+
row('continuation-enforcer', 'Continuation is stateful and bounded', 'adapt', ['src/core/loops/loop-continuation-enforcer.ts'], ['Use runtime proof when hook approval is not approved.']),
|
|
14
|
+
row('doctor-harness-matrix', 'Doctor merges readiness into one story', 'adopt', ['src/commands/doctor.ts'], ['Doctor should show Zellij, Codex Native, Loop, QA, and Research together.']),
|
|
15
|
+
row('mcp-tool-candidate-inventory', 'MCP plugin servers are candidates', 'adapt', ['src/core/mcp/mcp-plugin-inventory.ts'], ['Candidate-only inventory prevents accidental destructive auto-enable.']),
|
|
16
|
+
row('non-clobber-managed-assets', 'Managed assets avoid clobbering user files', 'adopt', ['src/core/codex-app/codex-skill-sync.ts', 'src/core/codex-app/codex-agent-role-sync.ts'], ['Skip unmarked user assets and include checksums for managed content.'])
|
|
17
|
+
];
|
|
18
|
+
export async function buildCodexNativePatternAnalysis(input) {
|
|
19
|
+
const root = path.resolve(input.root);
|
|
20
|
+
const evidence = input.evidence || await analyzeCodexNativeReferenceSource({ root, sourceDir: input.sourceDir || null, writeReport: true }).catch(() => null);
|
|
21
|
+
const evidenceByPattern = new Map();
|
|
22
|
+
for (const item of evidence?.evidence || []) {
|
|
23
|
+
const list = evidenceByPattern.get(item.pattern_id) || [];
|
|
24
|
+
list.push(item.snippet_hash);
|
|
25
|
+
evidenceByPattern.set(item.pattern_id, list);
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
schema: 'sks.codex-native-pattern-analysis.v1',
|
|
29
|
+
generated_at: nowIso(),
|
|
30
|
+
source_kind: 'external-reference-source',
|
|
31
|
+
source_ref: evidence?.source_ref || input.sourceDir || '.sneakoscope/cache/codex-native-reference',
|
|
32
|
+
source_sha: evidence?.source_sha || null,
|
|
33
|
+
patterns: PATTERN_ROWS.map((pattern) => {
|
|
34
|
+
const hashes = evidenceByPattern.get(pattern.id) || [];
|
|
35
|
+
return {
|
|
36
|
+
...pattern,
|
|
37
|
+
confidence: hashes.length ? 'high' : evidence ? 'medium' : 'low',
|
|
38
|
+
evidence_hashes: hashes
|
|
39
|
+
};
|
|
40
|
+
}),
|
|
41
|
+
blockers: evidence?.blockers || ['source_snapshot_missing'],
|
|
42
|
+
warnings: evidence?.warnings || ['reference_evidence_unavailable']
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export async function writeCodexNativePatternAnalysis(root, input = {}) {
|
|
46
|
+
const evidence = await analyzeCodexNativeReferenceSource({ root, sourceDir: input.sourceDir || null, writeReport: true }).catch(() => null);
|
|
47
|
+
const report = await buildCodexNativePatternAnalysis({ root, evidence, sourceDir: input.sourceDir || null });
|
|
48
|
+
await writeJsonAtomic(path.join(root, '.sneakoscope', 'reports', 'codex-native-pattern-analysis.json'), report);
|
|
49
|
+
if (evidence)
|
|
50
|
+
await writeTextAtomic(path.join(root, 'docs', 'codex-native-patterns.md'), renderCodexNativeReferenceMarkdown(evidence)).catch(() => undefined);
|
|
51
|
+
return report;
|
|
52
|
+
}
|
|
53
|
+
function row(id, title, adoption, sks_target_modules, implementation_notes) {
|
|
54
|
+
return { id, title, adoption, sks_target_modules, implementation_notes };
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=codex-native-pattern-analysis.js.map
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { nowIso, writeJsonAtomic, writeTextAtomic } from '../fsx.js';
|
|
5
|
+
const PATTERNS = [
|
|
6
|
+
{ id: 'no-global-optional-tooling', claim: 'optional tooling avoids mandatory global install', re: /\bnpx\b|no[- ]global|global install/i },
|
|
7
|
+
{ id: 'plugin-lifecycle-state-separation', claim: 'plugin install state is separated from approval/readiness', re: /\bplugin\b.+\b(install|enable|marketplace|lifecycle)\b/i },
|
|
8
|
+
{ id: 'hook-approval-gating', claim: 'hook approval is a separate counted evidence gate', re: /\bhook\b.+\b(approval|approve|review|trusted|trust)\b/i },
|
|
9
|
+
{ id: 'skill-picker-route-bridge', claim: 'route skills are exposed through command picker style bridges', re: /\b(skill|command picker|slash command|\$[A-Za-z-]+)\b/i },
|
|
10
|
+
{ id: 'native-agent-role-probe', claim: 'native agent role support is probed before use', re: /\bagent_type\b|agent role|spawn_agent/i },
|
|
11
|
+
{ id: 'message-role-fallback', claim: 'message-role fallback is used when native role payload is unavailable', re: /message[- ]role|fallback/i },
|
|
12
|
+
{ id: 'directory-local-memory', claim: 'directory-local memory is injected as context', re: /AGENTS\.md|directory[- ]local|project memory/i },
|
|
13
|
+
{ id: 'plan-work-proof-separation', claim: 'planning, work, and proof are separated', re: /\b(plan|work|proof)\b/i },
|
|
14
|
+
{ id: 'continuation-enforcer', claim: 'continuation is enforced through loop state', re: /continuation|resume|stop hook/i },
|
|
15
|
+
{ id: 'doctor-harness-matrix', claim: 'doctor merges feature probes into one readiness matrix', re: /doctor|health|matrix|readiness/i },
|
|
16
|
+
{ id: 'mcp-tool-candidate-inventory', claim: 'MCP tools are candidates until approved', re: /\bMCP\b|tool candidate|server candidate/i },
|
|
17
|
+
{ id: 'non-clobber-managed-assets', claim: 'managed assets preserve user-authored content', re: /non[- ]clobber|managed|preserve user|checksum/i }
|
|
18
|
+
];
|
|
19
|
+
export async function analyzeCodexNativeReferenceSource(input) {
|
|
20
|
+
const root = path.resolve(input.root);
|
|
21
|
+
const sourceDir = input.sourceDir ? path.resolve(input.sourceDir) : path.join(root, '.sneakoscope', 'cache', 'codex-native-reference');
|
|
22
|
+
const files = await listTextFiles(sourceDir);
|
|
23
|
+
const evidence = [];
|
|
24
|
+
const blockers = [];
|
|
25
|
+
for (const file of files) {
|
|
26
|
+
const rel = path.relative(sourceDir, file).split(path.sep).join('/');
|
|
27
|
+
const text = await fs.readFile(file, 'utf8').catch(() => '');
|
|
28
|
+
if (text)
|
|
29
|
+
evidence.push(...extractCodexNativeEvidence(rel, text));
|
|
30
|
+
}
|
|
31
|
+
if (!files.length || !evidence.length)
|
|
32
|
+
blockers.push('source_snapshot_missing');
|
|
33
|
+
const report = {
|
|
34
|
+
schema: 'sks.codex-native-reference-evidence.v1',
|
|
35
|
+
generated_at: nowIso(),
|
|
36
|
+
source_kind: 'external-reference-source',
|
|
37
|
+
source_ref: input.sourceRef || sourceDir,
|
|
38
|
+
source_sha: await gitSha(sourceDir),
|
|
39
|
+
evidence,
|
|
40
|
+
blockers,
|
|
41
|
+
warnings: blockers.length ? ['reference_evidence_incomplete'] : []
|
|
42
|
+
};
|
|
43
|
+
if (input.writeReport !== false) {
|
|
44
|
+
await writeJsonAtomic(path.join(root, '.sneakoscope', 'reports', 'codex-native-reference-evidence.json'), report).catch(() => undefined);
|
|
45
|
+
await writeTextAtomic(path.join(root, 'docs', 'codex-native-patterns.md'), renderCodexNativeReferenceMarkdown(report)).catch(() => undefined);
|
|
46
|
+
}
|
|
47
|
+
return report;
|
|
48
|
+
}
|
|
49
|
+
export function extractCodexNativeEvidence(file, text) {
|
|
50
|
+
const lines = text.split(/\r?\n/);
|
|
51
|
+
const rows = [];
|
|
52
|
+
for (const pattern of PATTERNS) {
|
|
53
|
+
const index = lines.findIndex((line) => pattern.re.test(line));
|
|
54
|
+
if (index < 0)
|
|
55
|
+
continue;
|
|
56
|
+
const snippet = lines.slice(Math.max(0, index - 1), Math.min(lines.length, index + 2)).join('\n').slice(0, 500);
|
|
57
|
+
rows.push({
|
|
58
|
+
pattern_id: pattern.id,
|
|
59
|
+
file,
|
|
60
|
+
line_range: [index + 1, index + 1],
|
|
61
|
+
snippet_hash: createHash('sha256').update(snippet).digest('hex'),
|
|
62
|
+
claim_id: pattern.claim,
|
|
63
|
+
confidence: 'high'
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return rows;
|
|
67
|
+
}
|
|
68
|
+
export function renderCodexNativeReferenceMarkdown(report) {
|
|
69
|
+
const rows = report.evidence.map((row) => `| ${row.pattern_id} | ${row.file} | ${row.line_range?.join('-') || '-'} | ${row.snippet_hash.slice(0, 16)} | ${row.confidence} |`).join('\n');
|
|
70
|
+
return [
|
|
71
|
+
'# SKS Codex Native Patterns',
|
|
72
|
+
'',
|
|
73
|
+
'This document records reference-derived Codex-native patterns in SKS-owned vocabulary. It stores line anchors and snippet hashes only.',
|
|
74
|
+
'',
|
|
75
|
+
`Generated at: \`${report.generated_at}\``,
|
|
76
|
+
`Source kind: \`${report.source_kind}\``,
|
|
77
|
+
'',
|
|
78
|
+
'| Pattern | File | Lines | Snippet Hash | Confidence |',
|
|
79
|
+
'|---|---|---:|---|---|',
|
|
80
|
+
rows || '| none | - | - | - | low |',
|
|
81
|
+
''
|
|
82
|
+
].join('\n');
|
|
83
|
+
}
|
|
84
|
+
async function listTextFiles(dir) {
|
|
85
|
+
const out = [];
|
|
86
|
+
await walk(dir, out);
|
|
87
|
+
return out.filter((file) => /\.(md|txt|json|toml|ya?ml|js|ts|mjs|cjs)$/i.test(file)).slice(0, 500);
|
|
88
|
+
}
|
|
89
|
+
async function walk(dir, out) {
|
|
90
|
+
const rows = await fs.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
91
|
+
for (const row of rows) {
|
|
92
|
+
const full = path.join(dir, row.name);
|
|
93
|
+
if (row.isDirectory()) {
|
|
94
|
+
if (['.git', 'node_modules', 'dist'].includes(row.name))
|
|
95
|
+
continue;
|
|
96
|
+
await walk(full, out);
|
|
97
|
+
}
|
|
98
|
+
else if (row.isFile()) {
|
|
99
|
+
out.push(full);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async function gitSha(sourceDir) {
|
|
104
|
+
const head = await fs.readFile(path.join(sourceDir, '.git', 'HEAD'), 'utf8').catch(() => '');
|
|
105
|
+
const ref = head.match(/^ref:\s*(.+)$/m)?.[1];
|
|
106
|
+
if (ref)
|
|
107
|
+
return (await fs.readFile(path.join(sourceDir, '.git', ref), 'utf8').catch(() => '')).trim() || null;
|
|
108
|
+
return /^[0-9a-f]{40}$/i.test(head.trim()) ? head.trim() : null;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=codex-native-reference-source.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const CODEX_NATIVE_RENAME_RULES = [
|
|
2
|
+
{ from_hash: 'external-analysis', to: 'codex-native:pattern-analysis', surface: 'gate' },
|
|
3
|
+
{ from_hash: 'external-evidence', to: 'codex-native:reference-evidence', surface: 'gate' },
|
|
4
|
+
{ from_hash: 'external-interop', to: 'codex-native:interop-policy', surface: 'gate' },
|
|
5
|
+
{ from_hash: 'app-harness', to: 'codex-native:harness-matrix', surface: 'gate' },
|
|
6
|
+
{ from_hash: 'skill-sync', to: 'codex-native:skill-sync', surface: 'gate' },
|
|
7
|
+
{ from_hash: 'agent-role-sync', to: 'codex-native:agent-role-sync', surface: 'gate' },
|
|
8
|
+
{ from_hash: 'hook-lifecycle', to: 'codex-native:hook-lifecycle', surface: 'gate' },
|
|
9
|
+
{ from_hash: 'execution-profile', to: 'codex-native:execution-profile', surface: 'gate' },
|
|
10
|
+
{ from_hash: 'feature-broker', to: 'codex-native:feature-broker', surface: 'gate' },
|
|
11
|
+
{ from_hash: 'invocation-router', to: 'codex-native:invocation-router', surface: 'gate' },
|
|
12
|
+
{ from_hash: 'pattern-schema', to: 'sks.codex-native-pattern-analysis.v1', surface: 'schema' },
|
|
13
|
+
{ from_hash: 'evidence-schema', to: 'sks.codex-native-reference-evidence.v1', surface: 'schema' },
|
|
14
|
+
{ from_hash: 'matrix-schema', to: 'sks.codex-native-feature-matrix.v1', surface: 'schema' },
|
|
15
|
+
{ from_hash: 'plan-schema', to: 'sks.codex-native-invocation-plan.v1', surface: 'schema' },
|
|
16
|
+
{ from_hash: 'pattern-report', to: '.sneakoscope/reports/codex-native-pattern-analysis.json', surface: 'artifact' },
|
|
17
|
+
{ from_hash: 'evidence-report', to: '.sneakoscope/reports/codex-native-reference-evidence.json', surface: 'artifact' },
|
|
18
|
+
{ from_hash: 'matrix-report', to: '.sneakoscope/reports/codex-native-feature-matrix.json', surface: 'artifact' },
|
|
19
|
+
{ from_hash: 'plan-report', to: '.sneakoscope/reports/codex-native-invocation-plan.json', surface: 'artifact' },
|
|
20
|
+
{ from_hash: 'patterns-doc', to: 'docs/codex-native-patterns.md', surface: 'docs' }
|
|
21
|
+
];
|
|
22
|
+
export function codexNativeRenameTargets() {
|
|
23
|
+
return CODEX_NATIVE_RENAME_RULES.map((rule) => rule.to);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=codex-native-rename-map.js.map
|