@goondocks/myco 0.19.4 → 0.19.6

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.
Files changed (116) hide show
  1. package/dist/{agent-run-OGWPNU43.js → agent-run-WK5NKBYA.js} +9 -5
  2. package/dist/{agent-run-OGWPNU43.js.map → agent-run-WK5NKBYA.js.map} +1 -1
  3. package/dist/{agent-tasks-XWMDAEPG.js → agent-tasks-2E73GG3A.js} +9 -5
  4. package/dist/{agent-tasks-XWMDAEPG.js.map → agent-tasks-2E73GG3A.js.map} +1 -1
  5. package/dist/{chunk-QLCD77AN.js → chunk-6RFZWV4R.js} +18 -1
  6. package/dist/chunk-6RFZWV4R.js.map +1 -0
  7. package/dist/{chunk-PLYWR5D7.js → chunk-FKBPXCH3.js} +2 -2
  8. package/dist/{chunk-5B2ORGTF.js → chunk-NCBLB2C6.js} +3 -3
  9. package/dist/{chunk-3C4LT4BW.js → chunk-NKQZ73LL.js} +3 -2
  10. package/dist/chunk-NKQZ73LL.js.map +1 -0
  11. package/dist/{chunk-RTNLDAIC.js → chunk-P5VNHGVZ.js} +3 -3
  12. package/dist/chunk-P5VNHGVZ.js.map +1 -0
  13. package/dist/{chunk-W3P6MHLQ.js → chunk-QH5HS54N.js} +2 -2
  14. package/dist/{chunk-NTWJR6KH.js → chunk-ST2D3SGM.js} +2 -2
  15. package/dist/{chunk-WYOE4IAX.js → chunk-TMNFCUAD.js} +81 -8
  16. package/dist/chunk-TMNFCUAD.js.map +1 -0
  17. package/dist/{chunk-YDCGI3CS.js → chunk-VLGBWOBY.js} +3 -3
  18. package/dist/{chunk-Y3IJFUVX.js → chunk-W3JUH5S3.js} +2 -2
  19. package/dist/{cli-XDG624PV.js → cli-LCTXK7N6.js} +41 -37
  20. package/dist/{cli-XDG624PV.js.map → cli-LCTXK7N6.js.map} +1 -1
  21. package/dist/{client-EEPUQVMX.js → client-S47ENM76.js} +3 -3
  22. package/dist/{config-2KQ45OC5.js → config-IO5WALOD.js} +2 -2
  23. package/dist/{doctor-L4LWMJYH.js → doctor-EE6GAC54.js} +11 -7
  24. package/dist/{doctor-L4LWMJYH.js.map → doctor-EE6GAC54.js.map} +1 -1
  25. package/dist/{executor-4TJOZN32.js → executor-NXNSUEMQ.js} +102 -63
  26. package/dist/executor-NXNSUEMQ.js.map +1 -0
  27. package/dist/{init-U2SG2IOC.js → init-IPL3XV6F.js} +9 -9
  28. package/dist/{installer-BWJED3ED.js → installer-WMTB4NCX.js} +8 -2
  29. package/dist/{loader-JG5OBPB6.js → loader-V774GZU4.js} +2 -2
  30. package/dist/{main-EVS3FXDJ.js → main-RPJSS7PT.js} +284 -117
  31. package/dist/main-RPJSS7PT.js.map +1 -0
  32. package/dist/{open-TEQZXO4A.js → open-OYBKVBYX.js} +9 -5
  33. package/dist/{open-TEQZXO4A.js.map → open-OYBKVBYX.js.map} +1 -1
  34. package/dist/{post-compact-POSTGJEV.js → post-compact-E2OVMNGQ.js} +4 -4
  35. package/dist/{post-tool-use-VE6YPEY2.js → post-tool-use-FGQE26GJ.js} +3 -3
  36. package/dist/{post-tool-use-failure-LUFD62SB.js → post-tool-use-failure-3CITJYQK.js} +4 -4
  37. package/dist/{pre-compact-7QGJYRJF.js → pre-compact-GYMHCXII.js} +4 -4
  38. package/dist/{remove-4UZXDSVY.js → remove-72ER3TG5.js} +6 -6
  39. package/dist/{restart-HLXD4ZGX.js → restart-EQHEJCGT.js} +10 -6
  40. package/dist/{restart-HLXD4ZGX.js.map → restart-EQHEJCGT.js.map} +1 -1
  41. package/dist/{search-MWXY3GTI.js → search-JOBYIW43.js} +9 -5
  42. package/dist/{search-MWXY3GTI.js.map → search-JOBYIW43.js.map} +1 -1
  43. package/dist/{server-TQY7CYOS.js → server-PZCWYWZL.js} +3 -3
  44. package/dist/{session-P2POKO22.js → session-APO4A2C7.js} +9 -5
  45. package/dist/{session-P2POKO22.js.map → session-APO4A2C7.js.map} +1 -1
  46. package/dist/{session-end-DZNJHGQB.js → session-end-4V4VHAOQ.js} +3 -3
  47. package/dist/{session-start-JNNJTP3C.js → session-start-K6ESRZU7.js} +4 -4
  48. package/dist/{setup-llm-UQO2INBY.js → setup-llm-QUWOSB7A.js} +6 -6
  49. package/dist/src/agent/definitions/tasks/full-intelligence.yaml +37 -8
  50. package/dist/src/agent/prompts/agent.md +2 -2
  51. package/dist/src/cli.js +1 -1
  52. package/dist/src/daemon/main.js +1 -1
  53. package/dist/src/hooks/post-tool-use.js +1 -1
  54. package/dist/src/hooks/session-end.js +1 -1
  55. package/dist/src/hooks/session-start.js +1 -1
  56. package/dist/src/hooks/stop.js +1 -1
  57. package/dist/src/hooks/user-prompt-submit.js +1 -1
  58. package/dist/src/mcp/server.js +1 -1
  59. package/dist/{stats-DJYTDCUE.js → stats-TYOZAOP2.js} +7 -7
  60. package/dist/{stop-VBA4RMQM.js → stop-2COOWEYG.js} +3 -3
  61. package/dist/{stop-failure-54Z2HSU4.js → stop-failure-UQ33GZLE.js} +4 -4
  62. package/dist/{subagent-start-XL773ZID.js → subagent-start-YENEY6VF.js} +4 -4
  63. package/dist/{subagent-stop-HJVSYNII.js → subagent-stop-W2757YDB.js} +4 -4
  64. package/dist/{task-completed-GLNYNBYP.js → task-completed-KU6GWMWV.js} +4 -4
  65. package/dist/{team-M6TC4TFC.js → team-SNLC6FZM.js} +3 -3
  66. package/dist/{turns-3ZQAF6HF.js → turns-YFNI5CQC.js} +6 -4
  67. package/dist/ui/assets/index-816yFmz_.js +842 -0
  68. package/dist/ui/assets/index-Dj6vQpFd.css +1 -0
  69. package/dist/ui/index.html +2 -2
  70. package/dist/{update-JZV2K4YG.js → update-5VYNQZJ4.js} +6 -6
  71. package/dist/update-5VYNQZJ4.js.map +1 -0
  72. package/dist/{user-prompt-submit-6KMTMHKW.js → user-prompt-submit-KATLHAKA.js} +3 -3
  73. package/dist/{verify-CJHF23QH.js → verify-BGJVB3K2.js} +2 -2
  74. package/dist/{version-KS3UADP5.js → version-MKNN5GYM.js} +2 -2
  75. package/package.json +1 -1
  76. package/skills/rules/SKILL.md +6 -0
  77. package/dist/chunk-3C4LT4BW.js.map +0 -1
  78. package/dist/chunk-QLCD77AN.js.map +0 -1
  79. package/dist/chunk-RTNLDAIC.js.map +0 -1
  80. package/dist/chunk-WYOE4IAX.js.map +0 -1
  81. package/dist/executor-4TJOZN32.js.map +0 -1
  82. package/dist/main-EVS3FXDJ.js.map +0 -1
  83. package/dist/ui/assets/index-CRmkSi63.css +0 -1
  84. package/dist/ui/assets/index-CwPuGRsJ.js +0 -842
  85. package/dist/update-JZV2K4YG.js.map +0 -1
  86. /package/dist/{chunk-PLYWR5D7.js.map → chunk-FKBPXCH3.js.map} +0 -0
  87. /package/dist/{chunk-5B2ORGTF.js.map → chunk-NCBLB2C6.js.map} +0 -0
  88. /package/dist/{chunk-W3P6MHLQ.js.map → chunk-QH5HS54N.js.map} +0 -0
  89. /package/dist/{chunk-NTWJR6KH.js.map → chunk-ST2D3SGM.js.map} +0 -0
  90. /package/dist/{chunk-YDCGI3CS.js.map → chunk-VLGBWOBY.js.map} +0 -0
  91. /package/dist/{chunk-Y3IJFUVX.js.map → chunk-W3JUH5S3.js.map} +0 -0
  92. /package/dist/{client-EEPUQVMX.js.map → client-S47ENM76.js.map} +0 -0
  93. /package/dist/{config-2KQ45OC5.js.map → config-IO5WALOD.js.map} +0 -0
  94. /package/dist/{init-U2SG2IOC.js.map → init-IPL3XV6F.js.map} +0 -0
  95. /package/dist/{installer-BWJED3ED.js.map → installer-WMTB4NCX.js.map} +0 -0
  96. /package/dist/{loader-JG5OBPB6.js.map → loader-V774GZU4.js.map} +0 -0
  97. /package/dist/{post-compact-POSTGJEV.js.map → post-compact-E2OVMNGQ.js.map} +0 -0
  98. /package/dist/{post-tool-use-VE6YPEY2.js.map → post-tool-use-FGQE26GJ.js.map} +0 -0
  99. /package/dist/{post-tool-use-failure-LUFD62SB.js.map → post-tool-use-failure-3CITJYQK.js.map} +0 -0
  100. /package/dist/{pre-compact-7QGJYRJF.js.map → pre-compact-GYMHCXII.js.map} +0 -0
  101. /package/dist/{remove-4UZXDSVY.js.map → remove-72ER3TG5.js.map} +0 -0
  102. /package/dist/{server-TQY7CYOS.js.map → server-PZCWYWZL.js.map} +0 -0
  103. /package/dist/{session-end-DZNJHGQB.js.map → session-end-4V4VHAOQ.js.map} +0 -0
  104. /package/dist/{session-start-JNNJTP3C.js.map → session-start-K6ESRZU7.js.map} +0 -0
  105. /package/dist/{setup-llm-UQO2INBY.js.map → setup-llm-QUWOSB7A.js.map} +0 -0
  106. /package/dist/{stats-DJYTDCUE.js.map → stats-TYOZAOP2.js.map} +0 -0
  107. /package/dist/{stop-VBA4RMQM.js.map → stop-2COOWEYG.js.map} +0 -0
  108. /package/dist/{stop-failure-54Z2HSU4.js.map → stop-failure-UQ33GZLE.js.map} +0 -0
  109. /package/dist/{subagent-start-XL773ZID.js.map → subagent-start-YENEY6VF.js.map} +0 -0
  110. /package/dist/{subagent-stop-HJVSYNII.js.map → subagent-stop-W2757YDB.js.map} +0 -0
  111. /package/dist/{task-completed-GLNYNBYP.js.map → task-completed-KU6GWMWV.js.map} +0 -0
  112. /package/dist/{team-M6TC4TFC.js.map → team-SNLC6FZM.js.map} +0 -0
  113. /package/dist/{turns-3ZQAF6HF.js.map → turns-YFNI5CQC.js.map} +0 -0
  114. /package/dist/{user-prompt-submit-6KMTMHKW.js.map → user-prompt-submit-KATLHAKA.js.map} +0 -0
  115. /package/dist/{verify-CJHF23QH.js.map → verify-BGJVB3K2.js.map} +0 -0
  116. /package/dist/{version-KS3UADP5.js.map → version-MKNN5GYM.js.map} +0 -0
