@goondocks/myco 0.3.7 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +9 -4
  4. package/commands/init.md +63 -39
  5. package/commands/setup-llm.md +69 -44
  6. package/commands/status.md +28 -10
  7. package/dist/{chunk-YFG2O5HR.js → chunk-2GJFTIWX.js} +2 -2
  8. package/dist/{chunk-ISCT2SI6.js → chunk-6UJWI4IW.js} +7359 -60
  9. package/dist/chunk-6UJWI4IW.js.map +1 -0
  10. package/dist/{chunk-PA3VMINE.js → chunk-AK6GNLPV.js} +6 -1
  11. package/dist/chunk-AK6GNLPV.js.map +1 -0
  12. package/dist/{chunk-JKOALBZC.js → chunk-BNIYWCST.js} +2 -2
  13. package/dist/{chunk-AWF3M57N.js → chunk-FPEDTLQ6.js} +9 -9
  14. package/dist/{chunk-AWF3M57N.js.map → chunk-FPEDTLQ6.js.map} +1 -1
  15. package/dist/{chunk-QWU7QLZI.js → chunk-I7PNZEBO.js} +10 -10
  16. package/dist/chunk-I7PNZEBO.js.map +1 -0
  17. package/dist/{chunk-7WNE22W7.js → chunk-IVS5MYBL.js} +3 -3
  18. package/dist/{chunk-7WNE22W7.js.map → chunk-IVS5MYBL.js.map} +1 -1
  19. package/dist/{chunk-7VPJK56U.js → chunk-JBD5KP5G.js} +31 -16
  20. package/dist/chunk-JBD5KP5G.js.map +1 -0
  21. package/dist/chunk-MIU3DKLN.js +37 -0
  22. package/dist/chunk-MIU3DKLN.js.map +1 -0
  23. package/dist/{chunk-NYAWCMRZ.js → chunk-OUFSLZTX.js} +4 -4
  24. package/dist/chunk-P7RNAYU7.js +242 -0
  25. package/dist/chunk-P7RNAYU7.js.map +1 -0
  26. package/dist/chunk-T7OC6GH5.js +99 -0
  27. package/dist/chunk-T7OC6GH5.js.map +1 -0
  28. package/dist/chunk-TBRZAJ7W.js +135 -0
  29. package/dist/chunk-TBRZAJ7W.js.map +1 -0
  30. package/dist/chunk-UKWO26VI.js +147 -0
  31. package/dist/chunk-UKWO26VI.js.map +1 -0
  32. package/dist/{chunk-FFQNE6CT.js → chunk-V2OWD2VV.js} +45 -31
  33. package/dist/chunk-V2OWD2VV.js.map +1 -0
  34. package/dist/chunk-WBT5DWGC.js +49 -0
  35. package/dist/chunk-WBT5DWGC.js.map +1 -0
  36. package/dist/{chunk-LR7RQCOB.js → chunk-XCPQHC4X.js} +2 -2
  37. package/dist/{chunk-CCIV47S4.js → chunk-XHWIIU5D.js} +8 -9
  38. package/dist/chunk-XHWIIU5D.js.map +1 -0
  39. package/dist/{chunk-ZBNT6E22.js → chunk-ZCBL5HER.js} +2 -2
  40. package/dist/{cli-3WQSDSW6.js → cli-IGZA3TZC.js} +23 -17
  41. package/dist/cli-IGZA3TZC.js.map +1 -0
  42. package/dist/{client-5T4M42UQ.js → client-5SUO2UYH.js} +5 -5
  43. package/dist/{config-MD4XMLUS.js → config-5FGLQGCW.js} +4 -4
  44. package/dist/{detect-providers-LNOLBICR.js → detect-providers-5FU3BN5Q.js} +3 -3
  45. package/dist/{init-RALMQKOQ.js → init-M3GDZRKI.js} +51 -60
  46. package/dist/init-M3GDZRKI.js.map +1 -0
  47. package/dist/{main-S3WSUF5T.js → main-3JSO25IZ.js} +657 -228
  48. package/dist/main-3JSO25IZ.js.map +1 -0
  49. package/dist/{rebuild-JW6BCHHZ.js → rebuild-MW4GCY6Z.js} +10 -10
  50. package/dist/rebuild-MW4GCY6Z.js.map +1 -0
  51. package/dist/{reprocess-SNXFNKBN.js → reprocess-SWRFIIDZ.js} +18 -18
  52. package/dist/reprocess-SWRFIIDZ.js.map +1 -0
  53. package/dist/{restart-YE2IGOYT.js → restart-5UY2KV54.js} +6 -6
  54. package/dist/{search-2HMG3ON7.js → search-IYVMRZU2.js} +9 -9
  55. package/dist/{server-JM3TM7D2.js → server-FSUSHJ3Y.js} +77 -54
  56. package/dist/{server-JM3TM7D2.js.map → server-FSUSHJ3Y.js.map} +1 -1
  57. package/dist/{session-5GI2YU6R.js → session-QF6MILAC.js} +2 -2
  58. package/dist/{session-start-2UEEEO52.js → session-start-YB4A4PZB.js} +29 -28
  59. package/dist/session-start-YB4A4PZB.js.map +1 -0
  60. package/dist/setup-digest-6TK5SPS6.js +15 -0
  61. package/dist/setup-llm-UGZBURZJ.js +15 -0
  62. package/dist/setup-llm-UGZBURZJ.js.map +1 -0
  63. package/dist/src/cli.js +4 -4
  64. package/dist/src/daemon/main.js +4 -4
  65. package/dist/src/hooks/post-tool-use.js +5 -5
  66. package/dist/src/hooks/session-end.js +5 -5
  67. package/dist/src/hooks/session-start.js +4 -4
  68. package/dist/src/hooks/stop.js +7 -7
  69. package/dist/src/hooks/user-prompt-submit.js +5 -5
  70. package/dist/src/hooks/user-prompt-submit.js.map +1 -1
  71. package/dist/src/mcp/server.js +4 -4
  72. package/dist/src/prompts/classification.md +1 -0
  73. package/dist/src/prompts/digest-10000.md +74 -0
  74. package/dist/src/prompts/digest-1500.md +25 -0
  75. package/dist/src/prompts/digest-3000.md +32 -0
  76. package/dist/src/prompts/digest-5000.md +43 -0
  77. package/dist/src/prompts/digest-system.md +32 -0
  78. package/dist/src/prompts/extraction.md +11 -10
  79. package/dist/src/prompts/summary.md +11 -1
  80. package/dist/src/prompts/title.md +1 -1
  81. package/dist/{stats-IOWXG576.js → stats-IVIXIKTS.js} +12 -12
  82. package/dist/stats-IVIXIKTS.js.map +1 -0
  83. package/dist/{verify-7MWOV72E.js → verify-WEGRM4W2.js} +6 -6
  84. package/dist/{version-S7MHLD5P.js → version-5B2TWXQJ.js} +4 -4
  85. package/dist/version-5B2TWXQJ.js.map +1 -0
  86. package/package.json +1 -1
  87. package/skills/myco/SKILL.md +20 -20
  88. package/skills/myco/references/wisdom.md +14 -14
  89. package/skills/rules/SKILL.md +4 -4
  90. package/dist/chunk-7VPJK56U.js.map +0 -1
  91. package/dist/chunk-BA23DROX.js +0 -160
  92. package/dist/chunk-BA23DROX.js.map +0 -1
  93. package/dist/chunk-CCIV47S4.js.map +0 -1
  94. package/dist/chunk-EF4JVH24.js +0 -7299
  95. package/dist/chunk-EF4JVH24.js.map +0 -1
  96. package/dist/chunk-FFQNE6CT.js.map +0 -1
  97. package/dist/chunk-ISCT2SI6.js.map +0 -1
  98. package/dist/chunk-PA3VMINE.js.map +0 -1
  99. package/dist/chunk-QWU7QLZI.js.map +0 -1
  100. package/dist/chunk-YMYJ7FNH.js +0 -19
  101. package/dist/chunk-YMYJ7FNH.js.map +0 -1
  102. package/dist/cli-3WQSDSW6.js.map +0 -1
  103. package/dist/init-RALMQKOQ.js.map +0 -1
  104. package/dist/main-S3WSUF5T.js.map +0 -1
  105. package/dist/rebuild-JW6BCHHZ.js.map +0 -1
  106. package/dist/reprocess-SNXFNKBN.js.map +0 -1
  107. package/dist/session-start-2UEEEO52.js.map +0 -1
  108. package/dist/stats-IOWXG576.js.map +0 -1
  109. /package/dist/{chunk-YFG2O5HR.js.map → chunk-2GJFTIWX.js.map} +0 -0
  110. /package/dist/{chunk-JKOALBZC.js.map → chunk-BNIYWCST.js.map} +0 -0
  111. /package/dist/{chunk-NYAWCMRZ.js.map → chunk-OUFSLZTX.js.map} +0 -0
  112. /package/dist/{chunk-LR7RQCOB.js.map → chunk-XCPQHC4X.js.map} +0 -0
  113. /package/dist/{chunk-ZBNT6E22.js.map → chunk-ZCBL5HER.js.map} +0 -0
  114. /package/dist/{client-5T4M42UQ.js.map → client-5SUO2UYH.js.map} +0 -0
  115. /package/dist/{config-MD4XMLUS.js.map → config-5FGLQGCW.js.map} +0 -0
  116. /package/dist/{detect-providers-LNOLBICR.js.map → detect-providers-5FU3BN5Q.js.map} +0 -0
  117. /package/dist/{restart-YE2IGOYT.js.map → restart-5UY2KV54.js.map} +0 -0
  118. /package/dist/{search-2HMG3ON7.js.map → search-IYVMRZU2.js.map} +0 -0
  119. /package/dist/{session-5GI2YU6R.js.map → session-QF6MILAC.js.map} +0 -0
  120. /package/dist/{version-S7MHLD5P.js.map → setup-digest-6TK5SPS6.js.map} +0 -0
  121. /package/dist/{verify-7MWOV72E.js.map → verify-WEGRM4W2.js.map} +0 -0
@@ -5,8 +5,16 @@ import {
5
5
  buildSimilarityPrompt,
6
6
  extractNumber,
7
7
  extractTurnsFromBuffer,
8
+ loadPrompt,
9
+ stripReasoningTokens,
8
10
  writeObservationNotes
9
- } from "./chunk-FFQNE6CT.js";
11
+ } from "./chunk-V2OWD2VV.js";
12
+ import {
13
+ handleMycoContext
14
+ } from "./chunk-WBT5DWGC.js";
15
+ import {
16
+ DaemonLogger
17
+ } from "./chunk-5EZ7QF6J.js";
10
18
  import {
11
19
  VaultWriter,
12
20
  bareSessionId,
@@ -14,64 +22,69 @@ import {
14
22
  sessionNoteId,
15
23
  sessionRelativePath,
16
24
  sessionWikilink
17
- } from "./chunk-QWU7QLZI.js";
25
+ } from "./chunk-I7PNZEBO.js";
18
26
  import {
19
27
  indexNote,
20
28
  rebuildIndex
21
- } from "./chunk-AWF3M57N.js";
29
+ } from "./chunk-FPEDTLQ6.js";
22
30
  import {
23
31
  generateEmbedding
24
32
  } from "./chunk-RGVBGTD6.js";
