volute 0.52.0 → 0.54.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 (153) hide show
  1. package/dist/{accept-5NK5XJB5.js → accept-RSDIVJL6.js} +3 -0
  2. package/dist/auto-upgrade-HEVZKPTF.js +46 -0
  3. package/dist/{backup-YVGV2ZNM.js → backup-QRNX6RK7.js} +10 -10
  4. package/dist/channels-CKCY64TD.js +203 -0
  5. package/dist/{chat-VAZ25KVT.js → chat-ZUGNL5GS.js} +5 -5
  6. package/dist/chunk-3LHUXY3E.js +102 -0
  7. package/dist/{chunk-SW2U6HRB.js → chunk-444RR3YF.js} +21 -4
  8. package/dist/{chunk-YVR6EHWL.js → chunk-56IT2ZXF.js} +160 -18
  9. package/dist/chunk-5RBEEAKW.js +58 -0
  10. package/dist/{chunk-OXWUEU5V.js → chunk-5U5GLZSD.js} +2 -2
  11. package/dist/{chunk-G7A5LEVI.js → chunk-7XKPG66D.js} +5 -5
  12. package/dist/{chunk-R772ET2M.js → chunk-AAPNU7GA.js} +4 -0
  13. package/dist/{chunk-XRWUQPCA.js → chunk-ATZF2RNJ.js} +25 -3
  14. package/dist/{chunk-6NLW72HP.js → chunk-CKPAVQNK.js} +1 -1
  15. package/dist/{chunk-JHKBALS2.js → chunk-CLCHOXLR.js} +1 -1
  16. package/dist/{chunk-DMK5ASKV.js → chunk-F6D766VQ.js} +6 -2
  17. package/dist/{chunk-AXFLY5GU.js → chunk-HKGYZVWN.js} +16 -1
  18. package/dist/{chunk-ZEZQNP2G.js → chunk-LGXVGIWN.js} +103 -25
  19. package/dist/{chunk-CW7BQKF6.js → chunk-LKUGUQUW.js} +3 -3
  20. package/dist/{chunk-FXWBFDQR.js → chunk-OAYY3WF3.js} +59 -12
  21. package/dist/{chunk-ITK6HV47.js → chunk-OGPVJ53N.js} +14 -6
  22. package/dist/{chunk-M77B73VV.js → chunk-OIOW3FPT.js} +7 -2
  23. package/dist/chunk-OT5SXF7L.js +904 -0
  24. package/dist/{chunk-EDR47UE2.js → chunk-OYF25B62.js} +1 -1
  25. package/dist/{chunk-RPPTGPYF.js → chunk-PPSN2MLC.js} +2 -2
  26. package/dist/{chunk-K2F237KS.js → chunk-RGHF3OK5.js} +154 -18
  27. package/dist/{chunk-RU74YG46.js → chunk-VDUCLVZI.js} +338 -30
  28. package/dist/{chunk-724DVYHU.js → chunk-WHL6PKYP.js} +10 -10
  29. package/dist/{chunk-EEOMA4DX.js → chunk-WZZCA23D.js} +2 -1
  30. package/dist/{chunk-UDZLPR34.js → chunk-YSRYCS3N.js} +13 -8
  31. package/dist/{chunk-5N32EN4O.js → chunk-Z4Q6TQWL.js} +1 -1
  32. package/dist/{chunk-VPOMJMV6.js → chunk-ZNHL5KQJ.js} +1 -1
  33. package/dist/cli.js +17 -17
  34. package/dist/{clock-ZT5YT6HA.js → clock-X7V3C7NL.js} +2 -2
  35. package/dist/{cloud-sync-H7EWZASD.js → cloud-sync-52YNJRMR.js} +12 -11
  36. package/dist/{daemon-restart-4FWUA5JF.js → daemon-restart-QWHN5VMU.js} +4 -4
  37. package/dist/daemon.js +538 -782
  38. package/dist/{db-IPXRJUI7.js → db-I4EH5SLF.js} +3 -1
  39. package/dist/{delivery-manager-VYXVKUMP.js → delivery-manager-7R2YIQ2W.js} +13 -7
  40. package/dist/delivery-notices-RZQ6GONP.js +18 -0
  41. package/dist/{delivery-router-RHANNTAC.js → delivery-router-QS4NLJR6.js} +3 -1
  42. package/dist/{down-QSNEMTTX.js → down-UN2EDX2Y.js} +3 -3
  43. package/dist/{echo-text-PEEV7FQU.js → echo-text-73CYQRL7.js} +14 -13
  44. package/dist/{exec-ABD3DYA2.js → exec-Z34TTUO3.js} +1 -1
  45. package/dist/{extensions-N6L5NYTK.js → extensions-QT65JGV6.js} +22 -11
  46. package/dist/{files-BRY5RRIM.js → files-PCKBQHAY.js} +2 -1
  47. package/dist/{isolation-GVV2IBAU.js → isolation-UQPDO34R.js} +1 -1
  48. package/dist/{message-delivery-7URC52ME.js → message-delivery-TRKT4T2P.js} +16 -13
  49. package/dist/migrate-name-placeholder-C7NCNLWF.js +37 -0
  50. package/dist/{mind-NEXGT3KE.js → mind-CT6ANXK4.js} +11 -11
  51. package/dist/{mind-contacts-QYU4TPEA.js → mind-contacts-PEXCDRXA.js} +6 -6
  52. package/dist/{mind-history-OGNR4L7W.js → mind-history-RZMMCHMX.js} +83 -11
  53. package/dist/{mind-list-SYRA7CH5.js → mind-list-7KBLPLES.js} +1 -1
  54. package/dist/{mind-service-E26ZQXDS.js → mind-service-7EFIJ3ZA.js} +12 -11
  55. package/dist/{mind-sleep-LZAFBDZD.js → mind-sleep-24HV4RCA.js} +2 -2
  56. package/dist/{mind-status-Z2LQFA6F.js → mind-status-4YW4PHMO.js} +15 -0
  57. package/dist/{package-2W2XKSIP.js → package-F6S5NHY2.js} +4 -4
  58. package/dist/{prompts-NBO3HRK3.js → prompts-JECJIFPQ.js} +1 -1
  59. package/dist/{reject-TWB4QJHG.js → reject-4NFLXKRN.js} +6 -2
  60. package/dist/{scheduler-JTTWZDYU.js → scheduler-73Q4MQ7Y.js} +8 -6
  61. package/dist/{seed-64XEHRUP.js → seed-DRKAP3XV.js} +1 -1
  62. package/dist/{seed-cmd-UEL2QB3Q.js → seed-cmd-6IMTO3LG.js} +2 -2
  63. package/dist/{seed-create-4JRQDPGA.js → seed-create-VNLDYRFK.js} +1 -1
  64. package/dist/{seed-readiness-DYOVCYHN.js → seed-readiness-H5TTPAQH.js} +2 -2
  65. package/dist/{seed-sprout-NIDIOJXT.js → seed-sprout-PPGYGK4G.js} +5 -5
  66. package/dist/{send-2YKOZJJ5.js → send-UXUQKO4N.js} +37 -22
  67. package/dist/{service-XQPMZAGI.js → service-T4P5W6RS.js} +2 -2
  68. package/dist/{service-install-2EWD7KXD.js → service-install-R4SNYUVO.js} +3 -3
  69. package/dist/{setup-4IX6PCD3.js → setup-YUAQMDVZ.js} +4 -4
  70. package/dist/skills/dreaming/SKILL.md +2 -2
  71. package/dist/skills/dreaming/references/INSTALL.md +1 -1
  72. package/dist/skills/memory/SKILL.md +47 -43
  73. package/dist/skills/tending/SKILL.md +2 -0
  74. package/dist/skills/volute-mind/references/integrations.md +3 -2
  75. package/dist/skills/volute-mind/references/routing.md +18 -5
  76. package/dist/{skills-MPUALV3S.js → skills-GMQ5UIIW.js} +2 -2
  77. package/dist/{sleep-manager-OFP2GFXF.js → sleep-manager-KHI65FEX.js} +12 -11
  78. package/dist/{spirit-4ECYIVGE.js → spirit-Q5VGFWUI.js} +19 -3
  79. package/dist/{spirit-availability-Y54Y3675.js → spirit-availability-G5FMWKRH.js} +13 -12
  80. package/dist/{sprout-GJMZFRGZ.js → sprout-PMTRL7QN.js} +1 -1
  81. package/dist/{src-LCSOQY6Z.js → src-3FIW7DLH.js} +241 -87
  82. package/dist/src-H3UCOP6B.js +516 -0
  83. package/dist/{src-HGNE2XG4.js → src-LTTQVN2Z.js} +1 -1
  84. package/dist/{status-MWLE3RVC.js → status-LCKTTIWS.js} +2 -2
  85. package/dist/{system-events-V43HDA3T.js → system-events-Q7IVZ5T4.js} +5 -1
  86. package/dist/{systems-VDRUZXNF.js → systems-HL7SGSW7.js} +2 -2
  87. package/dist/{turn-tracker-C5PVIC3B.js → turn-tracker-HZDPMSCC.js} +4 -2
  88. package/dist/{up-H6LJZDRK.js → up-XZDSJVMU.js} +3 -3
  89. package/dist/{update-CIWI2JYA.js → update-ILCPVNDD.js} +2 -2
  90. package/dist/{upgrade-LIE46UBB.js → upgrade-XY2J7NWZ.js} +9 -1
  91. package/dist/{variant-cleanup-STC6B5HR.js → variant-cleanup-QHGGY7ND.js} +8 -6
  92. package/dist/{version-notify-LBVHH5YV.js → version-notify-VNVFX6UP.js} +22 -7
  93. package/dist/web-assets/assets/{index-B_eYTa3R.js → index-CwtxGwe_.js} +16 -16
  94. package/dist/web-assets/assets/index-DhM1yYRN.css +1 -0
  95. package/dist/web-assets/index.html +2 -2
  96. package/package.json +4 -4
  97. package/packages/extensions/intentions/dist/ui/assets/index-3FneLCKR.css +1 -0
  98. package/packages/extensions/intentions/dist/ui/assets/index-CQz4aceM.js +67 -0
  99. package/packages/extensions/{plan → intentions}/dist/ui/index.html +3 -3
  100. package/packages/extensions/intentions/skills/intention-review/SKILL.md +38 -0
  101. package/packages/extensions/intentions/skills/intentions/SKILL.md +49 -0
  102. package/packages/extensions/intentions/skills/intentions/scripts/intentions-hook.sh +45 -0
  103. package/packages/extensions/pages/skills/commons-gardening/SKILL.md +50 -0
  104. package/packages/extensions/pages/skills/pages/SKILL.md +18 -13
  105. package/templates/_base/.init/.config/prompts.json +3 -3
  106. package/templates/{pi → _base}/.init/.config/routes.json +1 -0
  107. package/templates/_base/.init/memory/dreams/.gitkeep +0 -0
  108. package/templates/_base/home/.config/routes.json +1 -1
  109. package/templates/_base/home/VOLUTE.md +1 -1
  110. package/templates/_base/src/lib/codex-session-seed.ts +463 -0
  111. package/templates/_base/src/lib/context-breakdown.ts +11 -3
  112. package/templates/_base/src/lib/daemon-client.ts +35 -0
  113. package/templates/_base/src/lib/pi-session-seed.ts +434 -0
  114. package/templates/_base/src/lib/routing.ts +2 -2
  115. package/templates/_base/src/lib/seed-note.ts +78 -0
  116. package/templates/_base/src/lib/session-seed.ts +375 -0
  117. package/templates/_base/src/lib/startup.ts +112 -6
  118. package/templates/claude/.init/CLAUDE.md +7 -3
  119. package/templates/claude/src/agent.ts +295 -101
  120. package/templates/claude/src/lib/hooks/pre-compact.ts +30 -5
  121. package/templates/claude/src/lib/message-channel.ts +43 -15
  122. package/templates/claude/src/lib/recover.ts +69 -0
  123. package/templates/claude/src/lib/stream-consumer.ts +33 -2
  124. package/templates/claude/src/server.ts +2 -1
  125. package/templates/claude/volute-template.json +1 -1
  126. package/templates/codex/.init/AGENTS.md +7 -3
  127. package/templates/codex/src/agent.ts +256 -39
  128. package/templates/codex/src/server.ts +2 -1
  129. package/templates/codex/volute-template.json +1 -1
  130. package/templates/pi/.init/MINDS.md +7 -3
  131. package/templates/pi/src/agent.ts +269 -43
  132. package/templates/pi/src/lib/event-handler.ts +11 -0
  133. package/templates/pi/src/lib/mechanics-doc.ts +30 -0
  134. package/templates/pi/src/server.ts +5 -1
  135. package/templates/pi/volute-template.json +1 -1
  136. package/dist/channels-FSAHOQWI.js +0 -90
  137. package/dist/skills/plan-coordinator/SKILL.md +0 -60
  138. package/dist/src-UDMJZ6MH.js +0 -426
  139. package/dist/web-assets/assets/index-DhZrzddW.css +0 -1
  140. package/packages/extensions/plan/dist/ui/assets/index-B8s8wxyt.js +0 -67
  141. package/packages/extensions/plan/dist/ui/assets/index-jIkrt-vI.css +0 -1
  142. package/packages/extensions/plan/skills/plan/SKILL.md +0 -43
  143. package/packages/extensions/plan/skills/plan/scripts/plan-hook.sh +0 -37
  144. package/templates/claude/.init/.config/routes.json +0 -11
  145. package/templates/codex/.init/.config/routes.json +0 -11
  146. package/dist/{env-IBW2QI6K.js → env-7AZFBPWX.js} +5 -5
  147. package/dist/{login-RJJTCVR3.js → login-4NUS72Z5.js} +3 -3
  148. package/dist/{login-SB5OENMV.js → login-57MMYILL.js} +4 -4
  149. package/dist/{register-OX4HRSGC.js → register-WNCSOTAU.js} +3 -3
  150. package/dist/{restart-AGEGNSYQ.js → restart-B4GNMVF2.js} +4 -4
  151. package/dist/{skill-B5OJEQUA.js → skill-QYTBUDNQ.js} +4 -4
  152. package/dist/{start-MUMNFR52.js → start-BDHJVOVX.js} +3 -3
  153. package/dist/{stop-EKERNYTX.js → stop-45QYSGYS.js} +4 -4