@@ -15,7 +15,7 @@ import {
15
15
  getEmbeddingQueueDepth,
16
16
  getUnembedded,
17
17
  markEmbedded
18
- } from "./chunk-YDCGI3CS.js";
18
+ } from "./chunk-VLGBWOBY.js";
19
19
  import {
20
20
  getTeamPackageVersion,
21
21
  loadSecrets,
@@ -23,7 +23,7 @@ import {
23
23
  readSecrets,
24
24
  resolveVaultConfigPath,
25
25
  writeSecret
26
- } from "./chunk-PLYWR5D7.js";
26
+ } from "./chunk-FKBPXCH3.js";
27
27
  import {
28
28
  buildTaskInstruction,
29
29
  closeOpenBatches,
@@ -71,7 +71,7 @@ import {
71
71
  setResponseSummary,
72
72
  updateCandidate,
73
73
  updateNotificationStatus
74
- } from "./chunk-RTNLDAIC.js";
74
+ } from "./chunk-P5VNHGVZ.js";
75
75
  import {
76
76
  fullTextSearch,
77
77
  hydrateSearchResults
@@ -91,7 +91,7 @@ import {
91
91
  } from "./chunk-Q4QD6LJT.js";
92
92
  import {
93
93
  listTurnsByRun
94
- } from "./chunk-QLCD77AN.js";
94
+ } from "./chunk-6RFZWV4R.js";
95
95
  import {
96
96
  cleanupStagedSkill,
97
97
  listStaleStagingDirs
@@ -109,9 +109,11 @@ import {
109
109
  listBufferSessionIds
110
110
  } from "./chunk-V7XG6V6C.js";
111
111
  import "./chunk-POEPHBQK.js";
112
- import "./chunk-5B2ORGTF.js";
112
+ import "./chunk-NCBLB2C6.js";
113
113
  import "./chunk-SAKJMNSR.js";
114
- import "./chunk-WYOE4IAX.js";
114
+ import {
115
+ SymbiontInstaller
116
+ } from "./chunk-TMNFCUAD.js";
115
117
  import {
116
118
  checkLocalProvider
117
119
  } from "./chunk-6ZDJXSEO.js";
@@ -168,7 +170,7 @@ import {
168
170
  updateBackupConfig,
169
171
  updateConfig,
170
172
  updateTeamConfig
171
- } from "./chunk-3C4LT4BW.js";
173
+ } from "./chunk-NKQZ73LL.js";
172
174
  import {
173
175
  closeDatabase,
174
176
  getDatabase,
@@ -177,12 +179,13 @@ import {
177
179
  } from "./chunk-MYX5NCRH.js";
178
180
  import {
179
181
  resolveCliEntryPath
180
- } from "./chunk-W3P6MHLQ.js";
182
+ } from "./chunk-QH5HS54N.js";
181
183
  import {
182
184
  getPluginVersion
183
- } from "./chunk-NTWJR6KH.js";
185
+ } from "./chunk-ST2D3SGM.js";
184
186
  import {
185
- loadManifests
187
+ loadManifests,
188
+ resolvePackageRoot
186
189
  } from "./chunk-UVKQ62II.js";