33
+ import {
34
+ createEmbeddingProvider,
35
+ createLlmProvider
36
+ } from "./chunk-IVS5MYBL.js";
25
37
  import {
26
38
  VectorIndex
27
39
  } from "./chunk-XQXXF6MU.js";
28
40
  import {
29
- DaemonLogger
30
- } from "./chunk-5EZ7QF6J.js";
41
+ stripFrontmatter
42
+ } from "./chunk-MIU3DKLN.js";
31
43
  import {
32
44
  initFts
33
45
  } from "./chunk-6FQISQNA.js";
34
46
  import {
35
47
  MycoIndex
36
- } from "./chunk-PA3VMINE.js";
48
+ } from "./chunk-AK6GNLPV.js";
49
+ import "./chunk-P7RNAYU7.js";
37
50
  import {
38
- createEmbeddingProvider,
39
- createLlmProvider
40
- } from "./chunk-7WNE22W7.js";
41
- import "./chunk-BA23DROX.js";
42
- import {
43
- external_exports,
44
51
  loadConfig
45
- } from "./chunk-ISCT2SI6.js";
52
+ } from "./chunk-TBRZAJ7W.js";
46
53
  import {
54
+ external_exports,
47
55
  require_dist
48
- } from "./chunk-EF4JVH24.js";
56
+ } from "./chunk-6UJWI4IW.js";
49
57
  import {
50
58
  EventBuffer
51
59
  } from "./chunk-HIN3UVOG.js";
52
60
  import {
53
61
  getPluginVersion
54
- } from "./chunk-YFG2O5HR.js";
62
+ } from "./chunk-2GJFTIWX.js";
55
63
  import {
56
64
  claudeCodeAdapter,
57
65
  createPerProjectAdapter,
58
66
  extensionForMimeType
59
- } from "./chunk-JKOALBZC.js";
67
+ } from "./chunk-BNIYWCST.js";
60
68
  import {
61
69
  CANDIDATE_CONTENT_PREVIEW,
70
+ CHARS_PER_TOKEN,
62
71
  CONTENT_SNIPPET_CHARS,
63
72
  CONTEXT_SESSION_PREVIEW_CHARS,
73
+ DIGEST_LLM_REQUEST_TIMEOUT_MS,
74
+ DIGEST_SUBSTRATE_TYPE_WEIGHTS,
75
+ DIGEST_TIER_MIN_CONTEXT,
64
76
  EMBEDDING_INPUT_LIMIT,
65
77
  FILE_WATCH_STABILITY_MS,
66
78
  LINEAGE_RECENT_SESSIONS_LIMIT,
67
79
  MAX_SLUG_LENGTH,
68
- PROMPT_CONTEXT_MAX_MEMORIES,
80
+ PROMPT_CONTEXT_MAX_SPORES,
69
81
  PROMPT_CONTEXT_MIN_LENGTH,
70
82
  PROMPT_CONTEXT_MIN_SIMILARITY,
71
- RELATED_MEMORIES_LIMIT,
83
+ RELATED_SPORES_LIMIT,
72
84
  SESSION_CONTEXT_MAX_PLANS,
73
- STALE_BUFFER_MAX_AGE_MS
74
- } from "./chunk-7VPJK56U.js";
85
+ STALE_BUFFER_MAX_AGE_MS,
86
+ estimateTokens
87
+ } from "./chunk-JBD5KP5G.js";
75
88
  import {
76
89
  __toESM
77
90
  } from "./chunk-PZUWP5VK.js";
@@ -483,7 +496,7 @@ var ReaddirpStream = class extends Readable {
483
496
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
484
497
  const statMethod = opts.lstat ? lstat : stat;
485
498
  if (wantBigintFsStats) {
486
- this._stat = (path7) => statMethod(path7, { bigint: true });
499
+ this._stat = (path8) => statMethod(path8, { bigint: true });
487
500
  } else {
488
501
  this._stat = statMethod;
489
502
  }
@@ -508,8 +521,8 @@ var ReaddirpStream = class extends Readable {
508
521
  const par = this.parent;
509
522
  const fil = par && par.files;
510
523
  if (fil && fil.length > 0) {
511
- const { path: path7, depth } = par;
512
- const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path7));
524
+ const { path: path8, depth } = par;
525
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path8));
513
526
  const awaited = await Promise.all(slice);
514
527
  for (const entry of awaited) {
515
528
  if (!entry)
@@ -549,20 +562,20 @@ var ReaddirpStream = class extends Readable {
549
562
  this.reading = false;
550
563
  }
551
564
  }
