volute 0.41.0 → 0.41.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 (132) hide show
  1. package/dist/{accept-AHAOUFBK.js → accept-7YVHZKRD.js} +1 -1
  2. package/dist/{activity-events-EQGBUEZ7.js → activity-events-KFKVRZE3.js} +2 -2
  3. package/dist/{ai-service-ZHEPFC3U.js → ai-service-XCLE3MQP.js} +3 -3
  4. package/dist/{archive-LJAXDDEY.js → archive-4PPYF7LL.js} +2 -2
  5. package/dist/{auth-VYW2ECCE.js → auth-EAASQPTN.js} +3 -3
  6. package/dist/{bridge-F3ZJEKDN.js → bridge-WPYSOQKR.js} +1 -1
  7. package/dist/{chat-FO722GU2.js → chat-7DOENBY2.js} +8 -8
  8. package/dist/{chunk-6TPRURK5.js → chunk-5QG36RV7.js} +2 -2
  9. package/dist/{chunk-GMFCSXWB.js → chunk-62ICA2FF.js} +1 -1
  10. package/dist/{chunk-U7UASV36.js → chunk-763WUVJQ.js} +43 -10
  11. package/dist/{chunk-6ZAT5PYV.js → chunk-BLOAJLGI.js} +1 -1
  12. package/dist/{chunk-2I7OKOYV.js → chunk-CGPESELY.js} +2 -2
  13. package/dist/{chunk-FEQPNCXB.js → chunk-E7XWFDZL.js} +1 -1
  14. package/dist/{chunk-FU5YDH6Q.js → chunk-EKLRS2SX.js} +3 -3
  15. package/dist/{chunk-W5Z2H3LU.js → chunk-F44AEQAW.js} +290 -71
  16. package/dist/{chunk-V67XMNGP.js → chunk-G777ME4L.js} +2 -2
  17. package/dist/{chunk-YATR5BXD.js → chunk-GCS64EAD.js} +4 -4
  18. package/dist/{chunk-Y2XLASFJ.js → chunk-GN52E2DP.js} +1 -1
  19. package/dist/{chunk-ZX7EAV5J.js → chunk-IFNSAOA4.js} +9 -2
  20. package/dist/{chunk-VK2YD7VJ.js → chunk-IJCZAYGT.js} +1 -1
  21. package/dist/{chunk-VDODEQSJ.js → chunk-IUZ3EV2D.js} +4 -0
  22. package/dist/{chunk-2RQIIKFC.js → chunk-K547QOCM.js} +1 -1
  23. package/dist/{chunk-OQ7UEW67.js → chunk-KUJVCDWT.js} +2 -2
  24. package/dist/{chunk-GSOEUMVO.js → chunk-M2YMNTHK.js} +1 -1
  25. package/dist/{chunk-N64Q7FMP.js → chunk-MA7MYEOK.js} +4 -3
  26. package/dist/{chunk-JIGVTFIR.js → chunk-MJIJFCAH.js} +43 -14
  27. package/dist/{chunk-YN6ISG7A.js → chunk-MYJSKXGH.js} +14 -13
  28. package/dist/{chunk-MU2B7A3L.js → chunk-OEJFZHZZ.js} +1 -1
  29. package/dist/{chunk-SWY4DJ67.js → chunk-OSUF75I7.js} +2 -2
  30. package/dist/{chunk-WSRGS4XP.js → chunk-QLWG3C2Z.js} +10 -0
  31. package/dist/{chunk-UU3Q65US.js → chunk-QMJCNZ6C.js} +1 -1
  32. package/dist/{chunk-CYUNO4BM.js → chunk-QPTQKGGF.js} +1 -1
  33. package/dist/{chunk-4ED2DBNC.js → chunk-TFBQESH7.js} +1 -1
  34. package/dist/{chunk-AXNAK3HT.js → chunk-ULNQ6OC4.js} +7 -7
  35. package/dist/{chunk-PP5CGT2P.js → chunk-VBKRZCR7.js} +1 -1
  36. package/dist/{chunk-2R4JIZCB.js → chunk-YLTIEEVL.js} +2 -2
  37. package/dist/cli.js +22 -22
  38. package/dist/{clock-BMLJ2TR6.js → clock-HP2TGMG5.js} +3 -3
  39. package/dist/{cloud-sync-GV6O2HN2.js → cloud-sync-2XVXEOSU.js} +17 -17
  40. package/dist/{config-QB7W3Z7P.js → config-W7MS3PWY.js} +3 -3
  41. package/dist/{conversations-KW7IYESK.js → conversations-FSZCUUYO.js} +3 -3
  42. package/dist/{create-C3BBFYV7.js → create-CJ2SR4EU.js} +1 -1
  43. package/dist/{create-CTPXWFTL.js → create-OTM46ZUM.js} +2 -2
  44. package/dist/{daemon-client-2MIPKY3E.js → daemon-client-EWDPOOHC.js} +3 -1
  45. package/dist/{daemon-restart-W47YDE5E.js → daemon-restart-HDVGTYH7.js} +7 -7
  46. package/dist/daemon.js +218 -300
  47. package/dist/{db-D4FVCA5I.js → db-ZJJJYJBU.js} +1 -1
  48. package/dist/{delete-NLXES2C7.js → delete-4ND5PLE7.js} +1 -1
  49. package/dist/delivery-manager-CPADWRV2.js +33 -0
  50. package/dist/{delivery-router-Y66OXJPM.js → delivery-router-FDBZJQOY.js} +2 -2
  51. package/dist/{down-JVHNXOFU.js → down-DS6WCT34.js} +5 -5
  52. package/dist/echo-text-GEDEEY7M.js +32 -0
  53. package/dist/{env-IQ6Q2333.js → env-XX2MBZCZ.js} +1 -1
  54. package/dist/{exec-R2WWZ6FH.js → exec-ZDD7NEB4.js} +3 -3
  55. package/dist/{export-ZZ5WWBUH.js → export-5DOQV2WM.js} +3 -3
  56. package/dist/{extension-LZYHBNLV.js → extension-BCFYXI7A.js} +4 -1
  57. package/dist/{extensions-AGANCIQA.js → extensions-SU3N4COT.js} +17 -17
  58. package/dist/{files-Q2Z4LQZP.js → files-K2MEMV3W.js} +3 -3
  59. package/dist/{import-MFYCBS4K.js → import-V6QEHMPQ.js} +7 -7
  60. package/dist/{isolation-7F3MA4G7.js → isolation-F7ABZMDA.js} +2 -2
  61. package/dist/{join-6SZCA5FX.js → join-4S3KT7NE.js} +1 -1
  62. package/dist/{list-KHJZJPEJ.js → list-XJB5WII6.js} +1 -1
  63. package/dist/{login-WY3DADVB.js → login-PHMTLNUF.js} +2 -2
  64. package/dist/{login-GYTH67ES.js → login-YWD6PUOT.js} +1 -1
  65. package/dist/{logout-TFZHWNVL.js → logout-BP3R3CAA.js} +2 -2
  66. package/dist/{logout-YHQLOFLR.js → logout-Q2WICH4V.js} +1 -1
  67. package/dist/message-delivery-HPMELC4Q.js +41 -0
  68. package/dist/{mind-XIKEPJNS.js → mind-APS4URT7.js} +18 -18
  69. package/dist/{mind-activity-tracker-RSIWUUJK.js → mind-activity-tracker-HWVFE533.js} +3 -3
  70. package/dist/{mind-history-WHCNZ6I5.js → mind-history-TDUQFYAG.js} +1 -1
  71. package/dist/{mind-list-H3HC2ZRG.js → mind-list-2T353Q5G.js} +1 -1
  72. package/dist/mind-manager-74XQZEGX.js +33 -0
  73. package/dist/{mind-profile-7VYRJGFZ.js → mind-profile-2HHR7LZ7.js} +1 -1
  74. package/dist/mind-service-XGXSMQP6.js +37 -0
  75. package/dist/{mind-sleep-ZL5ZXFTM.js → mind-sleep-4NXV4J4U.js} +1 -1
  76. package/dist/{mind-status-ZWULKOUO.js → mind-status-CG66OXDK.js} +1 -1
  77. package/dist/{mind-wake-HK5ORGUK.js → mind-wake-TNB54DBR.js} +1 -1
  78. package/dist/{package-2X7UNSTQ.js → package-MVFX22K5.js} +2 -1
  79. package/dist/{read-CP7MYMJQ.js → read-JLR4NQXU.js} +1 -1
  80. package/dist/{register-XOBFEMI4.js → register-IQ2M4UO6.js} +1 -1
  81. package/dist/{registry-RAXNFN7K.js → registry-MDLNPTTI.js} +3 -1
  82. package/dist/{reject-43AGXB6B.js → reject-N2D4CZND.js} +1 -1
  83. package/dist/{restart-O5QIYQJT.js → restart-43A5MBGV.js} +1 -1
  84. package/dist/{sandbox-O3GZTS7J.js → sandbox-ND53WZVU.js} +7 -3
  85. package/dist/scheduler-MEBQF5MW.js +31 -0
  86. package/dist/{seed-I4CNKTKZ.js → seed-L4XFZ3VX.js} +1 -1
  87. package/dist/{seed-check-HZPVFJKZ.js → seed-check-N5ALJBT6.js} +1 -1
  88. package/dist/{seed-cmd-YTQYWCZF.js → seed-cmd-NSTPYJFC.js} +3 -3
  89. package/dist/{seed-create-MDBTVADS.js → seed-create-ZYCZC46W.js} +4 -4
  90. package/dist/{seed-sprout-N6O5FBPY.js → seed-sprout-YXHU73XA.js} +8 -8
  91. package/dist/{send-5XA7LRNB.js → send-KQECN2EL.js} +3 -3
  92. package/dist/{service-AY5TGWJX.js → service-Q5OVY5AK.js} +4 -4
  93. package/dist/{service-install-NLGAVTQS.js → service-install-GTDUHP6R.js} +5 -5
  94. package/dist/{setup-3434PQ5Q.js → setup-FPFWDMXD.js} +2 -2
  95. package/dist/{setup-47NBOCZL.js → setup-RMR3TKCR.js} +7 -7
  96. package/dist/{skill-ICN6Y2ZF.js → skill-E43BI34Y.js} +1 -1
  97. package/dist/skills/imagegen/scripts/imagegen.ts +1 -1
  98. package/dist/{skills-YTLBAF32.js → skills-AOZF6U2B.js} +5 -5
  99. package/dist/sleep-manager-OHM3TO62.js +35 -0
  100. package/dist/{spirit-KTBHLULO.js → spirit-ONLRFATY.js} +8 -8
  101. package/dist/{split-5YBEQTBF.js → split-5IBUODEE.js} +1 -1
  102. package/dist/{sprout-4ZUJUNDQ.js → sprout-2KJOQZCL.js} +1 -1
  103. package/dist/{src-OYWRPLC6.js → src-L2Z7X5UT.js} +5 -8
  104. package/dist/{src-4LFGGNW7.js → src-TJ7RBU5H.js} +2 -12
  105. package/dist/{start-LMXXRR3X.js → start-5AYFGNS7.js} +1 -1
  106. package/dist/{status-VMOZUIZ2.js → status-ECZHHSY5.js} +5 -5
  107. package/dist/{stop-TWDKVEUX.js → stop-WJ6IG6OK.js} +1 -1
  108. package/dist/system-chat-HZUKBIKJ.js +35 -0
  109. package/dist/{systems-Y2WZV2K4.js → systems-5MA57Q7G.js} +4 -4
  110. package/dist/{tailscale-PK3AI5EV.js → tailscale-TIRTGM6E.js} +1 -1
  111. package/dist/{template-hash-JARTCRGS.js → template-hash-446HHH5V.js} +2 -2
  112. package/dist/{turn-tracker-SZBSL7LK.js → turn-tracker-TIX4DY2W.js} +4 -4
  113. package/dist/{up-VGVPOB6J.js → up-7KVNER6V.js} +6 -6
  114. package/dist/{update-3ANTQO54.js → update-OPR4KU4M.js} +5 -5
  115. package/dist/{update-check-4O6DKUOF.js → update-check-OG27AL4Z.js} +2 -2
  116. package/dist/{upgrade-RXFZR5FI.js → upgrade-QB7AHIKX.js} +1 -1
  117. package/dist/{version-notify-SSNAWZMX.js → version-notify-UFFDUPCX.js} +19 -19
  118. package/package.json +2 -1
  119. package/packages/extensions/plan/skills/plan/scripts/plan-hook.sh +2 -2
  120. package/templates/_base/.init/.config/hooks/pre-prompt/session-activity.ts +3 -3
  121. package/templates/_base/.init/.local/hooks/pre-prompt/notices.ts +3 -3
  122. package/templates/_base/.init/.local/hooks/pre-prompt/session-activity.ts +3 -3
  123. package/templates/_base/src/lib/daemon-client.ts +1 -1
  124. package/templates/_base/src/lib/volute-server.ts +1 -1
  125. package/dist/delivery-manager-EB52CQ5X.js +0 -33
  126. package/dist/echo-text-QVPS6QDM.js +0 -32
  127. package/dist/message-delivery-X4CZE2L6.js +0 -41
  128. package/dist/mind-manager-VU3RGCXD.js +0 -31
  129. package/dist/mind-service-L7LMMDYJ.js +0 -37
  130. package/dist/scheduler-SXELVRWO.js +0 -31
  131. package/dist/sleep-manager-T3AXQB3R.js +0 -35
  132. package/dist/system-chat-HCPHUQGI.js +0 -35
