opencode-swarm-plugin 0.46.0 → 0.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/swarm.js CHANGED
@@ -1,4 +1,5 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env bun
2
+ // @bun
2
3
  import { createRequire } from "node:module";
3
4
  var __create = Object.create;
4
5
  var __getProtoOf = Object.getPrototypeOf;
@@ -12698,13 +12699,13 @@ __export(exports_eval_capture3, {
12698
12699
  readSessionEvents: () => readSessionEvents3,
12699
12700
  readPartialRecords: () => readPartialRecords3,
12700
12701
  readEvalRecords: () => readEvalRecords3,
12701
- getSessionPath: () => getSessionPath3,
12702
- getSessionDir: () => getSessionDir3,
12702
+ getSessionPath: () => getSessionPath4,
12703
+ getSessionDir: () => getSessionDir4,
12703
12704
  getEvalDataStats: () => getEvalDataStats3,
12704
12705
  getEvalDataPath: () => getEvalDataPath3,
12705
12706
  finalizeEvalRecord: () => finalizeEvalRecord3,
12706
12707
  exportForEvalite: () => exportForEvalite3,
12707
- ensureSessionDir: () => ensureSessionDir3,
12708
+ ensureSessionDir: () => ensureSessionDir4,
12708
12709
  ensureEvalDataDir: () => ensureEvalDataDir3,
12709
12710
  captureSubtaskOutcome: () => captureSubtaskOutcome3,
12710
12711
  captureSkillLoaded: () => captureSkillLoaded3,
@@ -12713,29 +12714,29 @@ __export(exports_eval_capture3, {
12713
12714
  captureInboxChecked: () => captureInboxChecked3,
12714
12715
  captureHumanFeedback: () => captureHumanFeedback3,
12715
12716
  captureDecomposition: () => captureDecomposition3,
12716
- captureCoordinatorEvent: () => captureCoordinatorEvent3,
12717
- captureCompactionEvent: () => captureCompactionEvent3,
12717
+ captureCoordinatorEvent: () => captureCoordinatorEvent4,
12718
+ captureCompactionEvent: () => captureCompactionEvent4,
12718
12719
  captureBlockerResolved: () => captureBlockerResolved3,
12719
12720
  captureBlockerDetected: () => captureBlockerDetected3,
12720
12721
  appendEvalRecord: () => appendEvalRecord3,
12721
- SubtaskOutcomeSchema: () => SubtaskOutcomeSchema3,
12722
- EvalRecordSchema: () => EvalRecordSchema3,
12722
+ SubtaskOutcomeSchema: () => SubtaskOutcomeSchema4,
12723
+ EvalRecordSchema: () => EvalRecordSchema4,
12723
12724
  DEFAULT_EVAL_DATA_PATH: () => DEFAULT_EVAL_DATA_PATH3,
12724
- CoordinatorSessionSchema: () => CoordinatorSessionSchema3,
12725
- CoordinatorEventSchema: () => CoordinatorEventSchema3
12725
+ CoordinatorSessionSchema: () => CoordinatorSessionSchema4,
12726
+ CoordinatorEventSchema: () => CoordinatorEventSchema4
12726
12727
  });
12727
- import * as fs5 from "node:fs";
12728
- import * as os3 from "node:os";
12729
- import * as path6 from "node:path";
12730
- import { getSwarmMailLibSQL as getSwarmMailLibSQL10 } from "swarm-mail";
12728
+ import * as fs8 from "node:fs";
12729
+ import * as os4 from "node:os";
12730
+ import * as path8 from "node:path";
12731
+ import { getSwarmMailLibSQL as getSwarmMailLibSQL11 } from "swarm-mail";
12731
12732
  function getEvalDataPath3(projectPath) {
12732
- return path6.join(projectPath, DEFAULT_EVAL_DATA_PATH3);
12733
+ return path8.join(projectPath, DEFAULT_EVAL_DATA_PATH3);
12733
12734
  }
12734
12735
  function ensureEvalDataDir3(projectPath) {
12735
12736
  const evalPath = getEvalDataPath3(projectPath);
12736
- const dir = path6.dirname(evalPath);
12737
- if (!fs5.existsSync(dir)) {
12738
- fs5.mkdirSync(dir, { recursive: true });
12737
+ const dir = path8.dirname(evalPath);
12738
+ if (!fs8.existsSync(dir)) {
12739
+ fs8.mkdirSync(dir, { recursive: true });
12739
12740
  }
12740
12741
  }
12741
12742
  function appendEvalRecord3(projectPath, record4) {
@@ -12743,27 +12744,27 @@ function appendEvalRecord3(projectPath, record4) {
12743
12744
  const evalPath = getEvalDataPath3(projectPath);
12744
12745
  const line = `${JSON.stringify(record4)}
12745
12746
  `;
12746
- fs5.appendFileSync(evalPath, line, "utf-8");
12747
+ fs8.appendFileSync(evalPath, line, "utf-8");
12747
12748
  }
12748
12749
  function readEvalRecords3(projectPath) {
12749
12750
  const evalPath = getEvalDataPath3(projectPath);
12750
- if (!fs5.existsSync(evalPath)) {
12751
+ if (!fs8.existsSync(evalPath)) {
12751
12752
  return [];
12752
12753
  }
12753
- const content = fs5.readFileSync(evalPath, "utf-8");
12754
+ const content = fs8.readFileSync(evalPath, "utf-8");
12754
12755
  const lines = content.trim().split(`
12755
12756
  `).filter(Boolean);
12756
12757
  return lines.map((line) => {
12757
12758
  const parsed = JSON.parse(line);
12758
- return EvalRecordSchema3.parse(parsed);
12759
+ return EvalRecordSchema4.parse(parsed);
12759
12760
  });
12760
12761
  }
12761
12762
  function readPartialRecords3(projectPath) {
12762
12763
  const evalPath = getEvalDataPath3(projectPath);
12763
- if (!fs5.existsSync(evalPath)) {
12764
+ if (!fs8.existsSync(evalPath)) {
12764
12765
  return [];
12765
12766
  }
12766
- const content = fs5.readFileSync(evalPath, "utf-8");
12767
+ const content = fs8.readFileSync(evalPath, "utf-8");
12767
12768
  const lines = content.trim().split(`
12768
12769
  `).filter(Boolean);
12769
12770
  return lines.map((line) => JSON.parse(line));
@@ -12779,7 +12780,7 @@ function updateEvalRecord3(projectPath, id, updates) {
12779
12780
  const content = `${records.map((r) => JSON.stringify(r)).join(`
12780
12781
  `)}
12781
12782
  `;
12782
- fs5.writeFileSync(evalPath, content, "utf-8");
12783
+ fs8.writeFileSync(evalPath, content, "utf-8");
12783
12784
  return true;
12784
12785
  }
12785
12786
  function captureDecomposition3(params) {
@@ -12796,7 +12797,7 @@ function captureDecomposition3(params) {
12796
12797
  subtasks: params.subtasks,
12797
12798
  outcomes: []
12798
12799
  };
12799
- inProgressRecords3.set(params.epicId, record4);
12800
+ inProgressRecords4.set(params.epicId, record4);
12800
12801
  appendEvalRecord3(params.projectPath, record4);
12801
12802
  return record4;
12802
12803
  }
@@ -12812,7 +12813,7 @@ function captureSubtaskOutcome3(params) {
12812
12813
  success: params.success,
12813
12814
  failure_mode: params.failureMode
12814
12815
  };
12815
- const record4 = inProgressRecords3.get(params.epicId);
12816
+ const record4 = inProgressRecords4.get(params.epicId);
12816
12817
  if (record4) {
12817
12818
  record4.outcomes = record4.outcomes || [];
12818
12819
  record4.outcomes.push(outcome);
@@ -12822,7 +12823,7 @@ function captureSubtaskOutcome3(params) {
12822
12823
  });
12823
12824
  }
12824
12825
  function finalizeEvalRecord3(params) {
12825
- const record4 = inProgressRecords3.get(params.epicId);
12826
+ const record4 = inProgressRecords4.get(params.epicId);
12826
12827
  if (!record4 || !record4.outcomes || record4.outcomes.length === 0) {
12827
12828
  return null;
12828
12829
  }
@@ -12851,7 +12852,7 @@ function finalizeEvalRecord3(params) {
12851
12852
  time_balance_ratio: timeBalanceRatio
12852
12853
  };
12853
12854
  updateEvalRecord3(params.projectPath, params.epicId, finalRecord);
12854
- inProgressRecords3.delete(params.epicId);
12855
+ inProgressRecords4.delete(params.epicId);
12855
12856
  return finalRecord;
12856
12857
  }
12857
12858
  function captureHumanFeedback3(params) {
@@ -12906,23 +12907,23 @@ function getEvalDataStats3(projectPath) {
12906
12907
  avgTimeBalance
12907
12908
  };
12908
12909
  }
12909
- function getSessionDir3() {
12910
- return process.env.SWARM_SESSIONS_DIR || path6.join(os3.homedir(), ".config", "swarm-tools", "sessions");
12910
+ function getSessionDir4() {
12911
+ return process.env.SWARM_SESSIONS_DIR || path8.join(os4.homedir(), ".config", "swarm-tools", "sessions");
12911
12912
  }
12912
- function getSessionPath3(sessionId) {
12913
- return path6.join(getSessionDir3(), `${sessionId}.jsonl`);
12913
+ function getSessionPath4(sessionId) {
12914
+ return path8.join(getSessionDir4(), `${sessionId}.jsonl`);
12914
12915
  }
12915
- function ensureSessionDir3() {
12916
- const sessionDir = getSessionDir3();
12917
- if (!fs5.existsSync(sessionDir)) {
12918
- fs5.mkdirSync(sessionDir, { recursive: true });
12916
+ function ensureSessionDir4() {
12917
+ const sessionDir = getSessionDir4();
12918
+ if (!fs8.existsSync(sessionDir)) {
12919
+ fs8.mkdirSync(sessionDir, { recursive: true });
12919
12920
  }
12920
12921
  }
12921
- async function captureCoordinatorEvent3(event) {
12922
- CoordinatorEventSchema3.parse(event);
12922
+ async function captureCoordinatorEvent4(event) {
12923
+ CoordinatorEventSchema4.parse(event);
12923
12924
  try {
12924
12925
  const projectPath = process.cwd();
12925
- const swarmMail = await getSwarmMailLibSQL10(projectPath);
12926
+ const swarmMail = await getSwarmMailLibSQL11(projectPath);
12926
12927
  const eventType = `coordinator_${event.event_type.toLowerCase()}`;
12927
12928
  const eventData = {
12928
12929
  type: eventType,
@@ -12943,21 +12944,21 @@ async function captureCoordinatorEvent3(event) {
12943
12944
  eventData.compaction_type = event.compaction_type;
12944
12945
  }
12945
12946
  await swarmMail.appendEvent(eventData);
12946
- ensureSessionDir3();
12947
- const sessionPath = getSessionPath3(event.session_id);
12947
+ ensureSessionDir4();
12948
+ const sessionPath = getSessionPath4(event.session_id);
12948
12949
  const line = `${JSON.stringify(event)}
12949
12950
  `;
12950
- fs5.appendFileSync(sessionPath, line, "utf-8");
12951
+ fs8.appendFileSync(sessionPath, line, "utf-8");
12951
12952
  } catch (error54) {
12952
12953
  console.warn("Failed to append event to libSQL, using JSONL fallback:", error54);
12953
- ensureSessionDir3();
12954
- const sessionPath = getSessionPath3(event.session_id);
12954
+ ensureSessionDir4();
12955
+ const sessionPath = getSessionPath4(event.session_id);
12955
12956
  const line = `${JSON.stringify(event)}
12956
12957
  `;
12957
- fs5.appendFileSync(sessionPath, line, "utf-8");
12958
+ fs8.appendFileSync(sessionPath, line, "utf-8");
12958
12959
  }
12959
12960
  }
12960
- async function captureCompactionEvent3(params) {
12961
+ async function captureCompactionEvent4(params) {
12961
12962
  const event = {
12962
12963
  session_id: params.session_id,
12963
12964
  epic_id: params.epic_id,
@@ -12966,7 +12967,7 @@ async function captureCompactionEvent3(params) {
12966
12967
  compaction_type: params.compaction_type,
12967
12968
  payload: params.payload
12968
12969
  };
12969
- await captureCoordinatorEvent3(event);
12970
+ await captureCoordinatorEvent4(event);
12970
12971
  }
12971
12972
  async function captureResearcherSpawned3(params) {
12972
12973
  const event = {
@@ -12981,7 +12982,7 @@ async function captureResearcherSpawned3(params) {
12981
12982
  tools_used: params.tools_used || []
12982
12983
  }
12983
12984
  };
12984
- await captureCoordinatorEvent3(event);
12985
+ await captureCoordinatorEvent4(event);
12985
12986
  }
12986
12987
  async function captureSkillLoaded3(params) {
12987
12988
  const event = {
@@ -12995,7 +12996,7 @@ async function captureSkillLoaded3(params) {
12995
12996
  context: params.context
12996
12997
  }
12997
12998
  };
12998
- await captureCoordinatorEvent3(event);
12999
+ await captureCoordinatorEvent4(event);
12999
13000
  }
13000
13001
  async function captureInboxChecked3(params) {
13001
13002
  const event = {
@@ -13009,7 +13010,7 @@ async function captureInboxChecked3(params) {
13009
13010
  urgent_count: params.urgent_count
13010
13011
  }
13011
13012
  };
13012
- await captureCoordinatorEvent3(event);
13013
+ await captureCoordinatorEvent4(event);
13013
13014
  }
13014
13015
  async function captureBlockerResolved3(params) {
13015
13016
  const event = {
@@ -13025,7 +13026,7 @@ async function captureBlockerResolved3(params) {
13025
13026
  resolution: params.resolution
13026
13027
  }
13027
13028
  };
13028
- await captureCoordinatorEvent3(event);
13029
+ await captureCoordinatorEvent4(event);
13029
13030
  }
13030
13031
  async function captureScopeChangeDecision3(params) {
13031
13032
  const event = {
@@ -13047,7 +13048,7 @@ async function captureScopeChangeDecision3(params) {
13047
13048
  rejection_reason: params.rejection_reason
13048
13049
  }
13049
13050
  };
13050
- await captureCoordinatorEvent3(event);
13051
+ await captureCoordinatorEvent4(event);
13051
13052
  }
13052
13053
  async function captureBlockerDetected3(params) {
13053
13054
  const event = {
@@ -13064,19 +13065,19 @@ async function captureBlockerDetected3(params) {
13064
13065
  reported_at: new Date().toISOString()
13065
13066
  }
13066
13067
  };
13067
- await captureCoordinatorEvent3(event);
13068
+ await captureCoordinatorEvent4(event);
13068
13069
  }
13069
13070
  function readSessionEvents3(sessionId) {
13070
- const sessionPath = getSessionPath3(sessionId);
13071
- if (!fs5.existsSync(sessionPath)) {
13071
+ const sessionPath = getSessionPath4(sessionId);
13072
+ if (!fs8.existsSync(sessionPath)) {
13072
13073
  return [];
13073
13074
  }
13074
- const content = fs5.readFileSync(sessionPath, "utf-8");
13075
+ const content = fs8.readFileSync(sessionPath, "utf-8");
13075
13076
  const lines = content.trim().split(`
13076
13077
  `).filter(Boolean);
13077
13078
  return lines.map((line) => {
13078
13079
  const parsed = JSON.parse(line);
13079
- return CoordinatorEventSchema3.parse(parsed);
13080
+ return CoordinatorEventSchema4.parse(parsed);
13080
13081
  });
13081
13082
  }
13082
13083
  function saveSession3(params) {
@@ -13096,10 +13097,10 @@ function saveSession3(params) {
13096
13097
  };
13097
13098
  return session;
13098
13099
  }
13099
- var SubtaskOutcomeSchema3, EvalRecordSchema3, CoordinatorEventSchema3, CoordinatorSessionSchema3, DEFAULT_EVAL_DATA_PATH3 = ".opencode/eval-data.jsonl", inProgressRecords3;
13100
+ var SubtaskOutcomeSchema4, EvalRecordSchema4, CoordinatorEventSchema4, CoordinatorSessionSchema4, DEFAULT_EVAL_DATA_PATH3 = ".opencode/eval-data.jsonl", inProgressRecords4;
13100
13101
  var init_eval_capture3 = __esm(() => {
13101
13102
  init_zod3();
13102
- SubtaskOutcomeSchema3 = exports_external3.object({
13103
+ SubtaskOutcomeSchema4 = exports_external3.object({
13103
13104
  bead_id: exports_external3.string(),
13104
13105
  title: exports_external3.string(),
13105
13106
  planned_files: exports_external3.array(exports_external3.string()),
@@ -13110,7 +13111,7 @@ var init_eval_capture3 = __esm(() => {
13110
13111
  success: exports_external3.boolean(),
13111
13112
  failure_mode: exports_external3.string().optional()
13112
13113
  });
13113
- EvalRecordSchema3 = exports_external3.object({
13114
+ EvalRecordSchema4 = exports_external3.object({
13114
13115
  id: exports_external3.string(),
13115
13116
  timestamp: exports_external3.string(),
13116
13117
  project_path: exports_external3.string(),
@@ -13127,7 +13128,7 @@ var init_eval_capture3 = __esm(() => {
13127
13128
  dependencies: exports_external3.array(exports_external3.number()).optional(),
13128
13129
  estimated_complexity: exports_external3.number().int().min(1).max(5).optional()
13129
13130
  })),
13130
- outcomes: exports_external3.array(SubtaskOutcomeSchema3).optional(),
13131
+ outcomes: exports_external3.array(SubtaskOutcomeSchema4).optional(),
13131
13132
  overall_success: exports_external3.boolean().optional(),
13132
13133
  total_duration_ms: exports_external3.number().int().min(0).optional(),
13133
13134
  total_errors: exports_external3.number().int().min(0).optional(),
@@ -13138,7 +13139,7 @@ var init_eval_capture3 = __esm(() => {
13138
13139
  scope_accuracy: exports_external3.number().min(0).max(2).optional(),
13139
13140
  time_balance_ratio: exports_external3.number().min(1).optional()
13140
13141
  });
13141
- CoordinatorEventSchema3 = exports_external3.discriminatedUnion("event_type", [
13142
+ CoordinatorEventSchema4 = exports_external3.discriminatedUnion("event_type", [
13142
13143
  exports_external3.object({
13143
13144
  session_id: exports_external3.string(),
13144
13145
  epic_id: exports_external3.string(),
@@ -13201,14 +13202,14 @@ var init_eval_capture3 = __esm(() => {
13201
13202
  payload: exports_external3.any()
13202
13203
  })
13203
13204
  ]);
13204
- CoordinatorSessionSchema3 = exports_external3.object({
13205
+ CoordinatorSessionSchema4 = exports_external3.object({
13205
13206
  session_id: exports_external3.string(),
13206
13207
  epic_id: exports_external3.string(),
13207
13208
  start_time: exports_external3.string(),
13208
13209
  end_time: exports_external3.string().optional(),
13209
- events: exports_external3.array(CoordinatorEventSchema3)
13210
+ events: exports_external3.array(CoordinatorEventSchema4)
13210
13211
  });
13211
- inProgressRecords3 = new Map;
13212
+ inProgressRecords4 = new Map;
13212
13213
  });
13213
13214
 
13214
13215
  // src/swarm-validation.ts
@@ -17161,7 +17162,7 @@ var require_has_flag = __commonJS((exports2, module2) => {
17161
17162
 
17162
17163
  // ../../node_modules/.bun/supports-color@7.2.0/node_modules/supports-color/index.js
17163
17164
  var require_supports_color = __commonJS((exports2, module2) => {
17164
- var os4 = __require("os");
17165
+ var os5 = __require("os");
17165
17166
  var tty = __require("tty");
17166
17167
  var hasFlag = require_has_flag();
17167
17168
  var { env } = process;
@@ -17209,7 +17210,7 @@ var require_supports_color = __commonJS((exports2, module2) => {
17209
17210
  return min;
17210
17211
  }
17211
17212
  if (process.platform === "win32") {
17212
- const osRelease = os4.release().split(".");
17213
+ const osRelease = os5.release().split(".");
17213
17214
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
17214
17215
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
17215
17216
  }
@@ -26790,7 +26791,7 @@ var require_parse2 = __commonJS((exports2, module2) => {
26790
26791
 
26791
26792
  // ../../node_modules/.bun/gray-matter@4.0.3/node_modules/gray-matter/index.js
26792
26793
  var require_gray_matter2 = __commonJS((exports2, module2) => {
26793
- var fs6 = __require("fs");
26794
+ var fs9 = __require("fs");
26794
26795
  var sections = require_section_matter2();
26795
26796
  var defaults2 = require_defaults2();
26796
26797
  var stringify = require_stringify2();
@@ -26877,7 +26878,7 @@ var require_gray_matter2 = __commonJS((exports2, module2) => {
26877
26878
  return stringify(file4, data, options2);
26878
26879
  };
26879
26880
  matter.read = function(filepath, options2) {
26880
- const str2 = fs6.readFileSync(filepath, "utf8");
26881
+ const str2 = fs9.readFileSync(filepath, "utf8");
26881
26882
  const file4 = matter(str2, options2);
26882
26883
  file4.path = filepath;
26883
26884
  return file4;
@@ -26929,20 +26930,20 @@ __export(exports_skills2, {
26929
26930
  });
26930
26931
  import { readdir as readdir2, readFile as readFile2, stat as stat2, mkdir as mkdir2, writeFile as writeFile2, rm as rm2 } from "fs/promises";
26931
26932
  import {
26932
- join as join16,
26933
+ join as join18,
26933
26934
  basename as basename2,
26934
- dirname as dirname6,
26935
+ dirname as dirname8,
26935
26936
  resolve as resolve2,
26936
26937
  relative as relative2,
26937
26938
  isAbsolute as isAbsolute2,
26938
26939
  sep as sep3
26939
26940
  } from "path";
26940
26941
  import { fileURLToPath as fileURLToPath2 } from "url";
26941
- import { getSwarmMailLibSQL as getSwarmMailLibSQL12, createEvent as createEvent7 } from "swarm-mail";
26942
+ import { getSwarmMailLibSQL as getSwarmMailLibSQL13, createEvent as createEvent7 } from "swarm-mail";
26942
26943
  async function emitSkillLoadedEvent2(data) {
26943
26944
  try {
26944
26945
  const projectPath = skillsProjectDirectory2;
26945
- const swarmMail = await getSwarmMailLibSQL12(projectPath);
26946
+ const swarmMail = await getSwarmMailLibSQL13(projectPath);
26946
26947
  const event = createEvent7("skill_loaded", {
26947
26948
  project_key: projectPath,
26948
26949
  skill_name: data.skill_name,
@@ -26956,7 +26957,7 @@ async function emitSkillLoadedEvent2(data) {
26956
26957
  async function emitSkillCreatedEvent2(data) {
26957
26958
  try {
26958
26959
  const projectPath = skillsProjectDirectory2;
26959
- const swarmMail = await getSwarmMailLibSQL12(projectPath);
26960
+ const swarmMail = await getSwarmMailLibSQL13(projectPath);
26960
26961
  const event = createEvent7("skill_created", {
26961
26962
  project_key: projectPath,
26962
26963
  skill_name: data.skill_name,
@@ -27005,19 +27006,19 @@ function validateSkillMetadata2(raw, filePath) {
27005
27006
  }
27006
27007
  function getGlobalSkillsDir2() {
27007
27008
  const home = process.env.HOME || process.env.USERPROFILE || "~";
27008
- return join16(home, ".config", "opencode", "skill");
27009
+ return join18(home, ".config", "opencode", "skill");
27009
27010
  }
27010
27011
  function getClaudeGlobalSkillsDir2() {
27011
27012
  const home = process.env.HOME || process.env.USERPROFILE || "~";
27012
- return join16(home, ".claude", "skills");
27013
+ return join18(home, ".claude", "skills");
27013
27014
  }
27014
27015
  function getPackageSkillsDir2() {
27015
27016
  try {
27016
27017
  const currentFilePath = fileURLToPath2(import.meta.url);
27017
- return join16(dirname6(currentFilePath), "..", "global-skills");
27018
+ return join18(dirname8(currentFilePath), "..", "global-skills");
27018
27019
  } catch {
27019
27020
  const currentDir = decodeURIComponent(new URL(".", import.meta.url).pathname);
27020
- return join16(currentDir, "..", "global-skills");
27021
+ return join18(currentDir, "..", "global-skills");
27021
27022
  }
27022
27023
  }
27023
27024
  async function findSkillFiles2(baseDir) {
@@ -27026,7 +27027,7 @@ async function findSkillFiles2(baseDir) {
27026
27027
  const entries = await readdir2(baseDir, { withFileTypes: true });
27027
27028
  for (const entry of entries) {
27028
27029
  if (entry.isDirectory()) {
27029
- const skillPath = join16(baseDir, entry.name, "SKILL.md");
27030
+ const skillPath = join18(baseDir, entry.name, "SKILL.md");
27030
27031
  try {
27031
27032
  const s = await stat2(skillPath);
27032
27033
  if (s.isFile()) {
@@ -27040,7 +27041,7 @@ async function findSkillFiles2(baseDir) {
27040
27041
  }
27041
27042
  async function findSkillScripts2(skillDir) {
27042
27043
  const scripts = [];
27043
- const scriptsDir = join16(skillDir, "scripts");
27044
+ const scriptsDir = join18(skillDir, "scripts");
27044
27045
  try {
27045
27046
  const entries = await readdir2(scriptsDir, { withFileTypes: true });
27046
27047
  for (const entry of entries) {
@@ -27055,7 +27056,7 @@ async function loadSkill2(skillPath) {
27055
27056
  const content = await readFile2(skillPath, "utf-8");
27056
27057
  const { metadata: rawMetadata, body } = parseFrontmatter2(content);
27057
27058
  const metadata = validateSkillMetadata2(rawMetadata, skillPath);
27058
- const directory = dirname6(skillPath);
27059
+ const directory = dirname8(skillPath);
27059
27060
  const scripts = await findSkillScripts2(directory);
27060
27061
  return {
27061
27062
  metadata,
@@ -27088,7 +27089,7 @@ async function discoverSkills2(projectDir) {
27088
27089
  }
27089
27090
  }
27090
27091
  for (const relPath of PROJECT_SKILL_DIRECTORIES2) {
27091
- await loadSkillsFromDir(join16(dir, relPath));
27092
+ await loadSkillsFromDir(join18(dir, relPath));
27092
27093
  }
27093
27094
  await loadSkillsFromDir(getGlobalSkillsDir2());
27094
27095
  await loadSkillsFromDir(getClaudeGlobalSkillsDir2());
@@ -27459,7 +27460,7 @@ Scripts run in the skill's directory with the project directory as an argument.`
27459
27460
  if (!skill.scripts.includes(args2.script)) {
27460
27461
  return `Script '${args2.script}' not found in skill '${args2.skill}'. Available: ${skill.scripts.join(", ") || "none"}`;
27461
27462
  }
27462
- const scriptPath = join16(skill.directory, "scripts", args2.script);
27463
+ const scriptPath = join18(skill.directory, "scripts", args2.script);
27463
27464
  const scriptArgs = args2.args || [];
27464
27465
  try {
27465
27466
  const TIMEOUT_MS = 60000;
@@ -27568,14 +27569,14 @@ Good skills have:
27568
27569
  const csoWarnings = validateCSOCompliance2(args2.name, args2.description);
27569
27570
  let skillDir;
27570
27571
  if (args2.directory === "global") {
27571
- skillDir = join16(getGlobalSkillsDir2(), args2.name);
27572
+ skillDir = join18(getGlobalSkillsDir2(), args2.name);
27572
27573
  } else if (args2.directory === "global-claude") {
27573
- skillDir = join16(getClaudeGlobalSkillsDir2(), args2.name);
27574
+ skillDir = join18(getClaudeGlobalSkillsDir2(), args2.name);
27574
27575
  } else {
27575
27576
  const baseDir = args2.directory || DEFAULT_SKILLS_DIR2;
27576
- skillDir = join16(skillsProjectDirectory2, baseDir, args2.name);
27577
+ skillDir = join18(skillsProjectDirectory2, baseDir, args2.name);
27577
27578
  }
27578
- const skillPath = join16(skillDir, "SKILL.md");
27579
+ const skillPath = join18(skillDir, "SKILL.md");
27579
27580
  try {
27580
27581
  await mkdir2(skillDir, { recursive: true });
27581
27582
  const content = generateSkillContent2(args2.name, args2.description, args2.body, { tags: args2.tags, tools: args2.tools });
@@ -27732,8 +27733,8 @@ executed with skills_execute. Use for:
27732
27733
  if (isAbsolute2(args2.script_name) || args2.script_name.includes("..") || args2.script_name.includes("/") || args2.script_name.includes("\\") || basename2(args2.script_name) !== args2.script_name) {
27733
27734
  return "Invalid script name. Use simple filenames without paths.";
27734
27735
  }
27735
- const scriptsDir = join16(skill.directory, "scripts");
27736
- const scriptPath = join16(scriptsDir, args2.script_name);
27736
+ const scriptsDir = join18(skill.directory, "scripts");
27737
+ const scriptPath = join18(scriptsDir, args2.script_name);
27737
27738
  try {
27738
27739
  await mkdir2(scriptsDir, { recursive: true });
27739
27740
  await writeFile2(scriptPath, args2.content, {
@@ -27782,20 +27783,20 @@ Perfect for learning to create effective skills.`,
27782
27783
  }
27783
27784
  let skillDir;
27784
27785
  if (args2.directory === "global") {
27785
- skillDir = join16(getGlobalSkillsDir2(), args2.name);
27786
+ skillDir = join18(getGlobalSkillsDir2(), args2.name);
27786
27787
  } else {
27787
27788
  const baseDir = args2.directory || DEFAULT_SKILLS_DIR2;
27788
- skillDir = join16(skillsProjectDirectory2, baseDir, args2.name);
27789
+ skillDir = join18(skillsProjectDirectory2, baseDir, args2.name);
27789
27790
  }
27790
27791
  const createdFiles = [];
27791
27792
  try {
27792
27793
  await mkdir2(skillDir, { recursive: true });
27793
- const skillPath = join16(skillDir, "SKILL.md");
27794
+ const skillPath = join18(skillDir, "SKILL.md");
27794
27795
  const skillContent = generateSkillTemplate2(args2.name, args2.description);
27795
27796
  await writeFile2(skillPath, skillContent, "utf-8");
27796
27797
  createdFiles.push("SKILL.md");
27797
27798
  if (args2.include_example_script !== false) {
27798
- const scriptsDir = join16(skillDir, "scripts");
27799
+ const scriptsDir = join18(skillDir, "scripts");
27799
27800
  await mkdir2(scriptsDir, { recursive: true });
27800
27801
  const exampleScript = `#!/usr/bin/env bash
27801
27802
  # Example helper script for ${args2.name}
@@ -27809,15 +27810,15 @@ echo "Project directory: $1"
27809
27810
 
27810
27811
  # TODO: Add actual script logic
27811
27812
  `;
27812
- const scriptPath = join16(scriptsDir, "example.sh");
27813
+ const scriptPath = join18(scriptsDir, "example.sh");
27813
27814
  await writeFile2(scriptPath, exampleScript, { mode: 493 });
27814
27815
  createdFiles.push("scripts/example.sh");
27815
27816
  }
27816
27817
  if (args2.include_reference !== false) {
27817
- const refsDir = join16(skillDir, "references");
27818
+ const refsDir = join18(skillDir, "references");
27818
27819
  await mkdir2(refsDir, { recursive: true });
27819
27820
  const refContent = generateReferenceTemplate2(args2.name);
27820
- const refPath = join16(refsDir, "guide.md");
27821
+ const refPath = join18(refsDir, "guide.md");
27821
27822
  await writeFile2(refPath, refContent, "utf-8");
27822
27823
  createdFiles.push("references/guide.md");
27823
27824
  }
@@ -34576,14 +34577,14 @@ var require_parser2 = __commonJS((exports2) => {
34576
34577
  case "scalar":
34577
34578
  case "single-quoted-scalar":
34578
34579
  case "double-quoted-scalar": {
34579
- const fs6 = this.flowScalar(this.type);
34580
+ const fs9 = this.flowScalar(this.type);
34580
34581
  if (atNextItem || it.value) {
34581
- map13.items.push({ start: start4, key: fs6, sep: [] });
34582
+ map13.items.push({ start: start4, key: fs9, sep: [] });
34582
34583
  this.onKeyLine = true;
34583
34584
  } else if (it.sep) {
34584
- this.stack.push(fs6);
34585
+ this.stack.push(fs9);
34585
34586
  } else {
34586
- Object.assign(it, { key: fs6, sep: [] });
34587
+ Object.assign(it, { key: fs9, sep: [] });
34587
34588
  this.onKeyLine = true;
34588
34589
  }
34589
34590
  return;
@@ -34711,13 +34712,13 @@ var require_parser2 = __commonJS((exports2) => {
34711
34712
  case "scalar":
34712
34713
  case "single-quoted-scalar":
34713
34714
  case "double-quoted-scalar": {
34714
- const fs6 = this.flowScalar(this.type);
34715
+ const fs9 = this.flowScalar(this.type);
34715
34716
  if (!it || it.value)
34716
- fc.items.push({ start: [], key: fs6, sep: [] });
34717
+ fc.items.push({ start: [], key: fs9, sep: [] });
34717
34718
  else if (it.sep)
34718
- this.stack.push(fs6);
34719
+ this.stack.push(fs9);
34719
34720
  else
34720
- Object.assign(it, { key: fs6, sep: [] });
34721
+ Object.assign(it, { key: fs9, sep: [] });
34721
34722
  return;
34722
34723
  }
34723
34724
  case "flow-map-end":
@@ -36115,7 +36116,7 @@ var require_atomic_sleep = __commonJS((exports2, module2) => {
36115
36116
 
36116
36117
  // ../../node_modules/.bun/sonic-boom@4.2.0/node_modules/sonic-boom/index.js
36117
36118
  var require_sonic_boom = __commonJS((exports2, module2) => {
36118
- var fs6 = __require("fs");
36119
+ var fs9 = __require("fs");
36119
36120
  var EventEmitter = __require("events");
36120
36121
  var inherits = __require("util").inherits;
36121
36122
  var path4 = __require("path");
@@ -36173,21 +36174,21 @@ var require_sonic_boom = __commonJS((exports2, module2) => {
36173
36174
  if (sonic.sync) {
36174
36175
  try {
36175
36176
  if (sonic.mkdir)
36176
- fs6.mkdirSync(path4.dirname(file4), { recursive: true });
36177
- const fd = fs6.openSync(file4, flags, mode);
36177
+ fs9.mkdirSync(path4.dirname(file4), { recursive: true });
36178
+ const fd = fs9.openSync(file4, flags, mode);
36178
36179
  fileOpened(null, fd);
36179
36180
  } catch (err) {
36180
36181
  fileOpened(err);
36181
36182
  throw err;
36182
36183
  }
36183
36184
  } else if (sonic.mkdir) {
36184
- fs6.mkdir(path4.dirname(file4), { recursive: true }, (err) => {
36185
+ fs9.mkdir(path4.dirname(file4), { recursive: true }, (err) => {
36185
36186
  if (err)
36186
36187
  return fileOpened(err);
36187
- fs6.open(file4, flags, mode, fileOpened);
36188
+ fs9.open(file4, flags, mode, fileOpened);
36188
36189
  });
36189
36190
  } else {
36190
- fs6.open(file4, flags, mode, fileOpened);
36191
+ fs9.open(file4, flags, mode, fileOpened);
36191
36192
  }
36192
36193
  }
36193
36194
  function SonicBoom(opts) {
@@ -36228,16 +36229,16 @@ var require_sonic_boom = __commonJS((exports2, module2) => {
36228
36229
  this.flush = flushBuffer;
36229
36230
  this.flushSync = flushBufferSync;
36230
36231
  this._actualWrite = actualWriteBuffer;
36231
- fsWriteSync = () => fs6.writeSync(this.fd, this._writingBuf);
36232
- fsWrite = () => fs6.write(this.fd, this._writingBuf, this.release);
36232
+ fsWriteSync = () => fs9.writeSync(this.fd, this._writingBuf);
36233
+ fsWrite = () => fs9.write(this.fd, this._writingBuf, this.release);
36233
36234
  } else if (contentMode === undefined || contentMode === kContentModeUtf8) {
36234
36235
  this._writingBuf = "";
36235
36236
  this.write = write;
36236
36237
  this.flush = flush;
36237
36238
  this.flushSync = flushSync;
36238
36239
  this._actualWrite = actualWrite;
36239
- fsWriteSync = () => fs6.writeSync(this.fd, this._writingBuf, "utf8");
36240
- fsWrite = () => fs6.write(this.fd, this._writingBuf, "utf8", this.release);
36240
+ fsWriteSync = () => fs9.writeSync(this.fd, this._writingBuf, "utf8");
36241
+ fsWrite = () => fs9.write(this.fd, this._writingBuf, "utf8", this.release);
36241
36242
  } else {
36242
36243
  throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
36243
36244
  }
@@ -36293,7 +36294,7 @@ var require_sonic_boom = __commonJS((exports2, module2) => {
36293
36294
  }
36294
36295
  }
36295
36296
  if (this._fsync) {
36296
- fs6.fsyncSync(this.fd);
36297
+ fs9.fsyncSync(this.fd);
36297
36298
  }
36298
36299
  const len = this._len;
36299
36300
  if (this._reopening) {
@@ -36406,7 +36407,7 @@ var require_sonic_boom = __commonJS((exports2, module2) => {
36406
36407
  const onDrain = () => {
36407
36408
  if (!this._fsync) {
36408
36409
  try {
36409
- fs6.fsync(this.fd, (err) => {
36410
+ fs9.fsync(this.fd, (err) => {
36410
36411
  this._flushPending = false;
36411
36412
  cb(err);
36412
36413
  });
@@ -36508,7 +36509,7 @@ var require_sonic_boom = __commonJS((exports2, module2) => {
36508
36509
  const fd = this.fd;
36509
36510
  this.once("ready", () => {
36510
36511
  if (fd !== this.fd) {
36511
- fs6.close(fd, (err) => {
36512
+ fs9.close(fd, (err) => {
36512
36513
  if (err) {
36513
36514
  return this.emit("error", err);
36514
36515
  }
@@ -36557,7 +36558,7 @@ var require_sonic_boom = __commonJS((exports2, module2) => {
36557
36558
  buf = this._bufs[0];
36558
36559
  }
36559
36560
  try {
36560
- const n = fs6.writeSync(this.fd, buf, "utf8");
36561
+ const n = fs9.writeSync(this.fd, buf, "utf8");
36561
36562
  const releasedBufObj = releaseWritingBuf(buf, this._len, n);
36562
36563
  buf = releasedBufObj.writingBuf;
36563
36564
  this._len = releasedBufObj.len;
@@ -36573,7 +36574,7 @@ var require_sonic_boom = __commonJS((exports2, module2) => {
36573
36574
  }
36574
36575
  }
36575
36576
  try {
36576
- fs6.fsyncSync(this.fd);
36577
+ fs9.fsyncSync(this.fd);
36577
36578
  } catch {}
36578
36579
  }
36579
36580
  function flushBufferSync() {
@@ -36593,7 +36594,7 @@ var require_sonic_boom = __commonJS((exports2, module2) => {
36593
36594
  buf = mergeBuf(this._bufs[0], this._lens[0]);
36594
36595
  }
36595
36596
  try {
36596
- const n = fs6.writeSync(this.fd, buf);
36597
+ const n = fs9.writeSync(this.fd, buf);
36597
36598
  buf = buf.subarray(n);
36598
36599
  this._len = Math.max(this._len - n, 0);
36599
36600
  if (buf.length <= 0) {
@@ -36621,13 +36622,13 @@ var require_sonic_boom = __commonJS((exports2, module2) => {
36621
36622
  this._writingBuf = this._writingBuf || this._bufs.shift() || "";
36622
36623
  if (this.sync) {
36623
36624
  try {
36624
- const written = fs6.writeSync(this.fd, this._writingBuf, "utf8");
36625
+ const written = fs9.writeSync(this.fd, this._writingBuf, "utf8");
36625
36626
  release(null, written);
36626
36627
  } catch (err) {
36627
36628
  release(err);
36628
36629
  }
36629
36630
  } else {
36630
- fs6.write(this.fd, this._writingBuf, "utf8", release);
36631
+ fs9.write(this.fd, this._writingBuf, "utf8", release);
36631
36632
  }
36632
36633
  }
36633
36634
  function actualWriteBuffer() {
@@ -36636,7 +36637,7 @@ var require_sonic_boom = __commonJS((exports2, module2) => {
36636
36637
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
36637
36638
  if (this.sync) {
36638
36639
  try {
36639
- const written = fs6.writeSync(this.fd, this._writingBuf);
36640
+ const written = fs9.writeSync(this.fd, this._writingBuf);
36640
36641
  release(null, written);
36641
36642
  } catch (err) {
36642
36643
  release(err);
@@ -36645,7 +36646,7 @@ var require_sonic_boom = __commonJS((exports2, module2) => {
36645
36646
  if (kCopyBuffer) {
36646
36647
  this._writingBuf = Buffer.from(this._writingBuf);
36647
36648
  }
36648
- fs6.write(this.fd, this._writingBuf, release);
36649
+ fs9.write(this.fd, this._writingBuf, release);
36649
36650
  }
36650
36651
  }
36651
36652
  function actualClose(sonic) {
@@ -36661,11 +36662,11 @@ var require_sonic_boom = __commonJS((exports2, module2) => {
36661
36662
  sonic._lens = [];
36662
36663
  assert4(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
36663
36664
  try {
36664
- fs6.fsync(sonic.fd, closeWrapped);
36665
+ fs9.fsync(sonic.fd, closeWrapped);
36665
36666
  } catch {}
36666
36667
  function closeWrapped() {
36667
36668
  if (sonic.fd !== 1 && sonic.fd !== 2) {
36668
- fs6.close(sonic.fd, done8);
36669
+ fs9.close(sonic.fd, done8);
36669
36670
  } else {
36670
36671
  done8();
36671
36672
  }
@@ -38953,7 +38954,7 @@ var require_multistream = __commonJS((exports2, module2) => {
38953
38954
 
38954
38955
  // ../../node_modules/.bun/pino@9.14.0/node_modules/pino/pino.js
38955
38956
  var require_pino = __commonJS((exports2, module2) => {
38956
- var os5 = __require("node:os");
38957
+ var os6 = __require("node:os");
38957
38958
  var stdSerializers = require_pino_std_serializers();
38958
38959
  var caller = require_caller();
38959
38960
  var redaction = require_redaction();
@@ -39000,7 +39001,7 @@ var require_pino = __commonJS((exports2, module2) => {
39000
39001
  } = symbols;
39001
39002
  var { epochTime, nullTime } = time4;
39002
39003
  var { pid } = process;
39003
- var hostname4 = os5.hostname();
39004
+ var hostname4 = os6.hostname();
39004
39005
  var defaultErrorSerializer = stdSerializers.err;
39005
39006
  var defaultOptions = {
39006
39007
  level: "info",
@@ -39164,18 +39165,18 @@ import * as p from "@clack/prompts";
39164
39165
  import {
39165
39166
  chmodSync,
39166
39167
  copyFileSync,
39167
- existsSync as existsSync17,
39168
- mkdirSync as mkdirSync9,
39169
- readFileSync as readFileSync13,
39168
+ existsSync as existsSync20,
39169
+ mkdirSync as mkdirSync11,
39170
+ readFileSync as readFileSync16,
39170
39171
  readdirSync as readdirSync2,
39171
39172
  renameSync,
39172
39173
  rmdirSync,
39173
39174
  rmSync,
39174
39175
  statSync as statSync2,
39175
- writeFileSync as writeFileSync6
39176
+ writeFileSync as writeFileSync7
39176
39177
  } from "fs";
39177
- import { homedir as homedir10 } from "os";
39178
- import { basename as basename3, dirname as dirname7, join as join27 } from "path";
39178
+ import { homedir as homedir11 } from "os";
39179
+ import { basename as basename3, dirname as dirname9, join as join29 } from "path";
39179
39180
  import { fileURLToPath as fileURLToPath3 } from "url";
39180
39181
 
39181
39182
  // dist/hive.js
@@ -93817,13 +93818,13 @@ import {
93817
93818
  getLibSQLProjectTempDirName,
93818
93819
  getLibSQLDatabasePath,
93819
93820
  hashLibSQLProjectPath,
93820
- getSwarmMailLibSQL as getSwarmMailLibSQL17,
93821
+ getSwarmMailLibSQL as getSwarmMailLibSQL19,
93821
93822
  createHiveAdapter as createHiveAdapter4,
93822
93823
  resolvePartialId as resolvePartialId4,
93823
93824
  createDurableStreamAdapter,
93824
93825
  createDurableStreamServer
93825
93826
  } from "swarm-mail";
93826
- import { execSync } from "child_process";
93827
+ import { execSync, spawn } from "child_process";
93827
93828
  import { tmpdir as tmpdir3 } from "os";
93828
93829
 
93829
93830
  // src/query-tools.ts
@@ -95082,12 +95083,6 @@ function formatSwarmHistory(records) {
95082
95083
  return lines.join(`
95083
95084
  `);
95084
95085
  }
95085
- var observabilityTools = {
95086
- swarm_analytics,
95087
- swarm_query,
95088
- swarm_diagnose,
95089
- swarm_insights
95090
- };
95091
95086
 
95092
95087
  // src/observability-health.ts
95093
95088
  import { getSwarmMailLibSQL as getSwarmMailLibSQL9 } from "swarm-mail";
@@ -95105,20 +95100,6 @@ var STABILIZATION_THRESHOLD = 50;
95105
95100
  function getEvalHistoryPath(projectPath) {
95106
95101
  return path5.join(projectPath, DEFAULT_EVAL_HISTORY_PATH);
95107
95102
  }
95108
- function ensureEvalHistoryDir(projectPath) {
95109
- const historyPath = getEvalHistoryPath(projectPath);
95110
- const dir = path5.dirname(historyPath);
95111
- if (!fs3.existsSync(dir)) {
95112
- fs3.mkdirSync(dir, { recursive: true });
95113
- }
95114
- }
95115
- function recordEvalRun(projectPath, run) {
95116
- ensureEvalHistoryDir(projectPath);
95117
- const historyPath = getEvalHistoryPath(projectPath);
95118
- const line = `${JSON.stringify(run)}
95119
- `;
95120
- fs3.appendFileSync(historyPath, line, "utf-8");
95121
- }
95122
95103
  function readAllRecords(projectPath) {
95123
95104
  const historyPath = getEvalHistoryPath(projectPath);
95124
95105
  if (!fs3.existsSync(historyPath)) {
@@ -95428,6 +95409,70 @@ async function getObservabilityHealth(projectPath, options2 = {}) {
95428
95409
  };
95429
95410
  }
95430
95411
 
95412
+ // src/eval-history.ts
95413
+ import * as fs5 from "node:fs";
95414
+ import * as path6 from "node:path";
95415
+ var DEFAULT_EVAL_HISTORY_PATH2 = ".opencode/eval-history.jsonl";
95416
+ var VARIANCE_THRESHOLD2 = 0.1;
95417
+ var BOOTSTRAP_THRESHOLD2 = 10;
95418
+ var STABILIZATION_THRESHOLD2 = 50;
95419
+ function getEvalHistoryPath2(projectPath) {
95420
+ return path6.join(projectPath, DEFAULT_EVAL_HISTORY_PATH2);
95421
+ }
95422
+ function ensureEvalHistoryDir(projectPath) {
95423
+ const historyPath = getEvalHistoryPath2(projectPath);
95424
+ const dir = path6.dirname(historyPath);
95425
+ if (!fs5.existsSync(dir)) {
95426
+ fs5.mkdirSync(dir, { recursive: true });
95427
+ }
95428
+ }
95429
+ function recordEvalRun(projectPath, run) {
95430
+ ensureEvalHistoryDir(projectPath);
95431
+ const historyPath = getEvalHistoryPath2(projectPath);
95432
+ const line = `${JSON.stringify(run)}
95433
+ `;
95434
+ fs5.appendFileSync(historyPath, line, "utf-8");
95435
+ }
95436
+ function readAllRecords3(projectPath) {
95437
+ const historyPath = getEvalHistoryPath2(projectPath);
95438
+ if (!fs5.existsSync(historyPath)) {
95439
+ return [];
95440
+ }
95441
+ const content = fs5.readFileSync(historyPath, "utf-8");
95442
+ const lines = content.trim().split(`
95443
+ `).filter(Boolean);
95444
+ return lines.map((line) => JSON.parse(line));
95445
+ }
95446
+ function getScoreHistory2(projectPath, evalName) {
95447
+ return readAllRecords3(projectPath).filter((run) => run.eval_name === evalName);
95448
+ }
95449
+ function calculateVariance2(scores) {
95450
+ if (scores.length <= 1) {
95451
+ return 0;
95452
+ }
95453
+ const mean = scores.reduce((sum, score) => sum + score, 0) / scores.length;
95454
+ const variance5 = scores.reduce((sum, score) => {
95455
+ const deviation = score - mean;
95456
+ return sum + deviation * deviation;
95457
+ }, 0) / scores.length;
95458
+ return variance5;
95459
+ }
95460
+ function getPhase2(projectPath, evalName) {
95461
+ const history = getScoreHistory2(projectPath, evalName);
95462
+ if (history.length < BOOTSTRAP_THRESHOLD2) {
95463
+ return "bootstrap";
95464
+ }
95465
+ if (history.length <= STABILIZATION_THRESHOLD2) {
95466
+ return "stabilization";
95467
+ }
95468
+ const scores = history.map((run) => run.score);
95469
+ const variance5 = calculateVariance2(scores);
95470
+ if (variance5 < VARIANCE_THRESHOLD2) {
95471
+ return "production";
95472
+ }
95473
+ return "stabilization";
95474
+ }
95475
+
95431
95476
  // src/eval-gates.ts
95432
95477
  var DEFAULT_THRESHOLDS = {
95433
95478
  stabilization: 0.1,
@@ -95518,8 +95563,236 @@ function checkGate(projectPath, evalName, currentScore, config4) {
95518
95563
  };
95519
95564
  }
95520
95565
 
95521
- // bin/swarm.ts
95522
- init_eval_capture3();
95566
+ // src/eval-capture.ts
95567
+ init_zod3();
95568
+ import * as fs6 from "node:fs";
95569
+ import * as os3 from "node:os";
95570
+ import * as path7 from "node:path";
95571
+ import { getSwarmMailLibSQL as getSwarmMailLibSQL10 } from "swarm-mail";
95572
+ var SubtaskOutcomeSchema3 = exports_external3.object({
95573
+ bead_id: exports_external3.string(),
95574
+ title: exports_external3.string(),
95575
+ planned_files: exports_external3.array(exports_external3.string()),
95576
+ actual_files: exports_external3.array(exports_external3.string()),
95577
+ duration_ms: exports_external3.number().int().min(0),
95578
+ error_count: exports_external3.number().int().min(0),
95579
+ retry_count: exports_external3.number().int().min(0),
95580
+ success: exports_external3.boolean(),
95581
+ failure_mode: exports_external3.string().optional()
95582
+ });
95583
+ var EvalRecordSchema3 = exports_external3.object({
95584
+ id: exports_external3.string(),
95585
+ timestamp: exports_external3.string(),
95586
+ project_path: exports_external3.string(),
95587
+ task: exports_external3.string(),
95588
+ context: exports_external3.string().optional(),
95589
+ strategy: exports_external3.enum(["file-based", "feature-based", "risk-based", "auto"]),
95590
+ subtask_count: exports_external3.number().int().min(1),
95591
+ epic_title: exports_external3.string(),
95592
+ epic_description: exports_external3.string().optional(),
95593
+ subtasks: exports_external3.array(exports_external3.object({
95594
+ title: exports_external3.string(),
95595
+ description: exports_external3.string().optional(),
95596
+ files: exports_external3.array(exports_external3.string()),
95597
+ dependencies: exports_external3.array(exports_external3.number()).optional(),
95598
+ estimated_complexity: exports_external3.number().int().min(1).max(5).optional()
95599
+ })),
95600
+ outcomes: exports_external3.array(SubtaskOutcomeSchema3).optional(),
95601
+ overall_success: exports_external3.boolean().optional(),
95602
+ total_duration_ms: exports_external3.number().int().min(0).optional(),
95603
+ total_errors: exports_external3.number().int().min(0).optional(),
95604
+ human_accepted: exports_external3.boolean().optional(),
95605
+ human_modified: exports_external3.boolean().optional(),
95606
+ human_notes: exports_external3.string().optional(),
95607
+ file_overlap_count: exports_external3.number().int().min(0).optional(),
95608
+ scope_accuracy: exports_external3.number().min(0).max(2).optional(),
95609
+ time_balance_ratio: exports_external3.number().min(1).optional()
95610
+ });
95611
+ var CoordinatorEventSchema3 = exports_external3.discriminatedUnion("event_type", [
95612
+ exports_external3.object({
95613
+ session_id: exports_external3.string(),
95614
+ epic_id: exports_external3.string(),
95615
+ timestamp: exports_external3.string(),
95616
+ event_type: exports_external3.literal("DECISION"),
95617
+ decision_type: exports_external3.enum([
95618
+ "strategy_selected",
95619
+ "worker_spawned",
95620
+ "review_completed",
95621
+ "decomposition_complete",
95622
+ "researcher_spawned",
95623
+ "skill_loaded",
95624
+ "inbox_checked",
95625
+ "blocker_resolved",
95626
+ "scope_change_approved",
95627
+ "scope_change_rejected"
95628
+ ]),
95629
+ payload: exports_external3.any()
95630
+ }),
95631
+ exports_external3.object({
95632
+ session_id: exports_external3.string(),
95633
+ epic_id: exports_external3.string(),
95634
+ timestamp: exports_external3.string(),
95635
+ event_type: exports_external3.literal("VIOLATION"),
95636
+ violation_type: exports_external3.enum([
95637
+ "coordinator_edited_file",
95638
+ "coordinator_ran_tests",
95639
+ "coordinator_reserved_files",
95640
+ "no_worker_spawned",
95641
+ "worker_completed_without_review"
95642
+ ]),
95643
+ payload: exports_external3.any()
95644
+ }),
95645
+ exports_external3.object({
95646
+ session_id: exports_external3.string(),
95647
+ epic_id: exports_external3.string(),
95648
+ timestamp: exports_external3.string(),
95649
+ event_type: exports_external3.literal("OUTCOME"),
95650
+ outcome_type: exports_external3.enum([
95651
+ "subtask_success",
95652
+ "subtask_retry",
95653
+ "subtask_failed",
95654
+ "epic_complete",
95655
+ "blocker_detected"
95656
+ ]),
95657
+ payload: exports_external3.any()
95658
+ }),
95659
+ exports_external3.object({
95660
+ session_id: exports_external3.string(),
95661
+ epic_id: exports_external3.string(),
95662
+ timestamp: exports_external3.string(),
95663
+ event_type: exports_external3.literal("COMPACTION"),
95664
+ compaction_type: exports_external3.enum([
95665
+ "detection_complete",
95666
+ "prompt_generated",
95667
+ "context_injected",
95668
+ "resumption_started",
95669
+ "tool_call_tracked"
95670
+ ]),
95671
+ payload: exports_external3.any()
95672
+ })
95673
+ ]);
95674
+ var CoordinatorSessionSchema3 = exports_external3.object({
95675
+ session_id: exports_external3.string(),
95676
+ epic_id: exports_external3.string(),
95677
+ start_time: exports_external3.string(),
95678
+ end_time: exports_external3.string().optional(),
95679
+ events: exports_external3.array(CoordinatorEventSchema3)
95680
+ });
95681
+ var inProgressRecords3 = new Map;
95682
+ function getSessionDir3() {
95683
+ return process.env.SWARM_SESSIONS_DIR || path7.join(os3.homedir(), ".config", "swarm-tools", "sessions");
95684
+ }
95685
+ function getSessionPath3(sessionId) {
95686
+ return path7.join(getSessionDir3(), `${sessionId}.jsonl`);
95687
+ }
95688
+ function ensureSessionDir3() {
95689
+ const sessionDir = getSessionDir3();
95690
+ if (!fs6.existsSync(sessionDir)) {
95691
+ fs6.mkdirSync(sessionDir, { recursive: true });
95692
+ }
95693
+ }
95694
+ async function captureCoordinatorEvent3(event) {
95695
+ CoordinatorEventSchema3.parse(event);
95696
+ try {
95697
+ const projectPath = process.cwd();
95698
+ const swarmMail = await getSwarmMailLibSQL10(projectPath);
95699
+ const eventType = `coordinator_${event.event_type.toLowerCase()}`;
95700
+ const eventData = {
95701
+ type: eventType,
95702
+ project_key: projectPath,
95703
+ timestamp: new Date(event.timestamp).getTime(),
95704
+ session_id: event.session_id,
95705
+ epic_id: event.epic_id,
95706
+ event_type: event.event_type,
95707
+ payload: event.payload
95708
+ };
95709
+ if (event.event_type === "DECISION") {
95710
+ eventData.decision_type = event.decision_type;
95711
+ } else if (event.event_type === "VIOLATION") {
95712
+ eventData.violation_type = event.violation_type;
95713
+ } else if (event.event_type === "OUTCOME") {
95714
+ eventData.outcome_type = event.outcome_type;
95715
+ } else if (event.event_type === "COMPACTION") {
95716
+ eventData.compaction_type = event.compaction_type;
95717
+ }
95718
+ await swarmMail.appendEvent(eventData);
95719
+ ensureSessionDir3();
95720
+ const sessionPath = getSessionPath3(event.session_id);
95721
+ const line = `${JSON.stringify(event)}
95722
+ `;
95723
+ fs6.appendFileSync(sessionPath, line, "utf-8");
95724
+ } catch (error54) {
95725
+ console.warn("Failed to append event to libSQL, using JSONL fallback:", error54);
95726
+ ensureSessionDir3();
95727
+ const sessionPath = getSessionPath3(event.session_id);
95728
+ const line = `${JSON.stringify(event)}
95729
+ `;
95730
+ fs6.appendFileSync(sessionPath, line, "utf-8");
95731
+ }
95732
+ }
95733
+ async function captureCompactionEvent3(params) {
95734
+ const event = {
95735
+ session_id: params.session_id,
95736
+ epic_id: params.epic_id,
95737
+ timestamp: new Date().toISOString(),
95738
+ event_type: "COMPACTION",
95739
+ compaction_type: params.compaction_type,
95740
+ payload: params.payload
95741
+ };
95742
+ await captureCoordinatorEvent3(event);
95743
+ }
95744
+
95745
+ // src/regression-detection.ts
95746
+ import * as fs7 from "node:fs";
95747
+ function readAllRecords4(projectPath) {
95748
+ const historyPath = getEvalHistoryPath(projectPath);
95749
+ if (!fs7.existsSync(historyPath)) {
95750
+ return [];
95751
+ }
95752
+ const content = fs7.readFileSync(historyPath, "utf-8");
95753
+ const lines = content.trim().split(`
95754
+ `).filter(Boolean);
95755
+ return lines.map((line) => JSON.parse(line));
95756
+ }
95757
+ function getEvalNames2(records) {
95758
+ const names = new Set;
95759
+ for (const record4 of records) {
95760
+ names.add(record4.eval_name);
95761
+ }
95762
+ return Array.from(names);
95763
+ }
95764
+ function getLastNRuns2(records, evalName, n) {
95765
+ const evalRecords = records.filter((r) => r.eval_name === evalName);
95766
+ return evalRecords.sort((a, b) => b.run_count - a.run_count).slice(0, n);
95767
+ }
95768
+ function detectRegressions2(projectPath, threshold = 0.1) {
95769
+ const records = readAllRecords4(projectPath);
95770
+ if (records.length === 0) {
95771
+ return [];
95772
+ }
95773
+ const evalNames = getEvalNames2(records);
95774
+ const regressions = [];
95775
+ for (const evalName of evalNames) {
95776
+ const lastTwoRuns = getLastNRuns2(records, evalName, 2);
95777
+ if (lastTwoRuns.length < 2) {
95778
+ continue;
95779
+ }
95780
+ const latest = lastTwoRuns[0];
95781
+ const previous = lastTwoRuns[1];
95782
+ const delta = previous.score - latest.score;
95783
+ const deltaPercent = (latest.score - previous.score) / previous.score * 100;
95784
+ if (delta > 0 && delta >= threshold) {
95785
+ regressions.push({
95786
+ evalName,
95787
+ oldScore: previous.score,
95788
+ newScore: latest.score,
95789
+ delta,
95790
+ deltaPercent
95791
+ });
95792
+ }
95793
+ }
95794
+ return regressions.sort((a, b) => b.delta - a.delta);
95795
+ }
95523
95796
 
95524
95797
  // src/hive.ts
95525
95798
  init_dist2();
@@ -95528,12 +95801,12 @@ import {
95528
95801
  FlushManager as FlushManager3,
95529
95802
  importFromJSONL as importFromJSONL3,
95530
95803
  syncMemories as syncMemories3,
95531
- getSwarmMailLibSQL as getSwarmMailLibSQL11,
95804
+ getSwarmMailLibSQL as getSwarmMailLibSQL12,
95532
95805
  resolvePartialId as resolvePartialId3,
95533
95806
  findCellsByPartialId as findCellsByPartialId3
95534
95807
  } from "swarm-mail";
95535
- import { existsSync as existsSync10, readFileSync as readFileSync10 } from "node:fs";
95536
- import { join as join12 } from "node:path";
95808
+ import { existsSync as existsSync13, readFileSync as readFileSync13 } from "node:fs";
95809
+ import { join as join14 } from "node:path";
95537
95810
 
95538
95811
  // src/schemas/cell.ts
95539
95812
  init_zod3();
@@ -96131,10 +96404,10 @@ class HiveError3 extends Error {
96131
96404
  }
96132
96405
  }
96133
96406
  function ensureHiveDirectory3(projectPath) {
96134
- const hiveDir = join12(projectPath, ".hive");
96135
- if (!existsSync10(hiveDir)) {
96136
- const { mkdirSync: mkdirSync5 } = __require("node:fs");
96137
- mkdirSync5(hiveDir, { recursive: true });
96407
+ const hiveDir = join14(projectPath, ".hive");
96408
+ if (!existsSync13(hiveDir)) {
96409
+ const { mkdirSync: mkdirSync7 } = __require("node:fs");
96410
+ mkdirSync7(hiveDir, { recursive: true });
96138
96411
  }
96139
96412
  }
96140
96413
  var adapterCache3 = new Map;
@@ -96179,7 +96452,7 @@ async function getHiveAdapter3(projectKey) {
96179
96452
  if (adapterCache3.has(projectKey)) {
96180
96453
  return adapterCache3.get(projectKey);
96181
96454
  }
96182
- const swarmMail = await getSwarmMailLibSQL11(projectKey);
96455
+ const swarmMail = await getSwarmMailLibSQL12(projectKey);
96183
96456
  const db = await swarmMail.getDatabase();
96184
96457
  const adapter = createHiveAdapter3(db, projectKey);
96185
96458
  await adapter.runMigrations();
@@ -96188,8 +96461,8 @@ async function getHiveAdapter3(projectKey) {
96188
96461
  return adapter;
96189
96462
  }
96190
96463
  async function autoMigrateFromJSONL3(adapter, projectKey) {
96191
- const jsonlPath = join12(projectKey, ".hive", "issues.jsonl");
96192
- if (!existsSync10(jsonlPath)) {
96464
+ const jsonlPath = join14(projectKey, ".hive", "issues.jsonl");
96465
+ if (!existsSync13(jsonlPath)) {
96193
96466
  return;
96194
96467
  }
96195
96468
  const existingCells = await adapter.queryCells(projectKey, { limit: 1 });
@@ -96197,7 +96470,7 @@ async function autoMigrateFromJSONL3(adapter, projectKey) {
96197
96470
  return;
96198
96471
  }
96199
96472
  try {
96200
- const jsonlContent = readFileSync10(jsonlPath, "utf-8");
96473
+ const jsonlContent = readFileSync13(jsonlPath, "utf-8");
96201
96474
  const result = await importFromJSONL3(adapter, projectKey, jsonlContent, {
96202
96475
  skipExisting: true
96203
96476
  });
@@ -96370,14 +96643,14 @@ var hive_create_epic3 = tool3({
96370
96643
  console.warn("[hive_create_epic] Failed to emit SwarmStartedEvent:", error54);
96371
96644
  }
96372
96645
  try {
96373
- const { captureCoordinatorEvent: captureCoordinatorEvent4 } = await Promise.resolve().then(() => (init_eval_capture3(), exports_eval_capture3));
96646
+ const { captureCoordinatorEvent: captureCoordinatorEvent5 } = await Promise.resolve().then(() => (init_eval_capture3(), exports_eval_capture3));
96374
96647
  const filesPerSubtask = {};
96375
96648
  validated.subtasks.forEach((subtask, index) => {
96376
96649
  if (subtask.files && subtask.files.length > 0) {
96377
96650
  filesPerSubtask[index] = subtask.files;
96378
96651
  }
96379
96652
  });
96380
- captureCoordinatorEvent4({
96653
+ captureCoordinatorEvent5({
96381
96654
  session_id: ctx.sessionID || "unknown",
96382
96655
  epic_id: epic.id,
96383
96656
  timestamp: new Date().toISOString(),
@@ -96807,9 +97080,9 @@ var hive_sync3 = tool3({
96807
97080
  outputPath: `${projectKey}/.hive/issues.jsonl`
96808
97081
  });
96809
97082
  const flushResult = await withTimeout(flushManager.flush(), TIMEOUT_MS, "flush hive");
96810
- const swarmMail = await getSwarmMailLibSQL11(projectKey);
97083
+ const swarmMail = await getSwarmMailLibSQL12(projectKey);
96811
97084
  const db = await swarmMail.getDatabase();
96812
- const hivePath = join12(projectKey, ".hive");
97085
+ const hivePath = join14(projectKey, ".hive");
96813
97086
  let memoriesSynced = 0;
96814
97087
  try {
96815
97088
  const memoryResult = await syncMemories3(db, hivePath);
@@ -97312,9 +97585,9 @@ function formatToolAvailability2(availability) {
97312
97585
 
97313
97586
  // src/rate-limiter.ts
97314
97587
  var import_ioredis = __toESM(require_built3(), 1);
97315
- import { mkdirSync as mkdirSync5, existsSync as existsSync11 } from "node:fs";
97316
- import { dirname as dirname5, join as join13 } from "node:path";
97317
- import { homedir as homedir6 } from "node:os";
97588
+ import { mkdirSync as mkdirSync7, existsSync as existsSync14 } from "node:fs";
97589
+ import { dirname as dirname7, join as join15 } from "node:path";
97590
+ import { homedir as homedir7 } from "node:os";
97318
97591
  var sqliteAvailable = false;
97319
97592
  var createDatabase = null;
97320
97593
  try {
@@ -97428,9 +97701,9 @@ class SqliteRateLimiter {
97428
97701
  if (!sqliteAvailable || !createDatabase) {
97429
97702
  throw new Error("SQLite is not available in this runtime (requires Bun)");
97430
97703
  }
97431
- const dir = dirname5(dbPath);
97432
- if (!existsSync11(dir)) {
97433
- mkdirSync5(dir, { recursive: true });
97704
+ const dir = dirname7(dbPath);
97705
+ if (!existsSync14(dir)) {
97706
+ mkdirSync7(dir, { recursive: true });
97434
97707
  }
97435
97708
  this.db = createDatabase(dbPath);
97436
97709
  this.initialize();
@@ -97574,7 +97847,7 @@ async function createRateLimiter(options2) {
97574
97847
  const {
97575
97848
  backend,
97576
97849
  redisUrl = process.env.OPENCODE_RATE_LIMIT_REDIS_URL || "redis://localhost:6379",
97577
- sqlitePath = process.env.OPENCODE_RATE_LIMIT_SQLITE_PATH || join13(homedir6(), ".config", "opencode", "rate-limits.db")
97850
+ sqlitePath = process.env.OPENCODE_RATE_LIMIT_SQLITE_PATH || join15(homedir7(), ".config", "opencode", "rate-limits.db")
97578
97851
  } = options2 || {};
97579
97852
  if (backend === "memory") {
97580
97853
  return new InMemoryRateLimiter;
@@ -97634,13 +97907,13 @@ async function getRateLimiter() {
97634
97907
 
97635
97908
  // src/agent-mail.ts
97636
97909
  import {
97637
- existsSync as existsSync12,
97638
- mkdirSync as mkdirSync6,
97639
- readFileSync as readFileSync11,
97640
- writeFileSync as writeFileSync4,
97910
+ existsSync as existsSync15,
97911
+ mkdirSync as mkdirSync8,
97912
+ readFileSync as readFileSync14,
97913
+ writeFileSync as writeFileSync5,
97641
97914
  unlinkSync
97642
97915
  } from "fs";
97643
- import { join as join14 } from "path";
97916
+ import { join as join16 } from "path";
97644
97917
  import { tmpdir } from "os";
97645
97918
  var AGENT_MAIL_URL = "http://127.0.0.1:8765";
97646
97919
  var DEFAULT_TTL_SECONDS = 3600;
@@ -97661,16 +97934,16 @@ var RECOVERY_CONFIG = {
97661
97934
  restartCooldownMs: 1e4,
97662
97935
  enabled: process.env.OPENCODE_AGENT_MAIL_AUTO_RESTART !== "false"
97663
97936
  };
97664
- var SESSION_STATE_DIR = process.env.SWARM_STATE_DIR || join14(tmpdir(), "swarm-sessions");
97937
+ var SESSION_STATE_DIR = process.env.SWARM_STATE_DIR || join16(tmpdir(), "swarm-sessions");
97665
97938
  function getSessionStatePath(sessionID) {
97666
97939
  const safeID = sessionID.replace(/[^a-zA-Z0-9_-]/g, "_");
97667
- return join14(SESSION_STATE_DIR, `${safeID}.json`);
97940
+ return join16(SESSION_STATE_DIR, `${safeID}.json`);
97668
97941
  }
97669
97942
  function loadSessionState(sessionID) {
97670
97943
  const path4 = getSessionStatePath(sessionID);
97671
97944
  try {
97672
- if (existsSync12(path4)) {
97673
- const data = readFileSync11(path4, "utf-8");
97945
+ if (existsSync15(path4)) {
97946
+ const data = readFileSync14(path4, "utf-8");
97674
97947
  return JSON.parse(data);
97675
97948
  }
97676
97949
  } catch (error54) {
@@ -97680,11 +97953,11 @@ function loadSessionState(sessionID) {
97680
97953
  }
97681
97954
  function saveSessionState(sessionID, state) {
97682
97955
  try {
97683
- if (!existsSync12(SESSION_STATE_DIR)) {
97684
- mkdirSync6(SESSION_STATE_DIR, { recursive: true });
97956
+ if (!existsSync15(SESSION_STATE_DIR)) {
97957
+ mkdirSync8(SESSION_STATE_DIR, { recursive: true });
97685
97958
  }
97686
97959
  const path4 = getSessionStatePath(sessionID);
97687
- writeFileSync4(path4, JSON.stringify(state, null, 2));
97960
+ writeFileSync5(path4, JSON.stringify(state, null, 2));
97688
97961
  return true;
97689
97962
  } catch (error54) {
97690
97963
  console.error(`[agent-mail] CRITICAL: Could not save session state: ${error54}`);
@@ -98368,29 +98641,29 @@ import {
98368
98641
  getActiveReservations
98369
98642
  } from "swarm-mail";
98370
98643
  import {
98371
- existsSync as existsSync13,
98372
- mkdirSync as mkdirSync7,
98373
- readFileSync as readFileSync12,
98374
- writeFileSync as writeFileSync5,
98644
+ existsSync as existsSync16,
98645
+ mkdirSync as mkdirSync9,
98646
+ readFileSync as readFileSync15,
98647
+ writeFileSync as writeFileSync6,
98375
98648
  unlinkSync as unlinkSync2
98376
98649
  } from "node:fs";
98377
- import { join as join15 } from "node:path";
98650
+ import { join as join17 } from "node:path";
98378
98651
  import { tmpdir as tmpdir2 } from "node:os";
98379
98652
  var MAX_INBOX_LIMIT2 = 5;
98380
98653
  var swarmMailProjectDirectory = null;
98381
98654
  function getSwarmMailProjectDirectory() {
98382
98655
  return swarmMailProjectDirectory ?? undefined;
98383
98656
  }
98384
- var SESSION_STATE_DIR2 = process.env.SWARM_STATE_DIR || join15(tmpdir2(), "swarm-sessions");
98657
+ var SESSION_STATE_DIR2 = process.env.SWARM_STATE_DIR || join17(tmpdir2(), "swarm-sessions");
98385
98658
  function getSessionStatePath2(sessionID) {
98386
98659
  const safeID = sessionID.replace(/[^a-zA-Z0-9_-]/g, "_");
98387
- return join15(SESSION_STATE_DIR2, `${safeID}.json`);
98660
+ return join17(SESSION_STATE_DIR2, `${safeID}.json`);
98388
98661
  }
98389
98662
  function loadSessionState2(sessionID) {
98390
98663
  const path4 = getSessionStatePath2(sessionID);
98391
98664
  try {
98392
- if (existsSync13(path4)) {
98393
- const data = readFileSync12(path4, "utf-8");
98665
+ if (existsSync16(path4)) {
98666
+ const data = readFileSync15(path4, "utf-8");
98394
98667
  return JSON.parse(data);
98395
98668
  }
98396
98669
  } catch (error54) {
@@ -98400,11 +98673,11 @@ function loadSessionState2(sessionID) {
98400
98673
  }
98401
98674
  function saveSessionState2(sessionID, state) {
98402
98675
  try {
98403
- if (!existsSync13(SESSION_STATE_DIR2)) {
98404
- mkdirSync7(SESSION_STATE_DIR2, { recursive: true });
98676
+ if (!existsSync16(SESSION_STATE_DIR2)) {
98677
+ mkdirSync9(SESSION_STATE_DIR2, { recursive: true });
98405
98678
  }
98406
98679
  const path4 = getSessionStatePath2(sessionID);
98407
- writeFileSync5(path4, JSON.stringify(state, null, 2));
98680
+ writeFileSync6(path4, JSON.stringify(state, null, 2));
98408
98681
  return true;
98409
98682
  } catch (error54) {
98410
98683
  console.warn(`[swarm-mail] Could not save session state: ${error54}`);
@@ -99713,7 +99986,7 @@ var swarm_delegate_planning = tool3({
99713
99986
  strategyReasoning = selection.reasoning;
99714
99987
  }
99715
99988
  try {
99716
- captureCoordinatorEvent3({
99989
+ captureCoordinatorEvent4({
99717
99990
  session_id: _ctx.sessionID || "unknown",
99718
99991
  epic_id: "planning",
99719
99992
  timestamp: new Date().toISOString(),
@@ -100882,11 +101155,11 @@ var qmarksTestNoExtDot2 = ([$0]) => {
100882
101155
  return (f) => f.length === len && f !== "." && f !== "..";
100883
101156
  };
100884
101157
  var defaultPlatform2 = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
100885
- var path7 = {
101158
+ var path9 = {
100886
101159
  win32: { sep: "\\" },
100887
101160
  posix: { sep: "/" }
100888
101161
  };
100889
- var sep5 = defaultPlatform2 === "win32" ? path7.win32.sep : path7.posix.sep;
101162
+ var sep5 = defaultPlatform2 === "win32" ? path9.win32.sep : path9.posix.sep;
100890
101163
  minimatch2.sep = sep5;
100891
101164
  var GLOBSTAR2 = Symbol("globstar **");
100892
101165
  minimatch2.GLOBSTAR = GLOBSTAR2;
@@ -101524,19 +101797,19 @@ import {
101524
101797
  getAgent as getAgent2,
101525
101798
  createEvent as createEvent8,
101526
101799
  appendEvent as appendEvent6,
101527
- getSwarmMailLibSQL as getSwarmMailLibSQL13
101800
+ getSwarmMailLibSQL as getSwarmMailLibSQL14
101528
101801
  } from "swarm-mail";
101529
101802
  init_skills2();
101530
101803
 
101531
101804
  // src/swarm-worktree.ts
101532
101805
  init_dist2();
101533
101806
  init_zod3();
101534
- import { join as join17 } from "node:path";
101535
- import { existsSync as existsSync14 } from "node:fs";
101807
+ import { join as join19 } from "node:path";
101808
+ import { existsSync as existsSync17 } from "node:fs";
101536
101809
  var WORKTREE_DIR2 = ".swarm/worktrees";
101537
101810
  function getWorktreePath2(projectPath, taskId) {
101538
101811
  const safeTaskId = taskId.replace(/[^a-zA-Z0-9.-]/g, "_");
101539
- return join17(projectPath, WORKTREE_DIR2, safeTaskId);
101812
+ return join19(projectPath, WORKTREE_DIR2, safeTaskId);
101540
101813
  }
101541
101814
  function parseTaskIdFromPath2(worktreePath) {
101542
101815
  const parts2 = worktreePath.split("/");
@@ -101570,7 +101843,7 @@ async function getWorktreeCommits2(worktreePath, startCommit) {
101570
101843
  `).filter((c) => c.length > 0);
101571
101844
  }
101572
101845
  async function ensureWorktreeDir2(projectPath) {
101573
- const worktreeDir = join17(projectPath, WORKTREE_DIR2);
101846
+ const worktreeDir = join19(projectPath, WORKTREE_DIR2);
101574
101847
  await Bun.$`mkdir -p ${worktreeDir}`.quiet().nothrow();
101575
101848
  }
101576
101849
  var swarm_worktree_create2 = tool3({
@@ -101589,7 +101862,7 @@ var swarm_worktree_create2 = tool3({
101589
101862
  return JSON.stringify(result2, null, 2);
101590
101863
  }
101591
101864
  const worktreePath = getWorktreePath2(args2.project_path, args2.task_id);
101592
- const exists3 = existsSync14(worktreePath);
101865
+ const exists3 = existsSync17(worktreePath);
101593
101866
  if (exists3) {
101594
101867
  const result2 = {
101595
101868
  success: false,
@@ -101625,7 +101898,7 @@ var swarm_worktree_merge2 = tool3({
101625
101898
  },
101626
101899
  async execute(args2) {
101627
101900
  const worktreePath = getWorktreePath2(args2.project_path, args2.task_id);
101628
- const exists3 = existsSync14(worktreePath);
101901
+ const exists3 = existsSync17(worktreePath);
101629
101902
  if (!exists3) {
101630
101903
  const result2 = {
101631
101904
  success: false,
@@ -101707,7 +101980,7 @@ var swarm_worktree_cleanup2 = tool3({
101707
101980
  return JSON.stringify(result3, null, 2);
101708
101981
  }
101709
101982
  const output = listResult.stdout.toString();
101710
- const worktreeDir = join17(args2.project_path, WORKTREE_DIR2);
101983
+ const worktreeDir = join19(args2.project_path, WORKTREE_DIR2);
101711
101984
  const worktrees = output.split(`
101712
101985
 
101713
101986
  `).filter((block) => block.includes(worktreeDir)).map((block) => {
@@ -101735,7 +102008,7 @@ var swarm_worktree_cleanup2 = tool3({
101735
102008
  return JSON.stringify(result2, null, 2);
101736
102009
  }
101737
102010
  const worktreePath = getWorktreePath2(args2.project_path, args2.task_id);
101738
- const exists3 = existsSync14(worktreePath);
102011
+ const exists3 = existsSync17(worktreePath);
101739
102012
  if (!exists3) {
101740
102013
  const result2 = {
101741
102014
  success: true,
@@ -101772,7 +102045,7 @@ var swarm_worktree_list2 = tool3({
101772
102045
  }, null, 2);
101773
102046
  }
101774
102047
  const output = listResult.stdout.toString();
101775
- const worktreeDir = join17(args2.project_path, WORKTREE_DIR2);
102048
+ const worktreeDir = join19(args2.project_path, WORKTREE_DIR2);
101776
102049
  const worktrees = [];
101777
102050
  const blocks = output.split(`
101778
102051
 
@@ -102086,7 +102359,7 @@ var swarm_review_feedback2 = tool3({
102086
102359
  if (args2.status === "approved") {
102087
102360
  markReviewApproved2(args2.task_id);
102088
102361
  try {
102089
- captureCoordinatorEvent3({
102362
+ captureCoordinatorEvent4({
102090
102363
  session_id: _ctx.sessionID || "unknown",
102091
102364
  epic_id: epicId,
102092
102365
  timestamp: new Date().toISOString(),
@@ -102154,7 +102427,7 @@ You may now complete the task with \`swarm_complete\`.`,
102154
102427
  const attemptNumber = incrementAttempt2(args2.task_id);
102155
102428
  const remaining = MAX_REVIEW_ATTEMPTS2 - attemptNumber;
102156
102429
  try {
102157
- captureCoordinatorEvent3({
102430
+ captureCoordinatorEvent4({
102158
102431
  session_id: _ctx.sessionID || "unknown",
102159
102432
  epic_id: epicId,
102160
102433
  timestamp: new Date().toISOString(),
@@ -103008,7 +103281,7 @@ This will be recorded as a negative learning signal.`;
103008
103281
  let deferredResolved = false;
103009
103282
  let deferredError;
103010
103283
  try {
103011
- const swarmMail = await getSwarmMailLibSQL13(args2.project_key);
103284
+ const swarmMail = await getSwarmMailLibSQL14(args2.project_key);
103012
103285
  const db = await swarmMail.getDatabase();
103013
103286
  const deferredUrl = `deferred:${args2.bead_id}`;
103014
103287
  const checkResult = await db.query(`SELECT url, resolved FROM deferred WHERE url = ? AND resolved = 0`, [deferredUrl]);
@@ -103207,7 +103480,7 @@ Files touched: ${args2.files_touched?.join(", ") || "none recorded"}`,
103207
103480
  }
103208
103481
  try {
103209
103482
  const durationMs = args2.start_time ? Date.now() - args2.start_time : 0;
103210
- captureCoordinatorEvent3({
103483
+ captureCoordinatorEvent4({
103211
103484
  session_id: _ctx.sessionID || "unknown",
103212
103485
  epic_id: epicId2,
103213
103486
  timestamp: new Date().toISOString(),
@@ -103289,7 +103562,7 @@ ${errorStack.slice(0, 1000)}
103289
103562
  }
103290
103563
  try {
103291
103564
  const durationMs = args2.start_time ? Date.now() - args2.start_time : 0;
103292
- captureCoordinatorEvent3({
103565
+ captureCoordinatorEvent4({
103293
103566
  session_id: _ctx.sessionID || "unknown",
103294
103567
  epic_id: epicId,
103295
103568
  timestamp: new Date().toISOString(),
@@ -103934,7 +104207,7 @@ init_eval_capture3();
103934
104207
 
103935
104208
  // src/memory-tools.ts
103936
104209
  init_dist2();
103937
- import { getSwarmMailLibSQL as getSwarmMailLibSQL14, createEvent as createEvent9, appendEvent as appendEvent7 } from "swarm-mail";
104210
+ import { getSwarmMailLibSQL as getSwarmMailLibSQL15, createEvent as createEvent9, appendEvent as appendEvent7 } from "swarm-mail";
103938
104211
 
103939
104212
  // ../../node_modules/.bun/effect@3.19.12/node_modules/effect/dist/esm/Function.js
103940
104213
  var isFunction3 = (input) => typeof input === "function";
@@ -104965,7 +105238,7 @@ var dedupeWith2 = /* @__PURE__ */ dual2(2, (self, isEquivalent) => {
104965
105238
  return [];
104966
105239
  });
104967
105240
  var dedupe2 = (self) => dedupeWith2(self, equivalence2());
104968
- var join18 = /* @__PURE__ */ dual2(2, (self, sep4) => fromIterable8(self).join(sep4));
105241
+ var join20 = /* @__PURE__ */ dual2(2, (self, sep4) => fromIterable8(self).join(sep4));
104969
105242
 
104970
105243
  // ../../node_modules/.bun/effect@3.19.12/node_modules/effect/dist/esm/Number.js
104971
105244
  var Order3 = number10;
@@ -109516,8 +109789,8 @@ var InvalidData2 = (path4, message, options2 = {
109516
109789
  Object.defineProperty(error54, "toString", {
109517
109790
  enumerable: false,
109518
109791
  value() {
109519
- const path8 = pipe4(this.path, join18(options2.pathDelim));
109520
- return `(Invalid data at ${path8}: "${this.message}")`;
109792
+ const path10 = pipe4(this.path, join20(options2.pathDelim));
109793
+ return `(Invalid data at ${path10}: "${this.message}")`;
109521
109794
  }
109522
109795
  });
109523
109796
  return error54;
@@ -109532,8 +109805,8 @@ var MissingData2 = (path4, message, options2 = {
109532
109805
  Object.defineProperty(error54, "toString", {
109533
109806
  enumerable: false,
109534
109807
  value() {
109535
- const path8 = pipe4(this.path, join18(options2.pathDelim));
109536
- return `(Missing data at ${path8}: "${this.message}")`;
109808
+ const path10 = pipe4(this.path, join20(options2.pathDelim));
109809
+ return `(Missing data at ${path10}: "${this.message}")`;
109537
109810
  }
109538
109811
  });
109539
109812
  return error54;
@@ -109549,8 +109822,8 @@ var SourceUnavailable2 = (path4, message, cause3, options2 = {
109549
109822
  Object.defineProperty(error54, "toString", {
109550
109823
  enumerable: false,
109551
109824
  value() {
109552
- const path8 = pipe4(this.path, join18(options2.pathDelim));
109553
- return `(Source unavailable at ${path8}: "${this.message}")`;
109825
+ const path10 = pipe4(this.path, join20(options2.pathDelim));
109826
+ return `(Source unavailable at ${path10}: "${this.message}")`;
109554
109827
  }
109555
109828
  });
109556
109829
  return error54;
@@ -109565,8 +109838,8 @@ var Unsupported2 = (path4, message, options2 = {
109565
109838
  Object.defineProperty(error54, "toString", {
109566
109839
  enumerable: false,
109567
109840
  value() {
109568
- const path8 = pipe4(this.path, join18(options2.pathDelim));
109569
- return `(Unsupported operation at ${path8}: "${this.message}")`;
109841
+ const path10 = pipe4(this.path, join20(options2.pathDelim));
109842
+ return `(Unsupported operation at ${path10}: "${this.message}")`;
109570
109843
  }
109571
109844
  });
109572
109845
  return error54;
@@ -109685,7 +109958,7 @@ var fromEnv2 = (options2) => {
109685
109958
  pathDelim: "_",
109686
109959
  seqDelim: ","
109687
109960
  }, options2);
109688
- const makePathString = (path4) => pipe4(path4, join18(pathDelim));
109961
+ const makePathString = (path4) => pipe4(path4, join20(pathDelim));
109689
109962
  const unmakePathString = (pathString) => pathString.split(pathDelim);
109690
109963
  const getEnv = () => typeof process !== "undefined" && ("env" in process) && typeof process.env === "object" ? process.env : {};
109691
109964
  const load = (path4, primitive, split = true) => {
@@ -109809,7 +110082,7 @@ var fromFlatLoop2 = (flat, prefix, config4, split) => {
109809
110082
  return fail5(right4.left);
109810
110083
  }
109811
110084
  if (isRight5(left4) && isRight5(right4)) {
109812
- const path4 = pipe4(prefix, join18("."));
110085
+ const path4 = pipe4(prefix, join20("."));
109813
110086
  const fail6 = fromFlatLoopFail2(prefix, path4);
109814
110087
  const [lefts, rights] = extend4(fail6, fail6, pipe4(left4.right, map8(right5)), pipe4(right4.right, map8(right5)));
109815
110088
  return pipe4(lefts, zip3(rights), forEachSequential2(([left6, right6]) => pipe4(zip5(left6, right6), map18(([left7, right7]) => op.zip(left7, right7)))));
@@ -111983,11 +112256,11 @@ var interruptAllAs2 = /* @__PURE__ */ dual2(2, /* @__PURE__ */ fnUntraced3(funct
111983
112256
  }
111984
112257
  }));
111985
112258
  var interruptAsFork2 = /* @__PURE__ */ dual2(2, (self, fiberId4) => self.interruptAsFork(fiberId4));
111986
- var join19 = (self) => zipLeft3(flatten11(self.await), self.inheritAll);
112259
+ var join21 = (self) => zipLeft3(flatten11(self.await), self.inheritAll);
111987
112260
  var _never4 = {
111988
112261
  ...CommitPrototype3,
111989
112262
  commit() {
111990
- return join19(this);
112263
+ return join21(this);
111991
112264
  },
111992
112265
  ...fiberProto2,
111993
112266
  id: () => none14,
@@ -113234,7 +113507,7 @@ class FiberRuntime2 extends Class4 {
113234
113507
  this.refreshRefCache();
113235
113508
  }
113236
113509
  commit() {
113237
- return join19(this);
113510
+ return join21(this);
113238
113511
  }
113239
113512
  id() {
113240
113513
  return this._fiberId;
@@ -114249,7 +114522,7 @@ var forEachConcurrentDiscard2 = (self, f, batching, processAll, n) => uninterrup
114249
114522
  next();
114250
114523
  }
114251
114524
  }));
114252
- return asVoid4(onExit4(flatten11(restore(join19(processingFiber))), exitMatch2({
114525
+ return asVoid4(onExit4(flatten11(restore(join21(processingFiber))), exitMatch2({
114253
114526
  onFailure: (cause4) => {
114254
114527
  onInterruptSignal();
114255
114528
  const target2 = residual.length + 1;
@@ -114571,7 +114844,7 @@ var fiberAll2 = (fibers) => {
114571
114844
  const _fiberAll = {
114572
114845
  ...CommitPrototype5,
114573
114846
  commit() {
114574
- return join19(this);
114847
+ return join21(this);
114575
114848
  },
114576
114849
  [FiberTypeId2]: fiberVariance5,
114577
114850
  id: () => fromIterable8(fibers).reduce((id, fiber) => combine12(id, fiber.id()), none14),
@@ -114624,14 +114897,14 @@ var raceWith3 = /* @__PURE__ */ dual2(3, (self, other, options2) => raceFibersWi
114624
114897
  }
114625
114898
  })
114626
114899
  }));
114627
- var disconnect3 = (self) => uninterruptibleMask4((restore) => fiberIdWith3((fiberId4) => flatMap15(forkDaemon3(restore(self)), (fiber) => pipe4(restore(join19(fiber)), onInterrupt3(() => pipe4(fiber, interruptAsFork2(fiberId4)))))));
114900
+ var disconnect3 = (self) => uninterruptibleMask4((restore) => fiberIdWith3((fiberId4) => flatMap15(forkDaemon3(restore(self)), (fiber) => pipe4(restore(join21(fiber)), onInterrupt3(() => pipe4(fiber, interruptAsFork2(fiberId4)))))));
114628
114901
  var race3 = /* @__PURE__ */ dual2(2, (self, that) => fiberIdWith3((parentFiberId) => raceWith3(self, that, {
114629
114902
  onSelfDone: (exit4, right4) => exitMatchEffect2(exit4, {
114630
- onFailure: (cause4) => pipe4(join19(right4), mapErrorCause3((cause22) => parallel4(cause4, cause22))),
114903
+ onFailure: (cause4) => pipe4(join21(right4), mapErrorCause3((cause22) => parallel4(cause4, cause22))),
114631
114904
  onSuccess: (value) => pipe4(right4, interruptAsFiber2(parentFiberId), as3(value))
114632
114905
  }),
114633
114906
  onOtherDone: (exit4, left4) => exitMatchEffect2(exit4, {
114634
- onFailure: (cause4) => pipe4(join19(left4), mapErrorCause3((cause22) => parallel4(cause22, cause4))),
114907
+ onFailure: (cause4) => pipe4(join21(left4), mapErrorCause3((cause22) => parallel4(cause22, cause4))),
114635
114908
  onSuccess: (value) => pipe4(left4, interruptAsFiber2(parentFiberId), as3(value))
114636
114909
  })
114637
114910
  })));
@@ -115785,8 +116058,8 @@ var forkIn3 = /* @__PURE__ */ dual2(2, (self, scope4) => withFiberRuntime3((pare
115785
116058
  return succeed5(fiber);
115786
116059
  }));
115787
116060
  var forkScoped3 = (self) => scopeWith3((scope4) => forkIn3(self, scope4));
115788
- var fromFiber3 = (fiber) => join19(fiber);
115789
- var fromFiberEffect3 = (fiber) => suspend4(() => flatMap15(fiber, join19));
116061
+ var fromFiber3 = (fiber) => join21(fiber);
116062
+ var fromFiberEffect3 = (fiber) => suspend4(() => flatMap15(fiber, join21));
115790
116063
  var memoKeySymbol2 = /* @__PURE__ */ Symbol.for("effect/Effect/memoizeFunction.key");
115791
116064
 
115792
116065
  class Key2 {
@@ -117551,7 +117824,7 @@ async function getMemoryAdapter2(projectPath) {
117551
117824
  if (cachedAdapter2 && cachedProjectPath2 === path4) {
117552
117825
  return cachedAdapter2;
117553
117826
  }
117554
- const swarmMail = await getSwarmMailLibSQL14(path4);
117827
+ const swarmMail = await getSwarmMailLibSQL15(path4);
117555
117828
  const dbAdapter = await swarmMail.getDatabase();
117556
117829
  cachedAdapter2 = await createMemoryAdapter2(dbAdapter);
117557
117830
  cachedProjectPath2 = path4;
@@ -118676,7 +118949,7 @@ var swarm_spawn_subtask2 = tool3({
118676
118949
  const filesJoined = args3.files.map((f) => `"${f}"`).join(", ");
118677
118950
  const postCompletionInstructions = COORDINATOR_POST_WORKER_CHECKLIST2.replace(/{project_key}/g, args3.project_path || "$PWD").replace(/{epic_id}/g, args3.epic_id).replace(/{task_id}/g, args3.bead_id).replace(/{files_touched}/g, filesJoined).replace(/{worker_id}/g, "worker");
118678
118951
  try {
118679
- captureCoordinatorEvent3({
118952
+ captureCoordinatorEvent4({
118680
118953
  session_id: _ctx.sessionID || "unknown",
118681
118954
  epic_id: args3.epic_id,
118682
118955
  timestamp: new Date().toISOString(),
@@ -119010,9 +119283,9 @@ var promptTools2 = {
119010
119283
  };
119011
119284
  // src/swarm-research.ts
119012
119285
  init_dist2();
119013
- import { existsSync as existsSync15 } from "node:fs";
119286
+ import { existsSync as existsSync18 } from "node:fs";
119014
119287
  import { readFile as readFile3 } from "node:fs/promises";
119015
- import { join as join20 } from "node:path";
119288
+ import { join as join23 } from "node:path";
119016
119289
 
119017
119290
  // ../../node_modules/.bun/yaml@2.8.2/node_modules/yaml/dist/index.js
119018
119291
  var composer = require_composer();
@@ -119190,21 +119463,21 @@ async function parsePackageJson(packageJsonPath, packages) {
119190
119463
  }
119191
119464
  }
119192
119465
  async function getInstalledVersions(projectPath, packages, checkUpgrades = false) {
119193
- const npmLock = join20(projectPath, "package-lock.json");
119466
+ const npmLock = join23(projectPath, "package-lock.json");
119194
119467
  let versions2 = [];
119195
- if (existsSync15(npmLock)) {
119468
+ if (existsSync18(npmLock)) {
119196
119469
  versions2 = await parseNpmLockfile(npmLock, packages);
119197
119470
  } else {
119198
- const pnpmLock = join20(projectPath, "pnpm-lock.yaml");
119199
- if (existsSync15(pnpmLock)) {
119471
+ const pnpmLock = join23(projectPath, "pnpm-lock.yaml");
119472
+ if (existsSync18(pnpmLock)) {
119200
119473
  versions2 = await parsePnpmLockfile(pnpmLock, packages);
119201
119474
  } else {
119202
- const yarnLock = join20(projectPath, "yarn.lock");
119203
- if (existsSync15(yarnLock)) {
119475
+ const yarnLock = join23(projectPath, "yarn.lock");
119476
+ if (existsSync18(yarnLock)) {
119204
119477
  versions2 = await parseYarnLockfile(yarnLock, packages);
119205
119478
  } else {
119206
- const packageJson = join20(projectPath, "package.json");
119207
- if (existsSync15(packageJson)) {
119479
+ const packageJson = join23(projectPath, "package.json");
119480
+ if (existsSync18(packageJson)) {
119208
119481
  versions2 = await parsePackageJson(packageJson, packages);
119209
119482
  }
119210
119483
  }
@@ -120346,16 +120619,16 @@ var mandateTools = {
120346
120619
  // src/hivemind-tools.ts
120347
120620
  init_dist2();
120348
120621
  import {
120349
- getSwarmMailLibSQL as getSwarmMailLibSQL15,
120622
+ getSwarmMailLibSQL as getSwarmMailLibSQL16,
120350
120623
  createEvent as createEvent10,
120351
120624
  SessionIndexer,
120352
120625
  syncMemories as syncMemories4,
120353
120626
  toSwarmDb as toSwarmDb3,
120354
120627
  makeOllamaLive as makeOllamaLive3
120355
120628
  } from "swarm-mail";
120356
- import * as os4 from "node:os";
120357
- import * as path8 from "node:path";
120358
- import { join as join23 } from "node:path";
120629
+ import * as os5 from "node:os";
120630
+ import * as path10 from "node:path";
120631
+ import { join as join26 } from "node:path";
120359
120632
  var cachedAdapter3 = null;
120360
120633
  var cachedIndexer = null;
120361
120634
  var cachedProjectPath3 = null;
@@ -120364,7 +120637,7 @@ async function getMemoryAdapter3(projectPath) {
120364
120637
  if (cachedAdapter3 && cachedProjectPath3 === path4) {
120365
120638
  return cachedAdapter3;
120366
120639
  }
120367
- const swarmMail = await getSwarmMailLibSQL15(path4);
120640
+ const swarmMail = await getSwarmMailLibSQL16(path4);
120368
120641
  const dbAdapter = await swarmMail.getDatabase();
120369
120642
  cachedAdapter3 = await createMemoryAdapter2(dbAdapter);
120370
120643
  cachedProjectPath3 = path4;
@@ -120375,7 +120648,7 @@ async function getSessionIndexer(projectPath) {
120375
120648
  if (cachedIndexer && cachedProjectPath3 === path4) {
120376
120649
  return cachedIndexer;
120377
120650
  }
120378
- const swarmMail = await getSwarmMailLibSQL15(path4);
120651
+ const swarmMail = await getSwarmMailLibSQL16(path4);
120379
120652
  const dbAdapter = await swarmMail.getDatabase();
120380
120653
  const db = toSwarmDb3(dbAdapter);
120381
120654
  const ollamaLayer = makeOllamaLive3({
@@ -120390,7 +120663,7 @@ var getHivemindAdapter = getMemoryAdapter3;
120390
120663
  async function emitEvent(eventType, data) {
120391
120664
  try {
120392
120665
  const projectPath = cachedProjectPath3 || process.cwd();
120393
- const swarmMail = await getSwarmMailLibSQL15(projectPath);
120666
+ const swarmMail = await getSwarmMailLibSQL16(projectPath);
120394
120667
  const event = createEvent10(eventType, {
120395
120668
  project_key: projectPath,
120396
120669
  ...data
@@ -120399,11 +120672,11 @@ async function emitEvent(eventType, data) {
120399
120672
  } catch {}
120400
120673
  }
120401
120674
  var AGENT_DIRECTORIES = [
120402
- path8.join(os4.homedir(), ".config", "swarm-tools", "sessions"),
120403
- path8.join(os4.homedir(), ".opencode"),
120404
- path8.join(os4.homedir(), "Cursor", "User", "History"),
120405
- path8.join(os4.homedir(), ".local", "share", "Claude"),
120406
- path8.join(os4.homedir(), ".aider")
120675
+ path10.join(os5.homedir(), ".config", "swarm-tools", "sessions"),
120676
+ path10.join(os5.homedir(), ".opencode"),
120677
+ path10.join(os5.homedir(), "Cursor", "User", "History"),
120678
+ path10.join(os5.homedir(), ".local", "share", "Claude"),
120679
+ path10.join(os5.homedir(), ".aider")
120407
120680
  ];
120408
120681
  var hivemind_store = tool3({
120409
120682
  description: "Store a memory (learning, decision, pattern) with semantic embedding. Memories are searchable by semantic similarity and organized into collections. Use collection='default' for manual learnings.",
@@ -120560,9 +120833,9 @@ var hivemind_sync = tool3({
120560
120833
  async execute(args3, ctx) {
120561
120834
  try {
120562
120835
  const projectPath = cachedProjectPath3 || process.cwd();
120563
- const swarmMail = await getSwarmMailLibSQL15(projectPath);
120836
+ const swarmMail = await getSwarmMailLibSQL16(projectPath);
120564
120837
  const dbAdapter = await swarmMail.getDatabase();
120565
- const hiveDir = join23(projectPath, ".hive");
120838
+ const hiveDir = join26(projectPath, ".hive");
120566
120839
  const result = await syncMemories4(dbAdapter, hiveDir);
120567
120840
  await emitEvent("memories_synced", {
120568
120841
  imported: result.imported.created,
@@ -120632,6 +120905,370 @@ var hivemindTools = {
120632
120905
  cass_stats
120633
120906
  };
120634
120907
 
120908
+ // src/observability-tools.ts
120909
+ init_dist2();
120910
+ import {
120911
+ agentActivity as agentActivity2,
120912
+ checkpointFrequency as checkpointFrequency2,
120913
+ failedDecompositions as failedDecompositions2,
120914
+ getSwarmMailLibSQL as getSwarmMailLibSQL17,
120915
+ humanFeedback as humanFeedback2,
120916
+ lockContention as lockContention2,
120917
+ messageLatency as messageLatency2,
120918
+ recoverySuccess as recoverySuccess2,
120919
+ scopeViolations as scopeViolations2,
120920
+ strategySuccessRates as strategySuccessRates2,
120921
+ taskDuration as taskDuration2
120922
+ } from "swarm-mail";
120923
+ function parseSince2(since) {
120924
+ const now = Date.now();
120925
+ const match12 = since.match(/^(\d+)([dhm])$/);
120926
+ if (!match12) {
120927
+ throw new Error(`Invalid since format: ${since}. Use "7d", "24h", or "1h"`);
120928
+ }
120929
+ const [, value, unit] = match12;
120930
+ const num = Number.parseInt(value, 10);
120931
+ switch (unit) {
120932
+ case "d":
120933
+ return now - num * 24 * 60 * 60 * 1000;
120934
+ case "h":
120935
+ return now - num * 60 * 60 * 1000;
120936
+ case "m":
120937
+ return now - num * 60 * 1000;
120938
+ default:
120939
+ throw new Error(`Unknown unit: ${unit}`);
120940
+ }
120941
+ }
120942
+ async function executeQuery3(swarmMail, query) {
120943
+ const db = await swarmMail.getDatabase();
120944
+ const result = await db.query(query.sql, Object.values(query.parameters || {}));
120945
+ return result.rows;
120946
+ }
120947
+ function formatSummary2(queryType, results) {
120948
+ if (results.length === 0) {
120949
+ return `No ${queryType} data found.`;
120950
+ }
120951
+ const count = results.length;
120952
+ const preview = results.slice(0, 3);
120953
+ return `${queryType}: ${count} result(s). Top 3: ${JSON.stringify(preview, null, 2).slice(0, 400)}`;
120954
+ }
120955
+ function capResults2(results) {
120956
+ return results.slice(0, 50);
120957
+ }
120958
+ var swarm_analytics2 = tool3({
120959
+ description: "Query pre-built analytics for swarm coordination. Returns structured data about failed decompositions, strategy success rates, lock contention, agent activity, message latency, scope violations, task duration, checkpoint frequency, recovery success, and human feedback.",
120960
+ args: {
120961
+ query: tool3.schema.enum([
120962
+ "failed-decompositions",
120963
+ "strategy-success-rates",
120964
+ "lock-contention",
120965
+ "agent-activity",
120966
+ "message-latency",
120967
+ "scope-violations",
120968
+ "task-duration",
120969
+ "checkpoint-frequency",
120970
+ "recovery-success",
120971
+ "human-feedback"
120972
+ ]).describe("Type of analytics query to run"),
120973
+ since: tool3.schema.string().optional().describe("Time filter: '7d', '24h', '1h' (optional)"),
120974
+ format: tool3.schema.enum(["json", "summary"]).optional().describe("Output format: 'json' (default) or 'summary' (context-efficient)")
120975
+ },
120976
+ async execute(args3) {
120977
+ try {
120978
+ const projectPath = process.cwd();
120979
+ const db = await getSwarmMailLibSQL17(projectPath);
120980
+ const filters = {
120981
+ project_key: projectPath
120982
+ };
120983
+ if (args3.since) {
120984
+ filters.since = parseSince2(args3.since);
120985
+ }
120986
+ let query;
120987
+ switch (args3.query) {
120988
+ case "failed-decompositions":
120989
+ query = failedDecompositions2(filters);
120990
+ break;
120991
+ case "strategy-success-rates":
120992
+ query = strategySuccessRates2(filters);
120993
+ break;
120994
+ case "lock-contention":
120995
+ query = lockContention2(filters);
120996
+ break;
120997
+ case "agent-activity":
120998
+ query = agentActivity2(filters);
120999
+ break;
121000
+ case "message-latency":
121001
+ query = messageLatency2(filters);
121002
+ break;
121003
+ case "scope-violations":
121004
+ query = scopeViolations2.buildQuery ? scopeViolations2.buildQuery(filters) : scopeViolations2;
121005
+ break;
121006
+ case "task-duration":
121007
+ query = taskDuration2.buildQuery ? taskDuration2.buildQuery(filters) : taskDuration2;
121008
+ break;
121009
+ case "checkpoint-frequency":
121010
+ query = checkpointFrequency2.buildQuery ? checkpointFrequency2.buildQuery(filters) : checkpointFrequency2;
121011
+ break;
121012
+ case "recovery-success":
121013
+ query = recoverySuccess2.buildQuery ? recoverySuccess2.buildQuery(filters) : recoverySuccess2;
121014
+ break;
121015
+ case "human-feedback":
121016
+ query = humanFeedback2.buildQuery ? humanFeedback2.buildQuery(filters) : humanFeedback2;
121017
+ break;
121018
+ default:
121019
+ return JSON.stringify({
121020
+ error: `Unknown query type: ${args3.query}`
121021
+ });
121022
+ }
121023
+ const results = await executeQuery3(db, query);
121024
+ if (args3.format === "summary") {
121025
+ return formatSummary2(args3.query, results);
121026
+ }
121027
+ return JSON.stringify({
121028
+ query: args3.query,
121029
+ filters,
121030
+ count: results.length,
121031
+ results
121032
+ }, null, 2);
121033
+ } catch (error54) {
121034
+ return JSON.stringify({
121035
+ error: error54 instanceof Error ? error54.message : String(error54)
121036
+ });
121037
+ }
121038
+ }
121039
+ });
121040
+ var swarm_query2 = tool3({
121041
+ description: "Execute raw SQL queries against the swarm event store. Context-safe: results capped at 50 rows. Useful for custom analytics and debugging.",
121042
+ args: {
121043
+ sql: tool3.schema.string().describe("SQL query to execute (SELECT only for safety)"),
121044
+ format: tool3.schema.enum(["json", "table"]).optional().describe("Output format: 'json' (default) or 'table' (visual)")
121045
+ },
121046
+ async execute(args3) {
121047
+ try {
121048
+ const projectPath = process.cwd();
121049
+ const swarmMail = await getSwarmMailLibSQL17(projectPath);
121050
+ const db = await swarmMail.getDatabase();
121051
+ if (!args3.sql.trim().toLowerCase().startsWith("select")) {
121052
+ return JSON.stringify({
121053
+ error: "Only SELECT queries are allowed for safety"
121054
+ });
121055
+ }
121056
+ const result = await db.query(args3.sql, []);
121057
+ const rows = result.rows;
121058
+ const cappedRows = capResults2(rows);
121059
+ if (args3.format === "table") {
121060
+ if (cappedRows.length === 0) {
121061
+ return "No results";
121062
+ }
121063
+ const headers = Object.keys(cappedRows[0]);
121064
+ const headerRow = headers.join(" | ");
121065
+ const separator = headers.map(() => "---").join(" | ");
121066
+ const dataRows = cappedRows.map((row) => headers.map((h) => row[h]).join(" | "));
121067
+ return [headerRow, separator, ...dataRows].join(`
121068
+ `);
121069
+ }
121070
+ return JSON.stringify({
121071
+ count: cappedRows.length,
121072
+ total: rows.length,
121073
+ capped: rows.length > 50,
121074
+ results: cappedRows
121075
+ }, null, 2);
121076
+ } catch (error54) {
121077
+ return JSON.stringify({
121078
+ error: error54 instanceof Error ? error54.message : String(error54)
121079
+ });
121080
+ }
121081
+ }
121082
+ });
121083
+ var swarm_diagnose2 = tool3({
121084
+ description: "Auto-diagnose issues for a specific epic or task. Returns structured diagnosis with blockers, conflicts, slow tasks, errors, and timeline.",
121085
+ args: {
121086
+ epic_id: tool3.schema.string().optional().describe("Epic ID to diagnose"),
121087
+ bead_id: tool3.schema.string().optional().describe("Task ID to diagnose"),
121088
+ include: tool3.schema.array(tool3.schema.enum([
121089
+ "blockers",
121090
+ "conflicts",
121091
+ "slow_tasks",
121092
+ "errors",
121093
+ "timeline"
121094
+ ])).optional().describe("What to include in diagnosis (default: all)")
121095
+ },
121096
+ async execute(args3) {
121097
+ try {
121098
+ const projectPath = process.cwd();
121099
+ const swarmMail = await getSwarmMailLibSQL17(projectPath);
121100
+ const db = await swarmMail.getDatabase();
121101
+ const diagnosis = [];
121102
+ const include = args3.include || [
121103
+ "blockers",
121104
+ "conflicts",
121105
+ "slow_tasks",
121106
+ "errors",
121107
+ "timeline"
121108
+ ];
121109
+ if (include.includes("blockers")) {
121110
+ const blockerQuery = `
121111
+ SELECT json_extract(data, '$.agent_name') as agent,
121112
+ json_extract(data, '$.bead_id') as bead_id,
121113
+ timestamp
121114
+ FROM events
121115
+ WHERE type = 'task_blocked'
121116
+ ${args3.epic_id ? "AND json_extract(data, '$.epic_id') = ?" : ""}
121117
+ ${args3.bead_id ? "AND json_extract(data, '$.bead_id') = ?" : ""}
121118
+ ORDER BY timestamp DESC
121119
+ LIMIT 10
121120
+ `;
121121
+ const params = [];
121122
+ if (args3.epic_id)
121123
+ params.push(args3.epic_id);
121124
+ if (args3.bead_id)
121125
+ params.push(args3.bead_id);
121126
+ const blockers = await db.query(blockerQuery, params);
121127
+ if (blockers.rows.length > 0) {
121128
+ diagnosis.push({
121129
+ type: "blockers",
121130
+ message: `Found ${blockers.rows.length} blocked task(s)`,
121131
+ severity: "high"
121132
+ });
121133
+ }
121134
+ }
121135
+ if (include.includes("errors")) {
121136
+ const errorQuery = `
121137
+ SELECT type, json_extract(data, '$.success') as success
121138
+ FROM events
121139
+ WHERE type = 'subtask_outcome'
121140
+ AND json_extract(data, '$.success') = 0
121141
+ ${args3.epic_id ? "AND json_extract(data, '$.epic_id') = ?" : ""}
121142
+ ${args3.bead_id ? "AND json_extract(data, '$.bead_id') = ?" : ""}
121143
+ LIMIT 10
121144
+ `;
121145
+ const params = [];
121146
+ if (args3.epic_id)
121147
+ params.push(args3.epic_id);
121148
+ if (args3.bead_id)
121149
+ params.push(args3.bead_id);
121150
+ const errors4 = await db.query(errorQuery, params);
121151
+ if (errors4.rows.length > 0) {
121152
+ diagnosis.push({
121153
+ type: "errors",
121154
+ message: `Found ${errors4.rows.length} failed task(s)`,
121155
+ severity: "high"
121156
+ });
121157
+ }
121158
+ }
121159
+ let timeline = [];
121160
+ if (include.includes("timeline")) {
121161
+ const timelineQuery = `
121162
+ SELECT timestamp, type, json_extract(data, '$.agent_name') as agent
121163
+ FROM events
121164
+ ${args3.epic_id ? "WHERE json_extract(data, '$.epic_id') = ?" : ""}
121165
+ ${args3.bead_id ? (args3.epic_id ? "AND" : "WHERE") + " json_extract(data, '$.bead_id') = ?" : ""}
121166
+ ORDER BY timestamp DESC
121167
+ LIMIT 20
121168
+ `;
121169
+ const params = [];
121170
+ if (args3.epic_id)
121171
+ params.push(args3.epic_id);
121172
+ if (args3.bead_id)
121173
+ params.push(args3.bead_id);
121174
+ const events = await db.query(timelineQuery, params);
121175
+ timeline = events.rows;
121176
+ }
121177
+ return JSON.stringify({
121178
+ epic_id: args3.epic_id,
121179
+ bead_id: args3.bead_id,
121180
+ diagnosis,
121181
+ timeline: include.includes("timeline") ? timeline : undefined
121182
+ }, null, 2);
121183
+ } catch (error54) {
121184
+ return JSON.stringify({
121185
+ error: error54 instanceof Error ? error54.message : String(error54)
121186
+ });
121187
+ }
121188
+ }
121189
+ });
121190
+ var swarm_insights2 = tool3({
121191
+ description: "Generate learning insights from swarm coordination metrics. Analyzes success rates, duration, conflicts, and retries to provide actionable recommendations.",
121192
+ args: {
121193
+ scope: tool3.schema.enum(["epic", "project", "recent"]).describe("Scope of analysis: 'epic', 'project', or 'recent'"),
121194
+ epic_id: tool3.schema.string().optional().describe("Epic ID (required if scope='epic')"),
121195
+ metrics: tool3.schema.array(tool3.schema.enum([
121196
+ "success_rate",
121197
+ "avg_duration",
121198
+ "conflict_rate",
121199
+ "retry_rate"
121200
+ ])).describe("Metrics to analyze")
121201
+ },
121202
+ async execute(args3) {
121203
+ try {
121204
+ if (args3.scope === "epic" && !args3.epic_id) {
121205
+ return JSON.stringify({
121206
+ error: "epic_id is required when scope='epic'"
121207
+ });
121208
+ }
121209
+ const projectPath = process.cwd();
121210
+ const swarmMail = await getSwarmMailLibSQL17(projectPath);
121211
+ const db = await swarmMail.getDatabase();
121212
+ const insights = [];
121213
+ if (args3.metrics.includes("success_rate")) {
121214
+ const query = `
121215
+ SELECT
121216
+ SUM(CASE WHEN json_extract(data, '$.success') = 1 THEN 1 ELSE 0 END) as successes,
121217
+ COUNT(*) as total
121218
+ FROM events
121219
+ WHERE type = 'subtask_outcome'
121220
+ ${args3.epic_id ? "AND json_extract(data, '$.epic_id') = ?" : ""}
121221
+ `;
121222
+ const result = await db.query(query, args3.epic_id ? [args3.epic_id] : []);
121223
+ const row = result.rows[0];
121224
+ if (row && row.total > 0) {
121225
+ const rate = row.successes / row.total * 100;
121226
+ insights.push({
121227
+ metric: "success_rate",
121228
+ value: `${rate.toFixed(1)}%`,
121229
+ insight: rate < 50 ? "Low success rate - review decomposition strategy" : rate < 80 ? "Moderate success rate - monitor for patterns" : "Good success rate - maintain current approach"
121230
+ });
121231
+ }
121232
+ }
121233
+ if (args3.metrics.includes("avg_duration")) {
121234
+ const query = `
121235
+ SELECT AVG(CAST(json_extract(data, '$.duration_ms') AS REAL)) as avg_duration
121236
+ FROM events
121237
+ WHERE type = 'subtask_outcome'
121238
+ AND json_extract(data, '$.success') = 1
121239
+ AND json_extract(data, '$.duration_ms') IS NOT NULL
121240
+ ${args3.epic_id ? "AND json_extract(data, '$.epic_id') = ?" : ""}
121241
+ `;
121242
+ const result = await db.query(query, args3.epic_id ? [args3.epic_id] : []);
121243
+ const row = result.rows[0];
121244
+ if (row?.avg_duration) {
121245
+ const avgMinutes = (row.avg_duration / 60000).toFixed(1);
121246
+ insights.push({
121247
+ metric: "avg_duration",
121248
+ value: `${avgMinutes} min`,
121249
+ insight: row.avg_duration > 600000 ? "Tasks taking >10min - consider smaller decomposition" : "Task duration is reasonable"
121250
+ });
121251
+ }
121252
+ }
121253
+ return JSON.stringify({
121254
+ scope: args3.scope,
121255
+ epic_id: args3.epic_id,
121256
+ insights
121257
+ }, null, 2);
121258
+ } catch (error54) {
121259
+ return JSON.stringify({
121260
+ error: error54 instanceof Error ? error54.message : String(error54)
121261
+ });
121262
+ }
121263
+ }
121264
+ });
121265
+ var observabilityTools = {
121266
+ swarm_analytics: swarm_analytics2,
121267
+ swarm_query: swarm_query2,
121268
+ swarm_diagnose: swarm_diagnose2,
121269
+ swarm_insights: swarm_insights2
121270
+ };
121271
+
120635
121272
  // src/contributor-tools.ts
120636
121273
  init_dist2();
120637
121274
  init_zod3();
@@ -120732,13 +121369,13 @@ import { checkSwarmHealth as checkSwarmHealth4 } from "swarm-mail";
120732
121369
 
120733
121370
  // src/logger.ts
120734
121371
  var import_pino = __toESM(require_pino(), 1);
120735
- import { mkdirSync as mkdirSync8, existsSync as existsSync16 } from "node:fs";
120736
- import { join as join25 } from "node:path";
120737
- import { homedir as homedir8 } from "node:os";
120738
- var DEFAULT_LOG_DIR = join25(homedir8(), ".config", "swarm-tools", "logs");
121372
+ import { mkdirSync as mkdirSync10, existsSync as existsSync19 } from "node:fs";
121373
+ import { join as join27 } from "node:path";
121374
+ import { homedir as homedir9 } from "node:os";
121375
+ var DEFAULT_LOG_DIR = join27(homedir9(), ".config", "swarm-tools", "logs");
120739
121376
  function ensureLogDir(logDir) {
120740
- if (!existsSync16(logDir)) {
120741
- mkdirSync8(logDir, { recursive: true });
121377
+ if (!existsSync19(logDir)) {
121378
+ mkdirSync10(logDir, { recursive: true });
120742
121379
  }
120743
121380
  }
120744
121381
  var loggerCache = new Map;
@@ -120754,7 +121391,7 @@ function getLogger(logDir = DEFAULT_LOG_DIR) {
120754
121391
  let logger;
120755
121392
  if (process.env.SWARM_LOG_FILE === "1") {
120756
121393
  ensureLogDir(logDir);
120757
- const logPath = join25(logDir, "swarm.log");
121394
+ const logPath = join27(logDir, "swarm.log");
120758
121395
  logger = import_pino.default(baseConfig, import_pino.default.destination({ dest: logPath, sync: false }));
120759
121396
  } else {
120760
121397
  logger = import_pino.default(baseConfig);
@@ -120911,16 +121548,16 @@ import {
120911
121548
  viewSessionLine,
120912
121549
  SessionIndexer as SessionIndexer2,
120913
121550
  createEvent as createEvent11,
120914
- getSwarmMailLibSQL as getSwarmMailLibSQL16
121551
+ getSwarmMailLibSQL as getSwarmMailLibSQL18
120915
121552
  } from "swarm-mail";
120916
- import * as os5 from "node:os";
120917
- import * as path9 from "node:path";
121553
+ import * as os6 from "node:os";
121554
+ import * as path11 from "node:path";
120918
121555
  var AGENT_DIRECTORIES2 = [
120919
- path9.join(os5.homedir(), ".config", "swarm-tools", "sessions"),
120920
- path9.join(os5.homedir(), ".opencode"),
120921
- path9.join(os5.homedir(), "Cursor", "User", "History"),
120922
- path9.join(os5.homedir(), ".local", "share", "Claude"),
120923
- path9.join(os5.homedir(), ".aider")
121556
+ path11.join(os6.homedir(), ".config", "swarm-tools", "sessions"),
121557
+ path11.join(os6.homedir(), ".opencode"),
121558
+ path11.join(os6.homedir(), "Cursor", "User", "History"),
121559
+ path11.join(os6.homedir(), ".local", "share", "Claude"),
121560
+ path11.join(os6.homedir(), ".aider")
120924
121561
  ];
120925
121562
  async function getSessionIndexer2() {
120926
121563
  const db = await getDb();
@@ -120933,7 +121570,7 @@ async function getSessionIndexer2() {
120933
121570
  async function emitEvent2(eventType, data) {
120934
121571
  try {
120935
121572
  const projectPath = process.cwd();
120936
- const swarmMail = await getSwarmMailLibSQL16(projectPath);
121573
+ const swarmMail = await getSwarmMailLibSQL18(projectPath);
120937
121574
  const event = createEvent11(eventType, {
120938
121575
  project_key: projectPath,
120939
121576
  ...data
@@ -121157,9 +121794,9 @@ var allTools = {
121157
121794
  };
121158
121795
 
121159
121796
  // bin/swarm.ts
121160
- var __dirname2 = dirname7(fileURLToPath3(import.meta.url));
121161
- var pkgPath = join27(__dirname2, "..", "..", "package.json");
121162
- var pkg = JSON.parse(readFileSync13(pkgPath, "utf-8"));
121797
+ var __dirname2 = dirname9(fileURLToPath3(import.meta.url));
121798
+ var pkgPath = join29(__dirname2, "..", "..", "package.json");
121799
+ var pkg = JSON.parse(readFileSync16(pkgPath, "utf-8"));
121163
121800
  var VERSION = pkg.version;
121164
121801
  var BEE = `
121165
121802
  \\ \` - ' /
@@ -121169,12 +121806,12 @@ var BEE = `
121169
121806
  (_| |_) bzzzz...
121170
121807
  `;
121171
121808
  var BANNER = `
121172
- ███████╗██╗ ██╗ █████╗ ██████╗ ███╗ ███╗
121173
- ██╔════╝██║ ██║██╔══██╗██╔══██╗████╗ ████║
121174
- ███████╗██║ █╗ ██║███████║██████╔╝██╔████╔██║
121175
- ╚════██║██║███╗██║██╔══██║██╔══██╗██║╚██╔╝██║
121176
- ███████║╚███╔███╔╝██║ ██║██║ ██║██║ ╚═╝ ██║
121177
- ╚══════╝ ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝
121809
+ \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557
121810
+ \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551
121811
+ \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551
121812
+ \u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551
121813
+ \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2554\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551
121814
+ \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u255D\u255A\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D
121178
121815
  `;
121179
121816
  var TAGLINE = "Multi-agent coordination for OpenCode";
121180
121817
  var dim = (s) => `\x1B[2m${s}\x1B[0m`;
@@ -121186,29 +121823,29 @@ var red = (s) => `\x1B[31m${s}\x1B[0m`;
121186
121823
  var bold = (s) => `\x1B[1m${s}\x1B[0m`;
121187
121824
  var PACKAGE_NAME = "opencode-swarm-plugin";
121188
121825
  function writeFileWithStatus(path4, content, label) {
121189
- const exists4 = existsSync17(path4);
121826
+ const exists4 = existsSync20(path4);
121190
121827
  if (exists4) {
121191
- const current = readFileSync13(path4, "utf-8");
121828
+ const current = readFileSync16(path4, "utf-8");
121192
121829
  if (current === content) {
121193
121830
  p.log.message(dim(` ${label}: ${path4} (unchanged)`));
121194
121831
  return "unchanged";
121195
121832
  }
121196
121833
  }
121197
- writeFileSync6(path4, content);
121834
+ writeFileSync7(path4, content);
121198
121835
  const status = exists4 ? "updated" : "created";
121199
121836
  p.log.success(`${label}: ${path4} (${status})`);
121200
121837
  return status;
121201
121838
  }
121202
121839
  function mkdirWithStatus(path4) {
121203
- if (!existsSync17(path4)) {
121204
- mkdirSync9(path4, { recursive: true });
121840
+ if (!existsSync20(path4)) {
121841
+ mkdirSync11(path4, { recursive: true });
121205
121842
  p.log.message(dim(` Created directory: ${path4}`));
121206
121843
  return true;
121207
121844
  }
121208
121845
  return false;
121209
121846
  }
121210
121847
  function rmWithStatus(path4, label) {
121211
- if (existsSync17(path4)) {
121848
+ if (existsSync20(path4)) {
121212
121849
  rmSync(path4);
121213
121850
  p.log.message(dim(` Removed ${label}: ${path4}`));
121214
121851
  }
@@ -121239,7 +121876,7 @@ function getSeasonalBee() {
121239
121876
  `Kicking off ${year} with coordinated chaos!`,
121240
121877
  `Happy ${year}! Time to orchestrate some magic.`
121241
121878
  ],
121242
- decorations: ["\uD83C\uDF89", "\uD83C\uDF8A", ""]
121879
+ decorations: ["\uD83C\uDF89", "\uD83C\uDF8A", "\u2728"]
121243
121880
  };
121244
121881
  case "spooky":
121245
121882
  return {
@@ -121250,7 +121887,7 @@ function getSeasonalBee() {
121250
121887
  `Let's conjure up a swarm of worker bees!`,
121251
121888
  `Something wicked this way computes...`
121252
121889
  ],
121253
- decorations: ["\uD83C\uDF83", "\uD83D\uDC7B", "\uD83D\uDD77", "\uD83E\uDD87"]
121890
+ decorations: ["\uD83C\uDF83", "\uD83D\uDC7B", "\uD83D\uDD77\uFE0F", "\uD83E\uDD87"]
121254
121891
  };
121255
121892
  case "holiday":
121256
121893
  return {
@@ -121261,7 +121898,7 @@ function getSeasonalBee() {
121261
121898
  `Jingle bells, agents swell, tasks get done today!`,
121262
121899
  `The best gift? A well-coordinated swarm.`
121263
121900
  ],
121264
- decorations: ["\uD83C\uDF84", "\uD83C\uDF81", "❄️", ""]
121901
+ decorations: ["\uD83C\uDF84", "\uD83C\uDF81", "\u2744\uFE0F", "\u2B50"]
121265
121902
  };
121266
121903
  case "summer":
121267
121904
  return {
@@ -121271,7 +121908,7 @@ function getSeasonalBee() {
121271
121908
  `Hot code, cool agents. Let's go!`,
121272
121909
  `Beach day? Nah, build day!`
121273
121910
  ],
121274
- decorations: ["☀️", "\uD83C\uDF3B", "\uD83C\uDF34"]
121911
+ decorations: ["\u2600\uFE0F", "\uD83C\uDF3B", "\uD83C\uDF34"]
121275
121912
  };
121276
121913
  default:
121277
121914
  return {
@@ -121377,15 +122014,24 @@ function compareVersions(a, b) {
121377
122014
  function showUpdateNotification(info) {
121378
122015
  if (info.updateAvailable) {
121379
122016
  console.log();
121380
- console.log(yellow(" ╭─────────────────────────────────────────────────────╮"));
121381
- console.log(yellow(" ") + " Update available! " + dim(info.current) + " " + green(info.latest) + " " + yellow(""));
121382
- console.log(yellow(" ") + " Run: " + cyan("npm install -g " + PACKAGE_NAME + "@latest") + " " + yellow(""));
121383
- console.log(yellow(" ") + " Or: " + cyan("swarm update") + " " + yellow(""));
121384
- console.log(yellow(" ╰─────────────────────────────────────────────────────╯"));
122017
+ console.log(yellow(" \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E"));
122018
+ console.log(yellow(" \u2502") + " Update available! " + dim(info.current) + " \u2192 " + green(info.latest) + " " + yellow("\u2502"));
122019
+ console.log(yellow(" \u2502") + " Run: " + cyan("npm install -g " + PACKAGE_NAME + "@latest") + " " + yellow("\u2502"));
122020
+ console.log(yellow(" \u2502") + " Or: " + cyan("swarm update") + " " + yellow("\u2502"));
122021
+ console.log(yellow(" \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F"));
121385
122022
  console.log();
121386
122023
  }
121387
122024
  }
121388
122025
  var DEPENDENCIES = [
122026
+ {
122027
+ name: "Bun",
122028
+ command: "bun",
122029
+ checkArgs: ["--version"],
122030
+ required: true,
122031
+ install: "curl -fsSL https://bun.sh/install | bash",
122032
+ installType: "manual",
122033
+ description: "JavaScript runtime (required for CLI)"
122034
+ },
121389
122035
  {
121390
122036
  name: "OpenCode",
121391
122037
  command: "opencode",
@@ -121424,33 +122070,47 @@ var DEPENDENCIES = [
121424
122070
  }
121425
122071
  ];
121426
122072
  async function checkCommand(cmd, args3) {
121427
- try {
121428
- const proc = Bun.spawn([cmd, ...args3], {
121429
- stdout: "pipe",
121430
- stderr: "pipe"
121431
- });
121432
- const exitCode = await proc.exited;
121433
- if (exitCode === 0) {
121434
- const output = await new Response(proc.stdout).text();
121435
- const versionMatch = output.match(/v?(\d+\.\d+\.\d+)/);
121436
- return { available: true, version: versionMatch?.[1] };
122073
+ return new Promise((resolve3) => {
122074
+ try {
122075
+ const proc = spawn(cmd, args3, {
122076
+ stdio: ["ignore", "pipe", "pipe"]
122077
+ });
122078
+ let stdout = "";
122079
+ proc.stdout?.on("data", (data) => {
122080
+ stdout += data.toString();
122081
+ });
122082
+ proc.on("error", () => {
122083
+ resolve3({ available: false });
122084
+ });
122085
+ proc.on("close", (exitCode) => {
122086
+ if (exitCode === 0) {
122087
+ const versionMatch = stdout.match(/v?(\d+\.\d+\.\d+)/);
122088
+ resolve3({ available: true, version: versionMatch?.[1] });
122089
+ } else {
122090
+ resolve3({ available: false });
122091
+ }
122092
+ });
122093
+ } catch {
122094
+ resolve3({ available: false });
121437
122095
  }
121438
- return { available: false };
121439
- } catch {
121440
- return { available: false };
121441
- }
122096
+ });
121442
122097
  }
121443
122098
  async function runInstall(command) {
121444
- try {
121445
- const proc = Bun.spawn(["bash", "-c", command], {
121446
- stdout: "inherit",
121447
- stderr: "inherit"
121448
- });
121449
- const exitCode = await proc.exited;
121450
- return exitCode === 0;
121451
- } catch {
121452
- return false;
121453
- }
122099
+ return new Promise((resolve3) => {
122100
+ try {
122101
+ const proc = spawn("bash", ["-c", command], {
122102
+ stdio: "inherit"
122103
+ });
122104
+ proc.on("error", () => {
122105
+ resolve3(false);
122106
+ });
122107
+ proc.on("close", (exitCode) => {
122108
+ resolve3(exitCode === 0);
122109
+ });
122110
+ } catch {
122111
+ resolve3(false);
122112
+ }
122113
+ });
121454
122114
  }
121455
122115
  async function checkAllDependencies() {
121456
122116
  const results = [];
@@ -121462,7 +122122,7 @@ async function checkAllDependencies() {
121462
122122
  }
121463
122123
  var BUNDLED_SKILL_MARKER_FILENAME = ".swarm-bundled-skill.json";
121464
122124
  function listDirectoryNames(dirPath) {
121465
- if (!existsSync17(dirPath))
122125
+ if (!existsSync20(dirPath))
121466
122126
  return [];
121467
122127
  try {
121468
122128
  return readdirSync2(dirPath, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name).sort();
@@ -121471,11 +122131,11 @@ function listDirectoryNames(dirPath) {
121471
122131
  }
121472
122132
  }
121473
122133
  function copyDirRecursiveSync(srcDir, destDir) {
121474
- mkdirSync9(destDir, { recursive: true });
122134
+ mkdirSync11(destDir, { recursive: true });
121475
122135
  const entries2 = readdirSync2(srcDir, { withFileTypes: true });
121476
122136
  for (const entry of entries2) {
121477
- const srcPath = join27(srcDir, entry.name);
121478
- const destPath = join27(destDir, entry.name);
122137
+ const srcPath = join29(srcDir, entry.name);
122138
+ const destPath = join29(destDir, entry.name);
121479
122139
  if (entry.isDirectory()) {
121480
122140
  copyDirRecursiveSync(srcPath, destPath);
121481
122141
  continue;
@@ -121489,8 +122149,8 @@ function copyDirRecursiveSync(srcDir, destDir) {
121489
122149
  }
121490
122150
  }
121491
122151
  function writeBundledSkillMarker(skillDir, info) {
121492
- const markerPath = join27(skillDir, BUNDLED_SKILL_MARKER_FILENAME);
121493
- writeFileSync6(markerPath, JSON.stringify({
122152
+ const markerPath = join29(skillDir, BUNDLED_SKILL_MARKER_FILENAME);
122153
+ writeFileSync7(markerPath, JSON.stringify({
121494
122154
  managed_by: "opencode-swarm-plugin",
121495
122155
  version: info.version,
121496
122156
  synced_at: new Date().toISOString()
@@ -121506,16 +122166,16 @@ function syncBundledSkillsToGlobal({
121506
122166
  const updated = [];
121507
122167
  const skipped = [];
121508
122168
  for (const name of bundledSkills) {
121509
- const srcSkillDir = join27(bundledSkillsPath, name);
121510
- const destSkillDir = join27(globalSkillsPath, name);
121511
- const markerPath = join27(destSkillDir, BUNDLED_SKILL_MARKER_FILENAME);
121512
- if (!existsSync17(destSkillDir)) {
122169
+ const srcSkillDir = join29(bundledSkillsPath, name);
122170
+ const destSkillDir = join29(globalSkillsPath, name);
122171
+ const markerPath = join29(destSkillDir, BUNDLED_SKILL_MARKER_FILENAME);
122172
+ if (!existsSync20(destSkillDir)) {
121513
122173
  copyDirRecursiveSync(srcSkillDir, destSkillDir);
121514
122174
  writeBundledSkillMarker(destSkillDir, { version: version4 });
121515
122175
  installed.push(name);
121516
122176
  continue;
121517
122177
  }
121518
- if (existsSync17(markerPath)) {
122178
+ if (existsSync20(markerPath)) {
121519
122179
  rmSync(destSkillDir, { recursive: true, force: true });
121520
122180
  copyDirRecursiveSync(srcSkillDir, destSkillDir);
121521
122181
  writeBundledSkillMarker(destSkillDir, { version: version4 });
@@ -121534,10 +122194,10 @@ function detectNewline(content) {
121534
122194
  }
121535
122195
  function backupFileWithTimestamp(filePath) {
121536
122196
  try {
121537
- const dir = dirname7(filePath);
122197
+ const dir = dirname9(filePath);
121538
122198
  const base = basename3(filePath);
121539
122199
  const timestamp = new Date().toISOString().replace(/[:.]/g, "").replace(/Z$/, "Z");
121540
- const backupPath = join27(dir, `${base}.swarm-backup-${timestamp}`);
122200
+ const backupPath = join29(dir, `${base}.swarm-backup-${timestamp}`);
121541
122201
  copyFileSync(filePath, backupPath);
121542
122202
  return backupPath;
121543
122203
  } catch {
@@ -121567,64 +122227,155 @@ function buildAgentsSkillsSection(bundledSkillsCsv, newline) {
121567
122227
  `**Bundled Skills:** ${bundledSkillsCsv}`
121568
122228
  ].join(newline);
121569
122229
  }
121570
- function buildAgentsCassSection(newline) {
122230
+ function buildAgentsHivemindSection(newline) {
121571
122231
  return [
121572
- "## CASS - Cross-Agent Session Search",
122232
+ "## Hivemind - Unified Memory System",
122233
+ "",
122234
+ "The hive remembers everything. Learnings, sessions, patterns\u2014all searchable.",
121573
122235
  "",
121574
- "Search across ALL your AI coding agent histories before solving problems from scratch.",
122236
+ "**Unified storage:** Manual learnings and AI agent session histories stored in the same database, searchable together. Powered by libSQL vectors + Ollama embeddings.",
122237
+ "",
122238
+ "**Indexed agents:** Claude Code, Codex, Cursor, Gemini, Aider, ChatGPT, Cline, OpenCode, Amp, Pi-Agent",
121575
122239
  "",
121576
122240
  "### When to Use",
121577
122241
  "",
121578
- "- **BEFORE implementing anything**: check if any agent solved it before",
121579
- '- **Debugging**: "what did I try last time this error happened?"',
121580
- '- **Learning patterns**: "how did Cursor handle this API?"',
122242
+ "- **BEFORE implementing** - check if you or any agent solved it before",
122243
+ "- **After solving hard problems** - store learnings for future sessions",
122244
+ "- **Debugging** - search past sessions for similar errors",
122245
+ "- **Architecture decisions** - record reasoning, alternatives, tradeoffs",
122246
+ "- **Project-specific patterns** - capture domain rules and gotchas",
122247
+ "",
122248
+ "### Tools",
122249
+ "",
122250
+ "| Tool | Purpose |",
122251
+ "|------|---------|",
122252
+ "| `hivemind_store` | Store a memory (learnings, decisions, patterns) |",
122253
+ "| `hivemind_find` | Search all memories (learnings + sessions, semantic + FTS fallback) |",
122254
+ "| `hivemind_get` | Get specific memory by ID |",
122255
+ "| `hivemind_remove` | Delete outdated/incorrect memory |",
122256
+ "| `hivemind_validate` | Confirm memory still accurate (resets 90-day decay timer) |",
122257
+ "| `hivemind_stats` | Memory statistics and health check |",
122258
+ "| `hivemind_index` | Index AI session directories |",
122259
+ "| `hivemind_sync` | Sync to .hive/memories.jsonl (git-backed, team-shared) |",
121581
122260
  "",
121582
122261
  "### Usage",
121583
122262
  "",
122263
+ "**Store a learning** (include WHY, not just WHAT):",
122264
+ "",
122265
+ "```typescript",
122266
+ "hivemind_store({",
122267
+ ' information: "OAuth refresh tokens need 5min buffer before expiry to avoid race conditions. Without buffer, token refresh can fail mid-request if expiry happens between check and use.",',
122268
+ ' tags: "auth,oauth,tokens,race-conditions"',
122269
+ "})",
122270
+ "```",
122271
+ "",
122272
+ "**Search all memories** (learnings + sessions):",
122273
+ "",
122274
+ "```typescript",
122275
+ "// Search everything",
122276
+ 'hivemind_find({ query: "token refresh", limit: 5 })',
122277
+ "",
122278
+ "// Search only learnings (manual entries)",
122279
+ 'hivemind_find({ query: "authentication", collection: "default" })',
122280
+ "",
122281
+ "// Search only Claude sessions",
122282
+ 'hivemind_find({ query: "Next.js caching", collection: "claude" })',
122283
+ "",
122284
+ "// Search only Cursor sessions",
122285
+ 'hivemind_find({ query: "API design", collection: "cursor" })',
122286
+ "```",
122287
+ "",
122288
+ "**Get specific memory**:",
122289
+ "",
122290
+ "```typescript",
122291
+ 'hivemind_get({ id: "mem_xyz123" })',
122292
+ "```",
122293
+ "",
122294
+ "**Delete outdated memory**:",
122295
+ "",
122296
+ "```typescript",
122297
+ 'hivemind_remove({ id: "mem_old456" })',
122298
+ "```",
122299
+ "",
122300
+ "**Validate memory is still accurate** (resets decay):",
122301
+ "",
122302
+ "```typescript",
122303
+ "// Confirmed this memory is still relevant",
122304
+ 'hivemind_validate({ id: "mem_xyz123" })',
122305
+ "```",
122306
+ "",
122307
+ "**Index new sessions**:",
122308
+ "",
122309
+ "```typescript",
122310
+ "// Automatically indexes ~/.config/opencode/sessions, ~/.cursor-tutor, etc.",
122311
+ "hivemind_index()",
122312
+ "```",
122313
+ "",
122314
+ "**Sync to git**:",
122315
+ "",
122316
+ "```typescript",
122317
+ "// Writes learnings to .hive/memories.jsonl for git sync",
122318
+ "hivemind_sync()",
122319
+ "```",
122320
+ "",
122321
+ "**Check stats**:",
122322
+ "",
122323
+ "```typescript",
122324
+ "hivemind_stats()",
122325
+ "```",
122326
+ "",
122327
+ "### Usage Pattern",
122328
+ "",
121584
122329
  "```bash",
121585
- "# Search all agents",
121586
- 'cass_search(query="authentication token refresh", limit=5)',
122330
+ "# 1. Before starting work - query for relevant learnings",
122331
+ 'hivemind_find({ query: "<task keywords>", limit: 5 })',
121587
122332
  "",
121588
- "# Filter by agent/time",
121589
- 'cass_search(query="useEffect cleanup", agent="claude", days=7)',
122333
+ "# 2. Do the work...",
121590
122334
  "",
121591
- "# View specific result",
121592
- 'cass_view(path="/path/from/search", line=42)',
122335
+ "# 3. After solving hard problem - store learning",
122336
+ "hivemind_store({",
122337
+ ' information: "<what you learned, WHY it matters>",',
122338
+ ' tags: "<relevant,tags>"',
122339
+ "})",
121593
122340
  "",
121594
- "# Expand context around match",
121595
- 'cass_expand(path="/path", line=42, context=10)',
122341
+ "# 4. Validate memories when you confirm they're still accurate",
122342
+ 'hivemind_validate({ id: "<memory-id>" })',
121596
122343
  "```",
121597
122344
  "",
121598
- "**Pro tip:** Query CASS at the START of complex tasks. Past solutions save time."
121599
- ].join(newline);
121600
- }
121601
- function buildAgentsSemanticMemorySection(newline) {
121602
- return [
121603
- "## Semantic Memory - Persistent Learning",
122345
+ "### Integration with Workflow",
121604
122346
  "",
121605
- "Store and retrieve learnings across sessions. Memories persist and are searchable.",
122347
+ "**At task start** (query BEFORE implementing):",
121606
122348
  "",
121607
- "### When to Use",
122349
+ "```bash",
122350
+ "# Check if you or any agent solved similar problems",
122351
+ 'hivemind_find({ query: "OAuth token refresh buffer", limit: 5 })',
122352
+ "```",
121608
122353
  "",
121609
- "- After solving a tricky problem - store the solution",
121610
- "- After making architectural decisions - store the reasoning",
121611
- "- Before starting work - search for relevant past learnings",
121612
- "- When you discover project-specific patterns",
122354
+ "**During debugging** (search past sessions):",
121613
122355
  "",
121614
- "### Usage",
122356
+ "```bash",
122357
+ "# Find similar errors from past sessions",
122358
+ 'hivemind_find({ query: "cannot read property of undefined", collection: "claude" })',
122359
+ "```",
122360
+ "",
122361
+ "**After solving problems** (store learnings):",
121615
122362
  "",
121616
122363
  "```bash",
121617
- "# Store a learning",
121618
- 'semantic-memory_store(information="OAuth refresh tokens need 5min buffer before expiry", metadata="auth, tokens")',
122364
+ '# Store root cause + solution, not just "fixed it"',
122365
+ "hivemind_store({",
122366
+ ' information: "Next.js searchParams causes dynamic rendering. Workaround: destructure in parent, pass as props to cached child.",',
122367
+ ' tags: "nextjs,cache-components,dynamic-rendering,searchparams"',
122368
+ "})",
122369
+ "```",
121619
122370
  "",
121620
- "# Search for relevant memories",
121621
- 'semantic-memory_find(query="token refresh", limit=5)',
122371
+ "**Learning from other agents**:",
121622
122372
  "",
121623
- "# Validate a memory is still accurate (resets decay timer)",
121624
- 'semantic-memory_validate(id="mem_123")',
122373
+ "```bash",
122374
+ "# See how Cursor handled similar feature",
122375
+ 'hivemind_find({ query: "implement authentication", collection: "cursor" })',
121625
122376
  "```",
121626
122377
  "",
121627
- "**Pro tip:** Store the WHY, not just the WHAT. Future you needs context."
122378
+ "**Pro tip:** Query Hivemind at the START of complex tasks. Past solutions (yours or other agents') save time and prevent reinventing wheels."
121628
122379
  ].join(newline);
121629
122380
  }
121630
122381
  function buildAgentsSwarmCoordinatorSection(newline) {
@@ -121636,35 +122387,35 @@ function buildAgentsSwarmCoordinatorSection(newline) {
121636
122387
  "### Monitor Loop",
121637
122388
  "",
121638
122389
  "```",
121639
- "┌─────────────────────────────────────────────────────────────┐",
121640
- " COORDINATOR MONITOR LOOP ",
121641
- "├─────────────────────────────────────────────────────────────┤",
121642
- " ",
121643
- " 1. CHECK INBOX ",
121644
- " swarmmail_inbox() ",
121645
- " swarmmail_read_message(message_id=N) ",
121646
- " ",
121647
- " 2. CHECK STATUS ",
121648
- " swarm_status(epic_id, project_key) ",
121649
- " ",
121650
- " 3. REVIEW COMPLETED WORK ",
121651
- " swarm_review(project_key, epic_id, task_id, files) ",
121652
- " Generates review prompt with epic context + diff ",
121653
- " ",
121654
- " 4. SEND FEEDBACK ",
121655
- " swarm_review_feedback( ",
121656
- " project_key, task_id, worker_id, ",
121657
- ' status="approved|needs_changes", ',
121658
- ' issues="[{file, line, issue, suggestion}]" ',
121659
- " ) ",
121660
- " ",
121661
- " 5. INTERVENE IF NEEDED ",
121662
- " - Blocked >5min unblock or reassign ",
121663
- " - File conflicts mediate ",
121664
- " - Scope creep approve or reject ",
121665
- " - 3 review failures escalate to human ",
121666
- " ",
121667
- "└─────────────────────────────────────────────────────────────┘",
122390
+ "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
122391
+ "\u2502 COORDINATOR MONITOR LOOP \u2502",
122392
+ "\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524",
122393
+ "\u2502 \u2502",
122394
+ "\u2502 1. CHECK INBOX \u2502",
122395
+ "\u2502 swarmmail_inbox() \u2502",
122396
+ "\u2502 swarmmail_read_message(message_id=N) \u2502",
122397
+ "\u2502 \u2502",
122398
+ "\u2502 2. CHECK STATUS \u2502",
122399
+ "\u2502 swarm_status(epic_id, project_key) \u2502",
122400
+ "\u2502 \u2502",
122401
+ "\u2502 3. REVIEW COMPLETED WORK \u2502",
122402
+ "\u2502 swarm_review(project_key, epic_id, task_id, files) \u2502",
122403
+ "\u2502 \u2192 Generates review prompt with epic context + diff \u2502",
122404
+ "\u2502 \u2502",
122405
+ "\u2502 4. SEND FEEDBACK \u2502",
122406
+ "\u2502 swarm_review_feedback( \u2502",
122407
+ "\u2502 project_key, task_id, worker_id, \u2502",
122408
+ '\u2502 status="approved|needs_changes", \u2502',
122409
+ '\u2502 issues="[{file, line, issue, suggestion}]" \u2502',
122410
+ "\u2502 ) \u2502",
122411
+ "\u2502 \u2502",
122412
+ "\u2502 5. INTERVENE IF NEEDED \u2502",
122413
+ "\u2502 - Blocked >5min \u2192 unblock or reassign \u2502",
122414
+ "\u2502 - File conflicts \u2192 mediate \u2502",
122415
+ "\u2502 - Scope creep \u2192 approve or reject \u2502",
122416
+ "\u2502 - 3 review failures \u2192 escalate to human \u2502",
122417
+ "\u2502 \u2502",
122418
+ "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518",
121668
122419
  "```",
121669
122420
  "",
121670
122421
  "### Review Tools",
@@ -121748,27 +122499,59 @@ function updateAgentsMdContent({
121748
122499
  if (updated !== beforeBundled) {
121749
122500
  changes.push("Updated bundled skills list");
121750
122501
  }
122502
+ const hasOldCassTools = /cass_search\(|cass_view\(|cass_expand\(/i.test(updated);
122503
+ const hasOldSemanticTools = /semantic-memory_store\(|semantic-memory_find\(/i.test(updated);
122504
+ const hasHivemindTools = /hivemind_store\(|hivemind_find\(/i.test(updated);
122505
+ if ((hasOldCassTools || hasOldSemanticTools) && !hasHivemindTools) {
122506
+ const beforeMigration = updated;
122507
+ updated = updated.replace(/semantic-memory_store\(/g, "hivemind_store(");
122508
+ updated = updated.replace(/semantic-memory_find\(/g, "hivemind_find(");
122509
+ updated = updated.replace(/semantic-memory_get\(/g, "hivemind_get(");
122510
+ updated = updated.replace(/semantic-memory_remove\(/g, "hivemind_remove(");
122511
+ updated = updated.replace(/semantic-memory_validate\(/g, "hivemind_validate(");
122512
+ updated = updated.replace(/semantic-memory_list\(/g, "hivemind_find(");
122513
+ updated = updated.replace(/semantic-memory_stats\(/g, "hivemind_stats(");
122514
+ updated = updated.replace(/cass_search\(/g, "hivemind_find(");
122515
+ updated = updated.replace(/cass_view\(/g, "hivemind_get(");
122516
+ updated = updated.replace(/cass_expand\(/g, "hivemind_get(");
122517
+ updated = updated.replace(/cass_health\(/g, "hivemind_stats(");
122518
+ updated = updated.replace(/cass_index\(/g, "hivemind_index(");
122519
+ updated = updated.replace(/cass_stats\(/g, "hivemind_stats(");
122520
+ updated = updated.replace(/\| `semantic-memory_store` \|/g, "| `hivemind_store` |");
122521
+ updated = updated.replace(/\| `semantic-memory_find` \|/g, "| `hivemind_find` |");
122522
+ updated = updated.replace(/\| `semantic-memory_get` \|/g, "| `hivemind_get` |");
122523
+ updated = updated.replace(/\| `semantic-memory_remove` \|/g, "| `hivemind_remove` |");
122524
+ updated = updated.replace(/\| `semantic-memory_validate` \|/g, "| `hivemind_validate` |");
122525
+ updated = updated.replace(/\| `semantic-memory_list` \|/g, "| `hivemind_find` |");
122526
+ updated = updated.replace(/\| `semantic-memory_stats` \|/g, "| `hivemind_stats` |");
122527
+ updated = updated.replace(/\| `semantic-memory_migrate` \|/g, "| `hivemind_stats` |");
122528
+ updated = updated.replace(/\| `semantic-memory_check` \|/g, "| `hivemind_stats` |");
122529
+ updated = updated.replace(/\| `cass_search` \|/g, "| `hivemind_find` |");
122530
+ updated = updated.replace(/\| `cass_view` \|/g, "| `hivemind_get` |");
122531
+ updated = updated.replace(/\| `cass_expand` \|/g, "| `hivemind_get` |");
122532
+ updated = updated.replace(/\| `cass_health` \|/g, "| `hivemind_stats` |");
122533
+ updated = updated.replace(/\| `cass_index` \|/g, "| `hivemind_index` |");
122534
+ updated = updated.replace(/\| `cass_stats` \|/g, "| `hivemind_stats` |");
122535
+ if (updated !== beforeMigration) {
122536
+ changes.push("Migrated cass_*/semantic-memory_* to hivemind_* (ADR-011)");
122537
+ }
122538
+ }
121751
122539
  const toolPrefsResult = updateAgentsToolPreferencesBlock(updated, newline);
121752
122540
  if (toolPrefsResult.changed) {
121753
122541
  updated = toolPrefsResult.content;
121754
122542
  changes.push("Updated tool_preferences tool list");
121755
122543
  }
121756
122544
  const hasSkillsSection = /^#{1,6}\s+Skills\b/im.test(updated) || /skills_list\(\)/.test(updated);
121757
- const hasCassSection = /^#{1,6}\s+.*CASS\b/im.test(updated) || /cass_search\(/.test(updated);
121758
- const hasSemanticMemorySection = /^#{1,6}\s+Semantic Memory\b/im.test(updated) || /semantic-memory_store\(/.test(updated);
122545
+ const hasHivemindSection = /^#{1,6}\s+Hivemind\b/im.test(updated) || /hivemind_store\(/.test(updated);
121759
122546
  const hasSwarmCoordinatorSection = /^#{1,6}\s+Swarm Coordinator\b/im.test(updated) || /swarm_review\(/.test(updated) || /COORDINATOR MONITOR LOOP/i.test(updated);
121760
122547
  const sectionsToAppend = [];
121761
122548
  if (!hasSkillsSection) {
121762
122549
  sectionsToAppend.push(buildAgentsSkillsSection(bundledSkillsCsv, newline));
121763
122550
  changes.push("Added Skills section");
121764
122551
  }
121765
- if (!hasCassSection) {
121766
- sectionsToAppend.push(buildAgentsCassSection(newline));
121767
- changes.push("Added CASS section");
121768
- }
121769
- if (!hasSemanticMemorySection) {
121770
- sectionsToAppend.push(buildAgentsSemanticMemorySection(newline));
121771
- changes.push("Added Semantic Memory section");
122552
+ if (!hasHivemindSection) {
122553
+ sectionsToAppend.push(buildAgentsHivemindSection(newline));
122554
+ changes.push("Added Hivemind section (unified memory)");
121772
122555
  }
121773
122556
  if (!hasSwarmCoordinatorSection) {
121774
122557
  sectionsToAppend.push(buildAgentsSwarmCoordinatorSection(newline));
@@ -121788,7 +122571,7 @@ function updateAgentsMdFile({
121788
122571
  agentsPath,
121789
122572
  bundledSkillsCsv
121790
122573
  }) {
121791
- const original = readFileSync13(agentsPath, "utf-8");
122574
+ const original = readFileSync16(agentsPath, "utf-8");
121792
122575
  const { updated, changed, changes } = updateAgentsMdContent({
121793
122576
  content: original,
121794
122577
  bundledSkillsCsv
@@ -121797,13 +122580,13 @@ function updateAgentsMdFile({
121797
122580
  return { changed: false, changes: ["No changes needed"] };
121798
122581
  }
121799
122582
  const backupPath = backupFileWithTimestamp(agentsPath) || undefined;
121800
- writeFileSync6(agentsPath, updated, "utf-8");
122583
+ writeFileSync7(agentsPath, updated, "utf-8");
121801
122584
  return { changed: true, backupPath, changes };
121802
122585
  }
121803
122586
  function getPluginWrapper() {
121804
- const templatePath = join27(__dirname2, "..", "examples", "plugin-wrapper-template.ts");
122587
+ const templatePath = join29(__dirname2, "..", "examples", "plugin-wrapper-template.ts");
121805
122588
  try {
121806
- return readFileSync13(templatePath, "utf-8");
122589
+ return readFileSync16(templatePath, "utf-8");
121807
122590
  } catch (error54) {
121808
122591
  console.warn(`[swarm] Could not read plugin template from ${templatePath}, using minimal wrapper`);
121809
122592
  return `// Minimal fallback - install opencode-swarm-plugin globally for full functionality
@@ -122124,10 +122907,10 @@ bash("ollama --version", description="Check Ollama availability")
122124
122907
 
122125
122908
  **NEVER dump raw documentation.** Always summarize.
122126
122909
 
122127
- | Bad (Context Bomb) | Good (Condensed) |
122910
+ | \u274C Bad (Context Bomb) | \u2705 Good (Condensed) |
122128
122911
  |---------------------|-------------------|
122129
122912
  | Paste entire API reference | "Library uses hooks API. Key hooks: useQuery, useMutation. Breaking change in v2: callbacks removed." |
122130
- | Copy full changelog | "v2.0 breaking changes: renamed auth() authenticate(), dropped IE11 support" |
122913
+ | Copy full changelog | "v2.0 breaking changes: renamed auth() \u2192 authenticate(), dropped IE11 support" |
122131
122914
  | Include all examples | "Common pattern: async/await with error boundaries (stored full example in semantic-memory)" |
122132
122915
 
122133
122916
  **Storage Strategy:**
@@ -122152,7 +122935,7 @@ bash("ollama --version", description="Check Ollama availability")
122152
122935
 
122153
122936
  **"Research Next.js 16 caching APIs"**
122154
122937
 
122155
- 1. Read package.json extract Next.js version
122938
+ 1. Read package.json \u2192 extract Next.js version
122156
122939
  2. Use context7 or fetch to get Next.js 16 cache docs
122157
122940
  3. Store findings: unstable_cache, revalidatePath, cache patterns
122158
122941
  4. Broadcast: "Next.js 16 uses native fetch caching + unstable_cache for functions"
@@ -122185,12 +122968,28 @@ function getFixCommand(dep) {
122185
122968
  return dep.installType !== "manual" ? dep.install : null;
122186
122969
  }
122187
122970
  }
122188
- async function doctor() {
122971
+ async function doctor(debug = false) {
122189
122972
  p.intro("swarm doctor v" + VERSION);
122973
+ if (debug) {
122974
+ p.log.step("Debug info:");
122975
+ p.log.message(dim(` Runtime: ${typeof Bun !== "undefined" ? "Bun" : "Node.js"}`));
122976
+ p.log.message(dim(` Node version: ${process.version}`));
122977
+ p.log.message(dim(` Platform: ${process.platform}`));
122978
+ p.log.message(dim(` Arch: ${process.arch}`));
122979
+ p.log.message(dim(` CWD: ${process.cwd()}`));
122980
+ p.log.message(dim(` PATH entries: ${(process.env.PATH || "").split(":").length}`));
122981
+ }
122190
122982
  const s = p.spinner();
122191
122983
  s.start("Checking dependencies...");
122192
122984
  const results = await checkAllDependencies();
122193
122985
  s.stop("Dependencies checked");
122986
+ if (debug) {
122987
+ p.log.step("Dependency check details:");
122988
+ for (const { dep, available, version: version4 } of results) {
122989
+ const status = available ? green("\u2713") : red("\u2717");
122990
+ p.log.message(dim(` ${status} ${dep.command} ${dep.checkArgs.join(" ")} \u2192 ${available ? `v${version4 || "unknown"}` : "not found"}`));
122991
+ }
122992
+ }
122194
122993
  const required4 = results.filter((r) => r.dep.required);
122195
122994
  const optional4 = results.filter((r) => !r.dep.required);
122196
122995
  p.log.step("Required dependencies:");
@@ -122201,7 +123000,7 @@ async function doctor() {
122201
123000
  p.log.error(dep.name + " - not found");
122202
123001
  const fixCmd = getFixCommand(dep);
122203
123002
  if (fixCmd) {
122204
- p.log.message(dim(" └─ Fix: " + fixCmd));
123003
+ p.log.message(dim(" \u2514\u2500 Fix: " + fixCmd));
122205
123004
  }
122206
123005
  }
122207
123006
  }
@@ -122213,17 +123012,17 @@ async function doctor() {
122213
123012
  p.log.warn(dep.name + " - not found (" + dep.description + ")");
122214
123013
  const fixCmd = getFixCommand(dep);
122215
123014
  if (fixCmd) {
122216
- p.log.message(dim(" └─ Fix: " + fixCmd));
123015
+ p.log.message(dim(" \u2514\u2500 Fix: " + fixCmd));
122217
123016
  }
122218
123017
  }
122219
123018
  }
122220
123019
  const requiredMissing = required4.filter((r) => !r.available);
122221
123020
  const optionalMissing = optional4.filter((r) => !r.available);
122222
123021
  p.log.step("Skills:");
122223
- const configDir = join27(homedir10(), ".config", "opencode");
122224
- const globalSkillsPath = join27(configDir, "skills");
122225
- const bundledSkillsPath = join27(__dirname2, "..", "global-skills");
122226
- if (existsSync17(globalSkillsPath)) {
123022
+ const configDir = join29(homedir11(), ".config", "opencode");
123023
+ const globalSkillsPath = join29(configDir, "skills");
123024
+ const bundledSkillsPath = join29(__dirname2, "..", "global-skills");
123025
+ if (existsSync20(globalSkillsPath)) {
122227
123026
  try {
122228
123027
  const { readdirSync: readdirSync3 } = __require("fs");
122229
123028
  const skills = readdirSync3(globalSkillsPath, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
@@ -122238,7 +123037,7 @@ async function doctor() {
122238
123037
  } else {
122239
123038
  p.log.warn("No global skills directory (run 'swarm setup' to create)");
122240
123039
  }
122241
- if (existsSync17(bundledSkillsPath)) {
123040
+ if (existsSync20(bundledSkillsPath)) {
122242
123041
  try {
122243
123042
  const { readdirSync: readdirSync3 } = __require("fs");
122244
123043
  const bundled = readdirSync3(bundledSkillsPath, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
@@ -122249,7 +123048,7 @@ async function doctor() {
122249
123048
  }
122250
123049
  const projectSkillsDirs = [".opencode/skill", ".claude/skills", "skill"];
122251
123050
  for (const dir of projectSkillsDirs) {
122252
- if (existsSync17(dir)) {
123051
+ if (existsSync20(dir)) {
122253
123052
  try {
122254
123053
  const { readdirSync: readdirSync3 } = __require("fs");
122255
123054
  const skills = readdirSync3(dir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
@@ -122279,11 +123078,26 @@ async function setup(forceReinstall = false, nonInteractive = false) {
122279
123078
  console.log(magenta(" " + getRandomMessage()));
122280
123079
  console.log();
122281
123080
  p.intro("opencode-swarm-plugin v" + VERSION);
123081
+ const bunCheck = await checkCommand("bun", ["--version"]);
123082
+ if (!bunCheck.available) {
123083
+ p.log.error("Bun is required but not installed!");
123084
+ console.log();
123085
+ console.log(dim(" The swarm CLI requires Bun runtime for Bun-specific APIs."));
123086
+ console.log();
123087
+ console.log(" Install Bun:");
123088
+ console.log(cyan(" curl -fsSL https://bun.sh/install | bash"));
123089
+ console.log();
123090
+ console.log(dim(" Or via Homebrew:"));
123091
+ console.log(cyan(" brew install oven-sh/bun/bun"));
123092
+ console.log();
123093
+ process.exit(1);
123094
+ }
123095
+ p.log.success(`Bun v${bunCheck.version} detected`);
122282
123096
  const cwd = process.cwd();
122283
123097
  const tempDirName = getLibSQLProjectTempDirName(cwd);
122284
- const tempDir = join27(tmpdir3(), tempDirName);
122285
- const pglitePath = join27(tempDir, "streams");
122286
- const libsqlPath = join27(tempDir, "streams.db");
123098
+ const tempDir = join29(tmpdir3(), tempDirName);
123099
+ const pglitePath = join29(tempDir, "streams");
123100
+ const libsqlPath = join29(tempDir, "streams.db");
122287
123101
  if (pgliteExists(pglitePath)) {
122288
123102
  const migrateSpinner = p.spinner();
122289
123103
  migrateSpinner.start("Migrating...");
@@ -122310,19 +123124,19 @@ async function setup(forceReinstall = false, nonInteractive = false) {
122310
123124
  }
122311
123125
  let isReinstall = false;
122312
123126
  p.log.step("Checking existing configuration...");
122313
- const configDir = join27(homedir10(), ".config", "opencode");
122314
- const pluginDir = join27(configDir, "plugin");
122315
- const commandDir = join27(configDir, "command");
122316
- const agentDir = join27(configDir, "agent");
122317
- const pluginPath = join27(pluginDir, "swarm.ts");
122318
- const commandPath = join27(commandDir, "swarm.md");
122319
- const plannerAgentPath = join27(agentDir, "swarm-planner.md");
122320
- const workerAgentPath = join27(agentDir, "swarm-worker.md");
122321
- const researcherAgentPath = join27(agentDir, "swarm-researcher.md");
122322
- const swarmAgentDir = join27(agentDir, "swarm");
122323
- const legacyPlannerPath = join27(swarmAgentDir, "planner.md");
122324
- const legacyWorkerPath = join27(swarmAgentDir, "worker.md");
122325
- const legacyResearcherPath = join27(swarmAgentDir, "researcher.md");
123127
+ const configDir = join29(homedir11(), ".config", "opencode");
123128
+ const pluginDir = join29(configDir, "plugin");
123129
+ const commandDir = join29(configDir, "command");
123130
+ const agentDir = join29(configDir, "agent");
123131
+ const pluginPath = join29(pluginDir, "swarm.ts");
123132
+ const commandPath = join29(commandDir, "swarm.md");
123133
+ const plannerAgentPath = join29(agentDir, "swarm-planner.md");
123134
+ const workerAgentPath = join29(agentDir, "swarm-worker.md");
123135
+ const researcherAgentPath = join29(agentDir, "swarm-researcher.md");
123136
+ const swarmAgentDir = join29(agentDir, "swarm");
123137
+ const legacyPlannerPath = join29(swarmAgentDir, "planner.md");
123138
+ const legacyWorkerPath = join29(swarmAgentDir, "worker.md");
123139
+ const legacyResearcherPath = join29(swarmAgentDir, "researcher.md");
122326
123140
  const existingFiles = [
122327
123141
  pluginPath,
122328
123142
  commandPath,
@@ -122332,7 +123146,7 @@ async function setup(forceReinstall = false, nonInteractive = false) {
122332
123146
  legacyPlannerPath,
122333
123147
  legacyWorkerPath,
122334
123148
  legacyResearcherPath
122335
- ].filter((f) => existsSync17(f));
123149
+ ].filter((f) => existsSync20(f));
122336
123150
  if (existingFiles.length > 0 && !forceReinstall) {
122337
123151
  p.log.success("Swarm is already configured!");
122338
123152
  p.log.message(dim(" Found " + existingFiles.length + "/5 config files"));
@@ -122379,20 +123193,20 @@ async function setup(forceReinstall = false, nonInteractive = false) {
122379
123193
  p.cancel("Setup cancelled");
122380
123194
  process.exit(0);
122381
123195
  }
122382
- const plannerPaths = [plannerAgentPath, legacyPlannerPath].filter(existsSync17);
122383
- const workerPaths = [workerAgentPath, legacyWorkerPath].filter(existsSync17);
123196
+ const plannerPaths = [plannerAgentPath, legacyPlannerPath].filter(existsSync20);
123197
+ const workerPaths = [workerAgentPath, legacyWorkerPath].filter(existsSync20);
122384
123198
  for (const path4 of plannerPaths) {
122385
- const content = readFileSync13(path4, "utf-8");
123199
+ const content = readFileSync16(path4, "utf-8");
122386
123200
  const updated = content.replace(/^model: .+$/m, `model: ${coordinatorModel2}`);
122387
- writeFileSync6(path4, updated);
123201
+ writeFileSync7(path4, updated);
122388
123202
  }
122389
123203
  if (plannerPaths.length > 0) {
122390
123204
  p.log.success("Planner: " + coordinatorModel2);
122391
123205
  }
122392
123206
  for (const path4 of workerPaths) {
122393
- const content = readFileSync13(path4, "utf-8");
123207
+ const content = readFileSync16(path4, "utf-8");
122394
123208
  const updated = content.replace(/^model: .+$/m, `model: ${workerModel2}`);
122395
- writeFileSync6(path4, updated);
123209
+ writeFileSync7(path4, updated);
122396
123210
  }
122397
123211
  if (workerPaths.length > 0) {
122398
123212
  p.log.success("Worker: " + workerModel2);
@@ -122525,7 +123339,7 @@ async function setup(forceReinstall = false, nonInteractive = false) {
122525
123339
  try {
122526
123340
  const result = await migrateBeadsToHive(cwd);
122527
123341
  if (result.migrated) {
122528
- migrateSpinner.stop("Renamed .beads/ .hive/");
123342
+ migrateSpinner.stop("Renamed .beads/ \u2192 .hive/");
122529
123343
  p.log.success("Directory migration complete");
122530
123344
  migrateSpinner.start("Merging historic cells...");
122531
123345
  const mergeResult = await mergeHistoricBeads(cwd);
@@ -122556,10 +123370,10 @@ async function setup(forceReinstall = false, nonInteractive = false) {
122556
123370
  p.log.message(dim(" No legacy .beads directory found"));
122557
123371
  }
122558
123372
  p.log.step("Checking for legacy MCP servers...");
122559
- const opencodeConfigPath = join27(configDir, "config.json");
122560
- if (existsSync17(opencodeConfigPath)) {
123373
+ const opencodeConfigPath = join29(configDir, "config.json");
123374
+ if (existsSync20(opencodeConfigPath)) {
122561
123375
  try {
122562
- const opencodeConfig = JSON.parse(readFileSync13(opencodeConfigPath, "utf-8"));
123376
+ const opencodeConfig = JSON.parse(readFileSync16(opencodeConfigPath, "utf-8"));
122563
123377
  if (opencodeConfig.mcpServers?.["semantic-memory"]) {
122564
123378
  p.log.warn("Found legacy semantic-memory MCP server");
122565
123379
  p.log.message(dim(" Semantic memory is now embedded in the plugin"));
@@ -122573,7 +123387,7 @@ async function setup(forceReinstall = false, nonInteractive = false) {
122573
123387
  }
122574
123388
  if (removeMcp) {
122575
123389
  delete opencodeConfig.mcpServers["semantic-memory"];
122576
- writeFileSync6(opencodeConfigPath, JSON.stringify(opencodeConfig, null, 2));
123390
+ writeFileSync7(opencodeConfigPath, JSON.stringify(opencodeConfig, null, 2));
122577
123391
  p.log.success("Removed semantic-memory from MCP servers");
122578
123392
  p.log.message(dim(` Updated: ${opencodeConfigPath}`));
122579
123393
  } else {
@@ -122735,13 +123549,13 @@ async function setup(forceReinstall = false, nonInteractive = false) {
122735
123549
  p.log.message(dim(` Lite: ${liteModel}`));
122736
123550
  p.log.step("Setting up OpenCode integration...");
122737
123551
  const stats = { created: 0, updated: 0, unchanged: 0 };
122738
- const legacySkillsDir = join27(configDir, "skills");
122739
- const skillsDir = join27(configDir, "skill");
122740
- if (existsSync17(legacySkillsDir) && !existsSync17(skillsDir)) {
123552
+ const legacySkillsDir = join29(configDir, "skills");
123553
+ const skillsDir = join29(configDir, "skill");
123554
+ if (existsSync20(legacySkillsDir) && !existsSync20(skillsDir)) {
122741
123555
  p.log.step("Migrating skills directory...");
122742
123556
  try {
122743
123557
  renameSync(legacySkillsDir, skillsDir);
122744
- p.log.message(dim(` Renamed: ${legacySkillsDir} ${skillsDir}`));
123558
+ p.log.message(dim(` Renamed: ${legacySkillsDir} \u2192 ${skillsDir}`));
122745
123559
  } catch (err) {
122746
123560
  p.log.warn(`Could not migrate skills directory: ${err}`);
122747
123561
  }
@@ -122758,28 +123572,28 @@ async function setup(forceReinstall = false, nonInteractive = false) {
122758
123572
  stats[writeFileWithStatus(plannerAgentPath, getPlannerAgent(coordinatorModel), "Planner agent")]++;
122759
123573
  stats[writeFileWithStatus(workerAgentPath, getWorkerAgent(workerModel), "Worker agent")]++;
122760
123574
  stats[writeFileWithStatus(researcherAgentPath, getResearcherAgent(workerModel), "Researcher agent")]++;
122761
- if (existsSync17(legacyPlannerPath) || existsSync17(legacyWorkerPath) || existsSync17(legacyResearcherPath)) {
123575
+ if (existsSync20(legacyPlannerPath) || existsSync20(legacyWorkerPath) || existsSync20(legacyResearcherPath)) {
122762
123576
  p.log.step("Cleaning up legacy nested agent files...");
122763
123577
  }
122764
123578
  rmWithStatus(legacyPlannerPath, "legacy swarm/planner");
122765
123579
  rmWithStatus(legacyWorkerPath, "legacy swarm/worker");
122766
123580
  rmWithStatus(legacyResearcherPath, "legacy swarm/researcher");
122767
- if (existsSync17(swarmAgentDir)) {
123581
+ if (existsSync20(swarmAgentDir)) {
122768
123582
  try {
122769
123583
  rmdirSync(swarmAgentDir);
122770
123584
  } catch {}
122771
123585
  }
122772
123586
  p.log.message(dim(` Skills directory: ${skillsDir}`));
122773
- const bundledSkillsPath = join27(__dirname2, "..", "global-skills");
123587
+ const bundledSkillsPath = join29(__dirname2, "..", "global-skills");
122774
123588
  const bundledSkills = listDirectoryNames(bundledSkillsPath);
122775
- if (existsSync17(bundledSkillsPath)) {
123589
+ if (existsSync20(bundledSkillsPath)) {
122776
123590
  if (bundledSkills.length > 0) {
122777
123591
  p.log.message(dim(" Bundled skills: " + bundledSkills.join(", ")));
122778
123592
  }
122779
123593
  }
122780
123594
  if (bundledSkills.length > 0) {
122781
123595
  const globalSkills = listDirectoryNames(skillsDir);
122782
- const managedBundled = globalSkills.filter((name) => existsSync17(join27(skillsDir, name, BUNDLED_SKILL_MARKER_FILENAME)));
123596
+ const managedBundled = globalSkills.filter((name) => existsSync20(join29(skillsDir, name, BUNDLED_SKILL_MARKER_FILENAME)));
122783
123597
  const missingBundled = bundledSkills.filter((name) => !globalSkills.includes(name));
122784
123598
  if (missingBundled.length > 0 || managedBundled.length > 0) {
122785
123599
  {
@@ -122809,8 +123623,8 @@ async function setup(forceReinstall = false, nonInteractive = false) {
122809
123623
  }
122810
123624
  }
122811
123625
  }
122812
- const agentsPath = join27(configDir, "AGENTS.md");
122813
- if (existsSync17(agentsPath)) {
123626
+ const agentsPath = join29(configDir, "AGENTS.md");
123627
+ if (existsSync20(agentsPath)) {
122814
123628
  {
122815
123629
  const s2 = p.spinner();
122816
123630
  s2.start("Updating AGENTS.md...");
@@ -122853,15 +123667,15 @@ Skills: Use skills_list to see available skills`, "Next steps");
122853
123667
  async function init() {
122854
123668
  p.intro("swarm init v" + VERSION);
122855
123669
  const projectPath = process.cwd();
122856
- const gitDir = existsSync17(".git");
123670
+ const gitDir = existsSync20(".git");
122857
123671
  if (!gitDir) {
122858
123672
  p.log.error("Not in a git repository");
122859
123673
  p.log.message("Run 'git init' first, or cd to a git repo");
122860
123674
  p.outro("Aborted");
122861
123675
  process.exit(1);
122862
123676
  }
122863
- const hiveDir = existsSync17(".hive");
122864
- const beadsDir = existsSync17(".beads");
123677
+ const hiveDir = existsSync20(".hive");
123678
+ const beadsDir = existsSync20(".beads");
122865
123679
  if (hiveDir) {
122866
123680
  p.log.warn("Hive already initialized in this project (.hive/ exists)");
122867
123681
  const reinit = await p.confirm({
@@ -122944,8 +123758,8 @@ async function init() {
122944
123758
  });
122945
123759
  if (!p.isCancel(createSkillsDir) && createSkillsDir) {
122946
123760
  const skillsPath = ".opencode/skill";
122947
- if (!existsSync17(skillsPath)) {
122948
- mkdirSync9(skillsPath, { recursive: true });
123761
+ if (!existsSync20(skillsPath)) {
123762
+ mkdirSync11(skillsPath, { recursive: true });
122949
123763
  p.log.success("Created " + skillsPath + "/");
122950
123764
  p.log.message(dim(" Add SKILL.md files here for project-specific skills"));
122951
123765
  } else {
@@ -122976,14 +123790,14 @@ async function version4() {
122976
123790
  showUpdateNotification(updateInfo3);
122977
123791
  }
122978
123792
  function config4() {
122979
- const configDir = join27(homedir10(), ".config", "opencode");
122980
- const pluginPath = join27(configDir, "plugin", "swarm.ts");
122981
- const commandPath = join27(configDir, "command", "swarm.md");
122982
- const agentDir = join27(configDir, "agent");
122983
- const plannerAgentPath = join27(agentDir, "swarm-planner.md");
122984
- const workerAgentPath = join27(agentDir, "swarm-worker.md");
122985
- const researcherAgentPath = join27(agentDir, "swarm-researcher.md");
122986
- const globalSkillsPath = join27(configDir, "skills");
123793
+ const configDir = join29(homedir11(), ".config", "opencode");
123794
+ const pluginPath = join29(configDir, "plugin", "swarm.ts");
123795
+ const commandPath = join29(configDir, "command", "swarm.md");
123796
+ const agentDir = join29(configDir, "agent");
123797
+ const plannerAgentPath = join29(agentDir, "swarm-planner.md");
123798
+ const workerAgentPath = join29(agentDir, "swarm-worker.md");
123799
+ const researcherAgentPath = join29(agentDir, "swarm-researcher.md");
123800
+ const globalSkillsPath = join29(configDir, "skills");
122987
123801
  console.log(yellow(BANNER));
122988
123802
  console.log(dim(" " + TAGLINE + " v" + VERSION));
122989
123803
  console.log();
@@ -122997,8 +123811,8 @@ function config4() {
122997
123811
  { path: researcherAgentPath, desc: "@swarm-researcher agent", emoji: "\uD83D\uDD2C" }
122998
123812
  ];
122999
123813
  for (const { path: path4, desc, emoji: emoji4 } of files) {
123000
- const exists4 = existsSync17(path4);
123001
- const status = exists4 ? "" : "";
123814
+ const exists4 = existsSync20(path4);
123815
+ const status = exists4 ? "\u2713" : "\u2717";
123002
123816
  const color = exists4 ? "\x1B[32m" : "\x1B[31m";
123003
123817
  console.log(` ${emoji4} ${desc}`);
123004
123818
  console.log(` ${color}${status}\x1B[0m ${dim(path4)}`);
@@ -123006,8 +123820,8 @@ function config4() {
123006
123820
  }
123007
123821
  console.log(cyan("Skills:"));
123008
123822
  console.log();
123009
- const globalSkillsExists = existsSync17(globalSkillsPath);
123010
- const globalStatus = globalSkillsExists ? "" : "";
123823
+ const globalSkillsExists = existsSync20(globalSkillsPath);
123824
+ const globalStatus = globalSkillsExists ? "\u2713" : "\u2717";
123011
123825
  const globalColor = globalSkillsExists ? "\x1B[32m" : "\x1B[31m";
123012
123826
  console.log(` \uD83D\uDCDA Global skills directory`);
123013
123827
  console.log(` ${globalColor}${globalStatus}\x1B[0m ${dim(globalSkillsPath)}`);
@@ -123026,8 +123840,8 @@ function config4() {
123026
123840
  console.log(` ${dim(".claude/skills/")}`);
123027
123841
  console.log(` ${dim("skill/")}`);
123028
123842
  console.log();
123029
- const bundledSkillsPath = join27(__dirname2, "..", "global-skills");
123030
- if (existsSync17(bundledSkillsPath)) {
123843
+ const bundledSkillsPath = join29(__dirname2, "..", "global-skills");
123844
+ if (existsSync20(bundledSkillsPath)) {
123031
123845
  try {
123032
123846
  const { readdirSync: readdirSync3 } = __require("fs");
123033
123847
  const bundled = readdirSync3(bundledSkillsPath, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
@@ -123058,7 +123872,7 @@ async function update10() {
123058
123872
  p.outro("No update needed!");
123059
123873
  return;
123060
123874
  }
123061
- s.stop("Update available: " + VERSION + " " + updateInfo3.latest);
123875
+ s.stop("Update available: " + VERSION + " \u2192 " + updateInfo3.latest);
123062
123876
  const confirmUpdate = await p.confirm({
123063
123877
  message: "Update to v" + updateInfo3.latest + "?",
123064
123878
  initialValue: true
@@ -123195,7 +124009,7 @@ async function dashboard() {
123195
124009
  console.log(dim(" No subtasks"));
123196
124010
  } else {
123197
124011
  for (const p2 of progress) {
123198
- const bar = "".repeat(Math.floor(p2.progress_percent / 10)) + "".repeat(10 - Math.floor(p2.progress_percent / 10));
124012
+ const bar = "\u2588".repeat(Math.floor(p2.progress_percent / 10)) + "\u2591".repeat(10 - Math.floor(p2.progress_percent / 10));
123199
124013
  console.log(` ${p2.bead_id} [${bar}] ${p2.progress_percent}% - ${p2.status}`);
123200
124014
  }
123201
124015
  }
@@ -123221,7 +124035,7 @@ async function dashboard() {
123221
124035
  for (const msg of messages) {
123222
124036
  const timeAgo = Math.floor((Date.now() - new Date(msg.timestamp).getTime()) / 1000);
123223
124037
  const toList = Array.isArray(msg.to) ? msg.to.join(", ") : "unknown";
123224
- console.log(` ${msg.from || "unknown"} ${toList}: ${msg.subject} (${timeAgo}s ago)`);
124038
+ console.log(` ${msg.from || "unknown"} \u2192 ${toList}: ${msg.subject} (${timeAgo}s ago)`);
123225
124039
  }
123226
124040
  }
123227
124041
  console.log();
@@ -123362,7 +124176,7 @@ async function exportEvents() {
123362
124176
  break;
123363
124177
  }
123364
124178
  if (parsed.output) {
123365
- writeFileSync6(parsed.output, result);
124179
+ writeFileSync7(parsed.output, result);
123366
124180
  p.log.success(`Exported to: ${parsed.output}`);
123367
124181
  } else {
123368
124182
  console.log();
@@ -123397,6 +124211,7 @@ ${cyan("Commands:")}
123397
124211
  swarm viz Alias for 'swarm serve' (deprecated, use serve)
123398
124212
  --port <n> Port to listen on (default: 4483)
123399
124213
  swarm cells List or get cells from database (replaces 'swarm tool hive_query')
124214
+ swarm memory Manage unified memory system (learnings + sessions)
123400
124215
  swarm log View swarm logs with filtering
123401
124216
  swarm stats Show swarm health metrics powered by swarm-insights (strategy success rates, patterns)
123402
124217
  swarm o11y Show observability health - hook coverage, event capture, session quality
@@ -123424,6 +124239,17 @@ ${cyan("Cell Management:")}
123424
124239
  swarm cells --ready Show next ready (unblocked) cell
123425
124240
  swarm cells --json Raw JSON output (array, no wrapper)
123426
124241
 
124242
+ ${cyan("Memory Management (Hivemind):")}
124243
+ swarm memory store <info> [--tags <tags>] Store a learning/memory
124244
+ swarm memory find <query> [--limit <n>] Search all memories (semantic + FTS)
124245
+ swarm memory get <id> Get specific memory by ID
124246
+ swarm memory remove <id> Delete outdated/incorrect memory
124247
+ swarm memory validate <id> Confirm accuracy (resets 90-day decay)
124248
+ swarm memory stats Show database statistics
124249
+ swarm memory index Index AI sessions (use hivemind_index tool)
124250
+ swarm memory sync Sync to .hive/memories.jsonl (use hivemind_sync tool)
124251
+ swarm memory <command> --json Output JSON for all commands
124252
+
123427
124253
  ${cyan("Log Viewing:")}
123428
124254
  swarm log Tail recent logs (last 50 lines)
123429
124255
  swarm log <module> Filter by module (e.g., compaction)
@@ -123582,43 +124408,74 @@ async function listTools() {
123582
124408
  console.log(dim("Example: swarm tool hive_ready"));
123583
124409
  console.log(dim(`Example: swarm tool hive_create --json '{"title": "Fix bug"}'`));
123584
124410
  }
123585
- async function agents() {
124411
+ async function agents(nonInteractive = false) {
123586
124412
  const home = process.env.HOME || process.env.USERPROFILE || "~";
123587
- const agentsPath = join27(home, ".config", "opencode", "AGENTS.md");
124413
+ const agentsPath = join29(home, ".config", "opencode", "AGENTS.md");
123588
124414
  p.intro(yellow(BANNER));
123589
- if (!existsSync17(agentsPath)) {
124415
+ if (!existsSync20(agentsPath)) {
123590
124416
  p.log.warn("No AGENTS.md found at " + agentsPath);
123591
124417
  p.log.message(dim("Create one first, then run this command to add skill awareness"));
123592
124418
  p.outro("Aborted");
123593
124419
  return;
123594
124420
  }
123595
- const confirm2 = await p.confirm({
123596
- message: "Update AGENTS.md with skill awareness?",
123597
- initialValue: true
123598
- });
123599
- if (p.isCancel(confirm2) || !confirm2) {
123600
- p.outro("Aborted");
123601
- return;
124421
+ if (!nonInteractive) {
124422
+ const result = await p.confirm({
124423
+ message: "Update AGENTS.md with Hivemind unification?",
124424
+ initialValue: true
124425
+ });
124426
+ if (p.isCancel(result) || !result) {
124427
+ p.outro("Aborted");
124428
+ return;
124429
+ }
123602
124430
  }
123603
124431
  const s = p.spinner();
123604
- s.start("Updating AGENTS.md with skill awareness...");
123605
- const bundledSkillsPath = join27(__dirname2, "..", "global-skills");
123606
- const bundledSkills = listDirectoryNames(bundledSkillsPath);
124432
+ s.start("Updating AGENTS.md via LLM...");
124433
+ const prompt = `You are updating ~/.config/opencode/AGENTS.md to unify memory tools under Hivemind (ADR-011).
124434
+
124435
+ TASK: Update the AGENTS.md file to:
124436
+
124437
+ 1. **Rename tool references** throughout the file:
124438
+ - \`cass_search\` \u2192 \`hivemind_find\`
124439
+ - \`cass_view\` \u2192 \`hivemind_get\`
124440
+ - \`cass_expand\` \u2192 \`hivemind_get\`
124441
+ - \`cass_health\` \u2192 \`hivemind_stats\`
124442
+ - \`cass_index\` \u2192 \`hivemind_index\`
124443
+ - \`cass_stats\` \u2192 \`hivemind_stats\`
124444
+ - \`semantic-memory_store\` \u2192 \`hivemind_store\`
124445
+ - \`semantic-memory_find\` \u2192 \`hivemind_find\`
124446
+ - \`semantic-memory_get\` \u2192 \`hivemind_get\`
124447
+ - \`semantic-memory_remove\` \u2192 \`hivemind_remove\`
124448
+ - \`semantic-memory_validate\` \u2192 \`hivemind_validate\`
124449
+ - \`semantic-memory_list\` \u2192 \`hivemind_find\`
124450
+ - \`semantic-memory_stats\` \u2192 \`hivemind_stats\`
124451
+
124452
+ 2. **Consolidate sections**: If there are separate "CASS" and "Semantic Memory" sections, merge them into a single "Hivemind - Unified Memory System" section that covers:
124453
+ - Unified storage (learnings + sessions in same DB)
124454
+ - All hivemind_* tools with descriptions
124455
+ - Usage examples showing both storing learnings and searching sessions
124456
+ - The 90-day decay and validation workflow
124457
+
124458
+ 3. **Update any prose** that mentions "CASS" or "semantic memory" separately to use "Hivemind" terminology.
124459
+
124460
+ 4. **Keep existing structure** - don't reorganize unrelated sections.
124461
+
124462
+ Read the file, make the updates, and save it. Create a backup first.`;
123607
124463
  try {
123608
- const bundledSkillsCsv = bundledSkills.length > 0 ? bundledSkills.join(", ") : "cli-builder, learning-systems, skill-creator, swarm-coordination, system-design, testing-patterns";
123609
- const result = updateAgentsMdFile({ agentsPath, bundledSkillsCsv });
123610
- if (result.changed) {
123611
- s.stop("AGENTS.md updated with skill awareness");
123612
- p.log.success("Skills section added to " + agentsPath);
123613
- p.log.message(dim("Skills available: skills_list, skills_use, skills_read"));
123614
- if (result.backupPath) {
123615
- p.log.message(dim("Backup: " + result.backupPath));
123616
- }
124464
+ const proc = Bun.spawn(["opencode", "run", prompt], {
124465
+ stdio: ["inherit", "pipe", "pipe"],
124466
+ cwd: home
124467
+ });
124468
+ const exitCode = await proc.exited;
124469
+ if (exitCode === 0) {
124470
+ s.stop("AGENTS.md updated via LLM");
124471
+ p.log.success("Hivemind unification complete");
123617
124472
  } else {
123618
- s.stop("AGENTS.md already up to date");
124473
+ const stderr = await new Response(proc.stderr).text();
124474
+ s.stop("LLM update failed");
124475
+ p.log.error(stderr || `Exit code: ${exitCode}`);
123619
124476
  }
123620
124477
  } catch (error54) {
123621
- s.stop("Failed to update AGENTS.md");
124478
+ s.stop("Failed to run opencode");
123622
124479
  p.log.error(String(error54));
123623
124480
  }
123624
124481
  p.outro("Done");
@@ -123627,9 +124484,9 @@ async function migrate() {
123627
124484
  p.intro("swarm migrate v" + VERSION);
123628
124485
  const projectPath = process.cwd();
123629
124486
  const tempDirName = getLibSQLProjectTempDirName(projectPath);
123630
- const tempDir = join27(tmpdir3(), tempDirName);
123631
- const pglitePath = join27(tempDir, "streams");
123632
- const libsqlPath = join27(tempDir, "streams.db");
124487
+ const tempDir = join29(tmpdir3(), tempDirName);
124488
+ const pglitePath = join29(tempDir, "streams");
124489
+ const libsqlPath = join29(tempDir, "streams.db");
123633
124490
  if (!pgliteExists(pglitePath)) {
123634
124491
  p.log.success("No PGlite database found - nothing to migrate!");
123635
124492
  p.outro("Done");
@@ -123659,7 +124516,7 @@ async function migrate() {
123659
124516
  p.log.message(` \uD83D\uDC1D ${dryResult.beads.migrated} cells`);
123660
124517
  }
123661
124518
  if (dryResult.messages.migrated > 0) {
123662
- p.log.message(` ✉️ ${dryResult.messages.migrated} messages`);
124519
+ p.log.message(` \u2709\uFE0F ${dryResult.messages.migrated} messages`);
123663
124520
  }
123664
124521
  if (dryResult.agents.migrated > 0) {
123665
124522
  p.log.message(` \uD83E\uDD16 ${dryResult.agents.migrated} agents`);
@@ -123717,10 +124574,10 @@ async function migrate() {
123717
124574
  }
123718
124575
  }
123719
124576
  function parseSessionFile(filePath) {
123720
- if (!existsSync17(filePath)) {
124577
+ if (!existsSync20(filePath)) {
123721
124578
  throw new Error(`Session file not found: ${filePath}`);
123722
124579
  }
123723
- const content = readFileSync13(filePath, "utf-8");
124580
+ const content = readFileSync16(filePath, "utf-8");
123724
124581
  const lines = content.split(`
123725
124582
  `).filter((line) => line.trim());
123726
124583
  const events = [];
@@ -123733,12 +124590,12 @@ function parseSessionFile(filePath) {
123733
124590
  return events;
123734
124591
  }
123735
124592
  function listSessionFiles(dir) {
123736
- if (!existsSync17(dir))
124593
+ if (!existsSync20(dir))
123737
124594
  return [];
123738
124595
  const files = readdirSync2(dir).filter((f) => f.endsWith(".jsonl"));
123739
124596
  const sessions = [];
123740
124597
  for (const file4 of files) {
123741
- const filePath = join27(dir, file4);
124598
+ const filePath = join29(dir, file4);
123742
124599
  try {
123743
124600
  const events = parseSessionFile(filePath);
123744
124601
  if (events.length === 0)
@@ -123788,7 +124645,7 @@ function formatEvent(event, useColor = true) {
123788
124645
  }
123789
124646
  async function logSessions() {
123790
124647
  const args3 = process.argv.slice(4);
123791
- const sessionsDir = join27(homedir10(), ".config", "swarm-tools", "sessions");
124648
+ const sessionsDir = join29(homedir11(), ".config", "swarm-tools", "sessions");
123792
124649
  let sessionId = null;
123793
124650
  let latest = false;
123794
124651
  let jsonOutput = false;
@@ -123989,14 +124846,14 @@ ${dim(JSON.stringify(log4.data, null, 2))}`;
123989
124846
  return output;
123990
124847
  }
123991
124848
  function readLogFiles(dir) {
123992
- if (!existsSync17(dir))
124849
+ if (!existsSync20(dir))
123993
124850
  return [];
123994
124851
  const allFiles = readdirSync2(dir);
123995
- const logFiles = allFiles.filter((f) => /\.\d+log$/.test(f) || /\.log$/.test(f)).sort().map((f) => join27(dir, f));
124852
+ const logFiles = allFiles.filter((f) => /\.\d+log$/.test(f) || /\.log$/.test(f)).sort().map((f) => join29(dir, f));
123996
124853
  const entries2 = [];
123997
124854
  for (const file4 of logFiles) {
123998
124855
  try {
123999
- const content = readFileSync13(file4, "utf-8");
124856
+ const content = readFileSync16(file4, "utf-8");
124000
124857
  const fileLines = content.split(`
124001
124858
  `).filter((line) => line.trim());
124002
124859
  for (const line of fileLines) {
@@ -124071,7 +124928,7 @@ async function cells() {
124071
124928
  }
124072
124929
  const projectPath = process.cwd();
124073
124930
  try {
124074
- const swarmMail = await getSwarmMailLibSQL17(projectPath);
124931
+ const swarmMail = await getSwarmMailLibSQL19(projectPath);
124075
124932
  const db = await swarmMail.getDatabase();
124076
124933
  const adapter = createHiveAdapter4(db, projectPath);
124077
124934
  await adapter.runMigrations();
@@ -124177,8 +125034,8 @@ async function logs() {
124177
125034
  moduleFilter = arg;
124178
125035
  }
124179
125036
  }
124180
- const logsDir = join27(homedir10(), ".config", "swarm-tools", "logs");
124181
- if (!existsSync17(logsDir)) {
125037
+ const logsDir = join29(homedir11(), ".config", "swarm-tools", "logs");
125038
+ if (!existsSync20(logsDir)) {
124182
125039
  if (!jsonOutput) {
124183
125040
  p.log.warn("No logs directory found");
124184
125041
  p.log.message(dim(` Expected: ${logsDir}`));
@@ -124211,11 +125068,11 @@ async function logs() {
124211
125068
  console.log();
124212
125069
  const filePositions = new Map;
124213
125070
  const initializePositions = () => {
124214
- if (!existsSync17(logsDir))
125071
+ if (!existsSync20(logsDir))
124215
125072
  return;
124216
125073
  const files = readdirSync2(logsDir).filter((f) => /\.\d+log$/.test(f) || /\.log$/.test(f));
124217
125074
  for (const file4 of files) {
124218
- const filePath = join27(logsDir, file4);
125075
+ const filePath = join29(logsDir, file4);
124219
125076
  try {
124220
125077
  const stats = statSync2(filePath);
124221
125078
  filePositions.set(filePath, stats.size);
@@ -124232,7 +125089,7 @@ async function logs() {
124232
125089
  }
124233
125090
  return [];
124234
125091
  }
124235
- const content = readFileSync13(filePath, "utf-8");
125092
+ const content = readFileSync16(filePath, "utf-8");
124236
125093
  const newContent = content.slice(lastPos);
124237
125094
  filePositions.set(filePath, stats.size);
124238
125095
  return newContent.split(`
@@ -124249,11 +125106,11 @@ async function logs() {
124249
125106
  }
124250
125107
  initializePositions();
124251
125108
  const pollForNewLogs = () => {
124252
- if (!existsSync17(logsDir))
125109
+ if (!existsSync20(logsDir))
124253
125110
  return;
124254
125111
  const files = readdirSync2(logsDir).filter((f) => /\.\d+log$/.test(f) || /\.log$/.test(f));
124255
125112
  for (const file4 of files) {
124256
- const filePath = join27(logsDir, file4);
125113
+ const filePath = join29(logsDir, file4);
124257
125114
  const newLines = readNewLines(filePath);
124258
125115
  for (const line of newLines) {
124259
125116
  const parsed = parseLogLine(line, filePath);
@@ -124309,7 +125166,7 @@ async function db() {
124309
125166
  const projectName = basename3(projectPath);
124310
125167
  const hash5 = hashLibSQLProjectPath(projectPath);
124311
125168
  const dbPath = getLibSQLDatabasePath(projectPath);
124312
- const dbDir = dirname7(dbPath.replace("file:", ""));
125169
+ const dbDir = dirname9(dbPath.replace("file:", ""));
124313
125170
  const dbFile = dbPath.replace("file:", "");
124314
125171
  console.log(yellow(BANNER));
124315
125172
  console.log(dim(` ${TAGLINE}
@@ -124322,51 +125179,51 @@ async function db() {
124322
125179
  console.log(` ${dim("DB Directory:")} ${dbDir}`);
124323
125180
  console.log(` ${dim("DB File:")} ${dbFile}`);
124324
125181
  console.log();
124325
- if (existsSync17(dbFile)) {
125182
+ if (existsSync20(dbFile)) {
124326
125183
  const stats = statSync2(dbFile);
124327
125184
  const sizeKB = Math.round(stats.size / 1024);
124328
- console.log(` ${green("")} Database exists (${sizeKB} KB)`);
125185
+ console.log(` ${green("\u2713")} Database exists (${sizeKB} KB)`);
124329
125186
  try {
124330
125187
  const schema = execSync(`sqlite3 "${dbFile}" "SELECT sql FROM sqlite_master WHERE type='table' AND name='beads'"`, { encoding: "utf-8" }).trim();
124331
125188
  if (schema) {
124332
125189
  const hasProjectKey = schema.includes("project_key");
124333
125190
  if (hasProjectKey) {
124334
- console.log(` ${green("")} Schema is correct (has project_key)`);
125191
+ console.log(` ${green("\u2713")} Schema is correct (has project_key)`);
124335
125192
  } else {
124336
- console.log(` \x1B[31m✗\x1B[0m Schema is OLD (missing project_key)`);
125193
+ console.log(` \x1B[31m\u2717\x1B[0m Schema is OLD (missing project_key)`);
124337
125194
  console.log();
124338
125195
  console.log(dim(" To fix: delete the database and restart OpenCode"));
124339
125196
  console.log(dim(` rm -r "${dbDir}"`));
124340
125197
  }
124341
125198
  } else {
124342
- console.log(` ${dim("")} No beads table yet (will be created on first use)`);
125199
+ console.log(` ${dim("\u25CB")} No beads table yet (will be created on first use)`);
124343
125200
  }
124344
125201
  try {
124345
125202
  const version5 = execSync(`sqlite3 "${dbFile}" "SELECT MAX(version) FROM schema_version"`, { encoding: "utf-8" }).trim();
124346
125203
  if (version5 && version5 !== "") {
124347
- console.log(` ${dim("")} Schema version: ${version5}`);
125204
+ console.log(` ${dim("\u25CB")} Schema version: ${version5}`);
124348
125205
  }
124349
125206
  } catch {
124350
- console.log(` ${dim("")} No schema_version table`);
125207
+ console.log(` ${dim("\u25CB")} No schema_version table`);
124351
125208
  }
124352
125209
  try {
124353
125210
  const beadCount = execSync(`sqlite3 "${dbFile}" "SELECT COUNT(*) FROM beads"`, { encoding: "utf-8" }).trim();
124354
- console.log(` ${dim("")} Cells: ${beadCount}`);
125211
+ console.log(` ${dim("\u25CB")} Cells: ${beadCount}`);
124355
125212
  } catch {}
124356
125213
  try {
124357
125214
  const memoryCount = execSync(`sqlite3 "${dbFile}" "SELECT COUNT(*) FROM memories"`, { encoding: "utf-8" }).trim();
124358
- console.log(` ${dim("")} Memories: ${memoryCount}`);
125215
+ console.log(` ${dim("\u25CB")} Memories: ${memoryCount}`);
124359
125216
  } catch {}
124360
125217
  } catch (error54) {
124361
- console.log(` ${dim("")} Could not inspect schema (sqlite3 not available)`);
125218
+ console.log(` ${dim("\u25CB")} Could not inspect schema (sqlite3 not available)`);
124362
125219
  }
124363
125220
  } else {
124364
- console.log(` ${dim("")} Database does not exist yet`);
125221
+ console.log(` ${dim("\u25CB")} Database does not exist yet`);
124365
125222
  console.log(dim(" Will be created on first use"));
124366
125223
  }
124367
125224
  console.log();
124368
- const pglitePath = join27(dbDir, "streams");
124369
- if (existsSync17(pglitePath)) {
125225
+ const pglitePath = join29(dbDir, "streams");
125226
+ if (existsSync20(pglitePath)) {
124370
125227
  console.log(` \x1B[33m!\x1B[0m Legacy PGLite directory exists`);
124371
125228
  console.log(dim(` ${pglitePath}`));
124372
125229
  console.log(dim(" Run 'swarm migrate' to migrate data"));
@@ -124376,7 +125233,7 @@ async function db() {
124376
125233
  function generateSparkline(scores) {
124377
125234
  if (scores.length === 0)
124378
125235
  return "";
124379
- const chars = ["", "", "", "", "", "", "", ""];
125236
+ const chars = ["\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588"];
124380
125237
  const min4 = Math.min(...scores);
124381
125238
  const max5 = Math.max(...scores);
124382
125239
  const range3 = max5 - min4;
@@ -124390,7 +125247,7 @@ function generateSparkline(scores) {
124390
125247
  }).join("");
124391
125248
  }
124392
125249
  function formatEvalStatusOutput(status) {
124393
- const phaseEmoji = status.phase === "bootstrap" ? "\uD83C\uDF31" : status.phase === "stabilization" ? "⚙️" : "\uD83D\uDE80";
125250
+ const phaseEmoji = status.phase === "bootstrap" ? "\uD83C\uDF31" : status.phase === "stabilization" ? "\u2699\uFE0F" : "\uD83D\uDE80";
124394
125251
  const phaseColor = status.phase === "bootstrap" ? yellow : status.phase === "stabilization" ? cyan : green;
124395
125252
  p.log.step(`${phaseEmoji} Phase: ${phaseColor(bold(status.phase))}`);
124396
125253
  p.log.message(`${dim("Runs:")} ${status.runCount}`);
@@ -124398,8 +125255,8 @@ function formatEvalStatusOutput(status) {
124398
125255
  p.log.message(bold("Gate Thresholds"));
124399
125256
  const stabilizationPct = (status.thresholds.stabilization * 100).toFixed(0);
124400
125257
  const productionPct = (status.thresholds.production * 100).toFixed(0);
124401
- p.log.message(` ${yellow("")} Stabilization: ${stabilizationPct}% regression ${dim("(warn)")}`);
124402
- p.log.message(` ${red("")} Production: ${productionPct}% regression ${dim("(fail)")}`);
125258
+ p.log.message(` ${yellow("\u26A0")} Stabilization: ${stabilizationPct}% regression ${dim("(warn)")}`);
125259
+ p.log.message(` ${red("\u2717")} Production: ${productionPct}% regression ${dim("(fail)")}`);
124403
125260
  console.log();
124404
125261
  if (status.recentScores.length > 0) {
124405
125262
  p.log.message(bold("Recent Scores"));
@@ -124449,9 +125306,9 @@ function formatEvalHistoryOutput(history) {
124449
125306
  }
124450
125307
  function formatEvalRunResultOutput(result) {
124451
125308
  if (result.passed) {
124452
- p.log.success(bold(green(" PASS")));
125309
+ p.log.success(bold(green("\u2713 PASS")));
124453
125310
  } else {
124454
- p.log.error(bold(red(" FAIL")));
125311
+ p.log.error(bold(red("\u2717 FAIL")));
124455
125312
  }
124456
125313
  console.log();
124457
125314
  const phaseColor = result.phase === "bootstrap" ? yellow : result.phase === "stabilization" ? cyan : green;
@@ -124488,7 +125345,7 @@ async function stats() {
124488
125345
  }
124489
125346
  try {
124490
125347
  const projectPath = process.cwd();
124491
- const swarmMail = await getSwarmMailLibSQL17(projectPath);
125348
+ const swarmMail = await getSwarmMailLibSQL19(projectPath);
124492
125349
  const db2 = await swarmMail.getDatabase();
124493
125350
  const since = parseTimePeriod(period);
124494
125351
  const periodMatch = period.match(/^(\d+)([dhm])$/);
@@ -124512,21 +125369,21 @@ async function stats() {
124512
125369
  strategy: row.strategy,
124513
125370
  success: row.success === "true"
124514
125371
  })));
124515
- const sessionsPath = join27(homedir10(), ".config", "swarm-tools", "sessions");
125372
+ const sessionsPath = join29(homedir11(), ".config", "swarm-tools", "sessions");
124516
125373
  let coordinatorStats = {
124517
125374
  violationRate: 0,
124518
125375
  spawnEfficiency: 0,
124519
125376
  reviewThoroughness: 0
124520
125377
  };
124521
- if (existsSync17(sessionsPath)) {
124522
- const sessionFiles = readdirSync2(sessionsPath).filter((f) => f.endsWith(".jsonl") && statSync2(join27(sessionsPath, f)).mtimeMs >= since);
125378
+ if (existsSync20(sessionsPath)) {
125379
+ const sessionFiles = readdirSync2(sessionsPath).filter((f) => f.endsWith(".jsonl") && statSync2(join29(sessionsPath, f)).mtimeMs >= since);
124523
125380
  let totalViolations = 0;
124524
125381
  let totalSpawns = 0;
124525
125382
  let totalReviews = 0;
124526
125383
  let totalSwarms = 0;
124527
125384
  for (const file4 of sessionFiles) {
124528
125385
  try {
124529
- const content = readFileSync13(join27(sessionsPath, file4), "utf-8");
125386
+ const content = readFileSync16(join29(sessionsPath, file4), "utf-8");
124530
125387
  const lines = content.trim().split(`
124531
125388
  `);
124532
125389
  let violations = 0;
@@ -124568,7 +125425,7 @@ async function stats() {
124568
125425
  recentDays: Math.round(periodDays * 10) / 10
124569
125426
  };
124570
125427
  if (showRegressions) {
124571
- const regressions = detectRegressions(projectPath, 0.1);
125428
+ const regressions = detectRegressions2(projectPath, 0.1);
124572
125429
  if (format5 === "json") {
124573
125430
  console.log(JSON.stringify({ stats: stats2, regressions }, null, 2));
124574
125431
  } else {
@@ -124577,17 +125434,17 @@ async function stats() {
124577
125434
  console.log();
124578
125435
  if (regressions.length > 0) {
124579
125436
  console.log(`
124580
- ⚠️ EVAL REGRESSIONS DETECTED`);
125437
+ \u26A0\uFE0F EVAL REGRESSIONS DETECTED`);
124581
125438
  for (const reg of regressions) {
124582
125439
  const oldPercent = (reg.oldScore * 100).toFixed(1);
124583
125440
  const newPercent = (reg.newScore * 100).toFixed(1);
124584
125441
  const deltaPercent = reg.deltaPercent.toFixed(1);
124585
- console.log(`├── ${reg.evalName}: ${oldPercent}% ${newPercent}% (${deltaPercent}%)`);
125442
+ console.log(`\u251C\u2500\u2500 ${reg.evalName}: ${oldPercent}% \u2192 ${newPercent}% (${deltaPercent}%)`);
124586
125443
  }
124587
- console.log(`└── Threshold: 10%
125444
+ console.log(`\u2514\u2500\u2500 Threshold: 10%
124588
125445
  `);
124589
125446
  } else {
124590
- console.log(`✅ No eval regressions detected (>10% threshold)
125447
+ console.log(`\u2705 No eval regressions detected (>10% threshold)
124591
125448
  `);
124592
125449
  }
124593
125450
  }
@@ -124677,7 +125534,7 @@ async function swarmHistory() {
124677
125534
  console.log("Details:");
124678
125535
  for (const record4 of records) {
124679
125536
  console.log(` ${record4.epic_id}: ${record4.epic_title} (${record4.strategy})`);
124680
- console.log(` Tasks: ${record4.completed_count}/${record4.task_count}, Success: ${record4.overall_success ? "" : ""}`);
125537
+ console.log(` Tasks: ${record4.completed_count}/${record4.task_count}, Success: ${record4.overall_success ? "\u2705" : "\u274C"}`);
124681
125538
  }
124682
125539
  console.log();
124683
125540
  }
@@ -124732,8 +125589,8 @@ async function evalStatus() {
124732
125589
  p.intro("swarm eval status");
124733
125590
  const projectPath = process.cwd();
124734
125591
  const evalName = process.argv[4] || "swarm-decomposition";
124735
- const phase = getPhase(projectPath, evalName);
124736
- const history = getScoreHistory(projectPath, evalName);
125592
+ const phase = getPhase2(projectPath, evalName);
125593
+ const history = getScoreHistory2(projectPath, evalName);
124737
125594
  const recentScores = history.slice(-5).map((run) => ({
124738
125595
  timestamp: run.timestamp,
124739
125596
  score: run.score
@@ -124750,14 +125607,14 @@ async function evalStatus() {
124750
125607
  async function evalHistory() {
124751
125608
  p.intro("swarm eval history");
124752
125609
  const projectPath = process.cwd();
124753
- const historyPath = getEvalHistoryPath(projectPath);
124754
- if (!existsSync17(historyPath)) {
125610
+ const historyPath = getEvalHistoryPath2(projectPath);
125611
+ if (!existsSync20(historyPath)) {
124755
125612
  p.log.warn("No eval history found");
124756
125613
  p.log.message(dim(`Expected: ${historyPath}`));
124757
125614
  p.outro("Run evals to generate history");
124758
125615
  return;
124759
125616
  }
124760
- const content = readFileSync13(historyPath, "utf-8");
125617
+ const content = readFileSync16(historyPath, "utf-8");
124761
125618
  const lines = content.trim().split(`
124762
125619
  `).filter(Boolean);
124763
125620
  const history = lines.map((line) => JSON.parse(line));
@@ -124788,7 +125645,7 @@ async function evalRun() {
124788
125645
  const evalPath = `evals/${evalName}.eval.ts`;
124789
125646
  const mockScore = 0.85;
124790
125647
  const gateResult = checkGate(projectPath, evalName, mockScore);
124791
- const history = getScoreHistory(projectPath, evalName);
125648
+ const history = getScoreHistory2(projectPath, evalName);
124792
125649
  recordEvalRun(projectPath, {
124793
125650
  timestamp: new Date().toISOString(),
124794
125651
  eval_name: evalName,
@@ -124802,7 +125659,7 @@ async function evalRun() {
124802
125659
  if (!ciMode) {
124803
125660
  formatEvalRunResultOutput(gateResult);
124804
125661
  } else {
124805
- const status = gateResult.passed ? " PASS" : " FAIL";
125662
+ const status = gateResult.passed ? "\u2705 PASS" : "\u274C FAIL";
124806
125663
  console.log(`${evalName}: ${status} (${gateResult.phase}, score: ${gateResult.currentScore.toFixed(2)})`);
124807
125664
  console.log(` ${gateResult.message}`);
124808
125665
  }
@@ -124816,21 +125673,21 @@ async function evalRun() {
124816
125673
  }
124817
125674
  }
124818
125675
  if (ciMode) {
124819
- const resultsPath = join27(projectPath, ".hive", "eval-results.json");
125676
+ const resultsPath = join29(projectPath, ".hive", "eval-results.json");
124820
125677
  ensureHiveDirectory(projectPath);
124821
- writeFileSync6(resultsPath, JSON.stringify(results, null, 2));
125678
+ writeFileSync7(resultsPath, JSON.stringify(results, null, 2));
124822
125679
  console.log(`
124823
125680
  Results written to ${resultsPath}`);
124824
125681
  if (anyFailure) {
124825
125682
  const productionFailures = Object.entries(results).filter(([_, result]) => !result.passed && result.phase === "production");
124826
125683
  if (productionFailures.length > 0) {
124827
125684
  console.error(`
124828
- ${productionFailures.length} production-phase eval(s) failed`);
125685
+ \u274C ${productionFailures.length} production-phase eval(s) failed`);
124829
125686
  process.exit(1);
124830
125687
  }
124831
125688
  }
124832
125689
  console.log(`
124833
- All evals passed or in pre-production phase`);
125690
+ \u2705 All evals passed or in pre-production phase`);
124834
125691
  } else {
124835
125692
  console.log();
124836
125693
  p.outro(anyFailure ? "Some evals need attention" : "All evals passed!");
@@ -124845,7 +125702,7 @@ async function serve() {
124845
125702
  p.log.message(dim(` Project: ${projectPath}`));
124846
125703
  p.log.message(dim(` Port: ${port} (HIVE on phone keypad)`));
124847
125704
  try {
124848
- const swarmMail = await getSwarmMailLibSQL17(projectPath);
125705
+ const swarmMail = await getSwarmMailLibSQL19(projectPath);
124849
125706
  const streamAdapter = createDurableStreamAdapter(swarmMail, projectPath);
124850
125707
  const db2 = await swarmMail.getDatabase(projectPath);
124851
125708
  const hiveAdapter = createHiveAdapter4(db2, projectPath);
@@ -124880,7 +125737,7 @@ async function viz() {
124880
125737
  p.log.message(dim(` Project: ${projectPath}`));
124881
125738
  p.log.message(dim(` Port: ${port}`));
124882
125739
  try {
124883
- const swarmMail = await getSwarmMailLibSQL17(projectPath);
125740
+ const swarmMail = await getSwarmMailLibSQL19(projectPath);
124884
125741
  const streamAdapter = createDurableStreamAdapter(swarmMail, projectPath);
124885
125742
  const db2 = await swarmMail.getDatabase(projectPath);
124886
125743
  const hiveAdapter = createHiveAdapter4(db2, projectPath);
@@ -124963,6 +125820,247 @@ async function capture3() {
124963
125820
  process.exit(1);
124964
125821
  }
124965
125822
  }
125823
+ function parseMemoryArgs(subcommand, args3) {
125824
+ let json4 = false;
125825
+ let info;
125826
+ let query2;
125827
+ let id;
125828
+ let tags;
125829
+ let limit;
125830
+ let collection;
125831
+ if (args3.length > 0 && !args3[0].startsWith("--")) {
125832
+ if (subcommand === "store") {
125833
+ info = args3[0];
125834
+ } else if (subcommand === "find") {
125835
+ query2 = args3[0];
125836
+ } else if (subcommand === "get" || subcommand === "remove" || subcommand === "validate") {
125837
+ id = args3[0];
125838
+ }
125839
+ }
125840
+ for (let i = 0;i < args3.length; i++) {
125841
+ const arg = args3[i];
125842
+ if (arg === "--json") {
125843
+ json4 = true;
125844
+ } else if (arg === "--tags" && i + 1 < args3.length) {
125845
+ tags = args3[++i];
125846
+ } else if (arg === "--limit" && i + 1 < args3.length) {
125847
+ const val = parseInt(args3[++i], 10);
125848
+ if (!isNaN(val))
125849
+ limit = val;
125850
+ } else if (arg === "--collection" && i + 1 < args3.length) {
125851
+ collection = args3[++i];
125852
+ }
125853
+ }
125854
+ return { json: json4, info, query: query2, id, tags, limit, collection };
125855
+ }
125856
+ async function memory() {
125857
+ const subcommand = process.argv[3];
125858
+ const args3 = process.argv.slice(4);
125859
+ const parsed = parseMemoryArgs(subcommand, args3);
125860
+ const projectPath = process.cwd();
125861
+ try {
125862
+ const { getDb: getDb2 } = await import("swarm-mail");
125863
+ const tempDirName = getLibSQLProjectTempDirName(projectPath);
125864
+ const tempDir = join29(tmpdir3(), tempDirName);
125865
+ if (!existsSync20(tempDir)) {
125866
+ mkdirSync11(tempDir, { recursive: true });
125867
+ }
125868
+ const dbPath = join29(tempDir, "streams.db");
125869
+ const dbUrl = `file://${dbPath}`;
125870
+ const db2 = await getDb2(dbUrl);
125871
+ const { createMemoryAdapter: createMemoryAdapter3 } = await import("swarm-mail");
125872
+ const adapter = createMemoryAdapter3(db2, {
125873
+ ollamaHost: process.env.OLLAMA_HOST || "http://localhost:11434",
125874
+ ollamaModel: process.env.OLLAMA_MODEL || "mxbai-embed-large"
125875
+ });
125876
+ switch (subcommand) {
125877
+ case "store": {
125878
+ if (!parsed.info) {
125879
+ console.error("Usage: swarm memory store <information> [--tags <tags>]");
125880
+ process.exit(1);
125881
+ }
125882
+ const result = await adapter.store(parsed.info, {
125883
+ tags: parsed.tags,
125884
+ collection: parsed.collection || "default"
125885
+ });
125886
+ if (parsed.json) {
125887
+ console.log(JSON.stringify({ success: true, id: result.id }));
125888
+ } else {
125889
+ p.intro("swarm memory store");
125890
+ p.log.success(`Stored memory: ${result.id}`);
125891
+ if (result.autoTags) {
125892
+ p.log.message(`Auto-tags: ${result.autoTags.tags.join(", ")}`);
125893
+ }
125894
+ p.outro("Done");
125895
+ }
125896
+ break;
125897
+ }
125898
+ case "find": {
125899
+ if (!parsed.query) {
125900
+ console.error("Usage: swarm memory find <query> [--limit <n>] [--collection <name>]");
125901
+ process.exit(1);
125902
+ }
125903
+ const results = await adapter.find(parsed.query, {
125904
+ limit: parsed.limit || 10,
125905
+ collection: parsed.collection
125906
+ });
125907
+ if (parsed.json) {
125908
+ console.log(JSON.stringify({ success: true, results }));
125909
+ } else {
125910
+ p.intro(`swarm memory find: "${parsed.query}"`);
125911
+ if (results.length === 0) {
125912
+ p.log.warn("No memories found");
125913
+ } else {
125914
+ for (const result of results) {
125915
+ console.log();
125916
+ console.log(cyan(`[${result.memory.id}] Score: ${result.score.toFixed(3)}`));
125917
+ console.log(dim(` Created: ${new Date(result.memory.createdAt).toLocaleDateString()}`));
125918
+ console.log(` ${result.memory.content.slice(0, 200)}${result.memory.content.length > 200 ? "..." : ""}`);
125919
+ if (result.memory.metadata.tags) {
125920
+ console.log(dim(` Tags: ${result.memory.metadata.tags.join(", ")}`));
125921
+ }
125922
+ }
125923
+ }
125924
+ p.outro(`Found ${results.length} result(s)`);
125925
+ }
125926
+ break;
125927
+ }
125928
+ case "get": {
125929
+ if (!parsed.id) {
125930
+ console.error("Usage: swarm memory get <id>");
125931
+ process.exit(1);
125932
+ }
125933
+ const memory2 = await adapter.get(parsed.id);
125934
+ if (parsed.json) {
125935
+ if (memory2) {
125936
+ console.log(JSON.stringify({ success: true, memory: memory2 }));
125937
+ } else {
125938
+ console.log(JSON.stringify({ success: false, error: "Memory not found" }));
125939
+ process.exit(1);
125940
+ }
125941
+ } else {
125942
+ p.intro(`swarm memory get: ${parsed.id}`);
125943
+ if (!memory2) {
125944
+ p.log.error("Memory not found");
125945
+ p.outro("Aborted");
125946
+ process.exit(1);
125947
+ } else {
125948
+ console.log();
125949
+ console.log(cyan("Content:"));
125950
+ console.log(memory2.content);
125951
+ console.log();
125952
+ console.log(dim(`Created: ${new Date(memory2.createdAt).toLocaleDateString()}`));
125953
+ console.log(dim(`Collection: ${memory2.collection}`));
125954
+ console.log(dim(`Confidence: ${memory2.confidence ?? 0.7}`));
125955
+ if (memory2.metadata.tags) {
125956
+ console.log(dim(`Tags: ${memory2.metadata.tags.join(", ")}`));
125957
+ }
125958
+ p.outro("Done");
125959
+ }
125960
+ }
125961
+ break;
125962
+ }
125963
+ case "remove": {
125964
+ if (!parsed.id) {
125965
+ console.error("Usage: swarm memory remove <id>");
125966
+ process.exit(1);
125967
+ }
125968
+ await adapter.remove(parsed.id);
125969
+ if (parsed.json) {
125970
+ console.log(JSON.stringify({ success: true }));
125971
+ } else {
125972
+ p.intro("swarm memory remove");
125973
+ p.log.success(`Removed memory: ${parsed.id}`);
125974
+ p.outro("Done");
125975
+ }
125976
+ break;
125977
+ }
125978
+ case "validate": {
125979
+ if (!parsed.id) {
125980
+ console.error("Usage: swarm memory validate <id>");
125981
+ process.exit(1);
125982
+ }
125983
+ await adapter.validate(parsed.id);
125984
+ if (parsed.json) {
125985
+ console.log(JSON.stringify({ success: true }));
125986
+ } else {
125987
+ p.intro("swarm memory validate");
125988
+ p.log.success(`Validated memory: ${parsed.id} (decay timer reset)`);
125989
+ p.outro("Done");
125990
+ }
125991
+ break;
125992
+ }
125993
+ case "stats": {
125994
+ const stats2 = await adapter.stats();
125995
+ if (parsed.json) {
125996
+ console.log(JSON.stringify({ success: true, stats: stats2 }));
125997
+ } else {
125998
+ p.intro("swarm memory stats");
125999
+ console.log();
126000
+ console.log(cyan("Database Statistics:"));
126001
+ console.log(` Memories: ${stats2.memories}`);
126002
+ console.log(` Embeddings: ${stats2.embeddings}`);
126003
+ p.outro("Done");
126004
+ }
126005
+ break;
126006
+ }
126007
+ case "index": {
126008
+ if (parsed.json) {
126009
+ console.log(JSON.stringify({ success: true, message: "Use hivemind_index tool for session indexing" }));
126010
+ } else {
126011
+ p.intro("swarm memory index");
126012
+ p.log.message("Session indexing is handled by the hivemind_index tool");
126013
+ p.log.message("Use: swarm tool hivemind_index");
126014
+ p.outro("Done");
126015
+ }
126016
+ break;
126017
+ }
126018
+ case "sync": {
126019
+ if (parsed.json) {
126020
+ console.log(JSON.stringify({ success: true, message: "Use hivemind_sync tool for git sync" }));
126021
+ } else {
126022
+ p.intro("swarm memory sync");
126023
+ p.log.message("Memory sync to .hive/memories.jsonl is handled by the hivemind_sync tool");
126024
+ p.log.message("Use: swarm tool hivemind_sync");
126025
+ p.outro("Done");
126026
+ }
126027
+ break;
126028
+ }
126029
+ default: {
126030
+ console.error(`Unknown subcommand: ${subcommand}`);
126031
+ console.error("");
126032
+ console.error("Usage: swarm memory <subcommand> [options]");
126033
+ console.error("");
126034
+ console.error("Subcommands:");
126035
+ console.error(" store <info> [--tags <tags>] Store a memory");
126036
+ console.error(" find <query> [--limit <n>] Search memories");
126037
+ console.error(" get <id> Get memory by ID");
126038
+ console.error(" remove <id> Delete memory");
126039
+ console.error(" validate <id> Reset decay timer");
126040
+ console.error(" stats Show database stats");
126041
+ console.error(" index Index sessions (use hivemind_index)");
126042
+ console.error(" sync Sync to git (use hivemind_sync)");
126043
+ console.error("");
126044
+ console.error("Global options:");
126045
+ console.error(" --json Output JSON");
126046
+ process.exit(1);
126047
+ }
126048
+ }
126049
+ } catch (error54) {
126050
+ if (parsed.json) {
126051
+ console.log(JSON.stringify({
126052
+ success: false,
126053
+ error: error54 instanceof Error ? error54.message : String(error54)
126054
+ }));
126055
+ process.exit(1);
126056
+ } else {
126057
+ p.log.error("Memory operation failed");
126058
+ p.log.message(error54 instanceof Error ? error54.message : String(error54));
126059
+ p.outro("Aborted");
126060
+ process.exit(1);
126061
+ }
126062
+ }
126063
+ }
124966
126064
  var command = process.argv[2];
124967
126065
  switch (command) {
124968
126066
  case "setup": {
@@ -124971,9 +126069,11 @@ switch (command) {
124971
126069
  await setup(reinstallFlag || yesFlag, yesFlag);
124972
126070
  break;
124973
126071
  }
124974
- case "doctor":
124975
- await doctor();
126072
+ case "doctor": {
126073
+ const debugFlag = process.argv.includes("--debug") || process.argv.includes("-d");
126074
+ await doctor(debugFlag);
124976
126075
  break;
126076
+ }
124977
126077
  case "init":
124978
126078
  await init();
124979
126079
  break;
@@ -125000,9 +126100,11 @@ switch (command) {
125000
126100
  }
125001
126101
  break;
125002
126102
  }
125003
- case "agents":
125004
- await agents();
126103
+ case "agents": {
126104
+ const agentsNonInteractive = process.argv.includes("--yes") || process.argv.includes("-y");
126105
+ await agents(agentsNonInteractive);
125005
126106
  break;
126107
+ }
125006
126108
  case "migrate":
125007
126109
  await migrate();
125008
126110
  break;
@@ -125031,6 +126133,9 @@ switch (command) {
125031
126133
  case "capture":
125032
126134
  await capture3();
125033
126135
  break;
126136
+ case "memory":
126137
+ await memory();
126138
+ break;
125034
126139
  case "query":
125035
126140
  await query();
125036
126141
  break;