opencode-swarm 7.50.3 → 7.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/cli/index.js +64 -16
- package/dist/index.js +1357 -578
- package/dist/lang/backend.d.ts +1 -0
- package/dist/tools/git-blame.d.ts +21 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/manifest.d.ts +1 -0
- package/dist/tools/suggest-patch.d.ts +1 -0
- package/dist/tools/test-runner.d.ts +3 -2
- package/dist/tools/tool-metadata.d.ts +4 -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.51.0",
|
|
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",
|
|
@@ -191,7 +191,7 @@ var init_tool_metadata = __esm(() => {
|
|
|
191
191
|
agents: ["architect", "reviewer", "critic_oversight"]
|
|
192
192
|
},
|
|
193
193
|
syntax_check: {
|
|
194
|
-
description: "syntax
|
|
194
|
+
description: "check syntax of source files using tree-sitter parsers across multiple languages, returning per-file errors",
|
|
195
195
|
agents: ["architect", "coder", "test_engineer"]
|
|
196
196
|
},
|
|
197
197
|
placeholder_scan: {
|
|
@@ -199,7 +199,7 @@ var init_tool_metadata = __esm(() => {
|
|
|
199
199
|
agents: ["architect", "reviewer"]
|
|
200
200
|
},
|
|
201
201
|
imports: {
|
|
202
|
-
description: "
|
|
202
|
+
description: "find all consumers that import from a given file — use before refactoring shared modules to avoid breaking unseen dependents",
|
|
203
203
|
agents: [
|
|
204
204
|
"architect",
|
|
205
205
|
"sme",
|
|
@@ -217,11 +217,11 @@ var init_tool_metadata = __esm(() => {
|
|
|
217
217
|
]
|
|
218
218
|
},
|
|
219
219
|
lint: {
|
|
220
|
-
description: "
|
|
220
|
+
description: "run project linter in check or fix mode; supports biome, eslint, ruff, clippy, and more, returns structured results",
|
|
221
221
|
agents: ["architect", "reviewer", "coder"]
|
|
222
222
|
},
|
|
223
223
|
secretscan: {
|
|
224
|
-
description: "
|
|
224
|
+
description: "scan for secrets (API keys, tokens, passwords) via regex and entropy; returns redacted previews, excludes common dirs",
|
|
225
225
|
agents: ["architect", "reviewer", "critic_oversight"]
|
|
226
226
|
},
|
|
227
227
|
sast_scan: {
|
|
@@ -229,7 +229,7 @@ var init_tool_metadata = __esm(() => {
|
|
|
229
229
|
agents: ["architect", "reviewer", "critic_oversight"]
|
|
230
230
|
},
|
|
231
231
|
build_check: {
|
|
232
|
-
description: "build
|
|
232
|
+
description: "discover and run build, typecheck, and test commands for various project ecosystems in the working directory",
|
|
233
233
|
agents: ["architect", "coder", "test_engineer"]
|
|
234
234
|
},
|
|
235
235
|
pre_check_batch: {
|
|
@@ -241,7 +241,7 @@ var init_tool_metadata = __esm(() => {
|
|
|
241
241
|
agents: ["architect"]
|
|
242
242
|
},
|
|
243
243
|
symbols: {
|
|
244
|
-
description: "
|
|
244
|
+
description: "extract exported symbols (functions, classes, interfaces, types) from source files; supports TypeScript, JavaScript, and Python",
|
|
245
245
|
agents: [
|
|
246
246
|
"architect",
|
|
247
247
|
"sme",
|
|
@@ -312,7 +312,7 @@ var init_tool_metadata = __esm(() => {
|
|
|
312
312
|
agents: ["architect"]
|
|
313
313
|
},
|
|
314
314
|
checkpoint: {
|
|
315
|
-
description: "
|
|
315
|
+
description: "create named git checkpoints for save, restore, and delete — use before risky operations to enable rollback",
|
|
316
316
|
agents: ["architect"]
|
|
317
317
|
},
|
|
318
318
|
pkg_audit: {
|
|
@@ -356,6 +356,10 @@ var init_tool_metadata = __esm(() => {
|
|
|
356
356
|
"explorer"
|
|
357
357
|
]
|
|
358
358
|
},
|
|
359
|
+
git_blame: {
|
|
360
|
+
description: "per-line git blame metadata: sha, author, date, summary for each line in a file",
|
|
361
|
+
agents: ["reviewer", "explorer", "architect"]
|
|
362
|
+
},
|
|
359
363
|
gitingest: {
|
|
360
364
|
description: "fetch a GitHub repository full content via gitingest.com",
|
|
361
365
|
agents: ["architect", "docs", "explorer"]
|
|
@@ -40728,6 +40732,7 @@ function isParallelGuidancePhaseComplete(phase) {
|
|
|
40728
40732
|
return phase.status === "complete" || phase.status === "completed" || phase.status === "closed";
|
|
40729
40733
|
}
|
|
40730
40734
|
async function getEvidenceTaskId(session, directory) {
|
|
40735
|
+
let resolvedPlanPath;
|
|
40731
40736
|
const primary = session.currentTaskId ?? session.lastCoderDelegationTaskId;
|
|
40732
40737
|
if (primary)
|
|
40733
40738
|
return primary;
|
|
@@ -40740,12 +40745,12 @@ async function getEvidenceTaskId(session, directory) {
|
|
|
40740
40745
|
}
|
|
40741
40746
|
const resolvedDirectory = path19.resolve(directory);
|
|
40742
40747
|
const planPath = path19.join(resolvedDirectory, ".swarm", "plan.json");
|
|
40743
|
-
|
|
40748
|
+
resolvedPlanPath = path19.resolve(planPath);
|
|
40744
40749
|
if (!resolvedPlanPath.startsWith(resolvedDirectory + path19.sep) && resolvedPlanPath !== resolvedDirectory) {
|
|
40745
40750
|
return null;
|
|
40746
40751
|
}
|
|
40747
40752
|
const planContent = await fs12.promises.readFile(resolvedPlanPath, "utf-8");
|
|
40748
|
-
const plan = JSON.parse(planContent);
|
|
40753
|
+
const plan = EvidenceTaskIdPlanSchema.parse(JSON.parse(planContent));
|
|
40749
40754
|
if (!plan || !Array.isArray(plan.phases)) {
|
|
40750
40755
|
return null;
|
|
40751
40756
|
}
|
|
@@ -40759,6 +40764,11 @@ async function getEvidenceTaskId(session, directory) {
|
|
|
40759
40764
|
}
|
|
40760
40765
|
}
|
|
40761
40766
|
} catch (err2) {
|
|
40767
|
+
if (err2 instanceof ZodError) {
|
|
40768
|
+
const issueSummary = err2.issues.slice(0, 3).map((issue2) => issue2.message).join("; ");
|
|
40769
|
+
warn(`[delegation-gate] getEvidenceTaskId ignored invalid plan schema at ${resolvedPlanPath ?? "unknown path"}: ${issueSummary}`);
|
|
40770
|
+
return null;
|
|
40771
|
+
}
|
|
40762
40772
|
if (process.env.DEBUG_SWARM && err2 instanceof Error) {
|
|
40763
40773
|
warn(`[delegation-gate] getEvidenceTaskId error: ${err2.message} (code=${err2.code ?? "none"})`);
|
|
40764
40774
|
}
|
|
@@ -41405,8 +41415,9 @@ ${warningLines.join(`
|
|
|
41405
41415
|
toolAfter
|
|
41406
41416
|
};
|
|
41407
41417
|
}
|
|
41408
|
-
var pendingCoderScopeByTaskId, ACTIVE_PARALLEL_TASK_STATES;
|
|
41418
|
+
var EvidenceTaskIdPlanSchema, pendingCoderScopeByTaskId, ACTIVE_PARALLEL_TASK_STATES;
|
|
41409
41419
|
var init_delegation_gate = __esm(() => {
|
|
41420
|
+
init_zod();
|
|
41410
41421
|
init_schema();
|
|
41411
41422
|
init_manager();
|
|
41412
41423
|
init_state();
|
|
@@ -41416,6 +41427,14 @@ var init_delegation_gate = __esm(() => {
|
|
|
41416
41427
|
init_guardrails();
|
|
41417
41428
|
init_normalize_tool_name();
|
|
41418
41429
|
init_utils2();
|
|
41430
|
+
EvidenceTaskIdPlanSchema = exports_external.object({
|
|
41431
|
+
phases: exports_external.array(exports_external.object({
|
|
41432
|
+
tasks: exports_external.array(exports_external.object({
|
|
41433
|
+
id: exports_external.string(),
|
|
41434
|
+
status: exports_external.string().optional()
|
|
41435
|
+
}).passthrough()).optional()
|
|
41436
|
+
}).passthrough()).optional()
|
|
41437
|
+
}).passthrough();
|
|
41419
41438
|
pendingCoderScopeByTaskId = new Map;
|
|
41420
41439
|
ACTIVE_PARALLEL_TASK_STATES = new Set([
|
|
41421
41440
|
"coder_delegated",
|
|
@@ -74590,11 +74609,14 @@ async function defaultSelectTestFramework(profile, dir) {
|
|
|
74590
74609
|
function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}) {
|
|
74591
74610
|
const scope = opts.scope ?? "all";
|
|
74592
74611
|
const coverage = opts.coverage ?? false;
|
|
74612
|
+
const bail = opts.bail ?? false;
|
|
74593
74613
|
switch (framework) {
|
|
74594
74614
|
case "bun": {
|
|
74595
74615
|
const args2 = ["bun", "test"];
|
|
74596
74616
|
if (coverage)
|
|
74597
74617
|
args2.push("--coverage");
|
|
74618
|
+
if (bail)
|
|
74619
|
+
args2.push("--bail");
|
|
74598
74620
|
if (scope !== "all" && files.length > 0)
|
|
74599
74621
|
args2.push(...files);
|
|
74600
74622
|
return args2;
|
|
@@ -74610,6 +74632,8 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
|
|
|
74610
74632
|
];
|
|
74611
74633
|
if (coverage)
|
|
74612
74634
|
args2.push("--coverage");
|
|
74635
|
+
if (bail)
|
|
74636
|
+
args2.push("--bail");
|
|
74613
74637
|
if (scope !== "all" && files.length > 0)
|
|
74614
74638
|
args2.push(...files);
|
|
74615
74639
|
return args2;
|
|
@@ -74618,12 +74642,16 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
|
|
|
74618
74642
|
const args2 = ["npx", "jest", "--json"];
|
|
74619
74643
|
if (coverage)
|
|
74620
74644
|
args2.push("--coverage");
|
|
74645
|
+
if (bail)
|
|
74646
|
+
args2.push("--bail");
|
|
74621
74647
|
if (scope !== "all" && files.length > 0)
|
|
74622
74648
|
args2.push(...files);
|
|
74623
74649
|
return args2;
|
|
74624
74650
|
}
|
|
74625
74651
|
case "mocha": {
|
|
74626
74652
|
const args2 = ["npx", "mocha"];
|
|
74653
|
+
if (bail)
|
|
74654
|
+
args2.push("--bail");
|
|
74627
74655
|
if (scope !== "all" && files.length > 0)
|
|
74628
74656
|
args2.push(...files);
|
|
74629
74657
|
return args2;
|
|
@@ -74633,6 +74661,8 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
|
|
|
74633
74661
|
const args2 = isWindows ? ["python", "-m", "pytest"] : ["python3", "-m", "pytest"];
|
|
74634
74662
|
if (coverage)
|
|
74635
74663
|
args2.push("--cov=.", "--cov-report=term-missing");
|
|
74664
|
+
if (bail)
|
|
74665
|
+
args2.push("-x");
|
|
74636
74666
|
if (scope !== "all" && files.length > 0)
|
|
74637
74667
|
args2.push(...files);
|
|
74638
74668
|
return args2;
|
|
@@ -74686,6 +74716,8 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
|
|
|
74686
74716
|
return isCommandAvailable("flutter") ? ["flutter", "test", ...files] : ["dart", "test", ...files];
|
|
74687
74717
|
case "rspec": {
|
|
74688
74718
|
const args2 = isCommandAvailable("bundle") ? ["bundle", "exec", "rspec"] : ["rspec"];
|
|
74719
|
+
if (bail)
|
|
74720
|
+
args2.push("--fail-fast");
|
|
74689
74721
|
if (scope !== "all" && files.length > 0)
|
|
74690
74722
|
args2.push(...files);
|
|
74691
74723
|
return args2;
|
|
@@ -76660,6 +76692,10 @@ function validateArgs2(args2) {
|
|
|
76660
76692
|
if (typeof obj.coverage !== "boolean")
|
|
76661
76693
|
return false;
|
|
76662
76694
|
}
|
|
76695
|
+
if (obj.bail !== undefined) {
|
|
76696
|
+
if (typeof obj.bail !== "boolean")
|
|
76697
|
+
return false;
|
|
76698
|
+
}
|
|
76663
76699
|
if (obj.timeout_ms !== undefined) {
|
|
76664
76700
|
if (typeof obj.timeout_ms !== "number")
|
|
76665
76701
|
return false;
|
|
@@ -76735,7 +76771,7 @@ async function detectTestFrameworkViaDispatch(cwd) {
|
|
|
76735
76771
|
return "none";
|
|
76736
76772
|
}
|
|
76737
76773
|
}
|
|
76738
|
-
async function buildTestCommandViaDispatch(framework, scope, files, coverage, baseDir) {
|
|
76774
|
+
async function buildTestCommandViaDispatch(framework, scope, files, coverage, baseDir, bail) {
|
|
76739
76775
|
if (framework === "none")
|
|
76740
76776
|
return null;
|
|
76741
76777
|
try {
|
|
@@ -76744,7 +76780,8 @@ async function buildTestCommandViaDispatch(framework, scope, files, coverage, ba
|
|
|
76744
76780
|
if (backend?.buildTestCommand) {
|
|
76745
76781
|
const cmd = backend.buildTestCommand(framework, files, baseDir, {
|
|
76746
76782
|
scope,
|
|
76747
|
-
coverage
|
|
76783
|
+
coverage,
|
|
76784
|
+
bail
|
|
76748
76785
|
});
|
|
76749
76786
|
if (cmd)
|
|
76750
76787
|
return cmd;
|
|
@@ -77113,12 +77150,14 @@ function getTargetedExecutionUnsupportedReason(framework) {
|
|
|
77113
77150
|
return null;
|
|
77114
77151
|
}
|
|
77115
77152
|
}
|
|
77116
|
-
function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
77153
|
+
function buildTestCommand2(framework, scope, files, coverage, baseDir, bail) {
|
|
77117
77154
|
switch (framework) {
|
|
77118
77155
|
case "bun": {
|
|
77119
77156
|
const args2 = ["bun", "test"];
|
|
77120
77157
|
if (coverage)
|
|
77121
77158
|
args2.push("--coverage");
|
|
77159
|
+
if (bail)
|
|
77160
|
+
args2.push("--bail");
|
|
77122
77161
|
if (scope !== "all" && files.length > 0) {
|
|
77123
77162
|
args2.push(...files);
|
|
77124
77163
|
}
|
|
@@ -77135,6 +77174,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
77135
77174
|
];
|
|
77136
77175
|
if (coverage)
|
|
77137
77176
|
args2.push("--coverage");
|
|
77177
|
+
if (bail)
|
|
77178
|
+
args2.push("--bail=1");
|
|
77138
77179
|
if (scope !== "all" && files.length > 0) {
|
|
77139
77180
|
args2.push(...files);
|
|
77140
77181
|
}
|
|
@@ -77144,6 +77185,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
77144
77185
|
const args2 = ["npx", "jest", "--json"];
|
|
77145
77186
|
if (coverage)
|
|
77146
77187
|
args2.push("--coverage");
|
|
77188
|
+
if (bail)
|
|
77189
|
+
args2.push("--bail");
|
|
77147
77190
|
if (scope !== "all" && files.length > 0) {
|
|
77148
77191
|
args2.push(...files);
|
|
77149
77192
|
}
|
|
@@ -77151,6 +77194,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
77151
77194
|
}
|
|
77152
77195
|
case "mocha": {
|
|
77153
77196
|
const args2 = ["npx", "mocha"];
|
|
77197
|
+
if (bail)
|
|
77198
|
+
args2.push("--bail");
|
|
77154
77199
|
if (scope !== "all" && files.length > 0) {
|
|
77155
77200
|
args2.push(...files);
|
|
77156
77201
|
}
|
|
@@ -77161,6 +77206,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
77161
77206
|
const args2 = isWindows ? ["python", "-m", "pytest"] : ["python3", "-m", "pytest"];
|
|
77162
77207
|
if (coverage)
|
|
77163
77208
|
args2.push("--cov=.", "--cov-report=term-missing");
|
|
77209
|
+
if (bail)
|
|
77210
|
+
args2.push("-x");
|
|
77164
77211
|
if (scope !== "all" && files.length > 0) {
|
|
77165
77212
|
args2.push(...files);
|
|
77166
77213
|
}
|
|
@@ -77217,6 +77264,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
|
|
|
77217
77264
|
return isCommandAvailable("flutter") ? ["flutter", "test", ...files] : ["dart", "test", ...files];
|
|
77218
77265
|
case "rspec": {
|
|
77219
77266
|
const args2 = isCommandAvailable("bundle") ? ["bundle", "exec", "rspec"] : ["rspec"];
|
|
77267
|
+
if (bail)
|
|
77268
|
+
args2.push("--fail-fast");
|
|
77220
77269
|
if (scope !== "all" && files.length > 0) {
|
|
77221
77270
|
args2.push(...files);
|
|
77222
77271
|
}
|
|
@@ -77602,7 +77651,7 @@ async function readBoundedStream(stream, maxBytes) {
|
|
|
77602
77651
|
}
|
|
77603
77652
|
return { text: decoder.decode(combined), truncated };
|
|
77604
77653
|
}
|
|
77605
|
-
async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
|
|
77654
|
+
async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail) {
|
|
77606
77655
|
if (scope !== "all" && files.length > 0) {
|
|
77607
77656
|
const unsupportedReason = getTargetedExecutionUnsupportedReason(framework);
|
|
77608
77657
|
if (unsupportedReason) {
|
|
@@ -77617,7 +77666,7 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
|
|
|
77617
77666
|
}
|
|
77618
77667
|
}
|
|
77619
77668
|
const useDispatchBuild = process.env.SWARM_LANG_BACKEND !== "legacy";
|
|
77620
|
-
const command = useDispatchBuild ? await buildTestCommandViaDispatch(framework, scope, files, coverage, cwd) ?? buildTestCommand2(framework, scope, files, coverage, cwd) : buildTestCommand2(framework, scope, files, coverage, cwd);
|
|
77669
|
+
const command = useDispatchBuild ? await buildTestCommandViaDispatch(framework, scope, files, coverage, cwd, bail) ?? buildTestCommand2(framework, scope, files, coverage, cwd, bail) : buildTestCommand2(framework, scope, files, coverage, cwd, bail);
|
|
77621
77670
|
if (!command) {
|
|
77622
77671
|
return {
|
|
77623
77672
|
success: false,
|
|
@@ -77965,6 +78014,7 @@ var init_test_runner = __esm(() => {
|
|
|
77965
78014
|
scope: exports_external.enum(["all", "convention", "graph", "impact"]).optional().describe('Test scope: "all" runs full suite, "convention" accepts direct test files or maps source files to tests by naming, "graph" finds related tests via imports from source files, "impact" finds tests covering changed source files via test-impact analysis'),
|
|
77966
78015
|
files: exports_external.array(exports_external.string()).optional().describe('Specific files to test. For "convention", pass source files or direct test files. For "graph" and "impact", pass source files only.'),
|
|
77967
78016
|
coverage: exports_external.boolean().optional().describe("Enable coverage reporting if supported"),
|
|
78017
|
+
bail: exports_external.boolean().optional().describe("Stop running tests after the first failure. Default false. Note: coverage may be incomplete when bail=true with coverage=true."),
|
|
77968
78018
|
timeout_ms: exports_external.number().optional().describe("Timeout in milliseconds (default 60000, max 300000)"),
|
|
77969
78019
|
allow_full_suite: exports_external.boolean().optional().describe('Explicit opt-in for scope "all". Required because full-suite output can destabilize SSE streaming.'),
|
|
77970
78020
|
working_directory: exports_external.string().optional().describe("Explicit project root directory. When provided, tests run relative to this path instead of the plugin context directory. Use this when CWD differs from the actual project root.")
|
|
@@ -78065,6 +78115,7 @@ var init_test_runner = __esm(() => {
|
|
|
78065
78115
|
}
|
|
78066
78116
|
const _files = args2.files || [];
|
|
78067
78117
|
const coverage = args2.coverage || false;
|
|
78118
|
+
const bail = args2.bail || false;
|
|
78068
78119
|
const timeout_ms = Math.min(args2.timeout_ms || DEFAULT_TIMEOUT_MS, MAX_TIMEOUT_MS);
|
|
78069
78120
|
const useDispatch = process.env.SWARM_LANG_BACKEND !== "legacy";
|
|
78070
78121
|
let framework;
|
|
@@ -78303,7 +78354,7 @@ var init_test_runner = __esm(() => {
|
|
|
78303
78354
|
};
|
|
78304
78355
|
return JSON.stringify(errorResult, null, 2);
|
|
78305
78356
|
}
|
|
78306
|
-
const result = await runTests(framework, effectiveScope, testFiles, coverage, timeout_ms, workingDir);
|
|
78357
|
+
const result = await runTests(framework, effectiveScope, testFiles, coverage, timeout_ms, workingDir, bail);
|
|
78307
78358
|
recordAndAnalyzeResults(result, testFiles, workingDir, _files.length > 0 ? _files : undefined, result.testCases);
|
|
78308
78359
|
let historyReport;
|
|
78309
78360
|
if (!result.success && result.totals && result.totals.failed > 0) {
|
|
@@ -78319,6 +78370,9 @@ var init_test_runner = __esm(() => {
|
|
|
78319
78370
|
if (graphFallbackReason && result.message) {
|
|
78320
78371
|
result.message = `${result.message} (${graphFallbackReason})`;
|
|
78321
78372
|
}
|
|
78373
|
+
if (bail && coverage && result.message) {
|
|
78374
|
+
result.message = `${result.message} (coverage may be incomplete: bail=true stopped early)`;
|
|
78375
|
+
}
|
|
78322
78376
|
return JSON.stringify(result, null, 2);
|
|
78323
78377
|
}
|
|
78324
78378
|
});
|
|
@@ -78523,7 +78577,7 @@ async function runLintCheck(dir, linter, timeoutMs) {
|
|
|
78523
78577
|
async function runTestsCheck(_dir, scope, timeoutMs) {
|
|
78524
78578
|
const startTime = Date.now();
|
|
78525
78579
|
try {
|
|
78526
|
-
const result = await runTests("none", scope, [], false, timeoutMs, _dir);
|
|
78580
|
+
const result = await runTests("none", scope, [], false, timeoutMs, _dir, false);
|
|
78527
78581
|
if (!result.success) {
|
|
78528
78582
|
return {
|
|
78529
78583
|
type: "tests",
|
|
@@ -91315,7 +91369,7 @@ async function scanDocIndex(directory) {
|
|
|
91315
91369
|
const resolvedDirectory = await realpath3(directory).catch(() => directory);
|
|
91316
91370
|
const discoveredFiles = [];
|
|
91317
91371
|
let rootReadable = false;
|
|
91318
|
-
const
|
|
91372
|
+
const walkDir2 = async (dir) => {
|
|
91319
91373
|
let entries;
|
|
91320
91374
|
try {
|
|
91321
91375
|
entries = await readdir6(dir, { withFileTypes: true });
|
|
@@ -91343,8 +91397,8 @@ async function scanDocIndex(directory) {
|
|
|
91343
91397
|
}
|
|
91344
91398
|
}
|
|
91345
91399
|
if (isDir) {
|
|
91346
|
-
if (!
|
|
91347
|
-
await
|
|
91400
|
+
if (!SKIP_DIRECTORIES4.has(entry.name)) {
|
|
91401
|
+
await walkDir2(path94.join(dir, entry.name));
|
|
91348
91402
|
}
|
|
91349
91403
|
continue;
|
|
91350
91404
|
}
|
|
@@ -91386,7 +91440,7 @@ async function scanDocIndex(directory) {
|
|
|
91386
91440
|
});
|
|
91387
91441
|
}
|
|
91388
91442
|
};
|
|
91389
|
-
await
|
|
91443
|
+
await walkDir2(directory);
|
|
91390
91444
|
if (!rootReadable) {
|
|
91391
91445
|
return {
|
|
91392
91446
|
manifest: {
|
|
@@ -91531,13 +91585,13 @@ async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
|
91531
91585
|
}
|
|
91532
91586
|
return { extracted: extractedCount, skipped: skippedCount, details };
|
|
91533
91587
|
}
|
|
91534
|
-
var
|
|
91588
|
+
var SKIP_DIRECTORIES4, SKIP_PATTERNS, MAX_SUMMARY_LENGTH = 200, MAX_INDEXED_FILES = 100, READ_LINES_LIMIT = 30, MIN_LESSON_LENGTH = 15, MAX_CONSTRAINTS_PER_DOC = 5, MAX_CONSTRAINT_LENGTH = 200, RELEVANCE_THRESHOLD = 0.1, DEDUP_THRESHOLD = 0.6, CONSTRAINT_PATTERNS, ACTION_WORDS, doc_scan, doc_extract;
|
|
91535
91589
|
var init_doc_scan = __esm(() => {
|
|
91536
91590
|
init_zod();
|
|
91537
91591
|
init_schema();
|
|
91538
91592
|
init_knowledge_store();
|
|
91539
91593
|
init_create_tool();
|
|
91540
|
-
|
|
91594
|
+
SKIP_DIRECTORIES4 = new Set([
|
|
91541
91595
|
"node_modules",
|
|
91542
91596
|
".git",
|
|
91543
91597
|
".swarm",
|
|
@@ -92391,11 +92445,11 @@ __export(exports_design_doc_drift, {
|
|
|
92391
92445
|
runDesignDocDriftCheck: () => runDesignDocDriftCheck,
|
|
92392
92446
|
_internals: () => _internals60
|
|
92393
92447
|
});
|
|
92394
|
-
import * as
|
|
92395
|
-
import * as
|
|
92448
|
+
import * as fs99 from "node:fs";
|
|
92449
|
+
import * as path138 from "node:path";
|
|
92396
92450
|
function mtimeMsOrNull(absPath) {
|
|
92397
92451
|
try {
|
|
92398
|
-
return
|
|
92452
|
+
return fs99.statSync(absPath).mtimeMs;
|
|
92399
92453
|
} catch {
|
|
92400
92454
|
return null;
|
|
92401
92455
|
}
|
|
@@ -92403,40 +92457,40 @@ function mtimeMsOrNull(absPath) {
|
|
|
92403
92457
|
function resolveAnchorWithin(directory, anchor) {
|
|
92404
92458
|
if (!anchor || typeof anchor !== "string")
|
|
92405
92459
|
return null;
|
|
92406
|
-
const root =
|
|
92407
|
-
const resolved =
|
|
92408
|
-
const rel =
|
|
92409
|
-
if (rel.startsWith("..") ||
|
|
92460
|
+
const root = path138.resolve(directory);
|
|
92461
|
+
const resolved = path138.resolve(root, anchor);
|
|
92462
|
+
const rel = path138.relative(root, resolved);
|
|
92463
|
+
if (rel.startsWith("..") || path138.isAbsolute(rel))
|
|
92410
92464
|
return null;
|
|
92411
92465
|
return resolved;
|
|
92412
92466
|
}
|
|
92413
92467
|
async function runDesignDocDriftCheck(directory, phase, outDir) {
|
|
92414
92468
|
try {
|
|
92415
|
-
const root =
|
|
92416
|
-
const outAbs =
|
|
92417
|
-
const outRel =
|
|
92418
|
-
if (outRel.startsWith("..") ||
|
|
92469
|
+
const root = path138.resolve(directory);
|
|
92470
|
+
const outAbs = path138.resolve(root, outDir);
|
|
92471
|
+
const outRel = path138.relative(root, outAbs);
|
|
92472
|
+
if (outRel.startsWith("..") || path138.isAbsolute(outRel)) {
|
|
92419
92473
|
return null;
|
|
92420
92474
|
}
|
|
92421
92475
|
const docMtimes = new Map;
|
|
92422
92476
|
const checkedDocs = [];
|
|
92423
92477
|
const missingDocs = [];
|
|
92424
92478
|
for (const [docName, relFile] of Object.entries(DESIGN_DOC_FILES)) {
|
|
92425
|
-
const abs =
|
|
92479
|
+
const abs = path138.join(outAbs, relFile);
|
|
92426
92480
|
const mtime = mtimeMsOrNull(abs);
|
|
92427
92481
|
docMtimes.set(docName, mtime);
|
|
92428
92482
|
if (mtime === null) {
|
|
92429
|
-
missingDocs.push(
|
|
92483
|
+
missingDocs.push(path138.join(outDir, relFile));
|
|
92430
92484
|
} else {
|
|
92431
|
-
checkedDocs.push(
|
|
92485
|
+
checkedDocs.push(path138.join(outDir, relFile));
|
|
92432
92486
|
}
|
|
92433
92487
|
}
|
|
92434
|
-
const traceabilityAbs =
|
|
92488
|
+
const traceabilityAbs = path138.join(outAbs, TRACEABILITY_REL);
|
|
92435
92489
|
let registry3 = null;
|
|
92436
92490
|
try {
|
|
92437
|
-
const stat9 = await
|
|
92491
|
+
const stat9 = await fs99.promises.stat(traceabilityAbs);
|
|
92438
92492
|
if (stat9.size <= MAX_TRACEABILITY_BYTES) {
|
|
92439
|
-
const raw = await
|
|
92493
|
+
const raw = await fs99.promises.readFile(traceabilityAbs, "utf-8");
|
|
92440
92494
|
const parsed = JSON.parse(raw);
|
|
92441
92495
|
registry3 = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
92442
92496
|
}
|
|
@@ -92444,7 +92498,7 @@ async function runDesignDocDriftCheck(directory, phase, outDir) {
|
|
|
92444
92498
|
registry3 = null;
|
|
92445
92499
|
}
|
|
92446
92500
|
const noDocs = checkedDocs.length === 0 || registry3 === null;
|
|
92447
|
-
const specMtime = mtimeMsOrNull(
|
|
92501
|
+
const specMtime = mtimeMsOrNull(path138.join(root, ".swarm", "spec.md"));
|
|
92448
92502
|
const staleSections = [];
|
|
92449
92503
|
if (!noDocs && Array.isArray(registry3?.sections)) {
|
|
92450
92504
|
for (const section of registry3.sections) {
|
|
@@ -92500,8 +92554,8 @@ async function runDesignDocDriftCheck(directory, phase, outDir) {
|
|
|
92500
92554
|
};
|
|
92501
92555
|
const filename = `${DOC_DRIFT_REPORT_PREFIX}${phase}.json`;
|
|
92502
92556
|
const filePath = validateSwarmPath(directory, filename);
|
|
92503
|
-
await
|
|
92504
|
-
await
|
|
92557
|
+
await fs99.promises.mkdir(path138.dirname(filePath), { recursive: true });
|
|
92558
|
+
await fs99.promises.writeFile(filePath, JSON.stringify(report, null, 2), "utf-8");
|
|
92505
92559
|
getGlobalEventBus().publish("curator.docdrift.completed", {
|
|
92506
92560
|
phase,
|
|
92507
92561
|
verdict,
|
|
@@ -92531,10 +92585,10 @@ var init_design_doc_drift = __esm(() => {
|
|
|
92531
92585
|
domain: "domain.md",
|
|
92532
92586
|
"technical-spec": "technical-spec.md",
|
|
92533
92587
|
"behavior-spec": "behavior-spec.md",
|
|
92534
|
-
"reference-impl":
|
|
92535
|
-
"idiom-notes":
|
|
92588
|
+
"reference-impl": path138.join("reference", "reference-impl.md"),
|
|
92589
|
+
"idiom-notes": path138.join("reference", "idiom-notes.md")
|
|
92536
92590
|
};
|
|
92537
|
-
TRACEABILITY_REL =
|
|
92591
|
+
TRACEABILITY_REL = path138.join("reference", "traceability.json");
|
|
92538
92592
|
_internals60 = {
|
|
92539
92593
|
mtimeMsOrNull,
|
|
92540
92594
|
resolveAnchorWithin,
|
|
@@ -92549,12 +92603,12 @@ __export(exports_project_context, {
|
|
|
92549
92603
|
_internals: () => _internals71,
|
|
92550
92604
|
LANG_BACKEND_DETECTION_TIMEOUT_MS: () => LANG_BACKEND_DETECTION_TIMEOUT_MS
|
|
92551
92605
|
});
|
|
92552
|
-
import * as
|
|
92553
|
-
import * as
|
|
92606
|
+
import * as fs123 from "node:fs";
|
|
92607
|
+
import * as path167 from "node:path";
|
|
92554
92608
|
function detectFileExists2(directory, pattern) {
|
|
92555
92609
|
if (pattern.includes("*") || pattern.includes("?")) {
|
|
92556
92610
|
try {
|
|
92557
|
-
const files =
|
|
92611
|
+
const files = fs123.readdirSync(directory);
|
|
92558
92612
|
const regex = new RegExp(`^${pattern.replace(/\./g, "\\.").replace(/\*/g, ".*").replace(/\?/g, ".")}$`);
|
|
92559
92613
|
return files.some((f) => regex.test(f));
|
|
92560
92614
|
} catch {
|
|
@@ -92562,7 +92616,7 @@ function detectFileExists2(directory, pattern) {
|
|
|
92562
92616
|
}
|
|
92563
92617
|
}
|
|
92564
92618
|
try {
|
|
92565
|
-
|
|
92619
|
+
fs123.accessSync(path167.join(directory, pattern));
|
|
92566
92620
|
return true;
|
|
92567
92621
|
} catch {
|
|
92568
92622
|
return false;
|
|
@@ -92571,7 +92625,7 @@ function detectFileExists2(directory, pattern) {
|
|
|
92571
92625
|
function selectTestCommandFromScriptsTest(backend, directory) {
|
|
92572
92626
|
let pkgRaw;
|
|
92573
92627
|
try {
|
|
92574
|
-
pkgRaw =
|
|
92628
|
+
pkgRaw = fs123.readFileSync(path167.join(directory, "package.json"), "utf-8");
|
|
92575
92629
|
} catch {
|
|
92576
92630
|
return null;
|
|
92577
92631
|
}
|
|
@@ -92680,7 +92734,7 @@ var init_project_context = __esm(() => {
|
|
|
92680
92734
|
init_package();
|
|
92681
92735
|
init_agents2();
|
|
92682
92736
|
init_critic();
|
|
92683
|
-
import * as
|
|
92737
|
+
import * as path168 from "node:path";
|
|
92684
92738
|
|
|
92685
92739
|
// src/background/index.ts
|
|
92686
92740
|
init_event_bus();
|
|
@@ -95444,7 +95498,29 @@ init_path_security();
|
|
|
95444
95498
|
import * as fs49 from "node:fs";
|
|
95445
95499
|
import * as path79 from "node:path";
|
|
95446
95500
|
var MAX_FILE_SIZE_BYTES2 = 1024 * 1024;
|
|
95501
|
+
var MAX_WORKSPACE_RESULTS = 50;
|
|
95502
|
+
var MAX_WORKSPACE_SCANNED_FILES = 200;
|
|
95503
|
+
var WORKSPACE_TIMEOUT_MS = 1e4;
|
|
95447
95504
|
var WINDOWS_RESERVED_NAMES = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
95505
|
+
var SYMBOL_EXTENSIONS = new Set([
|
|
95506
|
+
".ts",
|
|
95507
|
+
".tsx",
|
|
95508
|
+
".js",
|
|
95509
|
+
".jsx",
|
|
95510
|
+
".mjs",
|
|
95511
|
+
".cjs",
|
|
95512
|
+
".py"
|
|
95513
|
+
]);
|
|
95514
|
+
var SKIP_DIRECTORIES2 = new Set([
|
|
95515
|
+
"node_modules",
|
|
95516
|
+
".git",
|
|
95517
|
+
"dist",
|
|
95518
|
+
"build",
|
|
95519
|
+
"out",
|
|
95520
|
+
".next",
|
|
95521
|
+
"coverage",
|
|
95522
|
+
"__pycache__"
|
|
95523
|
+
]);
|
|
95448
95524
|
function containsWindowsAttacks(str) {
|
|
95449
95525
|
if (/:[^\\/]/.test(str)) {
|
|
95450
95526
|
return true;
|
|
@@ -95689,28 +95765,135 @@ function extractPythonSymbols(filePath, cwd) {
|
|
|
95689
95765
|
return a.name.localeCompare(b.name);
|
|
95690
95766
|
});
|
|
95691
95767
|
}
|
|
95768
|
+
function findSourceFiles(cwd, maxFiles) {
|
|
95769
|
+
const files = [];
|
|
95770
|
+
walkDir(cwd, cwd, files, maxFiles);
|
|
95771
|
+
return files;
|
|
95772
|
+
}
|
|
95773
|
+
function walkDir(currentDir, rootDir, files, maxFiles) {
|
|
95774
|
+
let entries;
|
|
95775
|
+
try {
|
|
95776
|
+
entries = fs49.readdirSync(currentDir, { withFileTypes: true });
|
|
95777
|
+
} catch {
|
|
95778
|
+
return;
|
|
95779
|
+
}
|
|
95780
|
+
entries.sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()));
|
|
95781
|
+
for (const entry of entries) {
|
|
95782
|
+
if (files.length >= maxFiles)
|
|
95783
|
+
return;
|
|
95784
|
+
if (SKIP_DIRECTORIES2.has(entry.name))
|
|
95785
|
+
continue;
|
|
95786
|
+
const fullPath = path79.join(currentDir, entry.name);
|
|
95787
|
+
if (entry.isDirectory()) {
|
|
95788
|
+
walkDir(fullPath, rootDir, files, maxFiles);
|
|
95789
|
+
} else if (entry.isFile() && SYMBOL_EXTENSIONS.has(path79.extname(entry.name).toLowerCase())) {
|
|
95790
|
+
files.push(path79.relative(rootDir, fullPath));
|
|
95791
|
+
}
|
|
95792
|
+
}
|
|
95793
|
+
}
|
|
95794
|
+
function searchWorkspaceSymbols(cwd, name2, exportedOnly = true) {
|
|
95795
|
+
const startTime = Date.now();
|
|
95796
|
+
const sourceFiles = findSourceFiles(cwd, MAX_WORKSPACE_SCANNED_FILES);
|
|
95797
|
+
const files = [];
|
|
95798
|
+
let scannedCount = 0;
|
|
95799
|
+
let truncated = false;
|
|
95800
|
+
if (sourceFiles.length >= MAX_WORKSPACE_SCANNED_FILES) {
|
|
95801
|
+
truncated = true;
|
|
95802
|
+
}
|
|
95803
|
+
let totalSymbols = 0;
|
|
95804
|
+
for (const relFile of sourceFiles) {
|
|
95805
|
+
if (Date.now() - startTime > WORKSPACE_TIMEOUT_MS) {
|
|
95806
|
+
truncated = true;
|
|
95807
|
+
break;
|
|
95808
|
+
}
|
|
95809
|
+
scannedCount++;
|
|
95810
|
+
let syms;
|
|
95811
|
+
const ext = path79.extname(relFile).toLowerCase();
|
|
95812
|
+
switch (ext) {
|
|
95813
|
+
case ".ts":
|
|
95814
|
+
case ".tsx":
|
|
95815
|
+
case ".js":
|
|
95816
|
+
case ".jsx":
|
|
95817
|
+
case ".mjs":
|
|
95818
|
+
case ".cjs":
|
|
95819
|
+
syms = extractTSSymbols(relFile, cwd);
|
|
95820
|
+
break;
|
|
95821
|
+
case ".py":
|
|
95822
|
+
syms = extractPythonSymbols(relFile, cwd);
|
|
95823
|
+
break;
|
|
95824
|
+
default:
|
|
95825
|
+
continue;
|
|
95826
|
+
}
|
|
95827
|
+
if (exportedOnly) {
|
|
95828
|
+
syms = syms.filter((s) => s.exported);
|
|
95829
|
+
}
|
|
95830
|
+
if (name2) {
|
|
95831
|
+
syms = syms.filter((s) => s.name.includes(name2));
|
|
95832
|
+
}
|
|
95833
|
+
if (syms.length > 0) {
|
|
95834
|
+
const remaining = MAX_WORKSPACE_RESULTS - totalSymbols;
|
|
95835
|
+
if (remaining <= 0) {
|
|
95836
|
+
truncated = true;
|
|
95837
|
+
break;
|
|
95838
|
+
}
|
|
95839
|
+
const cappedSyms = syms.slice(0, remaining);
|
|
95840
|
+
files.push({
|
|
95841
|
+
file: relFile,
|
|
95842
|
+
symbolCount: cappedSyms.length,
|
|
95843
|
+
symbols: cappedSyms
|
|
95844
|
+
});
|
|
95845
|
+
totalSymbols += cappedSyms.length;
|
|
95846
|
+
if (totalSymbols >= MAX_WORKSPACE_RESULTS) {
|
|
95847
|
+
truncated = syms.length > remaining || scannedCount < sourceFiles.length;
|
|
95848
|
+
break;
|
|
95849
|
+
}
|
|
95850
|
+
}
|
|
95851
|
+
}
|
|
95852
|
+
return {
|
|
95853
|
+
query: { workspace: true, name: name2 },
|
|
95854
|
+
fileCount: files.length,
|
|
95855
|
+
scannedFileCount: scannedCount,
|
|
95856
|
+
totalSymbols,
|
|
95857
|
+
files,
|
|
95858
|
+
truncated
|
|
95859
|
+
};
|
|
95860
|
+
}
|
|
95692
95861
|
var symbols = createSwarmTool({
|
|
95693
95862
|
description: "Extract all exported symbols from a source file: functions with signatures, " + "classes with public members, interfaces, types, enums, constants. " + "Supports TypeScript/JavaScript and Python. Use for architect planning, " + "designer scaffolding, and understanding module public API surface.",
|
|
95694
95863
|
args: {
|
|
95695
|
-
file: exports_external.string().describe('File path to extract symbols from (e.g., "src/auth/login.ts")'),
|
|
95696
|
-
exported_only: exports_external.boolean().default(true).describe("If true, only return exported/public symbols. If false, include all top-level symbols.")
|
|
95864
|
+
file: exports_external.string().optional().describe('File path to extract symbols from (e.g., "src/auth/login.ts"). Required when not using workspace mode.'),
|
|
95865
|
+
exported_only: exports_external.boolean().default(true).describe("If true, only return exported/public symbols. If false, include all top-level symbols."),
|
|
95866
|
+
workspace: exports_external.boolean().optional().describe("When true, search across the workspace instead of a single file. Returns per-file symbol summaries."),
|
|
95867
|
+
name: exports_external.string().optional().describe("Search for symbols by name (case-sensitive substring match). When provided without workspace, only searches the specified file.")
|
|
95697
95868
|
},
|
|
95698
95869
|
execute: async (args2, directory) => {
|
|
95699
95870
|
let file3;
|
|
95700
95871
|
let exportedOnly = true;
|
|
95872
|
+
let workspace = false;
|
|
95873
|
+
let name2;
|
|
95701
95874
|
try {
|
|
95702
95875
|
const obj = args2;
|
|
95703
|
-
file3 =
|
|
95876
|
+
file3 = obj.file != null && typeof obj.file === "string" ? obj.file : undefined;
|
|
95704
95877
|
exportedOnly = obj.exported_only === true;
|
|
95878
|
+
workspace = obj.workspace === true;
|
|
95879
|
+
name2 = obj.name != null && typeof obj.name === "string" ? obj.name : undefined;
|
|
95705
95880
|
} catch {
|
|
95706
95881
|
return JSON.stringify({
|
|
95707
95882
|
file: "<unknown>",
|
|
95708
|
-
error: "Invalid arguments: could not extract
|
|
95883
|
+
error: "Invalid arguments: could not extract parameters",
|
|
95709
95884
|
symbols: []
|
|
95710
95885
|
}, null, 2);
|
|
95711
95886
|
}
|
|
95712
95887
|
const cwd = directory;
|
|
95713
|
-
|
|
95888
|
+
if (workspace) {
|
|
95889
|
+
return JSON.stringify(searchWorkspaceSymbols(cwd, name2, exportedOnly), null, 2);
|
|
95890
|
+
}
|
|
95891
|
+
if (!file3) {
|
|
95892
|
+
return JSON.stringify({
|
|
95893
|
+
error: "file parameter is required when not using workspace mode",
|
|
95894
|
+
symbols: []
|
|
95895
|
+
}, null, 2);
|
|
95896
|
+
}
|
|
95714
95897
|
if (containsControlChars(file3)) {
|
|
95715
95898
|
return JSON.stringify({
|
|
95716
95899
|
file: file3,
|
|
@@ -95739,6 +95922,7 @@ var symbols = createSwarmTool({
|
|
|
95739
95922
|
symbols: []
|
|
95740
95923
|
}, null, 2);
|
|
95741
95924
|
}
|
|
95925
|
+
const ext = path79.extname(file3);
|
|
95742
95926
|
let syms;
|
|
95743
95927
|
switch (ext) {
|
|
95744
95928
|
case ".ts":
|
|
@@ -95762,6 +95946,9 @@ var symbols = createSwarmTool({
|
|
|
95762
95946
|
if (exportedOnly) {
|
|
95763
95947
|
syms = syms.filter((s) => s.exported);
|
|
95764
95948
|
}
|
|
95949
|
+
if (name2) {
|
|
95950
|
+
syms = syms.filter((s) => s.name.includes(name2));
|
|
95951
|
+
}
|
|
95765
95952
|
return JSON.stringify({
|
|
95766
95953
|
file: file3,
|
|
95767
95954
|
symbolCount: syms.length,
|
|
@@ -95910,7 +96097,7 @@ var _internals43 = {
|
|
|
95910
96097
|
extractPythonSymbols,
|
|
95911
96098
|
parseFileImports
|
|
95912
96099
|
};
|
|
95913
|
-
var
|
|
96100
|
+
var SKIP_DIRECTORIES3 = new Set([
|
|
95914
96101
|
"node_modules",
|
|
95915
96102
|
".git",
|
|
95916
96103
|
"dist",
|
|
@@ -96143,7 +96330,7 @@ async function findSourceFilesAsync(dir, stats, options) {
|
|
|
96143
96330
|
if (isWalkBudgetExceeded(ctx) || isFileCapReached(ctx, files.length)) {
|
|
96144
96331
|
break;
|
|
96145
96332
|
}
|
|
96146
|
-
if (
|
|
96333
|
+
if (SKIP_DIRECTORIES3.has(entry.name)) {
|
|
96147
96334
|
ctx.stats.skippedDirs++;
|
|
96148
96335
|
continue;
|
|
96149
96336
|
}
|
|
@@ -98147,7 +98334,7 @@ var DEFAULT_SKIP_DIRS = new Set([
|
|
|
98147
98334
|
var MAX_FILE_SIZE_BYTES3 = 1024 * 1024;
|
|
98148
98335
|
var DEFAULT_MAX_FILES = 1e4;
|
|
98149
98336
|
var SOURCE_EXT_SET = new Set(SOURCE_EXTENSIONS2);
|
|
98150
|
-
function
|
|
98337
|
+
function findSourceFiles2(workspaceRoot, skipDirs = DEFAULT_SKIP_DIRS) {
|
|
98151
98338
|
const out2 = [];
|
|
98152
98339
|
const stack = [workspaceRoot];
|
|
98153
98340
|
while (stack.length > 0) {
|
|
@@ -98184,7 +98371,7 @@ function findSourceFiles(workspaceRoot, skipDirs = DEFAULT_SKIP_DIRS) {
|
|
|
98184
98371
|
}
|
|
98185
98372
|
async function buildRepoGraph(workspaceRoot, options = {}) {
|
|
98186
98373
|
const skipDirs = options.skipDirs ? new Set([...DEFAULT_SKIP_DIRS, ...options.skipDirs]) : DEFAULT_SKIP_DIRS;
|
|
98187
|
-
let files =
|
|
98374
|
+
let files = findSourceFiles2(workspaceRoot, skipDirs);
|
|
98188
98375
|
const cap = typeof options.maxFiles === "number" && options.maxFiles > 0 ? options.maxFiles : DEFAULT_MAX_FILES;
|
|
98189
98376
|
if (files.length > cap) {
|
|
98190
98377
|
files = files.slice(0, cap);
|
|
@@ -108666,6 +108853,7 @@ ${body2}`);
|
|
|
108666
108853
|
}
|
|
108667
108854
|
|
|
108668
108855
|
// src/council/council-evidence-writer.ts
|
|
108856
|
+
init_zod();
|
|
108669
108857
|
init_task_file();
|
|
108670
108858
|
import { appendFileSync as appendFileSync12, existsSync as existsSync63, mkdirSync as mkdirSync29, readFileSync as readFileSync45 } from "node:fs";
|
|
108671
108859
|
import { join as join95 } from "node:path";
|
|
@@ -108673,6 +108861,7 @@ var EVIDENCE_DIR2 = ".swarm/evidence";
|
|
|
108673
108861
|
var VALID_TASK_ID = /^\d+\.\d+(\.\d+)*$/;
|
|
108674
108862
|
var COUNCIL_GATE_NAME = "council";
|
|
108675
108863
|
var COUNCIL_AGENT_ID = "architect";
|
|
108864
|
+
var EvidenceFileSchema = exports_external.record(exports_external.string(), exports_external.unknown());
|
|
108676
108865
|
var _internals53 = {
|
|
108677
108866
|
withTaskEvidenceLock
|
|
108678
108867
|
};
|
|
@@ -108712,10 +108901,8 @@ async function writeCouncilEvidence(workingDir, synthesis) {
|
|
|
108712
108901
|
const existingRoot = Object.create(null);
|
|
108713
108902
|
if (existsSync63(filePath)) {
|
|
108714
108903
|
try {
|
|
108715
|
-
const parsed = JSON.parse(readFileSync45(filePath, "utf-8"));
|
|
108716
|
-
|
|
108717
|
-
safeAssignOwnProps(existingRoot, parsed);
|
|
108718
|
-
}
|
|
108904
|
+
const parsed = EvidenceFileSchema.parse(JSON.parse(readFileSync45(filePath, "utf-8")));
|
|
108905
|
+
safeAssignOwnProps(existingRoot, parsed);
|
|
108719
108906
|
} catch {}
|
|
108720
108907
|
}
|
|
108721
108908
|
const existingGatesRaw = existingRoot.gates;
|
|
@@ -109073,9 +109260,19 @@ function buildFinalCouncilFeedback(projectSummary, verdict, vetoedBy, requiredFi
|
|
|
109073
109260
|
}
|
|
109074
109261
|
|
|
109075
109262
|
// src/council/criteria-store.ts
|
|
109263
|
+
init_zod();
|
|
109076
109264
|
import { existsSync as existsSync64, mkdirSync as mkdirSync30, readFileSync as readFileSync46, writeFileSync as writeFileSync22 } from "node:fs";
|
|
109077
109265
|
import { join as join96 } from "node:path";
|
|
109078
109266
|
var COUNCIL_DIR = ".swarm/council";
|
|
109267
|
+
var CouncilCriteriaSchema = exports_external.object({
|
|
109268
|
+
taskId: exports_external.string(),
|
|
109269
|
+
criteria: exports_external.array(exports_external.object({
|
|
109270
|
+
id: exports_external.string(),
|
|
109271
|
+
description: exports_external.string(),
|
|
109272
|
+
mandatory: exports_external.boolean()
|
|
109273
|
+
})),
|
|
109274
|
+
declaredAt: exports_external.string()
|
|
109275
|
+
});
|
|
109079
109276
|
function writeCriteria(workingDir, taskId, criteria) {
|
|
109080
109277
|
const dir = join96(workingDir, COUNCIL_DIR);
|
|
109081
109278
|
mkdirSync30(dir, { recursive: true });
|
|
@@ -109091,11 +109288,7 @@ function readCriteria(workingDir, taskId) {
|
|
|
109091
109288
|
if (!existsSync64(filePath))
|
|
109092
109289
|
return null;
|
|
109093
109290
|
try {
|
|
109094
|
-
|
|
109095
|
-
if (parsed && typeof parsed === "object" && typeof parsed.taskId === "string" && Array.isArray(parsed.criteria)) {
|
|
109096
|
-
return parsed;
|
|
109097
|
-
}
|
|
109098
|
-
return null;
|
|
109291
|
+
return CouncilCriteriaSchema.parse(JSON.parse(readFileSync46(filePath, "utf-8")));
|
|
109099
109292
|
} catch {
|
|
109100
109293
|
return null;
|
|
109101
109294
|
}
|
|
@@ -110231,10 +110424,12 @@ var diff = createSwarmTool({
|
|
|
110231
110424
|
description: "Analyze git diff for changed files, exports, interfaces, and function signatures. Returns structured output with contract change detection.",
|
|
110232
110425
|
args: {
|
|
110233
110426
|
base: exports_external.string().optional().describe('Base ref to diff against (default: HEAD). Use "staged" for staged changes, "unstaged" for working tree changes.'),
|
|
110234
|
-
paths: exports_external.array(exports_external.string()).optional().describe("Optional file paths to restrict diff scope.")
|
|
110427
|
+
paths: exports_external.array(exports_external.string()).optional().describe("Optional file paths to restrict diff scope."),
|
|
110428
|
+
summaryOnly: exports_external.boolean().optional().describe("When true, return only file list with additions/deletions counts and hasContractChanges. No hunk content or AST diff. Default false.")
|
|
110235
110429
|
},
|
|
110236
110430
|
async execute(args2, directory, _ctx) {
|
|
110237
110431
|
const typedArgs = args2;
|
|
110432
|
+
const summaryOnly = typedArgs.summaryOnly === true;
|
|
110238
110433
|
try {
|
|
110239
110434
|
let fileExistsInRef = function(refPath) {
|
|
110240
110435
|
try {
|
|
@@ -110312,13 +110507,6 @@ var diff = createSwarmTool({
|
|
|
110312
110507
|
cwd: directory,
|
|
110313
110508
|
stdio: ["ignore", "pipe", "pipe"]
|
|
110314
110509
|
});
|
|
110315
|
-
const fullDiffOutput = child_process7.execFileSync("git", fullDiffArgs, {
|
|
110316
|
-
encoding: "utf-8",
|
|
110317
|
-
timeout: DIFF_TIMEOUT_MS,
|
|
110318
|
-
maxBuffer: MAX_BUFFER_BYTES,
|
|
110319
|
-
cwd: directory,
|
|
110320
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
110321
|
-
});
|
|
110322
110510
|
const files = [];
|
|
110323
110511
|
const numstatLines = numstatOutput.split(`
|
|
110324
110512
|
`);
|
|
@@ -110333,6 +110521,50 @@ var diff = createSwarmTool({
|
|
|
110333
110521
|
files.push({ path: path118, additions, deletions });
|
|
110334
110522
|
}
|
|
110335
110523
|
}
|
|
110524
|
+
if (summaryOnly) {
|
|
110525
|
+
let hasContractChanges2 = false;
|
|
110526
|
+
try {
|
|
110527
|
+
const contractDiffArgs = [...gitArgs, "-U0"];
|
|
110528
|
+
if (typedArgs.paths?.length) {
|
|
110529
|
+
contractDiffArgs.push("--", ...typedArgs.paths);
|
|
110530
|
+
}
|
|
110531
|
+
const contractDiffOutput = child_process7.execFileSync("git", contractDiffArgs, {
|
|
110532
|
+
encoding: "utf-8",
|
|
110533
|
+
timeout: DIFF_TIMEOUT_MS,
|
|
110534
|
+
maxBuffer: MAX_BUFFER_BYTES,
|
|
110535
|
+
cwd: directory,
|
|
110536
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
110537
|
+
});
|
|
110538
|
+
const contractDiffLines = contractDiffOutput.split(`
|
|
110539
|
+
`);
|
|
110540
|
+
for (const line of contractDiffLines) {
|
|
110541
|
+
for (const pattern of CONTRACT_PATTERNS) {
|
|
110542
|
+
if (pattern.test(line)) {
|
|
110543
|
+
hasContractChanges2 = true;
|
|
110544
|
+
break;
|
|
110545
|
+
}
|
|
110546
|
+
}
|
|
110547
|
+
if (hasContractChanges2)
|
|
110548
|
+
break;
|
|
110549
|
+
}
|
|
110550
|
+
} catch {
|
|
110551
|
+
hasContractChanges2 = true;
|
|
110552
|
+
}
|
|
110553
|
+
const result2 = {
|
|
110554
|
+
files,
|
|
110555
|
+
contractChanges: [],
|
|
110556
|
+
hasContractChanges: hasContractChanges2,
|
|
110557
|
+
summary: `${files.length} files changed (summary only)`
|
|
110558
|
+
};
|
|
110559
|
+
return JSON.stringify(result2, null, 2);
|
|
110560
|
+
}
|
|
110561
|
+
const fullDiffOutput = child_process7.execFileSync("git", fullDiffArgs, {
|
|
110562
|
+
encoding: "utf-8",
|
|
110563
|
+
timeout: DIFF_TIMEOUT_MS,
|
|
110564
|
+
maxBuffer: MAX_BUFFER_BYTES,
|
|
110565
|
+
cwd: directory,
|
|
110566
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
110567
|
+
});
|
|
110336
110568
|
const contractChanges = [];
|
|
110337
110569
|
const diffLines = fullDiffOutput.split(`
|
|
110338
110570
|
`);
|
|
@@ -111398,13 +111630,389 @@ var get_qa_gate_profile = createSwarmTool({
|
|
|
111398
111630
|
}
|
|
111399
111631
|
});
|
|
111400
111632
|
|
|
111633
|
+
// src/tools/git-blame.ts
|
|
111634
|
+
init_zod();
|
|
111635
|
+
init_path_security();
|
|
111636
|
+
init_create_tool();
|
|
111637
|
+
import * as child_process9 from "node:child_process";
|
|
111638
|
+
import * as fs83 from "node:fs";
|
|
111639
|
+
import * as path121 from "node:path";
|
|
111640
|
+
var BLAME_TIMEOUT_MS = 30000;
|
|
111641
|
+
var MAX_OUTPUT_LINES2 = 500;
|
|
111642
|
+
var MAX_PATH_LENGTH2 = 500;
|
|
111643
|
+
var MAX_LINE_NUMBER = 1e6;
|
|
111644
|
+
var SHELL_METACHARACTERS3 = /[;|&$`(){}<>!'"]/;
|
|
111645
|
+
var BINARY_EXTENSIONS = new Set([
|
|
111646
|
+
".png",
|
|
111647
|
+
".jpg",
|
|
111648
|
+
".jpeg",
|
|
111649
|
+
".gif",
|
|
111650
|
+
".bmp",
|
|
111651
|
+
".ico",
|
|
111652
|
+
".svg",
|
|
111653
|
+
".webp",
|
|
111654
|
+
".mp3",
|
|
111655
|
+
".mp4",
|
|
111656
|
+
".wav",
|
|
111657
|
+
".avi",
|
|
111658
|
+
".mov",
|
|
111659
|
+
".wmv",
|
|
111660
|
+
".flv",
|
|
111661
|
+
".zip",
|
|
111662
|
+
".tar",
|
|
111663
|
+
".gz",
|
|
111664
|
+
".rar",
|
|
111665
|
+
".7z",
|
|
111666
|
+
".bz2",
|
|
111667
|
+
".pdf",
|
|
111668
|
+
".doc",
|
|
111669
|
+
".docx",
|
|
111670
|
+
".xls",
|
|
111671
|
+
".xlsx",
|
|
111672
|
+
".ppt",
|
|
111673
|
+
".pptx",
|
|
111674
|
+
".exe",
|
|
111675
|
+
".dll",
|
|
111676
|
+
".so",
|
|
111677
|
+
".dylib",
|
|
111678
|
+
".bin",
|
|
111679
|
+
".dat",
|
|
111680
|
+
".o",
|
|
111681
|
+
".obj",
|
|
111682
|
+
".woff",
|
|
111683
|
+
".woff2",
|
|
111684
|
+
".ttf",
|
|
111685
|
+
".eot",
|
|
111686
|
+
".otf",
|
|
111687
|
+
".sqlite",
|
|
111688
|
+
".db"
|
|
111689
|
+
]);
|
|
111690
|
+
function validateFilePath(filePath) {
|
|
111691
|
+
if (!filePath || filePath.length === 0) {
|
|
111692
|
+
return "file path is required";
|
|
111693
|
+
}
|
|
111694
|
+
if (filePath.length > MAX_PATH_LENGTH2) {
|
|
111695
|
+
return `file path exceeds maximum length of ${MAX_PATH_LENGTH2}`;
|
|
111696
|
+
}
|
|
111697
|
+
if (path121.isAbsolute(filePath)) {
|
|
111698
|
+
return "absolute paths are not allowed; use a relative path from the project root";
|
|
111699
|
+
}
|
|
111700
|
+
if (containsPathTraversal(filePath)) {
|
|
111701
|
+
return "path traversal detected";
|
|
111702
|
+
}
|
|
111703
|
+
if (containsControlChars(filePath)) {
|
|
111704
|
+
return "file path contains control characters";
|
|
111705
|
+
}
|
|
111706
|
+
if (SHELL_METACHARACTERS3.test(filePath)) {
|
|
111707
|
+
return "file path contains shell metacharacters";
|
|
111708
|
+
}
|
|
111709
|
+
if (filePath.startsWith("-")) {
|
|
111710
|
+
return 'file path cannot start with "-"';
|
|
111711
|
+
}
|
|
111712
|
+
return null;
|
|
111713
|
+
}
|
|
111714
|
+
function validateLineNumber(value, name2) {
|
|
111715
|
+
if (typeof value === "undefined")
|
|
111716
|
+
return null;
|
|
111717
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 1) {
|
|
111718
|
+
return `${name2} must be a positive integer`;
|
|
111719
|
+
}
|
|
111720
|
+
if (value > MAX_LINE_NUMBER) {
|
|
111721
|
+
return `${name2} exceeds maximum value of ${MAX_LINE_NUMBER}`;
|
|
111722
|
+
}
|
|
111723
|
+
return null;
|
|
111724
|
+
}
|
|
111725
|
+
function isBinaryFile2(filePath) {
|
|
111726
|
+
const ext = path121.extname(filePath).toLowerCase();
|
|
111727
|
+
return BINARY_EXTENSIONS.has(ext);
|
|
111728
|
+
}
|
|
111729
|
+
function parsePorcelainBlame(output, linesCap) {
|
|
111730
|
+
const entries = [];
|
|
111731
|
+
const outputLines = output.split(`
|
|
111732
|
+
`);
|
|
111733
|
+
const cappedLines = outputLines.slice(0, linesCap * 8);
|
|
111734
|
+
const commitCache = new Map;
|
|
111735
|
+
let currentSha = "";
|
|
111736
|
+
let currentLine = 0;
|
|
111737
|
+
let currentAuthor = "";
|
|
111738
|
+
let currentAuthorTime = "";
|
|
111739
|
+
let currentSummary = "";
|
|
111740
|
+
for (const rawLine of cappedLines) {
|
|
111741
|
+
const headerMatch = rawLine.match(/^([0-9a-f]{40})\s+(\d+)\s+(\d+)/);
|
|
111742
|
+
if (headerMatch) {
|
|
111743
|
+
currentSha = headerMatch[1];
|
|
111744
|
+
currentLine = Number.parseInt(headerMatch[3], 10);
|
|
111745
|
+
const cached3 = commitCache.get(currentSha);
|
|
111746
|
+
if (cached3) {
|
|
111747
|
+
currentAuthor = cached3.author;
|
|
111748
|
+
currentAuthorTime = cached3.authorTime;
|
|
111749
|
+
currentSummary = cached3.summary;
|
|
111750
|
+
} else {
|
|
111751
|
+
currentAuthor = "";
|
|
111752
|
+
currentAuthorTime = "";
|
|
111753
|
+
currentSummary = "";
|
|
111754
|
+
}
|
|
111755
|
+
continue;
|
|
111756
|
+
}
|
|
111757
|
+
if (rawLine.startsWith("author ")) {
|
|
111758
|
+
currentAuthor = rawLine.slice(7);
|
|
111759
|
+
let meta3 = commitCache.get(currentSha);
|
|
111760
|
+
if (!meta3) {
|
|
111761
|
+
meta3 = { author: "", authorTime: "", summary: "" };
|
|
111762
|
+
commitCache.set(currentSha, meta3);
|
|
111763
|
+
}
|
|
111764
|
+
meta3.author = currentAuthor;
|
|
111765
|
+
continue;
|
|
111766
|
+
}
|
|
111767
|
+
if (rawLine.startsWith("author-time ")) {
|
|
111768
|
+
currentAuthorTime = rawLine.slice(12);
|
|
111769
|
+
let meta3 = commitCache.get(currentSha);
|
|
111770
|
+
if (!meta3) {
|
|
111771
|
+
meta3 = { author: "", authorTime: "", summary: "" };
|
|
111772
|
+
commitCache.set(currentSha, meta3);
|
|
111773
|
+
}
|
|
111774
|
+
meta3.authorTime = currentAuthorTime;
|
|
111775
|
+
continue;
|
|
111776
|
+
}
|
|
111777
|
+
if (rawLine.startsWith("summary ")) {
|
|
111778
|
+
currentSummary = rawLine.slice(8);
|
|
111779
|
+
let meta3 = commitCache.get(currentSha);
|
|
111780
|
+
if (!meta3) {
|
|
111781
|
+
meta3 = { author: "", authorTime: "", summary: "" };
|
|
111782
|
+
commitCache.set(currentSha, meta3);
|
|
111783
|
+
}
|
|
111784
|
+
meta3.summary = currentSummary;
|
|
111785
|
+
continue;
|
|
111786
|
+
}
|
|
111787
|
+
if (rawLine.startsWith("\t")) {
|
|
111788
|
+
entries.push({
|
|
111789
|
+
line: currentLine,
|
|
111790
|
+
sha: currentSha.slice(0, 8),
|
|
111791
|
+
author: currentAuthor,
|
|
111792
|
+
authorTime: currentAuthorTime,
|
|
111793
|
+
summary: currentSummary,
|
|
111794
|
+
content: rawLine.slice(1)
|
|
111795
|
+
});
|
|
111796
|
+
if (entries.length >= linesCap)
|
|
111797
|
+
break;
|
|
111798
|
+
}
|
|
111799
|
+
}
|
|
111800
|
+
return entries.slice(0, linesCap);
|
|
111801
|
+
}
|
|
111802
|
+
var git_blame = createSwarmTool({
|
|
111803
|
+
description: "Analyze per-line git blame metadata for a file. Returns sha (abbreviated), author, date (ISO), summary, and content for each line. Uses git blame --porcelain. Rejects binary files and validates paths.",
|
|
111804
|
+
args: {
|
|
111805
|
+
file: exports_external.string().describe("Relative file path to blame (required, relative to project root)"),
|
|
111806
|
+
start: exports_external.number().optional().describe("Optional start line number (1-indexed). Requires end parameter."),
|
|
111807
|
+
end: exports_external.number().optional().describe("Optional end line number (1-indexed, inclusive). Requires start parameter.")
|
|
111808
|
+
},
|
|
111809
|
+
async execute(args2, directory) {
|
|
111810
|
+
let fileInput;
|
|
111811
|
+
let startInput;
|
|
111812
|
+
let endInput;
|
|
111813
|
+
try {
|
|
111814
|
+
if (args2 && typeof args2 === "object") {
|
|
111815
|
+
const obj = args2;
|
|
111816
|
+
fileInput = typeof obj.file === "string" ? obj.file : undefined;
|
|
111817
|
+
startInput = typeof obj.start === "number" ? obj.start : undefined;
|
|
111818
|
+
endInput = typeof obj.end === "number" ? obj.end : undefined;
|
|
111819
|
+
}
|
|
111820
|
+
} catch {}
|
|
111821
|
+
if (!fileInput) {
|
|
111822
|
+
return JSON.stringify({
|
|
111823
|
+
error: "file path is required",
|
|
111824
|
+
file: String(fileInput ?? ""),
|
|
111825
|
+
lineCount: 0,
|
|
111826
|
+
lines: []
|
|
111827
|
+
});
|
|
111828
|
+
}
|
|
111829
|
+
const file3 = fileInput;
|
|
111830
|
+
const pathError = validateFilePath(file3);
|
|
111831
|
+
if (pathError) {
|
|
111832
|
+
return JSON.stringify({
|
|
111833
|
+
error: pathError,
|
|
111834
|
+
file: file3,
|
|
111835
|
+
lineCount: 0,
|
|
111836
|
+
lines: []
|
|
111837
|
+
});
|
|
111838
|
+
}
|
|
111839
|
+
const startError = validateLineNumber(startInput, "start");
|
|
111840
|
+
if (startError) {
|
|
111841
|
+
return JSON.stringify({
|
|
111842
|
+
error: startError,
|
|
111843
|
+
file: file3,
|
|
111844
|
+
lineCount: 0,
|
|
111845
|
+
lines: []
|
|
111846
|
+
});
|
|
111847
|
+
}
|
|
111848
|
+
const endError = validateLineNumber(endInput, "end");
|
|
111849
|
+
if (endError) {
|
|
111850
|
+
return JSON.stringify({
|
|
111851
|
+
error: endError,
|
|
111852
|
+
file: file3,
|
|
111853
|
+
lineCount: 0,
|
|
111854
|
+
lines: []
|
|
111855
|
+
});
|
|
111856
|
+
}
|
|
111857
|
+
if (startInput !== undefined && endInput === undefined || startInput === undefined && endInput !== undefined) {
|
|
111858
|
+
return JSON.stringify({
|
|
111859
|
+
error: "both start and end must be provided together for a line range",
|
|
111860
|
+
file: file3,
|
|
111861
|
+
lineCount: 0,
|
|
111862
|
+
lines: []
|
|
111863
|
+
});
|
|
111864
|
+
}
|
|
111865
|
+
if (startInput !== undefined && endInput !== undefined && startInput > endInput) {
|
|
111866
|
+
return JSON.stringify({
|
|
111867
|
+
error: "start must be less than or equal to end",
|
|
111868
|
+
file: file3,
|
|
111869
|
+
lineCount: 0,
|
|
111870
|
+
lines: []
|
|
111871
|
+
});
|
|
111872
|
+
}
|
|
111873
|
+
const resolvedPath = path121.resolve(directory, file3);
|
|
111874
|
+
if (!fs83.existsSync(resolvedPath)) {
|
|
111875
|
+
return JSON.stringify({
|
|
111876
|
+
error: `file not found: ${file3}`,
|
|
111877
|
+
file: file3,
|
|
111878
|
+
lineCount: 0,
|
|
111879
|
+
lines: []
|
|
111880
|
+
});
|
|
111881
|
+
}
|
|
111882
|
+
const realDir = fs83.realpathSync(directory);
|
|
111883
|
+
const realPath = fs83.realpathSync(resolvedPath);
|
|
111884
|
+
const relative25 = path121.relative(realDir, realPath);
|
|
111885
|
+
if (relative25.startsWith("..") || path121.isAbsolute(relative25)) {
|
|
111886
|
+
return JSON.stringify({
|
|
111887
|
+
error: "file path resolves outside the workspace",
|
|
111888
|
+
file: file3,
|
|
111889
|
+
lineCount: 0,
|
|
111890
|
+
lines: []
|
|
111891
|
+
});
|
|
111892
|
+
}
|
|
111893
|
+
const stat9 = fs83.statSync(resolvedPath);
|
|
111894
|
+
if (stat9.isDirectory()) {
|
|
111895
|
+
return JSON.stringify({
|
|
111896
|
+
error: "path is a directory, not a file",
|
|
111897
|
+
file: file3,
|
|
111898
|
+
lineCount: 0,
|
|
111899
|
+
lines: []
|
|
111900
|
+
});
|
|
111901
|
+
}
|
|
111902
|
+
if (isBinaryFile2(file3)) {
|
|
111903
|
+
return JSON.stringify({
|
|
111904
|
+
error: "binary files are not supported for git blame",
|
|
111905
|
+
file: file3,
|
|
111906
|
+
lineCount: 0,
|
|
111907
|
+
lines: []
|
|
111908
|
+
});
|
|
111909
|
+
}
|
|
111910
|
+
const gitArgs = ["blame", "--porcelain"];
|
|
111911
|
+
if (startInput !== undefined && endInput !== undefined) {
|
|
111912
|
+
gitArgs.push("-L", `${startInput},${endInput}`);
|
|
111913
|
+
}
|
|
111914
|
+
gitArgs.push("--", file3);
|
|
111915
|
+
const result = child_process9.spawnSync("git", gitArgs, {
|
|
111916
|
+
cwd: directory,
|
|
111917
|
+
encoding: "utf-8",
|
|
111918
|
+
timeout: BLAME_TIMEOUT_MS,
|
|
111919
|
+
windowsHide: true,
|
|
111920
|
+
maxBuffer: 5 * 1024 * 1024,
|
|
111921
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
111922
|
+
});
|
|
111923
|
+
if (result.error) {
|
|
111924
|
+
const isTimeout = "code" in result.error && result.error.code === "ETIMEDOUT";
|
|
111925
|
+
if (isTimeout) {
|
|
111926
|
+
return JSON.stringify({
|
|
111927
|
+
error: "git blame timed out",
|
|
111928
|
+
file: file3,
|
|
111929
|
+
lineCount: 0,
|
|
111930
|
+
lines: []
|
|
111931
|
+
});
|
|
111932
|
+
}
|
|
111933
|
+
const message = result.error instanceof Error ? result.error.message : String(result.error);
|
|
111934
|
+
if (message.includes("ENOENT") || message.includes("not found")) {
|
|
111935
|
+
return JSON.stringify({
|
|
111936
|
+
error: "git is not available or not in PATH",
|
|
111937
|
+
file: file3,
|
|
111938
|
+
lineCount: 0,
|
|
111939
|
+
lines: []
|
|
111940
|
+
});
|
|
111941
|
+
}
|
|
111942
|
+
return JSON.stringify({
|
|
111943
|
+
error: `git execution failed: ${message}`,
|
|
111944
|
+
file: file3,
|
|
111945
|
+
lineCount: 0,
|
|
111946
|
+
lines: []
|
|
111947
|
+
});
|
|
111948
|
+
}
|
|
111949
|
+
if (result.status !== 0) {
|
|
111950
|
+
const stderr = (result.stderr ?? "").trim();
|
|
111951
|
+
if (stderr.includes("not a git repository") || stderr.includes("not in a git repository")) {
|
|
111952
|
+
return JSON.stringify({
|
|
111953
|
+
error: "not a git repository",
|
|
111954
|
+
file: file3,
|
|
111955
|
+
lineCount: 0,
|
|
111956
|
+
lines: []
|
|
111957
|
+
});
|
|
111958
|
+
}
|
|
111959
|
+
if (stderr.includes("no such path") || stderr.includes("did not match any files")) {
|
|
111960
|
+
return JSON.stringify({
|
|
111961
|
+
error: `file not tracked by git: ${file3}`,
|
|
111962
|
+
file: file3,
|
|
111963
|
+
lineCount: 0,
|
|
111964
|
+
lines: []
|
|
111965
|
+
});
|
|
111966
|
+
}
|
|
111967
|
+
return JSON.stringify({
|
|
111968
|
+
error: `git blame failed: ${stderr || `exit code ${result.status}`}`,
|
|
111969
|
+
file: file3,
|
|
111970
|
+
lineCount: 0,
|
|
111971
|
+
lines: []
|
|
111972
|
+
});
|
|
111973
|
+
}
|
|
111974
|
+
if (result.signal === "SIGTERM" || result.signal === "SIGKILL") {
|
|
111975
|
+
return JSON.stringify({
|
|
111976
|
+
error: "git blame timed out",
|
|
111977
|
+
file: file3,
|
|
111978
|
+
lineCount: 0,
|
|
111979
|
+
lines: []
|
|
111980
|
+
});
|
|
111981
|
+
}
|
|
111982
|
+
const stdout = result.stdout ?? "";
|
|
111983
|
+
if (!stdout.trim()) {
|
|
111984
|
+
return JSON.stringify({
|
|
111985
|
+
error: "no blame output (file may be empty or untracked)",
|
|
111986
|
+
file: file3,
|
|
111987
|
+
lineCount: 0,
|
|
111988
|
+
lines: []
|
|
111989
|
+
});
|
|
111990
|
+
}
|
|
111991
|
+
const rawEntries = parsePorcelainBlame(stdout, MAX_OUTPUT_LINES2);
|
|
111992
|
+
const lines = rawEntries.map((entry) => ({
|
|
111993
|
+
line: entry.line,
|
|
111994
|
+
sha: entry.sha,
|
|
111995
|
+
author: entry.author,
|
|
111996
|
+
date: Number.parseInt(entry.authorTime, 10) > 0 ? new Date(Number.parseInt(entry.authorTime, 10) * 1000).toISOString().slice(0, 10) : entry.authorTime,
|
|
111997
|
+
summary: entry.summary,
|
|
111998
|
+
content: entry.content
|
|
111999
|
+
}));
|
|
112000
|
+
const resultJson = {
|
|
112001
|
+
file: file3,
|
|
112002
|
+
lineCount: lines.length,
|
|
112003
|
+
lines
|
|
112004
|
+
};
|
|
112005
|
+
return JSON.stringify(resultJson, null, 2);
|
|
112006
|
+
}
|
|
112007
|
+
});
|
|
112008
|
+
|
|
111401
112009
|
// src/tools/gitingest.ts
|
|
111402
112010
|
init_zod();
|
|
111403
112011
|
init_create_tool();
|
|
111404
112012
|
var GITINGEST_TIMEOUT_MS = 1e4;
|
|
111405
112013
|
var GITINGEST_MAX_RESPONSE_BYTES = 5242880;
|
|
111406
112014
|
var GITINGEST_MAX_RETRIES = 2;
|
|
111407
|
-
var delay = (ms) => new Promise((
|
|
112015
|
+
var delay = (ms) => new Promise((resolve44) => setTimeout(resolve44, ms));
|
|
111408
112016
|
async function fetchGitingest(args2) {
|
|
111409
112017
|
for (let attempt = 0;attempt <= GITINGEST_MAX_RETRIES; attempt++) {
|
|
111410
112018
|
try {
|
|
@@ -111492,8 +112100,8 @@ var gitingest = createSwarmTool({
|
|
|
111492
112100
|
init_zod();
|
|
111493
112101
|
init_create_tool();
|
|
111494
112102
|
init_path_security();
|
|
111495
|
-
import * as
|
|
111496
|
-
import * as
|
|
112103
|
+
import * as fs84 from "node:fs";
|
|
112104
|
+
import * as path122 from "node:path";
|
|
111497
112105
|
var MAX_FILE_PATH_LENGTH2 = 500;
|
|
111498
112106
|
var MAX_SYMBOL_LENGTH = 256;
|
|
111499
112107
|
var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
|
|
@@ -111540,8 +112148,8 @@ function validateSymbolInput(symbol3) {
|
|
|
111540
112148
|
}
|
|
111541
112149
|
return null;
|
|
111542
112150
|
}
|
|
111543
|
-
function
|
|
111544
|
-
const ext =
|
|
112151
|
+
function isBinaryFile3(filePath, buffer) {
|
|
112152
|
+
const ext = path122.extname(filePath).toLowerCase();
|
|
111545
112153
|
if (ext === ".json" || ext === ".md" || ext === ".txt") {
|
|
111546
112154
|
return false;
|
|
111547
112155
|
}
|
|
@@ -111565,15 +112173,15 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
111565
112173
|
const imports = [];
|
|
111566
112174
|
let _resolvedTarget;
|
|
111567
112175
|
try {
|
|
111568
|
-
_resolvedTarget =
|
|
112176
|
+
_resolvedTarget = path122.resolve(targetFile);
|
|
111569
112177
|
} catch {
|
|
111570
112178
|
_resolvedTarget = targetFile;
|
|
111571
112179
|
}
|
|
111572
|
-
const targetBasename =
|
|
112180
|
+
const targetBasename = path122.basename(targetFile, path122.extname(targetFile));
|
|
111573
112181
|
const targetWithExt = targetFile;
|
|
111574
112182
|
const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
111575
|
-
const normalizedTargetWithExt =
|
|
111576
|
-
const normalizedTargetWithoutExt =
|
|
112183
|
+
const normalizedTargetWithExt = path122.normalize(targetWithExt).replace(/\\/g, "/");
|
|
112184
|
+
const normalizedTargetWithoutExt = path122.normalize(targetWithoutExt).replace(/\\/g, "/");
|
|
111577
112185
|
const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
|
|
111578
112186
|
for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
|
|
111579
112187
|
const modulePath = match[1] || match[2] || match[3];
|
|
@@ -111596,9 +112204,9 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
111596
112204
|
}
|
|
111597
112205
|
const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
|
|
111598
112206
|
let isMatch = false;
|
|
111599
|
-
const _targetDir =
|
|
111600
|
-
const targetExt =
|
|
111601
|
-
const targetBasenameNoExt =
|
|
112207
|
+
const _targetDir = path122.dirname(targetFile);
|
|
112208
|
+
const targetExt = path122.extname(targetFile);
|
|
112209
|
+
const targetBasenameNoExt = path122.basename(targetFile, targetExt);
|
|
111602
112210
|
const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
111603
112211
|
const moduleName = modulePath.split(/[/\\]/).pop() || "";
|
|
111604
112212
|
const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
@@ -111638,7 +112246,7 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
111638
112246
|
}
|
|
111639
112247
|
return imports;
|
|
111640
112248
|
}
|
|
111641
|
-
var
|
|
112249
|
+
var SKIP_DIRECTORIES5 = new Set([
|
|
111642
112250
|
"node_modules",
|
|
111643
112251
|
".git",
|
|
111644
112252
|
"dist",
|
|
@@ -111652,10 +112260,10 @@ var SKIP_DIRECTORIES4 = new Set([
|
|
|
111652
112260
|
".svn",
|
|
111653
112261
|
".hg"
|
|
111654
112262
|
]);
|
|
111655
|
-
function
|
|
112263
|
+
function findSourceFiles3(dir, files = [], stats = { skippedDirs: [], skippedFiles: 0, fileErrors: [] }) {
|
|
111656
112264
|
let entries;
|
|
111657
112265
|
try {
|
|
111658
|
-
entries =
|
|
112266
|
+
entries = fs84.readdirSync(dir);
|
|
111659
112267
|
} catch (e) {
|
|
111660
112268
|
stats.fileErrors.push({
|
|
111661
112269
|
path: dir,
|
|
@@ -111665,14 +112273,14 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
111665
112273
|
}
|
|
111666
112274
|
entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
|
111667
112275
|
for (const entry of entries) {
|
|
111668
|
-
if (
|
|
111669
|
-
stats.skippedDirs.push(
|
|
112276
|
+
if (SKIP_DIRECTORIES5.has(entry)) {
|
|
112277
|
+
stats.skippedDirs.push(path122.join(dir, entry));
|
|
111670
112278
|
continue;
|
|
111671
112279
|
}
|
|
111672
|
-
const fullPath =
|
|
112280
|
+
const fullPath = path122.join(dir, entry);
|
|
111673
112281
|
let stat9;
|
|
111674
112282
|
try {
|
|
111675
|
-
stat9 =
|
|
112283
|
+
stat9 = fs84.statSync(fullPath);
|
|
111676
112284
|
} catch (e) {
|
|
111677
112285
|
stats.fileErrors.push({
|
|
111678
112286
|
path: fullPath,
|
|
@@ -111681,9 +112289,9 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
111681
112289
|
continue;
|
|
111682
112290
|
}
|
|
111683
112291
|
if (stat9.isDirectory()) {
|
|
111684
|
-
|
|
112292
|
+
findSourceFiles3(fullPath, files, stats);
|
|
111685
112293
|
} else if (stat9.isFile()) {
|
|
111686
|
-
const ext =
|
|
112294
|
+
const ext = path122.extname(fullPath).toLowerCase();
|
|
111687
112295
|
if (SUPPORTED_EXTENSIONS3.includes(ext)) {
|
|
111688
112296
|
files.push(fullPath);
|
|
111689
112297
|
}
|
|
@@ -111740,8 +112348,8 @@ var imports = createSwarmTool({
|
|
|
111740
112348
|
return JSON.stringify(errorResult, null, 2);
|
|
111741
112349
|
}
|
|
111742
112350
|
try {
|
|
111743
|
-
const targetFile =
|
|
111744
|
-
if (!
|
|
112351
|
+
const targetFile = path122.resolve(file3);
|
|
112352
|
+
if (!fs84.existsSync(targetFile)) {
|
|
111745
112353
|
const errorResult = {
|
|
111746
112354
|
error: `target file not found: ${file3}`,
|
|
111747
112355
|
target: file3,
|
|
@@ -111751,7 +112359,7 @@ var imports = createSwarmTool({
|
|
|
111751
112359
|
};
|
|
111752
112360
|
return JSON.stringify(errorResult, null, 2);
|
|
111753
112361
|
}
|
|
111754
|
-
const targetStat =
|
|
112362
|
+
const targetStat = fs84.statSync(targetFile);
|
|
111755
112363
|
if (!targetStat.isFile()) {
|
|
111756
112364
|
const errorResult = {
|
|
111757
112365
|
error: "target must be a file, not a directory",
|
|
@@ -111762,13 +112370,13 @@ var imports = createSwarmTool({
|
|
|
111762
112370
|
};
|
|
111763
112371
|
return JSON.stringify(errorResult, null, 2);
|
|
111764
112372
|
}
|
|
111765
|
-
const baseDir =
|
|
112373
|
+
const baseDir = path122.dirname(targetFile);
|
|
111766
112374
|
const scanStats = {
|
|
111767
112375
|
skippedDirs: [],
|
|
111768
112376
|
skippedFiles: 0,
|
|
111769
112377
|
fileErrors: []
|
|
111770
112378
|
};
|
|
111771
|
-
const sourceFiles =
|
|
112379
|
+
const sourceFiles = findSourceFiles3(baseDir, [], scanStats);
|
|
111772
112380
|
const filesToScan = sourceFiles.filter((f) => f !== targetFile).sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())).slice(0, MAX_CONSUMERS * 10);
|
|
111773
112381
|
const consumers = [];
|
|
111774
112382
|
let skippedFileCount = 0;
|
|
@@ -111777,13 +112385,13 @@ var imports = createSwarmTool({
|
|
|
111777
112385
|
if (consumers.length >= MAX_CONSUMERS)
|
|
111778
112386
|
break;
|
|
111779
112387
|
try {
|
|
111780
|
-
const stat9 =
|
|
112388
|
+
const stat9 = fs84.statSync(filePath);
|
|
111781
112389
|
if (stat9.size > MAX_FILE_SIZE_BYTES7) {
|
|
111782
112390
|
skippedFileCount++;
|
|
111783
112391
|
continue;
|
|
111784
112392
|
}
|
|
111785
|
-
const buffer =
|
|
111786
|
-
if (
|
|
112393
|
+
const buffer = fs84.readFileSync(filePath);
|
|
112394
|
+
if (isBinaryFile3(filePath, buffer)) {
|
|
111787
112395
|
skippedFileCount++;
|
|
111788
112396
|
continue;
|
|
111789
112397
|
}
|
|
@@ -112150,7 +112758,7 @@ init_zod();
|
|
|
112150
112758
|
init_config();
|
|
112151
112759
|
init_knowledge_store();
|
|
112152
112760
|
init_create_tool();
|
|
112153
|
-
import { existsSync as
|
|
112761
|
+
import { existsSync as existsSync70 } from "node:fs";
|
|
112154
112762
|
var DEFAULT_LIMIT = 10;
|
|
112155
112763
|
var MAX_LESSON_LENGTH = 200;
|
|
112156
112764
|
var VALID_CATEGORIES3 = [
|
|
@@ -112226,14 +112834,14 @@ function validateLimit(limit) {
|
|
|
112226
112834
|
}
|
|
112227
112835
|
async function readSwarmKnowledge(directory) {
|
|
112228
112836
|
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
112229
|
-
if (!
|
|
112837
|
+
if (!existsSync70(swarmPath)) {
|
|
112230
112838
|
return [];
|
|
112231
112839
|
}
|
|
112232
112840
|
return readKnowledge(swarmPath);
|
|
112233
112841
|
}
|
|
112234
112842
|
async function readHiveKnowledge() {
|
|
112235
112843
|
const hivePath = resolveHiveKnowledgePath();
|
|
112236
|
-
if (!
|
|
112844
|
+
if (!existsSync70(hivePath)) {
|
|
112237
112845
|
return [];
|
|
112238
112846
|
}
|
|
112239
112847
|
return readKnowledge(hivePath);
|
|
@@ -112658,12 +113266,12 @@ var lean_turbo_acquire_locks = createSwarmTool({
|
|
|
112658
113266
|
// src/tools/lean-turbo-plan-lanes.ts
|
|
112659
113267
|
init_zod();
|
|
112660
113268
|
init_constants();
|
|
112661
|
-
import * as
|
|
112662
|
-
import * as
|
|
113269
|
+
import * as fs86 from "node:fs";
|
|
113270
|
+
import * as path124 from "node:path";
|
|
112663
113271
|
|
|
112664
113272
|
// src/turbo/lean/conflicts.ts
|
|
112665
|
-
import * as
|
|
112666
|
-
import * as
|
|
113273
|
+
import * as fs85 from "node:fs";
|
|
113274
|
+
import * as path123 from "node:path";
|
|
112667
113275
|
var DEFAULT_GLOBAL_FILES = [
|
|
112668
113276
|
"package.json",
|
|
112669
113277
|
"package-lock.json",
|
|
@@ -112790,12 +113398,12 @@ function isProtectedPath3(normalizedPath) {
|
|
|
112790
113398
|
return false;
|
|
112791
113399
|
}
|
|
112792
113400
|
function readTaskScopes(directory, taskId) {
|
|
112793
|
-
const scopePath =
|
|
113401
|
+
const scopePath = path123.join(directory, ".swarm", "scopes", `scope-${taskId}.json`);
|
|
112794
113402
|
try {
|
|
112795
|
-
if (!
|
|
113403
|
+
if (!fs85.existsSync(scopePath)) {
|
|
112796
113404
|
return null;
|
|
112797
113405
|
}
|
|
112798
|
-
const raw =
|
|
113406
|
+
const raw = fs85.readFileSync(scopePath, "utf-8");
|
|
112799
113407
|
const parsed = JSON.parse(raw);
|
|
112800
113408
|
if (!parsed || !Array.isArray(parsed.files)) {
|
|
112801
113409
|
return null;
|
|
@@ -113178,12 +113786,12 @@ function createEmptyPlan(phaseNumber, planId) {
|
|
|
113178
113786
|
// src/tools/lean-turbo-plan-lanes.ts
|
|
113179
113787
|
init_create_tool();
|
|
113180
113788
|
function readPlanJson(directory) {
|
|
113181
|
-
const planPath =
|
|
113182
|
-
if (!
|
|
113789
|
+
const planPath = path124.join(directory, ".swarm", "plan.json");
|
|
113790
|
+
if (!fs86.existsSync(planPath)) {
|
|
113183
113791
|
return null;
|
|
113184
113792
|
}
|
|
113185
113793
|
try {
|
|
113186
|
-
return JSON.parse(
|
|
113794
|
+
return JSON.parse(fs86.readFileSync(planPath, "utf-8"));
|
|
113187
113795
|
} catch {
|
|
113188
113796
|
return null;
|
|
113189
113797
|
}
|
|
@@ -113233,16 +113841,16 @@ init_config();
|
|
|
113233
113841
|
|
|
113234
113842
|
// src/turbo/lean/reviewer.ts
|
|
113235
113843
|
init_state();
|
|
113236
|
-
import * as
|
|
113237
|
-
import * as
|
|
113844
|
+
import * as fs88 from "node:fs/promises";
|
|
113845
|
+
import * as path126 from "node:path";
|
|
113238
113846
|
|
|
113239
113847
|
// src/turbo/lean/evidence.ts
|
|
113240
113848
|
init_bun_compat();
|
|
113241
113849
|
import { rmSync as rmSync6 } from "node:fs";
|
|
113242
|
-
import * as
|
|
113243
|
-
import * as
|
|
113850
|
+
import * as fs87 from "node:fs/promises";
|
|
113851
|
+
import * as path125 from "node:path";
|
|
113244
113852
|
function leanTurboEvidenceDir(directory, phase) {
|
|
113245
|
-
return
|
|
113853
|
+
return path125.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
|
|
113246
113854
|
}
|
|
113247
113855
|
function validateLaneId(laneId) {
|
|
113248
113856
|
if (laneId.length === 0) {
|
|
@@ -113264,21 +113872,21 @@ function validateLaneId(laneId) {
|
|
|
113264
113872
|
function laneEvidencePath(directory, phase, laneId) {
|
|
113265
113873
|
validateLaneId(laneId);
|
|
113266
113874
|
const expectedDir = leanTurboEvidenceDir(directory, phase);
|
|
113267
|
-
const resolvedPath =
|
|
113268
|
-
const resolvedDir =
|
|
113269
|
-
if (!resolvedPath.startsWith(resolvedDir +
|
|
113875
|
+
const resolvedPath = path125.resolve(path125.join(expectedDir, `${laneId}.json`));
|
|
113876
|
+
const resolvedDir = path125.resolve(expectedDir);
|
|
113877
|
+
if (!resolvedPath.startsWith(resolvedDir + path125.sep) && resolvedPath !== resolvedDir) {
|
|
113270
113878
|
throw new Error(`Invalid laneId: path traversal detected (got "${laneId}")`);
|
|
113271
113879
|
}
|
|
113272
113880
|
return resolvedPath;
|
|
113273
113881
|
}
|
|
113274
113882
|
async function atomicWriteJson(filePath, data) {
|
|
113275
113883
|
const content = JSON.stringify(data, null, 2);
|
|
113276
|
-
const dir =
|
|
113277
|
-
await
|
|
113884
|
+
const dir = path125.dirname(filePath);
|
|
113885
|
+
await fs87.mkdir(dir, { recursive: true });
|
|
113278
113886
|
const tempPath = `${filePath}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
113279
113887
|
try {
|
|
113280
113888
|
await bunWrite(tempPath, content);
|
|
113281
|
-
await
|
|
113889
|
+
await fs87.rename(tempPath, filePath);
|
|
113282
113890
|
} catch (error93) {
|
|
113283
113891
|
try {
|
|
113284
113892
|
rmSync6(tempPath, { force: true });
|
|
@@ -113287,7 +113895,7 @@ async function atomicWriteJson(filePath, data) {
|
|
|
113287
113895
|
}
|
|
113288
113896
|
}
|
|
113289
113897
|
function phaseEvidencePath(directory, phase) {
|
|
113290
|
-
return
|
|
113898
|
+
return path125.join(leanTurboEvidenceDir(directory, phase), "lean-turbo-phase.json");
|
|
113291
113899
|
}
|
|
113292
113900
|
async function writeLaneEvidence(directory, phase, evidence) {
|
|
113293
113901
|
const targetPath = laneEvidencePath(directory, phase, evidence.laneId);
|
|
@@ -113297,7 +113905,7 @@ async function readPhaseEvidence(directory, phase) {
|
|
|
113297
113905
|
const targetPath = phaseEvidencePath(directory, phase);
|
|
113298
113906
|
let content;
|
|
113299
113907
|
try {
|
|
113300
|
-
content = await
|
|
113908
|
+
content = await fs87.readFile(targetPath, "utf-8");
|
|
113301
113909
|
} catch (error93) {
|
|
113302
113910
|
const code = error93.code;
|
|
113303
113911
|
if (code === "ENOENT" || code === "ENOTDIR") {
|
|
@@ -113315,7 +113923,7 @@ async function listLaneEvidence(directory, phase) {
|
|
|
113315
113923
|
const evidenceDir = leanTurboEvidenceDir(directory, phase);
|
|
113316
113924
|
let entries;
|
|
113317
113925
|
try {
|
|
113318
|
-
entries = await
|
|
113926
|
+
entries = await fs87.readdir(evidenceDir);
|
|
113319
113927
|
} catch (error93) {
|
|
113320
113928
|
const code = error93.code;
|
|
113321
113929
|
if (code === "ENOENT" || code === "ENOTDIR") {
|
|
@@ -113331,10 +113939,10 @@ async function listLaneEvidence(directory, phase) {
|
|
|
113331
113939
|
if (entry === "lean-turbo-phase.json") {
|
|
113332
113940
|
continue;
|
|
113333
113941
|
}
|
|
113334
|
-
const filePath =
|
|
113942
|
+
const filePath = path125.join(evidenceDir, entry);
|
|
113335
113943
|
let content;
|
|
113336
113944
|
try {
|
|
113337
|
-
content = await
|
|
113945
|
+
content = await fs87.readFile(filePath, "utf-8");
|
|
113338
113946
|
} catch {
|
|
113339
113947
|
continue;
|
|
113340
113948
|
}
|
|
@@ -113462,9 +114070,9 @@ function parseReviewerVerdict(responseText) {
|
|
|
113462
114070
|
return { verdict, reason };
|
|
113463
114071
|
}
|
|
113464
114072
|
async function writeReviewerEvidence(directory, phase, verdict, reason) {
|
|
113465
|
-
const evidenceDir =
|
|
113466
|
-
await
|
|
113467
|
-
const evidencePath =
|
|
114073
|
+
const evidenceDir = path126.join(directory, ".swarm", "evidence", String(phase));
|
|
114074
|
+
await fs88.mkdir(evidenceDir, { recursive: true });
|
|
114075
|
+
const evidencePath = path126.join(evidenceDir, "lean-turbo-reviewer.json");
|
|
113468
114076
|
const content = JSON.stringify({
|
|
113469
114077
|
phase,
|
|
113470
114078
|
verdict,
|
|
@@ -113473,11 +114081,11 @@ async function writeReviewerEvidence(directory, phase, verdict, reason) {
|
|
|
113473
114081
|
}, null, 2);
|
|
113474
114082
|
const tempPath = `${evidencePath}.tmp.${process.pid}.${Date.now()}`;
|
|
113475
114083
|
try {
|
|
113476
|
-
await
|
|
113477
|
-
await
|
|
114084
|
+
await fs88.writeFile(tempPath, content, "utf-8");
|
|
114085
|
+
await fs88.rename(tempPath, evidencePath);
|
|
113478
114086
|
} catch (error93) {
|
|
113479
114087
|
try {
|
|
113480
|
-
await
|
|
114088
|
+
await fs88.unlink(tempPath);
|
|
113481
114089
|
} catch {}
|
|
113482
114090
|
throw error93;
|
|
113483
114091
|
}
|
|
@@ -114275,8 +114883,8 @@ init_lint();
|
|
|
114275
114883
|
// src/tools/lint-spec.ts
|
|
114276
114884
|
init_spec_schema();
|
|
114277
114885
|
init_create_tool();
|
|
114278
|
-
import * as
|
|
114279
|
-
import * as
|
|
114886
|
+
import * as fs89 from "node:fs";
|
|
114887
|
+
import * as path127 from "node:path";
|
|
114280
114888
|
var SPEC_FILE_NAME = "spec.md";
|
|
114281
114889
|
var SWARM_DIR2 = ".swarm";
|
|
114282
114890
|
var OBLIGATION_KEYWORDS = ["MUST", "SHALL", "SHOULD", "MAY"];
|
|
@@ -114329,8 +114937,8 @@ var lint_spec = createSwarmTool({
|
|
|
114329
114937
|
async execute(_args, directory) {
|
|
114330
114938
|
const errors5 = [];
|
|
114331
114939
|
const warnings = [];
|
|
114332
|
-
const specPath =
|
|
114333
|
-
if (!
|
|
114940
|
+
const specPath = path127.join(directory, SWARM_DIR2, SPEC_FILE_NAME);
|
|
114941
|
+
if (!fs89.existsSync(specPath)) {
|
|
114334
114942
|
const result2 = {
|
|
114335
114943
|
valid: false,
|
|
114336
114944
|
specMtime: null,
|
|
@@ -114349,12 +114957,12 @@ var lint_spec = createSwarmTool({
|
|
|
114349
114957
|
}
|
|
114350
114958
|
let specMtime = null;
|
|
114351
114959
|
try {
|
|
114352
|
-
const stats =
|
|
114960
|
+
const stats = fs89.statSync(specPath);
|
|
114353
114961
|
specMtime = stats.mtime.toISOString();
|
|
114354
114962
|
} catch {}
|
|
114355
114963
|
let content;
|
|
114356
114964
|
try {
|
|
114357
|
-
content =
|
|
114965
|
+
content = fs89.readFileSync(specPath, "utf-8");
|
|
114358
114966
|
} catch (e) {
|
|
114359
114967
|
const result2 = {
|
|
114360
114968
|
valid: false,
|
|
@@ -114400,13 +115008,13 @@ var lint_spec = createSwarmTool({
|
|
|
114400
115008
|
|
|
114401
115009
|
// src/tools/mutation-test.ts
|
|
114402
115010
|
init_zod();
|
|
114403
|
-
import * as
|
|
114404
|
-
import * as
|
|
115011
|
+
import * as fs90 from "node:fs";
|
|
115012
|
+
import * as path129 from "node:path";
|
|
114405
115013
|
|
|
114406
115014
|
// src/mutation/engine.ts
|
|
114407
|
-
import { spawnSync as
|
|
115015
|
+
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
114408
115016
|
import { unlinkSync as unlinkSync18, writeFileSync as writeFileSync24 } from "node:fs";
|
|
114409
|
-
import * as
|
|
115017
|
+
import * as path128 from "node:path";
|
|
114410
115018
|
|
|
114411
115019
|
// src/mutation/equivalence.ts
|
|
114412
115020
|
function isStaticallyEquivalent(originalCode, mutatedCode) {
|
|
@@ -114541,7 +115149,7 @@ var _internals57 = {
|
|
|
114541
115149
|
executeMutation,
|
|
114542
115150
|
computeReport,
|
|
114543
115151
|
executeMutationSuite,
|
|
114544
|
-
spawnSync:
|
|
115152
|
+
spawnSync: spawnSync9
|
|
114545
115153
|
};
|
|
114546
115154
|
async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
114547
115155
|
const startTime = Date.now();
|
|
@@ -114552,7 +115160,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
|
114552
115160
|
let patchFile;
|
|
114553
115161
|
try {
|
|
114554
115162
|
const safeId2 = patch.id.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
114555
|
-
patchFile =
|
|
115163
|
+
patchFile = path128.join(workingDir, `.mutation_patch_${safeId2}.diff`);
|
|
114556
115164
|
try {
|
|
114557
115165
|
writeFileSync24(patchFile, patch.patch);
|
|
114558
115166
|
} catch (writeErr) {
|
|
@@ -114956,8 +115564,8 @@ var mutation_test = createSwarmTool({
|
|
|
114956
115564
|
];
|
|
114957
115565
|
for (const filePath of uniquePaths) {
|
|
114958
115566
|
try {
|
|
114959
|
-
const resolvedPath =
|
|
114960
|
-
sourceFiles.set(filePath,
|
|
115567
|
+
const resolvedPath = path129.resolve(cwd, filePath);
|
|
115568
|
+
sourceFiles.set(filePath, fs90.readFileSync(resolvedPath, "utf-8"));
|
|
114961
115569
|
} catch {}
|
|
114962
115570
|
}
|
|
114963
115571
|
const report = await executeMutationSuite(typedArgs.patches, typedArgs.test_command, typedArgs.files, cwd, undefined, undefined, sourceFiles.size > 0 ? sourceFiles : undefined);
|
|
@@ -114977,30 +115585,30 @@ init_zod();
|
|
|
114977
115585
|
init_config();
|
|
114978
115586
|
init_schema();
|
|
114979
115587
|
init_manager2();
|
|
114980
|
-
import * as
|
|
114981
|
-
import * as
|
|
115588
|
+
import * as fs100 from "node:fs";
|
|
115589
|
+
import * as path139 from "node:path";
|
|
114982
115590
|
|
|
114983
115591
|
// src/full-auto/phase-approval.ts
|
|
114984
115592
|
init_utils2();
|
|
114985
115593
|
init_logger();
|
|
114986
115594
|
init_state2();
|
|
114987
|
-
import * as
|
|
114988
|
-
import * as
|
|
115595
|
+
import * as fs91 from "node:fs";
|
|
115596
|
+
import * as path130 from "node:path";
|
|
114989
115597
|
var APPROVAL_TTL_MS = 24 * 60 * 60 * 1000;
|
|
114990
115598
|
function readEvidenceDir(directory, phase) {
|
|
114991
115599
|
try {
|
|
114992
|
-
const dirPath = validateSwarmPath(directory,
|
|
114993
|
-
if (!
|
|
115600
|
+
const dirPath = validateSwarmPath(directory, path130.posix.join("evidence", String(phase)));
|
|
115601
|
+
if (!fs91.existsSync(dirPath))
|
|
114994
115602
|
return [];
|
|
114995
|
-
const entries =
|
|
114996
|
-
return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) =>
|
|
115603
|
+
const entries = fs91.readdirSync(dirPath);
|
|
115604
|
+
return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) => path130.join(dirPath, e));
|
|
114997
115605
|
} catch {
|
|
114998
115606
|
return [];
|
|
114999
115607
|
}
|
|
115000
115608
|
}
|
|
115001
115609
|
function parseEvidence(filePath) {
|
|
115002
115610
|
try {
|
|
115003
|
-
const raw =
|
|
115611
|
+
const raw = fs91.readFileSync(filePath, "utf-8");
|
|
115004
115612
|
const parsed = JSON.parse(raw);
|
|
115005
115613
|
return parsed;
|
|
115006
115614
|
} catch (error93) {
|
|
@@ -115089,9 +115697,9 @@ function verifyFullAutoPhaseApproval(directory, sessionID, phase, config3) {
|
|
|
115089
115697
|
function phaseIsExplicitlyNonCode(directory, phase) {
|
|
115090
115698
|
try {
|
|
115091
115699
|
const planPath = validateSwarmPath(directory, "plan.json");
|
|
115092
|
-
if (!
|
|
115700
|
+
if (!fs91.existsSync(planPath))
|
|
115093
115701
|
return false;
|
|
115094
|
-
const raw =
|
|
115702
|
+
const raw = fs91.readFileSync(planPath, "utf-8");
|
|
115095
115703
|
const plan = JSON.parse(raw);
|
|
115096
115704
|
const phases = Array.isArray(plan.phases) ? plan.phases : [];
|
|
115097
115705
|
const entry = phases.find((p) => p.id === phase || p.phase === phase);
|
|
@@ -115133,20 +115741,20 @@ init_file_locks();
|
|
|
115133
115741
|
init_plan_schema();
|
|
115134
115742
|
init_ledger();
|
|
115135
115743
|
init_manager();
|
|
115136
|
-
import * as
|
|
115137
|
-
import * as
|
|
115744
|
+
import * as fs92 from "node:fs";
|
|
115745
|
+
import * as path131 from "node:path";
|
|
115138
115746
|
async function writeCheckpoint(directory) {
|
|
115139
115747
|
try {
|
|
115140
115748
|
const plan = await loadPlan(directory);
|
|
115141
115749
|
if (!plan)
|
|
115142
115750
|
return;
|
|
115143
|
-
const swarmDir =
|
|
115144
|
-
|
|
115145
|
-
const jsonPath =
|
|
115146
|
-
const mdPath =
|
|
115147
|
-
|
|
115751
|
+
const swarmDir = path131.join(directory, ".swarm");
|
|
115752
|
+
fs92.mkdirSync(swarmDir, { recursive: true });
|
|
115753
|
+
const jsonPath = path131.join(swarmDir, "SWARM_PLAN.json");
|
|
115754
|
+
const mdPath = path131.join(swarmDir, "SWARM_PLAN.md");
|
|
115755
|
+
fs92.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
|
|
115148
115756
|
const md = derivePlanMarkdown(plan);
|
|
115149
|
-
|
|
115757
|
+
fs92.writeFileSync(mdPath, md, "utf8");
|
|
115150
115758
|
} catch (error93) {
|
|
115151
115759
|
console.warn(`[checkpoint] Failed to write SWARM_PLAN checkpoint: ${error93 instanceof Error ? error93.message : String(error93)}`);
|
|
115152
115760
|
}
|
|
@@ -115161,8 +115769,8 @@ init_telemetry();
|
|
|
115161
115769
|
|
|
115162
115770
|
// src/turbo/lean/phase-ready.ts
|
|
115163
115771
|
init_file_locks();
|
|
115164
|
-
import * as
|
|
115165
|
-
import * as
|
|
115772
|
+
import * as fs93 from "node:fs";
|
|
115773
|
+
import * as path132 from "node:path";
|
|
115166
115774
|
init_state3();
|
|
115167
115775
|
var DEFAULT_CONFIG3 = {
|
|
115168
115776
|
phase_reviewer: true,
|
|
@@ -115171,10 +115779,10 @@ var DEFAULT_CONFIG3 = {
|
|
|
115171
115779
|
};
|
|
115172
115780
|
function defaultReadPlanJson(dir) {
|
|
115173
115781
|
try {
|
|
115174
|
-
const planPath =
|
|
115175
|
-
if (!
|
|
115782
|
+
const planPath = path132.join(dir, ".swarm", "plan.json");
|
|
115783
|
+
if (!fs93.existsSync(planPath))
|
|
115176
115784
|
return null;
|
|
115177
|
-
const raw =
|
|
115785
|
+
const raw = fs93.readFileSync(planPath, "utf-8");
|
|
115178
115786
|
const plan = JSON.parse(raw);
|
|
115179
115787
|
if (typeof plan !== "object" || plan === null || !Array.isArray(plan.phases)) {
|
|
115180
115788
|
return null;
|
|
@@ -115186,11 +115794,11 @@ function defaultReadPlanJson(dir) {
|
|
|
115186
115794
|
}
|
|
115187
115795
|
function readReviewerEvidenceFromFile(directory, phase) {
|
|
115188
115796
|
try {
|
|
115189
|
-
const evidencePath =
|
|
115190
|
-
if (!
|
|
115797
|
+
const evidencePath = path132.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-reviewer.json");
|
|
115798
|
+
if (!fs93.existsSync(evidencePath)) {
|
|
115191
115799
|
return null;
|
|
115192
115800
|
}
|
|
115193
|
-
const raw =
|
|
115801
|
+
const raw = fs93.readFileSync(evidencePath, "utf-8");
|
|
115194
115802
|
const parsed = JSON.parse(raw);
|
|
115195
115803
|
if (typeof parsed !== "object" || parsed === null || typeof parsed.verdict !== "string") {
|
|
115196
115804
|
return null;
|
|
@@ -115206,11 +115814,11 @@ function readReviewerEvidenceFromFile(directory, phase) {
|
|
|
115206
115814
|
}
|
|
115207
115815
|
function readCriticEvidenceFromFile(directory, phase) {
|
|
115208
115816
|
try {
|
|
115209
|
-
const evidencePath =
|
|
115210
|
-
if (!
|
|
115817
|
+
const evidencePath = path132.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-critic.json");
|
|
115818
|
+
if (!fs93.existsSync(evidencePath)) {
|
|
115211
115819
|
return null;
|
|
115212
115820
|
}
|
|
115213
|
-
const raw =
|
|
115821
|
+
const raw = fs93.readFileSync(evidencePath, "utf-8");
|
|
115214
115822
|
const parsed = JSON.parse(raw);
|
|
115215
115823
|
if (typeof parsed !== "object" || parsed === null || typeof parsed.verdict !== "string") {
|
|
115216
115824
|
return null;
|
|
@@ -115225,10 +115833,10 @@ function readCriticEvidenceFromFile(directory, phase) {
|
|
|
115225
115833
|
}
|
|
115226
115834
|
}
|
|
115227
115835
|
function listLaneEvidenceSync(directory, phase) {
|
|
115228
|
-
const evidenceDir =
|
|
115836
|
+
const evidenceDir = path132.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
|
|
115229
115837
|
let entries;
|
|
115230
115838
|
try {
|
|
115231
|
-
entries =
|
|
115839
|
+
entries = fs93.readdirSync(evidenceDir);
|
|
115232
115840
|
} catch {
|
|
115233
115841
|
return [];
|
|
115234
115842
|
}
|
|
@@ -115295,8 +115903,8 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
115295
115903
|
...DEFAULT_CONFIG3,
|
|
115296
115904
|
...actualConfig
|
|
115297
115905
|
};
|
|
115298
|
-
const statePath =
|
|
115299
|
-
if (!
|
|
115906
|
+
const statePath = path132.join(directory, ".swarm", "turbo-state.json");
|
|
115907
|
+
if (!fs93.existsSync(statePath)) {
|
|
115300
115908
|
return {
|
|
115301
115909
|
ok: false,
|
|
115302
115910
|
reason: "Lean Turbo state unreadable or missing"
|
|
@@ -115483,10 +116091,10 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
115483
116091
|
}
|
|
115484
116092
|
}
|
|
115485
116093
|
if (mergedConfig.integrated_diff_required) {
|
|
115486
|
-
const evidencePath =
|
|
116094
|
+
const evidencePath = path132.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-phase.json");
|
|
115487
116095
|
let hasDiff = false;
|
|
115488
116096
|
try {
|
|
115489
|
-
const content =
|
|
116097
|
+
const content = fs93.readFileSync(evidencePath, "utf-8");
|
|
115490
116098
|
const evidence = JSON.parse(content);
|
|
115491
116099
|
hasDiff = !!evidence.integratedDiffSummary;
|
|
115492
116100
|
} catch {}
|
|
@@ -115634,15 +116242,15 @@ async function runCompletionVerifyGate(ctx) {
|
|
|
115634
116242
|
init_qa_gate_profile();
|
|
115635
116243
|
init_manager();
|
|
115636
116244
|
init_state();
|
|
115637
|
-
import * as
|
|
115638
|
-
import * as
|
|
116245
|
+
import * as fs94 from "node:fs";
|
|
116246
|
+
import * as path133 from "node:path";
|
|
115639
116247
|
async function runDriftGate(ctx) {
|
|
115640
116248
|
const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
|
|
115641
116249
|
let driftCheckEnabled = true;
|
|
115642
116250
|
let driftHasSpecMd = false;
|
|
115643
116251
|
try {
|
|
115644
|
-
const specMdPath =
|
|
115645
|
-
driftHasSpecMd =
|
|
116252
|
+
const specMdPath = path133.join(dir, ".swarm", "spec.md");
|
|
116253
|
+
driftHasSpecMd = fs94.existsSync(specMdPath);
|
|
115646
116254
|
const gatePlan = await loadPlan(dir);
|
|
115647
116255
|
if (gatePlan) {
|
|
115648
116256
|
const gatePlanId = derivePlanId(gatePlan);
|
|
@@ -115669,9 +116277,9 @@ async function runDriftGate(ctx) {
|
|
|
115669
116277
|
}
|
|
115670
116278
|
let phaseType;
|
|
115671
116279
|
try {
|
|
115672
|
-
const planPath =
|
|
115673
|
-
if (
|
|
115674
|
-
const planRaw =
|
|
116280
|
+
const planPath = path133.join(dir, ".swarm", "plan.json");
|
|
116281
|
+
if (fs94.existsSync(planPath)) {
|
|
116282
|
+
const planRaw = fs94.readFileSync(planPath, "utf-8");
|
|
115675
116283
|
const plan = JSON.parse(planRaw);
|
|
115676
116284
|
const targetPhase = plan.phases?.find((p) => p.id === phase);
|
|
115677
116285
|
phaseType = targetPhase?.type;
|
|
@@ -115688,11 +116296,11 @@ async function runDriftGate(ctx) {
|
|
|
115688
116296
|
};
|
|
115689
116297
|
}
|
|
115690
116298
|
try {
|
|
115691
|
-
const driftEvidencePath =
|
|
116299
|
+
const driftEvidencePath = path133.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
|
|
115692
116300
|
let driftVerdictFound = false;
|
|
115693
116301
|
let driftVerdictApproved = false;
|
|
115694
116302
|
try {
|
|
115695
|
-
const driftEvidenceContent =
|
|
116303
|
+
const driftEvidenceContent = fs94.readFileSync(driftEvidencePath, "utf-8");
|
|
115696
116304
|
const driftEvidence = JSON.parse(driftEvidenceContent);
|
|
115697
116305
|
const entries = driftEvidence.entries ?? [];
|
|
115698
116306
|
for (const entry of entries) {
|
|
@@ -115724,9 +116332,9 @@ async function runDriftGate(ctx) {
|
|
|
115724
116332
|
let incompleteTaskCount = 0;
|
|
115725
116333
|
let planParseable = false;
|
|
115726
116334
|
try {
|
|
115727
|
-
const planPath =
|
|
115728
|
-
if (
|
|
115729
|
-
const planRaw =
|
|
116335
|
+
const planPath = path133.join(dir, ".swarm", "plan.json");
|
|
116336
|
+
if (fs94.existsSync(planPath)) {
|
|
116337
|
+
const planRaw = fs94.readFileSync(planPath, "utf-8");
|
|
115730
116338
|
const plan = JSON.parse(planRaw);
|
|
115731
116339
|
planParseable = true;
|
|
115732
116340
|
const planPhase = plan.phases?.find((p) => p.id === phase);
|
|
@@ -115805,8 +116413,8 @@ async function runDriftGate(ctx) {
|
|
|
115805
116413
|
init_qa_gate_profile();
|
|
115806
116414
|
init_manager();
|
|
115807
116415
|
init_state();
|
|
115808
|
-
import * as
|
|
115809
|
-
import * as
|
|
116416
|
+
import * as fs95 from "node:fs";
|
|
116417
|
+
import * as path134 from "node:path";
|
|
115810
116418
|
async function runFinalCouncilGate(ctx) {
|
|
115811
116419
|
const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
|
|
115812
116420
|
let finalCouncilEnabled = false;
|
|
@@ -115823,11 +116431,11 @@ async function runFinalCouncilGate(ctx) {
|
|
|
115823
116431
|
const effective = getEffectiveGates(profile, overrides);
|
|
115824
116432
|
if (effective.final_council === true) {
|
|
115825
116433
|
finalCouncilEnabled = true;
|
|
115826
|
-
const fcPath =
|
|
116434
|
+
const fcPath = path134.join(dir, ".swarm", "evidence", "final-council.json");
|
|
115827
116435
|
let fcVerdictFound = false;
|
|
115828
116436
|
let _fcVerdict;
|
|
115829
116437
|
try {
|
|
115830
|
-
const fcContent =
|
|
116438
|
+
const fcContent = fs95.readFileSync(fcPath, "utf-8");
|
|
115831
116439
|
const fcBundle = JSON.parse(fcContent);
|
|
115832
116440
|
for (const entry of fcBundle.entries ?? []) {
|
|
115833
116441
|
if (typeof entry.type === "string" && entry.type === "final-council" && typeof entry.verdict === "string") {
|
|
@@ -115952,8 +116560,8 @@ async function runFinalCouncilGate(ctx) {
|
|
|
115952
116560
|
init_qa_gate_profile();
|
|
115953
116561
|
init_manager();
|
|
115954
116562
|
init_state();
|
|
115955
|
-
import * as
|
|
115956
|
-
import * as
|
|
116563
|
+
import * as fs96 from "node:fs";
|
|
116564
|
+
import * as path135 from "node:path";
|
|
115957
116565
|
async function runHallucinationGate(ctx) {
|
|
115958
116566
|
const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
|
|
115959
116567
|
try {
|
|
@@ -115966,11 +116574,11 @@ async function runHallucinationGate(ctx) {
|
|
|
115966
116574
|
const overrides = session?.qaGateSessionOverrides ?? {};
|
|
115967
116575
|
const effective = getEffectiveGates(profile, overrides);
|
|
115968
116576
|
if (effective.hallucination_guard === true) {
|
|
115969
|
-
const hgPath =
|
|
116577
|
+
const hgPath = path135.join(dir, ".swarm", "evidence", String(phase), "hallucination-guard.json");
|
|
115970
116578
|
let hgVerdictFound = false;
|
|
115971
116579
|
let hgVerdictApproved = false;
|
|
115972
116580
|
try {
|
|
115973
|
-
const hgContent =
|
|
116581
|
+
const hgContent = fs96.readFileSync(hgPath, "utf-8");
|
|
115974
116582
|
const hgBundle = JSON.parse(hgContent);
|
|
115975
116583
|
for (const entry of hgBundle.entries ?? []) {
|
|
115976
116584
|
if (typeof entry.type === "string" && entry.type.includes("hallucination") && typeof entry.verdict === "string") {
|
|
@@ -116028,8 +116636,8 @@ async function runHallucinationGate(ctx) {
|
|
|
116028
116636
|
init_qa_gate_profile();
|
|
116029
116637
|
init_manager();
|
|
116030
116638
|
init_state();
|
|
116031
|
-
import * as
|
|
116032
|
-
import * as
|
|
116639
|
+
import * as fs97 from "node:fs";
|
|
116640
|
+
import * as path136 from "node:path";
|
|
116033
116641
|
async function runMutationGate(ctx) {
|
|
116034
116642
|
const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
|
|
116035
116643
|
try {
|
|
@@ -116042,11 +116650,11 @@ async function runMutationGate(ctx) {
|
|
|
116042
116650
|
const overrides = session?.qaGateSessionOverrides ?? {};
|
|
116043
116651
|
const effective = getEffectiveGates(profile, overrides);
|
|
116044
116652
|
if (effective.mutation_test === true) {
|
|
116045
|
-
const mgPath =
|
|
116653
|
+
const mgPath = path136.join(dir, ".swarm", "evidence", String(phase), "mutation-gate.json");
|
|
116046
116654
|
let mgVerdictFound = false;
|
|
116047
116655
|
let mgVerdict;
|
|
116048
116656
|
try {
|
|
116049
|
-
const mgContent =
|
|
116657
|
+
const mgContent = fs97.readFileSync(mgPath, "utf-8");
|
|
116050
116658
|
const mgBundle = JSON.parse(mgContent);
|
|
116051
116659
|
for (const entry of mgBundle.entries ?? []) {
|
|
116052
116660
|
if (typeof entry.type === "string" && entry.type === "mutation-gate" && typeof entry.verdict === "string") {
|
|
@@ -116104,8 +116712,8 @@ async function runMutationGate(ctx) {
|
|
|
116104
116712
|
init_qa_gate_profile();
|
|
116105
116713
|
init_manager();
|
|
116106
116714
|
init_state();
|
|
116107
|
-
import * as
|
|
116108
|
-
import * as
|
|
116715
|
+
import * as fs98 from "node:fs";
|
|
116716
|
+
import * as path137 from "node:path";
|
|
116109
116717
|
async function runPhaseCouncilGate(ctx) {
|
|
116110
116718
|
const { phase, dir, sessionID, pluginConfig, agentsDispatched, safeWarn } = ctx;
|
|
116111
116719
|
let councilModeEnabled = false;
|
|
@@ -116120,14 +116728,14 @@ async function runPhaseCouncilGate(ctx) {
|
|
|
116120
116728
|
const effective = getEffectiveGates(profile, overrides);
|
|
116121
116729
|
if (effective.council_mode === true) {
|
|
116122
116730
|
councilModeEnabled = true;
|
|
116123
|
-
const pcPath =
|
|
116731
|
+
const pcPath = path137.join(dir, ".swarm", "evidence", String(phase), "phase-council.json");
|
|
116124
116732
|
let pcVerdictFound = false;
|
|
116125
116733
|
let _pcVerdict;
|
|
116126
116734
|
let pcQuorumSize;
|
|
116127
116735
|
let pcTimestamp;
|
|
116128
116736
|
let pcPhaseNumber;
|
|
116129
116737
|
try {
|
|
116130
|
-
const pcContent =
|
|
116738
|
+
const pcContent = fs98.readFileSync(pcPath, "utf-8");
|
|
116131
116739
|
const pcBundle = JSON.parse(pcContent);
|
|
116132
116740
|
for (const entry of pcBundle.entries ?? []) {
|
|
116133
116741
|
if (typeof entry.type === "string" && entry.type === "phase-council" && typeof entry.verdict === "string") {
|
|
@@ -116635,7 +117243,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
116635
117243
|
}
|
|
116636
117244
|
if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
|
|
116637
117245
|
try {
|
|
116638
|
-
const projectName =
|
|
117246
|
+
const projectName = path139.basename(dir);
|
|
116639
117247
|
const curationResult = await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig);
|
|
116640
117248
|
if (curationResult) {
|
|
116641
117249
|
const sessionState = swarmState.agentSessions.get(sessionID);
|
|
@@ -116735,14 +117343,14 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
116735
117343
|
const markerPath = validateSwarmPath(dir, "skill-usage-last-processed.json");
|
|
116736
117344
|
let sinceTimestamp;
|
|
116737
117345
|
try {
|
|
116738
|
-
const markerData = JSON.parse(
|
|
117346
|
+
const markerData = JSON.parse(fs100.readFileSync(markerPath, "utf-8"));
|
|
116739
117347
|
sinceTimestamp = markerData.lastProcessedTimestamp;
|
|
116740
117348
|
} catch {}
|
|
116741
117349
|
const feedbackResult = await applySkillUsageFeedback(dir, {
|
|
116742
117350
|
sinceTimestamp
|
|
116743
117351
|
});
|
|
116744
117352
|
try {
|
|
116745
|
-
|
|
117353
|
+
fs100.writeFileSync(markerPath, JSON.stringify({ lastProcessedTimestamp: new Date().toISOString() }), "utf-8");
|
|
116746
117354
|
} catch {}
|
|
116747
117355
|
if (feedbackResult.processed > 0) {
|
|
116748
117356
|
const sessionState = swarmState.agentSessions.get(sessionID);
|
|
@@ -116762,7 +117370,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
116762
117370
|
let phaseRequiredAgents;
|
|
116763
117371
|
try {
|
|
116764
117372
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
116765
|
-
const planRaw =
|
|
117373
|
+
const planRaw = fs100.readFileSync(planPath, "utf-8");
|
|
116766
117374
|
const plan = JSON.parse(planRaw);
|
|
116767
117375
|
const phaseObj = plan.phases.find((p) => p.id === phase);
|
|
116768
117376
|
phaseRequiredAgents = phaseObj?.required_agents;
|
|
@@ -116777,7 +117385,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
116777
117385
|
if (agentsMissing.length > 0) {
|
|
116778
117386
|
try {
|
|
116779
117387
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
116780
|
-
const planRaw =
|
|
117388
|
+
const planRaw = fs100.readFileSync(planPath, "utf-8");
|
|
116781
117389
|
const plan = JSON.parse(planRaw);
|
|
116782
117390
|
const targetPhase = plan.phases.find((p) => p.id === phase);
|
|
116783
117391
|
if (targetPhase && targetPhase.tasks.length > 0 && canInferMissingAgentsFromTaskGates(agentsMissing) && await allCompletedTasksHavePassedGateEvidence(dir, targetPhase.tasks)) {
|
|
@@ -116817,7 +117425,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
116817
117425
|
if (phaseCompleteConfig.regression_sweep?.enforce) {
|
|
116818
117426
|
try {
|
|
116819
117427
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
116820
|
-
const planRaw =
|
|
117428
|
+
const planRaw = fs100.readFileSync(planPath, "utf-8");
|
|
116821
117429
|
const plan = JSON.parse(planRaw);
|
|
116822
117430
|
const targetPhase = plan.phases.find((p) => p.id === phase);
|
|
116823
117431
|
if (targetPhase) {
|
|
@@ -116871,7 +117479,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
116871
117479
|
}
|
|
116872
117480
|
try {
|
|
116873
117481
|
const eventsPath = validateSwarmPath(dir, "events.jsonl");
|
|
116874
|
-
|
|
117482
|
+
fs100.appendFileSync(eventsPath, `${JSON.stringify(event)}
|
|
116875
117483
|
`, "utf-8");
|
|
116876
117484
|
} catch (writeError) {
|
|
116877
117485
|
warnings.push(`Warning: failed to write phase complete event: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
|
|
@@ -116946,12 +117554,12 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
116946
117554
|
warnings.push(`Warning: failed to update plan.json phase status`);
|
|
116947
117555
|
try {
|
|
116948
117556
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
116949
|
-
const planRaw =
|
|
117557
|
+
const planRaw = fs100.readFileSync(planPath, "utf-8");
|
|
116950
117558
|
const plan2 = JSON.parse(planRaw);
|
|
116951
117559
|
const phaseObj = plan2.phases.find((p) => p.id === phase);
|
|
116952
117560
|
if (phaseObj) {
|
|
116953
117561
|
phaseObj.status = "complete";
|
|
116954
|
-
|
|
117562
|
+
fs100.writeFileSync(planPath, JSON.stringify(plan2, null, 2), "utf-8");
|
|
116955
117563
|
}
|
|
116956
117564
|
} catch {}
|
|
116957
117565
|
} else if (plan) {
|
|
@@ -116988,12 +117596,12 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
116988
117596
|
warnings.push(`Warning: failed to update plan.json phase status`);
|
|
116989
117597
|
try {
|
|
116990
117598
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
116991
|
-
const planRaw =
|
|
117599
|
+
const planRaw = fs100.readFileSync(planPath, "utf-8");
|
|
116992
117600
|
const plan = JSON.parse(planRaw);
|
|
116993
117601
|
const phaseObj = plan.phases.find((p) => p.id === phase);
|
|
116994
117602
|
if (phaseObj) {
|
|
116995
117603
|
phaseObj.status = "complete";
|
|
116996
|
-
|
|
117604
|
+
fs100.writeFileSync(planPath, JSON.stringify(plan, null, 2), "utf-8");
|
|
116997
117605
|
}
|
|
116998
117606
|
} catch {}
|
|
116999
117607
|
}
|
|
@@ -117077,8 +117685,8 @@ init_discovery();
|
|
|
117077
117685
|
init_utils();
|
|
117078
117686
|
init_bun_compat();
|
|
117079
117687
|
init_create_tool();
|
|
117080
|
-
import * as
|
|
117081
|
-
import * as
|
|
117688
|
+
import * as fs101 from "node:fs";
|
|
117689
|
+
import * as path140 from "node:path";
|
|
117082
117690
|
var MAX_OUTPUT_BYTES6 = 52428800;
|
|
117083
117691
|
var AUDIT_TIMEOUT_MS = 120000;
|
|
117084
117692
|
function isValidEcosystem(value) {
|
|
@@ -117106,31 +117714,31 @@ function validateArgs3(args2) {
|
|
|
117106
117714
|
function detectEcosystems(directory) {
|
|
117107
117715
|
const ecosystems = [];
|
|
117108
117716
|
const cwd = directory;
|
|
117109
|
-
if (
|
|
117717
|
+
if (fs101.existsSync(path140.join(cwd, "package.json"))) {
|
|
117110
117718
|
ecosystems.push("npm");
|
|
117111
117719
|
}
|
|
117112
|
-
if (
|
|
117720
|
+
if (fs101.existsSync(path140.join(cwd, "pyproject.toml")) || fs101.existsSync(path140.join(cwd, "requirements.txt"))) {
|
|
117113
117721
|
ecosystems.push("pip");
|
|
117114
117722
|
}
|
|
117115
|
-
if (
|
|
117723
|
+
if (fs101.existsSync(path140.join(cwd, "Cargo.toml"))) {
|
|
117116
117724
|
ecosystems.push("cargo");
|
|
117117
117725
|
}
|
|
117118
|
-
if (
|
|
117726
|
+
if (fs101.existsSync(path140.join(cwd, "go.mod"))) {
|
|
117119
117727
|
ecosystems.push("go");
|
|
117120
117728
|
}
|
|
117121
117729
|
try {
|
|
117122
|
-
const files =
|
|
117730
|
+
const files = fs101.readdirSync(cwd);
|
|
117123
117731
|
if (files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
|
|
117124
117732
|
ecosystems.push("dotnet");
|
|
117125
117733
|
}
|
|
117126
117734
|
} catch {}
|
|
117127
|
-
if (
|
|
117735
|
+
if (fs101.existsSync(path140.join(cwd, "Gemfile")) || fs101.existsSync(path140.join(cwd, "Gemfile.lock"))) {
|
|
117128
117736
|
ecosystems.push("ruby");
|
|
117129
117737
|
}
|
|
117130
|
-
if (
|
|
117738
|
+
if (fs101.existsSync(path140.join(cwd, "pubspec.yaml"))) {
|
|
117131
117739
|
ecosystems.push("dart");
|
|
117132
117740
|
}
|
|
117133
|
-
if (
|
|
117741
|
+
if (fs101.existsSync(path140.join(cwd, "composer.lock"))) {
|
|
117134
117742
|
ecosystems.push("composer");
|
|
117135
117743
|
}
|
|
117136
117744
|
return ecosystems;
|
|
@@ -117143,7 +117751,7 @@ async function runNpmAudit(directory) {
|
|
|
117143
117751
|
stderr: "pipe",
|
|
117144
117752
|
cwd: directory
|
|
117145
117753
|
});
|
|
117146
|
-
const timeoutPromise = new Promise((
|
|
117754
|
+
const timeoutPromise = new Promise((resolve48) => setTimeout(() => resolve48("timeout"), AUDIT_TIMEOUT_MS));
|
|
117147
117755
|
const result = await Promise.race([
|
|
117148
117756
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
|
|
117149
117757
|
timeoutPromise
|
|
@@ -117263,7 +117871,7 @@ async function runPipAudit(directory) {
|
|
|
117263
117871
|
stderr: "pipe",
|
|
117264
117872
|
cwd: directory
|
|
117265
117873
|
});
|
|
117266
|
-
const timeoutPromise = new Promise((
|
|
117874
|
+
const timeoutPromise = new Promise((resolve48) => setTimeout(() => resolve48("timeout"), AUDIT_TIMEOUT_MS));
|
|
117267
117875
|
const result = await Promise.race([
|
|
117268
117876
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
|
|
117269
117877
|
timeoutPromise
|
|
@@ -117391,7 +117999,7 @@ async function runCargoAudit(directory) {
|
|
|
117391
117999
|
stderr: "pipe",
|
|
117392
118000
|
cwd: directory
|
|
117393
118001
|
});
|
|
117394
|
-
const timeoutPromise = new Promise((
|
|
118002
|
+
const timeoutPromise = new Promise((resolve48) => setTimeout(() => resolve48("timeout"), AUDIT_TIMEOUT_MS));
|
|
117395
118003
|
const result = await Promise.race([
|
|
117396
118004
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
117397
118005
|
timeoutPromise
|
|
@@ -117515,7 +118123,7 @@ async function runGoAudit(directory) {
|
|
|
117515
118123
|
stderr: "pipe",
|
|
117516
118124
|
cwd: directory
|
|
117517
118125
|
});
|
|
117518
|
-
const timeoutPromise = new Promise((
|
|
118126
|
+
const timeoutPromise = new Promise((resolve48) => setTimeout(() => resolve48("timeout"), AUDIT_TIMEOUT_MS));
|
|
117519
118127
|
const result = await Promise.race([
|
|
117520
118128
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
117521
118129
|
timeoutPromise
|
|
@@ -117648,7 +118256,7 @@ async function runDotnetAudit(directory) {
|
|
|
117648
118256
|
stderr: "pipe",
|
|
117649
118257
|
cwd: directory
|
|
117650
118258
|
});
|
|
117651
|
-
const timeoutPromise = new Promise((
|
|
118259
|
+
const timeoutPromise = new Promise((resolve48) => setTimeout(() => resolve48("timeout"), AUDIT_TIMEOUT_MS));
|
|
117652
118260
|
const result = await Promise.race([
|
|
117653
118261
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
117654
118262
|
timeoutPromise
|
|
@@ -117764,7 +118372,7 @@ async function runBundleAudit(directory) {
|
|
|
117764
118372
|
stderr: "pipe",
|
|
117765
118373
|
cwd: directory
|
|
117766
118374
|
});
|
|
117767
|
-
const timeoutPromise = new Promise((
|
|
118375
|
+
const timeoutPromise = new Promise((resolve48) => setTimeout(() => resolve48("timeout"), AUDIT_TIMEOUT_MS));
|
|
117768
118376
|
const result = await Promise.race([
|
|
117769
118377
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
117770
118378
|
timeoutPromise
|
|
@@ -117909,7 +118517,7 @@ async function runDartAudit(directory) {
|
|
|
117909
118517
|
stderr: "pipe",
|
|
117910
118518
|
cwd: directory
|
|
117911
118519
|
});
|
|
117912
|
-
const timeoutPromise = new Promise((
|
|
118520
|
+
const timeoutPromise = new Promise((resolve48) => setTimeout(() => resolve48("timeout"), AUDIT_TIMEOUT_MS));
|
|
117913
118521
|
const result = await Promise.race([
|
|
117914
118522
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
117915
118523
|
timeoutPromise
|
|
@@ -118024,7 +118632,7 @@ async function runComposerAudit(directory) {
|
|
|
118024
118632
|
stderr: "pipe",
|
|
118025
118633
|
cwd: directory
|
|
118026
118634
|
});
|
|
118027
|
-
const timeoutPromise = new Promise((
|
|
118635
|
+
const timeoutPromise = new Promise((resolve48) => setTimeout(() => resolve48("timeout"), AUDIT_TIMEOUT_MS));
|
|
118028
118636
|
const result = await Promise.race([
|
|
118029
118637
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
118030
118638
|
timeoutPromise
|
|
@@ -118266,8 +118874,8 @@ var pkg_audit = createSwarmTool({
|
|
|
118266
118874
|
// src/tools/placeholder-scan.ts
|
|
118267
118875
|
init_zod();
|
|
118268
118876
|
init_manager2();
|
|
118269
|
-
import * as
|
|
118270
|
-
import * as
|
|
118877
|
+
import * as fs102 from "node:fs";
|
|
118878
|
+
import * as path141 from "node:path";
|
|
118271
118879
|
init_utils();
|
|
118272
118880
|
init_create_tool();
|
|
118273
118881
|
var MAX_FILE_SIZE = 1024 * 1024;
|
|
@@ -118390,7 +118998,7 @@ function isScaffoldFile(filePath) {
|
|
|
118390
118998
|
if (SCAFFOLD_PATH_PATTERNS.some((pattern) => pattern.test(normalizedPath))) {
|
|
118391
118999
|
return true;
|
|
118392
119000
|
}
|
|
118393
|
-
const filename =
|
|
119001
|
+
const filename = path141.basename(filePath);
|
|
118394
119002
|
if (SCAFFOLD_FILENAME_PATTERNS.some((pattern) => pattern.test(filename))) {
|
|
118395
119003
|
return true;
|
|
118396
119004
|
}
|
|
@@ -118407,7 +119015,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
118407
119015
|
if (regex.test(normalizedPath)) {
|
|
118408
119016
|
return true;
|
|
118409
119017
|
}
|
|
118410
|
-
const filename =
|
|
119018
|
+
const filename = path141.basename(filePath);
|
|
118411
119019
|
const filenameRegex = new RegExp(`^${regexPattern}$`, "i");
|
|
118412
119020
|
if (filenameRegex.test(filename)) {
|
|
118413
119021
|
return true;
|
|
@@ -118416,7 +119024,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
118416
119024
|
return false;
|
|
118417
119025
|
}
|
|
118418
119026
|
function isParserSupported(filePath) {
|
|
118419
|
-
const ext =
|
|
119027
|
+
const ext = path141.extname(filePath).toLowerCase();
|
|
118420
119028
|
return SUPPORTED_PARSER_EXTENSIONS.has(ext);
|
|
118421
119029
|
}
|
|
118422
119030
|
function isPlanFile(filePath) {
|
|
@@ -118663,28 +119271,28 @@ async function placeholderScan(input, directory) {
|
|
|
118663
119271
|
let filesScanned = 0;
|
|
118664
119272
|
const filesWithFindings = new Set;
|
|
118665
119273
|
for (const filePath of changed_files) {
|
|
118666
|
-
const fullPath =
|
|
118667
|
-
const resolvedDirectory =
|
|
118668
|
-
if (!fullPath.startsWith(resolvedDirectory +
|
|
119274
|
+
const fullPath = path141.isAbsolute(filePath) ? filePath : path141.resolve(directory, filePath);
|
|
119275
|
+
const resolvedDirectory = path141.resolve(directory);
|
|
119276
|
+
if (!fullPath.startsWith(resolvedDirectory + path141.sep) && fullPath !== resolvedDirectory) {
|
|
118669
119277
|
continue;
|
|
118670
119278
|
}
|
|
118671
|
-
if (!
|
|
119279
|
+
if (!fs102.existsSync(fullPath)) {
|
|
118672
119280
|
continue;
|
|
118673
119281
|
}
|
|
118674
119282
|
if (isAllowedByGlobs(filePath, allow_globs)) {
|
|
118675
119283
|
continue;
|
|
118676
119284
|
}
|
|
118677
|
-
const relativeFilePath =
|
|
119285
|
+
const relativeFilePath = path141.relative(directory, fullPath).replace(/\\/g, "/");
|
|
118678
119286
|
if (FILE_ALLOWLIST.some((allowed) => relativeFilePath.endsWith(allowed))) {
|
|
118679
119287
|
continue;
|
|
118680
119288
|
}
|
|
118681
119289
|
let content;
|
|
118682
119290
|
try {
|
|
118683
|
-
const stat9 =
|
|
119291
|
+
const stat9 = fs102.statSync(fullPath);
|
|
118684
119292
|
if (stat9.size > MAX_FILE_SIZE) {
|
|
118685
119293
|
continue;
|
|
118686
119294
|
}
|
|
118687
|
-
content =
|
|
119295
|
+
content = fs102.readFileSync(fullPath, "utf-8");
|
|
118688
119296
|
} catch {
|
|
118689
119297
|
continue;
|
|
118690
119298
|
}
|
|
@@ -118746,8 +119354,8 @@ var placeholder_scan = createSwarmTool({
|
|
|
118746
119354
|
});
|
|
118747
119355
|
|
|
118748
119356
|
// src/tools/pre-check-batch.ts
|
|
118749
|
-
import * as
|
|
118750
|
-
import * as
|
|
119357
|
+
import * as fs106 from "node:fs";
|
|
119358
|
+
import * as path145 from "node:path";
|
|
118751
119359
|
init_zod();
|
|
118752
119360
|
init_manager2();
|
|
118753
119361
|
init_utils();
|
|
@@ -118887,9 +119495,9 @@ var _internals61 = {
|
|
|
118887
119495
|
init_zod();
|
|
118888
119496
|
init_manager2();
|
|
118889
119497
|
init_detector();
|
|
118890
|
-
import * as
|
|
118891
|
-
import * as
|
|
118892
|
-
import { extname as
|
|
119498
|
+
import * as fs105 from "node:fs";
|
|
119499
|
+
import * as path144 from "node:path";
|
|
119500
|
+
import { extname as extname21 } from "node:path";
|
|
118893
119501
|
|
|
118894
119502
|
// src/sast/rules/c.ts
|
|
118895
119503
|
var cRules = [
|
|
@@ -119602,9 +120210,9 @@ function executeRulesSync(filePath, content, language) {
|
|
|
119602
120210
|
}
|
|
119603
120211
|
|
|
119604
120212
|
// src/sast/semgrep.ts
|
|
119605
|
-
import * as
|
|
119606
|
-
import * as
|
|
119607
|
-
import * as
|
|
120213
|
+
import * as child_process10 from "node:child_process";
|
|
120214
|
+
import * as fs103 from "node:fs";
|
|
120215
|
+
import * as path142 from "node:path";
|
|
119608
120216
|
var semgrepAvailableCache = null;
|
|
119609
120217
|
var DEFAULT_RULES_DIR = ".swarm/semgrep-rules";
|
|
119610
120218
|
var DEFAULT_TIMEOUT_MS3 = 30000;
|
|
@@ -119621,7 +120229,7 @@ function isSemgrepAvailable() {
|
|
|
119621
120229
|
return semgrepAvailableCache;
|
|
119622
120230
|
}
|
|
119623
120231
|
try {
|
|
119624
|
-
|
|
120232
|
+
child_process10.execFileSync("semgrep", ["--version"], {
|
|
119625
120233
|
encoding: "utf-8",
|
|
119626
120234
|
stdio: "pipe"
|
|
119627
120235
|
});
|
|
@@ -119685,8 +120293,8 @@ function mapSemgrepSeverity(severity) {
|
|
|
119685
120293
|
}
|
|
119686
120294
|
}
|
|
119687
120295
|
async function executeWithTimeout(command, args2, options) {
|
|
119688
|
-
return new Promise((
|
|
119689
|
-
const child =
|
|
120296
|
+
return new Promise((resolve50) => {
|
|
120297
|
+
const child = child_process10.spawn(command, args2, {
|
|
119690
120298
|
shell: false,
|
|
119691
120299
|
cwd: options.cwd
|
|
119692
120300
|
});
|
|
@@ -119694,7 +120302,7 @@ async function executeWithTimeout(command, args2, options) {
|
|
|
119694
120302
|
let stderr = "";
|
|
119695
120303
|
const timeout = setTimeout(() => {
|
|
119696
120304
|
child.kill("SIGTERM");
|
|
119697
|
-
|
|
120305
|
+
resolve50({
|
|
119698
120306
|
stdout,
|
|
119699
120307
|
stderr: "Process timed out",
|
|
119700
120308
|
exitCode: 124
|
|
@@ -119708,7 +120316,7 @@ async function executeWithTimeout(command, args2, options) {
|
|
|
119708
120316
|
});
|
|
119709
120317
|
child.on("close", (code) => {
|
|
119710
120318
|
clearTimeout(timeout);
|
|
119711
|
-
|
|
120319
|
+
resolve50({
|
|
119712
120320
|
stdout,
|
|
119713
120321
|
stderr,
|
|
119714
120322
|
exitCode: code ?? 0
|
|
@@ -119716,7 +120324,7 @@ async function executeWithTimeout(command, args2, options) {
|
|
|
119716
120324
|
});
|
|
119717
120325
|
child.on("error", (err2) => {
|
|
119718
120326
|
clearTimeout(timeout);
|
|
119719
|
-
|
|
120327
|
+
resolve50({
|
|
119720
120328
|
stdout,
|
|
119721
120329
|
stderr: err2.message,
|
|
119722
120330
|
exitCode: 1
|
|
@@ -119791,14 +120399,14 @@ async function runSemgrep(options) {
|
|
|
119791
120399
|
}
|
|
119792
120400
|
function getRulesDirectory(projectRoot) {
|
|
119793
120401
|
if (projectRoot) {
|
|
119794
|
-
return
|
|
120402
|
+
return path142.resolve(projectRoot, DEFAULT_RULES_DIR);
|
|
119795
120403
|
}
|
|
119796
120404
|
return DEFAULT_RULES_DIR;
|
|
119797
120405
|
}
|
|
119798
120406
|
function hasBundledRules(projectRoot) {
|
|
119799
120407
|
const rulesDir = getRulesDirectory(projectRoot);
|
|
119800
120408
|
try {
|
|
119801
|
-
return
|
|
120409
|
+
return fs103.existsSync(rulesDir);
|
|
119802
120410
|
} catch {
|
|
119803
120411
|
return false;
|
|
119804
120412
|
}
|
|
@@ -119811,25 +120419,25 @@ init_create_tool();
|
|
|
119811
120419
|
// src/tools/sast-baseline.ts
|
|
119812
120420
|
init_utils2();
|
|
119813
120421
|
import * as crypto11 from "node:crypto";
|
|
119814
|
-
import * as
|
|
119815
|
-
import * as
|
|
120422
|
+
import * as fs104 from "node:fs";
|
|
120423
|
+
import * as path143 from "node:path";
|
|
119816
120424
|
var BASELINE_SCHEMA_VERSION = "1.0.0";
|
|
119817
120425
|
var MAX_BASELINE_FINDINGS = 2000;
|
|
119818
120426
|
var MAX_BASELINE_BYTES = 2 * 1048576;
|
|
119819
120427
|
var LOCK_RETRY_DELAYS_MS = [50, 100, 200, 400, 800];
|
|
119820
120428
|
function normalizeFindingPath(directory, file3) {
|
|
119821
|
-
const resolved =
|
|
119822
|
-
const rel =
|
|
120429
|
+
const resolved = path143.isAbsolute(file3) ? file3 : path143.resolve(directory, file3);
|
|
120430
|
+
const rel = path143.relative(path143.resolve(directory), resolved);
|
|
119823
120431
|
return rel.replace(/\\/g, "/");
|
|
119824
120432
|
}
|
|
119825
120433
|
function baselineRelPath(phase) {
|
|
119826
|
-
return
|
|
120434
|
+
return path143.join("evidence", String(phase), "sast-baseline.json");
|
|
119827
120435
|
}
|
|
119828
120436
|
function tempRelPath(phase) {
|
|
119829
|
-
return
|
|
120437
|
+
return path143.join("evidence", String(phase), `sast-baseline.json.tmp.${Date.now()}.${process.pid}`);
|
|
119830
120438
|
}
|
|
119831
120439
|
function lockRelPath(phase) {
|
|
119832
|
-
return
|
|
120440
|
+
return path143.join("evidence", String(phase), "sast-baseline.json.lock");
|
|
119833
120441
|
}
|
|
119834
120442
|
function getLine(lines, idx) {
|
|
119835
120443
|
if (idx < 0 || idx >= lines.length)
|
|
@@ -119846,7 +120454,7 @@ function fingerprintFinding(finding, directory, occurrenceIndex) {
|
|
|
119846
120454
|
}
|
|
119847
120455
|
const lineNum = finding.location.line;
|
|
119848
120456
|
try {
|
|
119849
|
-
const content =
|
|
120457
|
+
const content = fs104.readFileSync(finding.location.file, "utf-8");
|
|
119850
120458
|
const lines = content.split(`
|
|
119851
120459
|
`);
|
|
119852
120460
|
const idx = lineNum - 1;
|
|
@@ -119877,7 +120485,7 @@ function assignOccurrenceIndices(findings, directory) {
|
|
|
119877
120485
|
try {
|
|
119878
120486
|
if (relFile.startsWith(".."))
|
|
119879
120487
|
throw new Error("escapes workspace");
|
|
119880
|
-
const content =
|
|
120488
|
+
const content = fs104.readFileSync(finding.location.file, "utf-8");
|
|
119881
120489
|
const lines = content.split(`
|
|
119882
120490
|
`);
|
|
119883
120491
|
const idx = lineNum - 1;
|
|
@@ -119906,16 +120514,16 @@ function assignOccurrenceIndices(findings, directory) {
|
|
|
119906
120514
|
async function acquireLock2(lockPath) {
|
|
119907
120515
|
for (let attempt = 0;attempt <= LOCK_RETRY_DELAYS_MS.length; attempt++) {
|
|
119908
120516
|
try {
|
|
119909
|
-
const fd =
|
|
119910
|
-
|
|
120517
|
+
const fd = fs104.openSync(lockPath, "wx");
|
|
120518
|
+
fs104.closeSync(fd);
|
|
119911
120519
|
return () => {
|
|
119912
120520
|
try {
|
|
119913
|
-
|
|
120521
|
+
fs104.unlinkSync(lockPath);
|
|
119914
120522
|
} catch {}
|
|
119915
120523
|
};
|
|
119916
120524
|
} catch {
|
|
119917
120525
|
if (attempt < LOCK_RETRY_DELAYS_MS.length) {
|
|
119918
|
-
await new Promise((
|
|
120526
|
+
await new Promise((resolve51) => setTimeout(resolve51, LOCK_RETRY_DELAYS_MS[attempt]));
|
|
119919
120527
|
}
|
|
119920
120528
|
}
|
|
119921
120529
|
}
|
|
@@ -119950,13 +120558,13 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
119950
120558
|
message: e instanceof Error ? e.message : "Path validation failed"
|
|
119951
120559
|
};
|
|
119952
120560
|
}
|
|
119953
|
-
|
|
119954
|
-
|
|
120561
|
+
fs104.mkdirSync(path143.dirname(baselinePath), { recursive: true });
|
|
120562
|
+
fs104.mkdirSync(path143.dirname(tempPath), { recursive: true });
|
|
119955
120563
|
const releaseLock = await acquireLock2(lockPath);
|
|
119956
120564
|
try {
|
|
119957
120565
|
let existing = null;
|
|
119958
120566
|
try {
|
|
119959
|
-
const raw =
|
|
120567
|
+
const raw = fs104.readFileSync(baselinePath, "utf-8");
|
|
119960
120568
|
const parsed = JSON.parse(raw);
|
|
119961
120569
|
if (parsed.schema_version === BASELINE_SCHEMA_VERSION) {
|
|
119962
120570
|
existing = parsed;
|
|
@@ -120016,8 +120624,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
120016
120624
|
message: `Baseline would exceed size cap (${json4.length} bytes > ${MAX_BASELINE_BYTES})`
|
|
120017
120625
|
};
|
|
120018
120626
|
}
|
|
120019
|
-
|
|
120020
|
-
|
|
120627
|
+
fs104.writeFileSync(tempPath, json4, "utf-8");
|
|
120628
|
+
fs104.renameSync(tempPath, baselinePath);
|
|
120021
120629
|
return {
|
|
120022
120630
|
status: "merged",
|
|
120023
120631
|
path: baselinePath,
|
|
@@ -120048,8 +120656,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
120048
120656
|
message: `Baseline would exceed size cap (${json3.length} bytes > ${MAX_BASELINE_BYTES})`
|
|
120049
120657
|
};
|
|
120050
120658
|
}
|
|
120051
|
-
|
|
120052
|
-
|
|
120659
|
+
fs104.writeFileSync(tempPath, json3, "utf-8");
|
|
120660
|
+
fs104.renameSync(tempPath, baselinePath);
|
|
120053
120661
|
return {
|
|
120054
120662
|
status: "written",
|
|
120055
120663
|
path: baselinePath,
|
|
@@ -120074,7 +120682,7 @@ function loadBaseline(directory, phase) {
|
|
|
120074
120682
|
};
|
|
120075
120683
|
}
|
|
120076
120684
|
try {
|
|
120077
|
-
const raw =
|
|
120685
|
+
const raw = fs104.readFileSync(baselinePath, "utf-8");
|
|
120078
120686
|
const parsed = JSON.parse(raw);
|
|
120079
120687
|
if (parsed.schema_version !== BASELINE_SCHEMA_VERSION) {
|
|
120080
120688
|
return {
|
|
@@ -120122,17 +120730,17 @@ var SEVERITY_ORDER = {
|
|
|
120122
120730
|
};
|
|
120123
120731
|
function shouldSkipFile(filePath) {
|
|
120124
120732
|
try {
|
|
120125
|
-
const stats =
|
|
120733
|
+
const stats = fs105.statSync(filePath);
|
|
120126
120734
|
if (stats.size > MAX_FILE_SIZE_BYTES8) {
|
|
120127
120735
|
return { skip: true, reason: "file too large" };
|
|
120128
120736
|
}
|
|
120129
120737
|
if (stats.size === 0) {
|
|
120130
120738
|
return { skip: true, reason: "empty file" };
|
|
120131
120739
|
}
|
|
120132
|
-
const fd =
|
|
120740
|
+
const fd = fs105.openSync(filePath, "r");
|
|
120133
120741
|
const buffer = Buffer.alloc(8192);
|
|
120134
|
-
const bytesRead =
|
|
120135
|
-
|
|
120742
|
+
const bytesRead = fs105.readSync(fd, buffer, 0, 8192, 0);
|
|
120743
|
+
fs105.closeSync(fd);
|
|
120136
120744
|
if (bytesRead > 0) {
|
|
120137
120745
|
let nullCount = 0;
|
|
120138
120746
|
for (let i2 = 0;i2 < bytesRead; i2++) {
|
|
@@ -120171,7 +120779,7 @@ function countBySeverity(findings) {
|
|
|
120171
120779
|
}
|
|
120172
120780
|
function scanFileWithTierA(filePath, language) {
|
|
120173
120781
|
try {
|
|
120174
|
-
const content =
|
|
120782
|
+
const content = fs105.readFileSync(filePath, "utf-8");
|
|
120175
120783
|
const findings = executeRulesSync(filePath, content, language);
|
|
120176
120784
|
return findings.map((f) => ({
|
|
120177
120785
|
rule_id: f.rule_id,
|
|
@@ -120224,13 +120832,13 @@ async function sastScan(input, directory, config3) {
|
|
|
120224
120832
|
_filesSkipped++;
|
|
120225
120833
|
continue;
|
|
120226
120834
|
}
|
|
120227
|
-
const resolvedPath =
|
|
120228
|
-
const resolvedDirectory =
|
|
120229
|
-
if (!resolvedPath.startsWith(resolvedDirectory +
|
|
120835
|
+
const resolvedPath = path144.isAbsolute(filePath) ? filePath : path144.resolve(directory, filePath);
|
|
120836
|
+
const resolvedDirectory = path144.resolve(directory);
|
|
120837
|
+
if (!resolvedPath.startsWith(resolvedDirectory + path144.sep) && resolvedPath !== resolvedDirectory) {
|
|
120230
120838
|
_filesSkipped++;
|
|
120231
120839
|
continue;
|
|
120232
120840
|
}
|
|
120233
|
-
if (!
|
|
120841
|
+
if (!fs105.existsSync(resolvedPath)) {
|
|
120234
120842
|
_filesSkipped++;
|
|
120235
120843
|
continue;
|
|
120236
120844
|
}
|
|
@@ -120239,7 +120847,7 @@ async function sastScan(input, directory, config3) {
|
|
|
120239
120847
|
_filesSkipped++;
|
|
120240
120848
|
continue;
|
|
120241
120849
|
}
|
|
120242
|
-
const ext =
|
|
120850
|
+
const ext = extname21(resolvedPath).toLowerCase();
|
|
120243
120851
|
const profile = getProfileForFile(resolvedPath);
|
|
120244
120852
|
const langDef = getLanguageForExtension(ext);
|
|
120245
120853
|
if (!profile && !langDef) {
|
|
@@ -120541,20 +121149,20 @@ function validatePath(inputPath, baseDir, workspaceDir) {
|
|
|
120541
121149
|
let resolved;
|
|
120542
121150
|
const isWinAbs = isWindowsAbsolutePath(inputPath);
|
|
120543
121151
|
if (isWinAbs) {
|
|
120544
|
-
resolved =
|
|
120545
|
-
} else if (
|
|
120546
|
-
resolved =
|
|
121152
|
+
resolved = path145.win32.resolve(inputPath);
|
|
121153
|
+
} else if (path145.isAbsolute(inputPath)) {
|
|
121154
|
+
resolved = path145.resolve(inputPath);
|
|
120547
121155
|
} else {
|
|
120548
|
-
resolved =
|
|
121156
|
+
resolved = path145.resolve(baseDir, inputPath);
|
|
120549
121157
|
}
|
|
120550
|
-
const workspaceResolved =
|
|
120551
|
-
let
|
|
121158
|
+
const workspaceResolved = path145.resolve(workspaceDir);
|
|
121159
|
+
let relative29;
|
|
120552
121160
|
if (isWinAbs) {
|
|
120553
|
-
|
|
121161
|
+
relative29 = path145.win32.relative(workspaceResolved, resolved);
|
|
120554
121162
|
} else {
|
|
120555
|
-
|
|
121163
|
+
relative29 = path145.relative(workspaceResolved, resolved);
|
|
120556
121164
|
}
|
|
120557
|
-
if (
|
|
121165
|
+
if (relative29.startsWith("..")) {
|
|
120558
121166
|
return "path traversal detected";
|
|
120559
121167
|
}
|
|
120560
121168
|
return null;
|
|
@@ -120617,7 +121225,7 @@ async function runLintOnFiles(linter, files, workspaceDir) {
|
|
|
120617
121225
|
if (typeof file3 !== "string") {
|
|
120618
121226
|
continue;
|
|
120619
121227
|
}
|
|
120620
|
-
const resolvedPath =
|
|
121228
|
+
const resolvedPath = path145.resolve(file3);
|
|
120621
121229
|
const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
|
|
120622
121230
|
if (validationError) {
|
|
120623
121231
|
continue;
|
|
@@ -120774,7 +121382,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
120774
121382
|
skippedFiles++;
|
|
120775
121383
|
continue;
|
|
120776
121384
|
}
|
|
120777
|
-
const resolvedPath =
|
|
121385
|
+
const resolvedPath = path145.resolve(file3);
|
|
120778
121386
|
const validationError = validatePath(resolvedPath, directory, directory);
|
|
120779
121387
|
if (validationError) {
|
|
120780
121388
|
skippedFiles++;
|
|
@@ -120792,14 +121400,14 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
120792
121400
|
};
|
|
120793
121401
|
}
|
|
120794
121402
|
for (const file3 of validatedFiles) {
|
|
120795
|
-
const ext =
|
|
121403
|
+
const ext = path145.extname(file3).toLowerCase();
|
|
120796
121404
|
if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
|
|
120797
121405
|
skippedFiles++;
|
|
120798
121406
|
continue;
|
|
120799
121407
|
}
|
|
120800
121408
|
let stat9;
|
|
120801
121409
|
try {
|
|
120802
|
-
stat9 =
|
|
121410
|
+
stat9 = fs106.statSync(file3);
|
|
120803
121411
|
} catch {
|
|
120804
121412
|
skippedFiles++;
|
|
120805
121413
|
continue;
|
|
@@ -120810,7 +121418,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
120810
121418
|
}
|
|
120811
121419
|
let content;
|
|
120812
121420
|
try {
|
|
120813
|
-
const buffer =
|
|
121421
|
+
const buffer = fs106.readFileSync(file3);
|
|
120814
121422
|
if (buffer.includes(0)) {
|
|
120815
121423
|
skippedFiles++;
|
|
120816
121424
|
continue;
|
|
@@ -121011,7 +121619,7 @@ function classifySastFindings(findings, changedLineRanges, directory) {
|
|
|
121011
121619
|
const preexistingFindings = [];
|
|
121012
121620
|
for (const finding of findings) {
|
|
121013
121621
|
const filePath = finding.location.file;
|
|
121014
|
-
const normalised =
|
|
121622
|
+
const normalised = path145.relative(directory, filePath).replace(/\\/g, "/");
|
|
121015
121623
|
const changedLines = changedLineRanges.get(normalised);
|
|
121016
121624
|
if (changedLines?.has(finding.location.line)) {
|
|
121017
121625
|
newFindings.push(finding);
|
|
@@ -121062,7 +121670,7 @@ async function runPreCheckBatch(input, workspaceDir, contextDir) {
|
|
|
121062
121670
|
warn(`pre_check_batch: Invalid file path: ${file3}`);
|
|
121063
121671
|
continue;
|
|
121064
121672
|
}
|
|
121065
|
-
changedFiles.push(
|
|
121673
|
+
changedFiles.push(path145.resolve(directory, file3));
|
|
121066
121674
|
}
|
|
121067
121675
|
if (changedFiles.length === 0) {
|
|
121068
121676
|
warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
|
|
@@ -121263,9 +121871,9 @@ var pre_check_batch = createSwarmTool({
|
|
|
121263
121871
|
};
|
|
121264
121872
|
return JSON.stringify(errorResult, null, 2);
|
|
121265
121873
|
}
|
|
121266
|
-
const resolvedDirectory =
|
|
121267
|
-
const workspaceAnchor =
|
|
121268
|
-
if (resolvedDirectory !== workspaceAnchor && resolvedDirectory.startsWith(workspaceAnchor +
|
|
121874
|
+
const resolvedDirectory = path145.resolve(typedArgs.directory);
|
|
121875
|
+
const workspaceAnchor = path145.resolve(directory);
|
|
121876
|
+
if (resolvedDirectory !== workspaceAnchor && resolvedDirectory.startsWith(workspaceAnchor + path145.sep)) {
|
|
121269
121877
|
const subDirError = `directory "${typedArgs.directory}" is a subdirectory of the project root — pre_check_batch requires the project root directory "${workspaceAnchor}"`;
|
|
121270
121878
|
const subDirResult = {
|
|
121271
121879
|
gates_passed: false,
|
|
@@ -121317,7 +121925,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
121317
121925
|
|
|
121318
121926
|
// src/tools/repo-map.ts
|
|
121319
121927
|
init_zod();
|
|
121320
|
-
import * as
|
|
121928
|
+
import * as path146 from "node:path";
|
|
121321
121929
|
init_path_security();
|
|
121322
121930
|
init_create_tool();
|
|
121323
121931
|
var VALID_ACTIONS = [
|
|
@@ -121342,7 +121950,7 @@ function validateFile(p) {
|
|
|
121342
121950
|
return "file contains control characters";
|
|
121343
121951
|
if (containsPathTraversal(p))
|
|
121344
121952
|
return "file contains path traversal";
|
|
121345
|
-
if (
|
|
121953
|
+
if (path146.isAbsolute(p) || /^[a-zA-Z]:[\\/]/.test(p)) {
|
|
121346
121954
|
return "file must be a workspace-relative path, not absolute";
|
|
121347
121955
|
}
|
|
121348
121956
|
return null;
|
|
@@ -121365,8 +121973,8 @@ function ok(action, payload) {
|
|
|
121365
121973
|
}
|
|
121366
121974
|
function toRelativeGraphPath(input, workspaceRoot) {
|
|
121367
121975
|
const normalized = input.replace(/\\/g, "/");
|
|
121368
|
-
if (
|
|
121369
|
-
const rel =
|
|
121976
|
+
if (path146.isAbsolute(normalized)) {
|
|
121977
|
+
const rel = path146.relative(workspaceRoot, normalized).replace(/\\/g, "/");
|
|
121370
121978
|
return normalizeGraphPath2(rel);
|
|
121371
121979
|
}
|
|
121372
121980
|
return normalizeGraphPath2(normalized);
|
|
@@ -121511,8 +122119,8 @@ var repo_map = createSwarmTool({
|
|
|
121511
122119
|
// src/tools/req-coverage.ts
|
|
121512
122120
|
init_zod();
|
|
121513
122121
|
init_create_tool();
|
|
121514
|
-
import * as
|
|
121515
|
-
import * as
|
|
122122
|
+
import * as fs107 from "node:fs";
|
|
122123
|
+
import * as path147 from "node:path";
|
|
121516
122124
|
var SPEC_FILE = ".swarm/spec.md";
|
|
121517
122125
|
var EVIDENCE_DIR4 = ".swarm/evidence";
|
|
121518
122126
|
var OBLIGATION_KEYWORDS2 = ["MUST", "SHOULD", "SHALL"];
|
|
@@ -121571,19 +122179,19 @@ function extractObligationAndText(id, lineText) {
|
|
|
121571
122179
|
var PHASE_TASK_ID_REGEX = /^\d+\.\d+(\.\d+)*$/;
|
|
121572
122180
|
function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
121573
122181
|
const touchedFiles = new Set;
|
|
121574
|
-
if (!
|
|
122182
|
+
if (!fs107.existsSync(evidenceDir) || !fs107.statSync(evidenceDir).isDirectory()) {
|
|
121575
122183
|
return [];
|
|
121576
122184
|
}
|
|
121577
122185
|
let entries;
|
|
121578
122186
|
try {
|
|
121579
|
-
entries =
|
|
122187
|
+
entries = fs107.readdirSync(evidenceDir);
|
|
121580
122188
|
} catch {
|
|
121581
122189
|
return [];
|
|
121582
122190
|
}
|
|
121583
122191
|
for (const entry of entries) {
|
|
121584
|
-
const entryPath =
|
|
122192
|
+
const entryPath = path147.join(evidenceDir, entry);
|
|
121585
122193
|
try {
|
|
121586
|
-
const stat9 =
|
|
122194
|
+
const stat9 = fs107.statSync(entryPath);
|
|
121587
122195
|
if (!stat9.isDirectory()) {
|
|
121588
122196
|
continue;
|
|
121589
122197
|
}
|
|
@@ -121597,14 +122205,14 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
121597
122205
|
if (entryPhase !== String(phase)) {
|
|
121598
122206
|
continue;
|
|
121599
122207
|
}
|
|
121600
|
-
const evidenceFilePath =
|
|
122208
|
+
const evidenceFilePath = path147.join(entryPath, "evidence.json");
|
|
121601
122209
|
try {
|
|
121602
|
-
const resolvedPath =
|
|
121603
|
-
const evidenceDirResolved =
|
|
121604
|
-
if (!resolvedPath.startsWith(evidenceDirResolved +
|
|
122210
|
+
const resolvedPath = path147.resolve(evidenceFilePath);
|
|
122211
|
+
const evidenceDirResolved = path147.resolve(evidenceDir);
|
|
122212
|
+
if (!resolvedPath.startsWith(evidenceDirResolved + path147.sep)) {
|
|
121605
122213
|
continue;
|
|
121606
122214
|
}
|
|
121607
|
-
const stat9 =
|
|
122215
|
+
const stat9 = fs107.lstatSync(evidenceFilePath);
|
|
121608
122216
|
if (!stat9.isFile()) {
|
|
121609
122217
|
continue;
|
|
121610
122218
|
}
|
|
@@ -121616,7 +122224,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
121616
122224
|
}
|
|
121617
122225
|
let content;
|
|
121618
122226
|
try {
|
|
121619
|
-
content =
|
|
122227
|
+
content = fs107.readFileSync(evidenceFilePath, "utf-8");
|
|
121620
122228
|
} catch {
|
|
121621
122229
|
continue;
|
|
121622
122230
|
}
|
|
@@ -121635,7 +122243,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
121635
122243
|
if (Array.isArray(diffEntry.files_changed)) {
|
|
121636
122244
|
for (const file3 of diffEntry.files_changed) {
|
|
121637
122245
|
if (typeof file3 === "string") {
|
|
121638
|
-
touchedFiles.add(
|
|
122246
|
+
touchedFiles.add(path147.resolve(cwd, file3));
|
|
121639
122247
|
}
|
|
121640
122248
|
}
|
|
121641
122249
|
}
|
|
@@ -121648,12 +122256,12 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
121648
122256
|
}
|
|
121649
122257
|
function searchFileForKeywords(filePath, keywords, cwd) {
|
|
121650
122258
|
try {
|
|
121651
|
-
const resolvedPath =
|
|
121652
|
-
const cwdResolved =
|
|
122259
|
+
const resolvedPath = path147.resolve(filePath);
|
|
122260
|
+
const cwdResolved = path147.resolve(cwd);
|
|
121653
122261
|
if (!resolvedPath.startsWith(cwdResolved)) {
|
|
121654
122262
|
return false;
|
|
121655
122263
|
}
|
|
121656
|
-
const content =
|
|
122264
|
+
const content = fs107.readFileSync(resolvedPath, "utf-8");
|
|
121657
122265
|
for (const keyword of keywords) {
|
|
121658
122266
|
const regex = new RegExp(`\\b${keyword}\\b`, "i");
|
|
121659
122267
|
if (regex.test(content)) {
|
|
@@ -121783,10 +122391,10 @@ var req_coverage = createSwarmTool({
|
|
|
121783
122391
|
}, null, 2);
|
|
121784
122392
|
}
|
|
121785
122393
|
const cwd = inputDirectory || directory;
|
|
121786
|
-
const specPath =
|
|
122394
|
+
const specPath = path147.join(cwd, SPEC_FILE);
|
|
121787
122395
|
let specContent;
|
|
121788
122396
|
try {
|
|
121789
|
-
specContent =
|
|
122397
|
+
specContent = fs107.readFileSync(specPath, "utf-8");
|
|
121790
122398
|
} catch (readError) {
|
|
121791
122399
|
return JSON.stringify({
|
|
121792
122400
|
success: false,
|
|
@@ -121810,7 +122418,7 @@ var req_coverage = createSwarmTool({
|
|
|
121810
122418
|
message: "No FR requirements found in spec.md"
|
|
121811
122419
|
}, null, 2);
|
|
121812
122420
|
}
|
|
121813
|
-
const evidenceDir =
|
|
122421
|
+
const evidenceDir = path147.join(cwd, EVIDENCE_DIR4);
|
|
121814
122422
|
const touchedFiles = readTouchedFiles(evidenceDir, phase, cwd);
|
|
121815
122423
|
const analyzedRequirements = [];
|
|
121816
122424
|
let coveredCount = 0;
|
|
@@ -121836,12 +122444,12 @@ var req_coverage = createSwarmTool({
|
|
|
121836
122444
|
requirements: analyzedRequirements
|
|
121837
122445
|
};
|
|
121838
122446
|
const reportFilename = `req-coverage-phase-${phase}.json`;
|
|
121839
|
-
const reportPath =
|
|
122447
|
+
const reportPath = path147.join(evidenceDir, reportFilename);
|
|
121840
122448
|
try {
|
|
121841
|
-
if (!
|
|
121842
|
-
|
|
122449
|
+
if (!fs107.existsSync(evidenceDir)) {
|
|
122450
|
+
fs107.mkdirSync(evidenceDir, { recursive: true });
|
|
121843
122451
|
}
|
|
121844
|
-
|
|
122452
|
+
fs107.writeFileSync(reportPath, JSON.stringify(result, null, 2), "utf-8");
|
|
121845
122453
|
} catch (writeError) {
|
|
121846
122454
|
console.warn(`Failed to write coverage report: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
|
|
121847
122455
|
}
|
|
@@ -121925,8 +122533,8 @@ init_plan_schema();
|
|
|
121925
122533
|
init_qa_gate_profile();
|
|
121926
122534
|
init_file_locks();
|
|
121927
122535
|
import * as crypto12 from "node:crypto";
|
|
121928
|
-
import * as
|
|
121929
|
-
import * as
|
|
122536
|
+
import * as fs108 from "node:fs";
|
|
122537
|
+
import * as path148 from "node:path";
|
|
121930
122538
|
init_ledger();
|
|
121931
122539
|
init_manager();
|
|
121932
122540
|
init_state();
|
|
@@ -122007,17 +122615,17 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
122007
122615
|
};
|
|
122008
122616
|
}
|
|
122009
122617
|
if (args2.working_directory && fallbackDir) {
|
|
122010
|
-
const resolvedTarget =
|
|
122011
|
-
const resolvedRoot =
|
|
122618
|
+
const resolvedTarget = path148.resolve(args2.working_directory);
|
|
122619
|
+
const resolvedRoot = path148.resolve(fallbackDir);
|
|
122012
122620
|
let fallbackExists = false;
|
|
122013
122621
|
try {
|
|
122014
|
-
|
|
122622
|
+
fs108.accessSync(resolvedRoot, fs108.constants.F_OK);
|
|
122015
122623
|
fallbackExists = true;
|
|
122016
122624
|
} catch {
|
|
122017
122625
|
fallbackExists = false;
|
|
122018
122626
|
}
|
|
122019
122627
|
if (fallbackExists) {
|
|
122020
|
-
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot +
|
|
122628
|
+
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot + path148.sep);
|
|
122021
122629
|
if (isSubdirectory) {
|
|
122022
122630
|
return {
|
|
122023
122631
|
success: false,
|
|
@@ -122033,11 +122641,11 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
122033
122641
|
let specMtime;
|
|
122034
122642
|
let specHash;
|
|
122035
122643
|
if (process.env.SWARM_SKIP_SPEC_GATE !== "1") {
|
|
122036
|
-
const specPath =
|
|
122644
|
+
const specPath = path148.join(targetWorkspace, ".swarm", "spec.md");
|
|
122037
122645
|
try {
|
|
122038
|
-
const stat9 = await
|
|
122646
|
+
const stat9 = await fs108.promises.stat(specPath);
|
|
122039
122647
|
specMtime = stat9.mtime.toISOString();
|
|
122040
|
-
const content = await
|
|
122648
|
+
const content = await fs108.promises.readFile(specPath, "utf8");
|
|
122041
122649
|
specHash = crypto12.createHash("sha256").update(content).digest("hex");
|
|
122042
122650
|
} catch {
|
|
122043
122651
|
return {
|
|
@@ -122049,10 +122657,10 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
122049
122657
|
}
|
|
122050
122658
|
}
|
|
122051
122659
|
if (process.env.SWARM_SKIP_GATE_SELECTION !== "1") {
|
|
122052
|
-
const contextPath =
|
|
122660
|
+
const contextPath = path148.join(targetWorkspace, ".swarm", "context.md");
|
|
122053
122661
|
let contextContent = "";
|
|
122054
122662
|
try {
|
|
122055
|
-
contextContent = await
|
|
122663
|
+
contextContent = await fs108.promises.readFile(contextPath, "utf8");
|
|
122056
122664
|
} catch {}
|
|
122057
122665
|
const hasPendingSection = contextContent.includes("## Pending QA Gate Selection");
|
|
122058
122666
|
if (!hasPendingSection) {
|
|
@@ -122339,14 +122947,14 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
122339
122947
|
}
|
|
122340
122948
|
await writeCheckpoint(dir).catch(() => {});
|
|
122341
122949
|
try {
|
|
122342
|
-
const markerPath =
|
|
122950
|
+
const markerPath = path148.join(dir, ".swarm", ".plan-write-marker");
|
|
122343
122951
|
const marker = JSON.stringify({
|
|
122344
122952
|
source: "save_plan",
|
|
122345
122953
|
timestamp: new Date().toISOString(),
|
|
122346
122954
|
phases_count: plan.phases.length,
|
|
122347
122955
|
tasks_count: tasksCount
|
|
122348
122956
|
});
|
|
122349
|
-
await
|
|
122957
|
+
await fs108.promises.writeFile(markerPath, marker, "utf8");
|
|
122350
122958
|
} catch {}
|
|
122351
122959
|
const warnings = [];
|
|
122352
122960
|
let criticReviewFound = false;
|
|
@@ -122362,7 +122970,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
122362
122970
|
return {
|
|
122363
122971
|
success: true,
|
|
122364
122972
|
message: "Plan saved successfully",
|
|
122365
|
-
plan_path:
|
|
122973
|
+
plan_path: path148.join(dir, ".swarm", "plan.json"),
|
|
122366
122974
|
phases_count: plan.phases.length,
|
|
122367
122975
|
tasks_count: tasksCount,
|
|
122368
122976
|
...resolvedProfile !== undefined ? { execution_profile: resolvedProfile } : {},
|
|
@@ -122428,8 +123036,8 @@ var save_plan = createSwarmTool({
|
|
|
122428
123036
|
// src/tools/sbom-generate.ts
|
|
122429
123037
|
init_zod();
|
|
122430
123038
|
init_manager2();
|
|
122431
|
-
import * as
|
|
122432
|
-
import * as
|
|
123039
|
+
import * as fs109 from "node:fs";
|
|
123040
|
+
import * as path149 from "node:path";
|
|
122433
123041
|
|
|
122434
123042
|
// src/sbom/detectors/index.ts
|
|
122435
123043
|
init_utils();
|
|
@@ -123277,9 +123885,9 @@ function findManifestFiles(rootDir) {
|
|
|
123277
123885
|
const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
|
|
123278
123886
|
function searchDir(dir) {
|
|
123279
123887
|
try {
|
|
123280
|
-
const entries =
|
|
123888
|
+
const entries = fs109.readdirSync(dir, { withFileTypes: true });
|
|
123281
123889
|
for (const entry of entries) {
|
|
123282
|
-
const fullPath =
|
|
123890
|
+
const fullPath = path149.join(dir, entry.name);
|
|
123283
123891
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
|
|
123284
123892
|
continue;
|
|
123285
123893
|
}
|
|
@@ -123288,7 +123896,7 @@ function findManifestFiles(rootDir) {
|
|
|
123288
123896
|
} else if (entry.isFile()) {
|
|
123289
123897
|
for (const pattern of patterns) {
|
|
123290
123898
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
123291
|
-
manifestFiles.push(
|
|
123899
|
+
manifestFiles.push(path149.relative(rootDir, fullPath));
|
|
123292
123900
|
break;
|
|
123293
123901
|
}
|
|
123294
123902
|
}
|
|
@@ -123304,13 +123912,13 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
123304
123912
|
const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
|
|
123305
123913
|
for (const dir of directories) {
|
|
123306
123914
|
try {
|
|
123307
|
-
const entries =
|
|
123915
|
+
const entries = fs109.readdirSync(dir, { withFileTypes: true });
|
|
123308
123916
|
for (const entry of entries) {
|
|
123309
|
-
const fullPath =
|
|
123917
|
+
const fullPath = path149.join(dir, entry.name);
|
|
123310
123918
|
if (entry.isFile()) {
|
|
123311
123919
|
for (const pattern of patterns) {
|
|
123312
123920
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
123313
|
-
found.push(
|
|
123921
|
+
found.push(path149.relative(workingDir, fullPath));
|
|
123314
123922
|
break;
|
|
123315
123923
|
}
|
|
123316
123924
|
}
|
|
@@ -123323,11 +123931,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
123323
123931
|
function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
123324
123932
|
const dirs = new Set;
|
|
123325
123933
|
for (const file3 of changedFiles) {
|
|
123326
|
-
let currentDir =
|
|
123934
|
+
let currentDir = path149.dirname(file3);
|
|
123327
123935
|
while (true) {
|
|
123328
|
-
if (currentDir && currentDir !== "." && currentDir !==
|
|
123329
|
-
dirs.add(
|
|
123330
|
-
const parent =
|
|
123936
|
+
if (currentDir && currentDir !== "." && currentDir !== path149.sep) {
|
|
123937
|
+
dirs.add(path149.join(workingDir, currentDir));
|
|
123938
|
+
const parent = path149.dirname(currentDir);
|
|
123331
123939
|
if (parent === currentDir)
|
|
123332
123940
|
break;
|
|
123333
123941
|
currentDir = parent;
|
|
@@ -123341,7 +123949,7 @@ function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
|
123341
123949
|
}
|
|
123342
123950
|
function ensureOutputDir(outputDir) {
|
|
123343
123951
|
try {
|
|
123344
|
-
|
|
123952
|
+
fs109.mkdirSync(outputDir, { recursive: true });
|
|
123345
123953
|
} catch (error93) {
|
|
123346
123954
|
if (!error93 || error93.code !== "EEXIST") {
|
|
123347
123955
|
throw error93;
|
|
@@ -123411,7 +124019,7 @@ var sbom_generate = createSwarmTool({
|
|
|
123411
124019
|
const changedFiles = obj.changed_files;
|
|
123412
124020
|
const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
|
|
123413
124021
|
const workingDir = directory;
|
|
123414
|
-
const outputDir =
|
|
124022
|
+
const outputDir = path149.isAbsolute(relativeOutputDir) ? relativeOutputDir : path149.join(workingDir, relativeOutputDir);
|
|
123415
124023
|
let manifestFiles = [];
|
|
123416
124024
|
if (scope === "all") {
|
|
123417
124025
|
manifestFiles = findManifestFiles(workingDir);
|
|
@@ -123434,11 +124042,11 @@ var sbom_generate = createSwarmTool({
|
|
|
123434
124042
|
const processedFiles = [];
|
|
123435
124043
|
for (const manifestFile of manifestFiles) {
|
|
123436
124044
|
try {
|
|
123437
|
-
const fullPath =
|
|
123438
|
-
if (!
|
|
124045
|
+
const fullPath = path149.isAbsolute(manifestFile) ? manifestFile : path149.join(workingDir, manifestFile);
|
|
124046
|
+
if (!fs109.existsSync(fullPath)) {
|
|
123439
124047
|
continue;
|
|
123440
124048
|
}
|
|
123441
|
-
const content =
|
|
124049
|
+
const content = fs109.readFileSync(fullPath, "utf-8");
|
|
123442
124050
|
const components = detectComponents(manifestFile, content);
|
|
123443
124051
|
processedFiles.push(manifestFile);
|
|
123444
124052
|
if (components.length > 0) {
|
|
@@ -123451,8 +124059,8 @@ var sbom_generate = createSwarmTool({
|
|
|
123451
124059
|
const bom = generateCycloneDX(allComponents);
|
|
123452
124060
|
const bomJson = serializeCycloneDX(bom);
|
|
123453
124061
|
const filename = generateSbomFilename();
|
|
123454
|
-
const outputPath =
|
|
123455
|
-
|
|
124062
|
+
const outputPath = path149.join(outputDir, filename);
|
|
124063
|
+
fs109.writeFileSync(outputPath, bomJson, "utf-8");
|
|
123456
124064
|
const verdict = processedFiles.length > 0 ? "pass" : "pass";
|
|
123457
124065
|
try {
|
|
123458
124066
|
const timestamp = new Date().toISOString();
|
|
@@ -123495,8 +124103,8 @@ var sbom_generate = createSwarmTool({
|
|
|
123495
124103
|
// src/tools/schema-drift.ts
|
|
123496
124104
|
init_zod();
|
|
123497
124105
|
init_create_tool();
|
|
123498
|
-
import * as
|
|
123499
|
-
import * as
|
|
124106
|
+
import * as fs110 from "node:fs";
|
|
124107
|
+
import * as path150 from "node:path";
|
|
123500
124108
|
var SPEC_CANDIDATES = [
|
|
123501
124109
|
"openapi.json",
|
|
123502
124110
|
"openapi.yaml",
|
|
@@ -123528,28 +124136,28 @@ function normalizePath5(p) {
|
|
|
123528
124136
|
}
|
|
123529
124137
|
function discoverSpecFile(cwd, specFileArg) {
|
|
123530
124138
|
if (specFileArg) {
|
|
123531
|
-
const resolvedPath =
|
|
123532
|
-
const normalizedCwd = cwd.endsWith(
|
|
124139
|
+
const resolvedPath = path150.resolve(cwd, specFileArg);
|
|
124140
|
+
const normalizedCwd = cwd.endsWith(path150.sep) ? cwd : cwd + path150.sep;
|
|
123533
124141
|
if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
|
|
123534
124142
|
throw new Error("Invalid spec_file: path traversal detected");
|
|
123535
124143
|
}
|
|
123536
|
-
const ext =
|
|
124144
|
+
const ext = path150.extname(resolvedPath).toLowerCase();
|
|
123537
124145
|
if (!ALLOWED_EXTENSIONS.includes(ext)) {
|
|
123538
124146
|
throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
|
|
123539
124147
|
}
|
|
123540
|
-
const stats =
|
|
124148
|
+
const stats = fs110.statSync(resolvedPath);
|
|
123541
124149
|
if (stats.size > MAX_SPEC_SIZE) {
|
|
123542
124150
|
throw new Error(`Invalid spec_file: file exceeds ${MAX_SPEC_SIZE / 1024 / 1024}MB limit`);
|
|
123543
124151
|
}
|
|
123544
|
-
if (!
|
|
124152
|
+
if (!fs110.existsSync(resolvedPath)) {
|
|
123545
124153
|
throw new Error(`Spec file not found: ${resolvedPath}`);
|
|
123546
124154
|
}
|
|
123547
124155
|
return resolvedPath;
|
|
123548
124156
|
}
|
|
123549
124157
|
for (const candidate of SPEC_CANDIDATES) {
|
|
123550
|
-
const candidatePath =
|
|
123551
|
-
if (
|
|
123552
|
-
const stats =
|
|
124158
|
+
const candidatePath = path150.resolve(cwd, candidate);
|
|
124159
|
+
if (fs110.existsSync(candidatePath)) {
|
|
124160
|
+
const stats = fs110.statSync(candidatePath);
|
|
123553
124161
|
if (stats.size <= MAX_SPEC_SIZE) {
|
|
123554
124162
|
return candidatePath;
|
|
123555
124163
|
}
|
|
@@ -123558,8 +124166,8 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
123558
124166
|
return null;
|
|
123559
124167
|
}
|
|
123560
124168
|
function parseSpec(specFile) {
|
|
123561
|
-
const content =
|
|
123562
|
-
const ext =
|
|
124169
|
+
const content = fs110.readFileSync(specFile, "utf-8");
|
|
124170
|
+
const ext = path150.extname(specFile).toLowerCase();
|
|
123563
124171
|
if (ext === ".json") {
|
|
123564
124172
|
return parseJsonSpec(content);
|
|
123565
124173
|
}
|
|
@@ -123627,15 +124235,15 @@ function parseYamlSpec(content) {
|
|
|
123627
124235
|
}
|
|
123628
124236
|
function extractRoutes(cwd) {
|
|
123629
124237
|
const routes = [];
|
|
123630
|
-
function
|
|
124238
|
+
function walkDir2(dir) {
|
|
123631
124239
|
let entries;
|
|
123632
124240
|
try {
|
|
123633
|
-
entries =
|
|
124241
|
+
entries = fs110.readdirSync(dir, { withFileTypes: true });
|
|
123634
124242
|
} catch {
|
|
123635
124243
|
return;
|
|
123636
124244
|
}
|
|
123637
124245
|
for (const entry of entries) {
|
|
123638
|
-
const fullPath =
|
|
124246
|
+
const fullPath = path150.join(dir, entry.name);
|
|
123639
124247
|
if (entry.isSymbolicLink()) {
|
|
123640
124248
|
continue;
|
|
123641
124249
|
}
|
|
@@ -123643,9 +124251,9 @@ function extractRoutes(cwd) {
|
|
|
123643
124251
|
if (SKIP_DIRS.includes(entry.name)) {
|
|
123644
124252
|
continue;
|
|
123645
124253
|
}
|
|
123646
|
-
|
|
124254
|
+
walkDir2(fullPath);
|
|
123647
124255
|
} else if (entry.isFile()) {
|
|
123648
|
-
const ext =
|
|
124256
|
+
const ext = path150.extname(entry.name).toLowerCase();
|
|
123649
124257
|
const baseName = entry.name.toLowerCase();
|
|
123650
124258
|
if (![".ts", ".js", ".mjs"].includes(ext)) {
|
|
123651
124259
|
continue;
|
|
@@ -123658,12 +124266,12 @@ function extractRoutes(cwd) {
|
|
|
123658
124266
|
}
|
|
123659
124267
|
}
|
|
123660
124268
|
}
|
|
123661
|
-
|
|
124269
|
+
walkDir2(cwd);
|
|
123662
124270
|
return routes;
|
|
123663
124271
|
}
|
|
123664
124272
|
function extractRoutesFromFile(filePath) {
|
|
123665
124273
|
const routes = [];
|
|
123666
|
-
const content =
|
|
124274
|
+
const content = fs110.readFileSync(filePath, "utf-8");
|
|
123667
124275
|
const lines = content.split(/\r?\n/);
|
|
123668
124276
|
const expressRegex = /(?:app|router|server|express)\.(get|post|put|patch|delete|options|head)\s*\(\s*['"`]([^'"`]+)['"`]/g;
|
|
123669
124277
|
const flaskRegex = /@(?:app|blueprint|bp)\.route\s*\(\s*['"]([^'"]+)['"]/g;
|
|
@@ -123813,8 +124421,8 @@ init_zod();
|
|
|
123813
124421
|
init_bun_compat();
|
|
123814
124422
|
init_path_security();
|
|
123815
124423
|
init_create_tool();
|
|
123816
|
-
import * as
|
|
123817
|
-
import * as
|
|
124424
|
+
import * as fs111 from "node:fs";
|
|
124425
|
+
import * as path151 from "node:path";
|
|
123818
124426
|
var DEFAULT_MAX_RESULTS = 100;
|
|
123819
124427
|
var DEFAULT_MAX_LINES = 200;
|
|
123820
124428
|
var REGEX_TIMEOUT_MS = 5000;
|
|
@@ -123850,11 +124458,11 @@ function containsWindowsAttacks4(str) {
|
|
|
123850
124458
|
}
|
|
123851
124459
|
function isPathInWorkspace3(filePath, workspace) {
|
|
123852
124460
|
try {
|
|
123853
|
-
const resolvedPath =
|
|
123854
|
-
const realWorkspace =
|
|
123855
|
-
const realResolvedPath =
|
|
123856
|
-
const relativePath =
|
|
123857
|
-
if (relativePath.startsWith("..") ||
|
|
124461
|
+
const resolvedPath = path151.resolve(workspace, filePath);
|
|
124462
|
+
const realWorkspace = fs111.realpathSync(workspace);
|
|
124463
|
+
const realResolvedPath = fs111.realpathSync(resolvedPath);
|
|
124464
|
+
const relativePath = path151.relative(realWorkspace, realResolvedPath);
|
|
124465
|
+
if (relativePath.startsWith("..") || path151.isAbsolute(relativePath)) {
|
|
123858
124466
|
return false;
|
|
123859
124467
|
}
|
|
123860
124468
|
return true;
|
|
@@ -123867,12 +124475,12 @@ function validatePathForRead2(filePath, workspace) {
|
|
|
123867
124475
|
}
|
|
123868
124476
|
function findRgInEnvPath() {
|
|
123869
124477
|
const searchPath = process.env.PATH ?? "";
|
|
123870
|
-
for (const dir of searchPath.split(
|
|
124478
|
+
for (const dir of searchPath.split(path151.delimiter)) {
|
|
123871
124479
|
if (!dir)
|
|
123872
124480
|
continue;
|
|
123873
124481
|
const isWindows = process.platform === "win32";
|
|
123874
|
-
const candidate =
|
|
123875
|
-
if (
|
|
124482
|
+
const candidate = path151.join(dir, isWindows ? "rg.exe" : "rg");
|
|
124483
|
+
if (fs111.existsSync(candidate))
|
|
123876
124484
|
return candidate;
|
|
123877
124485
|
}
|
|
123878
124486
|
return null;
|
|
@@ -123926,7 +124534,7 @@ async function ripgrepSearch(opts) {
|
|
|
123926
124534
|
stderr: "pipe",
|
|
123927
124535
|
cwd: opts.workspace
|
|
123928
124536
|
});
|
|
123929
|
-
const timeout = new Promise((
|
|
124537
|
+
const timeout = new Promise((resolve57) => setTimeout(() => resolve57("timeout"), REGEX_TIMEOUT_MS));
|
|
123930
124538
|
const exitPromise = proc.exited;
|
|
123931
124539
|
const result = await Promise.race([exitPromise, timeout]);
|
|
123932
124540
|
if (result === "timeout") {
|
|
@@ -123999,10 +124607,10 @@ function collectFiles(dir, workspace, includeGlobs, excludeGlobs) {
|
|
|
123999
124607
|
return files;
|
|
124000
124608
|
}
|
|
124001
124609
|
try {
|
|
124002
|
-
const entries =
|
|
124610
|
+
const entries = fs111.readdirSync(dir, { withFileTypes: true });
|
|
124003
124611
|
for (const entry of entries) {
|
|
124004
|
-
const fullPath =
|
|
124005
|
-
const relativePath =
|
|
124612
|
+
const fullPath = path151.join(dir, entry.name);
|
|
124613
|
+
const relativePath = path151.relative(workspace, fullPath);
|
|
124006
124614
|
if (!validatePathForRead2(fullPath, workspace)) {
|
|
124007
124615
|
continue;
|
|
124008
124616
|
}
|
|
@@ -124043,13 +124651,13 @@ async function fallbackSearch(opts) {
|
|
|
124043
124651
|
const matches = [];
|
|
124044
124652
|
let total = 0;
|
|
124045
124653
|
for (const file3 of files) {
|
|
124046
|
-
const fullPath =
|
|
124654
|
+
const fullPath = path151.join(opts.workspace, file3);
|
|
124047
124655
|
if (!validatePathForRead2(fullPath, opts.workspace)) {
|
|
124048
124656
|
continue;
|
|
124049
124657
|
}
|
|
124050
124658
|
let stats;
|
|
124051
124659
|
try {
|
|
124052
|
-
stats =
|
|
124660
|
+
stats = fs111.statSync(fullPath);
|
|
124053
124661
|
if (stats.size > MAX_FILE_SIZE_BYTES10) {
|
|
124054
124662
|
continue;
|
|
124055
124663
|
}
|
|
@@ -124058,7 +124666,7 @@ async function fallbackSearch(opts) {
|
|
|
124058
124666
|
}
|
|
124059
124667
|
let content;
|
|
124060
124668
|
try {
|
|
124061
|
-
content =
|
|
124669
|
+
content = fs111.readFileSync(fullPath, "utf-8");
|
|
124062
124670
|
} catch {
|
|
124063
124671
|
continue;
|
|
124064
124672
|
}
|
|
@@ -124170,7 +124778,7 @@ var search = createSwarmTool({
|
|
|
124170
124778
|
message: "Exclude pattern contains invalid Windows-specific sequence"
|
|
124171
124779
|
}, null, 2);
|
|
124172
124780
|
}
|
|
124173
|
-
if (!
|
|
124781
|
+
if (!fs111.existsSync(directory)) {
|
|
124174
124782
|
return JSON.stringify({
|
|
124175
124783
|
error: true,
|
|
124176
124784
|
type: "unknown",
|
|
@@ -124456,7 +125064,7 @@ init_config();
|
|
|
124456
125064
|
init_schema();
|
|
124457
125065
|
init_create_tool();
|
|
124458
125066
|
import { mkdir as mkdir24, rename as rename10, writeFile as writeFile19 } from "node:fs/promises";
|
|
124459
|
-
import * as
|
|
125067
|
+
import * as path152 from "node:path";
|
|
124460
125068
|
var MAX_SPEC_BYTES = 256 * 1024;
|
|
124461
125069
|
var spec_write = createSwarmTool({
|
|
124462
125070
|
description: "Write the canonical project spec to .swarm/spec.md. Atomic write, size-bounded (256 KiB), heading-required. Honors spec_writer.allow_spec_write.",
|
|
@@ -124497,14 +125105,14 @@ var spec_write = createSwarmTool({
|
|
|
124497
125105
|
reason: 'spec must contain at least one top-level "# Heading"'
|
|
124498
125106
|
}, null, 2);
|
|
124499
125107
|
}
|
|
124500
|
-
const target =
|
|
124501
|
-
await mkdir24(
|
|
125108
|
+
const target = path152.join(directory, ".swarm", "spec.md");
|
|
125109
|
+
await mkdir24(path152.dirname(target), { recursive: true });
|
|
124502
125110
|
const tmp = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
124503
125111
|
let finalContent = content;
|
|
124504
125112
|
if (mode === "append") {
|
|
124505
125113
|
try {
|
|
124506
|
-
const
|
|
124507
|
-
const prior = await
|
|
125114
|
+
const fs112 = await import("node:fs/promises");
|
|
125115
|
+
const prior = await fs112.readFile(target, "utf-8");
|
|
124508
125116
|
finalContent = `${prior.replace(/\s+$/, "")}
|
|
124509
125117
|
|
|
124510
125118
|
${content}
|
|
@@ -124527,14 +125135,14 @@ ${content}
|
|
|
124527
125135
|
init_zod();
|
|
124528
125136
|
init_loader();
|
|
124529
125137
|
import {
|
|
124530
|
-
existsSync as
|
|
125138
|
+
existsSync as existsSync86,
|
|
124531
125139
|
mkdirSync as mkdirSync36,
|
|
124532
125140
|
readFileSync as readFileSync72,
|
|
124533
125141
|
renameSync as renameSync22,
|
|
124534
125142
|
unlinkSync as unlinkSync20,
|
|
124535
125143
|
writeFileSync as writeFileSync30
|
|
124536
125144
|
} from "node:fs";
|
|
124537
|
-
import
|
|
125145
|
+
import path153 from "node:path";
|
|
124538
125146
|
init_create_tool();
|
|
124539
125147
|
init_resolve_working_directory();
|
|
124540
125148
|
var VerdictSchema2 = exports_external.object({
|
|
@@ -124664,7 +125272,7 @@ var submit_phase_council_verdicts = createSwarmTool({
|
|
|
124664
125272
|
}
|
|
124665
125273
|
});
|
|
124666
125274
|
function getPhaseMutationGapFinding(phaseNumber, workingDir) {
|
|
124667
|
-
const mutationGatePath =
|
|
125275
|
+
const mutationGatePath = path153.join(workingDir, ".swarm", "evidence", String(phaseNumber), "mutation-gate.json");
|
|
124668
125276
|
try {
|
|
124669
125277
|
const raw = readFileSync72(mutationGatePath, "utf-8");
|
|
124670
125278
|
const parsed = JSON.parse(raw);
|
|
@@ -124726,9 +125334,9 @@ function getPhaseMutationGapFinding(phaseNumber, workingDir) {
|
|
|
124726
125334
|
}
|
|
124727
125335
|
}
|
|
124728
125336
|
function writePhaseCouncilEvidence(workingDir, synthesis) {
|
|
124729
|
-
const evidenceDir =
|
|
125337
|
+
const evidenceDir = path153.join(workingDir, ".swarm", "evidence", String(synthesis.phaseNumber));
|
|
124730
125338
|
mkdirSync36(evidenceDir, { recursive: true });
|
|
124731
|
-
const evidenceFile =
|
|
125339
|
+
const evidenceFile = path153.join(evidenceDir, "phase-council.json");
|
|
124732
125340
|
const evidenceBundle = {
|
|
124733
125341
|
entries: [
|
|
124734
125342
|
{
|
|
@@ -124764,7 +125372,7 @@ function writePhaseCouncilEvidence(workingDir, synthesis) {
|
|
|
124764
125372
|
writeFileSync30(tempFile, JSON.stringify(evidenceBundle, null, 2), "utf-8");
|
|
124765
125373
|
renameSync22(tempFile, evidenceFile);
|
|
124766
125374
|
} finally {
|
|
124767
|
-
if (
|
|
125375
|
+
if (existsSync86(tempFile)) {
|
|
124768
125376
|
unlinkSync20(tempFile);
|
|
124769
125377
|
}
|
|
124770
125378
|
}
|
|
@@ -124789,8 +125397,30 @@ function formatMutationGapFeedback(finding) {
|
|
|
124789
125397
|
init_zod();
|
|
124790
125398
|
init_path_security();
|
|
124791
125399
|
init_create_tool();
|
|
124792
|
-
import * as
|
|
124793
|
-
import * as
|
|
125400
|
+
import * as fs112 from "node:fs";
|
|
125401
|
+
import * as path154 from "node:path";
|
|
125402
|
+
var BINARY_EXTENSIONS2 = new Set([
|
|
125403
|
+
".png",
|
|
125404
|
+
".jpg",
|
|
125405
|
+
".jpeg",
|
|
125406
|
+
".gif",
|
|
125407
|
+
".bmp",
|
|
125408
|
+
".ico",
|
|
125409
|
+
".svg",
|
|
125410
|
+
".woff",
|
|
125411
|
+
".woff2",
|
|
125412
|
+
".ttf",
|
|
125413
|
+
".eot",
|
|
125414
|
+
".mp3",
|
|
125415
|
+
".mp4",
|
|
125416
|
+
".avi",
|
|
125417
|
+
".mov",
|
|
125418
|
+
".pdf",
|
|
125419
|
+
".zip",
|
|
125420
|
+
".tar",
|
|
125421
|
+
".gz",
|
|
125422
|
+
".rar"
|
|
125423
|
+
]);
|
|
124794
125424
|
var WINDOWS_RESERVED_NAMES5 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
124795
125425
|
function containsWindowsAttacks5(str) {
|
|
124796
125426
|
if (/:[^\\/]/.test(str))
|
|
@@ -124804,14 +125434,14 @@ function containsWindowsAttacks5(str) {
|
|
|
124804
125434
|
}
|
|
124805
125435
|
function isPathInWorkspace4(filePath, workspace) {
|
|
124806
125436
|
try {
|
|
124807
|
-
const resolvedPath =
|
|
124808
|
-
if (!
|
|
125437
|
+
const resolvedPath = path154.resolve(workspace, filePath);
|
|
125438
|
+
if (!fs112.existsSync(resolvedPath)) {
|
|
124809
125439
|
return true;
|
|
124810
125440
|
}
|
|
124811
|
-
const realWorkspace =
|
|
124812
|
-
const realResolvedPath =
|
|
124813
|
-
const relativePath =
|
|
124814
|
-
if (relativePath.startsWith("..") ||
|
|
125441
|
+
const realWorkspace = fs112.realpathSync(workspace);
|
|
125442
|
+
const realResolvedPath = fs112.realpathSync(resolvedPath);
|
|
125443
|
+
const relativePath = path154.relative(realWorkspace, realResolvedPath);
|
|
125444
|
+
if (relativePath.startsWith("..") || path154.isAbsolute(relativePath)) {
|
|
124815
125445
|
return false;
|
|
124816
125446
|
}
|
|
124817
125447
|
return true;
|
|
@@ -124819,7 +125449,7 @@ function isPathInWorkspace4(filePath, workspace) {
|
|
|
124819
125449
|
return false;
|
|
124820
125450
|
}
|
|
124821
125451
|
}
|
|
124822
|
-
function
|
|
125452
|
+
function validateFilePath2(filePath, workspace) {
|
|
124823
125453
|
if (!filePath || filePath.trim() === "")
|
|
124824
125454
|
return false;
|
|
124825
125455
|
if (containsPathTraversal(filePath))
|
|
@@ -124831,8 +125461,7 @@ function validateFilePath(filePath, workspace) {
|
|
|
124831
125461
|
return isPathInWorkspace4(filePath, workspace);
|
|
124832
125462
|
}
|
|
124833
125463
|
function findContextMatch(content, contextBefore, contextAfter, oldContent) {
|
|
124834
|
-
const lines = content
|
|
124835
|
-
`);
|
|
125464
|
+
const lines = splitDiffLines(content);
|
|
124836
125465
|
if ((!contextBefore || contextBefore.length === 0) && (!contextAfter || contextAfter.length === 0)) {
|
|
124837
125466
|
return null;
|
|
124838
125467
|
}
|
|
@@ -124854,8 +125483,7 @@ function findContextMatch(content, contextBefore, contextAfter, oldContent) {
|
|
|
124854
125483
|
};
|
|
124855
125484
|
} else {
|
|
124856
125485
|
if (oldContent && oldContent.length > 0) {
|
|
124857
|
-
const oldContentLines = oldContent
|
|
124858
|
-
`);
|
|
125486
|
+
const oldContentLines = splitDiffLines(oldContent);
|
|
124859
125487
|
const betweenLines = lines.slice(afterStart, j);
|
|
124860
125488
|
if (arraysEqual2(betweenLines, oldContentLines)) {
|
|
124861
125489
|
return {
|
|
@@ -124879,8 +125507,7 @@ function findContextMatch(content, contextBefore, contextAfter, oldContent) {
|
|
|
124879
125507
|
return null;
|
|
124880
125508
|
} else {
|
|
124881
125509
|
if (oldContent && oldContent.length > 0) {
|
|
124882
|
-
const oldContentLines = oldContent
|
|
124883
|
-
`);
|
|
125510
|
+
const oldContentLines = splitDiffLines(oldContent);
|
|
124884
125511
|
for (let k = afterStart;k <= lines.length - oldContentLines.length; k++) {
|
|
124885
125512
|
const candidate = lines.slice(k, k + oldContentLines.length);
|
|
124886
125513
|
if (arraysEqual2(candidate, oldContentLines)) {
|
|
@@ -124928,23 +125555,117 @@ function arraysEqual2(a, b) {
|
|
|
124928
125555
|
}
|
|
124929
125556
|
return true;
|
|
124930
125557
|
}
|
|
124931
|
-
function
|
|
125558
|
+
function isBinaryFile4(filePath) {
|
|
125559
|
+
const ext = path154.extname(filePath).toLowerCase();
|
|
125560
|
+
return BINARY_EXTENSIONS2.has(ext);
|
|
125561
|
+
}
|
|
125562
|
+
function splitDiffLines(content) {
|
|
125563
|
+
if (content === "")
|
|
125564
|
+
return [];
|
|
125565
|
+
return content.endsWith(`
|
|
125566
|
+
`) ? content.slice(0, -1).split(`
|
|
125567
|
+
`) : content.split(`
|
|
125568
|
+
`);
|
|
125569
|
+
}
|
|
125570
|
+
function generateFileHeader(file3) {
|
|
125571
|
+
return `diff --git a/${file3} b/${file3}
|
|
125572
|
+
` + `--- a/${file3}
|
|
125573
|
+
` + `+++ b/${file3}
|
|
125574
|
+
`;
|
|
125575
|
+
}
|
|
125576
|
+
function generateHunk(content, contextMatch, oldContent, newContent) {
|
|
125577
|
+
const lines = splitDiffLines(content);
|
|
125578
|
+
const originalEndsWithNewline = content.endsWith(`
|
|
125579
|
+
`);
|
|
125580
|
+
const newContentEndsWithNewline = newContent.endsWith(`
|
|
125581
|
+
`);
|
|
125582
|
+
const removalStartIdx = contextMatch.startLineIndex + contextMatch.matchedBefore.length;
|
|
125583
|
+
const removalLines = oldContent ? splitDiffLines(oldContent) : [];
|
|
125584
|
+
const removalEndIdx = removalLines.length > 0 ? removalStartIdx + removalLines.length - 1 : removalStartIdx - 1;
|
|
125585
|
+
const additionLines = splitDiffLines(newContent);
|
|
125586
|
+
const isAdjacentCase = contextMatch.matchedAfter.length > 0 && contextMatch.endLineIndex >= 0 && contextMatch.endLineIndex < lines.length && lines[contextMatch.endLineIndex] === contextMatch.matchedAfter[contextMatch.matchedAfter.length - 1];
|
|
125587
|
+
const contextAfterStartInFile = isAdjacentCase ? contextMatch.endLineIndex - contextMatch.matchedAfter.length + 1 : contextMatch.endLineIndex + 1;
|
|
125588
|
+
const overlapSkipCount = Math.max(0, removalLines.length > 0 ? removalEndIdx + 1 - contextAfterStartInFile : 0);
|
|
125589
|
+
const effectiveContextAfterCount = Math.max(0, contextMatch.matchedAfter.length - overlapSkipCount);
|
|
125590
|
+
const oldStart = contextMatch.matchedBefore.length > 0 ? contextMatch.startLineIndex + 1 : removalStartIdx + 1;
|
|
125591
|
+
const newStart = oldStart;
|
|
125592
|
+
const oldCount = contextMatch.matchedBefore.length + removalLines.length + effectiveContextAfterCount;
|
|
125593
|
+
const newCount = contextMatch.matchedBefore.length + additionLines.length + effectiveContextAfterCount;
|
|
125594
|
+
const hunkLines = [];
|
|
125595
|
+
let lastOldSidePos = -1;
|
|
125596
|
+
let lastNewSidePos = -1;
|
|
125597
|
+
for (const line of contextMatch.matchedBefore) {
|
|
125598
|
+
const idx = hunkLines.length;
|
|
125599
|
+
hunkLines.push(` ${line}`);
|
|
125600
|
+
lastOldSidePos = idx;
|
|
125601
|
+
lastNewSidePos = idx;
|
|
125602
|
+
}
|
|
125603
|
+
for (const line of removalLines) {
|
|
125604
|
+
const idx = hunkLines.length;
|
|
125605
|
+
hunkLines.push(`-${line}`);
|
|
125606
|
+
lastOldSidePos = idx;
|
|
125607
|
+
}
|
|
125608
|
+
for (const line of additionLines) {
|
|
125609
|
+
const idx = hunkLines.length;
|
|
125610
|
+
hunkLines.push(`+${line}`);
|
|
125611
|
+
lastNewSidePos = idx;
|
|
125612
|
+
}
|
|
125613
|
+
for (let k = overlapSkipCount;k < contextMatch.matchedAfter.length; k++) {
|
|
125614
|
+
const idx = hunkLines.length;
|
|
125615
|
+
hunkLines.push(` ${contextMatch.matchedAfter[k]}`);
|
|
125616
|
+
lastOldSidePos = idx;
|
|
125617
|
+
lastNewSidePos = idx;
|
|
125618
|
+
}
|
|
125619
|
+
const lastOldSideFileIdx = effectiveContextAfterCount > 0 ? contextAfterStartInFile + contextMatch.matchedAfter.length - 1 : removalLines.length > 0 ? removalEndIdx : contextMatch.matchedBefore.length > 0 ? contextMatch.startLineIndex + contextMatch.matchedBefore.length - 1 : -1;
|
|
125620
|
+
const isAtEof = lastOldSideFileIdx === lines.length - 1;
|
|
125621
|
+
const needsOldMarker = isAtEof && !originalEndsWithNewline && lastOldSidePos >= 0;
|
|
125622
|
+
const newSideEndsWithNewline = effectiveContextAfterCount > 0 ? originalEndsWithNewline : additionLines.length > 0 ? newContentEndsWithNewline : true;
|
|
125623
|
+
const needsNewMarker = isAtEof && !newSideEndsWithNewline && lastNewSidePos >= 0;
|
|
125624
|
+
const finalLines = [];
|
|
125625
|
+
let pendingOldMarker = needsOldMarker;
|
|
125626
|
+
let pendingNewMarker = needsNewMarker;
|
|
125627
|
+
for (let i2 = 0;i2 < hunkLines.length; i2++) {
|
|
125628
|
+
finalLines.push(hunkLines[i2]);
|
|
125629
|
+
if (pendingOldMarker && i2 === lastOldSidePos) {
|
|
125630
|
+
finalLines.push("\");
|
|
125631
|
+
pendingOldMarker = false;
|
|
125632
|
+
}
|
|
125633
|
+
if (pendingNewMarker && i2 === lastNewSidePos) {
|
|
125634
|
+
finalLines.push("\");
|
|
125635
|
+
pendingNewMarker = false;
|
|
125636
|
+
}
|
|
125637
|
+
}
|
|
125638
|
+
const oldCountStr = oldCount === 0 ? "0" : String(oldCount);
|
|
125639
|
+
const newCountStr = newCount === 0 ? "0" : String(newCount);
|
|
125640
|
+
let diff2 = "";
|
|
125641
|
+
diff2 += `@@ -${oldStart},${oldCountStr} +${newStart},${newCountStr} @@
|
|
125642
|
+
`;
|
|
125643
|
+
diff2 += finalLines.join(`
|
|
125644
|
+
`);
|
|
125645
|
+
diff2 += `
|
|
125646
|
+
`;
|
|
125647
|
+
return diff2;
|
|
125648
|
+
}
|
|
125649
|
+
function validateOldContent(lines, contextMatch, oldContent) {
|
|
124932
125650
|
if (!oldContent) {
|
|
124933
125651
|
return { valid: true };
|
|
124934
125652
|
}
|
|
124935
|
-
const
|
|
124936
|
-
|
|
124937
|
-
|
|
125653
|
+
const expectedLines = splitDiffLines(oldContent);
|
|
125654
|
+
const removalStartIdx = contextMatch.startLineIndex + contextMatch.matchedBefore.length;
|
|
125655
|
+
const actualLines = lines.slice(removalStartIdx, removalStartIdx + expectedLines.length);
|
|
125656
|
+
if (!arraysEqual2(actualLines, expectedLines)) {
|
|
124938
125657
|
return {
|
|
124939
125658
|
valid: false,
|
|
124940
|
-
expected:
|
|
124941
|
-
|
|
125659
|
+
expected: expectedLines.join(`
|
|
125660
|
+
`),
|
|
125661
|
+
actual: actualLines.join(`
|
|
125662
|
+
`)
|
|
124942
125663
|
};
|
|
124943
125664
|
}
|
|
124944
125665
|
return { valid: true };
|
|
124945
125666
|
}
|
|
124946
125667
|
var suggestPatch = createSwarmTool({
|
|
124947
|
-
description: "Suggest a structured patch for specified files without modifying them. " + "Returns context-based patch proposals with anchors for reviewer use. " + "This is a read-only tool — it does not modify any files.",
|
|
125668
|
+
description: "Suggest a structured patch for specified files without modifying them. " + "Returns context-based patch proposals with anchors for reviewer use. " + 'When format="unified", also produces a unified diff string consumable by apply_patch. ' + "This is a read-only tool — it does not modify any files.",
|
|
124948
125669
|
args: {
|
|
124949
125670
|
targetFiles: exports_external.array(exports_external.string()).describe("Array of file paths to patch").min(1),
|
|
124950
125671
|
changes: exports_external.array(exports_external.object({
|
|
@@ -124953,7 +125674,8 @@ var suggestPatch = createSwarmTool({
|
|
|
124953
125674
|
contextAfter: exports_external.array(exports_external.string()).optional().describe("Lines after the change region (anchor)"),
|
|
124954
125675
|
oldContent: exports_external.string().optional().describe("Current content to be replaced"),
|
|
124955
125676
|
newContent: exports_external.string().describe("New content to replace with")
|
|
124956
|
-
})).describe("Array of change descriptions with context anchors").min(1)
|
|
125677
|
+
})).describe("Array of change descriptions with context anchors").min(1),
|
|
125678
|
+
format: exports_external.enum(["json", "unified"]).optional().default("json").describe('Output format: "json" (default, existing structured output) or "unified" (unified diff string for apply_patch)')
|
|
124957
125679
|
},
|
|
124958
125680
|
execute: async (args2, directory) => {
|
|
124959
125681
|
if (!args2 || typeof args2 !== "object") {
|
|
@@ -124967,6 +125689,7 @@ var suggestPatch = createSwarmTool({
|
|
|
124967
125689
|
const obj = args2;
|
|
124968
125690
|
const targetFiles = obj.targetFiles ?? [];
|
|
124969
125691
|
const changes = obj.changes ?? [];
|
|
125692
|
+
const format = obj.format ?? "json";
|
|
124970
125693
|
if (!targetFiles || targetFiles.length === 0) {
|
|
124971
125694
|
return JSON.stringify({
|
|
124972
125695
|
success: false,
|
|
@@ -124983,7 +125706,7 @@ var suggestPatch = createSwarmTool({
|
|
|
124983
125706
|
message: "changes cannot be empty"
|
|
124984
125707
|
}, null, 2);
|
|
124985
125708
|
}
|
|
124986
|
-
if (!
|
|
125709
|
+
if (!fs112.existsSync(directory)) {
|
|
124987
125710
|
return JSON.stringify({
|
|
124988
125711
|
success: false,
|
|
124989
125712
|
error: true,
|
|
@@ -124994,9 +125717,28 @@ var suggestPatch = createSwarmTool({
|
|
|
124994
125717
|
const patches = [];
|
|
124995
125718
|
const filesModifiedSet = new Set;
|
|
124996
125719
|
const errors5 = [];
|
|
125720
|
+
const unifiedDiffEntries = [];
|
|
124997
125721
|
const targetFileSet = new Set(targetFiles);
|
|
125722
|
+
const skippedBinaryFiles = new Set;
|
|
125723
|
+
if (format === "unified") {
|
|
125724
|
+
for (const change of changes) {
|
|
125725
|
+
if (isBinaryFile4(change.file)) {
|
|
125726
|
+
errors5.push({
|
|
125727
|
+
success: false,
|
|
125728
|
+
error: true,
|
|
125729
|
+
type: "parse-error",
|
|
125730
|
+
message: `Binary files are not supported in unified diff mode: ${change.file}`,
|
|
125731
|
+
details: { location: change.file }
|
|
125732
|
+
});
|
|
125733
|
+
skippedBinaryFiles.add(change.file);
|
|
125734
|
+
}
|
|
125735
|
+
}
|
|
125736
|
+
}
|
|
124998
125737
|
for (let changeIndex = 0;changeIndex < changes.length; changeIndex++) {
|
|
124999
125738
|
const change = changes[changeIndex];
|
|
125739
|
+
if (format === "unified" && skippedBinaryFiles.has(change.file)) {
|
|
125740
|
+
continue;
|
|
125741
|
+
}
|
|
125000
125742
|
if (!targetFileSet.has(change.file)) {
|
|
125001
125743
|
errors5.push({
|
|
125002
125744
|
success: false,
|
|
@@ -125007,7 +125749,7 @@ var suggestPatch = createSwarmTool({
|
|
|
125007
125749
|
});
|
|
125008
125750
|
continue;
|
|
125009
125751
|
}
|
|
125010
|
-
if (!
|
|
125752
|
+
if (!validateFilePath2(change.file, directory)) {
|
|
125011
125753
|
errors5.push({
|
|
125012
125754
|
success: false,
|
|
125013
125755
|
error: true,
|
|
@@ -125019,8 +125761,8 @@ var suggestPatch = createSwarmTool({
|
|
|
125019
125761
|
});
|
|
125020
125762
|
continue;
|
|
125021
125763
|
}
|
|
125022
|
-
const fullPath =
|
|
125023
|
-
if (!
|
|
125764
|
+
const fullPath = path154.resolve(directory, change.file);
|
|
125765
|
+
if (!fs112.existsSync(fullPath)) {
|
|
125024
125766
|
errors5.push({
|
|
125025
125767
|
success: false,
|
|
125026
125768
|
error: true,
|
|
@@ -125034,7 +125776,7 @@ var suggestPatch = createSwarmTool({
|
|
|
125034
125776
|
}
|
|
125035
125777
|
let content;
|
|
125036
125778
|
try {
|
|
125037
|
-
content =
|
|
125779
|
+
content = fs112.readFileSync(fullPath, "utf-8");
|
|
125038
125780
|
} catch (err3) {
|
|
125039
125781
|
errors5.push({
|
|
125040
125782
|
success: false,
|
|
@@ -125060,9 +125802,8 @@ var suggestPatch = createSwarmTool({
|
|
|
125060
125802
|
});
|
|
125061
125803
|
continue;
|
|
125062
125804
|
}
|
|
125063
|
-
const lines = content
|
|
125064
|
-
|
|
125065
|
-
const oldContentValidation = validateOldContent(lines, contextMatch.startLineIndex + contextMatch.matchedBefore.length, contextMatch.endLineIndex - contextMatch.matchedAfter.length + 1, change.oldContent);
|
|
125805
|
+
const lines = splitDiffLines(content);
|
|
125806
|
+
const oldContentValidation = validateOldContent(lines, contextMatch, change.oldContent);
|
|
125066
125807
|
if (!oldContentValidation.valid) {
|
|
125067
125808
|
errors5.push({
|
|
125068
125809
|
success: false,
|
|
@@ -125089,14 +125830,51 @@ var suggestPatch = createSwarmTool({
|
|
|
125089
125830
|
hunkIndex: changeIndex
|
|
125090
125831
|
});
|
|
125091
125832
|
filesModifiedSet.add(change.file);
|
|
125833
|
+
if (format === "unified") {
|
|
125834
|
+
unifiedDiffEntries.push({
|
|
125835
|
+
file: change.file,
|
|
125836
|
+
contextMatch,
|
|
125837
|
+
oldContent: change.oldContent,
|
|
125838
|
+
newContent: change.newContent
|
|
125839
|
+
});
|
|
125840
|
+
}
|
|
125092
125841
|
}
|
|
125093
125842
|
if (patches.length > 0) {
|
|
125094
|
-
|
|
125843
|
+
const baseResult = {
|
|
125095
125844
|
success: true,
|
|
125096
125845
|
patches,
|
|
125097
125846
|
filesModified: Array.from(filesModifiedSet),
|
|
125098
125847
|
...errors5.length > 0 && { errors: errors5 }
|
|
125099
|
-
}
|
|
125848
|
+
};
|
|
125849
|
+
if (format === "unified") {
|
|
125850
|
+
const fileGroups = new Map;
|
|
125851
|
+
for (const entry of unifiedDiffEntries) {
|
|
125852
|
+
const group = fileGroups.get(entry.file) ?? [];
|
|
125853
|
+
group.push(entry);
|
|
125854
|
+
fileGroups.set(entry.file, group);
|
|
125855
|
+
}
|
|
125856
|
+
const unifiedParts = [];
|
|
125857
|
+
for (const [file3, entries] of fileGroups) {
|
|
125858
|
+
entries.sort((a, b) => a.contextMatch.startLineIndex - b.contextMatch.startLineIndex);
|
|
125859
|
+
const entryFullPath = path154.resolve(directory, file3);
|
|
125860
|
+
let entryContent;
|
|
125861
|
+
try {
|
|
125862
|
+
entryContent = fs112.readFileSync(entryFullPath, "utf-8");
|
|
125863
|
+
} catch {
|
|
125864
|
+
continue;
|
|
125865
|
+
}
|
|
125866
|
+
unifiedParts.push(generateFileHeader(file3));
|
|
125867
|
+
for (const entry of entries) {
|
|
125868
|
+
unifiedParts.push(generateHunk(entryContent, entry.contextMatch, entry.oldContent, entry.newContent));
|
|
125869
|
+
}
|
|
125870
|
+
}
|
|
125871
|
+
const unifiedPatch = unifiedParts.join("");
|
|
125872
|
+
return JSON.stringify({
|
|
125873
|
+
...baseResult,
|
|
125874
|
+
unifiedPatch
|
|
125875
|
+
}, null, 2);
|
|
125876
|
+
}
|
|
125877
|
+
return JSON.stringify(baseResult, null, 2);
|
|
125100
125878
|
}
|
|
125101
125879
|
if (errors5.length === 1) {
|
|
125102
125880
|
return JSON.stringify(errors5[0], null, 2);
|
|
@@ -125422,8 +126200,8 @@ function getContextAgent3(ctx) {
|
|
|
125422
126200
|
init_zod();
|
|
125423
126201
|
init_manager2();
|
|
125424
126202
|
init_detector();
|
|
125425
|
-
import * as
|
|
125426
|
-
import * as
|
|
126203
|
+
import * as fs113 from "node:fs";
|
|
126204
|
+
import * as path155 from "node:path";
|
|
125427
126205
|
init_create_tool();
|
|
125428
126206
|
var MAX_FILE_SIZE2 = 2 * 1024 * 1024;
|
|
125429
126207
|
var BINARY_CHECK_BYTES = 8192;
|
|
@@ -125489,7 +126267,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
125489
126267
|
if (languages?.length) {
|
|
125490
126268
|
const lowerLangs = languages.map((l) => l.toLowerCase());
|
|
125491
126269
|
filesToCheck = filesToCheck.filter((file3) => {
|
|
125492
|
-
const ext =
|
|
126270
|
+
const ext = path155.extname(file3.path).toLowerCase();
|
|
125493
126271
|
const langDef = getLanguageForExtension(ext);
|
|
125494
126272
|
const fileProfile = getProfileForFile(file3.path);
|
|
125495
126273
|
const langId = fileProfile?.id || langDef?.id;
|
|
@@ -125502,7 +126280,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
125502
126280
|
let skippedCount = 0;
|
|
125503
126281
|
for (const fileInfo of filesToCheck) {
|
|
125504
126282
|
const { path: filePath } = fileInfo;
|
|
125505
|
-
const fullPath =
|
|
126283
|
+
const fullPath = path155.isAbsolute(filePath) ? filePath : path155.join(directory, filePath);
|
|
125506
126284
|
const result = {
|
|
125507
126285
|
path: filePath,
|
|
125508
126286
|
language: "",
|
|
@@ -125532,7 +126310,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
125532
126310
|
}
|
|
125533
126311
|
let content;
|
|
125534
126312
|
try {
|
|
125535
|
-
content =
|
|
126313
|
+
content = fs113.readFileSync(fullPath, "utf8");
|
|
125536
126314
|
} catch {
|
|
125537
126315
|
result.skipped_reason = "file_read_error";
|
|
125538
126316
|
skippedCount++;
|
|
@@ -125551,7 +126329,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
125551
126329
|
results.push(result);
|
|
125552
126330
|
continue;
|
|
125553
126331
|
}
|
|
125554
|
-
const ext =
|
|
126332
|
+
const ext = path155.extname(filePath).toLowerCase();
|
|
125555
126333
|
const langDef = getLanguageForExtension(ext);
|
|
125556
126334
|
result.language = profile?.id || langDef?.id || "unknown";
|
|
125557
126335
|
const errors5 = extractSyntaxErrors(parser, content);
|
|
@@ -125649,8 +126427,8 @@ init_zod();
|
|
|
125649
126427
|
init_utils();
|
|
125650
126428
|
init_create_tool();
|
|
125651
126429
|
init_path_security();
|
|
125652
|
-
import * as
|
|
125653
|
-
import * as
|
|
126430
|
+
import * as fs114 from "node:fs";
|
|
126431
|
+
import * as path156 from "node:path";
|
|
125654
126432
|
var MAX_TEXT_LENGTH = 200;
|
|
125655
126433
|
var MAX_FILE_SIZE_BYTES11 = 1024 * 1024;
|
|
125656
126434
|
var SUPPORTED_EXTENSIONS4 = new Set([
|
|
@@ -125673,7 +126451,7 @@ var SUPPORTED_EXTENSIONS4 = new Set([
|
|
|
125673
126451
|
".swift",
|
|
125674
126452
|
".kt"
|
|
125675
126453
|
]);
|
|
125676
|
-
var
|
|
126454
|
+
var SKIP_DIRECTORIES6 = new Set([
|
|
125677
126455
|
"node_modules",
|
|
125678
126456
|
"dist",
|
|
125679
126457
|
"build",
|
|
@@ -125716,9 +126494,9 @@ function validatePathsInput(paths, cwd) {
|
|
|
125716
126494
|
return { error: "paths contains path traversal", resolvedPath: null };
|
|
125717
126495
|
}
|
|
125718
126496
|
try {
|
|
125719
|
-
const resolvedPath =
|
|
125720
|
-
const normalizedCwd =
|
|
125721
|
-
const normalizedResolved =
|
|
126497
|
+
const resolvedPath = path156.resolve(paths);
|
|
126498
|
+
const normalizedCwd = path156.resolve(cwd);
|
|
126499
|
+
const normalizedResolved = path156.resolve(resolvedPath);
|
|
125722
126500
|
if (!normalizedResolved.startsWith(normalizedCwd)) {
|
|
125723
126501
|
return {
|
|
125724
126502
|
error: "paths must be within the current working directory",
|
|
@@ -125734,30 +126512,30 @@ function validatePathsInput(paths, cwd) {
|
|
|
125734
126512
|
}
|
|
125735
126513
|
}
|
|
125736
126514
|
function isSupportedExtension(filePath) {
|
|
125737
|
-
const ext =
|
|
126515
|
+
const ext = path156.extname(filePath).toLowerCase();
|
|
125738
126516
|
return SUPPORTED_EXTENSIONS4.has(ext);
|
|
125739
126517
|
}
|
|
125740
|
-
function
|
|
126518
|
+
function findSourceFiles4(dir, files = []) {
|
|
125741
126519
|
let entries;
|
|
125742
126520
|
try {
|
|
125743
|
-
entries =
|
|
126521
|
+
entries = fs114.readdirSync(dir);
|
|
125744
126522
|
} catch {
|
|
125745
126523
|
return files;
|
|
125746
126524
|
}
|
|
125747
126525
|
entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
|
125748
126526
|
for (const entry of entries) {
|
|
125749
|
-
if (
|
|
126527
|
+
if (SKIP_DIRECTORIES6.has(entry)) {
|
|
125750
126528
|
continue;
|
|
125751
126529
|
}
|
|
125752
|
-
const fullPath =
|
|
126530
|
+
const fullPath = path156.join(dir, entry);
|
|
125753
126531
|
let stat9;
|
|
125754
126532
|
try {
|
|
125755
|
-
stat9 =
|
|
126533
|
+
stat9 = fs114.statSync(fullPath);
|
|
125756
126534
|
} catch {
|
|
125757
126535
|
continue;
|
|
125758
126536
|
}
|
|
125759
126537
|
if (stat9.isDirectory()) {
|
|
125760
|
-
|
|
126538
|
+
findSourceFiles4(fullPath, files);
|
|
125761
126539
|
} else if (stat9.isFile()) {
|
|
125762
126540
|
if (isSupportedExtension(fullPath)) {
|
|
125763
126541
|
files.push(fullPath);
|
|
@@ -125845,7 +126623,7 @@ var todo_extract = createSwarmTool({
|
|
|
125845
126623
|
return JSON.stringify(errorResult, null, 2);
|
|
125846
126624
|
}
|
|
125847
126625
|
const scanPath = resolvedPath;
|
|
125848
|
-
if (!
|
|
126626
|
+
if (!fs114.existsSync(scanPath)) {
|
|
125849
126627
|
const errorResult = {
|
|
125850
126628
|
error: `path not found: ${pathsInput}`,
|
|
125851
126629
|
total: 0,
|
|
@@ -125855,13 +126633,13 @@ var todo_extract = createSwarmTool({
|
|
|
125855
126633
|
return JSON.stringify(errorResult, null, 2);
|
|
125856
126634
|
}
|
|
125857
126635
|
const filesToScan = [];
|
|
125858
|
-
const stat9 =
|
|
126636
|
+
const stat9 = fs114.statSync(scanPath);
|
|
125859
126637
|
if (stat9.isFile()) {
|
|
125860
126638
|
if (isSupportedExtension(scanPath)) {
|
|
125861
126639
|
filesToScan.push(scanPath);
|
|
125862
126640
|
} else {
|
|
125863
126641
|
const errorResult = {
|
|
125864
|
-
error: `unsupported file extension: ${
|
|
126642
|
+
error: `unsupported file extension: ${path156.extname(scanPath)}`,
|
|
125865
126643
|
total: 0,
|
|
125866
126644
|
byPriority: { high: 0, medium: 0, low: 0 },
|
|
125867
126645
|
entries: []
|
|
@@ -125869,16 +126647,16 @@ var todo_extract = createSwarmTool({
|
|
|
125869
126647
|
return JSON.stringify(errorResult, null, 2);
|
|
125870
126648
|
}
|
|
125871
126649
|
} else {
|
|
125872
|
-
|
|
126650
|
+
findSourceFiles4(scanPath, filesToScan);
|
|
125873
126651
|
}
|
|
125874
126652
|
const allEntries = [];
|
|
125875
126653
|
for (const filePath of filesToScan) {
|
|
125876
126654
|
try {
|
|
125877
|
-
const fileStat =
|
|
126655
|
+
const fileStat = fs114.statSync(filePath);
|
|
125878
126656
|
if (fileStat.size > MAX_FILE_SIZE_BYTES11) {
|
|
125879
126657
|
continue;
|
|
125880
126658
|
}
|
|
125881
|
-
const content =
|
|
126659
|
+
const content = fs114.readFileSync(filePath, "utf-8");
|
|
125882
126660
|
const entries = parseTodoComments(content, filePath, tagsSet);
|
|
125883
126661
|
allEntries.push(...entries);
|
|
125884
126662
|
} catch {}
|
|
@@ -125910,18 +126688,18 @@ init_loader();
|
|
|
125910
126688
|
init_schema();
|
|
125911
126689
|
init_qa_gate_profile();
|
|
125912
126690
|
init_gate_evidence();
|
|
125913
|
-
import * as
|
|
125914
|
-
import * as
|
|
126691
|
+
import * as fs118 from "node:fs";
|
|
126692
|
+
import * as path160 from "node:path";
|
|
125915
126693
|
|
|
125916
126694
|
// src/hooks/diff-scope.ts
|
|
125917
126695
|
init_bun_compat();
|
|
125918
|
-
import * as
|
|
125919
|
-
import * as
|
|
126696
|
+
import * as fs116 from "node:fs";
|
|
126697
|
+
import * as path158 from "node:path";
|
|
125920
126698
|
|
|
125921
126699
|
// src/utils/gitignore-warning.ts
|
|
125922
126700
|
init_bun_compat();
|
|
125923
|
-
import * as
|
|
125924
|
-
import * as
|
|
126701
|
+
import * as fs115 from "node:fs";
|
|
126702
|
+
import * as path157 from "node:path";
|
|
125925
126703
|
var _internals67 = { bunSpawn };
|
|
125926
126704
|
var _swarmGitExcludedChecked = false;
|
|
125927
126705
|
function fileCoversSwarm(content) {
|
|
@@ -125995,16 +126773,16 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
125995
126773
|
const excludeRelPath = excludePathRaw.trim();
|
|
125996
126774
|
if (!excludeRelPath)
|
|
125997
126775
|
return;
|
|
125998
|
-
const excludePath =
|
|
126776
|
+
const excludePath = path157.isAbsolute(excludeRelPath) ? excludeRelPath : path157.join(directory, excludeRelPath);
|
|
125999
126777
|
if (checkIgnoreExitCode !== 0) {
|
|
126000
126778
|
try {
|
|
126001
|
-
|
|
126779
|
+
fs115.mkdirSync(path157.dirname(excludePath), { recursive: true });
|
|
126002
126780
|
let existing = "";
|
|
126003
126781
|
try {
|
|
126004
|
-
existing =
|
|
126782
|
+
existing = fs115.readFileSync(excludePath, "utf8");
|
|
126005
126783
|
} catch {}
|
|
126006
126784
|
if (!fileCoversSwarm(existing)) {
|
|
126007
|
-
|
|
126785
|
+
fs115.appendFileSync(excludePath, `
|
|
126008
126786
|
# opencode-swarm local runtime state
|
|
126009
126787
|
.swarm/
|
|
126010
126788
|
`, "utf8");
|
|
@@ -126042,10 +126820,10 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
126042
126820
|
var _internals68 = { bunSpawn };
|
|
126043
126821
|
function getDeclaredScope(taskId, directory) {
|
|
126044
126822
|
try {
|
|
126045
|
-
const planPath =
|
|
126046
|
-
if (!
|
|
126823
|
+
const planPath = path158.join(directory, ".swarm", "plan.json");
|
|
126824
|
+
if (!fs116.existsSync(planPath))
|
|
126047
126825
|
return null;
|
|
126048
|
-
const raw =
|
|
126826
|
+
const raw = fs116.readFileSync(planPath, "utf-8");
|
|
126049
126827
|
const plan = JSON.parse(raw);
|
|
126050
126828
|
for (const phase of plan.phases ?? []) {
|
|
126051
126829
|
for (const task of phase.tasks ?? []) {
|
|
@@ -126147,8 +126925,8 @@ init_telemetry();
|
|
|
126147
126925
|
|
|
126148
126926
|
// src/turbo/lean/task-completion.ts
|
|
126149
126927
|
init_file_locks();
|
|
126150
|
-
import * as
|
|
126151
|
-
import * as
|
|
126928
|
+
import * as fs117 from "node:fs";
|
|
126929
|
+
import * as path159 from "node:path";
|
|
126152
126930
|
var _internals69 = {
|
|
126153
126931
|
listActiveLocks,
|
|
126154
126932
|
verifyLeanTurboTaskCompletion
|
|
@@ -126167,7 +126945,7 @@ var TIER_3_PATTERNS = [
|
|
|
126167
126945
|
];
|
|
126168
126946
|
function matchesTier3Pattern(files) {
|
|
126169
126947
|
for (const file3 of files) {
|
|
126170
|
-
const fileName =
|
|
126948
|
+
const fileName = path159.basename(file3);
|
|
126171
126949
|
for (const pattern of TIER_3_PATTERNS) {
|
|
126172
126950
|
if (pattern.test(fileName)) {
|
|
126173
126951
|
return true;
|
|
@@ -126179,14 +126957,14 @@ function matchesTier3Pattern(files) {
|
|
|
126179
126957
|
function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
126180
126958
|
let persisted = null;
|
|
126181
126959
|
try {
|
|
126182
|
-
const statePath =
|
|
126183
|
-
if (!
|
|
126960
|
+
const statePath = path159.join(directory, ".swarm", "turbo-state.json");
|
|
126961
|
+
if (!fs117.existsSync(statePath)) {
|
|
126184
126962
|
return {
|
|
126185
126963
|
ok: false,
|
|
126186
126964
|
reason: "Lean Turbo state file not found"
|
|
126187
126965
|
};
|
|
126188
126966
|
}
|
|
126189
|
-
const raw =
|
|
126967
|
+
const raw = fs117.readFileSync(statePath, "utf-8");
|
|
126190
126968
|
persisted = JSON.parse(raw);
|
|
126191
126969
|
} catch {
|
|
126192
126970
|
return {
|
|
@@ -126263,11 +127041,11 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
126263
127041
|
};
|
|
126264
127042
|
}
|
|
126265
127043
|
const phase = runState.phase ?? 0;
|
|
126266
|
-
const evidencePath =
|
|
126267
|
-
const expectedDir =
|
|
126268
|
-
const resolvedPath =
|
|
126269
|
-
const resolvedDir =
|
|
126270
|
-
if (!resolvedPath.startsWith(resolvedDir +
|
|
127044
|
+
const evidencePath = path159.join(directory, ".swarm", "evidence", String(phase), "lean-turbo", `${lane.laneId}.json`);
|
|
127045
|
+
const expectedDir = path159.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
|
|
127046
|
+
const resolvedPath = path159.resolve(evidencePath);
|
|
127047
|
+
const resolvedDir = path159.resolve(expectedDir);
|
|
127048
|
+
if (!resolvedPath.startsWith(resolvedDir + path159.sep) && resolvedPath !== resolvedDir) {
|
|
126271
127049
|
return {
|
|
126272
127050
|
ok: false,
|
|
126273
127051
|
reason: `Lane ID causes path traversal: ${lane.laneId}`,
|
|
@@ -126279,7 +127057,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
126279
127057
|
}
|
|
126280
127058
|
};
|
|
126281
127059
|
}
|
|
126282
|
-
if (!
|
|
127060
|
+
if (!fs117.existsSync(evidencePath)) {
|
|
126283
127061
|
return {
|
|
126284
127062
|
ok: false,
|
|
126285
127063
|
reason: `Lane ${lane.laneId} evidence file not found: ${evidencePath}`,
|
|
@@ -126307,8 +127085,8 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
126307
127085
|
}
|
|
126308
127086
|
let filesTouched = [];
|
|
126309
127087
|
try {
|
|
126310
|
-
const planPath =
|
|
126311
|
-
const planRaw =
|
|
127088
|
+
const planPath = path159.join(directory, ".swarm", "plan.json");
|
|
127089
|
+
const planRaw = fs117.readFileSync(planPath, "utf-8");
|
|
126312
127090
|
const plan = JSON.parse(planRaw);
|
|
126313
127091
|
for (const planPhase of plan.phases ?? []) {
|
|
126314
127092
|
for (const task of planPhase.tasks ?? []) {
|
|
@@ -126391,7 +127169,7 @@ var TIER_3_PATTERNS2 = [
|
|
|
126391
127169
|
];
|
|
126392
127170
|
function matchesTier3Pattern2(files) {
|
|
126393
127171
|
for (const file3 of files) {
|
|
126394
|
-
const fileName =
|
|
127172
|
+
const fileName = path160.basename(file3);
|
|
126395
127173
|
for (const pattern of TIER_3_PATTERNS2) {
|
|
126396
127174
|
if (pattern.test(fileName)) {
|
|
126397
127175
|
return true;
|
|
@@ -126430,8 +127208,8 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
126430
127208
|
if (!skipStandardTurboBypass && hasActiveTurboMode()) {
|
|
126431
127209
|
const resolvedDir2 = workingDirectory;
|
|
126432
127210
|
try {
|
|
126433
|
-
const planPath =
|
|
126434
|
-
const planRaw =
|
|
127211
|
+
const planPath = path160.join(resolvedDir2, ".swarm", "plan.json");
|
|
127212
|
+
const planRaw = fs118.readFileSync(planPath, "utf-8");
|
|
126435
127213
|
const plan = JSON.parse(planRaw);
|
|
126436
127214
|
for (const planPhase of plan.phases ?? []) {
|
|
126437
127215
|
for (const task of planPhase.tasks ?? []) {
|
|
@@ -126508,8 +127286,8 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
126508
127286
|
}
|
|
126509
127287
|
if (resolvedDir) {
|
|
126510
127288
|
try {
|
|
126511
|
-
const planPath =
|
|
126512
|
-
const planRaw =
|
|
127289
|
+
const planPath = path160.join(resolvedDir, ".swarm", "plan.json");
|
|
127290
|
+
const planRaw = fs118.readFileSync(planPath, "utf-8");
|
|
126513
127291
|
const plan = JSON.parse(planRaw);
|
|
126514
127292
|
for (const planPhase of plan.phases ?? []) {
|
|
126515
127293
|
for (const task of planPhase.tasks ?? []) {
|
|
@@ -126744,8 +127522,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
126744
127522
|
};
|
|
126745
127523
|
}
|
|
126746
127524
|
directory = resolveResult.directory;
|
|
126747
|
-
const planPath =
|
|
126748
|
-
if (!
|
|
127525
|
+
const planPath = path160.join(directory, ".swarm", "plan.json");
|
|
127526
|
+
if (!fs118.existsSync(planPath)) {
|
|
126749
127527
|
return {
|
|
126750
127528
|
success: false,
|
|
126751
127529
|
message: `Invalid working_directory: plan not found in "${directory}"`,
|
|
@@ -126753,9 +127531,9 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
126753
127531
|
};
|
|
126754
127532
|
}
|
|
126755
127533
|
if (fallbackDir && directory !== fallbackDir) {
|
|
126756
|
-
const canonicalDir =
|
|
126757
|
-
const canonicalRoot =
|
|
126758
|
-
if (canonicalDir.startsWith(canonicalRoot +
|
|
127534
|
+
const canonicalDir = fs118.realpathSync(path160.resolve(directory));
|
|
127535
|
+
const canonicalRoot = fs118.realpathSync(path160.resolve(fallbackDir));
|
|
127536
|
+
if (canonicalDir.startsWith(canonicalRoot + path160.sep)) {
|
|
126759
127537
|
return {
|
|
126760
127538
|
success: false,
|
|
126761
127539
|
message: `Invalid working_directory: "${directory}" is a subdirectory of ` + `the project root "${fallbackDir}". Pass the project root path or ` + `omit working_directory entirely.`,
|
|
@@ -126767,22 +127545,22 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
126767
127545
|
}
|
|
126768
127546
|
if (args2.status === "in_progress") {
|
|
126769
127547
|
try {
|
|
126770
|
-
const evidencePath =
|
|
126771
|
-
|
|
126772
|
-
const fd =
|
|
127548
|
+
const evidencePath = path160.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
|
|
127549
|
+
fs118.mkdirSync(path160.dirname(evidencePath), { recursive: true });
|
|
127550
|
+
const fd = fs118.openSync(evidencePath, "wx");
|
|
126773
127551
|
let writeOk = false;
|
|
126774
127552
|
try {
|
|
126775
|
-
|
|
127553
|
+
fs118.writeSync(fd, JSON.stringify({
|
|
126776
127554
|
taskId: args2.task_id,
|
|
126777
127555
|
required_gates: [],
|
|
126778
127556
|
gates: {}
|
|
126779
127557
|
}, null, 2));
|
|
126780
127558
|
writeOk = true;
|
|
126781
127559
|
} finally {
|
|
126782
|
-
|
|
127560
|
+
fs118.closeSync(fd);
|
|
126783
127561
|
if (!writeOk) {
|
|
126784
127562
|
try {
|
|
126785
|
-
|
|
127563
|
+
fs118.unlinkSync(evidencePath);
|
|
126786
127564
|
} catch {}
|
|
126787
127565
|
}
|
|
126788
127566
|
}
|
|
@@ -126792,8 +127570,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
126792
127570
|
recoverTaskStateFromDelegations(args2.task_id, directory);
|
|
126793
127571
|
let phaseRequiresReviewer = true;
|
|
126794
127572
|
try {
|
|
126795
|
-
const planPath2 =
|
|
126796
|
-
const planRaw =
|
|
127573
|
+
const planPath2 = path160.join(directory, ".swarm", "plan.json");
|
|
127574
|
+
const planRaw = fs118.readFileSync(planPath2, "utf-8");
|
|
126797
127575
|
const plan = JSON.parse(planRaw);
|
|
126798
127576
|
const taskPhase = plan.phases.find((p) => p.tasks.some((t) => t.id === args2.task_id));
|
|
126799
127577
|
if (taskPhase?.required_agents && !taskPhase.required_agents.includes("reviewer")) {
|
|
@@ -127021,7 +127799,7 @@ init_utils2();
|
|
|
127021
127799
|
init_redaction();
|
|
127022
127800
|
import { createHash as createHash12 } from "node:crypto";
|
|
127023
127801
|
import { appendFile as appendFile14, mkdir as mkdir25 } from "node:fs/promises";
|
|
127024
|
-
import * as
|
|
127802
|
+
import * as path161 from "node:path";
|
|
127025
127803
|
var EVIDENCE_CACHE_FILE = "evidence-cache/documents.jsonl";
|
|
127026
127804
|
var MAX_EVIDENCE_TEXT_LENGTH = 4000;
|
|
127027
127805
|
async function writeEvidenceDocuments(directory, inputs, now = () => new Date) {
|
|
@@ -127029,7 +127807,7 @@ async function writeEvidenceDocuments(directory, inputs, now = () => new Date) {
|
|
|
127029
127807
|
const capturedAt = now().toISOString();
|
|
127030
127808
|
const records = inputs.map((input) => createEvidenceDocumentRecord(input, capturedAt)).filter((record3) => record3 !== null);
|
|
127031
127809
|
if (records.length > 0) {
|
|
127032
|
-
await mkdir25(
|
|
127810
|
+
await mkdir25(path161.dirname(filePath), { recursive: true });
|
|
127033
127811
|
await appendFile14(filePath, `${records.map((record3) => JSON.stringify(record3)).join(`
|
|
127034
127812
|
`)}
|
|
127035
127813
|
`, "utf-8");
|
|
@@ -127226,7 +128004,7 @@ init_schema3();
|
|
|
127226
128004
|
init_store();
|
|
127227
128005
|
init_create_tool();
|
|
127228
128006
|
init_resolve_working_directory();
|
|
127229
|
-
import * as
|
|
128007
|
+
import * as path162 from "node:path";
|
|
127230
128008
|
var FindingSchema2 = exports_external.object({
|
|
127231
128009
|
severity: exports_external.enum(["low", "medium", "high", "critical"]),
|
|
127232
128010
|
category: exports_external.string().min(1),
|
|
@@ -127290,7 +128068,7 @@ var write_architecture_supervisor_evidence = createSwarmTool({
|
|
|
127290
128068
|
if (config3.architectural_supervision?.persist_knowledge_recommendations && args2.knowledge_recommendations.length > 0) {
|
|
127291
128069
|
const knowledgeConfig = KnowledgeConfigSchema.parse(config3.knowledge ?? {});
|
|
127292
128070
|
const lessons = args2.knowledge_recommendations.map((r) => r.lesson);
|
|
127293
|
-
const result = await curateAndStoreSwarm(lessons,
|
|
128071
|
+
const result = await curateAndStoreSwarm(lessons, path162.basename(dirResult.directory), { phase_number: args2.phase }, dirResult.directory, knowledgeConfig, { skipAutoPromotion: true });
|
|
127294
128072
|
knowledgeProposed = result.stored;
|
|
127295
128073
|
}
|
|
127296
128074
|
} catch {}
|
|
@@ -127325,8 +128103,8 @@ init_utils2();
|
|
|
127325
128103
|
init_ledger();
|
|
127326
128104
|
init_manager();
|
|
127327
128105
|
init_create_tool();
|
|
127328
|
-
import
|
|
127329
|
-
import
|
|
128106
|
+
import fs119 from "node:fs";
|
|
128107
|
+
import path163 from "node:path";
|
|
127330
128108
|
function normalizeVerdict(verdict) {
|
|
127331
128109
|
switch (verdict) {
|
|
127332
128110
|
case "APPROVED":
|
|
@@ -127374,7 +128152,7 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
127374
128152
|
entries: [evidenceEntry]
|
|
127375
128153
|
};
|
|
127376
128154
|
const filename = "drift-verifier.json";
|
|
127377
|
-
const relativePath =
|
|
128155
|
+
const relativePath = path163.join("evidence", String(phase), filename);
|
|
127378
128156
|
let validatedPath;
|
|
127379
128157
|
try {
|
|
127380
128158
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -127385,12 +128163,12 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
127385
128163
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
127386
128164
|
}, null, 2);
|
|
127387
128165
|
}
|
|
127388
|
-
const evidenceDir =
|
|
128166
|
+
const evidenceDir = path163.dirname(validatedPath);
|
|
127389
128167
|
try {
|
|
127390
|
-
await
|
|
127391
|
-
const tempPath =
|
|
127392
|
-
await
|
|
127393
|
-
await
|
|
128168
|
+
await fs119.promises.mkdir(evidenceDir, { recursive: true });
|
|
128169
|
+
const tempPath = path163.join(evidenceDir, `.${filename}.tmp`);
|
|
128170
|
+
await fs119.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
128171
|
+
await fs119.promises.rename(tempPath, validatedPath);
|
|
127394
128172
|
let snapshotInfo;
|
|
127395
128173
|
let snapshotError;
|
|
127396
128174
|
let qaProfileLocked;
|
|
@@ -127484,8 +128262,8 @@ var write_drift_evidence = createSwarmTool({
|
|
|
127484
128262
|
// src/tools/write-final-council-evidence.ts
|
|
127485
128263
|
init_zod();
|
|
127486
128264
|
init_loader();
|
|
127487
|
-
import
|
|
127488
|
-
import
|
|
128265
|
+
import fs120 from "node:fs";
|
|
128266
|
+
import path164 from "node:path";
|
|
127489
128267
|
init_utils2();
|
|
127490
128268
|
init_manager();
|
|
127491
128269
|
init_create_tool();
|
|
@@ -127573,7 +128351,7 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
|
|
|
127573
128351
|
timestamp: synthesis.timestamp
|
|
127574
128352
|
};
|
|
127575
128353
|
const filename = "final-council.json";
|
|
127576
|
-
const relativePath =
|
|
128354
|
+
const relativePath = path164.join("evidence", filename);
|
|
127577
128355
|
let validatedPath;
|
|
127578
128356
|
try {
|
|
127579
128357
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -127587,12 +128365,12 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
|
|
|
127587
128365
|
const evidenceContent = {
|
|
127588
128366
|
entries: [evidenceEntry]
|
|
127589
128367
|
};
|
|
127590
|
-
const evidenceDir =
|
|
128368
|
+
const evidenceDir = path164.dirname(validatedPath);
|
|
127591
128369
|
try {
|
|
127592
|
-
await
|
|
127593
|
-
const tempPath =
|
|
127594
|
-
await
|
|
127595
|
-
await
|
|
128370
|
+
await fs120.promises.mkdir(evidenceDir, { recursive: true });
|
|
128371
|
+
const tempPath = path164.join(evidenceDir, `.${filename}.tmp`);
|
|
128372
|
+
await fs120.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
128373
|
+
await fs120.promises.rename(tempPath, validatedPath);
|
|
127596
128374
|
return JSON.stringify({
|
|
127597
128375
|
success: true,
|
|
127598
128376
|
phase: input.phase,
|
|
@@ -127649,8 +128427,8 @@ var write_final_council_evidence = createSwarmTool({
|
|
|
127649
128427
|
init_zod();
|
|
127650
128428
|
init_utils2();
|
|
127651
128429
|
init_create_tool();
|
|
127652
|
-
import
|
|
127653
|
-
import
|
|
128430
|
+
import fs121 from "node:fs";
|
|
128431
|
+
import path165 from "node:path";
|
|
127654
128432
|
function normalizeVerdict2(verdict) {
|
|
127655
128433
|
switch (verdict) {
|
|
127656
128434
|
case "APPROVED":
|
|
@@ -127698,7 +128476,7 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
127698
128476
|
entries: [evidenceEntry]
|
|
127699
128477
|
};
|
|
127700
128478
|
const filename = "hallucination-guard.json";
|
|
127701
|
-
const relativePath =
|
|
128479
|
+
const relativePath = path165.join("evidence", String(phase), filename);
|
|
127702
128480
|
let validatedPath;
|
|
127703
128481
|
try {
|
|
127704
128482
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -127709,12 +128487,12 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
127709
128487
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
127710
128488
|
}, null, 2);
|
|
127711
128489
|
}
|
|
127712
|
-
const evidenceDir =
|
|
128490
|
+
const evidenceDir = path165.dirname(validatedPath);
|
|
127713
128491
|
try {
|
|
127714
|
-
await
|
|
127715
|
-
const tempPath =
|
|
127716
|
-
await
|
|
127717
|
-
await
|
|
128492
|
+
await fs121.promises.mkdir(evidenceDir, { recursive: true });
|
|
128493
|
+
const tempPath = path165.join(evidenceDir, `.${filename}.tmp`);
|
|
128494
|
+
await fs121.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
128495
|
+
await fs121.promises.rename(tempPath, validatedPath);
|
|
127718
128496
|
return JSON.stringify({
|
|
127719
128497
|
success: true,
|
|
127720
128498
|
phase,
|
|
@@ -127761,8 +128539,8 @@ var write_hallucination_evidence = createSwarmTool({
|
|
|
127761
128539
|
init_zod();
|
|
127762
128540
|
init_utils2();
|
|
127763
128541
|
init_create_tool();
|
|
127764
|
-
import
|
|
127765
|
-
import
|
|
128542
|
+
import fs122 from "node:fs";
|
|
128543
|
+
import path166 from "node:path";
|
|
127766
128544
|
function normalizeVerdict3(verdict) {
|
|
127767
128545
|
switch (verdict) {
|
|
127768
128546
|
case "PASS":
|
|
@@ -127836,7 +128614,7 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
127836
128614
|
entries: [evidenceEntry]
|
|
127837
128615
|
};
|
|
127838
128616
|
const filename = "mutation-gate.json";
|
|
127839
|
-
const relativePath =
|
|
128617
|
+
const relativePath = path166.join("evidence", String(phase), filename);
|
|
127840
128618
|
let validatedPath;
|
|
127841
128619
|
try {
|
|
127842
128620
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -127847,12 +128625,12 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
127847
128625
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
127848
128626
|
}, null, 2);
|
|
127849
128627
|
}
|
|
127850
|
-
const evidenceDir =
|
|
128628
|
+
const evidenceDir = path166.dirname(validatedPath);
|
|
127851
128629
|
try {
|
|
127852
|
-
await
|
|
127853
|
-
const tempPath =
|
|
127854
|
-
await
|
|
127855
|
-
await
|
|
128630
|
+
await fs122.promises.mkdir(evidenceDir, { recursive: true });
|
|
128631
|
+
const tempPath = path166.join(evidenceDir, `.${filename}.tmp`);
|
|
128632
|
+
await fs122.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
128633
|
+
await fs122.promises.rename(tempPath, validatedPath);
|
|
127856
128634
|
return JSON.stringify({
|
|
127857
128635
|
success: true,
|
|
127858
128636
|
phase,
|
|
@@ -127934,6 +128712,7 @@ var TOOL_MANIFEST = defineHandlers({
|
|
|
127934
128712
|
mutation_test: () => mutation_test,
|
|
127935
128713
|
generate_mutants: () => generate_mutants,
|
|
127936
128714
|
detect_domains: () => detect_domains,
|
|
128715
|
+
git_blame: () => git_blame,
|
|
127937
128716
|
gitingest: () => gitingest,
|
|
127938
128717
|
retrieve_summary: () => retrieve_summary,
|
|
127939
128718
|
extract_code_blocks: () => extract_code_blocks,
|
|
@@ -128298,7 +129077,7 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
128298
129077
|
const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
|
|
128299
129078
|
preflightTriggerManager = new PTM(automationConfig);
|
|
128300
129079
|
const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
|
|
128301
|
-
const swarmDir =
|
|
129080
|
+
const swarmDir = path168.resolve(ctx.directory, ".swarm");
|
|
128302
129081
|
statusArtifact = new ASA(swarmDir);
|
|
128303
129082
|
statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
|
|
128304
129083
|
if (automationConfig.capabilities?.evidence_auto_summaries === true) {
|
|
@@ -128812,7 +129591,7 @@ ${promptRaw}`;
|
|
|
128812
129591
|
const meta3 = readSkillMetadata(s.skillPath, ctx.directory);
|
|
128813
129592
|
let desc = meta3.description || "";
|
|
128814
129593
|
if (!desc || desc === "No description provided") {
|
|
128815
|
-
desc =
|
|
129594
|
+
desc = path168.basename(path168.dirname(s.skillPath));
|
|
128816
129595
|
}
|
|
128817
129596
|
desc = desc.replace(/,/g, ";");
|
|
128818
129597
|
return `file:${s.skillPath} (-- ${desc})`;
|
|
@@ -128822,7 +129601,7 @@ ${promptRaw}`;
|
|
|
128822
129601
|
|
|
128823
129602
|
${promptRaw}`;
|
|
128824
129603
|
argsRecord.prompt = newPrompt;
|
|
128825
|
-
const skillNames = topSkills.map((s) => `${
|
|
129604
|
+
const skillNames = topSkills.map((s) => `${path168.basename(s.skillPath)} (score: ${s.score.toFixed(2)})`).join(", ");
|
|
128826
129605
|
console.warn(`[skill-propagation-gate] Injected skills: ${skillNames}`);
|
|
128827
129606
|
for (const skill of topSkills) {
|
|
128828
129607
|
try {
|