@@ -8,10 +8,10 @@ import {
8
8
  pollHealthDown,
9
9
  readDaemonConfig,
10
10
  stopService
11
- } from "./chunk-2I7OKOYV.js";
11
+ } from "./chunk-CGPESELY.js";
12
12
  import {
13
13
  voluteSystemDir
14
- } from "./chunk-VDODEQSJ.js";
14
+ } from "./chunk-IUZ3EV2D.js";
15
15
 
16
16
  // src/commands/down.ts
17
17
  import { existsSync, readFileSync, unlinkSync } from "fs";
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  aiCompleteUtility
4
- } from "./chunk-VK2YD7VJ.js";
4
+ } from "./chunk-IJCZAYGT.js";
5
5
  import {
6
6
  logger_default
7
7
  } from "./chunk-T2TP6ZC6.js";
8
8
  import {
9
9
  getDb
10
- } from "./chunk-VDODEQSJ.js";
10
+ } from "./chunk-IUZ3EV2D.js";
11
11
  import {
12
12
  messages,
13
13
  mindHistory,
@@ -1013,11 +1013,11 @@ var Summarizer = class {
1013
1013
  }
1014
1014
  };
1015
1015
  async function reconcileWedgedTurns(idleMs) {
1016
- const { sweepWedgedTurns: sweepWedgedTurns2, summarizeOrphanedTurns: summarizeOrphanedTurns2 } = await import("./turn-tracker-SZBSL7LK.js");
1016
+ const { sweepWedgedTurns: sweepWedgedTurns2, summarizeOrphanedTurns: summarizeOrphanedTurns2 } = await import("./turn-tracker-TIX4DY2W.js");
1017
1017
  const wedged = await sweepWedgedTurns2(idleMs);
1018
1018
  if (wedged.length === 0) return;
1019
1019
  summarizeOrphanedTurns2(wedged);
1020
- const { tryGetDeliveryManager } = await import("./delivery-manager-EB52CQ5X.js");
1020
+ const { tryGetDeliveryManager } = await import("./delivery-manager-CPADWRV2.js");
1021
1021
  const dm = tryGetDeliveryManager();
1022
1022
  if (!dm) return;
1023
1023
  for (const t of wedged) {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  wrapForIsolation
4
- } from "./chunk-4ED2DBNC.js";
4
+ } from "./chunk-TFBQESH7.js";
5
5
 
