opencode-swarm 7.32.3 → 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 +1052 -517
- package/dist/config/schema.d.ts +16 -2
- package/dist/evidence/gate-bridge.d.ts +15 -0
- package/dist/index.js +1179 -545
- package/dist/memory/config.d.ts +5 -1
- package/dist/memory/gateway.d.ts +2 -0
- package/dist/memory/index.d.ts +2 -1
- package/dist/memory/provider.d.ts +1 -0
- package/dist/memory/sqlite-provider.d.ts +39 -0
- 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.
|
|
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
|
|
@@ -17326,8 +17601,12 @@ var init_schema = __esm(() => {
|
|
|
17326
17601
|
});
|
|
17327
17602
|
MemoryConfigSchema = exports_external.object({
|
|
17328
17603
|
enabled: exports_external.boolean().default(false),
|
|
17329
|
-
provider: exports_external.
|
|
17604
|
+
provider: exports_external.enum(["local-jsonl", "sqlite"]).default("local-jsonl"),
|
|
17330
17605
|
storageDir: exports_external.string().default(".swarm/memory"),
|
|
17606
|
+
sqlite: exports_external.object({
|
|
17607
|
+
path: exports_external.string().default(".swarm/memory/memory.db"),
|
|
17608
|
+
busyTimeoutMs: exports_external.number().int().min(0).max(60000).default(5000)
|
|
17609
|
+
}).default({ path: ".swarm/memory/memory.db", busyTimeoutMs: 5000 }),
|
|
17331
17610
|
recall: exports_external.object({
|
|
17332
17611
|
defaultMaxItems: exports_external.number().int().min(1).max(20).default(8),
|
|
17333
17612
|
defaultTokenBudget: exports_external.number().int().min(100).max(5000).default(1200),
|
|
@@ -19759,11 +20038,11 @@ async function tryAcquireLock(directory, filePath, agent, taskId) {
|
|
|
19759
20038
|
};
|
|
19760
20039
|
return { acquired: true, lock };
|
|
19761
20040
|
}
|
|
19762
|
-
var import_proper_lockfile, LOCKS_DIR = ".swarm/locks", LOCK_TIMEOUT_MS,
|
|
20041
|
+
var import_proper_lockfile, LOCKS_DIR = ".swarm/locks", LOCK_TIMEOUT_MS, _internals5;
|
|
19763
20042
|
var init_file_locks = __esm(() => {
|
|
19764
20043
|
import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
|
|
19765
20044
|
LOCK_TIMEOUT_MS = 5 * 60 * 1000;
|
|
19766
|
-
|
|
20045
|
+
_internals5 = {
|
|
19767
20046
|
tryAcquireLock,
|
|
19768
20047
|
writeFile: fs3.promises.writeFile
|
|
19769
20048
|
};
|
|
@@ -19863,6 +20142,19 @@ function checkUnsafeChars(taskId) {
|
|
|
19863
20142
|
}
|
|
19864
20143
|
return;
|
|
19865
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
|
+
}
|
|
19866
20158
|
function sanitizeTaskId(taskId) {
|
|
19867
20159
|
const unsafeMsg = checkUnsafeChars(taskId);
|
|
19868
20160
|
if (unsafeMsg) {
|
|
@@ -19943,7 +20235,7 @@ function validateProjectRoot(directory) {
|
|
|
19943
20235
|
}
|
|
19944
20236
|
}
|
|
19945
20237
|
async function saveEvidence(directory, taskId, evidence) {
|
|
19946
|
-
|
|
20238
|
+
_internals6.validateProjectRoot(directory);
|
|
19947
20239
|
const sanitizedTaskId = sanitizeTaskId2(taskId);
|
|
19948
20240
|
const relativePath = path7.join("evidence", sanitizedTaskId, "evidence.json");
|
|
19949
20241
|
validateSwarmPath(directory, relativePath);
|
|
@@ -20044,7 +20336,7 @@ async function loadEvidence(directory, taskId) {
|
|
|
20044
20336
|
return { status: "invalid_schema", errors: ["Invalid JSON"] };
|
|
20045
20337
|
}
|
|
20046
20338
|
if (isFlatRetrospective(parsed)) {
|
|
20047
|
-
const wrappedBundle =
|
|
20339
|
+
const wrappedBundle = _internals6.wrapFlatRetrospective(parsed, sanitizedTaskId);
|
|
20048
20340
|
try {
|
|
20049
20341
|
const validated = EvidenceBundleSchema.parse(wrappedBundle);
|
|
20050
20342
|
try {
|
|
@@ -20140,14 +20432,14 @@ async function checkRequirementCoverage(phase, directory) {
|
|
|
20140
20432
|
}
|
|
20141
20433
|
}
|
|
20142
20434
|
async function archiveEvidence(directory, maxAgeDays, maxBundles) {
|
|
20143
|
-
const taskIds = await
|
|
20435
|
+
const taskIds = await _internals6.listEvidenceTaskIds(directory);
|
|
20144
20436
|
const cutoffDate = new Date;
|
|
20145
20437
|
cutoffDate.setDate(cutoffDate.getDate() - maxAgeDays);
|
|
20146
20438
|
const cutoffIso = cutoffDate.toISOString();
|
|
20147
20439
|
const archived = [];
|
|
20148
20440
|
const remainingBundles = [];
|
|
20149
20441
|
for (const taskId of taskIds) {
|
|
20150
|
-
const result = await
|
|
20442
|
+
const result = await _internals6.loadEvidence(directory, taskId);
|
|
20151
20443
|
if (result.status !== "found") {
|
|
20152
20444
|
continue;
|
|
20153
20445
|
}
|
|
@@ -20175,7 +20467,7 @@ async function archiveEvidence(directory, maxAgeDays, maxBundles) {
|
|
|
20175
20467
|
}
|
|
20176
20468
|
return archived;
|
|
20177
20469
|
}
|
|
20178
|
-
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;
|
|
20179
20471
|
var init_manager2 = __esm(() => {
|
|
20180
20472
|
init_zod();
|
|
20181
20473
|
init_evidence_schema();
|
|
@@ -20218,7 +20510,7 @@ var init_manager2 = __esm(() => {
|
|
|
20218
20510
|
medium: "moderate",
|
|
20219
20511
|
high: "complex"
|
|
20220
20512
|
};
|
|
20221
|
-
|
|
20513
|
+
_internals6 = {
|
|
20222
20514
|
wrapFlatRetrospective,
|
|
20223
20515
|
loadEvidence,
|
|
20224
20516
|
listEvidenceTaskIds,
|
|
@@ -20430,7 +20722,7 @@ function getProfile(directory, planId) {
|
|
|
20430
20722
|
return row ? rowToProfile(row) : null;
|
|
20431
20723
|
}
|
|
20432
20724
|
function getOrCreateProfile(directory, planId, projectType) {
|
|
20433
|
-
const existing =
|
|
20725
|
+
const existing = _internals7.getProfile(directory, planId);
|
|
20434
20726
|
if (existing)
|
|
20435
20727
|
return existing;
|
|
20436
20728
|
const db = getProjectDb(directory);
|
|
@@ -20446,14 +20738,14 @@ function getOrCreateProfile(directory, planId, projectType) {
|
|
|
20446
20738
|
throw err;
|
|
20447
20739
|
}
|
|
20448
20740
|
}
|
|
20449
|
-
const after =
|
|
20741
|
+
const after = _internals7.getProfile(directory, planId);
|
|
20450
20742
|
if (!after) {
|
|
20451
20743
|
throw new Error(`Failed to create or load QA gate profile for plan_id=${planId}`);
|
|
20452
20744
|
}
|
|
20453
20745
|
return after;
|
|
20454
20746
|
}
|
|
20455
20747
|
function setGates(directory, planId, gates) {
|
|
20456
|
-
const current =
|
|
20748
|
+
const current = _internals7.getProfile(directory, planId);
|
|
20457
20749
|
if (!current) {
|
|
20458
20750
|
throw new Error(`No QA gate profile found for plan_id=${planId} \u2014 call getOrCreateProfile first`);
|
|
20459
20751
|
}
|
|
@@ -20477,7 +20769,7 @@ function setGates(directory, planId, gates) {
|
|
|
20477
20769
|
JSON.stringify(merged),
|
|
20478
20770
|
planId
|
|
20479
20771
|
]);
|
|
20480
|
-
const updated =
|
|
20772
|
+
const updated = _internals7.getProfile(directory, planId);
|
|
20481
20773
|
if (!updated) {
|
|
20482
20774
|
throw new Error(`Failed to re-read QA gate profile after update for plan_id=${planId}`);
|
|
20483
20775
|
}
|
|
@@ -20499,10 +20791,10 @@ function getEffectiveGates(profile, sessionOverrides) {
|
|
|
20499
20791
|
}
|
|
20500
20792
|
return merged;
|
|
20501
20793
|
}
|
|
20502
|
-
var
|
|
20794
|
+
var _internals7, DEFAULT_QA_GATES;
|
|
20503
20795
|
var init_qa_gate_profile = __esm(() => {
|
|
20504
20796
|
init_project_db();
|
|
20505
|
-
|
|
20797
|
+
_internals7 = {
|
|
20506
20798
|
getProfile,
|
|
20507
20799
|
getOrCreateProfile,
|
|
20508
20800
|
setGates,
|
|
@@ -34950,7 +35242,7 @@ function resetToRemoteBranch(cwd, options) {
|
|
|
34950
35242
|
const prunedBranches = [];
|
|
34951
35243
|
try {
|
|
34952
35244
|
const currentBranch = getCurrentBranch(cwd);
|
|
34953
|
-
const defaultRemoteBranch =
|
|
35245
|
+
const defaultRemoteBranch = _internals8.detectDefaultRemoteBranch(cwd);
|
|
34954
35246
|
if (!defaultRemoteBranch) {
|
|
34955
35247
|
return {
|
|
34956
35248
|
success: false,
|
|
@@ -35132,7 +35424,7 @@ function resetToRemoteBranch(cwd, options) {
|
|
|
35132
35424
|
function resetToMainAfterMerge(cwd, options) {
|
|
35133
35425
|
const warnings = [];
|
|
35134
35426
|
try {
|
|
35135
|
-
const defaultBranch =
|
|
35427
|
+
const defaultBranch = _internals8.detectDefaultRemoteBranch(cwd);
|
|
35136
35428
|
if (!defaultBranch) {
|
|
35137
35429
|
return {
|
|
35138
35430
|
success: false,
|
|
@@ -35159,7 +35451,7 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35159
35451
|
}
|
|
35160
35452
|
if (currentBranch === defaultBranch) {
|
|
35161
35453
|
try {
|
|
35162
|
-
const logOutput =
|
|
35454
|
+
const logOutput = _internals8.gitExec(["log", `${targetBranch}..HEAD`, "--oneline"], cwd);
|
|
35163
35455
|
if (logOutput.trim().length > 0) {
|
|
35164
35456
|
return {
|
|
35165
35457
|
success: false,
|
|
@@ -35174,11 +35466,11 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35174
35466
|
} catch {}
|
|
35175
35467
|
} else {
|
|
35176
35468
|
try {
|
|
35177
|
-
|
|
35469
|
+
_internals8.gitExec(["rev-parse", "--abbrev-ref", `${currentBranch}@{upstream}`], cwd);
|
|
35178
35470
|
} catch {
|
|
35179
35471
|
try {
|
|
35180
|
-
const localSha =
|
|
35181
|
-
const remoteSha =
|
|
35472
|
+
const localSha = _internals8.gitExec(["rev-parse", "HEAD"], cwd).trim();
|
|
35473
|
+
const remoteSha = _internals8.gitExec(["rev-parse", targetBranch], cwd).trim();
|
|
35182
35474
|
if (localSha !== remoteSha) {
|
|
35183
35475
|
return {
|
|
35184
35476
|
success: false,
|
|
@@ -35204,7 +35496,7 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35204
35496
|
}
|
|
35205
35497
|
}
|
|
35206
35498
|
try {
|
|
35207
|
-
|
|
35499
|
+
_internals8.gitExec(["fetch", "--prune", "origin"], cwd);
|
|
35208
35500
|
} catch (err) {
|
|
35209
35501
|
return {
|
|
35210
35502
|
success: false,
|
|
@@ -35220,7 +35512,7 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35220
35512
|
let switchedBranch = false;
|
|
35221
35513
|
if (currentBranch !== defaultBranch) {
|
|
35222
35514
|
try {
|
|
35223
|
-
|
|
35515
|
+
_internals8.gitExec(["checkout", defaultBranch], cwd);
|
|
35224
35516
|
switchedBranch = true;
|
|
35225
35517
|
} catch (err) {
|
|
35226
35518
|
return {
|
|
@@ -35235,7 +35527,7 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35235
35527
|
}
|
|
35236
35528
|
}
|
|
35237
35529
|
try {
|
|
35238
|
-
|
|
35530
|
+
_internals8.gitExec(["reset", "--hard", targetBranch], cwd);
|
|
35239
35531
|
} catch (err) {
|
|
35240
35532
|
return {
|
|
35241
35533
|
success: false,
|
|
@@ -35256,7 +35548,7 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35256
35548
|
while (Date.now() < endTime) {}
|
|
35257
35549
|
}
|
|
35258
35550
|
try {
|
|
35259
|
-
|
|
35551
|
+
_internals8.gitExec(["checkout", "--", "."], cwd);
|
|
35260
35552
|
discardSucceeded = true;
|
|
35261
35553
|
break;
|
|
35262
35554
|
} catch {}
|
|
@@ -35267,18 +35559,18 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35267
35559
|
changesDiscarded = discardSucceeded;
|
|
35268
35560
|
}
|
|
35269
35561
|
try {
|
|
35270
|
-
|
|
35562
|
+
_internals8.gitExec(["clean", "-fd"], cwd);
|
|
35271
35563
|
} catch {
|
|
35272
35564
|
warnings.push("Could not clean untracked files");
|
|
35273
35565
|
}
|
|
35274
35566
|
let branchDeleted = false;
|
|
35275
35567
|
if (switchedBranch && previousBranch !== defaultBranch) {
|
|
35276
35568
|
try {
|
|
35277
|
-
const mergedOutput =
|
|
35569
|
+
const mergedOutput = _internals8.gitExec(["branch", "--merged", defaultBranch], cwd);
|
|
35278
35570
|
const isMerged = mergedOutput.split(`
|
|
35279
35571
|
`).some((line) => line.trim() === previousBranch || line.trim() === `* ${previousBranch}`);
|
|
35280
35572
|
if (isMerged) {
|
|
35281
|
-
|
|
35573
|
+
_internals8.gitExec(["branch", "-d", previousBranch], cwd);
|
|
35282
35574
|
branchDeleted = true;
|
|
35283
35575
|
} else {
|
|
35284
35576
|
warnings.push(`Branch ${previousBranch} is not merged into ${defaultBranch} \u2014 keeping it`);
|
|
@@ -35289,7 +35581,7 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35289
35581
|
}
|
|
35290
35582
|
if (options?.pruneBranches) {
|
|
35291
35583
|
try {
|
|
35292
|
-
const mergedOutput =
|
|
35584
|
+
const mergedOutput = _internals8.gitExec(["branch", "--merged", defaultBranch], cwd);
|
|
35293
35585
|
const mergedLines = mergedOutput.split(`
|
|
35294
35586
|
`);
|
|
35295
35587
|
for (const line of mergedLines) {
|
|
@@ -35298,7 +35590,7 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35298
35590
|
continue;
|
|
35299
35591
|
}
|
|
35300
35592
|
try {
|
|
35301
|
-
|
|
35593
|
+
_internals8.gitExec(["branch", "-d", trimmedLine], cwd);
|
|
35302
35594
|
} catch {
|
|
35303
35595
|
warnings.push(`Could not prune branch: ${trimmedLine}`);
|
|
35304
35596
|
}
|
|
@@ -35328,10 +35620,10 @@ function resetToMainAfterMerge(cwd, options) {
|
|
|
35328
35620
|
};
|
|
35329
35621
|
}
|
|
35330
35622
|
}
|
|
35331
|
-
var GIT_TIMEOUT_MS2 = 30000,
|
|
35623
|
+
var GIT_TIMEOUT_MS2 = 30000, _internals8;
|
|
35332
35624
|
var init_branch = __esm(() => {
|
|
35333
35625
|
init_logger();
|
|
35334
|
-
|
|
35626
|
+
_internals8 = {
|
|
35335
35627
|
gitExec: gitExec2,
|
|
35336
35628
|
detectDefaultRemoteBranch,
|
|
35337
35629
|
getDefaultBaseBranch,
|
|
@@ -36525,7 +36817,7 @@ async function curateAndStoreSwarm(lessons, projectName, phaseInfo, directory, c
|
|
|
36525
36817
|
existingEntries.push(entry);
|
|
36526
36818
|
}
|
|
36527
36819
|
await enforceKnowledgeCap(knowledgePath, config3.swarm_max_entries);
|
|
36528
|
-
await
|
|
36820
|
+
await _internals9.runAutoPromotion(directory, config3);
|
|
36529
36821
|
return { stored, skipped, rejected };
|
|
36530
36822
|
}
|
|
36531
36823
|
async function runAutoPromotion(directory, config3) {
|
|
@@ -36606,7 +36898,7 @@ function createKnowledgeCuratorHook(directory, config3) {
|
|
|
36606
36898
|
});
|
|
36607
36899
|
const projectName2 = evidenceData.project_name ?? "unknown";
|
|
36608
36900
|
const phaseNumber2 = typeof evidenceData.phase_number === "number" ? evidenceData.phase_number : 1;
|
|
36609
|
-
await
|
|
36901
|
+
await _internals9.curateAndStoreSwarm(lessons, projectName2, { phase_number: phaseNumber2 }, directory, config3);
|
|
36610
36902
|
return;
|
|
36611
36903
|
}
|
|
36612
36904
|
const planContent = await readSwarmFileAsync(directory, "plan.md");
|
|
@@ -36628,17 +36920,17 @@ function createKnowledgeCuratorHook(directory, config3) {
|
|
|
36628
36920
|
const projectName = projectNameMatch ? projectNameMatch[1].trim() : "unknown";
|
|
36629
36921
|
const phaseMatch = /^Phase:\s*(\d+)/m.exec(planContent);
|
|
36630
36922
|
const phaseNumber = phaseMatch ? parseInt(phaseMatch[1], 10) : 1;
|
|
36631
|
-
await
|
|
36923
|
+
await _internals9.curateAndStoreSwarm(normalLessons, projectName, { phase_number: phaseNumber }, directory, config3);
|
|
36632
36924
|
};
|
|
36633
36925
|
return safeHook(handler);
|
|
36634
36926
|
}
|
|
36635
|
-
var seenRetroSections,
|
|
36927
|
+
var seenRetroSections, _internals9;
|
|
36636
36928
|
var init_knowledge_curator = __esm(() => {
|
|
36637
36929
|
init_knowledge_store();
|
|
36638
36930
|
init_knowledge_validator();
|
|
36639
36931
|
init_utils2();
|
|
36640
36932
|
seenRetroSections = new Map;
|
|
36641
|
-
|
|
36933
|
+
_internals9 = {
|
|
36642
36934
|
isWriteToEvidenceFile,
|
|
36643
36935
|
curateAndStoreSwarm,
|
|
36644
36936
|
runAutoPromotion,
|
|
@@ -37845,7 +38137,7 @@ async function executeWriteRetro(args, directory) {
|
|
|
37845
38137
|
}, null, 2);
|
|
37846
38138
|
}
|
|
37847
38139
|
}
|
|
37848
|
-
var write_retro,
|
|
38140
|
+
var write_retro, _internals10;
|
|
37849
38141
|
var init_write_retro = __esm(() => {
|
|
37850
38142
|
init_zod();
|
|
37851
38143
|
init_evidence_schema();
|
|
@@ -37892,13 +38184,13 @@ var init_write_retro = __esm(() => {
|
|
|
37892
38184
|
task_id: args.task_id !== undefined ? String(args.task_id) : undefined,
|
|
37893
38185
|
metadata: args.metadata
|
|
37894
38186
|
};
|
|
37895
|
-
return await
|
|
38187
|
+
return await _internals10.executeWriteRetro(writeRetroArgs, directory);
|
|
37896
38188
|
} catch {
|
|
37897
38189
|
return JSON.stringify({ success: false, phase: rawPhase, message: "Invalid arguments" }, null, 2);
|
|
37898
38190
|
}
|
|
37899
38191
|
}
|
|
37900
38192
|
});
|
|
37901
|
-
|
|
38193
|
+
_internals10 = {
|
|
37902
38194
|
executeWriteRetro,
|
|
37903
38195
|
write_retro
|
|
37904
38196
|
};
|
|
@@ -38189,6 +38481,12 @@ async function handleCloseCommand(directory, args, options = {}) {
|
|
|
38189
38481
|
}
|
|
38190
38482
|
}
|
|
38191
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
|
+
}
|
|
38192
38490
|
const guaranteeResult = guaranteeAllPlansComplete(planData);
|
|
38193
38491
|
for (const phaseId of guaranteeResult.closedPhaseIds) {
|
|
38194
38492
|
if (!closedPhases.includes(phaseId)) {
|
|
@@ -38202,11 +38500,15 @@ async function handleCloseCommand(directory, args, options = {}) {
|
|
|
38202
38500
|
}
|
|
38203
38501
|
if (!planAlreadyDone || guaranteeResult.closedPhaseIds.length > 0 || guaranteeResult.closedTaskIds.length > 0) {
|
|
38204
38502
|
try {
|
|
38205
|
-
await
|
|
38503
|
+
await closePlanTerminalState(directory, planData, {
|
|
38504
|
+
closedPhaseIds: guaranteeResult.closedPhaseIds,
|
|
38505
|
+
closedTaskIds: guaranteeResult.closedTaskIds,
|
|
38506
|
+
originalStatuses
|
|
38507
|
+
});
|
|
38206
38508
|
} catch (error93) {
|
|
38207
38509
|
const msg = error93 instanceof Error ? error93.message : String(error93);
|
|
38208
|
-
warnings.push(`Failed to persist terminal plan
|
|
38209
|
-
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);
|
|
38210
38512
|
}
|
|
38211
38513
|
}
|
|
38212
38514
|
}
|
|
@@ -38494,6 +38796,7 @@ var init_close = __esm(() => {
|
|
|
38494
38796
|
init_knowledge_curator();
|
|
38495
38797
|
init_knowledge_store();
|
|
38496
38798
|
init_utils2();
|
|
38799
|
+
init_manager();
|
|
38497
38800
|
init_scope_persistence();
|
|
38498
38801
|
init_skill_improver();
|
|
38499
38802
|
init_state();
|
|
@@ -38902,9 +39205,9 @@ async function detectDarkMatter(directory, options) {
|
|
|
38902
39205
|
} catch {
|
|
38903
39206
|
return [];
|
|
38904
39207
|
}
|
|
38905
|
-
const commitMap = await
|
|
38906
|
-
const matrix =
|
|
38907
|
-
const staticEdges = await
|
|
39208
|
+
const commitMap = await _internals11.parseGitLog(directory, maxCommitsToAnalyze);
|
|
39209
|
+
const matrix = _internals11.buildCoChangeMatrix(commitMap);
|
|
39210
|
+
const staticEdges = await _internals11.getStaticEdges(directory);
|
|
38908
39211
|
const results = [];
|
|
38909
39212
|
for (const entry of matrix.values()) {
|
|
38910
39213
|
const key = `${entry.fileA}::${entry.fileB}`;
|
|
@@ -38984,7 +39287,7 @@ ${rows}
|
|
|
38984
39287
|
These pairs likely share an architectural concern invisible to static analysis.
|
|
38985
39288
|
Consider adding explicit documentation or extracting the shared concern.`;
|
|
38986
39289
|
}
|
|
38987
|
-
var co_change_analyzer,
|
|
39290
|
+
var co_change_analyzer, _internals11;
|
|
38988
39291
|
var init_co_change_analyzer = __esm(() => {
|
|
38989
39292
|
init_zod();
|
|
38990
39293
|
init_create_tool();
|
|
@@ -39016,11 +39319,11 @@ var init_co_change_analyzer = __esm(() => {
|
|
|
39016
39319
|
npmiThreshold,
|
|
39017
39320
|
maxCommitsToAnalyze
|
|
39018
39321
|
};
|
|
39019
|
-
const pairs = await
|
|
39020
|
-
return
|
|
39322
|
+
const pairs = await _internals11.detectDarkMatter(directory, options);
|
|
39323
|
+
return _internals11.formatDarkMatterOutput(pairs);
|
|
39021
39324
|
}
|
|
39022
39325
|
});
|
|
39023
|
-
|
|
39326
|
+
_internals11 = {
|
|
39024
39327
|
parseGitLog,
|
|
39025
39328
|
buildCoChangeMatrix,
|
|
39026
39329
|
getStaticEdges,
|
|
@@ -39051,7 +39354,7 @@ async function handleDarkMatterCommand(directory, args) {
|
|
|
39051
39354
|
}
|
|
39052
39355
|
let pairs;
|
|
39053
39356
|
try {
|
|
39054
|
-
pairs = await
|
|
39357
|
+
pairs = await _internals11.detectDarkMatter(directory, options);
|
|
39055
39358
|
} catch (err) {
|
|
39056
39359
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
39057
39360
|
return `## Dark Matter Analysis Failed
|
|
@@ -39243,24 +39546,213 @@ function getPluginLockFilePaths() {
|
|
|
39243
39546
|
}
|
|
39244
39547
|
var init_cache_paths = () => {};
|
|
39245
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
|
+
|
|
39246
39738
|
// src/services/version-check.ts
|
|
39247
|
-
import { existsSync as existsSync11, mkdirSync as
|
|
39739
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
|
|
39248
39740
|
import { homedir as homedir5 } from "os";
|
|
39249
|
-
import { join as
|
|
39741
|
+
import { join as join20 } from "path";
|
|
39250
39742
|
function cacheDir() {
|
|
39251
39743
|
const xdg = process.env.XDG_CACHE_HOME;
|
|
39252
|
-
const base = xdg && xdg.length > 0 ? xdg :
|
|
39253
|
-
return
|
|
39744
|
+
const base = xdg && xdg.length > 0 ? xdg : join20(homedir5(), ".cache");
|
|
39745
|
+
return join20(base, "opencode-swarm");
|
|
39254
39746
|
}
|
|
39255
39747
|
function cacheFile() {
|
|
39256
|
-
return
|
|
39748
|
+
return join20(cacheDir(), "version-check.json");
|
|
39257
39749
|
}
|
|
39258
39750
|
function readVersionCache() {
|
|
39259
39751
|
try {
|
|
39260
|
-
const
|
|
39261
|
-
if (!existsSync11(
|
|
39752
|
+
const path22 = cacheFile();
|
|
39753
|
+
if (!existsSync11(path22))
|
|
39262
39754
|
return null;
|
|
39263
|
-
const raw =
|
|
39755
|
+
const raw = readFileSync7(path22, "utf-8");
|
|
39264
39756
|
const parsed = JSON.parse(raw);
|
|
39265
39757
|
if (typeof parsed?.checkedAt !== "number")
|
|
39266
39758
|
return null;
|
|
@@ -39299,8 +39791,8 @@ var init_version_check = __esm(() => {
|
|
|
39299
39791
|
|
|
39300
39792
|
// src/services/diagnose-service.ts
|
|
39301
39793
|
import * as child_process4 from "child_process";
|
|
39302
|
-
import { existsSync as existsSync12, readdirSync as readdirSync4, readFileSync as
|
|
39303
|
-
import
|
|
39794
|
+
import { existsSync as existsSync12, readdirSync as readdirSync4, readFileSync as readFileSync8, statSync as statSync6 } from "fs";
|
|
39795
|
+
import path22 from "path";
|
|
39304
39796
|
import { fileURLToPath } from "url";
|
|
39305
39797
|
function validateTaskDag(plan) {
|
|
39306
39798
|
const allTaskIds = new Set;
|
|
@@ -39332,7 +39824,21 @@ async function checkEvidenceCompleteness(directory, plan) {
|
|
|
39332
39824
|
}
|
|
39333
39825
|
if (completedTaskIds.length > 0) {
|
|
39334
39826
|
const evidenceTaskIds = new Set(await listEvidenceTaskIds(directory));
|
|
39335
|
-
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
|
+
}
|
|
39336
39842
|
if (missingEvidence.length === 0) {
|
|
39337
39843
|
return {
|
|
39338
39844
|
name: "Evidence",
|
|
@@ -39597,7 +40103,7 @@ async function checkSpecStaleness(directory, plan) {
|
|
|
39597
40103
|
};
|
|
39598
40104
|
}
|
|
39599
40105
|
async function checkConfigParseability(directory) {
|
|
39600
|
-
const configPath =
|
|
40106
|
+
const configPath = path22.join(directory, ".opencode/opencode-swarm.json");
|
|
39601
40107
|
if (!existsSync12(configPath)) {
|
|
39602
40108
|
return {
|
|
39603
40109
|
name: "Config Parseability",
|
|
@@ -39606,7 +40112,7 @@ async function checkConfigParseability(directory) {
|
|
|
39606
40112
|
};
|
|
39607
40113
|
}
|
|
39608
40114
|
try {
|
|
39609
|
-
const content =
|
|
40115
|
+
const content = readFileSync8(configPath, "utf-8");
|
|
39610
40116
|
JSON.parse(content);
|
|
39611
40117
|
return {
|
|
39612
40118
|
name: "Config Parseability",
|
|
@@ -39626,7 +40132,7 @@ function resolveGrammarDir(thisDir) {
|
|
|
39626
40132
|
const normalized = thisDir.replace(/\\/g, "/");
|
|
39627
40133
|
const isSource = normalized.endsWith("/src/services");
|
|
39628
40134
|
const isCliBundle = normalized.endsWith("/cli");
|
|
39629
|
-
return isSource || isCliBundle ?
|
|
40135
|
+
return isSource || isCliBundle ? path22.join(thisDir, "..", "lang", "grammars") : path22.join(thisDir, "lang", "grammars");
|
|
39630
40136
|
}
|
|
39631
40137
|
async function checkGrammarWasmFiles() {
|
|
39632
40138
|
const grammarFiles = [
|
|
@@ -39650,14 +40156,14 @@ async function checkGrammarWasmFiles() {
|
|
|
39650
40156
|
"tree-sitter-ini.wasm",
|
|
39651
40157
|
"tree-sitter-regex.wasm"
|
|
39652
40158
|
];
|
|
39653
|
-
const thisDir =
|
|
40159
|
+
const thisDir = path22.dirname(fileURLToPath(import.meta.url));
|
|
39654
40160
|
const grammarDir = resolveGrammarDir(thisDir);
|
|
39655
40161
|
const missing = [];
|
|
39656
|
-
if (!existsSync12(
|
|
40162
|
+
if (!existsSync12(path22.join(grammarDir, "tree-sitter.wasm"))) {
|
|
39657
40163
|
missing.push("tree-sitter.wasm (core runtime)");
|
|
39658
40164
|
}
|
|
39659
40165
|
for (const file3 of grammarFiles) {
|
|
39660
|
-
if (!existsSync12(
|
|
40166
|
+
if (!existsSync12(path22.join(grammarDir, file3))) {
|
|
39661
40167
|
missing.push(file3);
|
|
39662
40168
|
}
|
|
39663
40169
|
}
|
|
@@ -39675,7 +40181,7 @@ async function checkGrammarWasmFiles() {
|
|
|
39675
40181
|
};
|
|
39676
40182
|
}
|
|
39677
40183
|
async function checkCheckpointManifest(directory) {
|
|
39678
|
-
const manifestPath =
|
|
40184
|
+
const manifestPath = path22.join(directory, ".swarm/checkpoints.json");
|
|
39679
40185
|
if (!existsSync12(manifestPath)) {
|
|
39680
40186
|
return {
|
|
39681
40187
|
name: "Checkpoint Manifest",
|
|
@@ -39684,7 +40190,7 @@ async function checkCheckpointManifest(directory) {
|
|
|
39684
40190
|
};
|
|
39685
40191
|
}
|
|
39686
40192
|
try {
|
|
39687
|
-
const content =
|
|
40193
|
+
const content = readFileSync8(manifestPath, "utf-8");
|
|
39688
40194
|
const parsed = JSON.parse(content);
|
|
39689
40195
|
if (!parsed.checkpoints || !Array.isArray(parsed.checkpoints)) {
|
|
39690
40196
|
return {
|
|
@@ -39727,7 +40233,7 @@ async function checkCheckpointManifest(directory) {
|
|
|
39727
40233
|
}
|
|
39728
40234
|
}
|
|
39729
40235
|
async function checkEventStreamIntegrity(directory) {
|
|
39730
|
-
const eventsPath =
|
|
40236
|
+
const eventsPath = path22.join(directory, ".swarm/events.jsonl");
|
|
39731
40237
|
if (!existsSync12(eventsPath)) {
|
|
39732
40238
|
return {
|
|
39733
40239
|
name: "Event Stream",
|
|
@@ -39736,7 +40242,7 @@ async function checkEventStreamIntegrity(directory) {
|
|
|
39736
40242
|
};
|
|
39737
40243
|
}
|
|
39738
40244
|
try {
|
|
39739
|
-
const content =
|
|
40245
|
+
const content = readFileSync8(eventsPath, "utf-8");
|
|
39740
40246
|
const lines = content.split(`
|
|
39741
40247
|
`).filter((line) => line.trim() !== "");
|
|
39742
40248
|
let malformedCount = 0;
|
|
@@ -39768,7 +40274,7 @@ async function checkEventStreamIntegrity(directory) {
|
|
|
39768
40274
|
}
|
|
39769
40275
|
}
|
|
39770
40276
|
async function checkSteeringDirectives(directory) {
|
|
39771
|
-
const eventsPath =
|
|
40277
|
+
const eventsPath = path22.join(directory, ".swarm/events.jsonl");
|
|
39772
40278
|
if (!existsSync12(eventsPath)) {
|
|
39773
40279
|
return {
|
|
39774
40280
|
name: "Steering Directives",
|
|
@@ -39777,7 +40283,7 @@ async function checkSteeringDirectives(directory) {
|
|
|
39777
40283
|
};
|
|
39778
40284
|
}
|
|
39779
40285
|
try {
|
|
39780
|
-
const content =
|
|
40286
|
+
const content = readFileSync8(eventsPath, "utf-8");
|
|
39781
40287
|
const lines = content.split(`
|
|
39782
40288
|
`).filter((line) => line.trim() !== "");
|
|
39783
40289
|
const directivesIssued = [];
|
|
@@ -39824,7 +40330,7 @@ async function checkCurator(directory) {
|
|
|
39824
40330
|
detail: "Disabled (enable via curator.enabled)"
|
|
39825
40331
|
};
|
|
39826
40332
|
}
|
|
39827
|
-
const summaryPath =
|
|
40333
|
+
const summaryPath = path22.join(directory, ".swarm/curator-summary.json");
|
|
39828
40334
|
if (!existsSync12(summaryPath)) {
|
|
39829
40335
|
return {
|
|
39830
40336
|
name: "Curator",
|
|
@@ -39833,7 +40339,7 @@ async function checkCurator(directory) {
|
|
|
39833
40339
|
};
|
|
39834
40340
|
}
|
|
39835
40341
|
try {
|
|
39836
|
-
const content =
|
|
40342
|
+
const content = readFileSync8(summaryPath, "utf-8");
|
|
39837
40343
|
const parsed = JSON.parse(content);
|
|
39838
40344
|
if (typeof parsed.schema_version !== "number" || parsed.schema_version !== 1) {
|
|
39839
40345
|
return {
|
|
@@ -39990,7 +40496,7 @@ async function getDiagnoseData(directory) {
|
|
|
39990
40496
|
checks5.push(await checkSteeringDirectives(directory));
|
|
39991
40497
|
checks5.push(await checkCurator(directory));
|
|
39992
40498
|
try {
|
|
39993
|
-
const evidenceDir =
|
|
40499
|
+
const evidenceDir = path22.join(directory, ".swarm", "evidence");
|
|
39994
40500
|
const snapshotFiles = existsSync12(evidenceDir) ? readdirSync4(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
|
|
39995
40501
|
if (snapshotFiles.length > 0) {
|
|
39996
40502
|
const latest = snapshotFiles.sort().pop();
|
|
@@ -40028,9 +40534,9 @@ async function getDiagnoseData(directory) {
|
|
|
40028
40534
|
cacheRows.push(`\u2B1C ${cachePath} \u2014 absent`);
|
|
40029
40535
|
continue;
|
|
40030
40536
|
}
|
|
40031
|
-
const pkgJsonPath =
|
|
40537
|
+
const pkgJsonPath = path22.join(cachePath, "package.json");
|
|
40032
40538
|
try {
|
|
40033
|
-
const raw =
|
|
40539
|
+
const raw = readFileSync8(pkgJsonPath, "utf-8");
|
|
40034
40540
|
const parsed = JSON.parse(raw);
|
|
40035
40541
|
const installedVersion = typeof parsed.version === "string" ? parsed.version : "?";
|
|
40036
40542
|
cacheRows.push(`\u2705 ${cachePath} \u2014 v${installedVersion}`);
|
|
@@ -40087,6 +40593,7 @@ var init_diagnose_service = __esm(() => {
|
|
|
40087
40593
|
init_package();
|
|
40088
40594
|
init_cache_paths();
|
|
40089
40595
|
init_loader();
|
|
40596
|
+
init_gate_bridge();
|
|
40090
40597
|
init_manager2();
|
|
40091
40598
|
init_utils2();
|
|
40092
40599
|
init_manager();
|
|
@@ -40118,13 +40625,13 @@ __export(exports_config_doctor, {
|
|
|
40118
40625
|
import * as crypto3 from "crypto";
|
|
40119
40626
|
import * as fs8 from "fs";
|
|
40120
40627
|
import * as os6 from "os";
|
|
40121
|
-
import * as
|
|
40628
|
+
import * as path23 from "path";
|
|
40122
40629
|
function getUserConfigDir3() {
|
|
40123
|
-
return process.env.XDG_CONFIG_HOME ||
|
|
40630
|
+
return process.env.XDG_CONFIG_HOME || path23.join(os6.homedir(), ".config");
|
|
40124
40631
|
}
|
|
40125
40632
|
function getConfigPaths(directory) {
|
|
40126
|
-
const userConfigPath =
|
|
40127
|
-
const projectConfigPath =
|
|
40633
|
+
const userConfigPath = path23.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
|
|
40634
|
+
const projectConfigPath = path23.join(directory, ".opencode", "opencode-swarm.json");
|
|
40128
40635
|
return { userConfigPath, projectConfigPath };
|
|
40129
40636
|
}
|
|
40130
40637
|
function computeHash(content) {
|
|
@@ -40149,9 +40656,9 @@ function isValidConfigPath(configPath, directory) {
|
|
|
40149
40656
|
const normalizedUser = userConfigPath.replace(/\\/g, "/");
|
|
40150
40657
|
const normalizedProject = projectConfigPath.replace(/\\/g, "/");
|
|
40151
40658
|
try {
|
|
40152
|
-
const resolvedConfig =
|
|
40153
|
-
const resolvedUser =
|
|
40154
|
-
const resolvedProject =
|
|
40659
|
+
const resolvedConfig = path23.resolve(configPath);
|
|
40660
|
+
const resolvedUser = path23.resolve(normalizedUser);
|
|
40661
|
+
const resolvedProject = path23.resolve(normalizedProject);
|
|
40155
40662
|
return resolvedConfig === resolvedUser || resolvedConfig === resolvedProject;
|
|
40156
40663
|
} catch {
|
|
40157
40664
|
return false;
|
|
@@ -40191,12 +40698,12 @@ function createConfigBackup(directory) {
|
|
|
40191
40698
|
};
|
|
40192
40699
|
}
|
|
40193
40700
|
function writeBackupArtifact(directory, backup) {
|
|
40194
|
-
const swarmDir =
|
|
40701
|
+
const swarmDir = path23.join(directory, ".swarm");
|
|
40195
40702
|
if (!fs8.existsSync(swarmDir)) {
|
|
40196
40703
|
fs8.mkdirSync(swarmDir, { recursive: true });
|
|
40197
40704
|
}
|
|
40198
40705
|
const backupFilename = `config-backup-${backup.createdAt}.json`;
|
|
40199
|
-
const backupPath =
|
|
40706
|
+
const backupPath = path23.join(swarmDir, backupFilename);
|
|
40200
40707
|
const artifact = {
|
|
40201
40708
|
createdAt: backup.createdAt,
|
|
40202
40709
|
configPath: backup.configPath,
|
|
@@ -40226,7 +40733,7 @@ function restoreFromBackup(backupPath, directory) {
|
|
|
40226
40733
|
return null;
|
|
40227
40734
|
}
|
|
40228
40735
|
const targetPath = artifact.configPath;
|
|
40229
|
-
const targetDir =
|
|
40736
|
+
const targetDir = path23.dirname(targetPath);
|
|
40230
40737
|
if (!fs8.existsSync(targetDir)) {
|
|
40231
40738
|
fs8.mkdirSync(targetDir, { recursive: true });
|
|
40232
40739
|
}
|
|
@@ -40257,9 +40764,9 @@ function readConfigFromFile(directory) {
|
|
|
40257
40764
|
return null;
|
|
40258
40765
|
}
|
|
40259
40766
|
}
|
|
40260
|
-
function validateConfigKey(
|
|
40767
|
+
function validateConfigKey(path24, value, _config) {
|
|
40261
40768
|
const findings = [];
|
|
40262
|
-
switch (
|
|
40769
|
+
switch (path24) {
|
|
40263
40770
|
case "agents": {
|
|
40264
40771
|
if (value !== undefined) {
|
|
40265
40772
|
findings.push({
|
|
@@ -40496,27 +41003,27 @@ function validateConfigKey(path23, value, _config) {
|
|
|
40496
41003
|
}
|
|
40497
41004
|
return findings;
|
|
40498
41005
|
}
|
|
40499
|
-
function walkConfigAndValidate(obj,
|
|
41006
|
+
function walkConfigAndValidate(obj, path24, config3, findings) {
|
|
40500
41007
|
if (obj === null || obj === undefined) {
|
|
40501
41008
|
return;
|
|
40502
41009
|
}
|
|
40503
|
-
if (
|
|
40504
|
-
const keyFindings = validateConfigKey(
|
|
41010
|
+
if (path24 && typeof obj === "object" && !Array.isArray(obj)) {
|
|
41011
|
+
const keyFindings = validateConfigKey(path24, obj, config3);
|
|
40505
41012
|
findings.push(...keyFindings);
|
|
40506
41013
|
}
|
|
40507
41014
|
if (typeof obj !== "object") {
|
|
40508
|
-
const keyFindings = validateConfigKey(
|
|
41015
|
+
const keyFindings = validateConfigKey(path24, obj, config3);
|
|
40509
41016
|
findings.push(...keyFindings);
|
|
40510
41017
|
return;
|
|
40511
41018
|
}
|
|
40512
41019
|
if (Array.isArray(obj)) {
|
|
40513
41020
|
obj.forEach((item, index) => {
|
|
40514
|
-
walkConfigAndValidate(item, `${
|
|
41021
|
+
walkConfigAndValidate(item, `${path24}[${index}]`, config3, findings);
|
|
40515
41022
|
});
|
|
40516
41023
|
return;
|
|
40517
41024
|
}
|
|
40518
41025
|
for (const [key, value] of Object.entries(obj)) {
|
|
40519
|
-
const newPath =
|
|
41026
|
+
const newPath = path24 ? `${path24}.${key}` : key;
|
|
40520
41027
|
walkConfigAndValidate(value, newPath, config3, findings);
|
|
40521
41028
|
}
|
|
40522
41029
|
}
|
|
@@ -40636,7 +41143,7 @@ function applySafeAutoFixes(directory, result) {
|
|
|
40636
41143
|
}
|
|
40637
41144
|
}
|
|
40638
41145
|
if (appliedFixes.length > 0) {
|
|
40639
|
-
const configDir =
|
|
41146
|
+
const configDir = path23.dirname(configPath);
|
|
40640
41147
|
if (!fs8.existsSync(configDir)) {
|
|
40641
41148
|
fs8.mkdirSync(configDir, { recursive: true });
|
|
40642
41149
|
}
|
|
@@ -40646,12 +41153,12 @@ function applySafeAutoFixes(directory, result) {
|
|
|
40646
41153
|
return { appliedFixes, updatedConfigPath };
|
|
40647
41154
|
}
|
|
40648
41155
|
function writeDoctorArtifact(directory, result) {
|
|
40649
|
-
const swarmDir =
|
|
41156
|
+
const swarmDir = path23.join(directory, ".swarm");
|
|
40650
41157
|
if (!fs8.existsSync(swarmDir)) {
|
|
40651
41158
|
fs8.mkdirSync(swarmDir, { recursive: true });
|
|
40652
41159
|
}
|
|
40653
41160
|
const artifactFilename = "config-doctor.json";
|
|
40654
|
-
const artifactPath =
|
|
41161
|
+
const artifactPath = path23.join(swarmDir, artifactFilename);
|
|
40655
41162
|
const guiOutput = {
|
|
40656
41163
|
timestamp: result.timestamp,
|
|
40657
41164
|
summary: result.summary,
|
|
@@ -40747,17 +41254,17 @@ function detectStraySwarmDirs(projectRoot) {
|
|
|
40747
41254
|
if (!entry.isDirectory())
|
|
40748
41255
|
continue;
|
|
40749
41256
|
const name = entry.name;
|
|
40750
|
-
const fullPath =
|
|
41257
|
+
const fullPath = path23.join(dir, name);
|
|
40751
41258
|
if (SKIP_DIRS.has(name))
|
|
40752
41259
|
continue;
|
|
40753
|
-
const gitPath =
|
|
41260
|
+
const gitPath = path23.join(fullPath, ".git");
|
|
40754
41261
|
try {
|
|
40755
41262
|
const gitStat = fs8.statSync(gitPath);
|
|
40756
41263
|
if (gitStat.isFile() || gitStat.isDirectory())
|
|
40757
41264
|
continue;
|
|
40758
41265
|
} catch {}
|
|
40759
41266
|
if (name === ".swarm") {
|
|
40760
|
-
const parentDir =
|
|
41267
|
+
const parentDir = path23.dirname(fullPath);
|
|
40761
41268
|
if (parentDir === projectRoot)
|
|
40762
41269
|
continue;
|
|
40763
41270
|
let contents = [];
|
|
@@ -40767,7 +41274,7 @@ function detectStraySwarmDirs(projectRoot) {
|
|
|
40767
41274
|
contents = ["<unreadable>"];
|
|
40768
41275
|
}
|
|
40769
41276
|
findings.push({
|
|
40770
|
-
path:
|
|
41277
|
+
path: path23.relative(projectRoot, fullPath).replace(/\\/g, "/"),
|
|
40771
41278
|
absolutePath: fullPath,
|
|
40772
41279
|
contents: contents.slice(0, MAX_CONTENTS_ENTRIES),
|
|
40773
41280
|
totalEntries: contents.length
|
|
@@ -40785,21 +41292,21 @@ function removeStraySwarmDir(projectRoot, strayPath) {
|
|
|
40785
41292
|
let canonicalStray;
|
|
40786
41293
|
try {
|
|
40787
41294
|
canonicalRoot = fs8.realpathSync(projectRoot);
|
|
40788
|
-
canonicalStray = fs8.realpathSync(
|
|
41295
|
+
canonicalStray = fs8.realpathSync(path23.isAbsolute(strayPath) ? strayPath : path23.resolve(projectRoot, strayPath));
|
|
40789
41296
|
} catch (err) {
|
|
40790
41297
|
return {
|
|
40791
41298
|
success: false,
|
|
40792
41299
|
message: `Failed to resolve paths: ${err instanceof Error ? err.message : String(err)}`
|
|
40793
41300
|
};
|
|
40794
41301
|
}
|
|
40795
|
-
const rootSwarm =
|
|
41302
|
+
const rootSwarm = path23.join(canonicalRoot, ".swarm");
|
|
40796
41303
|
if (canonicalStray === rootSwarm || canonicalStray === canonicalRoot) {
|
|
40797
41304
|
return {
|
|
40798
41305
|
success: false,
|
|
40799
41306
|
message: "Refusing to remove root .swarm/ directory"
|
|
40800
41307
|
};
|
|
40801
41308
|
}
|
|
40802
|
-
if (!canonicalStray.startsWith(canonicalRoot +
|
|
41309
|
+
if (!canonicalStray.startsWith(canonicalRoot + path23.sep)) {
|
|
40803
41310
|
return {
|
|
40804
41311
|
success: false,
|
|
40805
41312
|
message: "Path is outside project root \u2014 refusing to remove"
|
|
@@ -41888,7 +42395,7 @@ var init_profiles = __esm(() => {
|
|
|
41888
42395
|
|
|
41889
42396
|
// src/lang/detector.ts
|
|
41890
42397
|
import { access as access3, readdir as readdir2 } from "fs/promises";
|
|
41891
|
-
import { extname as extname2, join as
|
|
42398
|
+
import { extname as extname2, join as join22 } from "path";
|
|
41892
42399
|
async function detectProjectLanguages(projectDir) {
|
|
41893
42400
|
const detected = new Set;
|
|
41894
42401
|
async function scanDir(dir) {
|
|
@@ -41904,7 +42411,7 @@ async function detectProjectLanguages(projectDir) {
|
|
|
41904
42411
|
if (detectFile.includes("*") || detectFile.includes("?"))
|
|
41905
42412
|
continue;
|
|
41906
42413
|
try {
|
|
41907
|
-
await access3(
|
|
42414
|
+
await access3(join22(dir, detectFile));
|
|
41908
42415
|
detected.add(profile.id);
|
|
41909
42416
|
break;
|
|
41910
42417
|
} catch {}
|
|
@@ -41925,7 +42432,7 @@ async function detectProjectLanguages(projectDir) {
|
|
|
41925
42432
|
const topEntries = await readdir2(projectDir, { withFileTypes: true });
|
|
41926
42433
|
for (const entry of topEntries) {
|
|
41927
42434
|
if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
41928
|
-
await scanDir(
|
|
42435
|
+
await scanDir(join22(projectDir, entry.name));
|
|
41929
42436
|
}
|
|
41930
42437
|
}
|
|
41931
42438
|
} catch {}
|
|
@@ -41944,7 +42451,7 @@ var init_detector = __esm(() => {
|
|
|
41944
42451
|
|
|
41945
42452
|
// src/build/discovery.ts
|
|
41946
42453
|
import * as fs9 from "fs";
|
|
41947
|
-
import * as
|
|
42454
|
+
import * as path24 from "path";
|
|
41948
42455
|
function isCommandAvailable(command) {
|
|
41949
42456
|
if (toolchainCache.has(command)) {
|
|
41950
42457
|
return toolchainCache.get(command);
|
|
@@ -41952,7 +42459,7 @@ function isCommandAvailable(command) {
|
|
|
41952
42459
|
const isWindows = process.platform === "win32";
|
|
41953
42460
|
const cmd = isWindows ? `${command}.exe` : command;
|
|
41954
42461
|
try {
|
|
41955
|
-
const result =
|
|
42462
|
+
const result = _internals12.spawnSyncImpl(isWindows ? ["where", cmd] : ["which", cmd], {
|
|
41956
42463
|
cwd: process.cwd(),
|
|
41957
42464
|
stdin: "ignore",
|
|
41958
42465
|
stdout: "ignore",
|
|
@@ -41979,11 +42486,11 @@ function findBuildFiles(workingDir, patterns) {
|
|
|
41979
42486
|
const regex = simpleGlobToRegex(pattern);
|
|
41980
42487
|
const matches = files.filter((f) => regex.test(f));
|
|
41981
42488
|
if (matches.length > 0) {
|
|
41982
|
-
return
|
|
42489
|
+
return path24.join(dir, matches[0]);
|
|
41983
42490
|
}
|
|
41984
42491
|
} catch {}
|
|
41985
42492
|
} else {
|
|
41986
|
-
const filePath =
|
|
42493
|
+
const filePath = path24.join(workingDir, pattern);
|
|
41987
42494
|
if (fs9.existsSync(filePath)) {
|
|
41988
42495
|
return filePath;
|
|
41989
42496
|
}
|
|
@@ -41992,7 +42499,7 @@ function findBuildFiles(workingDir, patterns) {
|
|
|
41992
42499
|
return null;
|
|
41993
42500
|
}
|
|
41994
42501
|
function getRepoDefinedScripts(workingDir, scripts) {
|
|
41995
|
-
const packageJsonPath =
|
|
42502
|
+
const packageJsonPath = path24.join(workingDir, "package.json");
|
|
41996
42503
|
if (!fs9.existsSync(packageJsonPath)) {
|
|
41997
42504
|
return [];
|
|
41998
42505
|
}
|
|
@@ -42033,7 +42540,7 @@ function findAllBuildFiles(workingDir) {
|
|
|
42033
42540
|
const regex = simpleGlobToRegex(pattern);
|
|
42034
42541
|
findFilesRecursive(workingDir, regex, allBuildFiles);
|
|
42035
42542
|
} else {
|
|
42036
|
-
const filePath =
|
|
42543
|
+
const filePath = path24.join(workingDir, pattern);
|
|
42037
42544
|
if (fs9.existsSync(filePath)) {
|
|
42038
42545
|
allBuildFiles.add(filePath);
|
|
42039
42546
|
}
|
|
@@ -42046,7 +42553,7 @@ function findFilesRecursive(dir, regex, results) {
|
|
|
42046
42553
|
try {
|
|
42047
42554
|
const entries = fs9.readdirSync(dir, { withFileTypes: true });
|
|
42048
42555
|
for (const entry of entries) {
|
|
42049
|
-
const fullPath =
|
|
42556
|
+
const fullPath = path24.join(dir, entry.name);
|
|
42050
42557
|
if (entry.isDirectory() && !["node_modules", ".git", "dist", "build", "target"].includes(entry.name)) {
|
|
42051
42558
|
findFilesRecursive(fullPath, regex, results);
|
|
42052
42559
|
} else if (entry.isFile() && regex.test(entry.name)) {
|
|
@@ -42069,7 +42576,7 @@ async function discoverBuildCommandsFromProfiles(workingDir) {
|
|
|
42069
42576
|
let foundCommand = false;
|
|
42070
42577
|
for (const cmd of sortedCommands) {
|
|
42071
42578
|
if (cmd.detectFile) {
|
|
42072
|
-
const detectFilePath =
|
|
42579
|
+
const detectFilePath = path24.join(workingDir, cmd.detectFile);
|
|
42073
42580
|
if (!fs9.existsSync(detectFilePath)) {
|
|
42074
42581
|
continue;
|
|
42075
42582
|
}
|
|
@@ -42102,7 +42609,7 @@ async function discoverBuildCommands(workingDir, options) {
|
|
|
42102
42609
|
const scope = options?.scope ?? "all";
|
|
42103
42610
|
const changedFiles = options?.changedFiles ?? [];
|
|
42104
42611
|
const _filesToCheck = filterByScope(workingDir, scope, changedFiles);
|
|
42105
|
-
const profileResult = await
|
|
42612
|
+
const profileResult = await _internals12.discoverBuildCommandsFromProfiles(workingDir);
|
|
42106
42613
|
const profileCommands = profileResult.commands;
|
|
42107
42614
|
const profileSkipped = profileResult.skipped;
|
|
42108
42615
|
const coveredEcosystems = new Set;
|
|
@@ -42165,7 +42672,7 @@ function clearToolchainCache() {
|
|
|
42165
42672
|
function getEcosystems() {
|
|
42166
42673
|
return ECOSYSTEMS.map((e) => e.ecosystem);
|
|
42167
42674
|
}
|
|
42168
|
-
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;
|
|
42169
42676
|
var init_discovery = __esm(() => {
|
|
42170
42677
|
init_dist();
|
|
42171
42678
|
init_detector();
|
|
@@ -42283,7 +42790,7 @@ var init_discovery = __esm(() => {
|
|
|
42283
42790
|
php: ["php-composer"]
|
|
42284
42791
|
};
|
|
42285
42792
|
toolchainCache = new Map;
|
|
42286
|
-
|
|
42793
|
+
_internals12 = {
|
|
42287
42794
|
isCommandAvailable,
|
|
42288
42795
|
discoverBuildCommandsFromProfiles,
|
|
42289
42796
|
discoverBuildCommands,
|
|
@@ -42310,7 +42817,7 @@ var init_discovery = __esm(() => {
|
|
|
42310
42817
|
|
|
42311
42818
|
// src/services/tool-doctor.ts
|
|
42312
42819
|
import * as fs10 from "fs";
|
|
42313
|
-
import * as
|
|
42820
|
+
import * as path25 from "path";
|
|
42314
42821
|
function extractRegisteredToolKeys(indexPath) {
|
|
42315
42822
|
const registeredKeys = new Set;
|
|
42316
42823
|
try {
|
|
@@ -42365,8 +42872,8 @@ function checkBinaryReadiness() {
|
|
|
42365
42872
|
}
|
|
42366
42873
|
function runToolDoctor(_directory, pluginRoot) {
|
|
42367
42874
|
const findings = [];
|
|
42368
|
-
const resolvedPluginRoot = pluginRoot ??
|
|
42369
|
-
const indexPath =
|
|
42875
|
+
const resolvedPluginRoot = pluginRoot ?? path25.resolve(import.meta.dir, "..", "..");
|
|
42876
|
+
const indexPath = path25.join(resolvedPluginRoot, "src", "index.ts");
|
|
42370
42877
|
if (!fs10.existsSync(indexPath)) {
|
|
42371
42878
|
return {
|
|
42372
42879
|
findings: [
|
|
@@ -42586,7 +43093,7 @@ var exports_evidence_summary_service = {};
|
|
|
42586
43093
|
__export(exports_evidence_summary_service, {
|
|
42587
43094
|
isAutoSummaryEnabled: () => isAutoSummaryEnabled,
|
|
42588
43095
|
buildEvidenceSummary: () => buildEvidenceSummary,
|
|
42589
|
-
_internals: () =>
|
|
43096
|
+
_internals: () => _internals13,
|
|
42590
43097
|
REQUIRED_EVIDENCE_TYPES: () => REQUIRED_EVIDENCE_TYPES,
|
|
42591
43098
|
EVIDENCE_SUMMARY_VERSION: () => EVIDENCE_SUMMARY_VERSION
|
|
42592
43099
|
});
|
|
@@ -42624,14 +43131,13 @@ function getTaskStatus(task, bundle) {
|
|
|
42624
43131
|
if (task?.status) {
|
|
42625
43132
|
return task.status;
|
|
42626
43133
|
}
|
|
42627
|
-
const entries =
|
|
43134
|
+
const entries = _internals13.normalizeBundleEntries(bundle);
|
|
42628
43135
|
if (entries.length > 0) {
|
|
42629
43136
|
return "completed";
|
|
42630
43137
|
}
|
|
42631
43138
|
return "pending";
|
|
42632
43139
|
}
|
|
42633
|
-
function
|
|
42634
|
-
const entries = _internals12.normalizeBundleEntries(bundle);
|
|
43140
|
+
function evidenceCompleteFromEntries(entries) {
|
|
42635
43141
|
if (entries.length === 0) {
|
|
42636
43142
|
return {
|
|
42637
43143
|
isComplete: false,
|
|
@@ -42650,6 +43156,9 @@ function isEvidenceComplete(bundle) {
|
|
|
42650
43156
|
missingEvidence: missing
|
|
42651
43157
|
};
|
|
42652
43158
|
}
|
|
43159
|
+
function isEvidenceComplete(bundle) {
|
|
43160
|
+
return evidenceCompleteFromEntries(_internals13.normalizeBundleEntries(bundle));
|
|
43161
|
+
}
|
|
42653
43162
|
function getTaskBlockers(task, summary, status) {
|
|
42654
43163
|
const blockers = [];
|
|
42655
43164
|
if (task?.blocked_reason) {
|
|
@@ -42666,11 +43175,19 @@ function getTaskBlockers(task, summary, status) {
|
|
|
42666
43175
|
async function buildTaskSummary(directory, task, taskId) {
|
|
42667
43176
|
const result = await loadEvidence(directory, taskId);
|
|
42668
43177
|
const bundle = result.status === "found" ? result.bundle : null;
|
|
43178
|
+
const gateEvidence = await readDurableGateEvidence(directory, taskId);
|
|
42669
43179
|
const phase = task?.phase ?? 0;
|
|
42670
|
-
const status =
|
|
42671
|
-
const
|
|
42672
|
-
|
|
42673
|
-
|
|
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);
|
|
42674
43191
|
const hasReview = entries.some((e) => e.type === "review");
|
|
42675
43192
|
const hasTest = entries.some((e) => e.type === "test");
|
|
42676
43193
|
const hasApproval = entries.some((e) => e.type === "approval");
|
|
@@ -42699,12 +43216,12 @@ async function buildPhaseSummary(directory, phase) {
|
|
|
42699
43216
|
const taskSummaries = [];
|
|
42700
43217
|
const _taskMap = new Map(phase.tasks.map((t) => [t.id, t]));
|
|
42701
43218
|
for (const task of phase.tasks) {
|
|
42702
|
-
const summary = await
|
|
43219
|
+
const summary = await _internals13.buildTaskSummary(directory, task, task.id);
|
|
42703
43220
|
taskSummaries.push(summary);
|
|
42704
43221
|
}
|
|
42705
43222
|
const extraTaskIds = taskIds.filter((id) => !phaseTaskIds.has(id));
|
|
42706
43223
|
for (const taskId of extraTaskIds) {
|
|
42707
|
-
const summary = await
|
|
43224
|
+
const summary = await _internals13.buildTaskSummary(directory, undefined, taskId);
|
|
42708
43225
|
if (summary.phase === phase.id) {
|
|
42709
43226
|
taskSummaries.push(summary);
|
|
42710
43227
|
}
|
|
@@ -42805,7 +43322,7 @@ async function buildEvidenceSummary(directory, currentPhase) {
|
|
|
42805
43322
|
let totalTasks = 0;
|
|
42806
43323
|
let completedTasks = 0;
|
|
42807
43324
|
for (const phase of phasesToProcess) {
|
|
42808
|
-
const summary = await
|
|
43325
|
+
const summary = await _internals13.buildPhaseSummary(directory, phase);
|
|
42809
43326
|
phaseSummaries.push(summary);
|
|
42810
43327
|
totalTasks += summary.totalTasks;
|
|
42811
43328
|
completedTasks += summary.completedTasks;
|
|
@@ -42827,7 +43344,7 @@ async function buildEvidenceSummary(directory, currentPhase) {
|
|
|
42827
43344
|
overallBlockers,
|
|
42828
43345
|
summaryText: ""
|
|
42829
43346
|
};
|
|
42830
|
-
artifact.summaryText =
|
|
43347
|
+
artifact.summaryText = _internals13.generateSummaryText(artifact);
|
|
42831
43348
|
log("[EvidenceSummary] Summary built", {
|
|
42832
43349
|
phases: phaseSummaries.length,
|
|
42833
43350
|
totalTasks,
|
|
@@ -42846,8 +43363,9 @@ function isAutoSummaryEnabled(automationConfig) {
|
|
|
42846
43363
|
}
|
|
42847
43364
|
return automationConfig.capabilities?.evidence_auto_summaries === true;
|
|
42848
43365
|
}
|
|
42849
|
-
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;
|
|
42850
43367
|
var init_evidence_summary_service = __esm(() => {
|
|
43368
|
+
init_gate_bridge();
|
|
42851
43369
|
init_manager2();
|
|
42852
43370
|
init_manager();
|
|
42853
43371
|
init_utils();
|
|
@@ -42860,11 +43378,12 @@ var init_evidence_summary_service = __esm(() => {
|
|
|
42860
43378
|
"retrospective"
|
|
42861
43379
|
]);
|
|
42862
43380
|
REQUIRED_EVIDENCE_TYPES = ["review", "test"];
|
|
42863
|
-
|
|
43381
|
+
_internals13 = {
|
|
42864
43382
|
buildEvidenceSummary,
|
|
42865
43383
|
isAutoSummaryEnabled,
|
|
42866
43384
|
normalizeBundleEntries,
|
|
42867
43385
|
getTaskStatus,
|
|
43386
|
+
evidenceCompleteFromEntries,
|
|
42868
43387
|
isEvidenceComplete,
|
|
42869
43388
|
getTaskBlockers,
|
|
42870
43389
|
buildTaskSummary,
|
|
@@ -42915,7 +43434,7 @@ function getVerdictEmoji(verdict) {
|
|
|
42915
43434
|
return getVerdictIcon(verdict);
|
|
42916
43435
|
}
|
|
42917
43436
|
async function getTaskEvidenceData(directory, taskId) {
|
|
42918
|
-
const result = await
|
|
43437
|
+
const result = await _internals14.loadEvidence(directory, taskId);
|
|
42919
43438
|
if (result.status !== "found") {
|
|
42920
43439
|
return {
|
|
42921
43440
|
hasEvidence: false,
|
|
@@ -42938,13 +43457,13 @@ async function getTaskEvidenceData(directory, taskId) {
|
|
|
42938
43457
|
};
|
|
42939
43458
|
}
|
|
42940
43459
|
async function getEvidenceListData(directory) {
|
|
42941
|
-
const taskIds = await
|
|
43460
|
+
const taskIds = await _internals14.listEvidenceTaskIds(directory);
|
|
42942
43461
|
if (taskIds.length === 0) {
|
|
42943
43462
|
return { hasEvidence: false, tasks: [] };
|
|
42944
43463
|
}
|
|
42945
43464
|
const tasks = [];
|
|
42946
43465
|
for (const taskId of taskIds) {
|
|
42947
|
-
const result = await
|
|
43466
|
+
const result = await _internals14.loadEvidence(directory, taskId);
|
|
42948
43467
|
if (result.status === "found") {
|
|
42949
43468
|
tasks.push({
|
|
42950
43469
|
taskId,
|
|
@@ -43058,10 +43577,10 @@ async function handleEvidenceSummaryCommand(directory) {
|
|
|
43058
43577
|
return lines.join(`
|
|
43059
43578
|
`);
|
|
43060
43579
|
}
|
|
43061
|
-
var
|
|
43580
|
+
var _internals14;
|
|
43062
43581
|
var init_evidence_service = __esm(() => {
|
|
43063
43582
|
init_manager2();
|
|
43064
|
-
|
|
43583
|
+
_internals14 = {
|
|
43065
43584
|
loadEvidence,
|
|
43066
43585
|
listEvidenceTaskIds
|
|
43067
43586
|
};
|
|
@@ -43112,12 +43631,12 @@ var init_export = __esm(() => {
|
|
|
43112
43631
|
|
|
43113
43632
|
// src/full-auto/state.ts
|
|
43114
43633
|
import * as fs11 from "fs";
|
|
43115
|
-
import * as
|
|
43634
|
+
import * as path26 from "path";
|
|
43116
43635
|
function nowISO() {
|
|
43117
43636
|
return new Date().toISOString();
|
|
43118
43637
|
}
|
|
43119
43638
|
function ensureSwarmDir(directory) {
|
|
43120
|
-
const swarmDir =
|
|
43639
|
+
const swarmDir = path26.resolve(directory, ".swarm");
|
|
43121
43640
|
if (!fs11.existsSync(swarmDir)) {
|
|
43122
43641
|
fs11.mkdirSync(swarmDir, { recursive: true });
|
|
43123
43642
|
}
|
|
@@ -43468,7 +43987,7 @@ function extractCurrentPhaseFromPlan2(plan) {
|
|
|
43468
43987
|
if (!plan) {
|
|
43469
43988
|
return { currentPhase: null, currentTask: null, incompleteTasks: [] };
|
|
43470
43989
|
}
|
|
43471
|
-
if (!
|
|
43990
|
+
if (!_internals15.validatePlanPhases(plan)) {
|
|
43472
43991
|
return { currentPhase: null, currentTask: null, incompleteTasks: [] };
|
|
43473
43992
|
}
|
|
43474
43993
|
let currentPhase = null;
|
|
@@ -43610,9 +44129,9 @@ function extractPhaseMetrics(content) {
|
|
|
43610
44129
|
async function getHandoffData(directory) {
|
|
43611
44130
|
const now = new Date().toISOString();
|
|
43612
44131
|
const sessionContent = await readSwarmFileAsync(directory, "session/state.json");
|
|
43613
|
-
const sessionState =
|
|
44132
|
+
const sessionState = _internals15.parseSessionState(sessionContent);
|
|
43614
44133
|
const plan = await loadPlanJsonOnly(directory);
|
|
43615
|
-
const planInfo =
|
|
44134
|
+
const planInfo = _internals15.extractCurrentPhaseFromPlan(plan);
|
|
43616
44135
|
if (!plan) {
|
|
43617
44136
|
const planMdContent = await readSwarmFileAsync(directory, "plan.md");
|
|
43618
44137
|
if (planMdContent) {
|
|
@@ -43631,8 +44150,8 @@ async function getHandoffData(directory) {
|
|
|
43631
44150
|
}
|
|
43632
44151
|
}
|
|
43633
44152
|
const contextContent = await readSwarmFileAsync(directory, "context.md");
|
|
43634
|
-
const recentDecisions =
|
|
43635
|
-
const rawPhaseMetrics =
|
|
44153
|
+
const recentDecisions = _internals15.extractDecisions(contextContent);
|
|
44154
|
+
const rawPhaseMetrics = _internals15.extractPhaseMetrics(contextContent);
|
|
43636
44155
|
const phaseMetrics = sanitizeString(rawPhaseMetrics, 1000);
|
|
43637
44156
|
let delegationState = null;
|
|
43638
44157
|
if (sessionState?.delegationState) {
|
|
@@ -43796,13 +44315,13 @@ ${lines.join(`
|
|
|
43796
44315
|
`)}
|
|
43797
44316
|
\`\`\``;
|
|
43798
44317
|
}
|
|
43799
|
-
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;
|
|
43800
44319
|
var init_handoff_service = __esm(() => {
|
|
43801
44320
|
init_utils2();
|
|
43802
44321
|
init_manager();
|
|
43803
44322
|
init_utils();
|
|
43804
44323
|
RTL_OVERRIDE_PATTERN = /[\u202e\u202d\u202c\u200f]/g;
|
|
43805
|
-
|
|
44324
|
+
_internals15 = {
|
|
43806
44325
|
getHandoffData,
|
|
43807
44326
|
formatHandoffMarkdown,
|
|
43808
44327
|
formatContinuationPrompt,
|
|
@@ -43817,8 +44336,8 @@ var init_handoff_service = __esm(() => {
|
|
|
43817
44336
|
});
|
|
43818
44337
|
|
|
43819
44338
|
// src/session/snapshot-writer.ts
|
|
43820
|
-
import { closeSync as closeSync3, fsyncSync as fsyncSync2, mkdirSync as
|
|
43821
|
-
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";
|
|
43822
44341
|
function serializeAgentSession(s) {
|
|
43823
44342
|
const gateLog = {};
|
|
43824
44343
|
const rawGateLog = s.gateLog ?? new Map;
|
|
@@ -43915,8 +44434,8 @@ async function writeSnapshot(directory, state) {
|
|
|
43915
44434
|
}
|
|
43916
44435
|
const content = JSON.stringify(snapshot, null, 2);
|
|
43917
44436
|
const resolvedPath = validateSwarmPath(directory, "session/state.json");
|
|
43918
|
-
const dir =
|
|
43919
|
-
|
|
44437
|
+
const dir = path27.dirname(resolvedPath);
|
|
44438
|
+
mkdirSync11(dir, { recursive: true });
|
|
43920
44439
|
const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
43921
44440
|
await bunWrite(tempPath, content);
|
|
43922
44441
|
try {
|
|
@@ -43936,22 +44455,22 @@ async function writeSnapshot(directory, state) {
|
|
|
43936
44455
|
}
|
|
43937
44456
|
function createSnapshotWriterHook(directory) {
|
|
43938
44457
|
return (_input, _output) => {
|
|
43939
|
-
_writeInFlight = _writeInFlight.then(() =>
|
|
44458
|
+
_writeInFlight = _writeInFlight.then(() => _internals16.writeSnapshot(directory, swarmState), () => _internals16.writeSnapshot(directory, swarmState));
|
|
43940
44459
|
return _writeInFlight;
|
|
43941
44460
|
};
|
|
43942
44461
|
}
|
|
43943
44462
|
async function flushPendingSnapshot(directory) {
|
|
43944
|
-
_writeInFlight = _writeInFlight.then(() =>
|
|
44463
|
+
_writeInFlight = _writeInFlight.then(() => _internals16.writeSnapshot(directory, swarmState), () => _internals16.writeSnapshot(directory, swarmState));
|
|
43945
44464
|
await _writeInFlight;
|
|
43946
44465
|
}
|
|
43947
|
-
var _writeInFlight,
|
|
44466
|
+
var _writeInFlight, _internals16;
|
|
43948
44467
|
var init_snapshot_writer = __esm(() => {
|
|
43949
44468
|
init_utils2();
|
|
43950
44469
|
init_state();
|
|
43951
44470
|
init_utils();
|
|
43952
44471
|
init_bun_compat();
|
|
43953
44472
|
_writeInFlight = Promise.resolve();
|
|
43954
|
-
|
|
44473
|
+
_internals16 = {
|
|
43955
44474
|
writeSnapshot,
|
|
43956
44475
|
createSnapshotWriterHook,
|
|
43957
44476
|
flushPendingSnapshot
|
|
@@ -44372,9 +44891,9 @@ var init_issue = __esm(() => {
|
|
|
44372
44891
|
|
|
44373
44892
|
// src/hooks/knowledge-migrator.ts
|
|
44374
44893
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
44375
|
-
import { existsSync as existsSync17, readFileSync as
|
|
44894
|
+
import { existsSync as existsSync17, readFileSync as readFileSync13 } from "fs";
|
|
44376
44895
|
import { mkdir as mkdir7, readFile as readFile7, writeFile as writeFile8 } from "fs/promises";
|
|
44377
|
-
import * as
|
|
44896
|
+
import * as path28 from "path";
|
|
44378
44897
|
async function migrateKnowledgeToExternal(_directory, _config) {
|
|
44379
44898
|
return {
|
|
44380
44899
|
migrated: false,
|
|
@@ -44385,8 +44904,8 @@ async function migrateKnowledgeToExternal(_directory, _config) {
|
|
|
44385
44904
|
};
|
|
44386
44905
|
}
|
|
44387
44906
|
async function migrateContextToKnowledge(directory, config3) {
|
|
44388
|
-
const sentinelPath =
|
|
44389
|
-
const contextPath =
|
|
44907
|
+
const sentinelPath = path28.join(directory, ".swarm", ".knowledge-migrated");
|
|
44908
|
+
const contextPath = path28.join(directory, ".swarm", "context.md");
|
|
44390
44909
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
44391
44910
|
if (existsSync17(sentinelPath)) {
|
|
44392
44911
|
return {
|
|
@@ -44416,9 +44935,9 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
44416
44935
|
skippedReason: "empty-context"
|
|
44417
44936
|
};
|
|
44418
44937
|
}
|
|
44419
|
-
const rawEntries =
|
|
44938
|
+
const rawEntries = _internals17.parseContextMd(contextContent);
|
|
44420
44939
|
if (rawEntries.length === 0) {
|
|
44421
|
-
await
|
|
44940
|
+
await _internals17.writeSentinel(sentinelPath, 0, 0);
|
|
44422
44941
|
return {
|
|
44423
44942
|
migrated: true,
|
|
44424
44943
|
entriesMigrated: 0,
|
|
@@ -44429,10 +44948,10 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
44429
44948
|
const existing = await readKnowledge(knowledgePath);
|
|
44430
44949
|
let migrated = 0;
|
|
44431
44950
|
let dropped = 0;
|
|
44432
|
-
const projectName =
|
|
44951
|
+
const projectName = _internals17.inferProjectName(directory);
|
|
44433
44952
|
for (const raw of rawEntries) {
|
|
44434
44953
|
if (config3.validation_enabled !== false) {
|
|
44435
|
-
const category = raw.categoryHint ??
|
|
44954
|
+
const category = raw.categoryHint ?? _internals17.inferCategoryFromText(raw.text);
|
|
44436
44955
|
const result = validateLesson(raw.text, existing.map((e) => e.lesson), {
|
|
44437
44956
|
category,
|
|
44438
44957
|
scope: "global",
|
|
@@ -44452,8 +44971,8 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
44452
44971
|
const entry = {
|
|
44453
44972
|
id: randomUUID2(),
|
|
44454
44973
|
tier: "swarm",
|
|
44455
|
-
lesson:
|
|
44456
|
-
category: raw.categoryHint ??
|
|
44974
|
+
lesson: _internals17.truncateLesson(raw.text),
|
|
44975
|
+
category: raw.categoryHint ?? _internals17.inferCategoryFromText(raw.text),
|
|
44457
44976
|
tags: [...inferredTags, `migration:${raw.sourceSection}`],
|
|
44458
44977
|
scope: "global",
|
|
44459
44978
|
confidence: 0.3,
|
|
@@ -44476,7 +44995,7 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
44476
44995
|
if (migrated > 0) {
|
|
44477
44996
|
await rewriteKnowledge(knowledgePath, existing);
|
|
44478
44997
|
}
|
|
44479
|
-
await
|
|
44998
|
+
await _internals17.writeSentinel(sentinelPath, migrated, dropped);
|
|
44480
44999
|
log(`[knowledge-migrator] Migrated ${migrated} entries, dropped ${dropped}`);
|
|
44481
45000
|
return {
|
|
44482
45001
|
migrated: true,
|
|
@@ -44486,7 +45005,7 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
44486
45005
|
};
|
|
44487
45006
|
}
|
|
44488
45007
|
function parseContextMd(content) {
|
|
44489
|
-
const sections =
|
|
45008
|
+
const sections = _internals17.splitIntoSections(content);
|
|
44490
45009
|
const entries = [];
|
|
44491
45010
|
const seen = new Set;
|
|
44492
45011
|
const sectionPatterns = [
|
|
@@ -44502,7 +45021,7 @@ function parseContextMd(content) {
|
|
|
44502
45021
|
const match = sectionPatterns.find((sp) => sp.pattern.test(section.heading));
|
|
44503
45022
|
if (!match)
|
|
44504
45023
|
continue;
|
|
44505
|
-
const bullets =
|
|
45024
|
+
const bullets = _internals17.extractBullets(section.body);
|
|
44506
45025
|
for (const bullet of bullets) {
|
|
44507
45026
|
if (bullet.length < 15)
|
|
44508
45027
|
continue;
|
|
@@ -44511,9 +45030,9 @@ function parseContextMd(content) {
|
|
|
44511
45030
|
continue;
|
|
44512
45031
|
seen.add(normalized);
|
|
44513
45032
|
entries.push({
|
|
44514
|
-
text:
|
|
45033
|
+
text: _internals17.truncateLesson(bullet),
|
|
44515
45034
|
sourceSection: match.sourceSection,
|
|
44516
|
-
categoryHint:
|
|
45035
|
+
categoryHint: _internals17.inferCategoryFromText(bullet)
|
|
44517
45036
|
});
|
|
44518
45037
|
}
|
|
44519
45038
|
}
|
|
@@ -44582,16 +45101,16 @@ function truncateLesson(text) {
|
|
|
44582
45101
|
return `${text.slice(0, 277)}...`;
|
|
44583
45102
|
}
|
|
44584
45103
|
function inferProjectName(directory) {
|
|
44585
|
-
const packageJsonPath =
|
|
45104
|
+
const packageJsonPath = path28.join(directory, "package.json");
|
|
44586
45105
|
if (existsSync17(packageJsonPath)) {
|
|
44587
45106
|
try {
|
|
44588
|
-
const pkg = JSON.parse(
|
|
45107
|
+
const pkg = JSON.parse(readFileSync13(packageJsonPath, "utf-8"));
|
|
44589
45108
|
if (pkg.name && typeof pkg.name === "string") {
|
|
44590
45109
|
return pkg.name;
|
|
44591
45110
|
}
|
|
44592
45111
|
} catch {}
|
|
44593
45112
|
}
|
|
44594
|
-
return
|
|
45113
|
+
return path28.basename(directory);
|
|
44595
45114
|
}
|
|
44596
45115
|
async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
44597
45116
|
const sentinel = {
|
|
@@ -44603,15 +45122,15 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
|
44603
45122
|
schema_version: 1,
|
|
44604
45123
|
migration_tool: "knowledge-migrator.ts"
|
|
44605
45124
|
};
|
|
44606
|
-
await mkdir7(
|
|
45125
|
+
await mkdir7(path28.dirname(sentinelPath), { recursive: true });
|
|
44607
45126
|
await writeFile8(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
|
|
44608
45127
|
}
|
|
44609
|
-
var
|
|
45128
|
+
var _internals17;
|
|
44610
45129
|
var init_knowledge_migrator = __esm(() => {
|
|
44611
45130
|
init_logger();
|
|
44612
45131
|
init_knowledge_store();
|
|
44613
45132
|
init_knowledge_validator();
|
|
44614
|
-
|
|
45133
|
+
_internals17 = {
|
|
44615
45134
|
migrateContextToKnowledge,
|
|
44616
45135
|
migrateKnowledgeToExternal,
|
|
44617
45136
|
parseContextMd,
|
|
@@ -44625,7 +45144,7 @@ var init_knowledge_migrator = __esm(() => {
|
|
|
44625
45144
|
});
|
|
44626
45145
|
|
|
44627
45146
|
// src/commands/knowledge.ts
|
|
44628
|
-
import { join as
|
|
45147
|
+
import { join as join26 } from "path";
|
|
44629
45148
|
function resolveEntryByPrefix(entries, inputId) {
|
|
44630
45149
|
const exact = entries.find((e) => e.id === inputId);
|
|
44631
45150
|
if (exact)
|
|
@@ -44676,7 +45195,7 @@ async function handleKnowledgeRestoreCommand(directory, args) {
|
|
|
44676
45195
|
return "Invalid entry ID. IDs must be 1-64 characters: letters, digits, hyphens, underscores only.";
|
|
44677
45196
|
}
|
|
44678
45197
|
try {
|
|
44679
|
-
const quarantinePath =
|
|
45198
|
+
const quarantinePath = join26(directory, ".swarm", "knowledge-quarantined.jsonl");
|
|
44680
45199
|
const entries = await readKnowledge(quarantinePath);
|
|
44681
45200
|
const resolved = resolveEntryByPrefix(entries, inputId);
|
|
44682
45201
|
if ("error" in resolved) {
|
|
@@ -44748,9 +45267,9 @@ var init_knowledge = __esm(() => {
|
|
|
44748
45267
|
|
|
44749
45268
|
// src/services/plan-service.ts
|
|
44750
45269
|
async function getPlanData(directory, phaseArg) {
|
|
44751
|
-
const plan = await
|
|
45270
|
+
const plan = await _internals18.loadPlanJsonOnly(directory);
|
|
44752
45271
|
if (plan) {
|
|
44753
|
-
const fullMarkdown =
|
|
45272
|
+
const fullMarkdown = _internals18.derivePlanMarkdown(plan);
|
|
44754
45273
|
if (phaseArg === undefined || phaseArg === null || phaseArg === "") {
|
|
44755
45274
|
return {
|
|
44756
45275
|
hasPlan: true,
|
|
@@ -44793,7 +45312,7 @@ async function getPlanData(directory, phaseArg) {
|
|
|
44793
45312
|
isLegacy: false
|
|
44794
45313
|
};
|
|
44795
45314
|
}
|
|
44796
|
-
const planContent = await
|
|
45315
|
+
const planContent = await _internals18.readSwarmFileAsync(directory, "plan.md");
|
|
44797
45316
|
if (!planContent) {
|
|
44798
45317
|
return {
|
|
44799
45318
|
hasPlan: false,
|
|
@@ -44889,11 +45408,11 @@ async function handlePlanCommand(directory, args) {
|
|
|
44889
45408
|
const planData = await getPlanData(directory, phaseArg);
|
|
44890
45409
|
return formatPlanMarkdown(planData);
|
|
44891
45410
|
}
|
|
44892
|
-
var
|
|
45411
|
+
var _internals18;
|
|
44893
45412
|
var init_plan_service = __esm(() => {
|
|
44894
45413
|
init_utils2();
|
|
44895
45414
|
init_manager();
|
|
44896
|
-
|
|
45415
|
+
_internals18 = {
|
|
44897
45416
|
loadPlanJsonOnly,
|
|
44898
45417
|
derivePlanMarkdown,
|
|
44899
45418
|
readSwarmFileAsync
|
|
@@ -45131,7 +45650,7 @@ var init_path_security = () => {};
|
|
|
45131
45650
|
|
|
45132
45651
|
// src/tools/lint.ts
|
|
45133
45652
|
import * as fs12 from "fs";
|
|
45134
|
-
import * as
|
|
45653
|
+
import * as path29 from "path";
|
|
45135
45654
|
function validateArgs(args) {
|
|
45136
45655
|
if (typeof args !== "object" || args === null)
|
|
45137
45656
|
return false;
|
|
@@ -45142,9 +45661,9 @@ function validateArgs(args) {
|
|
|
45142
45661
|
}
|
|
45143
45662
|
function getLinterCommand(linter, mode, projectDir) {
|
|
45144
45663
|
const isWindows = process.platform === "win32";
|
|
45145
|
-
const binDir =
|
|
45146
|
-
const biomeBin = isWindows ?
|
|
45147
|
-
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");
|
|
45148
45667
|
switch (linter) {
|
|
45149
45668
|
case "biome":
|
|
45150
45669
|
if (mode === "fix") {
|
|
@@ -45160,7 +45679,7 @@ function getLinterCommand(linter, mode, projectDir) {
|
|
|
45160
45679
|
}
|
|
45161
45680
|
function getAdditionalLinterCommand(linter, mode, cwd) {
|
|
45162
45681
|
const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
|
|
45163
|
-
const gradlew = fs12.existsSync(
|
|
45682
|
+
const gradlew = fs12.existsSync(path29.join(cwd, gradlewName)) ? path29.join(cwd, gradlewName) : null;
|
|
45164
45683
|
switch (linter) {
|
|
45165
45684
|
case "ruff":
|
|
45166
45685
|
return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
|
|
@@ -45194,10 +45713,10 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
|
|
|
45194
45713
|
}
|
|
45195
45714
|
}
|
|
45196
45715
|
function detectRuff(cwd) {
|
|
45197
|
-
if (fs12.existsSync(
|
|
45716
|
+
if (fs12.existsSync(path29.join(cwd, "ruff.toml")))
|
|
45198
45717
|
return isCommandAvailable("ruff");
|
|
45199
45718
|
try {
|
|
45200
|
-
const pyproject =
|
|
45719
|
+
const pyproject = path29.join(cwd, "pyproject.toml");
|
|
45201
45720
|
if (fs12.existsSync(pyproject)) {
|
|
45202
45721
|
const content = fs12.readFileSync(pyproject, "utf-8");
|
|
45203
45722
|
if (content.includes("[tool.ruff]"))
|
|
@@ -45207,19 +45726,19 @@ function detectRuff(cwd) {
|
|
|
45207
45726
|
return false;
|
|
45208
45727
|
}
|
|
45209
45728
|
function detectClippy(cwd) {
|
|
45210
|
-
return fs12.existsSync(
|
|
45729
|
+
return fs12.existsSync(path29.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
|
|
45211
45730
|
}
|
|
45212
45731
|
function detectGolangciLint(cwd) {
|
|
45213
|
-
return fs12.existsSync(
|
|
45732
|
+
return fs12.existsSync(path29.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
|
|
45214
45733
|
}
|
|
45215
45734
|
function detectCheckstyle(cwd) {
|
|
45216
|
-
const hasMaven = fs12.existsSync(
|
|
45217
|
-
const hasGradle = fs12.existsSync(
|
|
45218
|
-
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"));
|
|
45219
45738
|
return (hasMaven || hasGradle) && hasBinary;
|
|
45220
45739
|
}
|
|
45221
45740
|
function detectKtlint(cwd) {
|
|
45222
|
-
const hasKotlin = fs12.existsSync(
|
|
45741
|
+
const hasKotlin = fs12.existsSync(path29.join(cwd, "build.gradle.kts")) || fs12.existsSync(path29.join(cwd, "build.gradle")) || (() => {
|
|
45223
45742
|
try {
|
|
45224
45743
|
return fs12.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
|
|
45225
45744
|
} catch {
|
|
@@ -45238,11 +45757,11 @@ function detectDotnetFormat(cwd) {
|
|
|
45238
45757
|
}
|
|
45239
45758
|
}
|
|
45240
45759
|
function detectCppcheck(cwd) {
|
|
45241
|
-
if (fs12.existsSync(
|
|
45760
|
+
if (fs12.existsSync(path29.join(cwd, "CMakeLists.txt"))) {
|
|
45242
45761
|
return isCommandAvailable("cppcheck");
|
|
45243
45762
|
}
|
|
45244
45763
|
try {
|
|
45245
|
-
const dirsToCheck = [cwd,
|
|
45764
|
+
const dirsToCheck = [cwd, path29.join(cwd, "src")];
|
|
45246
45765
|
const hasCpp = dirsToCheck.some((dir) => {
|
|
45247
45766
|
try {
|
|
45248
45767
|
return fs12.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
|
|
@@ -45256,13 +45775,13 @@ function detectCppcheck(cwd) {
|
|
|
45256
45775
|
}
|
|
45257
45776
|
}
|
|
45258
45777
|
function detectSwiftlint(cwd) {
|
|
45259
|
-
return fs12.existsSync(
|
|
45778
|
+
return fs12.existsSync(path29.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
|
|
45260
45779
|
}
|
|
45261
45780
|
function detectDartAnalyze(cwd) {
|
|
45262
|
-
return fs12.existsSync(
|
|
45781
|
+
return fs12.existsSync(path29.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
45263
45782
|
}
|
|
45264
45783
|
function detectRubocop(cwd) {
|
|
45265
|
-
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"));
|
|
45266
45785
|
}
|
|
45267
45786
|
function detectAdditionalLinter(cwd) {
|
|
45268
45787
|
if (detectRuff(cwd))
|
|
@@ -45290,10 +45809,10 @@ function detectAdditionalLinter(cwd) {
|
|
|
45290
45809
|
function findBinInAncestors(startDir, binName) {
|
|
45291
45810
|
let dir = startDir;
|
|
45292
45811
|
while (true) {
|
|
45293
|
-
const candidate =
|
|
45812
|
+
const candidate = path29.join(dir, "node_modules", ".bin", binName);
|
|
45294
45813
|
if (fs12.existsSync(candidate))
|
|
45295
45814
|
return candidate;
|
|
45296
|
-
const parent =
|
|
45815
|
+
const parent = path29.dirname(dir);
|
|
45297
45816
|
if (parent === dir)
|
|
45298
45817
|
break;
|
|
45299
45818
|
dir = parent;
|
|
@@ -45302,10 +45821,10 @@ function findBinInAncestors(startDir, binName) {
|
|
|
45302
45821
|
}
|
|
45303
45822
|
function findBinInEnvPath(binName) {
|
|
45304
45823
|
const searchPath = process.env.PATH ?? "";
|
|
45305
|
-
for (const dir of searchPath.split(
|
|
45824
|
+
for (const dir of searchPath.split(path29.delimiter)) {
|
|
45306
45825
|
if (!dir)
|
|
45307
45826
|
continue;
|
|
45308
|
-
const candidate =
|
|
45827
|
+
const candidate = path29.join(dir, binName);
|
|
45309
45828
|
if (fs12.existsSync(candidate))
|
|
45310
45829
|
return candidate;
|
|
45311
45830
|
}
|
|
@@ -45318,13 +45837,13 @@ async function detectAvailableLinter(directory) {
|
|
|
45318
45837
|
return null;
|
|
45319
45838
|
const projectDir = directory;
|
|
45320
45839
|
const isWindows = process.platform === "win32";
|
|
45321
|
-
const biomeBin = isWindows ?
|
|
45322
|
-
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");
|
|
45323
45842
|
const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
|
|
45324
45843
|
if (localResult)
|
|
45325
45844
|
return localResult;
|
|
45326
|
-
const biomeAncestor = findBinInAncestors(
|
|
45327
|
-
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");
|
|
45328
45847
|
if (biomeAncestor || eslintAncestor) {
|
|
45329
45848
|
return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
|
|
45330
45849
|
}
|
|
@@ -45483,7 +46002,7 @@ async function runAdditionalLint(linter, mode, cwd) {
|
|
|
45483
46002
|
};
|
|
45484
46003
|
}
|
|
45485
46004
|
}
|
|
45486
|
-
var MAX_OUTPUT_BYTES = 512000, MAX_COMMAND_LENGTH = 500, lint,
|
|
46005
|
+
var MAX_OUTPUT_BYTES = 512000, MAX_COMMAND_LENGTH = 500, lint, _internals19;
|
|
45487
46006
|
var init_lint = __esm(() => {
|
|
45488
46007
|
init_zod();
|
|
45489
46008
|
init_discovery();
|
|
@@ -45515,15 +46034,15 @@ var init_lint = __esm(() => {
|
|
|
45515
46034
|
}
|
|
45516
46035
|
const { mode } = args;
|
|
45517
46036
|
const cwd = directory;
|
|
45518
|
-
const linter = await
|
|
46037
|
+
const linter = await _internals19.detectAvailableLinter(directory);
|
|
45519
46038
|
if (linter) {
|
|
45520
|
-
const result = await
|
|
46039
|
+
const result = await _internals19.runLint(linter, mode, directory);
|
|
45521
46040
|
return JSON.stringify(result, null, 2);
|
|
45522
46041
|
}
|
|
45523
|
-
const additionalLinter =
|
|
46042
|
+
const additionalLinter = _internals19.detectAdditionalLinter(cwd);
|
|
45524
46043
|
if (additionalLinter) {
|
|
45525
46044
|
warn(`[lint] Using ${additionalLinter} linter for this project`);
|
|
45526
|
-
const result = await
|
|
46045
|
+
const result = await _internals19.runAdditionalLint(additionalLinter, mode, cwd);
|
|
45527
46046
|
return JSON.stringify(result, null, 2);
|
|
45528
46047
|
}
|
|
45529
46048
|
const errorResult = {
|
|
@@ -45537,7 +46056,7 @@ For Rust: rustup component add clippy`
|
|
|
45537
46056
|
return JSON.stringify(errorResult, null, 2);
|
|
45538
46057
|
}
|
|
45539
46058
|
});
|
|
45540
|
-
|
|
46059
|
+
_internals19 = {
|
|
45541
46060
|
detectAvailableLinter,
|
|
45542
46061
|
runLint,
|
|
45543
46062
|
detectAdditionalLinter,
|
|
@@ -45547,7 +46066,7 @@ For Rust: rustup component add clippy`
|
|
|
45547
46066
|
|
|
45548
46067
|
// src/tools/secretscan.ts
|
|
45549
46068
|
import * as fs13 from "fs";
|
|
45550
|
-
import * as
|
|
46069
|
+
import * as path30 from "path";
|
|
45551
46070
|
function calculateShannonEntropy(str) {
|
|
45552
46071
|
if (str.length === 0)
|
|
45553
46072
|
return 0;
|
|
@@ -45595,7 +46114,7 @@ function isGlobOrPathPattern(pattern) {
|
|
|
45595
46114
|
return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
|
|
45596
46115
|
}
|
|
45597
46116
|
function loadSecretScanIgnore(scanDir) {
|
|
45598
|
-
const ignorePath =
|
|
46117
|
+
const ignorePath = path30.join(scanDir, ".secretscanignore");
|
|
45599
46118
|
try {
|
|
45600
46119
|
if (!fs13.existsSync(ignorePath))
|
|
45601
46120
|
return [];
|
|
@@ -45618,7 +46137,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
|
|
|
45618
46137
|
if (exactNames.has(entry))
|
|
45619
46138
|
return true;
|
|
45620
46139
|
for (const pattern of globPatterns) {
|
|
45621
|
-
if (
|
|
46140
|
+
if (path30.matchesGlob(relPath, pattern))
|
|
45622
46141
|
return true;
|
|
45623
46142
|
}
|
|
45624
46143
|
return false;
|
|
@@ -45639,7 +46158,7 @@ function validateDirectoryInput(dir) {
|
|
|
45639
46158
|
return null;
|
|
45640
46159
|
}
|
|
45641
46160
|
function isBinaryFile(filePath, buffer) {
|
|
45642
|
-
const ext =
|
|
46161
|
+
const ext = path30.extname(filePath).toLowerCase();
|
|
45643
46162
|
if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
45644
46163
|
return true;
|
|
45645
46164
|
}
|
|
@@ -45775,9 +46294,9 @@ function isSymlinkLoop(realPath, visited) {
|
|
|
45775
46294
|
return false;
|
|
45776
46295
|
}
|
|
45777
46296
|
function isPathWithinScope(realPath, scanDir) {
|
|
45778
|
-
const resolvedScanDir =
|
|
45779
|
-
const resolvedRealPath =
|
|
45780
|
-
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}\\`);
|
|
45781
46300
|
}
|
|
45782
46301
|
function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
|
|
45783
46302
|
skippedDirs: 0,
|
|
@@ -45803,8 +46322,8 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
45803
46322
|
return a.localeCompare(b);
|
|
45804
46323
|
});
|
|
45805
46324
|
for (const entry of entries) {
|
|
45806
|
-
const fullPath =
|
|
45807
|
-
const relPath =
|
|
46325
|
+
const fullPath = path30.join(dir, entry);
|
|
46326
|
+
const relPath = path30.relative(scanDir, fullPath).replace(/\\/g, "/");
|
|
45808
46327
|
if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
|
|
45809
46328
|
stats.skippedDirs++;
|
|
45810
46329
|
continue;
|
|
@@ -45839,7 +46358,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
45839
46358
|
const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
|
|
45840
46359
|
files.push(...subFiles);
|
|
45841
46360
|
} else if (lstat.isFile()) {
|
|
45842
|
-
const ext =
|
|
46361
|
+
const ext = path30.extname(fullPath).toLowerCase();
|
|
45843
46362
|
if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
45844
46363
|
files.push(fullPath);
|
|
45845
46364
|
} else {
|
|
@@ -45851,7 +46370,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
45851
46370
|
}
|
|
45852
46371
|
async function runSecretscan(directory) {
|
|
45853
46372
|
try {
|
|
45854
|
-
const result = await
|
|
46373
|
+
const result = await _internals20.secretscan.execute({ directory }, {});
|
|
45855
46374
|
const jsonStr = typeof result === "string" ? result : result.output;
|
|
45856
46375
|
return JSON.parse(jsonStr);
|
|
45857
46376
|
} catch (e) {
|
|
@@ -45866,7 +46385,7 @@ async function runSecretscan(directory) {
|
|
|
45866
46385
|
return errorResult;
|
|
45867
46386
|
}
|
|
45868
46387
|
}
|
|
45869
|
-
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;
|
|
45870
46389
|
var init_secretscan = __esm(() => {
|
|
45871
46390
|
init_zod();
|
|
45872
46391
|
init_path_security();
|
|
@@ -46099,7 +46618,7 @@ var init_secretscan = __esm(() => {
|
|
|
46099
46618
|
}
|
|
46100
46619
|
}
|
|
46101
46620
|
try {
|
|
46102
|
-
const _scanDirRaw =
|
|
46621
|
+
const _scanDirRaw = path30.resolve(directory);
|
|
46103
46622
|
const scanDir = (() => {
|
|
46104
46623
|
try {
|
|
46105
46624
|
return fs13.realpathSync(_scanDirRaw);
|
|
@@ -46238,7 +46757,7 @@ var init_secretscan = __esm(() => {
|
|
|
46238
46757
|
}
|
|
46239
46758
|
}
|
|
46240
46759
|
});
|
|
46241
|
-
|
|
46760
|
+
_internals20 = {
|
|
46242
46761
|
secretscan,
|
|
46243
46762
|
runSecretscan
|
|
46244
46763
|
};
|
|
@@ -46246,7 +46765,7 @@ var init_secretscan = __esm(() => {
|
|
|
46246
46765
|
|
|
46247
46766
|
// src/lang/default-backend.ts
|
|
46248
46767
|
import * as fs14 from "fs";
|
|
46249
|
-
import * as
|
|
46768
|
+
import * as path31 from "path";
|
|
46250
46769
|
function detectFileExists(dir, pattern) {
|
|
46251
46770
|
if (pattern.includes("*") || pattern.includes("?")) {
|
|
46252
46771
|
try {
|
|
@@ -46258,7 +46777,7 @@ function detectFileExists(dir, pattern) {
|
|
|
46258
46777
|
}
|
|
46259
46778
|
}
|
|
46260
46779
|
try {
|
|
46261
|
-
fs14.accessSync(
|
|
46780
|
+
fs14.accessSync(path31.join(dir, pattern));
|
|
46262
46781
|
return true;
|
|
46263
46782
|
} catch {
|
|
46264
46783
|
return false;
|
|
@@ -46386,8 +46905,8 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
|
|
|
46386
46905
|
return ["mvn", "test"];
|
|
46387
46906
|
case "gradle": {
|
|
46388
46907
|
const isWindows = process.platform === "win32";
|
|
46389
|
-
const hasGradlewBat = fs14.existsSync(
|
|
46390
|
-
const hasGradlew = fs14.existsSync(
|
|
46908
|
+
const hasGradlewBat = fs14.existsSync(path31.join(dir, "gradlew.bat"));
|
|
46909
|
+
const hasGradlew = fs14.existsSync(path31.join(dir, "gradlew"));
|
|
46391
46910
|
if (hasGradlewBat && isWindows)
|
|
46392
46911
|
return ["gradlew.bat", "test"];
|
|
46393
46912
|
if (hasGradlew)
|
|
@@ -46404,7 +46923,7 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
|
|
|
46404
46923
|
"cmake-build-release",
|
|
46405
46924
|
"out"
|
|
46406
46925
|
];
|
|
46407
|
-
const actualBuildDir = buildDirCandidates.find((d) => fs14.existsSync(
|
|
46926
|
+
const actualBuildDir = buildDirCandidates.find((d) => fs14.existsSync(path31.join(dir, d, "CMakeCache.txt"))) ?? "build";
|
|
46408
46927
|
return ["ctest", "--test-dir", actualBuildDir];
|
|
46409
46928
|
}
|
|
46410
46929
|
case "swift-test":
|
|
@@ -46691,17 +47210,17 @@ async function defaultSelectBuildCommand(profile, dir) {
|
|
|
46691
47210
|
return null;
|
|
46692
47211
|
}
|
|
46693
47212
|
async function defaultTestFilesFor(profile, sourceFile, dir) {
|
|
46694
|
-
const ext =
|
|
47213
|
+
const ext = path31.extname(sourceFile);
|
|
46695
47214
|
if (!profile.extensions.includes(ext))
|
|
46696
47215
|
return [];
|
|
46697
|
-
const base =
|
|
46698
|
-
const rel =
|
|
46699
|
-
const relDir =
|
|
47216
|
+
const base = path31.basename(sourceFile, ext);
|
|
47217
|
+
const rel = path31.relative(dir, sourceFile);
|
|
47218
|
+
const relDir = path31.dirname(rel);
|
|
46700
47219
|
const stripSrc = relDir.replace(/^src(\/|\\)/, "");
|
|
46701
47220
|
const candidates = new Set;
|
|
46702
47221
|
for (const tDir of ["tests", "test", "__tests__", "spec"]) {
|
|
46703
47222
|
for (const suffix of ["", "_test", ".test", "_spec", ".spec"]) {
|
|
46704
|
-
candidates.add(
|
|
47223
|
+
candidates.add(path31.join(dir, tDir, stripSrc, `${base}${suffix}${ext}`));
|
|
46705
47224
|
}
|
|
46706
47225
|
}
|
|
46707
47226
|
const existing = [];
|
|
@@ -46742,7 +47261,7 @@ var init_default_backend = __esm(() => {
|
|
|
46742
47261
|
|
|
46743
47262
|
// src/lang/backends/go.ts
|
|
46744
47263
|
import * as fs15 from "fs";
|
|
46745
|
-
import * as
|
|
47264
|
+
import * as path32 from "path";
|
|
46746
47265
|
function extractImports(_sourceFile, source) {
|
|
46747
47266
|
const out = new Set;
|
|
46748
47267
|
IMPORT_REGEX_SINGLE.lastIndex = 0;
|
|
@@ -46768,7 +47287,7 @@ function extractImports(_sourceFile, source) {
|
|
|
46768
47287
|
async function selectFramework(dir) {
|
|
46769
47288
|
let content;
|
|
46770
47289
|
try {
|
|
46771
|
-
content = fs15.readFileSync(
|
|
47290
|
+
content = fs15.readFileSync(path32.join(dir, "go.mod"), "utf-8");
|
|
46772
47291
|
} catch {
|
|
46773
47292
|
return null;
|
|
46774
47293
|
}
|
|
@@ -46789,16 +47308,16 @@ async function selectFramework(dir) {
|
|
|
46789
47308
|
async function selectEntryPoints(dir) {
|
|
46790
47309
|
const points = [];
|
|
46791
47310
|
try {
|
|
46792
|
-
fs15.accessSync(
|
|
47311
|
+
fs15.accessSync(path32.join(dir, "main.go"));
|
|
46793
47312
|
points.push("main.go");
|
|
46794
47313
|
} catch {}
|
|
46795
47314
|
try {
|
|
46796
|
-
const cmdDir =
|
|
47315
|
+
const cmdDir = path32.join(dir, "cmd");
|
|
46797
47316
|
const subdirs = fs15.readdirSync(cmdDir, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
46798
47317
|
for (const sub of subdirs) {
|
|
46799
|
-
const main =
|
|
47318
|
+
const main = path32.join("cmd", sub.name, "main.go");
|
|
46800
47319
|
try {
|
|
46801
|
-
fs15.accessSync(
|
|
47320
|
+
fs15.accessSync(path32.join(dir, main));
|
|
46802
47321
|
points.push(main);
|
|
46803
47322
|
} catch {}
|
|
46804
47323
|
}
|
|
@@ -46817,19 +47336,19 @@ function buildGoBackend() {
|
|
|
46817
47336
|
selectEntryPoints
|
|
46818
47337
|
};
|
|
46819
47338
|
}
|
|
46820
|
-
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;
|
|
46821
47340
|
var init_go = __esm(() => {
|
|
46822
47341
|
init_default_backend();
|
|
46823
47342
|
init_profiles();
|
|
46824
47343
|
IMPORT_REGEX_SINGLE = /^\s*import\s+(?:[a-zA-Z_.][a-zA-Z0-9_]*\s+)?"([^"]+)"/gm;
|
|
46825
47344
|
IMPORT_REGEX_GROUP = /^\s*import\s*\(([\s\S]*?)\)/gm;
|
|
46826
47345
|
IMPORT_REGEX_GROUP_LINE = /(?:[a-zA-Z_.][a-zA-Z0-9_]*\s+)?"([^"]+)"/g;
|
|
46827
|
-
|
|
47346
|
+
_internals21 = { extractImports };
|
|
46828
47347
|
});
|
|
46829
47348
|
|
|
46830
47349
|
// src/lang/backends/python.ts
|
|
46831
47350
|
import * as fs16 from "fs";
|
|
46832
|
-
import * as
|
|
47351
|
+
import * as path33 from "path";
|
|
46833
47352
|
function parseImportTargets(rawTargets) {
|
|
46834
47353
|
const cleaned = rawTargets.replace(/[()]/g, "").split(`
|
|
46835
47354
|
`).map((line) => line.replace(/#.*$/, "").replace(/\\\s*$/, "")).join(" ");
|
|
@@ -46889,7 +47408,7 @@ async function selectFramework2(dir) {
|
|
|
46889
47408
|
];
|
|
46890
47409
|
for (const candidate of ["pyproject.toml", "requirements.txt", "setup.py"]) {
|
|
46891
47410
|
try {
|
|
46892
|
-
const content = fs16.readFileSync(
|
|
47411
|
+
const content = fs16.readFileSync(path33.join(dir, candidate), "utf-8");
|
|
46893
47412
|
const lower = content.toLowerCase();
|
|
46894
47413
|
for (const [pkg, name] of candidates) {
|
|
46895
47414
|
if (lower.includes(pkg)) {
|
|
@@ -46903,7 +47422,7 @@ async function selectFramework2(dir) {
|
|
|
46903
47422
|
async function selectEntryPoints2(dir) {
|
|
46904
47423
|
const points = new Set;
|
|
46905
47424
|
try {
|
|
46906
|
-
const content = fs16.readFileSync(
|
|
47425
|
+
const content = fs16.readFileSync(path33.join(dir, "pyproject.toml"), "utf-8");
|
|
46907
47426
|
const scriptsBlock = content.match(/\[project\.scripts\][\s\S]*?(?=\n\[|$)/);
|
|
46908
47427
|
if (scriptsBlock) {
|
|
46909
47428
|
for (const line of scriptsBlock[0].split(`
|
|
@@ -46918,7 +47437,7 @@ async function selectEntryPoints2(dir) {
|
|
|
46918
47437
|
} catch {}
|
|
46919
47438
|
for (const name of ["manage.py", "main.py", "app.py", "__main__.py"]) {
|
|
46920
47439
|
try {
|
|
46921
|
-
fs16.accessSync(
|
|
47440
|
+
fs16.accessSync(path33.join(dir, name));
|
|
46922
47441
|
points.add(name);
|
|
46923
47442
|
} catch {}
|
|
46924
47443
|
}
|
|
@@ -46936,18 +47455,18 @@ function buildPythonBackend() {
|
|
|
46936
47455
|
selectEntryPoints: selectEntryPoints2
|
|
46937
47456
|
};
|
|
46938
47457
|
}
|
|
46939
|
-
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;
|
|
46940
47459
|
var init_python = __esm(() => {
|
|
46941
47460
|
init_default_backend();
|
|
46942
47461
|
init_profiles();
|
|
46943
47462
|
IMPORT_REGEX_FROM_WITH_TARGETS = /^\s*from\s+(\.*[\w.]*)\s+import\s+(\([^)]*\)|[^\n#]+)/gm;
|
|
46944
47463
|
IMPORT_REGEX_IMPORT = /^\s*import\s+([^\n#]+)/gm;
|
|
46945
|
-
|
|
47464
|
+
_internals22 = { extractImports: extractImports2 };
|
|
46946
47465
|
});
|
|
46947
47466
|
|
|
46948
47467
|
// src/test-impact/analyzer.ts
|
|
46949
47468
|
import fs17 from "fs";
|
|
46950
|
-
import
|
|
47469
|
+
import path34 from "path";
|
|
46951
47470
|
function normalizePath(p) {
|
|
46952
47471
|
return p.replace(/\\/g, "/");
|
|
46953
47472
|
}
|
|
@@ -46968,8 +47487,8 @@ function resolveRelativeImport(fromDir, importPath) {
|
|
|
46968
47487
|
if (!importPath.startsWith(".")) {
|
|
46969
47488
|
return null;
|
|
46970
47489
|
}
|
|
46971
|
-
const resolved =
|
|
46972
|
-
if (
|
|
47490
|
+
const resolved = path34.resolve(fromDir, importPath);
|
|
47491
|
+
if (path34.extname(resolved)) {
|
|
46973
47492
|
if (fs17.existsSync(resolved) && fs17.statSync(resolved).isFile()) {
|
|
46974
47493
|
return normalizePath(resolved);
|
|
46975
47494
|
}
|
|
@@ -46989,20 +47508,20 @@ function resolvePythonImport(fromDir, module) {
|
|
|
46989
47508
|
const leadingDots = module.match(/^\.+/)?.[0].length ?? 0;
|
|
46990
47509
|
let baseDir = fromDir;
|
|
46991
47510
|
for (let i = 1;i < leadingDots; i++) {
|
|
46992
|
-
baseDir =
|
|
47511
|
+
baseDir = path34.dirname(baseDir);
|
|
46993
47512
|
}
|
|
46994
47513
|
const rest = module.slice(leadingDots);
|
|
46995
47514
|
if (rest.length === 0) {
|
|
46996
|
-
const initPath =
|
|
47515
|
+
const initPath = path34.join(baseDir, "__init__.py");
|
|
46997
47516
|
if (fs17.existsSync(initPath) && fs17.statSync(initPath).isFile()) {
|
|
46998
47517
|
return normalizePath(initPath);
|
|
46999
47518
|
}
|
|
47000
47519
|
return null;
|
|
47001
47520
|
}
|
|
47002
|
-
const subpath = rest.replace(/\./g,
|
|
47521
|
+
const subpath = rest.replace(/\./g, path34.sep);
|
|
47003
47522
|
const candidates = [
|
|
47004
|
-
`${
|
|
47005
|
-
|
|
47523
|
+
`${path34.join(baseDir, subpath)}.py`,
|
|
47524
|
+
path34.join(baseDir, subpath, "__init__.py")
|
|
47006
47525
|
];
|
|
47007
47526
|
for (const c of candidates) {
|
|
47008
47527
|
if (fs17.existsSync(c) && fs17.statSync(c).isFile())
|
|
@@ -47011,7 +47530,7 @@ function resolvePythonImport(fromDir, module) {
|
|
|
47011
47530
|
return null;
|
|
47012
47531
|
}
|
|
47013
47532
|
function findGoModule(fromDir) {
|
|
47014
|
-
const resolved =
|
|
47533
|
+
const resolved = path34.resolve(fromDir);
|
|
47015
47534
|
let cur = resolved;
|
|
47016
47535
|
const walked = [];
|
|
47017
47536
|
for (let i = 0;i < 16; i++) {
|
|
@@ -47023,7 +47542,7 @@ function findGoModule(fromDir) {
|
|
|
47023
47542
|
}
|
|
47024
47543
|
walked.push(cur);
|
|
47025
47544
|
try {
|
|
47026
|
-
const goMod =
|
|
47545
|
+
const goMod = path34.join(cur, "go.mod");
|
|
47027
47546
|
const content = fs17.readFileSync(goMod, "utf-8");
|
|
47028
47547
|
const moduleMatch = content.match(/^\s*module\s+"?([^"\s/]+(?:\/[^"\s]+)*)"?/m);
|
|
47029
47548
|
if (moduleMatch) {
|
|
@@ -47034,10 +47553,10 @@ function findGoModule(fromDir) {
|
|
|
47034
47553
|
}
|
|
47035
47554
|
} catch {}
|
|
47036
47555
|
try {
|
|
47037
|
-
fs17.accessSync(
|
|
47556
|
+
fs17.accessSync(path34.join(cur, ".git"));
|
|
47038
47557
|
break;
|
|
47039
47558
|
} catch {}
|
|
47040
|
-
const parent =
|
|
47559
|
+
const parent = path34.dirname(cur);
|
|
47041
47560
|
if (parent === cur)
|
|
47042
47561
|
break;
|
|
47043
47562
|
cur = parent;
|
|
@@ -47049,12 +47568,12 @@ function findGoModule(fromDir) {
|
|
|
47049
47568
|
function resolveGoImport(fromDir, importPath) {
|
|
47050
47569
|
let dir = null;
|
|
47051
47570
|
if (importPath.startsWith(".")) {
|
|
47052
|
-
dir =
|
|
47571
|
+
dir = path34.resolve(fromDir, importPath);
|
|
47053
47572
|
} else {
|
|
47054
47573
|
const mod = findGoModule(fromDir);
|
|
47055
47574
|
if (mod && (importPath === mod.modulePath || importPath.startsWith(`${mod.modulePath}/`))) {
|
|
47056
47575
|
const subpath = importPath.slice(mod.modulePath.length);
|
|
47057
|
-
dir =
|
|
47576
|
+
dir = path34.join(mod.moduleRoot, subpath);
|
|
47058
47577
|
}
|
|
47059
47578
|
}
|
|
47060
47579
|
if (dir === null)
|
|
@@ -47062,7 +47581,7 @@ function resolveGoImport(fromDir, importPath) {
|
|
|
47062
47581
|
if (!fs17.existsSync(dir) || !fs17.statSync(dir).isDirectory())
|
|
47063
47582
|
return [];
|
|
47064
47583
|
try {
|
|
47065
|
-
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)));
|
|
47066
47585
|
} catch {
|
|
47067
47586
|
return [];
|
|
47068
47587
|
}
|
|
@@ -47101,15 +47620,15 @@ function findTestFilesSync(cwd) {
|
|
|
47101
47620
|
for (const entry of entries) {
|
|
47102
47621
|
if (entry.isDirectory()) {
|
|
47103
47622
|
if (!skipDirs.has(entry.name)) {
|
|
47104
|
-
walk(
|
|
47623
|
+
walk(path34.join(dir, entry.name), visitedInodes);
|
|
47105
47624
|
}
|
|
47106
47625
|
} else if (entry.isFile()) {
|
|
47107
47626
|
const name = entry.name;
|
|
47108
47627
|
const isTsTest = /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name);
|
|
47109
|
-
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");
|
|
47110
47629
|
const isGoTest = /.+_test\.go$/.test(name);
|
|
47111
47630
|
if (isTsTest || isPyTest || isGoTest) {
|
|
47112
|
-
testFiles.push(normalizePath(
|
|
47631
|
+
testFiles.push(normalizePath(path34.join(dir, entry.name)));
|
|
47113
47632
|
}
|
|
47114
47633
|
}
|
|
47115
47634
|
}
|
|
@@ -47134,8 +47653,8 @@ function extractImports3(content) {
|
|
|
47134
47653
|
];
|
|
47135
47654
|
}
|
|
47136
47655
|
function addImpactEdgesForTestFile(testFile, content, impactMap) {
|
|
47137
|
-
const ext =
|
|
47138
|
-
const testDir =
|
|
47656
|
+
const ext = path34.extname(testFile).toLowerCase();
|
|
47657
|
+
const testDir = path34.dirname(testFile);
|
|
47139
47658
|
function addEdge(source) {
|
|
47140
47659
|
if (!impactMap[source])
|
|
47141
47660
|
impactMap[source] = [];
|
|
@@ -47153,7 +47672,7 @@ function addImpactEdgesForTestFile(testFile, content, impactMap) {
|
|
|
47153
47672
|
return;
|
|
47154
47673
|
}
|
|
47155
47674
|
if (PYTHON_EXTENSIONS.has(ext)) {
|
|
47156
|
-
const modules =
|
|
47675
|
+
const modules = _internals22.extractImports(testFile, content);
|
|
47157
47676
|
for (const mod of modules) {
|
|
47158
47677
|
const resolved = resolvePythonImport(testDir, mod);
|
|
47159
47678
|
if (resolved !== null)
|
|
@@ -47162,7 +47681,7 @@ function addImpactEdgesForTestFile(testFile, content, impactMap) {
|
|
|
47162
47681
|
return;
|
|
47163
47682
|
}
|
|
47164
47683
|
if (GO_EXTENSIONS.has(ext)) {
|
|
47165
|
-
const imports =
|
|
47684
|
+
const imports = _internals21.extractImports(testFile, content);
|
|
47166
47685
|
for (const importPath of imports) {
|
|
47167
47686
|
const sourceFiles = resolveGoImport(testDir, importPath);
|
|
47168
47687
|
for (const source of sourceFiles)
|
|
@@ -47189,12 +47708,12 @@ async function buildImpactMapInternal(cwd) {
|
|
|
47189
47708
|
return impactMap;
|
|
47190
47709
|
}
|
|
47191
47710
|
async function buildImpactMap(cwd) {
|
|
47192
|
-
const impactMap = await
|
|
47193
|
-
await
|
|
47711
|
+
const impactMap = await _internals23.buildImpactMapInternal(cwd);
|
|
47712
|
+
await _internals23.saveImpactMap(cwd, impactMap);
|
|
47194
47713
|
return impactMap;
|
|
47195
47714
|
}
|
|
47196
47715
|
async function loadImpactMap(cwd, options) {
|
|
47197
|
-
const cachePath =
|
|
47716
|
+
const cachePath = path34.join(cwd, ".swarm", "cache", "impact-map.json");
|
|
47198
47717
|
if (fs17.existsSync(cachePath)) {
|
|
47199
47718
|
try {
|
|
47200
47719
|
const content = fs17.readFileSync(cachePath, "utf-8");
|
|
@@ -47204,7 +47723,7 @@ async function loadImpactMap(cwd, options) {
|
|
|
47204
47723
|
const hasValidValues = Object.values(map3).every((v) => Array.isArray(v) && v.every((item) => typeof item === "string"));
|
|
47205
47724
|
if (hasValidValues) {
|
|
47206
47725
|
const generatedAt = new Date(data.generatedAt).getTime();
|
|
47207
|
-
if (!
|
|
47726
|
+
if (!_internals23.isCacheStale(map3, generatedAt)) {
|
|
47208
47727
|
return map3;
|
|
47209
47728
|
}
|
|
47210
47729
|
if (options?.skipRebuild) {
|
|
@@ -47224,15 +47743,15 @@ async function loadImpactMap(cwd, options) {
|
|
|
47224
47743
|
if (options?.skipRebuild) {
|
|
47225
47744
|
return {};
|
|
47226
47745
|
}
|
|
47227
|
-
return
|
|
47746
|
+
return _internals23.buildImpactMap(cwd);
|
|
47228
47747
|
}
|
|
47229
47748
|
async function saveImpactMap(cwd, impactMap) {
|
|
47230
|
-
if (!
|
|
47749
|
+
if (!path34.isAbsolute(cwd)) {
|
|
47231
47750
|
throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
|
|
47232
47751
|
}
|
|
47233
|
-
|
|
47234
|
-
const cacheDir2 =
|
|
47235
|
-
const cachePath =
|
|
47752
|
+
_internals23.validateProjectRoot(cwd);
|
|
47753
|
+
const cacheDir2 = path34.join(cwd, ".swarm", "cache");
|
|
47754
|
+
const cachePath = path34.join(cacheDir2, "impact-map.json");
|
|
47236
47755
|
if (!fs17.existsSync(cacheDir2)) {
|
|
47237
47756
|
fs17.mkdirSync(cacheDir2, { recursive: true });
|
|
47238
47757
|
}
|
|
@@ -47254,7 +47773,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
|
|
|
47254
47773
|
};
|
|
47255
47774
|
}
|
|
47256
47775
|
const validFiles = changedFiles.filter((f) => typeof f === "string" && f.length > 0 && !f.includes("\x00"));
|
|
47257
|
-
const impactMap = await
|
|
47776
|
+
const impactMap = await _internals23.loadImpactMap(cwd);
|
|
47258
47777
|
const impactedTestsSet = new Set;
|
|
47259
47778
|
const untestedFiles = [];
|
|
47260
47779
|
let visitedCount = 0;
|
|
@@ -47264,7 +47783,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
|
|
|
47264
47783
|
budgetExceeded = true;
|
|
47265
47784
|
break;
|
|
47266
47785
|
}
|
|
47267
|
-
const normalizedChanged = normalizePath(
|
|
47786
|
+
const normalizedChanged = normalizePath(path34.resolve(changedFile));
|
|
47268
47787
|
const tests = impactMap[normalizedChanged];
|
|
47269
47788
|
if (tests && tests.length > 0) {
|
|
47270
47789
|
for (const test of tests) {
|
|
@@ -47321,7 +47840,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
|
|
|
47321
47840
|
budgetExceeded
|
|
47322
47841
|
};
|
|
47323
47842
|
}
|
|
47324
|
-
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;
|
|
47325
47844
|
var init_analyzer = __esm(() => {
|
|
47326
47845
|
init_manager2();
|
|
47327
47846
|
init_go();
|
|
@@ -47334,7 +47853,7 @@ var init_analyzer = __esm(() => {
|
|
|
47334
47853
|
GO_EXTENSIONS = new Set([".go"]);
|
|
47335
47854
|
EXTENSIONS_TO_TRY = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
47336
47855
|
goModuleCache = new Map;
|
|
47337
|
-
|
|
47856
|
+
_internals23 = {
|
|
47338
47857
|
validateProjectRoot,
|
|
47339
47858
|
normalizePath,
|
|
47340
47859
|
isCacheStale,
|
|
@@ -47557,15 +48076,15 @@ var FLAKY_THRESHOLD = 0.3, MIN_RUNS_FOR_QUARANTINE = 5, MAX_HISTORY_RUNS = 20;
|
|
|
47557
48076
|
|
|
47558
48077
|
// src/test-impact/history-store.ts
|
|
47559
48078
|
import fs18 from "fs";
|
|
47560
|
-
import
|
|
48079
|
+
import path35 from "path";
|
|
47561
48080
|
function getHistoryPath(workingDir) {
|
|
47562
48081
|
if (!workingDir) {
|
|
47563
48082
|
throw new Error("getHistoryPath requires a working directory \u2014 project root must be provided by the caller");
|
|
47564
48083
|
}
|
|
47565
|
-
if (!
|
|
48084
|
+
if (!path35.isAbsolute(workingDir)) {
|
|
47566
48085
|
throw new Error(`getHistoryPath requires an absolute project root path, got: "${workingDir}"`);
|
|
47567
48086
|
}
|
|
47568
|
-
return
|
|
48087
|
+
return path35.join(workingDir, ".swarm", "cache", "test-history.jsonl");
|
|
47569
48088
|
}
|
|
47570
48089
|
function sanitizeErrorMessage(errorMessage) {
|
|
47571
48090
|
if (errorMessage === undefined) {
|
|
@@ -47652,8 +48171,8 @@ function batchAppendTestRuns(records, workingDir) {
|
|
|
47652
48171
|
}
|
|
47653
48172
|
}
|
|
47654
48173
|
const historyPath = getHistoryPath(workingDir);
|
|
47655
|
-
const historyDir =
|
|
47656
|
-
|
|
48174
|
+
const historyDir = path35.dirname(historyPath);
|
|
48175
|
+
_internals24.validateProjectRoot(workingDir);
|
|
47657
48176
|
if (!fs18.existsSync(historyDir)) {
|
|
47658
48177
|
fs18.mkdirSync(historyDir, { recursive: true });
|
|
47659
48178
|
}
|
|
@@ -47733,7 +48252,7 @@ function getAllHistory(workingDir) {
|
|
|
47733
48252
|
records.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
47734
48253
|
return records;
|
|
47735
48254
|
}
|
|
47736
|
-
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;
|
|
47737
48256
|
var init_history_store = __esm(() => {
|
|
47738
48257
|
init_manager2();
|
|
47739
48258
|
DANGEROUS_PROPERTY_NAMES = new Set([
|
|
@@ -47741,14 +48260,14 @@ var init_history_store = __esm(() => {
|
|
|
47741
48260
|
"constructor",
|
|
47742
48261
|
"prototype"
|
|
47743
48262
|
]);
|
|
47744
|
-
|
|
48263
|
+
_internals24 = {
|
|
47745
48264
|
validateProjectRoot
|
|
47746
48265
|
};
|
|
47747
48266
|
});
|
|
47748
48267
|
|
|
47749
48268
|
// src/tools/resolve-working-directory.ts
|
|
47750
48269
|
import * as fs19 from "fs";
|
|
47751
|
-
import * as
|
|
48270
|
+
import * as path36 from "path";
|
|
47752
48271
|
function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
47753
48272
|
if (workingDirectory == null || workingDirectory === "") {
|
|
47754
48273
|
return { success: true, directory: fallbackDirectory };
|
|
@@ -47768,15 +48287,15 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
47768
48287
|
};
|
|
47769
48288
|
}
|
|
47770
48289
|
}
|
|
47771
|
-
const normalizedDir =
|
|
47772
|
-
const pathParts = normalizedDir.split(
|
|
48290
|
+
const normalizedDir = path36.normalize(workingDirectory);
|
|
48291
|
+
const pathParts = normalizedDir.split(path36.sep);
|
|
47773
48292
|
if (pathParts.includes("..")) {
|
|
47774
48293
|
return {
|
|
47775
48294
|
success: false,
|
|
47776
48295
|
message: "Invalid working_directory: path traversal sequences (..) are not allowed"
|
|
47777
48296
|
};
|
|
47778
48297
|
}
|
|
47779
|
-
const resolvedDir =
|
|
48298
|
+
const resolvedDir = path36.resolve(normalizedDir);
|
|
47780
48299
|
let statResult;
|
|
47781
48300
|
try {
|
|
47782
48301
|
statResult = fs19.statSync(resolvedDir);
|
|
@@ -47792,7 +48311,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
47792
48311
|
message: `Invalid working_directory: path "${resolvedDir}" is not a directory`
|
|
47793
48312
|
};
|
|
47794
48313
|
}
|
|
47795
|
-
const resolvedFallback =
|
|
48314
|
+
const resolvedFallback = path36.resolve(fallbackDirectory);
|
|
47796
48315
|
let fallbackExists = false;
|
|
47797
48316
|
try {
|
|
47798
48317
|
fs19.statSync(resolvedFallback);
|
|
@@ -47802,7 +48321,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
47802
48321
|
}
|
|
47803
48322
|
if (workingDirectory != null && workingDirectory !== "") {
|
|
47804
48323
|
if (fallbackExists) {
|
|
47805
|
-
const isSubdirectory = resolvedDir.startsWith(resolvedFallback +
|
|
48324
|
+
const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path36.sep);
|
|
47806
48325
|
if (isSubdirectory) {
|
|
47807
48326
|
return {
|
|
47808
48327
|
success: false,
|
|
@@ -47857,17 +48376,17 @@ var init_registry_backend = __esm(() => {
|
|
|
47857
48376
|
|
|
47858
48377
|
// src/lang/backends/typescript.ts
|
|
47859
48378
|
import * as fs20 from "fs";
|
|
47860
|
-
import * as
|
|
48379
|
+
import * as path37 from "path";
|
|
47861
48380
|
function readPackageJsonRaw(dir) {
|
|
47862
48381
|
try {
|
|
47863
|
-
const content = fs20.readFileSync(
|
|
48382
|
+
const content = fs20.readFileSync(path37.join(dir, "package.json"), "utf-8");
|
|
47864
48383
|
return JSON.parse(content);
|
|
47865
48384
|
} catch {
|
|
47866
48385
|
return null;
|
|
47867
48386
|
}
|
|
47868
48387
|
}
|
|
47869
48388
|
function readPackageJson(dir) {
|
|
47870
|
-
return
|
|
48389
|
+
return _internals25.readPackageJsonRaw(dir);
|
|
47871
48390
|
}
|
|
47872
48391
|
function readPackageJsonTestScript(dir) {
|
|
47873
48392
|
return readPackageJson(dir)?.scripts?.test ?? null;
|
|
@@ -48037,7 +48556,7 @@ function buildTypescriptBackend() {
|
|
|
48037
48556
|
selectEntryPoints: selectEntryPoints3
|
|
48038
48557
|
};
|
|
48039
48558
|
}
|
|
48040
|
-
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;
|
|
48041
48560
|
var init_typescript = __esm(() => {
|
|
48042
48561
|
init_default_backend();
|
|
48043
48562
|
init_profiles();
|
|
@@ -48046,7 +48565,7 @@ var init_typescript = __esm(() => {
|
|
|
48046
48565
|
IMPORT_REGEX_REQUIRE2 = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
48047
48566
|
IMPORT_REGEX_DYNAMIC = /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
48048
48567
|
IMPORT_REGEX_REEXPORT2 = /export\s+(?:\{[^}]*\}|\*)\s+from\s+['"]([^'"]+)['"]/g;
|
|
48049
|
-
|
|
48568
|
+
_internals25 = {
|
|
48050
48569
|
readPackageJsonRaw,
|
|
48051
48570
|
readPackageJsonTestScript,
|
|
48052
48571
|
frameworkFromScriptsTest
|
|
@@ -48077,10 +48596,10 @@ __export(exports_dispatch, {
|
|
|
48077
48596
|
pickedProfiles: () => pickedProfiles,
|
|
48078
48597
|
pickBackend: () => pickBackend,
|
|
48079
48598
|
clearDispatchCache: () => clearDispatchCache,
|
|
48080
|
-
_internals: () =>
|
|
48599
|
+
_internals: () => _internals26
|
|
48081
48600
|
});
|
|
48082
48601
|
import * as fs21 from "fs";
|
|
48083
|
-
import * as
|
|
48602
|
+
import * as path38 from "path";
|
|
48084
48603
|
function safeReaddirSet(dir) {
|
|
48085
48604
|
try {
|
|
48086
48605
|
return new Set(fs21.readdirSync(dir));
|
|
@@ -48097,14 +48616,14 @@ function manifestHash(dir) {
|
|
|
48097
48616
|
if (!entries.has(name))
|
|
48098
48617
|
continue;
|
|
48099
48618
|
try {
|
|
48100
|
-
const stat3 = fs21.statSync(
|
|
48619
|
+
const stat3 = fs21.statSync(path38.join(dir, name));
|
|
48101
48620
|
parts.push(`${name}:${stat3.size}:${stat3.mtimeMs}:${stat3.ino}`);
|
|
48102
48621
|
} catch {}
|
|
48103
48622
|
}
|
|
48104
48623
|
return parts.join("|");
|
|
48105
48624
|
}
|
|
48106
48625
|
function findManifestRoot(start) {
|
|
48107
|
-
const resolved =
|
|
48626
|
+
const resolved = path38.resolve(start);
|
|
48108
48627
|
const cached3 = manifestRootCache.get(resolved);
|
|
48109
48628
|
if (cached3 !== undefined)
|
|
48110
48629
|
return cached3;
|
|
@@ -48123,7 +48642,7 @@ function findManifestRoot(start) {
|
|
|
48123
48642
|
return cur;
|
|
48124
48643
|
}
|
|
48125
48644
|
}
|
|
48126
|
-
const parent =
|
|
48645
|
+
const parent = path38.dirname(cur);
|
|
48127
48646
|
if (parent === cur)
|
|
48128
48647
|
break;
|
|
48129
48648
|
cur = parent;
|
|
@@ -48132,7 +48651,7 @@ function findManifestRoot(start) {
|
|
|
48132
48651
|
return start;
|
|
48133
48652
|
}
|
|
48134
48653
|
function evictIfNeeded() {
|
|
48135
|
-
if (cache.size <=
|
|
48654
|
+
if (cache.size <= _internals26.cacheCapacity)
|
|
48136
48655
|
return;
|
|
48137
48656
|
let oldestKey;
|
|
48138
48657
|
let oldestOrder = Infinity;
|
|
@@ -48163,7 +48682,7 @@ async function pickBackend(dir) {
|
|
|
48163
48682
|
evictIfNeeded();
|
|
48164
48683
|
return null;
|
|
48165
48684
|
}
|
|
48166
|
-
const profiles = await
|
|
48685
|
+
const profiles = await _internals26.detectProjectLanguages(root);
|
|
48167
48686
|
if (profiles.length === 0) {
|
|
48168
48687
|
cache.set(cacheKey, {
|
|
48169
48688
|
hash: hash3,
|
|
@@ -48195,12 +48714,12 @@ function clearDispatchCache() {
|
|
|
48195
48714
|
manifestRootCache.clear();
|
|
48196
48715
|
insertCounter = 0;
|
|
48197
48716
|
}
|
|
48198
|
-
var
|
|
48717
|
+
var _internals26, cache, insertCounter = 0, MANIFEST_FILES, _MANIFEST_SET, manifestRootCache;
|
|
48199
48718
|
var init_dispatch = __esm(() => {
|
|
48200
48719
|
init_backends();
|
|
48201
48720
|
init_detector();
|
|
48202
48721
|
init_registry_backend();
|
|
48203
|
-
|
|
48722
|
+
_internals26 = {
|
|
48204
48723
|
detectProjectLanguages,
|
|
48205
48724
|
cacheCapacity: 64
|
|
48206
48725
|
};
|
|
@@ -48233,13 +48752,13 @@ var init_dispatch = __esm(() => {
|
|
|
48233
48752
|
|
|
48234
48753
|
// src/tools/test-runner.ts
|
|
48235
48754
|
import * as fs22 from "fs";
|
|
48236
|
-
import * as
|
|
48755
|
+
import * as path39 from "path";
|
|
48237
48756
|
async function estimateFanOut(sourceFiles, cwd) {
|
|
48238
48757
|
try {
|
|
48239
48758
|
const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
|
|
48240
48759
|
const uniqueTestFiles = new Set;
|
|
48241
48760
|
for (const sourceFile of sourceFiles) {
|
|
48242
|
-
const resolvedPath =
|
|
48761
|
+
const resolvedPath = path39.resolve(cwd, sourceFile);
|
|
48243
48762
|
const normalizedPath = resolvedPath.replace(/\\/g, "/");
|
|
48244
48763
|
const testFiles = impactMap[normalizedPath];
|
|
48245
48764
|
if (testFiles) {
|
|
@@ -48317,14 +48836,14 @@ function hasDevDependency(devDeps, ...patterns) {
|
|
|
48317
48836
|
return hasPackageJsonDependency(devDeps, ...patterns);
|
|
48318
48837
|
}
|
|
48319
48838
|
function detectGoTest(cwd) {
|
|
48320
|
-
return fs22.existsSync(
|
|
48839
|
+
return fs22.existsSync(path39.join(cwd, "go.mod")) && isCommandAvailable("go");
|
|
48321
48840
|
}
|
|
48322
48841
|
function detectJavaMaven(cwd) {
|
|
48323
|
-
return fs22.existsSync(
|
|
48842
|
+
return fs22.existsSync(path39.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
|
|
48324
48843
|
}
|
|
48325
48844
|
function detectGradle(cwd) {
|
|
48326
|
-
const hasBuildFile = fs22.existsSync(
|
|
48327
|
-
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"));
|
|
48328
48847
|
return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
|
|
48329
48848
|
}
|
|
48330
48849
|
function detectDotnetTest(cwd) {
|
|
@@ -48337,25 +48856,25 @@ function detectDotnetTest(cwd) {
|
|
|
48337
48856
|
}
|
|
48338
48857
|
}
|
|
48339
48858
|
function detectCTest(cwd) {
|
|
48340
|
-
const hasSource = fs22.existsSync(
|
|
48341
|
-
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"));
|
|
48342
48861
|
return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
|
|
48343
48862
|
}
|
|
48344
48863
|
function detectSwiftTest(cwd) {
|
|
48345
|
-
return fs22.existsSync(
|
|
48864
|
+
return fs22.existsSync(path39.join(cwd, "Package.swift")) && isCommandAvailable("swift");
|
|
48346
48865
|
}
|
|
48347
48866
|
function detectDartTest(cwd) {
|
|
48348
|
-
return fs22.existsSync(
|
|
48867
|
+
return fs22.existsSync(path39.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
48349
48868
|
}
|
|
48350
48869
|
function detectRSpec(cwd) {
|
|
48351
|
-
const hasRSpecFile = fs22.existsSync(
|
|
48352
|
-
const hasGemfile = fs22.existsSync(
|
|
48353
|
-
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"));
|
|
48354
48873
|
const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
|
|
48355
48874
|
return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
|
|
48356
48875
|
}
|
|
48357
48876
|
function detectMinitest(cwd) {
|
|
48358
|
-
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");
|
|
48359
48878
|
}
|
|
48360
48879
|
async function detectTestFrameworkViaDispatch(cwd) {
|
|
48361
48880
|
try {
|
|
@@ -48417,7 +48936,7 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
|
|
|
48417
48936
|
async function detectTestFramework(cwd) {
|
|
48418
48937
|
const baseDir = cwd;
|
|
48419
48938
|
try {
|
|
48420
|
-
const packageJsonPath =
|
|
48939
|
+
const packageJsonPath = path39.join(baseDir, "package.json");
|
|
48421
48940
|
if (fs22.existsSync(packageJsonPath)) {
|
|
48422
48941
|
const content = fs22.readFileSync(packageJsonPath, "utf-8");
|
|
48423
48942
|
const pkg = JSON.parse(content);
|
|
@@ -48438,16 +48957,16 @@ async function detectTestFramework(cwd) {
|
|
|
48438
48957
|
return "jest";
|
|
48439
48958
|
if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
|
|
48440
48959
|
return "mocha";
|
|
48441
|
-
if (fs22.existsSync(
|
|
48960
|
+
if (fs22.existsSync(path39.join(baseDir, "bun.lockb")) || fs22.existsSync(path39.join(baseDir, "bun.lock"))) {
|
|
48442
48961
|
if (scripts.test?.includes("bun"))
|
|
48443
48962
|
return "bun";
|
|
48444
48963
|
}
|
|
48445
48964
|
}
|
|
48446
48965
|
} catch {}
|
|
48447
48966
|
try {
|
|
48448
|
-
const pyprojectTomlPath =
|
|
48449
|
-
const setupCfgPath =
|
|
48450
|
-
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");
|
|
48451
48970
|
if (fs22.existsSync(pyprojectTomlPath)) {
|
|
48452
48971
|
const content = fs22.readFileSync(pyprojectTomlPath, "utf-8");
|
|
48453
48972
|
if (content.includes("[tool.pytest"))
|
|
@@ -48467,7 +48986,7 @@ async function detectTestFramework(cwd) {
|
|
|
48467
48986
|
}
|
|
48468
48987
|
} catch {}
|
|
48469
48988
|
try {
|
|
48470
|
-
const cargoTomlPath =
|
|
48989
|
+
const cargoTomlPath = path39.join(baseDir, "Cargo.toml");
|
|
48471
48990
|
if (fs22.existsSync(cargoTomlPath)) {
|
|
48472
48991
|
const content = fs22.readFileSync(cargoTomlPath, "utf-8");
|
|
48473
48992
|
if (content.includes("[dev-dependencies]")) {
|
|
@@ -48478,9 +48997,9 @@ async function detectTestFramework(cwd) {
|
|
|
48478
48997
|
}
|
|
48479
48998
|
} catch {}
|
|
48480
48999
|
try {
|
|
48481
|
-
const pesterConfigPath =
|
|
48482
|
-
const pesterConfigJsonPath =
|
|
48483
|
-
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");
|
|
48484
49003
|
if (fs22.existsSync(pesterConfigPath) || fs22.existsSync(pesterConfigJsonPath) || fs22.existsSync(pesterPs1Path)) {
|
|
48485
49004
|
return "pester";
|
|
48486
49005
|
}
|
|
@@ -48509,12 +49028,12 @@ function isTestDirectoryPath(normalizedPath) {
|
|
|
48509
49028
|
return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
|
|
48510
49029
|
}
|
|
48511
49030
|
function resolveWorkspacePath(file3, workingDir) {
|
|
48512
|
-
return
|
|
49031
|
+
return path39.isAbsolute(file3) ? path39.resolve(file3) : path39.resolve(workingDir, file3);
|
|
48513
49032
|
}
|
|
48514
49033
|
function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
|
|
48515
49034
|
if (!preferRelative)
|
|
48516
49035
|
return absolutePath;
|
|
48517
|
-
return
|
|
49036
|
+
return path39.relative(workingDir, absolutePath);
|
|
48518
49037
|
}
|
|
48519
49038
|
function dedupePush(target, value) {
|
|
48520
49039
|
if (!target.includes(value)) {
|
|
@@ -48551,18 +49070,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
|
|
|
48551
49070
|
}
|
|
48552
49071
|
}
|
|
48553
49072
|
function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
|
|
48554
|
-
const relativeDir =
|
|
49073
|
+
const relativeDir = path39.dirname(relativePath);
|
|
48555
49074
|
const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
|
|
48556
49075
|
const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
|
|
48557
|
-
const rootDir =
|
|
48558
|
-
return nestedRelativeDir ? [rootDir,
|
|
49076
|
+
const rootDir = path39.join(workingDir, dirName);
|
|
49077
|
+
return nestedRelativeDir ? [rootDir, path39.join(rootDir, nestedRelativeDir)] : [rootDir];
|
|
48559
49078
|
});
|
|
48560
49079
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
48561
49080
|
if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
|
|
48562
|
-
directories.push(
|
|
49081
|
+
directories.push(path39.join(workingDir, "src/test/java", path39.dirname(normalizedRelativePath.slice("src/main/java/".length))));
|
|
48563
49082
|
}
|
|
48564
49083
|
if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
|
|
48565
|
-
directories.push(
|
|
49084
|
+
directories.push(path39.join(workingDir, "src/test/kotlin", path39.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
|
|
48566
49085
|
}
|
|
48567
49086
|
return [...new Set(directories)];
|
|
48568
49087
|
}
|
|
@@ -48590,23 +49109,23 @@ function isLanguageSpecificTestFile(basename6) {
|
|
|
48590
49109
|
}
|
|
48591
49110
|
function isConventionTestFilePath(filePath) {
|
|
48592
49111
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
48593
|
-
const basename6 =
|
|
49112
|
+
const basename6 = path39.basename(filePath);
|
|
48594
49113
|
return hasCompoundTestExtension(basename6) || basename6.includes(".spec.") || basename6.includes(".test.") || isLanguageSpecificTestFile(basename6) || isTestDirectoryPath(normalizedPath);
|
|
48595
49114
|
}
|
|
48596
49115
|
function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
48597
49116
|
const testFiles = [];
|
|
48598
49117
|
for (const file3 of sourceFiles) {
|
|
48599
49118
|
const absoluteFile = resolveWorkspacePath(file3, workingDir);
|
|
48600
|
-
const relativeFile =
|
|
48601
|
-
const basename6 =
|
|
48602
|
-
const dirname17 =
|
|
48603
|
-
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);
|
|
48604
49123
|
if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file3)) {
|
|
48605
49124
|
dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
|
|
48606
49125
|
continue;
|
|
48607
49126
|
}
|
|
48608
49127
|
const nameWithoutExt = basename6.replace(/\.[^.]+$/, "");
|
|
48609
|
-
const ext =
|
|
49128
|
+
const ext = path39.extname(basename6);
|
|
48610
49129
|
const genericTestNames = [
|
|
48611
49130
|
`${nameWithoutExt}.spec${ext}`,
|
|
48612
49131
|
`${nameWithoutExt}.test${ext}`
|
|
@@ -48615,7 +49134,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
48615
49134
|
const colocatedCandidates = [
|
|
48616
49135
|
...genericTestNames,
|
|
48617
49136
|
...languageSpecificTestNames
|
|
48618
|
-
].map((candidateName) =>
|
|
49137
|
+
].map((candidateName) => path39.join(dirname17, candidateName));
|
|
48619
49138
|
const testDirectoryNames = [
|
|
48620
49139
|
basename6,
|
|
48621
49140
|
...genericTestNames,
|
|
@@ -48624,8 +49143,8 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
48624
49143
|
const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
|
|
48625
49144
|
const possibleTestFiles = [
|
|
48626
49145
|
...colocatedCandidates,
|
|
48627
|
-
...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) =>
|
|
48628
|
-
...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)))
|
|
48629
49148
|
];
|
|
48630
49149
|
for (const testFile of possibleTestFiles) {
|
|
48631
49150
|
if (fs22.existsSync(testFile)) {
|
|
@@ -48646,7 +49165,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
48646
49165
|
try {
|
|
48647
49166
|
const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
|
|
48648
49167
|
const content = fs22.readFileSync(absoluteTestFile, "utf-8");
|
|
48649
|
-
const testDir =
|
|
49168
|
+
const testDir = path39.dirname(absoluteTestFile);
|
|
48650
49169
|
const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
|
|
48651
49170
|
let match;
|
|
48652
49171
|
match = importRegex.exec(content);
|
|
@@ -48654,8 +49173,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
48654
49173
|
const importPath = match[1];
|
|
48655
49174
|
let resolvedImport;
|
|
48656
49175
|
if (importPath.startsWith(".")) {
|
|
48657
|
-
resolvedImport =
|
|
48658
|
-
const existingExt =
|
|
49176
|
+
resolvedImport = path39.resolve(testDir, importPath);
|
|
49177
|
+
const existingExt = path39.extname(resolvedImport);
|
|
48659
49178
|
if (!existingExt) {
|
|
48660
49179
|
for (const extToTry of [
|
|
48661
49180
|
".ts",
|
|
@@ -48675,12 +49194,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
48675
49194
|
} else {
|
|
48676
49195
|
continue;
|
|
48677
49196
|
}
|
|
48678
|
-
const importBasename =
|
|
48679
|
-
const importDir =
|
|
49197
|
+
const importBasename = path39.basename(resolvedImport, path39.extname(resolvedImport));
|
|
49198
|
+
const importDir = path39.dirname(resolvedImport);
|
|
48680
49199
|
for (const sourceFile of absoluteSourceFiles) {
|
|
48681
|
-
const sourceDir =
|
|
48682
|
-
const sourceBasename =
|
|
48683
|
-
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");
|
|
48684
49203
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
48685
49204
|
dedupePush(testFiles, testFile);
|
|
48686
49205
|
break;
|
|
@@ -48693,8 +49212,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
48693
49212
|
while (match !== null) {
|
|
48694
49213
|
const importPath = match[1];
|
|
48695
49214
|
if (importPath.startsWith(".")) {
|
|
48696
|
-
let resolvedImport =
|
|
48697
|
-
const existingExt =
|
|
49215
|
+
let resolvedImport = path39.resolve(testDir, importPath);
|
|
49216
|
+
const existingExt = path39.extname(resolvedImport);
|
|
48698
49217
|
if (!existingExt) {
|
|
48699
49218
|
for (const extToTry of [
|
|
48700
49219
|
".ts",
|
|
@@ -48711,12 +49230,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
48711
49230
|
}
|
|
48712
49231
|
}
|
|
48713
49232
|
}
|
|
48714
|
-
const importDir =
|
|
48715
|
-
const importBasename =
|
|
49233
|
+
const importDir = path39.dirname(resolvedImport);
|
|
49234
|
+
const importBasename = path39.basename(resolvedImport, path39.extname(resolvedImport));
|
|
48716
49235
|
for (const sourceFile of absoluteSourceFiles) {
|
|
48717
|
-
const sourceDir =
|
|
48718
|
-
const sourceBasename =
|
|
48719
|
-
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");
|
|
48720
49239
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
48721
49240
|
dedupePush(testFiles, testFile);
|
|
48722
49241
|
break;
|
|
@@ -48826,8 +49345,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
48826
49345
|
return ["mvn", "test"];
|
|
48827
49346
|
case "gradle": {
|
|
48828
49347
|
const isWindows = process.platform === "win32";
|
|
48829
|
-
const hasGradlewBat = fs22.existsSync(
|
|
48830
|
-
const hasGradlew = fs22.existsSync(
|
|
49348
|
+
const hasGradlewBat = fs22.existsSync(path39.join(baseDir, "gradlew.bat"));
|
|
49349
|
+
const hasGradlew = fs22.existsSync(path39.join(baseDir, "gradlew"));
|
|
48831
49350
|
if (hasGradlewBat && isWindows)
|
|
48832
49351
|
return ["gradlew.bat", "test"];
|
|
48833
49352
|
if (hasGradlew)
|
|
@@ -48844,7 +49363,7 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
48844
49363
|
"cmake-build-release",
|
|
48845
49364
|
"out"
|
|
48846
49365
|
];
|
|
48847
|
-
const actualBuildDir = buildDirCandidates.find((d) => fs22.existsSync(
|
|
49366
|
+
const actualBuildDir = buildDirCandidates.find((d) => fs22.existsSync(path39.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
|
|
48848
49367
|
return ["ctest", "--test-dir", actualBuildDir];
|
|
48849
49368
|
}
|
|
48850
49369
|
case "swift-test":
|
|
@@ -49276,11 +49795,11 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
|
|
|
49276
49795
|
};
|
|
49277
49796
|
}
|
|
49278
49797
|
const startTime = Date.now();
|
|
49279
|
-
const vitestJsonOutputPath = framework === "vitest" ?
|
|
49798
|
+
const vitestJsonOutputPath = framework === "vitest" ? path39.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
|
|
49280
49799
|
try {
|
|
49281
49800
|
if (vitestJsonOutputPath) {
|
|
49282
49801
|
try {
|
|
49283
|
-
fs22.mkdirSync(
|
|
49802
|
+
fs22.mkdirSync(path39.dirname(vitestJsonOutputPath), { recursive: true });
|
|
49284
49803
|
if (fs22.existsSync(vitestJsonOutputPath)) {
|
|
49285
49804
|
fs22.unlinkSync(vitestJsonOutputPath);
|
|
49286
49805
|
}
|
|
@@ -49396,10 +49915,10 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
|
|
|
49396
49915
|
}
|
|
49397
49916
|
function normalizeHistoryTestFile(testFile, workingDir) {
|
|
49398
49917
|
const normalized = testFile.replace(/\\/g, "/");
|
|
49399
|
-
if (!
|
|
49918
|
+
if (!path39.isAbsolute(testFile))
|
|
49400
49919
|
return normalized;
|
|
49401
|
-
const relative9 =
|
|
49402
|
-
if (relative9.startsWith("..") ||
|
|
49920
|
+
const relative9 = path39.relative(workingDir, testFile);
|
|
49921
|
+
if (relative9.startsWith("..") || path39.isAbsolute(relative9)) {
|
|
49403
49922
|
return normalized;
|
|
49404
49923
|
}
|
|
49405
49924
|
return relative9.replace(/\\/g, "/");
|
|
@@ -49737,7 +50256,7 @@ var init_test_runner = __esm(() => {
|
|
|
49737
50256
|
const sourceFiles = args.files.filter((file3) => {
|
|
49738
50257
|
if (directTestFiles.includes(file3))
|
|
49739
50258
|
return false;
|
|
49740
|
-
const ext =
|
|
50259
|
+
const ext = path39.extname(file3).toLowerCase();
|
|
49741
50260
|
return SOURCE_EXTENSIONS.has(ext);
|
|
49742
50261
|
});
|
|
49743
50262
|
const invalidFiles = args.files.filter((file3) => !directTestFiles.includes(file3) && !sourceFiles.includes(file3));
|
|
@@ -49783,7 +50302,7 @@ var init_test_runner = __esm(() => {
|
|
|
49783
50302
|
if (isConventionTestFilePath(f)) {
|
|
49784
50303
|
return false;
|
|
49785
50304
|
}
|
|
49786
|
-
const ext =
|
|
50305
|
+
const ext = path39.extname(f).toLowerCase();
|
|
49787
50306
|
return SOURCE_EXTENSIONS.has(ext);
|
|
49788
50307
|
});
|
|
49789
50308
|
if (sourceFiles.length === 0) {
|
|
@@ -49833,7 +50352,7 @@ var init_test_runner = __esm(() => {
|
|
|
49833
50352
|
if (isConventionTestFilePath(f)) {
|
|
49834
50353
|
return false;
|
|
49835
50354
|
}
|
|
49836
|
-
const ext =
|
|
50355
|
+
const ext = path39.extname(f).toLowerCase();
|
|
49837
50356
|
return SOURCE_EXTENSIONS.has(ext);
|
|
49838
50357
|
});
|
|
49839
50358
|
if (sourceFiles.length === 0) {
|
|
@@ -49885,8 +50404,8 @@ var init_test_runner = __esm(() => {
|
|
|
49885
50404
|
}
|
|
49886
50405
|
if (impactResult.impactedTests.length > 0) {
|
|
49887
50406
|
testFiles = impactResult.impactedTests.map((absPath) => {
|
|
49888
|
-
const relativePath =
|
|
49889
|
-
return
|
|
50407
|
+
const relativePath = path39.relative(workingDir, absPath);
|
|
50408
|
+
return path39.isAbsolute(relativePath) ? absPath : relativePath;
|
|
49890
50409
|
});
|
|
49891
50410
|
} else {
|
|
49892
50411
|
graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
|
|
@@ -49962,7 +50481,7 @@ var init_test_runner = __esm(() => {
|
|
|
49962
50481
|
|
|
49963
50482
|
// src/services/preflight-service.ts
|
|
49964
50483
|
import * as fs23 from "fs";
|
|
49965
|
-
import * as
|
|
50484
|
+
import * as path40 from "path";
|
|
49966
50485
|
function validateDirectoryPath(dir) {
|
|
49967
50486
|
if (!dir || typeof dir !== "string") {
|
|
49968
50487
|
throw new Error("Directory path is required");
|
|
@@ -49970,8 +50489,8 @@ function validateDirectoryPath(dir) {
|
|
|
49970
50489
|
if (dir.includes("..")) {
|
|
49971
50490
|
throw new Error("Directory path must not contain path traversal sequences");
|
|
49972
50491
|
}
|
|
49973
|
-
const normalized =
|
|
49974
|
-
const absolutePath =
|
|
50492
|
+
const normalized = path40.normalize(dir);
|
|
50493
|
+
const absolutePath = path40.isAbsolute(normalized) ? normalized : path40.resolve(normalized);
|
|
49975
50494
|
return absolutePath;
|
|
49976
50495
|
}
|
|
49977
50496
|
function validateTimeout(timeoutMs, defaultValue) {
|
|
@@ -49994,7 +50513,7 @@ function validateTimeout(timeoutMs, defaultValue) {
|
|
|
49994
50513
|
}
|
|
49995
50514
|
function getPackageVersion(dir) {
|
|
49996
50515
|
try {
|
|
49997
|
-
const packagePath =
|
|
50516
|
+
const packagePath = path40.join(dir, "package.json");
|
|
49998
50517
|
if (fs23.existsSync(packagePath)) {
|
|
49999
50518
|
const content = fs23.readFileSync(packagePath, "utf-8");
|
|
50000
50519
|
const pkg = JSON.parse(content);
|
|
@@ -50005,7 +50524,7 @@ function getPackageVersion(dir) {
|
|
|
50005
50524
|
}
|
|
50006
50525
|
function getChangelogVersion(dir) {
|
|
50007
50526
|
try {
|
|
50008
|
-
const changelogPath =
|
|
50527
|
+
const changelogPath = path40.join(dir, "CHANGELOG.md");
|
|
50009
50528
|
if (fs23.existsSync(changelogPath)) {
|
|
50010
50529
|
const content = fs23.readFileSync(changelogPath, "utf-8");
|
|
50011
50530
|
const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
|
|
@@ -50019,7 +50538,7 @@ function getChangelogVersion(dir) {
|
|
|
50019
50538
|
function getVersionFileVersion(dir) {
|
|
50020
50539
|
const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
|
|
50021
50540
|
for (const file3 of possibleFiles) {
|
|
50022
|
-
const filePath =
|
|
50541
|
+
const filePath = path40.join(dir, file3);
|
|
50023
50542
|
if (fs23.existsSync(filePath)) {
|
|
50024
50543
|
try {
|
|
50025
50544
|
const content = fs23.readFileSync(filePath, "utf-8").trim();
|
|
@@ -50035,9 +50554,9 @@ function getVersionFileVersion(dir) {
|
|
|
50035
50554
|
async function runVersionCheck(dir, _timeoutMs) {
|
|
50036
50555
|
const startTime = Date.now();
|
|
50037
50556
|
try {
|
|
50038
|
-
const packageVersion =
|
|
50039
|
-
const changelogVersion =
|
|
50040
|
-
const versionFileVersion =
|
|
50557
|
+
const packageVersion = _internals27.getPackageVersion(dir);
|
|
50558
|
+
const changelogVersion = _internals27.getChangelogVersion(dir);
|
|
50559
|
+
const versionFileVersion = _internals27.getVersionFileVersion(dir);
|
|
50041
50560
|
const versions3 = [];
|
|
50042
50561
|
if (packageVersion)
|
|
50043
50562
|
versions3.push(`package.json: ${packageVersion}`);
|
|
@@ -50309,7 +50828,22 @@ async function runEvidenceCheck(dir) {
|
|
|
50309
50828
|
};
|
|
50310
50829
|
}
|
|
50311
50830
|
const evidenceTaskIds = new Set(await listEvidenceTaskIds(dir));
|
|
50312
|
-
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;
|
|
50313
50847
|
if (missingEvidence.length > 0) {
|
|
50314
50848
|
return {
|
|
50315
50849
|
type: "evidence",
|
|
@@ -50317,7 +50851,7 @@ async function runEvidenceCheck(dir) {
|
|
|
50317
50851
|
message: `${missingEvidence.length} completed task(s) missing evidence`,
|
|
50318
50852
|
details: {
|
|
50319
50853
|
totalCompleted: completedTaskIds.length,
|
|
50320
|
-
totalWithEvidence:
|
|
50854
|
+
totalWithEvidence: completedWithEvidence,
|
|
50321
50855
|
missingTasks: missingEvidence.slice(0, 10),
|
|
50322
50856
|
missingCount: missingEvidence.length
|
|
50323
50857
|
},
|
|
@@ -50330,7 +50864,7 @@ async function runEvidenceCheck(dir) {
|
|
|
50330
50864
|
message: `All ${completedTaskIds.length} completed tasks have evidence`,
|
|
50331
50865
|
details: {
|
|
50332
50866
|
totalCompleted: completedTaskIds.length,
|
|
50333
|
-
totalWithEvidence:
|
|
50867
|
+
totalWithEvidence: completedWithEvidence
|
|
50334
50868
|
},
|
|
50335
50869
|
durationMs: Date.now() - startTime
|
|
50336
50870
|
};
|
|
@@ -50346,7 +50880,7 @@ async function runEvidenceCheck(dir) {
|
|
|
50346
50880
|
async function runRequirementCoverageCheck(dir, currentPhase) {
|
|
50347
50881
|
const startTime = Date.now();
|
|
50348
50882
|
try {
|
|
50349
|
-
const specPath =
|
|
50883
|
+
const specPath = path40.join(dir, ".swarm", "spec.md");
|
|
50350
50884
|
if (!fs23.existsSync(specPath)) {
|
|
50351
50885
|
return {
|
|
50352
50886
|
type: "req_coverage",
|
|
@@ -50387,7 +50921,7 @@ async function runPreflight(dir, phase, config3) {
|
|
|
50387
50921
|
const reportId = `preflight-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
50388
50922
|
let validatedDir;
|
|
50389
50923
|
try {
|
|
50390
|
-
validatedDir =
|
|
50924
|
+
validatedDir = _internals27.validateDirectoryPath(dir);
|
|
50391
50925
|
} catch (error93) {
|
|
50392
50926
|
return {
|
|
50393
50927
|
id: reportId,
|
|
@@ -50407,7 +50941,7 @@ async function runPreflight(dir, phase, config3) {
|
|
|
50407
50941
|
}
|
|
50408
50942
|
let validatedTimeout;
|
|
50409
50943
|
try {
|
|
50410
|
-
validatedTimeout =
|
|
50944
|
+
validatedTimeout = _internals27.validateTimeout(config3?.checkTimeoutMs, DEFAULT_CONFIG.checkTimeoutMs);
|
|
50411
50945
|
} catch (error93) {
|
|
50412
50946
|
return {
|
|
50413
50947
|
id: reportId,
|
|
@@ -50448,12 +50982,12 @@ async function runPreflight(dir, phase, config3) {
|
|
|
50448
50982
|
});
|
|
50449
50983
|
const checks5 = [];
|
|
50450
50984
|
log("[Preflight] Running lint check...");
|
|
50451
|
-
const lintResult = await
|
|
50985
|
+
const lintResult = await _internals27.runLintCheck(validatedDir, cfg.linter, cfg.checkTimeoutMs);
|
|
50452
50986
|
checks5.push(lintResult);
|
|
50453
50987
|
log(`[Preflight] Lint check: ${lintResult.status} ${lintResult.message}`);
|
|
50454
50988
|
if (!cfg.skipTests) {
|
|
50455
50989
|
log("[Preflight] Running tests check...");
|
|
50456
|
-
const testsResult = await
|
|
50990
|
+
const testsResult = await _internals27.runTestsCheck(validatedDir, cfg.testScope, cfg.checkTimeoutMs);
|
|
50457
50991
|
checks5.push(testsResult);
|
|
50458
50992
|
log(`[Preflight] Tests check: ${testsResult.status} ${testsResult.message}`);
|
|
50459
50993
|
} else {
|
|
@@ -50465,7 +50999,7 @@ async function runPreflight(dir, phase, config3) {
|
|
|
50465
50999
|
}
|
|
50466
51000
|
if (!cfg.skipSecrets) {
|
|
50467
51001
|
log("[Preflight] Running secrets check...");
|
|
50468
|
-
const secretsResult = await
|
|
51002
|
+
const secretsResult = await _internals27.runSecretsCheck(validatedDir, cfg.checkTimeoutMs);
|
|
50469
51003
|
checks5.push(secretsResult);
|
|
50470
51004
|
log(`[Preflight] Secrets check: ${secretsResult.status} ${secretsResult.message}`);
|
|
50471
51005
|
} else {
|
|
@@ -50477,7 +51011,7 @@ async function runPreflight(dir, phase, config3) {
|
|
|
50477
51011
|
}
|
|
50478
51012
|
if (!cfg.skipEvidence) {
|
|
50479
51013
|
log("[Preflight] Running evidence check...");
|
|
50480
|
-
const evidenceResult = await
|
|
51014
|
+
const evidenceResult = await _internals27.runEvidenceCheck(validatedDir);
|
|
50481
51015
|
checks5.push(evidenceResult);
|
|
50482
51016
|
log(`[Preflight] Evidence check: ${evidenceResult.status} ${evidenceResult.message}`);
|
|
50483
51017
|
} else {
|
|
@@ -50488,12 +51022,12 @@ async function runPreflight(dir, phase, config3) {
|
|
|
50488
51022
|
});
|
|
50489
51023
|
}
|
|
50490
51024
|
log("[Preflight] Running requirement coverage check...");
|
|
50491
|
-
const reqCoverageResult = await
|
|
51025
|
+
const reqCoverageResult = await _internals27.runRequirementCoverageCheck(validatedDir, phase);
|
|
50492
51026
|
checks5.push(reqCoverageResult);
|
|
50493
51027
|
log(`[Preflight] Requirement coverage check: ${reqCoverageResult.status} ${reqCoverageResult.message}`);
|
|
50494
51028
|
if (!cfg.skipVersion) {
|
|
50495
51029
|
log("[Preflight] Running version check...");
|
|
50496
|
-
const versionResult = await
|
|
51030
|
+
const versionResult = await _internals27.runVersionCheck(validatedDir, cfg.checkTimeoutMs);
|
|
50497
51031
|
checks5.push(versionResult);
|
|
50498
51032
|
log(`[Preflight] Version check: ${versionResult.status} ${versionResult.message}`);
|
|
50499
51033
|
} else {
|
|
@@ -50556,11 +51090,12 @@ function formatPreflightMarkdown(report) {
|
|
|
50556
51090
|
async function handlePreflightCommand(directory, _args) {
|
|
50557
51091
|
const plan = await loadPlan(directory);
|
|
50558
51092
|
const phase = plan?.current_phase ?? 1;
|
|
50559
|
-
const report = await
|
|
50560
|
-
return
|
|
51093
|
+
const report = await _internals27.runPreflight(directory, phase);
|
|
51094
|
+
return _internals27.formatPreflightMarkdown(report);
|
|
50561
51095
|
}
|
|
50562
|
-
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;
|
|
50563
51097
|
var init_preflight_service = __esm(() => {
|
|
51098
|
+
init_gate_bridge();
|
|
50564
51099
|
init_manager2();
|
|
50565
51100
|
init_manager();
|
|
50566
51101
|
init_lint();
|
|
@@ -50576,7 +51111,7 @@ var init_preflight_service = __esm(() => {
|
|
|
50576
51111
|
testScope: "convention",
|
|
50577
51112
|
linter: "biome"
|
|
50578
51113
|
};
|
|
50579
|
-
|
|
51114
|
+
_internals27 = {
|
|
50580
51115
|
runPreflight,
|
|
50581
51116
|
formatPreflightMarkdown,
|
|
50582
51117
|
handlePreflightCommand,
|
|
@@ -51463,7 +51998,7 @@ var init_manager3 = __esm(() => {
|
|
|
51463
51998
|
|
|
51464
51999
|
// src/commands/reset.ts
|
|
51465
52000
|
import * as fs24 from "fs";
|
|
51466
|
-
import * as
|
|
52001
|
+
import * as path41 from "path";
|
|
51467
52002
|
async function handleResetCommand(directory, args) {
|
|
51468
52003
|
const hasConfirm = args.includes("--confirm");
|
|
51469
52004
|
if (!hasConfirm) {
|
|
@@ -51503,7 +52038,7 @@ async function handleResetCommand(directory, args) {
|
|
|
51503
52038
|
}
|
|
51504
52039
|
for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
|
|
51505
52040
|
try {
|
|
51506
|
-
const rootPath =
|
|
52041
|
+
const rootPath = path41.join(directory, filename);
|
|
51507
52042
|
if (fs24.existsSync(rootPath)) {
|
|
51508
52043
|
fs24.unlinkSync(rootPath);
|
|
51509
52044
|
results.push(`- \u2705 Deleted ${filename} (root)`);
|
|
@@ -51543,7 +52078,7 @@ var init_reset = __esm(() => {
|
|
|
51543
52078
|
|
|
51544
52079
|
// src/commands/reset-session.ts
|
|
51545
52080
|
import * as fs25 from "fs";
|
|
51546
|
-
import * as
|
|
52081
|
+
import * as path42 from "path";
|
|
51547
52082
|
async function handleResetSessionCommand(directory, _args) {
|
|
51548
52083
|
const results = [];
|
|
51549
52084
|
try {
|
|
@@ -51558,13 +52093,13 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
51558
52093
|
results.push("\u274C Failed to delete state.json");
|
|
51559
52094
|
}
|
|
51560
52095
|
try {
|
|
51561
|
-
const sessionDir =
|
|
52096
|
+
const sessionDir = path42.dirname(validateSwarmPath(directory, "session/state.json"));
|
|
51562
52097
|
if (fs25.existsSync(sessionDir)) {
|
|
51563
52098
|
const files = fs25.readdirSync(sessionDir);
|
|
51564
52099
|
const otherFiles = files.filter((f) => f !== "state.json");
|
|
51565
52100
|
let deletedCount = 0;
|
|
51566
52101
|
for (const file3 of otherFiles) {
|
|
51567
|
-
const filePath =
|
|
52102
|
+
const filePath = path42.join(sessionDir, file3);
|
|
51568
52103
|
if (fs25.lstatSync(filePath).isFile()) {
|
|
51569
52104
|
fs25.unlinkSync(filePath);
|
|
51570
52105
|
deletedCount++;
|
|
@@ -51596,7 +52131,7 @@ var init_reset_session = __esm(() => {
|
|
|
51596
52131
|
});
|
|
51597
52132
|
|
|
51598
52133
|
// src/summaries/manager.ts
|
|
51599
|
-
import * as
|
|
52134
|
+
import * as path43 from "path";
|
|
51600
52135
|
function sanitizeSummaryId(id) {
|
|
51601
52136
|
if (!id || id.length === 0) {
|
|
51602
52137
|
throw new Error("Invalid summary ID: empty string");
|
|
@@ -51619,7 +52154,7 @@ function sanitizeSummaryId(id) {
|
|
|
51619
52154
|
}
|
|
51620
52155
|
async function loadFullOutput(directory, id) {
|
|
51621
52156
|
const sanitizedId = sanitizeSummaryId(id);
|
|
51622
|
-
const relativePath =
|
|
52157
|
+
const relativePath = path43.join("summaries", `${sanitizedId}.json`);
|
|
51623
52158
|
validateSwarmPath(directory, relativePath);
|
|
51624
52159
|
const content = await readSwarmFileAsync(directory, relativePath);
|
|
51625
52160
|
if (content === null) {
|
|
@@ -51682,7 +52217,7 @@ var init_retrieve = __esm(() => {
|
|
|
51682
52217
|
|
|
51683
52218
|
// src/commands/rollback.ts
|
|
51684
52219
|
import * as fs26 from "fs";
|
|
51685
|
-
import * as
|
|
52220
|
+
import * as path44 from "path";
|
|
51686
52221
|
async function handleRollbackCommand(directory, args) {
|
|
51687
52222
|
const phaseArg = args[0];
|
|
51688
52223
|
if (!phaseArg) {
|
|
@@ -51747,8 +52282,8 @@ async function handleRollbackCommand(directory, args) {
|
|
|
51747
52282
|
if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
|
|
51748
52283
|
continue;
|
|
51749
52284
|
}
|
|
51750
|
-
const src =
|
|
51751
|
-
const dest =
|
|
52285
|
+
const src = path44.join(checkpointDir, file3);
|
|
52286
|
+
const dest = path44.join(swarmDir, file3);
|
|
51752
52287
|
try {
|
|
51753
52288
|
fs26.cpSync(src, dest, { recursive: true, force: true });
|
|
51754
52289
|
successes.push(file3);
|
|
@@ -51767,12 +52302,12 @@ async function handleRollbackCommand(directory, args) {
|
|
|
51767
52302
|
].join(`
|
|
51768
52303
|
`);
|
|
51769
52304
|
}
|
|
51770
|
-
const existingLedgerPath =
|
|
52305
|
+
const existingLedgerPath = path44.join(swarmDir, "plan-ledger.jsonl");
|
|
51771
52306
|
if (fs26.existsSync(existingLedgerPath)) {
|
|
51772
52307
|
fs26.unlinkSync(existingLedgerPath);
|
|
51773
52308
|
}
|
|
51774
52309
|
try {
|
|
51775
|
-
const planJsonPath =
|
|
52310
|
+
const planJsonPath = path44.join(swarmDir, "plan.json");
|
|
51776
52311
|
if (fs26.existsSync(planJsonPath)) {
|
|
51777
52312
|
const planRaw = fs26.readFileSync(planJsonPath, "utf-8");
|
|
51778
52313
|
const plan = PlanSchema.parse(JSON.parse(planRaw));
|
|
@@ -51833,7 +52368,7 @@ async function handleSimulateCommand(directory, args) {
|
|
|
51833
52368
|
}
|
|
51834
52369
|
let darkMatterPairs;
|
|
51835
52370
|
try {
|
|
51836
|
-
darkMatterPairs = await
|
|
52371
|
+
darkMatterPairs = await _internals11.detectDarkMatter(directory, options);
|
|
51837
52372
|
} catch (err) {
|
|
51838
52373
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
51839
52374
|
return `## Simulate Report
|
|
@@ -51863,9 +52398,9 @@ Ensure this is a git repository with commit history.`;
|
|
|
51863
52398
|
`);
|
|
51864
52399
|
try {
|
|
51865
52400
|
const fs27 = await import("fs/promises");
|
|
51866
|
-
const
|
|
51867
|
-
const reportPath =
|
|
51868
|
-
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 });
|
|
51869
52404
|
await fs27.writeFile(reportPath, report, "utf-8");
|
|
51870
52405
|
} catch (err) {
|
|
51871
52406
|
const writeErr = err instanceof Error ? err.message : String(err);
|
|
@@ -51889,12 +52424,12 @@ async function handleSpecifyCommand(_directory, args) {
|
|
|
51889
52424
|
|
|
51890
52425
|
// src/turbo/lean/state.ts
|
|
51891
52426
|
import * as fs27 from "fs";
|
|
51892
|
-
import * as
|
|
52427
|
+
import * as path45 from "path";
|
|
51893
52428
|
function nowISO2() {
|
|
51894
52429
|
return new Date().toISOString();
|
|
51895
52430
|
}
|
|
51896
52431
|
function ensureSwarmDir2(directory) {
|
|
51897
|
-
const swarmDir =
|
|
52432
|
+
const swarmDir = path45.resolve(directory, ".swarm");
|
|
51898
52433
|
if (!fs27.existsSync(swarmDir)) {
|
|
51899
52434
|
fs27.mkdirSync(swarmDir, { recursive: true });
|
|
51900
52435
|
}
|
|
@@ -51938,7 +52473,7 @@ function markStateUnreadable2(directory, reason) {
|
|
|
51938
52473
|
}
|
|
51939
52474
|
function readPersisted2(directory) {
|
|
51940
52475
|
try {
|
|
51941
|
-
const filePath =
|
|
52476
|
+
const filePath = path45.join(directory, ".swarm", STATE_FILE2);
|
|
51942
52477
|
if (!fs27.existsSync(filePath)) {
|
|
51943
52478
|
const seed = emptyPersisted2();
|
|
51944
52479
|
try {
|
|
@@ -51974,7 +52509,7 @@ function writePersisted2(directory, persisted) {
|
|
|
51974
52509
|
let payload;
|
|
51975
52510
|
try {
|
|
51976
52511
|
ensureSwarmDir2(directory);
|
|
51977
|
-
filePath =
|
|
52512
|
+
filePath = path45.join(directory, ".swarm", STATE_FILE2);
|
|
51978
52513
|
tmpPath = `${filePath}.tmp.${Date.now()}`;
|
|
51979
52514
|
persisted.updatedAt = nowISO2();
|
|
51980
52515
|
payload = `${JSON.stringify(persisted, null, 2)}
|
|
@@ -52101,10 +52636,10 @@ var init_context_budget_service = __esm(() => {
|
|
|
52101
52636
|
|
|
52102
52637
|
// src/services/status-service.ts
|
|
52103
52638
|
import * as fsSync2 from "fs";
|
|
52104
|
-
import * as
|
|
52639
|
+
import * as path46 from "path";
|
|
52105
52640
|
function readSpecStalenessSnapshot(directory) {
|
|
52106
52641
|
try {
|
|
52107
|
-
const p =
|
|
52642
|
+
const p = path46.join(directory, ".swarm", "spec-staleness.json");
|
|
52108
52643
|
if (!fsSync2.existsSync(p))
|
|
52109
52644
|
return { stale: false };
|
|
52110
52645
|
const raw = fsSync2.readFileSync(p, "utf-8");
|
|
@@ -52198,7 +52733,7 @@ async function getStatusData(directory, agents) {
|
|
|
52198
52733
|
}
|
|
52199
52734
|
function enrichWithLeanTurbo(status, directory) {
|
|
52200
52735
|
const turboMode = hasActiveTurboMode();
|
|
52201
|
-
const leanActive =
|
|
52736
|
+
const leanActive = _internals28.hasActiveLeanTurbo();
|
|
52202
52737
|
let turboStrategy = "off";
|
|
52203
52738
|
if (leanActive) {
|
|
52204
52739
|
turboStrategy = "lean";
|
|
@@ -52217,7 +52752,7 @@ function enrichWithLeanTurbo(status, directory) {
|
|
|
52217
52752
|
}
|
|
52218
52753
|
}
|
|
52219
52754
|
if (leanSessionID) {
|
|
52220
|
-
const runState =
|
|
52755
|
+
const runState = _internals28.loadLeanTurboRunState(directory, leanSessionID);
|
|
52221
52756
|
if (runState) {
|
|
52222
52757
|
status.leanTurboPhase = runState.phase;
|
|
52223
52758
|
status.leanMaxParallelCoders = runState.maxParallelCoders;
|
|
@@ -52249,7 +52784,7 @@ function enrichWithLeanTurbo(status, directory) {
|
|
|
52249
52784
|
}
|
|
52250
52785
|
}
|
|
52251
52786
|
}
|
|
52252
|
-
status.fullAutoActive =
|
|
52787
|
+
status.fullAutoActive = _internals28.hasActiveFullAuto();
|
|
52253
52788
|
return status;
|
|
52254
52789
|
}
|
|
52255
52790
|
function formatStatusMarkdown(status) {
|
|
@@ -52331,7 +52866,7 @@ async function handleStatusCommand(directory, agents) {
|
|
|
52331
52866
|
}
|
|
52332
52867
|
return formatStatusMarkdown(statusData);
|
|
52333
52868
|
}
|
|
52334
|
-
var
|
|
52869
|
+
var _internals28;
|
|
52335
52870
|
var init_status_service = __esm(() => {
|
|
52336
52871
|
init_extractors();
|
|
52337
52872
|
init_utils2();
|
|
@@ -52340,7 +52875,7 @@ var init_status_service = __esm(() => {
|
|
|
52340
52875
|
init_state3();
|
|
52341
52876
|
init_compaction_service();
|
|
52342
52877
|
init_context_budget_service();
|
|
52343
|
-
|
|
52878
|
+
_internals28 = {
|
|
52344
52879
|
loadLeanTurboRunState,
|
|
52345
52880
|
hasActiveLeanTurbo,
|
|
52346
52881
|
hasActiveFullAuto
|
|
@@ -52431,7 +52966,7 @@ async function handleTurboCommand(directory, args, sessionID) {
|
|
|
52431
52966
|
if (arg0 === "on") {
|
|
52432
52967
|
let strategy = "standard";
|
|
52433
52968
|
try {
|
|
52434
|
-
const { config: config3 } =
|
|
52969
|
+
const { config: config3 } = _internals29.loadPluginConfigWithMeta(directory);
|
|
52435
52970
|
if (config3.turbo?.strategy === "lean") {
|
|
52436
52971
|
strategy = "lean";
|
|
52437
52972
|
}
|
|
@@ -52486,7 +53021,7 @@ function enableLeanTurbo(session, directory, sessionID) {
|
|
|
52486
53021
|
let maxParallelCoders = 4;
|
|
52487
53022
|
let conflictPolicy = "serialize";
|
|
52488
53023
|
try {
|
|
52489
|
-
const { config: config3 } =
|
|
53024
|
+
const { config: config3 } = _internals29.loadPluginConfigWithMeta(directory);
|
|
52490
53025
|
const leanConfig = config3.turbo?.lean;
|
|
52491
53026
|
if (leanConfig) {
|
|
52492
53027
|
maxParallelCoders = leanConfig.max_parallel_coders ?? 4;
|
|
@@ -52556,13 +53091,13 @@ function buildStatusMessage(session, directory, sessionID) {
|
|
|
52556
53091
|
].join(`
|
|
52557
53092
|
`);
|
|
52558
53093
|
}
|
|
52559
|
-
var
|
|
53094
|
+
var _internals29;
|
|
52560
53095
|
var init_turbo = __esm(() => {
|
|
52561
53096
|
init_config();
|
|
52562
53097
|
init_state();
|
|
52563
53098
|
init_state3();
|
|
52564
53099
|
init_logger();
|
|
52565
|
-
|
|
53100
|
+
_internals29 = {
|
|
52566
53101
|
loadPluginConfigWithMeta
|
|
52567
53102
|
};
|
|
52568
53103
|
});
|
|
@@ -52630,7 +53165,7 @@ var init_write_retro2 = __esm(() => {
|
|
|
52630
53165
|
|
|
52631
53166
|
// src/commands/command-dispatch.ts
|
|
52632
53167
|
import fs28 from "fs";
|
|
52633
|
-
import
|
|
53168
|
+
import path47 from "path";
|
|
52634
53169
|
function normalizeSwarmCommandInput(command, argumentText) {
|
|
52635
53170
|
if (command !== "swarm" && !command.startsWith("swarm-")) {
|
|
52636
53171
|
return { isSwarmCommand: false, tokens: [] };
|
|
@@ -52655,7 +53190,7 @@ function formatCommandNotFound(tokens) {
|
|
|
52655
53190
|
const attemptedCommand = tokens[0] || "";
|
|
52656
53191
|
const MAX_DISPLAY = 100;
|
|
52657
53192
|
const displayCommand = attemptedCommand.length > MAX_DISPLAY ? `${attemptedCommand.slice(0, MAX_DISPLAY)}...` : attemptedCommand;
|
|
52658
|
-
const similar =
|
|
53193
|
+
const similar = _internals30.findSimilarCommands(attemptedCommand);
|
|
52659
53194
|
const header = `Command \`/swarm ${displayCommand}\` not found.`;
|
|
52660
53195
|
const suggestions = similar.length > 0 ? `Did you mean:
|
|
52661
53196
|
${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
|
|
@@ -52666,9 +53201,9 @@ ${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
|
|
|
52666
53201
|
`);
|
|
52667
53202
|
}
|
|
52668
53203
|
function maybeMarkFirstRun(directory) {
|
|
52669
|
-
const sentinelPath =
|
|
53204
|
+
const sentinelPath = path47.join(directory, ".swarm", ".first-run-complete");
|
|
52670
53205
|
try {
|
|
52671
|
-
const swarmDir =
|
|
53206
|
+
const swarmDir = path47.join(directory, ".swarm");
|
|
52672
53207
|
fs28.mkdirSync(swarmDir, { recursive: true });
|
|
52673
53208
|
fs28.writeFileSync(sentinelPath, `first-run-complete: ${new Date().toISOString()}
|
|
52674
53209
|
`, { flag: "wx" });
|
|
@@ -53104,7 +53639,7 @@ async function buildSwarmCommandPrompt(args) {
|
|
|
53104
53639
|
activeAgentName,
|
|
53105
53640
|
registeredAgents
|
|
53106
53641
|
} = args;
|
|
53107
|
-
const resolved =
|
|
53642
|
+
const resolved = _internals30.resolveCommand(tokens);
|
|
53108
53643
|
if (!resolved) {
|
|
53109
53644
|
if (tokens.length === 0) {
|
|
53110
53645
|
return buildHelpText();
|
|
@@ -53255,7 +53790,7 @@ function findSimilarCommands(query) {
|
|
|
53255
53790
|
}
|
|
53256
53791
|
const scored = VALID_COMMANDS.map((cmd) => {
|
|
53257
53792
|
const cmdLower = cmd.toLowerCase();
|
|
53258
|
-
const fullScore =
|
|
53793
|
+
const fullScore = _internals30.levenshteinDistance(q, cmdLower);
|
|
53259
53794
|
let tokenScore = Infinity;
|
|
53260
53795
|
if (cmd.includes(" ") || cmd.includes("-")) {
|
|
53261
53796
|
const qTokens = q.split(/[\s-]+/);
|
|
@@ -53268,7 +53803,7 @@ function findSimilarCommands(query) {
|
|
|
53268
53803
|
for (const ct of cmdTokens) {
|
|
53269
53804
|
if (ct.length === 0)
|
|
53270
53805
|
continue;
|
|
53271
|
-
const dist =
|
|
53806
|
+
const dist = _internals30.levenshteinDistance(qt, ct);
|
|
53272
53807
|
if (dist < minDist)
|
|
53273
53808
|
minDist = dist;
|
|
53274
53809
|
}
|
|
@@ -53278,7 +53813,7 @@ function findSimilarCommands(query) {
|
|
|
53278
53813
|
}
|
|
53279
53814
|
const dashStrippedQ = q.replace(/-/g, "");
|
|
53280
53815
|
const dashStrippedCmd = cmdLower.replace(/-/g, "");
|
|
53281
|
-
const dashScore =
|
|
53816
|
+
const dashScore = _internals30.levenshteinDistance(dashStrippedQ, dashStrippedCmd);
|
|
53282
53817
|
const score = Math.min(fullScore, tokenScore, dashScore);
|
|
53283
53818
|
return { cmd, score };
|
|
53284
53819
|
});
|
|
@@ -53310,11 +53845,11 @@ async function handleHelpCommand(ctx) {
|
|
|
53310
53845
|
return buildHelpText2();
|
|
53311
53846
|
}
|
|
53312
53847
|
const tokens = targetCommand.split(/\s+/);
|
|
53313
|
-
const resolved =
|
|
53848
|
+
const resolved = _internals30.resolveCommand(tokens);
|
|
53314
53849
|
if (resolved) {
|
|
53315
|
-
return
|
|
53850
|
+
return _internals30.buildDetailedHelp(resolved.key, resolved.entry);
|
|
53316
53851
|
}
|
|
53317
|
-
const similar =
|
|
53852
|
+
const similar = _internals30.findSimilarCommands(targetCommand);
|
|
53318
53853
|
const { buildHelpText: fullHelp } = await Promise.resolve().then(() => (init_commands(), exports_commands));
|
|
53319
53854
|
if (similar.length > 0) {
|
|
53320
53855
|
return `Command '/swarm ${targetCommand}' not found.
|
|
@@ -53350,24 +53885,24 @@ function validateAliases() {
|
|
|
53350
53885
|
}
|
|
53351
53886
|
aliasTargets.get(target).push(name);
|
|
53352
53887
|
const visited = new Set;
|
|
53353
|
-
const
|
|
53888
|
+
const path48 = [];
|
|
53354
53889
|
let current = target;
|
|
53355
53890
|
while (current) {
|
|
53356
53891
|
const currentEntry = COMMAND_REGISTRY[current];
|
|
53357
53892
|
if (!currentEntry)
|
|
53358
53893
|
break;
|
|
53359
53894
|
if (visited.has(current)) {
|
|
53360
|
-
const cycleStart =
|
|
53895
|
+
const cycleStart = path48.indexOf(current);
|
|
53361
53896
|
const fullChain = [
|
|
53362
53897
|
name,
|
|
53363
|
-
...
|
|
53898
|
+
...path48.slice(0, cycleStart > 0 ? cycleStart : path48.length),
|
|
53364
53899
|
current
|
|
53365
53900
|
].join(" \u2192 ");
|
|
53366
53901
|
errors5.push(`Circular alias detected: ${fullChain}`);
|
|
53367
53902
|
break;
|
|
53368
53903
|
}
|
|
53369
53904
|
visited.add(current);
|
|
53370
|
-
|
|
53905
|
+
path48.push(current);
|
|
53371
53906
|
current = currentEntry.aliasOf || "";
|
|
53372
53907
|
}
|
|
53373
53908
|
}
|
|
@@ -53408,7 +53943,7 @@ function resolveCommand(tokens) {
|
|
|
53408
53943
|
}
|
|
53409
53944
|
return null;
|
|
53410
53945
|
}
|
|
53411
|
-
var COMMAND_REGISTRY, VALID_COMMANDS,
|
|
53946
|
+
var COMMAND_REGISTRY, VALID_COMMANDS, _internals30, validation;
|
|
53412
53947
|
var init_registry = __esm(() => {
|
|
53413
53948
|
init_acknowledge_spec_drift();
|
|
53414
53949
|
init_agents();
|
|
@@ -53478,7 +54013,7 @@ var init_registry = __esm(() => {
|
|
|
53478
54013
|
clashesWithNativeCcCommand: "/agents"
|
|
53479
54014
|
},
|
|
53480
54015
|
help: {
|
|
53481
|
-
handler: (ctx) =>
|
|
54016
|
+
handler: (ctx) => _internals30.handleHelpCommand(ctx),
|
|
53482
54017
|
description: "Show help for swarm commands",
|
|
53483
54018
|
category: "core",
|
|
53484
54019
|
args: "[command]",
|
|
@@ -53850,7 +54385,7 @@ Subcommands:
|
|
|
53850
54385
|
}
|
|
53851
54386
|
};
|
|
53852
54387
|
VALID_COMMANDS = Object.keys(COMMAND_REGISTRY);
|
|
53853
|
-
|
|
54388
|
+
_internals30 = {
|
|
53854
54389
|
handleHelpCommand,
|
|
53855
54390
|
validateAliases,
|
|
53856
54391
|
resolveCommand,
|
|
@@ -53858,7 +54393,7 @@ Subcommands:
|
|
|
53858
54393
|
findSimilarCommands,
|
|
53859
54394
|
buildDetailedHelp
|
|
53860
54395
|
};
|
|
53861
|
-
validation =
|
|
54396
|
+
validation = _internals30.validateAliases();
|
|
53862
54397
|
if (!validation.valid) {
|
|
53863
54398
|
throw new Error(`COMMAND_REGISTRY alias validation failed:
|
|
53864
54399
|
${validation.errors.join(`
|
|
@@ -53878,53 +54413,53 @@ init_cache_paths();
|
|
|
53878
54413
|
init_constants();
|
|
53879
54414
|
import * as fs29 from "fs";
|
|
53880
54415
|
import * as os7 from "os";
|
|
53881
|
-
import * as
|
|
54416
|
+
import * as path48 from "path";
|
|
53882
54417
|
var { version: version4 } = package_default;
|
|
53883
54418
|
var CONFIG_DIR = getPluginConfigDir();
|
|
53884
|
-
var OPENCODE_CONFIG_PATH =
|
|
53885
|
-
var PLUGIN_CONFIG_PATH =
|
|
53886
|
-
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");
|
|
53887
54422
|
var OPENCODE_PLUGIN_CACHE_PATHS = getPluginCachePaths();
|
|
53888
54423
|
var OPENCODE_PLUGIN_LOCK_FILE_PATHS = getPluginLockFilePaths();
|
|
53889
54424
|
function isSafeCachePath(p) {
|
|
53890
|
-
const resolved =
|
|
53891
|
-
const home =
|
|
54425
|
+
const resolved = path48.resolve(p);
|
|
54426
|
+
const home = path48.resolve(os7.homedir());
|
|
53892
54427
|
if (resolved === "/" || resolved === home || resolved.length <= home.length) {
|
|
53893
54428
|
return false;
|
|
53894
54429
|
}
|
|
53895
|
-
const segments = resolved.split(
|
|
54430
|
+
const segments = resolved.split(path48.sep).filter((s) => s.length > 0);
|
|
53896
54431
|
if (segments.length < 4) {
|
|
53897
54432
|
return false;
|
|
53898
54433
|
}
|
|
53899
|
-
const leaf =
|
|
54434
|
+
const leaf = path48.basename(resolved);
|
|
53900
54435
|
if (leaf !== "opencode-swarm@latest" && leaf !== "opencode-swarm") {
|
|
53901
54436
|
return false;
|
|
53902
54437
|
}
|
|
53903
|
-
const parent =
|
|
54438
|
+
const parent = path48.basename(path48.dirname(resolved));
|
|
53904
54439
|
if (parent !== "packages" && parent !== "node_modules") {
|
|
53905
54440
|
return false;
|
|
53906
54441
|
}
|
|
53907
|
-
const grandparent =
|
|
54442
|
+
const grandparent = path48.basename(path48.dirname(path48.dirname(resolved)));
|
|
53908
54443
|
if (grandparent !== "opencode") {
|
|
53909
54444
|
return false;
|
|
53910
54445
|
}
|
|
53911
54446
|
return true;
|
|
53912
54447
|
}
|
|
53913
54448
|
function isSafeLockFilePath(p) {
|
|
53914
|
-
const resolved =
|
|
53915
|
-
const home =
|
|
54449
|
+
const resolved = path48.resolve(p);
|
|
54450
|
+
const home = path48.resolve(os7.homedir());
|
|
53916
54451
|
if (resolved === "/" || resolved === home || resolved.length <= home.length) {
|
|
53917
54452
|
return false;
|
|
53918
54453
|
}
|
|
53919
|
-
const segments = resolved.split(
|
|
54454
|
+
const segments = resolved.split(path48.sep).filter((s) => s.length > 0);
|
|
53920
54455
|
if (segments.length < 4) {
|
|
53921
54456
|
return false;
|
|
53922
54457
|
}
|
|
53923
|
-
const leaf =
|
|
54458
|
+
const leaf = path48.basename(resolved);
|
|
53924
54459
|
if (leaf !== "bun.lock" && leaf !== "bun.lockb" && leaf !== "package-lock.json") {
|
|
53925
54460
|
return false;
|
|
53926
54461
|
}
|
|
53927
|
-
const parent =
|
|
54462
|
+
const parent = path48.basename(path48.dirname(resolved));
|
|
53928
54463
|
if (parent !== "opencode") {
|
|
53929
54464
|
return false;
|
|
53930
54465
|
}
|
|
@@ -53950,8 +54485,8 @@ function saveJson(filepath, data) {
|
|
|
53950
54485
|
}
|
|
53951
54486
|
function writeProjectConfigIfMissing(cwd) {
|
|
53952
54487
|
try {
|
|
53953
|
-
const opencodeDir =
|
|
53954
|
-
const projectConfigPath =
|
|
54488
|
+
const opencodeDir = path48.join(cwd, ".opencode");
|
|
54489
|
+
const projectConfigPath = path48.join(opencodeDir, "opencode-swarm.json");
|
|
53955
54490
|
if (fs29.existsSync(projectConfigPath)) {
|
|
53956
54491
|
return;
|
|
53957
54492
|
}
|
|
@@ -53968,7 +54503,7 @@ async function install() {
|
|
|
53968
54503
|
`);
|
|
53969
54504
|
ensureDir(CONFIG_DIR);
|
|
53970
54505
|
ensureDir(PROMPTS_DIR);
|
|
53971
|
-
const LEGACY_CONFIG_PATH =
|
|
54506
|
+
const LEGACY_CONFIG_PATH = path48.join(CONFIG_DIR, "config.json");
|
|
53972
54507
|
let opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
|
|
53973
54508
|
if (!opencodeConfig) {
|
|
53974
54509
|
const legacyConfig = loadJson(LEGACY_CONFIG_PATH);
|