opencode-swarm 7.49.1 → 7.50.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 +1 -1
- package/dist/cli/index.js +5 -1
- package/dist/hooks/scope-guard.d.ts +24 -0
- package/dist/index.js +1290 -432
- package/dist/tools/apply-patch.d.ts +48 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/manifest.d.ts +1 -0
- 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.50.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",
|
|
@@ -679,6 +679,10 @@ var init_tool_metadata = __esm(() => {
|
|
|
679
679
|
lean_turbo_status: {
|
|
680
680
|
description: "returns Lean Turbo configuration and active status for the current session",
|
|
681
681
|
agents: ["architect"]
|
|
682
|
+
},
|
|
683
|
+
apply_patch: {
|
|
684
|
+
description: "Apply a unified diff patch to workspace files with exact context matching, atomic writes, and path validation",
|
|
685
|
+
agents: ["coder"]
|
|
682
686
|
}
|
|
683
687
|
};
|
|
684
688
|
TOOL_NAMES = Object.keys(TOOL_METADATA);
|
|
@@ -92314,7 +92318,7 @@ __export(exports_design_doc_drift, {
|
|
|
92314
92318
|
_internals: () => _internals60
|
|
92315
92319
|
});
|
|
92316
92320
|
import * as fs98 from "node:fs";
|
|
92317
|
-
import * as
|
|
92321
|
+
import * as path137 from "node:path";
|
|
92318
92322
|
function mtimeMsOrNull(absPath) {
|
|
92319
92323
|
try {
|
|
92320
92324
|
return fs98.statSync(absPath).mtimeMs;
|
|
@@ -92325,35 +92329,35 @@ function mtimeMsOrNull(absPath) {
|
|
|
92325
92329
|
function resolveAnchorWithin(directory, anchor) {
|
|
92326
92330
|
if (!anchor || typeof anchor !== "string")
|
|
92327
92331
|
return null;
|
|
92328
|
-
const root =
|
|
92329
|
-
const resolved =
|
|
92330
|
-
const rel =
|
|
92331
|
-
if (rel.startsWith("..") ||
|
|
92332
|
+
const root = path137.resolve(directory);
|
|
92333
|
+
const resolved = path137.resolve(root, anchor);
|
|
92334
|
+
const rel = path137.relative(root, resolved);
|
|
92335
|
+
if (rel.startsWith("..") || path137.isAbsolute(rel))
|
|
92332
92336
|
return null;
|
|
92333
92337
|
return resolved;
|
|
92334
92338
|
}
|
|
92335
92339
|
async function runDesignDocDriftCheck(directory, phase, outDir) {
|
|
92336
92340
|
try {
|
|
92337
|
-
const root =
|
|
92338
|
-
const outAbs =
|
|
92339
|
-
const outRel =
|
|
92340
|
-
if (outRel.startsWith("..") ||
|
|
92341
|
+
const root = path137.resolve(directory);
|
|
92342
|
+
const outAbs = path137.resolve(root, outDir);
|
|
92343
|
+
const outRel = path137.relative(root, outAbs);
|
|
92344
|
+
if (outRel.startsWith("..") || path137.isAbsolute(outRel)) {
|
|
92341
92345
|
return null;
|
|
92342
92346
|
}
|
|
92343
92347
|
const docMtimes = new Map;
|
|
92344
92348
|
const checkedDocs = [];
|
|
92345
92349
|
const missingDocs = [];
|
|
92346
92350
|
for (const [docName, relFile] of Object.entries(DESIGN_DOC_FILES)) {
|
|
92347
|
-
const abs =
|
|
92351
|
+
const abs = path137.join(outAbs, relFile);
|
|
92348
92352
|
const mtime = mtimeMsOrNull(abs);
|
|
92349
92353
|
docMtimes.set(docName, mtime);
|
|
92350
92354
|
if (mtime === null) {
|
|
92351
|
-
missingDocs.push(
|
|
92355
|
+
missingDocs.push(path137.join(outDir, relFile));
|
|
92352
92356
|
} else {
|
|
92353
|
-
checkedDocs.push(
|
|
92357
|
+
checkedDocs.push(path137.join(outDir, relFile));
|
|
92354
92358
|
}
|
|
92355
92359
|
}
|
|
92356
|
-
const traceabilityAbs =
|
|
92360
|
+
const traceabilityAbs = path137.join(outAbs, TRACEABILITY_REL);
|
|
92357
92361
|
let registry3 = null;
|
|
92358
92362
|
try {
|
|
92359
92363
|
const stat9 = await fs98.promises.stat(traceabilityAbs);
|
|
@@ -92366,7 +92370,7 @@ async function runDesignDocDriftCheck(directory, phase, outDir) {
|
|
|
92366
92370
|
registry3 = null;
|
|
92367
92371
|
}
|
|
92368
92372
|
const noDocs = checkedDocs.length === 0 || registry3 === null;
|
|
92369
|
-
const specMtime = mtimeMsOrNull(
|
|
92373
|
+
const specMtime = mtimeMsOrNull(path137.join(root, ".swarm", "spec.md"));
|
|
92370
92374
|
const staleSections = [];
|
|
92371
92375
|
if (!noDocs && Array.isArray(registry3?.sections)) {
|
|
92372
92376
|
for (const section of registry3.sections) {
|
|
@@ -92422,7 +92426,7 @@ async function runDesignDocDriftCheck(directory, phase, outDir) {
|
|
|
92422
92426
|
};
|
|
92423
92427
|
const filename = `${DOC_DRIFT_REPORT_PREFIX}${phase}.json`;
|
|
92424
92428
|
const filePath = validateSwarmPath(directory, filename);
|
|
92425
|
-
await fs98.promises.mkdir(
|
|
92429
|
+
await fs98.promises.mkdir(path137.dirname(filePath), { recursive: true });
|
|
92426
92430
|
await fs98.promises.writeFile(filePath, JSON.stringify(report, null, 2), "utf-8");
|
|
92427
92431
|
getGlobalEventBus().publish("curator.docdrift.completed", {
|
|
92428
92432
|
phase,
|
|
@@ -92453,10 +92457,10 @@ var init_design_doc_drift = __esm(() => {
|
|
|
92453
92457
|
domain: "domain.md",
|
|
92454
92458
|
"technical-spec": "technical-spec.md",
|
|
92455
92459
|
"behavior-spec": "behavior-spec.md",
|
|
92456
|
-
"reference-impl":
|
|
92457
|
-
"idiom-notes":
|
|
92460
|
+
"reference-impl": path137.join("reference", "reference-impl.md"),
|
|
92461
|
+
"idiom-notes": path137.join("reference", "idiom-notes.md")
|
|
92458
92462
|
};
|
|
92459
|
-
TRACEABILITY_REL =
|
|
92463
|
+
TRACEABILITY_REL = path137.join("reference", "traceability.json");
|
|
92460
92464
|
_internals60 = {
|
|
92461
92465
|
mtimeMsOrNull,
|
|
92462
92466
|
resolveAnchorWithin,
|
|
@@ -92472,7 +92476,7 @@ __export(exports_project_context, {
|
|
|
92472
92476
|
LANG_BACKEND_DETECTION_TIMEOUT_MS: () => LANG_BACKEND_DETECTION_TIMEOUT_MS
|
|
92473
92477
|
});
|
|
92474
92478
|
import * as fs122 from "node:fs";
|
|
92475
|
-
import * as
|
|
92479
|
+
import * as path166 from "node:path";
|
|
92476
92480
|
function detectFileExists2(directory, pattern) {
|
|
92477
92481
|
if (pattern.includes("*") || pattern.includes("?")) {
|
|
92478
92482
|
try {
|
|
@@ -92484,7 +92488,7 @@ function detectFileExists2(directory, pattern) {
|
|
|
92484
92488
|
}
|
|
92485
92489
|
}
|
|
92486
92490
|
try {
|
|
92487
|
-
fs122.accessSync(
|
|
92491
|
+
fs122.accessSync(path166.join(directory, pattern));
|
|
92488
92492
|
return true;
|
|
92489
92493
|
} catch {
|
|
92490
92494
|
return false;
|
|
@@ -92493,7 +92497,7 @@ function detectFileExists2(directory, pattern) {
|
|
|
92493
92497
|
function selectTestCommandFromScriptsTest(backend, directory) {
|
|
92494
92498
|
let pkgRaw;
|
|
92495
92499
|
try {
|
|
92496
|
-
pkgRaw = fs122.readFileSync(
|
|
92500
|
+
pkgRaw = fs122.readFileSync(path166.join(directory, "package.json"), "utf-8");
|
|
92497
92501
|
} catch {
|
|
92498
92502
|
return null;
|
|
92499
92503
|
}
|
|
@@ -92602,7 +92606,7 @@ var init_project_context = __esm(() => {
|
|
|
92602
92606
|
init_package();
|
|
92603
92607
|
init_agents2();
|
|
92604
92608
|
init_critic();
|
|
92605
|
-
import * as
|
|
92609
|
+
import * as path167 from "node:path";
|
|
92606
92610
|
|
|
92607
92611
|
// src/background/index.ts
|
|
92608
92612
|
init_event_bus();
|
|
@@ -103467,29 +103471,34 @@ function createScopeGuardHook(config3, directory, injectAdvisory) {
|
|
|
103467
103471
|
if (!declaredScope || declaredScope.length === 0)
|
|
103468
103472
|
return;
|
|
103469
103473
|
const argsObj = output.args;
|
|
103470
|
-
const
|
|
103471
|
-
|
|
103472
|
-
|
|
103473
|
-
|
|
103474
|
-
|
|
103475
|
-
|
|
103476
|
-
|
|
103477
|
-
|
|
103478
|
-
|
|
103479
|
-
|
|
103480
|
-
|
|
103481
|
-
|
|
103482
|
-
|
|
103483
|
-
|
|
103484
|
-
|
|
103485
|
-
|
|
103486
|
-
|
|
103487
|
-
} catch {}
|
|
103488
|
-
break;
|
|
103474
|
+
const candidatePaths = [];
|
|
103475
|
+
const singlePathKeys = ["path", "filePath", "file"];
|
|
103476
|
+
for (const key of singlePathKeys) {
|
|
103477
|
+
const val = argsObj?.[key];
|
|
103478
|
+
if (typeof val === "string" && val) {
|
|
103479
|
+
candidatePaths.push(val);
|
|
103480
|
+
}
|
|
103481
|
+
}
|
|
103482
|
+
let hasArrayKeys = false;
|
|
103483
|
+
const arrayPathKeys = ["files", "paths", "targetFiles"];
|
|
103484
|
+
for (const key of arrayPathKeys) {
|
|
103485
|
+
const val = argsObj?.[key];
|
|
103486
|
+
if (Array.isArray(val)) {
|
|
103487
|
+
hasArrayKeys = true;
|
|
103488
|
+
for (const item of val) {
|
|
103489
|
+
if (typeof item === "string" && item) {
|
|
103490
|
+
candidatePaths.push(item);
|
|
103489
103491
|
}
|
|
103490
103492
|
}
|
|
103491
103493
|
}
|
|
103492
|
-
|
|
103494
|
+
}
|
|
103495
|
+
if (candidatePaths.length === 0 && !hasArrayKeys)
|
|
103496
|
+
return;
|
|
103497
|
+
for (const rawPath of candidatePaths) {
|
|
103498
|
+
const filePath = sanitizePath(rawPath);
|
|
103499
|
+
if (!isFileInScope(filePath, declaredScope, directory)) {
|
|
103500
|
+
reportScopeViolation(agentName, filePath, taskId, session, injectAdvisory, swarmState, declaredScope);
|
|
103501
|
+
}
|
|
103493
103502
|
}
|
|
103494
103503
|
}
|
|
103495
103504
|
};
|
|
@@ -103497,7 +103506,7 @@ function createScopeGuardHook(config3, directory, injectAdvisory) {
|
|
|
103497
103506
|
function isFileInScope(filePath, scopeEntries, directory) {
|
|
103498
103507
|
const dir = directory ?? process.cwd();
|
|
103499
103508
|
const resolvedFile = path102.resolve(dir, filePath);
|
|
103500
|
-
return scopeEntries.some((scope) => {
|
|
103509
|
+
return scopeEntries.filter((scope) => scope.length > 0).some((scope) => {
|
|
103501
103510
|
const resolvedScope = path102.resolve(dir, scope);
|
|
103502
103511
|
if (resolvedFile === resolvedScope)
|
|
103503
103512
|
return true;
|
|
@@ -103505,6 +103514,38 @@ function isFileInScope(filePath, scopeEntries, directory) {
|
|
|
103505
103514
|
return rel.length > 0 && !rel.startsWith("..") && !path102.isAbsolute(rel);
|
|
103506
103515
|
});
|
|
103507
103516
|
}
|
|
103517
|
+
function sanitizePath(raw) {
|
|
103518
|
+
let result = "";
|
|
103519
|
+
for (let i2 = 0;i2 < raw.length; i2++) {
|
|
103520
|
+
const c = raw.charCodeAt(i2);
|
|
103521
|
+
if (c <= 31 || c === 127 || c >= 128 && c <= 159) {
|
|
103522
|
+
result += "_";
|
|
103523
|
+
continue;
|
|
103524
|
+
}
|
|
103525
|
+
result += raw[i2];
|
|
103526
|
+
}
|
|
103527
|
+
return result.replace(/\[[\d;]*m/g, "");
|
|
103528
|
+
}
|
|
103529
|
+
function reportScopeViolation(agentName, filePath, taskId, session, injectAdvisory, state, scopeEntries) {
|
|
103530
|
+
const taskLabel = taskId ?? "unknown";
|
|
103531
|
+
const violationMessage = `SCOPE VIOLATION: ${agentName} attempted to modify '${filePath}' which is not in declared scope for task ${taskLabel}. Declared scope: [${scopeEntries.slice(0, 3).join(", ")}${scopeEntries.length > 3 ? "..." : ""}]`;
|
|
103532
|
+
if (session) {
|
|
103533
|
+
session.lastScopeViolation = violationMessage;
|
|
103534
|
+
session.scopeViolationDetected = true;
|
|
103535
|
+
}
|
|
103536
|
+
if (injectAdvisory) {
|
|
103537
|
+
for (const [archSessionId, archSession] of state.agentSessions) {
|
|
103538
|
+
const archAgent = state.activeAgent.get(archSessionId) ?? archSession.agentName;
|
|
103539
|
+
if (stripKnownSwarmPrefix(archAgent) === ORCHESTRATOR_NAME) {
|
|
103540
|
+
try {
|
|
103541
|
+
injectAdvisory(archSessionId, `[SCOPE GUARD] ${violationMessage}`);
|
|
103542
|
+
} catch {}
|
|
103543
|
+
break;
|
|
103544
|
+
}
|
|
103545
|
+
}
|
|
103546
|
+
}
|
|
103547
|
+
throw new Error(violationMessage);
|
|
103548
|
+
}
|
|
103508
103549
|
|
|
103509
103550
|
// src/hooks/self-review.ts
|
|
103510
103551
|
init_constants();
|
|
@@ -105997,20 +106038,836 @@ init_snapshot_writer();
|
|
|
105997
106038
|
init_state();
|
|
105998
106039
|
init_telemetry();
|
|
105999
106040
|
|
|
106041
|
+
// src/tools/apply-patch.ts
|
|
106042
|
+
init_zod();
|
|
106043
|
+
init_path_security();
|
|
106044
|
+
init_create_tool();
|
|
106045
|
+
import {
|
|
106046
|
+
existsSync as existsSync58,
|
|
106047
|
+
mkdirSync as mkdirSync27,
|
|
106048
|
+
mkdtempSync as mkdtempSync2,
|
|
106049
|
+
readFileSync as readFileSync39,
|
|
106050
|
+
realpathSync as realpathSync13,
|
|
106051
|
+
renameSync as renameSync20,
|
|
106052
|
+
rmdirSync,
|
|
106053
|
+
unlinkSync as unlinkSync17,
|
|
106054
|
+
writeFileSync as writeFileSync20
|
|
106055
|
+
} from "node:fs";
|
|
106056
|
+
import * as path109 from "node:path";
|
|
106057
|
+
var WINDOWS_RESERVED_NAMES2 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
106058
|
+
var MAX_PATCH_SIZE = 500000;
|
|
106059
|
+
function containsWindowsAttacks2(filePath) {
|
|
106060
|
+
if (/:[^\\/]/.test(filePath))
|
|
106061
|
+
return true;
|
|
106062
|
+
const parts2 = filePath.split(/[/\\]/);
|
|
106063
|
+
for (const part of parts2) {
|
|
106064
|
+
if (WINDOWS_RESERVED_NAMES2.test(part))
|
|
106065
|
+
return true;
|
|
106066
|
+
}
|
|
106067
|
+
return false;
|
|
106068
|
+
}
|
|
106069
|
+
function isProtectedPath2(filePath) {
|
|
106070
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
106071
|
+
const segments = normalized.split("/");
|
|
106072
|
+
return segments.some((seg) => seg === ".git" || seg === ".swarm");
|
|
106073
|
+
}
|
|
106074
|
+
function containsStrictControlChars(str) {
|
|
106075
|
+
for (let i2 = 0;i2 < str.length; i2++) {
|
|
106076
|
+
const c = str.charCodeAt(i2);
|
|
106077
|
+
if (c <= 31 && c !== 9 && c !== 10 && c !== 13)
|
|
106078
|
+
return true;
|
|
106079
|
+
}
|
|
106080
|
+
return false;
|
|
106081
|
+
}
|
|
106082
|
+
function isCanonicalProtectedPath(targetPath, workspace) {
|
|
106083
|
+
try {
|
|
106084
|
+
const canonicalTarget = realpathSync13(targetPath);
|
|
106085
|
+
const canonicalWorkspace = realpathSync13(workspace);
|
|
106086
|
+
const relative21 = path109.relative(canonicalWorkspace, canonicalTarget).replace(/\\/g, "/");
|
|
106087
|
+
const segments = relative21.split("/").filter(Boolean);
|
|
106088
|
+
return segments.some((seg) => seg === ".git" || seg === ".swarm");
|
|
106089
|
+
} catch {
|
|
106090
|
+
const parentDir = path109.dirname(targetPath);
|
|
106091
|
+
if (parentDir === targetPath)
|
|
106092
|
+
return false;
|
|
106093
|
+
try {
|
|
106094
|
+
const canonicalParent = realpathSync13(parentDir);
|
|
106095
|
+
const canonicalWorkspace = realpathSync13(workspace);
|
|
106096
|
+
const relative21 = path109.relative(canonicalWorkspace, canonicalParent).replace(/\\/g, "/");
|
|
106097
|
+
const segments = relative21.split("/").filter(Boolean);
|
|
106098
|
+
return segments.some((seg) => seg === ".git" || seg === ".swarm");
|
|
106099
|
+
} catch {
|
|
106100
|
+
return false;
|
|
106101
|
+
}
|
|
106102
|
+
}
|
|
106103
|
+
}
|
|
106104
|
+
function isCanonicalPathWithinWorkspace(targetPath, workspaceRoot) {
|
|
106105
|
+
try {
|
|
106106
|
+
const canonicalTarget = realpathSync13(targetPath);
|
|
106107
|
+
const canonicalWorkspace = realpathSync13(workspaceRoot);
|
|
106108
|
+
const relative21 = path109.relative(canonicalWorkspace, canonicalTarget);
|
|
106109
|
+
if (relative21.startsWith("..") || path109.isAbsolute(relative21))
|
|
106110
|
+
return false;
|
|
106111
|
+
const segments = relative21.replace(/\\/g, "/").split("/").filter(Boolean);
|
|
106112
|
+
if (segments.some((seg) => seg === ".git" || seg === ".swarm"))
|
|
106113
|
+
return false;
|
|
106114
|
+
return true;
|
|
106115
|
+
} catch {
|
|
106116
|
+
const parentDir = path109.dirname(targetPath);
|
|
106117
|
+
if (parentDir === targetPath) {
|
|
106118
|
+
return false;
|
|
106119
|
+
}
|
|
106120
|
+
try {
|
|
106121
|
+
const canonicalParent = realpathSync13(parentDir);
|
|
106122
|
+
const canonicalWorkspace = realpathSync13(workspaceRoot);
|
|
106123
|
+
const relative21 = path109.relative(canonicalWorkspace, canonicalParent);
|
|
106124
|
+
if (relative21.startsWith("..") || path109.isAbsolute(relative21))
|
|
106125
|
+
return false;
|
|
106126
|
+
const segments = relative21.replace(/\\/g, "/").split("/").filter(Boolean);
|
|
106127
|
+
if (segments.some((seg) => seg === ".git" || seg === ".swarm"))
|
|
106128
|
+
return false;
|
|
106129
|
+
return true;
|
|
106130
|
+
} catch {
|
|
106131
|
+
return false;
|
|
106132
|
+
}
|
|
106133
|
+
}
|
|
106134
|
+
}
|
|
106135
|
+
function validatePatchTargetPath(filePath, workspace) {
|
|
106136
|
+
if (!filePath || filePath.trim() === "") {
|
|
106137
|
+
return "Empty file path";
|
|
106138
|
+
}
|
|
106139
|
+
if (path109.isAbsolute(filePath) || /^[A-Za-z]:[/\\]/.test(filePath)) {
|
|
106140
|
+
return `Absolute path rejected: ${filePath}`;
|
|
106141
|
+
}
|
|
106142
|
+
if (containsPathTraversal(filePath)) {
|
|
106143
|
+
return `Path traversal detected: ${filePath}`;
|
|
106144
|
+
}
|
|
106145
|
+
if (containsStrictControlChars(filePath)) {
|
|
106146
|
+
return `Control characters detected in path: ${filePath}`;
|
|
106147
|
+
}
|
|
106148
|
+
if (containsControlChars(filePath)) {
|
|
106149
|
+
return `Control characters detected in path: ${filePath}`;
|
|
106150
|
+
}
|
|
106151
|
+
if (containsWindowsAttacks2(filePath)) {
|
|
106152
|
+
return `Windows reserved name or invalid path: ${filePath}`;
|
|
106153
|
+
}
|
|
106154
|
+
if (isProtectedPath2(filePath)) {
|
|
106155
|
+
return `Protected directory target rejected: ${filePath}`;
|
|
106156
|
+
}
|
|
106157
|
+
const resolved = path109.resolve(workspace, filePath);
|
|
106158
|
+
const relative21 = path109.relative(workspace, resolved);
|
|
106159
|
+
if (relative21.startsWith("..") || path109.isAbsolute(relative21)) {
|
|
106160
|
+
return `Path escapes workspace: ${filePath}`;
|
|
106161
|
+
}
|
|
106162
|
+
if (!isCanonicalPathWithinWorkspace(resolved, workspace)) {
|
|
106163
|
+
return `Path escapes workspace via symlink/junction: ${filePath}`;
|
|
106164
|
+
}
|
|
106165
|
+
return null;
|
|
106166
|
+
}
|
|
106167
|
+
function extractHeaderPath(header, prefix) {
|
|
106168
|
+
const trimmed = header.trim();
|
|
106169
|
+
if (!trimmed.startsWith(prefix))
|
|
106170
|
+
return null;
|
|
106171
|
+
const rest = trimmed.slice(prefix.length).trim();
|
|
106172
|
+
if (rest === "/dev/null")
|
|
106173
|
+
return "/dev/null";
|
|
106174
|
+
if (rest.startsWith("a/") || rest.startsWith("b/")) {
|
|
106175
|
+
const stripped = rest.slice(2);
|
|
106176
|
+
if (stripped.length === 0)
|
|
106177
|
+
return null;
|
|
106178
|
+
return stripped;
|
|
106179
|
+
}
|
|
106180
|
+
return rest.length > 0 ? rest : null;
|
|
106181
|
+
}
|
|
106182
|
+
function parseHunkHeader(line) {
|
|
106183
|
+
const match = line.match(/^@@\s*-(\d+)(?:,(\d+))?\s*\+(\d+)(?:,(\d+))?\s*@@/);
|
|
106184
|
+
if (!match)
|
|
106185
|
+
return null;
|
|
106186
|
+
return {
|
|
106187
|
+
oldStart: parseInt(match[1], 10),
|
|
106188
|
+
oldCount: match[2] !== undefined ? parseInt(match[2], 10) : 1,
|
|
106189
|
+
newStart: parseInt(match[3], 10),
|
|
106190
|
+
newCount: match[4] !== undefined ? parseInt(match[4], 10) : 1
|
|
106191
|
+
};
|
|
106192
|
+
}
|
|
106193
|
+
function parseUnifiedDiff(patchText) {
|
|
106194
|
+
if (patchText.length > MAX_PATCH_SIZE) {
|
|
106195
|
+
return {
|
|
106196
|
+
files: [],
|
|
106197
|
+
error: `Patch exceeds maximum size of ${MAX_PATCH_SIZE} characters`
|
|
106198
|
+
};
|
|
106199
|
+
}
|
|
106200
|
+
if (patchText.includes("\x00")) {
|
|
106201
|
+
return {
|
|
106202
|
+
files: [],
|
|
106203
|
+
error: "Binary content detected (null byte) — binary patches are not supported (FR-013)"
|
|
106204
|
+
};
|
|
106205
|
+
}
|
|
106206
|
+
const normalized = patchText.replace(/\r\n/g, `
|
|
106207
|
+
`).replace(/\r/g, `
|
|
106208
|
+
`);
|
|
106209
|
+
let lines = normalized.split(`
|
|
106210
|
+
`);
|
|
106211
|
+
if (lines.length > 0 && lines[lines.length - 1] === "") {
|
|
106212
|
+
lines = lines.slice(0, -1);
|
|
106213
|
+
}
|
|
106214
|
+
for (const line of lines) {
|
|
106215
|
+
if (line === "GIT binary patch" || line.startsWith("Binary files ")) {
|
|
106216
|
+
return { files: [], error: "Binary patches are not supported (FR-013)" };
|
|
106217
|
+
}
|
|
106218
|
+
if (line.startsWith("rename from") || line.startsWith("rename to") || line.startsWith("copy from") || line.startsWith("copy to")) {
|
|
106219
|
+
return {
|
|
106220
|
+
files: [],
|
|
106221
|
+
error: "Rename/copy patches are not supported (FR-013)"
|
|
106222
|
+
};
|
|
106223
|
+
}
|
|
106224
|
+
}
|
|
106225
|
+
const fileDiffs = [];
|
|
106226
|
+
let i2 = 0;
|
|
106227
|
+
while (i2 < lines.length) {
|
|
106228
|
+
let oldHeaderPath = null;
|
|
106229
|
+
let newHeaderPath = null;
|
|
106230
|
+
if (lines[i2].startsWith("diff --git ")) {
|
|
106231
|
+
i2++;
|
|
106232
|
+
while (i2 < lines.length && (lines[i2].startsWith("index ") || lines[i2].startsWith("old mode ") || lines[i2].startsWith("new mode ") || lines[i2].startsWith("deleted file ") || lines[i2].startsWith("new file ") || lines[i2].startsWith("similarity index ") || lines[i2].startsWith("dissimilarity index "))) {
|
|
106233
|
+
i2++;
|
|
106234
|
+
}
|
|
106235
|
+
}
|
|
106236
|
+
if (i2 < lines.length && lines[i2].startsWith("--- ")) {
|
|
106237
|
+
oldHeaderPath = extractHeaderPath(lines[i2], "--- ");
|
|
106238
|
+
i2++;
|
|
106239
|
+
} else if (oldHeaderPath === null) {
|
|
106240
|
+
i2++;
|
|
106241
|
+
continue;
|
|
106242
|
+
}
|
|
106243
|
+
if (i2 < lines.length && lines[i2].startsWith("+++ ")) {
|
|
106244
|
+
newHeaderPath = extractHeaderPath(lines[i2], "+++ ");
|
|
106245
|
+
i2++;
|
|
106246
|
+
} else {
|
|
106247
|
+
continue;
|
|
106248
|
+
}
|
|
106249
|
+
if (oldHeaderPath === null || newHeaderPath === null) {
|
|
106250
|
+
continue;
|
|
106251
|
+
}
|
|
106252
|
+
const isNewFile = oldHeaderPath === "/dev/null";
|
|
106253
|
+
const isDelete = newHeaderPath === "/dev/null";
|
|
106254
|
+
const targetPath = isDelete ? oldHeaderPath : newHeaderPath;
|
|
106255
|
+
if (targetPath === "/dev/null") {
|
|
106256
|
+
continue;
|
|
106257
|
+
}
|
|
106258
|
+
const hunks = [];
|
|
106259
|
+
while (i2 < lines.length && lines[i2].startsWith("@@")) {
|
|
106260
|
+
const header = parseHunkHeader(lines[i2]);
|
|
106261
|
+
if (!header) {
|
|
106262
|
+
i2++;
|
|
106263
|
+
continue;
|
|
106264
|
+
}
|
|
106265
|
+
i2++;
|
|
106266
|
+
const hunkLines = [];
|
|
106267
|
+
while (i2 < lines.length) {
|
|
106268
|
+
const line = lines[i2];
|
|
106269
|
+
if (line.startsWith("@@") || line.startsWith("diff --git ") || line.startsWith("--- ") || line.startsWith("+++ ")) {
|
|
106270
|
+
break;
|
|
106271
|
+
}
|
|
106272
|
+
if (line.startsWith("\\")) {
|
|
106273
|
+
i2++;
|
|
106274
|
+
continue;
|
|
106275
|
+
}
|
|
106276
|
+
if (line.length === 0) {
|
|
106277
|
+
break;
|
|
106278
|
+
}
|
|
106279
|
+
const firstChar = line[0];
|
|
106280
|
+
if (firstChar !== " " && firstChar !== "+" && firstChar !== "-") {
|
|
106281
|
+
break;
|
|
106282
|
+
}
|
|
106283
|
+
if (firstChar === "+") {
|
|
106284
|
+
hunkLines.push({ type: "addition", content: line.slice(1) });
|
|
106285
|
+
} else if (firstChar === "-") {
|
|
106286
|
+
hunkLines.push({ type: "removal", content: line.slice(1) });
|
|
106287
|
+
} else {
|
|
106288
|
+
hunkLines.push({ type: "context", content: line.slice(1) });
|
|
106289
|
+
}
|
|
106290
|
+
i2++;
|
|
106291
|
+
}
|
|
106292
|
+
hunks.push({
|
|
106293
|
+
oldStart: header.oldStart,
|
|
106294
|
+
oldCount: header.oldCount,
|
|
106295
|
+
newStart: header.newStart,
|
|
106296
|
+
newCount: header.newCount,
|
|
106297
|
+
lines: hunkLines
|
|
106298
|
+
});
|
|
106299
|
+
}
|
|
106300
|
+
if (hunks.length > 0) {
|
|
106301
|
+
fileDiffs.push({
|
|
106302
|
+
oldPath: oldHeaderPath,
|
|
106303
|
+
newPath: newHeaderPath,
|
|
106304
|
+
isNewFile,
|
|
106305
|
+
isDelete,
|
|
106306
|
+
hunks
|
|
106307
|
+
});
|
|
106308
|
+
} else {
|
|
106309
|
+
fileDiffs.push({
|
|
106310
|
+
oldPath: oldHeaderPath,
|
|
106311
|
+
newPath: newHeaderPath,
|
|
106312
|
+
isNewFile,
|
|
106313
|
+
isDelete,
|
|
106314
|
+
hunks: []
|
|
106315
|
+
});
|
|
106316
|
+
}
|
|
106317
|
+
}
|
|
106318
|
+
return { files: fileDiffs, error: null };
|
|
106319
|
+
}
|
|
106320
|
+
function arraysEqual(a, b) {
|
|
106321
|
+
if (a.length !== b.length)
|
|
106322
|
+
return false;
|
|
106323
|
+
for (let idx = 0;idx < a.length; idx++) {
|
|
106324
|
+
if (a[idx] !== b[idx])
|
|
106325
|
+
return false;
|
|
106326
|
+
}
|
|
106327
|
+
return true;
|
|
106328
|
+
}
|
|
106329
|
+
function applyHunks(content, fileDiff) {
|
|
106330
|
+
const normalizedContent = content.replace(/\r\n/g, `
|
|
106331
|
+
`);
|
|
106332
|
+
const fileLines = normalizedContent.split(`
|
|
106333
|
+
`);
|
|
106334
|
+
if (fileDiff.isNewFile) {
|
|
106335
|
+
const newLines = [];
|
|
106336
|
+
for (const hunk of fileDiff.hunks) {
|
|
106337
|
+
for (const line of hunk.lines) {
|
|
106338
|
+
if (line.type === "addition" || line.type === "context") {
|
|
106339
|
+
newLines.push(line.content);
|
|
106340
|
+
}
|
|
106341
|
+
}
|
|
106342
|
+
}
|
|
106343
|
+
return { success: true, appliedLines: newLines };
|
|
106344
|
+
}
|
|
106345
|
+
if (fileDiff.isDelete) {
|
|
106346
|
+
return { success: true, appliedLines: [] };
|
|
106347
|
+
}
|
|
106348
|
+
let accumulatedDelta = 0;
|
|
106349
|
+
for (let hunkIdx = 0;hunkIdx < fileDiff.hunks.length; hunkIdx++) {
|
|
106350
|
+
const hunk = fileDiff.hunks[hunkIdx];
|
|
106351
|
+
const searchStart = Math.max(0, hunk.oldStart - 1 + accumulatedDelta);
|
|
106352
|
+
const expectedOldLines = [];
|
|
106353
|
+
const newLinesForHunk = [];
|
|
106354
|
+
for (const line of hunk.lines) {
|
|
106355
|
+
if (line.type === "context") {
|
|
106356
|
+
expectedOldLines.push(line.content);
|
|
106357
|
+
newLinesForHunk.push(line.content);
|
|
106358
|
+
} else if (line.type === "removal") {
|
|
106359
|
+
expectedOldLines.push(line.content);
|
|
106360
|
+
} else if (line.type === "addition") {
|
|
106361
|
+
newLinesForHunk.push(line.content);
|
|
106362
|
+
}
|
|
106363
|
+
}
|
|
106364
|
+
const exactOffset = searchStart;
|
|
106365
|
+
const matchFound = exactOffset <= fileLines.length - expectedOldLines.length && arraysEqual(fileLines.slice(exactOffset, exactOffset + expectedOldLines.length), expectedOldLines);
|
|
106366
|
+
if (matchFound) {
|
|
106367
|
+
fileLines.splice(exactOffset, expectedOldLines.length, ...newLinesForHunk);
|
|
106368
|
+
const delta = newLinesForHunk.length - expectedOldLines.length;
|
|
106369
|
+
accumulatedDelta += delta;
|
|
106370
|
+
}
|
|
106371
|
+
if (!matchFound) {
|
|
106372
|
+
const diagStart = Math.min(searchStart, fileLines.length);
|
|
106373
|
+
const diagEnd = Math.min(diagStart + expectedOldLines.length, fileLines.length);
|
|
106374
|
+
const actualContent = fileLines.slice(diagStart, diagEnd).join(`
|
|
106375
|
+
`);
|
|
106376
|
+
const expectedContent = expectedOldLines.join(`
|
|
106377
|
+
`);
|
|
106378
|
+
return {
|
|
106379
|
+
success: false,
|
|
106380
|
+
failedHunkIndex: hunkIdx,
|
|
106381
|
+
error: {
|
|
106382
|
+
hunkIndex: hunkIdx,
|
|
106383
|
+
type: "context-mismatch",
|
|
106384
|
+
message: `Context mismatch in hunk ${hunkIdx + 1} at line ${searchStart + 1}: expected context does not match file content`,
|
|
106385
|
+
expected: expectedContent.length > 200 ? `${expectedContent.slice(0, 200)}... (truncated)` : expectedContent,
|
|
106386
|
+
actual: actualContent.length > 200 ? `${actualContent.slice(0, 200)}... (truncated)` : actualContent,
|
|
106387
|
+
line: searchStart + 1
|
|
106388
|
+
}
|
|
106389
|
+
};
|
|
106390
|
+
}
|
|
106391
|
+
}
|
|
106392
|
+
return { success: true, appliedLines: fileLines };
|
|
106393
|
+
}
|
|
106394
|
+
function atomicWriteFileSync(targetPath, content) {
|
|
106395
|
+
const dir = path109.dirname(targetPath);
|
|
106396
|
+
mkdirSync27(dir, { recursive: true });
|
|
106397
|
+
const tempPrefix = `.apply-patch-${Date.now()}-${process.pid}`;
|
|
106398
|
+
let tempPath;
|
|
106399
|
+
try {
|
|
106400
|
+
const tempDir = realpathSync13(mkdtempSync2(path109.join(dir, tempPrefix)));
|
|
106401
|
+
tempPath = path109.join(tempDir, "content");
|
|
106402
|
+
} catch {
|
|
106403
|
+
tempPath = path109.join(dir, `${tempPrefix}.tmp`);
|
|
106404
|
+
}
|
|
106405
|
+
try {
|
|
106406
|
+
writeFileSync20(tempPath, content, "utf-8");
|
|
106407
|
+
renameSync20(tempPath, targetPath);
|
|
106408
|
+
} finally {
|
|
106409
|
+
if (existsSync58(tempPath)) {
|
|
106410
|
+
try {
|
|
106411
|
+
unlinkSync17(tempPath);
|
|
106412
|
+
} catch {}
|
|
106413
|
+
}
|
|
106414
|
+
const tempDir = path109.dirname(tempPath);
|
|
106415
|
+
if (tempDir !== dir && existsSync58(tempDir)) {
|
|
106416
|
+
try {
|
|
106417
|
+
rmdirSync(tempDir);
|
|
106418
|
+
} catch {}
|
|
106419
|
+
}
|
|
106420
|
+
}
|
|
106421
|
+
}
|
|
106422
|
+
function detectLineEnding(content) {
|
|
106423
|
+
return content.includes(`\r
|
|
106424
|
+
`) ? `\r
|
|
106425
|
+
` : `
|
|
106426
|
+
`;
|
|
106427
|
+
}
|
|
106428
|
+
function ensureFinalNewline(content, originalEndsWithNewline) {
|
|
106429
|
+
if (originalEndsWithNewline && !content.endsWith(`
|
|
106430
|
+
`)) {
|
|
106431
|
+
return `${content}
|
|
106432
|
+
`;
|
|
106433
|
+
}
|
|
106434
|
+
if (!originalEndsWithNewline && content.endsWith(`
|
|
106435
|
+
`)) {
|
|
106436
|
+
return content.slice(0, -1);
|
|
106437
|
+
}
|
|
106438
|
+
return content;
|
|
106439
|
+
}
|
|
106440
|
+
function processFileDiff(fileDiff, targetPath, fullPath, workspace, dryRun, allowCreates, allowDeletes) {
|
|
106441
|
+
const hunksTotal = fileDiff.hunks.length;
|
|
106442
|
+
if (!isCanonicalPathWithinWorkspace(fullPath, workspace)) {
|
|
106443
|
+
return {
|
|
106444
|
+
file: targetPath,
|
|
106445
|
+
status: "error",
|
|
106446
|
+
hunks: hunksTotal,
|
|
106447
|
+
hunksApplied: 0,
|
|
106448
|
+
hunksFailed: hunksTotal,
|
|
106449
|
+
errors: [
|
|
106450
|
+
{
|
|
106451
|
+
hunkIndex: 0,
|
|
106452
|
+
type: "context-mismatch",
|
|
106453
|
+
message: `Path escapes workspace via symlink/junction: ${targetPath}`
|
|
106454
|
+
}
|
|
106455
|
+
]
|
|
106456
|
+
};
|
|
106457
|
+
}
|
|
106458
|
+
if (isCanonicalProtectedPath(fullPath, workspace)) {
|
|
106459
|
+
return {
|
|
106460
|
+
file: targetPath,
|
|
106461
|
+
status: "error",
|
|
106462
|
+
hunks: hunksTotal,
|
|
106463
|
+
hunksApplied: 0,
|
|
106464
|
+
hunksFailed: hunksTotal,
|
|
106465
|
+
errors: [
|
|
106466
|
+
{
|
|
106467
|
+
hunkIndex: 0,
|
|
106468
|
+
type: "context-mismatch",
|
|
106469
|
+
message: `Protected directory target rejected via symlink: ${targetPath}`
|
|
106470
|
+
}
|
|
106471
|
+
]
|
|
106472
|
+
};
|
|
106473
|
+
}
|
|
106474
|
+
if (fileDiff.isNewFile) {
|
|
106475
|
+
if (!allowCreates) {
|
|
106476
|
+
return {
|
|
106477
|
+
file: targetPath,
|
|
106478
|
+
status: "error",
|
|
106479
|
+
hunks: hunksTotal,
|
|
106480
|
+
hunksApplied: 0,
|
|
106481
|
+
hunksFailed: hunksTotal,
|
|
106482
|
+
errors: [
|
|
106483
|
+
{
|
|
106484
|
+
hunkIndex: 0,
|
|
106485
|
+
type: "create-not-allowed",
|
|
106486
|
+
message: `New file creation not allowed: ${targetPath} (set allowCreates to true)`
|
|
106487
|
+
}
|
|
106488
|
+
]
|
|
106489
|
+
};
|
|
106490
|
+
}
|
|
106491
|
+
const parentDir = path109.dirname(fullPath);
|
|
106492
|
+
if (!existsSync58(parentDir)) {
|
|
106493
|
+
return {
|
|
106494
|
+
file: targetPath,
|
|
106495
|
+
status: "error",
|
|
106496
|
+
hunks: hunksTotal,
|
|
106497
|
+
hunksApplied: 0,
|
|
106498
|
+
hunksFailed: hunksTotal,
|
|
106499
|
+
errors: [
|
|
106500
|
+
{
|
|
106501
|
+
hunkIndex: 0,
|
|
106502
|
+
type: "file-not-found",
|
|
106503
|
+
message: `Parent directory does not exist: ${parentDir}`
|
|
106504
|
+
}
|
|
106505
|
+
]
|
|
106506
|
+
};
|
|
106507
|
+
}
|
|
106508
|
+
if (existsSync58(fullPath)) {
|
|
106509
|
+
return {
|
|
106510
|
+
file: targetPath,
|
|
106511
|
+
status: "error",
|
|
106512
|
+
hunks: hunksTotal,
|
|
106513
|
+
hunksApplied: 0,
|
|
106514
|
+
hunksFailed: hunksTotal,
|
|
106515
|
+
errors: [
|
|
106516
|
+
{
|
|
106517
|
+
hunkIndex: 0,
|
|
106518
|
+
type: "file-not-found",
|
|
106519
|
+
message: `File already exists: ${targetPath} (cannot create — patch may be stale)`
|
|
106520
|
+
}
|
|
106521
|
+
]
|
|
106522
|
+
};
|
|
106523
|
+
}
|
|
106524
|
+
if (hunksTotal === 0) {
|
|
106525
|
+
return {
|
|
106526
|
+
file: targetPath,
|
|
106527
|
+
status: "no-changes",
|
|
106528
|
+
hunks: 0,
|
|
106529
|
+
hunksApplied: 0,
|
|
106530
|
+
hunksFailed: 0
|
|
106531
|
+
};
|
|
106532
|
+
}
|
|
106533
|
+
const hunkResult2 = applyHunks("", fileDiff);
|
|
106534
|
+
if (!hunkResult2.success || !hunkResult2.appliedLines) {
|
|
106535
|
+
return {
|
|
106536
|
+
file: targetPath,
|
|
106537
|
+
status: "error",
|
|
106538
|
+
hunks: hunksTotal,
|
|
106539
|
+
hunksApplied: 0,
|
|
106540
|
+
hunksFailed: hunksTotal,
|
|
106541
|
+
errors: hunkResult2.error ? [hunkResult2.error] : []
|
|
106542
|
+
};
|
|
106543
|
+
}
|
|
106544
|
+
if (!dryRun) {
|
|
106545
|
+
const content2 = ensureFinalNewline(hunkResult2.appliedLines.join(`
|
|
106546
|
+
`), true);
|
|
106547
|
+
atomicWriteFileSync(fullPath, content2);
|
|
106548
|
+
}
|
|
106549
|
+
return {
|
|
106550
|
+
file: targetPath,
|
|
106551
|
+
status: "created",
|
|
106552
|
+
hunks: hunksTotal,
|
|
106553
|
+
hunksApplied: hunksTotal,
|
|
106554
|
+
hunksFailed: 0
|
|
106555
|
+
};
|
|
106556
|
+
}
|
|
106557
|
+
if (fileDiff.isDelete) {
|
|
106558
|
+
if (hunksTotal === 0) {
|
|
106559
|
+
return {
|
|
106560
|
+
file: targetPath,
|
|
106561
|
+
status: "no-changes",
|
|
106562
|
+
hunks: 0,
|
|
106563
|
+
hunksApplied: 0,
|
|
106564
|
+
hunksFailed: 0
|
|
106565
|
+
};
|
|
106566
|
+
}
|
|
106567
|
+
if (!allowDeletes) {
|
|
106568
|
+
return {
|
|
106569
|
+
file: targetPath,
|
|
106570
|
+
status: "error",
|
|
106571
|
+
hunks: hunksTotal,
|
|
106572
|
+
hunksApplied: 0,
|
|
106573
|
+
hunksFailed: hunksTotal,
|
|
106574
|
+
errors: [
|
|
106575
|
+
{
|
|
106576
|
+
hunkIndex: 0,
|
|
106577
|
+
type: "delete-not-allowed",
|
|
106578
|
+
message: `File deletion not allowed: ${targetPath} (set allowDeletes to true)`
|
|
106579
|
+
}
|
|
106580
|
+
]
|
|
106581
|
+
};
|
|
106582
|
+
}
|
|
106583
|
+
if (!existsSync58(fullPath)) {
|
|
106584
|
+
return {
|
|
106585
|
+
file: targetPath,
|
|
106586
|
+
status: "error",
|
|
106587
|
+
hunks: hunksTotal,
|
|
106588
|
+
hunksApplied: 0,
|
|
106589
|
+
hunksFailed: hunksTotal,
|
|
106590
|
+
errors: [
|
|
106591
|
+
{
|
|
106592
|
+
hunkIndex: 0,
|
|
106593
|
+
type: "file-not-found",
|
|
106594
|
+
message: `File not found for deletion: ${targetPath}`
|
|
106595
|
+
}
|
|
106596
|
+
]
|
|
106597
|
+
};
|
|
106598
|
+
}
|
|
106599
|
+
if (!dryRun) {
|
|
106600
|
+
try {
|
|
106601
|
+
unlinkSync17(fullPath);
|
|
106602
|
+
} catch (err2) {
|
|
106603
|
+
return {
|
|
106604
|
+
file: targetPath,
|
|
106605
|
+
status: "error",
|
|
106606
|
+
hunks: hunksTotal,
|
|
106607
|
+
hunksApplied: 0,
|
|
106608
|
+
hunksFailed: hunksTotal,
|
|
106609
|
+
errors: [
|
|
106610
|
+
{
|
|
106611
|
+
hunkIndex: 0,
|
|
106612
|
+
type: "file-not-found",
|
|
106613
|
+
message: `Failed to delete file: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
106614
|
+
}
|
|
106615
|
+
]
|
|
106616
|
+
};
|
|
106617
|
+
}
|
|
106618
|
+
}
|
|
106619
|
+
return {
|
|
106620
|
+
file: targetPath,
|
|
106621
|
+
status: "applied",
|
|
106622
|
+
hunks: hunksTotal,
|
|
106623
|
+
hunksApplied: hunksTotal,
|
|
106624
|
+
hunksFailed: 0
|
|
106625
|
+
};
|
|
106626
|
+
}
|
|
106627
|
+
if (!existsSync58(fullPath)) {
|
|
106628
|
+
return {
|
|
106629
|
+
file: targetPath,
|
|
106630
|
+
status: "error",
|
|
106631
|
+
hunks: hunksTotal,
|
|
106632
|
+
hunksApplied: 0,
|
|
106633
|
+
hunksFailed: hunksTotal,
|
|
106634
|
+
errors: [
|
|
106635
|
+
{
|
|
106636
|
+
hunkIndex: 0,
|
|
106637
|
+
type: "file-not-found",
|
|
106638
|
+
message: `File not found: ${targetPath}`
|
|
106639
|
+
}
|
|
106640
|
+
]
|
|
106641
|
+
};
|
|
106642
|
+
}
|
|
106643
|
+
let content;
|
|
106644
|
+
try {
|
|
106645
|
+
content = readFileSync39(fullPath, "utf-8");
|
|
106646
|
+
} catch (err2) {
|
|
106647
|
+
return {
|
|
106648
|
+
file: targetPath,
|
|
106649
|
+
status: "error",
|
|
106650
|
+
hunks: hunksTotal,
|
|
106651
|
+
hunksApplied: 0,
|
|
106652
|
+
hunksFailed: hunksTotal,
|
|
106653
|
+
errors: [
|
|
106654
|
+
{
|
|
106655
|
+
hunkIndex: 0,
|
|
106656
|
+
type: "file-not-found",
|
|
106657
|
+
message: `Could not read file: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
106658
|
+
}
|
|
106659
|
+
]
|
|
106660
|
+
};
|
|
106661
|
+
}
|
|
106662
|
+
if (hunksTotal === 0) {
|
|
106663
|
+
return {
|
|
106664
|
+
file: targetPath,
|
|
106665
|
+
status: "no-changes",
|
|
106666
|
+
hunks: 0,
|
|
106667
|
+
hunksApplied: 0,
|
|
106668
|
+
hunksFailed: 0
|
|
106669
|
+
};
|
|
106670
|
+
}
|
|
106671
|
+
const originalEndsWithNewline = content.endsWith(`
|
|
106672
|
+
`);
|
|
106673
|
+
const originalLineEnding = detectLineEnding(content);
|
|
106674
|
+
const hunkResult = applyHunks(content, fileDiff);
|
|
106675
|
+
if (!hunkResult.success) {
|
|
106676
|
+
return {
|
|
106677
|
+
file: targetPath,
|
|
106678
|
+
status: "error",
|
|
106679
|
+
hunks: hunksTotal,
|
|
106680
|
+
hunksApplied: 0,
|
|
106681
|
+
hunksFailed: hunksTotal,
|
|
106682
|
+
errors: hunkResult.error ? [hunkResult.error] : []
|
|
106683
|
+
};
|
|
106684
|
+
}
|
|
106685
|
+
const resultContent = hunkResult.appliedLines.join(`
|
|
106686
|
+
`);
|
|
106687
|
+
if (resultContent === "" && !dryRun && !allowDeletes && content.length > 0) {
|
|
106688
|
+
return {
|
|
106689
|
+
file: targetPath,
|
|
106690
|
+
status: "error",
|
|
106691
|
+
hunks: hunksTotal,
|
|
106692
|
+
hunksApplied: hunksTotal,
|
|
106693
|
+
hunksFailed: 0,
|
|
106694
|
+
errors: [
|
|
106695
|
+
{
|
|
106696
|
+
hunkIndex: 0,
|
|
106697
|
+
type: "delete-not-allowed",
|
|
106698
|
+
message: `Patch would delete all content from ${targetPath}. Set allowDeletes to true to permit file deletion.`
|
|
106699
|
+
}
|
|
106700
|
+
]
|
|
106701
|
+
};
|
|
106702
|
+
}
|
|
106703
|
+
let finalContent;
|
|
106704
|
+
if (resultContent === "") {
|
|
106705
|
+
finalContent = "";
|
|
106706
|
+
} else {
|
|
106707
|
+
const withLineEnding = originalLineEnding === `\r
|
|
106708
|
+
` ? resultContent.replace(/\n/g, `\r
|
|
106709
|
+
`) : resultContent;
|
|
106710
|
+
finalContent = ensureFinalNewline(withLineEnding, originalEndsWithNewline);
|
|
106711
|
+
}
|
|
106712
|
+
if (finalContent === content) {
|
|
106713
|
+
return {
|
|
106714
|
+
file: targetPath,
|
|
106715
|
+
status: "no-changes",
|
|
106716
|
+
hunks: hunksTotal,
|
|
106717
|
+
hunksApplied: hunksTotal,
|
|
106718
|
+
hunksFailed: 0
|
|
106719
|
+
};
|
|
106720
|
+
}
|
|
106721
|
+
if (!dryRun) {
|
|
106722
|
+
atomicWriteFileSync(fullPath, finalContent);
|
|
106723
|
+
}
|
|
106724
|
+
return {
|
|
106725
|
+
file: targetPath,
|
|
106726
|
+
status: "applied",
|
|
106727
|
+
hunks: hunksTotal,
|
|
106728
|
+
hunksApplied: hunksTotal,
|
|
106729
|
+
hunksFailed: 0
|
|
106730
|
+
};
|
|
106731
|
+
}
|
|
106732
|
+
function buildErrorResult(message) {
|
|
106733
|
+
return {
|
|
106734
|
+
success: false,
|
|
106735
|
+
files: [
|
|
106736
|
+
{
|
|
106737
|
+
file: "",
|
|
106738
|
+
status: "error",
|
|
106739
|
+
hunks: 0,
|
|
106740
|
+
hunksApplied: 0,
|
|
106741
|
+
hunksFailed: 0,
|
|
106742
|
+
errors: [
|
|
106743
|
+
{
|
|
106744
|
+
hunkIndex: 0,
|
|
106745
|
+
type: "context-mismatch",
|
|
106746
|
+
message
|
|
106747
|
+
}
|
|
106748
|
+
]
|
|
106749
|
+
}
|
|
106750
|
+
],
|
|
106751
|
+
summary: {
|
|
106752
|
+
totalFiles: 0,
|
|
106753
|
+
applied: 0,
|
|
106754
|
+
failed: 1,
|
|
106755
|
+
totalHunks: 0
|
|
106756
|
+
}
|
|
106757
|
+
};
|
|
106758
|
+
}
|
|
106759
|
+
var applyPatch = createSwarmTool({
|
|
106760
|
+
description: "Apply a unified diff patch to workspace files. Validates paths, matches context exactly, and writes atomically. Coder-scoped write tool.",
|
|
106761
|
+
args: {
|
|
106762
|
+
patch: exports_external.string().min(1).describe("Unified diff text to parse and apply"),
|
|
106763
|
+
files: exports_external.array(exports_external.string()).min(1).describe("Array of target file paths the patch is expected to touch. Every parsed target must appear in this list."),
|
|
106764
|
+
dryRun: exports_external.boolean().optional().default(false).describe("Validate without writing files (default: false)"),
|
|
106765
|
+
allowCreates: exports_external.boolean().optional().default(false).describe("Allow creating new files from patches with --- /dev/null (default: false)"),
|
|
106766
|
+
allowDeletes: exports_external.boolean().optional().default(false).describe("Allow deleting files from patches with +++ /dev/null (default: false)")
|
|
106767
|
+
},
|
|
106768
|
+
execute: async (args2, directory) => {
|
|
106769
|
+
if (!args2 || typeof args2 !== "object") {
|
|
106770
|
+
return JSON.stringify(buildErrorResult("Could not parse apply_patch arguments"), null, 2);
|
|
106771
|
+
}
|
|
106772
|
+
const obj = args2;
|
|
106773
|
+
const patchText = obj.patch ?? "";
|
|
106774
|
+
const files = obj.files ?? [];
|
|
106775
|
+
const dryRun = obj.dryRun ?? false;
|
|
106776
|
+
const allowCreates = obj.allowCreates ?? false;
|
|
106777
|
+
const allowDeletes = obj.allowDeletes ?? false;
|
|
106778
|
+
if (!existsSync58(directory)) {
|
|
106779
|
+
return JSON.stringify(buildErrorResult("Workspace directory does not exist"), null, 2);
|
|
106780
|
+
}
|
|
106781
|
+
if (files.length === 0) {
|
|
106782
|
+
return JSON.stringify(buildErrorResult("files array cannot be empty"), null, 2);
|
|
106783
|
+
}
|
|
106784
|
+
if (!patchText || patchText.trim() === "") {
|
|
106785
|
+
return JSON.stringify(buildErrorResult("patch text cannot be empty"), null, 2);
|
|
106786
|
+
}
|
|
106787
|
+
for (const filePath of files) {
|
|
106788
|
+
const validationError = validatePatchTargetPath(filePath, directory);
|
|
106789
|
+
if (validationError) {
|
|
106790
|
+
return JSON.stringify(buildErrorResult(validationError), null, 2);
|
|
106791
|
+
}
|
|
106792
|
+
}
|
|
106793
|
+
const { files: parsedFiles, error: parseError } = parseUnifiedDiff(patchText);
|
|
106794
|
+
if (parseError) {
|
|
106795
|
+
return JSON.stringify(buildErrorResult(parseError), null, 2);
|
|
106796
|
+
}
|
|
106797
|
+
if (parsedFiles.length === 0) {
|
|
106798
|
+
return JSON.stringify({
|
|
106799
|
+
success: true,
|
|
106800
|
+
dryRun,
|
|
106801
|
+
files: [],
|
|
106802
|
+
summary: { totalFiles: 0, applied: 0, failed: 0, totalHunks: 0 }
|
|
106803
|
+
}, null, 2);
|
|
106804
|
+
}
|
|
106805
|
+
const declaredFileSet = new Set(files);
|
|
106806
|
+
const undeclaredTargets = [];
|
|
106807
|
+
for (const fileDiff of parsedFiles) {
|
|
106808
|
+
const targetPath = fileDiff.isDelete ? fileDiff.oldPath : fileDiff.newPath;
|
|
106809
|
+
if (targetPath && targetPath !== "/dev/null" && !declaredFileSet.has(targetPath)) {
|
|
106810
|
+
undeclaredTargets.push(targetPath);
|
|
106811
|
+
}
|
|
106812
|
+
}
|
|
106813
|
+
if (undeclaredTargets.length > 0) {
|
|
106814
|
+
return JSON.stringify(buildErrorResult(`Patch targets files not in the declared files array: ${undeclaredTargets.join(", ")}`), null, 2);
|
|
106815
|
+
}
|
|
106816
|
+
const parsedTargetSet = new Set(parsedFiles.map((fd) => fd.isDelete ? fd.oldPath : fd.newPath).filter(Boolean));
|
|
106817
|
+
const extraFiles = files.filter((f) => !parsedTargetSet.has(f));
|
|
106818
|
+
const fileResults = [];
|
|
106819
|
+
let totalApplied = 0;
|
|
106820
|
+
let totalFailed = 0;
|
|
106821
|
+
let totalHunks = 0;
|
|
106822
|
+
for (const fileDiff of parsedFiles) {
|
|
106823
|
+
const targetPath = fileDiff.isDelete ? fileDiff.oldPath : fileDiff.newPath;
|
|
106824
|
+
const fullPath = path109.resolve(directory, targetPath);
|
|
106825
|
+
totalHunks += fileDiff.hunks.length;
|
|
106826
|
+
const result = processFileDiff(fileDiff, targetPath, fullPath, directory, dryRun, allowCreates, allowDeletes);
|
|
106827
|
+
fileResults.push(result);
|
|
106828
|
+
if (result.status === "applied" || result.status === "created") {
|
|
106829
|
+
totalApplied++;
|
|
106830
|
+
} else if (result.status === "error") {
|
|
106831
|
+
totalFailed++;
|
|
106832
|
+
}
|
|
106833
|
+
}
|
|
106834
|
+
const output = {
|
|
106835
|
+
success: totalFailed === 0,
|
|
106836
|
+
dryRun,
|
|
106837
|
+
files: fileResults,
|
|
106838
|
+
summary: {
|
|
106839
|
+
totalFiles: fileResults.length,
|
|
106840
|
+
applied: totalApplied,
|
|
106841
|
+
failed: totalFailed,
|
|
106842
|
+
totalHunks
|
|
106843
|
+
}
|
|
106844
|
+
};
|
|
106845
|
+
if (extraFiles.length > 0) {
|
|
106846
|
+
return JSON.stringify({
|
|
106847
|
+
...output,
|
|
106848
|
+
warnings: [
|
|
106849
|
+
`files[] contains entries not targeted by the patch: ${extraFiles.join(", ")}`
|
|
106850
|
+
]
|
|
106851
|
+
}, null, 2);
|
|
106852
|
+
}
|
|
106853
|
+
return JSON.stringify(output, null, 2);
|
|
106854
|
+
}
|
|
106855
|
+
});
|
|
106856
|
+
|
|
106000
106857
|
// src/tools/batch-symbols.ts
|
|
106001
106858
|
init_dist();
|
|
106002
106859
|
init_create_tool();
|
|
106003
106860
|
import * as fs72 from "node:fs";
|
|
106004
|
-
import * as
|
|
106861
|
+
import * as path110 from "node:path";
|
|
106005
106862
|
init_path_security();
|
|
106006
|
-
var
|
|
106007
|
-
function
|
|
106863
|
+
var WINDOWS_RESERVED_NAMES3 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
106864
|
+
function containsWindowsAttacks3(str) {
|
|
106008
106865
|
if (/:[^\\/]/.test(str)) {
|
|
106009
106866
|
return true;
|
|
106010
106867
|
}
|
|
106011
106868
|
const parts2 = str.split(/[/\\]/);
|
|
106012
106869
|
for (const part of parts2) {
|
|
106013
|
-
if (
|
|
106870
|
+
if (WINDOWS_RESERVED_NAMES3.test(part)) {
|
|
106014
106871
|
return true;
|
|
106015
106872
|
}
|
|
106016
106873
|
}
|
|
@@ -106018,14 +106875,14 @@ function containsWindowsAttacks2(str) {
|
|
|
106018
106875
|
}
|
|
106019
106876
|
function isPathInWorkspace2(filePath, workspace) {
|
|
106020
106877
|
try {
|
|
106021
|
-
const resolvedPath =
|
|
106878
|
+
const resolvedPath = path110.resolve(workspace, filePath);
|
|
106022
106879
|
if (!fs72.existsSync(resolvedPath)) {
|
|
106023
106880
|
return true;
|
|
106024
106881
|
}
|
|
106025
106882
|
const realWorkspace = fs72.realpathSync(workspace);
|
|
106026
106883
|
const realResolvedPath = fs72.realpathSync(resolvedPath);
|
|
106027
|
-
const relativePath =
|
|
106028
|
-
if (relativePath.startsWith("..") ||
|
|
106884
|
+
const relativePath = path110.relative(realWorkspace, realResolvedPath);
|
|
106885
|
+
if (relativePath.startsWith("..") || path110.isAbsolute(relativePath)) {
|
|
106029
106886
|
return false;
|
|
106030
106887
|
}
|
|
106031
106888
|
return true;
|
|
@@ -106034,7 +106891,7 @@ function isPathInWorkspace2(filePath, workspace) {
|
|
|
106034
106891
|
}
|
|
106035
106892
|
}
|
|
106036
106893
|
function processFile2(file3, cwd, exportedOnly) {
|
|
106037
|
-
const ext =
|
|
106894
|
+
const ext = path110.extname(file3);
|
|
106038
106895
|
if (containsControlChars(file3)) {
|
|
106039
106896
|
return {
|
|
106040
106897
|
file: file3,
|
|
@@ -106051,7 +106908,7 @@ function processFile2(file3, cwd, exportedOnly) {
|
|
|
106051
106908
|
errorType: "path-traversal"
|
|
106052
106909
|
};
|
|
106053
106910
|
}
|
|
106054
|
-
if (
|
|
106911
|
+
if (containsWindowsAttacks3(file3)) {
|
|
106055
106912
|
return {
|
|
106056
106913
|
file: file3,
|
|
106057
106914
|
success: false,
|
|
@@ -106067,7 +106924,7 @@ function processFile2(file3, cwd, exportedOnly) {
|
|
|
106067
106924
|
errorType: "path-outside-workspace"
|
|
106068
106925
|
};
|
|
106069
106926
|
}
|
|
106070
|
-
const fullPath =
|
|
106927
|
+
const fullPath = path110.join(cwd, file3);
|
|
106071
106928
|
if (!fs72.existsSync(fullPath)) {
|
|
106072
106929
|
return {
|
|
106073
106930
|
file: file3,
|
|
@@ -106361,15 +107218,15 @@ init_task_id();
|
|
|
106361
107218
|
init_create_tool();
|
|
106362
107219
|
init_resolve_working_directory();
|
|
106363
107220
|
import * as fs73 from "node:fs";
|
|
106364
|
-
import * as
|
|
107221
|
+
import * as path111 from "node:path";
|
|
106365
107222
|
var EVIDENCE_DIR = ".swarm/evidence";
|
|
106366
107223
|
function isValidTaskId3(taskId) {
|
|
106367
107224
|
return isStrictTaskId(taskId);
|
|
106368
107225
|
}
|
|
106369
107226
|
function isPathWithinSwarm(filePath, workspaceRoot) {
|
|
106370
|
-
const normalizedWorkspace =
|
|
106371
|
-
const swarmPath =
|
|
106372
|
-
const normalizedPath =
|
|
107227
|
+
const normalizedWorkspace = path111.resolve(workspaceRoot);
|
|
107228
|
+
const swarmPath = path111.join(normalizedWorkspace, ".swarm", "evidence");
|
|
107229
|
+
const normalizedPath = path111.resolve(filePath);
|
|
106373
107230
|
return normalizedPath.startsWith(swarmPath);
|
|
106374
107231
|
}
|
|
106375
107232
|
function readEvidenceFile(evidencePath) {
|
|
@@ -106450,7 +107307,7 @@ var check_gate_status = createSwarmTool({
|
|
|
106450
107307
|
};
|
|
106451
107308
|
return JSON.stringify(errorResult, null, 2);
|
|
106452
107309
|
}
|
|
106453
|
-
const evidencePath =
|
|
107310
|
+
const evidencePath = path111.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
|
|
106454
107311
|
if (!isPathWithinSwarm(evidencePath, directory)) {
|
|
106455
107312
|
const errorResult = {
|
|
106456
107313
|
taskId: taskIdInput,
|
|
@@ -106547,7 +107404,7 @@ init_state();
|
|
|
106547
107404
|
init_create_tool();
|
|
106548
107405
|
init_resolve_working_directory();
|
|
106549
107406
|
import * as fs74 from "node:fs";
|
|
106550
|
-
import * as
|
|
107407
|
+
import * as path112 from "node:path";
|
|
106551
107408
|
function extractMatches(regex, text) {
|
|
106552
107409
|
return Array.from(text.matchAll(regex));
|
|
106553
107410
|
}
|
|
@@ -106699,10 +107556,10 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
106699
107556
|
let hasFileReadFailure = false;
|
|
106700
107557
|
for (const filePath of fileTargets) {
|
|
106701
107558
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
106702
|
-
const resolvedPath =
|
|
106703
|
-
const projectRoot =
|
|
106704
|
-
const
|
|
106705
|
-
const withinProject =
|
|
107559
|
+
const resolvedPath = path112.resolve(directory, normalizedPath);
|
|
107560
|
+
const projectRoot = path112.resolve(directory);
|
|
107561
|
+
const relative23 = path112.relative(projectRoot, resolvedPath);
|
|
107562
|
+
const withinProject = relative23 === "" || !relative23.startsWith("..") && !path112.isAbsolute(relative23);
|
|
106706
107563
|
if (!withinProject) {
|
|
106707
107564
|
blockedTasks.push({
|
|
106708
107565
|
task_id: task.id,
|
|
@@ -106757,8 +107614,8 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
106757
107614
|
blockedTasks
|
|
106758
107615
|
};
|
|
106759
107616
|
try {
|
|
106760
|
-
const evidenceDir =
|
|
106761
|
-
const evidencePath =
|
|
107617
|
+
const evidenceDir = path112.join(directory, ".swarm", "evidence", `${phase}`);
|
|
107618
|
+
const evidencePath = path112.join(evidenceDir, "completion-verify.json");
|
|
106762
107619
|
fs74.mkdirSync(evidenceDir, { recursive: true });
|
|
106763
107620
|
const evidenceBundle = {
|
|
106764
107621
|
schema_version: "1.0.0",
|
|
@@ -106836,11 +107693,11 @@ var completion_verify = createSwarmTool({
|
|
|
106836
107693
|
// src/tools/complexity-hotspots.ts
|
|
106837
107694
|
init_zod();
|
|
106838
107695
|
import * as fs76 from "node:fs";
|
|
106839
|
-
import * as
|
|
107696
|
+
import * as path114 from "node:path";
|
|
106840
107697
|
|
|
106841
107698
|
// src/quality/metrics.ts
|
|
106842
107699
|
import * as fs75 from "node:fs";
|
|
106843
|
-
import * as
|
|
107700
|
+
import * as path113 from "node:path";
|
|
106844
107701
|
var MAX_FILE_SIZE_BYTES4 = 256 * 1024;
|
|
106845
107702
|
var MIN_DUPLICATION_LINES = 10;
|
|
106846
107703
|
function estimateCyclomaticComplexity(content) {
|
|
@@ -106892,7 +107749,7 @@ async function computeComplexityDelta(files, workingDir) {
|
|
|
106892
107749
|
let totalComplexity = 0;
|
|
106893
107750
|
const analyzedFiles = [];
|
|
106894
107751
|
for (const file3 of files) {
|
|
106895
|
-
const fullPath =
|
|
107752
|
+
const fullPath = path113.isAbsolute(file3) ? file3 : path113.join(workingDir, file3);
|
|
106896
107753
|
if (!fs75.existsSync(fullPath)) {
|
|
106897
107754
|
continue;
|
|
106898
107755
|
}
|
|
@@ -107015,7 +107872,7 @@ function countGoExports(content) {
|
|
|
107015
107872
|
function getExportCountForFile(filePath) {
|
|
107016
107873
|
try {
|
|
107017
107874
|
const content = fs75.readFileSync(filePath, "utf-8");
|
|
107018
|
-
const ext =
|
|
107875
|
+
const ext = path113.extname(filePath).toLowerCase();
|
|
107019
107876
|
switch (ext) {
|
|
107020
107877
|
case ".ts":
|
|
107021
107878
|
case ".tsx":
|
|
@@ -107041,7 +107898,7 @@ async function computePublicApiDelta(files, workingDir) {
|
|
|
107041
107898
|
let totalExports = 0;
|
|
107042
107899
|
const analyzedFiles = [];
|
|
107043
107900
|
for (const file3 of files) {
|
|
107044
|
-
const fullPath =
|
|
107901
|
+
const fullPath = path113.isAbsolute(file3) ? file3 : path113.join(workingDir, file3);
|
|
107045
107902
|
if (!fs75.existsSync(fullPath)) {
|
|
107046
107903
|
continue;
|
|
107047
107904
|
}
|
|
@@ -107075,7 +107932,7 @@ async function computeDuplicationRatio(files, workingDir) {
|
|
|
107075
107932
|
let duplicateLines = 0;
|
|
107076
107933
|
const analyzedFiles = [];
|
|
107077
107934
|
for (const file3 of files) {
|
|
107078
|
-
const fullPath =
|
|
107935
|
+
const fullPath = path113.isAbsolute(file3) ? file3 : path113.join(workingDir, file3);
|
|
107079
107936
|
if (!fs75.existsSync(fullPath)) {
|
|
107080
107937
|
continue;
|
|
107081
107938
|
}
|
|
@@ -107108,8 +107965,8 @@ function countCodeLines(content) {
|
|
|
107108
107965
|
return lines.length;
|
|
107109
107966
|
}
|
|
107110
107967
|
function isTestFile(filePath) {
|
|
107111
|
-
const basename16 =
|
|
107112
|
-
const _ext =
|
|
107968
|
+
const basename16 = path113.basename(filePath);
|
|
107969
|
+
const _ext = path113.extname(filePath).toLowerCase();
|
|
107113
107970
|
const testPatterns = [
|
|
107114
107971
|
".test.",
|
|
107115
107972
|
".spec.",
|
|
@@ -107190,8 +108047,8 @@ function matchGlobSegment(globSegments, pathSegments) {
|
|
|
107190
108047
|
}
|
|
107191
108048
|
return gIndex === globSegments.length && pIndex === pathSegments.length;
|
|
107192
108049
|
}
|
|
107193
|
-
function matchesGlobSegment(
|
|
107194
|
-
const normalizedPath =
|
|
108050
|
+
function matchesGlobSegment(path114, glob) {
|
|
108051
|
+
const normalizedPath = path114.replace(/\\/g, "/");
|
|
107195
108052
|
const normalizedGlob = glob.replace(/\\/g, "/");
|
|
107196
108053
|
if (normalizedPath.includes("//")) {
|
|
107197
108054
|
return false;
|
|
@@ -107222,8 +108079,8 @@ function simpleGlobToRegex2(glob) {
|
|
|
107222
108079
|
function hasGlobstar(glob) {
|
|
107223
108080
|
return glob.includes("**");
|
|
107224
108081
|
}
|
|
107225
|
-
function globMatches(
|
|
107226
|
-
const normalizedPath =
|
|
108082
|
+
function globMatches(path114, glob) {
|
|
108083
|
+
const normalizedPath = path114.replace(/\\/g, "/");
|
|
107227
108084
|
if (!glob || glob === "") {
|
|
107228
108085
|
if (normalizedPath.includes("//")) {
|
|
107229
108086
|
return false;
|
|
@@ -107259,7 +108116,7 @@ function shouldExcludeFile(filePath, excludeGlobs) {
|
|
|
107259
108116
|
async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
107260
108117
|
let testLines = 0;
|
|
107261
108118
|
let codeLines = 0;
|
|
107262
|
-
const srcDir =
|
|
108119
|
+
const srcDir = path113.join(workingDir, "src");
|
|
107263
108120
|
if (fs75.existsSync(srcDir)) {
|
|
107264
108121
|
await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
107265
108122
|
codeLines += lines;
|
|
@@ -107267,14 +108124,14 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
107267
108124
|
}
|
|
107268
108125
|
const possibleSrcDirs = ["lib", "app", "source", "core"];
|
|
107269
108126
|
for (const dir of possibleSrcDirs) {
|
|
107270
|
-
const dirPath =
|
|
108127
|
+
const dirPath = path113.join(workingDir, dir);
|
|
107271
108128
|
if (fs75.existsSync(dirPath)) {
|
|
107272
108129
|
await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
107273
108130
|
codeLines += lines;
|
|
107274
108131
|
});
|
|
107275
108132
|
}
|
|
107276
108133
|
}
|
|
107277
|
-
const testsDir =
|
|
108134
|
+
const testsDir = path113.join(workingDir, "tests");
|
|
107278
108135
|
if (fs75.existsSync(testsDir)) {
|
|
107279
108136
|
await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
107280
108137
|
testLines += lines;
|
|
@@ -107282,7 +108139,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
107282
108139
|
}
|
|
107283
108140
|
const possibleTestDirs = ["test", "__tests__", "specs"];
|
|
107284
108141
|
for (const dir of possibleTestDirs) {
|
|
107285
|
-
const dirPath =
|
|
108142
|
+
const dirPath = path113.join(workingDir, dir);
|
|
107286
108143
|
if (fs75.existsSync(dirPath) && dirPath !== testsDir) {
|
|
107287
108144
|
await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
107288
108145
|
testLines += lines;
|
|
@@ -107297,7 +108154,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
107297
108154
|
try {
|
|
107298
108155
|
const entries = fs75.readdirSync(dirPath, { withFileTypes: true });
|
|
107299
108156
|
for (const entry of entries) {
|
|
107300
|
-
const fullPath =
|
|
108157
|
+
const fullPath = path113.join(dirPath, entry.name);
|
|
107301
108158
|
if (entry.isDirectory()) {
|
|
107302
108159
|
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
|
|
107303
108160
|
continue;
|
|
@@ -107305,7 +108162,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
107305
108162
|
await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
|
|
107306
108163
|
} else if (entry.isFile()) {
|
|
107307
108164
|
const relativePath = fullPath.replace(`${dirPath}/`, "");
|
|
107308
|
-
const ext =
|
|
108165
|
+
const ext = path113.extname(entry.name).toLowerCase();
|
|
107309
108166
|
const validExts = [
|
|
107310
108167
|
".ts",
|
|
107311
108168
|
".tsx",
|
|
@@ -107556,7 +108413,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
107556
108413
|
const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
|
|
107557
108414
|
const filteredChurn = new Map;
|
|
107558
108415
|
for (const [file3, count] of churnMap) {
|
|
107559
|
-
const ext =
|
|
108416
|
+
const ext = path114.extname(file3).toLowerCase();
|
|
107560
108417
|
if (extSet.has(ext)) {
|
|
107561
108418
|
filteredChurn.set(file3, count);
|
|
107562
108419
|
}
|
|
@@ -107567,7 +108424,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
107567
108424
|
for (const [file3, churnCount] of filteredChurn) {
|
|
107568
108425
|
let fullPath = file3;
|
|
107569
108426
|
if (!fs76.existsSync(fullPath)) {
|
|
107570
|
-
fullPath =
|
|
108427
|
+
fullPath = path114.join(cwd, file3);
|
|
107571
108428
|
}
|
|
107572
108429
|
const complexity = getComplexityForFile2(fullPath);
|
|
107573
108430
|
if (complexity !== null) {
|
|
@@ -107736,8 +108593,8 @@ ${body2}`);
|
|
|
107736
108593
|
|
|
107737
108594
|
// src/council/council-evidence-writer.ts
|
|
107738
108595
|
init_task_file();
|
|
107739
|
-
import { appendFileSync as appendFileSync12, existsSync as
|
|
107740
|
-
import { join as
|
|
108596
|
+
import { appendFileSync as appendFileSync12, existsSync as existsSync63, mkdirSync as mkdirSync29, readFileSync as readFileSync45 } from "node:fs";
|
|
108597
|
+
import { join as join95 } from "node:path";
|
|
107741
108598
|
var EVIDENCE_DIR2 = ".swarm/evidence";
|
|
107742
108599
|
var VALID_TASK_ID = /^\d+\.\d+(\.\d+)*$/;
|
|
107743
108600
|
var COUNCIL_GATE_NAME = "council";
|
|
@@ -107774,14 +108631,14 @@ async function writeCouncilEvidence(workingDir, synthesis) {
|
|
|
107774
108631
|
if (!VALID_TASK_ID.test(synthesis.taskId)) {
|
|
107775
108632
|
throw new Error(`writeCouncilEvidence: invalid taskId "${synthesis.taskId}" — must match N.M or N.M.P format`);
|
|
107776
108633
|
}
|
|
107777
|
-
const dir =
|
|
107778
|
-
|
|
108634
|
+
const dir = join95(workingDir, EVIDENCE_DIR2);
|
|
108635
|
+
mkdirSync29(dir, { recursive: true });
|
|
107779
108636
|
const filePath = taskEvidencePath(workingDir, synthesis.taskId);
|
|
107780
108637
|
await _internals53.withTaskEvidenceLock(workingDir, synthesis.taskId, COUNCIL_AGENT_ID, async () => {
|
|
107781
108638
|
const existingRoot = Object.create(null);
|
|
107782
|
-
if (
|
|
108639
|
+
if (existsSync63(filePath)) {
|
|
107783
108640
|
try {
|
|
107784
|
-
const parsed = JSON.parse(
|
|
108641
|
+
const parsed = JSON.parse(readFileSync45(filePath, "utf-8"));
|
|
107785
108642
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
107786
108643
|
safeAssignOwnProps(existingRoot, parsed);
|
|
107787
108644
|
}
|
|
@@ -107812,15 +108669,15 @@ async function writeCouncilEvidence(workingDir, synthesis) {
|
|
|
107812
108669
|
await atomicWriteFile(filePath, JSON.stringify(updated, null, 2));
|
|
107813
108670
|
});
|
|
107814
108671
|
try {
|
|
107815
|
-
const councilDir =
|
|
107816
|
-
|
|
108672
|
+
const councilDir = join95(workingDir, ".swarm", "council");
|
|
108673
|
+
mkdirSync29(councilDir, { recursive: true });
|
|
107817
108674
|
const auditLine = JSON.stringify({
|
|
107818
108675
|
round: synthesis.roundNumber,
|
|
107819
108676
|
verdict: synthesis.overallVerdict,
|
|
107820
108677
|
timestamp: synthesis.timestamp,
|
|
107821
108678
|
vetoedBy: synthesis.vetoedBy
|
|
107822
108679
|
});
|
|
107823
|
-
appendFileSync12(
|
|
108680
|
+
appendFileSync12(join95(councilDir, `${synthesis.taskId}.rounds.jsonl`), `${auditLine}
|
|
107824
108681
|
`);
|
|
107825
108682
|
} catch (auditError) {
|
|
107826
108683
|
console.warn(`writeCouncilEvidence: failed to append round-history audit log: ${auditError instanceof Error ? auditError.message : String(auditError)}`);
|
|
@@ -108142,25 +108999,25 @@ function buildFinalCouncilFeedback(projectSummary, verdict, vetoedBy, requiredFi
|
|
|
108142
108999
|
}
|
|
108143
109000
|
|
|
108144
109001
|
// src/council/criteria-store.ts
|
|
108145
|
-
import { existsSync as
|
|
108146
|
-
import { join as
|
|
109002
|
+
import { existsSync as existsSync64, mkdirSync as mkdirSync30, readFileSync as readFileSync46, writeFileSync as writeFileSync22 } from "node:fs";
|
|
109003
|
+
import { join as join96 } from "node:path";
|
|
108147
109004
|
var COUNCIL_DIR = ".swarm/council";
|
|
108148
109005
|
function writeCriteria(workingDir, taskId, criteria) {
|
|
108149
|
-
const dir =
|
|
108150
|
-
|
|
109006
|
+
const dir = join96(workingDir, COUNCIL_DIR);
|
|
109007
|
+
mkdirSync30(dir, { recursive: true });
|
|
108151
109008
|
const payload = {
|
|
108152
109009
|
taskId,
|
|
108153
109010
|
criteria,
|
|
108154
109011
|
declaredAt: new Date().toISOString()
|
|
108155
109012
|
};
|
|
108156
|
-
|
|
109013
|
+
writeFileSync22(join96(dir, `${safeId(taskId)}.json`), JSON.stringify(payload, null, 2));
|
|
108157
109014
|
}
|
|
108158
109015
|
function readCriteria(workingDir, taskId) {
|
|
108159
|
-
const filePath =
|
|
108160
|
-
if (!
|
|
109016
|
+
const filePath = join96(workingDir, COUNCIL_DIR, `${safeId(taskId)}.json`);
|
|
109017
|
+
if (!existsSync64(filePath))
|
|
108161
109018
|
return null;
|
|
108162
109019
|
try {
|
|
108163
|
-
const parsed = JSON.parse(
|
|
109020
|
+
const parsed = JSON.parse(readFileSync46(filePath, "utf-8"));
|
|
108164
109021
|
if (parsed && typeof parsed === "object" && typeof parsed.taskId === "string" && Array.isArray(parsed.criteria)) {
|
|
108165
109022
|
return parsed;
|
|
108166
109023
|
}
|
|
@@ -108310,7 +109167,7 @@ var submit_council_verdicts = createSwarmTool({
|
|
|
108310
109167
|
init_zod();
|
|
108311
109168
|
init_loader();
|
|
108312
109169
|
import * as fs77 from "node:fs";
|
|
108313
|
-
import * as
|
|
109170
|
+
import * as path115 from "node:path";
|
|
108314
109171
|
|
|
108315
109172
|
// src/council/general-council-advisory.ts
|
|
108316
109173
|
var ADVISORY_HEADER = "[general_council] (advisory; not blocking)";
|
|
@@ -108738,10 +109595,10 @@ var convene_general_council = createSwarmTool({
|
|
|
108738
109595
|
const round1 = input.round1Responses;
|
|
108739
109596
|
const round2 = input.round2Responses ?? [];
|
|
108740
109597
|
const result = synthesizeGeneralCouncil(input.question, input.mode, round1, round2);
|
|
108741
|
-
const evidenceDir =
|
|
109598
|
+
const evidenceDir = path115.join(workingDir, ".swarm", "council", "general");
|
|
108742
109599
|
const safeTimestamp = result.timestamp.replace(/[:.]/g, "-");
|
|
108743
109600
|
const evidenceFile = `${safeTimestamp}-${input.mode}.json`;
|
|
108744
|
-
const evidencePath =
|
|
109601
|
+
const evidencePath = path115.join(evidenceDir, evidenceFile);
|
|
108745
109602
|
try {
|
|
108746
109603
|
await fs77.promises.mkdir(evidenceDir, { recursive: true });
|
|
108747
109604
|
await fs77.promises.writeFile(evidencePath, JSON.stringify(result, null, 2));
|
|
@@ -109012,7 +109869,7 @@ init_state();
|
|
|
109012
109869
|
init_task_id();
|
|
109013
109870
|
init_create_tool();
|
|
109014
109871
|
import * as fs78 from "node:fs";
|
|
109015
|
-
import * as
|
|
109872
|
+
import * as path116 from "node:path";
|
|
109016
109873
|
function validateTaskIdFormat2(taskId) {
|
|
109017
109874
|
return validateTaskIdFormat(taskId);
|
|
109018
109875
|
}
|
|
@@ -109086,8 +109943,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
109086
109943
|
};
|
|
109087
109944
|
}
|
|
109088
109945
|
}
|
|
109089
|
-
normalizedDir =
|
|
109090
|
-
const pathParts = normalizedDir.split(
|
|
109946
|
+
normalizedDir = path116.normalize(args2.working_directory);
|
|
109947
|
+
const pathParts = normalizedDir.split(path116.sep);
|
|
109091
109948
|
if (pathParts.includes("..")) {
|
|
109092
109949
|
return {
|
|
109093
109950
|
success: false,
|
|
@@ -109097,10 +109954,10 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
109097
109954
|
]
|
|
109098
109955
|
};
|
|
109099
109956
|
}
|
|
109100
|
-
const resolvedDir =
|
|
109957
|
+
const resolvedDir = path116.resolve(normalizedDir);
|
|
109101
109958
|
try {
|
|
109102
109959
|
const realPath = fs78.realpathSync(resolvedDir);
|
|
109103
|
-
const planPath2 =
|
|
109960
|
+
const planPath2 = path116.join(realPath, ".swarm", "plan.json");
|
|
109104
109961
|
if (!fs78.existsSync(planPath2)) {
|
|
109105
109962
|
return {
|
|
109106
109963
|
success: false,
|
|
@@ -109121,9 +109978,9 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
109121
109978
|
}
|
|
109122
109979
|
if (normalizedDir && fallbackDir) {
|
|
109123
109980
|
try {
|
|
109124
|
-
const canonicalWorkingDir = fs78.realpathSync(
|
|
109125
|
-
const canonicalProjectRoot = fs78.realpathSync(
|
|
109126
|
-
if (canonicalWorkingDir.startsWith(canonicalProjectRoot +
|
|
109981
|
+
const canonicalWorkingDir = fs78.realpathSync(path116.resolve(normalizedDir));
|
|
109982
|
+
const canonicalProjectRoot = fs78.realpathSync(path116.resolve(fallbackDir));
|
|
109983
|
+
if (canonicalWorkingDir.startsWith(canonicalProjectRoot + path116.sep)) {
|
|
109127
109984
|
return {
|
|
109128
109985
|
success: false,
|
|
109129
109986
|
message: `working_directory "${normalizedDir}" is a subdirectory of the project root. Use the project root "${fallbackDir}" instead.`,
|
|
@@ -109145,7 +110002,7 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
109145
110002
|
};
|
|
109146
110003
|
}
|
|
109147
110004
|
const directory = normalizedDir || fallbackDir;
|
|
109148
|
-
const planPath =
|
|
110005
|
+
const planPath = path116.resolve(directory, ".swarm", "plan.json");
|
|
109149
110006
|
if (!fs78.existsSync(planPath)) {
|
|
109150
110007
|
return {
|
|
109151
110008
|
success: false,
|
|
@@ -109185,8 +110042,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
109185
110042
|
const normalizeErrors = [];
|
|
109186
110043
|
const dir = directory;
|
|
109187
110044
|
const mergedFiles = rawMergedFiles.map((file3) => {
|
|
109188
|
-
if (
|
|
109189
|
-
const relativePath =
|
|
110045
|
+
if (path116.isAbsolute(file3)) {
|
|
110046
|
+
const relativePath = path116.relative(dir, file3).replace(/\\/g, "/");
|
|
109190
110047
|
if (relativePath.startsWith("..")) {
|
|
109191
110048
|
normalizeErrors.push(`Path '${file3}' resolves outside the project directory`);
|
|
109192
110049
|
return file3;
|
|
@@ -109248,7 +110105,7 @@ var declare_scope = createSwarmTool({
|
|
|
109248
110105
|
init_zod();
|
|
109249
110106
|
import * as child_process7 from "node:child_process";
|
|
109250
110107
|
import * as fs79 from "node:fs";
|
|
109251
|
-
import * as
|
|
110108
|
+
import * as path117 from "node:path";
|
|
109252
110109
|
init_create_tool();
|
|
109253
110110
|
var MAX_DIFF_LINES = 500;
|
|
109254
110111
|
var DIFF_TIMEOUT_MS = 30000;
|
|
@@ -109277,20 +110134,20 @@ function validateBase(base) {
|
|
|
109277
110134
|
function validatePaths(paths) {
|
|
109278
110135
|
if (!paths)
|
|
109279
110136
|
return null;
|
|
109280
|
-
for (const
|
|
109281
|
-
if (!
|
|
110137
|
+
for (const path118 of paths) {
|
|
110138
|
+
if (!path118 || path118.length === 0) {
|
|
109282
110139
|
return "empty path not allowed";
|
|
109283
110140
|
}
|
|
109284
|
-
if (
|
|
110141
|
+
if (path118.length > MAX_PATH_LENGTH) {
|
|
109285
110142
|
return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
|
|
109286
110143
|
}
|
|
109287
|
-
if (SHELL_METACHARACTERS2.test(
|
|
110144
|
+
if (SHELL_METACHARACTERS2.test(path118)) {
|
|
109288
110145
|
return "path contains shell metacharacters";
|
|
109289
110146
|
}
|
|
109290
|
-
if (
|
|
110147
|
+
if (path118.startsWith("-")) {
|
|
109291
110148
|
return 'path cannot start with "-" (option-like arguments not allowed)';
|
|
109292
110149
|
}
|
|
109293
|
-
if (CONTROL_CHAR_PATTERN2.test(
|
|
110150
|
+
if (CONTROL_CHAR_PATTERN2.test(path118)) {
|
|
109294
110151
|
return "path contains control characters";
|
|
109295
110152
|
}
|
|
109296
110153
|
}
|
|
@@ -109398,8 +110255,8 @@ var diff = createSwarmTool({
|
|
|
109398
110255
|
if (parts2.length >= 3) {
|
|
109399
110256
|
const additions = parseInt(parts2[0], 10) || 0;
|
|
109400
110257
|
const deletions = parseInt(parts2[1], 10) || 0;
|
|
109401
|
-
const
|
|
109402
|
-
files.push({ path:
|
|
110258
|
+
const path118 = parts2[2];
|
|
110259
|
+
files.push({ path: path118, additions, deletions });
|
|
109403
110260
|
}
|
|
109404
110261
|
}
|
|
109405
110262
|
const contractChanges = [];
|
|
@@ -109438,7 +110295,7 @@ var diff = createSwarmTool({
|
|
|
109438
110295
|
} else if (base === "unstaged") {
|
|
109439
110296
|
const oldRef = `:${file3.path}`;
|
|
109440
110297
|
oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
|
|
109441
|
-
newContent = fs79.readFileSync(
|
|
110298
|
+
newContent = fs79.readFileSync(path117.join(directory, file3.path), "utf-8");
|
|
109442
110299
|
} else {
|
|
109443
110300
|
const oldRef = `${base}:${file3.path}`;
|
|
109444
110301
|
oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
|
|
@@ -109515,12 +110372,12 @@ var diff = createSwarmTool({
|
|
|
109515
110372
|
init_zod();
|
|
109516
110373
|
import * as child_process8 from "node:child_process";
|
|
109517
110374
|
import * as fs80 from "node:fs";
|
|
109518
|
-
import * as
|
|
110375
|
+
import * as path118 from "node:path";
|
|
109519
110376
|
init_create_tool();
|
|
109520
110377
|
init_resolve_working_directory();
|
|
109521
110378
|
async function execGit2(workingDir, args2, options) {
|
|
109522
110379
|
try {
|
|
109523
|
-
const stdout = await new Promise((
|
|
110380
|
+
const stdout = await new Promise((resolve41, reject) => {
|
|
109524
110381
|
const execOpts = {
|
|
109525
110382
|
encoding: "utf-8",
|
|
109526
110383
|
cwd: workingDir,
|
|
@@ -109533,7 +110390,7 @@ async function execGit2(workingDir, args2, options) {
|
|
|
109533
110390
|
reject(error93);
|
|
109534
110391
|
return;
|
|
109535
110392
|
}
|
|
109536
|
-
|
|
110393
|
+
resolve41(output ?? "");
|
|
109537
110394
|
});
|
|
109538
110395
|
});
|
|
109539
110396
|
return stdout;
|
|
@@ -109584,7 +110441,7 @@ var diff_summary = createSwarmTool({
|
|
|
109584
110441
|
}
|
|
109585
110442
|
try {
|
|
109586
110443
|
let oldContent;
|
|
109587
|
-
const newContent = await fs80.promises.readFile(
|
|
110444
|
+
const newContent = await fs80.promises.readFile(path118.join(workingDir, filePath), "utf-8");
|
|
109588
110445
|
if (fileExistsInHead) {
|
|
109589
110446
|
oldContent = await execGit2(workingDir, ["show", `HEAD:${filePath}`], {
|
|
109590
110447
|
timeout: 5000,
|
|
@@ -109814,7 +110671,7 @@ init_zod();
|
|
|
109814
110671
|
init_create_tool();
|
|
109815
110672
|
init_path_security();
|
|
109816
110673
|
import * as fs81 from "node:fs";
|
|
109817
|
-
import * as
|
|
110674
|
+
import * as path119 from "node:path";
|
|
109818
110675
|
var MAX_FILE_SIZE_BYTES6 = 1024 * 1024;
|
|
109819
110676
|
var MAX_EVIDENCE_FILES = 1000;
|
|
109820
110677
|
var EVIDENCE_DIR3 = ".swarm/evidence";
|
|
@@ -109841,9 +110698,9 @@ function validateRequiredTypes(input) {
|
|
|
109841
110698
|
return null;
|
|
109842
110699
|
}
|
|
109843
110700
|
function isPathWithinSwarm2(filePath, cwd) {
|
|
109844
|
-
const normalizedCwd =
|
|
109845
|
-
const swarmPath =
|
|
109846
|
-
const normalizedPath =
|
|
110701
|
+
const normalizedCwd = path119.resolve(cwd);
|
|
110702
|
+
const swarmPath = path119.join(normalizedCwd, ".swarm");
|
|
110703
|
+
const normalizedPath = path119.resolve(filePath);
|
|
109847
110704
|
return normalizedPath.startsWith(swarmPath);
|
|
109848
110705
|
}
|
|
109849
110706
|
function parseCompletedTasks(planContent) {
|
|
@@ -109873,10 +110730,10 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
109873
110730
|
if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
|
|
109874
110731
|
continue;
|
|
109875
110732
|
}
|
|
109876
|
-
const filePath =
|
|
110733
|
+
const filePath = path119.join(evidenceDir, filename);
|
|
109877
110734
|
try {
|
|
109878
|
-
const resolvedPath =
|
|
109879
|
-
const evidenceDirResolved =
|
|
110735
|
+
const resolvedPath = path119.resolve(filePath);
|
|
110736
|
+
const evidenceDirResolved = path119.resolve(evidenceDir);
|
|
109880
110737
|
if (!resolvedPath.startsWith(evidenceDirResolved)) {
|
|
109881
110738
|
continue;
|
|
109882
110739
|
}
|
|
@@ -109994,7 +110851,7 @@ var evidence_check = createSwarmTool({
|
|
|
109994
110851
|
return JSON.stringify(errorResult, null, 2);
|
|
109995
110852
|
}
|
|
109996
110853
|
const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
|
|
109997
|
-
const planPath =
|
|
110854
|
+
const planPath = path119.join(cwd, PLAN_FILE);
|
|
109998
110855
|
if (!isPathWithinSwarm2(planPath, cwd)) {
|
|
109999
110856
|
const errorResult = {
|
|
110000
110857
|
error: "plan file path validation failed",
|
|
@@ -110026,7 +110883,7 @@ var evidence_check = createSwarmTool({
|
|
|
110026
110883
|
};
|
|
110027
110884
|
return JSON.stringify(result2, null, 2);
|
|
110028
110885
|
}
|
|
110029
|
-
const evidenceDir =
|
|
110886
|
+
const evidenceDir = path119.join(cwd, EVIDENCE_DIR3);
|
|
110030
110887
|
const evidence = readEvidenceFiles(evidenceDir, cwd);
|
|
110031
110888
|
const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
|
|
110032
110889
|
const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
|
|
@@ -110045,7 +110902,7 @@ var evidence_check = createSwarmTool({
|
|
|
110045
110902
|
init_zod();
|
|
110046
110903
|
init_create_tool();
|
|
110047
110904
|
import * as fs82 from "node:fs";
|
|
110048
|
-
import * as
|
|
110905
|
+
import * as path120 from "node:path";
|
|
110049
110906
|
var EXT_MAP = {
|
|
110050
110907
|
python: ".py",
|
|
110051
110908
|
py: ".py",
|
|
@@ -110126,12 +110983,12 @@ var extract_code_blocks = createSwarmTool({
|
|
|
110126
110983
|
if (prefix) {
|
|
110127
110984
|
filename = `${prefix}_${filename}`;
|
|
110128
110985
|
}
|
|
110129
|
-
let filepath =
|
|
110130
|
-
const base =
|
|
110131
|
-
const ext =
|
|
110986
|
+
let filepath = path120.join(targetDir, filename);
|
|
110987
|
+
const base = path120.basename(filepath, path120.extname(filepath));
|
|
110988
|
+
const ext = path120.extname(filepath);
|
|
110132
110989
|
let counter = 1;
|
|
110133
110990
|
while (fs82.existsSync(filepath)) {
|
|
110134
|
-
filepath =
|
|
110991
|
+
filepath = path120.join(targetDir, `${base}_${counter}${ext}`);
|
|
110135
110992
|
counter++;
|
|
110136
110993
|
}
|
|
110137
110994
|
try {
|
|
@@ -110473,7 +111330,7 @@ init_create_tool();
|
|
|
110473
111330
|
var GITINGEST_TIMEOUT_MS = 1e4;
|
|
110474
111331
|
var GITINGEST_MAX_RESPONSE_BYTES = 5242880;
|
|
110475
111332
|
var GITINGEST_MAX_RETRIES = 2;
|
|
110476
|
-
var delay = (ms) => new Promise((
|
|
111333
|
+
var delay = (ms) => new Promise((resolve42) => setTimeout(resolve42, ms));
|
|
110477
111334
|
async function fetchGitingest(args2) {
|
|
110478
111335
|
for (let attempt = 0;attempt <= GITINGEST_MAX_RETRIES; attempt++) {
|
|
110479
111336
|
try {
|
|
@@ -110562,7 +111419,7 @@ init_zod();
|
|
|
110562
111419
|
init_create_tool();
|
|
110563
111420
|
init_path_security();
|
|
110564
111421
|
import * as fs83 from "node:fs";
|
|
110565
|
-
import * as
|
|
111422
|
+
import * as path121 from "node:path";
|
|
110566
111423
|
var MAX_FILE_PATH_LENGTH2 = 500;
|
|
110567
111424
|
var MAX_SYMBOL_LENGTH = 256;
|
|
110568
111425
|
var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
|
|
@@ -110610,7 +111467,7 @@ function validateSymbolInput(symbol3) {
|
|
|
110610
111467
|
return null;
|
|
110611
111468
|
}
|
|
110612
111469
|
function isBinaryFile2(filePath, buffer) {
|
|
110613
|
-
const ext =
|
|
111470
|
+
const ext = path121.extname(filePath).toLowerCase();
|
|
110614
111471
|
if (ext === ".json" || ext === ".md" || ext === ".txt") {
|
|
110615
111472
|
return false;
|
|
110616
111473
|
}
|
|
@@ -110634,15 +111491,15 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
110634
111491
|
const imports = [];
|
|
110635
111492
|
let _resolvedTarget;
|
|
110636
111493
|
try {
|
|
110637
|
-
_resolvedTarget =
|
|
111494
|
+
_resolvedTarget = path121.resolve(targetFile);
|
|
110638
111495
|
} catch {
|
|
110639
111496
|
_resolvedTarget = targetFile;
|
|
110640
111497
|
}
|
|
110641
|
-
const targetBasename =
|
|
111498
|
+
const targetBasename = path121.basename(targetFile, path121.extname(targetFile));
|
|
110642
111499
|
const targetWithExt = targetFile;
|
|
110643
111500
|
const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
110644
|
-
const normalizedTargetWithExt =
|
|
110645
|
-
const normalizedTargetWithoutExt =
|
|
111501
|
+
const normalizedTargetWithExt = path121.normalize(targetWithExt).replace(/\\/g, "/");
|
|
111502
|
+
const normalizedTargetWithoutExt = path121.normalize(targetWithoutExt).replace(/\\/g, "/");
|
|
110646
111503
|
const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
|
|
110647
111504
|
for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
|
|
110648
111505
|
const modulePath = match[1] || match[2] || match[3];
|
|
@@ -110665,9 +111522,9 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
110665
111522
|
}
|
|
110666
111523
|
const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
|
|
110667
111524
|
let isMatch = false;
|
|
110668
|
-
const _targetDir =
|
|
110669
|
-
const targetExt =
|
|
110670
|
-
const targetBasenameNoExt =
|
|
111525
|
+
const _targetDir = path121.dirname(targetFile);
|
|
111526
|
+
const targetExt = path121.extname(targetFile);
|
|
111527
|
+
const targetBasenameNoExt = path121.basename(targetFile, targetExt);
|
|
110671
111528
|
const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
110672
111529
|
const moduleName = modulePath.split(/[/\\]/).pop() || "";
|
|
110673
111530
|
const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
@@ -110735,10 +111592,10 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
110735
111592
|
entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
|
110736
111593
|
for (const entry of entries) {
|
|
110737
111594
|
if (SKIP_DIRECTORIES4.has(entry)) {
|
|
110738
|
-
stats.skippedDirs.push(
|
|
111595
|
+
stats.skippedDirs.push(path121.join(dir, entry));
|
|
110739
111596
|
continue;
|
|
110740
111597
|
}
|
|
110741
|
-
const fullPath =
|
|
111598
|
+
const fullPath = path121.join(dir, entry);
|
|
110742
111599
|
let stat9;
|
|
110743
111600
|
try {
|
|
110744
111601
|
stat9 = fs83.statSync(fullPath);
|
|
@@ -110752,7 +111609,7 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
110752
111609
|
if (stat9.isDirectory()) {
|
|
110753
111610
|
findSourceFiles2(fullPath, files, stats);
|
|
110754
111611
|
} else if (stat9.isFile()) {
|
|
110755
|
-
const ext =
|
|
111612
|
+
const ext = path121.extname(fullPath).toLowerCase();
|
|
110756
111613
|
if (SUPPORTED_EXTENSIONS3.includes(ext)) {
|
|
110757
111614
|
files.push(fullPath);
|
|
110758
111615
|
}
|
|
@@ -110809,7 +111666,7 @@ var imports = createSwarmTool({
|
|
|
110809
111666
|
return JSON.stringify(errorResult, null, 2);
|
|
110810
111667
|
}
|
|
110811
111668
|
try {
|
|
110812
|
-
const targetFile =
|
|
111669
|
+
const targetFile = path121.resolve(file3);
|
|
110813
111670
|
if (!fs83.existsSync(targetFile)) {
|
|
110814
111671
|
const errorResult = {
|
|
110815
111672
|
error: `target file not found: ${file3}`,
|
|
@@ -110831,7 +111688,7 @@ var imports = createSwarmTool({
|
|
|
110831
111688
|
};
|
|
110832
111689
|
return JSON.stringify(errorResult, null, 2);
|
|
110833
111690
|
}
|
|
110834
|
-
const baseDir =
|
|
111691
|
+
const baseDir = path121.dirname(targetFile);
|
|
110835
111692
|
const scanStats = {
|
|
110836
111693
|
skippedDirs: [],
|
|
110837
111694
|
skippedFiles: 0,
|
|
@@ -111219,7 +112076,7 @@ init_zod();
|
|
|
111219
112076
|
init_config();
|
|
111220
112077
|
init_knowledge_store();
|
|
111221
112078
|
init_create_tool();
|
|
111222
|
-
import { existsSync as
|
|
112079
|
+
import { existsSync as existsSync69 } from "node:fs";
|
|
111223
112080
|
var DEFAULT_LIMIT = 10;
|
|
111224
112081
|
var MAX_LESSON_LENGTH = 200;
|
|
111225
112082
|
var VALID_CATEGORIES3 = [
|
|
@@ -111295,14 +112152,14 @@ function validateLimit(limit) {
|
|
|
111295
112152
|
}
|
|
111296
112153
|
async function readSwarmKnowledge(directory) {
|
|
111297
112154
|
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
111298
|
-
if (!
|
|
112155
|
+
if (!existsSync69(swarmPath)) {
|
|
111299
112156
|
return [];
|
|
111300
112157
|
}
|
|
111301
112158
|
return readKnowledge(swarmPath);
|
|
111302
112159
|
}
|
|
111303
112160
|
async function readHiveKnowledge() {
|
|
111304
112161
|
const hivePath = resolveHiveKnowledgePath();
|
|
111305
|
-
if (!
|
|
112162
|
+
if (!existsSync69(hivePath)) {
|
|
111306
112163
|
return [];
|
|
111307
112164
|
}
|
|
111308
112165
|
return readKnowledge(hivePath);
|
|
@@ -111728,11 +112585,11 @@ var lean_turbo_acquire_locks = createSwarmTool({
|
|
|
111728
112585
|
init_zod();
|
|
111729
112586
|
init_constants();
|
|
111730
112587
|
import * as fs85 from "node:fs";
|
|
111731
|
-
import * as
|
|
112588
|
+
import * as path123 from "node:path";
|
|
111732
112589
|
|
|
111733
112590
|
// src/turbo/lean/conflicts.ts
|
|
111734
112591
|
import * as fs84 from "node:fs";
|
|
111735
|
-
import * as
|
|
112592
|
+
import * as path122 from "node:path";
|
|
111736
112593
|
var DEFAULT_GLOBAL_FILES = [
|
|
111737
112594
|
"package.json",
|
|
111738
112595
|
"package-lock.json",
|
|
@@ -111835,7 +112692,7 @@ function isGlobalFile(normalizedPath) {
|
|
|
111835
112692
|
}
|
|
111836
112693
|
return false;
|
|
111837
112694
|
}
|
|
111838
|
-
function
|
|
112695
|
+
function isProtectedPath3(normalizedPath) {
|
|
111839
112696
|
const lowerPath = normalizedPath.toLowerCase();
|
|
111840
112697
|
for (const pattern of DEFAULT_PROTECTED_PATTERNS) {
|
|
111841
112698
|
if (lowerPath.includes(pattern.toLowerCase())) {
|
|
@@ -111859,7 +112716,7 @@ function isProtectedPath2(normalizedPath) {
|
|
|
111859
112716
|
return false;
|
|
111860
112717
|
}
|
|
111861
112718
|
function readTaskScopes(directory, taskId) {
|
|
111862
|
-
const scopePath =
|
|
112719
|
+
const scopePath = path122.join(directory, ".swarm", "scopes", `scope-${taskId}.json`);
|
|
111863
112720
|
try {
|
|
111864
112721
|
if (!fs84.existsSync(scopePath)) {
|
|
111865
112722
|
return null;
|
|
@@ -111885,7 +112742,7 @@ function assessTaskRisk(files, hasDeclaredScope, hasInvalidScope, config3) {
|
|
|
111885
112742
|
files: globalFiles
|
|
111886
112743
|
};
|
|
111887
112744
|
}
|
|
111888
|
-
const protectedFiles = files.filter(
|
|
112745
|
+
const protectedFiles = files.filter(isProtectedPath3);
|
|
111889
112746
|
if (protectedFiles.length > 0) {
|
|
111890
112747
|
return {
|
|
111891
112748
|
category: "protected",
|
|
@@ -112247,7 +113104,7 @@ function createEmptyPlan(phaseNumber, planId) {
|
|
|
112247
113104
|
// src/tools/lean-turbo-plan-lanes.ts
|
|
112248
113105
|
init_create_tool();
|
|
112249
113106
|
function readPlanJson(directory) {
|
|
112250
|
-
const planPath =
|
|
113107
|
+
const planPath = path123.join(directory, ".swarm", "plan.json");
|
|
112251
113108
|
if (!fs85.existsSync(planPath)) {
|
|
112252
113109
|
return null;
|
|
112253
113110
|
}
|
|
@@ -112303,15 +113160,15 @@ init_config();
|
|
|
112303
113160
|
// src/turbo/lean/reviewer.ts
|
|
112304
113161
|
init_state();
|
|
112305
113162
|
import * as fs87 from "node:fs/promises";
|
|
112306
|
-
import * as
|
|
113163
|
+
import * as path125 from "node:path";
|
|
112307
113164
|
|
|
112308
113165
|
// src/turbo/lean/evidence.ts
|
|
112309
113166
|
init_bun_compat();
|
|
112310
113167
|
import { rmSync as rmSync6 } from "node:fs";
|
|
112311
113168
|
import * as fs86 from "node:fs/promises";
|
|
112312
|
-
import * as
|
|
113169
|
+
import * as path124 from "node:path";
|
|
112313
113170
|
function leanTurboEvidenceDir(directory, phase) {
|
|
112314
|
-
return
|
|
113171
|
+
return path124.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
|
|
112315
113172
|
}
|
|
112316
113173
|
function validateLaneId(laneId) {
|
|
112317
113174
|
if (laneId.length === 0) {
|
|
@@ -112333,16 +113190,16 @@ function validateLaneId(laneId) {
|
|
|
112333
113190
|
function laneEvidencePath(directory, phase, laneId) {
|
|
112334
113191
|
validateLaneId(laneId);
|
|
112335
113192
|
const expectedDir = leanTurboEvidenceDir(directory, phase);
|
|
112336
|
-
const resolvedPath =
|
|
112337
|
-
const resolvedDir =
|
|
112338
|
-
if (!resolvedPath.startsWith(resolvedDir +
|
|
113193
|
+
const resolvedPath = path124.resolve(path124.join(expectedDir, `${laneId}.json`));
|
|
113194
|
+
const resolvedDir = path124.resolve(expectedDir);
|
|
113195
|
+
if (!resolvedPath.startsWith(resolvedDir + path124.sep) && resolvedPath !== resolvedDir) {
|
|
112339
113196
|
throw new Error(`Invalid laneId: path traversal detected (got "${laneId}")`);
|
|
112340
113197
|
}
|
|
112341
113198
|
return resolvedPath;
|
|
112342
113199
|
}
|
|
112343
113200
|
async function atomicWriteJson(filePath, data) {
|
|
112344
113201
|
const content = JSON.stringify(data, null, 2);
|
|
112345
|
-
const dir =
|
|
113202
|
+
const dir = path124.dirname(filePath);
|
|
112346
113203
|
await fs86.mkdir(dir, { recursive: true });
|
|
112347
113204
|
const tempPath = `${filePath}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
112348
113205
|
try {
|
|
@@ -112356,7 +113213,7 @@ async function atomicWriteJson(filePath, data) {
|
|
|
112356
113213
|
}
|
|
112357
113214
|
}
|
|
112358
113215
|
function phaseEvidencePath(directory, phase) {
|
|
112359
|
-
return
|
|
113216
|
+
return path124.join(leanTurboEvidenceDir(directory, phase), "lean-turbo-phase.json");
|
|
112360
113217
|
}
|
|
112361
113218
|
async function writeLaneEvidence(directory, phase, evidence) {
|
|
112362
113219
|
const targetPath = laneEvidencePath(directory, phase, evidence.laneId);
|
|
@@ -112400,7 +113257,7 @@ async function listLaneEvidence(directory, phase) {
|
|
|
112400
113257
|
if (entry === "lean-turbo-phase.json") {
|
|
112401
113258
|
continue;
|
|
112402
113259
|
}
|
|
112403
|
-
const filePath =
|
|
113260
|
+
const filePath = path124.join(evidenceDir, entry);
|
|
112404
113261
|
let content;
|
|
112405
113262
|
try {
|
|
112406
113263
|
content = await fs86.readFile(filePath, "utf-8");
|
|
@@ -112531,9 +113388,9 @@ function parseReviewerVerdict(responseText) {
|
|
|
112531
113388
|
return { verdict, reason };
|
|
112532
113389
|
}
|
|
112533
113390
|
async function writeReviewerEvidence(directory, phase, verdict, reason) {
|
|
112534
|
-
const evidenceDir =
|
|
113391
|
+
const evidenceDir = path125.join(directory, ".swarm", "evidence", String(phase));
|
|
112535
113392
|
await fs87.mkdir(evidenceDir, { recursive: true });
|
|
112536
|
-
const evidencePath =
|
|
113393
|
+
const evidencePath = path125.join(evidenceDir, "lean-turbo-reviewer.json");
|
|
112537
113394
|
const content = JSON.stringify({
|
|
112538
113395
|
phase,
|
|
112539
113396
|
verdict,
|
|
@@ -113345,7 +114202,7 @@ init_lint();
|
|
|
113345
114202
|
init_spec_schema();
|
|
113346
114203
|
init_create_tool();
|
|
113347
114204
|
import * as fs88 from "node:fs";
|
|
113348
|
-
import * as
|
|
114205
|
+
import * as path126 from "node:path";
|
|
113349
114206
|
var SPEC_FILE_NAME = "spec.md";
|
|
113350
114207
|
var SWARM_DIR2 = ".swarm";
|
|
113351
114208
|
var OBLIGATION_KEYWORDS = ["MUST", "SHALL", "SHOULD", "MAY"];
|
|
@@ -113398,7 +114255,7 @@ var lint_spec = createSwarmTool({
|
|
|
113398
114255
|
async execute(_args, directory) {
|
|
113399
114256
|
const errors5 = [];
|
|
113400
114257
|
const warnings = [];
|
|
113401
|
-
const specPath =
|
|
114258
|
+
const specPath = path126.join(directory, SWARM_DIR2, SPEC_FILE_NAME);
|
|
113402
114259
|
if (!fs88.existsSync(specPath)) {
|
|
113403
114260
|
const result2 = {
|
|
113404
114261
|
valid: false,
|
|
@@ -113470,12 +114327,12 @@ var lint_spec = createSwarmTool({
|
|
|
113470
114327
|
// src/tools/mutation-test.ts
|
|
113471
114328
|
init_zod();
|
|
113472
114329
|
import * as fs89 from "node:fs";
|
|
113473
|
-
import * as
|
|
114330
|
+
import * as path128 from "node:path";
|
|
113474
114331
|
|
|
113475
114332
|
// src/mutation/engine.ts
|
|
113476
114333
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
113477
|
-
import { unlinkSync as
|
|
113478
|
-
import * as
|
|
114334
|
+
import { unlinkSync as unlinkSync18, writeFileSync as writeFileSync24 } from "node:fs";
|
|
114335
|
+
import * as path127 from "node:path";
|
|
113479
114336
|
|
|
113480
114337
|
// src/mutation/equivalence.ts
|
|
113481
114338
|
function isStaticallyEquivalent(originalCode, mutatedCode) {
|
|
@@ -113621,9 +114478,9 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
|
113621
114478
|
let patchFile;
|
|
113622
114479
|
try {
|
|
113623
114480
|
const safeId2 = patch.id.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
113624
|
-
patchFile =
|
|
114481
|
+
patchFile = path127.join(workingDir, `.mutation_patch_${safeId2}.diff`);
|
|
113625
114482
|
try {
|
|
113626
|
-
|
|
114483
|
+
writeFileSync24(patchFile, patch.patch);
|
|
113627
114484
|
} catch (writeErr) {
|
|
113628
114485
|
error93 = `Failed to write patch file: ${writeErr}`;
|
|
113629
114486
|
outcome = "error";
|
|
@@ -113719,7 +114576,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
|
113719
114576
|
revertError = new Error(`Failed to revert mutation ${patch.id}: ${revertErr}. Working tree may be dirty.`);
|
|
113720
114577
|
}
|
|
113721
114578
|
try {
|
|
113722
|
-
|
|
114579
|
+
unlinkSync18(patchFile);
|
|
113723
114580
|
} catch (_unlinkErr) {}
|
|
113724
114581
|
}
|
|
113725
114582
|
}
|
|
@@ -114025,7 +114882,7 @@ var mutation_test = createSwarmTool({
|
|
|
114025
114882
|
];
|
|
114026
114883
|
for (const filePath of uniquePaths) {
|
|
114027
114884
|
try {
|
|
114028
|
-
const resolvedPath =
|
|
114885
|
+
const resolvedPath = path128.resolve(cwd, filePath);
|
|
114029
114886
|
sourceFiles.set(filePath, fs89.readFileSync(resolvedPath, "utf-8"));
|
|
114030
114887
|
} catch {}
|
|
114031
114888
|
}
|
|
@@ -114047,22 +114904,22 @@ init_config();
|
|
|
114047
114904
|
init_schema();
|
|
114048
114905
|
init_manager2();
|
|
114049
114906
|
import * as fs99 from "node:fs";
|
|
114050
|
-
import * as
|
|
114907
|
+
import * as path138 from "node:path";
|
|
114051
114908
|
|
|
114052
114909
|
// src/full-auto/phase-approval.ts
|
|
114053
114910
|
init_utils2();
|
|
114054
114911
|
init_logger();
|
|
114055
114912
|
init_state2();
|
|
114056
114913
|
import * as fs90 from "node:fs";
|
|
114057
|
-
import * as
|
|
114914
|
+
import * as path129 from "node:path";
|
|
114058
114915
|
var APPROVAL_TTL_MS = 24 * 60 * 60 * 1000;
|
|
114059
114916
|
function readEvidenceDir(directory, phase) {
|
|
114060
114917
|
try {
|
|
114061
|
-
const dirPath = validateSwarmPath(directory,
|
|
114918
|
+
const dirPath = validateSwarmPath(directory, path129.posix.join("evidence", String(phase)));
|
|
114062
114919
|
if (!fs90.existsSync(dirPath))
|
|
114063
114920
|
return [];
|
|
114064
114921
|
const entries = fs90.readdirSync(dirPath);
|
|
114065
|
-
return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) =>
|
|
114922
|
+
return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) => path129.join(dirPath, e));
|
|
114066
114923
|
} catch {
|
|
114067
114924
|
return [];
|
|
114068
114925
|
}
|
|
@@ -114203,16 +115060,16 @@ init_plan_schema();
|
|
|
114203
115060
|
init_ledger();
|
|
114204
115061
|
init_manager();
|
|
114205
115062
|
import * as fs91 from "node:fs";
|
|
114206
|
-
import * as
|
|
115063
|
+
import * as path130 from "node:path";
|
|
114207
115064
|
async function writeCheckpoint(directory) {
|
|
114208
115065
|
try {
|
|
114209
115066
|
const plan = await loadPlan(directory);
|
|
114210
115067
|
if (!plan)
|
|
114211
115068
|
return;
|
|
114212
|
-
const swarmDir =
|
|
115069
|
+
const swarmDir = path130.join(directory, ".swarm");
|
|
114213
115070
|
fs91.mkdirSync(swarmDir, { recursive: true });
|
|
114214
|
-
const jsonPath =
|
|
114215
|
-
const mdPath =
|
|
115071
|
+
const jsonPath = path130.join(swarmDir, "SWARM_PLAN.json");
|
|
115072
|
+
const mdPath = path130.join(swarmDir, "SWARM_PLAN.md");
|
|
114216
115073
|
fs91.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
|
|
114217
115074
|
const md = derivePlanMarkdown(plan);
|
|
114218
115075
|
fs91.writeFileSync(mdPath, md, "utf8");
|
|
@@ -114231,7 +115088,7 @@ init_telemetry();
|
|
|
114231
115088
|
// src/turbo/lean/phase-ready.ts
|
|
114232
115089
|
init_file_locks();
|
|
114233
115090
|
import * as fs92 from "node:fs";
|
|
114234
|
-
import * as
|
|
115091
|
+
import * as path131 from "node:path";
|
|
114235
115092
|
init_state3();
|
|
114236
115093
|
var DEFAULT_CONFIG3 = {
|
|
114237
115094
|
phase_reviewer: true,
|
|
@@ -114240,7 +115097,7 @@ var DEFAULT_CONFIG3 = {
|
|
|
114240
115097
|
};
|
|
114241
115098
|
function defaultReadPlanJson(dir) {
|
|
114242
115099
|
try {
|
|
114243
|
-
const planPath =
|
|
115100
|
+
const planPath = path131.join(dir, ".swarm", "plan.json");
|
|
114244
115101
|
if (!fs92.existsSync(planPath))
|
|
114245
115102
|
return null;
|
|
114246
115103
|
const raw = fs92.readFileSync(planPath, "utf-8");
|
|
@@ -114255,7 +115112,7 @@ function defaultReadPlanJson(dir) {
|
|
|
114255
115112
|
}
|
|
114256
115113
|
function readReviewerEvidenceFromFile(directory, phase) {
|
|
114257
115114
|
try {
|
|
114258
|
-
const evidencePath =
|
|
115115
|
+
const evidencePath = path131.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-reviewer.json");
|
|
114259
115116
|
if (!fs92.existsSync(evidencePath)) {
|
|
114260
115117
|
return null;
|
|
114261
115118
|
}
|
|
@@ -114275,7 +115132,7 @@ function readReviewerEvidenceFromFile(directory, phase) {
|
|
|
114275
115132
|
}
|
|
114276
115133
|
function readCriticEvidenceFromFile(directory, phase) {
|
|
114277
115134
|
try {
|
|
114278
|
-
const evidencePath =
|
|
115135
|
+
const evidencePath = path131.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-critic.json");
|
|
114279
115136
|
if (!fs92.existsSync(evidencePath)) {
|
|
114280
115137
|
return null;
|
|
114281
115138
|
}
|
|
@@ -114294,7 +115151,7 @@ function readCriticEvidenceFromFile(directory, phase) {
|
|
|
114294
115151
|
}
|
|
114295
115152
|
}
|
|
114296
115153
|
function listLaneEvidenceSync(directory, phase) {
|
|
114297
|
-
const evidenceDir =
|
|
115154
|
+
const evidenceDir = path131.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
|
|
114298
115155
|
let entries;
|
|
114299
115156
|
try {
|
|
114300
115157
|
entries = fs92.readdirSync(evidenceDir);
|
|
@@ -114364,7 +115221,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
114364
115221
|
...DEFAULT_CONFIG3,
|
|
114365
115222
|
...actualConfig
|
|
114366
115223
|
};
|
|
114367
|
-
const statePath =
|
|
115224
|
+
const statePath = path131.join(directory, ".swarm", "turbo-state.json");
|
|
114368
115225
|
if (!fs92.existsSync(statePath)) {
|
|
114369
115226
|
return {
|
|
114370
115227
|
ok: false,
|
|
@@ -114552,7 +115409,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
114552
115409
|
}
|
|
114553
115410
|
}
|
|
114554
115411
|
if (mergedConfig.integrated_diff_required) {
|
|
114555
|
-
const evidencePath =
|
|
115412
|
+
const evidencePath = path131.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-phase.json");
|
|
114556
115413
|
let hasDiff = false;
|
|
114557
115414
|
try {
|
|
114558
115415
|
const content = fs92.readFileSync(evidencePath, "utf-8");
|
|
@@ -114704,13 +115561,13 @@ init_qa_gate_profile();
|
|
|
114704
115561
|
init_manager();
|
|
114705
115562
|
init_state();
|
|
114706
115563
|
import * as fs93 from "node:fs";
|
|
114707
|
-
import * as
|
|
115564
|
+
import * as path132 from "node:path";
|
|
114708
115565
|
async function runDriftGate(ctx) {
|
|
114709
115566
|
const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
|
|
114710
115567
|
let driftCheckEnabled = true;
|
|
114711
115568
|
let driftHasSpecMd = false;
|
|
114712
115569
|
try {
|
|
114713
|
-
const specMdPath =
|
|
115570
|
+
const specMdPath = path132.join(dir, ".swarm", "spec.md");
|
|
114714
115571
|
driftHasSpecMd = fs93.existsSync(specMdPath);
|
|
114715
115572
|
const gatePlan = await loadPlan(dir);
|
|
114716
115573
|
if (gatePlan) {
|
|
@@ -114738,7 +115595,7 @@ async function runDriftGate(ctx) {
|
|
|
114738
115595
|
}
|
|
114739
115596
|
let phaseType;
|
|
114740
115597
|
try {
|
|
114741
|
-
const planPath =
|
|
115598
|
+
const planPath = path132.join(dir, ".swarm", "plan.json");
|
|
114742
115599
|
if (fs93.existsSync(planPath)) {
|
|
114743
115600
|
const planRaw = fs93.readFileSync(planPath, "utf-8");
|
|
114744
115601
|
const plan = JSON.parse(planRaw);
|
|
@@ -114757,7 +115614,7 @@ async function runDriftGate(ctx) {
|
|
|
114757
115614
|
};
|
|
114758
115615
|
}
|
|
114759
115616
|
try {
|
|
114760
|
-
const driftEvidencePath =
|
|
115617
|
+
const driftEvidencePath = path132.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
|
|
114761
115618
|
let driftVerdictFound = false;
|
|
114762
115619
|
let driftVerdictApproved = false;
|
|
114763
115620
|
try {
|
|
@@ -114793,7 +115650,7 @@ async function runDriftGate(ctx) {
|
|
|
114793
115650
|
let incompleteTaskCount = 0;
|
|
114794
115651
|
let planParseable = false;
|
|
114795
115652
|
try {
|
|
114796
|
-
const planPath =
|
|
115653
|
+
const planPath = path132.join(dir, ".swarm", "plan.json");
|
|
114797
115654
|
if (fs93.existsSync(planPath)) {
|
|
114798
115655
|
const planRaw = fs93.readFileSync(planPath, "utf-8");
|
|
114799
115656
|
const plan = JSON.parse(planRaw);
|
|
@@ -114875,7 +115732,7 @@ init_qa_gate_profile();
|
|
|
114875
115732
|
init_manager();
|
|
114876
115733
|
init_state();
|
|
114877
115734
|
import * as fs94 from "node:fs";
|
|
114878
|
-
import * as
|
|
115735
|
+
import * as path133 from "node:path";
|
|
114879
115736
|
async function runFinalCouncilGate(ctx) {
|
|
114880
115737
|
const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
|
|
114881
115738
|
let finalCouncilEnabled = false;
|
|
@@ -114892,7 +115749,7 @@ async function runFinalCouncilGate(ctx) {
|
|
|
114892
115749
|
const effective = getEffectiveGates(profile, overrides);
|
|
114893
115750
|
if (effective.final_council === true) {
|
|
114894
115751
|
finalCouncilEnabled = true;
|
|
114895
|
-
const fcPath =
|
|
115752
|
+
const fcPath = path133.join(dir, ".swarm", "evidence", "final-council.json");
|
|
114896
115753
|
let fcVerdictFound = false;
|
|
114897
115754
|
let _fcVerdict;
|
|
114898
115755
|
try {
|
|
@@ -115022,7 +115879,7 @@ init_qa_gate_profile();
|
|
|
115022
115879
|
init_manager();
|
|
115023
115880
|
init_state();
|
|
115024
115881
|
import * as fs95 from "node:fs";
|
|
115025
|
-
import * as
|
|
115882
|
+
import * as path134 from "node:path";
|
|
115026
115883
|
async function runHallucinationGate(ctx) {
|
|
115027
115884
|
const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
|
|
115028
115885
|
try {
|
|
@@ -115035,7 +115892,7 @@ async function runHallucinationGate(ctx) {
|
|
|
115035
115892
|
const overrides = session?.qaGateSessionOverrides ?? {};
|
|
115036
115893
|
const effective = getEffectiveGates(profile, overrides);
|
|
115037
115894
|
if (effective.hallucination_guard === true) {
|
|
115038
|
-
const hgPath =
|
|
115895
|
+
const hgPath = path134.join(dir, ".swarm", "evidence", String(phase), "hallucination-guard.json");
|
|
115039
115896
|
let hgVerdictFound = false;
|
|
115040
115897
|
let hgVerdictApproved = false;
|
|
115041
115898
|
try {
|
|
@@ -115098,7 +115955,7 @@ init_qa_gate_profile();
|
|
|
115098
115955
|
init_manager();
|
|
115099
115956
|
init_state();
|
|
115100
115957
|
import * as fs96 from "node:fs";
|
|
115101
|
-
import * as
|
|
115958
|
+
import * as path135 from "node:path";
|
|
115102
115959
|
async function runMutationGate(ctx) {
|
|
115103
115960
|
const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
|
|
115104
115961
|
try {
|
|
@@ -115111,7 +115968,7 @@ async function runMutationGate(ctx) {
|
|
|
115111
115968
|
const overrides = session?.qaGateSessionOverrides ?? {};
|
|
115112
115969
|
const effective = getEffectiveGates(profile, overrides);
|
|
115113
115970
|
if (effective.mutation_test === true) {
|
|
115114
|
-
const mgPath =
|
|
115971
|
+
const mgPath = path135.join(dir, ".swarm", "evidence", String(phase), "mutation-gate.json");
|
|
115115
115972
|
let mgVerdictFound = false;
|
|
115116
115973
|
let mgVerdict;
|
|
115117
115974
|
try {
|
|
@@ -115174,7 +116031,7 @@ init_qa_gate_profile();
|
|
|
115174
116031
|
init_manager();
|
|
115175
116032
|
init_state();
|
|
115176
116033
|
import * as fs97 from "node:fs";
|
|
115177
|
-
import * as
|
|
116034
|
+
import * as path136 from "node:path";
|
|
115178
116035
|
async function runPhaseCouncilGate(ctx) {
|
|
115179
116036
|
const { phase, dir, sessionID, pluginConfig, agentsDispatched, safeWarn } = ctx;
|
|
115180
116037
|
let councilModeEnabled = false;
|
|
@@ -115189,7 +116046,7 @@ async function runPhaseCouncilGate(ctx) {
|
|
|
115189
116046
|
const effective = getEffectiveGates(profile, overrides);
|
|
115190
116047
|
if (effective.council_mode === true) {
|
|
115191
116048
|
councilModeEnabled = true;
|
|
115192
|
-
const pcPath =
|
|
116049
|
+
const pcPath = path136.join(dir, ".swarm", "evidence", String(phase), "phase-council.json");
|
|
115193
116050
|
let pcVerdictFound = false;
|
|
115194
116051
|
let _pcVerdict;
|
|
115195
116052
|
let pcQuorumSize;
|
|
@@ -115704,7 +116561,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
115704
116561
|
}
|
|
115705
116562
|
if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
|
|
115706
116563
|
try {
|
|
115707
|
-
const projectName =
|
|
116564
|
+
const projectName = path138.basename(dir);
|
|
115708
116565
|
const curationResult = await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig);
|
|
115709
116566
|
if (curationResult) {
|
|
115710
116567
|
const sessionState = swarmState.agentSessions.get(sessionID);
|
|
@@ -116147,7 +117004,7 @@ init_utils();
|
|
|
116147
117004
|
init_bun_compat();
|
|
116148
117005
|
init_create_tool();
|
|
116149
117006
|
import * as fs100 from "node:fs";
|
|
116150
|
-
import * as
|
|
117007
|
+
import * as path139 from "node:path";
|
|
116151
117008
|
var MAX_OUTPUT_BYTES6 = 52428800;
|
|
116152
117009
|
var AUDIT_TIMEOUT_MS = 120000;
|
|
116153
117010
|
function isValidEcosystem(value) {
|
|
@@ -116175,16 +117032,16 @@ function validateArgs3(args2) {
|
|
|
116175
117032
|
function detectEcosystems(directory) {
|
|
116176
117033
|
const ecosystems = [];
|
|
116177
117034
|
const cwd = directory;
|
|
116178
|
-
if (fs100.existsSync(
|
|
117035
|
+
if (fs100.existsSync(path139.join(cwd, "package.json"))) {
|
|
116179
117036
|
ecosystems.push("npm");
|
|
116180
117037
|
}
|
|
116181
|
-
if (fs100.existsSync(
|
|
117038
|
+
if (fs100.existsSync(path139.join(cwd, "pyproject.toml")) || fs100.existsSync(path139.join(cwd, "requirements.txt"))) {
|
|
116182
117039
|
ecosystems.push("pip");
|
|
116183
117040
|
}
|
|
116184
|
-
if (fs100.existsSync(
|
|
117041
|
+
if (fs100.existsSync(path139.join(cwd, "Cargo.toml"))) {
|
|
116185
117042
|
ecosystems.push("cargo");
|
|
116186
117043
|
}
|
|
116187
|
-
if (fs100.existsSync(
|
|
117044
|
+
if (fs100.existsSync(path139.join(cwd, "go.mod"))) {
|
|
116188
117045
|
ecosystems.push("go");
|
|
116189
117046
|
}
|
|
116190
117047
|
try {
|
|
@@ -116193,13 +117050,13 @@ function detectEcosystems(directory) {
|
|
|
116193
117050
|
ecosystems.push("dotnet");
|
|
116194
117051
|
}
|
|
116195
117052
|
} catch {}
|
|
116196
|
-
if (fs100.existsSync(
|
|
117053
|
+
if (fs100.existsSync(path139.join(cwd, "Gemfile")) || fs100.existsSync(path139.join(cwd, "Gemfile.lock"))) {
|
|
116197
117054
|
ecosystems.push("ruby");
|
|
116198
117055
|
}
|
|
116199
|
-
if (fs100.existsSync(
|
|
117056
|
+
if (fs100.existsSync(path139.join(cwd, "pubspec.yaml"))) {
|
|
116200
117057
|
ecosystems.push("dart");
|
|
116201
117058
|
}
|
|
116202
|
-
if (fs100.existsSync(
|
|
117059
|
+
if (fs100.existsSync(path139.join(cwd, "composer.lock"))) {
|
|
116203
117060
|
ecosystems.push("composer");
|
|
116204
117061
|
}
|
|
116205
117062
|
return ecosystems;
|
|
@@ -116212,7 +117069,7 @@ async function runNpmAudit(directory) {
|
|
|
116212
117069
|
stderr: "pipe",
|
|
116213
117070
|
cwd: directory
|
|
116214
117071
|
});
|
|
116215
|
-
const timeoutPromise = new Promise((
|
|
117072
|
+
const timeoutPromise = new Promise((resolve46) => setTimeout(() => resolve46("timeout"), AUDIT_TIMEOUT_MS));
|
|
116216
117073
|
const result = await Promise.race([
|
|
116217
117074
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
|
|
116218
117075
|
timeoutPromise
|
|
@@ -116332,7 +117189,7 @@ async function runPipAudit(directory) {
|
|
|
116332
117189
|
stderr: "pipe",
|
|
116333
117190
|
cwd: directory
|
|
116334
117191
|
});
|
|
116335
|
-
const timeoutPromise = new Promise((
|
|
117192
|
+
const timeoutPromise = new Promise((resolve46) => setTimeout(() => resolve46("timeout"), AUDIT_TIMEOUT_MS));
|
|
116336
117193
|
const result = await Promise.race([
|
|
116337
117194
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
|
|
116338
117195
|
timeoutPromise
|
|
@@ -116460,7 +117317,7 @@ async function runCargoAudit(directory) {
|
|
|
116460
117317
|
stderr: "pipe",
|
|
116461
117318
|
cwd: directory
|
|
116462
117319
|
});
|
|
116463
|
-
const timeoutPromise = new Promise((
|
|
117320
|
+
const timeoutPromise = new Promise((resolve46) => setTimeout(() => resolve46("timeout"), AUDIT_TIMEOUT_MS));
|
|
116464
117321
|
const result = await Promise.race([
|
|
116465
117322
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
116466
117323
|
timeoutPromise
|
|
@@ -116584,7 +117441,7 @@ async function runGoAudit(directory) {
|
|
|
116584
117441
|
stderr: "pipe",
|
|
116585
117442
|
cwd: directory
|
|
116586
117443
|
});
|
|
116587
|
-
const timeoutPromise = new Promise((
|
|
117444
|
+
const timeoutPromise = new Promise((resolve46) => setTimeout(() => resolve46("timeout"), AUDIT_TIMEOUT_MS));
|
|
116588
117445
|
const result = await Promise.race([
|
|
116589
117446
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
116590
117447
|
timeoutPromise
|
|
@@ -116717,7 +117574,7 @@ async function runDotnetAudit(directory) {
|
|
|
116717
117574
|
stderr: "pipe",
|
|
116718
117575
|
cwd: directory
|
|
116719
117576
|
});
|
|
116720
|
-
const timeoutPromise = new Promise((
|
|
117577
|
+
const timeoutPromise = new Promise((resolve46) => setTimeout(() => resolve46("timeout"), AUDIT_TIMEOUT_MS));
|
|
116721
117578
|
const result = await Promise.race([
|
|
116722
117579
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
116723
117580
|
timeoutPromise
|
|
@@ -116833,7 +117690,7 @@ async function runBundleAudit(directory) {
|
|
|
116833
117690
|
stderr: "pipe",
|
|
116834
117691
|
cwd: directory
|
|
116835
117692
|
});
|
|
116836
|
-
const timeoutPromise = new Promise((
|
|
117693
|
+
const timeoutPromise = new Promise((resolve46) => setTimeout(() => resolve46("timeout"), AUDIT_TIMEOUT_MS));
|
|
116837
117694
|
const result = await Promise.race([
|
|
116838
117695
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
116839
117696
|
timeoutPromise
|
|
@@ -116978,7 +117835,7 @@ async function runDartAudit(directory) {
|
|
|
116978
117835
|
stderr: "pipe",
|
|
116979
117836
|
cwd: directory
|
|
116980
117837
|
});
|
|
116981
|
-
const timeoutPromise = new Promise((
|
|
117838
|
+
const timeoutPromise = new Promise((resolve46) => setTimeout(() => resolve46("timeout"), AUDIT_TIMEOUT_MS));
|
|
116982
117839
|
const result = await Promise.race([
|
|
116983
117840
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
116984
117841
|
timeoutPromise
|
|
@@ -117093,7 +117950,7 @@ async function runComposerAudit(directory) {
|
|
|
117093
117950
|
stderr: "pipe",
|
|
117094
117951
|
cwd: directory
|
|
117095
117952
|
});
|
|
117096
|
-
const timeoutPromise = new Promise((
|
|
117953
|
+
const timeoutPromise = new Promise((resolve46) => setTimeout(() => resolve46("timeout"), AUDIT_TIMEOUT_MS));
|
|
117097
117954
|
const result = await Promise.race([
|
|
117098
117955
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
117099
117956
|
timeoutPromise
|
|
@@ -117336,7 +118193,7 @@ var pkg_audit = createSwarmTool({
|
|
|
117336
118193
|
init_zod();
|
|
117337
118194
|
init_manager2();
|
|
117338
118195
|
import * as fs101 from "node:fs";
|
|
117339
|
-
import * as
|
|
118196
|
+
import * as path140 from "node:path";
|
|
117340
118197
|
init_utils();
|
|
117341
118198
|
init_create_tool();
|
|
117342
118199
|
var MAX_FILE_SIZE = 1024 * 1024;
|
|
@@ -117459,7 +118316,7 @@ function isScaffoldFile(filePath) {
|
|
|
117459
118316
|
if (SCAFFOLD_PATH_PATTERNS.some((pattern) => pattern.test(normalizedPath))) {
|
|
117460
118317
|
return true;
|
|
117461
118318
|
}
|
|
117462
|
-
const filename =
|
|
118319
|
+
const filename = path140.basename(filePath);
|
|
117463
118320
|
if (SCAFFOLD_FILENAME_PATTERNS.some((pattern) => pattern.test(filename))) {
|
|
117464
118321
|
return true;
|
|
117465
118322
|
}
|
|
@@ -117476,7 +118333,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
117476
118333
|
if (regex.test(normalizedPath)) {
|
|
117477
118334
|
return true;
|
|
117478
118335
|
}
|
|
117479
|
-
const filename =
|
|
118336
|
+
const filename = path140.basename(filePath);
|
|
117480
118337
|
const filenameRegex = new RegExp(`^${regexPattern}$`, "i");
|
|
117481
118338
|
if (filenameRegex.test(filename)) {
|
|
117482
118339
|
return true;
|
|
@@ -117485,7 +118342,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
117485
118342
|
return false;
|
|
117486
118343
|
}
|
|
117487
118344
|
function isParserSupported(filePath) {
|
|
117488
|
-
const ext =
|
|
118345
|
+
const ext = path140.extname(filePath).toLowerCase();
|
|
117489
118346
|
return SUPPORTED_PARSER_EXTENSIONS.has(ext);
|
|
117490
118347
|
}
|
|
117491
118348
|
function isPlanFile(filePath) {
|
|
@@ -117732,9 +118589,9 @@ async function placeholderScan(input, directory) {
|
|
|
117732
118589
|
let filesScanned = 0;
|
|
117733
118590
|
const filesWithFindings = new Set;
|
|
117734
118591
|
for (const filePath of changed_files) {
|
|
117735
|
-
const fullPath =
|
|
117736
|
-
const resolvedDirectory =
|
|
117737
|
-
if (!fullPath.startsWith(resolvedDirectory +
|
|
118592
|
+
const fullPath = path140.isAbsolute(filePath) ? filePath : path140.resolve(directory, filePath);
|
|
118593
|
+
const resolvedDirectory = path140.resolve(directory);
|
|
118594
|
+
if (!fullPath.startsWith(resolvedDirectory + path140.sep) && fullPath !== resolvedDirectory) {
|
|
117738
118595
|
continue;
|
|
117739
118596
|
}
|
|
117740
118597
|
if (!fs101.existsSync(fullPath)) {
|
|
@@ -117743,7 +118600,7 @@ async function placeholderScan(input, directory) {
|
|
|
117743
118600
|
if (isAllowedByGlobs(filePath, allow_globs)) {
|
|
117744
118601
|
continue;
|
|
117745
118602
|
}
|
|
117746
|
-
const relativeFilePath =
|
|
118603
|
+
const relativeFilePath = path140.relative(directory, fullPath).replace(/\\/g, "/");
|
|
117747
118604
|
if (FILE_ALLOWLIST.some((allowed) => relativeFilePath.endsWith(allowed))) {
|
|
117748
118605
|
continue;
|
|
117749
118606
|
}
|
|
@@ -117816,7 +118673,7 @@ var placeholder_scan = createSwarmTool({
|
|
|
117816
118673
|
|
|
117817
118674
|
// src/tools/pre-check-batch.ts
|
|
117818
118675
|
import * as fs105 from "node:fs";
|
|
117819
|
-
import * as
|
|
118676
|
+
import * as path144 from "node:path";
|
|
117820
118677
|
init_zod();
|
|
117821
118678
|
init_manager2();
|
|
117822
118679
|
init_utils();
|
|
@@ -117957,7 +118814,7 @@ init_zod();
|
|
|
117957
118814
|
init_manager2();
|
|
117958
118815
|
init_detector();
|
|
117959
118816
|
import * as fs104 from "node:fs";
|
|
117960
|
-
import * as
|
|
118817
|
+
import * as path143 from "node:path";
|
|
117961
118818
|
import { extname as extname20 } from "node:path";
|
|
117962
118819
|
|
|
117963
118820
|
// src/sast/rules/c.ts
|
|
@@ -118673,7 +119530,7 @@ function executeRulesSync(filePath, content, language) {
|
|
|
118673
119530
|
// src/sast/semgrep.ts
|
|
118674
119531
|
import * as child_process9 from "node:child_process";
|
|
118675
119532
|
import * as fs102 from "node:fs";
|
|
118676
|
-
import * as
|
|
119533
|
+
import * as path141 from "node:path";
|
|
118677
119534
|
var semgrepAvailableCache = null;
|
|
118678
119535
|
var DEFAULT_RULES_DIR = ".swarm/semgrep-rules";
|
|
118679
119536
|
var DEFAULT_TIMEOUT_MS3 = 30000;
|
|
@@ -118754,7 +119611,7 @@ function mapSemgrepSeverity(severity) {
|
|
|
118754
119611
|
}
|
|
118755
119612
|
}
|
|
118756
119613
|
async function executeWithTimeout(command, args2, options) {
|
|
118757
|
-
return new Promise((
|
|
119614
|
+
return new Promise((resolve48) => {
|
|
118758
119615
|
const child = child_process9.spawn(command, args2, {
|
|
118759
119616
|
shell: false,
|
|
118760
119617
|
cwd: options.cwd
|
|
@@ -118763,7 +119620,7 @@ async function executeWithTimeout(command, args2, options) {
|
|
|
118763
119620
|
let stderr = "";
|
|
118764
119621
|
const timeout = setTimeout(() => {
|
|
118765
119622
|
child.kill("SIGTERM");
|
|
118766
|
-
|
|
119623
|
+
resolve48({
|
|
118767
119624
|
stdout,
|
|
118768
119625
|
stderr: "Process timed out",
|
|
118769
119626
|
exitCode: 124
|
|
@@ -118777,7 +119634,7 @@ async function executeWithTimeout(command, args2, options) {
|
|
|
118777
119634
|
});
|
|
118778
119635
|
child.on("close", (code) => {
|
|
118779
119636
|
clearTimeout(timeout);
|
|
118780
|
-
|
|
119637
|
+
resolve48({
|
|
118781
119638
|
stdout,
|
|
118782
119639
|
stderr,
|
|
118783
119640
|
exitCode: code ?? 0
|
|
@@ -118785,7 +119642,7 @@ async function executeWithTimeout(command, args2, options) {
|
|
|
118785
119642
|
});
|
|
118786
119643
|
child.on("error", (err2) => {
|
|
118787
119644
|
clearTimeout(timeout);
|
|
118788
|
-
|
|
119645
|
+
resolve48({
|
|
118789
119646
|
stdout,
|
|
118790
119647
|
stderr: err2.message,
|
|
118791
119648
|
exitCode: 1
|
|
@@ -118860,7 +119717,7 @@ async function runSemgrep(options) {
|
|
|
118860
119717
|
}
|
|
118861
119718
|
function getRulesDirectory(projectRoot) {
|
|
118862
119719
|
if (projectRoot) {
|
|
118863
|
-
return
|
|
119720
|
+
return path141.resolve(projectRoot, DEFAULT_RULES_DIR);
|
|
118864
119721
|
}
|
|
118865
119722
|
return DEFAULT_RULES_DIR;
|
|
118866
119723
|
}
|
|
@@ -118881,24 +119738,24 @@ init_create_tool();
|
|
|
118881
119738
|
init_utils2();
|
|
118882
119739
|
import * as crypto11 from "node:crypto";
|
|
118883
119740
|
import * as fs103 from "node:fs";
|
|
118884
|
-
import * as
|
|
119741
|
+
import * as path142 from "node:path";
|
|
118885
119742
|
var BASELINE_SCHEMA_VERSION = "1.0.0";
|
|
118886
119743
|
var MAX_BASELINE_FINDINGS = 2000;
|
|
118887
119744
|
var MAX_BASELINE_BYTES = 2 * 1048576;
|
|
118888
119745
|
var LOCK_RETRY_DELAYS_MS = [50, 100, 200, 400, 800];
|
|
118889
119746
|
function normalizeFindingPath(directory, file3) {
|
|
118890
|
-
const resolved =
|
|
118891
|
-
const rel =
|
|
119747
|
+
const resolved = path142.isAbsolute(file3) ? file3 : path142.resolve(directory, file3);
|
|
119748
|
+
const rel = path142.relative(path142.resolve(directory), resolved);
|
|
118892
119749
|
return rel.replace(/\\/g, "/");
|
|
118893
119750
|
}
|
|
118894
119751
|
function baselineRelPath(phase) {
|
|
118895
|
-
return
|
|
119752
|
+
return path142.join("evidence", String(phase), "sast-baseline.json");
|
|
118896
119753
|
}
|
|
118897
119754
|
function tempRelPath(phase) {
|
|
118898
|
-
return
|
|
119755
|
+
return path142.join("evidence", String(phase), `sast-baseline.json.tmp.${Date.now()}.${process.pid}`);
|
|
118899
119756
|
}
|
|
118900
119757
|
function lockRelPath(phase) {
|
|
118901
|
-
return
|
|
119758
|
+
return path142.join("evidence", String(phase), "sast-baseline.json.lock");
|
|
118902
119759
|
}
|
|
118903
119760
|
function getLine(lines, idx) {
|
|
118904
119761
|
if (idx < 0 || idx >= lines.length)
|
|
@@ -118984,7 +119841,7 @@ async function acquireLock2(lockPath) {
|
|
|
118984
119841
|
};
|
|
118985
119842
|
} catch {
|
|
118986
119843
|
if (attempt < LOCK_RETRY_DELAYS_MS.length) {
|
|
118987
|
-
await new Promise((
|
|
119844
|
+
await new Promise((resolve49) => setTimeout(resolve49, LOCK_RETRY_DELAYS_MS[attempt]));
|
|
118988
119845
|
}
|
|
118989
119846
|
}
|
|
118990
119847
|
}
|
|
@@ -119019,8 +119876,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
119019
119876
|
message: e instanceof Error ? e.message : "Path validation failed"
|
|
119020
119877
|
};
|
|
119021
119878
|
}
|
|
119022
|
-
fs103.mkdirSync(
|
|
119023
|
-
fs103.mkdirSync(
|
|
119879
|
+
fs103.mkdirSync(path142.dirname(baselinePath), { recursive: true });
|
|
119880
|
+
fs103.mkdirSync(path142.dirname(tempPath), { recursive: true });
|
|
119024
119881
|
const releaseLock = await acquireLock2(lockPath);
|
|
119025
119882
|
try {
|
|
119026
119883
|
let existing = null;
|
|
@@ -119293,9 +120150,9 @@ async function sastScan(input, directory, config3) {
|
|
|
119293
120150
|
_filesSkipped++;
|
|
119294
120151
|
continue;
|
|
119295
120152
|
}
|
|
119296
|
-
const resolvedPath =
|
|
119297
|
-
const resolvedDirectory =
|
|
119298
|
-
if (!resolvedPath.startsWith(resolvedDirectory +
|
|
120153
|
+
const resolvedPath = path143.isAbsolute(filePath) ? filePath : path143.resolve(directory, filePath);
|
|
120154
|
+
const resolvedDirectory = path143.resolve(directory);
|
|
120155
|
+
if (!resolvedPath.startsWith(resolvedDirectory + path143.sep) && resolvedPath !== resolvedDirectory) {
|
|
119299
120156
|
_filesSkipped++;
|
|
119300
120157
|
continue;
|
|
119301
120158
|
}
|
|
@@ -119610,20 +120467,20 @@ function validatePath(inputPath, baseDir, workspaceDir) {
|
|
|
119610
120467
|
let resolved;
|
|
119611
120468
|
const isWinAbs = isWindowsAbsolutePath(inputPath);
|
|
119612
120469
|
if (isWinAbs) {
|
|
119613
|
-
resolved =
|
|
119614
|
-
} else if (
|
|
119615
|
-
resolved =
|
|
120470
|
+
resolved = path144.win32.resolve(inputPath);
|
|
120471
|
+
} else if (path144.isAbsolute(inputPath)) {
|
|
120472
|
+
resolved = path144.resolve(inputPath);
|
|
119616
120473
|
} else {
|
|
119617
|
-
resolved =
|
|
120474
|
+
resolved = path144.resolve(baseDir, inputPath);
|
|
119618
120475
|
}
|
|
119619
|
-
const workspaceResolved =
|
|
119620
|
-
let
|
|
120476
|
+
const workspaceResolved = path144.resolve(workspaceDir);
|
|
120477
|
+
let relative28;
|
|
119621
120478
|
if (isWinAbs) {
|
|
119622
|
-
|
|
120479
|
+
relative28 = path144.win32.relative(workspaceResolved, resolved);
|
|
119623
120480
|
} else {
|
|
119624
|
-
|
|
120481
|
+
relative28 = path144.relative(workspaceResolved, resolved);
|
|
119625
120482
|
}
|
|
119626
|
-
if (
|
|
120483
|
+
if (relative28.startsWith("..")) {
|
|
119627
120484
|
return "path traversal detected";
|
|
119628
120485
|
}
|
|
119629
120486
|
return null;
|
|
@@ -119686,7 +120543,7 @@ async function runLintOnFiles(linter, files, workspaceDir) {
|
|
|
119686
120543
|
if (typeof file3 !== "string") {
|
|
119687
120544
|
continue;
|
|
119688
120545
|
}
|
|
119689
|
-
const resolvedPath =
|
|
120546
|
+
const resolvedPath = path144.resolve(file3);
|
|
119690
120547
|
const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
|
|
119691
120548
|
if (validationError) {
|
|
119692
120549
|
continue;
|
|
@@ -119843,7 +120700,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
119843
120700
|
skippedFiles++;
|
|
119844
120701
|
continue;
|
|
119845
120702
|
}
|
|
119846
|
-
const resolvedPath =
|
|
120703
|
+
const resolvedPath = path144.resolve(file3);
|
|
119847
120704
|
const validationError = validatePath(resolvedPath, directory, directory);
|
|
119848
120705
|
if (validationError) {
|
|
119849
120706
|
skippedFiles++;
|
|
@@ -119861,7 +120718,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
119861
120718
|
};
|
|
119862
120719
|
}
|
|
119863
120720
|
for (const file3 of validatedFiles) {
|
|
119864
|
-
const ext =
|
|
120721
|
+
const ext = path144.extname(file3).toLowerCase();
|
|
119865
120722
|
if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
|
|
119866
120723
|
skippedFiles++;
|
|
119867
120724
|
continue;
|
|
@@ -120080,7 +120937,7 @@ function classifySastFindings(findings, changedLineRanges, directory) {
|
|
|
120080
120937
|
const preexistingFindings = [];
|
|
120081
120938
|
for (const finding of findings) {
|
|
120082
120939
|
const filePath = finding.location.file;
|
|
120083
|
-
const normalised =
|
|
120940
|
+
const normalised = path144.relative(directory, filePath).replace(/\\/g, "/");
|
|
120084
120941
|
const changedLines = changedLineRanges.get(normalised);
|
|
120085
120942
|
if (changedLines?.has(finding.location.line)) {
|
|
120086
120943
|
newFindings.push(finding);
|
|
@@ -120131,7 +120988,7 @@ async function runPreCheckBatch(input, workspaceDir, contextDir) {
|
|
|
120131
120988
|
warn(`pre_check_batch: Invalid file path: ${file3}`);
|
|
120132
120989
|
continue;
|
|
120133
120990
|
}
|
|
120134
|
-
changedFiles.push(
|
|
120991
|
+
changedFiles.push(path144.resolve(directory, file3));
|
|
120135
120992
|
}
|
|
120136
120993
|
if (changedFiles.length === 0) {
|
|
120137
120994
|
warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
|
|
@@ -120332,9 +121189,9 @@ var pre_check_batch = createSwarmTool({
|
|
|
120332
121189
|
};
|
|
120333
121190
|
return JSON.stringify(errorResult, null, 2);
|
|
120334
121191
|
}
|
|
120335
|
-
const resolvedDirectory =
|
|
120336
|
-
const workspaceAnchor =
|
|
120337
|
-
if (resolvedDirectory !== workspaceAnchor && resolvedDirectory.startsWith(workspaceAnchor +
|
|
121192
|
+
const resolvedDirectory = path144.resolve(typedArgs.directory);
|
|
121193
|
+
const workspaceAnchor = path144.resolve(directory);
|
|
121194
|
+
if (resolvedDirectory !== workspaceAnchor && resolvedDirectory.startsWith(workspaceAnchor + path144.sep)) {
|
|
120338
121195
|
const subDirError = `directory "${typedArgs.directory}" is a subdirectory of the project root — pre_check_batch requires the project root directory "${workspaceAnchor}"`;
|
|
120339
121196
|
const subDirResult = {
|
|
120340
121197
|
gates_passed: false,
|
|
@@ -120386,7 +121243,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
120386
121243
|
|
|
120387
121244
|
// src/tools/repo-map.ts
|
|
120388
121245
|
init_zod();
|
|
120389
|
-
import * as
|
|
121246
|
+
import * as path145 from "node:path";
|
|
120390
121247
|
init_path_security();
|
|
120391
121248
|
init_create_tool();
|
|
120392
121249
|
var VALID_ACTIONS = [
|
|
@@ -120411,7 +121268,7 @@ function validateFile(p) {
|
|
|
120411
121268
|
return "file contains control characters";
|
|
120412
121269
|
if (containsPathTraversal(p))
|
|
120413
121270
|
return "file contains path traversal";
|
|
120414
|
-
if (
|
|
121271
|
+
if (path145.isAbsolute(p) || /^[a-zA-Z]:[\\/]/.test(p)) {
|
|
120415
121272
|
return "file must be a workspace-relative path, not absolute";
|
|
120416
121273
|
}
|
|
120417
121274
|
return null;
|
|
@@ -120434,8 +121291,8 @@ function ok(action, payload) {
|
|
|
120434
121291
|
}
|
|
120435
121292
|
function toRelativeGraphPath(input, workspaceRoot) {
|
|
120436
121293
|
const normalized = input.replace(/\\/g, "/");
|
|
120437
|
-
if (
|
|
120438
|
-
const rel =
|
|
121294
|
+
if (path145.isAbsolute(normalized)) {
|
|
121295
|
+
const rel = path145.relative(workspaceRoot, normalized).replace(/\\/g, "/");
|
|
120439
121296
|
return normalizeGraphPath2(rel);
|
|
120440
121297
|
}
|
|
120441
121298
|
return normalizeGraphPath2(normalized);
|
|
@@ -120581,7 +121438,7 @@ var repo_map = createSwarmTool({
|
|
|
120581
121438
|
init_zod();
|
|
120582
121439
|
init_create_tool();
|
|
120583
121440
|
import * as fs106 from "node:fs";
|
|
120584
|
-
import * as
|
|
121441
|
+
import * as path146 from "node:path";
|
|
120585
121442
|
var SPEC_FILE = ".swarm/spec.md";
|
|
120586
121443
|
var EVIDENCE_DIR4 = ".swarm/evidence";
|
|
120587
121444
|
var OBLIGATION_KEYWORDS2 = ["MUST", "SHOULD", "SHALL"];
|
|
@@ -120650,7 +121507,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
120650
121507
|
return [];
|
|
120651
121508
|
}
|
|
120652
121509
|
for (const entry of entries) {
|
|
120653
|
-
const entryPath =
|
|
121510
|
+
const entryPath = path146.join(evidenceDir, entry);
|
|
120654
121511
|
try {
|
|
120655
121512
|
const stat9 = fs106.statSync(entryPath);
|
|
120656
121513
|
if (!stat9.isDirectory()) {
|
|
@@ -120666,11 +121523,11 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
120666
121523
|
if (entryPhase !== String(phase)) {
|
|
120667
121524
|
continue;
|
|
120668
121525
|
}
|
|
120669
|
-
const evidenceFilePath =
|
|
121526
|
+
const evidenceFilePath = path146.join(entryPath, "evidence.json");
|
|
120670
121527
|
try {
|
|
120671
|
-
const resolvedPath =
|
|
120672
|
-
const evidenceDirResolved =
|
|
120673
|
-
if (!resolvedPath.startsWith(evidenceDirResolved +
|
|
121528
|
+
const resolvedPath = path146.resolve(evidenceFilePath);
|
|
121529
|
+
const evidenceDirResolved = path146.resolve(evidenceDir);
|
|
121530
|
+
if (!resolvedPath.startsWith(evidenceDirResolved + path146.sep)) {
|
|
120674
121531
|
continue;
|
|
120675
121532
|
}
|
|
120676
121533
|
const stat9 = fs106.lstatSync(evidenceFilePath);
|
|
@@ -120704,7 +121561,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
120704
121561
|
if (Array.isArray(diffEntry.files_changed)) {
|
|
120705
121562
|
for (const file3 of diffEntry.files_changed) {
|
|
120706
121563
|
if (typeof file3 === "string") {
|
|
120707
|
-
touchedFiles.add(
|
|
121564
|
+
touchedFiles.add(path146.resolve(cwd, file3));
|
|
120708
121565
|
}
|
|
120709
121566
|
}
|
|
120710
121567
|
}
|
|
@@ -120717,8 +121574,8 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
120717
121574
|
}
|
|
120718
121575
|
function searchFileForKeywords(filePath, keywords, cwd) {
|
|
120719
121576
|
try {
|
|
120720
|
-
const resolvedPath =
|
|
120721
|
-
const cwdResolved =
|
|
121577
|
+
const resolvedPath = path146.resolve(filePath);
|
|
121578
|
+
const cwdResolved = path146.resolve(cwd);
|
|
120722
121579
|
if (!resolvedPath.startsWith(cwdResolved)) {
|
|
120723
121580
|
return false;
|
|
120724
121581
|
}
|
|
@@ -120852,7 +121709,7 @@ var req_coverage = createSwarmTool({
|
|
|
120852
121709
|
}, null, 2);
|
|
120853
121710
|
}
|
|
120854
121711
|
const cwd = inputDirectory || directory;
|
|
120855
|
-
const specPath =
|
|
121712
|
+
const specPath = path146.join(cwd, SPEC_FILE);
|
|
120856
121713
|
let specContent;
|
|
120857
121714
|
try {
|
|
120858
121715
|
specContent = fs106.readFileSync(specPath, "utf-8");
|
|
@@ -120879,7 +121736,7 @@ var req_coverage = createSwarmTool({
|
|
|
120879
121736
|
message: "No FR requirements found in spec.md"
|
|
120880
121737
|
}, null, 2);
|
|
120881
121738
|
}
|
|
120882
|
-
const evidenceDir =
|
|
121739
|
+
const evidenceDir = path146.join(cwd, EVIDENCE_DIR4);
|
|
120883
121740
|
const touchedFiles = readTouchedFiles(evidenceDir, phase, cwd);
|
|
120884
121741
|
const analyzedRequirements = [];
|
|
120885
121742
|
let coveredCount = 0;
|
|
@@ -120905,7 +121762,7 @@ var req_coverage = createSwarmTool({
|
|
|
120905
121762
|
requirements: analyzedRequirements
|
|
120906
121763
|
};
|
|
120907
121764
|
const reportFilename = `req-coverage-phase-${phase}.json`;
|
|
120908
|
-
const reportPath =
|
|
121765
|
+
const reportPath = path146.join(evidenceDir, reportFilename);
|
|
120909
121766
|
try {
|
|
120910
121767
|
if (!fs106.existsSync(evidenceDir)) {
|
|
120911
121768
|
fs106.mkdirSync(evidenceDir, { recursive: true });
|
|
@@ -120995,7 +121852,7 @@ init_qa_gate_profile();
|
|
|
120995
121852
|
init_file_locks();
|
|
120996
121853
|
import * as crypto12 from "node:crypto";
|
|
120997
121854
|
import * as fs107 from "node:fs";
|
|
120998
|
-
import * as
|
|
121855
|
+
import * as path147 from "node:path";
|
|
120999
121856
|
init_ledger();
|
|
121000
121857
|
init_manager();
|
|
121001
121858
|
init_state();
|
|
@@ -121076,8 +121933,8 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
121076
121933
|
};
|
|
121077
121934
|
}
|
|
121078
121935
|
if (args2.working_directory && fallbackDir) {
|
|
121079
|
-
const resolvedTarget =
|
|
121080
|
-
const resolvedRoot =
|
|
121936
|
+
const resolvedTarget = path147.resolve(args2.working_directory);
|
|
121937
|
+
const resolvedRoot = path147.resolve(fallbackDir);
|
|
121081
121938
|
let fallbackExists = false;
|
|
121082
121939
|
try {
|
|
121083
121940
|
fs107.accessSync(resolvedRoot, fs107.constants.F_OK);
|
|
@@ -121086,7 +121943,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
121086
121943
|
fallbackExists = false;
|
|
121087
121944
|
}
|
|
121088
121945
|
if (fallbackExists) {
|
|
121089
|
-
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot +
|
|
121946
|
+
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot + path147.sep);
|
|
121090
121947
|
if (isSubdirectory) {
|
|
121091
121948
|
return {
|
|
121092
121949
|
success: false,
|
|
@@ -121102,7 +121959,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
121102
121959
|
let specMtime;
|
|
121103
121960
|
let specHash;
|
|
121104
121961
|
if (process.env.SWARM_SKIP_SPEC_GATE !== "1") {
|
|
121105
|
-
const specPath =
|
|
121962
|
+
const specPath = path147.join(targetWorkspace, ".swarm", "spec.md");
|
|
121106
121963
|
try {
|
|
121107
121964
|
const stat9 = await fs107.promises.stat(specPath);
|
|
121108
121965
|
specMtime = stat9.mtime.toISOString();
|
|
@@ -121118,7 +121975,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
121118
121975
|
}
|
|
121119
121976
|
}
|
|
121120
121977
|
if (process.env.SWARM_SKIP_GATE_SELECTION !== "1") {
|
|
121121
|
-
const contextPath =
|
|
121978
|
+
const contextPath = path147.join(targetWorkspace, ".swarm", "context.md");
|
|
121122
121979
|
let contextContent = "";
|
|
121123
121980
|
try {
|
|
121124
121981
|
contextContent = await fs107.promises.readFile(contextPath, "utf8");
|
|
@@ -121408,7 +122265,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
121408
122265
|
}
|
|
121409
122266
|
await writeCheckpoint(dir).catch(() => {});
|
|
121410
122267
|
try {
|
|
121411
|
-
const markerPath =
|
|
122268
|
+
const markerPath = path147.join(dir, ".swarm", ".plan-write-marker");
|
|
121412
122269
|
const marker = JSON.stringify({
|
|
121413
122270
|
source: "save_plan",
|
|
121414
122271
|
timestamp: new Date().toISOString(),
|
|
@@ -121431,7 +122288,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
121431
122288
|
return {
|
|
121432
122289
|
success: true,
|
|
121433
122290
|
message: "Plan saved successfully",
|
|
121434
|
-
plan_path:
|
|
122291
|
+
plan_path: path147.join(dir, ".swarm", "plan.json"),
|
|
121435
122292
|
phases_count: plan.phases.length,
|
|
121436
122293
|
tasks_count: tasksCount,
|
|
121437
122294
|
...resolvedProfile !== undefined ? { execution_profile: resolvedProfile } : {},
|
|
@@ -121498,7 +122355,7 @@ var save_plan = createSwarmTool({
|
|
|
121498
122355
|
init_zod();
|
|
121499
122356
|
init_manager2();
|
|
121500
122357
|
import * as fs108 from "node:fs";
|
|
121501
|
-
import * as
|
|
122358
|
+
import * as path148 from "node:path";
|
|
121502
122359
|
|
|
121503
122360
|
// src/sbom/detectors/index.ts
|
|
121504
122361
|
init_utils();
|
|
@@ -122348,7 +123205,7 @@ function findManifestFiles(rootDir) {
|
|
|
122348
123205
|
try {
|
|
122349
123206
|
const entries = fs108.readdirSync(dir, { withFileTypes: true });
|
|
122350
123207
|
for (const entry of entries) {
|
|
122351
|
-
const fullPath =
|
|
123208
|
+
const fullPath = path148.join(dir, entry.name);
|
|
122352
123209
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
|
|
122353
123210
|
continue;
|
|
122354
123211
|
}
|
|
@@ -122357,7 +123214,7 @@ function findManifestFiles(rootDir) {
|
|
|
122357
123214
|
} else if (entry.isFile()) {
|
|
122358
123215
|
for (const pattern of patterns) {
|
|
122359
123216
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
122360
|
-
manifestFiles.push(
|
|
123217
|
+
manifestFiles.push(path148.relative(rootDir, fullPath));
|
|
122361
123218
|
break;
|
|
122362
123219
|
}
|
|
122363
123220
|
}
|
|
@@ -122375,11 +123232,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
122375
123232
|
try {
|
|
122376
123233
|
const entries = fs108.readdirSync(dir, { withFileTypes: true });
|
|
122377
123234
|
for (const entry of entries) {
|
|
122378
|
-
const fullPath =
|
|
123235
|
+
const fullPath = path148.join(dir, entry.name);
|
|
122379
123236
|
if (entry.isFile()) {
|
|
122380
123237
|
for (const pattern of patterns) {
|
|
122381
123238
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
122382
|
-
found.push(
|
|
123239
|
+
found.push(path148.relative(workingDir, fullPath));
|
|
122383
123240
|
break;
|
|
122384
123241
|
}
|
|
122385
123242
|
}
|
|
@@ -122392,11 +123249,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
122392
123249
|
function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
122393
123250
|
const dirs = new Set;
|
|
122394
123251
|
for (const file3 of changedFiles) {
|
|
122395
|
-
let currentDir =
|
|
123252
|
+
let currentDir = path148.dirname(file3);
|
|
122396
123253
|
while (true) {
|
|
122397
|
-
if (currentDir && currentDir !== "." && currentDir !==
|
|
122398
|
-
dirs.add(
|
|
122399
|
-
const parent =
|
|
123254
|
+
if (currentDir && currentDir !== "." && currentDir !== path148.sep) {
|
|
123255
|
+
dirs.add(path148.join(workingDir, currentDir));
|
|
123256
|
+
const parent = path148.dirname(currentDir);
|
|
122400
123257
|
if (parent === currentDir)
|
|
122401
123258
|
break;
|
|
122402
123259
|
currentDir = parent;
|
|
@@ -122480,7 +123337,7 @@ var sbom_generate = createSwarmTool({
|
|
|
122480
123337
|
const changedFiles = obj.changed_files;
|
|
122481
123338
|
const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
|
|
122482
123339
|
const workingDir = directory;
|
|
122483
|
-
const outputDir =
|
|
123340
|
+
const outputDir = path148.isAbsolute(relativeOutputDir) ? relativeOutputDir : path148.join(workingDir, relativeOutputDir);
|
|
122484
123341
|
let manifestFiles = [];
|
|
122485
123342
|
if (scope === "all") {
|
|
122486
123343
|
manifestFiles = findManifestFiles(workingDir);
|
|
@@ -122503,7 +123360,7 @@ var sbom_generate = createSwarmTool({
|
|
|
122503
123360
|
const processedFiles = [];
|
|
122504
123361
|
for (const manifestFile of manifestFiles) {
|
|
122505
123362
|
try {
|
|
122506
|
-
const fullPath =
|
|
123363
|
+
const fullPath = path148.isAbsolute(manifestFile) ? manifestFile : path148.join(workingDir, manifestFile);
|
|
122507
123364
|
if (!fs108.existsSync(fullPath)) {
|
|
122508
123365
|
continue;
|
|
122509
123366
|
}
|
|
@@ -122520,7 +123377,7 @@ var sbom_generate = createSwarmTool({
|
|
|
122520
123377
|
const bom = generateCycloneDX(allComponents);
|
|
122521
123378
|
const bomJson = serializeCycloneDX(bom);
|
|
122522
123379
|
const filename = generateSbomFilename();
|
|
122523
|
-
const outputPath =
|
|
123380
|
+
const outputPath = path148.join(outputDir, filename);
|
|
122524
123381
|
fs108.writeFileSync(outputPath, bomJson, "utf-8");
|
|
122525
123382
|
const verdict = processedFiles.length > 0 ? "pass" : "pass";
|
|
122526
123383
|
try {
|
|
@@ -122565,7 +123422,7 @@ var sbom_generate = createSwarmTool({
|
|
|
122565
123422
|
init_zod();
|
|
122566
123423
|
init_create_tool();
|
|
122567
123424
|
import * as fs109 from "node:fs";
|
|
122568
|
-
import * as
|
|
123425
|
+
import * as path149 from "node:path";
|
|
122569
123426
|
var SPEC_CANDIDATES = [
|
|
122570
123427
|
"openapi.json",
|
|
122571
123428
|
"openapi.yaml",
|
|
@@ -122597,12 +123454,12 @@ function normalizePath5(p) {
|
|
|
122597
123454
|
}
|
|
122598
123455
|
function discoverSpecFile(cwd, specFileArg) {
|
|
122599
123456
|
if (specFileArg) {
|
|
122600
|
-
const resolvedPath =
|
|
122601
|
-
const normalizedCwd = cwd.endsWith(
|
|
123457
|
+
const resolvedPath = path149.resolve(cwd, specFileArg);
|
|
123458
|
+
const normalizedCwd = cwd.endsWith(path149.sep) ? cwd : cwd + path149.sep;
|
|
122602
123459
|
if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
|
|
122603
123460
|
throw new Error("Invalid spec_file: path traversal detected");
|
|
122604
123461
|
}
|
|
122605
|
-
const ext =
|
|
123462
|
+
const ext = path149.extname(resolvedPath).toLowerCase();
|
|
122606
123463
|
if (!ALLOWED_EXTENSIONS.includes(ext)) {
|
|
122607
123464
|
throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
|
|
122608
123465
|
}
|
|
@@ -122616,7 +123473,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
122616
123473
|
return resolvedPath;
|
|
122617
123474
|
}
|
|
122618
123475
|
for (const candidate of SPEC_CANDIDATES) {
|
|
122619
|
-
const candidatePath =
|
|
123476
|
+
const candidatePath = path149.resolve(cwd, candidate);
|
|
122620
123477
|
if (fs109.existsSync(candidatePath)) {
|
|
122621
123478
|
const stats = fs109.statSync(candidatePath);
|
|
122622
123479
|
if (stats.size <= MAX_SPEC_SIZE) {
|
|
@@ -122628,7 +123485,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
122628
123485
|
}
|
|
122629
123486
|
function parseSpec(specFile) {
|
|
122630
123487
|
const content = fs109.readFileSync(specFile, "utf-8");
|
|
122631
|
-
const ext =
|
|
123488
|
+
const ext = path149.extname(specFile).toLowerCase();
|
|
122632
123489
|
if (ext === ".json") {
|
|
122633
123490
|
return parseJsonSpec(content);
|
|
122634
123491
|
}
|
|
@@ -122704,7 +123561,7 @@ function extractRoutes(cwd) {
|
|
|
122704
123561
|
return;
|
|
122705
123562
|
}
|
|
122706
123563
|
for (const entry of entries) {
|
|
122707
|
-
const fullPath =
|
|
123564
|
+
const fullPath = path149.join(dir, entry.name);
|
|
122708
123565
|
if (entry.isSymbolicLink()) {
|
|
122709
123566
|
continue;
|
|
122710
123567
|
}
|
|
@@ -122714,7 +123571,7 @@ function extractRoutes(cwd) {
|
|
|
122714
123571
|
}
|
|
122715
123572
|
walkDir(fullPath);
|
|
122716
123573
|
} else if (entry.isFile()) {
|
|
122717
|
-
const ext =
|
|
123574
|
+
const ext = path149.extname(entry.name).toLowerCase();
|
|
122718
123575
|
const baseName = entry.name.toLowerCase();
|
|
122719
123576
|
if (![".ts", ".js", ".mjs"].includes(ext)) {
|
|
122720
123577
|
continue;
|
|
@@ -122883,7 +123740,7 @@ init_bun_compat();
|
|
|
122883
123740
|
init_path_security();
|
|
122884
123741
|
init_create_tool();
|
|
122885
123742
|
import * as fs110 from "node:fs";
|
|
122886
|
-
import * as
|
|
123743
|
+
import * as path150 from "node:path";
|
|
122887
123744
|
var DEFAULT_MAX_RESULTS = 100;
|
|
122888
123745
|
var DEFAULT_MAX_LINES = 200;
|
|
122889
123746
|
var REGEX_TIMEOUT_MS = 5000;
|
|
@@ -122906,24 +123763,24 @@ function matchesGlobs(filePath, globs) {
|
|
|
122906
123763
|
return true;
|
|
122907
123764
|
return globs.some((glob) => globMatch(glob, filePath));
|
|
122908
123765
|
}
|
|
122909
|
-
var
|
|
122910
|
-
function
|
|
123766
|
+
var WINDOWS_RESERVED_NAMES4 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
123767
|
+
function containsWindowsAttacks4(str) {
|
|
122911
123768
|
if (/:[^\\/]/.test(str))
|
|
122912
123769
|
return true;
|
|
122913
123770
|
const parts2 = str.split(/[/\\]/);
|
|
122914
123771
|
for (const part of parts2) {
|
|
122915
|
-
if (
|
|
123772
|
+
if (WINDOWS_RESERVED_NAMES4.test(part))
|
|
122916
123773
|
return true;
|
|
122917
123774
|
}
|
|
122918
123775
|
return false;
|
|
122919
123776
|
}
|
|
122920
123777
|
function isPathInWorkspace3(filePath, workspace) {
|
|
122921
123778
|
try {
|
|
122922
|
-
const resolvedPath =
|
|
123779
|
+
const resolvedPath = path150.resolve(workspace, filePath);
|
|
122923
123780
|
const realWorkspace = fs110.realpathSync(workspace);
|
|
122924
123781
|
const realResolvedPath = fs110.realpathSync(resolvedPath);
|
|
122925
|
-
const relativePath =
|
|
122926
|
-
if (relativePath.startsWith("..") ||
|
|
123782
|
+
const relativePath = path150.relative(realWorkspace, realResolvedPath);
|
|
123783
|
+
if (relativePath.startsWith("..") || path150.isAbsolute(relativePath)) {
|
|
122927
123784
|
return false;
|
|
122928
123785
|
}
|
|
122929
123786
|
return true;
|
|
@@ -122936,11 +123793,11 @@ function validatePathForRead2(filePath, workspace) {
|
|
|
122936
123793
|
}
|
|
122937
123794
|
function findRgInEnvPath() {
|
|
122938
123795
|
const searchPath = process.env.PATH ?? "";
|
|
122939
|
-
for (const dir of searchPath.split(
|
|
123796
|
+
for (const dir of searchPath.split(path150.delimiter)) {
|
|
122940
123797
|
if (!dir)
|
|
122941
123798
|
continue;
|
|
122942
123799
|
const isWindows = process.platform === "win32";
|
|
122943
|
-
const candidate =
|
|
123800
|
+
const candidate = path150.join(dir, isWindows ? "rg.exe" : "rg");
|
|
122944
123801
|
if (fs110.existsSync(candidate))
|
|
122945
123802
|
return candidate;
|
|
122946
123803
|
}
|
|
@@ -122995,7 +123852,7 @@ async function ripgrepSearch(opts) {
|
|
|
122995
123852
|
stderr: "pipe",
|
|
122996
123853
|
cwd: opts.workspace
|
|
122997
123854
|
});
|
|
122998
|
-
const timeout = new Promise((
|
|
123855
|
+
const timeout = new Promise((resolve55) => setTimeout(() => resolve55("timeout"), REGEX_TIMEOUT_MS));
|
|
122999
123856
|
const exitPromise = proc.exited;
|
|
123000
123857
|
const result = await Promise.race([exitPromise, timeout]);
|
|
123001
123858
|
if (result === "timeout") {
|
|
@@ -123070,8 +123927,8 @@ function collectFiles(dir, workspace, includeGlobs, excludeGlobs) {
|
|
|
123070
123927
|
try {
|
|
123071
123928
|
const entries = fs110.readdirSync(dir, { withFileTypes: true });
|
|
123072
123929
|
for (const entry of entries) {
|
|
123073
|
-
const fullPath =
|
|
123074
|
-
const relativePath =
|
|
123930
|
+
const fullPath = path150.join(dir, entry.name);
|
|
123931
|
+
const relativePath = path150.relative(workspace, fullPath);
|
|
123075
123932
|
if (!validatePathForRead2(fullPath, workspace)) {
|
|
123076
123933
|
continue;
|
|
123077
123934
|
}
|
|
@@ -123112,7 +123969,7 @@ async function fallbackSearch(opts) {
|
|
|
123112
123969
|
const matches = [];
|
|
123113
123970
|
let total = 0;
|
|
123114
123971
|
for (const file3 of files) {
|
|
123115
|
-
const fullPath =
|
|
123972
|
+
const fullPath = path150.join(opts.workspace, file3);
|
|
123116
123973
|
if (!validatePathForRead2(fullPath, opts.workspace)) {
|
|
123117
123974
|
continue;
|
|
123118
123975
|
}
|
|
@@ -123225,14 +124082,14 @@ var search = createSwarmTool({
|
|
|
123225
124082
|
message: "Exclude pattern contains path traversal sequence"
|
|
123226
124083
|
}, null, 2);
|
|
123227
124084
|
}
|
|
123228
|
-
if (include &&
|
|
124085
|
+
if (include && containsWindowsAttacks4(include)) {
|
|
123229
124086
|
return JSON.stringify({
|
|
123230
124087
|
error: true,
|
|
123231
124088
|
type: "path-escape",
|
|
123232
124089
|
message: "Include pattern contains invalid Windows-specific sequence"
|
|
123233
124090
|
}, null, 2);
|
|
123234
124091
|
}
|
|
123235
|
-
if (exclude &&
|
|
124092
|
+
if (exclude && containsWindowsAttacks4(exclude)) {
|
|
123236
124093
|
return JSON.stringify({
|
|
123237
124094
|
error: true,
|
|
123238
124095
|
type: "path-escape",
|
|
@@ -123525,7 +124382,7 @@ init_config();
|
|
|
123525
124382
|
init_schema();
|
|
123526
124383
|
init_create_tool();
|
|
123527
124384
|
import { mkdir as mkdir24, rename as rename10, writeFile as writeFile19 } from "node:fs/promises";
|
|
123528
|
-
import * as
|
|
124385
|
+
import * as path151 from "node:path";
|
|
123529
124386
|
var MAX_SPEC_BYTES = 256 * 1024;
|
|
123530
124387
|
var spec_write = createSwarmTool({
|
|
123531
124388
|
description: "Write the canonical project spec to .swarm/spec.md. Atomic write, size-bounded (256 KiB), heading-required. Honors spec_writer.allow_spec_write.",
|
|
@@ -123566,8 +124423,8 @@ var spec_write = createSwarmTool({
|
|
|
123566
124423
|
reason: 'spec must contain at least one top-level "# Heading"'
|
|
123567
124424
|
}, null, 2);
|
|
123568
124425
|
}
|
|
123569
|
-
const target =
|
|
123570
|
-
await mkdir24(
|
|
124426
|
+
const target = path151.join(directory, ".swarm", "spec.md");
|
|
124427
|
+
await mkdir24(path151.dirname(target), { recursive: true });
|
|
123571
124428
|
const tmp = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
123572
124429
|
let finalContent = content;
|
|
123573
124430
|
if (mode === "append") {
|
|
@@ -123596,14 +124453,14 @@ ${content}
|
|
|
123596
124453
|
init_zod();
|
|
123597
124454
|
init_loader();
|
|
123598
124455
|
import {
|
|
123599
|
-
existsSync as
|
|
123600
|
-
mkdirSync as
|
|
123601
|
-
readFileSync as
|
|
123602
|
-
renameSync as
|
|
123603
|
-
unlinkSync as
|
|
123604
|
-
writeFileSync as
|
|
124456
|
+
existsSync as existsSync85,
|
|
124457
|
+
mkdirSync as mkdirSync36,
|
|
124458
|
+
readFileSync as readFileSync72,
|
|
124459
|
+
renameSync as renameSync22,
|
|
124460
|
+
unlinkSync as unlinkSync20,
|
|
124461
|
+
writeFileSync as writeFileSync30
|
|
123605
124462
|
} from "node:fs";
|
|
123606
|
-
import
|
|
124463
|
+
import path152 from "node:path";
|
|
123607
124464
|
init_create_tool();
|
|
123608
124465
|
init_resolve_working_directory();
|
|
123609
124466
|
var VerdictSchema2 = exports_external.object({
|
|
@@ -123733,9 +124590,9 @@ var submit_phase_council_verdicts = createSwarmTool({
|
|
|
123733
124590
|
}
|
|
123734
124591
|
});
|
|
123735
124592
|
function getPhaseMutationGapFinding(phaseNumber, workingDir) {
|
|
123736
|
-
const mutationGatePath =
|
|
124593
|
+
const mutationGatePath = path152.join(workingDir, ".swarm", "evidence", String(phaseNumber), "mutation-gate.json");
|
|
123737
124594
|
try {
|
|
123738
|
-
const raw =
|
|
124595
|
+
const raw = readFileSync72(mutationGatePath, "utf-8");
|
|
123739
124596
|
const parsed = JSON.parse(raw);
|
|
123740
124597
|
const gateEntry = (parsed.entries ?? []).find((entry) => entry?.type === "mutation-gate");
|
|
123741
124598
|
if (!gateEntry) {
|
|
@@ -123795,9 +124652,9 @@ function getPhaseMutationGapFinding(phaseNumber, workingDir) {
|
|
|
123795
124652
|
}
|
|
123796
124653
|
}
|
|
123797
124654
|
function writePhaseCouncilEvidence(workingDir, synthesis) {
|
|
123798
|
-
const evidenceDir =
|
|
123799
|
-
|
|
123800
|
-
const evidenceFile =
|
|
124655
|
+
const evidenceDir = path152.join(workingDir, ".swarm", "evidence", String(synthesis.phaseNumber));
|
|
124656
|
+
mkdirSync36(evidenceDir, { recursive: true });
|
|
124657
|
+
const evidenceFile = path152.join(evidenceDir, "phase-council.json");
|
|
123801
124658
|
const evidenceBundle = {
|
|
123802
124659
|
entries: [
|
|
123803
124660
|
{
|
|
@@ -123830,11 +124687,11 @@ function writePhaseCouncilEvidence(workingDir, synthesis) {
|
|
|
123830
124687
|
};
|
|
123831
124688
|
const tempFile = `${evidenceFile}.tmp-${Date.now()}`;
|
|
123832
124689
|
try {
|
|
123833
|
-
|
|
123834
|
-
|
|
124690
|
+
writeFileSync30(tempFile, JSON.stringify(evidenceBundle, null, 2), "utf-8");
|
|
124691
|
+
renameSync22(tempFile, evidenceFile);
|
|
123835
124692
|
} finally {
|
|
123836
|
-
if (
|
|
123837
|
-
|
|
124693
|
+
if (existsSync85(tempFile)) {
|
|
124694
|
+
unlinkSync20(tempFile);
|
|
123838
124695
|
}
|
|
123839
124696
|
}
|
|
123840
124697
|
}
|
|
@@ -123859,28 +124716,28 @@ init_zod();
|
|
|
123859
124716
|
init_path_security();
|
|
123860
124717
|
init_create_tool();
|
|
123861
124718
|
import * as fs111 from "node:fs";
|
|
123862
|
-
import * as
|
|
123863
|
-
var
|
|
123864
|
-
function
|
|
124719
|
+
import * as path153 from "node:path";
|
|
124720
|
+
var WINDOWS_RESERVED_NAMES5 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
124721
|
+
function containsWindowsAttacks5(str) {
|
|
123865
124722
|
if (/:[^\\/]/.test(str))
|
|
123866
124723
|
return true;
|
|
123867
124724
|
const parts2 = str.split(/[/\\]/);
|
|
123868
124725
|
for (const part of parts2) {
|
|
123869
|
-
if (
|
|
124726
|
+
if (WINDOWS_RESERVED_NAMES5.test(part))
|
|
123870
124727
|
return true;
|
|
123871
124728
|
}
|
|
123872
124729
|
return false;
|
|
123873
124730
|
}
|
|
123874
124731
|
function isPathInWorkspace4(filePath, workspace) {
|
|
123875
124732
|
try {
|
|
123876
|
-
const resolvedPath =
|
|
124733
|
+
const resolvedPath = path153.resolve(workspace, filePath);
|
|
123877
124734
|
if (!fs111.existsSync(resolvedPath)) {
|
|
123878
124735
|
return true;
|
|
123879
124736
|
}
|
|
123880
124737
|
const realWorkspace = fs111.realpathSync(workspace);
|
|
123881
124738
|
const realResolvedPath = fs111.realpathSync(resolvedPath);
|
|
123882
|
-
const relativePath =
|
|
123883
|
-
if (relativePath.startsWith("..") ||
|
|
124739
|
+
const relativePath = path153.relative(realWorkspace, realResolvedPath);
|
|
124740
|
+
if (relativePath.startsWith("..") || path153.isAbsolute(relativePath)) {
|
|
123884
124741
|
return false;
|
|
123885
124742
|
}
|
|
123886
124743
|
return true;
|
|
@@ -123895,7 +124752,7 @@ function validateFilePath(filePath, workspace) {
|
|
|
123895
124752
|
return false;
|
|
123896
124753
|
if (containsControlChars(filePath))
|
|
123897
124754
|
return false;
|
|
123898
|
-
if (
|
|
124755
|
+
if (containsWindowsAttacks5(filePath))
|
|
123899
124756
|
return false;
|
|
123900
124757
|
return isPathInWorkspace4(filePath, workspace);
|
|
123901
124758
|
}
|
|
@@ -123908,12 +124765,12 @@ function findContextMatch(content, contextBefore, contextAfter, oldContent) {
|
|
|
123908
124765
|
if (contextBefore && contextBefore.length > 0) {
|
|
123909
124766
|
for (let i2 = 0;i2 <= lines.length - contextBefore.length; i2++) {
|
|
123910
124767
|
const slice = lines.slice(i2, i2 + contextBefore.length);
|
|
123911
|
-
if (
|
|
124768
|
+
if (arraysEqual2(slice, contextBefore)) {
|
|
123912
124769
|
const afterStart = i2 + contextBefore.length;
|
|
123913
124770
|
if (contextAfter && contextAfter.length > 0) {
|
|
123914
124771
|
for (let j = afterStart;j <= lines.length - contextAfter.length; j++) {
|
|
123915
124772
|
const afterSlice = lines.slice(j, j + contextAfter.length);
|
|
123916
|
-
if (
|
|
124773
|
+
if (arraysEqual2(afterSlice, contextAfter)) {
|
|
123917
124774
|
if (j === afterStart) {
|
|
123918
124775
|
return {
|
|
123919
124776
|
startLineIndex: i2,
|
|
@@ -123926,7 +124783,7 @@ function findContextMatch(content, contextBefore, contextAfter, oldContent) {
|
|
|
123926
124783
|
const oldContentLines = oldContent.split(`
|
|
123927
124784
|
`);
|
|
123928
124785
|
const betweenLines = lines.slice(afterStart, j);
|
|
123929
|
-
if (
|
|
124786
|
+
if (arraysEqual2(betweenLines, oldContentLines)) {
|
|
123930
124787
|
return {
|
|
123931
124788
|
startLineIndex: i2,
|
|
123932
124789
|
endLineIndex: j - 1,
|
|
@@ -123952,7 +124809,7 @@ function findContextMatch(content, contextBefore, contextAfter, oldContent) {
|
|
|
123952
124809
|
`);
|
|
123953
124810
|
for (let k = afterStart;k <= lines.length - oldContentLines.length; k++) {
|
|
123954
124811
|
const candidate = lines.slice(k, k + oldContentLines.length);
|
|
123955
|
-
if (
|
|
124812
|
+
if (arraysEqual2(candidate, oldContentLines)) {
|
|
123956
124813
|
return {
|
|
123957
124814
|
startLineIndex: i2,
|
|
123958
124815
|
endLineIndex: k + oldContentLines.length - 1,
|
|
@@ -123976,7 +124833,7 @@ function findContextMatch(content, contextBefore, contextAfter, oldContent) {
|
|
|
123976
124833
|
} else if (contextAfter && contextAfter.length > 0) {
|
|
123977
124834
|
for (let j = 0;j <= lines.length - contextAfter.length; j++) {
|
|
123978
124835
|
const afterSlice = lines.slice(j, j + contextAfter.length);
|
|
123979
|
-
if (
|
|
124836
|
+
if (arraysEqual2(afterSlice, contextAfter)) {
|
|
123980
124837
|
return {
|
|
123981
124838
|
startLineIndex: 0,
|
|
123982
124839
|
endLineIndex: j - 1,
|
|
@@ -123988,7 +124845,7 @@ function findContextMatch(content, contextBefore, contextAfter, oldContent) {
|
|
|
123988
124845
|
}
|
|
123989
124846
|
return null;
|
|
123990
124847
|
}
|
|
123991
|
-
function
|
|
124848
|
+
function arraysEqual2(a, b) {
|
|
123992
124849
|
if (a.length !== b.length)
|
|
123993
124850
|
return false;
|
|
123994
124851
|
for (let i2 = 0;i2 < a.length; i2++) {
|
|
@@ -124088,7 +124945,7 @@ var suggestPatch = createSwarmTool({
|
|
|
124088
124945
|
});
|
|
124089
124946
|
continue;
|
|
124090
124947
|
}
|
|
124091
|
-
const fullPath =
|
|
124948
|
+
const fullPath = path153.resolve(directory, change.file);
|
|
124092
124949
|
if (!fs111.existsSync(fullPath)) {
|
|
124093
124950
|
errors5.push({
|
|
124094
124951
|
success: false,
|
|
@@ -124492,7 +125349,7 @@ init_zod();
|
|
|
124492
125349
|
init_manager2();
|
|
124493
125350
|
init_detector();
|
|
124494
125351
|
import * as fs112 from "node:fs";
|
|
124495
|
-
import * as
|
|
125352
|
+
import * as path154 from "node:path";
|
|
124496
125353
|
init_create_tool();
|
|
124497
125354
|
var MAX_FILE_SIZE2 = 2 * 1024 * 1024;
|
|
124498
125355
|
var BINARY_CHECK_BYTES = 8192;
|
|
@@ -124558,7 +125415,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
124558
125415
|
if (languages?.length) {
|
|
124559
125416
|
const lowerLangs = languages.map((l) => l.toLowerCase());
|
|
124560
125417
|
filesToCheck = filesToCheck.filter((file3) => {
|
|
124561
|
-
const ext =
|
|
125418
|
+
const ext = path154.extname(file3.path).toLowerCase();
|
|
124562
125419
|
const langDef = getLanguageForExtension(ext);
|
|
124563
125420
|
const fileProfile = getProfileForFile(file3.path);
|
|
124564
125421
|
const langId = fileProfile?.id || langDef?.id;
|
|
@@ -124571,7 +125428,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
124571
125428
|
let skippedCount = 0;
|
|
124572
125429
|
for (const fileInfo of filesToCheck) {
|
|
124573
125430
|
const { path: filePath } = fileInfo;
|
|
124574
|
-
const fullPath =
|
|
125431
|
+
const fullPath = path154.isAbsolute(filePath) ? filePath : path154.join(directory, filePath);
|
|
124575
125432
|
const result = {
|
|
124576
125433
|
path: filePath,
|
|
124577
125434
|
language: "",
|
|
@@ -124620,7 +125477,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
124620
125477
|
results.push(result);
|
|
124621
125478
|
continue;
|
|
124622
125479
|
}
|
|
124623
|
-
const ext =
|
|
125480
|
+
const ext = path154.extname(filePath).toLowerCase();
|
|
124624
125481
|
const langDef = getLanguageForExtension(ext);
|
|
124625
125482
|
result.language = profile?.id || langDef?.id || "unknown";
|
|
124626
125483
|
const errors5 = extractSyntaxErrors(parser, content);
|
|
@@ -124719,7 +125576,7 @@ init_utils();
|
|
|
124719
125576
|
init_create_tool();
|
|
124720
125577
|
init_path_security();
|
|
124721
125578
|
import * as fs113 from "node:fs";
|
|
124722
|
-
import * as
|
|
125579
|
+
import * as path155 from "node:path";
|
|
124723
125580
|
var MAX_TEXT_LENGTH = 200;
|
|
124724
125581
|
var MAX_FILE_SIZE_BYTES11 = 1024 * 1024;
|
|
124725
125582
|
var SUPPORTED_EXTENSIONS4 = new Set([
|
|
@@ -124785,9 +125642,9 @@ function validatePathsInput(paths, cwd) {
|
|
|
124785
125642
|
return { error: "paths contains path traversal", resolvedPath: null };
|
|
124786
125643
|
}
|
|
124787
125644
|
try {
|
|
124788
|
-
const resolvedPath =
|
|
124789
|
-
const normalizedCwd =
|
|
124790
|
-
const normalizedResolved =
|
|
125645
|
+
const resolvedPath = path155.resolve(paths);
|
|
125646
|
+
const normalizedCwd = path155.resolve(cwd);
|
|
125647
|
+
const normalizedResolved = path155.resolve(resolvedPath);
|
|
124791
125648
|
if (!normalizedResolved.startsWith(normalizedCwd)) {
|
|
124792
125649
|
return {
|
|
124793
125650
|
error: "paths must be within the current working directory",
|
|
@@ -124803,7 +125660,7 @@ function validatePathsInput(paths, cwd) {
|
|
|
124803
125660
|
}
|
|
124804
125661
|
}
|
|
124805
125662
|
function isSupportedExtension(filePath) {
|
|
124806
|
-
const ext =
|
|
125663
|
+
const ext = path155.extname(filePath).toLowerCase();
|
|
124807
125664
|
return SUPPORTED_EXTENSIONS4.has(ext);
|
|
124808
125665
|
}
|
|
124809
125666
|
function findSourceFiles3(dir, files = []) {
|
|
@@ -124818,7 +125675,7 @@ function findSourceFiles3(dir, files = []) {
|
|
|
124818
125675
|
if (SKIP_DIRECTORIES5.has(entry)) {
|
|
124819
125676
|
continue;
|
|
124820
125677
|
}
|
|
124821
|
-
const fullPath =
|
|
125678
|
+
const fullPath = path155.join(dir, entry);
|
|
124822
125679
|
let stat9;
|
|
124823
125680
|
try {
|
|
124824
125681
|
stat9 = fs113.statSync(fullPath);
|
|
@@ -124930,7 +125787,7 @@ var todo_extract = createSwarmTool({
|
|
|
124930
125787
|
filesToScan.push(scanPath);
|
|
124931
125788
|
} else {
|
|
124932
125789
|
const errorResult = {
|
|
124933
|
-
error: `unsupported file extension: ${
|
|
125790
|
+
error: `unsupported file extension: ${path155.extname(scanPath)}`,
|
|
124934
125791
|
total: 0,
|
|
124935
125792
|
byPriority: { high: 0, medium: 0, low: 0 },
|
|
124936
125793
|
entries: []
|
|
@@ -124980,17 +125837,17 @@ init_schema();
|
|
|
124980
125837
|
init_qa_gate_profile();
|
|
124981
125838
|
init_gate_evidence();
|
|
124982
125839
|
import * as fs117 from "node:fs";
|
|
124983
|
-
import * as
|
|
125840
|
+
import * as path159 from "node:path";
|
|
124984
125841
|
|
|
124985
125842
|
// src/hooks/diff-scope.ts
|
|
124986
125843
|
init_bun_compat();
|
|
124987
125844
|
import * as fs115 from "node:fs";
|
|
124988
|
-
import * as
|
|
125845
|
+
import * as path157 from "node:path";
|
|
124989
125846
|
|
|
124990
125847
|
// src/utils/gitignore-warning.ts
|
|
124991
125848
|
init_bun_compat();
|
|
124992
125849
|
import * as fs114 from "node:fs";
|
|
124993
|
-
import * as
|
|
125850
|
+
import * as path156 from "node:path";
|
|
124994
125851
|
var _internals67 = { bunSpawn };
|
|
124995
125852
|
var _swarmGitExcludedChecked = false;
|
|
124996
125853
|
function fileCoversSwarm(content) {
|
|
@@ -125064,10 +125921,10 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
125064
125921
|
const excludeRelPath = excludePathRaw.trim();
|
|
125065
125922
|
if (!excludeRelPath)
|
|
125066
125923
|
return;
|
|
125067
|
-
const excludePath =
|
|
125924
|
+
const excludePath = path156.isAbsolute(excludeRelPath) ? excludeRelPath : path156.join(directory, excludeRelPath);
|
|
125068
125925
|
if (checkIgnoreExitCode !== 0) {
|
|
125069
125926
|
try {
|
|
125070
|
-
fs114.mkdirSync(
|
|
125927
|
+
fs114.mkdirSync(path156.dirname(excludePath), { recursive: true });
|
|
125071
125928
|
let existing = "";
|
|
125072
125929
|
try {
|
|
125073
125930
|
existing = fs114.readFileSync(excludePath, "utf8");
|
|
@@ -125111,7 +125968,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
125111
125968
|
var _internals68 = { bunSpawn };
|
|
125112
125969
|
function getDeclaredScope(taskId, directory) {
|
|
125113
125970
|
try {
|
|
125114
|
-
const planPath =
|
|
125971
|
+
const planPath = path157.join(directory, ".swarm", "plan.json");
|
|
125115
125972
|
if (!fs115.existsSync(planPath))
|
|
125116
125973
|
return null;
|
|
125117
125974
|
const raw = fs115.readFileSync(planPath, "utf-8");
|
|
@@ -125217,7 +126074,7 @@ init_telemetry();
|
|
|
125217
126074
|
// src/turbo/lean/task-completion.ts
|
|
125218
126075
|
init_file_locks();
|
|
125219
126076
|
import * as fs116 from "node:fs";
|
|
125220
|
-
import * as
|
|
126077
|
+
import * as path158 from "node:path";
|
|
125221
126078
|
var _internals69 = {
|
|
125222
126079
|
listActiveLocks,
|
|
125223
126080
|
verifyLeanTurboTaskCompletion
|
|
@@ -125236,7 +126093,7 @@ var TIER_3_PATTERNS = [
|
|
|
125236
126093
|
];
|
|
125237
126094
|
function matchesTier3Pattern(files) {
|
|
125238
126095
|
for (const file3 of files) {
|
|
125239
|
-
const fileName =
|
|
126096
|
+
const fileName = path158.basename(file3);
|
|
125240
126097
|
for (const pattern of TIER_3_PATTERNS) {
|
|
125241
126098
|
if (pattern.test(fileName)) {
|
|
125242
126099
|
return true;
|
|
@@ -125248,7 +126105,7 @@ function matchesTier3Pattern(files) {
|
|
|
125248
126105
|
function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
125249
126106
|
let persisted = null;
|
|
125250
126107
|
try {
|
|
125251
|
-
const statePath =
|
|
126108
|
+
const statePath = path158.join(directory, ".swarm", "turbo-state.json");
|
|
125252
126109
|
if (!fs116.existsSync(statePath)) {
|
|
125253
126110
|
return {
|
|
125254
126111
|
ok: false,
|
|
@@ -125332,11 +126189,11 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
125332
126189
|
};
|
|
125333
126190
|
}
|
|
125334
126191
|
const phase = runState.phase ?? 0;
|
|
125335
|
-
const evidencePath =
|
|
125336
|
-
const expectedDir =
|
|
125337
|
-
const resolvedPath =
|
|
125338
|
-
const resolvedDir =
|
|
125339
|
-
if (!resolvedPath.startsWith(resolvedDir +
|
|
126192
|
+
const evidencePath = path158.join(directory, ".swarm", "evidence", String(phase), "lean-turbo", `${lane.laneId}.json`);
|
|
126193
|
+
const expectedDir = path158.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
|
|
126194
|
+
const resolvedPath = path158.resolve(evidencePath);
|
|
126195
|
+
const resolvedDir = path158.resolve(expectedDir);
|
|
126196
|
+
if (!resolvedPath.startsWith(resolvedDir + path158.sep) && resolvedPath !== resolvedDir) {
|
|
125340
126197
|
return {
|
|
125341
126198
|
ok: false,
|
|
125342
126199
|
reason: `Lane ID causes path traversal: ${lane.laneId}`,
|
|
@@ -125376,7 +126233,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
125376
126233
|
}
|
|
125377
126234
|
let filesTouched = [];
|
|
125378
126235
|
try {
|
|
125379
|
-
const planPath =
|
|
126236
|
+
const planPath = path158.join(directory, ".swarm", "plan.json");
|
|
125380
126237
|
const planRaw = fs116.readFileSync(planPath, "utf-8");
|
|
125381
126238
|
const plan = JSON.parse(planRaw);
|
|
125382
126239
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -125460,7 +126317,7 @@ var TIER_3_PATTERNS2 = [
|
|
|
125460
126317
|
];
|
|
125461
126318
|
function matchesTier3Pattern2(files) {
|
|
125462
126319
|
for (const file3 of files) {
|
|
125463
|
-
const fileName =
|
|
126320
|
+
const fileName = path159.basename(file3);
|
|
125464
126321
|
for (const pattern of TIER_3_PATTERNS2) {
|
|
125465
126322
|
if (pattern.test(fileName)) {
|
|
125466
126323
|
return true;
|
|
@@ -125499,7 +126356,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
125499
126356
|
if (!skipStandardTurboBypass && hasActiveTurboMode()) {
|
|
125500
126357
|
const resolvedDir2 = workingDirectory;
|
|
125501
126358
|
try {
|
|
125502
|
-
const planPath =
|
|
126359
|
+
const planPath = path159.join(resolvedDir2, ".swarm", "plan.json");
|
|
125503
126360
|
const planRaw = fs117.readFileSync(planPath, "utf-8");
|
|
125504
126361
|
const plan = JSON.parse(planRaw);
|
|
125505
126362
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -125577,7 +126434,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
125577
126434
|
}
|
|
125578
126435
|
if (resolvedDir) {
|
|
125579
126436
|
try {
|
|
125580
|
-
const planPath =
|
|
126437
|
+
const planPath = path159.join(resolvedDir, ".swarm", "plan.json");
|
|
125581
126438
|
const planRaw = fs117.readFileSync(planPath, "utf-8");
|
|
125582
126439
|
const plan = JSON.parse(planRaw);
|
|
125583
126440
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -125813,7 +126670,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
125813
126670
|
};
|
|
125814
126671
|
}
|
|
125815
126672
|
directory = resolveResult.directory;
|
|
125816
|
-
const planPath =
|
|
126673
|
+
const planPath = path159.join(directory, ".swarm", "plan.json");
|
|
125817
126674
|
if (!fs117.existsSync(planPath)) {
|
|
125818
126675
|
return {
|
|
125819
126676
|
success: false,
|
|
@@ -125822,9 +126679,9 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
125822
126679
|
};
|
|
125823
126680
|
}
|
|
125824
126681
|
if (fallbackDir && directory !== fallbackDir) {
|
|
125825
|
-
const canonicalDir = fs117.realpathSync(
|
|
125826
|
-
const canonicalRoot = fs117.realpathSync(
|
|
125827
|
-
if (canonicalDir.startsWith(canonicalRoot +
|
|
126682
|
+
const canonicalDir = fs117.realpathSync(path159.resolve(directory));
|
|
126683
|
+
const canonicalRoot = fs117.realpathSync(path159.resolve(fallbackDir));
|
|
126684
|
+
if (canonicalDir.startsWith(canonicalRoot + path159.sep)) {
|
|
125828
126685
|
return {
|
|
125829
126686
|
success: false,
|
|
125830
126687
|
message: `Invalid working_directory: "${directory}" is a subdirectory of ` + `the project root "${fallbackDir}". Pass the project root path or ` + `omit working_directory entirely.`,
|
|
@@ -125836,8 +126693,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
125836
126693
|
}
|
|
125837
126694
|
if (args2.status === "in_progress") {
|
|
125838
126695
|
try {
|
|
125839
|
-
const evidencePath =
|
|
125840
|
-
fs117.mkdirSync(
|
|
126696
|
+
const evidencePath = path159.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
|
|
126697
|
+
fs117.mkdirSync(path159.dirname(evidencePath), { recursive: true });
|
|
125841
126698
|
const fd = fs117.openSync(evidencePath, "wx");
|
|
125842
126699
|
let writeOk = false;
|
|
125843
126700
|
try {
|
|
@@ -125861,7 +126718,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
125861
126718
|
recoverTaskStateFromDelegations(args2.task_id, directory);
|
|
125862
126719
|
let phaseRequiresReviewer = true;
|
|
125863
126720
|
try {
|
|
125864
|
-
const planPath2 =
|
|
126721
|
+
const planPath2 = path159.join(directory, ".swarm", "plan.json");
|
|
125865
126722
|
const planRaw = fs117.readFileSync(planPath2, "utf-8");
|
|
125866
126723
|
const plan = JSON.parse(planRaw);
|
|
125867
126724
|
const taskPhase = plan.phases.find((p) => p.tasks.some((t) => t.id === args2.task_id));
|
|
@@ -126090,7 +126947,7 @@ init_utils2();
|
|
|
126090
126947
|
init_redaction();
|
|
126091
126948
|
import { createHash as createHash12 } from "node:crypto";
|
|
126092
126949
|
import { appendFile as appendFile14, mkdir as mkdir25 } from "node:fs/promises";
|
|
126093
|
-
import * as
|
|
126950
|
+
import * as path160 from "node:path";
|
|
126094
126951
|
var EVIDENCE_CACHE_FILE = "evidence-cache/documents.jsonl";
|
|
126095
126952
|
var MAX_EVIDENCE_TEXT_LENGTH = 4000;
|
|
126096
126953
|
async function writeEvidenceDocuments(directory, inputs, now = () => new Date) {
|
|
@@ -126098,7 +126955,7 @@ async function writeEvidenceDocuments(directory, inputs, now = () => new Date) {
|
|
|
126098
126955
|
const capturedAt = now().toISOString();
|
|
126099
126956
|
const records = inputs.map((input) => createEvidenceDocumentRecord(input, capturedAt)).filter((record3) => record3 !== null);
|
|
126100
126957
|
if (records.length > 0) {
|
|
126101
|
-
await mkdir25(
|
|
126958
|
+
await mkdir25(path160.dirname(filePath), { recursive: true });
|
|
126102
126959
|
await appendFile14(filePath, `${records.map((record3) => JSON.stringify(record3)).join(`
|
|
126103
126960
|
`)}
|
|
126104
126961
|
`, "utf-8");
|
|
@@ -126295,7 +127152,7 @@ init_schema3();
|
|
|
126295
127152
|
init_store();
|
|
126296
127153
|
init_create_tool();
|
|
126297
127154
|
init_resolve_working_directory();
|
|
126298
|
-
import * as
|
|
127155
|
+
import * as path161 from "node:path";
|
|
126299
127156
|
var FindingSchema2 = exports_external.object({
|
|
126300
127157
|
severity: exports_external.enum(["low", "medium", "high", "critical"]),
|
|
126301
127158
|
category: exports_external.string().min(1),
|
|
@@ -126359,7 +127216,7 @@ var write_architecture_supervisor_evidence = createSwarmTool({
|
|
|
126359
127216
|
if (config3.architectural_supervision?.persist_knowledge_recommendations && args2.knowledge_recommendations.length > 0) {
|
|
126360
127217
|
const knowledgeConfig = KnowledgeConfigSchema.parse(config3.knowledge ?? {});
|
|
126361
127218
|
const lessons = args2.knowledge_recommendations.map((r) => r.lesson);
|
|
126362
|
-
const result = await curateAndStoreSwarm(lessons,
|
|
127219
|
+
const result = await curateAndStoreSwarm(lessons, path161.basename(dirResult.directory), { phase_number: args2.phase }, dirResult.directory, knowledgeConfig, { skipAutoPromotion: true });
|
|
126363
127220
|
knowledgeProposed = result.stored;
|
|
126364
127221
|
}
|
|
126365
127222
|
} catch {}
|
|
@@ -126395,7 +127252,7 @@ init_ledger();
|
|
|
126395
127252
|
init_manager();
|
|
126396
127253
|
init_create_tool();
|
|
126397
127254
|
import fs118 from "node:fs";
|
|
126398
|
-
import
|
|
127255
|
+
import path162 from "node:path";
|
|
126399
127256
|
function normalizeVerdict(verdict) {
|
|
126400
127257
|
switch (verdict) {
|
|
126401
127258
|
case "APPROVED":
|
|
@@ -126443,7 +127300,7 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
126443
127300
|
entries: [evidenceEntry]
|
|
126444
127301
|
};
|
|
126445
127302
|
const filename = "drift-verifier.json";
|
|
126446
|
-
const relativePath =
|
|
127303
|
+
const relativePath = path162.join("evidence", String(phase), filename);
|
|
126447
127304
|
let validatedPath;
|
|
126448
127305
|
try {
|
|
126449
127306
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -126454,10 +127311,10 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
126454
127311
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
126455
127312
|
}, null, 2);
|
|
126456
127313
|
}
|
|
126457
|
-
const evidenceDir =
|
|
127314
|
+
const evidenceDir = path162.dirname(validatedPath);
|
|
126458
127315
|
try {
|
|
126459
127316
|
await fs118.promises.mkdir(evidenceDir, { recursive: true });
|
|
126460
|
-
const tempPath =
|
|
127317
|
+
const tempPath = path162.join(evidenceDir, `.${filename}.tmp`);
|
|
126461
127318
|
await fs118.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
126462
127319
|
await fs118.promises.rename(tempPath, validatedPath);
|
|
126463
127320
|
let snapshotInfo;
|
|
@@ -126554,7 +127411,7 @@ var write_drift_evidence = createSwarmTool({
|
|
|
126554
127411
|
init_zod();
|
|
126555
127412
|
init_loader();
|
|
126556
127413
|
import fs119 from "node:fs";
|
|
126557
|
-
import
|
|
127414
|
+
import path163 from "node:path";
|
|
126558
127415
|
init_utils2();
|
|
126559
127416
|
init_manager();
|
|
126560
127417
|
init_create_tool();
|
|
@@ -126642,7 +127499,7 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
|
|
|
126642
127499
|
timestamp: synthesis.timestamp
|
|
126643
127500
|
};
|
|
126644
127501
|
const filename = "final-council.json";
|
|
126645
|
-
const relativePath =
|
|
127502
|
+
const relativePath = path163.join("evidence", filename);
|
|
126646
127503
|
let validatedPath;
|
|
126647
127504
|
try {
|
|
126648
127505
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -126656,10 +127513,10 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
|
|
|
126656
127513
|
const evidenceContent = {
|
|
126657
127514
|
entries: [evidenceEntry]
|
|
126658
127515
|
};
|
|
126659
|
-
const evidenceDir =
|
|
127516
|
+
const evidenceDir = path163.dirname(validatedPath);
|
|
126660
127517
|
try {
|
|
126661
127518
|
await fs119.promises.mkdir(evidenceDir, { recursive: true });
|
|
126662
|
-
const tempPath =
|
|
127519
|
+
const tempPath = path163.join(evidenceDir, `.${filename}.tmp`);
|
|
126663
127520
|
await fs119.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
126664
127521
|
await fs119.promises.rename(tempPath, validatedPath);
|
|
126665
127522
|
return JSON.stringify({
|
|
@@ -126719,7 +127576,7 @@ init_zod();
|
|
|
126719
127576
|
init_utils2();
|
|
126720
127577
|
init_create_tool();
|
|
126721
127578
|
import fs120 from "node:fs";
|
|
126722
|
-
import
|
|
127579
|
+
import path164 from "node:path";
|
|
126723
127580
|
function normalizeVerdict2(verdict) {
|
|
126724
127581
|
switch (verdict) {
|
|
126725
127582
|
case "APPROVED":
|
|
@@ -126767,7 +127624,7 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
126767
127624
|
entries: [evidenceEntry]
|
|
126768
127625
|
};
|
|
126769
127626
|
const filename = "hallucination-guard.json";
|
|
126770
|
-
const relativePath =
|
|
127627
|
+
const relativePath = path164.join("evidence", String(phase), filename);
|
|
126771
127628
|
let validatedPath;
|
|
126772
127629
|
try {
|
|
126773
127630
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -126778,10 +127635,10 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
126778
127635
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
126779
127636
|
}, null, 2);
|
|
126780
127637
|
}
|
|
126781
|
-
const evidenceDir =
|
|
127638
|
+
const evidenceDir = path164.dirname(validatedPath);
|
|
126782
127639
|
try {
|
|
126783
127640
|
await fs120.promises.mkdir(evidenceDir, { recursive: true });
|
|
126784
|
-
const tempPath =
|
|
127641
|
+
const tempPath = path164.join(evidenceDir, `.${filename}.tmp`);
|
|
126785
127642
|
await fs120.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
126786
127643
|
await fs120.promises.rename(tempPath, validatedPath);
|
|
126787
127644
|
return JSON.stringify({
|
|
@@ -126831,7 +127688,7 @@ init_zod();
|
|
|
126831
127688
|
init_utils2();
|
|
126832
127689
|
init_create_tool();
|
|
126833
127690
|
import fs121 from "node:fs";
|
|
126834
|
-
import
|
|
127691
|
+
import path165 from "node:path";
|
|
126835
127692
|
function normalizeVerdict3(verdict) {
|
|
126836
127693
|
switch (verdict) {
|
|
126837
127694
|
case "PASS":
|
|
@@ -126905,7 +127762,7 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
126905
127762
|
entries: [evidenceEntry]
|
|
126906
127763
|
};
|
|
126907
127764
|
const filename = "mutation-gate.json";
|
|
126908
|
-
const relativePath =
|
|
127765
|
+
const relativePath = path165.join("evidence", String(phase), filename);
|
|
126909
127766
|
let validatedPath;
|
|
126910
127767
|
try {
|
|
126911
127768
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -126916,10 +127773,10 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
126916
127773
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
126917
127774
|
}, null, 2);
|
|
126918
127775
|
}
|
|
126919
|
-
const evidenceDir =
|
|
127776
|
+
const evidenceDir = path165.dirname(validatedPath);
|
|
126920
127777
|
try {
|
|
126921
127778
|
await fs121.promises.mkdir(evidenceDir, { recursive: true });
|
|
126922
|
-
const tempPath =
|
|
127779
|
+
const tempPath = path165.join(evidenceDir, `.${filename}.tmp`);
|
|
126923
127780
|
await fs121.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
126924
127781
|
await fs121.promises.rename(tempPath, validatedPath);
|
|
126925
127782
|
return JSON.stringify({
|
|
@@ -127055,7 +127912,8 @@ var TOOL_MANIFEST = defineHandlers({
|
|
|
127055
127912
|
lean_turbo_runner_status: () => lean_turbo_runner_status,
|
|
127056
127913
|
lean_turbo_review: () => lean_turbo_review,
|
|
127057
127914
|
lean_turbo_run_phase: () => lean_turbo_run_phase,
|
|
127058
|
-
lean_turbo_status: () => lean_turbo_status
|
|
127915
|
+
lean_turbo_status: () => lean_turbo_status,
|
|
127916
|
+
apply_patch: () => applyPatch
|
|
127059
127917
|
});
|
|
127060
127918
|
|
|
127061
127919
|
// src/tools/plugin-registration.ts
|
|
@@ -127366,7 +128224,7 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
127366
128224
|
const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
|
|
127367
128225
|
preflightTriggerManager = new PTM(automationConfig);
|
|
127368
128226
|
const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
|
|
127369
|
-
const swarmDir =
|
|
128227
|
+
const swarmDir = path167.resolve(ctx.directory, ".swarm");
|
|
127370
128228
|
statusArtifact = new ASA(swarmDir);
|
|
127371
128229
|
statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
|
|
127372
128230
|
if (automationConfig.capabilities?.evidence_auto_summaries === true) {
|
|
@@ -127880,7 +128738,7 @@ ${promptRaw}`;
|
|
|
127880
128738
|
const meta3 = readSkillMetadata(s.skillPath, ctx.directory);
|
|
127881
128739
|
let desc = meta3.description || "";
|
|
127882
128740
|
if (!desc || desc === "No description provided") {
|
|
127883
|
-
desc =
|
|
128741
|
+
desc = path167.basename(path167.dirname(s.skillPath));
|
|
127884
128742
|
}
|
|
127885
128743
|
desc = desc.replace(/,/g, ";");
|
|
127886
128744
|
return `file:${s.skillPath} (-- ${desc})`;
|
|
@@ -127890,7 +128748,7 @@ ${promptRaw}`;
|
|
|
127890
128748
|
|
|
127891
128749
|
${promptRaw}`;
|
|
127892
128750
|
argsRecord.prompt = newPrompt;
|
|
127893
|
-
const skillNames = topSkills.map((s) => `${
|
|
128751
|
+
const skillNames = topSkills.map((s) => `${path167.basename(s.skillPath)} (score: ${s.score.toFixed(2)})`).join(", ");
|
|
127894
128752
|
console.warn(`[skill-propagation-gate] Injected skills: ${skillNames}`);
|
|
127895
128753
|
for (const skill of topSkills) {
|
|
127896
128754
|
try {
|