sneakoscope 5.7.0 → 5.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/config/competitor-scorecard-baseline.json +97 -0
- package/config/perf-budgets.v1.json +10 -0
- 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/bin/sks.js +61 -1
- package/dist/cli/command-registry.js +2 -3
- package/dist/cli/commands-fast.js +20 -0
- package/dist/cli/root-fast.js +48 -0
- package/dist/cli/router.js +3 -0
- package/dist/cli/super-search-command.js +221 -0
- package/dist/cli/xai-command.js +7 -7
- package/dist/commands/doctor.js +56 -24
- package/dist/config/skills-manifest.json +63 -70
- package/dist/core/agents/agent-codex-cockpit.js +3 -3
- package/dist/core/agents/agent-orchestrator.js +20 -2
- package/dist/core/agents/agent-wrongness.js +1 -1
- package/dist/core/agents/native-cli-session-swarm.js +14 -1
- package/dist/core/agents/parallel-runtime-proof.js +82 -8
- package/dist/core/agents/parallel-write-fixture.js +301 -0
- package/dist/core/commands/gc-command.js +12 -6
- package/dist/core/commands/run-command.js +20 -18
- package/dist/core/doctor/doctor-idempotence.js +93 -0
- package/dist/core/errors/blocker-humanizer.js +13 -0
- package/dist/core/errors/next-action-map.js +56 -0
- package/dist/core/feature-fixtures.js +15 -8
- package/dist/core/fsx.js +1 -1
- package/dist/core/init/skills.js +1 -2
- package/dist/core/install/installed-package-smoke.js +121 -0
- package/dist/core/mission.js +41 -15
- package/dist/core/naruto/naruto-active-pool.js +6 -2
- package/dist/core/perf/perf-budget.js +145 -0
- package/dist/core/quality/competitor-scorecard.js +116 -0
- package/dist/core/release/gate-timing.js +103 -0
- package/dist/core/release-parallel-full-coverage.js +1 -1
- package/dist/core/retention/retention-budget.js +62 -0
- package/dist/core/retention.js +1 -1
- package/dist/core/routes/constants.js +2 -2
- package/dist/core/routes.js +155 -53
- package/dist/core/source-intelligence/source-intelligence-policy.js +5 -5
- package/dist/core/source-intelligence/source-intelligence-proof.js +8 -8
- package/dist/core/source-intelligence/source-intelligence-runner.js +16 -16
- package/dist/core/strategy/strategy-gate.js +2 -1
- package/dist/core/super-search/doctor.js +63 -0
- package/dist/core/super-search/runtime-helpers.js +289 -0
- package/dist/core/super-search/runtime.js +270 -0
- package/dist/core/super-search/source-records.js +96 -0
- package/dist/core/super-search/types.js +3 -0
- package/dist/core/trust-kernel/trust-report.js +3 -3
- package/dist/core/verification/real-evidence-policy.js +55 -0
- package/dist/core/version.js +1 -1
- package/dist/scripts/agent-fast-mode-default-check.js +10 -1
- package/dist/scripts/agent-visual-consistency-check.js +1 -1
- package/dist/scripts/check-architecture.js +0 -1
- package/dist/scripts/competitor-scorecard-check.js +25 -0
- package/dist/scripts/doctor-idempotence-check.js +8 -0
- package/dist/scripts/gate-timing-check.js +8 -0
- package/dist/scripts/hook-latency-quantum-check.js +122 -0
- package/dist/scripts/installed-package-smoke-check.js +12 -0
- package/dist/scripts/lib/native-cli-session-swarm-check-lib.js +2 -0
- package/dist/scripts/mutation-callsite-coverage-check.js +7 -0
- package/dist/scripts/package-published-contract-check.js +7 -0
- package/dist/scripts/packlist-performance-check.js +31 -3
- package/dist/scripts/parallel-production-smoke-check.js +21 -0
- package/dist/scripts/perf-budget-check.js +14 -0
- package/dist/scripts/quantum-baseline-report.js +38 -0
- package/dist/scripts/release-check-stamp.js +117 -16
- package/dist/scripts/release-metadata-1-19-check.js +2 -2
- package/dist/scripts/release-parallel-check.js +2 -2
- package/dist/scripts/release-parallel-full-coverage-check.js +1 -1
- package/dist/scripts/retention-budget-check.js +8 -0
- package/dist/scripts/route-intent-regression-check.js +44 -0
- package/dist/scripts/sks-1-18-gate-lib.js +2 -2
- package/dist/scripts/source-intelligence-all-modes-check.js +2 -2
- package/dist/scripts/source-intelligence-policy-check.js +1 -1
- package/dist/scripts/super-search-live-smoke-check.js +70 -0
- package/dist/scripts/super-search-name-guard-check.js +98 -0
- package/dist/scripts/super-search-offline-contract-check.js +45 -0
- package/dist/scripts/{ultra-search-provider-interface-check.js → super-search-provider-interface-check.js} +9 -9
- package/dist/scripts/trust-fixture-check.js +19 -6
- package/package.json +26 -8
- package/schemas/agents/parallel-runtime-proof.schema.json +17 -1
- package/dist/cli/insane-search-command.js +0 -195
- package/dist/core/ultra-search/runtime.js +0 -502
- package/dist/core/ultra-search/types.js +0 -3
- package/dist/scripts/release-readiness-report.js +0 -1262
- /package/dist/core/{ultra-search → super-search}/index.js +0 -0
|
@@ -146,7 +146,8 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
146
146
|
writeCapable,
|
|
147
147
|
visualRequired,
|
|
148
148
|
appshotsOk: sourceIntelligence.appshots?.ok === true,
|
|
149
|
-
sourceIntelligenceOk: sourceIntelligence.ok
|
|
149
|
+
sourceIntelligenceOk: sourceIntelligence.ok,
|
|
150
|
+
sourceIntelligenceRequired: sourceIntelligenceRequiredForWriteGate(sourceIntelligence, route)
|
|
150
151
|
});
|
|
151
152
|
await writeStrategyGateArtifact(dir, strategyGate);
|
|
152
153
|
const strategyRef = {
|
|
@@ -499,7 +500,9 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
499
500
|
minActiveWorkers: Math.min(targetActiveSlots, desiredWorkItemCount),
|
|
500
501
|
...(backend === 'codex-sdk' && opts.real === true ? { minSpeedupRatio: 3 } : {}),
|
|
501
502
|
proofMode: opts.mock === true ? 'mock-process' : 'production',
|
|
502
|
-
requireWorkerPids: opts.nativeCliSwarm !== false && targetActiveSlots >= 16
|
|
503
|
+
requireWorkerPids: opts.nativeCliSwarm !== false && targetActiveSlots >= 16,
|
|
504
|
+
requireChangedFiles: writeCapable && effectiveWriteMode === 'parallel',
|
|
505
|
+
minChangedFiles: Math.min(2, desiredWorkItemCount)
|
|
503
506
|
});
|
|
504
507
|
let results = scheduler.results;
|
|
505
508
|
const tournamentSelection = await selectSolutionTournamentWinners(root, ledgerRoot, results);
|
|
@@ -687,6 +690,21 @@ function normalizeMissionHardTimeoutMs(opts = {}, route = '') {
|
|
|
687
690
|
return Math.max(1000, Math.min(Math.floor(raw), 24 * 60 * 60 * 1000));
|
|
688
691
|
return String(route || '').replace(/^\$/, '').toUpperCase() === 'NARUTO' ? 10 * 60 * 1000 : 30 * 60 * 1000;
|
|
689
692
|
}
|
|
693
|
+
function sourceIntelligenceRequiredForWriteGate(sourceIntelligence, route) {
|
|
694
|
+
const policy = sourceIntelligence?.policy || {};
|
|
695
|
+
const mode = String(sourceIntelligence?.mode || policy.mode || '');
|
|
696
|
+
if (String(route || '').replace(/^\$/, '').toLowerCase() === 'super-search')
|
|
697
|
+
return true;
|
|
698
|
+
if (policy.context7?.required === true)
|
|
699
|
+
return true;
|
|
700
|
+
if (policy.requirements?.official_sources === true)
|
|
701
|
+
return true;
|
|
702
|
+
if (policy.requirements?.social_recency === true)
|
|
703
|
+
return true;
|
|
704
|
+
if (policy.requirements?.code_execution_verification === true && mode !== 'offline_cache')
|
|
705
|
+
return true;
|
|
706
|
+
return mode !== 'offline_cache';
|
|
707
|
+
}
|
|
690
708
|
function withFinalGptPatchEnvelopes(results, patchEnvelopes = []) {
|
|
691
709
|
const byAgent = new Map();
|
|
692
710
|
for (const envelope of patchEnvelopes) {
|
|
@@ -11,7 +11,7 @@ const WRONGNESS_MAP = [
|
|
|
11
11
|
['missing_follow_up_schema', /follow_up_work_item|follow_up_work_items|schema_invalid:.*follow_up/],
|
|
12
12
|
['session_generation_missing', /session_generation_open|terminal_close_report_missing|source_intelligence_missing_for_generation|goal_mode_missing_for_generation/],
|
|
13
13
|
['schema_invalid_output', /^schema_invalid:/],
|
|
14
|
-
['
|
|
14
|
+
['super_search_provider_independent_proof_missing', /super_search_provider_independent_proof_missing/],
|
|
15
15
|
['codex_web_search_missing', /codex_web_search_missing/],
|
|
16
16
|
['context7_missing', /context7_missing|docs_context_missing/],
|
|
17
17
|
['stale_heartbeat', /stale_heartbeat/],
|
|
@@ -274,6 +274,7 @@ class NativeCliSessionSwarmRecorder {
|
|
|
274
274
|
status: result.status === 'done' ? 'completed' : 'failed',
|
|
275
275
|
artifacts: result.artifacts || [],
|
|
276
276
|
blockers: result.blockers || [],
|
|
277
|
+
changedFiles: changedFilesFromWorkerResult(result),
|
|
277
278
|
logTail: result.summary || ''
|
|
278
279
|
});
|
|
279
280
|
await this.record(record);
|
|
@@ -649,6 +650,7 @@ class NativeCliSessionSwarmRecorder {
|
|
|
649
650
|
status: parsed.status === 'done' ? 'completed' : 'failed',
|
|
650
651
|
artifacts: [...new Set([...(Array.isArray(parsed.artifacts) ? parsed.artifacts : []), input.stdoutRel, input.stderrRel, path.join(input.workerDirRel, 'zellij-worker-pane.json')])],
|
|
651
652
|
blockers: input.record.blockers,
|
|
653
|
+
changedFiles: changedFilesFromWorkerResult(parsed),
|
|
652
654
|
logTail: parsed.summary || ''
|
|
653
655
|
});
|
|
654
656
|
return validateAgentWorkerResult({
|
|
@@ -752,6 +754,7 @@ class NativeCliSessionSwarmRecorder {
|
|
|
752
754
|
meta: {
|
|
753
755
|
status: input.status,
|
|
754
756
|
artifacts: input.artifacts || [],
|
|
757
|
+
changed_files: input.changedFiles || [],
|
|
755
758
|
blockers: input.blockers || []
|
|
756
759
|
}
|
|
757
760
|
}).catch(() => undefined);
|
|
@@ -956,9 +959,19 @@ function mapTelemetryToParallelEvent(eventType) {
|
|
|
956
959
|
return 'worker_failed';
|
|
957
960
|
return null;
|
|
958
961
|
}
|
|
962
|
+
function changedFilesFromWorkerResult(result) {
|
|
963
|
+
const direct = Array.isArray(result?.changed_files) ? result.changed_files : [];
|
|
964
|
+
const envelopeFiles = (Array.isArray(result?.patch_envelopes) ? result.patch_envelopes : [])
|
|
965
|
+
.flatMap((envelope) => [
|
|
966
|
+
...(Array.isArray(envelope?.changed_files) ? envelope.changed_files : []),
|
|
967
|
+
...(Array.isArray(envelope?.allowed_paths) ? envelope.allowed_paths : []),
|
|
968
|
+
...(Array.isArray(envelope?.operations) ? envelope.operations.map((operation) => operation?.path) : [])
|
|
969
|
+
]);
|
|
970
|
+
return [...new Set([...direct, ...envelopeFiles].map((file) => String(file || '').replace(/\\/g, '/').replace(/^\.\/+/, '')).filter(Boolean))];
|
|
971
|
+
}
|
|
959
972
|
function normalizeParallelPlacement(value) {
|
|
960
973
|
const text = String(value || '');
|
|
961
|
-
if (text === 'zellij-pane' || text === 'process' || text === 'headless')
|
|
974
|
+
if (text === 'zellij-pane' || text === 'process' || text === 'headless' || text === 'headless_by_design_viewport_ui')
|
|
962
975
|
return text;
|
|
963
976
|
return 'unknown';
|
|
964
977
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { appendJsonlBounded, ensureDir, nowIso, readJson, readText, writeJsonAtomic } from '../fsx.js';
|
|
3
3
|
export const PARALLEL_RUNTIME_EVENT_SCHEMA = 'sks.parallel-runtime-event.v1';
|
|
4
|
-
export const PARALLEL_RUNTIME_PROOF_SCHEMA = 'sks.parallel-runtime-proof.
|
|
4
|
+
export const PARALLEL_RUNTIME_PROOF_SCHEMA = 'sks.parallel-runtime-proof.v2';
|
|
5
5
|
export function parallelRuntimeEventPath(root, missionId) {
|
|
6
6
|
return path.join(inferAgentsDir(root, missionId), 'parallel-runtime.events.jsonl');
|
|
7
7
|
}
|
|
@@ -100,7 +100,7 @@ export async function buildParallelRuntimeProof(root, missionId, opts = {}) {
|
|
|
100
100
|
? workerDurations.reduce((sum, value) => sum + value, 0)
|
|
101
101
|
: requestedWorkers * positiveInt(opts.expectedWorkerRuntimeMs, 4000);
|
|
102
102
|
const visiblePanes = nonNegativeInt(opts.visiblePanes, sorted.filter((event) => event.placement === 'zellij-pane').length ? new Set(sorted.filter((event) => event.placement === 'zellij-pane').map((event) => event.slot_id || event.session_id || '')).size : 0);
|
|
103
|
-
const observedHeadlessWorkers = sorted.filter((event) => event.placement === 'headless' && (event.event_type === 'worker_launch_invoked' || event.event_type === 'worker_process_spawned')).length;
|
|
103
|
+
const observedHeadlessWorkers = sorted.filter((event) => (event.placement === 'headless' || event.placement === 'headless_by_design_viewport_ui') && (event.event_type === 'worker_launch_invoked' || event.event_type === 'worker_process_spawned')).length;
|
|
104
104
|
const headlessWorkers = Math.max(observedHeadlessWorkers, Math.max(0, targetActiveSlots - visiblePanes));
|
|
105
105
|
const minActiveWorkers = opts.minActiveWorkers === undefined
|
|
106
106
|
? Math.min(targetActiveSlots, requestedWorkers)
|
|
@@ -112,6 +112,7 @@ export async function buildParallelRuntimeProof(root, missionId, opts = {}) {
|
|
|
112
112
|
const firstBatchLimit = positiveInt(opts.firstBatchLaunchSpanLimitMs, requestedWorkers >= 16 ? 2500 : 30000);
|
|
113
113
|
const schedulerState = await readJson(path.join(root, 'agent-scheduler-state.json'), null).catch(() => null);
|
|
114
114
|
const coalescedOverlapWindows = coalesceOverlapWindows(overlapWindows);
|
|
115
|
+
const workerEvidence = buildWorkerRuntimeEvidence(sorted, firstMs, lastMs);
|
|
115
116
|
const utilizationProofConsistency = buildUtilizationProofConsistency(schedulerState, {
|
|
116
117
|
proofMaxActive: maxWorkers,
|
|
117
118
|
proofWallMs: wallMs,
|
|
@@ -130,15 +131,27 @@ export async function buildParallelRuntimeProof(root, missionId, opts = {}) {
|
|
|
130
131
|
blockers.push('speedup_ratio_below_target');
|
|
131
132
|
if (firstBatchLaunchSpanMs > firstBatchLimit)
|
|
132
133
|
blockers.push('first_batch_launch_span_above_limit');
|
|
134
|
+
if (minActiveWorkers > 1 && workerEvidence.unique_worker_ids.length < Math.min(minActiveWorkers, 2))
|
|
135
|
+
blockers.push('worker_id_diversity_below_target');
|
|
136
|
+
if (minActiveWorkers > 1 && workerEvidence.overlap_windows.length === 0)
|
|
137
|
+
blockers.push('worker_timestamp_overlap_missing');
|
|
138
|
+
if (opts.requireChangedFiles === true && workerEvidence.changed_file_count < positiveInt(opts.minChangedFiles, Math.min(2, requestedWorkers)))
|
|
139
|
+
blockers.push('parallel_write_changed_files_below_target');
|
|
140
|
+
const passed = blockers.length === 0;
|
|
133
141
|
return {
|
|
134
142
|
schema: PARALLEL_RUNTIME_PROOF_SCHEMA,
|
|
135
143
|
mission_id: missionId,
|
|
136
144
|
generated_at: nowIso(),
|
|
145
|
+
ok: passed,
|
|
137
146
|
proof_mode: proofMode,
|
|
147
|
+
production_runtime: proofMode === 'production',
|
|
148
|
+
mock_only: proofMode !== 'production',
|
|
138
149
|
require_worker_pids: requireWorkerPids,
|
|
139
150
|
allow_missing_pids: allowMissingPids,
|
|
140
151
|
requested_workers: requestedWorkers,
|
|
141
152
|
target_active_slots: targetActiveSlots,
|
|
153
|
+
observed_worker_count: workerEvidence.unique_worker_ids.length,
|
|
154
|
+
unique_worker_ids: workerEvidence.unique_worker_ids,
|
|
142
155
|
max_observed_active_workers: maxWorkers,
|
|
143
156
|
max_observed_worker_processes: Math.max(maxProcesses, workerPids.size ? maxProcesses : maxWorkers),
|
|
144
157
|
unique_worker_pids: workerPids.size,
|
|
@@ -149,11 +162,13 @@ export async function buildParallelRuntimeProof(root, missionId, opts = {}) {
|
|
|
149
162
|
wall_ms: wallMs,
|
|
150
163
|
sequential_estimate_ms: sequentialEstimateMs,
|
|
151
164
|
speedup_ratio: speedupRatio,
|
|
152
|
-
overlap_windows: coalescedOverlapWindows,
|
|
165
|
+
overlap_windows: [...coalescedOverlapWindows, ...workerEvidence.overlap_windows],
|
|
166
|
+
changed_file_count: workerEvidence.changed_file_count,
|
|
167
|
+
changed_files_by_worker: workerEvidence.changed_files_by_worker,
|
|
153
168
|
visible_panes: visiblePanes,
|
|
154
169
|
headless_workers: headlessWorkers,
|
|
155
170
|
utilization_proof_consistency: utilizationProofConsistency,
|
|
156
|
-
passed
|
|
171
|
+
passed,
|
|
157
172
|
blockers
|
|
158
173
|
};
|
|
159
174
|
}
|
|
@@ -200,7 +215,7 @@ function normalizeParallelRuntimeEvent(missionId, event) {
|
|
|
200
215
|
}
|
|
201
216
|
function normalizePlacement(value) {
|
|
202
217
|
const text = String(value || 'unknown');
|
|
203
|
-
if (text === 'zellij-pane' || text === 'process' || text === 'headless')
|
|
218
|
+
if (text === 'zellij-pane' || text === 'process' || text === 'headless' || text === 'headless_by_design_viewport_ui')
|
|
204
219
|
return text;
|
|
205
220
|
return 'unknown';
|
|
206
221
|
}
|
|
@@ -253,14 +268,73 @@ function buildUtilizationProofConsistency(state, input) {
|
|
|
253
268
|
};
|
|
254
269
|
}
|
|
255
270
|
function activeSlotTimeMsFromWindows(windows) {
|
|
256
|
-
return windows.reduce((sum, window) => sum + Math.max(0, window.end_ms - window.start_ms) * Math.max(0, window.active_workers), 0);
|
|
271
|
+
return windows.reduce((sum, window) => sum + Math.max(0, Number(window.end_ms || 0) - Number(window.start_ms || 0)) * Math.max(0, Number(window.active_workers || 0)), 0);
|
|
257
272
|
}
|
|
258
273
|
function coalesceOverlapWindows(windows) {
|
|
259
274
|
return windows
|
|
260
|
-
.filter((window) => window.end_ms > window.start_ms)
|
|
261
|
-
.filter((window) => window.active_workers > 0 || window.active_model_calls > 0)
|
|
275
|
+
.filter((window) => Number(window.end_ms || 0) > Number(window.start_ms || 0))
|
|
276
|
+
.filter((window) => Number(window.active_workers || 0) > 0 || Number(window.active_model_calls || 0) > 0)
|
|
262
277
|
.slice(0, 2000);
|
|
263
278
|
}
|
|
279
|
+
function buildWorkerRuntimeEvidence(events, firstMs, lastMs) {
|
|
280
|
+
const intervals = new Map();
|
|
281
|
+
for (const event of events) {
|
|
282
|
+
const workerId = workerRuntimeId(event);
|
|
283
|
+
if (!workerId)
|
|
284
|
+
continue;
|
|
285
|
+
if (event.event_type === 'worker_launch_invoked' || event.event_type === 'worker_process_spawned') {
|
|
286
|
+
const current = intervals.get(workerId);
|
|
287
|
+
if (current)
|
|
288
|
+
current.start = Math.min(current.start, event.ms);
|
|
289
|
+
else
|
|
290
|
+
intervals.set(workerId, { start: event.ms, end: event.ms, changedFiles: new Set() });
|
|
291
|
+
}
|
|
292
|
+
if (event.event_type === 'worker_completed' || event.event_type === 'worker_failed') {
|
|
293
|
+
const current = intervals.get(workerId) || { start: event.ms, end: event.ms, changedFiles: new Set() };
|
|
294
|
+
current.end = event.ms;
|
|
295
|
+
for (const file of eventChangedFiles(event))
|
|
296
|
+
current.changedFiles.add(file);
|
|
297
|
+
intervals.set(workerId, current);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
const uniqueWorkerIds = [...intervals.keys()].sort();
|
|
301
|
+
const changedFilesByWorker = Object.fromEntries(uniqueWorkerIds.map((id) => [id, [...(intervals.get(id)?.changedFiles || new Set())].sort()]));
|
|
302
|
+
const changedFileCount = new Set(Object.values(changedFilesByWorker).flat()).size;
|
|
303
|
+
const overlapWindows = [];
|
|
304
|
+
for (let i = 0; i < uniqueWorkerIds.length; i++) {
|
|
305
|
+
for (let j = i + 1; j < uniqueWorkerIds.length; j++) {
|
|
306
|
+
const a = uniqueWorkerIds[i];
|
|
307
|
+
const b = uniqueWorkerIds[j];
|
|
308
|
+
const left = intervals.get(a);
|
|
309
|
+
const right = intervals.get(b);
|
|
310
|
+
const overlapMs = Math.max(0, Math.min(left.end, right.end) - Math.max(left.start, right.start));
|
|
311
|
+
if (overlapMs > 0 && Math.max(left.start, right.start) < Math.min(left.end, right.end)) {
|
|
312
|
+
overlapWindows.push({
|
|
313
|
+
worker_a: a,
|
|
314
|
+
worker_b: b,
|
|
315
|
+
overlap_ms: overlapMs,
|
|
316
|
+
start_ms: Math.max(left.start, right.start) - firstMs,
|
|
317
|
+
end_ms: Math.min(left.end, right.end) - firstMs,
|
|
318
|
+
active_workers: 2,
|
|
319
|
+
active_model_calls: 0
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return {
|
|
325
|
+
unique_worker_ids: uniqueWorkerIds,
|
|
326
|
+
changed_files_by_worker: changedFilesByWorker,
|
|
327
|
+
changed_file_count: changedFileCount,
|
|
328
|
+
overlap_windows: overlapWindows.slice(0, 2000)
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
function workerRuntimeId(event) {
|
|
332
|
+
return event.slot_id || event.session_id || (event.pid == null ? null : `pid:${event.pid}`);
|
|
333
|
+
}
|
|
334
|
+
function eventChangedFiles(event) {
|
|
335
|
+
const fromMeta = Array.isArray(event.meta?.changed_files) ? event.meta.changed_files : [];
|
|
336
|
+
return fromMeta.map((file) => String(file || '').replace(/\\/g, '/').replace(/^\.\/+/, '')).filter(Boolean);
|
|
337
|
+
}
|
|
264
338
|
function inferAgentsDir(root, missionId) {
|
|
265
339
|
const resolved = path.resolve(root);
|
|
266
340
|
if (path.basename(resolved) === 'agents' && path.basename(path.dirname(resolved)) === missionId)
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import fsp from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
6
|
+
const execFileAsync = promisify(execFile);
|
|
7
|
+
export const PARALLEL_PRODUCTION_SMOKE_SCHEMA = 'sks.parallel-production-smoke.v1';
|
|
8
|
+
export async function runParallelProductionSmoke(options = {}) {
|
|
9
|
+
const tmpRoot = await fsp.mkdtemp(path.join(os.tmpdir(), 'sks-parallel-production-smoke-'));
|
|
10
|
+
const repoRoot = path.join(tmpRoot, 'tmp-repo');
|
|
11
|
+
const worktreesRoot = path.join(tmpRoot, 'worktrees');
|
|
12
|
+
const blockers = [];
|
|
13
|
+
let cleanup = null;
|
|
14
|
+
try {
|
|
15
|
+
await createFixtureRepo(repoRoot);
|
|
16
|
+
await fsp.mkdir(worktreesRoot, { recursive: true });
|
|
17
|
+
const workerSpecs = buildWorkerSpecs(options.injectFailure === true);
|
|
18
|
+
await Promise.all(workerSpecs.map((worker) => setupWorkerWorktree(repoRoot, worktreesRoot, worker)));
|
|
19
|
+
const workerResults = await Promise.all(workerSpecs.map((worker) => runWorker(worker, path.join(worktreesRoot, worker.id))));
|
|
20
|
+
const successfulWorkers = workerResults.filter((result) => result.ok);
|
|
21
|
+
const failedWorkers = workerResults.filter((result) => !result.ok);
|
|
22
|
+
const targetFiles = ['src/a.ts', 'src/b.ts', 'src/c.ts'];
|
|
23
|
+
await mergeWorkerOutputs(repoRoot, successfulWorkers);
|
|
24
|
+
const typecheck = await runTypecheck(repoRoot);
|
|
25
|
+
const sharedUntouched = await fileEquals(path.join(repoRoot, 'src', 'shared.ts'), "export const sharedValue = 'stable-shared-contract'\n");
|
|
26
|
+
const statusAfterMerge = (await runCommand(['git', 'status', '--short'], repoRoot)).stdout_tail.trim();
|
|
27
|
+
const parentMergeArtifact = {
|
|
28
|
+
schema: 'sks.parallel-production-parent-merge.v1',
|
|
29
|
+
ok: successfulWorkers.length >= 3 && targetFiles.every((file) => successfulWorkers.some((worker) => worker.changed_files.includes(file))) && sharedUntouched,
|
|
30
|
+
merged_files: Array.from(new Set(successfulWorkers.flatMap((worker) => worker.changed_files))).sort(),
|
|
31
|
+
shared_untouched: sharedUntouched,
|
|
32
|
+
git_status_after_merge: statusAfterMerge
|
|
33
|
+
};
|
|
34
|
+
if (parentMergeArtifact.ok) {
|
|
35
|
+
await runCommand(['git', 'add', ...parentMergeArtifact.merged_files], repoRoot, true);
|
|
36
|
+
await runCommand(['git', 'commit', '-m', 'parent merge parallel worker outputs'], repoRoot, true);
|
|
37
|
+
}
|
|
38
|
+
const changedFilesByWorker = Object.fromEntries(successfulWorkers.map((worker) => [worker.worker_id, worker.changed_files]));
|
|
39
|
+
const changedFiles = Array.from(new Set(successfulWorkers.flatMap((worker) => worker.changed_files))).sort();
|
|
40
|
+
const overlapWindows = buildOverlapWindows(workerResults);
|
|
41
|
+
const cleanupBefore = await runCommand(['git', 'worktree', 'list', '--porcelain'], repoRoot);
|
|
42
|
+
cleanup = await cleanupWorktreesAndBranches(repoRoot, tmpRoot, workerSpecs, cleanupBefore.stdout_tail, options.keepTmp === true);
|
|
43
|
+
if (workerSpecs.filter((worker) => !worker.fail).length < 3)
|
|
44
|
+
blockers.push('parallel_write_worker_target_below_three');
|
|
45
|
+
if (successfulWorkers.length < 3)
|
|
46
|
+
blockers.push('parallel_write_successful_workers_below_target');
|
|
47
|
+
if (changedFiles.length < 3)
|
|
48
|
+
blockers.push('parallel_write_changed_files_below_target');
|
|
49
|
+
if (!targetFiles.every((file) => changedFiles.includes(file)))
|
|
50
|
+
blockers.push('parallel_write_target_files_missing');
|
|
51
|
+
if (new Set(Object.entries(changedFilesByWorker).filter(([, files]) => files.some((file) => targetFiles.includes(file))).map(([workerId]) => workerId)).size < 2)
|
|
52
|
+
blockers.push('parallel_write_files_not_distributed');
|
|
53
|
+
if (overlapWindows.length === 0)
|
|
54
|
+
blockers.push('worker_timestamp_overlap_missing');
|
|
55
|
+
if (successfulWorkers.filter((worker) => worker.patch.trim()).length < 3)
|
|
56
|
+
blockers.push('patch_envelope_count_below_target');
|
|
57
|
+
if (!parentMergeArtifact.ok)
|
|
58
|
+
blockers.push('parent_merge_artifact_missing_or_invalid');
|
|
59
|
+
if (!typecheck.ok)
|
|
60
|
+
blockers.push('typecheck_failed');
|
|
61
|
+
if (!cleanup.ok)
|
|
62
|
+
blockers.push('worktree_cleanup_failed');
|
|
63
|
+
if (failedWorkers.length > 0 && successfulWorkers.length === 0)
|
|
64
|
+
blockers.push('failure_injection_killed_scheduler');
|
|
65
|
+
return {
|
|
66
|
+
schema: PARALLEL_PRODUCTION_SMOKE_SCHEMA,
|
|
67
|
+
ok: blockers.length === 0,
|
|
68
|
+
status: blockers.length === 0 ? 'passed' : 'blocked',
|
|
69
|
+
proof_level: blockers.length === 0 ? 'production_git_worktree_fixture' : 'blocked',
|
|
70
|
+
tmp_root: tmpRoot,
|
|
71
|
+
repo_root: repoRoot,
|
|
72
|
+
worker_count: successfulWorkers.length,
|
|
73
|
+
worker_ids: successfulWorkers.map((worker) => worker.worker_id).sort(),
|
|
74
|
+
changed_files: changedFiles,
|
|
75
|
+
changed_files_by_worker: changedFilesByWorker,
|
|
76
|
+
distributed_across_workers: new Set(Object.keys(changedFilesByWorker)).size >= 2,
|
|
77
|
+
timestamp_overlap: overlapWindows.length > 0,
|
|
78
|
+
overlap_windows: overlapWindows,
|
|
79
|
+
patch_envelope_count: successfulWorkers.filter((worker) => worker.patch.trim()).length,
|
|
80
|
+
parent_merge_artifact: parentMergeArtifact,
|
|
81
|
+
typecheck,
|
|
82
|
+
worktree_cleanup: cleanup,
|
|
83
|
+
failure_injection: {
|
|
84
|
+
requested: options.injectFailure === true,
|
|
85
|
+
worker_failure_seen: failedWorkers.length > 0,
|
|
86
|
+
reassignment_attempted: failedWorkers.length > 0,
|
|
87
|
+
survived_worker_failure: failedWorkers.length > 0 ? successfulWorkers.length >= 3 : true,
|
|
88
|
+
failed_worker_id: failedWorkers[0]?.worker_id ?? null,
|
|
89
|
+
failed_worker_ids: failedWorkers.map((worker) => worker.worker_id).sort(),
|
|
90
|
+
recovered_work_item_ids: failedWorkers.length > 0 ? successfulWorkers.flatMap((worker) => worker.changed_files).sort() : [],
|
|
91
|
+
scheduler_survived: successfulWorkers.length >= 3,
|
|
92
|
+
successful_workers: successfulWorkers.map((worker) => worker.worker_id).sort(),
|
|
93
|
+
failed_workers: failedWorkers.map((worker) => worker.worker_id).sort()
|
|
94
|
+
},
|
|
95
|
+
mock_only: false,
|
|
96
|
+
blockers
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
blockers.push(error instanceof Error ? `unexpected_error:${error.message}` : 'unexpected_error');
|
|
101
|
+
cleanup ??= await bestEffortCleanup(repoRoot, tmpRoot, options.keepTmp === true);
|
|
102
|
+
return blockedReport(tmpRoot, repoRoot, cleanup, blockers);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async function createFixtureRepo(repoRoot) {
|
|
106
|
+
await fsp.mkdir(path.join(repoRoot, 'src'), { recursive: true });
|
|
107
|
+
await fsp.writeFile(path.join(repoRoot, 'package.json'), `${JSON.stringify({ type: 'module', scripts: { typecheck: 'tsc -p tsconfig.json --noEmit' }, devDependencies: {} }, null, 2)}\n`);
|
|
108
|
+
await fsp.writeFile(path.join(repoRoot, 'tsconfig.json'), `${JSON.stringify({ compilerOptions: { target: 'ES2022', module: 'NodeNext', moduleResolution: 'NodeNext', strict: true, noEmit: true }, include: ['src/**/*.ts'] }, null, 2)}\n`);
|
|
109
|
+
await fsp.writeFile(path.join(repoRoot, 'src', 'shared.ts'), "export const sharedValue = 'stable-shared-contract'\n");
|
|
110
|
+
await fsp.writeFile(path.join(repoRoot, 'src', 'a.ts'), "import { sharedValue } from './shared.js'\nexport const aValue = `a:${sharedValue}`\n");
|
|
111
|
+
await fsp.writeFile(path.join(repoRoot, 'src', 'b.ts'), "import { sharedValue } from './shared.js'\nexport const bValue = `b:${sharedValue}`\n");
|
|
112
|
+
await fsp.writeFile(path.join(repoRoot, 'src', 'c.ts'), "import { sharedValue } from './shared.js'\nexport const cValue = `c:${sharedValue}`\n");
|
|
113
|
+
await runCommand(['git', 'init', '--initial-branch', 'main'], repoRoot, true);
|
|
114
|
+
await runCommand(['git', 'config', 'user.email', 'parallel-smoke@example.invalid'], repoRoot, true);
|
|
115
|
+
await runCommand(['git', 'config', 'user.name', 'Parallel Smoke'], repoRoot, true);
|
|
116
|
+
await runCommand(['git', 'add', '.'], repoRoot, true);
|
|
117
|
+
await runCommand(['git', 'commit', '-m', 'initial fixture'], repoRoot, true);
|
|
118
|
+
}
|
|
119
|
+
function buildWorkerSpecs(injectFailure) {
|
|
120
|
+
const workers = [
|
|
121
|
+
{ id: 'worker-a', branch: 'worker/parallel-a', file: 'src/a.ts', exportName: 'workerADeterministic', returnValue: 'alpha' },
|
|
122
|
+
{ id: 'worker-b', branch: 'worker/parallel-b', file: 'src/b.ts', exportName: 'workerBDeterministic', returnValue: 'bravo' },
|
|
123
|
+
{ id: 'worker-c', branch: 'worker/parallel-c', file: 'src/c.ts', exportName: 'workerCDeterministic', returnValue: 'charlie' }
|
|
124
|
+
];
|
|
125
|
+
if (injectFailure) {
|
|
126
|
+
workers.push({ id: 'worker-fail', branch: 'worker/parallel-fail', file: 'src/shared.ts', exportName: 'shouldNotLand', returnValue: 'failed', fail: true });
|
|
127
|
+
}
|
|
128
|
+
return workers;
|
|
129
|
+
}
|
|
130
|
+
async function setupWorkerWorktree(repoRoot, worktreesRoot, worker) {
|
|
131
|
+
await runCommand(['git', 'worktree', 'add', '-b', worker.branch, path.join(worktreesRoot, worker.id), 'HEAD'], repoRoot, true);
|
|
132
|
+
}
|
|
133
|
+
async function runWorker(worker, worktree) {
|
|
134
|
+
const startedMs = Date.now();
|
|
135
|
+
await delay(25);
|
|
136
|
+
if (worker.fail) {
|
|
137
|
+
return {
|
|
138
|
+
worker_id: worker.id,
|
|
139
|
+
ok: false,
|
|
140
|
+
branch: worker.branch,
|
|
141
|
+
worktree,
|
|
142
|
+
changed_files: [],
|
|
143
|
+
patch: '',
|
|
144
|
+
started_ms: startedMs,
|
|
145
|
+
completed_ms: Date.now(),
|
|
146
|
+
blocker: 'injected_worker_failure'
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
const filePath = path.join(worktree, worker.file);
|
|
150
|
+
const original = await fsp.readFile(filePath, 'utf8');
|
|
151
|
+
await fsp.writeFile(filePath, `${original}\nexport function ${worker.exportName}(): string {\n return '${worker.returnValue}'\n}\n`);
|
|
152
|
+
await runCommand(['git', 'add', worker.file], worktree, true);
|
|
153
|
+
await runCommand(['git', 'commit', '-m', `${worker.id} deterministic function`], worktree, true);
|
|
154
|
+
const diff = await runCommand(['git', 'diff', 'HEAD~1', 'HEAD', '--', worker.file], worktree, true);
|
|
155
|
+
return {
|
|
156
|
+
worker_id: worker.id,
|
|
157
|
+
ok: true,
|
|
158
|
+
branch: worker.branch,
|
|
159
|
+
worktree,
|
|
160
|
+
changed_files: [worker.file],
|
|
161
|
+
patch: diff.stdout_tail,
|
|
162
|
+
started_ms: startedMs,
|
|
163
|
+
completed_ms: Date.now()
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
async function mergeWorkerOutputs(repoRoot, workers) {
|
|
167
|
+
for (const worker of workers) {
|
|
168
|
+
for (const file of worker.changed_files) {
|
|
169
|
+
await fsp.copyFile(path.join(worker.worktree, file), path.join(repoRoot, file));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async function runTypecheck(repoRoot) {
|
|
174
|
+
const localTsc = path.join(process.cwd(), 'node_modules', '.bin', process.platform === 'win32' ? 'tsc.cmd' : 'tsc');
|
|
175
|
+
return runCommand([localTsc, '-p', 'tsconfig.json', '--noEmit'], repoRoot);
|
|
176
|
+
}
|
|
177
|
+
async function cleanupWorktreesAndBranches(repoRoot, tmpRoot, workers, before, keepTmp) {
|
|
178
|
+
for (const worker of workers) {
|
|
179
|
+
await runCommand(['git', 'worktree', 'remove', '--force', path.join(tmpRoot, 'worktrees', worker.id)], repoRoot);
|
|
180
|
+
}
|
|
181
|
+
await runCommand(['git', 'worktree', 'prune'], repoRoot);
|
|
182
|
+
for (const worker of workers) {
|
|
183
|
+
await runCommand(['git', 'branch', '-D', worker.branch], repoRoot);
|
|
184
|
+
}
|
|
185
|
+
const after = await runCommand(['git', 'worktree', 'list', '--porcelain'], repoRoot);
|
|
186
|
+
const status = await runCommand(['git', 'status', '--short'], repoRoot);
|
|
187
|
+
if (!keepTmp)
|
|
188
|
+
await fsp.rm(tmpRoot, { recursive: true, force: true });
|
|
189
|
+
const tmpRemoved = keepTmp ? false : !(await exists(tmpRoot));
|
|
190
|
+
return {
|
|
191
|
+
ok: workers.every((worker) => !after.stdout_tail.includes(worker.id) && !after.stdout_tail.includes(worker.branch)) && status.stdout_tail.trim().length === 0 && tmpRemoved,
|
|
192
|
+
worktree_list_before_cleanup: before,
|
|
193
|
+
worktree_list_after_cleanup: after.stdout_tail,
|
|
194
|
+
worker_worktrees_removed: workers.every((worker) => !after.stdout_tail.includes(worker.id)),
|
|
195
|
+
worker_branches_removed: workers.every((worker) => !after.stdout_tail.includes(worker.branch)),
|
|
196
|
+
parent_dirty_after_cleanup: status.stdout_tail.trim().length > 0,
|
|
197
|
+
tmp_removed: tmpRemoved
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
async function bestEffortCleanup(repoRoot, tmpRoot, keepTmp) {
|
|
201
|
+
const before = await runCommand(['git', 'worktree', 'list', '--porcelain'], repoRoot);
|
|
202
|
+
if (!keepTmp)
|
|
203
|
+
await fsp.rm(tmpRoot, { recursive: true, force: true });
|
|
204
|
+
return {
|
|
205
|
+
ok: !keepTmp && !(await exists(tmpRoot)),
|
|
206
|
+
worktree_list_before_cleanup: before.stdout_tail,
|
|
207
|
+
worktree_list_after_cleanup: '',
|
|
208
|
+
worker_worktrees_removed: true,
|
|
209
|
+
worker_branches_removed: false,
|
|
210
|
+
parent_dirty_after_cleanup: false,
|
|
211
|
+
tmp_removed: !keepTmp && !(await exists(tmpRoot))
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function buildOverlapWindows(results) {
|
|
215
|
+
const windows = [];
|
|
216
|
+
for (let i = 0; i < results.length; i += 1) {
|
|
217
|
+
for (let j = i + 1; j < results.length; j += 1) {
|
|
218
|
+
const a = results[i];
|
|
219
|
+
const b = results[j];
|
|
220
|
+
if (!a || !b)
|
|
221
|
+
continue;
|
|
222
|
+
const overlap = Math.min(a.completed_ms, b.completed_ms) - Math.max(a.started_ms, b.started_ms);
|
|
223
|
+
if (overlap > 0)
|
|
224
|
+
windows.push({ worker_a: a.worker_id, worker_b: b.worker_id, overlap_ms: overlap });
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return windows;
|
|
228
|
+
}
|
|
229
|
+
async function runCommand(command, cwd, throwOnFailure = false) {
|
|
230
|
+
try {
|
|
231
|
+
const { stdout, stderr } = await execFileAsync(command[0] ?? '', command.slice(1), { cwd, encoding: 'utf8', maxBuffer: 1024 * 1024 * 8 });
|
|
232
|
+
return { ok: true, command, cwd, exit_code: 0, stdout_tail: tail(stdout), stderr_tail: tail(stderr) };
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
const record = {
|
|
236
|
+
ok: false,
|
|
237
|
+
command,
|
|
238
|
+
cwd,
|
|
239
|
+
exit_code: typeof error.code === 'number' ? error.code : null,
|
|
240
|
+
stdout_tail: tail(typeof error.stdout === 'string' ? error.stdout : ''),
|
|
241
|
+
stderr_tail: tail(typeof error.stderr === 'string' ? error.stderr : error instanceof Error ? error.message : String(error))
|
|
242
|
+
};
|
|
243
|
+
if (throwOnFailure)
|
|
244
|
+
throw new Error(`${command.join(' ')} failed: ${record.stderr_tail || record.stdout_tail}`);
|
|
245
|
+
return record;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
function blockedReport(tmpRoot, repoRoot, cleanup, blockers) {
|
|
249
|
+
return {
|
|
250
|
+
schema: PARALLEL_PRODUCTION_SMOKE_SCHEMA,
|
|
251
|
+
ok: false,
|
|
252
|
+
status: 'blocked',
|
|
253
|
+
proof_level: 'blocked',
|
|
254
|
+
tmp_root: tmpRoot,
|
|
255
|
+
repo_root: repoRoot,
|
|
256
|
+
worker_count: 0,
|
|
257
|
+
worker_ids: [],
|
|
258
|
+
changed_files: [],
|
|
259
|
+
changed_files_by_worker: {},
|
|
260
|
+
distributed_across_workers: false,
|
|
261
|
+
timestamp_overlap: false,
|
|
262
|
+
overlap_windows: [],
|
|
263
|
+
patch_envelope_count: 0,
|
|
264
|
+
parent_merge_artifact: { schema: 'sks.parallel-production-parent-merge.v1', ok: false, merged_files: [], shared_untouched: false, git_status_after_merge: '' },
|
|
265
|
+
typecheck: { ok: false, command: [], cwd: repoRoot, exit_code: null, stdout_tail: '', stderr_tail: '' },
|
|
266
|
+
worktree_cleanup: cleanup,
|
|
267
|
+
failure_injection: {
|
|
268
|
+
requested: false,
|
|
269
|
+
worker_failure_seen: false,
|
|
270
|
+
reassignment_attempted: false,
|
|
271
|
+
survived_worker_failure: false,
|
|
272
|
+
failed_worker_id: null,
|
|
273
|
+
failed_worker_ids: [],
|
|
274
|
+
recovered_work_item_ids: [],
|
|
275
|
+
scheduler_survived: false,
|
|
276
|
+
successful_workers: [],
|
|
277
|
+
failed_workers: []
|
|
278
|
+
},
|
|
279
|
+
mock_only: false,
|
|
280
|
+
blockers
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
async function fileEquals(file, expected) {
|
|
284
|
+
return (await fsp.readFile(file, 'utf8')) === expected;
|
|
285
|
+
}
|
|
286
|
+
async function exists(file) {
|
|
287
|
+
try {
|
|
288
|
+
await fsp.access(file);
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
function delay(ms) {
|
|
296
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
297
|
+
}
|
|
298
|
+
function tail(text, max = 4000) {
|
|
299
|
+
return text.length > max ? text.slice(-max) : text;
|
|
300
|
+
}
|
|
301
|
+
//# sourceMappingURL=parallel-write-fixture.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { dirSize, formatBytes, packageRoot, projectRoot, sksRoot } from '../fsx.js';
|
|
2
|
-
import { enforceRetention, storageReport } from '../retention.js';
|
|
2
|
+
import { enforceRetention, lightweightStorageReport, storageReport } from '../retention.js';
|
|
3
3
|
import { flag } from './command-utils.js';
|
|
4
4
|
import { projectTriwikiToAgentsMd } from '../triwiki/agents-md-projector.js';
|
|
5
5
|
import { compileMistakeRules } from '../verification/mistake-rule-compiler.js';
|
|
@@ -45,13 +45,19 @@ function readOption(args = [], name, fallback = null) {
|
|
|
45
45
|
}
|
|
46
46
|
export async function statsCommand(args = []) {
|
|
47
47
|
const root = await sksRoot();
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
const
|
|
48
|
+
const full = flag(args, '--full');
|
|
49
|
+
const report = full ? await storageReport(root) : await lightweightStorageReport(root);
|
|
50
|
+
const pkgBytes = full ? await dirSize(packageRoot()).catch(() => 0) : null;
|
|
51
|
+
const out = {
|
|
52
|
+
package: full
|
|
53
|
+
? { bytes: pkgBytes, human: formatBytes(pkgBytes), full_size: true }
|
|
54
|
+
: { bytes: null, human: null, full_size: false, note: 'Run `sks stats --full --json` for recursive package sizing.' },
|
|
55
|
+
storage: report
|
|
56
|
+
};
|
|
51
57
|
if (flag(args, '--json'))
|
|
52
58
|
return console.log(JSON.stringify(out, null, 2));
|
|
53
59
|
console.log('ㅅㅋㅅ Stats');
|
|
54
|
-
console.log(`Package: ${out.package.human}`);
|
|
55
|
-
console.log(`State: ${report.total_human || '
|
|
60
|
+
console.log(`Package: ${out.package.human || 'not scanned (use --full)'}`);
|
|
61
|
+
console.log(`State: ${report.total_human || 'not scanned (use --full)'}`);
|
|
56
62
|
}
|
|
57
63
|
//# sourceMappingURL=gc-command.js.map
|
|
@@ -378,8 +378,8 @@ function runNextAction(route, id, args) {
|
|
|
378
378
|
function safeRouteExecutionArgs(route, prompt, { auto = false } = {}) {
|
|
379
379
|
if (route.command === '$DB')
|
|
380
380
|
return ['db', 'check', '--sql', 'SELECT 1', '--json'];
|
|
381
|
-
if (route.command === '$
|
|
382
|
-
return
|
|
381
|
+
if (route.command === '$Super-Search')
|
|
382
|
+
return superSearchExecutionArgs(prompt);
|
|
383
383
|
if (route.command === '$SEO-GEO-OPTIMIZER')
|
|
384
384
|
return ['seo-geo-optimizer', searchVisibilityActionFromPrompt(prompt), '--mode', searchVisibilityModeFromPrompt(prompt), '--target', searchVisibilityTargetFromPrompt(prompt), '--offline', '--json'];
|
|
385
385
|
if (route.command === '$Wiki')
|
|
@@ -394,32 +394,34 @@ function safeRouteExecutionArgs(route, prompt, { auto = false } = {}) {
|
|
|
394
394
|
return ['commit-and-push', '--json'];
|
|
395
395
|
return ['team', prompt, '--mock', '--json', ...(auto ? ['--no-open-zellij'] : [])];
|
|
396
396
|
}
|
|
397
|
-
function
|
|
398
|
-
const stripped =
|
|
397
|
+
function superSearchExecutionArgs(prompt = '') {
|
|
398
|
+
const stripped = stripSuperSearchPrompt(prompt);
|
|
399
399
|
const lower = stripped.toLowerCase();
|
|
400
400
|
if (!stripped || /^(?:doctor|check|status)\b/.test(lower))
|
|
401
|
-
return ['
|
|
401
|
+
return ['super-search', 'doctor', '--json'];
|
|
402
402
|
if (/^(?:x|x-search|x_search)\b/.test(lower)) {
|
|
403
403
|
const query = stripped.replace(/^(?:x|x-search|x_search)\b[:\s-]*/i, '').trim() || 'source intelligence fixture';
|
|
404
|
-
return ['
|
|
404
|
+
return ['super-search', 'x', query, '--json'];
|
|
405
405
|
}
|
|
406
406
|
const url = stripped.match(/\bhttps?:\/\/\S+/)?.[0];
|
|
407
|
-
if (/^(?:fetch|url)\b/.test(lower) || url)
|
|
408
|
-
|
|
407
|
+
if (/^(?:fetch|url)\b/.test(lower) || url) {
|
|
408
|
+
const fetchTarget = url || stripped.replace(/^(?:fetch|url)\b[:\s-]*/i, '').trim();
|
|
409
|
+
return fetchTarget ? ['super-search', 'fetch', fetchTarget, '--json'] : ['super-search', 'fetch', '--json'];
|
|
410
|
+
}
|
|
409
411
|
const query = stripped.replace(/^run\b[:\s-]*/i, '').trim() || 'source intelligence fixture';
|
|
410
|
-
return ['
|
|
412
|
+
return ['super-search', 'run', query, '--mode', 'balanced', '--json'];
|
|
411
413
|
}
|
|
412
|
-
function
|
|
414
|
+
function stripSuperSearchPrompt(prompt = '') {
|
|
413
415
|
return String(prompt || '')
|
|
414
416
|
.trim()
|
|
415
|
-
.replace(/^\[\$
|
|
416
|
-
.replace(/^\[\$
|
|
417
|
-
.replace(/^\[\$
|
|
418
|
-
.replace(/^\[\$
|
|
419
|
-
.replace(/^\$
|
|
420
|
-
.replace(/^\$
|
|
421
|
-
.replace(/^\$
|
|
422
|
-
.replace(/^\$
|
|
417
|
+
.replace(/^\[\$Super-Search\]\([^)]+\)(?:\s|:)?\s*/i, '')
|
|
418
|
+
.replace(/^\[\$Super-Search\]\([^)]+\)(?:\s|:)?\s*/i, '')
|
|
419
|
+
.replace(/^\[\$Super-Search\]\([^)]+\)(?:\s|:)?\s*/i, '')
|
|
420
|
+
.replace(/^\[\$Super-Search\]\([^)]+\)(?:\s|:)?\s*/i, '')
|
|
421
|
+
.replace(/^\$Super-Search(?:\s|:)?\s*/i, '')
|
|
422
|
+
.replace(/^\$Super-Search(?:\s|:)?\s*/i, '')
|
|
423
|
+
.replace(/^\$Super-Search(?:\s|:)?\s*/i, '')
|
|
424
|
+
.replace(/^\$Super-Search(?:\s|:)?\s*/i, '')
|
|
423
425
|
.trim();
|
|
424
426
|
}
|
|
425
427
|
function searchVisibilityActionFromPrompt(prompt = '') {
|