volute 0.22.0 → 0.23.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.
@@ -17,7 +17,7 @@ import {
17
17
  getPrompt,
18
18
  loadJsonMap,
19
19
  saveJsonMap
20
- } from "./chunk-VNVCRVYI.js";
20
+ } from "./chunk-M5CNKH4J.js";
21
21
  import {
22
22
  readVoluteConfig
23
23
  } from "./chunk-XLC342FO.js";
@@ -618,25 +618,53 @@ function getConnectorManager() {
618
618
  return instance;
619
619
  }
620
620
 
621
+ // src/lib/events/mind-events.ts
622
+ var subscribers = /* @__PURE__ */ new Map();
623
+ function subscribe2(mind, callback) {
624
+ let set = subscribers.get(mind);
625
+ if (!set) {
626
+ set = /* @__PURE__ */ new Set();
627
+ subscribers.set(mind, set);
628
+ }
629
+ set.add(callback);
630
+ return () => {
631
+ set.delete(callback);
632
+ if (set.size === 0) subscribers.delete(mind);
633
+ };
634
+ }
635
+ function publish2(mind, event) {
636
+ const set = subscribers.get(mind);
637
+ if (!set) return;
638
+ for (const cb of set) {
639
+ try {
640
+ cb(event);
641
+ } catch (err) {
642
+ console.error("[mind-events] subscriber threw:", err);
643
+ set.delete(cb);
644
+ if (set.size === 0) subscribers.delete(mind);
645
+ }
646
+ }
647
+ }
648
+
621
649
  // src/lib/delivery/delivery-manager.ts
622
650
  import { and, eq, sql } from "drizzle-orm";
623
651
 
624
652
  // src/lib/events/conversation-events.ts
