opencode-swarm 7.9.0 → 7.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +965 -702
- package/dist/git/branch.d.ts +19 -0
- package/dist/index.js +3131 -2868
- 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.10.0",
|
|
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",
|
|
@@ -34490,6 +34490,205 @@ function resetToRemoteBranch(cwd, options) {
|
|
|
34490
34490
|
};
|
|
34491
34491
|
}
|
|
34492
34492
|
}
|
|
34493
|
+
function resetToMainAfterMerge(cwd, options) {
|
|
34494
|
+
const warnings = [];
|
|
34495
|
+
try {
|
|
34496
|
+
const defaultBranch = _internals6.detectDefaultRemoteBranch(cwd);
|
|
34497
|
+
if (!defaultBranch) {
|
|
34498
|
+
return {
|
|
34499
|
+
success: false,
|
|
34500
|
+
targetBranch: "",
|
|
34501
|
+
previousBranch: "",
|
|
34502
|
+
message: "Could not detect default remote branch",
|
|
34503
|
+
branchDeleted: false,
|
|
34504
|
+
changesDiscarded: false,
|
|
34505
|
+
warnings
|
|
34506
|
+
};
|
|
34507
|
+
}
|
|
34508
|
+
const currentBranch = getCurrentBranch(cwd);
|
|
34509
|
+
const targetBranch = `origin/${defaultBranch}`;
|
|
34510
|
+
if (currentBranch === "HEAD") {
|
|
34511
|
+
return {
|
|
34512
|
+
success: false,
|
|
34513
|
+
targetBranch,
|
|
34514
|
+
previousBranch: "HEAD",
|
|
34515
|
+
message: "Cannot reset: detached HEAD state",
|
|
34516
|
+
branchDeleted: false,
|
|
34517
|
+
changesDiscarded: false,
|
|
34518
|
+
warnings
|
|
34519
|
+
};
|
|
34520
|
+
}
|
|
34521
|
+
if (currentBranch === defaultBranch) {
|
|
34522
|
+
try {
|
|
34523
|
+
const logOutput = _internals6.gitExec(["log", `${targetBranch}..HEAD`, "--oneline"], cwd);
|
|
34524
|
+
if (logOutput.trim().length > 0) {
|
|
34525
|
+
return {
|
|
34526
|
+
success: false,
|
|
34527
|
+
targetBranch,
|
|
34528
|
+
previousBranch: currentBranch,
|
|
34529
|
+
message: `Cannot reset: ${defaultBranch} has unpushed commits. Push them first.`,
|
|
34530
|
+
branchDeleted: false,
|
|
34531
|
+
changesDiscarded: false,
|
|
34532
|
+
warnings
|
|
34533
|
+
};
|
|
34534
|
+
}
|
|
34535
|
+
} catch {}
|
|
34536
|
+
} else {
|
|
34537
|
+
try {
|
|
34538
|
+
_internals6.gitExec(["rev-parse", "--abbrev-ref", `${currentBranch}@{upstream}`], cwd);
|
|
34539
|
+
} catch {
|
|
34540
|
+
try {
|
|
34541
|
+
const localSha = _internals6.gitExec(["rev-parse", "HEAD"], cwd).trim();
|
|
34542
|
+
const remoteSha = _internals6.gitExec(["rev-parse", targetBranch], cwd).trim();
|
|
34543
|
+
if (localSha !== remoteSha) {
|
|
34544
|
+
return {
|
|
34545
|
+
success: false,
|
|
34546
|
+
targetBranch,
|
|
34547
|
+
previousBranch: currentBranch,
|
|
34548
|
+
message: `Cannot reset: branch ${currentBranch} is local-only and diverges from ${defaultBranch}. Push or check manually.`,
|
|
34549
|
+
branchDeleted: false,
|
|
34550
|
+
changesDiscarded: false,
|
|
34551
|
+
warnings
|
|
34552
|
+
};
|
|
34553
|
+
}
|
|
34554
|
+
} catch {
|
|
34555
|
+
return {
|
|
34556
|
+
success: false,
|
|
34557
|
+
targetBranch,
|
|
34558
|
+
previousBranch: currentBranch,
|
|
34559
|
+
message: `Cannot reset: unable to compare ${currentBranch} with ${defaultBranch}`,
|
|
34560
|
+
branchDeleted: false,
|
|
34561
|
+
changesDiscarded: false,
|
|
34562
|
+
warnings
|
|
34563
|
+
};
|
|
34564
|
+
}
|
|
34565
|
+
}
|
|
34566
|
+
}
|
|
34567
|
+
try {
|
|
34568
|
+
_internals6.gitExec(["fetch", "--prune", "origin"], cwd);
|
|
34569
|
+
} catch (err) {
|
|
34570
|
+
return {
|
|
34571
|
+
success: false,
|
|
34572
|
+
targetBranch,
|
|
34573
|
+
previousBranch: currentBranch,
|
|
34574
|
+
message: `Cannot reset: fetch failed \u2014 ${err instanceof Error ? err.message : String(err)}`,
|
|
34575
|
+
branchDeleted: false,
|
|
34576
|
+
changesDiscarded: false,
|
|
34577
|
+
warnings
|
|
34578
|
+
};
|
|
34579
|
+
}
|
|
34580
|
+
const previousBranch = currentBranch;
|
|
34581
|
+
let switchedBranch = false;
|
|
34582
|
+
if (currentBranch !== defaultBranch) {
|
|
34583
|
+
try {
|
|
34584
|
+
_internals6.gitExec(["checkout", defaultBranch], cwd);
|
|
34585
|
+
switchedBranch = true;
|
|
34586
|
+
} catch (err) {
|
|
34587
|
+
return {
|
|
34588
|
+
success: false,
|
|
34589
|
+
targetBranch,
|
|
34590
|
+
previousBranch,
|
|
34591
|
+
message: `Checkout to ${defaultBranch} failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
34592
|
+
branchDeleted: false,
|
|
34593
|
+
changesDiscarded: false,
|
|
34594
|
+
warnings
|
|
34595
|
+
};
|
|
34596
|
+
}
|
|
34597
|
+
}
|
|
34598
|
+
try {
|
|
34599
|
+
_internals6.gitExec(["reset", "--hard", targetBranch], cwd);
|
|
34600
|
+
} catch (err) {
|
|
34601
|
+
return {
|
|
34602
|
+
success: false,
|
|
34603
|
+
targetBranch,
|
|
34604
|
+
previousBranch,
|
|
34605
|
+
message: `Reset to ${targetBranch} failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
34606
|
+
branchDeleted: false,
|
|
34607
|
+
changesDiscarded: false,
|
|
34608
|
+
warnings
|
|
34609
|
+
};
|
|
34610
|
+
}
|
|
34611
|
+
let changesDiscarded = false;
|
|
34612
|
+
if (hasUncommittedChanges(cwd)) {
|
|
34613
|
+
let discardSucceeded = false;
|
|
34614
|
+
for (let retry = 0;retry < 4; retry++) {
|
|
34615
|
+
if (retry > 0 && process.platform === "win32") {
|
|
34616
|
+
const endTime = Date.now() + 500;
|
|
34617
|
+
while (Date.now() < endTime) {}
|
|
34618
|
+
}
|
|
34619
|
+
try {
|
|
34620
|
+
_internals6.gitExec(["checkout", "--", "."], cwd);
|
|
34621
|
+
discardSucceeded = true;
|
|
34622
|
+
break;
|
|
34623
|
+
} catch {}
|
|
34624
|
+
}
|
|
34625
|
+
if (!discardSucceeded) {
|
|
34626
|
+
warnings.push("Could not discard all uncommitted changes after reset");
|
|
34627
|
+
}
|
|
34628
|
+
changesDiscarded = discardSucceeded;
|
|
34629
|
+
}
|
|
34630
|
+
try {
|
|
34631
|
+
_internals6.gitExec(["clean", "-fd"], cwd);
|
|
34632
|
+
} catch {
|
|
34633
|
+
warnings.push("Could not clean untracked files");
|
|
34634
|
+
}
|
|
34635
|
+
let branchDeleted = false;
|
|
34636
|
+
if (switchedBranch && previousBranch !== defaultBranch) {
|
|
34637
|
+
try {
|
|
34638
|
+
const mergedOutput = _internals6.gitExec(["branch", "--merged", defaultBranch], cwd);
|
|
34639
|
+
const isMerged = mergedOutput.split(`
|
|
34640
|
+
`).some((line) => line.trim() === previousBranch || line.trim() === `* ${previousBranch}`);
|
|
34641
|
+
if (isMerged) {
|
|
34642
|
+
_internals6.gitExec(["branch", "-d", previousBranch], cwd);
|
|
34643
|
+
branchDeleted = true;
|
|
34644
|
+
} else {
|
|
34645
|
+
warnings.push(`Branch ${previousBranch} is not merged into ${defaultBranch} \u2014 keeping it`);
|
|
34646
|
+
}
|
|
34647
|
+
} catch {
|
|
34648
|
+
warnings.push(`Could not delete branch ${previousBranch}`);
|
|
34649
|
+
}
|
|
34650
|
+
}
|
|
34651
|
+
if (options?.pruneBranches) {
|
|
34652
|
+
try {
|
|
34653
|
+
const mergedOutput = _internals6.gitExec(["branch", "--merged", defaultBranch], cwd);
|
|
34654
|
+
const mergedLines = mergedOutput.split(`
|
|
34655
|
+
`);
|
|
34656
|
+
for (const line of mergedLines) {
|
|
34657
|
+
const trimmedLine = line.trim();
|
|
34658
|
+
if (!trimmedLine || trimmedLine.startsWith("*") || trimmedLine === defaultBranch) {
|
|
34659
|
+
continue;
|
|
34660
|
+
}
|
|
34661
|
+
try {
|
|
34662
|
+
_internals6.gitExec(["branch", "-d", trimmedLine], cwd);
|
|
34663
|
+
} catch {
|
|
34664
|
+
warnings.push(`Could not prune branch: ${trimmedLine}`);
|
|
34665
|
+
}
|
|
34666
|
+
}
|
|
34667
|
+
} catch (err) {
|
|
34668
|
+
warnings.push(`Prune failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
34669
|
+
}
|
|
34670
|
+
}
|
|
34671
|
+
return {
|
|
34672
|
+
success: true,
|
|
34673
|
+
targetBranch,
|
|
34674
|
+
previousBranch,
|
|
34675
|
+
message: branchDeleted ? `Reset to ${defaultBranch} and deleted branch ${previousBranch}` : `Reset to ${defaultBranch}`,
|
|
34676
|
+
branchDeleted,
|
|
34677
|
+
changesDiscarded,
|
|
34678
|
+
warnings
|
|
34679
|
+
};
|
|
34680
|
+
} catch (err) {
|
|
34681
|
+
return {
|
|
34682
|
+
success: false,
|
|
34683
|
+
targetBranch: "",
|
|
34684
|
+
previousBranch: "",
|
|
34685
|
+
message: `Unexpected error: ${err instanceof Error ? err.message : String(err)}`,
|
|
34686
|
+
branchDeleted: false,
|
|
34687
|
+
changesDiscarded: false,
|
|
34688
|
+
warnings
|
|
34689
|
+
};
|
|
34690
|
+
}
|
|
34691
|
+
}
|
|
34493
34692
|
var GIT_TIMEOUT_MS2 = 30000, _internals6;
|
|
34494
34693
|
var init_branch = __esm(() => {
|
|
34495
34694
|
init_logger();
|
|
@@ -34497,10 +34696,81 @@ var init_branch = __esm(() => {
|
|
|
34497
34696
|
gitExec: gitExec2,
|
|
34498
34697
|
detectDefaultRemoteBranch,
|
|
34499
34698
|
getDefaultBaseBranch,
|
|
34500
|
-
resetToRemoteBranch
|
|
34699
|
+
resetToRemoteBranch,
|
|
34700
|
+
resetToMainAfterMerge
|
|
34501
34701
|
};
|
|
34502
34702
|
});
|
|
34503
34703
|
|
|
34704
|
+
// src/background/event-bus.ts
|
|
34705
|
+
class AutomationEventBus {
|
|
34706
|
+
listeners = new Map;
|
|
34707
|
+
eventHistory = [];
|
|
34708
|
+
maxHistorySize;
|
|
34709
|
+
constructor(options) {
|
|
34710
|
+
this.maxHistorySize = options?.maxHistorySize ?? 100;
|
|
34711
|
+
}
|
|
34712
|
+
subscribe(type, listener) {
|
|
34713
|
+
if (!this.listeners.has(type)) {
|
|
34714
|
+
this.listeners.set(type, new Set);
|
|
34715
|
+
}
|
|
34716
|
+
this.listeners.get(type).add(listener);
|
|
34717
|
+
return () => {
|
|
34718
|
+
this.listeners.get(type)?.delete(listener);
|
|
34719
|
+
};
|
|
34720
|
+
}
|
|
34721
|
+
async publish(type, payload, source) {
|
|
34722
|
+
const event = {
|
|
34723
|
+
type,
|
|
34724
|
+
timestamp: Date.now(),
|
|
34725
|
+
payload,
|
|
34726
|
+
source
|
|
34727
|
+
};
|
|
34728
|
+
this.eventHistory.push(event);
|
|
34729
|
+
if (this.eventHistory.length > this.maxHistorySize) {
|
|
34730
|
+
this.eventHistory.shift();
|
|
34731
|
+
}
|
|
34732
|
+
log(`[EventBus] ${type}`, {
|
|
34733
|
+
source,
|
|
34734
|
+
payload: typeof payload === "object" ? "..." : payload
|
|
34735
|
+
});
|
|
34736
|
+
const listeners = this.listeners.get(type);
|
|
34737
|
+
if (listeners) {
|
|
34738
|
+
await Promise.all(Array.from(listeners).map(async (listener) => {
|
|
34739
|
+
try {
|
|
34740
|
+
await listener(event);
|
|
34741
|
+
} catch (error93) {
|
|
34742
|
+
log(`[EventBus] Listener error for ${type}`, { error: error93 });
|
|
34743
|
+
}
|
|
34744
|
+
}));
|
|
34745
|
+
}
|
|
34746
|
+
}
|
|
34747
|
+
getHistory(types) {
|
|
34748
|
+
if (!types || types.length === 0) {
|
|
34749
|
+
return [...this.eventHistory];
|
|
34750
|
+
}
|
|
34751
|
+
return this.eventHistory.filter((e) => types.includes(e.type));
|
|
34752
|
+
}
|
|
34753
|
+
clearHistory() {
|
|
34754
|
+
this.eventHistory = [];
|
|
34755
|
+
}
|
|
34756
|
+
getListenerCount(type) {
|
|
34757
|
+
return this.listeners.get(type)?.size ?? 0;
|
|
34758
|
+
}
|
|
34759
|
+
hasListeners(type) {
|
|
34760
|
+
return this.getListenerCount(type) > 0;
|
|
34761
|
+
}
|
|
34762
|
+
}
|
|
34763
|
+
function getGlobalEventBus() {
|
|
34764
|
+
if (!globalEventBus) {
|
|
34765
|
+
globalEventBus = new AutomationEventBus;
|
|
34766
|
+
}
|
|
34767
|
+
return globalEventBus;
|
|
34768
|
+
}
|
|
34769
|
+
var globalEventBus = null;
|
|
34770
|
+
var init_event_bus = __esm(() => {
|
|
34771
|
+
init_utils();
|
|
34772
|
+
});
|
|
34773
|
+
|
|
34504
34774
|
// src/hooks/knowledge-store.ts
|
|
34505
34775
|
import { existsSync as existsSync7 } from "fs";
|
|
34506
34776
|
import { appendFile as appendFile2, mkdir as mkdir2, readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
|
|
@@ -34668,78 +34938,9 @@ var init_knowledge_store = __esm(() => {
|
|
|
34668
34938
|
import_proper_lockfile3 = __toESM(require_proper_lockfile(), 1);
|
|
34669
34939
|
});
|
|
34670
34940
|
|
|
34671
|
-
// src/hooks/knowledge-reader.ts
|
|
34672
|
-
import { existsSync as existsSync8 } from "fs";
|
|
34673
|
-
import { mkdir as mkdir3, readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
|
|
34674
|
-
import * as path11 from "path";
|
|
34675
|
-
async function updateRetrievalOutcome(directory, phaseInfo, phaseSucceeded) {
|
|
34676
|
-
const shownFile = path11.join(directory, ".swarm", ".knowledge-shown.json");
|
|
34677
|
-
try {
|
|
34678
|
-
if (!existsSync8(shownFile)) {
|
|
34679
|
-
return;
|
|
34680
|
-
}
|
|
34681
|
-
const content = await readFile4(shownFile, "utf-8");
|
|
34682
|
-
const shownData = JSON.parse(content);
|
|
34683
|
-
const shownIds = shownData[phaseInfo];
|
|
34684
|
-
if (!shownIds || shownIds.length === 0) {
|
|
34685
|
-
return;
|
|
34686
|
-
}
|
|
34687
|
-
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
34688
|
-
const entries = await readKnowledge(swarmPath);
|
|
34689
|
-
let updated = false;
|
|
34690
|
-
const foundInSwarm = new Set;
|
|
34691
|
-
for (const entry of entries) {
|
|
34692
|
-
if (shownIds.includes(entry.id)) {
|
|
34693
|
-
entry.retrieval_outcomes.applied_count++;
|
|
34694
|
-
if (phaseSucceeded) {
|
|
34695
|
-
entry.retrieval_outcomes.succeeded_after_count++;
|
|
34696
|
-
} else {
|
|
34697
|
-
entry.retrieval_outcomes.failed_after_count++;
|
|
34698
|
-
}
|
|
34699
|
-
updated = true;
|
|
34700
|
-
foundInSwarm.add(entry.id);
|
|
34701
|
-
}
|
|
34702
|
-
}
|
|
34703
|
-
if (updated) {
|
|
34704
|
-
await rewriteKnowledge(swarmPath, entries);
|
|
34705
|
-
}
|
|
34706
|
-
const remainingIds = shownIds.filter((id) => !foundInSwarm.has(id));
|
|
34707
|
-
if (remainingIds.length === 0) {
|
|
34708
|
-
delete shownData[phaseInfo];
|
|
34709
|
-
await writeFile4(shownFile, JSON.stringify(shownData, null, 2), "utf-8");
|
|
34710
|
-
return;
|
|
34711
|
-
}
|
|
34712
|
-
const hivePath = resolveHiveKnowledgePath();
|
|
34713
|
-
const hiveEntries = await readKnowledge(hivePath);
|
|
34714
|
-
let hiveUpdated = false;
|
|
34715
|
-
for (const entry of hiveEntries) {
|
|
34716
|
-
if (remainingIds.includes(entry.id)) {
|
|
34717
|
-
entry.retrieval_outcomes.applied_count++;
|
|
34718
|
-
if (phaseSucceeded) {
|
|
34719
|
-
entry.retrieval_outcomes.succeeded_after_count++;
|
|
34720
|
-
} else {
|
|
34721
|
-
entry.retrieval_outcomes.failed_after_count++;
|
|
34722
|
-
}
|
|
34723
|
-
hiveUpdated = true;
|
|
34724
|
-
}
|
|
34725
|
-
}
|
|
34726
|
-
if (hiveUpdated) {
|
|
34727
|
-
await rewriteKnowledge(hivePath, hiveEntries);
|
|
34728
|
-
}
|
|
34729
|
-
delete shownData[phaseInfo];
|
|
34730
|
-
await writeFile4(shownFile, JSON.stringify(shownData, null, 2), "utf-8");
|
|
34731
|
-
} catch {
|
|
34732
|
-
warn("[swarm] Knowledge: failed to update retrieval outcomes");
|
|
34733
|
-
}
|
|
34734
|
-
}
|
|
34735
|
-
var init_knowledge_reader = __esm(() => {
|
|
34736
|
-
init_logger();
|
|
34737
|
-
init_knowledge_store();
|
|
34738
|
-
});
|
|
34739
|
-
|
|
34740
34941
|
// src/hooks/knowledge-validator.ts
|
|
34741
|
-
import { appendFile as appendFile3, mkdir as
|
|
34742
|
-
import * as
|
|
34942
|
+
import { appendFile as appendFile3, mkdir as mkdir3, writeFile as writeFile4 } from "fs/promises";
|
|
34943
|
+
import * as path11 from "path";
|
|
34743
34944
|
function normalizeText(text) {
|
|
34744
34945
|
return text.normalize("NFKC").toLowerCase().replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
|
|
34745
34946
|
}
|
|
@@ -34893,11 +35094,11 @@ async function quarantineEntry(directory, entryId, reason, reportedBy) {
|
|
|
34893
35094
|
return;
|
|
34894
35095
|
}
|
|
34895
35096
|
const sanitizedReason = reason.slice(0, 500).replace(/[\x00-\x08\x0b-\x0c\x0e-\x1f\x7f\x0d]/g, "");
|
|
34896
|
-
const knowledgePath =
|
|
34897
|
-
const quarantinePath =
|
|
34898
|
-
const rejectedPath =
|
|
34899
|
-
const swarmDir =
|
|
34900
|
-
await
|
|
35097
|
+
const knowledgePath = path11.join(directory, ".swarm", "knowledge.jsonl");
|
|
35098
|
+
const quarantinePath = path11.join(directory, ".swarm", "knowledge-quarantined.jsonl");
|
|
35099
|
+
const rejectedPath = path11.join(directory, ".swarm", "knowledge-rejected.jsonl");
|
|
35100
|
+
const swarmDir = path11.join(directory, ".swarm");
|
|
35101
|
+
await mkdir3(swarmDir, { recursive: true });
|
|
34901
35102
|
let release;
|
|
34902
35103
|
try {
|
|
34903
35104
|
release = await import_proper_lockfile4.default.lock(swarmDir, {
|
|
@@ -34918,7 +35119,7 @@ async function quarantineEntry(directory, entryId, reason, reportedBy) {
|
|
|
34918
35119
|
const jsonlContent = remaining.length > 0 ? `${remaining.map((e) => JSON.stringify(e)).join(`
|
|
34919
35120
|
`)}
|
|
34920
35121
|
` : "";
|
|
34921
|
-
await
|
|
35122
|
+
await writeFile4(knowledgePath, jsonlContent, "utf-8");
|
|
34922
35123
|
await appendFile3(quarantinePath, `${JSON.stringify(quarantined)}
|
|
34923
35124
|
`, "utf-8");
|
|
34924
35125
|
const quarantinedEntries = await readKnowledge(quarantinePath);
|
|
@@ -34927,7 +35128,7 @@ async function quarantineEntry(directory, entryId, reason, reportedBy) {
|
|
|
34927
35128
|
const capContent = trimmed.length > 0 ? `${trimmed.map((e) => JSON.stringify(e)).join(`
|
|
34928
35129
|
`)}
|
|
34929
35130
|
` : "";
|
|
34930
|
-
await
|
|
35131
|
+
await writeFile4(quarantinePath, capContent, "utf-8");
|
|
34931
35132
|
}
|
|
34932
35133
|
const rejectedRecord = {
|
|
34933
35134
|
id: entryId,
|
|
@@ -34953,11 +35154,11 @@ async function restoreEntry(directory, entryId) {
|
|
|
34953
35154
|
warn("[knowledge-validator] restoreEntry: invalid entryId rejected");
|
|
34954
35155
|
return;
|
|
34955
35156
|
}
|
|
34956
|
-
const knowledgePath =
|
|
34957
|
-
const quarantinePath =
|
|
34958
|
-
const rejectedPath =
|
|
34959
|
-
const swarmDir =
|
|
34960
|
-
await
|
|
35157
|
+
const knowledgePath = path11.join(directory, ".swarm", "knowledge.jsonl");
|
|
35158
|
+
const quarantinePath = path11.join(directory, ".swarm", "knowledge-quarantined.jsonl");
|
|
35159
|
+
const rejectedPath = path11.join(directory, ".swarm", "knowledge-rejected.jsonl");
|
|
35160
|
+
const swarmDir = path11.join(directory, ".swarm");
|
|
35161
|
+
await mkdir3(swarmDir, { recursive: true });
|
|
34961
35162
|
let release;
|
|
34962
35163
|
try {
|
|
34963
35164
|
release = await import_proper_lockfile4.default.lock(swarmDir, {
|
|
@@ -34973,7 +35174,7 @@ async function restoreEntry(directory, entryId) {
|
|
|
34973
35174
|
const jsonlContent = remaining.length > 0 ? `${remaining.map((e) => JSON.stringify(e)).join(`
|
|
34974
35175
|
`)}
|
|
34975
35176
|
` : "";
|
|
34976
|
-
await
|
|
35177
|
+
await writeFile4(quarantinePath, jsonlContent, "utf-8");
|
|
34977
35178
|
await appendFile3(knowledgePath, `${JSON.stringify(original)}
|
|
34978
35179
|
`, "utf-8");
|
|
34979
35180
|
const rejectedEntries = await readKnowledge(rejectedPath);
|
|
@@ -34981,7 +35182,7 @@ async function restoreEntry(directory, entryId) {
|
|
|
34981
35182
|
const rejectedContent = filtered.length > 0 ? `${filtered.map((e) => JSON.stringify(e)).join(`
|
|
34982
35183
|
`)}
|
|
34983
35184
|
` : "";
|
|
34984
|
-
await
|
|
35185
|
+
await writeFile4(rejectedPath, rejectedContent, "utf-8");
|
|
34985
35186
|
} finally {
|
|
34986
35187
|
if (release) {
|
|
34987
35188
|
await release();
|
|
@@ -35096,6 +35297,321 @@ var init_knowledge_validator = __esm(() => {
|
|
|
35096
35297
|
];
|
|
35097
35298
|
});
|
|
35098
35299
|
|
|
35300
|
+
// src/hooks/curator.ts
|
|
35301
|
+
var init_curator = __esm(() => {
|
|
35302
|
+
init_event_bus();
|
|
35303
|
+
init_manager();
|
|
35304
|
+
init_bun_compat();
|
|
35305
|
+
init_logger();
|
|
35306
|
+
init_knowledge_store();
|
|
35307
|
+
init_knowledge_validator();
|
|
35308
|
+
init_utils2();
|
|
35309
|
+
});
|
|
35310
|
+
|
|
35311
|
+
// src/hooks/hive-promoter.ts
|
|
35312
|
+
import path12 from "path";
|
|
35313
|
+
function isAlreadyInHive(entry, hiveEntries, threshold) {
|
|
35314
|
+
return findNearDuplicate(entry.lesson, hiveEntries, threshold) !== undefined;
|
|
35315
|
+
}
|
|
35316
|
+
function countDistinctPhases(confirmedBy) {
|
|
35317
|
+
const phaseNumbers = new Set;
|
|
35318
|
+
for (const record3 of confirmedBy) {
|
|
35319
|
+
phaseNumbers.add(record3.phase_number);
|
|
35320
|
+
}
|
|
35321
|
+
return phaseNumbers.size;
|
|
35322
|
+
}
|
|
35323
|
+
function countDistinctProjects(confirmedBy) {
|
|
35324
|
+
const projectNames = new Set;
|
|
35325
|
+
for (const record3 of confirmedBy) {
|
|
35326
|
+
projectNames.add(record3.project_name);
|
|
35327
|
+
}
|
|
35328
|
+
return projectNames.size;
|
|
35329
|
+
}
|
|
35330
|
+
function hasProjectConfirmation(hiveEntry, projectName) {
|
|
35331
|
+
return hiveEntry.confirmed_by.some((record3) => record3.project_name === projectName);
|
|
35332
|
+
}
|
|
35333
|
+
function calculateEncounterScore(currentScore, isSameProject, config3) {
|
|
35334
|
+
const weight = isSameProject ? config3.same_project_weight : config3.cross_project_weight;
|
|
35335
|
+
const increment = config3.encounter_increment * weight;
|
|
35336
|
+
const newScore = currentScore + increment;
|
|
35337
|
+
return Math.min(Math.max(newScore, config3.min_encounter_score), config3.max_encounter_score);
|
|
35338
|
+
}
|
|
35339
|
+
function getEntryAgeMs(createdAt) {
|
|
35340
|
+
const createdTime = new Date(createdAt).getTime();
|
|
35341
|
+
if (Number.isNaN(createdTime))
|
|
35342
|
+
return 0;
|
|
35343
|
+
return Date.now() - createdTime;
|
|
35344
|
+
}
|
|
35345
|
+
async function checkHivePromotions(swarmEntries, config3) {
|
|
35346
|
+
let newPromotions = 0;
|
|
35347
|
+
let encountersIncremented = 0;
|
|
35348
|
+
let advancements = 0;
|
|
35349
|
+
if (config3.hive_enabled === false) {
|
|
35350
|
+
return {
|
|
35351
|
+
timestamp: new Date().toISOString(),
|
|
35352
|
+
new_promotions: 0,
|
|
35353
|
+
encounters_incremented: 0,
|
|
35354
|
+
advancements: 0,
|
|
35355
|
+
total_hive_entries: 0
|
|
35356
|
+
};
|
|
35357
|
+
}
|
|
35358
|
+
const hiveEntries = await readKnowledge(resolveHiveKnowledgePath());
|
|
35359
|
+
for (const swarmEntry of swarmEntries) {
|
|
35360
|
+
if (isAlreadyInHive(swarmEntry, hiveEntries, config3.dedup_threshold)) {
|
|
35361
|
+
continue;
|
|
35362
|
+
}
|
|
35363
|
+
let shouldPromote = false;
|
|
35364
|
+
if (swarmEntry.hive_eligible === true && countDistinctPhases(swarmEntry.confirmed_by) >= 3) {
|
|
35365
|
+
shouldPromote = true;
|
|
35366
|
+
}
|
|
35367
|
+
if (swarmEntry.tags.includes("hive-fast-track")) {
|
|
35368
|
+
shouldPromote = true;
|
|
35369
|
+
}
|
|
35370
|
+
const ageMs = getEntryAgeMs(swarmEntry.created_at);
|
|
35371
|
+
const ageThresholdMs = config3.auto_promote_days * 86400000;
|
|
35372
|
+
if (ageMs >= ageThresholdMs) {
|
|
35373
|
+
shouldPromote = true;
|
|
35374
|
+
}
|
|
35375
|
+
if (!shouldPromote) {
|
|
35376
|
+
continue;
|
|
35377
|
+
}
|
|
35378
|
+
const validationResult = validateLesson(swarmEntry.lesson, hiveEntries.map((e) => e.lesson), {
|
|
35379
|
+
category: swarmEntry.category,
|
|
35380
|
+
scope: swarmEntry.scope,
|
|
35381
|
+
confidence: swarmEntry.confidence
|
|
35382
|
+
});
|
|
35383
|
+
if (validationResult.severity === "error") {
|
|
35384
|
+
const rejectedLesson = {
|
|
35385
|
+
id: crypto.randomUUID(),
|
|
35386
|
+
lesson: swarmEntry.lesson,
|
|
35387
|
+
rejection_reason: validationResult.reason || "validation failed for hive promotion",
|
|
35388
|
+
rejected_at: new Date().toISOString(),
|
|
35389
|
+
rejection_layer: validationResult.layer || 2
|
|
35390
|
+
};
|
|
35391
|
+
const hiveRejectedPath = resolveHiveRejectedPath();
|
|
35392
|
+
await appendKnowledge(hiveRejectedPath, rejectedLesson);
|
|
35393
|
+
continue;
|
|
35394
|
+
}
|
|
35395
|
+
const newHiveEntry = {
|
|
35396
|
+
id: crypto.randomUUID(),
|
|
35397
|
+
tier: "hive",
|
|
35398
|
+
lesson: swarmEntry.lesson,
|
|
35399
|
+
category: swarmEntry.category,
|
|
35400
|
+
tags: swarmEntry.tags,
|
|
35401
|
+
scope: swarmEntry.scope,
|
|
35402
|
+
confidence: 0.5,
|
|
35403
|
+
status: "candidate",
|
|
35404
|
+
confirmed_by: [],
|
|
35405
|
+
retrieval_outcomes: {
|
|
35406
|
+
applied_count: 0,
|
|
35407
|
+
succeeded_after_count: 0,
|
|
35408
|
+
failed_after_count: 0
|
|
35409
|
+
},
|
|
35410
|
+
schema_version: config3.schema_version,
|
|
35411
|
+
created_at: new Date().toISOString(),
|
|
35412
|
+
updated_at: new Date().toISOString(),
|
|
35413
|
+
source_project: swarmEntry.project_name,
|
|
35414
|
+
encounter_score: config3.initial_encounter_score
|
|
35415
|
+
};
|
|
35416
|
+
await appendKnowledge(resolveHiveKnowledgePath(), newHiveEntry);
|
|
35417
|
+
newPromotions++;
|
|
35418
|
+
hiveEntries.push(newHiveEntry);
|
|
35419
|
+
}
|
|
35420
|
+
let hiveModified = false;
|
|
35421
|
+
for (const hiveEntry of hiveEntries) {
|
|
35422
|
+
const nearDuplicate = findNearDuplicate(hiveEntry.lesson, swarmEntries, config3.dedup_threshold);
|
|
35423
|
+
if (!nearDuplicate) {
|
|
35424
|
+
continue;
|
|
35425
|
+
}
|
|
35426
|
+
const isSameProject = nearDuplicate.project_name === hiveEntry.source_project;
|
|
35427
|
+
if (hasProjectConfirmation(hiveEntry, nearDuplicate.project_name)) {
|
|
35428
|
+
continue;
|
|
35429
|
+
}
|
|
35430
|
+
const newConfirmation = {
|
|
35431
|
+
project_name: nearDuplicate.project_name,
|
|
35432
|
+
confirmed_at: new Date().toISOString()
|
|
35433
|
+
};
|
|
35434
|
+
hiveEntry.confirmed_by.push(newConfirmation);
|
|
35435
|
+
const currentScore = hiveEntry.encounter_score ?? 1;
|
|
35436
|
+
hiveEntry.encounter_score = calculateEncounterScore(currentScore, isSameProject, config3);
|
|
35437
|
+
encountersIncremented++;
|
|
35438
|
+
hiveEntry.updated_at = new Date().toISOString();
|
|
35439
|
+
if (hiveEntry.status === "candidate" && countDistinctProjects(hiveEntry.confirmed_by) >= 3) {
|
|
35440
|
+
hiveEntry.status = "established";
|
|
35441
|
+
advancements++;
|
|
35442
|
+
}
|
|
35443
|
+
hiveModified = true;
|
|
35444
|
+
}
|
|
35445
|
+
if (hiveModified) {
|
|
35446
|
+
await rewriteKnowledge(resolveHiveKnowledgePath(), hiveEntries);
|
|
35447
|
+
}
|
|
35448
|
+
if (newPromotions > 0 || hiveModified) {
|
|
35449
|
+
await enforceKnowledgeCap(resolveHiveKnowledgePath(), config3.hive_max_entries);
|
|
35450
|
+
}
|
|
35451
|
+
return {
|
|
35452
|
+
timestamp: new Date().toISOString(),
|
|
35453
|
+
new_promotions: newPromotions,
|
|
35454
|
+
encounters_incremented: encountersIncremented,
|
|
35455
|
+
advancements,
|
|
35456
|
+
total_hive_entries: hiveEntries.length
|
|
35457
|
+
};
|
|
35458
|
+
}
|
|
35459
|
+
async function promoteToHive(directory, lesson, category) {
|
|
35460
|
+
const trimmedLesson = lesson.trim();
|
|
35461
|
+
const hiveEntries = await readKnowledge(resolveHiveKnowledgePath());
|
|
35462
|
+
const validationResult = validateLesson(trimmedLesson, hiveEntries.map((e) => e.lesson), {
|
|
35463
|
+
category: category || "process",
|
|
35464
|
+
scope: "global",
|
|
35465
|
+
confidence: 1
|
|
35466
|
+
});
|
|
35467
|
+
if (validationResult.severity === "error") {
|
|
35468
|
+
throw new Error(`Lesson rejected by validator: ${validationResult.reason}`);
|
|
35469
|
+
}
|
|
35470
|
+
if (findNearDuplicate(trimmedLesson, hiveEntries, 0.6)) {
|
|
35471
|
+
return `Lesson already exists in hive (near-duplicate).`;
|
|
35472
|
+
}
|
|
35473
|
+
const newHiveEntry = {
|
|
35474
|
+
id: crypto.randomUUID(),
|
|
35475
|
+
tier: "hive",
|
|
35476
|
+
lesson: trimmedLesson,
|
|
35477
|
+
category: category || "process",
|
|
35478
|
+
tags: [],
|
|
35479
|
+
scope: "global",
|
|
35480
|
+
confidence: 1,
|
|
35481
|
+
status: "promoted",
|
|
35482
|
+
confirmed_by: [],
|
|
35483
|
+
retrieval_outcomes: {
|
|
35484
|
+
applied_count: 0,
|
|
35485
|
+
succeeded_after_count: 0,
|
|
35486
|
+
failed_after_count: 0
|
|
35487
|
+
},
|
|
35488
|
+
schema_version: 1,
|
|
35489
|
+
created_at: new Date().toISOString(),
|
|
35490
|
+
updated_at: new Date().toISOString(),
|
|
35491
|
+
source_project: path12.basename(directory) || "unknown",
|
|
35492
|
+
encounter_score: 1
|
|
35493
|
+
};
|
|
35494
|
+
await appendKnowledge(resolveHiveKnowledgePath(), newHiveEntry);
|
|
35495
|
+
return `Promoted to hive: "${trimmedLesson.slice(0, 50)}${trimmedLesson.length > 50 ? "..." : ""}" (confidence: 1.0, source: manual)`;
|
|
35496
|
+
}
|
|
35497
|
+
async function promoteFromSwarm(directory, lessonId) {
|
|
35498
|
+
const swarmEntries = await readKnowledge(resolveSwarmKnowledgePath(directory));
|
|
35499
|
+
const swarmEntry = swarmEntries.find((e) => e.id === lessonId);
|
|
35500
|
+
if (!swarmEntry) {
|
|
35501
|
+
throw new Error(`Lesson ${lessonId} not found in .swarm/knowledge.jsonl`);
|
|
35502
|
+
}
|
|
35503
|
+
const hiveEntries = await readKnowledge(resolveHiveKnowledgePath());
|
|
35504
|
+
const validationResult = validateLesson(swarmEntry.lesson, hiveEntries.map((e) => e.lesson), {
|
|
35505
|
+
category: swarmEntry.category,
|
|
35506
|
+
scope: swarmEntry.scope,
|
|
35507
|
+
confidence: swarmEntry.confidence
|
|
35508
|
+
});
|
|
35509
|
+
if (validationResult.severity === "error") {
|
|
35510
|
+
throw new Error(`Lesson rejected by validator: ${validationResult.reason}`);
|
|
35511
|
+
}
|
|
35512
|
+
if (findNearDuplicate(swarmEntry.lesson, hiveEntries, 0.6)) {
|
|
35513
|
+
return `Lesson already exists in hive (near-duplicate).`;
|
|
35514
|
+
}
|
|
35515
|
+
const newHiveEntry = {
|
|
35516
|
+
id: crypto.randomUUID(),
|
|
35517
|
+
tier: "hive",
|
|
35518
|
+
lesson: swarmEntry.lesson,
|
|
35519
|
+
category: swarmEntry.category,
|
|
35520
|
+
tags: swarmEntry.tags,
|
|
35521
|
+
scope: swarmEntry.scope,
|
|
35522
|
+
confidence: 1,
|
|
35523
|
+
status: "promoted",
|
|
35524
|
+
confirmed_by: [],
|
|
35525
|
+
retrieval_outcomes: {
|
|
35526
|
+
applied_count: 0,
|
|
35527
|
+
succeeded_after_count: 0,
|
|
35528
|
+
failed_after_count: 0
|
|
35529
|
+
},
|
|
35530
|
+
schema_version: 1,
|
|
35531
|
+
created_at: new Date().toISOString(),
|
|
35532
|
+
updated_at: new Date().toISOString(),
|
|
35533
|
+
source_project: swarmEntry.project_name,
|
|
35534
|
+
encounter_score: 1
|
|
35535
|
+
};
|
|
35536
|
+
await appendKnowledge(resolveHiveKnowledgePath(), newHiveEntry);
|
|
35537
|
+
return `Promoted lesson ${lessonId} from swarm to hive: "${swarmEntry.lesson.slice(0, 50)}${swarmEntry.lesson.length > 50 ? "..." : ""}"`;
|
|
35538
|
+
}
|
|
35539
|
+
var init_hive_promoter = __esm(() => {
|
|
35540
|
+
init_curator();
|
|
35541
|
+
init_knowledge_store();
|
|
35542
|
+
init_knowledge_validator();
|
|
35543
|
+
init_utils2();
|
|
35544
|
+
});
|
|
35545
|
+
|
|
35546
|
+
// src/hooks/knowledge-reader.ts
|
|
35547
|
+
import { existsSync as existsSync8 } from "fs";
|
|
35548
|
+
import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
|
|
35549
|
+
import * as path13 from "path";
|
|
35550
|
+
async function updateRetrievalOutcome(directory, phaseInfo, phaseSucceeded) {
|
|
35551
|
+
const shownFile = path13.join(directory, ".swarm", ".knowledge-shown.json");
|
|
35552
|
+
try {
|
|
35553
|
+
if (!existsSync8(shownFile)) {
|
|
35554
|
+
return;
|
|
35555
|
+
}
|
|
35556
|
+
const content = await readFile4(shownFile, "utf-8");
|
|
35557
|
+
const shownData = JSON.parse(content);
|
|
35558
|
+
const shownIds = shownData[phaseInfo];
|
|
35559
|
+
if (!shownIds || shownIds.length === 0) {
|
|
35560
|
+
return;
|
|
35561
|
+
}
|
|
35562
|
+
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
35563
|
+
const entries = await readKnowledge(swarmPath);
|
|
35564
|
+
let updated = false;
|
|
35565
|
+
const foundInSwarm = new Set;
|
|
35566
|
+
for (const entry of entries) {
|
|
35567
|
+
if (shownIds.includes(entry.id)) {
|
|
35568
|
+
entry.retrieval_outcomes.applied_count++;
|
|
35569
|
+
if (phaseSucceeded) {
|
|
35570
|
+
entry.retrieval_outcomes.succeeded_after_count++;
|
|
35571
|
+
} else {
|
|
35572
|
+
entry.retrieval_outcomes.failed_after_count++;
|
|
35573
|
+
}
|
|
35574
|
+
updated = true;
|
|
35575
|
+
foundInSwarm.add(entry.id);
|
|
35576
|
+
}
|
|
35577
|
+
}
|
|
35578
|
+
if (updated) {
|
|
35579
|
+
await rewriteKnowledge(swarmPath, entries);
|
|
35580
|
+
}
|
|
35581
|
+
const remainingIds = shownIds.filter((id) => !foundInSwarm.has(id));
|
|
35582
|
+
if (remainingIds.length === 0) {
|
|
35583
|
+
delete shownData[phaseInfo];
|
|
35584
|
+
await writeFile5(shownFile, JSON.stringify(shownData, null, 2), "utf-8");
|
|
35585
|
+
return;
|
|
35586
|
+
}
|
|
35587
|
+
const hivePath = resolveHiveKnowledgePath();
|
|
35588
|
+
const hiveEntries = await readKnowledge(hivePath);
|
|
35589
|
+
let hiveUpdated = false;
|
|
35590
|
+
for (const entry of hiveEntries) {
|
|
35591
|
+
if (remainingIds.includes(entry.id)) {
|
|
35592
|
+
entry.retrieval_outcomes.applied_count++;
|
|
35593
|
+
if (phaseSucceeded) {
|
|
35594
|
+
entry.retrieval_outcomes.succeeded_after_count++;
|
|
35595
|
+
} else {
|
|
35596
|
+
entry.retrieval_outcomes.failed_after_count++;
|
|
35597
|
+
}
|
|
35598
|
+
hiveUpdated = true;
|
|
35599
|
+
}
|
|
35600
|
+
}
|
|
35601
|
+
if (hiveUpdated) {
|
|
35602
|
+
await rewriteKnowledge(hivePath, hiveEntries);
|
|
35603
|
+
}
|
|
35604
|
+
delete shownData[phaseInfo];
|
|
35605
|
+
await writeFile5(shownFile, JSON.stringify(shownData, null, 2), "utf-8");
|
|
35606
|
+
} catch {
|
|
35607
|
+
warn("[swarm] Knowledge: failed to update retrieval outcomes");
|
|
35608
|
+
}
|
|
35609
|
+
}
|
|
35610
|
+
var init_knowledge_reader = __esm(() => {
|
|
35611
|
+
init_logger();
|
|
35612
|
+
init_knowledge_store();
|
|
35613
|
+
});
|
|
35614
|
+
|
|
35099
35615
|
// src/hooks/knowledge-curator.ts
|
|
35100
35616
|
function pruneSeenRetroSections() {
|
|
35101
35617
|
const cutoff = Date.now() - 86400000;
|
|
@@ -35431,133 +35947,6 @@ var init_knowledge_curator = __esm(() => {
|
|
|
35431
35947
|
};
|
|
35432
35948
|
});
|
|
35433
35949
|
|
|
35434
|
-
// src/session/snapshot-writer.ts
|
|
35435
|
-
import { mkdirSync as mkdirSync7, renameSync as renameSync5 } from "fs";
|
|
35436
|
-
import * as path13 from "path";
|
|
35437
|
-
function serializeAgentSession(s) {
|
|
35438
|
-
const gateLog = {};
|
|
35439
|
-
const rawGateLog = s.gateLog ?? new Map;
|
|
35440
|
-
for (const [taskId, gates] of rawGateLog) {
|
|
35441
|
-
gateLog[taskId] = Array.from(gates ?? []);
|
|
35442
|
-
}
|
|
35443
|
-
const reviewerCallCount = {};
|
|
35444
|
-
const rawReviewerCallCount = s.reviewerCallCount ?? new Map;
|
|
35445
|
-
for (const [phase, count] of rawReviewerCallCount) {
|
|
35446
|
-
reviewerCallCount[String(phase)] = count;
|
|
35447
|
-
}
|
|
35448
|
-
const partialGateWarningsIssuedForTask = Array.from(s.partialGateWarningsIssuedForTask ?? new Set);
|
|
35449
|
-
const catastrophicPhaseWarnings = Array.from(s.catastrophicPhaseWarnings ?? new Set);
|
|
35450
|
-
const phaseAgentsDispatched = Array.from(s.phaseAgentsDispatched ?? new Set);
|
|
35451
|
-
const lastCompletedPhaseAgentsDispatched = Array.from(s.lastCompletedPhaseAgentsDispatched ?? new Set);
|
|
35452
|
-
const windows = {};
|
|
35453
|
-
const rawWindows = s.windows ?? {};
|
|
35454
|
-
for (const [key, win] of Object.entries(rawWindows)) {
|
|
35455
|
-
windows[key] = {
|
|
35456
|
-
id: win.id,
|
|
35457
|
-
agentName: win.agentName,
|
|
35458
|
-
startedAtMs: win.startedAtMs,
|
|
35459
|
-
toolCalls: win.toolCalls,
|
|
35460
|
-
consecutiveErrors: win.consecutiveErrors,
|
|
35461
|
-
hardLimitHit: win.hardLimitHit,
|
|
35462
|
-
lastSuccessTimeMs: win.lastSuccessTimeMs,
|
|
35463
|
-
recentToolCalls: win.recentToolCalls,
|
|
35464
|
-
warningIssued: win.warningIssued,
|
|
35465
|
-
warningReason: win.warningReason,
|
|
35466
|
-
transientRetryCount: win.transientRetryCount ?? 0
|
|
35467
|
-
};
|
|
35468
|
-
}
|
|
35469
|
-
return {
|
|
35470
|
-
agentName: s.agentName,
|
|
35471
|
-
lastToolCallTime: s.lastToolCallTime,
|
|
35472
|
-
lastAgentEventTime: s.lastAgentEventTime,
|
|
35473
|
-
delegationActive: s.delegationActive,
|
|
35474
|
-
activeInvocationId: s.activeInvocationId,
|
|
35475
|
-
lastInvocationIdByAgent: s.lastInvocationIdByAgent ?? {},
|
|
35476
|
-
windows,
|
|
35477
|
-
lastCompactionHint: s.lastCompactionHint ?? 0,
|
|
35478
|
-
architectWriteCount: s.architectWriteCount ?? 0,
|
|
35479
|
-
lastCoderDelegationTaskId: s.lastCoderDelegationTaskId ?? null,
|
|
35480
|
-
currentTaskId: s.currentTaskId ?? null,
|
|
35481
|
-
turboMode: s.turboMode ?? false,
|
|
35482
|
-
gateLog,
|
|
35483
|
-
reviewerCallCount,
|
|
35484
|
-
lastGateFailure: s.lastGateFailure ?? null,
|
|
35485
|
-
partialGateWarningsIssuedForTask,
|
|
35486
|
-
selfFixAttempted: s.selfFixAttempted ?? false,
|
|
35487
|
-
selfCodingWarnedAtCount: s.selfCodingWarnedAtCount ?? 0,
|
|
35488
|
-
catastrophicPhaseWarnings,
|
|
35489
|
-
lastPhaseCompleteTimestamp: s.lastPhaseCompleteTimestamp ?? 0,
|
|
35490
|
-
lastPhaseCompletePhase: s.lastPhaseCompletePhase ?? 0,
|
|
35491
|
-
phaseAgentsDispatched,
|
|
35492
|
-
lastCompletedPhaseAgentsDispatched,
|
|
35493
|
-
qaSkipCount: s.qaSkipCount ?? 0,
|
|
35494
|
-
qaSkipTaskIds: s.qaSkipTaskIds ?? [],
|
|
35495
|
-
pendingAdvisoryMessages: s.pendingAdvisoryMessages ?? [],
|
|
35496
|
-
taskWorkflowStates: Object.fromEntries(s.taskWorkflowStates ?? new Map),
|
|
35497
|
-
...s.scopeViolationDetected !== undefined && {
|
|
35498
|
-
scopeViolationDetected: s.scopeViolationDetected
|
|
35499
|
-
},
|
|
35500
|
-
model_fallback_index: s.model_fallback_index ?? 0,
|
|
35501
|
-
modelFallbackExhausted: s.modelFallbackExhausted ?? false,
|
|
35502
|
-
coderRevisions: s.coderRevisions ?? 0,
|
|
35503
|
-
revisionLimitHit: s.revisionLimitHit ?? false,
|
|
35504
|
-
fullAutoMode: s.fullAutoMode ?? false,
|
|
35505
|
-
fullAutoInteractionCount: s.fullAutoInteractionCount ?? 0,
|
|
35506
|
-
fullAutoDeadlockCount: s.fullAutoDeadlockCount ?? 0,
|
|
35507
|
-
fullAutoLastQuestionHash: s.fullAutoLastQuestionHash ?? null,
|
|
35508
|
-
sessionRehydratedAt: s.sessionRehydratedAt ?? 0
|
|
35509
|
-
};
|
|
35510
|
-
}
|
|
35511
|
-
async function writeSnapshot(directory, state) {
|
|
35512
|
-
try {
|
|
35513
|
-
const snapshot = {
|
|
35514
|
-
version: 2,
|
|
35515
|
-
writtenAt: Date.now(),
|
|
35516
|
-
toolAggregates: Object.fromEntries(state.toolAggregates),
|
|
35517
|
-
activeAgent: Object.fromEntries(state.activeAgent),
|
|
35518
|
-
delegationChains: Object.fromEntries(state.delegationChains),
|
|
35519
|
-
agentSessions: {}
|
|
35520
|
-
};
|
|
35521
|
-
for (const [sessionId, sessionState] of state.agentSessions) {
|
|
35522
|
-
snapshot.agentSessions[sessionId] = serializeAgentSession(sessionState);
|
|
35523
|
-
}
|
|
35524
|
-
const content = JSON.stringify(snapshot, null, 2);
|
|
35525
|
-
const resolvedPath = validateSwarmPath(directory, "session/state.json");
|
|
35526
|
-
const dir = path13.dirname(resolvedPath);
|
|
35527
|
-
mkdirSync7(dir, { recursive: true });
|
|
35528
|
-
const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
35529
|
-
await bunWrite(tempPath, content);
|
|
35530
|
-
renameSync5(tempPath, resolvedPath);
|
|
35531
|
-
} catch (error93) {
|
|
35532
|
-
log("[snapshot-writer] write failed", {
|
|
35533
|
-
error: error93 instanceof Error ? error93.message : String(error93)
|
|
35534
|
-
});
|
|
35535
|
-
}
|
|
35536
|
-
}
|
|
35537
|
-
function createSnapshotWriterHook(directory) {
|
|
35538
|
-
return (_input, _output) => {
|
|
35539
|
-
_writeInFlight = _writeInFlight.then(() => _internals8.writeSnapshot(directory, swarmState), () => _internals8.writeSnapshot(directory, swarmState));
|
|
35540
|
-
return _writeInFlight;
|
|
35541
|
-
};
|
|
35542
|
-
}
|
|
35543
|
-
async function flushPendingSnapshot(directory) {
|
|
35544
|
-
_writeInFlight = _writeInFlight.then(() => _internals8.writeSnapshot(directory, swarmState), () => _internals8.writeSnapshot(directory, swarmState));
|
|
35545
|
-
await _writeInFlight;
|
|
35546
|
-
}
|
|
35547
|
-
var _writeInFlight, _internals8;
|
|
35548
|
-
var init_snapshot_writer = __esm(() => {
|
|
35549
|
-
init_utils2();
|
|
35550
|
-
init_state();
|
|
35551
|
-
init_utils();
|
|
35552
|
-
init_bun_compat();
|
|
35553
|
-
_writeInFlight = Promise.resolve();
|
|
35554
|
-
_internals8 = {
|
|
35555
|
-
writeSnapshot,
|
|
35556
|
-
createSnapshotWriterHook,
|
|
35557
|
-
flushPendingSnapshot
|
|
35558
|
-
};
|
|
35559
|
-
});
|
|
35560
|
-
|
|
35561
35950
|
// src/tools/write-retro.ts
|
|
35562
35951
|
async function executeWriteRetro(args, directory) {
|
|
35563
35952
|
if (/^(CON|PRN|AUX|NUL|COM[0-9]|LPT[0-9])(:|$)/i.test(directory)) {
|
|
@@ -35859,7 +36248,7 @@ async function executeWriteRetro(args, directory) {
|
|
|
35859
36248
|
}, null, 2);
|
|
35860
36249
|
}
|
|
35861
36250
|
}
|
|
35862
|
-
var write_retro,
|
|
36251
|
+
var write_retro, _internals8;
|
|
35863
36252
|
var init_write_retro = __esm(() => {
|
|
35864
36253
|
init_zod();
|
|
35865
36254
|
init_evidence_schema();
|
|
@@ -35906,13 +36295,13 @@ var init_write_retro = __esm(() => {
|
|
|
35906
36295
|
task_id: args.task_id !== undefined ? String(args.task_id) : undefined,
|
|
35907
36296
|
metadata: args.metadata
|
|
35908
36297
|
};
|
|
35909
|
-
return await
|
|
36298
|
+
return await _internals8.executeWriteRetro(writeRetroArgs, directory);
|
|
35910
36299
|
} catch {
|
|
35911
36300
|
return JSON.stringify({ success: false, phase: rawPhase, message: "Invalid arguments" }, null, 2);
|
|
35912
36301
|
}
|
|
35913
36302
|
}
|
|
35914
36303
|
});
|
|
35915
|
-
|
|
36304
|
+
_internals8 = {
|
|
35916
36305
|
executeWriteRetro,
|
|
35917
36306
|
write_retro
|
|
35918
36307
|
};
|
|
@@ -35974,6 +36363,7 @@ async function handleCloseCommand(directory, args) {
|
|
|
35974
36363
|
const closedPhases = [];
|
|
35975
36364
|
const closedTasks = [];
|
|
35976
36365
|
const warnings = [];
|
|
36366
|
+
let hivePromoted = 0;
|
|
35977
36367
|
if (!planAlreadyDone) {
|
|
35978
36368
|
for (const phase of inProgressPhases) {
|
|
35979
36369
|
closedPhases.push(phase.id);
|
|
@@ -36094,6 +36484,26 @@ async function handleCloseCommand(directory, args) {
|
|
|
36094
36484
|
if (curationSucceeded && allLessons.length > 0) {
|
|
36095
36485
|
await fs7.unlink(lessonsFilePath).catch(() => {});
|
|
36096
36486
|
}
|
|
36487
|
+
if (curationSucceeded) {
|
|
36488
|
+
try {
|
|
36489
|
+
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
36490
|
+
const entries = await readKnowledge(knowledgePath);
|
|
36491
|
+
if (entries.length > 0) {
|
|
36492
|
+
for (const entry of entries) {
|
|
36493
|
+
try {
|
|
36494
|
+
await promoteToHive(directory, entry.lesson, entry.category);
|
|
36495
|
+
hivePromoted++;
|
|
36496
|
+
} catch (promotionErr) {
|
|
36497
|
+
const msg = promotionErr instanceof Error ? promotionErr.message : String(promotionErr);
|
|
36498
|
+
warnings.push(`Hive promotion skipped for lesson: ${msg}`);
|
|
36499
|
+
}
|
|
36500
|
+
}
|
|
36501
|
+
}
|
|
36502
|
+
} catch (hiveErr) {
|
|
36503
|
+
const msg = hiveErr instanceof Error ? hiveErr.message : String(hiveErr);
|
|
36504
|
+
warnings.push(`Hive promotion failed: ${msg}`);
|
|
36505
|
+
}
|
|
36506
|
+
}
|
|
36097
36507
|
if (planExists) {
|
|
36098
36508
|
const guaranteeResult = guaranteeAllPlansComplete(planData);
|
|
36099
36509
|
for (const phaseId of guaranteeResult.closedPhaseIds) {
|
|
@@ -36122,6 +36532,7 @@ async function handleCloseCommand(directory, args) {
|
|
|
36122
36532
|
let archiveResult = "";
|
|
36123
36533
|
let archivedFileCount = 0;
|
|
36124
36534
|
const archivedActiveStateFiles = new Set;
|
|
36535
|
+
const archivedActiveStateDirs = new Set;
|
|
36125
36536
|
try {
|
|
36126
36537
|
await fs7.mkdir(archiveDir, { recursive: true });
|
|
36127
36538
|
for (const artifact of ARCHIVE_ARTIFACTS) {
|
|
@@ -36135,38 +36546,34 @@ async function handleCloseCommand(directory, args) {
|
|
|
36135
36546
|
}
|
|
36136
36547
|
} catch {}
|
|
36137
36548
|
}
|
|
36138
|
-
const
|
|
36139
|
-
|
|
36140
|
-
|
|
36141
|
-
|
|
36142
|
-
|
|
36143
|
-
|
|
36144
|
-
|
|
36145
|
-
const
|
|
36146
|
-
|
|
36147
|
-
|
|
36148
|
-
|
|
36149
|
-
|
|
36150
|
-
|
|
36151
|
-
|
|
36152
|
-
|
|
36153
|
-
|
|
36549
|
+
for (const dirName of ACTIVE_STATE_DIRS_TO_CLEAN) {
|
|
36550
|
+
const srcDir = path14.join(swarmDir, dirName);
|
|
36551
|
+
const destDir = path14.join(archiveDir, dirName);
|
|
36552
|
+
try {
|
|
36553
|
+
const entries = await fs7.readdir(srcDir);
|
|
36554
|
+
if (entries.length > 0) {
|
|
36555
|
+
await fs7.mkdir(destDir, { recursive: true });
|
|
36556
|
+
for (const entry of entries) {
|
|
36557
|
+
const srcEntry = path14.join(srcDir, entry);
|
|
36558
|
+
const destEntry = path14.join(destDir, entry);
|
|
36559
|
+
try {
|
|
36560
|
+
const stat2 = await fs7.stat(srcEntry);
|
|
36561
|
+
if (stat2.isDirectory()) {
|
|
36562
|
+
await fs7.mkdir(destEntry, { recursive: true });
|
|
36563
|
+
const subEntries = await fs7.readdir(srcEntry);
|
|
36564
|
+
for (const sub of subEntries) {
|
|
36565
|
+
await fs7.copyFile(path14.join(srcEntry, sub), path14.join(destEntry, sub)).catch(() => {});
|
|
36566
|
+
}
|
|
36567
|
+
} else {
|
|
36568
|
+
await fs7.copyFile(srcEntry, destEntry);
|
|
36154
36569
|
}
|
|
36155
|
-
|
|
36156
|
-
|
|
36157
|
-
|
|
36158
|
-
archivedFileCount++;
|
|
36159
|
-
} catch {}
|
|
36570
|
+
archivedFileCount++;
|
|
36571
|
+
} catch {}
|
|
36572
|
+
}
|
|
36160
36573
|
}
|
|
36161
|
-
|
|
36162
|
-
|
|
36163
|
-
|
|
36164
|
-
try {
|
|
36165
|
-
const archiveSessionDir = path14.join(archiveDir, "session");
|
|
36166
|
-
await fs7.mkdir(archiveSessionDir, { recursive: true });
|
|
36167
|
-
await fs7.copyFile(sessionStatePath, path14.join(archiveSessionDir, "state.json"));
|
|
36168
|
-
archivedFileCount++;
|
|
36169
|
-
} catch {}
|
|
36574
|
+
archivedActiveStateDirs.add(dirName);
|
|
36575
|
+
} catch {}
|
|
36576
|
+
}
|
|
36170
36577
|
archiveResult = `Archived ${archivedFileCount} artifact(s) to .swarm/archive/swarm-${timestamp}/`;
|
|
36171
36578
|
} catch (archiveError) {
|
|
36172
36579
|
warnings.push(`Archive creation failed: ${archiveError instanceof Error ? archiveError.message : String(archiveError)}`);
|
|
@@ -36196,6 +36603,16 @@ async function handleCloseCommand(directory, args) {
|
|
|
36196
36603
|
} else {
|
|
36197
36604
|
warnings.push("Skipped active-state cleanup because no active-state files were archived. Files preserved to prevent data loss.");
|
|
36198
36605
|
}
|
|
36606
|
+
for (const dirName of ACTIVE_STATE_DIRS_TO_CLEAN) {
|
|
36607
|
+
if (!archivedActiveStateDirs.has(dirName)) {
|
|
36608
|
+
continue;
|
|
36609
|
+
}
|
|
36610
|
+
const dirPath = path14.join(swarmDir, dirName);
|
|
36611
|
+
try {
|
|
36612
|
+
await fs7.rm(dirPath, { recursive: true, force: true });
|
|
36613
|
+
cleanedFiles.push(`${dirName}/`);
|
|
36614
|
+
} catch {}
|
|
36615
|
+
}
|
|
36199
36616
|
try {
|
|
36200
36617
|
const swarmFiles = await fs7.readdir(swarmDir);
|
|
36201
36618
|
const configBackups = swarmFiles.filter((f) => f.startsWith("config-backup-") && f.endsWith(".json"));
|
|
@@ -36254,17 +36671,30 @@ async function handleCloseCommand(directory, args) {
|
|
|
36254
36671
|
const prunedBranches = [];
|
|
36255
36672
|
const isGit = isGitRepo2(directory);
|
|
36256
36673
|
if (isGit) {
|
|
36257
|
-
const
|
|
36258
|
-
|
|
36259
|
-
|
|
36260
|
-
if (
|
|
36261
|
-
|
|
36262
|
-
|
|
36263
|
-
|
|
36264
|
-
|
|
36265
|
-
|
|
36266
|
-
|
|
36267
|
-
|
|
36674
|
+
const aggressiveResult = resetToMainAfterMerge(directory, {
|
|
36675
|
+
pruneBranches
|
|
36676
|
+
});
|
|
36677
|
+
if (aggressiveResult.success) {
|
|
36678
|
+
gitAlignResult = aggressiveResult.message;
|
|
36679
|
+
for (const w of aggressiveResult.warnings) {
|
|
36680
|
+
warnings.push(w);
|
|
36681
|
+
}
|
|
36682
|
+
if (aggressiveResult.changesDiscarded) {
|
|
36683
|
+
warnings.push("Uncommitted changes were discarded during git alignment");
|
|
36684
|
+
}
|
|
36685
|
+
} else {
|
|
36686
|
+
const alignResult = resetToRemoteBranch(directory, { pruneBranches });
|
|
36687
|
+
gitAlignResult = alignResult.message;
|
|
36688
|
+
prunedBranches.push(...alignResult.prunedBranches);
|
|
36689
|
+
if (!alignResult.success) {
|
|
36690
|
+
warnings.push(`Git alignment: ${alignResult.message}`);
|
|
36691
|
+
}
|
|
36692
|
+
if (alignResult.alreadyAligned) {
|
|
36693
|
+
gitAlignResult = `Already aligned with ${alignResult.targetBranch}`;
|
|
36694
|
+
}
|
|
36695
|
+
for (const w of alignResult.warnings) {
|
|
36696
|
+
warnings.push(w);
|
|
36697
|
+
}
|
|
36268
36698
|
}
|
|
36269
36699
|
} else {
|
|
36270
36700
|
gitAlignResult = "Not a git repository \u2014 skipped git alignment";
|
|
@@ -36304,6 +36734,7 @@ async function handleCloseCommand(directory, args) {
|
|
|
36304
36734
|
...swarmPlanFilesRemoved > 0 ? [`- Removed ${swarmPlanFilesRemoved} SWARM_PLAN checkpoint artifact(s)`] : [],
|
|
36305
36735
|
...planExists && !planAlreadyDone ? ["- Set non-completed phases/tasks to closed status"] : [],
|
|
36306
36736
|
...curationSucceeded && allLessons.length > 0 ? [`- Committed ${allLessons.length} lesson(s) to knowledge store`] : [],
|
|
36737
|
+
...hivePromoted > 0 ? [`- Promoted ${hivePromoted} lesson(s) to hive knowledge`] : [],
|
|
36307
36738
|
"",
|
|
36308
36739
|
...warnings.length > 0 ? ["## Warnings", ...warnings.map((w) => `- ${w}`), ""] : []
|
|
36309
36740
|
].join(`
|
|
@@ -36315,13 +36746,6 @@ async function handleCloseCommand(directory, args) {
|
|
|
36315
36746
|
warnings.push(`Failed to write close-summary.md: ${msg}`);
|
|
36316
36747
|
console.warn("[close-command] Failed to write close-summary.md:", error93);
|
|
36317
36748
|
}
|
|
36318
|
-
try {
|
|
36319
|
-
await flushPendingSnapshot(directory);
|
|
36320
|
-
} catch (error93) {
|
|
36321
|
-
const msg = error93 instanceof Error ? error93.message : String(error93);
|
|
36322
|
-
warnings.push(`flushPendingSnapshot failed: ${msg}`);
|
|
36323
|
-
console.warn("[close-command] flushPendingSnapshot error:", error93);
|
|
36324
|
-
}
|
|
36325
36749
|
const preservedClient = swarmState.opencodeClient;
|
|
36326
36750
|
const preservedFullAutoFlag = swarmState.fullAutoEnabledInConfig;
|
|
36327
36751
|
const preservedCuratorInitNames = swarmState.curatorInitAgentNames;
|
|
@@ -36362,15 +36786,16 @@ ${otherWarnings.map((w) => `- ${w}`).join(`
|
|
|
36362
36786
|
**Archive:** ${archiveResult}
|
|
36363
36787
|
**Git:** ${gitAlignResult}${lessonSummary}${warningMsg}`;
|
|
36364
36788
|
}
|
|
36365
|
-
var ARCHIVE_ARTIFACTS, ACTIVE_STATE_TO_CLEAN;
|
|
36789
|
+
var ARCHIVE_ARTIFACTS, ACTIVE_STATE_TO_CLEAN, ACTIVE_STATE_DIRS_TO_CLEAN;
|
|
36366
36790
|
var init_close = __esm(() => {
|
|
36367
36791
|
init_schema();
|
|
36368
36792
|
init_manager2();
|
|
36369
36793
|
init_branch();
|
|
36794
|
+
init_hive_promoter();
|
|
36370
36795
|
init_knowledge_curator();
|
|
36796
|
+
init_knowledge_store();
|
|
36371
36797
|
init_utils2();
|
|
36372
36798
|
init_scope_persistence();
|
|
36373
|
-
init_snapshot_writer();
|
|
36374
36799
|
init_state();
|
|
36375
36800
|
init_write_retro();
|
|
36376
36801
|
ARCHIVE_ARTIFACTS = [
|
|
@@ -36383,7 +36808,18 @@ var init_close = __esm(() => {
|
|
|
36383
36808
|
"handoff-prompt.md",
|
|
36384
36809
|
"handoff-consumed.md",
|
|
36385
36810
|
"escalation-report.md",
|
|
36386
|
-
"close-lessons.md"
|
|
36811
|
+
"close-lessons.md",
|
|
36812
|
+
"knowledge.jsonl",
|
|
36813
|
+
"knowledge-rejected.jsonl",
|
|
36814
|
+
"repo-graph.json",
|
|
36815
|
+
"doc-manifest.json",
|
|
36816
|
+
"dark-matter.md",
|
|
36817
|
+
"telemetry.jsonl",
|
|
36818
|
+
"swarm.db",
|
|
36819
|
+
"swarm.db-shm",
|
|
36820
|
+
"swarm.db-wal",
|
|
36821
|
+
"close-summary.md",
|
|
36822
|
+
"spec.md"
|
|
36387
36823
|
];
|
|
36388
36824
|
ACTIVE_STATE_TO_CLEAN = [
|
|
36389
36825
|
"plan.json",
|
|
@@ -36393,7 +36829,23 @@ var init_close = __esm(() => {
|
|
|
36393
36829
|
"handoff.md",
|
|
36394
36830
|
"handoff-prompt.md",
|
|
36395
36831
|
"handoff-consumed.md",
|
|
36396
|
-
"escalation-report.md"
|
|
36832
|
+
"escalation-report.md",
|
|
36833
|
+
"knowledge.jsonl",
|
|
36834
|
+
"knowledge-rejected.jsonl",
|
|
36835
|
+
"repo-graph.json",
|
|
36836
|
+
"doc-manifest.json",
|
|
36837
|
+
"dark-matter.md",
|
|
36838
|
+
"telemetry.jsonl",
|
|
36839
|
+
"swarm.db",
|
|
36840
|
+
"swarm.db-shm",
|
|
36841
|
+
"swarm.db-wal"
|
|
36842
|
+
];
|
|
36843
|
+
ACTIVE_STATE_DIRS_TO_CLEAN = [
|
|
36844
|
+
"evidence",
|
|
36845
|
+
"session",
|
|
36846
|
+
"scopes",
|
|
36847
|
+
"locks",
|
|
36848
|
+
"spec-archive"
|
|
36397
36849
|
];
|
|
36398
36850
|
});
|
|
36399
36851
|
|
|
@@ -36496,322 +36948,6 @@ var init_council = __esm(() => {
|
|
|
36496
36948
|
`);
|
|
36497
36949
|
});
|
|
36498
36950
|
|
|
36499
|
-
// src/background/event-bus.ts
|
|
36500
|
-
class AutomationEventBus {
|
|
36501
|
-
listeners = new Map;
|
|
36502
|
-
eventHistory = [];
|
|
36503
|
-
maxHistorySize;
|
|
36504
|
-
constructor(options) {
|
|
36505
|
-
this.maxHistorySize = options?.maxHistorySize ?? 100;
|
|
36506
|
-
}
|
|
36507
|
-
subscribe(type, listener) {
|
|
36508
|
-
if (!this.listeners.has(type)) {
|
|
36509
|
-
this.listeners.set(type, new Set);
|
|
36510
|
-
}
|
|
36511
|
-
this.listeners.get(type).add(listener);
|
|
36512
|
-
return () => {
|
|
36513
|
-
this.listeners.get(type)?.delete(listener);
|
|
36514
|
-
};
|
|
36515
|
-
}
|
|
36516
|
-
async publish(type, payload, source) {
|
|
36517
|
-
const event = {
|
|
36518
|
-
type,
|
|
36519
|
-
timestamp: Date.now(),
|
|
36520
|
-
payload,
|
|
36521
|
-
source
|
|
36522
|
-
};
|
|
36523
|
-
this.eventHistory.push(event);
|
|
36524
|
-
if (this.eventHistory.length > this.maxHistorySize) {
|
|
36525
|
-
this.eventHistory.shift();
|
|
36526
|
-
}
|
|
36527
|
-
log(`[EventBus] ${type}`, {
|
|
36528
|
-
source,
|
|
36529
|
-
payload: typeof payload === "object" ? "..." : payload
|
|
36530
|
-
});
|
|
36531
|
-
const listeners = this.listeners.get(type);
|
|
36532
|
-
if (listeners) {
|
|
36533
|
-
await Promise.all(Array.from(listeners).map(async (listener) => {
|
|
36534
|
-
try {
|
|
36535
|
-
await listener(event);
|
|
36536
|
-
} catch (error93) {
|
|
36537
|
-
log(`[EventBus] Listener error for ${type}`, { error: error93 });
|
|
36538
|
-
}
|
|
36539
|
-
}));
|
|
36540
|
-
}
|
|
36541
|
-
}
|
|
36542
|
-
getHistory(types) {
|
|
36543
|
-
if (!types || types.length === 0) {
|
|
36544
|
-
return [...this.eventHistory];
|
|
36545
|
-
}
|
|
36546
|
-
return this.eventHistory.filter((e) => types.includes(e.type));
|
|
36547
|
-
}
|
|
36548
|
-
clearHistory() {
|
|
36549
|
-
this.eventHistory = [];
|
|
36550
|
-
}
|
|
36551
|
-
getListenerCount(type) {
|
|
36552
|
-
return this.listeners.get(type)?.size ?? 0;
|
|
36553
|
-
}
|
|
36554
|
-
hasListeners(type) {
|
|
36555
|
-
return this.getListenerCount(type) > 0;
|
|
36556
|
-
}
|
|
36557
|
-
}
|
|
36558
|
-
function getGlobalEventBus() {
|
|
36559
|
-
if (!globalEventBus) {
|
|
36560
|
-
globalEventBus = new AutomationEventBus;
|
|
36561
|
-
}
|
|
36562
|
-
return globalEventBus;
|
|
36563
|
-
}
|
|
36564
|
-
var globalEventBus = null;
|
|
36565
|
-
var init_event_bus = __esm(() => {
|
|
36566
|
-
init_utils();
|
|
36567
|
-
});
|
|
36568
|
-
|
|
36569
|
-
// src/hooks/curator.ts
|
|
36570
|
-
var init_curator = __esm(() => {
|
|
36571
|
-
init_event_bus();
|
|
36572
|
-
init_manager();
|
|
36573
|
-
init_bun_compat();
|
|
36574
|
-
init_logger();
|
|
36575
|
-
init_knowledge_store();
|
|
36576
|
-
init_knowledge_validator();
|
|
36577
|
-
init_utils2();
|
|
36578
|
-
});
|
|
36579
|
-
|
|
36580
|
-
// src/hooks/hive-promoter.ts
|
|
36581
|
-
import path16 from "path";
|
|
36582
|
-
function isAlreadyInHive(entry, hiveEntries, threshold) {
|
|
36583
|
-
return findNearDuplicate(entry.lesson, hiveEntries, threshold) !== undefined;
|
|
36584
|
-
}
|
|
36585
|
-
function countDistinctPhases(confirmedBy) {
|
|
36586
|
-
const phaseNumbers = new Set;
|
|
36587
|
-
for (const record3 of confirmedBy) {
|
|
36588
|
-
phaseNumbers.add(record3.phase_number);
|
|
36589
|
-
}
|
|
36590
|
-
return phaseNumbers.size;
|
|
36591
|
-
}
|
|
36592
|
-
function countDistinctProjects(confirmedBy) {
|
|
36593
|
-
const projectNames = new Set;
|
|
36594
|
-
for (const record3 of confirmedBy) {
|
|
36595
|
-
projectNames.add(record3.project_name);
|
|
36596
|
-
}
|
|
36597
|
-
return projectNames.size;
|
|
36598
|
-
}
|
|
36599
|
-
function hasProjectConfirmation(hiveEntry, projectName) {
|
|
36600
|
-
return hiveEntry.confirmed_by.some((record3) => record3.project_name === projectName);
|
|
36601
|
-
}
|
|
36602
|
-
function calculateEncounterScore(currentScore, isSameProject, config3) {
|
|
36603
|
-
const weight = isSameProject ? config3.same_project_weight : config3.cross_project_weight;
|
|
36604
|
-
const increment = config3.encounter_increment * weight;
|
|
36605
|
-
const newScore = currentScore + increment;
|
|
36606
|
-
return Math.min(Math.max(newScore, config3.min_encounter_score), config3.max_encounter_score);
|
|
36607
|
-
}
|
|
36608
|
-
function getEntryAgeMs(createdAt) {
|
|
36609
|
-
const createdTime = new Date(createdAt).getTime();
|
|
36610
|
-
if (Number.isNaN(createdTime))
|
|
36611
|
-
return 0;
|
|
36612
|
-
return Date.now() - createdTime;
|
|
36613
|
-
}
|
|
36614
|
-
async function checkHivePromotions(swarmEntries, config3) {
|
|
36615
|
-
let newPromotions = 0;
|
|
36616
|
-
let encountersIncremented = 0;
|
|
36617
|
-
let advancements = 0;
|
|
36618
|
-
if (config3.hive_enabled === false) {
|
|
36619
|
-
return {
|
|
36620
|
-
timestamp: new Date().toISOString(),
|
|
36621
|
-
new_promotions: 0,
|
|
36622
|
-
encounters_incremented: 0,
|
|
36623
|
-
advancements: 0,
|
|
36624
|
-
total_hive_entries: 0
|
|
36625
|
-
};
|
|
36626
|
-
}
|
|
36627
|
-
const hiveEntries = await readKnowledge(resolveHiveKnowledgePath());
|
|
36628
|
-
for (const swarmEntry of swarmEntries) {
|
|
36629
|
-
if (isAlreadyInHive(swarmEntry, hiveEntries, config3.dedup_threshold)) {
|
|
36630
|
-
continue;
|
|
36631
|
-
}
|
|
36632
|
-
let shouldPromote = false;
|
|
36633
|
-
if (swarmEntry.hive_eligible === true && countDistinctPhases(swarmEntry.confirmed_by) >= 3) {
|
|
36634
|
-
shouldPromote = true;
|
|
36635
|
-
}
|
|
36636
|
-
if (swarmEntry.tags.includes("hive-fast-track")) {
|
|
36637
|
-
shouldPromote = true;
|
|
36638
|
-
}
|
|
36639
|
-
const ageMs = getEntryAgeMs(swarmEntry.created_at);
|
|
36640
|
-
const ageThresholdMs = config3.auto_promote_days * 86400000;
|
|
36641
|
-
if (ageMs >= ageThresholdMs) {
|
|
36642
|
-
shouldPromote = true;
|
|
36643
|
-
}
|
|
36644
|
-
if (!shouldPromote) {
|
|
36645
|
-
continue;
|
|
36646
|
-
}
|
|
36647
|
-
const validationResult = validateLesson(swarmEntry.lesson, hiveEntries.map((e) => e.lesson), {
|
|
36648
|
-
category: swarmEntry.category,
|
|
36649
|
-
scope: swarmEntry.scope,
|
|
36650
|
-
confidence: swarmEntry.confidence
|
|
36651
|
-
});
|
|
36652
|
-
if (validationResult.severity === "error") {
|
|
36653
|
-
const rejectedLesson = {
|
|
36654
|
-
id: crypto.randomUUID(),
|
|
36655
|
-
lesson: swarmEntry.lesson,
|
|
36656
|
-
rejection_reason: validationResult.reason || "validation failed for hive promotion",
|
|
36657
|
-
rejected_at: new Date().toISOString(),
|
|
36658
|
-
rejection_layer: validationResult.layer || 2
|
|
36659
|
-
};
|
|
36660
|
-
const hiveRejectedPath = resolveHiveRejectedPath();
|
|
36661
|
-
await appendKnowledge(hiveRejectedPath, rejectedLesson);
|
|
36662
|
-
continue;
|
|
36663
|
-
}
|
|
36664
|
-
const newHiveEntry = {
|
|
36665
|
-
id: crypto.randomUUID(),
|
|
36666
|
-
tier: "hive",
|
|
36667
|
-
lesson: swarmEntry.lesson,
|
|
36668
|
-
category: swarmEntry.category,
|
|
36669
|
-
tags: swarmEntry.tags,
|
|
36670
|
-
scope: swarmEntry.scope,
|
|
36671
|
-
confidence: 0.5,
|
|
36672
|
-
status: "candidate",
|
|
36673
|
-
confirmed_by: [],
|
|
36674
|
-
retrieval_outcomes: {
|
|
36675
|
-
applied_count: 0,
|
|
36676
|
-
succeeded_after_count: 0,
|
|
36677
|
-
failed_after_count: 0
|
|
36678
|
-
},
|
|
36679
|
-
schema_version: config3.schema_version,
|
|
36680
|
-
created_at: new Date().toISOString(),
|
|
36681
|
-
updated_at: new Date().toISOString(),
|
|
36682
|
-
source_project: swarmEntry.project_name,
|
|
36683
|
-
encounter_score: config3.initial_encounter_score
|
|
36684
|
-
};
|
|
36685
|
-
await appendKnowledge(resolveHiveKnowledgePath(), newHiveEntry);
|
|
36686
|
-
newPromotions++;
|
|
36687
|
-
hiveEntries.push(newHiveEntry);
|
|
36688
|
-
}
|
|
36689
|
-
let hiveModified = false;
|
|
36690
|
-
for (const hiveEntry of hiveEntries) {
|
|
36691
|
-
const nearDuplicate = findNearDuplicate(hiveEntry.lesson, swarmEntries, config3.dedup_threshold);
|
|
36692
|
-
if (!nearDuplicate) {
|
|
36693
|
-
continue;
|
|
36694
|
-
}
|
|
36695
|
-
const isSameProject = nearDuplicate.project_name === hiveEntry.source_project;
|
|
36696
|
-
if (hasProjectConfirmation(hiveEntry, nearDuplicate.project_name)) {
|
|
36697
|
-
continue;
|
|
36698
|
-
}
|
|
36699
|
-
const newConfirmation = {
|
|
36700
|
-
project_name: nearDuplicate.project_name,
|
|
36701
|
-
confirmed_at: new Date().toISOString()
|
|
36702
|
-
};
|
|
36703
|
-
hiveEntry.confirmed_by.push(newConfirmation);
|
|
36704
|
-
const currentScore = hiveEntry.encounter_score ?? 1;
|
|
36705
|
-
hiveEntry.encounter_score = calculateEncounterScore(currentScore, isSameProject, config3);
|
|
36706
|
-
encountersIncremented++;
|
|
36707
|
-
hiveEntry.updated_at = new Date().toISOString();
|
|
36708
|
-
if (hiveEntry.status === "candidate" && countDistinctProjects(hiveEntry.confirmed_by) >= 3) {
|
|
36709
|
-
hiveEntry.status = "established";
|
|
36710
|
-
advancements++;
|
|
36711
|
-
}
|
|
36712
|
-
hiveModified = true;
|
|
36713
|
-
}
|
|
36714
|
-
if (hiveModified) {
|
|
36715
|
-
await rewriteKnowledge(resolveHiveKnowledgePath(), hiveEntries);
|
|
36716
|
-
}
|
|
36717
|
-
if (newPromotions > 0 || hiveModified) {
|
|
36718
|
-
await enforceKnowledgeCap(resolveHiveKnowledgePath(), config3.hive_max_entries);
|
|
36719
|
-
}
|
|
36720
|
-
return {
|
|
36721
|
-
timestamp: new Date().toISOString(),
|
|
36722
|
-
new_promotions: newPromotions,
|
|
36723
|
-
encounters_incremented: encountersIncremented,
|
|
36724
|
-
advancements,
|
|
36725
|
-
total_hive_entries: hiveEntries.length
|
|
36726
|
-
};
|
|
36727
|
-
}
|
|
36728
|
-
async function promoteToHive(directory, lesson, category) {
|
|
36729
|
-
const trimmedLesson = lesson.trim();
|
|
36730
|
-
const hiveEntries = await readKnowledge(resolveHiveKnowledgePath());
|
|
36731
|
-
const validationResult = validateLesson(trimmedLesson, hiveEntries.map((e) => e.lesson), {
|
|
36732
|
-
category: category || "process",
|
|
36733
|
-
scope: "global",
|
|
36734
|
-
confidence: 1
|
|
36735
|
-
});
|
|
36736
|
-
if (validationResult.severity === "error") {
|
|
36737
|
-
throw new Error(`Lesson rejected by validator: ${validationResult.reason}`);
|
|
36738
|
-
}
|
|
36739
|
-
if (findNearDuplicate(trimmedLesson, hiveEntries, 0.6)) {
|
|
36740
|
-
return `Lesson already exists in hive (near-duplicate).`;
|
|
36741
|
-
}
|
|
36742
|
-
const newHiveEntry = {
|
|
36743
|
-
id: crypto.randomUUID(),
|
|
36744
|
-
tier: "hive",
|
|
36745
|
-
lesson: trimmedLesson,
|
|
36746
|
-
category: category || "process",
|
|
36747
|
-
tags: [],
|
|
36748
|
-
scope: "global",
|
|
36749
|
-
confidence: 1,
|
|
36750
|
-
status: "promoted",
|
|
36751
|
-
confirmed_by: [],
|
|
36752
|
-
retrieval_outcomes: {
|
|
36753
|
-
applied_count: 0,
|
|
36754
|
-
succeeded_after_count: 0,
|
|
36755
|
-
failed_after_count: 0
|
|
36756
|
-
},
|
|
36757
|
-
schema_version: 1,
|
|
36758
|
-
created_at: new Date().toISOString(),
|
|
36759
|
-
updated_at: new Date().toISOString(),
|
|
36760
|
-
source_project: path16.basename(directory) || "unknown",
|
|
36761
|
-
encounter_score: 1
|
|
36762
|
-
};
|
|
36763
|
-
await appendKnowledge(resolveHiveKnowledgePath(), newHiveEntry);
|
|
36764
|
-
return `Promoted to hive: "${trimmedLesson.slice(0, 50)}${trimmedLesson.length > 50 ? "..." : ""}" (confidence: 1.0, source: manual)`;
|
|
36765
|
-
}
|
|
36766
|
-
async function promoteFromSwarm(directory, lessonId) {
|
|
36767
|
-
const swarmEntries = await readKnowledge(resolveSwarmKnowledgePath(directory));
|
|
36768
|
-
const swarmEntry = swarmEntries.find((e) => e.id === lessonId);
|
|
36769
|
-
if (!swarmEntry) {
|
|
36770
|
-
throw new Error(`Lesson ${lessonId} not found in .swarm/knowledge.jsonl`);
|
|
36771
|
-
}
|
|
36772
|
-
const hiveEntries = await readKnowledge(resolveHiveKnowledgePath());
|
|
36773
|
-
const validationResult = validateLesson(swarmEntry.lesson, hiveEntries.map((e) => e.lesson), {
|
|
36774
|
-
category: swarmEntry.category,
|
|
36775
|
-
scope: swarmEntry.scope,
|
|
36776
|
-
confidence: swarmEntry.confidence
|
|
36777
|
-
});
|
|
36778
|
-
if (validationResult.severity === "error") {
|
|
36779
|
-
throw new Error(`Lesson rejected by validator: ${validationResult.reason}`);
|
|
36780
|
-
}
|
|
36781
|
-
if (findNearDuplicate(swarmEntry.lesson, hiveEntries, 0.6)) {
|
|
36782
|
-
return `Lesson already exists in hive (near-duplicate).`;
|
|
36783
|
-
}
|
|
36784
|
-
const newHiveEntry = {
|
|
36785
|
-
id: crypto.randomUUID(),
|
|
36786
|
-
tier: "hive",
|
|
36787
|
-
lesson: swarmEntry.lesson,
|
|
36788
|
-
category: swarmEntry.category,
|
|
36789
|
-
tags: swarmEntry.tags,
|
|
36790
|
-
scope: swarmEntry.scope,
|
|
36791
|
-
confidence: 1,
|
|
36792
|
-
status: "promoted",
|
|
36793
|
-
confirmed_by: [],
|
|
36794
|
-
retrieval_outcomes: {
|
|
36795
|
-
applied_count: 0,
|
|
36796
|
-
succeeded_after_count: 0,
|
|
36797
|
-
failed_after_count: 0
|
|
36798
|
-
},
|
|
36799
|
-
schema_version: 1,
|
|
36800
|
-
created_at: new Date().toISOString(),
|
|
36801
|
-
updated_at: new Date().toISOString(),
|
|
36802
|
-
source_project: swarmEntry.project_name,
|
|
36803
|
-
encounter_score: 1
|
|
36804
|
-
};
|
|
36805
|
-
await appendKnowledge(resolveHiveKnowledgePath(), newHiveEntry);
|
|
36806
|
-
return `Promoted lesson ${lessonId} from swarm to hive: "${swarmEntry.lesson.slice(0, 50)}${swarmEntry.lesson.length > 50 ? "..." : ""}"`;
|
|
36807
|
-
}
|
|
36808
|
-
var init_hive_promoter = __esm(() => {
|
|
36809
|
-
init_curator();
|
|
36810
|
-
init_knowledge_store();
|
|
36811
|
-
init_knowledge_validator();
|
|
36812
|
-
init_utils2();
|
|
36813
|
-
});
|
|
36814
|
-
|
|
36815
36951
|
// src/commands/curate.ts
|
|
36816
36952
|
async function handleCurateCommand(directory, _args) {
|
|
36817
36953
|
try {
|
|
@@ -36849,7 +36985,7 @@ var init_curate = __esm(() => {
|
|
|
36849
36985
|
import * as child_process3 from "child_process";
|
|
36850
36986
|
import { randomUUID } from "crypto";
|
|
36851
36987
|
import { readdir, readFile as readFile5, stat as stat2 } from "fs/promises";
|
|
36852
|
-
import * as
|
|
36988
|
+
import * as path16 from "path";
|
|
36853
36989
|
import { promisify } from "util";
|
|
36854
36990
|
function getExecFileAsync() {
|
|
36855
36991
|
return promisify(child_process3.execFile);
|
|
@@ -36951,7 +37087,7 @@ async function scanSourceFiles(dir) {
|
|
|
36951
37087
|
try {
|
|
36952
37088
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
36953
37089
|
for (const entry of entries) {
|
|
36954
|
-
const fullPath =
|
|
37090
|
+
const fullPath = path16.join(dir, entry.name);
|
|
36955
37091
|
if (entry.isDirectory()) {
|
|
36956
37092
|
if (skipDirs.has(entry.name)) {
|
|
36957
37093
|
continue;
|
|
@@ -36959,7 +37095,7 @@ async function scanSourceFiles(dir) {
|
|
|
36959
37095
|
const subFiles = await scanSourceFiles(fullPath);
|
|
36960
37096
|
results.push(...subFiles);
|
|
36961
37097
|
} else if (entry.isFile()) {
|
|
36962
|
-
const ext =
|
|
37098
|
+
const ext = path16.extname(entry.name);
|
|
36963
37099
|
if ([".ts", ".tsx", ".js", ".jsx", ".mjs"].includes(ext)) {
|
|
36964
37100
|
results.push(fullPath);
|
|
36965
37101
|
}
|
|
@@ -36981,8 +37117,8 @@ async function getStaticEdges(directory) {
|
|
|
36981
37117
|
continue;
|
|
36982
37118
|
}
|
|
36983
37119
|
try {
|
|
36984
|
-
const sourceDir =
|
|
36985
|
-
const resolvedPath =
|
|
37120
|
+
const sourceDir = path16.dirname(sourceFile);
|
|
37121
|
+
const resolvedPath = path16.resolve(sourceDir, importPath);
|
|
36986
37122
|
const extensions = [
|
|
36987
37123
|
"",
|
|
36988
37124
|
".ts",
|
|
@@ -37007,8 +37143,8 @@ async function getStaticEdges(directory) {
|
|
|
37007
37143
|
if (!targetFile) {
|
|
37008
37144
|
continue;
|
|
37009
37145
|
}
|
|
37010
|
-
const relSource =
|
|
37011
|
-
const relTarget =
|
|
37146
|
+
const relSource = path16.relative(directory, sourceFile).replace(/\\/g, "/");
|
|
37147
|
+
const relTarget = path16.relative(directory, targetFile).replace(/\\/g, "/");
|
|
37012
37148
|
const [key] = relSource < relTarget ? [`${relSource}::${relTarget}`, relSource, relTarget] : [`${relTarget}::${relSource}`, relTarget, relSource];
|
|
37013
37149
|
edges.add(key);
|
|
37014
37150
|
} catch {}
|
|
@@ -37020,7 +37156,7 @@ async function getStaticEdges(directory) {
|
|
|
37020
37156
|
function isTestImplementationPair(fileA, fileB) {
|
|
37021
37157
|
const testPatterns = [".test.ts", ".test.js", ".spec.ts", ".spec.js"];
|
|
37022
37158
|
const getBaseName = (filePath) => {
|
|
37023
|
-
const base =
|
|
37159
|
+
const base = path16.basename(filePath);
|
|
37024
37160
|
for (const pattern of testPatterns) {
|
|
37025
37161
|
if (base.endsWith(pattern)) {
|
|
37026
37162
|
return base.slice(0, -pattern.length);
|
|
@@ -37030,16 +37166,16 @@ function isTestImplementationPair(fileA, fileB) {
|
|
|
37030
37166
|
};
|
|
37031
37167
|
const baseA = getBaseName(fileA);
|
|
37032
37168
|
const baseB = getBaseName(fileB);
|
|
37033
|
-
return baseA === baseB && baseA !==
|
|
37169
|
+
return baseA === baseB && baseA !== path16.basename(fileA) && baseA !== path16.basename(fileB);
|
|
37034
37170
|
}
|
|
37035
37171
|
function hasSharedPrefix(fileA, fileB) {
|
|
37036
|
-
const dirA =
|
|
37037
|
-
const dirB =
|
|
37172
|
+
const dirA = path16.dirname(fileA);
|
|
37173
|
+
const dirB = path16.dirname(fileB);
|
|
37038
37174
|
if (dirA !== dirB) {
|
|
37039
37175
|
return false;
|
|
37040
37176
|
}
|
|
37041
|
-
const baseA =
|
|
37042
|
-
const baseB =
|
|
37177
|
+
const baseA = path16.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
|
|
37178
|
+
const baseB = path16.basename(fileB).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
|
|
37043
37179
|
if (baseA.startsWith(baseB) || baseB.startsWith(baseA)) {
|
|
37044
37180
|
return true;
|
|
37045
37181
|
}
|
|
@@ -37067,9 +37203,9 @@ async function detectDarkMatter(directory, options) {
|
|
|
37067
37203
|
} catch {
|
|
37068
37204
|
return [];
|
|
37069
37205
|
}
|
|
37070
|
-
const commitMap = await
|
|
37071
|
-
const matrix =
|
|
37072
|
-
const staticEdges = await
|
|
37206
|
+
const commitMap = await _internals9.parseGitLog(directory, maxCommitsToAnalyze);
|
|
37207
|
+
const matrix = _internals9.buildCoChangeMatrix(commitMap);
|
|
37208
|
+
const staticEdges = await _internals9.getStaticEdges(directory);
|
|
37073
37209
|
const results = [];
|
|
37074
37210
|
for (const entry of matrix.values()) {
|
|
37075
37211
|
const key = `${entry.fileA}::${entry.fileB}`;
|
|
@@ -37093,8 +37229,8 @@ function darkMatterToKnowledgeEntries(pairs, projectName) {
|
|
|
37093
37229
|
const entries = [];
|
|
37094
37230
|
const now = new Date().toISOString();
|
|
37095
37231
|
for (const pair of pairs.slice(0, 10)) {
|
|
37096
|
-
const baseA =
|
|
37097
|
-
const baseB =
|
|
37232
|
+
const baseA = path16.basename(pair.fileA);
|
|
37233
|
+
const baseB = path16.basename(pair.fileB);
|
|
37098
37234
|
let lesson = `Files ${pair.fileA} and ${pair.fileB} co-change with NPMI=${pair.npmi.toFixed(3)} but have no import relationship. This hidden coupling suggests a shared architectural concern \u2014 changes to one likely require changes to the other.`;
|
|
37099
37235
|
if (lesson.length > 280) {
|
|
37100
37236
|
lesson = `Files ${baseA} and ${baseB} co-change with NPMI=${pair.npmi.toFixed(3)} but have no import relationship. This hidden coupling suggests a shared architectural concern \u2014 changes to one likely require changes to the other.`;
|
|
@@ -37149,7 +37285,7 @@ ${rows}
|
|
|
37149
37285
|
These pairs likely share an architectural concern invisible to static analysis.
|
|
37150
37286
|
Consider adding explicit documentation or extracting the shared concern.`;
|
|
37151
37287
|
}
|
|
37152
|
-
var co_change_analyzer,
|
|
37288
|
+
var co_change_analyzer, _internals9;
|
|
37153
37289
|
var init_co_change_analyzer = __esm(() => {
|
|
37154
37290
|
init_zod();
|
|
37155
37291
|
init_create_tool();
|
|
@@ -37181,11 +37317,11 @@ var init_co_change_analyzer = __esm(() => {
|
|
|
37181
37317
|
npmiThreshold,
|
|
37182
37318
|
maxCommitsToAnalyze
|
|
37183
37319
|
};
|
|
37184
|
-
const pairs = await
|
|
37185
|
-
return
|
|
37320
|
+
const pairs = await _internals9.detectDarkMatter(directory, options);
|
|
37321
|
+
return _internals9.formatDarkMatterOutput(pairs);
|
|
37186
37322
|
}
|
|
37187
37323
|
});
|
|
37188
|
-
|
|
37324
|
+
_internals9 = {
|
|
37189
37325
|
parseGitLog,
|
|
37190
37326
|
buildCoChangeMatrix,
|
|
37191
37327
|
getStaticEdges,
|
|
@@ -37196,7 +37332,7 @@ var init_co_change_analyzer = __esm(() => {
|
|
|
37196
37332
|
});
|
|
37197
37333
|
|
|
37198
37334
|
// src/commands/dark-matter.ts
|
|
37199
|
-
import
|
|
37335
|
+
import path17 from "path";
|
|
37200
37336
|
async function handleDarkMatterCommand(directory, args) {
|
|
37201
37337
|
const options = {};
|
|
37202
37338
|
for (let i = 0;i < args.length; i++) {
|
|
@@ -37216,7 +37352,7 @@ async function handleDarkMatterCommand(directory, args) {
|
|
|
37216
37352
|
}
|
|
37217
37353
|
let pairs;
|
|
37218
37354
|
try {
|
|
37219
|
-
pairs = await
|
|
37355
|
+
pairs = await _internals9.detectDarkMatter(directory, options);
|
|
37220
37356
|
} catch (err) {
|
|
37221
37357
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
37222
37358
|
return `## Dark Matter Analysis Failed
|
|
@@ -37228,7 +37364,7 @@ Ensure this is a git repository with commit history.`;
|
|
|
37228
37364
|
const output = formatDarkMatterOutput(pairs);
|
|
37229
37365
|
if (pairs.length > 0) {
|
|
37230
37366
|
try {
|
|
37231
|
-
const projectName =
|
|
37367
|
+
const projectName = path17.basename(path17.resolve(directory));
|
|
37232
37368
|
const entries = darkMatterToKnowledgeEntries(pairs, projectName);
|
|
37233
37369
|
if (entries.length > 0) {
|
|
37234
37370
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
@@ -37253,51 +37389,51 @@ var init_dark_matter = __esm(() => {
|
|
|
37253
37389
|
|
|
37254
37390
|
// src/config/cache-paths.ts
|
|
37255
37391
|
import * as os5 from "os";
|
|
37256
|
-
import * as
|
|
37392
|
+
import * as path18 from "path";
|
|
37257
37393
|
function getPluginConfigDir() {
|
|
37258
|
-
return
|
|
37394
|
+
return path18.join(process.env.XDG_CONFIG_HOME || path18.join(os5.homedir(), ".config"), "opencode");
|
|
37259
37395
|
}
|
|
37260
37396
|
function getPluginCachePaths() {
|
|
37261
|
-
const cacheBase = process.env.XDG_CACHE_HOME ||
|
|
37397
|
+
const cacheBase = process.env.XDG_CACHE_HOME || path18.join(os5.homedir(), ".cache");
|
|
37262
37398
|
const configDir = getPluginConfigDir();
|
|
37263
37399
|
const paths = [
|
|
37264
|
-
|
|
37265
|
-
|
|
37266
|
-
|
|
37400
|
+
path18.join(cacheBase, "opencode", "node_modules", "opencode-swarm"),
|
|
37401
|
+
path18.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
|
|
37402
|
+
path18.join(configDir, "node_modules", "opencode-swarm")
|
|
37267
37403
|
];
|
|
37268
37404
|
if (process.platform === "darwin") {
|
|
37269
|
-
const libCaches =
|
|
37270
|
-
paths.push(
|
|
37405
|
+
const libCaches = path18.join(os5.homedir(), "Library", "Caches");
|
|
37406
|
+
paths.push(path18.join(libCaches, "opencode", "node_modules", "opencode-swarm"), path18.join(libCaches, "opencode", "packages", "opencode-swarm@latest"));
|
|
37271
37407
|
}
|
|
37272
37408
|
if (process.platform === "win32") {
|
|
37273
|
-
const localAppData = process.env.LOCALAPPDATA ||
|
|
37274
|
-
const appData = process.env.APPDATA ||
|
|
37275
|
-
paths.push(
|
|
37409
|
+
const localAppData = process.env.LOCALAPPDATA || path18.join(os5.homedir(), "AppData", "Local");
|
|
37410
|
+
const appData = process.env.APPDATA || path18.join(os5.homedir(), "AppData", "Roaming");
|
|
37411
|
+
paths.push(path18.join(localAppData, "opencode", "node_modules", "opencode-swarm"), path18.join(localAppData, "opencode", "packages", "opencode-swarm@latest"), path18.join(appData, "opencode", "node_modules", "opencode-swarm"));
|
|
37276
37412
|
}
|
|
37277
37413
|
return paths;
|
|
37278
37414
|
}
|
|
37279
37415
|
function getPluginLockFilePaths() {
|
|
37280
|
-
const cacheBase = process.env.XDG_CACHE_HOME ||
|
|
37416
|
+
const cacheBase = process.env.XDG_CACHE_HOME || path18.join(os5.homedir(), ".cache");
|
|
37281
37417
|
const configDir = getPluginConfigDir();
|
|
37282
37418
|
const paths = [
|
|
37283
|
-
|
|
37284
|
-
|
|
37285
|
-
|
|
37419
|
+
path18.join(cacheBase, "opencode", "bun.lock"),
|
|
37420
|
+
path18.join(cacheBase, "opencode", "bun.lockb"),
|
|
37421
|
+
path18.join(configDir, "package-lock.json")
|
|
37286
37422
|
];
|
|
37287
37423
|
if (process.platform === "darwin") {
|
|
37288
|
-
const libCaches =
|
|
37289
|
-
paths.push(
|
|
37424
|
+
const libCaches = path18.join(os5.homedir(), "Library", "Caches");
|
|
37425
|
+
paths.push(path18.join(libCaches, "opencode", "bun.lock"), path18.join(libCaches, "opencode", "bun.lockb"));
|
|
37290
37426
|
}
|
|
37291
37427
|
if (process.platform === "win32") {
|
|
37292
|
-
const localAppData = process.env.LOCALAPPDATA ||
|
|
37293
|
-
paths.push(
|
|
37428
|
+
const localAppData = process.env.LOCALAPPDATA || path18.join(os5.homedir(), "AppData", "Local");
|
|
37429
|
+
paths.push(path18.join(localAppData, "opencode", "bun.lock"), path18.join(localAppData, "opencode", "bun.lockb"));
|
|
37294
37430
|
}
|
|
37295
37431
|
return paths;
|
|
37296
37432
|
}
|
|
37297
37433
|
var init_cache_paths = () => {};
|
|
37298
37434
|
|
|
37299
37435
|
// src/services/version-check.ts
|
|
37300
|
-
import { existsSync as existsSync9, mkdirSync as
|
|
37436
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
37301
37437
|
import { homedir as homedir5 } from "os";
|
|
37302
37438
|
import { join as join17 } from "path";
|
|
37303
37439
|
function cacheDir() {
|
|
@@ -37310,10 +37446,10 @@ function cacheFile() {
|
|
|
37310
37446
|
}
|
|
37311
37447
|
function readVersionCache() {
|
|
37312
37448
|
try {
|
|
37313
|
-
const
|
|
37314
|
-
if (!existsSync9(
|
|
37449
|
+
const path19 = cacheFile();
|
|
37450
|
+
if (!existsSync9(path19))
|
|
37315
37451
|
return null;
|
|
37316
|
-
const raw = readFileSync5(
|
|
37452
|
+
const raw = readFileSync5(path19, "utf-8");
|
|
37317
37453
|
const parsed = JSON.parse(raw);
|
|
37318
37454
|
if (typeof parsed?.checkedAt !== "number")
|
|
37319
37455
|
return null;
|
|
@@ -37353,7 +37489,7 @@ var init_version_check = __esm(() => {
|
|
|
37353
37489
|
// src/services/diagnose-service.ts
|
|
37354
37490
|
import * as child_process4 from "child_process";
|
|
37355
37491
|
import { existsSync as existsSync10, readdirSync as readdirSync4, readFileSync as readFileSync6, statSync as statSync6 } from "fs";
|
|
37356
|
-
import
|
|
37492
|
+
import path19 from "path";
|
|
37357
37493
|
import { fileURLToPath } from "url";
|
|
37358
37494
|
function validateTaskDag(plan) {
|
|
37359
37495
|
const allTaskIds = new Set;
|
|
@@ -37650,7 +37786,7 @@ async function checkSpecStaleness(directory, plan) {
|
|
|
37650
37786
|
};
|
|
37651
37787
|
}
|
|
37652
37788
|
async function checkConfigParseability(directory) {
|
|
37653
|
-
const configPath =
|
|
37789
|
+
const configPath = path19.join(directory, ".opencode/opencode-swarm.json");
|
|
37654
37790
|
if (!existsSync10(configPath)) {
|
|
37655
37791
|
return {
|
|
37656
37792
|
name: "Config Parseability",
|
|
@@ -37679,7 +37815,7 @@ function resolveGrammarDir(thisDir) {
|
|
|
37679
37815
|
const normalized = thisDir.replace(/\\/g, "/");
|
|
37680
37816
|
const isSource = normalized.endsWith("/src/services");
|
|
37681
37817
|
const isCliBundle = normalized.endsWith("/cli");
|
|
37682
|
-
return isSource || isCliBundle ?
|
|
37818
|
+
return isSource || isCliBundle ? path19.join(thisDir, "..", "lang", "grammars") : path19.join(thisDir, "lang", "grammars");
|
|
37683
37819
|
}
|
|
37684
37820
|
async function checkGrammarWasmFiles() {
|
|
37685
37821
|
const grammarFiles = [
|
|
@@ -37703,14 +37839,14 @@ async function checkGrammarWasmFiles() {
|
|
|
37703
37839
|
"tree-sitter-ini.wasm",
|
|
37704
37840
|
"tree-sitter-regex.wasm"
|
|
37705
37841
|
];
|
|
37706
|
-
const thisDir =
|
|
37842
|
+
const thisDir = path19.dirname(fileURLToPath(import.meta.url));
|
|
37707
37843
|
const grammarDir = resolveGrammarDir(thisDir);
|
|
37708
37844
|
const missing = [];
|
|
37709
|
-
if (!existsSync10(
|
|
37845
|
+
if (!existsSync10(path19.join(grammarDir, "tree-sitter.wasm"))) {
|
|
37710
37846
|
missing.push("tree-sitter.wasm (core runtime)");
|
|
37711
37847
|
}
|
|
37712
37848
|
for (const file3 of grammarFiles) {
|
|
37713
|
-
if (!existsSync10(
|
|
37849
|
+
if (!existsSync10(path19.join(grammarDir, file3))) {
|
|
37714
37850
|
missing.push(file3);
|
|
37715
37851
|
}
|
|
37716
37852
|
}
|
|
@@ -37728,7 +37864,7 @@ async function checkGrammarWasmFiles() {
|
|
|
37728
37864
|
};
|
|
37729
37865
|
}
|
|
37730
37866
|
async function checkCheckpointManifest(directory) {
|
|
37731
|
-
const manifestPath =
|
|
37867
|
+
const manifestPath = path19.join(directory, ".swarm/checkpoints.json");
|
|
37732
37868
|
if (!existsSync10(manifestPath)) {
|
|
37733
37869
|
return {
|
|
37734
37870
|
name: "Checkpoint Manifest",
|
|
@@ -37780,7 +37916,7 @@ async function checkCheckpointManifest(directory) {
|
|
|
37780
37916
|
}
|
|
37781
37917
|
}
|
|
37782
37918
|
async function checkEventStreamIntegrity(directory) {
|
|
37783
|
-
const eventsPath =
|
|
37919
|
+
const eventsPath = path19.join(directory, ".swarm/events.jsonl");
|
|
37784
37920
|
if (!existsSync10(eventsPath)) {
|
|
37785
37921
|
return {
|
|
37786
37922
|
name: "Event Stream",
|
|
@@ -37821,7 +37957,7 @@ async function checkEventStreamIntegrity(directory) {
|
|
|
37821
37957
|
}
|
|
37822
37958
|
}
|
|
37823
37959
|
async function checkSteeringDirectives(directory) {
|
|
37824
|
-
const eventsPath =
|
|
37960
|
+
const eventsPath = path19.join(directory, ".swarm/events.jsonl");
|
|
37825
37961
|
if (!existsSync10(eventsPath)) {
|
|
37826
37962
|
return {
|
|
37827
37963
|
name: "Steering Directives",
|
|
@@ -37877,7 +38013,7 @@ async function checkCurator(directory) {
|
|
|
37877
38013
|
detail: "Disabled (enable via curator.enabled)"
|
|
37878
38014
|
};
|
|
37879
38015
|
}
|
|
37880
|
-
const summaryPath =
|
|
38016
|
+
const summaryPath = path19.join(directory, ".swarm/curator-summary.json");
|
|
37881
38017
|
if (!existsSync10(summaryPath)) {
|
|
37882
38018
|
return {
|
|
37883
38019
|
name: "Curator",
|
|
@@ -38043,7 +38179,7 @@ async function getDiagnoseData(directory) {
|
|
|
38043
38179
|
checks5.push(await checkSteeringDirectives(directory));
|
|
38044
38180
|
checks5.push(await checkCurator(directory));
|
|
38045
38181
|
try {
|
|
38046
|
-
const evidenceDir =
|
|
38182
|
+
const evidenceDir = path19.join(directory, ".swarm", "evidence");
|
|
38047
38183
|
const snapshotFiles = existsSync10(evidenceDir) ? readdirSync4(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
|
|
38048
38184
|
if (snapshotFiles.length > 0) {
|
|
38049
38185
|
const latest = snapshotFiles.sort().pop();
|
|
@@ -38081,7 +38217,7 @@ async function getDiagnoseData(directory) {
|
|
|
38081
38217
|
cacheRows.push(`\u2B1C ${cachePath} \u2014 absent`);
|
|
38082
38218
|
continue;
|
|
38083
38219
|
}
|
|
38084
|
-
const pkgJsonPath =
|
|
38220
|
+
const pkgJsonPath = path19.join(cachePath, "package.json");
|
|
38085
38221
|
try {
|
|
38086
38222
|
const raw = readFileSync6(pkgJsonPath, "utf-8");
|
|
38087
38223
|
const parsed = JSON.parse(raw);
|
|
@@ -38169,13 +38305,13 @@ __export(exports_config_doctor, {
|
|
|
38169
38305
|
import * as crypto3 from "crypto";
|
|
38170
38306
|
import * as fs8 from "fs";
|
|
38171
38307
|
import * as os6 from "os";
|
|
38172
|
-
import * as
|
|
38308
|
+
import * as path20 from "path";
|
|
38173
38309
|
function getUserConfigDir3() {
|
|
38174
|
-
return process.env.XDG_CONFIG_HOME ||
|
|
38310
|
+
return process.env.XDG_CONFIG_HOME || path20.join(os6.homedir(), ".config");
|
|
38175
38311
|
}
|
|
38176
38312
|
function getConfigPaths(directory) {
|
|
38177
|
-
const userConfigPath =
|
|
38178
|
-
const projectConfigPath =
|
|
38313
|
+
const userConfigPath = path20.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
|
|
38314
|
+
const projectConfigPath = path20.join(directory, ".opencode", "opencode-swarm.json");
|
|
38179
38315
|
return { userConfigPath, projectConfigPath };
|
|
38180
38316
|
}
|
|
38181
38317
|
function computeHash(content) {
|
|
@@ -38200,9 +38336,9 @@ function isValidConfigPath(configPath, directory) {
|
|
|
38200
38336
|
const normalizedUser = userConfigPath.replace(/\\/g, "/");
|
|
38201
38337
|
const normalizedProject = projectConfigPath.replace(/\\/g, "/");
|
|
38202
38338
|
try {
|
|
38203
|
-
const resolvedConfig =
|
|
38204
|
-
const resolvedUser =
|
|
38205
|
-
const resolvedProject =
|
|
38339
|
+
const resolvedConfig = path20.resolve(configPath);
|
|
38340
|
+
const resolvedUser = path20.resolve(normalizedUser);
|
|
38341
|
+
const resolvedProject = path20.resolve(normalizedProject);
|
|
38206
38342
|
return resolvedConfig === resolvedUser || resolvedConfig === resolvedProject;
|
|
38207
38343
|
} catch {
|
|
38208
38344
|
return false;
|
|
@@ -38242,12 +38378,12 @@ function createConfigBackup(directory) {
|
|
|
38242
38378
|
};
|
|
38243
38379
|
}
|
|
38244
38380
|
function writeBackupArtifact(directory, backup) {
|
|
38245
|
-
const swarmDir =
|
|
38381
|
+
const swarmDir = path20.join(directory, ".swarm");
|
|
38246
38382
|
if (!fs8.existsSync(swarmDir)) {
|
|
38247
38383
|
fs8.mkdirSync(swarmDir, { recursive: true });
|
|
38248
38384
|
}
|
|
38249
38385
|
const backupFilename = `config-backup-${backup.createdAt}.json`;
|
|
38250
|
-
const backupPath =
|
|
38386
|
+
const backupPath = path20.join(swarmDir, backupFilename);
|
|
38251
38387
|
const artifact = {
|
|
38252
38388
|
createdAt: backup.createdAt,
|
|
38253
38389
|
configPath: backup.configPath,
|
|
@@ -38277,7 +38413,7 @@ function restoreFromBackup(backupPath, directory) {
|
|
|
38277
38413
|
return null;
|
|
38278
38414
|
}
|
|
38279
38415
|
const targetPath = artifact.configPath;
|
|
38280
|
-
const targetDir =
|
|
38416
|
+
const targetDir = path20.dirname(targetPath);
|
|
38281
38417
|
if (!fs8.existsSync(targetDir)) {
|
|
38282
38418
|
fs8.mkdirSync(targetDir, { recursive: true });
|
|
38283
38419
|
}
|
|
@@ -38308,9 +38444,9 @@ function readConfigFromFile(directory) {
|
|
|
38308
38444
|
return null;
|
|
38309
38445
|
}
|
|
38310
38446
|
}
|
|
38311
|
-
function validateConfigKey(
|
|
38447
|
+
function validateConfigKey(path21, value, _config) {
|
|
38312
38448
|
const findings = [];
|
|
38313
|
-
switch (
|
|
38449
|
+
switch (path21) {
|
|
38314
38450
|
case "agents": {
|
|
38315
38451
|
if (value !== undefined) {
|
|
38316
38452
|
findings.push({
|
|
@@ -38557,27 +38693,27 @@ function validateConfigKey(path22, value, _config) {
|
|
|
38557
38693
|
}
|
|
38558
38694
|
return findings;
|
|
38559
38695
|
}
|
|
38560
|
-
function walkConfigAndValidate(obj,
|
|
38696
|
+
function walkConfigAndValidate(obj, path21, config3, findings) {
|
|
38561
38697
|
if (obj === null || obj === undefined) {
|
|
38562
38698
|
return;
|
|
38563
38699
|
}
|
|
38564
|
-
if (
|
|
38565
|
-
const keyFindings = validateConfigKey(
|
|
38700
|
+
if (path21 && typeof obj === "object" && !Array.isArray(obj)) {
|
|
38701
|
+
const keyFindings = validateConfigKey(path21, obj, config3);
|
|
38566
38702
|
findings.push(...keyFindings);
|
|
38567
38703
|
}
|
|
38568
38704
|
if (typeof obj !== "object") {
|
|
38569
|
-
const keyFindings = validateConfigKey(
|
|
38705
|
+
const keyFindings = validateConfigKey(path21, obj, config3);
|
|
38570
38706
|
findings.push(...keyFindings);
|
|
38571
38707
|
return;
|
|
38572
38708
|
}
|
|
38573
38709
|
if (Array.isArray(obj)) {
|
|
38574
38710
|
obj.forEach((item, index) => {
|
|
38575
|
-
walkConfigAndValidate(item, `${
|
|
38711
|
+
walkConfigAndValidate(item, `${path21}[${index}]`, config3, findings);
|
|
38576
38712
|
});
|
|
38577
38713
|
return;
|
|
38578
38714
|
}
|
|
38579
38715
|
for (const [key, value] of Object.entries(obj)) {
|
|
38580
|
-
const newPath =
|
|
38716
|
+
const newPath = path21 ? `${path21}.${key}` : key;
|
|
38581
38717
|
walkConfigAndValidate(value, newPath, config3, findings);
|
|
38582
38718
|
}
|
|
38583
38719
|
}
|
|
@@ -38697,7 +38833,7 @@ function applySafeAutoFixes(directory, result) {
|
|
|
38697
38833
|
}
|
|
38698
38834
|
}
|
|
38699
38835
|
if (appliedFixes.length > 0) {
|
|
38700
|
-
const configDir =
|
|
38836
|
+
const configDir = path20.dirname(configPath);
|
|
38701
38837
|
if (!fs8.existsSync(configDir)) {
|
|
38702
38838
|
fs8.mkdirSync(configDir, { recursive: true });
|
|
38703
38839
|
}
|
|
@@ -38707,12 +38843,12 @@ function applySafeAutoFixes(directory, result) {
|
|
|
38707
38843
|
return { appliedFixes, updatedConfigPath };
|
|
38708
38844
|
}
|
|
38709
38845
|
function writeDoctorArtifact(directory, result) {
|
|
38710
|
-
const swarmDir =
|
|
38846
|
+
const swarmDir = path20.join(directory, ".swarm");
|
|
38711
38847
|
if (!fs8.existsSync(swarmDir)) {
|
|
38712
38848
|
fs8.mkdirSync(swarmDir, { recursive: true });
|
|
38713
38849
|
}
|
|
38714
38850
|
const artifactFilename = "config-doctor.json";
|
|
38715
|
-
const artifactPath =
|
|
38851
|
+
const artifactPath = path20.join(swarmDir, artifactFilename);
|
|
38716
38852
|
const guiOutput = {
|
|
38717
38853
|
timestamp: result.timestamp,
|
|
38718
38854
|
summary: result.summary,
|
|
@@ -39815,7 +39951,7 @@ var init_detector = __esm(() => {
|
|
|
39815
39951
|
|
|
39816
39952
|
// src/build/discovery.ts
|
|
39817
39953
|
import * as fs9 from "fs";
|
|
39818
|
-
import * as
|
|
39954
|
+
import * as path21 from "path";
|
|
39819
39955
|
function isCommandAvailable(command) {
|
|
39820
39956
|
if (toolchainCache.has(command)) {
|
|
39821
39957
|
return toolchainCache.get(command);
|
|
@@ -39847,11 +39983,11 @@ function findBuildFiles(workingDir, patterns) {
|
|
|
39847
39983
|
const regex = simpleGlobToRegex(pattern);
|
|
39848
39984
|
const matches = files.filter((f) => regex.test(f));
|
|
39849
39985
|
if (matches.length > 0) {
|
|
39850
|
-
return
|
|
39986
|
+
return path21.join(dir, matches[0]);
|
|
39851
39987
|
}
|
|
39852
39988
|
} catch {}
|
|
39853
39989
|
} else {
|
|
39854
|
-
const filePath =
|
|
39990
|
+
const filePath = path21.join(workingDir, pattern);
|
|
39855
39991
|
if (fs9.existsSync(filePath)) {
|
|
39856
39992
|
return filePath;
|
|
39857
39993
|
}
|
|
@@ -39860,7 +39996,7 @@ function findBuildFiles(workingDir, patterns) {
|
|
|
39860
39996
|
return null;
|
|
39861
39997
|
}
|
|
39862
39998
|
function getRepoDefinedScripts(workingDir, scripts) {
|
|
39863
|
-
const packageJsonPath =
|
|
39999
|
+
const packageJsonPath = path21.join(workingDir, "package.json");
|
|
39864
40000
|
if (!fs9.existsSync(packageJsonPath)) {
|
|
39865
40001
|
return [];
|
|
39866
40002
|
}
|
|
@@ -39901,7 +40037,7 @@ function findAllBuildFiles(workingDir) {
|
|
|
39901
40037
|
const regex = simpleGlobToRegex(pattern);
|
|
39902
40038
|
findFilesRecursive(workingDir, regex, allBuildFiles);
|
|
39903
40039
|
} else {
|
|
39904
|
-
const filePath =
|
|
40040
|
+
const filePath = path21.join(workingDir, pattern);
|
|
39905
40041
|
if (fs9.existsSync(filePath)) {
|
|
39906
40042
|
allBuildFiles.add(filePath);
|
|
39907
40043
|
}
|
|
@@ -39914,7 +40050,7 @@ function findFilesRecursive(dir, regex, results) {
|
|
|
39914
40050
|
try {
|
|
39915
40051
|
const entries = fs9.readdirSync(dir, { withFileTypes: true });
|
|
39916
40052
|
for (const entry of entries) {
|
|
39917
|
-
const fullPath =
|
|
40053
|
+
const fullPath = path21.join(dir, entry.name);
|
|
39918
40054
|
if (entry.isDirectory() && !["node_modules", ".git", "dist", "build", "target"].includes(entry.name)) {
|
|
39919
40055
|
findFilesRecursive(fullPath, regex, results);
|
|
39920
40056
|
} else if (entry.isFile() && regex.test(entry.name)) {
|
|
@@ -39937,7 +40073,7 @@ async function discoverBuildCommandsFromProfiles(workingDir) {
|
|
|
39937
40073
|
let foundCommand = false;
|
|
39938
40074
|
for (const cmd of sortedCommands) {
|
|
39939
40075
|
if (cmd.detectFile) {
|
|
39940
|
-
const detectFilePath =
|
|
40076
|
+
const detectFilePath = path21.join(workingDir, cmd.detectFile);
|
|
39941
40077
|
if (!fs9.existsSync(detectFilePath)) {
|
|
39942
40078
|
continue;
|
|
39943
40079
|
}
|
|
@@ -39970,7 +40106,7 @@ async function discoverBuildCommands(workingDir, options) {
|
|
|
39970
40106
|
const scope = options?.scope ?? "all";
|
|
39971
40107
|
const changedFiles = options?.changedFiles ?? [];
|
|
39972
40108
|
const _filesToCheck = filterByScope(workingDir, scope, changedFiles);
|
|
39973
|
-
const profileResult = await
|
|
40109
|
+
const profileResult = await _internals10.discoverBuildCommandsFromProfiles(workingDir);
|
|
39974
40110
|
const profileCommands = profileResult.commands;
|
|
39975
40111
|
const profileSkipped = profileResult.skipped;
|
|
39976
40112
|
const coveredEcosystems = new Set;
|
|
@@ -40033,7 +40169,7 @@ function clearToolchainCache() {
|
|
|
40033
40169
|
function getEcosystems() {
|
|
40034
40170
|
return ECOSYSTEMS.map((e) => e.ecosystem);
|
|
40035
40171
|
}
|
|
40036
|
-
var ECOSYSTEMS, PROFILE_TO_ECOSYSTEM_NAMES, toolchainCache,
|
|
40172
|
+
var ECOSYSTEMS, PROFILE_TO_ECOSYSTEM_NAMES, toolchainCache, _internals10, build_discovery;
|
|
40037
40173
|
var init_discovery = __esm(() => {
|
|
40038
40174
|
init_dist();
|
|
40039
40175
|
init_detector();
|
|
@@ -40151,7 +40287,7 @@ var init_discovery = __esm(() => {
|
|
|
40151
40287
|
php: ["php-composer"]
|
|
40152
40288
|
};
|
|
40153
40289
|
toolchainCache = new Map;
|
|
40154
|
-
|
|
40290
|
+
_internals10 = {
|
|
40155
40291
|
isCommandAvailable,
|
|
40156
40292
|
discoverBuildCommandsFromProfiles,
|
|
40157
40293
|
discoverBuildCommands,
|
|
@@ -40177,7 +40313,7 @@ var init_discovery = __esm(() => {
|
|
|
40177
40313
|
|
|
40178
40314
|
// src/services/tool-doctor.ts
|
|
40179
40315
|
import * as fs10 from "fs";
|
|
40180
|
-
import * as
|
|
40316
|
+
import * as path22 from "path";
|
|
40181
40317
|
function extractRegisteredToolKeys(indexPath) {
|
|
40182
40318
|
const registeredKeys = new Set;
|
|
40183
40319
|
try {
|
|
@@ -40232,8 +40368,8 @@ function checkBinaryReadiness() {
|
|
|
40232
40368
|
}
|
|
40233
40369
|
function runToolDoctor(_directory, pluginRoot) {
|
|
40234
40370
|
const findings = [];
|
|
40235
|
-
const resolvedPluginRoot = pluginRoot ??
|
|
40236
|
-
const indexPath =
|
|
40371
|
+
const resolvedPluginRoot = pluginRoot ?? path22.resolve(import.meta.dir, "..", "..");
|
|
40372
|
+
const indexPath = path22.join(resolvedPluginRoot, "src", "index.ts");
|
|
40237
40373
|
if (!fs10.existsSync(indexPath)) {
|
|
40238
40374
|
return {
|
|
40239
40375
|
findings: [
|
|
@@ -40403,7 +40539,7 @@ var exports_evidence_summary_service = {};
|
|
|
40403
40539
|
__export(exports_evidence_summary_service, {
|
|
40404
40540
|
isAutoSummaryEnabled: () => isAutoSummaryEnabled,
|
|
40405
40541
|
buildEvidenceSummary: () => buildEvidenceSummary,
|
|
40406
|
-
_internals: () =>
|
|
40542
|
+
_internals: () => _internals11,
|
|
40407
40543
|
REQUIRED_EVIDENCE_TYPES: () => REQUIRED_EVIDENCE_TYPES,
|
|
40408
40544
|
EVIDENCE_SUMMARY_VERSION: () => EVIDENCE_SUMMARY_VERSION
|
|
40409
40545
|
});
|
|
@@ -40441,14 +40577,14 @@ function getTaskStatus(task, bundle) {
|
|
|
40441
40577
|
if (task?.status) {
|
|
40442
40578
|
return task.status;
|
|
40443
40579
|
}
|
|
40444
|
-
const entries =
|
|
40580
|
+
const entries = _internals11.normalizeBundleEntries(bundle);
|
|
40445
40581
|
if (entries.length > 0) {
|
|
40446
40582
|
return "completed";
|
|
40447
40583
|
}
|
|
40448
40584
|
return "pending";
|
|
40449
40585
|
}
|
|
40450
40586
|
function isEvidenceComplete(bundle) {
|
|
40451
|
-
const entries =
|
|
40587
|
+
const entries = _internals11.normalizeBundleEntries(bundle);
|
|
40452
40588
|
if (entries.length === 0) {
|
|
40453
40589
|
return {
|
|
40454
40590
|
isComplete: false,
|
|
@@ -40484,10 +40620,10 @@ async function buildTaskSummary(directory, task, taskId) {
|
|
|
40484
40620
|
const result = await loadEvidence(directory, taskId);
|
|
40485
40621
|
const bundle = result.status === "found" ? result.bundle : null;
|
|
40486
40622
|
const phase = task?.phase ?? 0;
|
|
40487
|
-
const status =
|
|
40488
|
-
const evidenceCheck =
|
|
40489
|
-
const blockers =
|
|
40490
|
-
const entries =
|
|
40623
|
+
const status = _internals11.getTaskStatus(task, bundle);
|
|
40624
|
+
const evidenceCheck = _internals11.isEvidenceComplete(bundle);
|
|
40625
|
+
const blockers = _internals11.getTaskBlockers(task, evidenceCheck, status);
|
|
40626
|
+
const entries = _internals11.normalizeBundleEntries(bundle);
|
|
40491
40627
|
const hasReview = entries.some((e) => e.type === "review");
|
|
40492
40628
|
const hasTest = entries.some((e) => e.type === "test");
|
|
40493
40629
|
const hasApproval = entries.some((e) => e.type === "approval");
|
|
@@ -40516,12 +40652,12 @@ async function buildPhaseSummary(directory, phase) {
|
|
|
40516
40652
|
const taskSummaries = [];
|
|
40517
40653
|
const _taskMap = new Map(phase.tasks.map((t) => [t.id, t]));
|
|
40518
40654
|
for (const task of phase.tasks) {
|
|
40519
|
-
const summary = await
|
|
40655
|
+
const summary = await _internals11.buildTaskSummary(directory, task, task.id);
|
|
40520
40656
|
taskSummaries.push(summary);
|
|
40521
40657
|
}
|
|
40522
40658
|
const extraTaskIds = taskIds.filter((id) => !phaseTaskIds.has(id));
|
|
40523
40659
|
for (const taskId of extraTaskIds) {
|
|
40524
|
-
const summary = await
|
|
40660
|
+
const summary = await _internals11.buildTaskSummary(directory, undefined, taskId);
|
|
40525
40661
|
if (summary.phase === phase.id) {
|
|
40526
40662
|
taskSummaries.push(summary);
|
|
40527
40663
|
}
|
|
@@ -40622,7 +40758,7 @@ async function buildEvidenceSummary(directory, currentPhase) {
|
|
|
40622
40758
|
let totalTasks = 0;
|
|
40623
40759
|
let completedTasks = 0;
|
|
40624
40760
|
for (const phase of phasesToProcess) {
|
|
40625
|
-
const summary = await
|
|
40761
|
+
const summary = await _internals11.buildPhaseSummary(directory, phase);
|
|
40626
40762
|
phaseSummaries.push(summary);
|
|
40627
40763
|
totalTasks += summary.totalTasks;
|
|
40628
40764
|
completedTasks += summary.completedTasks;
|
|
@@ -40644,7 +40780,7 @@ async function buildEvidenceSummary(directory, currentPhase) {
|
|
|
40644
40780
|
overallBlockers,
|
|
40645
40781
|
summaryText: ""
|
|
40646
40782
|
};
|
|
40647
|
-
artifact.summaryText =
|
|
40783
|
+
artifact.summaryText = _internals11.generateSummaryText(artifact);
|
|
40648
40784
|
log("[EvidenceSummary] Summary built", {
|
|
40649
40785
|
phases: phaseSummaries.length,
|
|
40650
40786
|
totalTasks,
|
|
@@ -40663,7 +40799,7 @@ function isAutoSummaryEnabled(automationConfig) {
|
|
|
40663
40799
|
}
|
|
40664
40800
|
return automationConfig.capabilities?.evidence_auto_summaries === true;
|
|
40665
40801
|
}
|
|
40666
|
-
var VALID_EVIDENCE_TYPES2, REQUIRED_EVIDENCE_TYPES, EVIDENCE_SUMMARY_VERSION = "1.0.0",
|
|
40802
|
+
var VALID_EVIDENCE_TYPES2, REQUIRED_EVIDENCE_TYPES, EVIDENCE_SUMMARY_VERSION = "1.0.0", _internals11;
|
|
40667
40803
|
var init_evidence_summary_service = __esm(() => {
|
|
40668
40804
|
init_manager2();
|
|
40669
40805
|
init_manager();
|
|
@@ -40677,7 +40813,7 @@ var init_evidence_summary_service = __esm(() => {
|
|
|
40677
40813
|
"retrospective"
|
|
40678
40814
|
]);
|
|
40679
40815
|
REQUIRED_EVIDENCE_TYPES = ["review", "test"];
|
|
40680
|
-
|
|
40816
|
+
_internals11 = {
|
|
40681
40817
|
buildEvidenceSummary,
|
|
40682
40818
|
isAutoSummaryEnabled,
|
|
40683
40819
|
normalizeBundleEntries,
|
|
@@ -40924,12 +41060,12 @@ var init_export = __esm(() => {
|
|
|
40924
41060
|
|
|
40925
41061
|
// src/full-auto/state.ts
|
|
40926
41062
|
import * as fs11 from "fs";
|
|
40927
|
-
import * as
|
|
41063
|
+
import * as path23 from "path";
|
|
40928
41064
|
function nowISO() {
|
|
40929
41065
|
return new Date().toISOString();
|
|
40930
41066
|
}
|
|
40931
41067
|
function ensureSwarmDir(directory) {
|
|
40932
|
-
const swarmDir =
|
|
41068
|
+
const swarmDir = path23.resolve(directory, ".swarm");
|
|
40933
41069
|
if (!fs11.existsSync(swarmDir)) {
|
|
40934
41070
|
fs11.mkdirSync(swarmDir, { recursive: true });
|
|
40935
41071
|
}
|
|
@@ -41280,7 +41416,7 @@ function extractCurrentPhaseFromPlan2(plan) {
|
|
|
41280
41416
|
if (!plan) {
|
|
41281
41417
|
return { currentPhase: null, currentTask: null, incompleteTasks: [] };
|
|
41282
41418
|
}
|
|
41283
|
-
if (!
|
|
41419
|
+
if (!_internals12.validatePlanPhases(plan)) {
|
|
41284
41420
|
return { currentPhase: null, currentTask: null, incompleteTasks: [] };
|
|
41285
41421
|
}
|
|
41286
41422
|
let currentPhase = null;
|
|
@@ -41422,9 +41558,9 @@ function extractPhaseMetrics(content) {
|
|
|
41422
41558
|
async function getHandoffData(directory) {
|
|
41423
41559
|
const now = new Date().toISOString();
|
|
41424
41560
|
const sessionContent = await readSwarmFileAsync(directory, "session/state.json");
|
|
41425
|
-
const sessionState =
|
|
41561
|
+
const sessionState = _internals12.parseSessionState(sessionContent);
|
|
41426
41562
|
const plan = await loadPlanJsonOnly(directory);
|
|
41427
|
-
const planInfo =
|
|
41563
|
+
const planInfo = _internals12.extractCurrentPhaseFromPlan(plan);
|
|
41428
41564
|
if (!plan) {
|
|
41429
41565
|
const planMdContent = await readSwarmFileAsync(directory, "plan.md");
|
|
41430
41566
|
if (planMdContent) {
|
|
@@ -41443,8 +41579,8 @@ async function getHandoffData(directory) {
|
|
|
41443
41579
|
}
|
|
41444
41580
|
}
|
|
41445
41581
|
const contextContent = await readSwarmFileAsync(directory, "context.md");
|
|
41446
|
-
const recentDecisions =
|
|
41447
|
-
const rawPhaseMetrics =
|
|
41582
|
+
const recentDecisions = _internals12.extractDecisions(contextContent);
|
|
41583
|
+
const rawPhaseMetrics = _internals12.extractPhaseMetrics(contextContent);
|
|
41448
41584
|
const phaseMetrics = sanitizeString(rawPhaseMetrics, 1000);
|
|
41449
41585
|
let delegationState = null;
|
|
41450
41586
|
if (sessionState?.delegationState) {
|
|
@@ -41608,13 +41744,13 @@ ${lines.join(`
|
|
|
41608
41744
|
`)}
|
|
41609
41745
|
\`\`\``;
|
|
41610
41746
|
}
|
|
41611
|
-
var RTL_OVERRIDE_PATTERN, MAX_TASK_ID_LENGTH = 100, MAX_DECISION_LENGTH = 500, MAX_INCOMPLETE_TASKS = 20,
|
|
41747
|
+
var RTL_OVERRIDE_PATTERN, MAX_TASK_ID_LENGTH = 100, MAX_DECISION_LENGTH = 500, MAX_INCOMPLETE_TASKS = 20, _internals12;
|
|
41612
41748
|
var init_handoff_service = __esm(() => {
|
|
41613
41749
|
init_utils2();
|
|
41614
41750
|
init_manager();
|
|
41615
41751
|
init_utils();
|
|
41616
41752
|
RTL_OVERRIDE_PATTERN = /[\u202e\u202d\u202c\u200f]/g;
|
|
41617
|
-
|
|
41753
|
+
_internals12 = {
|
|
41618
41754
|
getHandoffData,
|
|
41619
41755
|
formatHandoffMarkdown,
|
|
41620
41756
|
formatContinuationPrompt,
|
|
@@ -41628,6 +41764,133 @@ var init_handoff_service = __esm(() => {
|
|
|
41628
41764
|
};
|
|
41629
41765
|
});
|
|
41630
41766
|
|
|
41767
|
+
// src/session/snapshot-writer.ts
|
|
41768
|
+
import { mkdirSync as mkdirSync10, renameSync as renameSync6 } from "fs";
|
|
41769
|
+
import * as path24 from "path";
|
|
41770
|
+
function serializeAgentSession(s) {
|
|
41771
|
+
const gateLog = {};
|
|
41772
|
+
const rawGateLog = s.gateLog ?? new Map;
|
|
41773
|
+
for (const [taskId, gates] of rawGateLog) {
|
|
41774
|
+
gateLog[taskId] = Array.from(gates ?? []);
|
|
41775
|
+
}
|
|
41776
|
+
const reviewerCallCount = {};
|
|
41777
|
+
const rawReviewerCallCount = s.reviewerCallCount ?? new Map;
|
|
41778
|
+
for (const [phase, count] of rawReviewerCallCount) {
|
|
41779
|
+
reviewerCallCount[String(phase)] = count;
|
|
41780
|
+
}
|
|
41781
|
+
const partialGateWarningsIssuedForTask = Array.from(s.partialGateWarningsIssuedForTask ?? new Set);
|
|
41782
|
+
const catastrophicPhaseWarnings = Array.from(s.catastrophicPhaseWarnings ?? new Set);
|
|
41783
|
+
const phaseAgentsDispatched = Array.from(s.phaseAgentsDispatched ?? new Set);
|
|
41784
|
+
const lastCompletedPhaseAgentsDispatched = Array.from(s.lastCompletedPhaseAgentsDispatched ?? new Set);
|
|
41785
|
+
const windows = {};
|
|
41786
|
+
const rawWindows = s.windows ?? {};
|
|
41787
|
+
for (const [key, win] of Object.entries(rawWindows)) {
|
|
41788
|
+
windows[key] = {
|
|
41789
|
+
id: win.id,
|
|
41790
|
+
agentName: win.agentName,
|
|
41791
|
+
startedAtMs: win.startedAtMs,
|
|
41792
|
+
toolCalls: win.toolCalls,
|
|
41793
|
+
consecutiveErrors: win.consecutiveErrors,
|
|
41794
|
+
hardLimitHit: win.hardLimitHit,
|
|
41795
|
+
lastSuccessTimeMs: win.lastSuccessTimeMs,
|
|
41796
|
+
recentToolCalls: win.recentToolCalls,
|
|
41797
|
+
warningIssued: win.warningIssued,
|
|
41798
|
+
warningReason: win.warningReason,
|
|
41799
|
+
transientRetryCount: win.transientRetryCount ?? 0
|
|
41800
|
+
};
|
|
41801
|
+
}
|
|
41802
|
+
return {
|
|
41803
|
+
agentName: s.agentName,
|
|
41804
|
+
lastToolCallTime: s.lastToolCallTime,
|
|
41805
|
+
lastAgentEventTime: s.lastAgentEventTime,
|
|
41806
|
+
delegationActive: s.delegationActive,
|
|
41807
|
+
activeInvocationId: s.activeInvocationId,
|
|
41808
|
+
lastInvocationIdByAgent: s.lastInvocationIdByAgent ?? {},
|
|
41809
|
+
windows,
|
|
41810
|
+
lastCompactionHint: s.lastCompactionHint ?? 0,
|
|
41811
|
+
architectWriteCount: s.architectWriteCount ?? 0,
|
|
41812
|
+
lastCoderDelegationTaskId: s.lastCoderDelegationTaskId ?? null,
|
|
41813
|
+
currentTaskId: s.currentTaskId ?? null,
|
|
41814
|
+
turboMode: s.turboMode ?? false,
|
|
41815
|
+
gateLog,
|
|
41816
|
+
reviewerCallCount,
|
|
41817
|
+
lastGateFailure: s.lastGateFailure ?? null,
|
|
41818
|
+
partialGateWarningsIssuedForTask,
|
|
41819
|
+
selfFixAttempted: s.selfFixAttempted ?? false,
|
|
41820
|
+
selfCodingWarnedAtCount: s.selfCodingWarnedAtCount ?? 0,
|
|
41821
|
+
catastrophicPhaseWarnings,
|
|
41822
|
+
lastPhaseCompleteTimestamp: s.lastPhaseCompleteTimestamp ?? 0,
|
|
41823
|
+
lastPhaseCompletePhase: s.lastPhaseCompletePhase ?? 0,
|
|
41824
|
+
phaseAgentsDispatched,
|
|
41825
|
+
lastCompletedPhaseAgentsDispatched,
|
|
41826
|
+
qaSkipCount: s.qaSkipCount ?? 0,
|
|
41827
|
+
qaSkipTaskIds: s.qaSkipTaskIds ?? [],
|
|
41828
|
+
pendingAdvisoryMessages: s.pendingAdvisoryMessages ?? [],
|
|
41829
|
+
taskWorkflowStates: Object.fromEntries(s.taskWorkflowStates ?? new Map),
|
|
41830
|
+
...s.scopeViolationDetected !== undefined && {
|
|
41831
|
+
scopeViolationDetected: s.scopeViolationDetected
|
|
41832
|
+
},
|
|
41833
|
+
model_fallback_index: s.model_fallback_index ?? 0,
|
|
41834
|
+
modelFallbackExhausted: s.modelFallbackExhausted ?? false,
|
|
41835
|
+
coderRevisions: s.coderRevisions ?? 0,
|
|
41836
|
+
revisionLimitHit: s.revisionLimitHit ?? false,
|
|
41837
|
+
fullAutoMode: s.fullAutoMode ?? false,
|
|
41838
|
+
fullAutoInteractionCount: s.fullAutoInteractionCount ?? 0,
|
|
41839
|
+
fullAutoDeadlockCount: s.fullAutoDeadlockCount ?? 0,
|
|
41840
|
+
fullAutoLastQuestionHash: s.fullAutoLastQuestionHash ?? null,
|
|
41841
|
+
sessionRehydratedAt: s.sessionRehydratedAt ?? 0
|
|
41842
|
+
};
|
|
41843
|
+
}
|
|
41844
|
+
async function writeSnapshot(directory, state) {
|
|
41845
|
+
try {
|
|
41846
|
+
const snapshot = {
|
|
41847
|
+
version: 2,
|
|
41848
|
+
writtenAt: Date.now(),
|
|
41849
|
+
toolAggregates: Object.fromEntries(state.toolAggregates),
|
|
41850
|
+
activeAgent: Object.fromEntries(state.activeAgent),
|
|
41851
|
+
delegationChains: Object.fromEntries(state.delegationChains),
|
|
41852
|
+
agentSessions: {}
|
|
41853
|
+
};
|
|
41854
|
+
for (const [sessionId, sessionState] of state.agentSessions) {
|
|
41855
|
+
snapshot.agentSessions[sessionId] = serializeAgentSession(sessionState);
|
|
41856
|
+
}
|
|
41857
|
+
const content = JSON.stringify(snapshot, null, 2);
|
|
41858
|
+
const resolvedPath = validateSwarmPath(directory, "session/state.json");
|
|
41859
|
+
const dir = path24.dirname(resolvedPath);
|
|
41860
|
+
mkdirSync10(dir, { recursive: true });
|
|
41861
|
+
const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
41862
|
+
await bunWrite(tempPath, content);
|
|
41863
|
+
renameSync6(tempPath, resolvedPath);
|
|
41864
|
+
} catch (error93) {
|
|
41865
|
+
log("[snapshot-writer] write failed", {
|
|
41866
|
+
error: error93 instanceof Error ? error93.message : String(error93)
|
|
41867
|
+
});
|
|
41868
|
+
}
|
|
41869
|
+
}
|
|
41870
|
+
function createSnapshotWriterHook(directory) {
|
|
41871
|
+
return (_input, _output) => {
|
|
41872
|
+
_writeInFlight = _writeInFlight.then(() => _internals13.writeSnapshot(directory, swarmState), () => _internals13.writeSnapshot(directory, swarmState));
|
|
41873
|
+
return _writeInFlight;
|
|
41874
|
+
};
|
|
41875
|
+
}
|
|
41876
|
+
async function flushPendingSnapshot(directory) {
|
|
41877
|
+
_writeInFlight = _writeInFlight.then(() => _internals13.writeSnapshot(directory, swarmState), () => _internals13.writeSnapshot(directory, swarmState));
|
|
41878
|
+
await _writeInFlight;
|
|
41879
|
+
}
|
|
41880
|
+
var _writeInFlight, _internals13;
|
|
41881
|
+
var init_snapshot_writer = __esm(() => {
|
|
41882
|
+
init_utils2();
|
|
41883
|
+
init_state();
|
|
41884
|
+
init_utils();
|
|
41885
|
+
init_bun_compat();
|
|
41886
|
+
_writeInFlight = Promise.resolve();
|
|
41887
|
+
_internals13 = {
|
|
41888
|
+
writeSnapshot,
|
|
41889
|
+
createSnapshotWriterHook,
|
|
41890
|
+
flushPendingSnapshot
|
|
41891
|
+
};
|
|
41892
|
+
});
|
|
41893
|
+
|
|
41631
41894
|
// src/commands/handoff.ts
|
|
41632
41895
|
import crypto4 from "crypto";
|
|
41633
41896
|
import { renameSync as renameSync7, unlinkSync as unlinkSync4 } from "fs";
|
|
@@ -47772,7 +48035,7 @@ async function handleSimulateCommand(directory, args) {
|
|
|
47772
48035
|
}
|
|
47773
48036
|
let darkMatterPairs;
|
|
47774
48037
|
try {
|
|
47775
|
-
darkMatterPairs = await
|
|
48038
|
+
darkMatterPairs = await _internals9.detectDarkMatter(directory, options);
|
|
47776
48039
|
} catch (err) {
|
|
47777
48040
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
47778
48041
|
return `## Simulate Report
|