sneakoscope 0.9.13 → 0.9.14
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 +30 -39
- package/crates/sks-core/Cargo.lock +99 -1
- package/crates/sks-core/Cargo.toml +2 -1
- package/crates/sks-core/src/main.rs +77 -43
- package/package.json +8 -5
- package/src/cli/command-registry.mjs +73 -114
- package/src/cli/feature-commands.mjs +44 -5
- package/src/cli/install-helpers.mjs +2 -2
- package/src/cli/router.mjs +2 -3
- package/src/commands/aliases.mjs +2 -0
- package/src/commands/auto-review.mjs +5 -0
- package/src/commands/autoresearch.mjs +5 -0
- package/src/commands/bootstrap.mjs +2 -0
- package/src/commands/code-structure.mjs +5 -0
- package/src/commands/codex-lb.mjs +61 -3
- package/src/commands/commands.mjs +5 -0
- package/src/commands/commit-and-push.mjs +5 -0
- package/src/commands/commit.mjs +5 -0
- package/src/commands/computer-use.mjs +31 -0
- package/src/commands/conflicts.mjs +13 -0
- package/src/commands/context7.mjs +5 -0
- package/src/commands/db.mjs +1 -1
- package/src/commands/deps.mjs +5 -0
- package/src/commands/dfix.mjs +2 -0
- package/src/commands/doctor.mjs +2 -2
- package/src/commands/dollar-commands.mjs +2 -0
- package/src/commands/eval.mjs +5 -0
- package/src/commands/fix-path.mjs +2 -0
- package/src/commands/gc.mjs +2 -0
- package/src/commands/goal.mjs +5 -0
- package/src/commands/guard.mjs +10 -0
- package/src/commands/gx.mjs +5 -0
- package/src/commands/harness.mjs +5 -0
- package/src/commands/help.mjs +3 -74
- package/src/commands/hook.mjs +8 -0
- package/src/commands/hproof.mjs +5 -0
- package/src/commands/image-ux-review.mjs +38 -0
- package/src/commands/init.mjs +2 -0
- package/src/commands/mad-sks.mjs +14 -0
- package/src/commands/memory.mjs +5 -0
- package/src/commands/openclaw.mjs +2 -0
- package/src/commands/perf.mjs +2 -2
- package/src/commands/pipeline.mjs +25 -0
- package/src/commands/postinstall.mjs +2 -0
- package/src/commands/ppt.mjs +44 -0
- package/src/commands/profile.mjs +5 -0
- package/src/commands/proof-field.mjs +5 -0
- package/src/commands/proof.mjs +22 -1
- package/src/commands/qa-loop.mjs +5 -0
- package/src/commands/quickstart.mjs +2 -0
- package/src/commands/reasoning.mjs +2 -0
- package/src/commands/recallpulse.mjs +5 -0
- package/src/commands/research.mjs +5 -0
- package/src/commands/selftest.mjs +2 -0
- package/src/commands/setup.mjs +2 -0
- package/src/commands/skill-dream.mjs +5 -0
- package/src/commands/stats.mjs +2 -0
- package/src/commands/team.mjs +2 -0
- package/src/commands/tmux.mjs +5 -0
- package/src/commands/update-check.mjs +2 -0
- package/src/commands/usage.mjs +2 -0
- package/src/commands/validate-artifacts.mjs +2 -0
- package/src/commands/versioning.mjs +16 -0
- package/src/commands/wiki.mjs +2 -2
- package/src/core/codex-lb-circuit.mjs +18 -0
- package/src/core/commands/basic-cli.mjs +315 -0
- package/src/{cli/maintenance-commands.mjs → core/commands/route-cli.mjs} +37 -37
- package/src/core/feature-fixture-runner.mjs +109 -0
- package/src/core/feature-fixtures.mjs +1 -1
- package/src/core/feature-registry.mjs +19 -7
- package/src/core/fsx.mjs +1 -1
- package/src/core/git-simple.mjs +118 -0
- package/src/core/pipeline.mjs +1 -1
- package/src/core/proof/route-finalizer-fixtures.mjs +21 -0
- package/src/core/proof/route-finalizer-policy.mjs +13 -0
- package/src/core/proof/route-finalizer.mjs +82 -0
- package/src/core/proof-field.mjs +2 -2
- package/src/core/routes.mjs +31 -1
- package/src/core/rust-accelerator.mjs +8 -3
- package/src/core/version.mjs +1 -1
- package/src/core/wiki-image/before-after-relation.mjs +1 -0
- package/src/core/wiki-image/computer-use-evidence.mjs +1 -0
- package/src/core/wiki-image/generated-review-parser.mjs +1 -0
- package/src/core/wiki-image/image-ux-evidence.mjs +1 -0
- package/src/core/wiki-image/image-voxel-ledger.mjs +10 -3
- package/src/core/wiki-image/ppt-image-evidence.mjs +1 -0
- package/src/core/wiki-image/route-image-evidence.mjs +107 -0
- package/src/cli/legacy-main.mjs +0 -4147
|
@@ -52,7 +52,7 @@ export async function allFeaturesCommand(sub = 'selftest', args = []) {
|
|
|
52
52
|
}
|
|
53
53
|
const root = await projectRoot();
|
|
54
54
|
const registry = await buildFeatureRegistry({ root });
|
|
55
|
-
const result = buildAllFeaturesSelftest(registry, { executeFixtures: flag(args, '--execute-fixtures'), root });
|
|
55
|
+
const result = buildAllFeaturesSelftest(registry, { executeFixtures: flag(args, '--execute-fixtures'), strictArtifacts: flag(args, '--strict-artifacts'), root });
|
|
56
56
|
if (flag(args, '--json')) console.log(JSON.stringify(result, null, 2));
|
|
57
57
|
else {
|
|
58
58
|
console.log('SKS all-features selftest');
|
|
@@ -154,9 +154,19 @@ async function hooksReplayReport(fixturePath) {
|
|
|
154
154
|
const runtime = await evaluateHookPayload(hookName, payload, { root: tempRoot, state });
|
|
155
155
|
const decision = runtime.decision || runtime.permissionDecision || (runtime.continue === true ? 'continue' : 'continue');
|
|
156
156
|
const expected = await readExpectedReplay(absolute);
|
|
157
|
-
const comparable = {
|
|
158
|
-
|
|
159
|
-
|
|
157
|
+
const comparable = {
|
|
158
|
+
decision,
|
|
159
|
+
permissionDecision: runtime.permissionDecision || null,
|
|
160
|
+
reason: runtime.reason || 'fixture_safe',
|
|
161
|
+
gate: runtime.gate || runtime.hookSpecificOutput?.gate || null,
|
|
162
|
+
missing: runtime.missing || runtime.hookSpecificOutput?.missing || [],
|
|
163
|
+
issues: runtime.issues || runtime.hookSpecificOutput?.issues || runtime.missing || [],
|
|
164
|
+
continue: runtime.continue,
|
|
165
|
+
secret_policy: 'redacted'
|
|
166
|
+
};
|
|
167
|
+
const match = expected ? matchHookExpected(comparable, expected) : { ok: decision !== 'block' && decision !== 'deny', failures: [] };
|
|
168
|
+
const matchesExpected = expected ? match.ok : null;
|
|
169
|
+
const ok = match.ok;
|
|
160
170
|
return redactSecrets({
|
|
161
171
|
schema: 'sks.hooks-replay.v1',
|
|
162
172
|
ok,
|
|
@@ -164,12 +174,41 @@ async function hooksReplayReport(fixturePath) {
|
|
|
164
174
|
hook: hookName,
|
|
165
175
|
command: payload.command || payload.tool_input?.command || payload.toolInput?.command || payload.input?.command || '',
|
|
166
176
|
decision,
|
|
167
|
-
|
|
177
|
+
permissionDecision: comparable.permissionDecision,
|
|
178
|
+
reason: comparable.reason,
|
|
179
|
+
gate: comparable.gate,
|
|
180
|
+
missing: comparable.missing,
|
|
181
|
+
issues: comparable.issues,
|
|
182
|
+
continue: comparable.continue,
|
|
168
183
|
matches_expected: matchesExpected,
|
|
184
|
+
expected_failures: match.failures,
|
|
169
185
|
secret_policy: 'redacted'
|
|
170
186
|
});
|
|
171
187
|
}
|
|
172
188
|
|
|
189
|
+
function matchHookExpected(actual = {}, expected = {}) {
|
|
190
|
+
const failures = [];
|
|
191
|
+
if (expected.decision !== undefined && expected.decision !== actual.decision) failures.push(`decision:${actual.decision}`);
|
|
192
|
+
if (expected.permissionDecision !== undefined && expected.permissionDecision !== actual.permissionDecision) failures.push(`permissionDecision:${actual.permissionDecision}`);
|
|
193
|
+
if (expected.reason !== undefined && expected.reason !== actual.reason) failures.push('reason');
|
|
194
|
+
if (expected.reason_contains !== undefined && !String(actual.reason || '').includes(expected.reason_contains)) failures.push('reason_contains');
|
|
195
|
+
if (expected.gate !== undefined && expected.gate !== actual.gate) failures.push(`gate:${actual.gate}`);
|
|
196
|
+
if (expected.continue !== undefined && expected.continue !== actual.continue) failures.push(`continue:${actual.continue}`);
|
|
197
|
+
for (const item of expected.missing_contains || []) {
|
|
198
|
+
if (!containsValue(actual.missing, item)) failures.push(`missing_contains:${item}`);
|
|
199
|
+
}
|
|
200
|
+
for (const item of expected.issues_contains || []) {
|
|
201
|
+
if (!containsValue(actual.issues, item) && !containsValue(actual.missing, item) && !String(actual.reason || '').includes(item)) failures.push(`issues_contains:${item}`);
|
|
202
|
+
}
|
|
203
|
+
if (expected.secret_policy !== undefined && expected.secret_policy !== actual.secret_policy) failures.push(`secret_policy:${actual.secret_policy}`);
|
|
204
|
+
return { ok: failures.length === 0, failures };
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function containsValue(values, item) {
|
|
208
|
+
const list = Array.isArray(values) ? values : [values].filter(Boolean);
|
|
209
|
+
return list.some((value) => String(value || '').includes(item));
|
|
210
|
+
}
|
|
211
|
+
|
|
173
212
|
function normalizeReplayHookName(event = '') {
|
|
174
213
|
const normalized = String(event || '').replace(/[_\s]+/g, '-').toLowerCase();
|
|
175
214
|
if (normalized.includes('pretool') || normalized.includes('pre-tool')) return 'pre-tool';
|
|
@@ -561,7 +561,7 @@ export async function checkCodexLbResponseChain(status = {}, opts = {}) {
|
|
|
561
561
|
|
|
562
562
|
async function recordCodexLbChainHealth(result, opts = {}) {
|
|
563
563
|
if (!result || result.skipped || opts.recordCircuit === false) return result;
|
|
564
|
-
await recordCodexLbHealthEvent(packageRoot(), result).catch(() => null);
|
|
564
|
+
await recordCodexLbHealthEvent(opts.root || packageRoot(), result).catch(() => null);
|
|
565
565
|
return result;
|
|
566
566
|
}
|
|
567
567
|
|
|
@@ -2349,7 +2349,7 @@ export async function selftestCodexLb(tmp) {
|
|
|
2349
2349
|
if (!codexLbLaunch.includes('sks-codex-lb.env')) throw new Error('selftest: tmux launch command does not source codex-lb env file');
|
|
2350
2350
|
if (!codexLbLaunch.includes("'--model' 'gpt-5.5'")) throw new Error('selftest: tmux launch command without args did not force GPT-5.5');
|
|
2351
2351
|
if (!codexLbLaunch.includes('SKS_TMUX_LOGO_ANIMATION') || !codexLbLaunch.includes('SNEAKOSCOPE CODEX')) throw new Error('selftest: tmux launch command does not include the animated SKS logo intro');
|
|
2352
|
-
const madLaunchSource = await safeReadText(path.join(packageRoot(), 'src', '
|
|
2352
|
+
const madLaunchSource = await safeReadText(path.join(packageRoot(), 'src', 'core', 'commands', 'route-cli.mjs'));
|
|
2353
2353
|
if (!madLaunchSource.includes('const lb = await deps.maybePromptCodexLbSetupForLaunch(args)') || !madLaunchSource.includes("const launchLb = lb.status === 'present'") || !madLaunchSource.includes('codexLbImmediateLaunchOpts(cleanArgs, launchLb') || !madLaunchSource.includes('bypass_codex_lb') || !madLaunchSource.includes('model_provider="openai"') || !madLaunchSource.includes('codexLbFreshSession: true')) throw new Error('selftest: MAD launch does not sync codex-lb auth and fresh-session launch options');
|
|
2354
2354
|
|
|
2355
2355
|
}
|
package/src/cli/router.mjs
CHANGED
|
@@ -13,8 +13,8 @@ function normalizeCommand(args = []) {
|
|
|
13
13
|
export async function dispatch(args = []) {
|
|
14
14
|
const { command, args: rest } = normalizeCommand(args);
|
|
15
15
|
if (!command) {
|
|
16
|
-
const
|
|
17
|
-
return
|
|
16
|
+
const mod = await import('../commands/tmux.mjs');
|
|
17
|
+
return mod.run('tmux', ['check']);
|
|
18
18
|
}
|
|
19
19
|
const entry = COMMANDS[command];
|
|
20
20
|
if (!entry) {
|
|
@@ -25,6 +25,5 @@ export async function dispatch(args = []) {
|
|
|
25
25
|
const mod = await entry.lazy();
|
|
26
26
|
const runner = mod.run || mod.main || mod.default;
|
|
27
27
|
if (typeof runner !== 'function') throw new Error(`Command ${command} has no run/main export`);
|
|
28
|
-
if (mod.IS_LEGACY_CLI) return runner([command, ...rest]);
|
|
29
28
|
return runner(command, rest);
|
|
30
29
|
}
|
|
@@ -2,7 +2,8 @@ import path from 'node:path';
|
|
|
2
2
|
import { projectRoot } from '../core/fsx.mjs';
|
|
3
3
|
import { flag, readOption } from '../cli/args.mjs';
|
|
4
4
|
import { printJson } from '../cli/output.mjs';
|
|
5
|
-
import { codexLbMetrics, readCodexLbCircuit, recordCodexLbHealthEvent, resetCodexLbCircuit } from '../core/codex-lb-circuit.mjs';
|
|
5
|
+
import { codexLbMetrics, readCodexLbCircuit, recordCodexLbHealthEvent, resetCodexLbCircuit, codexLbProofEvidence } from '../core/codex-lb-circuit.mjs';
|
|
6
|
+
import { checkCodexLbResponseChain, codexLbStatus, configureCodexLb, formatCodexLbStatusText, releaseCodexLbAuthHold, repairCodexLbAuth, unselectCodexLbProvider } from '../cli/install-helpers.mjs';
|
|
6
7
|
|
|
7
8
|
export async function run(command, args = []) {
|
|
8
9
|
const root = await projectRoot();
|
|
@@ -14,6 +15,57 @@ export async function run(command, args = []) {
|
|
|
14
15
|
if (!result.ok) process.exitCode = 1;
|
|
15
16
|
return;
|
|
16
17
|
}
|
|
18
|
+
if (action === 'status' || action === 'check') {
|
|
19
|
+
const result = await codexLbStatus();
|
|
20
|
+
if (flag(args, '--json')) return printJson(result);
|
|
21
|
+
process.stdout.write(formatCodexLbStatusText(result));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (action === 'health' || action === 'verify-chain' || action === 'chain') {
|
|
25
|
+
const status = await codexLbStatus();
|
|
26
|
+
const result = status.ok ? await checkCodexLbResponseChain(status, { force: true, root }) : { ok: false, status: 'not_configured', codex_lb: status };
|
|
27
|
+
if (flag(args, '--json')) return printJson(result);
|
|
28
|
+
console.log(`codex-lb response chain: ${result.ok ? 'ok' : `failed (${result.status})`}`);
|
|
29
|
+
if (!result.ok) process.exitCode = 1;
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (action === 'repair' || action === 'resync' || action === 'login') {
|
|
33
|
+
const result = await repairCodexLbAuth();
|
|
34
|
+
if (flag(args, '--json')) return printJson(result);
|
|
35
|
+
console.log(`codex-lb repair: ${result.ok ? 'ok' : result.status}`);
|
|
36
|
+
if (!result.ok) process.exitCode = 1;
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (action === 'release') {
|
|
40
|
+
const result = await releaseCodexLbAuthHold({ keepProvider: flag(args, '--keep-provider'), deleteBackup: flag(args, '--delete-backup'), force: flag(args, '--force') });
|
|
41
|
+
if (flag(args, '--json')) return printJson(result);
|
|
42
|
+
console.log(`codex-lb release: ${result.status}`);
|
|
43
|
+
if (['no_backup', 'auth_in_use', 'failed'].includes(result.status)) process.exitCode = 1;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (action === 'unselect') {
|
|
47
|
+
const result = await unselectCodexLbProvider();
|
|
48
|
+
if (flag(args, '--json')) return printJson(result);
|
|
49
|
+
console.log(`codex-lb unselect: ${result.status}`);
|
|
50
|
+
if (result.status === 'failed') process.exitCode = 1;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (action === 'setup' || action === 'reconfigure') {
|
|
54
|
+
const host = readOption(args, '--host', readOption(args, '--domain', null));
|
|
55
|
+
const apiKey = readOption(args, '--api-key', readOption(args, '--key', null));
|
|
56
|
+
if (!host || !apiKey) {
|
|
57
|
+
const result = { ok: false, reason: 'missing_host_or_api_key' };
|
|
58
|
+
if (flag(args, '--json')) return printJson(result);
|
|
59
|
+
console.error('Usage: sks codex-lb setup|reconfigure --host <domain> --api-key <key>');
|
|
60
|
+
process.exitCode = 1;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const result = await configureCodexLb({ host, apiKey });
|
|
64
|
+
if (flag(args, '--json')) return printJson(result);
|
|
65
|
+
console.log(`codex-lb configured: ${result.base_url || result.status}`);
|
|
66
|
+
if (!result.ok) process.exitCode = 1;
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
17
69
|
if (action === 'doctor' && flag(args, '--deep')) {
|
|
18
70
|
const result = { schema: 'sks.codex-lb-doctor.v1', deep: true, ...codexLbMetrics(await readCodexLbCircuit(root)) };
|
|
19
71
|
if (flag(args, '--json')) return printJson(result);
|
|
@@ -42,6 +94,12 @@ export async function run(command, args = []) {
|
|
|
42
94
|
console.log(`codex-lb circuit: ${circuit.state}`);
|
|
43
95
|
return;
|
|
44
96
|
}
|
|
45
|
-
|
|
46
|
-
|
|
97
|
+
if (action === 'proof-evidence') {
|
|
98
|
+
const result = await codexLbProofEvidence(root);
|
|
99
|
+
if (flag(args, '--json')) return printJson(result);
|
|
100
|
+
console.log(`codex-lb proof evidence: ${result.status}`);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
console.error('Usage: sks codex-lb status|metrics|doctor --deep|health|repair|release|unselect|setup|circuit reset|circuit record-fixture|proof-evidence [--json]');
|
|
104
|
+
process.exitCode = 1;
|
|
47
105
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { projectRoot } from '../core/fsx.mjs';
|
|
2
|
+
import { findLatestMission } from '../core/mission.mjs';
|
|
3
|
+
import { flag } from '../cli/args.mjs';
|
|
4
|
+
import { printJson } from '../cli/output.mjs';
|
|
5
|
+
import { finalizeRouteWithProof } from '../core/proof/route-finalizer.mjs';
|
|
6
|
+
|
|
7
|
+
export async function run(command, args = []) {
|
|
8
|
+
const root = await projectRoot();
|
|
9
|
+
const missionArg = args.find((arg) => !String(arg).startsWith('--')) || 'latest';
|
|
10
|
+
const missionId = missionArg === 'latest' ? await findLatestMission(root) : missionArg;
|
|
11
|
+
if (!missionId) {
|
|
12
|
+
const result = { schema: 'sks.computer-use-evidence.v1', ok: false, status: 'missing_mission' };
|
|
13
|
+
if (flag(args, '--json')) return printJson(result);
|
|
14
|
+
console.error('No mission found.');
|
|
15
|
+
process.exitCode = 1;
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const route = command === 'cu' ? '$CU' : '$Computer-Use';
|
|
19
|
+
const proof = await finalizeRouteWithProof(root, {
|
|
20
|
+
missionId,
|
|
21
|
+
route,
|
|
22
|
+
mock: flag(args, '--mock'),
|
|
23
|
+
requireRelation: flag(args, '--fix-claim') || flag(args, '--require-relation'),
|
|
24
|
+
artifacts: ['computer-use-evidence-ledger.json', 'screen-capture-ledger.json', 'image-voxel-ledger.json', 'visual-anchors.json'],
|
|
25
|
+
claims: [{ id: 'computer-use-evidence', status: flag(args, '--mock') ? 'verified_partial' : 'supported' }]
|
|
26
|
+
});
|
|
27
|
+
const result = { schema: 'sks.computer-use-evidence.v1', ok: proof.ok, mission_id: missionId, route, proof: proof.validation };
|
|
28
|
+
if (flag(args, '--json')) return printJson(result);
|
|
29
|
+
console.log(`Computer Use evidence: ${proof.ok ? 'ok' : 'blocked'} ${missionId}`);
|
|
30
|
+
if (!proof.ok) process.exitCode = 1;
|
|
31
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { projectRoot } from '../core/fsx.mjs';
|
|
2
|
+
import { formatHarnessConflictReport, llmHarnessCleanupPrompt, scanHarnessConflicts } from '../core/harness-conflicts.mjs';
|
|
3
|
+
import { flag } from '../cli/args.mjs';
|
|
4
|
+
import { printJson } from '../cli/output.mjs';
|
|
5
|
+
export async function run(_command, args = []) {
|
|
6
|
+
const action = args[0] || 'check';
|
|
7
|
+
const scan = await scanHarnessConflicts(await projectRoot());
|
|
8
|
+
const result = { ...scan, cleanup_prompt: scan.hard_block ? llmHarnessCleanupPrompt(scan) : null };
|
|
9
|
+
if (flag(args, '--json')) return printJson(result);
|
|
10
|
+
if (action === 'prompt') return console.log(result.cleanup_prompt || '');
|
|
11
|
+
console.log(formatHarnessConflictReport(scan));
|
|
12
|
+
if (scan.hard_block) process.exitCode = 1;
|
|
13
|
+
}
|
package/src/commands/db.mjs
CHANGED
package/src/commands/doctor.mjs
CHANGED
|
@@ -8,8 +8,8 @@ import { codexLbMetrics, readCodexLbCircuit } from '../core/codex-lb-circuit.mjs
|
|
|
8
8
|
|
|
9
9
|
export async function run(_command, args = []) {
|
|
10
10
|
if (flag(args, '--fix')) {
|
|
11
|
-
const
|
|
12
|
-
|
|
11
|
+
const { setupCommand } = await import('../core/commands/basic-cli.mjs');
|
|
12
|
+
await setupCommand(['--force', '--local-only']);
|
|
13
13
|
}
|
|
14
14
|
const root = await projectRoot();
|
|
15
15
|
const codex = await getCodexInfo().catch((err) => ({ available: false, error: err.message }));
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { projectRoot } from '../core/fsx.mjs';
|
|
2
|
+
import { harnessGuardStatus } from '../core/harness-guard.mjs';
|
|
3
|
+
import { flag } from '../cli/args.mjs';
|
|
4
|
+
import { printJson } from '../cli/output.mjs';
|
|
5
|
+
export async function run(_command, args = []) {
|
|
6
|
+
const result = await harnessGuardStatus(await projectRoot());
|
|
7
|
+
if (flag(args, '--json')) return printJson(result);
|
|
8
|
+
console.log(`Harness guard: ${result.ok ? 'ok' : 'blocked'}`);
|
|
9
|
+
if (!result.ok) process.exitCode = 1;
|
|
10
|
+
}
|
package/src/commands/help.mjs
CHANGED
|
@@ -1,77 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { flag } from '../cli/args.mjs';
|
|
3
|
-
import { printJson, sksTextLogo } from '../cli/output.mjs';
|
|
4
|
-
|
|
5
|
-
const FALLBACK_CATALOG = [
|
|
6
|
-
{ name: 'help', usage: 'sks help [stable|beta|labs|all]', description: 'Show concise SKS help.' },
|
|
7
|
-
{ name: 'version', usage: 'sks version | sks --version', description: 'Print the installed version.' },
|
|
8
|
-
{ name: 'commands', usage: 'sks commands [--json]', description: 'List the command registry.' },
|
|
9
|
-
{ name: 'root', usage: 'sks root [--json]', description: 'Show the active SKS root.' },
|
|
10
|
-
{ name: 'doctor', usage: 'sks doctor [--json]', description: 'Check local SKS readiness.' },
|
|
11
|
-
{ name: 'features', usage: 'sks features check --json', description: 'Validate feature coverage and fixtures.' },
|
|
12
|
-
{ name: 'all-features', usage: 'sks all-features selftest --mock --json', description: 'Run mock feature fixture checks.' },
|
|
13
|
-
{ name: 'proof', usage: 'sks proof show|validate|latest|export [--json|--md]', description: 'Inspect completion proof.' },
|
|
14
|
-
{ name: 'wiki', usage: 'sks wiki image-ingest|image-validate|image-summary ...', description: 'Manage TriWiki and image voxel ledgers.' },
|
|
15
|
-
{ name: 'hooks', usage: 'sks hooks explain|status|trust-report|replay ...', description: 'Inspect Codex hook policy and trust evidence.' },
|
|
16
|
-
{ name: 'codex-lb', usage: 'sks codex-lb status|metrics|doctor|circuit ...', description: 'Inspect codex-lb readiness and circuit state.' },
|
|
17
|
-
{ name: 'perf', usage: 'sks perf cold-start --json', description: 'Measure CLI cold-start budgets.' },
|
|
18
|
-
{ name: 'team', usage: 'sks team "task"', description: 'Create and observe Team missions.' },
|
|
19
|
-
{ name: 'qa-loop', usage: 'sks qa-loop prepare|run|status ...', description: 'Run QA loop missions.' },
|
|
20
|
-
{ name: 'research', usage: 'sks research prepare|run|status ...', description: 'Run research missions.' },
|
|
21
|
-
{ name: 'ppt', usage: 'sks ppt build|status ...', description: 'Build or inspect PPT route artifacts.' },
|
|
22
|
-
{ name: 'image-ux-review', usage: 'sks image-ux-review status ...', description: 'Inspect image UX review artifacts.' },
|
|
23
|
-
{ name: 'db', usage: 'sks db policy|scan|check ...', description: 'Inspect database safety policy.' },
|
|
24
|
-
{ name: 'gx', usage: 'sks gx init|render|validate|drift|snapshot ...', description: 'Create and verify visual context cartridges.' },
|
|
25
|
-
{ name: 'goal', usage: 'sks goal create|status|pause|resume|clear ...', description: 'Manage the Goal bridge.' }
|
|
26
|
-
];
|
|
1
|
+
import { commandsCommand, helpCommand } from '../core/commands/basic-cli.mjs';
|
|
27
2
|
|
|
28
3
|
export async function run(command, args = []) {
|
|
29
|
-
if (command === 'commands') return
|
|
30
|
-
|
|
31
|
-
if (topic === 'all') return printHelp('all');
|
|
32
|
-
if (['stable', 'beta', 'labs'].includes(topic)) return printHelp(topic);
|
|
33
|
-
if (topic) return printTopic(topic);
|
|
34
|
-
return printHelp('default');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function commands(args = []) {
|
|
38
|
-
const commands = commandRows('all');
|
|
39
|
-
if (flag(args, '--json')) {
|
|
40
|
-
return printJson({
|
|
41
|
-
schema: 'sks.command-registry.v1',
|
|
42
|
-
aliases: ['sks', 'sneakoscope'],
|
|
43
|
-
commands
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
console.log(`${sksTextLogo()}\n\nCommands\n`);
|
|
47
|
-
const width = Math.max(...commands.map((entry) => entry.usage.length));
|
|
48
|
-
for (const entry of commands) console.log(`${entry.usage.padEnd(width)} ${entry.description}`);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function printHelp(filter) {
|
|
52
|
-
const rows = commandRows(filter === 'default' ? 'stable-beta' : filter);
|
|
53
|
-
console.log(`${sksTextLogo()}\n\nUsage\n`);
|
|
54
|
-
console.log(' sks help [stable|beta|labs|all]');
|
|
55
|
-
console.log(' sks commands [--json]');
|
|
56
|
-
console.log(' sks root [--json]');
|
|
57
|
-
console.log(' sks proof show --json');
|
|
58
|
-
console.log('');
|
|
59
|
-
for (const row of rows) console.log(` ${row.usage.padEnd(54)} ${row.description}`);
|
|
60
|
-
console.log('\nCore promises: image-based Voxel TriWiki, Codex App/codex-lb readiness, and completion proof for serious routes.');
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function printTopic(topic) {
|
|
64
|
-
const row = commandRows('all').find((entry) => entry.name === topic);
|
|
65
|
-
if (!row) return printHelp('default');
|
|
66
|
-
console.log(`${sksTextLogo()}\n\n${row.name}\n`);
|
|
67
|
-
console.log(`Usage: ${row.usage}`);
|
|
68
|
-
console.log(row.description);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function commandRows(filter) {
|
|
72
|
-
const maturityByName = new Map(Object.entries(COMMANDS).map(([name, meta]) => [name, meta.maturity || 'labs']));
|
|
73
|
-
const rows = FALLBACK_CATALOG.map((entry) => ({ ...entry, maturity: maturityByName.get(entry.name) || 'labs' }));
|
|
74
|
-
if (filter === 'all') return rows;
|
|
75
|
-
if (filter === 'stable-beta') return rows.filter((row) => row.maturity === 'stable' || row.maturity === 'beta');
|
|
76
|
-
return rows.filter((row) => row.maturity === filter);
|
|
4
|
+
if (command === 'commands') return commandsCommand(args);
|
|
5
|
+
return helpCommand(args);
|
|
77
6
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { hookMain } from '../core/hooks-runtime.mjs';
|
|
2
|
+
import { printJson } from '../cli/output.mjs';
|
|
3
|
+
|
|
4
|
+
export async function run(_command, args = []) {
|
|
5
|
+
const [name = 'user-prompt-submit'] = args;
|
|
6
|
+
const result = await hookMain(name);
|
|
7
|
+
return printJson(result);
|
|
8
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { projectRoot, readJson } from '../core/fsx.mjs';
|
|
3
|
+
import { findLatestMission, loadMission } from '../core/mission.mjs';
|
|
4
|
+
import { flag } from '../cli/args.mjs';
|
|
5
|
+
import { printJson } from '../cli/output.mjs';
|
|
6
|
+
import { writeImageUxReviewRouteArtifacts } from '../core/image-ux-review.mjs';
|
|
7
|
+
import { finalizeRouteWithProof } from '../core/proof/route-finalizer.mjs';
|
|
8
|
+
|
|
9
|
+
export async function run(command, args = []) {
|
|
10
|
+
const root = await projectRoot();
|
|
11
|
+
const action = args[0] || 'status';
|
|
12
|
+
const missionArg = args[1] && !String(args[1]).startsWith('--') ? args[1] : 'latest';
|
|
13
|
+
const missionId = missionArg === 'latest' ? await findLatestMission(root) : missionArg;
|
|
14
|
+
if (!missionId) {
|
|
15
|
+
const result = { schema: 'sks.image-ux-review-status.v1', ok: false, status: 'missing_mission' };
|
|
16
|
+
if (flag(args, '--json')) return printJson(result);
|
|
17
|
+
console.error('No mission found.');
|
|
18
|
+
process.exitCode = 1;
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const { dir, mission } = await loadMission(root, missionId);
|
|
22
|
+
const contract = await readJson(path.join(dir, 'decision-contract.json'), { prompt: mission.prompt, answers: {}, sealed_hash: null });
|
|
23
|
+
if (action === 'build' || action === 'run' || (action === 'status' && flag(args, '--mock'))) {
|
|
24
|
+
const artifacts = await writeImageUxReviewRouteArtifacts(dir, contract);
|
|
25
|
+
const route = command === 'ux-review' ? '$UX-Review' : command === 'visual-review' ? '$Visual-Review' : command === 'ui-ux-review' ? '$UI-UX-Review' : '$Image-UX-Review';
|
|
26
|
+
const proof = await finalizeRouteWithProof(root, { missionId, route, mock: flag(args, '--mock'), artifacts: Object.keys(artifacts), claims: [{ id: 'image-ux-review-fixture', status: 'verified_partial' }] });
|
|
27
|
+
const result = { schema: 'sks.image-ux-review-build.v1', ok: proof.ok, mission_id: missionId, artifacts, proof: proof.validation };
|
|
28
|
+
if (flag(args, '--json')) return printJson(result);
|
|
29
|
+
console.log(`Image UX review: ${proof.ok ? 'ok' : 'blocked'} ${missionId}`);
|
|
30
|
+
if (!proof.ok) process.exitCode = 1;
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const gate = await readJson(path.join(dir, 'image-ux-review-gate.json'), null);
|
|
34
|
+
const result = { schema: 'sks.image-ux-review-status.v1', ok: true, mission_id: missionId, gate };
|
|
35
|
+
if (flag(args, '--json')) return printJson(result);
|
|
36
|
+
console.log(`Image UX Review mission: ${missionId}`);
|
|
37
|
+
console.log(`Gate: ${gate?.passed ? 'passed' : gate ? 'present' : 'missing'}`);
|
|
38
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { madHighCommand } from '../core/commands/route-cli.mjs';
|
|
2
|
+
import { maybePromptCodexUpdateForLaunch, maybePromptCodexLbSetupForLaunch } from '../cli/install-helpers.mjs';
|
|
3
|
+
import { PACKAGE_VERSION } from '../core/fsx.mjs';
|
|
4
|
+
|
|
5
|
+
export async function run(_command, args = []) {
|
|
6
|
+
return madHighCommand(['--mad-sks', ...args], {
|
|
7
|
+
maybePromptSksUpdateForLaunch: async () => ({ status: 'skipped' }),
|
|
8
|
+
maybePromptCodexUpdateForLaunch,
|
|
9
|
+
ensureMadLaunchDependencies: async () => ({ ready: true, actions: [], status: {} }),
|
|
10
|
+
printDepsInstallAction: (action) => console.log(JSON.stringify(action)),
|
|
11
|
+
maybePromptCodexLbSetupForLaunch,
|
|
12
|
+
packageVersion: PACKAGE_VERSION
|
|
13
|
+
});
|
|
14
|
+
}
|
package/src/commands/perf.mjs
CHANGED
|
@@ -25,8 +25,8 @@ export async function run(_command, args = []) {
|
|
|
25
25
|
if (!result.ok) process.exitCode = 1;
|
|
26
26
|
return;
|
|
27
27
|
}
|
|
28
|
-
const
|
|
29
|
-
return
|
|
28
|
+
const { perfCommand } = await import('../core/commands/route-cli.mjs');
|
|
29
|
+
return perfCommand(action, args.slice(1));
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
export function runColdStart({ root = process.cwd(), iterations = DEFAULT_COLD_START_ITERATIONS } = {}) {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { projectRoot, readJson } from '../core/fsx.mjs';
|
|
2
|
+
import { stateFile } from '../core/mission.mjs';
|
|
3
|
+
import { flag } from '../cli/args.mjs';
|
|
4
|
+
import { printJson } from '../cli/output.mjs';
|
|
5
|
+
import { projectGateStatus } from '../core/pipeline.mjs';
|
|
6
|
+
|
|
7
|
+
export async function run(_command, args = []) {
|
|
8
|
+
const root = await projectRoot();
|
|
9
|
+
const action = args[0] || 'status';
|
|
10
|
+
const state = await readJson(stateFile(root), {});
|
|
11
|
+
if (action === 'status') {
|
|
12
|
+
const result = { schema: 'sks.pipeline-status.v1', ok: true, state };
|
|
13
|
+
if (flag(args, '--json')) return printJson(result);
|
|
14
|
+
console.log(`Pipeline: ${state.mission_id || 'none'} ${state.route_command || state.mode || ''}`.trim());
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (action === 'plan') {
|
|
18
|
+
const result = await projectGateStatus(root, state);
|
|
19
|
+
if (flag(args, '--json')) return printJson(result);
|
|
20
|
+
console.log(`Pipeline gate: ${result.ok ? 'pass' : 'blocked'}`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
console.error('Usage: sks pipeline status|plan [--json]');
|
|
24
|
+
process.exitCode = 1;
|
|
25
|
+
}
|