@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.
Files changed (188) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +65 -0
  3. package/dist/agent/backend.d.ts +30 -0
  4. package/dist/agent/backend.d.ts.map +1 -0
  5. package/dist/agent/backend.js +226 -0
  6. package/dist/agent/backend.js.map +1 -0
  7. package/dist/app.d.ts +27 -0
  8. package/dist/app.d.ts.map +1 -0
  9. package/dist/app.js +116 -0
  10. package/dist/app.js.map +1 -0
  11. package/dist/brain/client.d.ts +43 -0
  12. package/dist/brain/client.d.ts.map +1 -0
  13. package/dist/brain/client.js +154 -0
  14. package/dist/brain/client.js.map +1 -0
  15. package/dist/brain/types.d.ts +41 -0
  16. package/dist/brain/types.d.ts.map +1 -0
  17. package/dist/brain/types.js +2 -0
  18. package/dist/brain/types.js.map +1 -0
  19. package/dist/cron/scheduler.d.ts +9 -0
  20. package/dist/cron/scheduler.d.ts.map +1 -0
  21. package/dist/cron/scheduler.js +58 -0
  22. package/dist/cron/scheduler.js.map +1 -0
  23. package/dist/db/client.d.ts +10 -0
  24. package/dist/db/client.d.ts.map +1 -0
  25. package/dist/db/client.js +73 -0
  26. package/dist/db/client.js.map +1 -0
  27. package/dist/files/walker.d.ts +63 -0
  28. package/dist/files/walker.d.ts.map +1 -0
  29. package/dist/files/walker.js +416 -0
  30. package/dist/files/walker.js.map +1 -0
  31. package/dist/index.d.ts +18 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +25 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/middleware/auth.d.ts +59 -0
  36. package/dist/middleware/auth.d.ts.map +1 -0
  37. package/dist/middleware/auth.js +246 -0
  38. package/dist/middleware/auth.js.map +1 -0
  39. package/dist/middleware/passkeys.d.ts +36 -0
  40. package/dist/middleware/passkeys.d.ts.map +1 -0
  41. package/dist/middleware/passkeys.js +427 -0
  42. package/dist/middleware/passkeys.js.map +1 -0
  43. package/dist/middleware/tailscale.d.ts +31 -0
  44. package/dist/middleware/tailscale.d.ts.map +1 -0
  45. package/dist/middleware/tailscale.js +64 -0
  46. package/dist/middleware/tailscale.js.map +1 -0
  47. package/dist/render/template.d.ts +7 -0
  48. package/dist/render/template.d.ts.map +1 -0
  49. package/dist/render/template.js +112 -0
  50. package/dist/render/template.js.map +1 -0
  51. package/dist/routes/brain.d.ts +155 -0
  52. package/dist/routes/brain.d.ts.map +1 -0
  53. package/dist/routes/brain.js +250 -0
  54. package/dist/routes/brain.js.map +1 -0
  55. package/dist/routes/files.d.ts +89 -0
  56. package/dist/routes/files.d.ts.map +1 -0
  57. package/dist/routes/files.js +91 -0
  58. package/dist/routes/files.js.map +1 -0
  59. package/dist/routes/health.d.ts +37 -0
  60. package/dist/routes/health.d.ts.map +1 -0
  61. package/dist/routes/health.js +27 -0
  62. package/dist/routes/health.js.map +1 -0
  63. package/dist/routes/providers.d.ts +33 -0
  64. package/dist/routes/providers.d.ts.map +1 -0
  65. package/dist/routes/providers.js +9 -0
  66. package/dist/routes/providers.js.map +1 -0
  67. package/dist/routes/render.d.ts +25 -0
  68. package/dist/routes/render.d.ts.map +1 -0
  69. package/dist/routes/render.js +47 -0
  70. package/dist/routes/render.js.map +1 -0
  71. package/dist/routes/sessions.d.ts +79 -0
  72. package/dist/routes/sessions.d.ts.map +1 -0
  73. package/dist/routes/sessions.js +37 -0
  74. package/dist/routes/sessions.js.map +1 -0
  75. package/dist/routes/voice.d.ts +92 -0
  76. package/dist/routes/voice.d.ts.map +1 -0
  77. package/dist/routes/voice.js +64 -0
  78. package/dist/routes/voice.js.map +1 -0
  79. package/dist/voice/deepgram-token.d.ts +5 -0
  80. package/dist/voice/deepgram-token.d.ts.map +1 -0
  81. package/dist/voice/deepgram-token.js +63 -0
  82. package/dist/voice/deepgram-token.js.map +1 -0
  83. package/dist/voice/keyterm-builder.d.ts +18 -0
  84. package/dist/voice/keyterm-builder.d.ts.map +1 -0
  85. package/dist/voice/keyterm-builder.js +391 -0
  86. package/dist/voice/keyterm-builder.js.map +1 -0
  87. package/dist/voice/speech-providers.d.ts +25 -0
  88. package/dist/voice/speech-providers.d.ts.map +1 -0
  89. package/dist/voice/speech-providers.js +104 -0
  90. package/dist/voice/speech-providers.js.map +1 -0
  91. package/dist/ws/attachments.d.ts +10 -0
  92. package/dist/ws/attachments.d.ts.map +1 -0
  93. package/dist/ws/attachments.js +63 -0
  94. package/dist/ws/attachments.js.map +1 -0
  95. package/dist/ws/bridge.d.ts +7 -0
  96. package/dist/ws/bridge.d.ts.map +1 -0
  97. package/dist/ws/bridge.js +86 -0
  98. package/dist/ws/bridge.js.map +1 -0
  99. package/dist/ws/clients.d.ts +20 -0
  100. package/dist/ws/clients.d.ts.map +1 -0
  101. package/dist/ws/clients.js +48 -0
  102. package/dist/ws/clients.js.map +1 -0
  103. package/dist/ws/connection.d.ts +8 -0
  104. package/dist/ws/connection.d.ts.map +1 -0
  105. package/dist/ws/connection.js +116 -0
  106. package/dist/ws/connection.js.map +1 -0
  107. package/dist/ws/dispatch.d.ts +5 -0
  108. package/dist/ws/dispatch.d.ts.map +1 -0
  109. package/dist/ws/dispatch.js +139 -0
  110. package/dist/ws/dispatch.js.map +1 -0
  111. package/dist/ws/frames.d.ts +17 -0
  112. package/dist/ws/frames.d.ts.map +1 -0
  113. package/dist/ws/frames.js +37 -0
  114. package/dist/ws/frames.js.map +1 -0
  115. package/dist/ws/handler.d.ts +34 -0
  116. package/dist/ws/handler.d.ts.map +1 -0
  117. package/dist/ws/handler.js +33 -0
  118. package/dist/ws/handler.js.map +1 -0
  119. package/dist/ws/history.d.ts +17 -0
  120. package/dist/ws/history.d.ts.map +1 -0
  121. package/dist/ws/history.js +45 -0
  122. package/dist/ws/history.js.map +1 -0
  123. package/dist/ws/host.d.ts +40 -0
  124. package/dist/ws/host.d.ts.map +1 -0
  125. package/dist/ws/host.js +49 -0
  126. package/dist/ws/host.js.map +1 -0
  127. package/dist/ws/routing.d.ts +12 -0
  128. package/dist/ws/routing.d.ts.map +1 -0
  129. package/dist/ws/routing.js +31 -0
  130. package/dist/ws/routing.js.map +1 -0
  131. package/dist/ws/run-session.d.ts +17 -0
  132. package/dist/ws/run-session.d.ts.map +1 -0
  133. package/dist/ws/run-session.js +160 -0
  134. package/dist/ws/run-session.js.map +1 -0
  135. package/dist/ws/session-catalog.d.ts +25 -0
  136. package/dist/ws/session-catalog.d.ts.map +1 -0
  137. package/dist/ws/session-catalog.js +45 -0
  138. package/dist/ws/session-catalog.js.map +1 -0
  139. package/dist/ws/shrink.d.ts +34 -0
  140. package/dist/ws/shrink.d.ts.map +1 -0
  141. package/dist/ws/shrink.js +91 -0
  142. package/dist/ws/shrink.js.map +1 -0
  143. package/dist/ws/turns.d.ts +77 -0
  144. package/dist/ws/turns.d.ts.map +1 -0
  145. package/dist/ws/turns.js +89 -0
  146. package/dist/ws/turns.js.map +1 -0
  147. package/migrations/001_initial.sql +29 -0
  148. package/migrations/002_session_provider.sql +1 -0
  149. package/migrations/003_session_backend.sql +5 -0
  150. package/migrations/004_drop_gemini_backend.sql +20 -0
  151. package/migrations/005_passkey_credentials.sql +18 -0
  152. package/package.json +72 -0
  153. package/src/agent/backend.ts +308 -0
  154. package/src/app.ts +159 -0
  155. package/src/brain/client.ts +186 -0
  156. package/src/brain/types.ts +44 -0
  157. package/src/cron/scheduler.ts +80 -0
  158. package/src/db/client.ts +85 -0
  159. package/src/files/walker.ts +418 -0
  160. package/src/index.ts +39 -0
  161. package/src/middleware/auth.ts +321 -0
  162. package/src/middleware/passkeys.ts +510 -0
  163. package/src/middleware/tailscale.ts +81 -0
  164. package/src/render/template.ts +124 -0
  165. package/src/routes/brain.ts +305 -0
  166. package/src/routes/files.ts +99 -0
  167. package/src/routes/health.ts +29 -0
  168. package/src/routes/providers.ts +9 -0
  169. package/src/routes/render.ts +68 -0
  170. package/src/routes/sessions.ts +49 -0
  171. package/src/routes/voice.ts +80 -0
  172. package/src/voice/deepgram-token.ts +80 -0
  173. package/src/voice/keyterm-builder.ts +426 -0
  174. package/src/voice/speech-providers.ts +111 -0
  175. package/src/ws/attachments.ts +86 -0
  176. package/src/ws/bridge.ts +139 -0
  177. package/src/ws/clients.ts +57 -0
  178. package/src/ws/connection.ts +132 -0
  179. package/src/ws/dispatch.ts +162 -0
  180. package/src/ws/frames.ts +42 -0
  181. package/src/ws/handler.ts +50 -0
  182. package/src/ws/history.ts +51 -0
  183. package/src/ws/host.ts +69 -0
  184. package/src/ws/routing.ts +43 -0
  185. package/src/ws/run-session.ts +192 -0
  186. package/src/ws/session-catalog.ts +97 -0
  187. package/src/ws/shrink.ts +95 -0
  188. package/src/ws/turns.ts +151 -0
