reasonix 0.34.1 → 0.36.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/dashboard/app.css +16 -14
- package/dashboard/dist/app.js +77 -18
- package/dashboard/dist/app.js.map +1 -1
- package/dist/cli/{chat-TD6GR3QK.js → chat-RGMYAOY2.js} +18 -17
- package/dist/cli/{chunk-SA4UGZPG.js → chunk-2MCYGFLK.js} +15 -10
- package/dist/cli/chunk-2MCYGFLK.js.map +1 -0
- package/dist/cli/{chunk-SW3CCXEV.js → chunk-4Q3GRJIU.js} +2 -2
- package/dist/cli/{chunk-5JXXEPDM.js → chunk-BHLHOS5Y.js} +8 -2
- package/dist/cli/chunk-BHLHOS5Y.js.map +1 -0
- package/dist/cli/{chunk-F3ILWP2L.js → chunk-BJ376EN3.js} +9 -8
- package/dist/cli/chunk-BJ376EN3.js.map +1 -0
- package/dist/cli/{chunk-2AWTGJ2C.js → chunk-CRPQUBP6.js} +26 -9
- package/dist/cli/{chunk-2AWTGJ2C.js.map → chunk-CRPQUBP6.js.map} +1 -1
- package/dist/cli/{chunk-EINEIIIW.js → chunk-EN4LAZW5.js} +563 -250
- package/dist/cli/chunk-EN4LAZW5.js.map +1 -0
- package/dist/cli/{chunk-OERAGRJX.js → chunk-IPCPEZWQ.js} +2 -2
- package/dist/cli/{chunk-U3V2ZQ5J.js → chunk-KJQIA4US.js} +6 -2
- package/dist/cli/chunk-KJQIA4US.js.map +1 -0
- package/dist/cli/{chunk-Q36KBLSU.js → chunk-MLXUGPJE.js} +292 -35
- package/dist/cli/chunk-MLXUGPJE.js.map +1 -0
- package/dist/cli/{chunk-SX6L4HZZ.js → chunk-QPNZWUZF.js} +53 -6
- package/dist/cli/chunk-QPNZWUZF.js.map +1 -0
- package/dist/cli/{chunk-LNTORE5K.js → chunk-QRUQ2BFT.js} +159 -40
- package/dist/cli/chunk-QRUQ2BFT.js.map +1 -0
- package/dist/cli/{chunk-KZHMKOJH.js → chunk-T52GAWPP.js} +25 -3
- package/dist/cli/chunk-T52GAWPP.js.map +1 -0
- package/dist/cli/{chunk-I6YIAK6C.js → chunk-UNMYFZPZ.js} +2 -2
- package/dist/cli/{update-4TJWRUIN.js → chunk-WJ3YX4PZ.js} +51 -12
- package/dist/cli/chunk-WJ3YX4PZ.js.map +1 -0
- package/dist/cli/{chunk-RXGEGA7K.js → chunk-XQIFIB3U.js} +18 -7
- package/dist/cli/{chunk-RXGEGA7K.js.map → chunk-XQIFIB3U.js.map} +1 -1
- package/dist/cli/{chunk-2EBODRRO.js → chunk-ZJR4QLXB.js} +5 -1
- package/dist/cli/{chunk-2EBODRRO.js.map → chunk-ZJR4QLXB.js.map} +1 -1
- package/dist/cli/{chunk-6TMHAK5D.js → chunk-ZU45XW3P.js} +2 -2
- package/dist/cli/code-KJB3WDU6.js +435 -0
- package/dist/cli/code-KJB3WDU6.js.map +1 -0
- package/dist/cli/{commands-MEZPSEHV.js → commands-FE2UDFBC.js} +3 -3
- package/dist/cli/{commit-CE4EFTUQ.js → commit-3IAGB22T.js} +5 -4
- package/dist/cli/commit-3IAGB22T.js.map +1 -0
- package/dist/cli/{doctor-YASM64X6.js → doctor-DKD34EFD.js} +7 -7
- package/dist/cli/index.js +35 -33
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/{mcp-LDFK5QJI.js → mcp-2RDEQST6.js} +2 -2
- package/dist/cli/{mcp-browse-FYHEITCM.js → mcp-browse-VM5GLRBQ.js} +2 -2
- package/dist/cli/{mcp-inspect-T2HBR22P.js → mcp-inspect-CWSVCZUQ.js} +3 -3
- package/dist/cli/{prompt-V47QKSAR.js → prompt-YEKXMNNV.js} +3 -3
- package/dist/cli/{replay-JEDLU7F2.js → replay-D7RT2DR7.js} +3 -3
- package/dist/cli/replay-D7RT2DR7.js.map +1 -0
- package/dist/cli/{run-NHD2RSTD.js → run-FK5UBIIM.js} +13 -12
- package/dist/cli/run-FK5UBIIM.js.map +1 -0
- package/dist/cli/{server-MC4A4WAJ.js → server-W4XJK4GX.js} +17 -17
- package/dist/cli/{server-MC4A4WAJ.js.map → server-W4XJK4GX.js.map} +1 -1
- package/dist/cli/{sessions-ZHWJEW4L.js → sessions-YZXWMIWW.js} +10 -10
- package/dist/cli/{setup-DK43MT47.js → setup-IIAJXHP4.js} +196 -130
- package/dist/cli/setup-IIAJXHP4.js.map +1 -0
- package/dist/cli/update-GUCWB4UN.js +13 -0
- package/dist/cli/update-GUCWB4UN.js.map +1 -0
- package/dist/cli/{version-O362UKPM.js → version-DWD6RLIU.js} +12 -12
- package/dist/index.d.ts +19 -2
- package/dist/index.js +543 -78
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli/chunk-5JXXEPDM.js.map +0 -1
- package/dist/cli/chunk-EINEIIIW.js.map +0 -1
- package/dist/cli/chunk-F3ILWP2L.js.map +0 -1
- package/dist/cli/chunk-KZHMKOJH.js.map +0 -1
- package/dist/cli/chunk-LNTORE5K.js.map +0 -1
- package/dist/cli/chunk-Q36KBLSU.js.map +0 -1
- package/dist/cli/chunk-SA4UGZPG.js.map +0 -1
- package/dist/cli/chunk-SX6L4HZZ.js.map +0 -1
- package/dist/cli/chunk-U3V2ZQ5J.js.map +0 -1
- package/dist/cli/code-TGUOQBRJ.js +0 -153
- package/dist/cli/code-TGUOQBRJ.js.map +0 -1
- package/dist/cli/commit-CE4EFTUQ.js.map +0 -1
- package/dist/cli/replay-JEDLU7F2.js.map +0 -1
- package/dist/cli/run-NHD2RSTD.js.map +0 -1
- package/dist/cli/setup-DK43MT47.js.map +0 -1
- package/dist/cli/update-4TJWRUIN.js.map +0 -1
- /package/dist/cli/{chat-TD6GR3QK.js.map → chat-RGMYAOY2.js.map} +0 -0
- /package/dist/cli/{chunk-SW3CCXEV.js.map → chunk-4Q3GRJIU.js.map} +0 -0
- /package/dist/cli/{chunk-OERAGRJX.js.map → chunk-IPCPEZWQ.js.map} +0 -0
- /package/dist/cli/{chunk-I6YIAK6C.js.map → chunk-UNMYFZPZ.js.map} +0 -0
- /package/dist/cli/{chunk-6TMHAK5D.js.map → chunk-ZU45XW3P.js.map} +0 -0
- /package/dist/cli/{commands-MEZPSEHV.js.map → commands-FE2UDFBC.js.map} +0 -0
- /package/dist/cli/{doctor-YASM64X6.js.map → doctor-DKD34EFD.js.map} +0 -0
- /package/dist/cli/{mcp-LDFK5QJI.js.map → mcp-2RDEQST6.js.map} +0 -0
- /package/dist/cli/{mcp-browse-FYHEITCM.js.map → mcp-browse-VM5GLRBQ.js.map} +0 -0
- /package/dist/cli/{mcp-inspect-T2HBR22P.js.map → mcp-inspect-CWSVCZUQ.js.map} +0 -0
- /package/dist/cli/{prompt-V47QKSAR.js.map → prompt-YEKXMNNV.js.map} +0 -0
- /package/dist/cli/{sessions-ZHWJEW4L.js.map → sessions-YZXWMIWW.js.map} +0 -0
- /package/dist/cli/{version-O362UKPM.js.map → version-DWD6RLIU.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/index.ts","../../src/server/api/events.ts","../../src/server/assets.ts","../../src/server/api/abort.ts","../../src/server/api/edit-mode.ts","../../src/server/api/files.ts","../../src/server/api/health.ts","../../src/server/api/hooks.ts","../../src/server/api/hooks-events.ts","../../src/server/api/index-config.ts","../../src/server/api/loop.ts","../../src/server/api/mcp.ts","../../src/server/api/memory.ts","../../src/server/api/messages.ts","../../src/server/api/modal.ts","../../src/server/api/models.ts","../../src/server/api/cockpit-events.ts","../../src/server/api/cockpit.ts","../../src/server/api/overview.ts","../../src/server/api/permissions.ts","../../src/server/api/plans.ts","../../src/server/api/semantic.ts","../../src/server/api/sessions.ts","../../src/server/api/settings.ts","../../src/server/api/skills.ts","../../src/server/api/slash.ts","../../src/server/api/submit.ts","../../src/server/api/tools.ts","../../src/server/api/usage.ts","../../src/server/router.ts"],"sourcesContent":["/** Dashboard HTTP server — pinned to 127.0.0.1, ephemeral per-boot token; mutations require the token in the header (CSRF). */\n\nimport { randomBytes } from \"node:crypto\";\nimport { type IncomingMessage, type ServerResponse, createServer } from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\nimport { handleEvents } from \"./api/events.js\";\nimport { renderIndexHtml, serveAsset } from \"./assets.js\";\nimport type { DashboardContext } from \"./context.js\";\nimport { handleApi } from \"./router.js\";\n\nexport interface StartDashboardOptions {\n /** Force a specific port. 0 = ephemeral. Default: 0. */\n port?: number;\n /** Host to bind. Argument exists for tests; production must keep 127.0.0.1 (no remote auth). */\n host?: string;\n token?: string;\n}\n\nexport interface DashboardServerHandle {\n url: string;\n token: string;\n port: number;\n /** Stop accepting new connections, drain, close. Idempotent. */\n close: () => Promise<void>;\n}\n\nfunction mintToken(): string {\n return randomBytes(32).toString(\"hex\");\n}\n\n/** `===` short-circuits on first mismatch — leaks position via timing even on localhost. */\nexport function constantTimeEquals(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n let mismatch = 0;\n for (let i = 0; i < a.length; i++) {\n mismatch |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return mismatch === 0;\n}\n\n/** Mutations require header (CSRF); reads accept header or query. Returns null on success. */\nexport function checkAuth(\n req: IncomingMessage,\n expectedToken: string,\n isMutation: boolean,\n): { status: number; body: string } | null {\n const url = new URL(req.url ?? \"/\", \"http://localhost\");\n const queryToken = url.searchParams.get(\"token\") ?? \"\";\n const headerToken =\n typeof req.headers[\"x-reasonix-token\"] === \"string\"\n ? (req.headers[\"x-reasonix-token\"] as string)\n : \"\";\n\n if (isMutation) {\n // Header-only for mutations. Query-only requests would still\n // reject here even if the token matched.\n if (!headerToken || !constantTimeEquals(headerToken, expectedToken)) {\n return {\n status: 403,\n body: JSON.stringify({\n error:\n \"mutation requires X-Reasonix-Token header (CSRF defence — query token alone is rejected for POST/DELETE).\",\n }),\n };\n }\n return null;\n }\n\n // Reads accept either form. We compare both candidates against the\n // expected token in constant time and treat the OR as \"any match\n // lets through.\"\n if (\n (queryToken && constantTimeEquals(queryToken, expectedToken)) ||\n (headerToken && constantTimeEquals(headerToken, expectedToken))\n ) {\n return null;\n }\n return {\n status: 401,\n body: JSON.stringify({ error: \"missing or invalid token\" }),\n };\n}\n\nconst MAX_BODY_BYTES = 256 * 1024;\n\nexport async function readBody(req: IncomingMessage): Promise<string> {\n let total = 0;\n const chunks: Buffer[] = [];\n return new Promise((resolve, reject) => {\n req.on(\"data\", (chunk: Buffer) => {\n total += chunk.length;\n if (total > MAX_BODY_BYTES) {\n reject(new Error(`body exceeds ${MAX_BODY_BYTES} bytes`));\n req.destroy();\n return;\n }\n chunks.push(chunk);\n });\n req.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf8\")));\n req.on(\"error\", reject);\n });\n}\n\nexport async function dispatch(\n req: IncomingMessage,\n res: ServerResponse,\n ctx: DashboardContext,\n expectedToken: string,\n): Promise<void> {\n const url = new URL(req.url ?? \"/\", \"http://localhost\");\n const path = url.pathname;\n const method = (req.method ?? \"GET\").toUpperCase();\n const isMutation = method === \"POST\" || method === \"DELETE\" || method === \"PUT\";\n\n // SPA routes — token-gate the HTML so a stranger can't even see the\n // shell without the token. This also means the user MUST come in\n // through the token-bearing URL we print to the TUI.\n if (path === \"/\" || path === \"/index.html\") {\n const fail = checkAuth(req, expectedToken, false);\n if (fail) {\n res.writeHead(fail.status, { \"content-type\": \"text/plain\" });\n res.end(\"unauthorized — open the URL printed by /dashboard, including ?token=…\");\n return;\n }\n const html = renderIndexHtml(expectedToken, ctx.mode);\n res.writeHead(200, { \"content-type\": \"text/html; charset=utf-8\" });\n res.end(html);\n return;\n }\n\n if (path.startsWith(\"/assets/\")) {\n const fail = checkAuth(req, expectedToken, false);\n if (fail) {\n res.writeHead(fail.status);\n res.end();\n return;\n }\n const asset = serveAsset(path.slice(\"/assets/\".length));\n if (!asset) {\n res.writeHead(404);\n res.end(\"not found\");\n return;\n }\n res.writeHead(200, { \"content-type\": asset.contentType });\n res.end(asset.body);\n return;\n }\n\n // SSE event stream — special-cased BEFORE the normal `/api/*` branch\n // because it keeps the response open and writes its own frames; the\n // normal path would try to JSON-encode and end the response.\n if (path === \"/api/events\") {\n const fail = checkAuth(req, expectedToken, false);\n if (fail) {\n res.writeHead(fail.status, { \"content-type\": \"application/json\" });\n res.end(fail.body);\n return;\n }\n handleEvents(req, res, ctx);\n return;\n }\n\n if (path.startsWith(\"/api/\")) {\n const fail = checkAuth(req, expectedToken, isMutation);\n if (fail) {\n res.writeHead(fail.status, { \"content-type\": \"application/json\" });\n res.end(fail.body);\n return;\n }\n let body = \"\";\n if (isMutation) {\n try {\n body = await readBody(req);\n } catch (err) {\n res.writeHead(413, { \"content-type\": \"application/json\" });\n res.end(JSON.stringify({ error: (err as Error).message }));\n return;\n }\n }\n const result = await handleApi(path.slice(\"/api/\".length), method, body, ctx, url.searchParams);\n res.writeHead(result.status, { \"content-type\": \"application/json\" });\n res.end(JSON.stringify(result.body));\n return;\n }\n\n res.writeHead(404, { \"content-type\": \"text/plain\" });\n res.end(\"not found\");\n}\n\n/**\n * Boot a server bound to 127.0.0.1, return an awaitable handle.\n */\nexport function startDashboardServer(\n ctx: DashboardContext,\n opts: StartDashboardOptions = {},\n): Promise<DashboardServerHandle> {\n const token = opts.token ?? mintToken();\n const host = opts.host ?? \"127.0.0.1\";\n const port = opts.port ?? 0;\n\n return new Promise((resolve, reject) => {\n const server = createServer((req, res) => {\n dispatch(req, res, ctx, token).catch((err) => {\n if (!res.headersSent) {\n res.writeHead(500, { \"content-type\": \"application/json\" });\n }\n res.end(JSON.stringify({ error: (err as Error).message }));\n });\n });\n server.on(\"error\", reject);\n server.listen(port, host, () => {\n const addr = server.address() as AddressInfo;\n const finalPort = addr.port;\n const url = `http://${host}:${finalPort}/?token=${token}`;\n\n let closed = false;\n const close = (): Promise<void> =>\n new Promise<void>((doneResolve) => {\n if (closed) return doneResolve();\n closed = true;\n server.close(() => doneResolve());\n // Force any keep-alive sockets to drop after a short grace.\n setTimeout(() => server.closeAllConnections?.(), 1000).unref();\n });\n\n resolve({ url, token, port: finalPort, close });\n });\n });\n}\n","/** SSE stream of DashboardEvents; 25s ping keeps proxies from dropping idle connections. */\n\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { DashboardContext, DashboardEvent } from \"../context.js\";\n\nconst PING_INTERVAL_MS = 25_000;\n\nexport function handleEvents(\n req: IncomingMessage,\n res: ServerResponse,\n ctx: DashboardContext,\n): void {\n if (!ctx.subscribeEvents) {\n res.writeHead(503, { \"content-type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"event stream requires an attached dashboard session.\" }));\n return;\n }\n\n res.writeHead(200, {\n \"content-type\": \"text/event-stream\",\n \"cache-control\": \"no-cache\",\n connection: \"keep-alive\",\n \"x-accel-buffering\": \"no\", // disable Nginx-style buffering if anything proxies us\n });\n\n const writeEvent = (event: DashboardEvent): void => {\n if (res.writableEnded) return;\n try {\n res.write(`data: ${JSON.stringify(event)}\\n\\n`);\n } catch {\n /* socket gone — connection close handler will tidy up */\n }\n };\n\n // Send a snapshot busy-change immediately so the client's button\n // state is correct on first paint (instead of inheriting whatever\n // the prior connection's last delta said).\n if (ctx.isBusy) writeEvent({ kind: \"busy-change\", busy: ctx.isBusy() });\n\n const unsubscribe = ctx.subscribeEvents(writeEvent);\n\n const ping = setInterval(() => writeEvent({ kind: \"ping\" }), PING_INTERVAL_MS);\n // Don't keep the process alive just for the heartbeat.\n ping.unref?.();\n\n const cleanup = (): void => {\n clearInterval(ping);\n try {\n unsubscribe();\n } catch {\n /* already torn down */\n }\n if (!res.writableEnded) {\n try {\n res.end();\n } catch {\n /* already closed */\n }\n }\n };\n\n req.on(\"close\", cleanup);\n req.on(\"error\", cleanup);\n res.on(\"close\", cleanup);\n}\n","import { closeSync, fstatSync, openSync, readFileSync, readSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/** Resolve dashboard/ across tsx-dev and tsup-bundled layouts. */\nfunction resolveAssetDir(): string {\n const here = dirname(fileURLToPath(import.meta.url));\n // Try a few candidates; the first existing one wins.\n // - src/server/ → ../../dashboard\n // - dist/ → ./dashboard (post-bundle, dashboard/ flat at dist root)\n // - dist/cli/ → ../dashboard\n const candidates = [\n join(here, \"..\", \"..\", \"dashboard\"),\n join(here, \"..\", \"dashboard\"),\n join(here, \"dashboard\"),\n ];\n for (const c of candidates) {\n try {\n readFileSync(join(c, \"index.html\"), \"utf8\");\n return c;\n } catch {\n /* try next */\n }\n }\n // Fall through to the most-likely-correct dev path; the read on first\n // request will throw with a useful path in the error message.\n return candidates[0]!;\n}\n\nconst ASSET_DIR = resolveAssetDir();\n\n/** mtime-keyed cache — `npm run build` invalidates without restart. */\nconst fileCache = new Map<string, { body: string; mtimeMs: number }>();\n\nfunction loadCachedFile(path: string): string {\n // Open once and reuse the fd so the mtime check and the read bind to\n // the same inode — closes the stat→read TOCTOU race.\n const fd = openSync(path, \"r\");\n try {\n const stat = fstatSync(fd);\n const cached = fileCache.get(path);\n if (cached && cached.mtimeMs === stat.mtimeMs) return cached.body;\n const buf = Buffer.alloc(stat.size);\n let read = 0;\n while (read < stat.size) {\n const n = readSync(fd, buf, read, stat.size - read, read);\n if (n <= 0) break;\n read += n;\n }\n const body = buf.toString(\"utf8\", 0, read);\n fileCache.set(path, { body, mtimeMs: stat.mtimeMs });\n return body;\n } finally {\n closeSync(fd);\n }\n}\n\nfunction loadIndexTemplate(): string {\n return loadCachedFile(join(ASSET_DIR, \"index.html\"));\n}\n\nfunction loadApp(): string {\n return loadCachedFile(join(ASSET_DIR, \"dist\", \"app.js\"));\n}\n\nfunction loadAppMap(): string | null {\n try {\n return loadCachedFile(join(ASSET_DIR, \"dist\", \"app.js.map\"));\n } catch {\n return null;\n }\n}\n\nfunction loadCss(): string {\n return loadCachedFile(join(ASSET_DIR, \"app.css\"));\n}\n\n/** Token HTML-attribute-escaped in case a future mint produces non-hex bytes. */\nexport function renderIndexHtml(token: string, mode: \"standalone\" | \"attached\"): string {\n const tpl = loadIndexTemplate();\n const safeToken = token.replace(/[^a-zA-Z0-9]/g, \"\");\n // String.replace(string, replacement) only swaps the FIRST match. The\n // template has __REASONIX_TOKEN__ in three places (meta + css href +\n // script src) — without `replaceAll` only the meta tag gets the real\n // token, the asset URLs keep the placeholder and the browser hits a\n // 401 on every asset fetch. Same trap for __REASONIX_MODE__ if it\n // ever appears more than once.\n return tpl.replaceAll(\"__REASONIX_TOKEN__\", safeToken).replaceAll(\"__REASONIX_MODE__\", mode);\n}\n\n/** Vendor CSS the bundle pulls from npm and the build script copies into `dashboard/dist/`. */\nconst VENDOR_CSS_NAMES = new Set([\"vendor-hljs.css\", \"vendor-uplot.css\"]);\n\nfunction loadVendorCss(name: string): string {\n return loadCachedFile(join(ASSET_DIR, \"dist\", name));\n}\n\nexport function serveAsset(name: string): { body: string; contentType: string } | null {\n if (name === \"app.js\") {\n return { body: loadApp(), contentType: \"application/javascript; charset=utf-8\" };\n }\n if (name === \"app.js.map\") {\n const body = loadAppMap();\n return body == null ? null : { body, contentType: \"application/json; charset=utf-8\" };\n }\n if (name === \"app.css\") {\n return { body: loadCss(), contentType: \"text/css; charset=utf-8\" };\n }\n if (VENDOR_CSS_NAMES.has(name)) {\n return { body: loadVendorCss(name), contentType: \"text/css; charset=utf-8\" };\n }\n return null;\n}\n","import type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\nexport async function handleAbort(\n method: string,\n _rest: string[],\n _body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"POST\") {\n return { status: 405, body: { error: \"POST only\" } };\n }\n if (!ctx.abortTurn) {\n return {\n status: 503,\n body: { error: \"abort requires an attached dashboard session.\" },\n };\n }\n ctx.abortTurn();\n ctx.audit?.({ ts: Date.now(), action: \"abort-turn\" });\n return { status: 202, body: { aborted: true } };\n}\n","import type { EditMode } from \"../../config.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface ModeBody {\n mode?: unknown;\n}\n\nfunction parseBody(raw: string): ModeBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as ModeBody) : {};\n } catch {\n return {};\n }\n}\n\nconst VALID = new Set<EditMode>([\"review\", \"auto\", \"yolo\"]);\n\nexport async function handleEditMode(\n method: string,\n _rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method === \"GET\") {\n return {\n status: 200,\n body: { mode: ctx.getEditMode?.() ?? null },\n };\n }\n if (method === \"POST\") {\n if (!ctx.setEditMode) {\n return {\n status: 503,\n body: { error: \"edit-mode mutation requires an attached `reasonix code` session.\" },\n };\n }\n const { mode } = parseBody(body);\n if (typeof mode !== \"string\" || !VALID.has(mode as EditMode)) {\n return { status: 400, body: { error: \"mode must be review | auto | yolo\" } };\n }\n const resolved = ctx.setEditMode(mode as EditMode);\n ctx.audit?.({ ts: Date.now(), action: \"set-edit-mode\", payload: { mode: resolved } });\n return { status: 200, body: { mode: resolved } };\n }\n return { status: 405, body: { error: \"GET or POST only\" } };\n}\n","import { existsSync, readdirSync, statSync } from \"node:fs\";\nimport { extname, join, relative, sep } from \"node:path\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\nconst RESULT_CAP = 50;\nconst MAX_DEPTH = 4;\nconst SKIP_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \".reasonix\",\n \"dist\",\n \"build\",\n \"out\",\n \".next\",\n \"coverage\",\n \".cache\",\n \"__pycache__\",\n \".venv\",\n \".pytest_cache\",\n]);\nconst SKIP_EXTS = new Set([\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".webp\",\n \".ico\",\n \".pdf\",\n \".zip\",\n \".tar\",\n \".gz\",\n \".lock\",\n \".woff\",\n \".woff2\",\n \".ttf\",\n]);\n\nexport async function handleFiles(\n method: string,\n _rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"POST\") return { status: 405, body: { error: \"POST only\" } };\n const cwd = ctx.getCurrentCwd?.();\n if (!cwd || !existsSync(cwd)) {\n return { status: 503, body: { error: \"@-mention picker requires a code-mode session\" } };\n }\n let parsed: { prefix?: unknown };\n try {\n parsed = JSON.parse(body || \"{}\");\n } catch {\n return { status: 400, body: { error: \"body must be JSON\" } };\n }\n const prefix = typeof parsed.prefix === \"string\" ? parsed.prefix.trim().toLowerCase() : \"\";\n const matches = walk(cwd, prefix);\n return { status: 200, body: { files: matches } };\n}\n\nfunction walk(root: string, prefix: string): string[] {\n const out: string[] = [];\n const stack: Array<{ path: string; depth: number }> = [{ path: root, depth: 0 }];\n while (stack.length > 0 && out.length < RESULT_CAP) {\n const { path, depth } = stack.pop()!;\n if (depth > MAX_DEPTH) continue;\n let names: string[];\n try {\n names = readdirSync(path);\n } catch {\n continue;\n }\n for (const name of names) {\n if (out.length >= RESULT_CAP) break;\n if (name.startsWith(\".\") && depth === 0) continue;\n if (SKIP_DIRS.has(name)) continue;\n const full = join(path, name);\n let st: ReturnType<typeof statSync>;\n try {\n st = statSync(full);\n } catch {\n continue;\n }\n if (st.isDirectory()) {\n stack.push({ path: full, depth: depth + 1 });\n continue;\n }\n if (!st.isFile()) continue;\n if (SKIP_EXTS.has(extname(name).toLowerCase())) continue;\n const rel = relative(root, full).split(sep).join(\"/\");\n if (prefix && !rel.toLowerCase().includes(prefix)) continue;\n out.push(rel);\n }\n }\n return out.sort((a, b) => a.localeCompare(b));\n}\n","import { existsSync, readdirSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { listSessions } from \"../../memory/session.js\";\nimport { VERSION } from \"../../version.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface DirStat {\n path: string;\n exists: boolean;\n fileCount: number;\n totalBytes: number;\n}\n\n/** Sum file sizes one level deep. Recursion deferred until we have a use-case for nested data dirs. */\nfunction dirSize(path: string): DirStat {\n if (!existsSync(path)) return { path, exists: false, fileCount: 0, totalBytes: 0 };\n let fileCount = 0;\n let totalBytes = 0;\n try {\n const entries = readdirSync(path);\n for (const name of entries) {\n const full = join(path, name);\n try {\n const s = statSync(full);\n if (s.isFile()) {\n fileCount++;\n totalBytes += s.size;\n } else if (s.isDirectory()) {\n // Recurse one level for nested folders (memory/<hash>, sessions/, etc).\n try {\n const inner = readdirSync(full);\n for (const child of inner) {\n try {\n const cs = statSync(join(full, child));\n if (cs.isFile()) {\n fileCount++;\n totalBytes += cs.size;\n }\n } catch {\n /* skip */\n }\n }\n } catch {\n /* skip */\n }\n }\n } catch {\n /* skip — file might have been deleted between readdir + stat */\n }\n }\n } catch {\n return { path, exists: true, fileCount: 0, totalBytes: 0 };\n }\n return { path, exists: true, fileCount, totalBytes };\n}\n\nexport async function handleHealth(\n method: string,\n _rest: string[],\n _body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"GET\") {\n return { status: 405, body: { error: \"GET only\" } };\n }\n const home = homedir();\n const reasonixHome = join(home, \".reasonix\");\n\n const sessionsStat = dirSize(join(reasonixHome, \"sessions\"));\n const memoryStat = dirSize(join(reasonixHome, \"memory\"));\n const semanticStat = dirSize(join(reasonixHome, \"semantic\"));\n\n let usageBytes = 0;\n if (existsSync(ctx.usageLogPath)) {\n try {\n usageBytes = statSync(ctx.usageLogPath).size;\n } catch {\n /* ignore */\n }\n }\n\n const sessions = listSessions();\n\n return {\n status: 200,\n body: {\n version: VERSION,\n latestVersion: ctx.getLatestVersion?.() ?? null,\n reasonixHome,\n sessions: {\n path: sessionsStat.path,\n count: sessions.length,\n totalBytes: sessionsStat.totalBytes,\n },\n memory: {\n path: memoryStat.path,\n fileCount: memoryStat.fileCount,\n totalBytes: memoryStat.totalBytes,\n },\n semantic: {\n path: semanticStat.path,\n exists: semanticStat.exists,\n fileCount: semanticStat.fileCount,\n totalBytes: semanticStat.totalBytes,\n },\n usageLog: {\n path: ctx.usageLogPath,\n bytes: usageBytes,\n },\n jobs: ctx.jobs ? ctx.jobs.list().length : null,\n },\n };\n}\n","/** Reload is a separate POST so save and apply stay decoupled; the SPA chains them by convention. */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { HOOK_EVENTS, globalSettingsPath, loadHooks, projectSettingsPath } from \"../../hooks.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\nimport { readRecentHookRuns } from \"./hooks-events.js\";\n\ninterface SaveBody {\n scope?: unknown;\n hooks?: unknown;\n}\n\nfunction parseBody(raw: string): SaveBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as SaveBody) : {};\n } catch {\n return {};\n }\n}\n\nfunction readSettingsFile(path: string): { hooks?: Record<string, unknown[]> } {\n if (!existsSync(path)) return {};\n try {\n const raw = readFileSync(path, \"utf8\");\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? parsed : {};\n } catch {\n return {};\n }\n}\n\nfunction writeSettingsFile(path: string, hooksBlock: unknown): void {\n // Preserve any other top-level keys that may live in the file.\n const existing = readSettingsFile(path);\n existing.hooks = hooksBlock as Record<string, unknown[]>;\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, `${JSON.stringify(existing, null, 2)}\\n`, \"utf8\");\n}\n\nexport async function handleHooks(\n method: string,\n rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method === \"GET\" && rest.length === 0) {\n const projectPath = ctx.getCurrentCwd ? projectSettingsPath(ctx.getCurrentCwd() ?? \"\") : null;\n const globalPath = globalSettingsPath();\n const projectFile = projectPath ? readSettingsFile(projectPath) : {};\n const globalFile = readSettingsFile(globalPath);\n const resolved = loadHooks({ projectRoot: ctx.getCurrentCwd?.() });\n return {\n status: 200,\n body: {\n project: {\n path: projectPath,\n hooks: projectFile.hooks ?? {},\n },\n global: {\n path: globalPath,\n hooks: globalFile.hooks ?? {},\n },\n resolved,\n events: HOOK_EVENTS,\n recentRuns: readRecentHookRuns(undefined, ctx.sessionsDir),\n },\n };\n }\n\n if (method === \"POST\" && rest[0] === \"save\") {\n const { scope, hooks } = parseBody(body);\n if (scope !== \"project\" && scope !== \"global\") {\n return { status: 400, body: { error: \"scope must be project | global\" } };\n }\n if (typeof hooks !== \"object\" || hooks === null) {\n return { status: 400, body: { error: \"hooks must be an object keyed by event name\" } };\n }\n let path: string | null;\n if (scope === \"project\") {\n const cwd = ctx.getCurrentCwd?.();\n if (!cwd) {\n return {\n status: 503,\n body: { error: \"no active project — open `/dashboard` from inside `reasonix code`\" },\n };\n }\n path = projectSettingsPath(cwd);\n } else {\n path = globalSettingsPath();\n }\n if (!path) {\n return { status: 500, body: { error: \"could not resolve settings path\" } };\n }\n writeSettingsFile(path, hooks);\n ctx.audit?.({ ts: Date.now(), action: \"save-hooks\", payload: { scope, path } });\n return { status: 200, body: { saved: true, path } };\n }\n\n if (method === \"POST\" && rest[0] === \"reload\") {\n if (!ctx.reloadHooks) {\n return {\n status: 503,\n body: { error: \"reload requires an attached session — App.tsx wires the callback\" },\n };\n }\n const count = ctx.reloadHooks();\n ctx.audit?.({ ts: Date.now(), action: \"reload-hooks\", payload: { count } });\n return { status: 200, body: { reloaded: true, count } };\n }\n\n return { status: 405, body: { error: `method ${method} not supported on this path` } };\n}\n","import { existsSync } from \"node:fs\";\nimport { readEventLogFile, recentEventFiles } from \"../../adapters/event-source-jsonl.js\";\nimport { sessionsDir as defaultSessionsDir } from \"../../memory/session.js\";\n\nexport interface HookRunRow {\n hookName: string;\n phase: \"PreToolUse\" | \"PostToolUse\" | \"UserPromptSubmit\" | \"Stop\";\n outcome: \"ok\" | \"blocked\" | \"modified\" | \"error\";\n whenMs: number;\n}\n\nconst HOOK_LOG_CAP = 12;\n\nexport function readRecentHookRuns(\n now: number = Date.now(),\n sessionsDirOverride?: string,\n): ReadonlyArray<HookRunRow> | null {\n const dir = sessionsDirOverride ?? defaultSessionsDir();\n if (!existsSync(dir)) return null;\n const files = recentEventFiles(dir, now);\n if (files.length === 0) return null;\n\n const rows: HookRunRow[] = [];\n for (const file of files) {\n const events = readEventLogFile(file);\n for (const ev of events) {\n if (ev.type !== \"hook.fired\") continue;\n const ts = Date.parse(ev.ts);\n if (!Number.isFinite(ts)) continue;\n rows.push({\n hookName: ev.hookName,\n phase: ev.phase,\n outcome: ev.outcome,\n whenMs: ts,\n });\n }\n }\n rows.sort((a, b) => b.whenMs - a.whenMs);\n return rows.slice(0, HOOK_LOG_CAP);\n}\n","/** GET returns resolved + defaults so the SPA can render a \"reset\" button without re-implementing them. */\n\nimport { loadIndexUserConfig, readConfig, writeConfig } from \"../../config.js\";\nimport {\n DEFAULT_INDEX_EXCLUDES,\n DEFAULT_MAX_FILE_BYTES,\n DEFAULT_RESPECT_GITIGNORE,\n type IndexUserConfig,\n resolveIndexConfig,\n} from \"../../index/config.js\";\nimport { type SkipReason, walkChunks } from \"../../index/semantic/chunker.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\nconst PREVIEW_INCLUDED_CAP = 50;\nconst PREVIEW_PER_REASON_CAP = 10;\n\ninterface PostBody {\n excludeDirs?: unknown;\n excludeFiles?: unknown;\n excludeExts?: unknown;\n excludePatterns?: unknown;\n respectGitignore?: unknown;\n maxFileBytes?: unknown;\n}\n\nfunction parseBody(raw: string): PostBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as PostBody) : {};\n } catch {\n return {};\n }\n}\n\nfunction isStringArray(v: unknown): v is string[] {\n return Array.isArray(v) && v.every((x) => typeof x === \"string\");\n}\n\nexport async function handleIndexConfig(\n method: string,\n rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (rest[0] === \"preview\" && method === \"POST\") {\n return await handlePreview(body, ctx);\n }\n if (method === \"GET\") {\n const user = loadIndexUserConfig(ctx.configPath);\n const resolved = resolveIndexConfig(user);\n return {\n status: 200,\n body: {\n user,\n resolved,\n defaults: {\n excludeDirs: [...DEFAULT_INDEX_EXCLUDES.dirs],\n excludeFiles: [...DEFAULT_INDEX_EXCLUDES.files],\n excludeExts: [...DEFAULT_INDEX_EXCLUDES.exts],\n excludePatterns: [],\n respectGitignore: DEFAULT_RESPECT_GITIGNORE,\n maxFileBytes: DEFAULT_MAX_FILE_BYTES,\n },\n },\n };\n }\n\n if (method === \"POST\") {\n const fields = parseBody(body);\n const next: IndexUserConfig = {};\n const changed: string[] = [];\n\n if (fields.excludeDirs !== undefined) {\n if (!isStringArray(fields.excludeDirs)) {\n return { status: 400, body: { error: \"excludeDirs must be string[]\" } };\n }\n next.excludeDirs = fields.excludeDirs;\n changed.push(\"excludeDirs\");\n }\n if (fields.excludeFiles !== undefined) {\n if (!isStringArray(fields.excludeFiles)) {\n return { status: 400, body: { error: \"excludeFiles must be string[]\" } };\n }\n next.excludeFiles = fields.excludeFiles;\n changed.push(\"excludeFiles\");\n }\n if (fields.excludeExts !== undefined) {\n if (!isStringArray(fields.excludeExts)) {\n return { status: 400, body: { error: \"excludeExts must be string[]\" } };\n }\n next.excludeExts = fields.excludeExts;\n changed.push(\"excludeExts\");\n }\n if (fields.excludePatterns !== undefined) {\n if (!isStringArray(fields.excludePatterns)) {\n return { status: 400, body: { error: \"excludePatterns must be string[]\" } };\n }\n next.excludePatterns = fields.excludePatterns;\n changed.push(\"excludePatterns\");\n }\n if (fields.respectGitignore !== undefined) {\n if (typeof fields.respectGitignore !== \"boolean\") {\n return { status: 400, body: { error: \"respectGitignore must be boolean\" } };\n }\n next.respectGitignore = fields.respectGitignore;\n changed.push(\"respectGitignore\");\n }\n if (fields.maxFileBytes !== undefined) {\n if (typeof fields.maxFileBytes !== \"number\" || fields.maxFileBytes <= 0) {\n return { status: 400, body: { error: \"maxFileBytes must be a positive number\" } };\n }\n next.maxFileBytes = fields.maxFileBytes;\n changed.push(\"maxFileBytes\");\n }\n\n const cfg = readConfig(ctx.configPath);\n cfg.index = { ...(cfg.index ?? {}), ...next };\n writeConfig(cfg, ctx.configPath);\n if (changed.length > 0) {\n ctx.audit?.({ ts: Date.now(), action: \"set-index-config\", payload: { fields: changed } });\n }\n return { status: 200, body: { changed, resolved: resolveIndexConfig(cfg.index) } };\n }\n\n return { status: 405, body: { error: \"GET or POST only\" } };\n}\n\nasync function handlePreview(body: string, ctx: DashboardContext): Promise<ApiResult> {\n const root = ctx.getCurrentCwd?.();\n if (!root) {\n return {\n status: 400,\n body: { error: \"preview requires a code-mode session (no project root attached)\" },\n };\n }\n const fields = parseBody(body);\n const draft: IndexUserConfig = {};\n if (isStringArray(fields.excludeDirs)) draft.excludeDirs = fields.excludeDirs;\n if (isStringArray(fields.excludeFiles)) draft.excludeFiles = fields.excludeFiles;\n if (isStringArray(fields.excludeExts)) draft.excludeExts = fields.excludeExts;\n if (isStringArray(fields.excludePatterns)) draft.excludePatterns = fields.excludePatterns;\n if (typeof fields.respectGitignore === \"boolean\")\n draft.respectGitignore = fields.respectGitignore;\n if (typeof fields.maxFileBytes === \"number\" && fields.maxFileBytes > 0) {\n draft.maxFileBytes = fields.maxFileBytes;\n }\n const resolved = resolveIndexConfig(draft);\n const skipBuckets: Record<SkipReason, number> = {\n defaultDir: 0,\n defaultFile: 0,\n binaryExt: 0,\n binaryContent: 0,\n tooLarge: 0,\n gitignore: 0,\n pattern: 0,\n readError: 0,\n };\n const skipSamples: Record<SkipReason, string[]> = {\n defaultDir: [],\n defaultFile: [],\n binaryExt: [],\n binaryContent: [],\n tooLarge: [],\n gitignore: [],\n pattern: [],\n readError: [],\n };\n const includedFiles = new Set<string>();\n const sampleIncluded: string[] = [];\n for await (const chunk of walkChunks(root, {\n config: resolved,\n onSkip: (rel, reason) => {\n skipBuckets[reason]++;\n const bucket = skipSamples[reason];\n if (bucket.length < PREVIEW_PER_REASON_CAP) bucket.push(rel);\n },\n })) {\n if (!includedFiles.has(chunk.path)) {\n includedFiles.add(chunk.path);\n if (sampleIncluded.length < PREVIEW_INCLUDED_CAP) sampleIncluded.push(chunk.path);\n }\n }\n return {\n status: 200,\n body: {\n filesIncluded: includedFiles.size,\n sampleIncluded,\n skipBuckets,\n skipSamples,\n resolved,\n },\n };\n}\n","import type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface LoopStartBody {\n intervalMs?: unknown;\n prompt?: unknown;\n}\n\nfunction parseBody(raw: string): LoopStartBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as LoopStartBody) : {};\n } catch {\n return {};\n }\n}\n\nconst MIN_INTERVAL_MS = 5_000;\nconst MAX_INTERVAL_MS = 6 * 60 * 60 * 1000;\n\nexport async function handleLoop(\n method: string,\n rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method === \"GET\" && rest[0] === \"status\") {\n if (!ctx.getLoopRunStatus) {\n return { status: 503, body: { error: \"auto-loop not available — attach to a chat session\" } };\n }\n return { status: 200, body: { status: ctx.getLoopRunStatus() } };\n }\n\n if (method === \"POST\" && rest[0] === \"start\") {\n if (!ctx.startAutoLoop) {\n return { status: 503, body: { error: \"auto-loop start not wired\" } };\n }\n const { intervalMs, prompt } = parseBody(body);\n if (typeof prompt !== \"string\" || !prompt.trim()) {\n return { status: 400, body: { error: \"prompt must be a non-empty string\" } };\n }\n if (\n typeof intervalMs !== \"number\" ||\n !Number.isFinite(intervalMs) ||\n intervalMs < MIN_INTERVAL_MS ||\n intervalMs > MAX_INTERVAL_MS\n ) {\n return {\n status: 400,\n body: {\n error: `intervalMs must be a number in [${MIN_INTERVAL_MS}, ${MAX_INTERVAL_MS}] (5s..6h)`,\n },\n };\n }\n ctx.startAutoLoop(intervalMs, prompt.trim());\n ctx.audit?.({ ts: Date.now(), action: \"auto-loop-start\", payload: { intervalMs } });\n return { status: 200, body: { started: true } };\n }\n\n if (method === \"POST\" && rest[0] === \"stop\") {\n if (!ctx.stopAutoLoop) {\n return { status: 503, body: { error: \"auto-loop stop not wired\" } };\n }\n ctx.stopAutoLoop();\n ctx.audit?.({ ts: Date.now(), action: \"auto-loop-stop\" });\n return { status: 200, body: { stopped: true } };\n }\n\n return {\n status: 405,\n body: { error: `method ${method} not supported on /api/loop/${rest[0] ?? \"\"}` },\n };\n}\n","/** Spec mutations don't auto-reload — adding a server shifts the system prefix and zeroes the next cache hit. */\n\nimport { readConfig, writeConfig } from \"../../config.js\";\nimport {\n fetchSmitheryDetail,\n handleToFetchResult,\n loadMorePages,\n openRegistry,\n specStringFor,\n} from \"../../mcp/registry-fetch.js\";\nimport type { RegistryEntry } from \"../../mcp/registry-types.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface SpecBody {\n spec?: unknown;\n}\ninterface InvokeBody {\n server?: unknown;\n tool?: unknown;\n args?: unknown;\n}\ninterface InstallBody {\n name?: unknown;\n maxPages?: unknown;\n}\n\nfunction parseBody<T>(raw: string): T {\n if (!raw) return {} as T;\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as T) : ({} as T);\n } catch {\n return {} as T;\n }\n}\n\nfunction clampInt(\n raw: string | null | undefined,\n min: number,\n max: number,\n fallback: number,\n): number {\n if (raw == null) return fallback;\n const n = Number.parseInt(raw, 10);\n if (!Number.isFinite(n)) return fallback;\n return Math.max(min, Math.min(max, n));\n}\n\nfunction findRegistryEntry(entries: RegistryEntry[], name: string): RegistryEntry | null {\n const exact = entries.find((e) => e.name === name);\n if (exact) return exact;\n const lower = name.toLowerCase();\n const ci = entries.find((e) => e.name.toLowerCase() === lower);\n if (ci) return ci;\n const tail = entries.find((e) => e.name.toLowerCase().endsWith(`/${lower}`));\n if (tail) return tail;\n return null;\n}\n\nexport async function handleMcp(\n method: string,\n rest: string[],\n body: string,\n ctx: DashboardContext,\n query: URLSearchParams = new URLSearchParams(),\n): Promise<ApiResult> {\n // Bridged-server view (live).\n if (method === \"GET\" && rest.length === 0) {\n const servers = (ctx.mcpServers ?? []).map((s) => ({\n label: s.label,\n spec: s.spec,\n toolCount: s.toolCount,\n protocolVersion: s.report.protocolVersion,\n serverInfo: s.report.serverInfo,\n capabilities: s.report.capabilities,\n tools: s.report.tools.supported ? s.report.tools.items : [],\n resources: s.report.resources.supported ? s.report.resources.items : [],\n prompts: s.report.prompts.supported ? s.report.prompts.items : [],\n instructions: s.report.instructions ?? null,\n }));\n return {\n status: 200,\n body: {\n servers,\n canHotReload: Boolean(ctx.reloadMcp),\n canInvoke: Boolean(ctx.invokeMcpTool),\n },\n };\n }\n\n // Persisted spec list — what config.mcp[] holds. May differ from\n // bridged set (a recent edit hasn't been reloaded yet).\n if (method === \"GET\" && rest[0] === \"specs\") {\n const cfg = readConfig(ctx.configPath);\n return { status: 200, body: { specs: cfg.mcp ?? [] } };\n }\n\n if (method === \"POST\" && rest[0] === \"specs\") {\n const { spec } = parseBody<SpecBody>(body);\n if (typeof spec !== \"string\" || !spec.trim()) {\n return { status: 400, body: { error: \"spec (non-empty string) required\" } };\n }\n const cfg = readConfig(ctx.configPath);\n const list = cfg.mcp ?? [];\n if (list.includes(spec)) {\n return { status: 200, body: { added: false, alreadyPresent: true } };\n }\n cfg.mcp = [...list, spec.trim()];\n writeConfig(cfg, ctx.configPath);\n ctx.audit?.({ ts: Date.now(), action: \"add-mcp-spec\", payload: { spec } });\n let bridged = false;\n if (ctx.reloadMcp) {\n try {\n await ctx.reloadMcp();\n bridged = true;\n } catch {\n /* fall through to requiresRestart */\n }\n }\n return { status: 200, body: { added: true, requiresRestart: !bridged, bridged } };\n }\n\n if (method === \"DELETE\" && rest[0] === \"specs\") {\n const { spec } = parseBody<SpecBody>(body);\n if (typeof spec !== \"string\") {\n return { status: 400, body: { error: \"spec (string) required\" } };\n }\n const cfg = readConfig(ctx.configPath);\n const list = cfg.mcp ?? [];\n if (!list.includes(spec)) {\n return { status: 200, body: { removed: false } };\n }\n cfg.mcp = list.filter((s) => s !== spec);\n writeConfig(cfg, ctx.configPath);\n ctx.audit?.({ ts: Date.now(), action: \"remove-mcp-spec\", payload: { spec } });\n let bridged = false;\n if (ctx.reloadMcp) {\n try {\n await ctx.reloadMcp();\n bridged = true;\n } catch {\n /* fall through */\n }\n }\n return { status: 200, body: { removed: true, requiresRestart: !bridged, bridged } };\n }\n\n if (method === \"POST\" && rest[0] === \"reload\") {\n if (!ctx.reloadMcp) {\n return {\n status: 503,\n body: {\n error:\n \"live MCP reload not wired in this session — restart `reasonix code` to apply spec edits.\",\n },\n };\n }\n const count = await ctx.reloadMcp();\n return { status: 200, body: { reloaded: true, count } };\n }\n\n // Marketplace registry — open + lazy-paginate. Query: ?pages=N&q=&maxPages=&limit=&refresh=1\n // Caps are generous on purpose: registry walks are bounded by the upstream\n // 24h cache, and an HTTP response of ~1000 entries is still under 1 MB.\n // The dashboard's \"load more\" click bumps these by 50 entries / 3 pages\n // each time, so without these ceilings users would hit a frustrating wall\n // after a few clicks.\n if (method === \"GET\" && rest[0] === \"registry\" && (rest[1] === undefined || rest[1] === \"list\")) {\n const pagesWanted = clampInt(query.get(\"pages\"), 1, 200, 1);\n const maxPages = clampInt(query.get(\"maxPages\"), 1, 200, 20);\n const limit = clampInt(query.get(\"limit\"), 1, 1000, 30);\n const refreshRaw = query.get(\"refresh\");\n const refresh = refreshRaw === \"1\" || refreshRaw === \"true\";\n const q = (query.get(\"q\") ?? \"\").trim().toLowerCase();\n\n try {\n const handle = await openRegistry({ noCache: refresh });\n const target = q ? maxPages : pagesWanted;\n const additional = Math.max(0, target - handle.cache.pagination.pagesLoaded);\n if (additional > 0) {\n await loadMorePages(handle, {\n pages: additional,\n matchTarget: q ? limit : undefined,\n filter: q\n ? (e) => `${e.name} ${e.title} ${e.description}`.toLowerCase().includes(q)\n : undefined,\n });\n }\n const result = handleToFetchResult(handle);\n const matched = q\n ? result.entries.filter((e) =>\n `${e.name} ${e.title} ${e.description}`.toLowerCase().includes(q),\n )\n : result.entries;\n const ranked = matched.slice().sort((a, b) => {\n const ap = a.popularity ?? -1;\n const bp = b.popularity ?? -1;\n if (ap !== bp) return bp - ap;\n return a.name.localeCompare(b.name);\n });\n return {\n status: 200,\n body: {\n source: result.source,\n fromCache: result.fromCache,\n fetchedAt: result.fetchedAt,\n loaded: result.entries.length,\n hasMore: result.hasMore,\n matched: matched.length,\n entries: ranked.slice(0, limit),\n errors: result.errors,\n },\n };\n } catch (err) {\n return { status: 500, body: { error: (err as Error).message } };\n }\n }\n\n if (method === \"POST\" && rest[0] === \"registry\" && rest[1] === \"install\") {\n const { name, maxPages } = parseBody<InstallBody>(body);\n if (typeof name !== \"string\" || !name.trim()) {\n return { status: 400, body: { error: \"name (string) required\" } };\n }\n const cap = typeof maxPages === \"number\" && maxPages > 0 ? maxPages : 30;\n try {\n const handle = await openRegistry({});\n const target = name.trim();\n const lower = target.toLowerCase();\n const filter = (e: RegistryEntry): boolean => {\n const n = e.name.toLowerCase();\n return n === lower || n.endsWith(`/${lower}`) || n.includes(lower);\n };\n const additional = Math.max(0, cap - handle.cache.pagination.pagesLoaded);\n if (additional > 0) {\n await loadMorePages(handle, { pages: additional, matchTarget: 1, filter });\n }\n const entry = findRegistryEntry(handle.cache.entries, target);\n if (!entry) {\n return {\n status: 404,\n body: {\n error: `no MCP server named \"${target}\" found in ${handle.cache.pagination.pagesLoaded} page(s)`,\n },\n };\n }\n if (!entry.install && entry.source === \"smithery\") {\n const fetched = await fetchSmitheryDetail(entry.name);\n if (fetched) entry.install = fetched;\n }\n if (!entry.install) {\n return {\n status: 422,\n body: {\n error: `Could not derive install metadata for ${entry.name}`,\n hint: `npx -y @smithery/cli install ${entry.name}`,\n },\n };\n }\n const spec = specStringFor(entry.name, entry.install);\n const cfg = readConfig(ctx.configPath);\n const existing = cfg.mcp ?? [];\n if (existing.includes(spec)) {\n return { status: 200, body: { added: false, alreadyPresent: true, spec, entry } };\n }\n cfg.mcp = [...existing, spec];\n writeConfig(cfg, ctx.configPath);\n ctx.audit?.({\n ts: Date.now(),\n action: \"install-mcp-from-registry\",\n payload: { name: entry.name, spec },\n });\n let bridged = false;\n let bridgeError: string | undefined;\n if (ctx.reloadMcp) {\n try {\n await ctx.reloadMcp();\n bridged = true;\n } catch (err) {\n bridgeError = (err as Error).message;\n }\n }\n return {\n status: 200,\n body: {\n added: true,\n requiresRestart: !ctx.reloadMcp || !!bridgeError,\n bridged,\n bridgeError,\n spec,\n entry,\n },\n };\n } catch (err) {\n return { status: 500, body: { error: (err as Error).message } };\n }\n }\n\n if (method === \"POST\" && rest[0] === \"invoke\") {\n if (!ctx.invokeMcpTool) {\n return {\n status: 503,\n body: { error: \"MCP invocation requires an attached session.\" },\n };\n }\n const { server, tool, args } = parseBody<InvokeBody>(body);\n if (typeof server !== \"string\" || typeof tool !== \"string\") {\n return { status: 400, body: { error: \"server + tool (strings) required\" } };\n }\n try {\n const result = await ctx.invokeMcpTool(\n server,\n tool,\n typeof args === \"object\" && args !== null ? (args as Record<string, unknown>) : {},\n );\n return { status: 200, body: { result } };\n } catch (err) {\n return { status: 500, body: { error: (err as Error).message } };\n }\n }\n\n return { status: 405, body: { error: `method ${method} not supported on this path` } };\n}\n","/** Names sanitized via SAFE_NAME on every write — guards against path traversal. */\n\nimport { createHash } from \"node:crypto\";\nimport {\n existsSync,\n mkdirSync,\n readFileSync,\n readdirSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, resolve as resolvePath } from \"node:path\";\nimport { PROJECT_MEMORY_FILE } from \"../../memory/project.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\nfunction projectHash(rootDir: string): string {\n return createHash(\"sha1\").update(resolvePath(rootDir)).digest(\"hex\").slice(0, 16);\n}\n\nfunction globalMemoryDir(): string {\n return join(homedir(), \".reasonix\", \"memory\", \"global\");\n}\n\nfunction projectMemoryDir(rootDir: string): string {\n return join(homedir(), \".reasonix\", \"memory\", projectHash(rootDir));\n}\n\ninterface WriteBody {\n body?: unknown;\n}\n\nfunction parseBody(raw: string): WriteBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as WriteBody) : {};\n } catch {\n return {};\n }\n}\n\nconst SAFE_NAME = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}$/;\n\nfunction listMemoryFiles(dir: string): Array<{ name: string; size: number; mtime: number }> {\n if (!existsSync(dir)) return [];\n try {\n return readdirSync(dir)\n .filter((f) => f.endsWith(\".md\"))\n .map((f) => {\n const stat = statSync(join(dir, f));\n return {\n name: f.replace(/\\.md$/, \"\"),\n size: stat.size,\n mtime: stat.mtime.getTime(),\n };\n })\n .sort((a, b) => b.mtime - a.mtime);\n } catch {\n return [];\n }\n}\n\nexport async function handleMemory(\n method: string,\n rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n const cwd = ctx.getCurrentCwd?.();\n const globalDir = globalMemoryDir();\n const projectMemDir = cwd ? projectMemoryDir(cwd) : \"\";\n\n if (method === \"GET\" && rest.length === 0) {\n const projectMemoryPath = cwd ? join(cwd, PROJECT_MEMORY_FILE) : null;\n const projectMemoryExists = projectMemoryPath ? existsSync(projectMemoryPath) : false;\n return {\n status: 200,\n body: {\n project: {\n path: projectMemoryPath,\n exists: projectMemoryExists,\n file: PROJECT_MEMORY_FILE,\n },\n global: {\n path: globalDir,\n files: listMemoryFiles(globalDir),\n },\n projectMem: {\n path: projectMemDir,\n files: projectMemDir ? listMemoryFiles(projectMemDir) : [],\n },\n },\n };\n }\n\n // /api/memory/<scope>/<name?>\n const [scope, ...nameParts] = rest;\n const name = nameParts.join(\"/\"); // empty for `project` scope which is a single file\n\n if (method === \"GET\") {\n if (scope === \"project\") {\n if (!cwd) return { status: 503, body: { error: \"no active project\" } };\n const path = join(cwd, PROJECT_MEMORY_FILE);\n if (!existsSync(path)) return { status: 404, body: { error: \"REASONIX.md not found\" } };\n return { status: 200, body: { path, body: readFileSync(path, \"utf8\") } };\n }\n if ((scope === \"global\" || scope === \"project-mem\") && name && SAFE_NAME.test(name)) {\n const dir = scope === \"global\" ? globalDir : projectMemDir;\n if (!dir) return { status: 503, body: { error: \"no project root for project-mem\" } };\n const path = join(dir, `${name}.md`);\n if (!existsSync(path)) return { status: 404, body: { error: \"not found\" } };\n return { status: 200, body: { path, body: readFileSync(path, \"utf8\") } };\n }\n return { status: 400, body: { error: \"bad scope or name\" } };\n }\n\n if (method === \"POST\") {\n const { body: contents } = parseBody(body);\n if (typeof contents !== \"string\") {\n return { status: 400, body: { error: \"body (string) required\" } };\n }\n if (scope === \"project\") {\n if (!cwd) return { status: 503, body: { error: \"no active project\" } };\n const path = join(cwd, PROJECT_MEMORY_FILE);\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, contents, \"utf8\");\n ctx.audit?.({ ts: Date.now(), action: \"save-memory\", payload: { scope, path } });\n return { status: 200, body: { saved: true, path } };\n }\n if ((scope === \"global\" || scope === \"project-mem\") && name && SAFE_NAME.test(name)) {\n const dir = scope === \"global\" ? globalDir : projectMemDir;\n if (!dir) return { status: 503, body: { error: \"no project root for project-mem\" } };\n mkdirSync(dir, { recursive: true });\n const path = join(dir, `${name}.md`);\n writeFileSync(path, contents, \"utf8\");\n ctx.audit?.({ ts: Date.now(), action: \"save-memory\", payload: { scope, name, path } });\n return { status: 200, body: { saved: true, path } };\n }\n return { status: 400, body: { error: \"bad scope or name\" } };\n }\n\n if (method === \"DELETE\") {\n if ((scope === \"global\" || scope === \"project-mem\") && name && SAFE_NAME.test(name)) {\n const dir = scope === \"global\" ? globalDir : projectMemDir;\n if (!dir) return { status: 503, body: { error: \"no project root for project-mem\" } };\n const path = join(dir, `${name}.md`);\n if (existsSync(path)) {\n unlinkSync(path);\n ctx.audit?.({ ts: Date.now(), action: \"delete-memory\", payload: { scope, name, path } });\n return { status: 200, body: { deleted: true } };\n }\n return { status: 404, body: { error: \"not found\" } };\n }\n if (scope === \"project\") {\n if (!cwd) return { status: 503, body: { error: \"no active project\" } };\n const path = join(cwd, PROJECT_MEMORY_FILE);\n if (existsSync(path)) {\n unlinkSync(path);\n ctx.audit?.({ ts: Date.now(), action: \"delete-memory\", payload: { scope, path } });\n return { status: 200, body: { deleted: true } };\n }\n return { status: 404, body: { error: \"not found\" } };\n }\n return { status: 400, body: { error: \"bad scope or name\" } };\n }\n\n return { status: 405, body: { error: `method ${method} not supported` } };\n}\n","import type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\nexport async function handleMessages(\n method: string,\n _rest: string[],\n _body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"GET\") {\n return { status: 405, body: { error: \"GET only\" } };\n }\n const messages = ctx.getMessages ? ctx.getMessages() : [];\n return {\n status: 200,\n body: {\n messages,\n busy: ctx.isBusy ? ctx.isBusy() : false,\n },\n };\n}\n","/** GET snapshots the active modal so a fresh client paints what's already up; POST routes resolution into the same handlers the TUI uses. */\n\nimport type { DashboardContext, PickerResolution } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface ResolveBody {\n kind?: unknown;\n choice?: unknown;\n text?: unknown;\n action?: unknown;\n id?: unknown;\n query?: unknown;\n}\n\nfunction parsePickerResolution(body: ResolveBody): PickerResolution | { error: string } {\n const { action, id, text, query } = body;\n if (typeof action !== \"string\") return { error: \"picker action required\" };\n switch (action) {\n case \"pick\":\n case \"delete\":\n case \"install\":\n case \"uninstall\":\n if (typeof id !== \"string\" || !id) return { error: `picker ${action} requires id` };\n return { action, id };\n case \"rename\":\n if (typeof id !== \"string\" || !id) return { error: \"picker rename requires id\" };\n if (typeof text !== \"string\") return { error: \"picker rename requires text\" };\n return { action: \"rename\", id, text };\n case \"new\":\n return typeof text === \"string\" && text ? { action: \"new\", text } : { action: \"new\" };\n case \"load-more\":\n return { action: \"load-more\" };\n case \"refine\":\n if (typeof query !== \"string\") return { error: \"picker refine requires query\" };\n return { action: \"refine\", query };\n case \"cancel\":\n return { action: \"cancel\" };\n default:\n return { error: `unknown picker action: ${action}` };\n }\n}\n\nfunction parseBody(raw: string): ResolveBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as ResolveBody) : {};\n } catch {\n return {};\n }\n}\n\nexport async function handleModal(\n method: string,\n rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method === \"GET\" && rest.length === 0) {\n return {\n status: 200,\n body: { modal: ctx.getActiveModal ? ctx.getActiveModal() : null },\n };\n }\n\n if (method === \"POST\" && rest[0] === \"resolve\") {\n const parsed = parseBody(body);\n const { kind, choice, text } = parsed;\n if (kind === \"shell\") {\n if (!ctx.resolveShellConfirm) {\n return { status: 503, body: { error: \"shell modal resolution not wired\" } };\n }\n if (choice !== \"run_once\" && choice !== \"always_allow\" && choice !== \"deny\") {\n return {\n status: 400,\n body: { error: \"shell choice must be run_once / always_allow / deny\" },\n };\n }\n ctx.resolveShellConfirm(choice);\n return { status: 200, body: { resolved: true } };\n }\n if (kind === \"choice\") {\n if (!ctx.resolveChoiceConfirm) {\n return { status: 503, body: { error: \"choice modal resolution not wired\" } };\n }\n // The wire shape mirrors ChoiceResolution: { kind: \"pick\"|\"custom\"|\"cancel\", ... }.\n const c = choice as Record<string, unknown> | undefined;\n if (!c || typeof c !== \"object\") {\n return { status: 400, body: { error: \"choice must be an object with a kind field\" } };\n }\n if (c.kind === \"pick\" && typeof c.optionId === \"string\") {\n ctx.resolveChoiceConfirm({ kind: \"pick\", optionId: c.optionId });\n return { status: 200, body: { resolved: true } };\n }\n if (c.kind === \"custom\" && typeof c.text === \"string\") {\n ctx.resolveChoiceConfirm({ kind: \"custom\", text: c.text });\n return { status: 200, body: { resolved: true } };\n }\n if (c.kind === \"cancel\") {\n ctx.resolveChoiceConfirm({ kind: \"cancel\" });\n return { status: 200, body: { resolved: true } };\n }\n return { status: 400, body: { error: \"unknown choice resolution shape\" } };\n }\n if (kind === \"plan\") {\n if (!ctx.resolvePlanConfirm) {\n return { status: 503, body: { error: \"plan modal resolution not wired\" } };\n }\n if (choice !== \"approve\" && choice !== \"refine\" && choice !== \"cancel\") {\n return { status: 400, body: { error: \"plan choice must be approve / refine / cancel\" } };\n }\n ctx.resolvePlanConfirm(choice, typeof text === \"string\" && text.trim() ? text : undefined);\n return { status: 200, body: { resolved: true } };\n }\n if (kind === \"edit-review\") {\n if (!ctx.resolveEditReview) {\n return { status: 503, body: { error: \"edit-review modal resolution not wired\" } };\n }\n if (\n choice !== \"apply\" &&\n choice !== \"reject\" &&\n choice !== \"apply-rest-of-turn\" &&\n choice !== \"flip-to-auto\"\n ) {\n return { status: 400, body: { error: \"edit-review choice invalid\" } };\n }\n ctx.resolveEditReview(choice);\n return { status: 200, body: { resolved: true } };\n }\n if (kind === \"checkpoint\") {\n if (!ctx.resolveCheckpointConfirm) {\n return { status: 503, body: { error: \"checkpoint modal resolution not wired\" } };\n }\n if (choice !== \"continue\" && choice !== \"revise\" && choice !== \"stop\") {\n return {\n status: 400,\n body: { error: \"checkpoint choice must be continue / revise / stop\" },\n };\n }\n ctx.resolveCheckpointConfirm(\n choice,\n typeof text === \"string\" && text.trim() ? text : undefined,\n );\n return { status: 200, body: { resolved: true } };\n }\n if (kind === \"revision\") {\n if (!ctx.resolveReviseConfirm) {\n return { status: 503, body: { error: \"revision modal resolution not wired\" } };\n }\n if (choice !== \"accept\" && choice !== \"reject\") {\n return { status: 400, body: { error: \"revision choice must be accept / reject\" } };\n }\n ctx.resolveReviseConfirm(choice);\n return { status: 200, body: { resolved: true } };\n }\n if (kind === \"picker\") {\n if (!ctx.resolvePicker) {\n return { status: 503, body: { error: \"picker modal resolution not wired\" } };\n }\n const resolution = parsePickerResolution(parsed);\n if (\"error\" in resolution) {\n return { status: 400, body: { error: resolution.error } };\n }\n ctx.resolvePicker(resolution);\n return { status: 200, body: { resolved: true } };\n }\n if (kind === \"viewer\") {\n if (!ctx.resolveViewer) {\n return { status: 503, body: { error: \"viewer modal resolution not wired\" } };\n }\n if (parsed.action !== \"close\") {\n return { status: 400, body: { error: \"viewer action must be close\" } };\n }\n ctx.resolveViewer({ action: \"close\" });\n return { status: 200, body: { resolved: true } };\n }\n return { status: 400, body: { error: `unknown modal kind: ${String(kind)}` } };\n }\n\n return { status: 405, body: { error: `method ${method} not supported on this path` } };\n}\n","import { DEEPSEEK_PRICING } from \"../../telemetry/stats.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\nexport async function handleModels(\n method: string,\n _rest: string[],\n _body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"GET\") return { status: 405, body: { error: \"GET only\" } };\n const models = ctx.getModels?.() ?? null;\n return {\n status: 200,\n body: {\n models,\n current: ctx.loop?.model ?? null,\n /** USD per 1M tokens — same table the cost gauge uses. */\n pricing: DEEPSEEK_PRICING,\n },\n };\n}\n","import { existsSync } from \"node:fs\";\nimport { readEventLogFile, recentEventFiles } from \"../../adapters/event-source-jsonl.js\";\nimport type { Event } from \"../../core/events.js\";\nimport { sessionsDir as defaultSessionsDir } from \"../../memory/session.js\";\n\nexport interface CockpitToolCallsKpi {\n total: number;\n delta: number | null;\n}\n\nexport interface CockpitRecentPlan {\n id: string;\n title: string;\n totalSteps: number;\n completedSteps: number;\n status: \"active\" | \"done\";\n whenMs: number;\n}\n\nexport interface CockpitToolFeedRow {\n name: string;\n args: string;\n level: \"ok\" | \"warn\" | \"err\";\n whenMs: number;\n}\n\nexport interface EventsCockpit {\n toolCalls24h: CockpitToolCallsKpi | null;\n recentPlans: ReadonlyArray<CockpitRecentPlan> | null;\n toolActivity: ReadonlyArray<CockpitToolFeedRow> | null;\n}\n\nconst DAY_MS = 86_400_000;\nconst RECENT_FILES_CAP = 8;\nconst PLAN_FEED_CAP = 4;\nconst TOOL_FEED_CAP = 6;\n\nexport function computeEventsCockpit(\n now: number = Date.now(),\n sessionsDirOverride?: string,\n): EventsCockpit {\n const dir = sessionsDirOverride ?? defaultSessionsDir();\n if (!existsSync(dir)) {\n return { toolCalls24h: null, recentPlans: null, toolActivity: null };\n }\n const files = recentEventFiles(dir, now, RECENT_FILES_CAP);\n if (files.length === 0) {\n return { toolCalls24h: null, recentPlans: null, toolActivity: null };\n }\n\n let calls24h = 0;\n let callsPrior24h = 0;\n const cutoff24h = now - DAY_MS;\n const cutoff48h = now - 2 * DAY_MS;\n const allTools: CockpitToolFeedRow[] = [];\n const allPlans: CockpitRecentPlan[] = [];\n\n for (const file of files) {\n const events = readEventLogFile(file);\n if (events.length === 0) continue;\n countToolCalls(events, cutoff24h, cutoff48h, (in24h) => {\n if (in24h) calls24h++;\n else callsPrior24h++;\n });\n collectToolActivity(events, allTools);\n collectPlans(events, allPlans);\n }\n\n allTools.sort((a, b) => b.whenMs - a.whenMs);\n allPlans.sort((a, b) => b.whenMs - a.whenMs);\n\n return {\n toolCalls24h: { total: calls24h, delta: calls24h - callsPrior24h },\n recentPlans: allPlans.slice(0, PLAN_FEED_CAP),\n toolActivity: allTools.slice(0, TOOL_FEED_CAP),\n };\n}\n\nfunction countToolCalls(\n events: ReadonlyArray<Event>,\n cutoff24h: number,\n cutoff48h: number,\n onCall: (in24h: boolean) => void,\n): void {\n for (const ev of events) {\n if (ev.type !== \"tool.intent\") continue;\n const ts = parseTs(ev.ts);\n if (ts === null) continue;\n if (ts >= cutoff24h) onCall(true);\n else if (ts >= cutoff48h) onCall(false);\n }\n}\n\nfunction collectToolActivity(events: ReadonlyArray<Event>, into: CockpitToolFeedRow[]): void {\n const intentByCallId = new Map<string, { name: string; args: string; ts: number }>();\n for (const ev of events) {\n if (ev.type === \"tool.intent\") {\n const ts = parseTs(ev.ts);\n if (ts !== null) intentByCallId.set(ev.callId, { name: ev.name, args: ev.args, ts });\n } else if (ev.type === \"tool.result\") {\n const intent = intentByCallId.get(ev.callId);\n if (!intent) continue;\n into.push({\n name: intent.name,\n args: summarizeArgs(intent.args),\n level: ev.ok ? \"ok\" : \"err\",\n whenMs: intent.ts,\n });\n } else if (ev.type === \"tool.denied\") {\n const intent = intentByCallId.get(ev.callId);\n if (!intent) continue;\n into.push({\n name: intent.name,\n args: summarizeArgs(intent.args),\n level: \"warn\",\n whenMs: intent.ts,\n });\n }\n }\n}\n\nfunction collectPlans(events: ReadonlyArray<Event>, into: CockpitRecentPlan[]): void {\n let current: { id: string; title: string; totalSteps: number; whenMs: number } | null = null;\n let completed = new Set<string>();\n for (const ev of events) {\n if (ev.type === \"plan.submitted\") {\n if (current) {\n into.push(buildPlan(current, completed));\n }\n const ts = parseTs(ev.ts);\n if (ts === null) {\n current = null;\n continue;\n }\n current = {\n id: `${ev.id}`,\n title: planTitle(ev.body, ev.steps),\n totalSteps: ev.steps.length,\n whenMs: ts,\n };\n completed = new Set();\n } else if (ev.type === \"plan.step.completed\") {\n if (!current) continue;\n completed.add(ev.stepId);\n }\n }\n if (current) into.push(buildPlan(current, completed));\n}\n\nfunction buildPlan(\n current: { id: string; title: string; totalSteps: number; whenMs: number },\n completed: Set<string>,\n): CockpitRecentPlan {\n return {\n id: current.id,\n title: current.title,\n totalSteps: current.totalSteps,\n completedSteps: completed.size,\n status: completed.size >= current.totalSteps && current.totalSteps > 0 ? \"done\" : \"active\",\n whenMs: current.whenMs,\n };\n}\n\nfunction planTitle(body: string, steps: ReadonlyArray<{ title: string }>): string {\n const firstBodyLine = body.split(/\\r?\\n/).find((l) => l.trim().length > 0);\n if (firstBodyLine)\n return firstBodyLine\n .replace(/^#+\\s*/, \"\")\n .trim()\n .slice(0, 80);\n if (steps.length > 0 && steps[0]) return steps[0].title.slice(0, 80);\n return \"(plan)\";\n}\n\nfunction summarizeArgs(args: string): string {\n if (!args) return \"\";\n let parsed: unknown;\n try {\n parsed = JSON.parse(args);\n } catch {\n return args.slice(0, 60);\n }\n if (parsed && typeof parsed === \"object\") {\n const obj = parsed as Record<string, unknown>;\n const path = obj.path ?? obj.file_path ?? obj.filename;\n const command = obj.command;\n if (typeof command === \"string\")\n return command.length > 60 ? `${command.slice(0, 60)}…` : command;\n if (typeof path === \"string\") return path;\n }\n return args.slice(0, 60);\n}\n\nfunction parseTs(ts: string): number | null {\n const n = Date.parse(ts);\n return Number.isFinite(n) ? n : null;\n}\n","import { aggregateUsage, bucketCacheHitRatio, readUsageLog } from \"../../telemetry/usage.js\";\nimport type { DashboardContext, DashboardStats } from \"../context.js\";\nimport { type EventsCockpit, computeEventsCockpit } from \"./cockpit-events.js\";\n\nexport type {\n CockpitRecentPlan,\n CockpitToolCallsKpi,\n CockpitToolFeedRow,\n} from \"./cockpit-events.js\";\n\nexport interface CockpitKpi {\n total: number;\n deltaPct: number | null;\n}\n\nexport interface CockpitCacheKpi {\n ratio: number;\n deltaPp: number | null;\n}\n\nexport interface CockpitDailyCost {\n date: string;\n usd: number;\n}\n\nexport interface CockpitCurrentSession {\n id: string;\n turns: number;\n totalCostUsd: number;\n lastPromptTokens: number;\n completionTokens: number;\n}\n\nexport interface CockpitData extends EventsCockpit {\n balance: { currency: string; total: string } | null;\n tokens7d: CockpitKpi | null;\n cacheHit7d: CockpitCacheKpi | null;\n costTrend14d: ReadonlyArray<CockpitDailyCost> | null;\n currentSession: CockpitCurrentSession | null;\n}\n\ntype WarmFields = Pick<\n CockpitData,\n \"tokens7d\" | \"cacheHit7d\" | \"costTrend14d\" | \"toolCalls24h\" | \"recentPlans\" | \"toolActivity\"\n>;\n\nconst TTL_MS = 30_000;\n\ninterface CacheEntry {\n ts: number;\n data: WarmFields;\n}\n\nconst cache = new Map<string, CacheEntry>();\n\nexport function _resetCockpitCacheForTests(): void {\n cache.clear();\n}\n\nexport function computeCockpit(ctx: DashboardContext, now: number = Date.now()): CockpitData {\n return {\n balance: extractBalance(ctx.getStats?.() ?? null),\n currentSession: extractCurrentSession(ctx),\n ...readWarmCached(ctx.usageLogPath, now, ctx.sessionsDir),\n };\n}\n\nfunction extractBalance(stats: DashboardStats | null): CockpitData[\"balance\"] {\n const first = stats?.balance?.[0];\n if (!first) return null;\n return { currency: first.currency, total: first.total_balance };\n}\n\nfunction extractCurrentSession(ctx: DashboardContext): CockpitData[\"currentSession\"] {\n const id = ctx.getSessionName?.() ?? null;\n const stats = ctx.getStats?.() ?? null;\n const loop = ctx.loop;\n if (!id || !stats || !loop) return null;\n let completion = 0;\n for (const t of loop.stats.turns) completion += t.usage.completionTokens;\n return {\n id,\n turns: stats.turns,\n totalCostUsd: stats.totalCostUsd,\n lastPromptTokens: stats.lastPromptTokens,\n completionTokens: completion,\n };\n}\n\nfunction readWarmCached(usageLogPath: string, now: number, sessionsDir?: string): WarmFields {\n const cacheKey = `${usageLogPath}::${sessionsDir ?? \"\"}`;\n const hit = cache.get(cacheKey);\n if (hit && now - hit.ts < TTL_MS) return hit.data;\n const data = computeWarm(usageLogPath, now, sessionsDir);\n cache.set(cacheKey, { ts: now, data });\n return data;\n}\n\nexport function computeWarm(usageLogPath: string, now: number, sessionsDir?: string): WarmFields {\n const events = computeEventsCockpit(now, sessionsDir);\n const records = readUsageLog(usageLogPath);\n if (records.length === 0) {\n return { tokens7d: null, cacheHit7d: null, costTrend14d: null, ...events };\n }\n const week = aggregateUsage(records, { now }).buckets[1]!;\n const priorWeekRecords = records.filter(\n (r) => r.ts < week.since && r.ts >= week.since - 7 * 86_400_000,\n );\n const priorWeek = aggregateUsage(priorWeekRecords, { now: week.since }).buckets[1]!;\n\n const tokens7dTotal = week.promptTokens + week.completionTokens;\n const tokens7dPrior = priorWeek.promptTokens + priorWeek.completionTokens;\n const tokens7d: CockpitKpi = {\n total: tokens7dTotal,\n deltaPct: tokens7dPrior > 0 ? ((tokens7dTotal - tokens7dPrior) / tokens7dPrior) * 100 : null,\n };\n\n const cacheHitRatio = bucketCacheHitRatio(week);\n const cacheHit7d: CockpitCacheKpi = {\n ratio: cacheHitRatio,\n deltaPp:\n priorWeek.cacheHitTokens + priorWeek.cacheMissTokens > 0\n ? (cacheHitRatio - bucketCacheHitRatio(priorWeek)) * 100\n : null,\n };\n\n return {\n tokens7d,\n cacheHit7d,\n costTrend14d: rollupDailyCost(records, now, 14),\n ...events,\n };\n}\n\nfunction rollupDailyCost(\n records: ReadonlyArray<{ ts: number; costUsd: number }>,\n now: number,\n days: number,\n): CockpitDailyCost[] {\n const since = now - days * 86_400_000;\n const buckets = new Map<string, number>();\n for (let i = 0; i < days; i++) {\n buckets.set(localDateKey(now - i * 86_400_000), 0);\n }\n for (const r of records) {\n if (r.ts < since) continue;\n const key = localDateKey(r.ts);\n if (!buckets.has(key)) continue;\n buckets.set(key, (buckets.get(key) ?? 0) + r.costUsd);\n }\n return Array.from(buckets.entries())\n .map(([date, usd]) => ({ date, usd }))\n .sort((a, b) => (a.date < b.date ? -1 : 1));\n}\n\nfunction localDateKey(ts: number): string {\n const d = new Date(ts);\n const y = d.getFullYear();\n const m = String(d.getMonth() + 1).padStart(2, \"0\");\n const day = String(d.getDate()).padStart(2, \"0\");\n return `${y}-${m}-${day}`;\n}\n","/** Bundled GET — avoids 6 round-trips per 2s poll; runtime fields null in standalone mode. */\n\nimport { readConfig } from \"../../config.js\";\nimport { indexExists } from \"../../index/semantic/builder.js\";\nimport { VERSION } from \"../../version.js\";\nimport type { DashboardContext, DashboardStats } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\nimport { type CockpitData, computeCockpit } from \"./cockpit.js\";\n\nexport interface OverviewResponse {\n /** Reasonix version string (drives the \"vs latest\" comparison in the SPA). */\n version: string;\n /** Current runtime mode — drives whether the SPA hides \"live-only\" controls. */\n mode: \"standalone\" | \"attached\";\n /** Latest published version, or null when the background fetch hasn't resolved. */\n latestVersion: string | null;\n session: string | null;\n cwd: string | null;\n model: string | null;\n editMode: string | null;\n planMode: boolean | null;\n pendingEdits: number | null;\n /** When attached, count of MCP servers currently bridged. */\n mcpServerCount: number | null;\n /** Total registered tools (builtin + MCP-bridged + skill tools). */\n toolCount: number | null;\n preset: string;\n /** Persisted reasoning_effort (high / max). Same rationale as preset. */\n reasoningEffort: string;\n /** Session USD spend cap; null when off. Drives the chat side-rail's Tool budget card. */\n budgetUsd: number | null;\n /** Live session stats — null in standalone mode. */\n stats: DashboardStats | null;\n semanticIndexExists: boolean | null;\n cockpit: CockpitData;\n}\n\nexport async function handleOverview(\n method: string,\n _rest: string[],\n _body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"GET\") {\n return { status: 405, body: { error: \"GET only\" } };\n }\n const cfg = readConfig(ctx.configPath);\n const cwd = ctx.getCurrentCwd?.() ?? null;\n const semanticIndexExists = cwd ? await indexExists(cwd).catch(() => false) : null;\n const overview: OverviewResponse = {\n version: VERSION,\n mode: ctx.mode,\n latestVersion: ctx.getLatestVersion?.() ?? null,\n session: ctx.getSessionName?.() ?? null,\n cwd,\n model: ctx.loop?.model ?? null,\n editMode: ctx.getEditMode?.() ?? null,\n planMode: ctx.getPlanMode?.() ?? null,\n pendingEdits: ctx.getPendingEditCount?.() ?? null,\n mcpServerCount: ctx.mcpServers?.length ?? null,\n toolCount: ctx.tools ? ctx.tools.size : null,\n preset: cfg.preset ?? \"auto\",\n reasoningEffort: cfg.reasoningEffort ?? \"max\",\n budgetUsd: ctx.loop?.budgetUsd ?? null,\n stats: ctx.getStats?.() ?? null,\n semanticIndexExists,\n cockpit: computeCockpit(ctx),\n };\n return { status: 200, body: overview };\n}\n","/** Mutations require an attached session — standalone mode returns 503 because we have no project root to scope under. */\n\nimport {\n addProjectShellAllowed,\n clearProjectShellAllowed,\n loadProjectShellAllowed,\n removeProjectShellAllowed,\n} from \"../../config.js\";\nimport { BUILTIN_ALLOWLIST } from \"../../tools/shell.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface MutationBody {\n prefix?: unknown;\n confirm?: unknown;\n}\n\nfunction parseBody(raw: string): MutationBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as MutationBody) : {};\n } catch {\n return {};\n }\n}\n\nexport async function handlePermissions(\n method: string,\n rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n // GET — listing works regardless of mode (builtin always shown,\n // project list optional).\n if (method === \"GET\" && rest.length === 0) {\n const cwd = ctx.getCurrentCwd?.();\n return {\n status: 200,\n body: {\n currentCwd: cwd ?? null,\n editMode: ctx.getEditMode?.() ?? null,\n builtin: [...BUILTIN_ALLOWLIST],\n project: cwd ? loadProjectShellAllowed(cwd, ctx.configPath) : [],\n },\n };\n }\n\n // Mutations require a current project root.\n const cwd = ctx.getCurrentCwd?.();\n if (!cwd) {\n return {\n status: 503,\n body: {\n error:\n \"no active project — mutations require an attached dashboard session (run `/dashboard` from inside `reasonix code`).\",\n },\n };\n }\n\n if (method === \"POST\" && rest.length === 0) {\n const { prefix } = parseBody(body);\n if (typeof prefix !== \"string\" || !prefix.trim()) {\n return { status: 400, body: { error: \"prefix (string) required\" } };\n }\n const trimmed = prefix.trim();\n if (BUILTIN_ALLOWLIST.includes(trimmed)) {\n return {\n status: 409,\n body: {\n error: `\\`${trimmed}\\` is already in the builtin allowlist — no project entry needed.`,\n },\n };\n }\n const before = loadProjectShellAllowed(cwd, ctx.configPath);\n if (before.includes(trimmed)) {\n return { status: 200, body: { added: false, prefix: trimmed, alreadyPresent: true } };\n }\n addProjectShellAllowed(cwd, trimmed, ctx.configPath);\n ctx.audit?.({\n ts: Date.now(),\n action: \"add-allowlist\",\n payload: { prefix: trimmed, project: cwd },\n });\n return { status: 200, body: { added: true, prefix: trimmed } };\n }\n\n if (method === \"DELETE\" && rest.length === 0) {\n const { prefix } = parseBody(body);\n if (typeof prefix !== \"string\" || !prefix.trim()) {\n return { status: 400, body: { error: \"prefix (string) required\" } };\n }\n const trimmed = prefix.trim();\n if (BUILTIN_ALLOWLIST.includes(trimmed)) {\n return {\n status: 409,\n body: {\n error: `\\`${trimmed}\\` is in the builtin allowlist (read-only); builtin entries can't be removed at runtime.`,\n },\n };\n }\n const removed = removeProjectShellAllowed(cwd, trimmed, ctx.configPath);\n if (removed) {\n ctx.audit?.({\n ts: Date.now(),\n action: \"remove-allowlist\",\n payload: { prefix: trimmed, project: cwd },\n });\n }\n return { status: 200, body: { removed, prefix: trimmed } };\n }\n\n if (method === \"POST\" && rest[0] === \"clear\") {\n const { confirm } = parseBody(body);\n if (confirm !== true) {\n return {\n status: 400,\n body: {\n error: \"clear requires { confirm: true } in the body — guards against accidental wipe.\",\n },\n };\n }\n const dropped = clearProjectShellAllowed(cwd, ctx.configPath);\n if (dropped > 0) {\n ctx.audit?.({\n ts: Date.now(),\n action: \"clear-allowlist\",\n payload: { dropped, project: cwd },\n });\n }\n return { status: 200, body: { dropped } };\n }\n\n return { status: 405, body: { error: `method ${method} not supported on this path` } };\n}\n","import { listPlanArchives } from \"../../code/plan-store.js\";\nimport { listSessions } from \"../../memory/session.js\";\nimport type { PlanStep } from \"../../tools/plan.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface PlanRow {\n session: string;\n path: string;\n completedAt: string;\n totalSteps: number;\n completedSteps: number;\n /** Computed completion ratio 0..1, surfaced so the SPA doesn't redo the math. */\n completionRatio: number;\n /** Plan summary (if the archive carried one). */\n summary?: string;\n /** Steps + completion ids — consumers render the step list inline. */\n steps: PlanStep[];\n completedStepIds: string[];\n}\n\nexport async function handlePlans(\n method: string,\n _rest: string[],\n _body: string,\n _ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"GET\") {\n return { status: 405, body: { error: \"GET only\" } };\n }\n const out: PlanRow[] = [];\n for (const session of listSessions()) {\n const archives = listPlanArchives(session.name);\n for (const a of archives) {\n const total = a.steps.length;\n const done = a.completedStepIds.length;\n const row: PlanRow = {\n session: session.name,\n path: a.path,\n completedAt: a.completedAt,\n totalSteps: total,\n completedSteps: done,\n completionRatio: total > 0 ? done / total : 0,\n steps: a.steps,\n completedStepIds: a.completedStepIds,\n };\n if (a.summary) row.summary = a.summary;\n out.push(row);\n }\n }\n // Newest archive first across the whole pool.\n out.sort((a, b) => b.completedAt.localeCompare(a.completedAt));\n return { status: 200, body: { plans: out } };\n}\n","/** Job state in a module-scoped Map keyed by project root so multi-root dashboards don't collide; CLI `reasonix index` runs independently. */\n\nimport { closeSync, fstatSync, openSync, readSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n type EmbeddingProvider,\n type SemanticEmbeddingUserConfig,\n loadIndexConfig,\n loadSemanticEmbeddingUserConfig,\n readConfig,\n redactSemanticEmbeddingConfig,\n resolveSemanticEmbeddingConfig,\n saveSemanticEmbeddingConfig,\n} from \"../../config.js\";\nimport {\n INDEX_DIR_NAME,\n buildIndex,\n indexCompatible,\n indexExists,\n querySemantic,\n} from \"../../index/semantic/builder.js\";\nimport type { BuildProgress, BuildResult } from \"../../index/semantic/builder.js\";\nimport {\n checkOllamaStatus,\n pullOllamaModel,\n startOllamaDaemon,\n} from \"../../index/semantic/ollama-launcher.js\";\nimport {\n compareIndexIdentity,\n readIndexMeta as readStoreIndexMeta,\n} from \"../../index/semantic/store.js\";\nimport { registerSemanticSearchTool } from \"../../index/semantic/tool.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface JobRecord {\n startedAt: number;\n finishedAt?: number;\n cancelledAt?: number;\n phase: BuildProgress[\"phase\"] | \"error\" | \"cancelled\";\n lastPhase?: BuildProgress[\"phase\"];\n filesScanned?: number;\n filesChanged?: number;\n filesSkipped?: number;\n chunksTotal?: number;\n chunksDone?: number;\n result?: BuildResult;\n error?: string;\n rebuild: boolean;\n aborted: boolean;\n controller: AbortController;\n}\n\nconst JOBS = new Map<string, JobRecord>();\n\ninterface PullRecord {\n startedAt: number;\n status: \"pulling\" | \"done\" | \"error\";\n lastLine: string;\n exitCode: number | null;\n}\nconst PULLS = new Map<string, PullRecord>();\n\nfunction getRoot(ctx: DashboardContext): string | null {\n const cwd = ctx.getCurrentCwd?.();\n return cwd ?? null;\n}\n\nexport async function handleSemantic(\n method: string,\n rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n const sub = rest[0] ?? \"\";\n\n if (sub === \"\" && method === \"GET\") return await getStatus(ctx);\n if (sub === \"config\" && method === \"GET\") return getSemanticConfig(ctx);\n if (sub === \"config\" && method === \"POST\") return saveSemanticConfigApi(body, ctx);\n if (sub === \"start\" && method === \"POST\") return await startJob(body, ctx);\n if (sub === \"stop\" && method === \"POST\") return await stopJob(ctx);\n if (sub === \"ollama\" && method === \"POST\") {\n const action = rest[1] ?? \"\";\n if (action === \"start\") return await startDaemon(ctx);\n if (action === \"pull\") return await startPull(body, ctx);\n }\n if (sub === \"search\" && method === \"POST\") return await runSearch(body, ctx);\n return { status: 404, body: { error: \"no such semantic endpoint\" } };\n}\n\nasync function runSearch(rawBody: string, ctx: DashboardContext): Promise<ApiResult> {\n const root = getRoot(ctx);\n if (!root) {\n return { status: 503, body: { error: \"search requires an attached code-mode session\" } };\n }\n let parsed: { query?: unknown; topK?: unknown; minScore?: unknown };\n try {\n parsed = JSON.parse(rawBody || \"{}\");\n } catch {\n return { status: 400, body: { error: \"body must be JSON\" } };\n }\n const query = typeof parsed.query === \"string\" ? parsed.query.trim() : \"\";\n if (!query) return { status: 400, body: { error: \"query required\" } };\n const topK =\n typeof parsed.topK === \"number\" && Number.isFinite(parsed.topK)\n ? Math.max(1, Math.min(16, Math.floor(parsed.topK)))\n : 8;\n const minScore =\n typeof parsed.minScore === \"number\" && Number.isFinite(parsed.minScore)\n ? Math.max(0, Math.min(1, parsed.minScore))\n : 0.3;\n const startedAt = Date.now();\n const embedding = resolveSemanticEmbeddingConfig(ctx.configPath);\n try {\n const hits = await querySemantic(root, query, {\n topK,\n minScore,\n configPath: ctx.configPath,\n });\n if (hits === null) {\n return { status: 404, body: { error: \"no semantic index for this project\" } };\n }\n return {\n status: 200,\n body: {\n hits: hits.map((h) => ({\n path: h.entry.path,\n startLine: h.entry.startLine,\n endLine: h.entry.endLine,\n score: h.score,\n snippet: h.entry.text,\n })),\n elapsedMs: Date.now() - startedAt,\n provider: embedding.provider,\n model: embedding.model,\n },\n };\n } catch (err) {\n return { status: 500, body: { error: (err as Error).message } };\n }\n}\n\nasync function getStatus(ctx: DashboardContext): Promise<ApiResult> {\n const root = getRoot(ctx);\n if (!root) {\n return {\n status: 200,\n body: {\n attached: false,\n reason:\n \"Semantic indexing requires a code-mode session — run `/dashboard` from inside `reasonix code` instead of standalone `reasonix dashboard`.\",\n },\n };\n }\n const config = loadSemanticEmbeddingUserConfig(ctx.configPath);\n const configView = redactSemanticEmbeddingConfig(config);\n const resolved = resolveSemanticEmbeddingConfig(ctx.configPath);\n const [hasIndex, providerStatus, index] = await Promise.all([\n indexExists(root),\n getProviderStatusFromConfig(configView),\n readIndexMeta(root, { provider: resolved.provider, model: resolved.model }),\n ]);\n const job = JOBS.get(root) ?? null;\n const pull =\n providerStatus.kind === \"ollama\" ? (PULLS.get(providerStatus.modelName) ?? null) : null;\n return {\n status: 200,\n body: {\n attached: true,\n root,\n provider: configView.provider,\n providerConfig: configView,\n providerStatus,\n index: hasIndex ? index : { exists: false },\n ollama: providerStatus.kind === \"ollama\" ? providerStatus : undefined,\n job: job ? snapshotJob(job) : null,\n pull: pull ? snapshotPull(pull) : null,\n },\n };\n}\n\ninterface IndexMetaResponse {\n exists: true;\n provider: EmbeddingProvider;\n chunks: number;\n files: number;\n dim: number;\n sizeBytes: number;\n lastBuiltMs: number;\n model: string;\n builtWith: { provider: EmbeddingProvider; model: string };\n current: { provider: EmbeddingProvider; model: string };\n compatible: boolean;\n mismatch: \"provider\" | \"model\" | null;\n}\n\nasync function readIndexMeta(\n root: string,\n current: { provider: EmbeddingProvider; model: string },\n): Promise<IndexMetaResponse | { exists: false }> {\n const dir = join(root, INDEX_DIR_NAME);\n const dataPath = join(dir, \"index.jsonl\");\n const diskMeta = await readStoreIndexMeta(dir);\n if (!diskMeta) return { exists: false };\n let chunks = 0;\n const files = new Set<string>();\n let sizeBytes = 0;\n try {\n const fd = openSync(dataPath, \"r\");\n let raw: string;\n try {\n const stat = fstatSync(fd);\n sizeBytes = stat.size;\n const buf = Buffer.alloc(stat.size);\n let read = 0;\n while (read < stat.size) {\n const n = readSync(fd, buf, read, stat.size - read, read);\n if (n <= 0) break;\n read += n;\n }\n raw = buf.toString(\"utf8\", 0, read);\n } finally {\n closeSync(fd);\n }\n for (const line of raw.split(/\\r?\\n/)) {\n if (!line.trim()) continue;\n chunks++;\n try {\n const rec = JSON.parse(line) as { p?: string };\n if (typeof rec.p === \"string\") files.add(rec.p);\n } catch {\n /* skip malformed */\n }\n }\n } catch {\n /* partial counts allowed */\n }\n const mismatch = compareIndexIdentity(diskMeta, current);\n return {\n exists: true,\n provider: diskMeta.provider,\n chunks,\n files: files.size,\n dim: diskMeta.dim ?? 0,\n sizeBytes,\n lastBuiltMs: diskMeta.updatedAt ? Date.parse(diskMeta.updatedAt) || 0 : 0,\n model: diskMeta.model ?? \"\",\n builtWith: { provider: diskMeta.provider, model: diskMeta.model },\n current,\n compatible: mismatch === null,\n mismatch,\n };\n}\n\nfunction snapshotPull(p: PullRecord): unknown {\n return {\n startedAt: p.startedAt,\n status: p.status,\n lastLine: p.lastLine,\n exitCode: p.exitCode,\n };\n}\n\nasync function startDaemon(ctx: DashboardContext): Promise<ApiResult> {\n const resolved = resolveSemanticEmbeddingConfig(ctx.configPath);\n if (resolved.provider !== \"ollama\") {\n return { status: 409, body: { error: \"ollama actions require provider=ollama\" } };\n }\n const r = await startOllamaDaemon({ baseUrl: resolved.baseUrl, timeoutMs: 15_000 }).catch(\n (err: Error) => ({\n ready: false,\n pid: null,\n error: err.message,\n }),\n );\n if (\"error\" in r) return { status: 500, body: { ready: false, error: r.error } };\n return { status: r.ready ? 200 : 504, body: r };\n}\n\ninterface PullBody {\n model?: unknown;\n}\n\nasync function startPull(body: string, ctx: DashboardContext): Promise<ApiResult> {\n const resolved = resolveSemanticEmbeddingConfig(ctx.configPath);\n if (resolved.provider !== \"ollama\") {\n return { status: 409, body: { error: \"ollama actions require provider=ollama\" } };\n }\n let parsed: PullBody = {};\n if (body) {\n try {\n parsed = JSON.parse(body) as PullBody;\n } catch {\n return { status: 400, body: { error: \"invalid JSON body\" } };\n }\n }\n const model = typeof parsed.model === \"string\" && parsed.model ? parsed.model : resolved.model;\n const existing = PULLS.get(model);\n if (existing && existing.status === \"pulling\") {\n return {\n status: 409,\n body: { error: `${model} is already pulling`, pull: snapshotPull(existing) },\n };\n }\n const rec: PullRecord = {\n startedAt: Date.now(),\n status: \"pulling\",\n lastLine: `pulling ${model}…`,\n exitCode: null,\n };\n PULLS.set(model, rec);\n void pullOllamaModel(model, {\n onLine: (line) => {\n if (line.trim().length > 0) rec.lastLine = line.trim();\n },\n })\n .then((code) => {\n rec.exitCode = code;\n rec.status = code === 0 ? \"done\" : \"error\";\n if (code !== 0 && (!rec.lastLine || !rec.lastLine.toLowerCase().includes(\"error\"))) {\n rec.lastLine = `ollama pull exited with code ${code}`;\n }\n })\n .catch((err: Error) => {\n rec.status = \"error\";\n rec.lastLine = err.message;\n });\n return { status: 202, body: { started: true, pull: snapshotPull(rec) } };\n}\n\nfunction snapshotJob(j: JobRecord): unknown {\n return {\n startedAt: j.startedAt,\n finishedAt: j.finishedAt ?? null,\n cancelledAt: j.cancelledAt ?? null,\n phase: j.phase,\n lastPhase: j.lastPhase ?? null,\n rebuild: j.rebuild,\n filesScanned: j.filesScanned ?? null,\n filesChanged: j.filesChanged ?? null,\n filesSkipped: j.filesSkipped ?? null,\n chunksTotal: j.chunksTotal ?? null,\n chunksDone: j.chunksDone ?? null,\n aborted: j.aborted,\n result: j.result ?? null,\n error: j.error ?? null,\n };\n}\n\ninterface StartBody {\n rebuild?: unknown;\n}\n\nasync function startJob(body: string, ctx: DashboardContext): Promise<ApiResult> {\n const root = getRoot(ctx);\n if (!root) {\n return {\n status: 400,\n body: { error: \"no project root — only available in attached (code-mode) dashboards\" },\n };\n }\n const existing = JOBS.get(root);\n if (\n existing &&\n (existing.phase === \"setup\" ||\n existing.phase === \"scan\" ||\n existing.phase === \"embed\" ||\n existing.phase === \"write\")\n ) {\n return {\n status: 409,\n body: { error: \"an indexing job is already running\", job: snapshotJob(existing) },\n };\n }\n\n let parsed: StartBody = {};\n if (body) {\n try {\n parsed = JSON.parse(body) as StartBody;\n } catch {\n return { status: 400, body: { error: \"invalid JSON body\" } };\n }\n }\n const rebuild = parsed.rebuild === true;\n\n const job: JobRecord = {\n startedAt: Date.now(),\n phase: \"setup\",\n lastPhase: \"setup\",\n rebuild,\n aborted: false,\n controller: new AbortController(),\n };\n JOBS.set(root, job);\n\n void runIndex(root, job, ctx).catch((err) => {\n job.phase = \"error\";\n job.finishedAt = Date.now();\n job.error = err instanceof Error ? err.message : String(err);\n });\n\n const resolved = resolveSemanticEmbeddingConfig(ctx.configPath);\n return {\n status: 202,\n body: {\n started: true,\n provider: resolved.provider,\n model: resolved.model,\n job: snapshotJob(job),\n },\n };\n}\n\nasync function runIndex(root: string, job: JobRecord, ctx: DashboardContext): Promise<void> {\n try {\n const resolved = resolveSemanticEmbeddingConfig(ctx.configPath);\n const result = await buildIndex(root, {\n rebuild: job.rebuild,\n configPath: ctx.configPath,\n signal: job.controller.signal,\n indexConfig: loadIndexConfig(ctx.configPath),\n onProgress: (p) => {\n job.phase = p.phase;\n if (p.phase !== \"done\") job.lastPhase = p.phase;\n if (p.filesScanned !== undefined) job.filesScanned = p.filesScanned;\n if (p.filesChanged !== undefined) job.filesChanged = p.filesChanged;\n if (p.filesSkipped !== undefined) job.filesSkipped = p.filesSkipped;\n if (p.chunksTotal !== undefined) job.chunksTotal = p.chunksTotal;\n if (p.chunksDone !== undefined) job.chunksDone = p.chunksDone;\n },\n });\n job.phase = \"done\";\n job.finishedAt = Date.now();\n job.result = result;\n if (ctx.tools && ctx.addToolToPrefix) {\n try {\n const added = await registerSemanticSearchTool(ctx.tools, { root, ...resolved });\n if (added) {\n const spec = ctx.tools.specs().find((s) => s.function.name === \"semantic_search\");\n if (spec) ctx.addToolToPrefix(spec);\n }\n } catch {\n /* non-fatal */\n }\n }\n } catch (err) {\n if (isAbortError(err)) {\n job.phase = \"cancelled\";\n job.cancelledAt = Date.now();\n job.finishedAt = job.cancelledAt;\n job.error = undefined;\n return;\n }\n job.phase = \"error\";\n job.finishedAt = Date.now();\n job.error = err instanceof Error ? err.message : String(err);\n }\n}\n\nasync function stopJob(ctx: DashboardContext): Promise<ApiResult> {\n const root = getRoot(ctx);\n if (!root) return { status: 400, body: { error: \"no project root\" } };\n const job = JOBS.get(root);\n if (!job || job.phase === \"done\" || job.phase === \"error\" || job.phase === \"cancelled\") {\n return { status: 404, body: { error: \"no running job\" } };\n }\n job.aborted = true;\n job.controller.abort(new Error(\"semantic indexing aborted\"));\n return { status: 202, body: { stopping: true, job: snapshotJob(job) } };\n}\n\nfunction getSemanticConfig(ctx: DashboardContext): ApiResult {\n return {\n status: 200,\n body: redactSemanticEmbeddingConfig(loadSemanticEmbeddingUserConfig(ctx.configPath)),\n };\n}\n\nfunction saveSemanticConfigApi(rawBody: string, ctx: DashboardContext): ApiResult {\n let parsed: {\n provider?: unknown;\n ollama?: { baseUrl?: unknown; model?: unknown };\n openaiCompat?: {\n baseUrl?: unknown;\n apiKey?: unknown;\n model?: unknown;\n extraBody?: unknown;\n };\n };\n try {\n parsed = JSON.parse(rawBody || \"{}\");\n } catch {\n return { status: 400, body: { error: \"body must be JSON\" } };\n }\n const existing = loadSemanticEmbeddingUserConfig(ctx.configPath);\n const next: SemanticEmbeddingUserConfig = {\n provider: parsed.provider === \"openai-compat\" ? \"openai-compat\" : \"ollama\",\n ollama: {\n baseUrl:\n typeof parsed.ollama?.baseUrl === \"string\"\n ? parsed.ollama.baseUrl\n : existing.ollama?.baseUrl,\n model:\n typeof parsed.ollama?.model === \"string\" ? parsed.ollama.model : existing.ollama?.model,\n },\n openaiCompat: {\n baseUrl:\n typeof parsed.openaiCompat?.baseUrl === \"string\"\n ? parsed.openaiCompat.baseUrl\n : existing.openaiCompat?.baseUrl,\n apiKey:\n typeof parsed.openaiCompat?.apiKey === \"string\"\n ? parsed.openaiCompat.apiKey.trim() || existing.openaiCompat?.apiKey\n : existing.openaiCompat?.apiKey,\n model:\n typeof parsed.openaiCompat?.model === \"string\"\n ? parsed.openaiCompat.model\n : existing.openaiCompat?.model,\n extraBody:\n parsed.openaiCompat?.extraBody === undefined\n ? existing.openaiCompat?.extraBody\n : (parsed.openaiCompat.extraBody as Record<string, unknown>),\n },\n };\n try {\n saveSemanticEmbeddingConfig(next, ctx.configPath);\n } catch (err) {\n return { status: 400, body: { error: (err as Error).message } };\n }\n ctx.audit?.({\n ts: Date.now(),\n action: \"set-semantic-config\",\n payload: { provider: next.provider },\n });\n return {\n status: 200,\n body: {\n changed: collectSemanticConfigChanges(existing, next),\n config: redactSemanticEmbeddingConfig(loadSemanticEmbeddingUserConfig(ctx.configPath)),\n },\n };\n}\n\nfunction collectSemanticConfigChanges(\n before: SemanticEmbeddingUserConfig,\n after: SemanticEmbeddingUserConfig,\n): string[] {\n const left = JSON.stringify(before);\n const right = JSON.stringify(after);\n if (left === right) return [];\n return [\"semantic\"];\n}\n\nasync function getProviderStatusFromConfig(\n config: ReturnType<typeof redactSemanticEmbeddingConfig>,\n): Promise<\n | {\n kind: \"ollama\";\n ready: boolean;\n baseUrl: string;\n binaryFound: boolean;\n daemonRunning: boolean;\n modelPulled: boolean;\n modelName: string;\n installedModels: string[];\n error?: string;\n }\n | {\n kind: \"openai-compat\";\n ready: boolean;\n baseUrl: string;\n apiKeySet: boolean;\n model: string;\n extraBodyKeys: string[];\n }\n> {\n if (config.provider === \"openai-compat\") {\n return {\n kind: \"openai-compat\",\n ready: Boolean(\n config.openaiCompat.baseUrl && config.openaiCompat.apiKeySet && config.openaiCompat.model,\n ),\n baseUrl: config.openaiCompat.baseUrl,\n apiKeySet: config.openaiCompat.apiKeySet,\n model: config.openaiCompat.model,\n extraBodyKeys: Object.keys(config.openaiCompat.extraBody),\n };\n }\n const ollama = await checkOllamaStatus(config.ollama.model, config.ollama.baseUrl).catch(\n (err) => ({\n binaryFound: false,\n daemonRunning: false,\n modelPulled: false,\n modelName: config.ollama.model,\n installedModels: [] as string[],\n error: err instanceof Error ? err.message : String(err),\n }),\n );\n return {\n kind: \"ollama\",\n ready: ollama.binaryFound && ollama.daemonRunning && ollama.modelPulled,\n baseUrl: config.ollama.baseUrl,\n ...ollama,\n };\n}\n\nasync function getProviderStatus(\n resolved: ReturnType<typeof resolveSemanticEmbeddingConfig>,\n): Promise<\n | {\n kind: \"ollama\";\n ready: boolean;\n baseUrl: string;\n binaryFound: boolean;\n daemonRunning: boolean;\n modelPulled: boolean;\n modelName: string;\n installedModels: string[];\n error?: string;\n }\n | {\n kind: \"openai-compat\";\n ready: boolean;\n baseUrl: string;\n apiKeySet: boolean;\n model: string;\n extraBodyKeys: string[];\n }\n> {\n if (resolved.provider === \"openai-compat\") {\n return {\n kind: \"openai-compat\",\n ready: Boolean(resolved.baseUrl && resolved.apiKey && resolved.model),\n baseUrl: resolved.baseUrl,\n apiKeySet: Boolean(resolved.apiKey),\n model: resolved.model,\n extraBodyKeys: Object.keys(resolved.extraBody),\n };\n }\n const ollama = await checkOllamaStatus(resolved.model, resolved.baseUrl).catch((err) => ({\n binaryFound: false,\n daemonRunning: false,\n modelPulled: false,\n modelName: resolved.model,\n installedModels: [] as string[],\n error: err instanceof Error ? err.message : String(err),\n }));\n return {\n kind: \"ollama\",\n ready: ollama.binaryFound && ollama.daemonRunning && ollama.modelPulled,\n baseUrl: resolved.baseUrl,\n ...ollama,\n };\n}\n\nvoid readConfig;\n\nfunction isAbortError(err: unknown): boolean {\n if (err instanceof Error) {\n if (err.name === \"AbortError\") return true;\n if (/aborted/i.test(err.message)) return true;\n }\n return false;\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { listSessions, sessionPath } from \"../../memory/session.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface SessionMessage {\n role: string;\n content?: string;\n toolName?: string;\n /** Raw record. Kept for debug; SPA reads from `role`/`content` first. */\n raw?: unknown;\n}\n\nfunction parseTranscript(path: string, maxBytes = 4 * 1024 * 1024): SessionMessage[] {\n // Cap reads at 4 MB so a runaway session file (rare but possible)\n // doesn't tie up the server. The `head` of a long session is the\n // useful part; we surface a `truncated` flag in the response.\n let raw: string;\n try {\n raw = readFileSync(path, \"utf8\");\n } catch {\n return [];\n }\n if (raw.length > maxBytes) raw = raw.slice(0, maxBytes);\n const out: SessionMessage[] = [];\n for (const line of raw.split(/\\r?\\n/)) {\n if (!line.trim()) continue;\n try {\n const rec = JSON.parse(line) as Record<string, unknown>;\n const role = typeof rec.role === \"string\" ? rec.role : \"unknown\";\n const msg: SessionMessage = { role };\n if (typeof rec.content === \"string\") msg.content = rec.content;\n else if (rec.content !== undefined) msg.content = JSON.stringify(rec.content);\n if (typeof rec.tool_name === \"string\") msg.toolName = rec.tool_name;\n if (typeof rec.toolName === \"string\") msg.toolName = rec.toolName;\n out.push(msg);\n } catch {\n /* skip malformed line — same rule as the rest of Reasonix's JSONL readers */\n }\n }\n return out;\n}\n\nexport async function handleSessions(\n method: string,\n rest: string[],\n _body: string,\n _ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"GET\") {\n return { status: 405, body: { error: \"GET only\" } };\n }\n\n // Listing.\n if (rest.length === 0) {\n const sessions = listSessions();\n return {\n status: 200,\n body: {\n sessions: sessions.map((s) => ({\n name: s.name,\n path: s.path,\n size: s.size,\n messageCount: s.messageCount,\n mtime: s.mtime.getTime(),\n })),\n },\n };\n }\n\n // Single-session detail. URL-decode in case the name had spaces / CJK\n // (sanitizeName allows them).\n const name = decodeURIComponent(rest[0]!);\n const path = sessionPath(name);\n if (!existsSync(path)) {\n return { status: 404, body: { error: `no such session: ${name}` } };\n }\n const messages = parseTranscript(path);\n return {\n status: 200,\n body: {\n name,\n path,\n messages,\n messageCount: messages.length,\n },\n };\n}\n","/** apiKey is write-only on the wire; GET always returns a redacted form so dashboard screenshots don't leak credentials. */\n\nimport { isPlausibleKey, readConfig, redactKey, saveEditMode, writeConfig } from \"../../config.js\";\nimport { getLanguage, getSupportedLanguages, setLanguage } from \"../../i18n/index.js\";\nimport type { LanguageCode } from \"../../i18n/types.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface SettingsBody {\n apiKey?: unknown;\n baseUrl?: unknown;\n lang?: unknown;\n preset?: unknown;\n reasoningEffort?: unknown;\n search?: unknown;\n model?: unknown;\n proNext?: unknown;\n budgetUsd?: unknown;\n}\n\nfunction parseBody(raw: string): SettingsBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as SettingsBody) : {};\n } catch {\n return {};\n }\n}\n\n// Accept new (auto/flash/pro) and legacy (fast/smart/max) — server\n// stores whatever the user picked; resolvePreset() canonicalizes at\n// read time. Web sends new names in 0.12.x onward.\nconst VALID_PRESETS = new Set([\"auto\", \"flash\", \"pro\", \"fast\", \"smart\", \"max\"]);\nconst VALID_EFFORTS = new Set([\"high\", \"max\"]);\n\nexport async function handleSettings(\n method: string,\n _rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method === \"GET\") {\n const cfg = readConfig(ctx.configPath);\n const live = ctx.loop;\n return {\n status: 200,\n body: {\n apiKey: cfg.apiKey ? redactKey(cfg.apiKey) : null,\n apiKeySet: Boolean(cfg.apiKey),\n baseUrl: cfg.baseUrl ?? null,\n lang: getLanguage(),\n preset: cfg.preset ?? \"auto\",\n reasoningEffort: cfg.reasoningEffort ?? \"max\",\n search: cfg.search !== false,\n editMode: cfg.editMode ?? \"review\",\n session: cfg.session ?? null,\n model: live?.model ?? null,\n proNext: live?.proArmed ?? false,\n budgetUsd: live?.budgetUsd ?? null,\n sessionSpendUsd: ctx.getStats?.()?.totalCostUsd ?? null,\n // Hint to the SPA which fields require restart.\n appliesAt: {\n apiKey: \"next-session\",\n baseUrl: \"next-session\",\n preset: \"next-session\",\n reasoningEffort: \"next-turn\",\n search: \"next-session\",\n model: \"next-turn\",\n proNext: \"next-turn\",\n budgetUsd: \"live\",\n },\n },\n };\n }\n\n if (method === \"POST\") {\n const fields = parseBody(body);\n // Single read up top, all field updates accumulate, single writeConfig at the end —\n // a per-field write would clobber earlier per-field writes from the same POST.\n const cfg = readConfig(ctx.configPath);\n const changed: string[] = [];\n let langPending: LanguageCode | null = null;\n let presetPendingLive: string | null = null;\n let effortPendingLive: \"high\" | \"max\" | null = null;\n\n if (fields.lang !== undefined) {\n const raw = String(fields.lang);\n const supported = getSupportedLanguages();\n const langCode = supported.find((l) => l.toLowerCase() === raw.toLowerCase()) as\n | LanguageCode\n | undefined;\n if (!langCode) {\n return { status: 400, body: { error: `lang must be one of: ${supported.join(\", \")}` } };\n }\n cfg.lang = langCode;\n langPending = langCode;\n changed.push(\"lang\");\n }\n if (fields.apiKey !== undefined) {\n if (typeof fields.apiKey !== \"string\" || !isPlausibleKey(fields.apiKey)) {\n return { status: 400, body: { error: \"apiKey must be a plausible sk- token\" } };\n }\n cfg.apiKey = fields.apiKey.trim();\n changed.push(\"apiKey\");\n }\n if (fields.baseUrl !== undefined) {\n if (typeof fields.baseUrl !== \"string\" || !fields.baseUrl.trim()) {\n return { status: 400, body: { error: \"baseUrl must be a non-empty string\" } };\n }\n cfg.baseUrl = fields.baseUrl.trim();\n changed.push(\"baseUrl\");\n }\n if (fields.preset !== undefined) {\n if (typeof fields.preset !== \"string\" || !VALID_PRESETS.has(fields.preset)) {\n return { status: 400, body: { error: \"preset must be auto | flash | pro\" } };\n }\n cfg.preset = fields.preset as \"auto\" | \"flash\" | \"pro\" | \"fast\" | \"smart\" | \"max\";\n presetPendingLive = fields.preset;\n changed.push(\"preset\");\n }\n if (fields.reasoningEffort !== undefined) {\n if (\n typeof fields.reasoningEffort !== \"string\" ||\n !VALID_EFFORTS.has(fields.reasoningEffort)\n ) {\n return { status: 400, body: { error: \"reasoningEffort must be high | max\" } };\n }\n cfg.reasoningEffort = fields.reasoningEffort as \"high\" | \"max\";\n effortPendingLive = fields.reasoningEffort as \"high\" | \"max\";\n changed.push(\"reasoningEffort\");\n }\n if (fields.search !== undefined) {\n if (typeof fields.search !== \"boolean\") {\n return { status: 400, body: { error: \"search must be a boolean\" } };\n }\n cfg.search = fields.search;\n changed.push(\"search\");\n }\n let modelPendingLive: string | null = null;\n let proNextPending: boolean | null = null;\n let budgetPending: number | null | undefined;\n if (fields.model !== undefined) {\n if (typeof fields.model !== \"string\" || !fields.model.trim()) {\n return { status: 400, body: { error: \"model must be a non-empty string\" } };\n }\n // Model is live-only (not in ReasonixConfig). Same as /model <id> slash — disk\n // pickup goes through preset / startup flag, not direct cfg.model.\n modelPendingLive = fields.model.trim();\n changed.push(\"model\");\n }\n if (fields.proNext !== undefined) {\n if (typeof fields.proNext !== \"boolean\") {\n return { status: 400, body: { error: \"proNext must be a boolean\" } };\n }\n // Not persisted: arming is per-turn ephemeral. Live-only side effect.\n proNextPending = fields.proNext;\n changed.push(\"proNext\");\n }\n if (fields.budgetUsd !== undefined) {\n if (fields.budgetUsd === null) {\n budgetPending = null;\n } else if (\n typeof fields.budgetUsd === \"number\" &&\n fields.budgetUsd > 0 &&\n Number.isFinite(fields.budgetUsd)\n ) {\n budgetPending = fields.budgetUsd;\n } else {\n return {\n status: 400,\n body: { error: \"budgetUsd must be null or a positive finite number\" },\n };\n }\n changed.push(\"budgetUsd\");\n }\n\n if (changed.length > 0) {\n writeConfig(cfg, ctx.configPath);\n // Runtime side-effects fire after the disk write succeeds —\n // prevents an i18n change from being visible while the on-disk\n // value still reflects the old setting (and vice-versa for\n // preset / reasoningEffort).\n if (langPending) setLanguage(langPending);\n if (presetPendingLive) ctx.applyPresetLive?.(presetPendingLive);\n if (effortPendingLive) ctx.applyEffortLive?.(effortPendingLive);\n if (modelPendingLive) ctx.applyModelLive?.(modelPendingLive);\n if (proNextPending !== null) ctx.setProNextLive?.(proNextPending);\n if (budgetPending !== undefined) ctx.setBudgetUsdLive?.(budgetPending);\n ctx.audit?.({ ts: Date.now(), action: \"set-settings\", payload: { fields: changed } });\n }\n return { status: 200, body: { changed } };\n }\n\n return { status: 405, body: { error: \"GET or POST only\" } };\n}\n\n// Keep saveEditMode imported so future GET responses can include the\n// canonical default — used by the SPA when /api/overview hasn't yet\n// resolved. (Currently surfaced via /api/overview directly.)\nvoid saveEditMode;\n","/** `/api/skills` — edits files only; loop reloads on /new or restart. `builtin` scope is read-only. */\n\nimport {\n closeSync,\n existsSync,\n fstatSync,\n mkdirSync,\n openSync,\n readFileSync,\n readSync,\n readdirSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { SKILLS_DIRNAME, SKILL_FILE } from \"../../skills.js\";\nimport { readUsageLog } from \"../../telemetry/usage.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface WriteBody {\n body?: unknown;\n}\n\nfunction parseBody(raw: string): WriteBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as WriteBody) : {};\n } catch {\n return {};\n }\n}\n\nconst SAFE_NAME = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}$/;\n\nfunction globalSkillsDir(): string {\n return join(homedir(), \".reasonix\", SKILLS_DIRNAME);\n}\n\nfunction projectSkillsDir(rootDir: string): string {\n return join(rootDir, \".reasonix\", SKILLS_DIRNAME);\n}\n\ninterface SkillListEntry {\n name: string;\n scope: \"project\" | \"global\" | \"builtin\";\n description?: string;\n path: string;\n size: number;\n mtime: number;\n}\n\nfunction parseFrontmatterDescription(raw: string): string | undefined {\n const lines = raw.split(/\\r?\\n/);\n if (lines[0] !== \"---\") return undefined;\n for (let i = 1; i < lines.length; i++) {\n if (lines[i] === \"---\") break;\n const m = lines[i]!.match(/^description:\\s*(.*)$/);\n if (m) return m[1]!.trim();\n }\n return undefined;\n}\n\nfunction listSkills(dir: string, scope: \"project\" | \"global\"): SkillListEntry[] {\n if (!existsSync(dir)) return [];\n const out: SkillListEntry[] = [];\n try {\n for (const entry of readdirSync(dir)) {\n if (!SAFE_NAME.test(entry)) continue;\n const skillPath = join(dir, entry, SKILL_FILE);\n try {\n // Open once and reuse the fd so size/mtime/content all bind to\n // the same inode — closes the exists→stat→read TOCTOU races.\n const fd = openSync(skillPath, \"r\");\n let stat: ReturnType<typeof fstatSync>;\n let raw: string;\n try {\n stat = fstatSync(fd);\n const buf = Buffer.alloc(stat.size);\n let read = 0;\n while (read < stat.size) {\n const n = readSync(fd, buf, read, stat.size - read, read);\n if (n <= 0) break;\n read += n;\n }\n raw = buf.toString(\"utf8\", 0, read);\n } finally {\n closeSync(fd);\n }\n const item: SkillListEntry = {\n name: entry,\n scope,\n path: skillPath,\n size: stat.size,\n mtime: stat.mtime.getTime(),\n };\n const desc = parseFrontmatterDescription(raw);\n if (desc) item.description = desc;\n out.push(item);\n } catch {\n /* skip unreadable */\n }\n }\n } catch {\n /* skip unreadable dir */\n }\n return out.sort((a, b) => a.name.localeCompare(b.name));\n}\n\nfunction countSubagentRuns(usageLogPath: string): Map<string, number> {\n const cutoff = Date.now() - 7 * 86_400_000;\n const counts = new Map<string, number>();\n for (const r of readUsageLog(usageLogPath)) {\n if (r.kind !== \"subagent\" || r.ts < cutoff) continue;\n const skill = r.subagent?.skillName?.trim();\n if (!skill) continue;\n counts.set(skill, (counts.get(skill) ?? 0) + 1);\n }\n return counts;\n}\n\nexport async function handleSkills(\n method: string,\n rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n const cwd = ctx.getCurrentCwd?.();\n\n if (method === \"GET\" && rest.length === 0) {\n const runs7d = countSubagentRuns(ctx.usageLogPath);\n const tag = (rows: SkillListEntry[]) =>\n rows.map((r) => ({ ...r, runs7d: runs7d.get(r.name) ?? 0 }));\n return {\n status: 200,\n body: {\n global: tag(listSkills(globalSkillsDir(), \"global\")),\n project: cwd ? tag(listSkills(projectSkillsDir(cwd), \"project\")) : [],\n builtin: [\n {\n name: \"explore\",\n scope: \"builtin\",\n description: \"subagent — broad codebase survey\",\n runs7d: runs7d.get(\"explore\") ?? 0,\n },\n {\n name: \"research\",\n scope: \"builtin\",\n description: \"subagent — deep web + repo research\",\n runs7d: runs7d.get(\"research\") ?? 0,\n },\n ],\n paths: {\n global: globalSkillsDir(),\n project: cwd ? projectSkillsDir(cwd) : null,\n },\n },\n };\n }\n\n const [scope, ...nameParts] = rest;\n const name = nameParts.join(\"/\");\n\n if (!scope || !name || !SAFE_NAME.test(name)) {\n return { status: 400, body: { error: \"expected /api/skills/<scope>/<name>\" } };\n }\n if (scope !== \"project\" && scope !== \"global\") {\n return {\n status: 400,\n body: { error: \"scope must be project | global (builtin is read-only)\" },\n };\n }\n let dir: string;\n if (scope === \"project\") {\n if (!cwd) {\n return {\n status: 503,\n body: { error: \"no active project — open `/dashboard` from `reasonix code`\" },\n };\n }\n dir = projectSkillsDir(cwd);\n } else {\n dir = globalSkillsDir();\n }\n const skillPath = join(dir, name, SKILL_FILE);\n\n if (method === \"GET\") {\n if (!existsSync(skillPath)) return { status: 404, body: { error: \"skill not found\" } };\n return { status: 200, body: { path: skillPath, body: readFileSync(skillPath, \"utf8\") } };\n }\n\n if (method === \"POST\") {\n const { body: contents } = parseBody(body);\n if (typeof contents !== \"string\") {\n return { status: 400, body: { error: \"body (string) required\" } };\n }\n mkdirSync(dirname(skillPath), { recursive: true });\n writeFileSync(skillPath, contents, \"utf8\");\n ctx.audit?.({\n ts: Date.now(),\n action: \"save-skill\",\n payload: { scope, name, path: skillPath },\n });\n return { status: 200, body: { saved: true, path: skillPath } };\n }\n\n if (method === \"DELETE\") {\n if (!existsSync(skillPath)) return { status: 404, body: { error: \"skill not found\" } };\n // Drop the whole skill folder (it may carry assets next to SKILL.md).\n rmSync(dirname(skillPath), { recursive: true, force: true });\n ctx.audit?.({ ts: Date.now(), action: \"delete-skill\", payload: { scope, name } });\n return { status: 200, body: { deleted: true } };\n }\n\n return { status: 405, body: { error: `method ${method} not supported` } };\n}\n","import { SLASH_COMMANDS } from \"../../cli/ui/slash/commands.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\nexport async function handleSlash(\n method: string,\n _rest: string[],\n _body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"GET\") return { status: 405, body: { error: \"GET only\" } };\n const codeMode = ctx.getCurrentCwd?.() != null;\n const commands = SLASH_COMMANDS.filter((c) => c.contextual !== \"code\" || codeMode).map((c) => ({\n cmd: c.cmd,\n summary: c.summary,\n argsHint: c.argsHint,\n contextual: c.contextual,\n aliases: c.aliases,\n }));\n return { status: 200, body: { commands, codeMode } };\n}\n","import type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface SubmitBody {\n prompt?: unknown;\n}\n\nfunction parseBody(raw: string): SubmitBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as SubmitBody) : {};\n } catch {\n return {};\n }\n}\n\nexport async function handleSubmit(\n method: string,\n _rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"POST\") {\n return { status: 405, body: { error: \"POST only\" } };\n }\n if (!ctx.submitPrompt) {\n return {\n status: 503,\n body: {\n error:\n \"submit requires an attached dashboard session — open `/dashboard` from inside `reasonix code` or `reasonix chat`.\",\n },\n };\n }\n const { prompt } = parseBody(body);\n if (typeof prompt !== \"string\" || !prompt.trim()) {\n return { status: 400, body: { error: \"prompt (non-empty string) required\" } };\n }\n const result = ctx.submitPrompt(prompt);\n if (!result.accepted) {\n return {\n status: 409,\n body: { accepted: false, reason: result.reason ?? \"loop is busy\" },\n };\n }\n ctx.audit?.({\n ts: Date.now(),\n action: \"submit-prompt\",\n payload: { length: prompt.length },\n });\n return { status: 202, body: { accepted: true } };\n}\n","import type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\nexport async function handleTools(\n method: string,\n _rest: string[],\n _body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"GET\") {\n return { status: 405, body: { error: \"GET only\" } };\n }\n if (!ctx.tools) {\n return {\n status: 503,\n body: {\n error:\n \"live tools view requires an attached session — run `/dashboard` from inside `reasonix code` instead of standalone `reasonix dashboard`.\",\n available: false,\n },\n };\n }\n const specs = ctx.tools.specs();\n // We deliberately surface the model-facing schema (`specs()` already\n // resolves auto-flattened forms) so what the SPA shows matches what\n // DeepSeek receives. ReadOnly + planMode flags come from the\n // internal definitions, accessed via `get()`.\n const items = specs.map((s) => {\n const def = ctx.tools!.get(s.function.name);\n return {\n name: s.function.name,\n description: s.function.description,\n schema: s.function.parameters,\n readOnly: Boolean(def?.readOnly),\n flattened: ctx.tools!.wasFlattened(s.function.name),\n };\n });\n return {\n status: 200,\n body: {\n planMode: ctx.tools.planMode,\n total: items.length,\n tools: items,\n },\n };\n}\n","import { cacheSavingsUsd } from \"../../telemetry/stats.js\";\nimport { aggregateUsage, formatLogSize, readUsageLog } from \"../../telemetry/usage.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface DailyBucket {\n /** UTC day key, ISO yyyy-mm-dd. Sorted ascending. */\n day: string;\n turns: number;\n promptTokens: number;\n completionTokens: number;\n cacheHitTokens: number;\n cacheMissTokens: number;\n costUsd: number;\n cacheSavingsUsd: number;\n}\n\nfunction dayKey(ts: number): string {\n return new Date(ts).toISOString().slice(0, 10);\n}\n\nfunction buildSeries(records: ReturnType<typeof readUsageLog>): DailyBucket[] {\n const map = new Map<string, DailyBucket>();\n for (const r of records) {\n const day = dayKey(r.ts);\n let b = map.get(day);\n if (!b) {\n b = {\n day,\n turns: 0,\n promptTokens: 0,\n completionTokens: 0,\n cacheHitTokens: 0,\n cacheMissTokens: 0,\n costUsd: 0,\n cacheSavingsUsd: 0,\n };\n map.set(day, b);\n }\n b.turns += 1;\n b.promptTokens += r.promptTokens;\n b.completionTokens += r.completionTokens;\n b.cacheHitTokens += r.cacheHitTokens;\n b.cacheMissTokens += r.cacheMissTokens;\n b.costUsd += r.costUsd;\n b.cacheSavingsUsd += cacheSavingsUsd(r.model, r.cacheHitTokens);\n }\n return Array.from(map.values()).sort((a, b) => a.day.localeCompare(b.day));\n}\n\nexport async function handleUsage(\n method: string,\n rest: string[],\n _body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"GET\") {\n return { status: 405, body: { error: \"GET only\" } };\n }\n const records = readUsageLog(ctx.usageLogPath);\n\n // /api/usage/series → daily roll-ups for the chart. Separate sub-path\n // so the main /api/usage stays a small dashboard payload that polls\n // every 5s without dragging the series along.\n if (rest[0] === \"series\") {\n return {\n status: 200,\n body: {\n days: buildSeries(records),\n recordCount: records.length,\n },\n };\n }\n\n const agg = aggregateUsage(records);\n return {\n status: 200,\n body: {\n logPath: ctx.usageLogPath,\n logSize: formatLogSize(ctx.usageLogPath),\n recordCount: records.length,\n buckets: agg.buckets,\n byModel: agg.byModel,\n bySession: agg.bySession,\n firstSeen: agg.firstSeen,\n lastSeen: agg.lastSeen,\n subagents: agg.subagents ?? null,\n },\n };\n}\n","import { handleAbort } from \"./api/abort.js\";\nimport { handleEditMode } from \"./api/edit-mode.js\";\nimport { handleFiles } from \"./api/files.js\";\nimport { handleHealth } from \"./api/health.js\";\nimport { handleHooks } from \"./api/hooks.js\";\nimport { handleIndexConfig } from \"./api/index-config.js\";\nimport { handleLoop } from \"./api/loop.js\";\nimport { handleMcp } from \"./api/mcp.js\";\nimport { handleMemory } from \"./api/memory.js\";\nimport { handleMessages } from \"./api/messages.js\";\nimport { handleModal } from \"./api/modal.js\";\nimport { handleModels } from \"./api/models.js\";\nimport { handleOverview } from \"./api/overview.js\";\nimport { handlePermissions } from \"./api/permissions.js\";\nimport { handlePlans } from \"./api/plans.js\";\nimport { handleSemantic } from \"./api/semantic.js\";\nimport { handleSessions } from \"./api/sessions.js\";\nimport { handleSettings } from \"./api/settings.js\";\nimport { handleSkills } from \"./api/skills.js\";\nimport { handleSlash } from \"./api/slash.js\";\nimport { handleSubmit } from \"./api/submit.js\";\nimport { handleTools } from \"./api/tools.js\";\nimport { handleUsage } from \"./api/usage.js\";\nimport type { DashboardContext } from \"./context.js\";\n\nexport interface ApiResult {\n status: number;\n body: unknown;\n}\n\nexport async function handleApi(\n pathTail: string,\n method: string,\n body: string,\n ctx: DashboardContext,\n query: URLSearchParams = new URLSearchParams(),\n): Promise<ApiResult> {\n // Strip a trailing slash so /api/usage and /api/usage/ both work.\n const normalized = pathTail.replace(/\\/+$/, \"\");\n const [head, ...rest] = normalized.split(\"/\");\n\n try {\n switch (head) {\n case \"overview\":\n return await handleOverview(method, rest, body, ctx);\n case \"usage\":\n return await handleUsage(method, rest, body, ctx);\n case \"tools\":\n return await handleTools(method, rest, body, ctx);\n case \"permissions\":\n return await handlePermissions(method, rest, body, ctx);\n case \"messages\":\n return await handleMessages(method, rest, body, ctx);\n case \"submit\":\n return await handleSubmit(method, rest, body, ctx);\n case \"abort\":\n return await handleAbort(method, rest, body, ctx);\n case \"health\":\n return await handleHealth(method, rest, body, ctx);\n case \"sessions\":\n return await handleSessions(method, rest, body, ctx);\n case \"plans\":\n return await handlePlans(method, rest, body, ctx);\n case \"modal\":\n return await handleModal(method, rest, body, ctx);\n case \"edit-mode\":\n return await handleEditMode(method, rest, body, ctx);\n case \"settings\":\n return await handleSettings(method, rest, body, ctx);\n case \"hooks\":\n return await handleHooks(method, rest, body, ctx);\n case \"memory\":\n return await handleMemory(method, rest, body, ctx);\n case \"skills\":\n return await handleSkills(method, rest, body, ctx);\n case \"mcp\":\n return await handleMcp(method, rest, body, ctx, query);\n case \"semantic\":\n return await handleSemantic(method, rest, body, ctx);\n case \"index-config\":\n return await handleIndexConfig(method, rest, body, ctx);\n case \"slash\":\n return await handleSlash(method, rest, body, ctx);\n case \"files\":\n return await handleFiles(method, rest, body, ctx);\n case \"loop\":\n return await handleLoop(method, rest, body, ctx);\n case \"models\":\n return await handleModels(method, rest, body, ctx);\n default:\n return { status: 404, body: { error: `no such endpoint: /${head}` } };\n }\n } catch (err) {\n // Any unexpected throw maps to 500. Endpoint code that wants a\n // user-friendly 4xx must catch + return the envelope itself.\n return {\n status: 500,\n body: { error: `handler crashed: ${(err as Error).message}` },\n };\n }\n}\n"],"mappings":"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","names":["join","existsSync","readdirSync","statSync","join","existsSync","readdirSync","join","statSync","existsSync","readFileSync","dirname","existsSync","existsSync","parseBody","existsSync","readFileSync","dirname","parseBody","parseBody","parseBody","existsSync","mkdirSync","readFileSync","readdirSync","statSync","writeFileSync","homedir","dirname","join","join","homedir","parseBody","existsSync","readdirSync","statSync","readFileSync","mkdirSync","dirname","writeFileSync","parseBody","existsSync","existsSync","sessionsDir","parseBody","cwd","closeSync","fstatSync","openSync","readSync","join","readIndexMeta","join","openSync","fstatSync","readSync","closeSync","existsSync","readFileSync","readFileSync","existsSync","parseBody","closeSync","existsSync","fstatSync","mkdirSync","openSync","readFileSync","readSync","readdirSync","writeFileSync","homedir","dirname","join","parseBody","SAFE_NAME","join","homedir","existsSync","readdirSync","openSync","fstatSync","readSync","closeSync","readFileSync","mkdirSync","dirname","writeFileSync","parseBody"]}
|
|
1
|
+
{"version":3,"sources":["../../src/server/index.ts","../../src/server/api/events.ts","../../src/server/assets.ts","../../src/server/api/abort.ts","../../src/server/api/edit-mode.ts","../../src/server/api/files.ts","../../src/server/api/health.ts","../../src/server/api/hooks.ts","../../src/server/api/hooks-events.ts","../../src/server/api/index-config.ts","../../src/server/api/loop.ts","../../src/server/api/mcp.ts","../../src/server/api/memory.ts","../../src/server/api/messages.ts","../../src/server/api/modal.ts","../../src/server/api/models.ts","../../src/server/api/cockpit-events.ts","../../src/server/api/cockpit.ts","../../src/server/api/overview.ts","../../src/server/api/permissions.ts","../../src/server/api/plans.ts","../../src/server/api/semantic.ts","../../src/server/api/sessions.ts","../../src/server/api/settings.ts","../../src/server/api/skills.ts","../../src/server/api/slash.ts","../../src/server/api/submit.ts","../../src/server/api/tools.ts","../../src/server/api/usage.ts","../../src/server/router.ts"],"sourcesContent":["/** Dashboard HTTP server — pinned to 127.0.0.1, ephemeral per-boot token; mutations require the token in the header (CSRF). */\n\nimport { randomBytes } from \"node:crypto\";\nimport { type IncomingMessage, type ServerResponse, createServer } from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\nimport { handleEvents } from \"./api/events.js\";\nimport { renderIndexHtml, serveAsset } from \"./assets.js\";\nimport type { DashboardContext } from \"./context.js\";\nimport { handleApi } from \"./router.js\";\n\nexport interface StartDashboardOptions {\n /** Force a specific port. 0 = ephemeral. Default: 0. */\n port?: number;\n /** Host to bind. Argument exists for tests; production must keep 127.0.0.1 (no remote auth). */\n host?: string;\n token?: string;\n}\n\nexport interface DashboardServerHandle {\n url: string;\n token: string;\n port: number;\n /** Stop accepting new connections, drain, close. Idempotent. */\n close: () => Promise<void>;\n}\n\nfunction mintToken(): string {\n return randomBytes(32).toString(\"hex\");\n}\n\n/** `===` short-circuits on first mismatch — leaks position via timing even on localhost. */\nexport function constantTimeEquals(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n let mismatch = 0;\n for (let i = 0; i < a.length; i++) {\n mismatch |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return mismatch === 0;\n}\n\n/** Mutations require header (CSRF); reads accept header or query. Returns null on success. */\nexport function checkAuth(\n req: IncomingMessage,\n expectedToken: string,\n isMutation: boolean,\n): { status: number; body: string } | null {\n const url = new URL(req.url ?? \"/\", \"http://localhost\");\n const queryToken = url.searchParams.get(\"token\") ?? \"\";\n const headerToken =\n typeof req.headers[\"x-reasonix-token\"] === \"string\"\n ? (req.headers[\"x-reasonix-token\"] as string)\n : \"\";\n\n if (isMutation) {\n // Header-only for mutations. Query-only requests would still\n // reject here even if the token matched.\n if (!headerToken || !constantTimeEquals(headerToken, expectedToken)) {\n return {\n status: 403,\n body: JSON.stringify({\n error:\n \"mutation requires X-Reasonix-Token header (CSRF defence — query token alone is rejected for POST/DELETE).\",\n }),\n };\n }\n return null;\n }\n\n // Reads accept either form. We compare both candidates against the\n // expected token in constant time and treat the OR as \"any match\n // lets through.\"\n if (\n (queryToken && constantTimeEquals(queryToken, expectedToken)) ||\n (headerToken && constantTimeEquals(headerToken, expectedToken))\n ) {\n return null;\n }\n return {\n status: 401,\n body: JSON.stringify({ error: \"missing or invalid token\" }),\n };\n}\n\nconst MAX_BODY_BYTES = 256 * 1024;\n\nexport async function readBody(req: IncomingMessage): Promise<string> {\n let total = 0;\n const chunks: Buffer[] = [];\n return new Promise((resolve, reject) => {\n req.on(\"data\", (chunk: Buffer) => {\n total += chunk.length;\n if (total > MAX_BODY_BYTES) {\n reject(new Error(`body exceeds ${MAX_BODY_BYTES} bytes`));\n req.destroy();\n return;\n }\n chunks.push(chunk);\n });\n req.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf8\")));\n req.on(\"error\", reject);\n });\n}\n\nexport async function dispatch(\n req: IncomingMessage,\n res: ServerResponse,\n ctx: DashboardContext,\n expectedToken: string,\n): Promise<void> {\n const url = new URL(req.url ?? \"/\", \"http://localhost\");\n const path = url.pathname;\n const method = (req.method ?? \"GET\").toUpperCase();\n const isMutation = method === \"POST\" || method === \"DELETE\" || method === \"PUT\";\n\n // SPA routes — token-gate the HTML so a stranger can't even see the\n // shell without the token. This also means the user MUST come in\n // through the token-bearing URL we print to the TUI.\n if (path === \"/\" || path === \"/index.html\") {\n const fail = checkAuth(req, expectedToken, false);\n if (fail) {\n res.writeHead(fail.status, { \"content-type\": \"text/plain\" });\n res.end(\"unauthorized — open the URL printed by /dashboard, including ?token=…\");\n return;\n }\n const html = renderIndexHtml(expectedToken, ctx.mode);\n res.writeHead(200, { \"content-type\": \"text/html; charset=utf-8\" });\n res.end(html);\n return;\n }\n\n if (path.startsWith(\"/assets/\")) {\n const fail = checkAuth(req, expectedToken, false);\n if (fail) {\n res.writeHead(fail.status);\n res.end();\n return;\n }\n const asset = serveAsset(path.slice(\"/assets/\".length));\n if (!asset) {\n res.writeHead(404);\n res.end(\"not found\");\n return;\n }\n res.writeHead(200, { \"content-type\": asset.contentType });\n res.end(asset.body);\n return;\n }\n\n // SSE event stream — special-cased BEFORE the normal `/api/*` branch\n // because it keeps the response open and writes its own frames; the\n // normal path would try to JSON-encode and end the response.\n if (path === \"/api/events\") {\n const fail = checkAuth(req, expectedToken, false);\n if (fail) {\n res.writeHead(fail.status, { \"content-type\": \"application/json\" });\n res.end(fail.body);\n return;\n }\n handleEvents(req, res, ctx);\n return;\n }\n\n if (path.startsWith(\"/api/\")) {\n const fail = checkAuth(req, expectedToken, isMutation);\n if (fail) {\n res.writeHead(fail.status, { \"content-type\": \"application/json\" });\n res.end(fail.body);\n return;\n }\n let body = \"\";\n if (isMutation) {\n try {\n body = await readBody(req);\n } catch (err) {\n res.writeHead(413, { \"content-type\": \"application/json\" });\n res.end(JSON.stringify({ error: (err as Error).message }));\n return;\n }\n }\n const result = await handleApi(path.slice(\"/api/\".length), method, body, ctx, url.searchParams);\n res.writeHead(result.status, { \"content-type\": \"application/json\" });\n res.end(JSON.stringify(result.body));\n return;\n }\n\n res.writeHead(404, { \"content-type\": \"text/plain\" });\n res.end(\"not found\");\n}\n\n/**\n * Boot a server bound to 127.0.0.1, return an awaitable handle.\n */\nexport function startDashboardServer(\n ctx: DashboardContext,\n opts: StartDashboardOptions = {},\n): Promise<DashboardServerHandle> {\n const token = opts.token ?? mintToken();\n const host = opts.host ?? \"127.0.0.1\";\n const port = opts.port ?? 0;\n\n return new Promise((resolve, reject) => {\n const server = createServer((req, res) => {\n dispatch(req, res, ctx, token).catch((err) => {\n if (!res.headersSent) {\n res.writeHead(500, { \"content-type\": \"application/json\" });\n }\n res.end(JSON.stringify({ error: (err as Error).message }));\n });\n });\n server.on(\"error\", reject);\n server.listen(port, host, () => {\n const addr = server.address() as AddressInfo;\n const finalPort = addr.port;\n const url = `http://${host}:${finalPort}/?token=${token}`;\n\n let closed = false;\n const close = (): Promise<void> =>\n new Promise<void>((doneResolve) => {\n if (closed) return doneResolve();\n closed = true;\n server.close(() => doneResolve());\n // Force any keep-alive sockets to drop after a short grace.\n setTimeout(() => server.closeAllConnections?.(), 1000).unref();\n });\n\n resolve({ url, token, port: finalPort, close });\n });\n });\n}\n","/** SSE stream of DashboardEvents; 25s ping keeps proxies from dropping idle connections. */\n\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { DashboardContext, DashboardEvent } from \"../context.js\";\n\nconst PING_INTERVAL_MS = 25_000;\n\nexport function handleEvents(\n req: IncomingMessage,\n res: ServerResponse,\n ctx: DashboardContext,\n): void {\n if (!ctx.subscribeEvents) {\n res.writeHead(503, { \"content-type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"event stream requires an attached dashboard session.\" }));\n return;\n }\n\n res.writeHead(200, {\n \"content-type\": \"text/event-stream\",\n \"cache-control\": \"no-cache\",\n connection: \"keep-alive\",\n \"x-accel-buffering\": \"no\", // disable Nginx-style buffering if anything proxies us\n });\n\n const writeEvent = (event: DashboardEvent): void => {\n if (res.writableEnded) return;\n try {\n res.write(`data: ${JSON.stringify(event)}\\n\\n`);\n } catch {\n /* socket gone — connection close handler will tidy up */\n }\n };\n\n // Send a snapshot busy-change immediately so the client's button\n // state is correct on first paint (instead of inheriting whatever\n // the prior connection's last delta said).\n if (ctx.isBusy) writeEvent({ kind: \"busy-change\", busy: ctx.isBusy() });\n\n const unsubscribe = ctx.subscribeEvents(writeEvent);\n\n const ping = setInterval(() => writeEvent({ kind: \"ping\" }), PING_INTERVAL_MS);\n // Don't keep the process alive just for the heartbeat.\n ping.unref?.();\n\n const cleanup = (): void => {\n clearInterval(ping);\n try {\n unsubscribe();\n } catch {\n /* already torn down */\n }\n if (!res.writableEnded) {\n try {\n res.end();\n } catch {\n /* already closed */\n }\n }\n };\n\n req.on(\"close\", cleanup);\n req.on(\"error\", cleanup);\n res.on(\"close\", cleanup);\n}\n","import { closeSync, fstatSync, openSync, readFileSync, readSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/** Resolve dashboard/ across tsx-dev and tsup-bundled layouts. */\nfunction resolveAssetDir(): string {\n const here = dirname(fileURLToPath(import.meta.url));\n // Try a few candidates; the first existing one wins.\n // - src/server/ → ../../dashboard\n // - dist/ → ./dashboard (post-bundle, dashboard/ flat at dist root)\n // - dist/cli/ → ../dashboard\n const candidates = [\n join(here, \"..\", \"..\", \"dashboard\"),\n join(here, \"..\", \"dashboard\"),\n join(here, \"dashboard\"),\n ];\n for (const c of candidates) {\n try {\n readFileSync(join(c, \"index.html\"), \"utf8\");\n return c;\n } catch {\n /* try next */\n }\n }\n // Fall through to the most-likely-correct dev path; the read on first\n // request will throw with a useful path in the error message.\n return candidates[0]!;\n}\n\nconst ASSET_DIR = resolveAssetDir();\n\n/** mtime-keyed cache — `npm run build` invalidates without restart. */\nconst fileCache = new Map<string, { body: string; mtimeMs: number }>();\n\nfunction loadCachedFile(path: string): string {\n // Open once and reuse the fd so the mtime check and the read bind to\n // the same inode — closes the stat→read TOCTOU race.\n const fd = openSync(path, \"r\");\n try {\n const stat = fstatSync(fd);\n const cached = fileCache.get(path);\n if (cached && cached.mtimeMs === stat.mtimeMs) return cached.body;\n const buf = Buffer.alloc(stat.size);\n let read = 0;\n while (read < stat.size) {\n const n = readSync(fd, buf, read, stat.size - read, read);\n if (n <= 0) break;\n read += n;\n }\n const body = buf.toString(\"utf8\", 0, read);\n fileCache.set(path, { body, mtimeMs: stat.mtimeMs });\n return body;\n } finally {\n closeSync(fd);\n }\n}\n\nfunction loadIndexTemplate(): string {\n return loadCachedFile(join(ASSET_DIR, \"index.html\"));\n}\n\nfunction loadApp(): string {\n return loadCachedFile(join(ASSET_DIR, \"dist\", \"app.js\"));\n}\n\nfunction loadAppMap(): string | null {\n try {\n return loadCachedFile(join(ASSET_DIR, \"dist\", \"app.js.map\"));\n } catch {\n return null;\n }\n}\n\nfunction loadCss(): string {\n return loadCachedFile(join(ASSET_DIR, \"app.css\"));\n}\n\n/** Token HTML-attribute-escaped in case a future mint produces non-hex bytes. */\nexport function renderIndexHtml(token: string, mode: \"standalone\" | \"attached\"): string {\n const tpl = loadIndexTemplate();\n const safeToken = token.replace(/[^a-zA-Z0-9]/g, \"\");\n // String.replace(string, replacement) only swaps the FIRST match. The\n // template has __REASONIX_TOKEN__ in three places (meta + css href +\n // script src) — without `replaceAll` only the meta tag gets the real\n // token, the asset URLs keep the placeholder and the browser hits a\n // 401 on every asset fetch. Same trap for __REASONIX_MODE__ if it\n // ever appears more than once.\n return tpl.replaceAll(\"__REASONIX_TOKEN__\", safeToken).replaceAll(\"__REASONIX_MODE__\", mode);\n}\n\n/** Vendor CSS the bundle pulls from npm and the build script copies into `dashboard/dist/`. */\nconst VENDOR_CSS_NAMES = new Set([\"vendor-hljs.css\", \"vendor-uplot.css\"]);\n\nfunction loadVendorCss(name: string): string {\n return loadCachedFile(join(ASSET_DIR, \"dist\", name));\n}\n\nexport function serveAsset(name: string): { body: string; contentType: string } | null {\n if (name === \"app.js\") {\n return { body: loadApp(), contentType: \"application/javascript; charset=utf-8\" };\n }\n if (name === \"app.js.map\") {\n const body = loadAppMap();\n return body == null ? null : { body, contentType: \"application/json; charset=utf-8\" };\n }\n if (name === \"app.css\") {\n return { body: loadCss(), contentType: \"text/css; charset=utf-8\" };\n }\n if (VENDOR_CSS_NAMES.has(name)) {\n return { body: loadVendorCss(name), contentType: \"text/css; charset=utf-8\" };\n }\n return null;\n}\n","import type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\nexport async function handleAbort(\n method: string,\n _rest: string[],\n _body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"POST\") {\n return { status: 405, body: { error: \"POST only\" } };\n }\n if (!ctx.abortTurn) {\n return {\n status: 503,\n body: { error: \"abort requires an attached dashboard session.\" },\n };\n }\n ctx.abortTurn();\n ctx.audit?.({ ts: Date.now(), action: \"abort-turn\" });\n return { status: 202, body: { aborted: true } };\n}\n","import type { EditMode } from \"../../config.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface ModeBody {\n mode?: unknown;\n}\n\nfunction parseBody(raw: string): ModeBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as ModeBody) : {};\n } catch {\n return {};\n }\n}\n\nconst VALID = new Set<EditMode>([\"review\", \"auto\", \"yolo\"]);\n\nexport async function handleEditMode(\n method: string,\n _rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method === \"GET\") {\n return {\n status: 200,\n body: { mode: ctx.getEditMode?.() ?? null },\n };\n }\n if (method === \"POST\") {\n if (!ctx.setEditMode) {\n return {\n status: 503,\n body: { error: \"edit-mode mutation requires an attached `reasonix code` session.\" },\n };\n }\n const { mode } = parseBody(body);\n if (typeof mode !== \"string\" || !VALID.has(mode as EditMode)) {\n return { status: 400, body: { error: \"mode must be review | auto | yolo\" } };\n }\n const resolved = ctx.setEditMode(mode as EditMode);\n ctx.audit?.({ ts: Date.now(), action: \"set-edit-mode\", payload: { mode: resolved } });\n return { status: 200, body: { mode: resolved } };\n }\n return { status: 405, body: { error: \"GET or POST only\" } };\n}\n","import { existsSync, readdirSync, statSync } from \"node:fs\";\nimport { extname, join, relative, sep } from \"node:path\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\nconst RESULT_CAP = 50;\nconst MAX_DEPTH = 4;\nconst SKIP_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \".reasonix\",\n \"dist\",\n \"build\",\n \"out\",\n \".next\",\n \"coverage\",\n \".cache\",\n \"__pycache__\",\n \".venv\",\n \".pytest_cache\",\n]);\nconst SKIP_EXTS = new Set([\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".webp\",\n \".ico\",\n \".pdf\",\n \".zip\",\n \".tar\",\n \".gz\",\n \".lock\",\n \".woff\",\n \".woff2\",\n \".ttf\",\n]);\n\nexport async function handleFiles(\n method: string,\n _rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"POST\") return { status: 405, body: { error: \"POST only\" } };\n const cwd = ctx.getCurrentCwd?.();\n if (!cwd || !existsSync(cwd)) {\n return { status: 503, body: { error: \"@-mention picker requires a code-mode session\" } };\n }\n let parsed: { prefix?: unknown };\n try {\n parsed = JSON.parse(body || \"{}\");\n } catch {\n return { status: 400, body: { error: \"body must be JSON\" } };\n }\n const prefix = typeof parsed.prefix === \"string\" ? parsed.prefix.trim().toLowerCase() : \"\";\n const matches = walk(cwd, prefix);\n return { status: 200, body: { files: matches } };\n}\n\nfunction walk(root: string, prefix: string): string[] {\n const out: string[] = [];\n const stack: Array<{ path: string; depth: number }> = [{ path: root, depth: 0 }];\n while (stack.length > 0 && out.length < RESULT_CAP) {\n const { path, depth } = stack.pop()!;\n if (depth > MAX_DEPTH) continue;\n let names: string[];\n try {\n names = readdirSync(path);\n } catch {\n continue;\n }\n for (const name of names) {\n if (out.length >= RESULT_CAP) break;\n if (name.startsWith(\".\") && depth === 0) continue;\n if (SKIP_DIRS.has(name)) continue;\n const full = join(path, name);\n let st: ReturnType<typeof statSync>;\n try {\n st = statSync(full);\n } catch {\n continue;\n }\n if (st.isDirectory()) {\n stack.push({ path: full, depth: depth + 1 });\n continue;\n }\n if (!st.isFile()) continue;\n if (SKIP_EXTS.has(extname(name).toLowerCase())) continue;\n const rel = relative(root, full).split(sep).join(\"/\");\n if (prefix && !rel.toLowerCase().includes(prefix)) continue;\n out.push(rel);\n }\n }\n return out.sort((a, b) => a.localeCompare(b));\n}\n","import { existsSync, readdirSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { listSessions } from \"../../memory/session.js\";\nimport { VERSION } from \"../../version.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface DirStat {\n path: string;\n exists: boolean;\n fileCount: number;\n totalBytes: number;\n}\n\n/** Sum file sizes one level deep. Recursion deferred until we have a use-case for nested data dirs. */\nfunction dirSize(path: string): DirStat {\n if (!existsSync(path)) return { path, exists: false, fileCount: 0, totalBytes: 0 };\n let fileCount = 0;\n let totalBytes = 0;\n try {\n const entries = readdirSync(path);\n for (const name of entries) {\n const full = join(path, name);\n try {\n const s = statSync(full);\n if (s.isFile()) {\n fileCount++;\n totalBytes += s.size;\n } else if (s.isDirectory()) {\n // Recurse one level for nested folders (memory/<hash>, sessions/, etc).\n try {\n const inner = readdirSync(full);\n for (const child of inner) {\n try {\n const cs = statSync(join(full, child));\n if (cs.isFile()) {\n fileCount++;\n totalBytes += cs.size;\n }\n } catch {\n /* skip */\n }\n }\n } catch {\n /* skip */\n }\n }\n } catch {\n /* skip — file might have been deleted between readdir + stat */\n }\n }\n } catch {\n return { path, exists: true, fileCount: 0, totalBytes: 0 };\n }\n return { path, exists: true, fileCount, totalBytes };\n}\n\nexport async function handleHealth(\n method: string,\n _rest: string[],\n _body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"GET\") {\n return { status: 405, body: { error: \"GET only\" } };\n }\n const home = homedir();\n const reasonixHome = join(home, \".reasonix\");\n\n const sessionsStat = dirSize(join(reasonixHome, \"sessions\"));\n const memoryStat = dirSize(join(reasonixHome, \"memory\"));\n const semanticStat = dirSize(join(reasonixHome, \"semantic\"));\n\n let usageBytes = 0;\n if (existsSync(ctx.usageLogPath)) {\n try {\n usageBytes = statSync(ctx.usageLogPath).size;\n } catch {\n /* ignore */\n }\n }\n\n const sessions = listSessions();\n\n return {\n status: 200,\n body: {\n version: VERSION,\n latestVersion: ctx.getLatestVersion?.() ?? null,\n reasonixHome,\n sessions: {\n path: sessionsStat.path,\n count: sessions.length,\n totalBytes: sessionsStat.totalBytes,\n },\n memory: {\n path: memoryStat.path,\n fileCount: memoryStat.fileCount,\n totalBytes: memoryStat.totalBytes,\n },\n semantic: {\n path: semanticStat.path,\n exists: semanticStat.exists,\n fileCount: semanticStat.fileCount,\n totalBytes: semanticStat.totalBytes,\n },\n usageLog: {\n path: ctx.usageLogPath,\n bytes: usageBytes,\n },\n jobs: ctx.jobs ? ctx.jobs.list().length : null,\n },\n };\n}\n","/** Reload is a separate POST so save and apply stay decoupled; the SPA chains them by convention. */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { HOOK_EVENTS, globalSettingsPath, loadHooks, projectSettingsPath } from \"../../hooks.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\nimport { readRecentHookRuns } from \"./hooks-events.js\";\n\ninterface SaveBody {\n scope?: unknown;\n hooks?: unknown;\n}\n\nfunction parseBody(raw: string): SaveBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as SaveBody) : {};\n } catch {\n return {};\n }\n}\n\nfunction readSettingsFile(path: string): { hooks?: Record<string, unknown[]> } {\n if (!existsSync(path)) return {};\n try {\n const raw = readFileSync(path, \"utf8\");\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? parsed : {};\n } catch {\n return {};\n }\n}\n\nfunction writeSettingsFile(path: string, hooksBlock: unknown): void {\n // Preserve any other top-level keys that may live in the file.\n const existing = readSettingsFile(path);\n existing.hooks = hooksBlock as Record<string, unknown[]>;\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, `${JSON.stringify(existing, null, 2)}\\n`, \"utf8\");\n}\n\nexport async function handleHooks(\n method: string,\n rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method === \"GET\" && rest.length === 0) {\n const projectPath = ctx.getCurrentCwd ? projectSettingsPath(ctx.getCurrentCwd() ?? \"\") : null;\n const globalPath = globalSettingsPath();\n const projectFile = projectPath ? readSettingsFile(projectPath) : {};\n const globalFile = readSettingsFile(globalPath);\n const resolved = loadHooks({ projectRoot: ctx.getCurrentCwd?.() });\n return {\n status: 200,\n body: {\n project: {\n path: projectPath,\n hooks: projectFile.hooks ?? {},\n },\n global: {\n path: globalPath,\n hooks: globalFile.hooks ?? {},\n },\n resolved,\n events: HOOK_EVENTS,\n recentRuns: readRecentHookRuns(undefined, ctx.sessionsDir),\n },\n };\n }\n\n if (method === \"POST\" && rest[0] === \"save\") {\n const { scope, hooks } = parseBody(body);\n if (scope !== \"project\" && scope !== \"global\") {\n return { status: 400, body: { error: \"scope must be project | global\" } };\n }\n if (typeof hooks !== \"object\" || hooks === null) {\n return { status: 400, body: { error: \"hooks must be an object keyed by event name\" } };\n }\n let path: string | null;\n if (scope === \"project\") {\n const cwd = ctx.getCurrentCwd?.();\n if (!cwd) {\n return {\n status: 503,\n body: { error: \"no active project — open `/dashboard` from inside `reasonix code`\" },\n };\n }\n path = projectSettingsPath(cwd);\n } else {\n path = globalSettingsPath();\n }\n if (!path) {\n return { status: 500, body: { error: \"could not resolve settings path\" } };\n }\n writeSettingsFile(path, hooks);\n ctx.audit?.({ ts: Date.now(), action: \"save-hooks\", payload: { scope, path } });\n return { status: 200, body: { saved: true, path } };\n }\n\n if (method === \"POST\" && rest[0] === \"reload\") {\n if (!ctx.reloadHooks) {\n return {\n status: 503,\n body: { error: \"reload requires an attached session — App.tsx wires the callback\" },\n };\n }\n const count = ctx.reloadHooks();\n ctx.audit?.({ ts: Date.now(), action: \"reload-hooks\", payload: { count } });\n return { status: 200, body: { reloaded: true, count } };\n }\n\n return { status: 405, body: { error: `method ${method} not supported on this path` } };\n}\n","import { existsSync } from \"node:fs\";\nimport { readEventLogFile, recentEventFiles } from \"../../adapters/event-source-jsonl.js\";\nimport { sessionsDir as defaultSessionsDir } from \"../../memory/session.js\";\n\nexport interface HookRunRow {\n hookName: string;\n phase: \"PreToolUse\" | \"PostToolUse\" | \"UserPromptSubmit\" | \"Stop\";\n outcome: \"ok\" | \"blocked\" | \"modified\" | \"error\";\n whenMs: number;\n}\n\nconst HOOK_LOG_CAP = 12;\n\nexport function readRecentHookRuns(\n now: number = Date.now(),\n sessionsDirOverride?: string,\n): ReadonlyArray<HookRunRow> | null {\n const dir = sessionsDirOverride ?? defaultSessionsDir();\n if (!existsSync(dir)) return null;\n const files = recentEventFiles(dir, now);\n if (files.length === 0) return null;\n\n const rows: HookRunRow[] = [];\n for (const file of files) {\n const events = readEventLogFile(file);\n for (const ev of events) {\n if (ev.type !== \"hook.fired\") continue;\n const ts = Date.parse(ev.ts);\n if (!Number.isFinite(ts)) continue;\n rows.push({\n hookName: ev.hookName,\n phase: ev.phase,\n outcome: ev.outcome,\n whenMs: ts,\n });\n }\n }\n rows.sort((a, b) => b.whenMs - a.whenMs);\n return rows.slice(0, HOOK_LOG_CAP);\n}\n","/** GET returns resolved + defaults so the SPA can render a \"reset\" button without re-implementing them. */\n\nimport { loadIndexUserConfig, readConfig, writeConfig } from \"../../config.js\";\nimport {\n DEFAULT_INDEX_EXCLUDES,\n DEFAULT_MAX_FILE_BYTES,\n DEFAULT_RESPECT_GITIGNORE,\n type IndexUserConfig,\n resolveIndexConfig,\n} from \"../../index/config.js\";\nimport { type SkipReason, walkChunks } from \"../../index/semantic/chunker.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\nconst PREVIEW_INCLUDED_CAP = 50;\nconst PREVIEW_PER_REASON_CAP = 10;\n\ninterface PostBody {\n excludeDirs?: unknown;\n excludeFiles?: unknown;\n excludeExts?: unknown;\n excludePatterns?: unknown;\n respectGitignore?: unknown;\n maxFileBytes?: unknown;\n}\n\nfunction parseBody(raw: string): PostBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as PostBody) : {};\n } catch {\n return {};\n }\n}\n\nfunction isStringArray(v: unknown): v is string[] {\n return Array.isArray(v) && v.every((x) => typeof x === \"string\");\n}\n\nexport async function handleIndexConfig(\n method: string,\n rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (rest[0] === \"preview\" && method === \"POST\") {\n return await handlePreview(body, ctx);\n }\n if (method === \"GET\") {\n const user = loadIndexUserConfig(ctx.configPath);\n const resolved = resolveIndexConfig(user);\n return {\n status: 200,\n body: {\n user,\n resolved,\n defaults: {\n excludeDirs: [...DEFAULT_INDEX_EXCLUDES.dirs],\n excludeFiles: [...DEFAULT_INDEX_EXCLUDES.files],\n excludeExts: [...DEFAULT_INDEX_EXCLUDES.exts],\n excludePatterns: [],\n respectGitignore: DEFAULT_RESPECT_GITIGNORE,\n maxFileBytes: DEFAULT_MAX_FILE_BYTES,\n },\n },\n };\n }\n\n if (method === \"POST\") {\n const fields = parseBody(body);\n const next: IndexUserConfig = {};\n const changed: string[] = [];\n\n if (fields.excludeDirs !== undefined) {\n if (!isStringArray(fields.excludeDirs)) {\n return { status: 400, body: { error: \"excludeDirs must be string[]\" } };\n }\n next.excludeDirs = fields.excludeDirs;\n changed.push(\"excludeDirs\");\n }\n if (fields.excludeFiles !== undefined) {\n if (!isStringArray(fields.excludeFiles)) {\n return { status: 400, body: { error: \"excludeFiles must be string[]\" } };\n }\n next.excludeFiles = fields.excludeFiles;\n changed.push(\"excludeFiles\");\n }\n if (fields.excludeExts !== undefined) {\n if (!isStringArray(fields.excludeExts)) {\n return { status: 400, body: { error: \"excludeExts must be string[]\" } };\n }\n next.excludeExts = fields.excludeExts;\n changed.push(\"excludeExts\");\n }\n if (fields.excludePatterns !== undefined) {\n if (!isStringArray(fields.excludePatterns)) {\n return { status: 400, body: { error: \"excludePatterns must be string[]\" } };\n }\n next.excludePatterns = fields.excludePatterns;\n changed.push(\"excludePatterns\");\n }\n if (fields.respectGitignore !== undefined) {\n if (typeof fields.respectGitignore !== \"boolean\") {\n return { status: 400, body: { error: \"respectGitignore must be boolean\" } };\n }\n next.respectGitignore = fields.respectGitignore;\n changed.push(\"respectGitignore\");\n }\n if (fields.maxFileBytes !== undefined) {\n if (typeof fields.maxFileBytes !== \"number\" || fields.maxFileBytes <= 0) {\n return { status: 400, body: { error: \"maxFileBytes must be a positive number\" } };\n }\n next.maxFileBytes = fields.maxFileBytes;\n changed.push(\"maxFileBytes\");\n }\n\n const cfg = readConfig(ctx.configPath);\n cfg.index = { ...(cfg.index ?? {}), ...next };\n writeConfig(cfg, ctx.configPath);\n if (changed.length > 0) {\n ctx.audit?.({ ts: Date.now(), action: \"set-index-config\", payload: { fields: changed } });\n }\n return { status: 200, body: { changed, resolved: resolveIndexConfig(cfg.index) } };\n }\n\n return { status: 405, body: { error: \"GET or POST only\" } };\n}\n\nasync function handlePreview(body: string, ctx: DashboardContext): Promise<ApiResult> {\n const root = ctx.getCurrentCwd?.();\n if (!root) {\n return {\n status: 400,\n body: { error: \"preview requires a code-mode session (no project root attached)\" },\n };\n }\n const fields = parseBody(body);\n const draft: IndexUserConfig = {};\n if (isStringArray(fields.excludeDirs)) draft.excludeDirs = fields.excludeDirs;\n if (isStringArray(fields.excludeFiles)) draft.excludeFiles = fields.excludeFiles;\n if (isStringArray(fields.excludeExts)) draft.excludeExts = fields.excludeExts;\n if (isStringArray(fields.excludePatterns)) draft.excludePatterns = fields.excludePatterns;\n if (typeof fields.respectGitignore === \"boolean\")\n draft.respectGitignore = fields.respectGitignore;\n if (typeof fields.maxFileBytes === \"number\" && fields.maxFileBytes > 0) {\n draft.maxFileBytes = fields.maxFileBytes;\n }\n const resolved = resolveIndexConfig(draft);\n const skipBuckets: Record<SkipReason, number> = {\n defaultDir: 0,\n defaultFile: 0,\n binaryExt: 0,\n binaryContent: 0,\n tooLarge: 0,\n gitignore: 0,\n pattern: 0,\n readError: 0,\n };\n const skipSamples: Record<SkipReason, string[]> = {\n defaultDir: [],\n defaultFile: [],\n binaryExt: [],\n binaryContent: [],\n tooLarge: [],\n gitignore: [],\n pattern: [],\n readError: [],\n };\n const includedFiles = new Set<string>();\n const sampleIncluded: string[] = [];\n for await (const chunk of walkChunks(root, {\n config: resolved,\n onSkip: (rel, reason) => {\n skipBuckets[reason]++;\n const bucket = skipSamples[reason];\n if (bucket.length < PREVIEW_PER_REASON_CAP) bucket.push(rel);\n },\n })) {\n if (!includedFiles.has(chunk.path)) {\n includedFiles.add(chunk.path);\n if (sampleIncluded.length < PREVIEW_INCLUDED_CAP) sampleIncluded.push(chunk.path);\n }\n }\n return {\n status: 200,\n body: {\n filesIncluded: includedFiles.size,\n sampleIncluded,\n skipBuckets,\n skipSamples,\n resolved,\n },\n };\n}\n","import type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface LoopStartBody {\n intervalMs?: unknown;\n prompt?: unknown;\n}\n\nfunction parseBody(raw: string): LoopStartBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as LoopStartBody) : {};\n } catch {\n return {};\n }\n}\n\nconst MIN_INTERVAL_MS = 5_000;\nconst MAX_INTERVAL_MS = 6 * 60 * 60 * 1000;\n\nexport async function handleLoop(\n method: string,\n rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method === \"GET\" && rest[0] === \"status\") {\n if (!ctx.getLoopRunStatus) {\n return { status: 503, body: { error: \"auto-loop not available — attach to a chat session\" } };\n }\n return { status: 200, body: { status: ctx.getLoopRunStatus() } };\n }\n\n if (method === \"POST\" && rest[0] === \"start\") {\n if (!ctx.startAutoLoop) {\n return { status: 503, body: { error: \"auto-loop start not wired\" } };\n }\n const { intervalMs, prompt } = parseBody(body);\n if (typeof prompt !== \"string\" || !prompt.trim()) {\n return { status: 400, body: { error: \"prompt must be a non-empty string\" } };\n }\n if (\n typeof intervalMs !== \"number\" ||\n !Number.isFinite(intervalMs) ||\n intervalMs < MIN_INTERVAL_MS ||\n intervalMs > MAX_INTERVAL_MS\n ) {\n return {\n status: 400,\n body: {\n error: `intervalMs must be a number in [${MIN_INTERVAL_MS}, ${MAX_INTERVAL_MS}] (5s..6h)`,\n },\n };\n }\n ctx.startAutoLoop(intervalMs, prompt.trim());\n ctx.audit?.({ ts: Date.now(), action: \"auto-loop-start\", payload: { intervalMs } });\n return { status: 200, body: { started: true } };\n }\n\n if (method === \"POST\" && rest[0] === \"stop\") {\n if (!ctx.stopAutoLoop) {\n return { status: 503, body: { error: \"auto-loop stop not wired\" } };\n }\n ctx.stopAutoLoop();\n ctx.audit?.({ ts: Date.now(), action: \"auto-loop-stop\" });\n return { status: 200, body: { stopped: true } };\n }\n\n return {\n status: 405,\n body: { error: `method ${method} not supported on /api/loop/${rest[0] ?? \"\"}` },\n };\n}\n","/** Spec mutations don't auto-reload — adding a server shifts the system prefix and zeroes the next cache hit. */\n\nimport { readConfig, writeConfig } from \"../../config.js\";\nimport {\n fetchSmitheryDetail,\n handleToFetchResult,\n loadMorePages,\n openRegistry,\n specStringFor,\n} from \"../../mcp/registry-fetch.js\";\nimport type { RegistryEntry } from \"../../mcp/registry-types.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface SpecBody {\n spec?: unknown;\n}\ninterface InvokeBody {\n server?: unknown;\n tool?: unknown;\n args?: unknown;\n}\ninterface InstallBody {\n name?: unknown;\n maxPages?: unknown;\n}\n\nfunction parseBody<T>(raw: string): T {\n if (!raw) return {} as T;\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as T) : ({} as T);\n } catch {\n return {} as T;\n }\n}\n\nfunction clampInt(\n raw: string | null | undefined,\n min: number,\n max: number,\n fallback: number,\n): number {\n if (raw == null) return fallback;\n const n = Number.parseInt(raw, 10);\n if (!Number.isFinite(n)) return fallback;\n return Math.max(min, Math.min(max, n));\n}\n\nfunction findRegistryEntry(entries: RegistryEntry[], name: string): RegistryEntry | null {\n const exact = entries.find((e) => e.name === name);\n if (exact) return exact;\n const lower = name.toLowerCase();\n const ci = entries.find((e) => e.name.toLowerCase() === lower);\n if (ci) return ci;\n const tail = entries.find((e) => e.name.toLowerCase().endsWith(`/${lower}`));\n if (tail) return tail;\n return null;\n}\n\nexport async function handleMcp(\n method: string,\n rest: string[],\n body: string,\n ctx: DashboardContext,\n query: URLSearchParams = new URLSearchParams(),\n): Promise<ApiResult> {\n // Bridged-server view (live).\n if (method === \"GET\" && rest.length === 0) {\n const servers = (ctx.mcpServers ?? []).map((s) => ({\n label: s.label,\n spec: s.spec,\n toolCount: s.toolCount,\n protocolVersion: s.report.protocolVersion,\n serverInfo: s.report.serverInfo,\n capabilities: s.report.capabilities,\n tools: s.report.tools.supported ? s.report.tools.items : [],\n resources: s.report.resources.supported ? s.report.resources.items : [],\n prompts: s.report.prompts.supported ? s.report.prompts.items : [],\n instructions: s.report.instructions ?? null,\n }));\n return {\n status: 200,\n body: {\n servers,\n canHotReload: Boolean(ctx.reloadMcp),\n canInvoke: Boolean(ctx.invokeMcpTool),\n },\n };\n }\n\n // Persisted spec list — what config.mcp[] holds. May differ from\n // bridged set (a recent edit hasn't been reloaded yet).\n if (method === \"GET\" && rest[0] === \"specs\") {\n const cfg = readConfig(ctx.configPath);\n return { status: 200, body: { specs: cfg.mcp ?? [] } };\n }\n\n if (method === \"POST\" && rest[0] === \"specs\") {\n const { spec } = parseBody<SpecBody>(body);\n if (typeof spec !== \"string\" || !spec.trim()) {\n return { status: 400, body: { error: \"spec (non-empty string) required\" } };\n }\n const cfg = readConfig(ctx.configPath);\n const list = cfg.mcp ?? [];\n if (list.includes(spec)) {\n return { status: 200, body: { added: false, alreadyPresent: true } };\n }\n cfg.mcp = [...list, spec.trim()];\n writeConfig(cfg, ctx.configPath);\n ctx.audit?.({ ts: Date.now(), action: \"add-mcp-spec\", payload: { spec } });\n let bridged = false;\n if (ctx.reloadMcp) {\n try {\n await ctx.reloadMcp();\n bridged = true;\n } catch {\n /* fall through to requiresRestart */\n }\n }\n return { status: 200, body: { added: true, requiresRestart: !bridged, bridged } };\n }\n\n if (method === \"DELETE\" && rest[0] === \"specs\") {\n const { spec } = parseBody<SpecBody>(body);\n if (typeof spec !== \"string\") {\n return { status: 400, body: { error: \"spec (string) required\" } };\n }\n const cfg = readConfig(ctx.configPath);\n const list = cfg.mcp ?? [];\n if (!list.includes(spec)) {\n return { status: 200, body: { removed: false } };\n }\n cfg.mcp = list.filter((s) => s !== spec);\n writeConfig(cfg, ctx.configPath);\n ctx.audit?.({ ts: Date.now(), action: \"remove-mcp-spec\", payload: { spec } });\n let bridged = false;\n if (ctx.reloadMcp) {\n try {\n await ctx.reloadMcp();\n bridged = true;\n } catch {\n /* fall through */\n }\n }\n return { status: 200, body: { removed: true, requiresRestart: !bridged, bridged } };\n }\n\n if (method === \"POST\" && rest[0] === \"reload\") {\n if (!ctx.reloadMcp) {\n return {\n status: 503,\n body: {\n error:\n \"live MCP reload not wired in this session — restart `reasonix code` to apply spec edits.\",\n },\n };\n }\n const count = await ctx.reloadMcp();\n return { status: 200, body: { reloaded: true, count } };\n }\n\n // Marketplace registry — open + lazy-paginate. Query: ?pages=N&q=&maxPages=&limit=&refresh=1\n // Caps are generous on purpose: registry walks are bounded by the upstream\n // 24h cache, and an HTTP response of ~1000 entries is still under 1 MB.\n // The dashboard's \"load more\" click bumps these by 50 entries / 3 pages\n // each time, so without these ceilings users would hit a frustrating wall\n // after a few clicks.\n if (method === \"GET\" && rest[0] === \"registry\" && (rest[1] === undefined || rest[1] === \"list\")) {\n const pagesWanted = clampInt(query.get(\"pages\"), 1, 200, 1);\n const maxPages = clampInt(query.get(\"maxPages\"), 1, 200, 20);\n const limit = clampInt(query.get(\"limit\"), 1, 1000, 30);\n const refreshRaw = query.get(\"refresh\");\n const refresh = refreshRaw === \"1\" || refreshRaw === \"true\";\n const q = (query.get(\"q\") ?? \"\").trim().toLowerCase();\n\n try {\n const handle = await openRegistry({ noCache: refresh });\n const target = q ? maxPages : pagesWanted;\n const additional = Math.max(0, target - handle.cache.pagination.pagesLoaded);\n if (additional > 0) {\n await loadMorePages(handle, {\n pages: additional,\n matchTarget: q ? limit : undefined,\n filter: q\n ? (e) => `${e.name} ${e.title} ${e.description}`.toLowerCase().includes(q)\n : undefined,\n });\n }\n const result = handleToFetchResult(handle);\n const matched = q\n ? result.entries.filter((e) =>\n `${e.name} ${e.title} ${e.description}`.toLowerCase().includes(q),\n )\n : result.entries;\n const ranked = matched.slice().sort((a, b) => {\n const ap = a.popularity ?? -1;\n const bp = b.popularity ?? -1;\n if (ap !== bp) return bp - ap;\n return a.name.localeCompare(b.name);\n });\n return {\n status: 200,\n body: {\n source: result.source,\n fromCache: result.fromCache,\n fetchedAt: result.fetchedAt,\n loaded: result.entries.length,\n hasMore: result.hasMore,\n matched: matched.length,\n entries: ranked.slice(0, limit),\n errors: result.errors,\n },\n };\n } catch (err) {\n return { status: 500, body: { error: (err as Error).message } };\n }\n }\n\n if (method === \"POST\" && rest[0] === \"registry\" && rest[1] === \"install\") {\n const { name, maxPages } = parseBody<InstallBody>(body);\n if (typeof name !== \"string\" || !name.trim()) {\n return { status: 400, body: { error: \"name (string) required\" } };\n }\n const cap = typeof maxPages === \"number\" && maxPages > 0 ? maxPages : 30;\n try {\n const handle = await openRegistry({});\n const target = name.trim();\n const lower = target.toLowerCase();\n const filter = (e: RegistryEntry): boolean => {\n const n = e.name.toLowerCase();\n return n === lower || n.endsWith(`/${lower}`) || n.includes(lower);\n };\n const additional = Math.max(0, cap - handle.cache.pagination.pagesLoaded);\n if (additional > 0) {\n await loadMorePages(handle, { pages: additional, matchTarget: 1, filter });\n }\n const entry = findRegistryEntry(handle.cache.entries, target);\n if (!entry) {\n return {\n status: 404,\n body: {\n error: `no MCP server named \"${target}\" found in ${handle.cache.pagination.pagesLoaded} page(s)`,\n },\n };\n }\n if (!entry.install && entry.source === \"smithery\") {\n const fetched = await fetchSmitheryDetail(entry.name);\n if (fetched) entry.install = fetched;\n }\n if (!entry.install) {\n return {\n status: 422,\n body: {\n error: `Could not derive install metadata for ${entry.name}`,\n hint: `npx -y @smithery/cli install ${entry.name}`,\n },\n };\n }\n const spec = specStringFor(entry.name, entry.install);\n const cfg = readConfig(ctx.configPath);\n const existing = cfg.mcp ?? [];\n if (existing.includes(spec)) {\n return { status: 200, body: { added: false, alreadyPresent: true, spec, entry } };\n }\n cfg.mcp = [...existing, spec];\n writeConfig(cfg, ctx.configPath);\n ctx.audit?.({\n ts: Date.now(),\n action: \"install-mcp-from-registry\",\n payload: { name: entry.name, spec },\n });\n let bridged = false;\n let bridgeError: string | undefined;\n if (ctx.reloadMcp) {\n try {\n await ctx.reloadMcp();\n bridged = true;\n } catch (err) {\n bridgeError = (err as Error).message;\n }\n }\n return {\n status: 200,\n body: {\n added: true,\n requiresRestart: !ctx.reloadMcp || !!bridgeError,\n bridged,\n bridgeError,\n spec,\n entry,\n },\n };\n } catch (err) {\n return { status: 500, body: { error: (err as Error).message } };\n }\n }\n\n if (method === \"POST\" && rest[0] === \"invoke\") {\n if (!ctx.invokeMcpTool) {\n return {\n status: 503,\n body: { error: \"MCP invocation requires an attached session.\" },\n };\n }\n const { server, tool, args } = parseBody<InvokeBody>(body);\n if (typeof server !== \"string\" || typeof tool !== \"string\") {\n return { status: 400, body: { error: \"server + tool (strings) required\" } };\n }\n try {\n const result = await ctx.invokeMcpTool(\n server,\n tool,\n typeof args === \"object\" && args !== null ? (args as Record<string, unknown>) : {},\n );\n return { status: 200, body: { result } };\n } catch (err) {\n return { status: 500, body: { error: (err as Error).message } };\n }\n }\n\n return { status: 405, body: { error: `method ${method} not supported on this path` } };\n}\n","/** Names sanitized via SAFE_NAME on every write — guards against path traversal. */\n\nimport { createHash } from \"node:crypto\";\nimport {\n existsSync,\n mkdirSync,\n readFileSync,\n readdirSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, resolve as resolvePath } from \"node:path\";\nimport { PROJECT_MEMORY_FILE } from \"../../memory/project.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\nfunction projectHash(rootDir: string): string {\n return createHash(\"sha1\").update(resolvePath(rootDir)).digest(\"hex\").slice(0, 16);\n}\n\nfunction globalMemoryDir(): string {\n return join(homedir(), \".reasonix\", \"memory\", \"global\");\n}\n\nfunction projectMemoryDir(rootDir: string): string {\n return join(homedir(), \".reasonix\", \"memory\", projectHash(rootDir));\n}\n\ninterface WriteBody {\n body?: unknown;\n}\n\nfunction parseBody(raw: string): WriteBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as WriteBody) : {};\n } catch {\n return {};\n }\n}\n\nconst SAFE_NAME = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}$/;\n\nfunction listMemoryFiles(dir: string): Array<{ name: string; size: number; mtime: number }> {\n if (!existsSync(dir)) return [];\n try {\n return readdirSync(dir)\n .filter((f) => f.endsWith(\".md\"))\n .map((f) => {\n const stat = statSync(join(dir, f));\n return {\n name: f.replace(/\\.md$/, \"\"),\n size: stat.size,\n mtime: stat.mtime.getTime(),\n };\n })\n .sort((a, b) => b.mtime - a.mtime);\n } catch {\n return [];\n }\n}\n\nexport async function handleMemory(\n method: string,\n rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n const cwd = ctx.getCurrentCwd?.();\n const globalDir = globalMemoryDir();\n const projectMemDir = cwd ? projectMemoryDir(cwd) : \"\";\n\n if (method === \"GET\" && rest.length === 0) {\n const projectMemoryPath = cwd ? join(cwd, PROJECT_MEMORY_FILE) : null;\n const projectMemoryExists = projectMemoryPath ? existsSync(projectMemoryPath) : false;\n return {\n status: 200,\n body: {\n project: {\n path: projectMemoryPath,\n exists: projectMemoryExists,\n file: PROJECT_MEMORY_FILE,\n },\n global: {\n path: globalDir,\n files: listMemoryFiles(globalDir),\n },\n projectMem: {\n path: projectMemDir,\n files: projectMemDir ? listMemoryFiles(projectMemDir) : [],\n },\n },\n };\n }\n\n // /api/memory/<scope>/<name?>\n const [scope, ...nameParts] = rest;\n const name = nameParts.join(\"/\"); // empty for `project` scope which is a single file\n\n if (method === \"GET\") {\n if (scope === \"project\") {\n if (!cwd) return { status: 503, body: { error: \"no active project\" } };\n const path = join(cwd, PROJECT_MEMORY_FILE);\n if (!existsSync(path)) return { status: 404, body: { error: \"REASONIX.md not found\" } };\n return { status: 200, body: { path, body: readFileSync(path, \"utf8\") } };\n }\n if ((scope === \"global\" || scope === \"project-mem\") && name && SAFE_NAME.test(name)) {\n const dir = scope === \"global\" ? globalDir : projectMemDir;\n if (!dir) return { status: 503, body: { error: \"no project root for project-mem\" } };\n const path = join(dir, `${name}.md`);\n if (!existsSync(path)) return { status: 404, body: { error: \"not found\" } };\n return { status: 200, body: { path, body: readFileSync(path, \"utf8\") } };\n }\n return { status: 400, body: { error: \"bad scope or name\" } };\n }\n\n if (method === \"POST\") {\n const { body: contents } = parseBody(body);\n if (typeof contents !== \"string\") {\n return { status: 400, body: { error: \"body (string) required\" } };\n }\n if (scope === \"project\") {\n if (!cwd) return { status: 503, body: { error: \"no active project\" } };\n const path = join(cwd, PROJECT_MEMORY_FILE);\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, contents, \"utf8\");\n ctx.audit?.({ ts: Date.now(), action: \"save-memory\", payload: { scope, path } });\n return { status: 200, body: { saved: true, path } };\n }\n if ((scope === \"global\" || scope === \"project-mem\") && name && SAFE_NAME.test(name)) {\n const dir = scope === \"global\" ? globalDir : projectMemDir;\n if (!dir) return { status: 503, body: { error: \"no project root for project-mem\" } };\n mkdirSync(dir, { recursive: true });\n const path = join(dir, `${name}.md`);\n writeFileSync(path, contents, \"utf8\");\n ctx.audit?.({ ts: Date.now(), action: \"save-memory\", payload: { scope, name, path } });\n return { status: 200, body: { saved: true, path } };\n }\n return { status: 400, body: { error: \"bad scope or name\" } };\n }\n\n if (method === \"DELETE\") {\n if ((scope === \"global\" || scope === \"project-mem\") && name && SAFE_NAME.test(name)) {\n const dir = scope === \"global\" ? globalDir : projectMemDir;\n if (!dir) return { status: 503, body: { error: \"no project root for project-mem\" } };\n const path = join(dir, `${name}.md`);\n if (existsSync(path)) {\n unlinkSync(path);\n ctx.audit?.({ ts: Date.now(), action: \"delete-memory\", payload: { scope, name, path } });\n return { status: 200, body: { deleted: true } };\n }\n return { status: 404, body: { error: \"not found\" } };\n }\n if (scope === \"project\") {\n if (!cwd) return { status: 503, body: { error: \"no active project\" } };\n const path = join(cwd, PROJECT_MEMORY_FILE);\n if (existsSync(path)) {\n unlinkSync(path);\n ctx.audit?.({ ts: Date.now(), action: \"delete-memory\", payload: { scope, path } });\n return { status: 200, body: { deleted: true } };\n }\n return { status: 404, body: { error: \"not found\" } };\n }\n return { status: 400, body: { error: \"bad scope or name\" } };\n }\n\n return { status: 405, body: { error: `method ${method} not supported` } };\n}\n","import type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\nexport async function handleMessages(\n method: string,\n _rest: string[],\n _body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"GET\") {\n return { status: 405, body: { error: \"GET only\" } };\n }\n const messages = ctx.getMessages ? ctx.getMessages() : [];\n return {\n status: 200,\n body: {\n messages,\n busy: ctx.isBusy ? ctx.isBusy() : false,\n },\n };\n}\n","/** GET snapshots the active modal so a fresh client paints what's already up; POST routes resolution into the same handlers the TUI uses. */\n\nimport type { DashboardContext, PickerResolution } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface ResolveBody {\n kind?: unknown;\n choice?: unknown;\n text?: unknown;\n action?: unknown;\n id?: unknown;\n query?: unknown;\n}\n\nfunction parsePickerResolution(body: ResolveBody): PickerResolution | { error: string } {\n const { action, id, text, query } = body;\n if (typeof action !== \"string\") return { error: \"picker action required\" };\n switch (action) {\n case \"pick\":\n case \"delete\":\n case \"install\":\n case \"uninstall\":\n if (typeof id !== \"string\" || !id) return { error: `picker ${action} requires id` };\n return { action, id };\n case \"rename\":\n if (typeof id !== \"string\" || !id) return { error: \"picker rename requires id\" };\n if (typeof text !== \"string\") return { error: \"picker rename requires text\" };\n return { action: \"rename\", id, text };\n case \"new\":\n return typeof text === \"string\" && text ? { action: \"new\", text } : { action: \"new\" };\n case \"load-more\":\n return { action: \"load-more\" };\n case \"refine\":\n if (typeof query !== \"string\") return { error: \"picker refine requires query\" };\n return { action: \"refine\", query };\n case \"cancel\":\n return { action: \"cancel\" };\n default:\n return { error: `unknown picker action: ${action}` };\n }\n}\n\nfunction parseBody(raw: string): ResolveBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as ResolveBody) : {};\n } catch {\n return {};\n }\n}\n\nexport async function handleModal(\n method: string,\n rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method === \"GET\" && rest.length === 0) {\n return {\n status: 200,\n body: { modal: ctx.getActiveModal ? ctx.getActiveModal() : null },\n };\n }\n\n if (method === \"POST\" && rest[0] === \"resolve\") {\n const parsed = parseBody(body);\n const { kind, choice, text } = parsed;\n if (kind === \"shell\") {\n if (!ctx.resolveShellConfirm) {\n return { status: 503, body: { error: \"shell modal resolution not wired\" } };\n }\n if (choice !== \"run_once\" && choice !== \"always_allow\" && choice !== \"deny\") {\n return {\n status: 400,\n body: { error: \"shell choice must be run_once / always_allow / deny\" },\n };\n }\n ctx.resolveShellConfirm(choice);\n return { status: 200, body: { resolved: true } };\n }\n if (kind === \"choice\") {\n if (!ctx.resolveChoiceConfirm) {\n return { status: 503, body: { error: \"choice modal resolution not wired\" } };\n }\n // The wire shape mirrors ChoiceResolution: { kind: \"pick\"|\"custom\"|\"cancel\", ... }.\n const c = choice as Record<string, unknown> | undefined;\n if (!c || typeof c !== \"object\") {\n return { status: 400, body: { error: \"choice must be an object with a kind field\" } };\n }\n if (c.kind === \"pick\" && typeof c.optionId === \"string\") {\n ctx.resolveChoiceConfirm({ kind: \"pick\", optionId: c.optionId });\n return { status: 200, body: { resolved: true } };\n }\n if (c.kind === \"custom\" && typeof c.text === \"string\") {\n ctx.resolveChoiceConfirm({ kind: \"custom\", text: c.text });\n return { status: 200, body: { resolved: true } };\n }\n if (c.kind === \"cancel\") {\n ctx.resolveChoiceConfirm({ kind: \"cancel\" });\n return { status: 200, body: { resolved: true } };\n }\n return { status: 400, body: { error: \"unknown choice resolution shape\" } };\n }\n if (kind === \"plan\") {\n if (!ctx.resolvePlanConfirm) {\n return { status: 503, body: { error: \"plan modal resolution not wired\" } };\n }\n if (choice !== \"approve\" && choice !== \"refine\" && choice !== \"cancel\") {\n return { status: 400, body: { error: \"plan choice must be approve / refine / cancel\" } };\n }\n ctx.resolvePlanConfirm(choice, typeof text === \"string\" && text.trim() ? text : undefined);\n return { status: 200, body: { resolved: true } };\n }\n if (kind === \"edit-review\") {\n if (!ctx.resolveEditReview) {\n return { status: 503, body: { error: \"edit-review modal resolution not wired\" } };\n }\n if (\n choice !== \"apply\" &&\n choice !== \"reject\" &&\n choice !== \"apply-rest-of-turn\" &&\n choice !== \"flip-to-auto\"\n ) {\n return { status: 400, body: { error: \"edit-review choice invalid\" } };\n }\n ctx.resolveEditReview(choice);\n return { status: 200, body: { resolved: true } };\n }\n if (kind === \"checkpoint\") {\n if (!ctx.resolveCheckpointConfirm) {\n return { status: 503, body: { error: \"checkpoint modal resolution not wired\" } };\n }\n if (choice !== \"continue\" && choice !== \"revise\" && choice !== \"stop\") {\n return {\n status: 400,\n body: { error: \"checkpoint choice must be continue / revise / stop\" },\n };\n }\n ctx.resolveCheckpointConfirm(\n choice,\n typeof text === \"string\" && text.trim() ? text : undefined,\n );\n return { status: 200, body: { resolved: true } };\n }\n if (kind === \"revision\") {\n if (!ctx.resolveReviseConfirm) {\n return { status: 503, body: { error: \"revision modal resolution not wired\" } };\n }\n if (choice !== \"accept\" && choice !== \"reject\") {\n return { status: 400, body: { error: \"revision choice must be accept / reject\" } };\n }\n ctx.resolveReviseConfirm(choice);\n return { status: 200, body: { resolved: true } };\n }\n if (kind === \"picker\") {\n if (!ctx.resolvePicker) {\n return { status: 503, body: { error: \"picker modal resolution not wired\" } };\n }\n const resolution = parsePickerResolution(parsed);\n if (\"error\" in resolution) {\n return { status: 400, body: { error: resolution.error } };\n }\n ctx.resolvePicker(resolution);\n return { status: 200, body: { resolved: true } };\n }\n if (kind === \"viewer\") {\n if (!ctx.resolveViewer) {\n return { status: 503, body: { error: \"viewer modal resolution not wired\" } };\n }\n if (parsed.action !== \"close\") {\n return { status: 400, body: { error: \"viewer action must be close\" } };\n }\n ctx.resolveViewer({ action: \"close\" });\n return { status: 200, body: { resolved: true } };\n }\n return { status: 400, body: { error: `unknown modal kind: ${String(kind)}` } };\n }\n\n return { status: 405, body: { error: `method ${method} not supported on this path` } };\n}\n","import { DEEPSEEK_PRICING } from \"../../telemetry/stats.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\nexport async function handleModels(\n method: string,\n _rest: string[],\n _body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"GET\") return { status: 405, body: { error: \"GET only\" } };\n const models = ctx.getModels?.() ?? null;\n return {\n status: 200,\n body: {\n models,\n current: ctx.loop?.model ?? null,\n /** USD per 1M tokens — same table the cost gauge uses. */\n pricing: DEEPSEEK_PRICING,\n },\n };\n}\n","import { existsSync } from \"node:fs\";\nimport { readEventLogFile, recentEventFiles } from \"../../adapters/event-source-jsonl.js\";\nimport type { Event } from \"../../core/events.js\";\nimport { sessionsDir as defaultSessionsDir } from \"../../memory/session.js\";\n\nexport interface CockpitToolCallsKpi {\n total: number;\n delta: number | null;\n}\n\nexport interface CockpitRecentPlan {\n id: string;\n title: string;\n totalSteps: number;\n completedSteps: number;\n status: \"active\" | \"done\";\n whenMs: number;\n}\n\nexport interface CockpitToolFeedRow {\n name: string;\n args: string;\n level: \"ok\" | \"warn\" | \"err\";\n whenMs: number;\n}\n\nexport interface EventsCockpit {\n toolCalls24h: CockpitToolCallsKpi | null;\n recentPlans: ReadonlyArray<CockpitRecentPlan> | null;\n toolActivity: ReadonlyArray<CockpitToolFeedRow> | null;\n}\n\nconst DAY_MS = 86_400_000;\nconst RECENT_FILES_CAP = 8;\nconst PLAN_FEED_CAP = 4;\nconst TOOL_FEED_CAP = 6;\n\nexport function computeEventsCockpit(\n now: number = Date.now(),\n sessionsDirOverride?: string,\n): EventsCockpit {\n const dir = sessionsDirOverride ?? defaultSessionsDir();\n if (!existsSync(dir)) {\n return { toolCalls24h: null, recentPlans: null, toolActivity: null };\n }\n const files = recentEventFiles(dir, now, RECENT_FILES_CAP);\n if (files.length === 0) {\n return { toolCalls24h: null, recentPlans: null, toolActivity: null };\n }\n\n let calls24h = 0;\n let callsPrior24h = 0;\n const cutoff24h = now - DAY_MS;\n const cutoff48h = now - 2 * DAY_MS;\n const allTools: CockpitToolFeedRow[] = [];\n const allPlans: CockpitRecentPlan[] = [];\n\n for (const file of files) {\n const events = readEventLogFile(file);\n if (events.length === 0) continue;\n countToolCalls(events, cutoff24h, cutoff48h, (in24h) => {\n if (in24h) calls24h++;\n else callsPrior24h++;\n });\n collectToolActivity(events, allTools);\n collectPlans(events, allPlans);\n }\n\n allTools.sort((a, b) => b.whenMs - a.whenMs);\n allPlans.sort((a, b) => b.whenMs - a.whenMs);\n\n return {\n toolCalls24h: { total: calls24h, delta: calls24h - callsPrior24h },\n recentPlans: allPlans.slice(0, PLAN_FEED_CAP),\n toolActivity: allTools.slice(0, TOOL_FEED_CAP),\n };\n}\n\nfunction countToolCalls(\n events: ReadonlyArray<Event>,\n cutoff24h: number,\n cutoff48h: number,\n onCall: (in24h: boolean) => void,\n): void {\n for (const ev of events) {\n if (ev.type !== \"tool.intent\") continue;\n const ts = parseTs(ev.ts);\n if (ts === null) continue;\n if (ts >= cutoff24h) onCall(true);\n else if (ts >= cutoff48h) onCall(false);\n }\n}\n\nfunction collectToolActivity(events: ReadonlyArray<Event>, into: CockpitToolFeedRow[]): void {\n const intentByCallId = new Map<string, { name: string; args: string; ts: number }>();\n for (const ev of events) {\n if (ev.type === \"tool.intent\") {\n const ts = parseTs(ev.ts);\n if (ts !== null) intentByCallId.set(ev.callId, { name: ev.name, args: ev.args, ts });\n } else if (ev.type === \"tool.result\") {\n const intent = intentByCallId.get(ev.callId);\n if (!intent) continue;\n into.push({\n name: intent.name,\n args: summarizeArgs(intent.args),\n level: ev.ok ? \"ok\" : \"err\",\n whenMs: intent.ts,\n });\n } else if (ev.type === \"tool.denied\") {\n const intent = intentByCallId.get(ev.callId);\n if (!intent) continue;\n into.push({\n name: intent.name,\n args: summarizeArgs(intent.args),\n level: \"warn\",\n whenMs: intent.ts,\n });\n }\n }\n}\n\nfunction collectPlans(events: ReadonlyArray<Event>, into: CockpitRecentPlan[]): void {\n let current: { id: string; title: string; totalSteps: number; whenMs: number } | null = null;\n let completed = new Set<string>();\n for (const ev of events) {\n if (ev.type === \"plan.submitted\") {\n if (current) {\n into.push(buildPlan(current, completed));\n }\n const ts = parseTs(ev.ts);\n if (ts === null) {\n current = null;\n continue;\n }\n current = {\n id: `${ev.id}`,\n title: planTitle(ev.body, ev.steps),\n totalSteps: ev.steps.length,\n whenMs: ts,\n };\n completed = new Set();\n } else if (ev.type === \"plan.step.completed\") {\n if (!current) continue;\n completed.add(ev.stepId);\n }\n }\n if (current) into.push(buildPlan(current, completed));\n}\n\nfunction buildPlan(\n current: { id: string; title: string; totalSteps: number; whenMs: number },\n completed: Set<string>,\n): CockpitRecentPlan {\n return {\n id: current.id,\n title: current.title,\n totalSteps: current.totalSteps,\n completedSteps: completed.size,\n status: completed.size >= current.totalSteps && current.totalSteps > 0 ? \"done\" : \"active\",\n whenMs: current.whenMs,\n };\n}\n\nfunction planTitle(body: string, steps: ReadonlyArray<{ title: string }>): string {\n const firstBodyLine = body.split(/\\r?\\n/).find((l) => l.trim().length > 0);\n if (firstBodyLine)\n return firstBodyLine\n .replace(/^#+\\s*/, \"\")\n .trim()\n .slice(0, 80);\n if (steps.length > 0 && steps[0]) return steps[0].title.slice(0, 80);\n return \"(plan)\";\n}\n\nfunction summarizeArgs(args: string): string {\n if (!args) return \"\";\n let parsed: unknown;\n try {\n parsed = JSON.parse(args);\n } catch {\n return args.slice(0, 60);\n }\n if (parsed && typeof parsed === \"object\") {\n const obj = parsed as Record<string, unknown>;\n const path = obj.path ?? obj.file_path ?? obj.filename;\n const command = obj.command;\n if (typeof command === \"string\")\n return command.length > 60 ? `${command.slice(0, 60)}…` : command;\n if (typeof path === \"string\") return path;\n }\n return args.slice(0, 60);\n}\n\nfunction parseTs(ts: string): number | null {\n const n = Date.parse(ts);\n return Number.isFinite(n) ? n : null;\n}\n","import { aggregateUsage, bucketCacheHitRatio, readUsageLog } from \"../../telemetry/usage.js\";\nimport type { DashboardContext, DashboardStats } from \"../context.js\";\nimport { type EventsCockpit, computeEventsCockpit } from \"./cockpit-events.js\";\n\nexport type {\n CockpitRecentPlan,\n CockpitToolCallsKpi,\n CockpitToolFeedRow,\n} from \"./cockpit-events.js\";\n\nexport interface CockpitKpi {\n total: number;\n deltaPct: number | null;\n}\n\nexport interface CockpitCacheKpi {\n ratio: number;\n deltaPp: number | null;\n}\n\nexport interface CockpitDailyCost {\n date: string;\n usd: number;\n}\n\nexport interface CockpitCurrentSession {\n id: string;\n turns: number;\n totalCostUsd: number;\n lastPromptTokens: number;\n completionTokens: number;\n}\n\nexport interface CockpitData extends EventsCockpit {\n balance: { currency: string; total: string } | null;\n tokens7d: CockpitKpi | null;\n cacheHit7d: CockpitCacheKpi | null;\n costTrend14d: ReadonlyArray<CockpitDailyCost> | null;\n currentSession: CockpitCurrentSession | null;\n}\n\ntype WarmFields = Pick<\n CockpitData,\n \"tokens7d\" | \"cacheHit7d\" | \"costTrend14d\" | \"toolCalls24h\" | \"recentPlans\" | \"toolActivity\"\n>;\n\nconst TTL_MS = 30_000;\n\ninterface CacheEntry {\n ts: number;\n data: WarmFields;\n}\n\nconst cache = new Map<string, CacheEntry>();\n\nexport function _resetCockpitCacheForTests(): void {\n cache.clear();\n}\n\nexport function computeCockpit(ctx: DashboardContext, now: number = Date.now()): CockpitData {\n return {\n balance: extractBalance(ctx.getStats?.() ?? null),\n currentSession: extractCurrentSession(ctx),\n ...readWarmCached(ctx.usageLogPath, now, ctx.sessionsDir),\n };\n}\n\nfunction extractBalance(stats: DashboardStats | null): CockpitData[\"balance\"] {\n const first = stats?.balance?.[0];\n if (!first) return null;\n return { currency: first.currency, total: first.total_balance };\n}\n\nfunction extractCurrentSession(ctx: DashboardContext): CockpitData[\"currentSession\"] {\n const id = ctx.getSessionName?.() ?? null;\n const stats = ctx.getStats?.() ?? null;\n const loop = ctx.loop;\n if (!id || !stats || !loop) return null;\n let completion = 0;\n for (const t of loop.stats.turns) completion += t.usage.completionTokens;\n return {\n id,\n turns: stats.turns,\n totalCostUsd: stats.totalCostUsd,\n lastPromptTokens: stats.lastPromptTokens,\n completionTokens: completion,\n };\n}\n\nfunction readWarmCached(usageLogPath: string, now: number, sessionsDir?: string): WarmFields {\n const cacheKey = `${usageLogPath}::${sessionsDir ?? \"\"}`;\n const hit = cache.get(cacheKey);\n if (hit && now - hit.ts < TTL_MS) return hit.data;\n const data = computeWarm(usageLogPath, now, sessionsDir);\n cache.set(cacheKey, { ts: now, data });\n return data;\n}\n\nexport function computeWarm(usageLogPath: string, now: number, sessionsDir?: string): WarmFields {\n const events = computeEventsCockpit(now, sessionsDir);\n const records = readUsageLog(usageLogPath);\n if (records.length === 0) {\n return { tokens7d: null, cacheHit7d: null, costTrend14d: null, ...events };\n }\n const week = aggregateUsage(records, { now }).buckets[1]!;\n const priorWeekRecords = records.filter(\n (r) => r.ts < week.since && r.ts >= week.since - 7 * 86_400_000,\n );\n const priorWeek = aggregateUsage(priorWeekRecords, { now: week.since }).buckets[1]!;\n\n const tokens7dTotal = week.promptTokens + week.completionTokens;\n const tokens7dPrior = priorWeek.promptTokens + priorWeek.completionTokens;\n const tokens7d: CockpitKpi = {\n total: tokens7dTotal,\n deltaPct: tokens7dPrior > 0 ? ((tokens7dTotal - tokens7dPrior) / tokens7dPrior) * 100 : null,\n };\n\n const cacheHitRatio = bucketCacheHitRatio(week);\n const cacheHit7d: CockpitCacheKpi = {\n ratio: cacheHitRatio,\n deltaPp:\n priorWeek.cacheHitTokens + priorWeek.cacheMissTokens > 0\n ? (cacheHitRatio - bucketCacheHitRatio(priorWeek)) * 100\n : null,\n };\n\n return {\n tokens7d,\n cacheHit7d,\n costTrend14d: rollupDailyCost(records, now, 14),\n ...events,\n };\n}\n\nfunction rollupDailyCost(\n records: ReadonlyArray<{ ts: number; costUsd: number }>,\n now: number,\n days: number,\n): CockpitDailyCost[] {\n const since = now - days * 86_400_000;\n const buckets = new Map<string, number>();\n for (let i = 0; i < days; i++) {\n buckets.set(localDateKey(now - i * 86_400_000), 0);\n }\n for (const r of records) {\n if (r.ts < since) continue;\n const key = localDateKey(r.ts);\n if (!buckets.has(key)) continue;\n buckets.set(key, (buckets.get(key) ?? 0) + r.costUsd);\n }\n return Array.from(buckets.entries())\n .map(([date, usd]) => ({ date, usd }))\n .sort((a, b) => (a.date < b.date ? -1 : 1));\n}\n\nfunction localDateKey(ts: number): string {\n const d = new Date(ts);\n const y = d.getFullYear();\n const m = String(d.getMonth() + 1).padStart(2, \"0\");\n const day = String(d.getDate()).padStart(2, \"0\");\n return `${y}-${m}-${day}`;\n}\n","/** Bundled GET — avoids 6 round-trips per 2s poll; runtime fields null in standalone mode. */\n\nimport { readConfig } from \"../../config.js\";\nimport { indexExists } from \"../../index/semantic/builder.js\";\nimport { VERSION } from \"../../version.js\";\nimport type { DashboardContext, DashboardStats } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\nimport { type CockpitData, computeCockpit } from \"./cockpit.js\";\n\nexport interface OverviewResponse {\n /** Reasonix version string (drives the \"vs latest\" comparison in the SPA). */\n version: string;\n /** Current runtime mode — drives whether the SPA hides \"live-only\" controls. */\n mode: \"standalone\" | \"attached\";\n /** Latest published version, or null when the background fetch hasn't resolved. */\n latestVersion: string | null;\n session: string | null;\n cwd: string | null;\n model: string | null;\n editMode: string | null;\n planMode: boolean | null;\n pendingEdits: number | null;\n /** When attached, count of MCP servers currently bridged. */\n mcpServerCount: number | null;\n /** Total registered tools (builtin + MCP-bridged + skill tools). */\n toolCount: number | null;\n preset: string;\n /** Persisted reasoning_effort (high / max). Same rationale as preset. */\n reasoningEffort: string;\n /** Session USD spend cap; null when off. Drives the chat side-rail's Tool budget card. */\n budgetUsd: number | null;\n /** Live session stats — null in standalone mode. */\n stats: DashboardStats | null;\n semanticIndexExists: boolean | null;\n cockpit: CockpitData;\n}\n\nexport async function handleOverview(\n method: string,\n _rest: string[],\n _body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"GET\") {\n return { status: 405, body: { error: \"GET only\" } };\n }\n const cfg = readConfig(ctx.configPath);\n const cwd = ctx.getCurrentCwd?.() ?? null;\n const semanticIndexExists = cwd ? await indexExists(cwd).catch(() => false) : null;\n const overview: OverviewResponse = {\n version: VERSION,\n mode: ctx.mode,\n latestVersion: ctx.getLatestVersion?.() ?? null,\n session: ctx.getSessionName?.() ?? null,\n cwd,\n model: ctx.loop?.model ?? null,\n editMode: ctx.getEditMode?.() ?? null,\n planMode: ctx.getPlanMode?.() ?? null,\n pendingEdits: ctx.getPendingEditCount?.() ?? null,\n mcpServerCount: ctx.mcpServers?.length ?? null,\n toolCount: ctx.tools ? ctx.tools.size : null,\n preset: cfg.preset ?? \"auto\",\n reasoningEffort: cfg.reasoningEffort ?? \"max\",\n budgetUsd: ctx.loop?.budgetUsd ?? null,\n stats: ctx.getStats?.() ?? null,\n semanticIndexExists,\n cockpit: computeCockpit(ctx),\n };\n return { status: 200, body: overview };\n}\n","/** Mutations require an attached session — standalone mode returns 503 because we have no project root to scope under. */\n\nimport {\n addProjectShellAllowed,\n clearProjectShellAllowed,\n loadProjectShellAllowed,\n removeProjectShellAllowed,\n} from \"../../config.js\";\nimport { BUILTIN_ALLOWLIST } from \"../../tools/shell.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface MutationBody {\n prefix?: unknown;\n confirm?: unknown;\n}\n\nfunction parseBody(raw: string): MutationBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as MutationBody) : {};\n } catch {\n return {};\n }\n}\n\nexport async function handlePermissions(\n method: string,\n rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n // GET — listing works regardless of mode (builtin always shown,\n // project list optional).\n if (method === \"GET\" && rest.length === 0) {\n const cwd = ctx.getCurrentCwd?.();\n return {\n status: 200,\n body: {\n currentCwd: cwd ?? null,\n editMode: ctx.getEditMode?.() ?? null,\n builtin: [...BUILTIN_ALLOWLIST],\n project: cwd ? loadProjectShellAllowed(cwd, ctx.configPath) : [],\n },\n };\n }\n\n // Mutations require a current project root.\n const cwd = ctx.getCurrentCwd?.();\n if (!cwd) {\n return {\n status: 503,\n body: {\n error:\n \"no active project — mutations require an attached dashboard session (run `/dashboard` from inside `reasonix code`).\",\n },\n };\n }\n\n if (method === \"POST\" && rest.length === 0) {\n const { prefix } = parseBody(body);\n if (typeof prefix !== \"string\" || !prefix.trim()) {\n return { status: 400, body: { error: \"prefix (string) required\" } };\n }\n const trimmed = prefix.trim();\n if (BUILTIN_ALLOWLIST.includes(trimmed)) {\n return {\n status: 409,\n body: {\n error: `\\`${trimmed}\\` is already in the builtin allowlist — no project entry needed.`,\n },\n };\n }\n const before = loadProjectShellAllowed(cwd, ctx.configPath);\n if (before.includes(trimmed)) {\n return { status: 200, body: { added: false, prefix: trimmed, alreadyPresent: true } };\n }\n addProjectShellAllowed(cwd, trimmed, ctx.configPath);\n ctx.audit?.({\n ts: Date.now(),\n action: \"add-allowlist\",\n payload: { prefix: trimmed, project: cwd },\n });\n return { status: 200, body: { added: true, prefix: trimmed } };\n }\n\n if (method === \"DELETE\" && rest.length === 0) {\n const { prefix } = parseBody(body);\n if (typeof prefix !== \"string\" || !prefix.trim()) {\n return { status: 400, body: { error: \"prefix (string) required\" } };\n }\n const trimmed = prefix.trim();\n if (BUILTIN_ALLOWLIST.includes(trimmed)) {\n return {\n status: 409,\n body: {\n error: `\\`${trimmed}\\` is in the builtin allowlist (read-only); builtin entries can't be removed at runtime.`,\n },\n };\n }\n const removed = removeProjectShellAllowed(cwd, trimmed, ctx.configPath);\n if (removed) {\n ctx.audit?.({\n ts: Date.now(),\n action: \"remove-allowlist\",\n payload: { prefix: trimmed, project: cwd },\n });\n }\n return { status: 200, body: { removed, prefix: trimmed } };\n }\n\n if (method === \"POST\" && rest[0] === \"clear\") {\n const { confirm } = parseBody(body);\n if (confirm !== true) {\n return {\n status: 400,\n body: {\n error: \"clear requires { confirm: true } in the body — guards against accidental wipe.\",\n },\n };\n }\n const dropped = clearProjectShellAllowed(cwd, ctx.configPath);\n if (dropped > 0) {\n ctx.audit?.({\n ts: Date.now(),\n action: \"clear-allowlist\",\n payload: { dropped, project: cwd },\n });\n }\n return { status: 200, body: { dropped } };\n }\n\n return { status: 405, body: { error: `method ${method} not supported on this path` } };\n}\n","import { listPlanArchives } from \"../../code/plan-store.js\";\nimport { listSessions } from \"../../memory/session.js\";\nimport type { PlanStep } from \"../../tools/plan.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface PlanRow {\n session: string;\n path: string;\n completedAt: string;\n totalSteps: number;\n completedSteps: number;\n /** Computed completion ratio 0..1, surfaced so the SPA doesn't redo the math. */\n completionRatio: number;\n /** Plan summary (if the archive carried one). */\n summary?: string;\n /** Steps + completion ids — consumers render the step list inline. */\n steps: PlanStep[];\n completedStepIds: string[];\n}\n\nexport async function handlePlans(\n method: string,\n _rest: string[],\n _body: string,\n _ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"GET\") {\n return { status: 405, body: { error: \"GET only\" } };\n }\n const out: PlanRow[] = [];\n for (const session of listSessions()) {\n const archives = listPlanArchives(session.name);\n for (const a of archives) {\n const total = a.steps.length;\n const done = a.completedStepIds.length;\n const row: PlanRow = {\n session: session.name,\n path: a.path,\n completedAt: a.completedAt,\n totalSteps: total,\n completedSteps: done,\n completionRatio: total > 0 ? done / total : 0,\n steps: a.steps,\n completedStepIds: a.completedStepIds,\n };\n if (a.summary) row.summary = a.summary;\n out.push(row);\n }\n }\n // Newest archive first across the whole pool.\n out.sort((a, b) => b.completedAt.localeCompare(a.completedAt));\n return { status: 200, body: { plans: out } };\n}\n","/** Job state in a module-scoped Map keyed by project root so multi-root dashboards don't collide; CLI `reasonix index` runs independently. */\n\nimport { closeSync, fstatSync, openSync, readSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n type EmbeddingProvider,\n type SemanticEmbeddingUserConfig,\n loadIndexConfig,\n loadSemanticEmbeddingUserConfig,\n readConfig,\n redactSemanticEmbeddingConfig,\n resolveSemanticEmbeddingConfig,\n saveSemanticEmbeddingConfig,\n} from \"../../config.js\";\nimport {\n INDEX_DIR_NAME,\n buildIndex,\n indexCompatible,\n indexExists,\n querySemantic,\n} from \"../../index/semantic/builder.js\";\nimport type { BuildProgress, BuildResult } from \"../../index/semantic/builder.js\";\nimport {\n checkOllamaStatus,\n pullOllamaModel,\n startOllamaDaemon,\n} from \"../../index/semantic/ollama-launcher.js\";\nimport {\n compareIndexIdentity,\n readIndexMeta as readStoreIndexMeta,\n} from \"../../index/semantic/store.js\";\nimport { registerSemanticSearchTool } from \"../../index/semantic/tool.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface JobRecord {\n startedAt: number;\n finishedAt?: number;\n cancelledAt?: number;\n phase: BuildProgress[\"phase\"] | \"error\" | \"cancelled\";\n lastPhase?: BuildProgress[\"phase\"];\n filesScanned?: number;\n filesChanged?: number;\n filesSkipped?: number;\n chunksTotal?: number;\n chunksDone?: number;\n result?: BuildResult;\n error?: string;\n rebuild: boolean;\n aborted: boolean;\n controller: AbortController;\n}\n\nconst JOBS = new Map<string, JobRecord>();\n\ninterface PullRecord {\n startedAt: number;\n status: \"pulling\" | \"done\" | \"error\";\n lastLine: string;\n exitCode: number | null;\n}\nconst PULLS = new Map<string, PullRecord>();\n\nfunction getRoot(ctx: DashboardContext): string | null {\n const cwd = ctx.getCurrentCwd?.();\n return cwd ?? null;\n}\n\nexport async function handleSemantic(\n method: string,\n rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n const sub = rest[0] ?? \"\";\n\n if (sub === \"\" && method === \"GET\") return await getStatus(ctx);\n if (sub === \"config\" && method === \"GET\") return getSemanticConfig(ctx);\n if (sub === \"config\" && method === \"POST\") return saveSemanticConfigApi(body, ctx);\n if (sub === \"start\" && method === \"POST\") return await startJob(body, ctx);\n if (sub === \"stop\" && method === \"POST\") return await stopJob(ctx);\n if (sub === \"ollama\" && method === \"POST\") {\n const action = rest[1] ?? \"\";\n if (action === \"start\") return await startDaemon(ctx);\n if (action === \"pull\") return await startPull(body, ctx);\n }\n if (sub === \"search\" && method === \"POST\") return await runSearch(body, ctx);\n return { status: 404, body: { error: \"no such semantic endpoint\" } };\n}\n\nasync function runSearch(rawBody: string, ctx: DashboardContext): Promise<ApiResult> {\n const root = getRoot(ctx);\n if (!root) {\n return { status: 503, body: { error: \"search requires an attached code-mode session\" } };\n }\n let parsed: { query?: unknown; topK?: unknown; minScore?: unknown };\n try {\n parsed = JSON.parse(rawBody || \"{}\");\n } catch {\n return { status: 400, body: { error: \"body must be JSON\" } };\n }\n const query = typeof parsed.query === \"string\" ? parsed.query.trim() : \"\";\n if (!query) return { status: 400, body: { error: \"query required\" } };\n const topK =\n typeof parsed.topK === \"number\" && Number.isFinite(parsed.topK)\n ? Math.max(1, Math.min(16, Math.floor(parsed.topK)))\n : 8;\n const minScore =\n typeof parsed.minScore === \"number\" && Number.isFinite(parsed.minScore)\n ? Math.max(0, Math.min(1, parsed.minScore))\n : 0.3;\n const startedAt = Date.now();\n const embedding = resolveSemanticEmbeddingConfig(ctx.configPath);\n try {\n const hits = await querySemantic(root, query, {\n topK,\n minScore,\n configPath: ctx.configPath,\n });\n if (hits === null) {\n return { status: 404, body: { error: \"no semantic index for this project\" } };\n }\n return {\n status: 200,\n body: {\n hits: hits.map((h) => ({\n path: h.entry.path,\n startLine: h.entry.startLine,\n endLine: h.entry.endLine,\n score: h.score,\n snippet: h.entry.text,\n })),\n elapsedMs: Date.now() - startedAt,\n provider: embedding.provider,\n model: embedding.model,\n },\n };\n } catch (err) {\n return { status: 500, body: { error: (err as Error).message } };\n }\n}\n\nasync function getStatus(ctx: DashboardContext): Promise<ApiResult> {\n const root = getRoot(ctx);\n if (!root) {\n return {\n status: 200,\n body: {\n attached: false,\n reason:\n \"Semantic indexing requires a code-mode session — run `/dashboard` from inside `reasonix code` instead of standalone `reasonix dashboard`.\",\n },\n };\n }\n const config = loadSemanticEmbeddingUserConfig(ctx.configPath);\n const configView = redactSemanticEmbeddingConfig(config);\n const resolved = resolveSemanticEmbeddingConfig(ctx.configPath);\n const [hasIndex, providerStatus, index] = await Promise.all([\n indexExists(root),\n getProviderStatusFromConfig(configView),\n readIndexMeta(root, { provider: resolved.provider, model: resolved.model }),\n ]);\n const job = JOBS.get(root) ?? null;\n const pull =\n providerStatus.kind === \"ollama\" ? (PULLS.get(providerStatus.modelName) ?? null) : null;\n return {\n status: 200,\n body: {\n attached: true,\n root,\n provider: configView.provider,\n providerConfig: configView,\n providerStatus,\n index: hasIndex ? index : { exists: false },\n ollama: providerStatus.kind === \"ollama\" ? providerStatus : undefined,\n job: job ? snapshotJob(job) : null,\n pull: pull ? snapshotPull(pull) : null,\n },\n };\n}\n\ninterface IndexMetaResponse {\n exists: true;\n provider: EmbeddingProvider;\n chunks: number;\n files: number;\n dim: number;\n sizeBytes: number;\n lastBuiltMs: number;\n model: string;\n builtWith: { provider: EmbeddingProvider; model: string };\n current: { provider: EmbeddingProvider; model: string };\n compatible: boolean;\n mismatch: \"provider\" | \"model\" | null;\n}\n\nasync function readIndexMeta(\n root: string,\n current: { provider: EmbeddingProvider; model: string },\n): Promise<IndexMetaResponse | { exists: false }> {\n const dir = join(root, INDEX_DIR_NAME);\n const dataPath = join(dir, \"index.jsonl\");\n const diskMeta = await readStoreIndexMeta(dir);\n if (!diskMeta) return { exists: false };\n let chunks = 0;\n const files = new Set<string>();\n let sizeBytes = 0;\n try {\n const fd = openSync(dataPath, \"r\");\n let raw: string;\n try {\n const stat = fstatSync(fd);\n sizeBytes = stat.size;\n const buf = Buffer.alloc(stat.size);\n let read = 0;\n while (read < stat.size) {\n const n = readSync(fd, buf, read, stat.size - read, read);\n if (n <= 0) break;\n read += n;\n }\n raw = buf.toString(\"utf8\", 0, read);\n } finally {\n closeSync(fd);\n }\n for (const line of raw.split(/\\r?\\n/)) {\n if (!line.trim()) continue;\n chunks++;\n try {\n const rec = JSON.parse(line) as { p?: string };\n if (typeof rec.p === \"string\") files.add(rec.p);\n } catch {\n /* skip malformed */\n }\n }\n } catch {\n /* partial counts allowed */\n }\n const mismatch = compareIndexIdentity(diskMeta, current);\n return {\n exists: true,\n provider: diskMeta.provider,\n chunks,\n files: files.size,\n dim: diskMeta.dim ?? 0,\n sizeBytes,\n lastBuiltMs: diskMeta.updatedAt ? Date.parse(diskMeta.updatedAt) || 0 : 0,\n model: diskMeta.model ?? \"\",\n builtWith: { provider: diskMeta.provider, model: diskMeta.model },\n current,\n compatible: mismatch === null,\n mismatch,\n };\n}\n\nfunction snapshotPull(p: PullRecord): unknown {\n return {\n startedAt: p.startedAt,\n status: p.status,\n lastLine: p.lastLine,\n exitCode: p.exitCode,\n };\n}\n\nasync function startDaemon(ctx: DashboardContext): Promise<ApiResult> {\n const resolved = resolveSemanticEmbeddingConfig(ctx.configPath);\n if (resolved.provider !== \"ollama\") {\n return { status: 409, body: { error: \"ollama actions require provider=ollama\" } };\n }\n const r = await startOllamaDaemon({ baseUrl: resolved.baseUrl, timeoutMs: 15_000 }).catch(\n (err: Error) => ({\n ready: false,\n pid: null,\n error: err.message,\n }),\n );\n if (\"error\" in r) return { status: 500, body: { ready: false, error: r.error } };\n return { status: r.ready ? 200 : 504, body: r };\n}\n\ninterface PullBody {\n model?: unknown;\n}\n\nasync function startPull(body: string, ctx: DashboardContext): Promise<ApiResult> {\n const resolved = resolveSemanticEmbeddingConfig(ctx.configPath);\n if (resolved.provider !== \"ollama\") {\n return { status: 409, body: { error: \"ollama actions require provider=ollama\" } };\n }\n let parsed: PullBody = {};\n if (body) {\n try {\n parsed = JSON.parse(body) as PullBody;\n } catch {\n return { status: 400, body: { error: \"invalid JSON body\" } };\n }\n }\n const model = typeof parsed.model === \"string\" && parsed.model ? parsed.model : resolved.model;\n const existing = PULLS.get(model);\n if (existing && existing.status === \"pulling\") {\n return {\n status: 409,\n body: { error: `${model} is already pulling`, pull: snapshotPull(existing) },\n };\n }\n const rec: PullRecord = {\n startedAt: Date.now(),\n status: \"pulling\",\n lastLine: `pulling ${model}…`,\n exitCode: null,\n };\n PULLS.set(model, rec);\n void pullOllamaModel(model, {\n onLine: (line) => {\n if (line.trim().length > 0) rec.lastLine = line.trim();\n },\n })\n .then((code) => {\n rec.exitCode = code;\n rec.status = code === 0 ? \"done\" : \"error\";\n if (code !== 0 && (!rec.lastLine || !rec.lastLine.toLowerCase().includes(\"error\"))) {\n rec.lastLine = `ollama pull exited with code ${code}`;\n }\n })\n .catch((err: Error) => {\n rec.status = \"error\";\n rec.lastLine = err.message;\n });\n return { status: 202, body: { started: true, pull: snapshotPull(rec) } };\n}\n\nfunction snapshotJob(j: JobRecord): unknown {\n return {\n startedAt: j.startedAt,\n finishedAt: j.finishedAt ?? null,\n cancelledAt: j.cancelledAt ?? null,\n phase: j.phase,\n lastPhase: j.lastPhase ?? null,\n rebuild: j.rebuild,\n filesScanned: j.filesScanned ?? null,\n filesChanged: j.filesChanged ?? null,\n filesSkipped: j.filesSkipped ?? null,\n chunksTotal: j.chunksTotal ?? null,\n chunksDone: j.chunksDone ?? null,\n aborted: j.aborted,\n result: j.result ?? null,\n error: j.error ?? null,\n };\n}\n\ninterface StartBody {\n rebuild?: unknown;\n}\n\nasync function startJob(body: string, ctx: DashboardContext): Promise<ApiResult> {\n const root = getRoot(ctx);\n if (!root) {\n return {\n status: 400,\n body: { error: \"no project root — only available in attached (code-mode) dashboards\" },\n };\n }\n const existing = JOBS.get(root);\n if (\n existing &&\n (existing.phase === \"setup\" ||\n existing.phase === \"scan\" ||\n existing.phase === \"embed\" ||\n existing.phase === \"write\")\n ) {\n return {\n status: 409,\n body: { error: \"an indexing job is already running\", job: snapshotJob(existing) },\n };\n }\n\n let parsed: StartBody = {};\n if (body) {\n try {\n parsed = JSON.parse(body) as StartBody;\n } catch {\n return { status: 400, body: { error: \"invalid JSON body\" } };\n }\n }\n const rebuild = parsed.rebuild === true;\n\n const job: JobRecord = {\n startedAt: Date.now(),\n phase: \"setup\",\n lastPhase: \"setup\",\n rebuild,\n aborted: false,\n controller: new AbortController(),\n };\n JOBS.set(root, job);\n\n void runIndex(root, job, ctx).catch((err) => {\n job.phase = \"error\";\n job.finishedAt = Date.now();\n job.error = err instanceof Error ? err.message : String(err);\n });\n\n const resolved = resolveSemanticEmbeddingConfig(ctx.configPath);\n return {\n status: 202,\n body: {\n started: true,\n provider: resolved.provider,\n model: resolved.model,\n job: snapshotJob(job),\n },\n };\n}\n\nasync function runIndex(root: string, job: JobRecord, ctx: DashboardContext): Promise<void> {\n try {\n const resolved = resolveSemanticEmbeddingConfig(ctx.configPath);\n const result = await buildIndex(root, {\n rebuild: job.rebuild,\n configPath: ctx.configPath,\n signal: job.controller.signal,\n indexConfig: loadIndexConfig(ctx.configPath),\n onProgress: (p) => {\n job.phase = p.phase;\n if (p.phase !== \"done\") job.lastPhase = p.phase;\n if (p.filesScanned !== undefined) job.filesScanned = p.filesScanned;\n if (p.filesChanged !== undefined) job.filesChanged = p.filesChanged;\n if (p.filesSkipped !== undefined) job.filesSkipped = p.filesSkipped;\n if (p.chunksTotal !== undefined) job.chunksTotal = p.chunksTotal;\n if (p.chunksDone !== undefined) job.chunksDone = p.chunksDone;\n },\n });\n job.phase = \"done\";\n job.finishedAt = Date.now();\n job.result = result;\n if (ctx.tools && ctx.addToolToPrefix) {\n try {\n const added = await registerSemanticSearchTool(ctx.tools, { root, ...resolved });\n if (added) {\n const spec = ctx.tools.specs().find((s) => s.function.name === \"semantic_search\");\n if (spec) ctx.addToolToPrefix(spec);\n }\n } catch {\n /* non-fatal */\n }\n }\n } catch (err) {\n if (isAbortError(err)) {\n job.phase = \"cancelled\";\n job.cancelledAt = Date.now();\n job.finishedAt = job.cancelledAt;\n job.error = undefined;\n return;\n }\n job.phase = \"error\";\n job.finishedAt = Date.now();\n job.error = err instanceof Error ? err.message : String(err);\n }\n}\n\nasync function stopJob(ctx: DashboardContext): Promise<ApiResult> {\n const root = getRoot(ctx);\n if (!root) return { status: 400, body: { error: \"no project root\" } };\n const job = JOBS.get(root);\n if (!job || job.phase === \"done\" || job.phase === \"error\" || job.phase === \"cancelled\") {\n return { status: 404, body: { error: \"no running job\" } };\n }\n job.aborted = true;\n job.controller.abort(new Error(\"semantic indexing aborted\"));\n return { status: 202, body: { stopping: true, job: snapshotJob(job) } };\n}\n\nfunction getSemanticConfig(ctx: DashboardContext): ApiResult {\n return {\n status: 200,\n body: redactSemanticEmbeddingConfig(loadSemanticEmbeddingUserConfig(ctx.configPath)),\n };\n}\n\nfunction saveSemanticConfigApi(rawBody: string, ctx: DashboardContext): ApiResult {\n let parsed: {\n provider?: unknown;\n ollama?: { baseUrl?: unknown; model?: unknown };\n openaiCompat?: {\n baseUrl?: unknown;\n apiKey?: unknown;\n model?: unknown;\n extraBody?: unknown;\n };\n };\n try {\n parsed = JSON.parse(rawBody || \"{}\");\n } catch {\n return { status: 400, body: { error: \"body must be JSON\" } };\n }\n const existing = loadSemanticEmbeddingUserConfig(ctx.configPath);\n const next: SemanticEmbeddingUserConfig = {\n provider: parsed.provider === \"openai-compat\" ? \"openai-compat\" : \"ollama\",\n ollama: {\n baseUrl:\n typeof parsed.ollama?.baseUrl === \"string\"\n ? parsed.ollama.baseUrl\n : existing.ollama?.baseUrl,\n model:\n typeof parsed.ollama?.model === \"string\" ? parsed.ollama.model : existing.ollama?.model,\n },\n openaiCompat: {\n baseUrl:\n typeof parsed.openaiCompat?.baseUrl === \"string\"\n ? parsed.openaiCompat.baseUrl\n : existing.openaiCompat?.baseUrl,\n apiKey:\n typeof parsed.openaiCompat?.apiKey === \"string\"\n ? parsed.openaiCompat.apiKey.trim() || existing.openaiCompat?.apiKey\n : existing.openaiCompat?.apiKey,\n model:\n typeof parsed.openaiCompat?.model === \"string\"\n ? parsed.openaiCompat.model\n : existing.openaiCompat?.model,\n extraBody:\n parsed.openaiCompat?.extraBody === undefined\n ? existing.openaiCompat?.extraBody\n : (parsed.openaiCompat.extraBody as Record<string, unknown>),\n },\n };\n try {\n saveSemanticEmbeddingConfig(next, ctx.configPath);\n } catch (err) {\n return { status: 400, body: { error: (err as Error).message } };\n }\n ctx.audit?.({\n ts: Date.now(),\n action: \"set-semantic-config\",\n payload: { provider: next.provider },\n });\n return {\n status: 200,\n body: {\n changed: collectSemanticConfigChanges(existing, next),\n config: redactSemanticEmbeddingConfig(loadSemanticEmbeddingUserConfig(ctx.configPath)),\n },\n };\n}\n\nfunction collectSemanticConfigChanges(\n before: SemanticEmbeddingUserConfig,\n after: SemanticEmbeddingUserConfig,\n): string[] {\n const left = JSON.stringify(before);\n const right = JSON.stringify(after);\n if (left === right) return [];\n return [\"semantic\"];\n}\n\nasync function getProviderStatusFromConfig(\n config: ReturnType<typeof redactSemanticEmbeddingConfig>,\n): Promise<\n | {\n kind: \"ollama\";\n ready: boolean;\n baseUrl: string;\n binaryFound: boolean;\n daemonRunning: boolean;\n modelPulled: boolean;\n modelName: string;\n installedModels: string[];\n error?: string;\n }\n | {\n kind: \"openai-compat\";\n ready: boolean;\n baseUrl: string;\n apiKeySet: boolean;\n model: string;\n extraBodyKeys: string[];\n }\n> {\n if (config.provider === \"openai-compat\") {\n return {\n kind: \"openai-compat\",\n ready: Boolean(\n config.openaiCompat.baseUrl && config.openaiCompat.apiKeySet && config.openaiCompat.model,\n ),\n baseUrl: config.openaiCompat.baseUrl,\n apiKeySet: config.openaiCompat.apiKeySet,\n model: config.openaiCompat.model,\n extraBodyKeys: Object.keys(config.openaiCompat.extraBody),\n };\n }\n const ollama = await checkOllamaStatus(config.ollama.model, config.ollama.baseUrl).catch(\n (err) => ({\n binaryFound: false,\n daemonRunning: false,\n modelPulled: false,\n modelName: config.ollama.model,\n installedModels: [] as string[],\n error: err instanceof Error ? err.message : String(err),\n }),\n );\n return {\n kind: \"ollama\",\n ready: ollama.daemonRunning && ollama.modelPulled,\n baseUrl: config.ollama.baseUrl,\n ...ollama,\n };\n}\n\nasync function getProviderStatus(\n resolved: ReturnType<typeof resolveSemanticEmbeddingConfig>,\n): Promise<\n | {\n kind: \"ollama\";\n ready: boolean;\n baseUrl: string;\n binaryFound: boolean;\n daemonRunning: boolean;\n modelPulled: boolean;\n modelName: string;\n installedModels: string[];\n error?: string;\n }\n | {\n kind: \"openai-compat\";\n ready: boolean;\n baseUrl: string;\n apiKeySet: boolean;\n model: string;\n extraBodyKeys: string[];\n }\n> {\n if (resolved.provider === \"openai-compat\") {\n return {\n kind: \"openai-compat\",\n ready: Boolean(resolved.baseUrl && resolved.apiKey && resolved.model),\n baseUrl: resolved.baseUrl,\n apiKeySet: Boolean(resolved.apiKey),\n model: resolved.model,\n extraBodyKeys: Object.keys(resolved.extraBody),\n };\n }\n const ollama = await checkOllamaStatus(resolved.model, resolved.baseUrl).catch((err) => ({\n binaryFound: false,\n daemonRunning: false,\n modelPulled: false,\n modelName: resolved.model,\n installedModels: [] as string[],\n error: err instanceof Error ? err.message : String(err),\n }));\n return {\n kind: \"ollama\",\n ready: ollama.daemonRunning && ollama.modelPulled,\n baseUrl: resolved.baseUrl,\n ...ollama,\n };\n}\n\nvoid readConfig;\n\nfunction isAbortError(err: unknown): boolean {\n if (err instanceof Error) {\n if (err.name === \"AbortError\") return true;\n if (/aborted/i.test(err.message)) return true;\n }\n return false;\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { listSessions, sessionPath } from \"../../memory/session.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface SessionMessage {\n role: string;\n content?: string;\n toolName?: string;\n /** Raw record. Kept for debug; SPA reads from `role`/`content` first. */\n raw?: unknown;\n}\n\nfunction parseTranscript(path: string, maxBytes = 4 * 1024 * 1024): SessionMessage[] {\n // Cap reads at 4 MB so a runaway session file (rare but possible)\n // doesn't tie up the server. The `head` of a long session is the\n // useful part; we surface a `truncated` flag in the response.\n let raw: string;\n try {\n raw = readFileSync(path, \"utf8\");\n } catch {\n return [];\n }\n if (raw.length > maxBytes) raw = raw.slice(0, maxBytes);\n const out: SessionMessage[] = [];\n for (const line of raw.split(/\\r?\\n/)) {\n if (!line.trim()) continue;\n try {\n const rec = JSON.parse(line) as Record<string, unknown>;\n const role = typeof rec.role === \"string\" ? rec.role : \"unknown\";\n const msg: SessionMessage = { role };\n if (typeof rec.content === \"string\") msg.content = rec.content;\n else if (rec.content !== undefined) msg.content = JSON.stringify(rec.content);\n if (typeof rec.tool_name === \"string\") msg.toolName = rec.tool_name;\n if (typeof rec.toolName === \"string\") msg.toolName = rec.toolName;\n out.push(msg);\n } catch {\n /* skip malformed line — same rule as the rest of Reasonix's JSONL readers */\n }\n }\n return out;\n}\n\nexport async function handleSessions(\n method: string,\n rest: string[],\n _body: string,\n _ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"GET\") {\n return { status: 405, body: { error: \"GET only\" } };\n }\n\n // Listing.\n if (rest.length === 0) {\n const sessions = listSessions();\n return {\n status: 200,\n body: {\n sessions: sessions.map((s) => ({\n name: s.name,\n path: s.path,\n size: s.size,\n messageCount: s.messageCount,\n mtime: s.mtime.getTime(),\n })),\n },\n };\n }\n\n // Single-session detail. URL-decode in case the name had spaces / CJK\n // (sanitizeName allows them).\n const name = decodeURIComponent(rest[0]!);\n const path = sessionPath(name);\n if (!existsSync(path)) {\n return { status: 404, body: { error: `no such session: ${name}` } };\n }\n const messages = parseTranscript(path);\n return {\n status: 200,\n body: {\n name,\n path,\n messages,\n messageCount: messages.length,\n },\n };\n}\n","/** apiKey is write-only on the wire; GET always returns a redacted form so dashboard screenshots don't leak credentials. */\n\nimport { isPlausibleKey, readConfig, redactKey, saveEditMode, writeConfig } from \"../../config.js\";\nimport { getLanguage, getSupportedLanguages, setLanguage } from \"../../i18n/index.js\";\nimport type { LanguageCode } from \"../../i18n/types.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface SettingsBody {\n apiKey?: unknown;\n baseUrl?: unknown;\n lang?: unknown;\n preset?: unknown;\n reasoningEffort?: unknown;\n search?: unknown;\n model?: unknown;\n proNext?: unknown;\n budgetUsd?: unknown;\n}\n\nfunction parseBody(raw: string): SettingsBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as SettingsBody) : {};\n } catch {\n return {};\n }\n}\n\n// Accept new (auto/flash/pro) and legacy (fast/smart/max) — server\n// stores whatever the user picked; resolvePreset() canonicalizes at\n// read time. Web sends new names in 0.12.x onward.\nconst VALID_PRESETS = new Set([\"auto\", \"flash\", \"pro\", \"fast\", \"smart\", \"max\"]);\nconst VALID_EFFORTS = new Set([\"high\", \"max\"]);\n\nexport async function handleSettings(\n method: string,\n _rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method === \"GET\") {\n const cfg = readConfig(ctx.configPath);\n const live = ctx.loop;\n return {\n status: 200,\n body: {\n apiKey: cfg.apiKey ? redactKey(cfg.apiKey) : null,\n apiKeySet: Boolean(cfg.apiKey),\n baseUrl: cfg.baseUrl ?? null,\n lang: getLanguage(),\n preset: cfg.preset ?? \"auto\",\n reasoningEffort: cfg.reasoningEffort ?? \"max\",\n search: cfg.search !== false,\n editMode: cfg.editMode ?? \"review\",\n session: cfg.session ?? null,\n model: live?.model ?? null,\n proNext: live?.proArmed ?? false,\n budgetUsd: live?.budgetUsd ?? null,\n sessionSpendUsd: ctx.getStats?.()?.totalCostUsd ?? null,\n // Hint to the SPA which fields require restart.\n appliesAt: {\n apiKey: \"next-session\",\n baseUrl: \"next-session\",\n preset: \"next-session\",\n reasoningEffort: \"next-turn\",\n search: \"next-session\",\n model: \"next-turn\",\n proNext: \"next-turn\",\n budgetUsd: \"live\",\n },\n },\n };\n }\n\n if (method === \"POST\") {\n const fields = parseBody(body);\n // Single read up top, all field updates accumulate, single writeConfig at the end —\n // a per-field write would clobber earlier per-field writes from the same POST.\n const cfg = readConfig(ctx.configPath);\n const changed: string[] = [];\n let langPending: LanguageCode | null = null;\n let presetPendingLive: string | null = null;\n let effortPendingLive: \"high\" | \"max\" | null = null;\n\n if (fields.lang !== undefined) {\n const raw = String(fields.lang);\n const supported = getSupportedLanguages();\n const langCode = supported.find((l) => l.toLowerCase() === raw.toLowerCase()) as\n | LanguageCode\n | undefined;\n if (!langCode) {\n return { status: 400, body: { error: `lang must be one of: ${supported.join(\", \")}` } };\n }\n cfg.lang = langCode;\n langPending = langCode;\n changed.push(\"lang\");\n }\n if (fields.apiKey !== undefined) {\n if (typeof fields.apiKey !== \"string\" || !isPlausibleKey(fields.apiKey)) {\n return { status: 400, body: { error: \"apiKey must be 16+ chars with no whitespace\" } };\n }\n cfg.apiKey = fields.apiKey.trim();\n changed.push(\"apiKey\");\n }\n if (fields.baseUrl !== undefined) {\n if (typeof fields.baseUrl !== \"string\" || !fields.baseUrl.trim()) {\n return { status: 400, body: { error: \"baseUrl must be a non-empty string\" } };\n }\n cfg.baseUrl = fields.baseUrl.trim();\n changed.push(\"baseUrl\");\n }\n if (fields.preset !== undefined) {\n if (typeof fields.preset !== \"string\" || !VALID_PRESETS.has(fields.preset)) {\n return { status: 400, body: { error: \"preset must be auto | flash | pro\" } };\n }\n cfg.preset = fields.preset as \"auto\" | \"flash\" | \"pro\" | \"fast\" | \"smart\" | \"max\";\n presetPendingLive = fields.preset;\n changed.push(\"preset\");\n }\n if (fields.reasoningEffort !== undefined) {\n if (\n typeof fields.reasoningEffort !== \"string\" ||\n !VALID_EFFORTS.has(fields.reasoningEffort)\n ) {\n return { status: 400, body: { error: \"reasoningEffort must be high | max\" } };\n }\n cfg.reasoningEffort = fields.reasoningEffort as \"high\" | \"max\";\n effortPendingLive = fields.reasoningEffort as \"high\" | \"max\";\n changed.push(\"reasoningEffort\");\n }\n if (fields.search !== undefined) {\n if (typeof fields.search !== \"boolean\") {\n return { status: 400, body: { error: \"search must be a boolean\" } };\n }\n cfg.search = fields.search;\n changed.push(\"search\");\n }\n let modelPendingLive: string | null = null;\n let proNextPending: boolean | null = null;\n let budgetPending: number | null | undefined;\n if (fields.model !== undefined) {\n if (typeof fields.model !== \"string\" || !fields.model.trim()) {\n return { status: 400, body: { error: \"model must be a non-empty string\" } };\n }\n // Model is live-only (not in ReasonixConfig). Same as /model <id> slash — disk\n // pickup goes through preset / startup flag, not direct cfg.model.\n modelPendingLive = fields.model.trim();\n changed.push(\"model\");\n }\n if (fields.proNext !== undefined) {\n if (typeof fields.proNext !== \"boolean\") {\n return { status: 400, body: { error: \"proNext must be a boolean\" } };\n }\n // Not persisted: arming is per-turn ephemeral. Live-only side effect.\n proNextPending = fields.proNext;\n changed.push(\"proNext\");\n }\n if (fields.budgetUsd !== undefined) {\n if (fields.budgetUsd === null) {\n budgetPending = null;\n } else if (\n typeof fields.budgetUsd === \"number\" &&\n fields.budgetUsd > 0 &&\n Number.isFinite(fields.budgetUsd)\n ) {\n budgetPending = fields.budgetUsd;\n } else {\n return {\n status: 400,\n body: { error: \"budgetUsd must be null or a positive finite number\" },\n };\n }\n changed.push(\"budgetUsd\");\n }\n\n if (changed.length > 0) {\n writeConfig(cfg, ctx.configPath);\n // Runtime side-effects fire after the disk write succeeds —\n // prevents an i18n change from being visible while the on-disk\n // value still reflects the old setting (and vice-versa for\n // preset / reasoningEffort).\n if (langPending) setLanguage(langPending);\n if (presetPendingLive) ctx.applyPresetLive?.(presetPendingLive);\n if (effortPendingLive) ctx.applyEffortLive?.(effortPendingLive);\n if (modelPendingLive) ctx.applyModelLive?.(modelPendingLive);\n if (proNextPending !== null) ctx.setProNextLive?.(proNextPending);\n if (budgetPending !== undefined) ctx.setBudgetUsdLive?.(budgetPending);\n ctx.audit?.({ ts: Date.now(), action: \"set-settings\", payload: { fields: changed } });\n }\n return { status: 200, body: { changed } };\n }\n\n return { status: 405, body: { error: \"GET or POST only\" } };\n}\n\n// Keep saveEditMode imported so future GET responses can include the\n// canonical default — used by the SPA when /api/overview hasn't yet\n// resolved. (Currently surfaced via /api/overview directly.)\nvoid saveEditMode;\n","/** `/api/skills` — edits files only; loop reloads on /new or restart. `builtin` scope is read-only. */\n\nimport {\n closeSync,\n existsSync,\n fstatSync,\n mkdirSync,\n openSync,\n readFileSync,\n readSync,\n readdirSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { SKILLS_DIRNAME, SKILL_FILE } from \"../../skills.js\";\nimport { readUsageLog } from \"../../telemetry/usage.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface WriteBody {\n body?: unknown;\n}\n\nfunction parseBody(raw: string): WriteBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as WriteBody) : {};\n } catch {\n return {};\n }\n}\n\nconst SAFE_NAME = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}$/;\n\nfunction globalSkillsDir(): string {\n return join(homedir(), \".reasonix\", SKILLS_DIRNAME);\n}\n\nfunction projectSkillsDir(rootDir: string): string {\n return join(rootDir, \".reasonix\", SKILLS_DIRNAME);\n}\n\ninterface SkillListEntry {\n name: string;\n scope: \"project\" | \"global\" | \"builtin\";\n description?: string;\n path: string;\n size: number;\n mtime: number;\n}\n\nfunction parseFrontmatterDescription(raw: string): string | undefined {\n const lines = raw.split(/\\r?\\n/);\n if (lines[0] !== \"---\") return undefined;\n for (let i = 1; i < lines.length; i++) {\n if (lines[i] === \"---\") break;\n const m = lines[i]!.match(/^description:\\s*(.*)$/);\n if (m) return m[1]!.trim();\n }\n return undefined;\n}\n\nfunction listSkills(dir: string, scope: \"project\" | \"global\"): SkillListEntry[] {\n if (!existsSync(dir)) return [];\n const out: SkillListEntry[] = [];\n try {\n for (const entry of readdirSync(dir)) {\n if (!SAFE_NAME.test(entry)) continue;\n const skillPath = join(dir, entry, SKILL_FILE);\n try {\n // Open once and reuse the fd so size/mtime/content all bind to\n // the same inode — closes the exists→stat→read TOCTOU races.\n const fd = openSync(skillPath, \"r\");\n let stat: ReturnType<typeof fstatSync>;\n let raw: string;\n try {\n stat = fstatSync(fd);\n const buf = Buffer.alloc(stat.size);\n let read = 0;\n while (read < stat.size) {\n const n = readSync(fd, buf, read, stat.size - read, read);\n if (n <= 0) break;\n read += n;\n }\n raw = buf.toString(\"utf8\", 0, read);\n } finally {\n closeSync(fd);\n }\n const item: SkillListEntry = {\n name: entry,\n scope,\n path: skillPath,\n size: stat.size,\n mtime: stat.mtime.getTime(),\n };\n const desc = parseFrontmatterDescription(raw);\n if (desc) item.description = desc;\n out.push(item);\n } catch {\n /* skip unreadable */\n }\n }\n } catch {\n /* skip unreadable dir */\n }\n return out.sort((a, b) => a.name.localeCompare(b.name));\n}\n\nfunction countSubagentRuns(usageLogPath: string): Map<string, number> {\n const cutoff = Date.now() - 7 * 86_400_000;\n const counts = new Map<string, number>();\n for (const r of readUsageLog(usageLogPath)) {\n if (r.kind !== \"subagent\" || r.ts < cutoff) continue;\n const skill = r.subagent?.skillName?.trim();\n if (!skill) continue;\n counts.set(skill, (counts.get(skill) ?? 0) + 1);\n }\n return counts;\n}\n\nexport async function handleSkills(\n method: string,\n rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n const cwd = ctx.getCurrentCwd?.();\n\n if (method === \"GET\" && rest.length === 0) {\n const runs7d = countSubagentRuns(ctx.usageLogPath);\n const tag = (rows: SkillListEntry[]) =>\n rows.map((r) => ({ ...r, runs7d: runs7d.get(r.name) ?? 0 }));\n return {\n status: 200,\n body: {\n global: tag(listSkills(globalSkillsDir(), \"global\")),\n project: cwd ? tag(listSkills(projectSkillsDir(cwd), \"project\")) : [],\n builtin: [\n {\n name: \"explore\",\n scope: \"builtin\",\n description: \"subagent — broad codebase survey\",\n runs7d: runs7d.get(\"explore\") ?? 0,\n },\n {\n name: \"research\",\n scope: \"builtin\",\n description: \"subagent — deep web + repo research\",\n runs7d: runs7d.get(\"research\") ?? 0,\n },\n ],\n paths: {\n global: globalSkillsDir(),\n project: cwd ? projectSkillsDir(cwd) : null,\n },\n },\n };\n }\n\n const [scope, ...nameParts] = rest;\n const name = nameParts.join(\"/\");\n\n if (!scope || !name || !SAFE_NAME.test(name)) {\n return { status: 400, body: { error: \"expected /api/skills/<scope>/<name>\" } };\n }\n if (scope !== \"project\" && scope !== \"global\") {\n return {\n status: 400,\n body: { error: \"scope must be project | global (builtin is read-only)\" },\n };\n }\n let dir: string;\n if (scope === \"project\") {\n if (!cwd) {\n return {\n status: 503,\n body: { error: \"no active project — open `/dashboard` from `reasonix code`\" },\n };\n }\n dir = projectSkillsDir(cwd);\n } else {\n dir = globalSkillsDir();\n }\n const skillPath = join(dir, name, SKILL_FILE);\n\n if (method === \"GET\") {\n if (!existsSync(skillPath)) return { status: 404, body: { error: \"skill not found\" } };\n return { status: 200, body: { path: skillPath, body: readFileSync(skillPath, \"utf8\") } };\n }\n\n if (method === \"POST\") {\n const { body: contents } = parseBody(body);\n if (typeof contents !== \"string\") {\n return { status: 400, body: { error: \"body (string) required\" } };\n }\n mkdirSync(dirname(skillPath), { recursive: true });\n writeFileSync(skillPath, contents, \"utf8\");\n ctx.audit?.({\n ts: Date.now(),\n action: \"save-skill\",\n payload: { scope, name, path: skillPath },\n });\n return { status: 200, body: { saved: true, path: skillPath } };\n }\n\n if (method === \"DELETE\") {\n if (!existsSync(skillPath)) return { status: 404, body: { error: \"skill not found\" } };\n // Drop the whole skill folder (it may carry assets next to SKILL.md).\n rmSync(dirname(skillPath), { recursive: true, force: true });\n ctx.audit?.({ ts: Date.now(), action: \"delete-skill\", payload: { scope, name } });\n return { status: 200, body: { deleted: true } };\n }\n\n return { status: 405, body: { error: `method ${method} not supported` } };\n}\n","import { SLASH_COMMANDS } from \"../../cli/ui/slash/commands.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\nexport async function handleSlash(\n method: string,\n _rest: string[],\n _body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"GET\") return { status: 405, body: { error: \"GET only\" } };\n const codeMode = ctx.getCurrentCwd?.() != null;\n const commands = SLASH_COMMANDS.filter((c) => c.contextual !== \"code\" || codeMode).map((c) => ({\n cmd: c.cmd,\n summary: c.summary,\n argsHint: c.argsHint,\n contextual: c.contextual,\n aliases: c.aliases,\n }));\n return { status: 200, body: { commands, codeMode } };\n}\n","import type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface SubmitBody {\n prompt?: unknown;\n}\n\nfunction parseBody(raw: string): SubmitBody {\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed !== null ? (parsed as SubmitBody) : {};\n } catch {\n return {};\n }\n}\n\nexport async function handleSubmit(\n method: string,\n _rest: string[],\n body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"POST\") {\n return { status: 405, body: { error: \"POST only\" } };\n }\n if (!ctx.submitPrompt) {\n return {\n status: 503,\n body: {\n error:\n \"submit requires an attached dashboard session — open `/dashboard` from inside `reasonix code` or `reasonix chat`.\",\n },\n };\n }\n const { prompt } = parseBody(body);\n if (typeof prompt !== \"string\" || !prompt.trim()) {\n return { status: 400, body: { error: \"prompt (non-empty string) required\" } };\n }\n const result = ctx.submitPrompt(prompt);\n if (!result.accepted) {\n return {\n status: 409,\n body: { accepted: false, reason: result.reason ?? \"loop is busy\" },\n };\n }\n ctx.audit?.({\n ts: Date.now(),\n action: \"submit-prompt\",\n payload: { length: prompt.length },\n });\n return { status: 202, body: { accepted: true } };\n}\n","import type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\nexport async function handleTools(\n method: string,\n _rest: string[],\n _body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"GET\") {\n return { status: 405, body: { error: \"GET only\" } };\n }\n if (!ctx.tools) {\n return {\n status: 503,\n body: {\n error:\n \"live tools view requires an attached session — run `/dashboard` from inside `reasonix code` instead of standalone `reasonix dashboard`.\",\n available: false,\n },\n };\n }\n const specs = ctx.tools.specs();\n // We deliberately surface the model-facing schema (`specs()` already\n // resolves auto-flattened forms) so what the SPA shows matches what\n // DeepSeek receives. ReadOnly + planMode flags come from the\n // internal definitions, accessed via `get()`.\n const items = specs.map((s) => {\n const def = ctx.tools!.get(s.function.name);\n return {\n name: s.function.name,\n description: s.function.description,\n schema: s.function.parameters,\n readOnly: Boolean(def?.readOnly),\n flattened: ctx.tools!.wasFlattened(s.function.name),\n };\n });\n return {\n status: 200,\n body: {\n planMode: ctx.tools.planMode,\n total: items.length,\n tools: items,\n },\n };\n}\n","import { cacheSavingsUsd } from \"../../telemetry/stats.js\";\nimport { aggregateUsage, formatLogSize, readUsageLog } from \"../../telemetry/usage.js\";\nimport type { DashboardContext } from \"../context.js\";\nimport type { ApiResult } from \"../router.js\";\n\ninterface DailyBucket {\n /** UTC day key, ISO yyyy-mm-dd. Sorted ascending. */\n day: string;\n turns: number;\n promptTokens: number;\n completionTokens: number;\n cacheHitTokens: number;\n cacheMissTokens: number;\n costUsd: number;\n cacheSavingsUsd: number;\n}\n\nfunction dayKey(ts: number): string {\n return new Date(ts).toISOString().slice(0, 10);\n}\n\nfunction buildSeries(records: ReturnType<typeof readUsageLog>): DailyBucket[] {\n const map = new Map<string, DailyBucket>();\n for (const r of records) {\n const day = dayKey(r.ts);\n let b = map.get(day);\n if (!b) {\n b = {\n day,\n turns: 0,\n promptTokens: 0,\n completionTokens: 0,\n cacheHitTokens: 0,\n cacheMissTokens: 0,\n costUsd: 0,\n cacheSavingsUsd: 0,\n };\n map.set(day, b);\n }\n b.turns += 1;\n b.promptTokens += r.promptTokens;\n b.completionTokens += r.completionTokens;\n b.cacheHitTokens += r.cacheHitTokens;\n b.cacheMissTokens += r.cacheMissTokens;\n b.costUsd += r.costUsd;\n b.cacheSavingsUsd += cacheSavingsUsd(r.model, r.cacheHitTokens);\n }\n return Array.from(map.values()).sort((a, b) => a.day.localeCompare(b.day));\n}\n\nexport async function handleUsage(\n method: string,\n rest: string[],\n _body: string,\n ctx: DashboardContext,\n): Promise<ApiResult> {\n if (method !== \"GET\") {\n return { status: 405, body: { error: \"GET only\" } };\n }\n const records = readUsageLog(ctx.usageLogPath);\n\n // /api/usage/series → daily roll-ups for the chart. Separate sub-path\n // so the main /api/usage stays a small dashboard payload that polls\n // every 5s without dragging the series along.\n if (rest[0] === \"series\") {\n return {\n status: 200,\n body: {\n days: buildSeries(records),\n recordCount: records.length,\n },\n };\n }\n\n const agg = aggregateUsage(records);\n return {\n status: 200,\n body: {\n logPath: ctx.usageLogPath,\n logSize: formatLogSize(ctx.usageLogPath),\n recordCount: records.length,\n buckets: agg.buckets,\n byModel: agg.byModel,\n bySession: agg.bySession,\n firstSeen: agg.firstSeen,\n lastSeen: agg.lastSeen,\n subagents: agg.subagents ?? null,\n },\n };\n}\n","import { handleAbort } from \"./api/abort.js\";\nimport { handleEditMode } from \"./api/edit-mode.js\";\nimport { handleFiles } from \"./api/files.js\";\nimport { handleHealth } from \"./api/health.js\";\nimport { handleHooks } from \"./api/hooks.js\";\nimport { handleIndexConfig } from \"./api/index-config.js\";\nimport { handleLoop } from \"./api/loop.js\";\nimport { handleMcp } from \"./api/mcp.js\";\nimport { handleMemory } from \"./api/memory.js\";\nimport { handleMessages } from \"./api/messages.js\";\nimport { handleModal } from \"./api/modal.js\";\nimport { handleModels } from \"./api/models.js\";\nimport { handleOverview } from \"./api/overview.js\";\nimport { handlePermissions } from \"./api/permissions.js\";\nimport { handlePlans } from \"./api/plans.js\";\nimport { handleSemantic } from \"./api/semantic.js\";\nimport { handleSessions } from \"./api/sessions.js\";\nimport { handleSettings } from \"./api/settings.js\";\nimport { handleSkills } from \"./api/skills.js\";\nimport { handleSlash } from \"./api/slash.js\";\nimport { handleSubmit } from \"./api/submit.js\";\nimport { handleTools } from \"./api/tools.js\";\nimport { handleUsage } from \"./api/usage.js\";\nimport type { DashboardContext } from \"./context.js\";\n\nexport interface ApiResult {\n status: number;\n body: unknown;\n}\n\nexport async function handleApi(\n pathTail: string,\n method: string,\n body: string,\n ctx: DashboardContext,\n query: URLSearchParams = new URLSearchParams(),\n): Promise<ApiResult> {\n // Strip a trailing slash so /api/usage and /api/usage/ both work.\n const normalized = pathTail.replace(/\\/+$/, \"\");\n const [head, ...rest] = normalized.split(\"/\");\n\n try {\n switch (head) {\n case \"overview\":\n return await handleOverview(method, rest, body, ctx);\n case \"usage\":\n return await handleUsage(method, rest, body, ctx);\n case \"tools\":\n return await handleTools(method, rest, body, ctx);\n case \"permissions\":\n return await handlePermissions(method, rest, body, ctx);\n case \"messages\":\n return await handleMessages(method, rest, body, ctx);\n case \"submit\":\n return await handleSubmit(method, rest, body, ctx);\n case \"abort\":\n return await handleAbort(method, rest, body, ctx);\n case \"health\":\n return await handleHealth(method, rest, body, ctx);\n case \"sessions\":\n return await handleSessions(method, rest, body, ctx);\n case \"plans\":\n return await handlePlans(method, rest, body, ctx);\n case \"modal\":\n return await handleModal(method, rest, body, ctx);\n case \"edit-mode\":\n return await handleEditMode(method, rest, body, ctx);\n case \"settings\":\n return await handleSettings(method, rest, body, ctx);\n case \"hooks\":\n return await handleHooks(method, rest, body, ctx);\n case \"memory\":\n return await handleMemory(method, rest, body, ctx);\n case \"skills\":\n return await handleSkills(method, rest, body, ctx);\n case \"mcp\":\n return await handleMcp(method, rest, body, ctx, query);\n case \"semantic\":\n return await handleSemantic(method, rest, body, ctx);\n case \"index-config\":\n return await handleIndexConfig(method, rest, body, ctx);\n case \"slash\":\n return await handleSlash(method, rest, body, ctx);\n case \"files\":\n return await handleFiles(method, rest, body, ctx);\n case \"loop\":\n return await handleLoop(method, rest, body, ctx);\n case \"models\":\n return await handleModels(method, rest, body, ctx);\n default:\n return { status: 404, body: { error: `no such endpoint: /${head}` } };\n }\n } catch (err) {\n // Any unexpected throw maps to 500. Endpoint code that wants a\n // user-friendly 4xx must catch + return the envelope itself.\n return {\n status: 500,\n body: { error: `handler crashed: ${(err as Error).message}` },\n };\n }\n}\n"],"mappings":"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","names":["join","existsSync","readdirSync","statSync","join","existsSync","readdirSync","join","statSync","existsSync","readFileSync","dirname","existsSync","existsSync","parseBody","existsSync","readFileSync","dirname","parseBody","parseBody","parseBody","existsSync","mkdirSync","readFileSync","readdirSync","statSync","writeFileSync","homedir","dirname","join","join","homedir","parseBody","existsSync","readdirSync","statSync","readFileSync","mkdirSync","dirname","writeFileSync","parseBody","existsSync","existsSync","sessionsDir","parseBody","cwd","closeSync","fstatSync","openSync","readSync","join","readIndexMeta","join","openSync","fstatSync","readSync","closeSync","existsSync","readFileSync","readFileSync","existsSync","parseBody","closeSync","existsSync","fstatSync","mkdirSync","openSync","readFileSync","readSync","readdirSync","writeFileSync","homedir","dirname","join","parseBody","SAFE_NAME","join","homedir","existsSync","readdirSync","openSync","fstatSync","readSync","closeSync","readFileSync","mkdirSync","dirname","writeFileSync","parseBody"]}
|