opencode-swarm 6.32.4 → 6.33.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/README.md +24 -0
- package/dist/agents/architect.dark-matter.test.d.ts +1 -0
- package/dist/cli/index.js +116 -24
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/registry.d.ts +4 -0
- package/dist/commands/reset-session.d.ts +7 -0
- package/dist/config/schema.d.ts +7 -0
- package/dist/hooks/delegation-gate.d.ts +7 -0
- package/dist/hooks/delegation-gate.verify.test.d.ts +11 -0
- package/dist/hooks/scope-guard.d.ts +2 -2
- package/dist/hooks/trajectory-logger.d.ts +57 -0
- package/dist/index.js +321 -191
- package/dist/session/snapshot-writer.d.ts +6 -0
- package/dist/tools/check-gate-status.prefix.test.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14798,6 +14798,7 @@ var init_schema = __esm(() => {
|
|
|
14798
14798
|
max_consecutive_errors: exports_external.number().min(2).max(20).default(5),
|
|
14799
14799
|
warning_threshold: exports_external.number().min(0.1).max(0.9).default(0.75),
|
|
14800
14800
|
idle_timeout_minutes: exports_external.number().min(5).max(240).default(60),
|
|
14801
|
+
no_op_warning_threshold: exports_external.number().min(1).max(100).default(15),
|
|
14801
14802
|
qa_gates: exports_external.object({
|
|
14802
14803
|
required_tools: exports_external.array(exports_external.string().min(1)).default([
|
|
14803
14804
|
"diff",
|
|
@@ -14913,6 +14914,7 @@ var init_schema = __esm(() => {
|
|
|
14913
14914
|
pipeline: PipelineConfigSchema.optional(),
|
|
14914
14915
|
phase_complete: PhaseCompleteConfigSchema.optional(),
|
|
14915
14916
|
qa_retry_limit: exports_external.number().min(1).max(10).default(3),
|
|
14917
|
+
execution_mode: exports_external.enum(["strict", "balanced", "fast"]).default("balanced"),
|
|
14916
14918
|
inject_phase_reminders: exports_external.boolean().default(true),
|
|
14917
14919
|
hooks: HooksConfigSchema.optional(),
|
|
14918
14920
|
gates: GateConfigSchema.optional(),
|
|
@@ -36248,7 +36250,7 @@ __export(exports_gate_evidence, {
|
|
|
36248
36250
|
deriveRequiredGates: () => deriveRequiredGates,
|
|
36249
36251
|
DEFAULT_REQUIRED_GATES: () => DEFAULT_REQUIRED_GATES
|
|
36250
36252
|
});
|
|
36251
|
-
import { mkdirSync as mkdirSync9, readFileSync as readFileSync14, renameSync as renameSync8, unlinkSync as
|
|
36253
|
+
import { mkdirSync as mkdirSync9, readFileSync as readFileSync14, renameSync as renameSync8, unlinkSync as unlinkSync5 } from "fs";
|
|
36252
36254
|
import * as path30 from "path";
|
|
36253
36255
|
function isValidTaskId2(taskId) {
|
|
36254
36256
|
if (!taskId)
|
|
@@ -36316,7 +36318,7 @@ async function atomicWrite(targetPath, content) {
|
|
|
36316
36318
|
renameSync8(tempPath, targetPath);
|
|
36317
36319
|
} finally {
|
|
36318
36320
|
try {
|
|
36319
|
-
|
|
36321
|
+
unlinkSync5(tempPath);
|
|
36320
36322
|
} catch {}
|
|
36321
36323
|
}
|
|
36322
36324
|
}
|
|
@@ -46774,6 +46776,8 @@ function formatHandoffMarkdown(data) {
|
|
|
46774
46776
|
init_utils2();
|
|
46775
46777
|
import { mkdirSync as mkdirSync7, renameSync as renameSync4 } from "fs";
|
|
46776
46778
|
import * as path19 from "path";
|
|
46779
|
+
var pendingWrite = null;
|
|
46780
|
+
var lastWritePromise = Promise.resolve();
|
|
46777
46781
|
function serializeAgentSession(s) {
|
|
46778
46782
|
const gateLog = {};
|
|
46779
46783
|
const rawGateLog = s.gateLog ?? new Map;
|
|
@@ -46858,14 +46862,28 @@ async function writeSnapshot(directory, state) {
|
|
|
46858
46862
|
const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
46859
46863
|
await Bun.write(tempPath, content);
|
|
46860
46864
|
renameSync4(tempPath, resolvedPath);
|
|
46861
|
-
} catch {
|
|
46865
|
+
} catch (error93) {
|
|
46866
|
+
console.warn("[snapshot-writer] write failed:", error93 instanceof Error ? error93.message : String(error93));
|
|
46867
|
+
}
|
|
46862
46868
|
}
|
|
46863
46869
|
function createSnapshotWriterHook(directory) {
|
|
46864
46870
|
return async (_input, _output) => {
|
|
46865
|
-
|
|
46866
|
-
|
|
46867
|
-
|
|
46868
|
-
|
|
46871
|
+
if (pendingWrite)
|
|
46872
|
+
clearTimeout(pendingWrite);
|
|
46873
|
+
pendingWrite = setTimeout(() => {
|
|
46874
|
+
pendingWrite = null;
|
|
46875
|
+
lastWritePromise = writeSnapshot(directory, swarmState).catch(() => {});
|
|
46876
|
+
}, 2000);
|
|
46877
|
+
};
|
|
46878
|
+
}
|
|
46879
|
+
async function flushPendingSnapshot(directory) {
|
|
46880
|
+
if (pendingWrite) {
|
|
46881
|
+
clearTimeout(pendingWrite);
|
|
46882
|
+
pendingWrite = null;
|
|
46883
|
+
await writeSnapshot(directory, swarmState).catch(() => {});
|
|
46884
|
+
} else {
|
|
46885
|
+
await lastWritePromise;
|
|
46886
|
+
}
|
|
46869
46887
|
}
|
|
46870
46888
|
|
|
46871
46889
|
// src/commands/handoff.ts
|
|
@@ -46877,6 +46895,7 @@ async function handleHandoffCommand(directory, _args) {
|
|
|
46877
46895
|
await Bun.write(tempPath, markdown);
|
|
46878
46896
|
renameSync5(tempPath, resolvedPath);
|
|
46879
46897
|
await writeSnapshot(directory, swarmState);
|
|
46898
|
+
await flushPendingSnapshot(directory);
|
|
46880
46899
|
return `## Handoff Brief Written
|
|
46881
46900
|
|
|
46882
46901
|
Brief written to \`.swarm/handoff.md\`.
|
|
@@ -47586,6 +47605,37 @@ async function handleResetCommand(directory, args2) {
|
|
|
47586
47605
|
`);
|
|
47587
47606
|
}
|
|
47588
47607
|
|
|
47608
|
+
// src/commands/reset-session.ts
|
|
47609
|
+
init_utils2();
|
|
47610
|
+
import * as fs15 from "fs";
|
|
47611
|
+
async function handleResetSessionCommand(directory, _args) {
|
|
47612
|
+
const results = [];
|
|
47613
|
+
try {
|
|
47614
|
+
const statePath = validateSwarmPath(directory, "session/state.json");
|
|
47615
|
+
if (fs15.existsSync(statePath)) {
|
|
47616
|
+
fs15.unlinkSync(statePath);
|
|
47617
|
+
results.push("\u2705 Deleted .swarm/session/state.json");
|
|
47618
|
+
} else {
|
|
47619
|
+
results.push("\u23ED\uFE0F state.json not found (already clean)");
|
|
47620
|
+
}
|
|
47621
|
+
} catch {
|
|
47622
|
+
results.push("\u274C Failed to delete state.json");
|
|
47623
|
+
}
|
|
47624
|
+
const sessionCount = swarmState.agentSessions.size;
|
|
47625
|
+
swarmState.agentSessions.clear();
|
|
47626
|
+
results.push(`\u2705 Cleared ${sessionCount} in-memory agent session(s)`);
|
|
47627
|
+
return [
|
|
47628
|
+
"## Session State Reset",
|
|
47629
|
+
"",
|
|
47630
|
+
...results,
|
|
47631
|
+
"",
|
|
47632
|
+
"Session state cleared. Plan, evidence, and knowledge preserved.",
|
|
47633
|
+
"",
|
|
47634
|
+
"**Next step:** Start a new OpenCode session. The plugin will initialize fresh session state on startup."
|
|
47635
|
+
].join(`
|
|
47636
|
+
`);
|
|
47637
|
+
}
|
|
47638
|
+
|
|
47589
47639
|
// src/summaries/manager.ts
|
|
47590
47640
|
init_utils2();
|
|
47591
47641
|
init_utils();
|
|
@@ -47696,18 +47746,18 @@ ${error93 instanceof Error ? error93.message : String(error93)}`;
|
|
|
47696
47746
|
|
|
47697
47747
|
// src/commands/rollback.ts
|
|
47698
47748
|
init_utils2();
|
|
47699
|
-
import * as
|
|
47749
|
+
import * as fs16 from "fs";
|
|
47700
47750
|
import * as path27 from "path";
|
|
47701
47751
|
async function handleRollbackCommand(directory, args2) {
|
|
47702
47752
|
const phaseArg = args2[0];
|
|
47703
47753
|
if (!phaseArg) {
|
|
47704
47754
|
const manifestPath2 = validateSwarmPath(directory, "checkpoints/manifest.json");
|
|
47705
|
-
if (!
|
|
47755
|
+
if (!fs16.existsSync(manifestPath2)) {
|
|
47706
47756
|
return "No checkpoints found. Use `/swarm checkpoint` to create checkpoints.";
|
|
47707
47757
|
}
|
|
47708
47758
|
let manifest2;
|
|
47709
47759
|
try {
|
|
47710
|
-
manifest2 = JSON.parse(
|
|
47760
|
+
manifest2 = JSON.parse(fs16.readFileSync(manifestPath2, "utf-8"));
|
|
47711
47761
|
} catch {
|
|
47712
47762
|
return "Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.";
|
|
47713
47763
|
}
|
|
@@ -47729,12 +47779,12 @@ async function handleRollbackCommand(directory, args2) {
|
|
|
47729
47779
|
return "Error: Phase number must be a positive integer.";
|
|
47730
47780
|
}
|
|
47731
47781
|
const manifestPath = validateSwarmPath(directory, "checkpoints/manifest.json");
|
|
47732
|
-
if (!
|
|
47782
|
+
if (!fs16.existsSync(manifestPath)) {
|
|
47733
47783
|
return `Error: No checkpoints found. Cannot rollback to phase ${targetPhase}.`;
|
|
47734
47784
|
}
|
|
47735
47785
|
let manifest;
|
|
47736
47786
|
try {
|
|
47737
|
-
manifest = JSON.parse(
|
|
47787
|
+
manifest = JSON.parse(fs16.readFileSync(manifestPath, "utf-8"));
|
|
47738
47788
|
} catch {
|
|
47739
47789
|
return `Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.`;
|
|
47740
47790
|
}
|
|
@@ -47744,10 +47794,10 @@ async function handleRollbackCommand(directory, args2) {
|
|
|
47744
47794
|
return `Error: Checkpoint for phase ${targetPhase} not found. Available phases: ${available}`;
|
|
47745
47795
|
}
|
|
47746
47796
|
const checkpointDir = validateSwarmPath(directory, `checkpoints/phase-${targetPhase}`);
|
|
47747
|
-
if (!
|
|
47797
|
+
if (!fs16.existsSync(checkpointDir)) {
|
|
47748
47798
|
return `Error: Checkpoint directory for phase ${targetPhase} does not exist.`;
|
|
47749
47799
|
}
|
|
47750
|
-
const checkpointFiles =
|
|
47800
|
+
const checkpointFiles = fs16.readdirSync(checkpointDir);
|
|
47751
47801
|
if (checkpointFiles.length === 0) {
|
|
47752
47802
|
return `Error: Checkpoint for phase ${targetPhase} is empty. Cannot rollback.`;
|
|
47753
47803
|
}
|
|
@@ -47758,7 +47808,7 @@ async function handleRollbackCommand(directory, args2) {
|
|
|
47758
47808
|
const src = path27.join(checkpointDir, file3);
|
|
47759
47809
|
const dest = path27.join(swarmDir, file3);
|
|
47760
47810
|
try {
|
|
47761
|
-
|
|
47811
|
+
fs16.cpSync(src, dest, { recursive: true, force: true });
|
|
47762
47812
|
successes.push(file3);
|
|
47763
47813
|
} catch (error93) {
|
|
47764
47814
|
failures.push({ file: file3, error: error93.message });
|
|
@@ -47775,7 +47825,7 @@ async function handleRollbackCommand(directory, args2) {
|
|
|
47775
47825
|
timestamp: new Date().toISOString()
|
|
47776
47826
|
};
|
|
47777
47827
|
try {
|
|
47778
|
-
|
|
47828
|
+
fs16.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
|
|
47779
47829
|
`);
|
|
47780
47830
|
} catch (error93) {
|
|
47781
47831
|
console.error("Failed to write rollback event:", error93);
|
|
@@ -47818,11 +47868,11 @@ async function handleSimulateCommand(directory, args2) {
|
|
|
47818
47868
|
];
|
|
47819
47869
|
const report = reportLines.filter(Boolean).join(`
|
|
47820
47870
|
`);
|
|
47821
|
-
const
|
|
47871
|
+
const fs17 = await import("fs/promises");
|
|
47822
47872
|
const path28 = await import("path");
|
|
47823
47873
|
const reportPath = path28.join(directory, ".swarm", "simulate-report.md");
|
|
47824
|
-
await
|
|
47825
|
-
await
|
|
47874
|
+
await fs17.mkdir(path28.dirname(reportPath), { recursive: true });
|
|
47875
|
+
await fs17.writeFile(reportPath, report, "utf-8");
|
|
47826
47876
|
return `${darkMatterPairs.length} hidden coupling pairs detected`;
|
|
47827
47877
|
}
|
|
47828
47878
|
|
|
@@ -48179,7 +48229,7 @@ init_utils2();
|
|
|
48179
48229
|
init_manager2();
|
|
48180
48230
|
|
|
48181
48231
|
// src/services/compaction-service.ts
|
|
48182
|
-
import * as
|
|
48232
|
+
import * as fs17 from "fs";
|
|
48183
48233
|
import * as path28 from "path";
|
|
48184
48234
|
function makeInitialState() {
|
|
48185
48235
|
return {
|
|
@@ -48201,7 +48251,7 @@ function appendSnapshot(directory, tier, budgetPct, message) {
|
|
|
48201
48251
|
## [${tier.toUpperCase()}] ${timestamp} \u2014 ${budgetPct.toFixed(1)}% used
|
|
48202
48252
|
${message}
|
|
48203
48253
|
`;
|
|
48204
|
-
|
|
48254
|
+
fs17.appendFileSync(snapshotPath, entry, "utf-8");
|
|
48205
48255
|
} catch {}
|
|
48206
48256
|
}
|
|
48207
48257
|
function buildObservationMessage(budgetPct) {
|
|
@@ -48749,6 +48799,47 @@ async function executeWriteRetro(args2, directory) {
|
|
|
48749
48799
|
message: "Invalid summary: must be a non-empty string"
|
|
48750
48800
|
}, null, 2);
|
|
48751
48801
|
}
|
|
48802
|
+
if (args2.task_id !== undefined) {
|
|
48803
|
+
const tid = args2.task_id;
|
|
48804
|
+
if (!tid || tid.length === 0 || tid.length > 200) {
|
|
48805
|
+
return JSON.stringify({
|
|
48806
|
+
success: false,
|
|
48807
|
+
phase,
|
|
48808
|
+
message: "Invalid task ID: must match pattern"
|
|
48809
|
+
}, null, 2);
|
|
48810
|
+
}
|
|
48811
|
+
if (/\0/.test(tid)) {
|
|
48812
|
+
return JSON.stringify({
|
|
48813
|
+
success: false,
|
|
48814
|
+
phase,
|
|
48815
|
+
message: "Invalid task ID: contains null bytes"
|
|
48816
|
+
}, null, 2);
|
|
48817
|
+
}
|
|
48818
|
+
for (let i2 = 0;i2 < tid.length; i2++) {
|
|
48819
|
+
if (tid.charCodeAt(i2) < 32) {
|
|
48820
|
+
return JSON.stringify({
|
|
48821
|
+
success: false,
|
|
48822
|
+
phase,
|
|
48823
|
+
message: "Invalid task ID: contains control characters"
|
|
48824
|
+
}, null, 2);
|
|
48825
|
+
}
|
|
48826
|
+
}
|
|
48827
|
+
if (tid.includes("..") || tid.includes("/") || tid.includes("\\")) {
|
|
48828
|
+
return JSON.stringify({
|
|
48829
|
+
success: false,
|
|
48830
|
+
phase,
|
|
48831
|
+
message: "Invalid task ID: path traversal detected"
|
|
48832
|
+
}, null, 2);
|
|
48833
|
+
}
|
|
48834
|
+
const VALID_TASK_ID = /^(retro-\d+|\d+\.\d+(\.\d+)*)$/;
|
|
48835
|
+
if (!VALID_TASK_ID.test(tid)) {
|
|
48836
|
+
return JSON.stringify({
|
|
48837
|
+
success: false,
|
|
48838
|
+
phase,
|
|
48839
|
+
message: "Invalid task ID: must match pattern"
|
|
48840
|
+
}, null, 2);
|
|
48841
|
+
}
|
|
48842
|
+
}
|
|
48752
48843
|
const taskId = args2.task_id ?? `retro-${phase}`;
|
|
48753
48844
|
const retroEntry = {
|
|
48754
48845
|
task_id: taskId,
|
|
@@ -48988,6 +49079,10 @@ var COMMAND_REGISTRY = {
|
|
|
48988
49079
|
handler: (ctx) => handleResetCommand(ctx.directory, ctx.args),
|
|
48989
49080
|
description: "Clear swarm state files [--confirm]"
|
|
48990
49081
|
},
|
|
49082
|
+
"reset-session": {
|
|
49083
|
+
handler: (ctx) => handleResetSessionCommand(ctx.directory, ctx.args),
|
|
49084
|
+
description: "Clear session state while preserving plan, evidence, and knowledge"
|
|
49085
|
+
},
|
|
48991
49086
|
rollback: {
|
|
48992
49087
|
handler: (ctx) => handleRollbackCommand(ctx.directory, ctx.args),
|
|
48993
49088
|
description: "Restore swarm state to a checkpoint <phase>"
|
|
@@ -49092,7 +49187,7 @@ init_constants();
|
|
|
49092
49187
|
init_schema();
|
|
49093
49188
|
|
|
49094
49189
|
// src/hooks/agent-activity.ts
|
|
49095
|
-
import { renameSync as renameSync7, unlinkSync as
|
|
49190
|
+
import { renameSync as renameSync7, unlinkSync as unlinkSync4 } from "fs";
|
|
49096
49191
|
init_utils();
|
|
49097
49192
|
init_utils2();
|
|
49098
49193
|
function createAgentActivityHooks(config3, directory) {
|
|
@@ -49169,7 +49264,7 @@ async function doFlush(directory) {
|
|
|
49169
49264
|
renameSync7(tempPath, path29);
|
|
49170
49265
|
} catch (writeError) {
|
|
49171
49266
|
try {
|
|
49172
|
-
|
|
49267
|
+
unlinkSync4(tempPath);
|
|
49173
49268
|
} catch {}
|
|
49174
49269
|
throw writeError;
|
|
49175
49270
|
}
|
|
@@ -49215,7 +49310,7 @@ ${content.substring(endIndex + 1)}`;
|
|
|
49215
49310
|
}
|
|
49216
49311
|
// src/hooks/compaction-customizer.ts
|
|
49217
49312
|
init_manager2();
|
|
49218
|
-
import * as
|
|
49313
|
+
import * as fs18 from "fs";
|
|
49219
49314
|
import { join as join25 } from "path";
|
|
49220
49315
|
init_utils2();
|
|
49221
49316
|
function createCompactionCustomizerHook(config3, directory) {
|
|
@@ -49263,7 +49358,7 @@ function createCompactionCustomizerHook(config3, directory) {
|
|
|
49263
49358
|
}
|
|
49264
49359
|
try {
|
|
49265
49360
|
const summariesDir = join25(directory, ".swarm", "summaries");
|
|
49266
|
-
const files = await
|
|
49361
|
+
const files = await fs18.promises.readdir(summariesDir);
|
|
49267
49362
|
if (files.length > 0) {
|
|
49268
49363
|
const count = files.length;
|
|
49269
49364
|
output.context.push(`[CONTEXT OPTIMIZATION] Tool outputs from earlier in this session have been stored to disk. When compacting, replace any large tool output blocks (bash, test_runner, lint, diff results) with a one-line reference: "[Output stored \u2014 use /swarm retrieve to access full content]". Preserve the tool name, exit status, and any error messages. Discard raw output lines.`);
|
|
@@ -49748,7 +49843,7 @@ function maskToolOutput(msg, _threshold) {
|
|
|
49748
49843
|
}
|
|
49749
49844
|
// src/hooks/delegation-gate.ts
|
|
49750
49845
|
init_schema();
|
|
49751
|
-
import * as
|
|
49846
|
+
import * as fs19 from "fs";
|
|
49752
49847
|
import * as path31 from "path";
|
|
49753
49848
|
|
|
49754
49849
|
// src/hooks/guardrails.ts
|
|
@@ -49809,6 +49904,8 @@ function setStoredInputArgs(callID, args2) {
|
|
|
49809
49904
|
function deleteStoredInputArgs(callID) {
|
|
49810
49905
|
storedInputArgs.delete(callID);
|
|
49811
49906
|
}
|
|
49907
|
+
var toolCallsSinceLastWrite = new Map;
|
|
49908
|
+
var noOpWarningIssued = new Set;
|
|
49812
49909
|
function extractPhaseNumber(phaseString) {
|
|
49813
49910
|
if (!phaseString)
|
|
49814
49911
|
return 1;
|
|
@@ -50326,6 +50423,19 @@ function createGuardrailsHooks(directory, directoryOrConfig, config3) {
|
|
|
50326
50423
|
session.modifiedFilesThisCoderTask = [];
|
|
50327
50424
|
}
|
|
50328
50425
|
}
|
|
50426
|
+
const sessionId = input.sessionID;
|
|
50427
|
+
const normalizedToolName = input.tool.replace(/^[^:]+[:.]/, "");
|
|
50428
|
+
if (isWriteTool(normalizedToolName)) {
|
|
50429
|
+
toolCallsSinceLastWrite.set(sessionId, 0);
|
|
50430
|
+
} else {
|
|
50431
|
+
const count = (toolCallsSinceLastWrite.get(sessionId) ?? 0) + 1;
|
|
50432
|
+
toolCallsSinceLastWrite.set(sessionId, count);
|
|
50433
|
+
const threshold = cfg.no_op_warning_threshold ?? 15;
|
|
50434
|
+
if (count >= threshold && !noOpWarningIssued.has(sessionId) && session?.pendingAdvisoryMessages) {
|
|
50435
|
+
noOpWarningIssued.add(sessionId);
|
|
50436
|
+
session.pendingAdvisoryMessages.push(`WARNING: Agent has made ${count} tool calls with no file modifications. If you are stuck, use /swarm handoff to reset or /swarm turbo to reduce overhead.`);
|
|
50437
|
+
}
|
|
50438
|
+
}
|
|
50329
50439
|
const window2 = getActiveWindow(input.sessionID);
|
|
50330
50440
|
if (!window2)
|
|
50331
50441
|
return;
|
|
@@ -50611,6 +50721,7 @@ function hashArgs(args2) {
|
|
|
50611
50721
|
|
|
50612
50722
|
// src/hooks/delegation-gate.ts
|
|
50613
50723
|
init_utils2();
|
|
50724
|
+
var pendingCoderScopeByTaskId = new Map;
|
|
50614
50725
|
function extractTaskLine(text) {
|
|
50615
50726
|
const match = text.match(/TASK:\s*(.+?)(?:\n|$)/i);
|
|
50616
50727
|
return match ? match[1].trim() : null;
|
|
@@ -50646,7 +50757,7 @@ function getEvidenceTaskId(session, directory) {
|
|
|
50646
50757
|
if (!resolvedPlanPath.startsWith(resolvedDirectory + path31.sep) && resolvedPlanPath !== resolvedDirectory) {
|
|
50647
50758
|
return null;
|
|
50648
50759
|
}
|
|
50649
|
-
const planContent =
|
|
50760
|
+
const planContent = fs19.readFileSync(resolvedPlanPath, "utf-8");
|
|
50650
50761
|
const plan = JSON.parse(planContent);
|
|
50651
50762
|
if (!plan || !Array.isArray(plan.phases)) {
|
|
50652
50763
|
return null;
|
|
@@ -50996,6 +51107,11 @@ ${trimComment}${after}`;
|
|
|
50996
51107
|
}
|
|
50997
51108
|
}
|
|
50998
51109
|
session.declaredCoderScope = declaredFiles.length > 0 ? declaredFiles : null;
|
|
51110
|
+
if (declaredFiles.length > 0 && currentTaskId) {
|
|
51111
|
+
pendingCoderScopeByTaskId.set(currentTaskId, declaredFiles);
|
|
51112
|
+
} else {
|
|
51113
|
+
pendingCoderScopeByTaskId.delete(currentTaskId);
|
|
51114
|
+
}
|
|
50999
51115
|
try {
|
|
51000
51116
|
advanceTaskState(session, currentTaskId, "coder_delegated");
|
|
51001
51117
|
} catch (err2) {
|
|
@@ -51123,7 +51239,7 @@ ${warningLines.join(`
|
|
|
51123
51239
|
}
|
|
51124
51240
|
// src/hooks/delegation-sanitizer.ts
|
|
51125
51241
|
init_utils2();
|
|
51126
|
-
import * as
|
|
51242
|
+
import * as fs20 from "fs";
|
|
51127
51243
|
var SANITIZATION_PATTERNS = [
|
|
51128
51244
|
/\b\d+(st|nd|rd|th)\s+(attempt|try|time)\b/gi,
|
|
51129
51245
|
/\b(5th|fifth|final|last)\s+attempt\b/gi,
|
|
@@ -51194,7 +51310,7 @@ function createDelegationSanitizerHook(directory) {
|
|
|
51194
51310
|
stripped_patterns: result.stripped,
|
|
51195
51311
|
timestamp: new Date().toISOString()
|
|
51196
51312
|
};
|
|
51197
|
-
|
|
51313
|
+
fs20.appendFileSync(eventsPath, `${JSON.stringify(event)}
|
|
51198
51314
|
`, "utf-8");
|
|
51199
51315
|
} catch {}
|
|
51200
51316
|
}
|
|
@@ -51451,12 +51567,12 @@ init_schema();
|
|
|
51451
51567
|
init_manager();
|
|
51452
51568
|
init_detector();
|
|
51453
51569
|
init_manager2();
|
|
51454
|
-
import * as
|
|
51570
|
+
import * as fs22 from "fs";
|
|
51455
51571
|
|
|
51456
51572
|
// src/services/decision-drift-analyzer.ts
|
|
51457
51573
|
init_utils2();
|
|
51458
51574
|
init_manager2();
|
|
51459
|
-
import * as
|
|
51575
|
+
import * as fs21 from "fs";
|
|
51460
51576
|
import * as path33 from "path";
|
|
51461
51577
|
var DEFAULT_DRIFT_CONFIG = {
|
|
51462
51578
|
staleThresholdPhases: 1,
|
|
@@ -51614,8 +51730,8 @@ async function analyzeDecisionDrift(directory, config3 = {}) {
|
|
|
51614
51730
|
const contextPath = path33.join(directory, ".swarm", "context.md");
|
|
51615
51731
|
let contextContent = "";
|
|
51616
51732
|
try {
|
|
51617
|
-
if (
|
|
51618
|
-
contextContent =
|
|
51733
|
+
if (fs21.existsSync(contextPath)) {
|
|
51734
|
+
contextContent = fs21.readFileSync(contextPath, "utf-8");
|
|
51619
51735
|
}
|
|
51620
51736
|
} catch {
|
|
51621
51737
|
return {
|
|
@@ -52109,11 +52225,11 @@ function createSystemEnhancerHook(config3, directory) {
|
|
|
52109
52225
|
if (handoffContent) {
|
|
52110
52226
|
const handoffPath = validateSwarmPath(directory, "handoff.md");
|
|
52111
52227
|
const consumedPath = validateSwarmPath(directory, "handoff-consumed.md");
|
|
52112
|
-
if (
|
|
52228
|
+
if (fs22.existsSync(consumedPath)) {
|
|
52113
52229
|
warn("Duplicate handoff detected: handoff-consumed.md already exists");
|
|
52114
|
-
|
|
52230
|
+
fs22.unlinkSync(consumedPath);
|
|
52115
52231
|
}
|
|
52116
|
-
|
|
52232
|
+
fs22.renameSync(handoffPath, consumedPath);
|
|
52117
52233
|
const handoffBlock = `## HANDOFF \u2014 Resuming from model switch
|
|
52118
52234
|
The previous model's session ended. Here is your starting context:
|
|
52119
52235
|
|
|
@@ -52393,11 +52509,11 @@ ${budgetWarning}`);
|
|
|
52393
52509
|
if (handoffContent) {
|
|
52394
52510
|
const handoffPath = validateSwarmPath(directory, "handoff.md");
|
|
52395
52511
|
const consumedPath = validateSwarmPath(directory, "handoff-consumed.md");
|
|
52396
|
-
if (
|
|
52512
|
+
if (fs22.existsSync(consumedPath)) {
|
|
52397
52513
|
warn("Duplicate handoff detected: handoff-consumed.md already exists");
|
|
52398
|
-
|
|
52514
|
+
fs22.unlinkSync(consumedPath);
|
|
52399
52515
|
}
|
|
52400
|
-
|
|
52516
|
+
fs22.renameSync(handoffPath, consumedPath);
|
|
52401
52517
|
const handoffBlock = `## HANDOFF \u2014 Resuming from model switch
|
|
52402
52518
|
The previous model's session ended. Here is your starting context:
|
|
52403
52519
|
|
|
@@ -53166,7 +53282,7 @@ function isReadTool(toolName) {
|
|
|
53166
53282
|
}
|
|
53167
53283
|
|
|
53168
53284
|
// src/hooks/incremental-verify.ts
|
|
53169
|
-
import * as
|
|
53285
|
+
import * as fs23 from "fs";
|
|
53170
53286
|
import * as path34 from "path";
|
|
53171
53287
|
|
|
53172
53288
|
// src/hooks/spawn-helper.ts
|
|
@@ -53242,21 +53358,21 @@ function spawnAsync(command, cwd, timeoutMs) {
|
|
|
53242
53358
|
// src/hooks/incremental-verify.ts
|
|
53243
53359
|
var emittedSkipAdvisories = new Set;
|
|
53244
53360
|
function detectPackageManager(projectDir) {
|
|
53245
|
-
if (
|
|
53361
|
+
if (fs23.existsSync(path34.join(projectDir, "bun.lockb")))
|
|
53246
53362
|
return "bun";
|
|
53247
|
-
if (
|
|
53363
|
+
if (fs23.existsSync(path34.join(projectDir, "pnpm-lock.yaml")))
|
|
53248
53364
|
return "pnpm";
|
|
53249
|
-
if (
|
|
53365
|
+
if (fs23.existsSync(path34.join(projectDir, "yarn.lock")))
|
|
53250
53366
|
return "yarn";
|
|
53251
|
-
if (
|
|
53367
|
+
if (fs23.existsSync(path34.join(projectDir, "package-lock.json")))
|
|
53252
53368
|
return "npm";
|
|
53253
53369
|
return "bun";
|
|
53254
53370
|
}
|
|
53255
53371
|
function detectTypecheckCommand(projectDir) {
|
|
53256
53372
|
const pkgPath = path34.join(projectDir, "package.json");
|
|
53257
|
-
if (
|
|
53373
|
+
if (fs23.existsSync(pkgPath)) {
|
|
53258
53374
|
try {
|
|
53259
|
-
const pkg = JSON.parse(
|
|
53375
|
+
const pkg = JSON.parse(fs23.readFileSync(pkgPath, "utf8"));
|
|
53260
53376
|
const scripts = pkg.scripts;
|
|
53261
53377
|
if (scripts?.typecheck) {
|
|
53262
53378
|
const pm = detectPackageManager(projectDir);
|
|
@@ -53270,8 +53386,8 @@ function detectTypecheckCommand(projectDir) {
|
|
|
53270
53386
|
...pkg.dependencies,
|
|
53271
53387
|
...pkg.devDependencies
|
|
53272
53388
|
};
|
|
53273
|
-
if (!deps?.typescript && !
|
|
53274
|
-
const hasTSMarkers = deps?.typescript ||
|
|
53389
|
+
if (!deps?.typescript && !fs23.existsSync(path34.join(projectDir, "tsconfig.json"))) {}
|
|
53390
|
+
const hasTSMarkers = deps?.typescript || fs23.existsSync(path34.join(projectDir, "tsconfig.json"));
|
|
53275
53391
|
if (hasTSMarkers) {
|
|
53276
53392
|
return { command: ["npx", "tsc", "--noEmit"], language: "typescript" };
|
|
53277
53393
|
}
|
|
@@ -53279,17 +53395,17 @@ function detectTypecheckCommand(projectDir) {
|
|
|
53279
53395
|
return null;
|
|
53280
53396
|
}
|
|
53281
53397
|
}
|
|
53282
|
-
if (
|
|
53398
|
+
if (fs23.existsSync(path34.join(projectDir, "go.mod"))) {
|
|
53283
53399
|
return { command: ["go", "vet", "./..."], language: "go" };
|
|
53284
53400
|
}
|
|
53285
|
-
if (
|
|
53401
|
+
if (fs23.existsSync(path34.join(projectDir, "Cargo.toml"))) {
|
|
53286
53402
|
return { command: ["cargo", "check"], language: "rust" };
|
|
53287
53403
|
}
|
|
53288
|
-
if (
|
|
53404
|
+
if (fs23.existsSync(path34.join(projectDir, "pyproject.toml")) || fs23.existsSync(path34.join(projectDir, "requirements.txt")) || fs23.existsSync(path34.join(projectDir, "setup.py"))) {
|
|
53289
53405
|
return { command: null, language: "python" };
|
|
53290
53406
|
}
|
|
53291
53407
|
try {
|
|
53292
|
-
const entries =
|
|
53408
|
+
const entries = fs23.readdirSync(projectDir);
|
|
53293
53409
|
if (entries.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
|
|
53294
53410
|
return {
|
|
53295
53411
|
command: ["dotnet", "build", "--no-restore"],
|
|
@@ -53358,7 +53474,7 @@ ${errorSummary}`);
|
|
|
53358
53474
|
}
|
|
53359
53475
|
|
|
53360
53476
|
// src/hooks/knowledge-reader.ts
|
|
53361
|
-
import { existsSync as
|
|
53477
|
+
import { existsSync as existsSync21 } from "fs";
|
|
53362
53478
|
import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
|
|
53363
53479
|
import * as path35 from "path";
|
|
53364
53480
|
var JACCARD_THRESHOLD = 0.6;
|
|
@@ -53411,7 +53527,7 @@ async function recordLessonsShown(directory, lessonIds, currentPhase) {
|
|
|
53411
53527
|
const shownFile = path35.join(directory, ".swarm", ".knowledge-shown.json");
|
|
53412
53528
|
try {
|
|
53413
53529
|
let shownData = {};
|
|
53414
|
-
if (
|
|
53530
|
+
if (existsSync21(shownFile)) {
|
|
53415
53531
|
const content = await readFile5(shownFile, "utf-8");
|
|
53416
53532
|
shownData = JSON.parse(content);
|
|
53417
53533
|
}
|
|
@@ -53513,7 +53629,7 @@ async function readMergedKnowledge(directory, config3, context) {
|
|
|
53513
53629
|
async function updateRetrievalOutcome(directory, phaseInfo, phaseSucceeded) {
|
|
53514
53630
|
const shownFile = path35.join(directory, ".swarm", ".knowledge-shown.json");
|
|
53515
53631
|
try {
|
|
53516
|
-
if (!
|
|
53632
|
+
if (!existsSync21(shownFile)) {
|
|
53517
53633
|
return;
|
|
53518
53634
|
}
|
|
53519
53635
|
const content = await readFile5(shownFile, "utf-8");
|
|
@@ -53983,12 +54099,12 @@ Use this data to avoid repeating known failure patterns.`;
|
|
|
53983
54099
|
// src/hooks/curator-drift.ts
|
|
53984
54100
|
init_event_bus();
|
|
53985
54101
|
init_utils2();
|
|
53986
|
-
import * as
|
|
54102
|
+
import * as fs24 from "fs";
|
|
53987
54103
|
import * as path36 from "path";
|
|
53988
54104
|
var DRIFT_REPORT_PREFIX = "drift-report-phase-";
|
|
53989
54105
|
async function readPriorDriftReports(directory) {
|
|
53990
54106
|
const swarmDir = path36.join(directory, ".swarm");
|
|
53991
|
-
const entries = await
|
|
54107
|
+
const entries = await fs24.promises.readdir(swarmDir).catch(() => null);
|
|
53992
54108
|
if (entries === null)
|
|
53993
54109
|
return [];
|
|
53994
54110
|
const reportFiles = entries.filter((name2) => name2.startsWith(DRIFT_REPORT_PREFIX) && name2.endsWith(".json")).sort();
|
|
@@ -54015,9 +54131,9 @@ async function writeDriftReport(directory, report) {
|
|
|
54015
54131
|
const filename = `${DRIFT_REPORT_PREFIX}${report.phase}.json`;
|
|
54016
54132
|
const filePath = validateSwarmPath(directory, filename);
|
|
54017
54133
|
const swarmDir = path36.dirname(filePath);
|
|
54018
|
-
await
|
|
54134
|
+
await fs24.promises.mkdir(swarmDir, { recursive: true });
|
|
54019
54135
|
try {
|
|
54020
|
-
await
|
|
54136
|
+
await fs24.promises.writeFile(filePath, JSON.stringify(report, null, 2), "utf-8");
|
|
54021
54137
|
} catch (err2) {
|
|
54022
54138
|
throw new Error(`[curator-drift] Failed to write drift report to ${filePath}: ${String(err2)}`);
|
|
54023
54139
|
}
|
|
@@ -54303,7 +54419,7 @@ var WRITE_TOOLS = new Set([
|
|
|
54303
54419
|
"append",
|
|
54304
54420
|
"prepend"
|
|
54305
54421
|
]);
|
|
54306
|
-
function createScopeGuardHook(config3,
|
|
54422
|
+
function createScopeGuardHook(config3, directory, injectAdvisory) {
|
|
54307
54423
|
const enabled = config3.enabled ?? true;
|
|
54308
54424
|
const _skipInTurbo = config3.skip_in_turbo ?? false;
|
|
54309
54425
|
return {
|
|
@@ -54320,7 +54436,7 @@ function createScopeGuardHook(config3, _directory, injectAdvisory) {
|
|
|
54320
54436
|
const isArchitect2 = stripKnownSwarmPrefix(agentName) === ORCHESTRATOR_NAME;
|
|
54321
54437
|
if (isArchitect2)
|
|
54322
54438
|
return;
|
|
54323
|
-
const declaredScope = session?.declaredCoderScope;
|
|
54439
|
+
const declaredScope = session?.declaredCoderScope ?? (session?.currentTaskId ? pendingCoderScopeByTaskId.get(session.currentTaskId) : null);
|
|
54324
54440
|
if (!declaredScope || declaredScope.length === 0)
|
|
54325
54441
|
return;
|
|
54326
54442
|
const argsObj = output.args;
|
|
@@ -54328,7 +54444,7 @@ function createScopeGuardHook(config3, _directory, injectAdvisory) {
|
|
|
54328
54444
|
if (typeof rawFilePath !== "string" || !rawFilePath)
|
|
54329
54445
|
return;
|
|
54330
54446
|
const filePath = rawFilePath.replace(/[\r\n\t]/g, "_").split(String.fromCharCode(27)).join("_").replace(/\[[\d;]*m/g, "");
|
|
54331
|
-
if (!isFileInScope(filePath, declaredScope)) {
|
|
54447
|
+
if (!isFileInScope(filePath, declaredScope, directory)) {
|
|
54332
54448
|
const taskId = session?.currentTaskId ?? "unknown";
|
|
54333
54449
|
const violationMessage = `SCOPE VIOLATION: ${agentName} attempted to modify '${filePath}' which is not in declared scope for task ${taskId}. Declared scope: [${declaredScope.slice(0, 3).join(", ")}${declaredScope.length > 3 ? "..." : ""}]`;
|
|
54334
54450
|
if (session) {
|
|
@@ -54351,10 +54467,11 @@ function createScopeGuardHook(config3, _directory, injectAdvisory) {
|
|
|
54351
54467
|
}
|
|
54352
54468
|
};
|
|
54353
54469
|
}
|
|
54354
|
-
function isFileInScope(filePath, scopeEntries) {
|
|
54355
|
-
const
|
|
54470
|
+
function isFileInScope(filePath, scopeEntries, directory) {
|
|
54471
|
+
const dir = directory ?? process.cwd();
|
|
54472
|
+
const resolvedFile = path37.resolve(dir, filePath);
|
|
54356
54473
|
return scopeEntries.some((scope) => {
|
|
54357
|
-
const resolvedScope = path37.resolve(scope);
|
|
54474
|
+
const resolvedScope = path37.resolve(dir, scope);
|
|
54358
54475
|
if (resolvedFile === resolvedScope)
|
|
54359
54476
|
return true;
|
|
54360
54477
|
const rel = path37.relative(resolvedScope, resolvedFile);
|
|
@@ -54407,7 +54524,7 @@ function createSelfReviewHook(config3, injectAdvisory) {
|
|
|
54407
54524
|
}
|
|
54408
54525
|
|
|
54409
54526
|
// src/hooks/slop-detector.ts
|
|
54410
|
-
import * as
|
|
54527
|
+
import * as fs25 from "fs";
|
|
54411
54528
|
import * as path38 from "path";
|
|
54412
54529
|
var WRITE_EDIT_TOOLS = new Set([
|
|
54413
54530
|
"write",
|
|
@@ -54453,7 +54570,7 @@ function checkBoilerplateExplosion(content, taskDescription, threshold) {
|
|
|
54453
54570
|
function walkFiles(dir, exts, deadline) {
|
|
54454
54571
|
const results = [];
|
|
54455
54572
|
try {
|
|
54456
|
-
for (const entry of
|
|
54573
|
+
for (const entry of fs25.readdirSync(dir, { withFileTypes: true })) {
|
|
54457
54574
|
if (deadline !== undefined && Date.now() > deadline)
|
|
54458
54575
|
break;
|
|
54459
54576
|
if (entry.isSymbolicLink())
|
|
@@ -54473,7 +54590,7 @@ function walkFiles(dir, exts, deadline) {
|
|
|
54473
54590
|
return results;
|
|
54474
54591
|
}
|
|
54475
54592
|
function checkDeadExports(content, projectDir, startTime) {
|
|
54476
|
-
const hasPackageJson =
|
|
54593
|
+
const hasPackageJson = fs25.existsSync(path38.join(projectDir, "package.json"));
|
|
54477
54594
|
if (!hasPackageJson)
|
|
54478
54595
|
return null;
|
|
54479
54596
|
const exportMatches = content.matchAll(/^\+(?:export)\s+(?:function|class|const|type|interface)\s+(\w{3,})/gm);
|
|
@@ -54496,7 +54613,7 @@ function checkDeadExports(content, projectDir, startTime) {
|
|
|
54496
54613
|
if (found || Date.now() - startTime > 480)
|
|
54497
54614
|
break;
|
|
54498
54615
|
try {
|
|
54499
|
-
const text =
|
|
54616
|
+
const text = fs25.readFileSync(file3, "utf-8");
|
|
54500
54617
|
if (importPattern.test(text))
|
|
54501
54618
|
found = true;
|
|
54502
54619
|
importPattern.lastIndex = 0;
|
|
@@ -54629,7 +54746,7 @@ Review before proceeding.`;
|
|
|
54629
54746
|
|
|
54630
54747
|
// src/hooks/steering-consumed.ts
|
|
54631
54748
|
init_utils2();
|
|
54632
|
-
import * as
|
|
54749
|
+
import * as fs26 from "fs";
|
|
54633
54750
|
function recordSteeringConsumed(directory, directiveId) {
|
|
54634
54751
|
try {
|
|
54635
54752
|
const eventsPath = validateSwarmPath(directory, "events.jsonl");
|
|
@@ -54638,7 +54755,7 @@ function recordSteeringConsumed(directory, directiveId) {
|
|
|
54638
54755
|
directiveId,
|
|
54639
54756
|
timestamp: new Date().toISOString()
|
|
54640
54757
|
};
|
|
54641
|
-
|
|
54758
|
+
fs26.appendFileSync(eventsPath, `${JSON.stringify(event)}
|
|
54642
54759
|
`, "utf-8");
|
|
54643
54760
|
} catch {}
|
|
54644
54761
|
}
|
|
@@ -54804,6 +54921,10 @@ async function rehydrateState(snapshot) {
|
|
|
54804
54921
|
}
|
|
54805
54922
|
if (snapshot.agentSessions) {
|
|
54806
54923
|
for (const [sessionId, serializedSession] of Object.entries(snapshot.agentSessions)) {
|
|
54924
|
+
if (!serializedSession || typeof serializedSession !== "object" || typeof serializedSession.agentName !== "string" || typeof serializedSession.lastToolCallTime !== "number" || typeof serializedSession.delegationActive !== "boolean") {
|
|
54925
|
+
console.warn("[snapshot-reader] Skipping malformed session %s: missing required fields (agentName, lastToolCallTime, delegationActive)", sessionId);
|
|
54926
|
+
continue;
|
|
54927
|
+
}
|
|
54807
54928
|
swarmState.agentSessions.set(sessionId, deserializeAgentSession(serializedSession));
|
|
54808
54929
|
}
|
|
54809
54930
|
}
|
|
@@ -54995,7 +55116,7 @@ var build_check = createSwarmTool({
|
|
|
54995
55116
|
// src/tools/check-gate-status.ts
|
|
54996
55117
|
init_dist();
|
|
54997
55118
|
init_create_tool();
|
|
54998
|
-
import * as
|
|
55119
|
+
import * as fs27 from "fs";
|
|
54999
55120
|
import * as path39 from "path";
|
|
55000
55121
|
var EVIDENCE_DIR = ".swarm/evidence";
|
|
55001
55122
|
var TASK_ID_PATTERN2 = /^\d+\.\d+(\.\d+)*$/;
|
|
@@ -55019,12 +55140,12 @@ function isPathWithinSwarm(filePath, workspaceRoot) {
|
|
|
55019
55140
|
return normalizedPath.startsWith(swarmPath);
|
|
55020
55141
|
}
|
|
55021
55142
|
function readEvidenceFile(evidencePath) {
|
|
55022
|
-
if (!
|
|
55143
|
+
if (!fs27.existsSync(evidencePath)) {
|
|
55023
55144
|
return null;
|
|
55024
55145
|
}
|
|
55025
55146
|
let content;
|
|
55026
55147
|
try {
|
|
55027
|
-
content =
|
|
55148
|
+
content = fs27.readFileSync(evidencePath, "utf-8");
|
|
55028
55149
|
} catch {
|
|
55029
55150
|
return null;
|
|
55030
55151
|
}
|
|
@@ -55145,7 +55266,7 @@ init_checkpoint();
|
|
|
55145
55266
|
// src/tools/complexity-hotspots.ts
|
|
55146
55267
|
init_dist();
|
|
55147
55268
|
init_create_tool();
|
|
55148
|
-
import * as
|
|
55269
|
+
import * as fs28 from "fs";
|
|
55149
55270
|
import * as path40 from "path";
|
|
55150
55271
|
var MAX_FILE_SIZE_BYTES2 = 256 * 1024;
|
|
55151
55272
|
var DEFAULT_DAYS = 90;
|
|
@@ -55275,11 +55396,11 @@ function estimateComplexity(content) {
|
|
|
55275
55396
|
}
|
|
55276
55397
|
function getComplexityForFile(filePath) {
|
|
55277
55398
|
try {
|
|
55278
|
-
const stat2 =
|
|
55399
|
+
const stat2 = fs28.statSync(filePath);
|
|
55279
55400
|
if (stat2.size > MAX_FILE_SIZE_BYTES2) {
|
|
55280
55401
|
return null;
|
|
55281
55402
|
}
|
|
55282
|
-
const content =
|
|
55403
|
+
const content = fs28.readFileSync(filePath, "utf-8");
|
|
55283
55404
|
return estimateComplexity(content);
|
|
55284
55405
|
} catch {
|
|
55285
55406
|
return null;
|
|
@@ -55300,7 +55421,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
55300
55421
|
let analyzedFiles = 0;
|
|
55301
55422
|
for (const [file3, churnCount] of filteredChurn) {
|
|
55302
55423
|
let fullPath = file3;
|
|
55303
|
-
if (!
|
|
55424
|
+
if (!fs28.existsSync(fullPath)) {
|
|
55304
55425
|
fullPath = path40.join(cwd, file3);
|
|
55305
55426
|
}
|
|
55306
55427
|
const complexity = getComplexityForFile(fullPath);
|
|
@@ -55509,7 +55630,7 @@ var curator_analyze = createSwarmTool({
|
|
|
55509
55630
|
});
|
|
55510
55631
|
// src/tools/declare-scope.ts
|
|
55511
55632
|
init_tool();
|
|
55512
|
-
import * as
|
|
55633
|
+
import * as fs29 from "fs";
|
|
55513
55634
|
import * as path41 from "path";
|
|
55514
55635
|
init_create_tool();
|
|
55515
55636
|
function validateTaskIdFormat(taskId) {
|
|
@@ -55602,9 +55723,9 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
55602
55723
|
}
|
|
55603
55724
|
const resolvedDir = path41.resolve(normalizedDir);
|
|
55604
55725
|
try {
|
|
55605
|
-
const realPath =
|
|
55726
|
+
const realPath = fs29.realpathSync(resolvedDir);
|
|
55606
55727
|
const planPath2 = path41.join(realPath, ".swarm", "plan.json");
|
|
55607
|
-
if (!
|
|
55728
|
+
if (!fs29.existsSync(planPath2)) {
|
|
55608
55729
|
return {
|
|
55609
55730
|
success: false,
|
|
55610
55731
|
message: `Invalid working_directory: plan not found in "${realPath}"`,
|
|
@@ -55628,7 +55749,7 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
55628
55749
|
}
|
|
55629
55750
|
const directory = normalizedDir || fallbackDir;
|
|
55630
55751
|
const planPath = path41.resolve(directory, ".swarm", "plan.json");
|
|
55631
|
-
if (!
|
|
55752
|
+
if (!fs29.existsSync(planPath)) {
|
|
55632
55753
|
return {
|
|
55633
55754
|
success: false,
|
|
55634
55755
|
message: "No plan found",
|
|
@@ -55637,7 +55758,7 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
55637
55758
|
}
|
|
55638
55759
|
let planContent;
|
|
55639
55760
|
try {
|
|
55640
|
-
planContent = JSON.parse(
|
|
55761
|
+
planContent = JSON.parse(fs29.readFileSync(planPath, "utf-8"));
|
|
55641
55762
|
} catch {
|
|
55642
55763
|
return {
|
|
55643
55764
|
success: false,
|
|
@@ -56042,7 +56163,7 @@ Use these as DOMAIN values when delegating to @sme.`;
|
|
|
56042
56163
|
// src/tools/evidence-check.ts
|
|
56043
56164
|
init_dist();
|
|
56044
56165
|
init_create_tool();
|
|
56045
|
-
import * as
|
|
56166
|
+
import * as fs30 from "fs";
|
|
56046
56167
|
import * as path42 from "path";
|
|
56047
56168
|
var MAX_FILE_SIZE_BYTES3 = 1024 * 1024;
|
|
56048
56169
|
var MAX_EVIDENCE_FILES = 1000;
|
|
@@ -56091,12 +56212,12 @@ function parseCompletedTasks(planContent) {
|
|
|
56091
56212
|
}
|
|
56092
56213
|
function readEvidenceFiles(evidenceDir, _cwd) {
|
|
56093
56214
|
const evidence = [];
|
|
56094
|
-
if (!
|
|
56215
|
+
if (!fs30.existsSync(evidenceDir) || !fs30.statSync(evidenceDir).isDirectory()) {
|
|
56095
56216
|
return evidence;
|
|
56096
56217
|
}
|
|
56097
56218
|
let files;
|
|
56098
56219
|
try {
|
|
56099
|
-
files =
|
|
56220
|
+
files = fs30.readdirSync(evidenceDir);
|
|
56100
56221
|
} catch {
|
|
56101
56222
|
return evidence;
|
|
56102
56223
|
}
|
|
@@ -56112,7 +56233,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
56112
56233
|
if (!resolvedPath.startsWith(evidenceDirResolved)) {
|
|
56113
56234
|
continue;
|
|
56114
56235
|
}
|
|
56115
|
-
const stat2 =
|
|
56236
|
+
const stat2 = fs30.lstatSync(filePath);
|
|
56116
56237
|
if (!stat2.isFile()) {
|
|
56117
56238
|
continue;
|
|
56118
56239
|
}
|
|
@@ -56121,7 +56242,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
56121
56242
|
}
|
|
56122
56243
|
let fileStat;
|
|
56123
56244
|
try {
|
|
56124
|
-
fileStat =
|
|
56245
|
+
fileStat = fs30.statSync(filePath);
|
|
56125
56246
|
if (fileStat.size > MAX_FILE_SIZE_BYTES3) {
|
|
56126
56247
|
continue;
|
|
56127
56248
|
}
|
|
@@ -56130,7 +56251,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
56130
56251
|
}
|
|
56131
56252
|
let content;
|
|
56132
56253
|
try {
|
|
56133
|
-
content =
|
|
56254
|
+
content = fs30.readFileSync(filePath, "utf-8");
|
|
56134
56255
|
} catch {
|
|
56135
56256
|
continue;
|
|
56136
56257
|
}
|
|
@@ -56240,7 +56361,7 @@ var evidence_check = createSwarmTool({
|
|
|
56240
56361
|
}
|
|
56241
56362
|
let planContent;
|
|
56242
56363
|
try {
|
|
56243
|
-
planContent =
|
|
56364
|
+
planContent = fs30.readFileSync(planPath, "utf-8");
|
|
56244
56365
|
} catch {
|
|
56245
56366
|
const result2 = {
|
|
56246
56367
|
message: "No completed tasks found in plan.",
|
|
@@ -56275,7 +56396,7 @@ var evidence_check = createSwarmTool({
|
|
|
56275
56396
|
// src/tools/file-extractor.ts
|
|
56276
56397
|
init_tool();
|
|
56277
56398
|
init_create_tool();
|
|
56278
|
-
import * as
|
|
56399
|
+
import * as fs31 from "fs";
|
|
56279
56400
|
import * as path43 from "path";
|
|
56280
56401
|
var EXT_MAP = {
|
|
56281
56402
|
python: ".py",
|
|
@@ -56338,8 +56459,8 @@ var extract_code_blocks = createSwarmTool({
|
|
|
56338
56459
|
execute: async (args2, directory) => {
|
|
56339
56460
|
const { content, output_dir, prefix } = args2;
|
|
56340
56461
|
const targetDir = output_dir || directory;
|
|
56341
|
-
if (!
|
|
56342
|
-
|
|
56462
|
+
if (!fs31.existsSync(targetDir)) {
|
|
56463
|
+
fs31.mkdirSync(targetDir, { recursive: true });
|
|
56343
56464
|
}
|
|
56344
56465
|
if (!content) {
|
|
56345
56466
|
return "Error: content is required";
|
|
@@ -56361,12 +56482,12 @@ var extract_code_blocks = createSwarmTool({
|
|
|
56361
56482
|
const base = path43.basename(filepath, path43.extname(filepath));
|
|
56362
56483
|
const ext = path43.extname(filepath);
|
|
56363
56484
|
let counter = 1;
|
|
56364
|
-
while (
|
|
56485
|
+
while (fs31.existsSync(filepath)) {
|
|
56365
56486
|
filepath = path43.join(targetDir, `${base}_${counter}${ext}`);
|
|
56366
56487
|
counter++;
|
|
56367
56488
|
}
|
|
56368
56489
|
try {
|
|
56369
|
-
|
|
56490
|
+
fs31.writeFileSync(filepath, code.trim(), "utf-8");
|
|
56370
56491
|
savedFiles.push(filepath);
|
|
56371
56492
|
} catch (error93) {
|
|
56372
56493
|
errors5.push(`Failed to save ${filename}: ${error93 instanceof Error ? error93.message : String(error93)}`);
|
|
@@ -56482,7 +56603,7 @@ var gitingest = createSwarmTool({
|
|
|
56482
56603
|
// src/tools/imports.ts
|
|
56483
56604
|
init_dist();
|
|
56484
56605
|
init_create_tool();
|
|
56485
|
-
import * as
|
|
56606
|
+
import * as fs32 from "fs";
|
|
56486
56607
|
import * as path44 from "path";
|
|
56487
56608
|
var MAX_FILE_PATH_LENGTH2 = 500;
|
|
56488
56609
|
var MAX_SYMBOL_LENGTH = 256;
|
|
@@ -56651,7 +56772,7 @@ var SKIP_DIRECTORIES2 = new Set([
|
|
|
56651
56772
|
function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFiles: 0, fileErrors: [] }) {
|
|
56652
56773
|
let entries;
|
|
56653
56774
|
try {
|
|
56654
|
-
entries =
|
|
56775
|
+
entries = fs32.readdirSync(dir);
|
|
56655
56776
|
} catch (e) {
|
|
56656
56777
|
stats.fileErrors.push({
|
|
56657
56778
|
path: dir,
|
|
@@ -56668,7 +56789,7 @@ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFile
|
|
|
56668
56789
|
const fullPath = path44.join(dir, entry);
|
|
56669
56790
|
let stat2;
|
|
56670
56791
|
try {
|
|
56671
|
-
stat2 =
|
|
56792
|
+
stat2 = fs32.statSync(fullPath);
|
|
56672
56793
|
} catch (e) {
|
|
56673
56794
|
stats.fileErrors.push({
|
|
56674
56795
|
path: fullPath,
|
|
@@ -56737,7 +56858,7 @@ var imports = createSwarmTool({
|
|
|
56737
56858
|
}
|
|
56738
56859
|
try {
|
|
56739
56860
|
const targetFile = path44.resolve(file3);
|
|
56740
|
-
if (!
|
|
56861
|
+
if (!fs32.existsSync(targetFile)) {
|
|
56741
56862
|
const errorResult = {
|
|
56742
56863
|
error: `target file not found: ${file3}`,
|
|
56743
56864
|
target: file3,
|
|
@@ -56747,7 +56868,7 @@ var imports = createSwarmTool({
|
|
|
56747
56868
|
};
|
|
56748
56869
|
return JSON.stringify(errorResult, null, 2);
|
|
56749
56870
|
}
|
|
56750
|
-
const targetStat =
|
|
56871
|
+
const targetStat = fs32.statSync(targetFile);
|
|
56751
56872
|
if (!targetStat.isFile()) {
|
|
56752
56873
|
const errorResult = {
|
|
56753
56874
|
error: "target must be a file, not a directory",
|
|
@@ -56773,12 +56894,12 @@ var imports = createSwarmTool({
|
|
|
56773
56894
|
if (consumers.length >= MAX_CONSUMERS)
|
|
56774
56895
|
break;
|
|
56775
56896
|
try {
|
|
56776
|
-
const stat2 =
|
|
56897
|
+
const stat2 = fs32.statSync(filePath);
|
|
56777
56898
|
if (stat2.size > MAX_FILE_SIZE_BYTES4) {
|
|
56778
56899
|
skippedFileCount++;
|
|
56779
56900
|
continue;
|
|
56780
56901
|
}
|
|
56781
|
-
const buffer =
|
|
56902
|
+
const buffer = fs32.readFileSync(filePath);
|
|
56782
56903
|
if (isBinaryFile2(filePath, buffer)) {
|
|
56783
56904
|
skippedFileCount++;
|
|
56784
56905
|
continue;
|
|
@@ -56950,7 +57071,7 @@ var knowledgeAdd = createSwarmTool({
|
|
|
56950
57071
|
});
|
|
56951
57072
|
// src/tools/knowledge-query.ts
|
|
56952
57073
|
init_dist();
|
|
56953
|
-
import { existsSync as
|
|
57074
|
+
import { existsSync as existsSync29 } from "fs";
|
|
56954
57075
|
init_create_tool();
|
|
56955
57076
|
var DEFAULT_LIMIT = 10;
|
|
56956
57077
|
var MAX_LESSON_LENGTH = 200;
|
|
@@ -57020,14 +57141,14 @@ function validateLimit(limit) {
|
|
|
57020
57141
|
}
|
|
57021
57142
|
async function readSwarmKnowledge(directory) {
|
|
57022
57143
|
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
57023
|
-
if (!
|
|
57144
|
+
if (!existsSync29(swarmPath)) {
|
|
57024
57145
|
return [];
|
|
57025
57146
|
}
|
|
57026
57147
|
return readKnowledge(swarmPath);
|
|
57027
57148
|
}
|
|
57028
57149
|
async function readHiveKnowledge() {
|
|
57029
57150
|
const hivePath = resolveHiveKnowledgePath();
|
|
57030
|
-
if (!
|
|
57151
|
+
if (!existsSync29(hivePath)) {
|
|
57031
57152
|
return [];
|
|
57032
57153
|
}
|
|
57033
57154
|
return readKnowledge(hivePath);
|
|
@@ -57327,7 +57448,7 @@ init_dist();
|
|
|
57327
57448
|
init_config();
|
|
57328
57449
|
init_schema();
|
|
57329
57450
|
init_manager();
|
|
57330
|
-
import * as
|
|
57451
|
+
import * as fs33 from "fs";
|
|
57331
57452
|
import * as path45 from "path";
|
|
57332
57453
|
init_utils2();
|
|
57333
57454
|
init_create_tool();
|
|
@@ -57587,7 +57708,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
57587
57708
|
if (agentsMissing.length > 0) {
|
|
57588
57709
|
try {
|
|
57589
57710
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
57590
|
-
const planRaw =
|
|
57711
|
+
const planRaw = fs33.readFileSync(planPath, "utf-8");
|
|
57591
57712
|
const plan = JSON.parse(planRaw);
|
|
57592
57713
|
const targetPhase = plan.phases.find((p) => p.id === phase);
|
|
57593
57714
|
if (targetPhase && targetPhase.tasks.length > 0 && targetPhase.tasks.every((t) => t.status === "completed")) {
|
|
@@ -57618,7 +57739,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
57618
57739
|
if (phaseCompleteConfig.regression_sweep?.enforce) {
|
|
57619
57740
|
try {
|
|
57620
57741
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
57621
|
-
const planRaw =
|
|
57742
|
+
const planRaw = fs33.readFileSync(planPath, "utf-8");
|
|
57622
57743
|
const plan = JSON.parse(planRaw);
|
|
57623
57744
|
const targetPhase = plan.phases.find((p) => p.id === phase);
|
|
57624
57745
|
if (targetPhase) {
|
|
@@ -57656,7 +57777,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
57656
57777
|
};
|
|
57657
57778
|
try {
|
|
57658
57779
|
const eventsPath = validateSwarmPath(dir, "events.jsonl");
|
|
57659
|
-
|
|
57780
|
+
fs33.appendFileSync(eventsPath, `${JSON.stringify(event)}
|
|
57660
57781
|
`, "utf-8");
|
|
57661
57782
|
} catch (writeError) {
|
|
57662
57783
|
warnings.push(`Warning: failed to write phase complete event: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
|
|
@@ -57675,12 +57796,12 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
57675
57796
|
}
|
|
57676
57797
|
try {
|
|
57677
57798
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
57678
|
-
const planJson =
|
|
57799
|
+
const planJson = fs33.readFileSync(planPath, "utf-8");
|
|
57679
57800
|
const plan = JSON.parse(planJson);
|
|
57680
57801
|
const phaseObj = plan.phases.find((p) => p.id === phase);
|
|
57681
57802
|
if (phaseObj) {
|
|
57682
57803
|
phaseObj.status = "completed";
|
|
57683
|
-
|
|
57804
|
+
fs33.writeFileSync(planPath, `${JSON.stringify(plan, null, 2)}
|
|
57684
57805
|
`, "utf-8");
|
|
57685
57806
|
}
|
|
57686
57807
|
} catch (error93) {
|
|
@@ -57699,6 +57820,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
57699
57820
|
agentsMissing,
|
|
57700
57821
|
warnings
|
|
57701
57822
|
};
|
|
57823
|
+
await flushPendingSnapshot(dir);
|
|
57702
57824
|
return JSON.stringify({ ...result, timestamp: event.timestamp, duration_ms: durationMs }, null, 2);
|
|
57703
57825
|
}
|
|
57704
57826
|
var phase_complete = createSwarmTool({
|
|
@@ -57733,7 +57855,7 @@ init_dist();
|
|
|
57733
57855
|
init_discovery();
|
|
57734
57856
|
init_utils();
|
|
57735
57857
|
init_create_tool();
|
|
57736
|
-
import * as
|
|
57858
|
+
import * as fs34 from "fs";
|
|
57737
57859
|
import * as path46 from "path";
|
|
57738
57860
|
var MAX_OUTPUT_BYTES5 = 52428800;
|
|
57739
57861
|
var AUDIT_TIMEOUT_MS = 120000;
|
|
@@ -57752,28 +57874,28 @@ function validateArgs3(args2) {
|
|
|
57752
57874
|
function detectEcosystems(directory) {
|
|
57753
57875
|
const ecosystems = [];
|
|
57754
57876
|
const cwd = directory;
|
|
57755
|
-
if (
|
|
57877
|
+
if (fs34.existsSync(path46.join(cwd, "package.json"))) {
|
|
57756
57878
|
ecosystems.push("npm");
|
|
57757
57879
|
}
|
|
57758
|
-
if (
|
|
57880
|
+
if (fs34.existsSync(path46.join(cwd, "pyproject.toml")) || fs34.existsSync(path46.join(cwd, "requirements.txt"))) {
|
|
57759
57881
|
ecosystems.push("pip");
|
|
57760
57882
|
}
|
|
57761
|
-
if (
|
|
57883
|
+
if (fs34.existsSync(path46.join(cwd, "Cargo.toml"))) {
|
|
57762
57884
|
ecosystems.push("cargo");
|
|
57763
57885
|
}
|
|
57764
|
-
if (
|
|
57886
|
+
if (fs34.existsSync(path46.join(cwd, "go.mod"))) {
|
|
57765
57887
|
ecosystems.push("go");
|
|
57766
57888
|
}
|
|
57767
57889
|
try {
|
|
57768
|
-
const files =
|
|
57890
|
+
const files = fs34.readdirSync(cwd);
|
|
57769
57891
|
if (files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
|
|
57770
57892
|
ecosystems.push("dotnet");
|
|
57771
57893
|
}
|
|
57772
57894
|
} catch {}
|
|
57773
|
-
if (
|
|
57895
|
+
if (fs34.existsSync(path46.join(cwd, "Gemfile")) || fs34.existsSync(path46.join(cwd, "Gemfile.lock"))) {
|
|
57774
57896
|
ecosystems.push("ruby");
|
|
57775
57897
|
}
|
|
57776
|
-
if (
|
|
57898
|
+
if (fs34.existsSync(path46.join(cwd, "pubspec.yaml"))) {
|
|
57777
57899
|
ecosystems.push("dart");
|
|
57778
57900
|
}
|
|
57779
57901
|
return ecosystems;
|
|
@@ -58835,7 +58957,7 @@ var SUPPORTED_PARSER_EXTENSIONS = new Set([
|
|
|
58835
58957
|
]);
|
|
58836
58958
|
// src/tools/pre-check-batch.ts
|
|
58837
58959
|
init_dist();
|
|
58838
|
-
import * as
|
|
58960
|
+
import * as fs37 from "fs";
|
|
58839
58961
|
import * as path49 from "path";
|
|
58840
58962
|
|
|
58841
58963
|
// node_modules/yocto-queue/index.js
|
|
@@ -59003,7 +59125,7 @@ init_lint();
|
|
|
59003
59125
|
init_manager();
|
|
59004
59126
|
|
|
59005
59127
|
// src/quality/metrics.ts
|
|
59006
|
-
import * as
|
|
59128
|
+
import * as fs35 from "fs";
|
|
59007
59129
|
import * as path47 from "path";
|
|
59008
59130
|
var MAX_FILE_SIZE_BYTES5 = 256 * 1024;
|
|
59009
59131
|
var MIN_DUPLICATION_LINES = 10;
|
|
@@ -59042,11 +59164,11 @@ function estimateCyclomaticComplexity(content) {
|
|
|
59042
59164
|
}
|
|
59043
59165
|
function getComplexityForFile2(filePath) {
|
|
59044
59166
|
try {
|
|
59045
|
-
const stat2 =
|
|
59167
|
+
const stat2 = fs35.statSync(filePath);
|
|
59046
59168
|
if (stat2.size > MAX_FILE_SIZE_BYTES5) {
|
|
59047
59169
|
return null;
|
|
59048
59170
|
}
|
|
59049
|
-
const content =
|
|
59171
|
+
const content = fs35.readFileSync(filePath, "utf-8");
|
|
59050
59172
|
return estimateCyclomaticComplexity(content);
|
|
59051
59173
|
} catch {
|
|
59052
59174
|
return null;
|
|
@@ -59057,7 +59179,7 @@ async function computeComplexityDelta(files, workingDir) {
|
|
|
59057
59179
|
const analyzedFiles = [];
|
|
59058
59180
|
for (const file3 of files) {
|
|
59059
59181
|
const fullPath = path47.isAbsolute(file3) ? file3 : path47.join(workingDir, file3);
|
|
59060
|
-
if (!
|
|
59182
|
+
if (!fs35.existsSync(fullPath)) {
|
|
59061
59183
|
continue;
|
|
59062
59184
|
}
|
|
59063
59185
|
const complexity = getComplexityForFile2(fullPath);
|
|
@@ -59178,7 +59300,7 @@ function countGoExports(content) {
|
|
|
59178
59300
|
}
|
|
59179
59301
|
function getExportCountForFile(filePath) {
|
|
59180
59302
|
try {
|
|
59181
|
-
const content =
|
|
59303
|
+
const content = fs35.readFileSync(filePath, "utf-8");
|
|
59182
59304
|
const ext = path47.extname(filePath).toLowerCase();
|
|
59183
59305
|
switch (ext) {
|
|
59184
59306
|
case ".ts":
|
|
@@ -59206,7 +59328,7 @@ async function computePublicApiDelta(files, workingDir) {
|
|
|
59206
59328
|
const analyzedFiles = [];
|
|
59207
59329
|
for (const file3 of files) {
|
|
59208
59330
|
const fullPath = path47.isAbsolute(file3) ? file3 : path47.join(workingDir, file3);
|
|
59209
|
-
if (!
|
|
59331
|
+
if (!fs35.existsSync(fullPath)) {
|
|
59210
59332
|
continue;
|
|
59211
59333
|
}
|
|
59212
59334
|
const exports = getExportCountForFile(fullPath);
|
|
@@ -59240,15 +59362,15 @@ async function computeDuplicationRatio(files, workingDir) {
|
|
|
59240
59362
|
const analyzedFiles = [];
|
|
59241
59363
|
for (const file3 of files) {
|
|
59242
59364
|
const fullPath = path47.isAbsolute(file3) ? file3 : path47.join(workingDir, file3);
|
|
59243
|
-
if (!
|
|
59365
|
+
if (!fs35.existsSync(fullPath)) {
|
|
59244
59366
|
continue;
|
|
59245
59367
|
}
|
|
59246
59368
|
try {
|
|
59247
|
-
const stat2 =
|
|
59369
|
+
const stat2 = fs35.statSync(fullPath);
|
|
59248
59370
|
if (stat2.size > MAX_FILE_SIZE_BYTES5) {
|
|
59249
59371
|
continue;
|
|
59250
59372
|
}
|
|
59251
|
-
const content =
|
|
59373
|
+
const content = fs35.readFileSync(fullPath, "utf-8");
|
|
59252
59374
|
const lines = content.split(`
|
|
59253
59375
|
`).filter((line) => line.trim().length > 0);
|
|
59254
59376
|
if (lines.length < MIN_DUPLICATION_LINES) {
|
|
@@ -59424,7 +59546,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
59424
59546
|
let testLines = 0;
|
|
59425
59547
|
let codeLines = 0;
|
|
59426
59548
|
const srcDir = path47.join(workingDir, "src");
|
|
59427
|
-
if (
|
|
59549
|
+
if (fs35.existsSync(srcDir)) {
|
|
59428
59550
|
await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
59429
59551
|
codeLines += lines;
|
|
59430
59552
|
});
|
|
@@ -59432,14 +59554,14 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
59432
59554
|
const possibleSrcDirs = ["lib", "app", "source", "core"];
|
|
59433
59555
|
for (const dir of possibleSrcDirs) {
|
|
59434
59556
|
const dirPath = path47.join(workingDir, dir);
|
|
59435
|
-
if (
|
|
59557
|
+
if (fs35.existsSync(dirPath)) {
|
|
59436
59558
|
await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
59437
59559
|
codeLines += lines;
|
|
59438
59560
|
});
|
|
59439
59561
|
}
|
|
59440
59562
|
}
|
|
59441
59563
|
const testsDir = path47.join(workingDir, "tests");
|
|
59442
|
-
if (
|
|
59564
|
+
if (fs35.existsSync(testsDir)) {
|
|
59443
59565
|
await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
59444
59566
|
testLines += lines;
|
|
59445
59567
|
});
|
|
@@ -59447,7 +59569,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
59447
59569
|
const possibleTestDirs = ["test", "__tests__", "specs"];
|
|
59448
59570
|
for (const dir of possibleTestDirs) {
|
|
59449
59571
|
const dirPath = path47.join(workingDir, dir);
|
|
59450
|
-
if (
|
|
59572
|
+
if (fs35.existsSync(dirPath) && dirPath !== testsDir) {
|
|
59451
59573
|
await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
59452
59574
|
testLines += lines;
|
|
59453
59575
|
});
|
|
@@ -59459,7 +59581,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
59459
59581
|
}
|
|
59460
59582
|
async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTestScan, callback) {
|
|
59461
59583
|
try {
|
|
59462
|
-
const entries =
|
|
59584
|
+
const entries = fs35.readdirSync(dirPath, { withFileTypes: true });
|
|
59463
59585
|
for (const entry of entries) {
|
|
59464
59586
|
const fullPath = path47.join(dirPath, entry.name);
|
|
59465
59587
|
if (entry.isDirectory()) {
|
|
@@ -59505,7 +59627,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
59505
59627
|
continue;
|
|
59506
59628
|
}
|
|
59507
59629
|
try {
|
|
59508
|
-
const content =
|
|
59630
|
+
const content = fs35.readFileSync(fullPath, "utf-8");
|
|
59509
59631
|
const lines = countCodeLines(content);
|
|
59510
59632
|
callback(lines);
|
|
59511
59633
|
} catch {}
|
|
@@ -59719,7 +59841,7 @@ async function qualityBudget(input, directory) {
|
|
|
59719
59841
|
init_dist();
|
|
59720
59842
|
init_manager();
|
|
59721
59843
|
init_detector();
|
|
59722
|
-
import * as
|
|
59844
|
+
import * as fs36 from "fs";
|
|
59723
59845
|
import * as path48 from "path";
|
|
59724
59846
|
import { extname as extname9 } from "path";
|
|
59725
59847
|
|
|
@@ -60587,17 +60709,17 @@ var SEVERITY_ORDER = {
|
|
|
60587
60709
|
};
|
|
60588
60710
|
function shouldSkipFile(filePath) {
|
|
60589
60711
|
try {
|
|
60590
|
-
const stats =
|
|
60712
|
+
const stats = fs36.statSync(filePath);
|
|
60591
60713
|
if (stats.size > MAX_FILE_SIZE_BYTES6) {
|
|
60592
60714
|
return { skip: true, reason: "file too large" };
|
|
60593
60715
|
}
|
|
60594
60716
|
if (stats.size === 0) {
|
|
60595
60717
|
return { skip: true, reason: "empty file" };
|
|
60596
60718
|
}
|
|
60597
|
-
const fd =
|
|
60719
|
+
const fd = fs36.openSync(filePath, "r");
|
|
60598
60720
|
const buffer = Buffer.alloc(8192);
|
|
60599
|
-
const bytesRead =
|
|
60600
|
-
|
|
60721
|
+
const bytesRead = fs36.readSync(fd, buffer, 0, 8192, 0);
|
|
60722
|
+
fs36.closeSync(fd);
|
|
60601
60723
|
if (bytesRead > 0) {
|
|
60602
60724
|
let nullCount = 0;
|
|
60603
60725
|
for (let i2 = 0;i2 < bytesRead; i2++) {
|
|
@@ -60636,7 +60758,7 @@ function countBySeverity(findings) {
|
|
|
60636
60758
|
}
|
|
60637
60759
|
function scanFileWithTierA(filePath, language) {
|
|
60638
60760
|
try {
|
|
60639
|
-
const content =
|
|
60761
|
+
const content = fs36.readFileSync(filePath, "utf-8");
|
|
60640
60762
|
const findings = executeRulesSync(filePath, content, language);
|
|
60641
60763
|
return findings.map((f) => ({
|
|
60642
60764
|
rule_id: f.rule_id,
|
|
@@ -60684,7 +60806,7 @@ async function sastScan(input, directory, config3) {
|
|
|
60684
60806
|
continue;
|
|
60685
60807
|
}
|
|
60686
60808
|
const resolvedPath = path48.isAbsolute(filePath) ? filePath : path48.resolve(directory, filePath);
|
|
60687
|
-
if (!
|
|
60809
|
+
if (!fs36.existsSync(resolvedPath)) {
|
|
60688
60810
|
_filesSkipped++;
|
|
60689
60811
|
continue;
|
|
60690
60812
|
}
|
|
@@ -61143,7 +61265,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
61143
61265
|
}
|
|
61144
61266
|
let stat2;
|
|
61145
61267
|
try {
|
|
61146
|
-
stat2 =
|
|
61268
|
+
stat2 = fs37.statSync(file3);
|
|
61147
61269
|
} catch {
|
|
61148
61270
|
skippedFiles++;
|
|
61149
61271
|
continue;
|
|
@@ -61154,7 +61276,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
61154
61276
|
}
|
|
61155
61277
|
let content;
|
|
61156
61278
|
try {
|
|
61157
|
-
const buffer =
|
|
61279
|
+
const buffer = fs37.readFileSync(file3);
|
|
61158
61280
|
if (buffer.includes(0)) {
|
|
61159
61281
|
skippedFiles++;
|
|
61160
61282
|
continue;
|
|
@@ -61554,7 +61676,7 @@ ${paginatedContent}`;
|
|
|
61554
61676
|
init_tool();
|
|
61555
61677
|
init_manager2();
|
|
61556
61678
|
init_create_tool();
|
|
61557
|
-
import * as
|
|
61679
|
+
import * as fs38 from "fs";
|
|
61558
61680
|
import * as path50 from "path";
|
|
61559
61681
|
function detectPlaceholderContent(args2) {
|
|
61560
61682
|
const issues = [];
|
|
@@ -61666,7 +61788,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
61666
61788
|
phases_count: plan.phases.length,
|
|
61667
61789
|
tasks_count: tasksCount
|
|
61668
61790
|
});
|
|
61669
|
-
await
|
|
61791
|
+
await fs38.promises.writeFile(markerPath, marker, "utf8");
|
|
61670
61792
|
} catch {}
|
|
61671
61793
|
return {
|
|
61672
61794
|
success: true,
|
|
@@ -61709,7 +61831,7 @@ var save_plan = createSwarmTool({
|
|
|
61709
61831
|
// src/tools/sbom-generate.ts
|
|
61710
61832
|
init_dist();
|
|
61711
61833
|
init_manager();
|
|
61712
|
-
import * as
|
|
61834
|
+
import * as fs39 from "fs";
|
|
61713
61835
|
import * as path51 from "path";
|
|
61714
61836
|
|
|
61715
61837
|
// src/sbom/detectors/index.ts
|
|
@@ -62556,7 +62678,7 @@ function findManifestFiles(rootDir) {
|
|
|
62556
62678
|
const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
|
|
62557
62679
|
function searchDir(dir) {
|
|
62558
62680
|
try {
|
|
62559
|
-
const entries =
|
|
62681
|
+
const entries = fs39.readdirSync(dir, { withFileTypes: true });
|
|
62560
62682
|
for (const entry of entries) {
|
|
62561
62683
|
const fullPath = path51.join(dir, entry.name);
|
|
62562
62684
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
|
|
@@ -62583,7 +62705,7 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
62583
62705
|
const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
|
|
62584
62706
|
for (const dir of directories) {
|
|
62585
62707
|
try {
|
|
62586
|
-
const entries =
|
|
62708
|
+
const entries = fs39.readdirSync(dir, { withFileTypes: true });
|
|
62587
62709
|
for (const entry of entries) {
|
|
62588
62710
|
const fullPath = path51.join(dir, entry.name);
|
|
62589
62711
|
if (entry.isFile()) {
|
|
@@ -62620,7 +62742,7 @@ function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
|
62620
62742
|
}
|
|
62621
62743
|
function ensureOutputDir(outputDir) {
|
|
62622
62744
|
try {
|
|
62623
|
-
|
|
62745
|
+
fs39.mkdirSync(outputDir, { recursive: true });
|
|
62624
62746
|
} catch (error93) {
|
|
62625
62747
|
if (!error93 || error93.code !== "EEXIST") {
|
|
62626
62748
|
throw error93;
|
|
@@ -62714,10 +62836,10 @@ var sbom_generate = createSwarmTool({
|
|
|
62714
62836
|
for (const manifestFile of manifestFiles) {
|
|
62715
62837
|
try {
|
|
62716
62838
|
const fullPath = path51.isAbsolute(manifestFile) ? manifestFile : path51.join(workingDir, manifestFile);
|
|
62717
|
-
if (!
|
|
62839
|
+
if (!fs39.existsSync(fullPath)) {
|
|
62718
62840
|
continue;
|
|
62719
62841
|
}
|
|
62720
|
-
const content =
|
|
62842
|
+
const content = fs39.readFileSync(fullPath, "utf-8");
|
|
62721
62843
|
const components = detectComponents(manifestFile, content);
|
|
62722
62844
|
processedFiles.push(manifestFile);
|
|
62723
62845
|
if (components.length > 0) {
|
|
@@ -62731,7 +62853,7 @@ var sbom_generate = createSwarmTool({
|
|
|
62731
62853
|
const bomJson = serializeCycloneDX(bom);
|
|
62732
62854
|
const filename = generateSbomFilename();
|
|
62733
62855
|
const outputPath = path51.join(outputDir, filename);
|
|
62734
|
-
|
|
62856
|
+
fs39.writeFileSync(outputPath, bomJson, "utf-8");
|
|
62735
62857
|
const verdict = processedFiles.length > 0 ? "pass" : "pass";
|
|
62736
62858
|
try {
|
|
62737
62859
|
const timestamp = new Date().toISOString();
|
|
@@ -62773,7 +62895,7 @@ var sbom_generate = createSwarmTool({
|
|
|
62773
62895
|
// src/tools/schema-drift.ts
|
|
62774
62896
|
init_dist();
|
|
62775
62897
|
init_create_tool();
|
|
62776
|
-
import * as
|
|
62898
|
+
import * as fs40 from "fs";
|
|
62777
62899
|
import * as path52 from "path";
|
|
62778
62900
|
var SPEC_CANDIDATES = [
|
|
62779
62901
|
"openapi.json",
|
|
@@ -62815,19 +62937,19 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
62815
62937
|
if (!ALLOWED_EXTENSIONS.includes(ext)) {
|
|
62816
62938
|
throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
|
|
62817
62939
|
}
|
|
62818
|
-
const stats =
|
|
62940
|
+
const stats = fs40.statSync(resolvedPath);
|
|
62819
62941
|
if (stats.size > MAX_SPEC_SIZE) {
|
|
62820
62942
|
throw new Error(`Invalid spec_file: file exceeds ${MAX_SPEC_SIZE / 1024 / 1024}MB limit`);
|
|
62821
62943
|
}
|
|
62822
|
-
if (!
|
|
62944
|
+
if (!fs40.existsSync(resolvedPath)) {
|
|
62823
62945
|
throw new Error(`Spec file not found: ${resolvedPath}`);
|
|
62824
62946
|
}
|
|
62825
62947
|
return resolvedPath;
|
|
62826
62948
|
}
|
|
62827
62949
|
for (const candidate of SPEC_CANDIDATES) {
|
|
62828
62950
|
const candidatePath = path52.resolve(cwd, candidate);
|
|
62829
|
-
if (
|
|
62830
|
-
const stats =
|
|
62951
|
+
if (fs40.existsSync(candidatePath)) {
|
|
62952
|
+
const stats = fs40.statSync(candidatePath);
|
|
62831
62953
|
if (stats.size <= MAX_SPEC_SIZE) {
|
|
62832
62954
|
return candidatePath;
|
|
62833
62955
|
}
|
|
@@ -62836,7 +62958,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
62836
62958
|
return null;
|
|
62837
62959
|
}
|
|
62838
62960
|
function parseSpec(specFile) {
|
|
62839
|
-
const content =
|
|
62961
|
+
const content = fs40.readFileSync(specFile, "utf-8");
|
|
62840
62962
|
const ext = path52.extname(specFile).toLowerCase();
|
|
62841
62963
|
if (ext === ".json") {
|
|
62842
62964
|
return parseJsonSpec(content);
|
|
@@ -62908,7 +63030,7 @@ function extractRoutes(cwd) {
|
|
|
62908
63030
|
function walkDir(dir) {
|
|
62909
63031
|
let entries;
|
|
62910
63032
|
try {
|
|
62911
|
-
entries =
|
|
63033
|
+
entries = fs40.readdirSync(dir, { withFileTypes: true });
|
|
62912
63034
|
} catch {
|
|
62913
63035
|
return;
|
|
62914
63036
|
}
|
|
@@ -62941,7 +63063,7 @@ function extractRoutes(cwd) {
|
|
|
62941
63063
|
}
|
|
62942
63064
|
function extractRoutesFromFile(filePath) {
|
|
62943
63065
|
const routes = [];
|
|
62944
|
-
const content =
|
|
63066
|
+
const content = fs40.readFileSync(filePath, "utf-8");
|
|
62945
63067
|
const lines = content.split(/\r?\n/);
|
|
62946
63068
|
const expressRegex = /(?:app|router|server|express)\.(get|post|put|patch|delete|options|head)\s*\(\s*['"`]([^'"`]+)['"`]/g;
|
|
62947
63069
|
const flaskRegex = /@(?:app|blueprint|bp)\.route\s*\(\s*['"]([^'"]+)['"]/g;
|
|
@@ -63092,7 +63214,7 @@ init_secretscan();
|
|
|
63092
63214
|
// src/tools/symbols.ts
|
|
63093
63215
|
init_tool();
|
|
63094
63216
|
init_create_tool();
|
|
63095
|
-
import * as
|
|
63217
|
+
import * as fs41 from "fs";
|
|
63096
63218
|
import * as path53 from "path";
|
|
63097
63219
|
var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
|
|
63098
63220
|
var WINDOWS_RESERVED_NAMES = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
@@ -63123,8 +63245,8 @@ function containsWindowsAttacks(str) {
|
|
|
63123
63245
|
function isPathInWorkspace(filePath, workspace) {
|
|
63124
63246
|
try {
|
|
63125
63247
|
const resolvedPath = path53.resolve(workspace, filePath);
|
|
63126
|
-
const realWorkspace =
|
|
63127
|
-
const realResolvedPath =
|
|
63248
|
+
const realWorkspace = fs41.realpathSync(workspace);
|
|
63249
|
+
const realResolvedPath = fs41.realpathSync(resolvedPath);
|
|
63128
63250
|
const relativePath = path53.relative(realWorkspace, realResolvedPath);
|
|
63129
63251
|
if (relativePath.startsWith("..") || path53.isAbsolute(relativePath)) {
|
|
63130
63252
|
return false;
|
|
@@ -63144,11 +63266,11 @@ function extractTSSymbols(filePath, cwd) {
|
|
|
63144
63266
|
}
|
|
63145
63267
|
let content;
|
|
63146
63268
|
try {
|
|
63147
|
-
const stats =
|
|
63269
|
+
const stats = fs41.statSync(fullPath);
|
|
63148
63270
|
if (stats.size > MAX_FILE_SIZE_BYTES7) {
|
|
63149
63271
|
throw new Error(`File too large: ${stats.size} bytes (max: ${MAX_FILE_SIZE_BYTES7})`);
|
|
63150
63272
|
}
|
|
63151
|
-
content =
|
|
63273
|
+
content = fs41.readFileSync(fullPath, "utf-8");
|
|
63152
63274
|
} catch {
|
|
63153
63275
|
return [];
|
|
63154
63276
|
}
|
|
@@ -63296,11 +63418,11 @@ function extractPythonSymbols(filePath, cwd) {
|
|
|
63296
63418
|
}
|
|
63297
63419
|
let content;
|
|
63298
63420
|
try {
|
|
63299
|
-
const stats =
|
|
63421
|
+
const stats = fs41.statSync(fullPath);
|
|
63300
63422
|
if (stats.size > MAX_FILE_SIZE_BYTES7) {
|
|
63301
63423
|
throw new Error(`File too large: ${stats.size} bytes (max: ${MAX_FILE_SIZE_BYTES7})`);
|
|
63302
63424
|
}
|
|
63303
|
-
content =
|
|
63425
|
+
content = fs41.readFileSync(fullPath, "utf-8");
|
|
63304
63426
|
} catch {
|
|
63305
63427
|
return [];
|
|
63306
63428
|
}
|
|
@@ -63444,7 +63566,7 @@ init_test_runner();
|
|
|
63444
63566
|
init_dist();
|
|
63445
63567
|
init_utils();
|
|
63446
63568
|
init_create_tool();
|
|
63447
|
-
import * as
|
|
63569
|
+
import * as fs42 from "fs";
|
|
63448
63570
|
import * as path54 from "path";
|
|
63449
63571
|
var MAX_TEXT_LENGTH = 200;
|
|
63450
63572
|
var MAX_FILE_SIZE_BYTES8 = 1024 * 1024;
|
|
@@ -63540,7 +63662,7 @@ function isSupportedExtension(filePath) {
|
|
|
63540
63662
|
function findSourceFiles2(dir, files = []) {
|
|
63541
63663
|
let entries;
|
|
63542
63664
|
try {
|
|
63543
|
-
entries =
|
|
63665
|
+
entries = fs42.readdirSync(dir);
|
|
63544
63666
|
} catch {
|
|
63545
63667
|
return files;
|
|
63546
63668
|
}
|
|
@@ -63552,7 +63674,7 @@ function findSourceFiles2(dir, files = []) {
|
|
|
63552
63674
|
const fullPath = path54.join(dir, entry);
|
|
63553
63675
|
let stat2;
|
|
63554
63676
|
try {
|
|
63555
|
-
stat2 =
|
|
63677
|
+
stat2 = fs42.statSync(fullPath);
|
|
63556
63678
|
} catch {
|
|
63557
63679
|
continue;
|
|
63558
63680
|
}
|
|
@@ -63645,7 +63767,7 @@ var todo_extract = createSwarmTool({
|
|
|
63645
63767
|
return JSON.stringify(errorResult, null, 2);
|
|
63646
63768
|
}
|
|
63647
63769
|
const scanPath = resolvedPath;
|
|
63648
|
-
if (!
|
|
63770
|
+
if (!fs42.existsSync(scanPath)) {
|
|
63649
63771
|
const errorResult = {
|
|
63650
63772
|
error: `path not found: ${pathsInput}`,
|
|
63651
63773
|
total: 0,
|
|
@@ -63655,7 +63777,7 @@ var todo_extract = createSwarmTool({
|
|
|
63655
63777
|
return JSON.stringify(errorResult, null, 2);
|
|
63656
63778
|
}
|
|
63657
63779
|
const filesToScan = [];
|
|
63658
|
-
const stat2 =
|
|
63780
|
+
const stat2 = fs42.statSync(scanPath);
|
|
63659
63781
|
if (stat2.isFile()) {
|
|
63660
63782
|
if (isSupportedExtension(scanPath)) {
|
|
63661
63783
|
filesToScan.push(scanPath);
|
|
@@ -63674,11 +63796,11 @@ var todo_extract = createSwarmTool({
|
|
|
63674
63796
|
const allEntries = [];
|
|
63675
63797
|
for (const filePath of filesToScan) {
|
|
63676
63798
|
try {
|
|
63677
|
-
const fileStat =
|
|
63799
|
+
const fileStat = fs42.statSync(filePath);
|
|
63678
63800
|
if (fileStat.size > MAX_FILE_SIZE_BYTES8) {
|
|
63679
63801
|
continue;
|
|
63680
63802
|
}
|
|
63681
|
-
const content =
|
|
63803
|
+
const content = fs42.readFileSync(filePath, "utf-8");
|
|
63682
63804
|
const entries = parseTodoComments(content, filePath, tagsSet);
|
|
63683
63805
|
allEntries.push(...entries);
|
|
63684
63806
|
} catch {}
|
|
@@ -63706,18 +63828,18 @@ var todo_extract = createSwarmTool({
|
|
|
63706
63828
|
// src/tools/update-task-status.ts
|
|
63707
63829
|
init_tool();
|
|
63708
63830
|
init_schema();
|
|
63709
|
-
import * as
|
|
63831
|
+
import * as fs44 from "fs";
|
|
63710
63832
|
import * as path56 from "path";
|
|
63711
63833
|
|
|
63712
63834
|
// src/hooks/diff-scope.ts
|
|
63713
|
-
import * as
|
|
63835
|
+
import * as fs43 from "fs";
|
|
63714
63836
|
import * as path55 from "path";
|
|
63715
63837
|
function getDeclaredScope(taskId, directory) {
|
|
63716
63838
|
try {
|
|
63717
63839
|
const planPath = path55.join(directory, ".swarm", "plan.json");
|
|
63718
|
-
if (!
|
|
63840
|
+
if (!fs43.existsSync(planPath))
|
|
63719
63841
|
return null;
|
|
63720
|
-
const raw =
|
|
63842
|
+
const raw = fs43.readFileSync(planPath, "utf-8");
|
|
63721
63843
|
const plan = JSON.parse(raw);
|
|
63722
63844
|
for (const phase of plan.phases ?? []) {
|
|
63723
63845
|
for (const task of phase.tasks ?? []) {
|
|
@@ -63852,7 +63974,7 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
63852
63974
|
const resolvedDir2 = workingDirectory;
|
|
63853
63975
|
try {
|
|
63854
63976
|
const planPath = path56.join(resolvedDir2, ".swarm", "plan.json");
|
|
63855
|
-
const planRaw =
|
|
63977
|
+
const planRaw = fs44.readFileSync(planPath, "utf-8");
|
|
63856
63978
|
const plan = JSON.parse(planRaw);
|
|
63857
63979
|
for (const planPhase of plan.phases ?? []) {
|
|
63858
63980
|
for (const task of planPhase.tasks ?? []) {
|
|
@@ -63872,7 +63994,7 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
63872
63994
|
const resolvedDir = workingDirectory;
|
|
63873
63995
|
try {
|
|
63874
63996
|
const evidencePath = path56.join(resolvedDir, ".swarm", "evidence", `${taskId}.json`);
|
|
63875
|
-
const raw =
|
|
63997
|
+
const raw = fs44.readFileSync(evidencePath, "utf-8");
|
|
63876
63998
|
const evidence = JSON.parse(raw);
|
|
63877
63999
|
if (evidence?.required_gates && Array.isArray(evidence.required_gates) && evidence?.gates) {
|
|
63878
64000
|
const allGatesMet = evidence.required_gates.every((gate) => evidence.gates[gate] != null);
|
|
@@ -63913,7 +64035,7 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
63913
64035
|
try {
|
|
63914
64036
|
const resolvedDir2 = workingDirectory;
|
|
63915
64037
|
const planPath = path56.join(resolvedDir2, ".swarm", "plan.json");
|
|
63916
|
-
const planRaw =
|
|
64038
|
+
const planRaw = fs44.readFileSync(planPath, "utf-8");
|
|
63917
64039
|
const plan = JSON.parse(planRaw);
|
|
63918
64040
|
for (const planPhase of plan.phases ?? []) {
|
|
63919
64041
|
for (const task of planPhase.tasks ?? []) {
|
|
@@ -64107,9 +64229,9 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
64107
64229
|
}
|
|
64108
64230
|
const resolvedDir = path56.resolve(normalizedDir);
|
|
64109
64231
|
try {
|
|
64110
|
-
const realPath =
|
|
64232
|
+
const realPath = fs44.realpathSync(resolvedDir);
|
|
64111
64233
|
const planPath = path56.join(realPath, ".swarm", "plan.json");
|
|
64112
|
-
if (!
|
|
64234
|
+
if (!fs44.existsSync(planPath)) {
|
|
64113
64235
|
return {
|
|
64114
64236
|
success: false,
|
|
64115
64237
|
message: `Invalid working_directory: plan not found in "${realPath}"`,
|
|
@@ -64623,6 +64745,7 @@ var OpenCodeSwarm = async (ctx) => {
|
|
|
64623
64745
|
await safeHook(activityHooks.toolBefore)(input, output);
|
|
64624
64746
|
},
|
|
64625
64747
|
"tool.execute.after": async (input, output) => {
|
|
64748
|
+
console.debug("[hook-chain] toolAfter start sessionID=%s agent=%s tool=%s", input.sessionID, input.agent, input.tool?.name);
|
|
64626
64749
|
await activityHooks.toolAfter(input, output);
|
|
64627
64750
|
await guardrailsHooks.toolAfter(input, output);
|
|
64628
64751
|
await safeHook(delegationLedgerHook.toolAfter)(input, output);
|
|
@@ -64637,12 +64760,15 @@ var OpenCodeSwarm = async (ctx) => {
|
|
|
64637
64760
|
await safeHook(darkMatterDetectorHook)(input, output);
|
|
64638
64761
|
await snapshotWriterHook(input, output);
|
|
64639
64762
|
await toolSummarizerHook?.(input, output);
|
|
64640
|
-
|
|
64641
|
-
|
|
64642
|
-
|
|
64643
|
-
|
|
64644
|
-
|
|
64645
|
-
|
|
64763
|
+
const execMode = config3.execution_mode ?? "balanced";
|
|
64764
|
+
if (execMode === "strict") {
|
|
64765
|
+
if (slopDetectorHook)
|
|
64766
|
+
await slopDetectorHook.toolAfter(input, output);
|
|
64767
|
+
if (incrementalVerifyHook)
|
|
64768
|
+
await incrementalVerifyHook.toolAfter(input, output);
|
|
64769
|
+
if (compactionServiceHook)
|
|
64770
|
+
await compactionServiceHook.toolAfter(input, output);
|
|
64771
|
+
}
|
|
64646
64772
|
const toolOutputConfig = config3.tool_output;
|
|
64647
64773
|
if (toolOutputConfig && toolOutputConfig.truncation_enabled !== false && typeof output.output === "string") {
|
|
64648
64774
|
const defaultTruncatableTools = new Set([
|
|
@@ -64676,8 +64802,12 @@ var OpenCodeSwarm = async (ctx) => {
|
|
|
64676
64802
|
session.lastAgentEventTime = Date.now();
|
|
64677
64803
|
}
|
|
64678
64804
|
}
|
|
64805
|
+
deleteStoredInputArgs(input.callID);
|
|
64679
64806
|
},
|
|
64680
|
-
"chat.message": safeHook(
|
|
64807
|
+
"chat.message": safeHook(async (input, output) => {
|
|
64808
|
+
console.debug("[session] chat.message sessionID=%s agent=%s", input.sessionID, input.agent);
|
|
64809
|
+
await delegationHandler(input, output);
|
|
64810
|
+
}),
|
|
64681
64811
|
automation: automationManager
|
|
64682
64812
|
};
|
|
64683
64813
|
};
|