@@ -0,0 +1,112 @@
1
+ import { marked } from "marked";
2
+ marked.setOptions({ gfm: true, breaks: false });
3
+ const STYLES = `
4
+ :root {
5
+ color-scheme: light;
6
+ --bg: #ffffff;
7
+ --fg: #1f2937;
8
+ --muted: #6b7280;
9
+ --border: #e5e7eb;
10
+ --surface: #f8fafc;
11
+ --primary: #2563eb;
12
+ --code-bg: #f3f4f6;
13
+ }
14
+ * { box-sizing: border-box; }
15
+ html, body { margin: 0; padding: 0; background: var(--bg); }
16
+ body {
17
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, "Helvetica Neue", Arial, sans-serif, "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji";
18
+ color: var(--fg);
19
+ font-size: 16px;
20
+ line-height: 1.6;
21
+ padding: 28px 32px;
22
+ word-wrap: break-word;
23
+ }
24
+ h1, h2, h3, h4, h5, h6 { font-weight: 600; line-height: 1.25; margin: 1.4em 0 0.6em; color: var(--fg); }
25
+ h1 { font-size: 1.75em; border-bottom: 1px solid var(--border); padding-bottom: 0.3em; }
26
+ h2 { font-size: 1.4em; border-bottom: 1px solid var(--border); padding-bottom: 0.25em; }
27
+ h3 { font-size: 1.2em; }
28
+ h4 { font-size: 1.05em; }
29
+ p { margin: 0.7em 0; }
30
+ a { color: var(--primary); text-decoration: none; }
31
+ a:hover { text-decoration: underline; }
32
+ ul, ol { padding-left: 1.6em; margin: 0.6em 0; }
33
+ li { margin: 0.2em 0; }
34
+ blockquote {
35
+ margin: 0.8em 0;
36
+ padding: 0.4em 1em;
37
+ border-left: 3px solid var(--border);
38
+ color: var(--muted);
39
+ background: var(--surface);
40
+ border-radius: 0 6px 6px 0;
41
+ }
42
+ code {
43
+ font-family: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
44
+ font-size: 0.9em;
45
+ background: var(--code-bg);
46
+ padding: 0.15em 0.35em;
47
+ border-radius: 4px;
48
+ }
49
+ pre {
50
+ background: var(--code-bg);
51
+ border: 1px solid var(--border);
52
+ border-radius: 8px;
53
+ padding: 0.8em 1em;
54
+ overflow-x: auto;
55
+ font-size: 0.88em;
56
+ line-height: 1.5;
57
+ }
58
+ pre code { background: transparent; padding: 0; border-radius: 0; }
59
+ hr { border: 0; border-top: 1px solid var(--border); margin: 1.6em 0; }
60
+ table { border-collapse: collapse; margin: 0.8em 0; width: 100%; }
61
+ th, td { border: 1px solid var(--border); padding: 0.45em 0.7em; text-align: left; }
62
+ th { background: var(--surface); font-weight: 600; }
63
+ img { max-width: 100%; height: auto; }
64
+ .remote-image {
65
+ display: inline-block; padding: 2px 8px; border: 1px dashed #b0b0b0;
66
+ border-radius: 4px; color: #6b6b6b; font-size: 0.9em;
67
+ }
68
+ /* Trim trailing whitespace at the bottom so screenshots crop tightly */
69
+ body > *:last-child { margin-bottom: 0; }
70
+ body > *:first-child { margin-top: 0; }
71
+ `;
72
+ function escapeHtml(s) {
73
+ return s
74
+ .replace(/&/g, "&")
75
+ .replace(/</g, "&lt;")
76
+ .replace(/>/g, "&gt;")
77
+ .replace(/"/g, "&quot;")
78
+ .replace(/'/g, "&#39;");
79
+ }
80
+ /**
81
+ * The renderer denies the page all network access (see
82
+ * @schlessera/brain-render-puppeteer), so a remote `<img>` would silently render
83
+ * as a broken-image box. Replace those with a visible, honest placeholder —
84
+ * inlined `data:` images still render normally.
85
+ */
86
+ function placeholderRemoteImages(html) {
87
+ return html.replace(/<img\b[^>]*\bsrc\s*=\s*["']([^"']+)["'][^>]*>/gi, (tag, src) => {
88
+ if (/^data:/i.test(src))
89
+ return tag;
90
+ const alt = /\balt\s*=\s*["']([^"']*)["']/i.exec(tag)?.[1];
91
+ const label = alt ? escapeHtml(alt) : "remote image";
92
+ return `<span class="remote-image">[${label} — not embedded]</span>`;
93
+ });
94
+ }
95
+ export function buildHtmlDocument(opts) {
96
+ const rendered = opts.contentType === "markdown"
97
+ ? marked.parse(opts.content, { async: false })
98
+ : opts.content;
99
+ const inner = placeholderRemoteImages(rendered);
100
+ const title = opts.title ?? "Shared from Brain";
101
+ return `<!doctype html>
102
+ <html lang="en">
103
+ <head>
104
+ <meta charset="utf-8" />
105
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
106
+ <title>${escapeHtml(title)}</title>
107
+ <style>${STYLES}</style>
108
+ </head>
109
+ <body>${inner}</body>
110
+ </html>`;
111
+ }
112
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/render/template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,MAAM,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;AAEhD,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoEd,CAAC;AAEF,SAAS,UAAU,CAAC,CAAS;IAC3B,OAAO,CAAC;SACL,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;GAKG;AACH,SAAS,uBAAuB,CAAC,IAAY;IAC3C,OAAO,IAAI,CAAC,OAAO,CACjB,iDAAiD,EACjD,CAAC,GAAG,EAAE,GAAW,EAAE,EAAE;QACnB,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,GAAG,CAAC;QACpC,MAAM,GAAG,GAAG,+BAA+B,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3D,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;QACrD,OAAO,+BAA+B,KAAK,yBAAyB,CAAC;IACvE,CAAC,CACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAIjC;IACC,MAAM,QAAQ,GACZ,IAAI,CAAC,WAAW,KAAK,UAAU;QAC7B,CAAC,CAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAY;QAC1D,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;IACnB,MAAM,KAAK,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,mBAAmB,CAAC;IAChD,OAAO;;;;;WAKE,UAAU,CAAC,KAAK,CAAC;WACjB,MAAM;;QAET,KAAK;QACL,CAAC;AACT,CAAC"}
@@ -0,0 +1,155 @@
1
+ export declare const brainRoutes: import("hono/hono-base").HonoBase<import("hono/types").BlankEnv, {
2
+ "/brain/search": {
3
+ $get: {
4
+ input: {};
5
+ output: {
6
+ error: string;
7
+ };
8
+ outputFormat: "json";
9
+ status: 400;
10
+ } | {
11
+ input: {};
12
+ output: {
13
+ results: {
14
+ path: string;
15
+ title: string;
16
+ type: string;
17
+ relevance: string;
18
+ score: number;
19
+ snippet: string;
20
+ }[];
21
+ warnings: string[];
22
+ };
23
+ outputFormat: "json";
24
+ status: import("hono/utils/http-status").ContentfulStatusCode;
25
+ } | {
26
+ input: {};
27
+ output: {
28
+ error: string;
29
+ };
30
+ outputFormat: "json";
31
+ status: 500;
32
+ };
33
+ };
34
+ } & {
35
+ "/brain/briefing": {
36
+ $get: {
37
+ input: {};
38
+ output: {
39
+ content: string;
40
+ };
41
+ outputFormat: "json";
42
+ status: import("hono/utils/http-status").ContentfulStatusCode;
43
+ } | {
44
+ input: {};
45
+ output: {
46
+ error: string;
47
+ };
48
+ outputFormat: "json";
49
+ status: 500;
50
+ };
51
+ };
52
+ } & {
53
+ "/brain/whatsup": {
54
+ $post: {
55
+ input: {};
56
+ output: {};
57
+ outputFormat: string;
58
+ status: import("hono/utils/http-status").StatusCode;
59
+ };
60
+ };
61
+ } & {
62
+ "/brain/stats": {
63
+ $get: {
64
+ input: {};
65
+ output: {
66
+ documents: number;
67
+ byType: {
68
+ [x: string]: number;
69
+ };
70
+ byStatus: {
71
+ [x: string]: number;
72
+ };
73
+ byRelevance: {
74
+ [x: string]: number;
75
+ };
76
+ tags: number;
77
+ links: number;
78
+ brokenLinks: number;
79
+ chunks: number;
80
+ };
81
+ outputFormat: "json";
82
+ status: import("hono/utils/http-status").ContentfulStatusCode;
83
+ } | {
84
+ input: {};
85
+ output: {
86
+ error: string;
87
+ };
88
+ outputFormat: "json";
89
+ status: 500;
90
+ };
91
+ };
92
+ } & {
93
+ "/brain/list": {
94
+ $get: {
95
+ input: {};
96
+ output: {
97
+ results: {
98
+ path: string;
99
+ title: string;
100
+ type: string;
101
+ status: string;
102
+ relevance: string;
103
+ tags: string[];
104
+ created: string;
105
+ updated: string;
106
+ summary?: string | undefined;
107
+ }[];
108
+ };
109
+ outputFormat: "json";
110
+ status: import("hono/utils/http-status").ContentfulStatusCode;
111
+ } | {
112
+ input: {};
113
+ output: {
114
+ error: string;
115
+ };
116
+ outputFormat: "json";
117
+ status: 500;
118
+ };
119
+ };
120
+ } & {
121
+ "/brain/sync": {
122
+ $post: {
123
+ input: {};
124
+ output: {};
125
+ outputFormat: string;
126
+ status: import("hono/utils/http-status").StatusCode;
127
+ };
128
+ };
129
+ } & {
130
+ "/brain/add": {
131
+ $post: {
132
+ input: {};
133
+ output: {
134
+ error: string;
135
+ };
136
+ outputFormat: "json";
137
+ status: 400;
138
+ } | {
139
+ input: {};
140
+ output: {
141
+ success: true;
142
+ };
143
+ outputFormat: "json";
144
+ status: import("hono/utils/http-status").ContentfulStatusCode;
145
+ } | {
146
+ input: {};
147
+ output: {
148
+ error: string;
149
+ };
150
+ outputFormat: "json";
151
+ status: 500;
152
+ };
153
+ };
154
+ }, "/", "/brain/add">;
155
+ //# sourceMappingURL=brain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brain.d.ts","sourceRoot":"","sources":["../../src/routes/brain.ts"],"names":[],"mappings":"AAiCA,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBA+QpB,CAAC"}
@@ -0,0 +1,250 @@
1
+ import { Hono } from "hono";
2
+ import { streamSSE } from "hono/streaming";
3
+ import { brainSearch, brainBriefing, brainStats, brainList, brainAdd, brainCliCommand, } from "../brain/client.js";
4
+ import { buildKeyterms, writeCache } from "../voice/keyterm-builder.js";
5
+ import { existsSync } from "fs";
6
+ import { join } from "path";
7
+ /**
8
+ * Locate the brain repo's `whatsup` script, relative to the repo root.
9
+ *
10
+ * Unlike the commands in brain/client.ts, whatsup is NOT part of the packaged
11
+ * @schlessera/brain CLI (it is absent from CORE_COMMAND_NAMES) — it stays a
12
+ * repo-local script. A brain repo migrated onto the published packages deletes
13
+ * the vendored `scripts/` tree and keeps whatsup at `private/whatsup.ts`; the
14
+ * legacy layout has it at `scripts/whatsup.ts`. Try both, newest layout first.
15
+ *
16
+ * Returns null when neither exists, so the route can report that plainly
17
+ * instead of surfacing bun's "module not found" through the SSE stream.
18
+ */
19
+ function findWhatsupScript(brainPath) {
20
+ for (const rel of ["private/whatsup.ts", "scripts/whatsup.ts"]) {
21
+ if (existsSync(join(brainPath, rel)))
22
+ return rel;
23
+ }
24
+ return null;
25
+ }
26
+ export const brainRoutes = new Hono()
27
+ .get("/brain/search", async (c) => {
28
+ const q = c.req.query("q");
29
+ if (!q) {
30
+ return c.json({ error: "Query parameter 'q' is required" }, 400);
31
+ }
32
+ try {
33
+ const { results, warnings } = await brainSearch(q, {
34
+ type: c.req.query("type"),
35
+ tag: c.req.query("tag"),
36
+ limit: c.req.query("limit") ? Number(c.req.query("limit")) : undefined,
37
+ mode: c.req.query("mode"),
38
+ });
39
+ return c.json({ results, warnings });
40
+ }
41
+ catch (err) {
42
+ return c.json({ error: err instanceof Error ? err.message : "Search failed" }, 500);
43
+ }
44
+ })
45
+ .get("/brain/briefing", async (c) => {
46
+ try {
47
+ const content = await brainBriefing();
48
+ return c.json({ content });
49
+ }
50
+ catch (err) {
51
+ return c.json({ error: err instanceof Error ? err.message : "Briefing failed" }, 500);
52
+ }
53
+ })
54
+ .post("/brain/whatsup", async (c) => {
55
+ const BRAIN_PATH = process.env.BRAIN_PATH ||
56
+ `${process.env.HOME || "/root"}/brain`;
57
+ // Defeat reverse-proxy buffering for SSE
58
+ c.header("X-Accel-Buffering", "no");
59
+ return streamSSE(c, async (stream) => {
60
+ const send = (data) => stream.writeSSE({ data: JSON.stringify(data) });
61
+ // Heartbeat keeps the proxy from idling out the connection while
62
+ // the upstream LLM call is in flight (~5-15s with no stdout)
63
+ const heartbeat = setInterval(() => {
64
+ stream
65
+ .writeSSE({ event: "ping", data: "" })
66
+ .catch(() => { });
67
+ }, 3000);
68
+ try {
69
+ await send({ type: "start", text: "Running whatsup briefing..." });
70
+ const script = findWhatsupScript(BRAIN_PATH);
71
+ if (!script) {
72
+ // Terminate with the frames the client actually handles: it only
73
+ // reads "progress" and "done", so an "error" type would leave the
74
+ // panel spinning on an empty body.
75
+ await send({
76
+ type: "progress",
77
+ text: "whatsup script not found in the brain repo (looked for private/whatsup.ts and scripts/whatsup.ts).",
78
+ });
79
+ await send({ type: "done", success: false, text: "Not available" });
80
+ return;
81
+ }
82
+ // --gemini: the default backend needs ANTHROPIC_API_KEY, which is no
83
+ // longer set (Claude runs on subscription auth, and the script's
84
+ // --claude backend uses --bare mode, which can't read the
85
+ // CLAUDE_CODE_OAUTH_TOKEN either).
86
+ const proc = Bun.spawn(["bun", script, "--gemini"], {
87
+ cwd: BRAIN_PATH,
88
+ stdout: "pipe",
89
+ stderr: "pipe",
90
+ env: { ...process.env, NO_COLOR: "1" },
91
+ });
92
+ const reader = proc.stdout.getReader();
93
+ const decoder = new TextDecoder();
94
+ let buffer = "";
95
+ try {
96
+ while (true) {
97
+ const { done, value } = await reader.read();
98
+ if (done)
99
+ break;
100
+ buffer += decoder.decode(value, { stream: true });
101
+ const lines = buffer.split("\n");
102
+ buffer = lines.pop() || "";
103
+ for (const line of lines) {
104
+ await send({ type: "progress", text: line });
105
+ }
106
+ }
107
+ if (buffer.trim()) {
108
+ await send({ type: "progress", text: buffer });
109
+ }
110
+ }
111
+ catch { }
112
+ const exitCode = await proc.exited;
113
+ const stderr = await new Response(proc.stderr).text();
114
+ if (stderr.trim()) {
115
+ for (const line of stderr.split("\n")) {
116
+ if (line.trim())
117
+ await send({ type: "progress", text: line });
118
+ }
119
+ }
120
+ await send({
121
+ type: "done",
122
+ success: exitCode === 0,
123
+ text: exitCode === 0
124
+ ? "Briefing complete"
125
+ : `Failed (exit ${exitCode})`,
126
+ });
127
+ }
128
+ finally {
129
+ clearInterval(heartbeat);
130
+ }
131
+ });
132
+ })
133
+ .get("/brain/stats", async (c) => {
134
+ try {
135
+ const stats = await brainStats();
136
+ return c.json(stats);
137
+ }
138
+ catch (err) {
139
+ return c.json({ error: err instanceof Error ? err.message : "Stats failed" }, 500);
140
+ }
141
+ })
142
+ .get("/brain/list", async (c) => {
143
+ try {
144
+ const results = await brainList({
145
+ type: c.req.query("type"),
146
+ tag: c.req.query("tag"),
147
+ status: c.req.query("status"),
148
+ relevance: c.req.query("relevance"),
149
+ limit: c.req.query("limit") ? Number(c.req.query("limit")) : undefined,
150
+ });
151
+ return c.json({ results });
152
+ }
153
+ catch (err) {
154
+ return c.json({ error: err instanceof Error ? err.message : "List failed" }, 500);
155
+ }
156
+ })
157
+ .post("/brain/sync", async (c) => {
158
+ // Stream sync output via SSE so the client sees live progress.
159
+ // brain sync spawns a nested Claude Code process that can take minutes.
160
+ const BRAIN_PATH = process.env.BRAIN_PATH ||
161
+ `${process.env.HOME || "/root"}/brain`;
162
+ return streamSSE(c, async (stream) => {
163
+ const send = (data) => stream.writeSSE({ data: JSON.stringify(data) });
164
+ await send({ type: "start", text: "Starting brain sync..." });
165
+ // The nested Claude process can be silent for minutes; without traffic
166
+ // the socket gets cut by idle timeouts (Bun's own, or a proxy's). SSE
167
+ // comment lines are ignored by EventSource and data-line parsers.
168
+ const keepalive = setInterval(() => {
169
+ stream.write(": keepalive\n\n").catch(() => { });
170
+ }, 15_000);
171
+ // Merge stderr into stdout — brain sync spawns a nested Claude Code
172
+ // process whose output goes to stderr. The command comes from
173
+ // brainCliCommand() (packaged bin or legacy vendored script), passed to
174
+ // bash as positional args rather than interpolated into the script, so a
175
+ // BRAIN_PATH containing spaces or shell metacharacters stays inert.
176
+ const [cliBin, ...cliArgs] = brainCliCommand();
177
+ const proc = Bun.spawn(["bash", "-c", '"$0" "$@" 2>&1', cliBin, ...cliArgs, "sync"], {
178
+ cwd: BRAIN_PATH,
179
+ stdout: "pipe",
180
+ stderr: "pipe",
181
+ env: { ...process.env, NO_COLOR: "1" },
182
+ });
183
+ const reader = proc.stdout.getReader();
184
+ const decoder = new TextDecoder();
185
+ let buffer = "";
186
+ try {
187
+ while (true) {
188
+ const { done, value } = await reader.read();
189
+ if (done)
190
+ break;
191
+ buffer += decoder.decode(value, { stream: true });
192
+ const lines = buffer.split("\n");
193
+ buffer = lines.pop() || "";
194
+ for (const line of lines) {
195
+ if (line.trim()) {
196
+ await send({ type: "progress", text: line });
197
+ }
198
+ }
199
+ }
200
+ if (buffer.trim()) {
201
+ await send({ type: "progress", text: buffer });
202
+ }
203
+ }
204
+ catch { }
205
+ finally {
206
+ clearInterval(keepalive);
207
+ }
208
+ const exitCode = await proc.exited;
209
+ // Rebuild voice keyterms cache after a successful sync.
210
+ if (exitCode === 0) {
211
+ try {
212
+ const cache = buildKeyterms();
213
+ writeCache(cache);
214
+ await send({
215
+ type: "progress",
216
+ text: `[voice] Rebuilt keyterms cache (${cache.count} terms)`,
217
+ });
218
+ }
219
+ catch (err) {
220
+ await send({
221
+ type: "progress",
222
+ text: `[voice] Keyterm rebuild failed: ${err instanceof Error ? err.message : String(err)}`,
223
+ });
224
+ }
225
+ }
226
+ await send({
227
+ type: "done",
228
+ success: exitCode === 0,
229
+ text: exitCode === 0 ? "Sync completed" : `Sync failed (exit ${exitCode})`,
230
+ });
231
+ });
232
+ })
233
+ .post("/brain/add", async (c) => {
234
+ const body = await c.req.json();
235
+ if (!body.content) {
236
+ return c.json({ error: "Field 'content' is required" }, 400);
237
+ }
238
+ try {
239
+ await brainAdd(body.content, {
240
+ type: body.type,
241
+ title: body.title,
242
+ tags: body.tags,
243
+ });
244
+ return c.json({ success: true });
245
+ }
246
+ catch (err) {
247
+ return c.json({ error: err instanceof Error ? err.message : "Add failed" }, 500);
248
+ }
249
+ });
250
+ //# sourceMappingURL=brain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brain.js","sourceRoot":"","sources":["../../src/routes/brain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,89 @@
1
+ export declare const filesRoutes: import("hono/hono-base").HonoBase<import("hono/types").BlankEnv, {
2
+ "/files/tree": {
3
+ $get: {
4
+ input: {};
5
+ output: {
6
+ path: string;
7
+ entries: {
8
+ name: string;
9
+ path: string;
10
+ type: "dir" | "file";
11
+ size?: number | undefined;
12
+ mtime?: number | undefined;
13
+ }[];
14
+ };
15
+ outputFormat: "json";
16
+ status: import("hono/utils/http-status").ContentfulStatusCode;
17
+ } | {
18
+ input: {};
19
+ output: {
20
+ error: string;
21
+ size?: number | undefined;
22
+ };
23
+ outputFormat: "json";
24
+ status: 400 | 404 | 413 | 500;
25
+ };
26
+ };
27
+ } & {
28
+ "/files/content": {
29
+ $get: {
30
+ input: {};
31
+ output: {};
32
+ outputFormat: string;
33
+ status: import("hono/utils/http-status").StatusCode;
34
+ };
35
+ };
36
+ } & {
37
+ "/files/resolve": {
38
+ $get: {
39
+ input: {};
40
+ output: {
41
+ error: string;
42
+ size?: number | undefined;
43
+ };
44
+ outputFormat: "json";
45
+ status: 400 | 404 | 413 | 500;
46
+ } | {
47
+ input: {};
48
+ output: {
49
+ error: string;
50
+ };
51
+ outputFormat: "json";
52
+ status: 400;
53
+ } | {
54
+ input: {};
55
+ output: {
56
+ ancestors: string[];
57
+ exists: boolean;
58
+ type?: "dir" | "file" | undefined;
59
+ path: string;
60
+ };
61
+ outputFormat: "json";
62
+ status: import("hono/utils/http-status").ContentfulStatusCode;
63
+ };
64
+ };
65
+ } & {
66
+ "/files/wikilinks": {
67
+ $get: {
68
+ input: {};
69
+ output: {
70
+ error: string;
71
+ size?: number | undefined;
72
+ };
73
+ outputFormat: "json";
74
+ status: 400 | 404 | 413 | 500;
75
+ } | {
76
+ input: {};
77
+ output: {
78
+ generatedAt: number;
79
+ count: number;
80
+ slugs: {
81
+ [x: string]: string;
82
+ };
83
+ };
84
+ outputFormat: "json";
85
+ status: import("hono/utils/http-status").ContentfulStatusCode;
86
+ };
87
+ };
88
+ }, "/", "/files/wikilinks">;
89
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/routes/files.ts"],"names":[],"mappings":"AA6BA,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;uBAd+B,MAAM;uBAAS,MAAM;;;;;;;;;;;;;;;;;;;;uBAArB,MAAM;uBAAS,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBAArB,MAAM;uBAAS,MAAM;;;;;;;;;;;;;;;;;2BAmFxE,CAAC"}