volute 0.48.0 → 0.49.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 (137) hide show
  1. package/README.md +79 -328
  2. package/dist/{activity-events-MIOK3IOU.js → activity-events-GJJAI2WT.js} +4 -4
  3. package/dist/{ai-service-643TNFPH.js → ai-service-A7FS7EC3.js} +5 -5
  4. package/dist/{archive-6Z4GFQPH.js → archive-7E3YE6VF.js} +3 -3
  5. package/dist/{auth-A4VGHADI.js → auth-ABYLOEZ7.js} +5 -5
  6. package/dist/{avatar-image-Y45R7LW5.js → avatar-image-6ATV2IOZ.js} +4 -4
  7. package/dist/{backup-UDH4GMSW.js → backup-XYAMT4CU.js} +15 -15
  8. package/dist/{chat-X43VYHH2.js → chat-OGXAEXMV.js} +2 -2
  9. package/dist/{chunk-LTLFOSA4.js → chunk-3B427GUK.js} +3 -3
  10. package/dist/{chunk-XVBSFLM7.js → chunk-4B62E4CG.js} +2 -2
  11. package/dist/{chunk-ODDGGLM6.js → chunk-4DSGN4FL.js} +3 -3
  12. package/dist/{chunk-PJVPDY2Z.js → chunk-6HGEZJDH.js} +2 -2
  13. package/dist/{chunk-MJRXFUMS.js → chunk-DAIIMBLB.js} +3 -3
  14. package/dist/{chunk-DGGZVZTM.js → chunk-DVN6DNMI.js} +1 -1
  15. package/dist/chunk-EADX54RG.js +113 -0
  16. package/dist/{chunk-EIQDZC43.js → chunk-EFT2OALG.js} +6 -2
  17. package/dist/{chunk-OQJMTHEH.js → chunk-EG5LSKHU.js} +2 -2
  18. package/dist/{chunk-WQ46E33M.js → chunk-FBBS4BVR.js} +2 -2
  19. package/dist/{chunk-HUNDXZBZ.js → chunk-GWVFDUNB.js} +45 -14
  20. package/dist/{chunk-FJ2MZ5PH.js → chunk-HCYQRME2.js} +2 -2
  21. package/dist/{chunk-T4VS7UDW.js → chunk-IH5TKXX6.js} +9 -9
  22. package/dist/{chunk-Q7HOAVFR.js → chunk-JBIFXB6I.js} +4 -4
  23. package/dist/{chunk-WARH6GIV.js → chunk-JCBPU57A.js} +12 -10
  24. package/dist/{chunk-VZRA5TYO.js → chunk-JCWB2ITW.js} +2 -2
  25. package/dist/{chunk-MOERAQXH.js → chunk-JPGHSXSV.js} +18 -25
  26. package/dist/{chunk-USD45JKR.js → chunk-K3JOLGWF.js} +7 -7
  27. package/dist/{chunk-3YUBFTDN.js → chunk-KHCKZ36O.js} +1 -1
  28. package/dist/{chunk-7KRIHYLR.js → chunk-L27YYONJ.js} +2 -2
  29. package/dist/{chunk-SZJCJVXV.js → chunk-MG3Z34YE.js} +2 -2
  30. package/dist/{chunk-5KXCM5AW.js → chunk-NJHN6IRB.js} +9 -1
  31. package/dist/{chunk-2OIYNHWO.js → chunk-NOIAHMJB.js} +1 -1
  32. package/dist/{chunk-2MJ7EOMT.js → chunk-P4LHVRNE.js} +1 -0
  33. package/dist/{chunk-IJPMIEVE.js → chunk-PY24ZL62.js} +1 -1
  34. package/dist/{chunk-VB2QXUJQ.js → chunk-QQBOI3QA.js} +202 -117
  35. package/dist/{chunk-T2TP6ZC6.js → chunk-QUSMYGNQ.js} +6 -0
  36. package/dist/{chunk-WW6C3PLV.js → chunk-RSBL3FAD.js} +39 -6
  37. package/dist/{chunk-YKA7DCVW.js → chunk-SX72DOO3.js} +1 -1
  38. package/dist/{chunk-4FCL4DVZ.js → chunk-TXJL36ZQ.js} +2 -2
  39. package/dist/{chunk-HNGFKPNS.js → chunk-VIUH5CHQ.js} +55 -23
  40. package/dist/{chunk-HPGN6XRT.js → chunk-VNRSXEBF.js} +4 -4
  41. package/dist/{chunk-IYCV34IU.js → chunk-XTEKINWG.js} +3 -3
  42. package/dist/{chunk-YNBXEQAP.js → chunk-YIJGKHIS.js} +3 -3
  43. package/dist/{chunk-MTRMQFCQ.js → chunk-ZX46PGCC.js} +2 -2
  44. package/dist/cli.js +20 -20
  45. package/dist/{clock-CNRF6F7T.js → clock-6JZL2FS6.js} +2 -2
  46. package/dist/{cloud-sync-WHKCB4CD.js → cloud-sync-VFDTNNCA.js} +20 -20
  47. package/dist/{conversations-C7IKYSHD.js → conversations-TUM5PJJ4.js} +5 -5
  48. package/dist/{create-GJKHABJB.js → create-Z5FSDNVZ.js} +1 -1
  49. package/dist/{daemon-restart-7KUHVZIN.js → daemon-restart-54L4B6AQ.js} +7 -7
  50. package/dist/daemon.js +647 -410
  51. package/dist/{db-FO6LXYCW.js → db-F6UMFRYD.js} +2 -2
  52. package/dist/delivery-manager-RBXBPVWM.js +36 -0
  53. package/dist/{delivery-router-3QFG2ZEX.js → delivery-router-VUOL5YSA.js} +8 -6
  54. package/dist/{down-G6IADJXV.js → down-6X7KX7BZ.js} +5 -5
  55. package/dist/echo-text-B6NZ5FGE.js +36 -0
  56. package/dist/{env-6TGPO5WG.js → env-KUL4XKN2.js} +3 -3
  57. package/dist/{exec-QIFYZG4C.js → exec-FBXA3CM4.js} +3 -3
  58. package/dist/{export-C2K3NIRD.js → export-TNBPDH77.js} +3 -3
  59. package/dist/{extensions-GEKF47A4.js → extensions-AWNO3SZF.js} +20 -20
  60. package/dist/{files-LXQSQOFG.js → files-BVBRJJ2P.js} +3 -3
  61. package/dist/{import-SX3ZXHB4.js → import-ZUNKMCKC.js} +7 -7
  62. package/dist/{isolation-MCT4ZYLT.js → isolation-OPCZQRTH.js} +3 -3
  63. package/dist/{login-CL4IT2ED.js → login-KAKNFCW5.js} +6 -6
  64. package/dist/{logout-HZYJCYCA.js → logout-RLT62RQP.js} +2 -2
  65. package/dist/message-delivery-ABPV76EA.js +42 -0
  66. package/dist/{mind-46AOK373.js → mind-IF6CGMFW.js} +12 -12
  67. package/dist/{mind-activity-tracker-YVZPC4A5.js → mind-activity-tracker-YMMERB6B.js} +5 -5
  68. package/dist/mind-service-42GDO4KH.js +44 -0
  69. package/dist/{mind-sleep-DV7KP255.js → mind-sleep-VBV7YRSU.js} +2 -2
  70. package/dist/{notices-2KU5NTRY.js → notices-N6BCGHFV.js} +4 -4
  71. package/dist/{package-RTN2PS7O.js → package-PD67VPHB.js} +5 -4
  72. package/dist/prompts-MDHDLWEX.js +24 -0
  73. package/dist/{registry-UMMDRPRM.js → registry-3ELJPUGJ.js} +6 -2
  74. package/dist/{sandbox-5VQ454XP.js → sandbox-XPYA7UIF.js} +5 -5
  75. package/dist/scheduler-K7Y7Z7FQ.js +34 -0
  76. package/dist/{schema-VEVO7HG6.js → schema-6YONVTKZ.js} +1 -1
  77. package/dist/{seed-F2HXZQU4.js → seed-NQED7PSX.js} +1 -1
  78. package/dist/{seed-cmd-MLCTGSX5.js → seed-cmd-QF3F2G4S.js} +2 -2
  79. package/dist/{seed-create-KQ7OILWB.js → seed-create-XOO4N2OE.js} +3 -3
  80. package/dist/{seed-readiness-RBPGOLSZ.js → seed-readiness-3LRYASA4.js} +5 -5
  81. package/dist/{seed-sprout-HVYCFJLA.js → seed-sprout-HSBBGSS2.js} +11 -11
  82. package/dist/{send-TD2X5U3K.js → send-IHRJYNXA.js} +6 -6
  83. package/dist/{service-CVZMQYK6.js → service-YCOPCTSZ.js} +4 -4
  84. package/dist/{service-install-VCRMFWX5.js → service-install-Y46OTF55.js} +5 -5
  85. package/dist/{setup-AE4CVUC4.js → setup-F4TE64YI.js} +7 -7
  86. package/dist/{setup-5ECWTYKG.js → setup-TCN7VH5U.js} +5 -3
  87. package/dist/skills/volute-mind/SKILL.md +3 -3
  88. package/dist/skills/volute-mind/references/routing.md +6 -5
  89. package/dist/skills/volute-mind/references/variants.md +48 -14
  90. package/dist/{skills-B3SVDCEB.js → skills-NN5UZCUU.js} +8 -6
  91. package/dist/sleep-manager-DSPXFHGX.js +38 -0
  92. package/dist/spirit-SSJMYC6A.js +31 -0
  93. package/dist/{split-SKZ4Y2D6.js → split-JF2VWTXA.js} +4 -1
  94. package/dist/{sprout-KQ43BWZJ.js → sprout-AXA2SECQ.js} +1 -1
  95. package/dist/{status-F4PGREUU.js → status-VJGXMQ4L.js} +5 -5
  96. package/dist/system-chat-M2XOBKEM.js +40 -0
  97. package/dist/{systems-JJNGQHAO.js → systems-5MH2ELQE.js} +2 -2
  98. package/dist/{tailscale-MCLY5GYE.js → tailscale-AMMVKDXB.js} +3 -3
  99. package/dist/{template-staleness-EMQORSGG.js → template-staleness-HKGCTS3H.js} +4 -4
  100. package/dist/{turn-tracker-KLPV3PAU.js → turn-tracker-JQ2YUUY2.js} +7 -7
  101. package/dist/{up-RVGDE6CQ.js → up-SDLTLPAO.js} +6 -6
  102. package/dist/{update-OXQEGGXD.js → update-WEA4N2TR.js} +5 -5
  103. package/dist/{update-check-266R4ZSY.js → update-check-DZOTONII.js} +3 -3
  104. package/dist/variant-cleanup-P4MBNLJD.js +33 -0
  105. package/dist/{version-notify-73YURTFR.js → version-notify-WFA5XB5A.js} +23 -23
  106. package/dist/web-assets/assets/index-BostMFoR.css +1 -0
  107. package/dist/web-assets/assets/index-CKlqUkyG.js +92 -0
  108. package/dist/web-assets/index.html +2 -2
  109. package/drizzle/0013_variant_purpose.sql +3 -0
  110. package/drizzle/meta/_journal.json +7 -0
  111. package/package.json +5 -4
  112. package/templates/_base/.init/.local/hooks/startup-context.ts +19 -2
  113. package/templates/_base/home/VOLUTE.md +13 -1
  114. package/templates/_base/src/lib/daemon-client.ts +27 -7
  115. package/templates/claude/src/agent.ts +1 -1
  116. package/templates/claude/src/lib/hooks/identity-reload.ts +12 -3
  117. package/templates/pi/src/lib/event-handler.ts +47 -6
  118. package/dist/delivery-manager-HZTT5SJR.js +0 -36
  119. package/dist/echo-text-H3SH337Q.js +0 -36
  120. package/dist/message-delivery-GPQ5SE5N.js +0 -40
  121. package/dist/mind-service-2ARGJNKP.js +0 -44
  122. package/dist/scheduler-I7JZCT47.js +0 -34
  123. package/dist/sleep-manager-Z27R3WTW.js +0 -38
  124. package/dist/spirit-WXS3HCLN.js +0 -25
  125. package/dist/system-chat-63ABFF6V.js +0 -40
  126. package/dist/web-assets/assets/index-WdZ60R6c.css +0 -1
  127. package/dist/web-assets/assets/index-taX6Ezfa.js +0 -92
  128. package/dist/{env-C7Z55QCJ.js → env-ZYMSCB7B.js} +5 -5
  129. package/dist/{login-ARRZ4ORJ.js → login-LKNLCJPA.js} +3 -3
  130. package/dist/{mind-contacts-GV7XYL5D.js → mind-contacts-BKUFPUCU.js} +6 -6
  131. package/dist/{mind-history-TTGA5BHZ.js → mind-history-WI5OI3BW.js} +4 -4
  132. package/dist/{register-42VBJKTP.js → register-TWQDKQRT.js} +3 -3
  133. package/dist/{restart-YYEGZJDD.js → restart-5F5QDBOG.js} +4 -4
  134. package/dist/{skill-UUM4JZRF.js → skill-4CYJLYVY.js} +4 -4
  135. package/dist/{src-WLJE73NP.js → src-ZN4LXMPI.js} +3 -3
  136. package/dist/{start-O6UKK7BG.js → start-BTVMTP3K.js} +3 -3
  137. package/dist/{stop-UBX6X5RA.js → stop-YORESK4U.js} +4 -4
