opencode-swarm 6.29.6 → 6.30.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +2 -1
- package/dist/index.js +243 -234
- package/dist/session/snapshot-reader.d.ts +1 -9
- package/dist/state.d.ts +4 -2
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -17453,7 +17453,8 @@ var swarmState = {
|
|
|
17453
17453
|
delegationChains: new Map,
|
|
17454
17454
|
pendingEvents: 0,
|
|
17455
17455
|
lastBudgetPct: 0,
|
|
17456
|
-
agentSessions: new Map
|
|
17456
|
+
agentSessions: new Map,
|
|
17457
|
+
pendingRehydrations: new Set
|
|
17457
17458
|
};
|
|
17458
17459
|
function getAgentSession(sessionId) {
|
|
17459
17460
|
return swarmState.agentSessions.get(sessionId);
|
package/dist/index.js
CHANGED
|
@@ -37604,11 +37604,11 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
37604
37604
|
throw toThrow;
|
|
37605
37605
|
}, "quit_");
|
|
37606
37606
|
var scriptDirectory = "";
|
|
37607
|
-
function locateFile(
|
|
37607
|
+
function locateFile(path46) {
|
|
37608
37608
|
if (Module["locateFile"]) {
|
|
37609
|
-
return Module["locateFile"](
|
|
37609
|
+
return Module["locateFile"](path46, scriptDirectory);
|
|
37610
37610
|
}
|
|
37611
|
-
return scriptDirectory +
|
|
37611
|
+
return scriptDirectory + path46;
|
|
37612
37612
|
}
|
|
37613
37613
|
__name(locateFile, "locateFile");
|
|
37614
37614
|
var readAsync, readBinary;
|
|
@@ -39356,7 +39356,7 @@ var init_runtime = __esm(() => {
|
|
|
39356
39356
|
});
|
|
39357
39357
|
|
|
39358
39358
|
// src/index.ts
|
|
39359
|
-
import * as
|
|
39359
|
+
import * as path56 from "path";
|
|
39360
39360
|
|
|
39361
39361
|
// src/agents/index.ts
|
|
39362
39362
|
init_config();
|
|
@@ -39377,9 +39377,10 @@ var swarmState = {
|
|
|
39377
39377
|
delegationChains: new Map,
|
|
39378
39378
|
pendingEvents: 0,
|
|
39379
39379
|
lastBudgetPct: 0,
|
|
39380
|
-
agentSessions: new Map
|
|
39380
|
+
agentSessions: new Map,
|
|
39381
|
+
pendingRehydrations: new Set
|
|
39381
39382
|
};
|
|
39382
|
-
function startAgentSession(sessionId, agentName, staleDurationMs = 7200000,
|
|
39383
|
+
function startAgentSession(sessionId, agentName, staleDurationMs = 7200000, directory) {
|
|
39383
39384
|
const now = Date.now();
|
|
39384
39385
|
const staleIds = [];
|
|
39385
39386
|
for (const [id, session] of swarmState.agentSessions) {
|
|
@@ -39428,11 +39429,18 @@ function startAgentSession(sessionId, agentName, staleDurationMs = 7200000, _dir
|
|
|
39428
39429
|
swarmState.agentSessions.set(sessionId, sessionState);
|
|
39429
39430
|
swarmState.activeAgent.set(sessionId, agentName);
|
|
39430
39431
|
applyRehydrationCache(sessionState);
|
|
39432
|
+
if (directory) {
|
|
39433
|
+
let rehydrationPromise;
|
|
39434
|
+
rehydrationPromise = rehydrateSessionFromDisk(directory, sessionState).catch(() => {}).finally(() => {
|
|
39435
|
+
swarmState.pendingRehydrations.delete(rehydrationPromise);
|
|
39436
|
+
});
|
|
39437
|
+
swarmState.pendingRehydrations.add(rehydrationPromise);
|
|
39438
|
+
}
|
|
39431
39439
|
}
|
|
39432
39440
|
function getAgentSession(sessionId) {
|
|
39433
39441
|
return swarmState.agentSessions.get(sessionId);
|
|
39434
39442
|
}
|
|
39435
|
-
function ensureAgentSession(sessionId, agentName,
|
|
39443
|
+
function ensureAgentSession(sessionId, agentName, directory) {
|
|
39436
39444
|
const now = Date.now();
|
|
39437
39445
|
let session = swarmState.agentSessions.get(sessionId);
|
|
39438
39446
|
if (session) {
|
|
@@ -39532,7 +39540,7 @@ function ensureAgentSession(sessionId, agentName, _directory) {
|
|
|
39532
39540
|
session.lastToolCallTime = now;
|
|
39533
39541
|
return session;
|
|
39534
39542
|
}
|
|
39535
|
-
startAgentSession(sessionId, agentName ?? "unknown", 7200000);
|
|
39543
|
+
startAgentSession(sessionId, agentName ?? "unknown", 7200000, directory);
|
|
39536
39544
|
session = swarmState.agentSessions.get(sessionId);
|
|
39537
39545
|
if (!session) {
|
|
39538
39546
|
throw new Error(`Failed to create guardrail session for ${sessionId}`);
|
|
@@ -39761,6 +39769,10 @@ function applyRehydrationCache(session) {
|
|
|
39761
39769
|
}
|
|
39762
39770
|
}
|
|
39763
39771
|
}
|
|
39772
|
+
async function rehydrateSessionFromDisk(directory, session) {
|
|
39773
|
+
await buildRehydrationCache(directory);
|
|
39774
|
+
applyRehydrationCache(session);
|
|
39775
|
+
}
|
|
39764
39776
|
function hasActiveTurboMode() {
|
|
39765
39777
|
for (const [_sessionId, session] of swarmState.agentSessions) {
|
|
39766
39778
|
if (session.turboMode === true) {
|
|
@@ -49897,6 +49909,8 @@ ${joined}
|
|
|
49897
49909
|
` + textPart2.text;
|
|
49898
49910
|
}
|
|
49899
49911
|
session.pendingAdvisoryMessages = [];
|
|
49912
|
+
} else if (!isArchitectSession && session && (session.pendingAdvisoryMessages?.length ?? 0) > 0) {
|
|
49913
|
+
session.pendingAdvisoryMessages = [];
|
|
49900
49914
|
}
|
|
49901
49915
|
if (isArchitectSession && session && session.architectWriteCount > session.selfCodingWarnedAtCount) {
|
|
49902
49916
|
let targetSystemMessage = systemMessages[0];
|
|
@@ -52565,19 +52579,38 @@ import * as path33 from "path";
|
|
|
52565
52579
|
|
|
52566
52580
|
// src/hooks/spawn-helper.ts
|
|
52567
52581
|
import { spawn } from "child_process";
|
|
52582
|
+
var WIN32_CMD_BINARIES = new Set(["npm", "npx", "pnpm", "yarn"]);
|
|
52568
52583
|
function spawnAsync(command, cwd, timeoutMs) {
|
|
52569
52584
|
return new Promise((resolve11) => {
|
|
52570
52585
|
try {
|
|
52571
|
-
const [
|
|
52586
|
+
const [rawCmd, ...args2] = command;
|
|
52587
|
+
const cmd = process.platform === "win32" && WIN32_CMD_BINARIES.has(rawCmd) && !rawCmd.includes(".") ? `${rawCmd}.cmd` : rawCmd;
|
|
52572
52588
|
const proc = spawn(cmd, args2, { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
52573
52589
|
let stdout = "";
|
|
52574
52590
|
let stderr = "";
|
|
52575
52591
|
let done = false;
|
|
52592
|
+
const MAX_OUTPUT = 512 * 1024;
|
|
52576
52593
|
proc.stdout.on("data", (d) => {
|
|
52577
|
-
stdout
|
|
52594
|
+
if (stdout.length < MAX_OUTPUT) {
|
|
52595
|
+
stdout += d;
|
|
52596
|
+
if (stdout.length >= MAX_OUTPUT) {
|
|
52597
|
+
stdout = stdout.slice(0, MAX_OUTPUT);
|
|
52598
|
+
try {
|
|
52599
|
+
proc.stdout.destroy();
|
|
52600
|
+
} catch {}
|
|
52601
|
+
}
|
|
52602
|
+
}
|
|
52578
52603
|
});
|
|
52579
52604
|
proc.stderr.on("data", (d) => {
|
|
52580
|
-
stderr
|
|
52605
|
+
if (stderr.length < MAX_OUTPUT) {
|
|
52606
|
+
stderr += d;
|
|
52607
|
+
if (stderr.length >= MAX_OUTPUT) {
|
|
52608
|
+
stderr = stderr.slice(0, MAX_OUTPUT);
|
|
52609
|
+
try {
|
|
52610
|
+
proc.stderr.destroy();
|
|
52611
|
+
} catch {}
|
|
52612
|
+
}
|
|
52613
|
+
}
|
|
52581
52614
|
});
|
|
52582
52615
|
const timer = setTimeout(() => {
|
|
52583
52616
|
if (done)
|
|
@@ -52616,19 +52649,31 @@ function spawnAsync(command, cwd, timeoutMs) {
|
|
|
52616
52649
|
|
|
52617
52650
|
// src/hooks/incremental-verify.ts
|
|
52618
52651
|
var emittedSkipAdvisories = new Set;
|
|
52652
|
+
function detectPackageManager(projectDir) {
|
|
52653
|
+
if (fs20.existsSync(path33.join(projectDir, "bun.lockb")))
|
|
52654
|
+
return "bun";
|
|
52655
|
+
if (fs20.existsSync(path33.join(projectDir, "pnpm-lock.yaml")))
|
|
52656
|
+
return "pnpm";
|
|
52657
|
+
if (fs20.existsSync(path33.join(projectDir, "yarn.lock")))
|
|
52658
|
+
return "yarn";
|
|
52659
|
+
if (fs20.existsSync(path33.join(projectDir, "package-lock.json")))
|
|
52660
|
+
return "npm";
|
|
52661
|
+
return "bun";
|
|
52662
|
+
}
|
|
52619
52663
|
function detectTypecheckCommand(projectDir) {
|
|
52620
52664
|
const pkgPath = path33.join(projectDir, "package.json");
|
|
52621
52665
|
if (fs20.existsSync(pkgPath)) {
|
|
52622
52666
|
try {
|
|
52623
52667
|
const pkg = JSON.parse(fs20.readFileSync(pkgPath, "utf8"));
|
|
52624
52668
|
const scripts = pkg.scripts;
|
|
52625
|
-
if (scripts?.typecheck)
|
|
52626
|
-
|
|
52627
|
-
|
|
52628
|
-
|
|
52629
|
-
|
|
52630
|
-
|
|
52631
|
-
};
|
|
52669
|
+
if (scripts?.typecheck) {
|
|
52670
|
+
const pm = detectPackageManager(projectDir);
|
|
52671
|
+
return { command: [pm, "run", "typecheck"], language: "typescript" };
|
|
52672
|
+
}
|
|
52673
|
+
if (scripts?.["type-check"]) {
|
|
52674
|
+
const pm = detectPackageManager(projectDir);
|
|
52675
|
+
return { command: [pm, "run", "type-check"], language: "typescript" };
|
|
52676
|
+
}
|
|
52632
52677
|
const deps = {
|
|
52633
52678
|
...pkg.dependencies,
|
|
52634
52679
|
...pkg.devDependencies
|
|
@@ -52683,7 +52728,11 @@ function createIncrementalVerifyHook(config3, projectDir, injectMessage) {
|
|
|
52683
52728
|
}
|
|
52684
52729
|
let commandToRun = null;
|
|
52685
52730
|
if (config3.command != null) {
|
|
52686
|
-
|
|
52731
|
+
if (Array.isArray(config3.command)) {
|
|
52732
|
+
commandToRun = config3.command;
|
|
52733
|
+
} else {
|
|
52734
|
+
commandToRun = config3.command.split(" ");
|
|
52735
|
+
}
|
|
52687
52736
|
} else {
|
|
52688
52737
|
const detected = detectTypecheckCommand(projectDir);
|
|
52689
52738
|
if (detected === null) {
|
|
@@ -53858,7 +53907,6 @@ init_config_doctor();
|
|
|
53858
53907
|
|
|
53859
53908
|
// src/session/snapshot-reader.ts
|
|
53860
53909
|
init_utils2();
|
|
53861
|
-
import path37 from "path";
|
|
53862
53910
|
var VALID_TASK_WORKFLOW_STATES = [
|
|
53863
53911
|
"idle",
|
|
53864
53912
|
"coder_delegated",
|
|
@@ -53955,7 +54003,10 @@ async function readSnapshot(directory) {
|
|
|
53955
54003
|
return null;
|
|
53956
54004
|
}
|
|
53957
54005
|
}
|
|
53958
|
-
function rehydrateState(snapshot) {
|
|
54006
|
+
async function rehydrateState(snapshot) {
|
|
54007
|
+
if (swarmState.pendingRehydrations.size > 0) {
|
|
54008
|
+
await Promise.allSettled([...swarmState.pendingRehydrations]);
|
|
54009
|
+
}
|
|
53959
54010
|
swarmState.toolAggregates.clear();
|
|
53960
54011
|
swarmState.activeAgent.clear();
|
|
53961
54012
|
swarmState.delegationChains.clear();
|
|
@@ -53981,57 +54032,15 @@ function rehydrateState(snapshot) {
|
|
|
53981
54032
|
}
|
|
53982
54033
|
}
|
|
53983
54034
|
}
|
|
53984
|
-
async function reconcileTaskStatesFromPlan(directory) {
|
|
53985
|
-
let raw;
|
|
53986
|
-
try {
|
|
53987
|
-
raw = await Bun.file(path37.join(directory, ".swarm/plan.json")).text();
|
|
53988
|
-
} catch {
|
|
53989
|
-
return;
|
|
53990
|
-
}
|
|
53991
|
-
let plan;
|
|
53992
|
-
try {
|
|
53993
|
-
plan = JSON.parse(raw);
|
|
53994
|
-
} catch {
|
|
53995
|
-
return;
|
|
53996
|
-
}
|
|
53997
|
-
if (!plan?.phases || !Array.isArray(plan.phases)) {
|
|
53998
|
-
return;
|
|
53999
|
-
}
|
|
54000
|
-
for (const phase of plan.phases) {
|
|
54001
|
-
if (!phase?.tasks || !Array.isArray(phase.tasks)) {
|
|
54002
|
-
continue;
|
|
54003
|
-
}
|
|
54004
|
-
for (const task of phase.tasks) {
|
|
54005
|
-
if (!task?.id || typeof task.id !== "string") {
|
|
54006
|
-
continue;
|
|
54007
|
-
}
|
|
54008
|
-
const taskId = task.id;
|
|
54009
|
-
const planStatus = task.status;
|
|
54010
|
-
for (const session of swarmState.agentSessions.values()) {
|
|
54011
|
-
const currentState = getTaskState(session, taskId);
|
|
54012
|
-
if (planStatus === "completed" && currentState !== "tests_run" && currentState !== "complete") {
|
|
54013
|
-
try {
|
|
54014
|
-
advanceTaskState(session, taskId, "tests_run");
|
|
54015
|
-
} catch {}
|
|
54016
|
-
} else if (planStatus === "in_progress" && currentState === "idle") {
|
|
54017
|
-
try {
|
|
54018
|
-
advanceTaskState(session, taskId, "coder_delegated");
|
|
54019
|
-
} catch {}
|
|
54020
|
-
}
|
|
54021
|
-
}
|
|
54022
|
-
}
|
|
54023
|
-
}
|
|
54024
|
-
}
|
|
54025
54035
|
async function loadSnapshot(directory) {
|
|
54026
54036
|
try {
|
|
54027
54037
|
await buildRehydrationCache(directory);
|
|
54028
54038
|
const snapshot = await readSnapshot(directory);
|
|
54029
54039
|
if (snapshot !== null) {
|
|
54030
|
-
rehydrateState(snapshot);
|
|
54040
|
+
await rehydrateState(snapshot);
|
|
54031
54041
|
for (const session of swarmState.agentSessions.values()) {
|
|
54032
54042
|
applyRehydrationCache(session);
|
|
54033
54043
|
}
|
|
54034
|
-
await reconcileTaskStatesFromPlan(directory);
|
|
54035
54044
|
}
|
|
54036
54045
|
} catch {}
|
|
54037
54046
|
}
|
|
@@ -54211,7 +54220,7 @@ var build_check = createSwarmTool({
|
|
|
54211
54220
|
init_dist();
|
|
54212
54221
|
init_create_tool();
|
|
54213
54222
|
import * as fs24 from "fs";
|
|
54214
|
-
import * as
|
|
54223
|
+
import * as path37 from "path";
|
|
54215
54224
|
var EVIDENCE_DIR = ".swarm/evidence";
|
|
54216
54225
|
var TASK_ID_PATTERN2 = /^\d+\.\d+(\.\d+)*$/;
|
|
54217
54226
|
function isValidTaskId3(taskId) {
|
|
@@ -54228,9 +54237,9 @@ function isValidTaskId3(taskId) {
|
|
|
54228
54237
|
return TASK_ID_PATTERN2.test(taskId);
|
|
54229
54238
|
}
|
|
54230
54239
|
function isPathWithinSwarm(filePath, workspaceRoot) {
|
|
54231
|
-
const normalizedWorkspace =
|
|
54232
|
-
const swarmPath =
|
|
54233
|
-
const normalizedPath =
|
|
54240
|
+
const normalizedWorkspace = path37.resolve(workspaceRoot);
|
|
54241
|
+
const swarmPath = path37.join(normalizedWorkspace, ".swarm", "evidence");
|
|
54242
|
+
const normalizedPath = path37.resolve(filePath);
|
|
54234
54243
|
return normalizedPath.startsWith(swarmPath);
|
|
54235
54244
|
}
|
|
54236
54245
|
function readEvidenceFile(evidencePath) {
|
|
@@ -54291,7 +54300,7 @@ var check_gate_status = createSwarmTool({
|
|
|
54291
54300
|
};
|
|
54292
54301
|
return JSON.stringify(errorResult, null, 2);
|
|
54293
54302
|
}
|
|
54294
|
-
const evidencePath =
|
|
54303
|
+
const evidencePath = path37.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
|
|
54295
54304
|
if (!isPathWithinSwarm(evidencePath, directory)) {
|
|
54296
54305
|
const errorResult = {
|
|
54297
54306
|
taskId: taskIdInput,
|
|
@@ -54352,7 +54361,7 @@ init_tool();
|
|
|
54352
54361
|
init_create_tool();
|
|
54353
54362
|
import { spawnSync } from "child_process";
|
|
54354
54363
|
import * as fs25 from "fs";
|
|
54355
|
-
import * as
|
|
54364
|
+
import * as path38 from "path";
|
|
54356
54365
|
var CHECKPOINT_LOG_PATH = ".swarm/checkpoints.json";
|
|
54357
54366
|
var MAX_LABEL_LENGTH = 100;
|
|
54358
54367
|
var GIT_TIMEOUT_MS = 30000;
|
|
@@ -54403,7 +54412,7 @@ function validateLabel(label) {
|
|
|
54403
54412
|
return null;
|
|
54404
54413
|
}
|
|
54405
54414
|
function getCheckpointLogPath(directory) {
|
|
54406
|
-
return
|
|
54415
|
+
return path38.join(directory, CHECKPOINT_LOG_PATH);
|
|
54407
54416
|
}
|
|
54408
54417
|
function readCheckpointLog(directory) {
|
|
54409
54418
|
const logPath = getCheckpointLogPath(directory);
|
|
@@ -54421,7 +54430,7 @@ function readCheckpointLog(directory) {
|
|
|
54421
54430
|
}
|
|
54422
54431
|
function writeCheckpointLog(log2, directory) {
|
|
54423
54432
|
const logPath = getCheckpointLogPath(directory);
|
|
54424
|
-
const dir =
|
|
54433
|
+
const dir = path38.dirname(logPath);
|
|
54425
54434
|
if (!fs25.existsSync(dir)) {
|
|
54426
54435
|
fs25.mkdirSync(dir, { recursive: true });
|
|
54427
54436
|
}
|
|
@@ -54629,7 +54638,7 @@ var checkpoint = createSwarmTool({
|
|
|
54629
54638
|
init_dist();
|
|
54630
54639
|
init_create_tool();
|
|
54631
54640
|
import * as fs26 from "fs";
|
|
54632
|
-
import * as
|
|
54641
|
+
import * as path39 from "path";
|
|
54633
54642
|
var MAX_FILE_SIZE_BYTES2 = 256 * 1024;
|
|
54634
54643
|
var DEFAULT_DAYS = 90;
|
|
54635
54644
|
var DEFAULT_TOP_N = 20;
|
|
@@ -54773,7 +54782,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
54773
54782
|
const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
|
|
54774
54783
|
const filteredChurn = new Map;
|
|
54775
54784
|
for (const [file3, count] of churnMap) {
|
|
54776
|
-
const ext =
|
|
54785
|
+
const ext = path39.extname(file3).toLowerCase();
|
|
54777
54786
|
if (extSet.has(ext)) {
|
|
54778
54787
|
filteredChurn.set(file3, count);
|
|
54779
54788
|
}
|
|
@@ -54784,7 +54793,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
54784
54793
|
for (const [file3, churnCount] of filteredChurn) {
|
|
54785
54794
|
let fullPath = file3;
|
|
54786
54795
|
if (!fs26.existsSync(fullPath)) {
|
|
54787
|
-
fullPath =
|
|
54796
|
+
fullPath = path39.join(cwd, file3);
|
|
54788
54797
|
}
|
|
54789
54798
|
const complexity = getComplexityForFile(fullPath);
|
|
54790
54799
|
if (complexity !== null) {
|
|
@@ -54932,7 +54941,7 @@ var complexity_hotspots = createSwarmTool({
|
|
|
54932
54941
|
// src/tools/declare-scope.ts
|
|
54933
54942
|
init_tool();
|
|
54934
54943
|
import * as fs27 from "fs";
|
|
54935
|
-
import * as
|
|
54944
|
+
import * as path40 from "path";
|
|
54936
54945
|
init_create_tool();
|
|
54937
54946
|
function validateTaskIdFormat(taskId) {
|
|
54938
54947
|
const taskIdPattern = /^\d+\.\d+(\.\d+)*$/;
|
|
@@ -55011,8 +55020,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
55011
55020
|
};
|
|
55012
55021
|
}
|
|
55013
55022
|
}
|
|
55014
|
-
normalizedDir =
|
|
55015
|
-
const pathParts = normalizedDir.split(
|
|
55023
|
+
normalizedDir = path40.normalize(args2.working_directory);
|
|
55024
|
+
const pathParts = normalizedDir.split(path40.sep);
|
|
55016
55025
|
if (pathParts.includes("..")) {
|
|
55017
55026
|
return {
|
|
55018
55027
|
success: false,
|
|
@@ -55022,10 +55031,10 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
55022
55031
|
]
|
|
55023
55032
|
};
|
|
55024
55033
|
}
|
|
55025
|
-
const resolvedDir =
|
|
55034
|
+
const resolvedDir = path40.resolve(normalizedDir);
|
|
55026
55035
|
try {
|
|
55027
55036
|
const realPath = fs27.realpathSync(resolvedDir);
|
|
55028
|
-
const planPath2 =
|
|
55037
|
+
const planPath2 = path40.join(realPath, ".swarm", "plan.json");
|
|
55029
55038
|
if (!fs27.existsSync(planPath2)) {
|
|
55030
55039
|
return {
|
|
55031
55040
|
success: false,
|
|
@@ -55046,7 +55055,7 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
55046
55055
|
}
|
|
55047
55056
|
}
|
|
55048
55057
|
const directory = normalizedDir ?? fallbackDir ?? process.cwd();
|
|
55049
|
-
const planPath =
|
|
55058
|
+
const planPath = path40.resolve(directory, ".swarm", "plan.json");
|
|
55050
55059
|
if (!fs27.existsSync(planPath)) {
|
|
55051
55060
|
return {
|
|
55052
55061
|
success: false,
|
|
@@ -55136,20 +55145,20 @@ function validateBase(base) {
|
|
|
55136
55145
|
function validatePaths(paths) {
|
|
55137
55146
|
if (!paths)
|
|
55138
55147
|
return null;
|
|
55139
|
-
for (const
|
|
55140
|
-
if (!
|
|
55148
|
+
for (const path41 of paths) {
|
|
55149
|
+
if (!path41 || path41.length === 0) {
|
|
55141
55150
|
return "empty path not allowed";
|
|
55142
55151
|
}
|
|
55143
|
-
if (
|
|
55152
|
+
if (path41.length > MAX_PATH_LENGTH) {
|
|
55144
55153
|
return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
|
|
55145
55154
|
}
|
|
55146
|
-
if (SHELL_METACHARACTERS2.test(
|
|
55155
|
+
if (SHELL_METACHARACTERS2.test(path41)) {
|
|
55147
55156
|
return "path contains shell metacharacters";
|
|
55148
55157
|
}
|
|
55149
|
-
if (
|
|
55158
|
+
if (path41.startsWith("-")) {
|
|
55150
55159
|
return 'path cannot start with "-" (option-like arguments not allowed)';
|
|
55151
55160
|
}
|
|
55152
|
-
if (CONTROL_CHAR_PATTERN2.test(
|
|
55161
|
+
if (CONTROL_CHAR_PATTERN2.test(path41)) {
|
|
55153
55162
|
return "path contains control characters";
|
|
55154
55163
|
}
|
|
55155
55164
|
}
|
|
@@ -55229,8 +55238,8 @@ var diff = tool({
|
|
|
55229
55238
|
if (parts2.length >= 3) {
|
|
55230
55239
|
const additions = parseInt(parts2[0], 10) || 0;
|
|
55231
55240
|
const deletions = parseInt(parts2[1], 10) || 0;
|
|
55232
|
-
const
|
|
55233
|
-
files.push({ path:
|
|
55241
|
+
const path41 = parts2[2];
|
|
55242
|
+
files.push({ path: path41, additions, deletions });
|
|
55234
55243
|
}
|
|
55235
55244
|
}
|
|
55236
55245
|
const contractChanges = [];
|
|
@@ -55460,7 +55469,7 @@ Use these as DOMAIN values when delegating to @sme.`;
|
|
|
55460
55469
|
init_dist();
|
|
55461
55470
|
init_create_tool();
|
|
55462
55471
|
import * as fs28 from "fs";
|
|
55463
|
-
import * as
|
|
55472
|
+
import * as path41 from "path";
|
|
55464
55473
|
var MAX_FILE_SIZE_BYTES3 = 1024 * 1024;
|
|
55465
55474
|
var MAX_EVIDENCE_FILES = 1000;
|
|
55466
55475
|
var EVIDENCE_DIR2 = ".swarm/evidence";
|
|
@@ -55490,9 +55499,9 @@ function validateRequiredTypes(input) {
|
|
|
55490
55499
|
return null;
|
|
55491
55500
|
}
|
|
55492
55501
|
function isPathWithinSwarm2(filePath, cwd) {
|
|
55493
|
-
const normalizedCwd =
|
|
55494
|
-
const swarmPath =
|
|
55495
|
-
const normalizedPath =
|
|
55502
|
+
const normalizedCwd = path41.resolve(cwd);
|
|
55503
|
+
const swarmPath = path41.join(normalizedCwd, ".swarm");
|
|
55504
|
+
const normalizedPath = path41.resolve(filePath);
|
|
55496
55505
|
return normalizedPath.startsWith(swarmPath);
|
|
55497
55506
|
}
|
|
55498
55507
|
function parseCompletedTasks(planContent) {
|
|
@@ -55522,10 +55531,10 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
55522
55531
|
if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
|
|
55523
55532
|
continue;
|
|
55524
55533
|
}
|
|
55525
|
-
const filePath =
|
|
55534
|
+
const filePath = path41.join(evidenceDir, filename);
|
|
55526
55535
|
try {
|
|
55527
|
-
const resolvedPath =
|
|
55528
|
-
const evidenceDirResolved =
|
|
55536
|
+
const resolvedPath = path41.resolve(filePath);
|
|
55537
|
+
const evidenceDirResolved = path41.resolve(evidenceDir);
|
|
55529
55538
|
if (!resolvedPath.startsWith(evidenceDirResolved)) {
|
|
55530
55539
|
continue;
|
|
55531
55540
|
}
|
|
@@ -55643,7 +55652,7 @@ var evidence_check = createSwarmTool({
|
|
|
55643
55652
|
return JSON.stringify(errorResult, null, 2);
|
|
55644
55653
|
}
|
|
55645
55654
|
const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
|
|
55646
|
-
const planPath =
|
|
55655
|
+
const planPath = path41.join(cwd, PLAN_FILE);
|
|
55647
55656
|
if (!isPathWithinSwarm2(planPath, cwd)) {
|
|
55648
55657
|
const errorResult = {
|
|
55649
55658
|
error: "plan file path validation failed",
|
|
@@ -55675,7 +55684,7 @@ var evidence_check = createSwarmTool({
|
|
|
55675
55684
|
};
|
|
55676
55685
|
return JSON.stringify(result2, null, 2);
|
|
55677
55686
|
}
|
|
55678
|
-
const evidenceDir =
|
|
55687
|
+
const evidenceDir = path41.join(cwd, EVIDENCE_DIR2);
|
|
55679
55688
|
const evidence = readEvidenceFiles(evidenceDir, cwd);
|
|
55680
55689
|
const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
|
|
55681
55690
|
const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
|
|
@@ -55693,7 +55702,7 @@ var evidence_check = createSwarmTool({
|
|
|
55693
55702
|
init_tool();
|
|
55694
55703
|
init_create_tool();
|
|
55695
55704
|
import * as fs29 from "fs";
|
|
55696
|
-
import * as
|
|
55705
|
+
import * as path42 from "path";
|
|
55697
55706
|
var EXT_MAP = {
|
|
55698
55707
|
python: ".py",
|
|
55699
55708
|
py: ".py",
|
|
@@ -55774,12 +55783,12 @@ var extract_code_blocks = createSwarmTool({
|
|
|
55774
55783
|
if (prefix) {
|
|
55775
55784
|
filename = `${prefix}_${filename}`;
|
|
55776
55785
|
}
|
|
55777
|
-
let filepath =
|
|
55778
|
-
const base =
|
|
55779
|
-
const ext =
|
|
55786
|
+
let filepath = path42.join(targetDir, filename);
|
|
55787
|
+
const base = path42.basename(filepath, path42.extname(filepath));
|
|
55788
|
+
const ext = path42.extname(filepath);
|
|
55780
55789
|
let counter = 1;
|
|
55781
55790
|
while (fs29.existsSync(filepath)) {
|
|
55782
|
-
filepath =
|
|
55791
|
+
filepath = path42.join(targetDir, `${base}_${counter}${ext}`);
|
|
55783
55792
|
counter++;
|
|
55784
55793
|
}
|
|
55785
55794
|
try {
|
|
@@ -55897,7 +55906,7 @@ var gitingest = tool({
|
|
|
55897
55906
|
// src/tools/imports.ts
|
|
55898
55907
|
init_dist();
|
|
55899
55908
|
import * as fs30 from "fs";
|
|
55900
|
-
import * as
|
|
55909
|
+
import * as path43 from "path";
|
|
55901
55910
|
var MAX_FILE_PATH_LENGTH2 = 500;
|
|
55902
55911
|
var MAX_SYMBOL_LENGTH = 256;
|
|
55903
55912
|
var MAX_FILE_SIZE_BYTES4 = 1024 * 1024;
|
|
@@ -55951,7 +55960,7 @@ function validateSymbolInput(symbol3) {
|
|
|
55951
55960
|
return null;
|
|
55952
55961
|
}
|
|
55953
55962
|
function isBinaryFile2(filePath, buffer) {
|
|
55954
|
-
const ext =
|
|
55963
|
+
const ext = path43.extname(filePath).toLowerCase();
|
|
55955
55964
|
if (ext === ".json" || ext === ".md" || ext === ".txt") {
|
|
55956
55965
|
return false;
|
|
55957
55966
|
}
|
|
@@ -55975,15 +55984,15 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
55975
55984
|
const imports = [];
|
|
55976
55985
|
let _resolvedTarget;
|
|
55977
55986
|
try {
|
|
55978
|
-
_resolvedTarget =
|
|
55987
|
+
_resolvedTarget = path43.resolve(targetFile);
|
|
55979
55988
|
} catch {
|
|
55980
55989
|
_resolvedTarget = targetFile;
|
|
55981
55990
|
}
|
|
55982
|
-
const targetBasename =
|
|
55991
|
+
const targetBasename = path43.basename(targetFile, path43.extname(targetFile));
|
|
55983
55992
|
const targetWithExt = targetFile;
|
|
55984
55993
|
const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
55985
|
-
const normalizedTargetWithExt =
|
|
55986
|
-
const normalizedTargetWithoutExt =
|
|
55994
|
+
const normalizedTargetWithExt = path43.normalize(targetWithExt).replace(/\\/g, "/");
|
|
55995
|
+
const normalizedTargetWithoutExt = path43.normalize(targetWithoutExt).replace(/\\/g, "/");
|
|
55987
55996
|
const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
|
|
55988
55997
|
for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
|
|
55989
55998
|
const modulePath = match[1] || match[2] || match[3];
|
|
@@ -56006,9 +56015,9 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
56006
56015
|
}
|
|
56007
56016
|
const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
|
|
56008
56017
|
let isMatch = false;
|
|
56009
|
-
const _targetDir =
|
|
56010
|
-
const targetExt =
|
|
56011
|
-
const targetBasenameNoExt =
|
|
56018
|
+
const _targetDir = path43.dirname(targetFile);
|
|
56019
|
+
const targetExt = path43.extname(targetFile);
|
|
56020
|
+
const targetBasenameNoExt = path43.basename(targetFile, targetExt);
|
|
56012
56021
|
const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
56013
56022
|
const moduleName = modulePath.split(/[/\\]/).pop() || "";
|
|
56014
56023
|
const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
@@ -56076,10 +56085,10 @@ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFile
|
|
|
56076
56085
|
entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
|
56077
56086
|
for (const entry of entries) {
|
|
56078
56087
|
if (SKIP_DIRECTORIES2.has(entry)) {
|
|
56079
|
-
stats.skippedDirs.push(
|
|
56088
|
+
stats.skippedDirs.push(path43.join(dir, entry));
|
|
56080
56089
|
continue;
|
|
56081
56090
|
}
|
|
56082
|
-
const fullPath =
|
|
56091
|
+
const fullPath = path43.join(dir, entry);
|
|
56083
56092
|
let stat2;
|
|
56084
56093
|
try {
|
|
56085
56094
|
stat2 = fs30.statSync(fullPath);
|
|
@@ -56093,7 +56102,7 @@ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFile
|
|
|
56093
56102
|
if (stat2.isDirectory()) {
|
|
56094
56103
|
findSourceFiles(fullPath, files, stats);
|
|
56095
56104
|
} else if (stat2.isFile()) {
|
|
56096
|
-
const ext =
|
|
56105
|
+
const ext = path43.extname(fullPath).toLowerCase();
|
|
56097
56106
|
if (SUPPORTED_EXTENSIONS.includes(ext)) {
|
|
56098
56107
|
files.push(fullPath);
|
|
56099
56108
|
}
|
|
@@ -56149,7 +56158,7 @@ var imports = tool({
|
|
|
56149
56158
|
return JSON.stringify(errorResult, null, 2);
|
|
56150
56159
|
}
|
|
56151
56160
|
try {
|
|
56152
|
-
const targetFile =
|
|
56161
|
+
const targetFile = path43.resolve(file3);
|
|
56153
56162
|
if (!fs30.existsSync(targetFile)) {
|
|
56154
56163
|
const errorResult = {
|
|
56155
56164
|
error: `target file not found: ${file3}`,
|
|
@@ -56171,7 +56180,7 @@ var imports = tool({
|
|
|
56171
56180
|
};
|
|
56172
56181
|
return JSON.stringify(errorResult, null, 2);
|
|
56173
56182
|
}
|
|
56174
|
-
const baseDir =
|
|
56183
|
+
const baseDir = path43.dirname(targetFile);
|
|
56175
56184
|
const scanStats = {
|
|
56176
56185
|
skippedDirs: [],
|
|
56177
56186
|
skippedFiles: 0,
|
|
@@ -56493,7 +56502,7 @@ init_config();
|
|
|
56493
56502
|
init_schema();
|
|
56494
56503
|
init_manager();
|
|
56495
56504
|
import * as fs31 from "fs";
|
|
56496
|
-
import * as
|
|
56505
|
+
import * as path44 from "path";
|
|
56497
56506
|
init_utils2();
|
|
56498
56507
|
init_create_tool();
|
|
56499
56508
|
function safeWarn(message, error93) {
|
|
@@ -56686,32 +56695,32 @@ async function executePhaseComplete(args2, workingDirectory) {
|
|
|
56686
56695
|
]
|
|
56687
56696
|
}, null, 2);
|
|
56688
56697
|
}
|
|
56698
|
+
const knowledgeConfig = {
|
|
56699
|
+
enabled: true,
|
|
56700
|
+
swarm_max_entries: 100,
|
|
56701
|
+
hive_max_entries: 200,
|
|
56702
|
+
auto_promote_days: 90,
|
|
56703
|
+
max_inject_count: 5,
|
|
56704
|
+
dedup_threshold: 0.6,
|
|
56705
|
+
scope_filter: ["global"],
|
|
56706
|
+
hive_enabled: true,
|
|
56707
|
+
rejected_max_entries: 20,
|
|
56708
|
+
validation_enabled: true,
|
|
56709
|
+
evergreen_confidence: 0.9,
|
|
56710
|
+
evergreen_utility: 0.8,
|
|
56711
|
+
low_utility_threshold: 0.3,
|
|
56712
|
+
min_retrievals_for_utility: 3,
|
|
56713
|
+
schema_version: 1,
|
|
56714
|
+
same_project_weight: 1,
|
|
56715
|
+
cross_project_weight: 0.5,
|
|
56716
|
+
min_encounter_score: 0.1,
|
|
56717
|
+
initial_encounter_score: 1,
|
|
56718
|
+
encounter_increment: 0.1,
|
|
56719
|
+
max_encounter_score: 10
|
|
56720
|
+
};
|
|
56689
56721
|
if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
|
|
56690
56722
|
try {
|
|
56691
|
-
const projectName =
|
|
56692
|
-
const knowledgeConfig = {
|
|
56693
|
-
enabled: true,
|
|
56694
|
-
swarm_max_entries: 100,
|
|
56695
|
-
hive_max_entries: 200,
|
|
56696
|
-
auto_promote_days: 90,
|
|
56697
|
-
max_inject_count: 5,
|
|
56698
|
-
dedup_threshold: 0.6,
|
|
56699
|
-
scope_filter: ["global"],
|
|
56700
|
-
hive_enabled: true,
|
|
56701
|
-
rejected_max_entries: 20,
|
|
56702
|
-
validation_enabled: true,
|
|
56703
|
-
evergreen_confidence: 0.9,
|
|
56704
|
-
evergreen_utility: 0.8,
|
|
56705
|
-
low_utility_threshold: 0.3,
|
|
56706
|
-
min_retrievals_for_utility: 3,
|
|
56707
|
-
schema_version: 1,
|
|
56708
|
-
same_project_weight: 1,
|
|
56709
|
-
cross_project_weight: 0.5,
|
|
56710
|
-
min_encounter_score: 0.1,
|
|
56711
|
-
initial_encounter_score: 1,
|
|
56712
|
-
encounter_increment: 0.1,
|
|
56713
|
-
max_encounter_score: 10
|
|
56714
|
-
};
|
|
56723
|
+
const projectName = path44.basename(dir);
|
|
56715
56724
|
await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig);
|
|
56716
56725
|
} catch (error93) {
|
|
56717
56726
|
safeWarn("[phase_complete] Failed to curate lessons from retrospective:", error93);
|
|
@@ -56722,7 +56731,7 @@ async function executePhaseComplete(args2, workingDirectory) {
|
|
|
56722
56731
|
const curatorConfig = CuratorConfigSchema.parse(config3.curator ?? {});
|
|
56723
56732
|
if (curatorConfig.enabled && curatorConfig.phase_enabled) {
|
|
56724
56733
|
const curatorResult = await runCuratorPhase(dir, phase, agentsDispatched, curatorConfig, {});
|
|
56725
|
-
await applyCuratorKnowledgeUpdates(dir, curatorResult.knowledge_recommendations,
|
|
56734
|
+
await applyCuratorKnowledgeUpdates(dir, curatorResult.knowledge_recommendations, knowledgeConfig);
|
|
56726
56735
|
await runCriticDriftCheck(dir, phase, curatorResult, curatorConfig);
|
|
56727
56736
|
if (curatorResult.compliance.length > 0 && !curatorConfig.suppress_warnings) {
|
|
56728
56737
|
const complianceLines = curatorResult.compliance.map((obs) => `[${obs.severity.toUpperCase()}] ${obs.description}`).slice(0, 5);
|
|
@@ -56860,7 +56869,7 @@ init_discovery();
|
|
|
56860
56869
|
init_utils();
|
|
56861
56870
|
init_create_tool();
|
|
56862
56871
|
import * as fs32 from "fs";
|
|
56863
|
-
import * as
|
|
56872
|
+
import * as path45 from "path";
|
|
56864
56873
|
var MAX_OUTPUT_BYTES5 = 52428800;
|
|
56865
56874
|
var AUDIT_TIMEOUT_MS = 120000;
|
|
56866
56875
|
function isValidEcosystem(value) {
|
|
@@ -56878,16 +56887,16 @@ function validateArgs3(args2) {
|
|
|
56878
56887
|
function detectEcosystems(directory) {
|
|
56879
56888
|
const ecosystems = [];
|
|
56880
56889
|
const cwd = directory;
|
|
56881
|
-
if (fs32.existsSync(
|
|
56890
|
+
if (fs32.existsSync(path45.join(cwd, "package.json"))) {
|
|
56882
56891
|
ecosystems.push("npm");
|
|
56883
56892
|
}
|
|
56884
|
-
if (fs32.existsSync(
|
|
56893
|
+
if (fs32.existsSync(path45.join(cwd, "pyproject.toml")) || fs32.existsSync(path45.join(cwd, "requirements.txt"))) {
|
|
56885
56894
|
ecosystems.push("pip");
|
|
56886
56895
|
}
|
|
56887
|
-
if (fs32.existsSync(
|
|
56896
|
+
if (fs32.existsSync(path45.join(cwd, "Cargo.toml"))) {
|
|
56888
56897
|
ecosystems.push("cargo");
|
|
56889
56898
|
}
|
|
56890
|
-
if (fs32.existsSync(
|
|
56899
|
+
if (fs32.existsSync(path45.join(cwd, "go.mod"))) {
|
|
56891
56900
|
ecosystems.push("go");
|
|
56892
56901
|
}
|
|
56893
56902
|
try {
|
|
@@ -56896,10 +56905,10 @@ function detectEcosystems(directory) {
|
|
|
56896
56905
|
ecosystems.push("dotnet");
|
|
56897
56906
|
}
|
|
56898
56907
|
} catch {}
|
|
56899
|
-
if (fs32.existsSync(
|
|
56908
|
+
if (fs32.existsSync(path45.join(cwd, "Gemfile")) || fs32.existsSync(path45.join(cwd, "Gemfile.lock"))) {
|
|
56900
56909
|
ecosystems.push("ruby");
|
|
56901
56910
|
}
|
|
56902
|
-
if (fs32.existsSync(
|
|
56911
|
+
if (fs32.existsSync(path45.join(cwd, "pubspec.yaml"))) {
|
|
56903
56912
|
ecosystems.push("dart");
|
|
56904
56913
|
}
|
|
56905
56914
|
return ecosystems;
|
|
@@ -57962,7 +57971,7 @@ var SUPPORTED_PARSER_EXTENSIONS = new Set([
|
|
|
57962
57971
|
// src/tools/pre-check-batch.ts
|
|
57963
57972
|
init_dist();
|
|
57964
57973
|
import * as fs35 from "fs";
|
|
57965
|
-
import * as
|
|
57974
|
+
import * as path48 from "path";
|
|
57966
57975
|
|
|
57967
57976
|
// node_modules/yocto-queue/index.js
|
|
57968
57977
|
class Node2 {
|
|
@@ -58130,7 +58139,7 @@ init_manager();
|
|
|
58130
58139
|
|
|
58131
58140
|
// src/quality/metrics.ts
|
|
58132
58141
|
import * as fs33 from "fs";
|
|
58133
|
-
import * as
|
|
58142
|
+
import * as path46 from "path";
|
|
58134
58143
|
var MAX_FILE_SIZE_BYTES5 = 256 * 1024;
|
|
58135
58144
|
var MIN_DUPLICATION_LINES = 10;
|
|
58136
58145
|
function estimateCyclomaticComplexity(content) {
|
|
@@ -58182,7 +58191,7 @@ async function computeComplexityDelta(files, workingDir) {
|
|
|
58182
58191
|
let totalComplexity = 0;
|
|
58183
58192
|
const analyzedFiles = [];
|
|
58184
58193
|
for (const file3 of files) {
|
|
58185
|
-
const fullPath =
|
|
58194
|
+
const fullPath = path46.isAbsolute(file3) ? file3 : path46.join(workingDir, file3);
|
|
58186
58195
|
if (!fs33.existsSync(fullPath)) {
|
|
58187
58196
|
continue;
|
|
58188
58197
|
}
|
|
@@ -58305,7 +58314,7 @@ function countGoExports(content) {
|
|
|
58305
58314
|
function getExportCountForFile(filePath) {
|
|
58306
58315
|
try {
|
|
58307
58316
|
const content = fs33.readFileSync(filePath, "utf-8");
|
|
58308
|
-
const ext =
|
|
58317
|
+
const ext = path46.extname(filePath).toLowerCase();
|
|
58309
58318
|
switch (ext) {
|
|
58310
58319
|
case ".ts":
|
|
58311
58320
|
case ".tsx":
|
|
@@ -58331,7 +58340,7 @@ async function computePublicApiDelta(files, workingDir) {
|
|
|
58331
58340
|
let totalExports = 0;
|
|
58332
58341
|
const analyzedFiles = [];
|
|
58333
58342
|
for (const file3 of files) {
|
|
58334
|
-
const fullPath =
|
|
58343
|
+
const fullPath = path46.isAbsolute(file3) ? file3 : path46.join(workingDir, file3);
|
|
58335
58344
|
if (!fs33.existsSync(fullPath)) {
|
|
58336
58345
|
continue;
|
|
58337
58346
|
}
|
|
@@ -58365,7 +58374,7 @@ async function computeDuplicationRatio(files, workingDir) {
|
|
|
58365
58374
|
let duplicateLines = 0;
|
|
58366
58375
|
const analyzedFiles = [];
|
|
58367
58376
|
for (const file3 of files) {
|
|
58368
|
-
const fullPath =
|
|
58377
|
+
const fullPath = path46.isAbsolute(file3) ? file3 : path46.join(workingDir, file3);
|
|
58369
58378
|
if (!fs33.existsSync(fullPath)) {
|
|
58370
58379
|
continue;
|
|
58371
58380
|
}
|
|
@@ -58398,8 +58407,8 @@ function countCodeLines(content) {
|
|
|
58398
58407
|
return lines.length;
|
|
58399
58408
|
}
|
|
58400
58409
|
function isTestFile(filePath) {
|
|
58401
|
-
const basename8 =
|
|
58402
|
-
const _ext =
|
|
58410
|
+
const basename8 = path46.basename(filePath);
|
|
58411
|
+
const _ext = path46.extname(filePath).toLowerCase();
|
|
58403
58412
|
const testPatterns = [
|
|
58404
58413
|
".test.",
|
|
58405
58414
|
".spec.",
|
|
@@ -58480,8 +58489,8 @@ function matchGlobSegment(globSegments, pathSegments) {
|
|
|
58480
58489
|
}
|
|
58481
58490
|
return gIndex === globSegments.length && pIndex === pathSegments.length;
|
|
58482
58491
|
}
|
|
58483
|
-
function matchesGlobSegment(
|
|
58484
|
-
const normalizedPath =
|
|
58492
|
+
function matchesGlobSegment(path47, glob) {
|
|
58493
|
+
const normalizedPath = path47.replace(/\\/g, "/");
|
|
58485
58494
|
const normalizedGlob = glob.replace(/\\/g, "/");
|
|
58486
58495
|
if (normalizedPath.includes("//")) {
|
|
58487
58496
|
return false;
|
|
@@ -58512,8 +58521,8 @@ function simpleGlobToRegex2(glob) {
|
|
|
58512
58521
|
function hasGlobstar(glob) {
|
|
58513
58522
|
return glob.includes("**");
|
|
58514
58523
|
}
|
|
58515
|
-
function globMatches(
|
|
58516
|
-
const normalizedPath =
|
|
58524
|
+
function globMatches(path47, glob) {
|
|
58525
|
+
const normalizedPath = path47.replace(/\\/g, "/");
|
|
58517
58526
|
if (!glob || glob === "") {
|
|
58518
58527
|
if (normalizedPath.includes("//")) {
|
|
58519
58528
|
return false;
|
|
@@ -58549,7 +58558,7 @@ function shouldExcludeFile(filePath, excludeGlobs) {
|
|
|
58549
58558
|
async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
58550
58559
|
let testLines = 0;
|
|
58551
58560
|
let codeLines = 0;
|
|
58552
|
-
const srcDir =
|
|
58561
|
+
const srcDir = path46.join(workingDir, "src");
|
|
58553
58562
|
if (fs33.existsSync(srcDir)) {
|
|
58554
58563
|
await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
58555
58564
|
codeLines += lines;
|
|
@@ -58557,14 +58566,14 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
58557
58566
|
}
|
|
58558
58567
|
const possibleSrcDirs = ["lib", "app", "source", "core"];
|
|
58559
58568
|
for (const dir of possibleSrcDirs) {
|
|
58560
|
-
const dirPath =
|
|
58569
|
+
const dirPath = path46.join(workingDir, dir);
|
|
58561
58570
|
if (fs33.existsSync(dirPath)) {
|
|
58562
58571
|
await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
58563
58572
|
codeLines += lines;
|
|
58564
58573
|
});
|
|
58565
58574
|
}
|
|
58566
58575
|
}
|
|
58567
|
-
const testsDir =
|
|
58576
|
+
const testsDir = path46.join(workingDir, "tests");
|
|
58568
58577
|
if (fs33.existsSync(testsDir)) {
|
|
58569
58578
|
await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
58570
58579
|
testLines += lines;
|
|
@@ -58572,7 +58581,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
58572
58581
|
}
|
|
58573
58582
|
const possibleTestDirs = ["test", "__tests__", "specs"];
|
|
58574
58583
|
for (const dir of possibleTestDirs) {
|
|
58575
|
-
const dirPath =
|
|
58584
|
+
const dirPath = path46.join(workingDir, dir);
|
|
58576
58585
|
if (fs33.existsSync(dirPath) && dirPath !== testsDir) {
|
|
58577
58586
|
await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
58578
58587
|
testLines += lines;
|
|
@@ -58587,7 +58596,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
58587
58596
|
try {
|
|
58588
58597
|
const entries = fs33.readdirSync(dirPath, { withFileTypes: true });
|
|
58589
58598
|
for (const entry of entries) {
|
|
58590
|
-
const fullPath =
|
|
58599
|
+
const fullPath = path46.join(dirPath, entry.name);
|
|
58591
58600
|
if (entry.isDirectory()) {
|
|
58592
58601
|
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
|
|
58593
58602
|
continue;
|
|
@@ -58595,7 +58604,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
58595
58604
|
await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
|
|
58596
58605
|
} else if (entry.isFile()) {
|
|
58597
58606
|
const relativePath = fullPath.replace(`${process.cwd()}/`, "");
|
|
58598
|
-
const ext =
|
|
58607
|
+
const ext = path46.extname(entry.name).toLowerCase();
|
|
58599
58608
|
const validExts = [
|
|
58600
58609
|
".ts",
|
|
58601
58610
|
".tsx",
|
|
@@ -58846,7 +58855,7 @@ init_dist();
|
|
|
58846
58855
|
init_manager();
|
|
58847
58856
|
init_detector();
|
|
58848
58857
|
import * as fs34 from "fs";
|
|
58849
|
-
import * as
|
|
58858
|
+
import * as path47 from "path";
|
|
58850
58859
|
import { extname as extname9 } from "path";
|
|
58851
58860
|
|
|
58852
58861
|
// src/sast/rules/c.ts
|
|
@@ -59809,7 +59818,7 @@ async function sastScan(input, directory, config3) {
|
|
|
59809
59818
|
_filesSkipped++;
|
|
59810
59819
|
continue;
|
|
59811
59820
|
}
|
|
59812
|
-
const resolvedPath =
|
|
59821
|
+
const resolvedPath = path47.isAbsolute(filePath) ? filePath : path47.resolve(directory, filePath);
|
|
59813
59822
|
if (!fs34.existsSync(resolvedPath)) {
|
|
59814
59823
|
_filesSkipped++;
|
|
59815
59824
|
continue;
|
|
@@ -60008,18 +60017,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
|
|
|
60008
60017
|
let resolved;
|
|
60009
60018
|
const isWinAbs = isWindowsAbsolutePath(inputPath);
|
|
60010
60019
|
if (isWinAbs) {
|
|
60011
|
-
resolved =
|
|
60012
|
-
} else if (
|
|
60013
|
-
resolved =
|
|
60020
|
+
resolved = path48.win32.resolve(inputPath);
|
|
60021
|
+
} else if (path48.isAbsolute(inputPath)) {
|
|
60022
|
+
resolved = path48.resolve(inputPath);
|
|
60014
60023
|
} else {
|
|
60015
|
-
resolved =
|
|
60024
|
+
resolved = path48.resolve(baseDir, inputPath);
|
|
60016
60025
|
}
|
|
60017
|
-
const workspaceResolved =
|
|
60026
|
+
const workspaceResolved = path48.resolve(workspaceDir);
|
|
60018
60027
|
let relative5;
|
|
60019
60028
|
if (isWinAbs) {
|
|
60020
|
-
relative5 =
|
|
60029
|
+
relative5 = path48.win32.relative(workspaceResolved, resolved);
|
|
60021
60030
|
} else {
|
|
60022
|
-
relative5 =
|
|
60031
|
+
relative5 = path48.relative(workspaceResolved, resolved);
|
|
60023
60032
|
}
|
|
60024
60033
|
if (relative5.startsWith("..")) {
|
|
60025
60034
|
return "path traversal detected";
|
|
@@ -60080,13 +60089,13 @@ async function runLintWrapped(files, directory, _config) {
|
|
|
60080
60089
|
}
|
|
60081
60090
|
async function runLintOnFiles(linter, files, workspaceDir) {
|
|
60082
60091
|
const isWindows = process.platform === "win32";
|
|
60083
|
-
const binDir =
|
|
60092
|
+
const binDir = path48.join(workspaceDir, "node_modules", ".bin");
|
|
60084
60093
|
const validatedFiles = [];
|
|
60085
60094
|
for (const file3 of files) {
|
|
60086
60095
|
if (typeof file3 !== "string") {
|
|
60087
60096
|
continue;
|
|
60088
60097
|
}
|
|
60089
|
-
const resolvedPath =
|
|
60098
|
+
const resolvedPath = path48.resolve(file3);
|
|
60090
60099
|
const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
|
|
60091
60100
|
if (validationError) {
|
|
60092
60101
|
continue;
|
|
@@ -60104,10 +60113,10 @@ async function runLintOnFiles(linter, files, workspaceDir) {
|
|
|
60104
60113
|
}
|
|
60105
60114
|
let command;
|
|
60106
60115
|
if (linter === "biome") {
|
|
60107
|
-
const biomeBin = isWindows ?
|
|
60116
|
+
const biomeBin = isWindows ? path48.join(binDir, "biome.EXE") : path48.join(binDir, "biome");
|
|
60108
60117
|
command = [biomeBin, "check", ...validatedFiles];
|
|
60109
60118
|
} else {
|
|
60110
|
-
const eslintBin = isWindows ?
|
|
60119
|
+
const eslintBin = isWindows ? path48.join(binDir, "eslint.cmd") : path48.join(binDir, "eslint");
|
|
60111
60120
|
command = [eslintBin, ...validatedFiles];
|
|
60112
60121
|
}
|
|
60113
60122
|
try {
|
|
@@ -60244,7 +60253,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
60244
60253
|
skippedFiles++;
|
|
60245
60254
|
continue;
|
|
60246
60255
|
}
|
|
60247
|
-
const resolvedPath =
|
|
60256
|
+
const resolvedPath = path48.resolve(file3);
|
|
60248
60257
|
const validationError = validatePath(resolvedPath, directory, directory);
|
|
60249
60258
|
if (validationError) {
|
|
60250
60259
|
skippedFiles++;
|
|
@@ -60262,7 +60271,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
60262
60271
|
};
|
|
60263
60272
|
}
|
|
60264
60273
|
for (const file3 of validatedFiles) {
|
|
60265
|
-
const ext =
|
|
60274
|
+
const ext = path48.extname(file3).toLowerCase();
|
|
60266
60275
|
if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
|
|
60267
60276
|
skippedFiles++;
|
|
60268
60277
|
continue;
|
|
@@ -60421,7 +60430,7 @@ async function runPreCheckBatch(input, workspaceDir) {
|
|
|
60421
60430
|
warn(`pre_check_batch: Invalid file path: ${file3}`);
|
|
60422
60431
|
continue;
|
|
60423
60432
|
}
|
|
60424
|
-
changedFiles.push(
|
|
60433
|
+
changedFiles.push(path48.resolve(directory, file3));
|
|
60425
60434
|
}
|
|
60426
60435
|
if (changedFiles.length === 0) {
|
|
60427
60436
|
warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
|
|
@@ -60572,7 +60581,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
60572
60581
|
};
|
|
60573
60582
|
return JSON.stringify(errorResult, null, 2);
|
|
60574
60583
|
}
|
|
60575
|
-
const resolvedDirectory =
|
|
60584
|
+
const resolvedDirectory = path48.resolve(typedArgs.directory);
|
|
60576
60585
|
const workspaceAnchor = resolvedDirectory;
|
|
60577
60586
|
const dirError = validateDirectory3(resolvedDirectory, workspaceAnchor);
|
|
60578
60587
|
if (dirError) {
|
|
@@ -60680,7 +60689,7 @@ init_tool();
|
|
|
60680
60689
|
init_manager2();
|
|
60681
60690
|
init_create_tool();
|
|
60682
60691
|
import * as fs36 from "fs";
|
|
60683
|
-
import * as
|
|
60692
|
+
import * as path49 from "path";
|
|
60684
60693
|
function detectPlaceholderContent(args2) {
|
|
60685
60694
|
const issues = [];
|
|
60686
60695
|
const placeholderPattern = /^\[\w[\w\s]*\]$/;
|
|
@@ -60784,7 +60793,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
60784
60793
|
try {
|
|
60785
60794
|
await savePlan(dir, plan);
|
|
60786
60795
|
try {
|
|
60787
|
-
const markerPath =
|
|
60796
|
+
const markerPath = path49.join(dir, ".swarm", ".plan-write-marker");
|
|
60788
60797
|
const marker = JSON.stringify({
|
|
60789
60798
|
source: "save_plan",
|
|
60790
60799
|
timestamp: new Date().toISOString(),
|
|
@@ -60796,7 +60805,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
60796
60805
|
return {
|
|
60797
60806
|
success: true,
|
|
60798
60807
|
message: "Plan saved successfully",
|
|
60799
|
-
plan_path:
|
|
60808
|
+
plan_path: path49.join(dir, ".swarm", "plan.json"),
|
|
60800
60809
|
phases_count: plan.phases.length,
|
|
60801
60810
|
tasks_count: tasksCount
|
|
60802
60811
|
};
|
|
@@ -60835,7 +60844,7 @@ var save_plan = createSwarmTool({
|
|
|
60835
60844
|
init_dist();
|
|
60836
60845
|
init_manager();
|
|
60837
60846
|
import * as fs37 from "fs";
|
|
60838
|
-
import * as
|
|
60847
|
+
import * as path50 from "path";
|
|
60839
60848
|
|
|
60840
60849
|
// src/sbom/detectors/index.ts
|
|
60841
60850
|
init_utils();
|
|
@@ -61683,7 +61692,7 @@ function findManifestFiles(rootDir) {
|
|
|
61683
61692
|
try {
|
|
61684
61693
|
const entries = fs37.readdirSync(dir, { withFileTypes: true });
|
|
61685
61694
|
for (const entry of entries) {
|
|
61686
|
-
const fullPath =
|
|
61695
|
+
const fullPath = path50.join(dir, entry.name);
|
|
61687
61696
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
|
|
61688
61697
|
continue;
|
|
61689
61698
|
}
|
|
@@ -61692,7 +61701,7 @@ function findManifestFiles(rootDir) {
|
|
|
61692
61701
|
} else if (entry.isFile()) {
|
|
61693
61702
|
for (const pattern of patterns) {
|
|
61694
61703
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
61695
|
-
manifestFiles.push(
|
|
61704
|
+
manifestFiles.push(path50.relative(rootDir, fullPath));
|
|
61696
61705
|
break;
|
|
61697
61706
|
}
|
|
61698
61707
|
}
|
|
@@ -61710,11 +61719,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
61710
61719
|
try {
|
|
61711
61720
|
const entries = fs37.readdirSync(dir, { withFileTypes: true });
|
|
61712
61721
|
for (const entry of entries) {
|
|
61713
|
-
const fullPath =
|
|
61722
|
+
const fullPath = path50.join(dir, entry.name);
|
|
61714
61723
|
if (entry.isFile()) {
|
|
61715
61724
|
for (const pattern of patterns) {
|
|
61716
61725
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
61717
|
-
found.push(
|
|
61726
|
+
found.push(path50.relative(workingDir, fullPath));
|
|
61718
61727
|
break;
|
|
61719
61728
|
}
|
|
61720
61729
|
}
|
|
@@ -61727,11 +61736,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
61727
61736
|
function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
61728
61737
|
const dirs = new Set;
|
|
61729
61738
|
for (const file3 of changedFiles) {
|
|
61730
|
-
let currentDir =
|
|
61739
|
+
let currentDir = path50.dirname(file3);
|
|
61731
61740
|
while (true) {
|
|
61732
|
-
if (currentDir && currentDir !== "." && currentDir !==
|
|
61733
|
-
dirs.add(
|
|
61734
|
-
const parent =
|
|
61741
|
+
if (currentDir && currentDir !== "." && currentDir !== path50.sep) {
|
|
61742
|
+
dirs.add(path50.join(workingDir, currentDir));
|
|
61743
|
+
const parent = path50.dirname(currentDir);
|
|
61735
61744
|
if (parent === currentDir)
|
|
61736
61745
|
break;
|
|
61737
61746
|
currentDir = parent;
|
|
@@ -61815,7 +61824,7 @@ var sbom_generate = createSwarmTool({
|
|
|
61815
61824
|
const changedFiles = obj.changed_files;
|
|
61816
61825
|
const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
|
|
61817
61826
|
const workingDir = directory;
|
|
61818
|
-
const outputDir =
|
|
61827
|
+
const outputDir = path50.isAbsolute(relativeOutputDir) ? relativeOutputDir : path50.join(workingDir, relativeOutputDir);
|
|
61819
61828
|
let manifestFiles = [];
|
|
61820
61829
|
if (scope === "all") {
|
|
61821
61830
|
manifestFiles = findManifestFiles(workingDir);
|
|
@@ -61838,7 +61847,7 @@ var sbom_generate = createSwarmTool({
|
|
|
61838
61847
|
const processedFiles = [];
|
|
61839
61848
|
for (const manifestFile of manifestFiles) {
|
|
61840
61849
|
try {
|
|
61841
|
-
const fullPath =
|
|
61850
|
+
const fullPath = path50.isAbsolute(manifestFile) ? manifestFile : path50.join(workingDir, manifestFile);
|
|
61842
61851
|
if (!fs37.existsSync(fullPath)) {
|
|
61843
61852
|
continue;
|
|
61844
61853
|
}
|
|
@@ -61855,7 +61864,7 @@ var sbom_generate = createSwarmTool({
|
|
|
61855
61864
|
const bom = generateCycloneDX(allComponents);
|
|
61856
61865
|
const bomJson = serializeCycloneDX(bom);
|
|
61857
61866
|
const filename = generateSbomFilename();
|
|
61858
|
-
const outputPath =
|
|
61867
|
+
const outputPath = path50.join(outputDir, filename);
|
|
61859
61868
|
fs37.writeFileSync(outputPath, bomJson, "utf-8");
|
|
61860
61869
|
const verdict = processedFiles.length > 0 ? "pass" : "pass";
|
|
61861
61870
|
try {
|
|
@@ -61899,7 +61908,7 @@ var sbom_generate = createSwarmTool({
|
|
|
61899
61908
|
init_dist();
|
|
61900
61909
|
init_create_tool();
|
|
61901
61910
|
import * as fs38 from "fs";
|
|
61902
|
-
import * as
|
|
61911
|
+
import * as path51 from "path";
|
|
61903
61912
|
var SPEC_CANDIDATES = [
|
|
61904
61913
|
"openapi.json",
|
|
61905
61914
|
"openapi.yaml",
|
|
@@ -61931,12 +61940,12 @@ function normalizePath2(p) {
|
|
|
61931
61940
|
}
|
|
61932
61941
|
function discoverSpecFile(cwd, specFileArg) {
|
|
61933
61942
|
if (specFileArg) {
|
|
61934
|
-
const resolvedPath =
|
|
61935
|
-
const normalizedCwd = cwd.endsWith(
|
|
61943
|
+
const resolvedPath = path51.resolve(cwd, specFileArg);
|
|
61944
|
+
const normalizedCwd = cwd.endsWith(path51.sep) ? cwd : cwd + path51.sep;
|
|
61936
61945
|
if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
|
|
61937
61946
|
throw new Error("Invalid spec_file: path traversal detected");
|
|
61938
61947
|
}
|
|
61939
|
-
const ext =
|
|
61948
|
+
const ext = path51.extname(resolvedPath).toLowerCase();
|
|
61940
61949
|
if (!ALLOWED_EXTENSIONS.includes(ext)) {
|
|
61941
61950
|
throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
|
|
61942
61951
|
}
|
|
@@ -61950,7 +61959,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
61950
61959
|
return resolvedPath;
|
|
61951
61960
|
}
|
|
61952
61961
|
for (const candidate of SPEC_CANDIDATES) {
|
|
61953
|
-
const candidatePath =
|
|
61962
|
+
const candidatePath = path51.resolve(cwd, candidate);
|
|
61954
61963
|
if (fs38.existsSync(candidatePath)) {
|
|
61955
61964
|
const stats = fs38.statSync(candidatePath);
|
|
61956
61965
|
if (stats.size <= MAX_SPEC_SIZE) {
|
|
@@ -61962,7 +61971,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
61962
61971
|
}
|
|
61963
61972
|
function parseSpec(specFile) {
|
|
61964
61973
|
const content = fs38.readFileSync(specFile, "utf-8");
|
|
61965
|
-
const ext =
|
|
61974
|
+
const ext = path51.extname(specFile).toLowerCase();
|
|
61966
61975
|
if (ext === ".json") {
|
|
61967
61976
|
return parseJsonSpec(content);
|
|
61968
61977
|
}
|
|
@@ -62038,7 +62047,7 @@ function extractRoutes(cwd) {
|
|
|
62038
62047
|
return;
|
|
62039
62048
|
}
|
|
62040
62049
|
for (const entry of entries) {
|
|
62041
|
-
const fullPath =
|
|
62050
|
+
const fullPath = path51.join(dir, entry.name);
|
|
62042
62051
|
if (entry.isSymbolicLink()) {
|
|
62043
62052
|
continue;
|
|
62044
62053
|
}
|
|
@@ -62048,7 +62057,7 @@ function extractRoutes(cwd) {
|
|
|
62048
62057
|
}
|
|
62049
62058
|
walkDir(fullPath);
|
|
62050
62059
|
} else if (entry.isFile()) {
|
|
62051
|
-
const ext =
|
|
62060
|
+
const ext = path51.extname(entry.name).toLowerCase();
|
|
62052
62061
|
const baseName = entry.name.toLowerCase();
|
|
62053
62062
|
if (![".ts", ".js", ".mjs"].includes(ext)) {
|
|
62054
62063
|
continue;
|
|
@@ -62218,7 +62227,7 @@ init_secretscan();
|
|
|
62218
62227
|
init_tool();
|
|
62219
62228
|
init_create_tool();
|
|
62220
62229
|
import * as fs39 from "fs";
|
|
62221
|
-
import * as
|
|
62230
|
+
import * as path52 from "path";
|
|
62222
62231
|
var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
|
|
62223
62232
|
var WINDOWS_RESERVED_NAMES = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
62224
62233
|
function containsControlCharacters(str) {
|
|
@@ -62247,11 +62256,11 @@ function containsWindowsAttacks(str) {
|
|
|
62247
62256
|
}
|
|
62248
62257
|
function isPathInWorkspace(filePath, workspace) {
|
|
62249
62258
|
try {
|
|
62250
|
-
const resolvedPath =
|
|
62259
|
+
const resolvedPath = path52.resolve(workspace, filePath);
|
|
62251
62260
|
const realWorkspace = fs39.realpathSync(workspace);
|
|
62252
62261
|
const realResolvedPath = fs39.realpathSync(resolvedPath);
|
|
62253
|
-
const relativePath =
|
|
62254
|
-
if (relativePath.startsWith("..") ||
|
|
62262
|
+
const relativePath = path52.relative(realWorkspace, realResolvedPath);
|
|
62263
|
+
if (relativePath.startsWith("..") || path52.isAbsolute(relativePath)) {
|
|
62255
62264
|
return false;
|
|
62256
62265
|
}
|
|
62257
62266
|
return true;
|
|
@@ -62263,7 +62272,7 @@ function validatePathForRead(filePath, workspace) {
|
|
|
62263
62272
|
return isPathInWorkspace(filePath, workspace);
|
|
62264
62273
|
}
|
|
62265
62274
|
function extractTSSymbols(filePath, cwd) {
|
|
62266
|
-
const fullPath =
|
|
62275
|
+
const fullPath = path52.join(cwd, filePath);
|
|
62267
62276
|
if (!validatePathForRead(fullPath, cwd)) {
|
|
62268
62277
|
return [];
|
|
62269
62278
|
}
|
|
@@ -62415,7 +62424,7 @@ function extractTSSymbols(filePath, cwd) {
|
|
|
62415
62424
|
});
|
|
62416
62425
|
}
|
|
62417
62426
|
function extractPythonSymbols(filePath, cwd) {
|
|
62418
|
-
const fullPath =
|
|
62427
|
+
const fullPath = path52.join(cwd, filePath);
|
|
62419
62428
|
if (!validatePathForRead(fullPath, cwd)) {
|
|
62420
62429
|
return [];
|
|
62421
62430
|
}
|
|
@@ -62498,7 +62507,7 @@ var symbols = createSwarmTool({
|
|
|
62498
62507
|
}, null, 2);
|
|
62499
62508
|
}
|
|
62500
62509
|
const cwd = directory;
|
|
62501
|
-
const ext =
|
|
62510
|
+
const ext = path52.extname(file3);
|
|
62502
62511
|
if (containsControlCharacters(file3)) {
|
|
62503
62512
|
return JSON.stringify({
|
|
62504
62513
|
file: file3,
|
|
@@ -62570,7 +62579,7 @@ init_dist();
|
|
|
62570
62579
|
init_utils();
|
|
62571
62580
|
init_create_tool();
|
|
62572
62581
|
import * as fs40 from "fs";
|
|
62573
|
-
import * as
|
|
62582
|
+
import * as path53 from "path";
|
|
62574
62583
|
var MAX_TEXT_LENGTH = 200;
|
|
62575
62584
|
var MAX_FILE_SIZE_BYTES8 = 1024 * 1024;
|
|
62576
62585
|
var SUPPORTED_EXTENSIONS2 = new Set([
|
|
@@ -62641,9 +62650,9 @@ function validatePathsInput(paths, cwd) {
|
|
|
62641
62650
|
return { error: "paths contains path traversal", resolvedPath: null };
|
|
62642
62651
|
}
|
|
62643
62652
|
try {
|
|
62644
|
-
const resolvedPath =
|
|
62645
|
-
const normalizedCwd =
|
|
62646
|
-
const normalizedResolved =
|
|
62653
|
+
const resolvedPath = path53.resolve(paths);
|
|
62654
|
+
const normalizedCwd = path53.resolve(cwd);
|
|
62655
|
+
const normalizedResolved = path53.resolve(resolvedPath);
|
|
62647
62656
|
if (!normalizedResolved.startsWith(normalizedCwd)) {
|
|
62648
62657
|
return {
|
|
62649
62658
|
error: "paths must be within the current working directory",
|
|
@@ -62659,7 +62668,7 @@ function validatePathsInput(paths, cwd) {
|
|
|
62659
62668
|
}
|
|
62660
62669
|
}
|
|
62661
62670
|
function isSupportedExtension(filePath) {
|
|
62662
|
-
const ext =
|
|
62671
|
+
const ext = path53.extname(filePath).toLowerCase();
|
|
62663
62672
|
return SUPPORTED_EXTENSIONS2.has(ext);
|
|
62664
62673
|
}
|
|
62665
62674
|
function findSourceFiles2(dir, files = []) {
|
|
@@ -62674,7 +62683,7 @@ function findSourceFiles2(dir, files = []) {
|
|
|
62674
62683
|
if (SKIP_DIRECTORIES3.has(entry)) {
|
|
62675
62684
|
continue;
|
|
62676
62685
|
}
|
|
62677
|
-
const fullPath =
|
|
62686
|
+
const fullPath = path53.join(dir, entry);
|
|
62678
62687
|
let stat2;
|
|
62679
62688
|
try {
|
|
62680
62689
|
stat2 = fs40.statSync(fullPath);
|
|
@@ -62786,7 +62795,7 @@ var todo_extract = createSwarmTool({
|
|
|
62786
62795
|
filesToScan.push(scanPath);
|
|
62787
62796
|
} else {
|
|
62788
62797
|
const errorResult = {
|
|
62789
|
-
error: `unsupported file extension: ${
|
|
62798
|
+
error: `unsupported file extension: ${path53.extname(scanPath)}`,
|
|
62790
62799
|
total: 0,
|
|
62791
62800
|
byPriority: { high: 0, medium: 0, low: 0 },
|
|
62792
62801
|
entries: []
|
|
@@ -62832,14 +62841,14 @@ var todo_extract = createSwarmTool({
|
|
|
62832
62841
|
init_tool();
|
|
62833
62842
|
init_schema();
|
|
62834
62843
|
import * as fs42 from "fs";
|
|
62835
|
-
import * as
|
|
62844
|
+
import * as path55 from "path";
|
|
62836
62845
|
|
|
62837
62846
|
// src/hooks/diff-scope.ts
|
|
62838
62847
|
import * as fs41 from "fs";
|
|
62839
|
-
import * as
|
|
62848
|
+
import * as path54 from "path";
|
|
62840
62849
|
function getDeclaredScope(taskId, directory) {
|
|
62841
62850
|
try {
|
|
62842
|
-
const planPath =
|
|
62851
|
+
const planPath = path54.join(directory, ".swarm", "plan.json");
|
|
62843
62852
|
if (!fs41.existsSync(planPath))
|
|
62844
62853
|
return null;
|
|
62845
62854
|
const raw = fs41.readFileSync(planPath, "utf-8");
|
|
@@ -62954,7 +62963,7 @@ var TIER_3_PATTERNS = [
|
|
|
62954
62963
|
];
|
|
62955
62964
|
function matchesTier3Pattern(files) {
|
|
62956
62965
|
for (const file3 of files) {
|
|
62957
|
-
const fileName =
|
|
62966
|
+
const fileName = path55.basename(file3);
|
|
62958
62967
|
for (const pattern of TIER_3_PATTERNS) {
|
|
62959
62968
|
if (pattern.test(fileName)) {
|
|
62960
62969
|
return true;
|
|
@@ -62976,7 +62985,7 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
62976
62985
|
if (hasActiveTurboMode2()) {
|
|
62977
62986
|
const resolvedDir2 = workingDirectory ?? process.cwd();
|
|
62978
62987
|
try {
|
|
62979
|
-
const planPath =
|
|
62988
|
+
const planPath = path55.join(resolvedDir2, ".swarm", "plan.json");
|
|
62980
62989
|
const planRaw = fs42.readFileSync(planPath, "utf-8");
|
|
62981
62990
|
const plan = JSON.parse(planRaw);
|
|
62982
62991
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -62996,7 +63005,7 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
62996
63005
|
}
|
|
62997
63006
|
const resolvedDir = workingDirectory ?? process.cwd();
|
|
62998
63007
|
try {
|
|
62999
|
-
const evidencePath =
|
|
63008
|
+
const evidencePath = path55.join(resolvedDir, ".swarm", "evidence", `${taskId}.json`);
|
|
63000
63009
|
const raw = fs42.readFileSync(evidencePath, "utf-8");
|
|
63001
63010
|
const evidence = JSON.parse(raw);
|
|
63002
63011
|
if (evidence?.required_gates && Array.isArray(evidence.required_gates) && evidence?.gates) {
|
|
@@ -63037,7 +63046,7 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
63037
63046
|
}
|
|
63038
63047
|
try {
|
|
63039
63048
|
const resolvedDir2 = workingDirectory ?? process.cwd();
|
|
63040
|
-
const planPath =
|
|
63049
|
+
const planPath = path55.join(resolvedDir2, ".swarm", "plan.json");
|
|
63041
63050
|
const planRaw = fs42.readFileSync(planPath, "utf-8");
|
|
63042
63051
|
const plan = JSON.parse(planRaw);
|
|
63043
63052
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -63219,8 +63228,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
63219
63228
|
};
|
|
63220
63229
|
}
|
|
63221
63230
|
}
|
|
63222
|
-
normalizedDir =
|
|
63223
|
-
const pathParts = normalizedDir.split(
|
|
63231
|
+
normalizedDir = path55.normalize(args2.working_directory);
|
|
63232
|
+
const pathParts = normalizedDir.split(path55.sep);
|
|
63224
63233
|
if (pathParts.includes("..")) {
|
|
63225
63234
|
return {
|
|
63226
63235
|
success: false,
|
|
@@ -63230,10 +63239,10 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
63230
63239
|
]
|
|
63231
63240
|
};
|
|
63232
63241
|
}
|
|
63233
|
-
const resolvedDir =
|
|
63242
|
+
const resolvedDir = path55.resolve(normalizedDir);
|
|
63234
63243
|
try {
|
|
63235
63244
|
const realPath = fs42.realpathSync(resolvedDir);
|
|
63236
|
-
const planPath =
|
|
63245
|
+
const planPath = path55.join(realPath, ".swarm", "plan.json");
|
|
63237
63246
|
if (!fs42.existsSync(planPath)) {
|
|
63238
63247
|
return {
|
|
63239
63248
|
success: false,
|
|
@@ -63428,7 +63437,7 @@ var OpenCodeSwarm = async (ctx) => {
|
|
|
63428
63437
|
const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
|
|
63429
63438
|
preflightTriggerManager = new PTM(automationConfig);
|
|
63430
63439
|
const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
|
|
63431
|
-
const swarmDir =
|
|
63440
|
+
const swarmDir = path56.resolve(ctx.directory, ".swarm");
|
|
63432
63441
|
statusArtifact = new ASA(swarmDir);
|
|
63433
63442
|
statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
|
|
63434
63443
|
if (automationConfig.capabilities?.evidence_auto_summaries === true) {
|
|
@@ -20,15 +20,7 @@ export declare function readSnapshot(directory: string): Promise<SnapshotData |
|
|
|
20
20
|
* Clears existing maps first, then populates from snapshot.
|
|
21
21
|
* Does NOT touch activeToolCalls or pendingEvents (remain at defaults).
|
|
22
22
|
*/
|
|
23
|
-
export declare function rehydrateState(snapshot: SnapshotData): void
|
|
24
|
-
/**
|
|
25
|
-
* Reconcile task workflow states from plan.json for all active sessions.
|
|
26
|
-
* Seeds completed plan tasks to 'tests_run' and in_progress tasks to 'coder_delegated'.
|
|
27
|
-
* Best-effort: returns silently on any file/parse error. NEVER throws.
|
|
28
|
-
*
|
|
29
|
-
* @param directory - The project root directory containing .swarm/plan.json
|
|
30
|
-
*/
|
|
31
|
-
export declare function reconcileTaskStatesFromPlan(directory: string): Promise<void>;
|
|
23
|
+
export declare function rehydrateState(snapshot: SnapshotData): Promise<void>;
|
|
32
24
|
/**
|
|
33
25
|
* Load snapshot from disk and rehydrate swarmState.
|
|
34
26
|
* Called on plugin init to restore state from previous session.
|
package/dist/state.d.ts
CHANGED
|
@@ -181,6 +181,8 @@ export declare const swarmState: {
|
|
|
181
181
|
lastBudgetPct: number;
|
|
182
182
|
/** Per-session guardrail state — keyed by sessionID */
|
|
183
183
|
agentSessions: Map<string, AgentSessionState>;
|
|
184
|
+
/** In-flight rehydration promises — awaited by rehydrateState before clearing agentSessions */
|
|
185
|
+
pendingRehydrations: Set<Promise<void>>;
|
|
184
186
|
};
|
|
185
187
|
/**
|
|
186
188
|
* Reset all state to initial values - useful for testing
|
|
@@ -194,7 +196,7 @@ export declare function resetSwarmState(): void;
|
|
|
194
196
|
* @param staleDurationMs - Age threshold for stale session eviction (default: 120 min)
|
|
195
197
|
* @param directory - Optional project directory for rehydrating workflow state from disk
|
|
196
198
|
*/
|
|
197
|
-
export declare function startAgentSession(sessionId: string, agentName: string, staleDurationMs?: number,
|
|
199
|
+
export declare function startAgentSession(sessionId: string, agentName: string, staleDurationMs?: number, directory?: string): void;
|
|
198
200
|
/**
|
|
199
201
|
* End an agent session by removing it from the state.
|
|
200
202
|
* NOTE: Currently unused in production — no session lifecycle teardown is wired up.
|
|
@@ -218,7 +220,7 @@ export declare function getAgentSession(sessionId: string): AgentSessionState |
|
|
|
218
220
|
* @param agentName - Optional agent name (if known)
|
|
219
221
|
* @returns The AgentSessionState
|
|
220
222
|
*/
|
|
221
|
-
export declare function ensureAgentSession(sessionId: string, agentName?: string,
|
|
223
|
+
export declare function ensureAgentSession(sessionId: string, agentName?: string, directory?: string): AgentSessionState;
|
|
222
224
|
/**
|
|
223
225
|
* Update only the agent event timestamp (for stale detection).
|
|
224
226
|
* Does NOT change agent name or reset guardrail state.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.30.1",
|
|
4
4
|
"description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|