opencode-swarm 7.33.0 → 7.33.1
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 +1047 -516
- package/dist/evidence/gate-bridge.d.ts +15 -0
- package/dist/index.js +403 -155
- 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/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.1",
|
|
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();
|
|
@@ -38906,9 +39205,9 @@ async function detectDarkMatter(directory, options) {
|
|
|
38906
39205
|
} catch {
|
|
38907
39206
|
return [];
|
|
38908
39207
|
}
|
|
38909
|
-
const commitMap = await
|
|
38910
|
-
const matrix =
|
|
38911
|
-
const staticEdges = await
|
|
39208
|
+
const commitMap = await _internals11.parseGitLog(directory, maxCommitsToAnalyze);
|
|
39209
|
+
const matrix = _internals11.buildCoChangeMatrix(commitMap);
|
|
39210
|
+
const staticEdges = await _internals11.getStaticEdges(directory);
|
|
38912
39211
|
const results = [];
|
|
38913
39212
|
for (const entry of matrix.values()) {
|
|
38914
39213
|
const key = `${entry.fileA}::${entry.fileB}`;
|
|
@@ -38988,7 +39287,7 @@ ${rows}
|
|
|
38988
39287
|
These pairs likely share an architectural concern invisible to static analysis.
|
|
38989
39288
|
Consider adding explicit documentation or extracting the shared concern.`;
|
|
38990
39289
|
}
|
|
38991
|
-
var co_change_analyzer,
|
|
39290
|
+
var co_change_analyzer, _internals11;
|
|
38992
39291
|
var init_co_change_analyzer = __esm(() => {
|
|
38993
39292
|
init_zod();
|
|
38994
39293
|
init_create_tool();
|
|
@@ -39020,11 +39319,11 @@ var init_co_change_analyzer = __esm(() => {
|
|
|
39020
39319
|
npmiThreshold,
|
|
39021
39320
|
maxCommitsToAnalyze
|
|
39022
39321
|
};
|
|
39023
|
-
const pairs = await
|
|
39024
|
-
return
|
|
39322
|
+
const pairs = await _internals11.detectDarkMatter(directory, options);
|
|
39323
|
+
return _internals11.formatDarkMatterOutput(pairs);
|
|
39025
39324
|
}
|
|
39026
39325
|
});
|
|
39027
|
-
|
|
39326
|
+
_internals11 = {
|
|
39028
39327
|
parseGitLog,
|
|
39029
39328
|
buildCoChangeMatrix,
|
|
39030
39329
|
getStaticEdges,
|
|
@@ -39055,7 +39354,7 @@ async function handleDarkMatterCommand(directory, args) {
|
|
|
39055
39354
|
}
|
|
39056
39355
|
let pairs;
|
|
39057
39356
|
try {
|
|
39058
|
-
pairs = await
|
|
39357
|
+
pairs = await _internals11.detectDarkMatter(directory, options);
|
|
39059
39358
|
} catch (err) {
|
|
39060
39359
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
39061
39360
|
return `## Dark Matter Analysis Failed
|
|
@@ -39247,24 +39546,213 @@ function getPluginLockFilePaths() {
|
|
|
39247
39546
|
}
|
|
39248
39547
|
var init_cache_paths = () => {};
|
|
39249
39548
|
|
|
39549
|
+
// src/evidence/task-file.ts
|
|
39550
|
+
import * as path21 from "path";
|
|
39551
|
+
function taskEvidenceRelPath(taskId) {
|
|
39552
|
+
return path21.join("evidence", `${taskId}.json`);
|
|
39553
|
+
}
|
|
39554
|
+
function taskEvidencePath(directory, taskId) {
|
|
39555
|
+
return path21.join(directory, ".swarm", taskEvidenceRelPath(taskId));
|
|
39556
|
+
}
|
|
39557
|
+
var init_task_file = __esm(() => {
|
|
39558
|
+
init_bun_compat();
|
|
39559
|
+
init_lock();
|
|
39560
|
+
});
|
|
39561
|
+
|
|
39562
|
+
// src/gate-evidence.ts
|
|
39563
|
+
import { mkdirSync as mkdirSync7, readFileSync as readFileSync6 } from "fs";
|
|
39564
|
+
function isValidTaskId(taskId) {
|
|
39565
|
+
return isStrictTaskId(taskId);
|
|
39566
|
+
}
|
|
39567
|
+
function assertValidTaskId(taskId) {
|
|
39568
|
+
assertStrictTaskId(taskId);
|
|
39569
|
+
}
|
|
39570
|
+
function getEvidencePath(directory, taskId) {
|
|
39571
|
+
assertValidTaskId(taskId);
|
|
39572
|
+
return taskEvidencePath(directory, taskId);
|
|
39573
|
+
}
|
|
39574
|
+
function readExisting(evidencePath, taskId) {
|
|
39575
|
+
try {
|
|
39576
|
+
const raw = readFileSync6(evidencePath, "utf-8");
|
|
39577
|
+
return TaskEvidenceSchema.parse(JSON.parse(raw));
|
|
39578
|
+
} catch (error93) {
|
|
39579
|
+
if (error93.code === "ENOENT")
|
|
39580
|
+
return null;
|
|
39581
|
+
telemetry.gateParseError(taskId, error93);
|
|
39582
|
+
throw error93;
|
|
39583
|
+
}
|
|
39584
|
+
}
|
|
39585
|
+
async function readTaskEvidence(directory, taskId) {
|
|
39586
|
+
try {
|
|
39587
|
+
assertValidTaskId(taskId);
|
|
39588
|
+
return readExisting(getEvidencePath(directory, taskId), taskId);
|
|
39589
|
+
} catch {
|
|
39590
|
+
return null;
|
|
39591
|
+
}
|
|
39592
|
+
}
|
|
39593
|
+
function readTaskEvidenceRaw(directory, taskId) {
|
|
39594
|
+
assertValidTaskId(taskId);
|
|
39595
|
+
const evidencePath = getEvidencePath(directory, taskId);
|
|
39596
|
+
try {
|
|
39597
|
+
const raw = readFileSync6(evidencePath, "utf-8");
|
|
39598
|
+
return TaskEvidenceSchema.parse(JSON.parse(raw));
|
|
39599
|
+
} catch (error93) {
|
|
39600
|
+
if (error93.code === "ENOENT")
|
|
39601
|
+
return null;
|
|
39602
|
+
throw error93;
|
|
39603
|
+
}
|
|
39604
|
+
}
|
|
39605
|
+
var GateEvidenceSchema, TaskEvidenceSchema;
|
|
39606
|
+
var init_gate_evidence = __esm(() => {
|
|
39607
|
+
init_zod();
|
|
39608
|
+
init_task_file();
|
|
39609
|
+
init_telemetry();
|
|
39610
|
+
init_task_id();
|
|
39611
|
+
GateEvidenceSchema = exports_external.object({
|
|
39612
|
+
sessionId: exports_external.string(),
|
|
39613
|
+
timestamp: exports_external.string(),
|
|
39614
|
+
agent: exports_external.string()
|
|
39615
|
+
}).passthrough();
|
|
39616
|
+
TaskEvidenceSchema = exports_external.object({
|
|
39617
|
+
taskId: exports_external.string(),
|
|
39618
|
+
required_gates: exports_external.array(exports_external.string()).default([]),
|
|
39619
|
+
gates: exports_external.record(exports_external.string(), GateEvidenceSchema),
|
|
39620
|
+
turbo: exports_external.boolean().optional()
|
|
39621
|
+
});
|
|
39622
|
+
});
|
|
39623
|
+
|
|
39624
|
+
// src/evidence/gate-bridge.ts
|
|
39625
|
+
async function readDurableGateEvidence(directory, taskId) {
|
|
39626
|
+
try {
|
|
39627
|
+
return await readTaskEvidence(directory, taskId);
|
|
39628
|
+
} catch {
|
|
39629
|
+
return null;
|
|
39630
|
+
}
|
|
39631
|
+
}
|
|
39632
|
+
function getDurableGateEvidenceStatus(evidence) {
|
|
39633
|
+
if (!evidence?.gates || typeof evidence.gates !== "object") {
|
|
39634
|
+
return {
|
|
39635
|
+
isComplete: false,
|
|
39636
|
+
missingGates: [],
|
|
39637
|
+
evidenceExists: evidence != null,
|
|
39638
|
+
invalid: false
|
|
39639
|
+
};
|
|
39640
|
+
}
|
|
39641
|
+
if (!Array.isArray(evidence.required_gates) || evidence.required_gates.length === 0) {
|
|
39642
|
+
return {
|
|
39643
|
+
isComplete: false,
|
|
39644
|
+
missingGates: ["required_gates"],
|
|
39645
|
+
evidenceExists: true,
|
|
39646
|
+
invalid: false
|
|
39647
|
+
};
|
|
39648
|
+
}
|
|
39649
|
+
const missingGates = evidence.required_gates.filter((gate) => evidence.gates[gate] == null);
|
|
39650
|
+
return {
|
|
39651
|
+
isComplete: missingGates.length === 0,
|
|
39652
|
+
missingGates,
|
|
39653
|
+
evidenceExists: true,
|
|
39654
|
+
invalid: false
|
|
39655
|
+
};
|
|
39656
|
+
}
|
|
39657
|
+
async function getDurableGateEvidenceStatusForTask(directory, taskId) {
|
|
39658
|
+
if (!isValidTaskId(taskId)) {
|
|
39659
|
+
return {
|
|
39660
|
+
isComplete: false,
|
|
39661
|
+
missingGates: [],
|
|
39662
|
+
evidenceExists: false,
|
|
39663
|
+
invalid: false
|
|
39664
|
+
};
|
|
39665
|
+
}
|
|
39666
|
+
try {
|
|
39667
|
+
return getDurableGateEvidenceStatus(readTaskEvidenceRaw(directory, taskId));
|
|
39668
|
+
} catch {
|
|
39669
|
+
return {
|
|
39670
|
+
isComplete: false,
|
|
39671
|
+
missingGates: ["invalid_gate_evidence"],
|
|
39672
|
+
evidenceExists: true,
|
|
39673
|
+
invalid: true
|
|
39674
|
+
};
|
|
39675
|
+
}
|
|
39676
|
+
}
|
|
39677
|
+
function gateEvidenceToEntry(taskId, gate, type, evidence) {
|
|
39678
|
+
const gateRecord = evidence.gates[gate];
|
|
39679
|
+
if (!gateRecord) {
|
|
39680
|
+
return null;
|
|
39681
|
+
}
|
|
39682
|
+
const base = {
|
|
39683
|
+
task_id: taskId,
|
|
39684
|
+
timestamp: gateRecord.timestamp,
|
|
39685
|
+
agent: gateRecord.agent || gate,
|
|
39686
|
+
verdict: "pass",
|
|
39687
|
+
summary: `Gate evidence recorded by ${gate}`,
|
|
39688
|
+
metadata: { source: "durable_gate_evidence", gate }
|
|
39689
|
+
};
|
|
39690
|
+
if (type === "review") {
|
|
39691
|
+
return {
|
|
39692
|
+
...base,
|
|
39693
|
+
type,
|
|
39694
|
+
risk: "low",
|
|
39695
|
+
issues: []
|
|
39696
|
+
};
|
|
39697
|
+
}
|
|
39698
|
+
if (type === "approval") {
|
|
39699
|
+
return {
|
|
39700
|
+
...base,
|
|
39701
|
+
type
|
|
39702
|
+
};
|
|
39703
|
+
}
|
|
39704
|
+
return {
|
|
39705
|
+
...base,
|
|
39706
|
+
type,
|
|
39707
|
+
tests_passed: 0,
|
|
39708
|
+
tests_failed: 0,
|
|
39709
|
+
failures: []
|
|
39710
|
+
};
|
|
39711
|
+
}
|
|
39712
|
+
function mergeDurableGateEntriesFromEvidence(taskId, entries, evidence) {
|
|
39713
|
+
if (!evidence?.gates) {
|
|
39714
|
+
return entries;
|
|
39715
|
+
}
|
|
39716
|
+
const merged = [...entries];
|
|
39717
|
+
for (const gate of Object.keys(evidence.gates).sort()) {
|
|
39718
|
+
const type = GATE_EVIDENCE_TYPE_BY_GATE[gate] ?? "approval";
|
|
39719
|
+
if ((type === "review" || type === "test") && merged.some((entry2) => entry2.type === type)) {
|
|
39720
|
+
continue;
|
|
39721
|
+
}
|
|
39722
|
+
const entry = gateEvidenceToEntry(taskId, gate, type, evidence);
|
|
39723
|
+
if (entry) {
|
|
39724
|
+
merged.push(entry);
|
|
39725
|
+
}
|
|
39726
|
+
}
|
|
39727
|
+
return merged;
|
|
39728
|
+
}
|
|
39729
|
+
var GATE_EVIDENCE_TYPE_BY_GATE;
|
|
39730
|
+
var init_gate_bridge = __esm(() => {
|
|
39731
|
+
init_gate_evidence();
|
|
39732
|
+
GATE_EVIDENCE_TYPE_BY_GATE = {
|
|
39733
|
+
reviewer: "review",
|
|
39734
|
+
test_engineer: "test"
|
|
39735
|
+
};
|
|
39736
|
+
});
|
|
39737
|
+
|
|
39250
39738
|
// src/services/version-check.ts
|
|
39251
|
-
import { existsSync as existsSync11, mkdirSync as
|
|
39739
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
|
|
39252
39740
|
import { homedir as homedir5 } from "os";
|
|
39253
|
-
import { join as
|
|
39741
|
+
import { join as join20 } from "path";
|
|
39254
39742
|
function cacheDir() {
|
|
39255
39743
|
const xdg = process.env.XDG_CACHE_HOME;
|
|
39256
|
-
const base = xdg && xdg.length > 0 ? xdg :
|
|
39257
|
-
return
|
|
39744
|
+
const base = xdg && xdg.length > 0 ? xdg : join20(homedir5(), ".cache");
|
|
39745
|
+
return join20(base, "opencode-swarm");
|
|
39258
39746
|
}
|
|
39259
39747
|
function cacheFile() {
|
|
39260
|
-
return
|
|
39748
|
+
return join20(cacheDir(), "version-check.json");
|
|
39261
39749
|
}
|
|
39262
39750
|
function readVersionCache() {
|
|
39263
39751
|
try {
|
|
39264
|
-
const
|
|
39265
|
-
if (!existsSync11(
|
|
39752
|
+
const path22 = cacheFile();
|
|
39753
|
+
if (!existsSync11(path22))
|
|
39266
39754
|
return null;
|
|
39267
|
-
const raw =
|
|
39755
|
+
const raw = readFileSync7(path22, "utf-8");
|
|
39268
39756
|
const parsed = JSON.parse(raw);
|
|
39269
39757
|
if (typeof parsed?.checkedAt !== "number")
|
|
39270
39758
|
return null;
|
|
@@ -39303,8 +39791,8 @@ var init_version_check = __esm(() => {
|
|
|
39303
39791
|
|
|
39304
39792
|
// src/services/diagnose-service.ts
|
|
39305
39793
|
import * as child_process4 from "child_process";
|
|
39306
|
-
import { existsSync as existsSync12, readdirSync as readdirSync4, readFileSync as
|
|
39307
|
-
import
|
|
39794
|
+
import { existsSync as existsSync12, readdirSync as readdirSync4, readFileSync as readFileSync8, statSync as statSync6 } from "fs";
|
|
39795
|
+
import path22 from "path";
|
|
39308
39796
|
import { fileURLToPath } from "url";
|
|
39309
39797
|
function validateTaskDag(plan) {
|
|
39310
39798
|
const allTaskIds = new Set;
|
|
@@ -39336,7 +39824,21 @@ async function checkEvidenceCompleteness(directory, plan) {
|
|
|
39336
39824
|
}
|
|
39337
39825
|
if (completedTaskIds.length > 0) {
|
|
39338
39826
|
const evidenceTaskIds = new Set(await listEvidenceTaskIds(directory));
|
|
39339
|
-
const missingEvidence =
|
|
39827
|
+
const missingEvidence = [];
|
|
39828
|
+
for (const id of completedTaskIds) {
|
|
39829
|
+
const gateStatus = await getDurableGateEvidenceStatusForTask(directory, id);
|
|
39830
|
+
if (gateStatus.isComplete) {
|
|
39831
|
+
continue;
|
|
39832
|
+
}
|
|
39833
|
+
if (gateStatus.evidenceExists && gateStatus.missingGates.length > 0) {
|
|
39834
|
+
missingEvidence.push(id);
|
|
39835
|
+
continue;
|
|
39836
|
+
}
|
|
39837
|
+
if (evidenceTaskIds.has(id)) {
|
|
39838
|
+
continue;
|
|
39839
|
+
}
|
|
39840
|
+
missingEvidence.push(id);
|
|
39841
|
+
}
|
|
39340
39842
|
if (missingEvidence.length === 0) {
|
|
39341
39843
|
return {
|
|
39342
39844
|
name: "Evidence",
|
|
@@ -39601,7 +40103,7 @@ async function checkSpecStaleness(directory, plan) {
|
|
|
39601
40103
|
};
|
|
39602
40104
|
}
|
|
39603
40105
|
async function checkConfigParseability(directory) {
|
|
39604
|
-
const configPath =
|
|
40106
|
+
const configPath = path22.join(directory, ".opencode/opencode-swarm.json");
|
|
39605
40107
|
if (!existsSync12(configPath)) {
|
|
39606
40108
|
return {
|
|
39607
40109
|
name: "Config Parseability",
|
|
@@ -39610,7 +40112,7 @@ async function checkConfigParseability(directory) {
|
|
|
39610
40112
|
};
|
|
39611
40113
|
}
|
|
39612
40114
|
try {
|
|
39613
|
-
const content =
|
|
40115
|
+
const content = readFileSync8(configPath, "utf-8");
|
|
39614
40116
|
JSON.parse(content);
|
|
39615
40117
|
return {
|
|
39616
40118
|
name: "Config Parseability",
|
|
@@ -39630,7 +40132,7 @@ function resolveGrammarDir(thisDir) {
|
|
|
39630
40132
|
const normalized = thisDir.replace(/\\/g, "/");
|
|
39631
40133
|
const isSource = normalized.endsWith("/src/services");
|
|
39632
40134
|
const isCliBundle = normalized.endsWith("/cli");
|
|
39633
|
-
return isSource || isCliBundle ?
|
|
40135
|
+
return isSource || isCliBundle ? path22.join(thisDir, "..", "lang", "grammars") : path22.join(thisDir, "lang", "grammars");
|
|
39634
40136
|
}
|
|
39635
40137
|
async function checkGrammarWasmFiles() {
|
|
39636
40138
|
const grammarFiles = [
|
|
@@ -39654,14 +40156,14 @@ async function checkGrammarWasmFiles() {
|
|
|
39654
40156
|
"tree-sitter-ini.wasm",
|
|
39655
40157
|
"tree-sitter-regex.wasm"
|
|
39656
40158
|
];
|
|
39657
|
-
const thisDir =
|
|
40159
|
+
const thisDir = path22.dirname(fileURLToPath(import.meta.url));
|
|
39658
40160
|
const grammarDir = resolveGrammarDir(thisDir);
|
|
39659
40161
|
const missing = [];
|
|
39660
|
-
if (!existsSync12(
|
|
40162
|
+
if (!existsSync12(path22.join(grammarDir, "tree-sitter.wasm"))) {
|
|
39661
40163
|
missing.push("tree-sitter.wasm (core runtime)");
|
|
39662
40164
|
}
|
|
39663
40165
|
for (const file3 of grammarFiles) {
|
|
39664
|
-
if (!existsSync12(
|
|
40166
|
+
if (!existsSync12(path22.join(grammarDir, file3))) {
|
|
39665
40167
|
missing.push(file3);
|
|
39666
40168
|
}
|
|
39667
40169
|
}
|
|
@@ -39679,7 +40181,7 @@ async function checkGrammarWasmFiles() {
|
|
|
39679
40181
|
};
|
|
39680
40182
|
}
|
|
39681
40183
|
async function checkCheckpointManifest(directory) {
|
|
39682
|
-
const manifestPath =
|
|
40184
|
+
const manifestPath = path22.join(directory, ".swarm/checkpoints.json");
|
|
39683
40185
|
if (!existsSync12(manifestPath)) {
|
|
39684
40186
|
return {
|
|
39685
40187
|
name: "Checkpoint Manifest",
|
|
@@ -39688,7 +40190,7 @@ async function checkCheckpointManifest(directory) {
|
|
|
39688
40190
|
};
|
|
39689
40191
|
}
|
|
39690
40192
|
try {
|
|
39691
|
-
const content =
|
|
40193
|
+
const content = readFileSync8(manifestPath, "utf-8");
|
|
39692
40194
|
const parsed = JSON.parse(content);
|
|
39693
40195
|
if (!parsed.checkpoints || !Array.isArray(parsed.checkpoints)) {
|
|
39694
40196
|
return {
|
|
@@ -39731,7 +40233,7 @@ async function checkCheckpointManifest(directory) {
|
|
|
39731
40233
|
}
|
|
39732
40234
|
}
|
|
39733
40235
|
async function checkEventStreamIntegrity(directory) {
|
|
39734
|
-
const eventsPath =
|
|
40236
|
+
const eventsPath = path22.join(directory, ".swarm/events.jsonl");
|
|
39735
40237
|
if (!existsSync12(eventsPath)) {
|
|
39736
40238
|
return {
|
|
39737
40239
|
name: "Event Stream",
|
|
@@ -39740,7 +40242,7 @@ async function checkEventStreamIntegrity(directory) {
|
|
|
39740
40242
|
};
|
|
39741
40243
|
}
|
|
39742
40244
|
try {
|
|
39743
|
-
const content =
|
|
40245
|
+
const content = readFileSync8(eventsPath, "utf-8");
|
|
39744
40246
|
const lines = content.split(`
|
|
39745
40247
|
`).filter((line) => line.trim() !== "");
|
|
39746
40248
|
let malformedCount = 0;
|
|
@@ -39772,7 +40274,7 @@ async function checkEventStreamIntegrity(directory) {
|
|
|
39772
40274
|
}
|
|
39773
40275
|
}
|
|
39774
40276
|
async function checkSteeringDirectives(directory) {
|
|
39775
|
-
const eventsPath =
|
|
40277
|
+
const eventsPath = path22.join(directory, ".swarm/events.jsonl");
|
|
39776
40278
|
if (!existsSync12(eventsPath)) {
|
|
39777
40279
|
return {
|
|
39778
40280
|
name: "Steering Directives",
|
|
@@ -39781,7 +40283,7 @@ async function checkSteeringDirectives(directory) {
|
|
|
39781
40283
|
};
|
|
39782
40284
|
}
|
|
39783
40285
|
try {
|
|
39784
|
-
const content =
|
|
40286
|
+
const content = readFileSync8(eventsPath, "utf-8");
|
|
39785
40287
|
const lines = content.split(`
|
|
39786
40288
|
`).filter((line) => line.trim() !== "");
|
|
39787
40289
|
const directivesIssued = [];
|
|
@@ -39828,7 +40330,7 @@ async function checkCurator(directory) {
|
|
|
39828
40330
|
detail: "Disabled (enable via curator.enabled)"
|
|
39829
40331
|
};
|
|
39830
40332
|
}
|
|
39831
|
-
const summaryPath =
|
|
40333
|
+
const summaryPath = path22.join(directory, ".swarm/curator-summary.json");
|
|
39832
40334
|
if (!existsSync12(summaryPath)) {
|
|
39833
40335
|
return {
|
|
39834
40336
|
name: "Curator",
|
|
@@ -39837,7 +40339,7 @@ async function checkCurator(directory) {
|
|
|
39837
40339
|
};
|
|
39838
40340
|
}
|
|
39839
40341
|
try {
|
|
39840
|
-
const content =
|
|
40342
|
+
const content = readFileSync8(summaryPath, "utf-8");
|
|
39841
40343
|
const parsed = JSON.parse(content);
|
|
39842
40344
|
if (typeof parsed.schema_version !== "number" || parsed.schema_version !== 1) {
|
|
39843
40345
|
return {
|
|
@@ -39994,7 +40496,7 @@ async function getDiagnoseData(directory) {
|
|
|
39994
40496
|
checks5.push(await checkSteeringDirectives(directory));
|
|
39995
40497
|
checks5.push(await checkCurator(directory));
|
|
39996
40498
|
try {
|
|
39997
|
-
const evidenceDir =
|
|
40499
|
+
const evidenceDir = path22.join(directory, ".swarm", "evidence");
|
|
39998
40500
|
const snapshotFiles = existsSync12(evidenceDir) ? readdirSync4(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
|
|
39999
40501
|
if (snapshotFiles.length > 0) {
|
|
40000
40502
|
const latest = snapshotFiles.sort().pop();
|
|
@@ -40032,9 +40534,9 @@ async function getDiagnoseData(directory) {
|
|
|
40032
40534
|
cacheRows.push(`\u2B1C ${cachePath} \u2014 absent`);
|
|
40033
40535
|
continue;
|
|
40034
40536
|
}
|
|
40035
|
-
const pkgJsonPath =
|
|
40537
|
+
const pkgJsonPath = path22.join(cachePath, "package.json");
|
|
40036
40538
|
try {
|
|
40037
|
-
const raw =
|
|
40539
|
+
const raw = readFileSync8(pkgJsonPath, "utf-8");
|
|
40038
40540
|
const parsed = JSON.parse(raw);
|
|
40039
40541
|
const installedVersion = typeof parsed.version === "string" ? parsed.version : "?";
|
|
40040
40542
|
cacheRows.push(`\u2705 ${cachePath} \u2014 v${installedVersion}`);
|
|
@@ -40091,6 +40593,7 @@ var init_diagnose_service = __esm(() => {
|
|
|
40091
40593
|
init_package();
|
|
40092
40594
|
init_cache_paths();
|
|
40093
40595
|
init_loader();
|
|
40596
|
+
init_gate_bridge();
|
|
40094
40597
|
init_manager2();
|
|
40095
40598
|
init_utils2();
|
|
40096
40599
|
init_manager();
|
|
@@ -40122,13 +40625,13 @@ __export(exports_config_doctor, {
|
|
|
40122
40625
|
import * as crypto3 from "crypto";
|
|
40123
40626
|
import * as fs8 from "fs";
|
|
40124
40627
|
import * as os6 from "os";
|
|
40125
|
-
import * as
|
|
40628
|
+
import * as path23 from "path";
|
|
40126
40629
|
function getUserConfigDir3() {
|
|
40127
|
-
return process.env.XDG_CONFIG_HOME ||
|
|
40630
|
+
return process.env.XDG_CONFIG_HOME || path23.join(os6.homedir(), ".config");
|
|
40128
40631
|
}
|
|
40129
40632
|
function getConfigPaths(directory) {
|
|
40130
|
-
const userConfigPath =
|
|
40131
|
-
const projectConfigPath =
|
|
40633
|
+
const userConfigPath = path23.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
|
|
40634
|
+
const projectConfigPath = path23.join(directory, ".opencode", "opencode-swarm.json");
|
|
40132
40635
|
return { userConfigPath, projectConfigPath };
|
|
40133
40636
|
}
|
|
40134
40637
|
function computeHash(content) {
|
|
@@ -40153,9 +40656,9 @@ function isValidConfigPath(configPath, directory) {
|
|
|
40153
40656
|
const normalizedUser = userConfigPath.replace(/\\/g, "/");
|
|
40154
40657
|
const normalizedProject = projectConfigPath.replace(/\\/g, "/");
|
|
40155
40658
|
try {
|
|
40156
|
-
const resolvedConfig =
|
|
40157
|
-
const resolvedUser =
|
|
40158
|
-
const resolvedProject =
|
|
40659
|
+
const resolvedConfig = path23.resolve(configPath);
|
|
40660
|
+
const resolvedUser = path23.resolve(normalizedUser);
|
|
40661
|
+
const resolvedProject = path23.resolve(normalizedProject);
|
|
40159
40662
|
return resolvedConfig === resolvedUser || resolvedConfig === resolvedProject;
|
|
40160
40663
|
} catch {
|
|
40161
40664
|
return false;
|
|
@@ -40195,12 +40698,12 @@ function createConfigBackup(directory) {
|
|
|
40195
40698
|
};
|
|
40196
40699
|
}
|
|
40197
40700
|
function writeBackupArtifact(directory, backup) {
|
|
40198
|
-
const swarmDir =
|
|
40701
|
+
const swarmDir = path23.join(directory, ".swarm");
|
|
40199
40702
|
if (!fs8.existsSync(swarmDir)) {
|
|
40200
40703
|
fs8.mkdirSync(swarmDir, { recursive: true });
|
|
40201
40704
|
}
|
|
40202
40705
|
const backupFilename = `config-backup-${backup.createdAt}.json`;
|
|
40203
|
-
const backupPath =
|
|
40706
|
+
const backupPath = path23.join(swarmDir, backupFilename);
|
|
40204
40707
|
const artifact = {
|
|
40205
40708
|
createdAt: backup.createdAt,
|
|
40206
40709
|
configPath: backup.configPath,
|
|
@@ -40230,7 +40733,7 @@ function restoreFromBackup(backupPath, directory) {
|
|
|
40230
40733
|
return null;
|
|
40231
40734
|
}
|
|
40232
40735
|
const targetPath = artifact.configPath;
|
|
40233
|
-
const targetDir =
|
|
40736
|
+
const targetDir = path23.dirname(targetPath);
|
|
40234
40737
|
if (!fs8.existsSync(targetDir)) {
|
|
40235
40738
|
fs8.mkdirSync(targetDir, { recursive: true });
|
|
40236
40739
|
}
|
|
@@ -40261,9 +40764,9 @@ function readConfigFromFile(directory) {
|
|
|
40261
40764
|
return null;
|
|
40262
40765
|
}
|
|
40263
40766
|
}
|
|
40264
|
-
function validateConfigKey(
|
|
40767
|
+
function validateConfigKey(path24, value, _config) {
|
|
40265
40768
|
const findings = [];
|
|
40266
|
-
switch (
|
|
40769
|
+
switch (path24) {
|
|
40267
40770
|
case "agents": {
|
|
40268
40771
|
if (value !== undefined) {
|
|
40269
40772
|
findings.push({
|
|
@@ -40500,27 +41003,27 @@ function validateConfigKey(path23, value, _config) {
|
|
|
40500
41003
|
}
|
|
40501
41004
|
return findings;
|
|
40502
41005
|
}
|
|
40503
|
-
function walkConfigAndValidate(obj,
|
|
41006
|
+
function walkConfigAndValidate(obj, path24, config3, findings) {
|
|
40504
41007
|
if (obj === null || obj === undefined) {
|
|
40505
41008
|
return;
|
|
40506
41009
|
}
|
|
40507
|
-
if (
|
|
40508
|
-
const keyFindings = validateConfigKey(
|
|
41010
|
+
if (path24 && typeof obj === "object" && !Array.isArray(obj)) {
|
|
41011
|
+
const keyFindings = validateConfigKey(path24, obj, config3);
|
|
40509
41012
|
findings.push(...keyFindings);
|
|
40510
41013
|
}
|
|
40511
41014
|
if (typeof obj !== "object") {
|
|
40512
|
-
const keyFindings = validateConfigKey(
|
|
41015
|
+
const keyFindings = validateConfigKey(path24, obj, config3);
|
|
40513
41016
|
findings.push(...keyFindings);
|
|
40514
41017
|
return;
|
|
40515
41018
|
}
|
|
40516
41019
|
if (Array.isArray(obj)) {
|
|
40517
41020
|
obj.forEach((item, index) => {
|
|
40518
|
-
walkConfigAndValidate(item, `${
|
|
41021
|
+
walkConfigAndValidate(item, `${path24}[${index}]`, config3, findings);
|
|
40519
41022
|
});
|
|
40520
41023
|
return;
|
|
40521
41024
|
}
|
|
40522
41025
|
for (const [key, value] of Object.entries(obj)) {
|
|
40523
|
-
const newPath =
|
|
41026
|
+
const newPath = path24 ? `${path24}.${key}` : key;
|
|
40524
41027
|
walkConfigAndValidate(value, newPath, config3, findings);
|
|
40525
41028
|
}
|
|
40526
41029
|
}
|
|
@@ -40640,7 +41143,7 @@ function applySafeAutoFixes(directory, result) {
|
|
|
40640
41143
|
}
|
|
40641
41144
|
}
|
|
40642
41145
|
if (appliedFixes.length > 0) {
|
|
40643
|
-
const configDir =
|
|
41146
|
+
const configDir = path23.dirname(configPath);
|
|
40644
41147
|
if (!fs8.existsSync(configDir)) {
|
|
40645
41148
|
fs8.mkdirSync(configDir, { recursive: true });
|
|
40646
41149
|
}
|
|
@@ -40650,12 +41153,12 @@ function applySafeAutoFixes(directory, result) {
|
|
|
40650
41153
|
return { appliedFixes, updatedConfigPath };
|
|
40651
41154
|
}
|
|
40652
41155
|
function writeDoctorArtifact(directory, result) {
|
|
40653
|
-
const swarmDir =
|
|
41156
|
+
const swarmDir = path23.join(directory, ".swarm");
|
|
40654
41157
|
if (!fs8.existsSync(swarmDir)) {
|
|
40655
41158
|
fs8.mkdirSync(swarmDir, { recursive: true });
|
|
40656
41159
|
}
|
|
40657
41160
|
const artifactFilename = "config-doctor.json";
|
|
40658
|
-
const artifactPath =
|
|
41161
|
+
const artifactPath = path23.join(swarmDir, artifactFilename);
|
|
40659
41162
|
const guiOutput = {
|
|
40660
41163
|
timestamp: result.timestamp,
|
|
40661
41164
|
summary: result.summary,
|
|
@@ -40751,17 +41254,17 @@ function detectStraySwarmDirs(projectRoot) {
|
|
|
40751
41254
|
if (!entry.isDirectory())
|
|
40752
41255
|
continue;
|
|
40753
41256
|
const name = entry.name;
|
|
40754
|
-
const fullPath =
|
|
41257
|
+
const fullPath = path23.join(dir, name);
|
|
40755
41258
|
if (SKIP_DIRS.has(name))
|
|
40756
41259
|
continue;
|
|
40757
|
-
const gitPath =
|
|
41260
|
+
const gitPath = path23.join(fullPath, ".git");
|
|
40758
41261
|
try {
|
|
40759
41262
|
const gitStat = fs8.statSync(gitPath);
|
|
40760
41263
|
if (gitStat.isFile() || gitStat.isDirectory())
|
|
40761
41264
|
continue;
|
|
40762
41265
|
} catch {}
|
|
40763
41266
|
if (name === ".swarm") {
|
|
40764
|
-
const parentDir =
|
|
41267
|
+
const parentDir = path23.dirname(fullPath);
|
|
40765
41268
|
if (parentDir === projectRoot)
|
|
40766
41269
|
continue;
|
|
40767
41270
|
let contents = [];
|
|
@@ -40771,7 +41274,7 @@ function detectStraySwarmDirs(projectRoot) {
|
|
|
40771
41274
|
contents = ["<unreadable>"];
|
|
40772
41275
|
}
|
|
40773
41276
|
findings.push({
|
|
40774
|
-
path:
|
|
41277
|
+
path: path23.relative(projectRoot, fullPath).replace(/\\/g, "/"),
|
|
40775
41278
|
absolutePath: fullPath,
|
|
40776
41279
|
contents: contents.slice(0, MAX_CONTENTS_ENTRIES),
|
|
40777
41280
|
totalEntries: contents.length
|
|
@@ -40789,21 +41292,21 @@ function removeStraySwarmDir(projectRoot, strayPath) {
|
|
|
40789
41292
|
let canonicalStray;
|
|
40790
41293
|
try {
|
|
40791
41294
|
canonicalRoot = fs8.realpathSync(projectRoot);
|
|
40792
|
-
canonicalStray = fs8.realpathSync(
|
|
41295
|
+
canonicalStray = fs8.realpathSync(path23.isAbsolute(strayPath) ? strayPath : path23.resolve(projectRoot, strayPath));
|
|
40793
41296
|
} catch (err) {
|
|
40794
41297
|
return {
|
|
40795
41298
|
success: false,
|
|
40796
41299
|
message: `Failed to resolve paths: ${err instanceof Error ? err.message : String(err)}`
|
|
40797
41300
|
};
|
|
40798
41301
|
}
|
|
40799
|
-
const rootSwarm =
|
|
41302
|
+
const rootSwarm = path23.join(canonicalRoot, ".swarm");
|
|
40800
41303
|
if (canonicalStray === rootSwarm || canonicalStray === canonicalRoot) {
|
|
40801
41304
|
return {
|
|
40802
41305
|
success: false,
|
|
40803
41306
|
message: "Refusing to remove root .swarm/ directory"
|
|
40804
41307
|
};
|
|
40805
41308
|
}
|
|
40806
|
-
if (!canonicalStray.startsWith(canonicalRoot +
|
|
41309
|
+
if (!canonicalStray.startsWith(canonicalRoot + path23.sep)) {
|
|
40807
41310
|
return {
|
|
40808
41311
|
success: false,
|
|
40809
41312
|
message: "Path is outside project root \u2014 refusing to remove"
|
|
@@ -41892,7 +42395,7 @@ var init_profiles = __esm(() => {
|
|
|
41892
42395
|
|
|
41893
42396
|
// src/lang/detector.ts
|
|
41894
42397
|
import { access as access3, readdir as readdir2 } from "fs/promises";
|
|
41895
|
-
import { extname as extname2, join as
|
|
42398
|
+
import { extname as extname2, join as join22 } from "path";
|
|
41896
42399
|
async function detectProjectLanguages(projectDir) {
|
|
41897
42400
|
const detected = new Set;
|
|
41898
42401
|
async function scanDir(dir) {
|
|
@@ -41908,7 +42411,7 @@ async function detectProjectLanguages(projectDir) {
|
|
|
41908
42411
|
if (detectFile.includes("*") || detectFile.includes("?"))
|
|
41909
42412
|
continue;
|
|
41910
42413
|
try {
|
|
41911
|
-
await access3(
|
|
42414
|
+
await access3(join22(dir, detectFile));
|
|
41912
42415
|
detected.add(profile.id);
|
|
41913
42416
|
break;
|
|
41914
42417
|
} catch {}
|
|
@@ -41929,7 +42432,7 @@ async function detectProjectLanguages(projectDir) {
|
|
|
41929
42432
|
const topEntries = await readdir2(projectDir, { withFileTypes: true });
|
|
41930
42433
|
for (const entry of topEntries) {
|
|
41931
42434
|
if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
41932
|
-
await scanDir(
|
|
42435
|
+
await scanDir(join22(projectDir, entry.name));
|
|
41933
42436
|
}
|
|
41934
42437
|
}
|
|
41935
42438
|
} catch {}
|
|
@@ -41948,7 +42451,7 @@ var init_detector = __esm(() => {
|
|
|
41948
42451
|
|
|
41949
42452
|
// src/build/discovery.ts
|
|
41950
42453
|
import * as fs9 from "fs";
|
|
41951
|
-
import * as
|
|
42454
|
+
import * as path24 from "path";
|
|
41952
42455
|
function isCommandAvailable(command) {
|
|
41953
42456
|
if (toolchainCache.has(command)) {
|
|
41954
42457
|
return toolchainCache.get(command);
|
|
@@ -41956,7 +42459,7 @@ function isCommandAvailable(command) {
|
|
|
41956
42459
|
const isWindows = process.platform === "win32";
|
|
41957
42460
|
const cmd = isWindows ? `${command}.exe` : command;
|
|
41958
42461
|
try {
|
|
41959
|
-
const result =
|
|
42462
|
+
const result = _internals12.spawnSyncImpl(isWindows ? ["where", cmd] : ["which", cmd], {
|
|
41960
42463
|
cwd: process.cwd(),
|
|
41961
42464
|
stdin: "ignore",
|
|
41962
42465
|
stdout: "ignore",
|
|
@@ -41983,11 +42486,11 @@ function findBuildFiles(workingDir, patterns) {
|
|
|
41983
42486
|
const regex = simpleGlobToRegex(pattern);
|
|
41984
42487
|
const matches = files.filter((f) => regex.test(f));
|
|
41985
42488
|
if (matches.length > 0) {
|
|
41986
|
-
return
|
|
42489
|
+
return path24.join(dir, matches[0]);
|
|
41987
42490
|
}
|
|
41988
42491
|
} catch {}
|
|
41989
42492
|
} else {
|
|
41990
|
-
const filePath =
|
|
42493
|
+
const filePath = path24.join(workingDir, pattern);
|
|
41991
42494
|
if (fs9.existsSync(filePath)) {
|
|
41992
42495
|
return filePath;
|
|
41993
42496
|
}
|
|
@@ -41996,7 +42499,7 @@ function findBuildFiles(workingDir, patterns) {
|
|
|
41996
42499
|
return null;
|
|
41997
42500
|
}
|
|
41998
42501
|
function getRepoDefinedScripts(workingDir, scripts) {
|
|
41999
|
-
const packageJsonPath =
|
|
42502
|
+
const packageJsonPath = path24.join(workingDir, "package.json");
|
|
42000
42503
|
if (!fs9.existsSync(packageJsonPath)) {
|
|
42001
42504
|
return [];
|
|
42002
42505
|
}
|
|
@@ -42037,7 +42540,7 @@ function findAllBuildFiles(workingDir) {
|
|
|
42037
42540
|
const regex = simpleGlobToRegex(pattern);
|
|
42038
42541
|
findFilesRecursive(workingDir, regex, allBuildFiles);
|
|
42039
42542
|
} else {
|
|
42040
|
-
const filePath =
|
|
42543
|
+
const filePath = path24.join(workingDir, pattern);
|
|
42041
42544
|
if (fs9.existsSync(filePath)) {
|
|
42042
42545
|
allBuildFiles.add(filePath);
|
|
42043
42546
|
}
|
|
@@ -42050,7 +42553,7 @@ function findFilesRecursive(dir, regex, results) {
|
|
|
42050
42553
|
try {
|
|
42051
42554
|
const entries = fs9.readdirSync(dir, { withFileTypes: true });
|
|
42052
42555
|
for (const entry of entries) {
|
|
42053
|
-
const fullPath =
|
|
42556
|
+
const fullPath = path24.join(dir, entry.name);
|
|
42054
42557
|
if (entry.isDirectory() && !["node_modules", ".git", "dist", "build", "target"].includes(entry.name)) {
|
|
42055
42558
|
findFilesRecursive(fullPath, regex, results);
|
|
42056
42559
|
} else if (entry.isFile() && regex.test(entry.name)) {
|
|
@@ -42073,7 +42576,7 @@ async function discoverBuildCommandsFromProfiles(workingDir) {
|
|
|
42073
42576
|
let foundCommand = false;
|
|
42074
42577
|
for (const cmd of sortedCommands) {
|
|
42075
42578
|
if (cmd.detectFile) {
|
|
42076
|
-
const detectFilePath =
|
|
42579
|
+
const detectFilePath = path24.join(workingDir, cmd.detectFile);
|
|
42077
42580
|
if (!fs9.existsSync(detectFilePath)) {
|
|
42078
42581
|
continue;
|
|
42079
42582
|
}
|
|
@@ -42106,7 +42609,7 @@ async function discoverBuildCommands(workingDir, options) {
|
|
|
42106
42609
|
const scope = options?.scope ?? "all";
|
|
42107
42610
|
const changedFiles = options?.changedFiles ?? [];
|
|
42108
42611
|
const _filesToCheck = filterByScope(workingDir, scope, changedFiles);
|
|
42109
|
-
const profileResult = await
|
|
42612
|
+
const profileResult = await _internals12.discoverBuildCommandsFromProfiles(workingDir);
|
|
42110
42613
|
const profileCommands = profileResult.commands;
|
|
42111
42614
|
const profileSkipped = profileResult.skipped;
|
|
42112
42615
|
const coveredEcosystems = new Set;
|
|
@@ -42169,7 +42672,7 @@ function clearToolchainCache() {
|
|
|
42169
42672
|
function getEcosystems() {
|
|
42170
42673
|
return ECOSYSTEMS.map((e) => e.ecosystem);
|
|
42171
42674
|
}
|
|
42172
|
-
var ECOSYSTEMS, PROFILE_TO_ECOSYSTEM_NAMES, toolchainCache, IS_COMMAND_AVAILABLE_TIMEOUT_MS = 3000,
|
|
42675
|
+
var ECOSYSTEMS, PROFILE_TO_ECOSYSTEM_NAMES, toolchainCache, IS_COMMAND_AVAILABLE_TIMEOUT_MS = 3000, _internals12, build_discovery;
|
|
42173
42676
|
var init_discovery = __esm(() => {
|
|
42174
42677
|
init_dist();
|
|
42175
42678
|
init_detector();
|
|
@@ -42287,7 +42790,7 @@ var init_discovery = __esm(() => {
|
|
|
42287
42790
|
php: ["php-composer"]
|
|
42288
42791
|
};
|
|
42289
42792
|
toolchainCache = new Map;
|
|
42290
|
-
|
|
42793
|
+
_internals12 = {
|
|
42291
42794
|
isCommandAvailable,
|
|
42292
42795
|
discoverBuildCommandsFromProfiles,
|
|
42293
42796
|
discoverBuildCommands,
|
|
@@ -42314,7 +42817,7 @@ var init_discovery = __esm(() => {
|
|
|
42314
42817
|
|
|
42315
42818
|
// src/services/tool-doctor.ts
|
|
42316
42819
|
import * as fs10 from "fs";
|
|
42317
|
-
import * as
|
|
42820
|
+
import * as path25 from "path";
|
|
42318
42821
|
function extractRegisteredToolKeys(indexPath) {
|
|
42319
42822
|
const registeredKeys = new Set;
|
|
42320
42823
|
try {
|
|
@@ -42369,8 +42872,8 @@ function checkBinaryReadiness() {
|
|
|
42369
42872
|
}
|
|
42370
42873
|
function runToolDoctor(_directory, pluginRoot) {
|
|
42371
42874
|
const findings = [];
|
|
42372
|
-
const resolvedPluginRoot = pluginRoot ??
|
|
42373
|
-
const indexPath =
|
|
42875
|
+
const resolvedPluginRoot = pluginRoot ?? path25.resolve(import.meta.dir, "..", "..");
|
|
42876
|
+
const indexPath = path25.join(resolvedPluginRoot, "src", "index.ts");
|
|
42374
42877
|
if (!fs10.existsSync(indexPath)) {
|
|
42375
42878
|
return {
|
|
42376
42879
|
findings: [
|
|
@@ -42590,7 +43093,7 @@ var exports_evidence_summary_service = {};
|
|
|
42590
43093
|
__export(exports_evidence_summary_service, {
|
|
42591
43094
|
isAutoSummaryEnabled: () => isAutoSummaryEnabled,
|
|
42592
43095
|
buildEvidenceSummary: () => buildEvidenceSummary,
|
|
42593
|
-
_internals: () =>
|
|
43096
|
+
_internals: () => _internals13,
|
|
42594
43097
|
REQUIRED_EVIDENCE_TYPES: () => REQUIRED_EVIDENCE_TYPES,
|
|
42595
43098
|
EVIDENCE_SUMMARY_VERSION: () => EVIDENCE_SUMMARY_VERSION
|
|
42596
43099
|
});
|
|
@@ -42628,14 +43131,13 @@ function getTaskStatus(task, bundle) {
|
|
|
42628
43131
|
if (task?.status) {
|
|
42629
43132
|
return task.status;
|
|
42630
43133
|
}
|
|
42631
|
-
const entries =
|
|
43134
|
+
const entries = _internals13.normalizeBundleEntries(bundle);
|
|
42632
43135
|
if (entries.length > 0) {
|
|
42633
43136
|
return "completed";
|
|
42634
43137
|
}
|
|
42635
43138
|
return "pending";
|
|
42636
43139
|
}
|
|
42637
|
-
function
|
|
42638
|
-
const entries = _internals12.normalizeBundleEntries(bundle);
|
|
43140
|
+
function evidenceCompleteFromEntries(entries) {
|
|
42639
43141
|
if (entries.length === 0) {
|
|
42640
43142
|
return {
|
|
42641
43143
|
isComplete: false,
|
|
@@ -42654,6 +43156,9 @@ function isEvidenceComplete(bundle) {
|
|
|
42654
43156
|
missingEvidence: missing
|
|
42655
43157
|
};
|
|
42656
43158
|
}
|
|
43159
|
+
function isEvidenceComplete(bundle) {
|
|
43160
|
+
return evidenceCompleteFromEntries(_internals13.normalizeBundleEntries(bundle));
|
|
43161
|
+
}
|
|
42657
43162
|
function getTaskBlockers(task, summary, status) {
|
|
42658
43163
|
const blockers = [];
|
|
42659
43164
|
if (task?.blocked_reason) {
|
|
@@ -42670,11 +43175,19 @@ function getTaskBlockers(task, summary, status) {
|
|
|
42670
43175
|
async function buildTaskSummary(directory, task, taskId) {
|
|
42671
43176
|
const result = await loadEvidence(directory, taskId);
|
|
42672
43177
|
const bundle = result.status === "found" ? result.bundle : null;
|
|
43178
|
+
const gateEvidence = await readDurableGateEvidence(directory, taskId);
|
|
42673
43179
|
const phase = task?.phase ?? 0;
|
|
42674
|
-
const status =
|
|
42675
|
-
const
|
|
42676
|
-
|
|
42677
|
-
|
|
43180
|
+
const status = _internals13.getTaskStatus(task, bundle);
|
|
43181
|
+
const entries = mergeDurableGateEntriesFromEvidence(taskId, _internals13.normalizeBundleEntries(bundle), gateEvidence);
|
|
43182
|
+
let evidenceCheck = _internals13.evidenceCompleteFromEntries(entries);
|
|
43183
|
+
if (gateEvidence) {
|
|
43184
|
+
const gateStatus = getDurableGateEvidenceStatus(gateEvidence);
|
|
43185
|
+
evidenceCheck = gateStatus.isComplete ? { isComplete: true, missingEvidence: [] } : {
|
|
43186
|
+
isComplete: false,
|
|
43187
|
+
missingEvidence: gateStatus.missingGates.map((gate) => `gate:${gate}`)
|
|
43188
|
+
};
|
|
43189
|
+
}
|
|
43190
|
+
const blockers = _internals13.getTaskBlockers(task, evidenceCheck, status);
|
|
42678
43191
|
const hasReview = entries.some((e) => e.type === "review");
|
|
42679
43192
|
const hasTest = entries.some((e) => e.type === "test");
|
|
42680
43193
|
const hasApproval = entries.some((e) => e.type === "approval");
|
|
@@ -42703,12 +43216,12 @@ async function buildPhaseSummary(directory, phase) {
|
|
|
42703
43216
|
const taskSummaries = [];
|
|
42704
43217
|
const _taskMap = new Map(phase.tasks.map((t) => [t.id, t]));
|
|
42705
43218
|
for (const task of phase.tasks) {
|
|
42706
|
-
const summary = await
|
|
43219
|
+
const summary = await _internals13.buildTaskSummary(directory, task, task.id);
|
|
42707
43220
|
taskSummaries.push(summary);
|
|
42708
43221
|
}
|
|
42709
43222
|
const extraTaskIds = taskIds.filter((id) => !phaseTaskIds.has(id));
|
|
42710
43223
|
for (const taskId of extraTaskIds) {
|
|
42711
|
-
const summary = await
|
|
43224
|
+
const summary = await _internals13.buildTaskSummary(directory, undefined, taskId);
|
|
42712
43225
|
if (summary.phase === phase.id) {
|
|
42713
43226
|
taskSummaries.push(summary);
|
|
42714
43227
|
}
|
|
@@ -42809,7 +43322,7 @@ async function buildEvidenceSummary(directory, currentPhase) {
|
|
|
42809
43322
|
let totalTasks = 0;
|
|
42810
43323
|
let completedTasks = 0;
|
|
42811
43324
|
for (const phase of phasesToProcess) {
|
|
42812
|
-
const summary = await
|
|
43325
|
+
const summary = await _internals13.buildPhaseSummary(directory, phase);
|
|
42813
43326
|
phaseSummaries.push(summary);
|
|
42814
43327
|
totalTasks += summary.totalTasks;
|
|
42815
43328
|
completedTasks += summary.completedTasks;
|
|
@@ -42831,7 +43344,7 @@ async function buildEvidenceSummary(directory, currentPhase) {
|
|
|
42831
43344
|
overallBlockers,
|
|
42832
43345
|
summaryText: ""
|
|
42833
43346
|
};
|
|
42834
|
-
artifact.summaryText =
|
|
43347
|
+
artifact.summaryText = _internals13.generateSummaryText(artifact);
|
|
42835
43348
|
log("[EvidenceSummary] Summary built", {
|
|
42836
43349
|
phases: phaseSummaries.length,
|
|
42837
43350
|
totalTasks,
|
|
@@ -42850,8 +43363,9 @@ function isAutoSummaryEnabled(automationConfig) {
|
|
|
42850
43363
|
}
|
|
42851
43364
|
return automationConfig.capabilities?.evidence_auto_summaries === true;
|
|
42852
43365
|
}
|
|
42853
|
-
var VALID_EVIDENCE_TYPES2, REQUIRED_EVIDENCE_TYPES, EVIDENCE_SUMMARY_VERSION = "1.0.0",
|
|
43366
|
+
var VALID_EVIDENCE_TYPES2, REQUIRED_EVIDENCE_TYPES, EVIDENCE_SUMMARY_VERSION = "1.0.0", _internals13;
|
|
42854
43367
|
var init_evidence_summary_service = __esm(() => {
|
|
43368
|
+
init_gate_bridge();
|
|
42855
43369
|
init_manager2();
|
|
42856
43370
|
init_manager();
|
|
42857
43371
|
init_utils();
|
|
@@ -42864,11 +43378,12 @@ var init_evidence_summary_service = __esm(() => {
|
|
|
42864
43378
|
"retrospective"
|
|
42865
43379
|
]);
|
|
42866
43380
|
REQUIRED_EVIDENCE_TYPES = ["review", "test"];
|
|
42867
|
-
|
|
43381
|
+
_internals13 = {
|
|
42868
43382
|
buildEvidenceSummary,
|
|
42869
43383
|
isAutoSummaryEnabled,
|
|
42870
43384
|
normalizeBundleEntries,
|
|
42871
43385
|
getTaskStatus,
|
|
43386
|
+
evidenceCompleteFromEntries,
|
|
42872
43387
|
isEvidenceComplete,
|
|
42873
43388
|
getTaskBlockers,
|
|
42874
43389
|
buildTaskSummary,
|
|
@@ -42919,7 +43434,7 @@ function getVerdictEmoji(verdict) {
|
|
|
42919
43434
|
return getVerdictIcon(verdict);
|
|
42920
43435
|
}
|
|
42921
43436
|
async function getTaskEvidenceData(directory, taskId) {
|
|
42922
|
-
const result = await
|
|
43437
|
+
const result = await _internals14.loadEvidence(directory, taskId);
|
|
42923
43438
|
if (result.status !== "found") {
|
|
42924
43439
|
return {
|
|
42925
43440
|
hasEvidence: false,
|
|
@@ -42942,13 +43457,13 @@ async function getTaskEvidenceData(directory, taskId) {
|
|
|
42942
43457
|
};
|
|
42943
43458
|
}
|
|
42944
43459
|
async function getEvidenceListData(directory) {
|
|
42945
|
-
const taskIds = await
|
|
43460
|
+
const taskIds = await _internals14.listEvidenceTaskIds(directory);
|
|
42946
43461
|
if (taskIds.length === 0) {
|
|
42947
43462
|
return { hasEvidence: false, tasks: [] };
|
|
42948
43463
|
}
|
|
42949
43464
|
const tasks = [];
|
|
42950
43465
|
for (const taskId of taskIds) {
|
|
42951
|
-
const result = await
|
|
43466
|
+
const result = await _internals14.loadEvidence(directory, taskId);
|
|
42952
43467
|
if (result.status === "found") {
|
|
42953
43468
|
tasks.push({
|
|
42954
43469
|
taskId,
|
|
@@ -43062,10 +43577,10 @@ async function handleEvidenceSummaryCommand(directory) {
|
|
|
43062
43577
|
return lines.join(`
|
|
43063
43578
|
`);
|
|
43064
43579
|
}
|
|
43065
|
-
var
|
|
43580
|
+
var _internals14;
|
|
43066
43581
|
var init_evidence_service = __esm(() => {
|
|
43067
43582
|
init_manager2();
|
|
43068
|
-
|
|
43583
|
+
_internals14 = {
|
|
43069
43584
|
loadEvidence,
|
|
43070
43585
|
listEvidenceTaskIds
|
|
43071
43586
|
};
|
|
@@ -43116,12 +43631,12 @@ var init_export = __esm(() => {
|
|
|
43116
43631
|
|
|
43117
43632
|
// src/full-auto/state.ts
|
|
43118
43633
|
import * as fs11 from "fs";
|
|
43119
|
-
import * as
|
|
43634
|
+
import * as path26 from "path";
|
|
43120
43635
|
function nowISO() {
|
|
43121
43636
|
return new Date().toISOString();
|
|
43122
43637
|
}
|
|
43123
43638
|
function ensureSwarmDir(directory) {
|
|
43124
|
-
const swarmDir =
|
|
43639
|
+
const swarmDir = path26.resolve(directory, ".swarm");
|
|
43125
43640
|
if (!fs11.existsSync(swarmDir)) {
|
|
43126
43641
|
fs11.mkdirSync(swarmDir, { recursive: true });
|
|
43127
43642
|
}
|
|
@@ -43472,7 +43987,7 @@ function extractCurrentPhaseFromPlan2(plan) {
|
|
|
43472
43987
|
if (!plan) {
|
|
43473
43988
|
return { currentPhase: null, currentTask: null, incompleteTasks: [] };
|
|
43474
43989
|
}
|
|
43475
|
-
if (!
|
|
43990
|
+
if (!_internals15.validatePlanPhases(plan)) {
|
|
43476
43991
|
return { currentPhase: null, currentTask: null, incompleteTasks: [] };
|
|
43477
43992
|
}
|
|
43478
43993
|
let currentPhase = null;
|
|
@@ -43614,9 +44129,9 @@ function extractPhaseMetrics(content) {
|
|
|
43614
44129
|
async function getHandoffData(directory) {
|
|
43615
44130
|
const now = new Date().toISOString();
|
|
43616
44131
|
const sessionContent = await readSwarmFileAsync(directory, "session/state.json");
|
|
43617
|
-
const sessionState =
|
|
44132
|
+
const sessionState = _internals15.parseSessionState(sessionContent);
|
|
43618
44133
|
const plan = await loadPlanJsonOnly(directory);
|
|
43619
|
-
const planInfo =
|
|
44134
|
+
const planInfo = _internals15.extractCurrentPhaseFromPlan(plan);
|
|
43620
44135
|
if (!plan) {
|
|
43621
44136
|
const planMdContent = await readSwarmFileAsync(directory, "plan.md");
|
|
43622
44137
|
if (planMdContent) {
|
|
@@ -43635,8 +44150,8 @@ async function getHandoffData(directory) {
|
|
|
43635
44150
|
}
|
|
43636
44151
|
}
|
|
43637
44152
|
const contextContent = await readSwarmFileAsync(directory, "context.md");
|
|
43638
|
-
const recentDecisions =
|
|
43639
|
-
const rawPhaseMetrics =
|
|
44153
|
+
const recentDecisions = _internals15.extractDecisions(contextContent);
|
|
44154
|
+
const rawPhaseMetrics = _internals15.extractPhaseMetrics(contextContent);
|
|
43640
44155
|
const phaseMetrics = sanitizeString(rawPhaseMetrics, 1000);
|
|
43641
44156
|
let delegationState = null;
|
|
43642
44157
|
if (sessionState?.delegationState) {
|
|
@@ -43800,13 +44315,13 @@ ${lines.join(`
|
|
|
43800
44315
|
`)}
|
|
43801
44316
|
\`\`\``;
|
|
43802
44317
|
}
|
|
43803
|
-
var RTL_OVERRIDE_PATTERN, MAX_TASK_ID_LENGTH = 100, MAX_DECISION_LENGTH = 500, MAX_INCOMPLETE_TASKS = 20,
|
|
44318
|
+
var RTL_OVERRIDE_PATTERN, MAX_TASK_ID_LENGTH = 100, MAX_DECISION_LENGTH = 500, MAX_INCOMPLETE_TASKS = 20, _internals15;
|
|
43804
44319
|
var init_handoff_service = __esm(() => {
|
|
43805
44320
|
init_utils2();
|
|
43806
44321
|
init_manager();
|
|
43807
44322
|
init_utils();
|
|
43808
44323
|
RTL_OVERRIDE_PATTERN = /[\u202e\u202d\u202c\u200f]/g;
|
|
43809
|
-
|
|
44324
|
+
_internals15 = {
|
|
43810
44325
|
getHandoffData,
|
|
43811
44326
|
formatHandoffMarkdown,
|
|
43812
44327
|
formatContinuationPrompt,
|
|
@@ -43821,8 +44336,8 @@ var init_handoff_service = __esm(() => {
|
|
|
43821
44336
|
});
|
|
43822
44337
|
|
|
43823
44338
|
// src/session/snapshot-writer.ts
|
|
43824
|
-
import { closeSync as closeSync3, fsyncSync as fsyncSync2, mkdirSync as
|
|
43825
|
-
import * as
|
|
44339
|
+
import { closeSync as closeSync3, fsyncSync as fsyncSync2, mkdirSync as mkdirSync11, openSync as openSync3, renameSync as renameSync6 } from "fs";
|
|
44340
|
+
import * as path27 from "path";
|
|
43826
44341
|
function serializeAgentSession(s) {
|
|
43827
44342
|
const gateLog = {};
|
|
43828
44343
|
const rawGateLog = s.gateLog ?? new Map;
|
|
@@ -43919,8 +44434,8 @@ async function writeSnapshot(directory, state) {
|
|
|
43919
44434
|
}
|
|
43920
44435
|
const content = JSON.stringify(snapshot, null, 2);
|
|
43921
44436
|
const resolvedPath = validateSwarmPath(directory, "session/state.json");
|
|
43922
|
-
const dir =
|
|
43923
|
-
|
|
44437
|
+
const dir = path27.dirname(resolvedPath);
|
|
44438
|
+
mkdirSync11(dir, { recursive: true });
|
|
43924
44439
|
const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
43925
44440
|
await bunWrite(tempPath, content);
|
|
43926
44441
|
try {
|
|
@@ -43940,22 +44455,22 @@ async function writeSnapshot(directory, state) {
|
|
|
43940
44455
|
}
|
|
43941
44456
|
function createSnapshotWriterHook(directory) {
|
|
43942
44457
|
return (_input, _output) => {
|
|
43943
|
-
_writeInFlight = _writeInFlight.then(() =>
|
|
44458
|
+
_writeInFlight = _writeInFlight.then(() => _internals16.writeSnapshot(directory, swarmState), () => _internals16.writeSnapshot(directory, swarmState));
|
|
43944
44459
|
return _writeInFlight;
|
|
43945
44460
|
};
|
|
43946
44461
|
}
|
|
43947
44462
|
async function flushPendingSnapshot(directory) {
|
|
43948
|
-
_writeInFlight = _writeInFlight.then(() =>
|
|
44463
|
+
_writeInFlight = _writeInFlight.then(() => _internals16.writeSnapshot(directory, swarmState), () => _internals16.writeSnapshot(directory, swarmState));
|
|
43949
44464
|
await _writeInFlight;
|
|
43950
44465
|
}
|
|
43951
|
-
var _writeInFlight,
|
|
44466
|
+
var _writeInFlight, _internals16;
|
|
43952
44467
|
var init_snapshot_writer = __esm(() => {
|
|
43953
44468
|
init_utils2();
|
|
43954
44469
|
init_state();
|
|
43955
44470
|
init_utils();
|
|
43956
44471
|
init_bun_compat();
|
|
43957
44472
|
_writeInFlight = Promise.resolve();
|
|
43958
|
-
|
|
44473
|
+
_internals16 = {
|
|
43959
44474
|
writeSnapshot,
|
|
43960
44475
|
createSnapshotWriterHook,
|
|
43961
44476
|
flushPendingSnapshot
|
|
@@ -44376,9 +44891,9 @@ var init_issue = __esm(() => {
|
|
|
44376
44891
|
|
|
44377
44892
|
// src/hooks/knowledge-migrator.ts
|
|
44378
44893
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
44379
|
-
import { existsSync as existsSync17, readFileSync as
|
|
44894
|
+
import { existsSync as existsSync17, readFileSync as readFileSync13 } from "fs";
|
|
44380
44895
|
import { mkdir as mkdir7, readFile as readFile7, writeFile as writeFile8 } from "fs/promises";
|
|
44381
|
-
import * as
|
|
44896
|
+
import * as path28 from "path";
|
|
44382
44897
|
async function migrateKnowledgeToExternal(_directory, _config) {
|
|
44383
44898
|
return {
|
|
44384
44899
|
migrated: false,
|
|
@@ -44389,8 +44904,8 @@ async function migrateKnowledgeToExternal(_directory, _config) {
|
|
|
44389
44904
|
};
|
|
44390
44905
|
}
|
|
44391
44906
|
async function migrateContextToKnowledge(directory, config3) {
|
|
44392
|
-
const sentinelPath =
|
|
44393
|
-
const contextPath =
|
|
44907
|
+
const sentinelPath = path28.join(directory, ".swarm", ".knowledge-migrated");
|
|
44908
|
+
const contextPath = path28.join(directory, ".swarm", "context.md");
|
|
44394
44909
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
44395
44910
|
if (existsSync17(sentinelPath)) {
|
|
44396
44911
|
return {
|
|
@@ -44420,9 +44935,9 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
44420
44935
|
skippedReason: "empty-context"
|
|
44421
44936
|
};
|
|
44422
44937
|
}
|
|
44423
|
-
const rawEntries =
|
|
44938
|
+
const rawEntries = _internals17.parseContextMd(contextContent);
|
|
44424
44939
|
if (rawEntries.length === 0) {
|
|
44425
|
-
await
|
|
44940
|
+
await _internals17.writeSentinel(sentinelPath, 0, 0);
|
|
44426
44941
|
return {
|
|
44427
44942
|
migrated: true,
|
|
44428
44943
|
entriesMigrated: 0,
|
|
@@ -44433,10 +44948,10 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
44433
44948
|
const existing = await readKnowledge(knowledgePath);
|
|
44434
44949
|
let migrated = 0;
|
|
44435
44950
|
let dropped = 0;
|
|
44436
|
-
const projectName =
|
|
44951
|
+
const projectName = _internals17.inferProjectName(directory);
|
|
44437
44952
|
for (const raw of rawEntries) {
|
|
44438
44953
|
if (config3.validation_enabled !== false) {
|
|
44439
|
-
const category = raw.categoryHint ??
|
|
44954
|
+
const category = raw.categoryHint ?? _internals17.inferCategoryFromText(raw.text);
|
|
44440
44955
|
const result = validateLesson(raw.text, existing.map((e) => e.lesson), {
|
|
44441
44956
|
category,
|
|
44442
44957
|
scope: "global",
|
|
@@ -44456,8 +44971,8 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
44456
44971
|
const entry = {
|
|
44457
44972
|
id: randomUUID2(),
|
|
44458
44973
|
tier: "swarm",
|
|
44459
|
-
lesson:
|
|
44460
|
-
category: raw.categoryHint ??
|
|
44974
|
+
lesson: _internals17.truncateLesson(raw.text),
|
|
44975
|
+
category: raw.categoryHint ?? _internals17.inferCategoryFromText(raw.text),
|
|
44461
44976
|
tags: [...inferredTags, `migration:${raw.sourceSection}`],
|
|
44462
44977
|
scope: "global",
|
|
44463
44978
|
confidence: 0.3,
|
|
@@ -44480,7 +44995,7 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
44480
44995
|
if (migrated > 0) {
|
|
44481
44996
|
await rewriteKnowledge(knowledgePath, existing);
|
|
44482
44997
|
}
|
|
44483
|
-
await
|
|
44998
|
+
await _internals17.writeSentinel(sentinelPath, migrated, dropped);
|
|
44484
44999
|
log(`[knowledge-migrator] Migrated ${migrated} entries, dropped ${dropped}`);
|
|
44485
45000
|
return {
|
|
44486
45001
|
migrated: true,
|
|
@@ -44490,7 +45005,7 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
44490
45005
|
};
|
|
44491
45006
|
}
|
|
44492
45007
|
function parseContextMd(content) {
|
|
44493
|
-
const sections =
|
|
45008
|
+
const sections = _internals17.splitIntoSections(content);
|
|
44494
45009
|
const entries = [];
|
|
44495
45010
|
const seen = new Set;
|
|
44496
45011
|
const sectionPatterns = [
|
|
@@ -44506,7 +45021,7 @@ function parseContextMd(content) {
|
|
|
44506
45021
|
const match = sectionPatterns.find((sp) => sp.pattern.test(section.heading));
|
|
44507
45022
|
if (!match)
|
|
44508
45023
|
continue;
|
|
44509
|
-
const bullets =
|
|
45024
|
+
const bullets = _internals17.extractBullets(section.body);
|
|
44510
45025
|
for (const bullet of bullets) {
|
|
44511
45026
|
if (bullet.length < 15)
|
|
44512
45027
|
continue;
|
|
@@ -44515,9 +45030,9 @@ function parseContextMd(content) {
|
|
|
44515
45030
|
continue;
|
|
44516
45031
|
seen.add(normalized);
|
|
44517
45032
|
entries.push({
|
|
44518
|
-
text:
|
|
45033
|
+
text: _internals17.truncateLesson(bullet),
|
|
44519
45034
|
sourceSection: match.sourceSection,
|
|
44520
|
-
categoryHint:
|
|
45035
|
+
categoryHint: _internals17.inferCategoryFromText(bullet)
|
|
44521
45036
|
});
|
|
44522
45037
|
}
|
|
44523
45038
|
}
|
|
@@ -44586,16 +45101,16 @@ function truncateLesson(text) {
|
|
|
44586
45101
|
return `${text.slice(0, 277)}...`;
|
|
44587
45102
|
}
|
|
44588
45103
|
function inferProjectName(directory) {
|
|
44589
|
-
const packageJsonPath =
|
|
45104
|
+
const packageJsonPath = path28.join(directory, "package.json");
|
|
44590
45105
|
if (existsSync17(packageJsonPath)) {
|
|
44591
45106
|
try {
|
|
44592
|
-
const pkg = JSON.parse(
|
|
45107
|
+
const pkg = JSON.parse(readFileSync13(packageJsonPath, "utf-8"));
|
|
44593
45108
|
if (pkg.name && typeof pkg.name === "string") {
|
|
44594
45109
|
return pkg.name;
|
|
44595
45110
|
}
|
|
44596
45111
|
} catch {}
|
|
44597
45112
|
}
|
|
44598
|
-
return
|
|
45113
|
+
return path28.basename(directory);
|
|
44599
45114
|
}
|
|
44600
45115
|
async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
44601
45116
|
const sentinel = {
|
|
@@ -44607,15 +45122,15 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
|
44607
45122
|
schema_version: 1,
|
|
44608
45123
|
migration_tool: "knowledge-migrator.ts"
|
|
44609
45124
|
};
|
|
44610
|
-
await mkdir7(
|
|
45125
|
+
await mkdir7(path28.dirname(sentinelPath), { recursive: true });
|
|
44611
45126
|
await writeFile8(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
|
|
44612
45127
|
}
|
|
44613
|
-
var
|
|
45128
|
+
var _internals17;
|
|
44614
45129
|
var init_knowledge_migrator = __esm(() => {
|
|
44615
45130
|
init_logger();
|
|
44616
45131
|
init_knowledge_store();
|
|
44617
45132
|
init_knowledge_validator();
|
|
44618
|
-
|
|
45133
|
+
_internals17 = {
|
|
44619
45134
|
migrateContextToKnowledge,
|
|
44620
45135
|
migrateKnowledgeToExternal,
|
|
44621
45136
|
parseContextMd,
|
|
@@ -44629,7 +45144,7 @@ var init_knowledge_migrator = __esm(() => {
|
|
|
44629
45144
|
});
|
|
44630
45145
|
|
|
44631
45146
|
// src/commands/knowledge.ts
|
|
44632
|
-
import { join as
|
|
45147
|
+
import { join as join26 } from "path";
|
|
44633
45148
|
function resolveEntryByPrefix(entries, inputId) {
|
|
44634
45149
|
const exact = entries.find((e) => e.id === inputId);
|
|
44635
45150
|
if (exact)
|
|
@@ -44680,7 +45195,7 @@ async function handleKnowledgeRestoreCommand(directory, args) {
|
|
|
44680
45195
|
return "Invalid entry ID. IDs must be 1-64 characters: letters, digits, hyphens, underscores only.";
|
|
44681
45196
|
}
|
|
44682
45197
|
try {
|
|
44683
|
-
const quarantinePath =
|
|
45198
|
+
const quarantinePath = join26(directory, ".swarm", "knowledge-quarantined.jsonl");
|
|
44684
45199
|
const entries = await readKnowledge(quarantinePath);
|
|
44685
45200
|
const resolved = resolveEntryByPrefix(entries, inputId);
|
|
44686
45201
|
if ("error" in resolved) {
|
|
@@ -44752,9 +45267,9 @@ var init_knowledge = __esm(() => {
|
|
|
44752
45267
|
|
|
44753
45268
|
// src/services/plan-service.ts
|
|
44754
45269
|
async function getPlanData(directory, phaseArg) {
|
|
44755
|
-
const plan = await
|
|
45270
|
+
const plan = await _internals18.loadPlanJsonOnly(directory);
|
|
44756
45271
|
if (plan) {
|
|
44757
|
-
const fullMarkdown =
|
|
45272
|
+
const fullMarkdown = _internals18.derivePlanMarkdown(plan);
|
|
44758
45273
|
if (phaseArg === undefined || phaseArg === null || phaseArg === "") {
|
|
44759
45274
|
return {
|
|
44760
45275
|
hasPlan: true,
|
|
@@ -44797,7 +45312,7 @@ async function getPlanData(directory, phaseArg) {
|
|
|
44797
45312
|
isLegacy: false
|
|
44798
45313
|
};
|
|
44799
45314
|
}
|
|
44800
|
-
const planContent = await
|
|
45315
|
+
const planContent = await _internals18.readSwarmFileAsync(directory, "plan.md");
|
|
44801
45316
|
if (!planContent) {
|
|
44802
45317
|
return {
|
|
44803
45318
|
hasPlan: false,
|
|
@@ -44893,11 +45408,11 @@ async function handlePlanCommand(directory, args) {
|
|
|
44893
45408
|
const planData = await getPlanData(directory, phaseArg);
|
|
44894
45409
|
return formatPlanMarkdown(planData);
|
|
44895
45410
|
}
|
|
44896
|
-
var
|
|
45411
|
+
var _internals18;
|
|
44897
45412
|
var init_plan_service = __esm(() => {
|
|
44898
45413
|
init_utils2();
|
|
44899
45414
|
init_manager();
|
|
44900
|
-
|
|
45415
|
+
_internals18 = {
|
|
44901
45416
|
loadPlanJsonOnly,
|
|
44902
45417
|
derivePlanMarkdown,
|
|
44903
45418
|
readSwarmFileAsync
|
|
@@ -45135,7 +45650,7 @@ var init_path_security = () => {};
|
|
|
45135
45650
|
|
|
45136
45651
|
// src/tools/lint.ts
|
|
45137
45652
|
import * as fs12 from "fs";
|
|
45138
|
-
import * as
|
|
45653
|
+
import * as path29 from "path";
|
|
45139
45654
|
function validateArgs(args) {
|
|
45140
45655
|
if (typeof args !== "object" || args === null)
|
|
45141
45656
|
return false;
|
|
@@ -45146,9 +45661,9 @@ function validateArgs(args) {
|
|
|
45146
45661
|
}
|
|
45147
45662
|
function getLinterCommand(linter, mode, projectDir) {
|
|
45148
45663
|
const isWindows = process.platform === "win32";
|
|
45149
|
-
const binDir =
|
|
45150
|
-
const biomeBin = isWindows ?
|
|
45151
|
-
const eslintBin = isWindows ?
|
|
45664
|
+
const binDir = path29.join(projectDir, "node_modules", ".bin");
|
|
45665
|
+
const biomeBin = isWindows ? path29.join(binDir, "biome.EXE") : path29.join(binDir, "biome");
|
|
45666
|
+
const eslintBin = isWindows ? path29.join(binDir, "eslint.cmd") : path29.join(binDir, "eslint");
|
|
45152
45667
|
switch (linter) {
|
|
45153
45668
|
case "biome":
|
|
45154
45669
|
if (mode === "fix") {
|
|
@@ -45164,7 +45679,7 @@ function getLinterCommand(linter, mode, projectDir) {
|
|
|
45164
45679
|
}
|
|
45165
45680
|
function getAdditionalLinterCommand(linter, mode, cwd) {
|
|
45166
45681
|
const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
|
|
45167
|
-
const gradlew = fs12.existsSync(
|
|
45682
|
+
const gradlew = fs12.existsSync(path29.join(cwd, gradlewName)) ? path29.join(cwd, gradlewName) : null;
|
|
45168
45683
|
switch (linter) {
|
|
45169
45684
|
case "ruff":
|
|
45170
45685
|
return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
|
|
@@ -45198,10 +45713,10 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
|
|
|
45198
45713
|
}
|
|
45199
45714
|
}
|
|
45200
45715
|
function detectRuff(cwd) {
|
|
45201
|
-
if (fs12.existsSync(
|
|
45716
|
+
if (fs12.existsSync(path29.join(cwd, "ruff.toml")))
|
|
45202
45717
|
return isCommandAvailable("ruff");
|
|
45203
45718
|
try {
|
|
45204
|
-
const pyproject =
|
|
45719
|
+
const pyproject = path29.join(cwd, "pyproject.toml");
|
|
45205
45720
|
if (fs12.existsSync(pyproject)) {
|
|
45206
45721
|
const content = fs12.readFileSync(pyproject, "utf-8");
|
|
45207
45722
|
if (content.includes("[tool.ruff]"))
|
|
@@ -45211,19 +45726,19 @@ function detectRuff(cwd) {
|
|
|
45211
45726
|
return false;
|
|
45212
45727
|
}
|
|
45213
45728
|
function detectClippy(cwd) {
|
|
45214
|
-
return fs12.existsSync(
|
|
45729
|
+
return fs12.existsSync(path29.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
|
|
45215
45730
|
}
|
|
45216
45731
|
function detectGolangciLint(cwd) {
|
|
45217
|
-
return fs12.existsSync(
|
|
45732
|
+
return fs12.existsSync(path29.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
|
|
45218
45733
|
}
|
|
45219
45734
|
function detectCheckstyle(cwd) {
|
|
45220
|
-
const hasMaven = fs12.existsSync(
|
|
45221
|
-
const hasGradle = fs12.existsSync(
|
|
45222
|
-
const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs12.existsSync(
|
|
45735
|
+
const hasMaven = fs12.existsSync(path29.join(cwd, "pom.xml"));
|
|
45736
|
+
const hasGradle = fs12.existsSync(path29.join(cwd, "build.gradle")) || fs12.existsSync(path29.join(cwd, "build.gradle.kts"));
|
|
45737
|
+
const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs12.existsSync(path29.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
|
|
45223
45738
|
return (hasMaven || hasGradle) && hasBinary;
|
|
45224
45739
|
}
|
|
45225
45740
|
function detectKtlint(cwd) {
|
|
45226
|
-
const hasKotlin = fs12.existsSync(
|
|
45741
|
+
const hasKotlin = fs12.existsSync(path29.join(cwd, "build.gradle.kts")) || fs12.existsSync(path29.join(cwd, "build.gradle")) || (() => {
|
|
45227
45742
|
try {
|
|
45228
45743
|
return fs12.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
|
|
45229
45744
|
} catch {
|
|
@@ -45242,11 +45757,11 @@ function detectDotnetFormat(cwd) {
|
|
|
45242
45757
|
}
|
|
45243
45758
|
}
|
|
45244
45759
|
function detectCppcheck(cwd) {
|
|
45245
|
-
if (fs12.existsSync(
|
|
45760
|
+
if (fs12.existsSync(path29.join(cwd, "CMakeLists.txt"))) {
|
|
45246
45761
|
return isCommandAvailable("cppcheck");
|
|
45247
45762
|
}
|
|
45248
45763
|
try {
|
|
45249
|
-
const dirsToCheck = [cwd,
|
|
45764
|
+
const dirsToCheck = [cwd, path29.join(cwd, "src")];
|
|
45250
45765
|
const hasCpp = dirsToCheck.some((dir) => {
|
|
45251
45766
|
try {
|
|
45252
45767
|
return fs12.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
|
|
@@ -45260,13 +45775,13 @@ function detectCppcheck(cwd) {
|
|
|
45260
45775
|
}
|
|
45261
45776
|
}
|
|
45262
45777
|
function detectSwiftlint(cwd) {
|
|
45263
|
-
return fs12.existsSync(
|
|
45778
|
+
return fs12.existsSync(path29.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
|
|
45264
45779
|
}
|
|
45265
45780
|
function detectDartAnalyze(cwd) {
|
|
45266
|
-
return fs12.existsSync(
|
|
45781
|
+
return fs12.existsSync(path29.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
45267
45782
|
}
|
|
45268
45783
|
function detectRubocop(cwd) {
|
|
45269
|
-
return (fs12.existsSync(
|
|
45784
|
+
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
45785
|
}
|
|
45271
45786
|
function detectAdditionalLinter(cwd) {
|
|
45272
45787
|
if (detectRuff(cwd))
|
|
@@ -45294,10 +45809,10 @@ function detectAdditionalLinter(cwd) {
|
|
|
45294
45809
|
function findBinInAncestors(startDir, binName) {
|
|
45295
45810
|
let dir = startDir;
|
|
45296
45811
|
while (true) {
|
|
45297
|
-
const candidate =
|
|
45812
|
+
const candidate = path29.join(dir, "node_modules", ".bin", binName);
|
|
45298
45813
|
if (fs12.existsSync(candidate))
|
|
45299
45814
|
return candidate;
|
|
45300
|
-
const parent =
|
|
45815
|
+
const parent = path29.dirname(dir);
|
|
45301
45816
|
if (parent === dir)
|
|
45302
45817
|
break;
|
|
45303
45818
|
dir = parent;
|
|
@@ -45306,10 +45821,10 @@ function findBinInAncestors(startDir, binName) {
|
|
|
45306
45821
|
}
|
|
45307
45822
|
function findBinInEnvPath(binName) {
|
|
45308
45823
|
const searchPath = process.env.PATH ?? "";
|
|
45309
|
-
for (const dir of searchPath.split(
|
|
45824
|
+
for (const dir of searchPath.split(path29.delimiter)) {
|
|
45310
45825
|
if (!dir)
|
|
45311
45826
|
continue;
|
|
45312
|
-
const candidate =
|
|
45827
|
+
const candidate = path29.join(dir, binName);
|
|
45313
45828
|
if (fs12.existsSync(candidate))
|
|
45314
45829
|
return candidate;
|
|
45315
45830
|
}
|
|
@@ -45322,13 +45837,13 @@ async function detectAvailableLinter(directory) {
|
|
|
45322
45837
|
return null;
|
|
45323
45838
|
const projectDir = directory;
|
|
45324
45839
|
const isWindows = process.platform === "win32";
|
|
45325
|
-
const biomeBin = isWindows ?
|
|
45326
|
-
const eslintBin = isWindows ?
|
|
45840
|
+
const biomeBin = isWindows ? path29.join(projectDir, "node_modules", ".bin", "biome.EXE") : path29.join(projectDir, "node_modules", ".bin", "biome");
|
|
45841
|
+
const eslintBin = isWindows ? path29.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path29.join(projectDir, "node_modules", ".bin", "eslint");
|
|
45327
45842
|
const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
|
|
45328
45843
|
if (localResult)
|
|
45329
45844
|
return localResult;
|
|
45330
|
-
const biomeAncestor = findBinInAncestors(
|
|
45331
|
-
const eslintAncestor = findBinInAncestors(
|
|
45845
|
+
const biomeAncestor = findBinInAncestors(path29.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
|
|
45846
|
+
const eslintAncestor = findBinInAncestors(path29.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
|
|
45332
45847
|
if (biomeAncestor || eslintAncestor) {
|
|
45333
45848
|
return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
|
|
45334
45849
|
}
|
|
@@ -45487,7 +46002,7 @@ async function runAdditionalLint(linter, mode, cwd) {
|
|
|
45487
46002
|
};
|
|
45488
46003
|
}
|
|
45489
46004
|
}
|
|
45490
|
-
var MAX_OUTPUT_BYTES = 512000, MAX_COMMAND_LENGTH = 500, lint,
|
|
46005
|
+
var MAX_OUTPUT_BYTES = 512000, MAX_COMMAND_LENGTH = 500, lint, _internals19;
|
|
45491
46006
|
var init_lint = __esm(() => {
|
|
45492
46007
|
init_zod();
|
|
45493
46008
|
init_discovery();
|
|
@@ -45519,15 +46034,15 @@ var init_lint = __esm(() => {
|
|
|
45519
46034
|
}
|
|
45520
46035
|
const { mode } = args;
|
|
45521
46036
|
const cwd = directory;
|
|
45522
|
-
const linter = await
|
|
46037
|
+
const linter = await _internals19.detectAvailableLinter(directory);
|
|
45523
46038
|
if (linter) {
|
|
45524
|
-
const result = await
|
|
46039
|
+
const result = await _internals19.runLint(linter, mode, directory);
|
|
45525
46040
|
return JSON.stringify(result, null, 2);
|
|
45526
46041
|
}
|
|
45527
|
-
const additionalLinter =
|
|
46042
|
+
const additionalLinter = _internals19.detectAdditionalLinter(cwd);
|
|
45528
46043
|
if (additionalLinter) {
|
|
45529
46044
|
warn(`[lint] Using ${additionalLinter} linter for this project`);
|
|
45530
|
-
const result = await
|
|
46045
|
+
const result = await _internals19.runAdditionalLint(additionalLinter, mode, cwd);
|
|
45531
46046
|
return JSON.stringify(result, null, 2);
|
|
45532
46047
|
}
|
|
45533
46048
|
const errorResult = {
|
|
@@ -45541,7 +46056,7 @@ For Rust: rustup component add clippy`
|
|
|
45541
46056
|
return JSON.stringify(errorResult, null, 2);
|
|
45542
46057
|
}
|
|
45543
46058
|
});
|
|
45544
|
-
|
|
46059
|
+
_internals19 = {
|
|
45545
46060
|
detectAvailableLinter,
|
|
45546
46061
|
runLint,
|
|
45547
46062
|
detectAdditionalLinter,
|
|
@@ -45551,7 +46066,7 @@ For Rust: rustup component add clippy`
|
|
|
45551
46066
|
|
|
45552
46067
|
// src/tools/secretscan.ts
|
|
45553
46068
|
import * as fs13 from "fs";
|
|
45554
|
-
import * as
|
|
46069
|
+
import * as path30 from "path";
|
|
45555
46070
|
function calculateShannonEntropy(str) {
|
|
45556
46071
|
if (str.length === 0)
|
|
45557
46072
|
return 0;
|
|
@@ -45599,7 +46114,7 @@ function isGlobOrPathPattern(pattern) {
|
|
|
45599
46114
|
return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
|
|
45600
46115
|
}
|
|
45601
46116
|
function loadSecretScanIgnore(scanDir) {
|
|
45602
|
-
const ignorePath =
|
|
46117
|
+
const ignorePath = path30.join(scanDir, ".secretscanignore");
|
|
45603
46118
|
try {
|
|
45604
46119
|
if (!fs13.existsSync(ignorePath))
|
|
45605
46120
|
return [];
|
|
@@ -45622,7 +46137,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
|
|
|
45622
46137
|
if (exactNames.has(entry))
|
|
45623
46138
|
return true;
|
|
45624
46139
|
for (const pattern of globPatterns) {
|
|
45625
|
-
if (
|
|
46140
|
+
if (path30.matchesGlob(relPath, pattern))
|
|
45626
46141
|
return true;
|
|
45627
46142
|
}
|
|
45628
46143
|
return false;
|
|
@@ -45643,7 +46158,7 @@ function validateDirectoryInput(dir) {
|
|
|
45643
46158
|
return null;
|
|
45644
46159
|
}
|
|
45645
46160
|
function isBinaryFile(filePath, buffer) {
|
|
45646
|
-
const ext =
|
|
46161
|
+
const ext = path30.extname(filePath).toLowerCase();
|
|
45647
46162
|
if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
45648
46163
|
return true;
|
|
45649
46164
|
}
|
|
@@ -45779,9 +46294,9 @@ function isSymlinkLoop(realPath, visited) {
|
|
|
45779
46294
|
return false;
|
|
45780
46295
|
}
|
|
45781
46296
|
function isPathWithinScope(realPath, scanDir) {
|
|
45782
|
-
const resolvedScanDir =
|
|
45783
|
-
const resolvedRealPath =
|
|
45784
|
-
return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir +
|
|
46297
|
+
const resolvedScanDir = path30.resolve(scanDir);
|
|
46298
|
+
const resolvedRealPath = path30.resolve(realPath);
|
|
46299
|
+
return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path30.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
|
|
45785
46300
|
}
|
|
45786
46301
|
function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
|
|
45787
46302
|
skippedDirs: 0,
|
|
@@ -45807,8 +46322,8 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
45807
46322
|
return a.localeCompare(b);
|
|
45808
46323
|
});
|
|
45809
46324
|
for (const entry of entries) {
|
|
45810
|
-
const fullPath =
|
|
45811
|
-
const relPath =
|
|
46325
|
+
const fullPath = path30.join(dir, entry);
|
|
46326
|
+
const relPath = path30.relative(scanDir, fullPath).replace(/\\/g, "/");
|
|
45812
46327
|
if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
|
|
45813
46328
|
stats.skippedDirs++;
|
|
45814
46329
|
continue;
|
|
@@ -45843,7 +46358,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
45843
46358
|
const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
|
|
45844
46359
|
files.push(...subFiles);
|
|
45845
46360
|
} else if (lstat.isFile()) {
|
|
45846
|
-
const ext =
|
|
46361
|
+
const ext = path30.extname(fullPath).toLowerCase();
|
|
45847
46362
|
if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
45848
46363
|
files.push(fullPath);
|
|
45849
46364
|
} else {
|
|
@@ -45855,7 +46370,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
45855
46370
|
}
|
|
45856
46371
|
async function runSecretscan(directory) {
|
|
45857
46372
|
try {
|
|
45858
|
-
const result = await
|
|
46373
|
+
const result = await _internals20.secretscan.execute({ directory }, {});
|
|
45859
46374
|
const jsonStr = typeof result === "string" ? result : result.output;
|
|
45860
46375
|
return JSON.parse(jsonStr);
|
|
45861
46376
|
} catch (e) {
|
|
@@ -45870,7 +46385,7 @@ async function runSecretscan(directory) {
|
|
|
45870
46385
|
return errorResult;
|
|
45871
46386
|
}
|
|
45872
46387
|
}
|
|
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,
|
|
46388
|
+
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
46389
|
var init_secretscan = __esm(() => {
|
|
45875
46390
|
init_zod();
|
|
45876
46391
|
init_path_security();
|
|
@@ -46103,7 +46618,7 @@ var init_secretscan = __esm(() => {
|
|
|
46103
46618
|
}
|
|
46104
46619
|
}
|
|
46105
46620
|
try {
|
|
46106
|
-
const _scanDirRaw =
|
|
46621
|
+
const _scanDirRaw = path30.resolve(directory);
|
|
46107
46622
|
const scanDir = (() => {
|
|
46108
46623
|
try {
|
|
46109
46624
|
return fs13.realpathSync(_scanDirRaw);
|
|
@@ -46242,7 +46757,7 @@ var init_secretscan = __esm(() => {
|
|
|
46242
46757
|
}
|
|
46243
46758
|
}
|
|
46244
46759
|
});
|
|
46245
|
-
|
|
46760
|
+
_internals20 = {
|
|
46246
46761
|
secretscan,
|
|
46247
46762
|
runSecretscan
|
|
46248
46763
|
};
|
|
@@ -46250,7 +46765,7 @@ var init_secretscan = __esm(() => {
|
|
|
46250
46765
|
|
|
46251
46766
|
// src/lang/default-backend.ts
|
|
46252
46767
|
import * as fs14 from "fs";
|
|
46253
|
-
import * as
|
|
46768
|
+
import * as path31 from "path";
|
|
46254
46769
|
function detectFileExists(dir, pattern) {
|
|
46255
46770
|
if (pattern.includes("*") || pattern.includes("?")) {
|
|
46256
46771
|
try {
|
|
@@ -46262,7 +46777,7 @@ function detectFileExists(dir, pattern) {
|
|
|
46262
46777
|
}
|
|
46263
46778
|
}
|
|
46264
46779
|
try {
|
|
46265
|
-
fs14.accessSync(
|
|
46780
|
+
fs14.accessSync(path31.join(dir, pattern));
|
|
46266
46781
|
return true;
|
|
46267
46782
|
} catch {
|
|
46268
46783
|
return false;
|
|
@@ -46390,8 +46905,8 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
|
|
|
46390
46905
|
return ["mvn", "test"];
|
|
46391
46906
|
case "gradle": {
|
|
46392
46907
|
const isWindows = process.platform === "win32";
|
|
46393
|
-
const hasGradlewBat = fs14.existsSync(
|
|
46394
|
-
const hasGradlew = fs14.existsSync(
|
|
46908
|
+
const hasGradlewBat = fs14.existsSync(path31.join(dir, "gradlew.bat"));
|
|
46909
|
+
const hasGradlew = fs14.existsSync(path31.join(dir, "gradlew"));
|
|
46395
46910
|
if (hasGradlewBat && isWindows)
|
|
46396
46911
|
return ["gradlew.bat", "test"];
|
|
46397
46912
|
if (hasGradlew)
|
|
@@ -46408,7 +46923,7 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
|
|
|
46408
46923
|
"cmake-build-release",
|
|
46409
46924
|
"out"
|
|
46410
46925
|
];
|
|
46411
|
-
const actualBuildDir = buildDirCandidates.find((d) => fs14.existsSync(
|
|
46926
|
+
const actualBuildDir = buildDirCandidates.find((d) => fs14.existsSync(path31.join(dir, d, "CMakeCache.txt"))) ?? "build";
|
|
46412
46927
|
return ["ctest", "--test-dir", actualBuildDir];
|
|
46413
46928
|
}
|
|
46414
46929
|
case "swift-test":
|
|
@@ -46695,17 +47210,17 @@ async function defaultSelectBuildCommand(profile, dir) {
|
|
|
46695
47210
|
return null;
|
|
46696
47211
|
}
|
|
46697
47212
|
async function defaultTestFilesFor(profile, sourceFile, dir) {
|
|
46698
|
-
const ext =
|
|
47213
|
+
const ext = path31.extname(sourceFile);
|
|
46699
47214
|
if (!profile.extensions.includes(ext))
|
|
46700
47215
|
return [];
|
|
46701
|
-
const base =
|
|
46702
|
-
const rel =
|
|
46703
|
-
const relDir =
|
|
47216
|
+
const base = path31.basename(sourceFile, ext);
|
|
47217
|
+
const rel = path31.relative(dir, sourceFile);
|
|
47218
|
+
const relDir = path31.dirname(rel);
|
|
46704
47219
|
const stripSrc = relDir.replace(/^src(\/|\\)/, "");
|
|
46705
47220
|
const candidates = new Set;
|
|
46706
47221
|
for (const tDir of ["tests", "test", "__tests__", "spec"]) {
|
|
46707
47222
|
for (const suffix of ["", "_test", ".test", "_spec", ".spec"]) {
|
|
46708
|
-
candidates.add(
|
|
47223
|
+
candidates.add(path31.join(dir, tDir, stripSrc, `${base}${suffix}${ext}`));
|
|
46709
47224
|
}
|
|
46710
47225
|
}
|
|
46711
47226
|
const existing = [];
|
|
@@ -46746,7 +47261,7 @@ var init_default_backend = __esm(() => {
|
|
|
46746
47261
|
|
|
46747
47262
|
// src/lang/backends/go.ts
|
|
46748
47263
|
import * as fs15 from "fs";
|
|
46749
|
-
import * as
|
|
47264
|
+
import * as path32 from "path";
|
|
46750
47265
|
function extractImports(_sourceFile, source) {
|
|
46751
47266
|
const out = new Set;
|
|
46752
47267
|
IMPORT_REGEX_SINGLE.lastIndex = 0;
|
|
@@ -46772,7 +47287,7 @@ function extractImports(_sourceFile, source) {
|
|
|
46772
47287
|
async function selectFramework(dir) {
|
|
46773
47288
|
let content;
|
|
46774
47289
|
try {
|
|
46775
|
-
content = fs15.readFileSync(
|
|
47290
|
+
content = fs15.readFileSync(path32.join(dir, "go.mod"), "utf-8");
|
|
46776
47291
|
} catch {
|
|
46777
47292
|
return null;
|
|
46778
47293
|
}
|
|
@@ -46793,16 +47308,16 @@ async function selectFramework(dir) {
|
|
|
46793
47308
|
async function selectEntryPoints(dir) {
|
|
46794
47309
|
const points = [];
|
|
46795
47310
|
try {
|
|
46796
|
-
fs15.accessSync(
|
|
47311
|
+
fs15.accessSync(path32.join(dir, "main.go"));
|
|
46797
47312
|
points.push("main.go");
|
|
46798
47313
|
} catch {}
|
|
46799
47314
|
try {
|
|
46800
|
-
const cmdDir =
|
|
47315
|
+
const cmdDir = path32.join(dir, "cmd");
|
|
46801
47316
|
const subdirs = fs15.readdirSync(cmdDir, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
46802
47317
|
for (const sub of subdirs) {
|
|
46803
|
-
const main =
|
|
47318
|
+
const main = path32.join("cmd", sub.name, "main.go");
|
|
46804
47319
|
try {
|
|
46805
|
-
fs15.accessSync(
|
|
47320
|
+
fs15.accessSync(path32.join(dir, main));
|
|
46806
47321
|
points.push(main);
|
|
46807
47322
|
} catch {}
|
|
46808
47323
|
}
|
|
@@ -46821,19 +47336,19 @@ function buildGoBackend() {
|
|
|
46821
47336
|
selectEntryPoints
|
|
46822
47337
|
};
|
|
46823
47338
|
}
|
|
46824
|
-
var PROFILE_ID = "go", IMPORT_REGEX_SINGLE, IMPORT_REGEX_GROUP, IMPORT_REGEX_GROUP_LINE,
|
|
47339
|
+
var PROFILE_ID = "go", IMPORT_REGEX_SINGLE, IMPORT_REGEX_GROUP, IMPORT_REGEX_GROUP_LINE, _internals21;
|
|
46825
47340
|
var init_go = __esm(() => {
|
|
46826
47341
|
init_default_backend();
|
|
46827
47342
|
init_profiles();
|
|
46828
47343
|
IMPORT_REGEX_SINGLE = /^\s*import\s+(?:[a-zA-Z_.][a-zA-Z0-9_]*\s+)?"([^"]+)"/gm;
|
|
46829
47344
|
IMPORT_REGEX_GROUP = /^\s*import\s*\(([\s\S]*?)\)/gm;
|
|
46830
47345
|
IMPORT_REGEX_GROUP_LINE = /(?:[a-zA-Z_.][a-zA-Z0-9_]*\s+)?"([^"]+)"/g;
|
|
46831
|
-
|
|
47346
|
+
_internals21 = { extractImports };
|
|
46832
47347
|
});
|
|
46833
47348
|
|
|
46834
47349
|
// src/lang/backends/python.ts
|
|
46835
47350
|
import * as fs16 from "fs";
|
|
46836
|
-
import * as
|
|
47351
|
+
import * as path33 from "path";
|
|
46837
47352
|
function parseImportTargets(rawTargets) {
|
|
46838
47353
|
const cleaned = rawTargets.replace(/[()]/g, "").split(`
|
|
46839
47354
|
`).map((line) => line.replace(/#.*$/, "").replace(/\\\s*$/, "")).join(" ");
|
|
@@ -46893,7 +47408,7 @@ async function selectFramework2(dir) {
|
|
|
46893
47408
|
];
|
|
46894
47409
|
for (const candidate of ["pyproject.toml", "requirements.txt", "setup.py"]) {
|
|
46895
47410
|
try {
|
|
46896
|
-
const content = fs16.readFileSync(
|
|
47411
|
+
const content = fs16.readFileSync(path33.join(dir, candidate), "utf-8");
|
|
46897
47412
|
const lower = content.toLowerCase();
|
|
46898
47413
|
for (const [pkg, name] of candidates) {
|
|
46899
47414
|
if (lower.includes(pkg)) {
|
|
@@ -46907,7 +47422,7 @@ async function selectFramework2(dir) {
|
|
|
46907
47422
|
async function selectEntryPoints2(dir) {
|
|
46908
47423
|
const points = new Set;
|
|
46909
47424
|
try {
|
|
46910
|
-
const content = fs16.readFileSync(
|
|
47425
|
+
const content = fs16.readFileSync(path33.join(dir, "pyproject.toml"), "utf-8");
|
|
46911
47426
|
const scriptsBlock = content.match(/\[project\.scripts\][\s\S]*?(?=\n\[|$)/);
|
|
46912
47427
|
if (scriptsBlock) {
|
|
46913
47428
|
for (const line of scriptsBlock[0].split(`
|
|
@@ -46922,7 +47437,7 @@ async function selectEntryPoints2(dir) {
|
|
|
46922
47437
|
} catch {}
|
|
46923
47438
|
for (const name of ["manage.py", "main.py", "app.py", "__main__.py"]) {
|
|
46924
47439
|
try {
|
|
46925
|
-
fs16.accessSync(
|
|
47440
|
+
fs16.accessSync(path33.join(dir, name));
|
|
46926
47441
|
points.add(name);
|
|
46927
47442
|
} catch {}
|
|
46928
47443
|
}
|
|
@@ -46940,18 +47455,18 @@ function buildPythonBackend() {
|
|
|
46940
47455
|
selectEntryPoints: selectEntryPoints2
|
|
46941
47456
|
};
|
|
46942
47457
|
}
|
|
46943
|
-
var PROFILE_ID2 = "python", IMPORT_REGEX_FROM_WITH_TARGETS, IMPORT_REGEX_IMPORT,
|
|
47458
|
+
var PROFILE_ID2 = "python", IMPORT_REGEX_FROM_WITH_TARGETS, IMPORT_REGEX_IMPORT, _internals22;
|
|
46944
47459
|
var init_python = __esm(() => {
|
|
46945
47460
|
init_default_backend();
|
|
46946
47461
|
init_profiles();
|
|
46947
47462
|
IMPORT_REGEX_FROM_WITH_TARGETS = /^\s*from\s+(\.*[\w.]*)\s+import\s+(\([^)]*\)|[^\n#]+)/gm;
|
|
46948
47463
|
IMPORT_REGEX_IMPORT = /^\s*import\s+([^\n#]+)/gm;
|
|
46949
|
-
|
|
47464
|
+
_internals22 = { extractImports: extractImports2 };
|
|
46950
47465
|
});
|
|
46951
47466
|
|
|
46952
47467
|
// src/test-impact/analyzer.ts
|
|
46953
47468
|
import fs17 from "fs";
|
|
46954
|
-
import
|
|
47469
|
+
import path34 from "path";
|
|
46955
47470
|
function normalizePath(p) {
|
|
46956
47471
|
return p.replace(/\\/g, "/");
|
|
46957
47472
|
}
|
|
@@ -46972,8 +47487,8 @@ function resolveRelativeImport(fromDir, importPath) {
|
|
|
46972
47487
|
if (!importPath.startsWith(".")) {
|
|
46973
47488
|
return null;
|
|
46974
47489
|
}
|
|
46975
|
-
const resolved =
|
|
46976
|
-
if (
|
|
47490
|
+
const resolved = path34.resolve(fromDir, importPath);
|
|
47491
|
+
if (path34.extname(resolved)) {
|
|
46977
47492
|
if (fs17.existsSync(resolved) && fs17.statSync(resolved).isFile()) {
|
|
46978
47493
|
return normalizePath(resolved);
|
|
46979
47494
|
}
|
|
@@ -46993,20 +47508,20 @@ function resolvePythonImport(fromDir, module) {
|
|
|
46993
47508
|
const leadingDots = module.match(/^\.+/)?.[0].length ?? 0;
|
|
46994
47509
|
let baseDir = fromDir;
|
|
46995
47510
|
for (let i = 1;i < leadingDots; i++) {
|
|
46996
|
-
baseDir =
|
|
47511
|
+
baseDir = path34.dirname(baseDir);
|
|
46997
47512
|
}
|
|
46998
47513
|
const rest = module.slice(leadingDots);
|
|
46999
47514
|
if (rest.length === 0) {
|
|
47000
|
-
const initPath =
|
|
47515
|
+
const initPath = path34.join(baseDir, "__init__.py");
|
|
47001
47516
|
if (fs17.existsSync(initPath) && fs17.statSync(initPath).isFile()) {
|
|
47002
47517
|
return normalizePath(initPath);
|
|
47003
47518
|
}
|
|
47004
47519
|
return null;
|
|
47005
47520
|
}
|
|
47006
|
-
const subpath = rest.replace(/\./g,
|
|
47521
|
+
const subpath = rest.replace(/\./g, path34.sep);
|
|
47007
47522
|
const candidates = [
|
|
47008
|
-
`${
|
|
47009
|
-
|
|
47523
|
+
`${path34.join(baseDir, subpath)}.py`,
|
|
47524
|
+
path34.join(baseDir, subpath, "__init__.py")
|
|
47010
47525
|
];
|
|
47011
47526
|
for (const c of candidates) {
|
|
47012
47527
|
if (fs17.existsSync(c) && fs17.statSync(c).isFile())
|
|
@@ -47015,7 +47530,7 @@ function resolvePythonImport(fromDir, module) {
|
|
|
47015
47530
|
return null;
|
|
47016
47531
|
}
|
|
47017
47532
|
function findGoModule(fromDir) {
|
|
47018
|
-
const resolved =
|
|
47533
|
+
const resolved = path34.resolve(fromDir);
|
|
47019
47534
|
let cur = resolved;
|
|
47020
47535
|
const walked = [];
|
|
47021
47536
|
for (let i = 0;i < 16; i++) {
|
|
@@ -47027,7 +47542,7 @@ function findGoModule(fromDir) {
|
|
|
47027
47542
|
}
|
|
47028
47543
|
walked.push(cur);
|
|
47029
47544
|
try {
|
|
47030
|
-
const goMod =
|
|
47545
|
+
const goMod = path34.join(cur, "go.mod");
|
|
47031
47546
|
const content = fs17.readFileSync(goMod, "utf-8");
|
|
47032
47547
|
const moduleMatch = content.match(/^\s*module\s+"?([^"\s/]+(?:\/[^"\s]+)*)"?/m);
|
|
47033
47548
|
if (moduleMatch) {
|
|
@@ -47038,10 +47553,10 @@ function findGoModule(fromDir) {
|
|
|
47038
47553
|
}
|
|
47039
47554
|
} catch {}
|
|
47040
47555
|
try {
|
|
47041
|
-
fs17.accessSync(
|
|
47556
|
+
fs17.accessSync(path34.join(cur, ".git"));
|
|
47042
47557
|
break;
|
|
47043
47558
|
} catch {}
|
|
47044
|
-
const parent =
|
|
47559
|
+
const parent = path34.dirname(cur);
|
|
47045
47560
|
if (parent === cur)
|
|
47046
47561
|
break;
|
|
47047
47562
|
cur = parent;
|
|
@@ -47053,12 +47568,12 @@ function findGoModule(fromDir) {
|
|
|
47053
47568
|
function resolveGoImport(fromDir, importPath) {
|
|
47054
47569
|
let dir = null;
|
|
47055
47570
|
if (importPath.startsWith(".")) {
|
|
47056
|
-
dir =
|
|
47571
|
+
dir = path34.resolve(fromDir, importPath);
|
|
47057
47572
|
} else {
|
|
47058
47573
|
const mod = findGoModule(fromDir);
|
|
47059
47574
|
if (mod && (importPath === mod.modulePath || importPath.startsWith(`${mod.modulePath}/`))) {
|
|
47060
47575
|
const subpath = importPath.slice(mod.modulePath.length);
|
|
47061
|
-
dir =
|
|
47576
|
+
dir = path34.join(mod.moduleRoot, subpath);
|
|
47062
47577
|
}
|
|
47063
47578
|
}
|
|
47064
47579
|
if (dir === null)
|
|
@@ -47066,7 +47581,7 @@ function resolveGoImport(fromDir, importPath) {
|
|
|
47066
47581
|
if (!fs17.existsSync(dir) || !fs17.statSync(dir).isDirectory())
|
|
47067
47582
|
return [];
|
|
47068
47583
|
try {
|
|
47069
|
-
return fs17.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath(
|
|
47584
|
+
return fs17.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath(path34.join(dir, f)));
|
|
47070
47585
|
} catch {
|
|
47071
47586
|
return [];
|
|
47072
47587
|
}
|
|
@@ -47105,15 +47620,15 @@ function findTestFilesSync(cwd) {
|
|
|
47105
47620
|
for (const entry of entries) {
|
|
47106
47621
|
if (entry.isDirectory()) {
|
|
47107
47622
|
if (!skipDirs.has(entry.name)) {
|
|
47108
|
-
walk(
|
|
47623
|
+
walk(path34.join(dir, entry.name), visitedInodes);
|
|
47109
47624
|
}
|
|
47110
47625
|
} else if (entry.isFile()) {
|
|
47111
47626
|
const name = entry.name;
|
|
47112
47627
|
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(`${
|
|
47628
|
+
const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path34.sep}tests${path34.sep}`) && name.endsWith(".py");
|
|
47114
47629
|
const isGoTest = /.+_test\.go$/.test(name);
|
|
47115
47630
|
if (isTsTest || isPyTest || isGoTest) {
|
|
47116
|
-
testFiles.push(normalizePath(
|
|
47631
|
+
testFiles.push(normalizePath(path34.join(dir, entry.name)));
|
|
47117
47632
|
}
|
|
47118
47633
|
}
|
|
47119
47634
|
}
|
|
@@ -47138,8 +47653,8 @@ function extractImports3(content) {
|
|
|
47138
47653
|
];
|
|
47139
47654
|
}
|
|
47140
47655
|
function addImpactEdgesForTestFile(testFile, content, impactMap) {
|
|
47141
|
-
const ext =
|
|
47142
|
-
const testDir =
|
|
47656
|
+
const ext = path34.extname(testFile).toLowerCase();
|
|
47657
|
+
const testDir = path34.dirname(testFile);
|
|
47143
47658
|
function addEdge(source) {
|
|
47144
47659
|
if (!impactMap[source])
|
|
47145
47660
|
impactMap[source] = [];
|
|
@@ -47157,7 +47672,7 @@ function addImpactEdgesForTestFile(testFile, content, impactMap) {
|
|
|
47157
47672
|
return;
|
|
47158
47673
|
}
|
|
47159
47674
|
if (PYTHON_EXTENSIONS.has(ext)) {
|
|
47160
|
-
const modules =
|
|
47675
|
+
const modules = _internals22.extractImports(testFile, content);
|
|
47161
47676
|
for (const mod of modules) {
|
|
47162
47677
|
const resolved = resolvePythonImport(testDir, mod);
|
|
47163
47678
|
if (resolved !== null)
|
|
@@ -47166,7 +47681,7 @@ function addImpactEdgesForTestFile(testFile, content, impactMap) {
|
|
|
47166
47681
|
return;
|
|
47167
47682
|
}
|
|
47168
47683
|
if (GO_EXTENSIONS.has(ext)) {
|
|
47169
|
-
const imports =
|
|
47684
|
+
const imports = _internals21.extractImports(testFile, content);
|
|
47170
47685
|
for (const importPath of imports) {
|
|
47171
47686
|
const sourceFiles = resolveGoImport(testDir, importPath);
|
|
47172
47687
|
for (const source of sourceFiles)
|
|
@@ -47193,12 +47708,12 @@ async function buildImpactMapInternal(cwd) {
|
|
|
47193
47708
|
return impactMap;
|
|
47194
47709
|
}
|
|
47195
47710
|
async function buildImpactMap(cwd) {
|
|
47196
|
-
const impactMap = await
|
|
47197
|
-
await
|
|
47711
|
+
const impactMap = await _internals23.buildImpactMapInternal(cwd);
|
|
47712
|
+
await _internals23.saveImpactMap(cwd, impactMap);
|
|
47198
47713
|
return impactMap;
|
|
47199
47714
|
}
|
|
47200
47715
|
async function loadImpactMap(cwd, options) {
|
|
47201
|
-
const cachePath =
|
|
47716
|
+
const cachePath = path34.join(cwd, ".swarm", "cache", "impact-map.json");
|
|
47202
47717
|
if (fs17.existsSync(cachePath)) {
|
|
47203
47718
|
try {
|
|
47204
47719
|
const content = fs17.readFileSync(cachePath, "utf-8");
|
|
@@ -47208,7 +47723,7 @@ async function loadImpactMap(cwd, options) {
|
|
|
47208
47723
|
const hasValidValues = Object.values(map3).every((v) => Array.isArray(v) && v.every((item) => typeof item === "string"));
|
|
47209
47724
|
if (hasValidValues) {
|
|
47210
47725
|
const generatedAt = new Date(data.generatedAt).getTime();
|
|
47211
|
-
if (!
|
|
47726
|
+
if (!_internals23.isCacheStale(map3, generatedAt)) {
|
|
47212
47727
|
return map3;
|
|
47213
47728
|
}
|
|
47214
47729
|
if (options?.skipRebuild) {
|
|
@@ -47228,15 +47743,15 @@ async function loadImpactMap(cwd, options) {
|
|
|
47228
47743
|
if (options?.skipRebuild) {
|
|
47229
47744
|
return {};
|
|
47230
47745
|
}
|
|
47231
|
-
return
|
|
47746
|
+
return _internals23.buildImpactMap(cwd);
|
|
47232
47747
|
}
|
|
47233
47748
|
async function saveImpactMap(cwd, impactMap) {
|
|
47234
|
-
if (!
|
|
47749
|
+
if (!path34.isAbsolute(cwd)) {
|
|
47235
47750
|
throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
|
|
47236
47751
|
}
|
|
47237
|
-
|
|
47238
|
-
const cacheDir2 =
|
|
47239
|
-
const cachePath =
|
|
47752
|
+
_internals23.validateProjectRoot(cwd);
|
|
47753
|
+
const cacheDir2 = path34.join(cwd, ".swarm", "cache");
|
|
47754
|
+
const cachePath = path34.join(cacheDir2, "impact-map.json");
|
|
47240
47755
|
if (!fs17.existsSync(cacheDir2)) {
|
|
47241
47756
|
fs17.mkdirSync(cacheDir2, { recursive: true });
|
|
47242
47757
|
}
|
|
@@ -47258,7 +47773,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
|
|
|
47258
47773
|
};
|
|
47259
47774
|
}
|
|
47260
47775
|
const validFiles = changedFiles.filter((f) => typeof f === "string" && f.length > 0 && !f.includes("\x00"));
|
|
47261
|
-
const impactMap = await
|
|
47776
|
+
const impactMap = await _internals23.loadImpactMap(cwd);
|
|
47262
47777
|
const impactedTestsSet = new Set;
|
|
47263
47778
|
const untestedFiles = [];
|
|
47264
47779
|
let visitedCount = 0;
|
|
@@ -47268,7 +47783,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
|
|
|
47268
47783
|
budgetExceeded = true;
|
|
47269
47784
|
break;
|
|
47270
47785
|
}
|
|
47271
|
-
const normalizedChanged = normalizePath(
|
|
47786
|
+
const normalizedChanged = normalizePath(path34.resolve(changedFile));
|
|
47272
47787
|
const tests = impactMap[normalizedChanged];
|
|
47273
47788
|
if (tests && tests.length > 0) {
|
|
47274
47789
|
for (const test of tests) {
|
|
@@ -47325,7 +47840,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
|
|
|
47325
47840
|
budgetExceeded
|
|
47326
47841
|
};
|
|
47327
47842
|
}
|
|
47328
|
-
var IMPORT_REGEX_ES, IMPORT_REGEX_REQUIRE, IMPORT_REGEX_REEXPORT, TS_EXTENSIONS, PYTHON_EXTENSIONS, GO_EXTENSIONS, EXTENSIONS_TO_TRY, goModuleCache,
|
|
47843
|
+
var IMPORT_REGEX_ES, IMPORT_REGEX_REQUIRE, IMPORT_REGEX_REEXPORT, TS_EXTENSIONS, PYTHON_EXTENSIONS, GO_EXTENSIONS, EXTENSIONS_TO_TRY, goModuleCache, _internals23;
|
|
47329
47844
|
var init_analyzer = __esm(() => {
|
|
47330
47845
|
init_manager2();
|
|
47331
47846
|
init_go();
|
|
@@ -47338,7 +47853,7 @@ var init_analyzer = __esm(() => {
|
|
|
47338
47853
|
GO_EXTENSIONS = new Set([".go"]);
|
|
47339
47854
|
EXTENSIONS_TO_TRY = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
47340
47855
|
goModuleCache = new Map;
|
|
47341
|
-
|
|
47856
|
+
_internals23 = {
|
|
47342
47857
|
validateProjectRoot,
|
|
47343
47858
|
normalizePath,
|
|
47344
47859
|
isCacheStale,
|
|
@@ -47561,15 +48076,15 @@ var FLAKY_THRESHOLD = 0.3, MIN_RUNS_FOR_QUARANTINE = 5, MAX_HISTORY_RUNS = 20;
|
|
|
47561
48076
|
|
|
47562
48077
|
// src/test-impact/history-store.ts
|
|
47563
48078
|
import fs18 from "fs";
|
|
47564
|
-
import
|
|
48079
|
+
import path35 from "path";
|
|
47565
48080
|
function getHistoryPath(workingDir) {
|
|
47566
48081
|
if (!workingDir) {
|
|
47567
48082
|
throw new Error("getHistoryPath requires a working directory \u2014 project root must be provided by the caller");
|
|
47568
48083
|
}
|
|
47569
|
-
if (!
|
|
48084
|
+
if (!path35.isAbsolute(workingDir)) {
|
|
47570
48085
|
throw new Error(`getHistoryPath requires an absolute project root path, got: "${workingDir}"`);
|
|
47571
48086
|
}
|
|
47572
|
-
return
|
|
48087
|
+
return path35.join(workingDir, ".swarm", "cache", "test-history.jsonl");
|
|
47573
48088
|
}
|
|
47574
48089
|
function sanitizeErrorMessage(errorMessage) {
|
|
47575
48090
|
if (errorMessage === undefined) {
|
|
@@ -47656,8 +48171,8 @@ function batchAppendTestRuns(records, workingDir) {
|
|
|
47656
48171
|
}
|
|
47657
48172
|
}
|
|
47658
48173
|
const historyPath = getHistoryPath(workingDir);
|
|
47659
|
-
const historyDir =
|
|
47660
|
-
|
|
48174
|
+
const historyDir = path35.dirname(historyPath);
|
|
48175
|
+
_internals24.validateProjectRoot(workingDir);
|
|
47661
48176
|
if (!fs18.existsSync(historyDir)) {
|
|
47662
48177
|
fs18.mkdirSync(historyDir, { recursive: true });
|
|
47663
48178
|
}
|
|
@@ -47737,7 +48252,7 @@ function getAllHistory(workingDir) {
|
|
|
47737
48252
|
records.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
47738
48253
|
return records;
|
|
47739
48254
|
}
|
|
47740
|
-
var MAX_HISTORY_PER_TEST = 20, MAX_ERROR_LENGTH = 500, MAX_STACK_LENGTH = 200, MAX_CHANGED_FILES = 50, DANGEROUS_PROPERTY_NAMES,
|
|
48255
|
+
var MAX_HISTORY_PER_TEST = 20, MAX_ERROR_LENGTH = 500, MAX_STACK_LENGTH = 200, MAX_CHANGED_FILES = 50, DANGEROUS_PROPERTY_NAMES, _internals24;
|
|
47741
48256
|
var init_history_store = __esm(() => {
|
|
47742
48257
|
init_manager2();
|
|
47743
48258
|
DANGEROUS_PROPERTY_NAMES = new Set([
|
|
@@ -47745,14 +48260,14 @@ var init_history_store = __esm(() => {
|
|
|
47745
48260
|
"constructor",
|
|
47746
48261
|
"prototype"
|
|
47747
48262
|
]);
|
|
47748
|
-
|
|
48263
|
+
_internals24 = {
|
|
47749
48264
|
validateProjectRoot
|
|
47750
48265
|
};
|
|
47751
48266
|
});
|
|
47752
48267
|
|
|
47753
48268
|
// src/tools/resolve-working-directory.ts
|
|
47754
48269
|
import * as fs19 from "fs";
|
|
47755
|
-
import * as
|
|
48270
|
+
import * as path36 from "path";
|
|
47756
48271
|
function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
47757
48272
|
if (workingDirectory == null || workingDirectory === "") {
|
|
47758
48273
|
return { success: true, directory: fallbackDirectory };
|
|
@@ -47772,15 +48287,15 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
47772
48287
|
};
|
|
47773
48288
|
}
|
|
47774
48289
|
}
|
|
47775
|
-
const normalizedDir =
|
|
47776
|
-
const pathParts = normalizedDir.split(
|
|
48290
|
+
const normalizedDir = path36.normalize(workingDirectory);
|
|
48291
|
+
const pathParts = normalizedDir.split(path36.sep);
|
|
47777
48292
|
if (pathParts.includes("..")) {
|
|
47778
48293
|
return {
|
|
47779
48294
|
success: false,
|
|
47780
48295
|
message: "Invalid working_directory: path traversal sequences (..) are not allowed"
|
|
47781
48296
|
};
|
|
47782
48297
|
}
|
|
47783
|
-
const resolvedDir =
|
|
48298
|
+
const resolvedDir = path36.resolve(normalizedDir);
|
|
47784
48299
|
let statResult;
|
|
47785
48300
|
try {
|
|
47786
48301
|
statResult = fs19.statSync(resolvedDir);
|
|
@@ -47796,7 +48311,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
47796
48311
|
message: `Invalid working_directory: path "${resolvedDir}" is not a directory`
|
|
47797
48312
|
};
|
|
47798
48313
|
}
|
|
47799
|
-
const resolvedFallback =
|
|
48314
|
+
const resolvedFallback = path36.resolve(fallbackDirectory);
|
|
47800
48315
|
let fallbackExists = false;
|
|
47801
48316
|
try {
|
|
47802
48317
|
fs19.statSync(resolvedFallback);
|
|
@@ -47806,7 +48321,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
47806
48321
|
}
|
|
47807
48322
|
if (workingDirectory != null && workingDirectory !== "") {
|
|
47808
48323
|
if (fallbackExists) {
|
|
47809
|
-
const isSubdirectory = resolvedDir.startsWith(resolvedFallback +
|
|
48324
|
+
const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path36.sep);
|
|
47810
48325
|
if (isSubdirectory) {
|
|
47811
48326
|
return {
|
|
47812
48327
|
success: false,
|
|
@@ -47861,17 +48376,17 @@ var init_registry_backend = __esm(() => {
|
|
|
47861
48376
|
|
|
47862
48377
|
// src/lang/backends/typescript.ts
|
|
47863
48378
|
import * as fs20 from "fs";
|
|
47864
|
-
import * as
|
|
48379
|
+
import * as path37 from "path";
|
|
47865
48380
|
function readPackageJsonRaw(dir) {
|
|
47866
48381
|
try {
|
|
47867
|
-
const content = fs20.readFileSync(
|
|
48382
|
+
const content = fs20.readFileSync(path37.join(dir, "package.json"), "utf-8");
|
|
47868
48383
|
return JSON.parse(content);
|
|
47869
48384
|
} catch {
|
|
47870
48385
|
return null;
|
|
47871
48386
|
}
|
|
47872
48387
|
}
|
|
47873
48388
|
function readPackageJson(dir) {
|
|
47874
|
-
return
|
|
48389
|
+
return _internals25.readPackageJsonRaw(dir);
|
|
47875
48390
|
}
|
|
47876
48391
|
function readPackageJsonTestScript(dir) {
|
|
47877
48392
|
return readPackageJson(dir)?.scripts?.test ?? null;
|
|
@@ -48041,7 +48556,7 @@ function buildTypescriptBackend() {
|
|
|
48041
48556
|
selectEntryPoints: selectEntryPoints3
|
|
48042
48557
|
};
|
|
48043
48558
|
}
|
|
48044
|
-
var PROFILE_ID3 = "typescript", IMPORT_REGEX_ES2, IMPORT_REGEX_BARE, IMPORT_REGEX_REQUIRE2, IMPORT_REGEX_DYNAMIC, IMPORT_REGEX_REEXPORT2,
|
|
48559
|
+
var PROFILE_ID3 = "typescript", IMPORT_REGEX_ES2, IMPORT_REGEX_BARE, IMPORT_REGEX_REQUIRE2, IMPORT_REGEX_DYNAMIC, IMPORT_REGEX_REEXPORT2, _internals25;
|
|
48045
48560
|
var init_typescript = __esm(() => {
|
|
48046
48561
|
init_default_backend();
|
|
48047
48562
|
init_profiles();
|
|
@@ -48050,7 +48565,7 @@ var init_typescript = __esm(() => {
|
|
|
48050
48565
|
IMPORT_REGEX_REQUIRE2 = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
48051
48566
|
IMPORT_REGEX_DYNAMIC = /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
48052
48567
|
IMPORT_REGEX_REEXPORT2 = /export\s+(?:\{[^}]*\}|\*)\s+from\s+['"]([^'"]+)['"]/g;
|
|
48053
|
-
|
|
48568
|
+
_internals25 = {
|
|
48054
48569
|
readPackageJsonRaw,
|
|
48055
48570
|
readPackageJsonTestScript,
|
|
48056
48571
|
frameworkFromScriptsTest
|
|
@@ -48081,10 +48596,10 @@ __export(exports_dispatch, {
|
|
|
48081
48596
|
pickedProfiles: () => pickedProfiles,
|
|
48082
48597
|
pickBackend: () => pickBackend,
|
|
48083
48598
|
clearDispatchCache: () => clearDispatchCache,
|
|
48084
|
-
_internals: () =>
|
|
48599
|
+
_internals: () => _internals26
|
|
48085
48600
|
});
|
|
48086
48601
|
import * as fs21 from "fs";
|
|
48087
|
-
import * as
|
|
48602
|
+
import * as path38 from "path";
|
|
48088
48603
|
function safeReaddirSet(dir) {
|
|
48089
48604
|
try {
|
|
48090
48605
|
return new Set(fs21.readdirSync(dir));
|
|
@@ -48101,14 +48616,14 @@ function manifestHash(dir) {
|
|
|
48101
48616
|
if (!entries.has(name))
|
|
48102
48617
|
continue;
|
|
48103
48618
|
try {
|
|
48104
|
-
const stat3 = fs21.statSync(
|
|
48619
|
+
const stat3 = fs21.statSync(path38.join(dir, name));
|
|
48105
48620
|
parts.push(`${name}:${stat3.size}:${stat3.mtimeMs}:${stat3.ino}`);
|
|
48106
48621
|
} catch {}
|
|
48107
48622
|
}
|
|
48108
48623
|
return parts.join("|");
|
|
48109
48624
|
}
|
|
48110
48625
|
function findManifestRoot(start) {
|
|
48111
|
-
const resolved =
|
|
48626
|
+
const resolved = path38.resolve(start);
|
|
48112
48627
|
const cached3 = manifestRootCache.get(resolved);
|
|
48113
48628
|
if (cached3 !== undefined)
|
|
48114
48629
|
return cached3;
|
|
@@ -48127,7 +48642,7 @@ function findManifestRoot(start) {
|
|
|
48127
48642
|
return cur;
|
|
48128
48643
|
}
|
|
48129
48644
|
}
|
|
48130
|
-
const parent =
|
|
48645
|
+
const parent = path38.dirname(cur);
|
|
48131
48646
|
if (parent === cur)
|
|
48132
48647
|
break;
|
|
48133
48648
|
cur = parent;
|
|
@@ -48136,7 +48651,7 @@ function findManifestRoot(start) {
|
|
|
48136
48651
|
return start;
|
|
48137
48652
|
}
|
|
48138
48653
|
function evictIfNeeded() {
|
|
48139
|
-
if (cache.size <=
|
|
48654
|
+
if (cache.size <= _internals26.cacheCapacity)
|
|
48140
48655
|
return;
|
|
48141
48656
|
let oldestKey;
|
|
48142
48657
|
let oldestOrder = Infinity;
|
|
@@ -48167,7 +48682,7 @@ async function pickBackend(dir) {
|
|
|
48167
48682
|
evictIfNeeded();
|
|
48168
48683
|
return null;
|
|
48169
48684
|
}
|
|
48170
|
-
const profiles = await
|
|
48685
|
+
const profiles = await _internals26.detectProjectLanguages(root);
|
|
48171
48686
|
if (profiles.length === 0) {
|
|
48172
48687
|
cache.set(cacheKey, {
|
|
48173
48688
|
hash: hash3,
|
|
@@ -48199,12 +48714,12 @@ function clearDispatchCache() {
|
|
|
48199
48714
|
manifestRootCache.clear();
|
|
48200
48715
|
insertCounter = 0;
|
|
48201
48716
|
}
|
|
48202
|
-
var
|
|
48717
|
+
var _internals26, cache, insertCounter = 0, MANIFEST_FILES, _MANIFEST_SET, manifestRootCache;
|
|
48203
48718
|
var init_dispatch = __esm(() => {
|
|
48204
48719
|
init_backends();
|
|
48205
48720
|
init_detector();
|
|
48206
48721
|
init_registry_backend();
|
|
48207
|
-
|
|
48722
|
+
_internals26 = {
|
|
48208
48723
|
detectProjectLanguages,
|
|
48209
48724
|
cacheCapacity: 64
|
|
48210
48725
|
};
|
|
@@ -48237,13 +48752,13 @@ var init_dispatch = __esm(() => {
|
|
|
48237
48752
|
|
|
48238
48753
|
// src/tools/test-runner.ts
|
|
48239
48754
|
import * as fs22 from "fs";
|
|
48240
|
-
import * as
|
|
48755
|
+
import * as path39 from "path";
|
|
48241
48756
|
async function estimateFanOut(sourceFiles, cwd) {
|
|
48242
48757
|
try {
|
|
48243
48758
|
const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
|
|
48244
48759
|
const uniqueTestFiles = new Set;
|
|
48245
48760
|
for (const sourceFile of sourceFiles) {
|
|
48246
|
-
const resolvedPath =
|
|
48761
|
+
const resolvedPath = path39.resolve(cwd, sourceFile);
|
|
48247
48762
|
const normalizedPath = resolvedPath.replace(/\\/g, "/");
|
|
48248
48763
|
const testFiles = impactMap[normalizedPath];
|
|
48249
48764
|
if (testFiles) {
|
|
@@ -48321,14 +48836,14 @@ function hasDevDependency(devDeps, ...patterns) {
|
|
|
48321
48836
|
return hasPackageJsonDependency(devDeps, ...patterns);
|
|
48322
48837
|
}
|
|
48323
48838
|
function detectGoTest(cwd) {
|
|
48324
|
-
return fs22.existsSync(
|
|
48839
|
+
return fs22.existsSync(path39.join(cwd, "go.mod")) && isCommandAvailable("go");
|
|
48325
48840
|
}
|
|
48326
48841
|
function detectJavaMaven(cwd) {
|
|
48327
|
-
return fs22.existsSync(
|
|
48842
|
+
return fs22.existsSync(path39.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
|
|
48328
48843
|
}
|
|
48329
48844
|
function detectGradle(cwd) {
|
|
48330
|
-
const hasBuildFile = fs22.existsSync(
|
|
48331
|
-
const hasGradlew = fs22.existsSync(
|
|
48845
|
+
const hasBuildFile = fs22.existsSync(path39.join(cwd, "build.gradle")) || fs22.existsSync(path39.join(cwd, "build.gradle.kts"));
|
|
48846
|
+
const hasGradlew = fs22.existsSync(path39.join(cwd, "gradlew")) || fs22.existsSync(path39.join(cwd, "gradlew.bat"));
|
|
48332
48847
|
return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
|
|
48333
48848
|
}
|
|
48334
48849
|
function detectDotnetTest(cwd) {
|
|
@@ -48341,25 +48856,25 @@ function detectDotnetTest(cwd) {
|
|
|
48341
48856
|
}
|
|
48342
48857
|
}
|
|
48343
48858
|
function detectCTest(cwd) {
|
|
48344
|
-
const hasSource = fs22.existsSync(
|
|
48345
|
-
const hasBuildCache = fs22.existsSync(
|
|
48859
|
+
const hasSource = fs22.existsSync(path39.join(cwd, "CMakeLists.txt"));
|
|
48860
|
+
const hasBuildCache = fs22.existsSync(path39.join(cwd, "CMakeCache.txt")) || fs22.existsSync(path39.join(cwd, "build", "CMakeCache.txt"));
|
|
48346
48861
|
return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
|
|
48347
48862
|
}
|
|
48348
48863
|
function detectSwiftTest(cwd) {
|
|
48349
|
-
return fs22.existsSync(
|
|
48864
|
+
return fs22.existsSync(path39.join(cwd, "Package.swift")) && isCommandAvailable("swift");
|
|
48350
48865
|
}
|
|
48351
48866
|
function detectDartTest(cwd) {
|
|
48352
|
-
return fs22.existsSync(
|
|
48867
|
+
return fs22.existsSync(path39.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
48353
48868
|
}
|
|
48354
48869
|
function detectRSpec(cwd) {
|
|
48355
|
-
const hasRSpecFile = fs22.existsSync(
|
|
48356
|
-
const hasGemfile = fs22.existsSync(
|
|
48357
|
-
const hasSpecDir = fs22.existsSync(
|
|
48870
|
+
const hasRSpecFile = fs22.existsSync(path39.join(cwd, ".rspec"));
|
|
48871
|
+
const hasGemfile = fs22.existsSync(path39.join(cwd, "Gemfile"));
|
|
48872
|
+
const hasSpecDir = fs22.existsSync(path39.join(cwd, "spec"));
|
|
48358
48873
|
const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
|
|
48359
48874
|
return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
|
|
48360
48875
|
}
|
|
48361
48876
|
function detectMinitest(cwd) {
|
|
48362
|
-
return fs22.existsSync(
|
|
48877
|
+
return fs22.existsSync(path39.join(cwd, "test")) && (fs22.existsSync(path39.join(cwd, "Gemfile")) || fs22.existsSync(path39.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
|
|
48363
48878
|
}
|
|
48364
48879
|
async function detectTestFrameworkViaDispatch(cwd) {
|
|
48365
48880
|
try {
|
|
@@ -48421,7 +48936,7 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
|
|
|
48421
48936
|
async function detectTestFramework(cwd) {
|
|
48422
48937
|
const baseDir = cwd;
|
|
48423
48938
|
try {
|
|
48424
|
-
const packageJsonPath =
|
|
48939
|
+
const packageJsonPath = path39.join(baseDir, "package.json");
|
|
48425
48940
|
if (fs22.existsSync(packageJsonPath)) {
|
|
48426
48941
|
const content = fs22.readFileSync(packageJsonPath, "utf-8");
|
|
48427
48942
|
const pkg = JSON.parse(content);
|
|
@@ -48442,16 +48957,16 @@ async function detectTestFramework(cwd) {
|
|
|
48442
48957
|
return "jest";
|
|
48443
48958
|
if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
|
|
48444
48959
|
return "mocha";
|
|
48445
|
-
if (fs22.existsSync(
|
|
48960
|
+
if (fs22.existsSync(path39.join(baseDir, "bun.lockb")) || fs22.existsSync(path39.join(baseDir, "bun.lock"))) {
|
|
48446
48961
|
if (scripts.test?.includes("bun"))
|
|
48447
48962
|
return "bun";
|
|
48448
48963
|
}
|
|
48449
48964
|
}
|
|
48450
48965
|
} catch {}
|
|
48451
48966
|
try {
|
|
48452
|
-
const pyprojectTomlPath =
|
|
48453
|
-
const setupCfgPath =
|
|
48454
|
-
const requirementsTxtPath =
|
|
48967
|
+
const pyprojectTomlPath = path39.join(baseDir, "pyproject.toml");
|
|
48968
|
+
const setupCfgPath = path39.join(baseDir, "setup.cfg");
|
|
48969
|
+
const requirementsTxtPath = path39.join(baseDir, "requirements.txt");
|
|
48455
48970
|
if (fs22.existsSync(pyprojectTomlPath)) {
|
|
48456
48971
|
const content = fs22.readFileSync(pyprojectTomlPath, "utf-8");
|
|
48457
48972
|
if (content.includes("[tool.pytest"))
|
|
@@ -48471,7 +48986,7 @@ async function detectTestFramework(cwd) {
|
|
|
48471
48986
|
}
|
|
48472
48987
|
} catch {}
|
|
48473
48988
|
try {
|
|
48474
|
-
const cargoTomlPath =
|
|
48989
|
+
const cargoTomlPath = path39.join(baseDir, "Cargo.toml");
|
|
48475
48990
|
if (fs22.existsSync(cargoTomlPath)) {
|
|
48476
48991
|
const content = fs22.readFileSync(cargoTomlPath, "utf-8");
|
|
48477
48992
|
if (content.includes("[dev-dependencies]")) {
|
|
@@ -48482,9 +48997,9 @@ async function detectTestFramework(cwd) {
|
|
|
48482
48997
|
}
|
|
48483
48998
|
} catch {}
|
|
48484
48999
|
try {
|
|
48485
|
-
const pesterConfigPath =
|
|
48486
|
-
const pesterConfigJsonPath =
|
|
48487
|
-
const pesterPs1Path =
|
|
49000
|
+
const pesterConfigPath = path39.join(baseDir, "pester.config.ps1");
|
|
49001
|
+
const pesterConfigJsonPath = path39.join(baseDir, "pester.config.ps1.json");
|
|
49002
|
+
const pesterPs1Path = path39.join(baseDir, "tests.ps1");
|
|
48488
49003
|
if (fs22.existsSync(pesterConfigPath) || fs22.existsSync(pesterConfigJsonPath) || fs22.existsSync(pesterPs1Path)) {
|
|
48489
49004
|
return "pester";
|
|
48490
49005
|
}
|
|
@@ -48513,12 +49028,12 @@ function isTestDirectoryPath(normalizedPath) {
|
|
|
48513
49028
|
return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
|
|
48514
49029
|
}
|
|
48515
49030
|
function resolveWorkspacePath(file3, workingDir) {
|
|
48516
|
-
return
|
|
49031
|
+
return path39.isAbsolute(file3) ? path39.resolve(file3) : path39.resolve(workingDir, file3);
|
|
48517
49032
|
}
|
|
48518
49033
|
function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
|
|
48519
49034
|
if (!preferRelative)
|
|
48520
49035
|
return absolutePath;
|
|
48521
|
-
return
|
|
49036
|
+
return path39.relative(workingDir, absolutePath);
|
|
48522
49037
|
}
|
|
48523
49038
|
function dedupePush(target, value) {
|
|
48524
49039
|
if (!target.includes(value)) {
|
|
@@ -48555,18 +49070,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
|
|
|
48555
49070
|
}
|
|
48556
49071
|
}
|
|
48557
49072
|
function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
|
|
48558
|
-
const relativeDir =
|
|
49073
|
+
const relativeDir = path39.dirname(relativePath);
|
|
48559
49074
|
const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
|
|
48560
49075
|
const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
|
|
48561
|
-
const rootDir =
|
|
48562
|
-
return nestedRelativeDir ? [rootDir,
|
|
49076
|
+
const rootDir = path39.join(workingDir, dirName);
|
|
49077
|
+
return nestedRelativeDir ? [rootDir, path39.join(rootDir, nestedRelativeDir)] : [rootDir];
|
|
48563
49078
|
});
|
|
48564
49079
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
48565
49080
|
if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
|
|
48566
|
-
directories.push(
|
|
49081
|
+
directories.push(path39.join(workingDir, "src/test/java", path39.dirname(normalizedRelativePath.slice("src/main/java/".length))));
|
|
48567
49082
|
}
|
|
48568
49083
|
if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
|
|
48569
|
-
directories.push(
|
|
49084
|
+
directories.push(path39.join(workingDir, "src/test/kotlin", path39.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
|
|
48570
49085
|
}
|
|
48571
49086
|
return [...new Set(directories)];
|
|
48572
49087
|
}
|
|
@@ -48594,23 +49109,23 @@ function isLanguageSpecificTestFile(basename6) {
|
|
|
48594
49109
|
}
|
|
48595
49110
|
function isConventionTestFilePath(filePath) {
|
|
48596
49111
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
48597
|
-
const basename6 =
|
|
49112
|
+
const basename6 = path39.basename(filePath);
|
|
48598
49113
|
return hasCompoundTestExtension(basename6) || basename6.includes(".spec.") || basename6.includes(".test.") || isLanguageSpecificTestFile(basename6) || isTestDirectoryPath(normalizedPath);
|
|
48599
49114
|
}
|
|
48600
49115
|
function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
48601
49116
|
const testFiles = [];
|
|
48602
49117
|
for (const file3 of sourceFiles) {
|
|
48603
49118
|
const absoluteFile = resolveWorkspacePath(file3, workingDir);
|
|
48604
|
-
const relativeFile =
|
|
48605
|
-
const basename6 =
|
|
48606
|
-
const dirname17 =
|
|
48607
|
-
const preferRelativeOutput = !
|
|
49119
|
+
const relativeFile = path39.relative(workingDir, absoluteFile);
|
|
49120
|
+
const basename6 = path39.basename(absoluteFile);
|
|
49121
|
+
const dirname17 = path39.dirname(absoluteFile);
|
|
49122
|
+
const preferRelativeOutput = !path39.isAbsolute(file3);
|
|
48608
49123
|
if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file3)) {
|
|
48609
49124
|
dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
|
|
48610
49125
|
continue;
|
|
48611
49126
|
}
|
|
48612
49127
|
const nameWithoutExt = basename6.replace(/\.[^.]+$/, "");
|
|
48613
|
-
const ext =
|
|
49128
|
+
const ext = path39.extname(basename6);
|
|
48614
49129
|
const genericTestNames = [
|
|
48615
49130
|
`${nameWithoutExt}.spec${ext}`,
|
|
48616
49131
|
`${nameWithoutExt}.test${ext}`
|
|
@@ -48619,7 +49134,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
48619
49134
|
const colocatedCandidates = [
|
|
48620
49135
|
...genericTestNames,
|
|
48621
49136
|
...languageSpecificTestNames
|
|
48622
|
-
].map((candidateName) =>
|
|
49137
|
+
].map((candidateName) => path39.join(dirname17, candidateName));
|
|
48623
49138
|
const testDirectoryNames = [
|
|
48624
49139
|
basename6,
|
|
48625
49140
|
...genericTestNames,
|
|
@@ -48628,8 +49143,8 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
48628
49143
|
const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
|
|
48629
49144
|
const possibleTestFiles = [
|
|
48630
49145
|
...colocatedCandidates,
|
|
48631
|
-
...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) =>
|
|
48632
|
-
...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) =>
|
|
49146
|
+
...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path39.join(dirname17, dirName, candidateName))),
|
|
49147
|
+
...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path39.join(candidateDir, candidateName)))
|
|
48633
49148
|
];
|
|
48634
49149
|
for (const testFile of possibleTestFiles) {
|
|
48635
49150
|
if (fs22.existsSync(testFile)) {
|
|
@@ -48650,7 +49165,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
48650
49165
|
try {
|
|
48651
49166
|
const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
|
|
48652
49167
|
const content = fs22.readFileSync(absoluteTestFile, "utf-8");
|
|
48653
|
-
const testDir =
|
|
49168
|
+
const testDir = path39.dirname(absoluteTestFile);
|
|
48654
49169
|
const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
|
|
48655
49170
|
let match;
|
|
48656
49171
|
match = importRegex.exec(content);
|
|
@@ -48658,8 +49173,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
48658
49173
|
const importPath = match[1];
|
|
48659
49174
|
let resolvedImport;
|
|
48660
49175
|
if (importPath.startsWith(".")) {
|
|
48661
|
-
resolvedImport =
|
|
48662
|
-
const existingExt =
|
|
49176
|
+
resolvedImport = path39.resolve(testDir, importPath);
|
|
49177
|
+
const existingExt = path39.extname(resolvedImport);
|
|
48663
49178
|
if (!existingExt) {
|
|
48664
49179
|
for (const extToTry of [
|
|
48665
49180
|
".ts",
|
|
@@ -48679,12 +49194,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
48679
49194
|
} else {
|
|
48680
49195
|
continue;
|
|
48681
49196
|
}
|
|
48682
|
-
const importBasename =
|
|
48683
|
-
const importDir =
|
|
49197
|
+
const importBasename = path39.basename(resolvedImport, path39.extname(resolvedImport));
|
|
49198
|
+
const importDir = path39.dirname(resolvedImport);
|
|
48684
49199
|
for (const sourceFile of absoluteSourceFiles) {
|
|
48685
|
-
const sourceDir =
|
|
48686
|
-
const sourceBasename =
|
|
48687
|
-
const isRelatedDir = importDir === sourceDir || importDir ===
|
|
49200
|
+
const sourceDir = path39.dirname(sourceFile);
|
|
49201
|
+
const sourceBasename = path39.basename(sourceFile, path39.extname(sourceFile));
|
|
49202
|
+
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
49203
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
48689
49204
|
dedupePush(testFiles, testFile);
|
|
48690
49205
|
break;
|
|
@@ -48697,8 +49212,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
48697
49212
|
while (match !== null) {
|
|
48698
49213
|
const importPath = match[1];
|
|
48699
49214
|
if (importPath.startsWith(".")) {
|
|
48700
|
-
let resolvedImport =
|
|
48701
|
-
const existingExt =
|
|
49215
|
+
let resolvedImport = path39.resolve(testDir, importPath);
|
|
49216
|
+
const existingExt = path39.extname(resolvedImport);
|
|
48702
49217
|
if (!existingExt) {
|
|
48703
49218
|
for (const extToTry of [
|
|
48704
49219
|
".ts",
|
|
@@ -48715,12 +49230,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
48715
49230
|
}
|
|
48716
49231
|
}
|
|
48717
49232
|
}
|
|
48718
|
-
const importDir =
|
|
48719
|
-
const importBasename =
|
|
49233
|
+
const importDir = path39.dirname(resolvedImport);
|
|
49234
|
+
const importBasename = path39.basename(resolvedImport, path39.extname(resolvedImport));
|
|
48720
49235
|
for (const sourceFile of absoluteSourceFiles) {
|
|
48721
|
-
const sourceDir =
|
|
48722
|
-
const sourceBasename =
|
|
48723
|
-
const isRelatedDir = importDir === sourceDir || importDir ===
|
|
49236
|
+
const sourceDir = path39.dirname(sourceFile);
|
|
49237
|
+
const sourceBasename = path39.basename(sourceFile, path39.extname(sourceFile));
|
|
49238
|
+
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
49239
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
48725
49240
|
dedupePush(testFiles, testFile);
|
|
48726
49241
|
break;
|
|
@@ -48830,8 +49345,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
48830
49345
|
return ["mvn", "test"];
|
|
48831
49346
|
case "gradle": {
|
|
48832
49347
|
const isWindows = process.platform === "win32";
|
|
48833
|
-
const hasGradlewBat = fs22.existsSync(
|
|
48834
|
-
const hasGradlew = fs22.existsSync(
|
|
49348
|
+
const hasGradlewBat = fs22.existsSync(path39.join(baseDir, "gradlew.bat"));
|
|
49349
|
+
const hasGradlew = fs22.existsSync(path39.join(baseDir, "gradlew"));
|
|
48835
49350
|
if (hasGradlewBat && isWindows)
|
|
48836
49351
|
return ["gradlew.bat", "test"];
|
|
48837
49352
|
if (hasGradlew)
|
|
@@ -48848,7 +49363,7 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
48848
49363
|
"cmake-build-release",
|
|
48849
49364
|
"out"
|
|
48850
49365
|
];
|
|
48851
|
-
const actualBuildDir = buildDirCandidates.find((d) => fs22.existsSync(
|
|
49366
|
+
const actualBuildDir = buildDirCandidates.find((d) => fs22.existsSync(path39.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
|
|
48852
49367
|
return ["ctest", "--test-dir", actualBuildDir];
|
|
48853
49368
|
}
|
|
48854
49369
|
case "swift-test":
|
|
@@ -49280,11 +49795,11 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
|
|
|
49280
49795
|
};
|
|
49281
49796
|
}
|
|
49282
49797
|
const startTime = Date.now();
|
|
49283
|
-
const vitestJsonOutputPath = framework === "vitest" ?
|
|
49798
|
+
const vitestJsonOutputPath = framework === "vitest" ? path39.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
|
|
49284
49799
|
try {
|
|
49285
49800
|
if (vitestJsonOutputPath) {
|
|
49286
49801
|
try {
|
|
49287
|
-
fs22.mkdirSync(
|
|
49802
|
+
fs22.mkdirSync(path39.dirname(vitestJsonOutputPath), { recursive: true });
|
|
49288
49803
|
if (fs22.existsSync(vitestJsonOutputPath)) {
|
|
49289
49804
|
fs22.unlinkSync(vitestJsonOutputPath);
|
|
49290
49805
|
}
|
|
@@ -49400,10 +49915,10 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
|
|
|
49400
49915
|
}
|
|
49401
49916
|
function normalizeHistoryTestFile(testFile, workingDir) {
|
|
49402
49917
|
const normalized = testFile.replace(/\\/g, "/");
|
|
49403
|
-
if (!
|
|
49918
|
+
if (!path39.isAbsolute(testFile))
|
|
49404
49919
|
return normalized;
|
|
49405
|
-
const relative9 =
|
|
49406
|
-
if (relative9.startsWith("..") ||
|
|
49920
|
+
const relative9 = path39.relative(workingDir, testFile);
|
|
49921
|
+
if (relative9.startsWith("..") || path39.isAbsolute(relative9)) {
|
|
49407
49922
|
return normalized;
|
|
49408
49923
|
}
|
|
49409
49924
|
return relative9.replace(/\\/g, "/");
|
|
@@ -49741,7 +50256,7 @@ var init_test_runner = __esm(() => {
|
|
|
49741
50256
|
const sourceFiles = args.files.filter((file3) => {
|
|
49742
50257
|
if (directTestFiles.includes(file3))
|
|
49743
50258
|
return false;
|
|
49744
|
-
const ext =
|
|
50259
|
+
const ext = path39.extname(file3).toLowerCase();
|
|
49745
50260
|
return SOURCE_EXTENSIONS.has(ext);
|
|
49746
50261
|
});
|
|
49747
50262
|
const invalidFiles = args.files.filter((file3) => !directTestFiles.includes(file3) && !sourceFiles.includes(file3));
|
|
@@ -49787,7 +50302,7 @@ var init_test_runner = __esm(() => {
|
|
|
49787
50302
|
if (isConventionTestFilePath(f)) {
|
|
49788
50303
|
return false;
|
|
49789
50304
|
}
|
|
49790
|
-
const ext =
|
|
50305
|
+
const ext = path39.extname(f).toLowerCase();
|
|
49791
50306
|
return SOURCE_EXTENSIONS.has(ext);
|
|
49792
50307
|
});
|
|
49793
50308
|
if (sourceFiles.length === 0) {
|
|
@@ -49837,7 +50352,7 @@ var init_test_runner = __esm(() => {
|
|
|
49837
50352
|
if (isConventionTestFilePath(f)) {
|
|
49838
50353
|
return false;
|
|
49839
50354
|
}
|
|
49840
|
-
const ext =
|
|
50355
|
+
const ext = path39.extname(f).toLowerCase();
|
|
49841
50356
|
return SOURCE_EXTENSIONS.has(ext);
|
|
49842
50357
|
});
|
|
49843
50358
|
if (sourceFiles.length === 0) {
|
|
@@ -49889,8 +50404,8 @@ var init_test_runner = __esm(() => {
|
|
|
49889
50404
|
}
|
|
49890
50405
|
if (impactResult.impactedTests.length > 0) {
|
|
49891
50406
|
testFiles = impactResult.impactedTests.map((absPath) => {
|
|
49892
|
-
const relativePath =
|
|
49893
|
-
return
|
|
50407
|
+
const relativePath = path39.relative(workingDir, absPath);
|
|
50408
|
+
return path39.isAbsolute(relativePath) ? absPath : relativePath;
|
|
49894
50409
|
});
|
|
49895
50410
|
} else {
|
|
49896
50411
|
graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
|
|
@@ -49966,7 +50481,7 @@ var init_test_runner = __esm(() => {
|
|
|
49966
50481
|
|
|
49967
50482
|
// src/services/preflight-service.ts
|
|
49968
50483
|
import * as fs23 from "fs";
|
|
49969
|
-
import * as
|
|
50484
|
+
import * as path40 from "path";
|
|
49970
50485
|
function validateDirectoryPath(dir) {
|
|
49971
50486
|
if (!dir || typeof dir !== "string") {
|
|
49972
50487
|
throw new Error("Directory path is required");
|
|
@@ -49974,8 +50489,8 @@ function validateDirectoryPath(dir) {
|
|
|
49974
50489
|
if (dir.includes("..")) {
|
|
49975
50490
|
throw new Error("Directory path must not contain path traversal sequences");
|
|
49976
50491
|
}
|
|
49977
|
-
const normalized =
|
|
49978
|
-
const absolutePath =
|
|
50492
|
+
const normalized = path40.normalize(dir);
|
|
50493
|
+
const absolutePath = path40.isAbsolute(normalized) ? normalized : path40.resolve(normalized);
|
|
49979
50494
|
return absolutePath;
|
|
49980
50495
|
}
|
|
49981
50496
|
function validateTimeout(timeoutMs, defaultValue) {
|
|
@@ -49998,7 +50513,7 @@ function validateTimeout(timeoutMs, defaultValue) {
|
|
|
49998
50513
|
}
|
|
49999
50514
|
function getPackageVersion(dir) {
|
|
50000
50515
|
try {
|
|
50001
|
-
const packagePath =
|
|
50516
|
+
const packagePath = path40.join(dir, "package.json");
|
|
50002
50517
|
if (fs23.existsSync(packagePath)) {
|
|
50003
50518
|
const content = fs23.readFileSync(packagePath, "utf-8");
|
|
50004
50519
|
const pkg = JSON.parse(content);
|
|
@@ -50009,7 +50524,7 @@ function getPackageVersion(dir) {
|
|
|
50009
50524
|
}
|
|
50010
50525
|
function getChangelogVersion(dir) {
|
|
50011
50526
|
try {
|
|
50012
|
-
const changelogPath =
|
|
50527
|
+
const changelogPath = path40.join(dir, "CHANGELOG.md");
|
|
50013
50528
|
if (fs23.existsSync(changelogPath)) {
|
|
50014
50529
|
const content = fs23.readFileSync(changelogPath, "utf-8");
|
|
50015
50530
|
const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
|
|
@@ -50023,7 +50538,7 @@ function getChangelogVersion(dir) {
|
|
|
50023
50538
|
function getVersionFileVersion(dir) {
|
|
50024
50539
|
const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
|
|
50025
50540
|
for (const file3 of possibleFiles) {
|
|
50026
|
-
const filePath =
|
|
50541
|
+
const filePath = path40.join(dir, file3);
|
|
50027
50542
|
if (fs23.existsSync(filePath)) {
|
|
50028
50543
|
try {
|
|
50029
50544
|
const content = fs23.readFileSync(filePath, "utf-8").trim();
|
|
@@ -50039,9 +50554,9 @@ function getVersionFileVersion(dir) {
|
|
|
50039
50554
|
async function runVersionCheck(dir, _timeoutMs) {
|
|
50040
50555
|
const startTime = Date.now();
|
|
50041
50556
|
try {
|
|
50042
|
-
const packageVersion =
|
|
50043
|
-
const changelogVersion =
|
|
50044
|
-
const versionFileVersion =
|
|
50557
|
+
const packageVersion = _internals27.getPackageVersion(dir);
|
|
50558
|
+
const changelogVersion = _internals27.getChangelogVersion(dir);
|
|
50559
|
+
const versionFileVersion = _internals27.getVersionFileVersion(dir);
|
|
50045
50560
|
const versions3 = [];
|
|
50046
50561
|
if (packageVersion)
|
|
50047
50562
|
versions3.push(`package.json: ${packageVersion}`);
|
|
@@ -50313,7 +50828,22 @@ async function runEvidenceCheck(dir) {
|
|
|
50313
50828
|
};
|
|
50314
50829
|
}
|
|
50315
50830
|
const evidenceTaskIds = new Set(await listEvidenceTaskIds(dir));
|
|
50316
|
-
const missingEvidence =
|
|
50831
|
+
const missingEvidence = [];
|
|
50832
|
+
for (const id of completedTaskIds) {
|
|
50833
|
+
const gateStatus = await getDurableGateEvidenceStatusForTask(dir, id);
|
|
50834
|
+
if (gateStatus.isComplete) {
|
|
50835
|
+
continue;
|
|
50836
|
+
}
|
|
50837
|
+
if (gateStatus.evidenceExists && gateStatus.missingGates.length > 0) {
|
|
50838
|
+
missingEvidence.push(id);
|
|
50839
|
+
continue;
|
|
50840
|
+
}
|
|
50841
|
+
if (evidenceTaskIds.has(id)) {
|
|
50842
|
+
continue;
|
|
50843
|
+
}
|
|
50844
|
+
missingEvidence.push(id);
|
|
50845
|
+
}
|
|
50846
|
+
const completedWithEvidence = completedTaskIds.length - missingEvidence.length;
|
|
50317
50847
|
if (missingEvidence.length > 0) {
|
|
50318
50848
|
return {
|
|
50319
50849
|
type: "evidence",
|
|
@@ -50321,7 +50851,7 @@ async function runEvidenceCheck(dir) {
|
|
|
50321
50851
|
message: `${missingEvidence.length} completed task(s) missing evidence`,
|
|
50322
50852
|
details: {
|
|
50323
50853
|
totalCompleted: completedTaskIds.length,
|
|
50324
|
-
totalWithEvidence:
|
|
50854
|
+
totalWithEvidence: completedWithEvidence,
|
|
50325
50855
|
missingTasks: missingEvidence.slice(0, 10),
|
|
50326
50856
|
missingCount: missingEvidence.length
|
|
50327
50857
|
},
|
|
@@ -50334,7 +50864,7 @@ async function runEvidenceCheck(dir) {
|
|
|
50334
50864
|
message: `All ${completedTaskIds.length} completed tasks have evidence`,
|
|
50335
50865
|
details: {
|
|
50336
50866
|
totalCompleted: completedTaskIds.length,
|
|
50337
|
-
totalWithEvidence:
|
|
50867
|
+
totalWithEvidence: completedWithEvidence
|
|
50338
50868
|
},
|
|
50339
50869
|
durationMs: Date.now() - startTime
|
|
50340
50870
|
};
|
|
@@ -50350,7 +50880,7 @@ async function runEvidenceCheck(dir) {
|
|
|
50350
50880
|
async function runRequirementCoverageCheck(dir, currentPhase) {
|
|
50351
50881
|
const startTime = Date.now();
|
|
50352
50882
|
try {
|
|
50353
|
-
const specPath =
|
|
50883
|
+
const specPath = path40.join(dir, ".swarm", "spec.md");
|
|
50354
50884
|
if (!fs23.existsSync(specPath)) {
|
|
50355
50885
|
return {
|
|
50356
50886
|
type: "req_coverage",
|
|
@@ -50391,7 +50921,7 @@ async function runPreflight(dir, phase, config3) {
|
|
|
50391
50921
|
const reportId = `preflight-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
50392
50922
|
let validatedDir;
|
|
50393
50923
|
try {
|
|
50394
|
-
validatedDir =
|
|
50924
|
+
validatedDir = _internals27.validateDirectoryPath(dir);
|
|
50395
50925
|
} catch (error93) {
|
|
50396
50926
|
return {
|
|
50397
50927
|
id: reportId,
|
|
@@ -50411,7 +50941,7 @@ async function runPreflight(dir, phase, config3) {
|
|
|
50411
50941
|
}
|
|
50412
50942
|
let validatedTimeout;
|
|
50413
50943
|
try {
|
|
50414
|
-
validatedTimeout =
|
|
50944
|
+
validatedTimeout = _internals27.validateTimeout(config3?.checkTimeoutMs, DEFAULT_CONFIG.checkTimeoutMs);
|
|
50415
50945
|
} catch (error93) {
|
|
50416
50946
|
return {
|
|
50417
50947
|
id: reportId,
|
|
@@ -50452,12 +50982,12 @@ async function runPreflight(dir, phase, config3) {
|
|
|
50452
50982
|
});
|
|
50453
50983
|
const checks5 = [];
|
|
50454
50984
|
log("[Preflight] Running lint check...");
|
|
50455
|
-
const lintResult = await
|
|
50985
|
+
const lintResult = await _internals27.runLintCheck(validatedDir, cfg.linter, cfg.checkTimeoutMs);
|
|
50456
50986
|
checks5.push(lintResult);
|
|
50457
50987
|
log(`[Preflight] Lint check: ${lintResult.status} ${lintResult.message}`);
|
|
50458
50988
|
if (!cfg.skipTests) {
|
|
50459
50989
|
log("[Preflight] Running tests check...");
|
|
50460
|
-
const testsResult = await
|
|
50990
|
+
const testsResult = await _internals27.runTestsCheck(validatedDir, cfg.testScope, cfg.checkTimeoutMs);
|
|
50461
50991
|
checks5.push(testsResult);
|
|
50462
50992
|
log(`[Preflight] Tests check: ${testsResult.status} ${testsResult.message}`);
|
|
50463
50993
|
} else {
|
|
@@ -50469,7 +50999,7 @@ async function runPreflight(dir, phase, config3) {
|
|
|
50469
50999
|
}
|
|
50470
51000
|
if (!cfg.skipSecrets) {
|
|
50471
51001
|
log("[Preflight] Running secrets check...");
|
|
50472
|
-
const secretsResult = await
|
|
51002
|
+
const secretsResult = await _internals27.runSecretsCheck(validatedDir, cfg.checkTimeoutMs);
|
|
50473
51003
|
checks5.push(secretsResult);
|
|
50474
51004
|
log(`[Preflight] Secrets check: ${secretsResult.status} ${secretsResult.message}`);
|
|
50475
51005
|
} else {
|
|
@@ -50481,7 +51011,7 @@ async function runPreflight(dir, phase, config3) {
|
|
|
50481
51011
|
}
|
|
50482
51012
|
if (!cfg.skipEvidence) {
|
|
50483
51013
|
log("[Preflight] Running evidence check...");
|
|
50484
|
-
const evidenceResult = await
|
|
51014
|
+
const evidenceResult = await _internals27.runEvidenceCheck(validatedDir);
|
|
50485
51015
|
checks5.push(evidenceResult);
|
|
50486
51016
|
log(`[Preflight] Evidence check: ${evidenceResult.status} ${evidenceResult.message}`);
|
|
50487
51017
|
} else {
|
|
@@ -50492,12 +51022,12 @@ async function runPreflight(dir, phase, config3) {
|
|
|
50492
51022
|
});
|
|
50493
51023
|
}
|
|
50494
51024
|
log("[Preflight] Running requirement coverage check...");
|
|
50495
|
-
const reqCoverageResult = await
|
|
51025
|
+
const reqCoverageResult = await _internals27.runRequirementCoverageCheck(validatedDir, phase);
|
|
50496
51026
|
checks5.push(reqCoverageResult);
|
|
50497
51027
|
log(`[Preflight] Requirement coverage check: ${reqCoverageResult.status} ${reqCoverageResult.message}`);
|
|
50498
51028
|
if (!cfg.skipVersion) {
|
|
50499
51029
|
log("[Preflight] Running version check...");
|
|
50500
|
-
const versionResult = await
|
|
51030
|
+
const versionResult = await _internals27.runVersionCheck(validatedDir, cfg.checkTimeoutMs);
|
|
50501
51031
|
checks5.push(versionResult);
|
|
50502
51032
|
log(`[Preflight] Version check: ${versionResult.status} ${versionResult.message}`);
|
|
50503
51033
|
} else {
|
|
@@ -50560,11 +51090,12 @@ function formatPreflightMarkdown(report) {
|
|
|
50560
51090
|
async function handlePreflightCommand(directory, _args) {
|
|
50561
51091
|
const plan = await loadPlan(directory);
|
|
50562
51092
|
const phase = plan?.current_phase ?? 1;
|
|
50563
|
-
const report = await
|
|
50564
|
-
return
|
|
51093
|
+
const report = await _internals27.runPreflight(directory, phase);
|
|
51094
|
+
return _internals27.formatPreflightMarkdown(report);
|
|
50565
51095
|
}
|
|
50566
|
-
var MIN_CHECK_TIMEOUT_MS = 5000, MAX_CHECK_TIMEOUT_MS = 300000, DEFAULT_CONFIG,
|
|
51096
|
+
var MIN_CHECK_TIMEOUT_MS = 5000, MAX_CHECK_TIMEOUT_MS = 300000, DEFAULT_CONFIG, _internals27;
|
|
50567
51097
|
var init_preflight_service = __esm(() => {
|
|
51098
|
+
init_gate_bridge();
|
|
50568
51099
|
init_manager2();
|
|
50569
51100
|
init_manager();
|
|
50570
51101
|
init_lint();
|
|
@@ -50580,7 +51111,7 @@ var init_preflight_service = __esm(() => {
|
|
|
50580
51111
|
testScope: "convention",
|
|
50581
51112
|
linter: "biome"
|
|
50582
51113
|
};
|
|
50583
|
-
|
|
51114
|
+
_internals27 = {
|
|
50584
51115
|
runPreflight,
|
|
50585
51116
|
formatPreflightMarkdown,
|
|
50586
51117
|
handlePreflightCommand,
|
|
@@ -51467,7 +51998,7 @@ var init_manager3 = __esm(() => {
|
|
|
51467
51998
|
|
|
51468
51999
|
// src/commands/reset.ts
|
|
51469
52000
|
import * as fs24 from "fs";
|
|
51470
|
-
import * as
|
|
52001
|
+
import * as path41 from "path";
|
|
51471
52002
|
async function handleResetCommand(directory, args) {
|
|
51472
52003
|
const hasConfirm = args.includes("--confirm");
|
|
51473
52004
|
if (!hasConfirm) {
|
|
@@ -51507,7 +52038,7 @@ async function handleResetCommand(directory, args) {
|
|
|
51507
52038
|
}
|
|
51508
52039
|
for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
|
|
51509
52040
|
try {
|
|
51510
|
-
const rootPath =
|
|
52041
|
+
const rootPath = path41.join(directory, filename);
|
|
51511
52042
|
if (fs24.existsSync(rootPath)) {
|
|
51512
52043
|
fs24.unlinkSync(rootPath);
|
|
51513
52044
|
results.push(`- \u2705 Deleted ${filename} (root)`);
|
|
@@ -51547,7 +52078,7 @@ var init_reset = __esm(() => {
|
|
|
51547
52078
|
|
|
51548
52079
|
// src/commands/reset-session.ts
|
|
51549
52080
|
import * as fs25 from "fs";
|
|
51550
|
-
import * as
|
|
52081
|
+
import * as path42 from "path";
|
|
51551
52082
|
async function handleResetSessionCommand(directory, _args) {
|
|
51552
52083
|
const results = [];
|
|
51553
52084
|
try {
|
|
@@ -51562,13 +52093,13 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
51562
52093
|
results.push("\u274C Failed to delete state.json");
|
|
51563
52094
|
}
|
|
51564
52095
|
try {
|
|
51565
|
-
const sessionDir =
|
|
52096
|
+
const sessionDir = path42.dirname(validateSwarmPath(directory, "session/state.json"));
|
|
51566
52097
|
if (fs25.existsSync(sessionDir)) {
|
|
51567
52098
|
const files = fs25.readdirSync(sessionDir);
|
|
51568
52099
|
const otherFiles = files.filter((f) => f !== "state.json");
|
|
51569
52100
|
let deletedCount = 0;
|
|
51570
52101
|
for (const file3 of otherFiles) {
|
|
51571
|
-
const filePath =
|
|
52102
|
+
const filePath = path42.join(sessionDir, file3);
|
|
51572
52103
|
if (fs25.lstatSync(filePath).isFile()) {
|
|
51573
52104
|
fs25.unlinkSync(filePath);
|
|
51574
52105
|
deletedCount++;
|
|
@@ -51600,7 +52131,7 @@ var init_reset_session = __esm(() => {
|
|
|
51600
52131
|
});
|
|
51601
52132
|
|
|
51602
52133
|
// src/summaries/manager.ts
|
|
51603
|
-
import * as
|
|
52134
|
+
import * as path43 from "path";
|
|
51604
52135
|
function sanitizeSummaryId(id) {
|
|
51605
52136
|
if (!id || id.length === 0) {
|
|
51606
52137
|
throw new Error("Invalid summary ID: empty string");
|
|
@@ -51623,7 +52154,7 @@ function sanitizeSummaryId(id) {
|
|
|
51623
52154
|
}
|
|
51624
52155
|
async function loadFullOutput(directory, id) {
|
|
51625
52156
|
const sanitizedId = sanitizeSummaryId(id);
|
|
51626
|
-
const relativePath =
|
|
52157
|
+
const relativePath = path43.join("summaries", `${sanitizedId}.json`);
|
|
51627
52158
|
validateSwarmPath(directory, relativePath);
|
|
51628
52159
|
const content = await readSwarmFileAsync(directory, relativePath);
|
|
51629
52160
|
if (content === null) {
|
|
@@ -51686,7 +52217,7 @@ var init_retrieve = __esm(() => {
|
|
|
51686
52217
|
|
|
51687
52218
|
// src/commands/rollback.ts
|
|
51688
52219
|
import * as fs26 from "fs";
|
|
51689
|
-
import * as
|
|
52220
|
+
import * as path44 from "path";
|
|
51690
52221
|
async function handleRollbackCommand(directory, args) {
|
|
51691
52222
|
const phaseArg = args[0];
|
|
51692
52223
|
if (!phaseArg) {
|
|
@@ -51751,8 +52282,8 @@ async function handleRollbackCommand(directory, args) {
|
|
|
51751
52282
|
if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
|
|
51752
52283
|
continue;
|
|
51753
52284
|
}
|
|
51754
|
-
const src =
|
|
51755
|
-
const dest =
|
|
52285
|
+
const src = path44.join(checkpointDir, file3);
|
|
52286
|
+
const dest = path44.join(swarmDir, file3);
|
|
51756
52287
|
try {
|
|
51757
52288
|
fs26.cpSync(src, dest, { recursive: true, force: true });
|
|
51758
52289
|
successes.push(file3);
|
|
@@ -51771,12 +52302,12 @@ async function handleRollbackCommand(directory, args) {
|
|
|
51771
52302
|
].join(`
|
|
51772
52303
|
`);
|
|
51773
52304
|
}
|
|
51774
|
-
const existingLedgerPath =
|
|
52305
|
+
const existingLedgerPath = path44.join(swarmDir, "plan-ledger.jsonl");
|
|
51775
52306
|
if (fs26.existsSync(existingLedgerPath)) {
|
|
51776
52307
|
fs26.unlinkSync(existingLedgerPath);
|
|
51777
52308
|
}
|
|
51778
52309
|
try {
|
|
51779
|
-
const planJsonPath =
|
|
52310
|
+
const planJsonPath = path44.join(swarmDir, "plan.json");
|
|
51780
52311
|
if (fs26.existsSync(planJsonPath)) {
|
|
51781
52312
|
const planRaw = fs26.readFileSync(planJsonPath, "utf-8");
|
|
51782
52313
|
const plan = PlanSchema.parse(JSON.parse(planRaw));
|
|
@@ -51837,7 +52368,7 @@ async function handleSimulateCommand(directory, args) {
|
|
|
51837
52368
|
}
|
|
51838
52369
|
let darkMatterPairs;
|
|
51839
52370
|
try {
|
|
51840
|
-
darkMatterPairs = await
|
|
52371
|
+
darkMatterPairs = await _internals11.detectDarkMatter(directory, options);
|
|
51841
52372
|
} catch (err) {
|
|
51842
52373
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
51843
52374
|
return `## Simulate Report
|
|
@@ -51867,9 +52398,9 @@ Ensure this is a git repository with commit history.`;
|
|
|
51867
52398
|
`);
|
|
51868
52399
|
try {
|
|
51869
52400
|
const fs27 = await import("fs/promises");
|
|
51870
|
-
const
|
|
51871
|
-
const reportPath =
|
|
51872
|
-
await fs27.mkdir(
|
|
52401
|
+
const path45 = await import("path");
|
|
52402
|
+
const reportPath = path45.join(directory, ".swarm", "simulate-report.md");
|
|
52403
|
+
await fs27.mkdir(path45.dirname(reportPath), { recursive: true });
|
|
51873
52404
|
await fs27.writeFile(reportPath, report, "utf-8");
|
|
51874
52405
|
} catch (err) {
|
|
51875
52406
|
const writeErr = err instanceof Error ? err.message : String(err);
|
|
@@ -51893,12 +52424,12 @@ async function handleSpecifyCommand(_directory, args) {
|
|
|
51893
52424
|
|
|
51894
52425
|
// src/turbo/lean/state.ts
|
|
51895
52426
|
import * as fs27 from "fs";
|
|
51896
|
-
import * as
|
|
52427
|
+
import * as path45 from "path";
|
|
51897
52428
|
function nowISO2() {
|
|
51898
52429
|
return new Date().toISOString();
|
|
51899
52430
|
}
|
|
51900
52431
|
function ensureSwarmDir2(directory) {
|
|
51901
|
-
const swarmDir =
|
|
52432
|
+
const swarmDir = path45.resolve(directory, ".swarm");
|
|
51902
52433
|
if (!fs27.existsSync(swarmDir)) {
|
|
51903
52434
|
fs27.mkdirSync(swarmDir, { recursive: true });
|
|
51904
52435
|
}
|
|
@@ -51942,7 +52473,7 @@ function markStateUnreadable2(directory, reason) {
|
|
|
51942
52473
|
}
|
|
51943
52474
|
function readPersisted2(directory) {
|
|
51944
52475
|
try {
|
|
51945
|
-
const filePath =
|
|
52476
|
+
const filePath = path45.join(directory, ".swarm", STATE_FILE2);
|
|
51946
52477
|
if (!fs27.existsSync(filePath)) {
|
|
51947
52478
|
const seed = emptyPersisted2();
|
|
51948
52479
|
try {
|
|
@@ -51978,7 +52509,7 @@ function writePersisted2(directory, persisted) {
|
|
|
51978
52509
|
let payload;
|
|
51979
52510
|
try {
|
|
51980
52511
|
ensureSwarmDir2(directory);
|
|
51981
|
-
filePath =
|
|
52512
|
+
filePath = path45.join(directory, ".swarm", STATE_FILE2);
|
|
51982
52513
|
tmpPath = `${filePath}.tmp.${Date.now()}`;
|
|
51983
52514
|
persisted.updatedAt = nowISO2();
|
|
51984
52515
|
payload = `${JSON.stringify(persisted, null, 2)}
|
|
@@ -52105,10 +52636,10 @@ var init_context_budget_service = __esm(() => {
|
|
|
52105
52636
|
|
|
52106
52637
|
// src/services/status-service.ts
|
|
52107
52638
|
import * as fsSync2 from "fs";
|
|
52108
|
-
import * as
|
|
52639
|
+
import * as path46 from "path";
|
|
52109
52640
|
function readSpecStalenessSnapshot(directory) {
|
|
52110
52641
|
try {
|
|
52111
|
-
const p =
|
|
52642
|
+
const p = path46.join(directory, ".swarm", "spec-staleness.json");
|
|
52112
52643
|
if (!fsSync2.existsSync(p))
|
|
52113
52644
|
return { stale: false };
|
|
52114
52645
|
const raw = fsSync2.readFileSync(p, "utf-8");
|
|
@@ -52202,7 +52733,7 @@ async function getStatusData(directory, agents) {
|
|
|
52202
52733
|
}
|
|
52203
52734
|
function enrichWithLeanTurbo(status, directory) {
|
|
52204
52735
|
const turboMode = hasActiveTurboMode();
|
|
52205
|
-
const leanActive =
|
|
52736
|
+
const leanActive = _internals28.hasActiveLeanTurbo();
|
|
52206
52737
|
let turboStrategy = "off";
|
|
52207
52738
|
if (leanActive) {
|
|
52208
52739
|
turboStrategy = "lean";
|
|
@@ -52221,7 +52752,7 @@ function enrichWithLeanTurbo(status, directory) {
|
|
|
52221
52752
|
}
|
|
52222
52753
|
}
|
|
52223
52754
|
if (leanSessionID) {
|
|
52224
|
-
const runState =
|
|
52755
|
+
const runState = _internals28.loadLeanTurboRunState(directory, leanSessionID);
|
|
52225
52756
|
if (runState) {
|
|
52226
52757
|
status.leanTurboPhase = runState.phase;
|
|
52227
52758
|
status.leanMaxParallelCoders = runState.maxParallelCoders;
|
|
@@ -52253,7 +52784,7 @@ function enrichWithLeanTurbo(status, directory) {
|
|
|
52253
52784
|
}
|
|
52254
52785
|
}
|
|
52255
52786
|
}
|
|
52256
|
-
status.fullAutoActive =
|
|
52787
|
+
status.fullAutoActive = _internals28.hasActiveFullAuto();
|
|
52257
52788
|
return status;
|
|
52258
52789
|
}
|
|
52259
52790
|
function formatStatusMarkdown(status) {
|
|
@@ -52335,7 +52866,7 @@ async function handleStatusCommand(directory, agents) {
|
|
|
52335
52866
|
}
|
|
52336
52867
|
return formatStatusMarkdown(statusData);
|
|
52337
52868
|
}
|
|
52338
|
-
var
|
|
52869
|
+
var _internals28;
|
|
52339
52870
|
var init_status_service = __esm(() => {
|
|
52340
52871
|
init_extractors();
|
|
52341
52872
|
init_utils2();
|
|
@@ -52344,7 +52875,7 @@ var init_status_service = __esm(() => {
|
|
|
52344
52875
|
init_state3();
|
|
52345
52876
|
init_compaction_service();
|
|
52346
52877
|
init_context_budget_service();
|
|
52347
|
-
|
|
52878
|
+
_internals28 = {
|
|
52348
52879
|
loadLeanTurboRunState,
|
|
52349
52880
|
hasActiveLeanTurbo,
|
|
52350
52881
|
hasActiveFullAuto
|
|
@@ -52435,7 +52966,7 @@ async function handleTurboCommand(directory, args, sessionID) {
|
|
|
52435
52966
|
if (arg0 === "on") {
|
|
52436
52967
|
let strategy = "standard";
|
|
52437
52968
|
try {
|
|
52438
|
-
const { config: config3 } =
|
|
52969
|
+
const { config: config3 } = _internals29.loadPluginConfigWithMeta(directory);
|
|
52439
52970
|
if (config3.turbo?.strategy === "lean") {
|
|
52440
52971
|
strategy = "lean";
|
|
52441
52972
|
}
|
|
@@ -52490,7 +53021,7 @@ function enableLeanTurbo(session, directory, sessionID) {
|
|
|
52490
53021
|
let maxParallelCoders = 4;
|
|
52491
53022
|
let conflictPolicy = "serialize";
|
|
52492
53023
|
try {
|
|
52493
|
-
const { config: config3 } =
|
|
53024
|
+
const { config: config3 } = _internals29.loadPluginConfigWithMeta(directory);
|
|
52494
53025
|
const leanConfig = config3.turbo?.lean;
|
|
52495
53026
|
if (leanConfig) {
|
|
52496
53027
|
maxParallelCoders = leanConfig.max_parallel_coders ?? 4;
|
|
@@ -52560,13 +53091,13 @@ function buildStatusMessage(session, directory, sessionID) {
|
|
|
52560
53091
|
].join(`
|
|
52561
53092
|
`);
|
|
52562
53093
|
}
|
|
52563
|
-
var
|
|
53094
|
+
var _internals29;
|
|
52564
53095
|
var init_turbo = __esm(() => {
|
|
52565
53096
|
init_config();
|
|
52566
53097
|
init_state();
|
|
52567
53098
|
init_state3();
|
|
52568
53099
|
init_logger();
|
|
52569
|
-
|
|
53100
|
+
_internals29 = {
|
|
52570
53101
|
loadPluginConfigWithMeta
|
|
52571
53102
|
};
|
|
52572
53103
|
});
|
|
@@ -52634,7 +53165,7 @@ var init_write_retro2 = __esm(() => {
|
|
|
52634
53165
|
|
|
52635
53166
|
// src/commands/command-dispatch.ts
|
|
52636
53167
|
import fs28 from "fs";
|
|
52637
|
-
import
|
|
53168
|
+
import path47 from "path";
|
|
52638
53169
|
function normalizeSwarmCommandInput(command, argumentText) {
|
|
52639
53170
|
if (command !== "swarm" && !command.startsWith("swarm-")) {
|
|
52640
53171
|
return { isSwarmCommand: false, tokens: [] };
|
|
@@ -52659,7 +53190,7 @@ function formatCommandNotFound(tokens) {
|
|
|
52659
53190
|
const attemptedCommand = tokens[0] || "";
|
|
52660
53191
|
const MAX_DISPLAY = 100;
|
|
52661
53192
|
const displayCommand = attemptedCommand.length > MAX_DISPLAY ? `${attemptedCommand.slice(0, MAX_DISPLAY)}...` : attemptedCommand;
|
|
52662
|
-
const similar =
|
|
53193
|
+
const similar = _internals30.findSimilarCommands(attemptedCommand);
|
|
52663
53194
|
const header = `Command \`/swarm ${displayCommand}\` not found.`;
|
|
52664
53195
|
const suggestions = similar.length > 0 ? `Did you mean:
|
|
52665
53196
|
${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
|
|
@@ -52670,9 +53201,9 @@ ${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
|
|
|
52670
53201
|
`);
|
|
52671
53202
|
}
|
|
52672
53203
|
function maybeMarkFirstRun(directory) {
|
|
52673
|
-
const sentinelPath =
|
|
53204
|
+
const sentinelPath = path47.join(directory, ".swarm", ".first-run-complete");
|
|
52674
53205
|
try {
|
|
52675
|
-
const swarmDir =
|
|
53206
|
+
const swarmDir = path47.join(directory, ".swarm");
|
|
52676
53207
|
fs28.mkdirSync(swarmDir, { recursive: true });
|
|
52677
53208
|
fs28.writeFileSync(sentinelPath, `first-run-complete: ${new Date().toISOString()}
|
|
52678
53209
|
`, { flag: "wx" });
|
|
@@ -53108,7 +53639,7 @@ async function buildSwarmCommandPrompt(args) {
|
|
|
53108
53639
|
activeAgentName,
|
|
53109
53640
|
registeredAgents
|
|
53110
53641
|
} = args;
|
|
53111
|
-
const resolved =
|
|
53642
|
+
const resolved = _internals30.resolveCommand(tokens);
|
|
53112
53643
|
if (!resolved) {
|
|
53113
53644
|
if (tokens.length === 0) {
|
|
53114
53645
|
return buildHelpText();
|
|
@@ -53259,7 +53790,7 @@ function findSimilarCommands(query) {
|
|
|
53259
53790
|
}
|
|
53260
53791
|
const scored = VALID_COMMANDS.map((cmd) => {
|
|
53261
53792
|
const cmdLower = cmd.toLowerCase();
|
|
53262
|
-
const fullScore =
|
|
53793
|
+
const fullScore = _internals30.levenshteinDistance(q, cmdLower);
|
|
53263
53794
|
let tokenScore = Infinity;
|
|
53264
53795
|
if (cmd.includes(" ") || cmd.includes("-")) {
|
|
53265
53796
|
const qTokens = q.split(/[\s-]+/);
|
|
@@ -53272,7 +53803,7 @@ function findSimilarCommands(query) {
|
|
|
53272
53803
|
for (const ct of cmdTokens) {
|
|
53273
53804
|
if (ct.length === 0)
|
|
53274
53805
|
continue;
|
|
53275
|
-
const dist =
|
|
53806
|
+
const dist = _internals30.levenshteinDistance(qt, ct);
|
|
53276
53807
|
if (dist < minDist)
|
|
53277
53808
|
minDist = dist;
|
|
53278
53809
|
}
|
|
@@ -53282,7 +53813,7 @@ function findSimilarCommands(query) {
|
|
|
53282
53813
|
}
|
|
53283
53814
|
const dashStrippedQ = q.replace(/-/g, "");
|
|
53284
53815
|
const dashStrippedCmd = cmdLower.replace(/-/g, "");
|
|
53285
|
-
const dashScore =
|
|
53816
|
+
const dashScore = _internals30.levenshteinDistance(dashStrippedQ, dashStrippedCmd);
|
|
53286
53817
|
const score = Math.min(fullScore, tokenScore, dashScore);
|
|
53287
53818
|
return { cmd, score };
|
|
53288
53819
|
});
|
|
@@ -53314,11 +53845,11 @@ async function handleHelpCommand(ctx) {
|
|
|
53314
53845
|
return buildHelpText2();
|
|
53315
53846
|
}
|
|
53316
53847
|
const tokens = targetCommand.split(/\s+/);
|
|
53317
|
-
const resolved =
|
|
53848
|
+
const resolved = _internals30.resolveCommand(tokens);
|
|
53318
53849
|
if (resolved) {
|
|
53319
|
-
return
|
|
53850
|
+
return _internals30.buildDetailedHelp(resolved.key, resolved.entry);
|
|
53320
53851
|
}
|
|
53321
|
-
const similar =
|
|
53852
|
+
const similar = _internals30.findSimilarCommands(targetCommand);
|
|
53322
53853
|
const { buildHelpText: fullHelp } = await Promise.resolve().then(() => (init_commands(), exports_commands));
|
|
53323
53854
|
if (similar.length > 0) {
|
|
53324
53855
|
return `Command '/swarm ${targetCommand}' not found.
|
|
@@ -53354,24 +53885,24 @@ function validateAliases() {
|
|
|
53354
53885
|
}
|
|
53355
53886
|
aliasTargets.get(target).push(name);
|
|
53356
53887
|
const visited = new Set;
|
|
53357
|
-
const
|
|
53888
|
+
const path48 = [];
|
|
53358
53889
|
let current = target;
|
|
53359
53890
|
while (current) {
|
|
53360
53891
|
const currentEntry = COMMAND_REGISTRY[current];
|
|
53361
53892
|
if (!currentEntry)
|
|
53362
53893
|
break;
|
|
53363
53894
|
if (visited.has(current)) {
|
|
53364
|
-
const cycleStart =
|
|
53895
|
+
const cycleStart = path48.indexOf(current);
|
|
53365
53896
|
const fullChain = [
|
|
53366
53897
|
name,
|
|
53367
|
-
...
|
|
53898
|
+
...path48.slice(0, cycleStart > 0 ? cycleStart : path48.length),
|
|
53368
53899
|
current
|
|
53369
53900
|
].join(" \u2192 ");
|
|
53370
53901
|
errors5.push(`Circular alias detected: ${fullChain}`);
|
|
53371
53902
|
break;
|
|
53372
53903
|
}
|
|
53373
53904
|
visited.add(current);
|
|
53374
|
-
|
|
53905
|
+
path48.push(current);
|
|
53375
53906
|
current = currentEntry.aliasOf || "";
|
|
53376
53907
|
}
|
|
53377
53908
|
}
|
|
@@ -53412,7 +53943,7 @@ function resolveCommand(tokens) {
|
|
|
53412
53943
|
}
|
|
53413
53944
|
return null;
|
|
53414
53945
|
}
|
|
53415
|
-
var COMMAND_REGISTRY, VALID_COMMANDS,
|
|
53946
|
+
var COMMAND_REGISTRY, VALID_COMMANDS, _internals30, validation;
|
|
53416
53947
|
var init_registry = __esm(() => {
|
|
53417
53948
|
init_acknowledge_spec_drift();
|
|
53418
53949
|
init_agents();
|
|
@@ -53482,7 +54013,7 @@ var init_registry = __esm(() => {
|
|
|
53482
54013
|
clashesWithNativeCcCommand: "/agents"
|
|
53483
54014
|
},
|
|
53484
54015
|
help: {
|
|
53485
|
-
handler: (ctx) =>
|
|
54016
|
+
handler: (ctx) => _internals30.handleHelpCommand(ctx),
|
|
53486
54017
|
description: "Show help for swarm commands",
|
|
53487
54018
|
category: "core",
|
|
53488
54019
|
args: "[command]",
|
|
@@ -53854,7 +54385,7 @@ Subcommands:
|
|
|
53854
54385
|
}
|
|
53855
54386
|
};
|
|
53856
54387
|
VALID_COMMANDS = Object.keys(COMMAND_REGISTRY);
|
|
53857
|
-
|
|
54388
|
+
_internals30 = {
|
|
53858
54389
|
handleHelpCommand,
|
|
53859
54390
|
validateAliases,
|
|
53860
54391
|
resolveCommand,
|
|
@@ -53862,7 +54393,7 @@ Subcommands:
|
|
|
53862
54393
|
findSimilarCommands,
|
|
53863
54394
|
buildDetailedHelp
|
|
53864
54395
|
};
|
|
53865
|
-
validation =
|
|
54396
|
+
validation = _internals30.validateAliases();
|
|
53866
54397
|
if (!validation.valid) {
|
|
53867
54398
|
throw new Error(`COMMAND_REGISTRY alias validation failed:
|
|
53868
54399
|
${validation.errors.join(`
|
|
@@ -53882,53 +54413,53 @@ init_cache_paths();
|
|
|
53882
54413
|
init_constants();
|
|
53883
54414
|
import * as fs29 from "fs";
|
|
53884
54415
|
import * as os7 from "os";
|
|
53885
|
-
import * as
|
|
54416
|
+
import * as path48 from "path";
|
|
53886
54417
|
var { version: version4 } = package_default;
|
|
53887
54418
|
var CONFIG_DIR = getPluginConfigDir();
|
|
53888
|
-
var OPENCODE_CONFIG_PATH =
|
|
53889
|
-
var PLUGIN_CONFIG_PATH =
|
|
53890
|
-
var PROMPTS_DIR =
|
|
54419
|
+
var OPENCODE_CONFIG_PATH = path48.join(CONFIG_DIR, "opencode.json");
|
|
54420
|
+
var PLUGIN_CONFIG_PATH = path48.join(CONFIG_DIR, "opencode-swarm.json");
|
|
54421
|
+
var PROMPTS_DIR = path48.join(CONFIG_DIR, "opencode-swarm");
|
|
53891
54422
|
var OPENCODE_PLUGIN_CACHE_PATHS = getPluginCachePaths();
|
|
53892
54423
|
var OPENCODE_PLUGIN_LOCK_FILE_PATHS = getPluginLockFilePaths();
|
|
53893
54424
|
function isSafeCachePath(p) {
|
|
53894
|
-
const resolved =
|
|
53895
|
-
const home =
|
|
54425
|
+
const resolved = path48.resolve(p);
|
|
54426
|
+
const home = path48.resolve(os7.homedir());
|
|
53896
54427
|
if (resolved === "/" || resolved === home || resolved.length <= home.length) {
|
|
53897
54428
|
return false;
|
|
53898
54429
|
}
|
|
53899
|
-
const segments = resolved.split(
|
|
54430
|
+
const segments = resolved.split(path48.sep).filter((s) => s.length > 0);
|
|
53900
54431
|
if (segments.length < 4) {
|
|
53901
54432
|
return false;
|
|
53902
54433
|
}
|
|
53903
|
-
const leaf =
|
|
54434
|
+
const leaf = path48.basename(resolved);
|
|
53904
54435
|
if (leaf !== "opencode-swarm@latest" && leaf !== "opencode-swarm") {
|
|
53905
54436
|
return false;
|
|
53906
54437
|
}
|
|
53907
|
-
const parent =
|
|
54438
|
+
const parent = path48.basename(path48.dirname(resolved));
|
|
53908
54439
|
if (parent !== "packages" && parent !== "node_modules") {
|
|
53909
54440
|
return false;
|
|
53910
54441
|
}
|
|
53911
|
-
const grandparent =
|
|
54442
|
+
const grandparent = path48.basename(path48.dirname(path48.dirname(resolved)));
|
|
53912
54443
|
if (grandparent !== "opencode") {
|
|
53913
54444
|
return false;
|
|
53914
54445
|
}
|
|
53915
54446
|
return true;
|
|
53916
54447
|
}
|
|
53917
54448
|
function isSafeLockFilePath(p) {
|
|
53918
|
-
const resolved =
|
|
53919
|
-
const home =
|
|
54449
|
+
const resolved = path48.resolve(p);
|
|
54450
|
+
const home = path48.resolve(os7.homedir());
|
|
53920
54451
|
if (resolved === "/" || resolved === home || resolved.length <= home.length) {
|
|
53921
54452
|
return false;
|
|
53922
54453
|
}
|
|
53923
|
-
const segments = resolved.split(
|
|
54454
|
+
const segments = resolved.split(path48.sep).filter((s) => s.length > 0);
|
|
53924
54455
|
if (segments.length < 4) {
|
|
53925
54456
|
return false;
|
|
53926
54457
|
}
|
|
53927
|
-
const leaf =
|
|
54458
|
+
const leaf = path48.basename(resolved);
|
|
53928
54459
|
if (leaf !== "bun.lock" && leaf !== "bun.lockb" && leaf !== "package-lock.json") {
|
|
53929
54460
|
return false;
|
|
53930
54461
|
}
|
|
53931
|
-
const parent =
|
|
54462
|
+
const parent = path48.basename(path48.dirname(resolved));
|
|
53932
54463
|
if (parent !== "opencode") {
|
|
53933
54464
|
return false;
|
|
53934
54465
|
}
|
|
@@ -53954,8 +54485,8 @@ function saveJson(filepath, data) {
|
|
|
53954
54485
|
}
|
|
53955
54486
|
function writeProjectConfigIfMissing(cwd) {
|
|
53956
54487
|
try {
|
|
53957
|
-
const opencodeDir =
|
|
53958
|
-
const projectConfigPath =
|
|
54488
|
+
const opencodeDir = path48.join(cwd, ".opencode");
|
|
54489
|
+
const projectConfigPath = path48.join(opencodeDir, "opencode-swarm.json");
|
|
53959
54490
|
if (fs29.existsSync(projectConfigPath)) {
|
|
53960
54491
|
return;
|
|
53961
54492
|
}
|
|
@@ -53972,7 +54503,7 @@ async function install() {
|
|
|
53972
54503
|
`);
|
|
53973
54504
|
ensureDir(CONFIG_DIR);
|
|
53974
54505
|
ensureDir(PROMPTS_DIR);
|
|
53975
|
-
const LEGACY_CONFIG_PATH =
|
|
54506
|
+
const LEGACY_CONFIG_PATH = path48.join(CONFIG_DIR, "config.json");
|
|
53976
54507
|
let opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
|
|
53977
54508
|
if (!opencodeConfig) {
|
|
53978
54509
|
const legacyConfig = loadJson(LEGACY_CONFIG_PATH);
|