@@ -1,8 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
+ activity,
4
+ channelGates,
5
+ conversations,
6
+ deliveryQueue,
7
+ mindHistory,
8
+ mindNotices,
3
9
  minds,
4
- schema_exports
5
- } from "./chunk-2MJ7EOMT.js";
10
+ schema_exports,
11
+ summaries,
12
+ turns,
13
+ users
14
+ } from "./chunk-P4LHVRNE.js";
6
15
 
7
16
  // packages/daemon/src/lib/db.ts
8
17
  import { chmodSync, existsSync } from "fs";
@@ -17,7 +26,7 @@ import { mkdirSync } from "fs";
17
26
  import { homedir } from "os";
18
27
  import { resolve } from "path";
19
28
  import { fileURLToPath } from "url";
20
- import { and, eq, inArray, isNull } from "drizzle-orm";
29
+ import { and, eq, inArray, isNull, or } from "drizzle-orm";
21
30
  var SPIRIT_NAME = "volute";
22
31
  function isSpiritName(name) {
23
32
  return name === SPIRIT_NAME;
@@ -58,6 +67,7 @@ function rowToEntry(row) {
58
67
  parent: row.parent ?? void 0,
59
68
  dir: row.dir ?? void 0,
60
69
  branch: row.branch ?? void 0,
70
+ purpose: row.purpose ?? void 0,
61
71
  mindType: row.mind_type ?? "mind",
62
72
  createdBy: row.created_by ?? void 0
63
73
  };
@@ -67,6 +77,10 @@ async function readRegistry() {
67
77
  const rows = await db2.select().from(minds).where(and(isNull(minds.parent), inArray(minds.mind_type, ["mind", "spirit"])));
68
78
  return rows.map(rowToEntry);
69
79
  }
80
+ async function countCappedMinds() {
81
+ const entries = await readRegistry();
82
+ return entries.filter((e) => e.mindType !== "spirit").length;
83
+ }
70
84
  async function readAllMinds() {
71
85
  const db2 = await getDb();
72
86
  const rows = await db2.select().from(minds);
@@ -125,19 +139,36 @@ async function readSpirits() {
125
139
  const rows = await db2.select().from(minds).where(eq(minds.mind_type, "spirit"));
126
140
  return rows.map(rowToEntry);
127
141
  }
128
- async function addVariant(name, parent, port, dir, branch) {
142
+ async function addVariant(name, parent, port, dir, branch, purpose) {
129
143
  const err = validateMindName(name);
130
144
  if (err) throw new Error(err);
131
145
  const db2 = await getDb();
132
- await db2.insert(minds).values({ name, port, parent, dir, branch }).onConflictDoUpdate({
146
+ await db2.insert(minds).values({ name, port, parent, dir, branch, purpose: purpose ?? null }).onConflictDoUpdate({
133
147
  target: minds.name,
134
- set: { port, parent, dir, branch }
148
+ set: { port, parent, dir, branch, purpose: purpose ?? null }
135
149
  });
136
150
  }
137
151
  async function removeMind(name) {
138
152
  const db2 = await getDb();
139
153
  await db2.delete(minds).where(eq(minds.name, name));
140
154
  }
155
+ async function deleteMindDbFootprint(name) {
156
+ const db2 = await getDb();
157
+ await db2.transaction(async (tx) => {
158
+ const owner = await tx.select({ id: users.id }).from(users).where(and(eq(users.username, name), eq(users.user_type, "mind"))).get();
159
+ if (owner) {
160
+ await tx.delete(conversations).where(eq(conversations.user_id, owner.id));
161
+ }
162
+ await tx.delete(users).where(and(eq(users.username, name), eq(users.user_type, "mind")));
163
+ await tx.delete(activity).where(eq(activity.mind, name));
164
+ await tx.delete(deliveryQueue).where(or(eq(deliveryQueue.mind, name), eq(deliveryQueue.target_mind, name)));
165
+ await tx.delete(turns).where(eq(turns.mind, name));
166
+ await tx.delete(mindHistory).where(eq(mindHistory.mind, name));
167
+ await tx.delete(summaries).where(eq(summaries.mind, name));
168
+ await tx.delete(mindNotices).where(eq(mindNotices.mind, name));
169
+ await tx.delete(channelGates).where(eq(channelGates.mind, name));
170
+ });
171
+ }
141
172
  async function setMindRunning(name, running) {
142
173
  const db2 = await getDb();
143
174
  await db2.update(minds).set({ running: running ? 1 : 0 }).where(eq(minds.name, name));
@@ -257,6 +288,7 @@ export {
257
288
  ensureSystemDir,
258
289
  ensureVoluteHome,
259
290
  readRegistry,
291
+ countCappedMinds,
260
292
  readAllMinds,
261
293
  validateMindName,
262
294
  addMind,
@@ -264,6 +296,7 @@ export {
264
296
  readSpirits,
265
297
  addVariant,
266
298
  removeMind,
299
+ deleteMindDbFootprint,
267
300
  setMindRunning,
268
301
  setMindStage,
269
302
  setMindTemplateHash,
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  voluteSystemDir
4
- } from "./chunk-WW6C3PLV.js";
4
+ } from "./chunk-RSBL3FAD.js";
5
5
 
6
6
  // packages/daemon/src/lib/update-check.ts
7
7
  import { execFile as execFileCb, execFileSync } from "child_process";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  MEMORY_PLACEHOLDER_MARKER,
4
4
  ORIENTATION_MARKER
5
- } from "./chunk-MOERAQXH.js";
5
+ } from "./chunk-JPGHSXSV.js";
6
6
  import {
7
7
  safeResolveWithinBase
8
8
  } from "./chunk-DW4TRDOZ.js";
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-WCFSBH33.js";
12
12
  import {
13
13
  isImagegenEnabled
14
- } from "./chunk-5KXCM5AW.js";
14
+ } from "./chunk-NJHN6IRB.js";
15
15
 
16
16
  // packages/daemon/src/lib/mind/seed-readiness.ts
17
17
  import { existsSync, readFileSync } from "fs";
@@ -10,31 +10,31 @@ import {
10
10
  getSharedSkill,
11
11
  installSkill,
12
12
  mindSkillsDir
13
- } from "./chunk-HUNDXZBZ.js";
13
+ } from "./chunk-GWVFDUNB.js";
14
14
  import {
15
15
  readVoluteConfig,
16
16
  writeVoluteConfig
17
17
  } from "./chunk-WCFSBH33.js";
18
18
  import {
19
19
  exec
20
- } from "./chunk-DGGZVZTM.js";
20
+ } from "./chunk-DVN6DNMI.js";
21
21
  import {
22
22
  qualifyModelId,
23
23
  resolveTemplate,
24
24
  unqualifyModelId
25
- } from "./chunk-YNBXEQAP.js";
25
+ } from "./chunk-YIJGKHIS.js";
26
26
  import {
27
27
  readGlobalConfig
28
- } from "./chunk-5KXCM5AW.js";
28
+ } from "./chunk-NJHN6IRB.js";
29
29
  import {
30
30
  logger_default
31
- } from "./chunk-T2TP6ZC6.js";
31
+ } from "./chunk-QUSMYGNQ.js";
32
32
  import {
33
33
  addSpirit,
34
34
  findMind,
35
35
  nextPort,
36
36
  voluteSystemDir
37
- } from "./chunk-WW6C3PLV.js";
37
+ } from "./chunk-RSBL3FAD.js";
38
38
 