6
6
  // packages/daemon/src/lib/util/exec.ts
7
7
  import { execFile as execFileCb, execFileSync, spawn } from "child_process";
@@ -4,6 +4,8 @@
4
4
  import { existsSync, readFileSync } from "fs";
5
5
  import { homedir } from "os";
6
6
  import { resolve } from "path";
7
+ import { Agent } from "undici";
8
+ var daemonDispatcher = new Agent({ headersTimeout: 0, bodyTimeout: 0 });
7
9
  function voluteUserHome() {
8
10
  return process.env.VOLUTE_USER_HOME ?? resolve(homedir(), ".volute");
9
11
  }
@@ -83,7 +85,7 @@ function resolveDaemonUrl() {
83
85
  async function daemonFetch(path, options) {
84
86
  const url = resolveDaemonUrl();
85
87
  const headers = new Headers(options?.headers);
86
- const daemonToken = process.env.VOLUTE_DAEMON_TOKEN;
88
+ const daemonToken = process.env.VOLUTE_MIND_TOKEN;
87
89
  const cliSession = daemonToken ? null : readCliSession();
88
90
  if (daemonToken) {
89
91
  headers.set("Authorization", `Bearer ${daemonToken}`);
@@ -96,7 +98,11 @@ async function daemonFetch(path, options) {
96
98
  headers.set("X-Volute-Session", voluteSession);
97
99
  }
98
100
  try {
99
- const res = await fetch(`${url}${path}`, { ...options, headers });
101
+ const res = await fetch(`${url}${path}`, {
102
+ ...options,
103
+ headers,
104
+ dispatcher: daemonDispatcher
105
+ });
100
106
  if (res.status === 401 && !path.startsWith("/api/auth/")) {
101
107
  if (cliSession) {
102
108
  console.error("Session expired. Run `volute login` again.");
@@ -116,6 +122,7 @@ async function daemonFetch(path, options) {
116
122
  }
117
123
 
118
124
  export {
125
+ daemonDispatcher,
119
126
  readSessionFile,
120
127
  resolveDaemonUrl,
121
128
  daemonFetch
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  readGlobalConfig,
4
4
  writeGlobalConfig
5
- } from "./chunk-N64Q7FMP.js";
5
+ } from "./chunk-MA7MYEOK.js";
6
6
  import {
7
7
  logger_default
8
8
  } from "./chunk-T2TP6ZC6.js";
@@ -179,6 +179,9 @@ async function resolveMindDir(name) {
179
179
  function stateDir(name) {
180
180
  return resolve(voluteSystemDir(), "state", name);
181
181
  }
182
+ function mindTmpDir(dir) {
183
+ return resolve(dir, ".mind", "tmp");
184
+ }
182
185
  async function nextPort() {
183
186
  const db2 = await getDb();
184
187
  const rows = await db2.select({ port: minds.port }).from(minds);
@@ -266,6 +269,7 @@ export {
266
269
  mindDir,
267
270
  resolveMindDir,
268
271
  stateDir,
272
+ mindTmpDir,
269
273
  nextPort,
270
274
  daemonLoopback
271
275
  };
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-T2TP6ZC6.js";
5
5
  import {
6
6
  getDb
7
- } from "./chunk-VDODEQSJ.js";
7
+ } from "./chunk-IUZ3EV2D.js";
8
8
  import {
9
9
  activity
10
10
  } from "./chunk-MHFAWJCC.js";
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  setBridgeConfig
4
- } from "./chunk-CYUNO4BM.js";
4
+ } from "./chunk-QPTQKGGF.js";
5
5
  import {
6
6
  readEnv,
7
7
  sharedEnvPath,
8
8
  writeEnv
9
- } from "./chunk-6ZAT5PYV.js";
9
+ } from "./chunk-BLOAJLGI.js";
10
10
 
11
11
  // packages/daemon/src/lib/template/import-utils.ts
12
12
  import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "fs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  stateDir
4
- } from "./chunk-VDODEQSJ.js";
4
+ } from "./chunk-IUZ3EV2D.js";
5
5
 
6
6
  // packages/daemon/src/lib/chat/file-sharing.ts
7
7
  import { randomBytes } from "crypto";
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  voluteSystemDir
4
- } from "./chunk-VDODEQSJ.js";
4
+ } from "./chunk-IUZ3EV2D.js";
5
5
 
