@schlessera/brain-ui-server 0.4.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/LICENSE +21 -0
- package/README.md +65 -0
- package/dist/agent/backend.d.ts +30 -0
- package/dist/agent/backend.d.ts.map +1 -0
- package/dist/agent/backend.js +226 -0
- package/dist/agent/backend.js.map +1 -0
- package/dist/app.d.ts +27 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +116 -0
- package/dist/app.js.map +1 -0
- package/dist/brain/client.d.ts +43 -0
- package/dist/brain/client.d.ts.map +1 -0
- package/dist/brain/client.js +154 -0
- package/dist/brain/client.js.map +1 -0
- package/dist/brain/types.d.ts +41 -0
- package/dist/brain/types.d.ts.map +1 -0
- package/dist/brain/types.js +2 -0
- package/dist/brain/types.js.map +1 -0
- package/dist/cron/scheduler.d.ts +9 -0
- package/dist/cron/scheduler.d.ts.map +1 -0
- package/dist/cron/scheduler.js +58 -0
- package/dist/cron/scheduler.js.map +1 -0
- package/dist/db/client.d.ts +10 -0
- package/dist/db/client.d.ts.map +1 -0
- package/dist/db/client.js +73 -0
- package/dist/db/client.js.map +1 -0
- package/dist/files/walker.d.ts +63 -0
- package/dist/files/walker.d.ts.map +1 -0
- package/dist/files/walker.js +416 -0
- package/dist/files/walker.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/auth.d.ts +59 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +246 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/passkeys.d.ts +36 -0
- package/dist/middleware/passkeys.d.ts.map +1 -0
- package/dist/middleware/passkeys.js +427 -0
- package/dist/middleware/passkeys.js.map +1 -0
- package/dist/middleware/tailscale.d.ts +31 -0
- package/dist/middleware/tailscale.d.ts.map +1 -0
- package/dist/middleware/tailscale.js +64 -0
- package/dist/middleware/tailscale.js.map +1 -0
- package/dist/render/template.d.ts +7 -0
- package/dist/render/template.d.ts.map +1 -0
- package/dist/render/template.js +112 -0
- package/dist/render/template.js.map +1 -0
- package/dist/routes/brain.d.ts +155 -0
- package/dist/routes/brain.d.ts.map +1 -0
- package/dist/routes/brain.js +250 -0
- package/dist/routes/brain.js.map +1 -0
- package/dist/routes/files.d.ts +89 -0
- package/dist/routes/files.d.ts.map +1 -0
- package/dist/routes/files.js +91 -0
- package/dist/routes/files.js.map +1 -0
- package/dist/routes/health.d.ts +37 -0
- package/dist/routes/health.d.ts.map +1 -0
- package/dist/routes/health.js +27 -0
- package/dist/routes/health.js.map +1 -0
- package/dist/routes/providers.d.ts +33 -0
- package/dist/routes/providers.d.ts.map +1 -0
- package/dist/routes/providers.js +9 -0
- package/dist/routes/providers.js.map +1 -0
- package/dist/routes/render.d.ts +25 -0
- package/dist/routes/render.d.ts.map +1 -0
- package/dist/routes/render.js +47 -0
- package/dist/routes/render.js.map +1 -0
- package/dist/routes/sessions.d.ts +79 -0
- package/dist/routes/sessions.d.ts.map +1 -0
- package/dist/routes/sessions.js +37 -0
- package/dist/routes/sessions.js.map +1 -0
- package/dist/routes/voice.d.ts +92 -0
- package/dist/routes/voice.d.ts.map +1 -0
- package/dist/routes/voice.js +64 -0
- package/dist/routes/voice.js.map +1 -0
- package/dist/voice/deepgram-token.d.ts +5 -0
- package/dist/voice/deepgram-token.d.ts.map +1 -0
- package/dist/voice/deepgram-token.js +63 -0
- package/dist/voice/deepgram-token.js.map +1 -0
- package/dist/voice/keyterm-builder.d.ts +18 -0
- package/dist/voice/keyterm-builder.d.ts.map +1 -0
- package/dist/voice/keyterm-builder.js +391 -0
- package/dist/voice/keyterm-builder.js.map +1 -0
- package/dist/voice/speech-providers.d.ts +25 -0
- package/dist/voice/speech-providers.d.ts.map +1 -0
- package/dist/voice/speech-providers.js +104 -0
- package/dist/voice/speech-providers.js.map +1 -0
- package/dist/ws/attachments.d.ts +10 -0
- package/dist/ws/attachments.d.ts.map +1 -0
- package/dist/ws/attachments.js +63 -0
- package/dist/ws/attachments.js.map +1 -0
- package/dist/ws/bridge.d.ts +7 -0
- package/dist/ws/bridge.d.ts.map +1 -0
- package/dist/ws/bridge.js +86 -0
- package/dist/ws/bridge.js.map +1 -0
- package/dist/ws/clients.d.ts +20 -0
- package/dist/ws/clients.d.ts.map +1 -0
- package/dist/ws/clients.js +48 -0
- package/dist/ws/clients.js.map +1 -0
- package/dist/ws/connection.d.ts +8 -0
- package/dist/ws/connection.d.ts.map +1 -0
- package/dist/ws/connection.js +116 -0
- package/dist/ws/connection.js.map +1 -0
- package/dist/ws/dispatch.d.ts +5 -0
- package/dist/ws/dispatch.d.ts.map +1 -0
- package/dist/ws/dispatch.js +139 -0
- package/dist/ws/dispatch.js.map +1 -0
- package/dist/ws/frames.d.ts +17 -0
- package/dist/ws/frames.d.ts.map +1 -0
- package/dist/ws/frames.js +37 -0
- package/dist/ws/frames.js.map +1 -0
- package/dist/ws/handler.d.ts +34 -0
- package/dist/ws/handler.d.ts.map +1 -0
- package/dist/ws/handler.js +33 -0
- package/dist/ws/handler.js.map +1 -0
- package/dist/ws/history.d.ts +17 -0
- package/dist/ws/history.d.ts.map +1 -0
- package/dist/ws/history.js +45 -0
- package/dist/ws/history.js.map +1 -0
- package/dist/ws/host.d.ts +40 -0
- package/dist/ws/host.d.ts.map +1 -0
- package/dist/ws/host.js +49 -0
- package/dist/ws/host.js.map +1 -0
- package/dist/ws/routing.d.ts +12 -0
- package/dist/ws/routing.d.ts.map +1 -0
- package/dist/ws/routing.js +31 -0
- package/dist/ws/routing.js.map +1 -0
- package/dist/ws/run-session.d.ts +17 -0
- package/dist/ws/run-session.d.ts.map +1 -0
- package/dist/ws/run-session.js +160 -0
- package/dist/ws/run-session.js.map +1 -0
- package/dist/ws/session-catalog.d.ts +25 -0
- package/dist/ws/session-catalog.d.ts.map +1 -0
- package/dist/ws/session-catalog.js +45 -0
- package/dist/ws/session-catalog.js.map +1 -0
- package/dist/ws/shrink.d.ts +34 -0
- package/dist/ws/shrink.d.ts.map +1 -0
- package/dist/ws/shrink.js +91 -0
- package/dist/ws/shrink.js.map +1 -0
- package/dist/ws/turns.d.ts +77 -0
- package/dist/ws/turns.d.ts.map +1 -0
- package/dist/ws/turns.js +89 -0
- package/dist/ws/turns.js.map +1 -0
- package/migrations/001_initial.sql +29 -0
- package/migrations/002_session_provider.sql +1 -0
- package/migrations/003_session_backend.sql +5 -0
- package/migrations/004_drop_gemini_backend.sql +20 -0
- package/migrations/005_passkey_credentials.sql +18 -0
- package/package.json +72 -0
- package/src/agent/backend.ts +308 -0
- package/src/app.ts +159 -0
- package/src/brain/client.ts +186 -0
- package/src/brain/types.ts +44 -0
- package/src/cron/scheduler.ts +80 -0
- package/src/db/client.ts +85 -0
- package/src/files/walker.ts +418 -0
- package/src/index.ts +39 -0
- package/src/middleware/auth.ts +321 -0
- package/src/middleware/passkeys.ts +510 -0
- package/src/middleware/tailscale.ts +81 -0
- package/src/render/template.ts +124 -0
- package/src/routes/brain.ts +305 -0
- package/src/routes/files.ts +99 -0
- package/src/routes/health.ts +29 -0
- package/src/routes/providers.ts +9 -0
- package/src/routes/render.ts +68 -0
- package/src/routes/sessions.ts +49 -0
- package/src/routes/voice.ts +80 -0
- package/src/voice/deepgram-token.ts +80 -0
- package/src/voice/keyterm-builder.ts +426 -0
- package/src/voice/speech-providers.ts +111 -0
- package/src/ws/attachments.ts +86 -0
- package/src/ws/bridge.ts +139 -0
- package/src/ws/clients.ts +57 -0
- package/src/ws/connection.ts +132 -0
- package/src/ws/dispatch.ts +162 -0
- package/src/ws/frames.ts +42 -0
- package/src/ws/handler.ts +50 -0
- package/src/ws/history.ts +51 -0
- package/src/ws/host.ts +69 -0
- package/src/ws/routing.ts +43 -0
- package/src/ws/run-session.ts +192 -0
- package/src/ws/session-catalog.ts +97 -0
- package/src/ws/shrink.ts +95 -0
- package/src/ws/turns.ts +151 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { existsSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
const BRAIN_PATH = process.env.BRAIN_PATH || join(process.env.HOME || "/root", "brain");
|
|
4
|
+
/**
|
|
5
|
+
* argv prefix for invoking the brain CLI inside BRAIN_PATH.
|
|
6
|
+
*
|
|
7
|
+
* Two brain-repo layouts exist and both must work: a repo that depends on
|
|
8
|
+
* `@schlessera/brain` gets a real bin at `node_modules/.bin/brain`, while the
|
|
9
|
+
* legacy layout vendors `scripts/brain-cli.ts`. Prefer the packaged bin.
|
|
10
|
+
*
|
|
11
|
+
* Resolved per call (a bare `existsSync` stat) rather than at import time: in
|
|
12
|
+
* the container the brain repo is cloned and `bun install`ed by entrypoint.sh,
|
|
13
|
+
* and a repo can gain the dependency without restarting this server. The same
|
|
14
|
+
* preference order is mirrored in `scripts/entrypoint.sh`, which links whichever
|
|
15
|
+
* it finds onto PATH for cron.
|
|
16
|
+
*/
|
|
17
|
+
export function brainCliCommand() {
|
|
18
|
+
const packaged = join(BRAIN_PATH, "node_modules", ".bin", "brain");
|
|
19
|
+
if (existsSync(packaged))
|
|
20
|
+
return [packaged];
|
|
21
|
+
return ["bun", "scripts/brain-cli.ts"];
|
|
22
|
+
}
|
|
23
|
+
async function execBrain(args) {
|
|
24
|
+
const proc = Bun.spawn([...brainCliCommand(), ...args], {
|
|
25
|
+
cwd: BRAIN_PATH,
|
|
26
|
+
stdout: "pipe",
|
|
27
|
+
stderr: "pipe",
|
|
28
|
+
env: {
|
|
29
|
+
...process.env,
|
|
30
|
+
// Force JSON output when not a TTY
|
|
31
|
+
NO_COLOR: "1",
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
const [stdout, stderr] = await Promise.all([
|
|
35
|
+
new Response(proc.stdout).text(),
|
|
36
|
+
new Response(proc.stderr).text(),
|
|
37
|
+
]);
|
|
38
|
+
const exitCode = await proc.exited;
|
|
39
|
+
return { stdout, stderr, exitCode };
|
|
40
|
+
}
|
|
41
|
+
function parseJsonOutput(result) {
|
|
42
|
+
if (result.exitCode !== 0) {
|
|
43
|
+
throw new Error(`brain CLI failed (exit ${result.exitCode}): ${result.stderr || result.stdout}`);
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
return JSON.parse(result.stdout);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Some commands output plain text, not JSON
|
|
50
|
+
return result.stdout;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export async function brainSearch(query, opts) {
|
|
54
|
+
const args = ["search", query];
|
|
55
|
+
if (opts?.type)
|
|
56
|
+
args.push("--type", opts.type);
|
|
57
|
+
if (opts?.tag)
|
|
58
|
+
args.push("--tag", opts.tag);
|
|
59
|
+
if (opts?.limit)
|
|
60
|
+
args.push("--limit", String(opts.limit));
|
|
61
|
+
if (opts?.mode)
|
|
62
|
+
args.push("--mode", opts.mode);
|
|
63
|
+
const result = await execBrain(args);
|
|
64
|
+
const parsed = parseJsonOutput(result);
|
|
65
|
+
// brain returns {results, warnings} since 22e82e1; tolerate the old bare array
|
|
66
|
+
return Array.isArray(parsed) ? { results: parsed, warnings: [] } : parsed;
|
|
67
|
+
}
|
|
68
|
+
export async function brainBriefing() {
|
|
69
|
+
const result = await execBrain(["briefing"]);
|
|
70
|
+
if (result.exitCode !== 0) {
|
|
71
|
+
throw new Error(`brain briefing failed: ${result.stderr}`);
|
|
72
|
+
}
|
|
73
|
+
return result.stdout;
|
|
74
|
+
}
|
|
75
|
+
export async function brainStats() {
|
|
76
|
+
const result = await execBrain(["stats"]);
|
|
77
|
+
return parseJsonOutput(result);
|
|
78
|
+
}
|
|
79
|
+
export async function brainList(opts) {
|
|
80
|
+
const args = ["list"];
|
|
81
|
+
if (opts?.type)
|
|
82
|
+
args.push("--type", opts.type);
|
|
83
|
+
if (opts?.tag)
|
|
84
|
+
args.push("--tag", opts.tag);
|
|
85
|
+
if (opts?.status)
|
|
86
|
+
args.push("--status", opts.status);
|
|
87
|
+
if (opts?.relevance)
|
|
88
|
+
args.push("--relevance", opts.relevance);
|
|
89
|
+
if (opts?.limit)
|
|
90
|
+
args.push("--limit", String(opts.limit));
|
|
91
|
+
const result = await execBrain(args);
|
|
92
|
+
return parseJsonOutput(result);
|
|
93
|
+
}
|
|
94
|
+
export async function brainRead(path) {
|
|
95
|
+
const result = await execBrain(["read", path]);
|
|
96
|
+
if (result.exitCode !== 0) {
|
|
97
|
+
throw new Error(`brain read failed: ${result.stderr}`);
|
|
98
|
+
}
|
|
99
|
+
return result.stdout;
|
|
100
|
+
}
|
|
101
|
+
export async function brainSync() {
|
|
102
|
+
// Note: brain sync spawns Claude Code internally via the /sync skill.
|
|
103
|
+
// For cron jobs, we use a simpler git-based sync instead.
|
|
104
|
+
const result = await execBrain(["sync"]);
|
|
105
|
+
if (result.exitCode !== 0) {
|
|
106
|
+
return {
|
|
107
|
+
success: false,
|
|
108
|
+
commits: 0,
|
|
109
|
+
conflicts: 0,
|
|
110
|
+
message: result.stderr || result.stdout,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
return parseJsonOutput(result);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return {
|
|
118
|
+
success: true,
|
|
119
|
+
commits: 0,
|
|
120
|
+
conflicts: 0,
|
|
121
|
+
message: result.stdout,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
export async function brainAdd(content, opts) {
|
|
126
|
+
const args = ["add", content];
|
|
127
|
+
if (opts?.type)
|
|
128
|
+
args.push("--type", opts.type);
|
|
129
|
+
if (opts?.title)
|
|
130
|
+
args.push("--title", opts.title);
|
|
131
|
+
if (opts?.tags)
|
|
132
|
+
args.push("--tags", opts.tags.join(","));
|
|
133
|
+
const result = await execBrain(args);
|
|
134
|
+
if (result.exitCode !== 0) {
|
|
135
|
+
throw new Error(`brain add failed: ${result.stderr}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
export async function brainIndex(opts) {
|
|
139
|
+
const args = ["index"];
|
|
140
|
+
if (opts?.force)
|
|
141
|
+
args.push("--force");
|
|
142
|
+
const result = await execBrain(args);
|
|
143
|
+
if (result.exitCode !== 0) {
|
|
144
|
+
throw new Error(`brain index failed: ${result.stderr}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
export async function brainValidate() {
|
|
148
|
+
const result = await execBrain(["validate"]);
|
|
149
|
+
if (result.exitCode !== 0) {
|
|
150
|
+
throw new Error(`brain validate failed: ${result.stderr}`);
|
|
151
|
+
}
|
|
152
|
+
return result.stdout;
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/brain/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export interface BrainSearchResult {
|
|
2
|
+
path: string;
|
|
3
|
+
title: string;
|
|
4
|
+
type: string;
|
|
5
|
+
relevance: string;
|
|
6
|
+
score: number;
|
|
7
|
+
snippet: string;
|
|
8
|
+
}
|
|
9
|
+
export interface BrainSearchResponse {
|
|
10
|
+
results: BrainSearchResult[];
|
|
11
|
+
/** Degraded-mode notices from the CLI, e.g. vector search unavailable so results are FTS-only. */
|
|
12
|
+
warnings: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface BrainDocument {
|
|
15
|
+
path: string;
|
|
16
|
+
title: string;
|
|
17
|
+
type: string;
|
|
18
|
+
status: string;
|
|
19
|
+
relevance: string;
|
|
20
|
+
tags: string[];
|
|
21
|
+
created: string;
|
|
22
|
+
updated: string;
|
|
23
|
+
summary?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface BrainStats {
|
|
26
|
+
documents: number;
|
|
27
|
+
byType: Record<string, number>;
|
|
28
|
+
byStatus: Record<string, number>;
|
|
29
|
+
byRelevance: Record<string, number>;
|
|
30
|
+
tags: number;
|
|
31
|
+
links: number;
|
|
32
|
+
brokenLinks: number;
|
|
33
|
+
chunks: number;
|
|
34
|
+
}
|
|
35
|
+
export interface BrainSyncResult {
|
|
36
|
+
success: boolean;
|
|
37
|
+
commits: number;
|
|
38
|
+
conflicts: number;
|
|
39
|
+
message: string;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/brain/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,kGAAkG;IAClG,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/brain/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/cron/scheduler.ts"],"names":[],"mappings":"AAsDA,wBAAgB,aAAa;;;;;;IAiB5B;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAM/D"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { getDb } from "../db/client.js";
|
|
2
|
+
import { brainSync, brainIndex, brainValidate } from "../brain/client.js";
|
|
3
|
+
const jobs = [
|
|
4
|
+
{
|
|
5
|
+
name: "sync",
|
|
6
|
+
handler: async () => {
|
|
7
|
+
await brainSync();
|
|
8
|
+
await brainIndex();
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
name: "validate",
|
|
13
|
+
handler: async () => {
|
|
14
|
+
await brainValidate();
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
];
|
|
18
|
+
async function runJob(job) {
|
|
19
|
+
const db = getDb();
|
|
20
|
+
const startedAt = Date.now();
|
|
21
|
+
db.prepare("INSERT INTO cron_runs (job_name, started_at, status) VALUES (?, ?, 'running')").run(job.name, startedAt);
|
|
22
|
+
try {
|
|
23
|
+
await job.handler();
|
|
24
|
+
const durationMs = Date.now() - startedAt;
|
|
25
|
+
db.prepare("UPDATE cron_runs SET status = 'success', finished_at = ?, duration_ms = ? WHERE job_name = ? AND started_at = ?").run(Date.now(), durationMs, job.name, startedAt);
|
|
26
|
+
console.log(`[cron] ${job.name} completed in ${durationMs}ms`);
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
const durationMs = Date.now() - startedAt;
|
|
30
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
31
|
+
db.prepare("UPDATE cron_runs SET status = 'error', finished_at = ?, duration_ms = ?, error_message = ? WHERE job_name = ? AND started_at = ?").run(Date.now(), durationMs, message, job.name, startedAt);
|
|
32
|
+
console.error(`[cron] ${job.name} failed: ${message}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export function getCronStatus() {
|
|
36
|
+
const db = getDb();
|
|
37
|
+
return jobs.map((job) => {
|
|
38
|
+
const lastRun = db
|
|
39
|
+
.query("SELECT * FROM cron_runs WHERE job_name = ? ORDER BY started_at DESC LIMIT 1")
|
|
40
|
+
.get(job.name);
|
|
41
|
+
return {
|
|
42
|
+
name: job.name,
|
|
43
|
+
lastRunAt: lastRun?.started_at ?? null,
|
|
44
|
+
lastStatus: lastRun?.status ?? null,
|
|
45
|
+
lastDurationMs: lastRun?.duration_ms ?? null,
|
|
46
|
+
lastError: lastRun?.error_message ?? null,
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
export async function triggerJob(name) {
|
|
51
|
+
const job = jobs.find((j) => j.name === name);
|
|
52
|
+
if (!job)
|
|
53
|
+
return false;
|
|
54
|
+
// Run async (don't await - let it run in background)
|
|
55
|
+
runJob(job);
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/cron/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAY1E,MAAM,IAAI,GAAc;IACtB;QACE,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,MAAM,SAAS,EAAE,CAAC;YAClB,MAAM,UAAU,EAAE,CAAC;QACrB,CAAC;KACF;IACD;QACE,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,MAAM,aAAa,EAAE,CAAC;QACxB,CAAC;KACF;CACF,CAAC;AAEF,KAAK,UAAU,MAAM,CAAC,GAAY;IAChC,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,EAAE,CAAC,OAAO,CACR,+EAA+E,CAChF,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAE3B,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAC1C,EAAE,CAAC,OAAO,CACR,iHAAiH,CAClH,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,UAAU,GAAG,CAAC,IAAI,iBAAiB,UAAU,IAAI,CAAC,CAAC;IACjE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAC1C,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,EAAE,CAAC,OAAO,CACR,kIAAkI,CACnI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC5D,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,IAAI,YAAY,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACtB,MAAM,OAAO,GAAG,EAAE;aACf,KAAK,CACJ,6EAA6E,CAC9E;aACA,GAAG,CAAC,GAAG,CAAC,IAAI,CAAQ,CAAC;QAExB,OAAO;YACL,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,SAAS,EAAE,OAAO,EAAE,UAAU,IAAI,IAAI;YACtC,UAAU,EAAE,OAAO,EAAE,MAAM,IAAI,IAAI;YACnC,cAAc,EAAE,OAAO,EAAE,WAAW,IAAI,IAAI;YAC5C,SAAS,EAAE,OAAO,EAAE,aAAa,IAAI,IAAI;SAC1C,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IAC9C,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IACvB,qDAAqD;IACrD,MAAM,CAAC,GAAG,CAAC,CAAC;IACZ,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Database } from "bun:sqlite";
|
|
2
|
+
/**
|
|
3
|
+
* Override the database path before the first `getDb()` call (used by
|
|
4
|
+
* `createApp({ dbPath })`). Configuring after the handle exists would silently
|
|
5
|
+
* split state across two files — refuse instead.
|
|
6
|
+
*/
|
|
7
|
+
export declare function configureDb(dbPath: string): void;
|
|
8
|
+
export declare function getDb(): Database;
|
|
9
|
+
export declare function closeDb(): void;
|
|
10
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/db/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAOtC;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAOhD;AAED,wBAAgB,KAAK,IAAI,QAAQ,CAUhC;AAED,wBAAgB,OAAO,SAKtB"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Database } from "bun:sqlite";
|
|
2
|
+
import { readdirSync, readFileSync } from "fs";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
let db = null;
|
|
5
|
+
let configuredPath = null;
|
|
6
|
+
/**
|
|
7
|
+
* Override the database path before the first `getDb()` call (used by
|
|
8
|
+
* `createApp({ dbPath })`). Configuring after the handle exists would silently
|
|
9
|
+
* split state across two files — refuse instead.
|
|
10
|
+
*/
|
|
11
|
+
export function configureDb(dbPath) {
|
|
12
|
+
if (db && configuredPath !== dbPath) {
|
|
13
|
+
throw new Error("configureDb() called after the database was opened; set dbPath before the first use");
|
|
14
|
+
}
|
|
15
|
+
configuredPath = dbPath;
|
|
16
|
+
}
|
|
17
|
+
export function getDb() {
|
|
18
|
+
if (!db) {
|
|
19
|
+
const dbPath = configuredPath || process.env.DB_PATH || join(process.cwd(), "brain-ui.db");
|
|
20
|
+
db = new Database(dbPath, { create: true });
|
|
21
|
+
db.exec("PRAGMA journal_mode = WAL");
|
|
22
|
+
db.exec("PRAGMA foreign_keys = ON");
|
|
23
|
+
runMigrations(db);
|
|
24
|
+
}
|
|
25
|
+
return db;
|
|
26
|
+
}
|
|
27
|
+
export function closeDb() {
|
|
28
|
+
if (db) {
|
|
29
|
+
db.close();
|
|
30
|
+
db = null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function runMigrations(database) {
|
|
34
|
+
// Ensure _migrations table exists
|
|
35
|
+
database.exec(`
|
|
36
|
+
CREATE TABLE IF NOT EXISTS _migrations (
|
|
37
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
38
|
+
filename TEXT NOT NULL UNIQUE,
|
|
39
|
+
applied_at INTEGER NOT NULL
|
|
40
|
+
)
|
|
41
|
+
`);
|
|
42
|
+
// The migrations ship inside the package (they are listed in `files`).
|
|
43
|
+
// src/db/ and dist/db/ sit at the same depth, so the relative hop to the
|
|
44
|
+
// package root resolves identically for the Bun (src) and Node (dist) paths.
|
|
45
|
+
const migrationsDir = join(import.meta.dir, "../../migrations");
|
|
46
|
+
let files;
|
|
47
|
+
try {
|
|
48
|
+
files = readdirSync(migrationsDir)
|
|
49
|
+
.filter((f) => f.endsWith(".sql"))
|
|
50
|
+
.sort();
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
console.warn("[db] No migrations directory found, skipping migrations");
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const applied = new Set(database
|
|
57
|
+
.query("SELECT filename FROM _migrations")
|
|
58
|
+
.all()
|
|
59
|
+
.map((r) => r.filename));
|
|
60
|
+
for (const file of files) {
|
|
61
|
+
if (applied.has(file))
|
|
62
|
+
continue;
|
|
63
|
+
console.log(`[db] Applying migration: ${file}`);
|
|
64
|
+
const sql = readFileSync(join(migrationsDir, file), "utf-8");
|
|
65
|
+
database.transaction(() => {
|
|
66
|
+
database.exec(sql);
|
|
67
|
+
database
|
|
68
|
+
.prepare("INSERT INTO _migrations (filename, applied_at) VALUES (?, ?)")
|
|
69
|
+
.run(file, Date.now());
|
|
70
|
+
})();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/db/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,IAAI,EAAE,GAAoB,IAAI,CAAC;AAC/B,IAAI,cAAc,GAAkB,IAAI,CAAC;AAEzC;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,IAAI,EAAE,IAAI,cAAc,KAAK,MAAM,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CACb,qFAAqF,CACtF,CAAC;IACJ,CAAC;IACD,cAAc,GAAG,MAAM,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,KAAK;IACnB,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,MAAM,MAAM,GACV,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,CAAC,CAAC;QAC9E,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,EAAE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QACrC,EAAE,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QACpC,aAAa,CAAC,EAAE,CAAC,CAAC;IACpB,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,IAAI,EAAE,EAAE,CAAC;QACP,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,EAAE,GAAG,IAAI,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,QAAkB;IACvC,kCAAkC;IAClC,QAAQ,CAAC,IAAI,CAAC;;;;;;GAMb,CAAC,CAAC;IAEH,uEAAuE;IACvE,yEAAyE;IACzE,6EAA6E;IAC7E,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;IAChE,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QACH,KAAK,GAAG,WAAW,CAAC,aAAa,CAAC;aAC/B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;aACjC,IAAI,EAAE,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC;QACxE,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,QAAQ;SACL,KAAK,CAAC,kCAAkC,CAAC;SACzC,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAC/B,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QAEhC,OAAO,CAAC,GAAG,CAAC,4BAA4B,IAAI,EAAE,CAAC,CAAC;QAChD,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;QAE7D,QAAQ,CAAC,WAAW,CAAC,GAAG,EAAE;YACxB,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnB,QAAQ;iBACL,OAAO,CAAC,8DAA8D,CAAC;iBACvE,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC3B,CAAC,CAAC,EAAE,CAAC;IACP,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { dirname } from "node:path";
|
|
2
|
+
import type { FileEntry, FileContentKind } from "@schlessera/brain-ui-sdk/protocol";
|
|
3
|
+
export declare function getBrainRoot(): string;
|
|
4
|
+
export declare class PathEscapeError extends Error {
|
|
5
|
+
constructor(rel: string);
|
|
6
|
+
}
|
|
7
|
+
export declare class NotFoundError extends Error {
|
|
8
|
+
constructor(rel: string);
|
|
9
|
+
}
|
|
10
|
+
export declare class TooLargeError extends Error {
|
|
11
|
+
size: number;
|
|
12
|
+
constructor(size: number);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Resolve a repo-relative path to an absolute path, rejecting any escape
|
|
16
|
+
* outside the brain root (including via symlinks).
|
|
17
|
+
*/
|
|
18
|
+
export declare function safeResolve(rel: string, root?: string): Promise<string>;
|
|
19
|
+
/**
|
|
20
|
+
* List entries of a directory, applying ignore rules.
|
|
21
|
+
* Always excludes: .git, node_modules, *.db*. Then applies .gitignore.
|
|
22
|
+
*/
|
|
23
|
+
export declare function listDirectory(rel: string, root?: string): Promise<FileEntry[]>;
|
|
24
|
+
export declare function classifyKind(name: string, bytes?: Buffer): FileContentKind;
|
|
25
|
+
export declare function mimeFor(name: string, kind: FileContentKind): string;
|
|
26
|
+
export interface FileContent {
|
|
27
|
+
kind: FileContentKind;
|
|
28
|
+
size: number;
|
|
29
|
+
mtime: number;
|
|
30
|
+
mime: string;
|
|
31
|
+
content?: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function readFileContent(rel: string, root?: string): Promise<FileContent>;
|
|
34
|
+
/**
|
|
35
|
+
* Stream raw bytes of a file (for image/binary preview).
|
|
36
|
+
* Returns the absolute path; caller uses Bun.file() to stream.
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveForRaw(rel: string, root?: string): Promise<{
|
|
39
|
+
abs: string;
|
|
40
|
+
size: number;
|
|
41
|
+
mime: string;
|
|
42
|
+
kind: FileContentKind;
|
|
43
|
+
}>;
|
|
44
|
+
/**
|
|
45
|
+
* Walk the brain repo and build a slug -> repo-relative-path map for all
|
|
46
|
+
* markdown files (.md / .markdown / .mdx), respecting the same ignore
|
|
47
|
+
* rules as listDirectory. Slug = basename without extension, lowercase.
|
|
48
|
+
*
|
|
49
|
+
* If two files share a slug (rare), the first one encountered wins —
|
|
50
|
+
* deterministic given the sorted directory traversal.
|
|
51
|
+
*/
|
|
52
|
+
export declare function buildWikilinkMap(root?: string): Promise<Record<string, string>>;
|
|
53
|
+
/**
|
|
54
|
+
* Return ancestor directories of a path, root-first (excluding root and the path itself).
|
|
55
|
+
* resolve("a/b/c.md") -> { ancestors: ["a", "a/b"], exists, type }
|
|
56
|
+
*/
|
|
57
|
+
export declare function resolveAncestors(rel: string, root?: string): Promise<{
|
|
58
|
+
ancestors: string[];
|
|
59
|
+
exists: boolean;
|
|
60
|
+
type?: "dir" | "file";
|
|
61
|
+
}>;
|
|
62
|
+
export { dirname };
|
|
63
|
+
//# sourceMappingURL=walker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walker.d.ts","sourceRoot":"","sources":["../../src/files/walker.ts"],"names":[],"mappings":"AACA,OAAO,EAA6B,OAAO,EAAE,MAAM,WAAW,CAAC;AAG/D,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAuBpF,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,GAAG,EAAE,MAAM;CAIxB;AAED,qBAAa,aAAc,SAAQ,KAAK;gBAC1B,GAAG,EAAE,MAAM;CAIxB;AAED,qBAAa,aAAc,SAAQ,KAAK;IACnB,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;CAIhC;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,SAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAwBrF;AAyCD;;;GAGG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,SAAiB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAyD5F;AAsBD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,CAsB1E;AAmBD,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,MAAM,CAOnE;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,SAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CAgD9F;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,SAAiB,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,eAAe,CAAA;CAAE,CAAC,CAYnJ;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,SAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAuD7F;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,SAAiB,GAAG,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;CAAE,CAAC,CAenJ;AAGD,OAAO,EAAE,OAAO,EAAE,CAAC"}
|