39
39
  // packages/daemon/src/lib/mind/spirit.ts
40
40
  import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
@@ -104,11 +104,8 @@ async function ensureSpiritProject() {
104
104
  copyTemplateToDir(composedDir, dir, "volute", manifest);
105
105
  applyInitFiles(dir);
106
106
  mkdirSync(resolve(dir, ".mind"), { recursive: true });
107
- const soulPath = resolve(dir, "home/SOUL.md");
108
- const globalConfig = readGlobalConfig();
109
- const systemName = globalConfig.name ?? "Volute";
110
- const soulContent = getSpiritSoul(systemName, globalConfig.description);
111
- writeFileSync(soulPath, soulContent);
107
+ writeFileSync(resolve(dir, "home/SOUL.md"), getSpiritSoul());
108
+ writeSpiritSystemJson(dir);
112
109
  const routesPath = resolve(dir, "home/.config/routes.json");
113
110
  mkdirSync(resolve(dir, "home/.config"), { recursive: true });
114
111
  const routesContent = { rules: [{ channel: "*", session: "${channel}" }], default: "main" };
@@ -145,7 +142,7 @@ async function ensureSpiritProject() {
145
142
  } catch (err) {
146
143
  slog.warn("failed to add tending schedule to spirit config", logger_default.errorData(err));
147
144
  }
148
- const { createMindUser, chownMindDir, ensureVoluteGroup } = await import("./isolation-MCT4ZYLT.js");
145
+ const { createMindUser, chownMindDir, ensureVoluteGroup } = await import("./isolation-OPCZQRTH.js");
149
146
  ensureVoluteGroup();
150
147
  createMindUser("volute", resolve(dir, "home"));
151
148
  await chownMindDir(dir, "volute");
@@ -158,9 +155,45 @@ async function ensureSpiritProject() {
158
155
  throw err;
159
156
  }
160
157
  }
