opencode-swarm 6.23.1 → 6.23.2
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/index.js
CHANGED
|
@@ -15749,6 +15749,39 @@ async function savePlan(directory, plan) {
|
|
|
15749
15749
|
throw new Error(`Invalid directory: directory must be a non-empty string`);
|
|
15750
15750
|
}
|
|
15751
15751
|
const validated = PlanSchema.parse(plan);
|
|
15752
|
+
try {
|
|
15753
|
+
const currentPlan = await loadPlanJsonOnly(directory);
|
|
15754
|
+
if (currentPlan) {
|
|
15755
|
+
const completedTaskIds = new Set;
|
|
15756
|
+
for (const phase of currentPlan.phases) {
|
|
15757
|
+
for (const task of phase.tasks) {
|
|
15758
|
+
if (task.status === "completed")
|
|
15759
|
+
completedTaskIds.add(task.id);
|
|
15760
|
+
}
|
|
15761
|
+
}
|
|
15762
|
+
if (completedTaskIds.size > 0) {
|
|
15763
|
+
for (const phase of validated.phases) {
|
|
15764
|
+
for (const task of phase.tasks) {
|
|
15765
|
+
if (completedTaskIds.has(task.id) && task.status !== "completed") {
|
|
15766
|
+
task.status = "completed";
|
|
15767
|
+
}
|
|
15768
|
+
}
|
|
15769
|
+
}
|
|
15770
|
+
}
|
|
15771
|
+
}
|
|
15772
|
+
} catch {}
|
|
15773
|
+
for (const phase of validated.phases) {
|
|
15774
|
+
const tasks = phase.tasks;
|
|
15775
|
+
if (tasks.length > 0 && tasks.every((t) => t.status === "completed")) {
|
|
15776
|
+
phase.status = "complete";
|
|
15777
|
+
} else if (tasks.some((t) => t.status === "in_progress")) {
|
|
15778
|
+
phase.status = "in_progress";
|
|
15779
|
+
} else if (tasks.some((t) => t.status === "blocked")) {
|
|
15780
|
+
phase.status = "blocked";
|
|
15781
|
+
} else {
|
|
15782
|
+
phase.status = "pending";
|
|
15783
|
+
}
|
|
15784
|
+
}
|
|
15752
15785
|
const swarmDir = path4.resolve(directory, ".swarm");
|
|
15753
15786
|
const planPath = path4.join(swarmDir, "plan.json");
|
|
15754
15787
|
const tempPath = path4.join(swarmDir, `plan.json.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
|
|
@@ -35824,6 +35857,133 @@ var init_preflight_service = __esm(() => {
|
|
|
35824
35857
|
};
|
|
35825
35858
|
});
|
|
35826
35859
|
|
|
35860
|
+
// src/gate-evidence.ts
|
|
35861
|
+
var exports_gate_evidence = {};
|
|
35862
|
+
__export(exports_gate_evidence, {
|
|
35863
|
+
recordGateEvidence: () => recordGateEvidence,
|
|
35864
|
+
recordAgentDispatch: () => recordAgentDispatch,
|
|
35865
|
+
readTaskEvidence: () => readTaskEvidence,
|
|
35866
|
+
hasPassedAllGates: () => hasPassedAllGates,
|
|
35867
|
+
expandRequiredGates: () => expandRequiredGates,
|
|
35868
|
+
deriveRequiredGates: () => deriveRequiredGates,
|
|
35869
|
+
DEFAULT_REQUIRED_GATES: () => DEFAULT_REQUIRED_GATES
|
|
35870
|
+
});
|
|
35871
|
+
import { mkdirSync as mkdirSync8, readFileSync as readFileSync13, renameSync as renameSync7, unlinkSync as unlinkSync4 } from "fs";
|
|
35872
|
+
import * as path27 from "path";
|
|
35873
|
+
function assertValidTaskId(taskId) {
|
|
35874
|
+
if (!taskId || taskId.includes("..") || taskId.includes("/") || taskId.includes("\\") || taskId.includes("\x00") || !TASK_ID_PATTERN.test(taskId)) {
|
|
35875
|
+
throw new Error(`Invalid taskId: "${taskId}". Must match N.M or N.M.P (e.g. "1.1", "1.2.3").`);
|
|
35876
|
+
}
|
|
35877
|
+
}
|
|
35878
|
+
function deriveRequiredGates(agentType) {
|
|
35879
|
+
switch (agentType) {
|
|
35880
|
+
case "coder":
|
|
35881
|
+
return ["reviewer", "test_engineer"];
|
|
35882
|
+
case "docs":
|
|
35883
|
+
return ["docs"];
|
|
35884
|
+
case "designer":
|
|
35885
|
+
return ["designer", "reviewer", "test_engineer"];
|
|
35886
|
+
case "explorer":
|
|
35887
|
+
return ["explorer"];
|
|
35888
|
+
case "sme":
|
|
35889
|
+
return ["sme"];
|
|
35890
|
+
case "reviewer":
|
|
35891
|
+
return ["reviewer"];
|
|
35892
|
+
case "test_engineer":
|
|
35893
|
+
return ["test_engineer"];
|
|
35894
|
+
case "critic":
|
|
35895
|
+
return ["critic"];
|
|
35896
|
+
default:
|
|
35897
|
+
return ["reviewer", "test_engineer"];
|
|
35898
|
+
}
|
|
35899
|
+
}
|
|
35900
|
+
function expandRequiredGates(existingGates, newAgentType) {
|
|
35901
|
+
const newGates = deriveRequiredGates(newAgentType);
|
|
35902
|
+
const combined = [...new Set([...existingGates, ...newGates])];
|
|
35903
|
+
return combined.sort();
|
|
35904
|
+
}
|
|
35905
|
+
function getEvidenceDir(directory) {
|
|
35906
|
+
return path27.join(directory, ".swarm", "evidence");
|
|
35907
|
+
}
|
|
35908
|
+
function getEvidencePath(directory, taskId) {
|
|
35909
|
+
return path27.join(getEvidenceDir(directory), `${taskId}.json`);
|
|
35910
|
+
}
|
|
35911
|
+
function readExisting(evidencePath) {
|
|
35912
|
+
try {
|
|
35913
|
+
const raw = readFileSync13(evidencePath, "utf-8");
|
|
35914
|
+
return JSON.parse(raw);
|
|
35915
|
+
} catch {
|
|
35916
|
+
return null;
|
|
35917
|
+
}
|
|
35918
|
+
}
|
|
35919
|
+
async function atomicWrite(targetPath, content) {
|
|
35920
|
+
const tempPath = `${targetPath}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`;
|
|
35921
|
+
try {
|
|
35922
|
+
await Bun.write(tempPath, content);
|
|
35923
|
+
renameSync7(tempPath, targetPath);
|
|
35924
|
+
} finally {
|
|
35925
|
+
try {
|
|
35926
|
+
unlinkSync4(tempPath);
|
|
35927
|
+
} catch {}
|
|
35928
|
+
}
|
|
35929
|
+
}
|
|
35930
|
+
async function recordGateEvidence(directory, taskId, gate, sessionId) {
|
|
35931
|
+
assertValidTaskId(taskId);
|
|
35932
|
+
const evidenceDir = getEvidenceDir(directory);
|
|
35933
|
+
const evidencePath = getEvidencePath(directory, taskId);
|
|
35934
|
+
mkdirSync8(evidenceDir, { recursive: true });
|
|
35935
|
+
const existing = readExisting(evidencePath);
|
|
35936
|
+
const requiredGates = existing ? expandRequiredGates(existing.required_gates, gate) : deriveRequiredGates(gate);
|
|
35937
|
+
const updated = {
|
|
35938
|
+
taskId,
|
|
35939
|
+
required_gates: requiredGates,
|
|
35940
|
+
gates: {
|
|
35941
|
+
...existing?.gates ?? {},
|
|
35942
|
+
[gate]: {
|
|
35943
|
+
sessionId,
|
|
35944
|
+
timestamp: new Date().toISOString(),
|
|
35945
|
+
agent: gate
|
|
35946
|
+
}
|
|
35947
|
+
}
|
|
35948
|
+
};
|
|
35949
|
+
await atomicWrite(evidencePath, JSON.stringify(updated, null, 2));
|
|
35950
|
+
}
|
|
35951
|
+
async function recordAgentDispatch(directory, taskId, agentType) {
|
|
35952
|
+
assertValidTaskId(taskId);
|
|
35953
|
+
const evidenceDir = getEvidenceDir(directory);
|
|
35954
|
+
const evidencePath = getEvidencePath(directory, taskId);
|
|
35955
|
+
mkdirSync8(evidenceDir, { recursive: true });
|
|
35956
|
+
const existing = readExisting(evidencePath);
|
|
35957
|
+
const requiredGates = existing ? expandRequiredGates(existing.required_gates, agentType) : deriveRequiredGates(agentType);
|
|
35958
|
+
const updated = {
|
|
35959
|
+
taskId,
|
|
35960
|
+
required_gates: requiredGates,
|
|
35961
|
+
gates: existing?.gates ?? {}
|
|
35962
|
+
};
|
|
35963
|
+
await atomicWrite(evidencePath, JSON.stringify(updated, null, 2));
|
|
35964
|
+
}
|
|
35965
|
+
async function readTaskEvidence(directory, taskId) {
|
|
35966
|
+
try {
|
|
35967
|
+
assertValidTaskId(taskId);
|
|
35968
|
+
return readExisting(getEvidencePath(directory, taskId));
|
|
35969
|
+
} catch {
|
|
35970
|
+
return null;
|
|
35971
|
+
}
|
|
35972
|
+
}
|
|
35973
|
+
async function hasPassedAllGates(directory, taskId) {
|
|
35974
|
+
const evidence = await readTaskEvidence(directory, taskId);
|
|
35975
|
+
if (!evidence)
|
|
35976
|
+
return false;
|
|
35977
|
+
if (!Array.isArray(evidence.required_gates) || evidence.required_gates.length === 0)
|
|
35978
|
+
return false;
|
|
35979
|
+
return evidence.required_gates.every((gate) => evidence.gates[gate] != null);
|
|
35980
|
+
}
|
|
35981
|
+
var DEFAULT_REQUIRED_GATES, TASK_ID_PATTERN;
|
|
35982
|
+
var init_gate_evidence = __esm(() => {
|
|
35983
|
+
DEFAULT_REQUIRED_GATES = ["reviewer", "test_engineer"];
|
|
35984
|
+
TASK_ID_PATTERN = /^\d+\.\d+(\.\d+)*$/;
|
|
35985
|
+
});
|
|
35986
|
+
|
|
35827
35987
|
// src/services/preflight-integration.ts
|
|
35828
35988
|
var exports_preflight_integration = {};
|
|
35829
35989
|
__export(exports_preflight_integration, {
|
|
@@ -37353,11 +37513,11 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
37353
37513
|
throw toThrow;
|
|
37354
37514
|
}, "quit_");
|
|
37355
37515
|
var scriptDirectory = "";
|
|
37356
|
-
function locateFile(
|
|
37516
|
+
function locateFile(path40) {
|
|
37357
37517
|
if (Module["locateFile"]) {
|
|
37358
|
-
return Module["locateFile"](
|
|
37518
|
+
return Module["locateFile"](path40, scriptDirectory);
|
|
37359
37519
|
}
|
|
37360
|
-
return scriptDirectory +
|
|
37520
|
+
return scriptDirectory + path40;
|
|
37361
37521
|
}
|
|
37362
37522
|
__name(locateFile, "locateFile");
|
|
37363
37523
|
var readAsync, readBinary;
|
|
@@ -39105,7 +39265,7 @@ var init_runtime = __esm(() => {
|
|
|
39105
39265
|
});
|
|
39106
39266
|
|
|
39107
39267
|
// src/index.ts
|
|
39108
|
-
import * as
|
|
39268
|
+
import * as path49 from "path";
|
|
39109
39269
|
|
|
39110
39270
|
// src/agents/index.ts
|
|
39111
39271
|
init_config();
|
|
@@ -48774,6 +48934,28 @@ function createDelegationGateHook(config3) {
|
|
|
48774
48934
|
}
|
|
48775
48935
|
}
|
|
48776
48936
|
}
|
|
48937
|
+
if (typeof subagentType === "string") {
|
|
48938
|
+
const evidenceTaskId = session.currentTaskId ?? session.lastCoderDelegationTaskId;
|
|
48939
|
+
if (evidenceTaskId) {
|
|
48940
|
+
try {
|
|
48941
|
+
const gateAgents = [
|
|
48942
|
+
"reviewer",
|
|
48943
|
+
"test_engineer",
|
|
48944
|
+
"docs",
|
|
48945
|
+
"designer",
|
|
48946
|
+
"critic"
|
|
48947
|
+
];
|
|
48948
|
+
const targetAgentForEvidence = stripKnownSwarmPrefix(subagentType);
|
|
48949
|
+
if (gateAgents.includes(targetAgentForEvidence)) {
|
|
48950
|
+
const { recordGateEvidence: recordGateEvidence2 } = await Promise.resolve().then(() => (init_gate_evidence(), exports_gate_evidence));
|
|
48951
|
+
await recordGateEvidence2(process.cwd(), evidenceTaskId, targetAgentForEvidence, input.sessionID);
|
|
48952
|
+
} else {
|
|
48953
|
+
const { recordAgentDispatch: recordAgentDispatch2 } = await Promise.resolve().then(() => (init_gate_evidence(), exports_gate_evidence));
|
|
48954
|
+
await recordAgentDispatch2(process.cwd(), evidenceTaskId, targetAgentForEvidence);
|
|
48955
|
+
}
|
|
48956
|
+
} catch {}
|
|
48957
|
+
}
|
|
48958
|
+
}
|
|
48777
48959
|
if (storedArgs !== undefined) {
|
|
48778
48960
|
deleteStoredInputArgs(input.callID);
|
|
48779
48961
|
}
|
|
@@ -48866,6 +49048,21 @@ function createDelegationGateHook(config3) {
|
|
|
48866
49048
|
}
|
|
48867
49049
|
}
|
|
48868
49050
|
}
|
|
49051
|
+
{
|
|
49052
|
+
const evidenceTaskId = session.currentTaskId ?? session.lastCoderDelegationTaskId;
|
|
49053
|
+
if (evidenceTaskId) {
|
|
49054
|
+
try {
|
|
49055
|
+
if (hasReviewer) {
|
|
49056
|
+
const { recordGateEvidence: recordGateEvidence2 } = await Promise.resolve().then(() => (init_gate_evidence(), exports_gate_evidence));
|
|
49057
|
+
await recordGateEvidence2(process.cwd(), evidenceTaskId, "reviewer", input.sessionID);
|
|
49058
|
+
}
|
|
49059
|
+
if (hasTestEngineer) {
|
|
49060
|
+
const { recordGateEvidence: recordGateEvidence2 } = await Promise.resolve().then(() => (init_gate_evidence(), exports_gate_evidence));
|
|
49061
|
+
await recordGateEvidence2(process.cwd(), evidenceTaskId, "test_engineer", input.sessionID);
|
|
49062
|
+
}
|
|
49063
|
+
} catch {}
|
|
49064
|
+
}
|
|
49065
|
+
}
|
|
48869
49066
|
}
|
|
48870
49067
|
}
|
|
48871
49068
|
};
|
|
@@ -49057,11 +49254,11 @@ ${trimComment}${after}`;
|
|
|
49057
49254
|
if (!hasReviewer || !hasTestEngineer || priorTaskStuckAtCoder) {
|
|
49058
49255
|
if (session.qaSkipCount >= 1) {
|
|
49059
49256
|
const skippedTasks = session.qaSkipTaskIds.join(", ");
|
|
49060
|
-
throw new Error(`\uD83D\uDED1 QA GATE ENFORCEMENT: ${session.qaSkipCount + 1} consecutive coder delegations without reviewer/test_engineer.
|
|
49257
|
+
throw new Error(`\uD83D\uDED1 QA GATE ENFORCEMENT: ${session.qaSkipCount + 1} consecutive coder delegations without reviewer/test_engineer. Skipped tasks: [${skippedTasks}]. DELEGATE to reviewer and test_engineer NOW before any further coder work.`);
|
|
49061
49258
|
}
|
|
49062
49259
|
session.qaSkipCount++;
|
|
49063
49260
|
session.qaSkipTaskIds.push(currentTaskId ?? "unknown");
|
|
49064
|
-
warnings.push(`\u26A0\uFE0F PROTOCOL VIOLATION: Previous coder task completed, but QA gate was skipped. ` + `You MUST delegate to reviewer (code review) and test_engineer (test execution)
|
|
49261
|
+
warnings.push(`\u26A0\uFE0F PROTOCOL VIOLATION: Previous coder task completed, but QA gate was skipped. ` + `You MUST delegate to reviewer (code review) and test_engineer (test execution) before starting a new coder task. Review RULES 7-8 in your system prompt.`);
|
|
49065
49262
|
}
|
|
49066
49263
|
}
|
|
49067
49264
|
}
|
|
@@ -49413,7 +49610,7 @@ import * as fs16 from "fs";
|
|
|
49413
49610
|
init_utils2();
|
|
49414
49611
|
init_manager2();
|
|
49415
49612
|
import * as fs15 from "fs";
|
|
49416
|
-
import * as
|
|
49613
|
+
import * as path28 from "path";
|
|
49417
49614
|
var DEFAULT_DRIFT_CONFIG = {
|
|
49418
49615
|
staleThresholdPhases: 1,
|
|
49419
49616
|
detectContradictions: true,
|
|
@@ -49567,7 +49764,7 @@ async function analyzeDecisionDrift(directory, config3 = {}) {
|
|
|
49567
49764
|
currentPhase = legacyPhase;
|
|
49568
49765
|
}
|
|
49569
49766
|
}
|
|
49570
|
-
const contextPath =
|
|
49767
|
+
const contextPath = path28.join(directory, ".swarm", "context.md");
|
|
49571
49768
|
let contextContent = "";
|
|
49572
49769
|
try {
|
|
49573
49770
|
if (fs15.existsSync(contextPath)) {
|
|
@@ -51190,7 +51387,7 @@ function createDarkMatterDetectorHook(directory) {
|
|
|
51190
51387
|
// src/hooks/knowledge-reader.ts
|
|
51191
51388
|
import { existsSync as existsSync18 } from "fs";
|
|
51192
51389
|
import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
|
|
51193
|
-
import * as
|
|
51390
|
+
import * as path29 from "path";
|
|
51194
51391
|
var JACCARD_THRESHOLD = 0.6;
|
|
51195
51392
|
var HIVE_TIER_BOOST = 0.05;
|
|
51196
51393
|
var SAME_PROJECT_PENALTY = -0.05;
|
|
@@ -51238,7 +51435,7 @@ function inferCategoriesFromPhase(phaseDescription) {
|
|
|
51238
51435
|
return ["process", "tooling"];
|
|
51239
51436
|
}
|
|
51240
51437
|
async function recordLessonsShown(directory, lessonIds, currentPhase) {
|
|
51241
|
-
const shownFile =
|
|
51438
|
+
const shownFile = path29.join(directory, ".swarm", ".knowledge-shown.json");
|
|
51242
51439
|
try {
|
|
51243
51440
|
let shownData = {};
|
|
51244
51441
|
if (existsSync18(shownFile)) {
|
|
@@ -51246,7 +51443,7 @@ async function recordLessonsShown(directory, lessonIds, currentPhase) {
|
|
|
51246
51443
|
shownData = JSON.parse(content);
|
|
51247
51444
|
}
|
|
51248
51445
|
shownData[currentPhase] = lessonIds;
|
|
51249
|
-
await mkdir4(
|
|
51446
|
+
await mkdir4(path29.dirname(shownFile), { recursive: true });
|
|
51250
51447
|
await writeFile4(shownFile, JSON.stringify(shownData, null, 2), "utf-8");
|
|
51251
51448
|
} catch {
|
|
51252
51449
|
console.warn("[swarm] Knowledge: failed to record shown lessons");
|
|
@@ -51341,7 +51538,7 @@ async function readMergedKnowledge(directory, config3, context) {
|
|
|
51341
51538
|
return topN;
|
|
51342
51539
|
}
|
|
51343
51540
|
async function updateRetrievalOutcome(directory, phaseInfo, phaseSucceeded) {
|
|
51344
|
-
const shownFile =
|
|
51541
|
+
const shownFile = path29.join(directory, ".swarm", ".knowledge-shown.json");
|
|
51345
51542
|
try {
|
|
51346
51543
|
if (!existsSync18(shownFile)) {
|
|
51347
51544
|
return;
|
|
@@ -51814,10 +52011,10 @@ Use this data to avoid repeating known failure patterns.`;
|
|
|
51814
52011
|
init_event_bus();
|
|
51815
52012
|
init_utils2();
|
|
51816
52013
|
import * as fs17 from "fs";
|
|
51817
|
-
import * as
|
|
52014
|
+
import * as path30 from "path";
|
|
51818
52015
|
var DRIFT_REPORT_PREFIX = "drift-report-phase-";
|
|
51819
52016
|
async function readPriorDriftReports(directory) {
|
|
51820
|
-
const swarmDir =
|
|
52017
|
+
const swarmDir = path30.join(directory, ".swarm");
|
|
51821
52018
|
const entries = await fs17.promises.readdir(swarmDir).catch(() => null);
|
|
51822
52019
|
if (entries === null)
|
|
51823
52020
|
return [];
|
|
@@ -51844,7 +52041,7 @@ async function readPriorDriftReports(directory) {
|
|
|
51844
52041
|
async function writeDriftReport(directory, report) {
|
|
51845
52042
|
const filename = `${DRIFT_REPORT_PREFIX}${report.phase}.json`;
|
|
51846
52043
|
const filePath = validateSwarmPath(directory, filename);
|
|
51847
|
-
const swarmDir =
|
|
52044
|
+
const swarmDir = path30.dirname(filePath);
|
|
51848
52045
|
await fs17.promises.mkdir(swarmDir, { recursive: true });
|
|
51849
52046
|
try {
|
|
51850
52047
|
await fs17.promises.writeFile(filePath, JSON.stringify(report, null, 2), "utf-8");
|
|
@@ -52153,7 +52350,7 @@ init_config_doctor();
|
|
|
52153
52350
|
|
|
52154
52351
|
// src/session/snapshot-reader.ts
|
|
52155
52352
|
init_utils2();
|
|
52156
|
-
import
|
|
52353
|
+
import path31 from "path";
|
|
52157
52354
|
var VALID_TASK_WORKFLOW_STATES = [
|
|
52158
52355
|
"idle",
|
|
52159
52356
|
"coder_delegated",
|
|
@@ -52276,7 +52473,7 @@ function rehydrateState(snapshot) {
|
|
|
52276
52473
|
async function reconcileTaskStatesFromPlan(directory) {
|
|
52277
52474
|
let raw;
|
|
52278
52475
|
try {
|
|
52279
|
-
raw = await Bun.file(
|
|
52476
|
+
raw = await Bun.file(path31.join(directory, ".swarm/plan.json")).text();
|
|
52280
52477
|
} catch {
|
|
52281
52478
|
return;
|
|
52282
52479
|
}
|
|
@@ -52500,7 +52697,7 @@ init_tool();
|
|
|
52500
52697
|
init_create_tool();
|
|
52501
52698
|
import { spawnSync } from "child_process";
|
|
52502
52699
|
import * as fs19 from "fs";
|
|
52503
|
-
import * as
|
|
52700
|
+
import * as path32 from "path";
|
|
52504
52701
|
var CHECKPOINT_LOG_PATH = ".swarm/checkpoints.json";
|
|
52505
52702
|
var MAX_LABEL_LENGTH = 100;
|
|
52506
52703
|
var GIT_TIMEOUT_MS = 30000;
|
|
@@ -52551,7 +52748,7 @@ function validateLabel(label) {
|
|
|
52551
52748
|
return null;
|
|
52552
52749
|
}
|
|
52553
52750
|
function getCheckpointLogPath(directory) {
|
|
52554
|
-
return
|
|
52751
|
+
return path32.join(directory, CHECKPOINT_LOG_PATH);
|
|
52555
52752
|
}
|
|
52556
52753
|
function readCheckpointLog(directory) {
|
|
52557
52754
|
const logPath = getCheckpointLogPath(directory);
|
|
@@ -52569,7 +52766,7 @@ function readCheckpointLog(directory) {
|
|
|
52569
52766
|
}
|
|
52570
52767
|
function writeCheckpointLog(log2, directory) {
|
|
52571
52768
|
const logPath = getCheckpointLogPath(directory);
|
|
52572
|
-
const dir =
|
|
52769
|
+
const dir = path32.dirname(logPath);
|
|
52573
52770
|
if (!fs19.existsSync(dir)) {
|
|
52574
52771
|
fs19.mkdirSync(dir, { recursive: true });
|
|
52575
52772
|
}
|
|
@@ -52777,7 +52974,7 @@ var checkpoint = createSwarmTool({
|
|
|
52777
52974
|
init_dist();
|
|
52778
52975
|
init_create_tool();
|
|
52779
52976
|
import * as fs20 from "fs";
|
|
52780
|
-
import * as
|
|
52977
|
+
import * as path33 from "path";
|
|
52781
52978
|
var MAX_FILE_SIZE_BYTES2 = 256 * 1024;
|
|
52782
52979
|
var DEFAULT_DAYS = 90;
|
|
52783
52980
|
var DEFAULT_TOP_N = 20;
|
|
@@ -52921,7 +53118,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
52921
53118
|
const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
|
|
52922
53119
|
const filteredChurn = new Map;
|
|
52923
53120
|
for (const [file3, count] of churnMap) {
|
|
52924
|
-
const ext =
|
|
53121
|
+
const ext = path33.extname(file3).toLowerCase();
|
|
52925
53122
|
if (extSet.has(ext)) {
|
|
52926
53123
|
filteredChurn.set(file3, count);
|
|
52927
53124
|
}
|
|
@@ -52932,7 +53129,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
52932
53129
|
for (const [file3, churnCount] of filteredChurn) {
|
|
52933
53130
|
let fullPath = file3;
|
|
52934
53131
|
if (!fs20.existsSync(fullPath)) {
|
|
52935
|
-
fullPath =
|
|
53132
|
+
fullPath = path33.join(cwd, file3);
|
|
52936
53133
|
}
|
|
52937
53134
|
const complexity = getComplexityForFile(fullPath);
|
|
52938
53135
|
if (complexity !== null) {
|
|
@@ -53080,7 +53277,7 @@ var complexity_hotspots = createSwarmTool({
|
|
|
53080
53277
|
// src/tools/declare-scope.ts
|
|
53081
53278
|
init_tool();
|
|
53082
53279
|
import * as fs21 from "fs";
|
|
53083
|
-
import * as
|
|
53280
|
+
import * as path34 from "path";
|
|
53084
53281
|
init_create_tool();
|
|
53085
53282
|
function validateTaskIdFormat(taskId) {
|
|
53086
53283
|
const taskIdPattern = /^\d+\.\d+(\.\d+)*$/;
|
|
@@ -53159,8 +53356,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
53159
53356
|
};
|
|
53160
53357
|
}
|
|
53161
53358
|
}
|
|
53162
|
-
normalizedDir =
|
|
53163
|
-
const pathParts = normalizedDir.split(
|
|
53359
|
+
normalizedDir = path34.normalize(args2.working_directory);
|
|
53360
|
+
const pathParts = normalizedDir.split(path34.sep);
|
|
53164
53361
|
if (pathParts.includes("..")) {
|
|
53165
53362
|
return {
|
|
53166
53363
|
success: false,
|
|
@@ -53170,10 +53367,10 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
53170
53367
|
]
|
|
53171
53368
|
};
|
|
53172
53369
|
}
|
|
53173
|
-
const resolvedDir =
|
|
53370
|
+
const resolvedDir = path34.resolve(normalizedDir);
|
|
53174
53371
|
try {
|
|
53175
53372
|
const realPath = fs21.realpathSync(resolvedDir);
|
|
53176
|
-
const planPath2 =
|
|
53373
|
+
const planPath2 = path34.join(realPath, ".swarm", "plan.json");
|
|
53177
53374
|
if (!fs21.existsSync(planPath2)) {
|
|
53178
53375
|
return {
|
|
53179
53376
|
success: false,
|
|
@@ -53194,7 +53391,7 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
53194
53391
|
}
|
|
53195
53392
|
}
|
|
53196
53393
|
const directory = normalizedDir ?? fallbackDir ?? process.cwd();
|
|
53197
|
-
const planPath =
|
|
53394
|
+
const planPath = path34.resolve(directory, ".swarm", "plan.json");
|
|
53198
53395
|
if (!fs21.existsSync(planPath)) {
|
|
53199
53396
|
return {
|
|
53200
53397
|
success: false,
|
|
@@ -53284,20 +53481,20 @@ function validateBase(base) {
|
|
|
53284
53481
|
function validatePaths(paths) {
|
|
53285
53482
|
if (!paths)
|
|
53286
53483
|
return null;
|
|
53287
|
-
for (const
|
|
53288
|
-
if (!
|
|
53484
|
+
for (const path35 of paths) {
|
|
53485
|
+
if (!path35 || path35.length === 0) {
|
|
53289
53486
|
return "empty path not allowed";
|
|
53290
53487
|
}
|
|
53291
|
-
if (
|
|
53488
|
+
if (path35.length > MAX_PATH_LENGTH) {
|
|
53292
53489
|
return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
|
|
53293
53490
|
}
|
|
53294
|
-
if (SHELL_METACHARACTERS2.test(
|
|
53491
|
+
if (SHELL_METACHARACTERS2.test(path35)) {
|
|
53295
53492
|
return "path contains shell metacharacters";
|
|
53296
53493
|
}
|
|
53297
|
-
if (
|
|
53494
|
+
if (path35.startsWith("-")) {
|
|
53298
53495
|
return 'path cannot start with "-" (option-like arguments not allowed)';
|
|
53299
53496
|
}
|
|
53300
|
-
if (CONTROL_CHAR_PATTERN2.test(
|
|
53497
|
+
if (CONTROL_CHAR_PATTERN2.test(path35)) {
|
|
53301
53498
|
return "path contains control characters";
|
|
53302
53499
|
}
|
|
53303
53500
|
}
|
|
@@ -53377,8 +53574,8 @@ var diff = tool({
|
|
|
53377
53574
|
if (parts2.length >= 3) {
|
|
53378
53575
|
const additions = parseInt(parts2[0], 10) || 0;
|
|
53379
53576
|
const deletions = parseInt(parts2[1], 10) || 0;
|
|
53380
|
-
const
|
|
53381
|
-
files.push({ path:
|
|
53577
|
+
const path35 = parts2[2];
|
|
53578
|
+
files.push({ path: path35, additions, deletions });
|
|
53382
53579
|
}
|
|
53383
53580
|
}
|
|
53384
53581
|
const contractChanges = [];
|
|
@@ -53608,7 +53805,7 @@ Use these as DOMAIN values when delegating to @sme.`;
|
|
|
53608
53805
|
init_dist();
|
|
53609
53806
|
init_create_tool();
|
|
53610
53807
|
import * as fs22 from "fs";
|
|
53611
|
-
import * as
|
|
53808
|
+
import * as path35 from "path";
|
|
53612
53809
|
var MAX_FILE_SIZE_BYTES3 = 1024 * 1024;
|
|
53613
53810
|
var MAX_EVIDENCE_FILES = 1000;
|
|
53614
53811
|
var EVIDENCE_DIR = ".swarm/evidence";
|
|
@@ -53631,9 +53828,9 @@ function validateRequiredTypes(input) {
|
|
|
53631
53828
|
return null;
|
|
53632
53829
|
}
|
|
53633
53830
|
function isPathWithinSwarm(filePath, cwd) {
|
|
53634
|
-
const normalizedCwd =
|
|
53635
|
-
const swarmPath =
|
|
53636
|
-
const normalizedPath =
|
|
53831
|
+
const normalizedCwd = path35.resolve(cwd);
|
|
53832
|
+
const swarmPath = path35.join(normalizedCwd, ".swarm");
|
|
53833
|
+
const normalizedPath = path35.resolve(filePath);
|
|
53637
53834
|
return normalizedPath.startsWith(swarmPath);
|
|
53638
53835
|
}
|
|
53639
53836
|
function parseCompletedTasks(planContent) {
|
|
@@ -53663,10 +53860,10 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
53663
53860
|
if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
|
|
53664
53861
|
continue;
|
|
53665
53862
|
}
|
|
53666
|
-
const filePath =
|
|
53863
|
+
const filePath = path35.join(evidenceDir, filename);
|
|
53667
53864
|
try {
|
|
53668
|
-
const resolvedPath =
|
|
53669
|
-
const evidenceDirResolved =
|
|
53865
|
+
const resolvedPath = path35.resolve(filePath);
|
|
53866
|
+
const evidenceDirResolved = path35.resolve(evidenceDir);
|
|
53670
53867
|
if (!resolvedPath.startsWith(evidenceDirResolved)) {
|
|
53671
53868
|
continue;
|
|
53672
53869
|
}
|
|
@@ -53773,7 +53970,7 @@ var evidence_check = createSwarmTool({
|
|
|
53773
53970
|
return JSON.stringify(errorResult, null, 2);
|
|
53774
53971
|
}
|
|
53775
53972
|
const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
53776
|
-
const planPath =
|
|
53973
|
+
const planPath = path35.join(cwd, PLAN_FILE);
|
|
53777
53974
|
if (!isPathWithinSwarm(planPath, cwd)) {
|
|
53778
53975
|
const errorResult = {
|
|
53779
53976
|
error: "plan file path validation failed",
|
|
@@ -53805,7 +54002,7 @@ var evidence_check = createSwarmTool({
|
|
|
53805
54002
|
};
|
|
53806
54003
|
return JSON.stringify(result2, null, 2);
|
|
53807
54004
|
}
|
|
53808
|
-
const evidenceDir =
|
|
54005
|
+
const evidenceDir = path35.join(cwd, EVIDENCE_DIR);
|
|
53809
54006
|
const evidence = readEvidenceFiles(evidenceDir, cwd);
|
|
53810
54007
|
const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
|
|
53811
54008
|
const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
|
|
@@ -53823,7 +54020,7 @@ var evidence_check = createSwarmTool({
|
|
|
53823
54020
|
init_tool();
|
|
53824
54021
|
init_create_tool();
|
|
53825
54022
|
import * as fs23 from "fs";
|
|
53826
|
-
import * as
|
|
54023
|
+
import * as path36 from "path";
|
|
53827
54024
|
var EXT_MAP = {
|
|
53828
54025
|
python: ".py",
|
|
53829
54026
|
py: ".py",
|
|
@@ -53904,12 +54101,12 @@ var extract_code_blocks = createSwarmTool({
|
|
|
53904
54101
|
if (prefix) {
|
|
53905
54102
|
filename = `${prefix}_${filename}`;
|
|
53906
54103
|
}
|
|
53907
|
-
let filepath =
|
|
53908
|
-
const base =
|
|
53909
|
-
const ext =
|
|
54104
|
+
let filepath = path36.join(targetDir, filename);
|
|
54105
|
+
const base = path36.basename(filepath, path36.extname(filepath));
|
|
54106
|
+
const ext = path36.extname(filepath);
|
|
53910
54107
|
let counter = 1;
|
|
53911
54108
|
while (fs23.existsSync(filepath)) {
|
|
53912
|
-
filepath =
|
|
54109
|
+
filepath = path36.join(targetDir, `${base}_${counter}${ext}`);
|
|
53913
54110
|
counter++;
|
|
53914
54111
|
}
|
|
53915
54112
|
try {
|
|
@@ -54027,7 +54224,7 @@ var gitingest = tool({
|
|
|
54027
54224
|
// src/tools/imports.ts
|
|
54028
54225
|
init_dist();
|
|
54029
54226
|
import * as fs24 from "fs";
|
|
54030
|
-
import * as
|
|
54227
|
+
import * as path37 from "path";
|
|
54031
54228
|
var MAX_FILE_PATH_LENGTH2 = 500;
|
|
54032
54229
|
var MAX_SYMBOL_LENGTH = 256;
|
|
54033
54230
|
var MAX_FILE_SIZE_BYTES4 = 1024 * 1024;
|
|
@@ -54081,7 +54278,7 @@ function validateSymbolInput(symbol3) {
|
|
|
54081
54278
|
return null;
|
|
54082
54279
|
}
|
|
54083
54280
|
function isBinaryFile2(filePath, buffer) {
|
|
54084
|
-
const ext =
|
|
54281
|
+
const ext = path37.extname(filePath).toLowerCase();
|
|
54085
54282
|
if (ext === ".json" || ext === ".md" || ext === ".txt") {
|
|
54086
54283
|
return false;
|
|
54087
54284
|
}
|
|
@@ -54105,15 +54302,15 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
54105
54302
|
const imports = [];
|
|
54106
54303
|
let _resolvedTarget;
|
|
54107
54304
|
try {
|
|
54108
|
-
_resolvedTarget =
|
|
54305
|
+
_resolvedTarget = path37.resolve(targetFile);
|
|
54109
54306
|
} catch {
|
|
54110
54307
|
_resolvedTarget = targetFile;
|
|
54111
54308
|
}
|
|
54112
|
-
const targetBasename =
|
|
54309
|
+
const targetBasename = path37.basename(targetFile, path37.extname(targetFile));
|
|
54113
54310
|
const targetWithExt = targetFile;
|
|
54114
54311
|
const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
54115
|
-
const normalizedTargetWithExt =
|
|
54116
|
-
const normalizedTargetWithoutExt =
|
|
54312
|
+
const normalizedTargetWithExt = path37.normalize(targetWithExt).replace(/\\/g, "/");
|
|
54313
|
+
const normalizedTargetWithoutExt = path37.normalize(targetWithoutExt).replace(/\\/g, "/");
|
|
54117
54314
|
const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
|
|
54118
54315
|
for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
|
|
54119
54316
|
const modulePath = match[1] || match[2] || match[3];
|
|
@@ -54136,9 +54333,9 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
54136
54333
|
}
|
|
54137
54334
|
const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
|
|
54138
54335
|
let isMatch = false;
|
|
54139
|
-
const _targetDir =
|
|
54140
|
-
const targetExt =
|
|
54141
|
-
const targetBasenameNoExt =
|
|
54336
|
+
const _targetDir = path37.dirname(targetFile);
|
|
54337
|
+
const targetExt = path37.extname(targetFile);
|
|
54338
|
+
const targetBasenameNoExt = path37.basename(targetFile, targetExt);
|
|
54142
54339
|
const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
54143
54340
|
const moduleName = modulePath.split(/[/\\]/).pop() || "";
|
|
54144
54341
|
const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
@@ -54206,10 +54403,10 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
54206
54403
|
entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
|
54207
54404
|
for (const entry of entries) {
|
|
54208
54405
|
if (SKIP_DIRECTORIES2.has(entry)) {
|
|
54209
|
-
stats.skippedDirs.push(
|
|
54406
|
+
stats.skippedDirs.push(path37.join(dir, entry));
|
|
54210
54407
|
continue;
|
|
54211
54408
|
}
|
|
54212
|
-
const fullPath =
|
|
54409
|
+
const fullPath = path37.join(dir, entry);
|
|
54213
54410
|
let stat2;
|
|
54214
54411
|
try {
|
|
54215
54412
|
stat2 = fs24.statSync(fullPath);
|
|
@@ -54223,7 +54420,7 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
54223
54420
|
if (stat2.isDirectory()) {
|
|
54224
54421
|
findSourceFiles2(fullPath, files, stats);
|
|
54225
54422
|
} else if (stat2.isFile()) {
|
|
54226
|
-
const ext =
|
|
54423
|
+
const ext = path37.extname(fullPath).toLowerCase();
|
|
54227
54424
|
if (SUPPORTED_EXTENSIONS.includes(ext)) {
|
|
54228
54425
|
files.push(fullPath);
|
|
54229
54426
|
}
|
|
@@ -54279,7 +54476,7 @@ var imports = tool({
|
|
|
54279
54476
|
return JSON.stringify(errorResult, null, 2);
|
|
54280
54477
|
}
|
|
54281
54478
|
try {
|
|
54282
|
-
const targetFile =
|
|
54479
|
+
const targetFile = path37.resolve(file3);
|
|
54283
54480
|
if (!fs24.existsSync(targetFile)) {
|
|
54284
54481
|
const errorResult = {
|
|
54285
54482
|
error: `target file not found: ${file3}`,
|
|
@@ -54301,7 +54498,7 @@ var imports = tool({
|
|
|
54301
54498
|
};
|
|
54302
54499
|
return JSON.stringify(errorResult, null, 2);
|
|
54303
54500
|
}
|
|
54304
|
-
const baseDir =
|
|
54501
|
+
const baseDir = path37.dirname(targetFile);
|
|
54305
54502
|
const scanStats = {
|
|
54306
54503
|
skippedDirs: [],
|
|
54307
54504
|
skippedFiles: 0,
|
|
@@ -54623,7 +54820,7 @@ init_config();
|
|
|
54623
54820
|
init_schema();
|
|
54624
54821
|
init_manager();
|
|
54625
54822
|
import * as fs25 from "fs";
|
|
54626
|
-
import * as
|
|
54823
|
+
import * as path38 from "path";
|
|
54627
54824
|
init_utils2();
|
|
54628
54825
|
init_create_tool();
|
|
54629
54826
|
function safeWarn(message, error93) {
|
|
@@ -54818,7 +55015,7 @@ async function executePhaseComplete(args2, workingDirectory) {
|
|
|
54818
55015
|
}
|
|
54819
55016
|
if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
|
|
54820
55017
|
try {
|
|
54821
|
-
const projectName =
|
|
55018
|
+
const projectName = path38.basename(dir);
|
|
54822
55019
|
const knowledgeConfig = {
|
|
54823
55020
|
enabled: true,
|
|
54824
55021
|
swarm_max_entries: 100,
|
|
@@ -54982,7 +55179,7 @@ init_discovery();
|
|
|
54982
55179
|
init_utils();
|
|
54983
55180
|
init_create_tool();
|
|
54984
55181
|
import * as fs26 from "fs";
|
|
54985
|
-
import * as
|
|
55182
|
+
import * as path39 from "path";
|
|
54986
55183
|
var MAX_OUTPUT_BYTES5 = 52428800;
|
|
54987
55184
|
var AUDIT_TIMEOUT_MS = 120000;
|
|
54988
55185
|
function isValidEcosystem(value) {
|
|
@@ -55000,16 +55197,16 @@ function validateArgs3(args2) {
|
|
|
55000
55197
|
function detectEcosystems(directory) {
|
|
55001
55198
|
const ecosystems = [];
|
|
55002
55199
|
const cwd = directory;
|
|
55003
|
-
if (fs26.existsSync(
|
|
55200
|
+
if (fs26.existsSync(path39.join(cwd, "package.json"))) {
|
|
55004
55201
|
ecosystems.push("npm");
|
|
55005
55202
|
}
|
|
55006
|
-
if (fs26.existsSync(
|
|
55203
|
+
if (fs26.existsSync(path39.join(cwd, "pyproject.toml")) || fs26.existsSync(path39.join(cwd, "requirements.txt"))) {
|
|
55007
55204
|
ecosystems.push("pip");
|
|
55008
55205
|
}
|
|
55009
|
-
if (fs26.existsSync(
|
|
55206
|
+
if (fs26.existsSync(path39.join(cwd, "Cargo.toml"))) {
|
|
55010
55207
|
ecosystems.push("cargo");
|
|
55011
55208
|
}
|
|
55012
|
-
if (fs26.existsSync(
|
|
55209
|
+
if (fs26.existsSync(path39.join(cwd, "go.mod"))) {
|
|
55013
55210
|
ecosystems.push("go");
|
|
55014
55211
|
}
|
|
55015
55212
|
try {
|
|
@@ -55018,10 +55215,10 @@ function detectEcosystems(directory) {
|
|
|
55018
55215
|
ecosystems.push("dotnet");
|
|
55019
55216
|
}
|
|
55020
55217
|
} catch {}
|
|
55021
|
-
if (fs26.existsSync(
|
|
55218
|
+
if (fs26.existsSync(path39.join(cwd, "Gemfile")) || fs26.existsSync(path39.join(cwd, "Gemfile.lock"))) {
|
|
55022
55219
|
ecosystems.push("ruby");
|
|
55023
55220
|
}
|
|
55024
|
-
if (fs26.existsSync(
|
|
55221
|
+
if (fs26.existsSync(path39.join(cwd, "pubspec.yaml"))) {
|
|
55025
55222
|
ecosystems.push("dart");
|
|
55026
55223
|
}
|
|
55027
55224
|
return ecosystems;
|
|
@@ -56084,7 +56281,7 @@ var SUPPORTED_PARSER_EXTENSIONS = new Set([
|
|
|
56084
56281
|
// src/tools/pre-check-batch.ts
|
|
56085
56282
|
init_dist();
|
|
56086
56283
|
import * as fs29 from "fs";
|
|
56087
|
-
import * as
|
|
56284
|
+
import * as path42 from "path";
|
|
56088
56285
|
|
|
56089
56286
|
// node_modules/yocto-queue/index.js
|
|
56090
56287
|
class Node2 {
|
|
@@ -56252,7 +56449,7 @@ init_manager();
|
|
|
56252
56449
|
|
|
56253
56450
|
// src/quality/metrics.ts
|
|
56254
56451
|
import * as fs27 from "fs";
|
|
56255
|
-
import * as
|
|
56452
|
+
import * as path40 from "path";
|
|
56256
56453
|
var MAX_FILE_SIZE_BYTES5 = 256 * 1024;
|
|
56257
56454
|
var MIN_DUPLICATION_LINES = 10;
|
|
56258
56455
|
function estimateCyclomaticComplexity(content) {
|
|
@@ -56304,7 +56501,7 @@ async function computeComplexityDelta(files, workingDir) {
|
|
|
56304
56501
|
let totalComplexity = 0;
|
|
56305
56502
|
const analyzedFiles = [];
|
|
56306
56503
|
for (const file3 of files) {
|
|
56307
|
-
const fullPath =
|
|
56504
|
+
const fullPath = path40.isAbsolute(file3) ? file3 : path40.join(workingDir, file3);
|
|
56308
56505
|
if (!fs27.existsSync(fullPath)) {
|
|
56309
56506
|
continue;
|
|
56310
56507
|
}
|
|
@@ -56427,7 +56624,7 @@ function countGoExports(content) {
|
|
|
56427
56624
|
function getExportCountForFile(filePath) {
|
|
56428
56625
|
try {
|
|
56429
56626
|
const content = fs27.readFileSync(filePath, "utf-8");
|
|
56430
|
-
const ext =
|
|
56627
|
+
const ext = path40.extname(filePath).toLowerCase();
|
|
56431
56628
|
switch (ext) {
|
|
56432
56629
|
case ".ts":
|
|
56433
56630
|
case ".tsx":
|
|
@@ -56453,7 +56650,7 @@ async function computePublicApiDelta(files, workingDir) {
|
|
|
56453
56650
|
let totalExports = 0;
|
|
56454
56651
|
const analyzedFiles = [];
|
|
56455
56652
|
for (const file3 of files) {
|
|
56456
|
-
const fullPath =
|
|
56653
|
+
const fullPath = path40.isAbsolute(file3) ? file3 : path40.join(workingDir, file3);
|
|
56457
56654
|
if (!fs27.existsSync(fullPath)) {
|
|
56458
56655
|
continue;
|
|
56459
56656
|
}
|
|
@@ -56487,7 +56684,7 @@ async function computeDuplicationRatio(files, workingDir) {
|
|
|
56487
56684
|
let duplicateLines = 0;
|
|
56488
56685
|
const analyzedFiles = [];
|
|
56489
56686
|
for (const file3 of files) {
|
|
56490
|
-
const fullPath =
|
|
56687
|
+
const fullPath = path40.isAbsolute(file3) ? file3 : path40.join(workingDir, file3);
|
|
56491
56688
|
if (!fs27.existsSync(fullPath)) {
|
|
56492
56689
|
continue;
|
|
56493
56690
|
}
|
|
@@ -56520,8 +56717,8 @@ function countCodeLines(content) {
|
|
|
56520
56717
|
return lines.length;
|
|
56521
56718
|
}
|
|
56522
56719
|
function isTestFile(filePath) {
|
|
56523
|
-
const basename8 =
|
|
56524
|
-
const _ext =
|
|
56720
|
+
const basename8 = path40.basename(filePath);
|
|
56721
|
+
const _ext = path40.extname(filePath).toLowerCase();
|
|
56525
56722
|
const testPatterns = [
|
|
56526
56723
|
".test.",
|
|
56527
56724
|
".spec.",
|
|
@@ -56602,8 +56799,8 @@ function matchGlobSegment(globSegments, pathSegments) {
|
|
|
56602
56799
|
}
|
|
56603
56800
|
return gIndex === globSegments.length && pIndex === pathSegments.length;
|
|
56604
56801
|
}
|
|
56605
|
-
function matchesGlobSegment(
|
|
56606
|
-
const normalizedPath =
|
|
56802
|
+
function matchesGlobSegment(path41, glob) {
|
|
56803
|
+
const normalizedPath = path41.replace(/\\/g, "/");
|
|
56607
56804
|
const normalizedGlob = glob.replace(/\\/g, "/");
|
|
56608
56805
|
if (normalizedPath.includes("//")) {
|
|
56609
56806
|
return false;
|
|
@@ -56634,8 +56831,8 @@ function simpleGlobToRegex2(glob) {
|
|
|
56634
56831
|
function hasGlobstar(glob) {
|
|
56635
56832
|
return glob.includes("**");
|
|
56636
56833
|
}
|
|
56637
|
-
function globMatches(
|
|
56638
|
-
const normalizedPath =
|
|
56834
|
+
function globMatches(path41, glob) {
|
|
56835
|
+
const normalizedPath = path41.replace(/\\/g, "/");
|
|
56639
56836
|
if (!glob || glob === "") {
|
|
56640
56837
|
if (normalizedPath.includes("//")) {
|
|
56641
56838
|
return false;
|
|
@@ -56671,7 +56868,7 @@ function shouldExcludeFile(filePath, excludeGlobs) {
|
|
|
56671
56868
|
async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
56672
56869
|
let testLines = 0;
|
|
56673
56870
|
let codeLines = 0;
|
|
56674
|
-
const srcDir =
|
|
56871
|
+
const srcDir = path40.join(workingDir, "src");
|
|
56675
56872
|
if (fs27.existsSync(srcDir)) {
|
|
56676
56873
|
await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
56677
56874
|
codeLines += lines;
|
|
@@ -56679,14 +56876,14 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
56679
56876
|
}
|
|
56680
56877
|
const possibleSrcDirs = ["lib", "app", "source", "core"];
|
|
56681
56878
|
for (const dir of possibleSrcDirs) {
|
|
56682
|
-
const dirPath =
|
|
56879
|
+
const dirPath = path40.join(workingDir, dir);
|
|
56683
56880
|
if (fs27.existsSync(dirPath)) {
|
|
56684
56881
|
await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
56685
56882
|
codeLines += lines;
|
|
56686
56883
|
});
|
|
56687
56884
|
}
|
|
56688
56885
|
}
|
|
56689
|
-
const testsDir =
|
|
56886
|
+
const testsDir = path40.join(workingDir, "tests");
|
|
56690
56887
|
if (fs27.existsSync(testsDir)) {
|
|
56691
56888
|
await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
56692
56889
|
testLines += lines;
|
|
@@ -56694,7 +56891,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
56694
56891
|
}
|
|
56695
56892
|
const possibleTestDirs = ["test", "__tests__", "specs"];
|
|
56696
56893
|
for (const dir of possibleTestDirs) {
|
|
56697
|
-
const dirPath =
|
|
56894
|
+
const dirPath = path40.join(workingDir, dir);
|
|
56698
56895
|
if (fs27.existsSync(dirPath) && dirPath !== testsDir) {
|
|
56699
56896
|
await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
56700
56897
|
testLines += lines;
|
|
@@ -56709,7 +56906,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
56709
56906
|
try {
|
|
56710
56907
|
const entries = fs27.readdirSync(dirPath, { withFileTypes: true });
|
|
56711
56908
|
for (const entry of entries) {
|
|
56712
|
-
const fullPath =
|
|
56909
|
+
const fullPath = path40.join(dirPath, entry.name);
|
|
56713
56910
|
if (entry.isDirectory()) {
|
|
56714
56911
|
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
|
|
56715
56912
|
continue;
|
|
@@ -56717,7 +56914,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
56717
56914
|
await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
|
|
56718
56915
|
} else if (entry.isFile()) {
|
|
56719
56916
|
const relativePath = fullPath.replace(`${process.cwd()}/`, "");
|
|
56720
|
-
const ext =
|
|
56917
|
+
const ext = path40.extname(entry.name).toLowerCase();
|
|
56721
56918
|
const validExts = [
|
|
56722
56919
|
".ts",
|
|
56723
56920
|
".tsx",
|
|
@@ -56968,7 +57165,7 @@ init_dist();
|
|
|
56968
57165
|
init_manager();
|
|
56969
57166
|
init_detector();
|
|
56970
57167
|
import * as fs28 from "fs";
|
|
56971
|
-
import * as
|
|
57168
|
+
import * as path41 from "path";
|
|
56972
57169
|
import { extname as extname9 } from "path";
|
|
56973
57170
|
|
|
56974
57171
|
// src/sast/rules/c.ts
|
|
@@ -57931,7 +58128,7 @@ async function sastScan(input, directory, config3) {
|
|
|
57931
58128
|
_filesSkipped++;
|
|
57932
58129
|
continue;
|
|
57933
58130
|
}
|
|
57934
|
-
const resolvedPath =
|
|
58131
|
+
const resolvedPath = path41.isAbsolute(filePath) ? filePath : path41.resolve(directory, filePath);
|
|
57935
58132
|
if (!fs28.existsSync(resolvedPath)) {
|
|
57936
58133
|
_filesSkipped++;
|
|
57937
58134
|
continue;
|
|
@@ -58130,18 +58327,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
|
|
|
58130
58327
|
let resolved;
|
|
58131
58328
|
const isWinAbs = isWindowsAbsolutePath(inputPath);
|
|
58132
58329
|
if (isWinAbs) {
|
|
58133
|
-
resolved =
|
|
58134
|
-
} else if (
|
|
58135
|
-
resolved =
|
|
58330
|
+
resolved = path42.win32.resolve(inputPath);
|
|
58331
|
+
} else if (path42.isAbsolute(inputPath)) {
|
|
58332
|
+
resolved = path42.resolve(inputPath);
|
|
58136
58333
|
} else {
|
|
58137
|
-
resolved =
|
|
58334
|
+
resolved = path42.resolve(baseDir, inputPath);
|
|
58138
58335
|
}
|
|
58139
|
-
const workspaceResolved =
|
|
58336
|
+
const workspaceResolved = path42.resolve(workspaceDir);
|
|
58140
58337
|
let relative5;
|
|
58141
58338
|
if (isWinAbs) {
|
|
58142
|
-
relative5 =
|
|
58339
|
+
relative5 = path42.win32.relative(workspaceResolved, resolved);
|
|
58143
58340
|
} else {
|
|
58144
|
-
relative5 =
|
|
58341
|
+
relative5 = path42.relative(workspaceResolved, resolved);
|
|
58145
58342
|
}
|
|
58146
58343
|
if (relative5.startsWith("..")) {
|
|
58147
58344
|
return "path traversal detected";
|
|
@@ -58202,13 +58399,13 @@ async function runLintWrapped(files, directory, _config) {
|
|
|
58202
58399
|
}
|
|
58203
58400
|
async function runLintOnFiles(linter, files, workspaceDir) {
|
|
58204
58401
|
const isWindows = process.platform === "win32";
|
|
58205
|
-
const binDir =
|
|
58402
|
+
const binDir = path42.join(workspaceDir, "node_modules", ".bin");
|
|
58206
58403
|
const validatedFiles = [];
|
|
58207
58404
|
for (const file3 of files) {
|
|
58208
58405
|
if (typeof file3 !== "string") {
|
|
58209
58406
|
continue;
|
|
58210
58407
|
}
|
|
58211
|
-
const resolvedPath =
|
|
58408
|
+
const resolvedPath = path42.resolve(file3);
|
|
58212
58409
|
const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
|
|
58213
58410
|
if (validationError) {
|
|
58214
58411
|
continue;
|
|
@@ -58226,10 +58423,10 @@ async function runLintOnFiles(linter, files, workspaceDir) {
|
|
|
58226
58423
|
}
|
|
58227
58424
|
let command;
|
|
58228
58425
|
if (linter === "biome") {
|
|
58229
|
-
const biomeBin = isWindows ?
|
|
58426
|
+
const biomeBin = isWindows ? path42.join(binDir, "biome.EXE") : path42.join(binDir, "biome");
|
|
58230
58427
|
command = [biomeBin, "check", ...validatedFiles];
|
|
58231
58428
|
} else {
|
|
58232
|
-
const eslintBin = isWindows ?
|
|
58429
|
+
const eslintBin = isWindows ? path42.join(binDir, "eslint.cmd") : path42.join(binDir, "eslint");
|
|
58233
58430
|
command = [eslintBin, ...validatedFiles];
|
|
58234
58431
|
}
|
|
58235
58432
|
try {
|
|
@@ -58366,7 +58563,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
58366
58563
|
skippedFiles++;
|
|
58367
58564
|
continue;
|
|
58368
58565
|
}
|
|
58369
|
-
const resolvedPath =
|
|
58566
|
+
const resolvedPath = path42.resolve(file3);
|
|
58370
58567
|
const validationError = validatePath(resolvedPath, directory, directory);
|
|
58371
58568
|
if (validationError) {
|
|
58372
58569
|
skippedFiles++;
|
|
@@ -58384,7 +58581,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
58384
58581
|
};
|
|
58385
58582
|
}
|
|
58386
58583
|
for (const file3 of validatedFiles) {
|
|
58387
|
-
const ext =
|
|
58584
|
+
const ext = path42.extname(file3).toLowerCase();
|
|
58388
58585
|
if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
|
|
58389
58586
|
skippedFiles++;
|
|
58390
58587
|
continue;
|
|
@@ -58543,7 +58740,7 @@ async function runPreCheckBatch(input, workspaceDir) {
|
|
|
58543
58740
|
warn(`pre_check_batch: Invalid file path: ${file3}`);
|
|
58544
58741
|
continue;
|
|
58545
58742
|
}
|
|
58546
|
-
changedFiles.push(
|
|
58743
|
+
changedFiles.push(path42.resolve(directory, file3));
|
|
58547
58744
|
}
|
|
58548
58745
|
if (changedFiles.length === 0) {
|
|
58549
58746
|
warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
|
|
@@ -58694,7 +58891,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
58694
58891
|
};
|
|
58695
58892
|
return JSON.stringify(errorResult, null, 2);
|
|
58696
58893
|
}
|
|
58697
|
-
const resolvedDirectory =
|
|
58894
|
+
const resolvedDirectory = path42.resolve(typedArgs.directory);
|
|
58698
58895
|
const workspaceAnchor = resolvedDirectory;
|
|
58699
58896
|
const dirError = validateDirectory3(resolvedDirectory, workspaceAnchor);
|
|
58700
58897
|
if (dirError) {
|
|
@@ -58802,7 +58999,7 @@ init_tool();
|
|
|
58802
58999
|
init_manager2();
|
|
58803
59000
|
init_create_tool();
|
|
58804
59001
|
import * as fs30 from "fs";
|
|
58805
|
-
import * as
|
|
59002
|
+
import * as path43 from "path";
|
|
58806
59003
|
function detectPlaceholderContent(args2) {
|
|
58807
59004
|
const issues = [];
|
|
58808
59005
|
const placeholderPattern = /^\[\w[\w\s]*\]$/;
|
|
@@ -58906,7 +59103,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
58906
59103
|
try {
|
|
58907
59104
|
await savePlan(dir, plan);
|
|
58908
59105
|
try {
|
|
58909
|
-
const markerPath =
|
|
59106
|
+
const markerPath = path43.join(dir, ".swarm", ".plan-write-marker");
|
|
58910
59107
|
const marker = JSON.stringify({
|
|
58911
59108
|
source: "save_plan",
|
|
58912
59109
|
timestamp: new Date().toISOString(),
|
|
@@ -58918,7 +59115,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
58918
59115
|
return {
|
|
58919
59116
|
success: true,
|
|
58920
59117
|
message: "Plan saved successfully",
|
|
58921
|
-
plan_path:
|
|
59118
|
+
plan_path: path43.join(dir, ".swarm", "plan.json"),
|
|
58922
59119
|
phases_count: plan.phases.length,
|
|
58923
59120
|
tasks_count: tasksCount
|
|
58924
59121
|
};
|
|
@@ -58957,7 +59154,7 @@ var save_plan = createSwarmTool({
|
|
|
58957
59154
|
init_dist();
|
|
58958
59155
|
init_manager();
|
|
58959
59156
|
import * as fs31 from "fs";
|
|
58960
|
-
import * as
|
|
59157
|
+
import * as path44 from "path";
|
|
58961
59158
|
|
|
58962
59159
|
// src/sbom/detectors/index.ts
|
|
58963
59160
|
init_utils();
|
|
@@ -59805,7 +60002,7 @@ function findManifestFiles(rootDir) {
|
|
|
59805
60002
|
try {
|
|
59806
60003
|
const entries = fs31.readdirSync(dir, { withFileTypes: true });
|
|
59807
60004
|
for (const entry of entries) {
|
|
59808
|
-
const fullPath =
|
|
60005
|
+
const fullPath = path44.join(dir, entry.name);
|
|
59809
60006
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
|
|
59810
60007
|
continue;
|
|
59811
60008
|
}
|
|
@@ -59814,7 +60011,7 @@ function findManifestFiles(rootDir) {
|
|
|
59814
60011
|
} else if (entry.isFile()) {
|
|
59815
60012
|
for (const pattern of patterns) {
|
|
59816
60013
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
59817
|
-
manifestFiles.push(
|
|
60014
|
+
manifestFiles.push(path44.relative(rootDir, fullPath));
|
|
59818
60015
|
break;
|
|
59819
60016
|
}
|
|
59820
60017
|
}
|
|
@@ -59832,11 +60029,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
59832
60029
|
try {
|
|
59833
60030
|
const entries = fs31.readdirSync(dir, { withFileTypes: true });
|
|
59834
60031
|
for (const entry of entries) {
|
|
59835
|
-
const fullPath =
|
|
60032
|
+
const fullPath = path44.join(dir, entry.name);
|
|
59836
60033
|
if (entry.isFile()) {
|
|
59837
60034
|
for (const pattern of patterns) {
|
|
59838
60035
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
59839
|
-
found.push(
|
|
60036
|
+
found.push(path44.relative(workingDir, fullPath));
|
|
59840
60037
|
break;
|
|
59841
60038
|
}
|
|
59842
60039
|
}
|
|
@@ -59849,11 +60046,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
59849
60046
|
function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
59850
60047
|
const dirs = new Set;
|
|
59851
60048
|
for (const file3 of changedFiles) {
|
|
59852
|
-
let currentDir =
|
|
60049
|
+
let currentDir = path44.dirname(file3);
|
|
59853
60050
|
while (true) {
|
|
59854
|
-
if (currentDir && currentDir !== "." && currentDir !==
|
|
59855
|
-
dirs.add(
|
|
59856
|
-
const parent =
|
|
60051
|
+
if (currentDir && currentDir !== "." && currentDir !== path44.sep) {
|
|
60052
|
+
dirs.add(path44.join(workingDir, currentDir));
|
|
60053
|
+
const parent = path44.dirname(currentDir);
|
|
59857
60054
|
if (parent === currentDir)
|
|
59858
60055
|
break;
|
|
59859
60056
|
currentDir = parent;
|
|
@@ -59937,7 +60134,7 @@ var sbom_generate = createSwarmTool({
|
|
|
59937
60134
|
const changedFiles = obj.changed_files;
|
|
59938
60135
|
const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
|
|
59939
60136
|
const workingDir = directory;
|
|
59940
|
-
const outputDir =
|
|
60137
|
+
const outputDir = path44.isAbsolute(relativeOutputDir) ? relativeOutputDir : path44.join(workingDir, relativeOutputDir);
|
|
59941
60138
|
let manifestFiles = [];
|
|
59942
60139
|
if (scope === "all") {
|
|
59943
60140
|
manifestFiles = findManifestFiles(workingDir);
|
|
@@ -59960,7 +60157,7 @@ var sbom_generate = createSwarmTool({
|
|
|
59960
60157
|
const processedFiles = [];
|
|
59961
60158
|
for (const manifestFile of manifestFiles) {
|
|
59962
60159
|
try {
|
|
59963
|
-
const fullPath =
|
|
60160
|
+
const fullPath = path44.isAbsolute(manifestFile) ? manifestFile : path44.join(workingDir, manifestFile);
|
|
59964
60161
|
if (!fs31.existsSync(fullPath)) {
|
|
59965
60162
|
continue;
|
|
59966
60163
|
}
|
|
@@ -59977,7 +60174,7 @@ var sbom_generate = createSwarmTool({
|
|
|
59977
60174
|
const bom = generateCycloneDX(allComponents);
|
|
59978
60175
|
const bomJson = serializeCycloneDX(bom);
|
|
59979
60176
|
const filename = generateSbomFilename();
|
|
59980
|
-
const outputPath =
|
|
60177
|
+
const outputPath = path44.join(outputDir, filename);
|
|
59981
60178
|
fs31.writeFileSync(outputPath, bomJson, "utf-8");
|
|
59982
60179
|
const verdict = processedFiles.length > 0 ? "pass" : "pass";
|
|
59983
60180
|
try {
|
|
@@ -60021,7 +60218,7 @@ var sbom_generate = createSwarmTool({
|
|
|
60021
60218
|
init_dist();
|
|
60022
60219
|
init_create_tool();
|
|
60023
60220
|
import * as fs32 from "fs";
|
|
60024
|
-
import * as
|
|
60221
|
+
import * as path45 from "path";
|
|
60025
60222
|
var SPEC_CANDIDATES = [
|
|
60026
60223
|
"openapi.json",
|
|
60027
60224
|
"openapi.yaml",
|
|
@@ -60053,12 +60250,12 @@ function normalizePath2(p) {
|
|
|
60053
60250
|
}
|
|
60054
60251
|
function discoverSpecFile(cwd, specFileArg) {
|
|
60055
60252
|
if (specFileArg) {
|
|
60056
|
-
const resolvedPath =
|
|
60057
|
-
const normalizedCwd = cwd.endsWith(
|
|
60253
|
+
const resolvedPath = path45.resolve(cwd, specFileArg);
|
|
60254
|
+
const normalizedCwd = cwd.endsWith(path45.sep) ? cwd : cwd + path45.sep;
|
|
60058
60255
|
if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
|
|
60059
60256
|
throw new Error("Invalid spec_file: path traversal detected");
|
|
60060
60257
|
}
|
|
60061
|
-
const ext =
|
|
60258
|
+
const ext = path45.extname(resolvedPath).toLowerCase();
|
|
60062
60259
|
if (!ALLOWED_EXTENSIONS.includes(ext)) {
|
|
60063
60260
|
throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
|
|
60064
60261
|
}
|
|
@@ -60072,7 +60269,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
60072
60269
|
return resolvedPath;
|
|
60073
60270
|
}
|
|
60074
60271
|
for (const candidate of SPEC_CANDIDATES) {
|
|
60075
|
-
const candidatePath =
|
|
60272
|
+
const candidatePath = path45.resolve(cwd, candidate);
|
|
60076
60273
|
if (fs32.existsSync(candidatePath)) {
|
|
60077
60274
|
const stats = fs32.statSync(candidatePath);
|
|
60078
60275
|
if (stats.size <= MAX_SPEC_SIZE) {
|
|
@@ -60084,7 +60281,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
60084
60281
|
}
|
|
60085
60282
|
function parseSpec(specFile) {
|
|
60086
60283
|
const content = fs32.readFileSync(specFile, "utf-8");
|
|
60087
|
-
const ext =
|
|
60284
|
+
const ext = path45.extname(specFile).toLowerCase();
|
|
60088
60285
|
if (ext === ".json") {
|
|
60089
60286
|
return parseJsonSpec(content);
|
|
60090
60287
|
}
|
|
@@ -60160,7 +60357,7 @@ function extractRoutes(cwd) {
|
|
|
60160
60357
|
return;
|
|
60161
60358
|
}
|
|
60162
60359
|
for (const entry of entries) {
|
|
60163
|
-
const fullPath =
|
|
60360
|
+
const fullPath = path45.join(dir, entry.name);
|
|
60164
60361
|
if (entry.isSymbolicLink()) {
|
|
60165
60362
|
continue;
|
|
60166
60363
|
}
|
|
@@ -60170,7 +60367,7 @@ function extractRoutes(cwd) {
|
|
|
60170
60367
|
}
|
|
60171
60368
|
walkDir(fullPath);
|
|
60172
60369
|
} else if (entry.isFile()) {
|
|
60173
|
-
const ext =
|
|
60370
|
+
const ext = path45.extname(entry.name).toLowerCase();
|
|
60174
60371
|
const baseName = entry.name.toLowerCase();
|
|
60175
60372
|
if (![".ts", ".js", ".mjs"].includes(ext)) {
|
|
60176
60373
|
continue;
|
|
@@ -60340,7 +60537,7 @@ init_secretscan();
|
|
|
60340
60537
|
init_tool();
|
|
60341
60538
|
init_create_tool();
|
|
60342
60539
|
import * as fs33 from "fs";
|
|
60343
|
-
import * as
|
|
60540
|
+
import * as path46 from "path";
|
|
60344
60541
|
var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
|
|
60345
60542
|
var WINDOWS_RESERVED_NAMES = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
60346
60543
|
function containsControlCharacters(str) {
|
|
@@ -60369,11 +60566,11 @@ function containsWindowsAttacks(str) {
|
|
|
60369
60566
|
}
|
|
60370
60567
|
function isPathInWorkspace(filePath, workspace) {
|
|
60371
60568
|
try {
|
|
60372
|
-
const resolvedPath =
|
|
60569
|
+
const resolvedPath = path46.resolve(workspace, filePath);
|
|
60373
60570
|
const realWorkspace = fs33.realpathSync(workspace);
|
|
60374
60571
|
const realResolvedPath = fs33.realpathSync(resolvedPath);
|
|
60375
|
-
const relativePath =
|
|
60376
|
-
if (relativePath.startsWith("..") ||
|
|
60572
|
+
const relativePath = path46.relative(realWorkspace, realResolvedPath);
|
|
60573
|
+
if (relativePath.startsWith("..") || path46.isAbsolute(relativePath)) {
|
|
60377
60574
|
return false;
|
|
60378
60575
|
}
|
|
60379
60576
|
return true;
|
|
@@ -60385,7 +60582,7 @@ function validatePathForRead(filePath, workspace) {
|
|
|
60385
60582
|
return isPathInWorkspace(filePath, workspace);
|
|
60386
60583
|
}
|
|
60387
60584
|
function extractTSSymbols(filePath, cwd) {
|
|
60388
|
-
const fullPath =
|
|
60585
|
+
const fullPath = path46.join(cwd, filePath);
|
|
60389
60586
|
if (!validatePathForRead(fullPath, cwd)) {
|
|
60390
60587
|
return [];
|
|
60391
60588
|
}
|
|
@@ -60537,7 +60734,7 @@ function extractTSSymbols(filePath, cwd) {
|
|
|
60537
60734
|
});
|
|
60538
60735
|
}
|
|
60539
60736
|
function extractPythonSymbols(filePath, cwd) {
|
|
60540
|
-
const fullPath =
|
|
60737
|
+
const fullPath = path46.join(cwd, filePath);
|
|
60541
60738
|
if (!validatePathForRead(fullPath, cwd)) {
|
|
60542
60739
|
return [];
|
|
60543
60740
|
}
|
|
@@ -60620,7 +60817,7 @@ var symbols = createSwarmTool({
|
|
|
60620
60817
|
}, null, 2);
|
|
60621
60818
|
}
|
|
60622
60819
|
const cwd = directory;
|
|
60623
|
-
const ext =
|
|
60820
|
+
const ext = path46.extname(file3);
|
|
60624
60821
|
if (containsControlCharacters(file3)) {
|
|
60625
60822
|
return JSON.stringify({
|
|
60626
60823
|
file: file3,
|
|
@@ -60692,7 +60889,7 @@ init_dist();
|
|
|
60692
60889
|
init_utils();
|
|
60693
60890
|
init_create_tool();
|
|
60694
60891
|
import * as fs34 from "fs";
|
|
60695
|
-
import * as
|
|
60892
|
+
import * as path47 from "path";
|
|
60696
60893
|
var MAX_TEXT_LENGTH = 200;
|
|
60697
60894
|
var MAX_FILE_SIZE_BYTES8 = 1024 * 1024;
|
|
60698
60895
|
var SUPPORTED_EXTENSIONS2 = new Set([
|
|
@@ -60763,9 +60960,9 @@ function validatePathsInput(paths, cwd) {
|
|
|
60763
60960
|
return { error: "paths contains path traversal", resolvedPath: null };
|
|
60764
60961
|
}
|
|
60765
60962
|
try {
|
|
60766
|
-
const resolvedPath =
|
|
60767
|
-
const normalizedCwd =
|
|
60768
|
-
const normalizedResolved =
|
|
60963
|
+
const resolvedPath = path47.resolve(paths);
|
|
60964
|
+
const normalizedCwd = path47.resolve(cwd);
|
|
60965
|
+
const normalizedResolved = path47.resolve(resolvedPath);
|
|
60769
60966
|
if (!normalizedResolved.startsWith(normalizedCwd)) {
|
|
60770
60967
|
return {
|
|
60771
60968
|
error: "paths must be within the current working directory",
|
|
@@ -60781,7 +60978,7 @@ function validatePathsInput(paths, cwd) {
|
|
|
60781
60978
|
}
|
|
60782
60979
|
}
|
|
60783
60980
|
function isSupportedExtension(filePath) {
|
|
60784
|
-
const ext =
|
|
60981
|
+
const ext = path47.extname(filePath).toLowerCase();
|
|
60785
60982
|
return SUPPORTED_EXTENSIONS2.has(ext);
|
|
60786
60983
|
}
|
|
60787
60984
|
function findSourceFiles3(dir, files = []) {
|
|
@@ -60796,7 +60993,7 @@ function findSourceFiles3(dir, files = []) {
|
|
|
60796
60993
|
if (SKIP_DIRECTORIES3.has(entry)) {
|
|
60797
60994
|
continue;
|
|
60798
60995
|
}
|
|
60799
|
-
const fullPath =
|
|
60996
|
+
const fullPath = path47.join(dir, entry);
|
|
60800
60997
|
let stat2;
|
|
60801
60998
|
try {
|
|
60802
60999
|
stat2 = fs34.statSync(fullPath);
|
|
@@ -60908,7 +61105,7 @@ var todo_extract = createSwarmTool({
|
|
|
60908
61105
|
filesToScan.push(scanPath);
|
|
60909
61106
|
} else {
|
|
60910
61107
|
const errorResult = {
|
|
60911
|
-
error: `unsupported file extension: ${
|
|
61108
|
+
error: `unsupported file extension: ${path47.extname(scanPath)}`,
|
|
60912
61109
|
total: 0,
|
|
60913
61110
|
byPriority: { high: 0, medium: 0, low: 0 },
|
|
60914
61111
|
entries: []
|
|
@@ -60955,7 +61152,7 @@ init_tool();
|
|
|
60955
61152
|
init_schema();
|
|
60956
61153
|
init_manager2();
|
|
60957
61154
|
import * as fs35 from "fs";
|
|
60958
|
-
import * as
|
|
61155
|
+
import * as path48 from "path";
|
|
60959
61156
|
init_create_tool();
|
|
60960
61157
|
var VALID_STATUSES2 = [
|
|
60961
61158
|
"pending",
|
|
@@ -60978,6 +61175,23 @@ function validateTaskId(taskId) {
|
|
|
60978
61175
|
}
|
|
60979
61176
|
function checkReviewerGate(taskId, workingDirectory) {
|
|
60980
61177
|
try {
|
|
61178
|
+
const resolvedDir = workingDirectory ?? process.cwd();
|
|
61179
|
+
try {
|
|
61180
|
+
const evidencePath = path48.join(resolvedDir, ".swarm", "evidence", `${taskId}.json`);
|
|
61181
|
+
const raw = fs35.readFileSync(evidencePath, "utf-8");
|
|
61182
|
+
const evidence = JSON.parse(raw);
|
|
61183
|
+
if (evidence?.required_gates && Array.isArray(evidence.required_gates) && evidence?.gates) {
|
|
61184
|
+
const allGatesMet = evidence.required_gates.every((gate) => evidence.gates[gate] != null);
|
|
61185
|
+
if (allGatesMet) {
|
|
61186
|
+
return { blocked: false, reason: "" };
|
|
61187
|
+
}
|
|
61188
|
+
const missingGates = evidence.required_gates.filter((gate) => evidence.gates[gate] == null);
|
|
61189
|
+
return {
|
|
61190
|
+
blocked: true,
|
|
61191
|
+
reason: `Task ${taskId} is missing required gates: [${missingGates.join(", ")}]. ` + `Required: [${evidence.required_gates.join(", ")}]. ` + `Completed: [${Object.keys(evidence.gates).join(", ")}]. ` + `Delegate the missing gate agents before marking task as completed.`
|
|
61192
|
+
};
|
|
61193
|
+
}
|
|
61194
|
+
} catch {}
|
|
60981
61195
|
if (swarmState.agentSessions.size === 0) {
|
|
60982
61196
|
return { blocked: false, reason: "" };
|
|
60983
61197
|
}
|
|
@@ -61003,8 +61217,8 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
61003
61217
|
stateEntries.push(`${sessionId}: ${state}`);
|
|
61004
61218
|
}
|
|
61005
61219
|
try {
|
|
61006
|
-
const
|
|
61007
|
-
const planPath =
|
|
61220
|
+
const resolvedDir2 = workingDirectory ?? process.cwd();
|
|
61221
|
+
const planPath = path48.join(resolvedDir2, ".swarm", "plan.json");
|
|
61008
61222
|
const planRaw = fs35.readFileSync(planPath, "utf-8");
|
|
61009
61223
|
const plan = JSON.parse(planRaw);
|
|
61010
61224
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -61027,13 +61241,16 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
61027
61241
|
function recoverTaskStateFromDelegations(taskId) {
|
|
61028
61242
|
let hasReviewer = false;
|
|
61029
61243
|
let hasTestEngineer = false;
|
|
61030
|
-
for (const [, chain] of swarmState.delegationChains) {
|
|
61031
|
-
|
|
61032
|
-
|
|
61033
|
-
|
|
61034
|
-
|
|
61035
|
-
|
|
61036
|
-
|
|
61244
|
+
for (const [sessionId, chain] of swarmState.delegationChains) {
|
|
61245
|
+
const session = swarmState.agentSessions.get(sessionId);
|
|
61246
|
+
if (session && (session.currentTaskId === taskId || session.lastCoderDelegationTaskId === taskId)) {
|
|
61247
|
+
for (const delegation of chain) {
|
|
61248
|
+
const target = stripKnownSwarmPrefix(delegation.to);
|
|
61249
|
+
if (target === "reviewer")
|
|
61250
|
+
hasReviewer = true;
|
|
61251
|
+
if (target === "test_engineer")
|
|
61252
|
+
hasTestEngineer = true;
|
|
61253
|
+
}
|
|
61037
61254
|
}
|
|
61038
61255
|
}
|
|
61039
61256
|
if (!hasReviewer && !hasTestEngineer)
|
|
@@ -61112,8 +61329,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
61112
61329
|
};
|
|
61113
61330
|
}
|
|
61114
61331
|
}
|
|
61115
|
-
normalizedDir =
|
|
61116
|
-
const pathParts = normalizedDir.split(
|
|
61332
|
+
normalizedDir = path48.normalize(args2.working_directory);
|
|
61333
|
+
const pathParts = normalizedDir.split(path48.sep);
|
|
61117
61334
|
if (pathParts.includes("..")) {
|
|
61118
61335
|
return {
|
|
61119
61336
|
success: false,
|
|
@@ -61123,10 +61340,10 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
61123
61340
|
]
|
|
61124
61341
|
};
|
|
61125
61342
|
}
|
|
61126
|
-
const resolvedDir =
|
|
61343
|
+
const resolvedDir = path48.resolve(normalizedDir);
|
|
61127
61344
|
try {
|
|
61128
61345
|
const realPath = fs35.realpathSync(resolvedDir);
|
|
61129
|
-
const planPath =
|
|
61346
|
+
const planPath = path48.join(realPath, ".swarm", "plan.json");
|
|
61130
61347
|
if (!fs35.existsSync(planPath)) {
|
|
61131
61348
|
return {
|
|
61132
61349
|
success: false,
|
|
@@ -61284,7 +61501,7 @@ var OpenCodeSwarm = async (ctx) => {
|
|
|
61284
61501
|
const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
|
|
61285
61502
|
preflightTriggerManager = new PTM(automationConfig);
|
|
61286
61503
|
const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
|
|
61287
|
-
const swarmDir =
|
|
61504
|
+
const swarmDir = path49.resolve(ctx.directory, ".swarm");
|
|
61288
61505
|
statusArtifact = new ASA(swarmDir);
|
|
61289
61506
|
statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
|
|
61290
61507
|
if (automationConfig.capabilities?.evidence_auto_summaries === true) {
|