volute 0.19.0 → 0.21.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 (104) hide show
  1. package/README.md +68 -68
  2. package/dist/activity-events-3WHHCOBB.js +15 -0
  3. package/dist/{archive-ZCFOSTKB.js → archive-4ZQYK5MN.js} +4 -2
  4. package/dist/auth-HM2RSPY7.js +37 -0
  5. package/dist/{channel-PUQKGSQM.js → channel-BOOMFULW.js} +2 -2
  6. package/dist/{chunk-OTWLI7F4.js → chunk-5462YKWP.js} +12 -9
  7. package/dist/{chunk-2TJGRJ4O.js → chunk-7LPTHFIL.js} +64 -59
  8. package/dist/chunk-A4S7H6G6.js +56 -0
  9. package/dist/chunk-AKPFNL7L.js +148 -0
  10. package/dist/{chunk-EBGCNDMM.js → chunk-B2CPS4QU.js} +128 -114
  11. package/dist/{chunk-FCDU5BFX.js → chunk-HFCBO2GL.js} +2 -2
  12. package/dist/chunk-HGCDWKSP.js +97 -0
  13. package/dist/{chunk-DYZGP3EW.js → chunk-IPJXU366.js} +1 -1
  14. package/dist/{chunk-VE4D3GOP.js → chunk-J5A3DF2U.js} +2 -2
  15. package/dist/{chunk-WC6ZHVRL.js → chunk-KFI7TQJ6.js} +2 -2
  16. package/dist/{chunk-AW7P4EVV.js → chunk-KTJGZ7M7.js} +55 -7
  17. package/dist/{chunk-4KPUF5JD.js → chunk-L3LHXZD7.js} +18 -5
  18. package/dist/{chunk-OGXOMR65.js → chunk-NWPT4ASZ.js} +1 -1
  19. package/dist/{chunk-FGV2H4TX.js → chunk-OGZYB5GL.js} +312 -268
  20. package/dist/{chunk-SCUDS4US.js → chunk-ON3FF5JA.js} +1 -1
  21. package/dist/{chunk-EMQSAY3B.js → chunk-PC6R6UUW.js} +6 -5
  22. package/dist/{chunk-VDWCHYTS.js → chunk-PHU4DEAJ.js} +1 -1
  23. package/dist/{chunk-7NO7EV5Z.js → chunk-Q7AITQ44.js} +2 -2
  24. package/dist/{chunk-32VR2EOH.js → chunk-QUJUKM4U.js} +2 -2
  25. package/dist/{chunk-VQWDC6UK.js → chunk-SGPEZ32F.js} +46 -1
  26. package/dist/{chunk-RHEGSQFJ.js → chunk-WSLPZF72.js} +1 -1
  27. package/dist/cli.js +59 -111
  28. package/dist/{connector-JBVNZ7VK.js → connector-PYT5UOTZ.js} +6 -6
  29. package/dist/connectors/discord.js +2 -2
  30. package/dist/connectors/slack.js +2 -2
  31. package/dist/connectors/telegram.js +2 -2
  32. package/dist/{create-HP4OVVHF.js → create-WIDA3M4C.js} +1 -1
  33. package/dist/{daemon-client-ITWUCNFO.js → daemon-client-ZHCDL4RS.js} +2 -2
  34. package/dist/{daemon-restart-JMZM3QY4.js → daemon-restart-BH67ZOTE.js} +8 -8
  35. package/dist/daemon.js +2872 -1301
  36. package/dist/{delete-BSU7K3RY.js → delete-LOIANQGD.js} +1 -1
  37. package/dist/down-LIOQ5JDH.js +14 -0
  38. package/dist/{env-A3LMO777.js → env-4PHIHTF4.js} +2 -2
  39. package/dist/{export-GCDNQCF3.js → export-XD6PJBQP.js} +19 -8
  40. package/dist/file-X4L5TTOL.js +204 -0
  41. package/dist/{history-WNK3DFUM.js → history-HTEKRNID.js} +2 -2
  42. package/dist/{import-M63VIUJ5.js → import-E433B4KG.js} +3 -3
  43. package/dist/{log-PPPZDVEF.js → log-SRO5Q6AD.js} +2 -2
  44. package/dist/{login-HNH3EUQV.js → login-UO6AOVEA.js} +4 -4
  45. package/dist/{logout-I5CB5UZS.js → logout-UKD5LA37.js} +2 -2
  46. package/dist/{logs-SF2IMJN4.js → logs-HNTNNBDW.js} +2 -2
  47. package/dist/{merge-33C237A4.js → merge-B6SYTGI7.js} +2 -2
  48. package/dist/{mind-PQ5NCPSU.js → mind-BIDOF65R.js} +27 -11
  49. package/dist/mind-activity-tracker-PGC3DBJ7.js +18 -0
  50. package/dist/{mind-manager-RVCFROAY.js → mind-manager-3V2NXX4I.js} +5 -6
  51. package/dist/{package-MYE2ZJLV.js → package-HQR52XSG.js} +1 -1
  52. package/dist/{pages-AXCOSY3P.js → pages-KQBR5TAZ.js} +6 -6
  53. package/dist/{publish-YB377JB7.js → publish-OJ4QMXVZ.js} +12 -9
  54. package/dist/{pull-XAEWQJ47.js → pull-GRQAXM2E.js} +2 -2
  55. package/dist/{register-VSPCMHKX.js → register-U2UO6TC4.js} +5 -5
  56. package/dist/registry-D2BSQ2X5.js +42 -0
  57. package/dist/{restart-IQKMCK5M.js → restart-CIDAKGG2.js} +3 -6
  58. package/dist/{schedule-LMX7GAQZ.js → schedule-NLR3LZLY.js} +27 -7
  59. package/dist/{seed-J43YDKXG.js → seed-3H2MRREW.js} +2 -2
  60. package/dist/{send-KVIZIGCE.js → send-RP2TA7SG.js} +132 -36
  61. package/dist/{service-LUR7WDO7.js → service-TVNEORO7.js} +31 -13
  62. package/dist/{setup-OH3PJUJO.js → setup-OZDYCKDI.js} +25 -34
  63. package/dist/{shared-KO35ZM44.js → shared-DCQ2UXOM.js} +4 -4
  64. package/dist/{skill-BCVNI6TV.js → skill-Q2Y6PQ3L.js} +2 -2
  65. package/dist/skills/orientation/SKILL.md +2 -2
  66. package/dist/skills/volute-mind/SKILL.md +38 -8
  67. package/dist/{sprout-VBEX63LX.js → sprout-6Z6C42YM.js} +34 -30
  68. package/dist/{start-I5JYB65M.js → start-JR6CUUWF.js} +3 -6
  69. package/dist/{status-D7E5HHBV.js → status-5XDGYHKP.js} +2 -2
  70. package/dist/{status-JCJAOXTW.js → status-LV34BG6G.js} +6 -5
  71. package/dist/{status-4ESFLGH4.js → status-Z7NAFMBI.js} +5 -5
  72. package/dist/{stop-NBVKEFQQ.js → stop-VKPGK25U.js} +2 -5
  73. package/dist/template-hash-BIMA4ILT.js +8 -0
  74. package/dist/{up-WG65SWJU.js → up-7BGDMFRT.js} +5 -5
  75. package/dist/{update-FJIHDJKM.js → update-4WT7VWHW.js} +5 -5
  76. package/dist/{update-check-MWE5AH4U.js → update-check-F5Z3ALXX.js} +2 -2
  77. package/dist/{upgrade-AIT24B5I.js → upgrade-ZEC2GGFO.js} +1 -1
  78. package/dist/{variant-63ZWO2W7.js → variant-A4I7PHXS.js} +16 -24
  79. package/dist/version-notify-TFS2U5CF.js +173 -0
  80. package/dist/web-assets/assets/index-BR3gtK3E.css +1 -0
  81. package/dist/web-assets/assets/index-CWmrZRQd.js +64 -0
  82. package/dist/web-assets/index.html +2 -2
  83. package/drizzle/0012_activity.sql +11 -0
  84. package/drizzle/meta/0012_snapshot.json +7 -0
  85. package/drizzle/meta/_journal.json +7 -0
  86. package/package.json +1 -1
  87. package/templates/_base/home/.config/routes.json +2 -2
  88. package/templates/_base/home/VOLUTE.md +1 -1
  89. package/templates/_base/src/lib/daemon-client.ts +22 -0
  90. package/templates/_base/src/lib/transparency.ts +1 -1
  91. package/templates/claude/.init/.config/routes.json +7 -1
  92. package/templates/pi/.init/.config/routes.json +7 -1
  93. package/templates/pi/src/agent.ts +11 -5
  94. package/templates/pi/src/lib/session-context-extension.ts +6 -4
  95. package/templates/pi/src/server.ts +2 -0
  96. package/dist/chunk-UJ6GHNR7.js +0 -675
  97. package/dist/chunk-Z524RFCJ.js +0 -36
  98. package/dist/db-5ZVC6MQF.js +0 -10
  99. package/dist/delivery-manager-ISTJMZDW.js +0 -16
  100. package/dist/down-ZY35KMHR.js +0 -14
  101. package/dist/schema-5BW7DFZI.js +0 -24
  102. package/dist/variants-JAGWGBXG.js +0 -26
  103. package/dist/web-assets/assets/index-BAbuRsVF.css +0 -1
  104. package/dist/web-assets/assets/index-CiQhSKi_.js +0 -63