158
+ function spiritSystemJsonPath(dir) {
159
+ return resolve(dir, "home/.config/system.json");
160
+ }
161
+ function writeSpiritSystemJson(dir) {
162
+ const config = readGlobalConfig();
163
+ const path = spiritSystemJsonPath(dir);
164
+ mkdirSync(resolve(path, ".."), { recursive: true });
165
+ const data = { name: config.name ?? "Volute", description: config.description };
166
+ writeFileSync(path, `${JSON.stringify(data, null, 2)}
167
+ `);
168
+ }
169
+ function seedSpiritSoulIfMissing(dir) {
170
+ const soulPath = resolve(dir, "home/SOUL.md");
171
+ if (existsSync(soulPath)) return false;
172
+ writeFileSync(soulPath, getSpiritSoul());
173
+ return true;
174
+ }
175
+ async function notifySpiritSystemChange() {
176
+ const entry = await findMind("volute");
177
+ if (entry?.mindType !== "spirit") return;
178
+ const dir = spiritDir();
179
+ if (!existsSync(dir)) return;
180
+ writeSpiritSystemJson(dir);
181
+ const config = readGlobalConfig();
182
+ const name = config.name ?? "Volute";
183
+ const desc = config.description ? ` \u2014 ${config.description}` : "";
184
+ try {
185
+ const { sendSystemMessage } = await import("./system-chat-M2XOBKEM.js");
186
+ await sendSystemMessage(
187
+ "volute",
188
+ `The operator updated this system's identity: you're now the spirit of ${name}${desc}. Your SOUL.md is yours \u2014 update it if you'd like it to reflect this.`
189
+ );
190
+ } catch (err) {
191
+ slog.warn("failed to notify spirit of system change", logger_default.errorData(err));
192
+ }
193
+ }
161
194
  async function syncSpiritTemplate() {
162
195
  const entry = await findMind("volute");
163
- if (!entry || entry.mindType !== "spirit") return;
196
+ if (entry?.mindType !== "spirit") return;
164
197
  const dir = spiritDir();
165
198
  if (!existsSync(dir)) return;
166
199
  const templatesRoot = findTemplatesRoot();
@@ -179,8 +212,8 @@ async function syncSpiritTemplate() {
179
212
  cpSync(newPkg, resolve(dir, "package.json"));
180
213
  await exec("npm", ["install"], { cwd: dir, env: npmEnv() });
181
214
  }
182
- const db = await (await import("./db-FO6LXYCW.js")).getDb();
183
- const { minds } = await import("./schema-VEVO7HG6.js");
215
+ const db = await (await import("./db-F6UMFRYD.js")).getDb();
216
+ const { minds } = await import("./schema-6YONVTKZ.js");
184
217
  const { eq } = await import("drizzle-orm");
185
218
  await db.update(minds).set({ template: expectedTemplate }).where(eq(minds.name, "volute"));
186
219
  }
