opencode-swarm 7.1.0 → 7.2.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 +79 -6
- package/dist/cli/index.js +10 -18
- package/dist/config/project-init.d.ts +15 -0
- package/dist/index.js +818 -798
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -33,7 +33,7 @@ var package_default;
|
|
|
33
33
|
var init_package = __esm(() => {
|
|
34
34
|
package_default = {
|
|
35
35
|
name: "opencode-swarm",
|
|
36
|
-
version: "7.
|
|
36
|
+
version: "7.2.0",
|
|
37
37
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
38
38
|
main: "dist/index.js",
|
|
39
39
|
types: "dist/index.d.ts",
|
|
@@ -15873,8 +15873,11 @@ var init_errors3 = __esm(() => {
|
|
|
15873
15873
|
});
|
|
15874
15874
|
|
|
15875
15875
|
// src/utils/logger.ts
|
|
15876
|
+
function isDebug() {
|
|
15877
|
+
return process.env.OPENCODE_SWARM_DEBUG === "1";
|
|
15878
|
+
}
|
|
15876
15879
|
function log(message, data) {
|
|
15877
|
-
if (!
|
|
15880
|
+
if (!isDebug())
|
|
15878
15881
|
return;
|
|
15879
15882
|
const timestamp = new Date().toISOString();
|
|
15880
15883
|
if (data !== undefined) {
|
|
@@ -15884,7 +15887,7 @@ function log(message, data) {
|
|
|
15884
15887
|
}
|
|
15885
15888
|
}
|
|
15886
15889
|
function warn(message, data) {
|
|
15887
|
-
if (!
|
|
15890
|
+
if (!isDebug())
|
|
15888
15891
|
return;
|
|
15889
15892
|
const timestamp = new Date().toISOString();
|
|
15890
15893
|
if (data !== undefined) {
|
|
@@ -15901,10 +15904,6 @@ function error48(message, data) {
|
|
|
15901
15904
|
console.error(`[opencode-swarm ${timestamp}] ERROR: ${message}`);
|
|
15902
15905
|
}
|
|
15903
15906
|
}
|
|
15904
|
-
var DEBUG;
|
|
15905
|
-
var init_logger = __esm(() => {
|
|
15906
|
-
DEBUG = process.env.OPENCODE_SWARM_DEBUG === "1";
|
|
15907
|
-
});
|
|
15908
15907
|
|
|
15909
15908
|
// src/utils/regex.ts
|
|
15910
15909
|
function escapeRegex2(s) {
|
|
@@ -15918,7 +15917,6 @@ function simpleGlobToRegex(pattern, flags2 = "i") {
|
|
|
15918
15917
|
// src/utils/index.ts
|
|
15919
15918
|
var init_utils = __esm(() => {
|
|
15920
15919
|
init_errors3();
|
|
15921
|
-
init_logger();
|
|
15922
15920
|
});
|
|
15923
15921
|
|
|
15924
15922
|
// src/utils/bun-compat.ts
|
|
@@ -25138,7 +25136,6 @@ var init_guardrails = __esm(() => {
|
|
|
25138
25136
|
init_telemetry();
|
|
25139
25137
|
init_utils();
|
|
25140
25138
|
init_bun_compat();
|
|
25141
|
-
init_logger();
|
|
25142
25139
|
init_conflict_resolution();
|
|
25143
25140
|
init_delegation_gate();
|
|
25144
25141
|
init_loop_detector();
|
|
@@ -26098,7 +26095,6 @@ var init_delegation_gate = __esm(() => {
|
|
|
26098
26095
|
init_schema();
|
|
26099
26096
|
init_state();
|
|
26100
26097
|
init_telemetry();
|
|
26101
|
-
init_logger();
|
|
26102
26098
|
init_guardrails();
|
|
26103
26099
|
init_normalize_tool_name();
|
|
26104
26100
|
init_utils2();
|
|
@@ -40586,9 +40582,7 @@ function resetToRemoteBranch(cwd, options) {
|
|
|
40586
40582
|
}
|
|
40587
40583
|
}
|
|
40588
40584
|
var GIT_TIMEOUT_MS2 = 30000;
|
|
40589
|
-
var init_branch =
|
|
40590
|
-
init_logger();
|
|
40591
|
-
});
|
|
40585
|
+
var init_branch = () => {};
|
|
40592
40586
|
|
|
40593
40587
|
// src/hooks/knowledge-store.ts
|
|
40594
40588
|
import { existsSync as existsSync9 } from "node:fs";
|
|
@@ -40915,7 +40909,7 @@ async function recordLessonsShown(directory, lessonIds, currentPhase) {
|
|
|
40915
40909
|
await mkdir4(path16.dirname(shownFile), { recursive: true });
|
|
40916
40910
|
await writeFile4(shownFile, JSON.stringify(shownData, null, 2), "utf-8");
|
|
40917
40911
|
} catch {
|
|
40918
|
-
|
|
40912
|
+
warn("[swarm] Knowledge: failed to record shown lessons");
|
|
40919
40913
|
}
|
|
40920
40914
|
}
|
|
40921
40915
|
async function readMergedKnowledge(directory, config3, context) {
|
|
@@ -41065,7 +41059,7 @@ async function updateRetrievalOutcome(directory, phaseInfo, phaseSucceeded) {
|
|
|
41065
41059
|
delete shownData[phaseInfo];
|
|
41066
41060
|
await writeFile4(shownFile, JSON.stringify(shownData, null, 2), "utf-8");
|
|
41067
41061
|
} catch {
|
|
41068
|
-
|
|
41062
|
+
warn("[swarm] Knowledge: failed to update retrieval outcomes");
|
|
41069
41063
|
}
|
|
41070
41064
|
}
|
|
41071
41065
|
var JACCARD_THRESHOLD = 0.6, HIVE_TIER_BOOST = 0.05, SAME_PROJECT_PENALTY = -0.05;
|
|
@@ -41216,12 +41210,12 @@ function validateLesson(candidate, existingLessons, meta3) {
|
|
|
41216
41210
|
}
|
|
41217
41211
|
async function quarantineEntry(directory, entryId, reason, reportedBy) {
|
|
41218
41212
|
if (!directory || directory.includes("..")) {
|
|
41219
|
-
|
|
41213
|
+
warn("[knowledge-validator] quarantineEntry: directory traversal attempt blocked");
|
|
41220
41214
|
return;
|
|
41221
41215
|
}
|
|
41222
41216
|
if (!entryId || entryId.includes("\x00") || entryId.includes(`
|
|
41223
41217
|
`)) {
|
|
41224
|
-
|
|
41218
|
+
warn("[knowledge-validator] quarantineEntry: invalid entryId rejected");
|
|
41225
41219
|
return;
|
|
41226
41220
|
}
|
|
41227
41221
|
const validReportedBy = ["architect", "user", "auto"];
|
|
@@ -41281,12 +41275,12 @@ async function quarantineEntry(directory, entryId, reason, reportedBy) {
|
|
|
41281
41275
|
}
|
|
41282
41276
|
async function restoreEntry(directory, entryId) {
|
|
41283
41277
|
if (!directory || directory.includes("..")) {
|
|
41284
|
-
|
|
41278
|
+
warn("[knowledge-validator] restoreEntry: directory traversal attempt blocked");
|
|
41285
41279
|
return;
|
|
41286
41280
|
}
|
|
41287
41281
|
if (!entryId || entryId.includes("\x00") || entryId.includes(`
|
|
41288
41282
|
`)) {
|
|
41289
|
-
|
|
41283
|
+
warn("[knowledge-validator] restoreEntry: invalid entryId rejected");
|
|
41290
41284
|
return;
|
|
41291
41285
|
}
|
|
41292
41286
|
const knowledgePath = path17.join(directory, ".swarm", "knowledge.jsonl");
|
|
@@ -43245,9 +43239,7 @@ async function readCuratorSummary(directory) {
|
|
|
43245
43239
|
}
|
|
43246
43240
|
return parsed;
|
|
43247
43241
|
} catch {
|
|
43248
|
-
|
|
43249
|
-
console.warn("Failed to parse curator-summary.json: invalid JSON");
|
|
43250
|
-
}
|
|
43242
|
+
warn("Failed to parse curator-summary.json: invalid JSON");
|
|
43251
43243
|
return null;
|
|
43252
43244
|
}
|
|
43253
43245
|
}
|
|
@@ -43280,9 +43272,7 @@ function filterPhaseEvents(eventsJsonl, phase, sinceTimestamp) {
|
|
|
43280
43272
|
}
|
|
43281
43273
|
}
|
|
43282
43274
|
} catch {
|
|
43283
|
-
|
|
43284
|
-
console.warn("filterPhaseEvents: skipping malformed line");
|
|
43285
|
-
}
|
|
43275
|
+
warn("filterPhaseEvents: skipping malformed line");
|
|
43286
43276
|
}
|
|
43287
43277
|
}
|
|
43288
43278
|
return filtered;
|
|
@@ -43831,7 +43821,6 @@ var init_curator = __esm(() => {
|
|
|
43831
43821
|
init_event_bus();
|
|
43832
43822
|
init_manager();
|
|
43833
43823
|
init_bun_compat();
|
|
43834
|
-
init_logger();
|
|
43835
43824
|
init_knowledge_store();
|
|
43836
43825
|
init_knowledge_validator();
|
|
43837
43826
|
init_utils2();
|
|
@@ -49256,7 +49245,6 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
|
49256
49245
|
await writeFile6(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
|
|
49257
49246
|
}
|
|
49258
49247
|
var init_knowledge_migrator = __esm(() => {
|
|
49259
|
-
init_logger();
|
|
49260
49248
|
init_knowledge_store();
|
|
49261
49249
|
init_knowledge_validator();
|
|
49262
49250
|
});
|
|
@@ -60219,13 +60207,13 @@ __export(exports_review_receipt, {
|
|
|
60219
60207
|
buildApprovedReceipt: () => buildApprovedReceipt
|
|
60220
60208
|
});
|
|
60221
60209
|
import * as crypto5 from "node:crypto";
|
|
60222
|
-
import * as
|
|
60223
|
-
import * as
|
|
60210
|
+
import * as fs35 from "node:fs";
|
|
60211
|
+
import * as path49 from "node:path";
|
|
60224
60212
|
function resolveReceiptsDir(directory) {
|
|
60225
|
-
return
|
|
60213
|
+
return path49.join(directory, ".swarm", "review-receipts");
|
|
60226
60214
|
}
|
|
60227
60215
|
function resolveReceiptIndexPath(directory) {
|
|
60228
|
-
return
|
|
60216
|
+
return path49.join(resolveReceiptsDir(directory), "index.json");
|
|
60229
60217
|
}
|
|
60230
60218
|
function buildReceiptFilename(id, date9) {
|
|
60231
60219
|
const dateStr = date9.toISOString().slice(0, 10);
|
|
@@ -60248,11 +60236,11 @@ function isScopeStale(receipt, currentContent) {
|
|
|
60248
60236
|
}
|
|
60249
60237
|
async function readReceiptIndex(directory) {
|
|
60250
60238
|
const indexPath = resolveReceiptIndexPath(directory);
|
|
60251
|
-
if (!
|
|
60239
|
+
if (!fs35.existsSync(indexPath)) {
|
|
60252
60240
|
return { schema_version: 1, entries: [] };
|
|
60253
60241
|
}
|
|
60254
60242
|
try {
|
|
60255
|
-
const content = await
|
|
60243
|
+
const content = await fs35.promises.readFile(indexPath, "utf-8");
|
|
60256
60244
|
const parsed = JSON.parse(content);
|
|
60257
60245
|
if (parsed.schema_version !== 1 || !Array.isArray(parsed.entries)) {
|
|
60258
60246
|
return { schema_version: 1, entries: [] };
|
|
@@ -60264,21 +60252,21 @@ async function readReceiptIndex(directory) {
|
|
|
60264
60252
|
}
|
|
60265
60253
|
async function writeReceiptIndex(directory, index) {
|
|
60266
60254
|
const indexPath = resolveReceiptIndexPath(directory);
|
|
60267
|
-
const dir =
|
|
60268
|
-
await
|
|
60255
|
+
const dir = path49.dirname(indexPath);
|
|
60256
|
+
await fs35.promises.mkdir(dir, { recursive: true });
|
|
60269
60257
|
const tmpPath = `${indexPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
60270
|
-
await
|
|
60271
|
-
|
|
60258
|
+
await fs35.promises.writeFile(tmpPath, JSON.stringify(index, null, 2), "utf-8");
|
|
60259
|
+
fs35.renameSync(tmpPath, indexPath);
|
|
60272
60260
|
}
|
|
60273
60261
|
async function persistReviewReceipt(directory, receipt) {
|
|
60274
60262
|
const receiptsDir = resolveReceiptsDir(directory);
|
|
60275
|
-
await
|
|
60263
|
+
await fs35.promises.mkdir(receiptsDir, { recursive: true });
|
|
60276
60264
|
const now = new Date(receipt.reviewed_at);
|
|
60277
60265
|
const filename = buildReceiptFilename(receipt.id, now);
|
|
60278
|
-
const receiptPath =
|
|
60266
|
+
const receiptPath = path49.join(receiptsDir, filename);
|
|
60279
60267
|
const tmpPath = `${receiptPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
60280
|
-
await
|
|
60281
|
-
|
|
60268
|
+
await fs35.promises.writeFile(tmpPath, JSON.stringify(receipt, null, 2), "utf-8");
|
|
60269
|
+
fs35.renameSync(tmpPath, receiptPath);
|
|
60282
60270
|
const index = await readReceiptIndex(directory);
|
|
60283
60271
|
const entry = {
|
|
60284
60272
|
id: receipt.id,
|
|
@@ -60297,9 +60285,9 @@ async function readReceiptById(directory, receiptId) {
|
|
|
60297
60285
|
const entry = index.entries.find((e) => e.id === receiptId);
|
|
60298
60286
|
if (!entry)
|
|
60299
60287
|
return null;
|
|
60300
|
-
const receiptPath =
|
|
60288
|
+
const receiptPath = path49.join(resolveReceiptsDir(directory), entry.filename);
|
|
60301
60289
|
try {
|
|
60302
|
-
const content = await
|
|
60290
|
+
const content = await fs35.promises.readFile(receiptPath, "utf-8");
|
|
60303
60291
|
return JSON.parse(content);
|
|
60304
60292
|
} catch {
|
|
60305
60293
|
return null;
|
|
@@ -60310,9 +60298,9 @@ async function readReceiptsByScopeHash(directory, scopeHash) {
|
|
|
60310
60298
|
const matching = index.entries.filter((e) => e.scope_hash === scopeHash).sort((a, b) => b.reviewed_at.localeCompare(a.reviewed_at));
|
|
60311
60299
|
const receipts = [];
|
|
60312
60300
|
for (const entry of matching) {
|
|
60313
|
-
const receiptPath =
|
|
60301
|
+
const receiptPath = path49.join(resolveReceiptsDir(directory), entry.filename);
|
|
60314
60302
|
try {
|
|
60315
|
-
const content = await
|
|
60303
|
+
const content = await fs35.promises.readFile(receiptPath, "utf-8");
|
|
60316
60304
|
receipts.push(JSON.parse(content));
|
|
60317
60305
|
} catch {}
|
|
60318
60306
|
}
|
|
@@ -60323,9 +60311,9 @@ async function readAllReceipts(directory) {
|
|
|
60323
60311
|
const sorted = [...index.entries].sort((a, b) => b.reviewed_at.localeCompare(a.reviewed_at));
|
|
60324
60312
|
const receipts = [];
|
|
60325
60313
|
for (const entry of sorted) {
|
|
60326
|
-
const receiptPath =
|
|
60314
|
+
const receiptPath = path49.join(resolveReceiptsDir(directory), entry.filename);
|
|
60327
60315
|
try {
|
|
60328
|
-
const content = await
|
|
60316
|
+
const content = await fs35.promises.readFile(receiptPath, "utf-8");
|
|
60329
60317
|
receipts.push(JSON.parse(content));
|
|
60330
60318
|
} catch {}
|
|
60331
60319
|
}
|
|
@@ -60446,7 +60434,6 @@ var init_preflight_integration = __esm(() => {
|
|
|
60446
60434
|
init_status_artifact();
|
|
60447
60435
|
init_trigger();
|
|
60448
60436
|
init_preflight_service();
|
|
60449
|
-
init_logger();
|
|
60450
60437
|
});
|
|
60451
60438
|
|
|
60452
60439
|
// node_modules/web-tree-sitter/tree-sitter.js
|
|
@@ -61911,11 +61898,11 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
61911
61898
|
throw toThrow;
|
|
61912
61899
|
}, "quit_");
|
|
61913
61900
|
var scriptDirectory = "";
|
|
61914
|
-
function locateFile(
|
|
61901
|
+
function locateFile(path60) {
|
|
61915
61902
|
if (Module["locateFile"]) {
|
|
61916
|
-
return Module["locateFile"](
|
|
61903
|
+
return Module["locateFile"](path60, scriptDirectory);
|
|
61917
61904
|
}
|
|
61918
|
-
return scriptDirectory +
|
|
61905
|
+
return scriptDirectory + path60;
|
|
61919
61906
|
}
|
|
61920
61907
|
__name(locateFile, "locateFile");
|
|
61921
61908
|
var readAsync, readBinary;
|
|
@@ -63664,13 +63651,13 @@ __export(exports_runtime, {
|
|
|
63664
63651
|
getInitializedLanguages: () => getInitializedLanguages,
|
|
63665
63652
|
clearParserCache: () => clearParserCache
|
|
63666
63653
|
});
|
|
63667
|
-
import * as
|
|
63654
|
+
import * as path60 from "node:path";
|
|
63668
63655
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
63669
63656
|
async function initTreeSitter() {
|
|
63670
63657
|
if (treeSitterInitialized) {
|
|
63671
63658
|
return;
|
|
63672
63659
|
}
|
|
63673
|
-
const thisDir =
|
|
63660
|
+
const thisDir = path60.dirname(fileURLToPath2(import.meta.url));
|
|
63674
63661
|
const isSource = thisDir.replace(/\\/g, "/").endsWith("/src/lang");
|
|
63675
63662
|
if (isSource) {
|
|
63676
63663
|
await Parser.init();
|
|
@@ -63678,7 +63665,7 @@ async function initTreeSitter() {
|
|
|
63678
63665
|
const grammarsDir = getGrammarsDirAbsolute();
|
|
63679
63666
|
await Parser.init({
|
|
63680
63667
|
locateFile(scriptName) {
|
|
63681
|
-
return
|
|
63668
|
+
return path60.join(grammarsDir, scriptName);
|
|
63682
63669
|
}
|
|
63683
63670
|
});
|
|
63684
63671
|
}
|
|
@@ -63699,11 +63686,11 @@ function getWasmFileName(languageId) {
|
|
|
63699
63686
|
return `tree-sitter-${sanitized}.wasm`;
|
|
63700
63687
|
}
|
|
63701
63688
|
function getGrammarsDirAbsolute() {
|
|
63702
|
-
const thisDir =
|
|
63689
|
+
const thisDir = path60.dirname(fileURLToPath2(import.meta.url));
|
|
63703
63690
|
const normalized = thisDir.replace(/\\/g, "/");
|
|
63704
63691
|
const isSource = normalized.endsWith("/src/lang");
|
|
63705
63692
|
const isCliBundle = normalized.endsWith("/cli");
|
|
63706
|
-
return isSource ?
|
|
63693
|
+
return isSource ? path60.join(thisDir, "grammars") : isCliBundle ? path60.join(thisDir, "..", "lang", "grammars") : path60.join(thisDir, "lang", "grammars");
|
|
63707
63694
|
}
|
|
63708
63695
|
async function loadGrammar(languageId) {
|
|
63709
63696
|
if (typeof languageId !== "string" || languageId.length > 100) {
|
|
@@ -63719,9 +63706,9 @@ async function loadGrammar(languageId) {
|
|
|
63719
63706
|
await initTreeSitter();
|
|
63720
63707
|
const parser = new Parser;
|
|
63721
63708
|
const wasmFileName = getWasmFileName(normalizedId);
|
|
63722
|
-
const wasmPath =
|
|
63723
|
-
const { existsSync:
|
|
63724
|
-
if (!
|
|
63709
|
+
const wasmPath = path60.join(getGrammarsDirAbsolute(), wasmFileName);
|
|
63710
|
+
const { existsSync: existsSync31 } = await import("node:fs");
|
|
63711
|
+
if (!existsSync31(wasmPath)) {
|
|
63725
63712
|
throw new Error(`Grammar file not found for ${languageId}: ${wasmPath}
|
|
63726
63713
|
Make sure to run 'bun run build' to copy grammar files to dist/lang/grammars/`);
|
|
63727
63714
|
}
|
|
@@ -63754,7 +63741,7 @@ async function isGrammarAvailable(languageId) {
|
|
|
63754
63741
|
}
|
|
63755
63742
|
try {
|
|
63756
63743
|
const wasmFileName = getWasmFileName(normalizedId);
|
|
63757
|
-
const wasmPath =
|
|
63744
|
+
const wasmPath = path60.join(getGrammarsDirAbsolute(), wasmFileName);
|
|
63758
63745
|
const { statSync: statSync19 } = await import("node:fs");
|
|
63759
63746
|
statSync19(wasmPath);
|
|
63760
63747
|
return true;
|
|
@@ -63811,15 +63798,15 @@ __export(exports_doc_scan, {
|
|
|
63811
63798
|
doc_extract: () => doc_extract
|
|
63812
63799
|
});
|
|
63813
63800
|
import * as crypto7 from "node:crypto";
|
|
63814
|
-
import * as
|
|
63801
|
+
import * as fs44 from "node:fs";
|
|
63815
63802
|
import { mkdir as mkdir10, readFile as readFile10, writeFile as writeFile9 } from "node:fs/promises";
|
|
63816
|
-
import * as
|
|
63803
|
+
import * as path62 from "node:path";
|
|
63817
63804
|
function normalizeSeparators(filePath) {
|
|
63818
63805
|
return filePath.replace(/\\/g, "/");
|
|
63819
63806
|
}
|
|
63820
63807
|
function matchesDocPattern(filePath, patterns) {
|
|
63821
63808
|
const normalizedPath = normalizeSeparators(filePath);
|
|
63822
|
-
const basename9 =
|
|
63809
|
+
const basename9 = path62.basename(filePath);
|
|
63823
63810
|
for (const pattern of patterns) {
|
|
63824
63811
|
if (!pattern.includes("/") && !pattern.includes("\\")) {
|
|
63825
63812
|
if (basename9 === pattern) {
|
|
@@ -63875,7 +63862,7 @@ function stripMarkdown(text) {
|
|
|
63875
63862
|
return text.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/^\s*[-*•]\s+/gm, "").replace(/^\s*\d+\.\s+/gm, "").trim();
|
|
63876
63863
|
}
|
|
63877
63864
|
async function scanDocIndex(directory) {
|
|
63878
|
-
const manifestPath =
|
|
63865
|
+
const manifestPath = path62.join(directory, ".swarm", "doc-manifest.json");
|
|
63879
63866
|
const defaultPatterns = DocsConfigSchema.parse({}).doc_patterns;
|
|
63880
63867
|
const extraPatterns = [
|
|
63881
63868
|
"ARCHITECTURE.md",
|
|
@@ -63892,8 +63879,8 @@ async function scanDocIndex(directory) {
|
|
|
63892
63879
|
let cacheValid = true;
|
|
63893
63880
|
for (const file3 of existingManifest.files) {
|
|
63894
63881
|
try {
|
|
63895
|
-
const fullPath =
|
|
63896
|
-
const stat5 =
|
|
63882
|
+
const fullPath = path62.join(directory, file3.path);
|
|
63883
|
+
const stat5 = fs44.statSync(fullPath);
|
|
63897
63884
|
if (stat5.mtimeMs > file3.mtime) {
|
|
63898
63885
|
cacheValid = false;
|
|
63899
63886
|
break;
|
|
@@ -63911,7 +63898,7 @@ async function scanDocIndex(directory) {
|
|
|
63911
63898
|
const discoveredFiles = [];
|
|
63912
63899
|
let rawEntries;
|
|
63913
63900
|
try {
|
|
63914
|
-
rawEntries =
|
|
63901
|
+
rawEntries = fs44.readdirSync(directory, { recursive: true });
|
|
63915
63902
|
} catch {
|
|
63916
63903
|
const manifest2 = {
|
|
63917
63904
|
schema_version: 1,
|
|
@@ -63922,10 +63909,10 @@ async function scanDocIndex(directory) {
|
|
|
63922
63909
|
}
|
|
63923
63910
|
const entries = rawEntries.filter((e) => typeof e === "string");
|
|
63924
63911
|
for (const entry of entries) {
|
|
63925
|
-
const fullPath =
|
|
63912
|
+
const fullPath = path62.join(directory, entry);
|
|
63926
63913
|
let stat5;
|
|
63927
63914
|
try {
|
|
63928
|
-
stat5 =
|
|
63915
|
+
stat5 = fs44.statSync(fullPath);
|
|
63929
63916
|
} catch {
|
|
63930
63917
|
continue;
|
|
63931
63918
|
}
|
|
@@ -63954,11 +63941,11 @@ async function scanDocIndex(directory) {
|
|
|
63954
63941
|
}
|
|
63955
63942
|
let content;
|
|
63956
63943
|
try {
|
|
63957
|
-
content =
|
|
63944
|
+
content = fs44.readFileSync(fullPath, "utf-8");
|
|
63958
63945
|
} catch {
|
|
63959
63946
|
continue;
|
|
63960
63947
|
}
|
|
63961
|
-
const { title, summary } = extractTitleAndSummary(content,
|
|
63948
|
+
const { title, summary } = extractTitleAndSummary(content, path62.basename(entry));
|
|
63962
63949
|
const lineCount = content.split(`
|
|
63963
63950
|
`).length;
|
|
63964
63951
|
discoveredFiles.push({
|
|
@@ -63984,7 +63971,7 @@ async function scanDocIndex(directory) {
|
|
|
63984
63971
|
files: discoveredFiles
|
|
63985
63972
|
};
|
|
63986
63973
|
try {
|
|
63987
|
-
await mkdir10(
|
|
63974
|
+
await mkdir10(path62.dirname(manifestPath), { recursive: true });
|
|
63988
63975
|
await writeFile9(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
63989
63976
|
} catch {}
|
|
63990
63977
|
return { manifest, cached: false };
|
|
@@ -64023,7 +64010,7 @@ function extractConstraintsFromContent(content) {
|
|
|
64023
64010
|
return constraints;
|
|
64024
64011
|
}
|
|
64025
64012
|
async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
64026
|
-
const manifestPath =
|
|
64013
|
+
const manifestPath = path62.join(directory, ".swarm", "doc-manifest.json");
|
|
64027
64014
|
let manifest;
|
|
64028
64015
|
try {
|
|
64029
64016
|
const content = await readFile10(manifestPath, "utf-8");
|
|
@@ -64049,7 +64036,7 @@ async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
|
64049
64036
|
}
|
|
64050
64037
|
let fullContent;
|
|
64051
64038
|
try {
|
|
64052
|
-
fullContent = await readFile10(
|
|
64039
|
+
fullContent = await readFile10(path62.join(directory, docFile.path), "utf-8");
|
|
64053
64040
|
} catch {
|
|
64054
64041
|
skippedCount++;
|
|
64055
64042
|
continue;
|
|
@@ -64072,7 +64059,7 @@ async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
|
64072
64059
|
tier: "swarm",
|
|
64073
64060
|
lesson: constraint,
|
|
64074
64061
|
category: "architecture",
|
|
64075
|
-
tags: ["doc-scan",
|
|
64062
|
+
tags: ["doc-scan", path62.basename(docFile.path)],
|
|
64076
64063
|
scope: "global",
|
|
64077
64064
|
confidence: 0.5,
|
|
64078
64065
|
status: "candidate",
|
|
@@ -64145,9 +64132,9 @@ var init_doc_scan = __esm(() => {
|
|
|
64145
64132
|
}
|
|
64146
64133
|
} catch {}
|
|
64147
64134
|
if (force) {
|
|
64148
|
-
const manifestPath =
|
|
64135
|
+
const manifestPath = path62.join(directory, ".swarm", "doc-manifest.json");
|
|
64149
64136
|
try {
|
|
64150
|
-
|
|
64137
|
+
fs44.unlinkSync(manifestPath);
|
|
64151
64138
|
} catch {}
|
|
64152
64139
|
}
|
|
64153
64140
|
const { manifest, cached: cached3 } = await scanDocIndex(directory);
|
|
@@ -64335,11 +64322,11 @@ __export(exports_curator_drift, {
|
|
|
64335
64322
|
readPriorDriftReports: () => readPriorDriftReports,
|
|
64336
64323
|
buildDriftInjectionText: () => buildDriftInjectionText
|
|
64337
64324
|
});
|
|
64338
|
-
import * as
|
|
64339
|
-
import * as
|
|
64325
|
+
import * as fs47 from "node:fs";
|
|
64326
|
+
import * as path65 from "node:path";
|
|
64340
64327
|
async function readPriorDriftReports(directory) {
|
|
64341
|
-
const swarmDir =
|
|
64342
|
-
const entries = await
|
|
64328
|
+
const swarmDir = path65.join(directory, ".swarm");
|
|
64329
|
+
const entries = await fs47.promises.readdir(swarmDir).catch(() => null);
|
|
64343
64330
|
if (entries === null)
|
|
64344
64331
|
return [];
|
|
64345
64332
|
const reportFiles = entries.filter((name2) => name2.startsWith(DRIFT_REPORT_PREFIX) && name2.endsWith(".json")).sort();
|
|
@@ -64365,10 +64352,10 @@ async function readPriorDriftReports(directory) {
|
|
|
64365
64352
|
async function writeDriftReport(directory, report) {
|
|
64366
64353
|
const filename = `${DRIFT_REPORT_PREFIX}${report.phase}.json`;
|
|
64367
64354
|
const filePath = validateSwarmPath(directory, filename);
|
|
64368
|
-
const swarmDir =
|
|
64369
|
-
await
|
|
64355
|
+
const swarmDir = path65.dirname(filePath);
|
|
64356
|
+
await fs47.promises.mkdir(swarmDir, { recursive: true });
|
|
64370
64357
|
try {
|
|
64371
|
-
await
|
|
64358
|
+
await fs47.promises.writeFile(filePath, JSON.stringify(report, null, 2), "utf-8");
|
|
64372
64359
|
} catch (err2) {
|
|
64373
64360
|
throw new Error(`[curator-drift] Failed to write drift report to ${filePath}: ${String(err2)}`);
|
|
64374
64361
|
}
|
|
@@ -64493,15 +64480,13 @@ function buildDriftInjectionText(report, maxChars) {
|
|
|
64493
64480
|
var DRIFT_REPORT_PREFIX = "drift-report-phase-";
|
|
64494
64481
|
var init_curator_drift = __esm(() => {
|
|
64495
64482
|
init_event_bus();
|
|
64496
|
-
init_logger();
|
|
64497
64483
|
init_utils2();
|
|
64498
64484
|
});
|
|
64499
64485
|
|
|
64500
64486
|
// src/index.ts
|
|
64501
64487
|
init_package();
|
|
64502
64488
|
init_agents2();
|
|
64503
|
-
import * as
|
|
64504
|
-
import * as path107 from "node:path";
|
|
64489
|
+
import * as path108 from "node:path";
|
|
64505
64490
|
|
|
64506
64491
|
// src/background/index.ts
|
|
64507
64492
|
init_event_bus();
|
|
@@ -64920,6 +64905,64 @@ function createSwarmCommandHandler(directory, agents) {
|
|
|
64920
64905
|
// src/index.ts
|
|
64921
64906
|
init_config();
|
|
64922
64907
|
init_constants();
|
|
64908
|
+
|
|
64909
|
+
// src/config/project-init.ts
|
|
64910
|
+
init_constants();
|
|
64911
|
+
import * as fs31 from "node:fs";
|
|
64912
|
+
import * as path48 from "node:path";
|
|
64913
|
+
var STARTER_CONTENT = `{}
|
|
64914
|
+
`;
|
|
64915
|
+
function writeProjectConfigIfNew(directory, quiet = false) {
|
|
64916
|
+
try {
|
|
64917
|
+
const opencodeDir = path48.join(directory, ".opencode");
|
|
64918
|
+
const dest = path48.join(opencodeDir, "opencode-swarm.json");
|
|
64919
|
+
try {
|
|
64920
|
+
const stat4 = fs31.lstatSync(opencodeDir);
|
|
64921
|
+
if (stat4.isSymbolicLink())
|
|
64922
|
+
return;
|
|
64923
|
+
} catch (err2) {
|
|
64924
|
+
if (err2.code !== "ENOENT")
|
|
64925
|
+
return;
|
|
64926
|
+
}
|
|
64927
|
+
if (!fs31.existsSync(opencodeDir)) {
|
|
64928
|
+
fs31.mkdirSync(opencodeDir, { recursive: true });
|
|
64929
|
+
}
|
|
64930
|
+
try {
|
|
64931
|
+
fs31.writeFileSync(dest, STARTER_CONTENT, {
|
|
64932
|
+
encoding: "utf-8",
|
|
64933
|
+
flag: "wx"
|
|
64934
|
+
});
|
|
64935
|
+
if (!quiet) {
|
|
64936
|
+
console.warn("[opencode-swarm] Created .opencode/opencode-swarm.json — " + "edit it to customize agent LLMs for this project, or commit it to share settings with your team");
|
|
64937
|
+
}
|
|
64938
|
+
} catch (_writeErr) {}
|
|
64939
|
+
} catch {}
|
|
64940
|
+
}
|
|
64941
|
+
function writeSwarmConfigExampleIfNew(projectDirectory) {
|
|
64942
|
+
try {
|
|
64943
|
+
const swarmDir = path48.join(projectDirectory, ".swarm");
|
|
64944
|
+
const dest = path48.join(swarmDir, "config.example.json");
|
|
64945
|
+
if (fs31.existsSync(dest))
|
|
64946
|
+
return;
|
|
64947
|
+
if (!fs31.existsSync(swarmDir)) {
|
|
64948
|
+
fs31.mkdirSync(swarmDir, { recursive: true });
|
|
64949
|
+
}
|
|
64950
|
+
const example = {
|
|
64951
|
+
agents: Object.fromEntries(Object.entries(DEFAULT_MODELS).filter(([name2]) => name2 !== "default").map(([name2, model]) => [
|
|
64952
|
+
name2,
|
|
64953
|
+
{
|
|
64954
|
+
model,
|
|
64955
|
+
fallback_models: ["opencode/gpt-5-nano", "opencode/big-pickle"]
|
|
64956
|
+
}
|
|
64957
|
+
])),
|
|
64958
|
+
max_iterations: 5
|
|
64959
|
+
};
|
|
64960
|
+
fs31.writeFileSync(dest, `${JSON.stringify(example, null, 2)}
|
|
64961
|
+
`, "utf-8");
|
|
64962
|
+
} catch {}
|
|
64963
|
+
}
|
|
64964
|
+
|
|
64965
|
+
// src/index.ts
|
|
64923
64966
|
init_schema();
|
|
64924
64967
|
|
|
64925
64968
|
// src/hooks/agent-activity.ts
|
|
@@ -64997,11 +65040,11 @@ async function doFlush(directory) {
|
|
|
64997
65040
|
const activitySection = renderActivitySection();
|
|
64998
65041
|
const updated = replaceOrAppendSection(existing, "## Agent Activity", activitySection);
|
|
64999
65042
|
const flushedCount = swarmState.pendingEvents;
|
|
65000
|
-
const
|
|
65001
|
-
const tempPath = `${
|
|
65043
|
+
const path49 = nodePath2.join(directory, ".swarm", "context.md");
|
|
65044
|
+
const tempPath = `${path49}.tmp`;
|
|
65002
65045
|
try {
|
|
65003
65046
|
await bunWrite(tempPath, updated);
|
|
65004
|
-
renameSync11(tempPath,
|
|
65047
|
+
renameSync11(tempPath, path49);
|
|
65005
65048
|
} catch (writeError) {
|
|
65006
65049
|
try {
|
|
65007
65050
|
unlinkSync8(tempPath);
|
|
@@ -65051,8 +65094,8 @@ ${content.substring(endIndex + 1)}`;
|
|
|
65051
65094
|
// src/hooks/compaction-customizer.ts
|
|
65052
65095
|
init_manager();
|
|
65053
65096
|
init_utils2();
|
|
65054
|
-
import * as
|
|
65055
|
-
import { join as
|
|
65097
|
+
import * as fs32 from "node:fs";
|
|
65098
|
+
import { join as join45 } from "node:path";
|
|
65056
65099
|
function createCompactionCustomizerHook(config3, directory) {
|
|
65057
65100
|
const enabled = config3.hooks?.compaction !== false;
|
|
65058
65101
|
if (!enabled) {
|
|
@@ -65097,8 +65140,8 @@ function createCompactionCustomizerHook(config3, directory) {
|
|
|
65097
65140
|
}
|
|
65098
65141
|
}
|
|
65099
65142
|
try {
|
|
65100
|
-
const summariesDir =
|
|
65101
|
-
const files = await
|
|
65143
|
+
const summariesDir = join45(directory, ".swarm", "summaries");
|
|
65144
|
+
const files = await fs32.promises.readdir(summariesDir);
|
|
65102
65145
|
if (files.length > 0) {
|
|
65103
65146
|
const count = files.length;
|
|
65104
65147
|
output.context.push(`[CONTEXT OPTIMIZATION] Tool outputs from earlier in this session have been stored to disk. When compacting, replace any large tool output blocks (bash, test_runner, lint, diff results) with a one-line reference: "[Output stored — use /swarm retrieve to access full content]". Preserve the tool name, exit status, and any error messages. Discard raw output lines.`);
|
|
@@ -65584,7 +65627,7 @@ init_delegation_gate();
|
|
|
65584
65627
|
|
|
65585
65628
|
// src/hooks/delegation-sanitizer.ts
|
|
65586
65629
|
init_utils2();
|
|
65587
|
-
import * as
|
|
65630
|
+
import * as fs33 from "node:fs";
|
|
65588
65631
|
var SANITIZATION_PATTERNS = [
|
|
65589
65632
|
/\b\d+(st|nd|rd|th)\s+(attempt|try|time)\b/gi,
|
|
65590
65633
|
/\b(5th|fifth|final|last)\s+attempt\b/gi,
|
|
@@ -65655,7 +65698,7 @@ function createDelegationSanitizerHook(directory) {
|
|
|
65655
65698
|
stripped_patterns: result.stripped,
|
|
65656
65699
|
timestamp: new Date().toISOString()
|
|
65657
65700
|
};
|
|
65658
|
-
|
|
65701
|
+
fs33.appendFileSync(eventsPath, `${JSON.stringify(event)}
|
|
65659
65702
|
`, "utf-8");
|
|
65660
65703
|
} catch {}
|
|
65661
65704
|
}
|
|
@@ -65721,9 +65764,8 @@ init_schema();
|
|
|
65721
65764
|
init_file_locks();
|
|
65722
65765
|
init_state();
|
|
65723
65766
|
init_telemetry();
|
|
65724
|
-
init_logger();
|
|
65725
65767
|
init_utils2();
|
|
65726
|
-
import * as
|
|
65768
|
+
import * as fs34 from "node:fs";
|
|
65727
65769
|
var END_OF_SENTENCE_QUESTION_PATTERN = /\?\s*$/;
|
|
65728
65770
|
var PHASE_COMPLETION_PATTERNS = [
|
|
65729
65771
|
/Ready for Phase (?:\d+|\[?N\+1\]?)\??/i,
|
|
@@ -65917,7 +65959,7 @@ async function writeAutoOversightEvent(directory, architectOutput, criticVerdict
|
|
|
65917
65959
|
}
|
|
65918
65960
|
try {
|
|
65919
65961
|
const eventsPath = validateSwarmPath(dir, "events.jsonl");
|
|
65920
|
-
|
|
65962
|
+
fs34.appendFileSync(eventsPath, `${JSON.stringify(event)}
|
|
65921
65963
|
`, "utf-8");
|
|
65922
65964
|
} catch (writeError) {
|
|
65923
65965
|
error48(`[full-auto-intercept] Warning: failed to write auto_oversight event: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
|
|
@@ -66229,7 +66271,7 @@ async function writeEscalationReport(directory, reason, architectOutput, interac
|
|
|
66229
66271
|
if (currentPhase === undefined) {
|
|
66230
66272
|
try {
|
|
66231
66273
|
const planPath = validateSwarmPath(directory, "plan.json");
|
|
66232
|
-
const planContent =
|
|
66274
|
+
const planContent = fs34.readFileSync(planPath, "utf-8");
|
|
66233
66275
|
const plan = JSON.parse(planContent);
|
|
66234
66276
|
const incompletePhases = plan.phases.filter((p) => p.status !== "complete").sort((a, b) => b.id - a.id);
|
|
66235
66277
|
currentPhase = incompletePhases[0]?.id;
|
|
@@ -66268,7 +66310,7 @@ ${currentPhase !== undefined ? `- **Phase Status**: Pending completion` : ""}
|
|
|
66268
66310
|
This escalation requires human intervention. The swarm has been paused.
|
|
66269
66311
|
Please review the architect's output above and provide guidance.
|
|
66270
66312
|
`;
|
|
66271
|
-
|
|
66313
|
+
fs34.writeFileSync(reportPath, reportContent, "utf-8");
|
|
66272
66314
|
log(`[full-auto-intercept] Escalation report written to: ${reportPath}`);
|
|
66273
66315
|
} catch (error93) {
|
|
66274
66316
|
error48(`[full-auto-intercept] Failed to write escalation report:`, error93 instanceof Error ? error93.message : String(error93));
|
|
@@ -66362,7 +66404,7 @@ init_schema();
|
|
|
66362
66404
|
init_manager();
|
|
66363
66405
|
init_curator();
|
|
66364
66406
|
init_utils2();
|
|
66365
|
-
import * as
|
|
66407
|
+
import * as path50 from "node:path";
|
|
66366
66408
|
function createPhaseMonitorHook(directory, preflightManager, curatorRunner, delegateFactory) {
|
|
66367
66409
|
let lastKnownPhase = null;
|
|
66368
66410
|
const handler = async (input, _output) => {
|
|
@@ -66382,9 +66424,9 @@ function createPhaseMonitorHook(directory, preflightManager, curatorRunner, dele
|
|
|
66382
66424
|
const llmDelegate = delegateFactory?.(sessionId);
|
|
66383
66425
|
const initResult = await runner(directory, curatorConfig, llmDelegate);
|
|
66384
66426
|
if (initResult.briefing) {
|
|
66385
|
-
const briefingPath =
|
|
66427
|
+
const briefingPath = path50.join(directory, ".swarm", "curator-briefing.md");
|
|
66386
66428
|
const { mkdir: mkdir8, writeFile: writeFile8 } = await import("node:fs/promises");
|
|
66387
|
-
await mkdir8(
|
|
66429
|
+
await mkdir8(path50.dirname(briefingPath), { recursive: true });
|
|
66388
66430
|
await writeFile8(briefingPath, initResult.briefing, "utf-8");
|
|
66389
66431
|
const { buildApprovedReceipt: buildApprovedReceipt2, persistReviewReceipt: persistReviewReceipt2 } = await Promise.resolve().then(() => (init_review_receipt(), exports_review_receipt));
|
|
66390
66432
|
const initReceipt = buildApprovedReceipt2({
|
|
@@ -66509,17 +66551,16 @@ ${originalText}`;
|
|
|
66509
66551
|
}
|
|
66510
66552
|
// src/hooks/repo-graph-builder.ts
|
|
66511
66553
|
init_constants();
|
|
66512
|
-
import * as
|
|
66554
|
+
import * as path53 from "node:path";
|
|
66513
66555
|
|
|
66514
66556
|
// src/tools/repo-graph.ts
|
|
66515
66557
|
init_utils2();
|
|
66516
|
-
init_logger();
|
|
66517
66558
|
init_path_security();
|
|
66518
66559
|
import * as fsSync3 from "node:fs";
|
|
66519
|
-
import { constants as constants4, existsSync as
|
|
66560
|
+
import { constants as constants4, existsSync as existsSync29, realpathSync as realpathSync6 } from "node:fs";
|
|
66520
66561
|
import * as fsPromises5 from "node:fs/promises";
|
|
66521
66562
|
import * as os7 from "node:os";
|
|
66522
|
-
import * as
|
|
66563
|
+
import * as path52 from "node:path";
|
|
66523
66564
|
|
|
66524
66565
|
// src/utils/timeout.ts
|
|
66525
66566
|
async function withTimeout(promise3, ms, timeoutError) {
|
|
@@ -66550,8 +66591,8 @@ function yieldToEventLoop() {
|
|
|
66550
66591
|
init_zod();
|
|
66551
66592
|
init_create_tool();
|
|
66552
66593
|
init_path_security();
|
|
66553
|
-
import * as
|
|
66554
|
-
import * as
|
|
66594
|
+
import * as fs36 from "node:fs";
|
|
66595
|
+
import * as path51 from "node:path";
|
|
66555
66596
|
var MAX_FILE_SIZE_BYTES2 = 1024 * 1024;
|
|
66556
66597
|
var WINDOWS_RESERVED_NAMES = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
66557
66598
|
function containsWindowsAttacks(str) {
|
|
@@ -66568,11 +66609,11 @@ function containsWindowsAttacks(str) {
|
|
|
66568
66609
|
}
|
|
66569
66610
|
function isPathInWorkspace(filePath, workspace) {
|
|
66570
66611
|
try {
|
|
66571
|
-
const resolvedPath =
|
|
66572
|
-
const realWorkspace =
|
|
66573
|
-
const realResolvedPath =
|
|
66574
|
-
const relativePath =
|
|
66575
|
-
if (relativePath.startsWith("..") ||
|
|
66612
|
+
const resolvedPath = path51.resolve(workspace, filePath);
|
|
66613
|
+
const realWorkspace = fs36.realpathSync(workspace);
|
|
66614
|
+
const realResolvedPath = fs36.realpathSync(resolvedPath);
|
|
66615
|
+
const relativePath = path51.relative(realWorkspace, realResolvedPath);
|
|
66616
|
+
if (relativePath.startsWith("..") || path51.isAbsolute(relativePath)) {
|
|
66576
66617
|
return false;
|
|
66577
66618
|
}
|
|
66578
66619
|
return true;
|
|
@@ -66584,17 +66625,17 @@ function validatePathForRead(filePath, workspace) {
|
|
|
66584
66625
|
return isPathInWorkspace(filePath, workspace);
|
|
66585
66626
|
}
|
|
66586
66627
|
function extractTSSymbols(filePath, cwd) {
|
|
66587
|
-
const fullPath =
|
|
66628
|
+
const fullPath = path51.join(cwd, filePath);
|
|
66588
66629
|
if (!validatePathForRead(fullPath, cwd)) {
|
|
66589
66630
|
return [];
|
|
66590
66631
|
}
|
|
66591
66632
|
let content;
|
|
66592
66633
|
try {
|
|
66593
|
-
const stats =
|
|
66634
|
+
const stats = fs36.statSync(fullPath);
|
|
66594
66635
|
if (stats.size > MAX_FILE_SIZE_BYTES2) {
|
|
66595
66636
|
throw new Error(`File too large: ${stats.size} bytes (max: ${MAX_FILE_SIZE_BYTES2})`);
|
|
66596
66637
|
}
|
|
66597
|
-
content =
|
|
66638
|
+
content = fs36.readFileSync(fullPath, "utf-8");
|
|
66598
66639
|
} catch {
|
|
66599
66640
|
return [];
|
|
66600
66641
|
}
|
|
@@ -66736,17 +66777,17 @@ function extractTSSymbols(filePath, cwd) {
|
|
|
66736
66777
|
});
|
|
66737
66778
|
}
|
|
66738
66779
|
function extractPythonSymbols(filePath, cwd) {
|
|
66739
|
-
const fullPath =
|
|
66780
|
+
const fullPath = path51.join(cwd, filePath);
|
|
66740
66781
|
if (!validatePathForRead(fullPath, cwd)) {
|
|
66741
66782
|
return [];
|
|
66742
66783
|
}
|
|
66743
66784
|
let content;
|
|
66744
66785
|
try {
|
|
66745
|
-
const stats =
|
|
66786
|
+
const stats = fs36.statSync(fullPath);
|
|
66746
66787
|
if (stats.size > MAX_FILE_SIZE_BYTES2) {
|
|
66747
66788
|
throw new Error(`File too large: ${stats.size} bytes (max: ${MAX_FILE_SIZE_BYTES2})`);
|
|
66748
66789
|
}
|
|
66749
|
-
content =
|
|
66790
|
+
content = fs36.readFileSync(fullPath, "utf-8");
|
|
66750
66791
|
} catch {
|
|
66751
66792
|
return [];
|
|
66752
66793
|
}
|
|
@@ -66819,7 +66860,7 @@ var symbols = createSwarmTool({
|
|
|
66819
66860
|
}, null, 2);
|
|
66820
66861
|
}
|
|
66821
66862
|
const cwd = directory;
|
|
66822
|
-
const ext =
|
|
66863
|
+
const ext = path51.extname(file3);
|
|
66823
66864
|
if (containsControlChars(file3)) {
|
|
66824
66865
|
return JSON.stringify({
|
|
66825
66866
|
file: file3,
|
|
@@ -66883,7 +66924,7 @@ var symbols = createSwarmTool({
|
|
|
66883
66924
|
var WINDOWS_RENAME_MAX_RETRIES2 = 3;
|
|
66884
66925
|
var WINDOWS_RENAME_RETRY_DELAY_MS2 = 50;
|
|
66885
66926
|
function normalizeGraphPath(filePath) {
|
|
66886
|
-
return
|
|
66927
|
+
return path52.normalize(filePath).replace(/\\/g, "/");
|
|
66887
66928
|
}
|
|
66888
66929
|
var REPO_GRAPH_FILENAME = "repo-graph.json";
|
|
66889
66930
|
var GRAPH_SCHEMA_VERSION = "1.0.0";
|
|
@@ -66992,8 +67033,8 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
|
|
|
66992
67033
|
}
|
|
66993
67034
|
try {
|
|
66994
67035
|
if (specifier.startsWith(".")) {
|
|
66995
|
-
const sourceDir =
|
|
66996
|
-
let resolved =
|
|
67036
|
+
const sourceDir = path52.dirname(sourceFile);
|
|
67037
|
+
let resolved = path52.resolve(sourceDir, specifier);
|
|
66997
67038
|
let realResolved;
|
|
66998
67039
|
try {
|
|
66999
67040
|
realResolved = realpathSync6(resolved);
|
|
@@ -67004,9 +67045,9 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
|
|
|
67004
67045
|
try {
|
|
67005
67046
|
realRoot = realpathSync6(workspaceRoot);
|
|
67006
67047
|
} catch {
|
|
67007
|
-
realRoot =
|
|
67048
|
+
realRoot = path52.normalize(workspaceRoot);
|
|
67008
67049
|
}
|
|
67009
|
-
if (!
|
|
67050
|
+
if (!existsSync29(resolved)) {
|
|
67010
67051
|
const EXTENSIONS = [
|
|
67011
67052
|
".ts",
|
|
67012
67053
|
".tsx",
|
|
@@ -67020,7 +67061,7 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
|
|
|
67020
67061
|
let found = null;
|
|
67021
67062
|
for (const ext of EXTENSIONS) {
|
|
67022
67063
|
const candidate = resolved + ext;
|
|
67023
|
-
if (
|
|
67064
|
+
if (existsSync29(candidate)) {
|
|
67024
67065
|
found = candidate;
|
|
67025
67066
|
break;
|
|
67026
67067
|
}
|
|
@@ -67036,9 +67077,9 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
|
|
|
67036
67077
|
return null;
|
|
67037
67078
|
}
|
|
67038
67079
|
}
|
|
67039
|
-
const normalizedResolved =
|
|
67040
|
-
const normalizedRoot =
|
|
67041
|
-
if (!normalizedResolved.startsWith(normalizedRoot +
|
|
67080
|
+
const normalizedResolved = path52.normalize(realResolved);
|
|
67081
|
+
const normalizedRoot = path52.normalize(realRoot);
|
|
67082
|
+
if (!normalizedResolved.startsWith(normalizedRoot + path52.sep) && normalizedResolved !== normalizedRoot) {
|
|
67042
67083
|
return null;
|
|
67043
67084
|
}
|
|
67044
67085
|
return resolved;
|
|
@@ -67051,7 +67092,7 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
|
|
|
67051
67092
|
function createEmptyGraph(workspaceRoot) {
|
|
67052
67093
|
return {
|
|
67053
67094
|
schema_version: GRAPH_SCHEMA_VERSION,
|
|
67054
|
-
workspaceRoot:
|
|
67095
|
+
workspaceRoot: path52.normalize(workspaceRoot),
|
|
67055
67096
|
nodes: {},
|
|
67056
67097
|
edges: [],
|
|
67057
67098
|
metadata: {
|
|
@@ -67085,10 +67126,10 @@ function addEdge(graph, edge) {
|
|
|
67085
67126
|
}
|
|
67086
67127
|
}
|
|
67087
67128
|
function getCachedGraph(workspace) {
|
|
67088
|
-
return graphCache.get(
|
|
67129
|
+
return graphCache.get(path52.normalize(workspace));
|
|
67089
67130
|
}
|
|
67090
67131
|
function setCachedGraph(workspace, graph, mtime) {
|
|
67091
|
-
const normalized =
|
|
67132
|
+
const normalized = path52.normalize(workspace);
|
|
67092
67133
|
graphCache.set(normalized, graph);
|
|
67093
67134
|
dirtyFlags.set(normalized, false);
|
|
67094
67135
|
if (mtime !== undefined) {
|
|
@@ -67096,10 +67137,10 @@ function setCachedGraph(workspace, graph, mtime) {
|
|
|
67096
67137
|
}
|
|
67097
67138
|
}
|
|
67098
67139
|
function isDirty(workspace) {
|
|
67099
|
-
return dirtyFlags.get(
|
|
67140
|
+
return dirtyFlags.get(path52.normalize(workspace)) ?? false;
|
|
67100
67141
|
}
|
|
67101
67142
|
function clearCache(workspace) {
|
|
67102
|
-
const normalized =
|
|
67143
|
+
const normalized = path52.normalize(workspace);
|
|
67103
67144
|
graphCache.delete(normalized);
|
|
67104
67145
|
dirtyFlags.delete(normalized);
|
|
67105
67146
|
mtimeCache.delete(normalized);
|
|
@@ -67112,12 +67153,12 @@ function getGraphPath(workspace) {
|
|
|
67112
67153
|
}
|
|
67113
67154
|
async function loadGraph(workspace) {
|
|
67114
67155
|
validateWorkspace(workspace);
|
|
67115
|
-
const normalized =
|
|
67156
|
+
const normalized = path52.normalize(workspace);
|
|
67116
67157
|
const cached3 = getCachedGraph(normalized);
|
|
67117
67158
|
if (cached3 && !isDirty(normalized)) {
|
|
67118
67159
|
try {
|
|
67119
67160
|
const graphPath = getGraphPath(workspace);
|
|
67120
|
-
if (
|
|
67161
|
+
if (existsSync29(graphPath)) {
|
|
67121
67162
|
const stats = await fsPromises5.stat(graphPath);
|
|
67122
67163
|
const cachedMtime = mtimeCache.get(normalized);
|
|
67123
67164
|
if (cachedMtime !== undefined && stats.mtimeMs !== cachedMtime) {
|
|
@@ -67134,7 +67175,7 @@ async function loadGraph(workspace) {
|
|
|
67134
67175
|
}
|
|
67135
67176
|
try {
|
|
67136
67177
|
const graphPath = getGraphPath(workspace);
|
|
67137
|
-
if (!
|
|
67178
|
+
if (!existsSync29(graphPath)) {
|
|
67138
67179
|
return null;
|
|
67139
67180
|
}
|
|
67140
67181
|
const stats = await fsPromises5.stat(graphPath);
|
|
@@ -67206,28 +67247,28 @@ async function saveGraph(workspace, graph, options) {
|
|
|
67206
67247
|
if (!Array.isArray(graph.edges)) {
|
|
67207
67248
|
throw new Error("Graph must have edges array");
|
|
67208
67249
|
}
|
|
67209
|
-
const normalizedWorkspace =
|
|
67250
|
+
const normalizedWorkspace = path52.normalize(workspace);
|
|
67210
67251
|
let realWorkspace;
|
|
67211
67252
|
try {
|
|
67212
67253
|
realWorkspace = realpathSync6(workspace);
|
|
67213
67254
|
} catch {
|
|
67214
67255
|
realWorkspace = normalizedWorkspace;
|
|
67215
67256
|
}
|
|
67216
|
-
const normalizedGraphRoot =
|
|
67257
|
+
const normalizedGraphRoot = path52.normalize(graph.workspaceRoot);
|
|
67217
67258
|
let realGraphRoot;
|
|
67218
67259
|
try {
|
|
67219
67260
|
realGraphRoot = realpathSync6(graph.workspaceRoot);
|
|
67220
67261
|
} catch {
|
|
67221
67262
|
realGraphRoot = normalizedGraphRoot;
|
|
67222
67263
|
}
|
|
67223
|
-
if (
|
|
67264
|
+
if (path52.normalize(realWorkspace) !== path52.normalize(realGraphRoot)) {
|
|
67224
67265
|
throw new Error(`Graph workspaceRoot mismatch: graph was built for "${graph.workspaceRoot}" but save was called for "${workspace}"`);
|
|
67225
67266
|
}
|
|
67226
67267
|
const normalized = normalizedWorkspace;
|
|
67227
67268
|
const graphPath = getGraphPath(workspace);
|
|
67228
67269
|
updateGraphMetadata(graph);
|
|
67229
67270
|
const tempPath = `${graphPath}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`;
|
|
67230
|
-
await fsPromises5.mkdir(
|
|
67271
|
+
await fsPromises5.mkdir(path52.dirname(tempPath), { recursive: true });
|
|
67231
67272
|
let lastError = null;
|
|
67232
67273
|
try {
|
|
67233
67274
|
if (options?.createAtomic) {
|
|
@@ -67311,12 +67352,12 @@ function isRefusedWorkspaceRoot(target) {
|
|
|
67311
67352
|
try {
|
|
67312
67353
|
resolved = realpathSync6(target);
|
|
67313
67354
|
} catch {
|
|
67314
|
-
resolved =
|
|
67355
|
+
resolved = path52.resolve(target);
|
|
67315
67356
|
}
|
|
67316
67357
|
const refused = new Set;
|
|
67317
67358
|
const add = (p) => {
|
|
67318
67359
|
if (typeof p === "string" && p.length > 0) {
|
|
67319
|
-
refused.add(
|
|
67360
|
+
refused.add(path52.resolve(p));
|
|
67320
67361
|
}
|
|
67321
67362
|
};
|
|
67322
67363
|
add(os7.homedir());
|
|
@@ -67435,7 +67476,7 @@ async function findSourceFilesAsync(dir, stats, options) {
|
|
|
67435
67476
|
ctx.stats.skippedDirs++;
|
|
67436
67477
|
continue;
|
|
67437
67478
|
}
|
|
67438
|
-
const fullPath =
|
|
67479
|
+
const fullPath = path52.join(current, entry.name);
|
|
67439
67480
|
if (entry.isSymbolicLink() && !ctx.followSymlinks) {
|
|
67440
67481
|
ctx.stats.skippedDirs++;
|
|
67441
67482
|
continue;
|
|
@@ -67443,7 +67484,7 @@ async function findSourceFilesAsync(dir, stats, options) {
|
|
|
67443
67484
|
if (entry.isDirectory()) {
|
|
67444
67485
|
queue.push(fullPath);
|
|
67445
67486
|
} else if (entry.isFile()) {
|
|
67446
|
-
const ext =
|
|
67487
|
+
const ext = path52.extname(fullPath).toLowerCase();
|
|
67447
67488
|
if (SUPPORTED_EXTENSIONS.includes(ext)) {
|
|
67448
67489
|
files.push(fullPath);
|
|
67449
67490
|
}
|
|
@@ -67460,11 +67501,11 @@ async function findSourceFilesAsync(dir, stats, options) {
|
|
|
67460
67501
|
return files;
|
|
67461
67502
|
}
|
|
67462
67503
|
function toModuleName(filePath, workspaceRoot) {
|
|
67463
|
-
const relative9 =
|
|
67464
|
-
return relative9.split(
|
|
67504
|
+
const relative9 = path52.relative(workspaceRoot, filePath);
|
|
67505
|
+
return relative9.split(path52.sep).join("/");
|
|
67465
67506
|
}
|
|
67466
67507
|
function getLanguage(filePath) {
|
|
67467
|
-
const ext =
|
|
67508
|
+
const ext = path52.extname(filePath).toLowerCase();
|
|
67468
67509
|
return EXTENSION_TO_LANGUAGE[ext] ?? "unknown";
|
|
67469
67510
|
}
|
|
67470
67511
|
function isBinaryContent(content) {
|
|
@@ -67479,8 +67520,8 @@ async function buildWorkspaceGraphAsync(workspaceRoot, options) {
|
|
|
67479
67520
|
const maxFiles = options?.maxFiles ?? DEFAULT_WALK_FILE_CAP;
|
|
67480
67521
|
const walkBudgetMs = options?.walkBudgetMs ?? DEFAULT_WALK_BUDGET_MS;
|
|
67481
67522
|
const followSymlinks = options?.followSymlinks ?? false;
|
|
67482
|
-
const absoluteRoot =
|
|
67483
|
-
if (!
|
|
67523
|
+
const absoluteRoot = path52.resolve(workspaceRoot);
|
|
67524
|
+
if (!existsSync29(absoluteRoot)) {
|
|
67484
67525
|
throw new Error(`Workspace directory does not exist: ${workspaceRoot}`);
|
|
67485
67526
|
}
|
|
67486
67527
|
if (isRefusedWorkspaceRoot(absoluteRoot)) {
|
|
@@ -67549,15 +67590,15 @@ function scanFile(filePath, absoluteRoot, maxFileSize) {
|
|
|
67549
67590
|
if (isBinaryContent(content)) {
|
|
67550
67591
|
return { node: null, edges: [] };
|
|
67551
67592
|
}
|
|
67552
|
-
const ext =
|
|
67593
|
+
const ext = path52.extname(filePath).toLowerCase();
|
|
67553
67594
|
let exports = [];
|
|
67554
67595
|
try {
|
|
67555
67596
|
if ([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"].includes(ext)) {
|
|
67556
|
-
const relativePath =
|
|
67597
|
+
const relativePath = path52.relative(absoluteRoot, filePath);
|
|
67557
67598
|
const symbols2 = extractTSSymbols(relativePath, absoluteRoot);
|
|
67558
67599
|
exports = symbols2.filter((s) => s.exported).map((s) => s.name);
|
|
67559
67600
|
} else if (ext === ".py") {
|
|
67560
|
-
const relativePath =
|
|
67601
|
+
const relativePath = path52.relative(absoluteRoot, filePath);
|
|
67561
67602
|
const symbols2 = extractPythonSymbols(relativePath, absoluteRoot);
|
|
67562
67603
|
exports = symbols2.filter((s) => s.exported).map((s) => s.name);
|
|
67563
67604
|
}
|
|
@@ -67601,12 +67642,12 @@ async function updateGraphForFiles(workspaceRoot, filePaths, options) {
|
|
|
67601
67642
|
return graph2;
|
|
67602
67643
|
}
|
|
67603
67644
|
const graph = existingGraph;
|
|
67604
|
-
const absoluteRoot =
|
|
67645
|
+
const absoluteRoot = path52.resolve(workspaceRoot);
|
|
67605
67646
|
const maxFileSize = 1024 * 1024;
|
|
67606
67647
|
const updatedPaths = new Set;
|
|
67607
67648
|
for (const rawFilePath of filePaths) {
|
|
67608
67649
|
const normalizedPath = normalizeGraphPath(rawFilePath);
|
|
67609
|
-
const fileExists =
|
|
67650
|
+
const fileExists = existsSync29(rawFilePath);
|
|
67610
67651
|
if (fileExists) {
|
|
67611
67652
|
graph.edges = graph.edges.filter((e) => normalizeGraphPath(e.source) !== normalizedPath);
|
|
67612
67653
|
const result = scanFile(rawFilePath, absoluteRoot, maxFileSize);
|
|
@@ -67645,9 +67686,7 @@ async function updateGraphForFiles(workspaceRoot, filePaths, options) {
|
|
|
67645
67686
|
await saveGraph(workspaceRoot, graph);
|
|
67646
67687
|
return graph;
|
|
67647
67688
|
}
|
|
67648
|
-
|
|
67649
67689
|
// src/hooks/repo-graph-builder.ts
|
|
67650
|
-
init_logger();
|
|
67651
67690
|
var SUPPORTED_EXTENSIONS2 = [
|
|
67652
67691
|
".ts",
|
|
67653
67692
|
".tsx",
|
|
@@ -67723,7 +67762,7 @@ function createRepoGraphBuilderHook(workspaceRoot, deps) {
|
|
|
67723
67762
|
filePath = filePath.replace(/./g, ".").replace(///g, "/").replace(/․/g, ".");
|
|
67724
67763
|
if (!isSupportedSourceFile(filePath))
|
|
67725
67764
|
return;
|
|
67726
|
-
const absoluteFilePath =
|
|
67765
|
+
const absoluteFilePath = path53.isAbsolute(filePath) ? filePath : path53.resolve(workspaceRoot, filePath);
|
|
67727
67766
|
const normalizedAbsolute = absoluteFilePath.replace(/\\/g, "/");
|
|
67728
67767
|
const normalizedWorkspace = workspaceRoot.replace(/\\/g, "/");
|
|
67729
67768
|
if (!normalizedAbsolute.startsWith(`${normalizedWorkspace}/`) && normalizedAbsolute !== normalizedWorkspace) {
|
|
@@ -67731,7 +67770,7 @@ function createRepoGraphBuilderHook(workspaceRoot, deps) {
|
|
|
67731
67770
|
}
|
|
67732
67771
|
try {
|
|
67733
67772
|
await _updateGraphForFiles(workspaceRoot, [absoluteFilePath]);
|
|
67734
|
-
log(`[repo-graph] Incremental update for ${
|
|
67773
|
+
log(`[repo-graph] Incremental update for ${path53.basename(filePath)}`);
|
|
67735
67774
|
} catch (error93) {
|
|
67736
67775
|
const message = error93 instanceof Error ? error93.message : String(error93);
|
|
67737
67776
|
error48(`[repo-graph] Incremental update failed: ${message}`);
|
|
@@ -67749,15 +67788,15 @@ init_schema();
|
|
|
67749
67788
|
init_manager2();
|
|
67750
67789
|
init_detector();
|
|
67751
67790
|
init_manager();
|
|
67752
|
-
import * as
|
|
67753
|
-
import * as
|
|
67791
|
+
import * as fs45 from "node:fs";
|
|
67792
|
+
import * as path63 from "node:path";
|
|
67754
67793
|
|
|
67755
67794
|
// src/services/decision-drift-analyzer.ts
|
|
67756
67795
|
init_utils2();
|
|
67757
67796
|
init_manager();
|
|
67758
67797
|
init_utils();
|
|
67759
|
-
import * as
|
|
67760
|
-
import * as
|
|
67798
|
+
import * as fs37 from "node:fs";
|
|
67799
|
+
import * as path54 from "node:path";
|
|
67761
67800
|
var DEFAULT_DRIFT_CONFIG = {
|
|
67762
67801
|
staleThresholdPhases: 1,
|
|
67763
67802
|
detectContradictions: true,
|
|
@@ -67911,11 +67950,11 @@ async function analyzeDecisionDrift(directory, config3 = {}) {
|
|
|
67911
67950
|
currentPhase = legacyPhase;
|
|
67912
67951
|
}
|
|
67913
67952
|
}
|
|
67914
|
-
const contextPath =
|
|
67953
|
+
const contextPath = path54.join(directory, ".swarm", "context.md");
|
|
67915
67954
|
let contextContent = "";
|
|
67916
67955
|
try {
|
|
67917
|
-
if (
|
|
67918
|
-
contextContent =
|
|
67956
|
+
if (fs37.existsSync(contextPath)) {
|
|
67957
|
+
contextContent = fs37.readFileSync(contextPath, "utf-8");
|
|
67919
67958
|
}
|
|
67920
67959
|
} catch (error93) {
|
|
67921
67960
|
log("[DecisionDriftAnalyzer] context file read failed", {
|
|
@@ -68049,8 +68088,8 @@ init_utils();
|
|
|
68049
68088
|
// src/hooks/adversarial-detector.ts
|
|
68050
68089
|
init_constants();
|
|
68051
68090
|
init_schema();
|
|
68052
|
-
import * as
|
|
68053
|
-
import * as
|
|
68091
|
+
import * as fs38 from "node:fs/promises";
|
|
68092
|
+
import * as path55 from "node:path";
|
|
68054
68093
|
function safeGet(obj, key) {
|
|
68055
68094
|
if (!obj || !Object.hasOwn(obj, key))
|
|
68056
68095
|
return;
|
|
@@ -68282,10 +68321,10 @@ async function handleDebuggingSpiral(match, taskId, directory) {
|
|
|
68282
68321
|
let eventLogged = false;
|
|
68283
68322
|
let checkpointCreated = false;
|
|
68284
68323
|
try {
|
|
68285
|
-
const swarmDir =
|
|
68286
|
-
await
|
|
68287
|
-
const eventsPath =
|
|
68288
|
-
await
|
|
68324
|
+
const swarmDir = path55.join(directory, ".swarm");
|
|
68325
|
+
await fs38.mkdir(swarmDir, { recursive: true });
|
|
68326
|
+
const eventsPath = path55.join(swarmDir, "events.jsonl");
|
|
68327
|
+
await fs38.appendFile(eventsPath, `${formatDebuggingSpiralEvent(match, taskId)}
|
|
68289
68328
|
`);
|
|
68290
68329
|
eventLogged = true;
|
|
68291
68330
|
} catch {}
|
|
@@ -68415,11 +68454,11 @@ function rankCandidates(candidates, config3) {
|
|
|
68415
68454
|
init_knowledge_store();
|
|
68416
68455
|
|
|
68417
68456
|
// src/hooks/repo-graph-injection.ts
|
|
68418
|
-
import * as
|
|
68457
|
+
import * as fs42 from "node:fs";
|
|
68419
68458
|
|
|
68420
68459
|
// src/graph/graph-builder.ts
|
|
68421
|
-
import * as
|
|
68422
|
-
import * as
|
|
68460
|
+
import * as fs40 from "node:fs";
|
|
68461
|
+
import * as path58 from "node:path";
|
|
68423
68462
|
|
|
68424
68463
|
// node_modules/yocto-queue/index.js
|
|
68425
68464
|
class Node {
|
|
@@ -68579,8 +68618,8 @@ function validateConcurrency(concurrency) {
|
|
|
68579
68618
|
|
|
68580
68619
|
// src/graph/import-extractor.ts
|
|
68581
68620
|
init_path_security();
|
|
68582
|
-
import * as
|
|
68583
|
-
import * as
|
|
68621
|
+
import * as fs39 from "node:fs";
|
|
68622
|
+
import * as path56 from "node:path";
|
|
68584
68623
|
var SOURCE_EXTENSIONS2 = [
|
|
68585
68624
|
".ts",
|
|
68586
68625
|
".tsx",
|
|
@@ -68625,27 +68664,27 @@ function getLanguageFromExtension(ext) {
|
|
|
68625
68664
|
return null;
|
|
68626
68665
|
}
|
|
68627
68666
|
function toRelForwardSlash(absPath, root) {
|
|
68628
|
-
return
|
|
68667
|
+
return path56.relative(root, absPath).replace(/\\/g, "/");
|
|
68629
68668
|
}
|
|
68630
68669
|
function tryResolveTSJS(rawModule, sourceFileAbs) {
|
|
68631
68670
|
if (!rawModule.startsWith(".") && !rawModule.startsWith("/")) {
|
|
68632
68671
|
return null;
|
|
68633
68672
|
}
|
|
68634
|
-
const sourceDir =
|
|
68635
|
-
const baseAbs =
|
|
68673
|
+
const sourceDir = path56.dirname(sourceFileAbs);
|
|
68674
|
+
const baseAbs = path56.resolve(sourceDir, rawModule);
|
|
68636
68675
|
const probe = (basePath) => {
|
|
68637
68676
|
for (const ext of RESOLVE_EXTENSION_CANDIDATES) {
|
|
68638
68677
|
const test = basePath + ext;
|
|
68639
68678
|
try {
|
|
68640
|
-
const stat5 =
|
|
68679
|
+
const stat5 = fs39.statSync(test);
|
|
68641
68680
|
if (stat5.isFile())
|
|
68642
68681
|
return test;
|
|
68643
68682
|
} catch {}
|
|
68644
68683
|
}
|
|
68645
68684
|
for (const indexFile of RESOLVE_INDEX_CANDIDATES) {
|
|
68646
|
-
const test =
|
|
68685
|
+
const test = path56.join(basePath, indexFile);
|
|
68647
68686
|
try {
|
|
68648
|
-
const stat5 =
|
|
68687
|
+
const stat5 = fs39.statSync(test);
|
|
68649
68688
|
if (stat5.isFile())
|
|
68650
68689
|
return test;
|
|
68651
68690
|
} catch {}
|
|
@@ -68673,13 +68712,13 @@ function tryResolvePython(rawModule, sourceFileAbs, workspaceRoot) {
|
|
|
68673
68712
|
}
|
|
68674
68713
|
const remainder = rawModule.slice(leadingDots).replace(/\./g, "/");
|
|
68675
68714
|
const upDirs = "../".repeat(Math.max(0, leadingDots - 1));
|
|
68676
|
-
const sourceDir =
|
|
68677
|
-
const baseAbs =
|
|
68715
|
+
const sourceDir = path56.dirname(sourceFileAbs);
|
|
68716
|
+
const baseAbs = path56.resolve(sourceDir, upDirs + remainder);
|
|
68678
68717
|
const accept = (test) => {
|
|
68679
68718
|
try {
|
|
68680
|
-
const stat5 =
|
|
68719
|
+
const stat5 = fs39.statSync(test);
|
|
68681
68720
|
if (stat5.isFile()) {
|
|
68682
|
-
const rel =
|
|
68721
|
+
const rel = path56.relative(workspaceRoot, test).replace(/\\/g, "/");
|
|
68683
68722
|
if (rel.startsWith(".."))
|
|
68684
68723
|
return null;
|
|
68685
68724
|
return test;
|
|
@@ -68693,7 +68732,7 @@ function tryResolvePython(rawModule, sourceFileAbs, workspaceRoot) {
|
|
|
68693
68732
|
return hit;
|
|
68694
68733
|
}
|
|
68695
68734
|
for (const indexFile of PY_INDEX_CANDIDATES) {
|
|
68696
|
-
const hit = accept(
|
|
68735
|
+
const hit = accept(path56.join(baseAbs, indexFile));
|
|
68697
68736
|
if (hit)
|
|
68698
68737
|
return hit;
|
|
68699
68738
|
}
|
|
@@ -69064,14 +69103,14 @@ function parseRustUses(content) {
|
|
|
69064
69103
|
}
|
|
69065
69104
|
function extractImports2(opts) {
|
|
69066
69105
|
const { absoluteFilePath, workspaceRoot } = opts;
|
|
69067
|
-
const ext =
|
|
69106
|
+
const ext = path56.extname(absoluteFilePath).toLowerCase();
|
|
69068
69107
|
const language = getLanguageFromExtension(ext);
|
|
69069
69108
|
if (!language)
|
|
69070
69109
|
return [];
|
|
69071
69110
|
let content = opts.content;
|
|
69072
69111
|
if (content === undefined) {
|
|
69073
69112
|
try {
|
|
69074
|
-
content =
|
|
69113
|
+
content = fs39.readFileSync(absoluteFilePath, "utf-8");
|
|
69075
69114
|
} catch {
|
|
69076
69115
|
return [];
|
|
69077
69116
|
}
|
|
@@ -69115,9 +69154,9 @@ function extractImports2(opts) {
|
|
|
69115
69154
|
}
|
|
69116
69155
|
|
|
69117
69156
|
// src/graph/symbol-extractor.ts
|
|
69118
|
-
import * as
|
|
69157
|
+
import * as path57 from "node:path";
|
|
69119
69158
|
function extractExportedSymbols(relativeFilePath, workspaceRoot) {
|
|
69120
|
-
const ext =
|
|
69159
|
+
const ext = path57.extname(relativeFilePath).toLowerCase();
|
|
69121
69160
|
const language = getLanguageFromExtension(ext);
|
|
69122
69161
|
if (!language)
|
|
69123
69162
|
return [];
|
|
@@ -69191,7 +69230,7 @@ function findSourceFiles(workspaceRoot, skipDirs = DEFAULT_SKIP_DIRS) {
|
|
|
69191
69230
|
const dir = stack.pop();
|
|
69192
69231
|
let entries;
|
|
69193
69232
|
try {
|
|
69194
|
-
entries =
|
|
69233
|
+
entries = fs40.readdirSync(dir, { withFileTypes: true });
|
|
69195
69234
|
} catch {
|
|
69196
69235
|
continue;
|
|
69197
69236
|
}
|
|
@@ -69206,15 +69245,15 @@ function findSourceFiles(workspaceRoot, skipDirs = DEFAULT_SKIP_DIRS) {
|
|
|
69206
69245
|
if (entry.isDirectory()) {
|
|
69207
69246
|
if (skipDirs.has(entry.name))
|
|
69208
69247
|
continue;
|
|
69209
|
-
stack.push(
|
|
69248
|
+
stack.push(path58.join(dir, entry.name));
|
|
69210
69249
|
continue;
|
|
69211
69250
|
}
|
|
69212
69251
|
if (!entry.isFile())
|
|
69213
69252
|
continue;
|
|
69214
|
-
const ext =
|
|
69253
|
+
const ext = path58.extname(entry.name).toLowerCase();
|
|
69215
69254
|
if (!SOURCE_EXT_SET.has(ext))
|
|
69216
69255
|
continue;
|
|
69217
|
-
out2.push(
|
|
69256
|
+
out2.push(path58.join(dir, entry.name));
|
|
69218
69257
|
}
|
|
69219
69258
|
}
|
|
69220
69259
|
return out2;
|
|
@@ -69242,13 +69281,13 @@ async function buildRepoGraph(workspaceRoot, options = {}) {
|
|
|
69242
69281
|
};
|
|
69243
69282
|
}
|
|
69244
69283
|
async function processFile(absoluteFilePath, workspaceRoot) {
|
|
69245
|
-
const ext =
|
|
69284
|
+
const ext = path58.extname(absoluteFilePath).toLowerCase();
|
|
69246
69285
|
const language = getLanguageFromExtension(ext);
|
|
69247
69286
|
if (!language)
|
|
69248
69287
|
return null;
|
|
69249
69288
|
let stats;
|
|
69250
69289
|
try {
|
|
69251
|
-
stats =
|
|
69290
|
+
stats = fs40.statSync(absoluteFilePath);
|
|
69252
69291
|
} catch {
|
|
69253
69292
|
return null;
|
|
69254
69293
|
}
|
|
@@ -69258,11 +69297,11 @@ async function processFile(absoluteFilePath, workspaceRoot) {
|
|
|
69258
69297
|
return null;
|
|
69259
69298
|
let content;
|
|
69260
69299
|
try {
|
|
69261
|
-
content =
|
|
69300
|
+
content = fs40.readFileSync(absoluteFilePath, "utf-8");
|
|
69262
69301
|
} catch {
|
|
69263
69302
|
return null;
|
|
69264
69303
|
}
|
|
69265
|
-
const relPath =
|
|
69304
|
+
const relPath = path58.relative(workspaceRoot, absoluteFilePath).replace(/\\/g, "/");
|
|
69266
69305
|
const imports = extractImports2({
|
|
69267
69306
|
absoluteFilePath,
|
|
69268
69307
|
workspaceRoot,
|
|
@@ -69503,17 +69542,17 @@ function formatSummary(opts) {
|
|
|
69503
69542
|
}
|
|
69504
69543
|
// src/graph/graph-store.ts
|
|
69505
69544
|
import * as crypto6 from "node:crypto";
|
|
69506
|
-
import * as
|
|
69507
|
-
import * as
|
|
69545
|
+
import * as fs41 from "node:fs";
|
|
69546
|
+
import * as path59 from "node:path";
|
|
69508
69547
|
var SWARM_DIR = ".swarm";
|
|
69509
69548
|
function getGraphPath2(workspaceRoot) {
|
|
69510
|
-
return
|
|
69549
|
+
return path59.join(workspaceRoot, SWARM_DIR, REPO_GRAPH_FILENAME2);
|
|
69511
69550
|
}
|
|
69512
69551
|
function loadGraph2(workspaceRoot) {
|
|
69513
69552
|
const file3 = getGraphPath2(workspaceRoot);
|
|
69514
69553
|
let raw;
|
|
69515
69554
|
try {
|
|
69516
|
-
raw =
|
|
69555
|
+
raw = fs41.readFileSync(file3, "utf-8");
|
|
69517
69556
|
} catch {
|
|
69518
69557
|
return null;
|
|
69519
69558
|
}
|
|
@@ -69529,9 +69568,9 @@ function loadGraph2(workspaceRoot) {
|
|
|
69529
69568
|
}
|
|
69530
69569
|
function saveGraph2(workspaceRoot, graph) {
|
|
69531
69570
|
const file3 = getGraphPath2(workspaceRoot);
|
|
69532
|
-
const dir =
|
|
69571
|
+
const dir = path59.dirname(file3);
|
|
69533
69572
|
try {
|
|
69534
|
-
const stat5 =
|
|
69573
|
+
const stat5 = fs41.lstatSync(dir);
|
|
69535
69574
|
if (stat5.isSymbolicLink()) {
|
|
69536
69575
|
throw new Error(`refusing to write graph: ${SWARM_DIR}/ is a symbolic link`);
|
|
69537
69576
|
}
|
|
@@ -69539,14 +69578,14 @@ function saveGraph2(workspaceRoot, graph) {
|
|
|
69539
69578
|
if (err2.code !== "ENOENT")
|
|
69540
69579
|
throw err2;
|
|
69541
69580
|
}
|
|
69542
|
-
|
|
69581
|
+
fs41.mkdirSync(dir, { recursive: true });
|
|
69543
69582
|
const tmp = `${file3}.tmp.${crypto6.randomUUID()}`;
|
|
69544
|
-
|
|
69583
|
+
fs41.writeFileSync(tmp, JSON.stringify(graph), "utf-8");
|
|
69545
69584
|
try {
|
|
69546
|
-
|
|
69585
|
+
fs41.renameSync(tmp, file3);
|
|
69547
69586
|
} catch (renameErr) {
|
|
69548
69587
|
try {
|
|
69549
|
-
|
|
69588
|
+
fs41.unlinkSync(tmp);
|
|
69550
69589
|
} catch {}
|
|
69551
69590
|
throw renameErr;
|
|
69552
69591
|
}
|
|
@@ -69570,7 +69609,7 @@ function getCachedGraph2(directory) {
|
|
|
69570
69609
|
const file3 = getGraphPath2(directory);
|
|
69571
69610
|
let stat5;
|
|
69572
69611
|
try {
|
|
69573
|
-
stat5 =
|
|
69612
|
+
stat5 = fs42.statSync(file3);
|
|
69574
69613
|
} catch {
|
|
69575
69614
|
cache.delete(directory);
|
|
69576
69615
|
return null;
|
|
@@ -69634,8 +69673,8 @@ function buildReviewerBlastRadiusBlock(directory, changedFiles) {
|
|
|
69634
69673
|
|
|
69635
69674
|
// src/hooks/semantic-diff-injection.ts
|
|
69636
69675
|
import * as child_process5 from "node:child_process";
|
|
69637
|
-
import * as
|
|
69638
|
-
import * as
|
|
69676
|
+
import * as fs43 from "node:fs";
|
|
69677
|
+
import * as path61 from "node:path";
|
|
69639
69678
|
|
|
69640
69679
|
// src/diff/ast-diff.ts
|
|
69641
69680
|
init_tree_sitter();
|
|
@@ -70382,17 +70421,17 @@ async function buildSemanticDiffBlock(directory, changedFiles, maxFiles = 10) {
|
|
|
70382
70421
|
const fileConsumers = {};
|
|
70383
70422
|
if (graph) {
|
|
70384
70423
|
for (const f of filesToProcess) {
|
|
70385
|
-
const relativePath =
|
|
70424
|
+
const relativePath = path61.isAbsolute(f) ? path61.relative(directory, f) : f;
|
|
70386
70425
|
const normalized = normalizeGraphPath2(relativePath);
|
|
70387
70426
|
fileConsumers[normalized] = getImporters(graph, normalized).length;
|
|
70388
70427
|
fileConsumers[f] = fileConsumers[normalized];
|
|
70389
70428
|
}
|
|
70390
70429
|
}
|
|
70391
70430
|
for (const filePath of filesToProcess) {
|
|
70392
|
-
const normalizedPath =
|
|
70393
|
-
const resolvedPath =
|
|
70394
|
-
const relativeToDir =
|
|
70395
|
-
if (relativeToDir.startsWith("..") ||
|
|
70431
|
+
const normalizedPath = path61.normalize(filePath);
|
|
70432
|
+
const resolvedPath = path61.resolve(directory, normalizedPath);
|
|
70433
|
+
const relativeToDir = path61.relative(directory, resolvedPath);
|
|
70434
|
+
if (relativeToDir.startsWith("..") || path61.isAbsolute(relativeToDir)) {
|
|
70396
70435
|
continue;
|
|
70397
70436
|
}
|
|
70398
70437
|
try {
|
|
@@ -70419,7 +70458,7 @@ async function buildSemanticDiffBlock(directory, changedFiles, maxFiles = 10) {
|
|
|
70419
70458
|
stdio: "pipe",
|
|
70420
70459
|
maxBuffer: 5 * 1024 * 1024
|
|
70421
70460
|
}) : "";
|
|
70422
|
-
const newContent =
|
|
70461
|
+
const newContent = fs43.readFileSync(path61.join(directory, filePath), "utf-8");
|
|
70423
70462
|
const astResult = await computeASTDiff(filePath, oldContent, newContent);
|
|
70424
70463
|
if (astResult && (astResult.changes.length > 0 || astResult.error !== undefined)) {
|
|
70425
70464
|
astDiffs.push(astResult);
|
|
@@ -70746,7 +70785,7 @@ function createSystemEnhancerHook(config3, directory) {
|
|
|
70746
70785
|
} catch {}
|
|
70747
70786
|
try {
|
|
70748
70787
|
const darkMatterPath = validateSwarmPath(directory, "dark-matter.md");
|
|
70749
|
-
if (!
|
|
70788
|
+
if (!fs45.existsSync(darkMatterPath)) {
|
|
70750
70789
|
const {
|
|
70751
70790
|
detectDarkMatter: detectDarkMatter2,
|
|
70752
70791
|
formatDarkMatterOutput: formatDarkMatterOutput2,
|
|
@@ -70758,25 +70797,25 @@ function createSystemEnhancerHook(config3, directory) {
|
|
|
70758
70797
|
});
|
|
70759
70798
|
if (darkMatter && darkMatter.length > 0) {
|
|
70760
70799
|
const darkMatterReport = formatDarkMatterOutput2(darkMatter);
|
|
70761
|
-
await
|
|
70800
|
+
await fs45.promises.writeFile(darkMatterPath, darkMatterReport, "utf-8");
|
|
70762
70801
|
warn(`[system-enhancer] Dark matter scan complete: ${darkMatter.length} co-change patterns found`);
|
|
70763
70802
|
try {
|
|
70764
|
-
const projectName =
|
|
70803
|
+
const projectName = path63.basename(path63.resolve(directory));
|
|
70765
70804
|
const knowledgeEntries = darkMatterToKnowledgeEntries2(darkMatter, projectName);
|
|
70766
70805
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
70767
70806
|
const existingEntries = await readKnowledge(knowledgePath);
|
|
70768
70807
|
const existingLessons = new Set(existingEntries.map((e) => e.lesson));
|
|
70769
70808
|
const newEntries = knowledgeEntries.filter((e) => !existingLessons.has(e.lesson));
|
|
70770
70809
|
if (newEntries.length === 0) {
|
|
70771
|
-
|
|
70810
|
+
warn(`[system-enhancer] No new knowledge entries (all duplicates)`);
|
|
70772
70811
|
} else {
|
|
70773
70812
|
for (const entry of newEntries) {
|
|
70774
70813
|
await appendKnowledge(knowledgePath, entry);
|
|
70775
70814
|
}
|
|
70776
|
-
|
|
70815
|
+
warn(`[system-enhancer] Created ${newEntries.length} new knowledge entries (${knowledgeEntries.length - newEntries.length} duplicates skipped)`);
|
|
70777
70816
|
}
|
|
70778
70817
|
} catch (e) {
|
|
70779
|
-
|
|
70818
|
+
warn(`[system-enhancer] Failed to create knowledge entries: ${e}`);
|
|
70780
70819
|
}
|
|
70781
70820
|
}
|
|
70782
70821
|
}
|
|
@@ -70825,14 +70864,14 @@ function createSystemEnhancerHook(config3, directory) {
|
|
|
70825
70864
|
if (handoffContent) {
|
|
70826
70865
|
const handoffPath = validateSwarmPath(directory, "handoff.md");
|
|
70827
70866
|
const consumedPath = validateSwarmPath(directory, "handoff-consumed.md");
|
|
70828
|
-
if (
|
|
70867
|
+
if (fs45.existsSync(consumedPath)) {
|
|
70829
70868
|
warn("Duplicate handoff detected: handoff-consumed.md already exists");
|
|
70830
|
-
|
|
70869
|
+
fs45.unlinkSync(consumedPath);
|
|
70831
70870
|
}
|
|
70832
|
-
|
|
70871
|
+
fs45.renameSync(handoffPath, consumedPath);
|
|
70833
70872
|
try {
|
|
70834
70873
|
const promptPath = validateSwarmPath(directory, "handoff-prompt.md");
|
|
70835
|
-
|
|
70874
|
+
fs45.unlinkSync(promptPath);
|
|
70836
70875
|
} catch {}
|
|
70837
70876
|
const handoffBlock = `## HANDOFF — Resuming from model switch
|
|
70838
70877
|
The previous model's session ended. Here is your starting context:
|
|
@@ -70960,9 +70999,9 @@ ${lines.join(`
|
|
|
70960
70999
|
try {
|
|
70961
71000
|
const taskId_ccp = ccpSession?.currentTaskId;
|
|
70962
71001
|
if (taskId_ccp && !taskId_ccp.includes("..") && !taskId_ccp.includes("/") && !taskId_ccp.includes("\\") && !taskId_ccp.includes("\x00")) {
|
|
70963
|
-
const evidencePath =
|
|
70964
|
-
if (
|
|
70965
|
-
const evidenceContent =
|
|
71002
|
+
const evidencePath = path63.join(directory, ".swarm", "evidence", `${taskId_ccp}.json`);
|
|
71003
|
+
if (fs45.existsSync(evidencePath)) {
|
|
71004
|
+
const evidenceContent = fs45.readFileSync(evidencePath, "utf-8");
|
|
70966
71005
|
const evidenceData = JSON.parse(evidenceContent);
|
|
70967
71006
|
const rejections = (evidenceData.bundle?.entries ?? []).filter((e) => e.type === "gate" && e.gate_type === "reviewer" && e.verdict === "reject");
|
|
70968
71007
|
if (rejections.length > 0) {
|
|
@@ -71226,11 +71265,11 @@ ${budgetWarning}`);
|
|
|
71226
71265
|
if (handoffContent) {
|
|
71227
71266
|
const handoffPath = validateSwarmPath(directory, "handoff.md");
|
|
71228
71267
|
const consumedPath = validateSwarmPath(directory, "handoff-consumed.md");
|
|
71229
|
-
if (
|
|
71268
|
+
if (fs45.existsSync(consumedPath)) {
|
|
71230
71269
|
warn("Duplicate handoff detected: handoff-consumed.md already exists");
|
|
71231
|
-
|
|
71270
|
+
fs45.unlinkSync(consumedPath);
|
|
71232
71271
|
}
|
|
71233
|
-
|
|
71272
|
+
fs45.renameSync(handoffPath, consumedPath);
|
|
71234
71273
|
const handoffBlock = `## HANDOFF — Resuming from model switch
|
|
71235
71274
|
The previous model's session ended. Here is your starting context:
|
|
71236
71275
|
|
|
@@ -72107,8 +72146,8 @@ init_guardrails();
|
|
|
72107
72146
|
init_hive_promoter();
|
|
72108
72147
|
|
|
72109
72148
|
// src/hooks/incremental-verify.ts
|
|
72110
|
-
import * as
|
|
72111
|
-
import * as
|
|
72149
|
+
import * as fs46 from "node:fs";
|
|
72150
|
+
import * as path64 from "node:path";
|
|
72112
72151
|
|
|
72113
72152
|
// src/hooks/spawn-helper.ts
|
|
72114
72153
|
import * as child_process6 from "node:child_process";
|
|
@@ -72186,21 +72225,21 @@ function spawnAsync(command, cwd, timeoutMs) {
|
|
|
72186
72225
|
// src/hooks/incremental-verify.ts
|
|
72187
72226
|
var emittedSkipAdvisories = new Set;
|
|
72188
72227
|
function detectPackageManager(projectDir) {
|
|
72189
|
-
if (
|
|
72228
|
+
if (fs46.existsSync(path64.join(projectDir, "bun.lockb")))
|
|
72190
72229
|
return "bun";
|
|
72191
|
-
if (
|
|
72230
|
+
if (fs46.existsSync(path64.join(projectDir, "pnpm-lock.yaml")))
|
|
72192
72231
|
return "pnpm";
|
|
72193
|
-
if (
|
|
72232
|
+
if (fs46.existsSync(path64.join(projectDir, "yarn.lock")))
|
|
72194
72233
|
return "yarn";
|
|
72195
|
-
if (
|
|
72234
|
+
if (fs46.existsSync(path64.join(projectDir, "package-lock.json")))
|
|
72196
72235
|
return "npm";
|
|
72197
72236
|
return "bun";
|
|
72198
72237
|
}
|
|
72199
72238
|
function detectTypecheckCommand(projectDir) {
|
|
72200
|
-
const pkgPath =
|
|
72201
|
-
if (
|
|
72239
|
+
const pkgPath = path64.join(projectDir, "package.json");
|
|
72240
|
+
if (fs46.existsSync(pkgPath)) {
|
|
72202
72241
|
try {
|
|
72203
|
-
const pkg = JSON.parse(
|
|
72242
|
+
const pkg = JSON.parse(fs46.readFileSync(pkgPath, "utf8"));
|
|
72204
72243
|
const scripts = pkg.scripts;
|
|
72205
72244
|
if (scripts?.typecheck) {
|
|
72206
72245
|
const pm = detectPackageManager(projectDir);
|
|
@@ -72214,8 +72253,8 @@ function detectTypecheckCommand(projectDir) {
|
|
|
72214
72253
|
...pkg.dependencies,
|
|
72215
72254
|
...pkg.devDependencies
|
|
72216
72255
|
};
|
|
72217
|
-
if (!deps?.typescript && !
|
|
72218
|
-
const hasTSMarkers = deps?.typescript ||
|
|
72256
|
+
if (!deps?.typescript && !fs46.existsSync(path64.join(projectDir, "tsconfig.json"))) {}
|
|
72257
|
+
const hasTSMarkers = deps?.typescript || fs46.existsSync(path64.join(projectDir, "tsconfig.json"));
|
|
72219
72258
|
if (hasTSMarkers) {
|
|
72220
72259
|
return { command: ["npx", "tsc", "--noEmit"], language: "typescript" };
|
|
72221
72260
|
}
|
|
@@ -72223,17 +72262,17 @@ function detectTypecheckCommand(projectDir) {
|
|
|
72223
72262
|
return null;
|
|
72224
72263
|
}
|
|
72225
72264
|
}
|
|
72226
|
-
if (
|
|
72265
|
+
if (fs46.existsSync(path64.join(projectDir, "go.mod"))) {
|
|
72227
72266
|
return { command: ["go", "vet", "./..."], language: "go" };
|
|
72228
72267
|
}
|
|
72229
|
-
if (
|
|
72268
|
+
if (fs46.existsSync(path64.join(projectDir, "Cargo.toml"))) {
|
|
72230
72269
|
return { command: ["cargo", "check"], language: "rust" };
|
|
72231
72270
|
}
|
|
72232
|
-
if (
|
|
72271
|
+
if (fs46.existsSync(path64.join(projectDir, "pyproject.toml")) || fs46.existsSync(path64.join(projectDir, "requirements.txt")) || fs46.existsSync(path64.join(projectDir, "setup.py"))) {
|
|
72233
72272
|
return { command: null, language: "python" };
|
|
72234
72273
|
}
|
|
72235
72274
|
try {
|
|
72236
|
-
const entries =
|
|
72275
|
+
const entries = fs46.readdirSync(projectDir);
|
|
72237
72276
|
if (entries.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
|
|
72238
72277
|
return {
|
|
72239
72278
|
command: ["dotnet", "build", "--no-restore"],
|
|
@@ -72477,7 +72516,7 @@ function createKnowledgeInjectorHook(directory, config3) {
|
|
|
72477
72516
|
const headroomChars = MODEL_LIMIT_CHARS - existingChars;
|
|
72478
72517
|
const MIN_INJECT_CHARS = config3.context_budget_threshold ?? 300;
|
|
72479
72518
|
if (headroomChars < MIN_INJECT_CHARS) {
|
|
72480
|
-
|
|
72519
|
+
warn(`[knowledge-injector] Skipping: only ${headroomChars} chars of headroom remain (existing: ${existingChars}, limit: ${MODEL_LIMIT_CHARS})`);
|
|
72481
72520
|
return;
|
|
72482
72521
|
}
|
|
72483
72522
|
const maxInjectChars = config3.inject_char_budget ?? 2000;
|
|
@@ -72579,7 +72618,7 @@ init_scope_persistence();
|
|
|
72579
72618
|
init_state();
|
|
72580
72619
|
init_delegation_gate();
|
|
72581
72620
|
init_normalize_tool_name();
|
|
72582
|
-
import * as
|
|
72621
|
+
import * as path66 from "node:path";
|
|
72583
72622
|
var WRITE_TOOLS = new Set(WRITE_TOOL_NAMES);
|
|
72584
72623
|
function createScopeGuardHook(config3, directory, injectAdvisory) {
|
|
72585
72624
|
const enabled = config3.enabled ?? true;
|
|
@@ -72637,13 +72676,13 @@ function createScopeGuardHook(config3, directory, injectAdvisory) {
|
|
|
72637
72676
|
}
|
|
72638
72677
|
function isFileInScope(filePath, scopeEntries, directory) {
|
|
72639
72678
|
const dir = directory ?? process.cwd();
|
|
72640
|
-
const resolvedFile =
|
|
72679
|
+
const resolvedFile = path66.resolve(dir, filePath);
|
|
72641
72680
|
return scopeEntries.some((scope) => {
|
|
72642
|
-
const resolvedScope =
|
|
72681
|
+
const resolvedScope = path66.resolve(dir, scope);
|
|
72643
72682
|
if (resolvedFile === resolvedScope)
|
|
72644
72683
|
return true;
|
|
72645
|
-
const rel =
|
|
72646
|
-
return rel.length > 0 && !rel.startsWith("..") && !
|
|
72684
|
+
const rel = path66.relative(resolvedScope, resolvedFile);
|
|
72685
|
+
return rel.length > 0 && !rel.startsWith("..") && !path66.isAbsolute(rel);
|
|
72647
72686
|
});
|
|
72648
72687
|
}
|
|
72649
72688
|
|
|
@@ -72694,8 +72733,8 @@ function createSelfReviewHook(config3, injectAdvisory) {
|
|
|
72694
72733
|
}
|
|
72695
72734
|
|
|
72696
72735
|
// src/hooks/slop-detector.ts
|
|
72697
|
-
import * as
|
|
72698
|
-
import * as
|
|
72736
|
+
import * as fs48 from "node:fs";
|
|
72737
|
+
import * as path67 from "node:path";
|
|
72699
72738
|
var WRITE_EDIT_TOOLS = new Set([
|
|
72700
72739
|
"write",
|
|
72701
72740
|
"edit",
|
|
@@ -72740,12 +72779,12 @@ function checkBoilerplateExplosion(content, taskDescription, threshold) {
|
|
|
72740
72779
|
function walkFiles(dir, exts, deadline) {
|
|
72741
72780
|
const results = [];
|
|
72742
72781
|
try {
|
|
72743
|
-
for (const entry of
|
|
72782
|
+
for (const entry of fs48.readdirSync(dir, { withFileTypes: true })) {
|
|
72744
72783
|
if (deadline !== undefined && Date.now() > deadline)
|
|
72745
72784
|
break;
|
|
72746
72785
|
if (entry.isSymbolicLink())
|
|
72747
72786
|
continue;
|
|
72748
|
-
const full =
|
|
72787
|
+
const full = path67.join(dir, entry.name);
|
|
72749
72788
|
if (entry.isDirectory()) {
|
|
72750
72789
|
if (entry.name === "node_modules" || entry.name === ".git")
|
|
72751
72790
|
continue;
|
|
@@ -72760,7 +72799,7 @@ function walkFiles(dir, exts, deadline) {
|
|
|
72760
72799
|
return results;
|
|
72761
72800
|
}
|
|
72762
72801
|
function checkDeadExports(content, projectDir, startTime) {
|
|
72763
|
-
const hasPackageJson =
|
|
72802
|
+
const hasPackageJson = fs48.existsSync(path67.join(projectDir, "package.json"));
|
|
72764
72803
|
if (!hasPackageJson)
|
|
72765
72804
|
return null;
|
|
72766
72805
|
const exportMatches = content.matchAll(/^\+(?:export)\s+(?:function|class|const|type|interface)\s+(\w{3,})/gm);
|
|
@@ -72783,7 +72822,7 @@ function checkDeadExports(content, projectDir, startTime) {
|
|
|
72783
72822
|
if (found || Date.now() - startTime > 480)
|
|
72784
72823
|
break;
|
|
72785
72824
|
try {
|
|
72786
|
-
const text =
|
|
72825
|
+
const text = fs48.readFileSync(file3, "utf-8");
|
|
72787
72826
|
if (importPattern.test(text))
|
|
72788
72827
|
found = true;
|
|
72789
72828
|
importPattern.lastIndex = 0;
|
|
@@ -72874,17 +72913,17 @@ function checkDuplicateUtility(content, projectDir, startTime, targetFile) {
|
|
|
72874
72913
|
for (const utilDir of utilityDirs) {
|
|
72875
72914
|
if (Date.now() > deadline)
|
|
72876
72915
|
break;
|
|
72877
|
-
const utilPath =
|
|
72878
|
-
if (!
|
|
72916
|
+
const utilPath = path67.join(projectDir, utilDir);
|
|
72917
|
+
if (!fs48.existsSync(utilPath))
|
|
72879
72918
|
continue;
|
|
72880
72919
|
const files = walkFiles(utilPath, [".ts", ".tsx", ".js", ".jsx"], deadline);
|
|
72881
72920
|
for (const file3 of files) {
|
|
72882
72921
|
if (Date.now() > deadline)
|
|
72883
72922
|
break;
|
|
72884
|
-
if (targetFile &&
|
|
72923
|
+
if (targetFile && path67.resolve(file3) === path67.resolve(targetFile))
|
|
72885
72924
|
continue;
|
|
72886
72925
|
try {
|
|
72887
|
-
const text =
|
|
72926
|
+
const text = fs48.readFileSync(file3, "utf-8");
|
|
72888
72927
|
for (const name2 of newExports) {
|
|
72889
72928
|
const exportPattern = new RegExp(`\\bexport\\s+(?:function|class|const|type|interface)\\s+${name2}\\b`);
|
|
72890
72929
|
if (exportPattern.test(text)) {
|
|
@@ -72967,7 +73006,7 @@ Review before proceeding.`;
|
|
|
72967
73006
|
// src/hooks/steering-consumed.ts
|
|
72968
73007
|
init_bun_compat();
|
|
72969
73008
|
init_utils2();
|
|
72970
|
-
import * as
|
|
73009
|
+
import * as fs49 from "node:fs";
|
|
72971
73010
|
function recordSteeringConsumed(directory, directiveId) {
|
|
72972
73011
|
try {
|
|
72973
73012
|
const eventsPath = validateSwarmPath(directory, "events.jsonl");
|
|
@@ -72976,7 +73015,7 @@ function recordSteeringConsumed(directory, directiveId) {
|
|
|
72976
73015
|
directiveId,
|
|
72977
73016
|
timestamp: new Date().toISOString()
|
|
72978
73017
|
};
|
|
72979
|
-
|
|
73018
|
+
fs49.appendFileSync(eventsPath, `${JSON.stringify(event)}
|
|
72980
73019
|
`, "utf-8");
|
|
72981
73020
|
} catch {}
|
|
72982
73021
|
}
|
|
@@ -73018,15 +73057,15 @@ function createSteeringConsumedHook(directory) {
|
|
|
73018
73057
|
|
|
73019
73058
|
// src/hooks/trajectory-logger.ts
|
|
73020
73059
|
init_manager2();
|
|
73021
|
-
import * as
|
|
73022
|
-
import * as
|
|
73060
|
+
import * as fs51 from "node:fs/promises";
|
|
73061
|
+
import * as path69 from "node:path";
|
|
73023
73062
|
|
|
73024
73063
|
// src/prm/trajectory-store.ts
|
|
73025
73064
|
init_utils2();
|
|
73026
|
-
import * as
|
|
73027
|
-
import * as
|
|
73065
|
+
import * as fs50 from "node:fs/promises";
|
|
73066
|
+
import * as path68 from "node:path";
|
|
73028
73067
|
function getTrajectoryPath(sessionId, directory) {
|
|
73029
|
-
const relativePath =
|
|
73068
|
+
const relativePath = path68.join("trajectories", `${sessionId}.jsonl`);
|
|
73030
73069
|
return validateSwarmPath(directory, relativePath);
|
|
73031
73070
|
}
|
|
73032
73071
|
var _inMemoryTrajectoryCache = new Map;
|
|
@@ -73045,10 +73084,10 @@ async function appendTrajectoryEntry(sessionId, entry, directory, maxLines = 100
|
|
|
73045
73084
|
_inMemoryTrajectoryCache.set(sessionId, cached3);
|
|
73046
73085
|
}
|
|
73047
73086
|
const trajectoryPath = getTrajectoryPath(sessionId, directory);
|
|
73048
|
-
await
|
|
73087
|
+
await fs50.mkdir(path68.dirname(trajectoryPath), { recursive: true });
|
|
73049
73088
|
const line = `${JSON.stringify(entry)}
|
|
73050
73089
|
`;
|
|
73051
|
-
await
|
|
73090
|
+
await fs50.appendFile(trajectoryPath, line, "utf-8");
|
|
73052
73091
|
} catch (err2) {
|
|
73053
73092
|
console.warn(`[trajectory-store] Failed to append trajectory entry: ${err2}`);
|
|
73054
73093
|
}
|
|
@@ -73056,7 +73095,7 @@ async function appendTrajectoryEntry(sessionId, entry, directory, maxLines = 100
|
|
|
73056
73095
|
async function readTrajectory(sessionId, directory) {
|
|
73057
73096
|
try {
|
|
73058
73097
|
const trajectoryPath = getTrajectoryPath(sessionId, directory);
|
|
73059
|
-
const content = await
|
|
73098
|
+
const content = await fs50.readFile(trajectoryPath, "utf-8");
|
|
73060
73099
|
const lines = content.split(`
|
|
73061
73100
|
`).filter((line) => line.trim().length > 0);
|
|
73062
73101
|
const entries = [];
|
|
@@ -73080,15 +73119,15 @@ async function cleanupOldTrajectoryFiles(directory, maxAgeDays = 7) {
|
|
|
73080
73119
|
for (const subdir of ["trajectories", "replays"]) {
|
|
73081
73120
|
try {
|
|
73082
73121
|
const dirPath = validateSwarmPath(directory, subdir);
|
|
73083
|
-
const entries = await
|
|
73122
|
+
const entries = await fs50.readdir(dirPath, { withFileTypes: true });
|
|
73084
73123
|
for (const entry of entries) {
|
|
73085
73124
|
if (!entry.isFile())
|
|
73086
73125
|
continue;
|
|
73087
|
-
const filePath =
|
|
73126
|
+
const filePath = path68.join(dirPath, entry.name);
|
|
73088
73127
|
try {
|
|
73089
|
-
const stat6 = await
|
|
73128
|
+
const stat6 = await fs50.stat(filePath);
|
|
73090
73129
|
if (now - stat6.mtimeMs > cutoffMs) {
|
|
73091
|
-
await
|
|
73130
|
+
await fs50.unlink(filePath);
|
|
73092
73131
|
}
|
|
73093
73132
|
} catch {}
|
|
73094
73133
|
}
|
|
@@ -73138,7 +73177,7 @@ function isSensitiveKey(key) {
|
|
|
73138
73177
|
}
|
|
73139
73178
|
async function truncateTrajectoryFile(filePath, maxLines) {
|
|
73140
73179
|
try {
|
|
73141
|
-
const content = await
|
|
73180
|
+
const content = await fs51.readFile(filePath, "utf-8");
|
|
73142
73181
|
const lines = content.split(`
|
|
73143
73182
|
`).filter((line) => line.trim().length > 0);
|
|
73144
73183
|
if (lines.length <= maxLines) {
|
|
@@ -73146,7 +73185,7 @@ async function truncateTrajectoryFile(filePath, maxLines) {
|
|
|
73146
73185
|
}
|
|
73147
73186
|
const keepCount = Math.floor(maxLines / 2);
|
|
73148
73187
|
const keptLines = lines.slice(-keepCount);
|
|
73149
|
-
await
|
|
73188
|
+
await fs51.writeFile(filePath, `${keptLines.join(`
|
|
73150
73189
|
`)}
|
|
73151
73190
|
`, "utf-8");
|
|
73152
73191
|
} catch {}
|
|
@@ -73276,13 +73315,13 @@ function createTrajectoryLoggerHook(config3, _directory) {
|
|
|
73276
73315
|
elapsed_ms
|
|
73277
73316
|
};
|
|
73278
73317
|
const sanitized = sanitizeTaskId2(taskId);
|
|
73279
|
-
const relativePath =
|
|
73318
|
+
const relativePath = path69.join("evidence", sanitized, "trajectory.jsonl");
|
|
73280
73319
|
const trajectoryPath = validateSwarmPath(_directory, relativePath);
|
|
73281
73320
|
try {
|
|
73282
|
-
await
|
|
73321
|
+
await fs51.mkdir(path69.dirname(trajectoryPath), { recursive: true });
|
|
73283
73322
|
const line = `${JSON.stringify(entry)}
|
|
73284
73323
|
`;
|
|
73285
|
-
await
|
|
73324
|
+
await fs51.appendFile(trajectoryPath, line, "utf-8");
|
|
73286
73325
|
await truncateTrajectoryFile(trajectoryPath, maxLines);
|
|
73287
73326
|
} catch {}
|
|
73288
73327
|
try {
|
|
@@ -73829,17 +73868,17 @@ init_state();
|
|
|
73829
73868
|
init_telemetry();
|
|
73830
73869
|
|
|
73831
73870
|
// src/prm/replay.ts
|
|
73832
|
-
import { promises as
|
|
73833
|
-
import
|
|
73871
|
+
import { promises as fs52 } from "node:fs";
|
|
73872
|
+
import path70 from "node:path";
|
|
73834
73873
|
function isPathSafe2(targetPath, basePath) {
|
|
73835
|
-
const resolvedTarget =
|
|
73836
|
-
const resolvedBase =
|
|
73837
|
-
const rel =
|
|
73838
|
-
return !rel.startsWith("..") && !
|
|
73874
|
+
const resolvedTarget = path70.resolve(targetPath);
|
|
73875
|
+
const resolvedBase = path70.resolve(basePath);
|
|
73876
|
+
const rel = path70.relative(resolvedBase, resolvedTarget);
|
|
73877
|
+
return !rel.startsWith("..") && !path70.isAbsolute(rel);
|
|
73839
73878
|
}
|
|
73840
73879
|
function isWithinReplaysDir(targetPath) {
|
|
73841
|
-
const resolved =
|
|
73842
|
-
const parts2 = resolved.split(
|
|
73880
|
+
const resolved = path70.resolve(targetPath);
|
|
73881
|
+
const parts2 = resolved.split(path70.sep);
|
|
73843
73882
|
for (let i2 = 0;i2 < parts2.length - 1; i2++) {
|
|
73844
73883
|
if (parts2[i2] === ".swarm" && parts2[i2 + 1] === "replays") {
|
|
73845
73884
|
return true;
|
|
@@ -73852,15 +73891,15 @@ function sanitizeFilename(input) {
|
|
|
73852
73891
|
}
|
|
73853
73892
|
async function startReplayRecording(sessionID, directory) {
|
|
73854
73893
|
try {
|
|
73855
|
-
const replayDir =
|
|
73894
|
+
const replayDir = path70.join(directory, ".swarm", "replays");
|
|
73856
73895
|
const safeSessionID = sanitizeFilename(sessionID);
|
|
73857
73896
|
const filename = `${safeSessionID}-${Date.now()}.jsonl`;
|
|
73858
|
-
const filepath =
|
|
73897
|
+
const filepath = path70.join(replayDir, filename);
|
|
73859
73898
|
if (!isPathSafe2(filepath, replayDir)) {
|
|
73860
73899
|
console.warn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
|
|
73861
73900
|
return null;
|
|
73862
73901
|
}
|
|
73863
|
-
await
|
|
73902
|
+
await fs52.mkdir(replayDir, { recursive: true });
|
|
73864
73903
|
return filepath;
|
|
73865
73904
|
} catch (err2) {
|
|
73866
73905
|
console.warn(`[replay] Failed to start recording for session ${sessionID}: ${err2}`);
|
|
@@ -73880,7 +73919,7 @@ async function recordReplayEntry(artifactPath, sessionID, entry) {
|
|
|
73880
73919
|
};
|
|
73881
73920
|
const line = `${JSON.stringify(fullEntry)}
|
|
73882
73921
|
`;
|
|
73883
|
-
await
|
|
73922
|
+
await fs52.appendFile(artifactPath, line, "utf-8");
|
|
73884
73923
|
} catch (err2) {
|
|
73885
73924
|
console.warn(`[replay] Failed to record entry: ${err2}`);
|
|
73886
73925
|
}
|
|
@@ -74228,8 +74267,8 @@ init_telemetry();
|
|
|
74228
74267
|
// src/tools/batch-symbols.ts
|
|
74229
74268
|
init_dist();
|
|
74230
74269
|
init_create_tool();
|
|
74231
|
-
import * as
|
|
74232
|
-
import * as
|
|
74270
|
+
import * as fs53 from "node:fs";
|
|
74271
|
+
import * as path71 from "node:path";
|
|
74233
74272
|
init_path_security();
|
|
74234
74273
|
var WINDOWS_RESERVED_NAMES2 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
74235
74274
|
function containsWindowsAttacks2(str) {
|
|
@@ -74246,14 +74285,14 @@ function containsWindowsAttacks2(str) {
|
|
|
74246
74285
|
}
|
|
74247
74286
|
function isPathInWorkspace2(filePath, workspace) {
|
|
74248
74287
|
try {
|
|
74249
|
-
const resolvedPath =
|
|
74250
|
-
if (!
|
|
74288
|
+
const resolvedPath = path71.resolve(workspace, filePath);
|
|
74289
|
+
if (!fs53.existsSync(resolvedPath)) {
|
|
74251
74290
|
return true;
|
|
74252
74291
|
}
|
|
74253
|
-
const realWorkspace =
|
|
74254
|
-
const realResolvedPath =
|
|
74255
|
-
const relativePath =
|
|
74256
|
-
if (relativePath.startsWith("..") ||
|
|
74292
|
+
const realWorkspace = fs53.realpathSync(workspace);
|
|
74293
|
+
const realResolvedPath = fs53.realpathSync(resolvedPath);
|
|
74294
|
+
const relativePath = path71.relative(realWorkspace, realResolvedPath);
|
|
74295
|
+
if (relativePath.startsWith("..") || path71.isAbsolute(relativePath)) {
|
|
74257
74296
|
return false;
|
|
74258
74297
|
}
|
|
74259
74298
|
return true;
|
|
@@ -74262,7 +74301,7 @@ function isPathInWorkspace2(filePath, workspace) {
|
|
|
74262
74301
|
}
|
|
74263
74302
|
}
|
|
74264
74303
|
function processFile2(file3, cwd, exportedOnly) {
|
|
74265
|
-
const ext =
|
|
74304
|
+
const ext = path71.extname(file3);
|
|
74266
74305
|
if (containsControlChars(file3)) {
|
|
74267
74306
|
return {
|
|
74268
74307
|
file: file3,
|
|
@@ -74295,8 +74334,8 @@ function processFile2(file3, cwd, exportedOnly) {
|
|
|
74295
74334
|
errorType: "path-outside-workspace"
|
|
74296
74335
|
};
|
|
74297
74336
|
}
|
|
74298
|
-
const fullPath =
|
|
74299
|
-
if (!
|
|
74337
|
+
const fullPath = path71.join(cwd, file3);
|
|
74338
|
+
if (!fs53.existsSync(fullPath)) {
|
|
74300
74339
|
return {
|
|
74301
74340
|
file: file3,
|
|
74302
74341
|
success: false,
|
|
@@ -74327,14 +74366,14 @@ function processFile2(file3, cwd, exportedOnly) {
|
|
|
74327
74366
|
}
|
|
74328
74367
|
let isEmptyFile = false;
|
|
74329
74368
|
try {
|
|
74330
|
-
const stats =
|
|
74369
|
+
const stats = fs53.statSync(fullPath);
|
|
74331
74370
|
if (stats.size === 0) {
|
|
74332
74371
|
isEmptyFile = true;
|
|
74333
74372
|
}
|
|
74334
74373
|
} catch {}
|
|
74335
74374
|
if (syms.length === 0) {
|
|
74336
74375
|
try {
|
|
74337
|
-
const content =
|
|
74376
|
+
const content = fs53.readFileSync(fullPath, "utf-8");
|
|
74338
74377
|
if (content.trim().length === 0) {
|
|
74339
74378
|
isEmptyFile = true;
|
|
74340
74379
|
}
|
|
@@ -74586,25 +74625,25 @@ init_manager2();
|
|
|
74586
74625
|
init_task_id();
|
|
74587
74626
|
init_create_tool();
|
|
74588
74627
|
init_resolve_working_directory();
|
|
74589
|
-
import * as
|
|
74590
|
-
import * as
|
|
74628
|
+
import * as fs54 from "node:fs";
|
|
74629
|
+
import * as path72 from "node:path";
|
|
74591
74630
|
var EVIDENCE_DIR = ".swarm/evidence";
|
|
74592
74631
|
function isValidTaskId3(taskId) {
|
|
74593
74632
|
return isStrictTaskId(taskId);
|
|
74594
74633
|
}
|
|
74595
74634
|
function isPathWithinSwarm(filePath, workspaceRoot) {
|
|
74596
|
-
const normalizedWorkspace =
|
|
74597
|
-
const swarmPath =
|
|
74598
|
-
const normalizedPath =
|
|
74635
|
+
const normalizedWorkspace = path72.resolve(workspaceRoot);
|
|
74636
|
+
const swarmPath = path72.join(normalizedWorkspace, ".swarm", "evidence");
|
|
74637
|
+
const normalizedPath = path72.resolve(filePath);
|
|
74599
74638
|
return normalizedPath.startsWith(swarmPath);
|
|
74600
74639
|
}
|
|
74601
74640
|
function readEvidenceFile(evidencePath) {
|
|
74602
|
-
if (!
|
|
74641
|
+
if (!fs54.existsSync(evidencePath)) {
|
|
74603
74642
|
return null;
|
|
74604
74643
|
}
|
|
74605
74644
|
let content;
|
|
74606
74645
|
try {
|
|
74607
|
-
content =
|
|
74646
|
+
content = fs54.readFileSync(evidencePath, "utf-8");
|
|
74608
74647
|
} catch {
|
|
74609
74648
|
return null;
|
|
74610
74649
|
}
|
|
@@ -74676,7 +74715,7 @@ var check_gate_status = createSwarmTool({
|
|
|
74676
74715
|
};
|
|
74677
74716
|
return JSON.stringify(errorResult, null, 2);
|
|
74678
74717
|
}
|
|
74679
|
-
const evidencePath =
|
|
74718
|
+
const evidencePath = path72.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
|
|
74680
74719
|
if (!isPathWithinSwarm(evidencePath, directory)) {
|
|
74681
74720
|
const errorResult = {
|
|
74682
74721
|
taskId: taskIdInput,
|
|
@@ -74772,8 +74811,8 @@ init_utils2();
|
|
|
74772
74811
|
init_state();
|
|
74773
74812
|
init_create_tool();
|
|
74774
74813
|
init_resolve_working_directory();
|
|
74775
|
-
import * as
|
|
74776
|
-
import * as
|
|
74814
|
+
import * as fs55 from "node:fs";
|
|
74815
|
+
import * as path73 from "node:path";
|
|
74777
74816
|
function extractMatches(regex, text) {
|
|
74778
74817
|
return Array.from(text.matchAll(regex));
|
|
74779
74818
|
}
|
|
@@ -74867,7 +74906,7 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
74867
74906
|
let plan;
|
|
74868
74907
|
try {
|
|
74869
74908
|
const planPath = validateSwarmPath(directory, "plan.json");
|
|
74870
|
-
const planRaw =
|
|
74909
|
+
const planRaw = fs55.readFileSync(planPath, "utf-8");
|
|
74871
74910
|
plan = JSON.parse(planRaw);
|
|
74872
74911
|
} catch {
|
|
74873
74912
|
const result2 = {
|
|
@@ -74925,10 +74964,10 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
74925
74964
|
let hasFileReadFailure = false;
|
|
74926
74965
|
for (const filePath of fileTargets) {
|
|
74927
74966
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
74928
|
-
const resolvedPath =
|
|
74929
|
-
const projectRoot =
|
|
74930
|
-
const relative16 =
|
|
74931
|
-
const withinProject = relative16 === "" || !relative16.startsWith("..") && !
|
|
74967
|
+
const resolvedPath = path73.resolve(directory, normalizedPath);
|
|
74968
|
+
const projectRoot = path73.resolve(directory);
|
|
74969
|
+
const relative16 = path73.relative(projectRoot, resolvedPath);
|
|
74970
|
+
const withinProject = relative16 === "" || !relative16.startsWith("..") && !path73.isAbsolute(relative16);
|
|
74932
74971
|
if (!withinProject) {
|
|
74933
74972
|
blockedTasks.push({
|
|
74934
74973
|
task_id: task.id,
|
|
@@ -74941,7 +74980,7 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
74941
74980
|
}
|
|
74942
74981
|
let fileContent;
|
|
74943
74982
|
try {
|
|
74944
|
-
fileContent =
|
|
74983
|
+
fileContent = fs55.readFileSync(resolvedPath, "utf-8");
|
|
74945
74984
|
} catch {
|
|
74946
74985
|
blockedTasks.push({
|
|
74947
74986
|
task_id: task.id,
|
|
@@ -74983,9 +75022,9 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
74983
75022
|
blockedTasks
|
|
74984
75023
|
};
|
|
74985
75024
|
try {
|
|
74986
|
-
const evidenceDir =
|
|
74987
|
-
const evidencePath =
|
|
74988
|
-
|
|
75025
|
+
const evidenceDir = path73.join(directory, ".swarm", "evidence", `${phase}`);
|
|
75026
|
+
const evidencePath = path73.join(evidenceDir, "completion-verify.json");
|
|
75027
|
+
fs55.mkdirSync(evidenceDir, { recursive: true });
|
|
74989
75028
|
const evidenceBundle = {
|
|
74990
75029
|
schema_version: "1.0.0",
|
|
74991
75030
|
task_id: "completion-verify",
|
|
@@ -75006,7 +75045,7 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
75006
75045
|
}
|
|
75007
75046
|
]
|
|
75008
75047
|
};
|
|
75009
|
-
|
|
75048
|
+
fs55.writeFileSync(evidencePath, JSON.stringify(evidenceBundle, null, 2), "utf-8");
|
|
75010
75049
|
} catch {}
|
|
75011
75050
|
return JSON.stringify(result, null, 2);
|
|
75012
75051
|
}
|
|
@@ -75060,12 +75099,12 @@ var completion_verify = createSwarmTool({
|
|
|
75060
75099
|
});
|
|
75061
75100
|
// src/tools/complexity-hotspots.ts
|
|
75062
75101
|
init_zod();
|
|
75063
|
-
import * as
|
|
75064
|
-
import * as
|
|
75102
|
+
import * as fs57 from "node:fs";
|
|
75103
|
+
import * as path75 from "node:path";
|
|
75065
75104
|
|
|
75066
75105
|
// src/quality/metrics.ts
|
|
75067
|
-
import * as
|
|
75068
|
-
import * as
|
|
75106
|
+
import * as fs56 from "node:fs";
|
|
75107
|
+
import * as path74 from "node:path";
|
|
75069
75108
|
var MAX_FILE_SIZE_BYTES4 = 256 * 1024;
|
|
75070
75109
|
var MIN_DUPLICATION_LINES = 10;
|
|
75071
75110
|
function estimateCyclomaticComplexity(content) {
|
|
@@ -75103,11 +75142,11 @@ function estimateCyclomaticComplexity(content) {
|
|
|
75103
75142
|
}
|
|
75104
75143
|
function getComplexityForFile(filePath) {
|
|
75105
75144
|
try {
|
|
75106
|
-
const stat6 =
|
|
75145
|
+
const stat6 = fs56.statSync(filePath);
|
|
75107
75146
|
if (stat6.size > MAX_FILE_SIZE_BYTES4) {
|
|
75108
75147
|
return null;
|
|
75109
75148
|
}
|
|
75110
|
-
const content =
|
|
75149
|
+
const content = fs56.readFileSync(filePath, "utf-8");
|
|
75111
75150
|
return estimateCyclomaticComplexity(content);
|
|
75112
75151
|
} catch {
|
|
75113
75152
|
return null;
|
|
@@ -75117,8 +75156,8 @@ async function computeComplexityDelta(files, workingDir) {
|
|
|
75117
75156
|
let totalComplexity = 0;
|
|
75118
75157
|
const analyzedFiles = [];
|
|
75119
75158
|
for (const file3 of files) {
|
|
75120
|
-
const fullPath =
|
|
75121
|
-
if (!
|
|
75159
|
+
const fullPath = path74.isAbsolute(file3) ? file3 : path74.join(workingDir, file3);
|
|
75160
|
+
if (!fs56.existsSync(fullPath)) {
|
|
75122
75161
|
continue;
|
|
75123
75162
|
}
|
|
75124
75163
|
const complexity = getComplexityForFile(fullPath);
|
|
@@ -75239,8 +75278,8 @@ function countGoExports(content) {
|
|
|
75239
75278
|
}
|
|
75240
75279
|
function getExportCountForFile(filePath) {
|
|
75241
75280
|
try {
|
|
75242
|
-
const content =
|
|
75243
|
-
const ext =
|
|
75281
|
+
const content = fs56.readFileSync(filePath, "utf-8");
|
|
75282
|
+
const ext = path74.extname(filePath).toLowerCase();
|
|
75244
75283
|
switch (ext) {
|
|
75245
75284
|
case ".ts":
|
|
75246
75285
|
case ".tsx":
|
|
@@ -75266,8 +75305,8 @@ async function computePublicApiDelta(files, workingDir) {
|
|
|
75266
75305
|
let totalExports = 0;
|
|
75267
75306
|
const analyzedFiles = [];
|
|
75268
75307
|
for (const file3 of files) {
|
|
75269
|
-
const fullPath =
|
|
75270
|
-
if (!
|
|
75308
|
+
const fullPath = path74.isAbsolute(file3) ? file3 : path74.join(workingDir, file3);
|
|
75309
|
+
if (!fs56.existsSync(fullPath)) {
|
|
75271
75310
|
continue;
|
|
75272
75311
|
}
|
|
75273
75312
|
const exports = getExportCountForFile(fullPath);
|
|
@@ -75300,16 +75339,16 @@ async function computeDuplicationRatio(files, workingDir) {
|
|
|
75300
75339
|
let duplicateLines = 0;
|
|
75301
75340
|
const analyzedFiles = [];
|
|
75302
75341
|
for (const file3 of files) {
|
|
75303
|
-
const fullPath =
|
|
75304
|
-
if (!
|
|
75342
|
+
const fullPath = path74.isAbsolute(file3) ? file3 : path74.join(workingDir, file3);
|
|
75343
|
+
if (!fs56.existsSync(fullPath)) {
|
|
75305
75344
|
continue;
|
|
75306
75345
|
}
|
|
75307
75346
|
try {
|
|
75308
|
-
const stat6 =
|
|
75347
|
+
const stat6 = fs56.statSync(fullPath);
|
|
75309
75348
|
if (stat6.size > MAX_FILE_SIZE_BYTES4) {
|
|
75310
75349
|
continue;
|
|
75311
75350
|
}
|
|
75312
|
-
const content =
|
|
75351
|
+
const content = fs56.readFileSync(fullPath, "utf-8");
|
|
75313
75352
|
const lines = content.split(`
|
|
75314
75353
|
`).filter((line) => line.trim().length > 0);
|
|
75315
75354
|
if (lines.length < MIN_DUPLICATION_LINES) {
|
|
@@ -75333,8 +75372,8 @@ function countCodeLines(content) {
|
|
|
75333
75372
|
return lines.length;
|
|
75334
75373
|
}
|
|
75335
75374
|
function isTestFile(filePath) {
|
|
75336
|
-
const basename11 =
|
|
75337
|
-
const _ext =
|
|
75375
|
+
const basename11 = path74.basename(filePath);
|
|
75376
|
+
const _ext = path74.extname(filePath).toLowerCase();
|
|
75338
75377
|
const testPatterns = [
|
|
75339
75378
|
".test.",
|
|
75340
75379
|
".spec.",
|
|
@@ -75415,8 +75454,8 @@ function matchGlobSegment(globSegments, pathSegments) {
|
|
|
75415
75454
|
}
|
|
75416
75455
|
return gIndex === globSegments.length && pIndex === pathSegments.length;
|
|
75417
75456
|
}
|
|
75418
|
-
function matchesGlobSegment(
|
|
75419
|
-
const normalizedPath =
|
|
75457
|
+
function matchesGlobSegment(path75, glob) {
|
|
75458
|
+
const normalizedPath = path75.replace(/\\/g, "/");
|
|
75420
75459
|
const normalizedGlob = glob.replace(/\\/g, "/");
|
|
75421
75460
|
if (normalizedPath.includes("//")) {
|
|
75422
75461
|
return false;
|
|
@@ -75447,8 +75486,8 @@ function simpleGlobToRegex2(glob) {
|
|
|
75447
75486
|
function hasGlobstar(glob) {
|
|
75448
75487
|
return glob.includes("**");
|
|
75449
75488
|
}
|
|
75450
|
-
function globMatches(
|
|
75451
|
-
const normalizedPath =
|
|
75489
|
+
function globMatches(path75, glob) {
|
|
75490
|
+
const normalizedPath = path75.replace(/\\/g, "/");
|
|
75452
75491
|
if (!glob || glob === "") {
|
|
75453
75492
|
if (normalizedPath.includes("//")) {
|
|
75454
75493
|
return false;
|
|
@@ -75484,31 +75523,31 @@ function shouldExcludeFile(filePath, excludeGlobs) {
|
|
|
75484
75523
|
async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
75485
75524
|
let testLines = 0;
|
|
75486
75525
|
let codeLines = 0;
|
|
75487
|
-
const srcDir =
|
|
75488
|
-
if (
|
|
75526
|
+
const srcDir = path74.join(workingDir, "src");
|
|
75527
|
+
if (fs56.existsSync(srcDir)) {
|
|
75489
75528
|
await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
75490
75529
|
codeLines += lines;
|
|
75491
75530
|
});
|
|
75492
75531
|
}
|
|
75493
75532
|
const possibleSrcDirs = ["lib", "app", "source", "core"];
|
|
75494
75533
|
for (const dir of possibleSrcDirs) {
|
|
75495
|
-
const dirPath =
|
|
75496
|
-
if (
|
|
75534
|
+
const dirPath = path74.join(workingDir, dir);
|
|
75535
|
+
if (fs56.existsSync(dirPath)) {
|
|
75497
75536
|
await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
75498
75537
|
codeLines += lines;
|
|
75499
75538
|
});
|
|
75500
75539
|
}
|
|
75501
75540
|
}
|
|
75502
|
-
const testsDir =
|
|
75503
|
-
if (
|
|
75541
|
+
const testsDir = path74.join(workingDir, "tests");
|
|
75542
|
+
if (fs56.existsSync(testsDir)) {
|
|
75504
75543
|
await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
75505
75544
|
testLines += lines;
|
|
75506
75545
|
});
|
|
75507
75546
|
}
|
|
75508
75547
|
const possibleTestDirs = ["test", "__tests__", "specs"];
|
|
75509
75548
|
for (const dir of possibleTestDirs) {
|
|
75510
|
-
const dirPath =
|
|
75511
|
-
if (
|
|
75549
|
+
const dirPath = path74.join(workingDir, dir);
|
|
75550
|
+
if (fs56.existsSync(dirPath) && dirPath !== testsDir) {
|
|
75512
75551
|
await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
75513
75552
|
testLines += lines;
|
|
75514
75553
|
});
|
|
@@ -75520,9 +75559,9 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
75520
75559
|
}
|
|
75521
75560
|
async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTestScan, callback) {
|
|
75522
75561
|
try {
|
|
75523
|
-
const entries =
|
|
75562
|
+
const entries = fs56.readdirSync(dirPath, { withFileTypes: true });
|
|
75524
75563
|
for (const entry of entries) {
|
|
75525
|
-
const fullPath =
|
|
75564
|
+
const fullPath = path74.join(dirPath, entry.name);
|
|
75526
75565
|
if (entry.isDirectory()) {
|
|
75527
75566
|
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
|
|
75528
75567
|
continue;
|
|
@@ -75530,7 +75569,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
75530
75569
|
await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
|
|
75531
75570
|
} else if (entry.isFile()) {
|
|
75532
75571
|
const relativePath = fullPath.replace(`${dirPath}/`, "");
|
|
75533
|
-
const ext =
|
|
75572
|
+
const ext = path74.extname(entry.name).toLowerCase();
|
|
75534
75573
|
const validExts = [
|
|
75535
75574
|
".ts",
|
|
75536
75575
|
".tsx",
|
|
@@ -75566,7 +75605,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
75566
75605
|
continue;
|
|
75567
75606
|
}
|
|
75568
75607
|
try {
|
|
75569
|
-
const content =
|
|
75608
|
+
const content = fs56.readFileSync(fullPath, "utf-8");
|
|
75570
75609
|
const lines = countCodeLines(content);
|
|
75571
75610
|
callback(lines);
|
|
75572
75611
|
} catch {}
|
|
@@ -75766,11 +75805,11 @@ async function getGitChurn(days, directory) {
|
|
|
75766
75805
|
}
|
|
75767
75806
|
function getComplexityForFile2(filePath) {
|
|
75768
75807
|
try {
|
|
75769
|
-
const stat6 =
|
|
75808
|
+
const stat6 = fs57.statSync(filePath);
|
|
75770
75809
|
if (stat6.size > MAX_FILE_SIZE_BYTES5) {
|
|
75771
75810
|
return null;
|
|
75772
75811
|
}
|
|
75773
|
-
const content =
|
|
75812
|
+
const content = fs57.readFileSync(filePath, "utf-8");
|
|
75774
75813
|
return estimateCyclomaticComplexity(content);
|
|
75775
75814
|
} catch {
|
|
75776
75815
|
return null;
|
|
@@ -75781,7 +75820,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
75781
75820
|
const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
|
|
75782
75821
|
const filteredChurn = new Map;
|
|
75783
75822
|
for (const [file3, count] of churnMap) {
|
|
75784
|
-
const ext =
|
|
75823
|
+
const ext = path75.extname(file3).toLowerCase();
|
|
75785
75824
|
if (extSet.has(ext)) {
|
|
75786
75825
|
filteredChurn.set(file3, count);
|
|
75787
75826
|
}
|
|
@@ -75791,8 +75830,8 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
75791
75830
|
let analyzedFiles = 0;
|
|
75792
75831
|
for (const [file3, churnCount] of filteredChurn) {
|
|
75793
75832
|
let fullPath = file3;
|
|
75794
|
-
if (!
|
|
75795
|
-
fullPath =
|
|
75833
|
+
if (!fs57.existsSync(fullPath)) {
|
|
75834
|
+
fullPath = path75.join(cwd, file3);
|
|
75796
75835
|
}
|
|
75797
75836
|
const complexity = getComplexityForFile2(fullPath);
|
|
75798
75837
|
if (complexity !== null) {
|
|
@@ -75961,12 +76000,12 @@ ${body2}`);
|
|
|
75961
76000
|
// src/council/council-evidence-writer.ts
|
|
75962
76001
|
import {
|
|
75963
76002
|
appendFileSync as appendFileSync6,
|
|
75964
|
-
existsSync as
|
|
75965
|
-
mkdirSync as
|
|
76003
|
+
existsSync as existsSync38,
|
|
76004
|
+
mkdirSync as mkdirSync19,
|
|
75966
76005
|
readFileSync as readFileSync36,
|
|
75967
|
-
writeFileSync as
|
|
76006
|
+
writeFileSync as writeFileSync12
|
|
75968
76007
|
} from "node:fs";
|
|
75969
|
-
import { join as
|
|
76008
|
+
import { join as join69 } from "node:path";
|
|
75970
76009
|
var EVIDENCE_DIR2 = ".swarm/evidence";
|
|
75971
76010
|
var VALID_TASK_ID = /^\d+\.\d+(\.\d+)*$/;
|
|
75972
76011
|
var COUNCIL_GATE_NAME = "council";
|
|
@@ -76000,11 +76039,11 @@ function writeCouncilEvidence(workingDir, synthesis) {
|
|
|
76000
76039
|
if (!VALID_TASK_ID.test(synthesis.taskId)) {
|
|
76001
76040
|
throw new Error(`writeCouncilEvidence: invalid taskId "${synthesis.taskId}" — must match N.M or N.M.P format`);
|
|
76002
76041
|
}
|
|
76003
|
-
const dir =
|
|
76004
|
-
|
|
76005
|
-
const filePath =
|
|
76042
|
+
const dir = join69(workingDir, EVIDENCE_DIR2);
|
|
76043
|
+
mkdirSync19(dir, { recursive: true });
|
|
76044
|
+
const filePath = join69(dir, `${synthesis.taskId}.json`);
|
|
76006
76045
|
const existingRoot = Object.create(null);
|
|
76007
|
-
if (
|
|
76046
|
+
if (existsSync38(filePath)) {
|
|
76008
76047
|
try {
|
|
76009
76048
|
const parsed = JSON.parse(readFileSync36(filePath, "utf-8"));
|
|
76010
76049
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
@@ -76034,17 +76073,17 @@ function writeCouncilEvidence(workingDir, synthesis) {
|
|
|
76034
76073
|
updated.taskId = synthesis.taskId;
|
|
76035
76074
|
if (!Array.isArray(updated.required_gates))
|
|
76036
76075
|
updated.required_gates = [];
|
|
76037
|
-
|
|
76076
|
+
writeFileSync12(filePath, JSON.stringify(updated, null, 2));
|
|
76038
76077
|
try {
|
|
76039
|
-
const councilDir =
|
|
76040
|
-
|
|
76078
|
+
const councilDir = join69(workingDir, ".swarm", "council");
|
|
76079
|
+
mkdirSync19(councilDir, { recursive: true });
|
|
76041
76080
|
const auditLine = JSON.stringify({
|
|
76042
76081
|
round: synthesis.roundNumber,
|
|
76043
76082
|
verdict: synthesis.overallVerdict,
|
|
76044
76083
|
timestamp: synthesis.timestamp,
|
|
76045
76084
|
vetoedBy: synthesis.vetoedBy
|
|
76046
76085
|
});
|
|
76047
|
-
appendFileSync6(
|
|
76086
|
+
appendFileSync6(join69(councilDir, `${synthesis.taskId}.rounds.jsonl`), `${auditLine}
|
|
76048
76087
|
`);
|
|
76049
76088
|
} catch (auditError) {
|
|
76050
76089
|
console.warn(`writeCouncilEvidence: failed to append round-history audit log: ${auditError instanceof Error ? auditError.message : String(auditError)}`);
|
|
@@ -76177,22 +76216,22 @@ function buildUnifiedFeedback(taskId, verdict, vetoedBy, requiredFixes, advisory
|
|
|
76177
76216
|
}
|
|
76178
76217
|
|
|
76179
76218
|
// src/council/criteria-store.ts
|
|
76180
|
-
import { existsSync as
|
|
76181
|
-
import { join as
|
|
76219
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync20, readFileSync as readFileSync37, writeFileSync as writeFileSync13 } from "node:fs";
|
|
76220
|
+
import { join as join70 } from "node:path";
|
|
76182
76221
|
var COUNCIL_DIR = ".swarm/council";
|
|
76183
76222
|
function writeCriteria(workingDir, taskId, criteria) {
|
|
76184
|
-
const dir =
|
|
76185
|
-
|
|
76223
|
+
const dir = join70(workingDir, COUNCIL_DIR);
|
|
76224
|
+
mkdirSync20(dir, { recursive: true });
|
|
76186
76225
|
const payload = {
|
|
76187
76226
|
taskId,
|
|
76188
76227
|
criteria,
|
|
76189
76228
|
declaredAt: new Date().toISOString()
|
|
76190
76229
|
};
|
|
76191
|
-
|
|
76230
|
+
writeFileSync13(join70(dir, `${safeId(taskId)}.json`), JSON.stringify(payload, null, 2));
|
|
76192
76231
|
}
|
|
76193
76232
|
function readCriteria(workingDir, taskId) {
|
|
76194
|
-
const filePath =
|
|
76195
|
-
if (!
|
|
76233
|
+
const filePath = join70(workingDir, COUNCIL_DIR, `${safeId(taskId)}.json`);
|
|
76234
|
+
if (!existsSync39(filePath))
|
|
76196
76235
|
return null;
|
|
76197
76236
|
try {
|
|
76198
76237
|
const parsed = JSON.parse(readFileSync37(filePath, "utf-8"));
|
|
@@ -76343,8 +76382,8 @@ var submit_council_verdicts = createSwarmTool({
|
|
|
76343
76382
|
// src/tools/convene-general-council.ts
|
|
76344
76383
|
init_zod();
|
|
76345
76384
|
init_loader();
|
|
76346
|
-
import * as
|
|
76347
|
-
import * as
|
|
76385
|
+
import * as fs58 from "node:fs";
|
|
76386
|
+
import * as path76 from "node:path";
|
|
76348
76387
|
|
|
76349
76388
|
// src/council/general-council-advisory.ts
|
|
76350
76389
|
var ADVISORY_HEADER = "[general_council] (advisory; not blocking)";
|
|
@@ -76772,13 +76811,13 @@ var convene_general_council = createSwarmTool({
|
|
|
76772
76811
|
const round1 = input.round1Responses;
|
|
76773
76812
|
const round2 = input.round2Responses ?? [];
|
|
76774
76813
|
const result = synthesizeGeneralCouncil(input.question, input.mode, round1, round2);
|
|
76775
|
-
const evidenceDir =
|
|
76814
|
+
const evidenceDir = path76.join(workingDir, ".swarm", "council", "general");
|
|
76776
76815
|
const safeTimestamp = result.timestamp.replace(/[:.]/g, "-");
|
|
76777
76816
|
const evidenceFile = `${safeTimestamp}-${input.mode}.json`;
|
|
76778
|
-
const evidencePath =
|
|
76817
|
+
const evidencePath = path76.join(evidenceDir, evidenceFile);
|
|
76779
76818
|
try {
|
|
76780
|
-
await
|
|
76781
|
-
await
|
|
76819
|
+
await fs58.promises.mkdir(evidenceDir, { recursive: true });
|
|
76820
|
+
await fs58.promises.writeFile(evidencePath, JSON.stringify(result, null, 2));
|
|
76782
76821
|
} catch (err2) {
|
|
76783
76822
|
const message = err2 instanceof Error ? err2.message : String(err2);
|
|
76784
76823
|
console.warn(`[convene_general_council] Failed to write evidence to ${evidencePath}: ${message}`);
|
|
@@ -77009,8 +77048,8 @@ init_scope_persistence();
|
|
|
77009
77048
|
init_state();
|
|
77010
77049
|
init_task_id();
|
|
77011
77050
|
init_create_tool();
|
|
77012
|
-
import * as
|
|
77013
|
-
import * as
|
|
77051
|
+
import * as fs59 from "node:fs";
|
|
77052
|
+
import * as path77 from "node:path";
|
|
77014
77053
|
function validateTaskIdFormat2(taskId) {
|
|
77015
77054
|
return validateTaskIdFormat(taskId);
|
|
77016
77055
|
}
|
|
@@ -77084,8 +77123,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
77084
77123
|
};
|
|
77085
77124
|
}
|
|
77086
77125
|
}
|
|
77087
|
-
normalizedDir =
|
|
77088
|
-
const pathParts = normalizedDir.split(
|
|
77126
|
+
normalizedDir = path77.normalize(args2.working_directory);
|
|
77127
|
+
const pathParts = normalizedDir.split(path77.sep);
|
|
77089
77128
|
if (pathParts.includes("..")) {
|
|
77090
77129
|
return {
|
|
77091
77130
|
success: false,
|
|
@@ -77095,11 +77134,11 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
77095
77134
|
]
|
|
77096
77135
|
};
|
|
77097
77136
|
}
|
|
77098
|
-
const resolvedDir =
|
|
77137
|
+
const resolvedDir = path77.resolve(normalizedDir);
|
|
77099
77138
|
try {
|
|
77100
|
-
const realPath =
|
|
77101
|
-
const planPath2 =
|
|
77102
|
-
if (!
|
|
77139
|
+
const realPath = fs59.realpathSync(resolvedDir);
|
|
77140
|
+
const planPath2 = path77.join(realPath, ".swarm", "plan.json");
|
|
77141
|
+
if (!fs59.existsSync(planPath2)) {
|
|
77103
77142
|
return {
|
|
77104
77143
|
success: false,
|
|
77105
77144
|
message: `Invalid working_directory: plan not found in "${realPath}"`,
|
|
@@ -77122,8 +77161,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
77122
77161
|
console.warn("[declare-scope] fallbackDir is undefined, falling back to process.cwd()");
|
|
77123
77162
|
}
|
|
77124
77163
|
const directory = normalizedDir || fallbackDir;
|
|
77125
|
-
const planPath =
|
|
77126
|
-
if (!
|
|
77164
|
+
const planPath = path77.resolve(directory, ".swarm", "plan.json");
|
|
77165
|
+
if (!fs59.existsSync(planPath)) {
|
|
77127
77166
|
return {
|
|
77128
77167
|
success: false,
|
|
77129
77168
|
message: "No plan found",
|
|
@@ -77132,7 +77171,7 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
77132
77171
|
}
|
|
77133
77172
|
let planContent;
|
|
77134
77173
|
try {
|
|
77135
|
-
planContent = JSON.parse(
|
|
77174
|
+
planContent = JSON.parse(fs59.readFileSync(planPath, "utf-8"));
|
|
77136
77175
|
} catch {
|
|
77137
77176
|
return {
|
|
77138
77177
|
success: false,
|
|
@@ -77162,8 +77201,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
77162
77201
|
const normalizeErrors = [];
|
|
77163
77202
|
const dir = normalizedDir || fallbackDir || process.cwd();
|
|
77164
77203
|
const mergedFiles = rawMergedFiles.map((file3) => {
|
|
77165
|
-
if (
|
|
77166
|
-
const relativePath =
|
|
77204
|
+
if (path77.isAbsolute(file3)) {
|
|
77205
|
+
const relativePath = path77.relative(dir, file3).replace(/\\/g, "/");
|
|
77167
77206
|
if (relativePath.startsWith("..")) {
|
|
77168
77207
|
normalizeErrors.push(`Path '${file3}' resolves outside the project directory`);
|
|
77169
77208
|
return file3;
|
|
@@ -77223,8 +77262,8 @@ var declare_scope = createSwarmTool({
|
|
|
77223
77262
|
// src/tools/diff.ts
|
|
77224
77263
|
init_zod();
|
|
77225
77264
|
import * as child_process7 from "node:child_process";
|
|
77226
|
-
import * as
|
|
77227
|
-
import * as
|
|
77265
|
+
import * as fs60 from "node:fs";
|
|
77266
|
+
import * as path78 from "node:path";
|
|
77228
77267
|
init_create_tool();
|
|
77229
77268
|
var MAX_DIFF_LINES = 500;
|
|
77230
77269
|
var DIFF_TIMEOUT_MS = 30000;
|
|
@@ -77253,20 +77292,20 @@ function validateBase(base) {
|
|
|
77253
77292
|
function validatePaths(paths) {
|
|
77254
77293
|
if (!paths)
|
|
77255
77294
|
return null;
|
|
77256
|
-
for (const
|
|
77257
|
-
if (!
|
|
77295
|
+
for (const path79 of paths) {
|
|
77296
|
+
if (!path79 || path79.length === 0) {
|
|
77258
77297
|
return "empty path not allowed";
|
|
77259
77298
|
}
|
|
77260
|
-
if (
|
|
77299
|
+
if (path79.length > MAX_PATH_LENGTH) {
|
|
77261
77300
|
return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
|
|
77262
77301
|
}
|
|
77263
|
-
if (SHELL_METACHARACTERS2.test(
|
|
77302
|
+
if (SHELL_METACHARACTERS2.test(path79)) {
|
|
77264
77303
|
return "path contains shell metacharacters";
|
|
77265
77304
|
}
|
|
77266
|
-
if (
|
|
77305
|
+
if (path79.startsWith("-")) {
|
|
77267
77306
|
return 'path cannot start with "-" (option-like arguments not allowed)';
|
|
77268
77307
|
}
|
|
77269
|
-
if (CONTROL_CHAR_PATTERN2.test(
|
|
77308
|
+
if (CONTROL_CHAR_PATTERN2.test(path79)) {
|
|
77270
77309
|
return "path contains control characters";
|
|
77271
77310
|
}
|
|
77272
77311
|
}
|
|
@@ -77372,8 +77411,8 @@ var diff = createSwarmTool({
|
|
|
77372
77411
|
if (parts2.length >= 3) {
|
|
77373
77412
|
const additions = parseInt(parts2[0], 10) || 0;
|
|
77374
77413
|
const deletions = parseInt(parts2[1], 10) || 0;
|
|
77375
|
-
const
|
|
77376
|
-
files.push({ path:
|
|
77414
|
+
const path79 = parts2[2];
|
|
77415
|
+
files.push({ path: path79, additions, deletions });
|
|
77377
77416
|
}
|
|
77378
77417
|
}
|
|
77379
77418
|
const contractChanges = [];
|
|
@@ -77413,7 +77452,7 @@ var diff = createSwarmTool({
|
|
|
77413
77452
|
} else if (base === "unstaged") {
|
|
77414
77453
|
const oldRef = `:${file3.path}`;
|
|
77415
77454
|
oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
|
|
77416
|
-
newContent =
|
|
77455
|
+
newContent = fs60.readFileSync(path78.join(directory, file3.path), "utf-8");
|
|
77417
77456
|
} else {
|
|
77418
77457
|
const oldRef = `${base}:${file3.path}`;
|
|
77419
77458
|
oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
|
|
@@ -77487,8 +77526,8 @@ var diff = createSwarmTool({
|
|
|
77487
77526
|
// src/tools/diff-summary.ts
|
|
77488
77527
|
init_zod();
|
|
77489
77528
|
import * as child_process8 from "node:child_process";
|
|
77490
|
-
import * as
|
|
77491
|
-
import * as
|
|
77529
|
+
import * as fs61 from "node:fs";
|
|
77530
|
+
import * as path79 from "node:path";
|
|
77492
77531
|
init_create_tool();
|
|
77493
77532
|
var diff_summary = createSwarmTool({
|
|
77494
77533
|
description: "Generate a filtered semantic diff summary from AST analysis. Returns SemanticDiffSummary with optional filtering by classification or riskLevel.",
|
|
@@ -77536,7 +77575,7 @@ var diff_summary = createSwarmTool({
|
|
|
77536
77575
|
}
|
|
77537
77576
|
try {
|
|
77538
77577
|
let oldContent;
|
|
77539
|
-
const newContent =
|
|
77578
|
+
const newContent = fs61.readFileSync(path79.join(workingDir, filePath), "utf-8");
|
|
77540
77579
|
if (fileExistsInHead) {
|
|
77541
77580
|
oldContent = child_process8.execFileSync("git", ["show", `HEAD:${filePath}`], {
|
|
77542
77581
|
encoding: "utf-8",
|
|
@@ -77764,8 +77803,8 @@ Use these as DOMAIN values when delegating to @sme.`;
|
|
|
77764
77803
|
init_zod();
|
|
77765
77804
|
init_create_tool();
|
|
77766
77805
|
init_path_security();
|
|
77767
|
-
import * as
|
|
77768
|
-
import * as
|
|
77806
|
+
import * as fs62 from "node:fs";
|
|
77807
|
+
import * as path80 from "node:path";
|
|
77769
77808
|
var MAX_FILE_SIZE_BYTES6 = 1024 * 1024;
|
|
77770
77809
|
var MAX_EVIDENCE_FILES = 1000;
|
|
77771
77810
|
var EVIDENCE_DIR3 = ".swarm/evidence";
|
|
@@ -77792,9 +77831,9 @@ function validateRequiredTypes(input) {
|
|
|
77792
77831
|
return null;
|
|
77793
77832
|
}
|
|
77794
77833
|
function isPathWithinSwarm2(filePath, cwd) {
|
|
77795
|
-
const normalizedCwd =
|
|
77796
|
-
const swarmPath =
|
|
77797
|
-
const normalizedPath =
|
|
77834
|
+
const normalizedCwd = path80.resolve(cwd);
|
|
77835
|
+
const swarmPath = path80.join(normalizedCwd, ".swarm");
|
|
77836
|
+
const normalizedPath = path80.resolve(filePath);
|
|
77798
77837
|
return normalizedPath.startsWith(swarmPath);
|
|
77799
77838
|
}
|
|
77800
77839
|
function parseCompletedTasks(planContent) {
|
|
@@ -77810,12 +77849,12 @@ function parseCompletedTasks(planContent) {
|
|
|
77810
77849
|
}
|
|
77811
77850
|
function readEvidenceFiles(evidenceDir, _cwd) {
|
|
77812
77851
|
const evidence = [];
|
|
77813
|
-
if (!
|
|
77852
|
+
if (!fs62.existsSync(evidenceDir) || !fs62.statSync(evidenceDir).isDirectory()) {
|
|
77814
77853
|
return evidence;
|
|
77815
77854
|
}
|
|
77816
77855
|
let files;
|
|
77817
77856
|
try {
|
|
77818
|
-
files =
|
|
77857
|
+
files = fs62.readdirSync(evidenceDir);
|
|
77819
77858
|
} catch {
|
|
77820
77859
|
return evidence;
|
|
77821
77860
|
}
|
|
@@ -77824,14 +77863,14 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
77824
77863
|
if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
|
|
77825
77864
|
continue;
|
|
77826
77865
|
}
|
|
77827
|
-
const filePath =
|
|
77866
|
+
const filePath = path80.join(evidenceDir, filename);
|
|
77828
77867
|
try {
|
|
77829
|
-
const resolvedPath =
|
|
77830
|
-
const evidenceDirResolved =
|
|
77868
|
+
const resolvedPath = path80.resolve(filePath);
|
|
77869
|
+
const evidenceDirResolved = path80.resolve(evidenceDir);
|
|
77831
77870
|
if (!resolvedPath.startsWith(evidenceDirResolved)) {
|
|
77832
77871
|
continue;
|
|
77833
77872
|
}
|
|
77834
|
-
const stat6 =
|
|
77873
|
+
const stat6 = fs62.lstatSync(filePath);
|
|
77835
77874
|
if (!stat6.isFile()) {
|
|
77836
77875
|
continue;
|
|
77837
77876
|
}
|
|
@@ -77840,7 +77879,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
77840
77879
|
}
|
|
77841
77880
|
let fileStat;
|
|
77842
77881
|
try {
|
|
77843
|
-
fileStat =
|
|
77882
|
+
fileStat = fs62.statSync(filePath);
|
|
77844
77883
|
if (fileStat.size > MAX_FILE_SIZE_BYTES6) {
|
|
77845
77884
|
continue;
|
|
77846
77885
|
}
|
|
@@ -77849,7 +77888,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
77849
77888
|
}
|
|
77850
77889
|
let content;
|
|
77851
77890
|
try {
|
|
77852
|
-
content =
|
|
77891
|
+
content = fs62.readFileSync(filePath, "utf-8");
|
|
77853
77892
|
} catch {
|
|
77854
77893
|
continue;
|
|
77855
77894
|
}
|
|
@@ -77945,7 +77984,7 @@ var evidence_check = createSwarmTool({
|
|
|
77945
77984
|
return JSON.stringify(errorResult, null, 2);
|
|
77946
77985
|
}
|
|
77947
77986
|
const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
|
|
77948
|
-
const planPath =
|
|
77987
|
+
const planPath = path80.join(cwd, PLAN_FILE);
|
|
77949
77988
|
if (!isPathWithinSwarm2(planPath, cwd)) {
|
|
77950
77989
|
const errorResult = {
|
|
77951
77990
|
error: "plan file path validation failed",
|
|
@@ -77959,7 +77998,7 @@ var evidence_check = createSwarmTool({
|
|
|
77959
77998
|
}
|
|
77960
77999
|
let planContent;
|
|
77961
78000
|
try {
|
|
77962
|
-
planContent =
|
|
78001
|
+
planContent = fs62.readFileSync(planPath, "utf-8");
|
|
77963
78002
|
} catch {
|
|
77964
78003
|
const result2 = {
|
|
77965
78004
|
message: "No completed tasks found in plan.",
|
|
@@ -77977,7 +78016,7 @@ var evidence_check = createSwarmTool({
|
|
|
77977
78016
|
};
|
|
77978
78017
|
return JSON.stringify(result2, null, 2);
|
|
77979
78018
|
}
|
|
77980
|
-
const evidenceDir =
|
|
78019
|
+
const evidenceDir = path80.join(cwd, EVIDENCE_DIR3);
|
|
77981
78020
|
const evidence = readEvidenceFiles(evidenceDir, cwd);
|
|
77982
78021
|
const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
|
|
77983
78022
|
const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
|
|
@@ -77994,8 +78033,8 @@ var evidence_check = createSwarmTool({
|
|
|
77994
78033
|
// src/tools/file-extractor.ts
|
|
77995
78034
|
init_zod();
|
|
77996
78035
|
init_create_tool();
|
|
77997
|
-
import * as
|
|
77998
|
-
import * as
|
|
78036
|
+
import * as fs63 from "node:fs";
|
|
78037
|
+
import * as path81 from "node:path";
|
|
77999
78038
|
var EXT_MAP = {
|
|
78000
78039
|
python: ".py",
|
|
78001
78040
|
py: ".py",
|
|
@@ -78057,8 +78096,8 @@ var extract_code_blocks = createSwarmTool({
|
|
|
78057
78096
|
execute: async (args2, directory) => {
|
|
78058
78097
|
const { content, output_dir, prefix } = args2;
|
|
78059
78098
|
const targetDir = output_dir || directory;
|
|
78060
|
-
if (!
|
|
78061
|
-
|
|
78099
|
+
if (!fs63.existsSync(targetDir)) {
|
|
78100
|
+
fs63.mkdirSync(targetDir, { recursive: true });
|
|
78062
78101
|
}
|
|
78063
78102
|
if (!content) {
|
|
78064
78103
|
return "Error: content is required";
|
|
@@ -78076,16 +78115,16 @@ var extract_code_blocks = createSwarmTool({
|
|
|
78076
78115
|
if (prefix) {
|
|
78077
78116
|
filename = `${prefix}_${filename}`;
|
|
78078
78117
|
}
|
|
78079
|
-
let filepath =
|
|
78080
|
-
const base =
|
|
78081
|
-
const ext =
|
|
78118
|
+
let filepath = path81.join(targetDir, filename);
|
|
78119
|
+
const base = path81.basename(filepath, path81.extname(filepath));
|
|
78120
|
+
const ext = path81.extname(filepath);
|
|
78082
78121
|
let counter = 1;
|
|
78083
|
-
while (
|
|
78084
|
-
filepath =
|
|
78122
|
+
while (fs63.existsSync(filepath)) {
|
|
78123
|
+
filepath = path81.join(targetDir, `${base}_${counter}${ext}`);
|
|
78085
78124
|
counter++;
|
|
78086
78125
|
}
|
|
78087
78126
|
try {
|
|
78088
|
-
|
|
78127
|
+
fs63.writeFileSync(filepath, code.trim(), "utf-8");
|
|
78089
78128
|
savedFiles.push(filepath);
|
|
78090
78129
|
} catch (error93) {
|
|
78091
78130
|
errors5.push(`Failed to save ${filename}: ${error93 instanceof Error ? error93.message : String(error93)}`);
|
|
@@ -78344,8 +78383,8 @@ var gitingest = createSwarmTool({
|
|
|
78344
78383
|
init_zod();
|
|
78345
78384
|
init_create_tool();
|
|
78346
78385
|
init_path_security();
|
|
78347
|
-
import * as
|
|
78348
|
-
import * as
|
|
78386
|
+
import * as fs64 from "node:fs";
|
|
78387
|
+
import * as path82 from "node:path";
|
|
78349
78388
|
var MAX_FILE_PATH_LENGTH2 = 500;
|
|
78350
78389
|
var MAX_SYMBOL_LENGTH = 256;
|
|
78351
78390
|
var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
|
|
@@ -78393,7 +78432,7 @@ function validateSymbolInput(symbol3) {
|
|
|
78393
78432
|
return null;
|
|
78394
78433
|
}
|
|
78395
78434
|
function isBinaryFile2(filePath, buffer) {
|
|
78396
|
-
const ext =
|
|
78435
|
+
const ext = path82.extname(filePath).toLowerCase();
|
|
78397
78436
|
if (ext === ".json" || ext === ".md" || ext === ".txt") {
|
|
78398
78437
|
return false;
|
|
78399
78438
|
}
|
|
@@ -78417,15 +78456,15 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
78417
78456
|
const imports = [];
|
|
78418
78457
|
let _resolvedTarget;
|
|
78419
78458
|
try {
|
|
78420
|
-
_resolvedTarget =
|
|
78459
|
+
_resolvedTarget = path82.resolve(targetFile);
|
|
78421
78460
|
} catch {
|
|
78422
78461
|
_resolvedTarget = targetFile;
|
|
78423
78462
|
}
|
|
78424
|
-
const targetBasename =
|
|
78463
|
+
const targetBasename = path82.basename(targetFile, path82.extname(targetFile));
|
|
78425
78464
|
const targetWithExt = targetFile;
|
|
78426
78465
|
const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
78427
|
-
const normalizedTargetWithExt =
|
|
78428
|
-
const normalizedTargetWithoutExt =
|
|
78466
|
+
const normalizedTargetWithExt = path82.normalize(targetWithExt).replace(/\\/g, "/");
|
|
78467
|
+
const normalizedTargetWithoutExt = path82.normalize(targetWithoutExt).replace(/\\/g, "/");
|
|
78429
78468
|
const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
|
|
78430
78469
|
for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
|
|
78431
78470
|
const modulePath = match[1] || match[2] || match[3];
|
|
@@ -78448,9 +78487,9 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
78448
78487
|
}
|
|
78449
78488
|
const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
|
|
78450
78489
|
let isMatch = false;
|
|
78451
|
-
const _targetDir =
|
|
78452
|
-
const targetExt =
|
|
78453
|
-
const targetBasenameNoExt =
|
|
78490
|
+
const _targetDir = path82.dirname(targetFile);
|
|
78491
|
+
const targetExt = path82.extname(targetFile);
|
|
78492
|
+
const targetBasenameNoExt = path82.basename(targetFile, targetExt);
|
|
78454
78493
|
const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
78455
78494
|
const moduleName = modulePath.split(/[/\\]/).pop() || "";
|
|
78456
78495
|
const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
@@ -78507,7 +78546,7 @@ var SKIP_DIRECTORIES4 = new Set([
|
|
|
78507
78546
|
function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFiles: 0, fileErrors: [] }) {
|
|
78508
78547
|
let entries;
|
|
78509
78548
|
try {
|
|
78510
|
-
entries =
|
|
78549
|
+
entries = fs64.readdirSync(dir);
|
|
78511
78550
|
} catch (e) {
|
|
78512
78551
|
stats.fileErrors.push({
|
|
78513
78552
|
path: dir,
|
|
@@ -78518,13 +78557,13 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
78518
78557
|
entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
|
78519
78558
|
for (const entry of entries) {
|
|
78520
78559
|
if (SKIP_DIRECTORIES4.has(entry)) {
|
|
78521
|
-
stats.skippedDirs.push(
|
|
78560
|
+
stats.skippedDirs.push(path82.join(dir, entry));
|
|
78522
78561
|
continue;
|
|
78523
78562
|
}
|
|
78524
|
-
const fullPath =
|
|
78563
|
+
const fullPath = path82.join(dir, entry);
|
|
78525
78564
|
let stat6;
|
|
78526
78565
|
try {
|
|
78527
|
-
stat6 =
|
|
78566
|
+
stat6 = fs64.statSync(fullPath);
|
|
78528
78567
|
} catch (e) {
|
|
78529
78568
|
stats.fileErrors.push({
|
|
78530
78569
|
path: fullPath,
|
|
@@ -78535,7 +78574,7 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
78535
78574
|
if (stat6.isDirectory()) {
|
|
78536
78575
|
findSourceFiles2(fullPath, files, stats);
|
|
78537
78576
|
} else if (stat6.isFile()) {
|
|
78538
|
-
const ext =
|
|
78577
|
+
const ext = path82.extname(fullPath).toLowerCase();
|
|
78539
78578
|
if (SUPPORTED_EXTENSIONS3.includes(ext)) {
|
|
78540
78579
|
files.push(fullPath);
|
|
78541
78580
|
}
|
|
@@ -78592,8 +78631,8 @@ var imports = createSwarmTool({
|
|
|
78592
78631
|
return JSON.stringify(errorResult, null, 2);
|
|
78593
78632
|
}
|
|
78594
78633
|
try {
|
|
78595
|
-
const targetFile =
|
|
78596
|
-
if (!
|
|
78634
|
+
const targetFile = path82.resolve(file3);
|
|
78635
|
+
if (!fs64.existsSync(targetFile)) {
|
|
78597
78636
|
const errorResult = {
|
|
78598
78637
|
error: `target file not found: ${file3}`,
|
|
78599
78638
|
target: file3,
|
|
@@ -78603,7 +78642,7 @@ var imports = createSwarmTool({
|
|
|
78603
78642
|
};
|
|
78604
78643
|
return JSON.stringify(errorResult, null, 2);
|
|
78605
78644
|
}
|
|
78606
|
-
const targetStat =
|
|
78645
|
+
const targetStat = fs64.statSync(targetFile);
|
|
78607
78646
|
if (!targetStat.isFile()) {
|
|
78608
78647
|
const errorResult = {
|
|
78609
78648
|
error: "target must be a file, not a directory",
|
|
@@ -78614,7 +78653,7 @@ var imports = createSwarmTool({
|
|
|
78614
78653
|
};
|
|
78615
78654
|
return JSON.stringify(errorResult, null, 2);
|
|
78616
78655
|
}
|
|
78617
|
-
const baseDir =
|
|
78656
|
+
const baseDir = path82.dirname(targetFile);
|
|
78618
78657
|
const scanStats = {
|
|
78619
78658
|
skippedDirs: [],
|
|
78620
78659
|
skippedFiles: 0,
|
|
@@ -78629,12 +78668,12 @@ var imports = createSwarmTool({
|
|
|
78629
78668
|
if (consumers.length >= MAX_CONSUMERS)
|
|
78630
78669
|
break;
|
|
78631
78670
|
try {
|
|
78632
|
-
const stat6 =
|
|
78671
|
+
const stat6 = fs64.statSync(filePath);
|
|
78633
78672
|
if (stat6.size > MAX_FILE_SIZE_BYTES7) {
|
|
78634
78673
|
skippedFileCount++;
|
|
78635
78674
|
continue;
|
|
78636
78675
|
}
|
|
78637
|
-
const buffer =
|
|
78676
|
+
const buffer = fs64.readFileSync(filePath);
|
|
78638
78677
|
if (isBinaryFile2(filePath, buffer)) {
|
|
78639
78678
|
skippedFileCount++;
|
|
78640
78679
|
continue;
|
|
@@ -78847,7 +78886,7 @@ init_zod();
|
|
|
78847
78886
|
init_config();
|
|
78848
78887
|
init_knowledge_store();
|
|
78849
78888
|
init_create_tool();
|
|
78850
|
-
import { existsSync as
|
|
78889
|
+
import { existsSync as existsSync44 } from "node:fs";
|
|
78851
78890
|
var DEFAULT_LIMIT = 10;
|
|
78852
78891
|
var MAX_LESSON_LENGTH = 200;
|
|
78853
78892
|
var VALID_CATEGORIES3 = [
|
|
@@ -78917,14 +78956,14 @@ function validateLimit(limit) {
|
|
|
78917
78956
|
}
|
|
78918
78957
|
async function readSwarmKnowledge(directory) {
|
|
78919
78958
|
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
78920
|
-
if (!
|
|
78959
|
+
if (!existsSync44(swarmPath)) {
|
|
78921
78960
|
return [];
|
|
78922
78961
|
}
|
|
78923
78962
|
return readKnowledge(swarmPath);
|
|
78924
78963
|
}
|
|
78925
78964
|
async function readHiveKnowledge() {
|
|
78926
78965
|
const hivePath = resolveHiveKnowledgePath();
|
|
78927
|
-
if (!
|
|
78966
|
+
if (!existsSync44(hivePath)) {
|
|
78928
78967
|
return [];
|
|
78929
78968
|
}
|
|
78930
78969
|
return readKnowledge(hivePath);
|
|
@@ -79159,8 +79198,8 @@ init_schema();
|
|
|
79159
79198
|
init_qa_gate_profile();
|
|
79160
79199
|
init_manager2();
|
|
79161
79200
|
init_curator();
|
|
79162
|
-
import * as
|
|
79163
|
-
import * as
|
|
79201
|
+
import * as fs66 from "node:fs";
|
|
79202
|
+
import * as path84 from "node:path";
|
|
79164
79203
|
init_knowledge_curator();
|
|
79165
79204
|
init_knowledge_reader();
|
|
79166
79205
|
init_knowledge_store();
|
|
@@ -79172,20 +79211,20 @@ init_file_locks();
|
|
|
79172
79211
|
init_plan_schema();
|
|
79173
79212
|
init_ledger();
|
|
79174
79213
|
init_manager();
|
|
79175
|
-
import * as
|
|
79176
|
-
import * as
|
|
79214
|
+
import * as fs65 from "node:fs";
|
|
79215
|
+
import * as path83 from "node:path";
|
|
79177
79216
|
async function writeCheckpoint(directory) {
|
|
79178
79217
|
try {
|
|
79179
79218
|
const plan = await loadPlan(directory);
|
|
79180
79219
|
if (!plan)
|
|
79181
79220
|
return;
|
|
79182
|
-
const swarmDir =
|
|
79183
|
-
|
|
79184
|
-
const jsonPath =
|
|
79185
|
-
const mdPath =
|
|
79186
|
-
|
|
79221
|
+
const swarmDir = path83.join(directory, ".swarm");
|
|
79222
|
+
fs65.mkdirSync(swarmDir, { recursive: true });
|
|
79223
|
+
const jsonPath = path83.join(swarmDir, "SWARM_PLAN.json");
|
|
79224
|
+
const mdPath = path83.join(swarmDir, "SWARM_PLAN.md");
|
|
79225
|
+
fs65.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
|
|
79187
79226
|
const md = derivePlanMarkdown(plan);
|
|
79188
|
-
|
|
79227
|
+
fs65.writeFileSync(mdPath, md, "utf8");
|
|
79189
79228
|
} catch (error93) {
|
|
79190
79229
|
console.warn(`[checkpoint] Failed to write SWARM_PLAN checkpoint: ${error93 instanceof Error ? error93.message : String(error93)}`);
|
|
79191
79230
|
}
|
|
@@ -79417,8 +79456,8 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
79417
79456
|
let driftCheckEnabled = true;
|
|
79418
79457
|
let driftHasSpecMd = false;
|
|
79419
79458
|
try {
|
|
79420
|
-
const specMdPath =
|
|
79421
|
-
driftHasSpecMd =
|
|
79459
|
+
const specMdPath = path84.join(dir, ".swarm", "spec.md");
|
|
79460
|
+
driftHasSpecMd = fs66.existsSync(specMdPath);
|
|
79422
79461
|
const gatePlan = await loadPlan(dir);
|
|
79423
79462
|
if (gatePlan) {
|
|
79424
79463
|
const gatePlanId = `${gatePlan.swarm}-${gatePlan.title}`.replace(/[^a-zA-Z0-9-_]/g, "_");
|
|
@@ -79439,9 +79478,9 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
79439
79478
|
} else {
|
|
79440
79479
|
let phaseType;
|
|
79441
79480
|
try {
|
|
79442
|
-
const planPath =
|
|
79443
|
-
if (
|
|
79444
|
-
const planRaw =
|
|
79481
|
+
const planPath = path84.join(dir, ".swarm", "plan.json");
|
|
79482
|
+
if (fs66.existsSync(planPath)) {
|
|
79483
|
+
const planRaw = fs66.readFileSync(planPath, "utf-8");
|
|
79445
79484
|
const plan = JSON.parse(planRaw);
|
|
79446
79485
|
const targetPhase = plan.phases?.find((p) => p.id === phase);
|
|
79447
79486
|
phaseType = targetPhase?.type;
|
|
@@ -79452,11 +79491,11 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
79452
79491
|
warnings.push(`Phase ${phase} is annotated as 'non-code'. Drift verification was skipped per phase type annotation.`);
|
|
79453
79492
|
} else {
|
|
79454
79493
|
try {
|
|
79455
|
-
const driftEvidencePath =
|
|
79494
|
+
const driftEvidencePath = path84.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
|
|
79456
79495
|
let driftVerdictFound = false;
|
|
79457
79496
|
let driftVerdictApproved = false;
|
|
79458
79497
|
try {
|
|
79459
|
-
const driftEvidenceContent =
|
|
79498
|
+
const driftEvidenceContent = fs66.readFileSync(driftEvidencePath, "utf-8");
|
|
79460
79499
|
const driftEvidence = JSON.parse(driftEvidenceContent);
|
|
79461
79500
|
const entries = driftEvidence.entries ?? [];
|
|
79462
79501
|
for (const entry of entries) {
|
|
@@ -79490,9 +79529,9 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
79490
79529
|
let incompleteTaskCount = 0;
|
|
79491
79530
|
let planParseable = false;
|
|
79492
79531
|
try {
|
|
79493
|
-
const planPath =
|
|
79494
|
-
if (
|
|
79495
|
-
const planRaw =
|
|
79532
|
+
const planPath = path84.join(dir, ".swarm", "plan.json");
|
|
79533
|
+
if (fs66.existsSync(planPath)) {
|
|
79534
|
+
const planRaw = fs66.readFileSync(planPath, "utf-8");
|
|
79496
79535
|
const plan = JSON.parse(planRaw);
|
|
79497
79536
|
planParseable = true;
|
|
79498
79537
|
const planPhase = plan.phases?.find((p) => p.id === phase);
|
|
@@ -79557,11 +79596,11 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
79557
79596
|
const overrides = session2?.qaGateSessionOverrides ?? {};
|
|
79558
79597
|
const effective = getEffectiveGates(profile, overrides);
|
|
79559
79598
|
if (effective.hallucination_guard === true) {
|
|
79560
|
-
const hgPath =
|
|
79599
|
+
const hgPath = path84.join(dir, ".swarm", "evidence", String(phase), "hallucination-guard.json");
|
|
79561
79600
|
let hgVerdictFound = false;
|
|
79562
79601
|
let hgVerdictApproved = false;
|
|
79563
79602
|
try {
|
|
79564
|
-
const hgContent =
|
|
79603
|
+
const hgContent = fs66.readFileSync(hgPath, "utf-8");
|
|
79565
79604
|
const hgBundle = JSON.parse(hgContent);
|
|
79566
79605
|
for (const entry of hgBundle.entries ?? []) {
|
|
79567
79606
|
if (typeof entry.type === "string" && entry.type.includes("hallucination") && typeof entry.verdict === "string") {
|
|
@@ -79629,11 +79668,11 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
79629
79668
|
const overrides = session2?.qaGateSessionOverrides ?? {};
|
|
79630
79669
|
const effective = getEffectiveGates(profile, overrides);
|
|
79631
79670
|
if (effective.mutation_test === true) {
|
|
79632
|
-
const mgPath =
|
|
79671
|
+
const mgPath = path84.join(dir, ".swarm", "evidence", String(phase), "mutation-gate.json");
|
|
79633
79672
|
let mgVerdictFound = false;
|
|
79634
79673
|
let mgVerdict;
|
|
79635
79674
|
try {
|
|
79636
|
-
const mgContent =
|
|
79675
|
+
const mgContent = fs66.readFileSync(mgPath, "utf-8");
|
|
79637
79676
|
const mgBundle = JSON.parse(mgContent);
|
|
79638
79677
|
for (const entry of mgBundle.entries ?? []) {
|
|
79639
79678
|
if (typeof entry.type === "string" && entry.type === "mutation-gate" && typeof entry.verdict === "string") {
|
|
@@ -79703,14 +79742,14 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
79703
79742
|
const effective = getEffectiveGates(profile, overrides);
|
|
79704
79743
|
if (effective.council_mode === true) {
|
|
79705
79744
|
councilModeEnabled = true;
|
|
79706
|
-
const pcPath =
|
|
79745
|
+
const pcPath = path84.join(dir, ".swarm", "evidence", String(phase), "phase-council.json");
|
|
79707
79746
|
let pcVerdictFound = false;
|
|
79708
79747
|
let _pcVerdict;
|
|
79709
79748
|
let pcQuorumSize;
|
|
79710
79749
|
let pcTimestamp;
|
|
79711
79750
|
let pcPhaseNumber;
|
|
79712
79751
|
try {
|
|
79713
|
-
const pcContent =
|
|
79752
|
+
const pcContent = fs66.readFileSync(pcPath, "utf-8");
|
|
79714
79753
|
const pcBundle = JSON.parse(pcContent);
|
|
79715
79754
|
for (const entry of pcBundle.entries ?? []) {
|
|
79716
79755
|
if (typeof entry.type === "string" && entry.type === "phase-council" && typeof entry.verdict === "string") {
|
|
@@ -79905,7 +79944,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
79905
79944
|
}
|
|
79906
79945
|
if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
|
|
79907
79946
|
try {
|
|
79908
|
-
const projectName =
|
|
79947
|
+
const projectName = path84.basename(dir);
|
|
79909
79948
|
const curationResult = await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig);
|
|
79910
79949
|
if (curationResult) {
|
|
79911
79950
|
const sessionState = swarmState.agentSessions.get(sessionID);
|
|
@@ -79985,7 +80024,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
79985
80024
|
let phaseRequiredAgents;
|
|
79986
80025
|
try {
|
|
79987
80026
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
79988
|
-
const planRaw =
|
|
80027
|
+
const planRaw = fs66.readFileSync(planPath, "utf-8");
|
|
79989
80028
|
const plan = JSON.parse(planRaw);
|
|
79990
80029
|
const phaseObj = plan.phases.find((p) => p.id === phase);
|
|
79991
80030
|
phaseRequiredAgents = phaseObj?.required_agents;
|
|
@@ -80000,7 +80039,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
80000
80039
|
if (agentsMissing.length > 0) {
|
|
80001
80040
|
try {
|
|
80002
80041
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
80003
|
-
const planRaw =
|
|
80042
|
+
const planRaw = fs66.readFileSync(planPath, "utf-8");
|
|
80004
80043
|
const plan = JSON.parse(planRaw);
|
|
80005
80044
|
const targetPhase = plan.phases.find((p) => p.id === phase);
|
|
80006
80045
|
if (targetPhase && targetPhase.tasks.length > 0 && targetPhase.tasks.every((t) => t.status === "completed")) {
|
|
@@ -80040,7 +80079,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
80040
80079
|
if (phaseCompleteConfig.regression_sweep?.enforce) {
|
|
80041
80080
|
try {
|
|
80042
80081
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
80043
|
-
const planRaw =
|
|
80082
|
+
const planRaw = fs66.readFileSync(planPath, "utf-8");
|
|
80044
80083
|
const plan = JSON.parse(planRaw);
|
|
80045
80084
|
const targetPhase = plan.phases.find((p) => p.id === phase);
|
|
80046
80085
|
if (targetPhase) {
|
|
@@ -80094,7 +80133,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
80094
80133
|
}
|
|
80095
80134
|
try {
|
|
80096
80135
|
const eventsPath = validateSwarmPath(dir, "events.jsonl");
|
|
80097
|
-
|
|
80136
|
+
fs66.appendFileSync(eventsPath, `${JSON.stringify(event)}
|
|
80098
80137
|
`, "utf-8");
|
|
80099
80138
|
} catch (writeError) {
|
|
80100
80139
|
warnings.push(`Warning: failed to write phase complete event: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
|
|
@@ -80169,12 +80208,12 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
80169
80208
|
warnings.push(`Warning: failed to update plan.json phase status`);
|
|
80170
80209
|
try {
|
|
80171
80210
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
80172
|
-
const planRaw =
|
|
80211
|
+
const planRaw = fs66.readFileSync(planPath, "utf-8");
|
|
80173
80212
|
const plan2 = JSON.parse(planRaw);
|
|
80174
80213
|
const phaseObj = plan2.phases.find((p) => p.id === phase);
|
|
80175
80214
|
if (phaseObj) {
|
|
80176
80215
|
phaseObj.status = "complete";
|
|
80177
|
-
|
|
80216
|
+
fs66.writeFileSync(planPath, JSON.stringify(plan2, null, 2), "utf-8");
|
|
80178
80217
|
}
|
|
80179
80218
|
} catch {}
|
|
80180
80219
|
} else if (plan) {
|
|
@@ -80211,12 +80250,12 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
80211
80250
|
warnings.push(`Warning: failed to update plan.json phase status`);
|
|
80212
80251
|
try {
|
|
80213
80252
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
80214
|
-
const planRaw =
|
|
80253
|
+
const planRaw = fs66.readFileSync(planPath, "utf-8");
|
|
80215
80254
|
const plan = JSON.parse(planRaw);
|
|
80216
80255
|
const phaseObj = plan.phases.find((p) => p.id === phase);
|
|
80217
80256
|
if (phaseObj) {
|
|
80218
80257
|
phaseObj.status = "complete";
|
|
80219
|
-
|
|
80258
|
+
fs66.writeFileSync(planPath, JSON.stringify(plan, null, 2), "utf-8");
|
|
80220
80259
|
}
|
|
80221
80260
|
} catch {}
|
|
80222
80261
|
}
|
|
@@ -80274,8 +80313,8 @@ init_discovery();
|
|
|
80274
80313
|
init_utils();
|
|
80275
80314
|
init_bun_compat();
|
|
80276
80315
|
init_create_tool();
|
|
80277
|
-
import * as
|
|
80278
|
-
import * as
|
|
80316
|
+
import * as fs67 from "node:fs";
|
|
80317
|
+
import * as path85 from "node:path";
|
|
80279
80318
|
var MAX_OUTPUT_BYTES5 = 52428800;
|
|
80280
80319
|
var AUDIT_TIMEOUT_MS = 120000;
|
|
80281
80320
|
function isValidEcosystem(value) {
|
|
@@ -80303,31 +80342,31 @@ function validateArgs3(args2) {
|
|
|
80303
80342
|
function detectEcosystems(directory) {
|
|
80304
80343
|
const ecosystems = [];
|
|
80305
80344
|
const cwd = directory;
|
|
80306
|
-
if (
|
|
80345
|
+
if (fs67.existsSync(path85.join(cwd, "package.json"))) {
|
|
80307
80346
|
ecosystems.push("npm");
|
|
80308
80347
|
}
|
|
80309
|
-
if (
|
|
80348
|
+
if (fs67.existsSync(path85.join(cwd, "pyproject.toml")) || fs67.existsSync(path85.join(cwd, "requirements.txt"))) {
|
|
80310
80349
|
ecosystems.push("pip");
|
|
80311
80350
|
}
|
|
80312
|
-
if (
|
|
80351
|
+
if (fs67.existsSync(path85.join(cwd, "Cargo.toml"))) {
|
|
80313
80352
|
ecosystems.push("cargo");
|
|
80314
80353
|
}
|
|
80315
|
-
if (
|
|
80354
|
+
if (fs67.existsSync(path85.join(cwd, "go.mod"))) {
|
|
80316
80355
|
ecosystems.push("go");
|
|
80317
80356
|
}
|
|
80318
80357
|
try {
|
|
80319
|
-
const files =
|
|
80358
|
+
const files = fs67.readdirSync(cwd);
|
|
80320
80359
|
if (files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
|
|
80321
80360
|
ecosystems.push("dotnet");
|
|
80322
80361
|
}
|
|
80323
80362
|
} catch {}
|
|
80324
|
-
if (
|
|
80363
|
+
if (fs67.existsSync(path85.join(cwd, "Gemfile")) || fs67.existsSync(path85.join(cwd, "Gemfile.lock"))) {
|
|
80325
80364
|
ecosystems.push("ruby");
|
|
80326
80365
|
}
|
|
80327
|
-
if (
|
|
80366
|
+
if (fs67.existsSync(path85.join(cwd, "pubspec.yaml"))) {
|
|
80328
80367
|
ecosystems.push("dart");
|
|
80329
80368
|
}
|
|
80330
|
-
if (
|
|
80369
|
+
if (fs67.existsSync(path85.join(cwd, "composer.lock"))) {
|
|
80331
80370
|
ecosystems.push("composer");
|
|
80332
80371
|
}
|
|
80333
80372
|
return ecosystems;
|
|
@@ -81462,8 +81501,8 @@ var pkg_audit = createSwarmTool({
|
|
|
81462
81501
|
// src/tools/placeholder-scan.ts
|
|
81463
81502
|
init_zod();
|
|
81464
81503
|
init_manager2();
|
|
81465
|
-
import * as
|
|
81466
|
-
import * as
|
|
81504
|
+
import * as fs68 from "node:fs";
|
|
81505
|
+
import * as path86 from "node:path";
|
|
81467
81506
|
init_utils();
|
|
81468
81507
|
init_create_tool();
|
|
81469
81508
|
var MAX_FILE_SIZE = 1024 * 1024;
|
|
@@ -81586,7 +81625,7 @@ function isScaffoldFile(filePath) {
|
|
|
81586
81625
|
if (SCAFFOLD_PATH_PATTERNS.some((pattern) => pattern.test(normalizedPath))) {
|
|
81587
81626
|
return true;
|
|
81588
81627
|
}
|
|
81589
|
-
const filename =
|
|
81628
|
+
const filename = path86.basename(filePath);
|
|
81590
81629
|
if (SCAFFOLD_FILENAME_PATTERNS.some((pattern) => pattern.test(filename))) {
|
|
81591
81630
|
return true;
|
|
81592
81631
|
}
|
|
@@ -81603,7 +81642,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
81603
81642
|
if (regex.test(normalizedPath)) {
|
|
81604
81643
|
return true;
|
|
81605
81644
|
}
|
|
81606
|
-
const filename =
|
|
81645
|
+
const filename = path86.basename(filePath);
|
|
81607
81646
|
const filenameRegex = new RegExp(`^${regexPattern}$`, "i");
|
|
81608
81647
|
if (filenameRegex.test(filename)) {
|
|
81609
81648
|
return true;
|
|
@@ -81612,7 +81651,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
81612
81651
|
return false;
|
|
81613
81652
|
}
|
|
81614
81653
|
function isParserSupported(filePath) {
|
|
81615
|
-
const ext =
|
|
81654
|
+
const ext = path86.extname(filePath).toLowerCase();
|
|
81616
81655
|
return SUPPORTED_PARSER_EXTENSIONS.has(ext);
|
|
81617
81656
|
}
|
|
81618
81657
|
function isPlanFile(filePath) {
|
|
@@ -81859,28 +81898,28 @@ async function placeholderScan(input, directory) {
|
|
|
81859
81898
|
let filesScanned = 0;
|
|
81860
81899
|
const filesWithFindings = new Set;
|
|
81861
81900
|
for (const filePath of changed_files) {
|
|
81862
|
-
const fullPath =
|
|
81863
|
-
const resolvedDirectory =
|
|
81864
|
-
if (!fullPath.startsWith(resolvedDirectory +
|
|
81901
|
+
const fullPath = path86.isAbsolute(filePath) ? filePath : path86.resolve(directory, filePath);
|
|
81902
|
+
const resolvedDirectory = path86.resolve(directory);
|
|
81903
|
+
if (!fullPath.startsWith(resolvedDirectory + path86.sep) && fullPath !== resolvedDirectory) {
|
|
81865
81904
|
continue;
|
|
81866
81905
|
}
|
|
81867
|
-
if (!
|
|
81906
|
+
if (!fs68.existsSync(fullPath)) {
|
|
81868
81907
|
continue;
|
|
81869
81908
|
}
|
|
81870
81909
|
if (isAllowedByGlobs(filePath, allow_globs)) {
|
|
81871
81910
|
continue;
|
|
81872
81911
|
}
|
|
81873
|
-
const relativeFilePath =
|
|
81912
|
+
const relativeFilePath = path86.relative(directory, fullPath).replace(/\\/g, "/");
|
|
81874
81913
|
if (FILE_ALLOWLIST.some((allowed) => relativeFilePath.endsWith(allowed))) {
|
|
81875
81914
|
continue;
|
|
81876
81915
|
}
|
|
81877
81916
|
let content;
|
|
81878
81917
|
try {
|
|
81879
|
-
const stat6 =
|
|
81918
|
+
const stat6 = fs68.statSync(fullPath);
|
|
81880
81919
|
if (stat6.size > MAX_FILE_SIZE) {
|
|
81881
81920
|
continue;
|
|
81882
81921
|
}
|
|
81883
|
-
content =
|
|
81922
|
+
content = fs68.readFileSync(fullPath, "utf-8");
|
|
81884
81923
|
} catch {
|
|
81885
81924
|
continue;
|
|
81886
81925
|
}
|
|
@@ -81941,8 +81980,8 @@ var placeholder_scan = createSwarmTool({
|
|
|
81941
81980
|
}
|
|
81942
81981
|
});
|
|
81943
81982
|
// src/tools/pre-check-batch.ts
|
|
81944
|
-
import * as
|
|
81945
|
-
import * as
|
|
81983
|
+
import * as fs71 from "node:fs";
|
|
81984
|
+
import * as path89 from "node:path";
|
|
81946
81985
|
init_zod();
|
|
81947
81986
|
init_manager2();
|
|
81948
81987
|
init_utils();
|
|
@@ -82079,8 +82118,8 @@ var quality_budget = createSwarmTool({
|
|
|
82079
82118
|
init_zod();
|
|
82080
82119
|
init_manager2();
|
|
82081
82120
|
init_detector();
|
|
82082
|
-
import * as
|
|
82083
|
-
import * as
|
|
82121
|
+
import * as fs70 from "node:fs";
|
|
82122
|
+
import * as path88 from "node:path";
|
|
82084
82123
|
import { extname as extname18 } from "node:path";
|
|
82085
82124
|
|
|
82086
82125
|
// src/sast/rules/c.ts
|
|
@@ -82973,25 +83012,25 @@ init_create_tool();
|
|
|
82973
83012
|
// src/tools/sast-baseline.ts
|
|
82974
83013
|
init_utils2();
|
|
82975
83014
|
import * as crypto8 from "node:crypto";
|
|
82976
|
-
import * as
|
|
82977
|
-
import * as
|
|
83015
|
+
import * as fs69 from "node:fs";
|
|
83016
|
+
import * as path87 from "node:path";
|
|
82978
83017
|
var BASELINE_SCHEMA_VERSION = "1.0.0";
|
|
82979
83018
|
var MAX_BASELINE_FINDINGS = 2000;
|
|
82980
83019
|
var MAX_BASELINE_BYTES = 2 * 1048576;
|
|
82981
83020
|
var LOCK_RETRY_DELAYS_MS = [50, 100, 200, 400, 800];
|
|
82982
83021
|
function normalizeFindingPath(directory, file3) {
|
|
82983
|
-
const resolved =
|
|
82984
|
-
const rel =
|
|
83022
|
+
const resolved = path87.isAbsolute(file3) ? file3 : path87.resolve(directory, file3);
|
|
83023
|
+
const rel = path87.relative(path87.resolve(directory), resolved);
|
|
82985
83024
|
return rel.replace(/\\/g, "/");
|
|
82986
83025
|
}
|
|
82987
83026
|
function baselineRelPath(phase) {
|
|
82988
|
-
return
|
|
83027
|
+
return path87.join("evidence", String(phase), "sast-baseline.json");
|
|
82989
83028
|
}
|
|
82990
83029
|
function tempRelPath(phase) {
|
|
82991
|
-
return
|
|
83030
|
+
return path87.join("evidence", String(phase), `sast-baseline.json.tmp.${Date.now()}.${process.pid}`);
|
|
82992
83031
|
}
|
|
82993
83032
|
function lockRelPath(phase) {
|
|
82994
|
-
return
|
|
83033
|
+
return path87.join("evidence", String(phase), "sast-baseline.json.lock");
|
|
82995
83034
|
}
|
|
82996
83035
|
function getLine(lines, idx) {
|
|
82997
83036
|
if (idx < 0 || idx >= lines.length)
|
|
@@ -83008,7 +83047,7 @@ function fingerprintFinding(finding, directory, occurrenceIndex) {
|
|
|
83008
83047
|
}
|
|
83009
83048
|
const lineNum = finding.location.line;
|
|
83010
83049
|
try {
|
|
83011
|
-
const content =
|
|
83050
|
+
const content = fs69.readFileSync(finding.location.file, "utf-8");
|
|
83012
83051
|
const lines = content.split(`
|
|
83013
83052
|
`);
|
|
83014
83053
|
const idx = lineNum - 1;
|
|
@@ -83039,7 +83078,7 @@ function assignOccurrenceIndices(findings, directory) {
|
|
|
83039
83078
|
try {
|
|
83040
83079
|
if (relFile.startsWith(".."))
|
|
83041
83080
|
throw new Error("escapes workspace");
|
|
83042
|
-
const content =
|
|
83081
|
+
const content = fs69.readFileSync(finding.location.file, "utf-8");
|
|
83043
83082
|
const lines = content.split(`
|
|
83044
83083
|
`);
|
|
83045
83084
|
const idx = lineNum - 1;
|
|
@@ -83068,11 +83107,11 @@ function assignOccurrenceIndices(findings, directory) {
|
|
|
83068
83107
|
async function acquireLock(lockPath) {
|
|
83069
83108
|
for (let attempt = 0;attempt <= LOCK_RETRY_DELAYS_MS.length; attempt++) {
|
|
83070
83109
|
try {
|
|
83071
|
-
const fd =
|
|
83072
|
-
|
|
83110
|
+
const fd = fs69.openSync(lockPath, "wx");
|
|
83111
|
+
fs69.closeSync(fd);
|
|
83073
83112
|
return () => {
|
|
83074
83113
|
try {
|
|
83075
|
-
|
|
83114
|
+
fs69.unlinkSync(lockPath);
|
|
83076
83115
|
} catch {}
|
|
83077
83116
|
};
|
|
83078
83117
|
} catch {
|
|
@@ -83112,13 +83151,13 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
83112
83151
|
message: e instanceof Error ? e.message : "Path validation failed"
|
|
83113
83152
|
};
|
|
83114
83153
|
}
|
|
83115
|
-
|
|
83116
|
-
|
|
83154
|
+
fs69.mkdirSync(path87.dirname(baselinePath), { recursive: true });
|
|
83155
|
+
fs69.mkdirSync(path87.dirname(tempPath), { recursive: true });
|
|
83117
83156
|
const releaseLock = await acquireLock(lockPath);
|
|
83118
83157
|
try {
|
|
83119
83158
|
let existing = null;
|
|
83120
83159
|
try {
|
|
83121
|
-
const raw =
|
|
83160
|
+
const raw = fs69.readFileSync(baselinePath, "utf-8");
|
|
83122
83161
|
const parsed = JSON.parse(raw);
|
|
83123
83162
|
if (parsed.schema_version === BASELINE_SCHEMA_VERSION) {
|
|
83124
83163
|
existing = parsed;
|
|
@@ -83178,8 +83217,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
83178
83217
|
message: `Baseline would exceed size cap (${json4.length} bytes > ${MAX_BASELINE_BYTES})`
|
|
83179
83218
|
};
|
|
83180
83219
|
}
|
|
83181
|
-
|
|
83182
|
-
|
|
83220
|
+
fs69.writeFileSync(tempPath, json4, "utf-8");
|
|
83221
|
+
fs69.renameSync(tempPath, baselinePath);
|
|
83183
83222
|
return {
|
|
83184
83223
|
status: "merged",
|
|
83185
83224
|
path: baselinePath,
|
|
@@ -83210,8 +83249,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
83210
83249
|
message: `Baseline would exceed size cap (${json3.length} bytes > ${MAX_BASELINE_BYTES})`
|
|
83211
83250
|
};
|
|
83212
83251
|
}
|
|
83213
|
-
|
|
83214
|
-
|
|
83252
|
+
fs69.writeFileSync(tempPath, json3, "utf-8");
|
|
83253
|
+
fs69.renameSync(tempPath, baselinePath);
|
|
83215
83254
|
return {
|
|
83216
83255
|
status: "written",
|
|
83217
83256
|
path: baselinePath,
|
|
@@ -83236,7 +83275,7 @@ function loadBaseline(directory, phase) {
|
|
|
83236
83275
|
};
|
|
83237
83276
|
}
|
|
83238
83277
|
try {
|
|
83239
|
-
const raw =
|
|
83278
|
+
const raw = fs69.readFileSync(baselinePath, "utf-8");
|
|
83240
83279
|
const parsed = JSON.parse(raw);
|
|
83241
83280
|
if (parsed.schema_version !== BASELINE_SCHEMA_VERSION) {
|
|
83242
83281
|
return {
|
|
@@ -83278,17 +83317,17 @@ var SEVERITY_ORDER = {
|
|
|
83278
83317
|
};
|
|
83279
83318
|
function shouldSkipFile(filePath) {
|
|
83280
83319
|
try {
|
|
83281
|
-
const stats =
|
|
83320
|
+
const stats = fs70.statSync(filePath);
|
|
83282
83321
|
if (stats.size > MAX_FILE_SIZE_BYTES8) {
|
|
83283
83322
|
return { skip: true, reason: "file too large" };
|
|
83284
83323
|
}
|
|
83285
83324
|
if (stats.size === 0) {
|
|
83286
83325
|
return { skip: true, reason: "empty file" };
|
|
83287
83326
|
}
|
|
83288
|
-
const fd =
|
|
83327
|
+
const fd = fs70.openSync(filePath, "r");
|
|
83289
83328
|
const buffer = Buffer.alloc(8192);
|
|
83290
|
-
const bytesRead =
|
|
83291
|
-
|
|
83329
|
+
const bytesRead = fs70.readSync(fd, buffer, 0, 8192, 0);
|
|
83330
|
+
fs70.closeSync(fd);
|
|
83292
83331
|
if (bytesRead > 0) {
|
|
83293
83332
|
let nullCount = 0;
|
|
83294
83333
|
for (let i2 = 0;i2 < bytesRead; i2++) {
|
|
@@ -83327,7 +83366,7 @@ function countBySeverity(findings) {
|
|
|
83327
83366
|
}
|
|
83328
83367
|
function scanFileWithTierA(filePath, language) {
|
|
83329
83368
|
try {
|
|
83330
|
-
const content =
|
|
83369
|
+
const content = fs70.readFileSync(filePath, "utf-8");
|
|
83331
83370
|
const findings = executeRulesSync(filePath, content, language);
|
|
83332
83371
|
return findings.map((f) => ({
|
|
83333
83372
|
rule_id: f.rule_id,
|
|
@@ -83380,13 +83419,13 @@ async function sastScan(input, directory, config3) {
|
|
|
83380
83419
|
_filesSkipped++;
|
|
83381
83420
|
continue;
|
|
83382
83421
|
}
|
|
83383
|
-
const resolvedPath =
|
|
83384
|
-
const resolvedDirectory =
|
|
83385
|
-
if (!resolvedPath.startsWith(resolvedDirectory +
|
|
83422
|
+
const resolvedPath = path88.isAbsolute(filePath) ? filePath : path88.resolve(directory, filePath);
|
|
83423
|
+
const resolvedDirectory = path88.resolve(directory);
|
|
83424
|
+
if (!resolvedPath.startsWith(resolvedDirectory + path88.sep) && resolvedPath !== resolvedDirectory) {
|
|
83386
83425
|
_filesSkipped++;
|
|
83387
83426
|
continue;
|
|
83388
83427
|
}
|
|
83389
|
-
if (!
|
|
83428
|
+
if (!fs70.existsSync(resolvedPath)) {
|
|
83390
83429
|
_filesSkipped++;
|
|
83391
83430
|
continue;
|
|
83392
83431
|
}
|
|
@@ -83693,18 +83732,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
|
|
|
83693
83732
|
let resolved;
|
|
83694
83733
|
const isWinAbs = isWindowsAbsolutePath(inputPath);
|
|
83695
83734
|
if (isWinAbs) {
|
|
83696
|
-
resolved =
|
|
83697
|
-
} else if (
|
|
83698
|
-
resolved =
|
|
83735
|
+
resolved = path89.win32.resolve(inputPath);
|
|
83736
|
+
} else if (path89.isAbsolute(inputPath)) {
|
|
83737
|
+
resolved = path89.resolve(inputPath);
|
|
83699
83738
|
} else {
|
|
83700
|
-
resolved =
|
|
83739
|
+
resolved = path89.resolve(baseDir, inputPath);
|
|
83701
83740
|
}
|
|
83702
|
-
const workspaceResolved =
|
|
83741
|
+
const workspaceResolved = path89.resolve(workspaceDir);
|
|
83703
83742
|
let relative20;
|
|
83704
83743
|
if (isWinAbs) {
|
|
83705
|
-
relative20 =
|
|
83744
|
+
relative20 = path89.win32.relative(workspaceResolved, resolved);
|
|
83706
83745
|
} else {
|
|
83707
|
-
relative20 =
|
|
83746
|
+
relative20 = path89.relative(workspaceResolved, resolved);
|
|
83708
83747
|
}
|
|
83709
83748
|
if (relative20.startsWith("..")) {
|
|
83710
83749
|
return "path traversal detected";
|
|
@@ -83769,7 +83808,7 @@ async function runLintOnFiles(linter, files, workspaceDir) {
|
|
|
83769
83808
|
if (typeof file3 !== "string") {
|
|
83770
83809
|
continue;
|
|
83771
83810
|
}
|
|
83772
|
-
const resolvedPath =
|
|
83811
|
+
const resolvedPath = path89.resolve(file3);
|
|
83773
83812
|
const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
|
|
83774
83813
|
if (validationError) {
|
|
83775
83814
|
continue;
|
|
@@ -83926,7 +83965,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
83926
83965
|
skippedFiles++;
|
|
83927
83966
|
continue;
|
|
83928
83967
|
}
|
|
83929
|
-
const resolvedPath =
|
|
83968
|
+
const resolvedPath = path89.resolve(file3);
|
|
83930
83969
|
const validationError = validatePath(resolvedPath, directory, directory);
|
|
83931
83970
|
if (validationError) {
|
|
83932
83971
|
skippedFiles++;
|
|
@@ -83944,14 +83983,14 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
83944
83983
|
};
|
|
83945
83984
|
}
|
|
83946
83985
|
for (const file3 of validatedFiles) {
|
|
83947
|
-
const ext =
|
|
83986
|
+
const ext = path89.extname(file3).toLowerCase();
|
|
83948
83987
|
if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
|
|
83949
83988
|
skippedFiles++;
|
|
83950
83989
|
continue;
|
|
83951
83990
|
}
|
|
83952
83991
|
let stat6;
|
|
83953
83992
|
try {
|
|
83954
|
-
stat6 =
|
|
83993
|
+
stat6 = fs71.statSync(file3);
|
|
83955
83994
|
} catch {
|
|
83956
83995
|
skippedFiles++;
|
|
83957
83996
|
continue;
|
|
@@ -83962,7 +84001,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
83962
84001
|
}
|
|
83963
84002
|
let content;
|
|
83964
84003
|
try {
|
|
83965
|
-
const buffer =
|
|
84004
|
+
const buffer = fs71.readFileSync(file3);
|
|
83966
84005
|
if (buffer.includes(0)) {
|
|
83967
84006
|
skippedFiles++;
|
|
83968
84007
|
continue;
|
|
@@ -84163,7 +84202,7 @@ function classifySastFindings(findings, changedLineRanges, directory) {
|
|
|
84163
84202
|
const preexistingFindings = [];
|
|
84164
84203
|
for (const finding of findings) {
|
|
84165
84204
|
const filePath = finding.location.file;
|
|
84166
|
-
const normalised =
|
|
84205
|
+
const normalised = path89.relative(directory, filePath).replace(/\\/g, "/");
|
|
84167
84206
|
const changedLines = changedLineRanges.get(normalised);
|
|
84168
84207
|
if (changedLines?.has(finding.location.line)) {
|
|
84169
84208
|
newFindings.push(finding);
|
|
@@ -84214,7 +84253,7 @@ async function runPreCheckBatch(input, workspaceDir, contextDir) {
|
|
|
84214
84253
|
warn(`pre_check_batch: Invalid file path: ${file3}`);
|
|
84215
84254
|
continue;
|
|
84216
84255
|
}
|
|
84217
|
-
changedFiles.push(
|
|
84256
|
+
changedFiles.push(path89.resolve(directory, file3));
|
|
84218
84257
|
}
|
|
84219
84258
|
if (changedFiles.length === 0) {
|
|
84220
84259
|
warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
|
|
@@ -84415,7 +84454,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
84415
84454
|
};
|
|
84416
84455
|
return JSON.stringify(errorResult, null, 2);
|
|
84417
84456
|
}
|
|
84418
|
-
const resolvedDirectory =
|
|
84457
|
+
const resolvedDirectory = path89.resolve(typedArgs.directory);
|
|
84419
84458
|
const workspaceAnchor = resolvedDirectory;
|
|
84420
84459
|
const dirError = validateDirectory2(resolvedDirectory, workspaceAnchor);
|
|
84421
84460
|
if (dirError) {
|
|
@@ -84456,7 +84495,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
84456
84495
|
});
|
|
84457
84496
|
// src/tools/repo-map.ts
|
|
84458
84497
|
init_zod();
|
|
84459
|
-
import * as
|
|
84498
|
+
import * as path90 from "node:path";
|
|
84460
84499
|
init_path_security();
|
|
84461
84500
|
init_create_tool();
|
|
84462
84501
|
var VALID_ACTIONS = [
|
|
@@ -84481,7 +84520,7 @@ function validateFile(p) {
|
|
|
84481
84520
|
return "file contains control characters";
|
|
84482
84521
|
if (containsPathTraversal(p))
|
|
84483
84522
|
return "file contains path traversal";
|
|
84484
|
-
if (
|
|
84523
|
+
if (path90.isAbsolute(p) || /^[a-zA-Z]:[\\/]/.test(p)) {
|
|
84485
84524
|
return "file must be a workspace-relative path, not absolute";
|
|
84486
84525
|
}
|
|
84487
84526
|
return null;
|
|
@@ -84504,8 +84543,8 @@ function ok(action, payload) {
|
|
|
84504
84543
|
}
|
|
84505
84544
|
function toRelativeGraphPath(input, workspaceRoot) {
|
|
84506
84545
|
const normalized = input.replace(/\\/g, "/");
|
|
84507
|
-
if (
|
|
84508
|
-
const rel =
|
|
84546
|
+
if (path90.isAbsolute(normalized)) {
|
|
84547
|
+
const rel = path90.relative(workspaceRoot, normalized).replace(/\\/g, "/");
|
|
84509
84548
|
return normalizeGraphPath2(rel);
|
|
84510
84549
|
}
|
|
84511
84550
|
return normalizeGraphPath2(normalized);
|
|
@@ -84649,8 +84688,8 @@ var repo_map = createSwarmTool({
|
|
|
84649
84688
|
// src/tools/req-coverage.ts
|
|
84650
84689
|
init_zod();
|
|
84651
84690
|
init_create_tool();
|
|
84652
|
-
import * as
|
|
84653
|
-
import * as
|
|
84691
|
+
import * as fs72 from "node:fs";
|
|
84692
|
+
import * as path91 from "node:path";
|
|
84654
84693
|
var SPEC_FILE = ".swarm/spec.md";
|
|
84655
84694
|
var EVIDENCE_DIR4 = ".swarm/evidence";
|
|
84656
84695
|
var OBLIGATION_KEYWORDS = ["MUST", "SHOULD", "SHALL"];
|
|
@@ -84709,19 +84748,19 @@ function extractObligationAndText(id, lineText) {
|
|
|
84709
84748
|
var PHASE_TASK_ID_REGEX = /^\d+\.\d+(\.\d+)*$/;
|
|
84710
84749
|
function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
84711
84750
|
const touchedFiles = new Set;
|
|
84712
|
-
if (!
|
|
84751
|
+
if (!fs72.existsSync(evidenceDir) || !fs72.statSync(evidenceDir).isDirectory()) {
|
|
84713
84752
|
return [];
|
|
84714
84753
|
}
|
|
84715
84754
|
let entries;
|
|
84716
84755
|
try {
|
|
84717
|
-
entries =
|
|
84756
|
+
entries = fs72.readdirSync(evidenceDir);
|
|
84718
84757
|
} catch {
|
|
84719
84758
|
return [];
|
|
84720
84759
|
}
|
|
84721
84760
|
for (const entry of entries) {
|
|
84722
|
-
const entryPath =
|
|
84761
|
+
const entryPath = path91.join(evidenceDir, entry);
|
|
84723
84762
|
try {
|
|
84724
|
-
const stat6 =
|
|
84763
|
+
const stat6 = fs72.statSync(entryPath);
|
|
84725
84764
|
if (!stat6.isDirectory()) {
|
|
84726
84765
|
continue;
|
|
84727
84766
|
}
|
|
@@ -84735,14 +84774,14 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
84735
84774
|
if (entryPhase !== String(phase)) {
|
|
84736
84775
|
continue;
|
|
84737
84776
|
}
|
|
84738
|
-
const evidenceFilePath =
|
|
84777
|
+
const evidenceFilePath = path91.join(entryPath, "evidence.json");
|
|
84739
84778
|
try {
|
|
84740
|
-
const resolvedPath =
|
|
84741
|
-
const evidenceDirResolved =
|
|
84742
|
-
if (!resolvedPath.startsWith(evidenceDirResolved +
|
|
84779
|
+
const resolvedPath = path91.resolve(evidenceFilePath);
|
|
84780
|
+
const evidenceDirResolved = path91.resolve(evidenceDir);
|
|
84781
|
+
if (!resolvedPath.startsWith(evidenceDirResolved + path91.sep)) {
|
|
84743
84782
|
continue;
|
|
84744
84783
|
}
|
|
84745
|
-
const stat6 =
|
|
84784
|
+
const stat6 = fs72.lstatSync(evidenceFilePath);
|
|
84746
84785
|
if (!stat6.isFile()) {
|
|
84747
84786
|
continue;
|
|
84748
84787
|
}
|
|
@@ -84754,7 +84793,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
84754
84793
|
}
|
|
84755
84794
|
let content;
|
|
84756
84795
|
try {
|
|
84757
|
-
content =
|
|
84796
|
+
content = fs72.readFileSync(evidenceFilePath, "utf-8");
|
|
84758
84797
|
} catch {
|
|
84759
84798
|
continue;
|
|
84760
84799
|
}
|
|
@@ -84773,7 +84812,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
84773
84812
|
if (Array.isArray(diffEntry.files_changed)) {
|
|
84774
84813
|
for (const file3 of diffEntry.files_changed) {
|
|
84775
84814
|
if (typeof file3 === "string") {
|
|
84776
|
-
touchedFiles.add(
|
|
84815
|
+
touchedFiles.add(path91.resolve(cwd, file3));
|
|
84777
84816
|
}
|
|
84778
84817
|
}
|
|
84779
84818
|
}
|
|
@@ -84786,12 +84825,12 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
84786
84825
|
}
|
|
84787
84826
|
function searchFileForKeywords(filePath, keywords, cwd) {
|
|
84788
84827
|
try {
|
|
84789
|
-
const resolvedPath =
|
|
84790
|
-
const cwdResolved =
|
|
84828
|
+
const resolvedPath = path91.resolve(filePath);
|
|
84829
|
+
const cwdResolved = path91.resolve(cwd);
|
|
84791
84830
|
if (!resolvedPath.startsWith(cwdResolved)) {
|
|
84792
84831
|
return false;
|
|
84793
84832
|
}
|
|
84794
|
-
const content =
|
|
84833
|
+
const content = fs72.readFileSync(resolvedPath, "utf-8");
|
|
84795
84834
|
for (const keyword of keywords) {
|
|
84796
84835
|
const regex = new RegExp(`\\b${keyword}\\b`, "i");
|
|
84797
84836
|
if (regex.test(content)) {
|
|
@@ -84921,10 +84960,10 @@ var req_coverage = createSwarmTool({
|
|
|
84921
84960
|
}, null, 2);
|
|
84922
84961
|
}
|
|
84923
84962
|
const cwd = inputDirectory || directory;
|
|
84924
|
-
const specPath =
|
|
84963
|
+
const specPath = path91.join(cwd, SPEC_FILE);
|
|
84925
84964
|
let specContent;
|
|
84926
84965
|
try {
|
|
84927
|
-
specContent =
|
|
84966
|
+
specContent = fs72.readFileSync(specPath, "utf-8");
|
|
84928
84967
|
} catch (readError) {
|
|
84929
84968
|
return JSON.stringify({
|
|
84930
84969
|
success: false,
|
|
@@ -84948,7 +84987,7 @@ var req_coverage = createSwarmTool({
|
|
|
84948
84987
|
message: "No FR requirements found in spec.md"
|
|
84949
84988
|
}, null, 2);
|
|
84950
84989
|
}
|
|
84951
|
-
const evidenceDir =
|
|
84990
|
+
const evidenceDir = path91.join(cwd, EVIDENCE_DIR4);
|
|
84952
84991
|
const touchedFiles = readTouchedFiles(evidenceDir, phase, cwd);
|
|
84953
84992
|
const analyzedRequirements = [];
|
|
84954
84993
|
let coveredCount = 0;
|
|
@@ -84974,12 +85013,12 @@ var req_coverage = createSwarmTool({
|
|
|
84974
85013
|
requirements: analyzedRequirements
|
|
84975
85014
|
};
|
|
84976
85015
|
const reportFilename = `req-coverage-phase-${phase}.json`;
|
|
84977
|
-
const reportPath =
|
|
85016
|
+
const reportPath = path91.join(evidenceDir, reportFilename);
|
|
84978
85017
|
try {
|
|
84979
|
-
if (!
|
|
84980
|
-
|
|
85018
|
+
if (!fs72.existsSync(evidenceDir)) {
|
|
85019
|
+
fs72.mkdirSync(evidenceDir, { recursive: true });
|
|
84981
85020
|
}
|
|
84982
|
-
|
|
85021
|
+
fs72.writeFileSync(reportPath, JSON.stringify(result, null, 2), "utf-8");
|
|
84983
85022
|
} catch (writeError) {
|
|
84984
85023
|
console.warn(`Failed to write coverage report: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
|
|
84985
85024
|
}
|
|
@@ -85061,8 +85100,8 @@ init_plan_schema();
|
|
|
85061
85100
|
init_qa_gate_profile();
|
|
85062
85101
|
init_file_locks();
|
|
85063
85102
|
import * as crypto9 from "node:crypto";
|
|
85064
|
-
import * as
|
|
85065
|
-
import * as
|
|
85103
|
+
import * as fs73 from "node:fs";
|
|
85104
|
+
import * as path92 from "node:path";
|
|
85066
85105
|
init_ledger();
|
|
85067
85106
|
init_manager();
|
|
85068
85107
|
init_state();
|
|
@@ -85140,17 +85179,17 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
85140
85179
|
};
|
|
85141
85180
|
}
|
|
85142
85181
|
if (args2.working_directory && fallbackDir) {
|
|
85143
|
-
const resolvedTarget =
|
|
85144
|
-
const resolvedRoot =
|
|
85182
|
+
const resolvedTarget = path92.resolve(args2.working_directory);
|
|
85183
|
+
const resolvedRoot = path92.resolve(fallbackDir);
|
|
85145
85184
|
let fallbackExists = false;
|
|
85146
85185
|
try {
|
|
85147
|
-
|
|
85186
|
+
fs73.accessSync(resolvedRoot, fs73.constants.F_OK);
|
|
85148
85187
|
fallbackExists = true;
|
|
85149
85188
|
} catch {
|
|
85150
85189
|
fallbackExists = false;
|
|
85151
85190
|
}
|
|
85152
85191
|
if (fallbackExists) {
|
|
85153
|
-
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot +
|
|
85192
|
+
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot + path92.sep);
|
|
85154
85193
|
if (isSubdirectory) {
|
|
85155
85194
|
return {
|
|
85156
85195
|
success: false,
|
|
@@ -85166,11 +85205,11 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
85166
85205
|
let specMtime;
|
|
85167
85206
|
let specHash;
|
|
85168
85207
|
if (process.env.SWARM_SKIP_SPEC_GATE !== "1") {
|
|
85169
|
-
const specPath =
|
|
85208
|
+
const specPath = path92.join(targetWorkspace, ".swarm", "spec.md");
|
|
85170
85209
|
try {
|
|
85171
|
-
const stat6 = await
|
|
85210
|
+
const stat6 = await fs73.promises.stat(specPath);
|
|
85172
85211
|
specMtime = stat6.mtime.toISOString();
|
|
85173
|
-
const content = await
|
|
85212
|
+
const content = await fs73.promises.readFile(specPath, "utf8");
|
|
85174
85213
|
specHash = crypto9.createHash("sha256").update(content).digest("hex");
|
|
85175
85214
|
} catch {
|
|
85176
85215
|
return {
|
|
@@ -85182,10 +85221,10 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
85182
85221
|
}
|
|
85183
85222
|
}
|
|
85184
85223
|
if (process.env.SWARM_SKIP_GATE_SELECTION !== "1") {
|
|
85185
|
-
const contextPath =
|
|
85224
|
+
const contextPath = path92.join(targetWorkspace, ".swarm", "context.md");
|
|
85186
85225
|
let contextContent = "";
|
|
85187
85226
|
try {
|
|
85188
|
-
contextContent = await
|
|
85227
|
+
contextContent = await fs73.promises.readFile(contextPath, "utf8");
|
|
85189
85228
|
} catch {}
|
|
85190
85229
|
const hasPendingSection = contextContent.includes("## Pending QA Gate Selection");
|
|
85191
85230
|
if (!hasPendingSection) {
|
|
@@ -85332,14 +85371,14 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
85332
85371
|
}
|
|
85333
85372
|
await writeCheckpoint(dir).catch(() => {});
|
|
85334
85373
|
try {
|
|
85335
|
-
const markerPath =
|
|
85374
|
+
const markerPath = path92.join(dir, ".swarm", ".plan-write-marker");
|
|
85336
85375
|
const marker = JSON.stringify({
|
|
85337
85376
|
source: "save_plan",
|
|
85338
85377
|
timestamp: new Date().toISOString(),
|
|
85339
85378
|
phases_count: plan.phases.length,
|
|
85340
85379
|
tasks_count: tasksCount
|
|
85341
85380
|
});
|
|
85342
|
-
await
|
|
85381
|
+
await fs73.promises.writeFile(markerPath, marker, "utf8");
|
|
85343
85382
|
} catch {}
|
|
85344
85383
|
const warnings = [];
|
|
85345
85384
|
let criticReviewFound = false;
|
|
@@ -85355,7 +85394,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
85355
85394
|
return {
|
|
85356
85395
|
success: true,
|
|
85357
85396
|
message: "Plan saved successfully",
|
|
85358
|
-
plan_path:
|
|
85397
|
+
plan_path: path92.join(dir, ".swarm", "plan.json"),
|
|
85359
85398
|
phases_count: plan.phases.length,
|
|
85360
85399
|
tasks_count: tasksCount,
|
|
85361
85400
|
...resolvedProfile !== undefined ? { execution_profile: resolvedProfile } : {},
|
|
@@ -85407,8 +85446,8 @@ var save_plan = createSwarmTool({
|
|
|
85407
85446
|
// src/tools/sbom-generate.ts
|
|
85408
85447
|
init_zod();
|
|
85409
85448
|
init_manager2();
|
|
85410
|
-
import * as
|
|
85411
|
-
import * as
|
|
85449
|
+
import * as fs74 from "node:fs";
|
|
85450
|
+
import * as path93 from "node:path";
|
|
85412
85451
|
|
|
85413
85452
|
// src/sbom/detectors/index.ts
|
|
85414
85453
|
init_utils();
|
|
@@ -86256,9 +86295,9 @@ function findManifestFiles(rootDir) {
|
|
|
86256
86295
|
const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
|
|
86257
86296
|
function searchDir(dir) {
|
|
86258
86297
|
try {
|
|
86259
|
-
const entries =
|
|
86298
|
+
const entries = fs74.readdirSync(dir, { withFileTypes: true });
|
|
86260
86299
|
for (const entry of entries) {
|
|
86261
|
-
const fullPath =
|
|
86300
|
+
const fullPath = path93.join(dir, entry.name);
|
|
86262
86301
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
|
|
86263
86302
|
continue;
|
|
86264
86303
|
}
|
|
@@ -86267,7 +86306,7 @@ function findManifestFiles(rootDir) {
|
|
|
86267
86306
|
} else if (entry.isFile()) {
|
|
86268
86307
|
for (const pattern of patterns) {
|
|
86269
86308
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
86270
|
-
manifestFiles.push(
|
|
86309
|
+
manifestFiles.push(path93.relative(rootDir, fullPath));
|
|
86271
86310
|
break;
|
|
86272
86311
|
}
|
|
86273
86312
|
}
|
|
@@ -86283,13 +86322,13 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
86283
86322
|
const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
|
|
86284
86323
|
for (const dir of directories) {
|
|
86285
86324
|
try {
|
|
86286
|
-
const entries =
|
|
86325
|
+
const entries = fs74.readdirSync(dir, { withFileTypes: true });
|
|
86287
86326
|
for (const entry of entries) {
|
|
86288
|
-
const fullPath =
|
|
86327
|
+
const fullPath = path93.join(dir, entry.name);
|
|
86289
86328
|
if (entry.isFile()) {
|
|
86290
86329
|
for (const pattern of patterns) {
|
|
86291
86330
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
86292
|
-
found.push(
|
|
86331
|
+
found.push(path93.relative(workingDir, fullPath));
|
|
86293
86332
|
break;
|
|
86294
86333
|
}
|
|
86295
86334
|
}
|
|
@@ -86302,11 +86341,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
86302
86341
|
function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
86303
86342
|
const dirs = new Set;
|
|
86304
86343
|
for (const file3 of changedFiles) {
|
|
86305
|
-
let currentDir =
|
|
86344
|
+
let currentDir = path93.dirname(file3);
|
|
86306
86345
|
while (true) {
|
|
86307
|
-
if (currentDir && currentDir !== "." && currentDir !==
|
|
86308
|
-
dirs.add(
|
|
86309
|
-
const parent =
|
|
86346
|
+
if (currentDir && currentDir !== "." && currentDir !== path93.sep) {
|
|
86347
|
+
dirs.add(path93.join(workingDir, currentDir));
|
|
86348
|
+
const parent = path93.dirname(currentDir);
|
|
86310
86349
|
if (parent === currentDir)
|
|
86311
86350
|
break;
|
|
86312
86351
|
currentDir = parent;
|
|
@@ -86320,7 +86359,7 @@ function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
|
86320
86359
|
}
|
|
86321
86360
|
function ensureOutputDir(outputDir) {
|
|
86322
86361
|
try {
|
|
86323
|
-
|
|
86362
|
+
fs74.mkdirSync(outputDir, { recursive: true });
|
|
86324
86363
|
} catch (error93) {
|
|
86325
86364
|
if (!error93 || error93.code !== "EEXIST") {
|
|
86326
86365
|
throw error93;
|
|
@@ -86390,7 +86429,7 @@ var sbom_generate = createSwarmTool({
|
|
|
86390
86429
|
const changedFiles = obj.changed_files;
|
|
86391
86430
|
const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
|
|
86392
86431
|
const workingDir = directory;
|
|
86393
|
-
const outputDir =
|
|
86432
|
+
const outputDir = path93.isAbsolute(relativeOutputDir) ? relativeOutputDir : path93.join(workingDir, relativeOutputDir);
|
|
86394
86433
|
let manifestFiles = [];
|
|
86395
86434
|
if (scope === "all") {
|
|
86396
86435
|
manifestFiles = findManifestFiles(workingDir);
|
|
@@ -86413,11 +86452,11 @@ var sbom_generate = createSwarmTool({
|
|
|
86413
86452
|
const processedFiles = [];
|
|
86414
86453
|
for (const manifestFile of manifestFiles) {
|
|
86415
86454
|
try {
|
|
86416
|
-
const fullPath =
|
|
86417
|
-
if (!
|
|
86455
|
+
const fullPath = path93.isAbsolute(manifestFile) ? manifestFile : path93.join(workingDir, manifestFile);
|
|
86456
|
+
if (!fs74.existsSync(fullPath)) {
|
|
86418
86457
|
continue;
|
|
86419
86458
|
}
|
|
86420
|
-
const content =
|
|
86459
|
+
const content = fs74.readFileSync(fullPath, "utf-8");
|
|
86421
86460
|
const components = detectComponents(manifestFile, content);
|
|
86422
86461
|
processedFiles.push(manifestFile);
|
|
86423
86462
|
if (components.length > 0) {
|
|
@@ -86430,8 +86469,8 @@ var sbom_generate = createSwarmTool({
|
|
|
86430
86469
|
const bom = generateCycloneDX(allComponents);
|
|
86431
86470
|
const bomJson = serializeCycloneDX(bom);
|
|
86432
86471
|
const filename = generateSbomFilename();
|
|
86433
|
-
const outputPath =
|
|
86434
|
-
|
|
86472
|
+
const outputPath = path93.join(outputDir, filename);
|
|
86473
|
+
fs74.writeFileSync(outputPath, bomJson, "utf-8");
|
|
86435
86474
|
const verdict = processedFiles.length > 0 ? "pass" : "pass";
|
|
86436
86475
|
try {
|
|
86437
86476
|
const timestamp = new Date().toISOString();
|
|
@@ -86473,8 +86512,8 @@ var sbom_generate = createSwarmTool({
|
|
|
86473
86512
|
// src/tools/schema-drift.ts
|
|
86474
86513
|
init_zod();
|
|
86475
86514
|
init_create_tool();
|
|
86476
|
-
import * as
|
|
86477
|
-
import * as
|
|
86515
|
+
import * as fs75 from "node:fs";
|
|
86516
|
+
import * as path94 from "node:path";
|
|
86478
86517
|
var SPEC_CANDIDATES = [
|
|
86479
86518
|
"openapi.json",
|
|
86480
86519
|
"openapi.yaml",
|
|
@@ -86506,28 +86545,28 @@ function normalizePath3(p) {
|
|
|
86506
86545
|
}
|
|
86507
86546
|
function discoverSpecFile(cwd, specFileArg) {
|
|
86508
86547
|
if (specFileArg) {
|
|
86509
|
-
const resolvedPath =
|
|
86510
|
-
const normalizedCwd = cwd.endsWith(
|
|
86548
|
+
const resolvedPath = path94.resolve(cwd, specFileArg);
|
|
86549
|
+
const normalizedCwd = cwd.endsWith(path94.sep) ? cwd : cwd + path94.sep;
|
|
86511
86550
|
if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
|
|
86512
86551
|
throw new Error("Invalid spec_file: path traversal detected");
|
|
86513
86552
|
}
|
|
86514
|
-
const ext =
|
|
86553
|
+
const ext = path94.extname(resolvedPath).toLowerCase();
|
|
86515
86554
|
if (!ALLOWED_EXTENSIONS.includes(ext)) {
|
|
86516
86555
|
throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
|
|
86517
86556
|
}
|
|
86518
|
-
const stats =
|
|
86557
|
+
const stats = fs75.statSync(resolvedPath);
|
|
86519
86558
|
if (stats.size > MAX_SPEC_SIZE) {
|
|
86520
86559
|
throw new Error(`Invalid spec_file: file exceeds ${MAX_SPEC_SIZE / 1024 / 1024}MB limit`);
|
|
86521
86560
|
}
|
|
86522
|
-
if (!
|
|
86561
|
+
if (!fs75.existsSync(resolvedPath)) {
|
|
86523
86562
|
throw new Error(`Spec file not found: ${resolvedPath}`);
|
|
86524
86563
|
}
|
|
86525
86564
|
return resolvedPath;
|
|
86526
86565
|
}
|
|
86527
86566
|
for (const candidate of SPEC_CANDIDATES) {
|
|
86528
|
-
const candidatePath =
|
|
86529
|
-
if (
|
|
86530
|
-
const stats =
|
|
86567
|
+
const candidatePath = path94.resolve(cwd, candidate);
|
|
86568
|
+
if (fs75.existsSync(candidatePath)) {
|
|
86569
|
+
const stats = fs75.statSync(candidatePath);
|
|
86531
86570
|
if (stats.size <= MAX_SPEC_SIZE) {
|
|
86532
86571
|
return candidatePath;
|
|
86533
86572
|
}
|
|
@@ -86536,8 +86575,8 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
86536
86575
|
return null;
|
|
86537
86576
|
}
|
|
86538
86577
|
function parseSpec(specFile) {
|
|
86539
|
-
const content =
|
|
86540
|
-
const ext =
|
|
86578
|
+
const content = fs75.readFileSync(specFile, "utf-8");
|
|
86579
|
+
const ext = path94.extname(specFile).toLowerCase();
|
|
86541
86580
|
if (ext === ".json") {
|
|
86542
86581
|
return parseJsonSpec(content);
|
|
86543
86582
|
}
|
|
@@ -86608,12 +86647,12 @@ function extractRoutes(cwd) {
|
|
|
86608
86647
|
function walkDir(dir) {
|
|
86609
86648
|
let entries;
|
|
86610
86649
|
try {
|
|
86611
|
-
entries =
|
|
86650
|
+
entries = fs75.readdirSync(dir, { withFileTypes: true });
|
|
86612
86651
|
} catch {
|
|
86613
86652
|
return;
|
|
86614
86653
|
}
|
|
86615
86654
|
for (const entry of entries) {
|
|
86616
|
-
const fullPath =
|
|
86655
|
+
const fullPath = path94.join(dir, entry.name);
|
|
86617
86656
|
if (entry.isSymbolicLink()) {
|
|
86618
86657
|
continue;
|
|
86619
86658
|
}
|
|
@@ -86623,7 +86662,7 @@ function extractRoutes(cwd) {
|
|
|
86623
86662
|
}
|
|
86624
86663
|
walkDir(fullPath);
|
|
86625
86664
|
} else if (entry.isFile()) {
|
|
86626
|
-
const ext =
|
|
86665
|
+
const ext = path94.extname(entry.name).toLowerCase();
|
|
86627
86666
|
const baseName = entry.name.toLowerCase();
|
|
86628
86667
|
if (![".ts", ".js", ".mjs"].includes(ext)) {
|
|
86629
86668
|
continue;
|
|
@@ -86641,7 +86680,7 @@ function extractRoutes(cwd) {
|
|
|
86641
86680
|
}
|
|
86642
86681
|
function extractRoutesFromFile(filePath) {
|
|
86643
86682
|
const routes = [];
|
|
86644
|
-
const content =
|
|
86683
|
+
const content = fs75.readFileSync(filePath, "utf-8");
|
|
86645
86684
|
const lines = content.split(/\r?\n/);
|
|
86646
86685
|
const expressRegex = /(?:app|router|server|express)\.(get|post|put|patch|delete|options|head)\s*\(\s*['"`]([^'"`]+)['"`]/g;
|
|
86647
86686
|
const flaskRegex = /@(?:app|blueprint|bp)\.route\s*\(\s*['"]([^'"]+)['"]/g;
|
|
@@ -86790,8 +86829,8 @@ init_zod();
|
|
|
86790
86829
|
init_bun_compat();
|
|
86791
86830
|
init_path_security();
|
|
86792
86831
|
init_create_tool();
|
|
86793
|
-
import * as
|
|
86794
|
-
import * as
|
|
86832
|
+
import * as fs76 from "node:fs";
|
|
86833
|
+
import * as path95 from "node:path";
|
|
86795
86834
|
var DEFAULT_MAX_RESULTS = 100;
|
|
86796
86835
|
var DEFAULT_MAX_LINES = 200;
|
|
86797
86836
|
var REGEX_TIMEOUT_MS = 5000;
|
|
@@ -86827,11 +86866,11 @@ function containsWindowsAttacks3(str) {
|
|
|
86827
86866
|
}
|
|
86828
86867
|
function isPathInWorkspace3(filePath, workspace) {
|
|
86829
86868
|
try {
|
|
86830
|
-
const resolvedPath =
|
|
86831
|
-
const realWorkspace =
|
|
86832
|
-
const realResolvedPath =
|
|
86833
|
-
const relativePath =
|
|
86834
|
-
if (relativePath.startsWith("..") ||
|
|
86869
|
+
const resolvedPath = path95.resolve(workspace, filePath);
|
|
86870
|
+
const realWorkspace = fs76.realpathSync(workspace);
|
|
86871
|
+
const realResolvedPath = fs76.realpathSync(resolvedPath);
|
|
86872
|
+
const relativePath = path95.relative(realWorkspace, realResolvedPath);
|
|
86873
|
+
if (relativePath.startsWith("..") || path95.isAbsolute(relativePath)) {
|
|
86835
86874
|
return false;
|
|
86836
86875
|
}
|
|
86837
86876
|
return true;
|
|
@@ -86844,12 +86883,12 @@ function validatePathForRead2(filePath, workspace) {
|
|
|
86844
86883
|
}
|
|
86845
86884
|
function findRgInEnvPath() {
|
|
86846
86885
|
const searchPath = process.env.PATH ?? "";
|
|
86847
|
-
for (const dir of searchPath.split(
|
|
86886
|
+
for (const dir of searchPath.split(path95.delimiter)) {
|
|
86848
86887
|
if (!dir)
|
|
86849
86888
|
continue;
|
|
86850
86889
|
const isWindows = process.platform === "win32";
|
|
86851
|
-
const candidate =
|
|
86852
|
-
if (
|
|
86890
|
+
const candidate = path95.join(dir, isWindows ? "rg.exe" : "rg");
|
|
86891
|
+
if (fs76.existsSync(candidate))
|
|
86853
86892
|
return candidate;
|
|
86854
86893
|
}
|
|
86855
86894
|
return null;
|
|
@@ -86976,10 +87015,10 @@ function collectFiles(dir, workspace, includeGlobs, excludeGlobs) {
|
|
|
86976
87015
|
return files;
|
|
86977
87016
|
}
|
|
86978
87017
|
try {
|
|
86979
|
-
const entries =
|
|
87018
|
+
const entries = fs76.readdirSync(dir, { withFileTypes: true });
|
|
86980
87019
|
for (const entry of entries) {
|
|
86981
|
-
const fullPath =
|
|
86982
|
-
const relativePath =
|
|
87020
|
+
const fullPath = path95.join(dir, entry.name);
|
|
87021
|
+
const relativePath = path95.relative(workspace, fullPath);
|
|
86983
87022
|
if (!validatePathForRead2(fullPath, workspace)) {
|
|
86984
87023
|
continue;
|
|
86985
87024
|
}
|
|
@@ -87020,13 +87059,13 @@ async function fallbackSearch(opts) {
|
|
|
87020
87059
|
const matches = [];
|
|
87021
87060
|
let total = 0;
|
|
87022
87061
|
for (const file3 of files) {
|
|
87023
|
-
const fullPath =
|
|
87062
|
+
const fullPath = path95.join(opts.workspace, file3);
|
|
87024
87063
|
if (!validatePathForRead2(fullPath, opts.workspace)) {
|
|
87025
87064
|
continue;
|
|
87026
87065
|
}
|
|
87027
87066
|
let stats;
|
|
87028
87067
|
try {
|
|
87029
|
-
stats =
|
|
87068
|
+
stats = fs76.statSync(fullPath);
|
|
87030
87069
|
if (stats.size > MAX_FILE_SIZE_BYTES10) {
|
|
87031
87070
|
continue;
|
|
87032
87071
|
}
|
|
@@ -87035,7 +87074,7 @@ async function fallbackSearch(opts) {
|
|
|
87035
87074
|
}
|
|
87036
87075
|
let content;
|
|
87037
87076
|
try {
|
|
87038
|
-
content =
|
|
87077
|
+
content = fs76.readFileSync(fullPath, "utf-8");
|
|
87039
87078
|
} catch {
|
|
87040
87079
|
continue;
|
|
87041
87080
|
}
|
|
@@ -87147,7 +87186,7 @@ var search = createSwarmTool({
|
|
|
87147
87186
|
message: "Exclude pattern contains invalid Windows-specific sequence"
|
|
87148
87187
|
}, null, 2);
|
|
87149
87188
|
}
|
|
87150
|
-
if (!
|
|
87189
|
+
if (!fs76.existsSync(directory)) {
|
|
87151
87190
|
return JSON.stringify({
|
|
87152
87191
|
error: true,
|
|
87153
87192
|
type: "unknown",
|
|
@@ -87276,8 +87315,8 @@ var set_qa_gates = createSwarmTool({
|
|
|
87276
87315
|
init_zod();
|
|
87277
87316
|
init_path_security();
|
|
87278
87317
|
init_create_tool();
|
|
87279
|
-
import * as
|
|
87280
|
-
import * as
|
|
87318
|
+
import * as fs77 from "node:fs";
|
|
87319
|
+
import * as path96 from "node:path";
|
|
87281
87320
|
var WINDOWS_RESERVED_NAMES4 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
87282
87321
|
function containsWindowsAttacks4(str) {
|
|
87283
87322
|
if (/:[^\\/]/.test(str))
|
|
@@ -87291,14 +87330,14 @@ function containsWindowsAttacks4(str) {
|
|
|
87291
87330
|
}
|
|
87292
87331
|
function isPathInWorkspace4(filePath, workspace) {
|
|
87293
87332
|
try {
|
|
87294
|
-
const resolvedPath =
|
|
87295
|
-
if (!
|
|
87333
|
+
const resolvedPath = path96.resolve(workspace, filePath);
|
|
87334
|
+
if (!fs77.existsSync(resolvedPath)) {
|
|
87296
87335
|
return true;
|
|
87297
87336
|
}
|
|
87298
|
-
const realWorkspace =
|
|
87299
|
-
const realResolvedPath =
|
|
87300
|
-
const relativePath =
|
|
87301
|
-
if (relativePath.startsWith("..") ||
|
|
87337
|
+
const realWorkspace = fs77.realpathSync(workspace);
|
|
87338
|
+
const realResolvedPath = fs77.realpathSync(resolvedPath);
|
|
87339
|
+
const relativePath = path96.relative(realWorkspace, realResolvedPath);
|
|
87340
|
+
if (relativePath.startsWith("..") || path96.isAbsolute(relativePath)) {
|
|
87302
87341
|
return false;
|
|
87303
87342
|
}
|
|
87304
87343
|
return true;
|
|
@@ -87470,7 +87509,7 @@ var suggestPatch = createSwarmTool({
|
|
|
87470
87509
|
message: "changes cannot be empty"
|
|
87471
87510
|
}, null, 2);
|
|
87472
87511
|
}
|
|
87473
|
-
if (!
|
|
87512
|
+
if (!fs77.existsSync(directory)) {
|
|
87474
87513
|
return JSON.stringify({
|
|
87475
87514
|
success: false,
|
|
87476
87515
|
error: true,
|
|
@@ -87506,8 +87545,8 @@ var suggestPatch = createSwarmTool({
|
|
|
87506
87545
|
});
|
|
87507
87546
|
continue;
|
|
87508
87547
|
}
|
|
87509
|
-
const fullPath =
|
|
87510
|
-
if (!
|
|
87548
|
+
const fullPath = path96.resolve(directory, change.file);
|
|
87549
|
+
if (!fs77.existsSync(fullPath)) {
|
|
87511
87550
|
errors5.push({
|
|
87512
87551
|
success: false,
|
|
87513
87552
|
error: true,
|
|
@@ -87521,7 +87560,7 @@ var suggestPatch = createSwarmTool({
|
|
|
87521
87560
|
}
|
|
87522
87561
|
let content;
|
|
87523
87562
|
try {
|
|
87524
|
-
content =
|
|
87563
|
+
content = fs77.readFileSync(fullPath, "utf-8");
|
|
87525
87564
|
} catch (err3) {
|
|
87526
87565
|
errors5.push({
|
|
87527
87566
|
success: false,
|
|
@@ -87768,8 +87807,8 @@ var generate_mutants = createSwarmTool({
|
|
|
87768
87807
|
// src/tools/lint-spec.ts
|
|
87769
87808
|
init_spec_schema();
|
|
87770
87809
|
init_create_tool();
|
|
87771
|
-
import * as
|
|
87772
|
-
import * as
|
|
87810
|
+
import * as fs78 from "node:fs";
|
|
87811
|
+
import * as path97 from "node:path";
|
|
87773
87812
|
var SPEC_FILE_NAME = "spec.md";
|
|
87774
87813
|
var SWARM_DIR2 = ".swarm";
|
|
87775
87814
|
var OBLIGATION_KEYWORDS2 = ["MUST", "SHALL", "SHOULD", "MAY"];
|
|
@@ -87822,8 +87861,8 @@ var lint_spec = createSwarmTool({
|
|
|
87822
87861
|
async execute(_args, directory) {
|
|
87823
87862
|
const errors5 = [];
|
|
87824
87863
|
const warnings = [];
|
|
87825
|
-
const specPath =
|
|
87826
|
-
if (!
|
|
87864
|
+
const specPath = path97.join(directory, SWARM_DIR2, SPEC_FILE_NAME);
|
|
87865
|
+
if (!fs78.existsSync(specPath)) {
|
|
87827
87866
|
const result2 = {
|
|
87828
87867
|
valid: false,
|
|
87829
87868
|
specMtime: null,
|
|
@@ -87842,12 +87881,12 @@ var lint_spec = createSwarmTool({
|
|
|
87842
87881
|
}
|
|
87843
87882
|
let specMtime = null;
|
|
87844
87883
|
try {
|
|
87845
|
-
const stats =
|
|
87884
|
+
const stats = fs78.statSync(specPath);
|
|
87846
87885
|
specMtime = stats.mtime.toISOString();
|
|
87847
87886
|
} catch {}
|
|
87848
87887
|
let content;
|
|
87849
87888
|
try {
|
|
87850
|
-
content =
|
|
87889
|
+
content = fs78.readFileSync(specPath, "utf-8");
|
|
87851
87890
|
} catch (e) {
|
|
87852
87891
|
const result2 = {
|
|
87853
87892
|
valid: false,
|
|
@@ -87892,13 +87931,13 @@ var lint_spec = createSwarmTool({
|
|
|
87892
87931
|
});
|
|
87893
87932
|
// src/tools/mutation-test.ts
|
|
87894
87933
|
init_zod();
|
|
87895
|
-
import * as
|
|
87896
|
-
import * as
|
|
87934
|
+
import * as fs79 from "node:fs";
|
|
87935
|
+
import * as path99 from "node:path";
|
|
87897
87936
|
|
|
87898
87937
|
// src/mutation/engine.ts
|
|
87899
87938
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
87900
|
-
import { unlinkSync as unlinkSync13, writeFileSync as
|
|
87901
|
-
import * as
|
|
87939
|
+
import { unlinkSync as unlinkSync13, writeFileSync as writeFileSync20 } from "node:fs";
|
|
87940
|
+
import * as path98 from "node:path";
|
|
87902
87941
|
|
|
87903
87942
|
// src/mutation/equivalence.ts
|
|
87904
87943
|
function isStaticallyEquivalent(originalCode, mutatedCode) {
|
|
@@ -88033,9 +88072,9 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
|
88033
88072
|
let patchFile;
|
|
88034
88073
|
try {
|
|
88035
88074
|
const safeId2 = patch.id.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
88036
|
-
patchFile =
|
|
88075
|
+
patchFile = path98.join(workingDir, `.mutation_patch_${safeId2}.diff`);
|
|
88037
88076
|
try {
|
|
88038
|
-
|
|
88077
|
+
writeFileSync20(patchFile, patch.patch);
|
|
88039
88078
|
} catch (writeErr) {
|
|
88040
88079
|
error93 = `Failed to write patch file: ${writeErr}`;
|
|
88041
88080
|
outcome = "error";
|
|
@@ -88427,8 +88466,8 @@ var mutation_test = createSwarmTool({
|
|
|
88427
88466
|
];
|
|
88428
88467
|
for (const filePath of uniquePaths) {
|
|
88429
88468
|
try {
|
|
88430
|
-
const resolvedPath =
|
|
88431
|
-
sourceFiles.set(filePath,
|
|
88469
|
+
const resolvedPath = path99.resolve(cwd, filePath);
|
|
88470
|
+
sourceFiles.set(filePath, fs79.readFileSync(resolvedPath, "utf-8"));
|
|
88432
88471
|
} catch {}
|
|
88433
88472
|
}
|
|
88434
88473
|
const report = await executeMutationSuite(typedArgs.patches, typedArgs.test_command, typedArgs.files, cwd, undefined, undefined, sourceFiles.size > 0 ? sourceFiles : undefined);
|
|
@@ -88446,8 +88485,8 @@ var mutation_test = createSwarmTool({
|
|
|
88446
88485
|
init_zod();
|
|
88447
88486
|
init_manager2();
|
|
88448
88487
|
init_detector();
|
|
88449
|
-
import * as
|
|
88450
|
-
import * as
|
|
88488
|
+
import * as fs80 from "node:fs";
|
|
88489
|
+
import * as path100 from "node:path";
|
|
88451
88490
|
init_create_tool();
|
|
88452
88491
|
var MAX_FILE_SIZE2 = 2 * 1024 * 1024;
|
|
88453
88492
|
var BINARY_CHECK_BYTES = 8192;
|
|
@@ -88513,7 +88552,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
88513
88552
|
if (languages?.length) {
|
|
88514
88553
|
const lowerLangs = languages.map((l) => l.toLowerCase());
|
|
88515
88554
|
filesToCheck = filesToCheck.filter((file3) => {
|
|
88516
|
-
const ext =
|
|
88555
|
+
const ext = path100.extname(file3.path).toLowerCase();
|
|
88517
88556
|
const langDef = getLanguageForExtension(ext);
|
|
88518
88557
|
const fileProfile = getProfileForFile(file3.path);
|
|
88519
88558
|
const langId = fileProfile?.id || langDef?.id;
|
|
@@ -88526,7 +88565,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
88526
88565
|
let skippedCount = 0;
|
|
88527
88566
|
for (const fileInfo of filesToCheck) {
|
|
88528
88567
|
const { path: filePath } = fileInfo;
|
|
88529
|
-
const fullPath =
|
|
88568
|
+
const fullPath = path100.isAbsolute(filePath) ? filePath : path100.join(directory, filePath);
|
|
88530
88569
|
const result = {
|
|
88531
88570
|
path: filePath,
|
|
88532
88571
|
language: "",
|
|
@@ -88556,7 +88595,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
88556
88595
|
}
|
|
88557
88596
|
let content;
|
|
88558
88597
|
try {
|
|
88559
|
-
content =
|
|
88598
|
+
content = fs80.readFileSync(fullPath, "utf8");
|
|
88560
88599
|
} catch {
|
|
88561
88600
|
result.skipped_reason = "file_read_error";
|
|
88562
88601
|
skippedCount++;
|
|
@@ -88575,7 +88614,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
88575
88614
|
results.push(result);
|
|
88576
88615
|
continue;
|
|
88577
88616
|
}
|
|
88578
|
-
const ext =
|
|
88617
|
+
const ext = path100.extname(filePath).toLowerCase();
|
|
88579
88618
|
const langDef = getLanguageForExtension(ext);
|
|
88580
88619
|
result.language = profile?.id || langDef?.id || "unknown";
|
|
88581
88620
|
const errors5 = extractSyntaxErrors(parser, content);
|
|
@@ -88667,8 +88706,8 @@ init_zod();
|
|
|
88667
88706
|
init_utils();
|
|
88668
88707
|
init_create_tool();
|
|
88669
88708
|
init_path_security();
|
|
88670
|
-
import * as
|
|
88671
|
-
import * as
|
|
88709
|
+
import * as fs81 from "node:fs";
|
|
88710
|
+
import * as path101 from "node:path";
|
|
88672
88711
|
var MAX_TEXT_LENGTH = 200;
|
|
88673
88712
|
var MAX_FILE_SIZE_BYTES11 = 1024 * 1024;
|
|
88674
88713
|
var SUPPORTED_EXTENSIONS4 = new Set([
|
|
@@ -88734,9 +88773,9 @@ function validatePathsInput(paths, cwd) {
|
|
|
88734
88773
|
return { error: "paths contains path traversal", resolvedPath: null };
|
|
88735
88774
|
}
|
|
88736
88775
|
try {
|
|
88737
|
-
const resolvedPath =
|
|
88738
|
-
const normalizedCwd =
|
|
88739
|
-
const normalizedResolved =
|
|
88776
|
+
const resolvedPath = path101.resolve(paths);
|
|
88777
|
+
const normalizedCwd = path101.resolve(cwd);
|
|
88778
|
+
const normalizedResolved = path101.resolve(resolvedPath);
|
|
88740
88779
|
if (!normalizedResolved.startsWith(normalizedCwd)) {
|
|
88741
88780
|
return {
|
|
88742
88781
|
error: "paths must be within the current working directory",
|
|
@@ -88752,13 +88791,13 @@ function validatePathsInput(paths, cwd) {
|
|
|
88752
88791
|
}
|
|
88753
88792
|
}
|
|
88754
88793
|
function isSupportedExtension(filePath) {
|
|
88755
|
-
const ext =
|
|
88794
|
+
const ext = path101.extname(filePath).toLowerCase();
|
|
88756
88795
|
return SUPPORTED_EXTENSIONS4.has(ext);
|
|
88757
88796
|
}
|
|
88758
88797
|
function findSourceFiles3(dir, files = []) {
|
|
88759
88798
|
let entries;
|
|
88760
88799
|
try {
|
|
88761
|
-
entries =
|
|
88800
|
+
entries = fs81.readdirSync(dir);
|
|
88762
88801
|
} catch {
|
|
88763
88802
|
return files;
|
|
88764
88803
|
}
|
|
@@ -88767,10 +88806,10 @@ function findSourceFiles3(dir, files = []) {
|
|
|
88767
88806
|
if (SKIP_DIRECTORIES5.has(entry)) {
|
|
88768
88807
|
continue;
|
|
88769
88808
|
}
|
|
88770
|
-
const fullPath =
|
|
88809
|
+
const fullPath = path101.join(dir, entry);
|
|
88771
88810
|
let stat6;
|
|
88772
88811
|
try {
|
|
88773
|
-
stat6 =
|
|
88812
|
+
stat6 = fs81.statSync(fullPath);
|
|
88774
88813
|
} catch {
|
|
88775
88814
|
continue;
|
|
88776
88815
|
}
|
|
@@ -88863,7 +88902,7 @@ var todo_extract = createSwarmTool({
|
|
|
88863
88902
|
return JSON.stringify(errorResult, null, 2);
|
|
88864
88903
|
}
|
|
88865
88904
|
const scanPath = resolvedPath;
|
|
88866
|
-
if (!
|
|
88905
|
+
if (!fs81.existsSync(scanPath)) {
|
|
88867
88906
|
const errorResult = {
|
|
88868
88907
|
error: `path not found: ${pathsInput}`,
|
|
88869
88908
|
total: 0,
|
|
@@ -88873,13 +88912,13 @@ var todo_extract = createSwarmTool({
|
|
|
88873
88912
|
return JSON.stringify(errorResult, null, 2);
|
|
88874
88913
|
}
|
|
88875
88914
|
const filesToScan = [];
|
|
88876
|
-
const stat6 =
|
|
88915
|
+
const stat6 = fs81.statSync(scanPath);
|
|
88877
88916
|
if (stat6.isFile()) {
|
|
88878
88917
|
if (isSupportedExtension(scanPath)) {
|
|
88879
88918
|
filesToScan.push(scanPath);
|
|
88880
88919
|
} else {
|
|
88881
88920
|
const errorResult = {
|
|
88882
|
-
error: `unsupported file extension: ${
|
|
88921
|
+
error: `unsupported file extension: ${path101.extname(scanPath)}`,
|
|
88883
88922
|
total: 0,
|
|
88884
88923
|
byPriority: { high: 0, medium: 0, low: 0 },
|
|
88885
88924
|
entries: []
|
|
@@ -88892,11 +88931,11 @@ var todo_extract = createSwarmTool({
|
|
|
88892
88931
|
const allEntries = [];
|
|
88893
88932
|
for (const filePath of filesToScan) {
|
|
88894
88933
|
try {
|
|
88895
|
-
const fileStat =
|
|
88934
|
+
const fileStat = fs81.statSync(filePath);
|
|
88896
88935
|
if (fileStat.size > MAX_FILE_SIZE_BYTES11) {
|
|
88897
88936
|
continue;
|
|
88898
88937
|
}
|
|
88899
|
-
const content =
|
|
88938
|
+
const content = fs81.readFileSync(filePath, "utf-8");
|
|
88900
88939
|
const entries = parseTodoComments(content, filePath, tagsSet);
|
|
88901
88940
|
allEntries.push(...entries);
|
|
88902
88941
|
} catch {}
|
|
@@ -88927,19 +88966,19 @@ init_loader();
|
|
|
88927
88966
|
init_schema();
|
|
88928
88967
|
init_qa_gate_profile();
|
|
88929
88968
|
init_gate_evidence();
|
|
88930
|
-
import * as
|
|
88931
|
-
import * as
|
|
88969
|
+
import * as fs83 from "node:fs";
|
|
88970
|
+
import * as path103 from "node:path";
|
|
88932
88971
|
|
|
88933
88972
|
// src/hooks/diff-scope.ts
|
|
88934
88973
|
init_bun_compat();
|
|
88935
|
-
import * as
|
|
88936
|
-
import * as
|
|
88974
|
+
import * as fs82 from "node:fs";
|
|
88975
|
+
import * as path102 from "node:path";
|
|
88937
88976
|
function getDeclaredScope(taskId, directory) {
|
|
88938
88977
|
try {
|
|
88939
|
-
const planPath =
|
|
88940
|
-
if (!
|
|
88978
|
+
const planPath = path102.join(directory, ".swarm", "plan.json");
|
|
88979
|
+
if (!fs82.existsSync(planPath))
|
|
88941
88980
|
return null;
|
|
88942
|
-
const raw =
|
|
88981
|
+
const raw = fs82.readFileSync(planPath, "utf-8");
|
|
88943
88982
|
const plan = JSON.parse(raw);
|
|
88944
88983
|
for (const phase of plan.phases ?? []) {
|
|
88945
88984
|
for (const task of phase.tasks ?? []) {
|
|
@@ -89055,7 +89094,7 @@ var TIER_3_PATTERNS = [
|
|
|
89055
89094
|
];
|
|
89056
89095
|
function matchesTier3Pattern(files) {
|
|
89057
89096
|
for (const file3 of files) {
|
|
89058
|
-
const fileName =
|
|
89097
|
+
const fileName = path103.basename(file3);
|
|
89059
89098
|
for (const pattern of TIER_3_PATTERNS) {
|
|
89060
89099
|
if (pattern.test(fileName)) {
|
|
89061
89100
|
return true;
|
|
@@ -89069,8 +89108,8 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
89069
89108
|
if (hasActiveTurboMode()) {
|
|
89070
89109
|
const resolvedDir2 = workingDirectory;
|
|
89071
89110
|
try {
|
|
89072
|
-
const planPath =
|
|
89073
|
-
const planRaw =
|
|
89111
|
+
const planPath = path103.join(resolvedDir2, ".swarm", "plan.json");
|
|
89112
|
+
const planRaw = fs83.readFileSync(planPath, "utf-8");
|
|
89074
89113
|
const plan = JSON.parse(planRaw);
|
|
89075
89114
|
for (const planPhase of plan.phases ?? []) {
|
|
89076
89115
|
for (const task of planPhase.tasks ?? []) {
|
|
@@ -89139,8 +89178,8 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
89139
89178
|
}
|
|
89140
89179
|
try {
|
|
89141
89180
|
const resolvedDir2 = workingDirectory;
|
|
89142
|
-
const planPath =
|
|
89143
|
-
const planRaw =
|
|
89181
|
+
const planPath = path103.join(resolvedDir2, ".swarm", "plan.json");
|
|
89182
|
+
const planRaw = fs83.readFileSync(planPath, "utf-8");
|
|
89144
89183
|
const plan = JSON.parse(planRaw);
|
|
89145
89184
|
for (const planPhase of plan.phases ?? []) {
|
|
89146
89185
|
for (const task of planPhase.tasks ?? []) {
|
|
@@ -89297,8 +89336,8 @@ function checkCouncilGate(workingDirectory, taskId) {
|
|
|
89297
89336
|
return { blocked: false, reason: "" };
|
|
89298
89337
|
}
|
|
89299
89338
|
try {
|
|
89300
|
-
const planPath =
|
|
89301
|
-
const planRaw =
|
|
89339
|
+
const planPath = path103.join(workingDirectory, ".swarm", "plan.json");
|
|
89340
|
+
const planRaw = fs83.readFileSync(planPath, "utf-8");
|
|
89302
89341
|
const planObj = JSON.parse(planRaw);
|
|
89303
89342
|
if (planObj.swarm && planObj.title) {
|
|
89304
89343
|
const planId = `${planObj.swarm}-${planObj.title}`.replace(/[^a-zA-Z0-9-_]/g, "_");
|
|
@@ -89388,8 +89427,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
89388
89427
|
};
|
|
89389
89428
|
}
|
|
89390
89429
|
}
|
|
89391
|
-
normalizedDir =
|
|
89392
|
-
const pathParts = normalizedDir.split(
|
|
89430
|
+
normalizedDir = path103.normalize(args2.working_directory);
|
|
89431
|
+
const pathParts = normalizedDir.split(path103.sep);
|
|
89393
89432
|
if (pathParts.includes("..")) {
|
|
89394
89433
|
return {
|
|
89395
89434
|
success: false,
|
|
@@ -89399,11 +89438,11 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
89399
89438
|
]
|
|
89400
89439
|
};
|
|
89401
89440
|
}
|
|
89402
|
-
const resolvedDir =
|
|
89441
|
+
const resolvedDir = path103.resolve(normalizedDir);
|
|
89403
89442
|
try {
|
|
89404
|
-
const realPath =
|
|
89405
|
-
const planPath =
|
|
89406
|
-
if (!
|
|
89443
|
+
const realPath = fs83.realpathSync(resolvedDir);
|
|
89444
|
+
const planPath = path103.join(realPath, ".swarm", "plan.json");
|
|
89445
|
+
if (!fs83.existsSync(planPath)) {
|
|
89407
89446
|
return {
|
|
89408
89447
|
success: false,
|
|
89409
89448
|
message: `Invalid working_directory: plan not found in "${realPath}"`,
|
|
@@ -89434,22 +89473,22 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
89434
89473
|
}
|
|
89435
89474
|
if (args2.status === "in_progress") {
|
|
89436
89475
|
try {
|
|
89437
|
-
const evidencePath =
|
|
89438
|
-
|
|
89439
|
-
const fd =
|
|
89476
|
+
const evidencePath = path103.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
|
|
89477
|
+
fs83.mkdirSync(path103.dirname(evidencePath), { recursive: true });
|
|
89478
|
+
const fd = fs83.openSync(evidencePath, "wx");
|
|
89440
89479
|
let writeOk = false;
|
|
89441
89480
|
try {
|
|
89442
|
-
|
|
89481
|
+
fs83.writeSync(fd, JSON.stringify({
|
|
89443
89482
|
taskId: args2.task_id,
|
|
89444
89483
|
required_gates: ["reviewer", "test_engineer"],
|
|
89445
89484
|
gates: {}
|
|
89446
89485
|
}, null, 2));
|
|
89447
89486
|
writeOk = true;
|
|
89448
89487
|
} finally {
|
|
89449
|
-
|
|
89488
|
+
fs83.closeSync(fd);
|
|
89450
89489
|
if (!writeOk) {
|
|
89451
89490
|
try {
|
|
89452
|
-
|
|
89491
|
+
fs83.unlinkSync(evidencePath);
|
|
89453
89492
|
} catch {}
|
|
89454
89493
|
}
|
|
89455
89494
|
}
|
|
@@ -89459,8 +89498,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
89459
89498
|
recoverTaskStateFromDelegations(args2.task_id);
|
|
89460
89499
|
let phaseRequiresReviewer = true;
|
|
89461
89500
|
try {
|
|
89462
|
-
const planPath =
|
|
89463
|
-
const planRaw =
|
|
89501
|
+
const planPath = path103.join(directory, ".swarm", "plan.json");
|
|
89502
|
+
const planRaw = fs83.readFileSync(planPath, "utf-8");
|
|
89464
89503
|
const plan = JSON.parse(planRaw);
|
|
89465
89504
|
const taskPhase = plan.phases.find((p) => p.tasks.some((t) => t.id === args2.task_id));
|
|
89466
89505
|
if (taskPhase?.required_agents && !taskPhase.required_agents.includes("reviewer")) {
|
|
@@ -89778,8 +89817,8 @@ init_utils2();
|
|
|
89778
89817
|
init_ledger();
|
|
89779
89818
|
init_manager();
|
|
89780
89819
|
init_create_tool();
|
|
89781
|
-
import
|
|
89782
|
-
import
|
|
89820
|
+
import fs84 from "node:fs";
|
|
89821
|
+
import path104 from "node:path";
|
|
89783
89822
|
function derivePlanId5(plan) {
|
|
89784
89823
|
return `${plan.swarm}-${plan.title}`.replace(/[^a-zA-Z0-9-_]/g, "_");
|
|
89785
89824
|
}
|
|
@@ -89830,7 +89869,7 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
89830
89869
|
entries: [evidenceEntry]
|
|
89831
89870
|
};
|
|
89832
89871
|
const filename = "drift-verifier.json";
|
|
89833
|
-
const relativePath =
|
|
89872
|
+
const relativePath = path104.join("evidence", String(phase), filename);
|
|
89834
89873
|
let validatedPath;
|
|
89835
89874
|
try {
|
|
89836
89875
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -89841,12 +89880,12 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
89841
89880
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
89842
89881
|
}, null, 2);
|
|
89843
89882
|
}
|
|
89844
|
-
const evidenceDir =
|
|
89883
|
+
const evidenceDir = path104.dirname(validatedPath);
|
|
89845
89884
|
try {
|
|
89846
|
-
await
|
|
89847
|
-
const tempPath =
|
|
89848
|
-
await
|
|
89849
|
-
await
|
|
89885
|
+
await fs84.promises.mkdir(evidenceDir, { recursive: true });
|
|
89886
|
+
const tempPath = path104.join(evidenceDir, `.${filename}.tmp`);
|
|
89887
|
+
await fs84.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
89888
|
+
await fs84.promises.rename(tempPath, validatedPath);
|
|
89850
89889
|
let snapshotInfo;
|
|
89851
89890
|
let snapshotError;
|
|
89852
89891
|
let qaProfileLocked;
|
|
@@ -89940,8 +89979,8 @@ var write_drift_evidence = createSwarmTool({
|
|
|
89940
89979
|
init_zod();
|
|
89941
89980
|
init_utils2();
|
|
89942
89981
|
init_create_tool();
|
|
89943
|
-
import
|
|
89944
|
-
import
|
|
89982
|
+
import fs85 from "node:fs";
|
|
89983
|
+
import path105 from "node:path";
|
|
89945
89984
|
function normalizeVerdict2(verdict) {
|
|
89946
89985
|
switch (verdict) {
|
|
89947
89986
|
case "APPROVED":
|
|
@@ -89989,7 +90028,7 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
89989
90028
|
entries: [evidenceEntry]
|
|
89990
90029
|
};
|
|
89991
90030
|
const filename = "hallucination-guard.json";
|
|
89992
|
-
const relativePath =
|
|
90031
|
+
const relativePath = path105.join("evidence", String(phase), filename);
|
|
89993
90032
|
let validatedPath;
|
|
89994
90033
|
try {
|
|
89995
90034
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -90000,12 +90039,12 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
90000
90039
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
90001
90040
|
}, null, 2);
|
|
90002
90041
|
}
|
|
90003
|
-
const evidenceDir =
|
|
90042
|
+
const evidenceDir = path105.dirname(validatedPath);
|
|
90004
90043
|
try {
|
|
90005
|
-
await
|
|
90006
|
-
const tempPath =
|
|
90007
|
-
await
|
|
90008
|
-
await
|
|
90044
|
+
await fs85.promises.mkdir(evidenceDir, { recursive: true });
|
|
90045
|
+
const tempPath = path105.join(evidenceDir, `.${filename}.tmp`);
|
|
90046
|
+
await fs85.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
90047
|
+
await fs85.promises.rename(tempPath, validatedPath);
|
|
90009
90048
|
return JSON.stringify({
|
|
90010
90049
|
success: true,
|
|
90011
90050
|
phase,
|
|
@@ -90051,8 +90090,8 @@ var write_hallucination_evidence = createSwarmTool({
|
|
|
90051
90090
|
init_zod();
|
|
90052
90091
|
init_utils2();
|
|
90053
90092
|
init_create_tool();
|
|
90054
|
-
import
|
|
90055
|
-
import
|
|
90093
|
+
import fs86 from "node:fs";
|
|
90094
|
+
import path106 from "node:path";
|
|
90056
90095
|
function normalizeVerdict3(verdict) {
|
|
90057
90096
|
switch (verdict) {
|
|
90058
90097
|
case "PASS":
|
|
@@ -90126,7 +90165,7 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
90126
90165
|
entries: [evidenceEntry]
|
|
90127
90166
|
};
|
|
90128
90167
|
const filename = "mutation-gate.json";
|
|
90129
|
-
const relativePath =
|
|
90168
|
+
const relativePath = path106.join("evidence", String(phase), filename);
|
|
90130
90169
|
let validatedPath;
|
|
90131
90170
|
try {
|
|
90132
90171
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -90137,12 +90176,12 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
90137
90176
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
90138
90177
|
}, null, 2);
|
|
90139
90178
|
}
|
|
90140
|
-
const evidenceDir =
|
|
90179
|
+
const evidenceDir = path106.dirname(validatedPath);
|
|
90141
90180
|
try {
|
|
90142
|
-
await
|
|
90143
|
-
const tempPath =
|
|
90144
|
-
await
|
|
90145
|
-
await
|
|
90181
|
+
await fs86.promises.mkdir(evidenceDir, { recursive: true });
|
|
90182
|
+
const tempPath = path106.join(evidenceDir, `.${filename}.tmp`);
|
|
90183
|
+
await fs86.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
90184
|
+
await fs86.promises.rename(tempPath, validatedPath);
|
|
90146
90185
|
return JSON.stringify({
|
|
90147
90186
|
success: true,
|
|
90148
90187
|
phase,
|
|
@@ -90196,20 +90235,20 @@ init_write_retro();
|
|
|
90196
90235
|
init_utils();
|
|
90197
90236
|
|
|
90198
90237
|
// src/utils/gitignore-warning.ts
|
|
90199
|
-
import * as
|
|
90200
|
-
import * as
|
|
90238
|
+
import * as fs87 from "node:fs";
|
|
90239
|
+
import * as path107 from "node:path";
|
|
90201
90240
|
var _gitignoreWarningEmitted = false;
|
|
90202
90241
|
function findGitRoot(startDir) {
|
|
90203
90242
|
let current = startDir;
|
|
90204
90243
|
while (true) {
|
|
90205
90244
|
try {
|
|
90206
|
-
const gitPath =
|
|
90207
|
-
const stat6 =
|
|
90245
|
+
const gitPath = path107.join(current, ".git");
|
|
90246
|
+
const stat6 = fs87.statSync(gitPath);
|
|
90208
90247
|
if (stat6.isDirectory()) {
|
|
90209
90248
|
return current;
|
|
90210
90249
|
}
|
|
90211
90250
|
} catch {}
|
|
90212
|
-
const parent =
|
|
90251
|
+
const parent = path107.dirname(current);
|
|
90213
90252
|
if (parent === current) {
|
|
90214
90253
|
return null;
|
|
90215
90254
|
}
|
|
@@ -90229,7 +90268,7 @@ function fileCoversSwarm(content) {
|
|
|
90229
90268
|
}
|
|
90230
90269
|
function readFileSafe(filePath) {
|
|
90231
90270
|
try {
|
|
90232
|
-
return
|
|
90271
|
+
return fs87.readFileSync(filePath, "utf8");
|
|
90233
90272
|
} catch {
|
|
90234
90273
|
return null;
|
|
90235
90274
|
}
|
|
@@ -90241,12 +90280,12 @@ function warnIfSwarmNotGitignored(directory, quiet = false) {
|
|
|
90241
90280
|
const gitRoot = findGitRoot(directory);
|
|
90242
90281
|
if (!gitRoot)
|
|
90243
90282
|
return;
|
|
90244
|
-
const gitignoreContent = readFileSafe(
|
|
90283
|
+
const gitignoreContent = readFileSafe(path107.join(gitRoot, ".gitignore"));
|
|
90245
90284
|
if (gitignoreContent !== null && fileCoversSwarm(gitignoreContent)) {
|
|
90246
90285
|
_gitignoreWarningEmitted = true;
|
|
90247
90286
|
return;
|
|
90248
90287
|
}
|
|
90249
|
-
const excludeContent = readFileSafe(
|
|
90288
|
+
const excludeContent = readFileSafe(path107.join(gitRoot, ".git", "info", "exclude"));
|
|
90250
90289
|
if (excludeContent !== null && fileCoversSwarm(excludeContent)) {
|
|
90251
90290
|
_gitignoreWarningEmitted = true;
|
|
90252
90291
|
return;
|
|
@@ -90292,26 +90331,6 @@ ${footerLines.join(`
|
|
|
90292
90331
|
// src/index.ts
|
|
90293
90332
|
init_warning_buffer();
|
|
90294
90333
|
var _heartbeatTimers = new Map;
|
|
90295
|
-
function writeSwarmConfigExampleIfNew(projectDirectory) {
|
|
90296
|
-
try {
|
|
90297
|
-
const swarmDir = path107.join(projectDirectory, ".swarm");
|
|
90298
|
-
const dest = path107.join(swarmDir, "config.example.json");
|
|
90299
|
-
if (fs87.existsSync(dest))
|
|
90300
|
-
return;
|
|
90301
|
-
const example = {
|
|
90302
|
-
agents: Object.fromEntries(Object.entries(DEFAULT_MODELS).filter(([name2]) => name2 !== "default").map(([name2, model]) => [
|
|
90303
|
-
name2,
|
|
90304
|
-
{
|
|
90305
|
-
model,
|
|
90306
|
-
fallback_models: ["opencode/gpt-5-nano", "opencode/big-pickle"]
|
|
90307
|
-
}
|
|
90308
|
-
])),
|
|
90309
|
-
max_iterations: 5
|
|
90310
|
-
};
|
|
90311
|
-
fs87.writeFileSync(dest, `${JSON.stringify(example, null, 2)}
|
|
90312
|
-
`, "utf-8");
|
|
90313
|
-
} catch {}
|
|
90314
|
-
}
|
|
90315
90334
|
var OpenCodeSwarm = async (ctx) => {
|
|
90316
90335
|
try {
|
|
90317
90336
|
return await initializeOpenCodeSwarm(ctx);
|
|
@@ -90383,6 +90402,7 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
90383
90402
|
});
|
|
90384
90403
|
initTelemetry(ctx.directory);
|
|
90385
90404
|
writeSwarmConfigExampleIfNew(ctx.directory);
|
|
90405
|
+
writeProjectConfigIfNew(ctx.directory, config3.quiet);
|
|
90386
90406
|
warnIfSwarmNotGitignored(ctx.directory, config3.quiet);
|
|
90387
90407
|
if (config3.version_check !== false) {
|
|
90388
90408
|
scheduleVersionCheck(package_default.version, (msg) => {
|
|
@@ -90510,7 +90530,7 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
90510
90530
|
const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
|
|
90511
90531
|
preflightTriggerManager = new PTM(automationConfig);
|
|
90512
90532
|
const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
|
|
90513
|
-
const swarmDir =
|
|
90533
|
+
const swarmDir = path108.resolve(ctx.directory, ".swarm");
|
|
90514
90534
|
statusArtifact = new ASA(swarmDir);
|
|
90515
90535
|
statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
|
|
90516
90536
|
if (automationConfig.capabilities?.evidence_auto_summaries === true) {
|