@@ -7,8 +7,8 @@
7
7
  <link rel="preconnect" href="https://fonts.googleapis.com" />
8
8
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
9
9
  <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,300;0,400;0,500;0,600;1,400&display=swap" rel="stylesheet" />
10
- <script type="module" crossorigin src="/assets/index-CiQhSKi_.js"></script>
11
- <link rel="stylesheet" crossorigin href="/assets/index-BAbuRsVF.css">
10
+ <script type="module" crossorigin src="/assets/index-CWmrZRQd.js"></script>
11
+ <link rel="stylesheet" crossorigin href="/assets/index-BR3gtK3E.css">
12
12
  </head>
13
13
  <body>
14
14
  <div id="root"></div>
@@ -0,0 +1,11 @@
1
+ CREATE TABLE `activity` (
2
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
3
+ `type` text NOT NULL,
4
+ `mind` text NOT NULL,
5
+ `summary` text NOT NULL,
6
+ `metadata` text,
7
+ `created_at` text DEFAULT (datetime('now')) NOT NULL
8
+ );
9
+ --> statement-breakpoint
10
+ CREATE INDEX `idx_activity_created_at` ON `activity` (`created_at`);--> statement-breakpoint
11
+ CREATE INDEX `idx_activity_mind` ON `activity` (`mind`);
@@ -0,0 +1,7 @@
1
+ {
2
+ "id": "0012_activity",
3
+ "prevId": "0011_rename_human_to_brain",
4
+ "version": "6",
5
+ "dialect": "sqlite",
6
+ "tables": {}
7
+ }
@@ -85,6 +85,13 @@
85
85
  "when": 1772000000000,