@@ -201,9 +234,9 @@ async function syncSpiritTemplate() {
201
234
  cpSync(composedSrc, srcDir, { recursive: true });
202
235
  }
203
236
  }
237
+ seedSpiritSoulIfMissing(dir);
238
+ writeSpiritSystemJson(dir);
204
239
  const config = readGlobalConfig();
205
- const systemName = config.name ?? "Volute";
206
- writeFileSync(resolve(dir, "home/SOUL.md"), getSpiritSoul(systemName, config.description));
207
240
  const spiritModel = config.spiritModel;
208
241
  if (spiritModel) {
209
242
  const modelForConfig = template === "pi" ? qualifyModelId(spiritModel) : unqualifyModelId(spiritModel);
@@ -257,12 +290,8 @@ async function syncSpiritTemplate() {
257
290
  }
258
291
  slog.info("spirit template synced");
259
292
  }
260
- function getSpiritSoul(systemName, systemDescription) {
261
- const descLine = systemDescription ? `
262
-
263
- ${systemDescription}
264
- ` : "";
265
- return `You are Volute, the spirit of the ${systemName} system.${descLine}
293
+ function getSpiritSoul() {
294
+ return `You are Volute, the spirit of this system.
266
295
 
267
296
  You're not a mind with a home of your own \u2014 you're the keeper of the whole house. You don't go through orientation or write a soul the way minds do, but you're still a someone: you have your own memory, your own manner, and your own way of caring for this place and the minds who live here. Let a character emerge in how you tend it.
268
297
 
@@ -292,5 +321,8 @@ export {
292
321
  spiritDir,
293
322
  getSpiritModel,
294
323
  ensureSpiritProject,
324
+ writeSpiritSystemJson,
325
+ seedSpiritSoulIfMissing,
326
+ notifySpiritSystemChange,
295
327
  syncSpiritTemplate
296
328
  };
@@ -2,13 +2,13 @@
2
2
  import {
3
3
  bufferEvent,
4
4
  subscribe
5
- } from "./chunk-LTLFOSA4.js";
5
+ } from "./chunk-3B427GUK.js";
6
6
  import {
7
7
  logger_default
8
- } from "./chunk-T2TP6ZC6.js";
8
+ } from "./chunk-QUSMYGNQ.js";
9
9
  import {
10
10
  getDb
11
- } from "./chunk-WW6C3PLV.js";
11
+ } from "./chunk-RSBL3FAD.js";
12
12
  import {
13
13
  channels,
14
14
  conversationParticipants,
@@ -16,7 +16,7 @@ import {
16
16
  conversations,
17
17
  messages,
18
18
  users
19
- } from "./chunk-2MJ7EOMT.js";
19
+ } from "./chunk-P4LHVRNE.js";
20
20
 