187
190
  import {
188
191
  findPackageRoot
@@ -1406,10 +1409,12 @@ async function handlePutConfig(vaultDir, body) {
1406
1409
  function createPlanDirHandlers(deps) {
1407
1410
  const { vaultDir, symbiontPlanDirsByAgent, symbiontPlanDirs } = deps;
1408
1411
  async function handleGetPlanDirs(_req) {
1412
+ const config = loadConfig(vaultDir);
1409
1413
  return {
1410
1414
  body: {
1411
1415
  symbiont: symbiontPlanDirsByAgent,
1412
- custom: deps.planWatchConfig.watchDirs.filter((d) => !symbiontPlanDirs.includes(d))
1416
+ custom: deps.planWatchConfig.watchDirs.filter((d) => !symbiontPlanDirs.includes(d)),
1417
+ ignore_plan_dirs_in_git: config.capture.ignore_plan_dirs_in_git
1413
1418
  }
1414
1419
  };
1415
1420
  }
@@ -1418,15 +1423,28 @@ function createPlanDirHandlers(deps) {
1418
1423
  if (!Array.isArray(body.plan_dirs)) {
1419
1424
  return { status: 400, body: { error: "plan_dirs must be an array" } };
1420
1425
  }
1426
+ if (body.ignore_plan_dirs_in_git !== void 0 && typeof body.ignore_plan_dirs_in_git !== "boolean") {
1427
+ return { status: 400, body: { error: "ignore_plan_dirs_in_git must be a boolean" } };
1428
+ }
1421
1429
  const updated = updateConfig(vaultDir, (cfg) => ({
1422
1430
  ...cfg,
1423
- capture: { ...cfg.capture, plan_dirs: body.plan_dirs }
1431
+ capture: {
1432
+ ...cfg.capture,
1433
+ plan_dirs: body.plan_dirs,
1434
+ ignore_plan_dirs_in_git: body.ignore_plan_dirs_in_git ?? cfg.capture.ignore_plan_dirs_in_git
1435
+ }
1424
1436
  }));
1425
1437
  deps.setPlanWatchConfig({
1426
1438
  ...deps.planWatchConfig,
1427
1439
  watchDirs: [.../* @__PURE__ */ new Set([...symbiontPlanDirs, ...body.plan_dirs])]
1428
1440
  });
1429
- return { body: { custom: updated.capture.plan_dirs } };
1441
+ deps.reconcileProjectFiles?.();
1442
+ return {
1443
+ body: {
1444
+ custom: updated.capture.plan_dirs,
1445
+ ignore_plan_dirs_in_git: updated.capture.ignore_plan_dirs_in_git
1446
+ }
1447
+ };
1430
1448
  }
1431
1449
  return { handleGetPlanDirs, handleUpdatePlanDirs };
1432
1450
  }
@@ -2200,9 +2218,33 @@ function createUpdateHandlers(deps) {
2200
2218
  };
2201
2219
  }
2202
2220
 
2203
- // src/daemon/backup.ts
2221
+ // src/symbionts/reconcile.ts
2204
2222
  import fs12 from "fs";
2205
2223
  import path12 from "path";
2224
+ function getConfiguredManifests(projectRoot, config) {
2225
+ const allManifests = loadManifests();
2226
+ const enabledNames = getEnabledSymbiontNames(config);
2227
+ if (enabledNames) {
2228
+ return allManifests.filter((manifest) => enabledNames.has(manifest.name));
2229
+ }
2230
+ return allManifests.filter((manifest) => fs12.existsSync(path12.join(projectRoot, manifest.configDir)));
2231
+ }
2232
+ function reconcileConfiguredSymbionts(projectRoot, vaultDir = path12.join(projectRoot, ".myco")) {
2233
+ const config = loadConfig(vaultDir);
2234
+ const manifests = getConfiguredManifests(projectRoot, config);
2235
+ const packageRoot = resolvePackageRoot();
2236
+ let updatedCount = 0;
2237
+ for (const manifest of manifests) {
2238
+ const installer = new SymbiontInstaller(manifest, projectRoot, packageRoot);
2239
+ installer.install();
2240
+ updatedCount++;
2241
+ }
2242
+ return updatedCount;
2243
+ }
2244
+
2245
+ // src/daemon/backup.ts
2246
+ import fs13 from "fs";
2247
+ import path13 from "path";
2206
2248
  var BACKUP_TABLES = [
2207
2249
  "sessions",
2208
2250
  "prompt_batches",
@@ -2229,7 +2271,7 @@ function toSqlLiteral(value) {
2229
2271
  return `'${escapeSql(String(value))}'`;
2230
2272
  }
2231
2273
  function createBackup(db, backupDir, machineId) {
2232
- fs12.mkdirSync(backupDir, { recursive: true });
2274
+ fs13.mkdirSync(backupDir, { recursive: true });
2233
2275
  const lines = [];
2234
2276
  const timestamp = epochSeconds();
2235
2277
  lines.push(`${BACKUP_HEADER_TEMPLATE}: machine_id=${machineId}, created_at=${timestamp}`);
@@ -2247,22 +2289,22 @@ function createBackup(db, backupDir, machineId) {
2247
2289
  }
2248
2290
  lines.push("");
2249
2291
  }
2250
- const filePath = path12.join(backupDir, `${machineId}${BACKUP_EXTENSION}`);
2251
- fs12.writeFileSync(filePath, lines.join("\n"), "utf-8");
2292
+ const filePath = path13.join(backupDir, `${machineId}${BACKUP_EXTENSION}`);
2293
+ fs13.writeFileSync(filePath, lines.join("\n"), "utf-8");
2252
2294
  return filePath;
2253
2295
  }
2254
2296
  function listBackups(backupDir) {
2255
2297
  let entries;
2256
2298
  try {
2257
- entries = fs12.readdirSync(backupDir);
2299
+ entries = fs13.readdirSync(backupDir);
2258
2300
  } catch {
2259
2301
  return [];
2260
2302
  }
2261
2303
  const backups = [];
2262
2304
  for (const entry of entries) {
2263
2305
  if (!BACKUP_FILENAME_PATTERN.test(entry)) continue;
2264
- const filePath = path12.join(backupDir, entry);
2265
- const stat = fs12.statSync(filePath);
2306
+ const filePath = path13.join(backupDir, entry);
2307
+ const stat = fs13.statSync(filePath);
2266
2308
  backups.push({
2267
2309
  machine_id: entry.slice(0, -BACKUP_EXTENSION.length),
2268
2310
  file_name: entry,
@@ -2274,7 +2316,7 @@ function listBackups(backupDir) {
2274
2316
  }
2275
2317
  var INSERT_REGEX = /^INSERT OR IGNORE INTO (\w+)\s+\(([^)]+)\)\s+VALUES\s+\((.+)\);$/;
2276
2318
  function parseBackupFile(backupPath) {
2277
- const content = fs12.readFileSync(backupPath, "utf-8");
2319
+ const content = fs13.readFileSync(backupPath, "utf-8");
2278
2320
  const inserts = [];
2279
2321
  for (const line of content.split("\n")) {
2280
2322
  const match = INSERT_REGEX.exec(line);
@@ -2358,7 +2400,7 @@ function restoreBackup(db, backupPath) {
2358
2400
  }
2359
2401
 
2360
2402
  // src/daemon/api/backup.ts
2361
- import path13 from "path";
2403
+ import path14 from "path";
2362
2404
  function createBackupHandlers(deps) {
2363
2405
  async function handleCreateBackup(_req) {
2364
2406
  const filePath = createBackup(deps.db, deps.backupDir, deps.machineId);
@@ -2417,7 +2459,7 @@ function createBackupConfigHandlers(deps) {
2417
2459
  const { vaultDir } = deps;
2418
2460
  async function handleGetBackupConfig() {
2419
2461
  const cfg = loadConfig(vaultDir);
2420
- return { body: { dir: cfg.backup.dir ?? null, default_dir: path13.resolve(vaultDir, "backups") } };
2462
+ return { body: { dir: cfg.backup.dir ?? null, default_dir: path14.resolve(vaultDir, "backups") } };
2421
2463
  }
2422
2464
  async function handlePutBackupConfig(req) {
2423
2465
  const { dir } = req.body;
@@ -2587,15 +2629,15 @@ var TeamSyncClient = class _TeamSyncClient {
2587
2629
  "Content-Type": "application/json"
2588
2630
  };
2589
2631
  }
2590
- async request(method, path22, body) {
2591
- const res = await this.fetchFn(`${this.workerUrl}${path22}`, {
2632
+ async request(method, path23, body) {
2633
+ const res = await this.fetchFn(`${this.workerUrl}${path23}`, {
2592
2634
  method,
2593
2635
  headers: this.headers(),
2594
2636
  body: body !== void 0 ? JSON.stringify(body) : void 0
2595
2637
  });
2596
2638
  if (!res.ok) {
2597
2639
  const text = await res.text().catch(() => "");
2598
- throw new Error(`Team sync request ${method} ${path22} failed: ${res.status} ${text}`);
2640
+ throw new Error(`Team sync request ${method} ${path23} failed: ${res.status} ${text}`);
2599
2641
  }
2600
2642
  return res.json();
2601
2643
  }
@@ -2730,7 +2772,7 @@ function createTeamHandlers(deps) {
2730
2772
  return { body: { retried: count } };
2731
2773
  }
2732
2774
  async function handleUpgradeWorker(_req) {
2733
- const { upgradeWorker } = await import("./team-M6TC4TFC.js");
2775
+ const { upgradeWorker } = await import("./team-SNLC6FZM.js");
2734
2776
  logger.info("team-sync.upgrade.start", "Starting worker upgrade");
2735
2777
  const result = upgradeWorker(vaultDir);
2736
2778
  if (!result.success) {
@@ -2946,8 +2988,8 @@ function createSessionLifecycleHandlers(deps) {
2946
2988
  }
2947
2989
 
2948
2990
  // src/daemon/api/skills.ts
2949
- import fs13 from "fs";
2950
- import path14 from "path";
2991
+ import fs14 from "fs";
2992
+ import path15 from "path";
2951
2993
 
2952
2994
  // src/db/queries/skill-usage.ts
2953
2995
  var USAGE_COLUMNS = [
@@ -3114,15 +3156,15 @@ function createSkillRecordDeleteHandler(deps) {
3114
3156
  if (result.body?.deleted) {
3115
3157
  const record = result.body;
3116
3158
  if (record.name) {
3117
- const projectRoot = path14.resolve(vaultDir, "..");
3118
- const skillDir = path14.resolve(projectRoot, ".agents", "skills", record.name);
3159
+ const projectRoot = path15.resolve(vaultDir, "..");
3160
+ const skillDir = path15.resolve(projectRoot, ".agents", "skills", record.name);
3119
3161
  try {
3120
- fs13.rmSync(skillDir, { recursive: true, force: true });
3162
+ fs14.rmSync(skillDir, { recursive: true, force: true });
3121
3163
  } catch (err) {
3122
3164
  logger.warn(LOG_KINDS.PROCESSOR_BATCH, "Failed to remove skill directory", { name: record.name, error: String(err) });
3123
3165
  }
3124
3166
  try {
3125
- const { syncSkillSymlinks } = await import("./installer-BWJED3ED.js");
3167
+ const { syncSkillSymlinks } = await import("./installer-WMTB4NCX.js");
3126
3168
  syncSkillSymlinks(projectRoot, record.name, { remove: true });
3127
3169
  } catch (err) {
3128
3170
  logger.warn(LOG_KINDS.PROCESSOR_BATCH, "Failed to remove skill symlinks", { name: record.name, error: String(err) });
@@ -3375,12 +3417,12 @@ async function handleGetModels(req) {
3375
3417
 
3376
3418
  // src/daemon/api/stats.ts
3377
3419
  import { createHash as createHash2 } from "crypto";
3378
- import fs14 from "fs";
3379
- import path15 from "path";
3420
+ import fs15 from "fs";
3421
+ import path16 from "path";
3380
3422
  function computeConfigHash(vaultDir) {
3381
3423
  try {
3382
- const configPath = path15.join(vaultDir, CONFIG_FILENAME);
3383
- const raw = fs14.readFileSync(configPath, "utf-8");
3424
+ const configPath = path16.join(vaultDir, CONFIG_FILENAME);
3425
+ const raw = fs15.readFileSync(configPath, "utf-8");
3384
3426
  return createHash2("md5").update(raw).digest("hex");
3385
3427
  } catch {
3386
3428
  return "";
@@ -3746,7 +3788,7 @@ async function triggerTitleSummary(sessionId, deps) {
3746
3788
  if (config.agent.summary_batch_interval <= 0) return;
3747
3789
  if (config.agent.event_tasks_enabled === false) return;
3748
3790
  try {
3749
- const { runAgent } = await import("./executor-4TJOZN32.js");
3791
+ const { runAgent } = await import("./executor-NXNSUEMQ.js");
3750
3792
  runAgent(vaultDir, {
3751
3793
  task: "title-summary",
3752
3794
  instruction: `Process session ${sessionId} only`,
@@ -3858,6 +3900,9 @@ var DEFAULT_LIST_OFFSET3 = 0;
3858
3900
  var DEFAULT_GRAPH_DEPTH = 1;
3859
3901
  var MAX_GRAPH_DEPTH = 3;
3860
3902
  var SPORE_NAME_PREVIEW_CHARS = 60;
3903
+ var GRAPH_SEED_ENTITY_LIMIT = 4;
3904
+ var GRAPH_SEED_SPORE_LIMIT = 4;
3905
+ var GRAPH_SEED_SESSION_LIMIT = 4;
3861
3906
  var EXCLUDED_GRAPH_EDGE_TYPES = /* @__PURE__ */ new Set(["HAS_BATCH", "EXTRACTED_FROM"]);
3862
3907
  async function handleListSpores(req) {
3863
3908
  const agentId = req.query.agent_id;
@@ -3898,11 +3943,93 @@ async function handleListEntities(req) {
3898
3943
  });
3899
3944
  return { body: { entities } };
3900
3945
  }
3946
+ async function handleGetGraphSeeds(_req) {
3947
+ const db = getDatabase();
3948
+ const sporeRows = db.prepare(
3949
+ `SELECT id, observation_type, status, content, created_at
3950
+ FROM spores
3951
+ WHERE agent_id = ? AND status = 'active'
3952
+ ORDER BY created_at DESC
3953
+ LIMIT ?`
3954
+ ).all(DEFAULT_AGENT_ID, GRAPH_SEED_SPORE_LIMIT);
3955
+ const sessionRows = db.prepare(
3956
+ `SELECT id, title, summary, status, started_at as created_at
3957
+ FROM sessions
3958
+ WHERE status != 'active'
3959
+ ORDER BY started_at DESC
3960
+ LIMIT ?`
3961
+ ).all(GRAPH_SEED_SESSION_LIMIT);
3962
+ const entityRows = db.prepare(
3963
+ `SELECT e.id, e.type, e.name, e.status, e.first_seen as created_at, COUNT(em.entity_id) as mention_count
3964
+ FROM entities e
3965
+ LEFT JOIN entity_mentions em ON em.entity_id = e.id
3966
+ WHERE e.agent_id = ? AND e.status = 'active'
3967
+ GROUP BY e.id
3968
+ ORDER BY mention_count DESC, e.last_seen DESC
3969
+ LIMIT ?`
3970
+ ).all(DEFAULT_AGENT_ID, GRAPH_SEED_ENTITY_LIMIT);
3971
+ const sporeSeeds = sporeRows.map((row) => ({
3972
+ id: row.id,
3973
+ name: (row.content ?? "").slice(0, SPORE_NAME_PREVIEW_CHARS),
3974
+ type: "spore",
3975
+ status: row.status ?? void 0,
3976
+ created_at: row.created_at,
3977
+ content: row.content,
3978
+ observation_type: row.observation_type
3979
+ }));
3980
+ const sessionSeeds = sessionRows.map((row) => ({
3981
+ id: row.id,
3982
+ name: row.title ?? `Session ${row.id.slice(-6)}`,
3983
+ type: "session",
3984
+ status: row.status ?? void 0,
3985
+ created_at: row.created_at,
3986
+ content: row.summary ?? void 0
3987
+ }));
3988
+ const entitySeeds = entityRows.map((row) => ({
3989
+ id: row.id,
3990
+ name: row.name,
3991
+ type: row.type,
3992
+ status: row.status ?? void 0,
3993
+ created_at: row.created_at,
3994
+ mention_count: Number(row.mention_count) || 0
3995
+ }));
3996
+ const seeds = [
3997
+ ...entitySeeds,
3998
+ ...sessionSeeds,
3999
+ ...sporeSeeds
4000
+ ];
4001
+ const recommendedId = entitySeeds[0]?.id ?? sessionSeeds[0]?.id ?? sporeSeeds[0]?.id ?? null;
4002
+ return {
4003
+ body: {
4004
+ seeds,
4005
+ recommended_id: recommendedId
4006
+ }
4007
+ };
4008
+ }
3901
4009
  async function handleGetGraph(req) {
3902
4010
  const depth = Math.min(Number(req.query.depth) || DEFAULT_GRAPH_DEPTH, MAX_GRAPH_DEPTH);
3903
- const center = getEntity(req.params.id);
3904
- if (!center) return { status: 404, body: { error: "not_found" } };
3905
- const graph = getGraphForNode(req.params.id, "entity", { depth });
4011
+ const id = req.params.id;
4012
+ let centerNode = null;
4013
+ let centerType = "entity";
4014
+ const entity = getEntity(id);
4015
+ if (entity) {
4016
+ centerNode = entity;
4017
+ centerType = "entity";
4018
+ } else {
4019
+ const spore = getSpore(id);
4020
+ if (spore) {
4021
+ centerNode = spore;
4022
+ centerType = "spore";
4023
+ } else {
4024
+ const session = getSession(id);
4025
+ if (session) {
4026
+ centerNode = session;
4027
+ centerType = "session";
4028
+ }
4029
+ }
4030
+ }
4031
+ if (!centerNode) return { status: 404, body: { error: "not_found" } };
4032
+ const graph = getGraphForNode(id, centerType, { depth });
3906
4033
  const filteredEdges = graph.edges.filter(
3907
4034
  (e) => !EXCLUDED_GRAPH_EDGE_TYPES.has(e.type)
3908
4035
  );
@@ -3911,24 +4038,26 @@ async function handleGetGraph(req) {
3911
4038
  const sporeIds = /* @__PURE__ */ new Set();
3912
4039
  const sessionIds = /* @__PURE__ */ new Set();
3913
4040
  for (const edge of filteredEdges) {
3914
- for (const [id, type] of [
4041
+ for (const [nodeId, type] of [
3915
4042
  [edge.source_id, edge.source_type],
3916
4043
  [edge.target_id, edge.target_type]
3917
4044
  ]) {
3918
4045
  switch (type) {
3919
4046
  case "entity":
3920
- entityIds.add(id);
4047
+ entityIds.add(nodeId);
3921
4048
  break;
3922
4049
  case "spore":
3923
- sporeIds.add(id);
4050
+ sporeIds.add(nodeId);
3924
4051
  break;
3925
4052
  case "session":
3926
- sessionIds.add(id);
4053
+ sessionIds.add(nodeId);
3927
4054
  break;
3928
4055
  }
3929
4056
  }
3930
4057
  }
3931
- entityIds.add(center.id);
4058
+ if (centerType === "entity") entityIds.add(id);
4059
+ if (centerType === "spore") sporeIds.add(id);
4060
+ if (centerType === "session") sessionIds.add(id);
3932
4061
  const entityIdArray = Array.from(entityIds);
3933
4062
  let entityNodes = [];
3934
4063
  if (entityIdArray.length > 0) {
@@ -3996,17 +4125,17 @@ async function handleGetGraph(req) {
3996
4125
  content: n.summary ?? void 0
3997
4126
  }))
3998
4127
  ];
3999
- const centerNode = allNodes.find((n) => n.id === center.id);
4000
4128
  const uiEdges = filteredEdges.map((e) => ({
4001
4129
  source_id: e.source_id,
4002
4130
  target_id: e.target_id,
4003
4131
  label: e.type,
4004
4132
  weight: e.confidence
4005
4133
  }));
4134
+ const centerResponseNode = allNodes.find((n) => n.id === id);
4006
4135
  return {
4007
4136
  body: {
4008
- center: centerNode ?? { ...center, mention_count: mentionCounts.get(center.id) ?? 0 },
4009
- nodes: allNodes.filter((n) => n.id !== center.id),
4137
+ center: centerResponseNode,
4138
+ nodes: allNodes.filter((n) => n.id !== id),
4010
4139
  edges: uiEdges,
4011
4140
  depth
4012
4141
  }
@@ -5433,17 +5562,17 @@ var SqliteRecordSource = class {
5433
5562
  };
5434
5563
 
5435
5564
  // src/daemon/database/manager.ts
5436
- import fs16 from "fs";
5565
+ import fs17 from "fs";
5437
5566
 
5438
5567
  // src/db/queries/database.ts
5439
- import fs15 from "fs";
5568
+ import fs16 from "fs";
5440
5569
  function pragmaScalar(name) {
5441
5570
  const db = getDatabase();
5442
5571
  return db.pragma(name, { simple: true });
5443
5572
  }
5444
5573
  function safeFileSize(filePath) {
5445
5574
  try {
5446
- return fs15.statSync(filePath).size;
5575
+ return fs16.statSync(filePath).size;
5447
5576
  } catch (err) {
5448
5577
  if (err.code === "ENOENT") return 0;
5449
5578
  throw err;
@@ -5715,7 +5844,7 @@ var DatabaseMaintenanceManager = class {
5715
5844
  }
5716
5845
  async vacuum() {
5717
5846
  const size_before = this.fileSize();
5718
- const stats = await fs16.promises.statfs(this.vaultDir);
5847
+ const stats = await fs17.promises.statfs(this.vaultDir);
5719
5848
  const free_bytes = Number(stats.bavail) * Number(stats.bsize);
5720
5849
  const required_bytes = size_before * VACUUM_FREE_SPACE_MULTIPLIER;
5721
5850
  if (free_bytes < required_bytes) {
@@ -5763,7 +5892,7 @@ var DatabaseMaintenanceManager = class {
5763
5892
  }
5764
5893
  fileSize() {
5765
5894
  try {
5766
- return fs16.statSync(this.dbPath).size;
5895
+ return fs17.statSync(this.dbPath).size;
5767
5896
  } catch {
5768
5897
  return 0;
5769
5898
  }
@@ -5776,8 +5905,8 @@ function registerBuiltinDomains() {
5776
5905
  domain: "agents",
5777
5906
  label: "Agent Tasks",
5778
5907
  types: [
5779
- { id: "agent.task.success", label: "Task completed", defaultMode: "banner", defaultLevel: "success" },
5780
- { id: "agent.task.failure", label: "Task failed", defaultMode: "banner", defaultLevel: "error" }
5908
+ { id: "agent.task.success", label: "Task completed", defaultMode: "summary", defaultLevel: "success" },
5909
+ { id: "agent.task.failure", label: "Task failed", defaultMode: "summary", defaultLevel: "error" }
5781
5910
  ]
5782
5911
  });
5783
5912
  register({
@@ -5793,8 +5922,8 @@ function registerBuiltinDomains() {
5793
5922
  label: "Skills",
5794
5923
  types: [
5795
5924
  { id: "skill.surveyed", label: "Skill candidate surveyed", defaultMode: "summary", defaultLevel: "info" },
5796
- { id: "skill.created", label: "Skill created", defaultMode: "banner", defaultLevel: "success" },
5797
- { id: "skill.evolved", label: "Skill evolved", defaultMode: "banner", defaultLevel: "info" }
5925
+ { id: "skill.created", label: "Skill created", defaultMode: "summary", defaultLevel: "success" },
5926
+ { id: "skill.evolved", label: "Skill evolved", defaultMode: "summary", defaultLevel: "info" }
5798
5927
  ]
5799
5928
  });
5800
5929
  register({
@@ -5809,7 +5938,7 @@ function registerBuiltinDomains() {
5809
5938
  domain: "daemon",
5810
5939
  label: "Daemon",
5811
5940
  types: [
5812
- { id: "daemon.version_sync", label: "Version sync restart", defaultMode: "banner", defaultLevel: "info" }
5941
+ { id: "daemon.version_sync", label: "Version sync restart", defaultMode: "summary", defaultLevel: "info" }
5813
5942
  ]
5814
5943
  });
5815
5944
  }
@@ -6242,7 +6371,7 @@ async function registerScheduledTasks(powerManager, deps) {
6242
6371
  else runningTasks.delete(name);
6243
6372
  },
6244
6373
  runTask: async (taskName) => {
6245
- const { runAgent } = await import("./executor-4TJOZN32.js");
6374
+ const { runAgent } = await import("./executor-NXNSUEMQ.js");
6246
6375
  const taskConfig = config.agent.tasks?.[taskName];
6247
6376
  const projectRoot = resolve(vaultDir, "..");
6248
6377
  const built = buildTaskInstruction(taskName, taskConfig?.params, taskAgentMap.get(taskName), projectRoot, embeddingManager);
@@ -6281,7 +6410,7 @@ async function registerScheduledTasks(powerManager, deps) {
6281
6410
  link: `/agent?run=${result.runId}`,
6282
6411
  metadata: { taskName, runId: result.runId }
6283
6412
  }, config);
6284
- const { countToolCallsByRun } = await import("./turns-3ZQAF6HF.js");
6413
+ const { countToolCallsByRun } = await import("./turns-YFNI5CQC.js");
6285
6414
  const counts = countToolCallsByRun(result.runId, ["vault_create_spore", "vault_write_digest"]);
6286
6415
  const sporeCount = counts["vault_create_spore"] ?? 0;
6287
6416
  const digestCount = counts["vault_write_digest"] ?? 0;
@@ -6546,7 +6675,7 @@ function createAgentRunHandlers(deps) {
6546
6675
  };
6547
6676
  }
6548
6677
  }
6549
- const { runAgent } = await import("./executor-4TJOZN32.js");
6678
+ const { runAgent } = await import("./executor-NXNSUEMQ.js");
6550
6679
  const resultPromise = runAgent(vaultDir, {
6551
6680
  task,
6552
6681
  instruction,
@@ -6557,13 +6686,29 @@ function createAgentRunHandlers(deps) {
6557
6686
  const effectiveAgentId = agentId ?? "myco-agent";
6558
6687
  const runId = getLatestRunId(effectiveAgentId, task);
6559
6688
  resultPromise.then((result) => {
6689
+ const taskName = task ?? "agent run";
6560
6690
  if (result.status === "failed") {
6691
+ notify(vaultDir, {
6692
+ domain: "agents",
6693
+ type: "agent.task.failure",
6694
+ title: `Task failed: ${taskName}`,
6695
+ message: result.error ?? "Unknown error",
6696
+ link: `/agent?run=${result.runId}`,
6697
+ metadata: { taskName: task ?? null, runId: result.runId }
6698
+ }, mycoConfig);
6561
6699
  logger.error(LOG_KINDS.AGENT_ERROR, "Agent run failed", {
6562
6700
  runId: result.runId,
6563
6701
  error: result.error ?? "No error message",
6564
6702
  phases: result.phases?.map((p) => `${p.name}:${p.status}`) ?? []
6565
6703
  });
6566
6704
  } else {
6705
+ notify(vaultDir, {
6706
+ domain: "agents",
6707
+ type: "agent.task.success",
6708
+ title: `Task completed: ${taskName}`,
6709
+ link: `/agent?run=${result.runId}`,
6710
+ metadata: { taskName: task ?? null, runId: result.runId }
6711
+ }, mycoConfig);
6567
6712
  logger.info(LOG_KINDS.AGENT_RUN, "Agent run completed", {
6568
6713
  runId: result.runId,
6569
6714
  status: result.status,
@@ -6615,8 +6760,8 @@ function createAgentRunHandlers(deps) {
6615
6760
  }
6616
6761
 
6617
6762
  // src/daemon/api/attachments.ts
6618
- import fs17 from "fs";
6619
- import path16 from "path";
6763
+ import fs18 from "fs";
6764
+ import path17 from "path";
6620
6765
  var ATTACHMENT_MEDIA_TYPES = {
6621
6766
  png: "image/png",
6622
6767
  jpg: "image/jpeg",
@@ -6636,14 +6781,14 @@ function createAttachmentHandler(deps) {
6636
6781
  const contentType2 = att.media_type ?? "application/octet-stream";
6637
6782
  return { status: 200, headers: { "Content-Type": contentType2 }, body: att.data };
6638
6783
  }
6639
- const filePath = path16.join(vaultDir, "attachments", filename);
6784
+ const filePath = path17.join(vaultDir, "attachments", filename);
6640
6785
  let diskData;
6641
6786
  try {
6642
- diskData = fs17.readFileSync(filePath);
6787
+ diskData = fs18.readFileSync(filePath);
6643
6788
  } catch {
6644
6789
  return { status: 404, body: { error: "not_found" } };
6645
6790
  }
6646
- const ext = path16.extname(filename).slice(1).toLowerCase();
6791
+ const ext = path17.extname(filename).slice(1).toLowerCase();
6647
6792
  const contentType = ATTACHMENT_MEDIA_TYPES[ext] ?? "application/octet-stream";
6648
6793
  return { status: 200, headers: { "Content-Type": contentType }, body: diskData };
6649
6794
  }
@@ -6651,19 +6796,19 @@ function createAttachmentHandler(deps) {
6651
6796
  }
6652
6797
 
6653
6798
  // src/daemon/log-reconcile.ts
6654
- import fs18 from "fs";
6655
- import path17 from "path";
6799
+ import fs19 from "fs";
6800
+ import path18 from "path";
6656
6801
  function reconcileLogBuffer(logDir, sinceTimestamp) {
6657
6802
  let replayed = 0;
6658
6803
  const files = [];
6659
6804
  for (let i = 3; i >= 1; i--) {
6660
- const rotated = path17.join(logDir, `daemon.${i}.log`);
6661
- if (fs18.existsSync(rotated)) files.push(rotated);
6805
+ const rotated = path18.join(logDir, `daemon.${i}.log`);
6806
+ if (fs19.existsSync(rotated)) files.push(rotated);
6662
6807
  }
6663
- const current = path17.join(logDir, "daemon.log");
6664
- if (fs18.existsSync(current)) files.push(current);
6808
+ const current = path18.join(logDir, "daemon.log");
6809
+ if (fs19.existsSync(current)) files.push(current);
6665
6810
  for (const file of files) {
6666
- const content = fs18.readFileSync(file, "utf-8");
6811
+ const content = fs19.readFileSync(file, "utf-8");
6667
6812
  for (const line of content.split("\n")) {
6668
6813
  if (!line.trim()) continue;
6669
6814
  try {
@@ -6940,8 +7085,8 @@ function registerPowerJobs(powerManager, deps) {
6940
7085
  }
6941
7086
 
6942
7087
  // src/daemon/reconciliation.ts
6943
- import fs19 from "fs";
6944
- import path18 from "path";
7088
+ import fs20 from "fs";
7089
+ import path19 from "path";
6945
7090
 
6946
7091
  // src/daemon/event-handlers.ts
6947
7092
  var TOOL_INPUT_STORE_LIMIT = 4e3;
@@ -7110,10 +7255,10 @@ function createReconciler({ bufferDir, logger }) {
7110
7255
  function reconcileSession(sessionId) {
7111
7256
  if (reconciledSessions.has(sessionId)) return;
7112
7257
  reconciledSessions.add(sessionId);
7113
- const bufferPath = path18.join(bufferDir, `${sessionId}.jsonl`);
7258
+ const bufferPath = path19.join(bufferDir, `${sessionId}.jsonl`);
7114
7259
  let content;
7115
7260
  try {
7116
- content = fs19.readFileSync(bufferPath, "utf-8").trim();
7261
+ content = fs20.readFileSync(bufferPath, "utf-8").trim();
7117
7262
  } catch {
7118
7263
  return;
7119
7264
  }
@@ -7182,7 +7327,7 @@ function createReconciler({ bufferDir, logger }) {
7182
7327
  }
7183
7328
 
7184
7329
  // src/daemon/stop-processing.ts
7185
- import fs20 from "fs";
7330
+ import fs21 from "fs";
7186
7331
 
7187
7332
  // src/daemon/capture-images.ts
7188
7333
  var SESSION_SHORT_LEN = 6;
@@ -7222,7 +7367,7 @@ function captureBatchImages(input) {
7222
7367
  // src/daemon/plan-capture.ts
7223
7368
  import { createHash as createHash4 } from "crypto";
7224
7369
  import os7 from "os";
7225
- import path19 from "path";
7370
+ import path20 from "path";
7226
7371
  function extractTaggedPlans(text, tags) {
7227
7372
  const results = [];
7228
7373
  for (const tag of tags) {
@@ -7248,11 +7393,11 @@ var FILE_WRITE_TOOLS = /* @__PURE__ */ new Set([
7248
7393
  var HEADING_REGEX = /^#\s+(.+)$/m;
7249
7394
  var PLAN_ID_HASH_LENGTH = 16;
7250
7395
  function isInPlanDirectory(filePath, watchDirs, projectRoot) {
7251
- const abs = path19.isAbsolute(filePath) ? filePath : path19.resolve(projectRoot, filePath);
7396
+ const abs = path20.isAbsolute(filePath) ? filePath : path20.resolve(projectRoot, filePath);
7252
7397
  return watchDirs.some((dir) => {
7253
- const expanded = dir.startsWith("~/") ? path19.join(os7.homedir(), dir.slice(2)) : dir;
7254
- const absDir = path19.isAbsolute(expanded) ? expanded : path19.resolve(projectRoot, expanded);
7255
- const prefix = absDir.endsWith(path19.sep) ? absDir : absDir + path19.sep;
7398
+ const expanded = dir.startsWith("~/") ? path20.join(os7.homedir(), dir.slice(2)) : dir;
7399
+ const absDir = path20.isAbsolute(expanded) ? expanded : path20.resolve(projectRoot, expanded);
7400
+ const prefix = absDir.endsWith(path20.sep) ? absDir : absDir + path20.sep;
7256
7401
  return abs === absDir || abs.startsWith(prefix);
7257
7402
  });
7258
7403
  }
@@ -7262,7 +7407,7 @@ function isPlanWriteEvent(toolName, toolInput, config) {
7262
7407
  if (typeof filePath !== "string") return null;
7263
7408
  if (!isInPlanDirectory(filePath, config.watchDirs, config.projectRoot)) return null;
7264
7409
  if (config.extensions?.length) {
7265
- const ext = path19.extname(filePath).toLowerCase();
7410
+ const ext = path20.extname(filePath).toLowerCase();
7266
7411
  if (!config.extensions.includes(ext)) return null;
7267
7412
  }
7268
7413
  return filePath;
@@ -7276,7 +7421,7 @@ function capturePlan(input) {
7276
7421
  const now = Math.floor(Date.now() / 1e3);
7277
7422
  const contentHash = createHash4(CONTENT_HASH_ALGORITHM).update(input.content).digest("hex");
7278
7423
  const id = createHash4("md5").update(input.sourcePath).digest("hex").slice(0, PLAN_ID_HASH_LENGTH);
7279
- const title = parsePlanTitle(input.content, path19.basename(input.sourcePath));
7424
+ const title = parsePlanTitle(input.content, path20.basename(input.sourcePath));
7280
7425
  return upsertPlan({
7281
7426
  id,
7282
7427
  title,
@@ -7445,7 +7590,7 @@ function createStopProcessor(deps) {
7445
7590
  let transcriptText = null;
7446
7591
  if (hookTranscriptPath) {
7447
7592
  try {
7448
- transcriptText = fs20.readFileSync(hookTranscriptPath, "utf-8");
7593
+ transcriptText = fs21.readFileSync(hookTranscriptPath, "utf-8");
7449
7594
  } catch {
7450
7595
  }
7451
7596
  }
@@ -7581,8 +7726,8 @@ function createStopProcessor(deps) {
7581
7726
  }
7582
7727
 
7583
7728
  // src/daemon/event-dispatch.ts
7584
- import fs21 from "fs";
7585
- import path20 from "path";
7729
+ import fs22 from "fs";
7730
+ import path21 from "path";
7586
7731
  var EventBody = external_exports.object({ type: external_exports.string(), session_id: external_exports.string() }).passthrough();
7587
7732
  function createEventDispatcher(deps) {
7588
7733
  const {
@@ -7621,7 +7766,7 @@ function createEventDispatcher(deps) {
7621
7766
  reconcileSession(event.session_id);
7622
7767
  }
7623
7768
  if (!sessionBuffers.has(event.session_id)) {
7624
- const bufferDir = path20.join(vaultDir, "buffer");
7769
+ const bufferDir = path21.join(vaultDir, "buffer");
7625
7770
  sessionBuffers.set(event.session_id, new EventBuffer(bufferDir, event.session_id));
7626
7771
  }
7627
7772
  sessionBuffers.get(event.session_id).append(event);
@@ -7680,10 +7825,10 @@ function createEventDispatcher(deps) {
7680
7825
  );
7681
7826
  if (planFilePath) {
7682
7827
  const captureSessionId = event.session_id;
7683
- fs21.promises.readFile(planFilePath, "utf-8").then((planContent) => {
7828
+ fs22.promises.readFile(planFilePath, "utf-8").then((planContent) => {
7684
7829
  const latestBatch = getLatestBatch(captureSessionId);
7685
7830
  capturePlan({
7686
- sourcePath: path20.relative(projectRoot, planFilePath),
7831
+ sourcePath: path21.relative(projectRoot, planFilePath),
7687
7832
  content: planContent,
7688
7833
  sessionId: captureSessionId,
7689
7834
  promptBatchId: latestBatch?.id ?? null
@@ -7825,14 +7970,14 @@ function createEventDispatcher(deps) {
7825
7970
  }
7826
7971
 
7827
7972
  // src/daemon/main.ts
7828
- import fs22 from "fs";
7973
+ import fs23 from "fs";
7829
7974
  import os8 from "os";
7830
- import path21 from "path";
7975
+ import path22 from "path";
7831
7976
  function killStaleDaemon(vaultDir, logger) {
7832
- const daemonJsonPath = path21.join(vaultDir, "daemon.json");
7977
+ const daemonJsonPath = path22.join(vaultDir, "daemon.json");
7833
7978
  try {
7834
- if (!fs22.existsSync(daemonJsonPath)) return;
7835
- const info = JSON.parse(fs22.readFileSync(daemonJsonPath, "utf-8"));
7979
+ if (!fs23.existsSync(daemonJsonPath)) return;
7980
+ const info = JSON.parse(fs23.readFileSync(daemonJsonPath, "utf-8"));
7836
7981
  if (!info.pid) return;
7837
7982
  if (info.pid === process.pid) return;
7838
7983
  try {
@@ -7841,7 +7986,7 @@ function killStaleDaemon(vaultDir, logger) {
7841
7986
  logger.info(LOG_KINDS.DAEMON_START, "Killed stale daemon", { pid: info.pid });
7842
7987
  } catch {
7843
7988
  }
7844
- fs22.unlinkSync(daemonJsonPath);
7989
+ fs23.unlinkSync(daemonJsonPath);
7845
7990
  } catch {
7846
7991
  }
7847
7992
  }
@@ -7851,7 +7996,7 @@ async function main() {
7851
7996
  process.stderr.write("Usage: mycod --vault <path>\n");
7852
7997
  process.exit(1);
7853
7998
  }
7854
- const vaultDir = path21.resolve(vaultArg);
7999
+ const vaultDir = path22.resolve(vaultArg);
7855
8000
  loadSecrets(vaultDir);
7856
8001
  const config = loadConfig(vaultDir);
7857
8002
  const manifests = loadManifests();
@@ -7863,7 +8008,7 @@ async function main() {
7863
8008
  projectRoot,
7864
8009
  extensions: config.capture.artifact_extensions
7865
8010
  };
7866
- const logger = new DaemonLogger(path21.join(vaultDir, "logs"), {
8011
+ const logger = new DaemonLogger(path22.join(vaultDir, "logs"), {
7867
8012
  level: config.daemon.log_level
7868
8013
  });
7869
8014
  if (config.daemon.log_level === "debug") {
@@ -7892,7 +8037,7 @@ async function main() {
7892
8037
  const devCliEntry = detectDevBuild(
7893
8038
  globalPrefix,
7894
8039
  process.argv[1],
7895
- fs22.realpathSync
8040
+ fs23.realpathSync
7896
8041
  );
7897
8042
  if (devCliEntry) {
7898
8043
  setDevBuildCliEntry(devCliEntry);
@@ -7906,11 +8051,11 @@ async function main() {
7906
8051
  registerBuiltinDomains();
7907
8052
  logger.info(LOG_KINDS.DAEMON_START, "SQLite initialized", { vault: vaultDir });
7908
8053
  {
7909
- const reasonPath = path21.join(vaultDir, RESTART_REASON_FILENAME);
8054
+ const reasonPath = path22.join(vaultDir, RESTART_REASON_FILENAME);
7910
8055
  try {
7911
- if (fs22.existsSync(reasonPath)) {
7912
- const raw = JSON.parse(fs22.readFileSync(reasonPath, "utf-8"));
7913
- fs22.unlinkSync(reasonPath);
8056
+ if (fs23.existsSync(reasonPath)) {
8057
+ const raw = JSON.parse(fs23.readFileSync(reasonPath, "utf-8"));
8058
+ fs23.unlinkSync(reasonPath);
7914
8059
  if (raw.reason === "version_sync" && raw.to_version) {
7915
8060
  const message = raw.local_update_ran ? "Restarted and updated local project hooks." : "Restarted to pick up the latest version.";
7916
8061
  notify(vaultDir, {
@@ -7952,13 +8097,13 @@ async function main() {
7952
8097
  });
7953
8098
  const lastLogTimestamp = getMaxTimestamp();
7954
8099
  if (lastLogTimestamp) {
7955
- const logDir = path21.join(vaultDir, "logs");
8100
+ const logDir = path22.join(vaultDir, "logs");
7956
8101
  const replayedCount = reconcileLogBuffer(logDir, lastLogTimestamp);
7957
8102
  if (replayedCount > 0) {
7958
8103
  logger.info(LOG_KINDS.DAEMON_RECONCILE, `Replayed ${replayedCount} log entries from buffer`, { replayed: replayedCount });
7959
8104
  }
7960
8105
  }
7961
- const vectorsDbPath = path21.join(vaultDir, "vectors.db");
8106
+ const vectorsDbPath = path22.join(vaultDir, "vectors.db");
7962
8107
  const vectorStore = new SqliteVecVectorStore(vectorsDbPath);
7963
8108
  const llmProvider = createEmbeddingProvider(config.embedding);
7964
8109
  const embeddingProvider = new EmbeddingProviderAdapter(llmProvider, config.embedding);
@@ -7978,12 +8123,23 @@ async function main() {
7978
8123
  try {
7979
8124
  const staleDb = getDatabase();
7980
8125
  const staleRows = staleDb.prepare(
7981
- `SELECT id FROM agent_runs WHERE status = 'running'`
8126
+ `SELECT id, task FROM agent_runs WHERE status = 'running'`
7982
8127
  ).all();
7983
8128
  if (staleRows.length > 0) {
8129
+ const completedAt = epochSeconds();
7984
8130
  staleDb.prepare(
7985
8131
  `UPDATE agent_runs SET status = 'failed', completed_at = ?, error = 'Daemon restarted while run was in progress' WHERE status = 'running'`
7986
- ).run(epochSeconds());
8132
+ ).run(completedAt);
8133
+ for (const row of staleRows) {
8134
+ notify(vaultDir, {
8135
+ domain: "agents",
8136
+ type: "agent.task.failure",
8137
+ title: `Task failed: ${row.task ?? "agent run"}`,
8138
+ message: "Daemon restarted while run was in progress",
8139
+ link: `/agent?run=${row.id}`,
8140
+ metadata: { taskName: row.task, runId: row.id, reason: "daemon_restart" }
8141
+ }, config);
8142
+ }
7987
8143
  logger.info(LOG_KINDS.AGENT_RUN, "Cleaned stale running agent runs", {
7988
8144
  count: staleRows.length,
7989
8145
  ids: staleRows.map((r) => r.id)
@@ -7994,10 +8150,10 @@ async function main() {
7994
8150
  }
7995
8151
  let uiDir = null;
7996
8152
  {
7997
- const root = findPackageRoot(path21.dirname(new URL(import.meta.url).pathname));
8153
+ const root = findPackageRoot(path22.dirname(new URL(import.meta.url).pathname));
7998
8154
  if (root) {
7999
- const candidate = path21.join(root, "dist", "ui");
8000
- if (fs22.existsSync(candidate)) uiDir = candidate;
8155
+ const candidate = path22.join(root, "dist", "ui");
8156
+ if (fs23.existsSync(candidate)) uiDir = candidate;
8001
8157
  }
8002
8158
  }
8003
8159
  if (uiDir) {
@@ -8030,7 +8186,7 @@ async function main() {
8030
8186
  (p) => createPerProjectAdapter(p, claudeCodeAdapter.parseTurns)
8031
8187
  )
8032
8188
  });
8033
- const bufferDir = path21.join(vaultDir, "buffer");
8189
+ const bufferDir = path22.join(vaultDir, "buffer");
8034
8190
  const sessionBuffers = /* @__PURE__ */ new Map();
8035
8191
  const reconciler = createReconciler({ bufferDir, logger });
8036
8192
  reconciler.runStartupReconciliation();
@@ -8083,6 +8239,7 @@ async function main() {
8083
8239
  server.registerRoute("PUT", "/api/config", async (req) => {
8084
8240
  const result = await handlePutConfig(vaultDir, req.body);
8085
8241
  if (!result.status || result.status < 400) {
8242
+ reconcileConfiguredSymbionts(path22.dirname(vaultDir), vaultDir);
8086
8243
  configHash = computeConfigHash(vaultDir);
8087
8244
  }
8088
8245
  return result;
@@ -8099,10 +8256,19 @@ async function main() {
8099
8256
  planWatchConfig,
8100
8257
  setPlanWatchConfig: (cfg) => {
8101
8258
  planWatchConfig = cfg;
8259
+ },
8260
+ reconcileProjectFiles: () => {
8261
+ reconcileConfiguredSymbionts(path22.dirname(vaultDir), vaultDir);
8102
8262
  }
8103
8263
  });
8104
8264
  server.registerRoute("GET", "/api/config/plan-dirs", planDirHandlers.handleGetPlanDirs);
8105
- server.registerRoute("POST", "/api/config/plan-dirs", planDirHandlers.handleUpdatePlanDirs);
8265
+ server.registerRoute("POST", "/api/config/plan-dirs", async (req) => {
8266
+ const result = await planDirHandlers.handleUpdatePlanDirs(req);
8267
+ if (!result.status || result.status < 400) {
8268
+ configHash = computeConfigHash(vaultDir);
8269
+ }
8270
+ return result;
8271
+ });
8106
8272
  const configHashRef = { get: () => configHash };
8107
8273
  server.registerRoute("GET", "/api/stats", createLiveStatsHandler({
8108
8274
  vaultDir,
@@ -8117,7 +8283,7 @@ async function main() {
8117
8283
  server.registerRoute("POST", "/api/log", createLogIngestionHandler(logger));
8118
8284
  server.registerRoute("GET", "/api/models", async (req) => handleGetModels(req));
8119
8285
  server.registerRoute("POST", "/api/restart", async (req) => handleRestart({ vaultDir, progressTracker }, req.body));
8120
- const updateProjectRoot = path21.dirname(vaultDir);
8286
+ const updateProjectRoot = path22.dirname(vaultDir);
8121
8287
  const updateHandlers = createUpdateHandlers({
8122
8288
  vaultDir,
8123
8289
  projectRoot: updateProjectRoot,
@@ -8154,6 +8320,7 @@ async function main() {
8154
8320
  server.registerRoute("GET", "/api/spores", handleListSpores);
8155
8321
  server.registerRoute("GET", "/api/spores/:id", handleGetSpore);
8156
8322
  server.registerRoute("GET", "/api/entities", handleListEntities);
8323
+ server.registerRoute("GET", "/api/graph/seeds", handleGetGraphSeeds);
8157
8324
  server.registerRoute("GET", "/api/graph", handleGetFullGraph);
8158
8325
  server.registerRoute("GET", "/api/graph/:id", handleGetGraph);
8159
8326
  server.registerRoute("GET", "/api/digest", handleGetDigest);
@@ -8183,7 +8350,7 @@ async function main() {
8183
8350
  server.registerRoute("GET", "/api/mcp/sessions", mcpProxy.handleSessions);
8184
8351
  server.registerRoute("GET", "/api/mcp/team", mcpProxy.handleTeam);
8185
8352
  const rawBackupDir = config.backup.dir;
8186
- const backupDir = rawBackupDir ? path21.resolve(rawBackupDir.startsWith("~/") ? path21.join(os8.homedir(), rawBackupDir.slice(2)) : rawBackupDir) : path21.resolve(vaultDir, "backups");
8353
+ const backupDir = rawBackupDir ? path22.resolve(rawBackupDir.startsWith("~/") ? path22.join(os8.homedir(), rawBackupDir.slice(2)) : rawBackupDir) : path22.resolve(vaultDir, "backups");
8187
8354
  const backupHandlers = createBackupHandlers({ db, backupDir, machineId });
8188
8355
  server.registerRoute("POST", "/api/backup", backupHandlers.handleCreateBackup);
8189
8356
  server.registerRoute("GET", "/api/backups", backupHandlers.handleListBackups);
@@ -8287,4 +8454,4 @@ export {
8287
8454
  handleUserPrompt,
8288
8455
  main
8289
8456
  };
8290
- //# sourceMappingURL=main-EVS3FXDJ.js.map
8457
+ //# sourceMappingURL=main-RPJSS7PT.js.map