volute 0.31.0 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/README.md +31 -22
  2. package/dist/{accept-GAKQ3MEH.js → accept-D5VBM7JW.js} +5 -4
  3. package/dist/{activity-events-T5ZRCVAL.js → activity-events-XJO3P4RR.js} +3 -2
  4. package/dist/{ai-service-UWUPM4T6.js → ai-service-SBY2WG7O.js} +18 -5
  5. package/dist/api.d.ts +703 -1068
  6. package/dist/{archive-YBNSJYZZ.js → archive-INXYFVCW.js} +3 -2
  7. package/dist/{auth-T5AW2USD.js → auth-GKCDSO4T.js} +4 -3
  8. package/dist/{bridge-4AJ3EY26.js → bridge-TXWWPPOJ.js} +5 -4
  9. package/dist/{chat-7YLT7FI3.js → chat-U5ZOME3O.js} +8 -8
  10. package/dist/{chunk-NV3TYNWX.js → chunk-2NGTS5UU.js} +1 -1
  11. package/dist/{chunk-BWKIHH7B.js → chunk-3Z2DPESO.js} +662 -508
  12. package/dist/chunk-6LXAAQ43.js +22 -0
  13. package/dist/chunk-7J3HEVR7.js +220 -0
  14. package/dist/{chunk-NOWVQ7AL.js → chunk-A2A4KLFE.js} +351 -301
  15. package/dist/{chunk-LX6T3GKQ.js → chunk-ALEF47VT.js} +1 -1
  16. package/dist/{chunk-S2TZLSDH.js → chunk-C7I35G4R.js} +163 -15
  17. package/dist/{chunk-VGWJSNHS.js → chunk-G53F3JA4.js} +1 -35
  18. package/dist/{chunk-A6TUJJ3L.js → chunk-G6BSYHPK.js} +2 -2
  19. package/dist/{chunk-DAXJKPHZ.js → chunk-GY5HBI7A.js} +2 -2
  20. package/dist/{chunk-BC3P3QCK.js → chunk-I5KY25PQ.js} +1 -9
  21. package/dist/{chunk-BNC43CSY.js → chunk-JUKK7FPS.js} +2 -2
  22. package/dist/{chunk-R5QJBZZG.js → chunk-JYVGHWEJ.js} +21 -11
  23. package/dist/chunk-KIEPMIM5.js +59 -0
  24. package/dist/{chunk-EKDWA7E4.js → chunk-KVK2DLWI.js} +5 -2
  25. package/dist/{chunk-AAO77TZX.js → chunk-LOEJ4HPQ.js} +1 -1
  26. package/dist/chunk-LRCG2JLP.js +251 -0
  27. package/dist/{chunk-EMPFLFTG.js → chunk-M7UL5S3Q.js} +1 -1
  28. package/dist/{chunk-6QIUN46C.js → chunk-N432I7QH.js} +20 -3
  29. package/dist/{chunk-SNVPRRT7.js → chunk-NNB4WIG7.js} +2 -2
  30. package/dist/{chunk-HDKY4TWU.js → chunk-NPKSDYA2.js} +3 -3
  31. package/dist/chunk-OYAKCAVY.js +29 -0
  32. package/dist/chunk-PB65JZK2.js +85 -0
  33. package/dist/chunk-PVY5W6QN.js +41 -0
  34. package/dist/{chunk-PNQCXLSV.js → chunk-QTUVYI7W.js} +58 -1
  35. package/dist/{chunk-X62AXPR7.js → chunk-RPZZSXV3.js} +8 -196
  36. package/dist/{chunk-WRS3B556.js → chunk-RSX4OPZY.js} +5 -5
  37. package/dist/{chunk-FAHDKPEH.js → chunk-RVGLDGMI.js} +5 -3
  38. package/dist/chunk-SKLSMHXO.js +208 -0
  39. package/dist/{chunk-4OUOFS23.js → chunk-UKVWJRKN.js} +1 -1
  40. package/dist/{chunk-57OKQMP3.js → chunk-VH33ZWMW.js} +5 -55
  41. package/dist/cli.js +49 -23
  42. package/dist/{clock-LJCG426D.js → clock-BVH3V6E3.js} +7 -6
  43. package/dist/{cloud-sync-O3LXIRN6.js → cloud-sync-4NWLMFVH.js} +20 -14
  44. package/dist/config-H2H4UIF7.js +72 -0
  45. package/dist/connectors/discord-bridge.js +1 -1
  46. package/dist/connectors/slack-bridge.js +1 -1
  47. package/dist/connectors/telegram-bridge.js +1 -1
  48. package/dist/{conversations-RKKGP5IA.js → conversations-AWI5SZW2.js} +4 -3
  49. package/dist/{create-TL623TFC.js → create-2FK7Z46Y.js} +6 -2
  50. package/dist/{create-WUTIIRI2.js → create-YWD2TIP4.js} +6 -5
  51. package/dist/{daemon-client-CVGM25DM.js → daemon-client-6QXHZ7US.js} +3 -2
  52. package/dist/{daemon-restart-EZP7XH3V.js → daemon-restart-GOBUKLX7.js} +8 -6
  53. package/dist/daemon.js +1918 -1472
  54. package/dist/{db-SW5PL6QA.js → db-F34YLV7D.js} +2 -1
  55. package/dist/db-RA45JBFG.js +16 -0
  56. package/dist/{delete-Z6HAG35F.js → delete-QTGWEDBI.js} +1 -1
  57. package/dist/delivery-manager-PFAKEJTC.js +32 -0
  58. package/dist/delivery-router-FL45JL7N.js +21 -0
  59. package/dist/down-FWWTEKXM.js +15 -0
  60. package/dist/{env-NHESNNSP.js → env-JCOF2222.js} +5 -4
  61. package/dist/{export-EVMP7GWY.js → export-SUYRLI5Q.js} +4 -3
  62. package/dist/{extension-LR7EW3JF.js → extension-OBTGKQQD.js} +5 -3
  63. package/dist/{extensions-NGEJI7JH.js → extensions-KYNTVTMO.js} +10 -7
  64. package/dist/{files-3SM7V33S.js → files-65PMW5IK.js} +6 -5
  65. package/dist/{history-PQD3LXEP.js → history-DKCDI3JO.js} +9 -4
  66. package/dist/{import-PR2OCGQJ.js → import-DDUFE7AY.js} +4 -3
  67. package/dist/isolation-LLAYQYDY.js +22 -0
  68. package/dist/{join-R4EN5CWQ.js → join-I5QEE3LG.js} +1 -1
  69. package/dist/{list-B4XNUOFO.js → list-JQ463EDA.js} +5 -4
  70. package/dist/{login-62JVY6A2.js → login-D7ETSU4R.js} +5 -4
  71. package/dist/{login-URWP6S2N.js → login-RIJF2F4G.js} +3 -2
  72. package/dist/{logout-NXJQJDLI.js → logout-5MLHZALK.js} +3 -2
  73. package/dist/{logout-ZK2N62T3.js → logout-UZJRGY4Z.js} +3 -2
  74. package/dist/message-delivery-DFF5SJRM.js +42 -0
  75. package/dist/{mind-E2ZV2WRX.js → mind-IOJFLEM5.js} +25 -19
  76. package/dist/{mind-activity-tracker-ASNZBMLC.js → mind-activity-tracker-F6O4Q2SL.js} +4 -3
  77. package/dist/{mind-list-BEI7E5WY.js → mind-list-WUPMQDYQ.js} +3 -2
  78. package/dist/mind-manager-NBJF5D26.js +32 -0
  79. package/dist/mind-profile-P67FEHOY.js +47 -0
  80. package/dist/mind-service-2MQ6UK5N.js +38 -0
  81. package/dist/{mind-sleep-CANABWJI.js → mind-sleep-WW2IX7JT.js} +5 -4
  82. package/dist/{mind-status-6WKZVUOP.js → mind-status-L3EFFRPR.js} +3 -2
  83. package/dist/{mind-wake-RZKLH2IN.js → mind-wake-VSSGW465.js} +5 -4
  84. package/dist/{package-NU4CA7OU.js → package-U3VFO273.js} +2 -1
  85. package/dist/{read-THL362EI.js → read-EBY56C33.js} +5 -4
  86. package/dist/read-stdin-HQJ7774D.js +8 -0
  87. package/dist/{register-QAQELAS6.js → register-HD74C4TT.js} +5 -4
  88. package/dist/{registry-ASXCQCNH.js → registry-PJ4S5PHQ.js} +8 -1
  89. package/dist/{reject-AYPBNPNL.js → reject-UJKFBHRO.js} +5 -4
  90. package/dist/{restart-6SKPV3T2.js → restart-3UCMRUVC.js} +3 -2
  91. package/dist/{sandbox-6ZEWQDVU.js → sandbox-GJOK4QLQ.js} +4 -3
  92. package/dist/scheduler-ZZ7XGQG6.js +32 -0
  93. package/dist/schema-PA3M5ZKH.js +32 -0
  94. package/dist/seed-QDYVLG74.js +11 -0
  95. package/dist/seed-check-S2IX25RL.js +32 -0
  96. package/dist/seed-cmd-DKOUFEAU.js +36 -0
  97. package/dist/{seed-OWX2AW75.js → seed-create-4XBBOLRH.js} +27 -10
  98. package/dist/{sprout-FDVI2CGN.js → seed-sprout-GQEIIQRT.js} +24 -9
  99. package/dist/{send-ZO4BTWXK.js → send-QIV2INHB.js} +92 -101
  100. package/dist/{setup-7CFITEQN.js → setup-TISPCO22.js} +7 -2
  101. package/dist/{setup-ZXBXG7E4.js → setup-XMCBE3LF.js} +11 -7
  102. package/dist/{skill-YFXP67A2.js → skill-PSQGRRJX.js} +5 -4
  103. package/dist/skills/dreaming/SKILL.md +6 -4
  104. package/dist/skills/dreaming/references/INSTALL.md +2 -2
  105. package/dist/skills/dreaming/scripts/dream.ts +2 -2
  106. package/dist/skills/dreaming/scripts/wake-context-dreams.sh +1 -1
  107. package/dist/skills/imagegen/SKILL.md +16 -11
  108. package/dist/skills/imagegen/references/INSTALL.md +1 -1
  109. package/dist/skills/imagegen/scripts/imagegen.ts +146 -25
  110. package/dist/skills/orientation/SKILL.md +9 -2
  111. package/dist/skills/resonance/SKILL.md +4 -1
  112. package/dist/skills/resonance/references/INSTALL.md +2 -2
  113. package/dist/skills/resonance/scripts/resonance-hook.sh +2 -0
  114. package/dist/skills/resonance/scripts/resonance.ts +35 -5
  115. package/dist/skills/seed-nurture/SKILL.md +42 -0
  116. package/dist/skills/volute-admin/SKILL.md +83 -0
  117. package/dist/skills/volute-mind/SKILL.md +15 -11
  118. package/dist/skills-7FV7EJTE.js +62 -0
  119. package/dist/sleep-manager-JTXSN7NV.js +36 -0
  120. package/dist/spirit-VRONKFMF.js +23 -0
  121. package/dist/{split-MI62KJUU.js → split-STOROBYJ.js} +1 -1
  122. package/dist/sprout-WKLZXUIQ.js +11 -0
  123. package/dist/{start-D64BRKPH.js → start-K2NCUUCG.js} +3 -2
  124. package/dist/{status-ZZWBYFGE.js → status-3JBTFSMI.js} +6 -4
  125. package/dist/{stop-OP2CTXCO.js → stop-H26JZDXF.js} +3 -2
  126. package/dist/system-chat-JAPOJ3KE.js +36 -0
  127. package/dist/{systems-EQPPT4B7.js → systems-XRI52VCH.js} +6 -5
  128. package/dist/{tailscale-6DJKUMNF.js → tailscale-XHQBZROW.js} +2 -1
  129. package/dist/{template-hash-3HOR4UAJ.js → template-hash-A6VVKOXJ.js} +2 -1
  130. package/dist/up-M5AS6SBV.js +18 -0
  131. package/dist/{update-KUJXATRS.js → update-UD543CXX.js} +6 -4
  132. package/dist/{update-check-5WVSU37T.js → update-check-ZD6OOIYQ.js} +3 -2
  133. package/dist/{upgrade-KBHCWX6T.js → upgrade-O4Q7WJM3.js} +12 -14
  134. package/dist/{version-notify-75ELVKPV.js → version-notify-NBI2MTJO.js} +22 -16
  135. package/dist/volute-config-HD7WWUQC.js +10 -0
  136. package/dist/web-assets/assets/index-CWJrVveV.css +1 -0
  137. package/dist/web-assets/assets/index-DJt14FRI.js +75 -0
  138. package/dist/web-assets/ext-theme.css +93 -0
  139. package/dist/web-assets/index.html +2 -2
  140. package/drizzle/0004_spirits.sql +5 -0
  141. package/drizzle/meta/0004_snapshot.json +7 -0
  142. package/drizzle/meta/_journal.json +7 -0
  143. package/package.json +2 -1
  144. package/packages/extensions/notes/dist/ui/assets/index-8jWEv9SA.js +61 -0
  145. package/packages/extensions/notes/dist/ui/assets/index-DkaB7Ytd.css +1 -0
  146. package/packages/extensions/notes/dist/ui/index.html +2 -2
  147. package/packages/extensions/pages/skills/pages/SKILL.md +16 -46
  148. package/templates/_base/.init/.config/hooks/pre-prompt/session-activity.ts +40 -0
  149. package/templates/_base/.init/{.config → .local}/bin/volute +1 -1
  150. package/templates/_base/.init/.local/hooks/pre-prompt/session-activity.ts +40 -0
  151. package/templates/_base/.init/.local/hooks/startup-context.ts +58 -0
  152. package/templates/_base/home/.config/routes.json +1 -1
  153. package/templates/_base/src/lib/daemon-client.ts +21 -13
  154. package/templates/_base/src/lib/format-prefix.ts +1 -0
  155. package/templates/_base/src/lib/hook-loader.ts +155 -0
  156. package/templates/_base/src/lib/startup.ts +11 -4
  157. package/templates/_base/src/lib/transparency.ts +2 -2
  158. package/templates/claude/.init/.claude/settings.json +1 -1
  159. package/templates/claude/.init/.config/routes.json +2 -2
  160. package/templates/claude/src/agent.ts +95 -13
  161. package/templates/claude/src/lib/message-channel.ts +7 -2
  162. package/templates/claude/src/lib/stream-consumer.ts +38 -0
  163. package/templates/codex/.init/.config/routes.json +11 -0
  164. package/templates/codex/.init/AGENTS.md +29 -0
  165. package/templates/codex/home/.config/config.json.tmpl +7 -0
  166. package/templates/codex/package.json.tmpl +20 -0
  167. package/templates/codex/src/agent.ts +554 -0
  168. package/templates/codex/src/lib/content.ts +16 -0
  169. package/templates/codex/src/lib/session-store.ts +56 -0
  170. package/templates/codex/src/server.ts +59 -0
  171. package/templates/codex/volute-template.json +8 -0
  172. package/templates/pi/.init/.config/routes.json +2 -2
  173. package/templates/pi/src/agent.ts +62 -8
  174. package/templates/pi/src/lib/event-handler.ts +1 -1
  175. package/templates/pi/src/lib/reply-instructions-extension.ts +32 -11
  176. package/dist/chunk-HR5JKIDG.js +0 -222
  177. package/dist/down-TS4XQBA4.js +0 -13
  178. package/dist/message-delivery-UJHCLVU4.js +0 -30
  179. package/dist/mind-manager-IPA6DZXD.js +0 -26
  180. package/dist/pages-watcher-72OVPRMH.js +0 -22
  181. package/dist/skills/sessions/SKILL.md +0 -49
  182. package/dist/sleep-manager-TPS6OGCA.js +0 -30
  183. package/dist/system-chat-B43GIXQU.js +0 -30
  184. package/dist/up-TDXEP3VA.js +0 -16
  185. package/dist/web-assets/assets/index-BM1cTzBg.js +0 -72
  186. package/dist/web-assets/assets/index-BfJkKTPF.css +0 -1
  187. package/packages/extensions/notes/dist/ui/assets/index-B8GdTnXs.css +0 -1
  188. package/packages/extensions/notes/dist/ui/assets/index-CDpGTCWb.js +0 -2
  189. package/packages/extensions/pages/skills/pages/scripts/pages.mjs +0 -58
  190. package/templates/_base/.init/.config/hooks/startup-context.sh +0 -46
  191. package/templates/_base/.init/.config/scripts/session-reader.ts +0 -59
  192. package/templates/_base/src/lib/session-monitor.ts +0 -400
  193. package/templates/claude/src/lib/hooks/session-context.ts +0 -32
  194. package/templates/pi/src/lib/session-context-extension.ts +0 -35
  195. /package/templates/_base/.init/{.config → .local}/hooks/wake-context.sh +0 -0
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "gateUnmatched": true,
3
3
  "rules": [
4
- { "channel": "volute:*", "isDM": true, "session": "${channel}" },
5
- { "channel": "volute:*", "isDM": false, "session": "group-${channel}" }
4
+ { "channel": "*", "isDM": true, "session": "${channel}" },
5
+ { "channel": "*", "isDM": false, "session": "group-${channel}" }
6
6
  ],