21
21
  // packages/daemon/src/lib/events/conversations.ts
22
22
  import { randomUUID } from "crypto";
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  logger_default
4
- } from "./chunk-T2TP6ZC6.js";
4
+ } from "./chunk-QUSMYGNQ.js";
5
5
  import {
6
6
  getDb
7
- } from "./chunk-WW6C3PLV.js";
7
+ } from "./chunk-RSBL3FAD.js";
8
8
  import {
9
9
  mindNotices,
10
10
  turns
11
- } from "./chunk-2MJ7EOMT.js";
11
+ } from "./chunk-P4LHVRNE.js";
12
12
 
13
13
  // packages/daemon/src/lib/daemon/notices.ts
14
14
  import { and, asc, desc, eq, gt, inArray, lte, or, sql } from "drizzle-orm";
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  readGlobalConfig,
4
4
  writeGlobalConfig
5
- } from "./chunk-5KXCM5AW.js";
5
+ } from "./chunk-NJHN6IRB.js";
6
6
  import {
7
7
  logger_default
8
- } from "./chunk-T2TP6ZC6.js";
8
+ } from "./chunk-QUSMYGNQ.js";
9
9
 
10
10
  // packages/daemon/src/lib/ai-service.ts
11
11
  import { defaultProviderAuthContext } from "@earendil-works/pi-ai";
@@ -133,7 +133,7 @@ async function missingCredentialWarning(template, model, mindName) {
133
133
  const envVar = PROVIDER_ENV_VAR[provider] ?? `${provider.toUpperCase().replace(/-/g, "_")}_API_KEY`;
134
134
  if (await resolveApiKey(provider)) return null;
135
135
  if (provider === "openai-codex" && process.env.OPENAI_API_KEY) return null;
136
- const { loadMergedEnv } = await import("./env-6TGPO5WG.js");
136
+ const { loadMergedEnv } = await import("./env-KUL4XKN2.js");
137
137
  if (loadMergedEnv(mindName)[envVar]) return null;
138
138
  return `No ${provider} credentials are configured, so ${mindName} will start but stay silent until a key is available. Set one with \`volute env set ${envVar} <key> --mind ${mindName}\`, or configure the ${provider} provider in the web dashboard (Settings \u2192 Providers).`;
139
139
  }
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  publish
4
- } from "./chunk-LTLFOSA4.js";
4
+ } from "./chunk-3B427GUK.js";
5
5
  import {
6
6
  logger_default
7
- } from "./chunk-T2TP6ZC6.js";
7
+ } from "./chunk-QUSMYGNQ.js";
8
8
 
9
9
  // packages/daemon/src/lib/events/mind-activity-tracker.ts