552
- async _exploreDir(path7, depth) {
565
+ async _exploreDir(path8, depth) {
553
566
  let files;
554
567
  try {
555
- files = await readdir(path7, this._rdOptions);
568
+ files = await readdir(path8, this._rdOptions);
556
569
  } catch (error) {
557
570
  this._onError(error);
558
571
  }
559
- return { files, depth, path: path7 };
572
+ return { files, depth, path: path8 };
560
573
  }
561
- async _formatEntry(dirent, path7) {
574
+ async _formatEntry(dirent, path8) {
562
575
  let entry;
563
576
  const basename3 = this._isDirent ? dirent.name : dirent;
564
577
  try {
565
- const fullPath = presolve(pjoin(path7, basename3));
578
+ const fullPath = presolve(pjoin(path8, basename3));
566
579
  entry = { path: prelative(this._root, fullPath), fullPath, basename: basename3 };
567
580
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
568
581
  } catch (err) {
@@ -962,16 +975,16 @@ var delFromSet = (main2, prop, item) => {
962
975
  };
963
976
  var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
964
977
  var FsWatchInstances = /* @__PURE__ */ new Map();
965
- function createFsWatchInstance(path7, options, listener, errHandler, emitRaw) {
978
+ function createFsWatchInstance(path8, options, listener, errHandler, emitRaw) {
966
979
  const handleEvent = (rawEvent, evPath) => {
967
- listener(path7);
968
- emitRaw(rawEvent, evPath, { watchedPath: path7 });
969
- if (evPath && path7 !== evPath) {
970
- fsWatchBroadcast(sp.resolve(path7, evPath), KEY_LISTENERS, sp.join(path7, evPath));
980
+ listener(path8);
981
+ emitRaw(rawEvent, evPath, { watchedPath: path8 });
982
+ if (evPath && path8 !== evPath) {
983
+ fsWatchBroadcast(sp.resolve(path8, evPath), KEY_LISTENERS, sp.join(path8, evPath));
971
984
  }
972
985
  };
973
986
  try {
974
- return fs_watch(path7, {
987
+ return fs_watch(path8, {
975
988
  persistent: options.persistent
976
989
  }, handleEvent);
977
990
  } catch (error) {
@@ -987,12 +1000,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
987
1000
  listener(val1, val2, val3);
988
1001
  });
989
1002
  };
990
- var setFsWatchListener = (path7, fullPath, options, handlers) => {
1003
+ var setFsWatchListener = (path8, fullPath, options, handlers) => {
991
1004
  const { listener, errHandler, rawEmitter } = handlers;
992
1005
  let cont = FsWatchInstances.get(fullPath);
993
1006
  let watcher;
994
1007
  if (!options.persistent) {
995
- watcher = createFsWatchInstance(path7, options, listener, errHandler, rawEmitter);
1008
+ watcher = createFsWatchInstance(path8, options, listener, errHandler, rawEmitter);
996
1009
  if (!watcher)
997
1010
  return;
998
1011
  return watcher.close.bind(watcher);
@@ -1003,7 +1016,7 @@ var setFsWatchListener = (path7, fullPath, options, handlers) => {
1003
1016
  addAndConvert(cont, KEY_RAW, rawEmitter);
1004
1017
  } else {
1005
1018
  watcher = createFsWatchInstance(
1006
- path7,
1019
+ path8,
1007
1020
  options,
1008
1021
  fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
1009
1022
  errHandler,
@@ -1018,7 +1031,7 @@ var setFsWatchListener = (path7, fullPath, options, handlers) => {
1018
1031
  cont.watcherUnusable = true;
1019
1032
  if (isWindows && error.code === "EPERM") {
1020
1033
  try {
1021
- const fd = await open(path7, "r");
1034
+ const fd = await open(path8, "r");
1022
1035
  await fd.close();
1023
1036
  broadcastErr(error);
1024
1037
  } catch (err) {
@@ -1049,7 +1062,7 @@ var setFsWatchListener = (path7, fullPath, options, handlers) => {
1049
1062
  };
1050
1063
  };
1051
1064
  var FsWatchFileInstances = /* @__PURE__ */ new Map();
1052
- var setFsWatchFileListener = (path7, fullPath, options, handlers) => {
1065
+ var setFsWatchFileListener = (path8, fullPath, options, handlers) => {
1053
1066
  const { listener, rawEmitter } = handlers;
1054
1067
  let cont = FsWatchFileInstances.get(fullPath);
1055
1068
  const copts = cont && cont.options;
@@ -1071,7 +1084,7 @@ var setFsWatchFileListener = (path7, fullPath, options, handlers) => {
1071
1084
  });
1072
1085
  const currmtime = curr.mtimeMs;
1073
1086
  if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
1074
- foreach(cont.listeners, (listener2) => listener2(path7, curr));
1087
+ foreach(cont.listeners, (listener2) => listener2(path8, curr));
1075
1088
  }
1076
1089
  })
1077
1090
  };
@@ -1101,13 +1114,13 @@ var NodeFsHandler = class {
1101
1114
  * @param listener on fs change
1102
1115
  * @returns closer for the watcher instance
1103
1116
  */
1104
- _watchWithNodeFs(path7, listener) {
1117
+ _watchWithNodeFs(path8, listener) {
1105
1118
  const opts = this.fsw.options;
1106
- const directory = sp.dirname(path7);
1107
- const basename3 = sp.basename(path7);
1119
+ const directory = sp.dirname(path8);
1120
+ const basename3 = sp.basename(path8);
1108
1121
  const parent = this.fsw._getWatchedDir(directory);
1109
1122
  parent.add(basename3);
1110
- const absolutePath = sp.resolve(path7);
1123
+ const absolutePath = sp.resolve(path8);
1111
1124
  const options = {
1112
1125
  persistent: opts.persistent
1113
1126
  };
@@ -1117,12 +1130,12 @@ var NodeFsHandler = class {
1117
1130
  if (opts.usePolling) {
1118
1131
  const enableBin = opts.interval !== opts.binaryInterval;
1119
1132
  options.interval = enableBin && isBinaryPath(basename3) ? opts.binaryInterval : opts.interval;
1120
- closer = setFsWatchFileListener(path7, absolutePath, options, {
1133
+ closer = setFsWatchFileListener(path8, absolutePath, options, {
1121
1134
  listener,
1122
1135
  rawEmitter: this.fsw._emitRaw
1123
1136
  });
1124
1137
  } else {
1125
- closer = setFsWatchListener(path7, absolutePath, options, {
1138
+ closer = setFsWatchListener(path8, absolutePath, options, {
1126
1139
  listener,
1127
1140
  errHandler: this._boundHandleError,
1128
1141
  rawEmitter: this.fsw._emitRaw
@@ -1144,7 +1157,7 @@ var NodeFsHandler = class {
1144
1157
  let prevStats = stats;
1145
1158
  if (parent.has(basename3))
1146
1159
  return;
1147
- const listener = async (path7, newStats) => {
1160
+ const listener = async (path8, newStats) => {
1148
1161
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
1149
1162
  return;
1150
1163
  if (!newStats || newStats.mtimeMs === 0) {
@@ -1158,11 +1171,11 @@ var NodeFsHandler = class {
1158
1171
  this.fsw._emit(EV.CHANGE, file, newStats2);
1159
1172
  }
1160
1173
  if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
1161
- this.fsw._closeFile(path7);
1174
+ this.fsw._closeFile(path8);
1162
1175
  prevStats = newStats2;
1163
1176
  const closer2 = this._watchWithNodeFs(file, listener);
1164
1177
  if (closer2)
1165
- this.fsw._addPathCloser(path7, closer2);
1178
+ this.fsw._addPathCloser(path8, closer2);
1166
1179
  } else {
1167
1180
  prevStats = newStats2;
1168
1181
  }
@@ -1194,7 +1207,7 @@ var NodeFsHandler = class {
1194
1207
  * @param item basename of this item
1195
1208
  * @returns true if no more processing is needed for this entry.
1196
1209
  */
1197
- async _handleSymlink(entry, directory, path7, item) {
1210
+ async _handleSymlink(entry, directory, path8, item) {
1198
1211
  if (this.fsw.closed) {
1199
1212
  return;
1200
1213
  }
@@ -1204,7 +1217,7 @@ var NodeFsHandler = class {
1204
1217
  this.fsw._incrReadyCount();
1205
1218
  let linkPath;
1206
1219
  try {
1207
- linkPath = await fsrealpath(path7);
1220
+ linkPath = await fsrealpath(path8);
1208
1221
  } catch (e) {
1209
1222
  this.fsw._emitReady();
1210
1223
  return true;
@@ -1214,12 +1227,12 @@ var NodeFsHandler = class {
1214
1227
  if (dir.has(item)) {
1215
1228
  if (this.fsw._symlinkPaths.get(full) !== linkPath) {
1216
1229
  this.fsw._symlinkPaths.set(full, linkPath);
1217
- this.fsw._emit(EV.CHANGE, path7, entry.stats);
1230
+ this.fsw._emit(EV.CHANGE, path8, entry.stats);
1218
1231
  }
1219
1232
  } else {
1220
1233
  dir.add(item);
1221
1234
  this.fsw._symlinkPaths.set(full, linkPath);
1222
- this.fsw._emit(EV.ADD, path7, entry.stats);
1235
+ this.fsw._emit(EV.ADD, path8, entry.stats);
1223
1236
  }
1224
1237
  this.fsw._emitReady();
1225
1238
  return true;
@@ -1249,9 +1262,9 @@ var NodeFsHandler = class {
1249
1262
  return;
1250
1263
  }
1251
1264
  const item = entry.path;
1252
- let path7 = sp.join(directory, item);
1265
+ let path8 = sp.join(directory, item);
1253
1266
  current.add(item);
1254
- if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path7, item)) {
1267
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path8, item)) {
1255
1268
  return;
1256
1269
  }
1257
1270
  if (this.fsw.closed) {
@@ -1260,8 +1273,8 @@ var NodeFsHandler = class {
1260
1273
  }
1261
1274
  if (item === target || !target && !previous.has(item)) {
1262
1275
  this.fsw._incrReadyCount();
1263
- path7 = sp.join(dir, sp.relative(dir, path7));
1264
- this._addToNodeFs(path7, initialAdd, wh, depth + 1);
1276
+ path8 = sp.join(dir, sp.relative(dir, path8));
1277
+ this._addToNodeFs(path8, initialAdd, wh, depth + 1);
1265
1278
  }
1266
1279
  }).on(EV.ERROR, this._boundHandleError);
1267
1280
  return new Promise((resolve3, reject) => {
@@ -1330,13 +1343,13 @@ var NodeFsHandler = class {
1330
1343
  * @param depth Child path actually targeted for watch
1331
1344
  * @param target Child path actually targeted for watch
1332
1345
  */
1333
- async _addToNodeFs(path7, initialAdd, priorWh, depth, target) {
1346
+ async _addToNodeFs(path8, initialAdd, priorWh, depth, target) {
1334
1347
  const ready = this.fsw._emitReady;
1335
- if (this.fsw._isIgnored(path7) || this.fsw.closed) {
1348
+ if (this.fsw._isIgnored(path8) || this.fsw.closed) {
1336
1349
  ready();
1337
1350
  return false;
1338
1351
  }
1339
- const wh = this.fsw._getWatchHelpers(path7);
1352
+ const wh = this.fsw._getWatchHelpers(path8);
1340
1353
  if (priorWh) {
1341
1354
  wh.filterPath = (entry) => priorWh.filterPath(entry);
1342
1355
  wh.filterDir = (entry) => priorWh.filterDir(entry);
@@ -1352,8 +1365,8 @@ var NodeFsHandler = class {
1352
1365
  const follow = this.fsw.options.followSymlinks;
1353
1366
  let closer;
1354
1367
  if (stats.isDirectory()) {
1355
- const absPath = sp.resolve(path7);
1356
- const targetPath = follow ? await fsrealpath(path7) : path7;
1368
+ const absPath = sp.resolve(path8);
1369
+ const targetPath = follow ? await fsrealpath(path8) : path8;
1357
1370
  if (this.fsw.closed)
1358
1371
  return;
1359
1372
  closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
@@ -1363,29 +1376,29 @@ var NodeFsHandler = class {
1363
1376
  this.fsw._symlinkPaths.set(absPath, targetPath);
1364
1377
  }
1365
1378
  } else if (stats.isSymbolicLink()) {
1366
- const targetPath = follow ? await fsrealpath(path7) : path7;
1379
+ const targetPath = follow ? await fsrealpath(path8) : path8;
1367
1380
  if (this.fsw.closed)
1368
1381
  return;
1369
1382
  const parent = sp.dirname(wh.watchPath);
1370
1383
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
1371
1384
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
1372
- closer = await this._handleDir(parent, stats, initialAdd, depth, path7, wh, targetPath);
1385
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path8, wh, targetPath);
1373
1386
  if (this.fsw.closed)
1374
1387
  return;
1375
1388
  if (targetPath !== void 0) {
1376
- this.fsw._symlinkPaths.set(sp.resolve(path7), targetPath);
1389
+ this.fsw._symlinkPaths.set(sp.resolve(path8), targetPath);
1377
1390
  }
1378
1391
  } else {
1379
1392
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
1380
1393
  }
1381
1394
  ready();
1382
1395
  if (closer)
1383
- this.fsw._addPathCloser(path7, closer);
1396
+ this.fsw._addPathCloser(path8, closer);
1384
1397
  return false;
1385
1398
  } catch (error) {
1386
1399
  if (this.fsw._handleError(error)) {
1387
1400
  ready();
1388
- return path7;
1401
+ return path8;
1389
1402
  }
1390
1403
  }
1391
1404
  }
@@ -1428,24 +1441,24 @@ function createPattern(matcher) {
1428
1441
  }
1429
1442
  return () => false;
1430
1443
  }
1431
- function normalizePath(path7) {
1432
- if (typeof path7 !== "string")
1444
+ function normalizePath(path8) {
1445
+ if (typeof path8 !== "string")
1433
1446
  throw new Error("string expected");
1434
- path7 = sp2.normalize(path7);
1435
- path7 = path7.replace(/\\/g, "/");
1447
+ path8 = sp2.normalize(path8);
1448
+ path8 = path8.replace(/\\/g, "/");
1436
1449
  let prepend = false;
1437
- if (path7.startsWith("//"))
1450
+ if (path8.startsWith("//"))
1438
1451
  prepend = true;
1439
- path7 = path7.replace(DOUBLE_SLASH_RE, "/");
1452
+ path8 = path8.replace(DOUBLE_SLASH_RE, "/");
1440
1453
  if (prepend)
1441
- path7 = "/" + path7;
1442
- return path7;
1454
+ path8 = "/" + path8;
1455
+ return path8;
1443
1456
  }
1444
1457
  function matchPatterns(patterns, testString, stats) {
1445
- const path7 = normalizePath(testString);
1458
+ const path8 = normalizePath(testString);
1446
1459
  for (let index = 0; index < patterns.length; index++) {
1447
1460
  const pattern = patterns[index];
1448
- if (pattern(path7, stats)) {
1461
+ if (pattern(path8, stats)) {
1449
1462
  return true;
1450
1463
  }
1451
1464
  }
@@ -1483,19 +1496,19 @@ var toUnix = (string) => {
1483
1496
  }
1484
1497
  return str;
1485
1498
  };
1486
- var normalizePathToUnix = (path7) => toUnix(sp2.normalize(toUnix(path7)));
1487
- var normalizeIgnored = (cwd = "") => (path7) => {
1488
- if (typeof path7 === "string") {
1489
- return normalizePathToUnix(sp2.isAbsolute(path7) ? path7 : sp2.join(cwd, path7));
1499
+ var normalizePathToUnix = (path8) => toUnix(sp2.normalize(toUnix(path8)));
1500
+ var normalizeIgnored = (cwd = "") => (path8) => {
1501
+ if (typeof path8 === "string") {
1502
+ return normalizePathToUnix(sp2.isAbsolute(path8) ? path8 : sp2.join(cwd, path8));
1490
1503
  } else {
1491
- return path7;
1504
+ return path8;
1492
1505
  }
1493
1506
  };
1494
- var getAbsolutePath = (path7, cwd) => {
1495
- if (sp2.isAbsolute(path7)) {
1496
- return path7;
1507
+ var getAbsolutePath = (path8, cwd) => {
1508
+ if (sp2.isAbsolute(path8)) {
1509
+ return path8;
1497
1510
  }
1498
- return sp2.join(cwd, path7);
1511
+ return sp2.join(cwd, path8);
1499
1512
  };
1500
1513
  var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
1501
1514
  var DirEntry = class {
@@ -1560,10 +1573,10 @@ var WatchHelper = class {
1560
1573
  dirParts;
1561
1574
  followSymlinks;
1562
1575
  statMethod;
1563
- constructor(path7, follow, fsw) {
1576
+ constructor(path8, follow, fsw) {
1564
1577
  this.fsw = fsw;
1565
- const watchPath = path7;
1566
- this.path = path7 = path7.replace(REPLACER_RE, "");
1578
+ const watchPath = path8;
1579
+ this.path = path8 = path8.replace(REPLACER_RE, "");
1567
1580
  this.watchPath = watchPath;
1568
1581
  this.fullWatchPath = sp2.resolve(watchPath);
1569
1582
  this.dirParts = [];
@@ -1703,20 +1716,20 @@ var FSWatcher = class extends EventEmitter {
1703
1716
  this._closePromise = void 0;
1704
1717
  let paths = unifyPaths(paths_);
1705
1718
  if (cwd) {
1706
- paths = paths.map((path7) => {
1707
- const absPath = getAbsolutePath(path7, cwd);
1719
+ paths = paths.map((path8) => {
1720
+ const absPath = getAbsolutePath(path8, cwd);
1708
1721
  return absPath;
1709
1722
  });
1710
1723
  }
1711
- paths.forEach((path7) => {
1712
- this._removeIgnoredPath(path7);
1724
+ paths.forEach((path8) => {
1725
+ this._removeIgnoredPath(path8);
1713
1726
  });
1714
1727
  this._userIgnored = void 0;
1715
1728
  if (!this._readyCount)
1716
1729
  this._readyCount = 0;
1717
1730
  this._readyCount += paths.length;
1718
- Promise.all(paths.map(async (path7) => {
1719
- const res = await this._nodeFsHandler._addToNodeFs(path7, !_internal, void 0, 0, _origAdd);
1731
+ Promise.all(paths.map(async (path8) => {
1732
+ const res = await this._nodeFsHandler._addToNodeFs(path8, !_internal, void 0, 0, _origAdd);
1720
1733
  if (res)
1721
1734
  this._emitReady();
1722
1735
  return res;
@@ -1738,17 +1751,17 @@ var FSWatcher = class extends EventEmitter {
1738
1751
  return this;
1739
1752
  const paths = unifyPaths(paths_);
1740
1753
  const { cwd } = this.options;
1741
- paths.forEach((path7) => {
1742
- if (!sp2.isAbsolute(path7) && !this._closers.has(path7)) {
1754
+ paths.forEach((path8) => {
1755
+ if (!sp2.isAbsolute(path8) && !this._closers.has(path8)) {
1743
1756
  if (cwd)
1744
- path7 = sp2.join(cwd, path7);
1745
- path7 = sp2.resolve(path7);
1757
+ path8 = sp2.join(cwd, path8);
1758
+ path8 = sp2.resolve(path8);
1746
1759
  }
1747
- this._closePath(path7);
1748
- this._addIgnoredPath(path7);
1749
- if (this._watched.has(path7)) {
1760
+ this._closePath(path8);
1761
+ this._addIgnoredPath(path8);
1762
+ if (this._watched.has(path8)) {
1750
1763
  this._addIgnoredPath({
1751
- path: path7,
1764
+ path: path8,
1752
1765
  recursive: true
1753
1766
  });
1754
1767
  }
@@ -1812,38 +1825,38 @@ var FSWatcher = class extends EventEmitter {
1812
1825
  * @param stats arguments to be passed with event
1813
1826
  * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
1814
1827
  */
1815
- async _emit(event, path7, stats) {
1828
+ async _emit(event, path8, stats) {
1816
1829
  if (this.closed)
1817
1830
  return;
1818
1831
  const opts = this.options;
1819
1832
  if (isWindows)
1820
- path7 = sp2.normalize(path7);
1833
+ path8 = sp2.normalize(path8);
1821
1834
  if (opts.cwd)
1822
- path7 = sp2.relative(opts.cwd, path7);
1823
- const args = [path7];
1835
+ path8 = sp2.relative(opts.cwd, path8);
1836
+ const args = [path8];
1824
1837
  if (stats != null)
1825
1838
  args.push(stats);
1826
1839
  const awf = opts.awaitWriteFinish;
1827
1840
  let pw;
1828
- if (awf && (pw = this._pendingWrites.get(path7))) {
1841
+ if (awf && (pw = this._pendingWrites.get(path8))) {
1829
1842
  pw.lastChange = /* @__PURE__ */ new Date();
1830
1843
  return this;
1831
1844
  }
1832
1845
  if (opts.atomic) {
1833
1846
  if (event === EVENTS.UNLINK) {
1834
- this._pendingUnlinks.set(path7, [event, ...args]);
1847
+ this._pendingUnlinks.set(path8, [event, ...args]);
1835
1848
  setTimeout(() => {
1836
- this._pendingUnlinks.forEach((entry, path8) => {
1849
+ this._pendingUnlinks.forEach((entry, path9) => {
1837
1850
  this.emit(...entry);
1838
1851
  this.emit(EVENTS.ALL, ...entry);
1839
- this._pendingUnlinks.delete(path8);
1852
+ this._pendingUnlinks.delete(path9);
1840
1853
  });
1841
1854
  }, typeof opts.atomic === "number" ? opts.atomic : 100);
1842
1855
  return this;
1843
1856
  }
1844
- if (event === EVENTS.ADD && this._pendingUnlinks.has(path7)) {
1857
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path8)) {
1845
1858
  event = EVENTS.CHANGE;
1846
- this._pendingUnlinks.delete(path7);
1859
+ this._pendingUnlinks.delete(path8);
1847
1860
  }
1848
1861
  }
1849
1862
  if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
@@ -1861,16 +1874,16 @@ var FSWatcher = class extends EventEmitter {
1861
1874
  this.emitWithAll(event, args);
1862
1875
  }
1863
1876
  };
1864
- this._awaitWriteFinish(path7, awf.stabilityThreshold, event, awfEmit);
1877
+ this._awaitWriteFinish(path8, awf.stabilityThreshold, event, awfEmit);
1865
1878
  return this;
1866
1879
  }
1867
1880
  if (event === EVENTS.CHANGE) {
1868
- const isThrottled = !this._throttle(EVENTS.CHANGE, path7, 50);
1881
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path8, 50);
1869
1882
  if (isThrottled)
1870
1883
  return this;
1871
1884
  }
1872
1885
  if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
1873
- const fullPath = opts.cwd ? sp2.join(opts.cwd, path7) : path7;
1886
+ const fullPath = opts.cwd ? sp2.join(opts.cwd, path8) : path8;
1874
1887
  let stats2;
1875
1888
  try {
1876
1889
  stats2 = await stat3(fullPath);
@@ -1901,23 +1914,23 @@ var FSWatcher = class extends EventEmitter {
1901
1914
  * @param timeout duration of time to suppress duplicate actions
1902
1915
  * @returns tracking object or false if action should be suppressed
1903
1916
  */
1904
- _throttle(actionType, path7, timeout) {
1917
+ _throttle(actionType, path8, timeout) {
1905
1918
  if (!this._throttled.has(actionType)) {
1906
1919
  this._throttled.set(actionType, /* @__PURE__ */ new Map());
1907
1920
  }
1908
1921
  const action = this._throttled.get(actionType);
1909
1922
  if (!action)
1910
1923
  throw new Error("invalid throttle");
1911
- const actionPath = action.get(path7);
1924
+ const actionPath = action.get(path8);
1912
1925
  if (actionPath) {
1913
1926
  actionPath.count++;
1914
1927
  return false;
1915
1928
  }
1916
1929
  let timeoutObject;
1917
1930
  const clear = () => {
1918
- const item = action.get(path7);
1931
+ const item = action.get(path8);
1919
1932
  const count = item ? item.count : 0;
1920
- action.delete(path7);
1933
+ action.delete(path8);
1921
1934
  clearTimeout(timeoutObject);
1922
1935
  if (item)
1923
1936
  clearTimeout(item.timeoutObject);
@@ -1925,7 +1938,7 @@ var FSWatcher = class extends EventEmitter {
1925
1938
  };
1926
1939
  timeoutObject = setTimeout(clear, timeout);
1927
1940
  const thr = { timeoutObject, clear, count: 0 };
1928
- action.set(path7, thr);
1941
+ action.set(path8, thr);
1929
1942
  return thr;
1930
1943
  }
1931
1944
  _incrReadyCount() {
@@ -1939,44 +1952,44 @@ var FSWatcher = class extends EventEmitter {
1939
1952
  * @param event
1940
1953
  * @param awfEmit Callback to be called when ready for event to be emitted.
1941
1954
  */
1942
- _awaitWriteFinish(path7, threshold, event, awfEmit) {
1955
+ _awaitWriteFinish(path8, threshold, event, awfEmit) {
1943
1956
  const awf = this.options.awaitWriteFinish;
1944
1957
  if (typeof awf !== "object")
1945
1958
  return;
1946
1959
  const pollInterval = awf.pollInterval;
1947
1960
  let timeoutHandler;
1948
- let fullPath = path7;
1949
- if (this.options.cwd && !sp2.isAbsolute(path7)) {
1950
- fullPath = sp2.join(this.options.cwd, path7);
1961
+ let fullPath = path8;
1962
+ if (this.options.cwd && !sp2.isAbsolute(path8)) {
1963
+ fullPath = sp2.join(this.options.cwd, path8);
1951
1964
  }
1952
1965
  const now = /* @__PURE__ */ new Date();
1953
1966
  const writes = this._pendingWrites;
1954
1967
  function awaitWriteFinishFn(prevStat) {
1955
1968
  statcb(fullPath, (err, curStat) => {
1956
- if (err || !writes.has(path7)) {
1969
+ if (err || !writes.has(path8)) {
1957
1970
  if (err && err.code !== "ENOENT")
1958
1971
  awfEmit(err);
1959
1972
  return;
1960
1973
  }
1961
1974
  const now2 = Number(/* @__PURE__ */ new Date());
1962
1975
  if (prevStat && curStat.size !== prevStat.size) {
1963
- writes.get(path7).lastChange = now2;
1976
+ writes.get(path8).lastChange = now2;
1964
1977
  }
1965
- const pw = writes.get(path7);
1978
+ const pw = writes.get(path8);
1966
1979
  const df = now2 - pw.lastChange;
1967
1980
  if (df >= threshold) {
1968
- writes.delete(path7);
1981
+ writes.delete(path8);
1969
1982
  awfEmit(void 0, curStat);
1970
1983
  } else {
1971
1984
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
1972
1985
  }
1973
1986
  });
1974
1987
  }
1975
- if (!writes.has(path7)) {
1976
- writes.set(path7, {
1988
+ if (!writes.has(path8)) {
1989
+ writes.set(path8, {
1977
1990
  lastChange: now,
1978
1991
  cancelWait: () => {
1979
- writes.delete(path7);
1992
+ writes.delete(path8);
1980
1993
  clearTimeout(timeoutHandler);
1981
1994
  return event;
1982
1995
  }
@@ -1987,8 +2000,8 @@ var FSWatcher = class extends EventEmitter {
1987
2000
  /**
1988
2001
  * Determines whether user has asked to ignore this path.
1989
2002
  */
1990
- _isIgnored(path7, stats) {
1991
- if (this.options.atomic && DOT_RE.test(path7))
2003
+ _isIgnored(path8, stats) {
2004
+ if (this.options.atomic && DOT_RE.test(path8))
1992
2005
  return true;
1993
2006
  if (!this._userIgnored) {
1994
2007
  const { cwd } = this.options;
@@ -1998,17 +2011,17 @@ var FSWatcher = class extends EventEmitter {
1998
2011
  const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
1999
2012
  this._userIgnored = anymatch(list, void 0);
2000
2013
  }
2001
- return this._userIgnored(path7, stats);
2014
+ return this._userIgnored(path8, stats);
2002
2015
  }
2003
- _isntIgnored(path7, stat4) {
2004
- return !this._isIgnored(path7, stat4);
2016
+ _isntIgnored(path8, stat4) {
2017
+ return !this._isIgnored(path8, stat4);
2005
2018
  }
2006
2019
  /**
2007
2020
  * Provides a set of common helpers and properties relating to symlink handling.
2008
2021
  * @param path file or directory pattern being watched
2009
2022
  */
2010
- _getWatchHelpers(path7) {
2011
- return new WatchHelper(path7, this.options.followSymlinks, this);
2023
+ _getWatchHelpers(path8) {
2024
+ return new WatchHelper(path8, this.options.followSymlinks, this);
2012
2025
  }
2013
2026
  // Directory helpers
2014
2027
  // -----------------
@@ -2040,63 +2053,63 @@ var FSWatcher = class extends EventEmitter {
2040
2053
  * @param item base path of item/directory
2041
2054
  */
2042
2055
  _remove(directory, item, isDirectory) {
2043
- const path7 = sp2.join(directory, item);
2044
- const fullPath = sp2.resolve(path7);
2045
- isDirectory = isDirectory != null ? isDirectory : this._watched.has(path7) || this._watched.has(fullPath);
2046
- if (!this._throttle("remove", path7, 100))
2056
+ const path8 = sp2.join(directory, item);
2057
+ const fullPath = sp2.resolve(path8);
2058
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path8) || this._watched.has(fullPath);
2059
+ if (!this._throttle("remove", path8, 100))
2047
2060
  return;
2048
2061
  if (!isDirectory && this._watched.size === 1) {
2049
2062
  this.add(directory, item, true);
2050
2063
  }
2051
- const wp = this._getWatchedDir(path7);
2064
+ const wp = this._getWatchedDir(path8);
2052
2065
  const nestedDirectoryChildren = wp.getChildren();
2053
- nestedDirectoryChildren.forEach((nested) => this._remove(path7, nested));
2066
+ nestedDirectoryChildren.forEach((nested) => this._remove(path8, nested));
2054
2067
  const parent = this._getWatchedDir(directory);
2055
2068
  const wasTracked = parent.has(item);
2056
2069
  parent.remove(item);
2057
2070
  if (this._symlinkPaths.has(fullPath)) {
2058
2071
  this._symlinkPaths.delete(fullPath);
2059
2072
  }
2060
- let relPath = path7;
2073
+ let relPath = path8;
2061
2074
  if (this.options.cwd)
2062
- relPath = sp2.relative(this.options.cwd, path7);
2075
+ relPath = sp2.relative(this.options.cwd, path8);
2063
2076
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
2064
2077
  const event = this._pendingWrites.get(relPath).cancelWait();
2065
2078
  if (event === EVENTS.ADD)
2066
2079
  return;
2067
2080
  }
2068
- this._watched.delete(path7);
2081
+ this._watched.delete(path8);
2069
2082
  this._watched.delete(fullPath);
2070
2083
  const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
2071
- if (wasTracked && !this._isIgnored(path7))
2072
- this._emit(eventName, path7);
2073
- this._closePath(path7);
2084
+ if (wasTracked && !this._isIgnored(path8))
2085
+ this._emit(eventName, path8);
2086
+ this._closePath(path8);
2074
2087
  }
2075
2088
  /**
2076
2089
  * Closes all watchers for a path
2077
2090
  */
2078
- _closePath(path7) {
2079
- this._closeFile(path7);
2080
- const dir = sp2.dirname(path7);
2081
- this._getWatchedDir(dir).remove(sp2.basename(path7));
2091
+ _closePath(path8) {
2092
+ this._closeFile(path8);
2093
+ const dir = sp2.dirname(path8);
2094
+ this._getWatchedDir(dir).remove(sp2.basename(path8));
2082
2095
  }
2083
2096
  /**
2084
2097
  * Closes only file-specific watchers
2085
2098
  */
2086
- _closeFile(path7) {
2087
- const closers = this._closers.get(path7);
2099
+ _closeFile(path8) {
2100
+ const closers = this._closers.get(path8);
2088
2101
  if (!closers)
2089
2102
  return;
2090
2103
  closers.forEach((closer) => closer());
2091
- this._closers.delete(path7);
2104
+ this._closers.delete(path8);
2092
2105
  }
2093
- _addPathCloser(path7, closer) {
2106
+ _addPathCloser(path8, closer) {
2094
2107
  if (!closer)
2095
2108
  return;
2096
- let list = this._closers.get(path7);
2109
+ let list = this._closers.get(path8);
2097
2110
  if (!list) {
2098
2111
  list = [];
2099
- this._closers.set(path7, list);
2112
+ this._closers.set(path8, list);
2100
2113
  }
2101
2114
  list.push(closer);
2102
2115
  }
@@ -2192,10 +2205,358 @@ var PlanWatcher = class {
2192
2205
  }
2193
2206
  };
2194
2207
 
2195
- // src/artifacts/candidates.ts
2196
- import { execFileSync } from "child_process";
2208
+ // src/daemon/digest.ts
2209
+ var import_yaml = __toESM(require_dist(), 1);
2197
2210
  import fs3 from "fs";
2198
2211
  import path4 from "path";
2212
+ import crypto from "crypto";
2213
+ var PREVIOUS_EXTRACT_OVERHEAD_TOKENS = 50;
2214
+ var CONTEXT_SAFETY_MARGIN = 0.7;
2215
+ var EXTRACT_TYPE = "extract";
2216
+ var DigestEngine = class {
2217
+ vaultDir;
2218
+ index;
2219
+ llm;
2220
+ config;
2221
+ log;
2222
+ lastCycleTimestampCache = void 0;
2223
+ cycleInProgress = false;
2224
+ modelReady = false;
2225
+ constructor(engineConfig) {
2226
+ this.vaultDir = engineConfig.vaultDir;
2227
+ this.index = engineConfig.index;
2228
+ this.llm = engineConfig.llmProvider;
2229
+ this.config = engineConfig.config;
2230
+ this.log = engineConfig.log ?? (() => {
2231
+ });
2232
+ }
2233
+ /**
2234
+ * Query index for recent vault notes to feed into the digest.
2235
+ * Filters out extract notes (our own output) and caps at max_notes_per_cycle.
2236
+ */
2237
+ discoverSubstrate(lastCycleTimestamp) {
2238
+ const maxNotes = this.config.digest.substrate.max_notes_per_cycle;
2239
+ const notes = lastCycleTimestamp ? this.index.query({ updatedSince: lastCycleTimestamp, limit: maxNotes }) : this.index.query({ limit: maxNotes });
2240
+ const filtered = notes.filter((n) => n.type !== EXTRACT_TYPE);
2241
+ filtered.sort((a, b) => {
2242
+ const weightA = DIGEST_SUBSTRATE_TYPE_WEIGHTS[a.type] ?? 0;
2243
+ const weightB = DIGEST_SUBSTRATE_TYPE_WEIGHTS[b.type] ?? 0;
2244
+ if (weightB !== weightA) return weightB - weightA;
2245
+ return b.created.localeCompare(a.created);
2246
+ });
2247
+ return filtered.slice(0, maxNotes);
2248
+ }
2249
+ /**
2250
+ * Filter configured tiers by the context window available.
2251
+ * Only tiers whose minimum context requirement is met are eligible.
2252
+ */
2253
+ getEligibleTiers() {
2254
+ const contextWindow = this.config.digest.intelligence.context_window;
2255
+ return this.config.digest.tiers.filter((tier) => {
2256
+ const minContext = DIGEST_TIER_MIN_CONTEXT[tier];
2257
+ return minContext !== void 0 && minContext <= contextWindow;
2258
+ });
2259
+ }
2260
+ /**
2261
+ * Format notes compactly for inclusion in the digest prompt.
2262
+ * Stops adding notes once the token budget is exceeded.
2263
+ */
2264
+ formatSubstrate(notes, tokenBudget) {
2265
+ const charBudget = tokenBudget * CHARS_PER_TOKEN;
2266
+ const parts = [];
2267
+ let usedChars = 0;
2268
+ for (const note of notes) {
2269
+ const entry = `### [${note.type}] ${note.id} \u2014 "${note.title}"
2270
+ ${note.content}`;
2271
+ if (usedChars + entry.length > charBudget && parts.length > 0) break;
2272
+ parts.push(entry);
2273
+ usedChars += entry.length;
2274
+ }
2275
+ return parts.join("\n\n");
2276
+ }
2277
+ /**
2278
+ * Read a previously generated extract for a given tier.
2279
+ * Returns the body (stripped of YAML frontmatter), or null if not found.
2280
+ */
2281
+ readPreviousExtract(tier) {
2282
+ const extractPath = path4.join(this.vaultDir, "digest", `extract-${tier}.md`);
2283
+ let content;
2284
+ try {
2285
+ content = fs3.readFileSync(extractPath, "utf-8");
2286
+ } catch {
2287
+ return null;
2288
+ }
2289
+ return stripFrontmatter(content).body;
2290
+ }
2291
+ /**
2292
+ * Write a digest extract to the vault with YAML frontmatter.
2293
+ * Uses atomic write pattern (temp file + rename).
2294
+ */
2295
+ writeExtract(tier, body, cycleId, model, substrateCount) {
2296
+ const digestDir = path4.join(this.vaultDir, "digest");
2297
+ fs3.mkdirSync(digestDir, { recursive: true });
2298
+ const frontmatter = {
2299
+ type: EXTRACT_TYPE,
2300
+ tier,
2301
+ generated: (/* @__PURE__ */ new Date()).toISOString(),
2302
+ cycle_id: cycleId,
2303
+ substrate_count: substrateCount,
2304
+ model
2305
+ };
2306
+ const fmYaml = import_yaml.default.stringify(frontmatter, {
2307
+ defaultStringType: "QUOTE_DOUBLE",
2308
+ defaultKeyType: "PLAIN"
2309
+ }).trim();
2310
+ const file = `---
2311
+ ${fmYaml}
2312
+ ---
2313
+
2314
+ ${body}
2315
+ `;
2316
+ const fullPath = path4.join(digestDir, `extract-${tier}.md`);
2317
+ const tmpPath = `${fullPath}.tmp`;
2318
+ fs3.writeFileSync(tmpPath, file, "utf-8");
2319
+ fs3.renameSync(tmpPath, fullPath);
2320
+ }
2321
+ /**
2322
+ * Append a digest cycle result as a JSON line to trace.jsonl.
2323
+ */
2324
+ appendTrace(record) {
2325
+ const digestDir = path4.join(this.vaultDir, "digest");
2326
+ fs3.mkdirSync(digestDir, { recursive: true });
2327
+ const tracePath = path4.join(digestDir, "trace.jsonl");
2328
+ fs3.appendFileSync(tracePath, JSON.stringify(record) + "\n", "utf-8");
2329
+ this.lastCycleTimestampCache = record.timestamp;
2330
+ }
2331
+ /**
2332
+ * Read the last cycle timestamp from trace.jsonl.
2333
+ * Cached in memory after first read — subsequent calls are O(1).
2334
+ */
2335
+ getLastCycleTimestamp() {
2336
+ if (this.lastCycleTimestampCache !== void 0) return this.lastCycleTimestampCache;
2337
+ const tracePath = path4.join(this.vaultDir, "digest", "trace.jsonl");
2338
+ let content;
2339
+ try {
2340
+ content = fs3.readFileSync(tracePath, "utf-8").trim();
2341
+ } catch {
2342
+ this.lastCycleTimestampCache = null;
2343
+ return null;
2344
+ }
2345
+ if (!content) {
2346
+ this.lastCycleTimestampCache = null;
2347
+ return null;
2348
+ }
2349
+ const lines = content.split("\n");
2350
+ const lastLine = lines[lines.length - 1];
2351
+ try {
2352
+ const record = JSON.parse(lastLine);
2353
+ this.lastCycleTimestampCache = record.timestamp;
2354
+ return record.timestamp;
2355
+ } catch {
2356
+ this.lastCycleTimestampCache = null;
2357
+ return null;
2358
+ }
2359
+ }
2360
+ /**
2361
+ * Run a full digest cycle: discover substrate, generate extracts for each tier.
2362
+ * Returns the cycle result, or null if no substrate was found.
2363
+ */
2364
+ async runCycle() {
2365
+ if (this.cycleInProgress) {
2366
+ this.log("debug", "Cycle already in progress \u2014 skipping");
2367
+ return null;
2368
+ }
2369
+ this.cycleInProgress = true;
2370
+ try {
2371
+ return await this.runCycleInternal();
2372
+ } finally {
2373
+ this.cycleInProgress = false;
2374
+ }
2375
+ }
2376
+ async runCycleInternal() {
2377
+ if (!this.modelReady && this.llm.ensureLoaded) {
2378
+ const { context_window: contextWindow, gpu_kv_cache: gpuKvCache } = this.config.digest.intelligence;
2379
+ this.log("info", "Loading digest model", { contextWindow, gpuKvCache });
2380
+ await this.llm.ensureLoaded(contextWindow, gpuKvCache);
2381
+ this.modelReady = true;
2382
+ }
2383
+ const startTime = Date.now();
2384
+ const lastTimestamp = this.getLastCycleTimestamp();
2385
+ const substrate = this.discoverSubstrate(lastTimestamp);
2386
+ this.log("debug", "Discovering substrate", { lastTimestamp: lastTimestamp ?? "cold start", substrateCount: substrate.length });
2387
+ if (substrate.length === 0) {
2388
+ this.log("debug", "No substrate found \u2014 skipping cycle");
2389
+ return null;
2390
+ }
2391
+ this.log("info", `Starting digest cycle`, { substrateCount: substrate.length });
2392
+ const cycleId = crypto.randomUUID();
2393
+ const eligibleTiers = this.getEligibleTiers();
2394
+ this.log("debug", `Eligible tiers: [${eligibleTiers.join(", ")}]`);
2395
+ const tiersGenerated = [];
2396
+ let totalTokensUsed = 0;
2397
+ let model = "";
2398
+ const typeToKey = {
2399
+ session: "sessions",
2400
+ spore: "spores",
2401
+ plan: "plans",
2402
+ artifact: "artifacts",
2403
+ "team-member": "team"
2404
+ };
2405
+ const substrateIndex = {
2406
+ sessions: [],
2407
+ spores: [],
2408
+ plans: [],
2409
+ artifacts: [],
2410
+ team: []
2411
+ };
2412
+ for (const note of substrate) {
2413
+ const key = typeToKey[note.type];
2414
+ if (key) {
2415
+ substrateIndex[key].push(note.id);
2416
+ }
2417
+ }
2418
+ const systemPrompt = loadPrompt("digest-system");
2419
+ for (const tier of eligibleTiers) {
2420
+ const tierPrompt = loadPrompt(`digest-${tier}`);
2421
+ const previousExtract = this.readPreviousExtract(tier);
2422
+ const contextWindow = this.config.digest.intelligence.context_window;
2423
+ const systemPromptTokens = estimateTokens(systemPrompt);
2424
+ const tierPromptTokens = estimateTokens(tierPrompt);
2425
+ const previousExtractTokens = previousExtract ? estimateTokens(previousExtract) + PREVIOUS_EXTRACT_OVERHEAD_TOKENS : 0;
2426
+ const availableTokens = Math.floor(contextWindow * CONTEXT_SAFETY_MARGIN);
2427
+ const substrateBudget = availableTokens - tier - systemPromptTokens - tierPromptTokens - previousExtractTokens;
2428
+ if (substrateBudget <= 0) continue;
2429
+ const formattedSubstrate = this.formatSubstrate(substrate, substrateBudget);
2430
+ const promptParts = [tierPrompt];
2431
+ if (previousExtract) {
2432
+ promptParts.push("", "## Previous Synthesis", "", previousExtract);
2433
+ }
2434
+ promptParts.push("", "## New Substrate", "", formattedSubstrate);
2435
+ promptParts.push(
2436
+ "",
2437
+ "---",
2438
+ "Produce your updated synthesis now. Stay within the token budget specified above."
2439
+ );
2440
+ const userPrompt = promptParts.join("\n");
2441
+ const promptTokens = estimateTokens(systemPrompt + userPrompt);
2442
+ this.log("debug", `Tier ${tier}: sending LLM request`, { promptTokens, maxTokens: tier, substrateBudget });
2443
+ const tierStart = Date.now();
2444
+ const digestConfig = this.config.digest.intelligence;
2445
+ const opts = {
2446
+ maxTokens: tier,
2447
+ timeoutMs: DIGEST_LLM_REQUEST_TIMEOUT_MS,
2448
+ contextLength: contextWindow,
2449
+ reasoning: "off",
2450
+ systemPrompt,
2451
+ keepAlive: digestConfig.keep_alive ?? void 0
2452
+ };
2453
+ const response = await this.llm.summarize(userPrompt, opts);
2454
+ const tierDuration = Date.now() - tierStart;
2455
+ const extractText = stripReasoningTokens(response.text);
2456
+ model = response.model;
2457
+ const responseTokens = estimateTokens(extractText);
2458
+ totalTokensUsed += promptTokens + responseTokens;
2459
+ this.log("info", `Tier ${tier}: completed`, { durationMs: tierDuration, responseTokens, model: response.model });
2460
+ this.writeExtract(tier, extractText, cycleId, response.model, substrate.length);
2461
+ tiersGenerated.push(tier);
2462
+ }
2463
+ const result = {
2464
+ cycleId,
2465
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2466
+ substrate: substrateIndex,
2467
+ tiersGenerated,
2468
+ model,
2469
+ durationMs: Date.now() - startTime,
2470
+ tokensUsed: totalTokensUsed
2471
+ };
2472
+ this.appendTrace(result);
2473
+ return result;
2474
+ }
2475
+ };
2476
+ var MS_PER_SECOND2 = 1e3;
2477
+ var Metabolism = class {
2478
+ state = "active";
2479
+ currentIntervalMs;
2480
+ cooldownStep = 0;
2481
+ lastSubstrateTime;
2482
+ timer = null;
2483
+ activeIntervalMs;
2484
+ cooldownIntervalsMs;
2485
+ dormancyThresholdMs;
2486
+ constructor(config) {
2487
+ this.activeIntervalMs = config.active_interval * MS_PER_SECOND2;
2488
+ this.cooldownIntervalsMs = config.cooldown_intervals.map((s) => s * MS_PER_SECOND2);
2489
+ this.dormancyThresholdMs = config.dormancy_threshold * MS_PER_SECOND2;
2490
+ this.currentIntervalMs = this.activeIntervalMs;
2491
+ this.lastSubstrateTime = Date.now();
2492
+ }
2493
+ /** Reset to active state when new substrate is found. */
2494
+ onSubstrateFound() {
2495
+ this.state = "active";
2496
+ this.cooldownStep = 0;
2497
+ this.currentIntervalMs = this.activeIntervalMs;
2498
+ this.lastSubstrateTime = Date.now();
2499
+ }
2500
+ /** Advance cooldown when a cycle finds no new substrate. */
2501
+ onEmptyCycle() {
2502
+ if (this.state === "dormant") return;
2503
+ this.state = "cooling";
2504
+ if (this.cooldownStep < this.cooldownIntervalsMs.length) {
2505
+ this.currentIntervalMs = this.cooldownIntervalsMs[this.cooldownStep];
2506
+ this.cooldownStep++;
2507
+ }
2508
+ this.checkDormancy();
2509
+ }
2510
+ /** Enter dormant state if enough time has elapsed since last substrate. */
2511
+ checkDormancy() {
2512
+ const elapsed = Date.now() - this.lastSubstrateTime;
2513
+ if (elapsed >= this.dormancyThresholdMs) {
2514
+ this.state = "dormant";
2515
+ }
2516
+ }
2517
+ /** Return to active from any state, resetting timers and rescheduling immediately. */
2518
+ activate() {
2519
+ this.onSubstrateFound();
2520
+ if (this.callback) {
2521
+ this.reschedule();
2522
+ }
2523
+ }
2524
+ /** Set lastSubstrateTime explicitly (for testing). */
2525
+ markLastSubstrate(time) {
2526
+ this.lastSubstrateTime = time;
2527
+ }
2528
+ /** Begin scheduling digest cycles with adaptive intervals. */
2529
+ start(callback) {
2530
+ this.callback = callback;
2531
+ this.reschedule();
2532
+ }
2533
+ /** Stop the timer. */
2534
+ stop() {
2535
+ if (this.timer) {
2536
+ clearTimeout(this.timer);
2537
+ this.timer = null;
2538
+ }
2539
+ }
2540
+ callback = null;
2541
+ reschedule() {
2542
+ this.stop();
2543
+ if (!this.callback) return;
2544
+ const cb = this.callback;
2545
+ const schedule = () => {
2546
+ this.timer = setTimeout(async () => {
2547
+ await cb();
2548
+ schedule();
2549
+ }, this.currentIntervalMs);
2550
+ this.timer.unref();
2551
+ };
2552
+ schedule();
2553
+ }
2554
+ };
2555
+
2556
+ // src/artifacts/candidates.ts
2557
+ import { execFileSync } from "child_process";
2558
+ import fs4 from "fs";
2559
+ import path5 from "path";
2199
2560
  var EXCLUDED_FILENAMES = /* @__PURE__ */ new Set([
2200
2561
  "claude.md",
2201
2562
  "agents.md",
@@ -2216,7 +2577,7 @@ var EXCLUDED_PREFIXES = [
2216
2577
  ".github/"
2217
2578
  ];
2218
2579
  function isExcludedPath(relativePath) {
2219
- const basename3 = path4.basename(relativePath).toLowerCase();
2580
+ const basename3 = path5.basename(relativePath).toLowerCase();
2220
2581
  if (EXCLUDED_FILENAMES.has(basename3)) return true;
2221
2582
  const normalized = relativePath.replace(/\\/g, "/");
2222
2583
  return EXCLUDED_PREFIXES.some((prefix) => normalized.startsWith(prefix));
@@ -2224,7 +2585,7 @@ function isExcludedPath(relativePath) {
2224
2585
  function collectArtifactCandidates(filePaths, config, projectRoot) {
2225
2586
  if (filePaths.size === 0) return [];
2226
2587
  const extFiltered = [...filePaths].filter(
2227
- (absPath) => config.artifact_extensions.includes(path4.extname(absPath))
2588
+ (absPath) => config.artifact_extensions.includes(path5.extname(absPath))
2228
2589
  );
2229
2590
  if (extFiltered.length === 0) return [];
2230
2591
  const ignoredSet = getGitIgnored(extFiltered, projectRoot);
@@ -2232,8 +2593,8 @@ function collectArtifactCandidates(filePaths, config, projectRoot) {
2232
2593
  for (const absPath of extFiltered) {
2233
2594
  if (ignoredSet.has(absPath)) continue;
2234
2595
  try {
2235
- const content = fs3.readFileSync(absPath, "utf-8");
2236
- const relativePath = path4.relative(projectRoot, absPath);
2596
+ const content = fs4.readFileSync(absPath, "utf-8");
2597
+ const relativePath = path5.relative(projectRoot, absPath);
2237
2598
  if (isExcludedPath(relativePath)) continue;
2238
2599
  candidates.push({ path: relativePath, content });
2239
2600
  } catch {
@@ -2255,23 +2616,23 @@ function getGitIgnored(filePaths, cwd) {
2255
2616
  }
2256
2617
 
2257
2618
  // src/artifacts/slugify.ts
2258
- import crypto from "crypto";
2259
- import path5 from "path";
2619
+ import crypto2 from "crypto";
2620
+ import path6 from "path";
2260
2621
  function slugifyPath(relativePath) {
2261
- const ext = path5.extname(relativePath);
2622
+ const ext = path6.extname(relativePath);
2262
2623
  const withoutExt = ext ? relativePath.slice(0, -ext.length) : relativePath;
2263
2624
  let slug = withoutExt.replace(/[/\\]/g, "-").toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
2264
2625
  if (slug.length > MAX_SLUG_LENGTH) {
2265
- const hash = crypto.createHash("sha256").update(relativePath).digest("hex").slice(0, 6);
2626
+ const hash = crypto2.createHash("sha256").update(relativePath).digest("hex").slice(0, 6);
2266
2627
  slug = slug.slice(0, MAX_SLUG_LENGTH) + "-" + hash;
2267
2628
  }
2268
2629
  return slug;
2269
2630
  }
2270
2631
 
2271
2632
  // src/daemon/main.ts
2272
- var import_yaml = __toESM(require_dist(), 1);
2273
- import fs4 from "fs";
2274
- import path6 from "path";
2633
+ var import_yaml2 = __toESM(require_dist(), 1);
2634
+ import fs5 from "fs";
2635
+ import path7 from "path";
2275
2636
  function indexAndEmbed(relativePath, noteId, embeddingText, metadata, deps) {
2276
2637
  indexNote(deps.index, deps.vaultDir, relativePath);
2277
2638
  if (deps.vectorIndex && embeddingText) {
@@ -2286,7 +2647,7 @@ function writeObservations(observations, sessionId, deps) {
2286
2647
  note.id,
2287
2648
  `${note.observation.title}
2288
2649
  ${note.observation.content}`,
2289
- { type: "memory", importance: "high", session_id: sessionId },
2650
+ { type: "spore", importance: "high", session_id: sessionId },
2290
2651
  deps
2291
2652
  );
2292
2653
  deps.logger.info("processor", "Observation written", { type: note.observation.type, title: note.observation.title, session_id: sessionId });
@@ -2323,29 +2684,29 @@ ${candidate.content}`,
2323
2684
  lineage?.registerArtifactForSession(sessionId, artifactId);
2324
2685
  }
2325
2686
  }
2326
- function migrateMemoryFiles(vaultDir) {
2327
- const memoriesDir = path6.join(vaultDir, "memories");
2328
- if (!fs4.existsSync(memoriesDir)) return 0;
2687
+ function migrateSporeFiles(vaultDir) {
2688
+ const sporesDir = path7.join(vaultDir, "spores");
2689
+ if (!fs5.existsSync(sporesDir)) return 0;
2329
2690
  let moved = 0;
2330
- const entries = fs4.readdirSync(memoriesDir);
2691
+ const entries = fs5.readdirSync(sporesDir);
2331
2692
  for (const entry of entries) {
2332
- const fullPath = path6.join(memoriesDir, entry);
2693
+ const fullPath = path7.join(sporesDir, entry);
2333
2694
  if (!entry.endsWith(".md")) continue;
2334
- if (fs4.statSync(fullPath).isDirectory()) continue;
2695
+ if (fs5.statSync(fullPath).isDirectory()) continue;
2335
2696
  try {
2336
- const content = fs4.readFileSync(fullPath, "utf-8");
2697
+ const content = fs5.readFileSync(fullPath, "utf-8");
2337
2698
  const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
2338
2699
  if (!fmMatch) continue;
2339
- const parsed = import_yaml.default.parse(fmMatch[1]);
2700
+ const parsed = import_yaml2.default.parse(fmMatch[1]);
2340
2701
  const obsType = parsed.observation_type;
2341
2702
  if (!obsType) continue;
2342
2703
  const normalizedType = obsType.replace(/_/g, "-");
2343
- const targetDir = path6.join(memoriesDir, normalizedType);
2344
- fs4.mkdirSync(targetDir, { recursive: true });
2345
- const targetPath = path6.join(targetDir, entry);
2346
- fs4.renameSync(fullPath, targetPath);
2704
+ const targetDir = path7.join(sporesDir, normalizedType);
2705
+ fs5.mkdirSync(targetDir, { recursive: true });
2706
+ const targetPath = path7.join(targetDir, entry);
2707
+ fs5.renameSync(fullPath, targetPath);
2347
2708
  const now = /* @__PURE__ */ new Date();
2348
- fs4.utimesSync(targetPath, now, now);
2709
+ fs5.utimesSync(targetPath, now, now);
2349
2710
  moved++;
2350
2711
  } catch {
2351
2712
  }
@@ -2358,9 +2719,9 @@ async function main() {
2358
2719
  process.stderr.write("Usage: mycod --vault <path>\n");
2359
2720
  process.exit(1);
2360
2721
  }
2361
- const vaultDir = path6.resolve(vaultArg);
2722
+ const vaultDir = path7.resolve(vaultArg);
2362
2723
  const config = loadConfig(vaultDir);
2363
- const logger = new DaemonLogger(path6.join(vaultDir, "logs"), {
2724
+ const logger = new DaemonLogger(path7.join(vaultDir, "logs"), {
2364
2725
  level: config.daemon.log_level,
2365
2726
  maxSize: config.daemon.max_log_size
2366
2727
  });
@@ -2369,6 +2730,7 @@ async function main() {
2369
2730
  gracePeriod: config.daemon.grace_period,
2370
2731
  onEmpty: async () => {
2371
2732
  logger.info("daemon", "Grace period expired, shutting down");
2733
+ metabolism?.stop();
2372
2734
  planWatcher.stopFileWatcher();
2373
2735
  await server.stop();
2374
2736
  vectorIndex?.close();
@@ -2382,14 +2744,14 @@ async function main() {
2382
2744
  let vectorIndex = null;
2383
2745
  try {
2384
2746
  const testEmbed = await embeddingProvider.embed("test");
2385
- vectorIndex = new VectorIndex(path6.join(vaultDir, "vectors.db"), testEmbed.dimensions);
2747
+ vectorIndex = new VectorIndex(path7.join(vaultDir, "vectors.db"), testEmbed.dimensions);
2386
2748
  logger.info("embeddings", "Vector index initialized", { dimensions: testEmbed.dimensions });
2387
2749
  } catch (error) {
2388
2750
  logger.warn("embeddings", "Vector index unavailable", { error: error.message });
2389
2751
  }
2390
- const processor = new BufferProcessor(llmProvider, config.intelligence.llm.context_window);
2752
+ const processor = new BufferProcessor(llmProvider, config.intelligence.llm.context_window, config.capture);
2391
2753
  const vault = new VaultWriter(vaultDir);
2392
- const index = new MycoIndex(path6.join(vaultDir, "index.db"));
2754
+ const index = new MycoIndex(path7.join(vaultDir, "index.db"));
2393
2755
  const lineageGraph = new LineageGraph(vaultDir);
2394
2756
  const transcriptMiner = new TranscriptMiner({
2395
2757
  additionalAdapters: config.capture.transcript_paths.map(
@@ -2398,24 +2760,25 @@ async function main() {
2398
2760
  });
2399
2761
  let activeStopProcessing = null;
2400
2762
  const indexDeps = { index, vaultDir, vectorIndex, embeddingProvider, logger };
2401
- const bufferDir = path6.join(vaultDir, "buffer");
2763
+ const bufferDir = path7.join(vaultDir, "buffer");
2402
2764
  const sessionBuffers = /* @__PURE__ */ new Map();
2403
2765
  const sessionFilePaths = /* @__PURE__ */ new Map();
2404
2766
  const capturedArtifactPaths = /* @__PURE__ */ new Map();
2405
- if (fs4.existsSync(bufferDir)) {
2767
+ if (fs5.existsSync(bufferDir)) {
2406
2768
  const cutoff = Date.now() - STALE_BUFFER_MAX_AGE_MS;
2407
- for (const file of fs4.readdirSync(bufferDir)) {
2408
- const filePath = path6.join(bufferDir, file);
2409
- const stat4 = fs4.statSync(filePath);
2769
+ for (const file of fs5.readdirSync(bufferDir)) {
2770
+ const filePath = path7.join(bufferDir, file);
2771
+ const stat4 = fs5.statSync(filePath);
2410
2772
  if (stat4.mtimeMs < cutoff) {
2411
- fs4.unlinkSync(filePath);
2773
+ fs5.unlinkSync(filePath);
2412
2774
  logger.debug("daemon", "Cleaned stale buffer", { file });
2413
2775
  }
2414
2776
  }
2415
2777
  }
2416
- const migrated = migrateMemoryFiles(vaultDir);
2778
+ const needsMigrationReindex = index.query({ type: "memory" }).length > 0;
2779
+ const migrated = migrateSporeFiles(vaultDir);
2417
2780
  if (migrated > 0) {
2418
- logger.info("daemon", "Migrated memory files to type subdirectories", { count: migrated });
2781
+ logger.info("daemon", "Migrated spore files to type subdirectories", { count: migrated });
2419
2782
  initFts(index);
2420
2783
  rebuildIndex(index, vaultDir);
2421
2784
  }
@@ -2444,10 +2807,10 @@ async function main() {
2444
2807
  logger.info("watcher", "Plan detected", { source: event.source, file: event.filePath });
2445
2808
  if (event.filePath) {
2446
2809
  try {
2447
- const content = fs4.readFileSync(event.filePath, "utf-8");
2448
- const relativePath = path6.relative(vaultDir, event.filePath);
2449
- const title = content.match(/^#\s+(.+)$/m)?.[1] ?? path6.basename(event.filePath);
2450
- const planId = `plan-${path6.basename(event.filePath, ".md")}`;
2810
+ const content = fs5.readFileSync(event.filePath, "utf-8");
2811
+ const relativePath = path7.relative(vaultDir, event.filePath);
2812
+ const title = content.match(/^#\s+(.+)$/m)?.[1] ?? path7.basename(event.filePath);
2813
+ const planId = `plan-${path7.basename(event.filePath, ".md")}`;
2451
2814
  indexAndEmbed(
2452
2815
  relativePath,
2453
2816
  planId,
@@ -2468,6 +2831,51 @@ ${content}`,
2468
2831
  }
2469
2832
  });
2470
2833
  planWatcher.startFileWatcher();
2834
+ let metabolism = null;
2835
+ if (config.digest.enabled) {
2836
+ const digestLlmConfig = {
2837
+ provider: config.digest.intelligence.provider ?? config.intelligence.llm.provider,
2838
+ model: config.digest.intelligence.model ?? config.intelligence.llm.model,
2839
+ base_url: config.digest.intelligence.base_url ?? config.intelligence.llm.base_url,
2840
+ context_window: config.digest.intelligence.context_window
2841
+ };
2842
+ logger.debug("digest", "Digest LLM config", digestLlmConfig);
2843
+ const digestLlm = config.digest.intelligence.model || config.digest.intelligence.provider ? createLlmProvider(digestLlmConfig) : llmProvider;
2844
+ logger.debug("digest", `Using ${digestLlm.name} provider for digest`);
2845
+ const digestEngine = new DigestEngine({
2846
+ vaultDir,
2847
+ index,
2848
+ llmProvider: digestLlm,
2849
+ config,
2850
+ log: (level, message, data) => logger[level]("digest", message, data)
2851
+ });
2852
+ metabolism = new Metabolism(config.digest.metabolism);
2853
+ logger.debug("digest", "Firing initial digest cycle (background)");
2854
+ digestEngine.runCycle().then((result) => {
2855
+ if (result) {
2856
+ metabolism.onSubstrateFound();
2857
+ logger.info("digest", `Initial digest cycle: ${result.tiersGenerated.length} tiers, ${result.durationMs}ms`);
2858
+ }
2859
+ }).catch((err) => {
2860
+ logger.warn("digest", "Initial digest cycle failed", { error: err.message });
2861
+ });
2862
+ metabolism.start(async () => {
2863
+ try {
2864
+ const cycleResult = await digestEngine.runCycle();
2865
+ if (cycleResult) {
2866
+ metabolism.onSubstrateFound();
2867
+ logger.info("digest", `Digest cycle ${cycleResult.cycleId}: ${cycleResult.tiersGenerated.length} tiers`);
2868
+ } else {
2869
+ metabolism.onEmptyCycle();
2870
+ logger.debug("digest", "No substrate, backing off");
2871
+ }
2872
+ } catch (err) {
2873
+ logger.warn("digest", "Digest cycle failed", { error: err.message });
2874
+ metabolism.onEmptyCycle();
2875
+ }
2876
+ });
2877
+ logger.info("digest", "Digest enabled \u2014 starting metabolism");
2878
+ }
2471
2879
  const batchManager = new BatchManager(async (closedBatch) => {
2472
2880
  if (closedBatch.length === 0) return;
2473
2881
  const sessionId = closedBatch[0].session_id;
@@ -2498,7 +2906,7 @@ ${content}`,
2498
2906
  }
2499
2907
  const captured = capturedArtifactPaths.get(sessionId);
2500
2908
  for (const c of candidates) {
2501
- const absPath = path6.resolve(process.cwd(), c.path);
2909
+ const absPath = path7.resolve(process.cwd(), c.path);
2502
2910
  captured.add(absPath);
2503
2911
  }
2504
2912
  }).catch((err) => logger.warn("processor", "Incremental artifact capture failed", {
@@ -2529,6 +2937,7 @@ ${content}`,
2529
2937
  } catch (err) {
2530
2938
  logger.debug("lineage", "Heuristic detection failed", { error: err.message });
2531
2939
  }
2940
+ metabolism?.activate();
2532
2941
  logger.info("lifecycle", "Session registered", { session_id, branch });
2533
2942
  return { ok: true, sessions: registry.sessions };
2534
2943
  });
@@ -2537,14 +2946,14 @@ ${content}`,
2537
2946
  registry.unregister(session_id);
2538
2947
  try {
2539
2948
  const cutoff = Date.now() - STALE_BUFFER_MAX_AGE_MS;
2540
- for (const file of fs4.readdirSync(bufferDir)) {
2949
+ for (const file of fs5.readdirSync(bufferDir)) {
2541
2950
  if (!file.endsWith(".jsonl")) continue;
2542
2951
  const bufferSessionId = file.replace(".jsonl", "");
2543
2952
  if (bufferSessionId === session_id) continue;
2544
- const filePath = path6.join(bufferDir, file);
2545
- const stat4 = fs4.statSync(filePath);
2953
+ const filePath = path7.join(bufferDir, file);
2954
+ const stat4 = fs5.statSync(filePath);
2546
2955
  if (stat4.mtimeMs < cutoff) {
2547
- fs4.unlinkSync(filePath);
2956
+ fs5.unlinkSync(filePath);
2548
2957
  logger.debug("daemon", "Cleaned stale buffer", { file });
2549
2958
  }
2550
2959
  }
@@ -2639,15 +3048,15 @@ ${content}`,
2639
3048
  }
2640
3049
  const ended = (/* @__PURE__ */ new Date()).toISOString();
2641
3050
  let started = allTurns.length > 0 && allTurns[0].timestamp ? allTurns[0].timestamp : ended;
2642
- const sessionsDir = path6.join(vaultDir, "sessions");
3051
+ const sessionsDir = path7.join(vaultDir, "sessions");
2643
3052
  const sessionFileName = `${sessionNoteId(sessionId)}.md`;
2644
3053
  let existingContent;
2645
3054
  const duplicatePaths = [];
2646
3055
  try {
2647
- for (const dateDir of fs4.readdirSync(sessionsDir)) {
2648
- const candidate = path6.join(sessionsDir, dateDir, sessionFileName);
3056
+ for (const dateDir of fs5.readdirSync(sessionsDir)) {
3057
+ const candidate = path7.join(sessionsDir, dateDir, sessionFileName);
2649
3058
  try {
2650
- const content = fs4.readFileSync(candidate, "utf-8");
3059
+ const content = fs5.readFileSync(candidate, "utf-8");
2651
3060
  if (!existingContent || content.length > existingContent.length) {
2652
3061
  existingContent = content;
2653
3062
  }
@@ -2707,20 +3116,20 @@ ${conversationText}`;
2707
3116
  }
2708
3117
  const date = started.slice(0, 10);
2709
3118
  const relativePath = sessionRelativePath(sessionId, date);
2710
- const targetFullPath = path6.join(vaultDir, relativePath);
3119
+ const targetFullPath = path7.join(vaultDir, relativePath);
2711
3120
  for (const dup of duplicatePaths) {
2712
3121
  if (dup !== targetFullPath) {
2713
3122
  try {
2714
- fs4.unlinkSync(dup);
3123
+ fs5.unlinkSync(dup);
2715
3124
  logger.debug("lifecycle", "Removed duplicate session file", { path: dup });
2716
3125
  } catch {
2717
3126
  }
2718
3127
  }
2719
3128
  }
2720
- const attachmentsDir = path6.join(vaultDir, "attachments");
3129
+ const attachmentsDir = path7.join(vaultDir, "attachments");
2721
3130
  const hasImages = allTurns.some((t) => t.images?.length);
2722
3131
  if (hasImages) {
2723
- fs4.mkdirSync(attachmentsDir, { recursive: true });
3132
+ fs5.mkdirSync(attachmentsDir, { recursive: true });
2724
3133
  }
2725
3134
  const turnImageNames = /* @__PURE__ */ new Map();
2726
3135
  for (let i = 0; i < allTurns.length; i++) {
@@ -2731,9 +3140,9 @@ ${conversationText}`;
2731
3140
  const img = turn.images[j];
2732
3141
  const ext = extensionForMimeType(img.mediaType);
2733
3142
  const filename = `${bareSessionId(sessionId)}-t${i + 1}-${j + 1}.${ext}`;
2734
- const filePath = path6.join(attachmentsDir, filename);
2735
- if (!fs4.existsSync(filePath)) {
2736
- fs4.writeFileSync(filePath, Buffer.from(img.data, "base64"));
3143
+ const filePath = path7.join(attachmentsDir, filename);
3144
+ if (!fs5.existsSync(filePath)) {
3145
+ fs5.writeFileSync(filePath, Buffer.from(img.data, "base64"));
2737
3146
  logger.debug("processor", "Image saved", { filename, turn: i + 1 });
2738
3147
  }
2739
3148
  names.push(filename);
@@ -2746,7 +3155,7 @@ ${conversationText}`;
2746
3155
  title = summaryResult.title;
2747
3156
  narrative = summaryResult.summary;
2748
3157
  }
2749
- const relatedMemories = index.query({ type: "memory", limit: RELATED_MEMORIES_LIMIT }).filter((n) => {
3158
+ const relatedMemories = index.query({ type: "spore", limit: RELATED_SPORES_LIMIT }).filter((n) => {
2750
3159
  const fm = n.frontmatter;
2751
3160
  return fm.session === sessionNoteId(sessionId) || fm.session === sessionId;
2752
3161
  }).map((n) => ({ id: n.id, title: n.title }));
@@ -2838,6 +3247,17 @@ ${conversationText}`;
2838
3247
  const { session_id, branch } = ContextBody.parse(body);
2839
3248
  logger.debug("hooks", "Session context query", { session_id });
2840
3249
  try {
3250
+ if (config.digest.enabled && config.digest.inject_tier) {
3251
+ const result = handleMycoContext(vaultDir, { tier: config.digest.inject_tier });
3252
+ if (result.generated !== void 0) {
3253
+ const meta = [result.content];
3254
+ if (branch) meta.push(`
3255
+ Branch:: \`${branch}\``);
3256
+ meta.push(`Session:: \`${session_id}\``);
3257
+ logger.debug("context", `Injecting digest extract (tier ${result.tier})`, { session_id, fallback: result.fallback });
3258
+ return { text: meta.join("\n\n"), source: "digest", tier: result.tier };
3259
+ }
3260
+ }
2841
3261
  const parts = [];
2842
3262
  const plans = index.query({ type: "plan" });
2843
3263
  const activePlans = plans.filter((p) => {
@@ -2888,8 +3308,8 @@ ${planLines.join("\n")}`);
2888
3308
  try {
2889
3309
  const emb = await generateEmbedding(embeddingProvider, prompt.slice(0, EMBEDDING_INPUT_LIMIT));
2890
3310
  const results = vectorIndex.search(emb.embedding, {
2891
- limit: PROMPT_CONTEXT_MAX_MEMORIES,
2892
- type: "memory",
3311
+ limit: PROMPT_CONTEXT_MAX_SPORES,
3312
+ type: "spore",
2893
3313
  relativeThreshold: PROMPT_CONTEXT_MIN_SIMILARITY
2894
3314
  });
2895
3315
  if (results.length === 0) return { text: "" };
@@ -2906,11 +3326,11 @@ ${planLines.join("\n")}`);
2906
3326
  lines.push(`- [${obsType}] ${note.title}: ${note.content.slice(0, CONTENT_SNIPPET_CHARS)} \`[${note.id}]\``);
2907
3327
  }
2908
3328
  if (lines.length === 0) return { text: "" };
2909
- const injected = `**Relevant memories for this task:**
3329
+ const injected = `**Relevant spores for this task:**
2910
3330
  ${lines.join("\n")}`;
2911
3331
  logger.debug("context", "Prompt context injected", {
2912
3332
  session_id,
2913
- memories: lines.length,
3333
+ spores: lines.length,
2914
3334
  prompt_preview: prompt.slice(0, 50)
2915
3335
  });
2916
3336
  return { text: injected };
@@ -2921,12 +3341,21 @@ ${lines.join("\n")}`;
2921
3341
  });
2922
3342
  await server.start();
2923
3343
  logger.info("daemon", "Daemon ready", { vault: vaultDir, port: server.port });
3344
+ if (needsMigrationReindex) {
3345
+ setImmediate(() => {
3346
+ logger.info("daemon", "Rebuilding index after memories\u2192spores migration (background)");
3347
+ initFts(index);
3348
+ rebuildIndex(index, vaultDir);
3349
+ logger.info("daemon", "Migration reindex complete");
3350
+ });
3351
+ }
2924
3352
  const shutdown = async (signal) => {
2925
3353
  logger.info("daemon", `${signal} received`);
2926
3354
  if (activeStopProcessing) {
2927
3355
  logger.info("daemon", "Waiting for active stop processing to complete...");
2928
3356
  await activeStopProcessing;
2929
3357
  }
3358
+ metabolism?.stop();
2930
3359
  planWatcher.stopFileWatcher();
2931
3360
  registry.destroy();
2932
3361
  await server.stop();
@@ -2940,11 +3369,11 @@ ${lines.join("\n")}`;
2940
3369
  }
2941
3370
  export {
2942
3371
  main,
2943
- migrateMemoryFiles
3372
+ migrateSporeFiles
2944
3373
  };
2945
3374
  /*! Bundled license information:
2946
3375
 
2947
3376
  chokidar/index.js:
2948
3377
  (*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) *)
2949
3378
  */
2950
- //# sourceMappingURL=main-S3WSUF5T.js.map
3379
+ //# sourceMappingURL=main-3JSO25IZ.js.map