@@ -35,6 +35,9 @@ var cmd = command({
35
35
  }
36
36
  const data = await res.json();
37
37
  console.log(`File accepted: ${data.destPath}`);
38
+ if (data.notified === false) {
39
+ console.log("Note: the sender could not be notified \u2014 mention it to them directly.");
40
+ }
38
41
  }
39
42
  });
40
43
  var run = cmd.execute;
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ autoUpgradeOne,
4
+ getUpgradeBlocked,
5
+ pruneBlocked,
6
+ runAutoUpgrades,
7
+ selectEligible
8
+ } from "./chunk-OT5SXF7L.js";
9
+ import "./chunk-CV6BNGFK.js";
10
+ import "./chunk-HTRSSOHY.js";
11
+ import "./chunk-OGPVJ53N.js";
12
+ import "./chunk-LGXVGIWN.js";
13
+ import "./chunk-RGHF3OK5.js";
14
+ import "./chunk-X67BDDZR.js";
15
+ import "./chunk-444RR3YF.js";
16
+ import "./chunk-VDUCLVZI.js";
17
+ import "./chunk-WHL6PKYP.js";
18
+ import "./chunk-YSRYCS3N.js";
19
+ import "./chunk-56IT2ZXF.js";
20
+ import "./chunk-PPSN2MLC.js";
21
+ import "./chunk-7LT3YZUR.js";
22
+ import "./chunk-HKGYZVWN.js";
23
+ import "./chunk-LNNI3MS4.js";
24
+ import "./chunk-OAYY3WF3.js";
25
+ import "./chunk-5Y54AE3L.js";
26
+ import "./chunk-TPX6E6PL.js";
27
+ import "./chunk-UFTDRTCP.js";
28
+ import "./chunk-U54PJPTB.js";
29
+ import "./chunk-ICXY54ZC.js";
30
+ import "./chunk-DW4TRDOZ.js";
31
+ import "./chunk-WCFSBH33.js";
32
+ import "./chunk-OIOW3FPT.js";
33
+ import "./chunk-GLM7TVWP.js";
34
+ import "./chunk-EGV6R6UF.js";
35
+ import "./chunk-QUSMYGNQ.js";
36
+ import "./chunk-LGNUFVMR.js";
37
+ import "./chunk-H6X6CKDN.js";
38
+ import "./chunk-2RNMBXD2.js";
39
+ import "./chunk-K3NQKI34.js";
40
+ export {
41
+ autoUpgradeOne,
42
+ getUpgradeBlocked,
43
+ pruneBlocked,
44
+ runAutoUpgrades,
45
+ selectEligible
46
+ };
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  stopDaemon
4
- } from "./chunk-5N32EN4O.js";
4
+ } from "./chunk-Z4Q6TQWL.js";
5
5
  import {
6
- promptLine,
7
- promptPassword
8
- } from "./chunk-VHWGEJ4V.js";
6
+ getClient,
7
+ urlOf
8
+ } from "./chunk-LOPXTW6H.js";
9
9
  import {
10
10
  daemonFetch
11
11
  } from "./chunk-M74I3HHF.js";