6
6
  // packages/daemon/src/lib/config/setup.ts
7
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
7
+ import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
8
8
  import { resolve } from "path";
9
9
  function configPath() {
10
10
  return resolve(voluteSystemDir(), "config.json");
@@ -36,7 +36,8 @@ function writeGlobalConfig(config) {
36
36
  const path = configPath();
37
37
  mkdirSync(voluteSystemDir(), { recursive: true });
38
38
  writeFileSync(path, `${JSON.stringify(config, null, 2)}
39
- `);
39
+ `, { mode: 384 });
40
+ chmodSync(path, 384);
40
41
  _cachedConfig = { config, ts: Date.now() };
41
42
  }
42
43
  function isSetupComplete() {
@@ -2,11 +2,11 @@
2
2
  import {
3
3
  exec,
4
4
  gitExec
5
- } from "./chunk-Y2XLASFJ.js";
5
+ } from "./chunk-GN52E2DP.js";
6
6
  import {
7
7
  readGlobalConfig,
8
8
  writeGlobalConfig
9
- } from "./chunk-N64Q7FMP.js";
9
+ } from "./chunk-MA7MYEOK.js";
10
10
  import {
11
11
  logger_default
12
12
  } from "./chunk-T2TP6ZC6.js";
@@ -15,7 +15,7 @@ import {
15
15
  mindDir,
16
16
  readRegistry,
17
17
  voluteHome
18
- } from "./chunk-VDODEQSJ.js";
18
+ } from "./chunk-IUZ3EV2D.js";
19
19
  import {
20
20
  sharedSkills
21
21
  } from "./chunk-MHFAWJCC.js";
@@ -46,7 +46,7 @@ async function initDefaultSkills() {
46
46
  const config = readGlobalConfig();
47
47
  let extensionSkills = [];
48
48
  try {
49
- const { getExtensionStandardSkills } = await import("./extensions-AGANCIQA.js");
49
+ const { getExtensionStandardSkills } = await import("./extensions-SU3N4COT.js");
50
50
  extensionSkills = getExtensionStandardSkills();
51
51
  } catch (err) {
52
52
  logger_default.warn("failed to load extension standard skills during init", logger_default.errorData(err));
@@ -129,14 +129,24 @@ async function importSkillFromDir(sourceDir, author) {
129
129
  throw new Error("Invalid skill directory name");
130
130
  }
131
131
  validateSkillId(id);
132
+ const db = await getDb();
133
+ const existing = await db.select().from(sharedSkills).where(eq(sharedSkills.id, id)).get();
134
+ if (existing && existing.author !== author) {
135
+ const existingProtected = existing.author === "volute" || existing.author.startsWith("ext:");
136
+ const callerProtected = author === "volute" || author.startsWith("ext:");
137
+ const reclaim = callerProtected && !existingProtected;
138
+ if (!reclaim) {
139
+ throw new Error(
140
+ existingProtected ? `Cannot overwrite protected skill "${id}" (authored by "${existing.author}")` : `Cannot overwrite skill "${id}" authored by "${existing.author}"`
141
+ );
142
+ }
143
+ }
132
144
  const destDir = join(sharedSkillsDir(), id);
133
145
  if (existsSync(destDir)) rmSync(destDir, { recursive: true });
134
146
  mkdirSync(destDir, { recursive: true });
135
147
  cpSync(sourceDir, destDir, { recursive: true });
136
148
  const upstreamPath = join(destDir, ".upstream.json");
137
149
  if (existsSync(upstreamPath)) rmSync(upstreamPath);
138
- const db = await getDb();
139
- const existing = await db.select().from(sharedSkills).where(eq(sharedSkills.id, id)).get();
140
150
  const version = existing ? existing.version + 1 : 1;
141
151
  await db.insert(sharedSkills).values({ id, name: name || id, description, author, version }).onConflictDoUpdate({
142
152
  target: sharedSkills.id,
@@ -219,8 +229,14 @@ async function installSkill(_mindName, dir, skillId) {
219
229
  );
220
230
  }
221
231
  }
222
- installHookShims(dir, skillId, hooks);
223
- if (bin) installBinShim(dir, skillId, bin);
232
+ try {
233
+ installHookShims(dir, skillId, hooks);
234
+ if (bin) installBinShim(dir, skillId, bin);
235
+ } catch (e) {
236
+ removeHookShims(dir, skillId);
237
+ rmSync(destDir, { recursive: true });
238
+ throw e;
239
+ }
224
240
  }
225
241
  let installNotes = null;
226
242
  const installMdPath = join(destDir, "references", "INSTALL.md");
@@ -457,26 +473,31 @@ function removeHookShims(dir, skillId) {
457
473
  if (existsSync(shimPath)) rmSync(shimPath);
458
474
  }
459
475
  }
476
+ var BIN_SHIM_MARKER = "# volute-skill:";
460
477
  function binShimContent(skillId, scriptPath, skillsSubdir) {
461
478
  const skillScriptPath = `${skillsSubdir}/${skillId}/${scriptPath}`;
462
479
  const ext = scriptPath.split(".").pop() ?? "sh";
480
+ const header = `#!/bin/bash
481
+ ${BIN_SHIM_MARKER} ${skillId}
482
+ `;
463
483
  if (ext === "ts") {
464
- return `#!/bin/bash
465
- exec node --import tsx ${skillScriptPath} "$@"
484
+ return `${header}exec node --import tsx ${skillScriptPath} "$@"
466
485
  `;
467
486
  }
468
487
  if (ext === "js") {
469
- return `#!/bin/bash
470
- exec node ${skillScriptPath} "$@"
488
+ return `${header}exec node ${skillScriptPath} "$@"
471
489
  `;
472
490
  }
473
- return `#!/bin/bash
474
- exec bash ${skillScriptPath} "$@"
491
+ return `${header}exec bash ${skillScriptPath} "$@"
475
492
  `;
476
493
  }
477
494
  function binCommandName(scriptPath) {
478
495
  return basename(scriptPath).replace(/\.[^.]+$/, "");
479
496
  }
497
+ function binShimOwner(shimPath) {
498
+ const line = readFileSync(shimPath, "utf-8").split("\n").find((l) => l.startsWith(BIN_SHIM_MARKER));
499
+ return line?.slice(BIN_SHIM_MARKER.length).trim() || void 0;
500
+ }
480
501
  function installBinShim(dir, skillId, scriptPath) {
481
502
  const home = resolve(dir, "home");
482
503
  const skillsSubdir = mindSkillsDir(dir).slice(home.length + 1);
@@ -484,6 +505,14 @@ function installBinShim(dir, skillId, scriptPath) {
484
505
  mkdirSync(binDir, { recursive: true });
485
506
  const cmdName = binCommandName(scriptPath);
486
507
  const shimPath = join(binDir, cmdName);
508
+ if (existsSync(shimPath)) {
509
+ const owner = binShimOwner(shimPath);
510
+ if (owner && owner !== skillId) {
511
+ throw new Error(
512
+ `Bin command "${cmdName}" is already provided by skill "${owner}"; skill "${skillId}" cannot overwrite it`
513
+ );
514
+ }
515
+ }
487
516
  writeFileSync(shimPath, binShimContent(skillId, scriptPath, skillsSubdir), { mode: 493 });
488
517
  }
489
518
  function removeBinShim(dir, scriptPath) {
@@ -3,27 +3,28 @@ import {
3
3
  applyInitFiles,
4
4
  composeTemplate,
5
5
  copyTemplateToDir,
6
- findTemplatesRoot
7
- } from "./chunk-WSRGS4XP.js";
6
+ findTemplatesRoot,
7
+ renderComposedPackageJson
8
+ } from "./chunk-QLWG3C2Z.js";
8
9
  import {
9
10
  getSharedSkill,
10
11
  installSkill,
11
12
  mindSkillsDir
12
- } from "./chunk-JIGVTFIR.js";
13
+ } from "./chunk-MJIJFCAH.js";
13
14
  import {
14
15
  readVoluteConfig,
15
16
  writeVoluteConfig
16
17
  } from "./chunk-CU6OFXMM.js";
17
18
  import {
18
19
  exec
19
- } from "./chunk-Y2XLASFJ.js";
20
+ } from "./chunk-GN52E2DP.js";
20
21
  import {
21
22
  qualifyModelId,
22
23
  resolveTemplate
23
- } from "./chunk-VK2YD7VJ.js";
24
+ } from "./chunk-IJCZAYGT.js";
24
25
  import {
25
26
  readGlobalConfig
26
- } from "./chunk-N64Q7FMP.js";
27
+ } from "./chunk-MA7MYEOK.js";
27
28
  import {
28
29
  logger_default
29
30
  } from "./chunk-T2TP6ZC6.js";