86
86
  "tag": "0011_rename_human_to_brain",
87
87
  "breakpoints": true
88
+ },
89
+ {
90
+ "idx": 12,
91
+ "version": "6",
92
+ "when": 1772100000000,
93
+ "tag": "0012_activity",
94
+ "breakpoints": true
88
95
  }
89
96
  ]
90
97
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "volute",
3
- "version": "0.19.0",
3
+ "version": "0.21.0",
4
4
  "description": "CLI for creating and managing self-modifying AI minds powered by the Claude Agent SDK",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,6 +1,6 @@
1
1
  {
2
- "rules": [{ "channel": "volute:*", "isDM": false, "session": "${channel}" }],
2
+ "rules": [{ "channel": "volute:*", "isDM": false, "session": "group-${channel}" }],
3
3
  "sessions": {
4
- "volute:*": { "batch": { "debounce": 20, "maxWait": 120, "triggers": ["@{{name}}"] } }
4
+ "group-*": { "batch": { "debounce": 20, "maxWait": 120, "triggers": ["@{{name}}"] } }
5
5
  }
6
6
  }
@@ -47,7 +47,7 @@ volute shared log # see recent shared history
47
47
 
48
48
  Files you edit in `shared/` are auto-committed to your branch. When you're ready to share, merge to main. Other minds get your changes by pulling. If there's a conflict, you'll be told — pull the latest, reconcile, and merge again.
