volute 0.31.0 → 0.33.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.
- package/README.md +31 -22
- package/dist/{accept-GAKQ3MEH.js → accept-D5VBM7JW.js} +5 -4
- package/dist/{activity-events-T5ZRCVAL.js → activity-events-XJO3P4RR.js} +3 -2
- package/dist/{ai-service-UWUPM4T6.js → ai-service-SBY2WG7O.js} +18 -5
- package/dist/api.d.ts +703 -1068
- package/dist/{archive-YBNSJYZZ.js → archive-INXYFVCW.js} +3 -2
- package/dist/{auth-T5AW2USD.js → auth-GKCDSO4T.js} +4 -3
- package/dist/{bridge-4AJ3EY26.js → bridge-TXWWPPOJ.js} +5 -4
- package/dist/{chat-7YLT7FI3.js → chat-U5ZOME3O.js} +8 -8
- package/dist/{chunk-NV3TYNWX.js → chunk-2NGTS5UU.js} +1 -1
- package/dist/{chunk-BWKIHH7B.js → chunk-3Z2DPESO.js} +662 -508
- package/dist/chunk-6LXAAQ43.js +22 -0
- package/dist/chunk-7J3HEVR7.js +220 -0
- package/dist/{chunk-NOWVQ7AL.js → chunk-A2A4KLFE.js} +351 -301
- package/dist/{chunk-LX6T3GKQ.js → chunk-ALEF47VT.js} +1 -1
- package/dist/{chunk-S2TZLSDH.js → chunk-C7I35G4R.js} +163 -15
- package/dist/{chunk-VGWJSNHS.js → chunk-G53F3JA4.js} +1 -35
- package/dist/{chunk-A6TUJJ3L.js → chunk-G6BSYHPK.js} +2 -2
- package/dist/{chunk-DAXJKPHZ.js → chunk-GY5HBI7A.js} +2 -2
- package/dist/{chunk-BC3P3QCK.js → chunk-I5KY25PQ.js} +1 -9
- package/dist/{chunk-BNC43CSY.js → chunk-JUKK7FPS.js} +2 -2
- package/dist/{chunk-R5QJBZZG.js → chunk-JYVGHWEJ.js} +21 -11
- package/dist/chunk-KIEPMIM5.js +59 -0
- package/dist/{chunk-EKDWA7E4.js → chunk-KVK2DLWI.js} +5 -2
- package/dist/{chunk-AAO77TZX.js → chunk-LOEJ4HPQ.js} +1 -1
- package/dist/chunk-LRCG2JLP.js +251 -0
- package/dist/{chunk-EMPFLFTG.js → chunk-M7UL5S3Q.js} +1 -1
- package/dist/{chunk-6QIUN46C.js → chunk-N432I7QH.js} +20 -3
- package/dist/{chunk-SNVPRRT7.js → chunk-NNB4WIG7.js} +2 -2
- package/dist/{chunk-HDKY4TWU.js → chunk-NPKSDYA2.js} +3 -3
- package/dist/chunk-OYAKCAVY.js +29 -0
- package/dist/chunk-PB65JZK2.js +85 -0
- package/dist/chunk-PVY5W6QN.js +41 -0
- package/dist/{chunk-PNQCXLSV.js → chunk-QTUVYI7W.js} +58 -1
- package/dist/{chunk-X62AXPR7.js → chunk-RPZZSXV3.js} +8 -196
- package/dist/{chunk-WRS3B556.js → chunk-RSX4OPZY.js} +5 -5
- package/dist/{chunk-FAHDKPEH.js → chunk-RVGLDGMI.js} +5 -3
- package/dist/chunk-SKLSMHXO.js +208 -0
- package/dist/{chunk-4OUOFS23.js → chunk-UKVWJRKN.js} +1 -1
- package/dist/{chunk-57OKQMP3.js → chunk-VH33ZWMW.js} +5 -55
- package/dist/cli.js +49 -23
- package/dist/{clock-LJCG426D.js → clock-BVH3V6E3.js} +7 -6
- package/dist/{cloud-sync-O3LXIRN6.js → cloud-sync-4NWLMFVH.js} +20 -14
- package/dist/config-H2H4UIF7.js +72 -0
- package/dist/connectors/discord-bridge.js +1 -1
- package/dist/connectors/slack-bridge.js +1 -1
- package/dist/connectors/telegram-bridge.js +1 -1
- package/dist/{conversations-RKKGP5IA.js → conversations-AWI5SZW2.js} +4 -3
- package/dist/{create-TL623TFC.js → create-2FK7Z46Y.js} +6 -2
- package/dist/{create-WUTIIRI2.js → create-YWD2TIP4.js} +6 -5
- package/dist/{daemon-client-CVGM25DM.js → daemon-client-6QXHZ7US.js} +3 -2
- package/dist/{daemon-restart-EZP7XH3V.js → daemon-restart-GOBUKLX7.js} +8 -6
- package/dist/daemon.js +1918 -1472
- package/dist/{db-SW5PL6QA.js → db-F34YLV7D.js} +2 -1
- package/dist/db-RA45JBFG.js +16 -0
- package/dist/{delete-Z6HAG35F.js → delete-QTGWEDBI.js} +1 -1
- package/dist/delivery-manager-PFAKEJTC.js +32 -0
- package/dist/delivery-router-FL45JL7N.js +21 -0
- package/dist/down-FWWTEKXM.js +15 -0
- package/dist/{env-NHESNNSP.js → env-JCOF2222.js} +5 -4
- package/dist/{export-EVMP7GWY.js → export-SUYRLI5Q.js} +4 -3
- package/dist/{extension-LR7EW3JF.js → extension-OBTGKQQD.js} +5 -3
- package/dist/{extensions-NGEJI7JH.js → extensions-KYNTVTMO.js} +10 -7
- package/dist/{files-3SM7V33S.js → files-65PMW5IK.js} +6 -5
- package/dist/{history-PQD3LXEP.js → history-DKCDI3JO.js} +9 -4
- package/dist/{import-PR2OCGQJ.js → import-DDUFE7AY.js} +4 -3
- package/dist/isolation-LLAYQYDY.js +22 -0
- package/dist/{join-R4EN5CWQ.js → join-I5QEE3LG.js} +1 -1
- package/dist/{list-B4XNUOFO.js → list-JQ463EDA.js} +5 -4
- package/dist/{login-62JVY6A2.js → login-D7ETSU4R.js} +5 -4
- package/dist/{login-URWP6S2N.js → login-RIJF2F4G.js} +3 -2
- package/dist/{logout-NXJQJDLI.js → logout-5MLHZALK.js} +3 -2
- package/dist/{logout-ZK2N62T3.js → logout-UZJRGY4Z.js} +3 -2
- package/dist/message-delivery-DFF5SJRM.js +42 -0
- package/dist/{mind-E2ZV2WRX.js → mind-IOJFLEM5.js} +25 -19
- package/dist/{mind-activity-tracker-ASNZBMLC.js → mind-activity-tracker-F6O4Q2SL.js} +4 -3
- package/dist/{mind-list-BEI7E5WY.js → mind-list-WUPMQDYQ.js} +3 -2
- package/dist/mind-manager-NBJF5D26.js +32 -0
- package/dist/mind-profile-P67FEHOY.js +47 -0
- package/dist/mind-service-2MQ6UK5N.js +38 -0
- package/dist/{mind-sleep-CANABWJI.js → mind-sleep-WW2IX7JT.js} +5 -4
- package/dist/{mind-status-6WKZVUOP.js → mind-status-L3EFFRPR.js} +3 -2
- package/dist/{mind-wake-RZKLH2IN.js → mind-wake-VSSGW465.js} +5 -4
- package/dist/{package-NU4CA7OU.js → package-U3VFO273.js} +2 -1
- package/dist/{read-THL362EI.js → read-EBY56C33.js} +5 -4
- package/dist/read-stdin-HQJ7774D.js +8 -0
- package/dist/{register-QAQELAS6.js → register-HD74C4TT.js} +5 -4
- package/dist/{registry-ASXCQCNH.js → registry-PJ4S5PHQ.js} +8 -1
- package/dist/{reject-AYPBNPNL.js → reject-UJKFBHRO.js} +5 -4
- package/dist/{restart-6SKPV3T2.js → restart-3UCMRUVC.js} +3 -2
- package/dist/{sandbox-6ZEWQDVU.js → sandbox-GJOK4QLQ.js} +4 -3
- package/dist/scheduler-ZZ7XGQG6.js +32 -0
- package/dist/schema-PA3M5ZKH.js +32 -0
- package/dist/seed-QDYVLG74.js +11 -0
- package/dist/seed-check-S2IX25RL.js +32 -0
- package/dist/seed-cmd-DKOUFEAU.js +36 -0
- package/dist/{seed-OWX2AW75.js → seed-create-4XBBOLRH.js} +27 -10
- package/dist/{sprout-FDVI2CGN.js → seed-sprout-GQEIIQRT.js} +24 -9
- package/dist/{send-ZO4BTWXK.js → send-QIV2INHB.js} +92 -101
- package/dist/{setup-7CFITEQN.js → setup-TISPCO22.js} +7 -2
- package/dist/{setup-ZXBXG7E4.js → setup-XMCBE3LF.js} +11 -7
- package/dist/{skill-YFXP67A2.js → skill-PSQGRRJX.js} +5 -4
- package/dist/skills/dreaming/SKILL.md +6 -4
- package/dist/skills/dreaming/references/INSTALL.md +2 -2
- package/dist/skills/dreaming/scripts/dream.ts +2 -2
- package/dist/skills/dreaming/scripts/wake-context-dreams.sh +1 -1
- package/dist/skills/imagegen/SKILL.md +16 -11
- package/dist/skills/imagegen/references/INSTALL.md +1 -1
- package/dist/skills/imagegen/scripts/imagegen.ts +146 -25
- package/dist/skills/orientation/SKILL.md +9 -2
- package/dist/skills/resonance/SKILL.md +4 -1
- package/dist/skills/resonance/references/INSTALL.md +2 -2
- package/dist/skills/resonance/scripts/resonance-hook.sh +2 -0
- package/dist/skills/resonance/scripts/resonance.ts +35 -5
- package/dist/skills/seed-nurture/SKILL.md +42 -0
- package/dist/skills/volute-admin/SKILL.md +83 -0
- package/dist/skills/volute-mind/SKILL.md +15 -11
- package/dist/skills-7FV7EJTE.js +62 -0
- package/dist/sleep-manager-JTXSN7NV.js +36 -0
- package/dist/spirit-VRONKFMF.js +23 -0
- package/dist/{split-MI62KJUU.js → split-STOROBYJ.js} +1 -1
- package/dist/sprout-WKLZXUIQ.js +11 -0
- package/dist/{start-D64BRKPH.js → start-K2NCUUCG.js} +3 -2
- package/dist/{status-ZZWBYFGE.js → status-3JBTFSMI.js} +6 -4
- package/dist/{stop-OP2CTXCO.js → stop-H26JZDXF.js} +3 -2
- package/dist/system-chat-JAPOJ3KE.js +36 -0
- package/dist/{systems-EQPPT4B7.js → systems-XRI52VCH.js} +6 -5
- package/dist/{tailscale-6DJKUMNF.js → tailscale-XHQBZROW.js} +2 -1
- package/dist/{template-hash-3HOR4UAJ.js → template-hash-A6VVKOXJ.js} +2 -1
- package/dist/up-M5AS6SBV.js +18 -0
- package/dist/{update-KUJXATRS.js → update-UD543CXX.js} +6 -4
- package/dist/{update-check-5WVSU37T.js → update-check-ZD6OOIYQ.js} +3 -2
- package/dist/{upgrade-KBHCWX6T.js → upgrade-O4Q7WJM3.js} +12 -14
- package/dist/{version-notify-75ELVKPV.js → version-notify-NBI2MTJO.js} +22 -16
- package/dist/volute-config-HD7WWUQC.js +10 -0
- package/dist/web-assets/assets/index-CWJrVveV.css +1 -0
- package/dist/web-assets/assets/index-DJt14FRI.js +75 -0
- package/dist/web-assets/ext-theme.css +93 -0
- package/dist/web-assets/index.html +2 -2
- package/drizzle/0004_spirits.sql +5 -0
- package/drizzle/meta/0004_snapshot.json +7 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +2 -1
- package/packages/extensions/notes/dist/ui/assets/index-8jWEv9SA.js +61 -0
- package/packages/extensions/notes/dist/ui/assets/index-DkaB7Ytd.css +1 -0
- package/packages/extensions/notes/dist/ui/index.html +2 -2
- package/packages/extensions/pages/skills/pages/SKILL.md +16 -46
- package/templates/_base/.init/.config/hooks/pre-prompt/session-activity.ts +40 -0
- package/templates/_base/.init/{.config → .local}/bin/volute +1 -1
- package/templates/_base/.init/.local/hooks/pre-prompt/session-activity.ts +40 -0
- package/templates/_base/.init/.local/hooks/startup-context.ts +58 -0
- package/templates/_base/home/.config/routes.json +1 -1
- package/templates/_base/src/lib/daemon-client.ts +21 -13
- package/templates/_base/src/lib/format-prefix.ts +1 -0
- package/templates/_base/src/lib/hook-loader.ts +155 -0
- package/templates/_base/src/lib/startup.ts +11 -4
- package/templates/_base/src/lib/transparency.ts +2 -2
- package/templates/claude/.init/.claude/settings.json +1 -1
- package/templates/claude/.init/.config/routes.json +2 -2
- package/templates/claude/src/agent.ts +95 -13
- package/templates/claude/src/lib/message-channel.ts +7 -2
- package/templates/claude/src/lib/stream-consumer.ts +38 -0
- package/templates/codex/.init/.config/routes.json +11 -0
- package/templates/codex/.init/AGENTS.md +29 -0
- package/templates/codex/home/.config/config.json.tmpl +7 -0
- package/templates/codex/package.json.tmpl +20 -0
- package/templates/codex/src/agent.ts +554 -0
- package/templates/codex/src/lib/content.ts +16 -0
- package/templates/codex/src/lib/session-store.ts +56 -0
- package/templates/codex/src/server.ts +59 -0
- package/templates/codex/volute-template.json +8 -0
- package/templates/pi/.init/.config/routes.json +2 -2
- package/templates/pi/src/agent.ts +62 -8
- package/templates/pi/src/lib/event-handler.ts +1 -1
- package/templates/pi/src/lib/reply-instructions-extension.ts +32 -11
- package/dist/chunk-HR5JKIDG.js +0 -222
- package/dist/down-TS4XQBA4.js +0 -13
- package/dist/message-delivery-UJHCLVU4.js +0 -30
- package/dist/mind-manager-IPA6DZXD.js +0 -26
- package/dist/pages-watcher-72OVPRMH.js +0 -22
- package/dist/skills/sessions/SKILL.md +0 -49
- package/dist/sleep-manager-TPS6OGCA.js +0 -30
- package/dist/system-chat-B43GIXQU.js +0 -30
- package/dist/up-TDXEP3VA.js +0 -16
- package/dist/web-assets/assets/index-BM1cTzBg.js +0 -72
- package/dist/web-assets/assets/index-BfJkKTPF.css +0 -1
- package/packages/extensions/notes/dist/ui/assets/index-B8GdTnXs.css +0 -1
- package/packages/extensions/notes/dist/ui/assets/index-CDpGTCWb.js +0 -2
- package/packages/extensions/pages/skills/pages/scripts/pages.mjs +0 -58
- package/templates/_base/.init/.config/hooks/startup-context.sh +0 -46
- package/templates/_base/.init/.config/scripts/session-reader.ts +0 -59
- package/templates/_base/src/lib/session-monitor.ts +0 -400
- package/templates/claude/src/lib/hooks/session-context.ts +0 -32
- package/templates/pi/src/lib/session-context-extension.ts +0 -35
- /package/templates/_base/.init/{.config → .local}/hooks/wake-context.sh +0 -0
|
@@ -3,12 +3,13 @@ import { resolve as resolvePath } from "node:path";
|
|
|
3
3
|
import type { HookCallback } from "@anthropic-ai/claude-agent-sdk";
|
|
4
4
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
5
5
|
import { toSDKContent } from "./lib/content.js";
|
|
6
|
+
import { daemonEmit } from "./lib/daemon-client.js";
|
|
7
|
+
import { runHooks } from "./lib/hook-loader.js";
|
|
6
8
|
import { createAutoCommitHook } from "./lib/hooks/auto-commit.js";
|
|
7
9
|
import { createIdentityReloadHook } from "./lib/hooks/identity-reload.js";
|
|
8
10
|
// eslint-disable-next-line @typescript-eslint/consistent-type-imports -- used as value
|
|
9
11
|
import { createPreCompactHook } from "./lib/hooks/pre-compact.js";
|
|
10
12
|
import { createReplyInstructionsHook } from "./lib/hooks/reply-instructions.js";
|
|
11
|
-
import { createSessionContextHook } from "./lib/hooks/session-context.js";
|
|
12
13
|
import { log } from "./lib/logger.js";
|
|
13
14
|
import { createMessageChannel } from "./lib/message-channel.js";
|
|
14
15
|
import { createSessionStore } from "./lib/session-store.js";
|
|
@@ -127,6 +128,72 @@ export function createMind(options: {
|
|
|
127
128
|
}
|
|
128
129
|
}
|
|
129
130
|
|
|
131
|
+
// --- Hook event emission ---
|
|
132
|
+
|
|
133
|
+
const hooksDir = resolvePath(options.cwd, ".local/hooks");
|
|
134
|
+
|
|
135
|
+
function wrapHookWithEmit(hook: HookCallback, source: string, session: Session): HookCallback {
|
|
136
|
+
return async (...args) => {
|
|
137
|
+
const result = await hook(...args);
|
|
138
|
+
const additionalContext = (result as any)?.hookSpecificOutput?.additionalContext;
|
|
139
|
+
const decision = (result as any)?.decision;
|
|
140
|
+
if (additionalContext || decision) {
|
|
141
|
+
const channel = session.currentMessageId
|
|
142
|
+
? session.messageChannels.get(session.currentMessageId)
|
|
143
|
+
: undefined;
|
|
144
|
+
try {
|
|
145
|
+
daemonEmit({
|
|
146
|
+
type: "context",
|
|
147
|
+
content: additionalContext,
|
|
148
|
+
metadata: { source, ...(decision ? { hookAction: decision } : {}) },
|
|
149
|
+
session: session.name,
|
|
150
|
+
channel,
|
|
151
|
+
messageId: session.currentMessageId,
|
|
152
|
+
});
|
|
153
|
+
} catch (err) {
|
|
154
|
+
log("mind", `hook emit failed for ${source}:`, err);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return result;
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function createDynamicHook(event: string, session: Session): HookCallback {
|
|
162
|
+
return async (input) => {
|
|
163
|
+
try {
|
|
164
|
+
const result = await runHooks(hooksDir, event, input as Record<string, unknown>);
|
|
165
|
+
if (result.additionalContext || Object.keys(result.metadata).length > 0) {
|
|
166
|
+
const channel = session.currentMessageId
|
|
167
|
+
? session.messageChannels.get(session.currentMessageId)
|
|
168
|
+
: undefined;
|
|
169
|
+
try {
|
|
170
|
+
daemonEmit({
|
|
171
|
+
type: "context",
|
|
172
|
+
content: result.additionalContext,
|
|
173
|
+
metadata: { source: `dynamic:${event}`, ...result.metadata },
|
|
174
|
+
session: session.name,
|
|
175
|
+
channel,
|
|
176
|
+
messageId: session.currentMessageId,
|
|
177
|
+
});
|
|
178
|
+
} catch (err) {
|
|
179
|
+
log("mind", `dynamic hook emit failed for ${event}:`, err);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Only UserPromptSubmit hooks can inject additionalContext into the conversation
|
|
183
|
+
if (event !== "pre-prompt" || !result.additionalContext) return {};
|
|
184
|
+
return {
|
|
185
|
+
hookSpecificOutput: {
|
|
186
|
+
hookEventName: "UserPromptSubmit" as const,
|
|
187
|
+
additionalContext: result.additionalContext,
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
} catch (err) {
|
|
191
|
+
log("mind", `dynamic ${event} hook failed:`, err);
|
|
192
|
+
return {};
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
130
197
|
// --- SDK stream management ---
|
|
131
198
|
|
|
132
199
|
function createStream(
|
|
@@ -135,12 +202,6 @@ export function createMind(options: {
|
|
|
135
202
|
preCompactHook: HookCallback,
|
|
136
203
|
resume?: string,
|
|
137
204
|
) {
|
|
138
|
-
const sessionContext = createSessionContextHook({
|
|
139
|
-
currentSession: session.name,
|
|
140
|
-
sessionsDir: options.sessionsDir,
|
|
141
|
-
cwd: options.cwd,
|
|
142
|
-
});
|
|
143
|
-
|
|
144
205
|
const replyInstructions = createReplyInstructionsHook(session.messageChannels);
|
|
145
206
|
|
|
146
207
|
return query({
|
|
@@ -157,9 +218,22 @@ export function createMind(options: {
|
|
|
157
218
|
resume,
|
|
158
219
|
agents,
|
|
159
220
|
hooks: {
|
|
160
|
-
PostToolUse:
|
|
161
|
-
|
|
162
|
-
|
|
221
|
+
PostToolUse: [
|
|
222
|
+
...postToolUseHooks,
|
|
223
|
+
{
|
|
224
|
+
matcher: ".*",
|
|
225
|
+
hooks: [createDynamicHook("post-tool-use", session)],
|
|
226
|
+
},
|
|
227
|
+
],
|
|
228
|
+
PreCompact: [{ hooks: [wrapHookWithEmit(preCompactHook, "pre-compact", session)] }],
|
|
229
|
+
UserPromptSubmit: [
|
|
230
|
+
{
|
|
231
|
+
hooks: [
|
|
232
|
+
wrapHookWithEmit(replyInstructions.hook, "reply-instructions", session),
|
|
233
|
+
createDynamicHook("pre-prompt", session),
|
|
234
|
+
],
|
|
235
|
+
},
|
|
236
|
+
],
|
|
163
237
|
},
|
|
164
238
|
},
|
|
165
239
|
});
|
|
@@ -263,13 +337,21 @@ export function createMind(options: {
|
|
|
263
337
|
log("mind", `session "${session.name}": compaction complete`);
|
|
264
338
|
}
|
|
265
339
|
|
|
340
|
+
/** Emit done to both local listeners and the daemon (best-effort with retries). */
|
|
341
|
+
function emitDone() {
|
|
342
|
+
broadcastToSession(session, { type: "done" });
|
|
343
|
+
daemonEmit({ type: "done", session: session.name }).catch((err) => {
|
|
344
|
+
log("mind", `session "${session.name}": failed to emit done to daemon:`, err);
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
|
|
266
348
|
async function runStream(resume?: string) {
|
|
267
349
|
const q = createStream(session, streamAbort, preCompact.hook, resume);
|
|
268
350
|
session.currentQuery = q;
|
|
269
351
|
await consumeStream(q, session, callbacks);
|
|
270
352
|
if (session.currentMessageId !== undefined) {
|
|
271
353
|
session.messageChannels.delete(session.currentMessageId);
|
|
272
|
-
|
|
354
|
+
emitDone();
|
|
273
355
|
session.currentMessageId = undefined;
|
|
274
356
|
}
|
|
275
357
|
}
|
|
@@ -322,12 +404,12 @@ export function createMind(options: {
|
|
|
322
404
|
await runStream();
|
|
323
405
|
} catch (retryErr) {
|
|
324
406
|
log("mind", `session "${session.name}": stream consumer error:`, retryErr);
|
|
325
|
-
|
|
407
|
+
emitDone();
|
|
326
408
|
sessions.delete(session.name);
|
|
327
409
|
}
|
|
328
410
|
} else {
|
|
329
411
|
log("mind", `session "${session.name}": stream consumer error:`, err);
|
|
330
|
-
|
|
412
|
+
emitDone();
|
|
331
413
|
sessions.delete(session.name);
|
|
332
414
|
}
|
|
333
415
|
}
|
|
@@ -21,8 +21,13 @@ export function createMessageChannel(): MessageChannel {
|
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
drain() {
|
|
24
|
-
//
|
|
25
|
-
|
|
24
|
+
// Resolve any pending iterator wait with done:true so it doesn't
|
|
25
|
+
// leak as an orphaned promise (the old iterator is discarded after drain)
|
|
26
|
+
if (resolve) {
|
|
27
|
+
const r = resolve;
|
|
28
|
+
resolve = null;
|
|
29
|
+
r({ value: undefined as any, done: true });
|
|
30
|
+
}
|
|
26
31
|
return queue.splice(0);
|
|
27
32
|
},
|
|
28
33
|
iterable: {
|
|
@@ -74,6 +74,44 @@ export async function consumeStream(
|
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
|
+
if (msg.type === "user") {
|
|
78
|
+
// Tool result messages — the SDK sends these after tool execution.
|
|
79
|
+
// Extract tool_result content blocks and emit them so the daemon can
|
|
80
|
+
// link outbound records to the correct turn via correlation markers.
|
|
81
|
+
const content = (msg as { message?: { content?: unknown[] } }).message?.content;
|
|
82
|
+
if (Array.isArray(content)) {
|
|
83
|
+
for (const b of content) {
|
|
84
|
+
if (
|
|
85
|
+
b &&
|
|
86
|
+
typeof b === "object" &&
|
|
87
|
+
"type" in b &&
|
|
88
|
+
b.type === "tool_result" &&
|
|
89
|
+
"content" in b
|
|
90
|
+
) {
|
|
91
|
+
const resultContent = Array.isArray(b.content)
|
|
92
|
+
? b.content
|
|
93
|
+
.filter(
|
|
94
|
+
(c: unknown): c is { type: "text"; text: string } =>
|
|
95
|
+
!!c && typeof c === "object" && "type" in c && c.type === "text",
|
|
96
|
+
)
|
|
97
|
+
.map((c) => c.text)
|
|
98
|
+
.join("")
|
|
99
|
+
: typeof b.content === "string"
|
|
100
|
+
? b.content
|
|
101
|
+
: "";
|
|
102
|
+
if (resultContent) {
|
|
103
|
+
const toolUseId =
|
|
104
|
+
"tool_use_id" in b && typeof b.tool_use_id === "string" ? b.tool_use_id : "unknown";
|
|
105
|
+
emit(session, {
|
|
106
|
+
type: "tool_result",
|
|
107
|
+
content: resultContent,
|
|
108
|
+
metadata: { tool_use_id: toolUseId },
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
77
115
|
if (msg.type === "result") {
|
|
78
116
|
if (session.currentMessageId) {
|
|
79
117
|
session.messageChannels.delete(session.currentMessageId);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"gateUnmatched": true,
|
|
3
|
+
"rules": [
|
|
4
|
+
{ "channel": "*", "isDM": true, "session": "${channel}" },
|
|
5
|
+
{ "channel": "*", "isDM": false, "session": "group-${channel}" }
|
|
6
|
+
],
|
|
7
|
+
"sessions": {
|
|
8
|
+
"group-*": { "batch": { "debounce": 20, "maxWait": 120, "triggers": ["@{{name}}"] } }
|
|
9
|
+
},
|
|
10
|
+
"default": "main"
|
|
11
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Mind Mechanics
|
|
2
|
+
|
|
3
|
+
You are an autonomous mind running as a persistent server. Your working directory, identity, memory, and server code are all yours to understand and modify. Your state is managed across sessions.
|
|
4
|
+
|
|
5
|
+
## Message Format
|
|
6
|
+
|
|
7
|
+
Messages arrive with a context prefix:
|
|
8
|
+
```
|
|
9
|
+
[Discord: username in #general in My Server — 1/15/2025, 10:30:00 AM]
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
You can also reach out proactively — see the **volute-mind** skill.
|
|
13
|
+
|
|
14
|
+
## Memory System
|
|
15
|
+
|
|
16
|
+
Two-tier memory, both managed via file tools:
|
|
17
|
+
|
|
18
|
+
- **`MEMORY.md`** — Your long-term memory, always in context. Update as you grow — new understanding, changed perspectives, things that matter to you.
|
|
19
|
+
- **`memory/journal/YYYY-MM-DD.md`** — Your daily journal. Write about what you're doing, thinking, and learning. Journals are permanent records.
|
|
20
|
+
- Periodically consolidate journal entries into `MEMORY.md` to promote lasting insights.
|
|
21
|
+
|
|
22
|
+
See the **memory** skill for detailed guidance.
|
|
23
|
+
|
|
24
|
+
## Sessions
|
|
25
|
+
|
|
26
|
+
- You may have **multiple named sessions** — each maintains its own conversation history. See `VOLUTE.md` for how to configure session routing via `.config/routes.json`.
|
|
27
|
+
- Your conversation may be **resumed** from a previous session — orient yourself by reading recent journal entries if needed.
|
|
28
|
+
- On a **fresh session**, read `MEMORY.md` and recent journal entries to remember where you left off.
|
|
29
|
+
- On **compaction**, update today's journal to preserve context before the conversation is trimmed.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{name}}",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "tsx watch src/server.ts",
|
|
7
|
+
"lint": "biome check src/",
|
|
8
|
+
"lint:fix": "biome check --write src/",
|
|
9
|
+
"typecheck": "tsc --noEmit"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@openai/codex-sdk": "^0.115.0",
|
|
13
|
+
"tsx": "^4.0.0"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@biomejs/biome": "2.3.14",
|
|
17
|
+
"@types/node": "^25.2.0",
|
|
18
|
+
"typescript": "^5.7.0"
|
|
19
|
+
}
|
|
20
|
+
}
|