@@ -32,7 +33,7 @@ import {
32
33
  findMind,
33
34
  nextPort,
34
35
  voluteSystemDir
35
- } from "./chunk-VDODEQSJ.js";
36
+ } from "./chunk-IUZ3EV2D.js";
36
37
 
37
38
  // packages/daemon/src/lib/mind/spirit.ts
38
39
  import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
@@ -128,7 +129,7 @@ async function ensureSpiritProject() {
128
129
  } catch (err) {
129
130
  slog.warn("failed to add tending schedule to spirit config", logger_default.errorData(err));
130
131
  }
131
- const { createMindUser, chownMindDir, ensureVoluteGroup } = await import("./isolation-7F3MA4G7.js");
132
+ const { createMindUser, chownMindDir, ensureVoluteGroup } = await import("./isolation-F7ABZMDA.js");
132
133
  ensureVoluteGroup();
133
134
  createMindUser("volute", resolve(dir, "home"));
134
135
  chownMindDir(dir, "volute");
@@ -157,12 +158,12 @@ async function syncSpiritTemplate() {
157
158
  if (existsSync(newSrc)) {
158
159
  cpSync(newSrc, resolve(dir, "src"), { recursive: true });
159
160
  }
160
- const newPkg = resolve(newComposed.composedDir, "package.json");
161
- if (existsSync(newPkg)) {
161
+ const newPkg = renderComposedPackageJson(newComposed.composedDir, "volute");
162
+ if (newPkg) {
162
163
  cpSync(newPkg, resolve(dir, "package.json"));
163
164
  await exec("npm", ["install"], { cwd: dir, env: npmEnv() });
164
165
  }
165
- const db = await (await import("./db-D4FVCA5I.js")).getDb();
166
+ const db = await (await import("./db-ZJJJYJBU.js")).getDb();
166
167
  const { minds } = await import("./schema-HHYJDG7B.js");
167
168
  const { eq } = await import("drizzle-orm");
168
169
  await db.update(minds).set({ template: expectedTemplate }).where(eq(minds.name, "volute"));
@@ -198,10 +199,10 @@ async function syncSpiritTemplate() {
198
199
  `);
199
200
  }
200
201
  }
201
- const composedPkg = resolve(composedDir, "package.json");
202
+ const composedPkg = renderComposedPackageJson(composedDir, "volute");
202
203
  const currentPkg = resolve(dir, "package.json");
203
204
  const nodeModulesMissing = !existsSync(resolve(dir, "node_modules"));
204
- if (existsSync(composedPkg)) {
205
+ if (composedPkg) {
205
206
  const composedContent = readFileSync(composedPkg, "utf-8");
206
207
  const currentContent = existsSync(currentPkg) ? readFileSync(currentPkg, "utf-8") : "";
207
208
  if (composedContent !== currentContent || nodeModulesMissing) {
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  mindDir,
4
4
  stateDir
5
- } from "./chunk-VDODEQSJ.js";
5
+ } from "./chunk-IUZ3EV2D.js";
6
6
 
7
7
  // packages/daemon/src/lib/mind/archive.ts
8
8
  import { execFileSync } from "child_process";
@@ -3,10 +3,10 @@ import {
3
3
  LAUNCHD_PLIST_LABEL,
4
4
  LAUNCHD_PLIST_PATH,
5
5
  USER_SYSTEMD_UNIT
6
- } from "./chunk-2I7OKOYV.js";
6
+ } from "./chunk-CGPESELY.js";
7
7
  import {
8
8
  resolveVoluteBin
9
- } from "./chunk-Y2XLASFJ.js";
9
+ } from "./chunk-GN52E2DP.js";
10
10
 
11
11
  // packages/daemon/src/lib/config/service-install.ts
12
12
  import { execFile } from "child_process";
@@ -78,6 +78,15 @@ function copyTemplateToDir(composedDir, destDir, mindName, manifest) {
78
78
  }
79
79
  }
80
80
  }
81
+ function renderComposedPackageJson(composedDir, mindName) {
82
+ const dest = resolve(composedDir, "package.json");
83
+ if (existsSync(dest)) return dest;
84
+ const tmpl = resolve(composedDir, "package.json.tmpl");
85
+ if (!existsSync(tmpl)) return null;
86
+ const content = readFileSync(tmpl, "utf-8").replaceAll("{{name}}", mindName);
87
+ writeFileSync(dest, content);
88
+ return dest;
89
+ }
81
90
  function applyInitFiles(destDir) {
82
91
  const initDir = resolve(destDir, ".init");
83
92
  if (!existsSync(initDir)) return;
@@ -146,6 +155,7 @@ export {
146
155
  findTemplatesRoot,
147
156
  composeTemplate,
148
157
  copyTemplateToDir,
158
+ renderComposedPackageJson,
149
159
  applyInitFiles,
150
160
  isKnownTemplate,
151
161
  applyTemplateHomeFiles,
@@ -3,7 +3,7 @@ import {
3
3
  composeTemplate,
4
4
  findTemplatesRoot,
5
5
  listFiles
6
- } from "./chunk-WSRGS4XP.js";
6
+ } from "./chunk-QLWG3C2Z.js";
7
7
 
8
8
  // packages/daemon/src/lib/template/template-hash.ts
9
9
  import { createHash } from "crypto";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-T2TP6ZC6.js";
5
5
  import {
6
6
  voluteSystemDir
7
- } from "./chunk-VDODEQSJ.js";
7
+ } from "./chunk-IUZ3EV2D.js";
8
8
 
9
9
  // packages/daemon/src/lib/bridges/bridges.ts
10
10
  import { existsSync, readFileSync, writeFileSync } from "fs";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  getBaseName,
4
4
  validateMindName
5
- } from "./chunk-VDODEQSJ.js";
5
+ } from "./chunk-IUZ3EV2D.js";
6
6
 
7
7
  // packages/daemon/src/lib/mind/isolation.ts
8
8
  import { execFileSync } from "child_process";
@@ -2,14 +2,14 @@
2
2
  import {
3
3
  findBridgeForChannel,
4
4
  getBridgeConfig
5
- } from "./chunk-CYUNO4BM.js";
5
+ } from "./chunk-QPTQKGGF.js";
6
6
  import {
7
7
  recordOutbound
8
- } from "./chunk-W5Z2H3LU.js";
8
+ } from "./chunk-F44AEQAW.js";
9
9
  import {
10
10
  readEnv,
11
11
  sharedEnvPath
12
- } from "./chunk-6ZAT5PYV.js";
12
+ } from "./chunk-BLOAJLGI.js";
13
13
  import {
14
14
  addMessage,
15
15
  findDMConversation,
@@ -17,17 +17,17 @@ import {
17
17
  getChannelName,
18
18
  getConversation,
19
19
  getParticipants
20
- } from "./chunk-2R4JIZCB.js";
20
+ } from "./chunk-YLTIEEVL.js";
21
21
  import {
22
22
  readVoluteConfig
23
23
  } from "./chunk-CU6OFXMM.js";
24
24
  import {
25
25
  publish
26
- } from "./chunk-YATR5BXD.js";
26
+ } from "./chunk-GCS64EAD.js";
27
27
  import {
28
28
  getOrCreateMindUser,
29
29
  getUserByUsername
30
- } from "./chunk-6TPRURK5.js";
30
+ } from "./chunk-5QG36RV7.js";
31
31
  import {
32
32
  logger_default
33
33
  } from "./chunk-T2TP6ZC6.js";
@@ -37,7 +37,7 @@ import {
37
37
  import {
38
38
  mindDir,
39
39
  voluteSystemDir
40
- } from "./chunk-VDODEQSJ.js";
40
+ } from "./chunk-IUZ3EV2D.js";
41
41
  import {
42
42
  __export
43
43
  } from "./chunk-K3NQKI34.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  publish
4
- } from "./chunk-2RQIIKFC.js";
4
+ } from "./chunk-K547QOCM.js";
5
5
  import {
6
6
  logger_default
7
7
  } from "./chunk-T2TP6ZC6.js";
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  subscribe
4
- } from "./chunk-2RQIIKFC.js";
4
+ } from "./chunk-K547QOCM.js";
5
5
  import {
6
6
  logger_default
7
7
  } from "./chunk-T2TP6ZC6.js";
8
8
  import {
9
9
  getDb
10
- } from "./chunk-VDODEQSJ.js";
10
+ } from "./chunk-IUZ3EV2D.js";
11
11
  import {
12
12
  channels,
13
13
  conversationParticipants,
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-2X7UNSTQ.js");
13
+ const { default: pkg } = await import("./package-MVFX22K5.js");
14
14
  console.log(pkg.version);
15
15
  process.exit(0);
16
16
  }
@@ -31,7 +31,7 @@ var ungatedCommands = /* @__PURE__ */ new Set([
31
31
  void 0
32
32
  ]);
33
33
  if (!ungatedCommands.has(command)) {
34
- const { isSetupComplete } = await import("./setup-3434PQ5Q.js");
34
+ const { isSetupComplete } = await import("./setup-FPFWDMXD.js");
35
35
  if (!isSetupComplete()) {
36
36
  console.error("Volute is not set up. Run `volute setup` first.");
37
37
  process.exit(1);
@@ -39,61 +39,61 @@ if (!ungatedCommands.has(command)) {
39
39
  }
40
40
  switch (command) {
41
41
  case "setup":
42
- await import("./setup-47NBOCZL.js").then((m) => m.run(args));
42
+ await import("./setup-RMR3TKCR.js").then((m) => m.run(args));
43
43
  break;
44
44
  case "mind":
45
- await import("./mind-XIKEPJNS.js").then((m) => m.run(args));
45
+ await import("./mind-APS4URT7.js").then((m) => m.run(args));
46
46
  break;
47
47
  case "seed":
48
- await import("./seed-cmd-YTQYWCZF.js").then((m) => m.run(args));
48
+ await import("./seed-cmd-NSTPYJFC.js").then((m) => m.run(args));
49
49
  break;
50
50
  case "chat":
51
- await import("./chat-FO722GU2.js").then((m) => m.run(args));
51
+ await import("./chat-7DOENBY2.js").then((m) => m.run(args));
52
52
  break;
53
53
  case "variant":
54
54
  await import("./variant-HHDTW74J.js").then((m) => m.run(args));
55
55
  break;
56
56
  case "clock":
57
- await import("./clock-BMLJ2TR6.js").then((m) => m.run(args));
57
+ await import("./clock-HP2TGMG5.js").then((m) => m.run(args));
58
58
  break;
59
59
  case "skill":
60
- await import("./skill-ICN6Y2ZF.js").then((m) => m.run(args));
60
+ await import("./skill-E43BI34Y.js").then((m) => m.run(args));
61
61
  break;
62
62
  case "env":
63
- await import("./env-IQ6Q2333.js").then((m) => m.run(args));
63
+ await import("./env-XX2MBZCZ.js").then((m) => m.run(args));
64
64
  break;
65
65
  case "config":
66
- await import("./config-QB7W3Z7P.js").then((m) => m.run(args));
66
+ await import("./config-W7MS3PWY.js").then((m) => m.run(args));
67
67
  break;
68
68
  case "up":
69
- await import("./up-VGVPOB6J.js").then((m) => m.run(args));
69
+ await import("./up-7KVNER6V.js").then((m) => m.run(args));
70
70
  break;
71
71
  case "down":
72
- await import("./down-JVHNXOFU.js").then((m) => m.run(args));
72
+ await import("./down-DS6WCT34.js").then((m) => m.run(args));
73
73
  break;
74
74
  case "restart":
75
- await import("./daemon-restart-W47YDE5E.js").then((m) => m.run(args));
75
+ await import("./daemon-restart-HDVGTYH7.js").then((m) => m.run(args));
76
76
  break;
77
77
  case "update":
78
- await import("./update-3ANTQO54.js").then((m) => m.run(args));
78
+ await import("./update-OPR4KU4M.js").then((m) => m.run(args));
79
79
  break;
80
80
  case "status":
81
- await import("./status-VMOZUIZ2.js").then((m) => m.run(args));
81
+ await import("./status-ECZHHSY5.js").then((m) => m.run(args));
82
82
  break;
83
83
  case "extension":
84
- await import("./extension-LZYHBNLV.js").then((m) => m.run(args));
84
+ await import("./extension-BCFYXI7A.js").then((m) => m.run(args));
85
85
  break;
86
86
  case "systems":
87
- await import("./systems-Y2WZV2K4.js").then((m) => m.run(args));
87
+ await import("./systems-5MA57Q7G.js").then((m) => m.run(args));
88
88
  break;
89
89
  case "login":
90
- await import("./login-WY3DADVB.js").then((m) => m.run(args));
90
+ await import("./login-PHMTLNUF.js").then((m) => m.run(args));
91
91
  break;
92
92
  case "logout":
93
- await import("./logout-TFZHWNVL.js").then((m) => m.run(args));
93
+ await import("./logout-BP3R3CAA.js").then((m) => m.run(args));
94
94
  break;
95
95
  case "service":
96
- await import("./service-AY5TGWJX.js").then((m) => m.run(args));
96
+ await import("./service-Q5OVY5AK.js").then((m) => m.run(args));
97
97
  break;
98
98
  case "--help":
99
99
  case "-h":
@@ -150,7 +150,7 @@ use --mind <name> or VOLUTE_MIND env var to identify the mind.`);
150
150
  default: {
151
151
  let isExtensionCommand = false;
152
152
  try {
153
- const { daemonFetch } = await import("./daemon-client-2MIPKY3E.js");
153
+ const { daemonFetch } = await import("./daemon-client-EWDPOOHC.js");
154
154
  const res = await daemonFetch("/api/extensions/commands");
155
155
  if (res.ok) {
156
156
  const extCommands = await res.json();
@@ -264,7 +264,7 @@ Run 'volute --help' for usage.`);
264
264
  }
265
265
  }
266
266
  if (command !== "update") {
267
- import("./update-check-4O6DKUOF.js").then((m) => m.checkForUpdate()).then((result) => {
267
+ import("./update-check-OG27AL4Z.js").then((m) => m.checkForUpdate()).then((result) => {
268
268
  if (result.updateAvailable) {
269
269
  console.error(`
270
270
  Update available: ${result.current} \u2192 ${result.latest}`);