49
49
 
50
- The `shared/pages/` directory can be published as the system's shared website with `volute pages publish` (no `--mind` flag).
50
+ The `shared/pages/` directory can be published as the system's shared website with `volute pages publish --system`.
51
51
 
52
52
  ## Reference
53
53
 
@@ -74,6 +74,28 @@ export async function daemonEmit(event: DaemonEvent): Promise<void> {
74
74
  }
75
75
  }
76
76
 
77
+ export async function daemonSendFile(
78
+ targetMind: string,
79
+ filePath: string,
80
+ ): Promise<{ status: string; id?: string; destPath?: string }> {
81
+ if (!port || !mind) {
82
+ throw new Error("[volute] daemonSendFile: VOLUTE_DAEMON_PORT or VOLUTE_MIND not set");
83
+ }
84
+ const res = await fetch(
85
+ `http://127.0.0.1:${port}/api/minds/${encodeURIComponent(mind)}/files/send`,
86
+ {
87
+ method: "POST",
88
+ headers: headers(),
89
+ body: JSON.stringify({ targetMind, filePath }),
90
+ },
91
+ );
92
+ if (!res.ok) {
93
+ const body = await res.text().catch(() => "");
94
+ throw new Error(`daemonSendFile failed (${res.status}): ${body}`);
95
+ }
96
+ return (await res.json()) as { status: string; id?: string; destPath?: string };
97
+ }
98
+
77
99
  export async function daemonSend(channel: string, text: string): Promise<void> {
78
100
  if (!port || !mind) {
79
101
  console.error("[volute] daemonSend: VOLUTE_DAEMON_PORT or VOLUTE_MIND not set");
@@ -66,7 +66,7 @@ export function loadTransparencyPreset(): TransparencyPreset {
66
66
  // try next
67
67
  }
68
68
  }
69
- return "standard";
69
+ return "transparent";
70
70
  }
71
71
 