12
12
  import {
13
- getClient,
14
- urlOf
15
- } from "./chunk-LOPXTW6H.js";
13
+ promptLine,
14
+ promptPassword
15
+ } from "./chunk-VHWGEJ4V.js";
16
16
  import {
17
17
  command,
18
18
  subcommands
@@ -23,18 +23,18 @@ import {
23
23
  RESTIC_INSTALL_HINT,
24
24
  resticVersion,
25
25
  restoreStagedDb
26
- } from "./chunk-EDR47UE2.js";
26
+ } from "./chunk-OYF25B62.js";
27
27
  import {
28
28
  getServiceMode,
29
29
  modeLabel,
30
30
  stopService
31
- } from "./chunk-6NLW72HP.js";
31
+ } from "./chunk-CKPAVQNK.js";
32
32
  import {
33
33
  chownMindDir,
34
34
  exec,
35
35
  execInherit,
36
36
  wrapForIsolation
37
- } from "./chunk-M77B73VV.js";
37
+ } from "./chunk-OIOW3FPT.js";
38
38
  import "./chunk-QUSMYGNQ.js";
39
39
  import {
40
40
  _resetConfigCache,
@@ -0,0 +1,203 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ resolveMindName
4
+ } from "./chunk-BTY4WNFE.js";
5
+ import {
6
+ daemonFetch
7
+ } from "./chunk-M74I3HHF.js";
8
+ import {
9
+ command,
10
+ subcommands
11
+ } from "./chunk-TXSA4Q3V.js";
12
+ import "./chunk-O7IGP7ZW.js";
13
+ import "./chunk-FNJCBRD3.js";
14
+ import {
15
+ formatSuggestions
16
+ } from "./chunk-VDUCLVZI.js";
17
+ import "./chunk-WHL6PKYP.js";
18
+ import "./chunk-YSRYCS3N.js";
19
+ import "./chunk-56IT2ZXF.js";
20
+ import "./chunk-7LT3YZUR.js";
21
+ import "./chunk-HKGYZVWN.js";
22
+ import "./chunk-LNNI3MS4.js";
23
+ import "./chunk-OAYY3WF3.js";
24
+ import "./chunk-5Y54AE3L.js";
25
+ import "./chunk-TPX6E6PL.js";
26
+ import "./chunk-UFTDRTCP.js";
27
+ import "./chunk-U54PJPTB.js";
28
+ import "./chunk-ICXY54ZC.js";
29
+ import "./chunk-DW4TRDOZ.js";
30
+ import "./chunk-WCFSBH33.js";
31
+ import "./chunk-OIOW3FPT.js";
32
+ import "./chunk-GLM7TVWP.js";
33
+ import "./chunk-EGV6R6UF.js";
34
+ import "./chunk-QUSMYGNQ.js";
35
+ import "./chunk-LGNUFVMR.js";
36
+ import "./chunk-H6X6CKDN.js";
37
+ import "./chunk-2RNMBXD2.js";
38
+ import "./chunk-K3NQKI34.js";
39
+
40
+ // packages/cli/src/commands/chat/channels.ts
41
+ var channelsListCmd = command({
42
+ name: "volute chat channels",
43
+ description: "List unrouted (gated) channels holding messages",
44
+ args: [],
45
+ flags: {
46
+ mind: { type: "string", description: "Mind name" }
47
+ },
48
+ run: async ({ flags }) => {
49
+ const mind = resolveMindName(flags);
50
+ const res = await daemonFetch(`/api/minds/${encodeURIComponent(mind)}/delivery/pending`);
51
+ if (!res.ok) {
52
+ const data = await res.json().catch(() => ({}));
53
+ console.error(data.error ?? `Failed to list gated channels: ${res.status}`);
54
+ process.exit(1);
55
+ }
56
+ const pending = await res.json();
57
+ if (pending.length === 0) {
58
+ console.log("No unrouted channels holding messages.");
59
+ return;
60
+ }
61
+ const chW = Math.max(7, ...pending.map((p) => (p.channel ?? "unknown").length));
62
+ console.log(`${"CHANNEL".padEnd(chW)} HELD SINCE`);
63
+ for (const p of pending) {
64
+ console.log(
65
+ `${(p.channel ?? "unknown").padEnd(chW)} ${String(p.count).padStart(4)} ${p.firstSeen}`
66
+ );
67
+ }
68
+ console.log(
69
+ `
70
+ Quote the channel \u2014 an unquoted #name is a comment to the shell.
71
+ volute chat channels peek "<channel>" read what's held
72
+ volute chat channels accept "<channel>" start hearing it
73
+ volute chat channels decline "<channel>" opt out`
74
+ );
75
+ }
76
+ });
77
+ var channelsDeclineCmd = command({
78
+ name: "volute chat channels decline",
79
+ description: "Decline an unrouted channel: stop invites and archive its held backlog",
80
+ args: [{ name: "channel", required: true, description: 'Channel to decline (e.g. "#bardo")' }],
81
+ flags: {
82
+ mind: { type: "string", description: "Mind name" }
83
+ },
84
+ run: async ({ args, flags }) => {
85
+ const mind = resolveMindName(flags);
86
+ const channel = args.channel;
87
+ const res = await daemonFetch(`/api/minds/${encodeURIComponent(mind)}/gates/decline`, {
88
+ method: "POST",
89
+ headers: { "Content-Type": "application/json" },
90
+ body: JSON.stringify({ channel })
91
+ });
92
+ if (!res.ok) {
93
+ const data2 = await res.json().catch(() => ({}));
94
+ console.error(data2.error ?? `Failed to decline channel: ${res.status}`);
95
+ process.exit(1);
96
+ }
97
+ const data = await res.json();
98
+ console.log(`Declined ${channel}; archived ${data.archived} held message(s).`);
99
+ }
100
+ });
101
+ var channelsAcceptCmd = command({
102
+ name: "volute chat channels accept",
103
+ description: "Accept an unrouted channel: add a routing rule and deliver its held backlog",
104
+ args: [{ name: "channel", required: true, description: 'Channel to accept (e.g. "#bardo")' }],
105
+ flags: {
106
+ mind: { type: "string", description: "Mind name" },
107
+ thread: { type: "string", description: "Thread to route it to (default: one per channel)" }
108
+ },
109
+ run: async ({ args, flags }) => {
110
+ const mind = resolveMindName(flags);
111
+ const channel = args.channel;
112
+ const res = await daemonFetch(`/api/minds/${encodeURIComponent(mind)}/gates/accept`, {
113
+ method: "POST",
114
+ headers: { "Content-Type": "application/json" },
115
+ body: JSON.stringify({ channel, thread: flags.thread })
116
+ });
117
+ if (!res.ok) {
118
+ const data2 = await res.json().catch(() => ({}));
119
+ console.error(data2.error ?? `Failed to accept channel: ${res.status}`);
120
+ process.exit(1);
121
+ }
122
+ const data = await res.json();
123
+ const note = data.ruleAdded ? "" : " (rule already existed)";
124
+ console.log(
125
+ `Accepted ${channel} \u2192 thread ${data.thread}${note}; released ${data.released} held message(s).`
126
+ );
127
+ if (!data.known) {
128
+ console.log(
129
+ `Note: no channel named ${channel} is known here and nothing was held for it. The rule will route future messages if the name is right \u2014 check it against 'volute chat channels list'.`
130
+ );
131
+ }
132
+ if (data.archived > 0) {
133
+ console.log(
134
+ `${data.archived} older message(s) were not delivered \u2014 read them with 'volute chat channels peek "${channel}"'.`
135
+ );
136
+ }
137
+ }
138
+ });
139
+ var channelsPeekCmd = command({
140
+ name: "volute chat channels peek",
141
+ description: "Read the messages held on an unrouted channel without accepting it",
142
+ args: [{ name: "channel", required: true, description: 'Channel to peek at (e.g. "#bardo")' }],
143
+ flags: {
144
+ mind: { type: "string", description: "Mind name" }
145
+ },
146
+ run: async ({ args, flags }) => {
147
+ const mind = resolveMindName(flags);
148
+ const channel = args.channel;
149
+ const res = await daemonFetch(
150
+ `/api/minds/${encodeURIComponent(mind)}/gates/peek?channel=${encodeURIComponent(channel)}`
151
+ );
152
+ if (!res.ok) {
153
+ const data2 = await res.json().catch(() => ({}));
154
+ console.error(data2.error ?? `Failed to read held messages: ${res.status}`);
155
+ process.exit(1);
156
+ }
157
+ const data = await res.json();
158
+ if (data.count === 0) {
159
+ console.log(`No held messages on ${channel}.`);
160
+ if (data.suggestions?.length) {
161
+ console.log(
162
+ `No channel by that name exists \u2014 did you mean ${formatSuggestions(data.suggestions)}?`
163
+ );
164
+ }
165
+ return;
166
+ }
167
+ if (data.shown < data.count) {
168
+ console.log(`Showing the ${data.shown} most recent of ${data.count} held message(s).
169
+ `);
170
+ }
171
+ for (const m of data.messages) {
172
+ const mark = m.status === "archived" ? " (archived)" : "";
173
+ console.log(`[${m.createdAt}] ${m.sender ?? "unknown"}${mark}: ${m.content}`);
174
+ }
175
+ }
176
+ });
177
+ var cmd = subcommands({
178
+ name: "volute chat channels",
179
+ description: "Manage unrouted (gated) channels",
180
+ commands: {
181
+ list: {
182
+ description: "List unrouted channels holding messages",
183
+ run: channelsListCmd.execute
184
+ },
185
+ peek: {
186
+ description: "Read messages held on an unrouted channel",
187
+ run: channelsPeekCmd.execute
188
+ },
189
+ accept: {
190
+ description: "Accept an unrouted channel and deliver its held backlog",
191
+ run: channelsAcceptCmd.execute
192
+ },
193
+ decline: {
194
+ description: "Decline an unrouted channel",
195
+ run: channelsDeclineCmd.execute
196
+ }
197
+ },
198
+ footer: "Use --mind <name> or VOLUTE_MIND to identify the mind."
199
+ });
200
+ var run = cmd.execute;
201
+ export {
202
+ run
203
+ };
@@ -12,7 +12,7 @@ var cmd = subcommands({
12
12
  commands: {
13
13
  send: {
14
14
  description: "Send a message",
15
- run: (args) => import("./send-2YKOZJJ5.js").then((m) => m.run(args))
15
+ run: (args) => import("./send-UXUQKO4N.js").then((m) => m.run(args))
16
16
  },
17
17
  list: {
18
18
  description: "List conversations",
@@ -32,19 +32,19 @@ var cmd = subcommands({
32
32
  },
33
33
  channels: {
34
34
  description: "Manage unrouted (gated) channels",
35
- run: (args) => import("./channels-FSAHOQWI.js").then((m) => m.run(args))
35
+ run: (args) => import("./channels-CKCY64TD.js").then((m) => m.run(args))
36
36
  },
37
37
  files: {
38
38
  description: "List pending incoming files",
39
- run: (args) => import("./files-BRY5RRIM.js").then((m) => m.run(args))
39
+ run: (args) => import("./files-PCKBQHAY.js").then((m) => m.run(args))
40
40
  },
41
41
  accept: {
42
42
  description: "Accept a pending file",
43
- run: (args) => import("./accept-5NK5XJB5.js").then((m) => m.run(args))
43
+ run: (args) => import("./accept-RSDIVJL6.js").then((m) => m.run(args))
44
44
  },
45
45
  reject: {
46
46
  description: "Reject a pending file",
47
- run: (args) => import("./reject-TWB4QJHG.js").then((m) => m.run(args))
47
+ run: (args) => import("./reject-4NFLXKRN.js").then((m) => m.run(args))
48
48
  }
49
49
  },
50
50
  footer: "Use --mind <name> or VOLUTE_MIND to identify the mind."
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ MIND_LEVEL_THREAD,
4
+ localHM,
5
+ parseMeta,
6
+ recordNotice
7
+ } from "./chunk-HKGYZVWN.js";
8
+ import {
9
+ getPrompt
10
+ } from "./chunk-OAYY3WF3.js";
11
+ import {
12
+ logger_default
13
+ } from "./chunk-QUSMYGNQ.js";
14
+ import {
15
+ findMind,
16
+ getDb
17
+ } from "./chunk-H6X6CKDN.js";
18
+ import {
19
+ systemEvents
20
+ } from "./chunk-2RNMBXD2.js";
21
+
22
+ // packages/daemon/src/lib/chat/delivery-notices.ts
23
+ import { and, desc, eq, isNull, sql } from "drizzle-orm";
24
+ var nlog = logger_default.child("delivery-notices");
25
+ var COALESCE_WINDOW_MINUTES = 15;
26
+ var recordChains = /* @__PURE__ */ new Map();
27
+ async function recordDeliveryFailure(input) {
28
+ const key = `${input.mind}
29
+ ${input.channel}`;
30
+ const next = (recordChains.get(key) ?? Promise.resolve()).then(
31
+ () => recordDeliveryFailureUnserialized(input)
32
+ );
33
+ recordChains.set(key, next);
34
+ await next;
35
+ if (recordChains.get(key) === next) recordChains.delete(key);
36
+ }
37
+ async function recordDeliveryFailureUnserialized(input) {
38
+ const thread = input.thread ?? MIND_LEVEL_THREAD;
39
+ try {
40
+ const db = await getDb();
41
+ const existing = await db.select().from(systemEvents).where(
42
+ and(
43
+ eq(systemEvents.mind, input.mind),
44
+ eq(systemEvents.type, "notice"),
45
+ eq(systemEvents.delivery, "next-turn"),
46
+ eq(systemEvents.thread, thread),
47
+ isNull(systemEvents.delivered_at),
48
+ // Literal subtype + bound channel value — not string-built SQL.
49
+ sql`json_extract(${systemEvents.meta}, '$.subtype') = 'delivery_failed'`,
50
+ sql`json_extract(${systemEvents.meta}, '$.channel') = ${input.channel}`,
51
+ sql`${systemEvents.created_at} > datetime('now', ${`-${COALESCE_WINDOW_MINUTES} minutes`})`
52
+ )
53
+ ).orderBy(desc(systemEvents.id)).limit(1).get();
54
+ if (existing) {
55
+ const meta = parseMeta(existing.meta, `event ${existing.id}`);
56
+ const count = (typeof meta.count === "number" ? meta.count : 1) + 1;
57
+ const body2 = await getPrompt("delivery_failure_coalesced", {
58
+ count: String(count),
59
+ channel: input.channel,
60
+ since: localHM(existing.created_at),
61
+ reason: input.reason
62
+ });
63
+ await db.update(systemEvents).set({ body: body2, meta: JSON.stringify({ ...meta, count }) }).where(eq(systemEvents.id, existing.id));
64
+ return;
65
+ }
66
+ const body = await getPrompt("delivery_failure_notice", {
67
+ channel: input.channel,
68
+ reason: input.reason
69
+ });
70
+ await recordNotice({
71
+ mind: input.mind,
72
+ thread,
73
+ kind: "delivery_failed",
74
+ reason: "delivery_failed",
75
+ detail: body,
76
+ meta: { channel: input.channel, count: 1 }
77
+ });
78
+ } catch (err) {
79
+ nlog.warn(
80
+ `failed to record delivery-failure notice for ${input.mind} \u2192 ${input.channel}`,
81
+ logger_default.errorData(err)
82
+ );
83
+ }
84
+ }
85
+ async function recordSenderDeliveryFailure(sender, channel, reason) {
86
+ try {
87
+ const entry = await findMind(sender);
88
+ if (!entry) return;
89
+ await recordDeliveryFailure({ mind: entry.parent ?? entry.name, channel, reason });
90
+ } catch (err) {
91
+ nlog.warn(
92
+ `failed to record sender delivery-failure notice for ${sender} \u2192 ${channel}`,
93
+ logger_default.errorData(err)
94
+ );
95
+ }
96
+ }
97
+
98
+ export {
99
+ COALESCE_WINDOW_MINUTES,
100
+ recordDeliveryFailure,
101
+ recordSenderDeliveryFailure
102
+ };
@@ -6,10 +6,15 @@ import {
6
6
  getMindToken,
7
7
  loadJsonMap,
8
8
  saveJsonMapAsync
9
- } from "./chunk-724DVYHU.js";
9
+ } from "./chunk-WHL6PKYP.js";
10
10
  import {
11
- deliverEvent
12
- } from "./chunk-AXFLY5GU.js";
11
+ MIND_LEVEL_THREAD,
12
+ deliverEvent,
13
+ recordNotice
14
+ } from "./chunk-HKGYZVWN.js";
15
+ import {
16
+ getPrompt
17
+ } from "./chunk-OAYY3WF3.js";
13
18
  import {
14
19
  isSandboxEnabled,
15
20
  wrapForSandbox
@@ -20,7 +25,7 @@ import {
20
25
  } from "./chunk-WCFSBH33.js";
21
26
  import {
22
27
  exec
23
- } from "./chunk-M77B73VV.js";
28
+ } from "./chunk-OIOW3FPT.js";
24
29
  import {
25
30
  loadMergedEnv
26
31
  } from "./chunk-GLM7TVWP.js";
@@ -197,6 +202,18 @@ ${stderr}` : ""}`;
197
202
  }
198
203
  } catch (err) {
199
204
  slog.warn(`failed to fire "${schedule.id}" for ${mindName}`, logger_default.errorData(err));
205
+ const detail = await getPrompt("schedule_failure_notice", {
206
+ id: schedule.id,
207
+ reason: err instanceof Error && err.message ? err.message : String(err)
208
+ });
209
+ const thread = schedule.thread && !schedule.thread.startsWith("new-") ? schedule.thread : MIND_LEVEL_THREAD;
210
+ await recordNotice({
211
+ mind: mindName,
212
+ thread,
213
+ kind: "delivery_failed",
214
+ reason: "schedule_failed",
215
+ detail
216
+ });
200
217
  }
201
218
  }
202
219
  removeSchedule(mindName, scheduleId) {