625
- var subscribers = /* @__PURE__ */ new Map();
626
- function subscribe2(conversationId, callback) {
627
- let set = subscribers.get(conversationId);
653
+ var subscribers2 = /* @__PURE__ */ new Map();
654
+ function subscribe3(conversationId, callback) {
655
+ let set = subscribers2.get(conversationId);
628
656
  if (!set) {
629
657
  set = /* @__PURE__ */ new Set();
630
- subscribers.set(conversationId, set);
658
+ subscribers2.set(conversationId, set);
631
659
  }
632
660
  set.add(callback);
633
661
  return () => {
634
662
  set.delete(callback);
635
- if (set.size === 0) subscribers.delete(conversationId);
663
+ if (set.size === 0) subscribers2.delete(conversationId);
636
664
  };
637
665
  }
638
- function publish2(conversationId, event) {
639
- const set = subscribers.get(conversationId);
666
+ function publish3(conversationId, event) {
667
+ const set = subscribers2.get(conversationId);
640
668
  if (!set) return;
641
669
  for (const cb of set) {
642
670
  try {
@@ -644,7 +672,7 @@ function publish2(conversationId, event) {
644
672
  } catch (err) {
645
673
  console.error("[conversation-events] subscriber threw:", err);
646
674
  set.delete(cb);
647
- if (set.size === 0) subscribers.delete(conversationId);
675
+ if (set.size === 0) subscribers2.delete(conversationId);
648
676
  }
649
677
  }
650
678
  }
@@ -734,7 +762,7 @@ function publishTypingForChannels(channels, map) {
734
762
  for (const channel of channels) {
735
763
  if (channel.startsWith(VOLUTE_PREFIX)) {
736
764
  const conversationId = channel.slice(VOLUTE_PREFIX.length);
737
- publish2(conversationId, { type: "typing", senders: map.get(channel) });
765
+ publish3(conversationId, { type: "typing", senders: map.get(channel) });
738
766
  }
739
767
  }
740
768
  }
@@ -1418,6 +1446,26 @@ function getDeliveryManager() {
1418
1446
 
1419
1447
  // src/lib/delivery/message-delivery.ts
1420
1448
  var dlog3 = logger_default.child("delivery");
1449
+ async function recordInbound(mind, channel, sender, content) {
1450
+ try {
1451
+ const db = await getDb();
1452
+ await db.insert(mindHistory).values({
1453
+ mind,
1454
+ type: "inbound",
1455
+ channel,
1456
+ sender,
1457
+ content
1458
+ });
1459
+ } catch (err) {
1460
+ dlog3.warn(`failed to persist inbound for ${mind}`, logger_default.errorData(err));
1461
+ }
1462
+ publish2(mind, {
1463
+ mind,
1464
+ type: "inbound",
1465
+ channel,
1466
+ content: content ?? void 0
1467
+ });
1468
+ }
1421
1469
  async function deliverMessage(mindName, payload) {
1422
1470
  try {
1423
1471
  const [baseName] = mindName.split("@", 2);
@@ -1427,18 +1475,7 @@ async function deliverMessage(mindName, payload) {
1427
1475
  return;
1428
1476
  }
1429
1477
  const textContent = extractTextContent(payload.content);
1430
- try {
1431
- const db = await getDb();
1432
- await db.insert(mindHistory).values({
1433
- mind: baseName,
1434
- type: "inbound",
1435
- channel: payload.channel,
1436
- sender: payload.sender ?? null,
1437
- content: textContent
1438
- });
1439
- } catch (err) {
1440
- dlog3.warn(`failed to persist message for ${baseName}`, logger_default.errorData(err));
1441
- }
1478
+ await recordInbound(baseName, payload.channel, payload.sender ?? null, textContent);
1442
1479
  const sleepManager = getSleepManagerIfReady();
1443
1480
  if (sleepManager?.isSleeping(baseName)) {
1444
1481
  if (sleepManager.checkWakeTrigger(baseName, payload)) {
@@ -2359,7 +2396,7 @@ var SleepManager = class {
2359
2396
  const db = await getDb();
2360
2397
  const rows = await db.select().from(deliveryQueue).where(and2(eq2(deliveryQueue.mind, name), eq2(deliveryQueue.status, "sleep-queued"))).all();
2361
2398
  if (rows.length === 0) return 0;
2362
- const { deliverMessage: deliverMessage2 } = await import("./message-delivery-WUS4K4ZC.js");
2399
+ const { deliverMessage: deliverMessage2 } = await import("./message-delivery-FHV4NO2F.js");
2363
2400
  const delivered = [];
2364
2401
  for (const row of rows) {
2365
2402
  try {
@@ -2640,11 +2677,14 @@ export {
2640
2677
  getSleepManagerIfReady,
2641
2678
  subscribe2 as subscribe,
2642
2679
  publish2 as publish,
2680
+ subscribe3 as subscribe2,
2681
+ publish3 as publish2,
2643
2682
  getTypingMap,
2644
2683
  publishTypingForChannels,
2645
2684
  extractTextContent,
2646
2685
  initDeliveryManager,
2647
2686
  getDeliveryManager,
2687
+ recordInbound,
2648
2688
  deliverMessage,
2649
2689
  initMailPoller,
2650
2690
  getMailPoller
@@ -548,7 +548,7 @@ var MindManager = class {
548
548
  if (this.shuttingDown || this.stopping.has(name)) return;
549
549
  mlog.error(`mind ${name} exited with code ${code}`);
550
550
  try {
551
- const { getSleepManagerIfReady } = await import("./sleep-manager-3RWUX2ZR.js");
551
+ const { getSleepManagerIfReady } = await import("./sleep-manager-2TMQ65E4.js");
552
552
  if (getSleepManagerIfReady()?.isSleeping(name)) {
553
553
  mlog.info(`${name} is sleeping \u2014 skipping crash recovery`);
554
554
  return;
package/dist/cli.js CHANGED
@@ -9,7 +9,7 @@ if (!process.env.VOLUTE_HOME) {
9
9
  var command = process.argv[2];
10
10
  var args = process.argv.slice(3);
11
11
  if (command === "--version" || command === "-v") {
12
- const { default: pkg } = await import("./package-A7PEYJI2.js");
12
+ const { default: pkg } = await import("./package-CUBJ4PKS.js");
13
13
  console.log(pkg.version);
14
14
  process.exit(0);
15
15
  }
@@ -45,13 +45,13 @@ switch (command) {
45
45
  await import("./env-4PHIHTF4.js").then((m) => m.run(args));
46
46
  break;
47
47
  case "up":
48
- await import("./up-JKGC7PPF.js").then((m) => m.run(args));
48
+ await import("./up-Z5JRG2M2.js").then((m) => m.run(args));
49
49
  break;
50
50
  case "down":
51
51
  await import("./down-WSUASL5E.js").then((m) => m.run(args));
52
52
  break;
53
53
  case "restart":
54
- await import("./daemon-restart-TPQ2XBRZ.js").then((m) => m.run(args));
54
+ await import("./daemon-restart-RMGOOGPE.js").then((m) => m.run(args));
55
55
  break;
56
56
  case "service":
57
57
  await import("./service-7BFXDI6J.js").then((m) => m.run(args));
@@ -5,11 +5,11 @@ import {
5
5
  } from "./chunk-G5KRTU2F.js";
6
6
  import {
7
7
  deliverMessage
8
- } from "./chunk-OSFGKF2T.js";
8
+ } from "./chunk-ISWZ6QUK.js";
9
9
  import "./chunk-HFCBO2GL.js";
10
10
  import "./chunk-HGCDWKSP.js";
11
11
  import "./chunk-A4S7H6G6.js";
12
- import "./chunk-VNVCRVYI.js";
12
+ import "./chunk-M5CNKH4J.js";
13
13
  import "./chunk-XLC342FO.js";
14
14
  import "./chunk-PHU4DEAJ.js";
15
15
  import "./chunk-SGPEZ32F.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  run
4
- } from "./chunk-JNFRY2WU.js";
4
+ } from "./chunk-JG4CCJOA.js";
5
5
  import {
6
6
  stopDaemon
7
7
  } from "./chunk-QIXPN3OO.js";
package/dist/daemon.js CHANGED
@@ -38,12 +38,15 @@ import {
38
38
  initSleepManager,
39
39
  initTokenBudget,
40
40
  publish,
41
+ publish2,
41
42
  publishTypingForChannels,
43
+ recordInbound,
42
44
  startMindFull,
43
45
  stopAllWatchers,
44
46
  stopMindFull,
45
- subscribe as subscribe2
46
- } from "./chunk-OSFGKF2T.js";
47
+ subscribe as subscribe2,
48
+ subscribe2 as subscribe3
49
+ } from "./chunk-ISWZ6QUK.js";
47
50
  import {
48
51
  readSystemsConfig
49
52
  } from "./chunk-HFCBO2GL.js";
@@ -66,7 +69,7 @@ import {
66
69
  getPromptIfCustom,
67
70
  initMindManager,
68
71
  substitute
69
- } from "./chunk-VNVCRVYI.js";
72
+ } from "./chunk-M5CNKH4J.js";
70
73
  import {
71
74
  findOpenClawSession,
72
75
  importOpenClawConnectors,
@@ -713,7 +716,7 @@ async function addMessage(conversationId, role, senderName, content) {
713
716
  content,
714
717
  created_at: result.created_at
715
718
  };
716
- publish(conversationId, {
719
+ publish2(conversationId, {
717
720
  type: "message",
718
721
  id: msg.id,
719
722
  role: msg.role,
@@ -915,7 +918,7 @@ var app = new Hono().get("/events", async (c) => {
915
918
  });
916
919
  cleanups.push(unsubActivity);
917
920
  for (const conv of conversations2) {
918
- const unsubConv = subscribe2(conv.id, (event) => {
921
+ const unsubConv = subscribe3(conv.id, (event) => {
919
922
  stream.writeSSE({
920
923
  data: JSON.stringify({ event: "conversation", conversationId: conv.id, ...event })
921
924
  }).catch((err) => {
@@ -2810,34 +2813,6 @@ function convertAssistantContent(content) {
2810
2813
  return result;
2811
2814
  }
2812
2815
 
2813
- // src/lib/events/mind-events.ts
2814
- var subscribers = /* @__PURE__ */ new Map();
2815
- function subscribe3(mind, callback) {
2816
- let set = subscribers.get(mind);
2817
- if (!set) {
2818
- set = /* @__PURE__ */ new Set();
2819
- subscribers.set(mind, set);
2820
- }
2821
- set.add(callback);
2822
- return () => {
2823
- set.delete(callback);
2824
- if (set.size === 0) subscribers.delete(mind);
2825
- };
2826
- }
2827
- function publish2(mind, event) {
2828
- const set = subscribers.get(mind);
2829
- if (!set) return;
2830
- for (const cb of set) {
2831
- try {
2832
- cb(event);
2833
- } catch (err) {
2834
- console.error("[mind-events] subscriber threw:", err);
2835
- set.delete(cb);
2836
- if (set.size === 0) subscribers.delete(mind);
2837
- }
2838
- }
2839
- }
2840
-
2841
2816
  // src/lib/variant-cleanup.ts
2842
2817
  import { existsSync as existsSync8, rmSync as rmSync2 } from "fs";
2843
2818
  async function cleanupVariant(mindName, variantName, projectRoot, variantPath, opts) {
@@ -2878,7 +2853,7 @@ async function getMindStatus(name, port) {
2878
2853
  const manager = getMindManager();
2879
2854
  let status = "stopped";
2880
2855
  try {
2881
- const { getSleepManagerIfReady } = await import("./sleep-manager-3RWUX2ZR.js");
2856
+ const { getSleepManagerIfReady } = await import("./sleep-manager-2TMQ65E4.js");
2882
2857
  if (getSleepManagerIfReady()?.isSleeping(name)) {
2883
2858
  status = "sleeping";
2884
2859
  }
@@ -3696,7 +3671,7 @@ ${user.trimEnd()}
3696
3671
  const name = c.req.param("name");
3697
3672
  const entry = findMind(name);
3698
3673
  if (!entry) return c.json({ error: "Mind not found" }, 404);
3699
- const { getSleepManagerIfReady } = await import("./sleep-manager-3RWUX2ZR.js");
3674
+ const { getSleepManagerIfReady } = await import("./sleep-manager-2TMQ65E4.js");
3700
3675
  const sm = getSleepManagerIfReady();
3701
3676
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
3702
3677
  return c.json(sm.getState(name));
@@ -3704,7 +3679,7 @@ ${user.trimEnd()}
3704
3679
  const name = c.req.param("name");
3705
3680
  const entry = findMind(name);
3706
3681
  if (!entry) return c.json({ error: "Mind not found" }, 404);
3707
- const { getSleepManagerIfReady } = await import("./sleep-manager-3RWUX2ZR.js");
3682
+ const { getSleepManagerIfReady } = await import("./sleep-manager-2TMQ65E4.js");
3708
3683
  const sm = getSleepManagerIfReady();
3709
3684
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
3710
3685
  if (sm.isSleeping(name)) return c.json({ error: "Mind is already sleeping" }, 409);
@@ -3724,7 +3699,7 @@ ${user.trimEnd()}
3724
3699
  const name = c.req.param("name");
3725
3700
  const entry = findMind(name);
3726
3701
  if (!entry) return c.json({ error: "Mind not found" }, 404);
3727
- const { getSleepManagerIfReady } = await import("./sleep-manager-3RWUX2ZR.js");
3702
+ const { getSleepManagerIfReady } = await import("./sleep-manager-2TMQ65E4.js");
3728
3703
  const sm = getSleepManagerIfReady();
3729
3704
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
3730
3705
  if (!sm.isSleeping(name)) return c.json({ error: "Mind is not sleeping" }, 409);
@@ -3734,7 +3709,7 @@ ${user.trimEnd()}
3734
3709
  const name = c.req.param("name");
3735
3710
  const entry = findMind(name);
3736
3711
  if (!entry) return c.json({ error: "Mind not found" }, 404);
3737
- const { getSleepManagerIfReady } = await import("./sleep-manager-3RWUX2ZR.js");
3712
+ const { getSleepManagerIfReady } = await import("./sleep-manager-2TMQ65E4.js");
3738
3713
  const sm = getSleepManagerIfReady();
3739
3714
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
3740
3715
  const flushed = await sm.flushQueuedMessages(name);
@@ -3952,7 +3927,7 @@ ${user.trimEnd()}
3952
3927
  if (!variant) return c.json({ error: `Unknown variant: ${variantName}` }, 404);
3953
3928
  }
3954
3929
  try {
3955
- const { getSleepManagerIfReady } = await import("./sleep-manager-3RWUX2ZR.js");
3930
+ const { getSleepManagerIfReady } = await import("./sleep-manager-2TMQ65E4.js");
3956
3931
  const sm = getSleepManagerIfReady();
3957
3932
  if (sm?.isSleeping(baseName)) {
3958
3933
  const body2 = await c.req.text();
@@ -3994,21 +3969,10 @@ ${user.trimEnd()}
3994
3969
  logger_default.error(`failed to parse message body for ${baseName}`, logger_default.errorData(err));
3995
3970
  }
3996
3971
  const channel = parsed?.channel ?? "unknown";
3997
- const db = await getDb();
3998
3972
  if (parsed) {
3999
- try {
4000
- const sender2 = parsed.sender ?? null;
4001
- const content = extractTextContent(parsed.content);
4002
- await db.insert(mindHistory).values({
4003
- mind: baseName,
4004
- type: "inbound",
4005
- channel,
4006
- sender: sender2,
4007
- content
4008
- });
4009
- } catch (err) {
4010
- logger_default.error(`failed to persist inbound message for ${baseName}`, logger_default.errorData(err));
4011
- }
3973
+ const sender2 = parsed.sender ?? null;
3974
+ const content = extractTextContent(parsed.content);
3975
+ await recordInbound(baseName, channel, sender2, content);
4012
3976
  }
4013
3977
  const budget = getTokenBudget();
4014
3978
  const budgetStatus = budget.checkBudget(baseName);
@@ -4060,6 +4024,7 @@ ${user.trimEnd()}
4060
4024
  const seedEntry = findMind(baseName);
4061
4025
  if (seedEntry?.stage === "seed") {
4062
4026
  try {
4027
+ const db = await getDb();
4063
4028
  const countResult = await db.select({ count: sql2`count(*)` }).from(mindHistory).where(eq4(mindHistory.mind, baseName));
4064
4029
  const msgCount = countResult[0]?.count ?? 0;
4065
4030
  if (msgCount >= 10 && msgCount % 10 === 0) {
@@ -4211,7 +4176,7 @@ ${user.trimEnd()}
4211
4176
  } catch (err) {
4212
4177
  logger_default.error(`failed to persist event for ${baseName}`, logger_default.errorData(err));
4213
4178
  }
4214
- publish2(baseName, {
4179
+ publish(baseName, {
4215
4180
  mind: baseName,
4216
4181
  type: body.type,
4217
4182
  session: body.session,
@@ -4261,14 +4226,29 @@ ${user.trimEnd()}
4261
4226
 
4262
4227
  `));
4263
4228
  };
4264
- const unsubscribe = subscribe3(baseName, (event) => {
4229
+ let unsubscribe;
4230
+ const pingInterval = setInterval(() => {
4231
+ try {
4232
+ controller.enqueue(encoder.encode(": ping\n\n"));
4233
+ } catch {
4234
+ clearInterval(pingInterval);
4235
+ unsubscribe?.();
4236
+ }
4237
+ }, 15e3);
4238
+ unsubscribe = subscribe2(baseName, (event) => {
4265
4239
  if (typeFilter && !typeFilter.includes(event.type)) return;
4266
4240
  if (sessionFilter && event.session !== sessionFilter) return;
4267
4241
  if (channelFilter && event.channel !== channelFilter) return;
4268
- send5(JSON.stringify(event));
4242
+ try {
4243
+ send5(JSON.stringify(event));
4244
+ } catch {
4245
+ clearInterval(pingInterval);
4246
+ unsubscribe?.();
4247
+ }
4269
4248
  });
4270
4249
  c.req.raw.signal.addEventListener("abort", () => {
4271
- unsubscribe();
4250
+ clearInterval(pingInterval);
4251
+ unsubscribe?.();
4272
4252
  try {
4273
4253
  controller.close();
4274
4254
  } catch {
@@ -4760,7 +4740,7 @@ var app18 = new Hono18().post("/:name/typing", zValidator5("json", typingSchema)
4760
4740
  const volutePrefix = "volute:";
4761
4741
  if (channel.startsWith(volutePrefix)) {
4762
4742
  const conversationId = channel.slice(volutePrefix.length);
4763
- publish(conversationId, { type: "typing", senders: map.get(channel) });
4743
+ publish2(conversationId, { type: "typing", senders: map.get(channel) });
4764
4744
  }
4765
4745
  return c.json({ ok: true });
4766
4746
  }).get("/:name/typing", (c) => {
@@ -4805,8 +4785,8 @@ async function fanOutToMinds(opts) {
4805
4785
  const participantNames = participants.map((p) => p.username);
4806
4786
  const isDM = opts.isDM ?? participants.length === 2;
4807
4787
  const channelEntryType = opts.channelEntryType ?? (isDM ? "dm" : "group");
4808
- const { getMindManager: getMindManager2 } = await import("./mind-manager-P5OBDUKI.js");
4809
- const { getSleepManagerIfReady } = await import("./sleep-manager-3RWUX2ZR.js");
4788
+ const { getMindManager: getMindManager2 } = await import("./mind-manager-KMY4GA2J.js");
4789
+ const { getSleepManagerIfReady } = await import("./sleep-manager-2TMQ65E4.js");
4810
4790
  const manager = getMindManager2();
4811
4791
  const sm = getSleepManagerIfReady();
4812
4792
  const targetMinds = mindParticipants.map((ap) => {
@@ -4935,7 +4915,7 @@ var app20 = new Hono20().use("*", authMiddleware).post("/minds/:name/chat", zVal
4935
4915
  return c.json({ error: "Conversation not found" }, 404);
4936
4916
  }
4937
4917
  return streamSSE4(c, async (stream) => {
4938
- const unsubscribe = subscribe2(conversationId, (event) => {
4918
+ const unsubscribe = subscribe3(conversationId, (event) => {
4939
4919
  stream.writeSSE({ data: JSON.stringify(event) }).catch((err) => {
4940
4920
  if (!stream.aborted) logger_default.error("[v1-chat] SSE write error:", logger_default.errorData(err));
4941
4921
  });
@@ -5155,7 +5135,7 @@ var app22 = new Hono22().use("*", authMiddleware).get("/", async (c) => {
5155
5135
  });
5156
5136
  cleanups.push(unsubActivity);
5157
5137
  for (const conv of conversations2) {
5158
- const unsubConv = subscribe2(conv.id, (event) => {
5138
+ const unsubConv = subscribe3(conv.id, (event) => {
5159
5139
  const data = { event: "conversation", conversationId: conv.id, ...event };
5160
5140
  const eventId = bufferEvent(data);
5161
5141
  stream.writeSSE({
@@ -5612,8 +5592,8 @@ async function fanOutToMinds2(opts) {
5612
5592
  const participantNames = participants.map((p) => p.username);
5613
5593
  const isDM = opts.isDM ?? participants.length === 2;
5614
5594
  const channelEntryType = opts.channelEntryType ?? (isDM ? "dm" : "group");
5615
- const { getMindManager: getMindManager2 } = await import("./mind-manager-P5OBDUKI.js");
5616
- const { getSleepManagerIfReady } = await import("./sleep-manager-3RWUX2ZR.js");
5595
+ const { getMindManager: getMindManager2 } = await import("./mind-manager-KMY4GA2J.js");
5596
+ const { getSleepManagerIfReady } = await import("./sleep-manager-2TMQ65E4.js");
5617
5597
  const manager = getMindManager2();
5618
5598
  const sm = getSleepManagerIfReady();
5619
5599
  const targetMinds = mindParticipants.map((ap) => {
@@ -5745,7 +5725,7 @@ var app25 = new Hono25().post("/:name/chat", zValidator9("json", chatSchema), as
5745
5725
  return c.json({ error: "Conversation not found" }, 404);
5746
5726
  }
5747
5727
  return streamSSE6(c, async (stream) => {
5748
- const unsubscribe = subscribe2(conversationId, (event) => {
5728
+ const unsubscribe = subscribe3(conversationId, (event) => {
5749
5729
  stream.writeSSE({ data: JSON.stringify(event) }).catch((err) => {
5750
5730
  if (!stream.aborted) console.error("[chat] SSE write error:", err);
5751
5731
  });
@@ -5961,7 +5941,7 @@ var app27 = new Hono27().use("*", authMiddleware).get("/", async (c) => {
5961
5941
  return c.json({ error: "Conversation not found" }, 404);
5962
5942
  }
5963
5943
  return streamSSE7(c, async (stream) => {
5964
- const unsubscribe = subscribe2(conversationId, (event) => {
5944
+ const unsubscribe = subscribe3(conversationId, (event) => {
5965
5945
  stream.writeSSE({ data: JSON.stringify(event) }).catch((err) => {
5966
5946
  if (!stream.aborted) console.error("[chat] SSE write error:", err);
5967
5947
  });
@@ -6246,7 +6226,7 @@ async function startDaemon(opts) {
6246
6226
  });
6247
6227
  await Promise.all(workers);
6248
6228
  }
6249
- import("./cloud-sync-C6WRYRVR.js").then(
6229
+ import("./cloud-sync-PI47U2LT.js").then(
6250
6230
  ({ consumeQueuedMessages }) => consumeQueuedMessages().catch((err) => {
6251
6231
  logger_default.warn("failed to consume queued cloud messages", logger_default.errorData(err));
6252
6232
  })
@@ -6254,7 +6234,7 @@ async function startDaemon(opts) {
6254
6234
  logger_default.warn("failed to load cloud-sync module", logger_default.errorData(err));
6255
6235
  });
6256
6236
  try {
6257
- const { backfillTemplateHashes, notifyVersionUpdate } = await import("./version-notify-5FGUAVSF.js");
6237
+ const { backfillTemplateHashes, notifyVersionUpdate } = await import("./version-notify-LKABEJSA.js");
6258
6238
  backfillTemplateHashes();
6259
6239
  notifyVersionUpdate().catch((err) => {
6260
6240
  logger_default.warn("failed to send version update notifications", logger_default.errorData(err));
@@ -1,12 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  deliverMessage,
4
- extractTextContent
5
- } from "./chunk-OSFGKF2T.js";
4
+ extractTextContent,
5
+ recordInbound
6
+ } from "./chunk-ISWZ6QUK.js";
6
7
  import "./chunk-HFCBO2GL.js";
7
8
  import "./chunk-HGCDWKSP.js";
8
9
  import "./chunk-A4S7H6G6.js";
9
- import "./chunk-VNVCRVYI.js";
10
+ import "./chunk-M5CNKH4J.js";
10
11
  import "./chunk-XLC342FO.js";
11
12
  import "./chunk-PHU4DEAJ.js";
12
13
  import "./chunk-SGPEZ32F.js";
@@ -17,5 +18,6 @@ import "./chunk-B2CPS4QU.js";
17
18
  import "./chunk-K3NQKI34.js";
18
19
  export {
19
20
  deliverMessage,
20
- extractTextContent
21
+ extractTextContent,
22
+ recordInbound
21
23
  };
@@ -3,7 +3,7 @@ import {
3
3
  MindManager,
4
4
  getMindManager,
5
5
  initMindManager
6
- } from "./chunk-VNVCRVYI.js";
6
+ } from "./chunk-M5CNKH4J.js";
7
7
  import "./chunk-PHU4DEAJ.js";
8
8
  import "./chunk-SGPEZ32F.js";
9
9
  import "./chunk-YUIHSKR6.js";
@@ -4,7 +4,7 @@ import "./chunk-K3NQKI34.js";
4
4
  // package.json
5
5
  var package_default = {
6
6
  name: "volute",
7
- version: "0.22.0",
7
+ version: "0.23.0",
8
8
  description: "CLI for creating and managing self-modifying AI minds powered by the Claude Agent SDK",
9
9
  type: "module",
10
10
  license: "MIT",
@@ -5,11 +5,11 @@ import {
5
5
  getSleepManagerIfReady,
6
6
  initSleepManager,
7
7
  matchesGlob
8
- } from "./chunk-OSFGKF2T.js";
8
+ } from "./chunk-ISWZ6QUK.js";
9
9
  import "./chunk-HFCBO2GL.js";
10
10
  import "./chunk-HGCDWKSP.js";
11
11
  import "./chunk-A4S7H6G6.js";
12
- import "./chunk-VNVCRVYI.js";
12
+ import "./chunk-M5CNKH4J.js";
13
13
  import "./chunk-XLC342FO.js";
14
14
  import "./chunk-PHU4DEAJ.js";
15
15
  import "./chunk-SGPEZ32F.js";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  readGlobalConfig,
4
4
  run
5
- } from "./chunk-JNFRY2WU.js";
5
+ } from "./chunk-JG4CCJOA.js";
6
6
  import "./chunk-VT5QODNE.js";
7
7
  import "./chunk-D424ZQGI.js";
8
8
  import "./chunk-JTDFJWI2.js";
@@ -4,11 +4,11 @@ import {
4
4
  } from "./chunk-AKPFNL7L.js";
5
5
  import {
6
6
  deliverMessage
7
- } from "./chunk-OSFGKF2T.js";
7
+ } from "./chunk-ISWZ6QUK.js";
8
8
  import "./chunk-HFCBO2GL.js";
9
9
  import "./chunk-HGCDWKSP.js";
10
10
  import "./chunk-A4S7H6G6.js";
11
- import "./chunk-VNVCRVYI.js";
11
+ import "./chunk-M5CNKH4J.js";
12
12
  import "./chunk-XLC342FO.js";
13
13
  import "./chunk-PHU4DEAJ.js";
14
14
  import "./chunk-SGPEZ32F.js";