72
72
  export function filterEvent(preset: TransparencyPreset, event: DaemonEvent): DaemonEvent | null {
@@ -1,5 +1,11 @@
1
1
  {
2
2
  "gateUnmatched": true,
3
- "rules": [{ "channel": "volute:*", "isDM": true, "session": "${channel}" }],
3
+ "rules": [
4
+ { "channel": "volute:*", "isDM": true, "session": "${channel}" },
5
+ { "channel": "volute:*", "isDM": false, "session": "group-${channel}" }
6
+ ],
7
+ "sessions": {
8
+ "group-*": { "batch": { "debounce": 20, "maxWait": 120, "triggers": ["@{{name}}"] } }
9
+ },
4
10
  "default": "main"
5
11
  }
@@ -1,5 +1,11 @@
1
1
  {
2
2
  "gateUnmatched": true,
3
- "rules": [{ "channel": "volute:*", "isDM": true, "session": "${channel}" }],
3
+ "rules": [
4
+ { "channel": "volute:*", "isDM": true, "session": "${channel}" },
5
+ { "channel": "volute:*", "isDM": false, "session": "group-${channel}" }
6
+ ],
7
+ "sessions": {
8
+ "group-*": { "batch": { "debounce": 20, "maxWait": 120, "triggers": ["@{{name}}"] } }
9
+ },
4
10
  "default": "main"
5
11
  }
@@ -39,6 +39,7 @@ type PiSession = {
39
39
  export function createMind(options: {
40
40
  systemPrompt: string;
41
41
  cwd: string;
42
+ mindDir: string;
42
43
  model?: string;
43
44
  thinkingLevel?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
44
45
  compactionMessage?: string;
@@ -111,7 +112,7 @@ export function createMind(options: {
111
112
 
112
113
  const sessionContextExtension = createSessionContextExtension({
113
114
  currentSession: session.name,
114
- cwd: options.cwd,
115
+ mindDir: options.mindDir,
115
116
  });
116
117
 
117
118
  const replyInstructionsExtension = createReplyInstructionsExtension(session.messageChannels);
@@ -202,15 +203,20 @@ export function createMind(options: {
202
203
  // Fire-and-forget: await session ready then prompt
203
204
  (async () => {
204
205
  await session.ready;
205
- if (session.agentSession!.isStreaming) {
206
+ if (!session.agentSession) {
207
+ log("mind", `session "${sessionName}": not initialized, dropping message`);
208
+ broadcast(session, { type: "done" });
209
+ return;
210
+ }
211
+ if (session.agentSession.isStreaming) {
206
212
  if (meta.interrupt) {
207
213
  interruptSession(sessionName);
208
- session.agentSession!.prompt(text, { streamingBehavior: "steer", ...opts });
214
+ session.agentSession.prompt(text, { streamingBehavior: "steer", ...opts });
209
215
  } else {
210
- session.agentSession!.prompt(text, { streamingBehavior: "followUp", ...opts });
216
+ session.agentSession.prompt(text, { streamingBehavior: "followUp", ...opts });
211
217
  }
212
218
  } else {
213
- session.agentSession!.prompt(text, opts);
219
+ session.agentSession.prompt(text, opts);
214
220
  }
215
221
  })().catch((err) => {
216
222
  log("mind", `session "${sessionName}": prompt failed:`, err);
@@ -1,19 +1,20 @@
1
1
  import { resolve } from "node:path";
2
2
  import type { ExtensionFactory } from "@mariozechner/pi-coding-agent";
3
+ import { log } from "./logger.js";
3
4
  import { getSessionUpdates, resolvePiJsonl } from "./session-monitor.js";
4
5
 
5
6
  export function createSessionContextExtension(options: {
6
7
  currentSession: string;
7
- cwd: string;
8
+ mindDir: string;
8
9
  }): ExtensionFactory {
9
10
  return (pi) => {
10
11
  pi.on("before_agent_start", () => {
11
12
  try {
12
- const sessionsDir = resolve(options.cwd, ".mind/pi-sessions");
13
+ const sessionsDir = resolve(options.mindDir, ".mind/pi-sessions");
13
14
  const summary = getSessionUpdates({
14
15
  currentSession: options.currentSession,
15
16
  sessionsDir,
16
- cursorFile: resolve(options.cwd, ".mind/session-cursors.json"),
17
+ cursorFile: resolve(options.mindDir, ".mind/session-cursors.json"),
17
18
  jsonlResolver: (name) => resolvePiJsonl(sessionsDir, name),
18
19
  format: "pi",
19
20
  });
@@ -25,7 +26,8 @@ export function createSessionContextExtension(options: {
25
26
  display: true,
26
27
  },
27
28
  };
28
- } catch {
29
+ } catch (err) {
30
+ log("mind", "session context extension failed:", err);
29
31
  return {};
30
32
  }
31
33
  });
@@ -21,9 +21,11 @@ if (config.thinkingLevel) log("server", `thinking level: ${config.thinkingLevel}
21
21
  const systemPrompt = loadSystemPrompt();
22
22
  const pkg = loadPackageInfo();
23
23
 
24
+ const mindDir = resolve(".");
24
25
  const mind = createMind({
25
26
  systemPrompt,
26
27
  cwd: resolve("home"),
28
+ mindDir,
27
29
  model: config.model,
28
30
  thinkingLevel: config.thinkingLevel,
29
31
  compactionMessage: config.compactionMessage,