opencode-swarm 7.33.0 → 7.33.2
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 -0
- package/dist/cli/index.js +1053 -519
- package/dist/evidence/gate-bridge.d.ts +15 -0
- package/dist/index.js +417 -163
- package/dist/plan/ledger.d.ts +9 -0
- package/dist/plan/manager.d.ts +28 -2
- package/dist/services/evidence-summary-service.d.ts +5 -0
- package/dist/telemetry.d.ts +1 -1
- package/dist/tools/co-change-analyzer.d.ts +2 -1
- package/dist/tools/save-plan.d.ts +12 -0
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -34,7 +34,7 @@ var package_default;
|
|
|
34
34
|
var init_package = __esm(() => {
|
|
35
35
|
package_default = {
|
|
36
36
|
name: "opencode-swarm",
|
|
37
|
-
version: "7.33.
|
|
37
|
+
version: "7.33.2",
|
|
38
38
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
39
39
|
main: "dist/index.js",
|
|
40
40
|
types: "dist/index.d.ts",
|
|
@@ -14580,9 +14580,138 @@ function emit(event, data) {
|
|
|
14580
14580
|
}
|
|
14581
14581
|
} catch {}
|
|
14582
14582
|
}
|
|
14583
|
-
var _writeStream = null, _listeners, _disabled = false;
|
|
14583
|
+
var _writeStream = null, _listeners, _disabled = false, telemetry, _internals2;
|
|
14584
14584
|
var init_telemetry = __esm(() => {
|
|
14585
14585
|
_listeners = [];
|
|
14586
|
+
telemetry = {
|
|
14587
|
+
sessionStarted(sessionId, agentName) {
|
|
14588
|
+
_internals2.emit("session_started", { sessionId, agentName });
|
|
14589
|
+
},
|
|
14590
|
+
sessionEnded(sessionId, reason) {
|
|
14591
|
+
_internals2.emit("session_ended", { sessionId, reason });
|
|
14592
|
+
},
|
|
14593
|
+
agentActivated(sessionId, agentName, oldName) {
|
|
14594
|
+
_internals2.emit("agent_activated", { sessionId, agentName, oldName });
|
|
14595
|
+
},
|
|
14596
|
+
delegationBegin(sessionId, agentName, taskId) {
|
|
14597
|
+
_internals2.emit("delegation_begin", { sessionId, agentName, taskId });
|
|
14598
|
+
},
|
|
14599
|
+
delegationEnd(sessionId, agentName, taskId, result) {
|
|
14600
|
+
_internals2.emit("delegation_end", { sessionId, agentName, taskId, result });
|
|
14601
|
+
},
|
|
14602
|
+
taskStateChanged(sessionId, taskId, newState, oldState) {
|
|
14603
|
+
_internals2.emit("task_state_changed", {
|
|
14604
|
+
sessionId,
|
|
14605
|
+
taskId,
|
|
14606
|
+
newState,
|
|
14607
|
+
oldState
|
|
14608
|
+
});
|
|
14609
|
+
},
|
|
14610
|
+
gatePassed(sessionId, gate, taskId) {
|
|
14611
|
+
_internals2.emit("gate_passed", { sessionId, gate, taskId });
|
|
14612
|
+
},
|
|
14613
|
+
gateParseError(taskId, error49) {
|
|
14614
|
+
_internals2.emit("gate_parse_error", {
|
|
14615
|
+
taskId,
|
|
14616
|
+
errorName: error49.name,
|
|
14617
|
+
errorMessage: error49.message.slice(0, 200)
|
|
14618
|
+
});
|
|
14619
|
+
},
|
|
14620
|
+
gateFailed(sessionId, gate, taskId, reason) {
|
|
14621
|
+
_internals2.emit("gate_failed", { sessionId, gate, taskId, reason });
|
|
14622
|
+
},
|
|
14623
|
+
phaseChanged(sessionId, oldPhase, newPhase) {
|
|
14624
|
+
_internals2.emit("phase_changed", { sessionId, oldPhase, newPhase });
|
|
14625
|
+
},
|
|
14626
|
+
budgetUpdated(sessionId, budgetPct, agentName) {
|
|
14627
|
+
_internals2.emit("budget_updated", { sessionId, budgetPct, agentName });
|
|
14628
|
+
},
|
|
14629
|
+
modelFallback(sessionId, agentName, fromModel, toModel, reason) {
|
|
14630
|
+
_internals2.emit("model_fallback", {
|
|
14631
|
+
sessionId,
|
|
14632
|
+
agentName,
|
|
14633
|
+
fromModel,
|
|
14634
|
+
toModel,
|
|
14635
|
+
reason
|
|
14636
|
+
});
|
|
14637
|
+
},
|
|
14638
|
+
hardLimitHit(sessionId, agentName, limitType, value) {
|
|
14639
|
+
_internals2.emit("hard_limit_hit", {
|
|
14640
|
+
sessionId,
|
|
14641
|
+
agentName,
|
|
14642
|
+
limitType,
|
|
14643
|
+
value
|
|
14644
|
+
});
|
|
14645
|
+
},
|
|
14646
|
+
revisionLimitHit(sessionId, agentName) {
|
|
14647
|
+
_internals2.emit("revision_limit_hit", { sessionId, agentName });
|
|
14648
|
+
},
|
|
14649
|
+
loopDetected(sessionId, agentName, loopType) {
|
|
14650
|
+
_internals2.emit("loop_detected", { sessionId, agentName, loopType });
|
|
14651
|
+
},
|
|
14652
|
+
scopeViolation(sessionId, agentName, file2, reason) {
|
|
14653
|
+
_internals2.emit("scope_violation", { sessionId, agentName, file: file2, reason });
|
|
14654
|
+
},
|
|
14655
|
+
qaSkipViolation(sessionId, agentName, skipCount) {
|
|
14656
|
+
_internals2.emit("qa_skip_violation", { sessionId, agentName, skipCount });
|
|
14657
|
+
},
|
|
14658
|
+
heartbeat(sessionId) {
|
|
14659
|
+
_internals2.emit("heartbeat", { sessionId });
|
|
14660
|
+
},
|
|
14661
|
+
turboModeChanged(sessionId, enabled, agentName) {
|
|
14662
|
+
_internals2.emit("turbo_mode_changed", { sessionId, enabled, agentName });
|
|
14663
|
+
},
|
|
14664
|
+
autoOversightEscalation(sessionId, reason, interactionCount, deadlockCount, phase) {
|
|
14665
|
+
_internals2.emit("auto_oversight_escalation", {
|
|
14666
|
+
sessionId,
|
|
14667
|
+
reason,
|
|
14668
|
+
interactionCount,
|
|
14669
|
+
deadlockCount,
|
|
14670
|
+
phase
|
|
14671
|
+
});
|
|
14672
|
+
},
|
|
14673
|
+
environmentDetected(sessionId, hostOS, shellFamily, executionMode) {
|
|
14674
|
+
_internals2.emit("environment_detected", {
|
|
14675
|
+
sessionId,
|
|
14676
|
+
hostOS,
|
|
14677
|
+
shellFamily,
|
|
14678
|
+
executionMode
|
|
14679
|
+
});
|
|
14680
|
+
},
|
|
14681
|
+
prmPatternDetected(sessionId, pattern, severity, category, stepRange) {
|
|
14682
|
+
_internals2.emit("prm_pattern_detected", {
|
|
14683
|
+
sessionId,
|
|
14684
|
+
pattern,
|
|
14685
|
+
severity,
|
|
14686
|
+
category,
|
|
14687
|
+
stepRange
|
|
14688
|
+
});
|
|
14689
|
+
},
|
|
14690
|
+
prmCourseCorrectionInjected(sessionId, pattern, level) {
|
|
14691
|
+
_internals2.emit("prm_course_correction_injected", {
|
|
14692
|
+
sessionId,
|
|
14693
|
+
pattern,
|
|
14694
|
+
level
|
|
14695
|
+
});
|
|
14696
|
+
},
|
|
14697
|
+
prmEscalationTriggered(sessionId, pattern, level, occurrenceCount) {
|
|
14698
|
+
_internals2.emit("prm_escalation_triggered", {
|
|
14699
|
+
sessionId,
|
|
14700
|
+
pattern,
|
|
14701
|
+
level,
|
|
14702
|
+
occurrenceCount
|
|
14703
|
+
});
|
|
14704
|
+
},
|
|
14705
|
+
prmHardStop(sessionId, pattern, level, occurrenceCount) {
|
|
14706
|
+
_internals2.emit("prm_hard_stop", {
|
|
14707
|
+
sessionId,
|
|
14708
|
+
pattern,
|
|
14709
|
+
level,
|
|
14710
|
+
occurrenceCount
|
|
14711
|
+
});
|
|
14712
|
+
}
|
|
14713
|
+
};
|
|
14714
|
+
_internals2 = { telemetry, emit };
|
|
14586
14715
|
});
|
|
14587
14716
|
|
|
14588
14717
|
// src/utils/spec-hash.ts
|
|
@@ -14603,7 +14732,7 @@ async function computeSpecHash(directory) {
|
|
|
14603
14732
|
return hash2;
|
|
14604
14733
|
}
|
|
14605
14734
|
async function isSpecStale(directory, plan) {
|
|
14606
|
-
const currentHash = await
|
|
14735
|
+
const currentHash = await _internals3.computeSpecHash(directory);
|
|
14607
14736
|
if (!plan.specHash) {
|
|
14608
14737
|
return { stale: false };
|
|
14609
14738
|
}
|
|
@@ -14623,9 +14752,9 @@ async function isSpecStale(directory, plan) {
|
|
|
14623
14752
|
}
|
|
14624
14753
|
return { stale: false };
|
|
14625
14754
|
}
|
|
14626
|
-
var
|
|
14755
|
+
var _internals3;
|
|
14627
14756
|
var init_spec_hash = __esm(() => {
|
|
14628
|
-
|
|
14757
|
+
_internals3 = {
|
|
14629
14758
|
computeSpecHash,
|
|
14630
14759
|
isSpecStale
|
|
14631
14760
|
};
|
|
@@ -14815,6 +14944,32 @@ async function appendLedgerEvent(directory, eventInput, options) {
|
|
|
14815
14944
|
fs.renameSync(tempPath, ledgerPath);
|
|
14816
14945
|
return event;
|
|
14817
14946
|
}
|
|
14947
|
+
async function takeSnapshotWithRetry(directory, plan, options) {
|
|
14948
|
+
const MAX_RETRIES = 3;
|
|
14949
|
+
const TOTAL_ATTEMPTS = 1 + MAX_RETRIES;
|
|
14950
|
+
const telemetrySource = options?.source ?? "save_plan_tool";
|
|
14951
|
+
const snapshotOptions = { planHashAfter: options?.planHashAfter };
|
|
14952
|
+
let lastError;
|
|
14953
|
+
for (let attempt = 1;attempt <= TOTAL_ATTEMPTS; attempt++) {
|
|
14954
|
+
try {
|
|
14955
|
+
await takeSnapshotEvent(directory, plan, snapshotOptions);
|
|
14956
|
+
return;
|
|
14957
|
+
} catch (err) {
|
|
14958
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
14959
|
+
if (attempt < TOTAL_ATTEMPTS) {
|
|
14960
|
+
await new Promise((r) => setTimeout(r, 10 * 2 ** (attempt - 1)));
|
|
14961
|
+
}
|
|
14962
|
+
}
|
|
14963
|
+
}
|
|
14964
|
+
console.warn(`[takeSnapshotWithRetry] Snapshot failed after ${MAX_RETRIES} retries (${TOTAL_ATTEMPTS} attempts): ${lastError.message}`);
|
|
14965
|
+
try {
|
|
14966
|
+
emit("snapshot_failed", {
|
|
14967
|
+
error: lastError.message,
|
|
14968
|
+
retries: MAX_RETRIES,
|
|
14969
|
+
source: telemetrySource
|
|
14970
|
+
});
|
|
14971
|
+
} catch {}
|
|
14972
|
+
}
|
|
14818
14973
|
async function takeSnapshotEvent(directory, plan, options) {
|
|
14819
14974
|
const payloadHash = computePlanHash(plan);
|
|
14820
14975
|
const snapshotPayload = {
|
|
@@ -15048,6 +15203,7 @@ async function loadLastApprovedPlan(directory, expectedPlanId) {
|
|
|
15048
15203
|
var LEDGER_SCHEMA_VERSION = "1.1.0", LEDGER_FILENAME = "plan-ledger.jsonl", PLAN_JSON_FILENAME = "plan.json", LedgerStaleWriterError;
|
|
15049
15204
|
var init_ledger = __esm(() => {
|
|
15050
15205
|
init_plan_schema();
|
|
15206
|
+
init_telemetry();
|
|
15051
15207
|
LedgerStaleWriterError = class LedgerStaleWriterError extends Error {
|
|
15052
15208
|
constructor(message) {
|
|
15053
15209
|
super(message);
|
|
@@ -15219,7 +15375,7 @@ async function loadPlan(directory) {
|
|
|
15219
15375
|
const inSync = await isPlanMdInSync(directory, validated);
|
|
15220
15376
|
if (!inSync) {
|
|
15221
15377
|
try {
|
|
15222
|
-
await
|
|
15378
|
+
await _internals4.regeneratePlanMarkdown(directory, validated);
|
|
15223
15379
|
} catch (regenError) {
|
|
15224
15380
|
warn(`Failed to regenerate plan.md: ${regenError instanceof Error ? regenError.message : String(regenError)}. Proceeding with plan.json only.`);
|
|
15225
15381
|
}
|
|
@@ -15241,7 +15397,9 @@ async function loadPlan(directory) {
|
|
|
15241
15397
|
try {
|
|
15242
15398
|
const rebuilt = await replayFromLedger(directory);
|
|
15243
15399
|
if (rebuilt) {
|
|
15244
|
-
await rebuildPlan(directory, rebuilt
|
|
15400
|
+
await rebuildPlan(directory, rebuilt, {
|
|
15401
|
+
reason: "ledger_hash_mismatch_recovery"
|
|
15402
|
+
});
|
|
15245
15403
|
warn("[loadPlan] Rebuilt plan from ledger. Checkpoint available at .swarm/SWARM_PLAN.md if it exists.");
|
|
15246
15404
|
return rebuilt;
|
|
15247
15405
|
}
|
|
@@ -15249,7 +15407,9 @@ async function loadPlan(directory) {
|
|
|
15249
15407
|
try {
|
|
15250
15408
|
const approved = await loadLastApprovedPlan(directory, currentPlanId);
|
|
15251
15409
|
if (approved) {
|
|
15252
|
-
await rebuildPlan(directory, approved.plan
|
|
15410
|
+
await rebuildPlan(directory, approved.plan, {
|
|
15411
|
+
reason: "approved_snapshot_fallback"
|
|
15412
|
+
});
|
|
15253
15413
|
try {
|
|
15254
15414
|
await takeSnapshotEvent(directory, approved.plan, {
|
|
15255
15415
|
source: "recovery_from_approved_snapshot",
|
|
@@ -15326,7 +15486,9 @@ async function loadPlan(directory) {
|
|
|
15326
15486
|
} else if (catchFirstEvent !== null && rawPlanId !== null) {
|
|
15327
15487
|
const rebuilt = await replayFromLedger(directory);
|
|
15328
15488
|
if (rebuilt) {
|
|
15329
|
-
await rebuildPlan(directory, rebuilt
|
|
15489
|
+
await rebuildPlan(directory, rebuilt, {
|
|
15490
|
+
reason: "validation_failure_recovery"
|
|
15491
|
+
});
|
|
15330
15492
|
warn("[loadPlan] Rebuilt plan from ledger after validation failure. Projection was stale.");
|
|
15331
15493
|
return rebuilt;
|
|
15332
15494
|
}
|
|
@@ -15358,7 +15520,7 @@ async function loadPlan(directory) {
|
|
|
15358
15520
|
const existingMutex = recoveryMutexes.get(resolvedDir);
|
|
15359
15521
|
if (existingMutex) {
|
|
15360
15522
|
await existingMutex;
|
|
15361
|
-
const postRecoveryPlan = await
|
|
15523
|
+
const postRecoveryPlan = await _internals4.loadPlanJsonOnly(directory);
|
|
15362
15524
|
if (postRecoveryPlan)
|
|
15363
15525
|
return postRecoveryPlan;
|
|
15364
15526
|
}
|
|
@@ -15418,7 +15580,7 @@ async function loadPlan(directory) {
|
|
|
15418
15580
|
return null;
|
|
15419
15581
|
}
|
|
15420
15582
|
async function savePlanWithAutoAcknowledgedRemovals(directory, plan, source, reason, options) {
|
|
15421
|
-
const existing = await
|
|
15583
|
+
const existing = await _internals4.loadPlanJsonOnly(directory);
|
|
15422
15584
|
const newIds = new Set;
|
|
15423
15585
|
for (const phase of plan.phases) {
|
|
15424
15586
|
for (const task of phase.tasks)
|
|
@@ -15446,7 +15608,7 @@ async function savePlan(directory, plan, options) {
|
|
|
15446
15608
|
const validated = PlanSchema.parse(plan);
|
|
15447
15609
|
if (options?.preserveCompletedStatuses !== false) {
|
|
15448
15610
|
try {
|
|
15449
|
-
const currentPlan2 = await
|
|
15611
|
+
const currentPlan2 = await _internals4.loadPlanJsonOnly(directory);
|
|
15450
15612
|
if (currentPlan2) {
|
|
15451
15613
|
const completedTaskIds = new Set;
|
|
15452
15614
|
for (const phase of currentPlan2.phases) {
|
|
@@ -15479,7 +15641,7 @@ async function savePlan(directory, plan, options) {
|
|
|
15479
15641
|
phase.status = "pending";
|
|
15480
15642
|
}
|
|
15481
15643
|
}
|
|
15482
|
-
const currentPlan = await
|
|
15644
|
+
const currentPlan = await _internals4.loadPlanJsonOnly(directory);
|
|
15483
15645
|
const planId = derivePlanId(validated);
|
|
15484
15646
|
const planHashForInit = computePlanHash(validated);
|
|
15485
15647
|
if (!await ledgerExists(directory)) {
|
|
@@ -15624,7 +15786,7 @@ async function savePlan(directory, plan, options) {
|
|
|
15624
15786
|
expectedHash: currentHash,
|
|
15625
15787
|
planHashAfter: hashAfter,
|
|
15626
15788
|
verifyValid: async () => {
|
|
15627
|
-
const onDisk = await
|
|
15789
|
+
const onDisk = await _internals4.loadPlanJsonOnly(directory);
|
|
15628
15790
|
if (!onDisk)
|
|
15629
15791
|
return true;
|
|
15630
15792
|
for (const p of onDisk.phases) {
|
|
@@ -15662,7 +15824,7 @@ async function savePlan(directory, plan, options) {
|
|
|
15662
15824
|
expectedHash: currentHash,
|
|
15663
15825
|
planHashAfter: hashAfter,
|
|
15664
15826
|
verifyValid: async () => {
|
|
15665
|
-
const onDisk = await
|
|
15827
|
+
const onDisk = await _internals4.loadPlanJsonOnly(directory);
|
|
15666
15828
|
if (!onDisk)
|
|
15667
15829
|
return true;
|
|
15668
15830
|
for (const p of onDisk.phases) {
|
|
@@ -15687,12 +15849,9 @@ async function savePlan(directory, plan, options) {
|
|
|
15687
15849
|
const SNAPSHOT_INTERVAL = 50;
|
|
15688
15850
|
const latestSeq = await getLatestLedgerSeq(directory);
|
|
15689
15851
|
if (latestSeq > 0 && latestSeq % SNAPSHOT_INTERVAL === 0) {
|
|
15690
|
-
await
|
|
15691
|
-
planHashAfter: hashAfter
|
|
15692
|
-
|
|
15693
|
-
if (process.env.DEBUG_SWARM) {
|
|
15694
|
-
warn(`[savePlan] Periodic snapshot write failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
|
|
15695
|
-
}
|
|
15852
|
+
await takeSnapshotWithRetry(directory, validated, {
|
|
15853
|
+
planHashAfter: hashAfter,
|
|
15854
|
+
source: "savePlan_manager"
|
|
15696
15855
|
});
|
|
15697
15856
|
}
|
|
15698
15857
|
const swarmDir = path4.resolve(directory, ".swarm");
|
|
@@ -15706,6 +15865,17 @@ async function savePlan(directory, plan, options) {
|
|
|
15706
15865
|
unlinkSync(tempPath);
|
|
15707
15866
|
} catch {}
|
|
15708
15867
|
}
|
|
15868
|
+
try {
|
|
15869
|
+
const markerPath = path4.join(swarmDir, ".plan-write-marker");
|
|
15870
|
+
const inProgressMarker = JSON.stringify({
|
|
15871
|
+
source: "plan_manager",
|
|
15872
|
+
timestamp: new Date().toISOString(),
|
|
15873
|
+
phases_count: validated.phases.length,
|
|
15874
|
+
tasks_count: validated.phases.reduce((sum, p) => sum + p.tasks.length, 0),
|
|
15875
|
+
in_progress: true
|
|
15876
|
+
});
|
|
15877
|
+
await bunWrite(markerPath, inProgressMarker);
|
|
15878
|
+
} catch {}
|
|
15709
15879
|
try {
|
|
15710
15880
|
const contentHash = computePlanContentHash(validated);
|
|
15711
15881
|
const markdown = derivePlanMarkdown(validated);
|
|
@@ -15739,41 +15909,146 @@ ${markdown}`;
|
|
|
15739
15909
|
source: "plan_manager",
|
|
15740
15910
|
timestamp: new Date().toISOString(),
|
|
15741
15911
|
phases_count: validated.phases.length,
|
|
15742
|
-
tasks_count: tasksCount
|
|
15912
|
+
tasks_count: tasksCount,
|
|
15913
|
+
in_progress: false
|
|
15743
15914
|
});
|
|
15744
15915
|
await bunWrite(markerPath, marker);
|
|
15745
15916
|
} catch {}
|
|
15746
15917
|
}
|
|
15747
|
-
async function rebuildPlan(directory, plan) {
|
|
15918
|
+
async function rebuildPlan(directory, plan, options) {
|
|
15748
15919
|
const targetPlan = plan ?? await replayFromLedger(directory);
|
|
15749
15920
|
if (!targetPlan)
|
|
15750
15921
|
return null;
|
|
15751
15922
|
const swarmDir = path4.join(directory, ".swarm");
|
|
15752
15923
|
const planPath = path4.join(swarmDir, "plan.json");
|
|
15753
15924
|
const mdPath = path4.join(swarmDir, "plan.md");
|
|
15754
|
-
const tempPlanPath = path4.join(swarmDir, `plan.json.rebuild.${Date.now()}`);
|
|
15925
|
+
const tempPlanPath = path4.join(swarmDir, `plan.json.rebuild.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
|
|
15755
15926
|
await bunWrite(tempPlanPath, JSON.stringify(targetPlan, null, 2));
|
|
15756
15927
|
renameSync2(tempPlanPath, planPath);
|
|
15757
|
-
const contentHash = computePlanContentHash(targetPlan);
|
|
15758
|
-
const markdown = derivePlanMarkdown(targetPlan);
|
|
15759
|
-
const markdownWithHash = `<!-- PLAN_HASH: ${contentHash} -->
|
|
15760
|
-
${markdown}`;
|
|
15761
|
-
const tempMdPath = path4.join(swarmDir, `plan.md.rebuild.${Date.now()}`);
|
|
15762
|
-
await bunWrite(tempMdPath, markdownWithHash);
|
|
15763
|
-
renameSync2(tempMdPath, mdPath);
|
|
15764
15928
|
try {
|
|
15765
15929
|
const markerPath = path4.join(swarmDir, ".plan-write-marker");
|
|
15766
|
-
const
|
|
15767
|
-
const marker = JSON.stringify({
|
|
15930
|
+
const inProgressMarker = JSON.stringify({
|
|
15768
15931
|
source: "plan_manager",
|
|
15769
15932
|
timestamp: new Date().toISOString(),
|
|
15770
15933
|
phases_count: targetPlan.phases.length,
|
|
15771
|
-
tasks_count:
|
|
15934
|
+
tasks_count: targetPlan.phases.reduce((sum, phase) => sum + phase.tasks.length, 0),
|
|
15935
|
+
in_progress: true
|
|
15772
15936
|
});
|
|
15773
|
-
await bunWrite(markerPath,
|
|
15937
|
+
await bunWrite(markerPath, inProgressMarker);
|
|
15938
|
+
} catch {}
|
|
15939
|
+
try {
|
|
15940
|
+
const contentHash = computePlanContentHash(targetPlan);
|
|
15941
|
+
const markdown = derivePlanMarkdown(targetPlan);
|
|
15942
|
+
const markdownWithHash = `<!-- PLAN_HASH: ${contentHash} -->
|
|
15943
|
+
${markdown}`;
|
|
15944
|
+
const tempMdPath = path4.join(swarmDir, `plan.md.rebuild.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
|
|
15945
|
+
await bunWrite(tempMdPath, markdownWithHash);
|
|
15946
|
+
renameSync2(tempMdPath, mdPath);
|
|
15947
|
+
} finally {
|
|
15948
|
+
try {
|
|
15949
|
+
const markerPath = path4.join(swarmDir, ".plan-write-marker");
|
|
15950
|
+
const tasksCount = targetPlan.phases.reduce((sum, phase) => sum + phase.tasks.length, 0);
|
|
15951
|
+
const marker = JSON.stringify({
|
|
15952
|
+
source: "plan_manager",
|
|
15953
|
+
timestamp: new Date().toISOString(),
|
|
15954
|
+
phases_count: targetPlan.phases.length,
|
|
15955
|
+
tasks_count: tasksCount,
|
|
15956
|
+
in_progress: false
|
|
15957
|
+
});
|
|
15958
|
+
await bunWrite(markerPath, marker);
|
|
15959
|
+
} catch {}
|
|
15960
|
+
}
|
|
15961
|
+
try {
|
|
15962
|
+
const planId = derivePlanId(targetPlan);
|
|
15963
|
+
const planHashAfter = computePlanHash(targetPlan);
|
|
15964
|
+
await appendLedgerEvent(directory, {
|
|
15965
|
+
event_type: "plan_rebuilt",
|
|
15966
|
+
source: "rebuildPlan",
|
|
15967
|
+
plan_id: planId,
|
|
15968
|
+
payload: {
|
|
15969
|
+
reason: options?.reason ?? "ledger_replay_recovery",
|
|
15970
|
+
phases_count: targetPlan.phases.length,
|
|
15971
|
+
tasks_count: targetPlan.phases.reduce((sum, p) => sum + p.tasks.length, 0)
|
|
15972
|
+
}
|
|
15973
|
+
}, { planHashAfter });
|
|
15774
15974
|
} catch {}
|
|
15775
15975
|
return targetPlan;
|
|
15776
15976
|
}
|
|
15977
|
+
async function closePlanTerminalState(directory, plan, options) {
|
|
15978
|
+
const planId = derivePlanId(plan);
|
|
15979
|
+
const validated = PlanSchema.parse(plan);
|
|
15980
|
+
const hashAfter = computePlanHash(validated);
|
|
15981
|
+
for (const taskId of options.closedTaskIds) {
|
|
15982
|
+
let taskPhaseId;
|
|
15983
|
+
for (const phase of validated.phases) {
|
|
15984
|
+
if (phase.tasks.some((t) => t.id === taskId)) {
|
|
15985
|
+
taskPhaseId = phase.id;
|
|
15986
|
+
break;
|
|
15987
|
+
}
|
|
15988
|
+
}
|
|
15989
|
+
const fromStatus = options.originalStatuses?.get(taskId) ?? "in_progress";
|
|
15990
|
+
await appendLedgerEvent(directory, {
|
|
15991
|
+
plan_id: planId,
|
|
15992
|
+
event_type: "task_status_changed",
|
|
15993
|
+
task_id: taskId,
|
|
15994
|
+
phase_id: taskPhaseId,
|
|
15995
|
+
from_status: fromStatus,
|
|
15996
|
+
to_status: "closed",
|
|
15997
|
+
source: "close_terminal"
|
|
15998
|
+
}, { planHashAfter: hashAfter });
|
|
15999
|
+
}
|
|
16000
|
+
for (const phaseId of options.closedPhaseIds) {
|
|
16001
|
+
await appendLedgerEvent(directory, {
|
|
16002
|
+
plan_id: planId,
|
|
16003
|
+
event_type: "phase_completed",
|
|
16004
|
+
phase_id: phaseId,
|
|
16005
|
+
source: "close_terminal"
|
|
16006
|
+
}, { planHashAfter: hashAfter });
|
|
16007
|
+
}
|
|
16008
|
+
await takeSnapshotEvent(directory, validated, {
|
|
16009
|
+
planHashAfter: hashAfter,
|
|
16010
|
+
source: "close_terminal"
|
|
16011
|
+
});
|
|
16012
|
+
const swarmDir = path4.join(directory, ".swarm");
|
|
16013
|
+
const planPath = path4.join(swarmDir, "plan.json");
|
|
16014
|
+
const tempPlanPath = path4.join(swarmDir, `plan.json.close.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
|
|
16015
|
+
await bunWrite(tempPlanPath, JSON.stringify(validated, null, 2));
|
|
16016
|
+
renameSync2(tempPlanPath, planPath);
|
|
16017
|
+
try {
|
|
16018
|
+
const markerPath = path4.join(swarmDir, ".plan-write-marker");
|
|
16019
|
+
const inProgressMarker = JSON.stringify({
|
|
16020
|
+
source: "plan_manager_close",
|
|
16021
|
+
timestamp: new Date().toISOString(),
|
|
16022
|
+
phases_count: validated.phases.length,
|
|
16023
|
+
tasks_count: validated.phases.reduce((sum, phase) => sum + phase.tasks.length, 0),
|
|
16024
|
+
in_progress: true
|
|
16025
|
+
});
|
|
16026
|
+
await bunWrite(markerPath, inProgressMarker);
|
|
16027
|
+
} catch {}
|
|
16028
|
+
try {
|
|
16029
|
+
const mdPath = path4.join(swarmDir, "plan.md");
|
|
16030
|
+
const contentHash = computePlanContentHash(validated);
|
|
16031
|
+
const markdown = derivePlanMarkdown(validated);
|
|
16032
|
+
const markdownWithHash = `<!-- PLAN_HASH: ${contentHash} -->
|
|
16033
|
+
${markdown}`;
|
|
16034
|
+
const mdTempPath = path4.join(swarmDir, `plan.md.close.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
|
|
16035
|
+
await bunWrite(mdTempPath, markdownWithHash);
|
|
16036
|
+
renameSync2(mdTempPath, mdPath);
|
|
16037
|
+
} finally {
|
|
16038
|
+
try {
|
|
16039
|
+
const markerPath = path4.join(swarmDir, ".plan-write-marker");
|
|
16040
|
+
const tasksCount = validated.phases.reduce((sum, phase) => sum + phase.tasks.length, 0);
|
|
16041
|
+
const marker = JSON.stringify({
|
|
16042
|
+
source: "plan_manager_close",
|
|
16043
|
+
timestamp: new Date().toISOString(),
|
|
16044
|
+
phases_count: validated.phases.length,
|
|
16045
|
+
tasks_count: tasksCount,
|
|
16046
|
+
in_progress: false
|
|
16047
|
+
});
|
|
16048
|
+
await bunWrite(markerPath, marker);
|
|
16049
|
+
} catch {}
|
|
16050
|
+
}
|
|
16051
|
+
}
|
|
15777
16052
|
function derivePlanMarkdown(plan) {
|
|
15778
16053
|
const statusMap = {
|
|
15779
16054
|
pending: "PENDING",
|
|
@@ -16042,7 +16317,7 @@ function migrateLegacyPlan(planContent, swarmId) {
|
|
|
16042
16317
|
};
|
|
16043
16318
|
return plan;
|
|
16044
16319
|
}
|
|
16045
|
-
var PlanConcurrentModificationError, PlanTaskRemovalNotAcknowledgedError, startupLedgerCheckedWorkspaces, recoveryMutexes,
|
|
16320
|
+
var PlanConcurrentModificationError, PlanTaskRemovalNotAcknowledgedError, startupLedgerCheckedWorkspaces, recoveryMutexes, _internals4, CAS_BACKOFF_START_MS = 5, CAS_BACKOFF_CAP_MS = 250, CAS_BACKOFF_JITTER = 0.25, CAS_MAX_RETRIES = 3;
|
|
16046
16321
|
var init_manager = __esm(() => {
|
|
16047
16322
|
init_plan_schema();
|
|
16048
16323
|
init_utils2();
|
|
@@ -16068,7 +16343,7 @@ var init_manager = __esm(() => {
|
|
|
16068
16343
|
};
|
|
16069
16344
|
startupLedgerCheckedWorkspaces = new Set;
|
|
16070
16345
|
recoveryMutexes = new Map;
|
|
16071
|
-
|
|
16346
|
+
_internals4 = {
|
|
16072
16347
|
loadPlan,
|
|
16073
16348
|
loadPlanJsonOnly,
|
|
16074
16349
|
regeneratePlanMarkdown
|
|
@@ -19763,11 +20038,11 @@ async function tryAcquireLock(directory, filePath, agent, taskId) {
|
|
|
19763
20038
|
};
|
|
19764
20039
|
return { acquired: true, lock };
|
|
19765
20040
|
}
|
|
19766
|
-
var import_proper_lockfile, LOCKS_DIR = ".swarm/locks", LOCK_TIMEOUT_MS,
|
|
20041
|
+
var import_proper_lockfile, LOCKS_DIR = ".swarm/locks", LOCK_TIMEOUT_MS, _internals5;
|
|
19767
20042
|
var init_file_locks = __esm(() => {
|
|
19768
20043
|
import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
|
|
19769
20044
|
LOCK_TIMEOUT_MS = 5 * 60 * 1000;
|
|
19770
|
-
|
|
20045
|
+
_internals5 = {
|
|
19771
20046
|
tryAcquireLock,
|
|
19772
20047
|
writeFile: fs3.promises.writeFile
|
|
19773
20048
|
};
|
|
@@ -19867,6 +20142,19 @@ function checkUnsafeChars(taskId) {
|
|
|
19867
20142
|
}
|
|
19868
20143
|
return;
|
|
19869
20144
|
}
|
|
20145
|
+
function isStrictTaskId(taskId) {
|
|
20146
|
+
if (!taskId)
|
|
20147
|
+
return false;
|
|
20148
|
+
const unsafeMsg = checkUnsafeChars(taskId);
|
|
20149
|
+
if (unsafeMsg)
|
|
20150
|
+
return false;
|
|
20151
|
+
return STRICT_TASK_ID_PATTERN.test(taskId);
|
|
20152
|
+
}
|
|
20153
|
+
function assertStrictTaskId(taskId) {
|
|
20154
|
+
if (!isStrictTaskId(taskId)) {
|
|
20155
|
+
throw new Error(`Invalid taskId: "${taskId}". Must match N.M or N.M.P (e.g. "1.1", "1.2.3").`);
|
|
20156
|
+
}
|
|
20157
|
+
}
|
|
19870
20158
|
function sanitizeTaskId(taskId) {
|
|
19871
20159
|
const unsafeMsg = checkUnsafeChars(taskId);
|
|
19872
20160
|
if (unsafeMsg) {
|
|
@@ -19947,7 +20235,7 @@ function validateProjectRoot(directory) {
|
|
|
19947
20235
|
}
|
|
19948
20236
|
}
|
|
19949
20237
|
async function saveEvidence(directory, taskId, evidence) {
|
|
19950
|
-
|
|
20238
|
+
_internals6.validateProjectRoot(directory);
|
|
19951
20239
|
const sanitizedTaskId = sanitizeTaskId2(taskId);
|
|
19952
20240
|
const relativePath = path7.join("evidence", sanitizedTaskId, "evidence.json");
|
|
19953
20241
|
validateSwarmPath(directory, relativePath);
|
|
@@ -20048,7 +20336,7 @@ async function loadEvidence(directory, taskId) {
|
|
|
20048
20336
|
return { status: "invalid_schema", errors: ["Invalid JSON"] };
|
|
20049
20337
|
}
|
|
20050
20338
|
if (isFlatRetrospective(parsed)) {
|
|
20051
|
-
const wrappedBundle =
|
|
20339
|
+
const wrappedBundle = _internals6.wrapFlatRetrospective(parsed, sanitizedTaskId);
|
|
20052
20340
|
try {
|
|
20053
20341
|
const validated = EvidenceBundleSchema.parse(wrappedBundle);
|
|
20054
20342
|
try {
|
|
@@ -20144,14 +20432,14 @@ async function checkRequirementCoverage(phase, directory) {
|
|
|
20144
20432
|
}
|
|
20145
20433
|
}
|
|
20146
20434
|
async function archiveEvidence(directory, maxAgeDays, maxBundles) {
|
|
20147
|
-
const taskIds = await
|
|
20435
|
+
const taskIds = await _internals6.listEvidenceTaskIds(directory);
|
|
20148
20436
|
const cutoffDate = new Date;
|
|
20149
20437
|
cutoffDate.setDate(cutoffDate.getDate() - maxAgeDays);
|
|
20150
20438
|
const cutoffIso = cutoffDate.toISOString();
|
|
20151
20439
|
const archived = [];
|
|
20152
20440
|
const remainingBundles = [];
|
|
20153
20441
|
for (const taskId of taskIds) {
|
|
20154
|
-
const result = await
|
|
20442
|
+
const result = await _internals6.loadEvidence(directory, taskId);
|
|
20155
20443
|
if (result.status !== "found") {
|
|
20156
20444
|
continue;
|
|
20157
20445
|
}
|
|
@@ -20179,7 +20467,7 @@ async function archiveEvidence(directory, maxAgeDays, maxBundles) {
|
|
|
20179
20467
|
}
|
|
20180
20468
|
return archived;
|
|
20181
20469
|
}
|
|
20182
|
-
var VALID_EVIDENCE_TYPES, sanitizeTaskId2, MAX_DEPTH = 20, PROJECT_INDICATORS, LEGACY_TASK_COMPLEXITY_MAP,
|
|
20470
|
+
var VALID_EVIDENCE_TYPES, sanitizeTaskId2, MAX_DEPTH = 20, PROJECT_INDICATORS, LEGACY_TASK_COMPLEXITY_MAP, _internals6;
|
|
20183
20471
|
var init_manager2 = __esm(() => {
|
|
20184
20472
|
init_zod();
|
|
20185
20473
|
init_evidence_schema();
|
|
@@ -20222,7 +20510,7 @@ var init_manager2 = __esm(() => {
|
|
|
20222
20510
|
medium: "moderate",
|
|
20223
20511
|
high: "complex"
|
|
20224
20512
|
};
|
|
20225
|
-
|
|
20513
|
+
_internals6 = {
|
|
20226
20514
|
wrapFlatRetrospective,
|
|
20227
20515
|
loadEvidence,
|
|
20228
20516
|
listEvidenceTaskIds,
|
|
@@ -20434,7 +20722,7 @@ function getProfile(directory, planId) {
|
|
|
20434
20722
|
return row ? rowToProfile(row) : null;
|
|
20435
20723
|
}
|
|
20436
20724
|
function getOrCreateProfile(directory, planId, projectType) {
|
|
20437
|
-
const existing =
|
|
20725
|
+
const existing = _internals7.getProfile(directory, planId);
|
|
20438
20726
|
if (existing)
|
|
20439
20727
|
return existing;
|
|
20440
20728
|
const db = getProjectDb(directory);
|
|
@@ -20450,14 +20738,14 @@ function getOrCreateProfile(directory, planId, projectType) {
|
|
|
20450
20738
|
throw err;
|
|
20451
20739
|
}
|
|
20452
20740
|
}
|
|
20453
|
-
const after =
|
|
20741
|
+
const after = _internals7.getProfile(directory, planId);
|
|
20454
20742
|
if (!after) {
|
|
20455
20743
|
throw new Error(`Failed to create or load QA gate profile for plan_id=${planId}`);
|
|
20456
20744
|
}
|
|
20457
20745
|
return after;
|
|
20458
20746
|
}
|
|
20459
20747
|
function setGates(directory, planId, gates) {
|
|
20460
|
-
const current =
|
|
20748
|
+
const current = _internals7.getProfile(directory, planId);
|
|
20461
20749
|
if (!current) {
|
|
20462
20750
|
throw new Error(`No QA gate profile found for plan_id=${planId} \u2014 call getOrCreateProfile first`);
|
|
20463
20751
|
}
|
|
@@ -20481,7 +20769,7 @@ function setGates(directory, planId, gates) {
|
|
|
20481
20769
|
JSON.stringify(merged),
|
|
20482
20770
|
planId
|
|
20483
20771
|
]);
|
|
20484
|
-
const updated =
|
|
20772
|
+
const updated = _internals7.getProfile(directory, planId);
|
|
20485
20773
|
if (!updated) {
|
|
20486
20774
|
throw new Error(`Failed to re-read QA gate profile after update for plan_id=${planId}`);
|
|
20487
20775
|
}
|
|
@@ -20503,10 +20791,10 @@ function getEffectiveGates(profile, sessionOverrides) {
|
|
|
20503
20791
|
}
|
|
20504
20792
|
return merged;
|
|
20505
20793
|
}
|
|
20506
|
-
var
|
|
20794
|
+
var _internals7, DEFAULT_QA_GATES;
|
|
20507
20795
|
var init_qa_gate_profile = __esm(() => {
|
|
20508
20796
|
init_project_db();
|
|
20509
|
-
|
|
20797
|
+
_internals7 = {
|
|
20510
20798
|
getProfile,
|
|
20511
20799
|
getOrCreateProfile,
|
|
20512
20800
|
setGates,
|
|
@@ -34954,7 +35242,7 @@ function resetToRemoteBranch(cwd, options) {
|
|
|
34954
35242
|
const prunedBranches = [];
|
|
34955
35243
|
try {
|
|
34956
35244
|
const currentBranch = getCurrentBranch(cwd);
|
|
34957
|
-
const defaultRemoteBranch =
|
|
35245
|
+
const defaultRemoteBranch = _internals8.detectDefaultRemoteBranch(cwd);
|
|
34958
35246
|
if (!defaultRemoteBranch) {
|
|
34959
35247
|
return {
|
|
34960
35248
|
success: false,
|
|
@@ -35136,7 +35424,7 @@ function resetToRemoteBranch(cwd, options) {
|
|
|
35136
35424
|
function resetToMainAfterMerge(cwd, options) {
|
|
35137
35425
|
const warnings = [];
|
|
35138
35426
|
try {
|
|
35139
|
-
const defaultBranch =
|
|
35427
|
+
const defaultBranch = _internals8.detectDefaultRemoteBranch(cwd);
|
|
35140
35428
|
if (!defaultBranch) {
|
|
35141
35429
|
return {
|
|
35142
35430
|
success: false,
|
|
@@ -35163,7 +35451,7 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35163
35451
|
}
|
|
35164
35452
|
if (currentBranch === defaultBranch) {
|
|
35165
35453
|
try {
|
|
35166
|
-
const logOutput =
|
|
35454
|
+
const logOutput = _internals8.gitExec(["log", `${targetBranch}..HEAD`, "--oneline"], cwd);
|
|
35167
35455
|
if (logOutput.trim().length > 0) {
|
|
35168
35456
|
return {
|
|
35169
35457
|
success: false,
|
|
@@ -35178,11 +35466,11 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35178
35466
|
} catch {}
|
|
35179
35467
|
} else {
|
|
35180
35468
|
try {
|
|
35181
|
-
|
|
35469
|
+
_internals8.gitExec(["rev-parse", "--abbrev-ref", `${currentBranch}@{upstream}`], cwd);
|
|
35182
35470
|
} catch {
|
|
35183
35471
|
try {
|
|
35184
|
-
const localSha =
|
|
35185
|
-
const remoteSha =
|
|
35472
|
+
const localSha = _internals8.gitExec(["rev-parse", "HEAD"], cwd).trim();
|
|
35473
|
+
const remoteSha = _internals8.gitExec(["rev-parse", targetBranch], cwd).trim();
|
|
35186
35474
|
if (localSha !== remoteSha) {
|
|
35187
35475
|
return {
|
|
35188
35476
|
success: false,
|
|
@@ -35208,7 +35496,7 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35208
35496
|
}
|
|
35209
35497
|
}
|
|
35210
35498
|
try {
|
|
35211
|
-
|
|
35499
|
+
_internals8.gitExec(["fetch", "--prune", "origin"], cwd);
|
|
35212
35500
|
} catch (err) {
|
|
35213
35501
|
return {
|
|
35214
35502
|
success: false,
|
|
@@ -35224,7 +35512,7 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35224
35512
|
let switchedBranch = false;
|
|
35225
35513
|
if (currentBranch !== defaultBranch) {
|
|
35226
35514
|
try {
|
|
35227
|
-
|
|
35515
|
+
_internals8.gitExec(["checkout", defaultBranch], cwd);
|
|
35228
35516
|
switchedBranch = true;
|
|
35229
35517
|
} catch (err) {
|
|
35230
35518
|
return {
|
|
@@ -35239,7 +35527,7 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35239
35527
|
}
|
|
35240
35528
|
}
|
|
35241
35529
|
try {
|
|
35242
|
-
|
|
35530
|
+
_internals8.gitExec(["reset", "--hard", targetBranch], cwd);
|
|
35243
35531
|
} catch (err) {
|
|
35244
35532
|
return {
|
|
35245
35533
|
success: false,
|
|
@@ -35260,7 +35548,7 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35260
35548
|
while (Date.now() < endTime) {}
|
|
35261
35549
|
}
|
|
35262
35550
|
try {
|
|
35263
|
-
|
|
35551
|
+
_internals8.gitExec(["checkout", "--", "."], cwd);
|
|
35264
35552
|
discardSucceeded = true;
|
|
35265
35553
|
break;
|
|
35266
35554
|
} catch {}
|
|
@@ -35271,18 +35559,18 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35271
35559
|
changesDiscarded = discardSucceeded;
|
|
35272
35560
|
}
|
|
35273
35561
|
try {
|
|
35274
|
-
|
|
35562
|
+
_internals8.gitExec(["clean", "-fd"], cwd);
|
|
35275
35563
|
} catch {
|
|
35276
35564
|
warnings.push("Could not clean untracked files");
|
|
35277
35565
|
}
|
|
35278
35566
|
let branchDeleted = false;
|
|
35279
35567
|
if (switchedBranch && previousBranch !== defaultBranch) {
|
|
35280
35568
|
try {
|
|
35281
|
-
const mergedOutput =
|
|
35569
|
+
const mergedOutput = _internals8.gitExec(["branch", "--merged", defaultBranch], cwd);
|
|
35282
35570
|
const isMerged = mergedOutput.split(`
|
|
35283
35571
|
`).some((line) => line.trim() === previousBranch || line.trim() === `* ${previousBranch}`);
|
|
35284
35572
|
if (isMerged) {
|
|
35285
|
-
|
|
35573
|
+
_internals8.gitExec(["branch", "-d", previousBranch], cwd);
|
|
35286
35574
|
branchDeleted = true;
|
|
35287
35575
|
} else {
|
|
35288
35576
|
warnings.push(`Branch ${previousBranch} is not merged into ${defaultBranch} \u2014 keeping it`);
|
|
@@ -35293,7 +35581,7 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35293
35581
|
}
|
|
35294
35582
|
if (options?.pruneBranches) {
|
|
35295
35583
|
try {
|
|
35296
|
-
const mergedOutput =
|
|
35584
|
+
const mergedOutput = _internals8.gitExec(["branch", "--merged", defaultBranch], cwd);
|
|
35297
35585
|
const mergedLines = mergedOutput.split(`
|
|
35298
35586
|
`);
|
|
35299
35587
|
for (const line of mergedLines) {
|
|
@@ -35302,7 +35590,7 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35302
35590
|
continue;
|
|
35303
35591
|
}
|
|
35304
35592
|
try {
|
|
35305
|
-
|
|
35593
|
+
_internals8.gitExec(["branch", "-d", trimmedLine], cwd);
|
|
35306
35594
|
} catch {
|
|
35307
35595
|
warnings.push(`Could not prune branch: ${trimmedLine}`);
|
|
35308
35596
|
}
|
|
@@ -35332,10 +35620,10 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35332
35620
|
};
|
|
35333
35621
|
}
|
|
35334
35622
|
}
|
|
35335
|
-
var GIT_TIMEOUT_MS2 = 30000,
|
|
35623
|
+
var GIT_TIMEOUT_MS2 = 30000, _internals8;
|
|
35336
35624
|
var init_branch = __esm(() => {
|
|
35337
35625
|
init_logger();
|
|
35338
|
-
|
|
35626
|
+
_internals8 = {
|
|
35339
35627
|
gitExec: gitExec2,
|
|
35340
35628
|
detectDefaultRemoteBranch,
|
|
35341
35629
|
getDefaultBaseBranch,
|
|
@@ -36529,7 +36817,7 @@ async function curateAndStoreSwarm(lessons, projectName, phaseInfo, directory, c
|
|
|
36529
36817
|
existingEntries.push(entry);
|
|
36530
36818
|
}
|
|
36531
36819
|
await enforceKnowledgeCap(knowledgePath, config3.swarm_max_entries);
|
|
36532
|
-
await
|
|
36820
|
+
await _internals9.runAutoPromotion(directory, config3);
|
|
36533
36821
|
return { stored, skipped, rejected };
|
|
36534
36822
|
}
|
|
36535
36823
|
async function runAutoPromotion(directory, config3) {
|
|
@@ -36610,7 +36898,7 @@ function createKnowledgeCuratorHook(directory, config3) {
|
|
|
36610
36898
|
});
|
|
36611
36899
|
const projectName2 = evidenceData.project_name ?? "unknown";
|
|
36612
36900
|
const phaseNumber2 = typeof evidenceData.phase_number === "number" ? evidenceData.phase_number : 1;
|
|
36613
|
-
await
|
|
36901
|
+
await _internals9.curateAndStoreSwarm(lessons, projectName2, { phase_number: phaseNumber2 }, directory, config3);
|
|
36614
36902
|
return;
|
|
36615
36903
|
}
|
|
36616
36904
|
const planContent = await readSwarmFileAsync(directory, "plan.md");
|
|
@@ -36632,17 +36920,17 @@ function createKnowledgeCuratorHook(directory, config3) {
|
|
|
36632
36920
|
const projectName = projectNameMatch ? projectNameMatch[1].trim() : "unknown";
|
|
36633
36921
|
const phaseMatch = /^Phase:\s*(\d+)/m.exec(planContent);
|
|
36634
36922
|
const phaseNumber = phaseMatch ? parseInt(phaseMatch[1], 10) : 1;
|
|
36635
|
-
await
|
|
36923
|
+
await _internals9.curateAndStoreSwarm(normalLessons, projectName, { phase_number: phaseNumber }, directory, config3);
|
|
36636
36924
|
};
|
|
36637
36925
|
return safeHook(handler);
|
|
36638
36926
|
}
|
|
36639
|
-
var seenRetroSections,
|
|
36927
|
+
var seenRetroSections, _internals9;
|
|
36640
36928
|
var init_knowledge_curator = __esm(() => {
|
|
36641
36929
|
init_knowledge_store();
|
|
36642
36930
|
init_knowledge_validator();
|
|
36643
36931
|
init_utils2();
|
|
36644
36932
|
seenRetroSections = new Map;
|
|
36645
|
-
|
|
36933
|
+
_internals9 = {
|
|
36646
36934
|
isWriteToEvidenceFile,
|
|
36647
36935
|
curateAndStoreSwarm,
|
|
36648
36936
|
runAutoPromotion,
|
|
@@ -37849,7 +38137,7 @@ async function executeWriteRetro(args, directory) {
|
|
|
37849
38137
|
}, null, 2);
|
|
37850
38138
|
}
|
|
37851
38139
|
}
|
|
37852
|
-
var write_retro,
|
|
38140
|
+
var write_retro, _internals10;
|
|
37853
38141
|
var init_write_retro = __esm(() => {
|
|
37854
38142
|
init_zod();
|
|
37855
38143
|
init_evidence_schema();
|
|
@@ -37896,13 +38184,13 @@ var init_write_retro = __esm(() => {
|
|
|
37896
38184
|
task_id: args.task_id !== undefined ? String(args.task_id) : undefined,
|
|
37897
38185
|
metadata: args.metadata
|
|
37898
38186
|
};
|
|
37899
|
-
return await
|
|
38187
|
+
return await _internals10.executeWriteRetro(writeRetroArgs, directory);
|
|
37900
38188
|
} catch {
|
|
37901
38189
|
return JSON.stringify({ success: false, phase: rawPhase, message: "Invalid arguments" }, null, 2);
|
|
37902
38190
|
}
|
|
37903
38191
|
}
|
|
37904
38192
|
});
|
|
37905
|
-
|
|
38193
|
+
_internals10 = {
|
|
37906
38194
|
executeWriteRetro,
|
|
37907
38195
|
write_retro
|
|
37908
38196
|
};
|
|
@@ -38193,6 +38481,12 @@ async function handleCloseCommand(directory, args, options = {}) {
|
|
|
38193
38481
|
}
|
|
38194
38482
|
}
|
|
38195
38483
|
if (planExists) {
|
|
38484
|
+
const originalStatuses = new Map;
|
|
38485
|
+
for (const phase of planData.phases ?? []) {
|
|
38486
|
+
for (const task of phase.tasks ?? []) {
|
|
38487
|
+
originalStatuses.set(task.id, task.status);
|
|
38488
|
+
}
|
|
38489
|
+
}
|
|
38196
38490
|
const guaranteeResult = guaranteeAllPlansComplete(planData);
|
|
38197
38491
|
for (const phaseId of guaranteeResult.closedPhaseIds) {
|
|
38198
38492
|
if (!closedPhases.includes(phaseId)) {
|
|
@@ -38206,11 +38500,15 @@ async function handleCloseCommand(directory, args, options = {}) {
|
|
|
38206
38500
|
}
|
|
38207
38501
|
if (!planAlreadyDone || guaranteeResult.closedPhaseIds.length > 0 || guaranteeResult.closedTaskIds.length > 0) {
|
|
38208
38502
|
try {
|
|
38209
|
-
await
|
|
38503
|
+
await closePlanTerminalState(directory, planData, {
|
|
38504
|
+
closedPhaseIds: guaranteeResult.closedPhaseIds,
|
|
38505
|
+
closedTaskIds: guaranteeResult.closedTaskIds,
|
|
38506
|
+
originalStatuses
|
|
38507
|
+
});
|
|
38210
38508
|
} catch (error93) {
|
|
38211
38509
|
const msg = error93 instanceof Error ? error93.message : String(error93);
|
|
38212
|
-
warnings.push(`Failed to persist terminal plan
|
|
38213
|
-
console.warn("[close-command] Failed to write plan
|
|
38510
|
+
warnings.push(`Failed to persist terminal plan state: ${msg}`);
|
|
38511
|
+
console.warn("[close-command] Failed to write terminal plan state:", error93);
|
|
38214
38512
|
}
|
|
38215
38513
|
}
|
|
38216
38514
|
}
|
|
@@ -38498,6 +38796,7 @@ var init_close = __esm(() => {
|
|
|
38498
38796
|
init_knowledge_curator();
|
|
38499
38797
|
init_knowledge_store();
|
|
38500
38798
|
init_utils2();
|
|
38799
|
+
init_manager();
|
|
38501
38800
|
init_scope_persistence();
|
|
38502
38801
|
init_skill_improver();
|
|
38503
38802
|
init_state();
|
|
@@ -38724,14 +39023,16 @@ async function parseGitLog(directory, maxCommits) {
|
|
|
38724
39023
|
}
|
|
38725
39024
|
return commitMap;
|
|
38726
39025
|
}
|
|
38727
|
-
function buildCoChangeMatrix(commitMap) {
|
|
39026
|
+
function buildCoChangeMatrix(commitMap, maxFilesPerCommit = 500) {
|
|
38728
39027
|
const matrix = new Map;
|
|
38729
39028
|
const fileCommitCount = new Map;
|
|
38730
39029
|
for (const files of commitMap.values()) {
|
|
38731
|
-
const
|
|
38732
|
-
for (const file3 of fileArray) {
|
|
39030
|
+
for (const file3 of files) {
|
|
38733
39031
|
fileCommitCount.set(file3, (fileCommitCount.get(file3) || 0) + 1);
|
|
38734
39032
|
}
|
|
39033
|
+
if (files.size > maxFilesPerCommit)
|
|
39034
|
+
continue;
|
|
39035
|
+
const fileArray = Array.from(files).sort();
|
|
38735
39036
|
for (let i = 0;i < fileArray.length; i++) {
|
|
38736
39037
|
for (let j = i + 1;j < fileArray.length; j++) {
|
|
38737
39038
|
const fileA = fileArray[i];
|
|
@@ -38894,6 +39195,7 @@ async function detectDarkMatter(directory, options) {
|
|
|
38894
39195
|
const minCoChanges = options?.minCoChanges ?? 3;
|
|
38895
39196
|
const npmiThreshold = options?.npmiThreshold ?? 0.5;
|
|
38896
39197
|
const maxCommitsToAnalyze = options?.maxCommitsToAnalyze ?? 500;
|
|
39198
|
+
const maxFilesPerCommit = options?.maxFilesPerCommit ?? 500;
|
|
38897
39199
|
try {
|
|
38898
39200
|
const { stdout } = await getExecFileAsync()("git", ["rev-list", "--count", "HEAD"], {
|
|
38899
39201
|
cwd: directory,
|
|
@@ -38906,9 +39208,9 @@ async function detectDarkMatter(directory, options) {
|
|
|
38906
39208
|
} catch {
|
|
38907
39209
|
return [];
|
|
38908
39210
|
}
|
|
38909
|
-
const commitMap = await
|
|
38910
|
-
const matrix =
|
|
38911
|
-
const staticEdges = await
|
|
39211
|
+
const commitMap = await _internals11.parseGitLog(directory, maxCommitsToAnalyze);
|
|
39212
|
+
const matrix = _internals11.buildCoChangeMatrix(commitMap, maxFilesPerCommit);
|
|
39213
|
+
const staticEdges = await _internals11.getStaticEdges(directory);
|
|
38912
39214
|
const results = [];
|
|
38913
39215
|
for (const entry of matrix.values()) {
|
|
38914
39216
|
const key = `${entry.fileA}::${entry.fileB}`;
|
|
@@ -38988,7 +39290,7 @@ ${rows}
|
|
|
38988
39290
|
These pairs likely share an architectural concern invisible to static analysis.
|
|
38989
39291
|
Consider adding explicit documentation or extracting the shared concern.`;
|
|
38990
39292
|
}
|
|
38991
|
-
var co_change_analyzer,
|
|
39293
|
+
var co_change_analyzer, _internals11;
|
|
38992
39294
|
var init_co_change_analyzer = __esm(() => {
|
|
38993
39295
|
init_zod();
|
|
38994
39296
|
init_create_tool();
|
|
@@ -39020,11 +39322,11 @@ var init_co_change_analyzer = __esm(() => {
|
|
|
39020
39322
|
npmiThreshold,
|
|
39021
39323
|
maxCommitsToAnalyze
|
|
39022
39324
|
};
|
|
39023
|
-
const pairs = await
|
|
39024
|
-
return
|
|
39325
|
+
const pairs = await _internals11.detectDarkMatter(directory, options);
|
|
39326
|
+
return _internals11.formatDarkMatterOutput(pairs);
|
|
39025
39327
|
}
|
|
39026
39328
|
});
|
|
39027
|
-
|
|
39329
|
+
_internals11 = {
|
|
39028
39330
|
parseGitLog,
|
|
39029
39331
|
buildCoChangeMatrix,
|
|
39030
39332
|
getStaticEdges,
|
|
@@ -39055,7 +39357,7 @@ async function handleDarkMatterCommand(directory, args) {
|
|
|
39055
39357
|
}
|
|
39056
39358
|
let pairs;
|
|
39057
39359
|
try {
|
|
39058
|
-
pairs = await
|
|
39360
|
+
pairs = await _internals11.detectDarkMatter(directory, options);
|
|
39059
39361
|
} catch (err) {
|
|
39060
39362
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
39061
39363
|
return `## Dark Matter Analysis Failed
|
|
@@ -39247,24 +39549,213 @@ function getPluginLockFilePaths() {
|
|
|
39247
39549
|
}
|
|
39248
39550
|
var init_cache_paths = () => {};
|
|
39249
39551
|
|
|
39552
|
+
// src/evidence/task-file.ts
|
|
39553
|
+
import * as path21 from "path";
|
|
39554
|
+
function taskEvidenceRelPath(taskId) {
|
|
39555
|
+
return path21.join("evidence", `${taskId}.json`);
|
|
39556
|
+
}
|
|
39557
|
+
function taskEvidencePath(directory, taskId) {
|
|
39558
|
+
return path21.join(directory, ".swarm", taskEvidenceRelPath(taskId));
|
|
39559
|
+
}
|
|
39560
|
+
var init_task_file = __esm(() => {
|
|
39561
|
+
init_bun_compat();
|
|
39562
|
+
init_lock();
|
|
39563
|
+
});
|
|
39564
|
+
|
|
39565
|
+
// src/gate-evidence.ts
|
|
39566
|
+
import { mkdirSync as mkdirSync7, readFileSync as readFileSync6 } from "fs";
|
|
39567
|
+
function isValidTaskId(taskId) {
|
|
39568
|
+
return isStrictTaskId(taskId);
|
|
39569
|
+
}
|
|
39570
|
+
function assertValidTaskId(taskId) {
|
|
39571
|
+
assertStrictTaskId(taskId);
|
|
39572
|
+
}
|
|
39573
|
+
function getEvidencePath(directory, taskId) {
|
|
39574
|
+
assertValidTaskId(taskId);
|
|
39575
|
+
return taskEvidencePath(directory, taskId);
|
|
39576
|
+
}
|
|
39577
|
+
function readExisting(evidencePath, taskId) {
|
|
39578
|
+
try {
|
|
39579
|
+
const raw = readFileSync6(evidencePath, "utf-8");
|
|
39580
|
+
return TaskEvidenceSchema.parse(JSON.parse(raw));
|
|
39581
|
+
} catch (error93) {
|
|
39582
|
+
if (error93.code === "ENOENT")
|
|
39583
|
+
return null;
|
|
39584
|
+
telemetry.gateParseError(taskId, error93);
|
|
39585
|
+
throw error93;
|
|
39586
|
+
}
|
|
39587
|
+
}
|
|
39588
|
+
async function readTaskEvidence(directory, taskId) {
|
|
39589
|
+
try {
|
|
39590
|
+
assertValidTaskId(taskId);
|
|
39591
|
+
return readExisting(getEvidencePath(directory, taskId), taskId);
|
|
39592
|
+
} catch {
|
|
39593
|
+
return null;
|
|
39594
|
+
}
|
|
39595
|
+
}
|
|
39596
|
+
function readTaskEvidenceRaw(directory, taskId) {
|
|
39597
|
+
assertValidTaskId(taskId);
|
|
39598
|
+
const evidencePath = getEvidencePath(directory, taskId);
|
|
39599
|
+
try {
|
|
39600
|
+
const raw = readFileSync6(evidencePath, "utf-8");
|
|
39601
|
+
return TaskEvidenceSchema.parse(JSON.parse(raw));
|
|
39602
|
+
} catch (error93) {
|
|
39603
|
+
if (error93.code === "ENOENT")
|
|
39604
|
+
return null;
|
|
39605
|
+
throw error93;
|
|
39606
|
+
}
|
|
39607
|
+
}
|
|
39608
|
+
var GateEvidenceSchema, TaskEvidenceSchema;
|
|
39609
|
+
var init_gate_evidence = __esm(() => {
|
|
39610
|
+
init_zod();
|
|
39611
|
+
init_task_file();
|
|
39612
|
+
init_telemetry();
|
|
39613
|
+
init_task_id();
|
|
39614
|
+
GateEvidenceSchema = exports_external.object({
|
|
39615
|
+
sessionId: exports_external.string(),
|
|
39616
|
+
timestamp: exports_external.string(),
|
|
39617
|
+
agent: exports_external.string()
|
|
39618
|
+
}).passthrough();
|
|
39619
|
+
TaskEvidenceSchema = exports_external.object({
|
|
39620
|
+
taskId: exports_external.string(),
|
|
39621
|
+
required_gates: exports_external.array(exports_external.string()).default([]),
|
|
39622
|
+
gates: exports_external.record(exports_external.string(), GateEvidenceSchema),
|
|
39623
|
+
turbo: exports_external.boolean().optional()
|
|
39624
|
+
});
|
|
39625
|
+
});
|
|
39626
|
+
|
|
39627
|
+
// src/evidence/gate-bridge.ts
|
|
39628
|
+
async function readDurableGateEvidence(directory, taskId) {
|
|
39629
|
+
try {
|
|
39630
|
+
return await readTaskEvidence(directory, taskId);
|
|
39631
|
+
} catch {
|
|
39632
|
+
return null;
|
|
39633
|
+
}
|
|
39634
|
+
}
|
|
39635
|
+
function getDurableGateEvidenceStatus(evidence) {
|
|
39636
|
+
if (!evidence?.gates || typeof evidence.gates !== "object") {
|
|
39637
|
+
return {
|
|
39638
|
+
isComplete: false,
|
|
39639
|
+
missingGates: [],
|
|
39640
|
+
evidenceExists: evidence != null,
|
|
39641
|
+
invalid: false
|
|
39642
|
+
};
|
|
39643
|
+
}
|
|
39644
|
+
if (!Array.isArray(evidence.required_gates) || evidence.required_gates.length === 0) {
|
|
39645
|
+
return {
|
|
39646
|
+
isComplete: false,
|
|
39647
|
+
missingGates: ["required_gates"],
|
|
39648
|
+
evidenceExists: true,
|
|
39649
|
+
invalid: false
|
|
39650
|
+
};
|
|
39651
|
+
}
|
|
39652
|
+
const missingGates = evidence.required_gates.filter((gate) => evidence.gates[gate] == null);
|
|
39653
|
+
return {
|
|
39654
|
+
isComplete: missingGates.length === 0,
|
|
39655
|
+
missingGates,
|
|
39656
|
+
evidenceExists: true,
|
|
39657
|
+
invalid: false
|
|
39658
|
+
};
|
|
39659
|
+
}
|
|
39660
|
+
async function getDurableGateEvidenceStatusForTask(directory, taskId) {
|
|
39661
|
+
if (!isValidTaskId(taskId)) {
|
|
39662
|
+
return {
|
|
39663
|
+
isComplete: false,
|
|
39664
|
+
missingGates: [],
|
|
39665
|
+
evidenceExists: false,
|
|
39666
|
+
invalid: false
|
|
39667
|
+
};
|
|
39668
|
+
}
|
|
39669
|
+
try {
|
|
39670
|
+
return getDurableGateEvidenceStatus(readTaskEvidenceRaw(directory, taskId));
|
|
39671
|
+
} catch {
|
|
39672
|
+
return {
|
|
39673
|
+
isComplete: false,
|
|
39674
|
+
missingGates: ["invalid_gate_evidence"],
|
|
39675
|
+
evidenceExists: true,
|
|
39676
|
+
invalid: true
|
|
39677
|
+
};
|
|
39678
|
+
}
|
|
39679
|
+
}
|
|
39680
|
+
function gateEvidenceToEntry(taskId, gate, type, evidence) {
|
|
39681
|
+
const gateRecord = evidence.gates[gate];
|
|
39682
|
+
if (!gateRecord) {
|
|
39683
|
+
return null;
|
|
39684
|
+
}
|
|
39685
|
+
const base = {
|
|
39686
|
+
task_id: taskId,
|
|
39687
|
+
timestamp: gateRecord.timestamp,
|
|
39688
|
+
agent: gateRecord.agent || gate,
|
|
39689
|
+
verdict: "pass",
|
|
39690
|
+
summary: `Gate evidence recorded by ${gate}`,
|
|
39691
|
+
metadata: { source: "durable_gate_evidence", gate }
|
|
39692
|
+
};
|
|
39693
|
+
if (type === "review") {
|
|
39694
|
+
return {
|
|
39695
|
+
...base,
|
|
39696
|
+
type,
|
|
39697
|
+
risk: "low",
|
|
39698
|
+
issues: []
|
|
39699
|
+
};
|
|
39700
|
+
}
|
|
39701
|
+
if (type === "approval") {
|
|
39702
|
+
return {
|
|
39703
|
+
...base,
|
|
39704
|
+
type
|
|
39705
|
+
};
|
|
39706
|
+
}
|
|
39707
|
+
return {
|
|
39708
|
+
...base,
|
|
39709
|
+
type,
|
|
39710
|
+
tests_passed: 0,
|
|
39711
|
+
tests_failed: 0,
|
|
39712
|
+
failures: []
|
|
39713
|
+
};
|
|
39714
|
+
}
|
|
39715
|
+
function mergeDurableGateEntriesFromEvidence(taskId, entries, evidence) {
|
|
39716
|
+
if (!evidence?.gates) {
|
|
39717
|
+
return entries;
|
|
39718
|
+
}
|
|
39719
|
+
const merged = [...entries];
|
|
39720
|
+
for (const gate of Object.keys(evidence.gates).sort()) {
|
|
39721
|
+
const type = GATE_EVIDENCE_TYPE_BY_GATE[gate] ?? "approval";
|
|
39722
|
+
if ((type === "review" || type === "test") && merged.some((entry2) => entry2.type === type)) {
|
|
39723
|
+
continue;
|
|
39724
|
+
}
|
|
39725
|
+
const entry = gateEvidenceToEntry(taskId, gate, type, evidence);
|
|
39726
|
+
if (entry) {
|
|
39727
|
+
merged.push(entry);
|
|
39728
|
+
}
|
|
39729
|
+
}
|
|
39730
|
+
return merged;
|
|
39731
|
+
}
|
|
39732
|
+
var GATE_EVIDENCE_TYPE_BY_GATE;
|
|
39733
|
+
var init_gate_bridge = __esm(() => {
|
|
39734
|
+
init_gate_evidence();
|
|
39735
|
+
GATE_EVIDENCE_TYPE_BY_GATE = {
|
|
39736
|
+
reviewer: "review",
|
|
39737
|
+
test_engineer: "test"
|
|
39738
|
+
};
|
|
39739
|
+
});
|
|
39740
|
+
|
|
39250
39741
|
// src/services/version-check.ts
|
|
39251
|
-
import { existsSync as existsSync11, mkdirSync as
|
|
39742
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
|
|
39252
39743
|
import { homedir as homedir5 } from "os";
|
|
39253
|
-
import { join as
|
|
39744
|
+
import { join as join20 } from "path";
|
|
39254
39745
|
function cacheDir() {
|
|
39255
39746
|
const xdg = process.env.XDG_CACHE_HOME;
|
|
39256
|
-
const base = xdg && xdg.length > 0 ? xdg :
|
|
39257
|
-
return
|
|
39747
|
+
const base = xdg && xdg.length > 0 ? xdg : join20(homedir5(), ".cache");
|
|
39748
|
+
return join20(base, "opencode-swarm");
|
|
39258
39749
|
}
|
|
39259
39750
|
function cacheFile() {
|
|
39260
|
-
return
|
|
39751
|
+
return join20(cacheDir(), "version-check.json");
|
|
39261
39752
|
}
|
|
39262
39753
|
function readVersionCache() {
|
|
39263
39754
|
try {
|
|
39264
|
-
const
|
|
39265
|
-
if (!existsSync11(
|
|
39755
|
+
const path22 = cacheFile();
|
|
39756
|
+
if (!existsSync11(path22))
|
|
39266
39757
|
return null;
|
|
39267
|
-
const raw =
|
|
39758
|
+
const raw = readFileSync7(path22, "utf-8");
|
|
39268
39759
|
const parsed = JSON.parse(raw);
|
|
39269
39760
|
if (typeof parsed?.checkedAt !== "number")
|
|
39270
39761
|
return null;
|
|
@@ -39303,8 +39794,8 @@ var init_version_check = __esm(() => {
|
|
|
39303
39794
|
|
|
39304
39795
|
// src/services/diagnose-service.ts
|
|
39305
39796
|
import * as child_process4 from "child_process";
|
|
39306
|
-
import { existsSync as existsSync12, readdirSync as readdirSync4, readFileSync as
|
|
39307
|
-
import
|
|
39797
|
+
import { existsSync as existsSync12, readdirSync as readdirSync4, readFileSync as readFileSync8, statSync as statSync6 } from "fs";
|
|
39798
|
+
import path22 from "path";
|
|
39308
39799
|
import { fileURLToPath } from "url";
|
|
39309
39800
|
function validateTaskDag(plan) {
|
|
39310
39801
|
const allTaskIds = new Set;
|
|
@@ -39336,7 +39827,21 @@ async function checkEvidenceCompleteness(directory, plan) {
|
|
|
39336
39827
|
}
|
|
39337
39828
|
if (completedTaskIds.length > 0) {
|
|
39338
39829
|
const evidenceTaskIds = new Set(await listEvidenceTaskIds(directory));
|
|
39339
|
-
const missingEvidence =
|
|
39830
|
+
const missingEvidence = [];
|
|
39831
|
+
for (const id of completedTaskIds) {
|
|
39832
|
+
const gateStatus = await getDurableGateEvidenceStatusForTask(directory, id);
|
|
39833
|
+
if (gateStatus.isComplete) {
|
|
39834
|
+
continue;
|
|
39835
|
+
}
|
|
39836
|
+
if (gateStatus.evidenceExists && gateStatus.missingGates.length > 0) {
|
|
39837
|
+
missingEvidence.push(id);
|
|
39838
|
+
continue;
|
|
39839
|
+
}
|
|
39840
|
+
if (evidenceTaskIds.has(id)) {
|
|
39841
|
+
continue;
|
|
39842
|
+
}
|
|
39843
|
+
missingEvidence.push(id);
|
|
39844
|
+
}
|
|
39340
39845
|
if (missingEvidence.length === 0) {
|
|
39341
39846
|
return {
|
|
39342
39847
|
name: "Evidence",
|
|
@@ -39601,7 +40106,7 @@ async function checkSpecStaleness(directory, plan) {
|
|
|
39601
40106
|
};
|
|
39602
40107
|
}
|
|
39603
40108
|
async function checkConfigParseability(directory) {
|
|
39604
|
-
const configPath =
|
|
40109
|
+
const configPath = path22.join(directory, ".opencode/opencode-swarm.json");
|
|
39605
40110
|
if (!existsSync12(configPath)) {
|
|
39606
40111
|
return {
|
|
39607
40112
|
name: "Config Parseability",
|
|
@@ -39610,7 +40115,7 @@ async function checkConfigParseability(directory) {
|
|
|
39610
40115
|
};
|
|
39611
40116
|
}
|
|
39612
40117
|
try {
|
|
39613
|
-
const content =
|
|
40118
|
+
const content = readFileSync8(configPath, "utf-8");
|
|
39614
40119
|
JSON.parse(content);
|
|
39615
40120
|
return {
|
|
39616
40121
|
name: "Config Parseability",
|
|
@@ -39630,7 +40135,7 @@ function resolveGrammarDir(thisDir) {
|
|
|
39630
40135
|
const normalized = thisDir.replace(/\\/g, "/");
|
|
39631
40136
|
const isSource = normalized.endsWith("/src/services");
|
|
39632
40137
|
const isCliBundle = normalized.endsWith("/cli");
|
|
39633
|
-
return isSource || isCliBundle ?
|
|
40138
|
+
return isSource || isCliBundle ? path22.join(thisDir, "..", "lang", "grammars") : path22.join(thisDir, "lang", "grammars");
|
|
39634
40139
|
}
|
|
39635
40140
|
async function checkGrammarWasmFiles() {
|
|
39636
40141
|
const grammarFiles = [
|
|
@@ -39654,14 +40159,14 @@ async function checkGrammarWasmFiles() {
|
|
|
39654
40159
|
"tree-sitter-ini.wasm",
|
|
39655
40160
|
"tree-sitter-regex.wasm"
|
|
39656
40161
|
];
|
|
39657
|
-
const thisDir =
|
|
40162
|
+
const thisDir = path22.dirname(fileURLToPath(import.meta.url));
|
|
39658
40163
|
const grammarDir = resolveGrammarDir(thisDir);
|
|
39659
40164
|
const missing = [];
|
|
39660
|
-
if (!existsSync12(
|
|
40165
|
+
if (!existsSync12(path22.join(grammarDir, "tree-sitter.wasm"))) {
|
|
39661
40166
|
missing.push("tree-sitter.wasm (core runtime)");
|
|
39662
40167
|
}
|
|
39663
40168
|
for (const file3 of grammarFiles) {
|
|
39664
|
-
if (!existsSync12(
|
|
40169
|
+
if (!existsSync12(path22.join(grammarDir, file3))) {
|
|
39665
40170
|
missing.push(file3);
|
|
39666
40171
|
}
|
|
39667
40172
|
}
|
|
@@ -39679,7 +40184,7 @@ async function checkGrammarWasmFiles() {
|
|
|
39679
40184
|
};
|
|
39680
40185
|
}
|
|
39681
40186
|
async function checkCheckpointManifest(directory) {
|
|
39682
|
-
const manifestPath =
|
|
40187
|
+
const manifestPath = path22.join(directory, ".swarm/checkpoints.json");
|
|
39683
40188
|
if (!existsSync12(manifestPath)) {
|
|
39684
40189
|
return {
|
|
39685
40190
|
name: "Checkpoint Manifest",
|
|
@@ -39688,7 +40193,7 @@ async function checkCheckpointManifest(directory) {
|
|
|
39688
40193
|
};
|
|
39689
40194
|
}
|
|
39690
40195
|
try {
|
|
39691
|
-
const content =
|
|
40196
|
+
const content = readFileSync8(manifestPath, "utf-8");
|
|
39692
40197
|
const parsed = JSON.parse(content);
|
|
39693
40198
|
if (!parsed.checkpoints || !Array.isArray(parsed.checkpoints)) {
|
|
39694
40199
|
return {
|
|
@@ -39731,7 +40236,7 @@ async function checkCheckpointManifest(directory) {
|
|
|
39731
40236
|
}
|
|
39732
40237
|
}
|
|
39733
40238
|
async function checkEventStreamIntegrity(directory) {
|
|
39734
|
-
const eventsPath =
|
|
40239
|
+
const eventsPath = path22.join(directory, ".swarm/events.jsonl");
|
|
39735
40240
|
if (!existsSync12(eventsPath)) {
|
|
39736
40241
|
return {
|
|
39737
40242
|
name: "Event Stream",
|
|
@@ -39740,7 +40245,7 @@ async function checkEventStreamIntegrity(directory) {
|
|
|
39740
40245
|
};
|
|
39741
40246
|
}
|
|
39742
40247
|
try {
|
|
39743
|
-
const content =
|
|
40248
|
+
const content = readFileSync8(eventsPath, "utf-8");
|
|
39744
40249
|
const lines = content.split(`
|
|
39745
40250
|
`).filter((line) => line.trim() !== "");
|
|
39746
40251
|
let malformedCount = 0;
|
|
@@ -39772,7 +40277,7 @@ async function checkEventStreamIntegrity(directory) {
|
|
|
39772
40277
|
}
|
|
39773
40278
|
}
|
|
39774
40279
|
async function checkSteeringDirectives(directory) {
|
|
39775
|
-
const eventsPath =
|
|
40280
|
+
const eventsPath = path22.join(directory, ".swarm/events.jsonl");
|
|
39776
40281
|
if (!existsSync12(eventsPath)) {
|
|
39777
40282
|
return {
|
|
39778
40283
|
name: "Steering Directives",
|
|
@@ -39781,7 +40286,7 @@ async function checkSteeringDirectives(directory) {
|
|
|
39781
40286
|
};
|
|
39782
40287
|
}
|
|
39783
40288
|
try {
|
|
39784
|
-
const content =
|
|
40289
|
+
const content = readFileSync8(eventsPath, "utf-8");
|
|
39785
40290
|
const lines = content.split(`
|
|
39786
40291
|
`).filter((line) => line.trim() !== "");
|
|
39787
40292
|
const directivesIssued = [];
|
|
@@ -39828,7 +40333,7 @@ async function checkCurator(directory) {
|
|
|
39828
40333
|
detail: "Disabled (enable via curator.enabled)"
|
|
39829
40334
|
};
|
|
39830
40335
|
}
|
|
39831
|
-
const summaryPath =
|
|
40336
|
+
const summaryPath = path22.join(directory, ".swarm/curator-summary.json");
|
|
39832
40337
|
if (!existsSync12(summaryPath)) {
|
|
39833
40338
|
return {
|
|
39834
40339
|
name: "Curator",
|
|
@@ -39837,7 +40342,7 @@ async function checkCurator(directory) {
|
|
|
39837
40342
|
};
|
|
39838
40343
|
}
|
|
39839
40344
|
try {
|
|
39840
|
-
const content =
|
|
40345
|
+
const content = readFileSync8(summaryPath, "utf-8");
|
|
39841
40346
|
const parsed = JSON.parse(content);
|
|
39842
40347
|
if (typeof parsed.schema_version !== "number" || parsed.schema_version !== 1) {
|
|
39843
40348
|
return {
|
|
@@ -39994,7 +40499,7 @@ async function getDiagnoseData(directory) {
|
|
|
39994
40499
|
checks5.push(await checkSteeringDirectives(directory));
|
|
39995
40500
|
checks5.push(await checkCurator(directory));
|
|
39996
40501
|
try {
|
|
39997
|
-
const evidenceDir =
|
|
40502
|
+
const evidenceDir = path22.join(directory, ".swarm", "evidence");
|
|
39998
40503
|
const snapshotFiles = existsSync12(evidenceDir) ? readdirSync4(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
|
|
39999
40504
|
if (snapshotFiles.length > 0) {
|
|
40000
40505
|
const latest = snapshotFiles.sort().pop();
|
|
@@ -40032,9 +40537,9 @@ async function getDiagnoseData(directory) {
|
|
|
40032
40537
|
cacheRows.push(`\u2B1C ${cachePath} \u2014 absent`);
|
|
40033
40538
|
continue;
|
|
40034
40539
|
}
|
|
40035
|
-
const pkgJsonPath =
|
|
40540
|
+
const pkgJsonPath = path22.join(cachePath, "package.json");
|
|
40036
40541
|
try {
|
|
40037
|
-
const raw =
|
|
40542
|
+
const raw = readFileSync8(pkgJsonPath, "utf-8");
|
|
40038
40543
|
const parsed = JSON.parse(raw);
|
|
40039
40544
|
const installedVersion = typeof parsed.version === "string" ? parsed.version : "?";
|
|
40040
40545
|
cacheRows.push(`\u2705 ${cachePath} \u2014 v${installedVersion}`);
|
|
@@ -40091,6 +40596,7 @@ var init_diagnose_service = __esm(() => {
|
|
|
40091
40596
|
init_package();
|
|
40092
40597
|
init_cache_paths();
|
|
40093
40598
|
init_loader();
|
|
40599
|
+
init_gate_bridge();
|
|
40094
40600
|
init_manager2();
|
|
40095
40601
|
init_utils2();
|
|
40096
40602
|
init_manager();
|
|
@@ -40122,13 +40628,13 @@ __export(exports_config_doctor, {
|
|
|
40122
40628
|
import * as crypto3 from "crypto";
|
|
40123
40629
|
import * as fs8 from "fs";
|
|
40124
40630
|
import * as os6 from "os";
|
|
40125
|
-
import * as
|
|
40631
|
+
import * as path23 from "path";
|
|
40126
40632
|
function getUserConfigDir3() {
|
|
40127
|
-
return process.env.XDG_CONFIG_HOME ||
|
|
40633
|
+
return process.env.XDG_CONFIG_HOME || path23.join(os6.homedir(), ".config");
|
|
40128
40634
|
}
|
|
40129
40635
|
function getConfigPaths(directory) {
|
|
40130
|
-
const userConfigPath =
|
|
40131
|
-
const projectConfigPath =
|
|
40636
|
+
const userConfigPath = path23.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
|
|
40637
|
+
const projectConfigPath = path23.join(directory, ".opencode", "opencode-swarm.json");
|
|
40132
40638
|
return { userConfigPath, projectConfigPath };
|
|
40133
40639
|
}
|
|
40134
40640
|
function computeHash(content) {
|
|
@@ -40153,9 +40659,9 @@ function isValidConfigPath(configPath, directory) {
|
|
|
40153
40659
|
const normalizedUser = userConfigPath.replace(/\\/g, "/");
|
|
40154
40660
|
const normalizedProject = projectConfigPath.replace(/\\/g, "/");
|
|
40155
40661
|
try {
|
|
40156
|
-
const resolvedConfig =
|
|
40157
|
-
const resolvedUser =
|
|
40158
|
-
const resolvedProject =
|
|
40662
|
+
const resolvedConfig = path23.resolve(configPath);
|
|
40663
|
+
const resolvedUser = path23.resolve(normalizedUser);
|
|
40664
|
+
const resolvedProject = path23.resolve(normalizedProject);
|
|
40159
40665
|
return resolvedConfig === resolvedUser || resolvedConfig === resolvedProject;
|
|
40160
40666
|
} catch {
|
|
40161
40667
|
return false;
|
|
@@ -40195,12 +40701,12 @@ function createConfigBackup(directory) {
|
|
|
40195
40701
|
};
|
|
40196
40702
|
}
|
|
40197
40703
|
function writeBackupArtifact(directory, backup) {
|
|
40198
|
-
const swarmDir =
|
|
40704
|
+
const swarmDir = path23.join(directory, ".swarm");
|
|
40199
40705
|
if (!fs8.existsSync(swarmDir)) {
|
|
40200
40706
|
fs8.mkdirSync(swarmDir, { recursive: true });
|
|
40201
40707
|
}
|
|
40202
40708
|
const backupFilename = `config-backup-${backup.createdAt}.json`;
|
|
40203
|
-
const backupPath =
|
|
40709
|
+
const backupPath = path23.join(swarmDir, backupFilename);
|
|
40204
40710
|
const artifact = {
|
|
40205
40711
|
createdAt: backup.createdAt,
|
|
40206
40712
|
configPath: backup.configPath,
|
|
@@ -40230,7 +40736,7 @@ function restoreFromBackup(backupPath, directory) {
|
|
|
40230
40736
|
return null;
|
|
40231
40737
|
}
|
|
40232
40738
|
const targetPath = artifact.configPath;
|
|
40233
|
-
const targetDir =
|
|
40739
|
+
const targetDir = path23.dirname(targetPath);
|
|
40234
40740
|
if (!fs8.existsSync(targetDir)) {
|
|
40235
40741
|
fs8.mkdirSync(targetDir, { recursive: true });
|
|
40236
40742
|
}
|
|
@@ -40261,9 +40767,9 @@ function readConfigFromFile(directory) {
|
|
|
40261
40767
|
return null;
|
|
40262
40768
|
}
|
|
40263
40769
|
}
|
|
40264
|
-
function validateConfigKey(
|
|
40770
|
+
function validateConfigKey(path24, value, _config) {
|
|
40265
40771
|
const findings = [];
|
|
40266
|
-
switch (
|
|
40772
|
+
switch (path24) {
|
|
40267
40773
|
case "agents": {
|
|
40268
40774
|
if (value !== undefined) {
|
|
40269
40775
|
findings.push({
|
|
@@ -40500,27 +41006,27 @@ function validateConfigKey(path23, value, _config) {
|
|
|
40500
41006
|
}
|
|
40501
41007
|
return findings;
|
|
40502
41008
|
}
|
|
40503
|
-
function walkConfigAndValidate(obj,
|
|
41009
|
+
function walkConfigAndValidate(obj, path24, config3, findings) {
|
|
40504
41010
|
if (obj === null || obj === undefined) {
|
|
40505
41011
|
return;
|
|
40506
41012
|
}
|
|
40507
|
-
if (
|
|
40508
|
-
const keyFindings = validateConfigKey(
|
|
41013
|
+
if (path24 && typeof obj === "object" && !Array.isArray(obj)) {
|
|
41014
|
+
const keyFindings = validateConfigKey(path24, obj, config3);
|
|
40509
41015
|
findings.push(...keyFindings);
|
|
40510
41016
|
}
|
|
40511
41017
|
if (typeof obj !== "object") {
|
|
40512
|
-
const keyFindings = validateConfigKey(
|
|
41018
|
+
const keyFindings = validateConfigKey(path24, obj, config3);
|
|
40513
41019
|
findings.push(...keyFindings);
|
|
40514
41020
|
return;
|
|
40515
41021
|
}
|
|
40516
41022
|
if (Array.isArray(obj)) {
|
|
40517
41023
|
obj.forEach((item, index) => {
|
|
40518
|
-
walkConfigAndValidate(item, `${
|
|
41024
|
+
walkConfigAndValidate(item, `${path24}[${index}]`, config3, findings);
|
|
40519
41025
|
});
|
|
40520
41026
|
return;
|
|
40521
41027
|
}
|
|
40522
41028
|
for (const [key, value] of Object.entries(obj)) {
|
|
40523
|
-
const newPath =
|
|
41029
|
+
const newPath = path24 ? `${path24}.${key}` : key;
|
|
40524
41030
|
walkConfigAndValidate(value, newPath, config3, findings);
|
|
40525
41031
|
}
|
|
40526
41032
|
}
|
|
@@ -40640,7 +41146,7 @@ function applySafeAutoFixes(directory, result) {
|
|
|
40640
41146
|
}
|
|
40641
41147
|
}
|
|
40642
41148
|
if (appliedFixes.length > 0) {
|
|
40643
|
-
const configDir =
|
|
41149
|
+
const configDir = path23.dirname(configPath);
|
|
40644
41150
|
if (!fs8.existsSync(configDir)) {
|
|
40645
41151
|
fs8.mkdirSync(configDir, { recursive: true });
|
|
40646
41152
|
}
|
|
@@ -40650,12 +41156,12 @@ function applySafeAutoFixes(directory, result) {
|
|
|
40650
41156
|
return { appliedFixes, updatedConfigPath };
|
|
40651
41157
|
}
|
|
40652
41158
|
function writeDoctorArtifact(directory, result) {
|
|
40653
|
-
const swarmDir =
|
|
41159
|
+
const swarmDir = path23.join(directory, ".swarm");
|
|
40654
41160
|
if (!fs8.existsSync(swarmDir)) {
|
|
40655
41161
|
fs8.mkdirSync(swarmDir, { recursive: true });
|
|
40656
41162
|
}
|
|
40657
41163
|
const artifactFilename = "config-doctor.json";
|
|
40658
|
-
const artifactPath =
|
|
41164
|
+
const artifactPath = path23.join(swarmDir, artifactFilename);
|
|
40659
41165
|
const guiOutput = {
|
|
40660
41166
|
timestamp: result.timestamp,
|
|
40661
41167
|
summary: result.summary,
|
|
@@ -40751,17 +41257,17 @@ function detectStraySwarmDirs(projectRoot) {
|
|
|
40751
41257
|
if (!entry.isDirectory())
|
|
40752
41258
|
continue;
|
|
40753
41259
|
const name = entry.name;
|
|
40754
|
-
const fullPath =
|
|
41260
|
+
const fullPath = path23.join(dir, name);
|
|
40755
41261
|
if (SKIP_DIRS.has(name))
|
|
40756
41262
|
continue;
|
|
40757
|
-
const gitPath =
|
|
41263
|
+
const gitPath = path23.join(fullPath, ".git");
|
|
40758
41264
|
try {
|
|
40759
41265
|
const gitStat = fs8.statSync(gitPath);
|
|
40760
41266
|
if (gitStat.isFile() || gitStat.isDirectory())
|
|
40761
41267
|
continue;
|
|
40762
41268
|
} catch {}
|
|
40763
41269
|
if (name === ".swarm") {
|
|
40764
|
-
const parentDir =
|
|
41270
|
+
const parentDir = path23.dirname(fullPath);
|
|
40765
41271
|
if (parentDir === projectRoot)
|
|
40766
41272
|
continue;
|
|
40767
41273
|
let contents = [];
|
|
@@ -40771,7 +41277,7 @@ function detectStraySwarmDirs(projectRoot) {
|
|
|
40771
41277
|
contents = ["<unreadable>"];
|
|
40772
41278
|
}
|
|
40773
41279
|
findings.push({
|
|
40774
|
-
path:
|
|
41280
|
+
path: path23.relative(projectRoot, fullPath).replace(/\\/g, "/"),
|
|
40775
41281
|
absolutePath: fullPath,
|
|
40776
41282
|
contents: contents.slice(0, MAX_CONTENTS_ENTRIES),
|
|
40777
41283
|
totalEntries: contents.length
|
|
@@ -40789,21 +41295,21 @@ function removeStraySwarmDir(projectRoot, strayPath) {
|
|
|
40789
41295
|
let canonicalStray;
|
|
40790
41296
|
try {
|
|
40791
41297
|
canonicalRoot = fs8.realpathSync(projectRoot);
|
|
40792
|
-
canonicalStray = fs8.realpathSync(
|
|
41298
|
+
canonicalStray = fs8.realpathSync(path23.isAbsolute(strayPath) ? strayPath : path23.resolve(projectRoot, strayPath));
|
|
40793
41299
|
} catch (err) {
|
|
40794
41300
|
return {
|
|
40795
41301
|
success: false,
|
|
40796
41302
|
message: `Failed to resolve paths: ${err instanceof Error ? err.message : String(err)}`
|
|
40797
41303
|
};
|
|
40798
41304
|
}
|
|
40799
|
-
const rootSwarm =
|
|
41305
|
+
const rootSwarm = path23.join(canonicalRoot, ".swarm");
|
|
40800
41306
|
if (canonicalStray === rootSwarm || canonicalStray === canonicalRoot) {
|
|
40801
41307
|
return {
|
|
40802
41308
|
success: false,
|
|
40803
41309
|
message: "Refusing to remove root .swarm/ directory"
|
|
40804
41310
|
};
|
|
40805
41311
|
}
|
|
40806
|
-
if (!canonicalStray.startsWith(canonicalRoot +
|
|
41312
|
+
if (!canonicalStray.startsWith(canonicalRoot + path23.sep)) {
|
|
40807
41313
|
return {
|
|
40808
41314
|
success: false,
|
|
40809
41315
|
message: "Path is outside project root \u2014 refusing to remove"
|
|
@@ -41892,7 +42398,7 @@ var init_profiles = __esm(() => {
|
|
|
41892
42398
|
|
|
41893
42399
|
// src/lang/detector.ts
|
|
41894
42400
|
import { access as access3, readdir as readdir2 } from "fs/promises";
|
|
41895
|
-
import { extname as extname2, join as
|
|
42401
|
+
import { extname as extname2, join as join22 } from "path";
|
|
41896
42402
|
async function detectProjectLanguages(projectDir) {
|
|
41897
42403
|
const detected = new Set;
|
|
41898
42404
|
async function scanDir(dir) {
|
|
@@ -41908,7 +42414,7 @@ async function detectProjectLanguages(projectDir) {
|
|
|
41908
42414
|
if (detectFile.includes("*") || detectFile.includes("?"))
|
|
41909
42415
|
continue;
|
|
41910
42416
|
try {
|
|
41911
|
-
await access3(
|
|
42417
|
+
await access3(join22(dir, detectFile));
|
|
41912
42418
|
detected.add(profile.id);
|
|
41913
42419
|
break;
|
|
41914
42420
|
} catch {}
|
|
@@ -41929,7 +42435,7 @@ async function detectProjectLanguages(projectDir) {
|
|
|
41929
42435
|
const topEntries = await readdir2(projectDir, { withFileTypes: true });
|
|
41930
42436
|
for (const entry of topEntries) {
|
|
41931
42437
|
if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
41932
|
-
await scanDir(
|
|
42438
|
+
await scanDir(join22(projectDir, entry.name));
|
|
41933
42439
|
}
|
|
41934
42440
|
}
|
|
41935
42441
|
} catch {}
|
|
@@ -41948,7 +42454,7 @@ var init_detector = __esm(() => {
|
|
|
41948
42454
|
|
|
41949
42455
|
// src/build/discovery.ts
|
|
41950
42456
|
import * as fs9 from "fs";
|
|
41951
|
-
import * as
|
|
42457
|
+
import * as path24 from "path";
|
|
41952
42458
|
function isCommandAvailable(command) {
|
|
41953
42459
|
if (toolchainCache.has(command)) {
|
|
41954
42460
|
return toolchainCache.get(command);
|
|
@@ -41956,7 +42462,7 @@ function isCommandAvailable(command) {
|
|
|
41956
42462
|
const isWindows = process.platform === "win32";
|
|
41957
42463
|
const cmd = isWindows ? `${command}.exe` : command;
|
|
41958
42464
|
try {
|
|
41959
|
-
const result =
|
|
42465
|
+
const result = _internals12.spawnSyncImpl(isWindows ? ["where", cmd] : ["which", cmd], {
|
|
41960
42466
|
cwd: process.cwd(),
|
|
41961
42467
|
stdin: "ignore",
|
|
41962
42468
|
stdout: "ignore",
|
|
@@ -41983,11 +42489,11 @@ function findBuildFiles(workingDir, patterns) {
|
|
|
41983
42489
|
const regex = simpleGlobToRegex(pattern);
|
|
41984
42490
|
const matches = files.filter((f) => regex.test(f));
|
|
41985
42491
|
if (matches.length > 0) {
|
|
41986
|
-
return
|
|
42492
|
+
return path24.join(dir, matches[0]);
|
|
41987
42493
|
}
|
|
41988
42494
|
} catch {}
|
|
41989
42495
|
} else {
|
|
41990
|
-
const filePath =
|
|
42496
|
+
const filePath = path24.join(workingDir, pattern);
|
|
41991
42497
|
if (fs9.existsSync(filePath)) {
|
|
41992
42498
|
return filePath;
|
|
41993
42499
|
}
|
|
@@ -41996,7 +42502,7 @@ function findBuildFiles(workingDir, patterns) {
|
|
|
41996
42502
|
return null;
|
|
41997
42503
|
}
|
|
41998
42504
|
function getRepoDefinedScripts(workingDir, scripts) {
|
|
41999
|
-
const packageJsonPath =
|
|
42505
|
+
const packageJsonPath = path24.join(workingDir, "package.json");
|
|
42000
42506
|
if (!fs9.existsSync(packageJsonPath)) {
|
|
42001
42507
|
return [];
|
|
42002
42508
|
}
|
|
@@ -42037,7 +42543,7 @@ function findAllBuildFiles(workingDir) {
|
|
|
42037
42543
|
const regex = simpleGlobToRegex(pattern);
|
|
42038
42544
|
findFilesRecursive(workingDir, regex, allBuildFiles);
|
|
42039
42545
|
} else {
|
|
42040
|
-
const filePath =
|
|
42546
|
+
const filePath = path24.join(workingDir, pattern);
|
|
42041
42547
|
if (fs9.existsSync(filePath)) {
|
|
42042
42548
|
allBuildFiles.add(filePath);
|
|
42043
42549
|
}
|
|
@@ -42050,7 +42556,7 @@ function findFilesRecursive(dir, regex, results) {
|
|
|
42050
42556
|
try {
|
|
42051
42557
|
const entries = fs9.readdirSync(dir, { withFileTypes: true });
|
|
42052
42558
|
for (const entry of entries) {
|
|
42053
|
-
const fullPath =
|
|
42559
|
+
const fullPath = path24.join(dir, entry.name);
|
|
42054
42560
|
if (entry.isDirectory() && !["node_modules", ".git", "dist", "build", "target"].includes(entry.name)) {
|
|
42055
42561
|
findFilesRecursive(fullPath, regex, results);
|
|
42056
42562
|
} else if (entry.isFile() && regex.test(entry.name)) {
|
|
@@ -42073,7 +42579,7 @@ async function discoverBuildCommandsFromProfiles(workingDir) {
|
|
|
42073
42579
|
let foundCommand = false;
|
|
42074
42580
|
for (const cmd of sortedCommands) {
|
|
42075
42581
|
if (cmd.detectFile) {
|
|
42076
|
-
const detectFilePath =
|
|
42582
|
+
const detectFilePath = path24.join(workingDir, cmd.detectFile);
|
|
42077
42583
|
if (!fs9.existsSync(detectFilePath)) {
|
|
42078
42584
|
continue;
|
|
42079
42585
|
}
|
|
@@ -42106,7 +42612,7 @@ async function discoverBuildCommands(workingDir, options) {
|
|
|
42106
42612
|
const scope = options?.scope ?? "all";
|
|
42107
42613
|
const changedFiles = options?.changedFiles ?? [];
|
|
42108
42614
|
const _filesToCheck = filterByScope(workingDir, scope, changedFiles);
|
|
42109
|
-
const profileResult = await
|
|
42615
|
+
const profileResult = await _internals12.discoverBuildCommandsFromProfiles(workingDir);
|
|
42110
42616
|
const profileCommands = profileResult.commands;
|
|
42111
42617
|
const profileSkipped = profileResult.skipped;
|
|
42112
42618
|
const coveredEcosystems = new Set;
|
|
@@ -42169,7 +42675,7 @@ function clearToolchainCache() {
|
|
|
42169
42675
|
function getEcosystems() {
|
|
42170
42676
|
return ECOSYSTEMS.map((e) => e.ecosystem);
|
|
42171
42677
|
}
|
|
42172
|
-
var ECOSYSTEMS, PROFILE_TO_ECOSYSTEM_NAMES, toolchainCache, IS_COMMAND_AVAILABLE_TIMEOUT_MS = 3000,
|
|
42678
|
+
var ECOSYSTEMS, PROFILE_TO_ECOSYSTEM_NAMES, toolchainCache, IS_COMMAND_AVAILABLE_TIMEOUT_MS = 3000, _internals12, build_discovery;
|
|
42173
42679
|
var init_discovery = __esm(() => {
|
|
42174
42680
|
init_dist();
|
|
42175
42681
|
init_detector();
|
|
@@ -42287,7 +42793,7 @@ var init_discovery = __esm(() => {
|
|
|
42287
42793
|
php: ["php-composer"]
|
|
42288
42794
|
};
|
|
42289
42795
|
toolchainCache = new Map;
|
|
42290
|
-
|
|
42796
|
+
_internals12 = {
|
|
42291
42797
|
isCommandAvailable,
|
|
42292
42798
|
discoverBuildCommandsFromProfiles,
|
|
42293
42799
|
discoverBuildCommands,
|
|
@@ -42314,7 +42820,7 @@ var init_discovery = __esm(() => {
|
|
|
42314
42820
|
|
|
42315
42821
|
// src/services/tool-doctor.ts
|
|
42316
42822
|
import * as fs10 from "fs";
|
|
42317
|
-
import * as
|
|
42823
|
+
import * as path25 from "path";
|
|
42318
42824
|
function extractRegisteredToolKeys(indexPath) {
|
|
42319
42825
|
const registeredKeys = new Set;
|
|
42320
42826
|
try {
|
|
@@ -42369,8 +42875,8 @@ function checkBinaryReadiness() {
|
|
|
42369
42875
|
}
|
|
42370
42876
|
function runToolDoctor(_directory, pluginRoot) {
|
|
42371
42877
|
const findings = [];
|
|
42372
|
-
const resolvedPluginRoot = pluginRoot ??
|
|
42373
|
-
const indexPath =
|
|
42878
|
+
const resolvedPluginRoot = pluginRoot ?? path25.resolve(import.meta.dir, "..", "..");
|
|
42879
|
+
const indexPath = path25.join(resolvedPluginRoot, "src", "index.ts");
|
|
42374
42880
|
if (!fs10.existsSync(indexPath)) {
|
|
42375
42881
|
return {
|
|
42376
42882
|
findings: [
|
|
@@ -42590,7 +43096,7 @@ var exports_evidence_summary_service = {};
|
|
|
42590
43096
|
__export(exports_evidence_summary_service, {
|
|
42591
43097
|
isAutoSummaryEnabled: () => isAutoSummaryEnabled,
|
|
42592
43098
|
buildEvidenceSummary: () => buildEvidenceSummary,
|
|
42593
|
-
_internals: () =>
|
|
43099
|
+
_internals: () => _internals13,
|
|
42594
43100
|
REQUIRED_EVIDENCE_TYPES: () => REQUIRED_EVIDENCE_TYPES,
|
|
42595
43101
|
EVIDENCE_SUMMARY_VERSION: () => EVIDENCE_SUMMARY_VERSION
|
|
42596
43102
|
});
|
|
@@ -42628,14 +43134,13 @@ function getTaskStatus(task, bundle) {
|
|
|
42628
43134
|
if (task?.status) {
|
|
42629
43135
|
return task.status;
|
|
42630
43136
|
}
|
|
42631
|
-
const entries =
|
|
43137
|
+
const entries = _internals13.normalizeBundleEntries(bundle);
|
|
42632
43138
|
if (entries.length > 0) {
|
|
42633
43139
|
return "completed";
|
|
42634
43140
|
}
|
|
42635
43141
|
return "pending";
|
|
42636
43142
|
}
|
|
42637
|
-
function
|
|
42638
|
-
const entries = _internals12.normalizeBundleEntries(bundle);
|
|
43143
|
+
function evidenceCompleteFromEntries(entries) {
|
|
42639
43144
|
if (entries.length === 0) {
|
|
42640
43145
|
return {
|
|
42641
43146
|
isComplete: false,
|
|
@@ -42654,6 +43159,9 @@ function isEvidenceComplete(bundle) {
|
|
|
42654
43159
|
missingEvidence: missing
|
|
42655
43160
|
};
|
|
42656
43161
|
}
|
|
43162
|
+
function isEvidenceComplete(bundle) {
|
|
43163
|
+
return evidenceCompleteFromEntries(_internals13.normalizeBundleEntries(bundle));
|
|
43164
|
+
}
|
|
42657
43165
|
function getTaskBlockers(task, summary, status) {
|
|
42658
43166
|
const blockers = [];
|
|
42659
43167
|
if (task?.blocked_reason) {
|
|
@@ -42670,11 +43178,19 @@ function getTaskBlockers(task, summary, status) {
|
|
|
42670
43178
|
async function buildTaskSummary(directory, task, taskId) {
|
|
42671
43179
|
const result = await loadEvidence(directory, taskId);
|
|
42672
43180
|
const bundle = result.status === "found" ? result.bundle : null;
|
|
43181
|
+
const gateEvidence = await readDurableGateEvidence(directory, taskId);
|
|
42673
43182
|
const phase = task?.phase ?? 0;
|
|
42674
|
-
const status =
|
|
42675
|
-
const
|
|
42676
|
-
|
|
42677
|
-
|
|
43183
|
+
const status = _internals13.getTaskStatus(task, bundle);
|
|
43184
|
+
const entries = mergeDurableGateEntriesFromEvidence(taskId, _internals13.normalizeBundleEntries(bundle), gateEvidence);
|
|
43185
|
+
let evidenceCheck = _internals13.evidenceCompleteFromEntries(entries);
|
|
43186
|
+
if (gateEvidence) {
|
|
43187
|
+
const gateStatus = getDurableGateEvidenceStatus(gateEvidence);
|
|
43188
|
+
evidenceCheck = gateStatus.isComplete ? { isComplete: true, missingEvidence: [] } : {
|
|
43189
|
+
isComplete: false,
|
|
43190
|
+
missingEvidence: gateStatus.missingGates.map((gate) => `gate:${gate}`)
|
|
43191
|
+
};
|
|
43192
|
+
}
|
|
43193
|
+
const blockers = _internals13.getTaskBlockers(task, evidenceCheck, status);
|
|
42678
43194
|
const hasReview = entries.some((e) => e.type === "review");
|
|
42679
43195
|
const hasTest = entries.some((e) => e.type === "test");
|
|
42680
43196
|
const hasApproval = entries.some((e) => e.type === "approval");
|
|
@@ -42703,12 +43219,12 @@ async function buildPhaseSummary(directory, phase) {
|
|
|
42703
43219
|
const taskSummaries = [];
|
|
42704
43220
|
const _taskMap = new Map(phase.tasks.map((t) => [t.id, t]));
|
|
42705
43221
|
for (const task of phase.tasks) {
|
|
42706
|
-
const summary = await
|
|
43222
|
+
const summary = await _internals13.buildTaskSummary(directory, task, task.id);
|
|
42707
43223
|
taskSummaries.push(summary);
|
|
42708
43224
|
}
|
|
42709
43225
|
const extraTaskIds = taskIds.filter((id) => !phaseTaskIds.has(id));
|
|
42710
43226
|
for (const taskId of extraTaskIds) {
|
|
42711
|
-
const summary = await
|
|
43227
|
+
const summary = await _internals13.buildTaskSummary(directory, undefined, taskId);
|
|
42712
43228
|
if (summary.phase === phase.id) {
|
|
42713
43229
|
taskSummaries.push(summary);
|
|
42714
43230
|
}
|
|
@@ -42809,7 +43325,7 @@ async function buildEvidenceSummary(directory, currentPhase) {
|
|
|
42809
43325
|
let totalTasks = 0;
|
|
42810
43326
|
let completedTasks = 0;
|
|
42811
43327
|
for (const phase of phasesToProcess) {
|
|
42812
|
-
const summary = await
|
|
43328
|
+
const summary = await _internals13.buildPhaseSummary(directory, phase);
|
|
42813
43329
|
phaseSummaries.push(summary);
|
|
42814
43330
|
totalTasks += summary.totalTasks;
|
|
42815
43331
|
completedTasks += summary.completedTasks;
|
|
@@ -42831,7 +43347,7 @@ async function buildEvidenceSummary(directory, currentPhase) {
|
|
|
42831
43347
|
overallBlockers,
|
|
42832
43348
|
summaryText: ""
|
|
42833
43349
|
};
|
|
42834
|
-
artifact.summaryText =
|
|
43350
|
+
artifact.summaryText = _internals13.generateSummaryText(artifact);
|
|
42835
43351
|
log("[EvidenceSummary] Summary built", {
|
|
42836
43352
|
phases: phaseSummaries.length,
|
|
42837
43353
|
totalTasks,
|
|
@@ -42850,8 +43366,9 @@ function isAutoSummaryEnabled(automationConfig) {
|
|
|
42850
43366
|
}
|
|
42851
43367
|
return automationConfig.capabilities?.evidence_auto_summaries === true;
|
|
42852
43368
|
}
|
|
42853
|
-
var VALID_EVIDENCE_TYPES2, REQUIRED_EVIDENCE_TYPES, EVIDENCE_SUMMARY_VERSION = "1.0.0",
|
|
43369
|
+
var VALID_EVIDENCE_TYPES2, REQUIRED_EVIDENCE_TYPES, EVIDENCE_SUMMARY_VERSION = "1.0.0", _internals13;
|
|
42854
43370
|
var init_evidence_summary_service = __esm(() => {
|
|
43371
|
+
init_gate_bridge();
|
|
42855
43372
|
init_manager2();
|
|
42856
43373
|
init_manager();
|
|
42857
43374
|
init_utils();
|
|
@@ -42864,11 +43381,12 @@ var init_evidence_summary_service = __esm(() => {
|
|
|
42864
43381
|
"retrospective"
|
|
42865
43382
|
]);
|
|
42866
43383
|
REQUIRED_EVIDENCE_TYPES = ["review", "test"];
|
|
42867
|
-
|
|
43384
|
+
_internals13 = {
|
|
42868
43385
|
buildEvidenceSummary,
|
|
42869
43386
|
isAutoSummaryEnabled,
|
|
42870
43387
|
normalizeBundleEntries,
|
|
42871
43388
|
getTaskStatus,
|
|
43389
|
+
evidenceCompleteFromEntries,
|
|
42872
43390
|
isEvidenceComplete,
|
|
42873
43391
|
getTaskBlockers,
|
|
42874
43392
|
buildTaskSummary,
|
|
@@ -42919,7 +43437,7 @@ function getVerdictEmoji(verdict) {
|
|
|
42919
43437
|
return getVerdictIcon(verdict);
|
|
42920
43438
|
}
|
|
42921
43439
|
async function getTaskEvidenceData(directory, taskId) {
|
|
42922
|
-
const result = await
|
|
43440
|
+
const result = await _internals14.loadEvidence(directory, taskId);
|
|
42923
43441
|
if (result.status !== "found") {
|
|
42924
43442
|
return {
|
|
42925
43443
|
hasEvidence: false,
|
|
@@ -42942,13 +43460,13 @@ async function getTaskEvidenceData(directory, taskId) {
|
|
|
42942
43460
|
};
|
|
42943
43461
|
}
|
|
42944
43462
|
async function getEvidenceListData(directory) {
|
|
42945
|
-
const taskIds = await
|
|
43463
|
+
const taskIds = await _internals14.listEvidenceTaskIds(directory);
|
|
42946
43464
|
if (taskIds.length === 0) {
|
|
42947
43465
|
return { hasEvidence: false, tasks: [] };
|
|
42948
43466
|
}
|
|
42949
43467
|
const tasks = [];
|
|
42950
43468
|
for (const taskId of taskIds) {
|
|
42951
|
-
const result = await
|
|
43469
|
+
const result = await _internals14.loadEvidence(directory, taskId);
|
|
42952
43470
|
if (result.status === "found") {
|
|
42953
43471
|
tasks.push({
|
|
42954
43472
|
taskId,
|
|
@@ -43062,10 +43580,10 @@ async function handleEvidenceSummaryCommand(directory) {
|
|
|
43062
43580
|
return lines.join(`
|
|
43063
43581
|
`);
|
|
43064
43582
|
}
|
|
43065
|
-
var
|
|
43583
|
+
var _internals14;
|
|
43066
43584
|
var init_evidence_service = __esm(() => {
|
|
43067
43585
|
init_manager2();
|
|
43068
|
-
|
|
43586
|
+
_internals14 = {
|
|
43069
43587
|
loadEvidence,
|
|
43070
43588
|
listEvidenceTaskIds
|
|
43071
43589
|
};
|
|
@@ -43116,12 +43634,12 @@ var init_export = __esm(() => {
|
|
|
43116
43634
|
|
|
43117
43635
|
// src/full-auto/state.ts
|
|
43118
43636
|
import * as fs11 from "fs";
|
|
43119
|
-
import * as
|
|
43637
|
+
import * as path26 from "path";
|
|
43120
43638
|
function nowISO() {
|
|
43121
43639
|
return new Date().toISOString();
|
|
43122
43640
|
}
|
|
43123
43641
|
function ensureSwarmDir(directory) {
|
|
43124
|
-
const swarmDir =
|
|
43642
|
+
const swarmDir = path26.resolve(directory, ".swarm");
|
|
43125
43643
|
if (!fs11.existsSync(swarmDir)) {
|
|
43126
43644
|
fs11.mkdirSync(swarmDir, { recursive: true });
|
|
43127
43645
|
}
|
|
@@ -43472,7 +43990,7 @@ function extractCurrentPhaseFromPlan2(plan) {
|
|
|
43472
43990
|
if (!plan) {
|
|
43473
43991
|
return { currentPhase: null, currentTask: null, incompleteTasks: [] };
|
|
43474
43992
|
}
|
|
43475
|
-
if (!
|
|
43993
|
+
if (!_internals15.validatePlanPhases(plan)) {
|
|
43476
43994
|
return { currentPhase: null, currentTask: null, incompleteTasks: [] };
|
|
43477
43995
|
}
|
|
43478
43996
|
let currentPhase = null;
|
|
@@ -43614,9 +44132,9 @@ function extractPhaseMetrics(content) {
|
|
|
43614
44132
|
async function getHandoffData(directory) {
|
|
43615
44133
|
const now = new Date().toISOString();
|
|
43616
44134
|
const sessionContent = await readSwarmFileAsync(directory, "session/state.json");
|
|
43617
|
-
const sessionState =
|
|
44135
|
+
const sessionState = _internals15.parseSessionState(sessionContent);
|
|
43618
44136
|
const plan = await loadPlanJsonOnly(directory);
|
|
43619
|
-
const planInfo =
|
|
44137
|
+
const planInfo = _internals15.extractCurrentPhaseFromPlan(plan);
|
|
43620
44138
|
if (!plan) {
|
|
43621
44139
|
const planMdContent = await readSwarmFileAsync(directory, "plan.md");
|
|
43622
44140
|
if (planMdContent) {
|
|
@@ -43635,8 +44153,8 @@ async function getHandoffData(directory) {
|
|
|
43635
44153
|
}
|
|
43636
44154
|
}
|
|
43637
44155
|
const contextContent = await readSwarmFileAsync(directory, "context.md");
|
|
43638
|
-
const recentDecisions =
|
|
43639
|
-
const rawPhaseMetrics =
|
|
44156
|
+
const recentDecisions = _internals15.extractDecisions(contextContent);
|
|
44157
|
+
const rawPhaseMetrics = _internals15.extractPhaseMetrics(contextContent);
|
|
43640
44158
|
const phaseMetrics = sanitizeString(rawPhaseMetrics, 1000);
|
|
43641
44159
|
let delegationState = null;
|
|
43642
44160
|
if (sessionState?.delegationState) {
|
|
@@ -43800,13 +44318,13 @@ ${lines.join(`
|
|
|
43800
44318
|
`)}
|
|
43801
44319
|
\`\`\``;
|
|
43802
44320
|
}
|
|
43803
|
-
var RTL_OVERRIDE_PATTERN, MAX_TASK_ID_LENGTH = 100, MAX_DECISION_LENGTH = 500, MAX_INCOMPLETE_TASKS = 20,
|
|
44321
|
+
var RTL_OVERRIDE_PATTERN, MAX_TASK_ID_LENGTH = 100, MAX_DECISION_LENGTH = 500, MAX_INCOMPLETE_TASKS = 20, _internals15;
|
|
43804
44322
|
var init_handoff_service = __esm(() => {
|
|
43805
44323
|
init_utils2();
|
|
43806
44324
|
init_manager();
|
|
43807
44325
|
init_utils();
|
|
43808
44326
|
RTL_OVERRIDE_PATTERN = /[\u202e\u202d\u202c\u200f]/g;
|
|
43809
|
-
|
|
44327
|
+
_internals15 = {
|
|
43810
44328
|
getHandoffData,
|
|
43811
44329
|
formatHandoffMarkdown,
|
|
43812
44330
|
formatContinuationPrompt,
|
|
@@ -43821,8 +44339,8 @@ var init_handoff_service = __esm(() => {
|
|
|
43821
44339
|
});
|
|
43822
44340
|
|
|
43823
44341
|
// src/session/snapshot-writer.ts
|
|
43824
|
-
import { closeSync as closeSync3, fsyncSync as fsyncSync2, mkdirSync as
|
|
43825
|
-
import * as
|
|
44342
|
+
import { closeSync as closeSync3, fsyncSync as fsyncSync2, mkdirSync as mkdirSync11, openSync as openSync3, renameSync as renameSync6 } from "fs";
|
|
44343
|
+
import * as path27 from "path";
|
|
43826
44344
|
function serializeAgentSession(s) {
|
|
43827
44345
|
const gateLog = {};
|
|
43828
44346
|
const rawGateLog = s.gateLog ?? new Map;
|
|
@@ -43919,8 +44437,8 @@ async function writeSnapshot(directory, state) {
|
|
|
43919
44437
|
}
|
|
43920
44438
|
const content = JSON.stringify(snapshot, null, 2);
|
|
43921
44439
|
const resolvedPath = validateSwarmPath(directory, "session/state.json");
|
|
43922
|
-
const dir =
|
|
43923
|
-
|
|
44440
|
+
const dir = path27.dirname(resolvedPath);
|
|
44441
|
+
mkdirSync11(dir, { recursive: true });
|
|
43924
44442
|
const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
43925
44443
|
await bunWrite(tempPath, content);
|
|
43926
44444
|
try {
|
|
@@ -43940,22 +44458,22 @@ async function writeSnapshot(directory, state) {
|
|
|
43940
44458
|
}
|
|
43941
44459
|
function createSnapshotWriterHook(directory) {
|
|
43942
44460
|
return (_input, _output) => {
|
|
43943
|
-
_writeInFlight = _writeInFlight.then(() =>
|
|
44461
|
+
_writeInFlight = _writeInFlight.then(() => _internals16.writeSnapshot(directory, swarmState), () => _internals16.writeSnapshot(directory, swarmState));
|
|
43944
44462
|
return _writeInFlight;
|
|
43945
44463
|
};
|
|
43946
44464
|
}
|
|
43947
44465
|
async function flushPendingSnapshot(directory) {
|
|
43948
|
-
_writeInFlight = _writeInFlight.then(() =>
|
|
44466
|
+
_writeInFlight = _writeInFlight.then(() => _internals16.writeSnapshot(directory, swarmState), () => _internals16.writeSnapshot(directory, swarmState));
|
|
43949
44467
|
await _writeInFlight;
|
|
43950
44468
|
}
|
|
43951
|
-
var _writeInFlight,
|
|
44469
|
+
var _writeInFlight, _internals16;
|
|
43952
44470
|
var init_snapshot_writer = __esm(() => {
|
|
43953
44471
|
init_utils2();
|
|
43954
44472
|
init_state();
|
|
43955
44473
|
init_utils();
|
|
43956
44474
|
init_bun_compat();
|
|
43957
44475
|
_writeInFlight = Promise.resolve();
|
|
43958
|
-
|
|
44476
|
+
_internals16 = {
|
|
43959
44477
|
writeSnapshot,
|
|
43960
44478
|
createSnapshotWriterHook,
|
|
43961
44479
|
flushPendingSnapshot
|
|
@@ -44376,9 +44894,9 @@ var init_issue = __esm(() => {
|
|
|
44376
44894
|
|
|
44377
44895
|
// src/hooks/knowledge-migrator.ts
|
|
44378
44896
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
44379
|
-
import { existsSync as existsSync17, readFileSync as
|
|
44897
|
+
import { existsSync as existsSync17, readFileSync as readFileSync13 } from "fs";
|
|
44380
44898
|
import { mkdir as mkdir7, readFile as readFile7, writeFile as writeFile8 } from "fs/promises";
|
|
44381
|
-
import * as
|
|
44899
|
+
import * as path28 from "path";
|
|
44382
44900
|
async function migrateKnowledgeToExternal(_directory, _config) {
|
|
44383
44901
|
return {
|
|
44384
44902
|
migrated: false,
|
|
@@ -44389,8 +44907,8 @@ async function migrateKnowledgeToExternal(_directory, _config) {
|
|
|
44389
44907
|
};
|
|
44390
44908
|
}
|
|
44391
44909
|
async function migrateContextToKnowledge(directory, config3) {
|
|
44392
|
-
const sentinelPath =
|
|
44393
|
-
const contextPath =
|
|
44910
|
+
const sentinelPath = path28.join(directory, ".swarm", ".knowledge-migrated");
|
|
44911
|
+
const contextPath = path28.join(directory, ".swarm", "context.md");
|
|
44394
44912
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
44395
44913
|
if (existsSync17(sentinelPath)) {
|
|
44396
44914
|
return {
|
|
@@ -44420,9 +44938,9 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
44420
44938
|
skippedReason: "empty-context"
|
|
44421
44939
|
};
|
|
44422
44940
|
}
|
|
44423
|
-
const rawEntries =
|
|
44941
|
+
const rawEntries = _internals17.parseContextMd(contextContent);
|
|
44424
44942
|
if (rawEntries.length === 0) {
|
|
44425
|
-
await
|
|
44943
|
+
await _internals17.writeSentinel(sentinelPath, 0, 0);
|
|
44426
44944
|
return {
|
|
44427
44945
|
migrated: true,
|
|
44428
44946
|
entriesMigrated: 0,
|
|
@@ -44433,10 +44951,10 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
44433
44951
|
const existing = await readKnowledge(knowledgePath);
|
|
44434
44952
|
let migrated = 0;
|
|
44435
44953
|
let dropped = 0;
|
|
44436
|
-
const projectName =
|
|
44954
|
+
const projectName = _internals17.inferProjectName(directory);
|
|
44437
44955
|
for (const raw of rawEntries) {
|
|
44438
44956
|
if (config3.validation_enabled !== false) {
|
|
44439
|
-
const category = raw.categoryHint ??
|
|
44957
|
+
const category = raw.categoryHint ?? _internals17.inferCategoryFromText(raw.text);
|
|
44440
44958
|
const result = validateLesson(raw.text, existing.map((e) => e.lesson), {
|
|
44441
44959
|
category,
|
|
44442
44960
|
scope: "global",
|
|
@@ -44456,8 +44974,8 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
44456
44974
|
const entry = {
|
|
44457
44975
|
id: randomUUID2(),
|
|
44458
44976
|
tier: "swarm",
|
|
44459
|
-
lesson:
|
|
44460
|
-
category: raw.categoryHint ??
|
|
44977
|
+
lesson: _internals17.truncateLesson(raw.text),
|
|
44978
|
+
category: raw.categoryHint ?? _internals17.inferCategoryFromText(raw.text),
|
|
44461
44979
|
tags: [...inferredTags, `migration:${raw.sourceSection}`],
|
|
44462
44980
|
scope: "global",
|
|
44463
44981
|
confidence: 0.3,
|
|
@@ -44480,7 +44998,7 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
44480
44998
|
if (migrated > 0) {
|
|
44481
44999
|
await rewriteKnowledge(knowledgePath, existing);
|
|
44482
45000
|
}
|
|
44483
|
-
await
|
|
45001
|
+
await _internals17.writeSentinel(sentinelPath, migrated, dropped);
|
|
44484
45002
|
log(`[knowledge-migrator] Migrated ${migrated} entries, dropped ${dropped}`);
|
|
44485
45003
|
return {
|
|
44486
45004
|
migrated: true,
|
|
@@ -44490,7 +45008,7 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
44490
45008
|
};
|
|
44491
45009
|
}
|
|
44492
45010
|
function parseContextMd(content) {
|
|
44493
|
-
const sections =
|
|
45011
|
+
const sections = _internals17.splitIntoSections(content);
|
|
44494
45012
|
const entries = [];
|
|
44495
45013
|
const seen = new Set;
|
|
44496
45014
|
const sectionPatterns = [
|
|
@@ -44506,7 +45024,7 @@ function parseContextMd(content) {
|
|
|
44506
45024
|
const match = sectionPatterns.find((sp) => sp.pattern.test(section.heading));
|
|
44507
45025
|
if (!match)
|
|
44508
45026
|
continue;
|
|
44509
|
-
const bullets =
|
|
45027
|
+
const bullets = _internals17.extractBullets(section.body);
|
|
44510
45028
|
for (const bullet of bullets) {
|
|
44511
45029
|
if (bullet.length < 15)
|
|
44512
45030
|
continue;
|
|
@@ -44515,9 +45033,9 @@ function parseContextMd(content) {
|
|
|
44515
45033
|
continue;
|
|
44516
45034
|
seen.add(normalized);
|
|
44517
45035
|
entries.push({
|
|
44518
|
-
text:
|
|
45036
|
+
text: _internals17.truncateLesson(bullet),
|
|
44519
45037
|
sourceSection: match.sourceSection,
|
|
44520
|
-
categoryHint:
|
|
45038
|
+
categoryHint: _internals17.inferCategoryFromText(bullet)
|
|
44521
45039
|
});
|
|
44522
45040
|
}
|
|
44523
45041
|
}
|
|
@@ -44586,16 +45104,16 @@ function truncateLesson(text) {
|
|
|
44586
45104
|
return `${text.slice(0, 277)}...`;
|
|
44587
45105
|
}
|
|
44588
45106
|
function inferProjectName(directory) {
|
|
44589
|
-
const packageJsonPath =
|
|
45107
|
+
const packageJsonPath = path28.join(directory, "package.json");
|
|
44590
45108
|
if (existsSync17(packageJsonPath)) {
|
|
44591
45109
|
try {
|
|
44592
|
-
const pkg = JSON.parse(
|
|
45110
|
+
const pkg = JSON.parse(readFileSync13(packageJsonPath, "utf-8"));
|
|
44593
45111
|
if (pkg.name && typeof pkg.name === "string") {
|
|
44594
45112
|
return pkg.name;
|
|
44595
45113
|
}
|
|
44596
45114
|
} catch {}
|
|
44597
45115
|
}
|
|
44598
|
-
return
|
|
45116
|
+
return path28.basename(directory);
|
|
44599
45117
|
}
|
|
44600
45118
|
async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
44601
45119
|
const sentinel = {
|
|
@@ -44607,15 +45125,15 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
|
44607
45125
|
schema_version: 1,
|
|
44608
45126
|
migration_tool: "knowledge-migrator.ts"
|
|
44609
45127
|
};
|
|
44610
|
-
await mkdir7(
|
|
45128
|
+
await mkdir7(path28.dirname(sentinelPath), { recursive: true });
|
|
44611
45129
|
await writeFile8(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
|
|
44612
45130
|
}
|
|
44613
|
-
var
|
|
45131
|
+
var _internals17;
|
|
44614
45132
|
var init_knowledge_migrator = __esm(() => {
|
|
44615
45133
|
init_logger();
|
|
44616
45134
|
init_knowledge_store();
|
|
44617
45135
|
init_knowledge_validator();
|
|
44618
|
-
|
|
45136
|
+
_internals17 = {
|
|
44619
45137
|
migrateContextToKnowledge,
|
|
44620
45138
|
migrateKnowledgeToExternal,
|
|
44621
45139
|
parseContextMd,
|
|
@@ -44629,7 +45147,7 @@ var init_knowledge_migrator = __esm(() => {
|
|
|
44629
45147
|
});
|
|
44630
45148
|
|
|
44631
45149
|
// src/commands/knowledge.ts
|
|
44632
|
-
import { join as
|
|
45150
|
+
import { join as join26 } from "path";
|
|
44633
45151
|
function resolveEntryByPrefix(entries, inputId) {
|
|
44634
45152
|
const exact = entries.find((e) => e.id === inputId);
|
|
44635
45153
|
if (exact)
|
|
@@ -44680,7 +45198,7 @@ async function handleKnowledgeRestoreCommand(directory, args) {
|
|
|
44680
45198
|
return "Invalid entry ID. IDs must be 1-64 characters: letters, digits, hyphens, underscores only.";
|
|
44681
45199
|
}
|
|
44682
45200
|
try {
|
|
44683
|
-
const quarantinePath =
|
|
45201
|
+
const quarantinePath = join26(directory, ".swarm", "knowledge-quarantined.jsonl");
|
|
44684
45202
|
const entries = await readKnowledge(quarantinePath);
|
|
44685
45203
|
const resolved = resolveEntryByPrefix(entries, inputId);
|
|
44686
45204
|
if ("error" in resolved) {
|
|
@@ -44752,9 +45270,9 @@ var init_knowledge = __esm(() => {
|
|
|
44752
45270
|
|
|
44753
45271
|
// src/services/plan-service.ts
|
|
44754
45272
|
async function getPlanData(directory, phaseArg) {
|
|
44755
|
-
const plan = await
|
|
45273
|
+
const plan = await _internals18.loadPlanJsonOnly(directory);
|
|
44756
45274
|
if (plan) {
|
|
44757
|
-
const fullMarkdown =
|
|
45275
|
+
const fullMarkdown = _internals18.derivePlanMarkdown(plan);
|
|
44758
45276
|
if (phaseArg === undefined || phaseArg === null || phaseArg === "") {
|
|
44759
45277
|
return {
|
|
44760
45278
|
hasPlan: true,
|
|
@@ -44797,7 +45315,7 @@ async function getPlanData(directory, phaseArg) {
|
|
|
44797
45315
|
isLegacy: false
|
|
44798
45316
|
};
|
|
44799
45317
|
}
|
|
44800
|
-
const planContent = await
|
|
45318
|
+
const planContent = await _internals18.readSwarmFileAsync(directory, "plan.md");
|
|
44801
45319
|
if (!planContent) {
|
|
44802
45320
|
return {
|
|
44803
45321
|
hasPlan: false,
|
|
@@ -44893,11 +45411,11 @@ async function handlePlanCommand(directory, args) {
|
|
|
44893
45411
|
const planData = await getPlanData(directory, phaseArg);
|
|
44894
45412
|
return formatPlanMarkdown(planData);
|
|
44895
45413
|
}
|
|
44896
|
-
var
|
|
45414
|
+
var _internals18;
|
|
44897
45415
|
var init_plan_service = __esm(() => {
|
|
44898
45416
|
init_utils2();
|
|
44899
45417
|
init_manager();
|
|
44900
|
-
|
|
45418
|
+
_internals18 = {
|
|
44901
45419
|
loadPlanJsonOnly,
|
|
44902
45420
|
derivePlanMarkdown,
|
|
44903
45421
|
readSwarmFileAsync
|
|
@@ -45135,7 +45653,7 @@ var init_path_security = () => {};
|
|
|
45135
45653
|
|
|
45136
45654
|
// src/tools/lint.ts
|
|
45137
45655
|
import * as fs12 from "fs";
|
|
45138
|
-
import * as
|
|
45656
|
+
import * as path29 from "path";
|
|
45139
45657
|
function validateArgs(args) {
|
|
45140
45658
|
if (typeof args !== "object" || args === null)
|
|
45141
45659
|
return false;
|
|
@@ -45146,9 +45664,9 @@ function validateArgs(args) {
|
|
|
45146
45664
|
}
|
|
45147
45665
|
function getLinterCommand(linter, mode, projectDir) {
|
|
45148
45666
|
const isWindows = process.platform === "win32";
|
|
45149
|
-
const binDir =
|
|
45150
|
-
const biomeBin = isWindows ?
|
|
45151
|
-
const eslintBin = isWindows ?
|
|
45667
|
+
const binDir = path29.join(projectDir, "node_modules", ".bin");
|
|
45668
|
+
const biomeBin = isWindows ? path29.join(binDir, "biome.EXE") : path29.join(binDir, "biome");
|
|
45669
|
+
const eslintBin = isWindows ? path29.join(binDir, "eslint.cmd") : path29.join(binDir, "eslint");
|
|
45152
45670
|
switch (linter) {
|
|
45153
45671
|
case "biome":
|
|
45154
45672
|
if (mode === "fix") {
|
|
@@ -45164,7 +45682,7 @@ function getLinterCommand(linter, mode, projectDir) {
|
|
|
45164
45682
|
}
|
|
45165
45683
|
function getAdditionalLinterCommand(linter, mode, cwd) {
|
|
45166
45684
|
const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
|
|
45167
|
-
const gradlew = fs12.existsSync(
|
|
45685
|
+
const gradlew = fs12.existsSync(path29.join(cwd, gradlewName)) ? path29.join(cwd, gradlewName) : null;
|
|
45168
45686
|
switch (linter) {
|
|
45169
45687
|
case "ruff":
|
|
45170
45688
|
return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
|
|
@@ -45198,10 +45716,10 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
|
|
|
45198
45716
|
}
|
|
45199
45717
|
}
|
|
45200
45718
|
function detectRuff(cwd) {
|
|
45201
|
-
if (fs12.existsSync(
|
|
45719
|
+
if (fs12.existsSync(path29.join(cwd, "ruff.toml")))
|
|
45202
45720
|
return isCommandAvailable("ruff");
|
|
45203
45721
|
try {
|
|
45204
|
-
const pyproject =
|
|
45722
|
+
const pyproject = path29.join(cwd, "pyproject.toml");
|
|
45205
45723
|
if (fs12.existsSync(pyproject)) {
|
|
45206
45724
|
const content = fs12.readFileSync(pyproject, "utf-8");
|
|
45207
45725
|
if (content.includes("[tool.ruff]"))
|
|
@@ -45211,19 +45729,19 @@ function detectRuff(cwd) {
|
|
|
45211
45729
|
return false;
|
|
45212
45730
|
}
|
|
45213
45731
|
function detectClippy(cwd) {
|
|
45214
|
-
return fs12.existsSync(
|
|
45732
|
+
return fs12.existsSync(path29.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
|
|
45215
45733
|
}
|
|
45216
45734
|
function detectGolangciLint(cwd) {
|
|
45217
|
-
return fs12.existsSync(
|
|
45735
|
+
return fs12.existsSync(path29.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
|
|
45218
45736
|
}
|
|
45219
45737
|
function detectCheckstyle(cwd) {
|
|
45220
|
-
const hasMaven = fs12.existsSync(
|
|
45221
|
-
const hasGradle = fs12.existsSync(
|
|
45222
|
-
const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs12.existsSync(
|
|
45738
|
+
const hasMaven = fs12.existsSync(path29.join(cwd, "pom.xml"));
|
|
45739
|
+
const hasGradle = fs12.existsSync(path29.join(cwd, "build.gradle")) || fs12.existsSync(path29.join(cwd, "build.gradle.kts"));
|
|
45740
|
+
const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs12.existsSync(path29.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
|
|
45223
45741
|
return (hasMaven || hasGradle) && hasBinary;
|
|
45224
45742
|
}
|
|
45225
45743
|
function detectKtlint(cwd) {
|
|
45226
|
-
const hasKotlin = fs12.existsSync(
|
|
45744
|
+
const hasKotlin = fs12.existsSync(path29.join(cwd, "build.gradle.kts")) || fs12.existsSync(path29.join(cwd, "build.gradle")) || (() => {
|
|
45227
45745
|
try {
|
|
45228
45746
|
return fs12.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
|
|
45229
45747
|
} catch {
|
|
@@ -45242,11 +45760,11 @@ function detectDotnetFormat(cwd) {
|
|
|
45242
45760
|
}
|
|
45243
45761
|
}
|
|
45244
45762
|
function detectCppcheck(cwd) {
|
|
45245
|
-
if (fs12.existsSync(
|
|
45763
|
+
if (fs12.existsSync(path29.join(cwd, "CMakeLists.txt"))) {
|
|
45246
45764
|
return isCommandAvailable("cppcheck");
|
|
45247
45765
|
}
|
|
45248
45766
|
try {
|
|
45249
|
-
const dirsToCheck = [cwd,
|
|
45767
|
+
const dirsToCheck = [cwd, path29.join(cwd, "src")];
|
|
45250
45768
|
const hasCpp = dirsToCheck.some((dir) => {
|
|
45251
45769
|
try {
|
|
45252
45770
|
return fs12.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
|
|
@@ -45260,13 +45778,13 @@ function detectCppcheck(cwd) {
|
|
|
45260
45778
|
}
|
|
45261
45779
|
}
|
|
45262
45780
|
function detectSwiftlint(cwd) {
|
|
45263
|
-
return fs12.existsSync(
|
|
45781
|
+
return fs12.existsSync(path29.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
|
|
45264
45782
|
}
|
|
45265
45783
|
function detectDartAnalyze(cwd) {
|
|
45266
|
-
return fs12.existsSync(
|
|
45784
|
+
return fs12.existsSync(path29.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
45267
45785
|
}
|
|
45268
45786
|
function detectRubocop(cwd) {
|
|
45269
|
-
return (fs12.existsSync(
|
|
45787
|
+
return (fs12.existsSync(path29.join(cwd, "Gemfile")) || fs12.existsSync(path29.join(cwd, "gems.rb")) || fs12.existsSync(path29.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
|
|
45270
45788
|
}
|
|
45271
45789
|
function detectAdditionalLinter(cwd) {
|
|
45272
45790
|
if (detectRuff(cwd))
|
|
@@ -45294,10 +45812,10 @@ function detectAdditionalLinter(cwd) {
|
|
|
45294
45812
|
function findBinInAncestors(startDir, binName) {
|
|
45295
45813
|
let dir = startDir;
|
|
45296
45814
|
while (true) {
|
|
45297
|
-
const candidate =
|
|
45815
|
+
const candidate = path29.join(dir, "node_modules", ".bin", binName);
|
|
45298
45816
|
if (fs12.existsSync(candidate))
|
|
45299
45817
|
return candidate;
|
|
45300
|
-
const parent =
|
|
45818
|
+
const parent = path29.dirname(dir);
|
|
45301
45819
|
if (parent === dir)
|
|
45302
45820
|
break;
|
|
45303
45821
|
dir = parent;
|
|
@@ -45306,10 +45824,10 @@ function findBinInAncestors(startDir, binName) {
|
|
|
45306
45824
|
}
|
|
45307
45825
|
function findBinInEnvPath(binName) {
|
|
45308
45826
|
const searchPath = process.env.PATH ?? "";
|
|
45309
|
-
for (const dir of searchPath.split(
|
|
45827
|
+
for (const dir of searchPath.split(path29.delimiter)) {
|
|
45310
45828
|
if (!dir)
|
|
45311
45829
|
continue;
|
|
45312
|
-
const candidate =
|
|
45830
|
+
const candidate = path29.join(dir, binName);
|
|
45313
45831
|
if (fs12.existsSync(candidate))
|
|
45314
45832
|
return candidate;
|
|
45315
45833
|
}
|
|
@@ -45322,13 +45840,13 @@ async function detectAvailableLinter(directory) {
|
|
|
45322
45840
|
return null;
|
|
45323
45841
|
const projectDir = directory;
|
|
45324
45842
|
const isWindows = process.platform === "win32";
|
|
45325
|
-
const biomeBin = isWindows ?
|
|
45326
|
-
const eslintBin = isWindows ?
|
|
45843
|
+
const biomeBin = isWindows ? path29.join(projectDir, "node_modules", ".bin", "biome.EXE") : path29.join(projectDir, "node_modules", ".bin", "biome");
|
|
45844
|
+
const eslintBin = isWindows ? path29.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path29.join(projectDir, "node_modules", ".bin", "eslint");
|
|
45327
45845
|
const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
|
|
45328
45846
|
if (localResult)
|
|
45329
45847
|
return localResult;
|
|
45330
|
-
const biomeAncestor = findBinInAncestors(
|
|
45331
|
-
const eslintAncestor = findBinInAncestors(
|
|
45848
|
+
const biomeAncestor = findBinInAncestors(path29.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
|
|
45849
|
+
const eslintAncestor = findBinInAncestors(path29.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
|
|
45332
45850
|
if (biomeAncestor || eslintAncestor) {
|
|
45333
45851
|
return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
|
|
45334
45852
|
}
|
|
@@ -45487,7 +46005,7 @@ async function runAdditionalLint(linter, mode, cwd) {
|
|
|
45487
46005
|
};
|
|
45488
46006
|
}
|
|
45489
46007
|
}
|
|
45490
|
-
var MAX_OUTPUT_BYTES = 512000, MAX_COMMAND_LENGTH = 500, lint,
|
|
46008
|
+
var MAX_OUTPUT_BYTES = 512000, MAX_COMMAND_LENGTH = 500, lint, _internals19;
|
|
45491
46009
|
var init_lint = __esm(() => {
|
|
45492
46010
|
init_zod();
|
|
45493
46011
|
init_discovery();
|
|
@@ -45519,15 +46037,15 @@ var init_lint = __esm(() => {
|
|
|
45519
46037
|
}
|
|
45520
46038
|
const { mode } = args;
|
|
45521
46039
|
const cwd = directory;
|
|
45522
|
-
const linter = await
|
|
46040
|
+
const linter = await _internals19.detectAvailableLinter(directory);
|
|
45523
46041
|
if (linter) {
|
|
45524
|
-
const result = await
|
|
46042
|
+
const result = await _internals19.runLint(linter, mode, directory);
|
|
45525
46043
|
return JSON.stringify(result, null, 2);
|
|
45526
46044
|
}
|
|
45527
|
-
const additionalLinter =
|
|
46045
|
+
const additionalLinter = _internals19.detectAdditionalLinter(cwd);
|
|
45528
46046
|
if (additionalLinter) {
|
|
45529
46047
|
warn(`[lint] Using ${additionalLinter} linter for this project`);
|
|
45530
|
-
const result = await
|
|
46048
|
+
const result = await _internals19.runAdditionalLint(additionalLinter, mode, cwd);
|
|
45531
46049
|
return JSON.stringify(result, null, 2);
|
|
45532
46050
|
}
|
|
45533
46051
|
const errorResult = {
|
|
@@ -45541,7 +46059,7 @@ For Rust: rustup component add clippy`
|
|
|
45541
46059
|
return JSON.stringify(errorResult, null, 2);
|
|
45542
46060
|
}
|
|
45543
46061
|
});
|
|
45544
|
-
|
|
46062
|
+
_internals19 = {
|
|
45545
46063
|
detectAvailableLinter,
|
|
45546
46064
|
runLint,
|
|
45547
46065
|
detectAdditionalLinter,
|
|
@@ -45551,7 +46069,7 @@ For Rust: rustup component add clippy`
|
|
|
45551
46069
|
|
|
45552
46070
|
// src/tools/secretscan.ts
|
|
45553
46071
|
import * as fs13 from "fs";
|
|
45554
|
-
import * as
|
|
46072
|
+
import * as path30 from "path";
|
|
45555
46073
|
function calculateShannonEntropy(str) {
|
|
45556
46074
|
if (str.length === 0)
|
|
45557
46075
|
return 0;
|
|
@@ -45599,7 +46117,7 @@ function isGlobOrPathPattern(pattern) {
|
|
|
45599
46117
|
return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
|
|
45600
46118
|
}
|
|
45601
46119
|
function loadSecretScanIgnore(scanDir) {
|
|
45602
|
-
const ignorePath =
|
|
46120
|
+
const ignorePath = path30.join(scanDir, ".secretscanignore");
|
|
45603
46121
|
try {
|
|
45604
46122
|
if (!fs13.existsSync(ignorePath))
|
|
45605
46123
|
return [];
|
|
@@ -45622,7 +46140,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
|
|
|
45622
46140
|
if (exactNames.has(entry))
|
|
45623
46141
|
return true;
|
|
45624
46142
|
for (const pattern of globPatterns) {
|
|
45625
|
-
if (
|
|
46143
|
+
if (path30.matchesGlob(relPath, pattern))
|
|
45626
46144
|
return true;
|
|
45627
46145
|
}
|
|
45628
46146
|
return false;
|
|
@@ -45643,7 +46161,7 @@ function validateDirectoryInput(dir) {
|
|
|
45643
46161
|
return null;
|
|
45644
46162
|
}
|
|
45645
46163
|
function isBinaryFile(filePath, buffer) {
|
|
45646
|
-
const ext =
|
|
46164
|
+
const ext = path30.extname(filePath).toLowerCase();
|
|
45647
46165
|
if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
45648
46166
|
return true;
|
|
45649
46167
|
}
|
|
@@ -45779,9 +46297,9 @@ function isSymlinkLoop(realPath, visited) {
|
|
|
45779
46297
|
return false;
|
|
45780
46298
|
}
|
|
45781
46299
|
function isPathWithinScope(realPath, scanDir) {
|
|
45782
|
-
const resolvedScanDir =
|
|
45783
|
-
const resolvedRealPath =
|
|
45784
|
-
return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir +
|
|
46300
|
+
const resolvedScanDir = path30.resolve(scanDir);
|
|
46301
|
+
const resolvedRealPath = path30.resolve(realPath);
|
|
46302
|
+
return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path30.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
|
|
45785
46303
|
}
|
|
45786
46304
|
function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
|
|
45787
46305
|
skippedDirs: 0,
|
|
@@ -45807,8 +46325,8 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
45807
46325
|
return a.localeCompare(b);
|
|
45808
46326
|
});
|
|
45809
46327
|
for (const entry of entries) {
|
|
45810
|
-
const fullPath =
|
|
45811
|
-
const relPath =
|
|
46328
|
+
const fullPath = path30.join(dir, entry);
|
|
46329
|
+
const relPath = path30.relative(scanDir, fullPath).replace(/\\/g, "/");
|
|
45812
46330
|
if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
|
|
45813
46331
|
stats.skippedDirs++;
|
|
45814
46332
|
continue;
|
|
@@ -45843,7 +46361,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
45843
46361
|
const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
|
|
45844
46362
|
files.push(...subFiles);
|
|
45845
46363
|
} else if (lstat.isFile()) {
|
|
45846
|
-
const ext =
|
|
46364
|
+
const ext = path30.extname(fullPath).toLowerCase();
|
|
45847
46365
|
if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
45848
46366
|
files.push(fullPath);
|
|
45849
46367
|
} else {
|
|
@@ -45855,7 +46373,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
45855
46373
|
}
|
|
45856
46374
|
async function runSecretscan(directory) {
|
|
45857
46375
|
try {
|
|
45858
|
-
const result = await
|
|
46376
|
+
const result = await _internals20.secretscan.execute({ directory }, {});
|
|
45859
46377
|
const jsonStr = typeof result === "string" ? result : result.output;
|
|
45860
46378
|
return JSON.parse(jsonStr);
|
|
45861
46379
|
} catch (e) {
|
|
@@ -45870,7 +46388,7 @@ async function runSecretscan(directory) {
|
|
|
45870
46388
|
return errorResult;
|
|
45871
46389
|
}
|
|
45872
46390
|
}
|
|
45873
|
-
var MAX_FILE_PATH_LENGTH = 500, MAX_FILE_SIZE_BYTES, MAX_FILES_SCANNED = 1000, MAX_FINDINGS = 100, MAX_OUTPUT_BYTES2 = 512000, MAX_LINE_LENGTH = 1e4, MAX_CONTENT_BYTES, BINARY_SIGNATURES, BINARY_PREFIX_BYTES = 4, BINARY_NULL_CHECK_BYTES = 8192, BINARY_NULL_THRESHOLD = 0.1, DEFAULT_EXCLUDE_DIRS, DEFAULT_EXCLUDE_EXTENSIONS, SECRET_PATTERNS, O_NOFOLLOW, secretscan,
|
|
46391
|
+
var MAX_FILE_PATH_LENGTH = 500, MAX_FILE_SIZE_BYTES, MAX_FILES_SCANNED = 1000, MAX_FINDINGS = 100, MAX_OUTPUT_BYTES2 = 512000, MAX_LINE_LENGTH = 1e4, MAX_CONTENT_BYTES, BINARY_SIGNATURES, BINARY_PREFIX_BYTES = 4, BINARY_NULL_CHECK_BYTES = 8192, BINARY_NULL_THRESHOLD = 0.1, DEFAULT_EXCLUDE_DIRS, DEFAULT_EXCLUDE_EXTENSIONS, SECRET_PATTERNS, O_NOFOLLOW, secretscan, _internals20;
|
|
45874
46392
|
var init_secretscan = __esm(() => {
|
|
45875
46393
|
init_zod();
|
|
45876
46394
|
init_path_security();
|
|
@@ -46103,7 +46621,7 @@ var init_secretscan = __esm(() => {
|
|
|
46103
46621
|
}
|
|
46104
46622
|
}
|
|
46105
46623
|
try {
|
|
46106
|
-
const _scanDirRaw =
|
|
46624
|
+
const _scanDirRaw = path30.resolve(directory);
|
|
46107
46625
|
const scanDir = (() => {
|
|
46108
46626
|
try {
|
|
46109
46627
|
return fs13.realpathSync(_scanDirRaw);
|
|
@@ -46242,7 +46760,7 @@ var init_secretscan = __esm(() => {
|
|
|
46242
46760
|
}
|
|
46243
46761
|
}
|
|
46244
46762
|
});
|
|
46245
|
-
|
|
46763
|
+
_internals20 = {
|
|
46246
46764
|
secretscan,
|
|
46247
46765
|
runSecretscan
|
|
46248
46766
|
};
|
|
@@ -46250,7 +46768,7 @@ var init_secretscan = __esm(() => {
|
|
|
46250
46768
|
|
|
46251
46769
|
// src/lang/default-backend.ts
|
|
46252
46770
|
import * as fs14 from "fs";
|
|
46253
|
-
import * as
|
|
46771
|
+
import * as path31 from "path";
|
|
46254
46772
|
function detectFileExists(dir, pattern) {
|
|
46255
46773
|
if (pattern.includes("*") || pattern.includes("?")) {
|
|
46256
46774
|
try {
|
|
@@ -46262,7 +46780,7 @@ function detectFileExists(dir, pattern) {
|
|
|
46262
46780
|
}
|
|
46263
46781
|
}
|
|
46264
46782
|
try {
|
|
46265
|
-
fs14.accessSync(
|
|
46783
|
+
fs14.accessSync(path31.join(dir, pattern));
|
|
46266
46784
|
return true;
|
|
46267
46785
|
} catch {
|
|
46268
46786
|
return false;
|
|
@@ -46390,8 +46908,8 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
|
|
|
46390
46908
|
return ["mvn", "test"];
|
|
46391
46909
|
case "gradle": {
|
|
46392
46910
|
const isWindows = process.platform === "win32";
|
|
46393
|
-
const hasGradlewBat = fs14.existsSync(
|
|
46394
|
-
const hasGradlew = fs14.existsSync(
|
|
46911
|
+
const hasGradlewBat = fs14.existsSync(path31.join(dir, "gradlew.bat"));
|
|
46912
|
+
const hasGradlew = fs14.existsSync(path31.join(dir, "gradlew"));
|
|
46395
46913
|
if (hasGradlewBat && isWindows)
|
|
46396
46914
|
return ["gradlew.bat", "test"];
|
|
46397
46915
|
if (hasGradlew)
|
|
@@ -46408,7 +46926,7 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
|
|
|
46408
46926
|
"cmake-build-release",
|
|
46409
46927
|
"out"
|
|
46410
46928
|
];
|
|
46411
|
-
const actualBuildDir = buildDirCandidates.find((d) => fs14.existsSync(
|
|
46929
|
+
const actualBuildDir = buildDirCandidates.find((d) => fs14.existsSync(path31.join(dir, d, "CMakeCache.txt"))) ?? "build";
|
|
46412
46930
|
return ["ctest", "--test-dir", actualBuildDir];
|
|
46413
46931
|
}
|
|
46414
46932
|
case "swift-test":
|
|
@@ -46695,17 +47213,17 @@ async function defaultSelectBuildCommand(profile, dir) {
|
|
|
46695
47213
|
return null;
|
|
46696
47214
|
}
|
|
46697
47215
|
async function defaultTestFilesFor(profile, sourceFile, dir) {
|
|
46698
|
-
const ext =
|
|
47216
|
+
const ext = path31.extname(sourceFile);
|
|
46699
47217
|
if (!profile.extensions.includes(ext))
|
|
46700
47218
|
return [];
|
|
46701
|
-
const base =
|
|
46702
|
-
const rel =
|
|
46703
|
-
const relDir =
|
|
47219
|
+
const base = path31.basename(sourceFile, ext);
|
|
47220
|
+
const rel = path31.relative(dir, sourceFile);
|
|
47221
|
+
const relDir = path31.dirname(rel);
|
|
46704
47222
|
const stripSrc = relDir.replace(/^src(\/|\\)/, "");
|
|
46705
47223
|
const candidates = new Set;
|
|
46706
47224
|
for (const tDir of ["tests", "test", "__tests__", "spec"]) {
|
|
46707
47225
|
for (const suffix of ["", "_test", ".test", "_spec", ".spec"]) {
|
|
46708
|
-
candidates.add(
|
|
47226
|
+
candidates.add(path31.join(dir, tDir, stripSrc, `${base}${suffix}${ext}`));
|
|
46709
47227
|
}
|
|
46710
47228
|
}
|
|
46711
47229
|
const existing = [];
|
|
@@ -46746,7 +47264,7 @@ var init_default_backend = __esm(() => {
|
|
|
46746
47264
|
|
|
46747
47265
|
// src/lang/backends/go.ts
|
|
46748
47266
|
import * as fs15 from "fs";
|
|
46749
|
-
import * as
|
|
47267
|
+
import * as path32 from "path";
|
|
46750
47268
|
function extractImports(_sourceFile, source) {
|
|
46751
47269
|
const out = new Set;
|
|
46752
47270
|
IMPORT_REGEX_SINGLE.lastIndex = 0;
|
|
@@ -46772,7 +47290,7 @@ function extractImports(_sourceFile, source) {
|
|
|
46772
47290
|
async function selectFramework(dir) {
|
|
46773
47291
|
let content;
|
|
46774
47292
|
try {
|
|
46775
|
-
content = fs15.readFileSync(
|
|
47293
|
+
content = fs15.readFileSync(path32.join(dir, "go.mod"), "utf-8");
|
|
46776
47294
|
} catch {
|
|
46777
47295
|
return null;
|
|
46778
47296
|
}
|
|
@@ -46793,16 +47311,16 @@ async function selectFramework(dir) {
|
|
|
46793
47311
|
async function selectEntryPoints(dir) {
|
|
46794
47312
|
const points = [];
|
|
46795
47313
|
try {
|
|
46796
|
-
fs15.accessSync(
|
|
47314
|
+
fs15.accessSync(path32.join(dir, "main.go"));
|
|
46797
47315
|
points.push("main.go");
|
|
46798
47316
|
} catch {}
|
|
46799
47317
|
try {
|
|
46800
|
-
const cmdDir =
|
|
47318
|
+
const cmdDir = path32.join(dir, "cmd");
|
|
46801
47319
|
const subdirs = fs15.readdirSync(cmdDir, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
46802
47320
|
for (const sub of subdirs) {
|
|
46803
|
-
const main =
|
|
47321
|
+
const main = path32.join("cmd", sub.name, "main.go");
|
|
46804
47322
|
try {
|
|
46805
|
-
fs15.accessSync(
|
|
47323
|
+
fs15.accessSync(path32.join(dir, main));
|
|
46806
47324
|
points.push(main);
|
|
46807
47325
|
} catch {}
|
|
46808
47326
|
}
|
|
@@ -46821,19 +47339,19 @@ function buildGoBackend() {
|
|
|
46821
47339
|
selectEntryPoints
|
|
46822
47340
|
};
|
|
46823
47341
|
}
|
|
46824
|
-
var PROFILE_ID = "go", IMPORT_REGEX_SINGLE, IMPORT_REGEX_GROUP, IMPORT_REGEX_GROUP_LINE,
|
|
47342
|
+
var PROFILE_ID = "go", IMPORT_REGEX_SINGLE, IMPORT_REGEX_GROUP, IMPORT_REGEX_GROUP_LINE, _internals21;
|
|
46825
47343
|
var init_go = __esm(() => {
|
|
46826
47344
|
init_default_backend();
|
|
46827
47345
|
init_profiles();
|
|
46828
47346
|
IMPORT_REGEX_SINGLE = /^\s*import\s+(?:[a-zA-Z_.][a-zA-Z0-9_]*\s+)?"([^"]+)"/gm;
|
|
46829
47347
|
IMPORT_REGEX_GROUP = /^\s*import\s*\(([\s\S]*?)\)/gm;
|
|
46830
47348
|
IMPORT_REGEX_GROUP_LINE = /(?:[a-zA-Z_.][a-zA-Z0-9_]*\s+)?"([^"]+)"/g;
|
|
46831
|
-
|
|
47349
|
+
_internals21 = { extractImports };
|
|
46832
47350
|
});
|
|
46833
47351
|
|
|
46834
47352
|
// src/lang/backends/python.ts
|
|
46835
47353
|
import * as fs16 from "fs";
|
|
46836
|
-
import * as
|
|
47354
|
+
import * as path33 from "path";
|
|
46837
47355
|
function parseImportTargets(rawTargets) {
|
|
46838
47356
|
const cleaned = rawTargets.replace(/[()]/g, "").split(`
|
|
46839
47357
|
`).map((line) => line.replace(/#.*$/, "").replace(/\\\s*$/, "")).join(" ");
|
|
@@ -46893,7 +47411,7 @@ async function selectFramework2(dir) {
|
|
|
46893
47411
|
];
|
|
46894
47412
|
for (const candidate of ["pyproject.toml", "requirements.txt", "setup.py"]) {
|
|
46895
47413
|
try {
|
|
46896
|
-
const content = fs16.readFileSync(
|
|
47414
|
+
const content = fs16.readFileSync(path33.join(dir, candidate), "utf-8");
|
|
46897
47415
|
const lower = content.toLowerCase();
|
|
46898
47416
|
for (const [pkg, name] of candidates) {
|
|
46899
47417
|
if (lower.includes(pkg)) {
|
|
@@ -46907,7 +47425,7 @@ async function selectFramework2(dir) {
|
|
|
46907
47425
|
async function selectEntryPoints2(dir) {
|
|
46908
47426
|
const points = new Set;
|
|
46909
47427
|
try {
|
|
46910
|
-
const content = fs16.readFileSync(
|
|
47428
|
+
const content = fs16.readFileSync(path33.join(dir, "pyproject.toml"), "utf-8");
|
|
46911
47429
|
const scriptsBlock = content.match(/\[project\.scripts\][\s\S]*?(?=\n\[|$)/);
|
|
46912
47430
|
if (scriptsBlock) {
|
|
46913
47431
|
for (const line of scriptsBlock[0].split(`
|
|
@@ -46922,7 +47440,7 @@ async function selectEntryPoints2(dir) {
|
|
|
46922
47440
|
} catch {}
|
|
46923
47441
|
for (const name of ["manage.py", "main.py", "app.py", "__main__.py"]) {
|
|
46924
47442
|
try {
|
|
46925
|
-
fs16.accessSync(
|
|
47443
|
+
fs16.accessSync(path33.join(dir, name));
|
|
46926
47444
|
points.add(name);
|
|
46927
47445
|
} catch {}
|
|
46928
47446
|
}
|
|
@@ -46940,18 +47458,18 @@ function buildPythonBackend() {
|
|
|
46940
47458
|
selectEntryPoints: selectEntryPoints2
|
|
46941
47459
|
};
|
|
46942
47460
|
}
|
|
46943
|
-
var PROFILE_ID2 = "python", IMPORT_REGEX_FROM_WITH_TARGETS, IMPORT_REGEX_IMPORT,
|
|
47461
|
+
var PROFILE_ID2 = "python", IMPORT_REGEX_FROM_WITH_TARGETS, IMPORT_REGEX_IMPORT, _internals22;
|
|
46944
47462
|
var init_python = __esm(() => {
|
|
46945
47463
|
init_default_backend();
|
|
46946
47464
|
init_profiles();
|
|
46947
47465
|
IMPORT_REGEX_FROM_WITH_TARGETS = /^\s*from\s+(\.*[\w.]*)\s+import\s+(\([^)]*\)|[^\n#]+)/gm;
|
|
46948
47466
|
IMPORT_REGEX_IMPORT = /^\s*import\s+([^\n#]+)/gm;
|
|
46949
|
-
|
|
47467
|
+
_internals22 = { extractImports: extractImports2 };
|
|
46950
47468
|
});
|
|
46951
47469
|
|
|
46952
47470
|
// src/test-impact/analyzer.ts
|
|
46953
47471
|
import fs17 from "fs";
|
|
46954
|
-
import
|
|
47472
|
+
import path34 from "path";
|
|
46955
47473
|
function normalizePath(p) {
|
|
46956
47474
|
return p.replace(/\\/g, "/");
|
|
46957
47475
|
}
|
|
@@ -46972,8 +47490,8 @@ function resolveRelativeImport(fromDir, importPath) {
|
|
|
46972
47490
|
if (!importPath.startsWith(".")) {
|
|
46973
47491
|
return null;
|
|
46974
47492
|
}
|
|
46975
|
-
const resolved =
|
|
46976
|
-
if (
|
|
47493
|
+
const resolved = path34.resolve(fromDir, importPath);
|
|
47494
|
+
if (path34.extname(resolved)) {
|
|
46977
47495
|
if (fs17.existsSync(resolved) && fs17.statSync(resolved).isFile()) {
|
|
46978
47496
|
return normalizePath(resolved);
|
|
46979
47497
|
}
|
|
@@ -46993,20 +47511,20 @@ function resolvePythonImport(fromDir, module) {
|
|
|
46993
47511
|
const leadingDots = module.match(/^\.+/)?.[0].length ?? 0;
|
|
46994
47512
|
let baseDir = fromDir;
|
|
46995
47513
|
for (let i = 1;i < leadingDots; i++) {
|
|
46996
|
-
baseDir =
|
|
47514
|
+
baseDir = path34.dirname(baseDir);
|
|
46997
47515
|
}
|
|
46998
47516
|
const rest = module.slice(leadingDots);
|
|
46999
47517
|
if (rest.length === 0) {
|
|
47000
|
-
const initPath =
|
|
47518
|
+
const initPath = path34.join(baseDir, "__init__.py");
|
|
47001
47519
|
if (fs17.existsSync(initPath) && fs17.statSync(initPath).isFile()) {
|
|
47002
47520
|
return normalizePath(initPath);
|
|
47003
47521
|
}
|
|
47004
47522
|
return null;
|
|
47005
47523
|
}
|
|
47006
|
-
const subpath = rest.replace(/\./g,
|
|
47524
|
+
const subpath = rest.replace(/\./g, path34.sep);
|
|
47007
47525
|
const candidates = [
|
|
47008
|
-
`${
|
|
47009
|
-
|
|
47526
|
+
`${path34.join(baseDir, subpath)}.py`,
|
|
47527
|
+
path34.join(baseDir, subpath, "__init__.py")
|
|
47010
47528
|
];
|
|
47011
47529
|
for (const c of candidates) {
|
|
47012
47530
|
if (fs17.existsSync(c) && fs17.statSync(c).isFile())
|
|
@@ -47015,7 +47533,7 @@ function resolvePythonImport(fromDir, module) {
|
|
|
47015
47533
|
return null;
|
|
47016
47534
|
}
|
|
47017
47535
|
function findGoModule(fromDir) {
|
|
47018
|
-
const resolved =
|
|
47536
|
+
const resolved = path34.resolve(fromDir);
|
|
47019
47537
|
let cur = resolved;
|
|
47020
47538
|
const walked = [];
|
|
47021
47539
|
for (let i = 0;i < 16; i++) {
|
|
@@ -47027,7 +47545,7 @@ function findGoModule(fromDir) {
|
|
|
47027
47545
|
}
|
|
47028
47546
|
walked.push(cur);
|
|
47029
47547
|
try {
|
|
47030
|
-
const goMod =
|
|
47548
|
+
const goMod = path34.join(cur, "go.mod");
|
|
47031
47549
|
const content = fs17.readFileSync(goMod, "utf-8");
|
|
47032
47550
|
const moduleMatch = content.match(/^\s*module\s+"?([^"\s/]+(?:\/[^"\s]+)*)"?/m);
|
|
47033
47551
|
if (moduleMatch) {
|
|
@@ -47038,10 +47556,10 @@ function findGoModule(fromDir) {
|
|
|
47038
47556
|
}
|
|
47039
47557
|
} catch {}
|
|
47040
47558
|
try {
|
|
47041
|
-
fs17.accessSync(
|
|
47559
|
+
fs17.accessSync(path34.join(cur, ".git"));
|
|
47042
47560
|
break;
|
|
47043
47561
|
} catch {}
|
|
47044
|
-
const parent =
|
|
47562
|
+
const parent = path34.dirname(cur);
|
|
47045
47563
|
if (parent === cur)
|
|
47046
47564
|
break;
|
|
47047
47565
|
cur = parent;
|
|
@@ -47053,12 +47571,12 @@ function findGoModule(fromDir) {
|
|
|
47053
47571
|
function resolveGoImport(fromDir, importPath) {
|
|
47054
47572
|
let dir = null;
|
|
47055
47573
|
if (importPath.startsWith(".")) {
|
|
47056
|
-
dir =
|
|
47574
|
+
dir = path34.resolve(fromDir, importPath);
|
|
47057
47575
|
} else {
|
|
47058
47576
|
const mod = findGoModule(fromDir);
|
|
47059
47577
|
if (mod && (importPath === mod.modulePath || importPath.startsWith(`${mod.modulePath}/`))) {
|
|
47060
47578
|
const subpath = importPath.slice(mod.modulePath.length);
|
|
47061
|
-
dir =
|
|
47579
|
+
dir = path34.join(mod.moduleRoot, subpath);
|
|
47062
47580
|
}
|
|
47063
47581
|
}
|
|
47064
47582
|
if (dir === null)
|
|
@@ -47066,7 +47584,7 @@ function resolveGoImport(fromDir, importPath) {
|
|
|
47066
47584
|
if (!fs17.existsSync(dir) || !fs17.statSync(dir).isDirectory())
|
|
47067
47585
|
return [];
|
|
47068
47586
|
try {
|
|
47069
|
-
return fs17.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath(
|
|
47587
|
+
return fs17.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath(path34.join(dir, f)));
|
|
47070
47588
|
} catch {
|
|
47071
47589
|
return [];
|
|
47072
47590
|
}
|
|
@@ -47105,15 +47623,15 @@ function findTestFilesSync(cwd) {
|
|
|
47105
47623
|
for (const entry of entries) {
|
|
47106
47624
|
if (entry.isDirectory()) {
|
|
47107
47625
|
if (!skipDirs.has(entry.name)) {
|
|
47108
|
-
walk(
|
|
47626
|
+
walk(path34.join(dir, entry.name), visitedInodes);
|
|
47109
47627
|
}
|
|
47110
47628
|
} else if (entry.isFile()) {
|
|
47111
47629
|
const name = entry.name;
|
|
47112
47630
|
const isTsTest = /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name);
|
|
47113
|
-
const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${
|
|
47631
|
+
const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path34.sep}tests${path34.sep}`) && name.endsWith(".py");
|
|
47114
47632
|
const isGoTest = /.+_test\.go$/.test(name);
|
|
47115
47633
|
if (isTsTest || isPyTest || isGoTest) {
|
|
47116
|
-
testFiles.push(normalizePath(
|
|
47634
|
+
testFiles.push(normalizePath(path34.join(dir, entry.name)));
|
|
47117
47635
|
}
|
|
47118
47636
|
}
|
|
47119
47637
|
}
|
|
@@ -47138,8 +47656,8 @@ function extractImports3(content) {
|
|
|
47138
47656
|
];
|
|
47139
47657
|
}
|
|
47140
47658
|
function addImpactEdgesForTestFile(testFile, content, impactMap) {
|
|
47141
|
-
const ext =
|
|
47142
|
-
const testDir =
|
|
47659
|
+
const ext = path34.extname(testFile).toLowerCase();
|
|
47660
|
+
const testDir = path34.dirname(testFile);
|
|
47143
47661
|
function addEdge(source) {
|
|
47144
47662
|
if (!impactMap[source])
|
|
47145
47663
|
impactMap[source] = [];
|
|
@@ -47157,7 +47675,7 @@ function addImpactEdgesForTestFile(testFile, content, impactMap) {
|
|
|
47157
47675
|
return;
|
|
47158
47676
|
}
|
|
47159
47677
|
if (PYTHON_EXTENSIONS.has(ext)) {
|
|
47160
|
-
const modules =
|
|
47678
|
+
const modules = _internals22.extractImports(testFile, content);
|
|
47161
47679
|
for (const mod of modules) {
|
|
47162
47680
|
const resolved = resolvePythonImport(testDir, mod);
|
|
47163
47681
|
if (resolved !== null)
|
|
@@ -47166,7 +47684,7 @@ function addImpactEdgesForTestFile(testFile, content, impactMap) {
|
|
|
47166
47684
|
return;
|
|
47167
47685
|
}
|
|
47168
47686
|
if (GO_EXTENSIONS.has(ext)) {
|
|
47169
|
-
const imports =
|
|
47687
|
+
const imports = _internals21.extractImports(testFile, content);
|
|
47170
47688
|
for (const importPath of imports) {
|
|
47171
47689
|
const sourceFiles = resolveGoImport(testDir, importPath);
|
|
47172
47690
|
for (const source of sourceFiles)
|
|
@@ -47193,12 +47711,12 @@ async function buildImpactMapInternal(cwd) {
|
|
|
47193
47711
|
return impactMap;
|
|
47194
47712
|
}
|
|
47195
47713
|
async function buildImpactMap(cwd) {
|
|
47196
|
-
const impactMap = await
|
|
47197
|
-
await
|
|
47714
|
+
const impactMap = await _internals23.buildImpactMapInternal(cwd);
|
|
47715
|
+
await _internals23.saveImpactMap(cwd, impactMap);
|
|
47198
47716
|
return impactMap;
|
|
47199
47717
|
}
|
|
47200
47718
|
async function loadImpactMap(cwd, options) {
|
|
47201
|
-
const cachePath =
|
|
47719
|
+
const cachePath = path34.join(cwd, ".swarm", "cache", "impact-map.json");
|
|
47202
47720
|
if (fs17.existsSync(cachePath)) {
|
|
47203
47721
|
try {
|
|
47204
47722
|
const content = fs17.readFileSync(cachePath, "utf-8");
|
|
@@ -47208,7 +47726,7 @@ async function loadImpactMap(cwd, options) {
|
|
|
47208
47726
|
const hasValidValues = Object.values(map3).every((v) => Array.isArray(v) && v.every((item) => typeof item === "string"));
|
|
47209
47727
|
if (hasValidValues) {
|
|
47210
47728
|
const generatedAt = new Date(data.generatedAt).getTime();
|
|
47211
|
-
if (!
|
|
47729
|
+
if (!_internals23.isCacheStale(map3, generatedAt)) {
|
|
47212
47730
|
return map3;
|
|
47213
47731
|
}
|
|
47214
47732
|
if (options?.skipRebuild) {
|
|
@@ -47228,15 +47746,15 @@ async function loadImpactMap(cwd, options) {
|
|
|
47228
47746
|
if (options?.skipRebuild) {
|
|
47229
47747
|
return {};
|
|
47230
47748
|
}
|
|
47231
|
-
return
|
|
47749
|
+
return _internals23.buildImpactMap(cwd);
|
|
47232
47750
|
}
|
|
47233
47751
|
async function saveImpactMap(cwd, impactMap) {
|
|
47234
|
-
if (!
|
|
47752
|
+
if (!path34.isAbsolute(cwd)) {
|
|
47235
47753
|
throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
|
|
47236
47754
|
}
|
|
47237
|
-
|
|
47238
|
-
const cacheDir2 =
|
|
47239
|
-
const cachePath =
|
|
47755
|
+
_internals23.validateProjectRoot(cwd);
|
|
47756
|
+
const cacheDir2 = path34.join(cwd, ".swarm", "cache");
|
|
47757
|
+
const cachePath = path34.join(cacheDir2, "impact-map.json");
|
|
47240
47758
|
if (!fs17.existsSync(cacheDir2)) {
|
|
47241
47759
|
fs17.mkdirSync(cacheDir2, { recursive: true });
|
|
47242
47760
|
}
|
|
@@ -47258,7 +47776,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
|
|
|
47258
47776
|
};
|
|
47259
47777
|
}
|
|
47260
47778
|
const validFiles = changedFiles.filter((f) => typeof f === "string" && f.length > 0 && !f.includes("\x00"));
|
|
47261
|
-
const impactMap = await
|
|
47779
|
+
const impactMap = await _internals23.loadImpactMap(cwd);
|
|
47262
47780
|
const impactedTestsSet = new Set;
|
|
47263
47781
|
const untestedFiles = [];
|
|
47264
47782
|
let visitedCount = 0;
|
|
@@ -47268,7 +47786,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
|
|
|
47268
47786
|
budgetExceeded = true;
|
|
47269
47787
|
break;
|
|
47270
47788
|
}
|
|
47271
|
-
const normalizedChanged = normalizePath(
|
|
47789
|
+
const normalizedChanged = normalizePath(path34.resolve(changedFile));
|
|
47272
47790
|
const tests = impactMap[normalizedChanged];
|
|
47273
47791
|
if (tests && tests.length > 0) {
|
|
47274
47792
|
for (const test of tests) {
|
|
@@ -47325,7 +47843,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
|
|
|
47325
47843
|
budgetExceeded
|
|
47326
47844
|
};
|
|
47327
47845
|
}
|
|
47328
|
-
var IMPORT_REGEX_ES, IMPORT_REGEX_REQUIRE, IMPORT_REGEX_REEXPORT, TS_EXTENSIONS, PYTHON_EXTENSIONS, GO_EXTENSIONS, EXTENSIONS_TO_TRY, goModuleCache,
|
|
47846
|
+
var IMPORT_REGEX_ES, IMPORT_REGEX_REQUIRE, IMPORT_REGEX_REEXPORT, TS_EXTENSIONS, PYTHON_EXTENSIONS, GO_EXTENSIONS, EXTENSIONS_TO_TRY, goModuleCache, _internals23;
|
|
47329
47847
|
var init_analyzer = __esm(() => {
|
|
47330
47848
|
init_manager2();
|
|
47331
47849
|
init_go();
|
|
@@ -47338,7 +47856,7 @@ var init_analyzer = __esm(() => {
|
|
|
47338
47856
|
GO_EXTENSIONS = new Set([".go"]);
|
|
47339
47857
|
EXTENSIONS_TO_TRY = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
47340
47858
|
goModuleCache = new Map;
|
|
47341
|
-
|
|
47859
|
+
_internals23 = {
|
|
47342
47860
|
validateProjectRoot,
|
|
47343
47861
|
normalizePath,
|
|
47344
47862
|
isCacheStale,
|
|
@@ -47561,15 +48079,15 @@ var FLAKY_THRESHOLD = 0.3, MIN_RUNS_FOR_QUARANTINE = 5, MAX_HISTORY_RUNS = 20;
|
|
|
47561
48079
|
|
|
47562
48080
|
// src/test-impact/history-store.ts
|
|
47563
48081
|
import fs18 from "fs";
|
|
47564
|
-
import
|
|
48082
|
+
import path35 from "path";
|
|
47565
48083
|
function getHistoryPath(workingDir) {
|
|
47566
48084
|
if (!workingDir) {
|
|
47567
48085
|
throw new Error("getHistoryPath requires a working directory \u2014 project root must be provided by the caller");
|
|
47568
48086
|
}
|
|
47569
|
-
if (!
|
|
48087
|
+
if (!path35.isAbsolute(workingDir)) {
|
|
47570
48088
|
throw new Error(`getHistoryPath requires an absolute project root path, got: "${workingDir}"`);
|
|
47571
48089
|
}
|
|
47572
|
-
return
|
|
48090
|
+
return path35.join(workingDir, ".swarm", "cache", "test-history.jsonl");
|
|
47573
48091
|
}
|
|
47574
48092
|
function sanitizeErrorMessage(errorMessage) {
|
|
47575
48093
|
if (errorMessage === undefined) {
|
|
@@ -47656,8 +48174,8 @@ function batchAppendTestRuns(records, workingDir) {
|
|
|
47656
48174
|
}
|
|
47657
48175
|
}
|
|
47658
48176
|
const historyPath = getHistoryPath(workingDir);
|
|
47659
|
-
const historyDir =
|
|
47660
|
-
|
|
48177
|
+
const historyDir = path35.dirname(historyPath);
|
|
48178
|
+
_internals24.validateProjectRoot(workingDir);
|
|
47661
48179
|
if (!fs18.existsSync(historyDir)) {
|
|
47662
48180
|
fs18.mkdirSync(historyDir, { recursive: true });
|
|
47663
48181
|
}
|
|
@@ -47737,7 +48255,7 @@ function getAllHistory(workingDir) {
|
|
|
47737
48255
|
records.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
47738
48256
|
return records;
|
|
47739
48257
|
}
|
|
47740
|
-
var MAX_HISTORY_PER_TEST = 20, MAX_ERROR_LENGTH = 500, MAX_STACK_LENGTH = 200, MAX_CHANGED_FILES = 50, DANGEROUS_PROPERTY_NAMES,
|
|
48258
|
+
var MAX_HISTORY_PER_TEST = 20, MAX_ERROR_LENGTH = 500, MAX_STACK_LENGTH = 200, MAX_CHANGED_FILES = 50, DANGEROUS_PROPERTY_NAMES, _internals24;
|
|
47741
48259
|
var init_history_store = __esm(() => {
|
|
47742
48260
|
init_manager2();
|
|
47743
48261
|
DANGEROUS_PROPERTY_NAMES = new Set([
|
|
@@ -47745,14 +48263,14 @@ var init_history_store = __esm(() => {
|
|
|
47745
48263
|
"constructor",
|
|
47746
48264
|
"prototype"
|
|
47747
48265
|
]);
|
|
47748
|
-
|
|
48266
|
+
_internals24 = {
|
|
47749
48267
|
validateProjectRoot
|
|
47750
48268
|
};
|
|
47751
48269
|
});
|
|
47752
48270
|
|
|
47753
48271
|
// src/tools/resolve-working-directory.ts
|
|
47754
48272
|
import * as fs19 from "fs";
|
|
47755
|
-
import * as
|
|
48273
|
+
import * as path36 from "path";
|
|
47756
48274
|
function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
47757
48275
|
if (workingDirectory == null || workingDirectory === "") {
|
|
47758
48276
|
return { success: true, directory: fallbackDirectory };
|
|
@@ -47772,15 +48290,15 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
47772
48290
|
};
|
|
47773
48291
|
}
|
|
47774
48292
|
}
|
|
47775
|
-
const normalizedDir =
|
|
47776
|
-
const pathParts = normalizedDir.split(
|
|
48293
|
+
const normalizedDir = path36.normalize(workingDirectory);
|
|
48294
|
+
const pathParts = normalizedDir.split(path36.sep);
|
|
47777
48295
|
if (pathParts.includes("..")) {
|
|
47778
48296
|
return {
|
|
47779
48297
|
success: false,
|
|
47780
48298
|
message: "Invalid working_directory: path traversal sequences (..) are not allowed"
|
|
47781
48299
|
};
|
|
47782
48300
|
}
|
|
47783
|
-
const resolvedDir =
|
|
48301
|
+
const resolvedDir = path36.resolve(normalizedDir);
|
|
47784
48302
|
let statResult;
|
|
47785
48303
|
try {
|
|
47786
48304
|
statResult = fs19.statSync(resolvedDir);
|
|
@@ -47796,7 +48314,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
47796
48314
|
message: `Invalid working_directory: path "${resolvedDir}" is not a directory`
|
|
47797
48315
|
};
|
|
47798
48316
|
}
|
|
47799
|
-
const resolvedFallback =
|
|
48317
|
+
const resolvedFallback = path36.resolve(fallbackDirectory);
|
|
47800
48318
|
let fallbackExists = false;
|
|
47801
48319
|
try {
|
|
47802
48320
|
fs19.statSync(resolvedFallback);
|
|
@@ -47806,7 +48324,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
47806
48324
|
}
|
|
47807
48325
|
if (workingDirectory != null && workingDirectory !== "") {
|
|
47808
48326
|
if (fallbackExists) {
|
|
47809
|
-
const isSubdirectory = resolvedDir.startsWith(resolvedFallback +
|
|
48327
|
+
const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path36.sep);
|
|
47810
48328
|
if (isSubdirectory) {
|
|
47811
48329
|
return {
|
|
47812
48330
|
success: false,
|
|
@@ -47861,17 +48379,17 @@ var init_registry_backend = __esm(() => {
|
|
|
47861
48379
|
|
|
47862
48380
|
// src/lang/backends/typescript.ts
|
|
47863
48381
|
import * as fs20 from "fs";
|
|
47864
|
-
import * as
|
|
48382
|
+
import * as path37 from "path";
|
|
47865
48383
|
function readPackageJsonRaw(dir) {
|
|
47866
48384
|
try {
|
|
47867
|
-
const content = fs20.readFileSync(
|
|
48385
|
+
const content = fs20.readFileSync(path37.join(dir, "package.json"), "utf-8");
|
|
47868
48386
|
return JSON.parse(content);
|
|
47869
48387
|
} catch {
|
|
47870
48388
|
return null;
|
|
47871
48389
|
}
|
|
47872
48390
|
}
|
|
47873
48391
|
function readPackageJson(dir) {
|
|
47874
|
-
return
|
|
48392
|
+
return _internals25.readPackageJsonRaw(dir);
|
|
47875
48393
|
}
|
|
47876
48394
|
function readPackageJsonTestScript(dir) {
|
|
47877
48395
|
return readPackageJson(dir)?.scripts?.test ?? null;
|
|
@@ -48041,7 +48559,7 @@ function buildTypescriptBackend() {
|
|
|
48041
48559
|
selectEntryPoints: selectEntryPoints3
|
|
48042
48560
|
};
|
|
48043
48561
|
}
|
|
48044
|
-
var PROFILE_ID3 = "typescript", IMPORT_REGEX_ES2, IMPORT_REGEX_BARE, IMPORT_REGEX_REQUIRE2, IMPORT_REGEX_DYNAMIC, IMPORT_REGEX_REEXPORT2,
|
|
48562
|
+
var PROFILE_ID3 = "typescript", IMPORT_REGEX_ES2, IMPORT_REGEX_BARE, IMPORT_REGEX_REQUIRE2, IMPORT_REGEX_DYNAMIC, IMPORT_REGEX_REEXPORT2, _internals25;
|
|
48045
48563
|
var init_typescript = __esm(() => {
|
|
48046
48564
|
init_default_backend();
|
|
48047
48565
|
init_profiles();
|
|
@@ -48050,7 +48568,7 @@ var init_typescript = __esm(() => {
|
|
|
48050
48568
|
IMPORT_REGEX_REQUIRE2 = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
48051
48569
|
IMPORT_REGEX_DYNAMIC = /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
48052
48570
|
IMPORT_REGEX_REEXPORT2 = /export\s+(?:\{[^}]*\}|\*)\s+from\s+['"]([^'"]+)['"]/g;
|
|
48053
|
-
|
|
48571
|
+
_internals25 = {
|
|
48054
48572
|
readPackageJsonRaw,
|
|
48055
48573
|
readPackageJsonTestScript,
|
|
48056
48574
|
frameworkFromScriptsTest
|
|
@@ -48081,10 +48599,10 @@ __export(exports_dispatch, {
|
|
|
48081
48599
|
pickedProfiles: () => pickedProfiles,
|
|
48082
48600
|
pickBackend: () => pickBackend,
|
|
48083
48601
|
clearDispatchCache: () => clearDispatchCache,
|
|
48084
|
-
_internals: () =>
|
|
48602
|
+
_internals: () => _internals26
|
|
48085
48603
|
});
|
|
48086
48604
|
import * as fs21 from "fs";
|
|
48087
|
-
import * as
|
|
48605
|
+
import * as path38 from "path";
|
|
48088
48606
|
function safeReaddirSet(dir) {
|
|
48089
48607
|
try {
|
|
48090
48608
|
return new Set(fs21.readdirSync(dir));
|
|
@@ -48101,14 +48619,14 @@ function manifestHash(dir) {
|
|
|
48101
48619
|
if (!entries.has(name))
|
|
48102
48620
|
continue;
|
|
48103
48621
|
try {
|
|
48104
|
-
const stat3 = fs21.statSync(
|
|
48622
|
+
const stat3 = fs21.statSync(path38.join(dir, name));
|
|
48105
48623
|
parts.push(`${name}:${stat3.size}:${stat3.mtimeMs}:${stat3.ino}`);
|
|
48106
48624
|
} catch {}
|
|
48107
48625
|
}
|
|
48108
48626
|
return parts.join("|");
|
|
48109
48627
|
}
|
|
48110
48628
|
function findManifestRoot(start) {
|
|
48111
|
-
const resolved =
|
|
48629
|
+
const resolved = path38.resolve(start);
|
|
48112
48630
|
const cached3 = manifestRootCache.get(resolved);
|
|
48113
48631
|
if (cached3 !== undefined)
|
|
48114
48632
|
return cached3;
|
|
@@ -48127,7 +48645,7 @@ function findManifestRoot(start) {
|
|
|
48127
48645
|
return cur;
|
|
48128
48646
|
}
|
|
48129
48647
|
}
|
|
48130
|
-
const parent =
|
|
48648
|
+
const parent = path38.dirname(cur);
|
|
48131
48649
|
if (parent === cur)
|
|
48132
48650
|
break;
|
|
48133
48651
|
cur = parent;
|
|
@@ -48136,7 +48654,7 @@ function findManifestRoot(start) {
|
|
|
48136
48654
|
return start;
|
|
48137
48655
|
}
|
|
48138
48656
|
function evictIfNeeded() {
|
|
48139
|
-
if (cache.size <=
|
|
48657
|
+
if (cache.size <= _internals26.cacheCapacity)
|
|
48140
48658
|
return;
|
|
48141
48659
|
let oldestKey;
|
|
48142
48660
|
let oldestOrder = Infinity;
|
|
@@ -48167,7 +48685,7 @@ async function pickBackend(dir) {
|
|
|
48167
48685
|
evictIfNeeded();
|
|
48168
48686
|
return null;
|
|
48169
48687
|
}
|
|
48170
|
-
const profiles = await
|
|
48688
|
+
const profiles = await _internals26.detectProjectLanguages(root);
|
|
48171
48689
|
if (profiles.length === 0) {
|
|
48172
48690
|
cache.set(cacheKey, {
|
|
48173
48691
|
hash: hash3,
|
|
@@ -48199,12 +48717,12 @@ function clearDispatchCache() {
|
|
|
48199
48717
|
manifestRootCache.clear();
|
|
48200
48718
|
insertCounter = 0;
|
|
48201
48719
|
}
|
|
48202
|
-
var
|
|
48720
|
+
var _internals26, cache, insertCounter = 0, MANIFEST_FILES, _MANIFEST_SET, manifestRootCache;
|
|
48203
48721
|
var init_dispatch = __esm(() => {
|
|
48204
48722
|
init_backends();
|
|
48205
48723
|
init_detector();
|
|
48206
48724
|
init_registry_backend();
|
|
48207
|
-
|
|
48725
|
+
_internals26 = {
|
|
48208
48726
|
detectProjectLanguages,
|
|
48209
48727
|
cacheCapacity: 64
|
|
48210
48728
|
};
|
|
@@ -48237,13 +48755,13 @@ var init_dispatch = __esm(() => {
|
|
|
48237
48755
|
|
|
48238
48756
|
// src/tools/test-runner.ts
|
|
48239
48757
|
import * as fs22 from "fs";
|
|
48240
|
-
import * as
|
|
48758
|
+
import * as path39 from "path";
|
|
48241
48759
|
async function estimateFanOut(sourceFiles, cwd) {
|
|
48242
48760
|
try {
|
|
48243
48761
|
const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
|
|
48244
48762
|
const uniqueTestFiles = new Set;
|
|
48245
48763
|
for (const sourceFile of sourceFiles) {
|
|
48246
|
-
const resolvedPath =
|
|
48764
|
+
const resolvedPath = path39.resolve(cwd, sourceFile);
|
|
48247
48765
|
const normalizedPath = resolvedPath.replace(/\\/g, "/");
|
|
48248
48766
|
const testFiles = impactMap[normalizedPath];
|
|
48249
48767
|
if (testFiles) {
|
|
@@ -48321,14 +48839,14 @@ function hasDevDependency(devDeps, ...patterns) {
|
|
|
48321
48839
|
return hasPackageJsonDependency(devDeps, ...patterns);
|
|
48322
48840
|
}
|
|
48323
48841
|
function detectGoTest(cwd) {
|
|
48324
|
-
return fs22.existsSync(
|
|
48842
|
+
return fs22.existsSync(path39.join(cwd, "go.mod")) && isCommandAvailable("go");
|
|
48325
48843
|
}
|
|
48326
48844
|
function detectJavaMaven(cwd) {
|
|
48327
|
-
return fs22.existsSync(
|
|
48845
|
+
return fs22.existsSync(path39.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
|
|
48328
48846
|
}
|
|
48329
48847
|
function detectGradle(cwd) {
|
|
48330
|
-
const hasBuildFile = fs22.existsSync(
|
|
48331
|
-
const hasGradlew = fs22.existsSync(
|
|
48848
|
+
const hasBuildFile = fs22.existsSync(path39.join(cwd, "build.gradle")) || fs22.existsSync(path39.join(cwd, "build.gradle.kts"));
|
|
48849
|
+
const hasGradlew = fs22.existsSync(path39.join(cwd, "gradlew")) || fs22.existsSync(path39.join(cwd, "gradlew.bat"));
|
|
48332
48850
|
return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
|
|
48333
48851
|
}
|
|
48334
48852
|
function detectDotnetTest(cwd) {
|
|
@@ -48341,25 +48859,25 @@ function detectDotnetTest(cwd) {
|
|
|
48341
48859
|
}
|
|
48342
48860
|
}
|
|
48343
48861
|
function detectCTest(cwd) {
|
|
48344
|
-
const hasSource = fs22.existsSync(
|
|
48345
|
-
const hasBuildCache = fs22.existsSync(
|
|
48862
|
+
const hasSource = fs22.existsSync(path39.join(cwd, "CMakeLists.txt"));
|
|
48863
|
+
const hasBuildCache = fs22.existsSync(path39.join(cwd, "CMakeCache.txt")) || fs22.existsSync(path39.join(cwd, "build", "CMakeCache.txt"));
|
|
48346
48864
|
return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
|
|
48347
48865
|
}
|
|
48348
48866
|
function detectSwiftTest(cwd) {
|
|
48349
|
-
return fs22.existsSync(
|
|
48867
|
+
return fs22.existsSync(path39.join(cwd, "Package.swift")) && isCommandAvailable("swift");
|
|
48350
48868
|
}
|
|
48351
48869
|
function detectDartTest(cwd) {
|
|
48352
|
-
return fs22.existsSync(
|
|
48870
|
+
return fs22.existsSync(path39.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
48353
48871
|
}
|
|
48354
48872
|
function detectRSpec(cwd) {
|
|
48355
|
-
const hasRSpecFile = fs22.existsSync(
|
|
48356
|
-
const hasGemfile = fs22.existsSync(
|
|
48357
|
-
const hasSpecDir = fs22.existsSync(
|
|
48873
|
+
const hasRSpecFile = fs22.existsSync(path39.join(cwd, ".rspec"));
|
|
48874
|
+
const hasGemfile = fs22.existsSync(path39.join(cwd, "Gemfile"));
|
|
48875
|
+
const hasSpecDir = fs22.existsSync(path39.join(cwd, "spec"));
|
|
48358
48876
|
const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
|
|
48359
48877
|
return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
|
|
48360
48878
|
}
|
|
48361
48879
|
function detectMinitest(cwd) {
|
|
48362
|
-
return fs22.existsSync(
|
|
48880
|
+
return fs22.existsSync(path39.join(cwd, "test")) && (fs22.existsSync(path39.join(cwd, "Gemfile")) || fs22.existsSync(path39.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
|
|
48363
48881
|
}
|
|
48364
48882
|
async function detectTestFrameworkViaDispatch(cwd) {
|
|
48365
48883
|
try {
|
|
@@ -48421,7 +48939,7 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
|
|
|
48421
48939
|
async function detectTestFramework(cwd) {
|
|
48422
48940
|
const baseDir = cwd;
|
|
48423
48941
|
try {
|
|
48424
|
-
const packageJsonPath =
|
|
48942
|
+
const packageJsonPath = path39.join(baseDir, "package.json");
|
|
48425
48943
|
if (fs22.existsSync(packageJsonPath)) {
|
|
48426
48944
|
const content = fs22.readFileSync(packageJsonPath, "utf-8");
|
|
48427
48945
|
const pkg = JSON.parse(content);
|
|
@@ -48442,16 +48960,16 @@ async function detectTestFramework(cwd) {
|
|
|
48442
48960
|
return "jest";
|
|
48443
48961
|
if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
|
|
48444
48962
|
return "mocha";
|
|
48445
|
-
if (fs22.existsSync(
|
|
48963
|
+
if (fs22.existsSync(path39.join(baseDir, "bun.lockb")) || fs22.existsSync(path39.join(baseDir, "bun.lock"))) {
|
|
48446
48964
|
if (scripts.test?.includes("bun"))
|
|
48447
48965
|
return "bun";
|
|
48448
48966
|
}
|
|
48449
48967
|
}
|
|
48450
48968
|
} catch {}
|
|
48451
48969
|
try {
|
|
48452
|
-
const pyprojectTomlPath =
|
|
48453
|
-
const setupCfgPath =
|
|
48454
|
-
const requirementsTxtPath =
|
|
48970
|
+
const pyprojectTomlPath = path39.join(baseDir, "pyproject.toml");
|
|
48971
|
+
const setupCfgPath = path39.join(baseDir, "setup.cfg");
|
|
48972
|
+
const requirementsTxtPath = path39.join(baseDir, "requirements.txt");
|
|
48455
48973
|
if (fs22.existsSync(pyprojectTomlPath)) {
|
|
48456
48974
|
const content = fs22.readFileSync(pyprojectTomlPath, "utf-8");
|
|
48457
48975
|
if (content.includes("[tool.pytest"))
|
|
@@ -48471,7 +48989,7 @@ async function detectTestFramework(cwd) {
|
|
|
48471
48989
|
}
|
|
48472
48990
|
} catch {}
|
|
48473
48991
|
try {
|
|
48474
|
-
const cargoTomlPath =
|
|
48992
|
+
const cargoTomlPath = path39.join(baseDir, "Cargo.toml");
|
|
48475
48993
|
if (fs22.existsSync(cargoTomlPath)) {
|
|
48476
48994
|
const content = fs22.readFileSync(cargoTomlPath, "utf-8");
|
|
48477
48995
|
if (content.includes("[dev-dependencies]")) {
|
|
@@ -48482,9 +49000,9 @@ async function detectTestFramework(cwd) {
|
|
|
48482
49000
|
}
|
|
48483
49001
|
} catch {}
|
|
48484
49002
|
try {
|
|
48485
|
-
const pesterConfigPath =
|
|
48486
|
-
const pesterConfigJsonPath =
|
|
48487
|
-
const pesterPs1Path =
|
|
49003
|
+
const pesterConfigPath = path39.join(baseDir, "pester.config.ps1");
|
|
49004
|
+
const pesterConfigJsonPath = path39.join(baseDir, "pester.config.ps1.json");
|
|
49005
|
+
const pesterPs1Path = path39.join(baseDir, "tests.ps1");
|
|
48488
49006
|
if (fs22.existsSync(pesterConfigPath) || fs22.existsSync(pesterConfigJsonPath) || fs22.existsSync(pesterPs1Path)) {
|
|
48489
49007
|
return "pester";
|
|
48490
49008
|
}
|
|
@@ -48513,12 +49031,12 @@ function isTestDirectoryPath(normalizedPath) {
|
|
|
48513
49031
|
return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
|
|
48514
49032
|
}
|
|
48515
49033
|
function resolveWorkspacePath(file3, workingDir) {
|
|
48516
|
-
return
|
|
49034
|
+
return path39.isAbsolute(file3) ? path39.resolve(file3) : path39.resolve(workingDir, file3);
|
|
48517
49035
|
}
|
|
48518
49036
|
function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
|
|
48519
49037
|
if (!preferRelative)
|
|
48520
49038
|
return absolutePath;
|
|
48521
|
-
return
|
|
49039
|
+
return path39.relative(workingDir, absolutePath);
|
|
48522
49040
|
}
|
|
48523
49041
|
function dedupePush(target, value) {
|
|
48524
49042
|
if (!target.includes(value)) {
|
|
@@ -48555,18 +49073,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
|
|
|
48555
49073
|
}
|
|
48556
49074
|
}
|
|
48557
49075
|
function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
|
|
48558
|
-
const relativeDir =
|
|
49076
|
+
const relativeDir = path39.dirname(relativePath);
|
|
48559
49077
|
const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
|
|
48560
49078
|
const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
|
|
48561
|
-
const rootDir =
|
|
48562
|
-
return nestedRelativeDir ? [rootDir,
|
|
49079
|
+
const rootDir = path39.join(workingDir, dirName);
|
|
49080
|
+
return nestedRelativeDir ? [rootDir, path39.join(rootDir, nestedRelativeDir)] : [rootDir];
|
|
48563
49081
|
});
|
|
48564
49082
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
48565
49083
|
if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
|
|
48566
|
-
directories.push(
|
|
49084
|
+
directories.push(path39.join(workingDir, "src/test/java", path39.dirname(normalizedRelativePath.slice("src/main/java/".length))));
|
|
48567
49085
|
}
|
|
48568
49086
|
if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
|
|
48569
|
-
directories.push(
|
|
49087
|
+
directories.push(path39.join(workingDir, "src/test/kotlin", path39.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
|
|
48570
49088
|
}
|
|
48571
49089
|
return [...new Set(directories)];
|
|
48572
49090
|
}
|
|
@@ -48594,23 +49112,23 @@ function isLanguageSpecificTestFile(basename6) {
|
|
|
48594
49112
|
}
|
|
48595
49113
|
function isConventionTestFilePath(filePath) {
|
|
48596
49114
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
48597
|
-
const basename6 =
|
|
49115
|
+
const basename6 = path39.basename(filePath);
|
|
48598
49116
|
return hasCompoundTestExtension(basename6) || basename6.includes(".spec.") || basename6.includes(".test.") || isLanguageSpecificTestFile(basename6) || isTestDirectoryPath(normalizedPath);
|
|
48599
49117
|
}
|
|
48600
49118
|
function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
48601
49119
|
const testFiles = [];
|
|
48602
49120
|
for (const file3 of sourceFiles) {
|
|
48603
49121
|
const absoluteFile = resolveWorkspacePath(file3, workingDir);
|
|
48604
|
-
const relativeFile =
|
|
48605
|
-
const basename6 =
|
|
48606
|
-
const dirname17 =
|
|
48607
|
-
const preferRelativeOutput = !
|
|
49122
|
+
const relativeFile = path39.relative(workingDir, absoluteFile);
|
|
49123
|
+
const basename6 = path39.basename(absoluteFile);
|
|
49124
|
+
const dirname17 = path39.dirname(absoluteFile);
|
|
49125
|
+
const preferRelativeOutput = !path39.isAbsolute(file3);
|
|
48608
49126
|
if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file3)) {
|
|
48609
49127
|
dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
|
|
48610
49128
|
continue;
|
|
48611
49129
|
}
|
|
48612
49130
|
const nameWithoutExt = basename6.replace(/\.[^.]+$/, "");
|
|
48613
|
-
const ext =
|
|
49131
|
+
const ext = path39.extname(basename6);
|
|
48614
49132
|
const genericTestNames = [
|
|
48615
49133
|
`${nameWithoutExt}.spec${ext}`,
|
|
48616
49134
|
`${nameWithoutExt}.test${ext}`
|
|
@@ -48619,7 +49137,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
48619
49137
|
const colocatedCandidates = [
|
|
48620
49138
|
...genericTestNames,
|
|
48621
49139
|
...languageSpecificTestNames
|
|
48622
|
-
].map((candidateName) =>
|
|
49140
|
+
].map((candidateName) => path39.join(dirname17, candidateName));
|
|
48623
49141
|
const testDirectoryNames = [
|
|
48624
49142
|
basename6,
|
|
48625
49143
|
...genericTestNames,
|
|
@@ -48628,8 +49146,8 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
48628
49146
|
const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
|
|
48629
49147
|
const possibleTestFiles = [
|
|
48630
49148
|
...colocatedCandidates,
|
|
48631
|
-
...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) =>
|
|
48632
|
-
...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) =>
|
|
49149
|
+
...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path39.join(dirname17, dirName, candidateName))),
|
|
49150
|
+
...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path39.join(candidateDir, candidateName)))
|
|
48633
49151
|
];
|
|
48634
49152
|
for (const testFile of possibleTestFiles) {
|
|
48635
49153
|
if (fs22.existsSync(testFile)) {
|
|
@@ -48650,7 +49168,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
48650
49168
|
try {
|
|
48651
49169
|
const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
|
|
48652
49170
|
const content = fs22.readFileSync(absoluteTestFile, "utf-8");
|
|
48653
|
-
const testDir =
|
|
49171
|
+
const testDir = path39.dirname(absoluteTestFile);
|
|
48654
49172
|
const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
|
|
48655
49173
|
let match;
|
|
48656
49174
|
match = importRegex.exec(content);
|
|
@@ -48658,8 +49176,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
48658
49176
|
const importPath = match[1];
|
|
48659
49177
|
let resolvedImport;
|
|
48660
49178
|
if (importPath.startsWith(".")) {
|
|
48661
|
-
resolvedImport =
|
|
48662
|
-
const existingExt =
|
|
49179
|
+
resolvedImport = path39.resolve(testDir, importPath);
|
|
49180
|
+
const existingExt = path39.extname(resolvedImport);
|
|
48663
49181
|
if (!existingExt) {
|
|
48664
49182
|
for (const extToTry of [
|
|
48665
49183
|
".ts",
|
|
@@ -48679,12 +49197,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
48679
49197
|
} else {
|
|
48680
49198
|
continue;
|
|
48681
49199
|
}
|
|
48682
|
-
const importBasename =
|
|
48683
|
-
const importDir =
|
|
49200
|
+
const importBasename = path39.basename(resolvedImport, path39.extname(resolvedImport));
|
|
49201
|
+
const importDir = path39.dirname(resolvedImport);
|
|
48684
49202
|
for (const sourceFile of absoluteSourceFiles) {
|
|
48685
|
-
const sourceDir =
|
|
48686
|
-
const sourceBasename =
|
|
48687
|
-
const isRelatedDir = importDir === sourceDir || importDir ===
|
|
49203
|
+
const sourceDir = path39.dirname(sourceFile);
|
|
49204
|
+
const sourceBasename = path39.basename(sourceFile, path39.extname(sourceFile));
|
|
49205
|
+
const isRelatedDir = importDir === sourceDir || importDir === path39.join(sourceDir, "__tests__") || importDir === path39.join(sourceDir, "tests") || importDir === path39.join(sourceDir, "test") || importDir === path39.join(sourceDir, "spec");
|
|
48688
49206
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
48689
49207
|
dedupePush(testFiles, testFile);
|
|
48690
49208
|
break;
|
|
@@ -48697,8 +49215,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
48697
49215
|
while (match !== null) {
|
|
48698
49216
|
const importPath = match[1];
|
|
48699
49217
|
if (importPath.startsWith(".")) {
|
|
48700
|
-
let resolvedImport =
|
|
48701
|
-
const existingExt =
|
|
49218
|
+
let resolvedImport = path39.resolve(testDir, importPath);
|
|
49219
|
+
const existingExt = path39.extname(resolvedImport);
|
|
48702
49220
|
if (!existingExt) {
|
|
48703
49221
|
for (const extToTry of [
|
|
48704
49222
|
".ts",
|
|
@@ -48715,12 +49233,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
48715
49233
|
}
|
|
48716
49234
|
}
|
|
48717
49235
|
}
|
|
48718
|
-
const importDir =
|
|
48719
|
-
const importBasename =
|
|
49236
|
+
const importDir = path39.dirname(resolvedImport);
|
|
49237
|
+
const importBasename = path39.basename(resolvedImport, path39.extname(resolvedImport));
|
|
48720
49238
|
for (const sourceFile of absoluteSourceFiles) {
|
|
48721
|
-
const sourceDir =
|
|
48722
|
-
const sourceBasename =
|
|
48723
|
-
const isRelatedDir = importDir === sourceDir || importDir ===
|
|
49239
|
+
const sourceDir = path39.dirname(sourceFile);
|
|
49240
|
+
const sourceBasename = path39.basename(sourceFile, path39.extname(sourceFile));
|
|
49241
|
+
const isRelatedDir = importDir === sourceDir || importDir === path39.join(sourceDir, "__tests__") || importDir === path39.join(sourceDir, "tests") || importDir === path39.join(sourceDir, "test") || importDir === path39.join(sourceDir, "spec");
|
|
48724
49242
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
48725
49243
|
dedupePush(testFiles, testFile);
|
|
48726
49244
|
break;
|
|
@@ -48830,8 +49348,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
48830
49348
|
return ["mvn", "test"];
|
|
48831
49349
|
case "gradle": {
|
|
48832
49350
|
const isWindows = process.platform === "win32";
|
|
48833
|
-
const hasGradlewBat = fs22.existsSync(
|
|
48834
|
-
const hasGradlew = fs22.existsSync(
|
|
49351
|
+
const hasGradlewBat = fs22.existsSync(path39.join(baseDir, "gradlew.bat"));
|
|
49352
|
+
const hasGradlew = fs22.existsSync(path39.join(baseDir, "gradlew"));
|
|
48835
49353
|
if (hasGradlewBat && isWindows)
|
|
48836
49354
|
return ["gradlew.bat", "test"];
|
|
48837
49355
|
if (hasGradlew)
|
|
@@ -48848,7 +49366,7 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
48848
49366
|
"cmake-build-release",
|
|
48849
49367
|
"out"
|
|
48850
49368
|
];
|
|
48851
|
-
const actualBuildDir = buildDirCandidates.find((d) => fs22.existsSync(
|
|
49369
|
+
const actualBuildDir = buildDirCandidates.find((d) => fs22.existsSync(path39.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
|
|
48852
49370
|
return ["ctest", "--test-dir", actualBuildDir];
|
|
48853
49371
|
}
|
|
48854
49372
|
case "swift-test":
|
|
@@ -49280,11 +49798,11 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
|
|
|
49280
49798
|
};
|
|
49281
49799
|
}
|
|
49282
49800
|
const startTime = Date.now();
|
|
49283
|
-
const vitestJsonOutputPath = framework === "vitest" ?
|
|
49801
|
+
const vitestJsonOutputPath = framework === "vitest" ? path39.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
|
|
49284
49802
|
try {
|
|
49285
49803
|
if (vitestJsonOutputPath) {
|
|
49286
49804
|
try {
|
|
49287
|
-
fs22.mkdirSync(
|
|
49805
|
+
fs22.mkdirSync(path39.dirname(vitestJsonOutputPath), { recursive: true });
|
|
49288
49806
|
if (fs22.existsSync(vitestJsonOutputPath)) {
|
|
49289
49807
|
fs22.unlinkSync(vitestJsonOutputPath);
|
|
49290
49808
|
}
|
|
@@ -49400,10 +49918,10 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
|
|
|
49400
49918
|
}
|
|
49401
49919
|
function normalizeHistoryTestFile(testFile, workingDir) {
|
|
49402
49920
|
const normalized = testFile.replace(/\\/g, "/");
|
|
49403
|
-
if (!
|
|
49921
|
+
if (!path39.isAbsolute(testFile))
|
|
49404
49922
|
return normalized;
|
|
49405
|
-
const relative9 =
|
|
49406
|
-
if (relative9.startsWith("..") ||
|
|
49923
|
+
const relative9 = path39.relative(workingDir, testFile);
|
|
49924
|
+
if (relative9.startsWith("..") || path39.isAbsolute(relative9)) {
|
|
49407
49925
|
return normalized;
|
|
49408
49926
|
}
|
|
49409
49927
|
return relative9.replace(/\\/g, "/");
|
|
@@ -49741,7 +50259,7 @@ var init_test_runner = __esm(() => {
|
|
|
49741
50259
|
const sourceFiles = args.files.filter((file3) => {
|
|
49742
50260
|
if (directTestFiles.includes(file3))
|
|
49743
50261
|
return false;
|
|
49744
|
-
const ext =
|
|
50262
|
+
const ext = path39.extname(file3).toLowerCase();
|
|
49745
50263
|
return SOURCE_EXTENSIONS.has(ext);
|
|
49746
50264
|
});
|
|
49747
50265
|
const invalidFiles = args.files.filter((file3) => !directTestFiles.includes(file3) && !sourceFiles.includes(file3));
|
|
@@ -49787,7 +50305,7 @@ var init_test_runner = __esm(() => {
|
|
|
49787
50305
|
if (isConventionTestFilePath(f)) {
|
|
49788
50306
|
return false;
|
|
49789
50307
|
}
|
|
49790
|
-
const ext =
|
|
50308
|
+
const ext = path39.extname(f).toLowerCase();
|
|
49791
50309
|
return SOURCE_EXTENSIONS.has(ext);
|
|
49792
50310
|
});
|
|
49793
50311
|
if (sourceFiles.length === 0) {
|
|
@@ -49837,7 +50355,7 @@ var init_test_runner = __esm(() => {
|
|
|
49837
50355
|
if (isConventionTestFilePath(f)) {
|
|
49838
50356
|
return false;
|
|
49839
50357
|
}
|
|
49840
|
-
const ext =
|
|
50358
|
+
const ext = path39.extname(f).toLowerCase();
|
|
49841
50359
|
return SOURCE_EXTENSIONS.has(ext);
|
|
49842
50360
|
});
|
|
49843
50361
|
if (sourceFiles.length === 0) {
|
|
@@ -49889,8 +50407,8 @@ var init_test_runner = __esm(() => {
|
|
|
49889
50407
|
}
|
|
49890
50408
|
if (impactResult.impactedTests.length > 0) {
|
|
49891
50409
|
testFiles = impactResult.impactedTests.map((absPath) => {
|
|
49892
|
-
const relativePath =
|
|
49893
|
-
return
|
|
50410
|
+
const relativePath = path39.relative(workingDir, absPath);
|
|
50411
|
+
return path39.isAbsolute(relativePath) ? absPath : relativePath;
|
|
49894
50412
|
});
|
|
49895
50413
|
} else {
|
|
49896
50414
|
graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
|
|
@@ -49966,7 +50484,7 @@ var init_test_runner = __esm(() => {
|
|
|
49966
50484
|
|
|
49967
50485
|
// src/services/preflight-service.ts
|
|
49968
50486
|
import * as fs23 from "fs";
|
|
49969
|
-
import * as
|
|
50487
|
+
import * as path40 from "path";
|
|
49970
50488
|
function validateDirectoryPath(dir) {
|
|
49971
50489
|
if (!dir || typeof dir !== "string") {
|
|
49972
50490
|
throw new Error("Directory path is required");
|
|
@@ -49974,8 +50492,8 @@ function validateDirectoryPath(dir) {
|
|
|
49974
50492
|
if (dir.includes("..")) {
|
|
49975
50493
|
throw new Error("Directory path must not contain path traversal sequences");
|
|
49976
50494
|
}
|
|
49977
|
-
const normalized =
|
|
49978
|
-
const absolutePath =
|
|
50495
|
+
const normalized = path40.normalize(dir);
|
|
50496
|
+
const absolutePath = path40.isAbsolute(normalized) ? normalized : path40.resolve(normalized);
|
|
49979
50497
|
return absolutePath;
|
|
49980
50498
|
}
|
|
49981
50499
|
function validateTimeout(timeoutMs, defaultValue) {
|
|
@@ -49998,7 +50516,7 @@ function validateTimeout(timeoutMs, defaultValue) {
|
|
|
49998
50516
|
}
|
|
49999
50517
|
function getPackageVersion(dir) {
|
|
50000
50518
|
try {
|
|
50001
|
-
const packagePath =
|
|
50519
|
+
const packagePath = path40.join(dir, "package.json");
|
|
50002
50520
|
if (fs23.existsSync(packagePath)) {
|
|
50003
50521
|
const content = fs23.readFileSync(packagePath, "utf-8");
|
|
50004
50522
|
const pkg = JSON.parse(content);
|
|
@@ -50009,7 +50527,7 @@ function getPackageVersion(dir) {
|
|
|
50009
50527
|
}
|
|
50010
50528
|
function getChangelogVersion(dir) {
|
|
50011
50529
|
try {
|
|
50012
|
-
const changelogPath =
|
|
50530
|
+
const changelogPath = path40.join(dir, "CHANGELOG.md");
|
|
50013
50531
|
if (fs23.existsSync(changelogPath)) {
|
|
50014
50532
|
const content = fs23.readFileSync(changelogPath, "utf-8");
|
|
50015
50533
|
const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
|
|
@@ -50023,7 +50541,7 @@ function getChangelogVersion(dir) {
|
|
|
50023
50541
|
function getVersionFileVersion(dir) {
|
|
50024
50542
|
const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
|
|
50025
50543
|
for (const file3 of possibleFiles) {
|
|
50026
|
-
const filePath =
|
|
50544
|
+
const filePath = path40.join(dir, file3);
|
|
50027
50545
|
if (fs23.existsSync(filePath)) {
|
|
50028
50546
|
try {
|
|
50029
50547
|
const content = fs23.readFileSync(filePath, "utf-8").trim();
|
|
@@ -50039,9 +50557,9 @@ function getVersionFileVersion(dir) {
|
|
|
50039
50557
|
async function runVersionCheck(dir, _timeoutMs) {
|
|
50040
50558
|
const startTime = Date.now();
|
|
50041
50559
|
try {
|
|
50042
|
-
const packageVersion =
|
|
50043
|
-
const changelogVersion =
|
|
50044
|
-
const versionFileVersion =
|
|
50560
|
+
const packageVersion = _internals27.getPackageVersion(dir);
|
|
50561
|
+
const changelogVersion = _internals27.getChangelogVersion(dir);
|
|
50562
|
+
const versionFileVersion = _internals27.getVersionFileVersion(dir);
|
|
50045
50563
|
const versions3 = [];
|
|
50046
50564
|
if (packageVersion)
|
|
50047
50565
|
versions3.push(`package.json: ${packageVersion}`);
|
|
@@ -50313,7 +50831,22 @@ async function runEvidenceCheck(dir) {
|
|
|
50313
50831
|
};
|
|
50314
50832
|
}
|
|
50315
50833
|
const evidenceTaskIds = new Set(await listEvidenceTaskIds(dir));
|
|
50316
|
-
const missingEvidence =
|
|
50834
|
+
const missingEvidence = [];
|
|
50835
|
+
for (const id of completedTaskIds) {
|
|
50836
|
+
const gateStatus = await getDurableGateEvidenceStatusForTask(dir, id);
|
|
50837
|
+
if (gateStatus.isComplete) {
|
|
50838
|
+
continue;
|
|
50839
|
+
}
|
|
50840
|
+
if (gateStatus.evidenceExists && gateStatus.missingGates.length > 0) {
|
|
50841
|
+
missingEvidence.push(id);
|
|
50842
|
+
continue;
|
|
50843
|
+
}
|
|
50844
|
+
if (evidenceTaskIds.has(id)) {
|
|
50845
|
+
continue;
|
|
50846
|
+
}
|
|
50847
|
+
missingEvidence.push(id);
|
|
50848
|
+
}
|
|
50849
|
+
const completedWithEvidence = completedTaskIds.length - missingEvidence.length;
|
|
50317
50850
|
if (missingEvidence.length > 0) {
|
|
50318
50851
|
return {
|
|
50319
50852
|
type: "evidence",
|
|
@@ -50321,7 +50854,7 @@ async function runEvidenceCheck(dir) {
|
|
|
50321
50854
|
message: `${missingEvidence.length} completed task(s) missing evidence`,
|
|
50322
50855
|
details: {
|
|
50323
50856
|
totalCompleted: completedTaskIds.length,
|
|
50324
|
-
totalWithEvidence:
|
|
50857
|
+
totalWithEvidence: completedWithEvidence,
|
|
50325
50858
|
missingTasks: missingEvidence.slice(0, 10),
|
|
50326
50859
|
missingCount: missingEvidence.length
|
|
50327
50860
|
},
|
|
@@ -50334,7 +50867,7 @@ async function runEvidenceCheck(dir) {
|
|
|
50334
50867
|
message: `All ${completedTaskIds.length} completed tasks have evidence`,
|
|
50335
50868
|
details: {
|
|
50336
50869
|
totalCompleted: completedTaskIds.length,
|
|
50337
|
-
totalWithEvidence:
|
|
50870
|
+
totalWithEvidence: completedWithEvidence
|
|
50338
50871
|
},
|
|
50339
50872
|
durationMs: Date.now() - startTime
|
|
50340
50873
|
};
|
|
@@ -50350,7 +50883,7 @@ async function runEvidenceCheck(dir) {
|
|
|
50350
50883
|
async function runRequirementCoverageCheck(dir, currentPhase) {
|
|
50351
50884
|
const startTime = Date.now();
|
|
50352
50885
|
try {
|
|
50353
|
-
const specPath =
|
|
50886
|
+
const specPath = path40.join(dir, ".swarm", "spec.md");
|
|
50354
50887
|
if (!fs23.existsSync(specPath)) {
|
|
50355
50888
|
return {
|
|
50356
50889
|
type: "req_coverage",
|
|
@@ -50391,7 +50924,7 @@ async function runPreflight(dir, phase, config3) {
|
|
|
50391
50924
|
const reportId = `preflight-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
50392
50925
|
let validatedDir;
|
|
50393
50926
|
try {
|
|
50394
|
-
validatedDir =
|
|
50927
|
+
validatedDir = _internals27.validateDirectoryPath(dir);
|
|
50395
50928
|
} catch (error93) {
|
|
50396
50929
|
return {
|
|
50397
50930
|
id: reportId,
|
|
@@ -50411,7 +50944,7 @@ async function runPreflight(dir, phase, config3) {
|
|
|
50411
50944
|
}
|
|
50412
50945
|
let validatedTimeout;
|
|
50413
50946
|
try {
|
|
50414
|
-
validatedTimeout =
|
|
50947
|
+
validatedTimeout = _internals27.validateTimeout(config3?.checkTimeoutMs, DEFAULT_CONFIG.checkTimeoutMs);
|
|
50415
50948
|
} catch (error93) {
|
|
50416
50949
|
return {
|
|
50417
50950
|
id: reportId,
|
|
@@ -50452,12 +50985,12 @@ async function runPreflight(dir, phase, config3) {
|
|
|
50452
50985
|
});
|
|
50453
50986
|
const checks5 = [];
|
|
50454
50987
|
log("[Preflight] Running lint check...");
|
|
50455
|
-
const lintResult = await
|
|
50988
|
+
const lintResult = await _internals27.runLintCheck(validatedDir, cfg.linter, cfg.checkTimeoutMs);
|
|
50456
50989
|
checks5.push(lintResult);
|
|
50457
50990
|
log(`[Preflight] Lint check: ${lintResult.status} ${lintResult.message}`);
|
|
50458
50991
|
if (!cfg.skipTests) {
|
|
50459
50992
|
log("[Preflight] Running tests check...");
|
|
50460
|
-
const testsResult = await
|
|
50993
|
+
const testsResult = await _internals27.runTestsCheck(validatedDir, cfg.testScope, cfg.checkTimeoutMs);
|
|
50461
50994
|
checks5.push(testsResult);
|
|
50462
50995
|
log(`[Preflight] Tests check: ${testsResult.status} ${testsResult.message}`);
|
|
50463
50996
|
} else {
|
|
@@ -50469,7 +51002,7 @@ async function runPreflight(dir, phase, config3) {
|
|
|
50469
51002
|
}
|
|
50470
51003
|
if (!cfg.skipSecrets) {
|
|
50471
51004
|
log("[Preflight] Running secrets check...");
|
|
50472
|
-
const secretsResult = await
|
|
51005
|
+
const secretsResult = await _internals27.runSecretsCheck(validatedDir, cfg.checkTimeoutMs);
|
|
50473
51006
|
checks5.push(secretsResult);
|
|
50474
51007
|
log(`[Preflight] Secrets check: ${secretsResult.status} ${secretsResult.message}`);
|
|
50475
51008
|
} else {
|
|
@@ -50481,7 +51014,7 @@ async function runPreflight(dir, phase, config3) {
|
|
|
50481
51014
|
}
|
|
50482
51015
|
if (!cfg.skipEvidence) {
|
|
50483
51016
|
log("[Preflight] Running evidence check...");
|
|
50484
|
-
const evidenceResult = await
|
|
51017
|
+
const evidenceResult = await _internals27.runEvidenceCheck(validatedDir);
|
|
50485
51018
|
checks5.push(evidenceResult);
|
|
50486
51019
|
log(`[Preflight] Evidence check: ${evidenceResult.status} ${evidenceResult.message}`);
|
|
50487
51020
|
} else {
|
|
@@ -50492,12 +51025,12 @@ async function runPreflight(dir, phase, config3) {
|
|
|
50492
51025
|
});
|
|
50493
51026
|
}
|
|
50494
51027
|
log("[Preflight] Running requirement coverage check...");
|
|
50495
|
-
const reqCoverageResult = await
|
|
51028
|
+
const reqCoverageResult = await _internals27.runRequirementCoverageCheck(validatedDir, phase);
|
|
50496
51029
|
checks5.push(reqCoverageResult);
|
|
50497
51030
|
log(`[Preflight] Requirement coverage check: ${reqCoverageResult.status} ${reqCoverageResult.message}`);
|
|
50498
51031
|
if (!cfg.skipVersion) {
|
|
50499
51032
|
log("[Preflight] Running version check...");
|
|
50500
|
-
const versionResult = await
|
|
51033
|
+
const versionResult = await _internals27.runVersionCheck(validatedDir, cfg.checkTimeoutMs);
|
|
50501
51034
|
checks5.push(versionResult);
|
|
50502
51035
|
log(`[Preflight] Version check: ${versionResult.status} ${versionResult.message}`);
|
|
50503
51036
|
} else {
|
|
@@ -50560,11 +51093,12 @@ function formatPreflightMarkdown(report) {
|
|
|
50560
51093
|
async function handlePreflightCommand(directory, _args) {
|
|
50561
51094
|
const plan = await loadPlan(directory);
|
|
50562
51095
|
const phase = plan?.current_phase ?? 1;
|
|
50563
|
-
const report = await
|
|
50564
|
-
return
|
|
51096
|
+
const report = await _internals27.runPreflight(directory, phase);
|
|
51097
|
+
return _internals27.formatPreflightMarkdown(report);
|
|
50565
51098
|
}
|
|
50566
|
-
var MIN_CHECK_TIMEOUT_MS = 5000, MAX_CHECK_TIMEOUT_MS = 300000, DEFAULT_CONFIG,
|
|
51099
|
+
var MIN_CHECK_TIMEOUT_MS = 5000, MAX_CHECK_TIMEOUT_MS = 300000, DEFAULT_CONFIG, _internals27;
|
|
50567
51100
|
var init_preflight_service = __esm(() => {
|
|
51101
|
+
init_gate_bridge();
|
|
50568
51102
|
init_manager2();
|
|
50569
51103
|
init_manager();
|
|
50570
51104
|
init_lint();
|
|
@@ -50580,7 +51114,7 @@ var init_preflight_service = __esm(() => {
|
|
|
50580
51114
|
testScope: "convention",
|
|
50581
51115
|
linter: "biome"
|
|
50582
51116
|
};
|
|
50583
|
-
|
|
51117
|
+
_internals27 = {
|
|
50584
51118
|
runPreflight,
|
|
50585
51119
|
formatPreflightMarkdown,
|
|
50586
51120
|
handlePreflightCommand,
|
|
@@ -51467,7 +52001,7 @@ var init_manager3 = __esm(() => {
|
|
|
51467
52001
|
|
|
51468
52002
|
// src/commands/reset.ts
|
|
51469
52003
|
import * as fs24 from "fs";
|
|
51470
|
-
import * as
|
|
52004
|
+
import * as path41 from "path";
|
|
51471
52005
|
async function handleResetCommand(directory, args) {
|
|
51472
52006
|
const hasConfirm = args.includes("--confirm");
|
|
51473
52007
|
if (!hasConfirm) {
|
|
@@ -51507,7 +52041,7 @@ async function handleResetCommand(directory, args) {
|
|
|
51507
52041
|
}
|
|
51508
52042
|
for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
|
|
51509
52043
|
try {
|
|
51510
|
-
const rootPath =
|
|
52044
|
+
const rootPath = path41.join(directory, filename);
|
|
51511
52045
|
if (fs24.existsSync(rootPath)) {
|
|
51512
52046
|
fs24.unlinkSync(rootPath);
|
|
51513
52047
|
results.push(`- \u2705 Deleted ${filename} (root)`);
|
|
@@ -51547,7 +52081,7 @@ var init_reset = __esm(() => {
|
|
|
51547
52081
|
|
|
51548
52082
|
// src/commands/reset-session.ts
|
|
51549
52083
|
import * as fs25 from "fs";
|
|
51550
|
-
import * as
|
|
52084
|
+
import * as path42 from "path";
|
|
51551
52085
|
async function handleResetSessionCommand(directory, _args) {
|
|
51552
52086
|
const results = [];
|
|
51553
52087
|
try {
|
|
@@ -51562,13 +52096,13 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
51562
52096
|
results.push("\u274C Failed to delete state.json");
|
|
51563
52097
|
}
|
|
51564
52098
|
try {
|
|
51565
|
-
const sessionDir =
|
|
52099
|
+
const sessionDir = path42.dirname(validateSwarmPath(directory, "session/state.json"));
|
|
51566
52100
|
if (fs25.existsSync(sessionDir)) {
|
|
51567
52101
|
const files = fs25.readdirSync(sessionDir);
|
|
51568
52102
|
const otherFiles = files.filter((f) => f !== "state.json");
|
|
51569
52103
|
let deletedCount = 0;
|
|
51570
52104
|
for (const file3 of otherFiles) {
|
|
51571
|
-
const filePath =
|
|
52105
|
+
const filePath = path42.join(sessionDir, file3);
|
|
51572
52106
|
if (fs25.lstatSync(filePath).isFile()) {
|
|
51573
52107
|
fs25.unlinkSync(filePath);
|
|
51574
52108
|
deletedCount++;
|
|
@@ -51600,7 +52134,7 @@ var init_reset_session = __esm(() => {
|
|
|
51600
52134
|
});
|
|
51601
52135
|
|
|
51602
52136
|
// src/summaries/manager.ts
|
|
51603
|
-
import * as
|
|
52137
|
+
import * as path43 from "path";
|
|
51604
52138
|
function sanitizeSummaryId(id) {
|
|
51605
52139
|
if (!id || id.length === 0) {
|
|
51606
52140
|
throw new Error("Invalid summary ID: empty string");
|
|
@@ -51623,7 +52157,7 @@ function sanitizeSummaryId(id) {
|
|
|
51623
52157
|
}
|
|
51624
52158
|
async function loadFullOutput(directory, id) {
|
|
51625
52159
|
const sanitizedId = sanitizeSummaryId(id);
|
|
51626
|
-
const relativePath =
|
|
52160
|
+
const relativePath = path43.join("summaries", `${sanitizedId}.json`);
|
|
51627
52161
|
validateSwarmPath(directory, relativePath);
|
|
51628
52162
|
const content = await readSwarmFileAsync(directory, relativePath);
|
|
51629
52163
|
if (content === null) {
|
|
@@ -51686,7 +52220,7 @@ var init_retrieve = __esm(() => {
|
|
|
51686
52220
|
|
|
51687
52221
|
// src/commands/rollback.ts
|
|
51688
52222
|
import * as fs26 from "fs";
|
|
51689
|
-
import * as
|
|
52223
|
+
import * as path44 from "path";
|
|
51690
52224
|
async function handleRollbackCommand(directory, args) {
|
|
51691
52225
|
const phaseArg = args[0];
|
|
51692
52226
|
if (!phaseArg) {
|
|
@@ -51751,8 +52285,8 @@ async function handleRollbackCommand(directory, args) {
|
|
|
51751
52285
|
if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
|
|
51752
52286
|
continue;
|
|
51753
52287
|
}
|
|
51754
|
-
const src =
|
|
51755
|
-
const dest =
|
|
52288
|
+
const src = path44.join(checkpointDir, file3);
|
|
52289
|
+
const dest = path44.join(swarmDir, file3);
|
|
51756
52290
|
try {
|
|
51757
52291
|
fs26.cpSync(src, dest, { recursive: true, force: true });
|
|
51758
52292
|
successes.push(file3);
|
|
@@ -51771,12 +52305,12 @@ async function handleRollbackCommand(directory, args) {
|
|
|
51771
52305
|
].join(`
|
|
51772
52306
|
`);
|
|
51773
52307
|
}
|
|
51774
|
-
const existingLedgerPath =
|
|
52308
|
+
const existingLedgerPath = path44.join(swarmDir, "plan-ledger.jsonl");
|
|
51775
52309
|
if (fs26.existsSync(existingLedgerPath)) {
|
|
51776
52310
|
fs26.unlinkSync(existingLedgerPath);
|
|
51777
52311
|
}
|
|
51778
52312
|
try {
|
|
51779
|
-
const planJsonPath =
|
|
52313
|
+
const planJsonPath = path44.join(swarmDir, "plan.json");
|
|
51780
52314
|
if (fs26.existsSync(planJsonPath)) {
|
|
51781
52315
|
const planRaw = fs26.readFileSync(planJsonPath, "utf-8");
|
|
51782
52316
|
const plan = PlanSchema.parse(JSON.parse(planRaw));
|
|
@@ -51837,7 +52371,7 @@ async function handleSimulateCommand(directory, args) {
|
|
|
51837
52371
|
}
|
|
51838
52372
|
let darkMatterPairs;
|
|
51839
52373
|
try {
|
|
51840
|
-
darkMatterPairs = await
|
|
52374
|
+
darkMatterPairs = await _internals11.detectDarkMatter(directory, options);
|
|
51841
52375
|
} catch (err) {
|
|
51842
52376
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
51843
52377
|
return `## Simulate Report
|
|
@@ -51867,9 +52401,9 @@ Ensure this is a git repository with commit history.`;
|
|
|
51867
52401
|
`);
|
|
51868
52402
|
try {
|
|
51869
52403
|
const fs27 = await import("fs/promises");
|
|
51870
|
-
const
|
|
51871
|
-
const reportPath =
|
|
51872
|
-
await fs27.mkdir(
|
|
52404
|
+
const path45 = await import("path");
|
|
52405
|
+
const reportPath = path45.join(directory, ".swarm", "simulate-report.md");
|
|
52406
|
+
await fs27.mkdir(path45.dirname(reportPath), { recursive: true });
|
|
51873
52407
|
await fs27.writeFile(reportPath, report, "utf-8");
|
|
51874
52408
|
} catch (err) {
|
|
51875
52409
|
const writeErr = err instanceof Error ? err.message : String(err);
|
|
@@ -51893,12 +52427,12 @@ async function handleSpecifyCommand(_directory, args) {
|
|
|
51893
52427
|
|
|
51894
52428
|
// src/turbo/lean/state.ts
|
|
51895
52429
|
import * as fs27 from "fs";
|
|
51896
|
-
import * as
|
|
52430
|
+
import * as path45 from "path";
|
|
51897
52431
|
function nowISO2() {
|
|
51898
52432
|
return new Date().toISOString();
|
|
51899
52433
|
}
|
|
51900
52434
|
function ensureSwarmDir2(directory) {
|
|
51901
|
-
const swarmDir =
|
|
52435
|
+
const swarmDir = path45.resolve(directory, ".swarm");
|
|
51902
52436
|
if (!fs27.existsSync(swarmDir)) {
|
|
51903
52437
|
fs27.mkdirSync(swarmDir, { recursive: true });
|
|
51904
52438
|
}
|
|
@@ -51942,7 +52476,7 @@ function markStateUnreadable2(directory, reason) {
|
|
|
51942
52476
|
}
|
|
51943
52477
|
function readPersisted2(directory) {
|
|
51944
52478
|
try {
|
|
51945
|
-
const filePath =
|
|
52479
|
+
const filePath = path45.join(directory, ".swarm", STATE_FILE2);
|
|
51946
52480
|
if (!fs27.existsSync(filePath)) {
|
|
51947
52481
|
const seed = emptyPersisted2();
|
|
51948
52482
|
try {
|
|
@@ -51978,7 +52512,7 @@ function writePersisted2(directory, persisted) {
|
|
|
51978
52512
|
let payload;
|
|
51979
52513
|
try {
|
|
51980
52514
|
ensureSwarmDir2(directory);
|
|
51981
|
-
filePath =
|
|
52515
|
+
filePath = path45.join(directory, ".swarm", STATE_FILE2);
|
|
51982
52516
|
tmpPath = `${filePath}.tmp.${Date.now()}`;
|
|
51983
52517
|
persisted.updatedAt = nowISO2();
|
|
51984
52518
|
payload = `${JSON.stringify(persisted, null, 2)}
|
|
@@ -52105,10 +52639,10 @@ var init_context_budget_service = __esm(() => {
|
|
|
52105
52639
|
|
|
52106
52640
|
// src/services/status-service.ts
|
|
52107
52641
|
import * as fsSync2 from "fs";
|
|
52108
|
-
import * as
|
|
52642
|
+
import * as path46 from "path";
|
|
52109
52643
|
function readSpecStalenessSnapshot(directory) {
|
|
52110
52644
|
try {
|
|
52111
|
-
const p =
|
|
52645
|
+
const p = path46.join(directory, ".swarm", "spec-staleness.json");
|
|
52112
52646
|
if (!fsSync2.existsSync(p))
|
|
52113
52647
|
return { stale: false };
|
|
52114
52648
|
const raw = fsSync2.readFileSync(p, "utf-8");
|
|
@@ -52202,7 +52736,7 @@ async function getStatusData(directory, agents) {
|
|
|
52202
52736
|
}
|
|
52203
52737
|
function enrichWithLeanTurbo(status, directory) {
|
|
52204
52738
|
const turboMode = hasActiveTurboMode();
|
|
52205
|
-
const leanActive =
|
|
52739
|
+
const leanActive = _internals28.hasActiveLeanTurbo();
|
|
52206
52740
|
let turboStrategy = "off";
|
|
52207
52741
|
if (leanActive) {
|
|
52208
52742
|
turboStrategy = "lean";
|
|
@@ -52221,7 +52755,7 @@ function enrichWithLeanTurbo(status, directory) {
|
|
|
52221
52755
|
}
|
|
52222
52756
|
}
|
|
52223
52757
|
if (leanSessionID) {
|
|
52224
|
-
const runState =
|
|
52758
|
+
const runState = _internals28.loadLeanTurboRunState(directory, leanSessionID);
|
|
52225
52759
|
if (runState) {
|
|
52226
52760
|
status.leanTurboPhase = runState.phase;
|
|
52227
52761
|
status.leanMaxParallelCoders = runState.maxParallelCoders;
|
|
@@ -52253,7 +52787,7 @@ function enrichWithLeanTurbo(status, directory) {
|
|
|
52253
52787
|
}
|
|
52254
52788
|
}
|
|
52255
52789
|
}
|
|
52256
|
-
status.fullAutoActive =
|
|
52790
|
+
status.fullAutoActive = _internals28.hasActiveFullAuto();
|
|
52257
52791
|
return status;
|
|
52258
52792
|
}
|
|
52259
52793
|
function formatStatusMarkdown(status) {
|
|
@@ -52335,7 +52869,7 @@ async function handleStatusCommand(directory, agents) {
|
|
|
52335
52869
|
}
|
|
52336
52870
|
return formatStatusMarkdown(statusData);
|
|
52337
52871
|
}
|
|
52338
|
-
var
|
|
52872
|
+
var _internals28;
|
|
52339
52873
|
var init_status_service = __esm(() => {
|
|
52340
52874
|
init_extractors();
|
|
52341
52875
|
init_utils2();
|
|
@@ -52344,7 +52878,7 @@ var init_status_service = __esm(() => {
|
|
|
52344
52878
|
init_state3();
|
|
52345
52879
|
init_compaction_service();
|
|
52346
52880
|
init_context_budget_service();
|
|
52347
|
-
|
|
52881
|
+
_internals28 = {
|
|
52348
52882
|
loadLeanTurboRunState,
|
|
52349
52883
|
hasActiveLeanTurbo,
|
|
52350
52884
|
hasActiveFullAuto
|
|
@@ -52435,7 +52969,7 @@ async function handleTurboCommand(directory, args, sessionID) {
|
|
|
52435
52969
|
if (arg0 === "on") {
|
|
52436
52970
|
let strategy = "standard";
|
|
52437
52971
|
try {
|
|
52438
|
-
const { config: config3 } =
|
|
52972
|
+
const { config: config3 } = _internals29.loadPluginConfigWithMeta(directory);
|
|
52439
52973
|
if (config3.turbo?.strategy === "lean") {
|
|
52440
52974
|
strategy = "lean";
|
|
52441
52975
|
}
|
|
@@ -52490,7 +53024,7 @@ function enableLeanTurbo(session, directory, sessionID) {
|
|
|
52490
53024
|
let maxParallelCoders = 4;
|
|
52491
53025
|
let conflictPolicy = "serialize";
|
|
52492
53026
|
try {
|
|
52493
|
-
const { config: config3 } =
|
|
53027
|
+
const { config: config3 } = _internals29.loadPluginConfigWithMeta(directory);
|
|
52494
53028
|
const leanConfig = config3.turbo?.lean;
|
|
52495
53029
|
if (leanConfig) {
|
|
52496
53030
|
maxParallelCoders = leanConfig.max_parallel_coders ?? 4;
|
|
@@ -52560,13 +53094,13 @@ function buildStatusMessage(session, directory, sessionID) {
|
|
|
52560
53094
|
].join(`
|
|
52561
53095
|
`);
|
|
52562
53096
|
}
|
|
52563
|
-
var
|
|
53097
|
+
var _internals29;
|
|
52564
53098
|
var init_turbo = __esm(() => {
|
|
52565
53099
|
init_config();
|
|
52566
53100
|
init_state();
|
|
52567
53101
|
init_state3();
|
|
52568
53102
|
init_logger();
|
|
52569
|
-
|
|
53103
|
+
_internals29 = {
|
|
52570
53104
|
loadPluginConfigWithMeta
|
|
52571
53105
|
};
|
|
52572
53106
|
});
|
|
@@ -52634,7 +53168,7 @@ var init_write_retro2 = __esm(() => {
|
|
|
52634
53168
|
|
|
52635
53169
|
// src/commands/command-dispatch.ts
|
|
52636
53170
|
import fs28 from "fs";
|
|
52637
|
-
import
|
|
53171
|
+
import path47 from "path";
|
|
52638
53172
|
function normalizeSwarmCommandInput(command, argumentText) {
|
|
52639
53173
|
if (command !== "swarm" && !command.startsWith("swarm-")) {
|
|
52640
53174
|
return { isSwarmCommand: false, tokens: [] };
|
|
@@ -52659,7 +53193,7 @@ function formatCommandNotFound(tokens) {
|
|
|
52659
53193
|
const attemptedCommand = tokens[0] || "";
|
|
52660
53194
|
const MAX_DISPLAY = 100;
|
|
52661
53195
|
const displayCommand = attemptedCommand.length > MAX_DISPLAY ? `${attemptedCommand.slice(0, MAX_DISPLAY)}...` : attemptedCommand;
|
|
52662
|
-
const similar =
|
|
53196
|
+
const similar = _internals30.findSimilarCommands(attemptedCommand);
|
|
52663
53197
|
const header = `Command \`/swarm ${displayCommand}\` not found.`;
|
|
52664
53198
|
const suggestions = similar.length > 0 ? `Did you mean:
|
|
52665
53199
|
${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
|
|
@@ -52670,9 +53204,9 @@ ${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
|
|
|
52670
53204
|
`);
|
|
52671
53205
|
}
|
|
52672
53206
|
function maybeMarkFirstRun(directory) {
|
|
52673
|
-
const sentinelPath =
|
|
53207
|
+
const sentinelPath = path47.join(directory, ".swarm", ".first-run-complete");
|
|
52674
53208
|
try {
|
|
52675
|
-
const swarmDir =
|
|
53209
|
+
const swarmDir = path47.join(directory, ".swarm");
|
|
52676
53210
|
fs28.mkdirSync(swarmDir, { recursive: true });
|
|
52677
53211
|
fs28.writeFileSync(sentinelPath, `first-run-complete: ${new Date().toISOString()}
|
|
52678
53212
|
`, { flag: "wx" });
|
|
@@ -53108,7 +53642,7 @@ async function buildSwarmCommandPrompt(args) {
|
|
|
53108
53642
|
activeAgentName,
|
|
53109
53643
|
registeredAgents
|
|
53110
53644
|
} = args;
|
|
53111
|
-
const resolved =
|
|
53645
|
+
const resolved = _internals30.resolveCommand(tokens);
|
|
53112
53646
|
if (!resolved) {
|
|
53113
53647
|
if (tokens.length === 0) {
|
|
53114
53648
|
return buildHelpText();
|
|
@@ -53259,7 +53793,7 @@ function findSimilarCommands(query) {
|
|
|
53259
53793
|
}
|
|
53260
53794
|
const scored = VALID_COMMANDS.map((cmd) => {
|
|
53261
53795
|
const cmdLower = cmd.toLowerCase();
|
|
53262
|
-
const fullScore =
|
|
53796
|
+
const fullScore = _internals30.levenshteinDistance(q, cmdLower);
|
|
53263
53797
|
let tokenScore = Infinity;
|
|
53264
53798
|
if (cmd.includes(" ") || cmd.includes("-")) {
|
|
53265
53799
|
const qTokens = q.split(/[\s-]+/);
|
|
@@ -53272,7 +53806,7 @@ function findSimilarCommands(query) {
|
|
|
53272
53806
|
for (const ct of cmdTokens) {
|
|
53273
53807
|
if (ct.length === 0)
|
|
53274
53808
|
continue;
|
|
53275
|
-
const dist =
|
|
53809
|
+
const dist = _internals30.levenshteinDistance(qt, ct);
|
|
53276
53810
|
if (dist < minDist)
|
|
53277
53811
|
minDist = dist;
|
|
53278
53812
|
}
|
|
@@ -53282,7 +53816,7 @@ function findSimilarCommands(query) {
|
|
|
53282
53816
|
}
|
|
53283
53817
|
const dashStrippedQ = q.replace(/-/g, "");
|
|
53284
53818
|
const dashStrippedCmd = cmdLower.replace(/-/g, "");
|
|
53285
|
-
const dashScore =
|
|
53819
|
+
const dashScore = _internals30.levenshteinDistance(dashStrippedQ, dashStrippedCmd);
|
|
53286
53820
|
const score = Math.min(fullScore, tokenScore, dashScore);
|
|
53287
53821
|
return { cmd, score };
|
|
53288
53822
|
});
|
|
@@ -53314,11 +53848,11 @@ async function handleHelpCommand(ctx) {
|
|
|
53314
53848
|
return buildHelpText2();
|
|
53315
53849
|
}
|
|
53316
53850
|
const tokens = targetCommand.split(/\s+/);
|
|
53317
|
-
const resolved =
|
|
53851
|
+
const resolved = _internals30.resolveCommand(tokens);
|
|
53318
53852
|
if (resolved) {
|
|
53319
|
-
return
|
|
53853
|
+
return _internals30.buildDetailedHelp(resolved.key, resolved.entry);
|
|
53320
53854
|
}
|
|
53321
|
-
const similar =
|
|
53855
|
+
const similar = _internals30.findSimilarCommands(targetCommand);
|
|
53322
53856
|
const { buildHelpText: fullHelp } = await Promise.resolve().then(() => (init_commands(), exports_commands));
|
|
53323
53857
|
if (similar.length > 0) {
|
|
53324
53858
|
return `Command '/swarm ${targetCommand}' not found.
|
|
@@ -53354,24 +53888,24 @@ function validateAliases() {
|
|
|
53354
53888
|
}
|
|
53355
53889
|
aliasTargets.get(target).push(name);
|
|
53356
53890
|
const visited = new Set;
|
|
53357
|
-
const
|
|
53891
|
+
const path48 = [];
|
|
53358
53892
|
let current = target;
|
|
53359
53893
|
while (current) {
|
|
53360
53894
|
const currentEntry = COMMAND_REGISTRY[current];
|
|
53361
53895
|
if (!currentEntry)
|
|
53362
53896
|
break;
|
|
53363
53897
|
if (visited.has(current)) {
|
|
53364
|
-
const cycleStart =
|
|
53898
|
+
const cycleStart = path48.indexOf(current);
|
|
53365
53899
|
const fullChain = [
|
|
53366
53900
|
name,
|
|
53367
|
-
...
|
|
53901
|
+
...path48.slice(0, cycleStart > 0 ? cycleStart : path48.length),
|
|
53368
53902
|
current
|
|
53369
53903
|
].join(" \u2192 ");
|
|
53370
53904
|
errors5.push(`Circular alias detected: ${fullChain}`);
|
|
53371
53905
|
break;
|
|
53372
53906
|
}
|
|
53373
53907
|
visited.add(current);
|
|
53374
|
-
|
|
53908
|
+
path48.push(current);
|
|
53375
53909
|
current = currentEntry.aliasOf || "";
|
|
53376
53910
|
}
|
|
53377
53911
|
}
|
|
@@ -53412,7 +53946,7 @@ function resolveCommand(tokens) {
|
|
|
53412
53946
|
}
|
|
53413
53947
|
return null;
|
|
53414
53948
|
}
|
|
53415
|
-
var COMMAND_REGISTRY, VALID_COMMANDS,
|
|
53949
|
+
var COMMAND_REGISTRY, VALID_COMMANDS, _internals30, validation;
|
|
53416
53950
|
var init_registry = __esm(() => {
|
|
53417
53951
|
init_acknowledge_spec_drift();
|
|
53418
53952
|
init_agents();
|
|
@@ -53482,7 +54016,7 @@ var init_registry = __esm(() => {
|
|
|
53482
54016
|
clashesWithNativeCcCommand: "/agents"
|
|
53483
54017
|
},
|
|
53484
54018
|
help: {
|
|
53485
|
-
handler: (ctx) =>
|
|
54019
|
+
handler: (ctx) => _internals30.handleHelpCommand(ctx),
|
|
53486
54020
|
description: "Show help for swarm commands",
|
|
53487
54021
|
category: "core",
|
|
53488
54022
|
args: "[command]",
|
|
@@ -53854,7 +54388,7 @@ Subcommands:
|
|
|
53854
54388
|
}
|
|
53855
54389
|
};
|
|
53856
54390
|
VALID_COMMANDS = Object.keys(COMMAND_REGISTRY);
|
|
53857
|
-
|
|
54391
|
+
_internals30 = {
|
|
53858
54392
|
handleHelpCommand,
|
|
53859
54393
|
validateAliases,
|
|
53860
54394
|
resolveCommand,
|
|
@@ -53862,7 +54396,7 @@ Subcommands:
|
|
|
53862
54396
|
findSimilarCommands,
|
|
53863
54397
|
buildDetailedHelp
|
|
53864
54398
|
};
|
|
53865
|
-
validation =
|
|
54399
|
+
validation = _internals30.validateAliases();
|
|
53866
54400
|
if (!validation.valid) {
|
|
53867
54401
|
throw new Error(`COMMAND_REGISTRY alias validation failed:
|
|
53868
54402
|
${validation.errors.join(`
|
|
@@ -53882,53 +54416,53 @@ init_cache_paths();
|
|
|
53882
54416
|
init_constants();
|
|
53883
54417
|
import * as fs29 from "fs";
|
|
53884
54418
|
import * as os7 from "os";
|
|
53885
|
-
import * as
|
|
54419
|
+
import * as path48 from "path";
|
|
53886
54420
|
var { version: version4 } = package_default;
|
|
53887
54421
|
var CONFIG_DIR = getPluginConfigDir();
|
|
53888
|
-
var OPENCODE_CONFIG_PATH =
|
|
53889
|
-
var PLUGIN_CONFIG_PATH =
|
|
53890
|
-
var PROMPTS_DIR =
|
|
54422
|
+
var OPENCODE_CONFIG_PATH = path48.join(CONFIG_DIR, "opencode.json");
|
|
54423
|
+
var PLUGIN_CONFIG_PATH = path48.join(CONFIG_DIR, "opencode-swarm.json");
|
|
54424
|
+
var PROMPTS_DIR = path48.join(CONFIG_DIR, "opencode-swarm");
|
|
53891
54425
|
var OPENCODE_PLUGIN_CACHE_PATHS = getPluginCachePaths();
|
|
53892
54426
|
var OPENCODE_PLUGIN_LOCK_FILE_PATHS = getPluginLockFilePaths();
|
|
53893
54427
|
function isSafeCachePath(p) {
|
|
53894
|
-
const resolved =
|
|
53895
|
-
const home =
|
|
54428
|
+
const resolved = path48.resolve(p);
|
|
54429
|
+
const home = path48.resolve(os7.homedir());
|
|
53896
54430
|
if (resolved === "/" || resolved === home || resolved.length <= home.length) {
|
|
53897
54431
|
return false;
|
|
53898
54432
|
}
|
|
53899
|
-
const segments = resolved.split(
|
|
54433
|
+
const segments = resolved.split(path48.sep).filter((s) => s.length > 0);
|
|
53900
54434
|
if (segments.length < 4) {
|
|
53901
54435
|
return false;
|
|
53902
54436
|
}
|
|
53903
|
-
const leaf =
|
|
54437
|
+
const leaf = path48.basename(resolved);
|
|
53904
54438
|
if (leaf !== "opencode-swarm@latest" && leaf !== "opencode-swarm") {
|
|
53905
54439
|
return false;
|
|
53906
54440
|
}
|
|
53907
|
-
const parent =
|
|
54441
|
+
const parent = path48.basename(path48.dirname(resolved));
|
|
53908
54442
|
if (parent !== "packages" && parent !== "node_modules") {
|
|
53909
54443
|
return false;
|
|
53910
54444
|
}
|
|
53911
|
-
const grandparent =
|
|
54445
|
+
const grandparent = path48.basename(path48.dirname(path48.dirname(resolved)));
|
|
53912
54446
|
if (grandparent !== "opencode") {
|
|
53913
54447
|
return false;
|
|
53914
54448
|
}
|
|
53915
54449
|
return true;
|
|
53916
54450
|
}
|
|
53917
54451
|
function isSafeLockFilePath(p) {
|
|
53918
|
-
const resolved =
|
|
53919
|
-
const home =
|
|
54452
|
+
const resolved = path48.resolve(p);
|
|
54453
|
+
const home = path48.resolve(os7.homedir());
|
|
53920
54454
|
if (resolved === "/" || resolved === home || resolved.length <= home.length) {
|
|
53921
54455
|
return false;
|
|
53922
54456
|
}
|
|
53923
|
-
const segments = resolved.split(
|
|
54457
|
+
const segments = resolved.split(path48.sep).filter((s) => s.length > 0);
|
|
53924
54458
|
if (segments.length < 4) {
|
|
53925
54459
|
return false;
|
|
53926
54460
|
}
|
|
53927
|
-
const leaf =
|
|
54461
|
+
const leaf = path48.basename(resolved);
|
|
53928
54462
|
if (leaf !== "bun.lock" && leaf !== "bun.lockb" && leaf !== "package-lock.json") {
|
|
53929
54463
|
return false;
|
|
53930
54464
|
}
|
|
53931
|
-
const parent =
|
|
54465
|
+
const parent = path48.basename(path48.dirname(resolved));
|
|
53932
54466
|
if (parent !== "opencode") {
|
|
53933
54467
|
return false;
|
|
53934
54468
|
}
|
|
@@ -53954,8 +54488,8 @@ function saveJson(filepath, data) {
|
|
|
53954
54488
|
}
|
|
53955
54489
|
function writeProjectConfigIfMissing(cwd) {
|
|
53956
54490
|
try {
|
|
53957
|
-
const opencodeDir =
|
|
53958
|
-
const projectConfigPath =
|
|
54491
|
+
const opencodeDir = path48.join(cwd, ".opencode");
|
|
54492
|
+
const projectConfigPath = path48.join(opencodeDir, "opencode-swarm.json");
|
|
53959
54493
|
if (fs29.existsSync(projectConfigPath)) {
|
|
53960
54494
|
return;
|
|
53961
54495
|
}
|
|
@@ -53972,7 +54506,7 @@ async function install() {
|
|
|
53972
54506
|
`);
|
|
53973
54507
|
ensureDir(CONFIG_DIR);
|
|
53974
54508
|
ensureDir(PROMPTS_DIR);
|
|
53975
|
-
const LEGACY_CONFIG_PATH =
|
|
54509
|
+
const LEGACY_CONFIG_PATH = path48.join(CONFIG_DIR, "config.json");
|
|
53976
54510
|
let opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
|
|
53977
54511
|
if (!opencodeConfig) {
|
|
53978
54512
|
const legacyConfig = loadJson(LEGACY_CONFIG_PATH);
|