@jefuriiij/synthra 0.8.0 → 0.8.1

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../package.json","../../src/cli/index.ts","../../src/dashboard/server.ts","../../src/shared/logger.ts","../../src/server/port.ts","../../src/dashboard/arsenal.ts","../../src/dashboard/delta.ts","../../src/learn/store.ts","../../src/learn/usage.ts","../../src/shared/paths.ts","../../src/shared/pricing.ts","../../src/shared/project-registry.ts","../../src/dashboard/built/index.html","../../src/dashboard/public/favicon.svg","../../src/hooks/installer.ts","../../src/hooks/scripts/pre-compact.ps1","../../src/hooks/scripts/pre-compact.sh","../../src/hooks/scripts/pre-tool-use.ps1","../../src/hooks/scripts/pre-tool-use.sh","../../src/hooks/scripts/prime.ps1","../../src/hooks/scripts/prime.sh","../../src/hooks/scripts/stop.ps1","../../src/hooks/scripts/stop.sh","../../src/server/http.ts","../../src/activity/activity-log.ts","../../src/activity/file-watcher.ts","../../src/activity/git-watcher.ts","../../src/cli/scan-command.ts","../../src/scanner/extract.ts","../../src/graph/types.ts","../../src/scanner/hash.ts","../../src/scanner/keywords.ts","../../src/scanner/parse-cache.ts","../../src/scanner/parser.ts","../../src/scanner/parsers/_generic.ts","../../src/scanner/parsers/c.ts","../../src/scanner/parsers/cpp.ts","../../src/scanner/parsers/csharp.ts","../../src/scanner/parsers/dart.ts","../../src/scanner/parsers/go.ts","../../src/scanner/parsers/hubl.ts","../../src/scanner/parsers/java.ts","../../src/scanner/parsers/kotlin.ts","../../src/scanner/parsers/php.ts","../../src/scanner/parsers/python.ts","../../src/scanner/parsers/ruby.ts","../../src/scanner/parsers/rust.ts","../../src/scanner/parsers/typescript.ts","../../src/scanner/parsers/svelte.ts","../../src/scanner/parsers/vue.ts","../../src/scanner/walker.ts","../../src/graph/store.ts","../../src/cli/bootstrap.ts","../../src/hooks/claude-md.ts","../../src/learn/runtime.ts","../../src/server/mcp.ts","../../src/graph/rank.ts","../../src/graph/retrieve.ts","../../src/memory/branches.ts","../../src/memory/context-md.ts","../../src/memory/context-store.ts","../../src/memory/index.ts","../../src/packer/format.ts","../../src/packer/inline.ts","../../src/packer/signatures.ts","../../src/packer/tests.ts","../../src/packer/index.ts","../../src/shared/config.ts","../../src/server/routes/activity.ts","../../src/memory/git-snapshot.ts","../../src/memory/session.ts","../../src/server/routes/context-update.ts","../../src/server/routes/gate.ts","../../src/server/routes/log.ts","../../src/server/routes/pack.ts","../../src/server/routes/prime.ts","../../src/cli/session-discovery.ts","../../src/cli/cleanup.ts","../../src/cli/dashboard-command.ts","../../src/cli/doctor-command.ts","../../src/cli/self-update.ts","../../src/cli/serve-command.ts","../../src/cli/start-claude.ts"],"sourcesContent":["{\n \"name\": \"@jefuriiij/synthra\",\n \"version\": \"0.8.0\",\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"description\": \"Local context engine for AI coding assistants — graph-based context, branch-aware memory, real-time human-activity awareness, deterministic Grep/Glob gating, and a live token dashboard.\",\n \"type\": \"module\",\n \"bin\": {\n \"syn\": \"bin/syn\",\n \"synthra\": \"bin/syn\"\n },\n \"scripts\": {\n \"build\": \"npm run build:ui && tsup\",\n \"build:ui\": \"vite build --config vite.config.dashboard.ts\",\n \"dev\": \"tsup --watch\",\n \"dev:ui\": \"vite --config vite.config.dashboard.ts\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"biome lint .\",\n \"format\": \"biome format --write .\",\n \"check\": \"biome check .\",\n \"check:fix\": \"biome check --write .\"\n },\n \"files\": [\n \"dist\",\n \"bin\",\n \"README.md\",\n \"CHANGELOG.md\",\n \"LICENSE\",\n \"ROADMAP.md\"\n ],\n \"keywords\": [\n \"claude-code\",\n \"mcp\",\n \"context-engine\",\n \"code-graph\",\n \"ai-coding\",\n \"token-savings\"\n ],\n \"author\": \"Jeff (@jefuriiij)\",\n \"license\": \"MIT\",\n \"homepage\": \"https://github.com/jefuriiij/synthra#readme\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/jefuriiij/synthra.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/jefuriiij/synthra/issues\"\n },\n \"engines\": {\n \"node\": \">=18\"\n },\n \"dependencies\": {\n \"@hono/node-server\": \"^1.18.0\",\n \"chokidar\": \"^5.0.0\",\n \"cross-spawn\": \"^7.0.6\",\n \"hono\": \"^4.12.23\",\n \"ignore\": \"^7.0.0\",\n \"sade\": \"^1.8.1\",\n \"tree-sitter-wasms\": \"^0.1.12\",\n \"web-tree-sitter\": \"^0.25.10\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^2.4.16\",\n \"@lucide/svelte\": \"^1.18.0\",\n \"@sveltejs/vite-plugin-svelte\": \"^7.1.2\",\n \"@tailwindcss/vite\": \"^4.3.1\",\n \"@types/cross-spawn\": \"^6.0.6\",\n \"@types/node\": \"^25.9.1\",\n \"@vitest/coverage-v8\": \"^4.1.8\",\n \"bits-ui\": \"^2.18.1\",\n \"clsx\": \"^2.1.1\",\n \"svelte\": \"^5.56.3\",\n \"tailwind-merge\": \"^3.6.0\",\n \"tailwind-variants\": \"^3.2.2\",\n \"tailwindcss\": \"^4.3.1\",\n \"tsup\": \"^8.5.1\",\n \"tw-animate-css\": \"^1.4.0\",\n \"typescript\": \"^6.0.3\",\n \"vite\": \"^8.0.16\",\n \"vite-plugin-singlefile\": \"^2.3.3\",\n \"vitest\": \"^4.1.7\"\n }\n}\n","// `syn` entry point. Parses args and dispatches to commands.\n//\n// Commands:\n// syn [path] → default: scan + start MCP + dashboard +\n// register MCP for IDE extension; block on\n// Ctrl+C. NO claude CLI spawn — use the IDE.\n// syn . [path] → alias for default\n// syn . --launch-cli → also spawn `claude` here (M3 behavior)\n// syn scan [path] → scan only\n// syn serve [path] → start MCP server only\n// syn dashboard [path] → run only the dashboard server\n// syn --resume <id> [path] → resume an existing Claude session\n// (only meaningful with --launch-cli)\n\nimport sade from \"sade\";\nimport { resolve } from \"node:path\";\n\n// Inlined at build time by tsup's JSON loader so `syn --version` always\n// matches the published package.\nimport pkgJson from \"../../package.json\" with { type: \"json\" };\n\nimport { startDashboard, type DashboardServerHandle } from \"../dashboard/server.js\";\nimport { installHooks } from \"../hooks/installer.js\";\nimport { startServer, type ServerHandle } from \"../server/http.js\";\nimport { loadConfig } from \"../shared/config.js\";\nimport { log } from \"../shared/logger.js\";\nimport { resolvePaths } from \"../shared/paths.js\";\nimport { recordProject } from \"../shared/project-registry.js\";\nimport { cleanup } from \"./cleanup.js\";\nimport { dashboardCommand } from \"./dashboard-command.js\";\nimport { doctorCommand } from \"./doctor-command.js\";\nimport { scanCommand, type ScanResult } from \"./scan-command.js\";\nimport { promptForUpdateOrLog, runStartupChangelogCheck } from \"./self-update.js\";\nimport { serveCommand } from \"./serve-command.js\";\nimport { registerMcp, spawnClaude, unregisterMcp } from \"./start-claude.js\";\n\nconst VERSION = (pkgJson as { version: string }).version;\n\ninterface DefaultOpts {\n resume?: string;\n \"launch-cli\"?: boolean;\n full?: boolean;\n}\n\ninterface BannerInfo {\n projectRoot: string;\n scan: ScanResult;\n mcpUrl: string;\n dashboardUrl: string | null;\n mcpRegistered: boolean;\n}\n\nfunction printReadyBanner(info: BannerInfo): void {\n log.info(\"\");\n log.info(\n ` ✅ scanned ${info.scan.parsed} files · ${info.scan.symbolCount} symbols · ${info.scan.edgeCount} edges`,\n );\n if (info.mcpRegistered) {\n log.info(` 🧠 MCP ${info.mcpUrl} → registered as 'synthra'`);\n } else {\n log.info(` 🧠 MCP ${info.mcpUrl} ⚠ registration with claude failed`);\n }\n if (info.dashboardUrl) {\n log.info(` 📊 Dashboard ${info.dashboardUrl}`);\n } else {\n log.info(` 📊 Dashboard (failed to start; data is still logged to .synthra-graph/)`);\n }\n log.info(` 🪝 Hooks installed in .claude/settings.local.json`);\n log.info(\"\");\n log.info(\n ` 🤖 Ready — open the Claude Code IDE extension (or run \\`claude\\` in another terminal).`,\n );\n log.info(` Synthra's tools and gate will be active for that session.`);\n log.info(\"\");\n log.info(` Press Ctrl+C here when you're done.`);\n log.info(\"\");\n}\n\nfunction waitForSignal(): Promise<NodeJS.Signals> {\n return new Promise((resolve) => {\n const handler = (sig: NodeJS.Signals) => {\n process.off(\"SIGINT\", handler);\n process.off(\"SIGTERM\", handler);\n resolve(sig);\n };\n process.on(\"SIGINT\", handler);\n process.on(\"SIGTERM\", handler);\n });\n}\n\nasync function defaultFlow(rawPath: string, opts: DefaultOpts): Promise<void> {\n const launchCli = opts[\"launch-cli\"] === true;\n const projectRoot = resolve(rawPath);\n const paths = resolvePaths(projectRoot);\n const cfg = loadConfig();\n\n // If the running binary is newer than last-seen (e.g. user upgraded via\n // `npm install -g …@latest` directly), print the changelog for what they\n // just got. Silent if already on latest-seen or on fresh install.\n await runStartupChangelogCheck();\n\n // Always-fresh registry check (no cache). If a newer version is on npm AND\n // we're on a TTY, prompts [y/N]. On 'y', runs npm install, prints the new\n // version's changelog, and exits with re-run instructions. On 'n' / no\n // update / non-TTY, continues silently. SYN_NO_UPDATE_CHECK=1 opts out.\n await promptForUpdateOrLog();\n\n // 1. bootstrap + scan + record in the global registry so the dashboard\n // can list this project alongside any others.\n await recordProject(projectRoot);\n const scan = await scanCommand(rawPath, { full: opts.full });\n\n // 2. MCP server (background within this process)\n const mcpHandle: ServerHandle = await startServer(paths);\n\n // 3. Dashboard (optional — non-fatal if it fails)\n let dashboardHandle: DashboardServerHandle | null = null;\n try {\n dashboardHandle = await startDashboard(paths, cfg.dashboardPort);\n } catch (err) {\n log.warn(`dashboard failed to start on port ${cfg.dashboardPort}: ${(err as Error).message}`);\n }\n\n // 4. Install hooks + register MCP so the IDE / external claude can see it\n await installHooks(paths);\n const mcpRegistered = await registerMcp(cfg.claudeBin, mcpHandle.port, projectRoot);\n\n let claudeExitCode = 0;\n try {\n if (launchCli) {\n claudeExitCode = await spawnClaude(cfg.claudeBin, {\n cwd: projectRoot,\n resumeSessionId: opts.resume,\n });\n log.info(`claude exited with code ${claudeExitCode}`);\n } else {\n printReadyBanner({\n projectRoot,\n scan,\n mcpUrl: mcpHandle.url,\n dashboardUrl: dashboardHandle?.url ?? null,\n mcpRegistered,\n });\n const sig = await waitForSignal();\n log.info(`received ${sig} — shutting down…`);\n }\n } finally {\n await unregisterMcp(cfg.claudeBin, projectRoot).catch(() => undefined);\n if (dashboardHandle) {\n await dashboardHandle\n .stop()\n .catch((err) => log.warn(`dashboard stop error: ${(err as Error).message}`));\n }\n await mcpHandle\n .stop()\n .catch((err) => log.warn(`MCP server stop error: ${(err as Error).message}`));\n await cleanup(paths).catch((err) => log.warn(`cleanup error: ${(err as Error).message}`));\n }\n}\n\nexport function buildProgram() {\n const prog = sade(\"syn\");\n prog.version(VERSION).describe(\"Local context engine for AI coding assistants.\");\n\n prog\n .command(\n \". [path]\",\n \"Scan + MCP + dashboard + hooks. Default flow — use with the Claude Code IDE extension.\",\n {\n default: true,\n },\n )\n .option(\"--resume <id>\", \"Resume an existing Claude session (only with --launch-cli)\")\n .option(\"--launch-cli\", \"Also spawn `claude` CLI in this terminal (legacy M3 behavior)\", false)\n .option(\"--full\", \"Re-parse every file, ignoring the incremental parse cache\", false)\n .action(async (path: string | undefined, opts: DefaultOpts) => {\n await defaultFlow(path ?? \".\", opts);\n });\n\n prog\n .command(\"scan [path]\", \"Scan only — walk + parse + write graph.\")\n .option(\"--full\", \"Re-parse every file, ignoring the incremental parse cache\", false)\n .action(async (path: string | undefined, opts: { full?: boolean }) => {\n await scanCommand(path ?? \".\", { full: opts.full });\n });\n\n prog\n .command(\"serve [path]\", \"Start the HTTP MCP server against a scanned project.\")\n .action(async (path: string | undefined) => {\n await serveCommand(path ?? \".\");\n });\n\n prog\n .command(\"dashboard [path]\", \"Run the token dashboard server (localhost:8901).\")\n .action(async (path: string | undefined) => {\n await dashboardCommand(path ?? \".\");\n });\n\n prog\n .command(\"doctor [path]\", \"Diagnose this project's Synthra setup + environment.\")\n .action(async (path: string | undefined) => {\n await doctorCommand(path ?? \".\");\n });\n\n return prog;\n}\n\nexport async function main(argv: string[]): Promise<void> {\n const prog = buildProgram();\n prog.parse(argv);\n}\n","// Standalone dashboard server. Default port 8901 (override via\n// SYN_DASHBOARD_PORT); falls back through a small range 8901–8910 if the\n// preferred port is busy (so we can coexist with other co-installed\n// AI-context tools that also expose a dashboard).\n// Reads .synthra-graph/token_log.jsonl + .synthra-graph/gate_log.jsonl for the\n// given project and renders a live SPA backed by GET /data polled every 2s.\n\nimport { serve } from \"@hono/node-server\";\nimport { Hono } from \"hono\";\n\n// Tsup inlines this import at build time so `c.html` can echo whatever\n// version is running. Replaces the v__SYN_VERSION__ placeholder in the\n// dashboard footer on every GET /.\nimport pkgJson from \"../../package.json\" with { type: \"json\" };\n\nimport { log } from \"../shared/logger.js\";\nimport type { SynthraPaths } from \"../shared/paths.js\";\nimport { findFreePort } from \"../server/port.js\";\nimport { computeArsenal } from \"./arsenal.js\";\nimport { computeDashboardData } from \"./delta.js\";\n\n// The dashboard UI is built by Vite (svelte + tailwind) into a single\n// self-contained HTML (JS+CSS inlined) at ./built/index.html; tsup text-inlines\n// it here. See vite.config.dashboard.ts. CSS is inside the HTML — no /style.css.\nimport indexHtml from \"./built/index.html\";\nimport faviconSvg from \"./public/favicon.svg\";\n\nconst FALLBACK_RANGE = 9; // try preferredPort + [0..9]\nconst VERSION = (pkgJson as { version: string }).version;\n// How many recent turns/gates the /data payload carries. The dashboard\n// paginates turns client-side (25/page); the donut uses the uncapped\n// per-project model aggregate, so it isn't bounded by this.\nconst RECENT_N = Number(process.env.SYN_DASHBOARD_RECENT_N) || 500;\n\nexport interface DashboardServerHandle {\n port: number;\n url: string;\n stop(): Promise<void>;\n}\n\nexport async function startDashboard(\n paths: SynthraPaths,\n preferredPort = 8901,\n): Promise<DashboardServerHandle> {\n const port = await findFreePort(preferredPort, preferredPort + FALLBACK_RANGE);\n if (port !== preferredPort) {\n log.info(\n `dashboard port ${preferredPort} was busy — bound to ${port} instead (likely another dashboard from a coexisting tool).`,\n );\n }\n const app = new Hono();\n\n app.get(\"/\", (c) => c.html(indexHtml.replaceAll(\"__SYN_VERSION__\", VERSION)));\n\n app.get(\"/favicon.svg\", (c) => {\n c.header(\"Content-Type\", \"image/svg+xml; charset=utf-8\");\n c.header(\"Cache-Control\", \"public, max-age=86400\");\n return c.body(faviconSvg);\n });\n\n app.get(\"/health\", (c) => c.json({ ok: true }));\n\n // Installed skills / agents / MCP servers (project · personal · plugin).\n // Fetched lazily when the Arsenal drawer opens — not on the /data poll.\n app.get(\"/arsenal\", async (c) => c.json(await computeArsenal(paths.projectRoot)));\n\n app.get(\"/data\", async (c) => {\n const data = await computeDashboardData(paths, RECENT_N);\n return c.json(data);\n });\n\n const nodeServer = serve({ fetch: app.fetch, port, hostname: \"127.0.0.1\" });\n\n return {\n port,\n url: `http://127.0.0.1:${port}`,\n async stop() {\n await new Promise<void>((resolve, reject) => {\n nodeServer.close((err) => (err ? reject(err) : resolve()));\n });\n },\n };\n}\n","// Minimal logger. Prefixes Synthra output with [syn].\n\ntype Level = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nconst LEVEL_PRIORITY: Record<Level, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n};\n\nlet activeLevel: Level = (process.env.SYN_LOG_LEVEL as Level) ?? \"info\";\n\nexport function setLevel(level: Level): void {\n activeLevel = level;\n}\n\nfunction shouldLog(level: Level): boolean {\n return LEVEL_PRIORITY[level] >= LEVEL_PRIORITY[activeLevel];\n}\n\nfunction emit(level: Level, msg: string, ...args: unknown[]): void {\n if (!shouldLog(level)) return;\n const stream = level === \"error\" || level === \"warn\" ? process.stderr : process.stdout;\n stream.write(`[syn] ${msg}${args.length ? \" \" + args.map(String).join(\" \") : \"\"}\\n`);\n}\n\nexport const log = {\n debug: (m: string, ...a: unknown[]) => emit(\"debug\", m, ...a),\n info: (m: string, ...a: unknown[]) => emit(\"info\", m, ...a),\n warn: (m: string, ...a: unknown[]) => emit(\"warn\", m, ...a),\n error: (m: string, ...a: unknown[]) => emit(\"error\", m, ...a),\n};\n","// Finds a free port in the 8080–8099 range. Writes the chosen port to\n// .synthra-graph/mcp_port so PowerShell/Bash hook scripts can read it.\n// TODO: M2\n\nimport { createServer } from \"node:net\";\n\nexport const PORT_RANGE_START = 8080;\nexport const PORT_RANGE_END = 8099;\n\nexport async function findFreePort(\n start = PORT_RANGE_START,\n end = PORT_RANGE_END,\n): Promise<number> {\n for (let port = start; port <= end; port++) {\n if (await isFree(port)) return port;\n }\n throw new Error(`Synthra: no free port in ${start}-${end}`);\n}\n\nfunction isFree(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const s = createServer();\n s.once(\"error\", () => resolve(false));\n s.once(\"listening\", () => s.close(() => resolve(true)));\n s.listen(port, \"127.0.0.1\");\n });\n}\n","// Scans the user's Claude Code \"arsenal\" — installed skills, subagents, and MCP\n// servers — across project, personal (~/.claude), and plugin scopes, so the\n// dashboard can show what's available without dropping to the CLI.\n//\n// This reads Claude Code's own on-disk layout (NOT Synthra's graph):\n// skills ~/.claude/skills/<name>/SKILL.md, <project>/.claude/skills/…, plugin skills/\n// agents ~/.claude/agents/*.md, <project>/.claude/agents/*.md, plugin agents/\n// mcp <project>/.mcp.json, ~/.claude.json mcpServers, plugin .mcp.json\n// plugins ~/.claude/plugins/installed_plugins.json (index) + settings.json enabledPlugins\n//\n// Security: MCP configs frequently carry auth headers/env tokens. We emit ONLY\n// name / type / url(query stripped) / command — headers, env, and args are\n// dropped so nothing secret reaches the dashboard.\n\nimport { readFile, readdir } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { basename, dirname, join } from \"node:path\";\n\nexport type ArsenalScope = \"project\" | \"personal\" | \"plugin\";\n\nexport interface ArsenalItem {\n name: string;\n description: string;\n scope: ArsenalScope;\n /** Plugin name when scope === \"plugin\". */\n source?: string;\n /** Plugin items: enabled state from settings.json; undefined = always-on (own files). */\n enabled?: boolean;\n /** Kind-specific extras: agents {tools,model}; skills {argument_hint,user_invocable}; mcp {type,url}. */\n meta?: Record<string, string>;\n}\n\nexport interface ArsenalData {\n skills: ArsenalItem[];\n agents: ArsenalItem[];\n mcp: ArsenalItem[];\n counts: { skills: number; agents: number; mcp: number; plugins: number };\n scanned_at: string;\n}\n\nconst DESC_MAX = 300;\nconst TOOLS_MAX = 200;\n\nasync function readText(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf8\");\n } catch {\n return null;\n }\n}\n\nasync function readJson<T>(path: string): Promise<T | null> {\n const text = await readText(path);\n if (text === null) return null;\n try {\n return JSON.parse(text) as T;\n } catch {\n return null;\n }\n}\n\nasync function listNames(dir: string): Promise<string[]> {\n try {\n return await readdir(dir);\n } catch {\n return [];\n }\n}\n\nfunction clip(s: string, max: number): string {\n const t = s.trim();\n return t.length > max ? `${t.slice(0, max - 1)}…` : t;\n}\n\n/**\n * Minimal YAML-frontmatter reader — no dependency (Synthra stays lean). Pulls\n * the column-0 `key: value` pairs from the leading `--- … ---` block. Supports\n * single-line values and quoted values that span multiple lines (agent\n * `description` blocks do). Nested/indented lines (e.g. under `metadata:`) are\n * ignored. Keys are returned verbatim (e.g. \"argument-hint\").\n */\nexport function parseFrontmatter(md: string): Record<string, string> {\n const m = md.match(/^?\\s*---\\r?\\n([\\s\\S]*?)\\r?\\n---/);\n if (!m) return {};\n const lines = (m[1] ?? \"\").split(/\\r?\\n/);\n const out: Record<string, string> = {};\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n const kv = line.match(/^([A-Za-z][\\w-]*):\\s?(.*)$/); // column-0 keys only\n if (!kv) continue;\n const key = kv[1] ?? \"\";\n if (!key) continue;\n let val = kv[2] ?? \"\";\n // Quoted value that doesn't close on this line → consume until the closer.\n if ((val.startsWith('\"') && !/[^\\\\]\"\\s*$/.test(val.slice(1))) || val === '\"') {\n const buf = [val];\n while (i + 1 < lines.length && !/\"\\s*$/.test(buf[buf.length - 1] ?? \"\")) {\n i += 1;\n buf.push(lines[i] ?? \"\");\n }\n val = buf.join(\" \");\n }\n val = val\n .trim()\n .replace(/^[\"']|[\"']$/g, \"\")\n .trim();\n out[key] = val;\n }\n return out;\n}\n\nfunction skillItem(\n fm: Record<string, string>,\n fallbackName: string,\n scope: ArsenalScope,\n source?: string,\n): ArsenalItem {\n const meta: Record<string, string> = {};\n if (fm[\"argument-hint\"]) meta.argument_hint = fm[\"argument-hint\"];\n if (fm[\"user-invocable\"]) meta.user_invocable = fm[\"user-invocable\"];\n return {\n name: fm.name || fallbackName,\n description: clip(fm.description || \"\", DESC_MAX),\n scope,\n ...(source ? { source } : {}),\n ...(Object.keys(meta).length ? { meta } : {}),\n };\n}\n\nfunction agentItem(\n fm: Record<string, string>,\n fallbackName: string,\n scope: ArsenalScope,\n source?: string,\n): ArsenalItem {\n const meta: Record<string, string> = {};\n if (fm.tools) meta.tools = clip(fm.tools, TOOLS_MAX);\n if (fm.model) meta.model = fm.model;\n return {\n name: fm.name || fallbackName,\n description: clip(fm.description || \"\", DESC_MAX),\n scope,\n ...(source ? { source } : {}),\n ...(Object.keys(meta).length ? { meta } : {}),\n };\n}\n\nasync function scanSkillsDir(\n dir: string,\n scope: ArsenalScope,\n source: string | undefined,\n out: ArsenalItem[],\n): Promise<void> {\n for (const name of await listNames(dir)) {\n const md = await readText(join(dir, name, \"SKILL.md\"));\n if (md === null) continue; // not a skill dir (or broken symlink) — skip\n out.push(skillItem(parseFrontmatter(md), name, scope, source));\n }\n}\n\nasync function scanAgentsDir(\n dir: string,\n scope: ArsenalScope,\n source: string | undefined,\n out: ArsenalItem[],\n): Promise<void> {\n for (const file of await listNames(dir)) {\n if (!file.endsWith(\".md\")) continue;\n const md = await readText(join(dir, file));\n if (md === null) continue;\n out.push(agentItem(parseFrontmatter(md), basename(file, \".md\"), scope, source));\n }\n}\n\n/** Redacted MCP server entries — name/type/url only, never headers/env/args. */\nfunction mcpItemsFrom(\n json: unknown,\n scope: ArsenalScope,\n source: string | undefined,\n): ArsenalItem[] {\n if (!json || typeof json !== \"object\") return [];\n const record = json as Record<string, unknown>;\n // Either { mcpServers: {...} } or a bare { name: {type,url} } map.\n const servers =\n record.mcpServers && typeof record.mcpServers === \"object\"\n ? (record.mcpServers as Record<string, unknown>)\n : record;\n const items: ArsenalItem[] = [];\n for (const [name, raw] of Object.entries(servers)) {\n if (!raw || typeof raw !== \"object\") continue;\n const cfg = raw as Record<string, unknown>;\n const type = typeof cfg.type === \"string\" ? cfg.type : cfg.command ? \"stdio\" : \"http\";\n const url =\n typeof cfg.url === \"string\"\n ? cfg.url.split(\"?\")[0]\n : typeof cfg.command === \"string\"\n ? cfg.command\n : \"\";\n const meta: Record<string, string> = { type };\n if (url) meta.url = url;\n items.push({ name, description: \"\", scope, ...(source ? { source } : {}), meta });\n }\n return items;\n}\n\ninterface InstalledEntry {\n scope?: string;\n installPath?: string;\n version?: string;\n}\n\nconst SCOPE_ORDER: Record<ArsenalScope, number> = { project: 0, personal: 1, plugin: 2 };\n\nfunction sortItems(items: ArsenalItem[]): ArsenalItem[] {\n return items.sort((a, b) => {\n if (a.scope !== b.scope) return SCOPE_ORDER[a.scope] - SCOPE_ORDER[b.scope];\n const sa = a.source ?? \"\";\n const sb = b.source ?? \"\";\n if (sa !== sb) return sa < sb ? -1 : 1;\n return a.name < b.name ? -1 : a.name > b.name ? 1 : 0;\n });\n}\n\nlet cache: { key: string; at: number; data: ArsenalData } | null = null;\nconst CACHE_TTL_MS = 15_000;\n\nexport async function computeArsenal(\n projectRoot: string,\n homeDir = homedir(),\n): Promise<ArsenalData> {\n const key = `${projectRoot}\u0000${homeDir}`;\n const now = Date.now();\n if (cache && cache.key === key && now - cache.at < CACHE_TTL_MS) return cache.data;\n\n const homeClaude = join(homeDir, \".claude\");\n const projClaude = join(projectRoot, \".claude\");\n\n const skills: ArsenalItem[] = [];\n const agents: ArsenalItem[] = [];\n const mcp: ArsenalItem[] = [];\n\n // --- own files: project, then personal ---\n await scanSkillsDir(join(projClaude, \"skills\"), \"project\", undefined, skills);\n await scanSkillsDir(join(homeClaude, \"skills\"), \"personal\", undefined, skills);\n await scanAgentsDir(join(projClaude, \"agents\"), \"project\", undefined, agents);\n await scanAgentsDir(join(homeClaude, \"agents\"), \"personal\", undefined, agents);\n mcp.push(...mcpItemsFrom(await readJson(join(projectRoot, \".mcp.json\")), \"project\", undefined));\n mcp.push(\n ...mcpItemsFrom(\n (await readJson<Record<string, unknown>>(join(homeDir, \".claude.json\")))?.mcpServers,\n \"personal\",\n undefined,\n ),\n );\n\n // --- plugins: installed_plugins.json gives exact installPath per plugin ---\n // installed_plugins.json is `{ version, plugins: { \"<key>\": [entries] } }`\n // (v2); tolerate an older flat `{ \"<key>\": [entries] }` shape too.\n const installedRaw = await readJson<Record<string, unknown>>(\n join(homeClaude, \"plugins\", \"installed_plugins.json\"),\n );\n const pluginsMap = (installedRaw?.plugins ?? installedRaw ?? {}) as Record<\n string,\n InstalledEntry[]\n >;\n const settings = await readJson<{ enabledPlugins?: Record<string, boolean> }>(\n join(homeClaude, \"settings.json\"),\n );\n const enabledMap = settings?.enabledPlugins ?? {};\n let pluginCount = 0;\n for (const [pluginKey, entries] of Object.entries(pluginsMap)) {\n const entry = Array.isArray(entries) ? entries[0] : undefined;\n if (!entry?.installPath) continue;\n pluginCount += 1;\n const pluginName = pluginKey.split(\"@\")[0];\n const enabled = enabledMap[pluginKey] !== false;\n const root = entry.installPath;\n\n // Layouts vary: some plugins keep agents/skills in agents/ + skills/\n // subdirs (feature-dev), others at the plugin root listed in plugin.json\n // (voltagent). Take the UNION of both, deduped by file path.\n const manifest = await readJson<{ agents?: string[]; skills?: string[] }>(\n join(root, \".claude-plugin\", \"plugin.json\"),\n );\n\n const agentFiles = new Set<string>();\n for (const f of await listNames(join(root, \"agents\"))) {\n if (f.endsWith(\".md\")) agentFiles.add(join(root, \"agents\", f));\n }\n for (const rel of manifest?.agents ?? []) agentFiles.add(join(root, rel));\n const pAgents: ArsenalItem[] = [];\n for (const file of agentFiles) {\n const md = await readText(file);\n if (md !== null)\n pAgents.push(agentItem(parseFrontmatter(md), basename(file, \".md\"), \"plugin\", pluginName));\n }\n\n const skillMds = new Set<string>();\n for (const name of await listNames(join(root, \"skills\"))) {\n skillMds.add(join(root, \"skills\", name, \"SKILL.md\"));\n }\n for (const rel of manifest?.skills ?? []) {\n skillMds.add(rel.endsWith(\".md\") ? join(root, rel) : join(root, rel, \"SKILL.md\"));\n }\n const pSkills: ArsenalItem[] = [];\n for (const md of skillMds) {\n const text = await readText(md);\n if (text !== null)\n pSkills.push(\n skillItem(parseFrontmatter(text), basename(dirname(md)), \"plugin\", pluginName),\n );\n }\n\n const pMcp = mcpItemsFrom(await readJson(join(root, \".mcp.json\")), \"plugin\", pluginName);\n for (const it of [...pSkills, ...pAgents, ...pMcp]) it.enabled = enabled;\n skills.push(...pSkills);\n agents.push(...pAgents);\n mcp.push(...pMcp);\n }\n\n // dedupe skills by scope+source+name (symlink/dir overlaps)\n const seen = new Set<string>();\n const dedupedSkills = skills.filter((s) => {\n const k = `${s.scope}:${s.source ?? \"\"}:${s.name}`;\n if (seen.has(k)) return false;\n seen.add(k);\n return true;\n });\n\n const data: ArsenalData = {\n skills: sortItems(dedupedSkills),\n agents: sortItems(agents),\n mcp: sortItems(mcp),\n counts: {\n skills: dedupedSkills.length,\n agents: agents.length,\n mcp: mcp.length,\n plugins: pluginCount,\n },\n scanned_at: new Date(now).toISOString(),\n };\n cache = { key, at: now, data };\n return data;\n}\n","// Reads token_log.jsonl + gate_log.jsonl for the active project AND every\n// project registered in ~/.synthra/projects.json, then computes the\n// dashboard's rendered shape: per-project + global aggregate + recent calls\n// across all projects.\n\nimport { readFile } from \"node:fs/promises\";\n\nimport { readLearnStore } from \"../learn/store.js\";\nimport { effectiveScores, emptyStore, type LearnStore } from \"../learn/usage.js\";\nimport { resolvePaths, type SynthraPaths } from \"../shared/paths.js\";\nimport { estimateCostUsd } from \"../shared/pricing.js\";\nimport { listProjects } from \"../shared/project-registry.js\";\n\nconst AVG_TOKENS_PER_BLOCKED_GREP = 500;\n\nexport interface TokenLogEntry {\n /** Stop-hook-supplied timestamp (preferred). */\n ts?: string;\n /** Server-side fallback added by handleLog when ts isn't provided. */\n written_at?: string;\n input_tokens: number;\n output_tokens: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n model: string;\n description?: string;\n project: string;\n}\n\nexport interface GateLogEntry {\n ts: string;\n tool: string;\n decision: \"allow\" | \"block\";\n query: string | null;\n /** Truncated to ~240 chars in the log; the full block hint lives only in the deny response. */\n reason?: string;\n /** Full length of the block hint delivered to the agent (v0.4.0+). */\n hint_chars?: number;\n}\n\nexport interface ToolLogEntry {\n ts?: string;\n /** Synthra MCP tool name, e.g. \"graph_continue\", \"graph_read\". */\n tool: string;\n}\n\n/** Count Synthra MCP tool calls by tool name. (#2) */\nexport function countToolCalls(entries: ToolLogEntry[]): Record<string, number> {\n const out: Record<string, number> = {};\n for (const e of entries) {\n if (!e.tool) continue;\n out[e.tool] = (out[e.tool] ?? 0) + 1;\n }\n return out;\n}\n\nexport interface HotFile {\n path: string;\n score: number;\n}\n\n/** Top files by current (decayed-to-now) usage weight — surfaces what the\n * usage-learning layer has learned this repo leans on. Ranked by effective\n * score so recency matters; score rounded for display. */\nexport function topHotFiles(store: LearnStore, nowMs: number, limit = 8): HotFile[] {\n return [...effectiveScores(store, nowMs).entries()]\n .map(([path, score]) => ({ path, score: Math.round(score * 10) / 10 }))\n .sort((a, b) => b.score - a.score)\n .slice(0, limit);\n}\n\nexport interface ProjectStats {\n path: string;\n name: string;\n last_seen: string | null;\n total_turns: number;\n total_input_tokens: number;\n total_output_tokens: number;\n total_cache_read: number;\n total_cache_create: number;\n total_gate_calls: number;\n blocked_count: number;\n estimated_tokens_saved: number;\n estimated_cost_usd: number;\n total_tool_calls: number;\n tool_calls: Record<string, number>;\n hot_files: HotFile[];\n hot_files_total: number;\n models: Record<string, number>;\n}\n\nexport interface RecentTurn {\n ts: string;\n project_name: string;\n project_path: string;\n input: number;\n output: number;\n cache_read: number;\n cache_create: number;\n model: string;\n cost_usd: number;\n}\n\nexport interface RecentGate {\n ts: string;\n project_name: string;\n project_path: string;\n tool: string;\n decision: \"allow\" | \"block\";\n query: string | null;\n}\n\nexport interface DashboardData {\n active: {\n project_root: string;\n project_name: string;\n stats: ProjectStats;\n };\n global: {\n project_count: number;\n total_turns: number;\n total_input_tokens: number;\n total_output_tokens: number;\n total_cache_read: number;\n total_cache_create: number;\n total_gate_calls: number;\n blocked_count: number;\n estimated_tokens_saved: number;\n saved_percent: number;\n estimated_cost_usd: number;\n total_tool_calls: number;\n tool_calls: Record<string, number>;\n };\n projects: ProjectStats[];\n recent_turns: RecentTurn[];\n recent_gates: RecentGate[];\n}\n\nasync function readJsonl<T>(path: string): Promise<T[]> {\n try {\n const text = await readFile(path, \"utf8\");\n return text\n .split(/\\r?\\n/)\n .filter((l) => l.length > 0)\n .map((l) => {\n try {\n return JSON.parse(l) as T;\n } catch {\n return null;\n }\n })\n .filter((v): v is T => v !== null);\n } catch {\n return [];\n }\n}\n\nfunction basename(p: string): string {\n const parts = p.split(/[\\\\/]/);\n return parts[parts.length - 1] || p;\n}\n\ninterface ProjectFiles {\n path: string;\n name: string;\n last_seen: string | null;\n tokens: TokenLogEntry[];\n gates: GateLogEntry[];\n tools: ToolLogEntry[];\n learn: LearnStore;\n}\n\nfunction summarize(p: ProjectFiles): ProjectStats {\n let totalIn = 0;\n let totalOut = 0;\n let totalCacheRead = 0;\n let totalCacheCreate = 0;\n let costUsd = 0;\n const models: Record<string, number> = {};\n\n for (const t of p.tokens) {\n totalIn += t.input_tokens ?? 0;\n totalOut += t.output_tokens ?? 0;\n totalCacheRead += t.cache_read_input_tokens ?? 0;\n totalCacheCreate += t.cache_creation_input_tokens ?? 0;\n costUsd += estimateCostUsd(t);\n if (t.model) models[t.model] = (models[t.model] ?? 0) + 1;\n }\n\n const blocked = p.gates.filter((g) => g.decision === \"block\").length;\n const saved = blocked * AVG_TOKENS_PER_BLOCKED_GREP;\n const now = Date.now();\n\n return {\n path: p.path,\n name: p.name,\n last_seen: p.last_seen,\n total_turns: p.tokens.length,\n total_input_tokens: totalIn,\n total_output_tokens: totalOut,\n total_cache_read: totalCacheRead,\n total_cache_create: totalCacheCreate,\n total_gate_calls: p.gates.length,\n blocked_count: blocked,\n estimated_tokens_saved: saved,\n estimated_cost_usd: Math.round(costUsd * 100) / 100,\n total_tool_calls: p.tools.length,\n tool_calls: countToolCalls(p.tools),\n hot_files: topHotFiles(p.learn, now),\n hot_files_total: effectiveScores(p.learn, now).size,\n models,\n };\n}\n\n// Dedupe is ON by default; set SYN_DASHBOARD_DEDUPE=0 (or \"off\"/\"false\") to see\n// every raw token-log entry — including duplicates a co-installed AI tool's Stop\n// hook may write to the same token_log.jsonl. (#7)\nfunction dedupeEnabled(): boolean {\n const v = process.env.SYN_DASHBOARD_DEDUPE;\n return v !== \"0\" && v !== \"off\" && v !== \"false\";\n}\n\nasync function loadProjectFiles(\n path: string,\n name: string,\n lastSeen: string | null,\n): Promise<ProjectFiles> {\n const paths = resolvePaths(path);\n const [rawTokens, gates, tools, learn] = await Promise.all([\n readJsonl<TokenLogEntry>(paths.tokenLog),\n readJsonl<GateLogEntry>(paths.gateLog),\n readJsonl<ToolLogEntry>(paths.toolLog),\n readLearnStore(paths.learnStore),\n ]);\n const tokens = dedupeEnabled() ? dedupeTokens(rawTokens) : rawTokens;\n return { path, name, last_seen: lastSeen, tokens, gates, tools, learn };\n}\n\n/**\n * Collapse duplicate token-log entries from co-installed AI tools.\n *\n * Synthra is friendly with other tools that share the .synthra-graph/\n * token_log.jsonl shape — if a second tool's Stop hook also writes to\n * it, both fire on the same turn and emit nearly-identical entries\n * within ~10ms, double-counting every metric in the dashboard.\n *\n * Strategy: group by (project, usage counts, second-rounded timestamp);\n * inside a group, keep the entry with the most credible model field —\n * a real Claude model > \"<synthetic>\" > empty.\n */\nfunction dedupeTokens(entries: TokenLogEntry[]): TokenLogEntry[] {\n const score = (model: string | undefined): number => {\n if (!model) return 0;\n if (model === \"<synthetic>\") return 1;\n return 2; // real model name\n };\n\n const groups = new Map<string, TokenLogEntry[]>();\n for (const e of entries) {\n const ts = e.ts ?? e.written_at ?? \"\";\n const second = ts.slice(0, 19); // YYYY-MM-DDTHH:mm:ss\n const key = [\n e.project ?? \"\",\n e.input_tokens ?? 0,\n e.output_tokens ?? 0,\n e.cache_creation_input_tokens ?? 0,\n e.cache_read_input_tokens ?? 0,\n second,\n ].join(\"|\");\n const arr = groups.get(key) ?? [];\n arr.push(e);\n groups.set(key, arr);\n }\n\n const out: TokenLogEntry[] = [];\n for (const arr of groups.values()) {\n if (arr.length === 1) {\n out.push(arr[0]!);\n continue;\n }\n arr.sort((a, b) => score(b.model) - score(a.model));\n out.push(arr[0]!);\n }\n\n // Preserve chronological order in the per-project list.\n out.sort((a, b) => {\n const at = a.ts ?? a.written_at ?? \"\";\n const bt = b.ts ?? b.written_at ?? \"\";\n return at.localeCompare(bt);\n });\n return out;\n}\n\nexport async function computeDashboardData(\n activePaths: SynthraPaths,\n recentN = 500,\n): Promise<DashboardData> {\n const registered = await listProjects();\n\n // Always include the active project, even if not yet in the registry.\n const activePath = activePaths.projectRoot;\n const activeName = basename(activePath);\n const knownPaths = new Set(registered.map((p) => p.path));\n const allEntries: Array<{ path: string; name: string; last_seen: string | null }> = [\n ...registered.map((p) => ({ path: p.path, name: p.name, last_seen: p.last_seen })),\n ];\n if (!knownPaths.has(activePath)) {\n allEntries.unshift({ path: activePath, name: activeName, last_seen: null });\n }\n\n const loaded = await Promise.all(\n allEntries.map((e) => loadProjectFiles(e.path, e.name, e.last_seen)),\n );\n\n const projects = loaded\n .map(summarize)\n .sort(\n (a, b) =>\n b.total_input_tokens +\n b.total_output_tokens -\n (a.total_input_tokens + a.total_output_tokens),\n );\n\n const activeFiles = loaded.find((p) => p.path === activePath) ?? {\n path: activePath,\n name: activeName,\n last_seen: null,\n tokens: [],\n gates: [],\n tools: [],\n learn: emptyStore(),\n };\n const activeStats = summarize(activeFiles);\n\n // Global aggregates\n let g_in = 0,\n g_out = 0,\n g_cr = 0,\n g_cc = 0,\n g_gate = 0,\n g_block = 0,\n g_cost = 0,\n g_turns = 0,\n g_tools = 0;\n const g_tool_calls: Record<string, number> = {};\n for (const s of projects) {\n g_turns += s.total_turns;\n g_in += s.total_input_tokens;\n g_out += s.total_output_tokens;\n g_cr += s.total_cache_read;\n g_cc += s.total_cache_create;\n g_gate += s.total_gate_calls;\n g_block += s.blocked_count;\n g_cost += s.estimated_cost_usd;\n g_tools += s.total_tool_calls;\n for (const [k, v] of Object.entries(s.tool_calls)) g_tool_calls[k] = (g_tool_calls[k] ?? 0) + v;\n }\n const g_saved = g_block * AVG_TOKENS_PER_BLOCKED_GREP;\n const g_used = g_in + g_out + g_cc;\n const g_saved_pct = g_used + g_saved > 0 ? (g_saved / (g_used + g_saved)) * 100 : 0;\n\n // Recent turns + gates across all projects, sorted by ts descending\n const allTurns: RecentTurn[] = [];\n const allGates: RecentGate[] = [];\n for (const p of loaded) {\n for (const t of p.tokens) {\n allTurns.push({\n // Fall back to written_at — the Stop hook today posts entries without\n // a `ts` field, and the server tags them with written_at on receive.\n ts: t.ts ?? t.written_at ?? \"\",\n project_name: p.name,\n project_path: p.path,\n input: t.input_tokens ?? 0,\n output: t.output_tokens ?? 0,\n cache_read: t.cache_read_input_tokens ?? 0,\n cache_create: t.cache_creation_input_tokens ?? 0,\n model: t.model ?? \"\",\n cost_usd: Math.round(estimateCostUsd(t) * 1000) / 1000,\n });\n }\n for (const gate of p.gates) {\n allGates.push({\n ts: gate.ts,\n project_name: p.name,\n project_path: p.path,\n tool: gate.tool,\n decision: gate.decision,\n query: gate.query,\n });\n }\n }\n allTurns.sort((a, b) => (a.ts < b.ts ? 1 : a.ts > b.ts ? -1 : 0));\n allGates.sort((a, b) => (a.ts < b.ts ? 1 : a.ts > b.ts ? -1 : 0));\n\n return {\n active: {\n project_root: activePath,\n project_name: activeName,\n stats: activeStats,\n },\n global: {\n project_count: projects.length,\n total_turns: g_turns,\n total_input_tokens: g_in,\n total_output_tokens: g_out,\n total_cache_read: g_cr,\n total_cache_create: g_cc,\n total_gate_calls: g_gate,\n blocked_count: g_block,\n estimated_tokens_saved: g_saved,\n saved_percent: Math.round(g_saved_pct * 10) / 10,\n estimated_cost_usd: Math.round(g_cost * 100) / 100,\n total_tool_calls: g_tools,\n tool_calls: g_tool_calls,\n },\n projects,\n recent_turns: allTurns.slice(0, recentN),\n recent_gates: allGates.slice(0, recentN),\n };\n}\n\n// Legacy shapes from the M2 stub — kept for compat.\nexport interface TurnBreakdown {\n systemPromptTokens: number;\n conversationHistoryTokens: number;\n synthraPackTokens: number;\n userMessageTokens: number;\n responseTokens: number;\n totalTokens: number;\n costUsd: number;\n}\n\nexport interface SavingsDelta {\n withSynthra: TurnBreakdown;\n estimatedWithoutSynthra: TurnBreakdown;\n savedUsd: number;\n savedPercent: number;\n}\n\nexport function computeDelta(breakdown: TurnBreakdown, blockedGreps: number): SavingsDelta {\n const savedTokens = blockedGreps * AVG_TOKENS_PER_BLOCKED_GREP;\n const without: TurnBreakdown = {\n ...breakdown,\n conversationHistoryTokens: breakdown.conversationHistoryTokens + savedTokens,\n totalTokens: breakdown.totalTokens + savedTokens,\n costUsd: breakdown.costUsd + (savedTokens / 1_000_000) * 3,\n };\n const savedUsd = without.costUsd - breakdown.costUsd;\n const savedPercent = without.totalTokens > 0 ? (savedTokens / without.totalTokens) * 100 : 0;\n return {\n withSynthra: breakdown,\n estimatedWithoutSynthra: without,\n savedUsd,\n savedPercent: Math.round(savedPercent * 10) / 10,\n };\n}\n","// I/O for the usage-learning layer. Two files, both in .synthra-graph/\n// (gitignored, machine-local — usage is per-developer):\n// - access_log.jsonl : append-only raw events (source of truth, replayable)\n// - learn_store.json : derived decayed aggregate (a cache of the log)\n//\n// Every read is best-effort: a missing / corrupt / schema-mismatched file yields\n// an empty store, so the ranker degrades to its deterministic behavior.\n\nimport { appendFile, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { emptyStore, LEARN_SCHEMA_VERSION, type AccessEvent, type LearnStore } from \"./usage.js\";\n\nexport async function readLearnStore(path: string): Promise<LearnStore> {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<LearnStore>;\n if (\n parsed.schema_version !== LEARN_SCHEMA_VERSION ||\n typeof parsed.files !== \"object\" ||\n parsed.files === null\n ) {\n return emptyStore();\n }\n return {\n schema_version: LEARN_SCHEMA_VERSION,\n asOf: typeof parsed.asOf === \"string\" ? parsed.asOf : emptyStore().asOf,\n files: parsed.files as LearnStore[\"files\"],\n };\n } catch {\n return emptyStore();\n }\n}\n\nexport async function writeLearnStore(path: string, store: LearnStore): Promise<void> {\n try {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, JSON.stringify(store, null, 2) + \"\\n\", \"utf8\");\n } catch {\n // Persistence is best-effort; the log remains the source of truth.\n }\n}\n\nexport async function readAccessLog(path: string): Promise<AccessEvent[]> {\n try {\n const raw = await readFile(path, \"utf8\");\n const out: AccessEvent[] = [];\n for (const line of raw.split(\"\\n\")) {\n const t = line.trim();\n if (!t) continue;\n try {\n const ev = JSON.parse(t) as AccessEvent;\n if (\n ev &&\n typeof ev.ts === \"string\" &&\n typeof ev.path === \"string\" &&\n typeof ev.source === \"string\"\n ) {\n out.push(ev);\n }\n } catch {\n // Skip a malformed line rather than failing the whole replay.\n }\n }\n return out;\n } catch {\n return [];\n }\n}\n\nexport async function appendAccess(path: string, ev: AccessEvent): Promise<void> {\n try {\n await mkdir(dirname(path), { recursive: true });\n await appendFile(path, JSON.stringify(ev) + \"\\n\", \"utf8\");\n } catch {\n // Best-effort; never fail a tool call over telemetry.\n }\n}\n","// Pure decay/aggregate core for the usage-learning signal (\"the more it's used,\n// the smarter it gets\"). No I/O here — persistence + the raw access log live in\n// store.ts, and the stateful wrapper in runtime.ts.\n//\n// Files the AI actually pulls (graph_read) or edits (graph_register_edit) accrue\n// a time-decayed weight. retrieve() applies a bounded, capped boost so genuinely\n// \"hot\" files surface first — never dominating the deterministic ranker.\n\nexport type AccessSource = \"read\" | \"register_edit\" | \"continue\";\n\nexport interface AccessEvent {\n ts: string; // ISO timestamp\n path: string; // canonical FileNode.path (\"\" for source === \"continue\")\n source: AccessSource;\n query?: string; // only set for source === \"continue\" — reserved fuel for v2/v3\n}\n\nexport interface FileStat {\n /** Raw access count (never decayed) — diagnostic only. */\n count: number;\n /** Decayed weight as of `lastTs`. */\n decayed: number;\n /** ISO timestamp of the most recent folded event. */\n lastTs: string;\n}\n\nexport interface LearnStore {\n schema_version: number;\n asOf: string;\n files: Record<string, FileStat>;\n}\n\nexport const LEARN_SCHEMA_VERSION = 1;\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\n/** Usage-decay half-life. Env-overridable for dogfood tuning. */\nexport function halfLifeMs(): number {\n const env = Number(process.env.SYN_LEARN_HALFLIFE_DAYS);\n const days = Number.isFinite(env) && env > 0 ? env : 7;\n return days * DAY_MS;\n}\n\n/** Per-source accrual weight. `continue` never contributes to frequency — it's\n * logged only as query→outcome fuel for a future mechanism. */\nexport function weightFor(source: AccessSource): number {\n switch (source) {\n case \"register_edit\":\n return 2;\n case \"read\":\n return 1;\n default:\n return 0;\n }\n}\n\nexport function emptyStore(): LearnStore {\n return {\n schema_version: LEARN_SCHEMA_VERSION,\n asOf: new Date(0).toISOString(),\n files: {},\n };\n}\n\n/** exp(-λ·Δt) decay multiplier from `fromTs` forward to `toMs` epoch ms. */\nfunction decayFactor(fromTs: string, toMs: number, hl: number): number {\n const fromMs = Date.parse(fromTs);\n if (!Number.isFinite(fromMs)) return 1;\n const dt = toMs - fromMs;\n if (dt <= 0) return 1;\n return Math.exp(-(Math.LN2 / hl) * dt);\n}\n\n/** Fold one access event into the store: decay the file's prior weight up to the\n * event's timestamp, then add the event weight. Mutates and returns `store`.\n * Zero-weight (`continue`) and path-less events are ignored. Malformed\n * timestamps are dropped so the function stays deterministic. */\nexport function foldEvent(store: LearnStore, ev: AccessEvent): LearnStore {\n const w = weightFor(ev.source);\n if (w <= 0 || !ev.path) return store;\n const tMs = Date.parse(ev.ts);\n if (!Number.isFinite(tMs)) return store;\n\n const hl = halfLifeMs();\n const prev = store.files[ev.path];\n if (prev) {\n const decayed = prev.decayed * decayFactor(prev.lastTs, tMs, hl) + w;\n store.files[ev.path] = { count: prev.count + 1, decayed, lastTs: ev.ts };\n } else {\n store.files[ev.path] = { count: 1, decayed: w, lastTs: ev.ts };\n }\n return store;\n}\n\n/** Decayed weights as of `nowMs`, keyed by path. Effectively-zero entries are\n * omitted so an old/cold store contributes nothing. */\nexport function effectiveScores(store: LearnStore, nowMs: number): Map<string, number> {\n const hl = halfLifeMs();\n const out = new Map<string, number>();\n for (const [path, stat] of Object.entries(store.files)) {\n const eff = stat.decayed * decayFactor(stat.lastTs, nowMs, hl);\n if (eff > 0.01) out.set(path, eff);\n }\n return out;\n}\n\n/** Rebuild a store by replaying a raw access-log stream (the source of truth). */\nexport function recomputeFromLog(events: AccessEvent[]): LearnStore {\n const store = emptyStore();\n for (const ev of events) foldEvent(store, ev);\n return store;\n}\n","// Resolves Synthra's storage locations inside a project root.\n\nimport { join } from \"node:path\";\n\nexport interface SynthraPaths {\n projectRoot: string;\n graphDir: string;\n contextDir: string;\n infoGraph: string;\n symbolIndex: string;\n sessionState: string;\n activityLog: string;\n tokenLog: string;\n gateLog: string;\n toolLog: string;\n accessLog: string;\n learnStore: string;\n parseCache: string;\n mcpPort: string;\n mcpServerLog: string;\n mcpServerErrLog: string;\n contextStore: string;\n contextMd: string;\n branchesDir: string;\n claudeDir: string;\n claudeSettings: string;\n claudeHooksDir: string;\n claudeMd: string;\n gitignore: string;\n}\n\nexport function resolvePaths(projectRoot: string): SynthraPaths {\n const graphDir = join(projectRoot, \".synthra-graph\");\n const contextDir = join(projectRoot, \".synthra\");\n const claudeDir = join(projectRoot, \".claude\");\n\n return {\n projectRoot,\n graphDir,\n contextDir,\n infoGraph: join(graphDir, \"info_graph.json\"),\n symbolIndex: join(graphDir, \"symbol_index.json\"),\n sessionState: join(graphDir, \"session.json\"),\n activityLog: join(graphDir, \"activity.jsonl\"),\n tokenLog: join(graphDir, \"token_log.jsonl\"),\n gateLog: join(graphDir, \"gate_log.jsonl\"),\n toolLog: join(graphDir, \"tool_log.jsonl\"),\n accessLog: join(graphDir, \"access_log.jsonl\"),\n learnStore: join(graphDir, \"learn_store.json\"),\n parseCache: join(graphDir, \"parse_cache.json\"),\n mcpPort: join(graphDir, \"mcp_port\"),\n mcpServerLog: join(graphDir, \"mcp_server.log\"),\n mcpServerErrLog: join(graphDir, \"mcp_server.err.log\"),\n contextStore: join(contextDir, \"context-store.json\"),\n contextMd: join(contextDir, \"CONTEXT.md\"),\n branchesDir: join(contextDir, \"branches\"),\n claudeDir,\n claudeSettings: join(claudeDir, \"settings.local.json\"),\n claudeHooksDir: join(claudeDir, \"hooks\"),\n claudeMd: join(projectRoot, \"CLAUDE.md\"),\n gitignore: join(projectRoot, \".gitignore\"),\n };\n}\n","// Approximate per-million-token pricing for Claude models, in USD.\n// Sourced from Anthropic's published rates. Tilde everywhere — these can shift.\n//\n// Used only for the dashboard's \"~$X\" estimate; not for billing.\n\nexport interface ModelPricing {\n /** Cost per 1M raw-input tokens. */\n input: number;\n /** Cost per 1M output tokens. */\n output: number;\n /** Cost per 1M cache-read tokens (typically ~10% of input). */\n cacheRead: number;\n /** Cost per 1M cache-creation tokens (typically input × 1.25). */\n cacheCreate: number;\n}\n\nconst PRICING: Record<string, ModelPricing> = {\n // Fable-class — frontier tier (same 0.1× cache-read / 1.25× cache-write\n // multipliers as the rest of the lineup, on a $10 input base)\n \"claude-fable-5\": { input: 10, output: 50, cacheRead: 1, cacheCreate: 12.5 },\n // Opus-class models — premium tier\n \"claude-opus-4-7\": { input: 15, output: 75, cacheRead: 1.5, cacheCreate: 18.75 },\n \"claude-opus-4-6\": { input: 15, output: 75, cacheRead: 1.5, cacheCreate: 18.75 },\n \"claude-opus-4-5\": { input: 15, output: 75, cacheRead: 1.5, cacheCreate: 18.75 },\n // Sonnet-class — workhorse\n \"claude-sonnet-4-6\": { input: 3, output: 15, cacheRead: 0.3, cacheCreate: 3.75 },\n \"claude-sonnet-4-5\": { input: 3, output: 15, cacheRead: 0.3, cacheCreate: 3.75 },\n // Haiku-class — fast and cheap\n \"claude-haiku-4-5\": { input: 1, output: 5, cacheRead: 0.1, cacheCreate: 1.25 },\n};\n\nconst FALLBACK: ModelPricing = { input: 3, output: 15, cacheRead: 0.3, cacheCreate: 3.75 };\n\nexport function pricingFor(model: string | undefined | null): ModelPricing {\n if (!model) return FALLBACK;\n const direct = PRICING[model];\n if (direct) return direct;\n // Loose prefix match: \"claude-fable-…\" (incl. the \"[1m]\" long-context\n // variant) / \"claude-opus-…\" / \"claude-sonnet-…\" / \"claude-haiku-…\"\n if (model.includes(\"fable\")) return PRICING[\"claude-fable-5\"] ?? FALLBACK;\n if (model.includes(\"opus\")) return PRICING[\"claude-opus-4-7\"] ?? FALLBACK;\n if (model.includes(\"sonnet\")) return PRICING[\"claude-sonnet-4-6\"] ?? FALLBACK;\n if (model.includes(\"haiku\")) return PRICING[\"claude-haiku-4-5\"] ?? FALLBACK;\n return FALLBACK;\n}\n\nexport interface UsageRecord {\n input_tokens: number;\n output_tokens: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n model?: string;\n}\n\n/** Approximate USD cost of a single usage record. */\nexport function estimateCostUsd(usage: UsageRecord): number {\n const p = pricingFor(usage.model);\n return (\n (usage.input_tokens / 1_000_000) * p.input +\n (usage.output_tokens / 1_000_000) * p.output +\n ((usage.cache_read_input_tokens ?? 0) / 1_000_000) * p.cacheRead +\n ((usage.cache_creation_input_tokens ?? 0) / 1_000_000) * p.cacheCreate\n );\n}\n","// Global registry of projects that have run `syn .` on this machine.\n// Stored at ~/.synthra/projects.json so the dashboard can enumerate them\n// without walking the filesystem.\n\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { basename, dirname, join } from \"node:path\";\n\nconst REGISTRY_DIR = join(homedir(), \".synthra\");\nconst REGISTRY_PATH = join(REGISTRY_DIR, \"projects.json\");\nconst SCHEMA_VERSION = 1;\n\nexport interface ProjectRegistryEntry {\n path: string; // absolute project root\n name: string; // basename for display\n first_seen: string; // ISO timestamp\n last_seen: string; // ISO timestamp\n}\n\ninterface Registry {\n schema_version: number;\n projects: ProjectRegistryEntry[];\n}\n\nasync function readRegistry(): Promise<Registry> {\n try {\n const raw = await readFile(REGISTRY_PATH, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<Registry>;\n if (!Array.isArray(parsed.projects)) return { schema_version: SCHEMA_VERSION, projects: [] };\n return { schema_version: parsed.schema_version ?? SCHEMA_VERSION, projects: parsed.projects };\n } catch {\n return { schema_version: SCHEMA_VERSION, projects: [] };\n }\n}\n\nasync function writeRegistry(registry: Registry): Promise<void> {\n await mkdir(dirname(REGISTRY_PATH), { recursive: true });\n await writeFile(REGISTRY_PATH, JSON.stringify(registry, null, 2) + \"\\n\", \"utf8\");\n}\n\n/** Upsert this project's entry. Updates `last_seen`; preserves `first_seen`. */\nexport async function recordProject(projectRoot: string): Promise<void> {\n const now = new Date().toISOString();\n const registry = await readRegistry();\n const existing = registry.projects.find((p) => p.path === projectRoot);\n if (existing) {\n existing.last_seen = now;\n existing.name = basename(projectRoot);\n } else {\n registry.projects.push({\n path: projectRoot,\n name: basename(projectRoot),\n first_seen: now,\n last_seen: now,\n });\n }\n try {\n await writeRegistry(registry);\n } catch {\n // Registry is best-effort — a write failure shouldn't block the session.\n }\n}\n\nexport async function listProjects(): Promise<ProjectRegistryEntry[]> {\n const registry = await readRegistry();\n // Sort by last_seen descending so the most active project surfaces first.\n return registry.projects\n .slice()\n .sort((a, b) => (a.last_seen > b.last_seen ? -1 : a.last_seen < b.last_seen ? 1 : 0));\n}\n\nexport { REGISTRY_PATH, REGISTRY_DIR };\n","<!doctype html>\n<html lang=\"en\" class=\"dark\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Synthra · Dashboard</title>\n <link rel=\"icon\" href=\"/favicon.svg\" type=\"image/svg+xml\" />\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n <link\n href=\"https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600;700&family=Geist+Mono:wght@400;500&display=swap\"\n rel=\"stylesheet\"\n />\n <script type=\"module\" crossorigin>(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel=\"modulepreload\"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var e=Array.isArray,t=Array.prototype.indexOf,n=Array.prototype.includes,r=Array.from,i=Object.defineProperty,a=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyDescriptors,s=Object.prototype,c=Array.prototype,l=Object.getPrototypeOf,u=Object.isExtensible;function d(e){return typeof e==`function`}var f=()=>{};function p(e){for(var t=0;t<e.length;t++)e[t]()}function m(){var e,t;return{promise:new Promise((n,r)=>{e=n,t=r}),resolve:e,reject:t}}function h(e,t){if(Array.isArray(e))return e;if(t===void 0||!(Symbol.iterator in e))return Array.from(e);let n=[];for(let r of e)if(n.push(r),n.length===t)break;return n}var g=1<<24,_=1024,v=2048,y=4096,b=8192,ee=16384,x=32768,te=1<<25,ne=65536,re=1<<19,ie=1<<20,ae=1<<25,oe=65536,se=1<<21,ce=1<<22,le=1<<23,ue=Symbol(`$state`),de=Symbol(`legacy props`),fe=Symbol(``),pe=Symbol(`attributes`),me=Symbol(`class`),he=Symbol(`style`),ge=Symbol(`text`),_e=Symbol(`form reset`),ve=new class extends Error{name=`StaleReactionError`;message=\"The reaction that called `getAbortSignal()` was re-run or destroyed\"},ye=!!globalThis.document?.contentType&&globalThis.document.contentType.includes(`xml`);function be(e){throw Error(`https://svelte.dev/e/lifecycle_outside_component`)}function xe(){throw Error(`https://svelte.dev/e/async_derived_orphan`)}function Se(e,t,n){throw Error(`https://svelte.dev/e/each_key_duplicate`)}function Ce(e){throw Error(`https://svelte.dev/e/effect_in_teardown`)}function we(){throw Error(`https://svelte.dev/e/effect_in_unowned_derived`)}function Te(e){throw Error(`https://svelte.dev/e/effect_orphan`)}function Ee(){throw Error(`https://svelte.dev/e/effect_update_depth_exceeded`)}function De(e){throw Error(`https://svelte.dev/e/props_invalid_value`)}function Oe(){throw Error(`https://svelte.dev/e/set_context_after_init`)}function ke(){throw Error(`https://svelte.dev/e/state_descriptors_fixed`)}function Ae(){throw Error(`https://svelte.dev/e/state_prototype_fixed`)}function je(){throw Error(`https://svelte.dev/e/state_unsafe_mutation`)}function Me(){throw Error(`https://svelte.dev/e/svelte_boundary_reset_onerror`)}var Ne={},S=Symbol(`uninitialized`),Pe=`http://www.w3.org/1999/xhtml`,Fe=`http://www.w3.org/2000/svg`,Ie=`@attach`;function Le(){console.warn(`https://svelte.dev/e/derived_inert`)}function Re(e){console.warn(`https://svelte.dev/e/hydration_mismatch`)}function ze(){console.warn(`https://svelte.dev/e/select_multiple_invalid_value`)}function Be(){console.warn(`https://svelte.dev/e/svelte_boundary_reset_noop`)}var C=!1;function Ve(e){C=e}var w;function T(e){if(e===null)throw Re(),Ne;return w=e}function He(){return T(Cn(w))}function E(e){if(C){if(Cn(w)!==null)throw Re(),Ne;w=e}}function Ue(e=1){if(C){for(var t=e,n=w;t--;)n=Cn(n);w=n}}function We(e=!0){for(var t=0,n=w;;){if(n.nodeType===8){var r=n.data;if(r===`]`){if(t===0)return n;--t}else (r===`[`||r===`[!`||r[0]===`[`&&!isNaN(Number(r.slice(1))))&&(t+=1)}var i=Cn(n);e&&n.remove(),n=i}}function Ge(e){if(!e||e.nodeType!==8)throw Re(),Ne;return e.data}function Ke(e){return e===this.v}function qe(e,t){return e==e?e!==t||typeof e==`object`&&!!e||typeof e==`function`:t==t}function Je(e){return!qe(e,this.v)}var Ye=!1,Xe=!1;function Ze(){Xe=!0}var D=null;function Qe(e){D=e}function $e(e){return it(`getContext`).get(e)}function et(e,t){let n=it(`setContext`);if(Ye){var r=V.f;!B&&r&32&&!D.i||Oe()}return n.set(e,t),t}function tt(e){return it(`hasContext`).has(e)}function nt(){return it(`getAllContexts`)}function O(e,t=!1,n){D={p:D,i:!1,c:null,e:null,s:e,x:null,r:V,l:Xe&&!t?{s:null,u:null,$:[]}:null}}function k(e){var t=D,n=t.e;if(n!==null){t.e=null;for(var r of n)zn(r)}return e!==void 0&&(t.x=e),t.i=!0,D=t.p,e??{}}function rt(){return!Xe||D!==null&&D.l===null}function it(e){return D===null&&be(e),D.c??=new Map(at(D)||void 0)}function at(e){let t=e.p;for(;t!==null;){let e=t.c;if(e!==null)return e;t=t.p}return null}var ot=[];function st(){var e=ot;ot=[],p(e)}function ct(e){if(ot.length===0&&!Vt){var t=ot;queueMicrotask(()=>{t===ot&&st()})}ot.push(e)}function lt(){for(;ot.length>0;)st()}function ut(e){var t=V;if(t===null)return B.f|=le,e;if(!(t.f&32768)&&!(t.f&4))throw e;dt(e,t)}function dt(e,t){if(!(t!==null&&t.f&16384)){for(;t!==null;){if(t.f&128){if(!(t.f&32768))throw e;try{t.b.error(e);return}catch(t){e=t}}t=t.parent}throw e}}var ft=~(v|y|_);function A(e,t){e.f=e.f&ft|t}function pt(e){e.f&512||e.deps===null?A(e,_):A(e,y)}function mt(e){if(e!==null)for(let t of e)!(t.f&2)||!(t.f&65536)||(t.f^=oe,mt(t.deps))}function ht(e,t,n){e.f&2048?t.add(e):e.f&4096&&n.add(e),mt(e.deps),A(e,_)}var gt=!1,_t=!1;function vt(e){var t=_t;try{return _t=!1,[e(),_t]}finally{_t=t}}function yt(e){let t=0,n=sn(0),r;return()=>{In()&&(H(n),Gn(()=>(t===0&&(r=Mr(()=>e(()=>dn(n)))),t+=1,()=>{ct(()=>{--t,t===0&&(r?.(),r=void 0,dn(n))})})))}}var bt=ne|re;function xt(e,t,n,r){new St(e,t,n,r)}var St=class{parent;is_pending=!1;transform_error;#e;#t=C?w:null;#n;#r;#i;#a=null;#o=null;#s=null;#c=null;#l=0;#u=0;#d=!1;#f=new Set;#p=new Set;#m=null;#h=yt(()=>(this.#m=sn(this.#l),()=>{this.#m=null}));constructor(e,t,n,r){this.#e=e,this.#n=t,this.#r=e=>{var t=V;t.b=this,t.f|=128,n(e)},this.parent=V.b,this.transform_error=r??this.parent?.transform_error??(e=>e),this.#i=Kn(()=>{if(C){let e=this.#t;He();let t=e.data===`[!`;if(e.data.startsWith(`[?`)){let t=JSON.parse(e.data.slice(2));this.#_(t)}else t?this.#v():this.#g()}else this.#y()},bt),C&&(this.#e=w)}#g(){try{this.#a=Jn(()=>this.#r(this.#e))}catch(e){this.error(e)}}#_(e){let t=this.#n.failed;t&&(this.#s=Jn(()=>{t(this.#e,()=>e,()=>()=>{})}))}#v(){let e=this.#n.pending;e&&(this.is_pending=!0,this.#o=Jn(()=>e(this.#e)),ct(()=>{var e=this.#c=document.createDocumentFragment(),t=xn();e.append(t),this.#a=this.#x(()=>Jn(()=>this.#r(t))),this.#u===0&&(this.#e.before(e),this.#c=null,er(this.#o,()=>{this.#o=null}),this.#b(M))}))}#y(){try{if(this.is_pending=this.has_pending_snippet(),this.#u=0,this.#l=0,this.#a=Jn(()=>{this.#r(this.#e)}),this.#u>0){var e=this.#c=document.createDocumentFragment();ir(this.#a,e);let t=this.#n.pending;this.#o=Jn(()=>t(this.#e))}else this.#b(M)}catch(e){this.error(e)}}#b(e){this.is_pending=!1,e.transfer_effects(this.#f,this.#p)}defer_effect(e){ht(e,this.#f,this.#p)}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!this.#n.pending}#x(e){var t=V,n=B,r=D;dr(this.#i),ur(this.#i),Qe(this.#i.ctx);try{return qt.ensure(),e()}catch(e){return ut(e),null}finally{dr(t),ur(n),Qe(r)}}#S(e,t){if(!this.has_pending_snippet()){this.parent&&this.parent.#S(e,t);return}this.#u+=e,this.#u===0&&(this.#b(t),this.#o&&er(this.#o,()=>{this.#o=null}),this.#c&&=(this.#e.before(this.#c),null))}update_pending_count(e,t){this.#S(e,t),this.#l+=e,!(!this.#m||this.#d)&&(this.#d=!0,ct(()=>{this.#d=!1,this.#m&&ln(this.#m,this.#l)}))}get_effect_pending(){return this.#h(),H(this.#m)}error(e){if(!this.#n.onerror&&!this.#n.failed)throw e;M?.is_fork?(this.#a&&M.skip_effect(this.#a),this.#o&&M.skip_effect(this.#o),this.#s&&M.skip_effect(this.#s),M.oncommit(()=>{this.#C(e)})):this.#C(e)}#C(e){this.#a&&=(z(this.#a),null),this.#o&&=(z(this.#o),null),this.#s&&=(z(this.#s),null),C&&(T(this.#t),Ue(),T(We()));var t=this.#n.onerror;let n=this.#n.failed;var r=!1,i=!1;let a=()=>{if(r){Be();return}r=!0,i&&Me(),this.#s!==null&&er(this.#s,()=>{this.#s=null}),this.#x(()=>{this.#y()})},o=e=>{try{i=!0,t?.(e,a),i=!1}catch(e){dt(e,this.#i&&this.#i.parent)}n&&(this.#s=this.#x(()=>{try{return Jn(()=>{var t=V;t.b=this,t.f|=128,n(this.#e,()=>e,()=>a)})}catch(e){return dt(e,this.#i.parent),null}}))};ct(()=>{var t;try{t=this.transform_error(e)}catch(e){dt(e,this.#i&&this.#i.parent);return}typeof t==`object`&&t&&typeof t.then==`function`?t.then(o,e=>dt(e,this.#i&&this.#i.parent)):o(t)})}};function Ct(e,t,n,r){let i=rt()?Dt:At;var a=e.filter(e=>!e.settled),o=t.map(i);if(n.length===0&&a.length===0){r(o);return}var s=V,c=wt(),l=a.length===1?a[0].promise:a.length>1?Promise.all(a.map(e=>e.promise)):null;function u(e){if(!(s.f&16384)){c();try{r([...o,...e])}catch(e){dt(e,s)}Tt()}}var d=Et();if(n.length===0){l.then(()=>u([])).finally(d);return}function f(){Promise.all(n.map(e=>kt(e))).then(u).catch(e=>dt(e,s)).finally(d)}l?l.then(()=>{c(),f(),Tt()}):f()}function wt(){var e=V,t=B,n=D,r=M;return function(i=!0){dr(e),ur(t),Qe(n),i&&!(e.f&16384)&&(r?.activate(),r?.apply())}}function Tt(e=!0){dr(null),ur(null),Qe(null),e&&M?.deactivate()}function Et(){var e=V,t=e.b,n=M,r=!!t?.is_rendered();return t?.update_pending_count(1,n),n.increment(r,e),()=>{t?.update_pending_count(-1,n),n.decrement(r,e)}}function Dt(e){var t=2|v;return V!==null&&(V.f|=re),{ctx:D,deps:null,effects:null,equals:Ke,f:t,fn:e,reactions:null,rv:0,v:S,wv:0,parent:V,ac:null}}var Ot=Symbol(`obsolete`);function kt(e,t,n){let r=V;r===null&&xe();var i=void 0,a=sn(S),o=!B,s=new Set;return Wn(()=>{var t=V,n=m();i=n.promise;try{Promise.resolve(e()).then(n.resolve,e=>{e!==ve&&n.reject(e)}).finally(Tt)}catch(e){n.reject(e),Tt()}var c=M;if(o){if(t.f&32768)var l=Et();if(r.b?.is_rendered())c.async_deriveds.get(t)?.reject(Ot);else for(let e of s.values())e.reject(Ot);s.add(n),c.async_deriveds.set(t,n)}let u=(e,t=void 0)=>{l?.(),s.delete(n),t!==Ot&&(c.activate(),t?(a.f|=le,ln(a,t)):(a.f&8388608&&(a.f^=le),ln(a,e)),c.deactivate())};n.promise.then(u,e=>u(null,e||`unknown`))}),Ln(()=>{for(let e of s)e.reject(Ot)}),new Promise(e=>{function t(n){function r(){n===i?e(a):t(i)}n.then(r,r)}t(i)})}function j(e){let t=Dt(e);return Ye||pr(t),t}function At(e){let t=Dt(e);return t.equals=Je,t}function jt(e){var t=e.effects;if(t!==null){e.effects=null;for(var n=0;n<t.length;n+=1)z(t[n])}}function Mt(e){var t,n=V,r=e.parent;if(!sr&&r!==null&&e.v!==S&&r.f&24576)return Le(),e.v;dr(r);try{e.f&=~oe,jt(e),t=Tr(e)}finally{dr(n)}return t}function Nt(e){var t=Mt(e);if(!e.equals(t)&&(e.wv=Sr(),(!M?.is_fork||e.deps===null)&&(M===null?e.v=t:(M.capture(e,t,!0),Rt?.capture(e,t,!0)),e.deps===null))){A(e,_);return}sr||(zt===null?pt(e):(In()||M?.is_fork)&&zt.set(e,t))}function Pt(e){if(e.effects!==null)for(let t of e.effects)(t.teardown||t.ac)&&(t.teardown?.(),t.ac?.abort(ve),t.fn!==null&&(t.teardown=f),t.ac=null,Dr(t,0),Xn(t))}function Ft(e){if(e.effects!==null)for(let t of e.effects)t.teardown&&t.fn!==null&&Or(t)}var It=null,Lt=null,M=null,Rt=null,zt=null,Bt=null,Vt=!1,Ht=!1,Ut=null,Wt=null,Gt=0,Kt=1,qt=class e{id=Kt++;#e=!1;linked=!0;#t=null;#n=null;async_deriveds=new Map;current=new Map;previous=new Map;#r=new Set;#i=new Set;#a=0;#o=new Map;#s=null;#c=[];#l=[];#u=new Set;#d=new Set;#f=new Map;#p=new Set;is_fork=!1;#m=!1;constructor(){Lt===null?It=Lt=this:(Lt.#n=this,this.#t=Lt),Lt=this}#h(){if(this.is_fork)return!0;for(let n of this.#o.keys()){for(var e=n,t=!1;e.parent!==null;){if(this.#f.has(e)){t=!0;break}e=e.parent}if(!t)return!0}return!1}skip_effect(e){this.#f.has(e)||this.#f.set(e,{d:[],m:[]}),this.#p.delete(e)}unskip_effect(e,t=e=>this.schedule(e)){var n=this.#f.get(e);if(n){this.#f.delete(e);for(var r of n.d)A(r,v),t(r);for(r of n.m)A(r,y),t(r)}this.#p.add(e)}#g(){this.#e=!0,Gt++>1e3&&(this.#S(),Yt());for(let e of this.#u)this.#d.delete(e),A(e,v),this.schedule(e);for(let e of this.#d)A(e,y),this.schedule(e);let t=this.#c;this.#c=[],this.apply();var n=Ut=[],r=[],i=Wt=[];for(let e of t)try{this.#_(e,n,r)}catch(t){throw nn(e),this.#h()||this.discard(),t}if(M=null,i.length>0){var a=e.ensure();for(let e of i)a.schedule(e)}if(Ut=null,Wt=null,this.#h()){this.#b(r),this.#b(n);for(let[e,t]of this.#f)tn(e,t);i.length>0&&M.#g();return}let o=this.#v();if(o){this.#b(r),this.#b(n),o.#y(this);return}this.#u.clear(),this.#d.clear();for(let e of this.#r)e(this);this.#r.clear(),Rt=this,Zt(r),Zt(n),Rt=null,this.#s?.resolve();var s=M;if(this.#a===0&&(this.#c.length===0||s!==null)&&(this.#S(),Ye&&(this.#x(),M=s)),this.#c.length>0)if(s!==null){let e=s;e.#c.push(...this.#c.filter(t=>!e.#c.includes(t)))}else s=this;s!==null&&s.#g()}#_(e,t,n){e.f^=_;for(var r=e.first;r!==null;){var i=r.f,a=(i&96)!=0;if(!(a&&i&1024||i&8192||this.#f.has(r))&&r.fn!==null){a?r.f^=_:i&4?t.push(r):Ye&&i&16777224?n.push(r):Cr(r)&&(i&16&&this.#d.add(r),Or(r));var o=r.first;if(o!==null){r=o;continue}}for(;r!==null;){var s=r.next;if(s!==null){r=s;break}r=r.parent}}}#v(){for(var e=this.#t;e!==null;){if(!e.is_fork){for(let[t,[,n]]of this.current)if(e.current.has(t)&&!n)return e}e=e.#t}return null}#y(e){for(let[t,n]of e.current)!this.previous.has(t)&&e.previous.has(t)&&this.previous.set(t,e.previous.get(t)),this.current.set(t,n);for(let[t,n]of e.async_deriveds){let e=this.async_deriveds.get(t);e&&n.promise.then(e.resolve).catch(e.reject)}e.async_deriveds.clear(),this.transfer_effects(e.#u,e.#d);let t=e=>{var n=e.reactions;if(n!==null)for(let e of n){var r=e.f;if(r&2)t(e);else{var i=e;r&4194320&&!this.async_deriveds.has(i)&&(this.#d.delete(i),A(i,v),this.schedule(i))}}};for(let e of this.current.keys())t(e);this.oncommit(()=>e.discard()),e.#S(),M=this,this.#g()}#b(e){for(var t=0;t<e.length;t+=1)ht(e[t],this.#u,this.#d)}capture(e,t,n=!1){e.v!==S&&!this.previous.has(e)&&this.previous.set(e,e.v),e.f&8388608||(this.current.set(e,[t,n]),zt?.set(e,t)),this.is_fork||(e.v=t)}activate(){M=this}deactivate(){M=null,zt=null}flush(){try{Ht=!0,M=this,this.#g()}finally{Gt=0,Bt=null,Ut=null,Wt=null,Ht=!1,M=null,zt=null,an.clear()}}discard(){for(let e of this.#i)e(this);this.#i.clear();for(let e of this.async_deriveds.values())e.reject(Ot);this.#S(),this.#s?.resolve()}register_created_effect(e){this.#l.push(e)}#x(){for(let u=It;u!==null;u=u.#n){var e=u.id<this.id,t=[];for(let[r,[i,a]]of this.current){if(u.current.has(r)){var n=u.current.get(r)[0];if(e&&i!==n)u.current.set(r,[i,a]);else continue}t.push(r)}if(e)for(let[e,t]of this.async_deriveds){let n=u.async_deriveds.get(e);n&&t.promise.then(n.resolve).catch(n.reject)}var r=[...u.current.keys()].filter(e=>!u.current.get(e)[1]);if(!(!u.#e||r.length===0)){var i=r.filter(e=>!this.current.has(e));if(i.length===0)e&&u.discard();else if(t.length>0){if(e)for(let e of this.#p)u.unskip_effect(e,e=>{e.f&4194320?u.schedule(e):u.#b([e])});u.activate();var a=new Set,o=new Map;for(var s of t)Qt(s,i,a,o);o=new Map;var c=[...u.current].filter(([e,t])=>{let n=this.current.get(e);return n?n[0]!==t[0]||n[1]!==t[1]:!0}).map(([e])=>e);if(c.length>0)for(let e of this.#l)!(e.f&155648)&&$t(e,c,o)&&(e.f&4194320?(A(e,v),u.schedule(e)):u.#u.add(e));if(u.#c.length>0&&!u.#m){u.apply();for(var l of u.#c)u.#_(l,[],[]);u.#c=[]}u.deactivate()}}}}increment(e,t){if(this.#a+=1,e){let e=this.#o.get(t)??0;this.#o.set(t,e+1)}}decrement(e,t){if(--this.#a,e){let e=this.#o.get(t)??0;e===1?this.#o.delete(t):this.#o.set(t,e-1)}this.#m||(this.#m=!0,ct(()=>{this.#m=!1,this.linked&&this.flush()}))}transfer_effects(e,t){for(let t of e)this.#u.add(t);for(let e of t)this.#d.add(e);e.clear(),t.clear()}oncommit(e){this.#r.add(e)}ondiscard(e){this.#i.add(e)}settled(){return(this.#s??=m()).promise}static ensure(){if(M===null){let t=M=new e;!Ht&&!Vt&&ct(()=>{t.#e||t.flush()})}return M}apply(){if(!Ye||!this.is_fork&&this.#t===null&&this.#n===null){zt=null;return}zt=new Map;for(let[e,[t]]of this.current)zt.set(e,t);for(let t=It;t!==null;t=t.#n)if(!(t===this||t.is_fork)){var e=!1;if(t.id<this.id){for(let[n,[,r]]of t.current)if(!r&&this.current.has(n)){e=!0;break}}if(!e)for(let[e,n]of t.previous)zt.has(e)||zt.set(e,n)}}schedule(e){if(Bt=e,e.b?.is_pending&&e.f&16777228&&!(e.f&32768)){e.b.defer_effect(e);return}for(var t=e;t.parent!==null;){t=t.parent;var n=t.f;if(Ut!==null&&t===V&&(Ye||(B===null||!(B.f&2))&&!gt))return;if(n&96){if(!(n&1024))return;t.f^=_}}this.#c.push(t)}#S(){if(this.linked){var e=this.#t,t=this.#n;e===null?It=t:e.#n=t,t===null?Lt=e:t.#t=e,this.linked=!1}}};function Jt(e){var t=Vt;Vt=!0;try{var n;for(e&&(M!==null&&!M.is_fork&&M.flush(),n=e());;){if(lt(),M===null)return n;M.flush()}}finally{Vt=t}}function Yt(){try{Ee()}catch(e){dt(e,Bt)}}var Xt=null;function Zt(e){var t=e.length;if(t!==0){for(var n=0;n<t;){var r=e[n++];if(!(r.f&24576)&&Cr(r)&&(Xt=new Set,Or(r),r.deps===null&&r.first===null&&r.nodes===null&&r.teardown===null&&r.ac===null&&$n(r),Xt?.size>0)){an.clear();for(let e of Xt){if(e.f&24576)continue;let t=[e],n=e.parent;for(;n!==null;)Xt.has(n)&&(Xt.delete(n),t.push(n)),n=n.parent;for(let e=t.length-1;e>=0;e--){let n=t[e];n.f&24576||Or(n)}}Xt.clear()}}Xt=null}}function Qt(e,t,n,r){if(!n.has(e)&&(n.add(e),e.reactions!==null))for(let i of e.reactions){let e=i.f;e&2?Qt(i,t,n,r):e&4194320&&!(e&2048)&&$t(i,t,r)&&(A(i,v),en(i))}}function $t(e,t,r){let i=r.get(e);if(i!==void 0)return i;if(e.deps!==null)for(let i of e.deps){if(n.call(t,i))return!0;if(i.f&2&&$t(i,t,r))return r.set(i,!0),!0}return r.set(e,!1),!1}function en(e){M.schedule(e)}function tn(e,t){if(!(e.f&32&&e.f&1024)){e.f&2048?t.d.push(e):e.f&4096&&t.m.push(e),A(e,_);for(var n=e.first;n!==null;)tn(n,t),n=n.next}}function nn(e){A(e,_);for(var t=e.first;t!==null;)nn(t),t=t.next}var rn=new Set,an=new Map,on=!1;function sn(e,t){return{f:0,v:e,reactions:null,equals:Ke,rv:0,wv:0}}function N(e,t){let n=sn(e,t);return pr(n),n}function cn(e,t=!1,n=!0){let r=sn(e);return t||(r.equals=Je),Xe&&n&&D!==null&&D.l!==null&&(D.l.s??=[]).push(r),r}function P(e,t,n=!1){return B!==null&&(!lr||B.f&131072)&&rt()&&B.f&4325394&&(fr===null||!fr.has(e))&&je(),ln(e,n?pn(t):t,Wt)}function ln(e,t,n=null){if(!e.equals(t)){an.set(e,sr?t:e.v);var r=qt.ensure();if(r.capture(e,t),e.f&2){let t=e;e.f&2048&&Mt(t),zt===null&&pt(t)}e.wv=Sr(),fn(e,v,n),rt()&&V!==null&&V.f&1024&&!(V.f&96)&&(gr===null?_r([e]):gr.push(e)),!r.is_fork&&rn.size>0&&!on&&un()}return t}function un(){on=!1;for(let e of rn){e.f&1024&&A(e,y);let t;try{t=Cr(e)}catch{t=!0}t&&Or(e)}rn.clear()}function dn(e){P(e,e.v+1)}function fn(e,t,n){var r=e.reactions;if(r!==null)for(var i=rt(),a=r.length,o=0;o<a;o++){var s=r[o],c=s.f;if(!(!i&&s===V)){var l=(c&v)===0;if(l&&A(s,t),c&131072)rn.add(s);else if(c&2){var u=s;zt?.delete(u),c&65536||(c&512&&(V===null||!(V.f&2097152))&&(s.f|=oe),fn(u,y,n))}else if(l){var d=s;c&16&&Xt!==null&&Xt.add(d),n===null?en(d):n.push(d)}}}}function pn(t){if(typeof t!=`object`||!t||ue in t)return t;let n=l(t);if(n!==s&&n!==c)return t;var r=new Map,i=e(t),o=N(0),u=null,d=br,f=e=>{if(br===d)return e();var t=B,n=br;ur(null),xr(d);var r=e();return ur(t),xr(n),r};return i&&r.set(`length`,N(t.length,u)),new Proxy(t,{defineProperty(e,t,n){(!(`value`in n)||n.configurable===!1||n.enumerable===!1||n.writable===!1)&&ke();var i=r.get(t);return i===void 0?f(()=>{var e=N(n.value,u);return r.set(t,e),e}):P(i,n.value,!0),!0},deleteProperty(e,t){var n=r.get(t);if(n===void 0){if(t in e){let e=f(()=>N(S,u));r.set(t,e),dn(o)}}else P(n,S),dn(o);return!0},get(e,n,i){if(n===ue)return t;var o=r.get(n),s=n in e;if(o===void 0&&(!s||a(e,n)?.writable)&&(o=f(()=>N(pn(s?e[n]:S),u)),r.set(n,o)),o!==void 0){var c=H(o);return c===S?void 0:c}return Reflect.get(e,n,i)},getOwnPropertyDescriptor(e,t){var n=Reflect.getOwnPropertyDescriptor(e,t);if(n&&`value`in n){var i=r.get(t);i&&(n.value=H(i))}else if(n===void 0){var a=r.get(t),o=a?.v;if(a!==void 0&&o!==S)return{enumerable:!0,configurable:!0,value:o,writable:!0}}return n},has(e,t){if(t===ue)return!0;var n=r.get(t),i=n!==void 0&&n.v!==S||Reflect.has(e,t);return(n!==void 0||V!==null&&(!i||a(e,t)?.writable))&&(n===void 0&&(n=f(()=>N(i?pn(e[t]):S,u)),r.set(t,n)),H(n)===S)?!1:i},set(e,t,n,s){var c=r.get(t),l=t in e;if(i&&t===`length`)for(var d=n;d<c.v;d+=1){var p=r.get(d+``);p===void 0?d in e&&(p=f(()=>N(S,u)),r.set(d+``,p)):P(p,S)}if(c===void 0)(!l||a(e,t)?.writable)&&(c=f(()=>N(void 0,u)),P(c,pn(n)),r.set(t,c));else{l=c.v!==S;var m=f(()=>pn(n));P(c,m)}var h=Reflect.getOwnPropertyDescriptor(e,t);if(h?.set&&h.set.call(s,n),!l){if(i&&typeof t==`string`){var g=r.get(`length`),_=Number(t);Number.isInteger(_)&&_>=g.v&&P(g,_+1)}dn(o)}return!0},ownKeys(e){H(o);var t=Reflect.ownKeys(e).filter(e=>{var t=r.get(e);return t===void 0||t.v!==S});for(var[n,i]of r)i.v!==S&&!(n in e)&&t.push(n);return t},setPrototypeOf(){Ae()}})}function mn(e){try{if(typeof e==`object`&&e&&ue in e)return e[ue]}catch{}return e}function hn(e,t){return Object.is(mn(e),mn(t))}new Set([`copyWithin`,`fill`,`pop`,`push`,`reverse`,`shift`,`sort`,`splice`,`unshift`]);var gn,_n,vn,yn;function bn(){if(gn===void 0){gn=window,_n=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,n=Text.prototype;vn=a(t,`firstChild`).get,yn=a(t,`nextSibling`).get,u(e)&&(e[me]=void 0,e[pe]=null,e[he]=void 0,e.__e=void 0),u(n)&&(n[ge]=void 0)}}function xn(e=``){return document.createTextNode(e)}function Sn(e){return vn.call(e)}function Cn(e){return yn.call(e)}function F(e,t){if(!C)return Sn(e);var n=Sn(w);if(n===null)n=w.appendChild(xn());else if(t&&n.nodeType!==3){var r=xn();return n?.before(r),T(r),r}return t&&Dn(n),T(n),n}function I(e,t=!1){if(!C){var n=Sn(e);return n instanceof Comment&&n.data===``?Cn(n):n}if(t){if(w?.nodeType!==3){var r=xn();return w?.before(r),T(r),r}Dn(w)}return w}function L(e,t=1,n=!1){let r=C?w:e;for(var i;t--;)i=r,r=Cn(r);if(!C)return r;if(n){if(r?.nodeType!==3){var a=xn();return r===null?i?.after(a):r.before(a),T(a),a}Dn(r)}return T(r),r}function wn(e){e.textContent=``}function Tn(){return!Ye||Xt!==null?!1:(V.f&x)!==0}function En(e,t,n){return t==null||t===`http://www.w3.org/1999/xhtml`?n?document.createElement(e,{is:n}):document.createElement(e):n?document.createElementNS(t,e,{is:n}):document.createElementNS(t,e)}function Dn(e){if(e.nodeValue.length<65536)return;let t=e.nextSibling;for(;t!==null&&t.nodeType===3;)t.remove(),e.nodeValue+=t.nodeValue,t=e.nextSibling}function On(e,t){if(t){let t=document.body;e.autofocus=!0,ct(()=>{document.activeElement===t&&e.focus()})}}var kn=!1;function An(){kn||(kn=!0,document.addEventListener(`reset`,e=>{Promise.resolve().then(()=>{if(!e.defaultPrevented)for(let t of e.target.elements)t[_e]?.()})},{capture:!0}))}function jn(e){var t=B,n=V;ur(null),dr(null);try{return e()}finally{ur(t),dr(n)}}function Mn(e,t,n,r=n){e.addEventListener(t,()=>jn(n));let i=e[_e];i?e[_e]=()=>{i(),r(!0)}:e[_e]=()=>r(!0),An()}function Nn(e){V===null&&(B===null&&Te(e),we()),sr&&Ce(e)}function Pn(e,t){var n=t.last;n===null?t.last=t.first=e:(n.next=e,e.prev=n,t.last=e)}function Fn(e,t){var n=V;n!==null&&n.f&8192&&(e|=b);var r={ctx:D,deps:null,nodes:null,f:e|v|512,first:null,fn:t,last:null,next:null,parent:n,b:n&&n.b,prev:null,teardown:null,wv:0,ac:null};M?.register_created_effect(r);var i=r;if(e&4)Ut===null?qt.ensure().schedule(r):Ut.push(r);else if(t!==null){try{Or(r)}catch(e){throw z(r),e}i.deps===null&&i.teardown===null&&i.nodes===null&&i.first===i.last&&!(i.f&524288)&&(i=i.first,e&16&&e&65536&&i!==null&&(i.f|=ne))}if(i!==null&&(i.parent=n,n!==null&&Pn(i,n),B!==null&&B.f&2&&!(e&64))){var a=B;(a.effects??=[]).push(i)}return r}function In(){return B!==null&&!lr}function Ln(e){let t=Fn(8,null);return A(t,_),t.teardown=e,t}function Rn(e){Nn(`$effect`);var t=V.f;if(!B&&t&32&&D!==null&&!D.i){var n=D;(n.e??=[]).push(e)}else return zn(e)}function zn(e){return Fn(4|ie,e)}function Bn(e){return Nn(`$effect.pre`),Fn(8|ie,e)}function Vn(e){qt.ensure();let t=Fn(64|re,e);return()=>{z(t)}}function Hn(e){qt.ensure();let t=Fn(64|re,e);return(e={})=>new Promise(n=>{e.outro?er(t,()=>{z(t),n(void 0)}):(z(t),n(void 0))})}function Un(e){return Fn(4,e)}function Wn(e){return Fn(ce|re,e)}function Gn(e,t=0){return Fn(8|t,e)}function R(e,t=[],n=[],r=[]){Ct(r,t,n,t=>{Fn(8,()=>{e(...t.map(H))})})}function Kn(e,t=0){return Fn(16|t,e)}function qn(e,t=0){return Fn(g|t,e)}function Jn(e){return Fn(32|re,e)}function Yn(e){var t=e.teardown;if(t!==null){let e=sr,n=B;cr(!0),ur(null);try{t.call(null)}finally{cr(e),ur(n)}}}function Xn(e,t=!1){var n=e.first;for(e.first=e.last=null;n!==null;){let e=n.ac;e!==null&&jn(()=>{e.abort(ve)});var r=n.next;n.f&64?n.parent=null:z(n,t),n=r}}function Zn(e){for(var t=e.first;t!==null;){var n=t.next;t.f&32||z(t),t=n}}function z(e,t=!0){var n=!1;(t||e.f&262144)&&e.nodes!==null&&e.nodes.end!==null&&(Qn(e.nodes.start,e.nodes.end),n=!0),e.f|=te,Xn(e,t&&!n),Dr(e,0);var r=e.nodes&&e.nodes.t;if(r!==null)for(let e of r)e.stop();Yn(e),e.f^=te,e.f|=ee;var i=e.parent;i!==null&&i.first!==null&&$n(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=e.b=null}function Qn(e,t){for(;e!==null;){var n=e===t?null:Cn(e);e.remove(),e=n}}function $n(e){var t=e.parent,n=e.prev,r=e.next;n!==null&&(n.next=r),r!==null&&(r.prev=n),t!==null&&(t.first===e&&(t.first=r),t.last===e&&(t.last=n))}function er(e,t,n=!0){var r=[];tr(e,r,!0);var i=()=>{n&&z(e),t&&t()},a=r.length;if(a>0){var o=()=>--a||i();for(var s of r)s.out(o)}else i()}function tr(e,t,n){if(!(e.f&8192)){e.f^=b;var r=e.nodes&&e.nodes.t;if(r!==null)for(let e of r)(e.is_global||n)&&t.push(e);for(var i=e.first;i!==null;){var a=i.next;if(!(i.f&64)){var o=(i.f&65536)!=0||(i.f&32)!=0&&(e.f&16)!=0;tr(i,t,o?n:!1)}i=a}}}function nr(e){rr(e,!0)}function rr(e,t){if(e.f&8192){e.f^=b,e.f&1024||(A(e,v),qt.ensure().schedule(e));for(var n=e.first;n!==null;){var r=n.next,i=(n.f&65536)!=0||(n.f&32)!=0;rr(n,i?t:!1),n=r}var a=e.nodes&&e.nodes.t;if(a!==null)for(let e of a)(e.is_global||t)&&e.in()}}function ir(e,t){if(e.nodes)for(var n=e.nodes.start,r=e.nodes.end;n!==null;){var i=n===r?null:Cn(n);t.append(n),n=i}}var ar=null,or=!1,sr=!1;function cr(e){sr=e}var B=null,lr=!1;function ur(e){B=e}var V=null;function dr(e){V=e}var fr=null;function pr(e){B!==null&&(!Ye||B.f&2)&&(fr??=new Set).add(e)}var mr=null,hr=0,gr=null;function _r(e){gr=e}var vr=1,yr=0,br=yr;function xr(e){br=e}function Sr(){return++vr}function Cr(e){var t=e.f;if(t&2048)return!0;if(t&2&&(e.f&=~oe),t&4096){for(var n=e.deps,r=n.length,i=0;i<r;i++){var a=n[i];if(Cr(a)&&Nt(a),a.wv>e.wv)return!0}t&512&&zt===null&&A(e,_)}return!1}function wr(e,t,n=!0){var r=e.reactions;if(r!==null&&!(!Ye&&fr!==null&&fr.has(e)))for(var i=0;i<r.length;i++){var a=r[i];a.f&2?wr(a,t,!1):t===a&&(n?A(a,v):a.f&1024&&A(a,y),en(a))}}function Tr(e){var t=mr,n=hr,r=gr,i=B,a=fr,o=D,s=lr,c=br,l=e.f;mr=null,hr=0,gr=null,B=l&96?null:e,fr=null,Qe(e.ctx),lr=!1,br=++yr,e.ac!==null&&(jn(()=>{e.ac.abort(ve)}),e.ac=null);try{e.f|=se;var u=e.fn,d=u();e.f|=x;var f=e.deps,p=M?.is_fork;if(mr!==null){var m;if(p||Dr(e,hr),f!==null&&hr>0)for(f.length=hr+mr.length,m=0;m<mr.length;m++)f[hr+m]=mr[m];else e.deps=f=mr;if(In()&&e.f&512)for(m=hr;m<f.length;m++)(f[m].reactions??=[]).push(e)}else !p&&f!==null&&hr<f.length&&(Dr(e,hr),f.length=hr);if(rt()&&gr!==null&&!lr&&f!==null&&!(e.f&6146))for(m=0;m<gr.length;m++)wr(gr[m],e);if(i!==null&&i!==e){if(yr++,i.deps!==null)for(let e=0;e<n;e+=1)i.deps[e].rv=yr;if(t!==null)for(let e of t)e.rv=yr;gr!==null&&(r===null?r=gr:r.push(...gr))}return e.f&8388608&&(e.f^=le),d}catch(e){return ut(e)}finally{e.f^=se,mr=t,hr=n,gr=r,B=i,fr=a,Qe(o),lr=s,br=c}}function Er(e,r){let i=r.reactions;if(i!==null){var a=t.call(i,e);if(a!==-1){var o=i.length-1;o===0?i=r.reactions=null:(i[a]=i[o],i.pop())}}if(i===null&&r.f&2&&(mr===null||!n.call(mr,r))){var s=r;s.f&512&&(s.f^=512,s.f&=~oe),s.v!==S&&pt(s),Pt(s),Dr(s,0)}}function Dr(e,t){var n=e.deps;if(n!==null)for(var r=t;r<n.length;r++)Er(e,n[r])}function Or(e){var t=e.f;if(!(t&16384)){A(e,_);var n=V,r=or;V=e,or=!0;try{t&16777232?Zn(e):Xn(e),Yn(e);var i=Tr(e);e.teardown=typeof i==`function`?i:null,e.wv=vr}finally{or=r,V=n}}}async function kr(){if(Ye)return new Promise(e=>{requestAnimationFrame(()=>e()),setTimeout(()=>e())});await Promise.resolve(),Jt()}function H(e){var t=(e.f&2)!=0;if(ar?.add(e),B!==null&&!lr&&!(V!==null&&V.f&16384)&&(fr===null||!fr.has(e))){var r=B.deps;if(B.f&2097152)e.rv<yr&&(e.rv=yr,mr===null&&r!==null&&r[hr]===e?hr++:mr===null?mr=[e]:mr.push(e));else{B.deps??=[],n.call(B.deps,e)||B.deps.push(e);var i=e.reactions;i===null?e.reactions=[B]:n.call(i,B)||i.push(B)}}if(sr&&an.has(e))return an.get(e);if(t){var a=e;if(sr){var o=a.v;return(!(a.f&1024)&&a.reactions!==null||jr(a))&&(o=Mt(a)),an.set(a,o),o}var s=(a.f&512)==0&&!lr&&B!==null&&(or||(B.f&512)!=0),c=(a.f&x)===0;Cr(a)&&(s&&(a.f|=512),Nt(a)),s&&!c&&(Ft(a),Ar(a))}if(zt?.has(e))return zt.get(e);if(e.f&8388608)throw e.v;return e.v}function Ar(e){if(e.f|=512,e.deps!==null)for(let t of e.deps)(t.reactions??=[]).push(e),t.f&2&&!(t.f&512)&&(Ft(t),Ar(t))}function jr(e){if(e.v===S)return!0;if(e.deps===null)return!1;for(let t of e.deps)if(an.has(t)||t.f&2&&jr(t))return!0;return!1}function Mr(e){var t=lr;try{return lr=!0,e()}finally{lr=t}}function Nr(){return Symbol(Ie)}function Pr(e){return e.endsWith(`capture`)&&e!==`gotpointercapture`&&e!==`lostpointercapture`}var Fr=[`beforeinput`,`click`,`change`,`dblclick`,`contextmenu`,`focusin`,`focusout`,`input`,`keydown`,`keyup`,`mousedown`,`mousemove`,`mouseout`,`mouseover`,`mouseup`,`pointerdown`,`pointermove`,`pointerout`,`pointerover`,`pointerup`,`touchend`,`touchmove`,`touchstart`];function Ir(e){return Fr.includes(e)}var Lr=`allowfullscreen.async.autofocus.autoplay.checked.controls.default.disabled.formnovalidate.indeterminate.inert.ismap.loop.multiple.muted.nomodule.novalidate.open.playsinline.readonly.required.reversed.seamless.selected.webkitdirectory.defer.disablepictureinpicture.disableremoteplayback`.split(`.`),Rr={formnovalidate:`formNoValidate`,ismap:`isMap`,nomodule:`noModule`,playsinline:`playsInline`,readonly:`readOnly`,defaultvalue:`defaultValue`,defaultchecked:`defaultChecked`,srcobject:`srcObject`,novalidate:`noValidate`,allowfullscreen:`allowFullscreen`,disablepictureinpicture:`disablePictureInPicture`,disableremoteplayback:`disableRemotePlayback`};function zr(e){return e=e.toLowerCase(),Rr[e]??e}[...Lr];var Br=[`touchstart`,`touchmove`];function Vr(e){return Br.includes(e)}var Hr=[`textarea`,`script`,`style`,`title`];function Ur(e){return Hr.includes(e)}var Wr=Symbol(`events`),Gr=new Set,Kr=new Set;function qr(e,t,n,r={}){function i(e){if(r.capture||Qr.call(t,e),!e.cancelBubble)return jn(()=>n?.call(this,e))}return e.startsWith(`pointer`)||e.startsWith(`touch`)||e===`wheel`?ct(()=>{t.addEventListener(e,i,r)}):t.addEventListener(e,i,r),i}function Jr(e,t,n,r={}){var i=qr(t,e,n,r);return()=>{e.removeEventListener(t,i,r)}}function Yr(e,t,n){(t[Wr]??={})[e]=n}function Xr(e){for(var t=0;t<e.length;t++)Gr.add(e[t]);for(var n of Kr)n(e)}var Zr=null;function Qr(e){var t=this,n=t.ownerDocument,r=e.type,a=e.composedPath?.()||[],o=a[0]||e.target;Zr=e;var s=0,c=Zr===e&&e[Wr];if(c){var l=a.indexOf(c);if(l!==-1&&(t===document||t===window)){e[Wr]=t;return}var u=a.indexOf(t);if(u===-1)return;l<=u&&(s=l)}if(o=a[s]||e.target,o!==t){i(e,`currentTarget`,{configurable:!0,get(){return o||n}});var d=B,f=V;ur(null),dr(null);try{for(var p,m=[];o!==null&&o!==t;){try{var h=o[Wr]?.[r];h!=null&&(!o.disabled||e.target===o)&&h.call(o,e)}catch(e){p?m.push(e):p=e}if(e.cancelBubble)break;s++,o=s<a.length?a[s]:null}if(p){for(let e of m)queueMicrotask(()=>{throw e});throw p}}finally{e[Wr]=t,delete e.currentTarget,ur(d),dr(f)}}}var $r=globalThis?.window?.trustedTypes&&globalThis.window.trustedTypes.createPolicy(`svelte-trusted-html`,{createHTML:e=>e});function ei(e){return $r?.createHTML(e)??e}function ti(e){var t=En(`template`);return t.innerHTML=ei(e.replaceAll(`<!>`,`\\x3C!---->`)),t.content}function ni(e,t){var n=V;n.nodes===null&&(n.nodes={start:e,end:t,a:null,t:null})}function U(e,t){var n=(t&1)!=0,r=(t&2)!=0,i,a=!e.startsWith(`<!>`);return()=>{if(C)return ni(w,null),w;i===void 0&&(i=ti(a?e:`<!>`+e),n||(i=Sn(i)));var t=r||_n?document.importNode(i,!0):i.cloneNode(!0);if(n){var o=Sn(t),s=t.lastChild;ni(o,s)}else ni(t,t);return t}}function ri(e,t,n=`svg`){var r=!e.startsWith(`<!>`),i=(t&1)!=0,a=`<${n}>${r?e:`<!>`+e}</${n}>`,o;return()=>{if(C)return ni(w,null),w;if(!o){var e=Sn(ti(a));if(i)for(o=document.createDocumentFragment();Sn(e);)o.appendChild(Sn(e));else o=Sn(e)}var t=o.cloneNode(!0);if(i){var n=Sn(t),r=t.lastChild;ni(n,r)}else ni(t,t);return t}}function ii(e,t){return ri(e,t,`svg`)}function ai(e=``){if(!C){var t=xn(e+``);return ni(t,t),t}var n=w;return n.nodeType===3?Dn(n):(n.before(n=xn()),T(n)),ni(n,n),n}function W(){if(C)return ni(w,null),w;var e=document.createDocumentFragment(),t=document.createComment(``),n=xn();return e.append(t,n),ni(t,n),e}function G(e,t){if(C){var n=V;(!(n.f&32768)||n.nodes.end===null)&&(n.nodes.end=w),He();return}e!==null&&e.before(t)}function oi(){if(C&&w&&w.nodeType===8&&w.textContent?.startsWith(`$`)){let e=w.textContent.substring(1);return He(),e}return(window.__svelte??={}).uid??=1,`c${window.__svelte.uid++}`}function K(e,t){var n=t==null?``:typeof t==`object`?`${t}`:t;n!==(e[ge]??=e.nodeValue)&&(e[ge]=n,e.nodeValue=`${n}`)}function si(e,t){return li(e,t)}var ci=new Map;function li(e,{target:t,anchor:n,props:i={},events:a,context:o,intro:s=!0,transformError:c}){bn();var l=void 0,u=Hn(()=>{var s=n??t.appendChild(xn());xt(s,{pending:()=>{}},t=>{O({});var n=D;if(o&&(n.c=o),a&&(i.$$events=a),C&&ni(t,null),l=e(t,i)||{},C&&(V.nodes.end=w,w===null||w.nodeType!==8||w.data!==`]`))throw Re(),Ne;k()},c);var u=new Set,d=e=>{for(var n=0;n<e.length;n++){var r=e[n];if(!u.has(r)){u.add(r);var i=Vr(r);for(let e of[t,document]){var a=ci.get(e);a===void 0&&(a=new Map,ci.set(e,a));var o=a.get(r);o===void 0?(e.addEventListener(r,Qr,{passive:i}),a.set(r,1)):a.set(r,o+1)}}}};return d(r(Gr)),Kr.add(d),()=>{for(var e of u)for(let n of[t,document]){var r=ci.get(n),i=r.get(e);--i==0?(n.removeEventListener(e,Qr),r.delete(e),r.size===0&&ci.delete(n)):r.set(e,i)}Kr.delete(d),s!==n&&s.parentNode?.removeChild(s)}});return ui.set(l,u),l}var ui=new WeakMap;function di(e,t){let n=ui.get(e);return n?(ui.delete(e),n(t)):Promise.resolve()}var fi=class{anchor;#e=new Map;#t=new Map;#n=new Map;#r=new Set;#i=!0;constructor(e,t=!0){this.anchor=e,this.#i=t}#a=e=>{if(this.#e.has(e)){var t=this.#e.get(e),n=this.#t.get(t);if(n)nr(n),this.#r.delete(t);else{var r=this.#n.get(t);r&&(nr(r.effect),this.#t.set(t,r.effect),this.#n.delete(t),r.fragment.lastChild.remove(),this.anchor.before(r.fragment),n=r.effect)}for(let[t,n]of this.#e){if(this.#e.delete(t),t===e)break;let r=this.#n.get(n);r&&(z(r.effect),this.#n.delete(n))}for(let[e,r]of this.#t){if(e===t||this.#r.has(e))continue;let i=()=>{if(Array.from(this.#e.values()).includes(e)){var t=document.createDocumentFragment();ir(r,t),t.append(xn()),this.#n.set(e,{effect:r,fragment:t})}else z(r);this.#r.delete(e),this.#t.delete(e)};this.#i||!n?(this.#r.add(e),er(r,i,!1)):i()}}};#o=e=>{this.#e.delete(e);let t=Array.from(this.#e.values());for(let[e,n]of this.#n)t.includes(e)||(z(n.effect),this.#n.delete(e))};ensure(e,t){var n=M,r=Tn();if(t&&!this.#t.has(e)&&!this.#n.has(e))if(r){var i=document.createDocumentFragment(),a=xn();i.append(a),this.#n.set(e,{effect:Jn(()=>t(a)),fragment:i})}else this.#t.set(e,Jn(()=>t(this.anchor)));if(this.#e.set(n,e),r){for(let[t,r]of this.#t)t===e?n.unskip_effect(r):n.skip_effect(r);for(let[t,r]of this.#n)t===e?n.unskip_effect(r.effect):n.skip_effect(r.effect);n.oncommit(this.#a),n.ondiscard(this.#o)}else C&&(this.anchor=w),this.#a(n)}};function q(e,t,n=!1){var r;C&&(r=w,He());var i=new fi(e),a=n?ne:0;function o(e,t){if(C){var n=Ge(r);if(e!==parseInt(n.substring(1))){var a=We();T(a),i.anchor=a,Ve(!1),i.ensure(e,t),Ve(!0);return}}i.ensure(e,t)}Kn(()=>{var e=!1;t((t,n=0)=>{e=!0,o(n,t)}),e||o(-1,null)},a)}var pi=Symbol(`NaN`);function mi(e,t,n){C&&He();var r=new fi(e),i=!rt();Kn(()=>{var e=t();e!==e&&(e=pi),i&&typeof e==`object`&&e&&(e={}),r.ensure(e,n)})}function hi(e,t){return t}function gi(e,t,n){for(var i=[],a=t.length,o,s=t.length,c=0;c<a;c++){let n=t[c];er(n,()=>{if(o){if(o.pending.delete(n),o.done.add(n),o.pending.size===0){var t=e.outrogroups;_i(e,r(o.done)),t.delete(o),t.size===0&&(e.outrogroups=null)}}else --s},!1)}if(s===0){var l=i.length===0&&n!==null;if(l){var u=n,d=u.parentNode;wn(d),d.append(u),e.items.clear()}_i(e,t,!l)}else o={pending:new Set(t),done:new Set},(e.outrogroups??=new Set).add(o)}function _i(e,t,n=!0){var r;if(e.pending.size>0){r=new Set;for(let t of e.pending.values())for(let n of t)r.add(e.items.get(n).e)}for(var i=0;i<t.length;i++){var a=t[i];r?.has(a)?(a.f|=ae,ir(a,document.createDocumentFragment())):z(t[i],n)}}var vi;function yi(t,n,i,a,o,s=null){var c=t,l=new Map;if(n&4){var u=t;c=C?T(Sn(u)):u.appendChild(xn())}C&&He();var d=null,f=At(()=>{var t=i();return e(t)?t:t==null?[]:r(t)}),p,m=new Map,h=!0;function g(e){v.effect.f&16384||(v.pending.delete(e),v.fallback=d,xi(v,p,c,n,a),d!==null&&(p.length===0?d.f&33554432?(d.f^=ae,Ci(d,null,c)):nr(d):er(d,()=>{d=null})))}function _(e){v.pending.delete(e)}var v={effect:Kn(()=>{p=H(f);var e=p.length;let t=!1;C&&Ge(c)===`[!`!=(e===0)&&(c=We(),T(c),Ve(!1),t=!0);for(var r=new Set,u=M,v=Tn(),y=0;y<e;y+=1){C&&w.nodeType===8&&w.data===`]`&&(c=w,t=!0,Ve(!1));var b=p[y],ee=a(b,y),x=h?null:l.get(ee);x?(x.v&&ln(x.v,b),x.i&&ln(x.i,y),v&&u.unskip_effect(x.e)):(x=Si(l,h?c:vi??=xn(),b,ee,y,o,n,i),h||(x.e.f|=ae),l.set(ee,x)),r.add(ee)}if(e===0&&s&&!d&&(h?d=Jn(()=>s(c)):(d=Jn(()=>s(vi??=xn())),d.f|=ae)),e>r.size&&Se(``,``,``),C&&e>0&&T(We()),!h)if(m.set(u,r),v){for(let[e,t]of l)r.has(e)||u.skip_effect(t.e);u.oncommit(g),u.ondiscard(_)}else g(u);t&&Ve(!0),H(f)}),flags:n,items:l,pending:m,outrogroups:null,fallback:d};h=!1,C&&(c=w)}function bi(e){for(;e!==null&&!(e.f&32);)e=e.next;return e}function xi(e,t,n,i,a){var o=(i&8)!=0,s=t.length,c=e.items,l=bi(e.effect.first),u,d=null,f,p=[],m=[],h,g,_,v;if(o)for(v=0;v<s;v+=1)h=t[v],g=a(h,v),_=c.get(g).e,_.f&33554432||(_.nodes?.a?.measure(),(f??=new Set).add(_));for(v=0;v<s;v+=1){if(h=t[v],g=a(h,v),_=c.get(g).e,e.outrogroups!==null)for(let t of e.outrogroups)t.pending.delete(_),t.done.delete(_);if(_.f&8192&&(nr(_),o&&(_.nodes?.a?.unfix(),(f??=new Set).delete(_))),_.f&33554432)if(_.f^=ae,_===l)Ci(_,null,n);else{var y=d?d.next:l;_===e.effect.last&&(e.effect.last=_.prev),_.prev&&(_.prev.next=_.next),_.next&&(_.next.prev=_.prev),wi(e,d,_),wi(e,_,y),Ci(_,y,n),d=_,p=[],m=[],l=bi(d.next);continue}if(_!==l){if(u!==void 0&&u.has(_)){if(p.length<m.length){var b=m[0],ee;d=b.prev;var x=p[0],te=p[p.length-1];for(ee=0;ee<p.length;ee+=1)Ci(p[ee],b,n);for(ee=0;ee<m.length;ee+=1)u.delete(m[ee]);wi(e,x.prev,te.next),wi(e,d,x),wi(e,te,b),l=b,d=te,--v,p=[],m=[]}else u.delete(_),Ci(_,l,n),wi(e,_.prev,_.next),wi(e,_,d===null?e.effect.first:d.next),wi(e,d,_),d=_;continue}for(p=[],m=[];l!==null&&l!==_;)(u??=new Set).add(l),m.push(l),l=bi(l.next);if(l===null)continue}_.f&33554432||p.push(_),d=_,l=bi(_.next)}if(e.outrogroups!==null){for(let t of e.outrogroups)t.pending.size===0&&(_i(e,r(t.done)),e.outrogroups?.delete(t));e.outrogroups.size===0&&(e.outrogroups=null)}if(l!==null||u!==void 0){var ne=[];if(u!==void 0)for(_ of u)_.f&8192||ne.push(_);for(;l!==null;)!(l.f&8192)&&l!==e.fallback&&ne.push(l),l=bi(l.next);var re=ne.length;if(re>0){var ie=i&4&&s===0?n:null;if(o){for(v=0;v<re;v+=1)ne[v].nodes?.a?.measure();for(v=0;v<re;v+=1)ne[v].nodes?.a?.fix()}gi(e,ne,ie)}}o&&ct(()=>{if(f!==void 0)for(_ of f)_.nodes?.a?.apply()})}function Si(e,t,n,r,i,a,o,s){var c=o&1?o&16?sn(n):cn(n,!1,!1):null,l=o&2?sn(i):null;return{v:c,i:l,e:Jn(()=>(a(t,c??n,l??i,s),()=>{e.delete(r)}))}}function Ci(e,t,n){if(e.nodes)for(var r=e.nodes.start,i=e.nodes.end,a=t&&!(t.f&33554432)?t.nodes.start:n;r!==null;){var o=Cn(r);if(a.before(r),r===i)return;r=o}}function wi(e,t,n){t===null?e.effect.first=n:t.next=n,n===null?e.effect.last=t:n.prev=t}function J(e,t,...n){var r=new fi(e);Kn(()=>{let e=t()??null;r.ensure(e,e&&(t=>e(t,...n)))},ne)}function Ti(e,t,n){var r;C&&(r=w,He());var i=new fi(e);Kn(()=>{var e=t()??null;if(C&&Ge(r)===`[`!=(e!==null)){var a=We();T(a),i.anchor=a,Ve(!1),i.ensure(e,e&&(t=>n(t,e))),Ve(!0);return}i.ensure(e,e&&(t=>n(t,e)))},ne)}function Ei(e,t,n,r,i,a){let o=C;C&&He();var s=null;C&&w.nodeType===1&&(s=w,He());var c=C?w:e,l=new fi(c,!1);Kn(()=>{let e=t()||null;var a=i?i():n||e===`svg`?Fe:void 0;if(e===null){l.ensure(null,null);return}return l.ensure(e,t=>{if(e){if(s=C?s:En(e,a),ni(s,s),r){var n=null;C&&Ur(e)&&s.append(n=document.createComment(``));var i=C?Sn(s):s.appendChild(xn());C&&(i===null?Ve(!1):T(i)),r(s,i),n?.remove()}V.nodes.end=s,t.before(s)}C&&T(t)}),()=>{}},ne),Ln(()=>{}),o&&(Ve(!0),T(c))}function Di(e,t){var n=void 0,r;qn(()=>{n!==(n=t())&&(r&&=(z(r),null),n&&(r=Jn(()=>{Un(()=>n(e))})))})}function Oi(e){var t,n,r=``;if(typeof e==`string`||typeof e==`number`)r+=e;else if(typeof e==`object`)if(Array.isArray(e)){var i=e.length;for(t=0;t<i;t++)e[t]&&(n=Oi(e[t]))&&(r&&(r+=` `),r+=n)}else for(n in e)e[n]&&(r&&(r+=` `),r+=n);return r}function ki(){for(var e,t,n=0,r=``,i=arguments.length;n<i;n++)(e=arguments[n])&&(t=Oi(e))&&(r&&(r+=` `),r+=t);return r}function Ai(e){return typeof e==`object`?ki(e):e??``}var ji=[...` \t\n\\r\\f\\xA0\\v`];function Mi(e,t,n){var r=e==null?``:``+e;if(t&&(r=r?r+` `+t:t),n){for(var i of Object.keys(n))if(n[i])r=r?r+` `+i:i;else if(r.length)for(var a=i.length,o=0;(o=r.indexOf(i,o))>=0;){var s=o+a;(o===0||ji.includes(r[o-1]))&&(s===r.length||ji.includes(r[s]))?r=(o===0?``:r.substring(0,o))+r.substring(s+1):o=s}}return r===``?null:r}function Ni(e,t=!1){var n=t?` !important;`:`;`,r=``;for(var i of Object.keys(e)){var a=e[i];a!=null&&a!==``&&(r+=` `+i+`: `+a+n)}return r}function Pi(e){return e[0]!==`-`||e[1]!==`-`?e.toLowerCase():e}function Fi(e,t){if(t){var n=``,r,i;if(Array.isArray(t)?(r=t[0],i=t[1]):r=t,e){e=String(e).replaceAll(/\\s*\\/\\*.*?\\*\\/\\s*/g,``).trim();var a=!1,o=0,s=!1,c=[];r&&c.push(...Object.keys(r).map(Pi)),i&&c.push(...Object.keys(i).map(Pi));var l=0,u=-1;let t=e.length;for(var d=0;d<t;d++){var f=e[d];if(s?f===`/`&&e[d-1]===`*`&&(s=!1):a?a===f&&(a=!1):f===`/`&&e[d+1]===`*`?s=!0:f===`\"`||f===`'`?a=f:f===`(`?o++:f===`)`&&o--,!s&&a===!1&&o===0){if(f===`:`&&u===-1)u=d;else if(f===`;`||d===t-1){if(u!==-1){var p=Pi(e.substring(l,u).trim());if(!c.includes(p)){f!==`;`&&d++;var m=e.substring(l,d).trim();n+=` `+m+`;`}}l=d+1,u=-1}}}}return r&&(n+=Ni(r)),i&&(n+=Ni(i,!0)),n=n.trim(),n===``?null:n}return e==null?null:String(e)}function Ii(e,t,n,r,i,a){var o=e[me];if(C||o!==n||o===void 0){var s=Mi(n,r,a);(!C||s!==e.getAttribute(`class`))&&(s==null?e.removeAttribute(`class`):t?e.className=s:e.setAttribute(`class`,s)),e[me]=n}else if(a&&i!==a)for(var c in a){var l=!!a[c];(i==null||l!==!!i[c])&&e.classList.toggle(c,l)}return a}function Li(e,t={},n,r){for(var i in n){var a=n[i];t[i]!==a&&(n[i]==null?e.style.removeProperty(i):e.style.setProperty(i,a,r))}}function Ri(e,t,n,r){var i=e[he];if(C||i!==t){var a=Fi(t,r);(!C||a!==e.getAttribute(`style`))&&(a==null?e.removeAttribute(`style`):e.style.cssText=a),e[he]=t}else r&&(Array.isArray(r)?(Li(e,n?.[0],r[0]),Li(e,n?.[1],r[1],`important`)):Li(e,n,r));return r}function zi(t,n,r=!1){if(t.multiple){if(n==null)return;if(!e(n))return ze();for(var i of t.options)i.selected=n.includes(Vi(i));return}for(i of t.options)if(hn(Vi(i),n)){i.selected=!0;return}(!r||n!==void 0)&&(t.selectedIndex=-1)}function Bi(e){var t=new MutationObserver(()=>{zi(e,e.__value)});t.observe(e,{childList:!0,subtree:!0,attributes:!0,attributeFilter:[`value`]}),Ln(()=>{t.disconnect()})}function Vi(e){return`__value`in e?e.__value:e.value}var Hi=Symbol(`class`),Ui=Symbol(`style`),Wi=Symbol(`is custom element`),Gi=Symbol(`is html`),Ki=ye?`link`:`LINK`,qi=ye?`input`:`INPUT`,Ji=ye?`option`:`OPTION`,Yi=ye?`select`:`SELECT`;function Xi(e){if(C){var t=!1,n=()=>{if(!t){if(t=!0,e.hasAttribute(`value`)){var n=e.value;Qi(e,`value`,null),e.value=n}if(e.hasAttribute(`checked`)){var r=e.checked;Qi(e,`checked`,null),e.checked=r}}};e[_e]=n,ct(n),An()}}function Zi(e,t){t?e.hasAttribute(`selected`)||e.setAttribute(`selected`,``):e.removeAttribute(`selected`)}function Qi(e,t,n,r){var i=ta(e);C&&(i[t]=e.getAttribute(t),t===`src`||t===`srcset`||t===`href`&&e.nodeName===Ki)||i[t]!==(i[t]=n)&&(t===`loading`&&(e[fe]=n),n==null?e.removeAttribute(t):typeof n!=`string`&&ra(e).includes(t)?e[t]=n:e.setAttribute(t,n))}function $i(e,t,n,r,i=!1,a=!1){if(C&&i&&e.nodeName===qi){var o=e;(o.type===`checkbox`?`defaultChecked`:`defaultValue`)in n||Xi(o)}var s=ta(e),c=s[Wi],l=!s[Gi];let u=C&&c;u&&Ve(!1);var d=t||{},f=e.nodeName===Ji;for(var p in t)p in n||(n[p]=null);n.class?n.class=Ai(n.class):(r||n[Hi])&&(n.class=null),n[Ui]&&(n.style??=null);var m=ra(e);if(e.nodeName===qi&&`type`in n&&(`value`in n||`__value`in n)){var h=n.type;(h!==d.type||h===void 0&&e.hasAttribute(`type`))&&(d.type=h,Qi(e,`type`,h,a))}for(let i in n){let o=n[i];if(f&&i===`value`&&o==null){e.value=e.__value=``,d[i]=o;continue}if(i===`class`){Ii(e,e.namespaceURI===`http://www.w3.org/1999/xhtml`,o,r,t?.[Hi],n[Hi]),d[i]=o,d[Hi]=n[Hi];continue}if(i===`style`){Ri(e,o,t?.[Ui],n[Ui]),d[i]=o,d[Ui]=n[Ui];continue}var g=d[i];if(!(o===g&&!(o===void 0&&e.hasAttribute(i)))){d[i]=o;var _=i[0]+i[1];if(_!==`$$`)if(_===`on`){let t={},n=`$$`+i,r=i.slice(2);var v=Ir(r);if(Pr(r)&&(r=r.slice(0,-7),t.capture=!0),!v&&g){if(o!=null)continue;e.removeEventListener(r,d[n],t),d[n]=null}if(v)Yr(r,e,o),Xr([r]);else if(o!=null){function a(e){d[i].call(this,e)}d[n]=qr(r,e,a,t)}}else if(i===`style`)Qi(e,i,o);else if(i===`autofocus`)On(e,!!o);else if(!c&&(i===`__value`||i===`value`&&o!=null))e.value=e.__value=o;else if(i===`selected`&&f)Zi(e,o);else{var y=i;l||(y=zr(y));var b=y===`defaultValue`||y===`defaultChecked`;if(o==null&&!c&&!b)if(s[i]=null,y===`value`||y===`checked`){let n=e,r=t===void 0;if(y===`value`){let e=n.defaultValue;n.removeAttribute(y),n.defaultValue=e,n.value=n.__value=r?e:null}else{let e=n.defaultChecked;n.removeAttribute(y),n.defaultChecked=e,n.checked=r?e:!1}}else e.removeAttribute(i);else b||m.includes(y)&&(c||typeof o!=`string`)?(e[y]=o,y in s&&(s[y]=S)):typeof o!=`function`&&Qi(e,y,o,a)}}}return u&&Ve(!0),d}function ea(e,t,n=[],r=[],i=[],a,o=!1,s=!1){Ct(i,n,r,n=>{var r=void 0,i={},c=e.nodeName===Yi,l=!1;if(qn(()=>{var u=t(...n.map(H)),d=$i(e,r,u,a,o,s);l&&c&&`value`in u&&zi(e,u.value);for(let e of Object.getOwnPropertySymbols(i))u[e]||z(i[e]);for(let t of Object.getOwnPropertySymbols(u)){var f=u[t];t.description===`@attach`&&(!r||f!==r[t])&&(i[t]&&z(i[t]),i[t]=Jn(()=>Di(e,()=>f))),d[t]=f}r=d}),c){var u=e;Un(()=>{zi(u,r.value,!0),Bi(u)})}l=!0})}function ta(e){return e[pe]??={[Wi]:e.nodeName.includes(`-`),[Gi]:e.namespaceURI===Pe}}var na=new Map;function ra(e){var t=e.getAttribute(`is`)||e.nodeName,n=na.get(t);if(n)return n;na.set(t,n=[]);for(var r,i=e,a=Element.prototype;a!==i;){for(var s in r=o(i),r)r[s].set&&s!==`innerHTML`&&s!==`textContent`&&s!==`innerText`&&n.push(s);i=l(i)}return n}function ia(e,t,n=t){var r=new WeakSet;Mn(e,`input`,async i=>{var a=i?e.defaultValue:e.value;if(a=aa(e)?oa(a):a,n(a),M!==null&&r.add(M),await kr(),a!==(a=t())){var o=e.selectionStart,s=e.selectionEnd,c=e.value.length;if(e.value=a??``,s!==null){var l=e.value.length;o===s&&s===c&&l>c?(e.selectionStart=l,e.selectionEnd=l):(e.selectionStart=o,e.selectionEnd=Math.min(s,l))}}}),(C&&e.defaultValue!==e.value||Mr(t)==null&&e.value)&&(n(aa(e)?oa(e.value):e.value),M!==null&&r.add(M)),Gn(()=>{var n=t();if(e===document.activeElement){var i=Ye?Rt:M;if(r.has(i))return}aa(e)&&n===oa(e.value)||e.type===`date`&&!n&&!e.value||n!==e.value&&(e.value=n??``)})}function aa(e){var t=e.type;return t===`number`||t===`range`}function oa(e){return e===``?null:+e}var sa={get(e,t){if(!e.exclude.has(t))return e.props[t]},set(e,t){return!1},getOwnPropertyDescriptor(e,t){if(!e.exclude.has(t)&&t in e.props)return{enumerable:!0,configurable:!0,value:e.props[t]}},has(e,t){return e.exclude.has(t)?!1:t in e.props},ownKeys(e){return Reflect.ownKeys(e.props).filter(t=>!e.exclude.has(t))}};function ca(e,t,n){return new Proxy({props:e,exclude:t},sa)}var la={get(e,t){let n=e.props.length;for(;n--;){let r=e.props[n];if(d(r)&&(r=r()),typeof r==`object`&&r&&t in r)return r[t]}},set(e,t,n){let r=e.props.length;for(;r--;){let i=e.props[r];d(i)&&(i=i());let o=a(i,t);if(o&&o.set)return o.set(n),!0}return!1},getOwnPropertyDescriptor(e,t){let n=e.props.length;for(;n--;){let r=e.props[n];if(d(r)&&(r=r()),typeof r==`object`&&r&&t in r){let e=a(r,t);return e&&!e.configurable&&(e.configurable=!0),e}}},has(e,t){if(t===ue||t===de)return!1;for(let n of e.props)if(d(n)&&(n=n()),n!=null&&t in n)return!0;return!1},ownKeys(e){let t=[];for(let n of e.props)if(d(n)&&(n=n()),n){for(let e in n)t.includes(e)||t.push(e);for(let e of Object.getOwnPropertySymbols(n))t.includes(e)||t.push(e)}return t}};function ua(...e){return new Proxy({props:e},la)}function Y(e,t,n,r){var i=!Xe||(n&2)!=0,o=(n&8)!=0,s=(n&16)!=0,c=r,l=!0,u=void 0,d=()=>s&&i?(u??=Dt(r),H(u)):(l&&(l=!1,c=s?Mr(r):r),c);let f;if(o){var p=ue in e||de in e;f=a(e,t)?.set??(p&&t in e?n=>e[t]=n:void 0)}var m,h=!1;o?[m,h]=vt(()=>e[t]):m=e[t],m===void 0&&r!==void 0&&(m=d(),f&&(i&&De(t),f(m)));var g=i?()=>{var n=e[t];return n===void 0?d():(l=!0,n)}:()=>{var n=e[t];return n!==void 0&&(c=void 0),n===void 0?c:n};if(i&&!(n&4))return g;if(f){var _=e.$$legacy;return(function(e,t){return arguments.length>0?((!i||!t||_||h)&&f(t?g():e),e):g()})}var v=!1,y=(n&1?Dt:At)(()=>(v=!1,g()));o&&H(y);var b=V;return(function(e,t){if(arguments.length>0){let n=t?H(y):i&&o?pn(e):e;return P(y,n),v=!0,c!==void 0&&(c=n),e}return sr&&v||b.f&16384?y.v:H(y)})}function da(e){D===null&&be(`onMount`),Xe&&D.l!==null?fa(D).m.push(e):Rn(()=>{let t=Mr(e);if(typeof t==`function`)return t})}function fa(e){var t=e.l;return t.u??={a:[],b:[],m:[]}}typeof window<`u`&&((window.__svelte??={}).v??=new Set).add(`5`);var X=new class{#e=N(null);get data(){return H(this.#e)}set data(e){P(this.#e,e,!0)}#t=N(null);get arsenal(){return H(this.#t)}set arsenal(e){P(this.#t,e,!0)}#n=N(`connecting`);get status(){return H(this.#n)}set status(e){P(this.#n,e,!0)}#r=N(``);get clock(){return H(this.#r)}set clock(e){P(this.#r,e,!0)}#i=N(`overview`);get view(){return H(this.#i)}set view(e){P(this.#i,e,!0)}#a=N(!1);get arsenalLoading(){return H(this.#a)}set arsenalLoading(e){P(this.#a,e,!0)}#o=!1;#s=null;async tick(){try{let e=await fetch(`/data`);if(!e.ok)throw Error(`HTTP ${e.status}`);this.data=await e.json(),this.status=`live`,this.clock=new Date().toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`})}catch{this.status=`offline`}}start(){this.tick(),this.#s=setInterval(()=>void this.tick(),1e4)}stop(){this.#s&&clearInterval(this.#s)}async loadArsenal(e=!1){if(!(this.#o&&!e)){this.arsenalLoading=!0;try{let e=await fetch(`/arsenal`);e.ok&&(this.arsenal=await e.json(),this.#o=!0)}catch{}finally{this.arsenalLoading=!1}}}go(e){this.view=e,e===`arsenal`&&this.loadArsenal()}};function Z(e){return typeof e!=`number`||!Number.isFinite(e)?`0`:e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:String(Math.round(e))}function pa(e){return typeof e!=`number`||!Number.isFinite(e)?`$0.00`:`$${e.toLocaleString(`en-US`,{minimumFractionDigits:2,maximumFractionDigits:2})}`}function ma(e){if(!e)return`—`;let t=new Date(e);if(Number.isNaN(t.getTime()))return`—`;let n=new Date;return t.getFullYear()===n.getFullYear()&&t.getMonth()===n.getMonth()&&t.getDate()===n.getDate()?t.toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}):t.toLocaleDateString([],{month:`short`,day:`numeric`})}function ha(e){if(!e)return`unknown`;let t=e.toLowerCase();return t===`<synthetic>`?`unknown`:t.includes(`fable`)?`fable`:t.includes(`opus`)?`opus`:t.includes(`sonnet`)?`sonnet`:t.includes(`haiku`)?`haiku`:`unknown`}function ga(e){return!e||e===`<synthetic>`?`synthetic`:e.replace(/^claude-/,``)}function _a(e){if(!e)return``;let t=e.split(/[/\\\\]/).filter(Boolean);return t.length<=2?t.join(`/`):`…/${t.slice(-2).join(`/`)}`}var va=[220,75,20,155,285,330,250,45];function ya(e){let t=0;for(let n=0;n<e.length;n++)t=t*31+e.charCodeAt(n)>>>0;return`oklch(72% 0.15 ${va[t%va.length]})`}var ba={xmlns:`http://www.w3.org/2000/svg`,width:24,height:24,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,\"stroke-width\":2,\"stroke-linecap\":`round`,\"stroke-linejoin\":`round`},xa=e=>{for(let t in e)if(t.startsWith(`aria-`)||t===`role`||t===`title`)return!0;return!1},Sa=Symbol(`lucide-context`),Ca=()=>$e(Sa),wa=new Set([`$$slots`,`$$events`,`$$legacy`,`name`,`color`,`size`,`strokeWidth`,`absoluteStrokeWidth`,`iconNode`,`children`]),Ta=ii(`<svg><!><!></svg>`);function Ea(e,t){O(t,!0);let n=Ca()??{},r=Y(t,`color`,19,()=>n.color??`currentColor`),i=Y(t,`size`,19,()=>n.size??24),a=Y(t,`strokeWidth`,19,()=>n.strokeWidth??2),o=Y(t,`absoluteStrokeWidth`,19,()=>n.absoluteStrokeWidth??!1),s=Y(t,`iconNode`,19,()=>[]),c=ca(t,wa),l=j(()=>o()?Number(a())*24/Number(i()):a());var u=Ta();ea(u,e=>({...ba,...e,...c,width:i(),height:i(),stroke:r(),\"stroke-width\":H(l),class:[`lucide-icon lucide`,n.class,t.name&&`lucide-${t.name}`,t.class]}),[()=>!t.children&&!xa(c)&&{\"aria-hidden\":`true`}]);var d=F(u);yi(d,17,s,hi,(e,t)=>{var n=j(()=>h(H(t),2));let r=()=>H(n)[0],i=()=>H(n)[1];var a=W();Ei(I(a),r,!0,(e,t)=>{ea(e,()=>({...i()}))}),G(e,a)}),J(L(d),()=>t.children??f),E(u),G(e,u),k()}var Da=new Set([`$$slots`,`$$events`,`$$legacy`]);function Oa(e,t){let n=ca(t,Da),r=[[`rect`,{width:`7`,height:`9`,x:`3`,y:`3`,rx:`1`}],[`rect`,{width:`7`,height:`5`,x:`14`,y:`3`,rx:`1`}],[`rect`,{width:`7`,height:`9`,x:`14`,y:`12`,rx:`1`}],[`rect`,{width:`7`,height:`5`,x:`3`,y:`16`,rx:`1`}]];Ea(e,ua({name:`layout-dashboard`},()=>n,{get iconNode(){return r}}))}var ka=new Set([`$$slots`,`$$events`,`$$legacy`]);function Aa(e,t){let n=ca(t,ka),r=[[`polyline`,{points:`14.5 17.5 3 6 3 3 6 3 17.5 14.5`}],[`line`,{x1:`13`,x2:`19`,y1:`19`,y2:`13`}],[`line`,{x1:`16`,x2:`20`,y1:`16`,y2:`20`}],[`line`,{x1:`19`,x2:`21`,y1:`21`,y2:`19`}],[`polyline`,{points:`14.5 6.5 18 3 21 3 21 6 17.5 9.5`}],[`line`,{x1:`5`,x2:`9`,y1:`14`,y2:`18`}],[`line`,{x1:`7`,x2:`4`,y1:`17`,y2:`20`}],[`line`,{x1:`3`,x2:`5`,y1:`19`,y2:`21`}]];Ea(e,ua({name:`swords`},()=>n,{get iconNode(){return r}}))}var ja=new Set([`$$slots`,`$$events`,`$$legacy`]);function Ma(e,t){let n=ca(t,ja),r=[[`circle`,{cx:`12`,cy:`12`,r:`10`}],[`path`,{d:`M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3`}],[`path`,{d:`M12 17h.01`}]];Ea(e,ua({name:`circle-question-mark`},()=>n,{get iconNode(){return r}}))}var Na=new Set([`$$slots`,`$$events`,`$$legacy`]);function Pa(e,t){let n=ca(t,Na),r=[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`}],[`path`,{d:`M9 3v18`}]];Ea(e,ua({name:`panel-left`},()=>n,{get iconNode(){return r}}))}var Fa=U(`<div class=\"min-w-0\"><div class=\"font-serif text-lg leading-none text-foreground\">Synth<em>ra</em></div> <div class=\"font-mono text-[9px] uppercase tracking-[0.18em] text-muted-foreground\">Dashboard</div></div>`),Ia=U(`<span class=\"font-mono text-[11px] text-muted-foreground\"> </span>`),La=U(`<span> </span>`),Ra=U(`<button><!> <!></button>`),za=U(`<span>FAQ</span>`),Ba=U(`<div class=\"flex flex-col gap-1 rounded-lg bg-sidebar-accent/40 p-2.5\"><div class=\"font-mono text-[9px] uppercase tracking-[0.14em] text-muted-foreground\">Active</div> <div class=\"truncate font-mono text-[11px] text-sidebar-foreground\"> </div> <div class=\"mt-1 flex items-center justify-between font-mono text-[9px] text-muted-foreground\"><span> </span> <span>v__SYN_VERSION__</span></div></div>`),Va=U(`<span class=\"text-xs\">Collapse</span>`),Ha=U(`<aside><div class=\"flex items-center gap-2.5 px-1 py-2\"><div class=\"grid size-8 shrink-0 place-items-center rounded-lg bg-primary/90 font-serif text-lg italic text-primary-foreground\">S</div> <!></div> <div><span></span> <!></div> <div class=\"my-1 h-px bg-sidebar-border\"></div> <nav class=\"flex flex-col gap-1\"><!> <button title=\"FAQ\"><!> <!></button></nav> <div class=\"flex-1\"></div> <!> <button title=\"Toggle sidebar\"><!> <!></button></aside>`);function Ua(e,t){O(t,!0);let n=N(!1),r=typeof window<`u`&&window.location.port||`8901`,i=[{id:`overview`,label:`Overview`,icon:Oa},{id:`arsenal`,label:`Arsenal`,icon:Aa}];var a=Ha(),o=F(a),s=L(F(o),2),c=e=>{G(e,Fa())};q(s,e=>{H(n)||e(c)}),E(o);var l=L(o,2),u=F(l);let d;var f=L(u,2),p=e=>{var t=Ia(),n=F(t,!0);E(t),R(()=>K(n,X.status===`live`?`live · ${X.clock}`:X.status)),G(e,t)};q(f,e=>{H(n)||e(p)}),E(l);var m=L(l,4),h=F(m);yi(h,17,()=>i,e=>e.id,(e,t)=>{var r=Ra(),i=F(r);Ti(i,()=>H(t).icon,(e,t)=>{t(e,{class:`size-4 shrink-0`})});var a=L(i,2),o=e=>{var n=La(),r=F(n,!0);E(n),R(()=>K(r,H(t).label)),G(e,n)};q(a,e=>{H(n)||e(o)}),E(r),R(()=>{Qi(r,`title`,H(t).label),Ii(r,1,`flex items-center gap-2.5 rounded-lg px-2.5 py-2 text-sm transition-colors `+(X.view===H(t).id?`bg-sidebar-accent text-sidebar-accent-foreground`:`text-sidebar-foreground/75 hover:bg-sidebar-accent/50 hover:text-sidebar-foreground`)+(H(n)?` justify-center`:``))}),Yr(`click`,r,()=>X.go(H(t).id)),G(e,r)});var g=L(h,2),_=F(g);Ma(_,{class:`size-4 shrink-0`});var v=L(_,2),y=e=>{G(e,za())};q(v,e=>{H(n)||e(y)}),E(g),E(m);var b=L(m,4),ee=e=>{var t=Ba(),n=L(F(t),2),i=F(n,!0);E(n);var a=L(n,2),o=F(a),s=F(o);E(o),Ue(2),E(a),E(t),R(()=>{Qi(n,`title`,X.data?.active?.project_root??`—`),K(i,X.data?.active?.project_name??`—`),K(s,`port ${r??``}`)}),G(e,t)};q(b,e=>{H(n)||e(ee)});var x=L(b,2),te=F(x);Pa(te,{class:`size-4 shrink-0`});var ne=L(te,2),re=e=>{G(e,Va())};q(ne,e=>{H(n)||e(re)}),E(x),E(a),R(()=>{Ii(a,1,`flex h-screen shrink-0 flex-col gap-1 border-r border-sidebar-border bg-sidebar p-3 transition-[width] duration-200 `+(H(n)?`w-[64px] items-center`:`w-[248px]`)),Ii(l,1,`flex items-center gap-2 rounded-md px-2 py-1.5 `+(H(n)?`justify-center`:``)),d=Ii(u,1,`size-2 shrink-0 rounded-full `+(X.status===`live`?`bg-[var(--c-fable)]`:X.status===`offline`?`bg-destructive`:`bg-muted-foreground`),null,d,{\"animate-pulse\":X.status===`live`}),Ii(g,1,`flex items-center gap-2.5 rounded-lg px-2.5 py-2 text-sm text-sidebar-foreground/75 transition-colors hover:bg-sidebar-accent/50 hover:text-sidebar-foreground `+(H(n)?`justify-center`:``)),Ii(x,1,`mt-1 flex items-center gap-2.5 rounded-lg px-2.5 py-2 text-sidebar-foreground/60 transition-colors hover:bg-sidebar-accent/50 hover:text-sidebar-foreground `+(H(n)?`justify-center`:``))}),Yr(`click`,g,function(...e){t.onFaq?.apply(this,e)}),Yr(`click`,x,()=>P(n,!H(n))),G(e,a),k()}Xr([`click`]),Ze();var Wa=U(`<div class=\"flex flex-col gap-1 bg-card/70 p-4\"><span class=\"font-mono text-[10px] uppercase tracking-[0.12em] text-muted-foreground\"> </span> <span class=\"font-mono text-2xl tabular-nums text-foreground\"> </span></div>`),Ga=U(`<div class=\"grid grid-cols-2 gap-px overflow-hidden rounded-xl border bg-border sm:grid-cols-3 lg:grid-cols-5\"></div>`);function Ka(e,t){O(t,!0);let n=j(()=>{let e=X.data?.global;return[{label:`Turns`,v:e?.total_turns??0},{label:`↓ Input`,v:e?.total_input_tokens??0},{label:`↑ Output`,v:e?.total_output_tokens??0},{label:`⟲ Cache R`,v:e?.total_cache_read??0},{label:`+ Cache W`,v:e?.total_cache_create??0}]});var r=Ga();yi(r,21,()=>H(n),e=>e.label,(e,t)=>{var n=Wa(),r=F(n),i=F(r,!0);E(r);var a=L(r,2),o=F(a,!0);E(a),E(n),R(e=>{K(i,H(t).label),K(o,e)},[()=>Z(H(t).v)]),G(e,n)}),E(r),G(e,r),k()}var qa=U(`<span class=\"font-mono text-[9px] uppercase tracking-[0.12em] text-muted-foreground\"> </span>`),Ja=U(`<header class=\"flex items-baseline justify-between gap-3\"><span class=\"font-mono text-[10px] uppercase tracking-[0.14em] text-muted-foreground\"> </span> <!></header>`),Ya=U(`<section><!> <!></section>`);function Xa(e,t){let n=Y(t,`class`,3,``);var r=Ya(),i=F(r),a=e=>{var n=Ja(),r=F(n),i=F(r,!0);E(r);var a=L(r,2),o=e=>{var n=qa(),r=F(n,!0);E(n),R(()=>K(r,t.meta)),G(e,n)};q(a,e=>{t.meta&&e(o)}),E(n),R(()=>K(i,t.title)),G(e,n)};q(i,e=>{t.title&&e(a)}),J(L(i,2),()=>t.children??f),E(r),R(()=>Ii(r,1,`flex min-h-0 flex-col gap-3 rounded-xl border bg-card/55 p-4 transition-colors hover:bg-card/80 `+n())),G(e,r)}var Za=U(`<div class=\"flex flex-col gap-3\"><div><div class=\"font-mono text-3xl text-[var(--money)]\"> </div> <div class=\"font-mono text-[11px] text-muted-foreground\"> </div></div> <div class=\"flex h-2 overflow-hidden rounded-full bg-border\"><div class=\"h-full bg-muted-foreground/40\"></div> <div class=\"h-full bg-[var(--money)]\"></div></div> <div class=\"flex justify-between font-mono text-[10px] text-muted-foreground\"><span>you paid <b class=\"text-foreground\"> </b></span> <span>baseline <b class=\"text-foreground\"> </b></span></div> <div class=\"rounded-md border border-dashed border-border px-3 py-2 text-center font-mono text-[10px] text-muted-foreground\"><b class=\"text-foreground\"> </b> blocks × <b class=\"text-foreground\">500</b> tokens × <b class=\"text-foreground\">$3</b>/M = <b class=\"text-[var(--money)]\"> </b></div></div>`);function Qa(e,t){O(t,!0);let n=j(()=>{let e=X.data?.global,t=e?.blocked_count??0,n=t*500*3/1e6,r=e?.estimated_cost_usd??0,i=r+n;return{blocks:t,money:n,paid:r,baseline:i,pct:i>0?n/i*100:0,tokens:e?.estimated_tokens_saved??0,paidWidth:i>0?r/i*100:100}});{let t=j(()=>`${H(n).pct.toFixed(1)}% off · floor`);Xa(e,{title:`Synthra savings`,get meta(){return H(t)},children:(e,t)=>{var r=Za(),i=F(r),a=F(i),o=F(a,!0);E(a);var s=L(a,2),c=F(s);E(s),E(i);var l=L(i,2),u=F(l),d=L(u,2);E(l);var f=L(l,2),p=F(f),m=L(F(p)),h=F(m,!0);E(m),E(p);var g=L(p,2),_=L(F(g)),v=F(_,!0);E(_),E(g),E(f);var y=L(f,2),b=F(y),ee=F(b,!0);E(b);var x=L(b,6),te=F(x,!0);E(x),E(y),E(r),R((e,t,r,i,a)=>{K(o,e),K(c,`${t??``} tokens avoided`),Ri(u,`width:${H(n).paidWidth}%`),Ri(d,`width:${100-H(n).paidWidth}%`),K(h,r),K(v,i),K(ee,H(n).blocks),K(te,a)},[()=>pa(H(n).money),()=>Z(H(n).tokens),()=>pa(H(n).paid),()=>pa(H(n).baseline),()=>pa(H(n).money)]),G(e,r)},$$slots:{default:!0}})}k()}var $a=U(`<div class=\"font-mono text-3xl text-[var(--money)]\"> </div> <div class=\"mt-1 flex flex-col gap-1 font-mono text-[11px] text-muted-foreground\"><div class=\"flex justify-between\"><span>Tokens (in+out)</span><span class=\"text-foreground\"> </span></div> <div class=\"flex justify-between\"><span>Avg / turn</span><span class=\"text-foreground\"> </span></div></div>`,1);function eo(e,t){O(t,!0);let n=j(()=>{let e=X.data?.global,t=e?.total_turns??0,n=e?.estimated_cost_usd??0;return{cost:n,tokens:(e?.total_input_tokens??0)+(e?.total_output_tokens??0),avg:t>0?n/t:0}});Xa(e,{title:`Total spend`,meta:`all time`,children:(e,t)=>{var r=$a(),i=I(r),a=F(i,!0);E(i);var o=L(i,2),s=F(o),c=L(F(s)),l=F(c,!0);E(c),E(s);var u=L(s,2),d=L(F(u)),f=F(d,!0);E(d),E(u),E(o),R((e,t,n)=>{K(a,e),K(l,t),K(f,n)},[()=>pa(H(n).cost),()=>Z(H(n).tokens),()=>pa(H(n).avg)]),G(e,r)},$$slots:{default:!0}}),k()}var to=ii(`<circle cx=\"70\" cy=\"70\" r=\"52\" fill=\"none\" stroke-width=\"14\"></circle>`),no=U(`<div class=\"flex items-center gap-2 font-mono text-[11px]\"><span class=\"size-2 rounded-sm\"></span> <span class=\"flex-1 text-muted-foreground\"> </span> <span class=\"tabular-nums text-foreground\"> </span> <span class=\"w-9 text-right tabular-nums text-muted-foreground\"> </span></div>`),ro=U(`<div class=\"text-[11px] text-muted-foreground\">No turns yet.</div>`),io=U(`<div class=\"flex items-center gap-4\"><div class=\"relative size-[116px] shrink-0\"><svg viewBox=\"0 0 140 140\" class=\"size-full -rotate-90\"><circle cx=\"70\" cy=\"70\" r=\"52\" fill=\"none\" stroke=\"var(--border)\" stroke-width=\"14\"></circle><!></svg> <div class=\"absolute inset-0 grid place-items-center\"><div class=\"text-center\"><div class=\"font-mono text-2xl text-foreground\"> </div> <div class=\"font-mono text-[9px] uppercase text-muted-foreground\">turns</div></div></div></div> <div class=\"flex min-w-0 flex-1 flex-col gap-1.5\"></div></div>`);function ao(e,t){O(t,!0);let n=[{fam:`fable`,label:`Fable`,color:`var(--c-fable)`},{fam:`opus`,label:`Opus`,color:`var(--c-opus)`},{fam:`sonnet`,label:`Sonnet`,color:`var(--c-sonnet)`},{fam:`haiku`,label:`Haiku`,color:`var(--c-haiku)`},{fam:`unknown`,label:`Other`,color:`var(--c-unknown)`}],r=2*Math.PI*52,i=j(()=>{let e={fable:0,opus:0,sonnet:0,haiku:0,unknown:0};for(let t of X.data?.projects??[])for(let[n,r]of Object.entries(t.models??{}))e[ha(n)]+=r;let t=n.reduce((t,n)=>t+e[n.fam],0),i=0;return{arcs:n.filter(t=>e[t.fam]>0).map(n=>{let a=e[n.fam],o=t>0?a/t*r:0,s={...n,n:a,len:o,offset:i,pct:t>0?Math.round(a/t*100):0};return i+=o,s}),total:t}});Xa(e,{title:`Model usage`,meta:`by turns`,children:(e,t)=>{var n=io(),a=F(n),o=F(a);yi(L(F(o)),17,()=>H(i).arcs,e=>e.fam,(e,t)=>{var n=to();R(()=>{Qi(n,`stroke`,H(t).color),Qi(n,`stroke-dasharray`,`${H(t).len} ${r}`),Qi(n,`stroke-dashoffset`,-H(t).offset),Qi(n,`stroke-linecap`,H(i).arcs.length===1?`round`:`butt`)}),G(e,n)}),E(o);var s=L(o,2),c=F(s),l=F(c),u=F(l,!0);E(l),Ue(2),E(c),E(s),E(a);var d=L(a,2);yi(d,21,()=>H(i).arcs,e=>e.fam,(e,t)=>{var n=no(),r=F(n),i=L(r,2),a=F(i,!0);E(i);var o=L(i,2),s=F(o,!0);E(o);var c=L(o,2),l=F(c);E(c),E(n),R(()=>{Ri(r,`background:${H(t).color}`),K(a,H(t).label),K(s,H(t).n),K(l,`${H(t).pct??``}%`)}),G(e,n)},e=>{G(e,ro())}),E(d),E(n),R(()=>K(u,H(i).total)),G(e,n)},$$slots:{default:!0}}),k()}function oo(e){return typeof e==`object`&&!!e}var so=[`string`,`number`,`bigint`,`boolean`];function co(e){return e==null||so.includes(typeof e)?!0:Array.isArray(e)?e.every(e=>co(e)):typeof e==`object`?Object.getPrototypeOf(e)===Object.prototype:!1}var lo=Symbol(`box`),uo=Symbol(`is-writable`);function Q(e,t){let n=j(e);return t?{[lo]:!0,[uo]:!0,get current(){return H(n)},set current(e){t(e)}}:{[lo]:!0,get current(){return e()}}}function fo(e){return oo(e)&&lo in e}function po(e){let t=N(pn(e));return{[lo]:!0,[uo]:!0,get current(){return H(t)},set current(e){P(t,e,!0)}}}function mo(...e){return function(t){for(let n of e)if(n){if(t.defaultPrevented)return;typeof n==`function`?n.call(this,t):n.current?.call(this,t)}}}var ho=/\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\//g,go=/\\n/g,_o=/^\\s*/,vo=/^(\\*?[-#/*\\\\\\w]+(\\[[0-9a-z_-]+\\])?)\\s*/,yo=/^:\\s*/,bo=/^((?:'(?:\\\\'|.)*?'|\"(?:\\\\\"|.)*?\"|\\([^)]*?\\)|[^};])+)/,xo=/^[;\\s]*/,So=/^\\s+|\\s+$/g,Co=`\n`,wo=`/`,To=`*`,Eo=``,Do=`comment`,Oo=`declaration`;function ko(e,t){if(typeof e!=`string`)throw TypeError(`First argument must be a string`);if(!e)return[];t||={};var n=1,r=1;function i(e){var t=e.match(go);t&&(n+=t.length);var i=e.lastIndexOf(Co);r=~i?e.length-i:r+e.length}function a(){var e={line:n,column:r};return function(t){return t.position=new o(e),l(),t}}function o(e){this.start=e,this.end={line:n,column:r},this.source=t.source}o.prototype.content=e;function s(i){var a=Error(t.source+`:`+n+`:`+r+`: `+i);if(a.reason=i,a.filename=t.source,a.line=n,a.column=r,a.source=e,!t.silent)throw a}function c(t){var n=t.exec(e);if(n){var r=n[0];return i(r),e=e.slice(r.length),n}}function l(){c(_o)}function u(e){var t;for(e||=[];t=d();)t!==!1&&e.push(t);return e}function d(){var t=a();if(!(wo!=e.charAt(0)||To!=e.charAt(1))){for(var n=2;Eo!=e.charAt(n)&&(To!=e.charAt(n)||wo!=e.charAt(n+1));)++n;if(n+=2,Eo===e.charAt(n-1))return s(`End of comment missing`);var o=e.slice(2,n-2);return r+=2,i(o),e=e.slice(n),r+=2,t({type:Do,comment:o})}}function f(){var e=a(),t=c(vo);if(t){if(d(),!c(yo))return s(`property missing ':'`);var n=c(bo),r=e({type:Oo,property:Ao(t[0].replace(ho,Eo)),value:n?Ao(n[0].replace(ho,Eo)):Eo});return c(xo),r}}function p(){var e=[];u(e);for(var t;t=f();)t!==!1&&(e.push(t),u(e));return e}return l(),p()}function Ao(e){return e?e.replace(So,Eo):Eo}function jo(e,t){let n=null;if(!e||typeof e!=`string`)return n;let r=ko(e),i=typeof t==`function`;return r.forEach(e=>{if(e.type!==`declaration`)return;let{property:r,value:a}=e;i?t(r,a,e):a&&(n||={},n[r]=a)}),n}var Mo=/\\d/,No=[`-`,`_`,`/`,`.`];function Po(e=``){if(!Mo.test(e))return e!==e.toLowerCase()}function Fo(e){let t=[],n=``,r,i;for(let a of e){let e=No.includes(a);if(e===!0){t.push(n),n=``,r=void 0;continue}let o=Po(a);if(i===!1){if(r===!1&&o===!0){t.push(n),n=a,r=o;continue}if(r===!0&&o===!1&&n.length>1){let e=n.at(-1);t.push(n.slice(0,Math.max(0,n.length-1))),n=e+a,r=o;continue}}n+=a,r=o,i=e}return t.push(n),t}function Io(e){return e?Fo(e).map(e=>Ro(e)).join(``):``}function Lo(e){return zo(Io(e||``))}function Ro(e){return e?e[0].toUpperCase()+e.slice(1):``}function zo(e){return e?e[0].toLowerCase()+e.slice(1):``}function Bo(e){if(!e)return{};let t={};function n(e,n){if(e.startsWith(`-moz-`)||e.startsWith(`-webkit-`)||e.startsWith(`-ms-`)||e.startsWith(`-o-`)){t[Io(e)]=n;return}if(e.startsWith(`--`)){t[e]=n;return}t[Lo(e)]=n}return jo(e,n),t}function Vo(...e){return(...t)=>{for(let n of e)typeof n==`function`&&n(...t)}}function Ho(e,t){let n=RegExp(e,`g`);return e=>{if(typeof e!=`string`)throw TypeError(`expected an argument of type string, but got ${typeof e}`);return e.match(n)?e.replace(n,t):e}}var Uo=Ho(/[A-Z]/,e=>`-${e.toLowerCase()}`);function Wo(e){if(!e||typeof e!=`object`||Array.isArray(e))throw TypeError(`expected an argument of type object, but got ${typeof e}`);return Object.keys(e).map(t=>`${Uo(t)}: ${e[t]};`).join(`\n`)}function Go(e={}){return Wo(e).replace(`\n`,` `)}var Ko=new Set(`onabort.onanimationcancel.onanimationend.onanimationiteration.onanimationstart.onauxclick.onbeforeinput.onbeforetoggle.onblur.oncancel.oncanplay.oncanplaythrough.onchange.onclick.onclose.oncompositionend.oncompositionstart.oncompositionupdate.oncontextlost.oncontextmenu.oncontextrestored.oncopy.oncuechange.oncut.ondblclick.ondrag.ondragend.ondragenter.ondragleave.ondragover.ondragstart.ondrop.ondurationchange.onemptied.onended.onerror.onfocus.onfocusin.onfocusout.onformdata.ongotpointercapture.oninput.oninvalid.onkeydown.onkeypress.onkeyup.onload.onloadeddata.onloadedmetadata.onloadstart.onlostpointercapture.onmousedown.onmouseenter.onmouseleave.onmousemove.onmouseout.onmouseover.onmouseup.onpaste.onpause.onplay.onplaying.onpointercancel.onpointerdown.onpointerenter.onpointerleave.onpointermove.onpointerout.onpointerover.onpointerup.onprogress.onratechange.onreset.onresize.onscroll.onscrollend.onsecuritypolicyviolation.onseeked.onseeking.onselect.onselectionchange.onselectstart.onslotchange.onstalled.onsubmit.onsuspend.ontimeupdate.ontoggle.ontouchcancel.ontouchend.ontouchmove.ontouchstart.ontransitioncancel.ontransitionend.ontransitionrun.ontransitionstart.onvolumechange.onwaiting.onwebkitanimationend.onwebkitanimationiteration.onwebkitanimationstart.onwebkittransitionend.onwheel`.split(`.`));function qo(e){return Ko.has(e)}function Jo(...e){let t={...e[0]};for(let n=1;n<e.length;n++){let r=e[n];if(r){for(let e of Object.keys(r)){let n=t[e],i=r[e],a=typeof n==`function`,o=typeof i==`function`;if(a&&typeof o&&qo(e))t[e]=mo(n,i);else if(a&&o)t[e]=Vo(n,i);else if(e===`class`){let r=co(n),a=co(i);r&&a?t[e]=ki(n,i):r?t[e]=ki(n):a&&(t[e]=ki(i))}else if(e===`style`){let r=typeof n==`object`,a=typeof i==`object`,o=typeof n==`string`,s=typeof i==`string`;if(r&&a)t[e]={...n,...i};else if(r&&s){let r=Bo(i);t[e]={...n,...r}}else if(o&&a)t[e]={...Bo(n),...i};else if(o&&s){let r=Bo(n),a=Bo(i);t[e]={...r,...a}}else r?t[e]=n:a?t[e]=i:o?t[e]=n:s&&(t[e]=i)}else t[e]=i===void 0?n:i}for(let e of Object.getOwnPropertySymbols(r)){let n=t[e],i=r[e];t[e]=i===void 0?n:i}}}return typeof t.style==`object`&&(t.style=Go(t.style).replaceAll(`\n`,` `)),t.hidden===!1&&(t.hidden=void 0,delete t.hidden),t.disabled===!1&&(t.disabled=void 0,delete t.disabled),t}var Yo=typeof window<`u`?window:void 0;typeof window<`u`&&window.document,typeof window<`u`&&window.navigator,typeof window<`u`&&window.location;function Xo(e){let t=e.activeElement;for(;t?.shadowRoot;){let e=t.shadowRoot.activeElement;if(e===t)break;t=e}return t}var Zo=class extends Map{#e=new Map;#t=N(0);#n=N(0);#r=br||-1;constructor(e){if(super(),e){for(var[t,n]of e)super.set(t,n);this.#n.v=super.size}}#i(e){return br===this.#r?N(e):sn(e)}has(e){var t=this.#e,n=t.get(e);if(n===void 0)if(super.has(e))n=this.#i(0),t.set(e,n);else return H(this.#t),!1;return H(n),!0}forEach(e,t){this.#a(),super.forEach(e,t)}get(e){var t=this.#e,n=t.get(e);if(n===void 0)if(super.has(e))n=this.#i(0),t.set(e,n);else{H(this.#t);return}return H(n),super.get(e)}set(e,t){var n=this.#e,r=n.get(e),i=super.get(e),a=super.set(e,t),o=this.#t;if(r===void 0)r=this.#i(0),n.set(e,r),P(this.#n,super.size),dn(o);else if(i!==t){dn(r);var s=o.reactions===null?null:new Set(o.reactions);(s===null||!r.reactions?.every(e=>s.has(e)))&&dn(o)}return a}delete(e){var t=this.#e,n=t.get(e),r=super.delete(e);return n!==void 0&&(t.delete(e),P(n,-1)),r&&(P(this.#n,super.size),dn(this.#t)),r}clear(){if(super.size!==0){super.clear();var e=this.#e;P(this.#n,0);for(var t of e.values())P(t,-1);dn(this.#t),e.clear()}}#a(){H(this.#t);var e=this.#e;if(this.#n.v!==e.size){for(var t of super.keys())if(!e.has(t)){var n=this.#i(0);e.set(t,n)}}for([,n]of this.#e)H(n)}keys(){return H(this.#t),super.keys()}values(){return this.#a(),super.values()}entries(){return this.#a(),super.entries()}[Symbol.iterator](){return this.entries()}get size(){return H(this.#n),super.size}};new class{#e;#t;constructor(e={}){let{window:t=Yo,document:n=t?.document}=e;t!==void 0&&(this.#e=n,this.#t=yt(e=>{let n=Jr(t,`focusin`,e),r=Jr(t,`focusout`,e);return()=>{n(),r()}}))}get current(){return this.#t?.(),this.#e?Xo(this.#e):null}};var Qo=class{#e;#t;constructor(e){this.#e=e,this.#t=Symbol(e)}get key(){return this.#t}exists(){return tt(this.#t)}get(){let e=$e(this.#t);if(e===void 0)throw Error(`Context \"${this.#e}\" not found`);return e}getOr(e){let t=$e(this.#t);return t===void 0?e:t}set(e){return et(this.#t,e)}};function $o(e,t){switch(e){case`post`:Rn(t);break;case`pre`:Bn(t);break}}function es(e,t,n,r={}){let{lazy:i=!1}=r,a=!i,o=Array.isArray(e)?[]:void 0;$o(t,()=>{let t=Array.isArray(e)?e.map(e=>e()):e();if(!a){a=!0,o=t;return}let r=Mr(()=>n(t,o));return o=t,r})}function ts(e,t,n){let r=Vn(()=>{let i=!1;es(e,t,(e,t)=>{if(i){r();return}let a=n(e,t);return i=!0,a},{lazy:!0})});Rn(()=>r)}function ns(e,t,n){es(e,`post`,t,n)}function rs(e,t,n){es(e,`pre`,t,n)}ns.pre=rs;function is(e,t){ts(e,`post`,t)}function as(e,t){ts(e,`pre`,t)}is.pre=as;function os(e,t){let n,r=null;return(...i)=>new Promise(a=>{r&&r(void 0),r=a,clearTimeout(n),n=setTimeout(async()=>{let t=await e(...i);r&&=(r(t),null)},t)})}function ss(e,t){let n=0,r=null;return(...i)=>{let a=Date.now();return n&&a-n<t?r??Promise.resolve(void 0):(n=a,r=e(...i),r)}}function cs(e,t,n={},r){let{lazy:i=!1,once:a=!1,initialValue:o,debounce:s,throttle:c}=n,l=N(pn(o)),u=N(!1),d=N(void 0),f=N(pn([])),p=()=>{H(f).forEach(e=>e()),P(f,[],!0)},m=e=>{P(f,[...H(f),e],!0)},h=async(e,n,r=!1)=>{try{P(u,!0),P(d,void 0),p();let i=new AbortController;m(()=>i.abort());let a=await t(e,n,{data:H(l),refetching:r,onCleanup:m,signal:i.signal});return P(l,a,!0),a}catch(e){e instanceof DOMException&&e.name===`AbortError`||P(d,e,!0);return}finally{P(u,!1)}},g=s?os(h,s):c?ss(h,c):h,_=Array.isArray(e)?e:[e],v;return r((t,n)=>{a&&v||(v=t,g(Array.isArray(e)?t:t[0],Array.isArray(e)?n:n?.[0]))},{lazy:i}),{get current(){return H(l)},get loading(){return H(u)},get error(){return H(d)},mutate:e=>{P(l,e,!0)},refetch:t=>{let n=_.map(e=>e());return g(Array.isArray(e)?n:n[0],Array.isArray(e)?n:n[0],t??!0)}}}function ls(e,t,n){return cs(e,t,n,(t,n)=>{let r=Array.isArray(e)?e:[e];ns(()=>r.map(e=>e()),(e,n)=>{t(e,n??[])},n)})}function us(e,t,n){return cs(e,t,n,(t,n)=>{let r=Array.isArray(e)?e:[e];ns.pre(()=>r.map(e=>e()),(e,n)=>{t(e,n??[])},n)})}ls.pre=us;function ds(e){Rn(()=>()=>{e()})}function fs(e,t){return setTimeout(t,e)}function ps(e){kr().then(e)}var ms=1,hs=9,gs=11;function _s(e){return oo(e)&&e.nodeType===ms&&typeof e.nodeName==`string`}function vs(e){return oo(e)&&e.nodeType===hs}function ys(e){return oo(e)&&e.constructor?.name===`VisualViewport`}function bs(e){return oo(e)&&e.nodeType!==void 0}function xs(e){return bs(e)&&e.nodeType===gs&&`host`in e}function Ss(e,t){if(!e||!t||!_s(e)||!_s(t))return!1;let n=t.getRootNode?.();if(e===t||e.contains(t))return!0;if(n&&xs(n)){let n=t;for(;n;){if(e===n)return!0;n=n.parentNode||n.host}}return!1}function Cs(e){return vs(e)?e:ys(e)?e.document:e?.ownerDocument??document}function ws(e){let t=e.activeElement;for(;t?.shadowRoot;){let e=t.shadowRoot.activeElement;if(e===t)break;t=e}return t}var Ts=class{element;#e=j(()=>this.element.current?this.element.current.getRootNode()??document:document);get root(){return H(this.#e)}set root(e){P(this.#e,e)}constructor(e){typeof e==`function`?this.element=Q(e):this.element=e}getDocument=()=>Cs(this.root);getWindow=()=>this.getDocument().defaultView??window;getActiveElement=()=>ws(this.root);isActiveElement=e=>e===this.getActiveElement();getElementById(e){return this.root.getElementById(e)}querySelector=e=>this.root?this.root.querySelector(e):null;querySelectorAll=e=>this.root?this.root.querySelectorAll(e):[];setTimeout=(e,t)=>this.getWindow().setTimeout(e,t);clearTimeout=e=>this.getWindow().clearTimeout(e)};function Es(e,t){return{[Nr()]:n=>fo(e)?(e.current=n,Mr(()=>t?.(n)),()=>{`isConnected`in n&&n.isConnected||(e.current=null,t?.(null))}):(e(n),Mr(()=>t?.(n)),()=>{`isConnected`in n&&n.isConnected||(e(null),t?.(null))})}}function Ds(e){return e?``:void 0}function Os(e){return e?`open`:`closed`}function ks(e){return e===`starting`?{\"data-starting-style\":``}:e===`ending`?{\"data-ending-style\":``}:{}}var As=class{#e;#t;attrs;constructor(e){this.#e=e.getVariant?e.getVariant():null,this.#t=this.#e?`data-${this.#e}-`:`data-${e.component}-`,this.getAttr=this.getAttr.bind(this),this.selector=this.selector.bind(this),this.attrs=Object.fromEntries(e.parts.map(e=>[e,this.getAttr(e)]))}getAttr(e,t){return t?`data-${t}-${e}`:`${this.#t}${e}`}selector(e,t){return`[${this.getAttr(e,t)}]`}};function js(e){let t=new As(e);return{...t.attrs,selector:t.selector,getAttr:t.getAttr}}var Ms=typeof document<`u`,Ns=Ps();function Ps(){return Ms&&window?.navigator?.userAgent&&(/iP(ad|hone|od)/.test(window.navigator.userAgent)||window?.navigator?.maxTouchPoints>2&&/iPad|Macintosh/.test(window?.navigator.userAgent))}function Fs(e){return e instanceof HTMLElement}function Is(e){return e instanceof Element||e instanceof SVGElement}var Ls=class{#e;#t=null;#n=null;#r=0;constructor(e){this.#e=e,ds(()=>this.#i())}#i(){this.#t!==null&&(window.cancelAnimationFrame(this.#t),this.#t=null),this.#n?.disconnect(),this.#n=null,this.#r++}run(e){this.#i();let t=this.#e.ref.current;if(!t)return;if(typeof t.getAnimations!=`function`){this.#a(e);return}let n=this.#r,r=()=>{n===this.#r&&this.#a(e)},i=()=>{if(n!==this.#r)return;let e=t.getAnimations();if(e.length===0){r();return}Promise.all(e.map(e=>e.finished)).then(()=>{r()}).catch(()=>{if(n===this.#r){if(t.getAnimations().some(e=>e.pending||e.playState!==`finished`)){i();return}r()}})},a=()=>{this.#t=window.requestAnimationFrame(()=>{this.#t=null,i()})};if(!this.#e.afterTick.current){a();return}this.#t=window.requestAnimationFrame(()=>{this.#t=null;let e=`data-starting-style`;if(!t.hasAttribute(e)){a();return}this.#n=new MutationObserver(()=>{n===this.#r&&(t.hasAttribute(e)||(this.#n?.disconnect(),this.#n=null,a()))}),this.#n.observe(t,{attributes:!0,attributeFilter:[e]})})}#a(e){let t=()=>{e()};this.#e.afterTick?ps(t):t()}},Rs=class{#e;#t;#n;#r=N(!1);#i=N(void 0);#a=!1;#o=null;constructor(e){this.#e=e,P(this.#r,e.open.current,!0),this.#t=e.enabled??!0,this.#n=new Ls({ref:this.#e.ref,afterTick:this.#e.open}),ds(()=>this.#s()),ns(()=>this.#e.open.current,e=>{if(!this.#a){this.#a=!0;return}if(this.#s(),!e&&this.#e.shouldSkipExitAnimation?.()){P(this.#r,!1),P(this.#i,void 0),this.#e.onComplete?.();return}if(e&&P(this.#r,!0),P(this.#i,e?`starting`:`ending`,!0),e&&(this.#o=window.requestAnimationFrame(()=>{this.#o=null,this.#e.open.current&&P(this.#i,void 0)})),!this.#t){e||P(this.#r,!1),P(this.#i,void 0),this.#e.onComplete?.();return}this.#n.run(()=>{e===this.#e.open.current&&(this.#e.open.current||P(this.#r,!1),P(this.#i,void 0),this.#e.onComplete?.())})})}get shouldRender(){return H(this.#r)}get transitionStatus(){return H(this.#i)}#s(){this.#o!==null&&(window.cancelAnimationFrame(this.#o),this.#o=null)}};function $(){}function zs(e,t){return t===void 0?`bits-${e}`:`bits-${e}-${t}`}var Bs=js({component:`dialog`,parts:[`content`,`trigger`,`overlay`,`title`,`description`,`close`,`cancel`,`action`]}),Vs=new Qo(`Dialog.Root | AlertDialog.Root`),Hs=class e{static create(t){let n=Vs.getOr(null);return Vs.set(new e(t,n))}opts;#e=N(null);get triggerNode(){return H(this.#e)}set triggerNode(e){P(this.#e,e,!0)}#t=N(null);get contentNode(){return H(this.#t)}set contentNode(e){P(this.#t,e,!0)}#n=N(null);get overlayNode(){return H(this.#n)}set overlayNode(e){P(this.#n,e,!0)}#r=N(null);get descriptionNode(){return H(this.#r)}set descriptionNode(e){P(this.#r,e,!0)}#i=N(void 0);get contentId(){return H(this.#i)}set contentId(e){P(this.#i,e,!0)}#a=N(void 0);get titleId(){return H(this.#a)}set titleId(e){P(this.#a,e,!0)}#o=N(void 0);get triggerId(){return H(this.#o)}set triggerId(e){P(this.#o,e,!0)}#s=N(void 0);get descriptionId(){return H(this.#s)}set descriptionId(e){P(this.#s,e,!0)}#c=N(null);get cancelNode(){return H(this.#c)}set cancelNode(e){P(this.#c,e,!0)}#l=N(0);get nestedOpenCount(){return H(this.#l)}set nestedOpenCount(e){P(this.#l,e,!0)}depth;parent;contentPresence;overlayPresence;constructor(e,t){this.opts=e,this.parent=t,this.depth=t?t.depth+1:0,this.handleOpen=this.handleOpen.bind(this),this.handleClose=this.handleClose.bind(this),this.contentPresence=new Rs({ref:Q(()=>this.contentNode),open:this.opts.open,enabled:!0,onComplete:()=>{this.opts.onOpenChangeComplete.current(this.opts.open.current)}}),this.overlayPresence=new Rs({ref:Q(()=>this.overlayNode),open:this.opts.open,enabled:!0}),ns(()=>this.opts.open.current,e=>{this.parent&&(e?this.parent.incrementNested():this.parent.decrementNested())},{lazy:!0}),ds(()=>{this.opts.open.current&&this.parent?.decrementNested()})}handleOpen(){this.opts.open.current||(this.opts.open.current=!0)}handleClose(){this.opts.open.current&&(this.opts.open.current=!1)}getBitsAttr=e=>Bs.getAttr(e,this.opts.variant.current);incrementNested(){this.nestedOpenCount++,this.parent?.incrementNested()}decrementNested(){this.nestedOpenCount!==0&&(this.nestedOpenCount--,this.parent?.decrementNested())}#u=j(()=>({\"data-state\":Os(this.opts.open.current)}));get sharedProps(){return H(this.#u)}set sharedProps(e){P(this.#u,e)}},Us=class e{static create(t){return new e(t,Vs.get())}opts;root;attachment;constructor(e,t){this.opts=e,this.root=t,this.attachment=Es(this.opts.ref),this.onclick=this.onclick.bind(this),this.onkeydown=this.onkeydown.bind(this)}onclick(e){this.opts.disabled.current||e.button>0||this.root.handleClose()}onkeydown(e){this.opts.disabled.current||(e.key===` `||e.key===`Enter`)&&(e.preventDefault(),this.root.handleClose())}#e=j(()=>({id:this.opts.id.current,[this.root.getBitsAttr(this.opts.variant.current)]:``,onclick:this.onclick,onkeydown:this.onkeydown,disabled:this.opts.disabled.current?!0:void 0,tabindex:0,...this.root.sharedProps,...this.attachment}));get props(){return H(this.#e)}set props(e){P(this.#e,e)}},Ws=class e{static create(t){return new e(t,Vs.get())}opts;root;attachment;constructor(e,t){this.opts=e,this.root=t,this.root.titleId=this.opts.id.current,this.attachment=Es(this.opts.ref),ns.pre(()=>this.opts.id.current,e=>{this.root.titleId=e})}#e=j(()=>({id:this.opts.id.current,role:`heading`,\"aria-level\":this.opts.level.current,[this.root.getBitsAttr(`title`)]:``,...this.root.sharedProps,...this.attachment}));get props(){return H(this.#e)}set props(e){P(this.#e,e)}},Gs=class e{static create(t){return new e(t,Vs.get())}opts;root;attachment;constructor(e,t){this.opts=e,this.root=t,this.root.descriptionId=this.opts.id.current,this.attachment=Es(this.opts.ref,e=>{this.root.descriptionNode=e}),ns.pre(()=>this.opts.id.current,e=>{this.root.descriptionId=e})}#e=j(()=>({id:this.opts.id.current,[this.root.getBitsAttr(`description`)]:``,...this.root.sharedProps,...this.attachment}));get props(){return H(this.#e)}set props(e){P(this.#e,e)}},Ks=class e{static create(t){return new e(t,Vs.get())}opts;root;attachment;constructor(e,t){this.opts=e,this.root=t,this.attachment=Es(this.opts.ref,e=>{this.root.contentNode=e,this.root.contentId=e?.id})}#e=j(()=>({open:this.root.opts.open.current}));get snippetProps(){return H(this.#e)}set snippetProps(e){P(this.#e,e)}#t=j(()=>({id:this.opts.id.current,role:this.root.opts.variant.current===`alert-dialog`?`alertdialog`:`dialog`,\"aria-modal\":`true`,\"aria-describedby\":this.root.descriptionId,\"aria-labelledby\":this.root.titleId,[this.root.getBitsAttr(`content`)]:``,style:{pointerEvents:`auto`,outline:this.root.opts.variant.current===`alert-dialog`?`none`:void 0,\"--bits-dialog-depth\":this.root.depth,\"--bits-dialog-nested-count\":this.root.nestedOpenCount,contain:`layout style`},tabindex:this.root.opts.variant.current===`alert-dialog`?-1:void 0,\"data-nested-open\":Ds(this.root.nestedOpenCount>0),\"data-nested\":Ds(this.root.parent!==null),...ks(this.root.contentPresence.transitionStatus),...this.root.sharedProps,...this.attachment}));get props(){return H(this.#t)}set props(e){P(this.#t,e)}get shouldRender(){return this.root.contentPresence.shouldRender}},qs=class e{static create(t){return new e(t,Vs.get())}opts;root;attachment;constructor(e,t){this.opts=e,this.root=t,this.attachment=Es(this.opts.ref,e=>this.root.overlayNode=e)}#e=j(()=>({open:this.root.opts.open.current}));get snippetProps(){return H(this.#e)}set snippetProps(e){P(this.#e,e)}#t=j(()=>({id:this.opts.id.current,[this.root.getBitsAttr(`overlay`)]:``,style:{pointerEvents:`auto`,\"--bits-dialog-depth\":this.root.depth,\"--bits-dialog-nested-count\":this.root.nestedOpenCount},\"data-nested-open\":Ds(this.root.nestedOpenCount>0),\"data-nested\":Ds(this.root.parent!==null),...ks(this.root.overlayPresence.transitionStatus),...this.root.sharedProps,...this.attachment}));get props(){return H(this.#t)}set props(e){P(this.#t,e)}get shouldRender(){return this.root.overlayPresence.shouldRender}},Js=new Set([`$$slots`,`$$events`,`$$legacy`,`id`,`ref`,`child`,`children`,`level`]),Ys=U(`<div><!></div>`);function Xs(e,t){let n=oi();O(t,!0);let r=Y(t,`id`,19,()=>zs(n)),i=Y(t,`ref`,15,null),a=Y(t,`level`,3,2),o=ca(t,Js),s=Ws.create({id:Q(()=>r()),level:Q(()=>a()),ref:Q(()=>i(),e=>i(e))}),c=j(()=>Jo(o,s.props));var l=W(),u=I(l),d=e=>{var n=W();J(I(n),()=>t.child,()=>({props:H(c)})),G(e,n)},p=e=>{var n=Ys();ea(n,()=>({...H(c)})),J(F(n),()=>t.children??f),E(n),G(e,n)};q(u,e=>{t.child?e(d):e(p,-1)}),G(e,l),k()}function Zs(e,t){var n=W();mi(I(n),()=>t.children,e=>{var n=W();J(I(n),()=>t.children??f),G(e,n)}),G(e,n)}var Qs=new Qo(`BitsConfig`);function $s(){let e=new ec(null,{});return Qs.getOr(e).opts}var ec=class{opts;constructor(e,t){let n=tc(e,t);this.opts={defaultPortalTo:n(e=>e.defaultPortalTo),defaultLocale:n(e=>e.defaultLocale)}}};function tc(e,t){return n=>Q(()=>{let r=n(t)?.current;if(r!==void 0)return r;if(e!==null)return n(e.opts)?.current})}function nc(e,t){return n=>{let r=$s();return Q(()=>{let i=n();if(i!==void 0)return i;let a=e(r).current;return a===void 0?t:a})}}var rc=nc(e=>e.defaultPortalTo,`body`);function ic(e,t){O(t,!0);let n=rc(()=>t.to),r=nt(),i=j(a);function a(){if(!Ms||t.disabled)return null;let e=null;return e=typeof n.current==`string`?document.querySelector(n.current):n.current,e}let o;function s(){o&&=(di(o),null)}ns([()=>H(i),()=>t.disabled],([e,n])=>{if(!e||n){s();return}return o=si(Zs,{target:e,props:{children:t.children},context:r}),()=>{s()}});var c=W(),l=I(c),u=e=>{var n=W();J(I(n),()=>t.children??f),G(e,n)};q(l,e=>{t.disabled&&e(u)}),G(e,c),k()}var ac=class{eventName;options;constructor(e,t={bubbles:!0,cancelable:!0}){this.eventName=e,this.options=t}createEvent(e){return new CustomEvent(this.eventName,{...this.options,detail:e})}dispatch(e,t){let n=this.createEvent(t);return e.dispatchEvent(n),n}listen(e,t,n){return Jr(e,this.eventName,e=>{t(e)},n)}};function oc(e,t=500){let n=null,r=(...r)=>{n!==null&&clearTimeout(n),n=setTimeout(()=>{e(...r)},t)};return r.destroy=()=>{n!==null&&(clearTimeout(n),n=null)},r}function sc(e,t){return e===t||e.contains(t)}function cc(e){return e?.ownerDocument??document}function lc(e,t){let{clientX:n,clientY:r}=e,i=t.getBoundingClientRect();return n<i.left||n>i.right||r<i.top||r>i.bottom}var uc=[`input:not([inert]):not([inert] *)`,`select:not([inert]):not([inert] *)`,`textarea:not([inert]):not([inert] *)`,`a[href]:not([inert]):not([inert] *)`,`button:not([inert]):not([inert] *)`,`[tabindex]:not(slot):not([inert]):not([inert] *)`,`audio[controls]:not([inert]):not([inert] *)`,`video[controls]:not([inert]):not([inert] *)`,`[contenteditable]:not([contenteditable=\"false\"]):not([inert]):not([inert] *)`,`details>summary:first-of-type:not([inert]):not([inert] *)`,`details:not([inert]):not([inert] *)`],dc=uc.join(`,`),fc=typeof Element>`u`,pc=fc?function(){}:Element.prototype.matches||Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector,mc=!fc&&Element.prototype.getRootNode?function(e){return e?.getRootNode?.call(e)}:function(e){return e?.ownerDocument},hc=function(e,t){t===void 0&&(t=!0);var n=e?.getAttribute?.call(e,`inert`);return n===``||n===`true`||t&&e&&(typeof e.closest==`function`?e.closest(`[inert]`):hc(e.parentNode))},gc=function(e){var t=e?.getAttribute?.call(e,`contenteditable`);return t===``||t===`true`},_c=function(e,t,n){if(hc(e))return[];var r=Array.prototype.slice.apply(e.querySelectorAll(dc));return t&&pc.call(e,dc)&&r.unshift(e),r=r.filter(n),r},vc=function(e,t,n){for(var r=[],i=Array.from(e);i.length;){var a=i.shift();if(!hc(a,!1))if(a.tagName===`SLOT`){var o=a.assignedElements(),s=vc(o.length?o:a.children,!0,n);n.flatten?r.push.apply(r,s):r.push({scopeParent:a,candidates:s})}else{pc.call(a,dc)&&n.filter(a)&&(t||!e.includes(a))&&r.push(a);var c=a.shadowRoot||typeof n.getShadowRoot==`function`&&n.getShadowRoot(a),l=!hc(c,!1)&&(!n.shadowRootFilter||n.shadowRootFilter(a));if(c&&l){var u=vc(c===!0?a.children:c.children,!0,n);n.flatten?r.push.apply(r,u):r.push({scopeParent:a,candidates:u})}else i.unshift.apply(i,a.children)}}return r},yc=function(e){return!isNaN(parseInt(e.getAttribute(`tabindex`),10))},bc=function(e){if(!e)throw Error(`No node provided`);return e.tabIndex<0&&(/^(AUDIO|VIDEO|DETAILS)$/.test(e.tagName)||gc(e))&&!yc(e)?0:e.tabIndex},xc=function(e,t){var n=bc(e);return n<0&&t&&!yc(e)?0:n},Sc=function(e,t){return e.tabIndex===t.tabIndex?e.documentOrder-t.documentOrder:e.tabIndex-t.tabIndex},Cc=function(e){return e.tagName===`INPUT`},wc=function(e){return Cc(e)&&e.type===`hidden`},Tc=function(e){return e.tagName===`DETAILS`&&Array.prototype.slice.apply(e.children).some(function(e){return e.tagName===`SUMMARY`})},Ec=function(e,t){for(var n=0;n<e.length;n++)if(e[n].checked&&e[n].form===t)return e[n]},Dc=function(e){if(!e.name)return!0;var t=e.form||mc(e),n=function(e){return t.querySelectorAll(`input[type=\"radio\"][name=\"`+e+`\"]`)},r;if(typeof window<`u`&&window.CSS!==void 0&&typeof window.CSS.escape==`function`)r=n(window.CSS.escape(e.name));else try{r=n(e.name)}catch(e){return console.error(`Looks like you have a radio button with a name attribute containing invalid CSS selector characters and need the CSS.escape polyfill: %s`,e.message),!1}var i=Ec(r,e.form);return!i||i===e},Oc=function(e){return Cc(e)&&e.type===`radio`},kc=function(e){return Oc(e)&&!Dc(e)},Ac=function(e){var t=e&&mc(e),n=t?.host,r=!1;if(t&&t!==e){var i,a,o;for(r=!!((i=n)!=null&&(a=i.ownerDocument)!=null&&a.contains(n)||e!=null&&(o=e.ownerDocument)!=null&&o.contains(e));!r&&n;){var s,c;t=mc(n),n=t?.host,r=!!((s=n)!=null&&(c=s.ownerDocument)!=null&&c.contains(n))}}return r},jc=function(e){var t=e.getBoundingClientRect(),n=t.width,r=t.height;return n===0&&r===0},Mc=function(e,t){var n=t.displayCheck,r=t.getShadowRoot;if(n===`full-native`&&`checkVisibility`in e)return!e.checkVisibility({checkOpacity:!1,opacityProperty:!1,contentVisibilityAuto:!0,visibilityProperty:!0,checkVisibilityCSS:!0});if(getComputedStyle(e).visibility===`hidden`)return!0;var i=pc.call(e,`details>summary:first-of-type`)?e.parentElement:e;if(pc.call(i,`details:not([open]) *`))return!0;if(!n||n===`full`||n===`full-native`||n===`legacy-full`){if(typeof r==`function`){for(var a=e;e;){var o=e.parentElement,s=mc(e);if(o&&!o.shadowRoot&&r(o)===!0)return jc(e);e=e.assignedSlot?e.assignedSlot:!o&&s!==e.ownerDocument?s.host:o}e=a}if(Ac(e))return!e.getClientRects().length;if(n!==`legacy-full`)return!0}else if(n===`non-zero-area`)return jc(e);return!1},Nc=function(e){if(/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(e.tagName))for(var t=e.parentElement;t;){if(t.tagName===`FIELDSET`&&t.disabled){for(var n=0;n<t.children.length;n++){var r=t.children.item(n);if(r.tagName===`LEGEND`)return pc.call(t,`fieldset[disabled] *`)?!0:!r.contains(e)}return!0}t=t.parentElement}return!1},Pc=function(e,t){return!(t.disabled||wc(t)||Mc(t,e)||Tc(t)||Nc(t))},Fc=function(e,t){return!(kc(t)||bc(t)<0||!Pc(e,t))},Ic=function(e){var t=parseInt(e.getAttribute(`tabindex`),10);return!!(isNaN(t)||t>=0)},Lc=function(e){var t=[],n=[];return e.forEach(function(e,r){var i=!!e.scopeParent,a=i?e.scopeParent:e,o=xc(a,i),s=i?Lc(e.candidates):a;o===0?i?t.push.apply(t,s):t.push(a):n.push({documentOrder:r,tabIndex:o,item:e,isScope:i,content:s})}),n.sort(Sc).reduce(function(e,t){return t.isScope?e.push.apply(e,t.content):e.push(t.content),e},[]).concat(t)},Rc=function(e,t){return t||={},Lc(t.getShadowRoot?vc([e],t.includeContainer,{filter:Fc.bind(null,t),flatten:!1,getShadowRoot:t.getShadowRoot,shadowRootFilter:Ic}):_c(e,t.includeContainer,Fc.bind(null,t)))},zc=function(e,t){return t||={},t.getShadowRoot?vc([e],t.includeContainer,{filter:Pc.bind(null,t),flatten:!0,getShadowRoot:t.getShadowRoot}):_c(e,t.includeContainer,Pc.bind(null,t))},Bc=uc.concat(`iframe:not([inert]):not([inert] *)`).join(`,`),Vc=function(e,t){if(t||={},!e)throw Error(`No node provided`);return pc.call(e,Bc)===!1?!1:Pc(t,e)},Hc=`data-context-menu-trigger`,Uc=`data-context-menu-content`;new Qo(`Menu.Root`),new Qo(`Menu.Root | Menu.Sub`),new Qo(`Menu.Content`),new Qo(`Menu.Group | Menu.RadioGroup`),new Qo(`Menu.RadioGroup`),new Qo(`Menu.CheckboxGroup`),new ac(`bitsmenuopen`,{bubbles:!1,cancelable:!0}),js({component:`menu`,parts:[`trigger`,`content`,`sub-trigger`,`item`,`group`,`group-heading`,`checkbox-group`,`checkbox-item`,`radio-group`,`radio-item`,`separator`,`sub-content`,`arrow`]}),globalThis.bitsDismissableLayers??=new Map;var Wc=class e{static create(t){return new e(t)}opts;#e;#t;#n={pointerdown:!1};#r=!1;#i=!1;#a=void 0;#o;#s=$;constructor(e){this.opts=e,this.#t=e.interactOutsideBehavior,this.#e=e.onInteractOutside,this.#o=e.onFocusOutside,Rn(()=>{this.#a=cc(this.opts.ref.current)});let t=$,n=()=>{this.#g(),globalThis.bitsDismissableLayers.delete(this),this.#d.destroy(),t()};ns([()=>this.opts.enabled.current,()=>this.opts.ref.current],()=>{if(!(!this.opts.enabled.current||!this.opts.ref.current))return fs(1,()=>{this.opts.ref.current&&(globalThis.bitsDismissableLayers.set(this,this.#t),t(),t=this.#l())}),n}),ds(()=>{this.#g.destroy(),globalThis.bitsDismissableLayers.delete(this),this.#d.destroy(),this.#s(),t()})}#c=e=>{e.defaultPrevented||this.opts.ref.current&&ps(()=>{!this.opts.ref.current||this.#h(e.target)||e.target&&!this.#i&&this.#o.current?.(e)})};#l(){return Vo(Jr(this.#a,`pointerdown`,Vo(this.#f,this.#m),{capture:!0}),Jr(this.#a,`pointerdown`,Vo(this.#p,this.#d)),Jr(this.#a,`focusin`,this.#c))}#u=e=>{let t=e;t.defaultPrevented&&(t=Jc(e)),this.#e.current(e)};#d=oc(e=>{if(!this.opts.ref.current){this.#s();return}let t=this.opts.isValidEvent.current(e,this.opts.ref.current)||qc(e,this.opts.ref.current);if(!this.#r||this.#_()||!t){this.#s();return}let n=e;if(n.defaultPrevented&&(n=Jc(n)),this.#t.current!==`close`&&this.#t.current!==`defer-otherwise-close`){this.#s();return}e.pointerType===`touch`?(this.#s(),this.#s=Jr(this.#a,`click`,this.#u,{once:!0})):this.#e.current(n)},10);#f=e=>{this.#n[e.type]=!0};#p=e=>{this.#n[e.type]=!1};#m=()=>{this.opts.ref.current&&(this.#r=Kc(this.opts.ref.current))};#h=e=>this.opts.ref.current?sc(this.opts.ref.current,e):!1;#g=oc(()=>{for(let e in this.#n)this.#n[e]=!1;this.#r=!1},20);#_(){return Object.values(this.#n).some(Boolean)}#v=()=>{this.#i=!0};#y=()=>{this.#i=!1};props={onfocuscapture:this.#v,onblurcapture:this.#y}};function Gc(e=[...globalThis.bitsDismissableLayers]){return e.findLast(([e,{current:t}])=>t===`close`||t===`ignore`)}function Kc(e){let t=[...globalThis.bitsDismissableLayers],n=Gc(t);if(n)return n[0].opts.ref.current===e;let[r]=t[0];return r.opts.ref.current===e}function qc(e,t){let n=e.target;if(!Is(n))return!1;let r=!!n.closest(`[${Hc}]`),i=!!t.closest(`[${Uc}]`);return`button`in e&&e.button>0&&!r?!1:`button`in e&&e.button===0&&r&&i?!0:r&&i?!1:cc(n).documentElement.contains(n)&&!sc(t,n)&&lc(e,t)}function Jc(e){let t=e.currentTarget,n=e.target,r;r=e instanceof PointerEvent?new PointerEvent(e.type,e):new PointerEvent(`pointerdown`,e);let i=!1;return new Proxy(r,{get:(r,a)=>a===`currentTarget`?t:a===`target`?n:a===`preventDefault`?()=>{i=!0,typeof r.preventDefault==`function`&&r.preventDefault()}:a===`defaultPrevented`?i:a in r?r[a]:e[a]})}function Yc(e,t){O(t,!0);let n=Y(t,`interactOutsideBehavior`,3,`close`),r=Y(t,`onInteractOutside`,3,$),i=Y(t,`onFocusOutside`,3,$),a=Y(t,`isValidEvent`,3,()=>!1),o=Wc.create({id:Q(()=>t.id),interactOutsideBehavior:Q(()=>n()),onInteractOutside:Q(()=>r()),enabled:Q(()=>t.enabled),onFocusOutside:Q(()=>i()),isValidEvent:Q(()=>a()),ref:t.ref});var s=W();J(I(s),()=>t.children??f,()=>({props:o.props})),G(e,s),k()}globalThis.bitsEscapeLayers??=new Map;var Xc=class e{static create(t){return new e(t)}opts;domContext;constructor(e){this.opts=e,this.domContext=new Ts(this.opts.ref);let t=$;ns(()=>e.enabled.current,n=>(n&&(globalThis.bitsEscapeLayers.set(this,e.escapeKeydownBehavior),t=this.#e()),()=>{t(),globalThis.bitsEscapeLayers.delete(this)}))}#e=()=>Jr(this.domContext.getDocument(),`keydown`,this.#t,{passive:!1});#t=e=>{if(e.key!==`Escape`||!Zc(this))return;let t=new KeyboardEvent(e.type,e);e.preventDefault();let n=this.opts.escapeKeydownBehavior.current;n!==`close`&&n!==`defer-otherwise-close`||this.opts.onEscapeKeydown.current(t)}};function Zc(e){let t=[...globalThis.bitsEscapeLayers],n=t.findLast(([e,{current:t}])=>t===`close`||t===`ignore`);if(n)return n[0]===e;let[r]=t[0];return r===e}function Qc(e,t){O(t,!0);let n=Y(t,`escapeKeydownBehavior`,3,`close`),r=Y(t,`onEscapeKeydown`,3,$);Xc.create({escapeKeydownBehavior:Q(()=>n()),onEscapeKeydown:Q(()=>r()),enabled:Q(()=>t.enabled),ref:t.ref});var i=W();J(I(i),()=>t.children??f),G(e,i),k()}var $c=class e{static instance;#e=po([]);#t=new WeakMap;#n=new WeakMap;static getInstance(){return this.instance||=new e,this.instance}register(e){let t=this.getActive();t&&t!==e&&t.pause();let n=document.activeElement;n&&n!==document.body&&this.#n.set(e,n),this.#e.current=this.#e.current.filter(t=>t!==e),this.#e.current.unshift(e)}unregister(e){this.#e.current=this.#e.current.filter(t=>t!==e);let t=this.getActive();t&&t.resume()}getActive(){return this.#e.current[0]}setFocusMemory(e,t){this.#t.set(e,t)}getFocusMemory(e){return this.#t.get(e)}isActiveScope(e){return this.getActive()===e}setPreFocusMemory(e,t){this.#n.set(e,t)}getPreFocusMemory(e){return this.#n.get(e)}clearPreFocusMemory(e){this.#n.delete(e)}},el=class e{#e=!1;#t=null;#n=$c.getInstance();#r=[];#i;constructor(e){this.#i=e}get paused(){return this.#e}pause(){this.#e=!0}resume(){this.#e=!1}#a(){for(let e of this.#r)e();this.#r=[]}mount(e){this.#t&&this.unmount(),this.#t=e,this.#n.register(this),this.#c(),this.#o()}unmount(){this.#t&&=(this.#a(),this.#s(),this.#n.unregister(this),this.#n.clearPreFocusMemory(this),null)}#o(){if(!this.#t)return;let e=new CustomEvent(`focusScope.onOpenAutoFocus`,{bubbles:!1,cancelable:!0});this.#i.onOpenAutoFocus.current(e),e.defaultPrevented||requestAnimationFrame(()=>{if(!this.#t)return;let e=this.#u();e?(e.focus(),this.#n.setFocusMemory(this,e)):this.#t.focus()})}#s(){let e=new CustomEvent(`focusScope.onCloseAutoFocus`,{bubbles:!1,cancelable:!0});if(this.#i.onCloseAutoFocus.current?.(e),!e.defaultPrevented){let e=this.#n.getPreFocusMemory(this);if(e&&document.contains(e))try{e.focus()}catch{document.body.focus()}}}#c(){if(!this.#t||!this.#i.trap.current)return;let e=this.#t,t=e.ownerDocument;this.#r.push(Jr(t,`focusin`,t=>{if(this.#e||!this.#n.isActiveScope(this))return;let n=t.target;if(n)if(e.contains(n))this.#n.setFocusMemory(this,n);else{let n=this.#n.getFocusMemory(this);if(n&&e.contains(n)&&Vc(n))t.preventDefault(),n.focus();else{let t=this.#u(),n=this.#d()[0];(t||n||e).focus()}}},{capture:!0}),Jr(e,`keydown`,e=>{if(!this.#i.loop||this.#e||e.key!==`Tab`||!this.#n.isActiveScope(this))return;let n=this.#l();if(n.length===0)return;let r=n[0],i=n[n.length-1];!e.shiftKey&&t.activeElement===i?(e.preventDefault(),r.focus()):e.shiftKey&&t.activeElement===r&&(e.preventDefault(),i.focus())}));let n=new MutationObserver(()=>{let t=this.#n.getFocusMemory(this);if(t&&!e.contains(t)){let t=this.#u(),n=this.#d()[0],r=t||n;r?(r.focus(),this.#n.setFocusMemory(this,r)):e.focus()}});n.observe(e,{childList:!0,subtree:!0}),this.#r.push(()=>n.disconnect())}#l(){return this.#t?Rc(this.#t,{includeContainer:!1,getShadowRoot:!0}):[]}#u(){return this.#l()[0]||null}#d(){return this.#t?zc(this.#t,{includeContainer:!1,getShadowRoot:!0}):[]}static use(t){let n=null;return ns([()=>t.ref.current,()=>t.enabled.current],([r,i])=>{r&&i?(n||=new e(t),n.mount(r)):n&&=(n.unmount(),null)}),ds(()=>{n?.unmount()}),{get props(){return{tabindex:-1}}}}};function tl(e,t){O(t,!0);let n=Y(t,`enabled`,3,!1),r=Y(t,`trapFocus`,3,!1),i=Y(t,`loop`,3,!1),a=Y(t,`onCloseAutoFocus`,3,$),o=Y(t,`onOpenAutoFocus`,3,$),s=el.use({enabled:Q(()=>n()),trap:Q(()=>r()),loop:i(),onCloseAutoFocus:Q(()=>a()),onOpenAutoFocus:Q(()=>o()),ref:t.ref});var c=W();J(I(c),()=>t.focusScope??f,()=>({props:s.props})),G(e,c),k()}var nl=()=>{};globalThis.bitsTextSelectionLayers??=new Map;var rl=class e{static create(t){return new e(t)}opts;domContext;#e=$;#t=!1;#n=nl;#r=nl;constructor(e){this.opts=e,this.domContext=new Ts(e.ref);let t=$;ns(()=>[this.opts.enabled.current,this.opts.onPointerDown.current,this.opts.onPointerUp.current],([e,n,r])=>(this.#t=e,this.#n=n,this.#r=r,e&&(globalThis.bitsTextSelectionLayers.set(this,this.opts.enabled),t(),t=this.#i()),()=>{this.#t=!1,t(),this.#s(),globalThis.bitsTextSelectionLayers.delete(this)}))}#i(){return Vo(Jr(this.domContext.getDocument(),`pointerdown`,this.#o),Jr(this.domContext.getDocument(),`pointerup`,mo(this.#s,this.#a)))}#a=e=>{this.#r(e)};#o=e=>{let t=this.opts.ref.current,n=e.target;!Fs(t)||!Fs(n)||!this.#t||!sl(this)||!Ss(t,n)||(this.#n(e),!e.defaultPrevented&&(this.#e=al(t,this.domContext.getDocument().body)))};#s=()=>{this.#e(),this.#e=$}},il=e=>e.style.userSelect||e.style.webkitUserSelect;function al(e,t){let n=il(t),r=il(e);return ol(t,`none`),ol(e,`text`),()=>{ol(t,n),ol(e,r)}}function ol(e,t){e.style.userSelect=t,e.style.webkitUserSelect=t}function sl(e){let t=[...globalThis.bitsTextSelectionLayers];if(!t.length)return!1;let n=t.at(-1);return n?n[0]===e:!1}function cl(e,t){O(t,!0);let n=Y(t,`preventOverflowTextSelection`,3,!0),r=Y(t,`onPointerDown`,3,$),i=Y(t,`onPointerUp`,3,$);rl.create({id:Q(()=>t.id),onPointerDown:Q(()=>r()),onPointerUp:Q(()=>i()),enabled:Q(()=>t.enabled&&n()),ref:t.ref});var a=W();J(I(a),()=>t.children??f),G(e,a),k()}globalThis.bitsIdCounter??={current:0};function ll(e=`bits`){return globalThis.bitsIdCounter.current++,`${e}-${globalThis.bitsIdCounter.current}`}var ul=class{#e;#t=0;#n=N();#r;constructor(e){this.#e=e}#i(){--this.#t,this.#r&&this.#t<=0&&(this.#r(),P(this.#n,void 0),this.#r=void 0)}get(...e){return this.#t+=1,H(this.#n)===void 0&&(this.#r=Vn(()=>{P(this.#n,this.#e(...e),!0)})),Rn(()=>()=>{this.#i()}),H(this.#n)}},dl=new Zo,fl=N(null),pl=null,ml=null,hl=!1,gl=Q(()=>{for(let e of dl.values())if(e)return!0;return!1}),_l=null,vl=new ul(()=>{function e(){document.body.setAttribute(`style`,H(fl)??``),document.body.style.removeProperty(`--scrollbar-width`),Ns&&pl?.(),P(fl,null)}function t(){ml!==null&&(window.clearTimeout(ml),ml=null)}function n(e,n){t(),hl=!0,_l=Date.now();let r=_l,i=()=>{ml=null,_l===r&&(bl(dl)?hl=!1:(hl=!1,n()))},a=e===null?24:e;ml=window.setTimeout(i,a)}function r(){H(fl)===null&&dl.size===0&&!hl&&P(fl,document.body.getAttribute(`style`),!0)}return ns(()=>gl.current,()=>{if(!gl.current)return;r(),hl=!1;let e=getComputedStyle(document.documentElement),t=getComputedStyle(document.body),n=e.scrollbarGutter?.includes(`stable`)||t.scrollbarGutter?.includes(`stable`),i=window.innerWidth-document.documentElement.clientWidth,a={padding:Number.parseInt(t.paddingRight??`0`,10)+i,margin:Number.parseInt(t.marginRight??`0`,10)};i>0&&!n&&(document.body.style.paddingRight=`${a.padding}px`,document.body.style.marginRight=`${a.margin}px`,document.body.style.setProperty(`--scrollbar-width`,`${i}px`)),document.body.style.overflow=`hidden`,Ns&&(pl=Jr(document,`touchmove`,e=>{e.target===document.documentElement&&(e.touches.length>1||e.preventDefault())},{passive:!1})),ps(()=>{document.body.style.pointerEvents=`none`,document.body.style.overflow=`hidden`})}),ds(()=>()=>{pl?.()}),{get lockMap(){return dl},resetBodyStyle:e,scheduleCleanupIfNoNewLocks:n,cancelPendingCleanup:t,ensureInitialStyleCaptured:r}}),yl=class{#e=ll();#t;#n=()=>null;#r;locked;constructor(e,t=()=>null){this.#t=e,this.#n=t,this.#r=vl.get(),this.#r&&(this.#r.cancelPendingCleanup(),this.#r.ensureInitialStyleCaptured(),this.#r.lockMap.set(this.#e,this.#t??!1),this.locked=Q(()=>this.#r.lockMap.get(this.#e)??!1,e=>this.#r.lockMap.set(this.#e,e)),ds(()=>{if(this.#r.lockMap.delete(this.#e),bl(this.#r.lockMap))return;let e=this.#n();this.#r.scheduleCleanupIfNoNewLocks(e,()=>{this.#r.resetBodyStyle()})}))}};function bl(e){for(let[t,n]of e)if(n)return!0;return!1}function xl(e,t){O(t,!0);let n=Y(t,`preventScroll`,3,!0),r=Y(t,`restoreScrollDelay`,3,null);n()&&new yl(n(),()=>r()),k()}var Sl=new Set([`$$slots`,`$$events`,`$$legacy`,`id`,`forceMount`,`child`,`children`,`ref`]),Cl=U(`<div><!></div>`);function wl(e,t){let n=oi();O(t,!0);let r=Y(t,`id`,19,()=>zs(n)),i=Y(t,`forceMount`,3,!1),a=Y(t,`ref`,15,null),o=ca(t,Sl),s=qs.create({id:Q(()=>r()),ref:Q(()=>a(),e=>a(e))}),c=j(()=>Jo(o,s.props));var l=W(),u=I(l),d=e=>{var n=W(),r=I(n),i=e=>{var n=W(),r=I(n);{let e=j(()=>({props:Jo(H(c)),...s.snippetProps}));J(r,()=>t.child,()=>H(e))}G(e,n)},a=e=>{var n=Cl();ea(n,e=>({...e}),[()=>Jo(H(c))]),J(F(n),()=>t.children??f,()=>s.snippetProps),E(n),G(e,n)};q(r,e=>{t.child?e(i):e(a,-1)}),G(e,n)};q(u,e=>{(s.shouldRender||i())&&e(d)}),G(e,l),k()}var Tl=new Set([`$$slots`,`$$events`,`$$legacy`,`id`,`children`,`child`,`ref`]),El=U(`<div><!></div>`);function Dl(e,t){let n=oi();O(t,!0);let r=Y(t,`id`,19,()=>zs(n)),i=Y(t,`ref`,15,null),a=ca(t,Tl),o=Gs.create({id:Q(()=>r()),ref:Q(()=>i(),e=>i(e))}),s=j(()=>Jo(a,o.props));var c=W(),l=I(c),u=e=>{var n=W();J(I(n),()=>t.child,()=>({props:H(s)})),G(e,n)},d=e=>{var n=El();ea(n,()=>({...H(s)})),J(F(n),()=>t.children??f),E(n),G(e,n)};q(l,e=>{t.child?e(u):e(d,-1)}),G(e,c),k()}function Ol(e,t){O(t,!0);let n=Y(t,`open`,15,!1),r=Y(t,`onOpenChange`,3,$),i=Y(t,`onOpenChangeComplete`,3,$);Hs.create({variant:Q(()=>`dialog`),open:Q(()=>n(),e=>{n(e),r()(e)}),onOpenChangeComplete:Q(()=>i())});var a=W();J(I(a),()=>t.children??f),G(e,a),k()}var kl=new Set([`$$slots`,`$$events`,`$$legacy`,`children`,`child`,`id`,`ref`,`disabled`]),Al=U(`<button><!></button>`);function jl(e,t){let n=oi();O(t,!0);let r=Y(t,`id`,19,()=>zs(n)),i=Y(t,`ref`,15,null),a=Y(t,`disabled`,3,!1),o=ca(t,kl),s=Us.create({variant:Q(()=>`close`),id:Q(()=>r()),ref:Q(()=>i(),e=>i(e)),disabled:Q(()=>!!a())}),c=j(()=>Jo(o,s.props));var l=W(),u=I(l),d=e=>{var n=W();J(I(n),()=>t.child,()=>({props:H(c)})),G(e,n)},p=e=>{var n=Al();ea(n,()=>({...H(c)})),J(F(n),()=>t.children??f),E(n),G(e,n)};q(u,e=>{t.child?e(d):e(p,-1)}),G(e,l),k()}var Ml=new Set([`$$slots`,`$$events`,`$$legacy`,`id`,`children`,`child`,`ref`,`forceMount`,`onCloseAutoFocus`,`onOpenAutoFocus`,`onEscapeKeydown`,`onInteractOutside`,`trapFocus`,`preventScroll`,`restoreScrollDelay`]),Nl=U(`<!> <!>`,1),Pl=U(`<!> <div><!></div>`,1);function Fl(e,t){let n=oi();O(t,!0);let r=Y(t,`id`,19,()=>zs(n)),i=Y(t,`ref`,15,null),a=Y(t,`forceMount`,3,!1),o=Y(t,`onCloseAutoFocus`,3,$),s=Y(t,`onOpenAutoFocus`,3,$),c=Y(t,`onEscapeKeydown`,3,$),l=Y(t,`onInteractOutside`,3,$),u=Y(t,`trapFocus`,3,!0),d=Y(t,`preventScroll`,3,!0),p=Y(t,`restoreScrollDelay`,3,null),m=ca(t,Ml),h=Ks.create({id:Q(()=>r()),ref:Q(()=>i(),e=>i(e))}),g=j(()=>Jo(m,h.props));var _=W(),v=I(_),y=e=>{tl(e,{get ref(){return h.opts.ref},loop:!0,get trapFocus(){return u()},get enabled(){return h.root.opts.open.current},get onOpenAutoFocus(){return s()},get onCloseAutoFocus(){return o()},focusScope:(e,n)=>{let r=()=>n?.().props;Qc(e,ua(()=>H(g),{get enabled(){return h.root.opts.open.current},get ref(){return h.opts.ref},onEscapeKeydown:e=>{c()(e),!e.defaultPrevented&&h.root.handleClose()},children:(e,n)=>{Yc(e,ua(()=>H(g),{get ref(){return h.opts.ref},get enabled(){return h.root.opts.open.current},onInteractOutside:e=>{l()(e),!e.defaultPrevented&&h.root.handleClose()},children:(e,n)=>{cl(e,ua(()=>H(g),{get ref(){return h.opts.ref},get enabled(){return h.root.opts.open.current},children:(e,n)=>{var i=W(),a=I(i),o=e=>{var n=Nl(),i=I(n),a=e=>{xl(e,{get preventScroll(){return d()},get restoreScrollDelay(){return p()}})};q(i,e=>{h.root.opts.open.current&&e(a)});var o=L(i,2);{let e=j(()=>({props:Jo(H(g),r()),...h.snippetProps}));J(o,()=>t.child,()=>H(e))}G(e,n)},s=e=>{var n=Pl(),i=I(n);xl(i,{get preventScroll(){return d()}});var a=L(i,2);ea(a,e=>({...e}),[()=>Jo(H(g),r())]),J(F(a),()=>t.children??f),E(a),G(e,n)};q(a,e=>{t.child?e(o):e(s,-1)}),G(e,i)},$$slots:{default:!0}}))},$$slots:{default:!0}}))},$$slots:{default:!0}}))},$$slots:{focusScope:!0}})};q(v,e=>{(h.shouldRender||a())&&e(y)}),G(e,_),k()}var Il=U(`<button class=\"flex flex-col gap-1 text-left\"><div class=\"flex items-center gap-2 font-mono text-[11px]\"><span class=\"size-2 shrink-0 rounded-sm\"></span> <span class=\"flex-1 truncate text-foreground\"> </span> <span class=\"tabular-nums text-muted-foreground\"> </span></div> <div class=\"h-1 overflow-hidden rounded-full bg-border\"><div class=\"h-full\"></div></div></button>`),Ll=U(`<div class=\"text-[11px] text-muted-foreground\">No projects tracked yet — run <code class=\"text-foreground\">syn .</code></div>`),Rl=U(`<div class=\"flex max-h-[260px] flex-col gap-2 overflow-y-auto pr-1\"></div>`),zl=U(`<div class=\"flex flex-col gap-0.5 bg-card p-3\"><span class=\"font-mono text-[9px] uppercase tracking-[0.1em] text-muted-foreground\"> </span> <span class=\"font-mono text-sm text-foreground\"> </span></div>`),Bl=U(`<!> <!> <div class=\"mt-4 grid grid-cols-2 gap-px overflow-hidden rounded-lg border bg-border\"></div> <!>`,1),Vl=U(`<!> <!>`,1);function Hl(e,t){O(t,!0);let n=N(!1),r=N(null),i=j(()=>X.data?.projects??[]),a=j(()=>Math.max(1,...H(i).map(e=>e.total_turns)));function o(e){let t=(X.data?.recent_turns??[]).find(t=>t.project_path===e.path);return t?ma(t.ts):e.last_seen?ma(e.last_seen):`—`}function s(e){return[[`Cost`,pa(e.estimated_cost_usd)],[`Turns`,Z(e.total_turns)],[`Input`,Z(e.total_input_tokens)],[`Output`,Z(e.total_output_tokens)],[`Cache R`,Z(e.total_cache_read)],[`Cache W`,Z(e.total_cache_create)],[`Blocks`,Z(e.blocked_count)],[`Last active`,o(e)]]}var c=Vl(),l=I(c);Xa(l,{title:`Projects`,meta:`by turns`,children:(e,t)=>{var o=Rl();yi(o,21,()=>H(i),e=>e.path,(e,t)=>{var i=Il(),o=F(i),s=F(o),c=L(s,2),l=F(c,!0);E(c);var u=L(c,2),d=F(u,!0);E(u),E(o);var f=L(o,2),p=F(f);E(f),E(i),R((e,n,r)=>{Ri(s,e),K(l,H(t).name),K(d,n),Ri(p,r)},[()=>`background:${ya(H(t).name)}`,()=>Z(H(t).total_turns),()=>`width:${H(t).total_turns/H(a)*100}%; background:${ya(H(t).name)}`]),Yr(`click`,i,()=>{P(r,H(t),!0),P(n,!0)}),G(e,i)},e=>{G(e,Ll())}),E(o),G(e,o)},$$slots:{default:!0}}),Ti(L(l,2),()=>Ol,(e,t)=>{t(e,{get open(){return H(n)},set open(e){P(n,e,!0)},children:(e,t)=>{var n=W();Ti(I(n),()=>ic,(e,t)=>{t(e,{children:(e,t)=>{var n=Vl(),i=I(n);Ti(i,()=>wl,(e,t)=>{t(e,{class:`fixed inset-0 z-50 bg-black/60`})}),Ti(L(i,2),()=>Fl,(e,t)=>{t(e,{class:`fixed left-1/2 top-1/2 z-50 w-[min(440px,92vw)] -translate-x-1/2 -translate-y-1/2 rounded-xl border bg-card p-5 text-card-foreground shadow-2xl`,children:(e,t)=>{var n=W(),i=I(n),a=e=>{var t=Bl(),n=I(t);{let e=j(()=>`color:${ya(H(r).name)}`);Ti(n,()=>Xs,(t,n)=>{n(t,{class:`font-serif text-xl`,get style(){return H(e)},children:(e,t)=>{Ue();var n=ai();R(()=>K(n,H(r).name)),G(e,n)},$$slots:{default:!0}})})}var i=L(n,2);Ti(i,()=>Dl,(e,t)=>{t(e,{class:`truncate font-mono text-[10px] text-muted-foreground`,children:(e,t)=>{Ue();var n=ai();R(()=>K(n,H(r).path)),G(e,n)},$$slots:{default:!0}})});var a=L(i,2);yi(a,21,()=>s(H(r)),([e,t])=>e,(e,t)=>{var n=j(()=>h(H(t),2));let r=()=>H(n)[0],i=()=>H(n)[1];var a=zl(),o=F(a),s=F(o,!0);E(o);var c=L(o,2),l=F(c,!0);E(c),E(a),R(()=>{K(s,r()),K(l,i())}),G(e,a)}),E(a),Ti(L(a,2),()=>jl,(e,t)=>{t(e,{class:`mt-4 w-full rounded-md border py-2 text-sm text-muted-foreground transition-colors hover:text-foreground`,children:(e,t)=>{Ue(),G(e,ai(`Close`))},$$slots:{default:!0}})}),G(e,t)};q(i,e=>{H(r)&&e(a)}),G(e,n)},$$slots:{default:!0}})}),G(e,n)},$$slots:{default:!0}})}),G(e,n)},$$slots:{default:!0}})}),G(e,c),k()}Xr([`click`]);var Ul=U(`<div class=\"flex items-baseline justify-between font-mono text-[11px]\"><span class=\"text-muted-foreground\"> </span> <span class=\"tabular-nums text-foreground\"> </span></div>`),Wl=U(`<div class=\"text-[11px] text-muted-foreground\">No graph-tool calls yet.</div>`),Gl=U(`<div class=\"font-mono text-2xl text-foreground\"> <span class=\"text-sm text-muted-foreground\">calls</span></div> <div class=\"flex flex-col gap-1.5\"></div>`,1);function Kl(e,t){O(t,!0);let n=j(()=>{let e=X.data?.global?.tool_calls??{};return Object.entries(e).sort((e,t)=>t[1]-e[1]).slice(0,8)}),r=j(()=>X.data?.global?.total_tool_calls??0);Xa(e,{title:`Graph tools used`,meta:`all projects`,children:(e,t)=>{var i=Gl(),a=I(i),o=F(a);Ue(),E(a);var s=L(a,2);yi(s,21,()=>H(n),([e,t])=>e,(e,t)=>{var n=j(()=>h(H(t),2));let r=()=>H(n)[0],i=()=>H(n)[1];var a=Ul(),o=F(a),s=F(o,!0);E(o);var c=L(o,2),l=F(c,!0);E(c),E(a),R(()=>{K(s,r()),K(l,i())}),G(e,a)},e=>{G(e,Wl())}),E(s),R(e=>K(o,`${e??``} `),[()=>Z(H(r))]),G(e,i)},$$slots:{default:!0}}),k()}var ql=U(`<tr class=\"border-t border-border/60\"><td class=\"py-1.5 pr-2 text-muted-foreground\"> </td><td class=\"max-w-[120px] truncate py-1.5 pr-2 text-foreground\"> </td><td class=\"py-1.5 pr-2\"><span class=\"inline-flex items-center gap-1.5 rounded px-1.5 py-0.5\"><span class=\"size-1.5 rounded-sm\"></span> </span></td><td class=\"py-1.5 pr-2 text-right tabular-nums text-foreground\"> </td><td class=\"py-1.5 pr-2 text-right tabular-nums text-foreground\"> </td><td class=\"py-1.5 pr-2 text-right tabular-nums text-muted-foreground\"> </td><td class=\"py-1.5 text-right tabular-nums text-[var(--money)]\"> </td></tr>`),Jl=U(`<tr><td colspan=\"7\" class=\"py-6 text-center text-muted-foreground\">No turns recorded yet.</td></tr>`),Yl=U(`<div class=\"flex items-center justify-end gap-3 pt-1 font-mono text-[11px] text-muted-foreground\"><button class=\"rounded border px-2 py-1 disabled:opacity-40 enabled:hover:text-foreground\">‹ Prev</button> <span> </span> <button class=\"rounded border px-2 py-1 disabled:opacity-40 enabled:hover:text-foreground\">Next ›</button></div>`),Xl=U(`<div class=\"min-h-0 flex-1 overflow-x-auto\"><table class=\"w-full border-collapse font-mono text-[11px]\"><thead><tr class=\"text-left text-[9px] uppercase tracking-[0.1em] text-muted-foreground\"><th class=\"py-1.5 pr-2 font-medium\">Time</th><th class=\"py-1.5 pr-2 font-medium\">Project</th><th class=\"py-1.5 pr-2 font-medium\">Model</th><th class=\"py-1.5 pr-2 text-right font-medium\">In</th><th class=\"py-1.5 pr-2 text-right font-medium\">Out</th><th class=\"py-1.5 pr-2 text-right font-medium\">Cache R/W</th><th class=\"py-1.5 text-right font-medium\">Cost</th></tr></thead><tbody></tbody></table></div> <!>`,1);function Zl(e,t){O(t,!0);let n=N(1),r=j(()=>X.data?.recent_turns??[]),i=j(()=>Math.max(1,Math.ceil(H(r).length/25)));Rn(()=>{H(n)>H(i)&&P(n,H(i),!0)});let a=j(()=>H(r).slice((H(n)-1)*25,(H(n)-1)*25+25)),o=j(()=>H(r).length?(H(n)-1)*25+1:0),s=j(()=>Math.min(H(n)*25,H(r).length));{let t=j(()=>`showing ${H(o)}–${H(s)} of ${H(r).length}`);Xa(e,{title:`Recent turns`,get meta(){return H(t)},children:(e,t)=>{var r=Xl(),o=I(r),s=F(o),c=L(F(s));yi(c,21,()=>H(a),e=>e.ts+e.project_path+e.model,(e,t)=>{var n=ql(),r=F(n),i=F(r,!0);E(r);var a=L(r),o=F(a,!0);E(a);var s=L(a),c=F(s),l=F(c),u=L(l);E(c),E(s);var d=L(s),f=F(d,!0);E(d);var p=L(d),m=F(p,!0);E(p);var h=L(p),g=F(h);E(h);var _=L(h),v=F(_,!0);E(_),E(n),R((e,n,r,s,d,p,h,_,y)=>{K(i,e),Qi(a,`title`,H(t).project_name),K(o,H(t).project_name),Ri(c,n),Ri(l,r),K(u,` ${s??``}`),K(f,d),K(m,p),K(g,`${h??``} / ${_??``}`),K(v,y)},[()=>ma(H(t).ts),()=>`color: var(--c-${ha(H(t).model)})`,()=>`background: var(--c-${ha(H(t).model)})`,()=>ga(H(t).model),()=>Z(H(t).input),()=>Z(H(t).output),()=>Z(H(t).cache_read),()=>Z(H(t).cache_create),()=>pa(H(t).cost_usd)]),G(e,n)},e=>{G(e,Jl())}),E(c),E(s),E(o);var l=L(o,2),u=e=>{var t=Yl(),r=F(t),a=L(r,2),o=F(a);E(a);var s=L(a,2);E(t),R(()=>{r.disabled=H(n)<=1,K(o,`page ${H(n)??``} of ${H(i)??``}`),s.disabled=H(n)>=H(i)}),Yr(`click`,r,()=>P(n,Math.max(1,H(n)-1),!0)),Yr(`click`,s,()=>P(n,Math.min(H(i),H(n)+1),!0)),G(e,t)};q(l,e=>{H(i)>1&&e(u)}),G(e,r)},$$slots:{default:!0}})}k()}Xr([`click`]);var Ql=U(`<div class=\"flex items-baseline gap-2 font-mono text-[10px]\"><span class=\"shrink-0 text-muted-foreground\"> </span> <span> </span> <span class=\"truncate text-foreground/80\"> </span></div>`),$l=U(`<div class=\"text-[11px] text-muted-foreground\">No gate decisions yet.</div>`),eu=U(`<div class=\"font-mono text-2xl text-foreground\"> <span class=\"text-sm text-muted-foreground\">blocks</span></div> <div class=\"flex max-h-[320px] flex-col gap-1 overflow-y-auto\"></div>`,1);function tu(e,t){O(t,!0);let n=j(()=>(X.data?.recent_gates??[]).slice(0,50)),r=j(()=>X.data?.global?.blocked_count??0);Xa(e,{title:`The Moat`,meta:`PreToolUse`,children:(e,t)=>{var i=eu(),a=I(i),o=F(a);Ue(),E(a);var s=L(a,2);yi(s,21,()=>H(n),e=>e.ts+e.query,(e,t)=>{var n=Ql(),r=F(n),i=F(r,!0);E(r);var a=L(r,2),o=F(a,!0);E(a);var s=L(a,2),c=F(s,!0);E(s),E(n),R(e=>{K(i,e),Ii(a,1,`shrink-0 rounded px-1 text-[9px] uppercase `+(H(t).decision===`block`?`bg-destructive/15 text-destructive`:`bg-[var(--c-fable)]/12 text-[var(--c-fable)]`)),K(o,H(t).decision),Qi(s,`title`,H(t).query??``),K(c,H(t).query??`—`)},[()=>ma(H(t).ts)]),G(e,n)},e=>{G(e,$l())}),E(s),R(e=>K(o,`${e??``} `),[()=>Z(H(r))]),G(e,i)},$$slots:{default:!0}}),k()}var nu=U(`<div class=\"flex items-baseline justify-between gap-3 font-mono text-[11px]\"><span class=\"truncate text-muted-foreground\"> </span> <span class=\"tabular-nums text-foreground\"> </span></div>`),ru=U(`<div class=\"text-[11px] text-muted-foreground\">No usage learned yet — Synthra learns as you read/edit files.</div>`),iu=U(`<div class=\"font-mono text-2xl text-foreground\"> <span class=\"text-sm text-muted-foreground\">tracked</span></div> <div class=\"flex max-h-[190px] flex-col gap-1.5 overflow-y-auto\"></div>`,1);function au(e,t){O(t,!0);let n=j(()=>X.data?.active),r=j(()=>H(n)?.stats?.hot_files??[]);{let t=j(()=>H(n)?.project_name??`active project`);Xa(e,{title:`Hot files`,get meta(){return H(t)},children:(e,t)=>{var i=iu(),a=I(i),o=F(a);Ue(),E(a);var s=L(a,2);yi(s,21,()=>H(r),e=>e.path,(e,t)=>{var n=nu(),r=F(n),i=F(r,!0);E(r);var a=L(r,2),o=F(a,!0);E(a),E(n),R(e=>{Qi(n,`title`,H(t).path),K(i,e),K(o,H(t).score)},[()=>_a(H(t).path)]),G(e,n)},e=>{G(e,ru())}),E(s),R(e=>K(o,`${e??``} `),[()=>Z(H(n)?.stats?.hot_files_total??0)]),G(e,i)},$$slots:{default:!0}})}k()}var ou=U(`<div class=\"flex flex-col gap-4 p-5\"><!> <div class=\"grid grid-cols-12 gap-4\"><div class=\"col-span-12 lg:col-span-7\"><!></div> <div class=\"col-span-12 lg:col-span-5\"><!></div> <div class=\"col-span-12 md:col-span-6 xl:col-span-4\"><!></div> <div class=\"col-span-12 md:col-span-6 xl:col-span-4\"><!></div> <div class=\"col-span-12 xl:col-span-4\"><!></div> <div class=\"col-span-12 xl:col-span-8\"><!></div> <div class=\"col-span-12 flex flex-col gap-4 xl:col-span-4\"><!> <!></div></div></div>`);function su(e){var t=ou(),n=F(t);Ka(n,{});var r=L(n,2),i=F(r);Qa(F(i),{}),E(i);var a=L(i,2);eo(F(a),{}),E(a);var o=L(a,2);ao(F(o),{}),E(o);var s=L(o,2);Hl(F(s),{}),E(s);var c=L(s,2);Kl(F(c),{}),E(c);var l=L(c,2);Zl(F(l),{}),E(l);var u=L(l,2),d=F(u);tu(d,{}),au(L(d,2),{}),E(u),E(r),E(t),G(e,t)}var cu=U(`<p> </p>`),lu=U(`<div class=\"break-all\"><span class=\"text-foreground/70\"> </span> </div>`),uu=U(`<div class=\"mt-1 flex flex-col gap-0.5 font-mono text-[10px] text-muted-foreground/80\"></div>`),du=U(`<button class=\"flex flex-col gap-1.5 rounded-lg border bg-card/55 p-3 text-left transition-colors hover:bg-card/85\"><div class=\"flex items-center gap-2\"><span class=\"min-w-0 flex-1 truncate font-mono text-[12px] text-foreground\"> </span> <span> </span></div> <!> <!></button>`);function fu(e,t){O(t,!0);let n=N(!1),r=j(()=>t.item.scope===`plugin`?t.item.source??`plugin`:t.item.scope),i=j(()=>t.item.scope===`project`?`var(--c-fable)`:t.item.scope===`personal`?`var(--c-sonnet)`:`#9bc2ef`),a=j(()=>Object.entries(t.item.meta??{}));var o=du(),s=F(o),c=F(s),l=F(c,!0);E(c);var u=L(c,2);let d;var f=F(u);E(u),E(s);var p=L(s,2),m=e=>{var r=cu(),i=F(r,!0);E(r),R(()=>{Ii(r,1,`text-[11.5px] leading-snug text-muted-foreground `+(H(n)?``:`line-clamp-2`)),K(i,t.item.description)}),G(e,r)};q(p,e=>{t.item.description&&e(m)});var g=L(p,2),_=e=>{var t=uu();yi(t,21,()=>H(a),([e,t])=>e,(e,t)=>{var n=j(()=>h(H(t),2));let r=()=>H(n)[0],i=()=>H(n)[1];var a=lu(),o=F(a),s=F(o);E(o);var c=L(o);E(a),R(()=>{K(s,`${r()??``}:`),K(c,` ${i()??``}`)}),G(e,a)}),E(t),G(e,t)};q(g,e=>{H(n)&&H(a).length&&e(_)}),E(o),R(()=>{K(l,t.item.name),d=Ii(u,1,`shrink-0 rounded border px-1.5 py-0.5 font-mono text-[8px] uppercase tracking-wide`,null,d,{\"opacity-50\":t.item.enabled===!1}),Ri(u,`color:${H(i)}; border-color:color-mix(in oklab, ${H(i)} 35%, transparent)`),K(f,`${H(r)??``}${t.item.enabled===!1?` · off`:``}`)}),Yr(`click`,o,()=>P(n,!H(n))),G(e,o),k()}Xr([`click`]);var pu=U(`<span> </span>`),mu=U(`<button> <span class=\"opacity-60\"> </span></button>`),hu=U(`<div class=\"text-sm text-muted-foreground\">Scanning your arsenal…</div>`),gu=U(`<div class=\"text-sm text-muted-foreground\"> </div>`),_u=U(`<div class=\"grid grid-cols-1 gap-2 md:grid-cols-2 2xl:grid-cols-3\"></div>`),vu=U(`<div class=\"flex h-full flex-col gap-4 p-5\"><div class=\"flex flex-wrap items-center justify-between gap-3\"><h1 class=\"font-serif text-2xl text-foreground\">⚔ Arsenal</h1> <div class=\"flex items-center gap-2 font-mono text-[10px] text-muted-foreground\"><!> <button class=\"rounded border px-2 py-1 transition-colors hover:text-foreground\">↻ Rescan</button></div></div> <div class=\"flex flex-wrap items-center gap-2\"><!> <input placeholder=\"Filter by name or description…\" autocomplete=\"off\" class=\"ml-auto w-full max-w-72 rounded-md border bg-card/60 px-3 py-1.5 text-sm outline-none transition-colors focus:border-ring\"/></div> <!></div>`);function yu(e,t){O(t,!0);let n=N(`skills`),r=N(``),i=j(()=>X.arsenal),a=[{id:`skills`,label:`Skills`},{id:`agents`,label:`Agents`},{id:`mcp`,label:`MCP`}],o=j(()=>{let e=H(i)?H(i)[H(n)]:[],t=H(r).toLowerCase().trim();return t?e.filter(e=>e.name.toLowerCase().includes(t)||(e.description??``).toLowerCase().includes(t)||(e.source??``).toLowerCase().includes(t)):e}),s=j(()=>H(i)?new Date(H(i).scanned_at).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}):``);var c=vu(),l=F(c),u=L(F(l),2),d=F(u),f=e=>{var t=pu(),n=F(t);E(t),R(()=>K(n,`${H(i).counts.plugins??``} plugins · scanned ${H(s)??``}`)),G(e,t)};q(d,e=>{H(i)&&e(f)});var p=L(d,2);E(u),E(l);var m=L(l,2),h=F(m);yi(h,17,()=>a,e=>e.id,(e,t)=>{var r=mu(),a=F(r),o=L(a),s=F(o,!0);E(o),E(r),R(()=>{Ii(r,1,`rounded-lg px-3 py-1.5 font-mono text-xs transition-colors `+(H(n)===H(t).id?`bg-accent text-accent-foreground`:`text-muted-foreground hover:text-foreground`)),K(a,`${H(t).label??``} `),K(s,H(i)?.counts?.[H(t).id]??0)}),Yr(`click`,r,()=>P(n,H(t).id,!0)),G(e,r)});var g=L(h,2);Xi(g),E(m);var _=L(m,2),v=e=>{G(e,hu())},y=e=>{var t=_u();yi(t,21,()=>H(o),e=>e.scope+(e.source??``)+e.name,(e,t)=>{fu(e,{get item(){return H(t)}})},e=>{var t=gu(),n=F(t,!0);E(t),R(()=>K(n,H(r)?`No matches.`:`Nothing installed in this category.`)),G(e,t)}),E(t),G(e,t)};q(_,e=>{X.arsenalLoading&&!H(i)?e(v):e(y,-1)}),E(c),Yr(`click`,p,()=>X.loadArsenal(!0)),ia(g,()=>H(r),e=>P(r,e)),G(e,c),k()}Xr([`click`]);var bu=U(`<details class=\"rounded-lg border bg-card/50 p-3\"><summary class=\"cursor-pointer text-sm font-medium text-foreground\"> </summary> <p class=\"mt-2 text-[13px] leading-relaxed text-muted-foreground\"> </p></details>`),xu=U(`<!> <!> <div class=\"mt-4 flex flex-col gap-2\"></div> <!>`,1),Su=U(`<!> <!>`,1);function Cu(e,t){O(t,!0);let n=Y(t,`open`,15,!1),r=[{q:`Where do these numbers come from?`,a:`Synthra's Stop hook reads Claude Code's transcript JSONL after each turn and logs token usage to .synthra-graph/token_log.jsonl. The gate logs to gate_log.jsonl, tool calls to tool_log.jsonl. The dashboard reads those — it never feeds back into retrieval.`},{q:`How is cost calculated?`,a:`Token counts × Anthropic's published per-model rates (in src/shared/pricing.ts), summed across input, output, cache-read and cache-write. These are API-equivalent estimates, not your plan billing — useful for comparing sessions.`},{q:`What is the savings floor?`,a:`Each time the Moat blocks an exploratory Grep/Glob, we credit a deliberately conservative 500 tokens × $3/M input rate. Real savings are usually higher (it ignores cache thrash and follow-up reads the block also prevents). It's a floor, not a guess.`},{q:`What is the Moat?`,a:`A PreToolUse hook that intercepts Grep/Glob and, when the graph has confident context, blocks them and hands back the exact graph_read targets + signatures — so the agent reads ~50-token slices instead of whole files.`},{q:`What is the Arsenal view?`,a:`A scan of every skill, subagent, and MCP server available to you — project, personal (~/.claude), and plugin — with descriptions, so you never have to drop to the CLI to recall what's installed. MCP entries show name/type/url only; auth tokens are never read.`},{q:`What's the codebase graph?`,a:`tree-sitter parses your project into a symbol graph (files, symbols, imports, call edges). graph_read returns a symbol's source plus its dependency surface; graph_continue packs a context bundle.`},{q:`Where is everything stored?`,a:`.synthra-graph/ (machine-local, gitignored) holds the graph + logs; .synthra/ (git-tracked) holds branch-aware memory. Nothing leaves your machine.`},{q:`Why is my bill not lower already?`,a:`Savings land only when the agent actually uses the cheap path. v0.4–0.6 push the answer to the point of use (block payloads, edit recipes, dependency footers); a real dogfood session on the latest version is the true test.`}];var i=W();Ti(I(i),()=>Ol,(e,t)=>{t(e,{get open(){return n()},set open(e){n(e)},children:(e,t)=>{var n=W();Ti(I(n),()=>ic,(e,t)=>{t(e,{children:(e,t)=>{var n=Su(),i=I(n);Ti(i,()=>wl,(e,t)=>{t(e,{class:`fixed inset-0 z-50 bg-black/60`})}),Ti(L(i,2),()=>Fl,(e,t)=>{t(e,{class:`fixed left-1/2 top-1/2 z-50 max-h-[85vh] w-[min(640px,92vw)] -translate-x-1/2 -translate-y-1/2 overflow-y-auto rounded-xl border bg-card p-6 text-card-foreground shadow-2xl`,children:(e,t)=>{var n=xu(),i=I(n);Ti(i,()=>Xs,(e,t)=>{t(e,{class:`font-serif text-2xl`,children:(e,t)=>{Ue(),G(e,ai(`FAQ`))},$$slots:{default:!0}})});var a=L(i,2);Ti(a,()=>Dl,(e,t)=>{t(e,{class:`text-xs text-muted-foreground`,children:(e,t)=>{Ue(),G(e,ai(`Where every number on this dashboard comes from.`))},$$slots:{default:!0}})});var o=L(a,2);yi(o,21,()=>r,e=>e.q,(e,t)=>{var n=bu(),r=F(n),i=F(r,!0);E(r);var a=L(r,2),o=F(a,!0);E(a),E(n),R(()=>{K(i,H(t).q),K(o,H(t).a)}),G(e,n)}),E(o),Ti(L(o,2),()=>jl,(e,t)=>{t(e,{class:`mt-4 w-full rounded-md border py-2 text-sm text-muted-foreground transition-colors hover:text-foreground`,children:(e,t)=>{Ue(),G(e,ai(`Close`))},$$slots:{default:!0}})}),G(e,n)},$$slots:{default:!0}})}),G(e,n)},$$slots:{default:!0}})}),G(e,n)},$$slots:{default:!0}})}),G(e,i),k()}var wu=U(`<div class=\"flex h-screen w-screen overflow-hidden\"><!> <main class=\"min-w-0 flex-1 overflow-y-auto\"><!></main></div> <!>`,1);function Tu(e,t){O(t,!0);let n=N(!1);da(()=>(X.start(),()=>X.stop()));var r=wu(),i=I(r),a=F(i);Ua(a,{onFaq:()=>P(n,!0)});var o=L(a,2),s=F(o),c=e=>{su(e,{})},l=e=>{yu(e,{})};q(s,e=>{X.view===`overview`?e(c):e(l,-1)}),E(o),E(i),Cu(L(i,2),{get open(){return H(n)},set open(e){P(n,e,!0)}}),G(e,r),k()}var Eu=document.getElementById(`app`);if(!Eu)throw Error(`missing #app mount node`);si(Tu,{target:Eu});</script>\n <style rel=\"stylesheet\" crossorigin>/*! tailwindcss v4.3.1 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0}}}@layer theme{:root,:host{--font-sans:var(--font-sans);--font-serif:var(--font-serif);--font-mono:var(--font-mono);--color-black:#000;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--font-weight-medium:500;--tracking-wide:.025em;--leading-snug:1.375;--leading-relaxed:1.625;--radius-xl:.75rem;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border)}html,body{height:100%}body{background:radial-gradient(1200px 800px at 14% 16%, #2c5db81f, transparent 60%), var(--background);color:var(--foreground);font-family:var(--font-sans);-webkit-font-smoothing:antialiased}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-thumb{background:var(--border);border-radius:999px}::-webkit-scrollbar-track{background:0 0}}@layer components;@layer utilities{.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:0}.top-1\\/2{top:50%}.left-1\\/2{left:50%}.z-50{z-index:50}.col-span-12{grid-column:span 12/span 12}.my-1{margin-block:var(--spacing)}.mt-1{margin-top:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-4{margin-top:calc(var(--spacing) * 4)}.ml-auto{margin-left:auto}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.grid{display:grid}.inline{display:inline}.inline-flex{display:inline-flex}.size-1\\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-\\[116px\\]{width:116px;height:116px}.size-full{width:100%;height:100%}.h-1{height:var(--spacing)}.h-2{height:calc(var(--spacing) * 2)}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-\\[85vh\\]{max-height:85vh}.max-h-\\[190px\\]{max-height:190px}.max-h-\\[260px\\]{max-height:260px}.max-h-\\[320px\\]{max-height:320px}.min-h-0{min-height:0}.w-9{width:calc(var(--spacing) * 9)}.w-\\[64px\\]{width:64px}.w-\\[248px\\]{width:248px}.w-\\[min\\(440px\\,92vw\\)\\]{width:min(440px,92vw)}.w-\\[min\\(640px\\,92vw\\)\\]{width:min(640px,92vw)}.w-full{width:100%}.w-screen{width:100vw}.max-w-72{max-width:calc(var(--spacing) * 72)}.max-w-\\[120px\\]{max-width:120px}.min-w-0{min-width:0}.flex-1{flex:1}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.-translate-x-1\\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-rotate-90{rotate:-90deg}.animate-pulse{animation:var(--animate-pulse)}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.items-baseline{align-items:baseline}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-px{gap:1px}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-border,.border-border\\/60{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.border-border\\/60{border-color:color-mix(in oklab, var(--border) 60%, transparent)}}.border-sidebar-border{border-color:var(--sidebar-border)}.bg-\\[var\\(--c-fable\\)\\],.bg-\\[var\\(--c-fable\\)\\]\\/12{background-color:var(--c-fable)}@supports (color:color-mix(in lab, red, red)){.bg-\\[var\\(--c-fable\\)\\]\\/12{background-color:color-mix(in oklab, var(--c-fable) 12%, transparent)}}.bg-\\[var\\(--money\\)\\]{background-color:var(--money)}.bg-accent{background-color:var(--accent)}.bg-black\\/60{background-color:#0009}@supports (color:color-mix(in lab, red, red)){.bg-black\\/60{background-color:color-mix(in oklab, var(--color-black) 60%, transparent)}}.bg-border{background-color:var(--border)}.bg-card,.bg-card\\/50{background-color:var(--card)}@supports (color:color-mix(in lab, red, red)){.bg-card\\/50{background-color:color-mix(in oklab, var(--card) 50%, transparent)}}.bg-card\\/55{background-color:var(--card)}@supports (color:color-mix(in lab, red, red)){.bg-card\\/55{background-color:color-mix(in oklab, var(--card) 55%, transparent)}}.bg-card\\/60{background-color:var(--card)}@supports (color:color-mix(in lab, red, red)){.bg-card\\/60{background-color:color-mix(in oklab, var(--card) 60%, transparent)}}.bg-card\\/70{background-color:var(--card)}@supports (color:color-mix(in lab, red, red)){.bg-card\\/70{background-color:color-mix(in oklab, var(--card) 70%, transparent)}}.bg-destructive,.bg-destructive\\/15{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.bg-destructive\\/15{background-color:color-mix(in oklab, var(--destructive) 15%, transparent)}}.bg-muted-foreground,.bg-muted-foreground\\/40{background-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.bg-muted-foreground\\/40{background-color:color-mix(in oklab, var(--muted-foreground) 40%, transparent)}}.bg-primary\\/90{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.bg-primary\\/90{background-color:color-mix(in oklab, var(--primary) 90%, transparent)}}.bg-sidebar{background-color:var(--sidebar)}.bg-sidebar-accent,.bg-sidebar-accent\\/40{background-color:var(--sidebar-accent)}@supports (color:color-mix(in lab, red, red)){.bg-sidebar-accent\\/40{background-color:color-mix(in oklab, var(--sidebar-accent) 40%, transparent)}}.bg-sidebar-border{background-color:var(--sidebar-border)}.p-2\\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.px-1{padding-inline:var(--spacing)}.px-1\\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.py-0\\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-6{padding-block:calc(var(--spacing) * 6)}.pt-1{padding-top:var(--spacing)}.pr-1{padding-right:var(--spacing)}.pr-2{padding-right:calc(var(--spacing) * 2)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.font-serif{font-family:var(--font-serif)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[8px\\]{font-size:8px}.text-\\[9px\\]{font-size:9px}.text-\\[10px\\]{font-size:10px}.text-\\[11\\.5px\\]{font-size:11.5px}.text-\\[11px\\]{font-size:11px}.text-\\[12px\\]{font-size:12px}.text-\\[13px\\]{font-size:13px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.tracking-\\[0\\.1em\\]{--tw-tracking:.1em;letter-spacing:.1em}.tracking-\\[0\\.12em\\]{--tw-tracking:.12em;letter-spacing:.12em}.tracking-\\[0\\.14em\\]{--tw-tracking:.14em;letter-spacing:.14em}.tracking-\\[0\\.18em\\]{--tw-tracking:.18em;letter-spacing:.18em}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.break-all{word-break:break-all}.text-\\[var\\(--c-fable\\)\\]{color:var(--c-fable)}.text-\\[var\\(--money\\)\\]{color:var(--money)}.text-accent-foreground{color:var(--accent-foreground)}.text-card-foreground{color:var(--card-foreground)}.text-destructive{color:var(--destructive)}.text-foreground,.text-foreground\\/70{color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.text-foreground\\/70{color:color-mix(in oklab, var(--foreground) 70%, transparent)}}.text-foreground\\/80{color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.text-foreground\\/80{color:color-mix(in oklab, var(--foreground) 80%, transparent)}}.text-muted-foreground,.text-muted-foreground\\/80{color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\\/80{color:color-mix(in oklab, var(--muted-foreground) 80%, transparent)}}.text-primary-foreground{color:var(--primary-foreground)}.text-sidebar-accent-foreground{color:var(--sidebar-accent-foreground)}.text-sidebar-foreground,.text-sidebar-foreground\\/60{color:var(--sidebar-foreground)}@supports (color:color-mix(in lab, red, red)){.text-sidebar-foreground\\/60{color:color-mix(in oklab, var(--sidebar-foreground) 60%, transparent)}}.text-sidebar-foreground\\/75{color:var(--sidebar-foreground)}@supports (color:color-mix(in lab, red, red)){.text-sidebar-foreground\\/75{color:color-mix(in oklab, var(--sidebar-foreground) 75%, transparent)}}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.transition-\\[width\\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.outline-none{--tw-outline-style:none;outline-style:none}@media (hover:hover){.hover\\:bg-card\\/80:hover{background-color:var(--card)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-card\\/80:hover{background-color:color-mix(in oklab, var(--card) 80%, transparent)}}.hover\\:bg-card\\/85:hover{background-color:var(--card)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-card\\/85:hover{background-color:color-mix(in oklab, var(--card) 85%, transparent)}}.hover\\:bg-sidebar-accent\\/50:hover{background-color:var(--sidebar-accent)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-sidebar-accent\\/50:hover{background-color:color-mix(in oklab, var(--sidebar-accent) 50%, transparent)}}.hover\\:text-foreground:hover{color:var(--foreground)}.hover\\:text-sidebar-foreground:hover{color:var(--sidebar-foreground)}}.focus\\:border-ring:focus{border-color:var(--ring)}@media (hover:hover){.enabled\\:hover\\:text-foreground:enabled:hover{color:var(--foreground)}}.disabled\\:opacity-40:disabled{opacity:.4}@media (width>=40rem){.sm\\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (width>=48rem){.md\\:col-span-6{grid-column:span 6/span 6}.md\\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (width>=64rem){.lg\\:col-span-5{grid-column:span 5/span 5}.lg\\:col-span-7{grid-column:span 7/span 7}.lg\\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}}@media (width>=80rem){.xl\\:col-span-4{grid-column:span 4/span 4}.xl\\:col-span-8{grid-column:span 8/span 8}}@media (width>=96rem){.\\32 xl\\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}}@property --tw-animation-delay{syntax:\"*\";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:\"*\";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:\"*\";inherits:false}@property --tw-animation-fill-mode{syntax:\"*\";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:\"*\";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:\"*\";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:\"*\";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:\"*\";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:\"*\";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:\"*\";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:\"*\";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:\"*\";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:\"*\";inherits:false;initial-value:0}:root{--radius:.75rem;--background:#04081a;--foreground:#ecf2fb;--card:#0a1733;--card-foreground:#ecf2fb;--popover:#0a1733;--popover-foreground:#ecf2fb;--primary:#2c5db8;--primary-foreground:#f4f7fc;--secondary:#122549;--secondary-foreground:#d7e6f7;--muted:#102146;--muted-foreground:#8ba0c2;--accent:#1b3a78;--accent-foreground:#ecf2fb;--destructive:#ff5d5d;--destructive-foreground:#fff5f5;--border:#9bc2ef24;--input:#9bc2ef2e;--ring:#5c8fe6;--sidebar:#081226;--sidebar-foreground:#d7e6f7;--sidebar-primary:#2c5db8;--sidebar-primary-foreground:#f4f7fc;--sidebar-accent:#122549;--sidebar-accent-foreground:#ecf2fb;--sidebar-border:#9bc2ef1f;--sidebar-ring:#5c8fe6;--c-fable:#2ee08f;--c-opus:#ff6338;--c-sonnet:#ffb938;--c-haiku:#7438ff;--c-unknown:#12cbf5;--money:#4ade9b;--font-sans:\"Geist\", ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif;--font-serif:\"Instrument Serif\", \"Times New Roman\", serif;--font-mono:\"Geist Mono\", ui-monospace, \"SF Mono\", Menlo, Consolas, monospace}@property --tw-translate-x{syntax:\"*\";inherits:false;initial-value:0}@property --tw-translate-y{syntax:\"*\";inherits:false;initial-value:0}@property --tw-translate-z{syntax:\"*\";inherits:false;initial-value:0}@property --tw-border-style{syntax:\"*\";inherits:false;initial-value:solid}@property --tw-leading{syntax:\"*\";inherits:false}@property --tw-font-weight{syntax:\"*\";inherits:false}@property --tw-tracking{syntax:\"*\";inherits:false}@property --tw-ordinal{syntax:\"*\";inherits:false}@property --tw-slashed-zero{syntax:\"*\";inherits:false}@property --tw-numeric-figure{syntax:\"*\";inherits:false}@property --tw-numeric-spacing{syntax:\"*\";inherits:false}@property --tw-numeric-fraction{syntax:\"*\";inherits:false}@property --tw-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:\"*\";inherits:false}@property --tw-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:\"*\";inherits:false}@property --tw-inset-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:\"*\";inherits:false}@property --tw-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:\"*\";inherits:false}@property --tw-inset-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:\"*\";inherits:false}@property --tw-ring-offset-width{syntax:\"<length>\";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:\"*\";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:\"*\";inherits:false}@keyframes pulse{50%{opacity:.5}}\n/*$vite$:1*/</style>\n </head>\n <body>\n <div id=\"app\"></div>\n </body>\n</html>\n","<svg width=\"107\" height=\"107\" viewBox=\"0 0 107 107\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<rect x=\"0.5\" y=\"0.5\" width=\"106\" height=\"106\" rx=\"7.5\" fill=\"url(#paint0_radial_21_11)\"/>\n<rect x=\"0.5\" y=\"0.5\" width=\"106\" height=\"106\" rx=\"7.5\" stroke=\"url(#paint1_linear_21_11)\"/>\n<path d=\"M26.408 72.558C25.5813 72.558 24.6513 72.4753 23.618 72.31C22.626 72.1447 21.6753 71.938 20.766 71.69C19.898 71.442 19.216 71.1733 18.72 70.884C18.4307 70.7187 18.2033 70.5533 18.038 70.388C17.914 70.1813 17.852 69.8507 17.852 69.396L17.542 59.662C17.542 58.8353 17.8107 58.422 18.348 58.422C18.8027 58.422 19.1127 58.794 19.278 59.538L19.836 61.894C21.2413 67.8047 23.866 70.76 27.71 70.76C29.7767 70.76 31.4093 70.078 32.608 68.714C33.848 67.3087 34.468 65.3453 34.468 62.824C34.468 60.3853 33.8273 58.112 32.546 56.004C31.306 53.896 29.3013 51.8087 26.532 49.742C23.4733 47.5513 21.2413 45.4433 19.836 43.418C18.4307 41.3513 17.728 39.1607 17.728 36.846C17.728 33.7873 18.782 31.3487 20.89 29.53C23.0393 27.67 25.7673 26.74 29.074 26.74C30.314 26.74 31.5127 26.8847 32.67 27.174C33.8273 27.4633 34.778 27.8767 35.522 28.414C35.77 28.5793 35.956 28.7653 36.08 28.972C36.2453 29.1787 36.328 29.4473 36.328 29.778L36.514 39.14C36.514 39.8427 36.2453 40.194 35.708 40.194C35.336 40.194 35.0673 39.9047 34.902 39.326L34.468 37.776C33.5587 34.5933 32.608 32.2787 31.616 30.832C30.6653 29.344 29.2807 28.6 27.462 28.6C25.6847 28.6 24.2587 29.1787 23.184 30.336C22.1507 31.4933 21.634 33.126 21.634 35.234C21.634 37.0113 22.2127 38.706 23.37 40.318C24.5273 41.93 26.5527 43.8933 29.446 46.208C32.546 48.7293 34.7987 51.168 36.204 53.524C37.6507 55.8387 38.374 58.3187 38.374 60.964C38.374 63.2787 37.8573 65.304 36.824 67.04C35.7907 68.776 34.3647 70.14 32.546 71.132C30.7687 72.0827 28.7227 72.558 26.408 72.558ZM44.1831 84.71C43.0671 84.71 42.1784 84.3173 41.5171 83.532C40.8558 82.788 40.5251 81.92 40.5251 80.928C40.5251 80.1427 40.7524 79.4813 41.2071 78.944C41.6618 78.4067 42.2818 78.138 43.0671 78.138C43.7284 78.138 44.2038 78.2827 44.4931 78.572C44.7824 78.8613 44.9891 79.192 45.1131 79.564C45.2371 79.936 45.3611 80.2667 45.4851 80.556C45.6091 80.8453 45.8571 80.99 46.2291 80.99C46.6838 80.99 47.0971 80.6593 47.4691 79.998C47.8411 79.378 48.3578 78.0347 49.0191 75.968C49.4324 74.728 49.6804 73.6533 49.7631 72.744C49.8871 71.8347 49.8664 70.8633 49.7011 69.83C49.5771 68.7967 49.2671 67.536 48.7711 66.048L42.0131 44.534C41.7238 43.542 41.4344 42.9013 41.1451 42.612C40.8971 42.3227 40.4838 42.116 39.9051 41.992L38.9751 41.806C38.4378 41.682 38.1691 41.4133 38.1691 41C38.1691 40.5867 38.4584 40.38 39.0371 40.38H49.2671C49.8458 40.38 50.1351 40.5867 50.1351 41C50.1351 41.4547 49.8664 41.7233 49.3291 41.806L48.3371 41.93C47.3451 42.054 46.7044 42.302 46.4151 42.674C46.1671 43.0047 46.1878 43.6247 46.4771 44.534L51.9331 62.7C52.0571 63.1133 52.2431 63.32 52.4911 63.32C52.7804 63.32 52.9871 63.1133 53.1111 62.7L58.3811 45.65C58.7118 44.534 58.7944 43.7073 58.6291 43.17C58.5051 42.5913 57.9264 42.2193 56.8931 42.054L55.5911 41.806C55.0538 41.682 54.7851 41.4133 54.7851 41C54.7851 40.5867 55.0744 40.38 55.6531 40.38H63.5271C64.1058 40.38 64.3951 40.6073 64.3951 41.062C64.3951 41.4753 64.1471 41.7647 63.6511 41.93L63.0931 42.116C62.4731 42.3227 61.9564 42.6947 61.5431 43.232C61.1298 43.7693 60.6958 44.6993 60.2411 46.022L51.0031 74.852C50.0938 77.7453 49.2671 79.8947 48.5231 81.3C47.8204 82.7053 47.1384 83.6147 46.4771 84.028C45.8158 84.4827 45.0511 84.71 44.1831 84.71ZM64.9342 72C64.3142 72 64.0042 71.7727 64.0042 71.318C64.0042 70.946 64.2729 70.698 64.8102 70.574L65.5542 70.45C66.4222 70.2847 66.9802 70.0367 67.2282 69.706C67.5176 69.334 67.6622 68.714 67.6622 67.846V47.014C67.6622 46.27 67.5382 45.774 67.2902 45.526C67.0836 45.2367 66.6909 45.0507 66.1122 44.968L64.8102 44.782C64.2729 44.7407 64.0042 44.5133 64.0042 44.1C64.0042 43.7693 64.3349 43.542 64.9962 43.418C66.2776 43.2113 67.2489 42.8807 67.9102 42.426C68.6129 41.9713 69.3362 41.4133 70.0802 40.752C70.4522 40.38 70.7622 40.194 71.0102 40.194C71.3822 40.194 71.5682 40.442 71.5682 40.938V43.728C71.5682 44.1 71.6922 44.348 71.9402 44.472C72.2296 44.5547 72.5396 44.4307 72.8702 44.1C74.5236 42.5293 75.9702 41.4547 77.2102 40.876C78.4916 40.2973 79.8349 40.008 81.2402 40.008C83.1002 40.008 84.5882 40.6693 85.7042 41.992C86.8202 43.2733 87.3782 45.1747 87.3782 47.696V67.846C87.3782 68.714 87.5022 69.334 87.7502 69.706C88.0396 70.0367 88.6182 70.264 89.4862 70.388L90.8502 70.574C91.3049 70.6567 91.5322 70.9047 91.5322 71.318C91.5322 71.7727 91.2842 72 90.7882 72H80.3722C79.7936 72 79.5042 71.7727 79.5042 71.318C79.5042 70.9047 79.7316 70.6567 80.1862 70.574L81.0542 70.45C81.9222 70.326 82.4802 70.078 82.7282 69.706C83.0176 69.334 83.1622 68.714 83.1622 67.846V48.378C83.1622 46.3527 82.7902 44.9267 82.0462 44.1C81.3022 43.2733 80.2482 42.86 78.8842 42.86C77.5616 42.86 76.3629 43.2527 75.2882 44.038C74.2549 44.782 73.4282 45.7947 72.8082 47.076C72.1882 48.316 71.8782 49.7007 71.8782 51.23V67.846C71.8782 68.714 72.0022 69.334 72.2502 69.706C72.5396 70.078 73.1182 70.3053 73.9862 70.388L75.6602 70.574C76.1149 70.6567 76.3422 70.884 76.3422 71.256C76.3422 71.752 76.0322 72 75.4122 72H64.9342Z\" fill=\"white\"/>\n<defs>\n<radialGradient id=\"paint0_radial_21_11\" cx=\"0\" cy=\"0\" r=\"1\" gradientUnits=\"userSpaceOnUse\" gradientTransform=\"translate(14 16) rotate(43.5498) scale(167.638 156.2)\">\n<stop stop-color=\"#2C5DB8\"/>\n<stop offset=\"1\" stop-color=\"#04081A\"/>\n</radialGradient>\n<linearGradient id=\"paint1_linear_21_11\" x1=\"1.77511\" y1=\"1.50277e-06\" x2=\"105.225\" y2=\"107\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#5C8FE6\"/>\n<stop offset=\"1\" stop-color=\"#335080\"/>\n</linearGradient>\n</defs>\n</svg>\n","// Writes hook scripts into <project>/.claude/hooks/ and registers them in\n// <project>/.claude/settings.local.json. Idempotent — re-running `syn .`\n// regenerates the scripts and merges hook entries cleanly with any user-added\n// hooks already in the file.\n\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport { log } from \"../shared/logger.js\";\nimport type { SynthraPaths } from \"../shared/paths.js\";\n\nimport preCompactPs1 from \"./scripts/pre-compact.ps1\";\nimport preCompactSh from \"./scripts/pre-compact.sh\";\nimport preToolUsePs1 from \"./scripts/pre-tool-use.ps1\";\nimport preToolUseSh from \"./scripts/pre-tool-use.sh\";\nimport primePs1 from \"./scripts/prime.ps1\";\nimport primeSh from \"./scripts/prime.sh\";\nimport stopPs1 from \"./scripts/stop.ps1\";\nimport stopSh from \"./scripts/stop.sh\";\n\nexport interface InstallResult {\n scriptsWritten: string[];\n settingsUpdated: boolean;\n}\n\ninterface ScriptDef {\n /** Hook event name as recognized by Claude Code. */\n event: \"SessionStart\" | \"PreToolUse\" | \"PreCompact\" | \"Stop\";\n /** Tool-name regex for PreToolUse only. */\n matcher?: string;\n /** Base filename written into .claude/hooks/. */\n baseName: string;\n ps1: string;\n sh: string;\n}\n\nconst SCRIPTS: ScriptDef[] = [\n { event: \"SessionStart\", baseName: \"synthra-prime\", ps1: primePs1, sh: primeSh },\n {\n event: \"PreToolUse\",\n matcher: \"Grep|Glob\",\n baseName: \"synthra-pre-tool-use\",\n ps1: preToolUsePs1,\n sh: preToolUseSh,\n },\n { event: \"PreCompact\", baseName: \"synthra-pre-compact\", ps1: preCompactPs1, sh: preCompactSh },\n { event: \"Stop\", baseName: \"synthra-stop\", ps1: stopPs1, sh: stopSh },\n];\n\nconst SYNTHRA_HOOK_MARKER = \"synthra-hook=true\";\n\nfunction commandFor(scriptPath: string): string {\n if (process.platform === \"win32\") {\n // PowerShell on Windows; -ExecutionPolicy Bypass so the script always runs.\n return `powershell.exe -ExecutionPolicy Bypass -NoProfile -File \"${scriptPath}\"`;\n }\n return `bash \"${scriptPath}\"`;\n}\n\nfunction chosenScriptBody(s: ScriptDef): string {\n return process.platform === \"win32\" ? s.ps1 : s.sh;\n}\n\nfunction chosenScriptExt(): string {\n return process.platform === \"win32\" ? \".ps1\" : \".sh\";\n}\n\ninterface HooksConfig {\n hooks?: {\n [event: string]: Array<{\n matcher?: string;\n hooks?: Array<{ type: string; command: string; meta?: string }>;\n }>;\n };\n [k: string]: unknown;\n}\n\nasync function readSettings(path: string): Promise<HooksConfig> {\n try {\n const raw = await readFile(path, \"utf8\");\n return JSON.parse(raw) as HooksConfig;\n } catch {\n return {};\n }\n}\n\nfunction stripOurHooks(config: HooksConfig): HooksConfig {\n if (!config.hooks) return config;\n const next: HooksConfig[\"hooks\"] = {};\n for (const [event, entries] of Object.entries(config.hooks)) {\n const filtered = entries\n .map((entry) => ({\n ...entry,\n hooks: (entry.hooks ?? []).filter((h) => h.meta !== SYNTHRA_HOOK_MARKER),\n }))\n .filter((entry) => (entry.hooks?.length ?? 0) > 0);\n if (filtered.length) next[event] = filtered;\n }\n config.hooks = next;\n return config;\n}\n\nfunction mergeOurHooks(config: HooksConfig, paths: SynthraPaths): HooksConfig {\n const hooks = (config.hooks = config.hooks ?? {});\n for (const s of SCRIPTS) {\n const scriptPath = join(paths.claudeHooksDir, `${s.baseName}${chosenScriptExt()}`);\n const entry = {\n ...(s.matcher ? { matcher: s.matcher } : {}),\n hooks: [\n {\n type: \"command\",\n command: commandFor(scriptPath),\n meta: SYNTHRA_HOOK_MARKER,\n },\n ],\n };\n const list = (hooks[s.event] = hooks[s.event] ?? []);\n list.push(entry);\n }\n return config;\n}\n\nexport async function installHooks(paths: SynthraPaths): Promise<InstallResult> {\n await mkdir(paths.claudeHooksDir, { recursive: true });\n\n const scriptsWritten: string[] = [];\n for (const s of SCRIPTS) {\n const target = join(paths.claudeHooksDir, `${s.baseName}${chosenScriptExt()}`);\n await writeFile(target, chosenScriptBody(s), \"utf8\");\n scriptsWritten.push(target);\n }\n\n await mkdir(dirname(paths.claudeSettings), { recursive: true });\n const existing = await readSettings(paths.claudeSettings);\n const stripped = stripOurHooks(existing);\n const merged = mergeOurHooks(stripped, paths);\n\n await writeFile(paths.claudeSettings, JSON.stringify(merged, null, 2) + \"\\n\", \"utf8\");\n\n log.debug(`installed ${scriptsWritten.length} hook script(s) into ${paths.claudeHooksDir}`);\n\n return { scriptsWritten, settingsUpdated: true };\n}\n","# PreCompact hook — Windows PowerShell.\n# Re-injects the primer after Claude auto-compacts. Same logic as prime.ps1.\n\n$ErrorActionPreference = \"SilentlyContinue\"\n\n$portFile = Join-Path $PWD \".synthra-graph\\mcp_port\"\nif (-not (Test-Path $portFile)) { exit 0 }\n$port = (Get-Content -Path $portFile -Raw).Trim()\nif (-not $port) { exit 0 }\n\ntry {\n $resp = Invoke-RestMethod -Uri \"http://127.0.0.1:$port/prime\" -Method GET -TimeoutSec 3\n if ($resp.primer) { Write-Output $resp.primer }\n} catch {\n # silent\n}\nexit 0\n","#!/usr/bin/env bash\n# PreCompact hook — bash. Re-injects the primer after Claude auto-compacts.\n\nset +e\n\nPORT_FILE=\"$PWD/.synthra-graph/mcp_port\"\nif [ ! -f \"$PORT_FILE\" ]; then exit 0; fi\nPORT=$(cat \"$PORT_FILE\" 2>/dev/null | tr -d '[:space:]')\nif [ -z \"$PORT\" ]; then exit 0; fi\n\n# Parse the primer with jq, not sed. The primer now carries a multi-line \"Since you\n# were last here\" resume digest with quotes and newlines, so the old greedy sed capture\n# (.*\") both over-ran into the trailing \"port\" field and broke on inner quotes. jq -r\n# also decodes JSON escapes, so we print with %s (not %b). No jq → no primer (matches\n# prime.sh / stop.sh — completes the jq migration across all bash hooks).\nif ! command -v jq >/dev/null 2>&1; then exit 0; fi\n\nPRIMER=$(curl -sS --max-time 3 \"http://127.0.0.1:$PORT/prime\" 2>/dev/null \\\n | jq -r '.primer // empty' 2>/dev/null \\\n | head -c 8000)\n\nif [ -n \"$PRIMER\" ]; then\n printf '%s\\n' \"$PRIMER\"\nfi\nexit 0\n","# PreToolUse hook — Windows PowerShell.\n# THE MOAT (improvement #1). Reads the tool call from stdin (JSON), POSTs it\n# to /gate, and if the server says \"block\" emits a JSON deny-decision to\n# stdout. Claude Code reads stdout JSON to enforce the decision.\n# Always exits 0; failure-to-reach-server leaves Claude untouched.\n\n$ErrorActionPreference = \"SilentlyContinue\"\n\n$raw = [Console]::In.ReadToEnd()\nif (-not $raw) { exit 0 }\n\ntry {\n $hookInput = $raw | ConvertFrom-Json -ErrorAction Stop\n} catch {\n exit 0\n}\n\n$portFile = Join-Path $PWD \".synthra-graph\\mcp_port\"\nif (-not (Test-Path $portFile)) { exit 0 }\n$port = (Get-Content -Path $portFile -Raw).Trim()\nif (-not $port) { exit 0 }\n\n$payload = @{\n tool_name = $hookInput.tool_name\n tool_input = $hookInput.tool_input\n} | ConvertTo-Json -Depth 10 -Compress\n\ntry {\n $resp = Invoke-RestMethod -Uri \"http://127.0.0.1:$port/gate\" -Method POST `\n -Body $payload -ContentType \"application/json\" -TimeoutSec 3\n} catch {\n exit 0\n}\n\nif ($resp.decision -eq \"block\") {\n $denyJson = @{\n hookSpecificOutput = @{\n hookEventName = \"PreToolUse\"\n permissionDecision = \"deny\"\n permissionDecisionReason = $resp.reason\n }\n } | ConvertTo-Json -Depth 5 -Compress\n Write-Output $denyJson\n}\nexit 0\n","#!/usr/bin/env bash\r\n# PreToolUse hook — bash. POSTs the tool call to /gate; if server returns\r\n# \"block\", emits the deny-decision JSON to stdout for Claude Code to enforce.\r\n# Always exits 0; server failures leave Claude untouched.\r\n# Requires `jq` to read the gate response; falls back to silent no-op (no\r\n# enforcement) if absent — same policy as the Stop/Prime hooks.\r\n\r\nset +e\r\n\r\nPORT_FILE=\"$PWD/.synthra-graph/mcp_port\"\r\nif [ ! -f \"$PORT_FILE\" ]; then exit 0; fi\r\nPORT=$(cat \"$PORT_FILE\" 2>/dev/null | tr -d '[:space:]')\r\nif [ -z \"$PORT\" ]; then exit 0; fi\r\n\r\nINPUT=$(cat 2>/dev/null)\r\nif [ -z \"$INPUT\" ]; then exit 0; fi\r\n\r\nRESP=$(curl -sS --max-time 3 -X POST -H \"Content-Type: application/json\" \\\r\n --data \"$INPUT\" \"http://127.0.0.1:$PORT/gate\" 2>/dev/null)\r\n\r\n# Parse the gate response with jq, not a greedy sed capture. The block `reason`\r\n# legitimately contains double quotes (it quotes the query, e.g. \"login\"), so the\r\n# old sed capture (\\(.*\\)\") both over-ran into the trailing JSON fields and, once\r\n# embedded raw in the heredoc, produced invalid hook output. jq reads each field\r\n# and re-emits the deny object with correct escaping. (matches stop.sh / prime.sh,\r\n# jq fix #1.) No jq → no enforcement; bail silently like the other hooks.\r\nif ! command -v jq >/dev/null 2>&1; then exit 0; fi\r\n\r\nDECISION=$(printf '%s' \"$RESP\" | jq -r '.decision // empty' 2>/dev/null)\r\nif [ \"$DECISION\" = \"block\" ]; then\r\n REASON=$(printf '%s' \"$RESP\" | jq -r '.reason // empty' 2>/dev/null)\r\n jq -nc --arg r \"$REASON\" \\\r\n '{hookSpecificOutput:{hookEventName:\"PreToolUse\",permissionDecision:\"deny\",permissionDecisionReason:$r}}'\r\nfi\r\nexit 0\r\n","# SessionStart + PreCompact hook — Windows PowerShell.\n# Reads .synthra-graph/mcp_port, calls GET /prime, prints the primer to stdout\n# (Claude Code appends stdout to the session's system prompt). Always exits 0;\n# any failure leaves Claude with the prompt it would have gotten without Synthra.\n\n$ErrorActionPreference = \"SilentlyContinue\"\n\n$portFile = Join-Path $PWD \".synthra-graph\\mcp_port\"\nif (-not (Test-Path $portFile)) { exit 0 }\n$port = (Get-Content -Path $portFile -Raw).Trim()\nif (-not $port) { exit 0 }\n\ntry {\n $resp = Invoke-RestMethod -Uri \"http://127.0.0.1:$port/prime\" -Method GET -TimeoutSec 3\n if ($resp.primer) { Write-Output $resp.primer }\n} catch {\n # silent on failure — Claude continues without the primer\n}\nexit 0\n","#!/usr/bin/env bash\n# SessionStart + PreCompact hook — bash.\n# Reads .synthra-graph/mcp_port, calls GET /prime, prints the primer to stdout.\n# Always exits 0; any failure leaves Claude with the prompt it would have had\n# without Synthra.\n\nset +e\n\nPORT_FILE=\"$PWD/.synthra-graph/mcp_port\"\nif [ ! -f \"$PORT_FILE\" ]; then exit 0; fi\nPORT=$(cat \"$PORT_FILE\" 2>/dev/null | tr -d '[:space:]')\nif [ -z \"$PORT\" ]; then exit 0; fi\n\n# Parse the primer with jq, not sed. Primer text legitimately contains quotes, so a\n# negated-class capture ([^\"]*) would truncate it at the first inner quote, while the\n# old greedy capture (.*\") over-ran into the trailing \"port\" field and injected junk.\n# jq -r also decodes JSON escapes, so we print with %s (not %b). No jq → no primer.\nif ! command -v jq >/dev/null 2>&1; then exit 0; fi\n\nPRIMER=$(curl -sS --max-time 3 \"http://127.0.0.1:$PORT/prime\" 2>/dev/null \\\n | jq -r '.primer // empty' 2>/dev/null \\\n | head -c 8000)\n\nif [ -n \"$PRIMER\" ]; then\n printf '%s\\n' \"$PRIMER\"\nfi\nexit 0\n","# Stop hook — Windows PowerShell.\r\n# Reads Claude's transcript JSONL from $hookInput.transcript_path, sums\r\n# usage.* token counts across all assistant turns since the last offset, and\r\n# POSTs the totals to /log. Uses a per-transcript .stopoffset file to avoid\r\n# double-counting on session resume.\r\n\r\n$ErrorActionPreference = \"SilentlyContinue\"\r\n\r\n$raw = [Console]::In.ReadToEnd()\r\nif (-not $raw) { exit 0 }\r\ntry { $hookInput = $raw | ConvertFrom-Json -ErrorAction Stop } catch { exit 0 }\r\n\r\n$transcript = $hookInput.transcript_path\r\nif (-not $transcript -or -not (Test-Path $transcript)) { exit 0 }\r\n\r\n$portFile = Join-Path $PWD \".synthra-graph\\mcp_port\"\r\nif (-not (Test-Path $portFile)) { exit 0 }\r\n$port = (Get-Content -Path $portFile -Raw).Trim()\r\nif (-not $port) { exit 0 }\r\n\r\n$offsetFile = \"$transcript.stopoffset\"\r\n$startOffset = 0\r\nif (Test-Path $offsetFile) {\r\n $val = (Get-Content -Path $offsetFile -Raw).Trim()\r\n if ($val -match '^\\d+$') { $startOffset = [int]$val }\r\n}\r\n\r\n$lines = Get-Content -Path $transcript\r\n$inT = 0; $outT = 0; $cc = 0; $cr = 0; $model = \"\"\r\n$lineNum = 0\r\nforeach ($line in $lines) {\r\n $lineNum++\r\n if ($lineNum -le $startOffset) { continue }\r\n if (-not $line) { continue }\r\n try { $e = $line | ConvertFrom-Json -ErrorAction Stop } catch { continue }\r\n $usage = $e.message.usage\r\n if (-not $usage) { continue }\r\n $inT += [int]($usage.input_tokens | ForEach-Object { if ($_) { $_ } else { 0 } })\r\n $outT += [int]($usage.output_tokens | ForEach-Object { if ($_) { $_ } else { 0 } })\r\n $cc += [int]($usage.cache_creation_input_tokens | ForEach-Object { if ($_) { $_ } else { 0 } })\r\n $cr += [int]($usage.cache_read_input_tokens | ForEach-Object { if ($_) { $_ } else { 0 } })\r\n if ($e.message.model) { $model = $e.message.model }\r\n}\r\n\r\nSet-Content -Path $offsetFile -Value $lineNum -Encoding ASCII\r\n\r\nif ($inT -eq 0 -and $outT -eq 0) { exit 0 }\r\n\r\n$payload = @{\r\n input_tokens = $inT\r\n output_tokens = $outT\r\n cache_creation_input_tokens = $cc\r\n cache_read_input_tokens = $cr\r\n model = $model\r\n description = \"synthra-stop-hook\"\r\n project = $PWD.Path\r\n} | ConvertTo-Json -Compress\r\n\r\ntry {\r\n Invoke-RestMethod -Uri \"http://127.0.0.1:$port/log\" -Method POST `\r\n -Body $payload -ContentType \"application/json\" -TimeoutSec 3 | Out-Null\r\n} catch {\r\n # silent\r\n}\r\n\r\n# Refresh CONTEXT.md from the branch-scoped store.\r\n$ctxPayload = @{ transcript_path = $transcript } | ConvertTo-Json -Compress\r\ntry {\r\n Invoke-RestMethod -Uri \"http://127.0.0.1:$port/context-update\" -Method POST `\r\n -Body $ctxPayload -ContentType \"application/json\" -TimeoutSec 3 | Out-Null\r\n} catch {\r\n # silent\r\n}\r\nexit 0\r\n","#!/usr/bin/env bash\r\n# Stop hook — bash. Reads transcript JSONL, sums usage.* across new lines,\r\n# POSTs totals to /log. Uses a .stopoffset file to avoid double-counting.\r\n# Requires `jq` for robust JSON parsing; falls back to silent no-op if absent.\r\n\r\nset +e\r\n\r\nINPUT=$(cat 2>/dev/null)\r\nif [ -z \"$INPUT\" ]; then exit 0; fi\r\n\r\n# jq is required for the parsing below — bail early (silent no-op) if it's absent.\r\nif ! command -v jq >/dev/null 2>&1; then exit 0; fi\r\n\r\n# Extract transcript_path with jq, not sed. A greedy sed capture (\\(.*\\)\") grabs the\r\n# trailing JSON fields after transcript_path and yields a path that doesn't exist, so\r\n# the -f check below always failed and totals were never POSTed to /log. (issue #1)\r\nTRANSCRIPT=$(printf '%s' \"$INPUT\" | jq -r '.transcript_path // empty' 2>/dev/null)\r\nif [ -z \"$TRANSCRIPT\" ] || [ ! -f \"$TRANSCRIPT\" ]; then exit 0; fi\r\n\r\nPORT_FILE=\"$PWD/.synthra-graph/mcp_port\"\r\nif [ ! -f \"$PORT_FILE\" ]; then exit 0; fi\r\nPORT=$(cat \"$PORT_FILE\" 2>/dev/null | tr -d '[:space:]')\r\nif [ -z \"$PORT\" ]; then exit 0; fi\r\n\r\nOFFSET_FILE=\"${TRANSCRIPT}.stopoffset\"\r\nSTART_OFFSET=0\r\nif [ -f \"$OFFSET_FILE\" ]; then\r\n START_OFFSET=$(cat \"$OFFSET_FILE\" 2>/dev/null | tr -d '[:space:]')\r\n case \"$START_OFFSET\" in ''|*[!0-9]*) START_OFFSET=0 ;; esac\r\nfi\r\n\r\nTOTAL_LINES=$(wc -l < \"$TRANSCRIPT\" 2>/dev/null | tr -d ' ')\r\nTOTAL_LINES=${TOTAL_LINES:-0}\r\n\r\nif [ \"$TOTAL_LINES\" -le \"$START_OFFSET\" ]; then exit 0; fi\r\n\r\nUSAGE=$(tail -n +$((START_OFFSET + 1)) \"$TRANSCRIPT\" 2>/dev/null \\\r\n | jq -s '\r\n map(select(.message.usage != null) | .message)\r\n | reduce .[] as $m (\r\n {in:0, out:0, cc:0, cr:0, model:\"\"};\r\n .in += ($m.usage.input_tokens // 0)\r\n | .out += ($m.usage.output_tokens // 0)\r\n | .cc += ($m.usage.cache_creation_input_tokens // 0)\r\n | .cr += ($m.usage.cache_read_input_tokens // 0)\r\n | .model = ($m.model // .model)\r\n )\r\n ' 2>/dev/null)\r\n\r\nprintf '%s' \"$TOTAL_LINES\" > \"$OFFSET_FILE\"\r\n\r\nIN=$(printf '%s' \"$USAGE\" | jq -r '.in // 0')\r\nOUT=$(printf '%s' \"$USAGE\" | jq -r '.out // 0')\r\nCC=$(printf '%s' \"$USAGE\" | jq -r '.cc // 0')\r\nCR=$(printf '%s' \"$USAGE\" | jq -r '.cr // 0')\r\nMODEL=$(printf '%s' \"$USAGE\" | jq -r '.model // \"\"')\r\n\r\nif [ \"$IN\" = \"0\" ] && [ \"$OUT\" = \"0\" ]; then exit 0; fi\r\n\r\ncurl -sS --max-time 3 -X POST -H \"Content-Type: application/json\" \\\r\n --data \"$(jq -nc --argjson i \"$IN\" --argjson o \"$OUT\" --argjson cc \"$CC\" --argjson cr \"$CR\" --arg m \"$MODEL\" --arg p \"$PWD\" \\\r\n '{input_tokens:$i, output_tokens:$o, cache_creation_input_tokens:$cc, cache_read_input_tokens:$cr, model:$m, description:\"synthra-stop-hook\", project:$p}')\" \\\r\n \"http://127.0.0.1:$PORT/log\" >/dev/null 2>&1\r\n\r\n# Refresh CONTEXT.md from the branch-scoped store.\r\ncurl -sS --max-time 3 -X POST -H \"Content-Type: application/json\" \\\r\n --data \"$(jq -nc --arg t \"$TRANSCRIPT\" '{transcript_path:$t}')\" \\\r\n \"http://127.0.0.1:$PORT/context-update\" >/dev/null 2>&1\r\n\r\nexit 0\r\n","// HTTP server (Hono). Hosts the routes hooks need (/prime, /pack, /log,\n// /gate, /activity) and serves the loaded graph from memory. The MCP-protocol\n// envelope (/mcp endpoint, JSON-RPC) is wired in M3.\n\nimport { serve } from \"@hono/node-server\";\nimport { Hono } from \"hono\";\nimport { writeFile } from \"node:fs/promises\";\n\nimport { ActivityStore } from \"../activity/activity-log.js\";\nimport { createFileWatcher, type FileWatcher } from \"../activity/file-watcher.js\";\nimport { createGitWatcher, type GitWatcher } from \"../activity/git-watcher.js\";\nimport { scanProject } from \"../cli/scan-command.js\";\nimport { readGraph, readSymbolIndex } from \"../graph/store.js\";\nimport { SCHEMA_VERSION } from \"../graph/types.js\";\nimport { LearnRuntime } from \"../learn/runtime.js\";\nimport { log } from \"../shared/logger.js\";\nimport type { SynthraPaths } from \"../shared/paths.js\";\nimport type { ServerContext } from \"./context.js\";\nimport { handleMcpRequest } from \"./mcp.js\";\nimport { findFreePort } from \"./port.js\";\nimport { handleActivity } from \"./routes/activity.js\";\nimport { handleContextUpdate } from \"./routes/context-update.js\";\nimport { handleGate } from \"./routes/gate.js\";\nimport { handleLog } from \"./routes/log.js\";\nimport { handlePack } from \"./routes/pack.js\";\nimport { handlePrime } from \"./routes/prime.js\";\n\nexport interface ServerHandle {\n port: number;\n url: string;\n stop(): Promise<void>;\n}\n\nexport interface StartOptions {\n /** Override the port range search. */\n port?: number;\n}\n\nasync function loadContext(paths: SynthraPaths): Promise<ServerContext> {\n try {\n let [graph, symbolIndex] = await Promise.all([\n readGraph(paths.infoGraph),\n readSymbolIndex(paths.symbolIndex),\n ]);\n // Schema-migration check (#8): a graph written by an older Synthra may have\n // an incompatible on-disk shape. On a version mismatch, auto-rescan once and\n // reload, rather than serving a stale/incompatible graph.\n if (graph.schema_version !== SCHEMA_VERSION) {\n log.info(`graph schema v${graph.schema_version} ≠ current v${SCHEMA_VERSION} — rescanning…`);\n await scanProject(paths.projectRoot, { silent: true });\n [graph, symbolIndex] = await Promise.all([\n readGraph(paths.infoGraph),\n readSymbolIndex(paths.symbolIndex),\n ]);\n }\n const activity = new ActivityStore(paths.activityLog);\n // Usage-learning runtime: loads the decayed aggregate (replaying the raw\n // access log if the aggregate is cold). Best-effort — never blocks startup.\n const learn = await LearnRuntime.load(paths.accessLog, paths.learnStore);\n return { paths, graph, symbolIndex, activity, learn };\n } catch (err) {\n throw new Error(\n `failed to load graph from ${paths.infoGraph}: ${(err as Error).message}. ` +\n `Run \\`syn scan\\` first.`,\n );\n }\n}\n\nfunction buildApp(ctx: ServerContext, port: number): Hono {\n const app = new Hono();\n\n app.get(\"/\", (c) =>\n c.json({\n service: \"synthra\",\n version: \"0.0.1\",\n port,\n file_count: ctx.graph.file_count,\n symbol_count: ctx.graph.symbol_count,\n generated_at: ctx.graph.generated_at,\n }),\n );\n\n app.get(\"/health\", (c) => c.json({ ok: true }));\n\n app.get(\"/prime\", async (c) => c.json(await handlePrime(ctx, port)));\n\n app.post(\"/pack\", async (c) => {\n const body = await c.req.json().catch(() => ({}));\n return c.json(await handlePack(body, ctx));\n });\n\n app.post(\"/log\", async (c) => {\n const body = await c.req.json().catch(() => ({}));\n return c.json(await handleLog(body, ctx));\n });\n\n app.post(\"/gate\", async (c) => {\n const body = await c.req.json().catch(() => ({}));\n return c.json(await handleGate(body, ctx));\n });\n\n app.get(\"/activity\", async (c) => {\n const sinceParam = c.req.query(\"since\");\n const sinceMs = sinceParam ? Number(sinceParam) : undefined;\n return c.json(await handleActivity(Number.isFinite(sinceMs) ? sinceMs : undefined, ctx));\n });\n\n app.post(\"/context-update\", async (c) => {\n const body = await c.req.json().catch(() => ({}));\n return c.json(await handleContextUpdate(body, ctx));\n });\n\n app.post(\"/mcp\", async (c) => {\n const body = await c.req.json().catch(() => null);\n return c.json(await handleMcpRequest(body, ctx));\n });\n\n app.onError((err, c) => {\n log.error(\"route error:\", err.message);\n return c.json({ error: err.message }, 400);\n });\n\n return app;\n}\n\nexport async function startServer(\n paths: SynthraPaths,\n options: StartOptions = {},\n): Promise<ServerHandle> {\n const ctx = await loadContext(paths);\n const port = options.port ?? (await findFreePort());\n\n const app = buildApp(ctx, port);\n const nodeServer = serve({ fetch: app.fetch, port, hostname: \"127.0.0.1\" });\n\n await writeFile(paths.mcpPort, String(port), \"utf8\");\n\n // Spin up the human-activity watchers. Both are best-effort — if chokidar\n // can't watch (e.g. unsupported FS) or .git is missing, they no-op silently.\n const fileWatcher: FileWatcher = createFileWatcher(paths.projectRoot, (e) => ctx.activity.add(e));\n const gitWatcher: GitWatcher = createGitWatcher(paths.projectRoot, async (e) => {\n await ctx.activity.add(e);\n // Per-branch graph: rebuild on branch switch so the in-memory graph\n // matches whichever branch is currently checked out.\n if (e.kind === \"branch-switch\") {\n try {\n const to = (e.details as { to?: string } | undefined)?.to ?? \"unknown\";\n log.info(`branch switched to '${to}' — rebuilding graph…`);\n await scanProject(paths.projectRoot, { silent: true });\n const [g, idx] = await Promise.all([\n readGraph(paths.infoGraph),\n readSymbolIndex(paths.symbolIndex),\n ]);\n ctx.graph = g;\n ctx.symbolIndex = idx;\n log.info(`graph rebuilt for '${to}' (${g.symbol_count} symbols).`);\n } catch (err) {\n log.warn(`branch rescan failed: ${(err as Error).message}`);\n }\n }\n });\n try {\n await fileWatcher.start();\n } catch (err) {\n log.warn(`file watcher failed to start: ${(err as Error).message}`);\n }\n try {\n await gitWatcher.start();\n } catch (err) {\n log.warn(`git watcher failed to start: ${(err as Error).message}`);\n }\n\n const url = `http://127.0.0.1:${port}`;\n\n return {\n port,\n url,\n async stop() {\n await fileWatcher.stop().catch(() => undefined);\n await gitWatcher.stop().catch(() => undefined);\n // Persist any pending usage signal before we go down.\n await ctx.learn?.flush().catch(() => undefined);\n await new Promise<void>((resolve, reject) => {\n nodeServer.close((err) => (err ? reject(err) : resolve()));\n });\n },\n };\n}\n","// Rolling JSONL log of human activity, written to .synthra-graph/activity.jsonl.\n// In-memory ring buffer for fast queries; disk append for durability.\n//\n// The buffer is bounded (defaults to 100 events) so we don't unbounded-grow\n// memory in long sessions. Disk gets every event so the dashboard / future\n// audit tooling can replay history.\n\nimport { appendFile, mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nexport interface FileEvent {\n kind: \"save\" | \"create\" | \"delete\";\n path: string;\n ts: string;\n}\n\nexport interface GitEvent {\n kind: \"branch-switch\" | \"stage\" | \"unstage\" | \"diff-change\";\n details: Record<string, unknown>;\n ts: string;\n}\n\nexport type ActivityEvent = FileEvent | GitEvent;\n\nconst DEFAULT_RING_SIZE = 100;\n\nexport class ActivityStore {\n private ring: ActivityEvent[] = [];\n private readonly maxRingSize: number;\n private readonly persistPath: string;\n\n constructor(persistPath: string, maxRingSize = DEFAULT_RING_SIZE) {\n this.persistPath = persistPath;\n this.maxRingSize = maxRingSize;\n }\n\n async add(event: ActivityEvent): Promise<void> {\n this.ring.push(event);\n while (this.ring.length > this.maxRingSize) this.ring.shift();\n await this.persist(event);\n }\n\n /** Get events newer than `sinceMs` (epoch ms). If omitted, returns the full ring. */\n getEvents(sinceMs?: number): ActivityEvent[] {\n if (!sinceMs || !Number.isFinite(sinceMs)) return this.ring.slice();\n const cutoff = new Date(sinceMs).toISOString();\n return this.ring.filter((e) => e.ts >= cutoff);\n }\n\n /** Project-relative file paths that have a save/create event newer than `maxAgeMs` ms ago. */\n recentFilePaths(maxAgeMs: number): string[] {\n const cutoff = new Date(Date.now() - maxAgeMs).toISOString();\n const out = new Set<string>();\n for (const e of this.ring) {\n if (\"path\" in e && (e.kind === \"save\" || e.kind === \"create\") && e.ts >= cutoff) {\n out.add(e.path);\n }\n }\n return Array.from(out);\n }\n\n size(): number {\n return this.ring.length;\n }\n\n private async persist(event: ActivityEvent): Promise<void> {\n try {\n await mkdir(dirname(this.persistPath), { recursive: true });\n await appendFile(this.persistPath, JSON.stringify(event) + \"\\n\", \"utf8\");\n } catch {\n // Durability is best-effort; an unwritable disk shouldn't crash the server.\n }\n }\n}\n","// chokidar-based file watcher. Emits save/create/delete events for human\n// edits inside the project. Respects .gitignore + .synthraignore plus a\n// hard-coded list of always-ignored directories (.git, .synthra*, .claude,\n// node_modules, dist, build, coverage).\n\nimport chokidar, { type FSWatcher } from \"chokidar\";\nimport { readFile } from \"node:fs/promises\";\nimport { join, relative, sep } from \"node:path\";\nimport ignore, { type Ignore } from \"ignore\";\n\nimport { log } from \"../shared/logger.js\";\nimport type { FileEvent } from \"./activity-log.js\";\n\nconst ALWAYS_IGNORE = [\n \".git\",\n \".synthra\",\n \".synthra-graph\",\n \".claude\",\n \"node_modules\",\n \"dist\",\n \"build\",\n \"out\",\n \"coverage\",\n \".next\",\n \".nuxt\",\n \".svelte-kit\",\n \".turbo\",\n \".cache\",\n \".vscode\",\n \".idea\",\n];\n\nexport interface FileWatcher {\n start(): Promise<void>;\n stop(): Promise<void>;\n}\n\nexport type FileEventHandler = (e: FileEvent) => void | Promise<void>;\n\nasync function readIgnoreFile(path: string): Promise<string[]> {\n try {\n const text = await readFile(path, \"utf8\");\n return text\n .split(/\\r?\\n/)\n .map((l) => l.trim())\n .filter((l) => l.length > 0 && !l.startsWith(\"#\"));\n } catch {\n return [];\n }\n}\n\nasync function buildMatcher(root: string): Promise<Ignore> {\n const ig = ignore();\n ig.add(ALWAYS_IGNORE.map((d) => `${d}/`));\n ig.add(await readIgnoreFile(join(root, \".gitignore\")));\n ig.add(await readIgnoreFile(join(root, \".synthraignore\")));\n return ig;\n}\n\nfunction toPosixRel(root: string, abs: string): string {\n const rel = relative(root, abs);\n return sep === \"/\" ? rel : rel.split(sep).join(\"/\");\n}\n\nexport function createFileWatcher(root: string, onEvent: FileEventHandler): FileWatcher {\n let watcher: FSWatcher | null = null;\n let ig: Ignore | null = null;\n\n const emit = async (kind: FileEvent[\"kind\"], abs: string) => {\n if (!ig) return;\n const rel = toPosixRel(root, abs);\n if (!rel || rel.startsWith(\"..\")) return;\n if (ig.ignores(rel)) return;\n try {\n await onEvent({ kind, path: rel, ts: new Date().toISOString() });\n } catch {\n // swallow handler errors — watcher must keep going\n }\n };\n\n return {\n async start() {\n ig = await buildMatcher(root);\n watcher = chokidar.watch(root, {\n // Cross-platform glob ignore. We match both the directory itself and\n // anything inside it. picomatch (chokidar's matcher) normalizes path\n // separators so a single set of forward-slash globs handles\n // Windows + POSIX. Function-based ignore was unreliable on Windows\n // and let chokidar descend into .git/, which crashed on transient\n // index.lock files held exclusively by git.\n ignored: ALWAYS_IGNORE.flatMap((d) => [`**/${d}`, `**/${d}/**`]),\n ignoreInitial: true,\n persistent: true,\n awaitWriteFinish: { stabilityThreshold: 150, pollInterval: 50 },\n });\n\n // Chokidar emits \"error\" for transient OS-level issues — most commonly\n // EPERM/ENOENT on rapidly created+deleted files. We never want one of\n // these to crash the syn process. Log + swallow.\n watcher.on(\"error\", (err) => {\n const e = err as NodeJS.ErrnoException;\n log.debug(`file watcher error (swallowed): ${e?.code ?? \"\"} ${e?.message ?? String(err)}`);\n });\n\n watcher.on(\"add\", (path) => emit(\"create\", path));\n watcher.on(\"change\", (path) => emit(\"save\", path));\n watcher.on(\"unlink\", (path) => emit(\"delete\", path));\n },\n\n async stop() {\n if (watcher) {\n await watcher.close();\n watcher = null;\n }\n },\n };\n}\n","// Watches `.git/HEAD` for branch switches (via fs.watch) and polls\n// `git status --porcelain` every ~2s to surface uncommitted-diff changes.\n// Always best-effort: in a non-git directory or when git is missing, the\n// watcher simply emits nothing.\n\nimport { execFile } from \"node:child_process\";\nimport { watch, type FSWatcher } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nimport type { GitEvent } from \"./activity-log.js\";\n\nconst execFileAsync = promisify(execFile);\n\nconst POLL_MS = 2000;\n\nexport interface GitWatcher {\n start(): Promise<void>;\n stop(): Promise<void>;\n}\n\nexport type GitEventHandler = (e: GitEvent) => void | Promise<void>;\n\nasync function readHeadBranch(projectRoot: string): Promise<string | null> {\n try {\n const head = await readFile(join(projectRoot, \".git\", \"HEAD\"), \"utf8\");\n const m = head.trim().match(/^ref:\\s+refs\\/heads\\/(.+)$/);\n return m?.[1] ?? null;\n } catch {\n return null;\n }\n}\n\nasync function readStatusPorcelain(projectRoot: string): Promise<string | null> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"status\", \"--porcelain\"], {\n cwd: projectRoot,\n });\n return stdout;\n } catch {\n return null;\n }\n}\n\nexport function createGitWatcher(root: string, onEvent: GitEventHandler): GitWatcher {\n let headWatcher: FSWatcher | null = null;\n let pollTimer: NodeJS.Timeout | null = null;\n let lastBranch: string | null = null;\n let lastStatus: string | null = null;\n\n const emitSafe = async (event: GitEvent) => {\n try {\n await onEvent(event);\n } catch {\n // swallow\n }\n };\n\n const checkHead = async () => {\n const branch = await readHeadBranch(root);\n if (branch && branch !== lastBranch) {\n const prev = lastBranch;\n lastBranch = branch;\n if (prev !== null) {\n await emitSafe({\n kind: \"branch-switch\",\n details: { from: prev, to: branch },\n ts: new Date().toISOString(),\n });\n }\n }\n };\n\n const pollStatus = async () => {\n const status = await readStatusPorcelain(root);\n if (status === null) return;\n if (lastStatus !== null && status !== lastStatus) {\n const prevFiles = parseStatusFiles(lastStatus);\n const nowFiles = parseStatusFiles(status);\n const added = nowFiles.filter((f) => !prevFiles.includes(f));\n const removed = prevFiles.filter((f) => !nowFiles.includes(f));\n await emitSafe({\n kind: \"diff-change\",\n details: {\n changed_count: nowFiles.length,\n newly_dirty: added,\n newly_clean: removed,\n },\n ts: new Date().toISOString(),\n });\n }\n lastStatus = status;\n };\n\n return {\n async start() {\n // Seed initial branch + status so the first real change emits an event\n // rather than a stale \"from null\".\n lastBranch = await readHeadBranch(root);\n lastStatus = await readStatusPorcelain(root);\n\n try {\n headWatcher = watch(join(root, \".git\", \"HEAD\"), () => {\n void checkHead();\n });\n // fs.watch emits \"error\" for transient OS issues (EPERM on lock\n // files, ENOENT when refs get rewritten). Swallow them — we never\n // want a transient FS event to crash the syn process.\n headWatcher.on(\"error\", () => {\n // silent — branch-switch detection is best-effort\n });\n } catch {\n // .git/HEAD not present — silently no-op\n }\n\n pollTimer = setInterval(() => {\n void pollStatus();\n }, POLL_MS);\n pollTimer.unref?.();\n },\n\n async stop() {\n if (headWatcher) {\n headWatcher.close();\n headWatcher = null;\n }\n if (pollTimer) {\n clearInterval(pollTimer);\n pollTimer = null;\n }\n },\n };\n}\n\nfunction parseStatusFiles(porcelain: string): string[] {\n return porcelain\n .split(/\\r?\\n/)\n .map((l) => l.slice(3).trim())\n .filter((l) => l.length > 0);\n}\n","// `syn scan [path]` — bootstrap then walk + parse + write graph.\n// Also invoked by the default `syn .` flow (M3 will chain start-claude after).\n\nimport { resolve } from \"node:path\";\n\nimport { buildGraph, buildSymbolIndex } from \"../scanner/extract.js\";\nimport { incrementalParse, readParseCache, writeParseCache } from \"../scanner/parse-cache.js\";\nimport { walk, type WalkedFile } from \"../scanner/walker.js\";\nimport { writeGraph, writeSymbolIndex } from \"../graph/store.js\";\nimport { log } from \"../shared/logger.js\";\nimport { resolvePaths } from \"../shared/paths.js\";\nimport { bootstrap } from \"./bootstrap.js\";\n\nconst PARSABLE_EXTS = new Set([\n \".ts\",\n \".tsx\",\n \".cts\",\n \".mts\",\n \".js\",\n \".jsx\",\n \".cjs\",\n \".mjs\",\n \".py\",\n \".pyi\",\n \".svelte\",\n \".vue\",\n \".go\",\n \".rs\",\n \".java\",\n \".kt\",\n \".kts\",\n \".php\",\n \".rb\",\n \".c\",\n \".h\",\n \".cpp\",\n \".cc\",\n \".cxx\",\n \".hpp\",\n \".hh\",\n \".hxx\",\n \".dart\",\n \".cs\",\n]);\n\nexport interface ScanResult {\n walked: number;\n parsed: number;\n symbolCount: number;\n edgeCount: number;\n durationMs: number;\n}\n\nexport interface ScanOptions {\n /** Suppress per-step log output (used for branch-switch rescans). */\n silent?: boolean;\n /** Ignore the parse cache and re-parse every file from scratch. */\n full?: boolean;\n}\n\n/**\n * Core scan pipeline — bootstrap + walk + parse + write graph. Importable\n * from anywhere (server, CLI, tests). `scanCommand` is just a logging wrapper\n * around this. Pass `silent: true` to skip the chatty progress output.\n */\nexport async function scanProject(\n projectRootRaw: string,\n opts: ScanOptions = {},\n): Promise<ScanResult> {\n const projectRoot = resolve(projectRootRaw);\n const paths = resolvePaths(projectRoot);\n const start = Date.now();\n const verbose = !opts.silent;\n\n if (verbose) log.info(`scanning ${projectRoot}`);\n\n const boot = await bootstrap(paths);\n if (verbose) {\n if (boot.graphCreated) log.info(\" created .synthra-graph/\");\n if (boot.contextCreated) log.info(\" created .synthra/\");\n if (boot.gitignoreUpdated) log.info(\" updated .gitignore\");\n if (boot.claudeMdCreated) {\n log.info(\" created CLAUDE.md — onboarding skeleton for the agent\");\n log.info(\n \" ↳ fill in Build / Conventions / Decisions (or run /init in Claude to auto-draft)\",\n );\n } else if (boot.claudeMdUpdated) {\n log.info(\" updated CLAUDE.md\");\n }\n }\n\n const walked: WalkedFile[] = [];\n for await (const file of walk(projectRoot)) walked.push(file);\n if (verbose) log.info(` walked ${walked.length} files`);\n\n const parsable = walked.filter((f) => PARSABLE_EXTS.has(f.ext));\n const prevCache = await readParseCache(paths.parseCache);\n const { parsed, cache, reused, reparsed, parseErrors } = await incrementalParse(\n parsable,\n prevCache,\n { full: opts.full },\n );\n if (verbose) {\n log.info(\n ` parsed ${parsed.length} files (${reused} reused · ${reparsed} reparsed` +\n (parseErrors ? `, ${parseErrors} errored` : \"\") +\n `; ${walked.length - parsable.length} non-code skipped)`,\n );\n }\n\n const graph = await buildGraph(projectRoot, parsed);\n const symbolIndex = buildSymbolIndex(graph);\n\n await writeGraph(paths.infoGraph, graph);\n await writeSymbolIndex(paths.symbolIndex, symbolIndex);\n await writeParseCache(paths.parseCache, cache);\n\n if (verbose) {\n log.info(\n ` wrote ${paths.infoGraph} — ${graph.symbol_count} symbols, ${graph.edge_count} edges`,\n );\n log.info(` wrote ${paths.symbolIndex} — ${Object.keys(symbolIndex).length} names`);\n }\n\n const durationMs = Date.now() - start;\n if (verbose) log.info(`done in ${(durationMs / 1000).toFixed(2)}s`);\n\n return {\n walked: walked.length,\n parsed: parsed.length,\n symbolCount: graph.symbol_count,\n edgeCount: graph.edge_count,\n durationMs,\n };\n}\n\n// Thin alias so the CLI command keeps its current name. Drop in v0.2 if we\n// settle on a single public function.\nexport async function scanCommand(rawPath: string, opts: ScanOptions = {}): Promise<ScanResult> {\n return scanProject(rawPath, opts);\n}\n","// Turns ParsedFile[] into a GraphSchema (nodes + edges).\n//\n// Edges produced in M1:\n// defines : file → symbol\n// imports : file → file (when the import target resolves inside the project)\n// tests : test-file → source-file (for foo.test.ts ↔ foo.ts)\n\nimport { dirname, join, posix } from \"node:path\";\n\nimport type { Edge, FileNode, GraphSchema, SymbolIndex, SymbolNode } from \"../graph/types.js\";\nimport { SCHEMA_VERSION } from \"../graph/types.js\";\nimport { fileHash } from \"./hash.js\";\nimport { extractKeywords } from \"./keywords.js\";\nimport type { CallSite, ParsedFile, ParsedSymbol } from \"./parser.js\";\n\nconst RESOLVE_EXTS = [\n \".ts\",\n \".tsx\",\n \".js\",\n \".jsx\",\n \".mjs\",\n \".cjs\",\n \".py\",\n \".svelte\",\n \".vue\",\n \".dart\",\n \".html\",\n \".hubl\",\n];\nconst INDEX_FILES = [\"index.ts\", \"index.tsx\", \"index.js\", \"index.jsx\", \"__init__.py\"];\n\nfunction fileId(relPath: string): string {\n return `file:${relPath}`;\n}\n\nfunction symbolId(relPath: string, sym: ParsedSymbol): string {\n return `symbol:${relPath}::${sym.name}:${sym.startLine}`;\n}\n\nfunction toFileNode(parsed: ParsedFile): FileNode {\n const content = parsed.source;\n return {\n id: fileId(parsed.file.relPath),\n kind: \"file\",\n path: parsed.file.relPath,\n ext: parsed.file.ext,\n size: parsed.file.size,\n keywords: extractKeywords(content, parsed.file.ext),\n content,\n summary: extractSummary(content),\n file_hash: fileHash(content),\n };\n}\n\nfunction extractSummary(content: string): string {\n // First leading comment block (// ... or /** ... */ or # ...), trimmed to ~200 chars.\n const trimmed = content.replace(/^\\s+/, \"\");\n const slashMatch = trimmed.match(/^\\/\\/\\s?(.*(?:\\r?\\n\\/\\/\\s?.*)*)/);\n if (slashMatch?.[1]) return slashMatch[1].split(/\\r?\\n/).join(\" \").trim().slice(0, 200);\n const blockMatch = trimmed.match(/^\\/\\*\\*?([\\s\\S]*?)\\*\\//);\n if (blockMatch?.[1]) {\n return blockMatch[1]\n .split(/\\r?\\n/)\n .map((l) => l.replace(/^\\s*\\*\\s?/, \"\"))\n .join(\" \")\n .trim()\n .slice(0, 200);\n }\n const hashMatch = trimmed.match(/^#\\s?(.*(?:\\r?\\n#\\s?.*)*)/);\n if (hashMatch?.[1]) return hashMatch[1].split(/\\r?\\n/).join(\" \").trim().slice(0, 200);\n return \"\";\n}\n\nfunction toSymbolNode(parsed: ParsedFile, sym: ParsedSymbol): SymbolNode {\n return {\n id: symbolId(parsed.file.relPath, sym),\n kind: \"symbol\",\n symbol_kind: sym.kind,\n name: sym.name,\n file: parsed.file.relPath,\n start_line: sym.startLine,\n end_line: sym.endLine,\n signature: sym.signature,\n };\n}\n\n/**\n * Resolve an import specifier to a project-relative path if it refers to a\n * file inside the project. Returns `null` for external packages (no leading\n * dot) or specifiers that don't match any known file.\n */\n// Strip a trailing JS-family extension so a spec like \"./crypto.js\" can\n// resolve to \"crypto.ts\". TypeScript-style `.js` imports are common.\nconst REWRITE_EXT_RE = /\\.(js|jsx|mjs|cjs)$/;\n\nfunction resolveImport(\n fromRelPath: string,\n spec: string,\n filesByPath: Map<string, true>,\n): string | null {\n if (!spec.startsWith(\".\")) return null;\n const fromDir = posix.dirname(toPosix(fromRelPath));\n const base = posix.normalize(posix.join(fromDir, toPosix(spec)));\n\n const candidates = [base];\n const rewritten = base.replace(REWRITE_EXT_RE, \"\");\n if (rewritten !== base) candidates.push(rewritten);\n\n for (const c of candidates) {\n if (filesByPath.has(c)) return c;\n for (const ext of RESOLVE_EXTS) {\n if (filesByPath.has(c + ext)) return c + ext;\n }\n for (const idx of INDEX_FILES) {\n const candidate = posix.join(c, idx);\n if (filesByPath.has(candidate)) return candidate;\n }\n }\n return null;\n}\n\nfunction toPosix(p: string): string {\n return p.split(/[\\\\/]/).join(\"/\");\n}\n\nconst TEST_RE = /^(?<base>.+?)\\.(test|spec)\\.(?<ext>[tj]sx?|py)$/;\n\nfunction testTarget(relPath: string, filesByPath: Map<string, true>): string | null {\n const fileName = relPath.split(\"/\").pop() ?? relPath;\n const match = TEST_RE.exec(fileName);\n if (!match) return null;\n const dir = relPath.includes(\"/\") ? relPath.slice(0, relPath.lastIndexOf(\"/\") + 1) : \"\";\n const base = match.groups?.base ?? \"\";\n const ext = match.groups?.ext ?? \"\";\n if (!base || !ext) return null;\n const candidate = `${dir}${base}.${ext}`;\n if (filesByPath.has(candidate)) return candidate;\n // Try sibling extensions (e.g. foo.test.ts → foo.tsx)\n for (const e of RESOLVE_EXTS) {\n const alt = `${dir}${base}${e}`;\n if (filesByPath.has(alt)) return alt;\n }\n return null;\n}\n\nexport async function buildGraph(root: string, parsed: ParsedFile[]): Promise<GraphSchema> {\n const filesByPath = new Map<string, true>();\n for (const p of parsed) filesByPath.set(p.file.relPath, true);\n\n const nodes: (FileNode | SymbolNode)[] = [];\n const edges: Edge[] = [];\n\n // Collected during the file loop, then resolved into `calls` edges in one pass\n // (callee resolution needs the full symbol set).\n const symbolsByFile = new Map<string, SymbolNode[]>();\n const callsByFile = new Map<string, CallSite[]>();\n\n for (const p of parsed) {\n const fileNode = toFileNode(p);\n nodes.push(fileNode);\n\n const fileSymNodes: SymbolNode[] = [];\n for (const sym of p.symbols) {\n const symNode = toSymbolNode(p, sym);\n nodes.push(symNode);\n fileSymNodes.push(symNode);\n edges.push({ from: fileNode.id, to: symNode.id, kind: \"defines\" });\n }\n symbolsByFile.set(p.file.relPath, fileSymNodes);\n callsByFile.set(p.file.relPath, p.calls);\n\n const importEdges = new Set<string>();\n for (const spec of p.imports) {\n const target = resolveImport(p.file.relPath, spec, filesByPath);\n if (!target) continue;\n const key = `${fileNode.id}->${fileId(target)}`;\n if (importEdges.has(key)) continue;\n importEdges.add(key);\n edges.push({ from: fileNode.id, to: fileId(target), kind: \"imports\" });\n }\n\n const testTargetPath = testTarget(p.file.relPath, filesByPath);\n if (testTargetPath && testTargetPath !== p.file.relPath) {\n edges.push({ from: fileNode.id, to: fileId(testTargetPath), kind: \"tests\" });\n }\n }\n\n edges.push(...buildCallEdges(symbolsByFile, callsByFile));\n\n const symbolCount = nodes.filter((n) => n.kind === \"symbol\").length;\n const fileCount = nodes.length - symbolCount;\n\n return {\n root,\n node_count: nodes.length,\n edge_count: edges.length,\n file_count: fileCount,\n symbol_count: symbolCount,\n nodes,\n edges,\n generated_at: new Date().toISOString(),\n schema_version: SCHEMA_VERSION,\n };\n}\n\nexport function buildSymbolIndex(graph: GraphSchema): SymbolIndex {\n // Null-prototype map: symbol names like \"toString\" or \"constructor\" (common\n // in Dart, where every class overrides toString) would otherwise resolve to\n // an inherited Object.prototype member and crash on the .push below.\n const out: SymbolIndex = Object.create(null);\n for (const node of graph.nodes) {\n if (node.kind !== \"symbol\") continue;\n const list = out[node.name] ?? (out[node.name] = []);\n list.push({ file: node.file, line: node.start_line, kind: node.symbol_kind });\n }\n return out;\n}\n\n/** The same-file symbol whose [start_line, end_line] tightest-contains `line`\n * (smallest span wins, so an inner method beats its enclosing class). null if\n * the line is outside every symbol (e.g. a module-level call). */\nexport function tightestContainer(syms: SymbolNode[], line: number): SymbolNode | null {\n let best: SymbolNode | null = null;\n for (const s of syms) {\n if (line < s.start_line || line > s.end_line) continue;\n if (!best || s.end_line - s.start_line < best.end_line - best.start_line) best = s;\n }\n return best;\n}\n\n/**\n * Resolve raw call sites into symbol→symbol `calls` edges. Name-based (no type\n * info), precision-first:\n * - caller = the call site's tightest-containing symbol in the SAME file\n * (no container, e.g. a top-level call → skipped)\n * - callee = a same-file symbol of that name, else the UNIQUE repo-wide symbol\n * of that name; 0 matches (external/builtin) or >1 (ambiguous) → skipped\n * Recursion self-edges and duplicates are dropped.\n */\nexport function buildCallEdges(\n symbolsByFile: Map<string, SymbolNode[]>,\n callsByFile: Map<string, CallSite[]>,\n): Edge[] {\n // Repo-wide name → symbols index, for the cross-file fallback.\n const byName = new Map<string, SymbolNode[]>();\n for (const syms of symbolsByFile.values()) {\n for (const s of syms) {\n const list = byName.get(s.name);\n if (list) list.push(s);\n else byName.set(s.name, [s]);\n }\n }\n\n const edges: Edge[] = [];\n const seen = new Set<string>();\n\n for (const [relPath, sites] of callsByFile) {\n const fileSyms = symbolsByFile.get(relPath) ?? [];\n for (const site of sites) {\n const caller = tightestContainer(fileSyms, site.line);\n if (!caller) continue;\n\n let callee = fileSyms.find((s) => s.name === site.callee);\n if (!callee) {\n const cands = byName.get(site.callee) ?? [];\n if (cands.length !== 1) continue; // 0 = external/builtin, >1 = ambiguous\n callee = cands[0];\n }\n if (!callee || callee.id === caller.id) continue; // skip recursion self-edges\n\n const key = `${caller.id}->${callee.id}`;\n if (seen.has(key)) continue;\n seen.add(key);\n edges.push({ from: caller.id, to: callee.id, kind: \"calls\" });\n }\n }\n return edges;\n}\n\n// Re-export node path helpers in case downstream wants the canonical id format\nexport { fileId, symbolId };\n// Suppress unused-import lint for dirname/join from node:path — kept reserved for incremental updates.\nvoid dirname;\nvoid join;\n","// Shared graph schema. Other modules read/write these shapes.\n\nexport type NodeKind = \"file\" | \"symbol\";\n\nexport type SymbolKind =\n | \"function\"\n | \"method\"\n | \"class\"\n | \"interface\"\n | \"type\"\n | \"const\"\n | \"enum\"\n | \"component\";\n\nexport interface FileNode {\n id: string;\n kind: \"file\";\n path: string;\n ext: string;\n size: number;\n keywords: string[];\n content: string;\n summary: string;\n file_hash: string;\n}\n\nexport interface SymbolNode {\n id: string;\n kind: \"symbol\";\n symbol_kind: SymbolKind;\n name: string;\n file: string;\n start_line: number;\n end_line: number;\n signature: string;\n}\n\nexport type GraphNode = FileNode | SymbolNode;\n\nexport type EdgeKind = \"imports\" | \"calls\" | \"defines\" | \"tests\";\n\nexport interface Edge {\n from: string;\n to: string;\n kind: EdgeKind;\n}\n\n// Bump when the on-disk info_graph.json shape changes incompatibly. The server\n// auto-rescans on load when a stored graph's schema_version differs (#8).\n// v2: `calls` edges are now populated.\nexport const SCHEMA_VERSION = 2;\n\nexport interface GraphSchema {\n root: string;\n node_count: number;\n edge_count: number;\n file_count: number;\n symbol_count: number;\n nodes: GraphNode[];\n edges: Edge[];\n generated_at: string;\n schema_version: number;\n}\n\nexport interface SymbolIndex {\n [name: string]: Array<{ file: string; line: number; kind: SymbolKind }>;\n}\n","// Stable, short content hash for files. Used to detect changed files\n// during incremental rescans (post-v0.1; M1 does full re-parse).\n// TODO: M1 (minimal); post-v0.1 (incremental)\n\nimport { createHash } from \"node:crypto\";\n\nexport function fileHash(content: string): string {\n return createHash(\"sha1\").update(content).digest(\"hex\").slice(0, 8);\n}\n","// Per-file keyword extraction. Used for query-time relevance ranking.\n// Tokenizes identifiers + comment words, splits camelCase/snake_case, filters\n// stopwords, and returns the top-N rare tokens scored by inverse frequency\n// against a small built-in english/code corpus.\n\nconst STOPWORDS = new Set([\n \"a\",\n \"an\",\n \"and\",\n \"are\",\n \"as\",\n \"at\",\n \"be\",\n \"but\",\n \"by\",\n \"do\",\n \"for\",\n \"from\",\n \"has\",\n \"have\",\n \"he\",\n \"if\",\n \"in\",\n \"is\",\n \"it\",\n \"its\",\n \"not\",\n \"of\",\n \"on\",\n \"or\",\n \"she\",\n \"that\",\n \"the\",\n \"they\",\n \"this\",\n \"to\",\n \"was\",\n \"we\",\n \"were\",\n \"will\",\n \"with\",\n \"you\",\n \"your\",\n \"i\",\n \"me\",\n \"my\",\n \"our\",\n \"us\",\n \"their\",\n \"them\",\n \"his\",\n \"her\",\n // common code words that add no signal\n \"function\",\n \"const\",\n \"let\",\n \"var\",\n \"class\",\n \"interface\",\n \"type\",\n \"enum\",\n \"import\",\n \"export\",\n \"from\",\n \"default\",\n \"return\",\n \"if\",\n \"else\",\n \"for\",\n \"while\",\n \"do\",\n \"switch\",\n \"case\",\n \"break\",\n \"continue\",\n \"new\",\n \"this\",\n \"super\",\n \"throw\",\n \"try\",\n \"catch\",\n \"finally\",\n \"async\",\n \"await\",\n \"yield\",\n \"true\",\n \"false\",\n \"null\",\n \"undefined\",\n \"void\",\n \"any\",\n \"string\",\n \"number\",\n \"boolean\",\n \"object\",\n \"array\",\n \"self\",\n \"cls\",\n \"def\",\n \"lambda\",\n \"pass\",\n \"raise\",\n \"with\",\n \"as\",\n \"in\",\n \"todo\",\n \"fixme\",\n \"note\",\n]);\n\nconst COMMON_CODE = new Set([\n \"value\",\n \"data\",\n \"result\",\n \"args\",\n \"kwargs\",\n \"options\",\n \"config\",\n \"params\",\n \"name\",\n \"id\",\n \"key\",\n \"index\",\n \"item\",\n \"items\",\n \"list\",\n \"map\",\n \"set\",\n \"get\",\n \"set\",\n \"add\",\n \"remove\",\n \"delete\",\n \"create\",\n \"update\",\n \"find\",\n \"fetch\",\n \"load\",\n \"save\",\n \"init\",\n \"main\",\n \"run\",\n \"start\",\n \"stop\",\n \"test\",\n \"check\",\n \"validate\",\n \"error\",\n \"err\",\n \"warn\",\n \"info\",\n \"debug\",\n \"log\",\n \"trace\",\n \"msg\",\n \"message\",\n \"path\",\n \"file\",\n \"dir\",\n \"url\",\n \"host\",\n \"port\",\n \"size\",\n \"length\",\n \"count\",\n \"input\",\n \"output\",\n \"source\",\n \"target\",\n \"callback\",\n \"handler\",\n \"listener\",\n \"props\",\n \"state\",\n \"context\",\n \"render\",\n \"component\",\n \"node\",\n \"tree\",\n \"root\",\n]);\n\n// Frequency weight — common-code words count for less than rare identifiers\nfunction score(token: string): number {\n if (STOPWORDS.has(token)) return 0;\n if (COMMON_CODE.has(token)) return 0.2;\n if (token.length <= 2) return 0.1;\n return 1;\n}\n\nfunction splitIdentifier(id: string): string[] {\n // snake_case + kebab-case → words\n const partsRaw = id.split(/[_\\-./]+/).filter(Boolean);\n const out: string[] = [];\n for (const part of partsRaw) {\n // camelCase / PascalCase → words. Handles \"XMLHttp\" → [\"XML\", \"Http\"]\n const camelParts = part.match(/[A-Z]+(?=[A-Z][a-z])|[A-Z]?[a-z]+|[A-Z]+|[0-9]+/g);\n if (camelParts) out.push(...camelParts);\n else out.push(part);\n }\n return out.map((w) => w.toLowerCase()).filter((w) => /[a-z]/.test(w));\n}\n\nexport function extractKeywords(content: string, _ext: string): string[] {\n // Identifiers + alphanumeric words. Picks up both code and comment text.\n const tokens = content.match(/[A-Za-z_][A-Za-z0-9_]{1,40}/g) ?? [];\n const counts = new Map<string, number>();\n for (const tok of tokens) {\n for (const word of splitIdentifier(tok)) {\n const w = score(word);\n if (w === 0) continue;\n counts.set(word, (counts.get(word) ?? 0) + w);\n }\n }\n return Array.from(counts.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 32)\n .map(([w]) => w);\n}\n","// Incremental-scan parse cache. Stores per-file parse results keyed by content\n// hash so a rescan can reuse unchanged files' symbols/imports and only re-run\n// the expensive tree-sitter parse on files that actually changed.\n//\n// Source is NOT stored here — it's re-read at scan time to compute the hash and\n// reused as ParsedFile.source, keeping the cache small (the graph holds content\n// separately). Lives in .synthra-graph/ (gitignored, machine-local).\n//\n// BUMP PARSE_CACHE_VERSION whenever parser/extract output shape or a tree-sitter\n// grammar changes — readParseCache returns an empty cache on a version mismatch,\n// forcing a full re-parse so stale symbols can never leak into the graph.\n\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { fileHash } from \"./hash.js\";\nimport { parseSource, type CallSite, type ParsedFile, type ParsedSymbol } from \"./parser.js\";\nimport type { WalkedFile } from \"./walker.js\";\n\n// Bumped to 2 when call sites were added to the parse output (the calls shape\n// changed) — old caches invalidate and re-parse cleanly.\nexport const PARSE_CACHE_VERSION = 2;\n\nexport interface CachedParse {\n hash: string;\n symbols: ParsedSymbol[];\n imports: string[];\n calls: CallSite[];\n}\n\nexport interface ParseCache {\n schema_version: number;\n files: Record<string, CachedParse>;\n}\n\nexport function emptyParseCache(): ParseCache {\n return { schema_version: PARSE_CACHE_VERSION, files: {} };\n}\n\nexport async function readParseCache(path: string): Promise<ParseCache> {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<ParseCache>;\n if (\n parsed.schema_version !== PARSE_CACHE_VERSION ||\n typeof parsed.files !== \"object\" ||\n parsed.files === null\n ) {\n return emptyParseCache();\n }\n return { schema_version: PARSE_CACHE_VERSION, files: parsed.files as ParseCache[\"files\"] };\n } catch {\n return emptyParseCache();\n }\n}\n\nexport async function writeParseCache(path: string, cache: ParseCache): Promise<void> {\n try {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify(cache)}\\n`, \"utf8\");\n } catch {\n // Best-effort: a missing/unwritable cache just means the next scan is full.\n }\n}\n\nexport interface IncrementalParseResult {\n parsed: ParsedFile[];\n cache: ParseCache;\n reused: number;\n reparsed: number;\n parseErrors: number;\n}\n\n/**\n * Parse `parsable` files, reusing prior results for files whose content hash is\n * unchanged. Returns the FULL ParsedFile[] (reused + freshly parsed) — so\n * `buildGraph` re-resolves every cross-file edge exactly as in a full scan —\n * plus a rebuilt cache containing only the currently-present files (deletions\n * and renames drop out naturally). Pass `full: true` to ignore the cache and\n * re-parse everything.\n */\nexport async function incrementalParse(\n parsable: WalkedFile[],\n prev: ParseCache,\n opts: { full?: boolean } = {},\n): Promise<IncrementalParseResult> {\n const cache = emptyParseCache();\n const parsed: ParsedFile[] = [];\n let reused = 0;\n let reparsed = 0;\n let parseErrors = 0;\n\n for (const f of parsable) {\n let source: string;\n try {\n source = await readFile(f.absPath, \"utf8\");\n } catch {\n continue; // unreadable → skip, same as a failed read in parseFile\n }\n const hash = fileHash(source);\n\n const cached = opts.full ? undefined : prev.files[f.relPath];\n if (cached && cached.hash === hash) {\n parsed.push({\n file: f,\n source,\n symbols: cached.symbols,\n imports: cached.imports,\n calls: cached.calls,\n });\n cache.files[f.relPath] = cached;\n reused += 1;\n continue;\n }\n\n try {\n const p = await parseSource(f, source);\n parsed.push(p);\n cache.files[f.relPath] = { hash, symbols: p.symbols, imports: p.imports, calls: p.calls };\n reparsed += 1;\n } catch {\n // Mirror scanProject's prior behavior: a parse failure drops the file\n // from the graph (and the cache) rather than failing the whole scan.\n parseErrors += 1;\n }\n }\n\n return { parsed, cache, reused, reparsed, parseErrors };\n}\n","// Dispatches a file to its language-specific parser based on extension.\n// Tree-sitter WASM grammars are loaded lazily via tree-sitter-wasms and\n// cached per language for the lifetime of the process.\n\nimport { readFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { Language, Parser } from \"web-tree-sitter\";\n\nimport type { SymbolKind } from \"../graph/types.js\";\nimport { parseC } from \"./parsers/c.js\";\nimport { parseCpp } from \"./parsers/cpp.js\";\nimport { parseCSharp } from \"./parsers/csharp.js\";\nimport { parseDart } from \"./parsers/dart.js\";\nimport { parseGo } from \"./parsers/go.js\";\nimport { parseHubL } from \"./parsers/hubl.js\";\nimport { parseJava } from \"./parsers/java.js\";\nimport { parseKotlin } from \"./parsers/kotlin.js\";\nimport { parsePhp } from \"./parsers/php.js\";\nimport { parsePython } from \"./parsers/python.js\";\nimport { parseRuby } from \"./parsers/ruby.js\";\nimport { parseRust } from \"./parsers/rust.js\";\nimport { parseSvelte } from \"./parsers/svelte.js\";\nimport { parseTypeScript } from \"./parsers/typescript.js\";\nimport { parseVue } from \"./parsers/vue.js\";\nimport type { WalkedFile } from \"./walker.js\";\n\nexport interface ParsedSymbol {\n name: string;\n kind: SymbolKind;\n startLine: number;\n endLine: number;\n signature: string;\n}\n\n/** A raw call site: the bare callee name as written (e.g. \"login\", not\n * \"auth.login\") + its 1-based line. Caller attribution + callee resolution\n * happen centrally in buildGraph (which has the full file set). */\nexport interface CallSite {\n callee: string;\n line: number;\n}\n\nexport interface ParsedFile {\n file: WalkedFile;\n source: string;\n symbols: ParsedSymbol[];\n imports: string[];\n calls: CallSite[];\n}\n\nconst require = createRequire(import.meta.url);\n\nexport type GrammarName =\n | \"typescript\"\n | \"tsx\"\n | \"javascript\"\n | \"python\"\n | \"go\"\n | \"rust\"\n | \"java\"\n | \"kotlin\"\n | \"php\"\n | \"ruby\"\n | \"c\"\n | \"cpp\"\n | \"dart\"\n | \"csharp\";\n\nconst GRAMMAR_FILES: Record<GrammarName, string> = {\n typescript: \"tree-sitter-wasms/out/tree-sitter-typescript.wasm\",\n tsx: \"tree-sitter-wasms/out/tree-sitter-tsx.wasm\",\n javascript: \"tree-sitter-wasms/out/tree-sitter-javascript.wasm\",\n python: \"tree-sitter-wasms/out/tree-sitter-python.wasm\",\n go: \"tree-sitter-wasms/out/tree-sitter-go.wasm\",\n rust: \"tree-sitter-wasms/out/tree-sitter-rust.wasm\",\n java: \"tree-sitter-wasms/out/tree-sitter-java.wasm\",\n kotlin: \"tree-sitter-wasms/out/tree-sitter-kotlin.wasm\",\n php: \"tree-sitter-wasms/out/tree-sitter-php.wasm\",\n ruby: \"tree-sitter-wasms/out/tree-sitter-ruby.wasm\",\n c: \"tree-sitter-wasms/out/tree-sitter-c.wasm\",\n cpp: \"tree-sitter-wasms/out/tree-sitter-cpp.wasm\",\n dart: \"tree-sitter-wasms/out/tree-sitter-dart.wasm\",\n csharp: \"tree-sitter-wasms/out/tree-sitter-c_sharp.wasm\",\n};\n\nlet parserInit: Promise<void> | null = null;\nconst languageCache = new Map<GrammarName, Language>();\n\nasync function ensureParserInit(): Promise<void> {\n if (!parserInit) {\n parserInit = Parser.init();\n }\n return parserInit;\n}\n\nexport async function loadGrammar(name: GrammarName): Promise<Language> {\n await ensureParserInit();\n const cached = languageCache.get(name);\n if (cached) return cached;\n const wasmPath = require.resolve(GRAMMAR_FILES[name]);\n const lang = await Language.load(wasmPath);\n languageCache.set(name, lang);\n return lang;\n}\n\nexport interface LoadedParser {\n parser: Parser;\n language: Language;\n}\n\nexport async function createParser(name: GrammarName): Promise<LoadedParser> {\n const language = await loadGrammar(name);\n const parser = new Parser();\n parser.setLanguage(language);\n return { parser, language };\n}\n\nfunction emptyParsed(file: WalkedFile, source: string): ParsedFile {\n return { file, source, symbols: [], imports: [], calls: [] };\n}\n\nexport async function parseFile(f: WalkedFile): Promise<ParsedFile> {\n let source: string;\n try {\n source = await readFile(f.absPath, \"utf8\");\n } catch {\n return emptyParsed(f, \"\");\n }\n return parseSource(f, source);\n}\n\n/** Parse already-read source. Split from parseFile so the incremental scanner\n * can read a file's content once (to hash it) and parse from that same string\n * on a cache miss — avoiding a second read. */\nexport async function parseSource(f: WalkedFile, source: string): Promise<ParsedFile> {\n switch (f.ext) {\n case \".ts\":\n case \".tsx\":\n case \".cts\":\n case \".mts\":\n case \".js\":\n case \".jsx\":\n case \".cjs\":\n case \".mjs\":\n return parseTypeScript(f, source);\n case \".py\":\n case \".pyi\":\n return parsePython(f, source);\n case \".svelte\":\n return parseSvelte(f, source);\n case \".vue\":\n return parseVue(f, source);\n case \".html\":\n case \".hubl\":\n return parseHubL(f, source);\n case \".go\":\n return parseGo(f, source);\n case \".rs\":\n return parseRust(f, source);\n case \".java\":\n return parseJava(f, source);\n case \".kt\":\n case \".kts\":\n return parseKotlin(f, source);\n case \".php\":\n return parsePhp(f, source);\n case \".rb\":\n return parseRuby(f, source);\n case \".c\":\n case \".h\":\n return parseC(f, source);\n case \".cpp\":\n case \".cc\":\n case \".cxx\":\n case \".hpp\":\n case \".hh\":\n case \".hxx\":\n return parseCpp(f, source);\n case \".dart\":\n return parseDart(f, source);\n case \".cs\":\n return parseCSharp(f, source);\n default:\n return emptyParsed(f, source);\n }\n}\n","// Generic tree-sitter parser used by the simpler-grammar languages\n// (Go, Rust, Java, Kotlin, PHP, Ruby, C, C++, Dart, C#).\n//\n// Each language file defines:\n// - which tree-sitter grammar to load\n// - a query string with capture names like `@function`, `@function.name`\n// - a `decls` table mapping declaration-capture pairs to SymbolKind\n// - optional `importCapture` for collecting import edges\n// Everything else (parser init, error handling, dedupe) lives here.\n\nimport { Query, type Node } from \"web-tree-sitter\";\n\nimport type { SymbolKind } from \"../../graph/types.js\";\nimport {\n createParser,\n type CallSite,\n type GrammarName,\n type ParsedFile,\n type ParsedSymbol,\n} from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\n\nexport interface DeclCapture {\n /** Capture name for the declaration node, e.g. \"function\". */\n declCapture: string;\n /** Capture name for the symbol's name node, e.g. \"function.name\". */\n nameCapture: string;\n /** SymbolKind to assign. */\n kind: SymbolKind;\n}\n\nexport interface GenericParserConfig {\n grammar: GrammarName;\n query: string;\n decls: DeclCapture[];\n /** Capture name for import-source nodes. Skipped when omitted. */\n importCapture?: string;\n /** Capture name for the whole call-site node (for its line). */\n callCapture?: string;\n /** Capture name for the callee-name node. Both call captures must be set. */\n callCalleeCapture?: string;\n}\n\nexport function firstLine(text: string, max = 200): string {\n const line = text.split(/\\r?\\n/, 1)[0] ?? \"\";\n return line.length > max ? line.slice(0, max) + \"…\" : line;\n}\n\nfunction cleanImport(s: string): string {\n // Strip surrounding string-literal quotes (used by Go, Dart, C/C++).\n // Strip angle brackets used by C/C++ system includes.\n return s.replace(/^[\"'`<]+|[\"'`>]+$/g, \"\").trim();\n}\n\nexport async function runGenericParser(\n config: GenericParserConfig,\n f: WalkedFile,\n source: string,\n): Promise<ParsedFile> {\n let symbols: ParsedSymbol[] = [];\n let imports: string[] = [];\n const calls: CallSite[] = [];\n\n try {\n const { parser, language } = await createParser(config.grammar);\n const tree = parser.parse(source);\n if (!tree) return { file: f, source, symbols, imports, calls };\n\n const query = new Query(language, config.query);\n const matches = query.matches(tree.rootNode);\n\n for (const match of matches) {\n const byName = new Map<string, Node>();\n for (const cap of match.captures) byName.set(cap.name, cap.node);\n\n let matched: DeclCapture | null = null;\n for (const d of config.decls) {\n if (byName.has(d.declCapture) && byName.has(d.nameCapture)) {\n matched = d;\n break;\n }\n }\n\n if (matched) {\n const declNode = byName.get(matched.declCapture)!;\n const nameNode = byName.get(matched.nameCapture)!;\n symbols.push({\n name: nameNode.text,\n kind: matched.kind,\n startLine: declNode.startPosition.row + 1,\n endLine: declNode.endPosition.row + 1,\n signature: firstLine(declNode.text),\n });\n continue;\n }\n\n if (config.callCapture && config.callCalleeCapture) {\n const callNode = byName.get(config.callCapture);\n const calleeNode = byName.get(config.callCalleeCapture);\n if (callNode && calleeNode) {\n calls.push({ callee: calleeNode.text, line: callNode.startPosition.row + 1 });\n continue;\n }\n }\n\n if (config.importCapture) {\n const imp = byName.get(config.importCapture);\n if (imp) imports.push(cleanImport(imp.text));\n }\n }\n\n const seen = new Set<string>();\n symbols = symbols.filter((s) => {\n const k = `${s.name}:${s.startLine}`;\n if (seen.has(k)) return false;\n seen.add(k);\n return true;\n });\n imports = Array.from(new Set(imports)).filter((s) => s.length > 0);\n } catch {\n // Query compile or parse failure — return what we have. Silent so a single\n // bad file doesn't abort the whole scan.\n }\n\n return { file: f, source, symbols, imports, calls };\n}\n","// C parser. Function definitions, structs, enums, typedefs, #include directives.\n\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\nimport { runGenericParser } from \"./_generic.js\";\n\nconst QUERY = `\n(function_definition declarator: (function_declarator declarator: (identifier) @function.name)) @function\n(struct_specifier name: (type_identifier) @struct.name) @struct\n(enum_specifier name: (type_identifier) @enum.name) @enum\n(type_definition declarator: (type_identifier) @type.name) @type\n(preproc_include path: (string_literal) @import)\n(preproc_include path: (system_lib_string) @import)\n(call_expression function: (identifier) @call.name) @call\n`;\n\nexport async function parseC(f: WalkedFile, source: string): Promise<ParsedFile> {\n return runGenericParser(\n {\n grammar: \"c\",\n query: QUERY,\n decls: [\n { declCapture: \"function\", nameCapture: \"function.name\", kind: \"function\" },\n { declCapture: \"struct\", nameCapture: \"struct.name\", kind: \"class\" },\n { declCapture: \"enum\", nameCapture: \"enum.name\", kind: \"enum\" },\n { declCapture: \"type\", nameCapture: \"type.name\", kind: \"type\" },\n ],\n importCapture: \"import\",\n callCapture: \"call\",\n callCalleeCapture: \"call.name\",\n },\n f,\n source,\n );\n}\n","// C++ parser. Functions, classes, structs, enums, namespaces, #includes.\n\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\nimport { runGenericParser } from \"./_generic.js\";\n\nconst QUERY = `\n(function_definition declarator: (function_declarator declarator: (identifier) @function.name)) @function\n(function_definition declarator: (function_declarator declarator: (qualified_identifier) @method.name)) @method\n(class_specifier name: (type_identifier) @class.name) @class\n(struct_specifier name: (type_identifier) @struct.name) @struct\n(enum_specifier name: (type_identifier) @enum.name) @enum\n(namespace_definition name: (namespace_identifier) @namespace.name) @namespace\n(preproc_include path: (string_literal) @import)\n(preproc_include path: (system_lib_string) @import)\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (field_expression field: (field_identifier) @call.name)) @call\n(call_expression function: (qualified_identifier name: (identifier) @call.name)) @call\n`;\n\nexport async function parseCpp(f: WalkedFile, source: string): Promise<ParsedFile> {\n return runGenericParser(\n {\n grammar: \"cpp\",\n query: QUERY,\n decls: [\n { declCapture: \"function\", nameCapture: \"function.name\", kind: \"function\" },\n { declCapture: \"method\", nameCapture: \"method.name\", kind: \"method\" },\n { declCapture: \"class\", nameCapture: \"class.name\", kind: \"class\" },\n { declCapture: \"struct\", nameCapture: \"struct.name\", kind: \"class\" },\n { declCapture: \"enum\", nameCapture: \"enum.name\", kind: \"enum\" },\n { declCapture: \"namespace\", nameCapture: \"namespace.name\", kind: \"class\" },\n ],\n importCapture: \"import\",\n callCapture: \"call\",\n callCalleeCapture: \"call.name\",\n },\n f,\n source,\n );\n}\n","// C# (.NET) parser. Classes, interfaces, structs, methods, namespaces.\n\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\nimport { runGenericParser } from \"./_generic.js\";\n\nconst QUERY = `\n(class_declaration name: (identifier) @class.name) @class\n(interface_declaration name: (identifier) @interface.name) @interface\n(struct_declaration name: (identifier) @struct.name) @struct\n(enum_declaration name: (identifier) @enum.name) @enum\n(method_declaration name: (identifier) @method.name) @method\n(namespace_declaration name: (_) @namespace.name) @namespace\n(using_directive (_) @import)\n(invocation_expression function: (identifier) @call.name) @call\n(invocation_expression function: (member_access_expression name: (identifier) @call.name)) @call\n`;\n\nexport async function parseCSharp(f: WalkedFile, source: string): Promise<ParsedFile> {\n return runGenericParser(\n {\n grammar: \"csharp\",\n query: QUERY,\n decls: [\n { declCapture: \"class\", nameCapture: \"class.name\", kind: \"class\" },\n { declCapture: \"interface\", nameCapture: \"interface.name\", kind: \"interface\" },\n { declCapture: \"struct\", nameCapture: \"struct.name\", kind: \"class\" },\n { declCapture: \"enum\", nameCapture: \"enum.name\", kind: \"enum\" },\n { declCapture: \"method\", nameCapture: \"method.name\", kind: \"method\" },\n { declCapture: \"namespace\", nameCapture: \"namespace.name\", kind: \"class\" },\n ],\n importCapture: \"import\",\n callCapture: \"call\",\n callCalleeCapture: \"call.name\",\n },\n f,\n source,\n );\n}\n","// Dart parser. v0.1.11 — real symbol extraction + import parsing on top of the\n// ABI-v15 grammar that ships in tree-sitter-wasms.\n//\n// Distinguishes top-level function_signature (kind: function) from\n// function_signature nested under method_signature (kind: method) by\n// anchoring the top-level pattern under `program`.\n//\n// Imports: `package:foo/bar.dart` and `dart:async` are stripped — they cross\n// the project boundary. Bare `foo.dart` is normalized to `./foo.dart` so the\n// shared resolveImport() (which requires a leading `.`) treats it as a\n// same-directory relative import.\n\nimport { Query, type Node } from \"web-tree-sitter\";\nimport type { SymbolKind } from \"../../graph/types.js\";\nimport { createParser, type ParsedFile, type ParsedSymbol } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\n\nconst QUERY = `\n(class_definition name: (identifier) @class.name) @class\n(mixin_declaration (identifier) @mixin.name) @mixin\n(extension_declaration name: (identifier) @ext.name) @ext\n(enum_declaration name: (identifier) @enum.name) @enum\n(type_alias (type_identifier) @typedef.name) @typedef\n\n(program (function_signature name: (identifier) @function.name) @function)\n\n(method_signature (function_signature name: (identifier) @method.name)) @method\n(method_signature (getter_signature name: (identifier) @getter.name)) @getter\n(method_signature (setter_signature name: (identifier) @setter.name)) @setter\n(constructor_signature name: (identifier) @ctor.name) @ctor\n\n(import_or_export (library_import (import_specification (configurable_uri (uri (string_literal) @import)))))\n`;\n\ninterface DeclShape {\n declCap: string;\n nameCap: string;\n kind: SymbolKind;\n}\n\nconst DECLS: DeclShape[] = [\n { declCap: \"class\", nameCap: \"class.name\", kind: \"class\" },\n { declCap: \"mixin\", nameCap: \"mixin.name\", kind: \"class\" },\n { declCap: \"ext\", nameCap: \"ext.name\", kind: \"class\" },\n { declCap: \"enum\", nameCap: \"enum.name\", kind: \"enum\" },\n { declCap: \"typedef\", nameCap: \"typedef.name\", kind: \"type\" },\n { declCap: \"function\", nameCap: \"function.name\", kind: \"function\" },\n { declCap: \"method\", nameCap: \"method.name\", kind: \"method\" },\n { declCap: \"getter\", nameCap: \"getter.name\", kind: \"method\" },\n { declCap: \"setter\", nameCap: \"setter.name\", kind: \"method\" },\n { declCap: \"ctor\", nameCap: \"ctor.name\", kind: \"method\" },\n];\n\nfunction firstLine(text: string, max = 200): string {\n const line = text.split(/\\r?\\n/, 1)[0] ?? \"\";\n return line.length > max ? line.slice(0, max) + \"…\" : line;\n}\n\n// Strip surrounding string-literal quotes and normalize bare same-directory\n// imports (Dart allows `import 'foo.dart';` without a leading `./`) so\n// resolveImport() — which keys off a leading dot — can match them.\nfunction normalizeDartImport(raw: string): string | null {\n const stripped = raw.replace(/^['\"]|['\"]$/g, \"\");\n if (!stripped) return null;\n if (stripped.startsWith(\"package:\")) return null;\n if (stripped.startsWith(\"dart:\")) return null;\n if (stripped.startsWith(\".\") || stripped.startsWith(\"/\")) return stripped;\n return `./${stripped}`;\n}\n\nexport async function parseDart(f: WalkedFile, source: string): Promise<ParsedFile> {\n let symbols: ParsedSymbol[] = [];\n let imports: string[] = [];\n\n try {\n const { parser, language } = await createParser(\"dart\");\n const tree = parser.parse(source);\n if (!tree) return { file: f, source, symbols, imports, calls: [] };\n\n const query = new Query(language, QUERY);\n const matches = query.matches(tree.rootNode);\n\n for (const match of matches) {\n const byName = new Map<string, Node>();\n for (const cap of match.captures) byName.set(cap.name, cap.node);\n\n let matched: DeclShape | null = null;\n for (const d of DECLS) {\n if (byName.has(d.declCap) && byName.has(d.nameCap)) {\n matched = d;\n break;\n }\n }\n\n if (matched) {\n const declNode = byName.get(matched.declCap)!;\n const nameNode = byName.get(matched.nameCap)!;\n symbols.push({\n name: nameNode.text,\n kind: matched.kind,\n startLine: declNode.startPosition.row + 1,\n endLine: declNode.endPosition.row + 1,\n signature: firstLine(declNode.text),\n });\n continue;\n }\n\n const importNode = byName.get(\"import\");\n if (importNode) {\n const norm = normalizeDartImport(importNode.text);\n if (norm) imports.push(norm);\n }\n }\n\n const seen = new Set<string>();\n symbols = symbols.filter((s) => {\n const k = `${s.name}:${s.startLine}`;\n if (seen.has(k)) return false;\n seen.add(k);\n return true;\n });\n imports = Array.from(new Set(imports));\n } catch {\n // swallow — see _generic.ts for the rationale (single bad file shouldn't\n // abort the whole scan).\n }\n\n return { file: f, source, symbols, imports, calls: [] };\n}\n","// Go parser. Functions, methods, type declarations, imports.\n\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\nimport { runGenericParser } from \"./_generic.js\";\n\nconst QUERY = `\n(function_declaration name: (identifier) @function.name) @function\n(method_declaration name: (field_identifier) @method.name) @method\n(type_spec name: (type_identifier) @type.name) @type\n(import_spec path: (interpreted_string_literal) @import)\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (selector_expression field: (field_identifier) @call.name)) @call\n`;\n\nexport async function parseGo(f: WalkedFile, source: string): Promise<ParsedFile> {\n return runGenericParser(\n {\n grammar: \"go\",\n query: QUERY,\n decls: [\n { declCapture: \"function\", nameCapture: \"function.name\", kind: \"function\" },\n { declCapture: \"method\", nameCapture: \"method.name\", kind: \"method\" },\n { declCapture: \"type\", nameCapture: \"type.name\", kind: \"type\" },\n ],\n importCapture: \"import\",\n callCapture: \"call\",\n callCalleeCapture: \"call.name\",\n },\n f,\n source,\n );\n}\n","// HubL (HubSpot CMS templating) parser. HubL lives in .html / .hubl files and\n// has no tree-sitter grammar, so we extract its symbol-like constructs with\n// regex: `{% macro %}` and `{% block %}` become symbols, and\n// `{% include / extends / import / from \"path\" %}` become import edges.\n// Plain HTML with no HubL tags simply yields no symbols (same as before).\n\nimport type { ParsedFile, ParsedSymbol } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\n\n// `{%-` / `-%}` are HubL/Jinja whitespace-control variants — tolerate them.\nconst MACRO_RE = /\\{%-?\\s*macro\\s+([A-Za-z_]\\w*)\\s*\\(([^)]*)\\)/g;\nconst ENDMACRO_RE = /\\{%-?\\s*endmacro\\b/g;\nconst BLOCK_RE = /\\{%-?\\s*block\\s+([A-Za-z_]\\w*)/g;\nconst ENDBLOCK_RE = /\\{%-?\\s*endblock\\b/g;\n// include / extends / import / from — all take a quoted template path first.\nconst IMPORT_RE = /\\{%-?\\s*(?:include|extends|import|from)\\s+[\"']([^\"']+)[\"']/g;\n\nfunction lineAt(source: string, index: number): number {\n return source.slice(0, index).split(/\\r?\\n/).length;\n}\n\n// Line of the next matching close tag after `fromIndex`; falls back to the\n// start line if the template is unbalanced (no close found).\nfunction endLineAfter(source: string, fromIndex: number, endRe: RegExp, startLine: number): number {\n endRe.lastIndex = fromIndex;\n const m = endRe.exec(source);\n return m ? lineAt(source, m.index) : startLine;\n}\n\nexport function parseHubL(f: WalkedFile, source: string): ParsedFile {\n const symbols: ParsedSymbol[] = [];\n const imports: string[] = [];\n\n for (const m of source.matchAll(MACRO_RE)) {\n const name = m[1];\n if (!name) continue;\n const args = (m[2] ?? \"\").trim();\n const start = m.index ?? 0;\n const startLine = lineAt(source, start);\n symbols.push({\n name,\n kind: \"function\",\n startLine,\n endLine: endLineAfter(source, start + m[0].length, ENDMACRO_RE, startLine),\n signature: `macro ${name}(${args})`,\n });\n }\n\n for (const m of source.matchAll(BLOCK_RE)) {\n const name = m[1];\n if (!name) continue;\n const start = m.index ?? 0;\n const startLine = lineAt(source, start);\n symbols.push({\n name,\n kind: \"component\",\n startLine,\n endLine: endLineAfter(source, start + m[0].length, ENDBLOCK_RE, startLine),\n signature: `block ${name}`,\n });\n }\n\n for (const m of source.matchAll(IMPORT_RE)) {\n const spec = m[1];\n if (spec) imports.push(spec);\n }\n\n return { file: f, source, symbols, imports: Array.from(new Set(imports)), calls: [] };\n}\n","// Java parser. Classes, interfaces, methods, imports.\n\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\nimport { runGenericParser } from \"./_generic.js\";\n\nconst QUERY = `\n(class_declaration name: (identifier) @class.name) @class\n(interface_declaration name: (identifier) @interface.name) @interface\n(method_declaration name: (identifier) @method.name) @method\n(enum_declaration name: (identifier) @enum.name) @enum\n(import_declaration (scoped_identifier) @import)\n(method_invocation name: (identifier) @call.name) @call\n`;\n\nexport async function parseJava(f: WalkedFile, source: string): Promise<ParsedFile> {\n return runGenericParser(\n {\n grammar: \"java\",\n query: QUERY,\n decls: [\n { declCapture: \"class\", nameCapture: \"class.name\", kind: \"class\" },\n { declCapture: \"interface\", nameCapture: \"interface.name\", kind: \"interface\" },\n { declCapture: \"method\", nameCapture: \"method.name\", kind: \"method\" },\n { declCapture: \"enum\", nameCapture: \"enum.name\", kind: \"enum\" },\n ],\n importCapture: \"import\",\n callCapture: \"call\",\n callCalleeCapture: \"call.name\",\n },\n f,\n source,\n );\n}\n","// Kotlin parser. Functions, classes, objects, interfaces, imports.\n\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\nimport { runGenericParser } from \"./_generic.js\";\n\nconst QUERY = `\n(function_declaration (simple_identifier) @function.name) @function\n(class_declaration (type_identifier) @class.name) @class\n(object_declaration (type_identifier) @object.name) @object\n(import_header (identifier) @import)\n(call_expression (simple_identifier) @call.name) @call\n`;\n\nexport async function parseKotlin(f: WalkedFile, source: string): Promise<ParsedFile> {\n return runGenericParser(\n {\n grammar: \"kotlin\",\n query: QUERY,\n decls: [\n { declCapture: \"function\", nameCapture: \"function.name\", kind: \"function\" },\n { declCapture: \"class\", nameCapture: \"class.name\", kind: \"class\" },\n { declCapture: \"object\", nameCapture: \"object.name\", kind: \"class\" },\n ],\n importCapture: \"import\",\n callCapture: \"call\",\n callCalleeCapture: \"call.name\",\n },\n f,\n source,\n );\n}\n","// PHP parser. Functions, classes, interfaces, methods, traits.\n\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\nimport { runGenericParser } from \"./_generic.js\";\n\nconst QUERY = `\n(function_definition name: (name) @function.name) @function\n(class_declaration name: (name) @class.name) @class\n(interface_declaration name: (name) @interface.name) @interface\n(trait_declaration name: (name) @trait.name) @trait\n(method_declaration name: (name) @method.name) @method\n(function_call_expression function: (name) @call.name) @call\n(member_call_expression name: (name) @call.name) @call\n(scoped_call_expression name: (name) @call.name) @call\n`;\n\nexport async function parsePhp(f: WalkedFile, source: string): Promise<ParsedFile> {\n return runGenericParser(\n {\n grammar: \"php\",\n query: QUERY,\n decls: [\n { declCapture: \"function\", nameCapture: \"function.name\", kind: \"function\" },\n { declCapture: \"class\", nameCapture: \"class.name\", kind: \"class\" },\n { declCapture: \"interface\", nameCapture: \"interface.name\", kind: \"interface\" },\n { declCapture: \"trait\", nameCapture: \"trait.name\", kind: \"class\" },\n { declCapture: \"method\", nameCapture: \"method.name\", kind: \"method\" },\n ],\n callCapture: \"call\",\n callCalleeCapture: \"call.name\",\n },\n f,\n source,\n );\n}\n","// Python parser using tree-sitter-python WASM.\n// Extracts: function/class definitions, methods, and import statements.\n\nimport { Query, type Node } from \"web-tree-sitter\";\nimport { createParser, type CallSite, type ParsedFile, type ParsedSymbol } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\n\nconst QUERY = `\n(function_definition name: (identifier) @function.name) @function\n(class_definition name: (identifier) @class.name) @class\n(import_statement name: (dotted_name) @import.module)\n(import_from_statement module_name: (dotted_name) @import.from)\n(import_from_statement module_name: (relative_import) @import.from)\n(call function: (identifier) @call.name) @call\n(call function: (attribute attribute: (identifier) @call.name)) @call\n`;\n\nfunction firstLine(text: string, max = 200): string {\n const line = text.split(/\\r?\\n/, 1)[0] ?? \"\";\n return line.length > max ? line.slice(0, max) + \"…\" : line;\n}\n\nexport async function parsePython(f: WalkedFile, source: string): Promise<ParsedFile> {\n let symbols: ParsedSymbol[] = [];\n let imports: string[] = [];\n const calls: CallSite[] = [];\n\n try {\n const { parser, language } = await createParser(\"python\");\n const tree = parser.parse(source);\n if (!tree) return { file: f, source, symbols, imports, calls };\n\n const query = new Query(language, QUERY);\n const matches = query.matches(tree.rootNode);\n\n for (const match of matches) {\n const byName = new Map<string, Node>();\n for (const cap of match.captures) byName.set(cap.name, cap.node);\n\n const funcDecl = byName.get(\"function\");\n const funcName = byName.get(\"function.name\");\n if (funcDecl && funcName) {\n const parentType = funcDecl.parent?.parent?.type;\n const isMethod = parentType === \"class_definition\";\n symbols.push({\n name: funcName.text,\n kind: isMethod ? \"method\" : \"function\",\n startLine: funcDecl.startPosition.row + 1,\n endLine: funcDecl.endPosition.row + 1,\n signature: firstLine(funcDecl.text),\n });\n continue;\n }\n\n const classDecl = byName.get(\"class\");\n const className = byName.get(\"class.name\");\n if (classDecl && className) {\n symbols.push({\n name: className.text,\n kind: \"class\",\n startLine: classDecl.startPosition.row + 1,\n endLine: classDecl.endPosition.row + 1,\n signature: firstLine(classDecl.text),\n });\n continue;\n }\n\n const importNode = byName.get(\"import.module\") ?? byName.get(\"import.from\");\n if (importNode) {\n imports.push(importNode.text);\n continue;\n }\n\n const callName = byName.get(\"call.name\");\n const callNode = byName.get(\"call\");\n if (callName && callNode) {\n calls.push({ callee: callName.text, line: callNode.startPosition.row + 1 });\n }\n }\n\n const seen = new Set<string>();\n symbols = symbols.filter((s) => {\n const key = `${s.name}:${s.startLine}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n imports = Array.from(new Set(imports));\n } catch {\n // swallow parse errors\n }\n\n return { file: f, source, symbols, imports, calls };\n}\n","// Ruby parser. Methods, classes, modules.\n// Imports omitted — Ruby's `require` is dynamic and hard to capture cleanly;\n// keyword indexing still surfaces dependencies.\n\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\nimport { runGenericParser } from \"./_generic.js\";\n\nconst QUERY = `\n(method name: (identifier) @function.name) @function\n(singleton_method name: (identifier) @method.name) @method\n(class name: (constant) @class.name) @class\n(module name: (constant) @module.name) @module\n(call method: (identifier) @call.name) @call\n`;\n\nexport async function parseRuby(f: WalkedFile, source: string): Promise<ParsedFile> {\n return runGenericParser(\n {\n grammar: \"ruby\",\n query: QUERY,\n decls: [\n { declCapture: \"function\", nameCapture: \"function.name\", kind: \"function\" },\n { declCapture: \"method\", nameCapture: \"method.name\", kind: \"method\" },\n { declCapture: \"class\", nameCapture: \"class.name\", kind: \"class\" },\n { declCapture: \"module\", nameCapture: \"module.name\", kind: \"class\" },\n ],\n callCapture: \"call\",\n callCalleeCapture: \"call.name\",\n },\n f,\n source,\n );\n}\n","// Rust parser. Functions, structs, enums, traits, impls.\n// Import capture is omitted — `use` paths are nested and complex; the file\n// will still be walked + keyword-indexed.\n\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\nimport { runGenericParser } from \"./_generic.js\";\n\nconst QUERY = `\n(function_item name: (identifier) @function.name) @function\n(struct_item name: (type_identifier) @struct.name) @struct\n(enum_item name: (type_identifier) @enum.name) @enum\n(trait_item name: (type_identifier) @trait.name) @trait\n(impl_item type: (type_identifier) @impl.name) @impl\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (scoped_identifier name: (identifier) @call.name)) @call\n(call_expression function: (field_expression field: (field_identifier) @call.name)) @call\n`;\n\nexport async function parseRust(f: WalkedFile, source: string): Promise<ParsedFile> {\n return runGenericParser(\n {\n grammar: \"rust\",\n query: QUERY,\n decls: [\n { declCapture: \"function\", nameCapture: \"function.name\", kind: \"function\" },\n { declCapture: \"struct\", nameCapture: \"struct.name\", kind: \"class\" },\n { declCapture: \"enum\", nameCapture: \"enum.name\", kind: \"enum\" },\n { declCapture: \"trait\", nameCapture: \"trait.name\", kind: \"interface\" },\n { declCapture: \"impl\", nameCapture: \"impl.name\", kind: \"class\" },\n ],\n callCapture: \"call\",\n callCalleeCapture: \"call.name\",\n },\n f,\n source,\n );\n}\n","// TS/JS parser using tree-sitter-typescript / -tsx WASM grammars.\n// Extracts: function/class/interface/type/enum declarations, exported consts,\n// arrow functions assigned to const, and import sources.\n\nimport { Query, type Node } from \"web-tree-sitter\";\nimport type { SymbolKind } from \"../../graph/types.js\";\nimport {\n createParser,\n type CallSite,\n type GrammarName,\n type ParsedFile,\n type ParsedSymbol,\n} from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\n\n// TS / TSX query — uses the type-identifier node type for class names, includes\n// interface / type-alias / enum declarations that don't exist in plain JS.\nconst TS_QUERY = `\n(function_declaration name: (identifier) @function.name) @function\n(class_declaration name: (type_identifier) @class.name) @class\n(interface_declaration name: (type_identifier) @interface.name) @interface\n(type_alias_declaration name: (type_identifier) @type.name) @type\n(enum_declaration name: (identifier) @enum.name) @enum\n(method_definition name: (property_identifier) @method.name) @method\n(lexical_declaration (variable_declarator name: (identifier) @const-fn.name value: [(arrow_function) (function_expression)])) @const-fn\n(assignment_expression left: (member_expression property: (property_identifier) @member-fn.name) right: [(arrow_function) (function_expression)]) @member-fn\n(import_statement source: (string) @import)\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (member_expression property: (property_identifier) @call.name)) @call\n`;\n\n// JS query — class names are plain identifiers (JS grammar has no\n// type_identifier node). No interface / type_alias / enum since JS lacks them.\n// Adds a call_expression capture for CommonJS require('x'); filtered in the\n// matching loop by checking the function identifier text equals \"require\".\nconst JS_QUERY = `\n(function_declaration name: (identifier) @function.name) @function\n(class_declaration name: (identifier) @class.name) @class\n(method_definition name: (property_identifier) @method.name) @method\n(lexical_declaration (variable_declarator name: (identifier) @const-fn.name value: [(arrow_function) (function_expression)])) @const-fn\n(assignment_expression left: (member_expression property: (property_identifier) @member-fn.name) right: [(arrow_function) (function_expression)]) @member-fn\n(import_statement source: (string) @import)\n(call_expression function: (identifier) @_require_fn arguments: (arguments . (string) @require_source))\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (member_expression property: (property_identifier) @call.name)) @call\n`;\n\nfunction grammarFor(ext: string): GrammarName {\n if (ext === \".tsx\" || ext === \".jsx\") return \"tsx\";\n if (ext === \".js\" || ext === \".cjs\" || ext === \".mjs\") return \"javascript\";\n return \"typescript\";\n}\n\nfunction queryFor(grammar: GrammarName): string {\n return grammar === \"javascript\" ? JS_QUERY : TS_QUERY;\n}\n\nfunction unquote(s: string): string {\n return s.replace(/^[\"'`]|[\"'`]$/g, \"\");\n}\n\nfunction firstLine(text: string, max = 200): string {\n const line = text.split(/\\r?\\n/, 1)[0] ?? \"\";\n return line.length > max ? line.slice(0, max) + \"…\" : line;\n}\n\ninterface DeclShape {\n decl: Node;\n name: Node;\n kind: SymbolKind;\n}\n\nfunction shapeFromCaptures(captures: Map<string, Node>): DeclShape | null {\n const findDecl = (k: string, sk: SymbolKind): DeclShape | null => {\n const decl = captures.get(k);\n const name = captures.get(`${k}.name`);\n return decl && name ? { decl, name, kind: sk } : null;\n };\n\n return (\n findDecl(\"function\", \"function\") ??\n findDecl(\"class\", \"class\") ??\n findDecl(\"interface\", \"interface\") ??\n findDecl(\"type\", \"type\") ??\n findDecl(\"enum\", \"enum\") ??\n findDecl(\"method\", \"method\") ??\n findDecl(\"const-fn\", \"function\") ??\n findDecl(\"member-fn\", \"function\")\n );\n}\n\nexport async function parseTypeScript(f: WalkedFile, source: string): Promise<ParsedFile> {\n const grammar = grammarFor(f.ext);\n let symbols: ParsedSymbol[] = [];\n let imports: string[] = [];\n const calls: CallSite[] = [];\n\n try {\n const { parser, language } = await createParser(grammar);\n const tree = parser.parse(source);\n if (!tree) return { file: f, source, symbols, imports, calls };\n\n const query = new Query(language, queryFor(grammar));\n const matches = query.matches(tree.rootNode);\n\n for (const match of matches) {\n const byName = new Map<string, Node>();\n for (const cap of match.captures) byName.set(cap.name, cap.node);\n\n const shape = shapeFromCaptures(byName);\n if (shape) {\n symbols.push({\n name: shape.name.text,\n kind: shape.kind,\n startLine: shape.decl.startPosition.row + 1,\n endLine: shape.decl.endPosition.row + 1,\n signature: firstLine(shape.decl.text),\n });\n continue;\n }\n const importNode = byName.get(\"import\");\n if (importNode) {\n imports.push(unquote(importNode.text));\n continue;\n }\n // CommonJS require('x') — only captured by JS_QUERY. The identifier\n // must literally be \"require\" (not setTimeout, console, etc).\n const requireFn = byName.get(\"_require_fn\");\n const requireSource = byName.get(\"require_source\");\n if (requireFn && requireSource && requireFn.text === \"require\") {\n imports.push(unquote(requireSource.text));\n continue;\n }\n // Call site (bare or member call). `require(...)` also matches here — it\n // resolves to no project symbol and is dropped, so no special-casing.\n const callName = byName.get(\"call.name\");\n const callNode = byName.get(\"call\");\n if (callName && callNode) {\n calls.push({ callee: callName.text, line: callNode.startPosition.row + 1 });\n }\n }\n\n const seen = new Set<string>();\n symbols = symbols.filter((s) => {\n const key = `${s.name}:${s.startLine}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n imports = Array.from(new Set(imports));\n } catch {\n // Parse failure shouldn't abort the whole scan — return what we have.\n }\n\n return { file: f, source, symbols, imports, calls };\n}\n","// Svelte parser. Extracts <script> and <script lang=\"ts\"> blocks and parses\n// their contents with the TypeScript parser. Tracks the original line offset\n// so reported symbol positions match the .svelte source.\n\nimport { parseTypeScript } from \"./typescript.js\";\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\n\nconst SCRIPT_RE = /<script\\b[^>]*>([\\s\\S]*?)<\\/script>/gi;\n\ninterface ScriptBlock {\n source: string;\n startLine: number; // 1-based line number where the script content begins\n isTsx: boolean;\n}\n\nfunction extractScripts(source: string): ScriptBlock[] {\n const out: ScriptBlock[] = [];\n for (const match of source.matchAll(SCRIPT_RE)) {\n const full = match[0];\n const inner = match[1] ?? \"\";\n const openTag = full.slice(0, full.indexOf(\">\") + 1);\n const tagStart = match.index ?? 0;\n const contentStart = tagStart + openTag.length;\n const startLine = source.slice(0, contentStart).split(/\\r?\\n/).length;\n const isTsx = /\\blang\\s*=\\s*[\"']?(ts|tsx|typescript)[\"']?/i.test(openTag);\n out.push({ source: inner, startLine, isTsx });\n }\n return out;\n}\n\nexport async function parseSvelte(f: WalkedFile, source: string): Promise<ParsedFile> {\n const blocks = extractScripts(source);\n const out: ParsedFile = { file: f, source, symbols: [], imports: [], calls: [] };\n\n for (const block of blocks) {\n const virtual: WalkedFile = { ...f, ext: block.isTsx ? \".ts\" : \".js\" };\n const parsed = await parseTypeScript(virtual, block.source);\n const offset = block.startLine - 1;\n for (const sym of parsed.symbols) {\n out.symbols.push({\n ...sym,\n startLine: sym.startLine + offset,\n endLine: sym.endLine + offset,\n });\n }\n for (const imp of parsed.imports) out.imports.push(imp);\n for (const call of parsed.calls) out.calls.push({ ...call, line: call.line + offset });\n }\n\n // The .svelte file itself is treated as a component.\n out.symbols.push({\n name:\n f.relPath\n .split(\"/\")\n .pop()\n ?.replace(/\\.svelte$/i, \"\") ?? f.relPath,\n kind: \"component\",\n startLine: 1,\n endLine: source.split(/\\r?\\n/).length,\n signature: f.relPath,\n });\n out.imports = Array.from(new Set(out.imports));\n return out;\n}\n","// Vue SFC parser. Extracts <script> / <script setup> / <script lang=\"ts\">\n// blocks and parses them with the TypeScript parser, preserving line offsets.\n\nimport { parseTypeScript } from \"./typescript.js\";\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\n\nconst SCRIPT_RE = /<script\\b[^>]*>([\\s\\S]*?)<\\/script>/gi;\n\ninterface ScriptBlock {\n source: string;\n startLine: number;\n isTs: boolean;\n}\n\nfunction extractScripts(source: string): ScriptBlock[] {\n const out: ScriptBlock[] = [];\n for (const match of source.matchAll(SCRIPT_RE)) {\n const full = match[0];\n const inner = match[1] ?? \"\";\n const openTag = full.slice(0, full.indexOf(\">\") + 1);\n const tagStart = match.index ?? 0;\n const contentStart = tagStart + openTag.length;\n const startLine = source.slice(0, contentStart).split(/\\r?\\n/).length;\n const isTs = /\\blang\\s*=\\s*[\"']?(ts|tsx|typescript)[\"']?/i.test(openTag);\n out.push({ source: inner, startLine, isTs });\n }\n return out;\n}\n\nexport async function parseVue(f: WalkedFile, source: string): Promise<ParsedFile> {\n const blocks = extractScripts(source);\n const out: ParsedFile = { file: f, source, symbols: [], imports: [], calls: [] };\n\n for (const block of blocks) {\n const virtual: WalkedFile = { ...f, ext: block.isTs ? \".ts\" : \".js\" };\n const parsed = await parseTypeScript(virtual, block.source);\n const offset = block.startLine - 1;\n for (const sym of parsed.symbols) {\n out.symbols.push({\n ...sym,\n startLine: sym.startLine + offset,\n endLine: sym.endLine + offset,\n });\n }\n for (const imp of parsed.imports) out.imports.push(imp);\n for (const call of parsed.calls) out.calls.push({ ...call, line: call.line + offset });\n }\n\n out.symbols.push({\n name:\n f.relPath\n .split(\"/\")\n .pop()\n ?.replace(/\\.vue$/i, \"\") ?? f.relPath,\n kind: \"component\",\n startLine: 1,\n endLine: source.split(/\\r?\\n/).length,\n signature: f.relPath,\n });\n out.imports = Array.from(new Set(out.imports));\n return out;\n}\n","// Walks project root, yields files to parse.\n// Honors .gitignore + .synthraignore (additive — entries in either are ignored).\n// Defensive defaults skip VCS, build, and dependency directories even if absent\n// from .gitignore.\n\nimport type { Dirent } from \"node:fs\";\nimport { readFile, readdir, stat } from \"node:fs/promises\";\nimport { extname, join, relative, sep } from \"node:path\";\nimport ignore, { type Ignore } from \"ignore\";\n\nexport interface WalkedFile {\n absPath: string;\n relPath: string;\n ext: string;\n size: number;\n}\n\nexport interface WalkOptions {\n /** Maximum file size to yield (bytes). Defaults to 2 MB. */\n maxFileSize?: number;\n /** Additional ignore patterns layered on top of .gitignore + .synthraignore. */\n extraIgnore?: string[];\n}\n\nconst DEFAULT_IGNORE = [\n \".git/\",\n \".synthra/\",\n \".synthra-graph/\",\n \".claude/\",\n \"node_modules/\",\n \"dist/\",\n \"build/\",\n \"out/\",\n \"coverage/\",\n \".next/\",\n \".nuxt/\",\n \".svelte-kit/\",\n \".turbo/\",\n \".cache/\",\n \".vscode/\",\n \".idea/\",\n \".vs/\",\n // Flutter / Dart build caches — IDE-rehydrated, contain third-party\n // type stubs (typescript.d.ts, babylon.js etc.) that contaminate the graph.\n \".dart_tool/\",\n \".flutter-plugins\",\n \".flutter-plugins-dependencies\",\n // Android / Java / Kotlin / Rust\n \".gradle/\",\n \"target/\",\n // iOS / Xcode\n \"Pods/\",\n \"DerivedData/\",\n // Python\n \"__pycache__/\",\n \".venv/\",\n \"venv/\",\n \".tox/\",\n \".pytest_cache/\",\n \".mypy_cache/\",\n \".ruff_cache/\",\n // .NET\n \"obj/\",\n];\n\nconst BINARY_EXTS = new Set([\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".webp\",\n \".svg\",\n \".ico\",\n \".bmp\",\n \".pdf\",\n \".zip\",\n \".tar\",\n \".gz\",\n \".7z\",\n \".rar\",\n \".mp3\",\n \".mp4\",\n \".mov\",\n \".avi\",\n \".webm\",\n \".wav\",\n \".ogg\",\n \".ttf\",\n \".otf\",\n \".woff\",\n \".woff2\",\n \".eot\",\n \".exe\",\n \".dll\",\n \".so\",\n \".dylib\",\n \".bin\",\n \".wasm\",\n \".lock\",\n \".lockb\",\n]);\n\nasync function readIgnoreFile(path: string): Promise<string[]> {\n try {\n const text = await readFile(path, \"utf8\");\n return text\n .split(/\\r?\\n/)\n .map((l) => l.trim())\n .filter((l) => l.length > 0 && !l.startsWith(\"#\"));\n } catch {\n return [];\n }\n}\n\nasync function buildMatcher(root: string, extra: string[]): Promise<Ignore> {\n const ig = ignore();\n ig.add(DEFAULT_IGNORE);\n ig.add(await readIgnoreFile(join(root, \".gitignore\")));\n ig.add(await readIgnoreFile(join(root, \".synthraignore\")));\n if (extra.length) ig.add(extra);\n return ig;\n}\n\nfunction toPosix(p: string): string {\n return sep === \"/\" ? p : p.split(sep).join(\"/\");\n}\n\nexport async function* walk(root: string, options: WalkOptions = {}): AsyncGenerator<WalkedFile> {\n const maxFileSize = options.maxFileSize ?? 2_000_000;\n const ig = await buildMatcher(root, options.extraIgnore ?? []);\n\n async function* recurse(dir: string): AsyncGenerator<WalkedFile> {\n let entries: Dirent[];\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n const abs = join(dir, entry.name);\n const rel = relative(root, abs);\n if (!rel) continue;\n const relPosix = toPosix(rel);\n const matchPath = entry.isDirectory() ? `${relPosix}/` : relPosix;\n if (ig.ignores(matchPath)) continue;\n\n if (entry.isDirectory()) {\n yield* recurse(abs);\n } else if (entry.isFile()) {\n const ext = extname(entry.name).toLowerCase();\n if (BINARY_EXTS.has(ext)) continue;\n let size: number;\n try {\n const s = await stat(abs);\n size = s.size;\n } catch {\n continue;\n }\n if (size > maxFileSize) continue;\n yield { absPath: abs, relPath: relPosix, ext, size };\n }\n }\n }\n\n yield* recurse(root);\n}\n","// Reads/writes info_graph.json and symbol_index.json.\n\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport type { GraphSchema, SymbolIndex } from \"./types.js\";\n\nasync function writeJson(path: string, data: unknown, pretty: boolean): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n const text = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);\n await writeFile(path, text + \"\\n\", \"utf8\");\n}\n\nasync function readJson<T>(path: string): Promise<T> {\n const text = await readFile(path, \"utf8\");\n return JSON.parse(text) as T;\n}\n\nexport async function writeGraph(path: string, graph: GraphSchema): Promise<void> {\n // Pretty-printing a graph with full file contents balloons disk size and\n // the JSON is only ever read by machines; keep it compact.\n await writeJson(path, graph, false);\n}\n\nexport async function readGraph(path: string): Promise<GraphSchema> {\n return readJson<GraphSchema>(path);\n}\n\nexport async function writeSymbolIndex(path: string, index: SymbolIndex): Promise<void> {\n await writeJson(path, index, true);\n}\n\nexport async function readSymbolIndex(path: string): Promise<SymbolIndex> {\n // Re-home onto a null prototype so name lookups (e.g. index[\"toString\"])\n // never resolve to an inherited Object.prototype member. Mirrors\n // buildSymbolIndex, which builds the index the same way.\n const parsed = await readJson<SymbolIndex>(path);\n return Object.assign(Object.create(null), parsed);\n}\n","// Project bootstrap: creates .synthra-graph/, .synthra/, updates .gitignore,\n// patches CLAUDE.md with the versioned policy block.\n\nimport { mkdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport { basename } from \"node:path\";\n\nimport { patchClaudeMd } from \"../hooks/claude-md.js\";\nimport type { SynthraPaths } from \"../shared/paths.js\";\n\nexport interface BootstrapResult {\n graphCreated: boolean;\n contextCreated: boolean;\n gitignoreUpdated: boolean;\n claudeMdUpdated: boolean;\n claudeMdCreated: boolean;\n}\n\n// Entries Synthra appends to the project .gitignore on bootstrap.\n// Each is gated by a check: if the entry is already present (any\n// indentation, trimmed match), it's skipped. Comments are per-entry so\n// users understand why each line is there and can remove what they don't\n// want without breaking the rest.\nconst GITIGNORE_ENTRIES: { comment: string; entry: string }[] = [\n {\n comment: \"added by synthra (heavy generated state — gitignored by design)\",\n entry: \".synthra-graph/\",\n },\n {\n comment:\n \"added by synthra — MCP registration. Remove this line if you want \" +\n \"to share the synthra MCP entry with teammates via committed .mcp.json\",\n entry: \".mcp.json\",\n },\n];\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function ensureDir(path: string): Promise<boolean> {\n const had = await exists(path);\n await mkdir(path, { recursive: true });\n return !had;\n}\n\nasync function patchGitignore(path: string): Promise<boolean> {\n let existing = \"\";\n try {\n existing = await readFile(path, \"utf8\");\n } catch {\n /* file may not exist */\n }\n const trimmed = new Set(existing.split(/\\r?\\n/).map((l) => l.trim()));\n const missing = GITIGNORE_ENTRIES.filter((e) => !trimmed.has(e.entry));\n if (missing.length === 0) return false;\n\n const block = missing.map((m) => `# ${m.comment}\\n${m.entry}`).join(\"\\n\") + \"\\n\";\n const appendix =\n (existing.length === 0 || existing.endsWith(\"\\n\") ? \"\" : \"\\n\") +\n (existing.length ? \"\\n\" : \"\") +\n block;\n await writeFile(path, existing + appendix, \"utf8\");\n return true;\n}\n\nexport async function bootstrap(paths: SynthraPaths): Promise<BootstrapResult> {\n const graphCreated = await ensureDir(paths.graphDir);\n const contextCreated = await ensureDir(paths.contextDir);\n const gitignoreUpdated = await patchGitignore(paths.gitignore);\n\n const claudeMdExistedBefore = await exists(paths.claudeMd);\n const patch = await patchClaudeMd(paths.claudeMd, basename(paths.projectRoot));\n\n return {\n graphCreated,\n contextCreated,\n gitignoreUpdated,\n claudeMdUpdated: patch.updated,\n claudeMdCreated: patch.created && !claudeMdExistedBefore,\n };\n}\n","// Idempotent patcher for the project's CLAUDE.md. Manages a single block\n// bounded by <!-- synthra-policy v<N> BEGIN --> ... <!-- synthra-policy v<N> END -->.\n// On each run, any prior synthra-policy block (any version) is removed and the\n// current-version block is appended at the end.\n\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { basename, dirname } from \"node:path\";\n\nexport const POLICY_VERSION = 7;\nexport const POLICY_BEGIN = `<!-- synthra-policy v${POLICY_VERSION} BEGIN -->`;\nexport const POLICY_END = `<!-- synthra-policy v${POLICY_VERSION} END -->`;\n\n// Matches a synthra-policy block of any version, e.g. v1, v2 …\nconst ANY_BLOCK_RE =\n /<!--\\s*synthra-policy\\s+v\\d+\\s+BEGIN\\s*-->[\\s\\S]*?<!--\\s*synthra-policy\\s+v\\d+\\s+END\\s*-->\\s*/g;\n\nexport interface PatchResult {\n created: boolean;\n updated: boolean;\n skipped: boolean;\n}\n\nexport function policyBlock(): string {\n return [\n POLICY_BEGIN,\n \"## Synthra context policy\",\n \"\",\n \"Synthra has pre-loaded structured context into this session and exposes\",\n \"the project's code graph through MCP tools. **Prefer these tools over\",\n \"Grep / Glob / Read** — they are faster, cheaper, and already filtered\",\n \"to relevant files.\",\n \"\",\n \"> **Tool namespace.** Synthra's MCP tools are exposed as\",\n \"> `mcp__synthra__graph_continue`, `mcp__synthra__graph_read`, and\",\n \"> `mcp__synthra__graph_register_edit`. **Short names will NOT resolve**\",\n \"> in ToolSearch or invocation — always use the full namespaced form.\",\n \"> If the tools are deferred, load their schemas with ToolSearch:\",\n \"> `select:mcp__synthra__graph_continue,mcp__synthra__graph_read,mcp__synthra__graph_register_edit`.\",\n \"> Below, short names (`graph_continue` etc.) appear in prose for\",\n \"> readability only.\",\n \"\",\n \"### Tools\",\n \"\",\n \"- **`graph_continue(query)`** — returns a `Confidence` label, the list\",\n \" of relevant `Files`, and signatures + top function bodies for those\",\n \" files. Your default first move when you need project context.\",\n \"- **`graph_read(target)`** — fetch source. Prefer the\",\n ' `\"file/path.ts::SymbolName\"` form over a bare file path — reading one',\n \" symbol is ~50 tokens, reading a whole file is thousands.\",\n \"- **`graph_register_edit(files)`** — after you edit files, call this so\",\n \" subsequent turns weight your changes and avoid stale snapshots.\",\n \"\",\n \"### When to call `graph_continue` — and when to skip\",\n \"\",\n \"**Call `graph_continue` only when you do NOT already know the relevant\",\n \"files.**\",\n \"\",\n \"Call it when:\",\n \"- This is the first message of a new task or conversation\",\n \"- The task shifts to a different area of the codebase\",\n \"- You need files you haven't seen yet in this session\",\n \"\",\n \"**Skip `graph_continue` when:**\",\n \"- You already identified the relevant files earlier in this conversation\",\n \"- You are doing follow-up work on files already read (verify, refactor,\",\n \" test, docs, cleanup, commit)\",\n \"- The task is pure text (commit message, explanation, summary)\",\n \"\",\n \"If skipping, go directly to\",\n '`mcp__synthra__graph_read(\"file.ts::symbol\")` on what you already know.',\n \"\",\n \"### Confidence caps\",\n \"\",\n \"When `graph_continue` returns:\",\n \"\",\n \"- **`Confidence: high`** → Stop. Do NOT Grep, Glob, or further explore\",\n \" for this query. The graph already has it.\",\n \"- **`Confidence: medium`** → Read the listed `Files` directly via\",\n ' `mcp__synthra__graph_read(\"file::symbol\")` *before* trying Grep. The',\n \" graph has narrowed the search space — use it, don't bypass it.\",\n \"- **`Confidence: low`** → You may use Grep / Glob, but the PreToolUse\",\n \" hook may still block redundant calls.\",\n \"\",\n \"### Reading code\",\n \"\",\n \"- **Always use `file::symbol` notation** with `graph_read`. Whole-file\",\n \" reads should be rare — only when you genuinely need the full file.\",\n \"- If `graph_continue`'s `Files` list contains a `::` entry, pass it\",\n \" verbatim to `graph_read`.\",\n \"- **Large file?** Don't read it in successive line-range chunks — call\",\n \" `mcp__synthra__graph_continue` or\",\n ' `mcp__synthra__graph_read(\"file::symbol\")` to pull the one symbol you',\n \" need. Chunked whole-file Reads are exactly the cost `graph_read`\",\n \" exists to avoid.\",\n \"\",\n \"### Editing a file\",\n \"\",\n \"Claude Code's `Edit` tool (and `Write` when overwriting) only accepts a\",\n \"file that was opened with the **`Read` tool** — a `graph_read` slice does\",\n 'not count, and editing such a file fails with *\"File has not been read',\n 'yet.\"* So before editing a file you only know through `graph_read`: take',\n \"the line range from its header (e.g. `…::handler (L120-168)`), `Read` that\",\n \"file with a matching `offset`/`limit`, then `Edit`. That satisfies the\",\n \"gate while keeping the read small — don't whole-file `Read` unless the\",\n \"edit spans most of the file.\",\n \"\",\n \"### Don'ts\",\n \"\",\n \"- Don't Grep / Glob before calling `graph_continue` when required — the\",\n \" PreToolUse hook may block it.\",\n \"- Don't call `graph_continue` more than once per turn.\",\n \"- Don't read whole files when a symbol-level read would suffice.\",\n \"\",\n \"### Resuming a session\",\n \"\",\n 'At session start the primer may begin with a **\"Since you were last here\"**',\n \"digest — recent commits, files touched, open next-steps, and recent\",\n \"decisions carried over from the previous session. **Trust it.** It is the\",\n \"cheapest possible orientation: do NOT re-run `graph_continue` or Grep just\",\n 'to rediscover \"what were we doing / what changed\" — that work is already',\n \"done. For the concrete next steps,\",\n '`mcp__synthra__context_recall({kind:\"next\"})` returns them verbatim. Only',\n \"reach for fresh retrieval when the task moves beyond what the digest\",\n \"covers.\",\n \"\",\n \"### Session-end resume note\",\n \"\",\n 'When the user signals they\\'re done (e.g. \"bye\", \"wrap up\", \"done\"),',\n \"persist the resume state by calling `context_remember` once per bullet.\",\n \"Synthra re-renders `.synthra/CONTEXT.md` from those entries at session\",\n \"end — do **NOT** write to `CONTEXT.md` directly, it is a derived view\",\n \"and direct edits are overwritten by the Stop hook.\",\n \"\",\n \"Use these `kind` values:\",\n \"\",\n '- **`kind: \"task\"`** — what is being worked on right now (1 entry)',\n '- **`kind: \"decision\"`** — non-obvious choices made this session (max 3)',\n '- **`kind: \"next\"`** — concrete next steps (max 3)',\n \"\",\n 'Tag entries with the relevant area (`tags: [\"auth\"]`) and the files',\n 'they touch (`files: [\"src/auth.ts\"]`) so later `context_recall` queries',\n \"can filter. Keep each `text` to 1–2 sentences.\",\n \"\",\n \"_This block is managed by Synthra. Edits inside the BEGIN/END markers\",\n \"are overwritten on every `syn .` run._\",\n \"\",\n POLICY_END,\n ].join(\"\\n\");\n}\n\n// A lean, agent-facing onboarding skeleton written ONLY when a project has no\n// CLAUDE.md yet. It captures the durable \"why/how\" the graph can't infer\n// (build/test, conventions, decisions, gotchas). It lives OUTSIDE the\n// synthra-policy markers, so later `syn .` runs — which strip and re-add the\n// policy block — never touch what the user fills in here.\nexport function onboardingSkeleton(projectName: string): string {\n return [\n `# ${projectName}`,\n \"\",\n \"> Onboarding notes for AI coding agents. Synthra's graph already knows the\",\n \"> code's *structure* (files, symbols, imports) — this file is for what the\",\n \"> graph can't infer: how to run the project, its conventions, and the\",\n \"> decisions behind them. Keep it lean and current; delete prompts you don't need.\",\n \"\",\n \"## Build & test\",\n \"\",\n \"- TODO: install deps / build\",\n \"- TODO: run tests / lint / typecheck\",\n \"- TODO: run the app locally\",\n \"\",\n \"## Conventions\",\n \"\",\n \"- TODO: code style, naming, file layout the agent should follow\",\n \"\",\n \"## Key decisions\",\n \"\",\n '- TODO: non-obvious choices and *why* (\"we use X not Y because …\")',\n \"\",\n \"## Gotchas\",\n \"\",\n '- TODO: traps, footguns, \"don\\'t touch X without Y\"',\n \"\",\n \"_Tip: run `/init` in Claude Code to auto-draft the sections above, then trim\",\n \"to the durable bits. Synthra manages its own block below — leave it._\",\n \"\",\n ].join(\"\\n\");\n}\n\nexport async function patchClaudeMd(path: string, projectName?: string): Promise<PatchResult> {\n let existing: string | null;\n try {\n existing = await readFile(path, \"utf8\");\n } catch {\n existing = null;\n }\n\n const block = policyBlock();\n\n if (existing === null) {\n // First creation: scaffold the onboarding skeleton (user-owned, written\n // once) followed by Synthra's managed policy block.\n const name = projectName || basename(dirname(path)) || \"this project\";\n await writeFile(path, onboardingSkeleton(name) + \"\\n\" + block + \"\\n\", \"utf8\");\n return { created: true, updated: false, skipped: false };\n }\n\n const stripped = existing.replace(ANY_BLOCK_RE, \"\");\n const hadBlock = stripped !== existing;\n\n const desired = stripped.endsWith(\"\\n\")\n ? stripped + \"\\n\" + block + \"\\n\"\n : (stripped.length ? stripped + \"\\n\\n\" : \"\") + block + \"\\n\";\n\n if (hadBlock && desired === existing) {\n return { created: false, updated: false, skipped: true };\n }\n\n await writeFile(path, desired, \"utf8\");\n return { created: false, updated: true, skipped: false };\n}\n","// Stateful wrapper around the usage-learning store. Keeps the decayed aggregate\n// in memory, folds each access as it happens, persists on a trailing debounce,\n// and exposes the live scores for the ranker. Constructed once per server, like\n// ActivityStore.\n\nimport { appendAccess, readAccessLog, readLearnStore, writeLearnStore } from \"./store.js\";\nimport {\n effectiveScores,\n foldEvent,\n recomputeFromLog,\n type AccessEvent,\n type LearnStore,\n} from \"./usage.js\";\n\nconst PERSIST_DEBOUNCE_MS = 2000;\n\nexport class LearnRuntime {\n private store: LearnStore;\n private dirty = false;\n private timer: ReturnType<typeof setTimeout> | null = null;\n\n private constructor(\n private readonly accessLogPath: string,\n private readonly storePath: string,\n store: LearnStore,\n ) {\n this.store = store;\n }\n\n /** Load the aggregate from disk; if it's empty but a raw log exists, replay it\n * (the log is the source of truth). Always succeeds — falls back to empty. */\n static async load(accessLogPath: string, storePath: string): Promise<LearnRuntime> {\n let store = await readLearnStore(storePath);\n if (Object.keys(store.files).length === 0) {\n const events = await readAccessLog(accessLogPath);\n if (events.length > 0) store = recomputeFromLog(events);\n }\n return new LearnRuntime(accessLogPath, storePath, store);\n }\n\n /** Record an access: append to the durable log + fold into the in-memory\n * aggregate. Best-effort — never throws into a tool call. */\n async record(ev: AccessEvent): Promise<void> {\n await appendAccess(this.accessLogPath, ev);\n foldEvent(this.store, ev);\n this.schedulePersist();\n }\n\n /** Decayed path→weight map for the ranker, as of now. */\n effectiveScores(nowMs: number = Date.now()): Map<string, number> {\n return effectiveScores(this.store, nowMs);\n }\n\n private schedulePersist(): void {\n this.dirty = true;\n if (this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.flush();\n }, PERSIST_DEBOUNCE_MS);\n // Don't keep the event loop alive just for the persist timer.\n this.timer.unref?.();\n }\n\n /** Persist the aggregate if it changed since the last write. Called on the\n * debounce and on server shutdown. */\n async flush(): Promise<void> {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n if (!this.dirty) return;\n this.dirty = false;\n this.store.asOf = new Date().toISOString();\n await writeLearnStore(this.storePath, this.store);\n }\n}\n","// MCP-over-HTTP (streamable) protocol handler. Exposes Synthra's graph tools\n// to Claude Code via JSON-RPC 2.0 messages POSTed to /mcp.\n//\n// Tools:\n// graph_continue(query) — retrieve + pack a context bundle\n// graph_read(target) — return source for \"file\" or \"file::symbol\"\n// graph_register_edit(files) — Claude tells Synthra it edited files\n//\n// Spec: https://modelcontextprotocol.io/specification\n\nimport { appendFile, mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { retrieve } from \"../graph/retrieve.js\";\nimport type { FileNode, GraphSchema, SymbolNode } from \"../graph/types.js\";\nimport { appendAccess } from \"../learn/store.js\";\nimport type { AccessEvent } from \"../learn/usage.js\";\nimport { recallEntries, rememberEntry } from \"../memory/index.js\";\nimport type { EntryKind } from \"../memory/context-store.js\";\nimport { pack } from \"../packer/index.js\";\nimport { loadConfig } from \"../shared/config.js\";\nimport type { ServerContext } from \"./context.js\";\n\nconst PROTOCOL_VERSION = \"2024-11-05\";\nconst SERVER_INFO = { name: \"synthra\", version: \"0.0.1\" } as const;\n\ntype JsonRpcId = string | number | null;\n\nexport interface JsonRpcRequest {\n jsonrpc: \"2.0\";\n id?: JsonRpcId;\n method: string;\n params?: Record<string, unknown>;\n}\n\nexport interface JsonRpcResponse {\n jsonrpc: \"2.0\";\n id: JsonRpcId;\n result?: unknown;\n error?: { code: number; message: string; data?: unknown };\n}\n\nconst ERR = {\n parse: -32700,\n invalidRequest: -32600,\n methodNotFound: -32601,\n invalidParams: -32602,\n internal: -32603,\n} as const;\n\nfunction ok(id: JsonRpcId, result: unknown): JsonRpcResponse {\n return { jsonrpc: \"2.0\", id, result };\n}\n\nfunction err(id: JsonRpcId, code: number, message: string, data?: unknown): JsonRpcResponse {\n return { jsonrpc: \"2.0\", id, error: { code, message, data } };\n}\n\nfunction textContent(text: string) {\n return { content: [{ type: \"text\", text }], isError: false };\n}\n\nfunction errorContent(message: string) {\n return { content: [{ type: \"text\", text: message }], isError: true };\n}\n\nconst TOOLS = [\n {\n name: \"graph_continue\",\n description:\n \"Returns the project context most relevant to a query — function signatures, top function bodies, and linked test files. Use this BEFORE Grep/Glob. If `confidence` is 'high', do not call Grep/Glob for the same query.\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: {\n type: \"string\",\n description: \"Natural-language description of what you're looking for.\",\n },\n },\n required: [\"query\"],\n },\n },\n {\n name: \"graph_read\",\n description:\n \"Return the source code for a specific file or symbol. Target is either a project-relative file path (e.g. 'src/auth.ts') or 'file::symbol' (e.g. 'src/auth.ts::AuthService'). A symbol read also returns its dependency surface — the signatures of the symbols it calls (edit against these instead of guessing or re-reading their files) and the names of the symbols that call it.\",\n inputSchema: {\n type: \"object\",\n properties: {\n target: { type: \"string\", description: \"File path or file::symbol notation.\" },\n },\n required: [\"target\"],\n },\n },\n {\n name: \"graph_register_edit\",\n description:\n \"Tell Synthra that you (the AI) have edited these files. Lets Synthra rank them higher in subsequent retrieval and avoid surfacing stale context.\",\n inputSchema: {\n type: \"object\",\n properties: {\n files: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Project-relative file paths that were edited.\",\n },\n },\n required: [\"files\"],\n },\n },\n {\n name: \"context_remember\",\n description:\n \"Persist a decision/task/next-step/fact/blocker into the project's branch-aware context store. Use when the user makes a decision worth keeping, identifies a TODO, or surfaces a key fact. Entries land in `.synthra/context-store.json` on the default branch, or `.synthra/branches/<sanitized>/context-store.json` on a feature branch — git-tracked, so teammates inherit them and they merge naturally.\",\n inputSchema: {\n type: \"object\",\n properties: {\n text: { type: \"string\", description: \"The thing to remember (1–3 sentences).\" },\n kind: {\n type: \"string\",\n enum: [\"decision\", \"task\", \"next\", \"fact\", \"blocker\"],\n description: \"What kind of entry. Required.\",\n },\n tags: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Optional tags for grouping (e.g. 'auth', 'perf').\",\n },\n files: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Optional project-relative file paths this entry relates to.\",\n },\n },\n required: [\"text\", \"kind\"],\n },\n },\n {\n name: \"context_recall\",\n description:\n \"Read previously-stored decisions/tasks/facts from the project's branch-aware context store. Defaults to the current branch.\",\n inputSchema: {\n type: \"object\",\n properties: {\n kind: {\n type: \"string\",\n enum: [\"decision\", \"task\", \"next\", \"fact\", \"blocker\"],\n description: \"Filter to a single kind.\",\n },\n branch: { type: \"string\", description: \"Override which branch to read from.\" },\n limit: { type: \"number\", description: \"Return only the most recent N entries.\" },\n },\n },\n },\n {\n name: \"recent_activity\",\n description:\n \"What has the human been doing in the editor recently — file saves, branch switches, and uncommitted-diff changes. Use this to check whether the static context pack may be stale (e.g. before answering a question about a file that was just edited).\",\n inputSchema: {\n type: \"object\",\n properties: {\n since_ms: {\n type: \"number\",\n description:\n \"Epoch milliseconds. Only return events newer than this. Defaults to the last 60 minutes.\",\n },\n limit: { type: \"number\", description: \"Cap on returned events.\" },\n },\n },\n },\n {\n name: \"count_tokens\",\n description:\n \"Estimate token count for a piece of text using a char/4 approximation. Accurate within ~10% for English + code. Useful for budgeting prompt content before sending.\",\n inputSchema: {\n type: \"object\",\n properties: {\n text: { type: \"string\", description: \"The text to estimate tokens for.\" },\n },\n required: [\"text\"],\n },\n },\n {\n name: \"blast_radius\",\n description:\n \"Given a file (or 'file::symbol' target), return all files that depend on it transitively via imports, tests, and call edges (callers). Use BEFORE editing a widely-used file to see what could break. Call edges are name-resolved (precise within a file, unique-name across files) and projected to file granularity.\",\n inputSchema: {\n type: \"object\",\n properties: {\n target: { type: \"string\", description: \"File path or 'file::symbol' notation.\" },\n depth: { type: \"number\", description: \"Max hops to traverse. Default 3.\" },\n },\n required: [\"target\"],\n },\n },\n {\n name: \"dead_code\",\n description:\n \"Return files in the project that no other file imports and no test file references — strong candidates for unused/orphaned code. File-level granularity; symbol-level dead code (unused exports, on top of the call graph) is a planned follow-up. Common entry-point patterns (main, index, app, CLI, bin/) are excluded heuristically.\",\n inputSchema: {\n type: \"object\",\n properties: {\n limit: { type: \"number\", description: \"Cap on returned files. Default 50.\" },\n },\n },\n },\n] as const;\n\nasync function callTool(\n name: string,\n args: Record<string, unknown> | undefined,\n ctx: ServerContext,\n) {\n switch (name) {\n case \"graph_continue\":\n return graphContinue(args, ctx);\n case \"graph_read\":\n return graphRead(args, ctx);\n case \"graph_register_edit\":\n return graphRegisterEdit(args, ctx);\n case \"context_remember\":\n return contextRemember(args, ctx);\n case \"context_recall\":\n return contextRecall(args, ctx);\n case \"recent_activity\":\n return recentActivity(args, ctx);\n case \"count_tokens\":\n return countTokens(args);\n case \"blast_radius\":\n return blastRadius(args, ctx);\n case \"dead_code\":\n return deadCode(args, ctx);\n default:\n return errorContent(`Unknown tool: ${name}`);\n }\n}\n\nfunction countTokens(args: Record<string, unknown> | undefined) {\n const text = typeof args?.text === \"string\" ? args.text : \"\";\n if (!text) return errorContent(\"count_tokens: 'text' (string) is required\");\n const tokens = Math.ceil(text.length / 4);\n return textContent(JSON.stringify({ tokens, method: \"chars/4 estimate\", chars: text.length }));\n}\n\nfunction blastRadius(args: Record<string, unknown> | undefined, ctx: ServerContext) {\n const targetRaw = typeof args?.target === \"string\" ? args.target.trim() : \"\";\n const maxDepth = typeof args?.depth === \"number\" && args.depth > 0 ? Math.floor(args.depth) : 3;\n if (!targetRaw) return errorContent(\"blast_radius: 'target' (string) is required\");\n\n const filePath = targetRaw.split(\"::\", 1)[0]?.trim() ?? targetRaw;\n const root = ctx.graph.nodes.find((n): n is FileNode => n.kind === \"file\" && n.path === filePath);\n if (!root) return errorContent(`blast_radius: file not in graph: ${filePath}`);\n\n // Index reverse edges (to → [{from, kind}]) once per call. `calls` edges are\n // symbol→symbol, so project them to file level (a caller's file depends on the\n // callee's file), skipping intra-file calls.\n const fileIdBySymbol = new Map<string, string>();\n for (const n of ctx.graph.nodes) {\n if (n.kind === \"symbol\") fileIdBySymbol.set(n.id, `file:${n.file}`);\n }\n const incoming = new Map<string, Array<{ from: string; kind: string }>>();\n const addIncoming = (to: string, from: string, kind: string): void => {\n const list = incoming.get(to) ?? [];\n list.push({ from, kind });\n incoming.set(to, list);\n };\n for (const e of ctx.graph.edges) {\n if (e.kind === \"imports\" || e.kind === \"tests\") {\n addIncoming(e.to, e.from, e.kind);\n } else if (e.kind === \"calls\") {\n const fromFile = fileIdBySymbol.get(e.from);\n const toFile = fileIdBySymbol.get(e.to);\n if (fromFile && toFile && fromFile !== toFile) addIncoming(toFile, fromFile, \"calls\");\n }\n }\n\n interface Hit {\n path: string;\n depth: number;\n via: string;\n }\n\n const visited = new Set<string>([root.id]);\n const hits: Hit[] = [];\n const pathById = new Map<string, string>();\n for (const n of ctx.graph.nodes) if (n.kind === \"file\") pathById.set(n.id, n.path);\n\n let frontier = [root.id];\n for (let d = 1; d <= maxDepth; d++) {\n const next: string[] = [];\n for (const cur of frontier) {\n const callers = incoming.get(cur) ?? [];\n for (const c of callers) {\n if (visited.has(c.from)) continue;\n visited.add(c.from);\n next.push(c.from);\n const path = pathById.get(c.from) ?? c.from;\n hits.push({ path, depth: d, via: c.kind });\n }\n }\n frontier = next;\n if (next.length === 0) break;\n }\n\n if (hits.length === 0) {\n return textContent(`# Blast radius for ${filePath}\\n\\n_(no dependents — file is isolated)_`);\n }\n\n hits.sort((a, b) => a.depth - b.depth || a.path.localeCompare(b.path));\n const lines = [`# Blast radius for ${filePath} (depth ≤ ${maxDepth})`, \"\"];\n lines.push(`${hits.length} dependent file(s):`);\n for (const h of hits) {\n lines.push(`- **depth ${h.depth}** \\`${h.path}\\` _(via ${h.via})_`);\n }\n return textContent(lines.join(\"\\n\"));\n}\n\nconst LIKELY_ENTRY_PATTERNS = [\n /(?:^|\\/)main\\.[a-z0-9_]+$/i,\n /(?:^|\\/)index\\.[a-z0-9_]+$/i,\n /(?:^|\\/)app\\.[a-z0-9_]+$/i,\n /(?:^|\\/)entry\\.[a-z0-9_]+$/i,\n /(?:^|\\/)cli[/.]/i,\n /(?:^|\\/)bin[/.]/i,\n /(?:^|\\/)server\\.[a-z0-9_]+$/i,\n /\\.test\\.[a-z0-9_]+$/i,\n /\\.spec\\.[a-z0-9_]+$/i,\n /(?:^|\\/)tests?\\//i,\n /(?:^|\\/)__tests__\\//i,\n /(?:^|\\/)__init__\\.py$/i,\n];\n\nfunction isLikelyEntry(path: string): boolean {\n return LIKELY_ENTRY_PATTERNS.some((re) => re.test(path));\n}\n\nfunction deadCode(args: Record<string, unknown> | undefined, ctx: ServerContext) {\n const limit = typeof args?.limit === \"number\" && args.limit > 0 ? Math.floor(args.limit) : 50;\n\n const hasIncoming = new Set<string>();\n for (const e of ctx.graph.edges) {\n if (e.kind === \"imports\" || e.kind === \"tests\") hasIncoming.add(e.to);\n }\n\n const candidates = ctx.graph.nodes\n .filter((n): n is FileNode => n.kind === \"file\")\n .filter((f) => !hasIncoming.has(f.id))\n .filter((f) => !isLikelyEntry(f.path));\n\n if (candidates.length === 0) {\n return textContent(\n `# Dead code\\n\\n_(no file is unreferenced — every file is either imported by another, has a linked test, or matches an entry-point pattern)_`,\n );\n }\n\n candidates.sort((a, b) => a.path.localeCompare(b.path));\n const shown = candidates.slice(0, limit);\n const lines = [`# Dead code candidates (file-level, v0.1)`, \"\"];\n lines.push(\n `${shown.length} of ${candidates.length} unreferenced file(s) — no other file imports them and no test links them:`,\n );\n lines.push(\"\");\n for (const f of shown) {\n lines.push(`- \\`${f.path}\\``);\n }\n lines.push(\"\");\n lines.push(\n `_caveat:_ this is file-level only. Symbol-level dead code (unused exports), built on the now-populated call graph, is a planned follow-up.`,\n );\n return textContent(lines.join(\"\\n\"));\n}\n\nasync function graphContinue(args: Record<string, unknown> | undefined, ctx: ServerContext) {\n const query = typeof args?.query === \"string\" ? args.query : \"\";\n if (!query) return errorContent(\"graph_continue: 'query' (string) is required\");\n\n // Session-aware routing (#14): seed retrieval with files the session has\n // touched — the human's recent saves + edits the AI registered via\n // graph_register_edit — so the ranker boosts them. Mirrors the /pack route.\n const retrieval = await retrieve(ctx.graph, query, {\n recentlyEditedPaths: ctx.activity.recentFilePaths(15 * 60 * 1000),\n sessionKnownPaths: getRegisteredEdits(),\n usageScores: ctx.learn?.effectiveScores(),\n });\n const packed = await pack(retrieval.files, { query, graph: ctx.graph });\n\n // Log the query (no file, weight 0) as query→outcome fuel for a future\n // mechanism — never count retrieval.files, which would feed ranking its own\n // output and cause popularity runaway.\n await logAccess(ctx, { ts: nowIso(), path: \"\", source: \"continue\", query });\n\n const header =\n `Confidence: ${retrieval.confidence}\\n` +\n `Files: ${retrieval.files.map((f) => f.path).join(\", \") || \"(none)\"}\\n` +\n `Reason: ${retrieval.reason}\\n`;\n\n // The pack body already starts with a header — keep them concatenated.\n return textContent(`${header}\\n${packed.text}`);\n}\n\n// Resolve a graph_read target's file part to a FileNode. Exact path wins; on a\n// miss, fall back to a unique path-suffix match so a shortened target like\n// \"appsettings.json\" finds \"api/.../appsettings.json\". Only serves the fallback\n// when EXACTLY one file matches — multiple matches are reported as ambiguous\n// rather than guessing. (#11)\nexport type FileTargetResult = { node: FileNode } | { ambiguous: string[] } | { none: true };\n\nexport function resolveFileTarget(graph: GraphSchema, filePath: string): FileTargetResult {\n const files = graph.nodes.filter((n): n is FileNode => n.kind === \"file\");\n const exact = files.find((n) => n.path === filePath);\n if (exact) return { node: exact };\n\n const suffix = \"/\" + filePath;\n const matches = files.filter((n) => n.path.endsWith(suffix));\n if (matches.length === 1) return { node: matches[0]! };\n if (matches.length > 1) return { ambiguous: matches.map((n) => n.path) };\n return { none: true };\n}\n\nconst DEPS_SIG_MAX = 140;\nconst DEPS_MAX_CALLEES = 10;\nconst DEPS_MAX_CALLERS = 12;\n\n/**\n * Dependency surface for a symbol, rendered as a point-of-use footer for\n * graph_read: the symbols it CALLS (with full signatures + graph_read targets —\n * so the agent edits against real signatures instead of guessing or re-reading\n * the callee files) and the symbols that CALL it (names only — cheap \"a change\n * here affects these\" awareness). Built from the v0.3.0 symbol→symbol `calls`\n * edges. Returns \"\" when the symbol has no call edges (leaf — keep reads lean).\n */\nexport function buildDepsFooter(\n symbol: SymbolNode,\n graph: GraphSchema,\n maxChars = loadConfig().readDepsMaxChars,\n): string {\n const symById = new Map<string, SymbolNode>();\n for (const n of graph.nodes) if (n.kind === \"symbol\") symById.set(n.id, n);\n\n const calleeIds: string[] = [];\n const callerIds: string[] = [];\n const seenCallee = new Set<string>();\n const seenCaller = new Set<string>();\n for (const e of graph.edges) {\n if (e.kind !== \"calls\") continue;\n if (e.from === symbol.id && e.to !== symbol.id && !seenCallee.has(e.to)) {\n seenCallee.add(e.to);\n calleeIds.push(e.to);\n } else if (e.to === symbol.id && e.from !== symbol.id && !seenCaller.has(e.from)) {\n seenCaller.add(e.from);\n callerIds.push(e.from);\n }\n }\n\n const resolve = (ids: string[]): SymbolNode[] =>\n ids.map((id) => symById.get(id)).filter((n): n is SymbolNode => !!n);\n const callees = resolve(calleeIds).sort((a, b) =>\n a.file === b.file ? a.start_line - b.start_line : a.file < b.file ? -1 : 1,\n );\n const callers = resolve(callerIds);\n\n if (callees.length === 0 && callers.length === 0) return \"\";\n\n const lines: string[] = [];\n let used = 0;\n\n if (callees.length > 0) {\n const head = \"Depends on (signatures — don't guess these):\";\n lines.push(head);\n used += head.length + 1;\n let shown = 0;\n for (const c of callees.slice(0, DEPS_MAX_CALLEES)) {\n const sig = c.signature.trim().slice(0, DEPS_SIG_MAX);\n const entry = `• ${sig} → mcp__synthra__graph_read(\"${c.file}::${c.name}\")`;\n if (used + entry.length + 1 > maxChars) break;\n lines.push(entry);\n used += entry.length + 1;\n shown += 1;\n }\n const omitted = callees.length - shown;\n if (omitted > 0) lines.push(`…+${omitted} more`);\n }\n\n if (callers.length > 0) {\n const sep = lines.length > 0 ? 1 : 0;\n const head = `Used by (${callers.length}): `;\n const shown: string[] = [];\n let cUsed = used + sep + head.length;\n for (const c of callers.slice(0, DEPS_MAX_CALLERS)) {\n const part = `${c.name} → ${c.file}`;\n const join = shown.length > 0 ? 3 : 0; // \" · \"\n if (cUsed + join + part.length > maxChars) break;\n shown.push(part);\n cUsed += join + part.length;\n }\n if (lines.length > 0) lines.push(\"\");\n if (shown.length > 0) {\n const omitted = callers.length - shown.length;\n lines.push(head + shown.join(\" · \") + (omitted > 0 ? ` …+${omitted} more` : \"\"));\n } else {\n lines.push(`Used by (${callers.length} callers)`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nasync function graphRead(args: Record<string, unknown> | undefined, ctx: ServerContext) {\n const target = typeof args?.target === \"string\" ? args.target : \"\";\n if (!target) return errorContent(\"graph_read: 'target' (string) is required\");\n\n const [rawFile, symbolName] = target.includes(\"::\") ? target.split(\"::\", 2) : [target, undefined];\n const filePath = (rawFile ?? \"\").trim();\n\n const resolved = resolveFileTarget(ctx.graph, filePath);\n if (\"ambiguous\" in resolved) {\n const shown = resolved.ambiguous.slice(0, 5).join(\", \");\n const more = resolved.ambiguous.length > 5 ? \", …\" : \"\";\n return errorContent(\n `graph_read: '${filePath}' matches multiple files (${shown}${more}). Pass a longer path.`,\n );\n }\n if (\"none\" in resolved) {\n return errorContent(`graph_read: file not found in graph: ${filePath}`);\n }\n const fileNode = resolved.node;\n\n // The AI deliberately pulled this file — the strongest \"this matters\" signal\n // short of an edit. Feed it to the learning layer.\n await logAccess(ctx, { ts: nowIso(), path: fileNode.path, source: \"read\" });\n\n if (!symbolName) {\n return textContent(`# ${fileNode.path}\\n\\n${fileNode.content}`);\n }\n\n const cleanSym = symbolName.trim();\n const symbol = ctx.graph.nodes.find(\n (n): n is SymbolNode => n.kind === \"symbol\" && n.file === fileNode.path && n.name === cleanSym,\n );\n if (!symbol) {\n return errorContent(`graph_read: symbol '${cleanSym}' not found in ${fileNode.path}`);\n }\n\n const lines = fileNode.content.split(/\\r?\\n/);\n const body = lines.slice(symbol.start_line - 1, symbol.end_line).join(\"\\n\");\n\n // Point-of-use edit recipe. Claude Code's Edit tool only accepts a file\n // opened with its own Read tool — this slice doesn't satisfy that gate — so\n // without this nudge agents re-Read the whole file before editing (the\n // dogfood log's biggest token leak: the same large file Read 15-19× a\n // session). Hand them the exact targeted Read that satisfies the gate cheaply,\n // with 2 lines of headroom each side for off-by-one safety + unique Edit context.\n const offset = Math.max(1, symbol.start_line - 2);\n const limit = symbol.end_line - symbol.start_line + 1 + 4;\n const editHint =\n `\\n\\n---\\n✎ To edit this symbol: Read(\"${fileNode.path}\", offset=${offset}, limit=${limit}) ` +\n `then Edit — that satisfies Claude Code's read-gate at ~${limit} lines; do NOT re-read the whole file.`;\n\n const deps = buildDepsFooter(symbol, ctx.graph);\n const depsBlock = deps ? `\\n\\n---\\n${deps}` : \"\";\n\n return textContent(\n `# ${fileNode.path}::${symbol.name} (L${symbol.start_line}-${symbol.end_line})\\n\\n${body}${depsBlock}${editHint}`,\n );\n}\n\nconst editedFiles = new Set<string>();\n\nasync function graphRegisterEdit(args: Record<string, unknown> | undefined, ctx: ServerContext) {\n const files = Array.isArray(args?.files)\n ? (args.files as unknown[]).filter((f) => typeof f === \"string\")\n : [];\n for (const f of files) {\n const file = f as string;\n editedFiles.add(file);\n // An edit is the strongest relevance signal — record it (weight 2). Resolve\n // to the canonical graph path so it keys to the same node the ranker scores;\n // a new/renamed file simply logs its raw path and decays out if unmatched.\n const resolved = resolveFileTarget(ctx.graph, file);\n await logAccess(ctx, {\n ts: nowIso(),\n path: \"node\" in resolved ? resolved.node.path : file,\n source: \"register_edit\",\n });\n }\n return textContent(\n `Registered ${files.length} edited file(s). Total tracked this session: ${editedFiles.size}.`,\n );\n}\n\nexport function getRegisteredEdits(): string[] {\n return Array.from(editedFiles);\n}\n\nconst VALID_KINDS = new Set<EntryKind>([\"decision\", \"task\", \"next\", \"fact\", \"blocker\"]);\n\nasync function contextRemember(args: Record<string, unknown> | undefined, ctx: ServerContext) {\n const text = typeof args?.text === \"string\" ? args.text.trim() : \"\";\n const kindRaw = typeof args?.kind === \"string\" ? args.kind : \"\";\n if (!text) return errorContent(\"context_remember: 'text' (string) is required\");\n if (!VALID_KINDS.has(kindRaw as EntryKind)) {\n return errorContent(\n `context_remember: 'kind' must be one of ${Array.from(VALID_KINDS).join(\", \")}`,\n );\n }\n const tags = Array.isArray(args?.tags)\n ? (args.tags as unknown[]).filter((t): t is string => typeof t === \"string\")\n : [];\n const files = Array.isArray(args?.files)\n ? (args.files as unknown[]).filter((f): f is string => typeof f === \"string\")\n : [];\n\n const result = await rememberEntry(ctx.paths, {\n text,\n kind: kindRaw as EntryKind,\n tags,\n files,\n });\n\n return textContent(\n `Remembered ${result.entry.type} on branch '${result.branch}'.\\n` +\n `Stored: ${result.storePath}\\n` +\n `CONTEXT.md refreshed: ${result.contextMdPath}`,\n );\n}\n\nconst DEFAULT_RECENT_WINDOW_MS = 60 * 60 * 1000;\n\nfunction recentActivity(args: Record<string, unknown> | undefined, ctx: ServerContext) {\n const sinceMs =\n typeof args?.since_ms === \"number\" && Number.isFinite(args.since_ms)\n ? args.since_ms\n : Date.now() - DEFAULT_RECENT_WINDOW_MS;\n const limit =\n typeof args?.limit === \"number\" && args.limit > 0 ? Math.floor(args.limit) : undefined;\n\n let events = ctx.activity.getEvents(sinceMs);\n if (limit) events = events.slice(-limit);\n\n if (events.length === 0) {\n return textContent(`No human-activity events since ${new Date(sinceMs).toISOString()}.`);\n }\n\n const lines = [`# Recent human activity (${events.length} events)`, \"\"];\n for (const e of events) {\n if (\"path\" in e) {\n lines.push(`- **${e.kind}** ${e.path} _(${e.ts})_`);\n } else {\n const summary = JSON.stringify(e.details);\n lines.push(`- **${e.kind}** ${summary} _(${e.ts})_`);\n }\n }\n return textContent(lines.join(\"\\n\"));\n}\n\nasync function contextRecall(args: Record<string, unknown> | undefined, ctx: ServerContext) {\n const kind =\n typeof args?.kind === \"string\" && VALID_KINDS.has(args.kind as EntryKind)\n ? (args.kind as EntryKind)\n : undefined;\n const branch = typeof args?.branch === \"string\" ? args.branch : undefined;\n const limit =\n typeof args?.limit === \"number\" && args.limit > 0 ? Math.floor(args.limit) : undefined;\n\n const result = await recallEntries(ctx.paths, { kind, branch, limit });\n\n if (result.entries.length === 0) {\n const filter = kind ? ` of kind '${kind}'` : \"\";\n return textContent(`No context entries${filter} on branch '${result.branch}'.`);\n }\n\n const lines = [`# Context entries — branch: ${result.branch}`, \"\"];\n for (const e of result.entries) {\n const tags = e.tags.length ? ` [${e.tags.join(\", \")}]` : \"\";\n lines.push(`- **${e.type}**${tags} (${e.date}): ${e.content}`);\n if (e.files.length) lines.push(` files: ${e.files.join(\", \")}`);\n }\n return textContent(lines.join(\"\\n\"));\n}\n\n// Best-effort per-call log of Synthra MCP tool usage — powers the dashboard's\n// graph-tool-usage metric (#2). A positive signal (how often the graph was\n// actually used) vs the blocked-Grep proxy, which misses well-behaved pivots.\nasync function logToolCall(ctx: ServerContext, tool: string): Promise<void> {\n try {\n await mkdir(dirname(ctx.paths.toolLog), { recursive: true });\n await appendFile(\n ctx.paths.toolLog,\n JSON.stringify({ ts: new Date().toISOString(), tool }) + \"\\n\",\n \"utf8\",\n );\n } catch {\n // Logging is best-effort; never fail a tool call over it.\n }\n}\n\n// Best-effort per-file usage capture (learning layer). Routes through the learn\n// runtime when present (folds the decayed aggregate in memory + appends the raw\n// log); otherwise appends the raw log directly so a runtime-less context (tests,\n// CLI) still records signal. Never throws — callers await it but its own errors\n// are swallowed, so telemetry can never fail a tool call.\nasync function logAccess(ctx: ServerContext, ev: AccessEvent): Promise<void> {\n try {\n if (ctx.learn) await ctx.learn.record(ev);\n else await appendAccess(ctx.paths.accessLog, ev);\n } catch {\n // best-effort\n }\n}\n\nfunction nowIso(): string {\n return new Date().toISOString();\n}\n\nexport async function handleMcpRequest(\n body: unknown,\n ctx: ServerContext,\n): Promise<JsonRpcResponse> {\n if (!body || typeof body !== \"object\") {\n return err(null, ERR.invalidRequest, \"Request body must be a JSON-RPC 2.0 object.\");\n }\n\n const req = body as JsonRpcRequest;\n if (req.jsonrpc !== \"2.0\" || typeof req.method !== \"string\") {\n return err(req.id ?? null, ERR.invalidRequest, \"Invalid JSON-RPC envelope.\");\n }\n\n const id = req.id ?? null;\n\n try {\n switch (req.method) {\n case \"initialize\":\n return ok(id, {\n protocolVersion:\n typeof req.params?.protocolVersion === \"string\"\n ? req.params.protocolVersion\n : PROTOCOL_VERSION,\n capabilities: { tools: {} },\n serverInfo: SERVER_INFO,\n });\n\n case \"notifications/initialized\":\n // Client confirms initialization. No response required for notifications (id===undefined).\n return ok(id, {});\n\n case \"tools/list\":\n return ok(id, { tools: TOOLS });\n\n case \"tools/call\": {\n const params = req.params ?? {};\n const toolName = typeof params.name === \"string\" ? params.name : \"\";\n if (!toolName) return err(id, ERR.invalidParams, \"'name' is required for tools/call.\");\n const args =\n params.arguments && typeof params.arguments === \"object\"\n ? (params.arguments as Record<string, unknown>)\n : {};\n void logToolCall(ctx, toolName);\n const result = await callTool(toolName, args, ctx);\n return ok(id, result);\n }\n\n case \"ping\":\n return ok(id, {});\n\n default:\n return err(id, ERR.methodNotFound, `Method not found: ${req.method}`);\n }\n } catch (e) {\n return err(id, ERR.internal, (e as Error).message);\n }\n}\n\n// Exposed for code that wants to enumerate the tool catalogue without going\n// through JSON-RPC (e.g. CLI introspection in M3).\nexport function listTools(): Array<{ name: string; description: string; inputSchema: unknown }> {\n return TOOLS.map((t) => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n }));\n}\n","// Scoring for retrieved files. Combines:\n// - keyword overlap with the (already-tokenized) query\n// - symbol-name overlap (boosted: hits in a file's defined symbols matter more)\n// - import-graph proximity from session-known + recent paths (boost adjacent files)\n// - recency boost from activity log (placeholder — wired in M5)\n\nimport type { Edge, FileNode, GraphSchema, SymbolNode } from \"./types.js\";\n\nexport interface RankInputs {\n candidates: FileNode[];\n query: string;\n graph?: GraphSchema;\n recentlyEditedPaths?: string[];\n sessionKnownPaths?: string[];\n /** Decayed per-file usage weights (path → weight) from the learning layer.\n * Applied as a bounded boost to files that ALREADY match the query. Omit to\n * disable (the ranker is then byte-identical to its deterministic form). */\n usageScores?: ReadonlyMap<string, number>;\n}\n\n// Base weight for a keyword match. The IDF reweighting is normalized to the\n// query's mean IDF, so a \"typical\"-rarity match contributes exactly this — which\n// preserves today's score magnitude (and the confidence/Moat calibration that\n// depends on it) while letting rarer terms score above and common terms below.\nconst KW_BASE_WEIGHT = 2;\n\n// Max additive usage boost. Strictly below the +5 seed boost so a maxed-out\n// usage signal can reorder within a relevance band but never leapfrog a freshly\n// seeded file or two exact symbol matches (+6). Env-overridable for tuning.\nconst USAGE_BOOST_CAP_DEFAULT = 4;\n\nfunction usageBoostCap(): number {\n const env = Number(process.env.SYN_LEARN_BOOST_CAP);\n return Number.isFinite(env) && env >= 0 ? env : USAGE_BOOST_CAP_DEFAULT;\n}\n\nexport interface ScoredFile {\n file: FileNode;\n score: number;\n reasons: string[];\n /** Total symbol-match weight (exact name = 3, partial substring = 1). */\n symHits: number;\n /** Count of symbols whose name a query token matched *exactly*. The gate\n * uses this — a partial substring match is too noisy (\"id\" ⊂ \"width\"). */\n exactSym: number;\n}\n\nconst STOPWORDS = new Set([\n \"a\",\n \"an\",\n \"and\",\n \"are\",\n \"as\",\n \"at\",\n \"be\",\n \"by\",\n \"for\",\n \"from\",\n \"has\",\n \"have\",\n \"in\",\n \"is\",\n \"it\",\n \"of\",\n \"on\",\n \"or\",\n \"that\",\n \"the\",\n \"this\",\n \"to\",\n \"was\",\n \"we\",\n \"with\",\n \"what\",\n \"where\",\n \"when\",\n \"why\",\n \"how\",\n \"do\",\n \"does\",\n \"i\",\n \"me\",\n \"my\",\n \"you\",\n \"your\",\n \"code\",\n \"file\",\n]);\n\nexport function tokenizeQuery(query: string): string[] {\n const tokens = query\n .toLowerCase()\n .split(/[^a-z0-9_]+/g)\n .filter((t) => t.length > 1 && !STOPWORDS.has(t));\n // Also split camelCase/snake_case for queries like \"AuthService\"\n const expanded = new Set<string>();\n for (const t of tokens) {\n expanded.add(t);\n const parts = t.match(/[a-z]+|[0-9]+/g) ?? [];\n for (const p of parts) if (p.length > 1) expanded.add(p);\n }\n return Array.from(expanded);\n}\n\nfunction indexSymbolsByFile(graph: GraphSchema | undefined): Map<string, SymbolNode[]> {\n const out = new Map<string, SymbolNode[]>();\n if (!graph) return out;\n for (const n of graph.nodes) {\n if (n.kind !== \"symbol\") continue;\n const list = out.get(n.file) ?? [];\n list.push(n);\n out.set(n.file, list);\n }\n return out;\n}\n\nfunction indexImportEdges(graph: GraphSchema | undefined): Map<string, Set<string>> {\n // file path → set of file paths it imports (1-hop)\n const out = new Map<string, Set<string>>();\n if (!graph) return out;\n const idToPath = new Map<string, string>();\n for (const n of graph.nodes) if (n.kind === \"file\") idToPath.set(n.id, n.path);\n for (const e of graph.edges as Edge[]) {\n if (e.kind !== \"imports\") continue;\n const from = idToPath.get(e.from);\n const to = idToPath.get(e.to);\n if (!from || !to) continue;\n const s = out.get(from) ?? new Set<string>();\n s.add(to);\n out.set(from, s);\n }\n return out;\n}\n\nexport function scoreFiles(inputs: RankInputs): ScoredFile[] {\n const qTokens = new Set(tokenizeQuery(inputs.query));\n const symbolsByFile = indexSymbolsByFile(inputs.graph);\n const importsFrom = indexImportEdges(inputs.graph);\n\n const seeds = new Set<string>(inputs.sessionKnownPaths ?? []);\n for (const p of inputs.recentlyEditedPaths ?? []) seeds.add(p);\n\n // IDF weighting for keyword matches — the part of BM25 that fits our deduped\n // top-N keyword representation (TF saturation / length-norm collapse here). A\n // query token that's rare across the repo counts for more than a common one.\n // Document frequency is computed over the candidate corpus for the query's\n // tokens only; `refIdf` (the query's mean IDF) normalizes the weighting so a\n // typical match still scores KW_BASE_WEIGHT — preserving the overall magnitude\n // and the confidence/Moat calibration, while reordering within the band.\n const corpusSize = inputs.candidates.length;\n const queryDf = new Map<string, number>();\n for (const f of inputs.candidates) {\n for (const kw of f.keywords) {\n if (qTokens.has(kw)) queryDf.set(kw, (queryDf.get(kw) ?? 0) + 1);\n }\n }\n const idf = (token: string): number => {\n const n = queryDf.get(token) ?? 0;\n if (n <= 0) return 0;\n return Math.log(1 + (corpusSize - n + 0.5) / (n + 0.5));\n };\n let idfSum = 0;\n let idfCount = 0;\n for (const t of qTokens) {\n const v = idf(t);\n if (v > 0) {\n idfSum += v;\n idfCount += 1;\n }\n }\n const refIdf = idfCount > 0 ? idfSum / idfCount : 1;\n\n // First pass: keyword + symbol score\n const scored: ScoredFile[] = [];\n for (const file of inputs.candidates) {\n const reasons: string[] = [];\n let score = 0;\n\n // Keyword overlap, IDF-weighted so a match on a rare query term outranks a\n // match on a common one (normalized to refIdf → magnitude-preserving).\n let kwHits = 0;\n let kwScore = 0;\n for (const kw of file.keywords) {\n if (!qTokens.has(kw)) continue;\n kwHits += 1;\n kwScore += KW_BASE_WEIGHT * (idf(kw) / refIdf);\n }\n if (kwHits) {\n score += kwScore;\n reasons.push(`kw=${kwHits}`);\n }\n\n // Symbol-name overlap (higher signal than file-level keywords)\n const symbols = symbolsByFile.get(file.path) ?? [];\n let symHits = 0;\n let exactSym = 0;\n for (const sym of symbols) {\n const name = sym.name.toLowerCase();\n if (qTokens.has(name)) {\n symHits += 3;\n exactSym += 1;\n } else {\n // partial match: any query token is a substring of, or contained by, the symbol name\n for (const t of qTokens) {\n if (name.includes(t) || t.includes(name)) {\n symHits += 1;\n break;\n }\n }\n }\n }\n if (symHits) {\n score += symHits;\n reasons.push(`sym=${symHits}`);\n }\n\n // Path match: file path contains a query token\n const pathLower = file.path.toLowerCase();\n let pathHits = 0;\n for (const t of qTokens) if (pathLower.includes(t)) pathHits += 1;\n if (pathHits) {\n score += pathHits;\n reasons.push(`path=${pathHits}`);\n }\n\n if (seeds.has(file.path)) {\n score += 5;\n reasons.push(\"seed\");\n }\n\n scored.push({ file, score, reasons, symHits, exactSym });\n }\n\n // Second pass: 1-hop import-graph boost from any file already scored > 0\n const positivePaths = new Set(scored.filter((s) => s.score > 0).map((s) => s.file.path));\n if (positivePaths.size > 0) {\n for (const s of scored) {\n if (s.score > 0) continue;\n // Does any file that imports this one have a positive score?\n let importBoost = 0;\n for (const [from, tos] of importsFrom) {\n if (!positivePaths.has(from)) continue;\n if (tos.has(s.file.path)) {\n importBoost += 1;\n break;\n }\n }\n if (importBoost) {\n s.score += importBoost * 0.5;\n s.reasons.push(\"imp-adj\");\n }\n }\n }\n\n // Usage-learning boost (learning v1): files the session has actually pulled or\n // edited get a small, decayed, capped bump so genuinely-hot files surface\n // first. Anchored to files that already match the query (score > 0) so a\n // popular-but-irrelevant file is never promoted; relatively normalized (u/maxU)\n // and capped below the +5 seed so it reorders within a band, never dominates.\n const usage = inputs.usageScores;\n if (usage && usage.size > 0) {\n let maxU = 0;\n for (const v of usage.values()) if (v > maxU) maxU = v;\n if (maxU > 0) {\n const cap = usageBoostCap();\n for (const s of scored) {\n if (s.score <= 0) continue;\n const u = usage.get(s.file.path) ?? 0;\n if (u <= 0) continue;\n s.score += cap * (u / maxU);\n s.reasons.push(`used×${Math.round(u)}`);\n }\n }\n }\n\n scored.sort((a, b) => b.score - a.score);\n return scored;\n}\n\nexport function rank(inputs: RankInputs): FileNode[] {\n return scoreFiles(inputs).map((s) => s.file);\n}\n","// Query-time retrieval. Given a natural-language query (or a symbol name),\n// returns a ranked list of FileNodes plus a confidence label.\n\nimport { scoreFiles, tokenizeQuery, type RankInputs } from \"./rank.js\";\nimport type { FileNode, GraphSchema } from \"./types.js\";\n\nexport interface RetrievalResult {\n files: FileNode[];\n confidence: \"high\" | \"medium\" | \"low\";\n reason: string;\n /** True if any returned file has a symbol whose name a query token matched\n * exactly — i.e. graph_read can serve a real `file::symbol` slice for this\n * query. When false, a Grep/Glob block would only force a fallback Read. */\n symbolMatched: boolean;\n}\n\nexport interface RetrieveOptions {\n topK?: number;\n recentlyEditedPaths?: string[];\n sessionKnownPaths?: string[];\n /** Decayed per-file usage weights from the learning layer. Passed straight\n * through to the ranker as a bounded boost on already-matching files. */\n usageScores?: ReadonlyMap<string, number>;\n}\n\nexport async function retrieve(\n graph: GraphSchema,\n query: string,\n options: RetrieveOptions = {},\n): Promise<RetrievalResult> {\n const topK = options.topK ?? 12;\n const qTokens = tokenizeQuery(query);\n\n const allFiles: FileNode[] = graph.nodes.filter((n): n is FileNode => n.kind === \"file\");\n\n if (allFiles.length === 0 || qTokens.length === 0) {\n return {\n files: [],\n confidence: \"low\",\n reason: qTokens.length === 0 ? \"empty query\" : \"empty graph\",\n symbolMatched: false,\n };\n }\n\n const rankInputs: RankInputs = {\n candidates: allFiles,\n query,\n graph,\n recentlyEditedPaths: options.recentlyEditedPaths,\n sessionKnownPaths: options.sessionKnownPaths,\n usageScores: options.usageScores,\n };\n const scored = scoreFiles(rankInputs);\n const positive = scored.filter((s) => s.score > 0);\n\n if (positive.length === 0) {\n return {\n files: [],\n confidence: \"low\",\n reason: `no matches for ${JSON.stringify(qTokens)}`,\n symbolMatched: false,\n };\n }\n\n const topScored = positive.slice(0, topK);\n const top = topScored.map((s) => s.file);\n const symbolMatched = topScored.some((s) => s.exactSym > 0);\n const topScore = positive[0]?.score ?? 0;\n const secondScore = positive[1]?.score ?? 0;\n\n // confidence: high = clear top match (2x next or only one hit)\n // medium = several hits but no dominant one\n // low = a few weak hits\n let confidence: \"high\" | \"medium\" | \"low\";\n if (positive.length === 1) confidence = \"high\";\n else if (topScore >= 6 && topScore >= secondScore * 2) confidence = \"high\";\n else if (topScore >= 3) confidence = \"medium\";\n else confidence = \"low\";\n\n const reasons = positive\n .slice(0, Math.min(3, top.length))\n .map((s) => `${s.file.path} (${s.reasons.join(\",\")})`)\n .join(\"; \");\n\n return {\n files: top,\n confidence,\n reason: `top: ${reasons}`,\n symbolMatched,\n };\n}\n","// Branch-aware routing for the context store.\n// On the default branch, reads/writes go to .synthra/context-store.json.\n// On a feature branch, they go to .synthra/branches/<sanitized-branch>/context-store.json.\n\nimport { execFile } from \"node:child_process\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\nexport async function currentBranch(projectRoot: string): Promise<string> {\n // Try .git/HEAD first — avoids the subprocess cost and works for detached\n // worktrees too (.git is a file there).\n try {\n const headPath = join(projectRoot, \".git\", \"HEAD\");\n const head = await readFile(headPath, \"utf8\");\n const trimmed = head.trim();\n const match = trimmed.match(/^ref:\\s+refs\\/heads\\/(.+)$/);\n if (match?.[1]) return match[1];\n // Detached HEAD — fall through\n } catch {\n // .git/HEAD unreadable (worktree file, submodule, or not a git repo)\n }\n\n try {\n const { stdout } = await execFileAsync(\"git\", [\"branch\", \"--show-current\"], {\n cwd: projectRoot,\n });\n const name = stdout.trim();\n if (name) return name;\n } catch {\n // git not on PATH or not a repo\n }\n\n return \"main\";\n}\n\nexport async function defaultBranch(projectRoot: string): Promise<string> {\n try {\n const { stdout } = await execFileAsync(\n \"git\",\n [\"symbolic-ref\", \"refs/remotes/origin/HEAD\", \"--short\"],\n { cwd: projectRoot },\n );\n const trimmed = stdout.trim();\n const match = trimmed.match(/^origin\\/(.+)$/);\n if (match?.[1]) return match[1];\n } catch {\n // No origin/HEAD set — fall back to heuristic\n }\n return \"main\";\n}\n\nexport function sanitizeBranchName(name: string): string {\n return name.replaceAll(\"/\", \"-\").replaceAll(\"\\\\\", \"-\");\n}\n\nexport interface BranchScopedPaths {\n contextStore: string;\n contextMd: string;\n branchDir: string | null;\n}\n\nexport function resolveBranchPaths(\n contextDir: string,\n branch: string,\n isDefault: boolean,\n): BranchScopedPaths {\n if (isDefault) {\n return {\n contextStore: join(contextDir, \"context-store.json\"),\n contextMd: join(contextDir, \"CONTEXT.md\"),\n branchDir: null,\n };\n }\n const branchDir = join(contextDir, \"branches\", sanitizeBranchName(branch));\n return {\n contextStore: join(branchDir, \"context-store.json\"),\n contextMd: join(branchDir, \"CONTEXT.md\"),\n branchDir,\n };\n}\n","// Free-form CONTEXT.md narrative. Updated by Stop hook at session end with:\n// - Current Task (1 sentence)\n// - Key Decisions (max 3 bullets)\n// - Next Steps (max 3 bullets)\n// Capped at ~20 visible content lines.\n\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport type { ContextEntry } from \"./context-store.js\";\n\nexport interface ContextMd {\n branch: string;\n currentTask: string;\n keyDecisions: string[];\n nextSteps: string[];\n date: string;\n}\n\nconst MAX_BULLETS = 3;\n\nexport function deriveContextMd(entries: ContextEntry[], branch: string): ContextMd {\n // Latest pending task drives \"current task\".\n const tasks = entries.filter((e) => e.type === \"task\").reverse();\n const currentTask = tasks[0]?.content ?? \"\";\n\n const keyDecisions = entries\n .filter((e) => e.type === \"decision\")\n .slice(-MAX_BULLETS)\n .map((e) => e.content);\n\n const nextSteps = entries\n .filter((e) => e.type === \"next\")\n .slice(-MAX_BULLETS)\n .map((e) => e.content);\n\n return {\n branch,\n currentTask,\n keyDecisions,\n nextSteps,\n date: new Date().toISOString(),\n };\n}\n\nexport function formatContextMd(ctx: ContextMd): string {\n const lines: string[] = [];\n lines.push(`# Context — ${ctx.branch}`);\n lines.push(\"\");\n lines.push(`_Updated: ${ctx.date}_`);\n lines.push(\"\");\n\n if (ctx.currentTask) {\n lines.push(`## Current task`);\n lines.push(ctx.currentTask);\n lines.push(\"\");\n }\n\n if (ctx.keyDecisions.length) {\n lines.push(`## Key decisions`);\n for (const d of ctx.keyDecisions) lines.push(`- ${d}`);\n lines.push(\"\");\n }\n\n if (ctx.nextSteps.length) {\n lines.push(`## Next steps`);\n for (const n of ctx.nextSteps) lines.push(`- ${n}`);\n lines.push(\"\");\n }\n\n if (!ctx.currentTask && !ctx.keyDecisions.length && !ctx.nextSteps.length) {\n lines.push(\"_(no context entries yet — use `context_remember` to add one)_\");\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n\nexport async function writeContextMd(path: string, ctx: ContextMd): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, formatContextMd(ctx), \"utf8\");\n}\n\nexport async function readContextMd(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf8\");\n } catch {\n return null;\n }\n}\n","// Structured decisions/tasks/facts that persist across sessions.\n// Stored in .synthra/ (GIT-TRACKED) so teammates inherit them.\n// Branch-partitioned via branches.ts.\n\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nexport type EntryKind = \"decision\" | \"task\" | \"next\" | \"fact\" | \"blocker\";\n\nexport interface ContextEntry {\n type: EntryKind;\n content: string;\n tags: string[];\n files: string[];\n date: string;\n /** Provenance. Reserved for v2 auto-capture; v1 only writes manual entries, so\n * the field is omitted today and read back as undefined (treated as manual). */\n source?: \"manual\" | \"auto\";\n}\n\ninterface Store {\n schema_version: number;\n entries: ContextEntry[];\n}\n\nconst SCHEMA_VERSION = 1;\n\nexport async function readEntries(path: string): Promise<ContextEntry[]> {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<Store>;\n return Array.isArray(parsed.entries) ? parsed.entries : [];\n } catch {\n return [];\n }\n}\n\nexport async function writeEntries(path: string, entries: ContextEntry[]): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n const store: Store = { schema_version: SCHEMA_VERSION, entries };\n await writeFile(path, JSON.stringify(store, null, 2) + \"\\n\", \"utf8\");\n}\n\nexport async function appendEntry(path: string, entry: ContextEntry): Promise<void> {\n const entries = await readEntries(path);\n entries.push(entry);\n await writeEntries(path, entries);\n}\n","// High-level orchestration: branch detection + store routing + CONTEXT.md\n// refresh in one call. Used by the MCP tools and the /context-update route.\n\nimport type { SynthraPaths } from \"../shared/paths.js\";\nimport {\n currentBranch,\n defaultBranch,\n resolveBranchPaths,\n type BranchScopedPaths,\n} from \"./branches.js\";\nimport { deriveContextMd, writeContextMd } from \"./context-md.js\";\nimport { appendEntry, readEntries, type ContextEntry, type EntryKind } from \"./context-store.js\";\n\nexport interface ActiveBranch {\n branch: string;\n isDefault: boolean;\n paths: BranchScopedPaths;\n}\n\nexport async function resolveActiveBranch(\n paths: SynthraPaths,\n override?: string,\n): Promise<ActiveBranch> {\n const branch = override ?? (await currentBranch(paths.projectRoot));\n const def = await defaultBranch(paths.projectRoot);\n const isDefault = branch === def;\n return {\n branch,\n isDefault,\n paths: resolveBranchPaths(paths.contextDir, branch, isDefault),\n };\n}\n\nexport interface RememberInput {\n text: string;\n kind: EntryKind;\n tags?: string[];\n files?: string[];\n}\n\nexport interface RememberResult {\n entry: ContextEntry;\n branch: string;\n storePath: string;\n contextMdPath: string;\n}\n\nexport async function rememberEntry(\n paths: SynthraPaths,\n input: RememberInput,\n): Promise<RememberResult> {\n const active = await resolveActiveBranch(paths);\n const entry: ContextEntry = {\n type: input.kind,\n content: input.text,\n tags: input.tags ?? [],\n files: input.files ?? [],\n date: new Date().toISOString(),\n };\n await appendEntry(active.paths.contextStore, entry);\n\n // Refresh CONTEXT.md so the narrative stays in sync with the structured store.\n const entries = await readEntries(active.paths.contextStore);\n const md = deriveContextMd(entries, active.branch);\n await writeContextMd(active.paths.contextMd, md);\n\n return {\n entry,\n branch: active.branch,\n storePath: active.paths.contextStore,\n contextMdPath: active.paths.contextMd,\n };\n}\n\nexport interface RecallInput {\n kind?: EntryKind;\n branch?: string;\n limit?: number;\n}\n\nexport interface RecallResult {\n branch: string;\n entries: ContextEntry[];\n storePath: string;\n}\n\nexport async function recallEntries(\n paths: SynthraPaths,\n input: RecallInput = {},\n): Promise<RecallResult> {\n const active = await resolveActiveBranch(paths, input.branch);\n let entries = await readEntries(active.paths.contextStore);\n if (input.kind) entries = entries.filter((e) => e.type === input.kind);\n if (input.limit && input.limit > 0) entries = entries.slice(-input.limit);\n return {\n branch: active.branch,\n entries,\n storePath: active.paths.contextStore,\n };\n}\n\nexport async function refreshContextMd(paths: SynthraPaths, branchOverride?: string) {\n const active = await resolveActiveBranch(paths, branchOverride);\n const entries = await readEntries(active.paths.contextStore);\n const md = deriveContextMd(entries, active.branch);\n await writeContextMd(active.paths.contextMd, md);\n return {\n branch: active.branch,\n path: active.paths.contextMd,\n entriesSeen: entries.length,\n };\n}\n","// Renders the final context pack as a single Markdown blob for Claude.\n\nexport interface FormatFileSection {\n path: string;\n reason?: string;\n signatures: string[];\n inlineBodies: string;\n associatedTests?: string[];\n}\n\nexport interface FormatInputs {\n query: string;\n files: FormatFileSection[];\n recentActivity?: string;\n truncated?: boolean;\n}\n\nexport function formatPack(inputs: FormatInputs): string {\n const parts: string[] = [];\n parts.push(`# Synthra context — query: ${JSON.stringify(inputs.query)}\\n`);\n\n if (inputs.files.length === 0) {\n parts.push(\"> No matching files found in the graph.\\n\");\n }\n\n for (const f of inputs.files) {\n const heading = f.reason ? `## ${f.path} _(${f.reason})_` : `## ${f.path}`;\n parts.push(heading);\n\n if (f.signatures.length === 0) {\n parts.push(\"_(no symbols extracted)_\");\n } else {\n parts.push(\"**Signatures:**\");\n for (const s of f.signatures) parts.push(`- ${s}`);\n }\n\n if (f.inlineBodies.trim().length > 0) {\n parts.push(\"\");\n parts.push(\"**Bodies:**\");\n parts.push(\"```\");\n parts.push(f.inlineBodies.trimEnd());\n parts.push(\"```\");\n }\n\n if (f.associatedTests?.length) {\n parts.push(\"\");\n parts.push(`**Tests:** ${f.associatedTests.join(\", \")}`);\n }\n\n parts.push(\"\");\n }\n\n if (inputs.recentActivity?.trim()) {\n parts.push(\"---\");\n parts.push(\"## Recent human activity\");\n parts.push(inputs.recentActivity.trim());\n parts.push(\"\");\n }\n\n if (inputs.truncated) {\n parts.push(\"> _(pack truncated to fit budget)_\");\n }\n\n return parts.join(\"\\n\");\n}\n","// Picks the top function bodies from a file (by relevance to the query) and\n// inlines them, respecting a char-based budget. Truncates oversized bodies.\n\nimport { tokenizeQuery } from \"../graph/rank.js\";\nimport type { FileNode, SymbolKind, SymbolNode } from \"../graph/types.js\";\n\nexport interface InlineSelection {\n text: string;\n charsUsed: number;\n functionsInlined: string[];\n}\n\nconst INLINABLE_KINDS = new Set<SymbolKind>([\"function\", \"method\", \"class\"]);\nconst MAX_BODY_CHARS = 1500;\n\nfunction sliceLines(content: string, startLine: number, endLine: number): string {\n const lines = content.split(/\\r?\\n/);\n return lines.slice(Math.max(0, startLine - 1), endLine).join(\"\\n\");\n}\n\nfunction scoreSymbol(name: string, qTokens: Set<string>): number {\n const lower = name.toLowerCase();\n if (qTokens.has(lower)) return 3;\n for (const t of qTokens) {\n if (lower.includes(t) || t.includes(lower)) return 1;\n }\n return 0;\n}\n\nfunction truncate(body: string): string {\n if (body.length <= MAX_BODY_CHARS) return body;\n return body.slice(0, MAX_BODY_CHARS).trimEnd() + \"\\n // … truncated\";\n}\n\nexport function selectInlineBodies(\n file: FileNode,\n symbols: SymbolNode[],\n query: string,\n budgetChars: number,\n): InlineSelection {\n if (budgetChars <= 0) {\n return { text: \"\", charsUsed: 0, functionsInlined: [] };\n }\n\n const qTokens = new Set(tokenizeQuery(query));\n const mine = symbols.filter((s) => s.file === file.path && INLINABLE_KINDS.has(s.symbol_kind));\n\n const scored = mine\n .map((s) => ({ sym: s, score: scoreSymbol(s.name, qTokens) }))\n .sort((a, b) => {\n if (b.score !== a.score) return b.score - a.score;\n // Tie-break: smaller bodies first (so we fit more)\n const aSpan = a.sym.end_line - a.sym.start_line || 1;\n const bSpan = b.sym.end_line - b.sym.start_line || 1;\n return aSpan - bSpan;\n });\n\n const parts: string[] = [];\n const inlined: string[] = [];\n let used = 0;\n\n for (const { sym, score } of scored) {\n // Skip irrelevant symbols entirely when we have positive hits available;\n // fall back to top-by-size if no query match landed.\n if (score === 0 && inlined.length > 0) break;\n\n const body = truncate(sliceLines(file.content, sym.start_line, sym.end_line));\n const header = `${file.path}::${sym.name} (L${sym.start_line}-${sym.end_line})`;\n const block = `${header}\\n${body}\\n`;\n if (used + block.length > budgetChars) {\n if (inlined.length > 0) break;\n // No room and nothing yet — take a head-only slice.\n const remaining = Math.max(0, budgetChars - used - header.length - 16);\n if (remaining <= 0) break;\n const partial = body.slice(0, remaining).trimEnd() + \"\\n // … truncated\";\n const finalBlock = `${header}\\n${partial}\\n`;\n parts.push(finalBlock);\n inlined.push(sym.name);\n used += finalBlock.length;\n break;\n }\n parts.push(block);\n inlined.push(sym.name);\n used += block.length;\n }\n\n return { text: parts.join(\"\\n\"), charsUsed: used, functionsInlined: inlined };\n}\n","// Extracts function/class signatures from a FileNode (no bodies).\n// Signatures are the first line of each symbol in the file, sorted by line.\n\nimport type { FileNode, SymbolNode } from \"../graph/types.js\";\n\nexport function extractSignatures(file: FileNode, symbols: SymbolNode[]): string[] {\n const mine = symbols\n .filter((s) => s.file === file.path)\n .slice()\n .sort((a, b) => a.start_line - b.start_line);\n\n return mine.map((s) => `L${s.start_line}: ${s.signature.trim()}`);\n}\n","// Test ↔ source co-retrieval. Given a source file, returns the test files\n// linked to it via `tests` edges in the graph (foo.test.ts → foo.ts).\n\nimport type { FileNode, GraphSchema } from \"../graph/types.js\";\n\nexport function findTestsForFile(graph: GraphSchema, file: FileNode): FileNode[] {\n // tests edges run from test file → source file\n const fileNodesById = new Map<string, FileNode>();\n for (const n of graph.nodes) {\n if (n.kind === \"file\") fileNodesById.set(n.id, n);\n }\n\n const out: FileNode[] = [];\n for (const e of graph.edges) {\n if (e.kind !== \"tests\" || e.to !== file.id) continue;\n const testFile = fileNodesById.get(e.from);\n if (testFile && !out.includes(testFile)) out.push(testFile);\n }\n return out;\n}\n","// Compresses a list of retrieved files into a structured context pack:\n// signatures + top function bodies + tests co-retrieved + dependency edges.\n// Budget is enforced in characters (~ tokens × 4) — see SYN_HARD_MAX_READ_CHARS.\n\nimport type { FileNode, GraphSchema, SymbolNode } from \"../graph/types.js\";\nimport { formatPack, type FormatFileSection } from \"./format.js\";\nimport { selectInlineBodies } from \"./inline.js\";\nimport { extractSignatures } from \"./signatures.js\";\nimport { findTestsForFile } from \"./tests.js\";\n\nexport interface PackOptions {\n query: string;\n graph: GraphSchema;\n /** Soft target for total tokens (≈ chars/4). Default: 4000. */\n budgetTokens?: number;\n /** Fraction of remaining budget to spend on a single file's inline bodies. Default: 0.5. */\n inlineBodyRatio?: number;\n /** Co-retrieve linked test files when packing source files. Default: true. */\n includeTests?: boolean;\n /** Optional: file path → reason string from the ranker, surfaced in the pack heading. */\n reasons?: Map<string, string>;\n}\n\nexport interface ContextPack {\n text: string;\n tokenEstimate: number;\n filesUsed: string[];\n testsCoRetrieved: string[];\n truncated: boolean;\n}\n\nconst STATIC_OVERHEAD_PER_FILE = 200; // headers + bullet markdown + spacing\nconst MAX_INLINE_CHARS_PER_FILE = 2500;\n\nfunction indexSymbolsByFile(graph: GraphSchema): SymbolNode[] {\n return graph.nodes.filter((n): n is SymbolNode => n.kind === \"symbol\");\n}\n\nexport async function pack(files: FileNode[], opts: PackOptions): Promise<ContextPack> {\n const budgetTokens = opts.budgetTokens ?? 4000;\n const budgetChars = budgetTokens * 4;\n const inlineRatio = opts.inlineBodyRatio ?? 0.5;\n const includeTests = opts.includeTests ?? true;\n const reasons = opts.reasons ?? new Map<string, string>();\n\n const symbols = indexSymbolsByFile(opts.graph);\n\n const sections: FormatFileSection[] = [];\n const testsCoRetrieved: string[] = [];\n let used = 0;\n let truncated = false;\n\n for (const file of files) {\n const sig = extractSignatures(file, symbols);\n const testFiles = includeTests ? findTestsForFile(opts.graph, file) : [];\n const testPaths = testFiles.map((t) => t.path);\n\n const staticCost =\n file.path.length +\n sig.join(\"\\n\").length +\n testPaths.join(\",\").length +\n STATIC_OVERHEAD_PER_FILE;\n\n if (used + staticCost > budgetChars) {\n truncated = true;\n break;\n }\n\n const remaining = budgetChars - used - staticCost;\n const inlineBudget = Math.min(Math.floor(remaining * inlineRatio), MAX_INLINE_CHARS_PER_FILE);\n\n const inline = selectInlineBodies(file, symbols, opts.query, inlineBudget);\n\n sections.push({\n path: file.path,\n reason: reasons.get(file.path),\n signatures: sig,\n inlineBodies: inline.text,\n associatedTests: testPaths,\n });\n\n used += staticCost + inline.charsUsed;\n for (const t of testPaths) if (!testsCoRetrieved.includes(t)) testsCoRetrieved.push(t);\n\n if (used >= budgetChars) {\n truncated = true;\n break;\n }\n }\n\n if (sections.length < files.length) truncated = true;\n\n const text = formatPack({\n query: opts.query,\n files: sections,\n truncated,\n });\n const tokenEstimate = Math.ceil(text.length / 4);\n\n return {\n text,\n tokenEstimate,\n filesUsed: sections.map((s) => s.path),\n testsCoRetrieved,\n truncated,\n };\n}\n","// Environment-variable-driven configuration.\n// All knobs are prefixed SYN_.\n\nexport interface SynthraConfig {\n hardMaxReadChars: number;\n gateHintMaxChars: number;\n readDepsMaxChars: number;\n turnReadBudgetChars: number;\n fallbackMaxCallsPerTurn: number;\n retrieveCacheTtlSec: number;\n mcpPort: number | null;\n dashboardPort: number;\n logLevel: \"debug\" | \"info\" | \"warn\" | \"error\";\n claudeBin: string;\n}\n\nfunction num(name: string, fallback: number): number {\n const v = process.env[name];\n if (!v) return fallback;\n const n = Number(v);\n return Number.isFinite(n) ? n : fallback;\n}\n\nfunction str<T extends string>(name: string, fallback: T): T {\n return (process.env[name] as T) ?? fallback;\n}\n\nexport function loadConfig(): SynthraConfig {\n return {\n hardMaxReadChars: num(\"SYN_HARD_MAX_READ_CHARS\", 4000),\n gateHintMaxChars: num(\"SYN_GATE_HINT_CHARS\", 1200),\n readDepsMaxChars: num(\"SYN_READ_DEPS_CHARS\", 900),\n turnReadBudgetChars: num(\"SYN_TURN_READ_BUDGET_CHARS\", 18000),\n fallbackMaxCallsPerTurn: num(\"SYN_FALLBACK_MAX_CALLS_PER_TURN\", 1),\n retrieveCacheTtlSec: num(\"SYN_RETRIEVE_CACHE_TTL_SEC\", 900),\n mcpPort: process.env.SYN_MCP_PORT ? num(\"SYN_MCP_PORT\", 0) : null,\n dashboardPort: num(\"SYN_DASHBOARD_PORT\", 8901),\n logLevel: str(\"SYN_LOG_LEVEL\", \"info\" as const),\n claudeBin: str(\"SYN_CLAUDE_BIN\", \"claude\" as const),\n };\n}\n","// GET /activity?since=<ms> — returns recent human-activity events.\n// Backed by the in-memory ActivityStore (file-watcher + git-watcher feed it).\n// MCP tool `recent_activity` is a thin wrapper.\n\nimport type { ActivityEvent } from \"../../activity/activity-log.js\";\nimport type { ServerContext } from \"../context.js\";\n\nexport interface ActivityResponse {\n events: ActivityEvent[];\n since: string;\n ring_size: number;\n}\n\nexport async function handleActivity(\n sinceMs: number | undefined,\n ctx: ServerContext,\n): Promise<ActivityResponse> {\n const events = ctx.activity.getEvents(sinceMs);\n return {\n events,\n since: new Date(sinceMs ?? Date.now()).toISOString(),\n ring_size: ctx.activity.size(),\n };\n}\n","// Thin git helpers for the session snapshot: commits since a timestamp and the\n// files changed in the latest commit. Best-effort — returns empty on no git /\n// not a repo, so the snapshot (and the resume digest built from it) degrades\n// gracefully. Mirrors the execFileAsync pattern in branches.ts / git-watcher.ts.\n\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nimport type { SessionCommit } from \"./session.js\";\n\nconst execFileAsync = promisify(execFile);\n\nconst MAX_COMMITS = 5;\nconst FIELD = \"\\x1f\"; // unit separator — safe delimiter inside commit subjects\n\n/** Commits since `sinceIso`, newest first, capped at MAX_COMMITS. When `sinceIso`\n * is empty/invalid (first run), returns the most recent MAX_COMMITS as\n * orientation rather than dumping the entire history. */\nexport async function getCommitsSince(\n projectRoot: string,\n sinceIso: string,\n): Promise<SessionCommit[]> {\n const args = [\n \"log\",\n `--max-count=${MAX_COMMITS}`,\n \"--no-merges\",\n `--pretty=format:%h${FIELD}%s${FIELD}%aI`,\n ];\n if (Number.isFinite(Date.parse(sinceIso))) args.push(`--since=${sinceIso}`);\n\n try {\n const { stdout } = await execFileAsync(\"git\", args, { cwd: projectRoot });\n const out: SessionCommit[] = [];\n for (const line of stdout.split(\"\\n\")) {\n const t = line.trim();\n if (!t) continue;\n const [hash, message, date] = t.split(FIELD);\n if (hash && message) out.push({ hash, message, date: date ?? \"\" });\n }\n return out;\n } catch {\n return [];\n }\n}\n\n/** Files changed in the latest commit (name-only). Empty on no git / shallow. */\nexport async function getDiffFiles(projectRoot: string): Promise<string[]> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"diff\", \"--name-only\", \"HEAD~1..HEAD\"], {\n cwd: projectRoot,\n });\n return stdout\n .split(\"\\n\")\n .map((s) => s.trim())\n .filter(Boolean);\n } catch {\n return [];\n }\n}\n","// Per-session snapshot, captured at session end (Stop hook → /context-update)\n// and read by the SessionStart primer to build the \"Since you were last here\"\n// resume digest. Persisted to .synthra-graph/session.json (machine-local,\n// gitignored): it describes THIS machine's last session and is regenerated every\n// Stop, so there is no migration — a schema mismatch is simply treated as\n// \"no snapshot\" and the primer degrades to its legacy output.\n\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nexport const SESSION_SCHEMA_VERSION = 1;\n\nexport interface SessionCommit {\n hash: string;\n message: string;\n date: string;\n}\n\nexport interface SessionSummary {\n tasks: string[];\n decisions: string[];\n next: string[];\n}\n\nexport interface SessionState {\n schema_version: number;\n endedAt: string;\n branch: string;\n filesTouched: string[];\n recentCommits: SessionCommit[];\n summary: SessionSummary;\n}\n\nexport async function readSession(path: string): Promise<SessionState | null> {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<SessionState>;\n if (parsed.schema_version !== SESSION_SCHEMA_VERSION) return null;\n return parsed as SessionState;\n } catch {\n return null;\n }\n}\n\nexport async function writeSession(path: string, state: SessionState): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, JSON.stringify(state, null, 2) + \"\\n\", \"utf8\");\n}\n","// POST /context-update — Stop hook calls this at session end.\n// 1. Re-renders CONTEXT.md from the branch-scoped store so the narrative stays\n// in sync with the structured entries that landed during the session.\n// 2. Captures a session snapshot (git diff since last session + files touched +\n// open decisions/next-steps) to .synthra-graph/session.json, which the next\n// SessionStart primer reads to build a \"Since you were last here\" digest.\n// Transcript-mining for new entries (auto \"we decided X\" → store) is deferred.\n\nimport { getCommitsSince } from \"../../memory/git-snapshot.js\";\nimport { recallEntries, refreshContextMd, resolveActiveBranch } from \"../../memory/index.js\";\nimport {\n readSession,\n writeSession,\n SESSION_SCHEMA_VERSION,\n type SessionState,\n} from \"../../memory/session.js\";\nimport type { ServerContext } from \"../context.js\";\nimport { getRegisteredEdits } from \"../mcp.js\";\n\nexport interface ContextUpdateRequest {\n transcript_path?: string;\n branch?: string;\n}\n\nexport interface ContextUpdateResponse {\n updated: boolean;\n branch: string;\n path: string;\n entries: number;\n}\n\n// Window for \"files the human touched this session\" harvested from the activity\n// ring at Stop. Generous — a session can be long, and the ring is bounded anyway.\nconst TOUCHED_WINDOW_MS = 24 * 60 * 60 * 1000;\n\nasync function captureSnapshot(ctx: ServerContext, branchOverride?: string): Promise<void> {\n const active = await resolveActiveBranch(ctx.paths, branchOverride);\n\n const [tasks, decisions, next] = await Promise.all([\n recallEntries(ctx.paths, { kind: \"task\", branch: active.branch, limit: 1 }),\n recallEntries(ctx.paths, { kind: \"decision\", branch: active.branch, limit: 3 }),\n recallEntries(ctx.paths, { kind: \"next\", branch: active.branch, limit: 3 }),\n ]);\n\n // Files touched this session: AI-registered edits ∪ recent human saves.\n const touched = new Set<string>(getRegisteredEdits());\n for (const p of ctx.activity.recentFilePaths(TOUCHED_WINDOW_MS)) touched.add(p);\n\n // Commits since the previous snapshot (or the most recent few on first run).\n const prev = await readSession(ctx.paths.sessionState);\n const recentCommits = await getCommitsSince(ctx.paths.projectRoot, prev?.endedAt ?? \"\");\n\n const snapshot: SessionState = {\n schema_version: SESSION_SCHEMA_VERSION,\n endedAt: new Date().toISOString(),\n branch: active.branch,\n filesTouched: Array.from(touched),\n recentCommits,\n summary: {\n tasks: tasks.entries.map((e) => e.content),\n decisions: decisions.entries.map((e) => e.content),\n next: next.entries.map((e) => e.content),\n },\n };\n await writeSession(ctx.paths.sessionState, snapshot);\n}\n\nexport async function handleContextUpdate(\n req: ContextUpdateRequest,\n ctx: ServerContext,\n): Promise<ContextUpdateResponse> {\n const r = await refreshContextMd(ctx.paths, req?.branch);\n\n // Best-effort: a snapshot failure (no git, unwritable disk) must never break\n // the CONTEXT.md refresh that downstream tooling relies on.\n try {\n await captureSnapshot(ctx, req?.branch);\n } catch {\n // ignore — the resume digest just falls back to the legacy primer next time.\n }\n\n return {\n updated: true,\n branch: r.branch,\n path: r.path,\n entries: r.entriesSeen,\n };\n}\n","// POST /gate — PreToolUse hook calls this with the tool name + arguments.\n// THE MOAT — improvement #1. Strategy:\n// - For Grep/Glob: extract the search pattern, run retrieve().\n// - If recent human activity touches a file matching the query → ALLOW\n// even at high confidence (the user's head is in that file; static\n// context may be stale).\n// - If confidence === \"high\" and no recent overlap → BLOCK. The deny reason\n// carries the answer: exact file::symbol graph_read targets + one-line\n// signatures, so the agent never needs the whole-file Read fallback.\n// - Otherwise → ALLOW.\n\nimport { appendFile, mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { retrieve } from \"../../graph/retrieve.js\";\nimport type { RetrievalResult } from \"../../graph/retrieve.js\";\nimport { tokenizeQuery } from \"../../graph/rank.js\";\nimport type { GraphSchema, SymbolNode } from \"../../graph/types.js\";\nimport { loadConfig } from \"../../shared/config.js\";\nimport type { ServerContext } from \"../context.js\";\n\nexport interface GateRequest {\n tool_name: string;\n tool_input: Record<string, unknown>;\n}\n\nexport interface GateResponse {\n decision: \"allow\" | \"block\";\n reason?: string;\n}\n\nconst BLOCKABLE_TOOLS = new Set([\"Grep\", \"Glob\"]);\nconst RECENT_ACTIVITY_WINDOW_MS = 5 * 60 * 1000;\n\nfunction extractQuery(toolName: string, input: Record<string, unknown>): string | null {\n if (toolName === \"Grep\") {\n const pattern = typeof input.pattern === \"string\" ? input.pattern : \"\";\n const query = typeof input.query === \"string\" ? input.query : \"\";\n return (pattern || query).trim() || null;\n }\n if (toolName === \"Glob\") {\n const pattern = typeof input.pattern === \"string\" ? input.pattern : \"\";\n return pattern.replace(/[*?/\\\\.]+/g, \" \").trim() || null;\n }\n return null;\n}\n\n// Heuristic: does this Grep pattern target markup / CSS / attributes / literals\n// rather than a code symbol? The graph only indexes symbols, so blocking these\n// and redirecting to graph_read just forces a fallback Read. Conservative — only\n// fires on syntax that never appears in a bare identifier search.\nfunction looksLikeNonSymbolQuery(pattern: string): boolean {\n // HTML / JSX tag: \"<div\", \"</\", \"<svg\"\n if (/<\\/?[a-zA-Z]/.test(pattern)) return true;\n // Hyphenated attribute assignment: \"data-tour=\", \"aria-label=\" ('-' is not a\n // valid identifier char, so this is markup, not a symbol).\n if (/[a-zA-Z][\\w-]*-[\\w-]*\\s*=/.test(pattern)) return true;\n // CSS rule / object brace: \".content{\", \"{ color\"\n if (/\\{/.test(pattern)) return true;\n // Escaped-dot class / member selector: \"\\.filter-bar\", \"\\.gs\"\n if (/\\\\\\.[a-zA-Z]/.test(pattern)) return true;\n // CSS property value or units: \": 100%\", \"12px\", \"1.5rem\", \"50%\"\n if (/:\\s*\\d/.test(pattern) || /\\d(?:px|rem|em|vh|vw)\\b/.test(pattern) || /\\d%/.test(pattern)) {\n return true;\n }\n // CSS custom property: \"var(--brand)\", \"--sidebar\" — a \"--\" prefix is never a\n // valid code identifier, so this is styling the graph doesn't index.\n if (/--[a-zA-Z]/.test(pattern)) return true;\n // Hex color literal: \"#fff\", \"#0a0a0a\".\n if (/#[0-9a-fA-F]{3,8}\\b/.test(pattern)) return true;\n // Kebab-case search (\"cw-code-chip\", \"data-tour\") — hyphens aren't valid in\n // JS/TS/Python identifiers, so it's a CSS class / HTML attribute / custom\n // element. Only treat it as non-symbol when EVERY alternation branch is kebab,\n // so a mixed query like \"fetchWith429Retry|Retry-After\" (real symbol + a\n // hyphenated header) still blocks. Strip regex char-classes first so a range\n // like \"[a-z]\" isn't mistaken for a kebab token.\n const branches = pattern\n .replace(/\\[[^\\]]*\\]/g, \"\")\n .split(\"|\")\n .map((b) => b.trim())\n .filter(Boolean);\n const isKebab = (b: string) => /^[a-z][a-z0-9]*(?:-[a-z0-9]+)+$/i.test(b);\n if (branches.length > 0 && branches.every(isKebab)) return true;\n return false;\n}\n\n// A recently-touched file \"matches\" the query if a query token appears in its\n// PATH or in its graph-node KEYWORDS (file contents). The content-keyword check\n// (#3) means a recent save of e.g. auth.ts relaxes `Grep \"login\"` when auth.ts\n// contains login — not only when the path itself contains the token.\nfunction recentlyTouchedMatchesQuery(\n recentPaths: string[],\n queryTokens: Set<string>,\n graph: GraphSchema,\n): string[] {\n if (recentPaths.length === 0) return [];\n\n // Pull keywords for the recently-touched files in a single graph pass.\n const recent = new Set(recentPaths);\n const keywordsByPath = new Map<string, string[]>();\n for (const n of graph.nodes) {\n if (n.kind === \"file\" && recent.has(n.path)) keywordsByPath.set(n.path, n.keywords);\n }\n\n const matches: string[] = [];\n for (const path of recentPaths) {\n const lower = path.toLowerCase();\n let matched = false;\n for (const t of queryTokens) {\n if (lower.includes(t)) {\n matched = true;\n break;\n }\n }\n if (!matched) {\n for (const kw of keywordsByPath.get(path) ?? []) {\n if (queryTokens.has(kw)) {\n matched = true;\n break;\n }\n }\n }\n if (matched) matches.push(path);\n }\n return matches;\n}\n\n// Block hints can run to ~1200 chars; the log (and the dashboard /data payload\n// built from it) only needs enough to identify the decision, so the stored\n// reason is truncated and the full hint size is kept as a separate count.\nconst LOG_REASON_MAX_CHARS = 240;\n\nasync function logDecision(\n ctx: ServerContext,\n toolName: string,\n query: string | null,\n decision: \"allow\" | \"block\",\n reason: string | undefined,\n hintChars?: number,\n): Promise<void> {\n try {\n await mkdir(dirname(ctx.paths.gateLog), { recursive: true });\n const entry = {\n ts: new Date().toISOString(),\n tool: toolName,\n decision,\n query,\n reason:\n reason && reason.length > LOG_REASON_MAX_CHARS\n ? `${reason.slice(0, LOG_REASON_MAX_CHARS)}…`\n : reason,\n ...(hintChars === undefined ? {} : { hint_chars: hintChars }),\n };\n await appendFile(ctx.paths.gateLog, JSON.stringify(entry) + \"\\n\", \"utf8\");\n } catch {\n // Durability is best-effort; an unwritable disk shouldn't fail the gate.\n }\n}\n\nconst SIG_LINE_MAX_CHARS = 140;\n\n// How relevant is a symbol name to the query? Mirrors the packer's inline\n// scoring: exact token match dominates, substring containment is a weak hit.\nfunction scoreSymbolName(name: string, qTokens: string[]): number {\n const lower = name.toLowerCase();\n let score = 0;\n for (const t of qTokens) {\n if (t === lower) score += 3;\n else if (t.length >= 3 && lower.includes(t)) score += 1;\n }\n return score;\n}\n\n/**\n * Render the deny reason for a block. Instead of bare file paths (which sent\n * agents into whole-file Read fallbacks — see the dogfood log), the hint\n * delivers copy-pasteable namespaced graph_read targets plus one-line\n * signatures for the query's best symbols. Signatures only, no bodies: the\n * hint lands in the transcript on every block, so its own size is a cost.\n */\nexport function buildBlockHint(\n query: string,\n retrieval: RetrievalResult,\n graph: GraphSchema,\n toolName: string,\n maxChars = loadConfig().gateHintMaxChars,\n): string {\n const topFiles = retrieval.files.slice(0, 3);\n const topPaths = new Set(topFiles.map((f) => f.path));\n\n const symsByFile = new Map<string, SymbolNode[]>();\n for (const n of graph.nodes) {\n if (n.kind !== \"symbol\" || !topPaths.has(n.file)) continue;\n const list = symsByFile.get(n.file);\n if (list) list.push(n);\n else symsByFile.set(n.file, [n]);\n }\n\n const qTokens = tokenizeQuery(query);\n const entries: string[] = [];\n for (const f of topFiles) {\n const syms = (symsByFile.get(f.path) ?? []).slice().sort((a, b) => a.start_line - b.start_line);\n if (syms.length === 0) {\n // Content-indexed only (no symbols) — still point at the slice tool.\n entries.push(`• mcp__synthra__graph_read(\"${f.path}\")`);\n continue;\n }\n const scored = syms\n .map((s) => ({ s, score: scoreSymbolName(s.name, qTokens) }))\n .filter((x) => x.score > 0)\n .sort((a, b) => b.score - a.score);\n // Best 1–2 query-relevant symbols; when nothing scores, the file's first\n // symbol still gives the agent a foothold into the file.\n const picks = scored.length > 0 ? scored.slice(0, 2).map((x) => x.s) : syms.slice(0, 1);\n for (const s of picks) {\n const sig = `L${s.start_line}: ${s.signature.trim()}`;\n const sigLine =\n sig.length > SIG_LINE_MAX_CHARS ? `${sig.slice(0, SIG_LINE_MAX_CHARS - 1)}…` : sig;\n entries.push(`• mcp__synthra__graph_read(\"${f.path}::${s.name}\")\\n ${sigLine}`);\n }\n }\n\n const header =\n `Synthra blocked this ${toolName} — ${retrieval.confidence}-confidence context for \"${query}\" already exists.\\n` +\n `Read symbols directly (~50 tokens each) instead of whole files:\\n`;\n const footer = `\\nFull pack: mcp__synthra__graph_continue(\"${query}\")`;\n\n const parts: string[] = [];\n let used = header.length + footer.length + 1;\n for (const e of entries) {\n if (used + e.length + 1 > maxChars) break; // drop whole entries, never mid-entry\n parts.push(e);\n used += e.length + 1;\n }\n\n if (parts.length === 0) {\n // Degenerate budget — fall back to the legacy path list, namespaced.\n const top = topFiles.map((f) => f.path).join(\", \");\n return (\n `Synthra has ${retrieval.confidence}-confidence context for \"${query}\" (top files: ${top}). ` +\n `Use mcp__synthra__graph_continue(\"${query}\") instead of ${toolName}, ` +\n `or read a specific file/symbol with mcp__synthra__graph_read.`\n );\n }\n\n return `${header}\\n${parts.join(\"\\n\")}\\n${footer}`;\n}\n\nexport async function handleGate(req: GateRequest, ctx: ServerContext): Promise<GateResponse> {\n if (!req?.tool_name || typeof req.tool_name !== \"string\") {\n return { decision: \"allow\", reason: \"no tool_name\" };\n }\n\n if (!BLOCKABLE_TOOLS.has(req.tool_name)) {\n return { decision: \"allow\" };\n }\n\n const input = (\n req.tool_input && typeof req.tool_input === \"object\" ? req.tool_input : {}\n ) as Record<string, unknown>;\n const query = extractQuery(req.tool_name, input);\n if (!query) {\n const res: GateResponse = { decision: \"allow\", reason: \"no extractable query\" };\n await logDecision(ctx, req.tool_name, null, res.decision, res.reason);\n return res;\n }\n\n // Guard 1 — the query targets markup/CSS/attributes/literals, which the graph\n // does not index. Blocking would only force a fallback, so let Grep through.\n if (req.tool_name === \"Grep\" && looksLikeNonSymbolQuery(query)) {\n const res: GateResponse = {\n decision: \"allow\",\n reason: `\"${query}\" targets markup/CSS/attributes, not code symbols — letting Grep through (the graph indexes symbols).`,\n };\n await logDecision(ctx, req.tool_name, query, res.decision, res.reason);\n return res;\n }\n\n const retrieval = await retrieve(ctx.graph, query);\n // \"low\" = no real matches → let Grep through; Synthra has nothing useful.\n // \"medium\" + \"high\" = Synthra has structured context for this query →\n // bias toward blocking. The pitch (\"use graph_continue instead of Grep\")\n // holds at medium too — on real codebases of any size, \"high\" is rare\n // because almost every query matches multiple files.\n if (retrieval.confidence === \"low\") {\n const res: GateResponse = {\n decision: \"allow\",\n reason: `confidence=low — no graph context for \"${query}\", letting ${req.tool_name} through`,\n };\n await logDecision(ctx, req.tool_name, query, res.decision, res.reason);\n return res;\n }\n\n // Medium / high — but check if recent activity overlaps the query first.\n // If the user just touched a file matching the query, static context may\n // be stale and they probably want a fresh search.\n const qTokens = new Set(tokenizeQuery(query));\n const recentPaths = ctx.activity.recentFilePaths(RECENT_ACTIVITY_WINDOW_MS);\n const overlap = recentlyTouchedMatchesQuery(recentPaths, qTokens, ctx.graph);\n\n if (overlap.length > 0) {\n const res: GateResponse = {\n decision: \"allow\",\n reason:\n `confidence=${retrieval.confidence} but human just touched ${overlap.slice(0, 3).join(\", \")} — ` +\n `static context may be stale, letting ${req.tool_name} through.`,\n };\n await logDecision(ctx, req.tool_name, query, res.decision, res.reason);\n return res;\n }\n\n // Guard 2 — the graph matched files only by keyword/path, not by a symbol the\n // query names, so graph_read can't return a real slice. A block would just\n // force a fallback Read; let the search through instead.\n if (!retrieval.symbolMatched) {\n const res: GateResponse = {\n decision: \"allow\",\n reason:\n `confidence=${retrieval.confidence} but only keyword/path matched (no symbol the query names) — ` +\n `graph_read can't slice it, letting ${req.tool_name} through.`,\n };\n await logDecision(ctx, req.tool_name, query, res.decision, res.reason);\n return res;\n }\n\n const hint = buildBlockHint(query, retrieval, ctx.graph, req.tool_name);\n const res: GateResponse = { decision: \"block\", reason: hint };\n await logDecision(ctx, req.tool_name, query, res.decision, hint, hint.length);\n return res;\n}\n","// POST /log — Stop hook posts per-turn token usage parsed from Claude's\n// transcript JSONL. Synthra appends each entry as one line to token_log.jsonl.\n\nimport { appendFile, mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport type { ServerContext } from \"../context.js\";\n\nexport interface LogEntry {\n input_tokens: number;\n output_tokens: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n model: string;\n description?: string;\n project: string;\n}\n\nexport interface LogResponse {\n ok: true;\n written_at: string;\n}\n\nexport async function handleLog(entry: LogEntry, ctx: ServerContext): Promise<LogResponse> {\n if (!entry || typeof entry.input_tokens !== \"number\" || typeof entry.output_tokens !== \"number\") {\n throw new Error(\"log: input_tokens and output_tokens (number) are required\");\n }\n\n const written_at = new Date().toISOString();\n const record = { ...entry, written_at };\n await mkdir(dirname(ctx.paths.tokenLog), { recursive: true });\n await appendFile(ctx.paths.tokenLog, JSON.stringify(record) + \"\\n\", \"utf8\");\n\n return { ok: true, written_at };\n}\n","// POST /pack { query, maxTokens? } → ContextPack JSON.\n// Runs retrieve → pack against the in-memory graph.\n\nimport { retrieve } from \"../../graph/retrieve.js\";\nimport { scoreFiles } from \"../../graph/rank.js\";\nimport { pack, type ContextPack } from \"../../packer/index.js\";\nimport type { ServerContext } from \"../context.js\";\n\nexport interface PackRequest {\n query: string;\n maxTokens?: number;\n includeTests?: boolean;\n}\n\nexport interface PackResponse extends ContextPack {\n query: string;\n confidence: \"high\" | \"medium\" | \"low\";\n retrievalReason: string;\n}\n\nexport async function handlePack(req: PackRequest, ctx: ServerContext): Promise<PackResponse> {\n if (!req?.query || typeof req.query !== \"string\") {\n throw new Error(\"pack: 'query' (string) is required\");\n }\n\n const recentlyEditedPaths = ctx.activity.recentFilePaths(15 * 60 * 1000);\n const usageScores = ctx.learn?.effectiveScores();\n const retrieval = await retrieve(ctx.graph, req.query, { recentlyEditedPaths, usageScores });\n\n // Surface per-file scoring rationale in the rendered pack.\n const allFiles = ctx.graph.nodes.filter((n) => n.kind === \"file\");\n const scored = scoreFiles({\n candidates: allFiles as Parameters<typeof scoreFiles>[0][\"candidates\"],\n query: req.query,\n graph: ctx.graph,\n recentlyEditedPaths,\n usageScores,\n });\n const reasons = new Map<string, string>();\n for (const s of scored) {\n if (s.reasons.length) reasons.set(s.file.path, s.reasons.join(\",\"));\n }\n\n const result = await pack(retrieval.files, {\n query: req.query,\n graph: ctx.graph,\n budgetTokens: req.maxTokens,\n includeTests: req.includeTests,\n reasons,\n });\n\n return {\n ...result,\n query: req.query,\n confidence: retrieval.confidence,\n retrievalReason: retrieval.reason,\n };\n}\n","// GET /prime — SessionStart and PreCompact hooks call this. Returns the priming\n// text Claude sees at session start.\n//\n// When the previous session left a snapshot (.synthra-graph/session.json), the\n// primer leads with a budget-bounded \"Since you were last here\" digest — recent\n// commits, files touched, open next-steps, recent decisions — so a fresh session\n// arrives oriented instead of re-paying tokens to rediscover recent work. With\n// no snapshot (first session, or none survived), it falls back to the legacy\n// graph-counts primer verbatim.\n\nimport { currentBranch } from \"../../memory/branches.js\";\nimport { readSession, type SessionState } from \"../../memory/session.js\";\nimport type { ServerContext } from \"../context.js\";\n\nexport interface PrimeResponse {\n primer: string;\n port: number;\n}\n\n// ~680 tokens. The digest rides the SessionStart primer channel, separate from\n// the graph pack's own ~4000-token budget — they don't compete.\nconst RESUME_PRIMER_MAX_CHARS = 2720;\n\nconst MAX_FILES = 15;\nconst MAX_COMMITS = 5;\nconst MAX_BULLETS = 3;\n\nfunction legacyPrimer(ctx: ServerContext): string {\n const g = ctx.graph;\n return (\n `Synthra context loaded for ${g.root}.\\n` +\n `${g.file_count} files indexed, ${g.symbol_count} symbols. ` +\n `Prefer the graph_* MCP tools over Grep/Glob for navigation.`\n );\n}\n\nfunction hasContent(snap: SessionState): boolean {\n return Boolean(\n snap.recentCommits.length ||\n snap.filesTouched.length ||\n snap.summary.tasks.length ||\n snap.summary.next.length ||\n snap.summary.decisions.length,\n );\n}\n\nfunction buildResumeDigest(snap: SessionState, branchNow: string): string {\n const plural = (n: number) => (n === 1 ? \"\" : \"s\");\n const head =\n `## Since you were last here — ${snap.branch} ` +\n `(${snap.recentCommits.length} commit${plural(snap.recentCommits.length)}, ` +\n `${snap.filesTouched.length} file${plural(snap.filesTouched.length)} touched)`;\n\n // Essential, high-signal block — never dropped under the budget.\n const essential: string[] = [head];\n if (snap.branch !== branchNow) {\n essential.push(\"\");\n essential.push(\n `_(snapshot was for branch '${snap.branch}'; you're now on '${branchNow}' — may be stale)_`,\n );\n }\n if (snap.summary.tasks[0]) {\n essential.push(\"\", \"### In progress\", `- ${snap.summary.tasks[0]}`);\n }\n if (snap.summary.next.length) {\n essential.push(\"\", \"### Open next steps\");\n for (const n of snap.summary.next.slice(0, MAX_BULLETS)) essential.push(`- ${n}`);\n }\n if (snap.summary.decisions.length) {\n essential.push(\"\", \"### Recent decisions\");\n for (const d of snap.summary.decisions.slice(0, MAX_BULLETS)) essential.push(`- ${d}`);\n }\n\n // Supporting context — appended only while budget remains, so commits/files\n // are what get dropped first if we're over the cap.\n const extra: string[] = [];\n if (snap.recentCommits.length) {\n extra.push(\"\", \"### Recent commits\");\n for (const c of snap.recentCommits.slice(0, MAX_COMMITS)) {\n const date = c.date ? ` (${c.date.slice(0, 10)})` : \"\";\n extra.push(`- \\`${c.hash}\\` ${c.message}${date}`);\n }\n }\n if (snap.filesTouched.length) {\n const shown = snap.filesTouched.slice(0, MAX_FILES);\n const more = snap.filesTouched.length - shown.length;\n extra.push(\"\", \"### Files touched\", shown.join(\", \") + (more > 0 ? `, +${more} more` : \"\"));\n }\n\n let out = essential.join(\"\\n\");\n for (const line of extra) {\n if ((out + \"\\n\" + line).length > RESUME_PRIMER_MAX_CHARS) break;\n out += \"\\n\" + line;\n }\n return (\n out.length > RESUME_PRIMER_MAX_CHARS ? out.slice(0, RESUME_PRIMER_MAX_CHARS) : out\n ).trimEnd();\n}\n\nexport async function handlePrime(ctx: ServerContext, port: number): Promise<PrimeResponse> {\n const legacy = legacyPrimer(ctx);\n\n const snap = await readSession(ctx.paths.sessionState);\n if (!snap || !hasContent(snap)) {\n return { primer: legacy, port };\n }\n\n const branchNow = await currentBranch(ctx.paths.projectRoot);\n const digest = buildResumeDigest(snap, branchNow);\n return { primer: `${digest}\\n\\n---\\n\\n${legacy}`, port };\n}\n","// Locate the most recently modified Claude session transcript for a project.\n// Claude Code stores them at: ~/.claude/projects/<encoded-cwd>/<session-uuid>.jsonl\n// where `encoded-cwd` replaces ANY of \\ / : with -.\n\nimport { readdir, stat } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport interface DiscoveredSession {\n sessionId: string;\n transcriptPath: string;\n modifiedAt: Date;\n}\n\nexport function encodeProjectPath(projectRoot: string): string {\n return projectRoot.replace(/[\\\\/:]/g, \"-\");\n}\n\nexport async function findLatestSession(projectRoot: string): Promise<DiscoveredSession | null> {\n const encoded = encodeProjectPath(projectRoot);\n const dir = join(homedir(), \".claude\", \"projects\", encoded);\n\n let entries: string[];\n try {\n entries = await readdir(dir);\n } catch {\n return null;\n }\n\n const jsonlFiles = entries.filter((f) => f.endsWith(\".jsonl\"));\n if (jsonlFiles.length === 0) return null;\n\n let latest: DiscoveredSession | null = null;\n for (const file of jsonlFiles) {\n const path = join(dir, file);\n try {\n const s = await stat(path);\n if (!latest || s.mtime > latest.modifiedAt) {\n latest = {\n sessionId: file.replace(/\\.jsonl$/, \"\"),\n transcriptPath: path,\n modifiedAt: s.mtime,\n };\n }\n } catch {\n // skip unreadable file\n }\n }\n return latest;\n}\n","// Graceful shutdown after `claude` exits:\n// - find latest Claude session JSONL → print `syn --resume <id>`\n// MCP-server shutdown is owned by the caller (it has the ServerHandle).\n// CONTEXT.md flushing is M4.\n\nimport { log } from \"../shared/logger.js\";\nimport type { SynthraPaths } from \"../shared/paths.js\";\nimport { findLatestSession } from \"./session-discovery.js\";\n\nexport async function cleanup(paths: SynthraPaths): Promise<void> {\n const session = await findLatestSession(paths.projectRoot);\n if (!session) {\n log.info(\"(no Claude session transcript found — nothing to resume)\");\n return;\n }\n log.info(\"\");\n log.info(`To resume this session: syn --resume ${session.sessionId}`);\n}\n","// `syn dashboard [path]` — starts the standalone token dashboard server on\n// localhost:8901 (or SYN_DASHBOARD_PORT). Reads token_log.jsonl + gate_log.jsonl\n// for the given project. Runs until Ctrl+C.\n\nimport { resolve } from \"node:path\";\n\nimport { startDashboard } from \"../dashboard/server.js\";\nimport { loadConfig } from \"../shared/config.js\";\nimport { log } from \"../shared/logger.js\";\nimport { resolvePaths } from \"../shared/paths.js\";\n\nexport async function dashboardCommand(rawPath: string): Promise<void> {\n const projectRoot = resolve(rawPath);\n const paths = resolvePaths(projectRoot);\n const cfg = loadConfig();\n\n const handle = await startDashboard(paths, cfg.dashboardPort);\n log.info(`Synthra dashboard listening on ${handle.url}`);\n log.info(`project: ${projectRoot}`);\n log.info(`reading: ${paths.tokenLog}`);\n log.info(` ${paths.gateLog}`);\n log.info(\"press Ctrl+C to stop.\");\n\n await new Promise<void>((res) => {\n const shutdown = async (signal: NodeJS.Signals) => {\n log.info(`received ${signal} — shutting down…`);\n try {\n await handle.stop();\n } catch (err) {\n log.warn(`dashboard stop error: ${(err as Error).message}`);\n }\n res();\n };\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n });\n}\n\n// Backwards-compat alias matching the M2-era stub signature.\nexport async function openDashboard(_port = 8901): Promise<void> {\n return dashboardCommand(\".\");\n}\n","// `syn doctor` — read-only diagnosis of a project's Synthra setup + environment.\n// Surfaces the common failure modes the dogfood log kept hitting: missing `jq`\n// (Stop/PreToolUse bash hooks silently no-op → no token logging or gating), a\n// stale or 0-symbol graph, no `.mcp.json` (the IDE can't see graph_* tools), and\n// an outdated policy block / uninstalled hooks. Never mutates anything.\n\nimport { readFile, stat } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\n\nimport spawn from \"cross-spawn\";\n\nimport { SCHEMA_VERSION } from \"../graph/types.js\";\nimport type { GraphSchema } from \"../graph/types.js\";\nimport { POLICY_VERSION } from \"../hooks/claude-md.js\";\nimport { loadConfig } from \"../shared/config.js\";\nimport { log } from \"../shared/logger.js\";\nimport { resolvePaths } from \"../shared/paths.js\";\n\nexport type CheckStatus = \"ok\" | \"warn\" | \"fail\";\n\nexport interface DoctorCheck {\n status: CheckStatus;\n label: string;\n detail: string;\n}\n\nconst ICON: Record<CheckStatus, string> = { ok: \"✅\", warn: \"⚠️\", fail: \"❌\" };\n\nfunction binWorks(bin: string, args: string[]): Promise<boolean> {\n return new Promise((res) => {\n let proc: ReturnType<typeof spawn>;\n try {\n proc = spawn(bin, args, { stdio: \"ignore\" });\n } catch {\n res(false);\n return;\n }\n proc.on(\"error\", () => res(false));\n proc.on(\"exit\", (code) => res(code === 0));\n });\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/** Collect the diagnostic checks for a project. Pure of console output so it can\n * be tested; doctorCommand() wraps it with printing. */\nexport async function runDoctorChecks(projectRoot: string): Promise<DoctorCheck[]> {\n const paths = resolvePaths(projectRoot);\n const cfg = loadConfig();\n const checks: DoctorCheck[] = [];\n\n // Node version\n const nodeMajor = Number(process.versions.node.split(\".\")[0]);\n checks.push(\n nodeMajor >= 18\n ? { status: \"ok\", label: \"Node\", detail: `v${process.versions.node}` }\n : {\n status: \"fail\",\n label: \"Node\",\n detail: `v${process.versions.node} — Synthra needs Node >= 18`,\n },\n );\n\n // jq — required by the bash hooks; on Windows the installer uses .ps1 instead.\n const hasJq = await binWorks(\"jq\", [\"--version\"]);\n if (process.platform === \"win32\") {\n checks.push({\n status: \"ok\",\n label: \"jq\",\n detail: hasJq\n ? \"present (not required — Windows uses .ps1 hooks)\"\n : \"not required on Windows (.ps1 hooks)\",\n });\n } else {\n checks.push(\n hasJq\n ? { status: \"ok\", label: \"jq\", detail: \"present\" }\n : {\n status: \"warn\",\n label: \"jq\",\n detail:\n \"missing — Stop/PreToolUse bash hooks silently no-op (no token logging or gating). Install jq (brew/apt).\",\n },\n );\n }\n\n // claude CLI — needed for MCP registration + IDE integration.\n const hasClaude = await binWorks(cfg.claudeBin, [\"--version\"]);\n checks.push(\n hasClaude\n ? { status: \"ok\", label: \"claude CLI\", detail: `'${cfg.claudeBin}' on PATH` }\n : {\n status: \"warn\",\n label: \"claude CLI\",\n detail: `'${cfg.claudeBin}' not found — MCP registration + IDE need it (set SYN_CLAUDE_BIN to override).`,\n },\n );\n\n // Graph\n if (!(await exists(paths.infoGraph))) {\n checks.push({\n status: \"warn\",\n label: \"Graph\",\n detail: \"no info_graph.json — run `syn .` (or `syn scan`) here.\",\n });\n } else {\n try {\n const graph = JSON.parse(await readFile(paths.infoGraph, \"utf8\")) as GraphSchema;\n const parts = [`${graph.symbol_count} symbols`, `${graph.file_count} files`];\n let status: CheckStatus = \"ok\";\n const ageMs = Date.now() - Date.parse(graph.generated_at);\n if (Number.isFinite(ageMs))\n parts.push(`scanned ${Math.max(0, Math.round(ageMs / 60000))}m ago`);\n if (graph.schema_version !== SCHEMA_VERSION) {\n status = \"warn\";\n parts.push(`schema v${graph.schema_version} ≠ v${SCHEMA_VERSION} (auto-rescans on serve)`);\n }\n if (graph.symbol_count === 0) {\n status = \"warn\";\n parts.push(\"0 symbols — unsupported language or nothing indexed\");\n }\n checks.push({ status, label: \"Graph\", detail: parts.join(\" · \") });\n } catch {\n checks.push({\n status: \"warn\",\n label: \"Graph\",\n detail: \"info_graph.json unreadable — re-run `syn scan`.\",\n });\n }\n }\n\n // MCP registration for the IDE (.mcp.json at the project root)\n checks.push(\n (await exists(join(projectRoot, \".mcp.json\")))\n ? {\n status: \"ok\",\n label: \"MCP registration\",\n detail: \".mcp.json present (IDE can see graph_* tools)\",\n }\n : {\n status: \"warn\",\n label: \"MCP registration\",\n detail: \"no .mcp.json — the IDE extension won't see Synthra's tools; run `syn .`.\",\n },\n );\n\n // CLAUDE.md policy block\n if (!(await exists(paths.claudeMd))) {\n checks.push({\n status: \"warn\",\n label: \"CLAUDE.md policy\",\n detail: \"no CLAUDE.md — run `syn .` to scaffold + inject the policy block.\",\n });\n } else {\n const md = await readFile(paths.claudeMd, \"utf8\");\n if (md.includes(`synthra-policy v${POLICY_VERSION} BEGIN`)) {\n checks.push({\n status: \"ok\",\n label: \"CLAUDE.md policy\",\n detail: `policy block v${POLICY_VERSION}`,\n });\n } else {\n const m = md.match(/synthra-policy v(\\d+) BEGIN/);\n checks.push({\n status: \"warn\",\n label: \"CLAUDE.md policy\",\n detail: m\n ? `policy block is v${m[1]}, current is v${POLICY_VERSION} — re-run \\`syn .\\` to refresh.`\n : \"no synthra-policy block — run `syn .`.\",\n });\n }\n }\n\n // Hooks installed\n if (!(await exists(paths.claudeSettings))) {\n checks.push({\n status: \"warn\",\n label: \"Hooks\",\n detail: \"no .claude/settings.local.json — run `syn .` to install hooks.\",\n });\n } else {\n const s = await readFile(paths.claudeSettings, \"utf8\");\n checks.push(\n s.includes(\"synthra-hook=true\")\n ? { status: \"ok\", label: \"Hooks\", detail: \"registered in .claude/settings.local.json\" }\n : {\n status: \"warn\",\n label: \"Hooks\",\n detail: \"settings.local.json present but no Synthra hooks — run `syn .`.\",\n },\n );\n }\n\n return checks;\n}\n\nexport async function doctorCommand(rawPath: string): Promise<void> {\n const projectRoot = resolve(rawPath);\n const checks = await runDoctorChecks(projectRoot);\n\n log.info(\"\");\n log.info(` Synthra doctor — ${projectRoot}`);\n log.info(\"\");\n for (const c of checks) {\n log.info(` ${ICON[c.status]} ${c.label.padEnd(18)}${c.detail}`);\n }\n const warn = checks.filter((c) => c.status === \"warn\").length;\n const fail = checks.filter((c) => c.status === \"fail\").length;\n log.info(\"\");\n log.info(\n fail === 0 && warn === 0 ? \" All checks passed.\" : ` ${fail} failed · ${warn} warning(s).`,\n );\n log.info(\"\");\n}\n","// Update flow:\n//\n// 1. At every `syn .` startup, check the npm registry for the latest\n// version. If we're on latest, stay silent. If outdated, prompt the\n// user [y/N]. On 'y', run `npm install -g …@latest` with inherited\n// stdio, print the new version's changelog section from the freshly-\n// installed package, then exit with re-run instructions.\n//\n// 2. On every startup, compare the running binary's version to a\n// persisted \"last seen\" version at ~/.synthra/last-seen-version.json.\n// If running > last-seen, print the changelog for the running version\n// (catches manual `npm install -g …@latest` upgrades that bypassed\n// our prompt). On a fresh install (no last-seen file), set last-seen\n// silently without printing — new users don't need the changelog.\n//\n// No 24h cache — the user explicitly asked for \"always check on every\n// `syn .` run.\" Cost: one ~100–300ms HTTPS round-trip per startup, hard-\n// capped by FETCH_TIMEOUT_MS. SYN_NO_UPDATE_CHECK=1 opts out of (1)\n// only; the local last-seen comparison in (2) still fires.\n\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createInterface } from \"node:readline/promises\";\n\nimport spawn from \"cross-spawn\";\n\nimport { log } from \"../shared/logger.js\";\n\nconst PKG_NAME = \"@jefuriiij/synthra\";\nconst SYNTHRA_DIR = join(homedir(), \".synthra\");\nconst LAST_SEEN_PATH = join(SYNTHRA_DIR, \"last-seen-version.json\");\nconst REGISTRY_URL = `https://registry.npmjs.org/${encodeURIComponent(PKG_NAME)}/latest`;\nconst FETCH_TIMEOUT_MS = 2000;\n\ninterface LastSeenFile {\n version: string;\n updated_at: string;\n}\n\nexport interface UpdateCheckResult {\n current: string;\n latest: string | null;\n hasUpdate: boolean;\n}\n\nlet currentVersionCache: string | null = null;\n\nasync function getCurrentVersion(): Promise<string> {\n if (currentVersionCache) return currentVersionCache;\n try {\n // Tsup inlines this import at build time.\n const pkg = (await import(\"../../package.json\", { with: { type: \"json\" } })) as\n | { default: { version: string } }\n | { version: string };\n const version = \"default\" in pkg ? pkg.default.version : pkg.version;\n currentVersionCache = version;\n return version;\n } catch {\n return \"0.0.0\";\n }\n}\n\n/** Returns true if `candidate` is a higher semver than `baseline`. */\nfunction isNewer(candidate: string, baseline: string): boolean {\n const a = candidate.split(/[.-]/).map((p) => Number(p));\n const b = baseline.split(/[.-]/).map((p) => Number(p));\n const len = Math.max(a.length, b.length);\n for (let i = 0; i < len; i++) {\n const ai = Number.isFinite(a[i]) ? (a[i] as number) : 0;\n const bi = Number.isFinite(b[i]) ? (b[i] as number) : 0;\n if (ai > bi) return true;\n if (ai < bi) return false;\n }\n return false;\n}\n\nasync function fetchLatestFromRegistry(): Promise<string | null> {\n try {\n const res = await fetch(REGISTRY_URL, {\n signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),\n headers: { Accept: \"application/json\" },\n });\n if (!res.ok) return null;\n const data = (await res.json()) as { version?: string };\n return typeof data.version === \"string\" ? data.version : null;\n } catch {\n return null;\n }\n}\n\nexport async function checkForUpdate(): Promise<UpdateCheckResult> {\n const current = await getCurrentVersion();\n\n if (process.env.SYN_NO_UPDATE_CHECK === \"1\") {\n return { current, latest: null, hasUpdate: false };\n }\n\n const latest = await fetchLatestFromRegistry();\n const hasUpdate = latest ? isNewer(latest, current) : false;\n return { current, latest, hasUpdate };\n}\n\nasync function readLastSeen(): Promise<string | null> {\n try {\n const raw = await readFile(LAST_SEEN_PATH, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<LastSeenFile>;\n return parsed.version ?? null;\n } catch {\n return null;\n }\n}\n\nasync function writeLastSeen(version: string): Promise<void> {\n try {\n await mkdir(SYNTHRA_DIR, { recursive: true });\n const data: LastSeenFile = { version, updated_at: new Date().toISOString() };\n await writeFile(LAST_SEEN_PATH, JSON.stringify(data, null, 2), \"utf8\");\n } catch {\n // best-effort\n }\n}\n\n/** Find the directory `npm root -g` reports. Used to locate the installed package. */\nfunction npmGlobalRoot(): Promise<string | null> {\n return new Promise((resolve) => {\n const chunks: Buffer[] = [];\n const proc = spawn(\"npm\", [\"root\", \"-g\"], { stdio: [\"ignore\", \"pipe\", \"ignore\"] });\n proc.stdout?.on(\"data\", (c: Buffer) => chunks.push(c));\n proc.on(\"error\", () => resolve(null));\n proc.on(\"exit\", (code) => {\n if (code !== 0) return resolve(null);\n const out = Buffer.concat(chunks).toString(\"utf8\").trim();\n resolve(out || null);\n });\n });\n}\n\n/**\n * Extract the markdown section under `## [version]` (or `## v0.1.11`) from a\n * CHANGELOG body. Returns the bullet/prose content between this version's\n * heading and the next H2, trimmed. Returns null if the version isn't found.\n */\nexport function extractChangelogSection(text: string, version: string): string | null {\n const escapedVersion = version.replace(/\\./g, \"\\\\.\");\n // Match: \"## [0.1.11]\" or \"## v0.1.11\" or \"## 0.1.11\", optionally followed by extra text.\n const headingRe = new RegExp(`^##\\\\s+\\\\[?v?${escapedVersion}\\\\]?.*$`, \"m\");\n const m = headingRe.exec(text);\n if (!m) return null;\n const startBody = m.index + m[0].length;\n const rest = text.slice(startBody);\n const nextHeadingIdx = rest.search(/^##\\s+/m);\n const body = nextHeadingIdx < 0 ? rest : rest.slice(0, nextHeadingIdx);\n // Strip horizontal-rule separator lines.\n return body.replace(/^---\\s*$/gm, \"\").trim() || null;\n}\n\nasync function readInstalledChangelog(): Promise<string | null> {\n const root = await npmGlobalRoot();\n if (!root) return null;\n try {\n return await readFile(join(root, \"@jefuriiij\", \"synthra\", \"CHANGELOG.md\"), \"utf8\");\n } catch {\n return null;\n }\n}\n\nasync function printChangelogForVersion(version: string): Promise<void> {\n const md = await readInstalledChangelog();\n if (!md) return;\n const section = extractChangelogSection(md, version);\n if (!section) return;\n log.info(\"\");\n log.info(`What's new in ${version}:`);\n log.info(\"\");\n for (const line of section.split(/\\r?\\n/)) {\n log.info(` ${line}`);\n }\n log.info(\"\");\n}\n\n/**\n * Compare the running binary's version against the persisted last-seen\n * version. If running > last-seen, print the changelog for the running\n * version and update last-seen. If last-seen is missing (fresh install),\n * silently set it to the current version — new installs don't need a\n * retroactive changelog.\n *\n * Catches users who upgraded via `npm install -g …@latest` outside of\n * Synthra's interactive prompt. Always silent on no-op.\n */\nexport async function runStartupChangelogCheck(): Promise<void> {\n try {\n const current = await getCurrentVersion();\n const lastSeen = await readLastSeen();\n if (!lastSeen) {\n await writeLastSeen(current);\n return;\n }\n if (isNewer(current, lastSeen)) {\n await printChangelogForVersion(current);\n await writeLastSeen(current);\n }\n } catch {\n // silent\n }\n}\n\n/**\n * Ask a yes/no question on stdin/stdout. Returns true only on explicit \"y\" /\n * \"yes\". Empty input or anything else returns false.\n */\nasync function promptYesNo(question: string): Promise<boolean> {\n if (!process.stdin.isTTY) return false;\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n try {\n const answer = (await rl.question(question)).trim().toLowerCase();\n return answer === \"y\" || answer === \"yes\";\n } finally {\n rl.close();\n }\n}\n\n/** Run `npm install -g @jefuriiij/synthra@latest`. Inherits stdio. */\nfunction runNpmUpdate(): Promise<boolean> {\n return new Promise((resolve) => {\n const proc = spawn(\"npm\", [\"install\", \"-g\", PKG_NAME + \"@latest\"], {\n stdio: \"inherit\",\n });\n proc.on(\"error\", () => resolve(false));\n proc.on(\"exit\", (code) => resolve(code === 0));\n });\n}\n\n/**\n * Interactive update flow. Always hits the registry — no cache. If a newer\n * version exists AND we're on a TTY, prompts the user [y/N]. On 'y', runs\n * npm install, prints the new version's changelog section, and exits with\n * re-run instructions. On 'n' / non-TTY / no update, returns silently so\n * startup continues.\n */\nexport async function promptForUpdateOrLog(): Promise<void> {\n try {\n const r = await checkForUpdate();\n if (!r.hasUpdate || !r.latest) return;\n\n // Non-interactive (CI, piped stdin) — log a one-line hint but don't prompt.\n if (!process.stdin.isTTY) {\n log.info(\n `Synthra ${r.latest} is available (you have ${r.current}) — run: npm install -g @jefuriiij/synthra@latest`,\n );\n return;\n }\n\n log.info(`Synthra ${r.latest} is available (you have ${r.current}).`);\n const yes = await promptYesNo(\"[syn] Update now? [y/N]: \");\n if (!yes) {\n log.info(\"Skipping update — continuing with current version.\");\n return;\n }\n\n log.info(`Running: npm install -g ${PKG_NAME}@latest`);\n const ok = await runNpmUpdate();\n if (!ok) {\n log.warn(\"npm install failed — continuing with current version.\");\n return;\n }\n log.info(`✓ Updated to ${r.latest}.`);\n await printChangelogForVersion(r.latest);\n await writeLastSeen(r.latest);\n log.info(`Please re-run: syn .`);\n process.exit(0);\n } catch {\n // silent\n }\n}\n","// `syn serve [path]` — starts the HTTP MCP server against an already-scanned\n// project. The graph + symbol index must exist (run `syn scan` first).\n// Traps SIGINT/SIGTERM for a graceful shutdown.\n\nimport { resolve } from \"node:path\";\nimport { stat } from \"node:fs/promises\";\n\nimport { startServer } from \"../server/http.js\";\nimport { log } from \"../shared/logger.js\";\nimport { resolvePaths } from \"../shared/paths.js\";\n\nexport async function serveCommand(rawPath: string): Promise<void> {\n const projectRoot = resolve(rawPath);\n const paths = resolvePaths(projectRoot);\n\n try {\n await stat(paths.infoGraph);\n } catch {\n log.error(`no graph found at ${paths.infoGraph}`);\n log.error(\"run `syn scan` in this project first.\");\n process.exit(2);\n }\n\n const handle = await startServer(paths);\n log.info(`MCP server listening on ${handle.url}`);\n log.info(`port written to ${paths.mcpPort}`);\n log.info(\"press Ctrl+C to stop.\");\n\n const shutdown = async (signal: NodeJS.Signals) => {\n log.info(`received ${signal} — shutting down…`);\n try {\n await handle.stop();\n } catch (err) {\n log.error(\"shutdown error:\", (err as Error).message);\n }\n process.exit(0);\n };\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n}\n","// Subroutines for plugging Synthra into Claude Code:\n// - registerMcp → `claude mcp add --transport http --scope local`\n// - unregisterMcp → `claude mcp remove`\n// - spawnClaude → spawn the terminal CLI (used only by `--launch-cli`)\n// - startClaude → legacy composite (install hooks + register + spawn + unregister)\n// kept for any external callers; cli/index.ts now composes the pieces\n// itself so the default flow can skip the CLI spawn.\n\nimport spawn from \"cross-spawn\";\n\nimport { installHooks } from \"../hooks/installer.js\";\nimport { loadConfig } from \"../shared/config.js\";\nimport { log } from \"../shared/logger.js\";\nimport type { SynthraPaths } from \"../shared/paths.js\";\n\nconst MCP_NAME = \"synthra\";\n\n// We use `cross-spawn` instead of `node:child_process` so Windows .cmd\n// shims (e.g. claude.cmd) resolve correctly without setting shell:true.\n// shell:true triggers Node's DEP0190 deprecation because args get\n// concatenated into a single command line with no escaping. cross-spawn\n// handles shim resolution + proper arg escaping internally, so we avoid\n// the deprecation and the underlying security concern in one move.\nfunction runClaude(\n bin: string,\n args: string[],\n cwd: string,\n stdio: \"inherit\" | \"pipe\" = \"pipe\",\n): Promise<{ code: number; stdout: string; stderr: string }> {\n return new Promise((resolve) => {\n const proc = spawn(bin, args, {\n cwd,\n stdio: stdio === \"inherit\" ? \"inherit\" : [\"ignore\", \"pipe\", \"pipe\"],\n });\n let stdout = \"\";\n let stderr = \"\";\n proc.stdout?.on(\"data\", (c) => (stdout += String(c)));\n proc.stderr?.on(\"data\", (c) => (stderr += String(c)));\n proc.on(\"error\", () => resolve({ code: -1, stdout, stderr: stderr || \"claude not on PATH\" }));\n proc.on(\"exit\", (code) => resolve({ code: code ?? 0, stdout, stderr }));\n });\n}\n\nexport async function registerMcp(bin: string, mcpPort: number, cwd: string): Promise<boolean> {\n const url = `http://127.0.0.1:${mcpPort}/mcp`;\n await runClaude(bin, [\"mcp\", \"remove\", MCP_NAME, \"--scope\", \"project\"], cwd).catch(\n () => undefined,\n );\n const reg = await runClaude(\n bin,\n [\"mcp\", \"add\", MCP_NAME, \"--transport\", \"http\", \"--scope\", \"project\", url],\n cwd,\n );\n if (reg.code !== 0) {\n log.warn(`claude mcp add failed (code ${reg.code}). stderr: ${reg.stderr.trim()}`);\n log.warn(`Synthra's MCP tools won't be visible to Claude this session.`);\n return false;\n }\n log.info(`registered MCP with Claude: ${MCP_NAME} → ${url}`);\n return true;\n}\n\nexport async function unregisterMcp(bin: string, cwd: string): Promise<void> {\n const r = await runClaude(bin, [\"mcp\", \"remove\", MCP_NAME, \"--scope\", \"project\"], cwd);\n if (r.code === 0) log.debug(\"unregistered MCP server\");\n}\n\nexport interface SpawnClaudeOptions {\n cwd: string;\n resumeSessionId?: string;\n initialPrompt?: string;\n}\n\nexport async function spawnClaude(bin: string, opts: SpawnClaudeOptions): Promise<number> {\n const args: string[] = [];\n if (opts.resumeSessionId) args.push(\"--resume\", opts.resumeSessionId);\n if (opts.initialPrompt) args.push(opts.initialPrompt);\n log.info(`launching ${bin} ${args.join(\" \")}`);\n const result = await runClaude(bin, args, opts.cwd, \"inherit\");\n return result.code;\n}\n\n// Legacy composite — install hooks + register MCP + spawn claude + cleanup.\n// cli/index.ts no longer relies on this; it composes the pieces above so the\n// new default `syn .` flow can skip the CLI spawn. Kept for compatibility.\nexport interface StartClaudeOptions {\n paths: SynthraPaths;\n mcpPort: number;\n resumeSessionId?: string;\n initialPrompt?: string;\n}\n\nexport async function startClaude(opts: StartClaudeOptions): Promise<number> {\n const bin = loadConfig().claudeBin;\n await installHooks(opts.paths);\n await registerMcp(bin, opts.mcpPort, opts.paths.projectRoot);\n const code = await spawnClaude(bin, {\n cwd: opts.paths.projectRoot,\n resumeSessionId: opts.resumeSessionId,\n initialPrompt: opts.initialPrompt,\n });\n await unregisterMcp(bin, opts.paths.projectRoot);\n return code;\n}\n"],"mappings":"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AAK,EAAE,MAAM,GAAG,CAAC;AACpE;;;ACHA,IAAM,YAAY,oBAAI,IAAI;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,cAAc,oBAAI,IAAI;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA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","names":["resolve","resolve","readFile","readFile","dirname","stat","readFile","dirname","join","mkdir","readFile","writeFile","homedir","basename","dirname","join","score","readFile","basename","resolve","err","mkdir","readFile","writeFile","dirname","join","pre_compact_default","pre_tool_use_default","prime_default","stop_default","prime_default","pre_tool_use_default","pre_compact_default","stop_default","readFile","join","mkdir","writeFile","dirname","serve","Hono","writeFile","appendFile","mkdir","dirname","readFile","join","readFile","join","emit","err","readFile","join","dirname","join","SCHEMA_VERSION","SCHEMA_VERSION","mkdir","readFile","writeFile","dirname","readFile","QUERY","QUERY","Query","QUERY","firstLine","Query","QUERY","QUERY","QUERY","QUERY","Query","QUERY","firstLine","Query","QUERY","QUERY","Query","firstLine","Query","SCRIPT_RE","extractScripts","require","readFile","cache","mkdir","dirname","writeFile","readFile","readdir","join","relative","sep","ignore","readIgnoreFile","buildMatcher","toPosix","mkdir","readFile","writeFile","dirname","readJson","mkdir","readFile","stat","writeFile","basename","readFile","writeFile","basename","dirname","stat","mkdir","readFile","writeFile","basename","cache","appendFile","mkdir","dirname","STOPWORDS","score","execFile","readFile","join","promisify","execFileAsync","mkdir","readFile","writeFile","dirname","mkdir","readFile","writeFile","dirname","SCHEMA_VERSION","score","indexSymbolsByFile","resolve","sep","join","mkdir","dirname","appendFile","execFile","promisify","execFileAsync","mkdir","readFile","writeFile","dirname","appendFile","mkdir","dirname","mkdir","dirname","appendFile","score","res","appendFile","mkdir","dirname","MAX_COMMITS","MAX_BULLETS","SCHEMA_VERSION","err","Hono","serve","writeFile","resolve","readdir","stat","homedir","join","resolve","resolve","err","readFile","stat","join","resolve","exists","stat","readFile","SCHEMA_VERSION","join","resolve","mkdir","readFile","writeFile","homedir","join","spawn","join","homedir","readFile","mkdir","writeFile","resolve","spawn","ok","resolve","stat","resolve","stat","err","spawn","resolve","spawn","VERSION","resolve","err"]}
1
+ {"version":3,"sources":["../../package.json","../../src/cli/index.ts","../../src/dashboard/server.ts","../../src/shared/logger.ts","../../src/server/port.ts","../../src/dashboard/arsenal.ts","../../src/dashboard/delta.ts","../../src/learn/store.ts","../../src/learn/usage.ts","../../src/shared/paths.ts","../../src/shared/pricing.ts","../../src/shared/project-registry.ts","../../src/dashboard/built/index.html","../../src/dashboard/public/favicon.svg","../../src/hooks/installer.ts","../../src/hooks/scripts/pre-compact.ps1","../../src/hooks/scripts/pre-compact.sh","../../src/hooks/scripts/pre-tool-use.ps1","../../src/hooks/scripts/pre-tool-use.sh","../../src/hooks/scripts/prime.ps1","../../src/hooks/scripts/prime.sh","../../src/hooks/scripts/stop.ps1","../../src/hooks/scripts/stop.sh","../../src/server/http.ts","../../src/activity/activity-log.ts","../../src/activity/file-watcher.ts","../../src/activity/git-watcher.ts","../../src/cli/scan-command.ts","../../src/scanner/extract.ts","../../src/graph/types.ts","../../src/scanner/hash.ts","../../src/scanner/keywords.ts","../../src/scanner/parse-cache.ts","../../src/scanner/parser.ts","../../src/scanner/parsers/_generic.ts","../../src/scanner/parsers/c.ts","../../src/scanner/parsers/cpp.ts","../../src/scanner/parsers/csharp.ts","../../src/scanner/parsers/dart.ts","../../src/scanner/parsers/go.ts","../../src/scanner/parsers/hubl.ts","../../src/scanner/parsers/java.ts","../../src/scanner/parsers/kotlin.ts","../../src/scanner/parsers/php.ts","../../src/scanner/parsers/python.ts","../../src/scanner/parsers/ruby.ts","../../src/scanner/parsers/rust.ts","../../src/scanner/parsers/typescript.ts","../../src/scanner/parsers/svelte.ts","../../src/scanner/parsers/vue.ts","../../src/scanner/walker.ts","../../src/graph/store.ts","../../src/cli/bootstrap.ts","../../src/hooks/claude-md.ts","../../src/learn/runtime.ts","../../src/server/mcp.ts","../../src/graph/rank.ts","../../src/graph/retrieve.ts","../../src/memory/branches.ts","../../src/memory/context-md.ts","../../src/memory/context-store.ts","../../src/memory/index.ts","../../src/packer/format.ts","../../src/packer/inline.ts","../../src/packer/signatures.ts","../../src/packer/tests.ts","../../src/packer/index.ts","../../src/shared/config.ts","../../src/server/routes/activity.ts","../../src/memory/git-snapshot.ts","../../src/memory/session.ts","../../src/server/routes/context-update.ts","../../src/server/routes/gate.ts","../../src/server/routes/log.ts","../../src/server/routes/pack.ts","../../src/server/routes/prime.ts","../../src/cli/session-discovery.ts","../../src/cli/cleanup.ts","../../src/cli/dashboard-command.ts","../../src/cli/doctor-command.ts","../../src/cli/self-update.ts","../../src/cli/serve-command.ts","../../src/cli/start-claude.ts"],"sourcesContent":["{\n \"name\": \"@jefuriiij/synthra\",\n \"version\": \"0.8.1\",\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"description\": \"Local context engine for AI coding assistants — graph-based context, branch-aware memory, real-time human-activity awareness, deterministic Grep/Glob gating, and a live token dashboard.\",\n \"type\": \"module\",\n \"bin\": {\n \"syn\": \"bin/syn\",\n \"synthra\": \"bin/syn\"\n },\n \"scripts\": {\n \"build\": \"npm run build:ui && tsup\",\n \"build:ui\": \"vite build --config vite.config.dashboard.ts\",\n \"dev\": \"tsup --watch\",\n \"dev:ui\": \"vite --config vite.config.dashboard.ts\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"biome lint .\",\n \"format\": \"biome format --write .\",\n \"check\": \"biome check .\",\n \"check:fix\": \"biome check --write .\"\n },\n \"files\": [\n \"dist\",\n \"bin\",\n \"README.md\",\n \"CHANGELOG.md\",\n \"LICENSE\",\n \"ROADMAP.md\"\n ],\n \"keywords\": [\n \"claude-code\",\n \"mcp\",\n \"context-engine\",\n \"code-graph\",\n \"ai-coding\",\n \"token-savings\"\n ],\n \"author\": \"Jeff (@jefuriiij)\",\n \"license\": \"MIT\",\n \"homepage\": \"https://github.com/jefuriiij/synthra#readme\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/jefuriiij/synthra.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/jefuriiij/synthra/issues\"\n },\n \"engines\": {\n \"node\": \">=18\"\n },\n \"dependencies\": {\n \"@hono/node-server\": \"^1.18.0\",\n \"chokidar\": \"^5.0.0\",\n \"cross-spawn\": \"^7.0.6\",\n \"hono\": \"^4.12.23\",\n \"ignore\": \"^7.0.0\",\n \"sade\": \"^1.8.1\",\n \"tree-sitter-wasms\": \"^0.1.12\",\n \"web-tree-sitter\": \"^0.25.10\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^2.4.16\",\n \"@lucide/svelte\": \"^1.18.0\",\n \"@sveltejs/vite-plugin-svelte\": \"^7.1.2\",\n \"@tailwindcss/vite\": \"^4.3.1\",\n \"@types/cross-spawn\": \"^6.0.6\",\n \"@types/node\": \"^25.9.1\",\n \"@vitest/coverage-v8\": \"^4.1.8\",\n \"bits-ui\": \"^2.18.1\",\n \"clsx\": \"^2.1.1\",\n \"svelte\": \"^5.56.3\",\n \"tailwind-merge\": \"^3.6.0\",\n \"tailwind-variants\": \"^3.2.2\",\n \"tailwindcss\": \"^4.3.1\",\n \"tsup\": \"^8.5.1\",\n \"tw-animate-css\": \"^1.4.0\",\n \"typescript\": \"^6.0.3\",\n \"vite\": \"^8.0.16\",\n \"vite-plugin-singlefile\": \"^2.3.3\",\n \"vitest\": \"^4.1.7\"\n }\n}\n","// `syn` entry point. Parses args and dispatches to commands.\n//\n// Commands:\n// syn [path] → default: scan + start MCP + dashboard +\n// register MCP for IDE extension; block on\n// Ctrl+C. NO claude CLI spawn — use the IDE.\n// syn . [path] → alias for default\n// syn . --launch-cli → also spawn `claude` here (M3 behavior)\n// syn scan [path] → scan only\n// syn serve [path] → start MCP server only\n// syn dashboard [path] → run only the dashboard server\n// syn --resume <id> [path] → resume an existing Claude session\n// (only meaningful with --launch-cli)\n\nimport sade from \"sade\";\nimport { resolve } from \"node:path\";\n\n// Inlined at build time by tsup's JSON loader so `syn --version` always\n// matches the published package.\nimport pkgJson from \"../../package.json\" with { type: \"json\" };\n\nimport { startDashboard, type DashboardServerHandle } from \"../dashboard/server.js\";\nimport { installHooks } from \"../hooks/installer.js\";\nimport { startServer, type ServerHandle } from \"../server/http.js\";\nimport { loadConfig } from \"../shared/config.js\";\nimport { log } from \"../shared/logger.js\";\nimport { resolvePaths } from \"../shared/paths.js\";\nimport { recordProject } from \"../shared/project-registry.js\";\nimport { cleanup } from \"./cleanup.js\";\nimport { dashboardCommand } from \"./dashboard-command.js\";\nimport { doctorCommand } from \"./doctor-command.js\";\nimport { scanCommand, type ScanResult } from \"./scan-command.js\";\nimport { promptForUpdateOrLog, runStartupChangelogCheck } from \"./self-update.js\";\nimport { serveCommand } from \"./serve-command.js\";\nimport { registerMcp, spawnClaude, unregisterMcp } from \"./start-claude.js\";\n\nconst VERSION = (pkgJson as { version: string }).version;\n\ninterface DefaultOpts {\n resume?: string;\n \"launch-cli\"?: boolean;\n full?: boolean;\n}\n\ninterface BannerInfo {\n projectRoot: string;\n scan: ScanResult;\n mcpUrl: string;\n dashboardUrl: string | null;\n mcpRegistered: boolean;\n}\n\nfunction printReadyBanner(info: BannerInfo): void {\n log.info(\"\");\n log.info(\n ` ✅ scanned ${info.scan.parsed} files · ${info.scan.symbolCount} symbols · ${info.scan.edgeCount} edges`,\n );\n if (info.mcpRegistered) {\n log.info(` 🧠 MCP ${info.mcpUrl} → registered as 'synthra'`);\n } else {\n log.info(` 🧠 MCP ${info.mcpUrl} ⚠ registration with claude failed`);\n }\n if (info.dashboardUrl) {\n log.info(` 📊 Dashboard ${info.dashboardUrl}`);\n } else {\n log.info(` 📊 Dashboard (failed to start; data is still logged to .synthra-graph/)`);\n }\n log.info(` 🪝 Hooks installed in .claude/settings.local.json`);\n log.info(\"\");\n log.info(\n ` 🤖 Ready — open the Claude Code IDE extension (or run \\`claude\\` in another terminal).`,\n );\n log.info(` Synthra's tools and gate will be active for that session.`);\n log.info(\"\");\n log.info(` Press Ctrl+C here when you're done.`);\n log.info(\"\");\n}\n\nfunction waitForSignal(): Promise<NodeJS.Signals> {\n return new Promise((resolve) => {\n const handler = (sig: NodeJS.Signals) => {\n process.off(\"SIGINT\", handler);\n process.off(\"SIGTERM\", handler);\n resolve(sig);\n };\n process.on(\"SIGINT\", handler);\n process.on(\"SIGTERM\", handler);\n });\n}\n\nasync function defaultFlow(rawPath: string, opts: DefaultOpts): Promise<void> {\n const launchCli = opts[\"launch-cli\"] === true;\n const projectRoot = resolve(rawPath);\n const paths = resolvePaths(projectRoot);\n const cfg = loadConfig();\n\n // If the running binary is newer than last-seen (e.g. user upgraded via\n // `npm install -g …@latest` directly), print the changelog for what they\n // just got. Silent if already on latest-seen or on fresh install.\n await runStartupChangelogCheck();\n\n // Always-fresh registry check (no cache). If a newer version is on npm AND\n // we're on a TTY, prompts [y/N]. On 'y', runs npm install, prints the new\n // version's changelog, and exits with re-run instructions. On 'n' / no\n // update / non-TTY, continues silently. SYN_NO_UPDATE_CHECK=1 opts out.\n await promptForUpdateOrLog();\n\n // 1. bootstrap + scan + record in the global registry so the dashboard\n // can list this project alongside any others.\n await recordProject(projectRoot);\n const scan = await scanCommand(rawPath, { full: opts.full });\n\n // 2. MCP server (background within this process)\n const mcpHandle: ServerHandle = await startServer(paths);\n\n // 3. Dashboard (optional — non-fatal if it fails)\n let dashboardHandle: DashboardServerHandle | null = null;\n try {\n dashboardHandle = await startDashboard(paths, cfg.dashboardPort);\n } catch (err) {\n log.warn(`dashboard failed to start on port ${cfg.dashboardPort}: ${(err as Error).message}`);\n }\n\n // 4. Install hooks + register MCP so the IDE / external claude can see it\n await installHooks(paths);\n const mcpRegistered = await registerMcp(cfg.claudeBin, mcpHandle.port, projectRoot);\n\n let claudeExitCode = 0;\n try {\n if (launchCli) {\n claudeExitCode = await spawnClaude(cfg.claudeBin, {\n cwd: projectRoot,\n resumeSessionId: opts.resume,\n });\n log.info(`claude exited with code ${claudeExitCode}`);\n } else {\n printReadyBanner({\n projectRoot,\n scan,\n mcpUrl: mcpHandle.url,\n dashboardUrl: dashboardHandle?.url ?? null,\n mcpRegistered,\n });\n const sig = await waitForSignal();\n log.info(`received ${sig} — shutting down…`);\n }\n } finally {\n await unregisterMcp(cfg.claudeBin, projectRoot).catch(() => undefined);\n if (dashboardHandle) {\n await dashboardHandle\n .stop()\n .catch((err) => log.warn(`dashboard stop error: ${(err as Error).message}`));\n }\n await mcpHandle\n .stop()\n .catch((err) => log.warn(`MCP server stop error: ${(err as Error).message}`));\n await cleanup(paths).catch((err) => log.warn(`cleanup error: ${(err as Error).message}`));\n }\n}\n\nexport function buildProgram() {\n const prog = sade(\"syn\");\n prog.version(VERSION).describe(\"Local context engine for AI coding assistants.\");\n\n prog\n .command(\n \". [path]\",\n \"Scan + MCP + dashboard + hooks. Default flow — use with the Claude Code IDE extension.\",\n {\n default: true,\n },\n )\n .option(\"--resume <id>\", \"Resume an existing Claude session (only with --launch-cli)\")\n .option(\"--launch-cli\", \"Also spawn `claude` CLI in this terminal (legacy M3 behavior)\", false)\n .option(\"--full\", \"Re-parse every file, ignoring the incremental parse cache\", false)\n .action(async (path: string | undefined, opts: DefaultOpts) => {\n await defaultFlow(path ?? \".\", opts);\n });\n\n prog\n .command(\"scan [path]\", \"Scan only — walk + parse + write graph.\")\n .option(\"--full\", \"Re-parse every file, ignoring the incremental parse cache\", false)\n .action(async (path: string | undefined, opts: { full?: boolean }) => {\n await scanCommand(path ?? \".\", { full: opts.full });\n });\n\n prog\n .command(\"serve [path]\", \"Start the HTTP MCP server against a scanned project.\")\n .action(async (path: string | undefined) => {\n await serveCommand(path ?? \".\");\n });\n\n prog\n .command(\"dashboard [path]\", \"Run the token dashboard server (localhost:8901).\")\n .action(async (path: string | undefined) => {\n await dashboardCommand(path ?? \".\");\n });\n\n prog\n .command(\"doctor [path]\", \"Diagnose this project's Synthra setup + environment.\")\n .action(async (path: string | undefined) => {\n await doctorCommand(path ?? \".\");\n });\n\n return prog;\n}\n\nexport async function main(argv: string[]): Promise<void> {\n const prog = buildProgram();\n prog.parse(argv);\n}\n","// Standalone dashboard server. Default port 8901 (override via\n// SYN_DASHBOARD_PORT); falls back through a small range 8901–8910 if the\n// preferred port is busy (so we can coexist with other co-installed\n// AI-context tools that also expose a dashboard).\n// Reads .synthra-graph/token_log.jsonl + .synthra-graph/gate_log.jsonl for the\n// given project and renders a live SPA backed by GET /data polled every 2s.\n\nimport { serve } from \"@hono/node-server\";\nimport { Hono } from \"hono\";\n\n// Tsup inlines this import at build time so `c.html` can echo whatever\n// version is running. Replaces the v__SYN_VERSION__ placeholder in the\n// dashboard footer on every GET /.\nimport pkgJson from \"../../package.json\" with { type: \"json\" };\n\nimport { log } from \"../shared/logger.js\";\nimport type { SynthraPaths } from \"../shared/paths.js\";\nimport { findFreePort } from \"../server/port.js\";\nimport { computeArsenal } from \"./arsenal.js\";\nimport { computeDashboardData } from \"./delta.js\";\n\n// The dashboard UI is built by Vite (svelte + tailwind) into a single\n// self-contained HTML (JS+CSS inlined) at ./built/index.html; tsup text-inlines\n// it here. See vite.config.dashboard.ts. CSS is inside the HTML — no /style.css.\nimport indexHtml from \"./built/index.html\";\nimport faviconSvg from \"./public/favicon.svg\";\n\nconst FALLBACK_RANGE = 9; // try preferredPort + [0..9]\nconst VERSION = (pkgJson as { version: string }).version;\n// How many recent turns/gates the /data payload carries. The dashboard\n// paginates turns client-side (25/page); the donut uses the uncapped\n// per-project model aggregate, so it isn't bounded by this.\nconst RECENT_N = Number(process.env.SYN_DASHBOARD_RECENT_N) || 500;\n\nexport interface DashboardServerHandle {\n port: number;\n url: string;\n stop(): Promise<void>;\n}\n\nexport async function startDashboard(\n paths: SynthraPaths,\n preferredPort = 8901,\n): Promise<DashboardServerHandle> {\n const port = await findFreePort(preferredPort, preferredPort + FALLBACK_RANGE);\n if (port !== preferredPort) {\n log.info(\n `dashboard port ${preferredPort} was busy — bound to ${port} instead (likely another dashboard from a coexisting tool).`,\n );\n }\n const app = new Hono();\n\n app.get(\"/\", (c) => c.html(indexHtml.replaceAll(\"__SYN_VERSION__\", VERSION)));\n\n app.get(\"/favicon.svg\", (c) => {\n c.header(\"Content-Type\", \"image/svg+xml; charset=utf-8\");\n c.header(\"Cache-Control\", \"public, max-age=86400\");\n return c.body(faviconSvg);\n });\n\n app.get(\"/health\", (c) => c.json({ ok: true }));\n\n // Installed skills / agents / MCP servers (project · personal · plugin).\n // Fetched lazily when the Arsenal drawer opens — not on the /data poll.\n app.get(\"/arsenal\", async (c) => c.json(await computeArsenal(paths.projectRoot)));\n\n app.get(\"/data\", async (c) => {\n const data = await computeDashboardData(paths, RECENT_N);\n return c.json(data);\n });\n\n const nodeServer = serve({ fetch: app.fetch, port, hostname: \"127.0.0.1\" });\n\n return {\n port,\n url: `http://127.0.0.1:${port}`,\n async stop() {\n await new Promise<void>((resolve, reject) => {\n nodeServer.close((err) => (err ? reject(err) : resolve()));\n });\n },\n };\n}\n","// Minimal logger. Prefixes Synthra output with [syn].\n\ntype Level = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nconst LEVEL_PRIORITY: Record<Level, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n};\n\nlet activeLevel: Level = (process.env.SYN_LOG_LEVEL as Level) ?? \"info\";\n\nexport function setLevel(level: Level): void {\n activeLevel = level;\n}\n\nfunction shouldLog(level: Level): boolean {\n return LEVEL_PRIORITY[level] >= LEVEL_PRIORITY[activeLevel];\n}\n\nfunction emit(level: Level, msg: string, ...args: unknown[]): void {\n if (!shouldLog(level)) return;\n const stream = level === \"error\" || level === \"warn\" ? process.stderr : process.stdout;\n stream.write(`[syn] ${msg}${args.length ? \" \" + args.map(String).join(\" \") : \"\"}\\n`);\n}\n\nexport const log = {\n debug: (m: string, ...a: unknown[]) => emit(\"debug\", m, ...a),\n info: (m: string, ...a: unknown[]) => emit(\"info\", m, ...a),\n warn: (m: string, ...a: unknown[]) => emit(\"warn\", m, ...a),\n error: (m: string, ...a: unknown[]) => emit(\"error\", m, ...a),\n};\n","// Finds a free port in the 8080–8099 range. Writes the chosen port to\n// .synthra-graph/mcp_port so PowerShell/Bash hook scripts can read it.\n// TODO: M2\n\nimport { createServer } from \"node:net\";\n\nexport const PORT_RANGE_START = 8080;\nexport const PORT_RANGE_END = 8099;\n\nexport async function findFreePort(\n start = PORT_RANGE_START,\n end = PORT_RANGE_END,\n): Promise<number> {\n for (let port = start; port <= end; port++) {\n if (await isFree(port)) return port;\n }\n throw new Error(`Synthra: no free port in ${start}-${end}`);\n}\n\nfunction isFree(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const s = createServer();\n s.once(\"error\", () => resolve(false));\n s.once(\"listening\", () => s.close(() => resolve(true)));\n s.listen(port, \"127.0.0.1\");\n });\n}\n","// Scans the user's Claude Code \"arsenal\" — installed skills, subagents, and MCP\n// servers — across project, personal (~/.claude), and plugin scopes, so the\n// dashboard can show what's available without dropping to the CLI.\n//\n// This reads Claude Code's own on-disk layout (NOT Synthra's graph):\n// skills ~/.claude/skills/<name>/SKILL.md, <project>/.claude/skills/…, plugin skills/\n// agents ~/.claude/agents/*.md, <project>/.claude/agents/*.md, plugin agents/\n// mcp <project>/.mcp.json, ~/.claude.json mcpServers, plugin .mcp.json\n// plugins ~/.claude/plugins/installed_plugins.json (index) + settings.json enabledPlugins\n//\n// Security: MCP configs frequently carry auth headers/env tokens. We emit ONLY\n// name / type / url(query stripped) / command — headers, env, and args are\n// dropped so nothing secret reaches the dashboard.\n\nimport { readFile, readdir } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { basename, dirname, join } from \"node:path\";\n\nexport type ArsenalScope = \"project\" | \"personal\" | \"plugin\";\n\nexport interface ArsenalItem {\n name: string;\n description: string;\n scope: ArsenalScope;\n /** Plugin name when scope === \"plugin\". */\n source?: string;\n /** Plugin items: enabled state from settings.json; undefined = always-on (own files). */\n enabled?: boolean;\n /** Kind-specific extras: agents {tools,model}; skills {argument_hint,user_invocable}; mcp {type,url}. */\n meta?: Record<string, string>;\n}\n\nexport interface ArsenalData {\n skills: ArsenalItem[];\n agents: ArsenalItem[];\n mcp: ArsenalItem[];\n counts: { skills: number; agents: number; mcp: number; plugins: number };\n scanned_at: string;\n}\n\nconst DESC_MAX = 300;\nconst TOOLS_MAX = 200;\n\nasync function readText(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf8\");\n } catch {\n return null;\n }\n}\n\nasync function readJson<T>(path: string): Promise<T | null> {\n const text = await readText(path);\n if (text === null) return null;\n try {\n return JSON.parse(text) as T;\n } catch {\n return null;\n }\n}\n\nasync function listNames(dir: string): Promise<string[]> {\n try {\n return await readdir(dir);\n } catch {\n return [];\n }\n}\n\nfunction clip(s: string, max: number): string {\n const t = s.trim();\n return t.length > max ? `${t.slice(0, max - 1)}…` : t;\n}\n\n/**\n * Minimal YAML-frontmatter reader — no dependency (Synthra stays lean). Pulls\n * the column-0 `key: value` pairs from the leading `--- … ---` block. Supports\n * single-line values and quoted values that span multiple lines (agent\n * `description` blocks do). Nested/indented lines (e.g. under `metadata:`) are\n * ignored. Keys are returned verbatim (e.g. \"argument-hint\").\n */\nexport function parseFrontmatter(md: string): Record<string, string> {\n const m = md.match(/^?\\s*---\\r?\\n([\\s\\S]*?)\\r?\\n---/);\n if (!m) return {};\n const lines = (m[1] ?? \"\").split(/\\r?\\n/);\n const out: Record<string, string> = {};\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n const kv = line.match(/^([A-Za-z][\\w-]*):\\s?(.*)$/); // column-0 keys only\n if (!kv) continue;\n const key = kv[1] ?? \"\";\n if (!key) continue;\n let val = kv[2] ?? \"\";\n // Quoted value that doesn't close on this line → consume until the closer.\n if ((val.startsWith('\"') && !/[^\\\\]\"\\s*$/.test(val.slice(1))) || val === '\"') {\n const buf = [val];\n while (i + 1 < lines.length && !/\"\\s*$/.test(buf[buf.length - 1] ?? \"\")) {\n i += 1;\n buf.push(lines[i] ?? \"\");\n }\n val = buf.join(\" \");\n }\n val = val\n .trim()\n .replace(/^[\"']|[\"']$/g, \"\")\n .trim();\n out[key] = val;\n }\n return out;\n}\n\nfunction skillItem(\n fm: Record<string, string>,\n fallbackName: string,\n scope: ArsenalScope,\n source?: string,\n): ArsenalItem {\n const meta: Record<string, string> = {};\n if (fm[\"argument-hint\"]) meta.argument_hint = fm[\"argument-hint\"];\n if (fm[\"user-invocable\"]) meta.user_invocable = fm[\"user-invocable\"];\n return {\n name: fm.name || fallbackName,\n description: clip(fm.description || \"\", DESC_MAX),\n scope,\n ...(source ? { source } : {}),\n ...(Object.keys(meta).length ? { meta } : {}),\n };\n}\n\nfunction agentItem(\n fm: Record<string, string>,\n fallbackName: string,\n scope: ArsenalScope,\n source?: string,\n): ArsenalItem {\n const meta: Record<string, string> = {};\n if (fm.tools) meta.tools = clip(fm.tools, TOOLS_MAX);\n if (fm.model) meta.model = fm.model;\n return {\n name: fm.name || fallbackName,\n description: clip(fm.description || \"\", DESC_MAX),\n scope,\n ...(source ? { source } : {}),\n ...(Object.keys(meta).length ? { meta } : {}),\n };\n}\n\nasync function scanSkillsDir(\n dir: string,\n scope: ArsenalScope,\n source: string | undefined,\n out: ArsenalItem[],\n): Promise<void> {\n for (const name of await listNames(dir)) {\n const md = await readText(join(dir, name, \"SKILL.md\"));\n if (md === null) continue; // not a skill dir (or broken symlink) — skip\n out.push(skillItem(parseFrontmatter(md), name, scope, source));\n }\n}\n\nasync function scanAgentsDir(\n dir: string,\n scope: ArsenalScope,\n source: string | undefined,\n out: ArsenalItem[],\n): Promise<void> {\n for (const file of await listNames(dir)) {\n if (!file.endsWith(\".md\")) continue;\n const md = await readText(join(dir, file));\n if (md === null) continue;\n out.push(agentItem(parseFrontmatter(md), basename(file, \".md\"), scope, source));\n }\n}\n\n/** Redacted MCP server entries — name/type/url only, never headers/env/args. */\nfunction mcpItemsFrom(\n json: unknown,\n scope: ArsenalScope,\n source: string | undefined,\n): ArsenalItem[] {\n if (!json || typeof json !== \"object\") return [];\n const record = json as Record<string, unknown>;\n // Either { mcpServers: {...} } or a bare { name: {type,url} } map.\n const servers =\n record.mcpServers && typeof record.mcpServers === \"object\"\n ? (record.mcpServers as Record<string, unknown>)\n : record;\n const items: ArsenalItem[] = [];\n for (const [name, raw] of Object.entries(servers)) {\n if (!raw || typeof raw !== \"object\") continue;\n const cfg = raw as Record<string, unknown>;\n const type = typeof cfg.type === \"string\" ? cfg.type : cfg.command ? \"stdio\" : \"http\";\n const url =\n typeof cfg.url === \"string\"\n ? cfg.url.split(\"?\")[0]\n : typeof cfg.command === \"string\"\n ? cfg.command\n : \"\";\n const meta: Record<string, string> = { type };\n if (url) meta.url = url;\n items.push({ name, description: \"\", scope, ...(source ? { source } : {}), meta });\n }\n return items;\n}\n\ninterface InstalledEntry {\n scope?: string;\n installPath?: string;\n version?: string;\n}\n\nconst SCOPE_ORDER: Record<ArsenalScope, number> = { project: 0, personal: 1, plugin: 2 };\n\nfunction sortItems(items: ArsenalItem[]): ArsenalItem[] {\n return items.sort((a, b) => {\n if (a.scope !== b.scope) return SCOPE_ORDER[a.scope] - SCOPE_ORDER[b.scope];\n const sa = a.source ?? \"\";\n const sb = b.source ?? \"\";\n if (sa !== sb) return sa < sb ? -1 : 1;\n return a.name < b.name ? -1 : a.name > b.name ? 1 : 0;\n });\n}\n\nlet cache: { key: string; at: number; data: ArsenalData } | null = null;\nconst CACHE_TTL_MS = 15_000;\n\nexport async function computeArsenal(\n projectRoot: string,\n homeDir = homedir(),\n): Promise<ArsenalData> {\n const key = `${projectRoot}\u0000${homeDir}`;\n const now = Date.now();\n if (cache && cache.key === key && now - cache.at < CACHE_TTL_MS) return cache.data;\n\n const homeClaude = join(homeDir, \".claude\");\n const projClaude = join(projectRoot, \".claude\");\n\n const skills: ArsenalItem[] = [];\n const agents: ArsenalItem[] = [];\n const mcp: ArsenalItem[] = [];\n\n // --- own files: project, then personal ---\n await scanSkillsDir(join(projClaude, \"skills\"), \"project\", undefined, skills);\n await scanSkillsDir(join(homeClaude, \"skills\"), \"personal\", undefined, skills);\n await scanAgentsDir(join(projClaude, \"agents\"), \"project\", undefined, agents);\n await scanAgentsDir(join(homeClaude, \"agents\"), \"personal\", undefined, agents);\n mcp.push(...mcpItemsFrom(await readJson(join(projectRoot, \".mcp.json\")), \"project\", undefined));\n mcp.push(\n ...mcpItemsFrom(\n (await readJson<Record<string, unknown>>(join(homeDir, \".claude.json\")))?.mcpServers,\n \"personal\",\n undefined,\n ),\n );\n\n // --- plugins: installed_plugins.json gives exact installPath per plugin ---\n // installed_plugins.json is `{ version, plugins: { \"<key>\": [entries] } }`\n // (v2); tolerate an older flat `{ \"<key>\": [entries] }` shape too.\n const installedRaw = await readJson<Record<string, unknown>>(\n join(homeClaude, \"plugins\", \"installed_plugins.json\"),\n );\n const pluginsMap = (installedRaw?.plugins ?? installedRaw ?? {}) as Record<\n string,\n InstalledEntry[]\n >;\n const settings = await readJson<{ enabledPlugins?: Record<string, boolean> }>(\n join(homeClaude, \"settings.json\"),\n );\n const enabledMap = settings?.enabledPlugins ?? {};\n let pluginCount = 0;\n for (const [pluginKey, entries] of Object.entries(pluginsMap)) {\n const entry = Array.isArray(entries) ? entries[0] : undefined;\n if (!entry?.installPath) continue;\n pluginCount += 1;\n const pluginName = pluginKey.split(\"@\")[0];\n const enabled = enabledMap[pluginKey] !== false;\n const root = entry.installPath;\n\n // Layouts vary: some plugins keep agents/skills in agents/ + skills/\n // subdirs (feature-dev), others at the plugin root listed in plugin.json\n // (voltagent). Take the UNION of both, deduped by file path.\n const manifest = await readJson<{ agents?: string[]; skills?: string[] }>(\n join(root, \".claude-plugin\", \"plugin.json\"),\n );\n\n const agentFiles = new Set<string>();\n for (const f of await listNames(join(root, \"agents\"))) {\n if (f.endsWith(\".md\")) agentFiles.add(join(root, \"agents\", f));\n }\n for (const rel of manifest?.agents ?? []) agentFiles.add(join(root, rel));\n const pAgents: ArsenalItem[] = [];\n for (const file of agentFiles) {\n const md = await readText(file);\n if (md !== null)\n pAgents.push(agentItem(parseFrontmatter(md), basename(file, \".md\"), \"plugin\", pluginName));\n }\n\n const skillMds = new Set<string>();\n for (const name of await listNames(join(root, \"skills\"))) {\n skillMds.add(join(root, \"skills\", name, \"SKILL.md\"));\n }\n for (const rel of manifest?.skills ?? []) {\n skillMds.add(rel.endsWith(\".md\") ? join(root, rel) : join(root, rel, \"SKILL.md\"));\n }\n const pSkills: ArsenalItem[] = [];\n for (const md of skillMds) {\n const text = await readText(md);\n if (text !== null)\n pSkills.push(\n skillItem(parseFrontmatter(text), basename(dirname(md)), \"plugin\", pluginName),\n );\n }\n\n const pMcp = mcpItemsFrom(await readJson(join(root, \".mcp.json\")), \"plugin\", pluginName);\n for (const it of [...pSkills, ...pAgents, ...pMcp]) it.enabled = enabled;\n skills.push(...pSkills);\n agents.push(...pAgents);\n mcp.push(...pMcp);\n }\n\n // dedupe skills by scope+source+name (symlink/dir overlaps)\n const seen = new Set<string>();\n const dedupedSkills = skills.filter((s) => {\n const k = `${s.scope}:${s.source ?? \"\"}:${s.name}`;\n if (seen.has(k)) return false;\n seen.add(k);\n return true;\n });\n\n const data: ArsenalData = {\n skills: sortItems(dedupedSkills),\n agents: sortItems(agents),\n mcp: sortItems(mcp),\n counts: {\n skills: dedupedSkills.length,\n agents: agents.length,\n mcp: mcp.length,\n plugins: pluginCount,\n },\n scanned_at: new Date(now).toISOString(),\n };\n cache = { key, at: now, data };\n return data;\n}\n","// Reads token_log.jsonl + gate_log.jsonl for the active project AND every\n// project registered in ~/.synthra/projects.json, then computes the\n// dashboard's rendered shape: per-project + global aggregate + recent calls\n// across all projects.\n\nimport { readFile } from \"node:fs/promises\";\n\nimport { readLearnStore } from \"../learn/store.js\";\nimport { effectiveScores, emptyStore, type LearnStore } from \"../learn/usage.js\";\nimport { resolvePaths, type SynthraPaths } from \"../shared/paths.js\";\nimport { estimateCostUsd } from \"../shared/pricing.js\";\nimport { listProjects } from \"../shared/project-registry.js\";\n\nconst AVG_TOKENS_PER_BLOCKED_GREP = 500;\n\nexport interface TokenLogEntry {\n /** Stop-hook-supplied timestamp (preferred). */\n ts?: string;\n /** Server-side fallback added by handleLog when ts isn't provided. */\n written_at?: string;\n input_tokens: number;\n output_tokens: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n model: string;\n description?: string;\n project: string;\n}\n\nexport interface GateLogEntry {\n ts: string;\n tool: string;\n decision: \"allow\" | \"block\";\n query: string | null;\n /** Truncated to ~240 chars in the log; the full block hint lives only in the deny response. */\n reason?: string;\n /** Full length of the block hint delivered to the agent (v0.4.0+). */\n hint_chars?: number;\n}\n\nexport interface ToolLogEntry {\n ts?: string;\n /** Synthra MCP tool name, e.g. \"graph_continue\", \"graph_read\". */\n tool: string;\n}\n\n/** Count Synthra MCP tool calls by tool name. (#2) */\nexport function countToolCalls(entries: ToolLogEntry[]): Record<string, number> {\n const out: Record<string, number> = {};\n for (const e of entries) {\n if (!e.tool) continue;\n out[e.tool] = (out[e.tool] ?? 0) + 1;\n }\n return out;\n}\n\nexport interface HotFile {\n path: string;\n score: number;\n}\n\n/** Top files by current (decayed-to-now) usage weight — surfaces what the\n * usage-learning layer has learned this repo leans on. Ranked by effective\n * score so recency matters; score rounded for display. */\nexport function topHotFiles(store: LearnStore, nowMs: number, limit = 8): HotFile[] {\n return [...effectiveScores(store, nowMs).entries()]\n .map(([path, score]) => ({ path, score: Math.round(score * 10) / 10 }))\n .sort((a, b) => b.score - a.score)\n .slice(0, limit);\n}\n\nexport interface ProjectStats {\n path: string;\n name: string;\n last_seen: string | null;\n total_turns: number;\n total_input_tokens: number;\n total_output_tokens: number;\n total_cache_read: number;\n total_cache_create: number;\n total_gate_calls: number;\n blocked_count: number;\n estimated_tokens_saved: number;\n estimated_cost_usd: number;\n total_tool_calls: number;\n tool_calls: Record<string, number>;\n hot_files: HotFile[];\n hot_files_total: number;\n models: Record<string, number>;\n}\n\nexport interface RecentTurn {\n ts: string;\n project_name: string;\n project_path: string;\n input: number;\n output: number;\n cache_read: number;\n cache_create: number;\n model: string;\n cost_usd: number;\n}\n\nexport interface RecentGate {\n ts: string;\n project_name: string;\n project_path: string;\n tool: string;\n decision: \"allow\" | \"block\";\n query: string | null;\n}\n\nexport interface DashboardData {\n active: {\n project_root: string;\n project_name: string;\n stats: ProjectStats;\n };\n global: {\n project_count: number;\n total_turns: number;\n total_input_tokens: number;\n total_output_tokens: number;\n total_cache_read: number;\n total_cache_create: number;\n total_gate_calls: number;\n blocked_count: number;\n estimated_tokens_saved: number;\n saved_percent: number;\n estimated_cost_usd: number;\n total_tool_calls: number;\n tool_calls: Record<string, number>;\n };\n projects: ProjectStats[];\n recent_turns: RecentTurn[];\n recent_gates: RecentGate[];\n}\n\nasync function readJsonl<T>(path: string): Promise<T[]> {\n try {\n const text = await readFile(path, \"utf8\");\n return text\n .split(/\\r?\\n/)\n .filter((l) => l.length > 0)\n .map((l) => {\n try {\n return JSON.parse(l) as T;\n } catch {\n return null;\n }\n })\n .filter((v): v is T => v !== null);\n } catch {\n return [];\n }\n}\n\nfunction basename(p: string): string {\n const parts = p.split(/[\\\\/]/);\n return parts[parts.length - 1] || p;\n}\n\ninterface ProjectFiles {\n path: string;\n name: string;\n last_seen: string | null;\n tokens: TokenLogEntry[];\n gates: GateLogEntry[];\n tools: ToolLogEntry[];\n learn: LearnStore;\n}\n\nfunction summarize(p: ProjectFiles): ProjectStats {\n let totalIn = 0;\n let totalOut = 0;\n let totalCacheRead = 0;\n let totalCacheCreate = 0;\n let costUsd = 0;\n const models: Record<string, number> = {};\n\n for (const t of p.tokens) {\n totalIn += t.input_tokens ?? 0;\n totalOut += t.output_tokens ?? 0;\n totalCacheRead += t.cache_read_input_tokens ?? 0;\n totalCacheCreate += t.cache_creation_input_tokens ?? 0;\n costUsd += estimateCostUsd(t);\n if (t.model) models[t.model] = (models[t.model] ?? 0) + 1;\n }\n\n const blocked = p.gates.filter((g) => g.decision === \"block\").length;\n const saved = blocked * AVG_TOKENS_PER_BLOCKED_GREP;\n const now = Date.now();\n\n return {\n path: p.path,\n name: p.name,\n last_seen: p.last_seen,\n total_turns: p.tokens.length,\n total_input_tokens: totalIn,\n total_output_tokens: totalOut,\n total_cache_read: totalCacheRead,\n total_cache_create: totalCacheCreate,\n total_gate_calls: p.gates.length,\n blocked_count: blocked,\n estimated_tokens_saved: saved,\n estimated_cost_usd: Math.round(costUsd * 100) / 100,\n total_tool_calls: p.tools.length,\n tool_calls: countToolCalls(p.tools),\n hot_files: topHotFiles(p.learn, now),\n hot_files_total: effectiveScores(p.learn, now).size,\n models,\n };\n}\n\n// Dedupe is ON by default; set SYN_DASHBOARD_DEDUPE=0 (or \"off\"/\"false\") to see\n// every raw token-log entry — including duplicates a co-installed AI tool's Stop\n// hook may write to the same token_log.jsonl. (#7)\nfunction dedupeEnabled(): boolean {\n const v = process.env.SYN_DASHBOARD_DEDUPE;\n return v !== \"0\" && v !== \"off\" && v !== \"false\";\n}\n\nasync function loadProjectFiles(\n path: string,\n name: string,\n lastSeen: string | null,\n): Promise<ProjectFiles> {\n const paths = resolvePaths(path);\n const [rawTokens, gates, tools, learn] = await Promise.all([\n readJsonl<TokenLogEntry>(paths.tokenLog),\n readJsonl<GateLogEntry>(paths.gateLog),\n readJsonl<ToolLogEntry>(paths.toolLog),\n readLearnStore(paths.learnStore),\n ]);\n const tokens = dedupeEnabled() ? dedupeTokens(rawTokens) : rawTokens;\n return { path, name, last_seen: lastSeen, tokens, gates, tools, learn };\n}\n\n/**\n * Collapse duplicate token-log entries from co-installed AI tools.\n *\n * Synthra is friendly with other tools that share the .synthra-graph/\n * token_log.jsonl shape — if a second tool's Stop hook also writes to\n * it, both fire on the same turn and emit nearly-identical entries\n * within ~10ms, double-counting every metric in the dashboard.\n *\n * Strategy: group by (project, usage counts, second-rounded timestamp);\n * inside a group, keep the entry with the most credible model field —\n * a real Claude model > \"<synthetic>\" > empty.\n */\nfunction dedupeTokens(entries: TokenLogEntry[]): TokenLogEntry[] {\n const score = (model: string | undefined): number => {\n if (!model) return 0;\n if (model === \"<synthetic>\") return 1;\n return 2; // real model name\n };\n\n const groups = new Map<string, TokenLogEntry[]>();\n for (const e of entries) {\n const ts = e.ts ?? e.written_at ?? \"\";\n const second = ts.slice(0, 19); // YYYY-MM-DDTHH:mm:ss\n const key = [\n e.project ?? \"\",\n e.input_tokens ?? 0,\n e.output_tokens ?? 0,\n e.cache_creation_input_tokens ?? 0,\n e.cache_read_input_tokens ?? 0,\n second,\n ].join(\"|\");\n const arr = groups.get(key) ?? [];\n arr.push(e);\n groups.set(key, arr);\n }\n\n const out: TokenLogEntry[] = [];\n for (const arr of groups.values()) {\n if (arr.length === 1) {\n out.push(arr[0]!);\n continue;\n }\n arr.sort((a, b) => score(b.model) - score(a.model));\n out.push(arr[0]!);\n }\n\n // Preserve chronological order in the per-project list.\n out.sort((a, b) => {\n const at = a.ts ?? a.written_at ?? \"\";\n const bt = b.ts ?? b.written_at ?? \"\";\n return at.localeCompare(bt);\n });\n return out;\n}\n\nexport async function computeDashboardData(\n activePaths: SynthraPaths,\n recentN = 500,\n): Promise<DashboardData> {\n const registered = await listProjects();\n\n // Always include the active project, even if not yet in the registry.\n const activePath = activePaths.projectRoot;\n const activeName = basename(activePath);\n const knownPaths = new Set(registered.map((p) => p.path));\n const allEntries: Array<{ path: string; name: string; last_seen: string | null }> = [\n ...registered.map((p) => ({ path: p.path, name: p.name, last_seen: p.last_seen })),\n ];\n if (!knownPaths.has(activePath)) {\n allEntries.unshift({ path: activePath, name: activeName, last_seen: null });\n }\n\n const loaded = await Promise.all(\n allEntries.map((e) => loadProjectFiles(e.path, e.name, e.last_seen)),\n );\n\n const projects = loaded\n .map(summarize)\n .sort(\n (a, b) =>\n b.total_input_tokens +\n b.total_output_tokens -\n (a.total_input_tokens + a.total_output_tokens),\n );\n\n const activeFiles = loaded.find((p) => p.path === activePath) ?? {\n path: activePath,\n name: activeName,\n last_seen: null,\n tokens: [],\n gates: [],\n tools: [],\n learn: emptyStore(),\n };\n const activeStats = summarize(activeFiles);\n\n // Global aggregates\n let g_in = 0,\n g_out = 0,\n g_cr = 0,\n g_cc = 0,\n g_gate = 0,\n g_block = 0,\n g_cost = 0,\n g_turns = 0,\n g_tools = 0;\n const g_tool_calls: Record<string, number> = {};\n for (const s of projects) {\n g_turns += s.total_turns;\n g_in += s.total_input_tokens;\n g_out += s.total_output_tokens;\n g_cr += s.total_cache_read;\n g_cc += s.total_cache_create;\n g_gate += s.total_gate_calls;\n g_block += s.blocked_count;\n g_cost += s.estimated_cost_usd;\n g_tools += s.total_tool_calls;\n for (const [k, v] of Object.entries(s.tool_calls)) g_tool_calls[k] = (g_tool_calls[k] ?? 0) + v;\n }\n const g_saved = g_block * AVG_TOKENS_PER_BLOCKED_GREP;\n const g_used = g_in + g_out + g_cc;\n const g_saved_pct = g_used + g_saved > 0 ? (g_saved / (g_used + g_saved)) * 100 : 0;\n\n // Recent turns + gates across all projects, sorted by ts descending\n const allTurns: RecentTurn[] = [];\n const allGates: RecentGate[] = [];\n for (const p of loaded) {\n for (const t of p.tokens) {\n allTurns.push({\n // Fall back to written_at — the Stop hook today posts entries without\n // a `ts` field, and the server tags them with written_at on receive.\n ts: t.ts ?? t.written_at ?? \"\",\n project_name: p.name,\n project_path: p.path,\n input: t.input_tokens ?? 0,\n output: t.output_tokens ?? 0,\n cache_read: t.cache_read_input_tokens ?? 0,\n cache_create: t.cache_creation_input_tokens ?? 0,\n model: t.model ?? \"\",\n cost_usd: Math.round(estimateCostUsd(t) * 1000) / 1000,\n });\n }\n for (const gate of p.gates) {\n allGates.push({\n ts: gate.ts,\n project_name: p.name,\n project_path: p.path,\n tool: gate.tool,\n decision: gate.decision,\n query: gate.query,\n });\n }\n }\n allTurns.sort((a, b) => (a.ts < b.ts ? 1 : a.ts > b.ts ? -1 : 0));\n allGates.sort((a, b) => (a.ts < b.ts ? 1 : a.ts > b.ts ? -1 : 0));\n\n return {\n active: {\n project_root: activePath,\n project_name: activeName,\n stats: activeStats,\n },\n global: {\n project_count: projects.length,\n total_turns: g_turns,\n total_input_tokens: g_in,\n total_output_tokens: g_out,\n total_cache_read: g_cr,\n total_cache_create: g_cc,\n total_gate_calls: g_gate,\n blocked_count: g_block,\n estimated_tokens_saved: g_saved,\n saved_percent: Math.round(g_saved_pct * 10) / 10,\n estimated_cost_usd: Math.round(g_cost * 100) / 100,\n total_tool_calls: g_tools,\n tool_calls: g_tool_calls,\n },\n projects,\n recent_turns: allTurns.slice(0, recentN),\n recent_gates: allGates.slice(0, recentN),\n };\n}\n\n// Legacy shapes from the M2 stub — kept for compat.\nexport interface TurnBreakdown {\n systemPromptTokens: number;\n conversationHistoryTokens: number;\n synthraPackTokens: number;\n userMessageTokens: number;\n responseTokens: number;\n totalTokens: number;\n costUsd: number;\n}\n\nexport interface SavingsDelta {\n withSynthra: TurnBreakdown;\n estimatedWithoutSynthra: TurnBreakdown;\n savedUsd: number;\n savedPercent: number;\n}\n\nexport function computeDelta(breakdown: TurnBreakdown, blockedGreps: number): SavingsDelta {\n const savedTokens = blockedGreps * AVG_TOKENS_PER_BLOCKED_GREP;\n const without: TurnBreakdown = {\n ...breakdown,\n conversationHistoryTokens: breakdown.conversationHistoryTokens + savedTokens,\n totalTokens: breakdown.totalTokens + savedTokens,\n costUsd: breakdown.costUsd + (savedTokens / 1_000_000) * 3,\n };\n const savedUsd = without.costUsd - breakdown.costUsd;\n const savedPercent = without.totalTokens > 0 ? (savedTokens / without.totalTokens) * 100 : 0;\n return {\n withSynthra: breakdown,\n estimatedWithoutSynthra: without,\n savedUsd,\n savedPercent: Math.round(savedPercent * 10) / 10,\n };\n}\n","// I/O for the usage-learning layer. Two files, both in .synthra-graph/\n// (gitignored, machine-local — usage is per-developer):\n// - access_log.jsonl : append-only raw events (source of truth, replayable)\n// - learn_store.json : derived decayed aggregate (a cache of the log)\n//\n// Every read is best-effort: a missing / corrupt / schema-mismatched file yields\n// an empty store, so the ranker degrades to its deterministic behavior.\n\nimport { appendFile, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { emptyStore, LEARN_SCHEMA_VERSION, type AccessEvent, type LearnStore } from \"./usage.js\";\n\nexport async function readLearnStore(path: string): Promise<LearnStore> {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<LearnStore>;\n if (\n parsed.schema_version !== LEARN_SCHEMA_VERSION ||\n typeof parsed.files !== \"object\" ||\n parsed.files === null\n ) {\n return emptyStore();\n }\n return {\n schema_version: LEARN_SCHEMA_VERSION,\n asOf: typeof parsed.asOf === \"string\" ? parsed.asOf : emptyStore().asOf,\n files: parsed.files as LearnStore[\"files\"],\n };\n } catch {\n return emptyStore();\n }\n}\n\nexport async function writeLearnStore(path: string, store: LearnStore): Promise<void> {\n try {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, JSON.stringify(store, null, 2) + \"\\n\", \"utf8\");\n } catch {\n // Persistence is best-effort; the log remains the source of truth.\n }\n}\n\nexport async function readAccessLog(path: string): Promise<AccessEvent[]> {\n try {\n const raw = await readFile(path, \"utf8\");\n const out: AccessEvent[] = [];\n for (const line of raw.split(\"\\n\")) {\n const t = line.trim();\n if (!t) continue;\n try {\n const ev = JSON.parse(t) as AccessEvent;\n if (\n ev &&\n typeof ev.ts === \"string\" &&\n typeof ev.path === \"string\" &&\n typeof ev.source === \"string\"\n ) {\n out.push(ev);\n }\n } catch {\n // Skip a malformed line rather than failing the whole replay.\n }\n }\n return out;\n } catch {\n return [];\n }\n}\n\nexport async function appendAccess(path: string, ev: AccessEvent): Promise<void> {\n try {\n await mkdir(dirname(path), { recursive: true });\n await appendFile(path, JSON.stringify(ev) + \"\\n\", \"utf8\");\n } catch {\n // Best-effort; never fail a tool call over telemetry.\n }\n}\n","// Pure decay/aggregate core for the usage-learning signal (\"the more it's used,\n// the smarter it gets\"). No I/O here — persistence + the raw access log live in\n// store.ts, and the stateful wrapper in runtime.ts.\n//\n// Files the AI actually pulls (graph_read) or edits (graph_register_edit) accrue\n// a time-decayed weight. retrieve() applies a bounded, capped boost so genuinely\n// \"hot\" files surface first — never dominating the deterministic ranker.\n\nexport type AccessSource = \"read\" | \"register_edit\" | \"continue\";\n\nexport interface AccessEvent {\n ts: string; // ISO timestamp\n path: string; // canonical FileNode.path (\"\" for source === \"continue\")\n source: AccessSource;\n query?: string; // only set for source === \"continue\" — reserved fuel for v2/v3\n}\n\nexport interface FileStat {\n /** Raw access count (never decayed) — diagnostic only. */\n count: number;\n /** Decayed weight as of `lastTs`. */\n decayed: number;\n /** ISO timestamp of the most recent folded event. */\n lastTs: string;\n}\n\nexport interface LearnStore {\n schema_version: number;\n asOf: string;\n files: Record<string, FileStat>;\n}\n\nexport const LEARN_SCHEMA_VERSION = 1;\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\n/** Usage-decay half-life. Env-overridable for dogfood tuning. */\nexport function halfLifeMs(): number {\n const env = Number(process.env.SYN_LEARN_HALFLIFE_DAYS);\n const days = Number.isFinite(env) && env > 0 ? env : 7;\n return days * DAY_MS;\n}\n\n/** Per-source accrual weight. `continue` never contributes to frequency — it's\n * logged only as query→outcome fuel for a future mechanism. */\nexport function weightFor(source: AccessSource): number {\n switch (source) {\n case \"register_edit\":\n return 2;\n case \"read\":\n return 1;\n default:\n return 0;\n }\n}\n\nexport function emptyStore(): LearnStore {\n return {\n schema_version: LEARN_SCHEMA_VERSION,\n asOf: new Date(0).toISOString(),\n files: {},\n };\n}\n\n/** exp(-λ·Δt) decay multiplier from `fromTs` forward to `toMs` epoch ms. */\nfunction decayFactor(fromTs: string, toMs: number, hl: number): number {\n const fromMs = Date.parse(fromTs);\n if (!Number.isFinite(fromMs)) return 1;\n const dt = toMs - fromMs;\n if (dt <= 0) return 1;\n return Math.exp(-(Math.LN2 / hl) * dt);\n}\n\n/** Fold one access event into the store: decay the file's prior weight up to the\n * event's timestamp, then add the event weight. Mutates and returns `store`.\n * Zero-weight (`continue`) and path-less events are ignored. Malformed\n * timestamps are dropped so the function stays deterministic. */\nexport function foldEvent(store: LearnStore, ev: AccessEvent): LearnStore {\n const w = weightFor(ev.source);\n if (w <= 0 || !ev.path) return store;\n const tMs = Date.parse(ev.ts);\n if (!Number.isFinite(tMs)) return store;\n\n const hl = halfLifeMs();\n const prev = store.files[ev.path];\n if (prev) {\n const decayed = prev.decayed * decayFactor(prev.lastTs, tMs, hl) + w;\n store.files[ev.path] = { count: prev.count + 1, decayed, lastTs: ev.ts };\n } else {\n store.files[ev.path] = { count: 1, decayed: w, lastTs: ev.ts };\n }\n return store;\n}\n\n/** Decayed weights as of `nowMs`, keyed by path. Effectively-zero entries are\n * omitted so an old/cold store contributes nothing. */\nexport function effectiveScores(store: LearnStore, nowMs: number): Map<string, number> {\n const hl = halfLifeMs();\n const out = new Map<string, number>();\n for (const [path, stat] of Object.entries(store.files)) {\n const eff = stat.decayed * decayFactor(stat.lastTs, nowMs, hl);\n if (eff > 0.01) out.set(path, eff);\n }\n return out;\n}\n\n/** Rebuild a store by replaying a raw access-log stream (the source of truth). */\nexport function recomputeFromLog(events: AccessEvent[]): LearnStore {\n const store = emptyStore();\n for (const ev of events) foldEvent(store, ev);\n return store;\n}\n","// Resolves Synthra's storage locations inside a project root.\n\nimport { join } from \"node:path\";\n\nexport interface SynthraPaths {\n projectRoot: string;\n graphDir: string;\n contextDir: string;\n infoGraph: string;\n symbolIndex: string;\n sessionState: string;\n activityLog: string;\n tokenLog: string;\n gateLog: string;\n toolLog: string;\n accessLog: string;\n learnStore: string;\n parseCache: string;\n mcpPort: string;\n mcpServerLog: string;\n mcpServerErrLog: string;\n contextStore: string;\n contextMd: string;\n branchesDir: string;\n claudeDir: string;\n claudeSettings: string;\n claudeHooksDir: string;\n claudeMd: string;\n gitignore: string;\n}\n\nexport function resolvePaths(projectRoot: string): SynthraPaths {\n const graphDir = join(projectRoot, \".synthra-graph\");\n const contextDir = join(projectRoot, \".synthra\");\n const claudeDir = join(projectRoot, \".claude\");\n\n return {\n projectRoot,\n graphDir,\n contextDir,\n infoGraph: join(graphDir, \"info_graph.json\"),\n symbolIndex: join(graphDir, \"symbol_index.json\"),\n sessionState: join(graphDir, \"session.json\"),\n activityLog: join(graphDir, \"activity.jsonl\"),\n tokenLog: join(graphDir, \"token_log.jsonl\"),\n gateLog: join(graphDir, \"gate_log.jsonl\"),\n toolLog: join(graphDir, \"tool_log.jsonl\"),\n accessLog: join(graphDir, \"access_log.jsonl\"),\n learnStore: join(graphDir, \"learn_store.json\"),\n parseCache: join(graphDir, \"parse_cache.json\"),\n mcpPort: join(graphDir, \"mcp_port\"),\n mcpServerLog: join(graphDir, \"mcp_server.log\"),\n mcpServerErrLog: join(graphDir, \"mcp_server.err.log\"),\n contextStore: join(contextDir, \"context-store.json\"),\n contextMd: join(contextDir, \"CONTEXT.md\"),\n branchesDir: join(contextDir, \"branches\"),\n claudeDir,\n claudeSettings: join(claudeDir, \"settings.local.json\"),\n claudeHooksDir: join(claudeDir, \"hooks\"),\n claudeMd: join(projectRoot, \"CLAUDE.md\"),\n gitignore: join(projectRoot, \".gitignore\"),\n };\n}\n","// Approximate per-million-token pricing for Claude models, in USD.\n// Sourced from Anthropic's published rates. Tilde everywhere — these can shift.\n//\n// Used only for the dashboard's \"~$X\" estimate; not for billing.\n\nexport interface ModelPricing {\n /** Cost per 1M raw-input tokens. */\n input: number;\n /** Cost per 1M output tokens. */\n output: number;\n /** Cost per 1M cache-read tokens (typically ~10% of input). */\n cacheRead: number;\n /** Cost per 1M cache-creation tokens (typically input × 1.25). */\n cacheCreate: number;\n}\n\nconst PRICING: Record<string, ModelPricing> = {\n // Fable-class — frontier tier (same 0.1× cache-read / 1.25× cache-write\n // multipliers as the rest of the lineup, on a $10 input base)\n \"claude-fable-5\": { input: 10, output: 50, cacheRead: 1, cacheCreate: 12.5 },\n // Opus-class models — premium tier\n \"claude-opus-4-7\": { input: 15, output: 75, cacheRead: 1.5, cacheCreate: 18.75 },\n \"claude-opus-4-6\": { input: 15, output: 75, cacheRead: 1.5, cacheCreate: 18.75 },\n \"claude-opus-4-5\": { input: 15, output: 75, cacheRead: 1.5, cacheCreate: 18.75 },\n // Sonnet-class — workhorse\n \"claude-sonnet-4-6\": { input: 3, output: 15, cacheRead: 0.3, cacheCreate: 3.75 },\n \"claude-sonnet-4-5\": { input: 3, output: 15, cacheRead: 0.3, cacheCreate: 3.75 },\n // Haiku-class — fast and cheap\n \"claude-haiku-4-5\": { input: 1, output: 5, cacheRead: 0.1, cacheCreate: 1.25 },\n};\n\nconst FALLBACK: ModelPricing = { input: 3, output: 15, cacheRead: 0.3, cacheCreate: 3.75 };\n\nexport function pricingFor(model: string | undefined | null): ModelPricing {\n if (!model) return FALLBACK;\n const direct = PRICING[model];\n if (direct) return direct;\n // Loose prefix match: \"claude-fable-…\" (incl. the \"[1m]\" long-context\n // variant) / \"claude-opus-…\" / \"claude-sonnet-…\" / \"claude-haiku-…\"\n if (model.includes(\"fable\")) return PRICING[\"claude-fable-5\"] ?? FALLBACK;\n if (model.includes(\"opus\")) return PRICING[\"claude-opus-4-7\"] ?? FALLBACK;\n if (model.includes(\"sonnet\")) return PRICING[\"claude-sonnet-4-6\"] ?? FALLBACK;\n if (model.includes(\"haiku\")) return PRICING[\"claude-haiku-4-5\"] ?? FALLBACK;\n return FALLBACK;\n}\n\nexport interface UsageRecord {\n input_tokens: number;\n output_tokens: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n model?: string;\n}\n\n/** Approximate USD cost of a single usage record. */\nexport function estimateCostUsd(usage: UsageRecord): number {\n const p = pricingFor(usage.model);\n return (\n (usage.input_tokens / 1_000_000) * p.input +\n (usage.output_tokens / 1_000_000) * p.output +\n ((usage.cache_read_input_tokens ?? 0) / 1_000_000) * p.cacheRead +\n ((usage.cache_creation_input_tokens ?? 0) / 1_000_000) * p.cacheCreate\n );\n}\n","// Global registry of projects that have run `syn .` on this machine.\n// Stored at ~/.synthra/projects.json so the dashboard can enumerate them\n// without walking the filesystem.\n\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { basename, dirname, join } from \"node:path\";\n\nconst REGISTRY_DIR = join(homedir(), \".synthra\");\nconst REGISTRY_PATH = join(REGISTRY_DIR, \"projects.json\");\nconst SCHEMA_VERSION = 1;\n\nexport interface ProjectRegistryEntry {\n path: string; // absolute project root\n name: string; // basename for display\n first_seen: string; // ISO timestamp\n last_seen: string; // ISO timestamp\n}\n\ninterface Registry {\n schema_version: number;\n projects: ProjectRegistryEntry[];\n}\n\nasync function readRegistry(): Promise<Registry> {\n try {\n const raw = await readFile(REGISTRY_PATH, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<Registry>;\n if (!Array.isArray(parsed.projects)) return { schema_version: SCHEMA_VERSION, projects: [] };\n return { schema_version: parsed.schema_version ?? SCHEMA_VERSION, projects: parsed.projects };\n } catch {\n return { schema_version: SCHEMA_VERSION, projects: [] };\n }\n}\n\nasync function writeRegistry(registry: Registry): Promise<void> {\n await mkdir(dirname(REGISTRY_PATH), { recursive: true });\n await writeFile(REGISTRY_PATH, JSON.stringify(registry, null, 2) + \"\\n\", \"utf8\");\n}\n\n/** Upsert this project's entry. Updates `last_seen`; preserves `first_seen`. */\nexport async function recordProject(projectRoot: string): Promise<void> {\n const now = new Date().toISOString();\n const registry = await readRegistry();\n const existing = registry.projects.find((p) => p.path === projectRoot);\n if (existing) {\n existing.last_seen = now;\n existing.name = basename(projectRoot);\n } else {\n registry.projects.push({\n path: projectRoot,\n name: basename(projectRoot),\n first_seen: now,\n last_seen: now,\n });\n }\n try {\n await writeRegistry(registry);\n } catch {\n // Registry is best-effort — a write failure shouldn't block the session.\n }\n}\n\nexport async function listProjects(): Promise<ProjectRegistryEntry[]> {\n const registry = await readRegistry();\n // Sort by last_seen descending so the most active project surfaces first.\n return registry.projects\n .slice()\n .sort((a, b) => (a.last_seen > b.last_seen ? -1 : a.last_seen < b.last_seen ? 1 : 0));\n}\n\nexport { REGISTRY_PATH, REGISTRY_DIR };\n","<!doctype html>\n<html lang=\"en\" class=\"dark\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Synthra · Dashboard</title>\n <link rel=\"icon\" href=\"/favicon.svg\" type=\"image/svg+xml\" />\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n <link\n href=\"https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600;700&family=Geist+Mono:wght@400;500&display=swap\"\n rel=\"stylesheet\"\n />\n <script type=\"module\" crossorigin>(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel=\"modulepreload\"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var e=Array.isArray,t=Array.prototype.indexOf,n=Array.prototype.includes,r=Array.from,i=Object.defineProperty,a=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyDescriptors,s=Object.prototype,c=Array.prototype,l=Object.getPrototypeOf,u=Object.isExtensible;function d(e){return typeof e==`function`}var f=()=>{};function p(e){for(var t=0;t<e.length;t++)e[t]()}function m(){var e,t;return{promise:new Promise((n,r)=>{e=n,t=r}),resolve:e,reject:t}}function h(e,t){if(Array.isArray(e))return e;if(t===void 0||!(Symbol.iterator in e))return Array.from(e);let n=[];for(let r of e)if(n.push(r),n.length===t)break;return n}var g=1<<24,_=1024,v=2048,y=4096,b=8192,ee=16384,x=32768,te=1<<25,ne=65536,re=1<<19,ie=1<<20,ae=1<<25,oe=65536,se=1<<21,ce=1<<22,le=1<<23,ue=Symbol(`$state`),de=Symbol(`legacy props`),fe=Symbol(``),pe=Symbol(`attributes`),me=Symbol(`class`),he=Symbol(`style`),ge=Symbol(`text`),_e=Symbol(`form reset`),ve=new class extends Error{name=`StaleReactionError`;message=\"The reaction that called `getAbortSignal()` was re-run or destroyed\"},ye=!!globalThis.document?.contentType&&globalThis.document.contentType.includes(`xml`);function be(e){throw Error(`https://svelte.dev/e/lifecycle_outside_component`)}function xe(){throw Error(`https://svelte.dev/e/async_derived_orphan`)}function Se(e,t,n){throw Error(`https://svelte.dev/e/each_key_duplicate`)}function Ce(e){throw Error(`https://svelte.dev/e/effect_in_teardown`)}function we(){throw Error(`https://svelte.dev/e/effect_in_unowned_derived`)}function Te(e){throw Error(`https://svelte.dev/e/effect_orphan`)}function Ee(){throw Error(`https://svelte.dev/e/effect_update_depth_exceeded`)}function De(e){throw Error(`https://svelte.dev/e/props_invalid_value`)}function Oe(){throw Error(`https://svelte.dev/e/set_context_after_init`)}function ke(){throw Error(`https://svelte.dev/e/state_descriptors_fixed`)}function Ae(){throw Error(`https://svelte.dev/e/state_prototype_fixed`)}function je(){throw Error(`https://svelte.dev/e/state_unsafe_mutation`)}function Me(){throw Error(`https://svelte.dev/e/svelte_boundary_reset_onerror`)}var Ne={},S=Symbol(`uninitialized`),Pe=`http://www.w3.org/1999/xhtml`,Fe=`http://www.w3.org/2000/svg`,Ie=`@attach`;function Le(){console.warn(`https://svelte.dev/e/derived_inert`)}function Re(e){console.warn(`https://svelte.dev/e/hydration_mismatch`)}function ze(){console.warn(`https://svelte.dev/e/select_multiple_invalid_value`)}function Be(){console.warn(`https://svelte.dev/e/svelte_boundary_reset_noop`)}var C=!1;function Ve(e){C=e}var w;function T(e){if(e===null)throw Re(),Ne;return w=e}function He(){return T(Cn(w))}function E(e){if(C){if(Cn(w)!==null)throw Re(),Ne;w=e}}function Ue(e=1){if(C){for(var t=e,n=w;t--;)n=Cn(n);w=n}}function We(e=!0){for(var t=0,n=w;;){if(n.nodeType===8){var r=n.data;if(r===`]`){if(t===0)return n;--t}else (r===`[`||r===`[!`||r[0]===`[`&&!isNaN(Number(r.slice(1))))&&(t+=1)}var i=Cn(n);e&&n.remove(),n=i}}function Ge(e){if(!e||e.nodeType!==8)throw Re(),Ne;return e.data}function Ke(e){return e===this.v}function qe(e,t){return e==e?e!==t||typeof e==`object`&&!!e||typeof e==`function`:t==t}function Je(e){return!qe(e,this.v)}var Ye=!1,Xe=!1;function Ze(){Xe=!0}var D=null;function Qe(e){D=e}function $e(e){return it(`getContext`).get(e)}function et(e,t){let n=it(`setContext`);if(Ye){var r=V.f;!B&&r&32&&!D.i||Oe()}return n.set(e,t),t}function tt(e){return it(`hasContext`).has(e)}function nt(){return it(`getAllContexts`)}function O(e,t=!1,n){D={p:D,i:!1,c:null,e:null,s:e,x:null,r:V,l:Xe&&!t?{s:null,u:null,$:[]}:null}}function k(e){var t=D,n=t.e;if(n!==null){t.e=null;for(var r of n)zn(r)}return e!==void 0&&(t.x=e),t.i=!0,D=t.p,e??{}}function rt(){return!Xe||D!==null&&D.l===null}function it(e){return D===null&&be(e),D.c??=new Map(at(D)||void 0)}function at(e){let t=e.p;for(;t!==null;){let e=t.c;if(e!==null)return e;t=t.p}return null}var ot=[];function st(){var e=ot;ot=[],p(e)}function ct(e){if(ot.length===0&&!Vt){var t=ot;queueMicrotask(()=>{t===ot&&st()})}ot.push(e)}function lt(){for(;ot.length>0;)st()}function ut(e){var t=V;if(t===null)return B.f|=le,e;if(!(t.f&32768)&&!(t.f&4))throw e;dt(e,t)}function dt(e,t){if(!(t!==null&&t.f&16384)){for(;t!==null;){if(t.f&128){if(!(t.f&32768))throw e;try{t.b.error(e);return}catch(t){e=t}}t=t.parent}throw e}}var ft=~(v|y|_);function A(e,t){e.f=e.f&ft|t}function pt(e){e.f&512||e.deps===null?A(e,_):A(e,y)}function mt(e){if(e!==null)for(let t of e)!(t.f&2)||!(t.f&65536)||(t.f^=oe,mt(t.deps))}function ht(e,t,n){e.f&2048?t.add(e):e.f&4096&&n.add(e),mt(e.deps),A(e,_)}var gt=!1,_t=!1;function vt(e){var t=_t;try{return _t=!1,[e(),_t]}finally{_t=t}}function yt(e){let t=0,n=sn(0),r;return()=>{In()&&(H(n),Gn(()=>(t===0&&(r=Mr(()=>e(()=>dn(n)))),t+=1,()=>{ct(()=>{--t,t===0&&(r?.(),r=void 0,dn(n))})})))}}var bt=ne|re;function xt(e,t,n,r){new St(e,t,n,r)}var St=class{parent;is_pending=!1;transform_error;#e;#t=C?w:null;#n;#r;#i;#a=null;#o=null;#s=null;#c=null;#l=0;#u=0;#d=!1;#f=new Set;#p=new Set;#m=null;#h=yt(()=>(this.#m=sn(this.#l),()=>{this.#m=null}));constructor(e,t,n,r){this.#e=e,this.#n=t,this.#r=e=>{var t=V;t.b=this,t.f|=128,n(e)},this.parent=V.b,this.transform_error=r??this.parent?.transform_error??(e=>e),this.#i=Kn(()=>{if(C){let e=this.#t;He();let t=e.data===`[!`;if(e.data.startsWith(`[?`)){let t=JSON.parse(e.data.slice(2));this.#_(t)}else t?this.#v():this.#g()}else this.#y()},bt),C&&(this.#e=w)}#g(){try{this.#a=Jn(()=>this.#r(this.#e))}catch(e){this.error(e)}}#_(e){let t=this.#n.failed;t&&(this.#s=Jn(()=>{t(this.#e,()=>e,()=>()=>{})}))}#v(){let e=this.#n.pending;e&&(this.is_pending=!0,this.#o=Jn(()=>e(this.#e)),ct(()=>{var e=this.#c=document.createDocumentFragment(),t=xn();e.append(t),this.#a=this.#x(()=>Jn(()=>this.#r(t))),this.#u===0&&(this.#e.before(e),this.#c=null,er(this.#o,()=>{this.#o=null}),this.#b(M))}))}#y(){try{if(this.is_pending=this.has_pending_snippet(),this.#u=0,this.#l=0,this.#a=Jn(()=>{this.#r(this.#e)}),this.#u>0){var e=this.#c=document.createDocumentFragment();ir(this.#a,e);let t=this.#n.pending;this.#o=Jn(()=>t(this.#e))}else this.#b(M)}catch(e){this.error(e)}}#b(e){this.is_pending=!1,e.transfer_effects(this.#f,this.#p)}defer_effect(e){ht(e,this.#f,this.#p)}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!this.#n.pending}#x(e){var t=V,n=B,r=D;dr(this.#i),ur(this.#i),Qe(this.#i.ctx);try{return qt.ensure(),e()}catch(e){return ut(e),null}finally{dr(t),ur(n),Qe(r)}}#S(e,t){if(!this.has_pending_snippet()){this.parent&&this.parent.#S(e,t);return}this.#u+=e,this.#u===0&&(this.#b(t),this.#o&&er(this.#o,()=>{this.#o=null}),this.#c&&=(this.#e.before(this.#c),null))}update_pending_count(e,t){this.#S(e,t),this.#l+=e,!(!this.#m||this.#d)&&(this.#d=!0,ct(()=>{this.#d=!1,this.#m&&ln(this.#m,this.#l)}))}get_effect_pending(){return this.#h(),H(this.#m)}error(e){if(!this.#n.onerror&&!this.#n.failed)throw e;M?.is_fork?(this.#a&&M.skip_effect(this.#a),this.#o&&M.skip_effect(this.#o),this.#s&&M.skip_effect(this.#s),M.oncommit(()=>{this.#C(e)})):this.#C(e)}#C(e){this.#a&&=(z(this.#a),null),this.#o&&=(z(this.#o),null),this.#s&&=(z(this.#s),null),C&&(T(this.#t),Ue(),T(We()));var t=this.#n.onerror;let n=this.#n.failed;var r=!1,i=!1;let a=()=>{if(r){Be();return}r=!0,i&&Me(),this.#s!==null&&er(this.#s,()=>{this.#s=null}),this.#x(()=>{this.#y()})},o=e=>{try{i=!0,t?.(e,a),i=!1}catch(e){dt(e,this.#i&&this.#i.parent)}n&&(this.#s=this.#x(()=>{try{return Jn(()=>{var t=V;t.b=this,t.f|=128,n(this.#e,()=>e,()=>a)})}catch(e){return dt(e,this.#i.parent),null}}))};ct(()=>{var t;try{t=this.transform_error(e)}catch(e){dt(e,this.#i&&this.#i.parent);return}typeof t==`object`&&t&&typeof t.then==`function`?t.then(o,e=>dt(e,this.#i&&this.#i.parent)):o(t)})}};function Ct(e,t,n,r){let i=rt()?Dt:At;var a=e.filter(e=>!e.settled),o=t.map(i);if(n.length===0&&a.length===0){r(o);return}var s=V,c=wt(),l=a.length===1?a[0].promise:a.length>1?Promise.all(a.map(e=>e.promise)):null;function u(e){if(!(s.f&16384)){c();try{r([...o,...e])}catch(e){dt(e,s)}Tt()}}var d=Et();if(n.length===0){l.then(()=>u([])).finally(d);return}function f(){Promise.all(n.map(e=>kt(e))).then(u).catch(e=>dt(e,s)).finally(d)}l?l.then(()=>{c(),f(),Tt()}):f()}function wt(){var e=V,t=B,n=D,r=M;return function(i=!0){dr(e),ur(t),Qe(n),i&&!(e.f&16384)&&(r?.activate(),r?.apply())}}function Tt(e=!0){dr(null),ur(null),Qe(null),e&&M?.deactivate()}function Et(){var e=V,t=e.b,n=M,r=!!t?.is_rendered();return t?.update_pending_count(1,n),n.increment(r,e),()=>{t?.update_pending_count(-1,n),n.decrement(r,e)}}function Dt(e){var t=2|v;return V!==null&&(V.f|=re),{ctx:D,deps:null,effects:null,equals:Ke,f:t,fn:e,reactions:null,rv:0,v:S,wv:0,parent:V,ac:null}}var Ot=Symbol(`obsolete`);function kt(e,t,n){let r=V;r===null&&xe();var i=void 0,a=sn(S),o=!B,s=new Set;return Wn(()=>{var t=V,n=m();i=n.promise;try{Promise.resolve(e()).then(n.resolve,e=>{e!==ve&&n.reject(e)}).finally(Tt)}catch(e){n.reject(e),Tt()}var c=M;if(o){if(t.f&32768)var l=Et();if(r.b?.is_rendered())c.async_deriveds.get(t)?.reject(Ot);else for(let e of s.values())e.reject(Ot);s.add(n),c.async_deriveds.set(t,n)}let u=(e,t=void 0)=>{l?.(),s.delete(n),t!==Ot&&(c.activate(),t?(a.f|=le,ln(a,t)):(a.f&8388608&&(a.f^=le),ln(a,e)),c.deactivate())};n.promise.then(u,e=>u(null,e||`unknown`))}),Ln(()=>{for(let e of s)e.reject(Ot)}),new Promise(e=>{function t(n){function r(){n===i?e(a):t(i)}n.then(r,r)}t(i)})}function j(e){let t=Dt(e);return Ye||pr(t),t}function At(e){let t=Dt(e);return t.equals=Je,t}function jt(e){var t=e.effects;if(t!==null){e.effects=null;for(var n=0;n<t.length;n+=1)z(t[n])}}function Mt(e){var t,n=V,r=e.parent;if(!sr&&r!==null&&e.v!==S&&r.f&24576)return Le(),e.v;dr(r);try{e.f&=~oe,jt(e),t=Tr(e)}finally{dr(n)}return t}function Nt(e){var t=Mt(e);if(!e.equals(t)&&(e.wv=Sr(),(!M?.is_fork||e.deps===null)&&(M===null?e.v=t:(M.capture(e,t,!0),Rt?.capture(e,t,!0)),e.deps===null))){A(e,_);return}sr||(zt===null?pt(e):(In()||M?.is_fork)&&zt.set(e,t))}function Pt(e){if(e.effects!==null)for(let t of e.effects)(t.teardown||t.ac)&&(t.teardown?.(),t.ac?.abort(ve),t.fn!==null&&(t.teardown=f),t.ac=null,Dr(t,0),Xn(t))}function Ft(e){if(e.effects!==null)for(let t of e.effects)t.teardown&&t.fn!==null&&Or(t)}var It=null,Lt=null,M=null,Rt=null,zt=null,Bt=null,Vt=!1,Ht=!1,Ut=null,Wt=null,Gt=0,Kt=1,qt=class e{id=Kt++;#e=!1;linked=!0;#t=null;#n=null;async_deriveds=new Map;current=new Map;previous=new Map;#r=new Set;#i=new Set;#a=0;#o=new Map;#s=null;#c=[];#l=[];#u=new Set;#d=new Set;#f=new Map;#p=new Set;is_fork=!1;#m=!1;constructor(){Lt===null?It=Lt=this:(Lt.#n=this,this.#t=Lt),Lt=this}#h(){if(this.is_fork)return!0;for(let n of this.#o.keys()){for(var e=n,t=!1;e.parent!==null;){if(this.#f.has(e)){t=!0;break}e=e.parent}if(!t)return!0}return!1}skip_effect(e){this.#f.has(e)||this.#f.set(e,{d:[],m:[]}),this.#p.delete(e)}unskip_effect(e,t=e=>this.schedule(e)){var n=this.#f.get(e);if(n){this.#f.delete(e);for(var r of n.d)A(r,v),t(r);for(r of n.m)A(r,y),t(r)}this.#p.add(e)}#g(){this.#e=!0,Gt++>1e3&&(this.#S(),Yt());for(let e of this.#u)this.#d.delete(e),A(e,v),this.schedule(e);for(let e of this.#d)A(e,y),this.schedule(e);let t=this.#c;this.#c=[],this.apply();var n=Ut=[],r=[],i=Wt=[];for(let e of t)try{this.#_(e,n,r)}catch(t){throw nn(e),this.#h()||this.discard(),t}if(M=null,i.length>0){var a=e.ensure();for(let e of i)a.schedule(e)}if(Ut=null,Wt=null,this.#h()){this.#b(r),this.#b(n);for(let[e,t]of this.#f)tn(e,t);i.length>0&&M.#g();return}let o=this.#v();if(o){this.#b(r),this.#b(n),o.#y(this);return}this.#u.clear(),this.#d.clear();for(let e of this.#r)e(this);this.#r.clear(),Rt=this,Zt(r),Zt(n),Rt=null,this.#s?.resolve();var s=M;if(this.#a===0&&(this.#c.length===0||s!==null)&&(this.#S(),Ye&&(this.#x(),M=s)),this.#c.length>0)if(s!==null){let e=s;e.#c.push(...this.#c.filter(t=>!e.#c.includes(t)))}else s=this;s!==null&&s.#g()}#_(e,t,n){e.f^=_;for(var r=e.first;r!==null;){var i=r.f,a=(i&96)!=0;if(!(a&&i&1024||i&8192||this.#f.has(r))&&r.fn!==null){a?r.f^=_:i&4?t.push(r):Ye&&i&16777224?n.push(r):Cr(r)&&(i&16&&this.#d.add(r),Or(r));var o=r.first;if(o!==null){r=o;continue}}for(;r!==null;){var s=r.next;if(s!==null){r=s;break}r=r.parent}}}#v(){for(var e=this.#t;e!==null;){if(!e.is_fork){for(let[t,[,n]]of this.current)if(e.current.has(t)&&!n)return e}e=e.#t}return null}#y(e){for(let[t,n]of e.current)!this.previous.has(t)&&e.previous.has(t)&&this.previous.set(t,e.previous.get(t)),this.current.set(t,n);for(let[t,n]of e.async_deriveds){let e=this.async_deriveds.get(t);e&&n.promise.then(e.resolve).catch(e.reject)}e.async_deriveds.clear(),this.transfer_effects(e.#u,e.#d);let t=e=>{var n=e.reactions;if(n!==null)for(let e of n){var r=e.f;if(r&2)t(e);else{var i=e;r&4194320&&!this.async_deriveds.has(i)&&(this.#d.delete(i),A(i,v),this.schedule(i))}}};for(let e of this.current.keys())t(e);this.oncommit(()=>e.discard()),e.#S(),M=this,this.#g()}#b(e){for(var t=0;t<e.length;t+=1)ht(e[t],this.#u,this.#d)}capture(e,t,n=!1){e.v!==S&&!this.previous.has(e)&&this.previous.set(e,e.v),e.f&8388608||(this.current.set(e,[t,n]),zt?.set(e,t)),this.is_fork||(e.v=t)}activate(){M=this}deactivate(){M=null,zt=null}flush(){try{Ht=!0,M=this,this.#g()}finally{Gt=0,Bt=null,Ut=null,Wt=null,Ht=!1,M=null,zt=null,an.clear()}}discard(){for(let e of this.#i)e(this);this.#i.clear();for(let e of this.async_deriveds.values())e.reject(Ot);this.#S(),this.#s?.resolve()}register_created_effect(e){this.#l.push(e)}#x(){for(let u=It;u!==null;u=u.#n){var e=u.id<this.id,t=[];for(let[r,[i,a]]of this.current){if(u.current.has(r)){var n=u.current.get(r)[0];if(e&&i!==n)u.current.set(r,[i,a]);else continue}t.push(r)}if(e)for(let[e,t]of this.async_deriveds){let n=u.async_deriveds.get(e);n&&t.promise.then(n.resolve).catch(n.reject)}var r=[...u.current.keys()].filter(e=>!u.current.get(e)[1]);if(!(!u.#e||r.length===0)){var i=r.filter(e=>!this.current.has(e));if(i.length===0)e&&u.discard();else if(t.length>0){if(e)for(let e of this.#p)u.unskip_effect(e,e=>{e.f&4194320?u.schedule(e):u.#b([e])});u.activate();var a=new Set,o=new Map;for(var s of t)Qt(s,i,a,o);o=new Map;var c=[...u.current].filter(([e,t])=>{let n=this.current.get(e);return n?n[0]!==t[0]||n[1]!==t[1]:!0}).map(([e])=>e);if(c.length>0)for(let e of this.#l)!(e.f&155648)&&$t(e,c,o)&&(e.f&4194320?(A(e,v),u.schedule(e)):u.#u.add(e));if(u.#c.length>0&&!u.#m){u.apply();for(var l of u.#c)u.#_(l,[],[]);u.#c=[]}u.deactivate()}}}}increment(e,t){if(this.#a+=1,e){let e=this.#o.get(t)??0;this.#o.set(t,e+1)}}decrement(e,t){if(--this.#a,e){let e=this.#o.get(t)??0;e===1?this.#o.delete(t):this.#o.set(t,e-1)}this.#m||(this.#m=!0,ct(()=>{this.#m=!1,this.linked&&this.flush()}))}transfer_effects(e,t){for(let t of e)this.#u.add(t);for(let e of t)this.#d.add(e);e.clear(),t.clear()}oncommit(e){this.#r.add(e)}ondiscard(e){this.#i.add(e)}settled(){return(this.#s??=m()).promise}static ensure(){if(M===null){let t=M=new e;!Ht&&!Vt&&ct(()=>{t.#e||t.flush()})}return M}apply(){if(!Ye||!this.is_fork&&this.#t===null&&this.#n===null){zt=null;return}zt=new Map;for(let[e,[t]]of this.current)zt.set(e,t);for(let t=It;t!==null;t=t.#n)if(!(t===this||t.is_fork)){var e=!1;if(t.id<this.id){for(let[n,[,r]]of t.current)if(!r&&this.current.has(n)){e=!0;break}}if(!e)for(let[e,n]of t.previous)zt.has(e)||zt.set(e,n)}}schedule(e){if(Bt=e,e.b?.is_pending&&e.f&16777228&&!(e.f&32768)){e.b.defer_effect(e);return}for(var t=e;t.parent!==null;){t=t.parent;var n=t.f;if(Ut!==null&&t===V&&(Ye||(B===null||!(B.f&2))&&!gt))return;if(n&96){if(!(n&1024))return;t.f^=_}}this.#c.push(t)}#S(){if(this.linked){var e=this.#t,t=this.#n;e===null?It=t:e.#n=t,t===null?Lt=e:t.#t=e,this.linked=!1}}};function Jt(e){var t=Vt;Vt=!0;try{var n;for(e&&(M!==null&&!M.is_fork&&M.flush(),n=e());;){if(lt(),M===null)return n;M.flush()}}finally{Vt=t}}function Yt(){try{Ee()}catch(e){dt(e,Bt)}}var Xt=null;function Zt(e){var t=e.length;if(t!==0){for(var n=0;n<t;){var r=e[n++];if(!(r.f&24576)&&Cr(r)&&(Xt=new Set,Or(r),r.deps===null&&r.first===null&&r.nodes===null&&r.teardown===null&&r.ac===null&&$n(r),Xt?.size>0)){an.clear();for(let e of Xt){if(e.f&24576)continue;let t=[e],n=e.parent;for(;n!==null;)Xt.has(n)&&(Xt.delete(n),t.push(n)),n=n.parent;for(let e=t.length-1;e>=0;e--){let n=t[e];n.f&24576||Or(n)}}Xt.clear()}}Xt=null}}function Qt(e,t,n,r){if(!n.has(e)&&(n.add(e),e.reactions!==null))for(let i of e.reactions){let e=i.f;e&2?Qt(i,t,n,r):e&4194320&&!(e&2048)&&$t(i,t,r)&&(A(i,v),en(i))}}function $t(e,t,r){let i=r.get(e);if(i!==void 0)return i;if(e.deps!==null)for(let i of e.deps){if(n.call(t,i))return!0;if(i.f&2&&$t(i,t,r))return r.set(i,!0),!0}return r.set(e,!1),!1}function en(e){M.schedule(e)}function tn(e,t){if(!(e.f&32&&e.f&1024)){e.f&2048?t.d.push(e):e.f&4096&&t.m.push(e),A(e,_);for(var n=e.first;n!==null;)tn(n,t),n=n.next}}function nn(e){A(e,_);for(var t=e.first;t!==null;)nn(t),t=t.next}var rn=new Set,an=new Map,on=!1;function sn(e,t){return{f:0,v:e,reactions:null,equals:Ke,rv:0,wv:0}}function N(e,t){let n=sn(e,t);return pr(n),n}function cn(e,t=!1,n=!0){let r=sn(e);return t||(r.equals=Je),Xe&&n&&D!==null&&D.l!==null&&(D.l.s??=[]).push(r),r}function P(e,t,n=!1){return B!==null&&(!lr||B.f&131072)&&rt()&&B.f&4325394&&(fr===null||!fr.has(e))&&je(),ln(e,n?pn(t):t,Wt)}function ln(e,t,n=null){if(!e.equals(t)){an.set(e,sr?t:e.v);var r=qt.ensure();if(r.capture(e,t),e.f&2){let t=e;e.f&2048&&Mt(t),zt===null&&pt(t)}e.wv=Sr(),fn(e,v,n),rt()&&V!==null&&V.f&1024&&!(V.f&96)&&(gr===null?_r([e]):gr.push(e)),!r.is_fork&&rn.size>0&&!on&&un()}return t}function un(){on=!1;for(let e of rn){e.f&1024&&A(e,y);let t;try{t=Cr(e)}catch{t=!0}t&&Or(e)}rn.clear()}function dn(e){P(e,e.v+1)}function fn(e,t,n){var r=e.reactions;if(r!==null)for(var i=rt(),a=r.length,o=0;o<a;o++){var s=r[o],c=s.f;if(!(!i&&s===V)){var l=(c&v)===0;if(l&&A(s,t),c&131072)rn.add(s);else if(c&2){var u=s;zt?.delete(u),c&65536||(c&512&&(V===null||!(V.f&2097152))&&(s.f|=oe),fn(u,y,n))}else if(l){var d=s;c&16&&Xt!==null&&Xt.add(d),n===null?en(d):n.push(d)}}}}function pn(t){if(typeof t!=`object`||!t||ue in t)return t;let n=l(t);if(n!==s&&n!==c)return t;var r=new Map,i=e(t),o=N(0),u=null,d=br,f=e=>{if(br===d)return e();var t=B,n=br;ur(null),xr(d);var r=e();return ur(t),xr(n),r};return i&&r.set(`length`,N(t.length,u)),new Proxy(t,{defineProperty(e,t,n){(!(`value`in n)||n.configurable===!1||n.enumerable===!1||n.writable===!1)&&ke();var i=r.get(t);return i===void 0?f(()=>{var e=N(n.value,u);return r.set(t,e),e}):P(i,n.value,!0),!0},deleteProperty(e,t){var n=r.get(t);if(n===void 0){if(t in e){let e=f(()=>N(S,u));r.set(t,e),dn(o)}}else P(n,S),dn(o);return!0},get(e,n,i){if(n===ue)return t;var o=r.get(n),s=n in e;if(o===void 0&&(!s||a(e,n)?.writable)&&(o=f(()=>N(pn(s?e[n]:S),u)),r.set(n,o)),o!==void 0){var c=H(o);return c===S?void 0:c}return Reflect.get(e,n,i)},getOwnPropertyDescriptor(e,t){var n=Reflect.getOwnPropertyDescriptor(e,t);if(n&&`value`in n){var i=r.get(t);i&&(n.value=H(i))}else if(n===void 0){var a=r.get(t),o=a?.v;if(a!==void 0&&o!==S)return{enumerable:!0,configurable:!0,value:o,writable:!0}}return n},has(e,t){if(t===ue)return!0;var n=r.get(t),i=n!==void 0&&n.v!==S||Reflect.has(e,t);return(n!==void 0||V!==null&&(!i||a(e,t)?.writable))&&(n===void 0&&(n=f(()=>N(i?pn(e[t]):S,u)),r.set(t,n)),H(n)===S)?!1:i},set(e,t,n,s){var c=r.get(t),l=t in e;if(i&&t===`length`)for(var d=n;d<c.v;d+=1){var p=r.get(d+``);p===void 0?d in e&&(p=f(()=>N(S,u)),r.set(d+``,p)):P(p,S)}if(c===void 0)(!l||a(e,t)?.writable)&&(c=f(()=>N(void 0,u)),P(c,pn(n)),r.set(t,c));else{l=c.v!==S;var m=f(()=>pn(n));P(c,m)}var h=Reflect.getOwnPropertyDescriptor(e,t);if(h?.set&&h.set.call(s,n),!l){if(i&&typeof t==`string`){var g=r.get(`length`),_=Number(t);Number.isInteger(_)&&_>=g.v&&P(g,_+1)}dn(o)}return!0},ownKeys(e){H(o);var t=Reflect.ownKeys(e).filter(e=>{var t=r.get(e);return t===void 0||t.v!==S});for(var[n,i]of r)i.v!==S&&!(n in e)&&t.push(n);return t},setPrototypeOf(){Ae()}})}function mn(e){try{if(typeof e==`object`&&e&&ue in e)return e[ue]}catch{}return e}function hn(e,t){return Object.is(mn(e),mn(t))}new Set([`copyWithin`,`fill`,`pop`,`push`,`reverse`,`shift`,`sort`,`splice`,`unshift`]);var gn,_n,vn,yn;function bn(){if(gn===void 0){gn=window,_n=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,n=Text.prototype;vn=a(t,`firstChild`).get,yn=a(t,`nextSibling`).get,u(e)&&(e[me]=void 0,e[pe]=null,e[he]=void 0,e.__e=void 0),u(n)&&(n[ge]=void 0)}}function xn(e=``){return document.createTextNode(e)}function Sn(e){return vn.call(e)}function Cn(e){return yn.call(e)}function F(e,t){if(!C)return Sn(e);var n=Sn(w);if(n===null)n=w.appendChild(xn());else if(t&&n.nodeType!==3){var r=xn();return n?.before(r),T(r),r}return t&&Dn(n),T(n),n}function I(e,t=!1){if(!C){var n=Sn(e);return n instanceof Comment&&n.data===``?Cn(n):n}if(t){if(w?.nodeType!==3){var r=xn();return w?.before(r),T(r),r}Dn(w)}return w}function L(e,t=1,n=!1){let r=C?w:e;for(var i;t--;)i=r,r=Cn(r);if(!C)return r;if(n){if(r?.nodeType!==3){var a=xn();return r===null?i?.after(a):r.before(a),T(a),a}Dn(r)}return T(r),r}function wn(e){e.textContent=``}function Tn(){return!Ye||Xt!==null?!1:(V.f&x)!==0}function En(e,t,n){return t==null||t===`http://www.w3.org/1999/xhtml`?n?document.createElement(e,{is:n}):document.createElement(e):n?document.createElementNS(t,e,{is:n}):document.createElementNS(t,e)}function Dn(e){if(e.nodeValue.length<65536)return;let t=e.nextSibling;for(;t!==null&&t.nodeType===3;)t.remove(),e.nodeValue+=t.nodeValue,t=e.nextSibling}function On(e,t){if(t){let t=document.body;e.autofocus=!0,ct(()=>{document.activeElement===t&&e.focus()})}}var kn=!1;function An(){kn||(kn=!0,document.addEventListener(`reset`,e=>{Promise.resolve().then(()=>{if(!e.defaultPrevented)for(let t of e.target.elements)t[_e]?.()})},{capture:!0}))}function jn(e){var t=B,n=V;ur(null),dr(null);try{return e()}finally{ur(t),dr(n)}}function Mn(e,t,n,r=n){e.addEventListener(t,()=>jn(n));let i=e[_e];i?e[_e]=()=>{i(),r(!0)}:e[_e]=()=>r(!0),An()}function Nn(e){V===null&&(B===null&&Te(e),we()),sr&&Ce(e)}function Pn(e,t){var n=t.last;n===null?t.last=t.first=e:(n.next=e,e.prev=n,t.last=e)}function Fn(e,t){var n=V;n!==null&&n.f&8192&&(e|=b);var r={ctx:D,deps:null,nodes:null,f:e|v|512,first:null,fn:t,last:null,next:null,parent:n,b:n&&n.b,prev:null,teardown:null,wv:0,ac:null};M?.register_created_effect(r);var i=r;if(e&4)Ut===null?qt.ensure().schedule(r):Ut.push(r);else if(t!==null){try{Or(r)}catch(e){throw z(r),e}i.deps===null&&i.teardown===null&&i.nodes===null&&i.first===i.last&&!(i.f&524288)&&(i=i.first,e&16&&e&65536&&i!==null&&(i.f|=ne))}if(i!==null&&(i.parent=n,n!==null&&Pn(i,n),B!==null&&B.f&2&&!(e&64))){var a=B;(a.effects??=[]).push(i)}return r}function In(){return B!==null&&!lr}function Ln(e){let t=Fn(8,null);return A(t,_),t.teardown=e,t}function Rn(e){Nn(`$effect`);var t=V.f;if(!B&&t&32&&D!==null&&!D.i){var n=D;(n.e??=[]).push(e)}else return zn(e)}function zn(e){return Fn(4|ie,e)}function Bn(e){return Nn(`$effect.pre`),Fn(8|ie,e)}function Vn(e){qt.ensure();let t=Fn(64|re,e);return()=>{z(t)}}function Hn(e){qt.ensure();let t=Fn(64|re,e);return(e={})=>new Promise(n=>{e.outro?er(t,()=>{z(t),n(void 0)}):(z(t),n(void 0))})}function Un(e){return Fn(4,e)}function Wn(e){return Fn(ce|re,e)}function Gn(e,t=0){return Fn(8|t,e)}function R(e,t=[],n=[],r=[]){Ct(r,t,n,t=>{Fn(8,()=>{e(...t.map(H))})})}function Kn(e,t=0){return Fn(16|t,e)}function qn(e,t=0){return Fn(g|t,e)}function Jn(e){return Fn(32|re,e)}function Yn(e){var t=e.teardown;if(t!==null){let e=sr,n=B;cr(!0),ur(null);try{t.call(null)}finally{cr(e),ur(n)}}}function Xn(e,t=!1){var n=e.first;for(e.first=e.last=null;n!==null;){let e=n.ac;e!==null&&jn(()=>{e.abort(ve)});var r=n.next;n.f&64?n.parent=null:z(n,t),n=r}}function Zn(e){for(var t=e.first;t!==null;){var n=t.next;t.f&32||z(t),t=n}}function z(e,t=!0){var n=!1;(t||e.f&262144)&&e.nodes!==null&&e.nodes.end!==null&&(Qn(e.nodes.start,e.nodes.end),n=!0),e.f|=te,Xn(e,t&&!n),Dr(e,0);var r=e.nodes&&e.nodes.t;if(r!==null)for(let e of r)e.stop();Yn(e),e.f^=te,e.f|=ee;var i=e.parent;i!==null&&i.first!==null&&$n(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=e.b=null}function Qn(e,t){for(;e!==null;){var n=e===t?null:Cn(e);e.remove(),e=n}}function $n(e){var t=e.parent,n=e.prev,r=e.next;n!==null&&(n.next=r),r!==null&&(r.prev=n),t!==null&&(t.first===e&&(t.first=r),t.last===e&&(t.last=n))}function er(e,t,n=!0){var r=[];tr(e,r,!0);var i=()=>{n&&z(e),t&&t()},a=r.length;if(a>0){var o=()=>--a||i();for(var s of r)s.out(o)}else i()}function tr(e,t,n){if(!(e.f&8192)){e.f^=b;var r=e.nodes&&e.nodes.t;if(r!==null)for(let e of r)(e.is_global||n)&&t.push(e);for(var i=e.first;i!==null;){var a=i.next;if(!(i.f&64)){var o=(i.f&65536)!=0||(i.f&32)!=0&&(e.f&16)!=0;tr(i,t,o?n:!1)}i=a}}}function nr(e){rr(e,!0)}function rr(e,t){if(e.f&8192){e.f^=b,e.f&1024||(A(e,v),qt.ensure().schedule(e));for(var n=e.first;n!==null;){var r=n.next,i=(n.f&65536)!=0||(n.f&32)!=0;rr(n,i?t:!1),n=r}var a=e.nodes&&e.nodes.t;if(a!==null)for(let e of a)(e.is_global||t)&&e.in()}}function ir(e,t){if(e.nodes)for(var n=e.nodes.start,r=e.nodes.end;n!==null;){var i=n===r?null:Cn(n);t.append(n),n=i}}var ar=null,or=!1,sr=!1;function cr(e){sr=e}var B=null,lr=!1;function ur(e){B=e}var V=null;function dr(e){V=e}var fr=null;function pr(e){B!==null&&(!Ye||B.f&2)&&(fr??=new Set).add(e)}var mr=null,hr=0,gr=null;function _r(e){gr=e}var vr=1,yr=0,br=yr;function xr(e){br=e}function Sr(){return++vr}function Cr(e){var t=e.f;if(t&2048)return!0;if(t&2&&(e.f&=~oe),t&4096){for(var n=e.deps,r=n.length,i=0;i<r;i++){var a=n[i];if(Cr(a)&&Nt(a),a.wv>e.wv)return!0}t&512&&zt===null&&A(e,_)}return!1}function wr(e,t,n=!0){var r=e.reactions;if(r!==null&&!(!Ye&&fr!==null&&fr.has(e)))for(var i=0;i<r.length;i++){var a=r[i];a.f&2?wr(a,t,!1):t===a&&(n?A(a,v):a.f&1024&&A(a,y),en(a))}}function Tr(e){var t=mr,n=hr,r=gr,i=B,a=fr,o=D,s=lr,c=br,l=e.f;mr=null,hr=0,gr=null,B=l&96?null:e,fr=null,Qe(e.ctx),lr=!1,br=++yr,e.ac!==null&&(jn(()=>{e.ac.abort(ve)}),e.ac=null);try{e.f|=se;var u=e.fn,d=u();e.f|=x;var f=e.deps,p=M?.is_fork;if(mr!==null){var m;if(p||Dr(e,hr),f!==null&&hr>0)for(f.length=hr+mr.length,m=0;m<mr.length;m++)f[hr+m]=mr[m];else e.deps=f=mr;if(In()&&e.f&512)for(m=hr;m<f.length;m++)(f[m].reactions??=[]).push(e)}else !p&&f!==null&&hr<f.length&&(Dr(e,hr),f.length=hr);if(rt()&&gr!==null&&!lr&&f!==null&&!(e.f&6146))for(m=0;m<gr.length;m++)wr(gr[m],e);if(i!==null&&i!==e){if(yr++,i.deps!==null)for(let e=0;e<n;e+=1)i.deps[e].rv=yr;if(t!==null)for(let e of t)e.rv=yr;gr!==null&&(r===null?r=gr:r.push(...gr))}return e.f&8388608&&(e.f^=le),d}catch(e){return ut(e)}finally{e.f^=se,mr=t,hr=n,gr=r,B=i,fr=a,Qe(o),lr=s,br=c}}function Er(e,r){let i=r.reactions;if(i!==null){var a=t.call(i,e);if(a!==-1){var o=i.length-1;o===0?i=r.reactions=null:(i[a]=i[o],i.pop())}}if(i===null&&r.f&2&&(mr===null||!n.call(mr,r))){var s=r;s.f&512&&(s.f^=512,s.f&=~oe),s.v!==S&&pt(s),Pt(s),Dr(s,0)}}function Dr(e,t){var n=e.deps;if(n!==null)for(var r=t;r<n.length;r++)Er(e,n[r])}function Or(e){var t=e.f;if(!(t&16384)){A(e,_);var n=V,r=or;V=e,or=!0;try{t&16777232?Zn(e):Xn(e),Yn(e);var i=Tr(e);e.teardown=typeof i==`function`?i:null,e.wv=vr}finally{or=r,V=n}}}async function kr(){if(Ye)return new Promise(e=>{requestAnimationFrame(()=>e()),setTimeout(()=>e())});await Promise.resolve(),Jt()}function H(e){var t=(e.f&2)!=0;if(ar?.add(e),B!==null&&!lr&&!(V!==null&&V.f&16384)&&(fr===null||!fr.has(e))){var r=B.deps;if(B.f&2097152)e.rv<yr&&(e.rv=yr,mr===null&&r!==null&&r[hr]===e?hr++:mr===null?mr=[e]:mr.push(e));else{B.deps??=[],n.call(B.deps,e)||B.deps.push(e);var i=e.reactions;i===null?e.reactions=[B]:n.call(i,B)||i.push(B)}}if(sr&&an.has(e))return an.get(e);if(t){var a=e;if(sr){var o=a.v;return(!(a.f&1024)&&a.reactions!==null||jr(a))&&(o=Mt(a)),an.set(a,o),o}var s=(a.f&512)==0&&!lr&&B!==null&&(or||(B.f&512)!=0),c=(a.f&x)===0;Cr(a)&&(s&&(a.f|=512),Nt(a)),s&&!c&&(Ft(a),Ar(a))}if(zt?.has(e))return zt.get(e);if(e.f&8388608)throw e.v;return e.v}function Ar(e){if(e.f|=512,e.deps!==null)for(let t of e.deps)(t.reactions??=[]).push(e),t.f&2&&!(t.f&512)&&(Ft(t),Ar(t))}function jr(e){if(e.v===S)return!0;if(e.deps===null)return!1;for(let t of e.deps)if(an.has(t)||t.f&2&&jr(t))return!0;return!1}function Mr(e){var t=lr;try{return lr=!0,e()}finally{lr=t}}function Nr(){return Symbol(Ie)}function Pr(e){return e.endsWith(`capture`)&&e!==`gotpointercapture`&&e!==`lostpointercapture`}var Fr=[`beforeinput`,`click`,`change`,`dblclick`,`contextmenu`,`focusin`,`focusout`,`input`,`keydown`,`keyup`,`mousedown`,`mousemove`,`mouseout`,`mouseover`,`mouseup`,`pointerdown`,`pointermove`,`pointerout`,`pointerover`,`pointerup`,`touchend`,`touchmove`,`touchstart`];function Ir(e){return Fr.includes(e)}var Lr=`allowfullscreen.async.autofocus.autoplay.checked.controls.default.disabled.formnovalidate.indeterminate.inert.ismap.loop.multiple.muted.nomodule.novalidate.open.playsinline.readonly.required.reversed.seamless.selected.webkitdirectory.defer.disablepictureinpicture.disableremoteplayback`.split(`.`),Rr={formnovalidate:`formNoValidate`,ismap:`isMap`,nomodule:`noModule`,playsinline:`playsInline`,readonly:`readOnly`,defaultvalue:`defaultValue`,defaultchecked:`defaultChecked`,srcobject:`srcObject`,novalidate:`noValidate`,allowfullscreen:`allowFullscreen`,disablepictureinpicture:`disablePictureInPicture`,disableremoteplayback:`disableRemotePlayback`};function zr(e){return e=e.toLowerCase(),Rr[e]??e}[...Lr];var Br=[`touchstart`,`touchmove`];function Vr(e){return Br.includes(e)}var Hr=[`textarea`,`script`,`style`,`title`];function Ur(e){return Hr.includes(e)}var Wr=Symbol(`events`),Gr=new Set,Kr=new Set;function qr(e,t,n,r={}){function i(e){if(r.capture||Qr.call(t,e),!e.cancelBubble)return jn(()=>n?.call(this,e))}return e.startsWith(`pointer`)||e.startsWith(`touch`)||e===`wheel`?ct(()=>{t.addEventListener(e,i,r)}):t.addEventListener(e,i,r),i}function Jr(e,t,n,r={}){var i=qr(t,e,n,r);return()=>{e.removeEventListener(t,i,r)}}function Yr(e,t,n){(t[Wr]??={})[e]=n}function Xr(e){for(var t=0;t<e.length;t++)Gr.add(e[t]);for(var n of Kr)n(e)}var Zr=null;function Qr(e){var t=this,n=t.ownerDocument,r=e.type,a=e.composedPath?.()||[],o=a[0]||e.target;Zr=e;var s=0,c=Zr===e&&e[Wr];if(c){var l=a.indexOf(c);if(l!==-1&&(t===document||t===window)){e[Wr]=t;return}var u=a.indexOf(t);if(u===-1)return;l<=u&&(s=l)}if(o=a[s]||e.target,o!==t){i(e,`currentTarget`,{configurable:!0,get(){return o||n}});var d=B,f=V;ur(null),dr(null);try{for(var p,m=[];o!==null&&o!==t;){try{var h=o[Wr]?.[r];h!=null&&(!o.disabled||e.target===o)&&h.call(o,e)}catch(e){p?m.push(e):p=e}if(e.cancelBubble)break;s++,o=s<a.length?a[s]:null}if(p){for(let e of m)queueMicrotask(()=>{throw e});throw p}}finally{e[Wr]=t,delete e.currentTarget,ur(d),dr(f)}}}var $r=globalThis?.window?.trustedTypes&&globalThis.window.trustedTypes.createPolicy(`svelte-trusted-html`,{createHTML:e=>e});function ei(e){return $r?.createHTML(e)??e}function ti(e){var t=En(`template`);return t.innerHTML=ei(e.replaceAll(`<!>`,`\\x3C!---->`)),t.content}function ni(e,t){var n=V;n.nodes===null&&(n.nodes={start:e,end:t,a:null,t:null})}function U(e,t){var n=(t&1)!=0,r=(t&2)!=0,i,a=!e.startsWith(`<!>`);return()=>{if(C)return ni(w,null),w;i===void 0&&(i=ti(a?e:`<!>`+e),n||(i=Sn(i)));var t=r||_n?document.importNode(i,!0):i.cloneNode(!0);if(n){var o=Sn(t),s=t.lastChild;ni(o,s)}else ni(t,t);return t}}function ri(e,t,n=`svg`){var r=!e.startsWith(`<!>`),i=(t&1)!=0,a=`<${n}>${r?e:`<!>`+e}</${n}>`,o;return()=>{if(C)return ni(w,null),w;if(!o){var e=Sn(ti(a));if(i)for(o=document.createDocumentFragment();Sn(e);)o.appendChild(Sn(e));else o=Sn(e)}var t=o.cloneNode(!0);if(i){var n=Sn(t),r=t.lastChild;ni(n,r)}else ni(t,t);return t}}function ii(e,t){return ri(e,t,`svg`)}function ai(e=``){if(!C){var t=xn(e+``);return ni(t,t),t}var n=w;return n.nodeType===3?Dn(n):(n.before(n=xn()),T(n)),ni(n,n),n}function W(){if(C)return ni(w,null),w;var e=document.createDocumentFragment(),t=document.createComment(``),n=xn();return e.append(t,n),ni(t,n),e}function G(e,t){if(C){var n=V;(!(n.f&32768)||n.nodes.end===null)&&(n.nodes.end=w),He();return}e!==null&&e.before(t)}function oi(){if(C&&w&&w.nodeType===8&&w.textContent?.startsWith(`$`)){let e=w.textContent.substring(1);return He(),e}return(window.__svelte??={}).uid??=1,`c${window.__svelte.uid++}`}function K(e,t){var n=t==null?``:typeof t==`object`?`${t}`:t;n!==(e[ge]??=e.nodeValue)&&(e[ge]=n,e.nodeValue=`${n}`)}function si(e,t){return li(e,t)}var ci=new Map;function li(e,{target:t,anchor:n,props:i={},events:a,context:o,intro:s=!0,transformError:c}){bn();var l=void 0,u=Hn(()=>{var s=n??t.appendChild(xn());xt(s,{pending:()=>{}},t=>{O({});var n=D;if(o&&(n.c=o),a&&(i.$$events=a),C&&ni(t,null),l=e(t,i)||{},C&&(V.nodes.end=w,w===null||w.nodeType!==8||w.data!==`]`))throw Re(),Ne;k()},c);var u=new Set,d=e=>{for(var n=0;n<e.length;n++){var r=e[n];if(!u.has(r)){u.add(r);var i=Vr(r);for(let e of[t,document]){var a=ci.get(e);a===void 0&&(a=new Map,ci.set(e,a));var o=a.get(r);o===void 0?(e.addEventListener(r,Qr,{passive:i}),a.set(r,1)):a.set(r,o+1)}}}};return d(r(Gr)),Kr.add(d),()=>{for(var e of u)for(let n of[t,document]){var r=ci.get(n),i=r.get(e);--i==0?(n.removeEventListener(e,Qr),r.delete(e),r.size===0&&ci.delete(n)):r.set(e,i)}Kr.delete(d),s!==n&&s.parentNode?.removeChild(s)}});return ui.set(l,u),l}var ui=new WeakMap;function di(e,t){let n=ui.get(e);return n?(ui.delete(e),n(t)):Promise.resolve()}var fi=class{anchor;#e=new Map;#t=new Map;#n=new Map;#r=new Set;#i=!0;constructor(e,t=!0){this.anchor=e,this.#i=t}#a=e=>{if(this.#e.has(e)){var t=this.#e.get(e),n=this.#t.get(t);if(n)nr(n),this.#r.delete(t);else{var r=this.#n.get(t);r&&(nr(r.effect),this.#t.set(t,r.effect),this.#n.delete(t),r.fragment.lastChild.remove(),this.anchor.before(r.fragment),n=r.effect)}for(let[t,n]of this.#e){if(this.#e.delete(t),t===e)break;let r=this.#n.get(n);r&&(z(r.effect),this.#n.delete(n))}for(let[e,r]of this.#t){if(e===t||this.#r.has(e))continue;let i=()=>{if(Array.from(this.#e.values()).includes(e)){var t=document.createDocumentFragment();ir(r,t),t.append(xn()),this.#n.set(e,{effect:r,fragment:t})}else z(r);this.#r.delete(e),this.#t.delete(e)};this.#i||!n?(this.#r.add(e),er(r,i,!1)):i()}}};#o=e=>{this.#e.delete(e);let t=Array.from(this.#e.values());for(let[e,n]of this.#n)t.includes(e)||(z(n.effect),this.#n.delete(e))};ensure(e,t){var n=M,r=Tn();if(t&&!this.#t.has(e)&&!this.#n.has(e))if(r){var i=document.createDocumentFragment(),a=xn();i.append(a),this.#n.set(e,{effect:Jn(()=>t(a)),fragment:i})}else this.#t.set(e,Jn(()=>t(this.anchor)));if(this.#e.set(n,e),r){for(let[t,r]of this.#t)t===e?n.unskip_effect(r):n.skip_effect(r);for(let[t,r]of this.#n)t===e?n.unskip_effect(r.effect):n.skip_effect(r.effect);n.oncommit(this.#a),n.ondiscard(this.#o)}else C&&(this.anchor=w),this.#a(n)}};function q(e,t,n=!1){var r;C&&(r=w,He());var i=new fi(e),a=n?ne:0;function o(e,t){if(C){var n=Ge(r);if(e!==parseInt(n.substring(1))){var a=We();T(a),i.anchor=a,Ve(!1),i.ensure(e,t),Ve(!0);return}}i.ensure(e,t)}Kn(()=>{var e=!1;t((t,n=0)=>{e=!0,o(n,t)}),e||o(-1,null)},a)}var pi=Symbol(`NaN`);function mi(e,t,n){C&&He();var r=new fi(e),i=!rt();Kn(()=>{var e=t();e!==e&&(e=pi),i&&typeof e==`object`&&e&&(e={}),r.ensure(e,n)})}function hi(e,t){return t}function gi(e,t,n){for(var i=[],a=t.length,o,s=t.length,c=0;c<a;c++){let n=t[c];er(n,()=>{if(o){if(o.pending.delete(n),o.done.add(n),o.pending.size===0){var t=e.outrogroups;_i(e,r(o.done)),t.delete(o),t.size===0&&(e.outrogroups=null)}}else --s},!1)}if(s===0){var l=i.length===0&&n!==null;if(l){var u=n,d=u.parentNode;wn(d),d.append(u),e.items.clear()}_i(e,t,!l)}else o={pending:new Set(t),done:new Set},(e.outrogroups??=new Set).add(o)}function _i(e,t,n=!0){var r;if(e.pending.size>0){r=new Set;for(let t of e.pending.values())for(let n of t)r.add(e.items.get(n).e)}for(var i=0;i<t.length;i++){var a=t[i];r?.has(a)?(a.f|=ae,ir(a,document.createDocumentFragment())):z(t[i],n)}}var vi;function yi(t,n,i,a,o,s=null){var c=t,l=new Map;if(n&4){var u=t;c=C?T(Sn(u)):u.appendChild(xn())}C&&He();var d=null,f=At(()=>{var t=i();return e(t)?t:t==null?[]:r(t)}),p,m=new Map,h=!0;function g(e){v.effect.f&16384||(v.pending.delete(e),v.fallback=d,xi(v,p,c,n,a),d!==null&&(p.length===0?d.f&33554432?(d.f^=ae,Ci(d,null,c)):nr(d):er(d,()=>{d=null})))}function _(e){v.pending.delete(e)}var v={effect:Kn(()=>{p=H(f);var e=p.length;let t=!1;C&&Ge(c)===`[!`!=(e===0)&&(c=We(),T(c),Ve(!1),t=!0);for(var r=new Set,u=M,v=Tn(),y=0;y<e;y+=1){C&&w.nodeType===8&&w.data===`]`&&(c=w,t=!0,Ve(!1));var b=p[y],ee=a(b,y),x=h?null:l.get(ee);x?(x.v&&ln(x.v,b),x.i&&ln(x.i,y),v&&u.unskip_effect(x.e)):(x=Si(l,h?c:vi??=xn(),b,ee,y,o,n,i),h||(x.e.f|=ae),l.set(ee,x)),r.add(ee)}if(e===0&&s&&!d&&(h?d=Jn(()=>s(c)):(d=Jn(()=>s(vi??=xn())),d.f|=ae)),e>r.size&&Se(``,``,``),C&&e>0&&T(We()),!h)if(m.set(u,r),v){for(let[e,t]of l)r.has(e)||u.skip_effect(t.e);u.oncommit(g),u.ondiscard(_)}else g(u);t&&Ve(!0),H(f)}),flags:n,items:l,pending:m,outrogroups:null,fallback:d};h=!1,C&&(c=w)}function bi(e){for(;e!==null&&!(e.f&32);)e=e.next;return e}function xi(e,t,n,i,a){var o=(i&8)!=0,s=t.length,c=e.items,l=bi(e.effect.first),u,d=null,f,p=[],m=[],h,g,_,v;if(o)for(v=0;v<s;v+=1)h=t[v],g=a(h,v),_=c.get(g).e,_.f&33554432||(_.nodes?.a?.measure(),(f??=new Set).add(_));for(v=0;v<s;v+=1){if(h=t[v],g=a(h,v),_=c.get(g).e,e.outrogroups!==null)for(let t of e.outrogroups)t.pending.delete(_),t.done.delete(_);if(_.f&8192&&(nr(_),o&&(_.nodes?.a?.unfix(),(f??=new Set).delete(_))),_.f&33554432)if(_.f^=ae,_===l)Ci(_,null,n);else{var y=d?d.next:l;_===e.effect.last&&(e.effect.last=_.prev),_.prev&&(_.prev.next=_.next),_.next&&(_.next.prev=_.prev),wi(e,d,_),wi(e,_,y),Ci(_,y,n),d=_,p=[],m=[],l=bi(d.next);continue}if(_!==l){if(u!==void 0&&u.has(_)){if(p.length<m.length){var b=m[0],ee;d=b.prev;var x=p[0],te=p[p.length-1];for(ee=0;ee<p.length;ee+=1)Ci(p[ee],b,n);for(ee=0;ee<m.length;ee+=1)u.delete(m[ee]);wi(e,x.prev,te.next),wi(e,d,x),wi(e,te,b),l=b,d=te,--v,p=[],m=[]}else u.delete(_),Ci(_,l,n),wi(e,_.prev,_.next),wi(e,_,d===null?e.effect.first:d.next),wi(e,d,_),d=_;continue}for(p=[],m=[];l!==null&&l!==_;)(u??=new Set).add(l),m.push(l),l=bi(l.next);if(l===null)continue}_.f&33554432||p.push(_),d=_,l=bi(_.next)}if(e.outrogroups!==null){for(let t of e.outrogroups)t.pending.size===0&&(_i(e,r(t.done)),e.outrogroups?.delete(t));e.outrogroups.size===0&&(e.outrogroups=null)}if(l!==null||u!==void 0){var ne=[];if(u!==void 0)for(_ of u)_.f&8192||ne.push(_);for(;l!==null;)!(l.f&8192)&&l!==e.fallback&&ne.push(l),l=bi(l.next);var re=ne.length;if(re>0){var ie=i&4&&s===0?n:null;if(o){for(v=0;v<re;v+=1)ne[v].nodes?.a?.measure();for(v=0;v<re;v+=1)ne[v].nodes?.a?.fix()}gi(e,ne,ie)}}o&&ct(()=>{if(f!==void 0)for(_ of f)_.nodes?.a?.apply()})}function Si(e,t,n,r,i,a,o,s){var c=o&1?o&16?sn(n):cn(n,!1,!1):null,l=o&2?sn(i):null;return{v:c,i:l,e:Jn(()=>(a(t,c??n,l??i,s),()=>{e.delete(r)}))}}function Ci(e,t,n){if(e.nodes)for(var r=e.nodes.start,i=e.nodes.end,a=t&&!(t.f&33554432)?t.nodes.start:n;r!==null;){var o=Cn(r);if(a.before(r),r===i)return;r=o}}function wi(e,t,n){t===null?e.effect.first=n:t.next=n,n===null?e.effect.last=t:n.prev=t}function J(e,t,...n){var r=new fi(e);Kn(()=>{let e=t()??null;r.ensure(e,e&&(t=>e(t,...n)))},ne)}function Ti(e,t,n){var r;C&&(r=w,He());var i=new fi(e);Kn(()=>{var e=t()??null;if(C&&Ge(r)===`[`!=(e!==null)){var a=We();T(a),i.anchor=a,Ve(!1),i.ensure(e,e&&(t=>n(t,e))),Ve(!0);return}i.ensure(e,e&&(t=>n(t,e)))},ne)}function Ei(e,t,n,r,i,a){let o=C;C&&He();var s=null;C&&w.nodeType===1&&(s=w,He());var c=C?w:e,l=new fi(c,!1);Kn(()=>{let e=t()||null;var a=i?i():n||e===`svg`?Fe:void 0;if(e===null){l.ensure(null,null);return}return l.ensure(e,t=>{if(e){if(s=C?s:En(e,a),ni(s,s),r){var n=null;C&&Ur(e)&&s.append(n=document.createComment(``));var i=C?Sn(s):s.appendChild(xn());C&&(i===null?Ve(!1):T(i)),r(s,i),n?.remove()}V.nodes.end=s,t.before(s)}C&&T(t)}),()=>{}},ne),Ln(()=>{}),o&&(Ve(!0),T(c))}function Di(e,t){var n=void 0,r;qn(()=>{n!==(n=t())&&(r&&=(z(r),null),n&&(r=Jn(()=>{Un(()=>n(e))})))})}function Oi(e){var t,n,r=``;if(typeof e==`string`||typeof e==`number`)r+=e;else if(typeof e==`object`)if(Array.isArray(e)){var i=e.length;for(t=0;t<i;t++)e[t]&&(n=Oi(e[t]))&&(r&&(r+=` `),r+=n)}else for(n in e)e[n]&&(r&&(r+=` `),r+=n);return r}function ki(){for(var e,t,n=0,r=``,i=arguments.length;n<i;n++)(e=arguments[n])&&(t=Oi(e))&&(r&&(r+=` `),r+=t);return r}function Ai(e){return typeof e==`object`?ki(e):e??``}var ji=[...` \t\n\\r\\f\\xA0\\v`];function Mi(e,t,n){var r=e==null?``:``+e;if(t&&(r=r?r+` `+t:t),n){for(var i of Object.keys(n))if(n[i])r=r?r+` `+i:i;else if(r.length)for(var a=i.length,o=0;(o=r.indexOf(i,o))>=0;){var s=o+a;(o===0||ji.includes(r[o-1]))&&(s===r.length||ji.includes(r[s]))?r=(o===0?``:r.substring(0,o))+r.substring(s+1):o=s}}return r===``?null:r}function Ni(e,t=!1){var n=t?` !important;`:`;`,r=``;for(var i of Object.keys(e)){var a=e[i];a!=null&&a!==``&&(r+=` `+i+`: `+a+n)}return r}function Pi(e){return e[0]!==`-`||e[1]!==`-`?e.toLowerCase():e}function Fi(e,t){if(t){var n=``,r,i;if(Array.isArray(t)?(r=t[0],i=t[1]):r=t,e){e=String(e).replaceAll(/\\s*\\/\\*.*?\\*\\/\\s*/g,``).trim();var a=!1,o=0,s=!1,c=[];r&&c.push(...Object.keys(r).map(Pi)),i&&c.push(...Object.keys(i).map(Pi));var l=0,u=-1;let t=e.length;for(var d=0;d<t;d++){var f=e[d];if(s?f===`/`&&e[d-1]===`*`&&(s=!1):a?a===f&&(a=!1):f===`/`&&e[d+1]===`*`?s=!0:f===`\"`||f===`'`?a=f:f===`(`?o++:f===`)`&&o--,!s&&a===!1&&o===0){if(f===`:`&&u===-1)u=d;else if(f===`;`||d===t-1){if(u!==-1){var p=Pi(e.substring(l,u).trim());if(!c.includes(p)){f!==`;`&&d++;var m=e.substring(l,d).trim();n+=` `+m+`;`}}l=d+1,u=-1}}}}return r&&(n+=Ni(r)),i&&(n+=Ni(i,!0)),n=n.trim(),n===``?null:n}return e==null?null:String(e)}function Ii(e,t,n,r,i,a){var o=e[me];if(C||o!==n||o===void 0){var s=Mi(n,r,a);(!C||s!==e.getAttribute(`class`))&&(s==null?e.removeAttribute(`class`):t?e.className=s:e.setAttribute(`class`,s)),e[me]=n}else if(a&&i!==a)for(var c in a){var l=!!a[c];(i==null||l!==!!i[c])&&e.classList.toggle(c,l)}return a}function Li(e,t={},n,r){for(var i in n){var a=n[i];t[i]!==a&&(n[i]==null?e.style.removeProperty(i):e.style.setProperty(i,a,r))}}function Ri(e,t,n,r){var i=e[he];if(C||i!==t){var a=Fi(t,r);(!C||a!==e.getAttribute(`style`))&&(a==null?e.removeAttribute(`style`):e.style.cssText=a),e[he]=t}else r&&(Array.isArray(r)?(Li(e,n?.[0],r[0]),Li(e,n?.[1],r[1],`important`)):Li(e,n,r));return r}function zi(t,n,r=!1){if(t.multiple){if(n==null)return;if(!e(n))return ze();for(var i of t.options)i.selected=n.includes(Vi(i));return}for(i of t.options)if(hn(Vi(i),n)){i.selected=!0;return}(!r||n!==void 0)&&(t.selectedIndex=-1)}function Bi(e){var t=new MutationObserver(()=>{zi(e,e.__value)});t.observe(e,{childList:!0,subtree:!0,attributes:!0,attributeFilter:[`value`]}),Ln(()=>{t.disconnect()})}function Vi(e){return`__value`in e?e.__value:e.value}var Hi=Symbol(`class`),Ui=Symbol(`style`),Wi=Symbol(`is custom element`),Gi=Symbol(`is html`),Ki=ye?`link`:`LINK`,qi=ye?`input`:`INPUT`,Ji=ye?`option`:`OPTION`,Yi=ye?`select`:`SELECT`;function Xi(e){if(C){var t=!1,n=()=>{if(!t){if(t=!0,e.hasAttribute(`value`)){var n=e.value;Qi(e,`value`,null),e.value=n}if(e.hasAttribute(`checked`)){var r=e.checked;Qi(e,`checked`,null),e.checked=r}}};e[_e]=n,ct(n),An()}}function Zi(e,t){t?e.hasAttribute(`selected`)||e.setAttribute(`selected`,``):e.removeAttribute(`selected`)}function Qi(e,t,n,r){var i=ta(e);C&&(i[t]=e.getAttribute(t),t===`src`||t===`srcset`||t===`href`&&e.nodeName===Ki)||i[t]!==(i[t]=n)&&(t===`loading`&&(e[fe]=n),n==null?e.removeAttribute(t):typeof n!=`string`&&ra(e).includes(t)?e[t]=n:e.setAttribute(t,n))}function $i(e,t,n,r,i=!1,a=!1){if(C&&i&&e.nodeName===qi){var o=e;(o.type===`checkbox`?`defaultChecked`:`defaultValue`)in n||Xi(o)}var s=ta(e),c=s[Wi],l=!s[Gi];let u=C&&c;u&&Ve(!1);var d=t||{},f=e.nodeName===Ji;for(var p in t)p in n||(n[p]=null);n.class?n.class=Ai(n.class):(r||n[Hi])&&(n.class=null),n[Ui]&&(n.style??=null);var m=ra(e);if(e.nodeName===qi&&`type`in n&&(`value`in n||`__value`in n)){var h=n.type;(h!==d.type||h===void 0&&e.hasAttribute(`type`))&&(d.type=h,Qi(e,`type`,h,a))}for(let i in n){let o=n[i];if(f&&i===`value`&&o==null){e.value=e.__value=``,d[i]=o;continue}if(i===`class`){Ii(e,e.namespaceURI===`http://www.w3.org/1999/xhtml`,o,r,t?.[Hi],n[Hi]),d[i]=o,d[Hi]=n[Hi];continue}if(i===`style`){Ri(e,o,t?.[Ui],n[Ui]),d[i]=o,d[Ui]=n[Ui];continue}var g=d[i];if(!(o===g&&!(o===void 0&&e.hasAttribute(i)))){d[i]=o;var _=i[0]+i[1];if(_!==`$$`)if(_===`on`){let t={},n=`$$`+i,r=i.slice(2);var v=Ir(r);if(Pr(r)&&(r=r.slice(0,-7),t.capture=!0),!v&&g){if(o!=null)continue;e.removeEventListener(r,d[n],t),d[n]=null}if(v)Yr(r,e,o),Xr([r]);else if(o!=null){function a(e){d[i].call(this,e)}d[n]=qr(r,e,a,t)}}else if(i===`style`)Qi(e,i,o);else if(i===`autofocus`)On(e,!!o);else if(!c&&(i===`__value`||i===`value`&&o!=null))e.value=e.__value=o;else if(i===`selected`&&f)Zi(e,o);else{var y=i;l||(y=zr(y));var b=y===`defaultValue`||y===`defaultChecked`;if(o==null&&!c&&!b)if(s[i]=null,y===`value`||y===`checked`){let n=e,r=t===void 0;if(y===`value`){let e=n.defaultValue;n.removeAttribute(y),n.defaultValue=e,n.value=n.__value=r?e:null}else{let e=n.defaultChecked;n.removeAttribute(y),n.defaultChecked=e,n.checked=r?e:!1}}else e.removeAttribute(i);else b||m.includes(y)&&(c||typeof o!=`string`)?(e[y]=o,y in s&&(s[y]=S)):typeof o!=`function`&&Qi(e,y,o,a)}}}return u&&Ve(!0),d}function ea(e,t,n=[],r=[],i=[],a,o=!1,s=!1){Ct(i,n,r,n=>{var r=void 0,i={},c=e.nodeName===Yi,l=!1;if(qn(()=>{var u=t(...n.map(H)),d=$i(e,r,u,a,o,s);l&&c&&`value`in u&&zi(e,u.value);for(let e of Object.getOwnPropertySymbols(i))u[e]||z(i[e]);for(let t of Object.getOwnPropertySymbols(u)){var f=u[t];t.description===`@attach`&&(!r||f!==r[t])&&(i[t]&&z(i[t]),i[t]=Jn(()=>Di(e,()=>f))),d[t]=f}r=d}),c){var u=e;Un(()=>{zi(u,r.value,!0),Bi(u)})}l=!0})}function ta(e){return e[pe]??={[Wi]:e.nodeName.includes(`-`),[Gi]:e.namespaceURI===Pe}}var na=new Map;function ra(e){var t=e.getAttribute(`is`)||e.nodeName,n=na.get(t);if(n)return n;na.set(t,n=[]);for(var r,i=e,a=Element.prototype;a!==i;){for(var s in r=o(i),r)r[s].set&&s!==`innerHTML`&&s!==`textContent`&&s!==`innerText`&&n.push(s);i=l(i)}return n}function ia(e,t,n=t){var r=new WeakSet;Mn(e,`input`,async i=>{var a=i?e.defaultValue:e.value;if(a=aa(e)?oa(a):a,n(a),M!==null&&r.add(M),await kr(),a!==(a=t())){var o=e.selectionStart,s=e.selectionEnd,c=e.value.length;if(e.value=a??``,s!==null){var l=e.value.length;o===s&&s===c&&l>c?(e.selectionStart=l,e.selectionEnd=l):(e.selectionStart=o,e.selectionEnd=Math.min(s,l))}}}),(C&&e.defaultValue!==e.value||Mr(t)==null&&e.value)&&(n(aa(e)?oa(e.value):e.value),M!==null&&r.add(M)),Gn(()=>{var n=t();if(e===document.activeElement){var i=Ye?Rt:M;if(r.has(i))return}aa(e)&&n===oa(e.value)||e.type===`date`&&!n&&!e.value||n!==e.value&&(e.value=n??``)})}function aa(e){var t=e.type;return t===`number`||t===`range`}function oa(e){return e===``?null:+e}var sa={get(e,t){if(!e.exclude.has(t))return e.props[t]},set(e,t){return!1},getOwnPropertyDescriptor(e,t){if(!e.exclude.has(t)&&t in e.props)return{enumerable:!0,configurable:!0,value:e.props[t]}},has(e,t){return e.exclude.has(t)?!1:t in e.props},ownKeys(e){return Reflect.ownKeys(e.props).filter(t=>!e.exclude.has(t))}};function ca(e,t,n){return new Proxy({props:e,exclude:t},sa)}var la={get(e,t){let n=e.props.length;for(;n--;){let r=e.props[n];if(d(r)&&(r=r()),typeof r==`object`&&r&&t in r)return r[t]}},set(e,t,n){let r=e.props.length;for(;r--;){let i=e.props[r];d(i)&&(i=i());let o=a(i,t);if(o&&o.set)return o.set(n),!0}return!1},getOwnPropertyDescriptor(e,t){let n=e.props.length;for(;n--;){let r=e.props[n];if(d(r)&&(r=r()),typeof r==`object`&&r&&t in r){let e=a(r,t);return e&&!e.configurable&&(e.configurable=!0),e}}},has(e,t){if(t===ue||t===de)return!1;for(let n of e.props)if(d(n)&&(n=n()),n!=null&&t in n)return!0;return!1},ownKeys(e){let t=[];for(let n of e.props)if(d(n)&&(n=n()),n){for(let e in n)t.includes(e)||t.push(e);for(let e of Object.getOwnPropertySymbols(n))t.includes(e)||t.push(e)}return t}};function ua(...e){return new Proxy({props:e},la)}function Y(e,t,n,r){var i=!Xe||(n&2)!=0,o=(n&8)!=0,s=(n&16)!=0,c=r,l=!0,u=void 0,d=()=>s&&i?(u??=Dt(r),H(u)):(l&&(l=!1,c=s?Mr(r):r),c);let f;if(o){var p=ue in e||de in e;f=a(e,t)?.set??(p&&t in e?n=>e[t]=n:void 0)}var m,h=!1;o?[m,h]=vt(()=>e[t]):m=e[t],m===void 0&&r!==void 0&&(m=d(),f&&(i&&De(t),f(m)));var g=i?()=>{var n=e[t];return n===void 0?d():(l=!0,n)}:()=>{var n=e[t];return n!==void 0&&(c=void 0),n===void 0?c:n};if(i&&!(n&4))return g;if(f){var _=e.$$legacy;return(function(e,t){return arguments.length>0?((!i||!t||_||h)&&f(t?g():e),e):g()})}var v=!1,y=(n&1?Dt:At)(()=>(v=!1,g()));o&&H(y);var b=V;return(function(e,t){if(arguments.length>0){let n=t?H(y):i&&o?pn(e):e;return P(y,n),v=!0,c!==void 0&&(c=n),e}return sr&&v||b.f&16384?y.v:H(y)})}function da(e){D===null&&be(`onMount`),Xe&&D.l!==null?fa(D).m.push(e):Rn(()=>{let t=Mr(e);if(typeof t==`function`)return t})}function fa(e){var t=e.l;return t.u??={a:[],b:[],m:[]}}typeof window<`u`&&((window.__svelte??={}).v??=new Set).add(`5`);var X=new class{#e=N(null);get data(){return H(this.#e)}set data(e){P(this.#e,e,!0)}#t=N(null);get arsenal(){return H(this.#t)}set arsenal(e){P(this.#t,e,!0)}#n=N(`connecting`);get status(){return H(this.#n)}set status(e){P(this.#n,e,!0)}#r=N(``);get clock(){return H(this.#r)}set clock(e){P(this.#r,e,!0)}#i=N(`overview`);get view(){return H(this.#i)}set view(e){P(this.#i,e,!0)}#a=N(!1);get arsenalLoading(){return H(this.#a)}set arsenalLoading(e){P(this.#a,e,!0)}#o=!1;#s=null;async tick(){try{let e=await fetch(`/data`);if(!e.ok)throw Error(`HTTP ${e.status}`);this.data=await e.json(),this.status=`live`,this.clock=new Date().toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`})}catch{this.status=`offline`}}start(){this.tick(),this.#s=setInterval(()=>void this.tick(),1e4)}stop(){this.#s&&clearInterval(this.#s)}async loadArsenal(e=!1){if(!(this.#o&&!e)){this.arsenalLoading=!0;try{let e=await fetch(`/arsenal`);e.ok&&(this.arsenal=await e.json(),this.#o=!0)}catch{}finally{this.arsenalLoading=!1}}}go(e){this.view=e,e===`arsenal`&&this.loadArsenal()}};function Z(e){return typeof e!=`number`||!Number.isFinite(e)?`0`:e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:String(Math.round(e))}function pa(e){return typeof e!=`number`||!Number.isFinite(e)?`$0.00`:`$${e.toLocaleString(`en-US`,{minimumFractionDigits:2,maximumFractionDigits:2})}`}function ma(e){if(!e)return`—`;let t=new Date(e);if(Number.isNaN(t.getTime()))return`—`;let n=new Date;return t.getFullYear()===n.getFullYear()&&t.getMonth()===n.getMonth()&&t.getDate()===n.getDate()?t.toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}):t.toLocaleDateString([],{month:`short`,day:`numeric`})}function ha(e){if(!e)return`unknown`;let t=e.toLowerCase();return t===`<synthetic>`?`unknown`:t.includes(`fable`)?`fable`:t.includes(`opus`)?`opus`:t.includes(`sonnet`)?`sonnet`:t.includes(`haiku`)?`haiku`:`unknown`}function ga(e){return!e||e===`<synthetic>`?`synthetic`:e.replace(/^claude-/,``)}function _a(e){if(!e)return``;let t=e.split(/[/\\\\]/).filter(Boolean);return t.length<=2?t.join(`/`):`…/${t.slice(-2).join(`/`)}`}var va=[220,75,20,155,285,330,250,45];function ya(e){let t=0;for(let n=0;n<e.length;n++)t=t*31+e.charCodeAt(n)>>>0;return`oklch(72% 0.15 ${va[t%va.length]})`}var ba={xmlns:`http://www.w3.org/2000/svg`,width:24,height:24,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,\"stroke-width\":2,\"stroke-linecap\":`round`,\"stroke-linejoin\":`round`},xa=e=>{for(let t in e)if(t.startsWith(`aria-`)||t===`role`||t===`title`)return!0;return!1},Sa=Symbol(`lucide-context`),Ca=()=>$e(Sa),wa=new Set([`$$slots`,`$$events`,`$$legacy`,`name`,`color`,`size`,`strokeWidth`,`absoluteStrokeWidth`,`iconNode`,`children`]),Ta=ii(`<svg><!><!></svg>`);function Ea(e,t){O(t,!0);let n=Ca()??{},r=Y(t,`color`,19,()=>n.color??`currentColor`),i=Y(t,`size`,19,()=>n.size??24),a=Y(t,`strokeWidth`,19,()=>n.strokeWidth??2),o=Y(t,`absoluteStrokeWidth`,19,()=>n.absoluteStrokeWidth??!1),s=Y(t,`iconNode`,19,()=>[]),c=ca(t,wa),l=j(()=>o()?Number(a())*24/Number(i()):a());var u=Ta();ea(u,e=>({...ba,...e,...c,width:i(),height:i(),stroke:r(),\"stroke-width\":H(l),class:[`lucide-icon lucide`,n.class,t.name&&`lucide-${t.name}`,t.class]}),[()=>!t.children&&!xa(c)&&{\"aria-hidden\":`true`}]);var d=F(u);yi(d,17,s,hi,(e,t)=>{var n=j(()=>h(H(t),2));let r=()=>H(n)[0],i=()=>H(n)[1];var a=W();Ei(I(a),r,!0,(e,t)=>{ea(e,()=>({...i()}))}),G(e,a)}),J(L(d),()=>t.children??f),E(u),G(e,u),k()}var Da=new Set([`$$slots`,`$$events`,`$$legacy`]);function Oa(e,t){let n=ca(t,Da),r=[[`rect`,{width:`7`,height:`9`,x:`3`,y:`3`,rx:`1`}],[`rect`,{width:`7`,height:`5`,x:`14`,y:`3`,rx:`1`}],[`rect`,{width:`7`,height:`9`,x:`14`,y:`12`,rx:`1`}],[`rect`,{width:`7`,height:`5`,x:`3`,y:`16`,rx:`1`}]];Ea(e,ua({name:`layout-dashboard`},()=>n,{get iconNode(){return r}}))}var ka=new Set([`$$slots`,`$$events`,`$$legacy`]);function Aa(e,t){let n=ca(t,ka),r=[[`polyline`,{points:`14.5 17.5 3 6 3 3 6 3 17.5 14.5`}],[`line`,{x1:`13`,x2:`19`,y1:`19`,y2:`13`}],[`line`,{x1:`16`,x2:`20`,y1:`16`,y2:`20`}],[`line`,{x1:`19`,x2:`21`,y1:`21`,y2:`19`}],[`polyline`,{points:`14.5 6.5 18 3 21 3 21 6 17.5 9.5`}],[`line`,{x1:`5`,x2:`9`,y1:`14`,y2:`18`}],[`line`,{x1:`7`,x2:`4`,y1:`17`,y2:`20`}],[`line`,{x1:`3`,x2:`5`,y1:`19`,y2:`21`}]];Ea(e,ua({name:`swords`},()=>n,{get iconNode(){return r}}))}var ja=new Set([`$$slots`,`$$events`,`$$legacy`]);function Ma(e,t){let n=ca(t,ja),r=[[`circle`,{cx:`12`,cy:`12`,r:`10`}],[`path`,{d:`M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3`}],[`path`,{d:`M12 17h.01`}]];Ea(e,ua({name:`circle-question-mark`},()=>n,{get iconNode(){return r}}))}var Na=new Set([`$$slots`,`$$events`,`$$legacy`]);function Pa(e,t){let n=ca(t,Na),r=[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`}],[`path`,{d:`M9 3v18`}]];Ea(e,ua({name:`panel-left`},()=>n,{get iconNode(){return r}}))}var Fa=U(`<div class=\"min-w-0\"><div class=\"font-serif text-lg leading-none text-foreground\">Synth<em>ra</em></div> <div class=\"font-mono text-[10px] uppercase tracking-[0.18em] text-muted-foreground\">Dashboard</div></div>`),Ia=U(`<span class=\"font-mono text-sm text-muted-foreground\"> </span>`),La=U(`<span> </span>`),Ra=U(`<button><!> <!></button>`),za=U(`<span>FAQ</span>`),Ba=U(`<div class=\"flex flex-col gap-1 rounded-lg bg-sidebar-accent/40 p-2.5\"><div class=\"font-mono text-[10px] uppercase tracking-[0.14em] text-muted-foreground\">Active</div> <div class=\"truncate font-mono text-sm text-sidebar-foreground\"> </div> <div class=\"mt-1 flex items-center justify-between font-mono text-[10px] text-muted-foreground\"><span> </span> <span>v__SYN_VERSION__</span></div></div>`),Va=U(`<span class=\"text-xs\">Collapse</span>`),Ha=U(`<aside><div class=\"flex items-center gap-2.5 px-1 py-2\"><div class=\"grid size-8 shrink-0 place-items-center rounded-lg bg-primary/90 font-serif text-lg italic text-primary-foreground\">S</div> <!></div> <div><span></span> <!></div> <div class=\"my-1 h-px bg-sidebar-border\"></div> <nav class=\"flex flex-col gap-1\"><!> <button title=\"FAQ\"><!> <!></button></nav> <div class=\"flex-1\"></div> <!> <button title=\"Toggle sidebar\"><!> <!></button></aside>`);function Ua(e,t){O(t,!0);let n=N(!1),r=typeof window<`u`&&window.location.port||`8901`,i=[{id:`overview`,label:`Overview`,icon:Oa},{id:`arsenal`,label:`Arsenal`,icon:Aa}];var a=Ha(),o=F(a),s=L(F(o),2),c=e=>{G(e,Fa())};q(s,e=>{H(n)||e(c)}),E(o);var l=L(o,2),u=F(l);let d;var f=L(u,2),p=e=>{var t=Ia(),n=F(t,!0);E(t),R(()=>K(n,X.status===`live`?`live · ${X.clock}`:X.status)),G(e,t)};q(f,e=>{H(n)||e(p)}),E(l);var m=L(l,4),h=F(m);yi(h,17,()=>i,e=>e.id,(e,t)=>{var r=Ra(),i=F(r);Ti(i,()=>H(t).icon,(e,t)=>{t(e,{class:`size-4 shrink-0`})});var a=L(i,2),o=e=>{var n=La(),r=F(n,!0);E(n),R(()=>K(r,H(t).label)),G(e,n)};q(a,e=>{H(n)||e(o)}),E(r),R(()=>{Qi(r,`title`,H(t).label),Ii(r,1,`flex items-center gap-2.5 rounded-lg px-2.5 py-2 text-sm transition-colors `+(X.view===H(t).id?`bg-sidebar-accent text-sidebar-accent-foreground`:`text-sidebar-foreground/75 hover:bg-sidebar-accent/50 hover:text-sidebar-foreground`)+(H(n)?` justify-center`:``))}),Yr(`click`,r,()=>X.go(H(t).id)),G(e,r)});var g=L(h,2),_=F(g);Ma(_,{class:`size-4 shrink-0`});var v=L(_,2),y=e=>{G(e,za())};q(v,e=>{H(n)||e(y)}),E(g),E(m);var b=L(m,4),ee=e=>{var t=Ba(),n=L(F(t),2),i=F(n,!0);E(n);var a=L(n,2),o=F(a),s=F(o);E(o),Ue(2),E(a),E(t),R(()=>{Qi(n,`title`,X.data?.active?.project_root??`—`),K(i,X.data?.active?.project_name??`—`),K(s,`port ${r??``}`)}),G(e,t)};q(b,e=>{H(n)||e(ee)});var x=L(b,2),te=F(x);Pa(te,{class:`size-4 shrink-0`});var ne=L(te,2),re=e=>{G(e,Va())};q(ne,e=>{H(n)||e(re)}),E(x),E(a),R(()=>{Ii(a,1,`flex h-screen shrink-0 flex-col gap-1 border-r border-sidebar-border bg-sidebar p-3 transition-[width] duration-200 `+(H(n)?`w-[64px] items-center`:`w-[248px]`)),Ii(l,1,`flex items-center gap-2 rounded-md px-2 py-1.5 `+(H(n)?`justify-center`:``)),d=Ii(u,1,`size-2 shrink-0 rounded-full `+(X.status===`live`?`bg-[var(--c-fable)]`:X.status===`offline`?`bg-destructive`:`bg-muted-foreground`),null,d,{\"animate-pulse\":X.status===`live`}),Ii(g,1,`flex items-center gap-2.5 rounded-lg px-2.5 py-2 text-sm text-sidebar-foreground/75 transition-colors hover:bg-sidebar-accent/50 hover:text-sidebar-foreground `+(H(n)?`justify-center`:``)),Ii(x,1,`mt-1 flex items-center gap-2.5 rounded-lg px-2.5 py-2 text-sidebar-foreground/60 transition-colors hover:bg-sidebar-accent/50 hover:text-sidebar-foreground `+(H(n)?`justify-center`:``))}),Yr(`click`,g,function(...e){t.onFaq?.apply(this,e)}),Yr(`click`,x,()=>P(n,!H(n))),G(e,a),k()}Xr([`click`]),Ze();var Wa=U(`<div class=\"flex flex-col gap-1 bg-card/70 p-4\"><span class=\"font-mono text-xs uppercase tracking-[0.12em] text-muted-foreground\"> </span> <span class=\"font-mono text-2xl tabular-nums text-foreground\"> </span></div>`),Ga=U(`<div class=\"grid grid-cols-2 gap-px overflow-hidden rounded-xl border bg-border sm:grid-cols-3 lg:grid-cols-5\"></div>`);function Ka(e,t){O(t,!0);let n=j(()=>{let e=X.data?.global;return[{label:`Turns`,v:e?.total_turns??0},{label:`↓ Input`,v:e?.total_input_tokens??0},{label:`↑ Output`,v:e?.total_output_tokens??0},{label:`⟲ Cache R`,v:e?.total_cache_read??0},{label:`+ Cache W`,v:e?.total_cache_create??0}]});var r=Ga();yi(r,21,()=>H(n),e=>e.label,(e,t)=>{var n=Wa(),r=F(n),i=F(r,!0);E(r);var a=L(r,2),o=F(a,!0);E(a),E(n),R(e=>{K(i,H(t).label),K(o,e)},[()=>Z(H(t).v)]),G(e,n)}),E(r),G(e,r),k()}var qa=U(`<span class=\"font-mono text-[10px] uppercase tracking-[0.12em] text-muted-foreground\"> </span>`),Ja=U(`<header class=\"flex items-baseline justify-between gap-3\"><span class=\"font-mono text-xs uppercase tracking-[0.14em] text-muted-foreground\"> </span> <!></header>`),Ya=U(`<section><!> <!></section>`);function Xa(e,t){let n=Y(t,`class`,3,``);var r=Ya(),i=F(r),a=e=>{var n=Ja(),r=F(n),i=F(r,!0);E(r);var a=L(r,2),o=e=>{var n=qa(),r=F(n,!0);E(n),R(()=>K(r,t.meta)),G(e,n)};q(a,e=>{t.meta&&e(o)}),E(n),R(()=>K(i,t.title)),G(e,n)};q(i,e=>{t.title&&e(a)}),J(L(i,2),()=>t.children??f),E(r),R(()=>Ii(r,1,`flex h-full min-h-0 flex-col gap-3 rounded-xl border bg-card/55 p-4 transition-colors hover:bg-card/80 `+n())),G(e,r)}var Za=U(`<div class=\"flex flex-col gap-3\"><div><div class=\"font-mono text-3xl text-[var(--money)]\"> </div> <div class=\"font-mono text-sm text-muted-foreground\"> </div></div> <div class=\"flex h-2 overflow-hidden rounded-full bg-border\"><div class=\"h-full bg-muted-foreground/40\"></div> <div class=\"h-full bg-[var(--money)]\"></div></div> <div class=\"flex justify-between font-mono text-xs text-muted-foreground\"><span>you paid <b class=\"text-foreground\"> </b></span> <span>baseline <b class=\"text-foreground\"> </b></span></div> <div class=\"rounded-md border border-dashed border-border px-3 py-2 text-center font-mono text-xs text-muted-foreground\"><b class=\"text-foreground\"> </b> blocks × <b class=\"text-foreground\">500</b> tokens × <b class=\"text-foreground\">$3</b>/M = <b class=\"text-[var(--money)]\"> </b></div></div>`);function Qa(e,t){O(t,!0);let n=j(()=>{let e=X.data?.global,t=e?.blocked_count??0,n=t*500*3/1e6,r=e?.estimated_cost_usd??0,i=r+n;return{blocks:t,money:n,paid:r,baseline:i,pct:i>0?n/i*100:0,tokens:e?.estimated_tokens_saved??0,paidWidth:i>0?r/i*100:100}});{let t=j(()=>`${H(n).pct.toFixed(1)}% off · floor`);Xa(e,{title:`Synthra savings`,get meta(){return H(t)},children:(e,t)=>{var r=Za(),i=F(r),a=F(i),o=F(a,!0);E(a);var s=L(a,2),c=F(s);E(s),E(i);var l=L(i,2),u=F(l),d=L(u,2);E(l);var f=L(l,2),p=F(f),m=L(F(p)),h=F(m,!0);E(m),E(p);var g=L(p,2),_=L(F(g)),v=F(_,!0);E(_),E(g),E(f);var y=L(f,2),b=F(y),ee=F(b,!0);E(b);var x=L(b,6),te=F(x,!0);E(x),E(y),E(r),R((e,t,r,i,a)=>{K(o,e),K(c,`${t??``} tokens avoided`),Ri(u,`width:${H(n).paidWidth}%`),Ri(d,`width:${100-H(n).paidWidth}%`),K(h,r),K(v,i),K(ee,H(n).blocks),K(te,a)},[()=>pa(H(n).money),()=>Z(H(n).tokens),()=>pa(H(n).paid),()=>pa(H(n).baseline),()=>pa(H(n).money)]),G(e,r)},$$slots:{default:!0}})}k()}var $a=U(`<div class=\"font-mono text-3xl text-[var(--money)]\"> </div> <div class=\"mt-1 flex flex-col gap-1 font-mono text-sm text-muted-foreground\"><div class=\"flex justify-between\"><span>Tokens (in+out)</span><span class=\"text-foreground\"> </span></div> <div class=\"flex justify-between\"><span>Avg / turn</span><span class=\"text-foreground\"> </span></div></div>`,1);function eo(e,t){O(t,!0);let n=j(()=>{let e=X.data?.global,t=e?.total_turns??0,n=e?.estimated_cost_usd??0;return{cost:n,tokens:(e?.total_input_tokens??0)+(e?.total_output_tokens??0),avg:t>0?n/t:0}});Xa(e,{title:`Total spend`,meta:`all time`,children:(e,t)=>{var r=$a(),i=I(r),a=F(i,!0);E(i);var o=L(i,2),s=F(o),c=L(F(s)),l=F(c,!0);E(c),E(s);var u=L(s,2),d=L(F(u)),f=F(d,!0);E(d),E(u),E(o),R((e,t,n)=>{K(a,e),K(l,t),K(f,n)},[()=>pa(H(n).cost),()=>Z(H(n).tokens),()=>pa(H(n).avg)]),G(e,r)},$$slots:{default:!0}}),k()}var to=ii(`<circle cx=\"70\" cy=\"70\" r=\"52\" fill=\"none\" stroke-width=\"14\"></circle>`),no=U(`<div class=\"flex items-center gap-2 font-mono text-sm\"><span class=\"size-2 rounded-sm\"></span> <span class=\"flex-1 text-muted-foreground\"> </span> <span class=\"tabular-nums text-foreground\"> </span> <span class=\"w-9 text-right tabular-nums text-muted-foreground\"> </span></div>`),ro=U(`<div class=\"text-sm text-muted-foreground\">No turns yet.</div>`),io=U(`<div class=\"flex items-center gap-4\"><div class=\"relative size-[116px] shrink-0\"><svg viewBox=\"0 0 140 140\" class=\"size-full -rotate-90\"><circle cx=\"70\" cy=\"70\" r=\"52\" fill=\"none\" stroke=\"var(--border)\" stroke-width=\"14\"></circle><!></svg> <div class=\"absolute inset-0 grid place-items-center\"><div class=\"text-center\"><div class=\"font-mono text-2xl text-foreground\"> </div> <div class=\"font-mono text-[10px] uppercase text-muted-foreground\">turns</div></div></div></div> <div class=\"flex min-w-0 flex-1 flex-col gap-1.5\"></div></div>`);function ao(e,t){O(t,!0);let n=[{fam:`fable`,label:`Fable`,color:`var(--c-fable)`},{fam:`opus`,label:`Opus`,color:`var(--c-opus)`},{fam:`sonnet`,label:`Sonnet`,color:`var(--c-sonnet)`},{fam:`haiku`,label:`Haiku`,color:`var(--c-haiku)`},{fam:`unknown`,label:`Other`,color:`var(--c-unknown)`}],r=2*Math.PI*52,i=j(()=>{let e={fable:0,opus:0,sonnet:0,haiku:0,unknown:0};for(let t of X.data?.projects??[])for(let[n,r]of Object.entries(t.models??{}))e[ha(n)]+=r;let t=n.reduce((t,n)=>t+e[n.fam],0),i=0;return{arcs:n.filter(t=>e[t.fam]>0).map(n=>{let a=e[n.fam],o=t>0?a/t*r:0,s={...n,n:a,len:o,offset:i,pct:t>0?Math.round(a/t*100):0};return i+=o,s}),total:t}});Xa(e,{title:`Model usage`,meta:`by turns`,children:(e,t)=>{var n=io(),a=F(n),o=F(a);yi(L(F(o)),17,()=>H(i).arcs,e=>e.fam,(e,t)=>{var n=to();R(()=>{Qi(n,`stroke`,H(t).color),Qi(n,`stroke-dasharray`,`${H(t).len} ${r}`),Qi(n,`stroke-dashoffset`,-H(t).offset),Qi(n,`stroke-linecap`,H(i).arcs.length===1?`round`:`butt`)}),G(e,n)}),E(o);var s=L(o,2),c=F(s),l=F(c),u=F(l,!0);E(l),Ue(2),E(c),E(s),E(a);var d=L(a,2);yi(d,21,()=>H(i).arcs,e=>e.fam,(e,t)=>{var n=no(),r=F(n),i=L(r,2),a=F(i,!0);E(i);var o=L(i,2),s=F(o,!0);E(o);var c=L(o,2),l=F(c);E(c),E(n),R(()=>{Ri(r,`background:${H(t).color}`),K(a,H(t).label),K(s,H(t).n),K(l,`${H(t).pct??``}%`)}),G(e,n)},e=>{G(e,ro())}),E(d),E(n),R(()=>K(u,H(i).total)),G(e,n)},$$slots:{default:!0}}),k()}function oo(e){return typeof e==`object`&&!!e}var so=[`string`,`number`,`bigint`,`boolean`];function co(e){return e==null||so.includes(typeof e)?!0:Array.isArray(e)?e.every(e=>co(e)):typeof e==`object`?Object.getPrototypeOf(e)===Object.prototype:!1}var lo=Symbol(`box`),uo=Symbol(`is-writable`);function Q(e,t){let n=j(e);return t?{[lo]:!0,[uo]:!0,get current(){return H(n)},set current(e){t(e)}}:{[lo]:!0,get current(){return e()}}}function fo(e){return oo(e)&&lo in e}function po(e){let t=N(pn(e));return{[lo]:!0,[uo]:!0,get current(){return H(t)},set current(e){P(t,e,!0)}}}function mo(...e){return function(t){for(let n of e)if(n){if(t.defaultPrevented)return;typeof n==`function`?n.call(this,t):n.current?.call(this,t)}}}var ho=/\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\//g,go=/\\n/g,_o=/^\\s*/,vo=/^(\\*?[-#/*\\\\\\w]+(\\[[0-9a-z_-]+\\])?)\\s*/,yo=/^:\\s*/,bo=/^((?:'(?:\\\\'|.)*?'|\"(?:\\\\\"|.)*?\"|\\([^)]*?\\)|[^};])+)/,xo=/^[;\\s]*/,So=/^\\s+|\\s+$/g,Co=`\n`,wo=`/`,To=`*`,Eo=``,Do=`comment`,Oo=`declaration`;function ko(e,t){if(typeof e!=`string`)throw TypeError(`First argument must be a string`);if(!e)return[];t||={};var n=1,r=1;function i(e){var t=e.match(go);t&&(n+=t.length);var i=e.lastIndexOf(Co);r=~i?e.length-i:r+e.length}function a(){var e={line:n,column:r};return function(t){return t.position=new o(e),l(),t}}function o(e){this.start=e,this.end={line:n,column:r},this.source=t.source}o.prototype.content=e;function s(i){var a=Error(t.source+`:`+n+`:`+r+`: `+i);if(a.reason=i,a.filename=t.source,a.line=n,a.column=r,a.source=e,!t.silent)throw a}function c(t){var n=t.exec(e);if(n){var r=n[0];return i(r),e=e.slice(r.length),n}}function l(){c(_o)}function u(e){var t;for(e||=[];t=d();)t!==!1&&e.push(t);return e}function d(){var t=a();if(!(wo!=e.charAt(0)||To!=e.charAt(1))){for(var n=2;Eo!=e.charAt(n)&&(To!=e.charAt(n)||wo!=e.charAt(n+1));)++n;if(n+=2,Eo===e.charAt(n-1))return s(`End of comment missing`);var o=e.slice(2,n-2);return r+=2,i(o),e=e.slice(n),r+=2,t({type:Do,comment:o})}}function f(){var e=a(),t=c(vo);if(t){if(d(),!c(yo))return s(`property missing ':'`);var n=c(bo),r=e({type:Oo,property:Ao(t[0].replace(ho,Eo)),value:n?Ao(n[0].replace(ho,Eo)):Eo});return c(xo),r}}function p(){var e=[];u(e);for(var t;t=f();)t!==!1&&(e.push(t),u(e));return e}return l(),p()}function Ao(e){return e?e.replace(So,Eo):Eo}function jo(e,t){let n=null;if(!e||typeof e!=`string`)return n;let r=ko(e),i=typeof t==`function`;return r.forEach(e=>{if(e.type!==`declaration`)return;let{property:r,value:a}=e;i?t(r,a,e):a&&(n||={},n[r]=a)}),n}var Mo=/\\d/,No=[`-`,`_`,`/`,`.`];function Po(e=``){if(!Mo.test(e))return e!==e.toLowerCase()}function Fo(e){let t=[],n=``,r,i;for(let a of e){let e=No.includes(a);if(e===!0){t.push(n),n=``,r=void 0;continue}let o=Po(a);if(i===!1){if(r===!1&&o===!0){t.push(n),n=a,r=o;continue}if(r===!0&&o===!1&&n.length>1){let e=n.at(-1);t.push(n.slice(0,Math.max(0,n.length-1))),n=e+a,r=o;continue}}n+=a,r=o,i=e}return t.push(n),t}function Io(e){return e?Fo(e).map(e=>Ro(e)).join(``):``}function Lo(e){return zo(Io(e||``))}function Ro(e){return e?e[0].toUpperCase()+e.slice(1):``}function zo(e){return e?e[0].toLowerCase()+e.slice(1):``}function Bo(e){if(!e)return{};let t={};function n(e,n){if(e.startsWith(`-moz-`)||e.startsWith(`-webkit-`)||e.startsWith(`-ms-`)||e.startsWith(`-o-`)){t[Io(e)]=n;return}if(e.startsWith(`--`)){t[e]=n;return}t[Lo(e)]=n}return jo(e,n),t}function Vo(...e){return(...t)=>{for(let n of e)typeof n==`function`&&n(...t)}}function Ho(e,t){let n=RegExp(e,`g`);return e=>{if(typeof e!=`string`)throw TypeError(`expected an argument of type string, but got ${typeof e}`);return e.match(n)?e.replace(n,t):e}}var Uo=Ho(/[A-Z]/,e=>`-${e.toLowerCase()}`);function Wo(e){if(!e||typeof e!=`object`||Array.isArray(e))throw TypeError(`expected an argument of type object, but got ${typeof e}`);return Object.keys(e).map(t=>`${Uo(t)}: ${e[t]};`).join(`\n`)}function Go(e={}){return Wo(e).replace(`\n`,` `)}var Ko=new Set(`onabort.onanimationcancel.onanimationend.onanimationiteration.onanimationstart.onauxclick.onbeforeinput.onbeforetoggle.onblur.oncancel.oncanplay.oncanplaythrough.onchange.onclick.onclose.oncompositionend.oncompositionstart.oncompositionupdate.oncontextlost.oncontextmenu.oncontextrestored.oncopy.oncuechange.oncut.ondblclick.ondrag.ondragend.ondragenter.ondragleave.ondragover.ondragstart.ondrop.ondurationchange.onemptied.onended.onerror.onfocus.onfocusin.onfocusout.onformdata.ongotpointercapture.oninput.oninvalid.onkeydown.onkeypress.onkeyup.onload.onloadeddata.onloadedmetadata.onloadstart.onlostpointercapture.onmousedown.onmouseenter.onmouseleave.onmousemove.onmouseout.onmouseover.onmouseup.onpaste.onpause.onplay.onplaying.onpointercancel.onpointerdown.onpointerenter.onpointerleave.onpointermove.onpointerout.onpointerover.onpointerup.onprogress.onratechange.onreset.onresize.onscroll.onscrollend.onsecuritypolicyviolation.onseeked.onseeking.onselect.onselectionchange.onselectstart.onslotchange.onstalled.onsubmit.onsuspend.ontimeupdate.ontoggle.ontouchcancel.ontouchend.ontouchmove.ontouchstart.ontransitioncancel.ontransitionend.ontransitionrun.ontransitionstart.onvolumechange.onwaiting.onwebkitanimationend.onwebkitanimationiteration.onwebkitanimationstart.onwebkittransitionend.onwheel`.split(`.`));function qo(e){return Ko.has(e)}function Jo(...e){let t={...e[0]};for(let n=1;n<e.length;n++){let r=e[n];if(r){for(let e of Object.keys(r)){let n=t[e],i=r[e],a=typeof n==`function`,o=typeof i==`function`;if(a&&typeof o&&qo(e))t[e]=mo(n,i);else if(a&&o)t[e]=Vo(n,i);else if(e===`class`){let r=co(n),a=co(i);r&&a?t[e]=ki(n,i):r?t[e]=ki(n):a&&(t[e]=ki(i))}else if(e===`style`){let r=typeof n==`object`,a=typeof i==`object`,o=typeof n==`string`,s=typeof i==`string`;if(r&&a)t[e]={...n,...i};else if(r&&s){let r=Bo(i);t[e]={...n,...r}}else if(o&&a)t[e]={...Bo(n),...i};else if(o&&s){let r=Bo(n),a=Bo(i);t[e]={...r,...a}}else r?t[e]=n:a?t[e]=i:o?t[e]=n:s&&(t[e]=i)}else t[e]=i===void 0?n:i}for(let e of Object.getOwnPropertySymbols(r)){let n=t[e],i=r[e];t[e]=i===void 0?n:i}}}return typeof t.style==`object`&&(t.style=Go(t.style).replaceAll(`\n`,` `)),t.hidden===!1&&(t.hidden=void 0,delete t.hidden),t.disabled===!1&&(t.disabled=void 0,delete t.disabled),t}var Yo=typeof window<`u`?window:void 0;typeof window<`u`&&window.document,typeof window<`u`&&window.navigator,typeof window<`u`&&window.location;function Xo(e){let t=e.activeElement;for(;t?.shadowRoot;){let e=t.shadowRoot.activeElement;if(e===t)break;t=e}return t}var Zo=class extends Map{#e=new Map;#t=N(0);#n=N(0);#r=br||-1;constructor(e){if(super(),e){for(var[t,n]of e)super.set(t,n);this.#n.v=super.size}}#i(e){return br===this.#r?N(e):sn(e)}has(e){var t=this.#e,n=t.get(e);if(n===void 0)if(super.has(e))n=this.#i(0),t.set(e,n);else return H(this.#t),!1;return H(n),!0}forEach(e,t){this.#a(),super.forEach(e,t)}get(e){var t=this.#e,n=t.get(e);if(n===void 0)if(super.has(e))n=this.#i(0),t.set(e,n);else{H(this.#t);return}return H(n),super.get(e)}set(e,t){var n=this.#e,r=n.get(e),i=super.get(e),a=super.set(e,t),o=this.#t;if(r===void 0)r=this.#i(0),n.set(e,r),P(this.#n,super.size),dn(o);else if(i!==t){dn(r);var s=o.reactions===null?null:new Set(o.reactions);(s===null||!r.reactions?.every(e=>s.has(e)))&&dn(o)}return a}delete(e){var t=this.#e,n=t.get(e),r=super.delete(e);return n!==void 0&&(t.delete(e),P(n,-1)),r&&(P(this.#n,super.size),dn(this.#t)),r}clear(){if(super.size!==0){super.clear();var e=this.#e;P(this.#n,0);for(var t of e.values())P(t,-1);dn(this.#t),e.clear()}}#a(){H(this.#t);var e=this.#e;if(this.#n.v!==e.size){for(var t of super.keys())if(!e.has(t)){var n=this.#i(0);e.set(t,n)}}for([,n]of this.#e)H(n)}keys(){return H(this.#t),super.keys()}values(){return this.#a(),super.values()}entries(){return this.#a(),super.entries()}[Symbol.iterator](){return this.entries()}get size(){return H(this.#n),super.size}};new class{#e;#t;constructor(e={}){let{window:t=Yo,document:n=t?.document}=e;t!==void 0&&(this.#e=n,this.#t=yt(e=>{let n=Jr(t,`focusin`,e),r=Jr(t,`focusout`,e);return()=>{n(),r()}}))}get current(){return this.#t?.(),this.#e?Xo(this.#e):null}};var Qo=class{#e;#t;constructor(e){this.#e=e,this.#t=Symbol(e)}get key(){return this.#t}exists(){return tt(this.#t)}get(){let e=$e(this.#t);if(e===void 0)throw Error(`Context \"${this.#e}\" not found`);return e}getOr(e){let t=$e(this.#t);return t===void 0?e:t}set(e){return et(this.#t,e)}};function $o(e,t){switch(e){case`post`:Rn(t);break;case`pre`:Bn(t);break}}function es(e,t,n,r={}){let{lazy:i=!1}=r,a=!i,o=Array.isArray(e)?[]:void 0;$o(t,()=>{let t=Array.isArray(e)?e.map(e=>e()):e();if(!a){a=!0,o=t;return}let r=Mr(()=>n(t,o));return o=t,r})}function ts(e,t,n){let r=Vn(()=>{let i=!1;es(e,t,(e,t)=>{if(i){r();return}let a=n(e,t);return i=!0,a},{lazy:!0})});Rn(()=>r)}function ns(e,t,n){es(e,`post`,t,n)}function rs(e,t,n){es(e,`pre`,t,n)}ns.pre=rs;function is(e,t){ts(e,`post`,t)}function as(e,t){ts(e,`pre`,t)}is.pre=as;function os(e,t){let n,r=null;return(...i)=>new Promise(a=>{r&&r(void 0),r=a,clearTimeout(n),n=setTimeout(async()=>{let t=await e(...i);r&&=(r(t),null)},t)})}function ss(e,t){let n=0,r=null;return(...i)=>{let a=Date.now();return n&&a-n<t?r??Promise.resolve(void 0):(n=a,r=e(...i),r)}}function cs(e,t,n={},r){let{lazy:i=!1,once:a=!1,initialValue:o,debounce:s,throttle:c}=n,l=N(pn(o)),u=N(!1),d=N(void 0),f=N(pn([])),p=()=>{H(f).forEach(e=>e()),P(f,[],!0)},m=e=>{P(f,[...H(f),e],!0)},h=async(e,n,r=!1)=>{try{P(u,!0),P(d,void 0),p();let i=new AbortController;m(()=>i.abort());let a=await t(e,n,{data:H(l),refetching:r,onCleanup:m,signal:i.signal});return P(l,a,!0),a}catch(e){e instanceof DOMException&&e.name===`AbortError`||P(d,e,!0);return}finally{P(u,!1)}},g=s?os(h,s):c?ss(h,c):h,_=Array.isArray(e)?e:[e],v;return r((t,n)=>{a&&v||(v=t,g(Array.isArray(e)?t:t[0],Array.isArray(e)?n:n?.[0]))},{lazy:i}),{get current(){return H(l)},get loading(){return H(u)},get error(){return H(d)},mutate:e=>{P(l,e,!0)},refetch:t=>{let n=_.map(e=>e());return g(Array.isArray(e)?n:n[0],Array.isArray(e)?n:n[0],t??!0)}}}function ls(e,t,n){return cs(e,t,n,(t,n)=>{let r=Array.isArray(e)?e:[e];ns(()=>r.map(e=>e()),(e,n)=>{t(e,n??[])},n)})}function us(e,t,n){return cs(e,t,n,(t,n)=>{let r=Array.isArray(e)?e:[e];ns.pre(()=>r.map(e=>e()),(e,n)=>{t(e,n??[])},n)})}ls.pre=us;function ds(e){Rn(()=>()=>{e()})}function fs(e,t){return setTimeout(t,e)}function ps(e){kr().then(e)}var ms=1,hs=9,gs=11;function _s(e){return oo(e)&&e.nodeType===ms&&typeof e.nodeName==`string`}function vs(e){return oo(e)&&e.nodeType===hs}function ys(e){return oo(e)&&e.constructor?.name===`VisualViewport`}function bs(e){return oo(e)&&e.nodeType!==void 0}function xs(e){return bs(e)&&e.nodeType===gs&&`host`in e}function Ss(e,t){if(!e||!t||!_s(e)||!_s(t))return!1;let n=t.getRootNode?.();if(e===t||e.contains(t))return!0;if(n&&xs(n)){let n=t;for(;n;){if(e===n)return!0;n=n.parentNode||n.host}}return!1}function Cs(e){return vs(e)?e:ys(e)?e.document:e?.ownerDocument??document}function ws(e){let t=e.activeElement;for(;t?.shadowRoot;){let e=t.shadowRoot.activeElement;if(e===t)break;t=e}return t}var Ts=class{element;#e=j(()=>this.element.current?this.element.current.getRootNode()??document:document);get root(){return H(this.#e)}set root(e){P(this.#e,e)}constructor(e){typeof e==`function`?this.element=Q(e):this.element=e}getDocument=()=>Cs(this.root);getWindow=()=>this.getDocument().defaultView??window;getActiveElement=()=>ws(this.root);isActiveElement=e=>e===this.getActiveElement();getElementById(e){return this.root.getElementById(e)}querySelector=e=>this.root?this.root.querySelector(e):null;querySelectorAll=e=>this.root?this.root.querySelectorAll(e):[];setTimeout=(e,t)=>this.getWindow().setTimeout(e,t);clearTimeout=e=>this.getWindow().clearTimeout(e)};function Es(e,t){return{[Nr()]:n=>fo(e)?(e.current=n,Mr(()=>t?.(n)),()=>{`isConnected`in n&&n.isConnected||(e.current=null,t?.(null))}):(e(n),Mr(()=>t?.(n)),()=>{`isConnected`in n&&n.isConnected||(e(null),t?.(null))})}}function Ds(e){return e?``:void 0}function Os(e){return e?`open`:`closed`}function ks(e){return e===`starting`?{\"data-starting-style\":``}:e===`ending`?{\"data-ending-style\":``}:{}}var As=class{#e;#t;attrs;constructor(e){this.#e=e.getVariant?e.getVariant():null,this.#t=this.#e?`data-${this.#e}-`:`data-${e.component}-`,this.getAttr=this.getAttr.bind(this),this.selector=this.selector.bind(this),this.attrs=Object.fromEntries(e.parts.map(e=>[e,this.getAttr(e)]))}getAttr(e,t){return t?`data-${t}-${e}`:`${this.#t}${e}`}selector(e,t){return`[${this.getAttr(e,t)}]`}};function js(e){let t=new As(e);return{...t.attrs,selector:t.selector,getAttr:t.getAttr}}var Ms=typeof document<`u`,Ns=Ps();function Ps(){return Ms&&window?.navigator?.userAgent&&(/iP(ad|hone|od)/.test(window.navigator.userAgent)||window?.navigator?.maxTouchPoints>2&&/iPad|Macintosh/.test(window?.navigator.userAgent))}function Fs(e){return e instanceof HTMLElement}function Is(e){return e instanceof Element||e instanceof SVGElement}var Ls=class{#e;#t=null;#n=null;#r=0;constructor(e){this.#e=e,ds(()=>this.#i())}#i(){this.#t!==null&&(window.cancelAnimationFrame(this.#t),this.#t=null),this.#n?.disconnect(),this.#n=null,this.#r++}run(e){this.#i();let t=this.#e.ref.current;if(!t)return;if(typeof t.getAnimations!=`function`){this.#a(e);return}let n=this.#r,r=()=>{n===this.#r&&this.#a(e)},i=()=>{if(n!==this.#r)return;let e=t.getAnimations();if(e.length===0){r();return}Promise.all(e.map(e=>e.finished)).then(()=>{r()}).catch(()=>{if(n===this.#r){if(t.getAnimations().some(e=>e.pending||e.playState!==`finished`)){i();return}r()}})},a=()=>{this.#t=window.requestAnimationFrame(()=>{this.#t=null,i()})};if(!this.#e.afterTick.current){a();return}this.#t=window.requestAnimationFrame(()=>{this.#t=null;let e=`data-starting-style`;if(!t.hasAttribute(e)){a();return}this.#n=new MutationObserver(()=>{n===this.#r&&(t.hasAttribute(e)||(this.#n?.disconnect(),this.#n=null,a()))}),this.#n.observe(t,{attributes:!0,attributeFilter:[e]})})}#a(e){let t=()=>{e()};this.#e.afterTick?ps(t):t()}},Rs=class{#e;#t;#n;#r=N(!1);#i=N(void 0);#a=!1;#o=null;constructor(e){this.#e=e,P(this.#r,e.open.current,!0),this.#t=e.enabled??!0,this.#n=new Ls({ref:this.#e.ref,afterTick:this.#e.open}),ds(()=>this.#s()),ns(()=>this.#e.open.current,e=>{if(!this.#a){this.#a=!0;return}if(this.#s(),!e&&this.#e.shouldSkipExitAnimation?.()){P(this.#r,!1),P(this.#i,void 0),this.#e.onComplete?.();return}if(e&&P(this.#r,!0),P(this.#i,e?`starting`:`ending`,!0),e&&(this.#o=window.requestAnimationFrame(()=>{this.#o=null,this.#e.open.current&&P(this.#i,void 0)})),!this.#t){e||P(this.#r,!1),P(this.#i,void 0),this.#e.onComplete?.();return}this.#n.run(()=>{e===this.#e.open.current&&(this.#e.open.current||P(this.#r,!1),P(this.#i,void 0),this.#e.onComplete?.())})})}get shouldRender(){return H(this.#r)}get transitionStatus(){return H(this.#i)}#s(){this.#o!==null&&(window.cancelAnimationFrame(this.#o),this.#o=null)}};function $(){}function zs(e,t){return t===void 0?`bits-${e}`:`bits-${e}-${t}`}var Bs=js({component:`dialog`,parts:[`content`,`trigger`,`overlay`,`title`,`description`,`close`,`cancel`,`action`]}),Vs=new Qo(`Dialog.Root | AlertDialog.Root`),Hs=class e{static create(t){let n=Vs.getOr(null);return Vs.set(new e(t,n))}opts;#e=N(null);get triggerNode(){return H(this.#e)}set triggerNode(e){P(this.#e,e,!0)}#t=N(null);get contentNode(){return H(this.#t)}set contentNode(e){P(this.#t,e,!0)}#n=N(null);get overlayNode(){return H(this.#n)}set overlayNode(e){P(this.#n,e,!0)}#r=N(null);get descriptionNode(){return H(this.#r)}set descriptionNode(e){P(this.#r,e,!0)}#i=N(void 0);get contentId(){return H(this.#i)}set contentId(e){P(this.#i,e,!0)}#a=N(void 0);get titleId(){return H(this.#a)}set titleId(e){P(this.#a,e,!0)}#o=N(void 0);get triggerId(){return H(this.#o)}set triggerId(e){P(this.#o,e,!0)}#s=N(void 0);get descriptionId(){return H(this.#s)}set descriptionId(e){P(this.#s,e,!0)}#c=N(null);get cancelNode(){return H(this.#c)}set cancelNode(e){P(this.#c,e,!0)}#l=N(0);get nestedOpenCount(){return H(this.#l)}set nestedOpenCount(e){P(this.#l,e,!0)}depth;parent;contentPresence;overlayPresence;constructor(e,t){this.opts=e,this.parent=t,this.depth=t?t.depth+1:0,this.handleOpen=this.handleOpen.bind(this),this.handleClose=this.handleClose.bind(this),this.contentPresence=new Rs({ref:Q(()=>this.contentNode),open:this.opts.open,enabled:!0,onComplete:()=>{this.opts.onOpenChangeComplete.current(this.opts.open.current)}}),this.overlayPresence=new Rs({ref:Q(()=>this.overlayNode),open:this.opts.open,enabled:!0}),ns(()=>this.opts.open.current,e=>{this.parent&&(e?this.parent.incrementNested():this.parent.decrementNested())},{lazy:!0}),ds(()=>{this.opts.open.current&&this.parent?.decrementNested()})}handleOpen(){this.opts.open.current||(this.opts.open.current=!0)}handleClose(){this.opts.open.current&&(this.opts.open.current=!1)}getBitsAttr=e=>Bs.getAttr(e,this.opts.variant.current);incrementNested(){this.nestedOpenCount++,this.parent?.incrementNested()}decrementNested(){this.nestedOpenCount!==0&&(this.nestedOpenCount--,this.parent?.decrementNested())}#u=j(()=>({\"data-state\":Os(this.opts.open.current)}));get sharedProps(){return H(this.#u)}set sharedProps(e){P(this.#u,e)}},Us=class e{static create(t){return new e(t,Vs.get())}opts;root;attachment;constructor(e,t){this.opts=e,this.root=t,this.attachment=Es(this.opts.ref),this.onclick=this.onclick.bind(this),this.onkeydown=this.onkeydown.bind(this)}onclick(e){this.opts.disabled.current||e.button>0||this.root.handleClose()}onkeydown(e){this.opts.disabled.current||(e.key===` `||e.key===`Enter`)&&(e.preventDefault(),this.root.handleClose())}#e=j(()=>({id:this.opts.id.current,[this.root.getBitsAttr(this.opts.variant.current)]:``,onclick:this.onclick,onkeydown:this.onkeydown,disabled:this.opts.disabled.current?!0:void 0,tabindex:0,...this.root.sharedProps,...this.attachment}));get props(){return H(this.#e)}set props(e){P(this.#e,e)}},Ws=class e{static create(t){return new e(t,Vs.get())}opts;root;attachment;constructor(e,t){this.opts=e,this.root=t,this.root.titleId=this.opts.id.current,this.attachment=Es(this.opts.ref),ns.pre(()=>this.opts.id.current,e=>{this.root.titleId=e})}#e=j(()=>({id:this.opts.id.current,role:`heading`,\"aria-level\":this.opts.level.current,[this.root.getBitsAttr(`title`)]:``,...this.root.sharedProps,...this.attachment}));get props(){return H(this.#e)}set props(e){P(this.#e,e)}},Gs=class e{static create(t){return new e(t,Vs.get())}opts;root;attachment;constructor(e,t){this.opts=e,this.root=t,this.root.descriptionId=this.opts.id.current,this.attachment=Es(this.opts.ref,e=>{this.root.descriptionNode=e}),ns.pre(()=>this.opts.id.current,e=>{this.root.descriptionId=e})}#e=j(()=>({id:this.opts.id.current,[this.root.getBitsAttr(`description`)]:``,...this.root.sharedProps,...this.attachment}));get props(){return H(this.#e)}set props(e){P(this.#e,e)}},Ks=class e{static create(t){return new e(t,Vs.get())}opts;root;attachment;constructor(e,t){this.opts=e,this.root=t,this.attachment=Es(this.opts.ref,e=>{this.root.contentNode=e,this.root.contentId=e?.id})}#e=j(()=>({open:this.root.opts.open.current}));get snippetProps(){return H(this.#e)}set snippetProps(e){P(this.#e,e)}#t=j(()=>({id:this.opts.id.current,role:this.root.opts.variant.current===`alert-dialog`?`alertdialog`:`dialog`,\"aria-modal\":`true`,\"aria-describedby\":this.root.descriptionId,\"aria-labelledby\":this.root.titleId,[this.root.getBitsAttr(`content`)]:``,style:{pointerEvents:`auto`,outline:this.root.opts.variant.current===`alert-dialog`?`none`:void 0,\"--bits-dialog-depth\":this.root.depth,\"--bits-dialog-nested-count\":this.root.nestedOpenCount,contain:`layout style`},tabindex:this.root.opts.variant.current===`alert-dialog`?-1:void 0,\"data-nested-open\":Ds(this.root.nestedOpenCount>0),\"data-nested\":Ds(this.root.parent!==null),...ks(this.root.contentPresence.transitionStatus),...this.root.sharedProps,...this.attachment}));get props(){return H(this.#t)}set props(e){P(this.#t,e)}get shouldRender(){return this.root.contentPresence.shouldRender}},qs=class e{static create(t){return new e(t,Vs.get())}opts;root;attachment;constructor(e,t){this.opts=e,this.root=t,this.attachment=Es(this.opts.ref,e=>this.root.overlayNode=e)}#e=j(()=>({open:this.root.opts.open.current}));get snippetProps(){return H(this.#e)}set snippetProps(e){P(this.#e,e)}#t=j(()=>({id:this.opts.id.current,[this.root.getBitsAttr(`overlay`)]:``,style:{pointerEvents:`auto`,\"--bits-dialog-depth\":this.root.depth,\"--bits-dialog-nested-count\":this.root.nestedOpenCount},\"data-nested-open\":Ds(this.root.nestedOpenCount>0),\"data-nested\":Ds(this.root.parent!==null),...ks(this.root.overlayPresence.transitionStatus),...this.root.sharedProps,...this.attachment}));get props(){return H(this.#t)}set props(e){P(this.#t,e)}get shouldRender(){return this.root.overlayPresence.shouldRender}},Js=new Set([`$$slots`,`$$events`,`$$legacy`,`id`,`ref`,`child`,`children`,`level`]),Ys=U(`<div><!></div>`);function Xs(e,t){let n=oi();O(t,!0);let r=Y(t,`id`,19,()=>zs(n)),i=Y(t,`ref`,15,null),a=Y(t,`level`,3,2),o=ca(t,Js),s=Ws.create({id:Q(()=>r()),level:Q(()=>a()),ref:Q(()=>i(),e=>i(e))}),c=j(()=>Jo(o,s.props));var l=W(),u=I(l),d=e=>{var n=W();J(I(n),()=>t.child,()=>({props:H(c)})),G(e,n)},p=e=>{var n=Ys();ea(n,()=>({...H(c)})),J(F(n),()=>t.children??f),E(n),G(e,n)};q(u,e=>{t.child?e(d):e(p,-1)}),G(e,l),k()}function Zs(e,t){var n=W();mi(I(n),()=>t.children,e=>{var n=W();J(I(n),()=>t.children??f),G(e,n)}),G(e,n)}var Qs=new Qo(`BitsConfig`);function $s(){let e=new ec(null,{});return Qs.getOr(e).opts}var ec=class{opts;constructor(e,t){let n=tc(e,t);this.opts={defaultPortalTo:n(e=>e.defaultPortalTo),defaultLocale:n(e=>e.defaultLocale)}}};function tc(e,t){return n=>Q(()=>{let r=n(t)?.current;if(r!==void 0)return r;if(e!==null)return n(e.opts)?.current})}function nc(e,t){return n=>{let r=$s();return Q(()=>{let i=n();if(i!==void 0)return i;let a=e(r).current;return a===void 0?t:a})}}var rc=nc(e=>e.defaultPortalTo,`body`);function ic(e,t){O(t,!0);let n=rc(()=>t.to),r=nt(),i=j(a);function a(){if(!Ms||t.disabled)return null;let e=null;return e=typeof n.current==`string`?document.querySelector(n.current):n.current,e}let o;function s(){o&&=(di(o),null)}ns([()=>H(i),()=>t.disabled],([e,n])=>{if(!e||n){s();return}return o=si(Zs,{target:e,props:{children:t.children},context:r}),()=>{s()}});var c=W(),l=I(c),u=e=>{var n=W();J(I(n),()=>t.children??f),G(e,n)};q(l,e=>{t.disabled&&e(u)}),G(e,c),k()}var ac=class{eventName;options;constructor(e,t={bubbles:!0,cancelable:!0}){this.eventName=e,this.options=t}createEvent(e){return new CustomEvent(this.eventName,{...this.options,detail:e})}dispatch(e,t){let n=this.createEvent(t);return e.dispatchEvent(n),n}listen(e,t,n){return Jr(e,this.eventName,e=>{t(e)},n)}};function oc(e,t=500){let n=null,r=(...r)=>{n!==null&&clearTimeout(n),n=setTimeout(()=>{e(...r)},t)};return r.destroy=()=>{n!==null&&(clearTimeout(n),n=null)},r}function sc(e,t){return e===t||e.contains(t)}function cc(e){return e?.ownerDocument??document}function lc(e,t){let{clientX:n,clientY:r}=e,i=t.getBoundingClientRect();return n<i.left||n>i.right||r<i.top||r>i.bottom}var uc=[`input:not([inert]):not([inert] *)`,`select:not([inert]):not([inert] *)`,`textarea:not([inert]):not([inert] *)`,`a[href]:not([inert]):not([inert] *)`,`button:not([inert]):not([inert] *)`,`[tabindex]:not(slot):not([inert]):not([inert] *)`,`audio[controls]:not([inert]):not([inert] *)`,`video[controls]:not([inert]):not([inert] *)`,`[contenteditable]:not([contenteditable=\"false\"]):not([inert]):not([inert] *)`,`details>summary:first-of-type:not([inert]):not([inert] *)`,`details:not([inert]):not([inert] *)`],dc=uc.join(`,`),fc=typeof Element>`u`,pc=fc?function(){}:Element.prototype.matches||Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector,mc=!fc&&Element.prototype.getRootNode?function(e){return e?.getRootNode?.call(e)}:function(e){return e?.ownerDocument},hc=function(e,t){t===void 0&&(t=!0);var n=e?.getAttribute?.call(e,`inert`);return n===``||n===`true`||t&&e&&(typeof e.closest==`function`?e.closest(`[inert]`):hc(e.parentNode))},gc=function(e){var t=e?.getAttribute?.call(e,`contenteditable`);return t===``||t===`true`},_c=function(e,t,n){if(hc(e))return[];var r=Array.prototype.slice.apply(e.querySelectorAll(dc));return t&&pc.call(e,dc)&&r.unshift(e),r=r.filter(n),r},vc=function(e,t,n){for(var r=[],i=Array.from(e);i.length;){var a=i.shift();if(!hc(a,!1))if(a.tagName===`SLOT`){var o=a.assignedElements(),s=vc(o.length?o:a.children,!0,n);n.flatten?r.push.apply(r,s):r.push({scopeParent:a,candidates:s})}else{pc.call(a,dc)&&n.filter(a)&&(t||!e.includes(a))&&r.push(a);var c=a.shadowRoot||typeof n.getShadowRoot==`function`&&n.getShadowRoot(a),l=!hc(c,!1)&&(!n.shadowRootFilter||n.shadowRootFilter(a));if(c&&l){var u=vc(c===!0?a.children:c.children,!0,n);n.flatten?r.push.apply(r,u):r.push({scopeParent:a,candidates:u})}else i.unshift.apply(i,a.children)}}return r},yc=function(e){return!isNaN(parseInt(e.getAttribute(`tabindex`),10))},bc=function(e){if(!e)throw Error(`No node provided`);return e.tabIndex<0&&(/^(AUDIO|VIDEO|DETAILS)$/.test(e.tagName)||gc(e))&&!yc(e)?0:e.tabIndex},xc=function(e,t){var n=bc(e);return n<0&&t&&!yc(e)?0:n},Sc=function(e,t){return e.tabIndex===t.tabIndex?e.documentOrder-t.documentOrder:e.tabIndex-t.tabIndex},Cc=function(e){return e.tagName===`INPUT`},wc=function(e){return Cc(e)&&e.type===`hidden`},Tc=function(e){return e.tagName===`DETAILS`&&Array.prototype.slice.apply(e.children).some(function(e){return e.tagName===`SUMMARY`})},Ec=function(e,t){for(var n=0;n<e.length;n++)if(e[n].checked&&e[n].form===t)return e[n]},Dc=function(e){if(!e.name)return!0;var t=e.form||mc(e),n=function(e){return t.querySelectorAll(`input[type=\"radio\"][name=\"`+e+`\"]`)},r;if(typeof window<`u`&&window.CSS!==void 0&&typeof window.CSS.escape==`function`)r=n(window.CSS.escape(e.name));else try{r=n(e.name)}catch(e){return console.error(`Looks like you have a radio button with a name attribute containing invalid CSS selector characters and need the CSS.escape polyfill: %s`,e.message),!1}var i=Ec(r,e.form);return!i||i===e},Oc=function(e){return Cc(e)&&e.type===`radio`},kc=function(e){return Oc(e)&&!Dc(e)},Ac=function(e){var t=e&&mc(e),n=t?.host,r=!1;if(t&&t!==e){var i,a,o;for(r=!!((i=n)!=null&&(a=i.ownerDocument)!=null&&a.contains(n)||e!=null&&(o=e.ownerDocument)!=null&&o.contains(e));!r&&n;){var s,c;t=mc(n),n=t?.host,r=!!((s=n)!=null&&(c=s.ownerDocument)!=null&&c.contains(n))}}return r},jc=function(e){var t=e.getBoundingClientRect(),n=t.width,r=t.height;return n===0&&r===0},Mc=function(e,t){var n=t.displayCheck,r=t.getShadowRoot;if(n===`full-native`&&`checkVisibility`in e)return!e.checkVisibility({checkOpacity:!1,opacityProperty:!1,contentVisibilityAuto:!0,visibilityProperty:!0,checkVisibilityCSS:!0});if(getComputedStyle(e).visibility===`hidden`)return!0;var i=pc.call(e,`details>summary:first-of-type`)?e.parentElement:e;if(pc.call(i,`details:not([open]) *`))return!0;if(!n||n===`full`||n===`full-native`||n===`legacy-full`){if(typeof r==`function`){for(var a=e;e;){var o=e.parentElement,s=mc(e);if(o&&!o.shadowRoot&&r(o)===!0)return jc(e);e=e.assignedSlot?e.assignedSlot:!o&&s!==e.ownerDocument?s.host:o}e=a}if(Ac(e))return!e.getClientRects().length;if(n!==`legacy-full`)return!0}else if(n===`non-zero-area`)return jc(e);return!1},Nc=function(e){if(/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(e.tagName))for(var t=e.parentElement;t;){if(t.tagName===`FIELDSET`&&t.disabled){for(var n=0;n<t.children.length;n++){var r=t.children.item(n);if(r.tagName===`LEGEND`)return pc.call(t,`fieldset[disabled] *`)?!0:!r.contains(e)}return!0}t=t.parentElement}return!1},Pc=function(e,t){return!(t.disabled||wc(t)||Mc(t,e)||Tc(t)||Nc(t))},Fc=function(e,t){return!(kc(t)||bc(t)<0||!Pc(e,t))},Ic=function(e){var t=parseInt(e.getAttribute(`tabindex`),10);return!!(isNaN(t)||t>=0)},Lc=function(e){var t=[],n=[];return e.forEach(function(e,r){var i=!!e.scopeParent,a=i?e.scopeParent:e,o=xc(a,i),s=i?Lc(e.candidates):a;o===0?i?t.push.apply(t,s):t.push(a):n.push({documentOrder:r,tabIndex:o,item:e,isScope:i,content:s})}),n.sort(Sc).reduce(function(e,t){return t.isScope?e.push.apply(e,t.content):e.push(t.content),e},[]).concat(t)},Rc=function(e,t){return t||={},Lc(t.getShadowRoot?vc([e],t.includeContainer,{filter:Fc.bind(null,t),flatten:!1,getShadowRoot:t.getShadowRoot,shadowRootFilter:Ic}):_c(e,t.includeContainer,Fc.bind(null,t)))},zc=function(e,t){return t||={},t.getShadowRoot?vc([e],t.includeContainer,{filter:Pc.bind(null,t),flatten:!0,getShadowRoot:t.getShadowRoot}):_c(e,t.includeContainer,Pc.bind(null,t))},Bc=uc.concat(`iframe:not([inert]):not([inert] *)`).join(`,`),Vc=function(e,t){if(t||={},!e)throw Error(`No node provided`);return pc.call(e,Bc)===!1?!1:Pc(t,e)},Hc=`data-context-menu-trigger`,Uc=`data-context-menu-content`;new Qo(`Menu.Root`),new Qo(`Menu.Root | Menu.Sub`),new Qo(`Menu.Content`),new Qo(`Menu.Group | Menu.RadioGroup`),new Qo(`Menu.RadioGroup`),new Qo(`Menu.CheckboxGroup`),new ac(`bitsmenuopen`,{bubbles:!1,cancelable:!0}),js({component:`menu`,parts:[`trigger`,`content`,`sub-trigger`,`item`,`group`,`group-heading`,`checkbox-group`,`checkbox-item`,`radio-group`,`radio-item`,`separator`,`sub-content`,`arrow`]}),globalThis.bitsDismissableLayers??=new Map;var Wc=class e{static create(t){return new e(t)}opts;#e;#t;#n={pointerdown:!1};#r=!1;#i=!1;#a=void 0;#o;#s=$;constructor(e){this.opts=e,this.#t=e.interactOutsideBehavior,this.#e=e.onInteractOutside,this.#o=e.onFocusOutside,Rn(()=>{this.#a=cc(this.opts.ref.current)});let t=$,n=()=>{this.#g(),globalThis.bitsDismissableLayers.delete(this),this.#d.destroy(),t()};ns([()=>this.opts.enabled.current,()=>this.opts.ref.current],()=>{if(!(!this.opts.enabled.current||!this.opts.ref.current))return fs(1,()=>{this.opts.ref.current&&(globalThis.bitsDismissableLayers.set(this,this.#t),t(),t=this.#l())}),n}),ds(()=>{this.#g.destroy(),globalThis.bitsDismissableLayers.delete(this),this.#d.destroy(),this.#s(),t()})}#c=e=>{e.defaultPrevented||this.opts.ref.current&&ps(()=>{!this.opts.ref.current||this.#h(e.target)||e.target&&!this.#i&&this.#o.current?.(e)})};#l(){return Vo(Jr(this.#a,`pointerdown`,Vo(this.#f,this.#m),{capture:!0}),Jr(this.#a,`pointerdown`,Vo(this.#p,this.#d)),Jr(this.#a,`focusin`,this.#c))}#u=e=>{let t=e;t.defaultPrevented&&(t=Jc(e)),this.#e.current(e)};#d=oc(e=>{if(!this.opts.ref.current){this.#s();return}let t=this.opts.isValidEvent.current(e,this.opts.ref.current)||qc(e,this.opts.ref.current);if(!this.#r||this.#_()||!t){this.#s();return}let n=e;if(n.defaultPrevented&&(n=Jc(n)),this.#t.current!==`close`&&this.#t.current!==`defer-otherwise-close`){this.#s();return}e.pointerType===`touch`?(this.#s(),this.#s=Jr(this.#a,`click`,this.#u,{once:!0})):this.#e.current(n)},10);#f=e=>{this.#n[e.type]=!0};#p=e=>{this.#n[e.type]=!1};#m=()=>{this.opts.ref.current&&(this.#r=Kc(this.opts.ref.current))};#h=e=>this.opts.ref.current?sc(this.opts.ref.current,e):!1;#g=oc(()=>{for(let e in this.#n)this.#n[e]=!1;this.#r=!1},20);#_(){return Object.values(this.#n).some(Boolean)}#v=()=>{this.#i=!0};#y=()=>{this.#i=!1};props={onfocuscapture:this.#v,onblurcapture:this.#y}};function Gc(e=[...globalThis.bitsDismissableLayers]){return e.findLast(([e,{current:t}])=>t===`close`||t===`ignore`)}function Kc(e){let t=[...globalThis.bitsDismissableLayers],n=Gc(t);if(n)return n[0].opts.ref.current===e;let[r]=t[0];return r.opts.ref.current===e}function qc(e,t){let n=e.target;if(!Is(n))return!1;let r=!!n.closest(`[${Hc}]`),i=!!t.closest(`[${Uc}]`);return`button`in e&&e.button>0&&!r?!1:`button`in e&&e.button===0&&r&&i?!0:r&&i?!1:cc(n).documentElement.contains(n)&&!sc(t,n)&&lc(e,t)}function Jc(e){let t=e.currentTarget,n=e.target,r;r=e instanceof PointerEvent?new PointerEvent(e.type,e):new PointerEvent(`pointerdown`,e);let i=!1;return new Proxy(r,{get:(r,a)=>a===`currentTarget`?t:a===`target`?n:a===`preventDefault`?()=>{i=!0,typeof r.preventDefault==`function`&&r.preventDefault()}:a===`defaultPrevented`?i:a in r?r[a]:e[a]})}function Yc(e,t){O(t,!0);let n=Y(t,`interactOutsideBehavior`,3,`close`),r=Y(t,`onInteractOutside`,3,$),i=Y(t,`onFocusOutside`,3,$),a=Y(t,`isValidEvent`,3,()=>!1),o=Wc.create({id:Q(()=>t.id),interactOutsideBehavior:Q(()=>n()),onInteractOutside:Q(()=>r()),enabled:Q(()=>t.enabled),onFocusOutside:Q(()=>i()),isValidEvent:Q(()=>a()),ref:t.ref});var s=W();J(I(s),()=>t.children??f,()=>({props:o.props})),G(e,s),k()}globalThis.bitsEscapeLayers??=new Map;var Xc=class e{static create(t){return new e(t)}opts;domContext;constructor(e){this.opts=e,this.domContext=new Ts(this.opts.ref);let t=$;ns(()=>e.enabled.current,n=>(n&&(globalThis.bitsEscapeLayers.set(this,e.escapeKeydownBehavior),t=this.#e()),()=>{t(),globalThis.bitsEscapeLayers.delete(this)}))}#e=()=>Jr(this.domContext.getDocument(),`keydown`,this.#t,{passive:!1});#t=e=>{if(e.key!==`Escape`||!Zc(this))return;let t=new KeyboardEvent(e.type,e);e.preventDefault();let n=this.opts.escapeKeydownBehavior.current;n!==`close`&&n!==`defer-otherwise-close`||this.opts.onEscapeKeydown.current(t)}};function Zc(e){let t=[...globalThis.bitsEscapeLayers],n=t.findLast(([e,{current:t}])=>t===`close`||t===`ignore`);if(n)return n[0]===e;let[r]=t[0];return r===e}function Qc(e,t){O(t,!0);let n=Y(t,`escapeKeydownBehavior`,3,`close`),r=Y(t,`onEscapeKeydown`,3,$);Xc.create({escapeKeydownBehavior:Q(()=>n()),onEscapeKeydown:Q(()=>r()),enabled:Q(()=>t.enabled),ref:t.ref});var i=W();J(I(i),()=>t.children??f),G(e,i),k()}var $c=class e{static instance;#e=po([]);#t=new WeakMap;#n=new WeakMap;static getInstance(){return this.instance||=new e,this.instance}register(e){let t=this.getActive();t&&t!==e&&t.pause();let n=document.activeElement;n&&n!==document.body&&this.#n.set(e,n),this.#e.current=this.#e.current.filter(t=>t!==e),this.#e.current.unshift(e)}unregister(e){this.#e.current=this.#e.current.filter(t=>t!==e);let t=this.getActive();t&&t.resume()}getActive(){return this.#e.current[0]}setFocusMemory(e,t){this.#t.set(e,t)}getFocusMemory(e){return this.#t.get(e)}isActiveScope(e){return this.getActive()===e}setPreFocusMemory(e,t){this.#n.set(e,t)}getPreFocusMemory(e){return this.#n.get(e)}clearPreFocusMemory(e){this.#n.delete(e)}},el=class e{#e=!1;#t=null;#n=$c.getInstance();#r=[];#i;constructor(e){this.#i=e}get paused(){return this.#e}pause(){this.#e=!0}resume(){this.#e=!1}#a(){for(let e of this.#r)e();this.#r=[]}mount(e){this.#t&&this.unmount(),this.#t=e,this.#n.register(this),this.#c(),this.#o()}unmount(){this.#t&&=(this.#a(),this.#s(),this.#n.unregister(this),this.#n.clearPreFocusMemory(this),null)}#o(){if(!this.#t)return;let e=new CustomEvent(`focusScope.onOpenAutoFocus`,{bubbles:!1,cancelable:!0});this.#i.onOpenAutoFocus.current(e),e.defaultPrevented||requestAnimationFrame(()=>{if(!this.#t)return;let e=this.#u();e?(e.focus(),this.#n.setFocusMemory(this,e)):this.#t.focus()})}#s(){let e=new CustomEvent(`focusScope.onCloseAutoFocus`,{bubbles:!1,cancelable:!0});if(this.#i.onCloseAutoFocus.current?.(e),!e.defaultPrevented){let e=this.#n.getPreFocusMemory(this);if(e&&document.contains(e))try{e.focus()}catch{document.body.focus()}}}#c(){if(!this.#t||!this.#i.trap.current)return;let e=this.#t,t=e.ownerDocument;this.#r.push(Jr(t,`focusin`,t=>{if(this.#e||!this.#n.isActiveScope(this))return;let n=t.target;if(n)if(e.contains(n))this.#n.setFocusMemory(this,n);else{let n=this.#n.getFocusMemory(this);if(n&&e.contains(n)&&Vc(n))t.preventDefault(),n.focus();else{let t=this.#u(),n=this.#d()[0];(t||n||e).focus()}}},{capture:!0}),Jr(e,`keydown`,e=>{if(!this.#i.loop||this.#e||e.key!==`Tab`||!this.#n.isActiveScope(this))return;let n=this.#l();if(n.length===0)return;let r=n[0],i=n[n.length-1];!e.shiftKey&&t.activeElement===i?(e.preventDefault(),r.focus()):e.shiftKey&&t.activeElement===r&&(e.preventDefault(),i.focus())}));let n=new MutationObserver(()=>{let t=this.#n.getFocusMemory(this);if(t&&!e.contains(t)){let t=this.#u(),n=this.#d()[0],r=t||n;r?(r.focus(),this.#n.setFocusMemory(this,r)):e.focus()}});n.observe(e,{childList:!0,subtree:!0}),this.#r.push(()=>n.disconnect())}#l(){return this.#t?Rc(this.#t,{includeContainer:!1,getShadowRoot:!0}):[]}#u(){return this.#l()[0]||null}#d(){return this.#t?zc(this.#t,{includeContainer:!1,getShadowRoot:!0}):[]}static use(t){let n=null;return ns([()=>t.ref.current,()=>t.enabled.current],([r,i])=>{r&&i?(n||=new e(t),n.mount(r)):n&&=(n.unmount(),null)}),ds(()=>{n?.unmount()}),{get props(){return{tabindex:-1}}}}};function tl(e,t){O(t,!0);let n=Y(t,`enabled`,3,!1),r=Y(t,`trapFocus`,3,!1),i=Y(t,`loop`,3,!1),a=Y(t,`onCloseAutoFocus`,3,$),o=Y(t,`onOpenAutoFocus`,3,$),s=el.use({enabled:Q(()=>n()),trap:Q(()=>r()),loop:i(),onCloseAutoFocus:Q(()=>a()),onOpenAutoFocus:Q(()=>o()),ref:t.ref});var c=W();J(I(c),()=>t.focusScope??f,()=>({props:s.props})),G(e,c),k()}var nl=()=>{};globalThis.bitsTextSelectionLayers??=new Map;var rl=class e{static create(t){return new e(t)}opts;domContext;#e=$;#t=!1;#n=nl;#r=nl;constructor(e){this.opts=e,this.domContext=new Ts(e.ref);let t=$;ns(()=>[this.opts.enabled.current,this.opts.onPointerDown.current,this.opts.onPointerUp.current],([e,n,r])=>(this.#t=e,this.#n=n,this.#r=r,e&&(globalThis.bitsTextSelectionLayers.set(this,this.opts.enabled),t(),t=this.#i()),()=>{this.#t=!1,t(),this.#s(),globalThis.bitsTextSelectionLayers.delete(this)}))}#i(){return Vo(Jr(this.domContext.getDocument(),`pointerdown`,this.#o),Jr(this.domContext.getDocument(),`pointerup`,mo(this.#s,this.#a)))}#a=e=>{this.#r(e)};#o=e=>{let t=this.opts.ref.current,n=e.target;!Fs(t)||!Fs(n)||!this.#t||!sl(this)||!Ss(t,n)||(this.#n(e),!e.defaultPrevented&&(this.#e=al(t,this.domContext.getDocument().body)))};#s=()=>{this.#e(),this.#e=$}},il=e=>e.style.userSelect||e.style.webkitUserSelect;function al(e,t){let n=il(t),r=il(e);return ol(t,`none`),ol(e,`text`),()=>{ol(t,n),ol(e,r)}}function ol(e,t){e.style.userSelect=t,e.style.webkitUserSelect=t}function sl(e){let t=[...globalThis.bitsTextSelectionLayers];if(!t.length)return!1;let n=t.at(-1);return n?n[0]===e:!1}function cl(e,t){O(t,!0);let n=Y(t,`preventOverflowTextSelection`,3,!0),r=Y(t,`onPointerDown`,3,$),i=Y(t,`onPointerUp`,3,$);rl.create({id:Q(()=>t.id),onPointerDown:Q(()=>r()),onPointerUp:Q(()=>i()),enabled:Q(()=>t.enabled&&n()),ref:t.ref});var a=W();J(I(a),()=>t.children??f),G(e,a),k()}globalThis.bitsIdCounter??={current:0};function ll(e=`bits`){return globalThis.bitsIdCounter.current++,`${e}-${globalThis.bitsIdCounter.current}`}var ul=class{#e;#t=0;#n=N();#r;constructor(e){this.#e=e}#i(){--this.#t,this.#r&&this.#t<=0&&(this.#r(),P(this.#n,void 0),this.#r=void 0)}get(...e){return this.#t+=1,H(this.#n)===void 0&&(this.#r=Vn(()=>{P(this.#n,this.#e(...e),!0)})),Rn(()=>()=>{this.#i()}),H(this.#n)}},dl=new Zo,fl=N(null),pl=null,ml=null,hl=!1,gl=Q(()=>{for(let e of dl.values())if(e)return!0;return!1}),_l=null,vl=new ul(()=>{function e(){document.body.setAttribute(`style`,H(fl)??``),document.body.style.removeProperty(`--scrollbar-width`),Ns&&pl?.(),P(fl,null)}function t(){ml!==null&&(window.clearTimeout(ml),ml=null)}function n(e,n){t(),hl=!0,_l=Date.now();let r=_l,i=()=>{ml=null,_l===r&&(bl(dl)?hl=!1:(hl=!1,n()))},a=e===null?24:e;ml=window.setTimeout(i,a)}function r(){H(fl)===null&&dl.size===0&&!hl&&P(fl,document.body.getAttribute(`style`),!0)}return ns(()=>gl.current,()=>{if(!gl.current)return;r(),hl=!1;let e=getComputedStyle(document.documentElement),t=getComputedStyle(document.body),n=e.scrollbarGutter?.includes(`stable`)||t.scrollbarGutter?.includes(`stable`),i=window.innerWidth-document.documentElement.clientWidth,a={padding:Number.parseInt(t.paddingRight??`0`,10)+i,margin:Number.parseInt(t.marginRight??`0`,10)};i>0&&!n&&(document.body.style.paddingRight=`${a.padding}px`,document.body.style.marginRight=`${a.margin}px`,document.body.style.setProperty(`--scrollbar-width`,`${i}px`)),document.body.style.overflow=`hidden`,Ns&&(pl=Jr(document,`touchmove`,e=>{e.target===document.documentElement&&(e.touches.length>1||e.preventDefault())},{passive:!1})),ps(()=>{document.body.style.pointerEvents=`none`,document.body.style.overflow=`hidden`})}),ds(()=>()=>{pl?.()}),{get lockMap(){return dl},resetBodyStyle:e,scheduleCleanupIfNoNewLocks:n,cancelPendingCleanup:t,ensureInitialStyleCaptured:r}}),yl=class{#e=ll();#t;#n=()=>null;#r;locked;constructor(e,t=()=>null){this.#t=e,this.#n=t,this.#r=vl.get(),this.#r&&(this.#r.cancelPendingCleanup(),this.#r.ensureInitialStyleCaptured(),this.#r.lockMap.set(this.#e,this.#t??!1),this.locked=Q(()=>this.#r.lockMap.get(this.#e)??!1,e=>this.#r.lockMap.set(this.#e,e)),ds(()=>{if(this.#r.lockMap.delete(this.#e),bl(this.#r.lockMap))return;let e=this.#n();this.#r.scheduleCleanupIfNoNewLocks(e,()=>{this.#r.resetBodyStyle()})}))}};function bl(e){for(let[t,n]of e)if(n)return!0;return!1}function xl(e,t){O(t,!0);let n=Y(t,`preventScroll`,3,!0),r=Y(t,`restoreScrollDelay`,3,null);n()&&new yl(n(),()=>r()),k()}var Sl=new Set([`$$slots`,`$$events`,`$$legacy`,`id`,`forceMount`,`child`,`children`,`ref`]),Cl=U(`<div><!></div>`);function wl(e,t){let n=oi();O(t,!0);let r=Y(t,`id`,19,()=>zs(n)),i=Y(t,`forceMount`,3,!1),a=Y(t,`ref`,15,null),o=ca(t,Sl),s=qs.create({id:Q(()=>r()),ref:Q(()=>a(),e=>a(e))}),c=j(()=>Jo(o,s.props));var l=W(),u=I(l),d=e=>{var n=W(),r=I(n),i=e=>{var n=W(),r=I(n);{let e=j(()=>({props:Jo(H(c)),...s.snippetProps}));J(r,()=>t.child,()=>H(e))}G(e,n)},a=e=>{var n=Cl();ea(n,e=>({...e}),[()=>Jo(H(c))]),J(F(n),()=>t.children??f,()=>s.snippetProps),E(n),G(e,n)};q(r,e=>{t.child?e(i):e(a,-1)}),G(e,n)};q(u,e=>{(s.shouldRender||i())&&e(d)}),G(e,l),k()}var Tl=new Set([`$$slots`,`$$events`,`$$legacy`,`id`,`children`,`child`,`ref`]),El=U(`<div><!></div>`);function Dl(e,t){let n=oi();O(t,!0);let r=Y(t,`id`,19,()=>zs(n)),i=Y(t,`ref`,15,null),a=ca(t,Tl),o=Gs.create({id:Q(()=>r()),ref:Q(()=>i(),e=>i(e))}),s=j(()=>Jo(a,o.props));var c=W(),l=I(c),u=e=>{var n=W();J(I(n),()=>t.child,()=>({props:H(s)})),G(e,n)},d=e=>{var n=El();ea(n,()=>({...H(s)})),J(F(n),()=>t.children??f),E(n),G(e,n)};q(l,e=>{t.child?e(u):e(d,-1)}),G(e,c),k()}function Ol(e,t){O(t,!0);let n=Y(t,`open`,15,!1),r=Y(t,`onOpenChange`,3,$),i=Y(t,`onOpenChangeComplete`,3,$);Hs.create({variant:Q(()=>`dialog`),open:Q(()=>n(),e=>{n(e),r()(e)}),onOpenChangeComplete:Q(()=>i())});var a=W();J(I(a),()=>t.children??f),G(e,a),k()}var kl=new Set([`$$slots`,`$$events`,`$$legacy`,`children`,`child`,`id`,`ref`,`disabled`]),Al=U(`<button><!></button>`);function jl(e,t){let n=oi();O(t,!0);let r=Y(t,`id`,19,()=>zs(n)),i=Y(t,`ref`,15,null),a=Y(t,`disabled`,3,!1),o=ca(t,kl),s=Us.create({variant:Q(()=>`close`),id:Q(()=>r()),ref:Q(()=>i(),e=>i(e)),disabled:Q(()=>!!a())}),c=j(()=>Jo(o,s.props));var l=W(),u=I(l),d=e=>{var n=W();J(I(n),()=>t.child,()=>({props:H(c)})),G(e,n)},p=e=>{var n=Al();ea(n,()=>({...H(c)})),J(F(n),()=>t.children??f),E(n),G(e,n)};q(u,e=>{t.child?e(d):e(p,-1)}),G(e,l),k()}var Ml=new Set([`$$slots`,`$$events`,`$$legacy`,`id`,`children`,`child`,`ref`,`forceMount`,`onCloseAutoFocus`,`onOpenAutoFocus`,`onEscapeKeydown`,`onInteractOutside`,`trapFocus`,`preventScroll`,`restoreScrollDelay`]),Nl=U(`<!> <!>`,1),Pl=U(`<!> <div><!></div>`,1);function Fl(e,t){let n=oi();O(t,!0);let r=Y(t,`id`,19,()=>zs(n)),i=Y(t,`ref`,15,null),a=Y(t,`forceMount`,3,!1),o=Y(t,`onCloseAutoFocus`,3,$),s=Y(t,`onOpenAutoFocus`,3,$),c=Y(t,`onEscapeKeydown`,3,$),l=Y(t,`onInteractOutside`,3,$),u=Y(t,`trapFocus`,3,!0),d=Y(t,`preventScroll`,3,!0),p=Y(t,`restoreScrollDelay`,3,null),m=ca(t,Ml),h=Ks.create({id:Q(()=>r()),ref:Q(()=>i(),e=>i(e))}),g=j(()=>Jo(m,h.props));var _=W(),v=I(_),y=e=>{tl(e,{get ref(){return h.opts.ref},loop:!0,get trapFocus(){return u()},get enabled(){return h.root.opts.open.current},get onOpenAutoFocus(){return s()},get onCloseAutoFocus(){return o()},focusScope:(e,n)=>{let r=()=>n?.().props;Qc(e,ua(()=>H(g),{get enabled(){return h.root.opts.open.current},get ref(){return h.opts.ref},onEscapeKeydown:e=>{c()(e),!e.defaultPrevented&&h.root.handleClose()},children:(e,n)=>{Yc(e,ua(()=>H(g),{get ref(){return h.opts.ref},get enabled(){return h.root.opts.open.current},onInteractOutside:e=>{l()(e),!e.defaultPrevented&&h.root.handleClose()},children:(e,n)=>{cl(e,ua(()=>H(g),{get ref(){return h.opts.ref},get enabled(){return h.root.opts.open.current},children:(e,n)=>{var i=W(),a=I(i),o=e=>{var n=Nl(),i=I(n),a=e=>{xl(e,{get preventScroll(){return d()},get restoreScrollDelay(){return p()}})};q(i,e=>{h.root.opts.open.current&&e(a)});var o=L(i,2);{let e=j(()=>({props:Jo(H(g),r()),...h.snippetProps}));J(o,()=>t.child,()=>H(e))}G(e,n)},s=e=>{var n=Pl(),i=I(n);xl(i,{get preventScroll(){return d()}});var a=L(i,2);ea(a,e=>({...e}),[()=>Jo(H(g),r())]),J(F(a),()=>t.children??f),E(a),G(e,n)};q(a,e=>{t.child?e(o):e(s,-1)}),G(e,i)},$$slots:{default:!0}}))},$$slots:{default:!0}}))},$$slots:{default:!0}}))},$$slots:{focusScope:!0}})};q(v,e=>{(h.shouldRender||a())&&e(y)}),G(e,_),k()}var Il=U(`<button class=\"flex flex-col gap-1 text-left\"><div class=\"flex items-center gap-2 font-mono text-sm\"><span class=\"size-2 shrink-0 rounded-sm\"></span> <span class=\"flex-1 truncate text-foreground\"> </span> <span class=\"tabular-nums text-muted-foreground\"> </span></div> <div class=\"h-1 overflow-hidden rounded-full bg-border\"><div class=\"h-full\"></div></div></button>`),Ll=U(`<div class=\"text-sm text-muted-foreground\">No projects tracked yet — run <code class=\"text-foreground\">syn .</code></div>`),Rl=U(`<div class=\"flex max-h-[260px] flex-col gap-2 overflow-y-auto pr-1\"></div>`),zl=U(`<div class=\"flex flex-col gap-0.5 bg-card p-3\"><span class=\"font-mono text-[10px] uppercase tracking-[0.1em] text-muted-foreground\"> </span> <span class=\"font-mono text-sm text-foreground\"> </span></div>`),Bl=U(`<!> <!> <div class=\"mt-4 grid grid-cols-2 gap-px overflow-hidden rounded-lg border bg-border\"></div> <!>`,1),Vl=U(`<!> <!>`,1);function Hl(e,t){O(t,!0);let n=N(!1),r=N(null),i=j(()=>X.data?.projects??[]),a=j(()=>Math.max(1,...H(i).map(e=>e.total_turns)));function o(e){let t=(X.data?.recent_turns??[]).find(t=>t.project_path===e.path);return t?ma(t.ts):e.last_seen?ma(e.last_seen):`—`}function s(e){return[[`Cost`,pa(e.estimated_cost_usd)],[`Turns`,Z(e.total_turns)],[`Input`,Z(e.total_input_tokens)],[`Output`,Z(e.total_output_tokens)],[`Cache R`,Z(e.total_cache_read)],[`Cache W`,Z(e.total_cache_create)],[`Blocks`,Z(e.blocked_count)],[`Last active`,o(e)]]}var c=Vl(),l=I(c);Xa(l,{title:`Projects`,meta:`by turns`,children:(e,t)=>{var o=Rl();yi(o,21,()=>H(i),e=>e.path,(e,t)=>{var i=Il(),o=F(i),s=F(o),c=L(s,2),l=F(c,!0);E(c);var u=L(c,2),d=F(u,!0);E(u),E(o);var f=L(o,2),p=F(f);E(f),E(i),R((e,n,r)=>{Ri(s,e),K(l,H(t).name),K(d,n),Ri(p,r)},[()=>`background:${ya(H(t).name)}`,()=>Z(H(t).total_turns),()=>`width:${H(t).total_turns/H(a)*100}%; background:${ya(H(t).name)}`]),Yr(`click`,i,()=>{P(r,H(t),!0),P(n,!0)}),G(e,i)},e=>{G(e,Ll())}),E(o),G(e,o)},$$slots:{default:!0}}),Ti(L(l,2),()=>Ol,(e,t)=>{t(e,{get open(){return H(n)},set open(e){P(n,e,!0)},children:(e,t)=>{var n=W();Ti(I(n),()=>ic,(e,t)=>{t(e,{children:(e,t)=>{var n=Vl(),i=I(n);Ti(i,()=>wl,(e,t)=>{t(e,{class:`fixed inset-0 z-50 bg-black/60`})}),Ti(L(i,2),()=>Fl,(e,t)=>{t(e,{class:`fixed left-1/2 top-1/2 z-50 w-[min(440px,92vw)] -translate-x-1/2 -translate-y-1/2 rounded-xl border bg-card p-5 text-card-foreground shadow-2xl`,children:(e,t)=>{var n=W(),i=I(n),a=e=>{var t=Bl(),n=I(t);{let e=j(()=>`color:${ya(H(r).name)}`);Ti(n,()=>Xs,(t,n)=>{n(t,{class:`font-serif text-xl`,get style(){return H(e)},children:(e,t)=>{Ue();var n=ai();R(()=>K(n,H(r).name)),G(e,n)},$$slots:{default:!0}})})}var i=L(n,2);Ti(i,()=>Dl,(e,t)=>{t(e,{class:`truncate font-mono text-xs text-muted-foreground`,children:(e,t)=>{Ue();var n=ai();R(()=>K(n,H(r).path)),G(e,n)},$$slots:{default:!0}})});var a=L(i,2);yi(a,21,()=>s(H(r)),([e,t])=>e,(e,t)=>{var n=j(()=>h(H(t),2));let r=()=>H(n)[0],i=()=>H(n)[1];var a=zl(),o=F(a),s=F(o,!0);E(o);var c=L(o,2),l=F(c,!0);E(c),E(a),R(()=>{K(s,r()),K(l,i())}),G(e,a)}),E(a),Ti(L(a,2),()=>jl,(e,t)=>{t(e,{class:`mt-4 w-full rounded-md border py-2 text-sm text-muted-foreground transition-colors hover:text-foreground`,children:(e,t)=>{Ue(),G(e,ai(`Close`))},$$slots:{default:!0}})}),G(e,t)};q(i,e=>{H(r)&&e(a)}),G(e,n)},$$slots:{default:!0}})}),G(e,n)},$$slots:{default:!0}})}),G(e,n)},$$slots:{default:!0}})}),G(e,c),k()}Xr([`click`]);var Ul=U(`<div class=\"flex items-baseline justify-between font-mono text-sm\"><span class=\"text-muted-foreground\"> </span> <span class=\"tabular-nums text-foreground\"> </span></div>`),Wl=U(`<div class=\"text-sm text-muted-foreground\">No graph-tool calls yet.</div>`),Gl=U(`<div class=\"font-mono text-2xl text-foreground\"> <span class=\"text-sm text-muted-foreground\">calls</span></div> <div class=\"flex flex-col gap-1.5\"></div>`,1);function Kl(e,t){O(t,!0);let n=j(()=>{let e=X.data?.global?.tool_calls??{};return Object.entries(e).sort((e,t)=>t[1]-e[1]).slice(0,8)}),r=j(()=>X.data?.global?.total_tool_calls??0);Xa(e,{title:`Graph tools used`,meta:`all projects`,children:(e,t)=>{var i=Gl(),a=I(i),o=F(a);Ue(),E(a);var s=L(a,2);yi(s,21,()=>H(n),([e,t])=>e,(e,t)=>{var n=j(()=>h(H(t),2));let r=()=>H(n)[0],i=()=>H(n)[1];var a=Ul(),o=F(a),s=F(o,!0);E(o);var c=L(o,2),l=F(c,!0);E(c),E(a),R(()=>{K(s,r()),K(l,i())}),G(e,a)},e=>{G(e,Wl())}),E(s),R(e=>K(o,`${e??``} `),[()=>Z(H(r))]),G(e,i)},$$slots:{default:!0}}),k()}var ql=U(`<tr class=\"border-t border-border/60\"><td class=\"py-1.5 pr-2 text-muted-foreground\"> </td><td class=\"max-w-[120px] truncate py-1.5 pr-2 text-foreground\"> </td><td class=\"py-1.5 pr-2\"><span class=\"inline-flex items-center gap-1.5 rounded px-1.5 py-0.5\"><span class=\"size-1.5 rounded-sm\"></span> </span></td><td class=\"py-1.5 pr-2 text-right tabular-nums text-foreground\"> </td><td class=\"py-1.5 pr-2 text-right tabular-nums text-foreground\"> </td><td class=\"py-1.5 pr-2 text-right tabular-nums text-muted-foreground\"> </td><td class=\"py-1.5 text-right tabular-nums text-[var(--money)]\"> </td></tr>`),Jl=U(`<tr><td colspan=\"7\" class=\"py-6 text-center text-muted-foreground\">No turns recorded yet.</td></tr>`),Yl=U(`<div class=\"flex items-center justify-end gap-3 pt-1 font-mono text-sm text-muted-foreground\"><button class=\"rounded border px-2 py-1 disabled:opacity-40 enabled:hover:text-foreground\">‹ Prev</button> <span> </span> <button class=\"rounded border px-2 py-1 disabled:opacity-40 enabled:hover:text-foreground\">Next ›</button></div>`),Xl=U(`<div class=\"min-h-0 flex-1 overflow-x-auto\"><table class=\"w-full border-collapse font-mono text-sm\"><thead><tr class=\"text-left text-[10px] uppercase tracking-[0.1em] text-muted-foreground\"><th class=\"py-1.5 pr-2 font-medium\">Time</th><th class=\"py-1.5 pr-2 font-medium\">Project</th><th class=\"py-1.5 pr-2 font-medium\">Model</th><th class=\"py-1.5 pr-2 text-right font-medium\">In</th><th class=\"py-1.5 pr-2 text-right font-medium\">Out</th><th class=\"py-1.5 pr-2 text-right font-medium\">Cache R/W</th><th class=\"py-1.5 text-right font-medium\">Cost</th></tr></thead><tbody></tbody></table></div> <!>`,1);function Zl(e,t){O(t,!0);let n=N(1),r=j(()=>X.data?.recent_turns??[]),i=j(()=>Math.max(1,Math.ceil(H(r).length/25)));Rn(()=>{H(n)>H(i)&&P(n,H(i),!0)});let a=j(()=>H(r).slice((H(n)-1)*25,(H(n)-1)*25+25)),o=j(()=>H(r).length?(H(n)-1)*25+1:0),s=j(()=>Math.min(H(n)*25,H(r).length));{let t=j(()=>`showing ${H(o)}–${H(s)} of ${H(r).length}`);Xa(e,{title:`Recent turns`,get meta(){return H(t)},children:(e,t)=>{var r=Xl(),o=I(r),s=F(o),c=L(F(s));yi(c,21,()=>H(a),e=>e.ts+e.project_path+e.model,(e,t)=>{var n=ql(),r=F(n),i=F(r,!0);E(r);var a=L(r),o=F(a,!0);E(a);var s=L(a),c=F(s),l=F(c),u=L(l);E(c),E(s);var d=L(s),f=F(d,!0);E(d);var p=L(d),m=F(p,!0);E(p);var h=L(p),g=F(h);E(h);var _=L(h),v=F(_,!0);E(_),E(n),R((e,n,r,s,d,p,h,_,y)=>{K(i,e),Qi(a,`title`,H(t).project_name),K(o,H(t).project_name),Ri(c,n),Ri(l,r),K(u,` ${s??``}`),K(f,d),K(m,p),K(g,`${h??``} / ${_??``}`),K(v,y)},[()=>ma(H(t).ts),()=>`color: var(--c-${ha(H(t).model)})`,()=>`background: var(--c-${ha(H(t).model)})`,()=>ga(H(t).model),()=>Z(H(t).input),()=>Z(H(t).output),()=>Z(H(t).cache_read),()=>Z(H(t).cache_create),()=>pa(H(t).cost_usd)]),G(e,n)},e=>{G(e,Jl())}),E(c),E(s),E(o);var l=L(o,2),u=e=>{var t=Yl(),r=F(t),a=L(r,2),o=F(a);E(a);var s=L(a,2);E(t),R(()=>{r.disabled=H(n)<=1,K(o,`page ${H(n)??``} of ${H(i)??``}`),s.disabled=H(n)>=H(i)}),Yr(`click`,r,()=>P(n,Math.max(1,H(n)-1),!0)),Yr(`click`,s,()=>P(n,Math.min(H(i),H(n)+1),!0)),G(e,t)};q(l,e=>{H(i)>1&&e(u)}),G(e,r)},$$slots:{default:!0}})}k()}Xr([`click`]);var Ql=U(`<div class=\"flex items-baseline gap-2 font-mono text-xs\"><span class=\"shrink-0 text-muted-foreground\"> </span> <span> </span> <span class=\"truncate text-foreground/80\"> </span></div>`),$l=U(`<div class=\"text-sm text-muted-foreground\">No gate decisions yet.</div>`),eu=U(`<div class=\"font-mono text-2xl text-foreground\"> <span class=\"text-sm text-muted-foreground\">blocks</span></div> <div class=\"flex min-h-0 flex-1 flex-col gap-1 overflow-y-auto\"></div>`,1);function tu(e,t){O(t,!0);let n=j(()=>(X.data?.recent_gates??[]).slice(0,50)),r=j(()=>X.data?.global?.blocked_count??0);Xa(e,{title:`The Moat`,meta:`PreToolUse`,children:(e,t)=>{var i=eu(),a=I(i),o=F(a);Ue(),E(a);var s=L(a,2);yi(s,21,()=>H(n),e=>e.ts+e.query,(e,t)=>{var n=Ql(),r=F(n),i=F(r,!0);E(r);var a=L(r,2),o=F(a,!0);E(a);var s=L(a,2),c=F(s,!0);E(s),E(n),R(e=>{K(i,e),Ii(a,1,`shrink-0 rounded px-1 text-[10px] uppercase `+(H(t).decision===`block`?`bg-destructive/15 text-destructive`:`bg-[var(--c-fable)]/12 text-[var(--c-fable)]`)),K(o,H(t).decision),Qi(s,`title`,H(t).query??``),K(c,H(t).query??`—`)},[()=>ma(H(t).ts)]),G(e,n)},e=>{G(e,$l())}),E(s),R(e=>K(o,`${e??``} `),[()=>Z(H(r))]),G(e,i)},$$slots:{default:!0}}),k()}var nu=U(`<div class=\"flex items-baseline justify-between gap-3 font-mono text-sm\"><span class=\"truncate text-muted-foreground\"> </span> <span class=\"tabular-nums text-foreground\"> </span></div>`),ru=U(`<div class=\"text-sm text-muted-foreground\">No usage learned yet — Synthra learns as you read/edit files.</div>`),iu=U(`<div class=\"font-mono text-2xl text-foreground\"> <span class=\"text-sm text-muted-foreground\">tracked</span></div> <div class=\"flex max-h-[190px] flex-col gap-1.5 overflow-y-auto\"></div>`,1);function au(e,t){O(t,!0);let n=j(()=>X.data?.active),r=j(()=>H(n)?.stats?.hot_files??[]);{let t=j(()=>H(n)?.project_name??`active project`);Xa(e,{title:`Hot files`,get meta(){return H(t)},children:(e,t)=>{var i=iu(),a=I(i),o=F(a);Ue(),E(a);var s=L(a,2);yi(s,21,()=>H(r),e=>e.path,(e,t)=>{var n=nu(),r=F(n),i=F(r,!0);E(r);var a=L(r,2),o=F(a,!0);E(a),E(n),R(e=>{Qi(n,`title`,H(t).path),K(i,e),K(o,H(t).score)},[()=>_a(H(t).path)]),G(e,n)},e=>{G(e,ru())}),E(s),R(e=>K(o,`${e??``} `),[()=>Z(H(n)?.stats?.hot_files_total??0)]),G(e,i)},$$slots:{default:!0}})}k()}var ou=U(`<div class=\"grid grid-cols-1 gap-4 p-5 lg:grid-cols-3\"><div class=\"lg:col-span-3 lg:row-start-1\"><!></div> <div class=\"lg:col-start-1 lg:row-start-2\"><!></div> <div class=\"lg:col-start-2 lg:row-start-2\"><!></div> <div class=\"lg:col-start-1 lg:row-start-3\"><!></div> <div class=\"lg:col-start-2 lg:row-start-3\"><!></div> <div class=\"lg:col-start-1 lg:row-start-4\"><!></div> <div class=\"lg:col-start-2 lg:row-start-4\"><!></div> <div class=\"relative lg:col-start-3 lg:row-start-2 lg:row-span-3\"><div class=\"lg:absolute lg:inset-0\"><!></div></div> <div class=\"lg:col-span-3 lg:row-start-5\"><!></div></div>`);function su(e){var t=ou(),n=F(t);Ka(F(n),{}),E(n);var r=L(n,2);Qa(F(r),{}),E(r);var i=L(r,2);eo(F(i),{}),E(i);var a=L(i,2);ao(F(a),{}),E(a);var o=L(a,2);au(F(o),{}),E(o);var s=L(o,2);Hl(F(s),{}),E(s);var c=L(s,2);Kl(F(c),{}),E(c);var l=L(c,2),u=F(l);tu(F(u),{}),E(u),E(l);var d=L(l,2);Zl(F(d),{}),E(d),E(t),G(e,t)}var cu=U(`<p> </p>`),lu=U(`<div class=\"break-all\"><span class=\"text-foreground/70\"> </span> </div>`),uu=U(`<div class=\"mt-1 flex flex-col gap-0.5 font-mono text-xs text-muted-foreground/80\"></div>`),du=U(`<button class=\"flex flex-col gap-1.5 rounded-lg border bg-card/55 p-3 text-left transition-colors hover:bg-card/85\"><div class=\"flex items-center gap-2\"><span class=\"min-w-0 flex-1 truncate font-mono text-sm text-foreground\"> </span> <span> </span></div> <!> <!></button>`);function fu(e,t){O(t,!0);let n=N(!1),r=j(()=>t.item.scope===`plugin`?t.item.source??`plugin`:t.item.scope),i=j(()=>t.item.scope===`project`?`var(--c-fable)`:t.item.scope===`personal`?`var(--c-sonnet)`:`#9bc2ef`),a=j(()=>Object.entries(t.item.meta??{}));var o=du(),s=F(o),c=F(s),l=F(c,!0);E(c);var u=L(c,2);let d;var f=F(u);E(u),E(s);var p=L(s,2),m=e=>{var r=cu(),i=F(r,!0);E(r),R(()=>{Ii(r,1,`text-sm leading-snug text-muted-foreground `+(H(n)?``:`line-clamp-2`)),K(i,t.item.description)}),G(e,r)};q(p,e=>{t.item.description&&e(m)});var g=L(p,2),_=e=>{var t=uu();yi(t,21,()=>H(a),([e,t])=>e,(e,t)=>{var n=j(()=>h(H(t),2));let r=()=>H(n)[0],i=()=>H(n)[1];var a=lu(),o=F(a),s=F(o);E(o);var c=L(o);E(a),R(()=>{K(s,`${r()??``}:`),K(c,` ${i()??``}`)}),G(e,a)}),E(t),G(e,t)};q(g,e=>{H(n)&&H(a).length&&e(_)}),E(o),R(()=>{K(l,t.item.name),d=Ii(u,1,`shrink-0 rounded border px-1.5 py-0.5 font-mono text-[9px] uppercase tracking-wide`,null,d,{\"opacity-50\":t.item.enabled===!1}),Ri(u,`color:${H(i)}; border-color:color-mix(in oklab, ${H(i)} 35%, transparent)`),K(f,`${H(r)??``}${t.item.enabled===!1?` · off`:``}`)}),Yr(`click`,o,()=>P(n,!H(n))),G(e,o),k()}Xr([`click`]);var pu=U(`<span> </span>`),mu=U(`<button> <span class=\"opacity-60\"> </span></button>`),hu=U(`<div class=\"text-sm text-muted-foreground\">Scanning your arsenal…</div>`),gu=U(`<div class=\"text-sm text-muted-foreground\"> </div>`),_u=U(`<section class=\"flex flex-col gap-2\"><div class=\"flex items-center gap-3 border-b border-border pb-1.5\"><span class=\"size-1.5 shrink-0 rounded-sm\"></span> <span class=\"font-mono text-xs uppercase tracking-[0.14em]\"> </span> <span class=\"font-mono text-xs tracking-[0.1em] text-muted-foreground\"> </span></div> <div class=\"grid grid-cols-1 gap-2 md:grid-cols-2 2xl:grid-cols-3\"></div></section>`),vu=U(`<div class=\"flex flex-col gap-6\"></div>`),yu=U(`<div class=\"flex h-full flex-col gap-4 p-5\"><div class=\"flex flex-wrap items-center justify-between gap-3\"><h1 class=\"font-serif text-2xl text-foreground\">⚔ Arsenal</h1> <div class=\"flex items-center gap-2 font-mono text-xs text-muted-foreground\"><!> <button class=\"rounded border px-2 py-1 transition-colors hover:text-foreground\">↻ Rescan</button></div></div> <div class=\"flex flex-wrap items-center gap-2\"><!> <input placeholder=\"Filter by name or description…\" autocomplete=\"off\" class=\"ml-auto w-full max-w-72 rounded-md border bg-card/60 px-3 py-1.5 text-sm outline-none transition-colors focus:border-ring\"/></div> <!></div>`);function bu(e,t){O(t,!0);let n=N(`skills`),r=N(``),i=j(()=>X.arsenal),a=[{id:`skills`,label:`Skills`},{id:`agents`,label:`Agents`},{id:`mcp`,label:`MCP`}],o=j(()=>{let e=H(i)?H(i)[H(n)]:[],t=H(r).toLowerCase().trim();return t?e.filter(e=>e.name.toLowerCase().includes(t)||(e.description??``).toLowerCase().includes(t)||(e.source??``).toLowerCase().includes(t)):e}),s=j(()=>{let e=new Map;for(let t of H(o)){let n=t.scope===`plugin`?`plugin:${t.source??`plugin`}`:t.scope,r=e.get(n);r||(r={label:t.scope===`plugin`?t.source??`plugin`:t.scope===`project`?`In this project`:`Personal · this machine`,scope:t.scope,items:[]},e.set(n,r)),r.items.push(t)}return[...e.values()]});function c(e){return e===`project`?`var(--c-fable)`:e===`personal`?`var(--c-sonnet)`:`#9bc2ef`}let l=j(()=>H(i)?new Date(H(i).scanned_at).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}):``);var u=yu(),d=F(u),f=L(F(d),2),p=F(f),m=e=>{var t=pu(),n=F(t);E(t),R(()=>K(n,`${H(i).counts.plugins??``} plugins · scanned ${H(l)??``}`)),G(e,t)};q(p,e=>{H(i)&&e(m)});var h=L(p,2);E(f),E(d);var g=L(d,2),_=F(g);yi(_,17,()=>a,e=>e.id,(e,t)=>{var r=mu(),a=F(r),o=L(a),s=F(o,!0);E(o),E(r),R(()=>{Ii(r,1,`rounded-lg px-3 py-1.5 font-mono text-xs transition-colors `+(H(n)===H(t).id?`bg-accent text-accent-foreground`:`text-muted-foreground hover:text-foreground`)),K(a,`${H(t).label??``} `),K(s,H(i)?.counts?.[H(t).id]??0)}),Yr(`click`,r,()=>P(n,H(t).id,!0)),G(e,r)});var v=L(_,2);Xi(v),E(g);var y=L(g,2),b=e=>{G(e,hu())},ee=e=>{var t=gu(),n=F(t,!0);E(t),R(()=>K(n,H(r)?`No matches.`:`Nothing installed in this category.`)),G(e,t)},x=e=>{var t=vu();yi(t,21,()=>H(s),e=>e.label+e.scope,(e,t)=>{var n=_u(),r=F(n),i=F(r),a=L(i,2),o=F(a,!0);E(a);var s=L(a,2),l=F(s,!0);E(s),E(r);var u=L(r,2);yi(u,21,()=>H(t).items,e=>e.scope+(e.source??``)+e.name,(e,t)=>{fu(e,{get item(){return H(t)}})}),E(u),E(n),R((e,n)=>{Ri(i,e),Ri(a,n),K(o,H(t).label),K(l,H(t).items.length)},[()=>`background:${c(H(t).scope)}`,()=>`color:${c(H(t).scope)}`]),G(e,n)}),E(t),G(e,t)};q(y,e=>{X.arsenalLoading&&!H(i)?e(b):H(s).length?e(x,-1):e(ee,1)}),E(u),Yr(`click`,h,()=>X.loadArsenal(!0)),ia(v,()=>H(r),e=>P(r,e)),G(e,u),k()}Xr([`click`]);var xu=U(`<details class=\"rounded-lg border bg-card/50 p-3\"><summary class=\"cursor-pointer text-sm font-medium text-foreground\"> </summary> <p class=\"mt-2 text-[13px] leading-relaxed text-muted-foreground\"> </p></details>`),Su=U(`<!> <!> <div class=\"mt-4 flex flex-col gap-2\"></div> <!>`,1),Cu=U(`<!> <!>`,1);function wu(e,t){O(t,!0);let n=Y(t,`open`,15,!1),r=[{q:`Where do these numbers come from?`,a:`Synthra's Stop hook reads Claude Code's transcript JSONL after each turn and logs token usage to .synthra-graph/token_log.jsonl. The gate logs to gate_log.jsonl, tool calls to tool_log.jsonl. The dashboard reads those — it never feeds back into retrieval.`},{q:`How is cost calculated?`,a:`Token counts × Anthropic's published per-model rates (in src/shared/pricing.ts), summed across input, output, cache-read and cache-write. These are API-equivalent estimates, not your plan billing — useful for comparing sessions.`},{q:`What is the savings floor?`,a:`Each time the Moat blocks an exploratory Grep/Glob, we credit a deliberately conservative 500 tokens × $3/M input rate. Real savings are usually higher (it ignores cache thrash and follow-up reads the block also prevents). It's a floor, not a guess.`},{q:`What is the Moat?`,a:`A PreToolUse hook that intercepts Grep/Glob and, when the graph has confident context, blocks them and hands back the exact graph_read targets + signatures — so the agent reads ~50-token slices instead of whole files.`},{q:`What is the Arsenal view?`,a:`A scan of every skill, subagent, and MCP server available to you — project, personal (~/.claude), and plugin — with descriptions, so you never have to drop to the CLI to recall what's installed. MCP entries show name/type/url only; auth tokens are never read.`},{q:`What's the codebase graph?`,a:`tree-sitter parses your project into a symbol graph (files, symbols, imports, call edges). graph_read returns a symbol's source plus its dependency surface; graph_continue packs a context bundle.`},{q:`Where is everything stored?`,a:`.synthra-graph/ (machine-local, gitignored) holds the graph + logs; .synthra/ (git-tracked) holds branch-aware memory. Nothing leaves your machine.`},{q:`Why is my bill not lower already?`,a:`Savings land only when the agent actually uses the cheap path. v0.4–0.6 push the answer to the point of use (block payloads, edit recipes, dependency footers); a real dogfood session on the latest version is the true test.`}];var i=W();Ti(I(i),()=>Ol,(e,t)=>{t(e,{get open(){return n()},set open(e){n(e)},children:(e,t)=>{var n=W();Ti(I(n),()=>ic,(e,t)=>{t(e,{children:(e,t)=>{var n=Cu(),i=I(n);Ti(i,()=>wl,(e,t)=>{t(e,{class:`fixed inset-0 z-50 bg-black/60`})}),Ti(L(i,2),()=>Fl,(e,t)=>{t(e,{class:`fixed left-1/2 top-1/2 z-50 max-h-[85vh] w-[min(640px,92vw)] -translate-x-1/2 -translate-y-1/2 overflow-y-auto rounded-xl border bg-card p-6 text-card-foreground shadow-2xl`,children:(e,t)=>{var n=Su(),i=I(n);Ti(i,()=>Xs,(e,t)=>{t(e,{class:`font-serif text-2xl`,children:(e,t)=>{Ue(),G(e,ai(`FAQ`))},$$slots:{default:!0}})});var a=L(i,2);Ti(a,()=>Dl,(e,t)=>{t(e,{class:`text-xs text-muted-foreground`,children:(e,t)=>{Ue(),G(e,ai(`Where every number on this dashboard comes from.`))},$$slots:{default:!0}})});var o=L(a,2);yi(o,21,()=>r,e=>e.q,(e,t)=>{var n=xu(),r=F(n),i=F(r,!0);E(r);var a=L(r,2),o=F(a,!0);E(a),E(n),R(()=>{K(i,H(t).q),K(o,H(t).a)}),G(e,n)}),E(o),Ti(L(o,2),()=>jl,(e,t)=>{t(e,{class:`mt-4 w-full rounded-md border py-2 text-sm text-muted-foreground transition-colors hover:text-foreground`,children:(e,t)=>{Ue(),G(e,ai(`Close`))},$$slots:{default:!0}})}),G(e,n)},$$slots:{default:!0}})}),G(e,n)},$$slots:{default:!0}})}),G(e,n)},$$slots:{default:!0}})}),G(e,i),k()}var Tu=U(`<div class=\"flex h-screen w-screen overflow-hidden\"><!> <main class=\"min-w-0 flex-1 overflow-y-auto\"><!></main></div> <!>`,1);function Eu(e,t){O(t,!0);let n=N(!1);da(()=>(X.start(),()=>X.stop()));var r=Tu(),i=I(r),a=F(i);Ua(a,{onFaq:()=>P(n,!0)});var o=L(a,2),s=F(o),c=e=>{su(e,{})},l=e=>{bu(e,{})};q(s,e=>{X.view===`overview`?e(c):e(l,-1)}),E(o),E(i),wu(L(i,2),{get open(){return H(n)},set open(e){P(n,e,!0)}}),G(e,r),k()}var Du=document.getElementById(`app`);if(!Du)throw Error(`missing #app mount node`);si(Eu,{target:Du});</script>\n <style rel=\"stylesheet\" crossorigin>/*! tailwindcss v4.3.1 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0}}}@layer theme{:root,:host{--font-sans:var(--font-sans);--font-serif:var(--font-serif);--font-mono:var(--font-mono);--color-black:#000;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--font-weight-medium:500;--tracking-wide:.025em;--leading-snug:1.375;--leading-relaxed:1.625;--radius-xl:.75rem;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border)}html,body{height:100%}body{background:radial-gradient(1200px 800px at 14% 16%, #2c5db81f, transparent 60%), var(--background);color:var(--foreground);font-family:var(--font-sans);-webkit-font-smoothing:antialiased}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-thumb{background:var(--border);border-radius:999px}::-webkit-scrollbar-track{background:0 0}}@layer components;@layer utilities{.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:0}.top-1\\/2{top:50%}.left-1\\/2{left:50%}.z-50{z-index:50}.my-1{margin-block:var(--spacing)}.mt-1{margin-top:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-4{margin-top:calc(var(--spacing) * 4)}.ml-auto{margin-left:auto}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.grid{display:grid}.inline{display:inline}.inline-flex{display:inline-flex}.size-1\\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-\\[116px\\]{width:116px;height:116px}.size-full{width:100%;height:100%}.h-1{height:var(--spacing)}.h-2{height:calc(var(--spacing) * 2)}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-\\[85vh\\]{max-height:85vh}.max-h-\\[190px\\]{max-height:190px}.max-h-\\[260px\\]{max-height:260px}.min-h-0{min-height:0}.w-9{width:calc(var(--spacing) * 9)}.w-\\[64px\\]{width:64px}.w-\\[248px\\]{width:248px}.w-\\[min\\(440px\\,92vw\\)\\]{width:min(440px,92vw)}.w-\\[min\\(640px\\,92vw\\)\\]{width:min(640px,92vw)}.w-full{width:100%}.w-screen{width:100vw}.max-w-72{max-width:calc(var(--spacing) * 72)}.max-w-\\[120px\\]{max-width:120px}.min-w-0{min-width:0}.flex-1{flex:1}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.-translate-x-1\\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-rotate-90{rotate:-90deg}.animate-pulse{animation:var(--animate-pulse)}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.items-baseline{align-items:baseline}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-px{gap:1px}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-border,.border-border\\/60{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.border-border\\/60{border-color:color-mix(in oklab, var(--border) 60%, transparent)}}.border-sidebar-border{border-color:var(--sidebar-border)}.bg-\\[var\\(--c-fable\\)\\],.bg-\\[var\\(--c-fable\\)\\]\\/12{background-color:var(--c-fable)}@supports (color:color-mix(in lab, red, red)){.bg-\\[var\\(--c-fable\\)\\]\\/12{background-color:color-mix(in oklab, var(--c-fable) 12%, transparent)}}.bg-\\[var\\(--money\\)\\]{background-color:var(--money)}.bg-accent{background-color:var(--accent)}.bg-black\\/60{background-color:#0009}@supports (color:color-mix(in lab, red, red)){.bg-black\\/60{background-color:color-mix(in oklab, var(--color-black) 60%, transparent)}}.bg-border{background-color:var(--border)}.bg-card,.bg-card\\/50{background-color:var(--card)}@supports (color:color-mix(in lab, red, red)){.bg-card\\/50{background-color:color-mix(in oklab, var(--card) 50%, transparent)}}.bg-card\\/55{background-color:var(--card)}@supports (color:color-mix(in lab, red, red)){.bg-card\\/55{background-color:color-mix(in oklab, var(--card) 55%, transparent)}}.bg-card\\/60{background-color:var(--card)}@supports (color:color-mix(in lab, red, red)){.bg-card\\/60{background-color:color-mix(in oklab, var(--card) 60%, transparent)}}.bg-card\\/70{background-color:var(--card)}@supports (color:color-mix(in lab, red, red)){.bg-card\\/70{background-color:color-mix(in oklab, var(--card) 70%, transparent)}}.bg-destructive,.bg-destructive\\/15{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.bg-destructive\\/15{background-color:color-mix(in oklab, var(--destructive) 15%, transparent)}}.bg-muted-foreground,.bg-muted-foreground\\/40{background-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.bg-muted-foreground\\/40{background-color:color-mix(in oklab, var(--muted-foreground) 40%, transparent)}}.bg-primary\\/90{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.bg-primary\\/90{background-color:color-mix(in oklab, var(--primary) 90%, transparent)}}.bg-sidebar{background-color:var(--sidebar)}.bg-sidebar-accent,.bg-sidebar-accent\\/40{background-color:var(--sidebar-accent)}@supports (color:color-mix(in lab, red, red)){.bg-sidebar-accent\\/40{background-color:color-mix(in oklab, var(--sidebar-accent) 40%, transparent)}}.bg-sidebar-border{background-color:var(--sidebar-border)}.p-2\\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.px-1{padding-inline:var(--spacing)}.px-1\\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.py-0\\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-6{padding-block:calc(var(--spacing) * 6)}.pt-1{padding-top:var(--spacing)}.pr-1{padding-right:var(--spacing)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pb-1\\.5{padding-bottom:calc(var(--spacing) * 1.5)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.font-serif{font-family:var(--font-serif)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[9px\\]{font-size:9px}.text-\\[10px\\]{font-size:10px}.text-\\[13px\\]{font-size:13px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.tracking-\\[0\\.1em\\]{--tw-tracking:.1em;letter-spacing:.1em}.tracking-\\[0\\.12em\\]{--tw-tracking:.12em;letter-spacing:.12em}.tracking-\\[0\\.14em\\]{--tw-tracking:.14em;letter-spacing:.14em}.tracking-\\[0\\.18em\\]{--tw-tracking:.18em;letter-spacing:.18em}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.break-all{word-break:break-all}.text-\\[var\\(--c-fable\\)\\]{color:var(--c-fable)}.text-\\[var\\(--money\\)\\]{color:var(--money)}.text-accent-foreground{color:var(--accent-foreground)}.text-card-foreground{color:var(--card-foreground)}.text-destructive{color:var(--destructive)}.text-foreground,.text-foreground\\/70{color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.text-foreground\\/70{color:color-mix(in oklab, var(--foreground) 70%, transparent)}}.text-foreground\\/80{color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.text-foreground\\/80{color:color-mix(in oklab, var(--foreground) 80%, transparent)}}.text-muted-foreground,.text-muted-foreground\\/80{color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\\/80{color:color-mix(in oklab, var(--muted-foreground) 80%, transparent)}}.text-primary-foreground{color:var(--primary-foreground)}.text-sidebar-accent-foreground{color:var(--sidebar-accent-foreground)}.text-sidebar-foreground,.text-sidebar-foreground\\/60{color:var(--sidebar-foreground)}@supports (color:color-mix(in lab, red, red)){.text-sidebar-foreground\\/60{color:color-mix(in oklab, var(--sidebar-foreground) 60%, transparent)}}.text-sidebar-foreground\\/75{color:var(--sidebar-foreground)}@supports (color:color-mix(in lab, red, red)){.text-sidebar-foreground\\/75{color:color-mix(in oklab, var(--sidebar-foreground) 75%, transparent)}}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.transition-\\[width\\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.outline-none{--tw-outline-style:none;outline-style:none}@media (hover:hover){.hover\\:bg-card\\/80:hover{background-color:var(--card)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-card\\/80:hover{background-color:color-mix(in oklab, var(--card) 80%, transparent)}}.hover\\:bg-card\\/85:hover{background-color:var(--card)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-card\\/85:hover{background-color:color-mix(in oklab, var(--card) 85%, transparent)}}.hover\\:bg-sidebar-accent\\/50:hover{background-color:var(--sidebar-accent)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-sidebar-accent\\/50:hover{background-color:color-mix(in oklab, var(--sidebar-accent) 50%, transparent)}}.hover\\:text-foreground:hover{color:var(--foreground)}.hover\\:text-sidebar-foreground:hover{color:var(--sidebar-foreground)}}.focus\\:border-ring:focus{border-color:var(--ring)}@media (hover:hover){.enabled\\:hover\\:text-foreground:enabled:hover{color:var(--foreground)}}.disabled\\:opacity-40:disabled{opacity:.4}@media (width>=40rem){.sm\\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (width>=48rem){.md\\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (width>=64rem){.lg\\:absolute{position:absolute}.lg\\:inset-0{inset:0}.lg\\:col-span-3{grid-column:span 3/span 3}.lg\\:col-start-1{grid-column-start:1}.lg\\:col-start-2{grid-column-start:2}.lg\\:col-start-3{grid-column-start:3}.lg\\:row-span-3{grid-row:span 3/span 3}.lg\\:row-start-1{grid-row-start:1}.lg\\:row-start-2{grid-row-start:2}.lg\\:row-start-3{grid-row-start:3}.lg\\:row-start-4{grid-row-start:4}.lg\\:row-start-5{grid-row-start:5}.lg\\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}}@media (width>=96rem){.\\32 xl\\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}}@property --tw-animation-delay{syntax:\"*\";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:\"*\";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:\"*\";inherits:false}@property --tw-animation-fill-mode{syntax:\"*\";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:\"*\";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:\"*\";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:\"*\";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:\"*\";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:\"*\";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:\"*\";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:\"*\";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:\"*\";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:\"*\";inherits:false;initial-value:0}:root{--radius:.75rem;--background:#04081a;--foreground:#ecf2fb;--card:#0a1733;--card-foreground:#ecf2fb;--popover:#0a1733;--popover-foreground:#ecf2fb;--primary:#2c5db8;--primary-foreground:#f4f7fc;--secondary:#122549;--secondary-foreground:#d7e6f7;--muted:#102146;--muted-foreground:#8ba0c2;--accent:#1b3a78;--accent-foreground:#ecf2fb;--destructive:#ff5d5d;--destructive-foreground:#fff5f5;--border:#9bc2ef24;--input:#9bc2ef2e;--ring:#5c8fe6;--sidebar:#081226;--sidebar-foreground:#d7e6f7;--sidebar-primary:#2c5db8;--sidebar-primary-foreground:#f4f7fc;--sidebar-accent:#122549;--sidebar-accent-foreground:#ecf2fb;--sidebar-border:#9bc2ef1f;--sidebar-ring:#5c8fe6;--c-fable:#2ee08f;--c-opus:#ff6338;--c-sonnet:#ffb938;--c-haiku:#7438ff;--c-unknown:#12cbf5;--money:#4ade9b;--font-sans:\"Geist\", ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif;--font-serif:\"Instrument Serif\", \"Times New Roman\", serif;--font-mono:\"Geist Mono\", ui-monospace, \"SF Mono\", Menlo, Consolas, monospace}@property --tw-translate-x{syntax:\"*\";inherits:false;initial-value:0}@property --tw-translate-y{syntax:\"*\";inherits:false;initial-value:0}@property --tw-translate-z{syntax:\"*\";inherits:false;initial-value:0}@property --tw-border-style{syntax:\"*\";inherits:false;initial-value:solid}@property --tw-leading{syntax:\"*\";inherits:false}@property --tw-font-weight{syntax:\"*\";inherits:false}@property --tw-tracking{syntax:\"*\";inherits:false}@property --tw-ordinal{syntax:\"*\";inherits:false}@property --tw-slashed-zero{syntax:\"*\";inherits:false}@property --tw-numeric-figure{syntax:\"*\";inherits:false}@property --tw-numeric-spacing{syntax:\"*\";inherits:false}@property --tw-numeric-fraction{syntax:\"*\";inherits:false}@property --tw-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:\"*\";inherits:false}@property --tw-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:\"*\";inherits:false}@property --tw-inset-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:\"*\";inherits:false}@property --tw-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:\"*\";inherits:false}@property --tw-inset-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:\"*\";inherits:false}@property --tw-ring-offset-width{syntax:\"<length>\";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:\"*\";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:\"*\";inherits:false}@keyframes pulse{50%{opacity:.5}}\n/*$vite$:1*/</style>\n </head>\n <body>\n <div id=\"app\"></div>\n </body>\n</html>\n","<svg width=\"107\" height=\"107\" viewBox=\"0 0 107 107\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<rect x=\"0.5\" y=\"0.5\" width=\"106\" height=\"106\" rx=\"7.5\" fill=\"url(#paint0_radial_21_11)\"/>\n<rect x=\"0.5\" y=\"0.5\" width=\"106\" height=\"106\" rx=\"7.5\" stroke=\"url(#paint1_linear_21_11)\"/>\n<path d=\"M26.408 72.558C25.5813 72.558 24.6513 72.4753 23.618 72.31C22.626 72.1447 21.6753 71.938 20.766 71.69C19.898 71.442 19.216 71.1733 18.72 70.884C18.4307 70.7187 18.2033 70.5533 18.038 70.388C17.914 70.1813 17.852 69.8507 17.852 69.396L17.542 59.662C17.542 58.8353 17.8107 58.422 18.348 58.422C18.8027 58.422 19.1127 58.794 19.278 59.538L19.836 61.894C21.2413 67.8047 23.866 70.76 27.71 70.76C29.7767 70.76 31.4093 70.078 32.608 68.714C33.848 67.3087 34.468 65.3453 34.468 62.824C34.468 60.3853 33.8273 58.112 32.546 56.004C31.306 53.896 29.3013 51.8087 26.532 49.742C23.4733 47.5513 21.2413 45.4433 19.836 43.418C18.4307 41.3513 17.728 39.1607 17.728 36.846C17.728 33.7873 18.782 31.3487 20.89 29.53C23.0393 27.67 25.7673 26.74 29.074 26.74C30.314 26.74 31.5127 26.8847 32.67 27.174C33.8273 27.4633 34.778 27.8767 35.522 28.414C35.77 28.5793 35.956 28.7653 36.08 28.972C36.2453 29.1787 36.328 29.4473 36.328 29.778L36.514 39.14C36.514 39.8427 36.2453 40.194 35.708 40.194C35.336 40.194 35.0673 39.9047 34.902 39.326L34.468 37.776C33.5587 34.5933 32.608 32.2787 31.616 30.832C30.6653 29.344 29.2807 28.6 27.462 28.6C25.6847 28.6 24.2587 29.1787 23.184 30.336C22.1507 31.4933 21.634 33.126 21.634 35.234C21.634 37.0113 22.2127 38.706 23.37 40.318C24.5273 41.93 26.5527 43.8933 29.446 46.208C32.546 48.7293 34.7987 51.168 36.204 53.524C37.6507 55.8387 38.374 58.3187 38.374 60.964C38.374 63.2787 37.8573 65.304 36.824 67.04C35.7907 68.776 34.3647 70.14 32.546 71.132C30.7687 72.0827 28.7227 72.558 26.408 72.558ZM44.1831 84.71C43.0671 84.71 42.1784 84.3173 41.5171 83.532C40.8558 82.788 40.5251 81.92 40.5251 80.928C40.5251 80.1427 40.7524 79.4813 41.2071 78.944C41.6618 78.4067 42.2818 78.138 43.0671 78.138C43.7284 78.138 44.2038 78.2827 44.4931 78.572C44.7824 78.8613 44.9891 79.192 45.1131 79.564C45.2371 79.936 45.3611 80.2667 45.4851 80.556C45.6091 80.8453 45.8571 80.99 46.2291 80.99C46.6838 80.99 47.0971 80.6593 47.4691 79.998C47.8411 79.378 48.3578 78.0347 49.0191 75.968C49.4324 74.728 49.6804 73.6533 49.7631 72.744C49.8871 71.8347 49.8664 70.8633 49.7011 69.83C49.5771 68.7967 49.2671 67.536 48.7711 66.048L42.0131 44.534C41.7238 43.542 41.4344 42.9013 41.1451 42.612C40.8971 42.3227 40.4838 42.116 39.9051 41.992L38.9751 41.806C38.4378 41.682 38.1691 41.4133 38.1691 41C38.1691 40.5867 38.4584 40.38 39.0371 40.38H49.2671C49.8458 40.38 50.1351 40.5867 50.1351 41C50.1351 41.4547 49.8664 41.7233 49.3291 41.806L48.3371 41.93C47.3451 42.054 46.7044 42.302 46.4151 42.674C46.1671 43.0047 46.1878 43.6247 46.4771 44.534L51.9331 62.7C52.0571 63.1133 52.2431 63.32 52.4911 63.32C52.7804 63.32 52.9871 63.1133 53.1111 62.7L58.3811 45.65C58.7118 44.534 58.7944 43.7073 58.6291 43.17C58.5051 42.5913 57.9264 42.2193 56.8931 42.054L55.5911 41.806C55.0538 41.682 54.7851 41.4133 54.7851 41C54.7851 40.5867 55.0744 40.38 55.6531 40.38H63.5271C64.1058 40.38 64.3951 40.6073 64.3951 41.062C64.3951 41.4753 64.1471 41.7647 63.6511 41.93L63.0931 42.116C62.4731 42.3227 61.9564 42.6947 61.5431 43.232C61.1298 43.7693 60.6958 44.6993 60.2411 46.022L51.0031 74.852C50.0938 77.7453 49.2671 79.8947 48.5231 81.3C47.8204 82.7053 47.1384 83.6147 46.4771 84.028C45.8158 84.4827 45.0511 84.71 44.1831 84.71ZM64.9342 72C64.3142 72 64.0042 71.7727 64.0042 71.318C64.0042 70.946 64.2729 70.698 64.8102 70.574L65.5542 70.45C66.4222 70.2847 66.9802 70.0367 67.2282 69.706C67.5176 69.334 67.6622 68.714 67.6622 67.846V47.014C67.6622 46.27 67.5382 45.774 67.2902 45.526C67.0836 45.2367 66.6909 45.0507 66.1122 44.968L64.8102 44.782C64.2729 44.7407 64.0042 44.5133 64.0042 44.1C64.0042 43.7693 64.3349 43.542 64.9962 43.418C66.2776 43.2113 67.2489 42.8807 67.9102 42.426C68.6129 41.9713 69.3362 41.4133 70.0802 40.752C70.4522 40.38 70.7622 40.194 71.0102 40.194C71.3822 40.194 71.5682 40.442 71.5682 40.938V43.728C71.5682 44.1 71.6922 44.348 71.9402 44.472C72.2296 44.5547 72.5396 44.4307 72.8702 44.1C74.5236 42.5293 75.9702 41.4547 77.2102 40.876C78.4916 40.2973 79.8349 40.008 81.2402 40.008C83.1002 40.008 84.5882 40.6693 85.7042 41.992C86.8202 43.2733 87.3782 45.1747 87.3782 47.696V67.846C87.3782 68.714 87.5022 69.334 87.7502 69.706C88.0396 70.0367 88.6182 70.264 89.4862 70.388L90.8502 70.574C91.3049 70.6567 91.5322 70.9047 91.5322 71.318C91.5322 71.7727 91.2842 72 90.7882 72H80.3722C79.7936 72 79.5042 71.7727 79.5042 71.318C79.5042 70.9047 79.7316 70.6567 80.1862 70.574L81.0542 70.45C81.9222 70.326 82.4802 70.078 82.7282 69.706C83.0176 69.334 83.1622 68.714 83.1622 67.846V48.378C83.1622 46.3527 82.7902 44.9267 82.0462 44.1C81.3022 43.2733 80.2482 42.86 78.8842 42.86C77.5616 42.86 76.3629 43.2527 75.2882 44.038C74.2549 44.782 73.4282 45.7947 72.8082 47.076C72.1882 48.316 71.8782 49.7007 71.8782 51.23V67.846C71.8782 68.714 72.0022 69.334 72.2502 69.706C72.5396 70.078 73.1182 70.3053 73.9862 70.388L75.6602 70.574C76.1149 70.6567 76.3422 70.884 76.3422 71.256C76.3422 71.752 76.0322 72 75.4122 72H64.9342Z\" fill=\"white\"/>\n<defs>\n<radialGradient id=\"paint0_radial_21_11\" cx=\"0\" cy=\"0\" r=\"1\" gradientUnits=\"userSpaceOnUse\" gradientTransform=\"translate(14 16) rotate(43.5498) scale(167.638 156.2)\">\n<stop stop-color=\"#2C5DB8\"/>\n<stop offset=\"1\" stop-color=\"#04081A\"/>\n</radialGradient>\n<linearGradient id=\"paint1_linear_21_11\" x1=\"1.77511\" y1=\"1.50277e-06\" x2=\"105.225\" y2=\"107\" gradientUnits=\"userSpaceOnUse\">\n<stop stop-color=\"#5C8FE6\"/>\n<stop offset=\"1\" stop-color=\"#335080\"/>\n</linearGradient>\n</defs>\n</svg>\n","// Writes hook scripts into <project>/.claude/hooks/ and registers them in\n// <project>/.claude/settings.local.json. Idempotent — re-running `syn .`\n// regenerates the scripts and merges hook entries cleanly with any user-added\n// hooks already in the file.\n\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport { log } from \"../shared/logger.js\";\nimport type { SynthraPaths } from \"../shared/paths.js\";\n\nimport preCompactPs1 from \"./scripts/pre-compact.ps1\";\nimport preCompactSh from \"./scripts/pre-compact.sh\";\nimport preToolUsePs1 from \"./scripts/pre-tool-use.ps1\";\nimport preToolUseSh from \"./scripts/pre-tool-use.sh\";\nimport primePs1 from \"./scripts/prime.ps1\";\nimport primeSh from \"./scripts/prime.sh\";\nimport stopPs1 from \"./scripts/stop.ps1\";\nimport stopSh from \"./scripts/stop.sh\";\n\nexport interface InstallResult {\n scriptsWritten: string[];\n settingsUpdated: boolean;\n}\n\ninterface ScriptDef {\n /** Hook event name as recognized by Claude Code. */\n event: \"SessionStart\" | \"PreToolUse\" | \"PreCompact\" | \"Stop\";\n /** Tool-name regex for PreToolUse only. */\n matcher?: string;\n /** Base filename written into .claude/hooks/. */\n baseName: string;\n ps1: string;\n sh: string;\n}\n\nconst SCRIPTS: ScriptDef[] = [\n { event: \"SessionStart\", baseName: \"synthra-prime\", ps1: primePs1, sh: primeSh },\n {\n event: \"PreToolUse\",\n matcher: \"Grep|Glob\",\n baseName: \"synthra-pre-tool-use\",\n ps1: preToolUsePs1,\n sh: preToolUseSh,\n },\n { event: \"PreCompact\", baseName: \"synthra-pre-compact\", ps1: preCompactPs1, sh: preCompactSh },\n { event: \"Stop\", baseName: \"synthra-stop\", ps1: stopPs1, sh: stopSh },\n];\n\nconst SYNTHRA_HOOK_MARKER = \"synthra-hook=true\";\n\nfunction commandFor(scriptPath: string): string {\n if (process.platform === \"win32\") {\n // PowerShell on Windows; -ExecutionPolicy Bypass so the script always runs.\n return `powershell.exe -ExecutionPolicy Bypass -NoProfile -File \"${scriptPath}\"`;\n }\n return `bash \"${scriptPath}\"`;\n}\n\nfunction chosenScriptBody(s: ScriptDef): string {\n return process.platform === \"win32\" ? s.ps1 : s.sh;\n}\n\nfunction chosenScriptExt(): string {\n return process.platform === \"win32\" ? \".ps1\" : \".sh\";\n}\n\ninterface HooksConfig {\n hooks?: {\n [event: string]: Array<{\n matcher?: string;\n hooks?: Array<{ type: string; command: string; meta?: string }>;\n }>;\n };\n [k: string]: unknown;\n}\n\nasync function readSettings(path: string): Promise<HooksConfig> {\n try {\n const raw = await readFile(path, \"utf8\");\n return JSON.parse(raw) as HooksConfig;\n } catch {\n return {};\n }\n}\n\nfunction stripOurHooks(config: HooksConfig): HooksConfig {\n if (!config.hooks) return config;\n const next: HooksConfig[\"hooks\"] = {};\n for (const [event, entries] of Object.entries(config.hooks)) {\n const filtered = entries\n .map((entry) => ({\n ...entry,\n hooks: (entry.hooks ?? []).filter((h) => h.meta !== SYNTHRA_HOOK_MARKER),\n }))\n .filter((entry) => (entry.hooks?.length ?? 0) > 0);\n if (filtered.length) next[event] = filtered;\n }\n config.hooks = next;\n return config;\n}\n\nfunction mergeOurHooks(config: HooksConfig, paths: SynthraPaths): HooksConfig {\n const hooks = (config.hooks = config.hooks ?? {});\n for (const s of SCRIPTS) {\n const scriptPath = join(paths.claudeHooksDir, `${s.baseName}${chosenScriptExt()}`);\n const entry = {\n ...(s.matcher ? { matcher: s.matcher } : {}),\n hooks: [\n {\n type: \"command\",\n command: commandFor(scriptPath),\n meta: SYNTHRA_HOOK_MARKER,\n },\n ],\n };\n const list = (hooks[s.event] = hooks[s.event] ?? []);\n list.push(entry);\n }\n return config;\n}\n\nexport async function installHooks(paths: SynthraPaths): Promise<InstallResult> {\n await mkdir(paths.claudeHooksDir, { recursive: true });\n\n const scriptsWritten: string[] = [];\n for (const s of SCRIPTS) {\n const target = join(paths.claudeHooksDir, `${s.baseName}${chosenScriptExt()}`);\n await writeFile(target, chosenScriptBody(s), \"utf8\");\n scriptsWritten.push(target);\n }\n\n await mkdir(dirname(paths.claudeSettings), { recursive: true });\n const existing = await readSettings(paths.claudeSettings);\n const stripped = stripOurHooks(existing);\n const merged = mergeOurHooks(stripped, paths);\n\n await writeFile(paths.claudeSettings, JSON.stringify(merged, null, 2) + \"\\n\", \"utf8\");\n\n log.debug(`installed ${scriptsWritten.length} hook script(s) into ${paths.claudeHooksDir}`);\n\n return { scriptsWritten, settingsUpdated: true };\n}\n","# PreCompact hook — Windows PowerShell.\n# Re-injects the primer after Claude auto-compacts. Same logic as prime.ps1.\n\n$ErrorActionPreference = \"SilentlyContinue\"\n\n$portFile = Join-Path $PWD \".synthra-graph\\mcp_port\"\nif (-not (Test-Path $portFile)) { exit 0 }\n$port = (Get-Content -Path $portFile -Raw).Trim()\nif (-not $port) { exit 0 }\n\ntry {\n $resp = Invoke-RestMethod -Uri \"http://127.0.0.1:$port/prime\" -Method GET -TimeoutSec 3\n if ($resp.primer) { Write-Output $resp.primer }\n} catch {\n # silent\n}\nexit 0\n","#!/usr/bin/env bash\n# PreCompact hook — bash. Re-injects the primer after Claude auto-compacts.\n\nset +e\n\nPORT_FILE=\"$PWD/.synthra-graph/mcp_port\"\nif [ ! -f \"$PORT_FILE\" ]; then exit 0; fi\nPORT=$(cat \"$PORT_FILE\" 2>/dev/null | tr -d '[:space:]')\nif [ -z \"$PORT\" ]; then exit 0; fi\n\n# Parse the primer with jq, not sed. The primer now carries a multi-line \"Since you\n# were last here\" resume digest with quotes and newlines, so the old greedy sed capture\n# (.*\") both over-ran into the trailing \"port\" field and broke on inner quotes. jq -r\n# also decodes JSON escapes, so we print with %s (not %b). No jq → no primer (matches\n# prime.sh / stop.sh — completes the jq migration across all bash hooks).\nif ! command -v jq >/dev/null 2>&1; then exit 0; fi\n\nPRIMER=$(curl -sS --max-time 3 \"http://127.0.0.1:$PORT/prime\" 2>/dev/null \\\n | jq -r '.primer // empty' 2>/dev/null \\\n | head -c 8000)\n\nif [ -n \"$PRIMER\" ]; then\n printf '%s\\n' \"$PRIMER\"\nfi\nexit 0\n","# PreToolUse hook — Windows PowerShell.\n# THE MOAT (improvement #1). Reads the tool call from stdin (JSON), POSTs it\n# to /gate, and if the server says \"block\" emits a JSON deny-decision to\n# stdout. Claude Code reads stdout JSON to enforce the decision.\n# Always exits 0; failure-to-reach-server leaves Claude untouched.\n\n$ErrorActionPreference = \"SilentlyContinue\"\n\n$raw = [Console]::In.ReadToEnd()\nif (-not $raw) { exit 0 }\n\ntry {\n $hookInput = $raw | ConvertFrom-Json -ErrorAction Stop\n} catch {\n exit 0\n}\n\n$portFile = Join-Path $PWD \".synthra-graph\\mcp_port\"\nif (-not (Test-Path $portFile)) { exit 0 }\n$port = (Get-Content -Path $portFile -Raw).Trim()\nif (-not $port) { exit 0 }\n\n$payload = @{\n tool_name = $hookInput.tool_name\n tool_input = $hookInput.tool_input\n} | ConvertTo-Json -Depth 10 -Compress\n\ntry {\n $resp = Invoke-RestMethod -Uri \"http://127.0.0.1:$port/gate\" -Method POST `\n -Body $payload -ContentType \"application/json\" -TimeoutSec 3\n} catch {\n exit 0\n}\n\nif ($resp.decision -eq \"block\") {\n $denyJson = @{\n hookSpecificOutput = @{\n hookEventName = \"PreToolUse\"\n permissionDecision = \"deny\"\n permissionDecisionReason = $resp.reason\n }\n } | ConvertTo-Json -Depth 5 -Compress\n Write-Output $denyJson\n}\nexit 0\n","#!/usr/bin/env bash\r\n# PreToolUse hook — bash. POSTs the tool call to /gate; if server returns\r\n# \"block\", emits the deny-decision JSON to stdout for Claude Code to enforce.\r\n# Always exits 0; server failures leave Claude untouched.\r\n# Requires `jq` to read the gate response; falls back to silent no-op (no\r\n# enforcement) if absent — same policy as the Stop/Prime hooks.\r\n\r\nset +e\r\n\r\nPORT_FILE=\"$PWD/.synthra-graph/mcp_port\"\r\nif [ ! -f \"$PORT_FILE\" ]; then exit 0; fi\r\nPORT=$(cat \"$PORT_FILE\" 2>/dev/null | tr -d '[:space:]')\r\nif [ -z \"$PORT\" ]; then exit 0; fi\r\n\r\nINPUT=$(cat 2>/dev/null)\r\nif [ -z \"$INPUT\" ]; then exit 0; fi\r\n\r\nRESP=$(curl -sS --max-time 3 -X POST -H \"Content-Type: application/json\" \\\r\n --data \"$INPUT\" \"http://127.0.0.1:$PORT/gate\" 2>/dev/null)\r\n\r\n# Parse the gate response with jq, not a greedy sed capture. The block `reason`\r\n# legitimately contains double quotes (it quotes the query, e.g. \"login\"), so the\r\n# old sed capture (\\(.*\\)\") both over-ran into the trailing JSON fields and, once\r\n# embedded raw in the heredoc, produced invalid hook output. jq reads each field\r\n# and re-emits the deny object with correct escaping. (matches stop.sh / prime.sh,\r\n# jq fix #1.) No jq → no enforcement; bail silently like the other hooks.\r\nif ! command -v jq >/dev/null 2>&1; then exit 0; fi\r\n\r\nDECISION=$(printf '%s' \"$RESP\" | jq -r '.decision // empty' 2>/dev/null)\r\nif [ \"$DECISION\" = \"block\" ]; then\r\n REASON=$(printf '%s' \"$RESP\" | jq -r '.reason // empty' 2>/dev/null)\r\n jq -nc --arg r \"$REASON\" \\\r\n '{hookSpecificOutput:{hookEventName:\"PreToolUse\",permissionDecision:\"deny\",permissionDecisionReason:$r}}'\r\nfi\r\nexit 0\r\n","# SessionStart + PreCompact hook — Windows PowerShell.\n# Reads .synthra-graph/mcp_port, calls GET /prime, prints the primer to stdout\n# (Claude Code appends stdout to the session's system prompt). Always exits 0;\n# any failure leaves Claude with the prompt it would have gotten without Synthra.\n\n$ErrorActionPreference = \"SilentlyContinue\"\n\n$portFile = Join-Path $PWD \".synthra-graph\\mcp_port\"\nif (-not (Test-Path $portFile)) { exit 0 }\n$port = (Get-Content -Path $portFile -Raw).Trim()\nif (-not $port) { exit 0 }\n\ntry {\n $resp = Invoke-RestMethod -Uri \"http://127.0.0.1:$port/prime\" -Method GET -TimeoutSec 3\n if ($resp.primer) { Write-Output $resp.primer }\n} catch {\n # silent on failure — Claude continues without the primer\n}\nexit 0\n","#!/usr/bin/env bash\n# SessionStart + PreCompact hook — bash.\n# Reads .synthra-graph/mcp_port, calls GET /prime, prints the primer to stdout.\n# Always exits 0; any failure leaves Claude with the prompt it would have had\n# without Synthra.\n\nset +e\n\nPORT_FILE=\"$PWD/.synthra-graph/mcp_port\"\nif [ ! -f \"$PORT_FILE\" ]; then exit 0; fi\nPORT=$(cat \"$PORT_FILE\" 2>/dev/null | tr -d '[:space:]')\nif [ -z \"$PORT\" ]; then exit 0; fi\n\n# Parse the primer with jq, not sed. Primer text legitimately contains quotes, so a\n# negated-class capture ([^\"]*) would truncate it at the first inner quote, while the\n# old greedy capture (.*\") over-ran into the trailing \"port\" field and injected junk.\n# jq -r also decodes JSON escapes, so we print with %s (not %b). No jq → no primer.\nif ! command -v jq >/dev/null 2>&1; then exit 0; fi\n\nPRIMER=$(curl -sS --max-time 3 \"http://127.0.0.1:$PORT/prime\" 2>/dev/null \\\n | jq -r '.primer // empty' 2>/dev/null \\\n | head -c 8000)\n\nif [ -n \"$PRIMER\" ]; then\n printf '%s\\n' \"$PRIMER\"\nfi\nexit 0\n","# Stop hook — Windows PowerShell.\r\n# Reads Claude's transcript JSONL from $hookInput.transcript_path, sums\r\n# usage.* token counts across all assistant turns since the last offset, and\r\n# POSTs the totals to /log. Uses a per-transcript .stopoffset file to avoid\r\n# double-counting on session resume.\r\n\r\n$ErrorActionPreference = \"SilentlyContinue\"\r\n\r\n$raw = [Console]::In.ReadToEnd()\r\nif (-not $raw) { exit 0 }\r\ntry { $hookInput = $raw | ConvertFrom-Json -ErrorAction Stop } catch { exit 0 }\r\n\r\n$transcript = $hookInput.transcript_path\r\nif (-not $transcript -or -not (Test-Path $transcript)) { exit 0 }\r\n\r\n$portFile = Join-Path $PWD \".synthra-graph\\mcp_port\"\r\nif (-not (Test-Path $portFile)) { exit 0 }\r\n$port = (Get-Content -Path $portFile -Raw).Trim()\r\nif (-not $port) { exit 0 }\r\n\r\n$offsetFile = \"$transcript.stopoffset\"\r\n$startOffset = 0\r\nif (Test-Path $offsetFile) {\r\n $val = (Get-Content -Path $offsetFile -Raw).Trim()\r\n if ($val -match '^\\d+$') { $startOffset = [int]$val }\r\n}\r\n\r\n$lines = Get-Content -Path $transcript\r\n$inT = 0; $outT = 0; $cc = 0; $cr = 0; $model = \"\"\r\n$lineNum = 0\r\nforeach ($line in $lines) {\r\n $lineNum++\r\n if ($lineNum -le $startOffset) { continue }\r\n if (-not $line) { continue }\r\n try { $e = $line | ConvertFrom-Json -ErrorAction Stop } catch { continue }\r\n $usage = $e.message.usage\r\n if (-not $usage) { continue }\r\n $inT += [int]($usage.input_tokens | ForEach-Object { if ($_) { $_ } else { 0 } })\r\n $outT += [int]($usage.output_tokens | ForEach-Object { if ($_) { $_ } else { 0 } })\r\n $cc += [int]($usage.cache_creation_input_tokens | ForEach-Object { if ($_) { $_ } else { 0 } })\r\n $cr += [int]($usage.cache_read_input_tokens | ForEach-Object { if ($_) { $_ } else { 0 } })\r\n if ($e.message.model) { $model = $e.message.model }\r\n}\r\n\r\nSet-Content -Path $offsetFile -Value $lineNum -Encoding ASCII\r\n\r\nif ($inT -eq 0 -and $outT -eq 0) { exit 0 }\r\n\r\n$payload = @{\r\n input_tokens = $inT\r\n output_tokens = $outT\r\n cache_creation_input_tokens = $cc\r\n cache_read_input_tokens = $cr\r\n model = $model\r\n description = \"synthra-stop-hook\"\r\n project = $PWD.Path\r\n} | ConvertTo-Json -Compress\r\n\r\ntry {\r\n Invoke-RestMethod -Uri \"http://127.0.0.1:$port/log\" -Method POST `\r\n -Body $payload -ContentType \"application/json\" -TimeoutSec 3 | Out-Null\r\n} catch {\r\n # silent\r\n}\r\n\r\n# Refresh CONTEXT.md from the branch-scoped store.\r\n$ctxPayload = @{ transcript_path = $transcript } | ConvertTo-Json -Compress\r\ntry {\r\n Invoke-RestMethod -Uri \"http://127.0.0.1:$port/context-update\" -Method POST `\r\n -Body $ctxPayload -ContentType \"application/json\" -TimeoutSec 3 | Out-Null\r\n} catch {\r\n # silent\r\n}\r\nexit 0\r\n","#!/usr/bin/env bash\r\n# Stop hook — bash. Reads transcript JSONL, sums usage.* across new lines,\r\n# POSTs totals to /log. Uses a .stopoffset file to avoid double-counting.\r\n# Requires `jq` for robust JSON parsing; falls back to silent no-op if absent.\r\n\r\nset +e\r\n\r\nINPUT=$(cat 2>/dev/null)\r\nif [ -z \"$INPUT\" ]; then exit 0; fi\r\n\r\n# jq is required for the parsing below — bail early (silent no-op) if it's absent.\r\nif ! command -v jq >/dev/null 2>&1; then exit 0; fi\r\n\r\n# Extract transcript_path with jq, not sed. A greedy sed capture (\\(.*\\)\") grabs the\r\n# trailing JSON fields after transcript_path and yields a path that doesn't exist, so\r\n# the -f check below always failed and totals were never POSTed to /log. (issue #1)\r\nTRANSCRIPT=$(printf '%s' \"$INPUT\" | jq -r '.transcript_path // empty' 2>/dev/null)\r\nif [ -z \"$TRANSCRIPT\" ] || [ ! -f \"$TRANSCRIPT\" ]; then exit 0; fi\r\n\r\nPORT_FILE=\"$PWD/.synthra-graph/mcp_port\"\r\nif [ ! -f \"$PORT_FILE\" ]; then exit 0; fi\r\nPORT=$(cat \"$PORT_FILE\" 2>/dev/null | tr -d '[:space:]')\r\nif [ -z \"$PORT\" ]; then exit 0; fi\r\n\r\nOFFSET_FILE=\"${TRANSCRIPT}.stopoffset\"\r\nSTART_OFFSET=0\r\nif [ -f \"$OFFSET_FILE\" ]; then\r\n START_OFFSET=$(cat \"$OFFSET_FILE\" 2>/dev/null | tr -d '[:space:]')\r\n case \"$START_OFFSET\" in ''|*[!0-9]*) START_OFFSET=0 ;; esac\r\nfi\r\n\r\nTOTAL_LINES=$(wc -l < \"$TRANSCRIPT\" 2>/dev/null | tr -d ' ')\r\nTOTAL_LINES=${TOTAL_LINES:-0}\r\n\r\nif [ \"$TOTAL_LINES\" -le \"$START_OFFSET\" ]; then exit 0; fi\r\n\r\nUSAGE=$(tail -n +$((START_OFFSET + 1)) \"$TRANSCRIPT\" 2>/dev/null \\\r\n | jq -s '\r\n map(select(.message.usage != null) | .message)\r\n | reduce .[] as $m (\r\n {in:0, out:0, cc:0, cr:0, model:\"\"};\r\n .in += ($m.usage.input_tokens // 0)\r\n | .out += ($m.usage.output_tokens // 0)\r\n | .cc += ($m.usage.cache_creation_input_tokens // 0)\r\n | .cr += ($m.usage.cache_read_input_tokens // 0)\r\n | .model = ($m.model // .model)\r\n )\r\n ' 2>/dev/null)\r\n\r\nprintf '%s' \"$TOTAL_LINES\" > \"$OFFSET_FILE\"\r\n\r\nIN=$(printf '%s' \"$USAGE\" | jq -r '.in // 0')\r\nOUT=$(printf '%s' \"$USAGE\" | jq -r '.out // 0')\r\nCC=$(printf '%s' \"$USAGE\" | jq -r '.cc // 0')\r\nCR=$(printf '%s' \"$USAGE\" | jq -r '.cr // 0')\r\nMODEL=$(printf '%s' \"$USAGE\" | jq -r '.model // \"\"')\r\n\r\nif [ \"$IN\" = \"0\" ] && [ \"$OUT\" = \"0\" ]; then exit 0; fi\r\n\r\ncurl -sS --max-time 3 -X POST -H \"Content-Type: application/json\" \\\r\n --data \"$(jq -nc --argjson i \"$IN\" --argjson o \"$OUT\" --argjson cc \"$CC\" --argjson cr \"$CR\" --arg m \"$MODEL\" --arg p \"$PWD\" \\\r\n '{input_tokens:$i, output_tokens:$o, cache_creation_input_tokens:$cc, cache_read_input_tokens:$cr, model:$m, description:\"synthra-stop-hook\", project:$p}')\" \\\r\n \"http://127.0.0.1:$PORT/log\" >/dev/null 2>&1\r\n\r\n# Refresh CONTEXT.md from the branch-scoped store.\r\ncurl -sS --max-time 3 -X POST -H \"Content-Type: application/json\" \\\r\n --data \"$(jq -nc --arg t \"$TRANSCRIPT\" '{transcript_path:$t}')\" \\\r\n \"http://127.0.0.1:$PORT/context-update\" >/dev/null 2>&1\r\n\r\nexit 0\r\n","// HTTP server (Hono). Hosts the routes hooks need (/prime, /pack, /log,\n// /gate, /activity) and serves the loaded graph from memory. The MCP-protocol\n// envelope (/mcp endpoint, JSON-RPC) is wired in M3.\n\nimport { serve } from \"@hono/node-server\";\nimport { Hono } from \"hono\";\nimport { writeFile } from \"node:fs/promises\";\n\nimport { ActivityStore } from \"../activity/activity-log.js\";\nimport { createFileWatcher, type FileWatcher } from \"../activity/file-watcher.js\";\nimport { createGitWatcher, type GitWatcher } from \"../activity/git-watcher.js\";\nimport { scanProject } from \"../cli/scan-command.js\";\nimport { readGraph, readSymbolIndex } from \"../graph/store.js\";\nimport { SCHEMA_VERSION } from \"../graph/types.js\";\nimport { LearnRuntime } from \"../learn/runtime.js\";\nimport { log } from \"../shared/logger.js\";\nimport type { SynthraPaths } from \"../shared/paths.js\";\nimport type { ServerContext } from \"./context.js\";\nimport { handleMcpRequest } from \"./mcp.js\";\nimport { findFreePort } from \"./port.js\";\nimport { handleActivity } from \"./routes/activity.js\";\nimport { handleContextUpdate } from \"./routes/context-update.js\";\nimport { handleGate } from \"./routes/gate.js\";\nimport { handleLog } from \"./routes/log.js\";\nimport { handlePack } from \"./routes/pack.js\";\nimport { handlePrime } from \"./routes/prime.js\";\n\nexport interface ServerHandle {\n port: number;\n url: string;\n stop(): Promise<void>;\n}\n\nexport interface StartOptions {\n /** Override the port range search. */\n port?: number;\n}\n\nasync function loadContext(paths: SynthraPaths): Promise<ServerContext> {\n try {\n let [graph, symbolIndex] = await Promise.all([\n readGraph(paths.infoGraph),\n readSymbolIndex(paths.symbolIndex),\n ]);\n // Schema-migration check (#8): a graph written by an older Synthra may have\n // an incompatible on-disk shape. On a version mismatch, auto-rescan once and\n // reload, rather than serving a stale/incompatible graph.\n if (graph.schema_version !== SCHEMA_VERSION) {\n log.info(`graph schema v${graph.schema_version} ≠ current v${SCHEMA_VERSION} — rescanning…`);\n await scanProject(paths.projectRoot, { silent: true });\n [graph, symbolIndex] = await Promise.all([\n readGraph(paths.infoGraph),\n readSymbolIndex(paths.symbolIndex),\n ]);\n }\n const activity = new ActivityStore(paths.activityLog);\n // Usage-learning runtime: loads the decayed aggregate (replaying the raw\n // access log if the aggregate is cold). Best-effort — never blocks startup.\n const learn = await LearnRuntime.load(paths.accessLog, paths.learnStore);\n return { paths, graph, symbolIndex, activity, learn };\n } catch (err) {\n throw new Error(\n `failed to load graph from ${paths.infoGraph}: ${(err as Error).message}. ` +\n `Run \\`syn scan\\` first.`,\n );\n }\n}\n\nfunction buildApp(ctx: ServerContext, port: number): Hono {\n const app = new Hono();\n\n app.get(\"/\", (c) =>\n c.json({\n service: \"synthra\",\n version: \"0.0.1\",\n port,\n file_count: ctx.graph.file_count,\n symbol_count: ctx.graph.symbol_count,\n generated_at: ctx.graph.generated_at,\n }),\n );\n\n app.get(\"/health\", (c) => c.json({ ok: true }));\n\n app.get(\"/prime\", async (c) => c.json(await handlePrime(ctx, port)));\n\n app.post(\"/pack\", async (c) => {\n const body = await c.req.json().catch(() => ({}));\n return c.json(await handlePack(body, ctx));\n });\n\n app.post(\"/log\", async (c) => {\n const body = await c.req.json().catch(() => ({}));\n return c.json(await handleLog(body, ctx));\n });\n\n app.post(\"/gate\", async (c) => {\n const body = await c.req.json().catch(() => ({}));\n return c.json(await handleGate(body, ctx));\n });\n\n app.get(\"/activity\", async (c) => {\n const sinceParam = c.req.query(\"since\");\n const sinceMs = sinceParam ? Number(sinceParam) : undefined;\n return c.json(await handleActivity(Number.isFinite(sinceMs) ? sinceMs : undefined, ctx));\n });\n\n app.post(\"/context-update\", async (c) => {\n const body = await c.req.json().catch(() => ({}));\n return c.json(await handleContextUpdate(body, ctx));\n });\n\n app.post(\"/mcp\", async (c) => {\n const body = await c.req.json().catch(() => null);\n return c.json(await handleMcpRequest(body, ctx));\n });\n\n app.onError((err, c) => {\n log.error(\"route error:\", err.message);\n return c.json({ error: err.message }, 400);\n });\n\n return app;\n}\n\nexport async function startServer(\n paths: SynthraPaths,\n options: StartOptions = {},\n): Promise<ServerHandle> {\n const ctx = await loadContext(paths);\n const port = options.port ?? (await findFreePort());\n\n const app = buildApp(ctx, port);\n const nodeServer = serve({ fetch: app.fetch, port, hostname: \"127.0.0.1\" });\n\n await writeFile(paths.mcpPort, String(port), \"utf8\");\n\n // Spin up the human-activity watchers. Both are best-effort — if chokidar\n // can't watch (e.g. unsupported FS) or .git is missing, they no-op silently.\n const fileWatcher: FileWatcher = createFileWatcher(paths.projectRoot, (e) => ctx.activity.add(e));\n const gitWatcher: GitWatcher = createGitWatcher(paths.projectRoot, async (e) => {\n await ctx.activity.add(e);\n // Per-branch graph: rebuild on branch switch so the in-memory graph\n // matches whichever branch is currently checked out.\n if (e.kind === \"branch-switch\") {\n try {\n const to = (e.details as { to?: string } | undefined)?.to ?? \"unknown\";\n log.info(`branch switched to '${to}' — rebuilding graph…`);\n await scanProject(paths.projectRoot, { silent: true });\n const [g, idx] = await Promise.all([\n readGraph(paths.infoGraph),\n readSymbolIndex(paths.symbolIndex),\n ]);\n ctx.graph = g;\n ctx.symbolIndex = idx;\n log.info(`graph rebuilt for '${to}' (${g.symbol_count} symbols).`);\n } catch (err) {\n log.warn(`branch rescan failed: ${(err as Error).message}`);\n }\n }\n });\n try {\n await fileWatcher.start();\n } catch (err) {\n log.warn(`file watcher failed to start: ${(err as Error).message}`);\n }\n try {\n await gitWatcher.start();\n } catch (err) {\n log.warn(`git watcher failed to start: ${(err as Error).message}`);\n }\n\n const url = `http://127.0.0.1:${port}`;\n\n return {\n port,\n url,\n async stop() {\n await fileWatcher.stop().catch(() => undefined);\n await gitWatcher.stop().catch(() => undefined);\n // Persist any pending usage signal before we go down.\n await ctx.learn?.flush().catch(() => undefined);\n await new Promise<void>((resolve, reject) => {\n nodeServer.close((err) => (err ? reject(err) : resolve()));\n });\n },\n };\n}\n","// Rolling JSONL log of human activity, written to .synthra-graph/activity.jsonl.\n// In-memory ring buffer for fast queries; disk append for durability.\n//\n// The buffer is bounded (defaults to 100 events) so we don't unbounded-grow\n// memory in long sessions. Disk gets every event so the dashboard / future\n// audit tooling can replay history.\n\nimport { appendFile, mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nexport interface FileEvent {\n kind: \"save\" | \"create\" | \"delete\";\n path: string;\n ts: string;\n}\n\nexport interface GitEvent {\n kind: \"branch-switch\" | \"stage\" | \"unstage\" | \"diff-change\";\n details: Record<string, unknown>;\n ts: string;\n}\n\nexport type ActivityEvent = FileEvent | GitEvent;\n\nconst DEFAULT_RING_SIZE = 100;\n\nexport class ActivityStore {\n private ring: ActivityEvent[] = [];\n private readonly maxRingSize: number;\n private readonly persistPath: string;\n\n constructor(persistPath: string, maxRingSize = DEFAULT_RING_SIZE) {\n this.persistPath = persistPath;\n this.maxRingSize = maxRingSize;\n }\n\n async add(event: ActivityEvent): Promise<void> {\n this.ring.push(event);\n while (this.ring.length > this.maxRingSize) this.ring.shift();\n await this.persist(event);\n }\n\n /** Get events newer than `sinceMs` (epoch ms). If omitted, returns the full ring. */\n getEvents(sinceMs?: number): ActivityEvent[] {\n if (!sinceMs || !Number.isFinite(sinceMs)) return this.ring.slice();\n const cutoff = new Date(sinceMs).toISOString();\n return this.ring.filter((e) => e.ts >= cutoff);\n }\n\n /** Project-relative file paths that have a save/create event newer than `maxAgeMs` ms ago. */\n recentFilePaths(maxAgeMs: number): string[] {\n const cutoff = new Date(Date.now() - maxAgeMs).toISOString();\n const out = new Set<string>();\n for (const e of this.ring) {\n if (\"path\" in e && (e.kind === \"save\" || e.kind === \"create\") && e.ts >= cutoff) {\n out.add(e.path);\n }\n }\n return Array.from(out);\n }\n\n size(): number {\n return this.ring.length;\n }\n\n private async persist(event: ActivityEvent): Promise<void> {\n try {\n await mkdir(dirname(this.persistPath), { recursive: true });\n await appendFile(this.persistPath, JSON.stringify(event) + \"\\n\", \"utf8\");\n } catch {\n // Durability is best-effort; an unwritable disk shouldn't crash the server.\n }\n }\n}\n","// chokidar-based file watcher. Emits save/create/delete events for human\n// edits inside the project. Respects .gitignore + .synthraignore plus a\n// hard-coded list of always-ignored directories (.git, .synthra*, .claude,\n// node_modules, dist, build, coverage).\n\nimport chokidar, { type FSWatcher } from \"chokidar\";\nimport { readFile } from \"node:fs/promises\";\nimport { join, relative, sep } from \"node:path\";\nimport ignore, { type Ignore } from \"ignore\";\n\nimport { log } from \"../shared/logger.js\";\nimport type { FileEvent } from \"./activity-log.js\";\n\nconst ALWAYS_IGNORE = [\n \".git\",\n \".synthra\",\n \".synthra-graph\",\n \".claude\",\n \"node_modules\",\n \"dist\",\n \"build\",\n \"out\",\n \"coverage\",\n \".next\",\n \".nuxt\",\n \".svelte-kit\",\n \".turbo\",\n \".cache\",\n \".vscode\",\n \".idea\",\n];\n\nexport interface FileWatcher {\n start(): Promise<void>;\n stop(): Promise<void>;\n}\n\nexport type FileEventHandler = (e: FileEvent) => void | Promise<void>;\n\nasync function readIgnoreFile(path: string): Promise<string[]> {\n try {\n const text = await readFile(path, \"utf8\");\n return text\n .split(/\\r?\\n/)\n .map((l) => l.trim())\n .filter((l) => l.length > 0 && !l.startsWith(\"#\"));\n } catch {\n return [];\n }\n}\n\nasync function buildMatcher(root: string): Promise<Ignore> {\n const ig = ignore();\n ig.add(ALWAYS_IGNORE.map((d) => `${d}/`));\n ig.add(await readIgnoreFile(join(root, \".gitignore\")));\n ig.add(await readIgnoreFile(join(root, \".synthraignore\")));\n return ig;\n}\n\nfunction toPosixRel(root: string, abs: string): string {\n const rel = relative(root, abs);\n return sep === \"/\" ? rel : rel.split(sep).join(\"/\");\n}\n\nexport function createFileWatcher(root: string, onEvent: FileEventHandler): FileWatcher {\n let watcher: FSWatcher | null = null;\n let ig: Ignore | null = null;\n\n const emit = async (kind: FileEvent[\"kind\"], abs: string) => {\n if (!ig) return;\n const rel = toPosixRel(root, abs);\n if (!rel || rel.startsWith(\"..\")) return;\n if (ig.ignores(rel)) return;\n try {\n await onEvent({ kind, path: rel, ts: new Date().toISOString() });\n } catch {\n // swallow handler errors — watcher must keep going\n }\n };\n\n return {\n async start() {\n ig = await buildMatcher(root);\n watcher = chokidar.watch(root, {\n // Cross-platform glob ignore. We match both the directory itself and\n // anything inside it. picomatch (chokidar's matcher) normalizes path\n // separators so a single set of forward-slash globs handles\n // Windows + POSIX. Function-based ignore was unreliable on Windows\n // and let chokidar descend into .git/, which crashed on transient\n // index.lock files held exclusively by git.\n ignored: ALWAYS_IGNORE.flatMap((d) => [`**/${d}`, `**/${d}/**`]),\n ignoreInitial: true,\n persistent: true,\n awaitWriteFinish: { stabilityThreshold: 150, pollInterval: 50 },\n });\n\n // Chokidar emits \"error\" for transient OS-level issues — most commonly\n // EPERM/ENOENT on rapidly created+deleted files. We never want one of\n // these to crash the syn process. Log + swallow.\n watcher.on(\"error\", (err) => {\n const e = err as NodeJS.ErrnoException;\n log.debug(`file watcher error (swallowed): ${e?.code ?? \"\"} ${e?.message ?? String(err)}`);\n });\n\n watcher.on(\"add\", (path) => emit(\"create\", path));\n watcher.on(\"change\", (path) => emit(\"save\", path));\n watcher.on(\"unlink\", (path) => emit(\"delete\", path));\n },\n\n async stop() {\n if (watcher) {\n await watcher.close();\n watcher = null;\n }\n },\n };\n}\n","// Watches `.git/HEAD` for branch switches (via fs.watch) and polls\n// `git status --porcelain` every ~2s to surface uncommitted-diff changes.\n// Always best-effort: in a non-git directory or when git is missing, the\n// watcher simply emits nothing.\n\nimport { execFile } from \"node:child_process\";\nimport { watch, type FSWatcher } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nimport type { GitEvent } from \"./activity-log.js\";\n\nconst execFileAsync = promisify(execFile);\n\nconst POLL_MS = 2000;\n\nexport interface GitWatcher {\n start(): Promise<void>;\n stop(): Promise<void>;\n}\n\nexport type GitEventHandler = (e: GitEvent) => void | Promise<void>;\n\nasync function readHeadBranch(projectRoot: string): Promise<string | null> {\n try {\n const head = await readFile(join(projectRoot, \".git\", \"HEAD\"), \"utf8\");\n const m = head.trim().match(/^ref:\\s+refs\\/heads\\/(.+)$/);\n return m?.[1] ?? null;\n } catch {\n return null;\n }\n}\n\nasync function readStatusPorcelain(projectRoot: string): Promise<string | null> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"status\", \"--porcelain\"], {\n cwd: projectRoot,\n });\n return stdout;\n } catch {\n return null;\n }\n}\n\nexport function createGitWatcher(root: string, onEvent: GitEventHandler): GitWatcher {\n let headWatcher: FSWatcher | null = null;\n let pollTimer: NodeJS.Timeout | null = null;\n let lastBranch: string | null = null;\n let lastStatus: string | null = null;\n\n const emitSafe = async (event: GitEvent) => {\n try {\n await onEvent(event);\n } catch {\n // swallow\n }\n };\n\n const checkHead = async () => {\n const branch = await readHeadBranch(root);\n if (branch && branch !== lastBranch) {\n const prev = lastBranch;\n lastBranch = branch;\n if (prev !== null) {\n await emitSafe({\n kind: \"branch-switch\",\n details: { from: prev, to: branch },\n ts: new Date().toISOString(),\n });\n }\n }\n };\n\n const pollStatus = async () => {\n const status = await readStatusPorcelain(root);\n if (status === null) return;\n if (lastStatus !== null && status !== lastStatus) {\n const prevFiles = parseStatusFiles(lastStatus);\n const nowFiles = parseStatusFiles(status);\n const added = nowFiles.filter((f) => !prevFiles.includes(f));\n const removed = prevFiles.filter((f) => !nowFiles.includes(f));\n await emitSafe({\n kind: \"diff-change\",\n details: {\n changed_count: nowFiles.length,\n newly_dirty: added,\n newly_clean: removed,\n },\n ts: new Date().toISOString(),\n });\n }\n lastStatus = status;\n };\n\n return {\n async start() {\n // Seed initial branch + status so the first real change emits an event\n // rather than a stale \"from null\".\n lastBranch = await readHeadBranch(root);\n lastStatus = await readStatusPorcelain(root);\n\n try {\n headWatcher = watch(join(root, \".git\", \"HEAD\"), () => {\n void checkHead();\n });\n // fs.watch emits \"error\" for transient OS issues (EPERM on lock\n // files, ENOENT when refs get rewritten). Swallow them — we never\n // want a transient FS event to crash the syn process.\n headWatcher.on(\"error\", () => {\n // silent — branch-switch detection is best-effort\n });\n } catch {\n // .git/HEAD not present — silently no-op\n }\n\n pollTimer = setInterval(() => {\n void pollStatus();\n }, POLL_MS);\n pollTimer.unref?.();\n },\n\n async stop() {\n if (headWatcher) {\n headWatcher.close();\n headWatcher = null;\n }\n if (pollTimer) {\n clearInterval(pollTimer);\n pollTimer = null;\n }\n },\n };\n}\n\nfunction parseStatusFiles(porcelain: string): string[] {\n return porcelain\n .split(/\\r?\\n/)\n .map((l) => l.slice(3).trim())\n .filter((l) => l.length > 0);\n}\n","// `syn scan [path]` — bootstrap then walk + parse + write graph.\n// Also invoked by the default `syn .` flow (M3 will chain start-claude after).\n\nimport { resolve } from \"node:path\";\n\nimport { buildGraph, buildSymbolIndex } from \"../scanner/extract.js\";\nimport { incrementalParse, readParseCache, writeParseCache } from \"../scanner/parse-cache.js\";\nimport { walk, type WalkedFile } from \"../scanner/walker.js\";\nimport { writeGraph, writeSymbolIndex } from \"../graph/store.js\";\nimport { log } from \"../shared/logger.js\";\nimport { resolvePaths } from \"../shared/paths.js\";\nimport { bootstrap } from \"./bootstrap.js\";\n\nconst PARSABLE_EXTS = new Set([\n \".ts\",\n \".tsx\",\n \".cts\",\n \".mts\",\n \".js\",\n \".jsx\",\n \".cjs\",\n \".mjs\",\n \".py\",\n \".pyi\",\n \".svelte\",\n \".vue\",\n \".go\",\n \".rs\",\n \".java\",\n \".kt\",\n \".kts\",\n \".php\",\n \".rb\",\n \".c\",\n \".h\",\n \".cpp\",\n \".cc\",\n \".cxx\",\n \".hpp\",\n \".hh\",\n \".hxx\",\n \".dart\",\n \".cs\",\n]);\n\nexport interface ScanResult {\n walked: number;\n parsed: number;\n symbolCount: number;\n edgeCount: number;\n durationMs: number;\n}\n\nexport interface ScanOptions {\n /** Suppress per-step log output (used for branch-switch rescans). */\n silent?: boolean;\n /** Ignore the parse cache and re-parse every file from scratch. */\n full?: boolean;\n}\n\n/**\n * Core scan pipeline — bootstrap + walk + parse + write graph. Importable\n * from anywhere (server, CLI, tests). `scanCommand` is just a logging wrapper\n * around this. Pass `silent: true` to skip the chatty progress output.\n */\nexport async function scanProject(\n projectRootRaw: string,\n opts: ScanOptions = {},\n): Promise<ScanResult> {\n const projectRoot = resolve(projectRootRaw);\n const paths = resolvePaths(projectRoot);\n const start = Date.now();\n const verbose = !opts.silent;\n\n if (verbose) log.info(`scanning ${projectRoot}`);\n\n const boot = await bootstrap(paths);\n if (verbose) {\n if (boot.graphCreated) log.info(\" created .synthra-graph/\");\n if (boot.contextCreated) log.info(\" created .synthra/\");\n if (boot.gitignoreUpdated) log.info(\" updated .gitignore\");\n if (boot.claudeMdCreated) {\n log.info(\" created CLAUDE.md — onboarding skeleton for the agent\");\n log.info(\n \" ↳ fill in Build / Conventions / Decisions (or run /init in Claude to auto-draft)\",\n );\n } else if (boot.claudeMdUpdated) {\n log.info(\" updated CLAUDE.md\");\n }\n }\n\n const walked: WalkedFile[] = [];\n for await (const file of walk(projectRoot)) walked.push(file);\n if (verbose) log.info(` walked ${walked.length} files`);\n\n const parsable = walked.filter((f) => PARSABLE_EXTS.has(f.ext));\n const prevCache = await readParseCache(paths.parseCache);\n const { parsed, cache, reused, reparsed, parseErrors } = await incrementalParse(\n parsable,\n prevCache,\n { full: opts.full },\n );\n if (verbose) {\n log.info(\n ` parsed ${parsed.length} files (${reused} reused · ${reparsed} reparsed` +\n (parseErrors ? `, ${parseErrors} errored` : \"\") +\n `; ${walked.length - parsable.length} non-code skipped)`,\n );\n }\n\n const graph = await buildGraph(projectRoot, parsed);\n const symbolIndex = buildSymbolIndex(graph);\n\n await writeGraph(paths.infoGraph, graph);\n await writeSymbolIndex(paths.symbolIndex, symbolIndex);\n await writeParseCache(paths.parseCache, cache);\n\n if (verbose) {\n log.info(\n ` wrote ${paths.infoGraph} — ${graph.symbol_count} symbols, ${graph.edge_count} edges`,\n );\n log.info(` wrote ${paths.symbolIndex} — ${Object.keys(symbolIndex).length} names`);\n }\n\n const durationMs = Date.now() - start;\n if (verbose) log.info(`done in ${(durationMs / 1000).toFixed(2)}s`);\n\n return {\n walked: walked.length,\n parsed: parsed.length,\n symbolCount: graph.symbol_count,\n edgeCount: graph.edge_count,\n durationMs,\n };\n}\n\n// Thin alias so the CLI command keeps its current name. Drop in v0.2 if we\n// settle on a single public function.\nexport async function scanCommand(rawPath: string, opts: ScanOptions = {}): Promise<ScanResult> {\n return scanProject(rawPath, opts);\n}\n","// Turns ParsedFile[] into a GraphSchema (nodes + edges).\n//\n// Edges produced in M1:\n// defines : file → symbol\n// imports : file → file (when the import target resolves inside the project)\n// tests : test-file → source-file (for foo.test.ts ↔ foo.ts)\n\nimport { dirname, join, posix } from \"node:path\";\n\nimport type { Edge, FileNode, GraphSchema, SymbolIndex, SymbolNode } from \"../graph/types.js\";\nimport { SCHEMA_VERSION } from \"../graph/types.js\";\nimport { fileHash } from \"./hash.js\";\nimport { extractKeywords } from \"./keywords.js\";\nimport type { CallSite, ParsedFile, ParsedSymbol } from \"./parser.js\";\n\nconst RESOLVE_EXTS = [\n \".ts\",\n \".tsx\",\n \".js\",\n \".jsx\",\n \".mjs\",\n \".cjs\",\n \".py\",\n \".svelte\",\n \".vue\",\n \".dart\",\n \".html\",\n \".hubl\",\n];\nconst INDEX_FILES = [\"index.ts\", \"index.tsx\", \"index.js\", \"index.jsx\", \"__init__.py\"];\n\nfunction fileId(relPath: string): string {\n return `file:${relPath}`;\n}\n\nfunction symbolId(relPath: string, sym: ParsedSymbol): string {\n return `symbol:${relPath}::${sym.name}:${sym.startLine}`;\n}\n\nfunction toFileNode(parsed: ParsedFile): FileNode {\n const content = parsed.source;\n return {\n id: fileId(parsed.file.relPath),\n kind: \"file\",\n path: parsed.file.relPath,\n ext: parsed.file.ext,\n size: parsed.file.size,\n keywords: extractKeywords(content, parsed.file.ext),\n content,\n summary: extractSummary(content),\n file_hash: fileHash(content),\n };\n}\n\nfunction extractSummary(content: string): string {\n // First leading comment block (// ... or /** ... */ or # ...), trimmed to ~200 chars.\n const trimmed = content.replace(/^\\s+/, \"\");\n const slashMatch = trimmed.match(/^\\/\\/\\s?(.*(?:\\r?\\n\\/\\/\\s?.*)*)/);\n if (slashMatch?.[1]) return slashMatch[1].split(/\\r?\\n/).join(\" \").trim().slice(0, 200);\n const blockMatch = trimmed.match(/^\\/\\*\\*?([\\s\\S]*?)\\*\\//);\n if (blockMatch?.[1]) {\n return blockMatch[1]\n .split(/\\r?\\n/)\n .map((l) => l.replace(/^\\s*\\*\\s?/, \"\"))\n .join(\" \")\n .trim()\n .slice(0, 200);\n }\n const hashMatch = trimmed.match(/^#\\s?(.*(?:\\r?\\n#\\s?.*)*)/);\n if (hashMatch?.[1]) return hashMatch[1].split(/\\r?\\n/).join(\" \").trim().slice(0, 200);\n return \"\";\n}\n\nfunction toSymbolNode(parsed: ParsedFile, sym: ParsedSymbol): SymbolNode {\n return {\n id: symbolId(parsed.file.relPath, sym),\n kind: \"symbol\",\n symbol_kind: sym.kind,\n name: sym.name,\n file: parsed.file.relPath,\n start_line: sym.startLine,\n end_line: sym.endLine,\n signature: sym.signature,\n };\n}\n\n/**\n * Resolve an import specifier to a project-relative path if it refers to a\n * file inside the project. Returns `null` for external packages (no leading\n * dot) or specifiers that don't match any known file.\n */\n// Strip a trailing JS-family extension so a spec like \"./crypto.js\" can\n// resolve to \"crypto.ts\". TypeScript-style `.js` imports are common.\nconst REWRITE_EXT_RE = /\\.(js|jsx|mjs|cjs)$/;\n\nfunction resolveImport(\n fromRelPath: string,\n spec: string,\n filesByPath: Map<string, true>,\n): string | null {\n if (!spec.startsWith(\".\")) return null;\n const fromDir = posix.dirname(toPosix(fromRelPath));\n const base = posix.normalize(posix.join(fromDir, toPosix(spec)));\n\n const candidates = [base];\n const rewritten = base.replace(REWRITE_EXT_RE, \"\");\n if (rewritten !== base) candidates.push(rewritten);\n\n for (const c of candidates) {\n if (filesByPath.has(c)) return c;\n for (const ext of RESOLVE_EXTS) {\n if (filesByPath.has(c + ext)) return c + ext;\n }\n for (const idx of INDEX_FILES) {\n const candidate = posix.join(c, idx);\n if (filesByPath.has(candidate)) return candidate;\n }\n }\n return null;\n}\n\nfunction toPosix(p: string): string {\n return p.split(/[\\\\/]/).join(\"/\");\n}\n\nconst TEST_RE = /^(?<base>.+?)\\.(test|spec)\\.(?<ext>[tj]sx?|py)$/;\n\nfunction testTarget(relPath: string, filesByPath: Map<string, true>): string | null {\n const fileName = relPath.split(\"/\").pop() ?? relPath;\n const match = TEST_RE.exec(fileName);\n if (!match) return null;\n const dir = relPath.includes(\"/\") ? relPath.slice(0, relPath.lastIndexOf(\"/\") + 1) : \"\";\n const base = match.groups?.base ?? \"\";\n const ext = match.groups?.ext ?? \"\";\n if (!base || !ext) return null;\n const candidate = `${dir}${base}.${ext}`;\n if (filesByPath.has(candidate)) return candidate;\n // Try sibling extensions (e.g. foo.test.ts → foo.tsx)\n for (const e of RESOLVE_EXTS) {\n const alt = `${dir}${base}${e}`;\n if (filesByPath.has(alt)) return alt;\n }\n return null;\n}\n\nexport async function buildGraph(root: string, parsed: ParsedFile[]): Promise<GraphSchema> {\n const filesByPath = new Map<string, true>();\n for (const p of parsed) filesByPath.set(p.file.relPath, true);\n\n const nodes: (FileNode | SymbolNode)[] = [];\n const edges: Edge[] = [];\n\n // Collected during the file loop, then resolved into `calls` edges in one pass\n // (callee resolution needs the full symbol set).\n const symbolsByFile = new Map<string, SymbolNode[]>();\n const callsByFile = new Map<string, CallSite[]>();\n\n for (const p of parsed) {\n const fileNode = toFileNode(p);\n nodes.push(fileNode);\n\n const fileSymNodes: SymbolNode[] = [];\n for (const sym of p.symbols) {\n const symNode = toSymbolNode(p, sym);\n nodes.push(symNode);\n fileSymNodes.push(symNode);\n edges.push({ from: fileNode.id, to: symNode.id, kind: \"defines\" });\n }\n symbolsByFile.set(p.file.relPath, fileSymNodes);\n callsByFile.set(p.file.relPath, p.calls);\n\n const importEdges = new Set<string>();\n for (const spec of p.imports) {\n const target = resolveImport(p.file.relPath, spec, filesByPath);\n if (!target) continue;\n const key = `${fileNode.id}->${fileId(target)}`;\n if (importEdges.has(key)) continue;\n importEdges.add(key);\n edges.push({ from: fileNode.id, to: fileId(target), kind: \"imports\" });\n }\n\n const testTargetPath = testTarget(p.file.relPath, filesByPath);\n if (testTargetPath && testTargetPath !== p.file.relPath) {\n edges.push({ from: fileNode.id, to: fileId(testTargetPath), kind: \"tests\" });\n }\n }\n\n edges.push(...buildCallEdges(symbolsByFile, callsByFile));\n\n const symbolCount = nodes.filter((n) => n.kind === \"symbol\").length;\n const fileCount = nodes.length - symbolCount;\n\n return {\n root,\n node_count: nodes.length,\n edge_count: edges.length,\n file_count: fileCount,\n symbol_count: symbolCount,\n nodes,\n edges,\n generated_at: new Date().toISOString(),\n schema_version: SCHEMA_VERSION,\n };\n}\n\nexport function buildSymbolIndex(graph: GraphSchema): SymbolIndex {\n // Null-prototype map: symbol names like \"toString\" or \"constructor\" (common\n // in Dart, where every class overrides toString) would otherwise resolve to\n // an inherited Object.prototype member and crash on the .push below.\n const out: SymbolIndex = Object.create(null);\n for (const node of graph.nodes) {\n if (node.kind !== \"symbol\") continue;\n const list = out[node.name] ?? (out[node.name] = []);\n list.push({ file: node.file, line: node.start_line, kind: node.symbol_kind });\n }\n return out;\n}\n\n/** The same-file symbol whose [start_line, end_line] tightest-contains `line`\n * (smallest span wins, so an inner method beats its enclosing class). null if\n * the line is outside every symbol (e.g. a module-level call). */\nexport function tightestContainer(syms: SymbolNode[], line: number): SymbolNode | null {\n let best: SymbolNode | null = null;\n for (const s of syms) {\n if (line < s.start_line || line > s.end_line) continue;\n if (!best || s.end_line - s.start_line < best.end_line - best.start_line) best = s;\n }\n return best;\n}\n\n/**\n * Resolve raw call sites into symbol→symbol `calls` edges. Name-based (no type\n * info), precision-first:\n * - caller = the call site's tightest-containing symbol in the SAME file\n * (no container, e.g. a top-level call → skipped)\n * - callee = a same-file symbol of that name, else the UNIQUE repo-wide symbol\n * of that name; 0 matches (external/builtin) or >1 (ambiguous) → skipped\n * Recursion self-edges and duplicates are dropped.\n */\nexport function buildCallEdges(\n symbolsByFile: Map<string, SymbolNode[]>,\n callsByFile: Map<string, CallSite[]>,\n): Edge[] {\n // Repo-wide name → symbols index, for the cross-file fallback.\n const byName = new Map<string, SymbolNode[]>();\n for (const syms of symbolsByFile.values()) {\n for (const s of syms) {\n const list = byName.get(s.name);\n if (list) list.push(s);\n else byName.set(s.name, [s]);\n }\n }\n\n const edges: Edge[] = [];\n const seen = new Set<string>();\n\n for (const [relPath, sites] of callsByFile) {\n const fileSyms = symbolsByFile.get(relPath) ?? [];\n for (const site of sites) {\n const caller = tightestContainer(fileSyms, site.line);\n if (!caller) continue;\n\n let callee = fileSyms.find((s) => s.name === site.callee);\n if (!callee) {\n const cands = byName.get(site.callee) ?? [];\n if (cands.length !== 1) continue; // 0 = external/builtin, >1 = ambiguous\n callee = cands[0];\n }\n if (!callee || callee.id === caller.id) continue; // skip recursion self-edges\n\n const key = `${caller.id}->${callee.id}`;\n if (seen.has(key)) continue;\n seen.add(key);\n edges.push({ from: caller.id, to: callee.id, kind: \"calls\" });\n }\n }\n return edges;\n}\n\n// Re-export node path helpers in case downstream wants the canonical id format\nexport { fileId, symbolId };\n// Suppress unused-import lint for dirname/join from node:path — kept reserved for incremental updates.\nvoid dirname;\nvoid join;\n","// Shared graph schema. Other modules read/write these shapes.\n\nexport type NodeKind = \"file\" | \"symbol\";\n\nexport type SymbolKind =\n | \"function\"\n | \"method\"\n | \"class\"\n | \"interface\"\n | \"type\"\n | \"const\"\n | \"enum\"\n | \"component\";\n\nexport interface FileNode {\n id: string;\n kind: \"file\";\n path: string;\n ext: string;\n size: number;\n keywords: string[];\n content: string;\n summary: string;\n file_hash: string;\n}\n\nexport interface SymbolNode {\n id: string;\n kind: \"symbol\";\n symbol_kind: SymbolKind;\n name: string;\n file: string;\n start_line: number;\n end_line: number;\n signature: string;\n}\n\nexport type GraphNode = FileNode | SymbolNode;\n\nexport type EdgeKind = \"imports\" | \"calls\" | \"defines\" | \"tests\";\n\nexport interface Edge {\n from: string;\n to: string;\n kind: EdgeKind;\n}\n\n// Bump when the on-disk info_graph.json shape changes incompatibly. The server\n// auto-rescans on load when a stored graph's schema_version differs (#8).\n// v2: `calls` edges are now populated.\nexport const SCHEMA_VERSION = 2;\n\nexport interface GraphSchema {\n root: string;\n node_count: number;\n edge_count: number;\n file_count: number;\n symbol_count: number;\n nodes: GraphNode[];\n edges: Edge[];\n generated_at: string;\n schema_version: number;\n}\n\nexport interface SymbolIndex {\n [name: string]: Array<{ file: string; line: number; kind: SymbolKind }>;\n}\n","// Stable, short content hash for files. Used to detect changed files\n// during incremental rescans (post-v0.1; M1 does full re-parse).\n// TODO: M1 (minimal); post-v0.1 (incremental)\n\nimport { createHash } from \"node:crypto\";\n\nexport function fileHash(content: string): string {\n return createHash(\"sha1\").update(content).digest(\"hex\").slice(0, 8);\n}\n","// Per-file keyword extraction. Used for query-time relevance ranking.\n// Tokenizes identifiers + comment words, splits camelCase/snake_case, filters\n// stopwords, and returns the top-N rare tokens scored by inverse frequency\n// against a small built-in english/code corpus.\n\nconst STOPWORDS = new Set([\n \"a\",\n \"an\",\n \"and\",\n \"are\",\n \"as\",\n \"at\",\n \"be\",\n \"but\",\n \"by\",\n \"do\",\n \"for\",\n \"from\",\n \"has\",\n \"have\",\n \"he\",\n \"if\",\n \"in\",\n \"is\",\n \"it\",\n \"its\",\n \"not\",\n \"of\",\n \"on\",\n \"or\",\n \"she\",\n \"that\",\n \"the\",\n \"they\",\n \"this\",\n \"to\",\n \"was\",\n \"we\",\n \"were\",\n \"will\",\n \"with\",\n \"you\",\n \"your\",\n \"i\",\n \"me\",\n \"my\",\n \"our\",\n \"us\",\n \"their\",\n \"them\",\n \"his\",\n \"her\",\n // common code words that add no signal\n \"function\",\n \"const\",\n \"let\",\n \"var\",\n \"class\",\n \"interface\",\n \"type\",\n \"enum\",\n \"import\",\n \"export\",\n \"from\",\n \"default\",\n \"return\",\n \"if\",\n \"else\",\n \"for\",\n \"while\",\n \"do\",\n \"switch\",\n \"case\",\n \"break\",\n \"continue\",\n \"new\",\n \"this\",\n \"super\",\n \"throw\",\n \"try\",\n \"catch\",\n \"finally\",\n \"async\",\n \"await\",\n \"yield\",\n \"true\",\n \"false\",\n \"null\",\n \"undefined\",\n \"void\",\n \"any\",\n \"string\",\n \"number\",\n \"boolean\",\n \"object\",\n \"array\",\n \"self\",\n \"cls\",\n \"def\",\n \"lambda\",\n \"pass\",\n \"raise\",\n \"with\",\n \"as\",\n \"in\",\n \"todo\",\n \"fixme\",\n \"note\",\n]);\n\nconst COMMON_CODE = new Set([\n \"value\",\n \"data\",\n \"result\",\n \"args\",\n \"kwargs\",\n \"options\",\n \"config\",\n \"params\",\n \"name\",\n \"id\",\n \"key\",\n \"index\",\n \"item\",\n \"items\",\n \"list\",\n \"map\",\n \"set\",\n \"get\",\n \"set\",\n \"add\",\n \"remove\",\n \"delete\",\n \"create\",\n \"update\",\n \"find\",\n \"fetch\",\n \"load\",\n \"save\",\n \"init\",\n \"main\",\n \"run\",\n \"start\",\n \"stop\",\n \"test\",\n \"check\",\n \"validate\",\n \"error\",\n \"err\",\n \"warn\",\n \"info\",\n \"debug\",\n \"log\",\n \"trace\",\n \"msg\",\n \"message\",\n \"path\",\n \"file\",\n \"dir\",\n \"url\",\n \"host\",\n \"port\",\n \"size\",\n \"length\",\n \"count\",\n \"input\",\n \"output\",\n \"source\",\n \"target\",\n \"callback\",\n \"handler\",\n \"listener\",\n \"props\",\n \"state\",\n \"context\",\n \"render\",\n \"component\",\n \"node\",\n \"tree\",\n \"root\",\n]);\n\n// Frequency weight — common-code words count for less than rare identifiers\nfunction score(token: string): number {\n if (STOPWORDS.has(token)) return 0;\n if (COMMON_CODE.has(token)) return 0.2;\n if (token.length <= 2) return 0.1;\n return 1;\n}\n\nfunction splitIdentifier(id: string): string[] {\n // snake_case + kebab-case → words\n const partsRaw = id.split(/[_\\-./]+/).filter(Boolean);\n const out: string[] = [];\n for (const part of partsRaw) {\n // camelCase / PascalCase → words. Handles \"XMLHttp\" → [\"XML\", \"Http\"]\n const camelParts = part.match(/[A-Z]+(?=[A-Z][a-z])|[A-Z]?[a-z]+|[A-Z]+|[0-9]+/g);\n if (camelParts) out.push(...camelParts);\n else out.push(part);\n }\n return out.map((w) => w.toLowerCase()).filter((w) => /[a-z]/.test(w));\n}\n\nexport function extractKeywords(content: string, _ext: string): string[] {\n // Identifiers + alphanumeric words. Picks up both code and comment text.\n const tokens = content.match(/[A-Za-z_][A-Za-z0-9_]{1,40}/g) ?? [];\n const counts = new Map<string, number>();\n for (const tok of tokens) {\n for (const word of splitIdentifier(tok)) {\n const w = score(word);\n if (w === 0) continue;\n counts.set(word, (counts.get(word) ?? 0) + w);\n }\n }\n return Array.from(counts.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 32)\n .map(([w]) => w);\n}\n","// Incremental-scan parse cache. Stores per-file parse results keyed by content\n// hash so a rescan can reuse unchanged files' symbols/imports and only re-run\n// the expensive tree-sitter parse on files that actually changed.\n//\n// Source is NOT stored here — it's re-read at scan time to compute the hash and\n// reused as ParsedFile.source, keeping the cache small (the graph holds content\n// separately). Lives in .synthra-graph/ (gitignored, machine-local).\n//\n// BUMP PARSE_CACHE_VERSION whenever parser/extract output shape or a tree-sitter\n// grammar changes — readParseCache returns an empty cache on a version mismatch,\n// forcing a full re-parse so stale symbols can never leak into the graph.\n\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { fileHash } from \"./hash.js\";\nimport { parseSource, type CallSite, type ParsedFile, type ParsedSymbol } from \"./parser.js\";\nimport type { WalkedFile } from \"./walker.js\";\n\n// Bumped to 2 when call sites were added to the parse output (the calls shape\n// changed) — old caches invalidate and re-parse cleanly.\nexport const PARSE_CACHE_VERSION = 2;\n\nexport interface CachedParse {\n hash: string;\n symbols: ParsedSymbol[];\n imports: string[];\n calls: CallSite[];\n}\n\nexport interface ParseCache {\n schema_version: number;\n files: Record<string, CachedParse>;\n}\n\nexport function emptyParseCache(): ParseCache {\n return { schema_version: PARSE_CACHE_VERSION, files: {} };\n}\n\nexport async function readParseCache(path: string): Promise<ParseCache> {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<ParseCache>;\n if (\n parsed.schema_version !== PARSE_CACHE_VERSION ||\n typeof parsed.files !== \"object\" ||\n parsed.files === null\n ) {\n return emptyParseCache();\n }\n return { schema_version: PARSE_CACHE_VERSION, files: parsed.files as ParseCache[\"files\"] };\n } catch {\n return emptyParseCache();\n }\n}\n\nexport async function writeParseCache(path: string, cache: ParseCache): Promise<void> {\n try {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify(cache)}\\n`, \"utf8\");\n } catch {\n // Best-effort: a missing/unwritable cache just means the next scan is full.\n }\n}\n\nexport interface IncrementalParseResult {\n parsed: ParsedFile[];\n cache: ParseCache;\n reused: number;\n reparsed: number;\n parseErrors: number;\n}\n\n/**\n * Parse `parsable` files, reusing prior results for files whose content hash is\n * unchanged. Returns the FULL ParsedFile[] (reused + freshly parsed) — so\n * `buildGraph` re-resolves every cross-file edge exactly as in a full scan —\n * plus a rebuilt cache containing only the currently-present files (deletions\n * and renames drop out naturally). Pass `full: true` to ignore the cache and\n * re-parse everything.\n */\nexport async function incrementalParse(\n parsable: WalkedFile[],\n prev: ParseCache,\n opts: { full?: boolean } = {},\n): Promise<IncrementalParseResult> {\n const cache = emptyParseCache();\n const parsed: ParsedFile[] = [];\n let reused = 0;\n let reparsed = 0;\n let parseErrors = 0;\n\n for (const f of parsable) {\n let source: string;\n try {\n source = await readFile(f.absPath, \"utf8\");\n } catch {\n continue; // unreadable → skip, same as a failed read in parseFile\n }\n const hash = fileHash(source);\n\n const cached = opts.full ? undefined : prev.files[f.relPath];\n if (cached && cached.hash === hash) {\n parsed.push({\n file: f,\n source,\n symbols: cached.symbols,\n imports: cached.imports,\n calls: cached.calls,\n });\n cache.files[f.relPath] = cached;\n reused += 1;\n continue;\n }\n\n try {\n const p = await parseSource(f, source);\n parsed.push(p);\n cache.files[f.relPath] = { hash, symbols: p.symbols, imports: p.imports, calls: p.calls };\n reparsed += 1;\n } catch {\n // Mirror scanProject's prior behavior: a parse failure drops the file\n // from the graph (and the cache) rather than failing the whole scan.\n parseErrors += 1;\n }\n }\n\n return { parsed, cache, reused, reparsed, parseErrors };\n}\n","// Dispatches a file to its language-specific parser based on extension.\n// Tree-sitter WASM grammars are loaded lazily via tree-sitter-wasms and\n// cached per language for the lifetime of the process.\n\nimport { readFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { Language, Parser } from \"web-tree-sitter\";\n\nimport type { SymbolKind } from \"../graph/types.js\";\nimport { parseC } from \"./parsers/c.js\";\nimport { parseCpp } from \"./parsers/cpp.js\";\nimport { parseCSharp } from \"./parsers/csharp.js\";\nimport { parseDart } from \"./parsers/dart.js\";\nimport { parseGo } from \"./parsers/go.js\";\nimport { parseHubL } from \"./parsers/hubl.js\";\nimport { parseJava } from \"./parsers/java.js\";\nimport { parseKotlin } from \"./parsers/kotlin.js\";\nimport { parsePhp } from \"./parsers/php.js\";\nimport { parsePython } from \"./parsers/python.js\";\nimport { parseRuby } from \"./parsers/ruby.js\";\nimport { parseRust } from \"./parsers/rust.js\";\nimport { parseSvelte } from \"./parsers/svelte.js\";\nimport { parseTypeScript } from \"./parsers/typescript.js\";\nimport { parseVue } from \"./parsers/vue.js\";\nimport type { WalkedFile } from \"./walker.js\";\n\nexport interface ParsedSymbol {\n name: string;\n kind: SymbolKind;\n startLine: number;\n endLine: number;\n signature: string;\n}\n\n/** A raw call site: the bare callee name as written (e.g. \"login\", not\n * \"auth.login\") + its 1-based line. Caller attribution + callee resolution\n * happen centrally in buildGraph (which has the full file set). */\nexport interface CallSite {\n callee: string;\n line: number;\n}\n\nexport interface ParsedFile {\n file: WalkedFile;\n source: string;\n symbols: ParsedSymbol[];\n imports: string[];\n calls: CallSite[];\n}\n\nconst require = createRequire(import.meta.url);\n\nexport type GrammarName =\n | \"typescript\"\n | \"tsx\"\n | \"javascript\"\n | \"python\"\n | \"go\"\n | \"rust\"\n | \"java\"\n | \"kotlin\"\n | \"php\"\n | \"ruby\"\n | \"c\"\n | \"cpp\"\n | \"dart\"\n | \"csharp\";\n\nconst GRAMMAR_FILES: Record<GrammarName, string> = {\n typescript: \"tree-sitter-wasms/out/tree-sitter-typescript.wasm\",\n tsx: \"tree-sitter-wasms/out/tree-sitter-tsx.wasm\",\n javascript: \"tree-sitter-wasms/out/tree-sitter-javascript.wasm\",\n python: \"tree-sitter-wasms/out/tree-sitter-python.wasm\",\n go: \"tree-sitter-wasms/out/tree-sitter-go.wasm\",\n rust: \"tree-sitter-wasms/out/tree-sitter-rust.wasm\",\n java: \"tree-sitter-wasms/out/tree-sitter-java.wasm\",\n kotlin: \"tree-sitter-wasms/out/tree-sitter-kotlin.wasm\",\n php: \"tree-sitter-wasms/out/tree-sitter-php.wasm\",\n ruby: \"tree-sitter-wasms/out/tree-sitter-ruby.wasm\",\n c: \"tree-sitter-wasms/out/tree-sitter-c.wasm\",\n cpp: \"tree-sitter-wasms/out/tree-sitter-cpp.wasm\",\n dart: \"tree-sitter-wasms/out/tree-sitter-dart.wasm\",\n csharp: \"tree-sitter-wasms/out/tree-sitter-c_sharp.wasm\",\n};\n\nlet parserInit: Promise<void> | null = null;\nconst languageCache = new Map<GrammarName, Language>();\n\nasync function ensureParserInit(): Promise<void> {\n if (!parserInit) {\n parserInit = Parser.init();\n }\n return parserInit;\n}\n\nexport async function loadGrammar(name: GrammarName): Promise<Language> {\n await ensureParserInit();\n const cached = languageCache.get(name);\n if (cached) return cached;\n const wasmPath = require.resolve(GRAMMAR_FILES[name]);\n const lang = await Language.load(wasmPath);\n languageCache.set(name, lang);\n return lang;\n}\n\nexport interface LoadedParser {\n parser: Parser;\n language: Language;\n}\n\nexport async function createParser(name: GrammarName): Promise<LoadedParser> {\n const language = await loadGrammar(name);\n const parser = new Parser();\n parser.setLanguage(language);\n return { parser, language };\n}\n\nfunction emptyParsed(file: WalkedFile, source: string): ParsedFile {\n return { file, source, symbols: [], imports: [], calls: [] };\n}\n\nexport async function parseFile(f: WalkedFile): Promise<ParsedFile> {\n let source: string;\n try {\n source = await readFile(f.absPath, \"utf8\");\n } catch {\n return emptyParsed(f, \"\");\n }\n return parseSource(f, source);\n}\n\n/** Parse already-read source. Split from parseFile so the incremental scanner\n * can read a file's content once (to hash it) and parse from that same string\n * on a cache miss — avoiding a second read. */\nexport async function parseSource(f: WalkedFile, source: string): Promise<ParsedFile> {\n switch (f.ext) {\n case \".ts\":\n case \".tsx\":\n case \".cts\":\n case \".mts\":\n case \".js\":\n case \".jsx\":\n case \".cjs\":\n case \".mjs\":\n return parseTypeScript(f, source);\n case \".py\":\n case \".pyi\":\n return parsePython(f, source);\n case \".svelte\":\n return parseSvelte(f, source);\n case \".vue\":\n return parseVue(f, source);\n case \".html\":\n case \".hubl\":\n return parseHubL(f, source);\n case \".go\":\n return parseGo(f, source);\n case \".rs\":\n return parseRust(f, source);\n case \".java\":\n return parseJava(f, source);\n case \".kt\":\n case \".kts\":\n return parseKotlin(f, source);\n case \".php\":\n return parsePhp(f, source);\n case \".rb\":\n return parseRuby(f, source);\n case \".c\":\n case \".h\":\n return parseC(f, source);\n case \".cpp\":\n case \".cc\":\n case \".cxx\":\n case \".hpp\":\n case \".hh\":\n case \".hxx\":\n return parseCpp(f, source);\n case \".dart\":\n return parseDart(f, source);\n case \".cs\":\n return parseCSharp(f, source);\n default:\n return emptyParsed(f, source);\n }\n}\n","// Generic tree-sitter parser used by the simpler-grammar languages\n// (Go, Rust, Java, Kotlin, PHP, Ruby, C, C++, Dart, C#).\n//\n// Each language file defines:\n// - which tree-sitter grammar to load\n// - a query string with capture names like `@function`, `@function.name`\n// - a `decls` table mapping declaration-capture pairs to SymbolKind\n// - optional `importCapture` for collecting import edges\n// Everything else (parser init, error handling, dedupe) lives here.\n\nimport { Query, type Node } from \"web-tree-sitter\";\n\nimport type { SymbolKind } from \"../../graph/types.js\";\nimport {\n createParser,\n type CallSite,\n type GrammarName,\n type ParsedFile,\n type ParsedSymbol,\n} from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\n\nexport interface DeclCapture {\n /** Capture name for the declaration node, e.g. \"function\". */\n declCapture: string;\n /** Capture name for the symbol's name node, e.g. \"function.name\". */\n nameCapture: string;\n /** SymbolKind to assign. */\n kind: SymbolKind;\n}\n\nexport interface GenericParserConfig {\n grammar: GrammarName;\n query: string;\n decls: DeclCapture[];\n /** Capture name for import-source nodes. Skipped when omitted. */\n importCapture?: string;\n /** Capture name for the whole call-site node (for its line). */\n callCapture?: string;\n /** Capture name for the callee-name node. Both call captures must be set. */\n callCalleeCapture?: string;\n}\n\nexport function firstLine(text: string, max = 200): string {\n const line = text.split(/\\r?\\n/, 1)[0] ?? \"\";\n return line.length > max ? line.slice(0, max) + \"…\" : line;\n}\n\nfunction cleanImport(s: string): string {\n // Strip surrounding string-literal quotes (used by Go, Dart, C/C++).\n // Strip angle brackets used by C/C++ system includes.\n return s.replace(/^[\"'`<]+|[\"'`>]+$/g, \"\").trim();\n}\n\nexport async function runGenericParser(\n config: GenericParserConfig,\n f: WalkedFile,\n source: string,\n): Promise<ParsedFile> {\n let symbols: ParsedSymbol[] = [];\n let imports: string[] = [];\n const calls: CallSite[] = [];\n\n try {\n const { parser, language } = await createParser(config.grammar);\n const tree = parser.parse(source);\n if (!tree) return { file: f, source, symbols, imports, calls };\n\n const query = new Query(language, config.query);\n const matches = query.matches(tree.rootNode);\n\n for (const match of matches) {\n const byName = new Map<string, Node>();\n for (const cap of match.captures) byName.set(cap.name, cap.node);\n\n let matched: DeclCapture | null = null;\n for (const d of config.decls) {\n if (byName.has(d.declCapture) && byName.has(d.nameCapture)) {\n matched = d;\n break;\n }\n }\n\n if (matched) {\n const declNode = byName.get(matched.declCapture)!;\n const nameNode = byName.get(matched.nameCapture)!;\n symbols.push({\n name: nameNode.text,\n kind: matched.kind,\n startLine: declNode.startPosition.row + 1,\n endLine: declNode.endPosition.row + 1,\n signature: firstLine(declNode.text),\n });\n continue;\n }\n\n if (config.callCapture && config.callCalleeCapture) {\n const callNode = byName.get(config.callCapture);\n const calleeNode = byName.get(config.callCalleeCapture);\n if (callNode && calleeNode) {\n calls.push({ callee: calleeNode.text, line: callNode.startPosition.row + 1 });\n continue;\n }\n }\n\n if (config.importCapture) {\n const imp = byName.get(config.importCapture);\n if (imp) imports.push(cleanImport(imp.text));\n }\n }\n\n const seen = new Set<string>();\n symbols = symbols.filter((s) => {\n const k = `${s.name}:${s.startLine}`;\n if (seen.has(k)) return false;\n seen.add(k);\n return true;\n });\n imports = Array.from(new Set(imports)).filter((s) => s.length > 0);\n } catch {\n // Query compile or parse failure — return what we have. Silent so a single\n // bad file doesn't abort the whole scan.\n }\n\n return { file: f, source, symbols, imports, calls };\n}\n","// C parser. Function definitions, structs, enums, typedefs, #include directives.\n\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\nimport { runGenericParser } from \"./_generic.js\";\n\nconst QUERY = `\n(function_definition declarator: (function_declarator declarator: (identifier) @function.name)) @function\n(struct_specifier name: (type_identifier) @struct.name) @struct\n(enum_specifier name: (type_identifier) @enum.name) @enum\n(type_definition declarator: (type_identifier) @type.name) @type\n(preproc_include path: (string_literal) @import)\n(preproc_include path: (system_lib_string) @import)\n(call_expression function: (identifier) @call.name) @call\n`;\n\nexport async function parseC(f: WalkedFile, source: string): Promise<ParsedFile> {\n return runGenericParser(\n {\n grammar: \"c\",\n query: QUERY,\n decls: [\n { declCapture: \"function\", nameCapture: \"function.name\", kind: \"function\" },\n { declCapture: \"struct\", nameCapture: \"struct.name\", kind: \"class\" },\n { declCapture: \"enum\", nameCapture: \"enum.name\", kind: \"enum\" },\n { declCapture: \"type\", nameCapture: \"type.name\", kind: \"type\" },\n ],\n importCapture: \"import\",\n callCapture: \"call\",\n callCalleeCapture: \"call.name\",\n },\n f,\n source,\n );\n}\n","// C++ parser. Functions, classes, structs, enums, namespaces, #includes.\n\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\nimport { runGenericParser } from \"./_generic.js\";\n\nconst QUERY = `\n(function_definition declarator: (function_declarator declarator: (identifier) @function.name)) @function\n(function_definition declarator: (function_declarator declarator: (qualified_identifier) @method.name)) @method\n(class_specifier name: (type_identifier) @class.name) @class\n(struct_specifier name: (type_identifier) @struct.name) @struct\n(enum_specifier name: (type_identifier) @enum.name) @enum\n(namespace_definition name: (namespace_identifier) @namespace.name) @namespace\n(preproc_include path: (string_literal) @import)\n(preproc_include path: (system_lib_string) @import)\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (field_expression field: (field_identifier) @call.name)) @call\n(call_expression function: (qualified_identifier name: (identifier) @call.name)) @call\n`;\n\nexport async function parseCpp(f: WalkedFile, source: string): Promise<ParsedFile> {\n return runGenericParser(\n {\n grammar: \"cpp\",\n query: QUERY,\n decls: [\n { declCapture: \"function\", nameCapture: \"function.name\", kind: \"function\" },\n { declCapture: \"method\", nameCapture: \"method.name\", kind: \"method\" },\n { declCapture: \"class\", nameCapture: \"class.name\", kind: \"class\" },\n { declCapture: \"struct\", nameCapture: \"struct.name\", kind: \"class\" },\n { declCapture: \"enum\", nameCapture: \"enum.name\", kind: \"enum\" },\n { declCapture: \"namespace\", nameCapture: \"namespace.name\", kind: \"class\" },\n ],\n importCapture: \"import\",\n callCapture: \"call\",\n callCalleeCapture: \"call.name\",\n },\n f,\n source,\n );\n}\n","// C# (.NET) parser. Classes, interfaces, structs, methods, namespaces.\n\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\nimport { runGenericParser } from \"./_generic.js\";\n\nconst QUERY = `\n(class_declaration name: (identifier) @class.name) @class\n(interface_declaration name: (identifier) @interface.name) @interface\n(struct_declaration name: (identifier) @struct.name) @struct\n(enum_declaration name: (identifier) @enum.name) @enum\n(method_declaration name: (identifier) @method.name) @method\n(namespace_declaration name: (_) @namespace.name) @namespace\n(using_directive (_) @import)\n(invocation_expression function: (identifier) @call.name) @call\n(invocation_expression function: (member_access_expression name: (identifier) @call.name)) @call\n`;\n\nexport async function parseCSharp(f: WalkedFile, source: string): Promise<ParsedFile> {\n return runGenericParser(\n {\n grammar: \"csharp\",\n query: QUERY,\n decls: [\n { declCapture: \"class\", nameCapture: \"class.name\", kind: \"class\" },\n { declCapture: \"interface\", nameCapture: \"interface.name\", kind: \"interface\" },\n { declCapture: \"struct\", nameCapture: \"struct.name\", kind: \"class\" },\n { declCapture: \"enum\", nameCapture: \"enum.name\", kind: \"enum\" },\n { declCapture: \"method\", nameCapture: \"method.name\", kind: \"method\" },\n { declCapture: \"namespace\", nameCapture: \"namespace.name\", kind: \"class\" },\n ],\n importCapture: \"import\",\n callCapture: \"call\",\n callCalleeCapture: \"call.name\",\n },\n f,\n source,\n );\n}\n","// Dart parser. v0.1.11 — real symbol extraction + import parsing on top of the\n// ABI-v15 grammar that ships in tree-sitter-wasms.\n//\n// Distinguishes top-level function_signature (kind: function) from\n// function_signature nested under method_signature (kind: method) by\n// anchoring the top-level pattern under `program`.\n//\n// Imports: `package:foo/bar.dart` and `dart:async` are stripped — they cross\n// the project boundary. Bare `foo.dart` is normalized to `./foo.dart` so the\n// shared resolveImport() (which requires a leading `.`) treats it as a\n// same-directory relative import.\n\nimport { Query, type Node } from \"web-tree-sitter\";\nimport type { SymbolKind } from \"../../graph/types.js\";\nimport { createParser, type ParsedFile, type ParsedSymbol } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\n\nconst QUERY = `\n(class_definition name: (identifier) @class.name) @class\n(mixin_declaration (identifier) @mixin.name) @mixin\n(extension_declaration name: (identifier) @ext.name) @ext\n(enum_declaration name: (identifier) @enum.name) @enum\n(type_alias (type_identifier) @typedef.name) @typedef\n\n(program (function_signature name: (identifier) @function.name) @function)\n\n(method_signature (function_signature name: (identifier) @method.name)) @method\n(method_signature (getter_signature name: (identifier) @getter.name)) @getter\n(method_signature (setter_signature name: (identifier) @setter.name)) @setter\n(constructor_signature name: (identifier) @ctor.name) @ctor\n\n(import_or_export (library_import (import_specification (configurable_uri (uri (string_literal) @import)))))\n`;\n\ninterface DeclShape {\n declCap: string;\n nameCap: string;\n kind: SymbolKind;\n}\n\nconst DECLS: DeclShape[] = [\n { declCap: \"class\", nameCap: \"class.name\", kind: \"class\" },\n { declCap: \"mixin\", nameCap: \"mixin.name\", kind: \"class\" },\n { declCap: \"ext\", nameCap: \"ext.name\", kind: \"class\" },\n { declCap: \"enum\", nameCap: \"enum.name\", kind: \"enum\" },\n { declCap: \"typedef\", nameCap: \"typedef.name\", kind: \"type\" },\n { declCap: \"function\", nameCap: \"function.name\", kind: \"function\" },\n { declCap: \"method\", nameCap: \"method.name\", kind: \"method\" },\n { declCap: \"getter\", nameCap: \"getter.name\", kind: \"method\" },\n { declCap: \"setter\", nameCap: \"setter.name\", kind: \"method\" },\n { declCap: \"ctor\", nameCap: \"ctor.name\", kind: \"method\" },\n];\n\nfunction firstLine(text: string, max = 200): string {\n const line = text.split(/\\r?\\n/, 1)[0] ?? \"\";\n return line.length > max ? line.slice(0, max) + \"…\" : line;\n}\n\n// Strip surrounding string-literal quotes and normalize bare same-directory\n// imports (Dart allows `import 'foo.dart';` without a leading `./`) so\n// resolveImport() — which keys off a leading dot — can match them.\nfunction normalizeDartImport(raw: string): string | null {\n const stripped = raw.replace(/^['\"]|['\"]$/g, \"\");\n if (!stripped) return null;\n if (stripped.startsWith(\"package:\")) return null;\n if (stripped.startsWith(\"dart:\")) return null;\n if (stripped.startsWith(\".\") || stripped.startsWith(\"/\")) return stripped;\n return `./${stripped}`;\n}\n\nexport async function parseDart(f: WalkedFile, source: string): Promise<ParsedFile> {\n let symbols: ParsedSymbol[] = [];\n let imports: string[] = [];\n\n try {\n const { parser, language } = await createParser(\"dart\");\n const tree = parser.parse(source);\n if (!tree) return { file: f, source, symbols, imports, calls: [] };\n\n const query = new Query(language, QUERY);\n const matches = query.matches(tree.rootNode);\n\n for (const match of matches) {\n const byName = new Map<string, Node>();\n for (const cap of match.captures) byName.set(cap.name, cap.node);\n\n let matched: DeclShape | null = null;\n for (const d of DECLS) {\n if (byName.has(d.declCap) && byName.has(d.nameCap)) {\n matched = d;\n break;\n }\n }\n\n if (matched) {\n const declNode = byName.get(matched.declCap)!;\n const nameNode = byName.get(matched.nameCap)!;\n symbols.push({\n name: nameNode.text,\n kind: matched.kind,\n startLine: declNode.startPosition.row + 1,\n endLine: declNode.endPosition.row + 1,\n signature: firstLine(declNode.text),\n });\n continue;\n }\n\n const importNode = byName.get(\"import\");\n if (importNode) {\n const norm = normalizeDartImport(importNode.text);\n if (norm) imports.push(norm);\n }\n }\n\n const seen = new Set<string>();\n symbols = symbols.filter((s) => {\n const k = `${s.name}:${s.startLine}`;\n if (seen.has(k)) return false;\n seen.add(k);\n return true;\n });\n imports = Array.from(new Set(imports));\n } catch {\n // swallow — see _generic.ts for the rationale (single bad file shouldn't\n // abort the whole scan).\n }\n\n return { file: f, source, symbols, imports, calls: [] };\n}\n","// Go parser. Functions, methods, type declarations, imports.\n\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\nimport { runGenericParser } from \"./_generic.js\";\n\nconst QUERY = `\n(function_declaration name: (identifier) @function.name) @function\n(method_declaration name: (field_identifier) @method.name) @method\n(type_spec name: (type_identifier) @type.name) @type\n(import_spec path: (interpreted_string_literal) @import)\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (selector_expression field: (field_identifier) @call.name)) @call\n`;\n\nexport async function parseGo(f: WalkedFile, source: string): Promise<ParsedFile> {\n return runGenericParser(\n {\n grammar: \"go\",\n query: QUERY,\n decls: [\n { declCapture: \"function\", nameCapture: \"function.name\", kind: \"function\" },\n { declCapture: \"method\", nameCapture: \"method.name\", kind: \"method\" },\n { declCapture: \"type\", nameCapture: \"type.name\", kind: \"type\" },\n ],\n importCapture: \"import\",\n callCapture: \"call\",\n callCalleeCapture: \"call.name\",\n },\n f,\n source,\n );\n}\n","// HubL (HubSpot CMS templating) parser. HubL lives in .html / .hubl files and\n// has no tree-sitter grammar, so we extract its symbol-like constructs with\n// regex: `{% macro %}` and `{% block %}` become symbols, and\n// `{% include / extends / import / from \"path\" %}` become import edges.\n// Plain HTML with no HubL tags simply yields no symbols (same as before).\n\nimport type { ParsedFile, ParsedSymbol } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\n\n// `{%-` / `-%}` are HubL/Jinja whitespace-control variants — tolerate them.\nconst MACRO_RE = /\\{%-?\\s*macro\\s+([A-Za-z_]\\w*)\\s*\\(([^)]*)\\)/g;\nconst ENDMACRO_RE = /\\{%-?\\s*endmacro\\b/g;\nconst BLOCK_RE = /\\{%-?\\s*block\\s+([A-Za-z_]\\w*)/g;\nconst ENDBLOCK_RE = /\\{%-?\\s*endblock\\b/g;\n// include / extends / import / from — all take a quoted template path first.\nconst IMPORT_RE = /\\{%-?\\s*(?:include|extends|import|from)\\s+[\"']([^\"']+)[\"']/g;\n\nfunction lineAt(source: string, index: number): number {\n return source.slice(0, index).split(/\\r?\\n/).length;\n}\n\n// Line of the next matching close tag after `fromIndex`; falls back to the\n// start line if the template is unbalanced (no close found).\nfunction endLineAfter(source: string, fromIndex: number, endRe: RegExp, startLine: number): number {\n endRe.lastIndex = fromIndex;\n const m = endRe.exec(source);\n return m ? lineAt(source, m.index) : startLine;\n}\n\nexport function parseHubL(f: WalkedFile, source: string): ParsedFile {\n const symbols: ParsedSymbol[] = [];\n const imports: string[] = [];\n\n for (const m of source.matchAll(MACRO_RE)) {\n const name = m[1];\n if (!name) continue;\n const args = (m[2] ?? \"\").trim();\n const start = m.index ?? 0;\n const startLine = lineAt(source, start);\n symbols.push({\n name,\n kind: \"function\",\n startLine,\n endLine: endLineAfter(source, start + m[0].length, ENDMACRO_RE, startLine),\n signature: `macro ${name}(${args})`,\n });\n }\n\n for (const m of source.matchAll(BLOCK_RE)) {\n const name = m[1];\n if (!name) continue;\n const start = m.index ?? 0;\n const startLine = lineAt(source, start);\n symbols.push({\n name,\n kind: \"component\",\n startLine,\n endLine: endLineAfter(source, start + m[0].length, ENDBLOCK_RE, startLine),\n signature: `block ${name}`,\n });\n }\n\n for (const m of source.matchAll(IMPORT_RE)) {\n const spec = m[1];\n if (spec) imports.push(spec);\n }\n\n return { file: f, source, symbols, imports: Array.from(new Set(imports)), calls: [] };\n}\n","// Java parser. Classes, interfaces, methods, imports.\n\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\nimport { runGenericParser } from \"./_generic.js\";\n\nconst QUERY = `\n(class_declaration name: (identifier) @class.name) @class\n(interface_declaration name: (identifier) @interface.name) @interface\n(method_declaration name: (identifier) @method.name) @method\n(enum_declaration name: (identifier) @enum.name) @enum\n(import_declaration (scoped_identifier) @import)\n(method_invocation name: (identifier) @call.name) @call\n`;\n\nexport async function parseJava(f: WalkedFile, source: string): Promise<ParsedFile> {\n return runGenericParser(\n {\n grammar: \"java\",\n query: QUERY,\n decls: [\n { declCapture: \"class\", nameCapture: \"class.name\", kind: \"class\" },\n { declCapture: \"interface\", nameCapture: \"interface.name\", kind: \"interface\" },\n { declCapture: \"method\", nameCapture: \"method.name\", kind: \"method\" },\n { declCapture: \"enum\", nameCapture: \"enum.name\", kind: \"enum\" },\n ],\n importCapture: \"import\",\n callCapture: \"call\",\n callCalleeCapture: \"call.name\",\n },\n f,\n source,\n );\n}\n","// Kotlin parser. Functions, classes, objects, interfaces, imports.\n\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\nimport { runGenericParser } from \"./_generic.js\";\n\nconst QUERY = `\n(function_declaration (simple_identifier) @function.name) @function\n(class_declaration (type_identifier) @class.name) @class\n(object_declaration (type_identifier) @object.name) @object\n(import_header (identifier) @import)\n(call_expression (simple_identifier) @call.name) @call\n`;\n\nexport async function parseKotlin(f: WalkedFile, source: string): Promise<ParsedFile> {\n return runGenericParser(\n {\n grammar: \"kotlin\",\n query: QUERY,\n decls: [\n { declCapture: \"function\", nameCapture: \"function.name\", kind: \"function\" },\n { declCapture: \"class\", nameCapture: \"class.name\", kind: \"class\" },\n { declCapture: \"object\", nameCapture: \"object.name\", kind: \"class\" },\n ],\n importCapture: \"import\",\n callCapture: \"call\",\n callCalleeCapture: \"call.name\",\n },\n f,\n source,\n );\n}\n","// PHP parser. Functions, classes, interfaces, methods, traits.\n\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\nimport { runGenericParser } from \"./_generic.js\";\n\nconst QUERY = `\n(function_definition name: (name) @function.name) @function\n(class_declaration name: (name) @class.name) @class\n(interface_declaration name: (name) @interface.name) @interface\n(trait_declaration name: (name) @trait.name) @trait\n(method_declaration name: (name) @method.name) @method\n(function_call_expression function: (name) @call.name) @call\n(member_call_expression name: (name) @call.name) @call\n(scoped_call_expression name: (name) @call.name) @call\n`;\n\nexport async function parsePhp(f: WalkedFile, source: string): Promise<ParsedFile> {\n return runGenericParser(\n {\n grammar: \"php\",\n query: QUERY,\n decls: [\n { declCapture: \"function\", nameCapture: \"function.name\", kind: \"function\" },\n { declCapture: \"class\", nameCapture: \"class.name\", kind: \"class\" },\n { declCapture: \"interface\", nameCapture: \"interface.name\", kind: \"interface\" },\n { declCapture: \"trait\", nameCapture: \"trait.name\", kind: \"class\" },\n { declCapture: \"method\", nameCapture: \"method.name\", kind: \"method\" },\n ],\n callCapture: \"call\",\n callCalleeCapture: \"call.name\",\n },\n f,\n source,\n );\n}\n","// Python parser using tree-sitter-python WASM.\n// Extracts: function/class definitions, methods, and import statements.\n\nimport { Query, type Node } from \"web-tree-sitter\";\nimport { createParser, type CallSite, type ParsedFile, type ParsedSymbol } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\n\nconst QUERY = `\n(function_definition name: (identifier) @function.name) @function\n(class_definition name: (identifier) @class.name) @class\n(import_statement name: (dotted_name) @import.module)\n(import_from_statement module_name: (dotted_name) @import.from)\n(import_from_statement module_name: (relative_import) @import.from)\n(call function: (identifier) @call.name) @call\n(call function: (attribute attribute: (identifier) @call.name)) @call\n`;\n\nfunction firstLine(text: string, max = 200): string {\n const line = text.split(/\\r?\\n/, 1)[0] ?? \"\";\n return line.length > max ? line.slice(0, max) + \"…\" : line;\n}\n\nexport async function parsePython(f: WalkedFile, source: string): Promise<ParsedFile> {\n let symbols: ParsedSymbol[] = [];\n let imports: string[] = [];\n const calls: CallSite[] = [];\n\n try {\n const { parser, language } = await createParser(\"python\");\n const tree = parser.parse(source);\n if (!tree) return { file: f, source, symbols, imports, calls };\n\n const query = new Query(language, QUERY);\n const matches = query.matches(tree.rootNode);\n\n for (const match of matches) {\n const byName = new Map<string, Node>();\n for (const cap of match.captures) byName.set(cap.name, cap.node);\n\n const funcDecl = byName.get(\"function\");\n const funcName = byName.get(\"function.name\");\n if (funcDecl && funcName) {\n const parentType = funcDecl.parent?.parent?.type;\n const isMethod = parentType === \"class_definition\";\n symbols.push({\n name: funcName.text,\n kind: isMethod ? \"method\" : \"function\",\n startLine: funcDecl.startPosition.row + 1,\n endLine: funcDecl.endPosition.row + 1,\n signature: firstLine(funcDecl.text),\n });\n continue;\n }\n\n const classDecl = byName.get(\"class\");\n const className = byName.get(\"class.name\");\n if (classDecl && className) {\n symbols.push({\n name: className.text,\n kind: \"class\",\n startLine: classDecl.startPosition.row + 1,\n endLine: classDecl.endPosition.row + 1,\n signature: firstLine(classDecl.text),\n });\n continue;\n }\n\n const importNode = byName.get(\"import.module\") ?? byName.get(\"import.from\");\n if (importNode) {\n imports.push(importNode.text);\n continue;\n }\n\n const callName = byName.get(\"call.name\");\n const callNode = byName.get(\"call\");\n if (callName && callNode) {\n calls.push({ callee: callName.text, line: callNode.startPosition.row + 1 });\n }\n }\n\n const seen = new Set<string>();\n symbols = symbols.filter((s) => {\n const key = `${s.name}:${s.startLine}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n imports = Array.from(new Set(imports));\n } catch {\n // swallow parse errors\n }\n\n return { file: f, source, symbols, imports, calls };\n}\n","// Ruby parser. Methods, classes, modules.\n// Imports omitted — Ruby's `require` is dynamic and hard to capture cleanly;\n// keyword indexing still surfaces dependencies.\n\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\nimport { runGenericParser } from \"./_generic.js\";\n\nconst QUERY = `\n(method name: (identifier) @function.name) @function\n(singleton_method name: (identifier) @method.name) @method\n(class name: (constant) @class.name) @class\n(module name: (constant) @module.name) @module\n(call method: (identifier) @call.name) @call\n`;\n\nexport async function parseRuby(f: WalkedFile, source: string): Promise<ParsedFile> {\n return runGenericParser(\n {\n grammar: \"ruby\",\n query: QUERY,\n decls: [\n { declCapture: \"function\", nameCapture: \"function.name\", kind: \"function\" },\n { declCapture: \"method\", nameCapture: \"method.name\", kind: \"method\" },\n { declCapture: \"class\", nameCapture: \"class.name\", kind: \"class\" },\n { declCapture: \"module\", nameCapture: \"module.name\", kind: \"class\" },\n ],\n callCapture: \"call\",\n callCalleeCapture: \"call.name\",\n },\n f,\n source,\n );\n}\n","// Rust parser. Functions, structs, enums, traits, impls.\n// Import capture is omitted — `use` paths are nested and complex; the file\n// will still be walked + keyword-indexed.\n\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\nimport { runGenericParser } from \"./_generic.js\";\n\nconst QUERY = `\n(function_item name: (identifier) @function.name) @function\n(struct_item name: (type_identifier) @struct.name) @struct\n(enum_item name: (type_identifier) @enum.name) @enum\n(trait_item name: (type_identifier) @trait.name) @trait\n(impl_item type: (type_identifier) @impl.name) @impl\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (scoped_identifier name: (identifier) @call.name)) @call\n(call_expression function: (field_expression field: (field_identifier) @call.name)) @call\n`;\n\nexport async function parseRust(f: WalkedFile, source: string): Promise<ParsedFile> {\n return runGenericParser(\n {\n grammar: \"rust\",\n query: QUERY,\n decls: [\n { declCapture: \"function\", nameCapture: \"function.name\", kind: \"function\" },\n { declCapture: \"struct\", nameCapture: \"struct.name\", kind: \"class\" },\n { declCapture: \"enum\", nameCapture: \"enum.name\", kind: \"enum\" },\n { declCapture: \"trait\", nameCapture: \"trait.name\", kind: \"interface\" },\n { declCapture: \"impl\", nameCapture: \"impl.name\", kind: \"class\" },\n ],\n callCapture: \"call\",\n callCalleeCapture: \"call.name\",\n },\n f,\n source,\n );\n}\n","// TS/JS parser using tree-sitter-typescript / -tsx WASM grammars.\n// Extracts: function/class/interface/type/enum declarations, exported consts,\n// arrow functions assigned to const, and import sources.\n\nimport { Query, type Node } from \"web-tree-sitter\";\nimport type { SymbolKind } from \"../../graph/types.js\";\nimport {\n createParser,\n type CallSite,\n type GrammarName,\n type ParsedFile,\n type ParsedSymbol,\n} from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\n\n// TS / TSX query — uses the type-identifier node type for class names, includes\n// interface / type-alias / enum declarations that don't exist in plain JS.\nconst TS_QUERY = `\n(function_declaration name: (identifier) @function.name) @function\n(class_declaration name: (type_identifier) @class.name) @class\n(interface_declaration name: (type_identifier) @interface.name) @interface\n(type_alias_declaration name: (type_identifier) @type.name) @type\n(enum_declaration name: (identifier) @enum.name) @enum\n(method_definition name: (property_identifier) @method.name) @method\n(lexical_declaration (variable_declarator name: (identifier) @const-fn.name value: [(arrow_function) (function_expression)])) @const-fn\n(assignment_expression left: (member_expression property: (property_identifier) @member-fn.name) right: [(arrow_function) (function_expression)]) @member-fn\n(import_statement source: (string) @import)\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (member_expression property: (property_identifier) @call.name)) @call\n`;\n\n// JS query — class names are plain identifiers (JS grammar has no\n// type_identifier node). No interface / type_alias / enum since JS lacks them.\n// Adds a call_expression capture for CommonJS require('x'); filtered in the\n// matching loop by checking the function identifier text equals \"require\".\nconst JS_QUERY = `\n(function_declaration name: (identifier) @function.name) @function\n(class_declaration name: (identifier) @class.name) @class\n(method_definition name: (property_identifier) @method.name) @method\n(lexical_declaration (variable_declarator name: (identifier) @const-fn.name value: [(arrow_function) (function_expression)])) @const-fn\n(assignment_expression left: (member_expression property: (property_identifier) @member-fn.name) right: [(arrow_function) (function_expression)]) @member-fn\n(import_statement source: (string) @import)\n(call_expression function: (identifier) @_require_fn arguments: (arguments . (string) @require_source))\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (member_expression property: (property_identifier) @call.name)) @call\n`;\n\nfunction grammarFor(ext: string): GrammarName {\n if (ext === \".tsx\" || ext === \".jsx\") return \"tsx\";\n if (ext === \".js\" || ext === \".cjs\" || ext === \".mjs\") return \"javascript\";\n return \"typescript\";\n}\n\nfunction queryFor(grammar: GrammarName): string {\n return grammar === \"javascript\" ? JS_QUERY : TS_QUERY;\n}\n\nfunction unquote(s: string): string {\n return s.replace(/^[\"'`]|[\"'`]$/g, \"\");\n}\n\nfunction firstLine(text: string, max = 200): string {\n const line = text.split(/\\r?\\n/, 1)[0] ?? \"\";\n return line.length > max ? line.slice(0, max) + \"…\" : line;\n}\n\ninterface DeclShape {\n decl: Node;\n name: Node;\n kind: SymbolKind;\n}\n\nfunction shapeFromCaptures(captures: Map<string, Node>): DeclShape | null {\n const findDecl = (k: string, sk: SymbolKind): DeclShape | null => {\n const decl = captures.get(k);\n const name = captures.get(`${k}.name`);\n return decl && name ? { decl, name, kind: sk } : null;\n };\n\n return (\n findDecl(\"function\", \"function\") ??\n findDecl(\"class\", \"class\") ??\n findDecl(\"interface\", \"interface\") ??\n findDecl(\"type\", \"type\") ??\n findDecl(\"enum\", \"enum\") ??\n findDecl(\"method\", \"method\") ??\n findDecl(\"const-fn\", \"function\") ??\n findDecl(\"member-fn\", \"function\")\n );\n}\n\nexport async function parseTypeScript(f: WalkedFile, source: string): Promise<ParsedFile> {\n const grammar = grammarFor(f.ext);\n let symbols: ParsedSymbol[] = [];\n let imports: string[] = [];\n const calls: CallSite[] = [];\n\n try {\n const { parser, language } = await createParser(grammar);\n const tree = parser.parse(source);\n if (!tree) return { file: f, source, symbols, imports, calls };\n\n const query = new Query(language, queryFor(grammar));\n const matches = query.matches(tree.rootNode);\n\n for (const match of matches) {\n const byName = new Map<string, Node>();\n for (const cap of match.captures) byName.set(cap.name, cap.node);\n\n const shape = shapeFromCaptures(byName);\n if (shape) {\n symbols.push({\n name: shape.name.text,\n kind: shape.kind,\n startLine: shape.decl.startPosition.row + 1,\n endLine: shape.decl.endPosition.row + 1,\n signature: firstLine(shape.decl.text),\n });\n continue;\n }\n const importNode = byName.get(\"import\");\n if (importNode) {\n imports.push(unquote(importNode.text));\n continue;\n }\n // CommonJS require('x') — only captured by JS_QUERY. The identifier\n // must literally be \"require\" (not setTimeout, console, etc).\n const requireFn = byName.get(\"_require_fn\");\n const requireSource = byName.get(\"require_source\");\n if (requireFn && requireSource && requireFn.text === \"require\") {\n imports.push(unquote(requireSource.text));\n continue;\n }\n // Call site (bare or member call). `require(...)` also matches here — it\n // resolves to no project symbol and is dropped, so no special-casing.\n const callName = byName.get(\"call.name\");\n const callNode = byName.get(\"call\");\n if (callName && callNode) {\n calls.push({ callee: callName.text, line: callNode.startPosition.row + 1 });\n }\n }\n\n const seen = new Set<string>();\n symbols = symbols.filter((s) => {\n const key = `${s.name}:${s.startLine}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n imports = Array.from(new Set(imports));\n } catch {\n // Parse failure shouldn't abort the whole scan — return what we have.\n }\n\n return { file: f, source, symbols, imports, calls };\n}\n","// Svelte parser. Extracts <script> and <script lang=\"ts\"> blocks and parses\n// their contents with the TypeScript parser. Tracks the original line offset\n// so reported symbol positions match the .svelte source.\n\nimport { parseTypeScript } from \"./typescript.js\";\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\n\nconst SCRIPT_RE = /<script\\b[^>]*>([\\s\\S]*?)<\\/script>/gi;\n\ninterface ScriptBlock {\n source: string;\n startLine: number; // 1-based line number where the script content begins\n isTsx: boolean;\n}\n\nfunction extractScripts(source: string): ScriptBlock[] {\n const out: ScriptBlock[] = [];\n for (const match of source.matchAll(SCRIPT_RE)) {\n const full = match[0];\n const inner = match[1] ?? \"\";\n const openTag = full.slice(0, full.indexOf(\">\") + 1);\n const tagStart = match.index ?? 0;\n const contentStart = tagStart + openTag.length;\n const startLine = source.slice(0, contentStart).split(/\\r?\\n/).length;\n const isTsx = /\\blang\\s*=\\s*[\"']?(ts|tsx|typescript)[\"']?/i.test(openTag);\n out.push({ source: inner, startLine, isTsx });\n }\n return out;\n}\n\nexport async function parseSvelte(f: WalkedFile, source: string): Promise<ParsedFile> {\n const blocks = extractScripts(source);\n const out: ParsedFile = { file: f, source, symbols: [], imports: [], calls: [] };\n\n for (const block of blocks) {\n const virtual: WalkedFile = { ...f, ext: block.isTsx ? \".ts\" : \".js\" };\n const parsed = await parseTypeScript(virtual, block.source);\n const offset = block.startLine - 1;\n for (const sym of parsed.symbols) {\n out.symbols.push({\n ...sym,\n startLine: sym.startLine + offset,\n endLine: sym.endLine + offset,\n });\n }\n for (const imp of parsed.imports) out.imports.push(imp);\n for (const call of parsed.calls) out.calls.push({ ...call, line: call.line + offset });\n }\n\n // The .svelte file itself is treated as a component.\n out.symbols.push({\n name:\n f.relPath\n .split(\"/\")\n .pop()\n ?.replace(/\\.svelte$/i, \"\") ?? f.relPath,\n kind: \"component\",\n startLine: 1,\n endLine: source.split(/\\r?\\n/).length,\n signature: f.relPath,\n });\n out.imports = Array.from(new Set(out.imports));\n return out;\n}\n","// Vue SFC parser. Extracts <script> / <script setup> / <script lang=\"ts\">\n// blocks and parses them with the TypeScript parser, preserving line offsets.\n\nimport { parseTypeScript } from \"./typescript.js\";\nimport type { ParsedFile } from \"../parser.js\";\nimport type { WalkedFile } from \"../walker.js\";\n\nconst SCRIPT_RE = /<script\\b[^>]*>([\\s\\S]*?)<\\/script>/gi;\n\ninterface ScriptBlock {\n source: string;\n startLine: number;\n isTs: boolean;\n}\n\nfunction extractScripts(source: string): ScriptBlock[] {\n const out: ScriptBlock[] = [];\n for (const match of source.matchAll(SCRIPT_RE)) {\n const full = match[0];\n const inner = match[1] ?? \"\";\n const openTag = full.slice(0, full.indexOf(\">\") + 1);\n const tagStart = match.index ?? 0;\n const contentStart = tagStart + openTag.length;\n const startLine = source.slice(0, contentStart).split(/\\r?\\n/).length;\n const isTs = /\\blang\\s*=\\s*[\"']?(ts|tsx|typescript)[\"']?/i.test(openTag);\n out.push({ source: inner, startLine, isTs });\n }\n return out;\n}\n\nexport async function parseVue(f: WalkedFile, source: string): Promise<ParsedFile> {\n const blocks = extractScripts(source);\n const out: ParsedFile = { file: f, source, symbols: [], imports: [], calls: [] };\n\n for (const block of blocks) {\n const virtual: WalkedFile = { ...f, ext: block.isTs ? \".ts\" : \".js\" };\n const parsed = await parseTypeScript(virtual, block.source);\n const offset = block.startLine - 1;\n for (const sym of parsed.symbols) {\n out.symbols.push({\n ...sym,\n startLine: sym.startLine + offset,\n endLine: sym.endLine + offset,\n });\n }\n for (const imp of parsed.imports) out.imports.push(imp);\n for (const call of parsed.calls) out.calls.push({ ...call, line: call.line + offset });\n }\n\n out.symbols.push({\n name:\n f.relPath\n .split(\"/\")\n .pop()\n ?.replace(/\\.vue$/i, \"\") ?? f.relPath,\n kind: \"component\",\n startLine: 1,\n endLine: source.split(/\\r?\\n/).length,\n signature: f.relPath,\n });\n out.imports = Array.from(new Set(out.imports));\n return out;\n}\n","// Walks project root, yields files to parse.\n// Honors .gitignore + .synthraignore (additive — entries in either are ignored).\n// Defensive defaults skip VCS, build, and dependency directories even if absent\n// from .gitignore.\n\nimport type { Dirent } from \"node:fs\";\nimport { readFile, readdir, stat } from \"node:fs/promises\";\nimport { extname, join, relative, sep } from \"node:path\";\nimport ignore, { type Ignore } from \"ignore\";\n\nexport interface WalkedFile {\n absPath: string;\n relPath: string;\n ext: string;\n size: number;\n}\n\nexport interface WalkOptions {\n /** Maximum file size to yield (bytes). Defaults to 2 MB. */\n maxFileSize?: number;\n /** Additional ignore patterns layered on top of .gitignore + .synthraignore. */\n extraIgnore?: string[];\n}\n\nconst DEFAULT_IGNORE = [\n \".git/\",\n \".synthra/\",\n \".synthra-graph/\",\n \".claude/\",\n \"node_modules/\",\n \"dist/\",\n \"build/\",\n \"out/\",\n \"coverage/\",\n \".next/\",\n \".nuxt/\",\n \".svelte-kit/\",\n \".turbo/\",\n \".cache/\",\n \".vscode/\",\n \".idea/\",\n \".vs/\",\n // Flutter / Dart build caches — IDE-rehydrated, contain third-party\n // type stubs (typescript.d.ts, babylon.js etc.) that contaminate the graph.\n \".dart_tool/\",\n \".flutter-plugins\",\n \".flutter-plugins-dependencies\",\n // Android / Java / Kotlin / Rust\n \".gradle/\",\n \"target/\",\n // iOS / Xcode\n \"Pods/\",\n \"DerivedData/\",\n // Python\n \"__pycache__/\",\n \".venv/\",\n \"venv/\",\n \".tox/\",\n \".pytest_cache/\",\n \".mypy_cache/\",\n \".ruff_cache/\",\n // .NET\n \"obj/\",\n];\n\nconst BINARY_EXTS = new Set([\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".webp\",\n \".svg\",\n \".ico\",\n \".bmp\",\n \".pdf\",\n \".zip\",\n \".tar\",\n \".gz\",\n \".7z\",\n \".rar\",\n \".mp3\",\n \".mp4\",\n \".mov\",\n \".avi\",\n \".webm\",\n \".wav\",\n \".ogg\",\n \".ttf\",\n \".otf\",\n \".woff\",\n \".woff2\",\n \".eot\",\n \".exe\",\n \".dll\",\n \".so\",\n \".dylib\",\n \".bin\",\n \".wasm\",\n \".lock\",\n \".lockb\",\n]);\n\nasync function readIgnoreFile(path: string): Promise<string[]> {\n try {\n const text = await readFile(path, \"utf8\");\n return text\n .split(/\\r?\\n/)\n .map((l) => l.trim())\n .filter((l) => l.length > 0 && !l.startsWith(\"#\"));\n } catch {\n return [];\n }\n}\n\nasync function buildMatcher(root: string, extra: string[]): Promise<Ignore> {\n const ig = ignore();\n ig.add(DEFAULT_IGNORE);\n ig.add(await readIgnoreFile(join(root, \".gitignore\")));\n ig.add(await readIgnoreFile(join(root, \".synthraignore\")));\n if (extra.length) ig.add(extra);\n return ig;\n}\n\nfunction toPosix(p: string): string {\n return sep === \"/\" ? p : p.split(sep).join(\"/\");\n}\n\nexport async function* walk(root: string, options: WalkOptions = {}): AsyncGenerator<WalkedFile> {\n const maxFileSize = options.maxFileSize ?? 2_000_000;\n const ig = await buildMatcher(root, options.extraIgnore ?? []);\n\n async function* recurse(dir: string): AsyncGenerator<WalkedFile> {\n let entries: Dirent[];\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n const abs = join(dir, entry.name);\n const rel = relative(root, abs);\n if (!rel) continue;\n const relPosix = toPosix(rel);\n const matchPath = entry.isDirectory() ? `${relPosix}/` : relPosix;\n if (ig.ignores(matchPath)) continue;\n\n if (entry.isDirectory()) {\n yield* recurse(abs);\n } else if (entry.isFile()) {\n const ext = extname(entry.name).toLowerCase();\n if (BINARY_EXTS.has(ext)) continue;\n let size: number;\n try {\n const s = await stat(abs);\n size = s.size;\n } catch {\n continue;\n }\n if (size > maxFileSize) continue;\n yield { absPath: abs, relPath: relPosix, ext, size };\n }\n }\n }\n\n yield* recurse(root);\n}\n","// Reads/writes info_graph.json and symbol_index.json.\n\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport type { GraphSchema, SymbolIndex } from \"./types.js\";\n\nasync function writeJson(path: string, data: unknown, pretty: boolean): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n const text = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);\n await writeFile(path, text + \"\\n\", \"utf8\");\n}\n\nasync function readJson<T>(path: string): Promise<T> {\n const text = await readFile(path, \"utf8\");\n return JSON.parse(text) as T;\n}\n\nexport async function writeGraph(path: string, graph: GraphSchema): Promise<void> {\n // Pretty-printing a graph with full file contents balloons disk size and\n // the JSON is only ever read by machines; keep it compact.\n await writeJson(path, graph, false);\n}\n\nexport async function readGraph(path: string): Promise<GraphSchema> {\n return readJson<GraphSchema>(path);\n}\n\nexport async function writeSymbolIndex(path: string, index: SymbolIndex): Promise<void> {\n await writeJson(path, index, true);\n}\n\nexport async function readSymbolIndex(path: string): Promise<SymbolIndex> {\n // Re-home onto a null prototype so name lookups (e.g. index[\"toString\"])\n // never resolve to an inherited Object.prototype member. Mirrors\n // buildSymbolIndex, which builds the index the same way.\n const parsed = await readJson<SymbolIndex>(path);\n return Object.assign(Object.create(null), parsed);\n}\n","// Project bootstrap: creates .synthra-graph/, .synthra/, updates .gitignore,\n// patches CLAUDE.md with the versioned policy block.\n\nimport { mkdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport { basename } from \"node:path\";\n\nimport { patchClaudeMd } from \"../hooks/claude-md.js\";\nimport type { SynthraPaths } from \"../shared/paths.js\";\n\nexport interface BootstrapResult {\n graphCreated: boolean;\n contextCreated: boolean;\n gitignoreUpdated: boolean;\n claudeMdUpdated: boolean;\n claudeMdCreated: boolean;\n}\n\n// Entries Synthra appends to the project .gitignore on bootstrap.\n// Each is gated by a check: if the entry is already present (any\n// indentation, trimmed match), it's skipped. Comments are per-entry so\n// users understand why each line is there and can remove what they don't\n// want without breaking the rest.\nconst GITIGNORE_ENTRIES: { comment: string; entry: string }[] = [\n {\n comment: \"added by synthra (heavy generated state — gitignored by design)\",\n entry: \".synthra-graph/\",\n },\n {\n comment:\n \"added by synthra — MCP registration. Remove this line if you want \" +\n \"to share the synthra MCP entry with teammates via committed .mcp.json\",\n entry: \".mcp.json\",\n },\n];\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function ensureDir(path: string): Promise<boolean> {\n const had = await exists(path);\n await mkdir(path, { recursive: true });\n return !had;\n}\n\nasync function patchGitignore(path: string): Promise<boolean> {\n let existing = \"\";\n try {\n existing = await readFile(path, \"utf8\");\n } catch {\n /* file may not exist */\n }\n const trimmed = new Set(existing.split(/\\r?\\n/).map((l) => l.trim()));\n const missing = GITIGNORE_ENTRIES.filter((e) => !trimmed.has(e.entry));\n if (missing.length === 0) return false;\n\n const block = missing.map((m) => `# ${m.comment}\\n${m.entry}`).join(\"\\n\") + \"\\n\";\n const appendix =\n (existing.length === 0 || existing.endsWith(\"\\n\") ? \"\" : \"\\n\") +\n (existing.length ? \"\\n\" : \"\") +\n block;\n await writeFile(path, existing + appendix, \"utf8\");\n return true;\n}\n\nexport async function bootstrap(paths: SynthraPaths): Promise<BootstrapResult> {\n const graphCreated = await ensureDir(paths.graphDir);\n const contextCreated = await ensureDir(paths.contextDir);\n const gitignoreUpdated = await patchGitignore(paths.gitignore);\n\n const claudeMdExistedBefore = await exists(paths.claudeMd);\n const patch = await patchClaudeMd(paths.claudeMd, basename(paths.projectRoot));\n\n return {\n graphCreated,\n contextCreated,\n gitignoreUpdated,\n claudeMdUpdated: patch.updated,\n claudeMdCreated: patch.created && !claudeMdExistedBefore,\n };\n}\n","// Idempotent patcher for the project's CLAUDE.md. Manages a single block\n// bounded by <!-- synthra-policy v<N> BEGIN --> ... <!-- synthra-policy v<N> END -->.\n// On each run, any prior synthra-policy block (any version) is removed and the\n// current-version block is appended at the end.\n\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { basename, dirname } from \"node:path\";\n\nexport const POLICY_VERSION = 7;\nexport const POLICY_BEGIN = `<!-- synthra-policy v${POLICY_VERSION} BEGIN -->`;\nexport const POLICY_END = `<!-- synthra-policy v${POLICY_VERSION} END -->`;\n\n// Matches a synthra-policy block of any version, e.g. v1, v2 …\nconst ANY_BLOCK_RE =\n /<!--\\s*synthra-policy\\s+v\\d+\\s+BEGIN\\s*-->[\\s\\S]*?<!--\\s*synthra-policy\\s+v\\d+\\s+END\\s*-->\\s*/g;\n\nexport interface PatchResult {\n created: boolean;\n updated: boolean;\n skipped: boolean;\n}\n\nexport function policyBlock(): string {\n return [\n POLICY_BEGIN,\n \"## Synthra context policy\",\n \"\",\n \"Synthra has pre-loaded structured context into this session and exposes\",\n \"the project's code graph through MCP tools. **Prefer these tools over\",\n \"Grep / Glob / Read** — they are faster, cheaper, and already filtered\",\n \"to relevant files.\",\n \"\",\n \"> **Tool namespace.** Synthra's MCP tools are exposed as\",\n \"> `mcp__synthra__graph_continue`, `mcp__synthra__graph_read`, and\",\n \"> `mcp__synthra__graph_register_edit`. **Short names will NOT resolve**\",\n \"> in ToolSearch or invocation — always use the full namespaced form.\",\n \"> If the tools are deferred, load their schemas with ToolSearch:\",\n \"> `select:mcp__synthra__graph_continue,mcp__synthra__graph_read,mcp__synthra__graph_register_edit`.\",\n \"> Below, short names (`graph_continue` etc.) appear in prose for\",\n \"> readability only.\",\n \"\",\n \"### Tools\",\n \"\",\n \"- **`graph_continue(query)`** — returns a `Confidence` label, the list\",\n \" of relevant `Files`, and signatures + top function bodies for those\",\n \" files. Your default first move when you need project context.\",\n \"- **`graph_read(target)`** — fetch source. Prefer the\",\n ' `\"file/path.ts::SymbolName\"` form over a bare file path — reading one',\n \" symbol is ~50 tokens, reading a whole file is thousands.\",\n \"- **`graph_register_edit(files)`** — after you edit files, call this so\",\n \" subsequent turns weight your changes and avoid stale snapshots.\",\n \"\",\n \"### When to call `graph_continue` — and when to skip\",\n \"\",\n \"**Call `graph_continue` only when you do NOT already know the relevant\",\n \"files.**\",\n \"\",\n \"Call it when:\",\n \"- This is the first message of a new task or conversation\",\n \"- The task shifts to a different area of the codebase\",\n \"- You need files you haven't seen yet in this session\",\n \"\",\n \"**Skip `graph_continue` when:**\",\n \"- You already identified the relevant files earlier in this conversation\",\n \"- You are doing follow-up work on files already read (verify, refactor,\",\n \" test, docs, cleanup, commit)\",\n \"- The task is pure text (commit message, explanation, summary)\",\n \"\",\n \"If skipping, go directly to\",\n '`mcp__synthra__graph_read(\"file.ts::symbol\")` on what you already know.',\n \"\",\n \"### Confidence caps\",\n \"\",\n \"When `graph_continue` returns:\",\n \"\",\n \"- **`Confidence: high`** → Stop. Do NOT Grep, Glob, or further explore\",\n \" for this query. The graph already has it.\",\n \"- **`Confidence: medium`** → Read the listed `Files` directly via\",\n ' `mcp__synthra__graph_read(\"file::symbol\")` *before* trying Grep. The',\n \" graph has narrowed the search space — use it, don't bypass it.\",\n \"- **`Confidence: low`** → You may use Grep / Glob, but the PreToolUse\",\n \" hook may still block redundant calls.\",\n \"\",\n \"### Reading code\",\n \"\",\n \"- **Always use `file::symbol` notation** with `graph_read`. Whole-file\",\n \" reads should be rare — only when you genuinely need the full file.\",\n \"- If `graph_continue`'s `Files` list contains a `::` entry, pass it\",\n \" verbatim to `graph_read`.\",\n \"- **Large file?** Don't read it in successive line-range chunks — call\",\n \" `mcp__synthra__graph_continue` or\",\n ' `mcp__synthra__graph_read(\"file::symbol\")` to pull the one symbol you',\n \" need. Chunked whole-file Reads are exactly the cost `graph_read`\",\n \" exists to avoid.\",\n \"\",\n \"### Editing a file\",\n \"\",\n \"Claude Code's `Edit` tool (and `Write` when overwriting) only accepts a\",\n \"file that was opened with the **`Read` tool** — a `graph_read` slice does\",\n 'not count, and editing such a file fails with *\"File has not been read',\n 'yet.\"* So before editing a file you only know through `graph_read`: take',\n \"the line range from its header (e.g. `…::handler (L120-168)`), `Read` that\",\n \"file with a matching `offset`/`limit`, then `Edit`. That satisfies the\",\n \"gate while keeping the read small — don't whole-file `Read` unless the\",\n \"edit spans most of the file.\",\n \"\",\n \"### Don'ts\",\n \"\",\n \"- Don't Grep / Glob before calling `graph_continue` when required — the\",\n \" PreToolUse hook may block it.\",\n \"- Don't call `graph_continue` more than once per turn.\",\n \"- Don't read whole files when a symbol-level read would suffice.\",\n \"\",\n \"### Resuming a session\",\n \"\",\n 'At session start the primer may begin with a **\"Since you were last here\"**',\n \"digest — recent commits, files touched, open next-steps, and recent\",\n \"decisions carried over from the previous session. **Trust it.** It is the\",\n \"cheapest possible orientation: do NOT re-run `graph_continue` or Grep just\",\n 'to rediscover \"what were we doing / what changed\" — that work is already',\n \"done. For the concrete next steps,\",\n '`mcp__synthra__context_recall({kind:\"next\"})` returns them verbatim. Only',\n \"reach for fresh retrieval when the task moves beyond what the digest\",\n \"covers.\",\n \"\",\n \"### Session-end resume note\",\n \"\",\n 'When the user signals they\\'re done (e.g. \"bye\", \"wrap up\", \"done\"),',\n \"persist the resume state by calling `context_remember` once per bullet.\",\n \"Synthra re-renders `.synthra/CONTEXT.md` from those entries at session\",\n \"end — do **NOT** write to `CONTEXT.md` directly, it is a derived view\",\n \"and direct edits are overwritten by the Stop hook.\",\n \"\",\n \"Use these `kind` values:\",\n \"\",\n '- **`kind: \"task\"`** — what is being worked on right now (1 entry)',\n '- **`kind: \"decision\"`** — non-obvious choices made this session (max 3)',\n '- **`kind: \"next\"`** — concrete next steps (max 3)',\n \"\",\n 'Tag entries with the relevant area (`tags: [\"auth\"]`) and the files',\n 'they touch (`files: [\"src/auth.ts\"]`) so later `context_recall` queries',\n \"can filter. Keep each `text` to 1–2 sentences.\",\n \"\",\n \"_This block is managed by Synthra. Edits inside the BEGIN/END markers\",\n \"are overwritten on every `syn .` run._\",\n \"\",\n POLICY_END,\n ].join(\"\\n\");\n}\n\n// A lean, agent-facing onboarding skeleton written ONLY when a project has no\n// CLAUDE.md yet. It captures the durable \"why/how\" the graph can't infer\n// (build/test, conventions, decisions, gotchas). It lives OUTSIDE the\n// synthra-policy markers, so later `syn .` runs — which strip and re-add the\n// policy block — never touch what the user fills in here.\nexport function onboardingSkeleton(projectName: string): string {\n return [\n `# ${projectName}`,\n \"\",\n \"> Onboarding notes for AI coding agents. Synthra's graph already knows the\",\n \"> code's *structure* (files, symbols, imports) — this file is for what the\",\n \"> graph can't infer: how to run the project, its conventions, and the\",\n \"> decisions behind them. Keep it lean and current; delete prompts you don't need.\",\n \"\",\n \"## Build & test\",\n \"\",\n \"- TODO: install deps / build\",\n \"- TODO: run tests / lint / typecheck\",\n \"- TODO: run the app locally\",\n \"\",\n \"## Conventions\",\n \"\",\n \"- TODO: code style, naming, file layout the agent should follow\",\n \"\",\n \"## Key decisions\",\n \"\",\n '- TODO: non-obvious choices and *why* (\"we use X not Y because …\")',\n \"\",\n \"## Gotchas\",\n \"\",\n '- TODO: traps, footguns, \"don\\'t touch X without Y\"',\n \"\",\n \"_Tip: run `/init` in Claude Code to auto-draft the sections above, then trim\",\n \"to the durable bits. Synthra manages its own block below — leave it._\",\n \"\",\n ].join(\"\\n\");\n}\n\nexport async function patchClaudeMd(path: string, projectName?: string): Promise<PatchResult> {\n let existing: string | null;\n try {\n existing = await readFile(path, \"utf8\");\n } catch {\n existing = null;\n }\n\n const block = policyBlock();\n\n if (existing === null) {\n // First creation: scaffold the onboarding skeleton (user-owned, written\n // once) followed by Synthra's managed policy block.\n const name = projectName || basename(dirname(path)) || \"this project\";\n await writeFile(path, onboardingSkeleton(name) + \"\\n\" + block + \"\\n\", \"utf8\");\n return { created: true, updated: false, skipped: false };\n }\n\n const stripped = existing.replace(ANY_BLOCK_RE, \"\");\n const hadBlock = stripped !== existing;\n\n const desired = stripped.endsWith(\"\\n\")\n ? stripped + \"\\n\" + block + \"\\n\"\n : (stripped.length ? stripped + \"\\n\\n\" : \"\") + block + \"\\n\";\n\n if (hadBlock && desired === existing) {\n return { created: false, updated: false, skipped: true };\n }\n\n await writeFile(path, desired, \"utf8\");\n return { created: false, updated: true, skipped: false };\n}\n","// Stateful wrapper around the usage-learning store. Keeps the decayed aggregate\n// in memory, folds each access as it happens, persists on a trailing debounce,\n// and exposes the live scores for the ranker. Constructed once per server, like\n// ActivityStore.\n\nimport { appendAccess, readAccessLog, readLearnStore, writeLearnStore } from \"./store.js\";\nimport {\n effectiveScores,\n foldEvent,\n recomputeFromLog,\n type AccessEvent,\n type LearnStore,\n} from \"./usage.js\";\n\nconst PERSIST_DEBOUNCE_MS = 2000;\n\nexport class LearnRuntime {\n private store: LearnStore;\n private dirty = false;\n private timer: ReturnType<typeof setTimeout> | null = null;\n\n private constructor(\n private readonly accessLogPath: string,\n private readonly storePath: string,\n store: LearnStore,\n ) {\n this.store = store;\n }\n\n /** Load the aggregate from disk; if it's empty but a raw log exists, replay it\n * (the log is the source of truth). Always succeeds — falls back to empty. */\n static async load(accessLogPath: string, storePath: string): Promise<LearnRuntime> {\n let store = await readLearnStore(storePath);\n if (Object.keys(store.files).length === 0) {\n const events = await readAccessLog(accessLogPath);\n if (events.length > 0) store = recomputeFromLog(events);\n }\n return new LearnRuntime(accessLogPath, storePath, store);\n }\n\n /** Record an access: append to the durable log + fold into the in-memory\n * aggregate. Best-effort — never throws into a tool call. */\n async record(ev: AccessEvent): Promise<void> {\n await appendAccess(this.accessLogPath, ev);\n foldEvent(this.store, ev);\n this.schedulePersist();\n }\n\n /** Decayed path→weight map for the ranker, as of now. */\n effectiveScores(nowMs: number = Date.now()): Map<string, number> {\n return effectiveScores(this.store, nowMs);\n }\n\n private schedulePersist(): void {\n this.dirty = true;\n if (this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.flush();\n }, PERSIST_DEBOUNCE_MS);\n // Don't keep the event loop alive just for the persist timer.\n this.timer.unref?.();\n }\n\n /** Persist the aggregate if it changed since the last write. Called on the\n * debounce and on server shutdown. */\n async flush(): Promise<void> {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n if (!this.dirty) return;\n this.dirty = false;\n this.store.asOf = new Date().toISOString();\n await writeLearnStore(this.storePath, this.store);\n }\n}\n","// MCP-over-HTTP (streamable) protocol handler. Exposes Synthra's graph tools\n// to Claude Code via JSON-RPC 2.0 messages POSTed to /mcp.\n//\n// Tools:\n// graph_continue(query) — retrieve + pack a context bundle\n// graph_read(target) — return source for \"file\" or \"file::symbol\"\n// graph_register_edit(files) — Claude tells Synthra it edited files\n//\n// Spec: https://modelcontextprotocol.io/specification\n\nimport { appendFile, mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { retrieve } from \"../graph/retrieve.js\";\nimport type { FileNode, GraphSchema, SymbolNode } from \"../graph/types.js\";\nimport { appendAccess } from \"../learn/store.js\";\nimport type { AccessEvent } from \"../learn/usage.js\";\nimport { recallEntries, rememberEntry } from \"../memory/index.js\";\nimport type { EntryKind } from \"../memory/context-store.js\";\nimport { pack } from \"../packer/index.js\";\nimport { loadConfig } from \"../shared/config.js\";\nimport type { ServerContext } from \"./context.js\";\n\nconst PROTOCOL_VERSION = \"2024-11-05\";\nconst SERVER_INFO = { name: \"synthra\", version: \"0.0.1\" } as const;\n\ntype JsonRpcId = string | number | null;\n\nexport interface JsonRpcRequest {\n jsonrpc: \"2.0\";\n id?: JsonRpcId;\n method: string;\n params?: Record<string, unknown>;\n}\n\nexport interface JsonRpcResponse {\n jsonrpc: \"2.0\";\n id: JsonRpcId;\n result?: unknown;\n error?: { code: number; message: string; data?: unknown };\n}\n\nconst ERR = {\n parse: -32700,\n invalidRequest: -32600,\n methodNotFound: -32601,\n invalidParams: -32602,\n internal: -32603,\n} as const;\n\nfunction ok(id: JsonRpcId, result: unknown): JsonRpcResponse {\n return { jsonrpc: \"2.0\", id, result };\n}\n\nfunction err(id: JsonRpcId, code: number, message: string, data?: unknown): JsonRpcResponse {\n return { jsonrpc: \"2.0\", id, error: { code, message, data } };\n}\n\nfunction textContent(text: string) {\n return { content: [{ type: \"text\", text }], isError: false };\n}\n\nfunction errorContent(message: string) {\n return { content: [{ type: \"text\", text: message }], isError: true };\n}\n\nconst TOOLS = [\n {\n name: \"graph_continue\",\n description:\n \"Returns the project context most relevant to a query — function signatures, top function bodies, and linked test files. Use this BEFORE Grep/Glob. If `confidence` is 'high', do not call Grep/Glob for the same query.\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: {\n type: \"string\",\n description: \"Natural-language description of what you're looking for.\",\n },\n },\n required: [\"query\"],\n },\n },\n {\n name: \"graph_read\",\n description:\n \"Return the source code for a specific file or symbol. Target is either a project-relative file path (e.g. 'src/auth.ts') or 'file::symbol' (e.g. 'src/auth.ts::AuthService'). A symbol read also returns its dependency surface — the signatures of the symbols it calls (edit against these instead of guessing or re-reading their files) and the names of the symbols that call it.\",\n inputSchema: {\n type: \"object\",\n properties: {\n target: { type: \"string\", description: \"File path or file::symbol notation.\" },\n },\n required: [\"target\"],\n },\n },\n {\n name: \"graph_register_edit\",\n description:\n \"Tell Synthra that you (the AI) have edited these files. Lets Synthra rank them higher in subsequent retrieval and avoid surfacing stale context.\",\n inputSchema: {\n type: \"object\",\n properties: {\n files: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Project-relative file paths that were edited.\",\n },\n },\n required: [\"files\"],\n },\n },\n {\n name: \"context_remember\",\n description:\n \"Persist a decision/task/next-step/fact/blocker into the project's branch-aware context store. Use when the user makes a decision worth keeping, identifies a TODO, or surfaces a key fact. Entries land in `.synthra/context-store.json` on the default branch, or `.synthra/branches/<sanitized>/context-store.json` on a feature branch — git-tracked, so teammates inherit them and they merge naturally.\",\n inputSchema: {\n type: \"object\",\n properties: {\n text: { type: \"string\", description: \"The thing to remember (1–3 sentences).\" },\n kind: {\n type: \"string\",\n enum: [\"decision\", \"task\", \"next\", \"fact\", \"blocker\"],\n description: \"What kind of entry. Required.\",\n },\n tags: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Optional tags for grouping (e.g. 'auth', 'perf').\",\n },\n files: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Optional project-relative file paths this entry relates to.\",\n },\n },\n required: [\"text\", \"kind\"],\n },\n },\n {\n name: \"context_recall\",\n description:\n \"Read previously-stored decisions/tasks/facts from the project's branch-aware context store. Defaults to the current branch.\",\n inputSchema: {\n type: \"object\",\n properties: {\n kind: {\n type: \"string\",\n enum: [\"decision\", \"task\", \"next\", \"fact\", \"blocker\"],\n description: \"Filter to a single kind.\",\n },\n branch: { type: \"string\", description: \"Override which branch to read from.\" },\n limit: { type: \"number\", description: \"Return only the most recent N entries.\" },\n },\n },\n },\n {\n name: \"recent_activity\",\n description:\n \"What has the human been doing in the editor recently — file saves, branch switches, and uncommitted-diff changes. Use this to check whether the static context pack may be stale (e.g. before answering a question about a file that was just edited).\",\n inputSchema: {\n type: \"object\",\n properties: {\n since_ms: {\n type: \"number\",\n description:\n \"Epoch milliseconds. Only return events newer than this. Defaults to the last 60 minutes.\",\n },\n limit: { type: \"number\", description: \"Cap on returned events.\" },\n },\n },\n },\n {\n name: \"count_tokens\",\n description:\n \"Estimate token count for a piece of text using a char/4 approximation. Accurate within ~10% for English + code. Useful for budgeting prompt content before sending.\",\n inputSchema: {\n type: \"object\",\n properties: {\n text: { type: \"string\", description: \"The text to estimate tokens for.\" },\n },\n required: [\"text\"],\n },\n },\n {\n name: \"blast_radius\",\n description:\n \"Given a file (or 'file::symbol' target), return all files that depend on it transitively via imports, tests, and call edges (callers). Use BEFORE editing a widely-used file to see what could break. Call edges are name-resolved (precise within a file, unique-name across files) and projected to file granularity.\",\n inputSchema: {\n type: \"object\",\n properties: {\n target: { type: \"string\", description: \"File path or 'file::symbol' notation.\" },\n depth: { type: \"number\", description: \"Max hops to traverse. Default 3.\" },\n },\n required: [\"target\"],\n },\n },\n {\n name: \"dead_code\",\n description:\n \"Return files in the project that no other file imports and no test file references — strong candidates for unused/orphaned code. File-level granularity; symbol-level dead code (unused exports, on top of the call graph) is a planned follow-up. Common entry-point patterns (main, index, app, CLI, bin/) are excluded heuristically.\",\n inputSchema: {\n type: \"object\",\n properties: {\n limit: { type: \"number\", description: \"Cap on returned files. Default 50.\" },\n },\n },\n },\n] as const;\n\nasync function callTool(\n name: string,\n args: Record<string, unknown> | undefined,\n ctx: ServerContext,\n) {\n switch (name) {\n case \"graph_continue\":\n return graphContinue(args, ctx);\n case \"graph_read\":\n return graphRead(args, ctx);\n case \"graph_register_edit\":\n return graphRegisterEdit(args, ctx);\n case \"context_remember\":\n return contextRemember(args, ctx);\n case \"context_recall\":\n return contextRecall(args, ctx);\n case \"recent_activity\":\n return recentActivity(args, ctx);\n case \"count_tokens\":\n return countTokens(args);\n case \"blast_radius\":\n return blastRadius(args, ctx);\n case \"dead_code\":\n return deadCode(args, ctx);\n default:\n return errorContent(`Unknown tool: ${name}`);\n }\n}\n\nfunction countTokens(args: Record<string, unknown> | undefined) {\n const text = typeof args?.text === \"string\" ? args.text : \"\";\n if (!text) return errorContent(\"count_tokens: 'text' (string) is required\");\n const tokens = Math.ceil(text.length / 4);\n return textContent(JSON.stringify({ tokens, method: \"chars/4 estimate\", chars: text.length }));\n}\n\nfunction blastRadius(args: Record<string, unknown> | undefined, ctx: ServerContext) {\n const targetRaw = typeof args?.target === \"string\" ? args.target.trim() : \"\";\n const maxDepth = typeof args?.depth === \"number\" && args.depth > 0 ? Math.floor(args.depth) : 3;\n if (!targetRaw) return errorContent(\"blast_radius: 'target' (string) is required\");\n\n const filePath = targetRaw.split(\"::\", 1)[0]?.trim() ?? targetRaw;\n const root = ctx.graph.nodes.find((n): n is FileNode => n.kind === \"file\" && n.path === filePath);\n if (!root) return errorContent(`blast_radius: file not in graph: ${filePath}`);\n\n // Index reverse edges (to → [{from, kind}]) once per call. `calls` edges are\n // symbol→symbol, so project them to file level (a caller's file depends on the\n // callee's file), skipping intra-file calls.\n const fileIdBySymbol = new Map<string, string>();\n for (const n of ctx.graph.nodes) {\n if (n.kind === \"symbol\") fileIdBySymbol.set(n.id, `file:${n.file}`);\n }\n const incoming = new Map<string, Array<{ from: string; kind: string }>>();\n const addIncoming = (to: string, from: string, kind: string): void => {\n const list = incoming.get(to) ?? [];\n list.push({ from, kind });\n incoming.set(to, list);\n };\n for (const e of ctx.graph.edges) {\n if (e.kind === \"imports\" || e.kind === \"tests\") {\n addIncoming(e.to, e.from, e.kind);\n } else if (e.kind === \"calls\") {\n const fromFile = fileIdBySymbol.get(e.from);\n const toFile = fileIdBySymbol.get(e.to);\n if (fromFile && toFile && fromFile !== toFile) addIncoming(toFile, fromFile, \"calls\");\n }\n }\n\n interface Hit {\n path: string;\n depth: number;\n via: string;\n }\n\n const visited = new Set<string>([root.id]);\n const hits: Hit[] = [];\n const pathById = new Map<string, string>();\n for (const n of ctx.graph.nodes) if (n.kind === \"file\") pathById.set(n.id, n.path);\n\n let frontier = [root.id];\n for (let d = 1; d <= maxDepth; d++) {\n const next: string[] = [];\n for (const cur of frontier) {\n const callers = incoming.get(cur) ?? [];\n for (const c of callers) {\n if (visited.has(c.from)) continue;\n visited.add(c.from);\n next.push(c.from);\n const path = pathById.get(c.from) ?? c.from;\n hits.push({ path, depth: d, via: c.kind });\n }\n }\n frontier = next;\n if (next.length === 0) break;\n }\n\n if (hits.length === 0) {\n return textContent(`# Blast radius for ${filePath}\\n\\n_(no dependents — file is isolated)_`);\n }\n\n hits.sort((a, b) => a.depth - b.depth || a.path.localeCompare(b.path));\n const lines = [`# Blast radius for ${filePath} (depth ≤ ${maxDepth})`, \"\"];\n lines.push(`${hits.length} dependent file(s):`);\n for (const h of hits) {\n lines.push(`- **depth ${h.depth}** \\`${h.path}\\` _(via ${h.via})_`);\n }\n return textContent(lines.join(\"\\n\"));\n}\n\nconst LIKELY_ENTRY_PATTERNS = [\n /(?:^|\\/)main\\.[a-z0-9_]+$/i,\n /(?:^|\\/)index\\.[a-z0-9_]+$/i,\n /(?:^|\\/)app\\.[a-z0-9_]+$/i,\n /(?:^|\\/)entry\\.[a-z0-9_]+$/i,\n /(?:^|\\/)cli[/.]/i,\n /(?:^|\\/)bin[/.]/i,\n /(?:^|\\/)server\\.[a-z0-9_]+$/i,\n /\\.test\\.[a-z0-9_]+$/i,\n /\\.spec\\.[a-z0-9_]+$/i,\n /(?:^|\\/)tests?\\//i,\n /(?:^|\\/)__tests__\\//i,\n /(?:^|\\/)__init__\\.py$/i,\n];\n\nfunction isLikelyEntry(path: string): boolean {\n return LIKELY_ENTRY_PATTERNS.some((re) => re.test(path));\n}\n\nfunction deadCode(args: Record<string, unknown> | undefined, ctx: ServerContext) {\n const limit = typeof args?.limit === \"number\" && args.limit > 0 ? Math.floor(args.limit) : 50;\n\n const hasIncoming = new Set<string>();\n for (const e of ctx.graph.edges) {\n if (e.kind === \"imports\" || e.kind === \"tests\") hasIncoming.add(e.to);\n }\n\n const candidates = ctx.graph.nodes\n .filter((n): n is FileNode => n.kind === \"file\")\n .filter((f) => !hasIncoming.has(f.id))\n .filter((f) => !isLikelyEntry(f.path));\n\n if (candidates.length === 0) {\n return textContent(\n `# Dead code\\n\\n_(no file is unreferenced — every file is either imported by another, has a linked test, or matches an entry-point pattern)_`,\n );\n }\n\n candidates.sort((a, b) => a.path.localeCompare(b.path));\n const shown = candidates.slice(0, limit);\n const lines = [`# Dead code candidates (file-level, v0.1)`, \"\"];\n lines.push(\n `${shown.length} of ${candidates.length} unreferenced file(s) — no other file imports them and no test links them:`,\n );\n lines.push(\"\");\n for (const f of shown) {\n lines.push(`- \\`${f.path}\\``);\n }\n lines.push(\"\");\n lines.push(\n `_caveat:_ this is file-level only. Symbol-level dead code (unused exports), built on the now-populated call graph, is a planned follow-up.`,\n );\n return textContent(lines.join(\"\\n\"));\n}\n\nasync function graphContinue(args: Record<string, unknown> | undefined, ctx: ServerContext) {\n const query = typeof args?.query === \"string\" ? args.query : \"\";\n if (!query) return errorContent(\"graph_continue: 'query' (string) is required\");\n\n // Session-aware routing (#14): seed retrieval with files the session has\n // touched — the human's recent saves + edits the AI registered via\n // graph_register_edit — so the ranker boosts them. Mirrors the /pack route.\n const retrieval = await retrieve(ctx.graph, query, {\n recentlyEditedPaths: ctx.activity.recentFilePaths(15 * 60 * 1000),\n sessionKnownPaths: getRegisteredEdits(),\n usageScores: ctx.learn?.effectiveScores(),\n });\n const packed = await pack(retrieval.files, { query, graph: ctx.graph });\n\n // Log the query (no file, weight 0) as query→outcome fuel for a future\n // mechanism — never count retrieval.files, which would feed ranking its own\n // output and cause popularity runaway.\n await logAccess(ctx, { ts: nowIso(), path: \"\", source: \"continue\", query });\n\n const header =\n `Confidence: ${retrieval.confidence}\\n` +\n `Files: ${retrieval.files.map((f) => f.path).join(\", \") || \"(none)\"}\\n` +\n `Reason: ${retrieval.reason}\\n`;\n\n // The pack body already starts with a header — keep them concatenated.\n return textContent(`${header}\\n${packed.text}`);\n}\n\n// Resolve a graph_read target's file part to a FileNode. Exact path wins; on a\n// miss, fall back to a unique path-suffix match so a shortened target like\n// \"appsettings.json\" finds \"api/.../appsettings.json\". Only serves the fallback\n// when EXACTLY one file matches — multiple matches are reported as ambiguous\n// rather than guessing. (#11)\nexport type FileTargetResult = { node: FileNode } | { ambiguous: string[] } | { none: true };\n\nexport function resolveFileTarget(graph: GraphSchema, filePath: string): FileTargetResult {\n const files = graph.nodes.filter((n): n is FileNode => n.kind === \"file\");\n const exact = files.find((n) => n.path === filePath);\n if (exact) return { node: exact };\n\n const suffix = \"/\" + filePath;\n const matches = files.filter((n) => n.path.endsWith(suffix));\n if (matches.length === 1) return { node: matches[0]! };\n if (matches.length > 1) return { ambiguous: matches.map((n) => n.path) };\n return { none: true };\n}\n\nconst DEPS_SIG_MAX = 140;\nconst DEPS_MAX_CALLEES = 10;\nconst DEPS_MAX_CALLERS = 12;\n\n/**\n * Dependency surface for a symbol, rendered as a point-of-use footer for\n * graph_read: the symbols it CALLS (with full signatures + graph_read targets —\n * so the agent edits against real signatures instead of guessing or re-reading\n * the callee files) and the symbols that CALL it (names only — cheap \"a change\n * here affects these\" awareness). Built from the v0.3.0 symbol→symbol `calls`\n * edges. Returns \"\" when the symbol has no call edges (leaf — keep reads lean).\n */\nexport function buildDepsFooter(\n symbol: SymbolNode,\n graph: GraphSchema,\n maxChars = loadConfig().readDepsMaxChars,\n): string {\n const symById = new Map<string, SymbolNode>();\n for (const n of graph.nodes) if (n.kind === \"symbol\") symById.set(n.id, n);\n\n const calleeIds: string[] = [];\n const callerIds: string[] = [];\n const seenCallee = new Set<string>();\n const seenCaller = new Set<string>();\n for (const e of graph.edges) {\n if (e.kind !== \"calls\") continue;\n if (e.from === symbol.id && e.to !== symbol.id && !seenCallee.has(e.to)) {\n seenCallee.add(e.to);\n calleeIds.push(e.to);\n } else if (e.to === symbol.id && e.from !== symbol.id && !seenCaller.has(e.from)) {\n seenCaller.add(e.from);\n callerIds.push(e.from);\n }\n }\n\n const resolve = (ids: string[]): SymbolNode[] =>\n ids.map((id) => symById.get(id)).filter((n): n is SymbolNode => !!n);\n const callees = resolve(calleeIds).sort((a, b) =>\n a.file === b.file ? a.start_line - b.start_line : a.file < b.file ? -1 : 1,\n );\n const callers = resolve(callerIds);\n\n if (callees.length === 0 && callers.length === 0) return \"\";\n\n const lines: string[] = [];\n let used = 0;\n\n if (callees.length > 0) {\n const head = \"Depends on (signatures — don't guess these):\";\n lines.push(head);\n used += head.length + 1;\n let shown = 0;\n for (const c of callees.slice(0, DEPS_MAX_CALLEES)) {\n const sig = c.signature.trim().slice(0, DEPS_SIG_MAX);\n const entry = `• ${sig} → mcp__synthra__graph_read(\"${c.file}::${c.name}\")`;\n if (used + entry.length + 1 > maxChars) break;\n lines.push(entry);\n used += entry.length + 1;\n shown += 1;\n }\n const omitted = callees.length - shown;\n if (omitted > 0) lines.push(`…+${omitted} more`);\n }\n\n if (callers.length > 0) {\n const sep = lines.length > 0 ? 1 : 0;\n const head = `Used by (${callers.length}): `;\n const shown: string[] = [];\n let cUsed = used + sep + head.length;\n for (const c of callers.slice(0, DEPS_MAX_CALLERS)) {\n const part = `${c.name} → ${c.file}`;\n const join = shown.length > 0 ? 3 : 0; // \" · \"\n if (cUsed + join + part.length > maxChars) break;\n shown.push(part);\n cUsed += join + part.length;\n }\n if (lines.length > 0) lines.push(\"\");\n if (shown.length > 0) {\n const omitted = callers.length - shown.length;\n lines.push(head + shown.join(\" · \") + (omitted > 0 ? ` …+${omitted} more` : \"\"));\n } else {\n lines.push(`Used by (${callers.length} callers)`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nasync function graphRead(args: Record<string, unknown> | undefined, ctx: ServerContext) {\n const target = typeof args?.target === \"string\" ? args.target : \"\";\n if (!target) return errorContent(\"graph_read: 'target' (string) is required\");\n\n const [rawFile, symbolName] = target.includes(\"::\") ? target.split(\"::\", 2) : [target, undefined];\n const filePath = (rawFile ?? \"\").trim();\n\n const resolved = resolveFileTarget(ctx.graph, filePath);\n if (\"ambiguous\" in resolved) {\n const shown = resolved.ambiguous.slice(0, 5).join(\", \");\n const more = resolved.ambiguous.length > 5 ? \", …\" : \"\";\n return errorContent(\n `graph_read: '${filePath}' matches multiple files (${shown}${more}). Pass a longer path.`,\n );\n }\n if (\"none\" in resolved) {\n return errorContent(`graph_read: file not found in graph: ${filePath}`);\n }\n const fileNode = resolved.node;\n\n // The AI deliberately pulled this file — the strongest \"this matters\" signal\n // short of an edit. Feed it to the learning layer.\n await logAccess(ctx, { ts: nowIso(), path: fileNode.path, source: \"read\" });\n\n if (!symbolName) {\n return textContent(`# ${fileNode.path}\\n\\n${fileNode.content}`);\n }\n\n const cleanSym = symbolName.trim();\n const symbol = ctx.graph.nodes.find(\n (n): n is SymbolNode => n.kind === \"symbol\" && n.file === fileNode.path && n.name === cleanSym,\n );\n if (!symbol) {\n return errorContent(`graph_read: symbol '${cleanSym}' not found in ${fileNode.path}`);\n }\n\n const lines = fileNode.content.split(/\\r?\\n/);\n const body = lines.slice(symbol.start_line - 1, symbol.end_line).join(\"\\n\");\n\n // Point-of-use edit recipe. Claude Code's Edit tool only accepts a file\n // opened with its own Read tool — this slice doesn't satisfy that gate — so\n // without this nudge agents re-Read the whole file before editing (the\n // dogfood log's biggest token leak: the same large file Read 15-19× a\n // session). Hand them the exact targeted Read that satisfies the gate cheaply,\n // with 2 lines of headroom each side for off-by-one safety + unique Edit context.\n const offset = Math.max(1, symbol.start_line - 2);\n const limit = symbol.end_line - symbol.start_line + 1 + 4;\n const editHint =\n `\\n\\n---\\n✎ To edit this symbol: Read(\"${fileNode.path}\", offset=${offset}, limit=${limit}) ` +\n `then Edit — that satisfies Claude Code's read-gate at ~${limit} lines; do NOT re-read the whole file.`;\n\n const deps = buildDepsFooter(symbol, ctx.graph);\n const depsBlock = deps ? `\\n\\n---\\n${deps}` : \"\";\n\n return textContent(\n `# ${fileNode.path}::${symbol.name} (L${symbol.start_line}-${symbol.end_line})\\n\\n${body}${depsBlock}${editHint}`,\n );\n}\n\nconst editedFiles = new Set<string>();\n\nasync function graphRegisterEdit(args: Record<string, unknown> | undefined, ctx: ServerContext) {\n const files = Array.isArray(args?.files)\n ? (args.files as unknown[]).filter((f) => typeof f === \"string\")\n : [];\n for (const f of files) {\n const file = f as string;\n editedFiles.add(file);\n // An edit is the strongest relevance signal — record it (weight 2). Resolve\n // to the canonical graph path so it keys to the same node the ranker scores;\n // a new/renamed file simply logs its raw path and decays out if unmatched.\n const resolved = resolveFileTarget(ctx.graph, file);\n await logAccess(ctx, {\n ts: nowIso(),\n path: \"node\" in resolved ? resolved.node.path : file,\n source: \"register_edit\",\n });\n }\n return textContent(\n `Registered ${files.length} edited file(s). Total tracked this session: ${editedFiles.size}.`,\n );\n}\n\nexport function getRegisteredEdits(): string[] {\n return Array.from(editedFiles);\n}\n\nconst VALID_KINDS = new Set<EntryKind>([\"decision\", \"task\", \"next\", \"fact\", \"blocker\"]);\n\nasync function contextRemember(args: Record<string, unknown> | undefined, ctx: ServerContext) {\n const text = typeof args?.text === \"string\" ? args.text.trim() : \"\";\n const kindRaw = typeof args?.kind === \"string\" ? args.kind : \"\";\n if (!text) return errorContent(\"context_remember: 'text' (string) is required\");\n if (!VALID_KINDS.has(kindRaw as EntryKind)) {\n return errorContent(\n `context_remember: 'kind' must be one of ${Array.from(VALID_KINDS).join(\", \")}`,\n );\n }\n const tags = Array.isArray(args?.tags)\n ? (args.tags as unknown[]).filter((t): t is string => typeof t === \"string\")\n : [];\n const files = Array.isArray(args?.files)\n ? (args.files as unknown[]).filter((f): f is string => typeof f === \"string\")\n : [];\n\n const result = await rememberEntry(ctx.paths, {\n text,\n kind: kindRaw as EntryKind,\n tags,\n files,\n });\n\n return textContent(\n `Remembered ${result.entry.type} on branch '${result.branch}'.\\n` +\n `Stored: ${result.storePath}\\n` +\n `CONTEXT.md refreshed: ${result.contextMdPath}`,\n );\n}\n\nconst DEFAULT_RECENT_WINDOW_MS = 60 * 60 * 1000;\n\nfunction recentActivity(args: Record<string, unknown> | undefined, ctx: ServerContext) {\n const sinceMs =\n typeof args?.since_ms === \"number\" && Number.isFinite(args.since_ms)\n ? args.since_ms\n : Date.now() - DEFAULT_RECENT_WINDOW_MS;\n const limit =\n typeof args?.limit === \"number\" && args.limit > 0 ? Math.floor(args.limit) : undefined;\n\n let events = ctx.activity.getEvents(sinceMs);\n if (limit) events = events.slice(-limit);\n\n if (events.length === 0) {\n return textContent(`No human-activity events since ${new Date(sinceMs).toISOString()}.`);\n }\n\n const lines = [`# Recent human activity (${events.length} events)`, \"\"];\n for (const e of events) {\n if (\"path\" in e) {\n lines.push(`- **${e.kind}** ${e.path} _(${e.ts})_`);\n } else {\n const summary = JSON.stringify(e.details);\n lines.push(`- **${e.kind}** ${summary} _(${e.ts})_`);\n }\n }\n return textContent(lines.join(\"\\n\"));\n}\n\nasync function contextRecall(args: Record<string, unknown> | undefined, ctx: ServerContext) {\n const kind =\n typeof args?.kind === \"string\" && VALID_KINDS.has(args.kind as EntryKind)\n ? (args.kind as EntryKind)\n : undefined;\n const branch = typeof args?.branch === \"string\" ? args.branch : undefined;\n const limit =\n typeof args?.limit === \"number\" && args.limit > 0 ? Math.floor(args.limit) : undefined;\n\n const result = await recallEntries(ctx.paths, { kind, branch, limit });\n\n if (result.entries.length === 0) {\n const filter = kind ? ` of kind '${kind}'` : \"\";\n return textContent(`No context entries${filter} on branch '${result.branch}'.`);\n }\n\n const lines = [`# Context entries — branch: ${result.branch}`, \"\"];\n for (const e of result.entries) {\n const tags = e.tags.length ? ` [${e.tags.join(\", \")}]` : \"\";\n lines.push(`- **${e.type}**${tags} (${e.date}): ${e.content}`);\n if (e.files.length) lines.push(` files: ${e.files.join(\", \")}`);\n }\n return textContent(lines.join(\"\\n\"));\n}\n\n// Best-effort per-call log of Synthra MCP tool usage — powers the dashboard's\n// graph-tool-usage metric (#2). A positive signal (how often the graph was\n// actually used) vs the blocked-Grep proxy, which misses well-behaved pivots.\nasync function logToolCall(ctx: ServerContext, tool: string): Promise<void> {\n try {\n await mkdir(dirname(ctx.paths.toolLog), { recursive: true });\n await appendFile(\n ctx.paths.toolLog,\n JSON.stringify({ ts: new Date().toISOString(), tool }) + \"\\n\",\n \"utf8\",\n );\n } catch {\n // Logging is best-effort; never fail a tool call over it.\n }\n}\n\n// Best-effort per-file usage capture (learning layer). Routes through the learn\n// runtime when present (folds the decayed aggregate in memory + appends the raw\n// log); otherwise appends the raw log directly so a runtime-less context (tests,\n// CLI) still records signal. Never throws — callers await it but its own errors\n// are swallowed, so telemetry can never fail a tool call.\nasync function logAccess(ctx: ServerContext, ev: AccessEvent): Promise<void> {\n try {\n if (ctx.learn) await ctx.learn.record(ev);\n else await appendAccess(ctx.paths.accessLog, ev);\n } catch {\n // best-effort\n }\n}\n\nfunction nowIso(): string {\n return new Date().toISOString();\n}\n\nexport async function handleMcpRequest(\n body: unknown,\n ctx: ServerContext,\n): Promise<JsonRpcResponse> {\n if (!body || typeof body !== \"object\") {\n return err(null, ERR.invalidRequest, \"Request body must be a JSON-RPC 2.0 object.\");\n }\n\n const req = body as JsonRpcRequest;\n if (req.jsonrpc !== \"2.0\" || typeof req.method !== \"string\") {\n return err(req.id ?? null, ERR.invalidRequest, \"Invalid JSON-RPC envelope.\");\n }\n\n const id = req.id ?? null;\n\n try {\n switch (req.method) {\n case \"initialize\":\n return ok(id, {\n protocolVersion:\n typeof req.params?.protocolVersion === \"string\"\n ? req.params.protocolVersion\n : PROTOCOL_VERSION,\n capabilities: { tools: {} },\n serverInfo: SERVER_INFO,\n });\n\n case \"notifications/initialized\":\n // Client confirms initialization. No response required for notifications (id===undefined).\n return ok(id, {});\n\n case \"tools/list\":\n return ok(id, { tools: TOOLS });\n\n case \"tools/call\": {\n const params = req.params ?? {};\n const toolName = typeof params.name === \"string\" ? params.name : \"\";\n if (!toolName) return err(id, ERR.invalidParams, \"'name' is required for tools/call.\");\n const args =\n params.arguments && typeof params.arguments === \"object\"\n ? (params.arguments as Record<string, unknown>)\n : {};\n void logToolCall(ctx, toolName);\n const result = await callTool(toolName, args, ctx);\n return ok(id, result);\n }\n\n case \"ping\":\n return ok(id, {});\n\n default:\n return err(id, ERR.methodNotFound, `Method not found: ${req.method}`);\n }\n } catch (e) {\n return err(id, ERR.internal, (e as Error).message);\n }\n}\n\n// Exposed for code that wants to enumerate the tool catalogue without going\n// through JSON-RPC (e.g. CLI introspection in M3).\nexport function listTools(): Array<{ name: string; description: string; inputSchema: unknown }> {\n return TOOLS.map((t) => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n }));\n}\n","// Scoring for retrieved files. Combines:\n// - keyword overlap with the (already-tokenized) query\n// - symbol-name overlap (boosted: hits in a file's defined symbols matter more)\n// - import-graph proximity from session-known + recent paths (boost adjacent files)\n// - recency boost from activity log (placeholder — wired in M5)\n\nimport type { Edge, FileNode, GraphSchema, SymbolNode } from \"./types.js\";\n\nexport interface RankInputs {\n candidates: FileNode[];\n query: string;\n graph?: GraphSchema;\n recentlyEditedPaths?: string[];\n sessionKnownPaths?: string[];\n /** Decayed per-file usage weights (path → weight) from the learning layer.\n * Applied as a bounded boost to files that ALREADY match the query. Omit to\n * disable (the ranker is then byte-identical to its deterministic form). */\n usageScores?: ReadonlyMap<string, number>;\n}\n\n// Base weight for a keyword match. The IDF reweighting is normalized to the\n// query's mean IDF, so a \"typical\"-rarity match contributes exactly this — which\n// preserves today's score magnitude (and the confidence/Moat calibration that\n// depends on it) while letting rarer terms score above and common terms below.\nconst KW_BASE_WEIGHT = 2;\n\n// Max additive usage boost. Strictly below the +5 seed boost so a maxed-out\n// usage signal can reorder within a relevance band but never leapfrog a freshly\n// seeded file or two exact symbol matches (+6). Env-overridable for tuning.\nconst USAGE_BOOST_CAP_DEFAULT = 4;\n\nfunction usageBoostCap(): number {\n const env = Number(process.env.SYN_LEARN_BOOST_CAP);\n return Number.isFinite(env) && env >= 0 ? env : USAGE_BOOST_CAP_DEFAULT;\n}\n\nexport interface ScoredFile {\n file: FileNode;\n score: number;\n reasons: string[];\n /** Total symbol-match weight (exact name = 3, partial substring = 1). */\n symHits: number;\n /** Count of symbols whose name a query token matched *exactly*. The gate\n * uses this — a partial substring match is too noisy (\"id\" ⊂ \"width\"). */\n exactSym: number;\n}\n\nconst STOPWORDS = new Set([\n \"a\",\n \"an\",\n \"and\",\n \"are\",\n \"as\",\n \"at\",\n \"be\",\n \"by\",\n \"for\",\n \"from\",\n \"has\",\n \"have\",\n \"in\",\n \"is\",\n \"it\",\n \"of\",\n \"on\",\n \"or\",\n \"that\",\n \"the\",\n \"this\",\n \"to\",\n \"was\",\n \"we\",\n \"with\",\n \"what\",\n \"where\",\n \"when\",\n \"why\",\n \"how\",\n \"do\",\n \"does\",\n \"i\",\n \"me\",\n \"my\",\n \"you\",\n \"your\",\n \"code\",\n \"file\",\n]);\n\nexport function tokenizeQuery(query: string): string[] {\n const tokens = query\n .toLowerCase()\n .split(/[^a-z0-9_]+/g)\n .filter((t) => t.length > 1 && !STOPWORDS.has(t));\n // Also split camelCase/snake_case for queries like \"AuthService\"\n const expanded = new Set<string>();\n for (const t of tokens) {\n expanded.add(t);\n const parts = t.match(/[a-z]+|[0-9]+/g) ?? [];\n for (const p of parts) if (p.length > 1) expanded.add(p);\n }\n return Array.from(expanded);\n}\n\nfunction indexSymbolsByFile(graph: GraphSchema | undefined): Map<string, SymbolNode[]> {\n const out = new Map<string, SymbolNode[]>();\n if (!graph) return out;\n for (const n of graph.nodes) {\n if (n.kind !== \"symbol\") continue;\n const list = out.get(n.file) ?? [];\n list.push(n);\n out.set(n.file, list);\n }\n return out;\n}\n\nfunction indexImportEdges(graph: GraphSchema | undefined): Map<string, Set<string>> {\n // file path → set of file paths it imports (1-hop)\n const out = new Map<string, Set<string>>();\n if (!graph) return out;\n const idToPath = new Map<string, string>();\n for (const n of graph.nodes) if (n.kind === \"file\") idToPath.set(n.id, n.path);\n for (const e of graph.edges as Edge[]) {\n if (e.kind !== \"imports\") continue;\n const from = idToPath.get(e.from);\n const to = idToPath.get(e.to);\n if (!from || !to) continue;\n const s = out.get(from) ?? new Set<string>();\n s.add(to);\n out.set(from, s);\n }\n return out;\n}\n\nexport function scoreFiles(inputs: RankInputs): ScoredFile[] {\n const qTokens = new Set(tokenizeQuery(inputs.query));\n const symbolsByFile = indexSymbolsByFile(inputs.graph);\n const importsFrom = indexImportEdges(inputs.graph);\n\n const seeds = new Set<string>(inputs.sessionKnownPaths ?? []);\n for (const p of inputs.recentlyEditedPaths ?? []) seeds.add(p);\n\n // IDF weighting for keyword matches — the part of BM25 that fits our deduped\n // top-N keyword representation (TF saturation / length-norm collapse here). A\n // query token that's rare across the repo counts for more than a common one.\n // Document frequency is computed over the candidate corpus for the query's\n // tokens only; `refIdf` (the query's mean IDF) normalizes the weighting so a\n // typical match still scores KW_BASE_WEIGHT — preserving the overall magnitude\n // and the confidence/Moat calibration, while reordering within the band.\n const corpusSize = inputs.candidates.length;\n const queryDf = new Map<string, number>();\n for (const f of inputs.candidates) {\n for (const kw of f.keywords) {\n if (qTokens.has(kw)) queryDf.set(kw, (queryDf.get(kw) ?? 0) + 1);\n }\n }\n const idf = (token: string): number => {\n const n = queryDf.get(token) ?? 0;\n if (n <= 0) return 0;\n return Math.log(1 + (corpusSize - n + 0.5) / (n + 0.5));\n };\n let idfSum = 0;\n let idfCount = 0;\n for (const t of qTokens) {\n const v = idf(t);\n if (v > 0) {\n idfSum += v;\n idfCount += 1;\n }\n }\n const refIdf = idfCount > 0 ? idfSum / idfCount : 1;\n\n // First pass: keyword + symbol score\n const scored: ScoredFile[] = [];\n for (const file of inputs.candidates) {\n const reasons: string[] = [];\n let score = 0;\n\n // Keyword overlap, IDF-weighted so a match on a rare query term outranks a\n // match on a common one (normalized to refIdf → magnitude-preserving).\n let kwHits = 0;\n let kwScore = 0;\n for (const kw of file.keywords) {\n if (!qTokens.has(kw)) continue;\n kwHits += 1;\n kwScore += KW_BASE_WEIGHT * (idf(kw) / refIdf);\n }\n if (kwHits) {\n score += kwScore;\n reasons.push(`kw=${kwHits}`);\n }\n\n // Symbol-name overlap (higher signal than file-level keywords)\n const symbols = symbolsByFile.get(file.path) ?? [];\n let symHits = 0;\n let exactSym = 0;\n for (const sym of symbols) {\n const name = sym.name.toLowerCase();\n if (qTokens.has(name)) {\n symHits += 3;\n exactSym += 1;\n } else {\n // partial match: any query token is a substring of, or contained by, the symbol name\n for (const t of qTokens) {\n if (name.includes(t) || t.includes(name)) {\n symHits += 1;\n break;\n }\n }\n }\n }\n if (symHits) {\n score += symHits;\n reasons.push(`sym=${symHits}`);\n }\n\n // Path match: file path contains a query token\n const pathLower = file.path.toLowerCase();\n let pathHits = 0;\n for (const t of qTokens) if (pathLower.includes(t)) pathHits += 1;\n if (pathHits) {\n score += pathHits;\n reasons.push(`path=${pathHits}`);\n }\n\n if (seeds.has(file.path)) {\n score += 5;\n reasons.push(\"seed\");\n }\n\n scored.push({ file, score, reasons, symHits, exactSym });\n }\n\n // Second pass: 1-hop import-graph boost from any file already scored > 0\n const positivePaths = new Set(scored.filter((s) => s.score > 0).map((s) => s.file.path));\n if (positivePaths.size > 0) {\n for (const s of scored) {\n if (s.score > 0) continue;\n // Does any file that imports this one have a positive score?\n let importBoost = 0;\n for (const [from, tos] of importsFrom) {\n if (!positivePaths.has(from)) continue;\n if (tos.has(s.file.path)) {\n importBoost += 1;\n break;\n }\n }\n if (importBoost) {\n s.score += importBoost * 0.5;\n s.reasons.push(\"imp-adj\");\n }\n }\n }\n\n // Usage-learning boost (learning v1): files the session has actually pulled or\n // edited get a small, decayed, capped bump so genuinely-hot files surface\n // first. Anchored to files that already match the query (score > 0) so a\n // popular-but-irrelevant file is never promoted; relatively normalized (u/maxU)\n // and capped below the +5 seed so it reorders within a band, never dominates.\n const usage = inputs.usageScores;\n if (usage && usage.size > 0) {\n let maxU = 0;\n for (const v of usage.values()) if (v > maxU) maxU = v;\n if (maxU > 0) {\n const cap = usageBoostCap();\n for (const s of scored) {\n if (s.score <= 0) continue;\n const u = usage.get(s.file.path) ?? 0;\n if (u <= 0) continue;\n s.score += cap * (u / maxU);\n s.reasons.push(`used×${Math.round(u)}`);\n }\n }\n }\n\n scored.sort((a, b) => b.score - a.score);\n return scored;\n}\n\nexport function rank(inputs: RankInputs): FileNode[] {\n return scoreFiles(inputs).map((s) => s.file);\n}\n","// Query-time retrieval. Given a natural-language query (or a symbol name),\n// returns a ranked list of FileNodes plus a confidence label.\n\nimport { scoreFiles, tokenizeQuery, type RankInputs } from \"./rank.js\";\nimport type { FileNode, GraphSchema } from \"./types.js\";\n\nexport interface RetrievalResult {\n files: FileNode[];\n confidence: \"high\" | \"medium\" | \"low\";\n reason: string;\n /** True if any returned file has a symbol whose name a query token matched\n * exactly — i.e. graph_read can serve a real `file::symbol` slice for this\n * query. When false, a Grep/Glob block would only force a fallback Read. */\n symbolMatched: boolean;\n}\n\nexport interface RetrieveOptions {\n topK?: number;\n recentlyEditedPaths?: string[];\n sessionKnownPaths?: string[];\n /** Decayed per-file usage weights from the learning layer. Passed straight\n * through to the ranker as a bounded boost on already-matching files. */\n usageScores?: ReadonlyMap<string, number>;\n}\n\nexport async function retrieve(\n graph: GraphSchema,\n query: string,\n options: RetrieveOptions = {},\n): Promise<RetrievalResult> {\n const topK = options.topK ?? 12;\n const qTokens = tokenizeQuery(query);\n\n const allFiles: FileNode[] = graph.nodes.filter((n): n is FileNode => n.kind === \"file\");\n\n if (allFiles.length === 0 || qTokens.length === 0) {\n return {\n files: [],\n confidence: \"low\",\n reason: qTokens.length === 0 ? \"empty query\" : \"empty graph\",\n symbolMatched: false,\n };\n }\n\n const rankInputs: RankInputs = {\n candidates: allFiles,\n query,\n graph,\n recentlyEditedPaths: options.recentlyEditedPaths,\n sessionKnownPaths: options.sessionKnownPaths,\n usageScores: options.usageScores,\n };\n const scored = scoreFiles(rankInputs);\n const positive = scored.filter((s) => s.score > 0);\n\n if (positive.length === 0) {\n return {\n files: [],\n confidence: \"low\",\n reason: `no matches for ${JSON.stringify(qTokens)}`,\n symbolMatched: false,\n };\n }\n\n const topScored = positive.slice(0, topK);\n const top = topScored.map((s) => s.file);\n const symbolMatched = topScored.some((s) => s.exactSym > 0);\n const topScore = positive[0]?.score ?? 0;\n const secondScore = positive[1]?.score ?? 0;\n\n // confidence: high = clear top match (2x next or only one hit)\n // medium = several hits but no dominant one\n // low = a few weak hits\n let confidence: \"high\" | \"medium\" | \"low\";\n if (positive.length === 1) confidence = \"high\";\n else if (topScore >= 6 && topScore >= secondScore * 2) confidence = \"high\";\n else if (topScore >= 3) confidence = \"medium\";\n else confidence = \"low\";\n\n const reasons = positive\n .slice(0, Math.min(3, top.length))\n .map((s) => `${s.file.path} (${s.reasons.join(\",\")})`)\n .join(\"; \");\n\n return {\n files: top,\n confidence,\n reason: `top: ${reasons}`,\n symbolMatched,\n };\n}\n","// Branch-aware routing for the context store.\n// On the default branch, reads/writes go to .synthra/context-store.json.\n// On a feature branch, they go to .synthra/branches/<sanitized-branch>/context-store.json.\n\nimport { execFile } from \"node:child_process\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\nexport async function currentBranch(projectRoot: string): Promise<string> {\n // Try .git/HEAD first — avoids the subprocess cost and works for detached\n // worktrees too (.git is a file there).\n try {\n const headPath = join(projectRoot, \".git\", \"HEAD\");\n const head = await readFile(headPath, \"utf8\");\n const trimmed = head.trim();\n const match = trimmed.match(/^ref:\\s+refs\\/heads\\/(.+)$/);\n if (match?.[1]) return match[1];\n // Detached HEAD — fall through\n } catch {\n // .git/HEAD unreadable (worktree file, submodule, or not a git repo)\n }\n\n try {\n const { stdout } = await execFileAsync(\"git\", [\"branch\", \"--show-current\"], {\n cwd: projectRoot,\n });\n const name = stdout.trim();\n if (name) return name;\n } catch {\n // git not on PATH or not a repo\n }\n\n return \"main\";\n}\n\nexport async function defaultBranch(projectRoot: string): Promise<string> {\n try {\n const { stdout } = await execFileAsync(\n \"git\",\n [\"symbolic-ref\", \"refs/remotes/origin/HEAD\", \"--short\"],\n { cwd: projectRoot },\n );\n const trimmed = stdout.trim();\n const match = trimmed.match(/^origin\\/(.+)$/);\n if (match?.[1]) return match[1];\n } catch {\n // No origin/HEAD set — fall back to heuristic\n }\n return \"main\";\n}\n\nexport function sanitizeBranchName(name: string): string {\n return name.replaceAll(\"/\", \"-\").replaceAll(\"\\\\\", \"-\");\n}\n\nexport interface BranchScopedPaths {\n contextStore: string;\n contextMd: string;\n branchDir: string | null;\n}\n\nexport function resolveBranchPaths(\n contextDir: string,\n branch: string,\n isDefault: boolean,\n): BranchScopedPaths {\n if (isDefault) {\n return {\n contextStore: join(contextDir, \"context-store.json\"),\n contextMd: join(contextDir, \"CONTEXT.md\"),\n branchDir: null,\n };\n }\n const branchDir = join(contextDir, \"branches\", sanitizeBranchName(branch));\n return {\n contextStore: join(branchDir, \"context-store.json\"),\n contextMd: join(branchDir, \"CONTEXT.md\"),\n branchDir,\n };\n}\n","// Free-form CONTEXT.md narrative. Updated by Stop hook at session end with:\n// - Current Task (1 sentence)\n// - Key Decisions (max 3 bullets)\n// - Next Steps (max 3 bullets)\n// Capped at ~20 visible content lines.\n\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport type { ContextEntry } from \"./context-store.js\";\n\nexport interface ContextMd {\n branch: string;\n currentTask: string;\n keyDecisions: string[];\n nextSteps: string[];\n date: string;\n}\n\nconst MAX_BULLETS = 3;\n\nexport function deriveContextMd(entries: ContextEntry[], branch: string): ContextMd {\n // Latest pending task drives \"current task\".\n const tasks = entries.filter((e) => e.type === \"task\").reverse();\n const currentTask = tasks[0]?.content ?? \"\";\n\n const keyDecisions = entries\n .filter((e) => e.type === \"decision\")\n .slice(-MAX_BULLETS)\n .map((e) => e.content);\n\n const nextSteps = entries\n .filter((e) => e.type === \"next\")\n .slice(-MAX_BULLETS)\n .map((e) => e.content);\n\n return {\n branch,\n currentTask,\n keyDecisions,\n nextSteps,\n date: new Date().toISOString(),\n };\n}\n\nexport function formatContextMd(ctx: ContextMd): string {\n const lines: string[] = [];\n lines.push(`# Context — ${ctx.branch}`);\n lines.push(\"\");\n lines.push(`_Updated: ${ctx.date}_`);\n lines.push(\"\");\n\n if (ctx.currentTask) {\n lines.push(`## Current task`);\n lines.push(ctx.currentTask);\n lines.push(\"\");\n }\n\n if (ctx.keyDecisions.length) {\n lines.push(`## Key decisions`);\n for (const d of ctx.keyDecisions) lines.push(`- ${d}`);\n lines.push(\"\");\n }\n\n if (ctx.nextSteps.length) {\n lines.push(`## Next steps`);\n for (const n of ctx.nextSteps) lines.push(`- ${n}`);\n lines.push(\"\");\n }\n\n if (!ctx.currentTask && !ctx.keyDecisions.length && !ctx.nextSteps.length) {\n lines.push(\"_(no context entries yet — use `context_remember` to add one)_\");\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n\nexport async function writeContextMd(path: string, ctx: ContextMd): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, formatContextMd(ctx), \"utf8\");\n}\n\nexport async function readContextMd(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf8\");\n } catch {\n return null;\n }\n}\n","// Structured decisions/tasks/facts that persist across sessions.\n// Stored in .synthra/ (GIT-TRACKED) so teammates inherit them.\n// Branch-partitioned via branches.ts.\n\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nexport type EntryKind = \"decision\" | \"task\" | \"next\" | \"fact\" | \"blocker\";\n\nexport interface ContextEntry {\n type: EntryKind;\n content: string;\n tags: string[];\n files: string[];\n date: string;\n /** Provenance. Reserved for v2 auto-capture; v1 only writes manual entries, so\n * the field is omitted today and read back as undefined (treated as manual). */\n source?: \"manual\" | \"auto\";\n}\n\ninterface Store {\n schema_version: number;\n entries: ContextEntry[];\n}\n\nconst SCHEMA_VERSION = 1;\n\nexport async function readEntries(path: string): Promise<ContextEntry[]> {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<Store>;\n return Array.isArray(parsed.entries) ? parsed.entries : [];\n } catch {\n return [];\n }\n}\n\nexport async function writeEntries(path: string, entries: ContextEntry[]): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n const store: Store = { schema_version: SCHEMA_VERSION, entries };\n await writeFile(path, JSON.stringify(store, null, 2) + \"\\n\", \"utf8\");\n}\n\nexport async function appendEntry(path: string, entry: ContextEntry): Promise<void> {\n const entries = await readEntries(path);\n entries.push(entry);\n await writeEntries(path, entries);\n}\n","// High-level orchestration: branch detection + store routing + CONTEXT.md\n// refresh in one call. Used by the MCP tools and the /context-update route.\n\nimport type { SynthraPaths } from \"../shared/paths.js\";\nimport {\n currentBranch,\n defaultBranch,\n resolveBranchPaths,\n type BranchScopedPaths,\n} from \"./branches.js\";\nimport { deriveContextMd, writeContextMd } from \"./context-md.js\";\nimport { appendEntry, readEntries, type ContextEntry, type EntryKind } from \"./context-store.js\";\n\nexport interface ActiveBranch {\n branch: string;\n isDefault: boolean;\n paths: BranchScopedPaths;\n}\n\nexport async function resolveActiveBranch(\n paths: SynthraPaths,\n override?: string,\n): Promise<ActiveBranch> {\n const branch = override ?? (await currentBranch(paths.projectRoot));\n const def = await defaultBranch(paths.projectRoot);\n const isDefault = branch === def;\n return {\n branch,\n isDefault,\n paths: resolveBranchPaths(paths.contextDir, branch, isDefault),\n };\n}\n\nexport interface RememberInput {\n text: string;\n kind: EntryKind;\n tags?: string[];\n files?: string[];\n}\n\nexport interface RememberResult {\n entry: ContextEntry;\n branch: string;\n storePath: string;\n contextMdPath: string;\n}\n\nexport async function rememberEntry(\n paths: SynthraPaths,\n input: RememberInput,\n): Promise<RememberResult> {\n const active = await resolveActiveBranch(paths);\n const entry: ContextEntry = {\n type: input.kind,\n content: input.text,\n tags: input.tags ?? [],\n files: input.files ?? [],\n date: new Date().toISOString(),\n };\n await appendEntry(active.paths.contextStore, entry);\n\n // Refresh CONTEXT.md so the narrative stays in sync with the structured store.\n const entries = await readEntries(active.paths.contextStore);\n const md = deriveContextMd(entries, active.branch);\n await writeContextMd(active.paths.contextMd, md);\n\n return {\n entry,\n branch: active.branch,\n storePath: active.paths.contextStore,\n contextMdPath: active.paths.contextMd,\n };\n}\n\nexport interface RecallInput {\n kind?: EntryKind;\n branch?: string;\n limit?: number;\n}\n\nexport interface RecallResult {\n branch: string;\n entries: ContextEntry[];\n storePath: string;\n}\n\nexport async function recallEntries(\n paths: SynthraPaths,\n input: RecallInput = {},\n): Promise<RecallResult> {\n const active = await resolveActiveBranch(paths, input.branch);\n let entries = await readEntries(active.paths.contextStore);\n if (input.kind) entries = entries.filter((e) => e.type === input.kind);\n if (input.limit && input.limit > 0) entries = entries.slice(-input.limit);\n return {\n branch: active.branch,\n entries,\n storePath: active.paths.contextStore,\n };\n}\n\nexport async function refreshContextMd(paths: SynthraPaths, branchOverride?: string) {\n const active = await resolveActiveBranch(paths, branchOverride);\n const entries = await readEntries(active.paths.contextStore);\n const md = deriveContextMd(entries, active.branch);\n await writeContextMd(active.paths.contextMd, md);\n return {\n branch: active.branch,\n path: active.paths.contextMd,\n entriesSeen: entries.length,\n };\n}\n","// Renders the final context pack as a single Markdown blob for Claude.\n\nexport interface FormatFileSection {\n path: string;\n reason?: string;\n signatures: string[];\n inlineBodies: string;\n associatedTests?: string[];\n}\n\nexport interface FormatInputs {\n query: string;\n files: FormatFileSection[];\n recentActivity?: string;\n truncated?: boolean;\n}\n\nexport function formatPack(inputs: FormatInputs): string {\n const parts: string[] = [];\n parts.push(`# Synthra context — query: ${JSON.stringify(inputs.query)}\\n`);\n\n if (inputs.files.length === 0) {\n parts.push(\"> No matching files found in the graph.\\n\");\n }\n\n for (const f of inputs.files) {\n const heading = f.reason ? `## ${f.path} _(${f.reason})_` : `## ${f.path}`;\n parts.push(heading);\n\n if (f.signatures.length === 0) {\n parts.push(\"_(no symbols extracted)_\");\n } else {\n parts.push(\"**Signatures:**\");\n for (const s of f.signatures) parts.push(`- ${s}`);\n }\n\n if (f.inlineBodies.trim().length > 0) {\n parts.push(\"\");\n parts.push(\"**Bodies:**\");\n parts.push(\"```\");\n parts.push(f.inlineBodies.trimEnd());\n parts.push(\"```\");\n }\n\n if (f.associatedTests?.length) {\n parts.push(\"\");\n parts.push(`**Tests:** ${f.associatedTests.join(\", \")}`);\n }\n\n parts.push(\"\");\n }\n\n if (inputs.recentActivity?.trim()) {\n parts.push(\"---\");\n parts.push(\"## Recent human activity\");\n parts.push(inputs.recentActivity.trim());\n parts.push(\"\");\n }\n\n if (inputs.truncated) {\n parts.push(\"> _(pack truncated to fit budget)_\");\n }\n\n return parts.join(\"\\n\");\n}\n","// Picks the top function bodies from a file (by relevance to the query) and\n// inlines them, respecting a char-based budget. Truncates oversized bodies.\n\nimport { tokenizeQuery } from \"../graph/rank.js\";\nimport type { FileNode, SymbolKind, SymbolNode } from \"../graph/types.js\";\n\nexport interface InlineSelection {\n text: string;\n charsUsed: number;\n functionsInlined: string[];\n}\n\nconst INLINABLE_KINDS = new Set<SymbolKind>([\"function\", \"method\", \"class\"]);\nconst MAX_BODY_CHARS = 1500;\n\nfunction sliceLines(content: string, startLine: number, endLine: number): string {\n const lines = content.split(/\\r?\\n/);\n return lines.slice(Math.max(0, startLine - 1), endLine).join(\"\\n\");\n}\n\nfunction scoreSymbol(name: string, qTokens: Set<string>): number {\n const lower = name.toLowerCase();\n if (qTokens.has(lower)) return 3;\n for (const t of qTokens) {\n if (lower.includes(t) || t.includes(lower)) return 1;\n }\n return 0;\n}\n\nfunction truncate(body: string): string {\n if (body.length <= MAX_BODY_CHARS) return body;\n return body.slice(0, MAX_BODY_CHARS).trimEnd() + \"\\n // … truncated\";\n}\n\nexport function selectInlineBodies(\n file: FileNode,\n symbols: SymbolNode[],\n query: string,\n budgetChars: number,\n): InlineSelection {\n if (budgetChars <= 0) {\n return { text: \"\", charsUsed: 0, functionsInlined: [] };\n }\n\n const qTokens = new Set(tokenizeQuery(query));\n const mine = symbols.filter((s) => s.file === file.path && INLINABLE_KINDS.has(s.symbol_kind));\n\n const scored = mine\n .map((s) => ({ sym: s, score: scoreSymbol(s.name, qTokens) }))\n .sort((a, b) => {\n if (b.score !== a.score) return b.score - a.score;\n // Tie-break: smaller bodies first (so we fit more)\n const aSpan = a.sym.end_line - a.sym.start_line || 1;\n const bSpan = b.sym.end_line - b.sym.start_line || 1;\n return aSpan - bSpan;\n });\n\n const parts: string[] = [];\n const inlined: string[] = [];\n let used = 0;\n\n for (const { sym, score } of scored) {\n // Skip irrelevant symbols entirely when we have positive hits available;\n // fall back to top-by-size if no query match landed.\n if (score === 0 && inlined.length > 0) break;\n\n const body = truncate(sliceLines(file.content, sym.start_line, sym.end_line));\n const header = `${file.path}::${sym.name} (L${sym.start_line}-${sym.end_line})`;\n const block = `${header}\\n${body}\\n`;\n if (used + block.length > budgetChars) {\n if (inlined.length > 0) break;\n // No room and nothing yet — take a head-only slice.\n const remaining = Math.max(0, budgetChars - used - header.length - 16);\n if (remaining <= 0) break;\n const partial = body.slice(0, remaining).trimEnd() + \"\\n // … truncated\";\n const finalBlock = `${header}\\n${partial}\\n`;\n parts.push(finalBlock);\n inlined.push(sym.name);\n used += finalBlock.length;\n break;\n }\n parts.push(block);\n inlined.push(sym.name);\n used += block.length;\n }\n\n return { text: parts.join(\"\\n\"), charsUsed: used, functionsInlined: inlined };\n}\n","// Extracts function/class signatures from a FileNode (no bodies).\n// Signatures are the first line of each symbol in the file, sorted by line.\n\nimport type { FileNode, SymbolNode } from \"../graph/types.js\";\n\nexport function extractSignatures(file: FileNode, symbols: SymbolNode[]): string[] {\n const mine = symbols\n .filter((s) => s.file === file.path)\n .slice()\n .sort((a, b) => a.start_line - b.start_line);\n\n return mine.map((s) => `L${s.start_line}: ${s.signature.trim()}`);\n}\n","// Test ↔ source co-retrieval. Given a source file, returns the test files\n// linked to it via `tests` edges in the graph (foo.test.ts → foo.ts).\n\nimport type { FileNode, GraphSchema } from \"../graph/types.js\";\n\nexport function findTestsForFile(graph: GraphSchema, file: FileNode): FileNode[] {\n // tests edges run from test file → source file\n const fileNodesById = new Map<string, FileNode>();\n for (const n of graph.nodes) {\n if (n.kind === \"file\") fileNodesById.set(n.id, n);\n }\n\n const out: FileNode[] = [];\n for (const e of graph.edges) {\n if (e.kind !== \"tests\" || e.to !== file.id) continue;\n const testFile = fileNodesById.get(e.from);\n if (testFile && !out.includes(testFile)) out.push(testFile);\n }\n return out;\n}\n","// Compresses a list of retrieved files into a structured context pack:\n// signatures + top function bodies + tests co-retrieved + dependency edges.\n// Budget is enforced in characters (~ tokens × 4) — see SYN_HARD_MAX_READ_CHARS.\n\nimport type { FileNode, GraphSchema, SymbolNode } from \"../graph/types.js\";\nimport { formatPack, type FormatFileSection } from \"./format.js\";\nimport { selectInlineBodies } from \"./inline.js\";\nimport { extractSignatures } from \"./signatures.js\";\nimport { findTestsForFile } from \"./tests.js\";\n\nexport interface PackOptions {\n query: string;\n graph: GraphSchema;\n /** Soft target for total tokens (≈ chars/4). Default: 4000. */\n budgetTokens?: number;\n /** Fraction of remaining budget to spend on a single file's inline bodies. Default: 0.5. */\n inlineBodyRatio?: number;\n /** Co-retrieve linked test files when packing source files. Default: true. */\n includeTests?: boolean;\n /** Optional: file path → reason string from the ranker, surfaced in the pack heading. */\n reasons?: Map<string, string>;\n}\n\nexport interface ContextPack {\n text: string;\n tokenEstimate: number;\n filesUsed: string[];\n testsCoRetrieved: string[];\n truncated: boolean;\n}\n\nconst STATIC_OVERHEAD_PER_FILE = 200; // headers + bullet markdown + spacing\nconst MAX_INLINE_CHARS_PER_FILE = 2500;\n\nfunction indexSymbolsByFile(graph: GraphSchema): SymbolNode[] {\n return graph.nodes.filter((n): n is SymbolNode => n.kind === \"symbol\");\n}\n\nexport async function pack(files: FileNode[], opts: PackOptions): Promise<ContextPack> {\n const budgetTokens = opts.budgetTokens ?? 4000;\n const budgetChars = budgetTokens * 4;\n const inlineRatio = opts.inlineBodyRatio ?? 0.5;\n const includeTests = opts.includeTests ?? true;\n const reasons = opts.reasons ?? new Map<string, string>();\n\n const symbols = indexSymbolsByFile(opts.graph);\n\n const sections: FormatFileSection[] = [];\n const testsCoRetrieved: string[] = [];\n let used = 0;\n let truncated = false;\n\n for (const file of files) {\n const sig = extractSignatures(file, symbols);\n const testFiles = includeTests ? findTestsForFile(opts.graph, file) : [];\n const testPaths = testFiles.map((t) => t.path);\n\n const staticCost =\n file.path.length +\n sig.join(\"\\n\").length +\n testPaths.join(\",\").length +\n STATIC_OVERHEAD_PER_FILE;\n\n if (used + staticCost > budgetChars) {\n truncated = true;\n break;\n }\n\n const remaining = budgetChars - used - staticCost;\n const inlineBudget = Math.min(Math.floor(remaining * inlineRatio), MAX_INLINE_CHARS_PER_FILE);\n\n const inline = selectInlineBodies(file, symbols, opts.query, inlineBudget);\n\n sections.push({\n path: file.path,\n reason: reasons.get(file.path),\n signatures: sig,\n inlineBodies: inline.text,\n associatedTests: testPaths,\n });\n\n used += staticCost + inline.charsUsed;\n for (const t of testPaths) if (!testsCoRetrieved.includes(t)) testsCoRetrieved.push(t);\n\n if (used >= budgetChars) {\n truncated = true;\n break;\n }\n }\n\n if (sections.length < files.length) truncated = true;\n\n const text = formatPack({\n query: opts.query,\n files: sections,\n truncated,\n });\n const tokenEstimate = Math.ceil(text.length / 4);\n\n return {\n text,\n tokenEstimate,\n filesUsed: sections.map((s) => s.path),\n testsCoRetrieved,\n truncated,\n };\n}\n","// Environment-variable-driven configuration.\n// All knobs are prefixed SYN_.\n\nexport interface SynthraConfig {\n hardMaxReadChars: number;\n gateHintMaxChars: number;\n readDepsMaxChars: number;\n turnReadBudgetChars: number;\n fallbackMaxCallsPerTurn: number;\n retrieveCacheTtlSec: number;\n mcpPort: number | null;\n dashboardPort: number;\n logLevel: \"debug\" | \"info\" | \"warn\" | \"error\";\n claudeBin: string;\n}\n\nfunction num(name: string, fallback: number): number {\n const v = process.env[name];\n if (!v) return fallback;\n const n = Number(v);\n return Number.isFinite(n) ? n : fallback;\n}\n\nfunction str<T extends string>(name: string, fallback: T): T {\n return (process.env[name] as T) ?? fallback;\n}\n\nexport function loadConfig(): SynthraConfig {\n return {\n hardMaxReadChars: num(\"SYN_HARD_MAX_READ_CHARS\", 4000),\n gateHintMaxChars: num(\"SYN_GATE_HINT_CHARS\", 1200),\n readDepsMaxChars: num(\"SYN_READ_DEPS_CHARS\", 900),\n turnReadBudgetChars: num(\"SYN_TURN_READ_BUDGET_CHARS\", 18000),\n fallbackMaxCallsPerTurn: num(\"SYN_FALLBACK_MAX_CALLS_PER_TURN\", 1),\n retrieveCacheTtlSec: num(\"SYN_RETRIEVE_CACHE_TTL_SEC\", 900),\n mcpPort: process.env.SYN_MCP_PORT ? num(\"SYN_MCP_PORT\", 0) : null,\n dashboardPort: num(\"SYN_DASHBOARD_PORT\", 8901),\n logLevel: str(\"SYN_LOG_LEVEL\", \"info\" as const),\n claudeBin: str(\"SYN_CLAUDE_BIN\", \"claude\" as const),\n };\n}\n","// GET /activity?since=<ms> — returns recent human-activity events.\n// Backed by the in-memory ActivityStore (file-watcher + git-watcher feed it).\n// MCP tool `recent_activity` is a thin wrapper.\n\nimport type { ActivityEvent } from \"../../activity/activity-log.js\";\nimport type { ServerContext } from \"../context.js\";\n\nexport interface ActivityResponse {\n events: ActivityEvent[];\n since: string;\n ring_size: number;\n}\n\nexport async function handleActivity(\n sinceMs: number | undefined,\n ctx: ServerContext,\n): Promise<ActivityResponse> {\n const events = ctx.activity.getEvents(sinceMs);\n return {\n events,\n since: new Date(sinceMs ?? Date.now()).toISOString(),\n ring_size: ctx.activity.size(),\n };\n}\n","// Thin git helpers for the session snapshot: commits since a timestamp and the\n// files changed in the latest commit. Best-effort — returns empty on no git /\n// not a repo, so the snapshot (and the resume digest built from it) degrades\n// gracefully. Mirrors the execFileAsync pattern in branches.ts / git-watcher.ts.\n\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nimport type { SessionCommit } from \"./session.js\";\n\nconst execFileAsync = promisify(execFile);\n\nconst MAX_COMMITS = 5;\nconst FIELD = \"\\x1f\"; // unit separator — safe delimiter inside commit subjects\n\n/** Commits since `sinceIso`, newest first, capped at MAX_COMMITS. When `sinceIso`\n * is empty/invalid (first run), returns the most recent MAX_COMMITS as\n * orientation rather than dumping the entire history. */\nexport async function getCommitsSince(\n projectRoot: string,\n sinceIso: string,\n): Promise<SessionCommit[]> {\n const args = [\n \"log\",\n `--max-count=${MAX_COMMITS}`,\n \"--no-merges\",\n `--pretty=format:%h${FIELD}%s${FIELD}%aI`,\n ];\n if (Number.isFinite(Date.parse(sinceIso))) args.push(`--since=${sinceIso}`);\n\n try {\n const { stdout } = await execFileAsync(\"git\", args, { cwd: projectRoot });\n const out: SessionCommit[] = [];\n for (const line of stdout.split(\"\\n\")) {\n const t = line.trim();\n if (!t) continue;\n const [hash, message, date] = t.split(FIELD);\n if (hash && message) out.push({ hash, message, date: date ?? \"\" });\n }\n return out;\n } catch {\n return [];\n }\n}\n\n/** Files changed in the latest commit (name-only). Empty on no git / shallow. */\nexport async function getDiffFiles(projectRoot: string): Promise<string[]> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"diff\", \"--name-only\", \"HEAD~1..HEAD\"], {\n cwd: projectRoot,\n });\n return stdout\n .split(\"\\n\")\n .map((s) => s.trim())\n .filter(Boolean);\n } catch {\n return [];\n }\n}\n","// Per-session snapshot, captured at session end (Stop hook → /context-update)\n// and read by the SessionStart primer to build the \"Since you were last here\"\n// resume digest. Persisted to .synthra-graph/session.json (machine-local,\n// gitignored): it describes THIS machine's last session and is regenerated every\n// Stop, so there is no migration — a schema mismatch is simply treated as\n// \"no snapshot\" and the primer degrades to its legacy output.\n\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nexport const SESSION_SCHEMA_VERSION = 1;\n\nexport interface SessionCommit {\n hash: string;\n message: string;\n date: string;\n}\n\nexport interface SessionSummary {\n tasks: string[];\n decisions: string[];\n next: string[];\n}\n\nexport interface SessionState {\n schema_version: number;\n endedAt: string;\n branch: string;\n filesTouched: string[];\n recentCommits: SessionCommit[];\n summary: SessionSummary;\n}\n\nexport async function readSession(path: string): Promise<SessionState | null> {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<SessionState>;\n if (parsed.schema_version !== SESSION_SCHEMA_VERSION) return null;\n return parsed as SessionState;\n } catch {\n return null;\n }\n}\n\nexport async function writeSession(path: string, state: SessionState): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, JSON.stringify(state, null, 2) + \"\\n\", \"utf8\");\n}\n","// POST /context-update — Stop hook calls this at session end.\n// 1. Re-renders CONTEXT.md from the branch-scoped store so the narrative stays\n// in sync with the structured entries that landed during the session.\n// 2. Captures a session snapshot (git diff since last session + files touched +\n// open decisions/next-steps) to .synthra-graph/session.json, which the next\n// SessionStart primer reads to build a \"Since you were last here\" digest.\n// Transcript-mining for new entries (auto \"we decided X\" → store) is deferred.\n\nimport { getCommitsSince } from \"../../memory/git-snapshot.js\";\nimport { recallEntries, refreshContextMd, resolveActiveBranch } from \"../../memory/index.js\";\nimport {\n readSession,\n writeSession,\n SESSION_SCHEMA_VERSION,\n type SessionState,\n} from \"../../memory/session.js\";\nimport type { ServerContext } from \"../context.js\";\nimport { getRegisteredEdits } from \"../mcp.js\";\n\nexport interface ContextUpdateRequest {\n transcript_path?: string;\n branch?: string;\n}\n\nexport interface ContextUpdateResponse {\n updated: boolean;\n branch: string;\n path: string;\n entries: number;\n}\n\n// Window for \"files the human touched this session\" harvested from the activity\n// ring at Stop. Generous — a session can be long, and the ring is bounded anyway.\nconst TOUCHED_WINDOW_MS = 24 * 60 * 60 * 1000;\n\nasync function captureSnapshot(ctx: ServerContext, branchOverride?: string): Promise<void> {\n const active = await resolveActiveBranch(ctx.paths, branchOverride);\n\n const [tasks, decisions, next] = await Promise.all([\n recallEntries(ctx.paths, { kind: \"task\", branch: active.branch, limit: 1 }),\n recallEntries(ctx.paths, { kind: \"decision\", branch: active.branch, limit: 3 }),\n recallEntries(ctx.paths, { kind: \"next\", branch: active.branch, limit: 3 }),\n ]);\n\n // Files touched this session: AI-registered edits ∪ recent human saves.\n const touched = new Set<string>(getRegisteredEdits());\n for (const p of ctx.activity.recentFilePaths(TOUCHED_WINDOW_MS)) touched.add(p);\n\n // Commits since the previous snapshot (or the most recent few on first run).\n const prev = await readSession(ctx.paths.sessionState);\n const recentCommits = await getCommitsSince(ctx.paths.projectRoot, prev?.endedAt ?? \"\");\n\n const snapshot: SessionState = {\n schema_version: SESSION_SCHEMA_VERSION,\n endedAt: new Date().toISOString(),\n branch: active.branch,\n filesTouched: Array.from(touched),\n recentCommits,\n summary: {\n tasks: tasks.entries.map((e) => e.content),\n decisions: decisions.entries.map((e) => e.content),\n next: next.entries.map((e) => e.content),\n },\n };\n await writeSession(ctx.paths.sessionState, snapshot);\n}\n\nexport async function handleContextUpdate(\n req: ContextUpdateRequest,\n ctx: ServerContext,\n): Promise<ContextUpdateResponse> {\n const r = await refreshContextMd(ctx.paths, req?.branch);\n\n // Best-effort: a snapshot failure (no git, unwritable disk) must never break\n // the CONTEXT.md refresh that downstream tooling relies on.\n try {\n await captureSnapshot(ctx, req?.branch);\n } catch {\n // ignore — the resume digest just falls back to the legacy primer next time.\n }\n\n return {\n updated: true,\n branch: r.branch,\n path: r.path,\n entries: r.entriesSeen,\n };\n}\n","// POST /gate — PreToolUse hook calls this with the tool name + arguments.\n// THE MOAT — improvement #1. Strategy:\n// - For Grep/Glob: extract the search pattern, run retrieve().\n// - If recent human activity touches a file matching the query → ALLOW\n// even at high confidence (the user's head is in that file; static\n// context may be stale).\n// - If confidence === \"high\" and no recent overlap → BLOCK. The deny reason\n// carries the answer: exact file::symbol graph_read targets + one-line\n// signatures, so the agent never needs the whole-file Read fallback.\n// - Otherwise → ALLOW.\n\nimport { appendFile, mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { retrieve } from \"../../graph/retrieve.js\";\nimport type { RetrievalResult } from \"../../graph/retrieve.js\";\nimport { tokenizeQuery } from \"../../graph/rank.js\";\nimport type { GraphSchema, SymbolNode } from \"../../graph/types.js\";\nimport { loadConfig } from \"../../shared/config.js\";\nimport type { ServerContext } from \"../context.js\";\n\nexport interface GateRequest {\n tool_name: string;\n tool_input: Record<string, unknown>;\n}\n\nexport interface GateResponse {\n decision: \"allow\" | \"block\";\n reason?: string;\n}\n\nconst BLOCKABLE_TOOLS = new Set([\"Grep\", \"Glob\"]);\nconst RECENT_ACTIVITY_WINDOW_MS = 5 * 60 * 1000;\n\nfunction extractQuery(toolName: string, input: Record<string, unknown>): string | null {\n if (toolName === \"Grep\") {\n const pattern = typeof input.pattern === \"string\" ? input.pattern : \"\";\n const query = typeof input.query === \"string\" ? input.query : \"\";\n return (pattern || query).trim() || null;\n }\n if (toolName === \"Glob\") {\n const pattern = typeof input.pattern === \"string\" ? input.pattern : \"\";\n return pattern.replace(/[*?/\\\\.]+/g, \" \").trim() || null;\n }\n return null;\n}\n\n// Heuristic: does this Grep pattern target markup / CSS / attributes / literals\n// rather than a code symbol? The graph only indexes symbols, so blocking these\n// and redirecting to graph_read just forces a fallback Read. Conservative — only\n// fires on syntax that never appears in a bare identifier search.\nfunction looksLikeNonSymbolQuery(pattern: string): boolean {\n // HTML / JSX tag: \"<div\", \"</\", \"<svg\"\n if (/<\\/?[a-zA-Z]/.test(pattern)) return true;\n // Hyphenated attribute assignment: \"data-tour=\", \"aria-label=\" ('-' is not a\n // valid identifier char, so this is markup, not a symbol).\n if (/[a-zA-Z][\\w-]*-[\\w-]*\\s*=/.test(pattern)) return true;\n // CSS rule / object brace: \".content{\", \"{ color\"\n if (/\\{/.test(pattern)) return true;\n // Escaped-dot class / member selector: \"\\.filter-bar\", \"\\.gs\"\n if (/\\\\\\.[a-zA-Z]/.test(pattern)) return true;\n // CSS property value or units: \": 100%\", \"12px\", \"1.5rem\", \"50%\"\n if (/:\\s*\\d/.test(pattern) || /\\d(?:px|rem|em|vh|vw)\\b/.test(pattern) || /\\d%/.test(pattern)) {\n return true;\n }\n // CSS custom property: \"var(--brand)\", \"--sidebar\" — a \"--\" prefix is never a\n // valid code identifier, so this is styling the graph doesn't index.\n if (/--[a-zA-Z]/.test(pattern)) return true;\n // Hex color literal: \"#fff\", \"#0a0a0a\".\n if (/#[0-9a-fA-F]{3,8}\\b/.test(pattern)) return true;\n // Kebab-case search (\"cw-code-chip\", \"data-tour\") — hyphens aren't valid in\n // JS/TS/Python identifiers, so it's a CSS class / HTML attribute / custom\n // element. Only treat it as non-symbol when EVERY alternation branch is kebab,\n // so a mixed query like \"fetchWith429Retry|Retry-After\" (real symbol + a\n // hyphenated header) still blocks. Strip regex char-classes first so a range\n // like \"[a-z]\" isn't mistaken for a kebab token.\n const branches = pattern\n .replace(/\\[[^\\]]*\\]/g, \"\")\n .split(\"|\")\n .map((b) => b.trim())\n .filter(Boolean);\n const isKebab = (b: string) => /^[a-z][a-z0-9]*(?:-[a-z0-9]+)+$/i.test(b);\n if (branches.length > 0 && branches.every(isKebab)) return true;\n return false;\n}\n\n// A recently-touched file \"matches\" the query if a query token appears in its\n// PATH or in its graph-node KEYWORDS (file contents). The content-keyword check\n// (#3) means a recent save of e.g. auth.ts relaxes `Grep \"login\"` when auth.ts\n// contains login — not only when the path itself contains the token.\nfunction recentlyTouchedMatchesQuery(\n recentPaths: string[],\n queryTokens: Set<string>,\n graph: GraphSchema,\n): string[] {\n if (recentPaths.length === 0) return [];\n\n // Pull keywords for the recently-touched files in a single graph pass.\n const recent = new Set(recentPaths);\n const keywordsByPath = new Map<string, string[]>();\n for (const n of graph.nodes) {\n if (n.kind === \"file\" && recent.has(n.path)) keywordsByPath.set(n.path, n.keywords);\n }\n\n const matches: string[] = [];\n for (const path of recentPaths) {\n const lower = path.toLowerCase();\n let matched = false;\n for (const t of queryTokens) {\n if (lower.includes(t)) {\n matched = true;\n break;\n }\n }\n if (!matched) {\n for (const kw of keywordsByPath.get(path) ?? []) {\n if (queryTokens.has(kw)) {\n matched = true;\n break;\n }\n }\n }\n if (matched) matches.push(path);\n }\n return matches;\n}\n\n// Block hints can run to ~1200 chars; the log (and the dashboard /data payload\n// built from it) only needs enough to identify the decision, so the stored\n// reason is truncated and the full hint size is kept as a separate count.\nconst LOG_REASON_MAX_CHARS = 240;\n\nasync function logDecision(\n ctx: ServerContext,\n toolName: string,\n query: string | null,\n decision: \"allow\" | \"block\",\n reason: string | undefined,\n hintChars?: number,\n): Promise<void> {\n try {\n await mkdir(dirname(ctx.paths.gateLog), { recursive: true });\n const entry = {\n ts: new Date().toISOString(),\n tool: toolName,\n decision,\n query,\n reason:\n reason && reason.length > LOG_REASON_MAX_CHARS\n ? `${reason.slice(0, LOG_REASON_MAX_CHARS)}…`\n : reason,\n ...(hintChars === undefined ? {} : { hint_chars: hintChars }),\n };\n await appendFile(ctx.paths.gateLog, JSON.stringify(entry) + \"\\n\", \"utf8\");\n } catch {\n // Durability is best-effort; an unwritable disk shouldn't fail the gate.\n }\n}\n\nconst SIG_LINE_MAX_CHARS = 140;\n\n// How relevant is a symbol name to the query? Mirrors the packer's inline\n// scoring: exact token match dominates, substring containment is a weak hit.\nfunction scoreSymbolName(name: string, qTokens: string[]): number {\n const lower = name.toLowerCase();\n let score = 0;\n for (const t of qTokens) {\n if (t === lower) score += 3;\n else if (t.length >= 3 && lower.includes(t)) score += 1;\n }\n return score;\n}\n\n/**\n * Render the deny reason for a block. Instead of bare file paths (which sent\n * agents into whole-file Read fallbacks — see the dogfood log), the hint\n * delivers copy-pasteable namespaced graph_read targets plus one-line\n * signatures for the query's best symbols. Signatures only, no bodies: the\n * hint lands in the transcript on every block, so its own size is a cost.\n */\nexport function buildBlockHint(\n query: string,\n retrieval: RetrievalResult,\n graph: GraphSchema,\n toolName: string,\n maxChars = loadConfig().gateHintMaxChars,\n): string {\n const topFiles = retrieval.files.slice(0, 3);\n const topPaths = new Set(topFiles.map((f) => f.path));\n\n const symsByFile = new Map<string, SymbolNode[]>();\n for (const n of graph.nodes) {\n if (n.kind !== \"symbol\" || !topPaths.has(n.file)) continue;\n const list = symsByFile.get(n.file);\n if (list) list.push(n);\n else symsByFile.set(n.file, [n]);\n }\n\n const qTokens = tokenizeQuery(query);\n const entries: string[] = [];\n for (const f of topFiles) {\n const syms = (symsByFile.get(f.path) ?? []).slice().sort((a, b) => a.start_line - b.start_line);\n if (syms.length === 0) {\n // Content-indexed only (no symbols) — still point at the slice tool.\n entries.push(`• mcp__synthra__graph_read(\"${f.path}\")`);\n continue;\n }\n const scored = syms\n .map((s) => ({ s, score: scoreSymbolName(s.name, qTokens) }))\n .filter((x) => x.score > 0)\n .sort((a, b) => b.score - a.score);\n // Best 1–2 query-relevant symbols; when nothing scores, the file's first\n // symbol still gives the agent a foothold into the file.\n const picks = scored.length > 0 ? scored.slice(0, 2).map((x) => x.s) : syms.slice(0, 1);\n for (const s of picks) {\n const sig = `L${s.start_line}: ${s.signature.trim()}`;\n const sigLine =\n sig.length > SIG_LINE_MAX_CHARS ? `${sig.slice(0, SIG_LINE_MAX_CHARS - 1)}…` : sig;\n entries.push(`• mcp__synthra__graph_read(\"${f.path}::${s.name}\")\\n ${sigLine}`);\n }\n }\n\n const header =\n `Synthra blocked this ${toolName} — ${retrieval.confidence}-confidence context for \"${query}\" already exists.\\n` +\n `Read symbols directly (~50 tokens each) instead of whole files:\\n`;\n const footer = `\\nFull pack: mcp__synthra__graph_continue(\"${query}\")`;\n\n const parts: string[] = [];\n let used = header.length + footer.length + 1;\n for (const e of entries) {\n if (used + e.length + 1 > maxChars) break; // drop whole entries, never mid-entry\n parts.push(e);\n used += e.length + 1;\n }\n\n if (parts.length === 0) {\n // Degenerate budget — fall back to the legacy path list, namespaced.\n const top = topFiles.map((f) => f.path).join(\", \");\n return (\n `Synthra has ${retrieval.confidence}-confidence context for \"${query}\" (top files: ${top}). ` +\n `Use mcp__synthra__graph_continue(\"${query}\") instead of ${toolName}, ` +\n `or read a specific file/symbol with mcp__synthra__graph_read.`\n );\n }\n\n return `${header}\\n${parts.join(\"\\n\")}\\n${footer}`;\n}\n\nexport async function handleGate(req: GateRequest, ctx: ServerContext): Promise<GateResponse> {\n if (!req?.tool_name || typeof req.tool_name !== \"string\") {\n return { decision: \"allow\", reason: \"no tool_name\" };\n }\n\n if (!BLOCKABLE_TOOLS.has(req.tool_name)) {\n return { decision: \"allow\" };\n }\n\n const input = (\n req.tool_input && typeof req.tool_input === \"object\" ? req.tool_input : {}\n ) as Record<string, unknown>;\n const query = extractQuery(req.tool_name, input);\n if (!query) {\n const res: GateResponse = { decision: \"allow\", reason: \"no extractable query\" };\n await logDecision(ctx, req.tool_name, null, res.decision, res.reason);\n return res;\n }\n\n // Guard 1 — the query targets markup/CSS/attributes/literals, which the graph\n // does not index. Blocking would only force a fallback, so let Grep through.\n if (req.tool_name === \"Grep\" && looksLikeNonSymbolQuery(query)) {\n const res: GateResponse = {\n decision: \"allow\",\n reason: `\"${query}\" targets markup/CSS/attributes, not code symbols — letting Grep through (the graph indexes symbols).`,\n };\n await logDecision(ctx, req.tool_name, query, res.decision, res.reason);\n return res;\n }\n\n const retrieval = await retrieve(ctx.graph, query);\n // \"low\" = no real matches → let Grep through; Synthra has nothing useful.\n // \"medium\" + \"high\" = Synthra has structured context for this query →\n // bias toward blocking. The pitch (\"use graph_continue instead of Grep\")\n // holds at medium too — on real codebases of any size, \"high\" is rare\n // because almost every query matches multiple files.\n if (retrieval.confidence === \"low\") {\n const res: GateResponse = {\n decision: \"allow\",\n reason: `confidence=low — no graph context for \"${query}\", letting ${req.tool_name} through`,\n };\n await logDecision(ctx, req.tool_name, query, res.decision, res.reason);\n return res;\n }\n\n // Medium / high — but check if recent activity overlaps the query first.\n // If the user just touched a file matching the query, static context may\n // be stale and they probably want a fresh search.\n const qTokens = new Set(tokenizeQuery(query));\n const recentPaths = ctx.activity.recentFilePaths(RECENT_ACTIVITY_WINDOW_MS);\n const overlap = recentlyTouchedMatchesQuery(recentPaths, qTokens, ctx.graph);\n\n if (overlap.length > 0) {\n const res: GateResponse = {\n decision: \"allow\",\n reason:\n `confidence=${retrieval.confidence} but human just touched ${overlap.slice(0, 3).join(\", \")} — ` +\n `static context may be stale, letting ${req.tool_name} through.`,\n };\n await logDecision(ctx, req.tool_name, query, res.decision, res.reason);\n return res;\n }\n\n // Guard 2 — the graph matched files only by keyword/path, not by a symbol the\n // query names, so graph_read can't return a real slice. A block would just\n // force a fallback Read; let the search through instead.\n if (!retrieval.symbolMatched) {\n const res: GateResponse = {\n decision: \"allow\",\n reason:\n `confidence=${retrieval.confidence} but only keyword/path matched (no symbol the query names) — ` +\n `graph_read can't slice it, letting ${req.tool_name} through.`,\n };\n await logDecision(ctx, req.tool_name, query, res.decision, res.reason);\n return res;\n }\n\n const hint = buildBlockHint(query, retrieval, ctx.graph, req.tool_name);\n const res: GateResponse = { decision: \"block\", reason: hint };\n await logDecision(ctx, req.tool_name, query, res.decision, hint, hint.length);\n return res;\n}\n","// POST /log — Stop hook posts per-turn token usage parsed from Claude's\n// transcript JSONL. Synthra appends each entry as one line to token_log.jsonl.\n\nimport { appendFile, mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport type { ServerContext } from \"../context.js\";\n\nexport interface LogEntry {\n input_tokens: number;\n output_tokens: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n model: string;\n description?: string;\n project: string;\n}\n\nexport interface LogResponse {\n ok: true;\n written_at: string;\n}\n\nexport async function handleLog(entry: LogEntry, ctx: ServerContext): Promise<LogResponse> {\n if (!entry || typeof entry.input_tokens !== \"number\" || typeof entry.output_tokens !== \"number\") {\n throw new Error(\"log: input_tokens and output_tokens (number) are required\");\n }\n\n const written_at = new Date().toISOString();\n const record = { ...entry, written_at };\n await mkdir(dirname(ctx.paths.tokenLog), { recursive: true });\n await appendFile(ctx.paths.tokenLog, JSON.stringify(record) + \"\\n\", \"utf8\");\n\n return { ok: true, written_at };\n}\n","// POST /pack { query, maxTokens? } → ContextPack JSON.\n// Runs retrieve → pack against the in-memory graph.\n\nimport { retrieve } from \"../../graph/retrieve.js\";\nimport { scoreFiles } from \"../../graph/rank.js\";\nimport { pack, type ContextPack } from \"../../packer/index.js\";\nimport type { ServerContext } from \"../context.js\";\n\nexport interface PackRequest {\n query: string;\n maxTokens?: number;\n includeTests?: boolean;\n}\n\nexport interface PackResponse extends ContextPack {\n query: string;\n confidence: \"high\" | \"medium\" | \"low\";\n retrievalReason: string;\n}\n\nexport async function handlePack(req: PackRequest, ctx: ServerContext): Promise<PackResponse> {\n if (!req?.query || typeof req.query !== \"string\") {\n throw new Error(\"pack: 'query' (string) is required\");\n }\n\n const recentlyEditedPaths = ctx.activity.recentFilePaths(15 * 60 * 1000);\n const usageScores = ctx.learn?.effectiveScores();\n const retrieval = await retrieve(ctx.graph, req.query, { recentlyEditedPaths, usageScores });\n\n // Surface per-file scoring rationale in the rendered pack.\n const allFiles = ctx.graph.nodes.filter((n) => n.kind === \"file\");\n const scored = scoreFiles({\n candidates: allFiles as Parameters<typeof scoreFiles>[0][\"candidates\"],\n query: req.query,\n graph: ctx.graph,\n recentlyEditedPaths,\n usageScores,\n });\n const reasons = new Map<string, string>();\n for (const s of scored) {\n if (s.reasons.length) reasons.set(s.file.path, s.reasons.join(\",\"));\n }\n\n const result = await pack(retrieval.files, {\n query: req.query,\n graph: ctx.graph,\n budgetTokens: req.maxTokens,\n includeTests: req.includeTests,\n reasons,\n });\n\n return {\n ...result,\n query: req.query,\n confidence: retrieval.confidence,\n retrievalReason: retrieval.reason,\n };\n}\n","// GET /prime — SessionStart and PreCompact hooks call this. Returns the priming\n// text Claude sees at session start.\n//\n// When the previous session left a snapshot (.synthra-graph/session.json), the\n// primer leads with a budget-bounded \"Since you were last here\" digest — recent\n// commits, files touched, open next-steps, recent decisions — so a fresh session\n// arrives oriented instead of re-paying tokens to rediscover recent work. With\n// no snapshot (first session, or none survived), it falls back to the legacy\n// graph-counts primer verbatim.\n\nimport { currentBranch } from \"../../memory/branches.js\";\nimport { readSession, type SessionState } from \"../../memory/session.js\";\nimport type { ServerContext } from \"../context.js\";\n\nexport interface PrimeResponse {\n primer: string;\n port: number;\n}\n\n// ~680 tokens. The digest rides the SessionStart primer channel, separate from\n// the graph pack's own ~4000-token budget — they don't compete.\nconst RESUME_PRIMER_MAX_CHARS = 2720;\n\nconst MAX_FILES = 15;\nconst MAX_COMMITS = 5;\nconst MAX_BULLETS = 3;\n\nfunction legacyPrimer(ctx: ServerContext): string {\n const g = ctx.graph;\n return (\n `Synthra context loaded for ${g.root}.\\n` +\n `${g.file_count} files indexed, ${g.symbol_count} symbols. ` +\n `Prefer the graph_* MCP tools over Grep/Glob for navigation.`\n );\n}\n\nfunction hasContent(snap: SessionState): boolean {\n return Boolean(\n snap.recentCommits.length ||\n snap.filesTouched.length ||\n snap.summary.tasks.length ||\n snap.summary.next.length ||\n snap.summary.decisions.length,\n );\n}\n\nfunction buildResumeDigest(snap: SessionState, branchNow: string): string {\n const plural = (n: number) => (n === 1 ? \"\" : \"s\");\n const head =\n `## Since you were last here — ${snap.branch} ` +\n `(${snap.recentCommits.length} commit${plural(snap.recentCommits.length)}, ` +\n `${snap.filesTouched.length} file${plural(snap.filesTouched.length)} touched)`;\n\n // Essential, high-signal block — never dropped under the budget.\n const essential: string[] = [head];\n if (snap.branch !== branchNow) {\n essential.push(\"\");\n essential.push(\n `_(snapshot was for branch '${snap.branch}'; you're now on '${branchNow}' — may be stale)_`,\n );\n }\n if (snap.summary.tasks[0]) {\n essential.push(\"\", \"### In progress\", `- ${snap.summary.tasks[0]}`);\n }\n if (snap.summary.next.length) {\n essential.push(\"\", \"### Open next steps\");\n for (const n of snap.summary.next.slice(0, MAX_BULLETS)) essential.push(`- ${n}`);\n }\n if (snap.summary.decisions.length) {\n essential.push(\"\", \"### Recent decisions\");\n for (const d of snap.summary.decisions.slice(0, MAX_BULLETS)) essential.push(`- ${d}`);\n }\n\n // Supporting context — appended only while budget remains, so commits/files\n // are what get dropped first if we're over the cap.\n const extra: string[] = [];\n if (snap.recentCommits.length) {\n extra.push(\"\", \"### Recent commits\");\n for (const c of snap.recentCommits.slice(0, MAX_COMMITS)) {\n const date = c.date ? ` (${c.date.slice(0, 10)})` : \"\";\n extra.push(`- \\`${c.hash}\\` ${c.message}${date}`);\n }\n }\n if (snap.filesTouched.length) {\n const shown = snap.filesTouched.slice(0, MAX_FILES);\n const more = snap.filesTouched.length - shown.length;\n extra.push(\"\", \"### Files touched\", shown.join(\", \") + (more > 0 ? `, +${more} more` : \"\"));\n }\n\n let out = essential.join(\"\\n\");\n for (const line of extra) {\n if ((out + \"\\n\" + line).length > RESUME_PRIMER_MAX_CHARS) break;\n out += \"\\n\" + line;\n }\n return (\n out.length > RESUME_PRIMER_MAX_CHARS ? out.slice(0, RESUME_PRIMER_MAX_CHARS) : out\n ).trimEnd();\n}\n\nexport async function handlePrime(ctx: ServerContext, port: number): Promise<PrimeResponse> {\n const legacy = legacyPrimer(ctx);\n\n const snap = await readSession(ctx.paths.sessionState);\n if (!snap || !hasContent(snap)) {\n return { primer: legacy, port };\n }\n\n const branchNow = await currentBranch(ctx.paths.projectRoot);\n const digest = buildResumeDigest(snap, branchNow);\n return { primer: `${digest}\\n\\n---\\n\\n${legacy}`, port };\n}\n","// Locate the most recently modified Claude session transcript for a project.\n// Claude Code stores them at: ~/.claude/projects/<encoded-cwd>/<session-uuid>.jsonl\n// where `encoded-cwd` replaces ANY of \\ / : with -.\n\nimport { readdir, stat } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport interface DiscoveredSession {\n sessionId: string;\n transcriptPath: string;\n modifiedAt: Date;\n}\n\nexport function encodeProjectPath(projectRoot: string): string {\n return projectRoot.replace(/[\\\\/:]/g, \"-\");\n}\n\nexport async function findLatestSession(projectRoot: string): Promise<DiscoveredSession | null> {\n const encoded = encodeProjectPath(projectRoot);\n const dir = join(homedir(), \".claude\", \"projects\", encoded);\n\n let entries: string[];\n try {\n entries = await readdir(dir);\n } catch {\n return null;\n }\n\n const jsonlFiles = entries.filter((f) => f.endsWith(\".jsonl\"));\n if (jsonlFiles.length === 0) return null;\n\n let latest: DiscoveredSession | null = null;\n for (const file of jsonlFiles) {\n const path = join(dir, file);\n try {\n const s = await stat(path);\n if (!latest || s.mtime > latest.modifiedAt) {\n latest = {\n sessionId: file.replace(/\\.jsonl$/, \"\"),\n transcriptPath: path,\n modifiedAt: s.mtime,\n };\n }\n } catch {\n // skip unreadable file\n }\n }\n return latest;\n}\n","// Graceful shutdown after `claude` exits:\n// - find latest Claude session JSONL → print `syn --resume <id>`\n// MCP-server shutdown is owned by the caller (it has the ServerHandle).\n// CONTEXT.md flushing is M4.\n\nimport { log } from \"../shared/logger.js\";\nimport type { SynthraPaths } from \"../shared/paths.js\";\nimport { findLatestSession } from \"./session-discovery.js\";\n\nexport async function cleanup(paths: SynthraPaths): Promise<void> {\n const session = await findLatestSession(paths.projectRoot);\n if (!session) {\n log.info(\"(no Claude session transcript found — nothing to resume)\");\n return;\n }\n log.info(\"\");\n log.info(`To resume this session: syn --resume ${session.sessionId}`);\n}\n","// `syn dashboard [path]` — starts the standalone token dashboard server on\n// localhost:8901 (or SYN_DASHBOARD_PORT). Reads token_log.jsonl + gate_log.jsonl\n// for the given project. Runs until Ctrl+C.\n\nimport { resolve } from \"node:path\";\n\nimport { startDashboard } from \"../dashboard/server.js\";\nimport { loadConfig } from \"../shared/config.js\";\nimport { log } from \"../shared/logger.js\";\nimport { resolvePaths } from \"../shared/paths.js\";\n\nexport async function dashboardCommand(rawPath: string): Promise<void> {\n const projectRoot = resolve(rawPath);\n const paths = resolvePaths(projectRoot);\n const cfg = loadConfig();\n\n const handle = await startDashboard(paths, cfg.dashboardPort);\n log.info(`Synthra dashboard listening on ${handle.url}`);\n log.info(`project: ${projectRoot}`);\n log.info(`reading: ${paths.tokenLog}`);\n log.info(` ${paths.gateLog}`);\n log.info(\"press Ctrl+C to stop.\");\n\n await new Promise<void>((res) => {\n const shutdown = async (signal: NodeJS.Signals) => {\n log.info(`received ${signal} — shutting down…`);\n try {\n await handle.stop();\n } catch (err) {\n log.warn(`dashboard stop error: ${(err as Error).message}`);\n }\n res();\n };\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n });\n}\n\n// Backwards-compat alias matching the M2-era stub signature.\nexport async function openDashboard(_port = 8901): Promise<void> {\n return dashboardCommand(\".\");\n}\n","// `syn doctor` — read-only diagnosis of a project's Synthra setup + environment.\n// Surfaces the common failure modes the dogfood log kept hitting: missing `jq`\n// (Stop/PreToolUse bash hooks silently no-op → no token logging or gating), a\n// stale or 0-symbol graph, no `.mcp.json` (the IDE can't see graph_* tools), and\n// an outdated policy block / uninstalled hooks. Never mutates anything.\n\nimport { readFile, stat } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\n\nimport spawn from \"cross-spawn\";\n\nimport { SCHEMA_VERSION } from \"../graph/types.js\";\nimport type { GraphSchema } from \"../graph/types.js\";\nimport { POLICY_VERSION } from \"../hooks/claude-md.js\";\nimport { loadConfig } from \"../shared/config.js\";\nimport { log } from \"../shared/logger.js\";\nimport { resolvePaths } from \"../shared/paths.js\";\n\nexport type CheckStatus = \"ok\" | \"warn\" | \"fail\";\n\nexport interface DoctorCheck {\n status: CheckStatus;\n label: string;\n detail: string;\n}\n\nconst ICON: Record<CheckStatus, string> = { ok: \"✅\", warn: \"⚠️\", fail: \"❌\" };\n\nfunction binWorks(bin: string, args: string[]): Promise<boolean> {\n return new Promise((res) => {\n let proc: ReturnType<typeof spawn>;\n try {\n proc = spawn(bin, args, { stdio: \"ignore\" });\n } catch {\n res(false);\n return;\n }\n proc.on(\"error\", () => res(false));\n proc.on(\"exit\", (code) => res(code === 0));\n });\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/** Collect the diagnostic checks for a project. Pure of console output so it can\n * be tested; doctorCommand() wraps it with printing. */\nexport async function runDoctorChecks(projectRoot: string): Promise<DoctorCheck[]> {\n const paths = resolvePaths(projectRoot);\n const cfg = loadConfig();\n const checks: DoctorCheck[] = [];\n\n // Node version\n const nodeMajor = Number(process.versions.node.split(\".\")[0]);\n checks.push(\n nodeMajor >= 18\n ? { status: \"ok\", label: \"Node\", detail: `v${process.versions.node}` }\n : {\n status: \"fail\",\n label: \"Node\",\n detail: `v${process.versions.node} — Synthra needs Node >= 18`,\n },\n );\n\n // jq — required by the bash hooks; on Windows the installer uses .ps1 instead.\n const hasJq = await binWorks(\"jq\", [\"--version\"]);\n if (process.platform === \"win32\") {\n checks.push({\n status: \"ok\",\n label: \"jq\",\n detail: hasJq\n ? \"present (not required — Windows uses .ps1 hooks)\"\n : \"not required on Windows (.ps1 hooks)\",\n });\n } else {\n checks.push(\n hasJq\n ? { status: \"ok\", label: \"jq\", detail: \"present\" }\n : {\n status: \"warn\",\n label: \"jq\",\n detail:\n \"missing — Stop/PreToolUse bash hooks silently no-op (no token logging or gating). Install jq (brew/apt).\",\n },\n );\n }\n\n // claude CLI — needed for MCP registration + IDE integration.\n const hasClaude = await binWorks(cfg.claudeBin, [\"--version\"]);\n checks.push(\n hasClaude\n ? { status: \"ok\", label: \"claude CLI\", detail: `'${cfg.claudeBin}' on PATH` }\n : {\n status: \"warn\",\n label: \"claude CLI\",\n detail: `'${cfg.claudeBin}' not found — MCP registration + IDE need it (set SYN_CLAUDE_BIN to override).`,\n },\n );\n\n // Graph\n if (!(await exists(paths.infoGraph))) {\n checks.push({\n status: \"warn\",\n label: \"Graph\",\n detail: \"no info_graph.json — run `syn .` (or `syn scan`) here.\",\n });\n } else {\n try {\n const graph = JSON.parse(await readFile(paths.infoGraph, \"utf8\")) as GraphSchema;\n const parts = [`${graph.symbol_count} symbols`, `${graph.file_count} files`];\n let status: CheckStatus = \"ok\";\n const ageMs = Date.now() - Date.parse(graph.generated_at);\n if (Number.isFinite(ageMs))\n parts.push(`scanned ${Math.max(0, Math.round(ageMs / 60000))}m ago`);\n if (graph.schema_version !== SCHEMA_VERSION) {\n status = \"warn\";\n parts.push(`schema v${graph.schema_version} ≠ v${SCHEMA_VERSION} (auto-rescans on serve)`);\n }\n if (graph.symbol_count === 0) {\n status = \"warn\";\n parts.push(\"0 symbols — unsupported language or nothing indexed\");\n }\n checks.push({ status, label: \"Graph\", detail: parts.join(\" · \") });\n } catch {\n checks.push({\n status: \"warn\",\n label: \"Graph\",\n detail: \"info_graph.json unreadable — re-run `syn scan`.\",\n });\n }\n }\n\n // MCP registration for the IDE (.mcp.json at the project root)\n checks.push(\n (await exists(join(projectRoot, \".mcp.json\")))\n ? {\n status: \"ok\",\n label: \"MCP registration\",\n detail: \".mcp.json present (IDE can see graph_* tools)\",\n }\n : {\n status: \"warn\",\n label: \"MCP registration\",\n detail: \"no .mcp.json — the IDE extension won't see Synthra's tools; run `syn .`.\",\n },\n );\n\n // CLAUDE.md policy block\n if (!(await exists(paths.claudeMd))) {\n checks.push({\n status: \"warn\",\n label: \"CLAUDE.md policy\",\n detail: \"no CLAUDE.md — run `syn .` to scaffold + inject the policy block.\",\n });\n } else {\n const md = await readFile(paths.claudeMd, \"utf8\");\n if (md.includes(`synthra-policy v${POLICY_VERSION} BEGIN`)) {\n checks.push({\n status: \"ok\",\n label: \"CLAUDE.md policy\",\n detail: `policy block v${POLICY_VERSION}`,\n });\n } else {\n const m = md.match(/synthra-policy v(\\d+) BEGIN/);\n checks.push({\n status: \"warn\",\n label: \"CLAUDE.md policy\",\n detail: m\n ? `policy block is v${m[1]}, current is v${POLICY_VERSION} — re-run \\`syn .\\` to refresh.`\n : \"no synthra-policy block — run `syn .`.\",\n });\n }\n }\n\n // Hooks installed\n if (!(await exists(paths.claudeSettings))) {\n checks.push({\n status: \"warn\",\n label: \"Hooks\",\n detail: \"no .claude/settings.local.json — run `syn .` to install hooks.\",\n });\n } else {\n const s = await readFile(paths.claudeSettings, \"utf8\");\n checks.push(\n s.includes(\"synthra-hook=true\")\n ? { status: \"ok\", label: \"Hooks\", detail: \"registered in .claude/settings.local.json\" }\n : {\n status: \"warn\",\n label: \"Hooks\",\n detail: \"settings.local.json present but no Synthra hooks — run `syn .`.\",\n },\n );\n }\n\n return checks;\n}\n\nexport async function doctorCommand(rawPath: string): Promise<void> {\n const projectRoot = resolve(rawPath);\n const checks = await runDoctorChecks(projectRoot);\n\n log.info(\"\");\n log.info(` Synthra doctor — ${projectRoot}`);\n log.info(\"\");\n for (const c of checks) {\n log.info(` ${ICON[c.status]} ${c.label.padEnd(18)}${c.detail}`);\n }\n const warn = checks.filter((c) => c.status === \"warn\").length;\n const fail = checks.filter((c) => c.status === \"fail\").length;\n log.info(\"\");\n log.info(\n fail === 0 && warn === 0 ? \" All checks passed.\" : ` ${fail} failed · ${warn} warning(s).`,\n );\n log.info(\"\");\n}\n","// Update flow:\n//\n// 1. At every `syn .` startup, check the npm registry for the latest\n// version. If we're on latest, stay silent. If outdated, prompt the\n// user [y/N]. On 'y', run `npm install -g …@latest` with inherited\n// stdio, print the new version's changelog section from the freshly-\n// installed package, then exit with re-run instructions.\n//\n// 2. On every startup, compare the running binary's version to a\n// persisted \"last seen\" version at ~/.synthra/last-seen-version.json.\n// If running > last-seen, print the changelog for the running version\n// (catches manual `npm install -g …@latest` upgrades that bypassed\n// our prompt). On a fresh install (no last-seen file), set last-seen\n// silently without printing — new users don't need the changelog.\n//\n// No 24h cache — the user explicitly asked for \"always check on every\n// `syn .` run.\" Cost: one ~100–300ms HTTPS round-trip per startup, hard-\n// capped by FETCH_TIMEOUT_MS. SYN_NO_UPDATE_CHECK=1 opts out of (1)\n// only; the local last-seen comparison in (2) still fires.\n\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createInterface } from \"node:readline/promises\";\n\nimport spawn from \"cross-spawn\";\n\nimport { log } from \"../shared/logger.js\";\n\nconst PKG_NAME = \"@jefuriiij/synthra\";\nconst SYNTHRA_DIR = join(homedir(), \".synthra\");\nconst LAST_SEEN_PATH = join(SYNTHRA_DIR, \"last-seen-version.json\");\nconst REGISTRY_URL = `https://registry.npmjs.org/${encodeURIComponent(PKG_NAME)}/latest`;\nconst FETCH_TIMEOUT_MS = 2000;\n\ninterface LastSeenFile {\n version: string;\n updated_at: string;\n}\n\nexport interface UpdateCheckResult {\n current: string;\n latest: string | null;\n hasUpdate: boolean;\n}\n\nlet currentVersionCache: string | null = null;\n\nasync function getCurrentVersion(): Promise<string> {\n if (currentVersionCache) return currentVersionCache;\n try {\n // Tsup inlines this import at build time.\n const pkg = (await import(\"../../package.json\", { with: { type: \"json\" } })) as\n | { default: { version: string } }\n | { version: string };\n const version = \"default\" in pkg ? pkg.default.version : pkg.version;\n currentVersionCache = version;\n return version;\n } catch {\n return \"0.0.0\";\n }\n}\n\n/** Returns true if `candidate` is a higher semver than `baseline`. */\nfunction isNewer(candidate: string, baseline: string): boolean {\n const a = candidate.split(/[.-]/).map((p) => Number(p));\n const b = baseline.split(/[.-]/).map((p) => Number(p));\n const len = Math.max(a.length, b.length);\n for (let i = 0; i < len; i++) {\n const ai = Number.isFinite(a[i]) ? (a[i] as number) : 0;\n const bi = Number.isFinite(b[i]) ? (b[i] as number) : 0;\n if (ai > bi) return true;\n if (ai < bi) return false;\n }\n return false;\n}\n\nasync function fetchLatestFromRegistry(): Promise<string | null> {\n try {\n const res = await fetch(REGISTRY_URL, {\n signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),\n headers: { Accept: \"application/json\" },\n });\n if (!res.ok) return null;\n const data = (await res.json()) as { version?: string };\n return typeof data.version === \"string\" ? data.version : null;\n } catch {\n return null;\n }\n}\n\nexport async function checkForUpdate(): Promise<UpdateCheckResult> {\n const current = await getCurrentVersion();\n\n if (process.env.SYN_NO_UPDATE_CHECK === \"1\") {\n return { current, latest: null, hasUpdate: false };\n }\n\n const latest = await fetchLatestFromRegistry();\n const hasUpdate = latest ? isNewer(latest, current) : false;\n return { current, latest, hasUpdate };\n}\n\nasync function readLastSeen(): Promise<string | null> {\n try {\n const raw = await readFile(LAST_SEEN_PATH, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<LastSeenFile>;\n return parsed.version ?? null;\n } catch {\n return null;\n }\n}\n\nasync function writeLastSeen(version: string): Promise<void> {\n try {\n await mkdir(SYNTHRA_DIR, { recursive: true });\n const data: LastSeenFile = { version, updated_at: new Date().toISOString() };\n await writeFile(LAST_SEEN_PATH, JSON.stringify(data, null, 2), \"utf8\");\n } catch {\n // best-effort\n }\n}\n\n/** Find the directory `npm root -g` reports. Used to locate the installed package. */\nfunction npmGlobalRoot(): Promise<string | null> {\n return new Promise((resolve) => {\n const chunks: Buffer[] = [];\n const proc = spawn(\"npm\", [\"root\", \"-g\"], { stdio: [\"ignore\", \"pipe\", \"ignore\"] });\n proc.stdout?.on(\"data\", (c: Buffer) => chunks.push(c));\n proc.on(\"error\", () => resolve(null));\n proc.on(\"exit\", (code) => {\n if (code !== 0) return resolve(null);\n const out = Buffer.concat(chunks).toString(\"utf8\").trim();\n resolve(out || null);\n });\n });\n}\n\n/**\n * Extract the markdown section under `## [version]` (or `## v0.1.11`) from a\n * CHANGELOG body. Returns the bullet/prose content between this version's\n * heading and the next H2, trimmed. Returns null if the version isn't found.\n */\nexport function extractChangelogSection(text: string, version: string): string | null {\n const escapedVersion = version.replace(/\\./g, \"\\\\.\");\n // Match: \"## [0.1.11]\" or \"## v0.1.11\" or \"## 0.1.11\", optionally followed by extra text.\n const headingRe = new RegExp(`^##\\\\s+\\\\[?v?${escapedVersion}\\\\]?.*$`, \"m\");\n const m = headingRe.exec(text);\n if (!m) return null;\n const startBody = m.index + m[0].length;\n const rest = text.slice(startBody);\n const nextHeadingIdx = rest.search(/^##\\s+/m);\n const body = nextHeadingIdx < 0 ? rest : rest.slice(0, nextHeadingIdx);\n // Strip horizontal-rule separator lines.\n return body.replace(/^---\\s*$/gm, \"\").trim() || null;\n}\n\nasync function readInstalledChangelog(): Promise<string | null> {\n const root = await npmGlobalRoot();\n if (!root) return null;\n try {\n return await readFile(join(root, \"@jefuriiij\", \"synthra\", \"CHANGELOG.md\"), \"utf8\");\n } catch {\n return null;\n }\n}\n\nasync function printChangelogForVersion(version: string): Promise<void> {\n const md = await readInstalledChangelog();\n if (!md) return;\n const section = extractChangelogSection(md, version);\n if (!section) return;\n log.info(\"\");\n log.info(`What's new in ${version}:`);\n log.info(\"\");\n for (const line of section.split(/\\r?\\n/)) {\n log.info(` ${line}`);\n }\n log.info(\"\");\n}\n\n/**\n * Compare the running binary's version against the persisted last-seen\n * version. If running > last-seen, print the changelog for the running\n * version and update last-seen. If last-seen is missing (fresh install),\n * silently set it to the current version — new installs don't need a\n * retroactive changelog.\n *\n * Catches users who upgraded via `npm install -g …@latest` outside of\n * Synthra's interactive prompt. Always silent on no-op.\n */\nexport async function runStartupChangelogCheck(): Promise<void> {\n try {\n const current = await getCurrentVersion();\n const lastSeen = await readLastSeen();\n if (!lastSeen) {\n await writeLastSeen(current);\n return;\n }\n if (isNewer(current, lastSeen)) {\n await printChangelogForVersion(current);\n await writeLastSeen(current);\n }\n } catch {\n // silent\n }\n}\n\n/**\n * Ask a yes/no question on stdin/stdout. Returns true only on explicit \"y\" /\n * \"yes\". Empty input or anything else returns false.\n */\nasync function promptYesNo(question: string): Promise<boolean> {\n if (!process.stdin.isTTY) return false;\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n try {\n const answer = (await rl.question(question)).trim().toLowerCase();\n return answer === \"y\" || answer === \"yes\";\n } finally {\n rl.close();\n }\n}\n\n/** Run `npm install -g @jefuriiij/synthra@latest`. Inherits stdio. */\nfunction runNpmUpdate(): Promise<boolean> {\n return new Promise((resolve) => {\n const proc = spawn(\"npm\", [\"install\", \"-g\", PKG_NAME + \"@latest\"], {\n stdio: \"inherit\",\n });\n proc.on(\"error\", () => resolve(false));\n proc.on(\"exit\", (code) => resolve(code === 0));\n });\n}\n\n/**\n * Interactive update flow. Always hits the registry — no cache. If a newer\n * version exists AND we're on a TTY, prompts the user [y/N]. On 'y', runs\n * npm install, prints the new version's changelog section, and exits with\n * re-run instructions. On 'n' / non-TTY / no update, returns silently so\n * startup continues.\n */\nexport async function promptForUpdateOrLog(): Promise<void> {\n try {\n const r = await checkForUpdate();\n if (!r.hasUpdate || !r.latest) return;\n\n // Non-interactive (CI, piped stdin) — log a one-line hint but don't prompt.\n if (!process.stdin.isTTY) {\n log.info(\n `Synthra ${r.latest} is available (you have ${r.current}) — run: npm install -g @jefuriiij/synthra@latest`,\n );\n return;\n }\n\n log.info(`Synthra ${r.latest} is available (you have ${r.current}).`);\n const yes = await promptYesNo(\"[syn] Update now? [y/N]: \");\n if (!yes) {\n log.info(\"Skipping update — continuing with current version.\");\n return;\n }\n\n log.info(`Running: npm install -g ${PKG_NAME}@latest`);\n const ok = await runNpmUpdate();\n if (!ok) {\n log.warn(\"npm install failed — continuing with current version.\");\n return;\n }\n log.info(`✓ Updated to ${r.latest}.`);\n await printChangelogForVersion(r.latest);\n await writeLastSeen(r.latest);\n log.info(`Please re-run: syn .`);\n process.exit(0);\n } catch {\n // silent\n }\n}\n","// `syn serve [path]` — starts the HTTP MCP server against an already-scanned\n// project. The graph + symbol index must exist (run `syn scan` first).\n// Traps SIGINT/SIGTERM for a graceful shutdown.\n\nimport { resolve } from \"node:path\";\nimport { stat } from \"node:fs/promises\";\n\nimport { startServer } from \"../server/http.js\";\nimport { log } from \"../shared/logger.js\";\nimport { resolvePaths } from \"../shared/paths.js\";\n\nexport async function serveCommand(rawPath: string): Promise<void> {\n const projectRoot = resolve(rawPath);\n const paths = resolvePaths(projectRoot);\n\n try {\n await stat(paths.infoGraph);\n } catch {\n log.error(`no graph found at ${paths.infoGraph}`);\n log.error(\"run `syn scan` in this project first.\");\n process.exit(2);\n }\n\n const handle = await startServer(paths);\n log.info(`MCP server listening on ${handle.url}`);\n log.info(`port written to ${paths.mcpPort}`);\n log.info(\"press Ctrl+C to stop.\");\n\n const shutdown = async (signal: NodeJS.Signals) => {\n log.info(`received ${signal} — shutting down…`);\n try {\n await handle.stop();\n } catch (err) {\n log.error(\"shutdown error:\", (err as Error).message);\n }\n process.exit(0);\n };\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n}\n","// Subroutines for plugging Synthra into Claude Code:\n// - registerMcp → `claude mcp add --transport http --scope local`\n// - unregisterMcp → `claude mcp remove`\n// - spawnClaude → spawn the terminal CLI (used only by `--launch-cli`)\n// - startClaude → legacy composite (install hooks + register + spawn + unregister)\n// kept for any external callers; cli/index.ts now composes the pieces\n// itself so the default flow can skip the CLI spawn.\n\nimport spawn from \"cross-spawn\";\n\nimport { installHooks } from \"../hooks/installer.js\";\nimport { loadConfig } from \"../shared/config.js\";\nimport { log } from \"../shared/logger.js\";\nimport type { SynthraPaths } from \"../shared/paths.js\";\n\nconst MCP_NAME = \"synthra\";\n\n// We use `cross-spawn` instead of `node:child_process` so Windows .cmd\n// shims (e.g. claude.cmd) resolve correctly without setting shell:true.\n// shell:true triggers Node's DEP0190 deprecation because args get\n// concatenated into a single command line with no escaping. cross-spawn\n// handles shim resolution + proper arg escaping internally, so we avoid\n// the deprecation and the underlying security concern in one move.\nfunction runClaude(\n bin: string,\n args: string[],\n cwd: string,\n stdio: \"inherit\" | \"pipe\" = \"pipe\",\n): Promise<{ code: number; stdout: string; stderr: string }> {\n return new Promise((resolve) => {\n const proc = spawn(bin, args, {\n cwd,\n stdio: stdio === \"inherit\" ? \"inherit\" : [\"ignore\", \"pipe\", \"pipe\"],\n });\n let stdout = \"\";\n let stderr = \"\";\n proc.stdout?.on(\"data\", (c) => (stdout += String(c)));\n proc.stderr?.on(\"data\", (c) => (stderr += String(c)));\n proc.on(\"error\", () => resolve({ code: -1, stdout, stderr: stderr || \"claude not on PATH\" }));\n proc.on(\"exit\", (code) => resolve({ code: code ?? 0, stdout, stderr }));\n });\n}\n\nexport async function registerMcp(bin: string, mcpPort: number, cwd: string): Promise<boolean> {\n const url = `http://127.0.0.1:${mcpPort}/mcp`;\n await runClaude(bin, [\"mcp\", \"remove\", MCP_NAME, \"--scope\", \"project\"], cwd).catch(\n () => undefined,\n );\n const reg = await runClaude(\n bin,\n [\"mcp\", \"add\", MCP_NAME, \"--transport\", \"http\", \"--scope\", \"project\", url],\n cwd,\n );\n if (reg.code !== 0) {\n log.warn(`claude mcp add failed (code ${reg.code}). stderr: ${reg.stderr.trim()}`);\n log.warn(`Synthra's MCP tools won't be visible to Claude this session.`);\n return false;\n }\n log.info(`registered MCP with Claude: ${MCP_NAME} → ${url}`);\n return true;\n}\n\nexport async function unregisterMcp(bin: string, cwd: string): Promise<void> {\n const r = await runClaude(bin, [\"mcp\", \"remove\", MCP_NAME, \"--scope\", \"project\"], cwd);\n if (r.code === 0) log.debug(\"unregistered MCP server\");\n}\n\nexport interface SpawnClaudeOptions {\n cwd: string;\n resumeSessionId?: string;\n initialPrompt?: string;\n}\n\nexport async function spawnClaude(bin: string, opts: SpawnClaudeOptions): Promise<number> {\n const args: string[] = [];\n if (opts.resumeSessionId) args.push(\"--resume\", opts.resumeSessionId);\n if (opts.initialPrompt) args.push(opts.initialPrompt);\n log.info(`launching ${bin} ${args.join(\" \")}`);\n const result = await runClaude(bin, args, opts.cwd, \"inherit\");\n return result.code;\n}\n\n// Legacy composite — install hooks + register MCP + spawn claude + cleanup.\n// cli/index.ts no longer relies on this; it composes the pieces above so the\n// new default `syn .` flow can skip the CLI spawn. Kept for compatibility.\nexport interface StartClaudeOptions {\n paths: SynthraPaths;\n mcpPort: number;\n resumeSessionId?: string;\n initialPrompt?: string;\n}\n\nexport async function startClaude(opts: StartClaudeOptions): Promise<number> {\n const bin = loadConfig().claudeBin;\n await installHooks(opts.paths);\n await registerMcp(bin, opts.mcpPort, opts.paths.projectRoot);\n const code = await spawnClaude(bin, {\n cwd: opts.paths.projectRoot,\n resumeSessionId: opts.resumeSessionId,\n initialPrompt: opts.initialPrompt,\n });\n await unregisterMcp(bin, opts.paths.projectRoot);\n return code;\n}\n"],"mappings":"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AAK,EAAE,MAAM,GAAG,CAAC;AACpE;;;ACHA,IAAM,YAAY,oBAAI,IAAI;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,cAAc,oBAAI,IAAI;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA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","names":["resolve","resolve","readFile","readFile","dirname","stat","readFile","dirname","join","mkdir","readFile","writeFile","homedir","basename","dirname","join","score","readFile","basename","resolve","err","mkdir","readFile","writeFile","dirname","join","pre_compact_default","pre_tool_use_default","prime_default","stop_default","prime_default","pre_tool_use_default","pre_compact_default","stop_default","readFile","join","mkdir","writeFile","dirname","serve","Hono","writeFile","appendFile","mkdir","dirname","readFile","join","readFile","join","emit","err","readFile","join","dirname","join","SCHEMA_VERSION","SCHEMA_VERSION","mkdir","readFile","writeFile","dirname","readFile","QUERY","QUERY","Query","QUERY","firstLine","Query","QUERY","QUERY","QUERY","QUERY","Query","QUERY","firstLine","Query","QUERY","QUERY","Query","firstLine","Query","SCRIPT_RE","extractScripts","require","readFile","cache","mkdir","dirname","writeFile","readFile","readdir","join","relative","sep","ignore","readIgnoreFile","buildMatcher","toPosix","mkdir","readFile","writeFile","dirname","readJson","mkdir","readFile","stat","writeFile","basename","readFile","writeFile","basename","dirname","stat","mkdir","readFile","writeFile","basename","cache","appendFile","mkdir","dirname","STOPWORDS","score","execFile","readFile","join","promisify","execFileAsync","mkdir","readFile","writeFile","dirname","mkdir","readFile","writeFile","dirname","SCHEMA_VERSION","score","indexSymbolsByFile","resolve","sep","join","mkdir","dirname","appendFile","execFile","promisify","execFileAsync","mkdir","readFile","writeFile","dirname","appendFile","mkdir","dirname","mkdir","dirname","appendFile","score","res","appendFile","mkdir","dirname","MAX_COMMITS","MAX_BULLETS","SCHEMA_VERSION","err","Hono","serve","writeFile","resolve","readdir","stat","homedir","join","resolve","resolve","err","readFile","stat","join","resolve","exists","stat","readFile","SCHEMA_VERSION","join","resolve","mkdir","readFile","writeFile","homedir","join","spawn","join","homedir","readFile","mkdir","writeFile","resolve","spawn","ok","resolve","stat","resolve","stat","err","spawn","resolve","spawn","VERSION","resolve","err"]}