7
7
  "sessions": {
8
8
  "group-*": { "batch": { "debounce": 20, "maxWait": 120, "triggers": ["@{{name}}"] } }
@@ -10,11 +10,11 @@ import {
10
10
  SettingsManager,
11
11
  } from "@mariozechner/pi-coding-agent";
12
12
  import { extractImages, extractText } from "./lib/content.js";
13
- import { createEventHandler } from "./lib/event-handler.js";
13
+ import { createEventHandler, emit } from "./lib/event-handler.js";
14
+ import { runHooks } from "./lib/hook-loader.js";
14
15
  import { log } from "./lib/logger.js";
15
16
  import { createReplyInstructionsExtension } from "./lib/reply-instructions-extension.js";
16
17
  import { resolveModel } from "./lib/resolve-model.js";
17
- import { createSessionContextExtension } from "./lib/session-context-extension.js";
18
18
  import { loadPrompts, type SubagentConfig } from "./lib/startup.js";
19
19
  import { createSubagentExtension, type SubagentDefinition } from "./lib/subagents.js";
20
20
  import type {
@@ -109,6 +109,59 @@ export function createMind(options: {
109
109
  ? createSubagentExtension(subagents, { cwd: options.cwd, model, authStorage, modelRegistry })
110
110
  : undefined;
111
111
 
112
+ // --- Dynamic hook extension ---
113
+
114
+ const hooksDir = resolvePath(options.cwd, ".local/hooks");
115
+
116
+ function createDynamicHookExtension(session: PiSession): ExtensionFactory {
117
+ return (pi) => {
118
+ pi.on("before_agent_start", async () => {
119
+ try {
120
+ const result = await runHooks(hooksDir, "pre-prompt", {
121
+ event: "pre-prompt",
122
+ session: session.name,
123
+ });
124
+ if (result.additionalContext) {
125
+ emit(session, {
126
+ type: "context",
127
+ content: result.additionalContext,
128
+ metadata: { source: "dynamic:pre-prompt", ...result.metadata },
129
+ });
130
+ return {
131
+ message: {
132
+ customType: "dynamic-hook",
133
+ content: result.additionalContext,
134
+ display: true,
135
+ },
136
+ };
137
+ }
138
+ } catch (err) {
139
+ log("mind", "dynamic pre-prompt hook failed:", err);
140
+ }
141
+ return {};
142
+ });
143
+
144
+ pi.on("tool_execution_end", async (event: any) => {
145
+ try {
146
+ const result = await runHooks(hooksDir, "post-tool-use", {
147
+ event: "post-tool-use",
148
+ tool_name: event.toolName,
149
+ tool_input: event.args,
150
+ });
151
+ if (result.additionalContext) {
152
+ emit(session, {
153
+ type: "context",
154
+ content: result.additionalContext,
155
+ metadata: { source: "dynamic:post-tool-use", ...result.metadata },
156
+ });
157
+ }
158
+ } catch (err) {
159
+ log("mind", "dynamic post-tool-use hook failed:", err);
160
+ }
161
+ });
162
+ };
163
+ }
164
+
112
165
  // --- Session lifecycle ---
113
166
 
114
167
  function getOrCreateSession(name: string): PiSession {
@@ -189,12 +242,13 @@ export function createMind(options: {
189
242
  retry: { enabled: true, maxRetries: 3 },
190
243
  });
191
244
 
192
- const sessionContextExtension = createSessionContextExtension({
193
- currentSession: session.name,
194
- mindDir: options.mindDir,
195
- });
245
+ const replyInstructionsExtension = createReplyInstructionsExtension(
246
+ session.messageChannels,
247
+ emit,
248
+ session,
249
+ );
196
250
 
197
- const replyInstructionsExtension = createReplyInstructionsExtension(session.messageChannels);
251
+ const dynamicHookExtension = createDynamicHookExtension(session);
198
252
 
199
253
  const resourceLoader = new DefaultResourceLoader({
200
254
  cwd: options.cwd,
@@ -202,9 +256,9 @@ export function createMind(options: {
202
256
  systemPrompt: options.systemPrompt,
203
257
  extensionFactories: [
204
258
  preCompactExtension,
205
- sessionContextExtension,
206
259
  replyInstructionsExtension,
207
260
  ...(subagentExtension ? [subagentExtension] : []),
261
+ dynamicHookExtension,
208
262
  ],
209
263
  });
210
264
  await resourceLoader.reload();
@@ -21,7 +21,7 @@ export type EventHandlerOptions = {
21
21
  // Loaded once at startup — mind restarts on config changes
22
22
  const preset = loadTransparencyPreset();
23
23
 
24
- function emit(
24
+ export function emit(
25
25
  session: EventSession,
26
26
  event: { type: EventType; content?: string; metadata?: Record<string, unknown> },
27
27
  ) {
@@ -1,27 +1,48 @@
1
1
  import type { ExtensionFactory } from "@mariozechner/pi-coding-agent";
2
+ import type { EventSession } from "./event-handler.js";
3
+ import { log } from "./logger.js";
2
4
  import { loadPrompts } from "./startup.js";
3
5
 
4
6
  export function createReplyInstructionsExtension(
5
7
  messageChannels: Map<string, string>,
8
+ emitContext?: (
9
+ session: EventSession,
10
+ event: { type: "context"; content: string; metadata: Record<string, unknown> },
11
+ ) => void,
12
+ session?: EventSession,
6
13
  ): ExtensionFactory {
7
14
  const prompts = loadPrompts();
8
15
  return (pi) => {
9
16
  let fired = false;
10
17
  pi.on("before_agent_start", () => {
11
- if (fired) return {};
18
+ try {
19
+ if (fired) return {};
12
20
 
13
- const channel = messageChannels.values().next().value;
14
- if (!channel) return {};
21
+ const channel = messageChannels.values().next().value;
22
+ if (!channel) return {};
15
23
 
16
- fired = true;
24
+ fired = true;
17
25
 
18
- return {
19
- message: {
20
- customType: "reply-instructions",
21
- content: prompts.reply_instructions.replace(/\$\{channel\}/g, channel),
22
- display: true,
23
- },
24
- };
26
+ const content = prompts.reply_instructions.replace(/\$\{channel\}/g, channel);
27
+ if (emitContext && session) {
28
+ emitContext(session, {
29
+ type: "context",
30
+ content,
31
+ metadata: { source: "reply-instructions" },
32
+ });
33
+ }
34
+
35
+ return {
36
+ message: {
37
+ customType: "reply-instructions",
38
+ content,
39
+ display: true,
40
+ },
41
+ };
42
+ } catch (err) {
43
+ log("mind", "reply instructions extension failed:", err);
44
+ return {};
45
+ }
25
46
  });
26
47
  };
27
48
  }
@@ -1,222 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- logger_default
4
- } from "./chunk-YUIHSKR6.js";
5
- import {
6
- mindDir,
7
- readRegistry,
8
- voluteHome
9
- } from "./chunk-X62AXPR7.js";
10
-
11
- // src/lib/pages-watcher.ts
12
- import { existsSync, readdirSync, statSync, watch } from "fs";
13
- import { join, resolve } from "path";
14
- var watchers = /* @__PURE__ */ new Map();
15
- var homeWatchers = /* @__PURE__ */ new Map();
16
- var debounceTimers = /* @__PURE__ */ new Map();
17
- var sitesCache = null;
18
- var recentPagesCache = null;
19
- function startPagesWatcher(mindName, pagesDir) {
20
- try {
21
- const watcher = watch(pagesDir, { recursive: true }, (_eventType, filename) => {
22
- if (!filename || !filename.endsWith(".html")) return;
23
- const key = `${mindName}:${filename}`;
24
- const existing = debounceTimers.get(key);
25
- if (existing) clearTimeout(existing);
26
- debounceTimers.set(
27
- key,
28
- setTimeout(() => {
29
- debounceTimers.delete(key);
30
- invalidateCache();
31
- }, 100)
32
- );
33
- });
34
- watchers.set(mindName, watcher);
35
- } catch (err) {
36
- logger_default.warn(`failed to start pages watcher for ${mindName}`, logger_default.errorData(err));
37
- }
38
- }
39
- function startSystemWatcher() {
40
- if (watchers.has("_system")) return;
41
- const systemPagesDir = resolve(voluteHome(), "shared", "pages");
42
- if (!existsSync(systemPagesDir)) return;
43
- startPagesWatcher("_system", systemPagesDir);
44
- }
45
- function startWatcher(mindName) {
46
- if (watchers.has(mindName)) return;
47
- const pagesDir = resolve(mindDir(mindName), "home", "public", "pages");
48
- if (existsSync(pagesDir)) {
49
- startPagesWatcher(mindName, pagesDir);
50
- return;
51
- }
52
- if (homeWatchers.has(mindName)) return;
53
- const publicDir = resolve(mindDir(mindName), "home", "public");
54
- if (!existsSync(publicDir)) return;
55
- try {
56
- const hw = watch(publicDir, (_eventType, filename) => {
57
- if (filename !== "pages") return;
58
- if (!existsSync(pagesDir)) return;
59
- hw.close();
60
- homeWatchers.delete(mindName);
61
- invalidateCache();
62
- startPagesWatcher(mindName, pagesDir);
63
- });
64
- homeWatchers.set(mindName, hw);
65
- } catch (err) {
66
- logger_default.warn(`failed to start home watcher for ${mindName}`, logger_default.errorData(err));
67
- }
68
- }
69
- function stopWatcher(mindName) {
70
- const watcher = watchers.get(mindName);
71
- if (watcher) {
72
- watcher.close();
73
- watchers.delete(mindName);
74
- }
75
- const hw = homeWatchers.get(mindName);
76
- if (hw) {
77
- hw.close();
78
- homeWatchers.delete(mindName);
79
- }
80
- for (const [key, timer] of debounceTimers) {
81
- if (key.startsWith(`${mindName}:`)) {
82
- clearTimeout(timer);
83
- debounceTimers.delete(key);
84
- }
85
- }
86
- }
87
- function stopAllWatchers() {
88
- for (const [, watcher] of watchers) {
89
- watcher.close();
90
- }
91
- watchers.clear();
92
- for (const [, hw] of homeWatchers) {
93
- hw.close();
94
- }
95
- homeWatchers.clear();
96
- for (const [, timer] of debounceTimers) {
97
- clearTimeout(timer);
98
- }
99
- debounceTimers.clear();
100
- invalidateCache();
101
- }
102
- function invalidateCache() {
103
- sitesCache = null;
104
- recentPagesCache = null;
105
- }
106
- function scanPagesDir(dir, urlPrefix) {
107
- const pages = [];
108
- let items;
109
- try {
110
- items = readdirSync(dir);
111
- } catch {
112
- return pages;
113
- }
114
- for (const item of items) {
115
- if (item.startsWith(".")) continue;
116
- const fullPath = resolve(dir, item);
117
- try {
118
- const s = statSync(fullPath);
119
- if (s.isFile() && item.endsWith(".html")) {
120
- pages.push({
121
- file: item,
122
- modified: s.mtime.toISOString(),
123
- url: `${urlPrefix}/${item}`
124
- });
125
- } else if (s.isDirectory()) {
126
- const indexPath = resolve(fullPath, "index.html");
127
- if (existsSync(indexPath)) {
128
- const indexStat = statSync(indexPath);
129
- pages.push({
130
- file: join(item, "index.html"),
131
- modified: indexStat.mtime.toISOString(),
132
- url: `${urlPrefix}/${item}/`
133
- });
134
- }
135
- }
136
- } catch {
137
- }
138
- }
139
- pages.sort((a, b) => new Date(b.modified).getTime() - new Date(a.modified).getTime());
140
- return pages;
141
- }
142
- async function buildSites() {
143
- const sites = [];
144
- const systemPagesDir = resolve(voluteHome(), "shared", "pages");
145
- if (existsSync(systemPagesDir)) {
146
- const systemPages = scanPagesDir(systemPagesDir, "/pages/_system");
147
- if (systemPages.length > 0) {
148
- sites.push({ name: "_system", label: "System", pages: systemPages });
149
- }
150
- }
151
- const entries = await readRegistry();
152
- for (const entry of [...entries].sort((a, b) => a.name.localeCompare(b.name))) {
153
- const pagesDir = resolve(mindDir(entry.name), "home", "public", "pages");
154
- if (!existsSync(pagesDir)) continue;
155
- const mindPages = scanPagesDir(pagesDir, `/minds/${entry.name}/pages`);
156
- if (mindPages.length > 0) {
157
- sites.push({ name: entry.name, label: entry.name, pages: mindPages });
158
- }
159
- }
160
- return sites;
161
- }
162
- async function buildRecentPages() {
163
- const entries = await readRegistry();
164
- const pages = [];
165
- for (const entry of entries) {
166
- const pagesDir = resolve(mindDir(entry.name), "home", "public", "pages");
167
- if (!existsSync(pagesDir)) continue;
168
- let items;
169
- try {
170
- items = readdirSync(pagesDir);
171
- } catch {
172
- continue;
173
- }
174
- for (const item of items) {
175
- if (item.startsWith(".")) continue;
176
- const fullPath = resolve(pagesDir, item);
177
- try {
178
- const s = statSync(fullPath);
179
- if (s.isFile() && item.endsWith(".html")) {
180
- pages.push({
181
- mind: entry.name,
182
- file: item,
183
- modified: s.mtime.toISOString(),
184
- url: `/minds/${entry.name}/pages/${item}`
185
- });
186
- } else if (s.isDirectory()) {
187
- const indexPath = resolve(fullPath, "index.html");
188
- if (existsSync(indexPath)) {
189
- const indexStat = statSync(indexPath);
190
- pages.push({
191
- mind: entry.name,
192
- file: join(item, "index.html"),
193
- modified: indexStat.mtime.toISOString(),
194
- url: `/minds/${entry.name}/pages/${item}/`
195
- });
196
- }
197
- }
198
- } catch {
199
- }
200
- }
201
- }
202
- pages.sort((a, b) => new Date(b.modified).getTime() - new Date(a.modified).getTime());
203
- return pages.slice(0, 10);
204
- }
205
- async function getCachedSites() {
206
- if (!sitesCache) sitesCache = await buildSites();
207
- return sitesCache;
208
- }
209
- async function getCachedRecentPages() {
210
- if (!recentPagesCache) recentPagesCache = await buildRecentPages();
211
- return recentPagesCache;
212
- }
213
-
214
- export {
215
- startSystemWatcher,
216
- startWatcher,
217
- stopWatcher,
218
- stopAllWatchers,
219
- invalidateCache,
220
- getCachedSites,
221
- getCachedRecentPages
222
- };
@@ -1,13 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- run,
4
- stopDaemon
5
- } from "./chunk-BNC43CSY.js";
6
- import "./chunk-SNVPRRT7.js";
7
- import "./chunk-57OKQMP3.js";
8
- import "./chunk-X62AXPR7.js";
9
- import "./chunk-K3NQKI34.js";
10
- export {
11
- run,
12
- stopDaemon
13
- };
@@ -1,30 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- deliverMessage,
4
- recordInbound,
5
- resolveSleepAction,
6
- tagRecentInbound,
7
- tagUntaggedInbound
8
- } from "./chunk-BWKIHH7B.js";
9
- import "./chunk-FAHDKPEH.js";
10
- import "./chunk-DAXJKPHZ.js";
11
- import "./chunk-AAO77TZX.js";
12
- import "./chunk-NOWVQ7AL.js";
13
- import "./chunk-R5QJBZZG.js";
14
- import "./chunk-EKDWA7E4.js";
15
- import "./chunk-S2TZLSDH.js";
16
- import "./chunk-NV3TYNWX.js";
17
- import "./chunk-PNQCXLSV.js";
18
- import "./chunk-YUIHSKR6.js";
19
- import "./chunk-57OKQMP3.js";
20
- import "./chunk-6QIUN46C.js";
21
- import "./chunk-A6TUJJ3L.js";
22
- import "./chunk-X62AXPR7.js";
23
- import "./chunk-K3NQKI34.js";
24
- export {
25
- deliverMessage,
26
- recordInbound,
27
- resolveSleepAction,
28
- tagRecentInbound,
29
- tagUntaggedInbound
30
- };
@@ -1,26 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- MindManager,
4
- getMindManager,
5
- initMindManager
6
- } from "./chunk-BWKIHH7B.js";
7
- import "./chunk-FAHDKPEH.js";
8
- import "./chunk-DAXJKPHZ.js";
9
- import "./chunk-AAO77TZX.js";
10
- import "./chunk-NOWVQ7AL.js";
11
- import "./chunk-R5QJBZZG.js";
12
- import "./chunk-EKDWA7E4.js";
13
- import "./chunk-S2TZLSDH.js";
14
- import "./chunk-NV3TYNWX.js";
15
- import "./chunk-PNQCXLSV.js";
16
- import "./chunk-YUIHSKR6.js";
17
- import "./chunk-57OKQMP3.js";
18
- import "./chunk-6QIUN46C.js";
19
- import "./chunk-A6TUJJ3L.js";
20
- import "./chunk-X62AXPR7.js";
21
- import "./chunk-K3NQKI34.js";
22
- export {
23
- MindManager,
24
- getMindManager,
25
- initMindManager
26
- };
@@ -1,22 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- getCachedRecentPages,
4
- getCachedSites,
5
- invalidateCache,
6
- startSystemWatcher,
7
- startWatcher,
8
- stopAllWatchers,
9
- stopWatcher
10
- } from "./chunk-HR5JKIDG.js";
11
- import "./chunk-YUIHSKR6.js";
12
- import "./chunk-X62AXPR7.js";
13
- import "./chunk-K3NQKI34.js";
14
- export {
15
- getCachedRecentPages,
16
- getCachedSites,
17
- invalidateCache,
18
- startSystemWatcher,
19
- startWatcher,
20
- stopAllWatchers,
21
- stopWatcher
22
- };
@@ -1,49 +0,0 @@
1
- ---
2
- name: Sessions
3
- description: This skill should be used when checking activity in other sessions, reading session logs, understanding cross-session context, or investigating what happened in another session. Covers "session activity", "other sessions", "session reader", "session log", "cross-session", "what happened in discord", "check session".
4
- ---
5
-
6
- # Cross-Session Awareness
7
-
8
- You can have multiple concurrent sessions (main, discord, email, etc.), each with its own conversation history stored as a JSONL file.
9
-
10
- ## Automatic Updates
11
-
12
- When a message arrives, you automatically receive a brief summary of new activity in other sessions (if any). This appears as a `[Session Activity]` block showing what happened since your last check.
13
-
14
- ## Listing Sessions
15
-
16
- To see which sessions are active:
17
-
18
- ```sh
19
- ls ../.mind/sessions/ # claude template
20
- ls ../.mind/pi-sessions/ # pi template
21
- ```
22
-
23
- ## Reading a Session Log
24
-
25
- For a detailed view of what happened in another session, run the session reader script:
26
-
27
- ```sh
28
- npx tsx .config/scripts/session-reader.ts <session-name> [--lines N]
29
- ```
30
-
31
- - `session-name`: The session to inspect (e.g., `discord`, `main`, `email`)
32
- - `--lines N`: Number of recent entries to show (default: 50)
33
-
34
- ### Output Format
35
-
36
- The reader shows a chronological log with:
37
- - **User messages**: Full text of what was sent
38
- - **Assistant text**: Full text of your responses
39
- - **Tool uses**: `[ToolName primary-arg]` format (e.g., `[Edit home/MEMORY.md]`, `[Bash npm test]`)
40
- - **Timestamps** on each entry
41
-
42
- Thinking blocks, tool result content, and metadata entries are omitted for readability.
43
-
44
- ## When to Use This
45
-
46
- - When you receive a `[Session Activity]` summary and want more detail
47
- - When you want to understand what happened in another session before responding
48
- - When coordinating work across multiple sessions
49
- - When a user references something from a different channel
@@ -1,30 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- SleepManager,
4
- getSleepManager,
5
- getSleepManagerIfReady,
6
- initSleepManager,
7
- matchesGlob
8
- } from "./chunk-BWKIHH7B.js";
9
- import "./chunk-FAHDKPEH.js";
10
- import "./chunk-DAXJKPHZ.js";
11
- import "./chunk-AAO77TZX.js";
12
- import "./chunk-NOWVQ7AL.js";
13
- import "./chunk-R5QJBZZG.js";
14
- import "./chunk-EKDWA7E4.js";
15
- import "./chunk-S2TZLSDH.js";
16
- import "./chunk-NV3TYNWX.js";
17
- import "./chunk-PNQCXLSV.js";
18
- import "./chunk-YUIHSKR6.js";
19
- import "./chunk-57OKQMP3.js";
20
- import "./chunk-6QIUN46C.js";
21
- import "./chunk-A6TUJJ3L.js";
22
- import "./chunk-X62AXPR7.js";
23
- import "./chunk-K3NQKI34.js";
24
- export {
25
- SleepManager,
26
- getSleepManager,
27
- getSleepManagerIfReady,
28
- initSleepManager,
29
- matchesGlob
30
- };
@@ -1,30 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- ensureSystemDM,
4
- generateSystemReply,
5
- resetSystemDMCache,
6
- sendSystemMessage,
7
- sendSystemMessageDirect
8
- } from "./chunk-BWKIHH7B.js";
9
- import "./chunk-FAHDKPEH.js";
10
- import "./chunk-DAXJKPHZ.js";
11
- import "./chunk-AAO77TZX.js";
12
- import "./chunk-NOWVQ7AL.js";
13
- import "./chunk-R5QJBZZG.js";
14
- import "./chunk-EKDWA7E4.js";
15
- import "./chunk-S2TZLSDH.js";
16
- import "./chunk-NV3TYNWX.js";
17
- import "./chunk-PNQCXLSV.js";
18
- import "./chunk-YUIHSKR6.js";
19
- import "./chunk-57OKQMP3.js";
20
- import "./chunk-6QIUN46C.js";
21
- import "./chunk-A6TUJJ3L.js";
22
- import "./chunk-X62AXPR7.js";
23
- import "./chunk-K3NQKI34.js";
24
- export {
25
- ensureSystemDM,
26
- generateSystemReply,
27
- resetSystemDMCache,
28
- sendSystemMessage,
29
- sendSystemMessageDirect
30
- };
@@ -1,16 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- run
4
- } from "./chunk-HDKY4TWU.js";
5
- import "./chunk-SNVPRRT7.js";
6
- import "./chunk-57OKQMP3.js";
7
- import {
8
- readGlobalConfig
9
- } from "./chunk-6QIUN46C.js";
10
- import "./chunk-D424ZQGI.js";
11
- import "./chunk-X62AXPR7.js";
12
- import "./chunk-K3NQKI34.js";
13
- export {
14
- readGlobalConfig,
15
- run
16
- };