opencode-swarm 6.22.15 → 6.22.17

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.
@@ -31,7 +31,7 @@ interface MessageWithParts {
31
31
  * Creates the experimental.chat.messages.transform hook for pipeline tracking.
32
32
  * Only injects for the architect agent.
33
33
  */
34
- export declare function createPipelineTrackerHook(config: PluginConfig): {
34
+ export declare function createPipelineTrackerHook(config: PluginConfig, directory?: string): {
35
35
  'experimental.chat.messages.transform'?: undefined;
36
36
  } | {
37
37
  'experimental.chat.messages.transform': (input: Record<string, never>, output: {
package/dist/index.js CHANGED
@@ -46323,7 +46323,12 @@ async function handleRollbackCommand(directory, args2) {
46323
46323
  if (!fs13.existsSync(manifestPath2)) {
46324
46324
  return "No checkpoints found. Use `/swarm checkpoint` to create checkpoints.";
46325
46325
  }
46326
- const manifest2 = JSON.parse(fs13.readFileSync(manifestPath2, "utf-8"));
46326
+ let manifest2;
46327
+ try {
46328
+ manifest2 = JSON.parse(fs13.readFileSync(manifestPath2, "utf-8"));
46329
+ } catch {
46330
+ return "Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.";
46331
+ }
46327
46332
  const checkpoints = manifest2.checkpoints || [];
46328
46333
  if (checkpoints.length === 0) {
46329
46334
  return "No checkpoints found in manifest.";
@@ -46345,7 +46350,12 @@ async function handleRollbackCommand(directory, args2) {
46345
46350
  if (!fs13.existsSync(manifestPath)) {
46346
46351
  return `Error: No checkpoints found. Cannot rollback to phase ${targetPhase}.`;
46347
46352
  }
46348
- const manifest = JSON.parse(fs13.readFileSync(manifestPath, "utf-8"));
46353
+ let manifest;
46354
+ try {
46355
+ manifest = JSON.parse(fs13.readFileSync(manifestPath, "utf-8"));
46356
+ } catch {
46357
+ return `Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.`;
46358
+ }
46349
46359
  const checkpoint = manifest.checkpoints?.find((c) => c.phase === targetPhase);
46350
46360
  if (!checkpoint) {
46351
46361
  const available = manifest.checkpoints?.map((c) => c.phase).join(", ") || "none";
@@ -49247,7 +49257,7 @@ ${phaseNumber !== null && phaseNumber >= 4 ? `
49247
49257
  \u26A0\uFE0F You are in Phase ${phaseNumber}. Compliance degrades with time. Do not skip reviewer or test_engineer.` : ""}
49248
49258
  </swarm_reminder>`;
49249
49259
  }
49250
- function createPipelineTrackerHook(config3) {
49260
+ function createPipelineTrackerHook(config3, directory) {
49251
49261
  const enabled = config3.inject_phase_reminders !== false;
49252
49262
  if (!enabled) {
49253
49263
  return {};
@@ -49277,7 +49287,7 @@ function createPipelineTrackerHook(config3) {
49277
49287
  return;
49278
49288
  let phaseNumber = null;
49279
49289
  try {
49280
- const plan = await loadPlan(process.cwd());
49290
+ const plan = await loadPlan(directory ?? process.cwd());
49281
49291
  if (plan) {
49282
49292
  const phaseString = extractCurrentPhaseFromPlan2(plan);
49283
49293
  phaseNumber = parsePhaseNumber(phaseString);
@@ -53873,7 +53883,12 @@ async function fetchGitingest(args2) {
53873
53883
  if (Buffer.byteLength(text) > GITINGEST_MAX_RESPONSE_BYTES) {
53874
53884
  throw new Error("gitingest response too large");
53875
53885
  }
53876
- const data = JSON.parse(text);
53886
+ let data;
53887
+ try {
53888
+ data = JSON.parse(text);
53889
+ } catch {
53890
+ throw new Error(`gitingest API returned non-JSON response (${text.length} chars, starts: ${text.slice(0, 80)})`);
53891
+ }
53877
53892
  return `${data.summary}
53878
53893
 
53879
53894
  ${data.tree}
@@ -59687,7 +59702,6 @@ init_create_tool();
59687
59702
  var DEFAULT_OUTPUT_DIR = ".swarm/evidence/sbom";
59688
59703
  function findManifestFiles(rootDir) {
59689
59704
  const manifestFiles = [];
59690
- const cwd = process.cwd();
59691
59705
  const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
59692
59706
  function searchDir(dir) {
59693
59707
  try {
@@ -59703,7 +59717,7 @@ function findManifestFiles(rootDir) {
59703
59717
  for (const pattern of patterns) {
59704
59718
  const regex = pattern.replace(/\./g, "\\.").replace(/\*/g, ".*").replace(/\?/g, ".");
59705
59719
  if (new RegExp(regex, "i").test(entry.name)) {
59706
- manifestFiles.push(path43.relative(cwd, fullPath));
59720
+ manifestFiles.push(path43.relative(rootDir, fullPath));
59707
59721
  break;
59708
59722
  }
59709
59723
  }
@@ -59716,7 +59730,6 @@ function findManifestFiles(rootDir) {
59716
59730
  }
59717
59731
  function findManifestFilesInDirs(directories, workingDir) {
59718
59732
  const found = [];
59719
- const _cwd = process.cwd();
59720
59733
  const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
59721
59734
  for (const dir of directories) {
59722
59735
  try {
@@ -59826,8 +59839,9 @@ var sbom_generate = createSwarmTool({
59826
59839
  const obj = args2;
59827
59840
  const scope = obj.scope;
59828
59841
  const changedFiles = obj.changed_files;
59829
- const outputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
59842
+ const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
59830
59843
  const workingDir = directory;
59844
+ const outputDir = path43.isAbsolute(relativeOutputDir) ? relativeOutputDir : path43.join(workingDir, relativeOutputDir);
59831
59845
  let manifestFiles = [];
59832
59846
  if (scope === "all") {
59833
59847
  manifestFiles = findManifestFiles(workingDir);
@@ -59981,7 +59995,12 @@ function parseSpec(specFile) {
59981
59995
  return parseYamlSpec(content);
59982
59996
  }
59983
59997
  function parseJsonSpec(content) {
59984
- const spec = JSON.parse(content);
59998
+ let spec;
59999
+ try {
60000
+ spec = JSON.parse(content);
60001
+ } catch {
60002
+ return [];
60003
+ }
59985
60004
  const paths = [];
59986
60005
  if (!spec.paths) {
59987
60006
  return paths;
@@ -61063,7 +61082,7 @@ var OpenCodeSwarm = async (ctx) => {
61063
61082
  await loadSnapshot(ctx.directory);
61064
61083
  const agents = getAgentConfigs(config3);
61065
61084
  const agentDefinitions = createAgents(config3);
61066
- const pipelineHook = createPipelineTrackerHook(config3);
61085
+ const pipelineHook = createPipelineTrackerHook(config3, ctx.directory);
61067
61086
  const systemEnhancerHook = createSystemEnhancerHook(config3, ctx.directory);
61068
61087
  const compactionHook = createCompactionCustomizerHook(config3, ctx.directory);
61069
61088
  const contextBudgetHandler = createContextBudgetHandler(config3);
package/dist/state.d.ts CHANGED
@@ -177,6 +177,9 @@ export declare function resetSwarmState(): void;
177
177
  export declare function startAgentSession(sessionId: string, agentName: string, staleDurationMs?: number): void;
178
178
  /**
179
179
  * End an agent session by removing it from the state.
180
+ * NOTE: Currently unused in production — no session lifecycle teardown is wired up.
181
+ * Sessions accumulate for the process lifetime. Callers should integrate this into
182
+ * a session TTL or idle-timeout mechanism to prevent unbounded Map growth.
180
183
  * @param sessionId - The session identifier to remove
181
184
  */
182
185
  export declare function endAgentSession(sessionId: string): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "6.22.15",
3
+ "version": "6.22.17",
4
4
  "description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",