volute 0.20.0 → 0.22.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 +7 -7
- package/dist/{activity-events-OMXKXD5N.js → activity-events-3WHHCOBB.js} +3 -4
- package/dist/api.d.ts +4294 -0
- package/dist/{archive-ZCFOSTKB.js → archive-4ZQYK5MN.js} +4 -2
- package/dist/auth-HM2RSPY7.js +37 -0
- package/dist/{channel-PUQKGSQM.js → channel-BOOMFULW.js} +2 -2
- package/dist/{chunk-UU7A7KLB.js → chunk-A4S7H6G6.js} +5 -7
- package/dist/chunk-AKPFNL7L.js +148 -0
- package/dist/{chunk-EBGCNDMM.js → chunk-B2CPS4QU.js} +128 -114
- package/dist/chunk-G5KRTU2F.js +76 -0
- package/dist/{chunk-FCDU5BFX.js → chunk-HFCBO2GL.js} +2 -2
- package/dist/{chunk-GZ7DW4YL.js → chunk-HGCDWKSP.js} +2 -2
- package/dist/{chunk-7UFKREVW.js → chunk-JNFRY2WU.js} +2 -2
- package/dist/{chunk-DYZGP3EW.js → chunk-JTDFJWI2.js} +2 -1
- package/dist/{chunk-WC6ZHVRL.js → chunk-KFI7TQJ6.js} +2 -2
- package/dist/{chunk-AW7P4EVV.js → chunk-KTJGZ7M7.js} +55 -7
- package/dist/{chunk-OGXOMR65.js → chunk-NWPT4ASZ.js} +1 -1
- package/dist/{chunk-SCUDS4US.js → chunk-ON3FF5JA.js} +1 -1
- package/dist/chunk-OSFGKF2T.js +2651 -0
- package/dist/{chunk-TIWH32HP.js → chunk-PHHKNGA3.js} +3 -3
- package/dist/{chunk-VDWCHYTS.js → chunk-PHU4DEAJ.js} +1 -1
- package/dist/{chunk-7NO7EV5Z.js → chunk-QIXPN3OO.js} +2 -2
- package/dist/{chunk-O6ASDHFO.js → chunk-RK627D57.js} +40 -63
- package/dist/{chunk-NSE7VJQA.js → chunk-SGPEZ32F.js} +29 -1
- package/dist/{chunk-IKMY5X76.js → chunk-TFS25FIM.js} +12 -9
- package/dist/{chunk-PUVXOZ6T.js → chunk-VNVCRVYI.js} +118 -69
- package/dist/{chunk-32VR2EOH.js → chunk-VT5QODNE.js} +2 -2
- package/dist/{chunk-RHEGSQFJ.js → chunk-WSLPZF72.js} +1 -1
- package/dist/chunk-XLC342FO.js +29 -0
- package/dist/cli.js +57 -119
- package/dist/cloud-sync-C6WRYRVR.js +96 -0
- package/dist/{connector-JBVNZ7VK.js → connector-PYT5UOTZ.js} +6 -6
- package/dist/connectors/discord.js +2 -2
- package/dist/connectors/slack.js +2 -2
- package/dist/connectors/telegram.js +2 -2
- package/dist/{create-HP4OVVHF.js → create-WIDA3M4C.js} +1 -1
- package/dist/{daemon-client-ITWUCNFO.js → daemon-client-ZHCDL4RS.js} +2 -2
- package/dist/{daemon-restart-KPSWNYTH.js → daemon-restart-TPQ2XBRZ.js} +6 -6
- package/dist/daemon.js +2250 -1985
- package/dist/{delete-BSU7K3RY.js → delete-LOIANQGD.js} +1 -1
- package/dist/down-WSUASL5E.js +14 -0
- package/dist/{env-A3LMO777.js → env-4PHIHTF4.js} +2 -2
- package/dist/{export-6QBUOQGC.js → export-XD6PJBQP.js} +19 -8
- package/dist/{file-C57SK5DK.js → file-X4L5TTOL.js} +2 -2
- package/dist/{history-WNK3DFUM.js → history-HTEKRNID.js} +2 -2
- package/dist/{import-XEC34Y4Z.js → import-EAXTHHXL.js} +4 -3
- package/dist/{log-PPPZDVEF.js → log-SRO5Q6AD.js} +2 -2
- package/dist/{login-HNH3EUQV.js → login-UO6AOVEA.js} +4 -4
- package/dist/{logout-I5CB5UZS.js → logout-UKD5LA37.js} +2 -2
- package/dist/{logs-SF2IMJN4.js → logs-HNTNNBDW.js} +2 -2
- package/dist/{merge-33C237A4.js → merge-B6SYTGI7.js} +2 -2
- package/dist/message-delivery-WUS4K4ZC.js +21 -0
- package/dist/{mind-Z7CKD6DG.js → mind-BTXR5B3C.js} +35 -11
- package/dist/{mind-activity-tracker-624QLQLC.js → mind-activity-tracker-PGC3DBJ7.js} +4 -5
- package/dist/{mind-manager-3DMYKZPB.js → mind-manager-P5OBDUKI.js} +5 -6
- package/dist/mind-sleep-FWRBIFBS.js +41 -0
- package/dist/mind-wake-LJK2YU5X.js +36 -0
- package/dist/{package-4NHAVUUI.js → package-A7PEYJI2.js} +10 -1
- package/dist/{pages-4DGQT7ZA.js → pages-YSTRWJR4.js} +6 -6
- package/dist/{publish-TAJUET4I.js → publish-BZNHKUUK.js} +6 -6
- package/dist/{pull-XAEWQJ47.js → pull-GRQAXM2E.js} +2 -2
- package/dist/{register-VSPCMHKX.js → register-U2UO6TC4.js} +5 -5
- package/dist/registry-D2BSQ2X5.js +42 -0
- package/dist/{restart-IQKMCK5M.js → restart-CIDAKGG2.js} +3 -6
- package/dist/{schedule-FFZG23IW.js → schedule-NLR3LZLY.js} +2 -2
- package/dist/{seed-J43YDKXG.js → seed-3H2MRREW.js} +2 -2
- package/dist/{send-KVIZIGCE.js → send-RP2TA7SG.js} +132 -36
- package/dist/{service-LUR7WDO7.js → service-7BFXDI6J.js} +31 -13
- package/dist/{setup-52YRV7VP.js → setup-SSIIXQMI.js} +9 -34
- package/dist/{shared-KO35ZM44.js → shared-2OGT3NSL.js} +4 -4
- package/dist/{skill-BCVNI6TV.js → skill-Q2Y6PQ3L.js} +2 -2
- package/dist/skills/orientation/SKILL.md +2 -2
- package/dist/skills/volute-mind/SKILL.md +5 -5
- package/dist/sleep-manager-3RWUX2ZR.js +27 -0
- package/dist/{sprout-QN7Y4VVO.js → sprout-UKCYBGHK.js} +34 -30
- package/dist/{start-I5JYB65M.js → start-JR6CUUWF.js} +3 -6
- package/dist/{status-D7E5HHBV.js → status-5XDGYHKP.js} +2 -2
- package/dist/{status-4ESFLGH4.js → status-H2MKDN6L.js} +5 -5
- package/dist/{status-FU2PFVVF.js → status-LV34BG6G.js} +3 -3
- package/dist/{stop-NBVKEFQQ.js → stop-VKPGK25U.js} +2 -5
- package/dist/template-hash-BIMA4ILT.js +8 -0
- package/dist/{up-FS7CKM6V.js → up-JKGC7PPF.js} +5 -5
- package/dist/{update-FJIHDJKM.js → update-ELC6MEUT.js} +5 -5
- package/dist/{update-check-MWE5AH4U.js → update-check-F5Z3ALXX.js} +2 -2
- package/dist/{upgrade-AIT24B5I.js → upgrade-GXW2EQY3.js} +12 -3
- package/dist/{variant-63ZWO2W7.js → variant-A4I7PHXS.js} +16 -24
- package/dist/version-notify-5FGUAVSF.js +181 -0
- package/dist/web-assets/assets/index-DWBxl4LO.js +69 -0
- package/dist/web-assets/assets/index-ZqMd1mx1.css +1 -0
- package/dist/web-assets/index.html +2 -2
- package/package.json +10 -1
- package/templates/_base/.init/.config/prompts.json +1 -0
- package/templates/_base/home/.config/config.json.tmpl +4 -1
- package/templates/_base/src/lib/logger.ts +68 -23
- package/templates/_base/src/lib/startup.ts +12 -3
- package/templates/claude/src/agent.ts +150 -29
- package/templates/claude/src/lib/hooks/pre-compact.ts +18 -4
- package/templates/claude/src/lib/message-channel.ts +6 -0
- package/templates/claude/src/lib/stream-consumer.ts +7 -0
- package/templates/claude/src/server.ts +3 -1
- package/templates/pi/home/.config/config.json.tmpl +4 -1
- package/templates/pi/src/agent.ts +87 -0
- package/templates/pi/src/lib/event-handler.ts +13 -1
- package/templates/pi/src/server.ts +3 -1
- package/dist/chunk-5XNT2472.js +0 -36
- package/dist/chunk-FGSYHIS3.js +0 -891
- package/dist/chunk-UJ6GHNR7.js +0 -675
- package/dist/db-C2CJ46ZU.js +0 -10
- package/dist/delivery-manager-CSG7LXA4.js +0 -16
- package/dist/down-ZY35KMHR.js +0 -14
- package/dist/schema-GFH6RV3W.js +0 -26
- package/dist/variants-JAGWGBXG.js +0 -26
- package/dist/web-assets/assets/index-CUZTZzaW.js +0 -64
- package/dist/web-assets/assets/index-adVuCkqy.css +0 -1
|
@@ -2,6 +2,7 @@ import type { SDKUserMessage } from "@anthropic-ai/claude-agent-sdk";
|
|
|
2
2
|
|
|
3
3
|
export type MessageChannel = {
|
|
4
4
|
push: (msg: SDKUserMessage) => void;
|
|
5
|
+
drain: () => SDKUserMessage[];
|
|
5
6
|
iterable: AsyncIterable<SDKUserMessage>;
|
|
6
7
|
};
|
|
7
8
|
|
|
@@ -19,6 +20,11 @@ export function createMessageChannel(): MessageChannel {
|
|
|
19
20
|
queue.push(msg);
|
|
20
21
|
}
|
|
21
22
|
},
|
|
23
|
+
drain() {
|
|
24
|
+
// Clear any pending iterator wait so it doesn't consume a message after drain
|
|
25
|
+
resolve = null;
|
|
26
|
+
return queue.splice(0);
|
|
27
|
+
},
|
|
22
28
|
iterable: {
|
|
23
29
|
[Symbol.asyncIterator]() {
|
|
24
30
|
return {
|
|
@@ -15,6 +15,7 @@ export type StreamCallbacks = {
|
|
|
15
15
|
onSessionId?: (sessionId: string) => void;
|
|
16
16
|
broadcast: (event: VoluteEvent) => void;
|
|
17
17
|
onTurnEnd?: () => void;
|
|
18
|
+
onContextTokens?: (tokens: number) => void;
|
|
18
19
|
};
|
|
19
20
|
|
|
20
21
|
// Loaded once at startup — mind restarts on config changes
|
|
@@ -50,6 +51,12 @@ export async function consumeStream(
|
|
|
50
51
|
callbacks.onSessionId?.(msg.session_id as string);
|
|
51
52
|
}
|
|
52
53
|
if (msg.type === "assistant") {
|
|
54
|
+
const usage = msg.message.usage as unknown as Record<string, unknown> | undefined;
|
|
55
|
+
const inputTokens = (usage?.input_tokens as number) ?? 0;
|
|
56
|
+
const cacheCreation = (usage?.cache_creation_input_tokens as number) ?? 0;
|
|
57
|
+
const cacheRead = (usage?.cache_read_input_tokens as number) ?? 0;
|
|
58
|
+
const contextTokens = inputTokens + cacheCreation + cacheRead;
|
|
59
|
+
if (contextTokens) callbacks.onContextTokens?.(contextTokens);
|
|
53
60
|
for (const b of msg.message.content) {
|
|
54
61
|
if (b.type === "thinking" && "thinking" in b && b.thinking) {
|
|
55
62
|
const text = b.thinking as string;
|
|
@@ -3,7 +3,7 @@ import { resolve } from "node:path";
|
|
|
3
3
|
import { createMind } from "./agent.js";
|
|
4
4
|
import { daemonRestart } from "./lib/daemon-client.js";
|
|
5
5
|
import { createFileHandlerResolver } from "./lib/file-handler.js";
|
|
6
|
-
import { log } from "./lib/logger.js";
|
|
6
|
+
import { log, setLevel } from "./lib/logger.js";
|
|
7
7
|
import { createRouter } from "./lib/router.js";
|
|
8
8
|
import {
|
|
9
9
|
loadConfig,
|
|
@@ -16,6 +16,7 @@ import { createVoluteServer } from "./lib/volute-server.js";
|
|
|
16
16
|
|
|
17
17
|
const { port } = parseArgs();
|
|
18
18
|
const config = loadConfig();
|
|
19
|
+
if (config.logLevel) setLevel(config.logLevel);
|
|
19
20
|
if (config.model) log("server", `using model: ${config.model}`);
|
|
20
21
|
if (config.maxThinkingTokens) log("server", `max thinking tokens: ${config.maxThinkingTokens}`);
|
|
21
22
|
|
|
@@ -40,6 +41,7 @@ const mind = createMind({
|
|
|
40
41
|
maxThinkingTokens: config.maxThinkingTokens,
|
|
41
42
|
sessionsDir,
|
|
42
43
|
compactionMessage: config.compactionMessage,
|
|
44
|
+
maxContextTokens: config.compaction?.maxContextTokens,
|
|
43
45
|
onIdentityReload: async () => {
|
|
44
46
|
log("server", "identity file changed — restarting to reload");
|
|
45
47
|
await mind.waitForCommits();
|
|
@@ -43,12 +43,19 @@ export function createMind(options: {
|
|
|
43
43
|
model?: string;
|
|
44
44
|
thinkingLevel?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
|
|
45
45
|
compactionMessage?: string;
|
|
46
|
+
maxContextTokens?: number;
|
|
46
47
|
}): { resolve: HandlerResolver } {
|
|
47
48
|
const sessions = new Map<string, PiSession>();
|
|
48
49
|
const prompts = loadPrompts();
|
|
49
50
|
const today = new Date().toLocaleDateString("en-CA");
|
|
50
51
|
const compactionMessage =
|
|
51
52
|
options.compactionMessage ?? prompts.compaction_warning.replace("${date}", today);
|
|
53
|
+
const compactionInstructions = prompts.compaction_instructions;
|
|
54
|
+
const maxContextTokens = options.maxContextTokens;
|
|
55
|
+
|
|
56
|
+
if (maxContextTokens) {
|
|
57
|
+
log("mind", `compaction threshold: ${maxContextTokens} tokens`);
|
|
58
|
+
}
|
|
52
59
|
|
|
53
60
|
// Shared setup (created once)
|
|
54
61
|
const modelStr = options.model || process.env.PI_MODEL || "anthropic:claude-sonnet-4-20250514";
|
|
@@ -88,9 +95,35 @@ export function createMind(options: {
|
|
|
88
95
|
|
|
89
96
|
log("mind", `session "${session.name}": ${isEphemeral ? "ephemeral" : "persistent"}`);
|
|
90
97
|
|
|
98
|
+
// Compaction state machine:
|
|
99
|
+
// 1. onContextTokens sets compactionTriggered=true and sends warning
|
|
100
|
+
// 2. onTurnEnd (after warning turn): compactionTriggered -> compactOnNextTurnEnd
|
|
101
|
+
// 3. onTurnEnd (after mind's save turn): compactOnNextTurnEnd -> call compact()
|
|
91
102
|
let compactBlocked = false;
|
|
103
|
+
let manualCompactPending = false;
|
|
104
|
+
let compactionTriggered = false;
|
|
105
|
+
let compactOnNextTurnEnd = false;
|
|
106
|
+
let compactionInProgress = false;
|
|
107
|
+
|
|
108
|
+
function resetCompactionState() {
|
|
109
|
+
compactionTriggered = false;
|
|
110
|
+
compactOnNextTurnEnd = false;
|
|
111
|
+
compactionInProgress = false;
|
|
112
|
+
}
|
|
113
|
+
|
|
92
114
|
const preCompactExtension: ExtensionFactory = (pi) => {
|
|
93
115
|
pi.on("session_before_compact", () => {
|
|
116
|
+
// Our programmatic compact() call (triggered by token threshold) — allow through
|
|
117
|
+
if (manualCompactPending) {
|
|
118
|
+
manualCompactPending = false;
|
|
119
|
+
log(
|
|
120
|
+
"mind",
|
|
121
|
+
`session "${session.name}": allowing manual compaction with custom instructions`,
|
|
122
|
+
);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Auto-compaction: two-pass block (first pass warns mind, second pass allows)
|
|
94
127
|
if (!compactBlocked) {
|
|
95
128
|
compactBlocked = true;
|
|
96
129
|
log(
|
|
@@ -146,6 +179,60 @@ export function createMind(options: {
|
|
|
146
179
|
createEventHandler(session, {
|
|
147
180
|
cwd: options.cwd,
|
|
148
181
|
broadcast: (event) => broadcast(session, event),
|
|
182
|
+
onContextTokens: maxContextTokens
|
|
183
|
+
? (tokens: number) => {
|
|
184
|
+
if (tokens >= maxContextTokens && !compactionTriggered && !compactionInProgress) {
|
|
185
|
+
if (!session.agentSession) {
|
|
186
|
+
log(
|
|
187
|
+
"mind",
|
|
188
|
+
`session "${session.name}": compaction threshold hit but session not ready`,
|
|
189
|
+
);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
compactionTriggered = true;
|
|
193
|
+
log(
|
|
194
|
+
"mind",
|
|
195
|
+
`session "${session.name}": ${tokens} tokens >= ${maxContextTokens} — triggering compaction`,
|
|
196
|
+
);
|
|
197
|
+
// Send compaction warning; compaction will follow after the mind finishes its response turn
|
|
198
|
+
session.messageIds.push(undefined);
|
|
199
|
+
session.agentSession.prompt(compactionMessage, {
|
|
200
|
+
streamingBehavior: "followUp",
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
: undefined,
|
|
205
|
+
onTurnEnd: maxContextTokens
|
|
206
|
+
? () => {
|
|
207
|
+
try {
|
|
208
|
+
// Compact on the turn AFTER the warning was sent (so the mind gets a turn to save state)
|
|
209
|
+
if (compactOnNextTurnEnd) {
|
|
210
|
+
compactOnNextTurnEnd = false;
|
|
211
|
+
manualCompactPending = true;
|
|
212
|
+
compactionInProgress = true;
|
|
213
|
+
log("mind", `session "${session.name}": compacting with custom instructions`);
|
|
214
|
+
Promise.resolve(session.agentSession?.compact(compactionInstructions))
|
|
215
|
+
.catch((err) =>
|
|
216
|
+
log("mind", `session "${session.name}": compact() failed:`, err),
|
|
217
|
+
)
|
|
218
|
+
.finally(() => {
|
|
219
|
+
compactionInProgress = false;
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
if (compactionTriggered) {
|
|
223
|
+
compactionTriggered = false;
|
|
224
|
+
compactOnNextTurnEnd = true;
|
|
225
|
+
}
|
|
226
|
+
} catch (err) {
|
|
227
|
+
log(
|
|
228
|
+
"mind",
|
|
229
|
+
`session "${session.name}": onTurnEnd error, resetting compaction state:`,
|
|
230
|
+
err,
|
|
231
|
+
);
|
|
232
|
+
resetCompactionState();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
: undefined,
|
|
149
236
|
}),
|
|
150
237
|
);
|
|
151
238
|
|
|
@@ -14,6 +14,8 @@ export type EventSession = {
|
|
|
14
14
|
export type EventHandlerOptions = {
|
|
15
15
|
cwd: string;
|
|
16
16
|
broadcast: (event: VoluteEvent) => void;
|
|
17
|
+
onContextTokens?: (tokens: number) => void;
|
|
18
|
+
onTurnEnd?: () => void;
|
|
17
19
|
};
|
|
18
20
|
|
|
19
21
|
// Loaded once at startup — mind restarts on config changes
|
|
@@ -133,14 +135,20 @@ export function createEventHandler(session: EventSession, options: EventHandlerO
|
|
|
133
135
|
session.messageChannels.delete(session.currentMessageId);
|
|
134
136
|
}
|
|
135
137
|
log("mind", `session "${session.name}": turn done`);
|
|
136
|
-
// Sum usage from assistant messages
|
|
138
|
+
// Sum usage from assistant messages. The last assistant message's input tokens
|
|
139
|
+
// approximate current context size (it includes the full conversation up to that point).
|
|
137
140
|
if (event.messages) {
|
|
138
141
|
let inputTokens = 0;
|
|
139
142
|
let outputTokens = 0;
|
|
143
|
+
let lastInputTokens = 0;
|
|
140
144
|
for (const msg of event.messages as any[]) {
|
|
141
145
|
if (msg.role === "assistant" && msg.usage) {
|
|
142
146
|
inputTokens += msg.usage.input ?? 0;
|
|
143
147
|
outputTokens += msg.usage.output ?? 0;
|
|
148
|
+
const cacheWrite = msg.usage.cacheWrite ?? msg.usage.cache_creation ?? 0;
|
|
149
|
+
const cacheRead = msg.usage.cacheRead ?? msg.usage.cache_read ?? 0;
|
|
150
|
+
const contextTokens = (msg.usage.input ?? 0) + cacheWrite + cacheRead;
|
|
151
|
+
if (contextTokens) lastInputTokens = contextTokens;
|
|
144
152
|
}
|
|
145
153
|
}
|
|
146
154
|
if (inputTokens > 0 || outputTokens > 0) {
|
|
@@ -148,10 +156,14 @@ export function createEventHandler(session: EventSession, options: EventHandlerO
|
|
|
148
156
|
options.broadcast({ type: "usage", ...usage });
|
|
149
157
|
emit(session, { type: "usage", metadata: usage });
|
|
150
158
|
}
|
|
159
|
+
if (lastInputTokens > 0) {
|
|
160
|
+
options.onContextTokens?.(lastInputTokens);
|
|
161
|
+
}
|
|
151
162
|
}
|
|
152
163
|
options.broadcast({ type: "done" });
|
|
153
164
|
emit(session, { type: "done" });
|
|
154
165
|
session.currentMessageId = undefined;
|
|
166
|
+
options.onTurnEnd?.();
|
|
155
167
|
}
|
|
156
168
|
} catch (err) {
|
|
157
169
|
log("mind", `session "${session.name}": event handler error (${event?.type}):`, err);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolve } from "node:path";
|
|
2
2
|
import { createMind } from "./agent.js";
|
|
3
3
|
import { createFileHandlerResolver } from "./lib/file-handler.js";
|
|
4
|
-
import { log } from "./lib/logger.js";
|
|
4
|
+
import { log, setLevel } from "./lib/logger.js";
|
|
5
5
|
import { createRouter } from "./lib/router.js";
|
|
6
6
|
import {
|
|
7
7
|
handleStartupContext,
|
|
@@ -15,6 +15,7 @@ import { createVoluteServer } from "./lib/volute-server.js";
|
|
|
15
15
|
|
|
16
16
|
const { port } = parseArgs();
|
|
17
17
|
const config = loadConfig();
|
|
18
|
+
if (config.logLevel) setLevel(config.logLevel);
|
|
18
19
|
if (config.model) log("server", `using model: ${config.model}`);
|
|
19
20
|
if (config.thinkingLevel) log("server", `thinking level: ${config.thinkingLevel}`);
|
|
20
21
|
|
|
@@ -29,6 +30,7 @@ const mind = createMind({
|
|
|
29
30
|
model: config.model,
|
|
30
31
|
thinkingLevel: config.thinkingLevel,
|
|
31
32
|
compactionMessage: config.compactionMessage,
|
|
33
|
+
maxContextTokens: config.compaction?.maxContextTokens,
|
|
32
34
|
});
|
|
33
35
|
|
|
34
36
|
const router = createRouter({
|
package/dist/chunk-5XNT2472.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
schema_exports
|
|
4
|
-
} from "./chunk-NSE7VJQA.js";
|
|
5
|
-
import {
|
|
6
|
-
voluteHome
|
|
7
|
-
} from "./chunk-EBGCNDMM.js";
|
|
8
|
-
|
|
9
|
-
// src/lib/db.ts
|
|
10
|
-
import { chmodSync, existsSync } from "fs";
|
|
11
|
-
import { dirname, resolve } from "path";
|
|
12
|
-
import { fileURLToPath } from "url";
|
|
13
|
-
import { drizzle } from "drizzle-orm/libsql";
|
|
14
|
-
import { migrate } from "drizzle-orm/libsql/migrator";
|
|
15
|
-
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
16
|
-
var migrationsFolder = existsSync(resolve(__dirname, "../drizzle")) ? resolve(__dirname, "../drizzle") : resolve(__dirname, "../../drizzle");
|
|
17
|
-
var db = null;
|
|
18
|
-
async function getDb() {
|
|
19
|
-
if (db) return db;
|
|
20
|
-
const dbPath = process.env.VOLUTE_DB_PATH || resolve(voluteHome(), "volute.db");
|
|
21
|
-
db = drizzle({ connection: { url: `file:${dbPath}` }, schema: schema_exports });
|
|
22
|
-
await migrate(db, { migrationsFolder });
|
|
23
|
-
try {
|
|
24
|
-
chmodSync(dbPath, 384);
|
|
25
|
-
} catch (err) {
|
|
26
|
-
console.error(
|
|
27
|
-
`[volute] WARNING: Failed to restrict database file permissions on ${dbPath}:`,
|
|
28
|
-
err
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
return db;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export {
|
|
35
|
-
getDb
|
|
36
|
-
};
|