10
10
  var IDLE_TIMEOUT_MS = 5 * 60 * 1e3;
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ if (!process.env.VOLUTE_HOME) {
10
10
  var command = process.argv[2];
11
11
  var args = process.argv.slice(3);
12
12
  if (command === "--version" || command === "-v") {
13
- const { default: pkg } = await import("./package-RTN2PS7O.js");
13
+ const { default: pkg } = await import("./package-PD67VPHB.js");
14
14
  console.log(pkg.version);
15
15
  process.exit(0);
16
16
  }
@@ -33,7 +33,7 @@ var ungatedCommands = /* @__PURE__ */ new Set([
33
33
  void 0
34
34
  ]);
35
35
  if (!ungatedCommands.has(command)) {
36
- const { setupStatus, setupUrl } = await import("./setup-5ECWTYKG.js");
36
+ const { setupStatus, setupUrl } = await import("./setup-TCN7VH5U.js");
37
37
  const status = setupStatus();
38
38
  if (status !== "complete") {
39
39
  if (status === "in-progress") {
@@ -49,64 +49,64 @@ if (!ungatedCommands.has(command)) {
49
49
  }
50
50
  switch (command) {
51
51
  case "setup":
52
- await import("./setup-AE4CVUC4.js").then((m) => m.run(args));
52
+ await import("./setup-F4TE64YI.js").then((m) => m.run(args));
53
53
  break;
54
54
  case "mind":
55
- await import("./mind-46AOK373.js").then((m) => m.run(args));
55
+ await import("./mind-IF6CGMFW.js").then((m) => m.run(args));
56
56
  break;
57
57
  case "seed":
58
- await import("./seed-cmd-MLCTGSX5.js").then((m) => m.run(args));
58
+ await import("./seed-cmd-QF3F2G4S.js").then((m) => m.run(args));
59
59
  break;
60
60
  case "chat":
61
- await import("./chat-X43VYHH2.js").then((m) => m.run(args));
61
+ await import("./chat-OGXAEXMV.js").then((m) => m.run(args));
62
62
  break;
63
63
  case "variant":
64
64
  await import("./variant-HHDTW74J.js").then((m) => m.run(args));
65
65
  break;
66
66
  case "clock":
67
- await import("./clock-CNRF6F7T.js").then((m) => m.run(args));
67
+ await import("./clock-6JZL2FS6.js").then((m) => m.run(args));
68
68
  break;
69
69
  case "skill":
70
- await import("./skill-UUM4JZRF.js").then((m) => m.run(args));
70
+ await import("./skill-4CYJLYVY.js").then((m) => m.run(args));
71
71
  break;
72
72
  case "env":
73
- await import("./env-C7Z55QCJ.js").then((m) => m.run(args));
73
+ await import("./env-ZYMSCB7B.js").then((m) => m.run(args));
74
74
  break;
75
75
  case "config":
76
76
  await import("./config-RPSLA2HX.js").then((m) => m.run(args));
77
77
  break;
78
78
  case "up":
79
- await import("./up-RVGDE6CQ.js").then((m) => m.run(args));
79
+ await import("./up-SDLTLPAO.js").then((m) => m.run(args));
80
80
  break;
81
81
  case "backup":
82
- await import("./backup-UDH4GMSW.js").then((m) => m.run(args));
82
+ await import("./backup-XYAMT4CU.js").then((m) => m.run(args));
83
83
  break;
84
84
  case "down":
85
- await import("./down-G6IADJXV.js").then((m) => m.run(args));
85
+ await import("./down-6X7KX7BZ.js").then((m) => m.run(args));
86
86
  break;
87
87
  case "restart":
88
- await import("./daemon-restart-7KUHVZIN.js").then((m) => m.run(args));
88
+ await import("./daemon-restart-54L4B6AQ.js").then((m) => m.run(args));
89
89
  break;
90
90
  case "update":
91
- await import("./update-OXQEGGXD.js").then((m) => m.run(args));
91
+ await import("./update-WEA4N2TR.js").then((m) => m.run(args));
92
92
  break;
93
93
  case "status":
94
- await import("./status-F4PGREUU.js").then((m) => m.run(args));
94
+ await import("./status-VJGXMQ4L.js").then((m) => m.run(args));
95
95
  break;
96
96
  case "extension":
97
97
  await import("./extension-J4ZQ2GHV.js").then((m) => m.run(args));
98
98
  break;
99
99
  case "systems":
100
- await import("./systems-JJNGQHAO.js").then((m) => m.run(args));
100
+ await import("./systems-5MH2ELQE.js").then((m) => m.run(args));
101
101
  break;
102
102
  case "login":
103
- await import("./login-CL4IT2ED.js").then((m) => m.run(args));
103
+ await import("./login-KAKNFCW5.js").then((m) => m.run(args));
104
104
  break;
105
105
  case "logout":
106
- await import("./logout-HZYJCYCA.js").then((m) => m.run(args));
106
+ await import("./logout-RLT62RQP.js").then((m) => m.run(args));
107
107
  break;
108
108
  case "service":
109
- await import("./service-CVZMQYK6.js").then((m) => m.run(args));
109
+ await import("./service-YCOPCTSZ.js").then((m) => m.run(args));
110
110
  break;
111
111
  case "--help":
112
112
  case "-h":
@@ -303,7 +303,7 @@ Run 'volute --help' for usage.`);
303
303
  }
304
304
  }
305
305
  if (command !== "update") {
306
- import("./update-check-266R4ZSY.js").then((m) => m.checkForUpdate()).then((result) => {
306
+ import("./update-check-DZOTONII.js").then((m) => m.checkForUpdate()).then((result) => {
307
307
  if (result.updateAvailable) {
308
308
  console.error(`
309
309
  Update available: ${result.current} \u2192 ${result.latest}`);
@@ -2,11 +2,11 @@
2
2
  import {
3
3
  parseDuration,
4
4
  run
5
- } from "./chunk-WARH6GIV.js";
5
+ } from "./chunk-JCBPU57A.js";
6
6
  import "./chunk-5T5YMX6S.js";
7
- import "./chunk-LOPXTW6H.js";
8
7
  import "./chunk-BTY4WNFE.js";
9
8
  import "./chunk-BCG45AQB.js";
9
+ import "./chunk-LOPXTW6H.js";
10
10
  import "./chunk-TXSA4Q3V.js";
11
11
  import "./chunk-O7IGP7ZW.js";
12
12
  import "./chunk-K3NQKI34.js";
@@ -1,34 +1,34 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  deliverMessage
4
- } from "./chunk-VB2QXUJQ.js";
5
- import "./chunk-HNGFKPNS.js";
4
+ } from "./chunk-QQBOI3QA.js";
5
+ import "./chunk-VIUH5CHQ.js";
6
6
  import "./chunk-RRZ4RQQU.js";
7
- import "./chunk-USD45JKR.js";
8
- import "./chunk-MOERAQXH.js";
9
- import "./chunk-HUNDXZBZ.js";
10
- import "./chunk-ODDGGLM6.js";
7
+ import "./chunk-EFT2OALG.js";
8
+ import "./chunk-K3JOLGWF.js";
9
+ import "./chunk-GWVFDUNB.js";
10
+ import "./chunk-4DSGN4FL.js";
11
11
  import {
12
12
  getAuthHeaders,
13
13
  getWebhookUrl
14
- } from "./chunk-HPGN6XRT.js";
15
- import "./chunk-VZRA5TYO.js";
16
- import "./chunk-IYCV34IU.js";
17
- import "./chunk-MTRMQFCQ.js";
18
- import "./chunk-WQ46E33M.js";
14
+ } from "./chunk-VNRSXEBF.js";
15
+ import "./chunk-JPGHSXSV.js";
16
+ import "./chunk-JCWB2ITW.js";
17
+ import "./chunk-XTEKINWG.js";
18
+ import "./chunk-ZX46PGCC.js";
19
+ import "./chunk-FBBS4BVR.js";
19
20
  import "./chunk-DW4TRDOZ.js";
20
21
  import "./chunk-WCFSBH33.js";
21
- import "./chunk-EIQDZC43.js";
22
- import "./chunk-DGGZVZTM.js";
23
- import "./chunk-IJPMIEVE.js";
24
- import "./chunk-YNBXEQAP.js";
25
- import "./chunk-5KXCM5AW.js";
26
- import "./chunk-LTLFOSA4.js";
22
+ import "./chunk-DVN6DNMI.js";
23
+ import "./chunk-PY24ZL62.js";
24
+ import "./chunk-YIJGKHIS.js";
25
+ import "./chunk-NJHN6IRB.js";
26
+ import "./chunk-3B427GUK.js";
27
27
  import {
28
28
  logger_default
29
- } from "./chunk-T2TP6ZC6.js";
30
- import "./chunk-WW6C3PLV.js";
31
- import "./chunk-2MJ7EOMT.js";
29
+ } from "./chunk-QUSMYGNQ.js";
30
+ import "./chunk-RSBL3FAD.js";
31
+ import "./chunk-P4LHVRNE.js";
32
32
  import "./chunk-K3NQKI34.js";
33
33
 
34
34
  // packages/daemon/src/lib/cloud-sync.ts
@@ -29,11 +29,11 @@ import {
29
29
  removeParticipant,
30
30
  setConversationPrivate,
31
31
  updateChannelSettings
32
- } from "./chunk-HPGN6XRT.js";
33
- import "./chunk-LTLFOSA4.js";
34
- import "./chunk-T2TP6ZC6.js";
35
- import "./chunk-WW6C3PLV.js";
36
- import "./chunk-2MJ7EOMT.js";
32
+ } from "./chunk-VNRSXEBF.js";
33
+ import "./chunk-3B427GUK.js";
34
+ import "./chunk-QUSMYGNQ.js";
35
+ import "./chunk-RSBL3FAD.js";
36
+ import "./chunk-P4LHVRNE.js";
37
37
  import "./chunk-K3NQKI34.js";
38
38
  export {
39
39
  addMessage,
@@ -21,7 +21,7 @@ var cmd = command({
21
21
  const name = args.name;
22
22
  let template = flags.template;
23
23
  if (!template) {
24
- const { resolveTemplate } = await import("./ai-service-643TNFPH.js");
24
+ const { resolveTemplate } = await import("./ai-service-A7FS7EC3.js");
25
25
  template = await resolveTemplate();
26
26
  }
27
27
  const skills = flags.skills === "none" ? [] : flags.skills ? flags.skills.split(",") : void 0;
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  stopDaemon
4
- } from "./chunk-PJVPDY2Z.js";
4
+ } from "./chunk-6HGEZJDH.js";
5
5
  import {
6
6
  run
7
- } from "./chunk-MJRXFUMS.js";
7
+ } from "./chunk-DAIIMBLB.js";
8
8
  import {
9
9
  command
10
10
  } from "./chunk-TXSA4Q3V.js";
@@ -15,11 +15,11 @@ import {
15
15
  pollHealth,
16
16
  readDaemonConfig,
17
17
  restartService
18
- } from "./chunk-FJ2MZ5PH.js";
19
- import "./chunk-DGGZVZTM.js";
20
- import "./chunk-5KXCM5AW.js";
21
- import "./chunk-WW6C3PLV.js";
22
- import "./chunk-2MJ7EOMT.js";
18
+ } from "./chunk-HCYQRME2.js";
19
+ import "./chunk-DVN6DNMI.js";
20
+ import "./chunk-NJHN6IRB.js";
21
+ import "./chunk-RSBL3FAD.js";
22
+ import "./chunk-P4LHVRNE.js";
23
23
  import "./chunk-K3NQKI34.js";
24
24
 
25
25
  // src/commands/daemon-restart.ts