opencode-swarm 7.58.1 → 7.59.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/agent-output-schema.d.ts +1 -1
- package/dist/cli/index.js +5 -5
- package/dist/config/constants.d.ts +1 -1
- package/dist/config/schema.d.ts +42 -0
- package/dist/index.js +968 -318
- package/dist/memory/schema.d.ts +1 -1
- package/dist/tools/lean-turbo-run-phase.d.ts +2 -1
- package/dist/turbo/lean/index.d.ts +4 -1
- package/dist/turbo/lean/merge-back.d.ts +180 -0
- package/dist/turbo/lean/runner.d.ts +47 -1
- package/dist/turbo/lean/state.d.ts +10 -0
- package/dist/turbo/lean/worktree.d.ts +194 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -69,7 +69,7 @@ var package_default;
|
|
|
69
69
|
var init_package = __esm(() => {
|
|
70
70
|
package_default = {
|
|
71
71
|
name: "opencode-swarm",
|
|
72
|
-
version: "7.
|
|
72
|
+
version: "7.59.1",
|
|
73
73
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
74
74
|
main: "dist/index.js",
|
|
75
75
|
types: "dist/index.d.ts",
|
|
@@ -1044,7 +1044,9 @@ var init_constants = __esm(() => {
|
|
|
1044
1044
|
phase_critic: true,
|
|
1045
1045
|
integrated_diff_required: true,
|
|
1046
1046
|
allow_docs_only_without_reviewer: false,
|
|
1047
|
-
worktree_isolation: false
|
|
1047
|
+
worktree_isolation: false,
|
|
1048
|
+
merge_strategy: "merge",
|
|
1049
|
+
worktree_dir: undefined
|
|
1048
1050
|
};
|
|
1049
1051
|
});
|
|
1050
1052
|
|
|
@@ -15917,9 +15919,9 @@ var init_schema = __esm(() => {
|
|
|
15917
15919
|
phase_critic: exports_external.boolean().default(true),
|
|
15918
15920
|
integrated_diff_required: exports_external.boolean().default(true),
|
|
15919
15921
|
allow_docs_only_without_reviewer: exports_external.boolean().default(false),
|
|
15920
|
-
worktree_isolation: exports_external.boolean().default(false)
|
|
15921
|
-
|
|
15922
|
-
|
|
15922
|
+
worktree_isolation: exports_external.boolean().default(false),
|
|
15923
|
+
merge_strategy: exports_external.enum(["merge", "rebase", "cherry-pick"]).default("merge").optional(),
|
|
15924
|
+
worktree_dir: exports_external.string().optional()
|
|
15923
15925
|
});
|
|
15924
15926
|
StandardTurboConfigSchema = exports_external.object({
|
|
15925
15927
|
strategy: exports_external.literal("standard"),
|
|
@@ -57803,7 +57805,7 @@ var init_knowledge_validator = __esm(() => {
|
|
|
57803
57805
|
/\bmkfs\b/,
|
|
57804
57806
|
/\bdd\s+if=/,
|
|
57805
57807
|
/:\(\)\s*\{/,
|
|
57806
|
-
/\bchmod\s+-R\s+777\b
|
|
57808
|
+
/\bchmod\s+-R\s+777\b/i,
|
|
57807
57809
|
/\bdeltree\b/,
|
|
57808
57810
|
/\brmdir\s+\/s\b/,
|
|
57809
57811
|
/\bkill\s+-9\b/,
|
|
@@ -92851,7 +92853,7 @@ async function readMergedKnowledge(directory, config3, context, opts) {
|
|
|
92851
92853
|
const retractionRecords = await readRetractionRecords(directory);
|
|
92852
92854
|
const suppressedLessons = new Set(retractionRecords.map((record3) => record3.normalized_lesson).filter((value) => typeof value === "string" && value.length > 0));
|
|
92853
92855
|
const scopeFilter = config3.scope_filter ?? ["global"];
|
|
92854
|
-
const filtered = merged.filter((entry) => (opts?.skipScopeFilter || scopeFilter.some((pattern) => (entry.scope ?? "global") === pattern)) &&
|
|
92856
|
+
const filtered = merged.filter((entry) => (opts?.skipScopeFilter || scopeFilter.some((pattern) => (entry.scope ?? "global") === pattern)) && entry.status !== QUARANTINED_STATUS && !suppressedLessons.has(normalize4(entry.lesson)));
|
|
92855
92857
|
const ranked = filtered.map((entry) => {
|
|
92856
92858
|
let categoryScore = 0;
|
|
92857
92859
|
if (context?.currentPhase) {
|
|
@@ -93023,12 +93025,11 @@ function scoreDirectiveAgainstContext(entry, ctx) {
|
|
|
93023
93025
|
score += 0.1;
|
|
93024
93026
|
return { triggerHit, actionHit, agentHit, score: Math.min(1, score) };
|
|
93025
93027
|
}
|
|
93026
|
-
var JACCARD_THRESHOLD2 = 0.6, HIVE_TIER_BOOST = 0.05, SAME_PROJECT_PENALTY = -0.05,
|
|
93028
|
+
var JACCARD_THRESHOLD2 = 0.6, HIVE_TIER_BOOST = 0.05, SAME_PROJECT_PENALTY = -0.05, QUARANTINED_STATUS = "quarantined";
|
|
93027
93029
|
var init_knowledge_reader = __esm(() => {
|
|
93028
93030
|
init_task_file();
|
|
93029
93031
|
init_logger();
|
|
93030
93032
|
init_knowledge_store();
|
|
93031
|
-
NORMAL_RETRIEVAL_STATUSES = new Set(["established", "promoted"]);
|
|
93032
93033
|
});
|
|
93033
93034
|
|
|
93034
93035
|
// src/hooks/search-knowledge.ts
|
|
@@ -93081,6 +93082,8 @@ async function searchKnowledge(params) {
|
|
|
93081
93082
|
});
|
|
93082
93083
|
const counterRollups = await readKnowledgeCounterRollups(directory);
|
|
93083
93084
|
candidates = candidates.filter((e) => {
|
|
93085
|
+
if (e.status === "archived")
|
|
93086
|
+
return false;
|
|
93084
93087
|
if (e.status === "quarantined")
|
|
93085
93088
|
return false;
|
|
93086
93089
|
if (tier === "hive" && e.tier !== "hive")
|
|
@@ -93513,10 +93516,10 @@ var init_curator_drift = __esm(() => {
|
|
|
93513
93516
|
var exports_design_doc_drift = {};
|
|
93514
93517
|
__export(exports_design_doc_drift, {
|
|
93515
93518
|
runDesignDocDriftCheck: () => runDesignDocDriftCheck,
|
|
93516
|
-
_internals: () =>
|
|
93519
|
+
_internals: () => _internals69
|
|
93517
93520
|
});
|
|
93518
93521
|
import * as fs109 from "node:fs";
|
|
93519
|
-
import * as
|
|
93522
|
+
import * as path149 from "node:path";
|
|
93520
93523
|
function mtimeMsOrNull(absPath) {
|
|
93521
93524
|
try {
|
|
93522
93525
|
return fs109.statSync(absPath).mtimeMs;
|
|
@@ -93527,35 +93530,35 @@ function mtimeMsOrNull(absPath) {
|
|
|
93527
93530
|
function resolveAnchorWithin(directory, anchor) {
|
|
93528
93531
|
if (!anchor || typeof anchor !== "string")
|
|
93529
93532
|
return null;
|
|
93530
|
-
const root =
|
|
93531
|
-
const resolved =
|
|
93532
|
-
const rel =
|
|
93533
|
-
if (rel.startsWith("..") ||
|
|
93533
|
+
const root = path149.resolve(directory);
|
|
93534
|
+
const resolved = path149.resolve(root, anchor);
|
|
93535
|
+
const rel = path149.relative(root, resolved);
|
|
93536
|
+
if (rel.startsWith("..") || path149.isAbsolute(rel))
|
|
93534
93537
|
return null;
|
|
93535
93538
|
return resolved;
|
|
93536
93539
|
}
|
|
93537
93540
|
async function runDesignDocDriftCheck(directory, phase, outDir) {
|
|
93538
93541
|
try {
|
|
93539
|
-
const root =
|
|
93540
|
-
const outAbs =
|
|
93541
|
-
const outRel =
|
|
93542
|
-
if (outRel.startsWith("..") ||
|
|
93542
|
+
const root = path149.resolve(directory);
|
|
93543
|
+
const outAbs = path149.resolve(root, outDir);
|
|
93544
|
+
const outRel = path149.relative(root, outAbs);
|
|
93545
|
+
if (outRel.startsWith("..") || path149.isAbsolute(outRel)) {
|
|
93543
93546
|
return null;
|
|
93544
93547
|
}
|
|
93545
93548
|
const docMtimes = new Map;
|
|
93546
93549
|
const checkedDocs = [];
|
|
93547
93550
|
const missingDocs = [];
|
|
93548
93551
|
for (const [docName, relFile] of Object.entries(DESIGN_DOC_FILES)) {
|
|
93549
|
-
const abs =
|
|
93552
|
+
const abs = path149.join(outAbs, relFile);
|
|
93550
93553
|
const mtime = mtimeMsOrNull(abs);
|
|
93551
93554
|
docMtimes.set(docName, mtime);
|
|
93552
93555
|
if (mtime === null) {
|
|
93553
|
-
missingDocs.push(
|
|
93556
|
+
missingDocs.push(path149.join(outDir, relFile));
|
|
93554
93557
|
} else {
|
|
93555
|
-
checkedDocs.push(
|
|
93558
|
+
checkedDocs.push(path149.join(outDir, relFile));
|
|
93556
93559
|
}
|
|
93557
93560
|
}
|
|
93558
|
-
const traceabilityAbs =
|
|
93561
|
+
const traceabilityAbs = path149.join(outAbs, TRACEABILITY_REL);
|
|
93559
93562
|
let registry3 = null;
|
|
93560
93563
|
try {
|
|
93561
93564
|
const stat9 = await fs109.promises.stat(traceabilityAbs);
|
|
@@ -93568,7 +93571,7 @@ async function runDesignDocDriftCheck(directory, phase, outDir) {
|
|
|
93568
93571
|
registry3 = null;
|
|
93569
93572
|
}
|
|
93570
93573
|
const noDocs = checkedDocs.length === 0 || registry3 === null;
|
|
93571
|
-
const specMtime = mtimeMsOrNull(
|
|
93574
|
+
const specMtime = mtimeMsOrNull(path149.join(root, ".swarm", "spec.md"));
|
|
93572
93575
|
const staleSections = [];
|
|
93573
93576
|
if (!noDocs && Array.isArray(registry3?.sections)) {
|
|
93574
93577
|
for (const section of registry3.sections) {
|
|
@@ -93624,7 +93627,7 @@ async function runDesignDocDriftCheck(directory, phase, outDir) {
|
|
|
93624
93627
|
};
|
|
93625
93628
|
const filename = `${DOC_DRIFT_REPORT_PREFIX}${phase}.json`;
|
|
93626
93629
|
const filePath = validateSwarmPath(directory, filename);
|
|
93627
|
-
await fs109.promises.mkdir(
|
|
93630
|
+
await fs109.promises.mkdir(path149.dirname(filePath), { recursive: true });
|
|
93628
93631
|
await fs109.promises.writeFile(filePath, JSON.stringify(report, null, 2), "utf-8");
|
|
93629
93632
|
getGlobalEventBus().publish("curator.docdrift.completed", {
|
|
93630
93633
|
phase,
|
|
@@ -93645,7 +93648,7 @@ async function runDesignDocDriftCheck(directory, phase, outDir) {
|
|
|
93645
93648
|
return null;
|
|
93646
93649
|
}
|
|
93647
93650
|
}
|
|
93648
|
-
var DOC_DRIFT_REPORT_PREFIX = "doc-drift-phase-", MAX_TRACEABILITY_BYTES, DESIGN_DOC_FILES, TRACEABILITY_REL,
|
|
93651
|
+
var DOC_DRIFT_REPORT_PREFIX = "doc-drift-phase-", MAX_TRACEABILITY_BYTES, DESIGN_DOC_FILES, TRACEABILITY_REL, _internals69;
|
|
93649
93652
|
var init_design_doc_drift = __esm(() => {
|
|
93650
93653
|
init_event_bus();
|
|
93651
93654
|
init_logger();
|
|
@@ -93655,11 +93658,11 @@ var init_design_doc_drift = __esm(() => {
|
|
|
93655
93658
|
domain: "domain.md",
|
|
93656
93659
|
"technical-spec": "technical-spec.md",
|
|
93657
93660
|
"behavior-spec": "behavior-spec.md",
|
|
93658
|
-
"reference-impl":
|
|
93659
|
-
"idiom-notes":
|
|
93661
|
+
"reference-impl": path149.join("reference", "reference-impl.md"),
|
|
93662
|
+
"idiom-notes": path149.join("reference", "idiom-notes.md")
|
|
93660
93663
|
};
|
|
93661
|
-
TRACEABILITY_REL =
|
|
93662
|
-
|
|
93664
|
+
TRACEABILITY_REL = path149.join("reference", "traceability.json");
|
|
93665
|
+
_internals69 = {
|
|
93663
93666
|
mtimeMsOrNull,
|
|
93664
93667
|
resolveAnchorWithin,
|
|
93665
93668
|
DESIGN_DOC_FILES
|
|
@@ -93670,11 +93673,11 @@ var init_design_doc_drift = __esm(() => {
|
|
|
93670
93673
|
var exports_project_context = {};
|
|
93671
93674
|
__export(exports_project_context, {
|
|
93672
93675
|
buildProjectContext: () => buildProjectContext,
|
|
93673
|
-
_internals: () =>
|
|
93676
|
+
_internals: () => _internals80,
|
|
93674
93677
|
LANG_BACKEND_DETECTION_TIMEOUT_MS: () => LANG_BACKEND_DETECTION_TIMEOUT_MS
|
|
93675
93678
|
});
|
|
93676
93679
|
import * as fs133 from "node:fs";
|
|
93677
|
-
import * as
|
|
93680
|
+
import * as path178 from "node:path";
|
|
93678
93681
|
function detectFileExists2(directory, pattern) {
|
|
93679
93682
|
if (pattern.includes("*") || pattern.includes("?")) {
|
|
93680
93683
|
try {
|
|
@@ -93686,7 +93689,7 @@ function detectFileExists2(directory, pattern) {
|
|
|
93686
93689
|
}
|
|
93687
93690
|
}
|
|
93688
93691
|
try {
|
|
93689
|
-
fs133.accessSync(
|
|
93692
|
+
fs133.accessSync(path178.join(directory, pattern));
|
|
93690
93693
|
return true;
|
|
93691
93694
|
} catch {
|
|
93692
93695
|
return false;
|
|
@@ -93695,7 +93698,7 @@ function detectFileExists2(directory, pattern) {
|
|
|
93695
93698
|
function selectTestCommandFromScriptsTest(backend, directory) {
|
|
93696
93699
|
let pkgRaw;
|
|
93697
93700
|
try {
|
|
93698
|
-
pkgRaw = fs133.readFileSync(
|
|
93701
|
+
pkgRaw = fs133.readFileSync(path178.join(directory, "package.json"), "utf-8");
|
|
93699
93702
|
} catch {
|
|
93700
93703
|
return null;
|
|
93701
93704
|
}
|
|
@@ -93754,7 +93757,7 @@ function selectLintCommand(backend, directory) {
|
|
|
93754
93757
|
return null;
|
|
93755
93758
|
}
|
|
93756
93759
|
async function buildProjectContext(directory) {
|
|
93757
|
-
const backend = await
|
|
93760
|
+
const backend = await _internals80.pickBackend(directory);
|
|
93758
93761
|
if (!backend)
|
|
93759
93762
|
return null;
|
|
93760
93763
|
const ctx = emptyProjectContext();
|
|
@@ -93793,17 +93796,17 @@ async function buildProjectContext(directory) {
|
|
|
93793
93796
|
if (backend.prompts.reviewerChecklist.length > 0) {
|
|
93794
93797
|
ctx.REVIEWER_CHECKLIST = bulletList(backend.prompts.reviewerChecklist);
|
|
93795
93798
|
}
|
|
93796
|
-
const profiles =
|
|
93799
|
+
const profiles = _internals80.pickedProfiles(directory);
|
|
93797
93800
|
if (profiles.length > 1) {
|
|
93798
93801
|
ctx.PROJECT_CONTEXT_SECONDARY_LANGUAGES = profiles.slice(1).map((p) => p.id).join(", ");
|
|
93799
93802
|
}
|
|
93800
93803
|
return ctx;
|
|
93801
93804
|
}
|
|
93802
|
-
var LANG_BACKEND_DETECTION_TIMEOUT_MS = 300,
|
|
93805
|
+
var LANG_BACKEND_DETECTION_TIMEOUT_MS = 300, _internals80;
|
|
93803
93806
|
var init_project_context = __esm(() => {
|
|
93804
93807
|
init_dispatch();
|
|
93805
93808
|
init_framework_detector();
|
|
93806
|
-
|
|
93809
|
+
_internals80 = {
|
|
93807
93810
|
pickBackend,
|
|
93808
93811
|
pickedProfiles
|
|
93809
93812
|
};
|
|
@@ -93813,7 +93816,7 @@ var init_project_context = __esm(() => {
|
|
|
93813
93816
|
init_package();
|
|
93814
93817
|
init_agents2();
|
|
93815
93818
|
init_critic();
|
|
93816
|
-
import * as
|
|
93819
|
+
import * as path179 from "node:path";
|
|
93817
93820
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
93818
93821
|
|
|
93819
93822
|
// src/background/index.ts
|
|
@@ -116503,7 +116506,468 @@ init_state2();
|
|
|
116503
116506
|
init_file_locks();
|
|
116504
116507
|
init_manager();
|
|
116505
116508
|
init_state();
|
|
116509
|
+
|
|
116510
|
+
// src/turbo/lean/merge-back.ts
|
|
116511
|
+
init_bun_compat();
|
|
116512
|
+
|
|
116513
|
+
// src/turbo/lean/worktree.ts
|
|
116514
|
+
init_bun_compat();
|
|
116515
|
+
import * as os14 from "node:os";
|
|
116516
|
+
import * as path137 from "node:path";
|
|
116517
|
+
var _internals62 = {
|
|
116518
|
+
bunSpawn,
|
|
116519
|
+
platform: process.platform,
|
|
116520
|
+
sleep: (ms) => new Promise((resolve50) => setTimeout(resolve50, ms)),
|
|
116521
|
+
osTmpdir: () => os14.tmpdir(),
|
|
116522
|
+
getCoreLongPaths: async (directory) => {
|
|
116523
|
+
const result = await runGit(["config", "core.longpaths"], directory);
|
|
116524
|
+
if (result.exitCode !== 0) {
|
|
116525
|
+
return;
|
|
116526
|
+
}
|
|
116527
|
+
const value = result.stdout.trim().toLowerCase();
|
|
116528
|
+
return value === "" ? undefined : value;
|
|
116529
|
+
}
|
|
116530
|
+
};
|
|
116531
|
+
var WORKTREE_TIMEOUT_MS = 30000;
|
|
116532
|
+
var WIN_PATH_BUDGET = 250;
|
|
116533
|
+
async function runGit(args2, cwd, timeoutMs = WORKTREE_TIMEOUT_MS) {
|
|
116534
|
+
const proc = _internals62.bunSpawn(["git", ...args2], {
|
|
116535
|
+
cwd,
|
|
116536
|
+
timeout: timeoutMs,
|
|
116537
|
+
stdin: "ignore",
|
|
116538
|
+
stdout: "pipe",
|
|
116539
|
+
stderr: "pipe",
|
|
116540
|
+
env: { ...process.env, LC_ALL: "C" }
|
|
116541
|
+
});
|
|
116542
|
+
try {
|
|
116543
|
+
const exitCode = await proc.exited;
|
|
116544
|
+
const stdout = await proc.stdout.text();
|
|
116545
|
+
const stderr = await proc.stderr.text();
|
|
116546
|
+
return { exitCode, stdout, stderr };
|
|
116547
|
+
} finally {
|
|
116548
|
+
try {
|
|
116549
|
+
proc.kill();
|
|
116550
|
+
} catch {}
|
|
116551
|
+
}
|
|
116552
|
+
}
|
|
116553
|
+
async function checkPathBudget(worktreeRoot, directory) {
|
|
116554
|
+
if (_internals62.platform !== "win32") {
|
|
116555
|
+
return { ok: true };
|
|
116556
|
+
}
|
|
116557
|
+
let longPaths;
|
|
116558
|
+
try {
|
|
116559
|
+
longPaths = await _internals62.getCoreLongPaths(directory);
|
|
116560
|
+
} catch {}
|
|
116561
|
+
if (longPaths === "true") {
|
|
116562
|
+
return { ok: true };
|
|
116563
|
+
}
|
|
116564
|
+
const proc = _internals62.bunSpawn(["git", "ls-files"], {
|
|
116565
|
+
cwd: directory,
|
|
116566
|
+
timeout: WORKTREE_TIMEOUT_MS,
|
|
116567
|
+
stdin: "ignore",
|
|
116568
|
+
stdout: "pipe",
|
|
116569
|
+
stderr: "ignore",
|
|
116570
|
+
env: { ...process.env, LC_ALL: "C" }
|
|
116571
|
+
});
|
|
116572
|
+
try {
|
|
116573
|
+
const exitCode = await proc.exited;
|
|
116574
|
+
const stdout = await proc.stdout.text();
|
|
116575
|
+
if (exitCode !== 0 || stdout.trim().length === 0) {
|
|
116576
|
+
return { ok: true };
|
|
116577
|
+
}
|
|
116578
|
+
const files = stdout.split(/\r?\n/);
|
|
116579
|
+
let longest = 0;
|
|
116580
|
+
for (const file3 of files) {
|
|
116581
|
+
if (file3.length > longest) {
|
|
116582
|
+
longest = file3.length;
|
|
116583
|
+
}
|
|
116584
|
+
}
|
|
116585
|
+
const totalPathLength = worktreeRoot.length + 1 + longest;
|
|
116586
|
+
if (totalPathLength >= WIN_PATH_BUDGET) {
|
|
116587
|
+
return {
|
|
116588
|
+
ok: false,
|
|
116589
|
+
error: `Total path budget exceeded: worktree root "${worktreeRoot}" (${worktreeRoot.length} chars) + longest file "${files.find((f) => f.length === longest)}" (${longest} chars) = ${totalPathLength} chars (budget: ${WIN_PATH_BUDGET})`,
|
|
116590
|
+
suggestion: "Set config.worktree_dir to a shorter absolute path, or let the auto-shorten feature relocate the worktree to the system temp directory."
|
|
116591
|
+
};
|
|
116592
|
+
}
|
|
116593
|
+
return { ok: true };
|
|
116594
|
+
} finally {
|
|
116595
|
+
try {
|
|
116596
|
+
proc.kill();
|
|
116597
|
+
} catch {}
|
|
116598
|
+
}
|
|
116599
|
+
}
|
|
116600
|
+
function shortenWorktreePath(_directory, sessionId, laneId) {
|
|
116601
|
+
return path137.join(_internals62.osTmpdir(), "swwt", sessionId, laneId);
|
|
116602
|
+
}
|
|
116603
|
+
async function provisionWorktree(directory, laneId, sessionId, config3) {
|
|
116604
|
+
const branchName = `swarm-lane/${sessionId}/${laneId}`;
|
|
116605
|
+
let worktreePath = config3.worktree_dir ? path137.resolve(directory, config3.worktree_dir, sessionId, laneId) : path137.resolve(path137.dirname(directory), ".swarm-worktrees", sessionId, laneId);
|
|
116606
|
+
const budgetResult = await checkPathBudget(worktreePath, directory);
|
|
116607
|
+
if (budgetResult.ok === false) {
|
|
116608
|
+
if (config3.worktree_dir) {
|
|
116609
|
+
console.warn(`[swarm] Path budget warning: ${budgetResult.error} ${budgetResult.suggestion}`);
|
|
116610
|
+
} else {
|
|
116611
|
+
const shortPath = shortenWorktreePath(directory, sessionId, laneId);
|
|
116612
|
+
const shortBudget = await checkPathBudget(shortPath, directory);
|
|
116613
|
+
if (shortBudget.ok === false) {
|
|
116614
|
+
return { error: budgetResult.error };
|
|
116615
|
+
}
|
|
116616
|
+
worktreePath = shortPath;
|
|
116617
|
+
}
|
|
116618
|
+
}
|
|
116619
|
+
const checkResult = await runGit(["show-ref", "--verify", "--quiet", `refs/heads/${branchName}`], directory);
|
|
116620
|
+
if (checkResult.exitCode === 0) {
|
|
116621
|
+
return { error: `Branch already exists: ${branchName}` };
|
|
116622
|
+
}
|
|
116623
|
+
const addResult = await runGit(["worktree", "add", "-b", branchName, worktreePath, "HEAD"], directory);
|
|
116624
|
+
if (addResult.exitCode !== 0) {
|
|
116625
|
+
return {
|
|
116626
|
+
error: `Failed to create worktree: ${addResult.stderr.trim() || addResult.stdout.trim()}`
|
|
116627
|
+
};
|
|
116628
|
+
}
|
|
116629
|
+
return { worktreePath, branchName };
|
|
116630
|
+
}
|
|
116631
|
+
async function removeWorktree(worktreePath, projectRoot) {
|
|
116632
|
+
const isWindows = _internals62.platform === "win32";
|
|
116633
|
+
const MAX_RETRIES = 4;
|
|
116634
|
+
const RETRY_DELAY_MS = 2000;
|
|
116635
|
+
let lastError = "";
|
|
116636
|
+
for (let attempt = 0;attempt < MAX_RETRIES; attempt++) {
|
|
116637
|
+
const result = await runGit(["worktree", "remove", worktreePath], projectRoot);
|
|
116638
|
+
if (result.exitCode === 0) {
|
|
116639
|
+
return { success: true };
|
|
116640
|
+
}
|
|
116641
|
+
lastError = result.stderr.trim() || result.stdout.trim();
|
|
116642
|
+
if (isWindows && (lastError.includes("EBUSY") || lastError.includes("EPERM")) && attempt < MAX_RETRIES - 1) {
|
|
116643
|
+
await _internals62.sleep(RETRY_DELAY_MS);
|
|
116644
|
+
continue;
|
|
116645
|
+
}
|
|
116646
|
+
return { error: lastError };
|
|
116647
|
+
}
|
|
116648
|
+
return { error: lastError };
|
|
116649
|
+
}
|
|
116650
|
+
async function autoCommitDirty(worktreePath) {
|
|
116651
|
+
const COMMIT_MESSAGE = "swarm-lane: auto-commit before cleanup";
|
|
116652
|
+
const addResult = await runGit(["add", "-A"], worktreePath);
|
|
116653
|
+
if (addResult.exitCode !== 0) {
|
|
116654
|
+
return {
|
|
116655
|
+
committed: false,
|
|
116656
|
+
reason: `git add failed: ${addResult.stderr.trim() || addResult.stdout.trim()}`
|
|
116657
|
+
};
|
|
116658
|
+
}
|
|
116659
|
+
const commitResult = await runGit(["commit", "-m", COMMIT_MESSAGE], worktreePath);
|
|
116660
|
+
if (commitResult.exitCode !== 0) {
|
|
116661
|
+
const stderr = commitResult.stderr.trim();
|
|
116662
|
+
const stdout = commitResult.stdout.trim();
|
|
116663
|
+
if (stderr.includes("nothing to commit") || stdout.includes("nothing to commit") || stderr.includes("nothing added to commit")) {
|
|
116664
|
+
return { committed: false, reason: "Nothing to commit" };
|
|
116665
|
+
}
|
|
116666
|
+
return {
|
|
116667
|
+
committed: false,
|
|
116668
|
+
reason: `git commit failed: ${stderr || stdout}`
|
|
116669
|
+
};
|
|
116670
|
+
}
|
|
116671
|
+
return { committed: true, message: COMMIT_MESSAGE };
|
|
116672
|
+
}
|
|
116673
|
+
var SAFE_CLEAN_PATTERNS = [
|
|
116674
|
+
"dist/",
|
|
116675
|
+
"build/",
|
|
116676
|
+
".turbo/",
|
|
116677
|
+
"coverage/",
|
|
116678
|
+
"node_modules/.cache/",
|
|
116679
|
+
".log",
|
|
116680
|
+
".tmp",
|
|
116681
|
+
".o",
|
|
116682
|
+
".pyc",
|
|
116683
|
+
".class"
|
|
116684
|
+
];
|
|
116685
|
+
function isSafeToClean(candidatePath) {
|
|
116686
|
+
const normalized = candidatePath.replace(/\\/g, "/").toLowerCase();
|
|
116687
|
+
return SAFE_CLEAN_PATTERNS.some((pattern) => {
|
|
116688
|
+
const p = pattern.toLowerCase();
|
|
116689
|
+
if (p.endsWith("/")) {
|
|
116690
|
+
return normalized.startsWith(p) || normalized.includes("/" + p);
|
|
116691
|
+
}
|
|
116692
|
+
return normalized.endsWith(p);
|
|
116693
|
+
});
|
|
116694
|
+
}
|
|
116695
|
+
async function cleanUntrackedFiles(worktreePath) {
|
|
116696
|
+
const dryRun = await runGit(["clean", "-fdn"], worktreePath);
|
|
116697
|
+
if (dryRun.exitCode === 0) {
|
|
116698
|
+
const candidates = dryRun.stdout.trim().split(`
|
|
116699
|
+
`).map((line) => {
|
|
116700
|
+
const match = line.match(/^Would remove (.+)$/);
|
|
116701
|
+
return match ? match[1].trim() : "";
|
|
116702
|
+
}).filter((p) => p.length > 0);
|
|
116703
|
+
const unsafePaths = candidates.filter((p) => !isSafeToClean(p));
|
|
116704
|
+
if (unsafePaths.length > 0) {
|
|
116705
|
+
console.warn(`[swarm:cleanUntrackedFiles] Skipping clean — untracked source files detected: ${unsafePaths.join(", ")}`);
|
|
116706
|
+
return {
|
|
116707
|
+
cleaned: false,
|
|
116708
|
+
error: "untracked source files detected — skipping clean to prevent data loss"
|
|
116709
|
+
};
|
|
116710
|
+
}
|
|
116711
|
+
}
|
|
116712
|
+
const result = await runGit(["clean", "-fd"], worktreePath);
|
|
116713
|
+
if (result.exitCode !== 0) {
|
|
116714
|
+
return {
|
|
116715
|
+
cleaned: false,
|
|
116716
|
+
error: result.stderr.trim() || result.stdout.trim()
|
|
116717
|
+
};
|
|
116718
|
+
}
|
|
116719
|
+
return { cleaned: true };
|
|
116720
|
+
}
|
|
116721
|
+
async function assertCleanWorkingTree(directory) {
|
|
116722
|
+
const [statusResult, untrackedResult] = await Promise.all([
|
|
116723
|
+
runGit(["status", "--porcelain"], directory),
|
|
116724
|
+
runGit(["ls-files", "--others", "--exclude-standard"], directory)
|
|
116725
|
+
]);
|
|
116726
|
+
if (statusResult.exitCode !== 0) {
|
|
116727
|
+
return {
|
|
116728
|
+
clean: false,
|
|
116729
|
+
error: `Unable to verify working tree cleanliness: ${statusResult.stderr.trim() || statusResult.stdout.trim()}`
|
|
116730
|
+
};
|
|
116731
|
+
}
|
|
116732
|
+
if (untrackedResult.exitCode !== 0) {
|
|
116733
|
+
return {
|
|
116734
|
+
clean: false,
|
|
116735
|
+
error: `Unable to verify working tree cleanliness: ${untrackedResult.stderr.trim() || untrackedResult.stdout.trim()}`
|
|
116736
|
+
};
|
|
116737
|
+
}
|
|
116738
|
+
const hasChanges = statusResult.stdout.trim().length > 0;
|
|
116739
|
+
const hasUntracked = untrackedResult.stdout.trim().length > 0;
|
|
116740
|
+
if (hasChanges || hasUntracked) {
|
|
116741
|
+
return {
|
|
116742
|
+
clean: false,
|
|
116743
|
+
error: "Working tree has uncommitted changes. Please commit or stash before provisioning worktrees. Run 'git status' for details."
|
|
116744
|
+
};
|
|
116745
|
+
}
|
|
116746
|
+
return { clean: true };
|
|
116747
|
+
}
|
|
116748
|
+
|
|
116749
|
+
// src/turbo/lean/merge-back.ts
|
|
116750
|
+
var _internals63 = {
|
|
116751
|
+
bunSpawn,
|
|
116752
|
+
platform: process.platform,
|
|
116753
|
+
sleep: (ms) => new Promise((resolve50) => setTimeout(resolve50, ms))
|
|
116754
|
+
};
|
|
116755
|
+
var MERGE_TIMEOUT_MS = 30000;
|
|
116756
|
+
async function runGit2(args2, cwd, timeoutMs = MERGE_TIMEOUT_MS) {
|
|
116757
|
+
const proc = _internals63.bunSpawn(["git", ...args2], {
|
|
116758
|
+
cwd,
|
|
116759
|
+
timeout: timeoutMs,
|
|
116760
|
+
stdin: "ignore",
|
|
116761
|
+
stdout: "pipe",
|
|
116762
|
+
stderr: "pipe",
|
|
116763
|
+
env: { ...process.env, LC_ALL: "C" }
|
|
116764
|
+
});
|
|
116765
|
+
try {
|
|
116766
|
+
const exitCode = await proc.exited;
|
|
116767
|
+
const stdout = await proc.stdout.text();
|
|
116768
|
+
const stderr = await proc.stderr.text();
|
|
116769
|
+
return { exitCode, stdout, stderr };
|
|
116770
|
+
} finally {
|
|
116771
|
+
try {
|
|
116772
|
+
proc.kill();
|
|
116773
|
+
} catch {}
|
|
116774
|
+
}
|
|
116775
|
+
}
|
|
116776
|
+
function parseConflictFiles(output) {
|
|
116777
|
+
const files = [];
|
|
116778
|
+
const lines = output.split(`
|
|
116779
|
+
`);
|
|
116780
|
+
for (const line of lines) {
|
|
116781
|
+
const match = line.match(/CONFLICT\b.*(?:Merge conflict in |in )(.+)/);
|
|
116782
|
+
if (match?.[1]) {
|
|
116783
|
+
files.push(match[1].trim());
|
|
116784
|
+
}
|
|
116785
|
+
}
|
|
116786
|
+
return files;
|
|
116787
|
+
}
|
|
116788
|
+
function getMergeStrategy(config3) {
|
|
116789
|
+
return config3.merge_strategy ?? "merge";
|
|
116790
|
+
}
|
|
116791
|
+
async function mergeLaneBranch(primaryDir, branchName, strategy) {
|
|
116792
|
+
let result;
|
|
116793
|
+
switch (strategy) {
|
|
116794
|
+
case "merge":
|
|
116795
|
+
result = await runGit2(["merge", "--no-edit", branchName], primaryDir);
|
|
116796
|
+
break;
|
|
116797
|
+
case "rebase":
|
|
116798
|
+
result = await runGit2(["rebase", branchName], primaryDir);
|
|
116799
|
+
break;
|
|
116800
|
+
case "cherry-pick": {
|
|
116801
|
+
const mergeBaseResult = await runGit2(["merge-base", "HEAD", branchName], primaryDir);
|
|
116802
|
+
if (mergeBaseResult.exitCode === 0 && mergeBaseResult.stdout.trim()) {
|
|
116803
|
+
const mergeBase = mergeBaseResult.stdout.trim();
|
|
116804
|
+
result = await runGit2(["cherry-pick", `${mergeBase}..${branchName}`], primaryDir);
|
|
116805
|
+
} else {
|
|
116806
|
+
console.warn("[lean-turbo] mergeLaneBranch: git merge-base failed for cherry-pick; falling back to tip-only cherry-pick");
|
|
116807
|
+
result = await runGit2(["cherry-pick", branchName], primaryDir);
|
|
116808
|
+
}
|
|
116809
|
+
break;
|
|
116810
|
+
}
|
|
116811
|
+
}
|
|
116812
|
+
if (result.exitCode === 0) {
|
|
116813
|
+
return { merged: true, strategy };
|
|
116814
|
+
}
|
|
116815
|
+
const combinedOutput = `${result.stderr}
|
|
116816
|
+
${result.stdout}`;
|
|
116817
|
+
const hasConflict = /CONFLICT/i.test(combinedOutput) || /conflict/i.test(combinedOutput);
|
|
116818
|
+
if (hasConflict) {
|
|
116819
|
+
const files = parseConflictFiles(combinedOutput);
|
|
116820
|
+
const abortArgs = strategy === "rebase" ? ["rebase", "--abort"] : strategy === "cherry-pick" ? ["cherry-pick", "--abort"] : ["merge", "--abort"];
|
|
116821
|
+
await runGit2(abortArgs, primaryDir);
|
|
116822
|
+
return {
|
|
116823
|
+
conflict: true,
|
|
116824
|
+
files,
|
|
116825
|
+
message: result.stderr.trim()
|
|
116826
|
+
};
|
|
116827
|
+
}
|
|
116828
|
+
return {
|
|
116829
|
+
error: result.stderr.trim() || result.stdout.trim()
|
|
116830
|
+
};
|
|
116831
|
+
}
|
|
116832
|
+
async function postMergeCleanup(directory, branchName) {
|
|
116833
|
+
const deleteResult = await runGit2(["branch", "-D", branchName], directory);
|
|
116834
|
+
const deleteOk = deleteResult.exitCode === 0;
|
|
116835
|
+
const pruneResult = await runGit2(["worktree", "prune"], directory);
|
|
116836
|
+
const pruneOk = pruneResult.exitCode === 0;
|
|
116837
|
+
if (deleteOk && pruneOk) {
|
|
116838
|
+
return { cleaned: true };
|
|
116839
|
+
}
|
|
116840
|
+
if (!deleteOk && pruneOk) {
|
|
116841
|
+
return {
|
|
116842
|
+
error: `Branch delete failed: ${deleteResult.stderr.trim() || deleteResult.stdout.trim()}`,
|
|
116843
|
+
partial: true
|
|
116844
|
+
};
|
|
116845
|
+
}
|
|
116846
|
+
return {
|
|
116847
|
+
error: deleteOk ? `Worktree prune failed: ${pruneResult.stderr.trim() || pruneResult.stdout.trim()}` : `Branch delete failed: ${deleteResult.stderr.trim() || deleteResult.stdout.trim()}; worktree prune failed: ${pruneResult.stderr.trim() || pruneResult.stdout.trim()}`
|
|
116848
|
+
};
|
|
116849
|
+
}
|
|
116850
|
+
async function attemptMergeBackFromDirty(worktreePath, branchName, primaryDir, strategy) {
|
|
116851
|
+
let autoCommitted = false;
|
|
116852
|
+
let cleaned = false;
|
|
116853
|
+
let autoCommitFailed = false;
|
|
116854
|
+
let cleanFailed = false;
|
|
116855
|
+
const commitResult = await autoCommitDirty(worktreePath);
|
|
116856
|
+
if (commitResult.committed) {
|
|
116857
|
+
autoCommitted = true;
|
|
116858
|
+
} else if (commitResult.reason !== "Nothing to commit") {
|
|
116859
|
+
autoCommitFailed = true;
|
|
116860
|
+
console.warn(`[lean-turbo] attemptMergeBackFromDirty: auto-commit failed for worktree "${worktreePath}" branch "${branchName}": ${commitResult.reason}`);
|
|
116861
|
+
}
|
|
116862
|
+
const cleanResult = await cleanUntrackedFiles(worktreePath);
|
|
116863
|
+
if (cleanResult.cleaned) {
|
|
116864
|
+
cleaned = true;
|
|
116865
|
+
} else {
|
|
116866
|
+
cleanFailed = true;
|
|
116867
|
+
console.warn(`[lean-turbo] attemptMergeBackFromDirty: clean untracked failed for worktree "${worktreePath}" branch "${branchName}": ${cleanResult.error}`);
|
|
116868
|
+
}
|
|
116869
|
+
if (autoCommitFailed && cleanFailed) {
|
|
116870
|
+
return {
|
|
116871
|
+
failed: true,
|
|
116872
|
+
stage: "cleanup",
|
|
116873
|
+
message: "Auto-commit and clean both failed; abandoning worktree"
|
|
116874
|
+
};
|
|
116875
|
+
}
|
|
116876
|
+
const mergeResult = await mergeLaneBranch(primaryDir, branchName, strategy);
|
|
116877
|
+
if ("merged" in mergeResult && mergeResult.merged) {
|
|
116878
|
+
return { merged: true, strategy, autoCommitted, cleaned };
|
|
116879
|
+
}
|
|
116880
|
+
if ("conflict" in mergeResult) {
|
|
116881
|
+
return {
|
|
116882
|
+
partial: true,
|
|
116883
|
+
stage: "merge",
|
|
116884
|
+
autoCommitted,
|
|
116885
|
+
cleaned,
|
|
116886
|
+
message: mergeResult.message
|
|
116887
|
+
};
|
|
116888
|
+
}
|
|
116889
|
+
if ("error" in mergeResult) {
|
|
116890
|
+
return {
|
|
116891
|
+
failed: true,
|
|
116892
|
+
stage: "merge",
|
|
116893
|
+
message: mergeResult.error
|
|
116894
|
+
};
|
|
116895
|
+
}
|
|
116896
|
+
return {
|
|
116897
|
+
failed: true,
|
|
116898
|
+
stage: "merge",
|
|
116899
|
+
message: "Merge failed with unexpected result"
|
|
116900
|
+
};
|
|
116901
|
+
}
|
|
116902
|
+
function extractSessionId(branchName) {
|
|
116903
|
+
const segments = branchName.trim().split("/");
|
|
116904
|
+
if (segments.length >= 3 && segments[0] === "swarm-lane") {
|
|
116905
|
+
return segments[1];
|
|
116906
|
+
}
|
|
116907
|
+
return null;
|
|
116908
|
+
}
|
|
116909
|
+
async function startupOrphanRecovery(directory, activeSessionIds = []) {
|
|
116910
|
+
const warnings = [];
|
|
116911
|
+
const pruneResult = await runGit2(["worktree", "prune"], directory);
|
|
116912
|
+
if (pruneResult.exitCode !== 0) {
|
|
116913
|
+
warnings.push(`git worktree prune failed: ${pruneResult.stderr.trim() || pruneResult.stdout.trim()}`);
|
|
116914
|
+
}
|
|
116915
|
+
const listResult = await runGit2(["branch", "--format=%(refname:short)", "--list", "swarm-lane/*"], directory);
|
|
116916
|
+
const allBranches = listResult.stdout.split(`
|
|
116917
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
116918
|
+
const orphanBranches = [];
|
|
116919
|
+
for (const branch of allBranches) {
|
|
116920
|
+
const sessionId = extractSessionId(branch);
|
|
116921
|
+
if (sessionId === null || !activeSessionIds.includes(sessionId)) {
|
|
116922
|
+
orphanBranches.push(branch);
|
|
116923
|
+
warnings.push(`Orphaned swarm-lane branch "${branch}" detected in "${directory}"`);
|
|
116924
|
+
}
|
|
116925
|
+
}
|
|
116926
|
+
for (const warning of warnings) {
|
|
116927
|
+
console.warn(warning);
|
|
116928
|
+
}
|
|
116929
|
+
return {
|
|
116930
|
+
prunedWorktrees: pruneResult.exitCode === 0,
|
|
116931
|
+
remainingBranches: orphanBranches,
|
|
116932
|
+
warnings
|
|
116933
|
+
};
|
|
116934
|
+
}
|
|
116935
|
+
|
|
116936
|
+
// src/turbo/lean/runner.ts
|
|
116506
116937
|
init_state3();
|
|
116938
|
+
function isTransientProvisionError(errorMsg) {
|
|
116939
|
+
const lower = errorMsg.toLowerCase();
|
|
116940
|
+
if (lower.includes("already exists") || lower.includes("not a git repository")) {
|
|
116941
|
+
return false;
|
|
116942
|
+
}
|
|
116943
|
+
const transientCodes = [
|
|
116944
|
+
"enoent",
|
|
116945
|
+
"econnrefused",
|
|
116946
|
+
"etimedout",
|
|
116947
|
+
"ebusy",
|
|
116948
|
+
"eperm",
|
|
116949
|
+
"enomem"
|
|
116950
|
+
];
|
|
116951
|
+
for (const code of transientCodes) {
|
|
116952
|
+
if (lower.includes(code)) {
|
|
116953
|
+
return true;
|
|
116954
|
+
}
|
|
116955
|
+
}
|
|
116956
|
+
const transientMessages = [
|
|
116957
|
+
"disk full",
|
|
116958
|
+
"no space left",
|
|
116959
|
+
"resource temporarily unavailable"
|
|
116960
|
+
];
|
|
116961
|
+
for (const msg of transientMessages) {
|
|
116962
|
+
if (lower.includes(msg)) {
|
|
116963
|
+
return true;
|
|
116964
|
+
}
|
|
116965
|
+
}
|
|
116966
|
+
if (lower.includes("fatal:")) {
|
|
116967
|
+
return true;
|
|
116968
|
+
}
|
|
116969
|
+
return false;
|
|
116970
|
+
}
|
|
116507
116971
|
|
|
116508
116972
|
class LeanTurboRunner {
|
|
116509
116973
|
static _internals = {
|
|
@@ -116516,7 +116980,15 @@ class LeanTurboRunner {
|
|
|
116516
116980
|
hasActiveFullAuto,
|
|
116517
116981
|
loadFullAutoRunState,
|
|
116518
116982
|
writeLaneEvidence,
|
|
116519
|
-
laneDispatchTimeoutMs: undefined
|
|
116983
|
+
laneDispatchTimeoutMs: undefined,
|
|
116984
|
+
provisionWorktree,
|
|
116985
|
+
removeWorktree,
|
|
116986
|
+
mergeLaneBranch,
|
|
116987
|
+
postMergeCleanup,
|
|
116988
|
+
attemptMergeBackFromDirty,
|
|
116989
|
+
startupOrphanRecovery,
|
|
116990
|
+
getMergeStrategy,
|
|
116991
|
+
assertCleanWorkingTree
|
|
116520
116992
|
};
|
|
116521
116993
|
_sessionOps = null;
|
|
116522
116994
|
_directory;
|
|
@@ -116575,6 +117047,22 @@ class LeanTurboRunner {
|
|
|
116575
117047
|
}
|
|
116576
117048
|
}
|
|
116577
117049
|
const leanConfig = this._getLeanConfig(this._leanConfig);
|
|
117050
|
+
if (leanConfig.worktree_isolation) {
|
|
117051
|
+
await LeanTurboRunner._internals.startupOrphanRecovery(this._directory, [
|
|
117052
|
+
this._sessionID
|
|
117053
|
+
]);
|
|
117054
|
+
try {
|
|
117055
|
+
const cleanResult = await LeanTurboRunner._internals.assertCleanWorkingTree(this._directory);
|
|
117056
|
+
if (!cleanResult.clean) {
|
|
117057
|
+
console.warn(`[lean-turbo] worktree isolation requires clean working tree: ${cleanResult.error}`);
|
|
117058
|
+
leanConfig.worktree_isolation = false;
|
|
117059
|
+
}
|
|
117060
|
+
} catch (assertErr) {
|
|
117061
|
+
const assertMsg = assertErr instanceof Error ? assertErr.message : String(assertErr);
|
|
117062
|
+
console.warn(`[lean-turbo] unable to verify working tree cleanliness: ${assertMsg} — degrading to shared directory`);
|
|
117063
|
+
leanConfig.worktree_isolation = false;
|
|
117064
|
+
}
|
|
117065
|
+
}
|
|
116578
117066
|
const lanePlan = LeanTurboRunner._internals.planLeanTurboLanes(this._directory, phaseNumber, { phases: plan.phases }, leanConfig);
|
|
116579
117067
|
const degradedTasks = lanePlan.degradedTasks.map((d) => d.taskId);
|
|
116580
117068
|
if (lanePlan.lanes.length === 0 && degradedTasks.length === 0 && lanePlan.serializedTasks.length === 0) {
|
|
@@ -116598,21 +117086,23 @@ class LeanTurboRunner {
|
|
|
116598
117086
|
await this._withStateLock(() => this._updateDurableState(lanePlan));
|
|
116599
117087
|
this._laneStatuses = new Map(lanePlan.lanes.map((lane) => [lane.laneId, { ...lane }]));
|
|
116600
117088
|
const laneResults = [];
|
|
116601
|
-
const results = await Promise.all(lanePlan.lanes.map((lane) => this._processLane(lane)));
|
|
117089
|
+
const results = await Promise.all(lanePlan.lanes.map((lane) => this._processLane(lane, leanConfig)));
|
|
116602
117090
|
laneResults.push(...results);
|
|
117091
|
+
const mergeBackFailures = await this._sequentialWorktreeCleanup(laneResults, leanConfig);
|
|
116603
117092
|
return {
|
|
116604
117093
|
ok: true,
|
|
116605
117094
|
lanes: laneResults,
|
|
116606
117095
|
degradedTasks,
|
|
116607
|
-
serializedTasks: lanePlan.serializedTasks
|
|
117096
|
+
serializedTasks: lanePlan.serializedTasks,
|
|
117097
|
+
mergeBackFailures: mergeBackFailures.length > 0 ? mergeBackFailures : undefined
|
|
116608
117098
|
};
|
|
116609
117099
|
}
|
|
116610
|
-
async dispatchLane(lane, agentName) {
|
|
117100
|
+
async dispatchLane(lane, agentName, worktreeDirectory) {
|
|
116611
117101
|
const session = this._sessionOps ?? this._client?.session;
|
|
116612
117102
|
if (!session) {
|
|
116613
117103
|
return { ok: false, error: "NO_CLIENT" };
|
|
116614
117104
|
}
|
|
116615
|
-
const dispatchPromise = this._doDispatch(session, lane, agentName);
|
|
117105
|
+
const dispatchPromise = this._doDispatch(session, lane, agentName, worktreeDirectory);
|
|
116616
117106
|
const timeoutMs = LeanTurboRunner._internals.laneDispatchTimeoutMs;
|
|
116617
117107
|
if (timeoutMs !== undefined && timeoutMs > 0) {
|
|
116618
117108
|
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error(`Lane dispatch timed out after ${timeoutMs}ms`)), timeoutMs));
|
|
@@ -116643,10 +117133,11 @@ class LeanTurboRunner {
|
|
|
116643
117133
|
}
|
|
116644
117134
|
return dispatchPromise;
|
|
116645
117135
|
}
|
|
116646
|
-
async _doDispatch(session, lane, agentName) {
|
|
117136
|
+
async _doDispatch(session, lane, agentName, worktreeDirectory) {
|
|
116647
117137
|
try {
|
|
117138
|
+
const effectiveDirectory = worktreeDirectory ?? this._directory;
|
|
116648
117139
|
const createResult = await session.create({
|
|
116649
|
-
query: { directory:
|
|
117140
|
+
query: { directory: effectiveDirectory }
|
|
116650
117141
|
});
|
|
116651
117142
|
if (!createResult.data) {
|
|
116652
117143
|
return {
|
|
@@ -116698,6 +117189,13 @@ class LeanTurboRunner {
|
|
|
116698
117189
|
} catch {}
|
|
116699
117190
|
}
|
|
116700
117191
|
this._laneLockMap = {};
|
|
117192
|
+
for (const [_laneId, lane] of this._laneStatuses) {
|
|
117193
|
+
if (lane.worktreePath) {
|
|
117194
|
+
try {
|
|
117195
|
+
await LeanTurboRunner._internals.removeWorktree(lane.worktreePath, this._directory);
|
|
117196
|
+
} catch {}
|
|
117197
|
+
}
|
|
117198
|
+
}
|
|
116701
117199
|
await this._withStateLock(async () => {
|
|
116702
117200
|
const runState = LeanTurboRunner._internals.loadLeanTurboRunState(this._directory, this._sessionID);
|
|
116703
117201
|
if (runState) {
|
|
@@ -116745,7 +117243,7 @@ class LeanTurboRunner {
|
|
|
116745
117243
|
}
|
|
116746
117244
|
return defaults;
|
|
116747
117245
|
}
|
|
116748
|
-
async _processLane(lane) {
|
|
117246
|
+
async _processLane(lane, leanConfig) {
|
|
116749
117247
|
const laneInState = this._laneStatuses.get(lane.laneId);
|
|
116750
117248
|
if (laneInState) {
|
|
116751
117249
|
laneInState.status = "running";
|
|
@@ -116782,12 +117280,85 @@ class LeanTurboRunner {
|
|
|
116782
117280
|
};
|
|
116783
117281
|
}
|
|
116784
117282
|
this._laneLockMap[lane.laneId] = [...lane.files];
|
|
116785
|
-
|
|
117283
|
+
let worktreeDirectory;
|
|
117284
|
+
if (leanConfig.worktree_isolation) {
|
|
117285
|
+
let provisionError;
|
|
117286
|
+
try {
|
|
117287
|
+
const provisionResult = await LeanTurboRunner._internals.provisionWorktree(this._directory, lane.laneId, this._sessionID, leanConfig);
|
|
117288
|
+
if ("worktreePath" in provisionResult) {
|
|
117289
|
+
worktreeDirectory = provisionResult.worktreePath;
|
|
117290
|
+
if (laneInState) {
|
|
117291
|
+
laneInState.worktreePath = provisionResult.worktreePath;
|
|
117292
|
+
laneInState.branchName = provisionResult.branchName;
|
|
117293
|
+
}
|
|
117294
|
+
await this._persistLaneWorktreeFields(lane.laneId, provisionResult.worktreePath, provisionResult.branchName);
|
|
117295
|
+
} else {
|
|
117296
|
+
provisionError = provisionResult.error;
|
|
117297
|
+
}
|
|
117298
|
+
} catch (provisionErr) {
|
|
117299
|
+
provisionError = provisionErr instanceof Error ? provisionErr.message : String(provisionErr);
|
|
117300
|
+
}
|
|
117301
|
+
if (provisionError) {
|
|
117302
|
+
if (isTransientProvisionError(provisionError)) {
|
|
117303
|
+
console.warn(`[lean-turbo] worktree provision failed for lane ${lane.laneId}: ${provisionError} — retrying once...`);
|
|
117304
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
117305
|
+
try {
|
|
117306
|
+
const retryResult = await LeanTurboRunner._internals.provisionWorktree(this._directory, lane.laneId, this._sessionID, leanConfig);
|
|
117307
|
+
if ("worktreePath" in retryResult) {
|
|
117308
|
+
worktreeDirectory = retryResult.worktreePath;
|
|
117309
|
+
if (laneInState) {
|
|
117310
|
+
laneInState.worktreePath = retryResult.worktreePath;
|
|
117311
|
+
laneInState.branchName = retryResult.branchName;
|
|
117312
|
+
}
|
|
117313
|
+
await this._persistLaneWorktreeFields(lane.laneId, retryResult.worktreePath, retryResult.branchName);
|
|
117314
|
+
console.warn(`[lean-turbo] worktree provision retry succeeded for lane ${lane.laneId}`);
|
|
117315
|
+
provisionError = undefined;
|
|
117316
|
+
} else {
|
|
117317
|
+
provisionError = retryResult.error;
|
|
117318
|
+
console.warn(`[lean-turbo] worktree provision retry failed for lane ${lane.laneId}: ${retryResult.error}`);
|
|
117319
|
+
}
|
|
117320
|
+
} catch (retryErr) {
|
|
117321
|
+
const retryMsg = retryErr instanceof Error ? retryErr.message : String(retryErr);
|
|
117322
|
+
console.warn(`[lean-turbo] worktree provision retry threw for lane ${lane.laneId}: ${retryMsg}`);
|
|
117323
|
+
}
|
|
117324
|
+
} else {
|
|
117325
|
+
console.warn(`[lean-turbo] worktree provision failed for lane ${lane.laneId}: ${provisionError}`);
|
|
117326
|
+
}
|
|
117327
|
+
}
|
|
117328
|
+
if (!worktreeDirectory) {
|
|
117329
|
+
const failMsg = `worktree provision failed: ${provisionError ?? "unknown error"}`;
|
|
117330
|
+
try {
|
|
117331
|
+
await LeanTurboRunner._internals.releaseLaneLocks(this._directory, lane.laneId);
|
|
117332
|
+
} catch {}
|
|
117333
|
+
delete this._laneLockMap[lane.laneId];
|
|
117334
|
+
if (laneInState) {
|
|
117335
|
+
laneInState.status = "failed";
|
|
117336
|
+
laneInState.error = failMsg;
|
|
117337
|
+
}
|
|
117338
|
+
await this._updateDurableStateLaneStatus(lane.laneId, "failed");
|
|
117339
|
+
await this._writeLaneEvidenceSafely(lane, "failed", {
|
|
117340
|
+
status: "failed",
|
|
117341
|
+
error: failMsg,
|
|
117342
|
+
agent
|
|
117343
|
+
});
|
|
117344
|
+
return {
|
|
117345
|
+
laneId: lane.laneId,
|
|
117346
|
+
status: "failed",
|
|
117347
|
+
taskIds: lane.taskIds,
|
|
117348
|
+
agent,
|
|
117349
|
+
error: failMsg
|
|
117350
|
+
};
|
|
117351
|
+
}
|
|
117352
|
+
}
|
|
117353
|
+
const dispatchResult = await this.dispatchLane(lane, agent, worktreeDirectory);
|
|
116786
117354
|
if (!dispatchResult.ok) {
|
|
116787
117355
|
try {
|
|
116788
117356
|
await LeanTurboRunner._internals.releaseLaneLocks(this._directory, lane.laneId);
|
|
116789
117357
|
} catch {}
|
|
116790
117358
|
delete this._laneLockMap[lane.laneId];
|
|
117359
|
+
if (worktreeDirectory && laneInState) {
|
|
117360
|
+
laneInState._failureCleanupPending = true;
|
|
117361
|
+
}
|
|
116791
117362
|
if (laneInState) {
|
|
116792
117363
|
laneInState.status = "failed";
|
|
116793
117364
|
laneInState.error = dispatchResult.error;
|
|
@@ -116832,6 +117403,69 @@ class LeanTurboRunner {
|
|
|
116832
117403
|
sessionId: dispatchResult.sessionId
|
|
116833
117404
|
};
|
|
116834
117405
|
}
|
|
117406
|
+
async _sequentialWorktreeCleanup(laneResults, leanConfig) {
|
|
117407
|
+
const mergeBackFailures = [];
|
|
117408
|
+
for (const lr of laneResults) {
|
|
117409
|
+
const laneInState = this._laneStatuses.get(lr.laneId);
|
|
117410
|
+
if (!laneInState?.worktreePath)
|
|
117411
|
+
continue;
|
|
117412
|
+
let needsPostMergeCleanup = false;
|
|
117413
|
+
if (lr.status === "completed") {
|
|
117414
|
+
if (!laneInState.branchName)
|
|
117415
|
+
continue;
|
|
117416
|
+
try {
|
|
117417
|
+
const strategy = LeanTurboRunner._internals.getMergeStrategy(leanConfig);
|
|
117418
|
+
const mergeResult = await LeanTurboRunner._internals.mergeLaneBranch(this._directory, laneInState.branchName, strategy);
|
|
117419
|
+
if ("merged" in mergeResult && mergeResult.merged) {
|
|
117420
|
+
needsPostMergeCleanup = true;
|
|
117421
|
+
} else if ("conflict" in mergeResult && mergeResult.conflict) {
|
|
117422
|
+
const failureInfo = {
|
|
117423
|
+
laneId: lr.laneId,
|
|
117424
|
+
reason: mergeResult.message || "merge conflict",
|
|
117425
|
+
conflictFiles: mergeResult.files
|
|
117426
|
+
};
|
|
117427
|
+
mergeBackFailures.push(failureInfo);
|
|
117428
|
+
lr.mergeBackFailure = failureInfo;
|
|
117429
|
+
console.warn(`[lean-turbo] merge-back CONFLICT for lane ${lr.laneId}: ${failureInfo.reason} — worktree preserved at ${laneInState.worktreePath} for manual recovery`);
|
|
117430
|
+
continue;
|
|
117431
|
+
} else if ("error" in mergeResult && mergeResult.error) {
|
|
117432
|
+
const failureInfo = {
|
|
117433
|
+
laneId: lr.laneId,
|
|
117434
|
+
reason: mergeResult.error
|
|
117435
|
+
};
|
|
117436
|
+
mergeBackFailures.push(failureInfo);
|
|
117437
|
+
lr.mergeBackFailure = failureInfo;
|
|
117438
|
+
console.warn(`[lean-turbo] merge-back ERROR for lane ${lr.laneId}: ${failureInfo.reason} — worktree preserved at ${laneInState.worktreePath} for manual recovery`);
|
|
117439
|
+
continue;
|
|
117440
|
+
}
|
|
117441
|
+
} catch (err2) {
|
|
117442
|
+
const errMsg = err2 instanceof Error ? err2.message : String(err2);
|
|
117443
|
+
const failureInfo = {
|
|
117444
|
+
laneId: lr.laneId,
|
|
117445
|
+
reason: errMsg
|
|
117446
|
+
};
|
|
117447
|
+
mergeBackFailures.push(failureInfo);
|
|
117448
|
+
lr.mergeBackFailure = failureInfo;
|
|
117449
|
+
console.warn(`[lean-turbo] merge-back EXCEPTION for lane ${lr.laneId}: ${errMsg} — worktree preserved at ${laneInState.worktreePath} for manual recovery`);
|
|
117450
|
+
continue;
|
|
117451
|
+
}
|
|
117452
|
+
} else if (lr.status === "failed" && laneInState._failureCleanupPending) {
|
|
117453
|
+
try {
|
|
117454
|
+
const strategy = LeanTurboRunner._internals.getMergeStrategy(leanConfig);
|
|
117455
|
+
await LeanTurboRunner._internals.attemptMergeBackFromDirty(laneInState.worktreePath, laneInState.branchName ?? `swarm-lane/${this._sessionID}/${lr.laneId}`, this._directory, strategy);
|
|
117456
|
+
} catch {}
|
|
117457
|
+
}
|
|
117458
|
+
try {
|
|
117459
|
+
await LeanTurboRunner._internals.removeWorktree(laneInState.worktreePath, this._directory);
|
|
117460
|
+
} catch {}
|
|
117461
|
+
if (needsPostMergeCleanup && laneInState.branchName) {
|
|
117462
|
+
try {
|
|
117463
|
+
await LeanTurboRunner._internals.postMergeCleanup(this._directory, laneInState.branchName);
|
|
117464
|
+
} catch {}
|
|
117465
|
+
}
|
|
117466
|
+
}
|
|
117467
|
+
return mergeBackFailures;
|
|
117468
|
+
}
|
|
116835
117469
|
_selectNextAgent() {
|
|
116836
117470
|
if (this._availableAgents.length === 0) {
|
|
116837
117471
|
return "coder";
|
|
@@ -116925,6 +117559,21 @@ ${fileList}
|
|
|
116925
117559
|
LeanTurboRunner._internals.saveLeanTurboRunState(this._directory, runState);
|
|
116926
117560
|
} catch {}
|
|
116927
117561
|
}
|
|
117562
|
+
async _persistLaneWorktreeFields(laneId, worktreePath, branchName) {
|
|
117563
|
+
await this._withStateLock(async () => {
|
|
117564
|
+
try {
|
|
117565
|
+
const runState = LeanTurboRunner._internals.loadLeanTurboRunState(this._directory, this._sessionID);
|
|
117566
|
+
if (!runState)
|
|
117567
|
+
return;
|
|
117568
|
+
const lane = runState.lanes.find((l) => l.laneId === laneId);
|
|
117569
|
+
if (lane) {
|
|
117570
|
+
lane.worktreePath = worktreePath;
|
|
117571
|
+
lane.branchName = branchName;
|
|
117572
|
+
LeanTurboRunner._internals.saveLeanTurboRunState(this._directory, runState);
|
|
117573
|
+
}
|
|
117574
|
+
} catch {}
|
|
117575
|
+
});
|
|
117576
|
+
}
|
|
116928
117577
|
async _updateDurableStateLaneStatus(laneId, status) {
|
|
116929
117578
|
await this._withStateLock(async () => {
|
|
116930
117579
|
try {
|
|
@@ -116950,7 +117599,7 @@ ${fileList}
|
|
|
116950
117599
|
|
|
116951
117600
|
// src/tools/lean-turbo-run-phase.ts
|
|
116952
117601
|
init_create_tool();
|
|
116953
|
-
var
|
|
117602
|
+
var _internals64 = {
|
|
116954
117603
|
LeanTurboRunner,
|
|
116955
117604
|
loadPluginConfigWithMeta
|
|
116956
117605
|
};
|
|
@@ -116960,9 +117609,9 @@ async function executeLeanTurboRunPhase(args2) {
|
|
|
116960
117609
|
let runError = null;
|
|
116961
117610
|
let runner = null;
|
|
116962
117611
|
try {
|
|
116963
|
-
const { config: config3 } =
|
|
117612
|
+
const { config: config3 } = _internals64.loadPluginConfigWithMeta(directory);
|
|
116964
117613
|
const leanConfig = config3.turbo?.strategy === "lean" ? config3.turbo.lean : undefined;
|
|
116965
|
-
runner = new
|
|
117614
|
+
runner = new _internals64.LeanTurboRunner({
|
|
116966
117615
|
directory,
|
|
116967
117616
|
sessionID,
|
|
116968
117617
|
opencodeClient: swarmState.opencodeClient ?? null,
|
|
@@ -116995,6 +117644,7 @@ async function executeLeanTurboRunPhase(args2) {
|
|
|
116995
117644
|
lanes: runResult.lanes,
|
|
116996
117645
|
degradedTasks: runResult.degradedTasks,
|
|
116997
117646
|
serializedTasks: runResult.serializedTasks,
|
|
117647
|
+
mergeBackFailures: runResult.mergeBackFailures,
|
|
116998
117648
|
reason: runResult.reason
|
|
116999
117649
|
};
|
|
117000
117650
|
}
|
|
@@ -117121,7 +117771,7 @@ init_lint();
|
|
|
117121
117771
|
init_spec_schema();
|
|
117122
117772
|
init_create_tool();
|
|
117123
117773
|
import * as fs99 from "node:fs";
|
|
117124
|
-
import * as
|
|
117774
|
+
import * as path138 from "node:path";
|
|
117125
117775
|
var SPEC_FILE_NAME = "spec.md";
|
|
117126
117776
|
var SWARM_DIR2 = ".swarm";
|
|
117127
117777
|
var OBLIGATION_KEYWORDS = ["MUST", "SHALL", "SHOULD", "MAY"];
|
|
@@ -117174,7 +117824,7 @@ var lint_spec = createSwarmTool({
|
|
|
117174
117824
|
async execute(_args, directory) {
|
|
117175
117825
|
const errors5 = [];
|
|
117176
117826
|
const warnings = [];
|
|
117177
|
-
const specPath =
|
|
117827
|
+
const specPath = path138.join(directory, SWARM_DIR2, SPEC_FILE_NAME);
|
|
117178
117828
|
if (!fs99.existsSync(specPath)) {
|
|
117179
117829
|
const result2 = {
|
|
117180
117830
|
valid: false,
|
|
@@ -117246,12 +117896,12 @@ var lint_spec = createSwarmTool({
|
|
|
117246
117896
|
// src/tools/mutation-test.ts
|
|
117247
117897
|
init_zod();
|
|
117248
117898
|
import * as fs100 from "node:fs";
|
|
117249
|
-
import * as
|
|
117899
|
+
import * as path140 from "node:path";
|
|
117250
117900
|
|
|
117251
117901
|
// src/mutation/engine.ts
|
|
117252
117902
|
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
117253
117903
|
import { unlinkSync as unlinkSync19, writeFileSync as writeFileSync26 } from "node:fs";
|
|
117254
|
-
import * as
|
|
117904
|
+
import * as path139 from "node:path";
|
|
117255
117905
|
|
|
117256
117906
|
// src/mutation/equivalence.ts
|
|
117257
117907
|
function isStaticallyEquivalent(originalCode, mutatedCode) {
|
|
@@ -117323,7 +117973,7 @@ function isStaticallyEquivalent(originalCode, mutatedCode) {
|
|
|
117323
117973
|
const strippedMutated = stripCode(mutatedCode);
|
|
117324
117974
|
return strippedOriginal === strippedMutated;
|
|
117325
117975
|
}
|
|
117326
|
-
var
|
|
117976
|
+
var _internals65 = {
|
|
117327
117977
|
isStaticallyEquivalent,
|
|
117328
117978
|
checkEquivalence,
|
|
117329
117979
|
batchCheckEquivalence
|
|
@@ -117363,7 +118013,7 @@ async function batchCheckEquivalence(patches, llmJudge) {
|
|
|
117363
118013
|
const results = [];
|
|
117364
118014
|
for (const { patch, originalCode, mutatedCode } of patches) {
|
|
117365
118015
|
try {
|
|
117366
|
-
const result = await
|
|
118016
|
+
const result = await _internals65.checkEquivalence(patch, originalCode, mutatedCode, llmJudge);
|
|
117367
118017
|
results.push(result);
|
|
117368
118018
|
} catch (err2) {
|
|
117369
118019
|
results.push({
|
|
@@ -117382,7 +118032,7 @@ async function batchCheckEquivalence(patches, llmJudge) {
|
|
|
117382
118032
|
var MUTATION_TIMEOUT_MS = 30000;
|
|
117383
118033
|
var TOTAL_BUDGET_MS = 300000;
|
|
117384
118034
|
var GIT_APPLY_TIMEOUT_MS = 5000;
|
|
117385
|
-
var
|
|
118035
|
+
var _internals66 = {
|
|
117386
118036
|
executeMutation,
|
|
117387
118037
|
computeReport,
|
|
117388
118038
|
executeMutationSuite,
|
|
@@ -117397,7 +118047,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
|
117397
118047
|
let patchFile;
|
|
117398
118048
|
try {
|
|
117399
118049
|
const safeId2 = patch.id.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
117400
|
-
patchFile =
|
|
118050
|
+
patchFile = path139.join(workingDir, `.mutation_patch_${safeId2}.diff`);
|
|
117401
118051
|
try {
|
|
117402
118052
|
writeFileSync26(patchFile, patch.patch);
|
|
117403
118053
|
} catch (writeErr) {
|
|
@@ -117414,7 +118064,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
|
117414
118064
|
};
|
|
117415
118065
|
}
|
|
117416
118066
|
try {
|
|
117417
|
-
const applyResult =
|
|
118067
|
+
const applyResult = _internals66.spawnSync("git", ["apply", "--", patchFile], {
|
|
117418
118068
|
cwd: workingDir,
|
|
117419
118069
|
timeout: GIT_APPLY_TIMEOUT_MS,
|
|
117420
118070
|
stdio: "pipe"
|
|
@@ -117443,7 +118093,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
|
117443
118093
|
}
|
|
117444
118094
|
let testPassed = false;
|
|
117445
118095
|
try {
|
|
117446
|
-
const spawnResult =
|
|
118096
|
+
const spawnResult = _internals66.spawnSync(testCommand[0], testCommand.slice(1), {
|
|
117447
118097
|
cwd: workingDir,
|
|
117448
118098
|
timeout: MUTATION_TIMEOUT_MS,
|
|
117449
118099
|
stdio: "pipe"
|
|
@@ -117476,7 +118126,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
|
117476
118126
|
} finally {
|
|
117477
118127
|
if (patchFile) {
|
|
117478
118128
|
try {
|
|
117479
|
-
const revertResult =
|
|
118129
|
+
const revertResult = _internals66.spawnSync("git", ["apply", "-R", "--", patchFile], {
|
|
117480
118130
|
cwd: workingDir,
|
|
117481
118131
|
timeout: GIT_APPLY_TIMEOUT_MS,
|
|
117482
118132
|
stdio: "pipe"
|
|
@@ -117669,7 +118319,7 @@ async function executeMutationSuite(patches, testCommand, testFiles, workingDir,
|
|
|
117669
118319
|
}
|
|
117670
118320
|
|
|
117671
118321
|
// src/mutation/gate.ts
|
|
117672
|
-
var
|
|
118322
|
+
var _internals67 = {
|
|
117673
118323
|
evaluateMutationGate,
|
|
117674
118324
|
buildTestImprovementPrompt,
|
|
117675
118325
|
buildMessage
|
|
@@ -117690,8 +118340,8 @@ function evaluateMutationGate(report, passThreshold = PASS_THRESHOLD, warnThresh
|
|
|
117690
118340
|
} else {
|
|
117691
118341
|
verdict = "fail";
|
|
117692
118342
|
}
|
|
117693
|
-
const testImprovementPrompt =
|
|
117694
|
-
const message =
|
|
118343
|
+
const testImprovementPrompt = _internals67.buildTestImprovementPrompt(report, passThreshold, verdict);
|
|
118344
|
+
const message = _internals67.buildMessage(verdict, adjustedKillRate, report.killed, report.totalMutants, report.equivalent, warnThreshold);
|
|
117695
118345
|
return {
|
|
117696
118346
|
verdict,
|
|
117697
118347
|
killRate: report.killRate,
|
|
@@ -117801,7 +118451,7 @@ var mutation_test = createSwarmTool({
|
|
|
117801
118451
|
];
|
|
117802
118452
|
for (const filePath of uniquePaths) {
|
|
117803
118453
|
try {
|
|
117804
|
-
const resolvedPath =
|
|
118454
|
+
const resolvedPath = path140.resolve(cwd, filePath);
|
|
117805
118455
|
sourceFiles.set(filePath, fs100.readFileSync(resolvedPath, "utf-8"));
|
|
117806
118456
|
} catch {}
|
|
117807
118457
|
}
|
|
@@ -117823,22 +118473,22 @@ init_config();
|
|
|
117823
118473
|
init_schema();
|
|
117824
118474
|
init_manager2();
|
|
117825
118475
|
import * as fs110 from "node:fs";
|
|
117826
|
-
import * as
|
|
118476
|
+
import * as path150 from "node:path";
|
|
117827
118477
|
|
|
117828
118478
|
// src/full-auto/phase-approval.ts
|
|
117829
118479
|
init_utils2();
|
|
117830
118480
|
init_logger();
|
|
117831
118481
|
init_state2();
|
|
117832
118482
|
import * as fs101 from "node:fs";
|
|
117833
|
-
import * as
|
|
118483
|
+
import * as path141 from "node:path";
|
|
117834
118484
|
var APPROVAL_TTL_MS = 24 * 60 * 60 * 1000;
|
|
117835
118485
|
function readEvidenceDir(directory, phase) {
|
|
117836
118486
|
try {
|
|
117837
|
-
const dirPath = validateSwarmPath(directory,
|
|
118487
|
+
const dirPath = validateSwarmPath(directory, path141.posix.join("evidence", String(phase)));
|
|
117838
118488
|
if (!fs101.existsSync(dirPath))
|
|
117839
118489
|
return [];
|
|
117840
118490
|
const entries = fs101.readdirSync(dirPath);
|
|
117841
|
-
return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) =>
|
|
118491
|
+
return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) => path141.join(dirPath, e));
|
|
117842
118492
|
} catch {
|
|
117843
118493
|
return [];
|
|
117844
118494
|
}
|
|
@@ -117979,16 +118629,16 @@ init_plan_schema();
|
|
|
117979
118629
|
init_ledger();
|
|
117980
118630
|
init_manager();
|
|
117981
118631
|
import * as fs102 from "node:fs";
|
|
117982
|
-
import * as
|
|
118632
|
+
import * as path142 from "node:path";
|
|
117983
118633
|
async function writeCheckpoint(directory) {
|
|
117984
118634
|
try {
|
|
117985
118635
|
const plan = await loadPlan(directory);
|
|
117986
118636
|
if (!plan)
|
|
117987
118637
|
return;
|
|
117988
|
-
const swarmDir =
|
|
118638
|
+
const swarmDir = path142.join(directory, ".swarm");
|
|
117989
118639
|
fs102.mkdirSync(swarmDir, { recursive: true });
|
|
117990
|
-
const jsonPath =
|
|
117991
|
-
const mdPath =
|
|
118640
|
+
const jsonPath = path142.join(swarmDir, "SWARM_PLAN.json");
|
|
118641
|
+
const mdPath = path142.join(swarmDir, "SWARM_PLAN.md");
|
|
117992
118642
|
fs102.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
|
|
117993
118643
|
const md = derivePlanMarkdown(plan);
|
|
117994
118644
|
fs102.writeFileSync(mdPath, md, "utf8");
|
|
@@ -118007,7 +118657,7 @@ init_telemetry();
|
|
|
118007
118657
|
// src/turbo/lean/phase-ready.ts
|
|
118008
118658
|
init_file_locks();
|
|
118009
118659
|
import * as fs103 from "node:fs";
|
|
118010
|
-
import * as
|
|
118660
|
+
import * as path143 from "node:path";
|
|
118011
118661
|
init_state3();
|
|
118012
118662
|
var DEFAULT_CONFIG3 = {
|
|
118013
118663
|
phase_reviewer: true,
|
|
@@ -118016,7 +118666,7 @@ var DEFAULT_CONFIG3 = {
|
|
|
118016
118666
|
};
|
|
118017
118667
|
function defaultReadPlanJson(dir) {
|
|
118018
118668
|
try {
|
|
118019
|
-
const planPath =
|
|
118669
|
+
const planPath = path143.join(dir, ".swarm", "plan.json");
|
|
118020
118670
|
if (!fs103.existsSync(planPath))
|
|
118021
118671
|
return null;
|
|
118022
118672
|
const raw = fs103.readFileSync(planPath, "utf-8");
|
|
@@ -118031,7 +118681,7 @@ function defaultReadPlanJson(dir) {
|
|
|
118031
118681
|
}
|
|
118032
118682
|
function readReviewerEvidenceFromFile(directory, phase) {
|
|
118033
118683
|
try {
|
|
118034
|
-
const evidencePath =
|
|
118684
|
+
const evidencePath = path143.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-reviewer.json");
|
|
118035
118685
|
if (!fs103.existsSync(evidencePath)) {
|
|
118036
118686
|
return null;
|
|
118037
118687
|
}
|
|
@@ -118051,7 +118701,7 @@ function readReviewerEvidenceFromFile(directory, phase) {
|
|
|
118051
118701
|
}
|
|
118052
118702
|
function readCriticEvidenceFromFile(directory, phase) {
|
|
118053
118703
|
try {
|
|
118054
|
-
const evidencePath =
|
|
118704
|
+
const evidencePath = path143.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-critic.json");
|
|
118055
118705
|
if (!fs103.existsSync(evidencePath)) {
|
|
118056
118706
|
return null;
|
|
118057
118707
|
}
|
|
@@ -118070,7 +118720,7 @@ function readCriticEvidenceFromFile(directory, phase) {
|
|
|
118070
118720
|
}
|
|
118071
118721
|
}
|
|
118072
118722
|
function listLaneEvidenceSync(directory, phase) {
|
|
118073
|
-
const evidenceDir =
|
|
118723
|
+
const evidenceDir = path143.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
|
|
118074
118724
|
let entries;
|
|
118075
118725
|
try {
|
|
118076
118726
|
entries = fs103.readdirSync(evidenceDir);
|
|
@@ -118086,7 +118736,7 @@ function listLaneEvidenceSync(directory, phase) {
|
|
|
118086
118736
|
}
|
|
118087
118737
|
return laneIds;
|
|
118088
118738
|
}
|
|
118089
|
-
var
|
|
118739
|
+
var _internals68 = {
|
|
118090
118740
|
listActiveLocks,
|
|
118091
118741
|
readPersisted: readPersisted2,
|
|
118092
118742
|
readPlanJson: defaultReadPlanJson,
|
|
@@ -118140,14 +118790,14 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
118140
118790
|
...DEFAULT_CONFIG3,
|
|
118141
118791
|
...actualConfig
|
|
118142
118792
|
};
|
|
118143
|
-
const statePath =
|
|
118793
|
+
const statePath = path143.join(directory, ".swarm", "turbo-state.json");
|
|
118144
118794
|
if (!fs103.existsSync(statePath)) {
|
|
118145
118795
|
return {
|
|
118146
118796
|
ok: false,
|
|
118147
118797
|
reason: "Lean Turbo state unreadable or missing"
|
|
118148
118798
|
};
|
|
118149
118799
|
}
|
|
118150
|
-
const persisted =
|
|
118800
|
+
const persisted = _internals68.readPersisted(directory);
|
|
118151
118801
|
if (!persisted) {
|
|
118152
118802
|
return {
|
|
118153
118803
|
ok: false,
|
|
@@ -118211,7 +118861,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
118211
118861
|
}
|
|
118212
118862
|
}
|
|
118213
118863
|
if (runState.lanes.length > 0) {
|
|
118214
|
-
const evidenceLaneIds = new Set(
|
|
118864
|
+
const evidenceLaneIds = new Set(_internals68.listLaneEvidenceSync(directory, phase));
|
|
118215
118865
|
for (const lane of runState.lanes) {
|
|
118216
118866
|
if ((lane.status === "completed" || lane.status === "failed") && !evidenceLaneIds.has(lane.laneId)) {
|
|
118217
118867
|
return {
|
|
@@ -118221,7 +118871,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
118221
118871
|
}
|
|
118222
118872
|
}
|
|
118223
118873
|
}
|
|
118224
|
-
const activeLocks =
|
|
118874
|
+
const activeLocks = _internals68.listActiveLocks(directory);
|
|
118225
118875
|
const phaseLaneIds = new Set(laneIds);
|
|
118226
118876
|
for (const lock of activeLocks) {
|
|
118227
118877
|
if (lock.laneId && phaseLaneIds.has(lock.laneId)) {
|
|
@@ -118241,7 +118891,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
118241
118891
|
}
|
|
118242
118892
|
const serialDegradedTasks = runState.degradedTasks.filter((dt) => !laneTaskIds.has(dt.taskId));
|
|
118243
118893
|
if (serialDegradedTasks.length > 0) {
|
|
118244
|
-
const plan =
|
|
118894
|
+
const plan = _internals68.readPlanJson(directory);
|
|
118245
118895
|
if (!plan) {
|
|
118246
118896
|
return {
|
|
118247
118897
|
ok: false,
|
|
@@ -118285,7 +118935,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
118285
118935
|
}
|
|
118286
118936
|
const serializedTasks = runState.serializedTasks;
|
|
118287
118937
|
if (Array.isArray(serializedTasks) && serializedTasks.length > 0) {
|
|
118288
|
-
const plan =
|
|
118938
|
+
const plan = _internals68.readPlanJson(directory);
|
|
118289
118939
|
if (!plan) {
|
|
118290
118940
|
return {
|
|
118291
118941
|
ok: false,
|
|
@@ -118328,7 +118978,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
118328
118978
|
}
|
|
118329
118979
|
}
|
|
118330
118980
|
if (mergedConfig.integrated_diff_required) {
|
|
118331
|
-
const evidencePath =
|
|
118981
|
+
const evidencePath = path143.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-phase.json");
|
|
118332
118982
|
let hasDiff = false;
|
|
118333
118983
|
try {
|
|
118334
118984
|
const content = fs103.readFileSync(evidencePath, "utf-8");
|
|
@@ -118344,7 +118994,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
118344
118994
|
}
|
|
118345
118995
|
let reviewerVerdict = runState.lastReviewerVerdict;
|
|
118346
118996
|
if (!reviewerVerdict) {
|
|
118347
|
-
const evidence =
|
|
118997
|
+
const evidence = _internals68.readReviewerEvidence(directory, phase);
|
|
118348
118998
|
reviewerVerdict = evidence?.verdict ?? undefined;
|
|
118349
118999
|
}
|
|
118350
119000
|
if (mergedConfig.phase_reviewer) {
|
|
@@ -118357,7 +119007,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
118357
119007
|
}
|
|
118358
119008
|
let criticVerdict = runState.lastCriticVerdict;
|
|
118359
119009
|
if (!criticVerdict) {
|
|
118360
|
-
const evidence =
|
|
119010
|
+
const evidence = _internals68.readCriticEvidence(directory, phase);
|
|
118361
119011
|
criticVerdict = evidence?.verdict ?? undefined;
|
|
118362
119012
|
}
|
|
118363
119013
|
if (mergedConfig.phase_critic) {
|
|
@@ -118480,13 +119130,13 @@ init_qa_gate_profile();
|
|
|
118480
119130
|
init_manager();
|
|
118481
119131
|
init_state();
|
|
118482
119132
|
import * as fs104 from "node:fs";
|
|
118483
|
-
import * as
|
|
119133
|
+
import * as path144 from "node:path";
|
|
118484
119134
|
async function runDriftGate(ctx) {
|
|
118485
119135
|
const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
|
|
118486
119136
|
let driftCheckEnabled = true;
|
|
118487
119137
|
let driftHasSpecMd = false;
|
|
118488
119138
|
try {
|
|
118489
|
-
const specMdPath =
|
|
119139
|
+
const specMdPath = path144.join(dir, ".swarm", "spec.md");
|
|
118490
119140
|
driftHasSpecMd = fs104.existsSync(specMdPath);
|
|
118491
119141
|
const gatePlan = await loadPlan(dir);
|
|
118492
119142
|
if (gatePlan) {
|
|
@@ -118514,7 +119164,7 @@ async function runDriftGate(ctx) {
|
|
|
118514
119164
|
}
|
|
118515
119165
|
let phaseType;
|
|
118516
119166
|
try {
|
|
118517
|
-
const planPath =
|
|
119167
|
+
const planPath = path144.join(dir, ".swarm", "plan.json");
|
|
118518
119168
|
if (fs104.existsSync(planPath)) {
|
|
118519
119169
|
const planRaw = fs104.readFileSync(planPath, "utf-8");
|
|
118520
119170
|
const plan = JSON.parse(planRaw);
|
|
@@ -118533,7 +119183,7 @@ async function runDriftGate(ctx) {
|
|
|
118533
119183
|
};
|
|
118534
119184
|
}
|
|
118535
119185
|
try {
|
|
118536
|
-
const driftEvidencePath =
|
|
119186
|
+
const driftEvidencePath = path144.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
|
|
118537
119187
|
let driftVerdictFound = false;
|
|
118538
119188
|
let driftVerdictApproved = false;
|
|
118539
119189
|
try {
|
|
@@ -118569,7 +119219,7 @@ async function runDriftGate(ctx) {
|
|
|
118569
119219
|
let incompleteTaskCount = 0;
|
|
118570
119220
|
let planParseable = false;
|
|
118571
119221
|
try {
|
|
118572
|
-
const planPath =
|
|
119222
|
+
const planPath = path144.join(dir, ".swarm", "plan.json");
|
|
118573
119223
|
if (fs104.existsSync(planPath)) {
|
|
118574
119224
|
const planRaw = fs104.readFileSync(planPath, "utf-8");
|
|
118575
119225
|
const plan = JSON.parse(planRaw);
|
|
@@ -118651,7 +119301,7 @@ init_qa_gate_profile();
|
|
|
118651
119301
|
init_manager();
|
|
118652
119302
|
init_state();
|
|
118653
119303
|
import * as fs105 from "node:fs";
|
|
118654
|
-
import * as
|
|
119304
|
+
import * as path145 from "node:path";
|
|
118655
119305
|
async function runFinalCouncilGate(ctx) {
|
|
118656
119306
|
const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
|
|
118657
119307
|
let finalCouncilEnabled = false;
|
|
@@ -118669,7 +119319,7 @@ async function runFinalCouncilGate(ctx) {
|
|
|
118669
119319
|
const effective = getEffectiveGates(profile, overrides);
|
|
118670
119320
|
if (effective.final_council === true) {
|
|
118671
119321
|
finalCouncilEnabled = true;
|
|
118672
|
-
const fcPath =
|
|
119322
|
+
const fcPath = path145.join(dir, ".swarm", "evidence", "final-council.json");
|
|
118673
119323
|
let fcVerdictFound = false;
|
|
118674
119324
|
let _fcVerdict;
|
|
118675
119325
|
try {
|
|
@@ -118810,7 +119460,7 @@ init_qa_gate_profile();
|
|
|
118810
119460
|
init_manager();
|
|
118811
119461
|
init_state();
|
|
118812
119462
|
import * as fs106 from "node:fs";
|
|
118813
|
-
import * as
|
|
119463
|
+
import * as path146 from "node:path";
|
|
118814
119464
|
async function runHallucinationGate(ctx) {
|
|
118815
119465
|
const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
|
|
118816
119466
|
try {
|
|
@@ -118823,7 +119473,7 @@ async function runHallucinationGate(ctx) {
|
|
|
118823
119473
|
const overrides = session?.qaGateSessionOverrides ?? {};
|
|
118824
119474
|
const effective = getEffectiveGates(profile, overrides);
|
|
118825
119475
|
if (effective.hallucination_guard === true) {
|
|
118826
|
-
const hgPath =
|
|
119476
|
+
const hgPath = path146.join(dir, ".swarm", "evidence", String(phase), "hallucination-guard.json");
|
|
118827
119477
|
let hgVerdictFound = false;
|
|
118828
119478
|
let hgVerdictApproved = false;
|
|
118829
119479
|
try {
|
|
@@ -118886,7 +119536,7 @@ init_qa_gate_profile();
|
|
|
118886
119536
|
init_manager();
|
|
118887
119537
|
init_state();
|
|
118888
119538
|
import * as fs107 from "node:fs";
|
|
118889
|
-
import * as
|
|
119539
|
+
import * as path147 from "node:path";
|
|
118890
119540
|
async function runMutationGate(ctx) {
|
|
118891
119541
|
const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
|
|
118892
119542
|
try {
|
|
@@ -118899,7 +119549,7 @@ async function runMutationGate(ctx) {
|
|
|
118899
119549
|
const overrides = session?.qaGateSessionOverrides ?? {};
|
|
118900
119550
|
const effective = getEffectiveGates(profile, overrides);
|
|
118901
119551
|
if (effective.mutation_test === true) {
|
|
118902
|
-
const mgPath =
|
|
119552
|
+
const mgPath = path147.join(dir, ".swarm", "evidence", String(phase), "mutation-gate.json");
|
|
118903
119553
|
let mgVerdictFound = false;
|
|
118904
119554
|
let mgVerdict;
|
|
118905
119555
|
try {
|
|
@@ -118962,7 +119612,7 @@ init_qa_gate_profile();
|
|
|
118962
119612
|
init_manager();
|
|
118963
119613
|
init_state();
|
|
118964
119614
|
import * as fs108 from "node:fs";
|
|
118965
|
-
import * as
|
|
119615
|
+
import * as path148 from "node:path";
|
|
118966
119616
|
async function runPhaseCouncilGate(ctx) {
|
|
118967
119617
|
const { phase, dir, sessionID, pluginConfig, agentsDispatched, safeWarn } = ctx;
|
|
118968
119618
|
let councilModeEnabled = false;
|
|
@@ -118977,7 +119627,7 @@ async function runPhaseCouncilGate(ctx) {
|
|
|
118977
119627
|
const effective = getEffectiveGates(profile, overrides);
|
|
118978
119628
|
if (effective.council_mode === true) {
|
|
118979
119629
|
councilModeEnabled = true;
|
|
118980
|
-
const pcPath =
|
|
119630
|
+
const pcPath = path148.join(dir, ".swarm", "evidence", String(phase), "phase-council.json");
|
|
118981
119631
|
let pcVerdictFound = false;
|
|
118982
119632
|
let _pcVerdict;
|
|
118983
119633
|
let pcQuorumSize;
|
|
@@ -119469,7 +120119,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
119469
120119
|
phase_critic: leanConfig.phase_critic,
|
|
119470
120120
|
integrated_diff_required: leanConfig.integrated_diff_required
|
|
119471
120121
|
} : undefined;
|
|
119472
|
-
const leanCheck =
|
|
120122
|
+
const leanCheck = _internals68.verifyLeanTurboPhaseReady(dir, phase, sessionID, leanPhaseReadyConfig);
|
|
119473
120123
|
if (!leanCheck.ok) {
|
|
119474
120124
|
return JSON.stringify({
|
|
119475
120125
|
success: false,
|
|
@@ -119492,7 +120142,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
119492
120142
|
}
|
|
119493
120143
|
if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
|
|
119494
120144
|
try {
|
|
119495
|
-
const projectName =
|
|
120145
|
+
const projectName = path150.basename(dir);
|
|
119496
120146
|
const curationResult = await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig);
|
|
119497
120147
|
if (curationResult) {
|
|
119498
120148
|
const sessionState = swarmState.agentSessions.get(sessionID);
|
|
@@ -119935,7 +120585,7 @@ init_utils();
|
|
|
119935
120585
|
init_bun_compat();
|
|
119936
120586
|
init_create_tool();
|
|
119937
120587
|
import * as fs111 from "node:fs";
|
|
119938
|
-
import * as
|
|
120588
|
+
import * as path151 from "node:path";
|
|
119939
120589
|
var MAX_OUTPUT_BYTES6 = 52428800;
|
|
119940
120590
|
var AUDIT_TIMEOUT_MS = 120000;
|
|
119941
120591
|
function isValidEcosystem(value) {
|
|
@@ -119963,16 +120613,16 @@ function validateArgs3(args2) {
|
|
|
119963
120613
|
function detectEcosystems(directory) {
|
|
119964
120614
|
const ecosystems = [];
|
|
119965
120615
|
const cwd = directory;
|
|
119966
|
-
if (fs111.existsSync(
|
|
120616
|
+
if (fs111.existsSync(path151.join(cwd, "package.json"))) {
|
|
119967
120617
|
ecosystems.push("npm");
|
|
119968
120618
|
}
|
|
119969
|
-
if (fs111.existsSync(
|
|
120619
|
+
if (fs111.existsSync(path151.join(cwd, "pyproject.toml")) || fs111.existsSync(path151.join(cwd, "requirements.txt"))) {
|
|
119970
120620
|
ecosystems.push("pip");
|
|
119971
120621
|
}
|
|
119972
|
-
if (fs111.existsSync(
|
|
120622
|
+
if (fs111.existsSync(path151.join(cwd, "Cargo.toml"))) {
|
|
119973
120623
|
ecosystems.push("cargo");
|
|
119974
120624
|
}
|
|
119975
|
-
if (fs111.existsSync(
|
|
120625
|
+
if (fs111.existsSync(path151.join(cwd, "go.mod"))) {
|
|
119976
120626
|
ecosystems.push("go");
|
|
119977
120627
|
}
|
|
119978
120628
|
try {
|
|
@@ -119981,13 +120631,13 @@ function detectEcosystems(directory) {
|
|
|
119981
120631
|
ecosystems.push("dotnet");
|
|
119982
120632
|
}
|
|
119983
120633
|
} catch {}
|
|
119984
|
-
if (fs111.existsSync(
|
|
120634
|
+
if (fs111.existsSync(path151.join(cwd, "Gemfile")) || fs111.existsSync(path151.join(cwd, "Gemfile.lock"))) {
|
|
119985
120635
|
ecosystems.push("ruby");
|
|
119986
120636
|
}
|
|
119987
|
-
if (fs111.existsSync(
|
|
120637
|
+
if (fs111.existsSync(path151.join(cwd, "pubspec.yaml"))) {
|
|
119988
120638
|
ecosystems.push("dart");
|
|
119989
120639
|
}
|
|
119990
|
-
if (fs111.existsSync(
|
|
120640
|
+
if (fs111.existsSync(path151.join(cwd, "composer.lock"))) {
|
|
119991
120641
|
ecosystems.push("composer");
|
|
119992
120642
|
}
|
|
119993
120643
|
return ecosystems;
|
|
@@ -120000,7 +120650,7 @@ async function runNpmAudit(directory) {
|
|
|
120000
120650
|
stderr: "pipe",
|
|
120001
120651
|
cwd: directory
|
|
120002
120652
|
});
|
|
120003
|
-
const timeoutPromise = new Promise((
|
|
120653
|
+
const timeoutPromise = new Promise((resolve52) => setTimeout(() => resolve52("timeout"), AUDIT_TIMEOUT_MS));
|
|
120004
120654
|
const result = await Promise.race([
|
|
120005
120655
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
|
|
120006
120656
|
timeoutPromise
|
|
@@ -120120,7 +120770,7 @@ async function runPipAudit(directory) {
|
|
|
120120
120770
|
stderr: "pipe",
|
|
120121
120771
|
cwd: directory
|
|
120122
120772
|
});
|
|
120123
|
-
const timeoutPromise = new Promise((
|
|
120773
|
+
const timeoutPromise = new Promise((resolve52) => setTimeout(() => resolve52("timeout"), AUDIT_TIMEOUT_MS));
|
|
120124
120774
|
const result = await Promise.race([
|
|
120125
120775
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
|
|
120126
120776
|
timeoutPromise
|
|
@@ -120248,7 +120898,7 @@ async function runCargoAudit(directory) {
|
|
|
120248
120898
|
stderr: "pipe",
|
|
120249
120899
|
cwd: directory
|
|
120250
120900
|
});
|
|
120251
|
-
const timeoutPromise = new Promise((
|
|
120901
|
+
const timeoutPromise = new Promise((resolve52) => setTimeout(() => resolve52("timeout"), AUDIT_TIMEOUT_MS));
|
|
120252
120902
|
const result = await Promise.race([
|
|
120253
120903
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
120254
120904
|
timeoutPromise
|
|
@@ -120372,7 +121022,7 @@ async function runGoAudit(directory) {
|
|
|
120372
121022
|
stderr: "pipe",
|
|
120373
121023
|
cwd: directory
|
|
120374
121024
|
});
|
|
120375
|
-
const timeoutPromise = new Promise((
|
|
121025
|
+
const timeoutPromise = new Promise((resolve52) => setTimeout(() => resolve52("timeout"), AUDIT_TIMEOUT_MS));
|
|
120376
121026
|
const result = await Promise.race([
|
|
120377
121027
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
120378
121028
|
timeoutPromise
|
|
@@ -120505,7 +121155,7 @@ async function runDotnetAudit(directory) {
|
|
|
120505
121155
|
stderr: "pipe",
|
|
120506
121156
|
cwd: directory
|
|
120507
121157
|
});
|
|
120508
|
-
const timeoutPromise = new Promise((
|
|
121158
|
+
const timeoutPromise = new Promise((resolve52) => setTimeout(() => resolve52("timeout"), AUDIT_TIMEOUT_MS));
|
|
120509
121159
|
const result = await Promise.race([
|
|
120510
121160
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
120511
121161
|
timeoutPromise
|
|
@@ -120621,7 +121271,7 @@ async function runBundleAudit(directory) {
|
|
|
120621
121271
|
stderr: "pipe",
|
|
120622
121272
|
cwd: directory
|
|
120623
121273
|
});
|
|
120624
|
-
const timeoutPromise = new Promise((
|
|
121274
|
+
const timeoutPromise = new Promise((resolve52) => setTimeout(() => resolve52("timeout"), AUDIT_TIMEOUT_MS));
|
|
120625
121275
|
const result = await Promise.race([
|
|
120626
121276
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
120627
121277
|
timeoutPromise
|
|
@@ -120766,7 +121416,7 @@ async function runDartAudit(directory) {
|
|
|
120766
121416
|
stderr: "pipe",
|
|
120767
121417
|
cwd: directory
|
|
120768
121418
|
});
|
|
120769
|
-
const timeoutPromise = new Promise((
|
|
121419
|
+
const timeoutPromise = new Promise((resolve52) => setTimeout(() => resolve52("timeout"), AUDIT_TIMEOUT_MS));
|
|
120770
121420
|
const result = await Promise.race([
|
|
120771
121421
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
120772
121422
|
timeoutPromise
|
|
@@ -120881,7 +121531,7 @@ async function runComposerAudit(directory) {
|
|
|
120881
121531
|
stderr: "pipe",
|
|
120882
121532
|
cwd: directory
|
|
120883
121533
|
});
|
|
120884
|
-
const timeoutPromise = new Promise((
|
|
121534
|
+
const timeoutPromise = new Promise((resolve52) => setTimeout(() => resolve52("timeout"), AUDIT_TIMEOUT_MS));
|
|
120885
121535
|
const result = await Promise.race([
|
|
120886
121536
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
120887
121537
|
timeoutPromise
|
|
@@ -121124,7 +121774,7 @@ var pkg_audit = createSwarmTool({
|
|
|
121124
121774
|
init_zod();
|
|
121125
121775
|
init_manager2();
|
|
121126
121776
|
import * as fs112 from "node:fs";
|
|
121127
|
-
import * as
|
|
121777
|
+
import * as path152 from "node:path";
|
|
121128
121778
|
init_utils();
|
|
121129
121779
|
init_create_tool();
|
|
121130
121780
|
var MAX_FILE_SIZE = 1024 * 1024;
|
|
@@ -121247,7 +121897,7 @@ function isScaffoldFile(filePath) {
|
|
|
121247
121897
|
if (SCAFFOLD_PATH_PATTERNS.some((pattern) => pattern.test(normalizedPath))) {
|
|
121248
121898
|
return true;
|
|
121249
121899
|
}
|
|
121250
|
-
const filename =
|
|
121900
|
+
const filename = path152.basename(filePath);
|
|
121251
121901
|
if (SCAFFOLD_FILENAME_PATTERNS.some((pattern) => pattern.test(filename))) {
|
|
121252
121902
|
return true;
|
|
121253
121903
|
}
|
|
@@ -121264,7 +121914,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
121264
121914
|
if (regex.test(normalizedPath)) {
|
|
121265
121915
|
return true;
|
|
121266
121916
|
}
|
|
121267
|
-
const filename =
|
|
121917
|
+
const filename = path152.basename(filePath);
|
|
121268
121918
|
const filenameRegex = new RegExp(`^${regexPattern}$`, "i");
|
|
121269
121919
|
if (filenameRegex.test(filename)) {
|
|
121270
121920
|
return true;
|
|
@@ -121273,7 +121923,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
121273
121923
|
return false;
|
|
121274
121924
|
}
|
|
121275
121925
|
function isParserSupported(filePath) {
|
|
121276
|
-
const ext =
|
|
121926
|
+
const ext = path152.extname(filePath).toLowerCase();
|
|
121277
121927
|
return SUPPORTED_PARSER_EXTENSIONS.has(ext);
|
|
121278
121928
|
}
|
|
121279
121929
|
function isPlanFile(filePath) {
|
|
@@ -121520,9 +122170,9 @@ async function placeholderScan(input, directory) {
|
|
|
121520
122170
|
let filesScanned = 0;
|
|
121521
122171
|
const filesWithFindings = new Set;
|
|
121522
122172
|
for (const filePath of changed_files) {
|
|
121523
|
-
const fullPath =
|
|
121524
|
-
const resolvedDirectory =
|
|
121525
|
-
if (!fullPath.startsWith(resolvedDirectory +
|
|
122173
|
+
const fullPath = path152.isAbsolute(filePath) ? filePath : path152.resolve(directory, filePath);
|
|
122174
|
+
const resolvedDirectory = path152.resolve(directory);
|
|
122175
|
+
if (!fullPath.startsWith(resolvedDirectory + path152.sep) && fullPath !== resolvedDirectory) {
|
|
121526
122176
|
continue;
|
|
121527
122177
|
}
|
|
121528
122178
|
if (!fs112.existsSync(fullPath)) {
|
|
@@ -121531,7 +122181,7 @@ async function placeholderScan(input, directory) {
|
|
|
121531
122181
|
if (isAllowedByGlobs(filePath, allow_globs)) {
|
|
121532
122182
|
continue;
|
|
121533
122183
|
}
|
|
121534
|
-
const relativeFilePath =
|
|
122184
|
+
const relativeFilePath = path152.relative(directory, fullPath).replace(/\\/g, "/");
|
|
121535
122185
|
if (FILE_ALLOWLIST.some((allowed) => relativeFilePath.endsWith(allowed))) {
|
|
121536
122186
|
continue;
|
|
121537
122187
|
}
|
|
@@ -121604,7 +122254,7 @@ var placeholder_scan = createSwarmTool({
|
|
|
121604
122254
|
|
|
121605
122255
|
// src/tools/pre-check-batch.ts
|
|
121606
122256
|
import * as fs116 from "node:fs";
|
|
121607
|
-
import * as
|
|
122257
|
+
import * as path156 from "node:path";
|
|
121608
122258
|
init_zod();
|
|
121609
122259
|
init_manager2();
|
|
121610
122260
|
init_utils();
|
|
@@ -121732,11 +122382,11 @@ var quality_budget = createSwarmTool({
|
|
|
121732
122382
|
}).optional().describe("Quality budget thresholds")
|
|
121733
122383
|
},
|
|
121734
122384
|
async execute(args2, directory) {
|
|
121735
|
-
const result = await
|
|
122385
|
+
const result = await _internals70.qualityBudget(args2, directory);
|
|
121736
122386
|
return JSON.stringify(result);
|
|
121737
122387
|
}
|
|
121738
122388
|
});
|
|
121739
|
-
var
|
|
122389
|
+
var _internals70 = {
|
|
121740
122390
|
qualityBudget
|
|
121741
122391
|
};
|
|
121742
122392
|
|
|
@@ -121745,7 +122395,7 @@ init_zod();
|
|
|
121745
122395
|
init_manager2();
|
|
121746
122396
|
init_detector();
|
|
121747
122397
|
import * as fs115 from "node:fs";
|
|
121748
|
-
import * as
|
|
122398
|
+
import * as path155 from "node:path";
|
|
121749
122399
|
import { extname as extname22 } from "node:path";
|
|
121750
122400
|
|
|
121751
122401
|
// src/sast/rules/c.ts
|
|
@@ -122455,13 +123105,13 @@ function executeRulesSync(filePath, content, language) {
|
|
|
122455
123105
|
// src/sast/semgrep.ts
|
|
122456
123106
|
import * as child_process10 from "node:child_process";
|
|
122457
123107
|
import * as fs113 from "node:fs";
|
|
122458
|
-
import * as
|
|
123108
|
+
import * as path153 from "node:path";
|
|
122459
123109
|
var semgrepAvailableCache = null;
|
|
122460
123110
|
var DEFAULT_RULES_DIR = ".swarm/semgrep-rules";
|
|
122461
123111
|
var DEFAULT_TIMEOUT_MS3 = 30000;
|
|
122462
123112
|
var MAX_OUTPUT_BYTES7 = 10 * 1024 * 1024;
|
|
122463
123113
|
var KILL_GRACE_MS = 2000;
|
|
122464
|
-
var
|
|
123114
|
+
var _internals71 = {
|
|
122465
123115
|
isSemgrepAvailable,
|
|
122466
123116
|
checkSemgrepAvailable,
|
|
122467
123117
|
resetSemgrepCache,
|
|
@@ -122487,7 +123137,7 @@ function isSemgrepAvailable() {
|
|
|
122487
123137
|
}
|
|
122488
123138
|
}
|
|
122489
123139
|
async function checkSemgrepAvailable() {
|
|
122490
|
-
return
|
|
123140
|
+
return _internals71.isSemgrepAvailable();
|
|
122491
123141
|
}
|
|
122492
123142
|
function resetSemgrepCache() {
|
|
122493
123143
|
semgrepAvailableCache = null;
|
|
@@ -122540,7 +123190,7 @@ function mapSemgrepSeverity(severity) {
|
|
|
122540
123190
|
}
|
|
122541
123191
|
async function executeWithTimeout(command, args2, options) {
|
|
122542
123192
|
const maxOutputBytes = options.maxOutputBytes ?? MAX_OUTPUT_BYTES7;
|
|
122543
|
-
return new Promise((
|
|
123193
|
+
return new Promise((resolve54) => {
|
|
122544
123194
|
const child = child_process10.spawn(command, args2, {
|
|
122545
123195
|
shell: false,
|
|
122546
123196
|
cwd: options.cwd,
|
|
@@ -122572,7 +123222,7 @@ async function executeWithTimeout(command, args2, options) {
|
|
|
122572
123222
|
escalation.unref();
|
|
122573
123223
|
}
|
|
122574
123224
|
}
|
|
122575
|
-
|
|
123225
|
+
resolve54({ ...result, truncated });
|
|
122576
123226
|
};
|
|
122577
123227
|
timeout = setTimeout(() => {
|
|
122578
123228
|
settle({
|
|
@@ -122631,12 +123281,12 @@ async function runSemgrep(options) {
|
|
|
122631
123281
|
const timeoutMs = options.timeoutMs || DEFAULT_TIMEOUT_MS3;
|
|
122632
123282
|
if (files.length === 0) {
|
|
122633
123283
|
return {
|
|
122634
|
-
available:
|
|
123284
|
+
available: _internals71.isSemgrepAvailable(),
|
|
122635
123285
|
findings: [],
|
|
122636
123286
|
engine: "tier_a"
|
|
122637
123287
|
};
|
|
122638
123288
|
}
|
|
122639
|
-
if (!
|
|
123289
|
+
if (!_internals71.isSemgrepAvailable()) {
|
|
122640
123290
|
return {
|
|
122641
123291
|
available: false,
|
|
122642
123292
|
findings: [],
|
|
@@ -122700,7 +123350,7 @@ async function runSemgrep(options) {
|
|
|
122700
123350
|
}
|
|
122701
123351
|
function getRulesDirectory(projectRoot) {
|
|
122702
123352
|
if (projectRoot) {
|
|
122703
|
-
return
|
|
123353
|
+
return path153.resolve(projectRoot, DEFAULT_RULES_DIR);
|
|
122704
123354
|
}
|
|
122705
123355
|
return DEFAULT_RULES_DIR;
|
|
122706
123356
|
}
|
|
@@ -122721,24 +123371,24 @@ init_create_tool();
|
|
|
122721
123371
|
init_utils2();
|
|
122722
123372
|
import * as crypto12 from "node:crypto";
|
|
122723
123373
|
import * as fs114 from "node:fs";
|
|
122724
|
-
import * as
|
|
123374
|
+
import * as path154 from "node:path";
|
|
122725
123375
|
var BASELINE_SCHEMA_VERSION = "1.0.0";
|
|
122726
123376
|
var MAX_BASELINE_FINDINGS = 2000;
|
|
122727
123377
|
var MAX_BASELINE_BYTES = 2 * 1048576;
|
|
122728
123378
|
var LOCK_RETRY_DELAYS_MS = [50, 100, 200, 400, 800];
|
|
122729
123379
|
function normalizeFindingPath(directory, file3) {
|
|
122730
|
-
const resolved =
|
|
122731
|
-
const rel =
|
|
123380
|
+
const resolved = path154.isAbsolute(file3) ? file3 : path154.resolve(directory, file3);
|
|
123381
|
+
const rel = path154.relative(path154.resolve(directory), resolved);
|
|
122732
123382
|
return rel.replace(/\\/g, "/");
|
|
122733
123383
|
}
|
|
122734
123384
|
function baselineRelPath(phase) {
|
|
122735
|
-
return
|
|
123385
|
+
return path154.join("evidence", String(phase), "sast-baseline.json");
|
|
122736
123386
|
}
|
|
122737
123387
|
function tempRelPath(phase) {
|
|
122738
|
-
return
|
|
123388
|
+
return path154.join("evidence", String(phase), `sast-baseline.json.tmp.${Date.now()}.${process.pid}`);
|
|
122739
123389
|
}
|
|
122740
123390
|
function lockRelPath(phase) {
|
|
122741
|
-
return
|
|
123391
|
+
return path154.join("evidence", String(phase), "sast-baseline.json.lock");
|
|
122742
123392
|
}
|
|
122743
123393
|
function getLine(lines, idx) {
|
|
122744
123394
|
if (idx < 0 || idx >= lines.length)
|
|
@@ -122803,7 +123453,7 @@ function assignOccurrenceIndices(findings, directory) {
|
|
|
122803
123453
|
}
|
|
122804
123454
|
const occIdx = countMap.get(baseKey) ?? 0;
|
|
122805
123455
|
countMap.set(baseKey, occIdx + 1);
|
|
122806
|
-
const fp =
|
|
123456
|
+
const fp = _internals72.fingerprintFinding(finding, directory, occIdx);
|
|
122807
123457
|
return {
|
|
122808
123458
|
finding,
|
|
122809
123459
|
index: occIdx,
|
|
@@ -122824,7 +123474,7 @@ async function acquireLock2(lockPath) {
|
|
|
122824
123474
|
};
|
|
122825
123475
|
} catch {
|
|
122826
123476
|
if (attempt < LOCK_RETRY_DELAYS_MS.length) {
|
|
122827
|
-
await new Promise((
|
|
123477
|
+
await new Promise((resolve55) => setTimeout(resolve55, LOCK_RETRY_DELAYS_MS[attempt]));
|
|
122828
123478
|
}
|
|
122829
123479
|
}
|
|
122830
123480
|
}
|
|
@@ -122859,8 +123509,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
122859
123509
|
message: e instanceof Error ? e.message : "Path validation failed"
|
|
122860
123510
|
};
|
|
122861
123511
|
}
|
|
122862
|
-
fs114.mkdirSync(
|
|
122863
|
-
fs114.mkdirSync(
|
|
123512
|
+
fs114.mkdirSync(path154.dirname(baselinePath), { recursive: true });
|
|
123513
|
+
fs114.mkdirSync(path154.dirname(tempPath), { recursive: true });
|
|
122864
123514
|
const releaseLock = await acquireLock2(lockPath);
|
|
122865
123515
|
try {
|
|
122866
123516
|
let existing = null;
|
|
@@ -122872,7 +123522,7 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
122872
123522
|
}
|
|
122873
123523
|
} catch {}
|
|
122874
123524
|
const scannedRelFiles = new Set(scannedFiles.map((f) => normalizeFindingPath(directory, f)));
|
|
122875
|
-
const indexed =
|
|
123525
|
+
const indexed = _internals72.assignOccurrenceIndices(findings, directory);
|
|
122876
123526
|
if (existing && !opts?.force) {
|
|
122877
123527
|
const prunedFingerprints = existing.fingerprints.filter((fp) => {
|
|
122878
123528
|
const relFile = fp.slice(0, fp.indexOf("|"));
|
|
@@ -123012,7 +123662,7 @@ function loadBaseline(directory, phase) {
|
|
|
123012
123662
|
};
|
|
123013
123663
|
}
|
|
123014
123664
|
}
|
|
123015
|
-
var
|
|
123665
|
+
var _internals72 = {
|
|
123016
123666
|
fingerprintFinding,
|
|
123017
123667
|
assignOccurrenceIndices,
|
|
123018
123668
|
captureOrMergeBaseline,
|
|
@@ -123133,9 +123783,9 @@ async function sastScan(input, directory, config3) {
|
|
|
123133
123783
|
_filesSkipped++;
|
|
123134
123784
|
continue;
|
|
123135
123785
|
}
|
|
123136
|
-
const resolvedPath =
|
|
123137
|
-
const resolvedDirectory =
|
|
123138
|
-
if (!resolvedPath.startsWith(resolvedDirectory +
|
|
123786
|
+
const resolvedPath = path155.isAbsolute(filePath) ? filePath : path155.resolve(directory, filePath);
|
|
123787
|
+
const resolvedDirectory = path155.resolve(directory);
|
|
123788
|
+
if (!resolvedPath.startsWith(resolvedDirectory + path155.sep) && resolvedPath !== resolvedDirectory) {
|
|
123139
123789
|
_filesSkipped++;
|
|
123140
123790
|
continue;
|
|
123141
123791
|
}
|
|
@@ -123422,11 +124072,11 @@ var sast_scan = createSwarmTool({
|
|
|
123422
124072
|
capture_baseline: safeArgs.capture_baseline,
|
|
123423
124073
|
phase: safeArgs.phase
|
|
123424
124074
|
};
|
|
123425
|
-
const result = await
|
|
124075
|
+
const result = await _internals73.sastScan(input, directory);
|
|
123426
124076
|
return JSON.stringify(result, null, 2);
|
|
123427
124077
|
}
|
|
123428
124078
|
});
|
|
123429
|
-
var
|
|
124079
|
+
var _internals73 = {
|
|
123430
124080
|
sastScan,
|
|
123431
124081
|
sast_scan
|
|
123432
124082
|
};
|
|
@@ -123450,18 +124100,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
|
|
|
123450
124100
|
let resolved;
|
|
123451
124101
|
const isWinAbs = isWindowsAbsolutePath(inputPath);
|
|
123452
124102
|
if (isWinAbs) {
|
|
123453
|
-
resolved =
|
|
123454
|
-
} else if (
|
|
123455
|
-
resolved =
|
|
124103
|
+
resolved = path156.win32.resolve(inputPath);
|
|
124104
|
+
} else if (path156.isAbsolute(inputPath)) {
|
|
124105
|
+
resolved = path156.resolve(inputPath);
|
|
123456
124106
|
} else {
|
|
123457
|
-
resolved =
|
|
124107
|
+
resolved = path156.resolve(baseDir, inputPath);
|
|
123458
124108
|
}
|
|
123459
|
-
const workspaceResolved =
|
|
124109
|
+
const workspaceResolved = path156.resolve(workspaceDir);
|
|
123460
124110
|
let relative31;
|
|
123461
124111
|
if (isWinAbs) {
|
|
123462
|
-
relative31 =
|
|
124112
|
+
relative31 = path156.win32.relative(workspaceResolved, resolved);
|
|
123463
124113
|
} else {
|
|
123464
|
-
relative31 =
|
|
124114
|
+
relative31 = path156.relative(workspaceResolved, resolved);
|
|
123465
124115
|
}
|
|
123466
124116
|
if (relative31.startsWith("..")) {
|
|
123467
124117
|
return "path traversal detected";
|
|
@@ -123526,7 +124176,7 @@ async function runLintOnFiles(linter, files, workspaceDir) {
|
|
|
123526
124176
|
if (typeof file3 !== "string") {
|
|
123527
124177
|
continue;
|
|
123528
124178
|
}
|
|
123529
|
-
const resolvedPath =
|
|
124179
|
+
const resolvedPath = path156.resolve(file3);
|
|
123530
124180
|
const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
|
|
123531
124181
|
if (validationError) {
|
|
123532
124182
|
continue;
|
|
@@ -123683,7 +124333,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
123683
124333
|
skippedFiles++;
|
|
123684
124334
|
continue;
|
|
123685
124335
|
}
|
|
123686
|
-
const resolvedPath =
|
|
124336
|
+
const resolvedPath = path156.resolve(file3);
|
|
123687
124337
|
const validationError = validatePath(resolvedPath, directory, directory);
|
|
123688
124338
|
if (validationError) {
|
|
123689
124339
|
skippedFiles++;
|
|
@@ -123701,7 +124351,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
123701
124351
|
};
|
|
123702
124352
|
}
|
|
123703
124353
|
for (const file3 of validatedFiles) {
|
|
123704
|
-
const ext =
|
|
124354
|
+
const ext = path156.extname(file3).toLowerCase();
|
|
123705
124355
|
if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
|
|
123706
124356
|
skippedFiles++;
|
|
123707
124357
|
continue;
|
|
@@ -123920,7 +124570,7 @@ function classifySastFindings(findings, changedLineRanges, directory) {
|
|
|
123920
124570
|
const preexistingFindings = [];
|
|
123921
124571
|
for (const finding of findings) {
|
|
123922
124572
|
const filePath = finding.location.file;
|
|
123923
|
-
const normalised =
|
|
124573
|
+
const normalised = path156.relative(directory, filePath).replace(/\\/g, "/");
|
|
123924
124574
|
const changedLines = changedLineRanges.get(normalised);
|
|
123925
124575
|
if (changedLines?.has(finding.location.line)) {
|
|
123926
124576
|
newFindings.push(finding);
|
|
@@ -123971,7 +124621,7 @@ async function runPreCheckBatch(input, workspaceDir, contextDir) {
|
|
|
123971
124621
|
warn(`pre_check_batch: Invalid file path: ${file3}`);
|
|
123972
124622
|
continue;
|
|
123973
124623
|
}
|
|
123974
|
-
changedFiles.push(
|
|
124624
|
+
changedFiles.push(path156.resolve(directory, file3));
|
|
123975
124625
|
}
|
|
123976
124626
|
if (changedFiles.length === 0) {
|
|
123977
124627
|
warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
|
|
@@ -124172,9 +124822,9 @@ var pre_check_batch = createSwarmTool({
|
|
|
124172
124822
|
};
|
|
124173
124823
|
return JSON.stringify(errorResult, null, 2);
|
|
124174
124824
|
}
|
|
124175
|
-
const resolvedDirectory =
|
|
124176
|
-
const workspaceAnchor =
|
|
124177
|
-
if (resolvedDirectory !== workspaceAnchor && resolvedDirectory.startsWith(workspaceAnchor +
|
|
124825
|
+
const resolvedDirectory = path156.resolve(typedArgs.directory);
|
|
124826
|
+
const workspaceAnchor = path156.resolve(directory);
|
|
124827
|
+
if (resolvedDirectory !== workspaceAnchor && resolvedDirectory.startsWith(workspaceAnchor + path156.sep)) {
|
|
124178
124828
|
const subDirError = `directory "${typedArgs.directory}" is a subdirectory of the project root — pre_check_batch requires the project root directory "${workspaceAnchor}"`;
|
|
124179
124829
|
const subDirResult = {
|
|
124180
124830
|
gates_passed: false,
|
|
@@ -124226,7 +124876,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
124226
124876
|
|
|
124227
124877
|
// src/tools/repo-map.ts
|
|
124228
124878
|
init_zod();
|
|
124229
|
-
import * as
|
|
124879
|
+
import * as path157 from "node:path";
|
|
124230
124880
|
init_path_security();
|
|
124231
124881
|
init_create_tool();
|
|
124232
124882
|
var VALID_ACTIONS = [
|
|
@@ -124251,7 +124901,7 @@ function validateFile(p) {
|
|
|
124251
124901
|
return "file contains control characters";
|
|
124252
124902
|
if (containsPathTraversal(p))
|
|
124253
124903
|
return "file contains path traversal";
|
|
124254
|
-
if (
|
|
124904
|
+
if (path157.isAbsolute(p) || /^[a-zA-Z]:[\\/]/.test(p)) {
|
|
124255
124905
|
return "file must be a workspace-relative path, not absolute";
|
|
124256
124906
|
}
|
|
124257
124907
|
return null;
|
|
@@ -124274,8 +124924,8 @@ function ok(action, payload) {
|
|
|
124274
124924
|
}
|
|
124275
124925
|
function toRelativeGraphPath(input, workspaceRoot) {
|
|
124276
124926
|
const normalized = input.replace(/\\/g, "/");
|
|
124277
|
-
if (
|
|
124278
|
-
const rel =
|
|
124927
|
+
if (path157.isAbsolute(normalized)) {
|
|
124928
|
+
const rel = path157.relative(workspaceRoot, normalized).replace(/\\/g, "/");
|
|
124279
124929
|
return normalizeGraphPath2(rel);
|
|
124280
124930
|
}
|
|
124281
124931
|
return normalizeGraphPath2(normalized);
|
|
@@ -124421,7 +125071,7 @@ var repo_map = createSwarmTool({
|
|
|
124421
125071
|
init_zod();
|
|
124422
125072
|
init_create_tool();
|
|
124423
125073
|
import * as fs117 from "node:fs";
|
|
124424
|
-
import * as
|
|
125074
|
+
import * as path158 from "node:path";
|
|
124425
125075
|
var SPEC_FILE = ".swarm/spec.md";
|
|
124426
125076
|
var EVIDENCE_DIR4 = ".swarm/evidence";
|
|
124427
125077
|
var OBLIGATION_KEYWORDS2 = ["MUST", "SHOULD", "SHALL"];
|
|
@@ -124490,7 +125140,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
124490
125140
|
return [];
|
|
124491
125141
|
}
|
|
124492
125142
|
for (const entry of entries) {
|
|
124493
|
-
const entryPath =
|
|
125143
|
+
const entryPath = path158.join(evidenceDir, entry);
|
|
124494
125144
|
try {
|
|
124495
125145
|
const stat9 = fs117.statSync(entryPath);
|
|
124496
125146
|
if (!stat9.isDirectory()) {
|
|
@@ -124506,11 +125156,11 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
124506
125156
|
if (entryPhase !== String(phase)) {
|
|
124507
125157
|
continue;
|
|
124508
125158
|
}
|
|
124509
|
-
const evidenceFilePath =
|
|
125159
|
+
const evidenceFilePath = path158.join(entryPath, "evidence.json");
|
|
124510
125160
|
try {
|
|
124511
|
-
const resolvedPath =
|
|
124512
|
-
const evidenceDirResolved =
|
|
124513
|
-
if (!resolvedPath.startsWith(evidenceDirResolved +
|
|
125161
|
+
const resolvedPath = path158.resolve(evidenceFilePath);
|
|
125162
|
+
const evidenceDirResolved = path158.resolve(evidenceDir);
|
|
125163
|
+
if (!resolvedPath.startsWith(evidenceDirResolved + path158.sep)) {
|
|
124514
125164
|
continue;
|
|
124515
125165
|
}
|
|
124516
125166
|
const stat9 = fs117.lstatSync(evidenceFilePath);
|
|
@@ -124544,7 +125194,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
124544
125194
|
if (Array.isArray(diffEntry.files_changed)) {
|
|
124545
125195
|
for (const file3 of diffEntry.files_changed) {
|
|
124546
125196
|
if (typeof file3 === "string") {
|
|
124547
|
-
touchedFiles.add(
|
|
125197
|
+
touchedFiles.add(path158.resolve(cwd, file3));
|
|
124548
125198
|
}
|
|
124549
125199
|
}
|
|
124550
125200
|
}
|
|
@@ -124557,8 +125207,8 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
124557
125207
|
}
|
|
124558
125208
|
function searchFileForKeywords(filePath, keywords, cwd) {
|
|
124559
125209
|
try {
|
|
124560
|
-
const resolvedPath =
|
|
124561
|
-
const cwdResolved =
|
|
125210
|
+
const resolvedPath = path158.resolve(filePath);
|
|
125211
|
+
const cwdResolved = path158.resolve(cwd);
|
|
124562
125212
|
if (!resolvedPath.startsWith(cwdResolved)) {
|
|
124563
125213
|
return false;
|
|
124564
125214
|
}
|
|
@@ -124692,7 +125342,7 @@ var req_coverage = createSwarmTool({
|
|
|
124692
125342
|
}, null, 2);
|
|
124693
125343
|
}
|
|
124694
125344
|
const cwd = inputDirectory || directory;
|
|
124695
|
-
const specPath =
|
|
125345
|
+
const specPath = path158.join(cwd, SPEC_FILE);
|
|
124696
125346
|
let specContent;
|
|
124697
125347
|
try {
|
|
124698
125348
|
specContent = fs117.readFileSync(specPath, "utf-8");
|
|
@@ -124719,7 +125369,7 @@ var req_coverage = createSwarmTool({
|
|
|
124719
125369
|
message: "No FR requirements found in spec.md"
|
|
124720
125370
|
}, null, 2);
|
|
124721
125371
|
}
|
|
124722
|
-
const evidenceDir =
|
|
125372
|
+
const evidenceDir = path158.join(cwd, EVIDENCE_DIR4);
|
|
124723
125373
|
const touchedFiles = readTouchedFiles(evidenceDir, phase, cwd);
|
|
124724
125374
|
const analyzedRequirements = [];
|
|
124725
125375
|
let coveredCount = 0;
|
|
@@ -124745,7 +125395,7 @@ var req_coverage = createSwarmTool({
|
|
|
124745
125395
|
requirements: analyzedRequirements
|
|
124746
125396
|
};
|
|
124747
125397
|
const reportFilename = `req-coverage-phase-${phase}.json`;
|
|
124748
|
-
const reportPath =
|
|
125398
|
+
const reportPath = path158.join(evidenceDir, reportFilename);
|
|
124749
125399
|
try {
|
|
124750
125400
|
if (!fs117.existsSync(evidenceDir)) {
|
|
124751
125401
|
fs117.mkdirSync(evidenceDir, { recursive: true });
|
|
@@ -124835,7 +125485,7 @@ init_qa_gate_profile();
|
|
|
124835
125485
|
init_file_locks();
|
|
124836
125486
|
import * as crypto13 from "node:crypto";
|
|
124837
125487
|
import * as fs118 from "node:fs";
|
|
124838
|
-
import * as
|
|
125488
|
+
import * as path159 from "node:path";
|
|
124839
125489
|
init_ledger();
|
|
124840
125490
|
init_manager();
|
|
124841
125491
|
init_state();
|
|
@@ -124916,8 +125566,8 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
124916
125566
|
};
|
|
124917
125567
|
}
|
|
124918
125568
|
if (args2.working_directory && fallbackDir) {
|
|
124919
|
-
const resolvedTarget =
|
|
124920
|
-
const resolvedRoot =
|
|
125569
|
+
const resolvedTarget = path159.resolve(args2.working_directory);
|
|
125570
|
+
const resolvedRoot = path159.resolve(fallbackDir);
|
|
124921
125571
|
let fallbackExists = false;
|
|
124922
125572
|
try {
|
|
124923
125573
|
fs118.accessSync(resolvedRoot, fs118.constants.F_OK);
|
|
@@ -124926,7 +125576,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
124926
125576
|
fallbackExists = false;
|
|
124927
125577
|
}
|
|
124928
125578
|
if (fallbackExists) {
|
|
124929
|
-
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot +
|
|
125579
|
+
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot + path159.sep);
|
|
124930
125580
|
if (isSubdirectory) {
|
|
124931
125581
|
return {
|
|
124932
125582
|
success: false,
|
|
@@ -124942,7 +125592,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
124942
125592
|
let specMtime;
|
|
124943
125593
|
let specHash;
|
|
124944
125594
|
if (process.env.SWARM_SKIP_SPEC_GATE !== "1") {
|
|
124945
|
-
const specPath =
|
|
125595
|
+
const specPath = path159.join(targetWorkspace, ".swarm", "spec.md");
|
|
124946
125596
|
try {
|
|
124947
125597
|
const stat9 = await fs118.promises.stat(specPath);
|
|
124948
125598
|
specMtime = stat9.mtime.toISOString();
|
|
@@ -124958,7 +125608,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
124958
125608
|
}
|
|
124959
125609
|
}
|
|
124960
125610
|
if (process.env.SWARM_SKIP_GATE_SELECTION !== "1") {
|
|
124961
|
-
const contextPath =
|
|
125611
|
+
const contextPath = path159.join(targetWorkspace, ".swarm", "context.md");
|
|
124962
125612
|
let contextContent = "";
|
|
124963
125613
|
try {
|
|
124964
125614
|
contextContent = await fs118.promises.readFile(contextPath, "utf8");
|
|
@@ -125248,7 +125898,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
125248
125898
|
}
|
|
125249
125899
|
await writeCheckpoint(dir).catch(() => {});
|
|
125250
125900
|
try {
|
|
125251
|
-
const markerPath =
|
|
125901
|
+
const markerPath = path159.join(dir, ".swarm", ".plan-write-marker");
|
|
125252
125902
|
const marker = JSON.stringify({
|
|
125253
125903
|
source: "save_plan",
|
|
125254
125904
|
timestamp: new Date().toISOString(),
|
|
@@ -125271,7 +125921,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
125271
125921
|
return {
|
|
125272
125922
|
success: true,
|
|
125273
125923
|
message: "Plan saved successfully",
|
|
125274
|
-
plan_path:
|
|
125924
|
+
plan_path: path159.join(dir, ".swarm", "plan.json"),
|
|
125275
125925
|
phases_count: plan.phases.length,
|
|
125276
125926
|
tasks_count: tasksCount,
|
|
125277
125927
|
...resolvedProfile !== undefined ? { execution_profile: resolvedProfile } : {},
|
|
@@ -125338,7 +125988,7 @@ var save_plan = createSwarmTool({
|
|
|
125338
125988
|
init_zod();
|
|
125339
125989
|
init_manager2();
|
|
125340
125990
|
import * as fs119 from "node:fs";
|
|
125341
|
-
import * as
|
|
125991
|
+
import * as path160 from "node:path";
|
|
125342
125992
|
|
|
125343
125993
|
// src/sbom/detectors/index.ts
|
|
125344
125994
|
init_utils();
|
|
@@ -126188,7 +126838,7 @@ function findManifestFiles(rootDir) {
|
|
|
126188
126838
|
try {
|
|
126189
126839
|
const entries = fs119.readdirSync(dir, { withFileTypes: true });
|
|
126190
126840
|
for (const entry of entries) {
|
|
126191
|
-
const fullPath =
|
|
126841
|
+
const fullPath = path160.join(dir, entry.name);
|
|
126192
126842
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
|
|
126193
126843
|
continue;
|
|
126194
126844
|
}
|
|
@@ -126197,7 +126847,7 @@ function findManifestFiles(rootDir) {
|
|
|
126197
126847
|
} else if (entry.isFile()) {
|
|
126198
126848
|
for (const pattern of patterns) {
|
|
126199
126849
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
126200
|
-
manifestFiles.push(
|
|
126850
|
+
manifestFiles.push(path160.relative(rootDir, fullPath));
|
|
126201
126851
|
break;
|
|
126202
126852
|
}
|
|
126203
126853
|
}
|
|
@@ -126215,11 +126865,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
126215
126865
|
try {
|
|
126216
126866
|
const entries = fs119.readdirSync(dir, { withFileTypes: true });
|
|
126217
126867
|
for (const entry of entries) {
|
|
126218
|
-
const fullPath =
|
|
126868
|
+
const fullPath = path160.join(dir, entry.name);
|
|
126219
126869
|
if (entry.isFile()) {
|
|
126220
126870
|
for (const pattern of patterns) {
|
|
126221
126871
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
126222
|
-
found.push(
|
|
126872
|
+
found.push(path160.relative(workingDir, fullPath));
|
|
126223
126873
|
break;
|
|
126224
126874
|
}
|
|
126225
126875
|
}
|
|
@@ -126232,11 +126882,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
126232
126882
|
function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
126233
126883
|
const dirs = new Set;
|
|
126234
126884
|
for (const file3 of changedFiles) {
|
|
126235
|
-
let currentDir =
|
|
126885
|
+
let currentDir = path160.dirname(file3);
|
|
126236
126886
|
while (true) {
|
|
126237
|
-
if (currentDir && currentDir !== "." && currentDir !==
|
|
126238
|
-
dirs.add(
|
|
126239
|
-
const parent =
|
|
126887
|
+
if (currentDir && currentDir !== "." && currentDir !== path160.sep) {
|
|
126888
|
+
dirs.add(path160.join(workingDir, currentDir));
|
|
126889
|
+
const parent = path160.dirname(currentDir);
|
|
126240
126890
|
if (parent === currentDir)
|
|
126241
126891
|
break;
|
|
126242
126892
|
currentDir = parent;
|
|
@@ -126320,7 +126970,7 @@ var sbom_generate = createSwarmTool({
|
|
|
126320
126970
|
const changedFiles = obj.changed_files;
|
|
126321
126971
|
const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
|
|
126322
126972
|
const workingDir = directory;
|
|
126323
|
-
const outputDir =
|
|
126973
|
+
const outputDir = path160.isAbsolute(relativeOutputDir) ? relativeOutputDir : path160.join(workingDir, relativeOutputDir);
|
|
126324
126974
|
let manifestFiles = [];
|
|
126325
126975
|
if (scope === "all") {
|
|
126326
126976
|
manifestFiles = findManifestFiles(workingDir);
|
|
@@ -126343,7 +126993,7 @@ var sbom_generate = createSwarmTool({
|
|
|
126343
126993
|
const processedFiles = [];
|
|
126344
126994
|
for (const manifestFile of manifestFiles) {
|
|
126345
126995
|
try {
|
|
126346
|
-
const fullPath =
|
|
126996
|
+
const fullPath = path160.isAbsolute(manifestFile) ? manifestFile : path160.join(workingDir, manifestFile);
|
|
126347
126997
|
if (!fs119.existsSync(fullPath)) {
|
|
126348
126998
|
continue;
|
|
126349
126999
|
}
|
|
@@ -126360,7 +127010,7 @@ var sbom_generate = createSwarmTool({
|
|
|
126360
127010
|
const bom = generateCycloneDX(allComponents);
|
|
126361
127011
|
const bomJson = serializeCycloneDX(bom);
|
|
126362
127012
|
const filename = generateSbomFilename();
|
|
126363
|
-
const outputPath =
|
|
127013
|
+
const outputPath = path160.join(outputDir, filename);
|
|
126364
127014
|
fs119.writeFileSync(outputPath, bomJson, "utf-8");
|
|
126365
127015
|
const verdict = processedFiles.length > 0 ? "pass" : "pass";
|
|
126366
127016
|
try {
|
|
@@ -126405,7 +127055,7 @@ var sbom_generate = createSwarmTool({
|
|
|
126405
127055
|
init_zod();
|
|
126406
127056
|
init_create_tool();
|
|
126407
127057
|
import * as fs120 from "node:fs";
|
|
126408
|
-
import * as
|
|
127058
|
+
import * as path161 from "node:path";
|
|
126409
127059
|
var SPEC_CANDIDATES = [
|
|
126410
127060
|
"openapi.json",
|
|
126411
127061
|
"openapi.yaml",
|
|
@@ -126437,12 +127087,12 @@ function normalizePath5(p) {
|
|
|
126437
127087
|
}
|
|
126438
127088
|
function discoverSpecFile(cwd, specFileArg) {
|
|
126439
127089
|
if (specFileArg) {
|
|
126440
|
-
const resolvedPath =
|
|
126441
|
-
const normalizedCwd = cwd.endsWith(
|
|
127090
|
+
const resolvedPath = path161.resolve(cwd, specFileArg);
|
|
127091
|
+
const normalizedCwd = cwd.endsWith(path161.sep) ? cwd : cwd + path161.sep;
|
|
126442
127092
|
if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
|
|
126443
127093
|
throw new Error("Invalid spec_file: path traversal detected");
|
|
126444
127094
|
}
|
|
126445
|
-
const ext =
|
|
127095
|
+
const ext = path161.extname(resolvedPath).toLowerCase();
|
|
126446
127096
|
if (!ALLOWED_EXTENSIONS.includes(ext)) {
|
|
126447
127097
|
throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
|
|
126448
127098
|
}
|
|
@@ -126456,7 +127106,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
126456
127106
|
return resolvedPath;
|
|
126457
127107
|
}
|
|
126458
127108
|
for (const candidate of SPEC_CANDIDATES) {
|
|
126459
|
-
const candidatePath =
|
|
127109
|
+
const candidatePath = path161.resolve(cwd, candidate);
|
|
126460
127110
|
if (fs120.existsSync(candidatePath)) {
|
|
126461
127111
|
const stats = fs120.statSync(candidatePath);
|
|
126462
127112
|
if (stats.size <= MAX_SPEC_SIZE) {
|
|
@@ -126468,7 +127118,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
126468
127118
|
}
|
|
126469
127119
|
function parseSpec(specFile) {
|
|
126470
127120
|
const content = fs120.readFileSync(specFile, "utf-8");
|
|
126471
|
-
const ext =
|
|
127121
|
+
const ext = path161.extname(specFile).toLowerCase();
|
|
126472
127122
|
if (ext === ".json") {
|
|
126473
127123
|
return parseJsonSpec(content);
|
|
126474
127124
|
}
|
|
@@ -126544,7 +127194,7 @@ function extractRoutes(cwd) {
|
|
|
126544
127194
|
return;
|
|
126545
127195
|
}
|
|
126546
127196
|
for (const entry of entries) {
|
|
126547
|
-
const fullPath =
|
|
127197
|
+
const fullPath = path161.join(dir, entry.name);
|
|
126548
127198
|
if (entry.isSymbolicLink()) {
|
|
126549
127199
|
continue;
|
|
126550
127200
|
}
|
|
@@ -126554,7 +127204,7 @@ function extractRoutes(cwd) {
|
|
|
126554
127204
|
}
|
|
126555
127205
|
walkDir2(fullPath);
|
|
126556
127206
|
} else if (entry.isFile()) {
|
|
126557
|
-
const ext =
|
|
127207
|
+
const ext = path161.extname(entry.name).toLowerCase();
|
|
126558
127208
|
const baseName = entry.name.toLowerCase();
|
|
126559
127209
|
if (![".ts", ".js", ".mjs"].includes(ext)) {
|
|
126560
127210
|
continue;
|
|
@@ -126723,7 +127373,7 @@ init_bun_compat();
|
|
|
126723
127373
|
init_path_security();
|
|
126724
127374
|
init_create_tool();
|
|
126725
127375
|
import * as fs121 from "node:fs";
|
|
126726
|
-
import * as
|
|
127376
|
+
import * as path162 from "node:path";
|
|
126727
127377
|
var DEFAULT_MAX_RESULTS = 100;
|
|
126728
127378
|
var DEFAULT_MAX_LINES = 200;
|
|
126729
127379
|
var REGEX_TIMEOUT_MS = 5000;
|
|
@@ -126759,11 +127409,11 @@ function containsWindowsAttacks4(str) {
|
|
|
126759
127409
|
}
|
|
126760
127410
|
function isPathInWorkspace3(filePath, workspace) {
|
|
126761
127411
|
try {
|
|
126762
|
-
const resolvedPath =
|
|
127412
|
+
const resolvedPath = path162.resolve(workspace, filePath);
|
|
126763
127413
|
const realWorkspace = fs121.realpathSync(workspace);
|
|
126764
127414
|
const realResolvedPath = fs121.realpathSync(resolvedPath);
|
|
126765
|
-
const relativePath =
|
|
126766
|
-
if (relativePath.startsWith("..") ||
|
|
127415
|
+
const relativePath = path162.relative(realWorkspace, realResolvedPath);
|
|
127416
|
+
if (relativePath.startsWith("..") || path162.isAbsolute(relativePath)) {
|
|
126767
127417
|
return false;
|
|
126768
127418
|
}
|
|
126769
127419
|
return true;
|
|
@@ -126776,11 +127426,11 @@ function validatePathForRead2(filePath, workspace) {
|
|
|
126776
127426
|
}
|
|
126777
127427
|
function findRgInEnvPath() {
|
|
126778
127428
|
const searchPath = process.env.PATH ?? "";
|
|
126779
|
-
for (const dir of searchPath.split(
|
|
127429
|
+
for (const dir of searchPath.split(path162.delimiter)) {
|
|
126780
127430
|
if (!dir)
|
|
126781
127431
|
continue;
|
|
126782
127432
|
const isWindows = process.platform === "win32";
|
|
126783
|
-
const candidate =
|
|
127433
|
+
const candidate = path162.join(dir, isWindows ? "rg.exe" : "rg");
|
|
126784
127434
|
if (fs121.existsSync(candidate))
|
|
126785
127435
|
return candidate;
|
|
126786
127436
|
}
|
|
@@ -126835,7 +127485,7 @@ async function ripgrepSearch(opts) {
|
|
|
126835
127485
|
stderr: "pipe",
|
|
126836
127486
|
cwd: opts.workspace
|
|
126837
127487
|
});
|
|
126838
|
-
const timeout = new Promise((
|
|
127488
|
+
const timeout = new Promise((resolve61) => setTimeout(() => resolve61("timeout"), REGEX_TIMEOUT_MS));
|
|
126839
127489
|
const exitPromise = proc.exited;
|
|
126840
127490
|
const result = await Promise.race([exitPromise, timeout]);
|
|
126841
127491
|
if (result === "timeout") {
|
|
@@ -126910,8 +127560,8 @@ function collectFiles(dir, workspace, includeGlobs, excludeGlobs) {
|
|
|
126910
127560
|
try {
|
|
126911
127561
|
const entries = fs121.readdirSync(dir, { withFileTypes: true });
|
|
126912
127562
|
for (const entry of entries) {
|
|
126913
|
-
const fullPath =
|
|
126914
|
-
const relativePath =
|
|
127563
|
+
const fullPath = path162.join(dir, entry.name);
|
|
127564
|
+
const relativePath = path162.relative(workspace, fullPath);
|
|
126915
127565
|
if (!validatePathForRead2(fullPath, workspace)) {
|
|
126916
127566
|
continue;
|
|
126917
127567
|
}
|
|
@@ -126952,7 +127602,7 @@ async function fallbackSearch(opts) {
|
|
|
126952
127602
|
const matches = [];
|
|
126953
127603
|
let total = 0;
|
|
126954
127604
|
for (const file3 of files) {
|
|
126955
|
-
const fullPath =
|
|
127605
|
+
const fullPath = path162.join(opts.workspace, file3);
|
|
126956
127606
|
if (!validatePathForRead2(fullPath, opts.workspace)) {
|
|
126957
127607
|
continue;
|
|
126958
127608
|
}
|
|
@@ -127365,7 +128015,7 @@ init_config();
|
|
|
127365
128015
|
init_schema();
|
|
127366
128016
|
init_create_tool();
|
|
127367
128017
|
import { mkdir as mkdir23, rename as rename10, writeFile as writeFile16 } from "node:fs/promises";
|
|
127368
|
-
import * as
|
|
128018
|
+
import * as path163 from "node:path";
|
|
127369
128019
|
var MAX_SPEC_BYTES = 256 * 1024;
|
|
127370
128020
|
var spec_write = createSwarmTool({
|
|
127371
128021
|
description: "Write the canonical project spec to .swarm/spec.md. Atomic write, size-bounded (256 KiB), heading-required. Honors spec_writer.allow_spec_write.",
|
|
@@ -127406,8 +128056,8 @@ var spec_write = createSwarmTool({
|
|
|
127406
128056
|
reason: 'spec must contain at least one top-level "# Heading"'
|
|
127407
128057
|
}, null, 2);
|
|
127408
128058
|
}
|
|
127409
|
-
const target =
|
|
127410
|
-
await mkdir23(
|
|
128059
|
+
const target = path163.join(directory, ".swarm", "spec.md");
|
|
128060
|
+
await mkdir23(path163.dirname(target), { recursive: true });
|
|
127411
128061
|
const tmp = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
127412
128062
|
let finalContent = content;
|
|
127413
128063
|
if (mode === "append") {
|
|
@@ -127443,7 +128093,7 @@ import {
|
|
|
127443
128093
|
unlinkSync as unlinkSync21,
|
|
127444
128094
|
writeFileSync as writeFileSync32
|
|
127445
128095
|
} from "node:fs";
|
|
127446
|
-
import
|
|
128096
|
+
import path164 from "node:path";
|
|
127447
128097
|
init_create_tool();
|
|
127448
128098
|
init_resolve_working_directory();
|
|
127449
128099
|
var VerdictSchema2 = exports_external.object({
|
|
@@ -127587,7 +128237,7 @@ var submit_phase_council_verdicts = createSwarmTool({
|
|
|
127587
128237
|
}
|
|
127588
128238
|
});
|
|
127589
128239
|
function getPhaseMutationGapFinding(phaseNumber, workingDir) {
|
|
127590
|
-
const mutationGatePath =
|
|
128240
|
+
const mutationGatePath = path164.join(workingDir, ".swarm", "evidence", String(phaseNumber), "mutation-gate.json");
|
|
127591
128241
|
try {
|
|
127592
128242
|
const raw = readFileSync81(mutationGatePath, "utf-8");
|
|
127593
128243
|
const parsed = JSON.parse(raw);
|
|
@@ -127649,9 +128299,9 @@ function getPhaseMutationGapFinding(phaseNumber, workingDir) {
|
|
|
127649
128299
|
}
|
|
127650
128300
|
}
|
|
127651
128301
|
function writePhaseCouncilEvidence(workingDir, synthesis) {
|
|
127652
|
-
const evidenceDir =
|
|
128302
|
+
const evidenceDir = path164.join(workingDir, ".swarm", "evidence", String(synthesis.phaseNumber));
|
|
127653
128303
|
mkdirSync41(evidenceDir, { recursive: true });
|
|
127654
|
-
const evidenceFile =
|
|
128304
|
+
const evidenceFile = path164.join(evidenceDir, "phase-council.json");
|
|
127655
128305
|
const evidenceBundle = {
|
|
127656
128306
|
entries: [
|
|
127657
128307
|
{
|
|
@@ -127713,7 +128363,7 @@ init_zod();
|
|
|
127713
128363
|
init_path_security();
|
|
127714
128364
|
init_create_tool();
|
|
127715
128365
|
import * as fs122 from "node:fs";
|
|
127716
|
-
import * as
|
|
128366
|
+
import * as path165 from "node:path";
|
|
127717
128367
|
var BINARY_EXTENSIONS2 = new Set([
|
|
127718
128368
|
".png",
|
|
127719
128369
|
".jpg",
|
|
@@ -127749,14 +128399,14 @@ function containsWindowsAttacks5(str) {
|
|
|
127749
128399
|
}
|
|
127750
128400
|
function isPathInWorkspace4(filePath, workspace) {
|
|
127751
128401
|
try {
|
|
127752
|
-
const resolvedPath =
|
|
128402
|
+
const resolvedPath = path165.resolve(workspace, filePath);
|
|
127753
128403
|
if (!fs122.existsSync(resolvedPath)) {
|
|
127754
128404
|
return true;
|
|
127755
128405
|
}
|
|
127756
128406
|
const realWorkspace = fs122.realpathSync(workspace);
|
|
127757
128407
|
const realResolvedPath = fs122.realpathSync(resolvedPath);
|
|
127758
|
-
const relativePath =
|
|
127759
|
-
if (relativePath.startsWith("..") ||
|
|
128408
|
+
const relativePath = path165.relative(realWorkspace, realResolvedPath);
|
|
128409
|
+
if (relativePath.startsWith("..") || path165.isAbsolute(relativePath)) {
|
|
127760
128410
|
return false;
|
|
127761
128411
|
}
|
|
127762
128412
|
return true;
|
|
@@ -127871,7 +128521,7 @@ function arraysEqual2(a, b) {
|
|
|
127871
128521
|
return true;
|
|
127872
128522
|
}
|
|
127873
128523
|
function isBinaryFile4(filePath) {
|
|
127874
|
-
const ext =
|
|
128524
|
+
const ext = path165.extname(filePath).toLowerCase();
|
|
127875
128525
|
return BINARY_EXTENSIONS2.has(ext);
|
|
127876
128526
|
}
|
|
127877
128527
|
function splitDiffLines(content) {
|
|
@@ -128076,7 +128726,7 @@ var suggestPatch = createSwarmTool({
|
|
|
128076
128726
|
});
|
|
128077
128727
|
continue;
|
|
128078
128728
|
}
|
|
128079
|
-
const fullPath =
|
|
128729
|
+
const fullPath = path165.resolve(directory, change.file);
|
|
128080
128730
|
if (!fs122.existsSync(fullPath)) {
|
|
128081
128731
|
errors5.push({
|
|
128082
128732
|
success: false,
|
|
@@ -128171,7 +128821,7 @@ var suggestPatch = createSwarmTool({
|
|
|
128171
128821
|
const unifiedParts = [];
|
|
128172
128822
|
for (const [file3, entries] of fileGroups) {
|
|
128173
128823
|
entries.sort((a, b) => a.contextMatch.startLineIndex - b.contextMatch.startLineIndex);
|
|
128174
|
-
const entryFullPath =
|
|
128824
|
+
const entryFullPath = path165.resolve(directory, file3);
|
|
128175
128825
|
let entryContent;
|
|
128176
128826
|
try {
|
|
128177
128827
|
entryContent = fs122.readFileSync(entryFullPath, "utf-8");
|
|
@@ -128372,7 +129022,7 @@ var swarm_memory_propose = createSwarmTool({
|
|
|
128372
129022
|
evidenceRefs: exports_external.array(exports_external.string().min(1).max(500)).max(20).optional().describe("Evidence refs such as files, commits, test outputs, or URLs")
|
|
128373
129023
|
},
|
|
128374
129024
|
execute: async (args2, directory, ctx) => {
|
|
128375
|
-
const { config: config3 } =
|
|
129025
|
+
const { config: config3 } = _internals74.loadPluginConfigWithMeta(directory);
|
|
128376
129026
|
if (config3.memory?.enabled !== true) {
|
|
128377
129027
|
return JSON.stringify({
|
|
128378
129028
|
success: false,
|
|
@@ -128388,7 +129038,7 @@ var swarm_memory_propose = createSwarmTool({
|
|
|
128388
129038
|
});
|
|
128389
129039
|
}
|
|
128390
129040
|
const agent = getContextAgent2(ctx);
|
|
128391
|
-
const gateway =
|
|
129041
|
+
const gateway = _internals74.createMemoryGateway({
|
|
128392
129042
|
directory,
|
|
128393
129043
|
sessionID: ctx?.sessionID,
|
|
128394
129044
|
agentRole: agent,
|
|
@@ -128413,7 +129063,7 @@ var swarm_memory_propose = createSwarmTool({
|
|
|
128413
129063
|
}
|
|
128414
129064
|
}
|
|
128415
129065
|
});
|
|
128416
|
-
var
|
|
129066
|
+
var _internals74 = {
|
|
128417
129067
|
loadPluginConfigWithMeta,
|
|
128418
129068
|
createMemoryGateway
|
|
128419
129069
|
};
|
|
@@ -128451,7 +129101,7 @@ var swarm_memory_recall = createSwarmTool({
|
|
|
128451
129101
|
maxItems: exports_external.number().int().min(1).max(20).optional().describe("Maximum memories to return")
|
|
128452
129102
|
},
|
|
128453
129103
|
execute: async (args2, directory, ctx) => {
|
|
128454
|
-
const { config: config3 } =
|
|
129104
|
+
const { config: config3 } = _internals75.loadPluginConfigWithMeta(directory);
|
|
128455
129105
|
if (config3.memory?.enabled !== true) {
|
|
128456
129106
|
return JSON.stringify({
|
|
128457
129107
|
success: false,
|
|
@@ -128467,7 +129117,7 @@ var swarm_memory_recall = createSwarmTool({
|
|
|
128467
129117
|
});
|
|
128468
129118
|
}
|
|
128469
129119
|
const agent = getContextAgent3(ctx);
|
|
128470
|
-
const gateway =
|
|
129120
|
+
const gateway = _internals75.createMemoryGateway({
|
|
128471
129121
|
directory,
|
|
128472
129122
|
sessionID: ctx?.sessionID,
|
|
128473
129123
|
agentRole: agent,
|
|
@@ -128500,7 +129150,7 @@ var RecallArgsSchema = exports_external.object({
|
|
|
128500
129150
|
kinds: exports_external.array(exports_external.enum(MEMORY_KINDS2)).optional(),
|
|
128501
129151
|
maxItems: exports_external.number().int().min(1).max(20).optional()
|
|
128502
129152
|
});
|
|
128503
|
-
var
|
|
129153
|
+
var _internals75 = {
|
|
128504
129154
|
loadPluginConfigWithMeta,
|
|
128505
129155
|
createMemoryGateway
|
|
128506
129156
|
};
|
|
@@ -128513,7 +129163,7 @@ function getContextAgent3(ctx) {
|
|
|
128513
129163
|
|
|
128514
129164
|
// src/tools/syntax-check.ts
|
|
128515
129165
|
import * as fs123 from "node:fs";
|
|
128516
|
-
import * as
|
|
129166
|
+
import * as path166 from "node:path";
|
|
128517
129167
|
init_zod();
|
|
128518
129168
|
init_manager2();
|
|
128519
129169
|
init_detector();
|
|
@@ -128585,7 +129235,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
128585
129235
|
if (languages?.length) {
|
|
128586
129236
|
const lowerLangs = languages.map((l) => l.toLowerCase());
|
|
128587
129237
|
filesToCheck = filesToCheck.filter((file3) => {
|
|
128588
|
-
const ext =
|
|
129238
|
+
const ext = path166.extname(file3.path).toLowerCase();
|
|
128589
129239
|
const langDef = getLanguageForExtension(ext);
|
|
128590
129240
|
const fileProfile = getProfileForFile(file3.path);
|
|
128591
129241
|
const langId = fileProfile?.id || langDef?.id;
|
|
@@ -128595,7 +129245,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
128595
129245
|
const { loadGrammar: loadGrammar2 } = await Promise.resolve().then(() => (init_runtime(), exports_runtime));
|
|
128596
129246
|
async function checkOneFile(fileInfo) {
|
|
128597
129247
|
const { path: filePath } = fileInfo;
|
|
128598
|
-
const fullPath =
|
|
129248
|
+
const fullPath = path166.isAbsolute(filePath) ? filePath : path166.join(directory, filePath);
|
|
128599
129249
|
const result = {
|
|
128600
129250
|
path: filePath,
|
|
128601
129251
|
language: "",
|
|
@@ -128642,7 +129292,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
128642
129292
|
result.skipped_reason = "binary_file";
|
|
128643
129293
|
return { result, counted: false, failed: false, skipped: true };
|
|
128644
129294
|
}
|
|
128645
|
-
const ext =
|
|
129295
|
+
const ext = path166.extname(filePath).toLowerCase();
|
|
128646
129296
|
const langDef = getLanguageForExtension(ext);
|
|
128647
129297
|
result.language = profile?.id || langDef?.id || "unknown";
|
|
128648
129298
|
const errors5 = extractSyntaxErrors(parser, content);
|
|
@@ -128754,7 +129404,7 @@ init_utils();
|
|
|
128754
129404
|
init_create_tool();
|
|
128755
129405
|
init_path_security();
|
|
128756
129406
|
import * as fs124 from "node:fs";
|
|
128757
|
-
import * as
|
|
129407
|
+
import * as path167 from "node:path";
|
|
128758
129408
|
var MAX_TEXT_LENGTH = 200;
|
|
128759
129409
|
var MAX_FILE_SIZE_BYTES11 = 1024 * 1024;
|
|
128760
129410
|
var SUPPORTED_EXTENSIONS4 = new Set([
|
|
@@ -128820,9 +129470,9 @@ function validatePathsInput(paths, cwd) {
|
|
|
128820
129470
|
return { error: "paths contains path traversal", resolvedPath: null };
|
|
128821
129471
|
}
|
|
128822
129472
|
try {
|
|
128823
|
-
const resolvedPath =
|
|
128824
|
-
const normalizedCwd =
|
|
128825
|
-
const normalizedResolved =
|
|
129473
|
+
const resolvedPath = path167.resolve(paths);
|
|
129474
|
+
const normalizedCwd = path167.resolve(cwd);
|
|
129475
|
+
const normalizedResolved = path167.resolve(resolvedPath);
|
|
128826
129476
|
if (!normalizedResolved.startsWith(normalizedCwd)) {
|
|
128827
129477
|
return {
|
|
128828
129478
|
error: "paths must be within the current working directory",
|
|
@@ -128838,7 +129488,7 @@ function validatePathsInput(paths, cwd) {
|
|
|
128838
129488
|
}
|
|
128839
129489
|
}
|
|
128840
129490
|
function isSupportedExtension(filePath) {
|
|
128841
|
-
const ext =
|
|
129491
|
+
const ext = path167.extname(filePath).toLowerCase();
|
|
128842
129492
|
return SUPPORTED_EXTENSIONS4.has(ext);
|
|
128843
129493
|
}
|
|
128844
129494
|
function findSourceFiles4(dir, files = []) {
|
|
@@ -128853,7 +129503,7 @@ function findSourceFiles4(dir, files = []) {
|
|
|
128853
129503
|
if (SKIP_DIRECTORIES6.has(entry)) {
|
|
128854
129504
|
continue;
|
|
128855
129505
|
}
|
|
128856
|
-
const fullPath =
|
|
129506
|
+
const fullPath = path167.join(dir, entry);
|
|
128857
129507
|
let stat9;
|
|
128858
129508
|
try {
|
|
128859
129509
|
stat9 = fs124.statSync(fullPath);
|
|
@@ -128965,7 +129615,7 @@ var todo_extract = createSwarmTool({
|
|
|
128965
129615
|
filesToScan.push(scanPath);
|
|
128966
129616
|
} else {
|
|
128967
129617
|
const errorResult = {
|
|
128968
|
-
error: `unsupported file extension: ${
|
|
129618
|
+
error: `unsupported file extension: ${path167.extname(scanPath)}`,
|
|
128969
129619
|
total: 0,
|
|
128970
129620
|
byPriority: { high: 0, medium: 0, low: 0 },
|
|
128971
129621
|
entries: []
|
|
@@ -129015,18 +129665,18 @@ init_schema();
|
|
|
129015
129665
|
init_qa_gate_profile();
|
|
129016
129666
|
init_gate_evidence();
|
|
129017
129667
|
import * as fs128 from "node:fs";
|
|
129018
|
-
import * as
|
|
129668
|
+
import * as path171 from "node:path";
|
|
129019
129669
|
|
|
129020
129670
|
// src/hooks/diff-scope.ts
|
|
129021
129671
|
init_bun_compat();
|
|
129022
129672
|
import * as fs126 from "node:fs";
|
|
129023
|
-
import * as
|
|
129673
|
+
import * as path169 from "node:path";
|
|
129024
129674
|
|
|
129025
129675
|
// src/utils/gitignore-warning.ts
|
|
129026
129676
|
init_bun_compat();
|
|
129027
129677
|
import * as fs125 from "node:fs";
|
|
129028
|
-
import * as
|
|
129029
|
-
var
|
|
129678
|
+
import * as path168 from "node:path";
|
|
129679
|
+
var _internals76 = { bunSpawn };
|
|
129030
129680
|
var _swarmGitExcludedChecked = false;
|
|
129031
129681
|
function fileCoversSwarm(content) {
|
|
129032
129682
|
for (const rawLine of content.split(`
|
|
@@ -129059,7 +129709,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
129059
129709
|
checkIgnoreExitCode
|
|
129060
129710
|
] = await Promise.all([
|
|
129061
129711
|
(async () => {
|
|
129062
|
-
const proc =
|
|
129712
|
+
const proc = _internals76.bunSpawn(["git", "-C", directory, "rev-parse", "--show-toplevel"], GIT_SPAWN_OPTIONS);
|
|
129063
129713
|
try {
|
|
129064
129714
|
return await Promise.all([proc.exited, proc.stdout.text()]);
|
|
129065
129715
|
} finally {
|
|
@@ -129069,7 +129719,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
129069
129719
|
}
|
|
129070
129720
|
})(),
|
|
129071
129721
|
(async () => {
|
|
129072
|
-
const proc =
|
|
129722
|
+
const proc = _internals76.bunSpawn(["git", "-C", directory, "rev-parse", "--git-path", "info/exclude"], GIT_SPAWN_OPTIONS);
|
|
129073
129723
|
try {
|
|
129074
129724
|
return await Promise.all([proc.exited, proc.stdout.text()]);
|
|
129075
129725
|
} finally {
|
|
@@ -129079,7 +129729,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
129079
129729
|
}
|
|
129080
129730
|
})(),
|
|
129081
129731
|
(async () => {
|
|
129082
|
-
const proc =
|
|
129732
|
+
const proc = _internals76.bunSpawn(["git", "-C", directory, "check-ignore", "-q", ".swarm/.gitkeep"], GIT_SPAWN_OPTIONS);
|
|
129083
129733
|
try {
|
|
129084
129734
|
return await proc.exited;
|
|
129085
129735
|
} finally {
|
|
@@ -129099,10 +129749,10 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
129099
129749
|
const excludeRelPath = excludePathRaw.trim();
|
|
129100
129750
|
if (!excludeRelPath)
|
|
129101
129751
|
return;
|
|
129102
|
-
const excludePath =
|
|
129752
|
+
const excludePath = path168.isAbsolute(excludeRelPath) ? excludeRelPath : path168.join(directory, excludeRelPath);
|
|
129103
129753
|
if (checkIgnoreExitCode !== 0) {
|
|
129104
129754
|
try {
|
|
129105
|
-
fs125.mkdirSync(
|
|
129755
|
+
fs125.mkdirSync(path168.dirname(excludePath), { recursive: true });
|
|
129106
129756
|
let existing = "";
|
|
129107
129757
|
try {
|
|
129108
129758
|
existing = fs125.readFileSync(excludePath, "utf8");
|
|
@@ -129118,7 +129768,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
129118
129768
|
}
|
|
129119
129769
|
} catch {}
|
|
129120
129770
|
}
|
|
129121
|
-
const trackedProc =
|
|
129771
|
+
const trackedProc = _internals76.bunSpawn(["git", "-C", directory, "ls-files", "--", ".swarm"], GIT_SPAWN_OPTIONS);
|
|
129122
129772
|
let trackedExitCode;
|
|
129123
129773
|
let trackedOutput;
|
|
129124
129774
|
try {
|
|
@@ -129143,10 +129793,10 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
129143
129793
|
}
|
|
129144
129794
|
|
|
129145
129795
|
// src/hooks/diff-scope.ts
|
|
129146
|
-
var
|
|
129796
|
+
var _internals77 = { bunSpawn };
|
|
129147
129797
|
function getDeclaredScope(taskId, directory) {
|
|
129148
129798
|
try {
|
|
129149
|
-
const planPath =
|
|
129799
|
+
const planPath = path169.join(directory, ".swarm", "plan.json");
|
|
129150
129800
|
if (!fs126.existsSync(planPath))
|
|
129151
129801
|
return null;
|
|
129152
129802
|
const raw = fs126.readFileSync(planPath, "utf-8");
|
|
@@ -129178,7 +129828,7 @@ var GIT_DIFF_SPAWN_OPTIONS = {
|
|
|
129178
129828
|
};
|
|
129179
129829
|
async function getChangedFiles(directory) {
|
|
129180
129830
|
try {
|
|
129181
|
-
const proc =
|
|
129831
|
+
const proc = _internals77.bunSpawn(["git", "diff", "--name-only", "HEAD~1"], {
|
|
129182
129832
|
cwd: directory,
|
|
129183
129833
|
...GIT_DIFF_SPAWN_OPTIONS
|
|
129184
129834
|
});
|
|
@@ -129195,7 +129845,7 @@ async function getChangedFiles(directory) {
|
|
|
129195
129845
|
return stdout.trim().split(`
|
|
129196
129846
|
`).map((f) => f.trim()).filter((f) => f.length > 0);
|
|
129197
129847
|
}
|
|
129198
|
-
const proc2 =
|
|
129848
|
+
const proc2 = _internals77.bunSpawn(["git", "diff", "--name-only", "HEAD"], {
|
|
129199
129849
|
cwd: directory,
|
|
129200
129850
|
...GIT_DIFF_SPAWN_OPTIONS
|
|
129201
129851
|
});
|
|
@@ -129252,8 +129902,8 @@ init_telemetry();
|
|
|
129252
129902
|
// src/turbo/lean/task-completion.ts
|
|
129253
129903
|
init_file_locks();
|
|
129254
129904
|
import * as fs127 from "node:fs";
|
|
129255
|
-
import * as
|
|
129256
|
-
var
|
|
129905
|
+
import * as path170 from "node:path";
|
|
129906
|
+
var _internals78 = {
|
|
129257
129907
|
listActiveLocks,
|
|
129258
129908
|
verifyLeanTurboTaskCompletion
|
|
129259
129909
|
};
|
|
@@ -129271,7 +129921,7 @@ var TIER_3_PATTERNS = [
|
|
|
129271
129921
|
];
|
|
129272
129922
|
function matchesTier3Pattern(files) {
|
|
129273
129923
|
for (const file3 of files) {
|
|
129274
|
-
const fileName =
|
|
129924
|
+
const fileName = path170.basename(file3);
|
|
129275
129925
|
for (const pattern of TIER_3_PATTERNS) {
|
|
129276
129926
|
if (pattern.test(fileName)) {
|
|
129277
129927
|
return true;
|
|
@@ -129283,7 +129933,7 @@ function matchesTier3Pattern(files) {
|
|
|
129283
129933
|
function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
129284
129934
|
let persisted = null;
|
|
129285
129935
|
try {
|
|
129286
|
-
const statePath =
|
|
129936
|
+
const statePath = path170.join(directory, ".swarm", "turbo-state.json");
|
|
129287
129937
|
if (!fs127.existsSync(statePath)) {
|
|
129288
129938
|
return {
|
|
129289
129939
|
ok: false,
|
|
@@ -129367,11 +130017,11 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
129367
130017
|
};
|
|
129368
130018
|
}
|
|
129369
130019
|
const phase = runState.phase ?? 0;
|
|
129370
|
-
const evidencePath =
|
|
129371
|
-
const expectedDir =
|
|
129372
|
-
const resolvedPath =
|
|
129373
|
-
const resolvedDir =
|
|
129374
|
-
if (!resolvedPath.startsWith(resolvedDir +
|
|
130020
|
+
const evidencePath = path170.join(directory, ".swarm", "evidence", String(phase), "lean-turbo", `${lane.laneId}.json`);
|
|
130021
|
+
const expectedDir = path170.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
|
|
130022
|
+
const resolvedPath = path170.resolve(evidencePath);
|
|
130023
|
+
const resolvedDir = path170.resolve(expectedDir);
|
|
130024
|
+
if (!resolvedPath.startsWith(resolvedDir + path170.sep) && resolvedPath !== resolvedDir) {
|
|
129375
130025
|
return {
|
|
129376
130026
|
ok: false,
|
|
129377
130027
|
reason: `Lane ID causes path traversal: ${lane.laneId}`,
|
|
@@ -129395,7 +130045,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
129395
130045
|
}
|
|
129396
130046
|
};
|
|
129397
130047
|
}
|
|
129398
|
-
const activeLocks =
|
|
130048
|
+
const activeLocks = _internals78.listActiveLocks(directory);
|
|
129399
130049
|
const laneLocks = activeLocks.filter((lock) => lock.laneId === lane.laneId);
|
|
129400
130050
|
if (laneLocks.length > 0) {
|
|
129401
130051
|
return {
|
|
@@ -129411,7 +130061,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
129411
130061
|
}
|
|
129412
130062
|
let filesTouched = [];
|
|
129413
130063
|
try {
|
|
129414
|
-
const planPath =
|
|
130064
|
+
const planPath = path170.join(directory, ".swarm", "plan.json");
|
|
129415
130065
|
const planRaw = fs127.readFileSync(planPath, "utf-8");
|
|
129416
130066
|
const plan = JSON.parse(planRaw);
|
|
129417
130067
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -129495,7 +130145,7 @@ var TIER_3_PATTERNS2 = [
|
|
|
129495
130145
|
];
|
|
129496
130146
|
function matchesTier3Pattern2(files) {
|
|
129497
130147
|
for (const file3 of files) {
|
|
129498
|
-
const fileName =
|
|
130148
|
+
const fileName = path171.basename(file3);
|
|
129499
130149
|
for (const pattern of TIER_3_PATTERNS2) {
|
|
129500
130150
|
if (pattern.test(fileName)) {
|
|
129501
130151
|
return true;
|
|
@@ -129534,7 +130184,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
129534
130184
|
if (!skipStandardTurboBypass && hasActiveTurboMode()) {
|
|
129535
130185
|
const resolvedDir2 = workingDirectory;
|
|
129536
130186
|
try {
|
|
129537
|
-
const planPath =
|
|
130187
|
+
const planPath = path171.join(resolvedDir2, ".swarm", "plan.json");
|
|
129538
130188
|
const planRaw = fs128.readFileSync(planPath, "utf-8");
|
|
129539
130189
|
const plan = JSON.parse(planRaw);
|
|
129540
130190
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -129612,7 +130262,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
129612
130262
|
}
|
|
129613
130263
|
if (resolvedDir) {
|
|
129614
130264
|
try {
|
|
129615
|
-
const planPath =
|
|
130265
|
+
const planPath = path171.join(resolvedDir, ".swarm", "plan.json");
|
|
129616
130266
|
const planRaw = fs128.readFileSync(planPath, "utf-8");
|
|
129617
130267
|
const plan = JSON.parse(planRaw);
|
|
129618
130268
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -129854,7 +130504,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
129854
130504
|
};
|
|
129855
130505
|
}
|
|
129856
130506
|
directory = resolveResult.directory;
|
|
129857
|
-
const planPath =
|
|
130507
|
+
const planPath = path171.join(directory, ".swarm", "plan.json");
|
|
129858
130508
|
if (!fs128.existsSync(planPath)) {
|
|
129859
130509
|
return {
|
|
129860
130510
|
success: false,
|
|
@@ -129863,9 +130513,9 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
129863
130513
|
};
|
|
129864
130514
|
}
|
|
129865
130515
|
if (fallbackDir && directory !== fallbackDir) {
|
|
129866
|
-
const canonicalDir = fs128.realpathSync(
|
|
129867
|
-
const canonicalRoot = fs128.realpathSync(
|
|
129868
|
-
if (canonicalDir.startsWith(canonicalRoot +
|
|
130516
|
+
const canonicalDir = fs128.realpathSync(path171.resolve(directory));
|
|
130517
|
+
const canonicalRoot = fs128.realpathSync(path171.resolve(fallbackDir));
|
|
130518
|
+
if (canonicalDir.startsWith(canonicalRoot + path171.sep)) {
|
|
129869
130519
|
return {
|
|
129870
130520
|
success: false,
|
|
129871
130521
|
message: `Invalid working_directory: "${directory}" is a subdirectory of ` + `the project root "${fallbackDir}". Pass the project root path or ` + `omit working_directory entirely.`,
|
|
@@ -129877,8 +130527,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
129877
130527
|
}
|
|
129878
130528
|
if (args2.status === "in_progress") {
|
|
129879
130529
|
try {
|
|
129880
|
-
const evidencePath =
|
|
129881
|
-
fs128.mkdirSync(
|
|
130530
|
+
const evidencePath = path171.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
|
|
130531
|
+
fs128.mkdirSync(path171.dirname(evidencePath), { recursive: true });
|
|
129882
130532
|
const fd = fs128.openSync(evidencePath, "wx");
|
|
129883
130533
|
let writeOk = false;
|
|
129884
130534
|
try {
|
|
@@ -129902,7 +130552,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
129902
130552
|
recoverTaskStateFromDelegations(args2.task_id, directory);
|
|
129903
130553
|
let phaseRequiresReviewer = true;
|
|
129904
130554
|
try {
|
|
129905
|
-
const planPath2 =
|
|
130555
|
+
const planPath2 = path171.join(directory, ".swarm", "plan.json");
|
|
129906
130556
|
const planRaw = fs128.readFileSync(planPath2, "utf-8");
|
|
129907
130557
|
const plan = JSON.parse(planRaw);
|
|
129908
130558
|
const taskPhase = plan.phases.find((p) => p.tasks.some((t) => t.id === args2.task_id));
|
|
@@ -130199,7 +130849,7 @@ init_utils2();
|
|
|
130199
130849
|
init_redaction();
|
|
130200
130850
|
import { createHash as createHash13 } from "node:crypto";
|
|
130201
130851
|
import { appendFile as appendFile14, mkdir as mkdir24 } from "node:fs/promises";
|
|
130202
|
-
import * as
|
|
130852
|
+
import * as path172 from "node:path";
|
|
130203
130853
|
var EVIDENCE_CACHE_FILE = "evidence-cache/documents.jsonl";
|
|
130204
130854
|
var MAX_EVIDENCE_TEXT_LENGTH = 4000;
|
|
130205
130855
|
async function writeEvidenceDocuments(directory, inputs, now = () => new Date) {
|
|
@@ -130207,7 +130857,7 @@ async function writeEvidenceDocuments(directory, inputs, now = () => new Date) {
|
|
|
130207
130857
|
const capturedAt = now().toISOString();
|
|
130208
130858
|
const records = inputs.map((input) => createEvidenceDocumentRecord(input, capturedAt)).filter((record3) => record3 !== null);
|
|
130209
130859
|
if (records.length > 0) {
|
|
130210
|
-
await mkdir24(
|
|
130860
|
+
await mkdir24(path172.dirname(filePath), { recursive: true });
|
|
130211
130861
|
await appendFile14(filePath, `${records.map((record3) => JSON.stringify(record3)).join(`
|
|
130212
130862
|
`)}
|
|
130213
130863
|
`, "utf-8");
|
|
@@ -130373,7 +131023,7 @@ var web_search = createSwarmTool({
|
|
|
130373
131023
|
});
|
|
130374
131024
|
async function captureSearchEvidence(directory, query, results) {
|
|
130375
131025
|
try {
|
|
130376
|
-
const written = await
|
|
131026
|
+
const written = await _internals79.writeEvidenceDocuments(directory, results.map((result) => ({
|
|
130377
131027
|
sourceType: "web_search",
|
|
130378
131028
|
query,
|
|
130379
131029
|
title: result.title,
|
|
@@ -130401,7 +131051,7 @@ async function captureSearchEvidence(directory, query, results) {
|
|
|
130401
131051
|
};
|
|
130402
131052
|
}
|
|
130403
131053
|
}
|
|
130404
|
-
var
|
|
131054
|
+
var _internals79 = {
|
|
130405
131055
|
writeEvidenceDocuments
|
|
130406
131056
|
};
|
|
130407
131057
|
|
|
@@ -130415,7 +131065,7 @@ init_schema3();
|
|
|
130415
131065
|
init_store();
|
|
130416
131066
|
init_create_tool();
|
|
130417
131067
|
init_resolve_working_directory();
|
|
130418
|
-
import * as
|
|
131068
|
+
import * as path173 from "node:path";
|
|
130419
131069
|
var FindingSchema2 = exports_external.object({
|
|
130420
131070
|
severity: exports_external.enum(["low", "medium", "high", "critical"]),
|
|
130421
131071
|
category: exports_external.string().min(1),
|
|
@@ -130479,7 +131129,7 @@ var write_architecture_supervisor_evidence = createSwarmTool({
|
|
|
130479
131129
|
if (config3.architectural_supervision?.persist_knowledge_recommendations && args2.knowledge_recommendations.length > 0) {
|
|
130480
131130
|
const knowledgeConfig = KnowledgeConfigSchema.parse(config3.knowledge ?? {});
|
|
130481
131131
|
const lessons = args2.knowledge_recommendations.map((r) => r.lesson);
|
|
130482
|
-
const result = await curateAndStoreSwarm(lessons,
|
|
131132
|
+
const result = await curateAndStoreSwarm(lessons, path173.basename(dirResult.directory), { phase_number: args2.phase }, dirResult.directory, knowledgeConfig, { skipAutoPromotion: true });
|
|
130483
131133
|
knowledgeProposed = result.stored;
|
|
130484
131134
|
}
|
|
130485
131135
|
} catch {}
|
|
@@ -130515,7 +131165,7 @@ init_ledger();
|
|
|
130515
131165
|
init_manager();
|
|
130516
131166
|
init_create_tool();
|
|
130517
131167
|
import fs129 from "node:fs";
|
|
130518
|
-
import
|
|
131168
|
+
import path174 from "node:path";
|
|
130519
131169
|
function normalizeVerdict(verdict) {
|
|
130520
131170
|
switch (verdict) {
|
|
130521
131171
|
case "APPROVED":
|
|
@@ -130563,7 +131213,7 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
130563
131213
|
entries: [evidenceEntry]
|
|
130564
131214
|
};
|
|
130565
131215
|
const filename = "drift-verifier.json";
|
|
130566
|
-
const relativePath =
|
|
131216
|
+
const relativePath = path174.join("evidence", String(phase), filename);
|
|
130567
131217
|
let validatedPath;
|
|
130568
131218
|
try {
|
|
130569
131219
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -130574,10 +131224,10 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
130574
131224
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
130575
131225
|
}, null, 2);
|
|
130576
131226
|
}
|
|
130577
|
-
const evidenceDir =
|
|
131227
|
+
const evidenceDir = path174.dirname(validatedPath);
|
|
130578
131228
|
try {
|
|
130579
131229
|
await fs129.promises.mkdir(evidenceDir, { recursive: true });
|
|
130580
|
-
const tempPath =
|
|
131230
|
+
const tempPath = path174.join(evidenceDir, `.${filename}.tmp`);
|
|
130581
131231
|
await fs129.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
130582
131232
|
await fs129.promises.rename(tempPath, validatedPath);
|
|
130583
131233
|
let snapshotInfo;
|
|
@@ -130674,7 +131324,7 @@ var write_drift_evidence = createSwarmTool({
|
|
|
130674
131324
|
init_zod();
|
|
130675
131325
|
init_loader();
|
|
130676
131326
|
import fs130 from "node:fs";
|
|
130677
|
-
import
|
|
131327
|
+
import path175 from "node:path";
|
|
130678
131328
|
init_utils2();
|
|
130679
131329
|
init_manager();
|
|
130680
131330
|
init_create_tool();
|
|
@@ -130768,7 +131418,7 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
|
|
|
130768
131418
|
timestamp: synthesis.timestamp
|
|
130769
131419
|
};
|
|
130770
131420
|
const filename = "final-council.json";
|
|
130771
|
-
const relativePath =
|
|
131421
|
+
const relativePath = path175.join("evidence", filename);
|
|
130772
131422
|
let validatedPath;
|
|
130773
131423
|
try {
|
|
130774
131424
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -130782,10 +131432,10 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
|
|
|
130782
131432
|
const evidenceContent = {
|
|
130783
131433
|
entries: [evidenceEntry]
|
|
130784
131434
|
};
|
|
130785
|
-
const evidenceDir =
|
|
131435
|
+
const evidenceDir = path175.dirname(validatedPath);
|
|
130786
131436
|
try {
|
|
130787
131437
|
await fs130.promises.mkdir(evidenceDir, { recursive: true });
|
|
130788
|
-
const tempPath =
|
|
131438
|
+
const tempPath = path175.join(evidenceDir, `.${filename}.tmp`);
|
|
130789
131439
|
await fs130.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
130790
131440
|
await fs130.promises.rename(tempPath, validatedPath);
|
|
130791
131441
|
return JSON.stringify({
|
|
@@ -130845,7 +131495,7 @@ init_zod();
|
|
|
130845
131495
|
init_utils2();
|
|
130846
131496
|
init_create_tool();
|
|
130847
131497
|
import fs131 from "node:fs";
|
|
130848
|
-
import
|
|
131498
|
+
import path176 from "node:path";
|
|
130849
131499
|
function normalizeVerdict2(verdict) {
|
|
130850
131500
|
switch (verdict) {
|
|
130851
131501
|
case "APPROVED":
|
|
@@ -130893,7 +131543,7 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
130893
131543
|
entries: [evidenceEntry]
|
|
130894
131544
|
};
|
|
130895
131545
|
const filename = "hallucination-guard.json";
|
|
130896
|
-
const relativePath =
|
|
131546
|
+
const relativePath = path176.join("evidence", String(phase), filename);
|
|
130897
131547
|
let validatedPath;
|
|
130898
131548
|
try {
|
|
130899
131549
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -130904,10 +131554,10 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
130904
131554
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
130905
131555
|
}, null, 2);
|
|
130906
131556
|
}
|
|
130907
|
-
const evidenceDir =
|
|
131557
|
+
const evidenceDir = path176.dirname(validatedPath);
|
|
130908
131558
|
try {
|
|
130909
131559
|
await fs131.promises.mkdir(evidenceDir, { recursive: true });
|
|
130910
|
-
const tempPath =
|
|
131560
|
+
const tempPath = path176.join(evidenceDir, `.${filename}.tmp`);
|
|
130911
131561
|
await fs131.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
130912
131562
|
await fs131.promises.rename(tempPath, validatedPath);
|
|
130913
131563
|
return JSON.stringify({
|
|
@@ -130957,7 +131607,7 @@ init_zod();
|
|
|
130957
131607
|
init_utils2();
|
|
130958
131608
|
init_create_tool();
|
|
130959
131609
|
import fs132 from "node:fs";
|
|
130960
|
-
import
|
|
131610
|
+
import path177 from "node:path";
|
|
130961
131611
|
function normalizeVerdict3(verdict) {
|
|
130962
131612
|
switch (verdict) {
|
|
130963
131613
|
case "PASS":
|
|
@@ -131031,7 +131681,7 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
131031
131681
|
entries: [evidenceEntry]
|
|
131032
131682
|
};
|
|
131033
131683
|
const filename = "mutation-gate.json";
|
|
131034
|
-
const relativePath =
|
|
131684
|
+
const relativePath = path177.join("evidence", String(phase), filename);
|
|
131035
131685
|
let validatedPath;
|
|
131036
131686
|
try {
|
|
131037
131687
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -131042,10 +131692,10 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
131042
131692
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
131043
131693
|
}, null, 2);
|
|
131044
131694
|
}
|
|
131045
|
-
const evidenceDir =
|
|
131695
|
+
const evidenceDir = path177.dirname(validatedPath);
|
|
131046
131696
|
try {
|
|
131047
131697
|
await fs132.promises.mkdir(evidenceDir, { recursive: true });
|
|
131048
|
-
const tempPath =
|
|
131698
|
+
const tempPath = path177.join(evidenceDir, `.${filename}.tmp`);
|
|
131049
131699
|
await fs132.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
131050
131700
|
await fs132.promises.rename(tempPath, validatedPath);
|
|
131051
131701
|
return JSON.stringify({
|
|
@@ -131233,7 +131883,7 @@ ${footerLines.join(`
|
|
|
131233
131883
|
init_warning_buffer();
|
|
131234
131884
|
var _heartbeatTimers = new Map;
|
|
131235
131885
|
var SWARM_COMMAND_SYSTEM_RULE_TAG = "[opencode-swarm:swarm-command-rule]";
|
|
131236
|
-
var PACKAGE_ROOT2 =
|
|
131886
|
+
var PACKAGE_ROOT2 = path179.resolve(path179.dirname(fileURLToPath5(import.meta.url)), "..");
|
|
131237
131887
|
function createSwarmCommandSystemRuleHook(agentDefinitions, registeredAgents) {
|
|
131238
131888
|
return async (input, output) => {
|
|
131239
131889
|
const { sessionID } = input;
|
|
@@ -131503,7 +132153,7 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
131503
132153
|
const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
|
|
131504
132154
|
preflightTriggerManager = new PTM(automationConfig);
|
|
131505
132155
|
const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
|
|
131506
|
-
const swarmDir =
|
|
132156
|
+
const swarmDir = path179.resolve(ctx.directory, ".swarm");
|
|
131507
132157
|
statusArtifact = new ASA(swarmDir);
|
|
131508
132158
|
statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
|
|
131509
132159
|
if (automationConfig.capabilities?.evidence_auto_summaries === true) {
|
|
@@ -132034,7 +132684,7 @@ ${promptRaw}`;
|
|
|
132034
132684
|
const meta3 = readSkillMetadata(s.skillPath, ctx.directory);
|
|
132035
132685
|
let desc = meta3.description || "";
|
|
132036
132686
|
if (!desc || desc === "No description provided") {
|
|
132037
|
-
desc =
|
|
132687
|
+
desc = path179.basename(path179.dirname(s.skillPath));
|
|
132038
132688
|
}
|
|
132039
132689
|
desc = desc.replace(/,/g, ";");
|
|
132040
132690
|
return `file:${s.skillPath} (-- ${desc})`;
|
|
@@ -132044,7 +132694,7 @@ ${promptRaw}`;
|
|
|
132044
132694
|
|
|
132045
132695
|
${promptRaw}`;
|
|
132046
132696
|
argsRecord.prompt = newPrompt;
|
|
132047
|
-
const skillNames = topSkills.map((s) => `${
|
|
132697
|
+
const skillNames = topSkills.map((s) => `${path179.basename(s.skillPath)} (score: ${s.score.toFixed(2)})`).join(", ");
|
|
132048
132698
|
console.warn(`[skill-propagation-gate] Injected skills: ${skillNames}`);
|
|
132049
132699
|
for (const skill of topSkills) {
|
|
132050
132700
|
try {
|