@routecraft/cli 0.5.0-canary.71 → 0.5.0-canary.73
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-TDKTL4RU.js +2 -0
- package/dist/chunk-TDKTL4RU.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/tui/app.js +3 -3
- package/dist/tui/app.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../package.json"],"names":["version"],"mappings":"AAEE,IAAAA,CAAAA,CAAW","file":"chunk-TDKTL4RU.js","sourcesContent":["{\n \"name\": \"@routecraft/cli\",\n \"version\": \"0.5.0-canary.73\",\n \"description\": \"CLI for running Routecraft routes\",\n \"private\": false,\n \"type\": \"module\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\"\n }\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup src/index.ts src/tui/app.tsx src/tui/db.ts --format esm --dts --external react --external ink --external bun:sqlite\",\n \"test\": \"vitest\",\n \"test:coverage\": \"vitest --coverage\",\n \"prepublishOnly\": \"bun run build\"\n },\n \"dependencies\": {\n \"@opentelemetry/sdk-trace-base\": \"^2.7.1\",\n \"@routecraft/routecraft\": \"^0.5.0-canary.73\",\n \"agent-browser\": \"^0.17.1\",\n \"cheerio\": \"^1.2.0\",\n \"commander\": \"^14.0.3\",\n \"croner\": \"^10.0.1\",\n \"dotenv\": \"^17.4.2\",\n \"imapflow\": \"^1.3.3\",\n \"ink\": \"^5.2.1\",\n \"jose\": \"^6.2.3\",\n \"mailparser\": \"^3.9.8\",\n \"nodemailer\": \"^6.10.1\",\n \"papaparse\": \"^5.5.3\",\n \"pino-pretty\": \"^13.1.3\",\n \"react\": \"^18.3.1\"\n },\n \"devDependencies\": {\n \"@types/mailparser\": \"^3.4.6\",\n \"@types/nodemailer\": \"^6.4.23\",\n \"@types/react\": \"^18.3.28\",\n \"ink-testing-library\": \"^4.0.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"repository\": \"https://github.com/routecraftjs/routecraft\",\n \"bin\": {\n \"craft\": \"./dist/index.js\"\n },\n \"engines\": {\n \"bun\": \">=1.1.0\"\n },\n \"keywords\": [\n \"routecraft\",\n \"cli\",\n \"routes\",\n \"automation\",\n \"typescript\"\n ],\n \"author\": \"routecraftjs\",\n \"license\": \"Apache-2.0\",\n \"homepage\": \"https://routecraft.dev\"\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
var n={major:1,minor:1,patch:0},
|
|
2
|
+
import {a}from'./chunk-TDKTL4RU.js';var n={major:1,minor:1,patch:0},m="https://bun.com/docs/installation",v="https://routecraft.dev/docs/advanced/programmatic-invocation";function d(e=process.versions.bun??null){let o=e;if(!o)return {ok:false,message:`[routecraft] The craft CLI requires Bun. Install Bun from ${m}, or embed @routecraft/routecraft programmatically (see ${v}).`};let s=o.split(/[-+]/)[0]??"",[t,a,u]=s.split("."),r=Number(t),c=Number(a),l=Number(u??"0");return !Number.isFinite(r)||!Number.isFinite(c)||!Number.isFinite(l)?{ok:false,message:`[routecraft] Could not parse Bun version "${o}". Routecraft requires Bun ${f(n)} or later. Upgrade Bun: ${m}.`}:r>n.major||r===n.major&&(c>n.minor||c===n.minor&&l>=n.patch)?{ok:true}:{ok:false,message:`[routecraft] Bun ${o} is not supported. Routecraft requires Bun ${f(n)} or later. Upgrade Bun: ${m}.`}}function f(e){return `${e.major}.${e.minor}.${e.patch}`}var g=d();g.ok||(console.error(g.message),process.exit(1));var{Command:h}=await import('commander'),i=new h;i.name("craft").description("A modern routing framework for TypeScript").version(a).enablePositionalOptions().option("--log-level <level>","Log level (e.g. info, warn, error, silent to disable)").option("--log-file <path>","Write logs to a file instead of stdout").showSuggestionAfterError().showHelpAfterError().exitOverride(e=>{e.code==="commander.unknownCommand"&&process.exit(0);});process.argv.length<=2&&i.help({error:false});i.command("run").description("Run routes from a single TypeScript/JavaScript file").argument("<file>","Path to a file containing routes").argument("[args...]","CLI command and flags to pass through to CLI adapter routes").option("--env <path>","Load environment variables from a .env file (default: .env)").passThroughOptions().action(async(e,o,s)=>{let t=i.opts();t.logLevel!==void 0&&(process.env.LOG_LEVEL=t.logLevel,process.env.CRAFT_LOG_LEVEL=t.logLevel),t.logFile!==void 0&&(process.env.LOG_FILE=t.logFile,process.env.CRAFT_LOG_FILE=t.logFile);let{loadEnvFile:a}=await import('./util-GX4G3K5I.js');s.env!==void 0?a(s.env):a();let{runCommand:u}=await import('./run-3Y3G7OTJ.js'),r=await u(e,o);if(!r.success){r.message&&console.error(r.message);let c=r.code??1;setImmediate(()=>process.exit(c));return}});i.command("tui").description("Launch the Terminal UI to monitor Routecraft execution history").option("--db <path>","Path to the telemetry SQLite database",".routecraft/telemetry.db").action(async e=>{let{resolve:o,isAbsolute:s}=await import('path'),t=s(e.db)?e.db:o(process.cwd(),e.db),{renderTui:a}=await import('./tui/app.js');await a(t);});i.parse();//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runtime-gate.ts","../src/index.ts"],"names":["MIN_BUN_VERSION","INSTALL_URL","EMBEDDING_DOC_URL","checkBunRuntime","bunVersion","version","stripped","majorStr","minorStr","patchStr","major","minor","patch","formatVersion","v","gate","Command","program","err","filePath","args","options","globalOpts","loadEnvFile","runCommand","result","code","resolve","isAbsolute","dbPath","renderTui"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Runtime gate for the craft CLI.\n *\n * The CLI is Bun-only. Users on Node embed @routecraft/routecraft\n * programmatically instead of going through the CLI.\n *\n * Exposed as a pure function so unit tests can pass arbitrary version strings\n * without spawning real bun processes.\n */\n\nconst MIN_BUN_VERSION = { major: 1, minor: 1, patch: 0 } as const;\n\nconst INSTALL_URL = \"https://bun.com/docs/installation\";\nconst EMBEDDING_DOC_URL =\n \"https://routecraft.dev/docs/advanced/programmatic-invocation\";\n\nexport type RuntimeGateResult = { ok: true } | { ok: false; message: string };\n\n// Accept `null` (not `undefined`) to express \"not running on Bun\" so tests can\n// reliably exercise the missing-bun path. JS default-parameter semantics\n// re-apply the default for explicit `undefined`, which would otherwise let\n// `process.versions.bun` leak in when the suite runs under Bun.\nexport function checkBunRuntime(\n bunVersion: string | null = process.versions[\"bun\"] ?? null,\n): RuntimeGateResult {\n const version = bunVersion;\n\n if (!version) {\n return {\n ok: false,\n message:\n `[routecraft] The craft CLI requires Bun. ` +\n `Install Bun from ${INSTALL_URL}, ` +\n `or embed @routecraft/routecraft programmatically (see ${EMBEDDING_DOC_URL}).`,\n };\n }\n\n // Strip both prerelease (`-`) and build metadata (`+`) per SemVer.\n const stripped = version.split(/[-+]/)[0] ?? \"\";\n const [majorStr, minorStr, patchStr] = stripped.split(\".\");\n const major = Number(majorStr);\n const minor = Number(minorStr);\n const patch = Number(patchStr ?? \"0\");\n\n if (\n !Number.isFinite(major) ||\n !Number.isFinite(minor) ||\n !Number.isFinite(patch)\n ) {\n return {\n ok: false,\n message:\n `[routecraft] Could not parse Bun version \"${version}\". ` +\n `Routecraft requires Bun ${formatVersion(MIN_BUN_VERSION)} or later. ` +\n `Upgrade Bun: ${INSTALL_URL}.`,\n };\n }\n\n const meetsFloor =\n major > MIN_BUN_VERSION.major ||\n (major === MIN_BUN_VERSION.major &&\n (minor > MIN_BUN_VERSION.minor ||\n (minor === MIN_BUN_VERSION.minor && patch >= MIN_BUN_VERSION.patch)));\n\n if (!meetsFloor) {\n return {\n ok: false,\n message:\n `[routecraft] Bun ${version} is not supported. ` +\n `Routecraft requires Bun ${formatVersion(MIN_BUN_VERSION)} or later. ` +\n `Upgrade Bun: ${INSTALL_URL}.`,\n };\n }\n\n return { ok: true };\n}\n\nfunction formatVersion(v: typeof MIN_BUN_VERSION): string {\n return `${v.major}.${v.minor}.${v.patch}`;\n}\n","#!/usr/bin/env bun\n\n/**\n * Routecraft CLI: single entry point.\n *\n * The CLI runs on Bun. For Node-based usage, embed @routecraft/routecraft\n * programmatically (see https://routecraft.dev/docs/advanced/programmatic-invocation).\n *\n * 1. Bun runtime gate (presence + version floor)\n * 2. Define program and parse; log options are global and applied before\n * lazy-loading run/util (which load the logger)\n */\n\nimport { checkBunRuntime } from \"./runtime-gate.js\";\n\n// ── 1. Bun runtime gate ─────────────────────────────────────────────\nconst gate = checkBunRuntime();\nif (!gate.ok) {\n // eslint-disable-next-line no-console\n console.error(gate.message);\n process.exit(1);\n}\n\n// ── 2. CLI definition (only Commander; run/util are lazy-loaded so logger sees env) ─\nconst { Command } = await import(\"commander\");\nconst program = new Command();\n\nprogram\n .name(\"craft\")\n .description(\"A modern routing framework for TypeScript\")\n .version(\"0.5.0-canary.71\")\n .enablePositionalOptions()\n .option(\n \"--log-level <level>\",\n \"Log level (e.g. info, warn, error, silent to disable)\",\n )\n .option(\"--log-file <path>\", \"Write logs to a file instead of stdout\")\n .showSuggestionAfterError()\n .showHelpAfterError()\n .exitOverride((err) => {\n if (err.code === \"commander.unknownCommand\") {\n process.exit(0);\n }\n });\n\n// Show help by default if no arguments provided\nif (process.argv.length <= 2) {\n program.help({ error: false });\n}\n\n/**\n * The 'run' command executes routes from a single file.\n *\n * Example:\n * craft run ./my-routes.ts\n * craft run ./my-cli.ts greet --name World\n */\nprogram\n .command(\"run\")\n .description(\"Run routes from a single TypeScript/JavaScript file\")\n .argument(\"<file>\", \"Path to a file containing routes\")\n .argument(\n \"[args...]\",\n \"CLI command and flags to pass through to CLI adapter routes\",\n )\n .option(\n \"--env <path>\",\n \"Load environment variables from a .env file (default: .env)\",\n )\n .passThroughOptions()\n .action(async (filePath, args: string[], options) => {\n // Apply global log options to env before any import that creates the logger\n const globalOpts = program.opts();\n if (globalOpts[\"logLevel\"] !== undefined) {\n process.env[\"LOG_LEVEL\"] = globalOpts[\"logLevel\"];\n process.env[\"CRAFT_LOG_LEVEL\"] = globalOpts[\"logLevel\"];\n }\n if (globalOpts[\"logFile\"] !== undefined) {\n process.env[\"LOG_FILE\"] = globalOpts[\"logFile\"];\n process.env[\"CRAFT_LOG_FILE\"] = globalOpts[\"logFile\"];\n }\n\n const { loadEnvFile } = await import(\"./util.js\");\n if (options.env !== undefined) {\n loadEnvFile(options.env);\n } else {\n loadEnvFile();\n }\n\n const { runCommand } = await import(\"./run.js\");\n const result = await runCommand(filePath, args);\n if (!result.success) {\n if (result.message) {\n // eslint-disable-next-line no-console\n console.error(result.message);\n }\n // Defer exit so pino/sonic-boom can finish initializing and avoid \"sonic boom is not ready yet\"\n const code = result.code ?? 1;\n setImmediate(() => process.exit(code));\n return;\n }\n // Don't call process.exit(); let the event loop drain naturally.\n // process.exit() triggers C++ static destructors that race with ONNX\n // Runtime cleanup (onnxruntime#25038: \"mutex lock failed\").\n });\n\n/**\n * The 'tui' command launches the Terminal UI for monitoring Routecraft execution.\n *\n * Example:\n * craft tui\n * craft tui --db .routecraft/telemetry.db\n */\nprogram\n .command(\"tui\")\n .description(\"Launch the Terminal UI to monitor Routecraft execution history\")\n .option(\n \"--db <path>\",\n \"Path to the telemetry SQLite database\",\n \".routecraft/telemetry.db\",\n )\n .action(async (options) => {\n const { resolve, isAbsolute } = await import(\"node:path\");\n const dbPath = isAbsolute(options.db)\n ? options.db\n : resolve(process.cwd(), options.db);\n\n const { renderTui } = await import(\"./tui/app.js\");\n await renderTui(dbPath);\n });\n\n// Parse the command line arguments and execute the appropriate command\nprogram.parse();\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/runtime-gate.ts","../src/index.ts"],"names":["MIN_BUN_VERSION","INSTALL_URL","EMBEDDING_DOC_URL","checkBunRuntime","bunVersion","version","stripped","majorStr","minorStr","patchStr","major","minor","patch","formatVersion","v","gate","Command","program","err","filePath","args","options","globalOpts","loadEnvFile","runCommand","result","code","resolve","isAbsolute","dbPath","renderTui"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Runtime gate for the craft CLI.\n *\n * The CLI is Bun-only. Users on Node embed @routecraft/routecraft\n * programmatically instead of going through the CLI.\n *\n * Exposed as a pure function so unit tests can pass arbitrary version strings\n * without spawning real bun processes.\n */\n\nconst MIN_BUN_VERSION = { major: 1, minor: 1, patch: 0 } as const;\n\nconst INSTALL_URL = \"https://bun.com/docs/installation\";\nconst EMBEDDING_DOC_URL =\n \"https://routecraft.dev/docs/advanced/programmatic-invocation\";\n\nexport type RuntimeGateResult = { ok: true } | { ok: false; message: string };\n\n// Accept `null` (not `undefined`) to express \"not running on Bun\" so tests can\n// reliably exercise the missing-bun path. JS default-parameter semantics\n// re-apply the default for explicit `undefined`, which would otherwise let\n// `process.versions.bun` leak in when the suite runs under Bun.\nexport function checkBunRuntime(\n bunVersion: string | null = process.versions[\"bun\"] ?? null,\n): RuntimeGateResult {\n const version = bunVersion;\n\n if (!version) {\n return {\n ok: false,\n message:\n `[routecraft] The craft CLI requires Bun. ` +\n `Install Bun from ${INSTALL_URL}, ` +\n `or embed @routecraft/routecraft programmatically (see ${EMBEDDING_DOC_URL}).`,\n };\n }\n\n // Strip both prerelease (`-`) and build metadata (`+`) per SemVer.\n const stripped = version.split(/[-+]/)[0] ?? \"\";\n const [majorStr, minorStr, patchStr] = stripped.split(\".\");\n const major = Number(majorStr);\n const minor = Number(minorStr);\n const patch = Number(patchStr ?? \"0\");\n\n if (\n !Number.isFinite(major) ||\n !Number.isFinite(minor) ||\n !Number.isFinite(patch)\n ) {\n return {\n ok: false,\n message:\n `[routecraft] Could not parse Bun version \"${version}\". ` +\n `Routecraft requires Bun ${formatVersion(MIN_BUN_VERSION)} or later. ` +\n `Upgrade Bun: ${INSTALL_URL}.`,\n };\n }\n\n const meetsFloor =\n major > MIN_BUN_VERSION.major ||\n (major === MIN_BUN_VERSION.major &&\n (minor > MIN_BUN_VERSION.minor ||\n (minor === MIN_BUN_VERSION.minor && patch >= MIN_BUN_VERSION.patch)));\n\n if (!meetsFloor) {\n return {\n ok: false,\n message:\n `[routecraft] Bun ${version} is not supported. ` +\n `Routecraft requires Bun ${formatVersion(MIN_BUN_VERSION)} or later. ` +\n `Upgrade Bun: ${INSTALL_URL}.`,\n };\n }\n\n return { ok: true };\n}\n\nfunction formatVersion(v: typeof MIN_BUN_VERSION): string {\n return `${v.major}.${v.minor}.${v.patch}`;\n}\n","#!/usr/bin/env bun\n\n/**\n * Routecraft CLI: single entry point.\n *\n * The CLI runs on Bun. For Node-based usage, embed @routecraft/routecraft\n * programmatically (see https://routecraft.dev/docs/advanced/programmatic-invocation).\n *\n * 1. Bun runtime gate (presence + version floor)\n * 2. Define program and parse; log options are global and applied before\n * lazy-loading run/util (which load the logger)\n */\n\nimport { checkBunRuntime } from \"./runtime-gate.js\";\nimport { version } from \"../package.json\";\n\n// ── 1. Bun runtime gate ─────────────────────────────────────────────\nconst gate = checkBunRuntime();\nif (!gate.ok) {\n // eslint-disable-next-line no-console\n console.error(gate.message);\n process.exit(1);\n}\n\n// ── 2. CLI definition (only Commander; run/util are lazy-loaded so logger sees env) ─\nconst { Command } = await import(\"commander\");\nconst program = new Command();\n\nprogram\n .name(\"craft\")\n .description(\"A modern routing framework for TypeScript\")\n .version(version)\n .enablePositionalOptions()\n .option(\n \"--log-level <level>\",\n \"Log level (e.g. info, warn, error, silent to disable)\",\n )\n .option(\"--log-file <path>\", \"Write logs to a file instead of stdout\")\n .showSuggestionAfterError()\n .showHelpAfterError()\n .exitOverride((err) => {\n if (err.code === \"commander.unknownCommand\") {\n process.exit(0);\n }\n });\n\n// Show help by default if no arguments provided\nif (process.argv.length <= 2) {\n program.help({ error: false });\n}\n\n/**\n * The 'run' command executes routes from a single file.\n *\n * Example:\n * craft run ./my-routes.ts\n * craft run ./my-cli.ts greet --name World\n */\nprogram\n .command(\"run\")\n .description(\"Run routes from a single TypeScript/JavaScript file\")\n .argument(\"<file>\", \"Path to a file containing routes\")\n .argument(\n \"[args...]\",\n \"CLI command and flags to pass through to CLI adapter routes\",\n )\n .option(\n \"--env <path>\",\n \"Load environment variables from a .env file (default: .env)\",\n )\n .passThroughOptions()\n .action(async (filePath, args: string[], options) => {\n // Apply global log options to env before any import that creates the logger\n const globalOpts = program.opts();\n if (globalOpts[\"logLevel\"] !== undefined) {\n process.env[\"LOG_LEVEL\"] = globalOpts[\"logLevel\"];\n process.env[\"CRAFT_LOG_LEVEL\"] = globalOpts[\"logLevel\"];\n }\n if (globalOpts[\"logFile\"] !== undefined) {\n process.env[\"LOG_FILE\"] = globalOpts[\"logFile\"];\n process.env[\"CRAFT_LOG_FILE\"] = globalOpts[\"logFile\"];\n }\n\n const { loadEnvFile } = await import(\"./util.js\");\n if (options.env !== undefined) {\n loadEnvFile(options.env);\n } else {\n loadEnvFile();\n }\n\n const { runCommand } = await import(\"./run.js\");\n const result = await runCommand(filePath, args);\n if (!result.success) {\n if (result.message) {\n // eslint-disable-next-line no-console\n console.error(result.message);\n }\n // Defer exit so pino/sonic-boom can finish initializing and avoid \"sonic boom is not ready yet\"\n const code = result.code ?? 1;\n setImmediate(() => process.exit(code));\n return;\n }\n // Don't call process.exit(); let the event loop drain naturally.\n // process.exit() triggers C++ static destructors that race with ONNX\n // Runtime cleanup (onnxruntime#25038: \"mutex lock failed\").\n });\n\n/**\n * The 'tui' command launches the Terminal UI for monitoring Routecraft execution.\n *\n * Example:\n * craft tui\n * craft tui --db .routecraft/telemetry.db\n */\nprogram\n .command(\"tui\")\n .description(\"Launch the Terminal UI to monitor Routecraft execution history\")\n .option(\n \"--db <path>\",\n \"Path to the telemetry SQLite database\",\n \".routecraft/telemetry.db\",\n )\n .action(async (options) => {\n const { resolve, isAbsolute } = await import(\"node:path\");\n const dbPath = isAbsolute(options.db)\n ? options.db\n : resolve(process.cwd(), options.db);\n\n const { renderTui } = await import(\"./tui/app.js\");\n await renderTui(dbPath);\n });\n\n// Parse the command line arguments and execute the appropriate command\nprogram.parse();\n"]}
|
package/dist/tui/app.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {a}from'../chunk-5UHEZNN5.js';import {useState,useCallback,useEffect,Fragment as Fragment$1}from'react';import {render,useApp,useStdout,useInput,Box,Text}from'ink';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var st=[{items:[{key:"capabilities",label:"Capabilities",shortcut:"1"}]},{items:[{key:"exchanges",label:"Exchanges",shortcut:"2"},{key:"errors",label:"Errors",shortcut:"3"},{key:"events",label:"Events",shortcut:"4"}]}],
|
|
1
|
+
import {a as a$1}from'../chunk-TDKTL4RU.js';import {a}from'../chunk-5UHEZNN5.js';import {useState,useCallback,useEffect,Fragment as Fragment$1}from'react';import {render,useApp,useStdout,useInput,Box,Text}from'ink';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var st=[{items:[{key:"capabilities",label:"Capabilities",shortcut:"1"}]},{items:[{key:"exchanges",label:"Exchanges",shortcut:"2"},{key:"errors",label:"Errors",shortcut:"3"},{key:"events",label:"Events",shortcut:"4"}]}],Dt=st.flatMap(e=>e.items);function ge(e,t){return t<=0?"":e.length>t?e.slice(0,t-1)+"\u2026":e}function _(e){return e==null||!Number.isFinite(e)||e<0?"-":e===0?"<1ms":e<1e3?`${Math.round(e)}ms`:`${(e/1e3).toFixed(1)}s`}function oe(e){switch(e){case "completed":case "started":return "green";case "failed":return "red";case "stopped":case "dropped":return "yellow";default:return "white"}}function B(e,t){return t===void 0?e:t<=0?"":e.length>t?e.slice(0,t-1)+"\u2026":e.padEnd(t)}function Xt(e){try{let t=JSON.parse(e),o="exchangeId"in t?`${String(t.exchangeId).slice(0,8)}`:"",s="duration"in t?_(t.duration):"";if("operation"in t&&"routeId"in t){let r="adapter"in t?`(${t.adapter})`:"adapterId"in t?`(${t.adapterId})`:"",n="";if("metadata"in t&&typeof t.metadata=="object"&&t.metadata!==null){let u=t.metadata,l=Object.keys(u).slice(0,2);l.length>0&&(n=l.map(m=>`${m}=${u[m]}`).join(" "));}return {step:String(t.operation),adapter:r,exchange:o,duration:s,meta:n}}if("routeId"in t&&"exchangeId"in t){let r="error"in t?"(err)":"reason"in t?`(${String(t.reason).slice(0,8)})`:"";return {step:String(t.routeId),adapter:r,exchange:o,duration:s,meta:""}}if("route"in t&&typeof t.route=="object"&&t.route!==null){let r=t.route;return {step:r.routeId??r.definition?.id??"?",adapter:"",exchange:"",duration:"",meta:""}}if("pluginId"in t)return {step:`plugin=${t.pluginId}`,adapter:"",exchange:"",duration:"",meta:""};if("error"in t){let r=t.error;return {step:typeof r=="object"&&r!==null&&"message"in r?String(r.message):String(r),adapter:"",exchange:"",duration:"",meta:""}}return null}catch{return null}}function It(e,t){let o=Xt(t);return o||{step:t,adapter:"",exchange:"",duration:"",meta:""}}function q(e){return e.toLocaleString("en-US")}function at(e,t,o){return o<=0?t:e<t?e:e>=t+o?e-o+1:t}function Ce(e=0){let[t,o]=useState(e),[s,r]=useState(0),n=useCallback((m,d,g)=>{let p=Math.max(0,Math.min(m,d-1));o(p),r(f=>at(p,f,g));},[]),u=useCallback((m,d,g)=>{o(p=>{let f=Math.max(0,Math.min(p+m,d-1));return r(i=>at(f,i,g)),f});},[]),l=useCallback(()=>{o(0),r(0);},[]);return {selectedIndex:t,scrollOffset:s,moveBy:u,moveTo:n,reset:l}}function S({title:e,subtitle:t,color:o="gray",width:s,flexGrow:r,paddingX:n=1,children:u}){let l=s?s-2-n*2:20;return jsxs(Box,{flexDirection:"column",borderStyle:"round",borderColor:o,paddingX:n,width:s,flexGrow:r,children:[e&&jsxs(Fragment,{children:[jsxs(Text,{bold:true,children:[e,t&&jsxs(Fragment,{children:[" ",t]})]}),jsx(Text,{dimColor:true,children:"\u2500".repeat(Math.max(l,1))})]}),u]})}var qt=[192,36,18,9],Yt=10240,De=[{max:0,color:"gray"},{max:10,color:"green"},{max:20,color:"green"},{max:30,color:"yellow"},{max:40,color:"yellow"},{max:50,color:"red"}];function He({values:e,columns:t,steps:o=De,label:s}){let r=o.length-1,n=e.length>=t?e.slice(e.length-t):[...new Array(t-e.length).fill(0),...e],u=n.map(d=>{if(d<=0)return 0;for(let g=1;g<o.length;g++)if(d<o[g].max)return g;return r}),l=Math.ceil(r/4),m=[];for(let d=l-1;d>=0;d--){let g=d*4,p=[];for(let f=0;f<n.length;f++){let i=u[f],y=0,k="";for(let X=0;X<4;X++){let E=g+X+1;if(E>r)break;(i>=E||i===0&&E===1)&&(y|=qt[X],k=i===0?o[0].color:o[E].color);}let L=String.fromCharCode(Yt+y),K=p[p.length-1];K&&K.color===k?K.text+=L:p.push({text:L,color:k});}m.push(jsx(Text,{children:p.map((f,i)=>f.color?jsx(Text,{color:f.color,children:f.text},i):jsx(Text,{children:f.text},i))},d));}return jsxs(Fragment,{children:[m,s&&jsx(Text,{dimColor:true,children:s})]})}function Bt({route:e}){return jsxs(Fragment,{children:[jsxs(Text,{children:["Capability:"," ",jsx(Text,{bold:true,color:"cyan",children:e.id})]}),jsxs(Text,{children:["Status:"," ",jsx(Text,{bold:true,color:oe(e.status),children:e.status})," ","Exchanges: ",jsx(Text,{bold:true,children:q(e.totalExchanges)})," ","Errors:"," ",jsx(Text,{bold:true,...e.failedExchanges>0?{color:"red"}:{},children:q(e.failedExchanges)})," ","Dropped:"," ",jsx(Text,{bold:true,...e.droppedExchanges>0?{color:"yellow"}:{},children:q(e.droppedExchanges)})," ","Avg: ",jsx(Text,{bold:true,children:_(e.avgDurationMs)})]})]})}function Ee({columns:e,data:t,rowKey:o,selectedIndex:s,scrollOffset:r,visibleRows:n,gap:u=2,emptyMessage:l="No data",renderFullRow:m}){let d=" ".repeat(u),g=jsx(Box,{children:e.map((i,y)=>{let L=y===e.length-1?"":d;if(i.width==="flex")return jsxs(Fragment$1,{children:[jsx(Box,{flexGrow:1,children:jsx(Text,{bold:true,dimColor:true,children:i.header})}),L&&jsx(Text,{children:L})]},y);let K=i.align==="right"?i.header.padStart(i.width):B(i.header,i.width);return jsxs(Fragment$1,{children:[jsx(Text,{bold:true,dimColor:true,children:K}),L&&jsx(Text,{children:L})]},y)})});if(t.length===0)return jsxs(Fragment,{children:[g,jsx(Text,{dimColor:true,children:l})]});let p=t.slice(r,r+n),f=t.length-r-n;return jsxs(Fragment,{children:[g,p.map((i,y)=>{let k=r+y,L=k===s,K=m?.(i,k);return K!==void 0?jsx(Box,{children:K},o(i,k)):jsx(Box,{children:e.map((X,E)=>{let O=E===e.length-1?"":d,T=X.width==="flex"?void 0:X.width,w=X.render(i,L,T);return X.width==="flex"?jsxs(Fragment$1,{children:[jsx(Box,{flexGrow:1,children:jsx(Text,{wrap:"truncate",children:w})}),O&&jsx(Text,{children:O})]},E):jsxs(Fragment$1,{children:[w,O&&jsx(Text,{children:O})]},E)})},o(i,k))}),jsx(Text,{dimColor:true,children:f>0?"\u2193 more":" "})]})}function Je(e){let t=new WeakMap;function o(s){let r=e(s);if(!r)return;let n=t.get(r);return n||(n=It(r.eventName,r.details),t.set(r,n)),n}return [{header:"Step",width:10,render:(s,r,n)=>{let u=o(s);return u?jsx(Text,{children:B(u.step,n)}):jsx(Text,{children:B("",n)})}},{header:"Adapter",width:10,render:(s,r,n)=>{let u=o(s);return u?jsx(Text,{children:B(u.adapter,n)}):jsx(Text,{children:B("",n)})}},{header:"Exchange",width:12,render:(s,r,n)=>{let u=o(s);return u?jsx(Text,{children:B(u.exchange,n)}):jsx(Text,{children:B("",n)})}},{header:"Duration",width:8,align:"right",render:s=>{let r=o(s);return r?jsx(Text,{children:r.duration.padStart(8)}):jsx(Text,{children:""})}}]}function Te(){return {header:"",width:2,render:(e,t)=>jsx(Text,{...t?{color:"cyan"}:{},bold:t,children:t?"> ":" "})}}var tr=[Te(),{header:"ID",width:"flex",render:(e,t)=>jsx(Text,{...t?{color:"cyan"}:{},bold:t,children:e.id})},{header:"Status",width:9,render:(e,t,o)=>jsx(Text,{color:oe(e.status),children:B(e.status,o)})},{header:"Duration",width:8,align:"right",render:e=>jsx(Text,{children:_(e.durationMs).padStart(8)})},{header:"Time",width:8,render:(e,t,o)=>jsx(Text,{dimColor:true,children:B(e.startedAt.replace("T"," ").slice(11,19),o)})}];function Ve({capabilityId:e,route:t,exchanges:o,selectedIndex:s,scrollOffset:r,width:n,height:u,color:l="gray",activity:m}){let d=Math.ceil((De.length-1)/4),g=t?2+d+2:0,p=Math.max(u-6-g,3),f=t?"EXCHANGES":`EXCHANGES: ${e}`;return jsxs(Box,{flexDirection:"column",width:n,flexGrow:1,children:[t&&jsxs(S,{width:n,children:[jsx(Bt,{route:t}),jsx(Text,{children:" "}),jsx(He,{values:m?m.throughput:[],columns:n-4,label:"Exchanges per 5s bucket"})]}),jsx(S,{title:f,width:n,flexGrow:1,color:l,children:jsx(Ee,{columns:tr,data:o,rowKey:i=>i.id+i.contextId,selectedIndex:s,scrollOffset:r,visibleRows:p,emptyMessage:"No exchanges"})})]})}function rr(e){let t=[],o=/("(?:[^"\\]|\\.)*")\s*:|("(?:[^"\\]|\\.)*")|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)|(\btrue\b|\bfalse\b)|(\bnull\b)|([{}[\],:])/g,s=0,r;for(;(r=o.exec(e))!==null;)r.index>s&&t.push({text:e.slice(s,r.index),type:"brace"}),r[1]!==void 0?(t.push({text:r[1],type:"key"}),t.push({text:":",type:"brace"})):r[2]!==void 0?t.push({text:r[2],type:"string"}):r[3]!==void 0?t.push({text:r[3],type:"number"}):r[4]!==void 0?t.push({text:r[4],type:"boolean"}):r[5]!==void 0?t.push({text:r[5],type:"null"}):r[6]!==void 0&&t.push({text:r[6],type:"brace"}),s=r.index+r[0].length;return s<e.length&&t.push({text:e.slice(s),type:"brace"}),t}var nr={key:"cyan",string:"green",number:"yellow",boolean:"yellow",null:"red",brace:"gray"};function Ae(e,t){try{let o=JSON.parse(e);return JSON.stringify(o,null,2).split(`
|
|
2
2
|
`).map(r=>{let n=Math.max(1,t);return r.length>n?r.slice(0,Math.max(0,n-1))+"\u2026":r})}catch{let o=Math.max(1,t);return e.split(`
|
|
3
|
-
`).map(s=>s.length>o?s.slice(0,Math.max(0,o-1))+"\u2026":s)}}function Ue({line:e}){let t=tr(e);return t.length===0?jsx(Text,{children:e}):jsx(Text,{children:t.map((o,s)=>jsx(Text,{color:rr[o.type],children:o.text},s))})}function Xe(e){try{let t=JSON.parse(e);return typeof t!="object"||t===null||Array.isArray(t)?null:t}catch{return null}}function or(e,t){let o=new Map,s=0;o.set(t,{exchangeId:t,label:"parent",events:[]});for(let r of e){let n=Xe(r.details),u=n?String(n.exchangeId??""):"",l=!u||u===t?t:u;o.has(l)||(s++,o.set(l,{exchangeId:l,label:`child ${s}`,events:[]})),o.get(l).events.push(r);}return Array.from(o.values())}var sr=[Te(),{header:"Time",width:8,render:(e,t,o)=>{if(!e.event)return jsx(Text,{children:N("",o)});let s=" ".repeat(e.indent);return jsxs(Text,{dimColor:true,children:[s,e.event.timestamp.replace("T"," ").slice(11,19)]})}},{header:"Event",width:"flex",render:e=>e.event?jsx(Text,{color:"cyan",children:e.event.eventName}):jsx(Text,{})},...Je(e=>e.event)];function We({exchange:e,events:t,width:o,height:s,scrollOffset:r,selectedIndex:n=-1,color:u="gray"}){let l=e.error?2:0,m=Math.max(s-9-l,3),d=or(t,e.id),g=d.length>1,p=[];for(let i of d){g&&p.push({type:"header",text:`${i.label} (${i.exchangeId.slice(0,8)}) - ${i.events.length} events`,indent:0});for(let y of i.events)p.push({type:"event",event:y,indent:g?2:0});}let f=g?`EXCHANGE FLOW (${d.length} exchanges, ${t.length} events)`:`RELATED EVENTS (${t.length})`;return jsxs(Box,{flexDirection:"column",width:o,flexGrow:1,children:[jsxs(S,{width:o,children:[jsxs(Text,{children:["Capability:"," ",jsx(Text,{bold:true,color:"cyan",children:e.routeId})]}),jsxs(Text,{children:["Exchange:"," ",jsx(Text,{bold:true,color:"cyan",children:ge(e.id,o-14)})]}),jsxs(Text,{children:["Status:"," ",jsx(Text,{bold:true,color:oe(e.status),children:e.status}),e.durationMs!==null&&jsxs(Text,{children:[" ","Duration:"," ",jsx(Text,{bold:true,children:_(e.durationMs)})]})," ","Started: ",jsx(Text,{bold:true,children:e.startedAt}),e.completedAt&&jsxs(Text,{children:[" ","Completed: ",jsx(Text,{bold:true,children:e.completedAt})]})]}),e.error&&e.status==="failed"&&jsxs(Fragment,{children:[jsx(Text,{children:" "}),jsxs(Text,{color:"red",children:["Error: ",e.error]})]}),e.error&&e.status==="dropped"&&jsxs(Fragment,{children:[jsx(Text,{children:" "}),jsxs(Text,{color:"yellow",children:["Reason: ",e.error]})]})]}),jsx(S,{title:f,width:o,flexGrow:1,color:u,children:jsx(Ee,{columns:sr,data:p,rowKey:(i,y)=>i.type==="header"?`h-${y}`:`${i.event?.id??i.event?.timestamp}-${y}`,selectedIndex:n,scrollOffset:r,visibleRows:m,emptyMessage:"No related events found",renderFullRow:i=>i.type==="header"?jsx(Text,{bold:true,color:"yellow",children:i.text}):void 0})})]})}var ar=[Te(),{header:"Time",width:19,render:(e,t,o)=>jsx(Text,{...t?{color:"cyan"}:{},bold:t,children:N(e.timestamp.replace("T"," ").slice(0,19),o)})},{header:"Event",width:"flex",render:e=>jsx(Text,{color:"cyan",children:e.eventName})},...Je(e=>e)];function Ot({events:e,selectedIndex:t,scrollOffset:o,width:s,height:r,color:n="gray"}){let u=Math.max(r-6,5);return jsx(S,{title:"EVENTS",subtitle:jsxs(Text,{dimColor:true,children:["(",e.length," total)"]}),width:s,flexGrow:1,color:n,children:jsx(Ee,{columns:ar,data:e,rowKey:(l,m)=>l.id!==void 0?String(l.id):`${l.timestamp}-${m}`,selectedIndex:t,scrollOffset:o,visibleRows:u,emptyMessage:"No events recorded yet."})})}function Ne({event:e,width:t,height:o,scrollOffset:s,color:r="cyan"}){let n=Xe(e.details),u=n&&typeof n.routeId=="string"?n.routeId:void 0,l=n&&typeof n.exchangeId=="string"?n.exchangeId:void 0,d=2+(1+(u?1:0)+(l?1:0)+2),g=5,p=Math.max(t-6,20),f=Ae(e.details,p),i=Math.max(o-d-g,3),y=f.slice(s,s+i);return jsxs(Box,{flexDirection:"column",width:t,flexGrow:1,children:[jsxs(S,{width:t,children:[jsxs(Text,{children:["Context:"," ",jsx(Text,{bold:true,color:"cyan",children:e.contextId})]}),u&&jsxs(Text,{children:["Capability:"," ",jsx(Text,{bold:true,color:"cyan",children:u})]}),l&&jsxs(Text,{children:["Exchange:"," ",jsx(Text,{bold:true,color:"cyan",children:l})]}),jsxs(Text,{children:["Event:"," ",jsx(Text,{bold:true,color:"cyan",children:e.eventName})]}),jsxs(Text,{children:["Time: ",jsx(Text,{bold:true,children:e.timestamp.replace("T"," ")})]})]}),jsxs(S,{title:"DETAILS",subtitle:jsxs(Text,{dimColor:true,children:["(",s+1,"-",Math.min(s+i,f.length),"/",f.length," lines)"]}),width:t,flexGrow:1,color:r,children:[y.map((k,L)=>jsx(Ue,{line:k},s+L)),y.length<i&&Array.from({length:i-y.length}).map((k,L)=>jsx(Text,{children:" "},`pad-${L}`))]})]})}function dr(e,t){let o=[];return o.push("HEADERS"),o.push(...Ae(e.headers,t)),o.push(""),o.push("BODY"),e.body!==null?(o.push(...Ae(e.body,t)),e.truncated&&(o.push(""),o.push("[Body truncated to configured limit]"))):o.push("[null]"),o}function qe({exchange:e,snapshot:t,width:o,height:s,scrollOffset:r,color:n="cyan"}){let m=Math.max(o-6,20),d=Math.max(s-5-5,3),p=t!==null?dr(t,m):["[Snapshots not captured]","","Enable with:"," telemetry({ sqlite: { captureSnapshots: true } })"],f=p.slice(r,r+d);return jsxs(Box,{flexDirection:"column",width:o,flexGrow:1,children:[jsxs(S,{width:o,children:[jsxs(Text,{children:["Capability:"," ",jsx(Text,{bold:true,color:"cyan",children:e.routeId})]}),jsxs(Text,{children:["Exchange:"," ",jsx(Text,{bold:true,color:"cyan",children:ge(e.id,o-14)})]}),jsxs(Text,{children:["Status:"," ",jsx(Text,{bold:true,color:oe(e.status),children:e.status}),e.durationMs!==null&&jsxs(Text,{children:[" ","Duration:"," ",jsx(Text,{bold:true,children:_(e.durationMs)})]})]})]}),jsxs(S,{title:"EXCHANGE SNAPSHOT",subtitle:jsxs(Text,{dimColor:true,children:["(",r+1,"-",Math.min(r+d,p.length),"/",p.length," lines)"]}),width:o,flexGrow:1,color:n,children:[f.map((i,y)=>i==="HEADERS"||i==="BODY"?jsx(Text,{bold:true,color:"yellow",children:i},r+y):i.startsWith("[")?jsx(Text,{dimColor:true,children:i},r+y):jsx(Ue,{line:i},r+y)),f.length<d&&Array.from({length:d-f.length}).map((i,y)=>jsx(Text,{children:" "},`pad-${y}`))]})]})}function ur(e){return e.failedExchanges>0?"red":e.totalExchanges>0?"green":"yellow"}function _t({routes:e,selectedIndex:t,listOffset:o,visibleRows:s,width:r}){let n=o;return jsxs(Fragment,{children:[jsx(Text,{children:" "}),jsx(Text,{bold:true,dimColor:true,children:"\u2500".repeat(r+2)}),e.length===0?jsx(Text,{dimColor:true,children:"No capabilities"}):e.slice(n,n+s).map((u,l)=>{let m=n+l;return jsxs(Text,{wrap:"truncate",children:[jsx(Text,{...m===t?{color:"cyan"}:{},bold:m===t,children:m===t?"> ":" "}),jsx(Text,{color:ur(u),children:"\u25CF "}),jsx(Text,{...m===t?{color:"cyan"}:{},bold:m===t,children:ge(u.id,r-2)})]},u.id)}),e.length>s&&jsxs(Text,{dimColor:true,children:[t+1,"/",e.length]})]})}function yr({db:e}){let{exit:t}=useApp(),{stdout:o}=useStdout(),s=o?.columns??80,r=o?.rows??24,[n,u]=useState("capabilities"),[l,m]=useState("nav"),[d,g]=useState(false),[p,f]=useState([]),[i,y]=useState({totalRoutes:0,totalExchanges:0,completedExchanges:0,failedExchanges:0,droppedExchanges:0,errorRate:0,avgDurationMs:null,p90DurationMs:null,p95DurationMs:null,p99DurationMs:null}),[k,L]=useState([]),[K,X]=useState(void 0),E=Ce(),[W,O]=useState([]),T=Ce(),[w,ht]=useState(void 0),[he,ft]=useState([]),[Be,gt]=useState([]),te=Ce(),F=Ce(),[re,bt]=useState(void 0),[G,ce]=useState(false),[Le,ne]=useState(0),[H,Ye]=useState(false),[ze,ke]=useState(0),[Qe,Pt]=useState(null),fe=50,de=10,Oe=Math.max(Math.min(Math.floor(s*.18),26),16),ue=Math.max(Math.min(Math.floor(s*.22),30),20),A=Math.max(s-Oe-ue,30),R=Math.max(r-5,10),Ze=Math.max(R-10,3),et=useCallback(()=>{try{let c=e.getRouteSummary();f(c),y(e.getMetrics());let a=ue-4;L(e.getLiveTrafficBuckets(a,5));let I=A-4,b=c[E.selectedIndex];if(b&&X(e.getSingleRouteActivity(b.id,I,5)),l==="center")return;if(n==="capabilities"){let h=c[E.selectedIndex];h&&O(e.getExchangesByRoute(h.id,fe));}else n==="exchanges"?O(e.getAllExchanges(fe)):n==="errors"?O(e.getFailedExchanges(fe)):n==="events"&>(e.getRecentEvents({limit:200}));}catch{}},[e,n,E.selectedIndex,ue,A,l]);useEffect(()=>{et();let c=setInterval(et,2e3);return ()=>{clearInterval(c);}},[et]);let yt=useCallback(c=>{E.moveTo(c,p.length,Ze),T.reset();let a=p[c];a&&O(e.getExchangesByRoute(a.id,fe));},[e,p,E,T,Ze]),jt=useCallback(c=>{u(c),g(false),ce(false),Ye(false),m("nav"),T.reset(),c==="exchanges"?O(e.getAllExchanges(fe)):c==="errors"?O(e.getFailedExchanges(fe)):c==="events"&&(te.reset(),gt(e.getRecentEvents({limit:200})));},[e,T,te]),tt=p[E.selectedIndex],Gt=Math.ceil((De.length-1)/4),Ft=tt?2+Gt+2:0,_e=Math.max(R-6-Ft,3),Et=Math.max(R-6,5);useInput((c,a)=>{if(c==="q"){e.close(),t();return}let I=Ct.find(b=>b.shortcut===c);if(I){jt(I.key);return}if(n==="events"){if(G){let b=a.ctrl?de:1;c==="j"||a.downArrow?ne(h=>h+b):c==="k"||a.upArrow?ne(h=>Math.max(h-b,0)):(a.escape||a.backspace||a.delete)&&(ce(false),ne(0));return}if(l==="nav")a.return&&m("center");else {let b=a.ctrl?de:1;if(c==="j"||a.downArrow)te.moveBy(b,Be.length,Et);else if(c==="k"||a.upArrow)te.moveBy(-b,Be.length,Et);else if(a.return){let h=Be[te.selectedIndex];h&&(bt(h),ne(0),ce(true));}else (a.escape||a.backspace||a.delete)&&(m("nav"),te.reset());}return}if(H){let b=a.ctrl?de:1;c==="j"||a.downArrow?ke(h=>h+b):c==="k"||a.upArrow?ke(h=>Math.max(h-b,0)):(a.escape||a.backspace||a.delete)&&(Ye(false),ke(0));return}if(d&&!G){let b=w?.error?2:0,h=Math.max(R-9-b,3),$t=new Set(he.map(me=>{try{let Re=JSON.parse(me.details);return String(Re.exchangeId??"")}catch{return ""}})),vt=Math.max($t.size,1),Jt=vt>1?vt:0,wt=he.length+Jt,Rt=a.ctrl?de:1;if(c==="j"||a.downArrow)F.moveBy(Rt,wt,h);else if(c==="k"||a.upArrow)F.moveBy(-Rt,wt,h);else if(a.return){let me=0,Re,Pe=w?.id??"",xe=new Map;xe.set(Pe,[]);for(let Se of he)try{let rt=JSON.parse(Se.details),nt=String(rt.exchangeId??""),ot=!nt||nt===Pe?Pe:nt;xe.has(ot)||xe.set(ot,[]),xe.get(ot).push(Se);}catch{xe.get(Pe).push(Se);}let Vt=xe.size>1;for(let[,Se]of xe){Vt&&me++;for(let rt of Se)me===F.selectedIndex&&(Re=rt),me++;}Re&&(bt(Re),ne(0),ce(true));}else if(c==="e"&&w){let me=e.getExchangeSnapshot(w.id);Pt(me),ke(0),Ye(true);}else (a.escape||a.backspace||a.delete)&&(F.reset(),g(false));return}if(d&&G){let b=a.ctrl?de:1;c==="j"||a.downArrow?ne(h=>h+b):c==="k"||a.upArrow?ne(h=>Math.max(h-b,0)):(a.escape||a.backspace||a.delete)&&(ce(false),ne(0));return}if(n==="capabilities"&&l==="nav"){if(c==="j"||a.downArrow)yt(Math.min(E.selectedIndex+1,p.length-1));else if(c==="k"||a.upArrow)yt(Math.max(E.selectedIndex-1,0));else if(a.return){m("center");let b=p[E.selectedIndex];b&&O(e.getExchangesByRoute(b.id));}return}if(n==="capabilities"&&l==="center"){let b=a.ctrl?de:1;if(c==="j"||a.downArrow)T.moveBy(b,W.length,_e);else if(c==="k"||a.upArrow)T.moveBy(-b,W.length,_e);else if(a.return){let h=W[T.selectedIndex];h&&(ht(h),ft(e.getEventsByExchange(h.id,h.correlationId)),F.reset(),ce(false),g(true));}else (a.escape||a.backspace||a.delete)&&(m("nav"),T.reset());return}if(n==="exchanges"||n==="errors"){if(l==="nav")a.return&&(m("center"),O(n==="exchanges"?e.getAllExchanges():e.getFailedExchanges()));else {let b=a.ctrl?de:1;if(c==="j"||a.downArrow)T.moveBy(b,W.length,_e);else if(c==="k"||a.upArrow)T.moveBy(-b,W.length,_e);else if(a.return){let h=W[T.selectedIndex];h&&(ht(h),ft(e.getEventsByExchange(h.id,h.correlationId)),F.reset(),ce(false),g(true));}else (a.escape||a.backspace||a.delete)&&(m("nav"),T.reset());}return}});let Tt=n==="capabilities"&&l==="nav"&&!d,Ht=!Tt,D=[];return H?(D.push({key:"j/k",action:"Scroll"}),D.push({key:"Ctrl+j/k",action:"Jump 10"}),D.push({key:"Esc",action:"Back"})):l==="center"&&(D.push({key:"j/k",action:"Navigate"}),D.push({key:"Ctrl+j/k",action:"Jump 10"})),H||(l==="nav"?n==="capabilities"?(D.push({key:"j/k",action:"Navigate"}),D.push({key:"Enter",action:"Exchanges"})):D.push({key:"Enter",action:"Browse"}):!d&&!G?(D.push({key:"Enter",action:"Detail"}),D.push({key:"Esc",action:"Back"})):d&&!G?(D.push({key:"Enter",action:"Event detail"}),D.push({key:"e",action:"Snapshot"}),D.push({key:"Esc",action:"Back"})):D.push({key:"Esc",action:"Back"})),D.push({key:"1..4",action:"Switch view"}),D.push({key:"q",action:"Quit"}),jsxs(Box,{flexDirection:"column",width:s,height:r,children:[jsxs(Box,{borderStyle:"round",borderColor:"cyan",paddingX:1,width:s,children:[jsx(Text,{bold:true,color:"cyan",children:"ROUTECRAFT TUI"}),jsx(Text,{children:" "}),jsx(Text,{dimColor:true,children:"v0.4.0"})]}),jsxs(Box,{flexDirection:"row",width:s,flexGrow:1,children:[jsx(Box,{flexDirection:"column",width:Oe,children:jsxs(S,{title:"NAVIGATION",color:Tt?"cyan":"gray",width:Oe,flexGrow:1,children:[st.map((c,a)=>jsxs(Box,{flexDirection:"column",children:[a>0&&jsx(Text,{children:" "}),c.label&&jsx(Text,{dimColor:true,bold:true,children:c.label}),c.items.map(I=>jsxs(Text,{children:[jsxs(Text,{bold:n===I.key,...n===I.key?{color:"cyan"}:{},children:[n===I.key?"> ":" ",I.label]}),jsxs(Text,{dimColor:true,children:[" (",I.shortcut,")"]})]},I.key))]},c.label??a)),n==="capabilities"&&jsx(_t,{routes:p,selectedIndex:E.selectedIndex,listOffset:E.scrollOffset,visibleRows:Ze,width:Oe-6})]})}),n==="capabilities"&&!d&&jsx(Ve,{capabilityId:tt?.id??"",route:tt,exchanges:W,selectedIndex:l==="center"?T.selectedIndex:-1,scrollOffset:l==="center"?T.scrollOffset:0,width:A,height:R,color:Ht?"cyan":"gray",activity:K}),n==="capabilities"&&H&&w&&jsx(qe,{exchange:w,snapshot:Qe,width:A,height:R,scrollOffset:ze,color:"cyan"}),n==="capabilities"&&d&&w&&!G&&!H&&jsx(We,{exchange:w,events:he,width:A,height:R,selectedIndex:F.selectedIndex,scrollOffset:F.scrollOffset,color:"cyan"}),n==="capabilities"&&d&&G&&!H&&re&&jsx(Ne,{event:re,width:A,height:R,scrollOffset:Le,color:"cyan"}),n==="exchanges"&&!d&&jsx(Ve,{capabilityId:"All Capabilities",exchanges:W,selectedIndex:l==="center"?T.selectedIndex:-1,scrollOffset:l==="center"?T.scrollOffset:0,width:A,height:R,color:l==="center"?"cyan":"gray"}),n==="exchanges"&&H&&w&&jsx(qe,{exchange:w,snapshot:Qe,width:A,height:R,scrollOffset:ze,color:"cyan"}),n==="exchanges"&&d&&w&&!G&&!H&&jsx(We,{exchange:w,events:he,width:A,height:R,selectedIndex:F.selectedIndex,scrollOffset:F.scrollOffset,color:"cyan"}),n==="exchanges"&&d&&G&&!H&&re&&jsx(Ne,{event:re,width:A,height:R,scrollOffset:Le,color:"cyan"}),n==="errors"&&!d&&jsx(Ve,{capabilityId:"Failed Exchanges",exchanges:W,selectedIndex:l==="center"?T.selectedIndex:-1,scrollOffset:l==="center"?T.scrollOffset:0,width:A,height:R,color:l==="center"?"cyan":"gray"}),n==="errors"&&H&&w&&jsx(qe,{exchange:w,snapshot:Qe,width:A,height:R,scrollOffset:ze,color:"cyan"}),n==="errors"&&d&&w&&!G&&!H&&jsx(We,{exchange:w,events:he,width:A,height:R,selectedIndex:F.selectedIndex,scrollOffset:F.scrollOffset,color:"cyan"}),n==="errors"&&d&&G&&!H&&re&&jsx(Ne,{event:re,width:A,height:R,scrollOffset:Le,color:"cyan"}),n==="events"&&!G&&jsx(Ot,{events:Be,selectedIndex:l==="center"?te.selectedIndex:-1,scrollOffset:l==="center"?te.scrollOffset:0,width:A,height:R,color:l==="center"?"cyan":"gray"}),n==="events"&&G&&re&&jsx(Ne,{event:re,width:A,height:R,scrollOffset:Le,color:"cyan"}),jsxs(Box,{flexDirection:"column",width:ue,children:[jsxs(S,{title:"METRICS",width:ue,flexGrow:1,children:[jsx(He,{values:k,columns:ue-4,steps:[{max:0,color:"gray"},...Array.from({length:7},(c,a)=>({max:(a+1)*5,color:"green"})),...Array.from({length:7},(c,a)=>({max:35+(a+1)*10,color:"yellow"})),...Array.from({length:6},(c,a)=>({max:105+(a+1)*25,color:"red"}))],label:"Exchanges per 5s bucket"}),jsx(Text,{children:" "}),jsx(Text,{bold:true,dimColor:true,children:"THROUGHPUT"}),[["Exchanges",q(i.totalExchanges),"cyan"],["Completed",q(i.completedExchanges),"green"],["Errors",q(i.failedExchanges),i.failedExchanges>0?"red":"green"],["Dropped",q(i.droppedExchanges),i.droppedExchanges>0?"yellow":"green"],["Error Rate",`${(i.errorRate*100).toFixed(1)}%`,i.errorRate>.1?"red":"green"],["Capabilities",q(i.totalRoutes),""]].map(([c,a,I])=>jsxs(Box,{children:[jsxs(Text,{children:[c,":"]}),jsx(Box,{flexGrow:1,justifyContent:"flex-end",children:jsx(Text,{bold:true,...I?{color:I}:{},children:a})})]},c)),jsx(Text,{children:" "}),jsx(Text,{bold:true,dimColor:true,children:"LATENCY (5m)"}),[["Avg",_(i.avgDurationMs),""],["p90",_(i.p90DurationMs),""],["p95",_(i.p95DurationMs),""],["p99",_(i.p99DurationMs),""]].map(([c,a,I])=>jsxs(Box,{children:[jsxs(Text,{children:[c,":"]}),jsx(Box,{flexGrow:1,justifyContent:"flex-end",children:jsx(Text,{bold:true,...I?{color:I}:{},children:a})})]},c))]}),jsx(S,{title:"KEYMAP",width:ue,children:D.map(c=>jsxs(Box,{children:[jsx(Text,{children:c.action}),jsx(Box,{flexGrow:1,justifyContent:"flex-end",children:jsxs(Text,{color:"yellow",children:["[",c.key,"]"]})})]},c.key))})]})]})]})}async function Zn(e){let t;try{t=await a.open(e);}catch(s){let r=s instanceof Error?s.message:String(s);process.stderr.write(`Failed to open telemetry database: ${r}
|
|
3
|
+
`).map(s=>s.length>o?s.slice(0,Math.max(0,o-1))+"\u2026":s)}}function Ue({line:e}){let t=rr(e);return t.length===0?jsx(Text,{children:e}):jsx(Text,{children:t.map((o,s)=>jsx(Text,{color:nr[o.type],children:o.text},s))})}function Xe(e){try{let t=JSON.parse(e);return typeof t!="object"||t===null||Array.isArray(t)?null:t}catch{return null}}function sr(e,t){let o=new Map,s=0;o.set(t,{exchangeId:t,label:"parent",events:[]});for(let r of e){let n=Xe(r.details),u=n?String(n.exchangeId??""):"",l=!u||u===t?t:u;o.has(l)||(s++,o.set(l,{exchangeId:l,label:`child ${s}`,events:[]})),o.get(l).events.push(r);}return Array.from(o.values())}var ar=[Te(),{header:"Time",width:8,render:(e,t,o)=>{if(!e.event)return jsx(Text,{children:B("",o)});let s=" ".repeat(e.indent);return jsxs(Text,{dimColor:true,children:[s,e.event.timestamp.replace("T"," ").slice(11,19)]})}},{header:"Event",width:"flex",render:e=>e.event?jsx(Text,{color:"cyan",children:e.event.eventName}):jsx(Text,{})},...Je(e=>e.event)];function We({exchange:e,events:t,width:o,height:s,scrollOffset:r,selectedIndex:n=-1,color:u="gray"}){let l=e.error?2:0,m=Math.max(s-9-l,3),d=sr(t,e.id),g=d.length>1,p=[];for(let i of d){g&&p.push({type:"header",text:`${i.label} (${i.exchangeId.slice(0,8)}) - ${i.events.length} events`,indent:0});for(let y of i.events)p.push({type:"event",event:y,indent:g?2:0});}let f=g?`EXCHANGE FLOW (${d.length} exchanges, ${t.length} events)`:`RELATED EVENTS (${t.length})`;return jsxs(Box,{flexDirection:"column",width:o,flexGrow:1,children:[jsxs(S,{width:o,children:[jsxs(Text,{children:["Capability:"," ",jsx(Text,{bold:true,color:"cyan",children:e.routeId})]}),jsxs(Text,{children:["Exchange:"," ",jsx(Text,{bold:true,color:"cyan",children:ge(e.id,o-14)})]}),jsxs(Text,{children:["Status:"," ",jsx(Text,{bold:true,color:oe(e.status),children:e.status}),e.durationMs!==null&&jsxs(Text,{children:[" ","Duration:"," ",jsx(Text,{bold:true,children:_(e.durationMs)})]})," ","Started: ",jsx(Text,{bold:true,children:e.startedAt}),e.completedAt&&jsxs(Text,{children:[" ","Completed: ",jsx(Text,{bold:true,children:e.completedAt})]})]}),e.error&&e.status==="failed"&&jsxs(Fragment,{children:[jsx(Text,{children:" "}),jsxs(Text,{color:"red",children:["Error: ",e.error]})]}),e.error&&e.status==="dropped"&&jsxs(Fragment,{children:[jsx(Text,{children:" "}),jsxs(Text,{color:"yellow",children:["Reason: ",e.error]})]})]}),jsx(S,{title:f,width:o,flexGrow:1,color:u,children:jsx(Ee,{columns:ar,data:p,rowKey:(i,y)=>i.type==="header"?`h-${y}`:`${i.event?.id??i.event?.timestamp}-${y}`,selectedIndex:n,scrollOffset:r,visibleRows:m,emptyMessage:"No related events found",renderFullRow:i=>i.type==="header"?jsx(Text,{bold:true,color:"yellow",children:i.text}):void 0})})]})}var ir=[Te(),{header:"Time",width:19,render:(e,t,o)=>jsx(Text,{...t?{color:"cyan"}:{},bold:t,children:B(e.timestamp.replace("T"," ").slice(0,19),o)})},{header:"Event",width:"flex",render:e=>jsx(Text,{color:"cyan",children:e.eventName})},...Je(e=>e)];function _t({events:e,selectedIndex:t,scrollOffset:o,width:s,height:r,color:n="gray"}){let u=Math.max(r-6,5);return jsx(S,{title:"EVENTS",subtitle:jsxs(Text,{dimColor:true,children:["(",e.length," total)"]}),width:s,flexGrow:1,color:n,children:jsx(Ee,{columns:ir,data:e,rowKey:(l,m)=>l.id!==void 0?String(l.id):`${l.timestamp}-${m}`,selectedIndex:t,scrollOffset:o,visibleRows:u,emptyMessage:"No events recorded yet."})})}function Ne({event:e,width:t,height:o,scrollOffset:s,color:r="cyan"}){let n=Xe(e.details),u=n&&typeof n.routeId=="string"?n.routeId:void 0,l=n&&typeof n.exchangeId=="string"?n.exchangeId:void 0,d=2+(1+(u?1:0)+(l?1:0)+2),g=5,p=Math.max(t-6,20),f=Ae(e.details,p),i=Math.max(o-d-g,3),y=f.slice(s,s+i);return jsxs(Box,{flexDirection:"column",width:t,flexGrow:1,children:[jsxs(S,{width:t,children:[jsxs(Text,{children:["Context:"," ",jsx(Text,{bold:true,color:"cyan",children:e.contextId})]}),u&&jsxs(Text,{children:["Capability:"," ",jsx(Text,{bold:true,color:"cyan",children:u})]}),l&&jsxs(Text,{children:["Exchange:"," ",jsx(Text,{bold:true,color:"cyan",children:l})]}),jsxs(Text,{children:["Event:"," ",jsx(Text,{bold:true,color:"cyan",children:e.eventName})]}),jsxs(Text,{children:["Time: ",jsx(Text,{bold:true,children:e.timestamp.replace("T"," ")})]})]}),jsxs(S,{title:"DETAILS",subtitle:jsxs(Text,{dimColor:true,children:["(",s+1,"-",Math.min(s+i,f.length),"/",f.length," lines)"]}),width:t,flexGrow:1,color:r,children:[y.map((k,L)=>jsx(Ue,{line:k},s+L)),y.length<i&&Array.from({length:i-y.length}).map((k,L)=>jsx(Text,{children:" "},`pad-${L}`))]})]})}function ur(e,t){let o=[];return o.push("HEADERS"),o.push(...Ae(e.headers,t)),o.push(""),o.push("BODY"),e.body!==null?(o.push(...Ae(e.body,t)),e.truncated&&(o.push(""),o.push("[Body truncated to configured limit]"))):o.push("[null]"),o}function qe({exchange:e,snapshot:t,width:o,height:s,scrollOffset:r,color:n="cyan"}){let m=Math.max(o-6,20),d=Math.max(s-5-5,3),p=t!==null?ur(t,m):["[Snapshots not captured]","","Enable with:"," telemetry({ sqlite: { captureSnapshots: true } })"],f=p.slice(r,r+d);return jsxs(Box,{flexDirection:"column",width:o,flexGrow:1,children:[jsxs(S,{width:o,children:[jsxs(Text,{children:["Capability:"," ",jsx(Text,{bold:true,color:"cyan",children:e.routeId})]}),jsxs(Text,{children:["Exchange:"," ",jsx(Text,{bold:true,color:"cyan",children:ge(e.id,o-14)})]}),jsxs(Text,{children:["Status:"," ",jsx(Text,{bold:true,color:oe(e.status),children:e.status}),e.durationMs!==null&&jsxs(Text,{children:[" ","Duration:"," ",jsx(Text,{bold:true,children:_(e.durationMs)})]})]})]}),jsxs(S,{title:"EXCHANGE SNAPSHOT",subtitle:jsxs(Text,{dimColor:true,children:["(",r+1,"-",Math.min(r+d,p.length),"/",p.length," lines)"]}),width:o,flexGrow:1,color:n,children:[f.map((i,y)=>i==="HEADERS"||i==="BODY"?jsx(Text,{bold:true,color:"yellow",children:i},r+y):i.startsWith("[")?jsx(Text,{dimColor:true,children:i},r+y):jsx(Ue,{line:i},r+y)),f.length<d&&Array.from({length:d-f.length}).map((i,y)=>jsx(Text,{children:" "},`pad-${y}`))]})]})}function mr(e){return e.failedExchanges>0?"red":e.totalExchanges>0?"green":"yellow"}function Pt({routes:e,selectedIndex:t,listOffset:o,visibleRows:s,width:r}){let n=o;return jsxs(Fragment,{children:[jsx(Text,{children:" "}),jsx(Text,{bold:true,dimColor:true,children:"\u2500".repeat(r+2)}),e.length===0?jsx(Text,{dimColor:true,children:"No capabilities"}):e.slice(n,n+s).map((u,l)=>{let m=n+l;return jsxs(Text,{wrap:"truncate",children:[jsx(Text,{...m===t?{color:"cyan"}:{},bold:m===t,children:m===t?"> ":" "}),jsx(Text,{color:mr(u),children:"\u25CF "}),jsx(Text,{...m===t?{color:"cyan"}:{},bold:m===t,children:ge(u.id,r-2)})]},u.id)}),e.length>s&&jsxs(Text,{dimColor:true,children:[t+1,"/",e.length]})]})}function Er({db:e}){let{exit:t}=useApp(),{stdout:o}=useStdout(),s=o?.columns??80,r=o?.rows??24,[n,u]=useState("capabilities"),[l,m]=useState("nav"),[d,g]=useState(false),[p,f]=useState([]),[i,y]=useState({totalRoutes:0,totalExchanges:0,completedExchanges:0,failedExchanges:0,droppedExchanges:0,errorRate:0,avgDurationMs:null,p90DurationMs:null,p95DurationMs:null,p99DurationMs:null}),[k,L]=useState([]),[K,X]=useState(void 0),E=Ce(),[W,O]=useState([]),T=Ce(),[w,ht]=useState(void 0),[he,ft]=useState([]),[Be,gt]=useState([]),te=Ce(),F=Ce(),[re,bt]=useState(void 0),[G,ce]=useState(false),[Le,ne]=useState(0),[H,Ye]=useState(false),[ze,ke]=useState(0),[Qe,jt]=useState(null),fe=50,de=10,Oe=Math.max(Math.min(Math.floor(s*.18),26),16),ue=Math.max(Math.min(Math.floor(s*.22),30),20),N=Math.max(s-Oe-ue,30),R=Math.max(r-5,10),Ze=Math.max(R-10,3),et=useCallback(()=>{try{let c=e.getRouteSummary();f(c),y(e.getMetrics());let a=ue-4;L(e.getLiveTrafficBuckets(a,5));let I=N-4,b=c[E.selectedIndex];if(b&&X(e.getSingleRouteActivity(b.id,I,5)),l==="center")return;if(n==="capabilities"){let h=c[E.selectedIndex];h&&O(e.getExchangesByRoute(h.id,fe));}else n==="exchanges"?O(e.getAllExchanges(fe)):n==="errors"?O(e.getFailedExchanges(fe)):n==="events"&>(e.getRecentEvents({limit:200}));}catch{}},[e,n,E.selectedIndex,ue,N,l]);useEffect(()=>{et();let c=setInterval(et,2e3);return ()=>{clearInterval(c);}},[et]);let yt=useCallback(c=>{E.moveTo(c,p.length,Ze),T.reset();let a=p[c];a&&O(e.getExchangesByRoute(a.id,fe));},[e,p,E,T,Ze]),Gt=useCallback(c=>{u(c),g(false),ce(false),Ye(false),m("nav"),T.reset(),c==="exchanges"?O(e.getAllExchanges(fe)):c==="errors"?O(e.getFailedExchanges(fe)):c==="events"&&(te.reset(),gt(e.getRecentEvents({limit:200})));},[e,T,te]),tt=p[E.selectedIndex],Ft=Math.ceil((De.length-1)/4),Ht=tt?2+Ft+2:0,_e=Math.max(R-6-Ht,3),Et=Math.max(R-6,5);useInput((c,a)=>{if(c==="q"){e.close(),t();return}let I=Dt.find(b=>b.shortcut===c);if(I){Gt(I.key);return}if(n==="events"){if(G){let b=a.ctrl?de:1;c==="j"||a.downArrow?ne(h=>h+b):c==="k"||a.upArrow?ne(h=>Math.max(h-b,0)):(a.escape||a.backspace||a.delete)&&(ce(false),ne(0));return}if(l==="nav")a.return&&m("center");else {let b=a.ctrl?de:1;if(c==="j"||a.downArrow)te.moveBy(b,Be.length,Et);else if(c==="k"||a.upArrow)te.moveBy(-b,Be.length,Et);else if(a.return){let h=Be[te.selectedIndex];h&&(bt(h),ne(0),ce(true));}else (a.escape||a.backspace||a.delete)&&(m("nav"),te.reset());}return}if(H){let b=a.ctrl?de:1;c==="j"||a.downArrow?ke(h=>h+b):c==="k"||a.upArrow?ke(h=>Math.max(h-b,0)):(a.escape||a.backspace||a.delete)&&(Ye(false),ke(0));return}if(d&&!G){let b=w?.error?2:0,h=Math.max(R-9-b,3),Jt=new Set(he.map(me=>{try{let Re=JSON.parse(me.details);return String(Re.exchangeId??"")}catch{return ""}})),vt=Math.max(Jt.size,1),Vt=vt>1?vt:0,wt=he.length+Vt,Rt=a.ctrl?de:1;if(c==="j"||a.downArrow)F.moveBy(Rt,wt,h);else if(c==="k"||a.upArrow)F.moveBy(-Rt,wt,h);else if(a.return){let me=0,Re,Pe=w?.id??"",xe=new Map;xe.set(Pe,[]);for(let Se of he)try{let rt=JSON.parse(Se.details),nt=String(rt.exchangeId??""),ot=!nt||nt===Pe?Pe:nt;xe.has(ot)||xe.set(ot,[]),xe.get(ot).push(Se);}catch{xe.get(Pe).push(Se);}let Ut=xe.size>1;for(let[,Se]of xe){Ut&&me++;for(let rt of Se)me===F.selectedIndex&&(Re=rt),me++;}Re&&(bt(Re),ne(0),ce(true));}else if(c==="e"&&w){let me=e.getExchangeSnapshot(w.id);jt(me),ke(0),Ye(true);}else (a.escape||a.backspace||a.delete)&&(F.reset(),g(false));return}if(d&&G){let b=a.ctrl?de:1;c==="j"||a.downArrow?ne(h=>h+b):c==="k"||a.upArrow?ne(h=>Math.max(h-b,0)):(a.escape||a.backspace||a.delete)&&(ce(false),ne(0));return}if(n==="capabilities"&&l==="nav"){if(c==="j"||a.downArrow)yt(Math.min(E.selectedIndex+1,p.length-1));else if(c==="k"||a.upArrow)yt(Math.max(E.selectedIndex-1,0));else if(a.return){m("center");let b=p[E.selectedIndex];b&&O(e.getExchangesByRoute(b.id));}return}if(n==="capabilities"&&l==="center"){let b=a.ctrl?de:1;if(c==="j"||a.downArrow)T.moveBy(b,W.length,_e);else if(c==="k"||a.upArrow)T.moveBy(-b,W.length,_e);else if(a.return){let h=W[T.selectedIndex];h&&(ht(h),ft(e.getEventsByExchange(h.id,h.correlationId)),F.reset(),ce(false),g(true));}else (a.escape||a.backspace||a.delete)&&(m("nav"),T.reset());return}if(n==="exchanges"||n==="errors"){if(l==="nav")a.return&&(m("center"),O(n==="exchanges"?e.getAllExchanges():e.getFailedExchanges()));else {let b=a.ctrl?de:1;if(c==="j"||a.downArrow)T.moveBy(b,W.length,_e);else if(c==="k"||a.upArrow)T.moveBy(-b,W.length,_e);else if(a.return){let h=W[T.selectedIndex];h&&(ht(h),ft(e.getEventsByExchange(h.id,h.correlationId)),F.reset(),ce(false),g(true));}else (a.escape||a.backspace||a.delete)&&(m("nav"),T.reset());}return}});let Tt=n==="capabilities"&&l==="nav"&&!d,$t=!Tt,D=[];return H?(D.push({key:"j/k",action:"Scroll"}),D.push({key:"Ctrl+j/k",action:"Jump 10"}),D.push({key:"Esc",action:"Back"})):l==="center"&&(D.push({key:"j/k",action:"Navigate"}),D.push({key:"Ctrl+j/k",action:"Jump 10"})),H||(l==="nav"?n==="capabilities"?(D.push({key:"j/k",action:"Navigate"}),D.push({key:"Enter",action:"Exchanges"})):D.push({key:"Enter",action:"Browse"}):!d&&!G?(D.push({key:"Enter",action:"Detail"}),D.push({key:"Esc",action:"Back"})):d&&!G?(D.push({key:"Enter",action:"Event detail"}),D.push({key:"e",action:"Snapshot"}),D.push({key:"Esc",action:"Back"})):D.push({key:"Esc",action:"Back"})),D.push({key:"1..4",action:"Switch view"}),D.push({key:"q",action:"Quit"}),jsxs(Box,{flexDirection:"column",width:s,height:r,children:[jsxs(Box,{borderStyle:"round",borderColor:"cyan",paddingX:1,width:s,children:[jsx(Text,{bold:true,color:"cyan",children:"ROUTECRAFT TUI"}),jsx(Text,{children:" "}),jsxs(Text,{dimColor:true,children:["v",a$1]})]}),jsxs(Box,{flexDirection:"row",width:s,flexGrow:1,children:[jsx(Box,{flexDirection:"column",width:Oe,children:jsxs(S,{title:"NAVIGATION",color:Tt?"cyan":"gray",width:Oe,flexGrow:1,children:[st.map((c,a)=>jsxs(Box,{flexDirection:"column",children:[a>0&&jsx(Text,{children:" "}),c.label&&jsx(Text,{dimColor:true,bold:true,children:c.label}),c.items.map(I=>jsxs(Text,{children:[jsxs(Text,{bold:n===I.key,...n===I.key?{color:"cyan"}:{},children:[n===I.key?"> ":" ",I.label]}),jsxs(Text,{dimColor:true,children:[" (",I.shortcut,")"]})]},I.key))]},c.label??a)),n==="capabilities"&&jsx(Pt,{routes:p,selectedIndex:E.selectedIndex,listOffset:E.scrollOffset,visibleRows:Ze,width:Oe-6})]})}),n==="capabilities"&&!d&&jsx(Ve,{capabilityId:tt?.id??"",route:tt,exchanges:W,selectedIndex:l==="center"?T.selectedIndex:-1,scrollOffset:l==="center"?T.scrollOffset:0,width:N,height:R,color:$t?"cyan":"gray",activity:K}),n==="capabilities"&&H&&w&&jsx(qe,{exchange:w,snapshot:Qe,width:N,height:R,scrollOffset:ze,color:"cyan"}),n==="capabilities"&&d&&w&&!G&&!H&&jsx(We,{exchange:w,events:he,width:N,height:R,selectedIndex:F.selectedIndex,scrollOffset:F.scrollOffset,color:"cyan"}),n==="capabilities"&&d&&G&&!H&&re&&jsx(Ne,{event:re,width:N,height:R,scrollOffset:Le,color:"cyan"}),n==="exchanges"&&!d&&jsx(Ve,{capabilityId:"All Capabilities",exchanges:W,selectedIndex:l==="center"?T.selectedIndex:-1,scrollOffset:l==="center"?T.scrollOffset:0,width:N,height:R,color:l==="center"?"cyan":"gray"}),n==="exchanges"&&H&&w&&jsx(qe,{exchange:w,snapshot:Qe,width:N,height:R,scrollOffset:ze,color:"cyan"}),n==="exchanges"&&d&&w&&!G&&!H&&jsx(We,{exchange:w,events:he,width:N,height:R,selectedIndex:F.selectedIndex,scrollOffset:F.scrollOffset,color:"cyan"}),n==="exchanges"&&d&&G&&!H&&re&&jsx(Ne,{event:re,width:N,height:R,scrollOffset:Le,color:"cyan"}),n==="errors"&&!d&&jsx(Ve,{capabilityId:"Failed Exchanges",exchanges:W,selectedIndex:l==="center"?T.selectedIndex:-1,scrollOffset:l==="center"?T.scrollOffset:0,width:N,height:R,color:l==="center"?"cyan":"gray"}),n==="errors"&&H&&w&&jsx(qe,{exchange:w,snapshot:Qe,width:N,height:R,scrollOffset:ze,color:"cyan"}),n==="errors"&&d&&w&&!G&&!H&&jsx(We,{exchange:w,events:he,width:N,height:R,selectedIndex:F.selectedIndex,scrollOffset:F.scrollOffset,color:"cyan"}),n==="errors"&&d&&G&&!H&&re&&jsx(Ne,{event:re,width:N,height:R,scrollOffset:Le,color:"cyan"}),n==="events"&&!G&&jsx(_t,{events:Be,selectedIndex:l==="center"?te.selectedIndex:-1,scrollOffset:l==="center"?te.scrollOffset:0,width:N,height:R,color:l==="center"?"cyan":"gray"}),n==="events"&&G&&re&&jsx(Ne,{event:re,width:N,height:R,scrollOffset:Le,color:"cyan"}),jsxs(Box,{flexDirection:"column",width:ue,children:[jsxs(S,{title:"METRICS",width:ue,flexGrow:1,children:[jsx(He,{values:k,columns:ue-4,steps:[{max:0,color:"gray"},...Array.from({length:7},(c,a)=>({max:(a+1)*5,color:"green"})),...Array.from({length:7},(c,a)=>({max:35+(a+1)*10,color:"yellow"})),...Array.from({length:6},(c,a)=>({max:105+(a+1)*25,color:"red"}))],label:"Exchanges per 5s bucket"}),jsx(Text,{children:" "}),jsx(Text,{bold:true,dimColor:true,children:"THROUGHPUT"}),[["Exchanges",q(i.totalExchanges),"cyan"],["Completed",q(i.completedExchanges),"green"],["Errors",q(i.failedExchanges),i.failedExchanges>0?"red":"green"],["Dropped",q(i.droppedExchanges),i.droppedExchanges>0?"yellow":"green"],["Error Rate",`${(i.errorRate*100).toFixed(1)}%`,i.errorRate>.1?"red":"green"],["Capabilities",q(i.totalRoutes),""]].map(([c,a,I])=>jsxs(Box,{children:[jsxs(Text,{children:[c,":"]}),jsx(Box,{flexGrow:1,justifyContent:"flex-end",children:jsx(Text,{bold:true,...I?{color:I}:{},children:a})})]},c)),jsx(Text,{children:" "}),jsx(Text,{bold:true,dimColor:true,children:"LATENCY (5m)"}),[["Avg",_(i.avgDurationMs),""],["p90",_(i.p90DurationMs),""],["p95",_(i.p95DurationMs),""],["p99",_(i.p99DurationMs),""]].map(([c,a,I])=>jsxs(Box,{children:[jsxs(Text,{children:[c,":"]}),jsx(Box,{flexGrow:1,justifyContent:"flex-end",children:jsx(Text,{bold:true,...I?{color:I}:{},children:a})})]},c))]}),jsx(S,{title:"KEYMAP",width:ue,children:D.map(c=>jsxs(Box,{children:[jsx(Text,{children:c.action}),jsx(Box,{flexGrow:1,justifyContent:"flex-end",children:jsxs(Text,{color:"yellow",children:["[",c.key,"]"]})})]},c.key))})]})]})]})}async function to(e){let t;try{t=await a.open(e);}catch(s){let r=s instanceof Error?s.message:String(s);process.stderr.write(`Failed to open telemetry database: ${r}
|
|
4
4
|
`),process.stderr.write(`Path: ${e}
|
|
5
5
|
`),process.stderr.write(`Make sure you have a running Routecraft context with telemetry() enabled.
|
|
6
|
-
`),process.exit(1);}await render(jsx(
|
|
6
|
+
`),process.exit(1);}await render(jsx(Er,{db:t})).waitUntilExit();}export{to as renderTui};//# sourceMappingURL=app.js.map
|
|
7
7
|
//# sourceMappingURL=app.js.map
|
package/dist/tui/app.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/tui/types.ts","../../src/tui/utils.ts","../../src/tui/hooks/use-scroll-list.ts","../../src/tui/components/panel.tsx","../../src/tui/components/dot-graph.tsx","../../src/tui/components/route-header.tsx","../../src/tui/components/table.tsx","../../src/tui/components/event-columns.tsx","../../src/tui/components/center-exchange-list.tsx","../../src/tui/components/json-format.tsx","../../src/tui/components/center-exchange-detail.tsx","../../src/tui/components/events-view.tsx","../../src/tui/components/event-detail.tsx","../../src/tui/components/exchange-deep-view.tsx","../../src/tui/components/capability-list.tsx","../../src/tui/app.tsx"],"names":["NAV_SECTIONS","ALL_NAV_ITEMS","s","truncate","str","maxLen","formatDuration","ms","statusColor","status","col","len","parseEventDetail","raw","d","exchange","duration","adapter","meta","m","keys","k","qualifier","route","err","formatDetailColumns","_eventName","parsed","fmtNum","n","adjustScrollOffset","selected","currentOffset","visibleRows","useScrollList","initialIndex","selectedIndex","setSelectedIndex","useState","scrollOffset","setScrollOffset","moveTo","useCallback","index","listLength","clamped","off","moveBy","delta","prev","next","reset","Panel","title","subtitle","color","width","flexGrow","paddingX","children","innerWidth","jsxs","Box","Fragment","Text","jsx","BRAILLE_DOTS","BRAILLE_BASE","DEFAULT_STEPS","DotGraph","values","columns","steps","label","dotHeight","data","heights","v","i","termRows","rows","tr","baseStep","segments","ci","h","bits","sr","stepLevel","char","last","RouteHeader","Table","rowKey","gap","emptyMessage","renderFullRow","gapStr","header","c","after","text","visible","remaining","row","vi","dataIndex","fullRow","resolved","cell","eventDetailColumns","accessor","cache","getColumns","ev","cols","_sel","w","selectorColumn","_row","exchangeColumns","CenterExchangeList","capabilityId","exchanges","height","activity","graphTermRows","headerRows","tableRows","ex","tokenizeLine","line","tokens","re","lastIndex","match","TOKEN_COLORS","formatJson","maxWidth","clampedMax","ColoredJsonLine","token","parseDetails","groupEventsByExchange","events","parentExchangeId","groups","childIndex","exId","key","detailColumns","indent","CenterExchangeDetail","hasExtra","eventRows","hasChildren","displayRows","group","eventsTitle","eventColumns","EventsView","EventDetail","event","routeId","exchangeId","headerHeight","jsonChrome","jsonWidth","jsonLines","_","buildSnapshotLines","snapshot","lines","ExchangeDeepView","dotColor","CapabilityList","routes","listOffset","offset","App","db","exit","useApp","stdout","useStdout","activeNav","setActiveNav","focus","setFocus","showDetail","setShowDetail","setRoutes","metrics","setMetrics","liveTraffic","setLiveTraffic","selectedRouteActivity","setSelectedRouteActivity","routeScroll","setExchanges","exchangeScroll","selectedExchange","setSelectedExchange","exchangeEvents","setExchangeEvents","setEvents","eventScroll","detailScroll","selectedEvent","setSelectedEvent","showEventDetail","setShowEventDetail","eventDetailScroll","setEventDetailScroll","showDeepView","setShowDeepView","deepViewScroll","setDeepViewScroll","exchangeSnapshot","setExchangeSnapshot","PAGE_SIZE","JUMP","leftWidth","rightWidth","centerWidth","bodyHeight","navListHeight","refresh","routeSummary","liveCols","routeCols","curRoute","useEffect","timer","selectRoute","switchNav","nav","selectedRoute","exchangeHeaderRows","exchangeTableRows","eventsTableRows","useInput","input","navByShortcut","step","detailEventRows","uniqueExchangeIds","groupCount","totalDisplayRows","rowIndex","targetEvent","parentId","gKey","groupEvents","navActive","centerActive","keymapItems","section","si","item","value","renderTui","dbPath","TelemetryDb","msg","render"],"mappings":"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","file":"app.js","sourcesContent":["export type NavItem = \"capabilities\" | \"exchanges\" | \"errors\" | \"events\";\n\nexport type NavSection = {\n label?: string;\n items: { key: NavItem; label: string; shortcut: string }[];\n};\n\nexport const NAV_SECTIONS: NavSection[] = [\n {\n items: [{ key: \"capabilities\", label: \"Capabilities\", shortcut: \"1\" }],\n },\n {\n items: [\n { key: \"exchanges\", label: \"Exchanges\", shortcut: \"2\" },\n { key: \"errors\", label: \"Errors\", shortcut: \"3\" },\n { key: \"events\", label: \"Events\", shortcut: \"4\" },\n ],\n },\n];\n\nexport const ALL_NAV_ITEMS = NAV_SECTIONS.flatMap((s) => s.items);\n\nexport interface RouteSummary {\n id: string;\n status: string;\n totalExchanges: number;\n completedExchanges: number;\n failedExchanges: number;\n droppedExchanges: number;\n avgDurationMs: number | null;\n}\n\nexport interface ExchangeRecord {\n id: string;\n routeId: string;\n contextId: string;\n correlationId: string;\n status: string;\n startedAt: string;\n completedAt: string | null;\n durationMs: number | null;\n error: string | null;\n}\n\nexport interface EventRecord {\n id?: number;\n timestamp: string;\n contextId: string;\n eventName: string;\n details: string;\n}\n\nexport interface Metrics {\n totalRoutes: number;\n totalExchanges: number;\n completedExchanges: number;\n failedExchanges: number;\n droppedExchanges: number;\n errorRate: number;\n avgDurationMs: number | null;\n p90DurationMs: number | null;\n p95DurationMs: number | null;\n p99DurationMs: number | null;\n}\n\nexport interface ExchangeSnapshot {\n headers: string;\n body: string | null;\n truncated: boolean;\n}\n\nexport interface RouteActivity {\n throughput: number[];\n recentErrors: number;\n}\n","export function truncate(str: string, maxLen: number): string {\n if (maxLen <= 0) return \"\";\n return str.length > maxLen ? str.slice(0, maxLen - 1) + \"\\u2026\" : str;\n}\n\nexport function formatDuration(ms: number | null): string {\n if (ms === null || ms === undefined) return \"-\";\n if (!Number.isFinite(ms) || ms < 0) return \"-\";\n if (ms === 0) return \"<1ms\";\n if (ms < 1000) return `${Math.round(ms)}ms`;\n return `${(ms / 1000).toFixed(1)}s`;\n}\n\nexport function statusColor(status: string): string {\n switch (status) {\n case \"completed\":\n case \"started\":\n return \"green\";\n case \"failed\":\n return \"red\";\n case \"stopped\":\n case \"dropped\":\n return \"yellow\";\n default:\n return \"white\";\n }\n}\n\nexport function col(str: string, len: number | undefined): string {\n if (len === undefined) return str;\n if (len <= 0) return \"\";\n if (str.length > len) return str.slice(0, len - 1) + \"\\u2026\";\n return str.padEnd(len);\n}\n\n// Fixed column widths for the Details column so fields line up across rows.\n// All event types share the same 4-column layout:\n// [col1: 10] [col2: 10] [exId: 12] [dur: 6] [extra]\n// Step events: operation (adapter) id… dur metadata\n// Exchange events: routeId (status) id… dur\nconst DET = {\n COL1: 10, // operation or routeId\n COL2: 10, // (adapter) or (err)/(reason)/(dropped)\n EX: 12, // \"789003e7 \"\n DUR: 6, // \"1ms \" \"10.0s \"\n} as const;\n\nexport interface DetailColumns {\n step: string;\n adapter: string;\n exchange: string;\n duration: string;\n meta: string;\n}\n\n/**\n * Parse a JSON event detail string into structured columns.\n * Shared normalizer used by both formatDetails and formatDetailColumns.\n */\nfunction parseEventDetail(raw: string): DetailColumns | null {\n try {\n const d = JSON.parse(raw) as Record<string, unknown>;\n\n const exchange =\n \"exchangeId\" in d ? `${String(d[\"exchangeId\"]).slice(0, 8)}` : \"\";\n const duration =\n \"duration\" in d ? formatDuration(d[\"duration\"] as number) : \"\";\n\n // Step/operation events\n if (\"operation\" in d && \"routeId\" in d) {\n const adapter =\n \"adapter\" in d\n ? `(${d[\"adapter\"]})`\n : \"adapterId\" in d\n ? `(${d[\"adapterId\"]})`\n : \"\";\n let meta = \"\";\n if (\n \"metadata\" in d &&\n typeof d[\"metadata\"] === \"object\" &&\n d[\"metadata\"] !== null\n ) {\n const m = d[\"metadata\"] as Record<string, unknown>;\n const keys = Object.keys(m).slice(0, 2);\n if (keys.length > 0) meta = keys.map((k) => `${k}=${m[k]}`).join(\" \");\n }\n return {\n step: String(d[\"operation\"]),\n adapter,\n exchange,\n duration,\n meta,\n };\n }\n\n // Exchange events\n if (\"routeId\" in d && \"exchangeId\" in d) {\n const qualifier =\n \"error\" in d\n ? \"(err)\"\n : \"reason\" in d\n ? `(${String(d[\"reason\"]).slice(0, 8)})`\n : \"\";\n return {\n step: String(d[\"routeId\"]),\n adapter: qualifier,\n exchange,\n duration,\n meta: \"\",\n };\n }\n\n // Route lifecycle events\n if (\"route\" in d && typeof d[\"route\"] === \"object\" && d[\"route\"] !== null) {\n const route = d[\"route\"] as {\n routeId?: string;\n definition?: { id?: string };\n };\n return {\n step: route.routeId ?? route.definition?.id ?? \"?\",\n adapter: \"\",\n exchange: \"\",\n duration: \"\",\n meta: \"\",\n };\n }\n\n // Plugin events\n if (\"pluginId\" in d) {\n return {\n step: `plugin=${d[\"pluginId\"]}`,\n adapter: \"\",\n exchange: \"\",\n duration: \"\",\n meta: \"\",\n };\n }\n\n // Error events\n if (\"error\" in d) {\n const err = d[\"error\"];\n const msg =\n typeof err === \"object\" && err !== null && \"message\" in err\n ? String((err as { message: string }).message)\n : String(err);\n return {\n step: msg,\n adapter: \"\",\n exchange: \"\",\n duration: \"\",\n meta: \"\",\n };\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\nexport function formatDetails(_eventName: string, raw: string): string {\n const parsed = parseEventDetail(raw);\n if (!parsed) {\n return raw.length > 100 ? raw.slice(0, 97) + \"...\" : raw;\n }\n\n // Non-columnar events (plugin, route lifecycle, error) have no exchange/duration\n if (!parsed.exchange && !parsed.duration && !parsed.adapter) {\n return parsed.step;\n }\n\n return [\n col(parsed.step, DET.COL1),\n col(parsed.adapter, DET.COL2),\n col(parsed.exchange, DET.EX),\n col(parsed.duration, DET.DUR),\n parsed.meta,\n ]\n .join(\" \")\n .trimEnd();\n}\n\n/**\n * Structured version of formatDetails that returns individual columns\n * so the component can control alignment per-column.\n */\nexport function formatDetailColumns(\n _eventName: string,\n raw: string,\n): DetailColumns {\n const parsed = parseEventDetail(raw);\n if (!parsed) {\n return { step: raw, adapter: \"\", exchange: \"\", duration: \"\", meta: \"\" };\n }\n return parsed;\n}\n\n/**\n * Render a single-line sparkline from an array of values.\n * Uses Unicode block characters (▁▂▃▄▅▆▇█).\n * Empty/zero-only input returns spaces of the same length.\n */\nexport function sparkline(values: number[]): string {\n if (values.length === 0) return \"\";\n const blocks = [\n \" \",\n \"\\u2581\",\n \"\\u2582\",\n \"\\u2583\",\n \"\\u2584\",\n \"\\u2585\",\n \"\\u2586\",\n \"\\u2587\",\n \"\\u2588\",\n ];\n const max = Math.max(...values, 1);\n return values\n .map((v) => {\n const idx = Math.max(0, Math.min(8, Math.round((v / max) * 8)));\n return blocks[Number.isFinite(idx) ? idx : 0];\n })\n .join(\"\");\n}\n\nexport function fmtNum(n: number): string {\n return n.toLocaleString(\"en-US\");\n}\n\n/**\n * Adjust scroll offset so the selected item stays visible without centering.\n * The cursor moves freely within the visible window; the list only scrolls\n * when the cursor hits the top or bottom edge.\n *\n * @param selected - New selected index\n * @param currentOffset - Current scroll offset (tracked as state by the caller)\n * @param visibleRows - Number of rows visible in the list\n * @returns Updated scroll offset\n */\nexport function adjustScrollOffset(\n selected: number,\n currentOffset: number,\n visibleRows: number,\n): number {\n if (visibleRows <= 0) return currentOffset;\n if (selected < currentOffset) return selected;\n if (selected >= currentOffset + visibleRows)\n return selected - visibleRows + 1;\n return currentOffset;\n}\n","import { useState, useCallback } from \"react\";\nimport { adjustScrollOffset } from \"../utils.js\";\n\nexport interface ScrollListState {\n selectedIndex: number;\n scrollOffset: number;\n /** Move selection by delta (positive = down, negative = up). */\n moveBy: (delta: number, listLength: number, visibleRows: number) => void;\n /** Jump to an absolute index. */\n moveTo: (index: number, listLength: number, visibleRows: number) => void;\n /** Reset selection and scroll to the beginning. */\n reset: () => void;\n}\n\n/**\n * Manages a paired (selectedIndex, scrollOffset) state for scrollable lists.\n * Keeps the selected item visible without centering.\n *\n * `listLength` and `visibleRows` are passed at call time (not stored)\n * because they change every render (terminal resize, data load).\n */\nexport function useScrollList(initialIndex = 0): ScrollListState {\n const [selectedIndex, setSelectedIndex] = useState(initialIndex);\n const [scrollOffset, setScrollOffset] = useState(0);\n\n const moveTo = useCallback(\n (index: number, listLength: number, visibleRows: number) => {\n const clamped = Math.max(0, Math.min(index, listLength - 1));\n setSelectedIndex(clamped);\n setScrollOffset((off) => adjustScrollOffset(clamped, off, visibleRows));\n },\n [],\n );\n\n const moveBy = useCallback(\n (delta: number, listLength: number, visibleRows: number) => {\n setSelectedIndex((prev) => {\n const next = Math.max(0, Math.min(prev + delta, listLength - 1));\n setScrollOffset((off) => adjustScrollOffset(next, off, visibleRows));\n return next;\n });\n },\n [],\n );\n\n const reset = useCallback(() => {\n setSelectedIndex(0);\n setScrollOffset(0);\n }, []);\n\n return { selectedIndex, scrollOffset, moveBy, moveTo, reset };\n}\n","import type { ReactNode } from \"react\";\nimport { Box, Text } from \"ink\";\n\nexport function Panel({\n title,\n subtitle,\n color = \"gray\",\n width,\n flexGrow,\n paddingX = 1,\n children,\n}: {\n title?: string;\n subtitle?: ReactNode;\n color?: string;\n width?: number;\n flexGrow?: number;\n paddingX?: number;\n children: ReactNode;\n}) {\n // Border adds 2 chars per side; padding adds paddingX per side\n const innerWidth = width ? width - 2 - paddingX * 2 : 20;\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={color}\n paddingX={paddingX}\n width={width}\n flexGrow={flexGrow}\n >\n {title && (\n <>\n <Text bold>\n {title}\n {subtitle && <> {subtitle}</>}\n </Text>\n <Text dimColor>{\"\\u2500\".repeat(Math.max(innerWidth, 1))}</Text>\n </>\n )}\n {children}\n </Box>\n );\n}\n","import type { JSX } from \"react\";\nimport { Text } from \"ink\";\n\n/**\n * Braille layout: 1 bucket per character, both columns.\n *\n * Left Right\n * 0x01 0x08 sub-row 0 (top)\n * 0x02 0x10 sub-row 1\n * 0x04 0x20 sub-row 2\n * 0x40 0x80 sub-row 3 (bottom)\n *\n * Each terminal character represents 1 time bucket.\n * Both columns mirror the same data for btop-style dot density.\n * Each terminal row packs up to 4 step levels vertically.\n */\nconst BRAILLE_DOTS = [\n 0x40 | 0x80,\n 0x04 | 0x20,\n 0x02 | 0x10,\n 0x01 | 0x08,\n] as const; // bottom to top\nconst BRAILLE_BASE = 0x2800;\n\nexport interface DotStep {\n max: number;\n color: string;\n}\n\n/** Default 5-step config: gray baseline, green low, yellow mid, red high. */\nexport const DEFAULT_STEPS: DotStep[] = [\n { max: 0, color: \"gray\" },\n { max: 10, color: \"green\" },\n { max: 20, color: \"green\" },\n { max: 30, color: \"yellow\" },\n { max: 40, color: \"yellow\" },\n { max: 50, color: \"red\" },\n];\n\n/**\n * Stacked dot graph using braille characters.\n *\n * 1 bucket = 1 terminal character. Both braille columns mirror the same\n * data for btop-style dot density. Each character can stack up to 4 step\n * levels vertically.\n *\n * - 0 exchanges: gray baseline dot (bottom)\n * - 1-9 exchanges: green dot (bottom)\n * - 10-19 exchanges: two green dots stacked\n * - etc., stacking upward with per-level colors\n */\nexport function DotGraph({\n values,\n columns,\n steps = DEFAULT_STEPS,\n label,\n}: {\n values: number[];\n columns: number;\n steps?: DotStep[];\n label?: string;\n}) {\n const dotHeight = steps.length - 1;\n\n // Right-align: newest on right, pad left with zeros\n const data =\n values.length >= columns\n ? values.slice(values.length - columns)\n : [\n ...(new Array(columns - values.length).fill(0) as number[]),\n ...values,\n ];\n\n // Map each value to a step index (0 = baseline, 1..dotHeight)\n const heights = data.map((v) => {\n if (v <= 0) return 0;\n for (let i = 1; i < steps.length; i++) {\n if (v < steps[i]!.max) return i;\n }\n return dotHeight;\n });\n\n const termRows = Math.ceil(dotHeight / 4);\n\n // Build terminal rows from top to bottom\n const rows: JSX.Element[] = [];\n for (let tr = termRows - 1; tr >= 0; tr--) {\n const baseStep = tr * 4;\n\n // For each bucket, compute the braille bits and color for this terminal row\n const segments: { text: string; color: string }[] = [];\n\n for (let ci = 0; ci < data.length; ci++) {\n const h = heights[ci]!;\n let bits = 0;\n let color = \"\";\n\n for (let sr = 0; sr < 4; sr++) {\n const stepLevel = baseStep + sr + 1;\n if (stepLevel > dotHeight) break;\n\n // Show dot if height reaches this level, or baseline dot for zero values\n const on = h >= stepLevel || (h === 0 && stepLevel === 1);\n if (on) {\n bits |= BRAILLE_DOTS[sr]!;\n // Color: gray for baseline (zero), step color for data\n color = h === 0 ? steps[0]!.color : steps[stepLevel]!.color;\n }\n }\n\n const char = String.fromCharCode(BRAILLE_BASE + bits);\n const last = segments[segments.length - 1];\n if (last && last.color === color) {\n last.text += char;\n } else {\n segments.push({ text: char, color });\n }\n }\n\n rows.push(\n <Text key={tr}>\n {segments.map((s, i) =>\n s.color ? (\n <Text key={i} color={s.color}>\n {s.text}\n </Text>\n ) : (\n <Text key={i}>{s.text}</Text>\n ),\n )}\n </Text>,\n );\n }\n\n return (\n <>\n {rows}\n {label && <Text dimColor>{label}</Text>}\n </>\n );\n}\n","import { Text } from \"ink\";\nimport type { RouteSummary } from \"../types.js\";\nimport { statusColor, fmtNum, formatDuration } from \"../utils.js\";\n\nexport function RouteHeader({ route }: { route: RouteSummary }) {\n return (\n <>\n <Text>\n Capability:{\" \"}\n <Text bold color=\"cyan\">\n {route.id}\n </Text>\n </Text>\n <Text>\n Status:{\" \"}\n <Text bold color={statusColor(route.status)}>\n {route.status}\n </Text>\n {\" \"}Exchanges: <Text bold>{fmtNum(route.totalExchanges)}</Text>\n {\" \"}Errors:{\" \"}\n <Text\n bold\n {...(route.failedExchanges > 0 ? { color: \"red\" as const } : {})}\n >\n {fmtNum(route.failedExchanges)}\n </Text>\n {\" \"}Dropped:{\" \"}\n <Text\n bold\n {...(route.droppedExchanges > 0 ? { color: \"yellow\" as const } : {})}\n >\n {fmtNum(route.droppedExchanges)}\n </Text>\n {\" \"}Avg: <Text bold>{formatDuration(route.avgDurationMs)}</Text>\n </Text>\n </>\n );\n}\n","import { Fragment, type ReactNode } from \"react\";\nimport { Box, Text } from \"ink\";\nimport { col } from \"../utils.js\";\n\nexport interface ColumnDef<T> {\n /** Header label */\n header: string;\n /** Fixed character width, or \"flex\" to fill remaining space */\n width: number | \"flex\";\n /** Text alignment. Default: \"left\" */\n align?: \"left\" | \"right\";\n /** Render cell content. `colWidth` is the resolved width for fixed columns, undefined for flex. */\n render: (\n row: T,\n selected: boolean,\n colWidth: number | undefined,\n ) => ReactNode;\n}\n\nexport interface TableProps<T> {\n columns: ColumnDef<T>[];\n data: T[];\n /** Unique key for each row */\n rowKey: (row: T, index: number) => string;\n /** Selected row index in full data array, or -1/undefined for no selection */\n selectedIndex?: number;\n /** First visible row (scroll offset) */\n scrollOffset: number;\n /** Number of visible rows */\n visibleRows: number;\n /** Gap between columns in characters. Default: 2 */\n gap?: number;\n /** Message when data is empty */\n emptyMessage?: string;\n /**\n * Optional full-row override for special rows (e.g., group headers).\n * Return undefined to use normal column rendering.\n */\n renderFullRow?: (row: T, index: number) => ReactNode | undefined;\n}\n\nexport function Table<T>({\n columns,\n data,\n rowKey,\n selectedIndex,\n scrollOffset,\n visibleRows,\n gap = 2,\n emptyMessage = \"No data\",\n renderFullRow,\n}: TableProps<T>) {\n const gapStr = \" \".repeat(gap);\n\n // Header\n const header = (\n <Box>\n {columns.map((c, ci) => {\n const isLast = ci === columns.length - 1;\n const after = isLast ? \"\" : gapStr;\n\n if (c.width === \"flex\") {\n return (\n <Fragment key={ci}>\n <Box flexGrow={1}>\n <Text bold dimColor>\n {c.header}\n </Text>\n </Box>\n {after && <Text>{after}</Text>}\n </Fragment>\n );\n }\n\n const text =\n c.align === \"right\"\n ? c.header.padStart(c.width)\n : col(c.header, c.width);\n\n return (\n <Fragment key={ci}>\n <Text bold dimColor>\n {text}\n </Text>\n {after && <Text>{after}</Text>}\n </Fragment>\n );\n })}\n </Box>\n );\n\n if (data.length === 0) {\n return (\n <>\n {header}\n <Text dimColor>{emptyMessage}</Text>\n </>\n );\n }\n\n const visible = data.slice(scrollOffset, scrollOffset + visibleRows);\n const remaining = data.length - scrollOffset - visibleRows;\n\n return (\n <>\n {header}\n {visible.map((row, vi) => {\n const dataIndex = scrollOffset + vi;\n const selected = dataIndex === selectedIndex;\n\n // Full-row override (e.g., group headers)\n const fullRow = renderFullRow?.(row, dataIndex);\n if (fullRow !== undefined) {\n return <Box key={rowKey(row, dataIndex)}>{fullRow}</Box>;\n }\n\n return (\n <Box key={rowKey(row, dataIndex)}>\n {columns.map((c, ci) => {\n const isLast = ci === columns.length - 1;\n const after = isLast ? \"\" : gapStr;\n const resolved = c.width === \"flex\" ? undefined : c.width;\n const cell = c.render(row, selected, resolved);\n\n if (c.width === \"flex\") {\n return (\n <Fragment key={ci}>\n <Box flexGrow={1}>\n <Text wrap=\"truncate\">{cell}</Text>\n </Box>\n {after && <Text>{after}</Text>}\n </Fragment>\n );\n }\n\n return (\n <Fragment key={ci}>\n {cell}\n {after && <Text>{after}</Text>}\n </Fragment>\n );\n })}\n </Box>\n );\n })}\n <Text dimColor>{remaining > 0 ? \"\\u2193 more\" : \" \"}</Text>\n </>\n );\n}\n","import { Text } from \"ink\";\nimport type { EventRecord } from \"../types.js\";\nimport { col, formatDetailColumns, type DetailColumns } from \"../utils.js\";\nimport type { ColumnDef } from \"./table.js\";\n\n/**\n * Build the 4 standard event detail columns (Step, Adapter, Exchange, Duration).\n *\n * The accessor extracts an EventRecord from whatever row type T the table uses.\n * Returns undefined when the row has no event data (e.g., group headers).\n *\n * JSON is parsed once per row and shared across all 4 columns via a WeakMap cache.\n */\nexport function eventDetailColumns<T>(\n accessor: (row: T) => EventRecord | undefined,\n): ColumnDef<T>[] {\n const cache = new WeakMap<EventRecord, DetailColumns>();\n\n function getColumns(row: T): DetailColumns | undefined {\n const ev = accessor(row);\n if (!ev) return undefined;\n let cols = cache.get(ev);\n if (!cols) {\n cols = formatDetailColumns(ev.eventName, ev.details);\n cache.set(ev, cols);\n }\n return cols;\n }\n\n return [\n {\n header: \"Step\",\n width: 10,\n render: (row, _sel, w) => {\n const cols = getColumns(row);\n if (!cols) return <Text>{col(\"\", w)}</Text>;\n return <Text>{col(cols.step, w)}</Text>;\n },\n },\n {\n header: \"Adapter\",\n width: 10,\n render: (row, _sel, w) => {\n const cols = getColumns(row);\n if (!cols) return <Text>{col(\"\", w)}</Text>;\n return <Text>{col(cols.adapter, w)}</Text>;\n },\n },\n {\n header: \"Exchange\",\n width: 12,\n render: (row, _sel, w) => {\n const cols = getColumns(row);\n if (!cols) return <Text>{col(\"\", w)}</Text>;\n return <Text>{col(cols.exchange, w)}</Text>;\n },\n },\n {\n header: \"Duration\",\n width: 8,\n align: \"right\" as const,\n render: (row) => {\n const cols = getColumns(row);\n if (!cols) return <Text>{\"\"}</Text>;\n return <Text>{cols.duration.padStart(8)}</Text>;\n },\n },\n ];\n}\n\n/**\n * Selector column that shows \"> \" for the selected row.\n */\nexport function selectorColumn<T>(): ColumnDef<T> {\n return {\n header: \"\",\n width: 2,\n render: (_row, selected) => (\n <Text {...(selected ? { color: \"cyan\" as const } : {})} bold={selected}>\n {selected ? \"> \" : \" \"}\n </Text>\n ),\n };\n}\n","import { Box, Text } from \"ink\";\nimport type { ExchangeRecord, RouteSummary, RouteActivity } from \"../types.js\";\nimport { statusColor, formatDuration, col } from \"../utils.js\";\nimport { PANEL_TABLE_CHROME } from \"../layout.js\";\nimport { Panel } from \"./panel.js\";\nimport { RouteHeader } from \"./route-header.js\";\nimport { DotGraph, DEFAULT_STEPS } from \"./dot-graph.js\";\nimport { Table, type ColumnDef } from \"./table.js\";\nimport { selectorColumn } from \"./event-columns.js\";\n\nconst exchangeColumns: ColumnDef<ExchangeRecord>[] = [\n selectorColumn<ExchangeRecord>(),\n {\n header: \"ID\",\n width: \"flex\",\n render: (row, selected) => (\n <Text {...(selected ? { color: \"cyan\" as const } : {})} bold={selected}>\n {row.id}\n </Text>\n ),\n },\n {\n header: \"Status\",\n width: 9,\n render: (row, _sel, w) => (\n <Text color={statusColor(row.status)}>{col(row.status, w)}</Text>\n ),\n },\n {\n header: \"Duration\",\n width: 8,\n align: \"right\",\n render: (row) => <Text>{formatDuration(row.durationMs).padStart(8)}</Text>,\n },\n {\n header: \"Time\",\n width: 8,\n render: (row, _sel, w) => (\n <Text dimColor>\n {col(row.startedAt.replace(\"T\", \" \").slice(11, 19), w)}\n </Text>\n ),\n },\n];\n\nexport function CenterExchangeList({\n capabilityId,\n route,\n exchanges,\n selectedIndex,\n scrollOffset,\n width,\n height,\n color = \"gray\",\n activity,\n}: {\n capabilityId: string;\n route?: RouteSummary;\n exchanges: ExchangeRecord[];\n selectedIndex: number;\n scrollOffset: number;\n width: number;\n height: number;\n color?: string;\n activity?: RouteActivity | undefined;\n}) {\n const graphTermRows = Math.ceil((DEFAULT_STEPS.length - 1) / 4);\n const headerRows = route ? 2 + graphTermRows + 2 : 0;\n const tableRows = Math.max(height - PANEL_TABLE_CHROME - headerRows, 3);\n\n const title = route ? \"EXCHANGES\" : `EXCHANGES: ${capabilityId}`;\n\n return (\n <Box flexDirection=\"column\" width={width} flexGrow={1}>\n {route && (\n <Panel width={width}>\n <RouteHeader route={route} />\n <Text> </Text>\n <DotGraph\n values={activity ? activity.throughput : []}\n columns={width - 4}\n label=\"Exchanges per 5s bucket\"\n />\n </Panel>\n )}\n <Panel title={title} width={width} flexGrow={1} color={color}>\n <Table\n columns={exchangeColumns}\n data={exchanges}\n rowKey={(ex) => ex.id + ex.contextId}\n selectedIndex={selectedIndex}\n scrollOffset={scrollOffset}\n visibleRows={tableRows}\n emptyMessage=\"No exchanges\"\n />\n </Panel>\n </Box>\n );\n}\n","import { Text } from \"ink\";\n\n/** Token types for JSON syntax coloring. */\nexport type TokenType =\n | \"key\"\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"null\"\n | \"brace\";\n\nexport interface JsonToken {\n text: string;\n type: TokenType;\n}\n\n/**\n * Tokenize a single line of pretty-printed JSON into colored segments.\n * Handles: keys, string values, numbers, booleans, null, and structural chars.\n */\nexport function tokenizeLine(line: string): JsonToken[] {\n const tokens: JsonToken[] = [];\n const re =\n /(\"(?:[^\"\\\\]|\\\\.)*\")\\s*:|(\"(?:[^\"\\\\]|\\\\.)*\")|(-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)|(\\btrue\\b|\\bfalse\\b)|(\\bnull\\b)|([{}[\\],:])/g;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = re.exec(line)) !== null) {\n // Plain text before this match (whitespace / indent)\n if (match.index > lastIndex) {\n tokens.push({ text: line.slice(lastIndex, match.index), type: \"brace\" });\n }\n\n if (match[1] !== undefined) {\n // Key (the colon is part of the regex but we split it out)\n tokens.push({ text: match[1], type: \"key\" });\n tokens.push({ text: \":\", type: \"brace\" });\n } else if (match[2] !== undefined) {\n tokens.push({ text: match[2], type: \"string\" });\n } else if (match[3] !== undefined) {\n tokens.push({ text: match[3], type: \"number\" });\n } else if (match[4] !== undefined) {\n tokens.push({ text: match[4], type: \"boolean\" });\n } else if (match[5] !== undefined) {\n tokens.push({ text: match[5], type: \"null\" });\n } else if (match[6] !== undefined) {\n tokens.push({ text: match[6], type: \"brace\" });\n }\n\n lastIndex = match.index + match[0].length;\n }\n\n // Trailing text\n if (lastIndex < line.length) {\n tokens.push({ text: line.slice(lastIndex), type: \"brace\" });\n }\n\n return tokens;\n}\n\nexport const TOKEN_COLORS: Record<TokenType, string> = {\n key: \"cyan\",\n string: \"green\",\n number: \"yellow\",\n boolean: \"yellow\",\n null: \"red\",\n brace: \"gray\",\n};\n\n/**\n * Parse a JSON string into pretty-printed lines, truncating long lines.\n */\nexport function formatJson(raw: string, maxWidth: number): string[] {\n try {\n const parsed = JSON.parse(raw) as unknown;\n const pretty = JSON.stringify(parsed, null, 2);\n return pretty.split(\"\\n\").map((line) => {\n const clampedMax = Math.max(1, maxWidth);\n return line.length > clampedMax\n ? line.slice(0, Math.max(0, clampedMax - 1)) + \"\\u2026\"\n : line;\n });\n } catch {\n const clampedMax = Math.max(1, maxWidth);\n return raw\n .split(\"\\n\")\n .map((line) =>\n line.length > clampedMax\n ? line.slice(0, Math.max(0, clampedMax - 1)) + \"\\u2026\"\n : line,\n );\n }\n}\n\n/**\n * Render a single line of JSON with syntax coloring.\n */\nexport function ColoredJsonLine({ line }: { line: string }) {\n const tokens = tokenizeLine(line);\n if (tokens.length === 0) return <Text>{line}</Text>;\n return (\n <Text>\n {tokens.map((token, i) => (\n <Text key={i} color={TOKEN_COLORS[token.type]}>\n {token.text}\n </Text>\n ))}\n </Text>\n );\n}\n\n/**\n * Safely parse a JSON details string.\n */\nexport function parseDetails(raw: string): Record<string, unknown> | null {\n try {\n const parsed: unknown = JSON.parse(raw);\n if (\n typeof parsed !== \"object\" ||\n parsed === null ||\n Array.isArray(parsed)\n ) {\n return null;\n }\n return parsed as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n","import { Box, Text } from \"ink\";\nimport type { ExchangeRecord, EventRecord } from \"../types.js\";\nimport { statusColor, formatDuration, col, truncate } from \"../utils.js\";\nimport { DETAIL_INFO_CHROME } from \"../layout.js\";\nimport { Panel } from \"./panel.js\";\nimport { Table, type ColumnDef } from \"./table.js\";\nimport { selectorColumn, eventDetailColumns } from \"./event-columns.js\";\nimport { parseDetails } from \"./json-format.js\";\n\ntype DisplayRow = {\n type: \"header\" | \"event\";\n text?: string;\n event?: EventRecord;\n indent: number;\n};\n\n/**\n * Group events by exchangeId to show parent/child flow.\n */\nfunction groupEventsByExchange(\n events: EventRecord[],\n parentExchangeId: string,\n): { exchangeId: string; label: string; events: EventRecord[] }[] {\n const groups = new Map<\n string,\n { exchangeId: string; label: string; events: EventRecord[] }\n >();\n let childIndex = 0;\n\n groups.set(parentExchangeId, {\n exchangeId: parentExchangeId,\n label: \"parent\",\n events: [],\n });\n\n for (const ev of events) {\n const d = parseDetails(ev.details);\n const exId = d ? String(d[\"exchangeId\"] ?? \"\") : \"\";\n const key = !exId || exId === parentExchangeId ? parentExchangeId : exId;\n\n if (!groups.has(key)) {\n childIndex++;\n groups.set(key, {\n exchangeId: key,\n label: `child ${childIndex}`,\n events: [],\n });\n }\n groups.get(key)!.events.push(ev);\n }\n\n return Array.from(groups.values());\n}\n\nconst detailColumns: ColumnDef<DisplayRow>[] = [\n selectorColumn<DisplayRow>(),\n {\n header: \"Time\",\n width: 8,\n render: (row, _sel, w) => {\n if (!row.event) return <Text>{col(\"\", w)}</Text>;\n const indent = \" \".repeat(row.indent);\n return (\n <Text dimColor>\n {indent}\n {row.event.timestamp.replace(\"T\", \" \").slice(11, 19)}\n </Text>\n );\n },\n },\n {\n header: \"Event\",\n width: \"flex\",\n render: (row) => {\n if (!row.event) return <Text />;\n return <Text color=\"cyan\">{row.event.eventName}</Text>;\n },\n },\n ...eventDetailColumns<DisplayRow>((row) => row.event),\n];\n\nexport function CenterExchangeDetail({\n exchange,\n events,\n width,\n height,\n scrollOffset,\n selectedIndex = -1,\n color = \"gray\",\n}: {\n exchange: ExchangeRecord;\n events: EventRecord[];\n width: number;\n height: number;\n scrollOffset: number;\n selectedIndex?: number;\n color?: string;\n}) {\n const hasExtra = exchange.error ? 2 : 0;\n const eventRows = Math.max(height - DETAIL_INFO_CHROME - hasExtra, 3);\n\n const groups = groupEventsByExchange(events, exchange.id);\n const hasChildren = groups.length > 1;\n\n const displayRows: DisplayRow[] = [];\n for (const group of groups) {\n if (hasChildren) {\n displayRows.push({\n type: \"header\",\n text: `${group.label} (${group.exchangeId.slice(0, 8)}) - ${group.events.length} events`,\n indent: 0,\n });\n }\n for (const ev of group.events) {\n displayRows.push({\n type: \"event\",\n event: ev,\n indent: hasChildren ? 2 : 0,\n });\n }\n }\n\n const eventsTitle = hasChildren\n ? `EXCHANGE FLOW (${groups.length} exchanges, ${events.length} events)`\n : `RELATED EVENTS (${events.length})`;\n\n return (\n <Box flexDirection=\"column\" width={width} flexGrow={1}>\n <Panel width={width}>\n <Text>\n Capability:{\" \"}\n <Text bold color=\"cyan\">\n {exchange.routeId}\n </Text>\n </Text>\n <Text>\n Exchange:{\" \"}\n <Text bold color=\"cyan\">\n {truncate(exchange.id, width - 14)}\n </Text>\n </Text>\n <Text>\n Status:{\" \"}\n <Text bold color={statusColor(exchange.status)}>\n {exchange.status}\n </Text>\n {exchange.durationMs !== null && (\n <Text>\n {\" \"}Duration:{\" \"}\n <Text bold>{formatDuration(exchange.durationMs)}</Text>\n </Text>\n )}\n {\" \"}Started: <Text bold>{exchange.startedAt}</Text>\n {exchange.completedAt && (\n <Text>\n {\" \"}Completed: <Text bold>{exchange.completedAt}</Text>\n </Text>\n )}\n </Text>\n {exchange.error && exchange.status === \"failed\" && (\n <>\n <Text> </Text>\n <Text color=\"red\">Error: {exchange.error}</Text>\n </>\n )}\n {exchange.error && exchange.status === \"dropped\" && (\n <>\n <Text> </Text>\n <Text color=\"yellow\">Reason: {exchange.error}</Text>\n </>\n )}\n </Panel>\n\n <Panel title={eventsTitle} width={width} flexGrow={1} color={color}>\n <Table\n columns={detailColumns}\n data={displayRows}\n rowKey={(row, i) =>\n row.type === \"header\"\n ? `h-${i}`\n : `${row.event?.id ?? row.event?.timestamp}-${i}`\n }\n selectedIndex={selectedIndex}\n scrollOffset={scrollOffset}\n visibleRows={eventRows}\n emptyMessage=\"No related events found\"\n renderFullRow={(row) =>\n row.type === \"header\" ? (\n <Text bold color=\"yellow\">\n {row.text}\n </Text>\n ) : undefined\n }\n />\n </Panel>\n </Box>\n );\n}\n","import { Text } from \"ink\";\nimport type { EventRecord } from \"../types.js\";\nimport { col } from \"../utils.js\";\nimport { PANEL_TABLE_CHROME } from \"../layout.js\";\nimport { Panel } from \"./panel.js\";\nimport { Table, type ColumnDef } from \"./table.js\";\nimport { selectorColumn, eventDetailColumns } from \"./event-columns.js\";\n\nconst eventColumns: ColumnDef<EventRecord>[] = [\n selectorColumn<EventRecord>(),\n {\n header: \"Time\",\n width: 19,\n render: (row, selected, w) => (\n <Text {...(selected ? { color: \"cyan\" as const } : {})} bold={selected}>\n {col(row.timestamp.replace(\"T\", \" \").slice(0, 19), w)}\n </Text>\n ),\n },\n {\n header: \"Event\",\n width: \"flex\",\n render: (row) => <Text color=\"cyan\">{row.eventName}</Text>,\n },\n ...eventDetailColumns<EventRecord>((row) => row),\n];\n\nexport function EventsView({\n events,\n selectedIndex,\n scrollOffset,\n width,\n height,\n color = \"gray\",\n}: {\n events: EventRecord[];\n selectedIndex: number;\n scrollOffset: number;\n width: number;\n height: number;\n color?: string;\n}) {\n const tableRows = Math.max(height - PANEL_TABLE_CHROME, 5);\n\n return (\n <Panel\n title=\"EVENTS\"\n subtitle={<Text dimColor>({events.length} total)</Text>}\n width={width}\n flexGrow={1}\n color={color}\n >\n <Table\n columns={eventColumns}\n data={events}\n rowKey={(ev, i) =>\n ev.id !== undefined ? String(ev.id) : `${ev.timestamp}-${i}`\n }\n selectedIndex={selectedIndex}\n scrollOffset={scrollOffset}\n visibleRows={tableRows}\n emptyMessage=\"No events recorded yet.\"\n />\n </Panel>\n );\n}\n","import { Box, Text } from \"ink\";\nimport type { EventRecord } from \"../types.js\";\nimport { Panel } from \"./panel.js\";\nimport { formatJson, ColoredJsonLine, parseDetails } from \"./json-format.js\";\n\nexport function EventDetail({\n event,\n width,\n height,\n scrollOffset,\n color = \"cyan\",\n}: {\n event: EventRecord;\n width: number;\n height: number;\n scrollOffset: number;\n color?: string;\n}) {\n const d = parseDetails(event.details);\n const routeId =\n d && typeof d[\"routeId\"] === \"string\" ? d[\"routeId\"] : undefined;\n const exchangeId =\n d && typeof d[\"exchangeId\"] === \"string\" ? d[\"exchangeId\"] : undefined;\n\n // Header lines: context (always) + capability + exchange + event + time\n const headerLines = 1 + (routeId ? 1 : 0) + (exchangeId ? 1 : 0) + 2;\n // Top panel: border (2) + content lines\n const headerHeight = 2 + headerLines;\n // Bottom panel: border (2) + title/separator (2) + footer (1) = 5\n const jsonChrome = 5;\n const jsonWidth = Math.max(width - 6, 20);\n const jsonLines = formatJson(event.details, jsonWidth);\n const visibleRows = Math.max(height - headerHeight - jsonChrome, 3);\n const visible = jsonLines.slice(scrollOffset, scrollOffset + visibleRows);\n\n return (\n <Box flexDirection=\"column\" width={width} flexGrow={1}>\n <Panel width={width}>\n <Text>\n Context:{\" \"}\n <Text bold color=\"cyan\">\n {event.contextId}\n </Text>\n </Text>\n {routeId && (\n <Text>\n Capability:{\" \"}\n <Text bold color=\"cyan\">\n {routeId}\n </Text>\n </Text>\n )}\n {exchangeId && (\n <Text>\n Exchange:{\" \"}\n <Text bold color=\"cyan\">\n {exchangeId}\n </Text>\n </Text>\n )}\n <Text>\n Event:{\" \"}\n <Text bold color=\"cyan\">\n {event.eventName}\n </Text>\n </Text>\n <Text>\n Time: <Text bold>{event.timestamp.replace(\"T\", \" \")}</Text>\n </Text>\n </Panel>\n\n <Panel\n title=\"DETAILS\"\n subtitle={\n <Text dimColor>\n ({scrollOffset + 1}-\n {Math.min(scrollOffset + visibleRows, jsonLines.length)}/\n {jsonLines.length} lines)\n </Text>\n }\n width={width}\n flexGrow={1}\n color={color}\n >\n {visible.map((line, i) => (\n <ColoredJsonLine key={scrollOffset + i} line={line} />\n ))}\n {visible.length < visibleRows &&\n Array.from({ length: visibleRows - visible.length }).map((_, i) => (\n <Text key={`pad-${i}`}> </Text>\n ))}\n </Panel>\n </Box>\n );\n}\n","import { Box, Text } from \"ink\";\nimport type { ExchangeRecord, ExchangeSnapshot } from \"../types.js\";\nimport { statusColor, formatDuration, truncate } from \"../utils.js\";\nimport { Panel } from \"./panel.js\";\nimport { formatJson, ColoredJsonLine } from \"./json-format.js\";\n\n/**\n * Build the scrollable lines for the deep view: headers + body sections.\n */\nfunction buildSnapshotLines(\n snapshot: ExchangeSnapshot,\n maxWidth: number,\n): string[] {\n const lines: string[] = [];\n\n lines.push(\"HEADERS\");\n lines.push(...formatJson(snapshot.headers, maxWidth));\n lines.push(\"\");\n lines.push(\"BODY\");\n if (snapshot.body !== null) {\n lines.push(...formatJson(snapshot.body, maxWidth));\n if (snapshot.truncated) {\n lines.push(\"\");\n lines.push(\"[Body truncated to configured limit]\");\n }\n } else {\n lines.push(\"[null]\");\n }\n\n return lines;\n}\n\nexport function ExchangeDeepView({\n exchange,\n snapshot,\n width,\n height,\n scrollOffset,\n color = \"cyan\",\n}: {\n exchange: ExchangeRecord;\n snapshot: ExchangeSnapshot | null;\n width: number;\n height: number;\n scrollOffset: number;\n color?: string;\n}) {\n // Header panel: border (2) + content (3 lines: capability + exchange + status)\n const headerHeight = 5;\n // JSON panel chrome: border (2) + title (1) + separator (1) + footer (1)\n const jsonChrome = 5;\n const jsonWidth = Math.max(width - 6, 20);\n const visibleRows = Math.max(height - headerHeight - jsonChrome, 3);\n\n const hasSnapshot = snapshot !== null;\n const jsonLines = hasSnapshot\n ? buildSnapshotLines(snapshot, jsonWidth)\n : [\n \"[Snapshots not captured]\",\n \"\",\n \"Enable with:\",\n \" telemetry({ sqlite: { captureSnapshots: true } })\",\n ];\n\n const visible = jsonLines.slice(scrollOffset, scrollOffset + visibleRows);\n\n return (\n <Box flexDirection=\"column\" width={width} flexGrow={1}>\n <Panel width={width}>\n <Text>\n Capability:{\" \"}\n <Text bold color=\"cyan\">\n {exchange.routeId}\n </Text>\n </Text>\n <Text>\n Exchange:{\" \"}\n <Text bold color=\"cyan\">\n {truncate(exchange.id, width - 14)}\n </Text>\n </Text>\n <Text>\n Status:{\" \"}\n <Text bold color={statusColor(exchange.status)}>\n {exchange.status}\n </Text>\n {exchange.durationMs !== null && (\n <Text>\n {\" \"}Duration:{\" \"}\n <Text bold>{formatDuration(exchange.durationMs)}</Text>\n </Text>\n )}\n </Text>\n </Panel>\n\n <Panel\n title=\"EXCHANGE SNAPSHOT\"\n subtitle={\n <Text dimColor>\n ({scrollOffset + 1}-\n {Math.min(scrollOffset + visibleRows, jsonLines.length)}/\n {jsonLines.length} lines)\n </Text>\n }\n width={width}\n flexGrow={1}\n color={color}\n >\n {visible.map((line, i) => {\n if (line === \"HEADERS\" || line === \"BODY\") {\n return (\n <Text key={scrollOffset + i} bold color=\"yellow\">\n {line}\n </Text>\n );\n }\n if (line.startsWith(\"[\")) {\n return (\n <Text key={scrollOffset + i} dimColor>\n {line}\n </Text>\n );\n }\n return <ColoredJsonLine key={scrollOffset + i} line={line} />;\n })}\n {visible.length < visibleRows &&\n Array.from({ length: visibleRows - visible.length }).map((_, i) => (\n <Text key={`pad-${i}`}> </Text>\n ))}\n </Panel>\n </Box>\n );\n}\n","import { Text } from \"ink\";\nimport type { RouteSummary } from \"../types.js\";\nimport { truncate } from \"../utils.js\";\n\nfunction dotColor(route: RouteSummary): string {\n if (route.failedExchanges > 0) return \"red\";\n if (route.totalExchanges > 0) return \"green\";\n return \"yellow\";\n}\n\nexport function CapabilityList({\n routes,\n selectedIndex,\n listOffset,\n visibleRows,\n width,\n}: {\n routes: RouteSummary[];\n selectedIndex: number;\n listOffset: number;\n visibleRows: number;\n width: number;\n}) {\n const offset = listOffset;\n\n return (\n <>\n <Text> </Text>\n <Text bold dimColor>\n {\"\\u2500\".repeat(width + 2)}\n </Text>\n {routes.length === 0 ? (\n <Text dimColor>No capabilities</Text>\n ) : (\n routes.slice(offset, offset + visibleRows).map((route, vi) => {\n const i = offset + vi;\n return (\n <Text key={route.id} wrap=\"truncate\">\n <Text\n {...(i === selectedIndex ? { color: \"cyan\" as const } : {})}\n bold={i === selectedIndex}\n >\n {i === selectedIndex ? \"> \" : \" \"}\n </Text>\n <Text color={dotColor(route)}>{\"\\u25CF \"}</Text>\n <Text\n {...(i === selectedIndex ? { color: \"cyan\" as const } : {})}\n bold={i === selectedIndex}\n >\n {truncate(route.id, width - 2)}\n </Text>\n </Text>\n );\n })\n )}\n {routes.length > visibleRows && (\n <Text dimColor>\n {selectedIndex + 1}/{routes.length}\n </Text>\n )}\n </>\n );\n}\n","import { useState, useEffect, useCallback } from \"react\";\nimport { render, Box, Text, useInput, useApp, useStdout } from \"ink\";\nimport { TelemetryDb } from \"./db.js\";\nimport type {\n NavItem,\n RouteSummary,\n ExchangeRecord,\n ExchangeSnapshot,\n EventRecord,\n Metrics,\n RouteActivity,\n} from \"./types.js\";\nimport { NAV_SECTIONS, ALL_NAV_ITEMS } from \"./types.js\";\nimport { fmtNum, formatDuration } from \"./utils.js\";\nimport { useScrollList } from \"./hooks/use-scroll-list.js\";\nimport { PANEL_TABLE_CHROME, DETAIL_INFO_CHROME, NAV_JUMP } from \"./layout.js\";\nimport { Panel } from \"./components/panel.js\";\nimport { DotGraph, DEFAULT_STEPS } from \"./components/dot-graph.js\";\nimport { CenterExchangeList } from \"./components/center-exchange-list.js\";\nimport { CenterExchangeDetail } from \"./components/center-exchange-detail.js\";\nimport { EventsView } from \"./components/events-view.js\";\nimport { EventDetail } from \"./components/event-detail.js\";\nimport { ExchangeDeepView } from \"./components/exchange-deep-view.js\";\nimport { CapabilityList } from \"./components/capability-list.js\";\n\n/**\n * Focus tracks which panel owns the cursor.\n * - \"nav\": left panel (route list / nav items)\n * - \"center\": center panel (exchange list, events, detail)\n */\ntype Focus = \"nav\" | \"center\";\n\nfunction App({ db }: { db: TelemetryDb }) {\n const { exit } = useApp();\n const { stdout } = useStdout();\n const width = stdout?.columns ?? 80;\n const height = stdout?.rows ?? 24;\n\n const [activeNav, setActiveNav] = useState<NavItem>(\"capabilities\");\n const [focus, setFocus] = useState<Focus>(\"nav\");\n const [showDetail, setShowDetail] = useState(false);\n\n const [routes, setRoutes] = useState<RouteSummary[]>([]);\n const [metrics, setMetrics] = useState<Metrics>({\n totalRoutes: 0,\n totalExchanges: 0,\n completedExchanges: 0,\n failedExchanges: 0,\n droppedExchanges: 0,\n errorRate: 0,\n avgDurationMs: null,\n p90DurationMs: null,\n p95DurationMs: null,\n p99DurationMs: null,\n });\n const [liveTraffic, setLiveTraffic] = useState<number[]>([]);\n const [selectedRouteActivity, setSelectedRouteActivity] = useState<\n RouteActivity | undefined\n >(undefined);\n const routeScroll = useScrollList();\n const [exchanges, setExchanges] = useState<ExchangeRecord[]>([]);\n const exchangeScroll = useScrollList();\n const [selectedExchange, setSelectedExchange] = useState<\n ExchangeRecord | undefined\n >(undefined);\n const [exchangeEvents, setExchangeEvents] = useState<EventRecord[]>([]);\n const [events, setEvents] = useState<EventRecord[]>([]);\n const eventScroll = useScrollList();\n const detailScroll = useScrollList();\n const [selectedEvent, setSelectedEvent] = useState<EventRecord | undefined>(\n undefined,\n );\n const [showEventDetail, setShowEventDetail] = useState(false);\n const [eventDetailScroll, setEventDetailScroll] = useState(0);\n const [showDeepView, setShowDeepView] = useState(false);\n const [deepViewScroll, setDeepViewScroll] = useState(0);\n const [exchangeSnapshot, setExchangeSnapshot] =\n useState<ExchangeSnapshot | null>(null);\n const PAGE_SIZE = 50;\n const JUMP = NAV_JUMP;\n\n // Layout dimensions (needed by both refresh and render)\n const leftWidth = Math.max(Math.min(Math.floor(width * 0.18), 26), 16);\n const rightWidth = Math.max(Math.min(Math.floor(width * 0.22), 30), 20);\n const centerWidth = Math.max(width - leftWidth - rightWidth, 30);\n const bodyHeight = Math.max(height - 5, 10);\n const navHeaderRows = 10;\n const navListHeight = Math.max(bodyHeight - navHeaderRows, 3);\n\n const refresh = useCallback(() => {\n try {\n // Always refresh: routes, metrics, graphs\n const routeSummary = db.getRouteSummary();\n setRoutes(routeSummary);\n setMetrics(db.getMetrics());\n const liveCols = rightWidth - 4;\n setLiveTraffic(db.getLiveTrafficBuckets(liveCols, 5));\n\n // Only load activity for the currently selected route\n const routeCols = centerWidth - 4;\n const curRoute = routeSummary[routeScroll.selectedIndex];\n if (curRoute) {\n setSelectedRouteActivity(\n db.getSingleRouteActivity(curRoute.id, routeCols, 5),\n );\n }\n\n // Skip list refresh when cursor is active (user is browsing)\n if (focus === \"center\") return;\n\n if (activeNav === \"capabilities\") {\n const route = routeSummary[routeScroll.selectedIndex];\n if (route) {\n setExchanges(db.getExchangesByRoute(route.id, PAGE_SIZE));\n }\n } else if (activeNav === \"exchanges\") {\n setExchanges(db.getAllExchanges(PAGE_SIZE));\n } else if (activeNav === \"errors\") {\n setExchanges(db.getFailedExchanges(PAGE_SIZE));\n } else if (activeNav === \"events\") {\n setEvents(db.getRecentEvents({ limit: 200 }));\n }\n } catch {\n // Database may be temporarily locked\n }\n }, [\n db,\n activeNav,\n routeScroll.selectedIndex,\n rightWidth,\n centerWidth,\n focus,\n ]);\n\n useEffect(() => {\n refresh();\n const timer = setInterval(refresh, 2000);\n return () => {\n clearInterval(timer);\n };\n }, [refresh]);\n\n const selectRoute = useCallback(\n (index: number) => {\n routeScroll.moveTo(index, routes.length, navListHeight);\n exchangeScroll.reset();\n const route = routes[index];\n if (route) {\n setExchanges(db.getExchangesByRoute(route.id, PAGE_SIZE));\n }\n },\n [db, routes, routeScroll, exchangeScroll, navListHeight],\n );\n\n const switchNav = useCallback(\n (nav: NavItem) => {\n setActiveNav(nav);\n setShowDetail(false);\n setShowEventDetail(false);\n setShowDeepView(false);\n setFocus(\"nav\");\n exchangeScroll.reset();\n if (nav === \"exchanges\") {\n setExchanges(db.getAllExchanges(PAGE_SIZE));\n } else if (nav === \"errors\") {\n setExchanges(db.getFailedExchanges(PAGE_SIZE));\n } else if (nav === \"events\") {\n eventScroll.reset();\n setEvents(db.getRecentEvents({ limit: 200 }));\n }\n },\n [db, exchangeScroll, eventScroll],\n );\n\n const selectedRoute = routes[routeScroll.selectedIndex];\n\n // Visible row counts mirror the view components\n // Must match CenterExchangeList: 2 (capability + stats) + graphTermRows + 2 (label + spacer)\n const graphTermRows = Math.ceil((DEFAULT_STEPS.length - 1) / 4);\n const exchangeHeaderRows = selectedRoute ? 2 + graphTermRows + 2 : 0;\n const exchangeTableRows = Math.max(\n bodyHeight - PANEL_TABLE_CHROME - exchangeHeaderRows,\n 3,\n );\n const eventsTableRows = Math.max(bodyHeight - PANEL_TABLE_CHROME, 5);\n\n useInput((input, key) => {\n if (input === \"q\") {\n db.close();\n exit();\n return;\n }\n\n // Number shortcuts to switch nav (always available)\n const navByShortcut = ALL_NAV_ITEMS.find((n) => n.shortcut === input);\n if (navByShortcut) {\n switchNav(navByShortcut.key);\n return;\n }\n\n // Events view: overview -> browse -> detail\n if (activeNav === \"events\") {\n if (showEventDetail) {\n // Detail view: scroll JSON, Esc to go back to list\n const step = key.ctrl ? JUMP : 1;\n if (input === \"j\" || key.downArrow) {\n setEventDetailScroll((i) => i + step);\n } else if (input === \"k\" || key.upArrow) {\n setEventDetailScroll((i) => Math.max(i - step, 0));\n } else if (key.escape || key.backspace || key.delete) {\n setShowEventDetail(false);\n setEventDetailScroll(0);\n }\n return;\n }\n if (focus === \"nav\") {\n if (key.return) {\n setFocus(\"center\");\n }\n } else {\n const step = key.ctrl ? JUMP : 1;\n if (input === \"j\" || key.downArrow) {\n eventScroll.moveBy(step, events.length, eventsTableRows);\n } else if (input === \"k\" || key.upArrow) {\n eventScroll.moveBy(-step, events.length, eventsTableRows);\n } else if (key.return) {\n const ev = events[eventScroll.selectedIndex];\n if (ev) {\n setSelectedEvent(ev);\n setEventDetailScroll(0);\n setShowEventDetail(true);\n }\n } else if (key.escape || key.backspace || key.delete) {\n setFocus(\"nav\");\n eventScroll.reset();\n }\n }\n return;\n }\n\n // Exchange deep view: scrollable JSON of headers + body\n if (showDeepView) {\n const step = key.ctrl ? JUMP : 1;\n if (input === \"j\" || key.downArrow) {\n setDeepViewScroll((i) => i + step);\n } else if (input === \"k\" || key.upArrow) {\n setDeepViewScroll((i) => Math.max(i - step, 0));\n } else if (key.escape || key.backspace || key.delete) {\n setShowDeepView(false);\n setDeepViewScroll(0);\n }\n return;\n }\n\n // Exchange detail (any nav)\n if (showDetail && !showEventDetail) {\n const hasExtra = selectedExchange?.error ? 2 : 0;\n const detailEventRows = Math.max(\n bodyHeight - DETAIL_INFO_CHROME - hasExtra,\n 3,\n );\n // Count group headers: when events span multiple exchanges, each group gets a header row\n const uniqueExchangeIds = new Set(\n exchangeEvents.map((ev) => {\n try {\n const d = JSON.parse(ev.details) as Record<string, unknown>;\n return String(d[\"exchangeId\"] ?? \"\");\n } catch {\n return \"\";\n }\n }),\n );\n const groupCount = Math.max(uniqueExchangeIds.size, 1);\n const headerRows = groupCount > 1 ? groupCount : 0;\n const totalDisplayRows = exchangeEvents.length + headerRows;\n const step = key.ctrl ? JUMP : 1;\n if (input === \"j\" || key.downArrow) {\n detailScroll.moveBy(step, totalDisplayRows, detailEventRows);\n } else if (input === \"k\" || key.upArrow) {\n detailScroll.moveBy(-step, totalDisplayRows, detailEventRows);\n } else if (key.return) {\n // Resolve the selected display row to an EventRecord (skip headers)\n // Build the same display row list the component builds\n let rowIndex = 0;\n let targetEvent: EventRecord | undefined;\n const parentId = selectedExchange?.id ?? \"\";\n const groups = new Map<string, EventRecord[]>();\n groups.set(parentId, []);\n for (const ev of exchangeEvents) {\n try {\n const d = JSON.parse(ev.details) as Record<string, unknown>;\n const exId = String(d[\"exchangeId\"] ?? \"\");\n const gKey = !exId || exId === parentId ? parentId : exId;\n if (!groups.has(gKey)) groups.set(gKey, []);\n groups.get(gKey)!.push(ev);\n } catch {\n groups.get(parentId)!.push(ev);\n }\n }\n const hasChildren = groups.size > 1;\n for (const [, groupEvents] of groups) {\n if (hasChildren) rowIndex++; // header row\n for (const ev of groupEvents) {\n if (rowIndex === detailScroll.selectedIndex) {\n targetEvent = ev;\n }\n rowIndex++;\n }\n }\n if (targetEvent) {\n setSelectedEvent(targetEvent);\n setEventDetailScroll(0);\n setShowEventDetail(true);\n }\n } else if (input === \"e\" && selectedExchange) {\n const snapshot = db.getExchangeSnapshot(selectedExchange.id);\n setExchangeSnapshot(snapshot);\n setDeepViewScroll(0);\n setShowDeepView(true);\n } else if (key.escape || key.backspace || key.delete) {\n detailScroll.reset();\n setShowDetail(false);\n }\n return;\n }\n\n // Event detail from exchange detail: Esc goes back to exchange detail\n if (showDetail && showEventDetail) {\n const step = key.ctrl ? JUMP : 1;\n if (input === \"j\" || key.downArrow) {\n setEventDetailScroll((i) => i + step);\n } else if (input === \"k\" || key.upArrow) {\n setEventDetailScroll((i) => Math.max(i - step, 0));\n } else if (key.escape || key.backspace || key.delete) {\n setShowEventDetail(false);\n setEventDetailScroll(0);\n }\n return;\n }\n\n // Capabilities: nav focus (left panel)\n if (activeNav === \"capabilities\" && focus === \"nav\") {\n if (input === \"j\" || key.downArrow) {\n selectRoute(Math.min(routeScroll.selectedIndex + 1, routes.length - 1));\n } else if (input === \"k\" || key.upArrow) {\n selectRoute(Math.max(routeScroll.selectedIndex - 1, 0));\n } else if (key.return) {\n setFocus(\"center\");\n // Load all exchanges for browsing (auto-refresh uses PAGE_SIZE)\n const route = routes[routeScroll.selectedIndex];\n if (route) {\n setExchanges(db.getExchangesByRoute(route.id));\n }\n }\n return;\n }\n\n // Capabilities: center focus (exchange list)\n if (activeNav === \"capabilities\" && focus === \"center\") {\n const step = key.ctrl ? JUMP : 1;\n if (input === \"j\" || key.downArrow) {\n exchangeScroll.moveBy(step, exchanges.length, exchangeTableRows);\n } else if (input === \"k\" || key.upArrow) {\n exchangeScroll.moveBy(-step, exchanges.length, exchangeTableRows);\n } else if (key.return) {\n const ex = exchanges[exchangeScroll.selectedIndex];\n if (ex) {\n setSelectedExchange(ex);\n setExchangeEvents(db.getEventsByExchange(ex.id, ex.correlationId));\n detailScroll.reset();\n setShowEventDetail(false);\n setShowDetail(true);\n }\n } else if (key.escape || key.backspace || key.delete) {\n setFocus(\"nav\");\n exchangeScroll.reset();\n }\n return;\n }\n\n // Exchanges / Errors: overview (nav focus) or browsing (center focus)\n if (activeNav === \"exchanges\" || activeNav === \"errors\") {\n if (focus === \"nav\") {\n // Overview mode: Enter to freeze and browse\n if (key.return) {\n setFocus(\"center\");\n // Load full data set for browsing\n if (activeNav === \"exchanges\") {\n setExchanges(db.getAllExchanges());\n } else {\n setExchanges(db.getFailedExchanges());\n }\n }\n } else {\n // Browsing mode: navigate with pointer\n const step = key.ctrl ? JUMP : 1;\n if (input === \"j\" || key.downArrow) {\n exchangeScroll.moveBy(step, exchanges.length, exchangeTableRows);\n } else if (input === \"k\" || key.upArrow) {\n exchangeScroll.moveBy(-step, exchanges.length, exchangeTableRows);\n } else if (key.return) {\n const ex = exchanges[exchangeScroll.selectedIndex];\n if (ex) {\n setSelectedExchange(ex);\n setExchangeEvents(db.getEventsByExchange(ex.id, ex.correlationId));\n detailScroll.reset();\n setShowEventDetail(false);\n setShowDetail(true);\n }\n } else if (key.escape || key.backspace || key.delete) {\n setFocus(\"nav\");\n exchangeScroll.reset();\n }\n }\n return;\n }\n });\n\n // Determine which panel is active for border highlighting\n const navActive =\n activeNav === \"capabilities\" && focus === \"nav\" && !showDetail;\n const centerActive = !navActive;\n\n // Keymap items based on context\n const keymapItems: { key: string; action: string }[] = [];\n if (showDeepView) {\n keymapItems.push({ key: \"j/k\", action: \"Scroll\" });\n keymapItems.push({ key: \"Ctrl+j/k\", action: \"Jump 10\" });\n keymapItems.push({ key: \"Esc\", action: \"Back\" });\n } else if (focus === \"center\") {\n keymapItems.push({ key: \"j/k\", action: \"Navigate\" });\n keymapItems.push({ key: \"Ctrl+j/k\", action: \"Jump 10\" });\n }\n if (!showDeepView) {\n if (focus === \"nav\") {\n if (activeNav === \"capabilities\") {\n keymapItems.push({ key: \"j/k\", action: \"Navigate\" });\n keymapItems.push({ key: \"Enter\", action: \"Exchanges\" });\n } else {\n keymapItems.push({ key: \"Enter\", action: \"Browse\" });\n }\n } else if (!showDetail && !showEventDetail) {\n keymapItems.push({ key: \"Enter\", action: \"Detail\" });\n keymapItems.push({ key: \"Esc\", action: \"Back\" });\n } else if (showDetail && !showEventDetail) {\n keymapItems.push({ key: \"Enter\", action: \"Event detail\" });\n keymapItems.push({ key: \"e\", action: \"Snapshot\" });\n keymapItems.push({ key: \"Esc\", action: \"Back\" });\n } else {\n keymapItems.push({ key: \"Esc\", action: \"Back\" });\n }\n }\n keymapItems.push({ key: \"1..4\", action: \"Switch view\" });\n keymapItems.push({ key: \"q\", action: \"Quit\" });\n\n return (\n <Box flexDirection=\"column\" width={width} height={height}>\n {/* Title bar */}\n <Box borderStyle=\"round\" borderColor=\"cyan\" paddingX={1} width={width}>\n <Text bold color=\"cyan\">\n ROUTECRAFT TUI\n </Text>\n <Text> </Text>\n <Text dimColor>v0.4.0</Text>\n </Box>\n\n {/* 3-column body */}\n <Box flexDirection=\"row\" width={width} flexGrow={1}>\n {/* Left column: Navigation (top) + Keymap (bottom) */}\n <Box flexDirection=\"column\" width={leftWidth}>\n <Panel\n title=\"NAVIGATION\"\n color={navActive ? \"cyan\" : \"gray\"}\n width={leftWidth}\n flexGrow={1}\n >\n {NAV_SECTIONS.map((section, si) => (\n <Box key={section.label ?? si} flexDirection=\"column\">\n {si > 0 && <Text> </Text>}\n {section.label && (\n <Text dimColor bold>\n {section.label}\n </Text>\n )}\n {section.items.map((item) => (\n <Text key={item.key}>\n <Text\n bold={activeNav === item.key}\n {...(activeNav === item.key\n ? { color: \"cyan\" as const }\n : {})}\n >\n {activeNav === item.key ? \"> \" : \" \"}\n {item.label}\n </Text>\n <Text dimColor> ({item.shortcut})</Text>\n </Text>\n ))}\n </Box>\n ))}\n\n {activeNav === \"capabilities\" && (\n <CapabilityList\n routes={routes}\n selectedIndex={routeScroll.selectedIndex}\n listOffset={routeScroll.scrollOffset}\n visibleRows={navListHeight}\n width={leftWidth - 6}\n />\n )}\n </Panel>\n </Box>\n\n {/* Center */}\n {activeNav === \"capabilities\" && !showDetail && (\n <CenterExchangeList\n capabilityId={selectedRoute?.id ?? \"\"}\n route={selectedRoute}\n exchanges={exchanges}\n selectedIndex={\n focus === \"center\" ? exchangeScroll.selectedIndex : -1\n }\n scrollOffset={focus === \"center\" ? exchangeScroll.scrollOffset : 0}\n width={centerWidth}\n height={bodyHeight}\n color={centerActive ? \"cyan\" : \"gray\"}\n activity={selectedRouteActivity}\n />\n )}\n {activeNav === \"capabilities\" && showDeepView && selectedExchange && (\n <ExchangeDeepView\n exchange={selectedExchange}\n snapshot={exchangeSnapshot}\n width={centerWidth}\n height={bodyHeight}\n scrollOffset={deepViewScroll}\n color=\"cyan\"\n />\n )}\n {activeNav === \"capabilities\" &&\n showDetail &&\n selectedExchange &&\n !showEventDetail &&\n !showDeepView && (\n <CenterExchangeDetail\n exchange={selectedExchange}\n events={exchangeEvents}\n width={centerWidth}\n height={bodyHeight}\n selectedIndex={detailScroll.selectedIndex}\n scrollOffset={detailScroll.scrollOffset}\n color=\"cyan\"\n />\n )}\n {activeNav === \"capabilities\" &&\n showDetail &&\n showEventDetail &&\n !showDeepView &&\n selectedEvent && (\n <EventDetail\n event={selectedEvent}\n width={centerWidth}\n height={bodyHeight}\n scrollOffset={eventDetailScroll}\n color=\"cyan\"\n />\n )}\n {activeNav === \"exchanges\" && !showDetail && (\n <CenterExchangeList\n capabilityId=\"All Capabilities\"\n exchanges={exchanges}\n selectedIndex={\n focus === \"center\" ? exchangeScroll.selectedIndex : -1\n }\n scrollOffset={focus === \"center\" ? exchangeScroll.scrollOffset : 0}\n width={centerWidth}\n height={bodyHeight}\n color={focus === \"center\" ? \"cyan\" : \"gray\"}\n />\n )}\n {activeNav === \"exchanges\" && showDeepView && selectedExchange && (\n <ExchangeDeepView\n exchange={selectedExchange}\n snapshot={exchangeSnapshot}\n width={centerWidth}\n height={bodyHeight}\n scrollOffset={deepViewScroll}\n color=\"cyan\"\n />\n )}\n {activeNav === \"exchanges\" &&\n showDetail &&\n selectedExchange &&\n !showEventDetail &&\n !showDeepView && (\n <CenterExchangeDetail\n exchange={selectedExchange}\n events={exchangeEvents}\n width={centerWidth}\n height={bodyHeight}\n selectedIndex={detailScroll.selectedIndex}\n scrollOffset={detailScroll.scrollOffset}\n color=\"cyan\"\n />\n )}\n {activeNav === \"exchanges\" &&\n showDetail &&\n showEventDetail &&\n !showDeepView &&\n selectedEvent && (\n <EventDetail\n event={selectedEvent}\n width={centerWidth}\n height={bodyHeight}\n scrollOffset={eventDetailScroll}\n color=\"cyan\"\n />\n )}\n {activeNav === \"errors\" && !showDetail && (\n <CenterExchangeList\n capabilityId=\"Failed Exchanges\"\n exchanges={exchanges}\n selectedIndex={\n focus === \"center\" ? exchangeScroll.selectedIndex : -1\n }\n scrollOffset={focus === \"center\" ? exchangeScroll.scrollOffset : 0}\n width={centerWidth}\n height={bodyHeight}\n color={focus === \"center\" ? \"cyan\" : \"gray\"}\n />\n )}\n {activeNav === \"errors\" && showDeepView && selectedExchange && (\n <ExchangeDeepView\n exchange={selectedExchange}\n snapshot={exchangeSnapshot}\n width={centerWidth}\n height={bodyHeight}\n scrollOffset={deepViewScroll}\n color=\"cyan\"\n />\n )}\n {activeNav === \"errors\" &&\n showDetail &&\n selectedExchange &&\n !showEventDetail &&\n !showDeepView && (\n <CenterExchangeDetail\n exchange={selectedExchange}\n events={exchangeEvents}\n width={centerWidth}\n height={bodyHeight}\n selectedIndex={detailScroll.selectedIndex}\n scrollOffset={detailScroll.scrollOffset}\n color=\"cyan\"\n />\n )}\n {activeNav === \"errors\" &&\n showDetail &&\n showEventDetail &&\n !showDeepView &&\n selectedEvent && (\n <EventDetail\n event={selectedEvent}\n width={centerWidth}\n height={bodyHeight}\n scrollOffset={eventDetailScroll}\n color=\"cyan\"\n />\n )}\n {activeNav === \"events\" && !showEventDetail && (\n <EventsView\n events={events}\n selectedIndex={focus === \"center\" ? eventScroll.selectedIndex : -1}\n scrollOffset={focus === \"center\" ? eventScroll.scrollOffset : 0}\n width={centerWidth}\n height={bodyHeight}\n color={focus === \"center\" ? \"cyan\" : \"gray\"}\n />\n )}\n {activeNav === \"events\" && showEventDetail && selectedEvent && (\n <EventDetail\n event={selectedEvent}\n width={centerWidth}\n height={bodyHeight}\n scrollOffset={eventDetailScroll}\n color=\"cyan\"\n />\n )}\n\n {/* Right: Metrics + Keymap */}\n <Box flexDirection=\"column\" width={rightWidth}>\n <Panel title=\"METRICS\" width={rightWidth} flexGrow={1}>\n <DotGraph\n values={liveTraffic}\n columns={rightWidth - 4}\n steps={[\n { max: 0, color: \"gray\" },\n ...(Array.from({ length: 7 }, (_, i) => ({\n max: (i + 1) * 5,\n color: \"green\",\n })) as { max: number; color: string }[]),\n ...(Array.from({ length: 7 }, (_, i) => ({\n max: 35 + (i + 1) * 10,\n color: \"yellow\",\n })) as { max: number; color: string }[]),\n ...(Array.from({ length: 6 }, (_, i) => ({\n max: 105 + (i + 1) * 25,\n color: \"red\",\n })) as { max: number; color: string }[]),\n ]}\n label=\"Exchanges per 5s bucket\"\n />\n <Text> </Text>\n <Text bold dimColor>\n THROUGHPUT\n </Text>\n {(\n [\n [\"Exchanges\", fmtNum(metrics.totalExchanges), \"cyan\"],\n [\"Completed\", fmtNum(metrics.completedExchanges), \"green\"],\n [\n \"Errors\",\n fmtNum(metrics.failedExchanges),\n metrics.failedExchanges > 0 ? \"red\" : \"green\",\n ],\n [\n \"Dropped\",\n fmtNum(metrics.droppedExchanges),\n metrics.droppedExchanges > 0 ? \"yellow\" : \"green\",\n ],\n [\n \"Error Rate\",\n `${(metrics.errorRate * 100).toFixed(1)}%`,\n metrics.errorRate > 0.1 ? \"red\" : \"green\",\n ],\n [\"Capabilities\", fmtNum(metrics.totalRoutes), \"\"],\n ] as [string, string, string][]\n ).map(([label, value, color]) => (\n <Box key={label}>\n <Text>{label}:</Text>\n <Box flexGrow={1} justifyContent=\"flex-end\">\n <Text bold {...(color ? { color } : {})}>\n {value}\n </Text>\n </Box>\n </Box>\n ))}\n <Text> </Text>\n <Text bold dimColor>\n LATENCY (5m)\n </Text>\n {(\n [\n [\"Avg\", formatDuration(metrics.avgDurationMs), \"\"],\n [\"p90\", formatDuration(metrics.p90DurationMs), \"\"],\n [\"p95\", formatDuration(metrics.p95DurationMs), \"\"],\n [\"p99\", formatDuration(metrics.p99DurationMs), \"\"],\n ] as [string, string, string][]\n ).map(([label, value, color]) => (\n <Box key={label}>\n <Text>{label}:</Text>\n <Box flexGrow={1} justifyContent=\"flex-end\">\n <Text bold {...(color ? { color } : {})}>\n {value}\n </Text>\n </Box>\n </Box>\n ))}\n </Panel>\n\n <Panel title=\"KEYMAP\" width={rightWidth}>\n {keymapItems.map((item) => (\n <Box key={item.key}>\n <Text>{item.action}</Text>\n <Box flexGrow={1} justifyContent=\"flex-end\">\n <Text color=\"yellow\">[{item.key}]</Text>\n </Box>\n </Box>\n ))}\n </Panel>\n </Box>\n </Box>\n </Box>\n );\n}\n\nexport async function renderTui(dbPath: string): Promise<void> {\n let db: TelemetryDb;\n try {\n db = await TelemetryDb.open(dbPath);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n process.stderr.write(`Failed to open telemetry database: ${msg}\\n`);\n process.stderr.write(`Path: ${dbPath}\\n`);\n process.stderr.write(\n \"Make sure you have a running Routecraft context with telemetry() enabled.\\n\",\n );\n process.exit(1);\n }\n\n const instance = render(<App db={db} />);\n await instance.waitUntilExit();\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/tui/types.ts","../../src/tui/utils.ts","../../src/tui/hooks/use-scroll-list.ts","../../src/tui/components/panel.tsx","../../src/tui/components/dot-graph.tsx","../../src/tui/components/route-header.tsx","../../src/tui/components/table.tsx","../../src/tui/components/event-columns.tsx","../../src/tui/components/center-exchange-list.tsx","../../src/tui/components/json-format.tsx","../../src/tui/components/center-exchange-detail.tsx","../../src/tui/components/events-view.tsx","../../src/tui/components/event-detail.tsx","../../src/tui/components/exchange-deep-view.tsx","../../src/tui/components/capability-list.tsx","../../src/tui/app.tsx"],"names":["NAV_SECTIONS","ALL_NAV_ITEMS","s","truncate","str","maxLen","formatDuration","ms","statusColor","status","col","len","parseEventDetail","raw","d","exchange","duration","adapter","meta","m","keys","k","qualifier","route","err","formatDetailColumns","_eventName","parsed","fmtNum","n","adjustScrollOffset","selected","currentOffset","visibleRows","useScrollList","initialIndex","selectedIndex","setSelectedIndex","useState","scrollOffset","setScrollOffset","moveTo","useCallback","index","listLength","clamped","off","moveBy","delta","prev","next","reset","Panel","title","subtitle","color","width","flexGrow","paddingX","children","innerWidth","jsxs","Box","Fragment","Text","jsx","BRAILLE_DOTS","BRAILLE_BASE","DEFAULT_STEPS","DotGraph","values","columns","steps","label","dotHeight","data","heights","v","i","termRows","rows","tr","baseStep","segments","ci","h","bits","sr","stepLevel","char","last","RouteHeader","Table","rowKey","gap","emptyMessage","renderFullRow","gapStr","header","c","after","text","visible","remaining","row","vi","dataIndex","fullRow","resolved","cell","eventDetailColumns","accessor","cache","getColumns","ev","cols","_sel","w","selectorColumn","_row","exchangeColumns","CenterExchangeList","capabilityId","exchanges","height","activity","graphTermRows","headerRows","tableRows","ex","tokenizeLine","line","tokens","re","lastIndex","match","TOKEN_COLORS","formatJson","maxWidth","clampedMax","ColoredJsonLine","token","parseDetails","groupEventsByExchange","events","parentExchangeId","groups","childIndex","exId","key","detailColumns","indent","CenterExchangeDetail","hasExtra","eventRows","hasChildren","displayRows","group","eventsTitle","eventColumns","EventsView","EventDetail","event","routeId","exchangeId","headerHeight","jsonChrome","jsonWidth","jsonLines","_","buildSnapshotLines","snapshot","lines","ExchangeDeepView","dotColor","CapabilityList","routes","listOffset","offset","App","db","exit","useApp","stdout","useStdout","activeNav","setActiveNav","focus","setFocus","showDetail","setShowDetail","setRoutes","metrics","setMetrics","liveTraffic","setLiveTraffic","selectedRouteActivity","setSelectedRouteActivity","routeScroll","setExchanges","exchangeScroll","selectedExchange","setSelectedExchange","exchangeEvents","setExchangeEvents","setEvents","eventScroll","detailScroll","selectedEvent","setSelectedEvent","showEventDetail","setShowEventDetail","eventDetailScroll","setEventDetailScroll","showDeepView","setShowDeepView","deepViewScroll","setDeepViewScroll","exchangeSnapshot","setExchangeSnapshot","PAGE_SIZE","JUMP","leftWidth","rightWidth","centerWidth","bodyHeight","navListHeight","refresh","routeSummary","liveCols","routeCols","curRoute","useEffect","timer","selectRoute","switchNav","nav","selectedRoute","exchangeHeaderRows","exchangeTableRows","eventsTableRows","useInput","input","navByShortcut","step","detailEventRows","uniqueExchangeIds","groupCount","totalDisplayRows","rowIndex","targetEvent","parentId","gKey","groupEvents","navActive","centerActive","keymapItems","version","section","si","item","value","renderTui","dbPath","TelemetryDb","msg","render"],"mappings":"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","file":"app.js","sourcesContent":["export type NavItem = \"capabilities\" | \"exchanges\" | \"errors\" | \"events\";\n\nexport type NavSection = {\n label?: string;\n items: { key: NavItem; label: string; shortcut: string }[];\n};\n\nexport const NAV_SECTIONS: NavSection[] = [\n {\n items: [{ key: \"capabilities\", label: \"Capabilities\", shortcut: \"1\" }],\n },\n {\n items: [\n { key: \"exchanges\", label: \"Exchanges\", shortcut: \"2\" },\n { key: \"errors\", label: \"Errors\", shortcut: \"3\" },\n { key: \"events\", label: \"Events\", shortcut: \"4\" },\n ],\n },\n];\n\nexport const ALL_NAV_ITEMS = NAV_SECTIONS.flatMap((s) => s.items);\n\nexport interface RouteSummary {\n id: string;\n status: string;\n totalExchanges: number;\n completedExchanges: number;\n failedExchanges: number;\n droppedExchanges: number;\n avgDurationMs: number | null;\n}\n\nexport interface ExchangeRecord {\n id: string;\n routeId: string;\n contextId: string;\n correlationId: string;\n status: string;\n startedAt: string;\n completedAt: string | null;\n durationMs: number | null;\n error: string | null;\n}\n\nexport interface EventRecord {\n id?: number;\n timestamp: string;\n contextId: string;\n eventName: string;\n details: string;\n}\n\nexport interface Metrics {\n totalRoutes: number;\n totalExchanges: number;\n completedExchanges: number;\n failedExchanges: number;\n droppedExchanges: number;\n errorRate: number;\n avgDurationMs: number | null;\n p90DurationMs: number | null;\n p95DurationMs: number | null;\n p99DurationMs: number | null;\n}\n\nexport interface ExchangeSnapshot {\n headers: string;\n body: string | null;\n truncated: boolean;\n}\n\nexport interface RouteActivity {\n throughput: number[];\n recentErrors: number;\n}\n","export function truncate(str: string, maxLen: number): string {\n if (maxLen <= 0) return \"\";\n return str.length > maxLen ? str.slice(0, maxLen - 1) + \"\\u2026\" : str;\n}\n\nexport function formatDuration(ms: number | null): string {\n if (ms === null || ms === undefined) return \"-\";\n if (!Number.isFinite(ms) || ms < 0) return \"-\";\n if (ms === 0) return \"<1ms\";\n if (ms < 1000) return `${Math.round(ms)}ms`;\n return `${(ms / 1000).toFixed(1)}s`;\n}\n\nexport function statusColor(status: string): string {\n switch (status) {\n case \"completed\":\n case \"started\":\n return \"green\";\n case \"failed\":\n return \"red\";\n case \"stopped\":\n case \"dropped\":\n return \"yellow\";\n default:\n return \"white\";\n }\n}\n\nexport function col(str: string, len: number | undefined): string {\n if (len === undefined) return str;\n if (len <= 0) return \"\";\n if (str.length > len) return str.slice(0, len - 1) + \"\\u2026\";\n return str.padEnd(len);\n}\n\n// Fixed column widths for the Details column so fields line up across rows.\n// All event types share the same 4-column layout:\n// [col1: 10] [col2: 10] [exId: 12] [dur: 6] [extra]\n// Step events: operation (adapter) id… dur metadata\n// Exchange events: routeId (status) id… dur\nconst DET = {\n COL1: 10, // operation or routeId\n COL2: 10, // (adapter) or (err)/(reason)/(dropped)\n EX: 12, // \"789003e7 \"\n DUR: 6, // \"1ms \" \"10.0s \"\n} as const;\n\nexport interface DetailColumns {\n step: string;\n adapter: string;\n exchange: string;\n duration: string;\n meta: string;\n}\n\n/**\n * Parse a JSON event detail string into structured columns.\n * Shared normalizer used by both formatDetails and formatDetailColumns.\n */\nfunction parseEventDetail(raw: string): DetailColumns | null {\n try {\n const d = JSON.parse(raw) as Record<string, unknown>;\n\n const exchange =\n \"exchangeId\" in d ? `${String(d[\"exchangeId\"]).slice(0, 8)}` : \"\";\n const duration =\n \"duration\" in d ? formatDuration(d[\"duration\"] as number) : \"\";\n\n // Step/operation events\n if (\"operation\" in d && \"routeId\" in d) {\n const adapter =\n \"adapter\" in d\n ? `(${d[\"adapter\"]})`\n : \"adapterId\" in d\n ? `(${d[\"adapterId\"]})`\n : \"\";\n let meta = \"\";\n if (\n \"metadata\" in d &&\n typeof d[\"metadata\"] === \"object\" &&\n d[\"metadata\"] !== null\n ) {\n const m = d[\"metadata\"] as Record<string, unknown>;\n const keys = Object.keys(m).slice(0, 2);\n if (keys.length > 0) meta = keys.map((k) => `${k}=${m[k]}`).join(\" \");\n }\n return {\n step: String(d[\"operation\"]),\n adapter,\n exchange,\n duration,\n meta,\n };\n }\n\n // Exchange events\n if (\"routeId\" in d && \"exchangeId\" in d) {\n const qualifier =\n \"error\" in d\n ? \"(err)\"\n : \"reason\" in d\n ? `(${String(d[\"reason\"]).slice(0, 8)})`\n : \"\";\n return {\n step: String(d[\"routeId\"]),\n adapter: qualifier,\n exchange,\n duration,\n meta: \"\",\n };\n }\n\n // Route lifecycle events\n if (\"route\" in d && typeof d[\"route\"] === \"object\" && d[\"route\"] !== null) {\n const route = d[\"route\"] as {\n routeId?: string;\n definition?: { id?: string };\n };\n return {\n step: route.routeId ?? route.definition?.id ?? \"?\",\n adapter: \"\",\n exchange: \"\",\n duration: \"\",\n meta: \"\",\n };\n }\n\n // Plugin events\n if (\"pluginId\" in d) {\n return {\n step: `plugin=${d[\"pluginId\"]}`,\n adapter: \"\",\n exchange: \"\",\n duration: \"\",\n meta: \"\",\n };\n }\n\n // Error events\n if (\"error\" in d) {\n const err = d[\"error\"];\n const msg =\n typeof err === \"object\" && err !== null && \"message\" in err\n ? String((err as { message: string }).message)\n : String(err);\n return {\n step: msg,\n adapter: \"\",\n exchange: \"\",\n duration: \"\",\n meta: \"\",\n };\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\nexport function formatDetails(_eventName: string, raw: string): string {\n const parsed = parseEventDetail(raw);\n if (!parsed) {\n return raw.length > 100 ? raw.slice(0, 97) + \"...\" : raw;\n }\n\n // Non-columnar events (plugin, route lifecycle, error) have no exchange/duration\n if (!parsed.exchange && !parsed.duration && !parsed.adapter) {\n return parsed.step;\n }\n\n return [\n col(parsed.step, DET.COL1),\n col(parsed.adapter, DET.COL2),\n col(parsed.exchange, DET.EX),\n col(parsed.duration, DET.DUR),\n parsed.meta,\n ]\n .join(\" \")\n .trimEnd();\n}\n\n/**\n * Structured version of formatDetails that returns individual columns\n * so the component can control alignment per-column.\n */\nexport function formatDetailColumns(\n _eventName: string,\n raw: string,\n): DetailColumns {\n const parsed = parseEventDetail(raw);\n if (!parsed) {\n return { step: raw, adapter: \"\", exchange: \"\", duration: \"\", meta: \"\" };\n }\n return parsed;\n}\n\n/**\n * Render a single-line sparkline from an array of values.\n * Uses Unicode block characters (▁▂▃▄▅▆▇█).\n * Empty/zero-only input returns spaces of the same length.\n */\nexport function sparkline(values: number[]): string {\n if (values.length === 0) return \"\";\n const blocks = [\n \" \",\n \"\\u2581\",\n \"\\u2582\",\n \"\\u2583\",\n \"\\u2584\",\n \"\\u2585\",\n \"\\u2586\",\n \"\\u2587\",\n \"\\u2588\",\n ];\n const max = Math.max(...values, 1);\n return values\n .map((v) => {\n const idx = Math.max(0, Math.min(8, Math.round((v / max) * 8)));\n return blocks[Number.isFinite(idx) ? idx : 0];\n })\n .join(\"\");\n}\n\nexport function fmtNum(n: number): string {\n return n.toLocaleString(\"en-US\");\n}\n\n/**\n * Adjust scroll offset so the selected item stays visible without centering.\n * The cursor moves freely within the visible window; the list only scrolls\n * when the cursor hits the top or bottom edge.\n *\n * @param selected - New selected index\n * @param currentOffset - Current scroll offset (tracked as state by the caller)\n * @param visibleRows - Number of rows visible in the list\n * @returns Updated scroll offset\n */\nexport function adjustScrollOffset(\n selected: number,\n currentOffset: number,\n visibleRows: number,\n): number {\n if (visibleRows <= 0) return currentOffset;\n if (selected < currentOffset) return selected;\n if (selected >= currentOffset + visibleRows)\n return selected - visibleRows + 1;\n return currentOffset;\n}\n","import { useState, useCallback } from \"react\";\nimport { adjustScrollOffset } from \"../utils.js\";\n\nexport interface ScrollListState {\n selectedIndex: number;\n scrollOffset: number;\n /** Move selection by delta (positive = down, negative = up). */\n moveBy: (delta: number, listLength: number, visibleRows: number) => void;\n /** Jump to an absolute index. */\n moveTo: (index: number, listLength: number, visibleRows: number) => void;\n /** Reset selection and scroll to the beginning. */\n reset: () => void;\n}\n\n/**\n * Manages a paired (selectedIndex, scrollOffset) state for scrollable lists.\n * Keeps the selected item visible without centering.\n *\n * `listLength` and `visibleRows` are passed at call time (not stored)\n * because they change every render (terminal resize, data load).\n */\nexport function useScrollList(initialIndex = 0): ScrollListState {\n const [selectedIndex, setSelectedIndex] = useState(initialIndex);\n const [scrollOffset, setScrollOffset] = useState(0);\n\n const moveTo = useCallback(\n (index: number, listLength: number, visibleRows: number) => {\n const clamped = Math.max(0, Math.min(index, listLength - 1));\n setSelectedIndex(clamped);\n setScrollOffset((off) => adjustScrollOffset(clamped, off, visibleRows));\n },\n [],\n );\n\n const moveBy = useCallback(\n (delta: number, listLength: number, visibleRows: number) => {\n setSelectedIndex((prev) => {\n const next = Math.max(0, Math.min(prev + delta, listLength - 1));\n setScrollOffset((off) => adjustScrollOffset(next, off, visibleRows));\n return next;\n });\n },\n [],\n );\n\n const reset = useCallback(() => {\n setSelectedIndex(0);\n setScrollOffset(0);\n }, []);\n\n return { selectedIndex, scrollOffset, moveBy, moveTo, reset };\n}\n","import type { ReactNode } from \"react\";\nimport { Box, Text } from \"ink\";\n\nexport function Panel({\n title,\n subtitle,\n color = \"gray\",\n width,\n flexGrow,\n paddingX = 1,\n children,\n}: {\n title?: string;\n subtitle?: ReactNode;\n color?: string;\n width?: number;\n flexGrow?: number;\n paddingX?: number;\n children: ReactNode;\n}) {\n // Border adds 2 chars per side; padding adds paddingX per side\n const innerWidth = width ? width - 2 - paddingX * 2 : 20;\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={color}\n paddingX={paddingX}\n width={width}\n flexGrow={flexGrow}\n >\n {title && (\n <>\n <Text bold>\n {title}\n {subtitle && <> {subtitle}</>}\n </Text>\n <Text dimColor>{\"\\u2500\".repeat(Math.max(innerWidth, 1))}</Text>\n </>\n )}\n {children}\n </Box>\n );\n}\n","import type { JSX } from \"react\";\nimport { Text } from \"ink\";\n\n/**\n * Braille layout: 1 bucket per character, both columns.\n *\n * Left Right\n * 0x01 0x08 sub-row 0 (top)\n * 0x02 0x10 sub-row 1\n * 0x04 0x20 sub-row 2\n * 0x40 0x80 sub-row 3 (bottom)\n *\n * Each terminal character represents 1 time bucket.\n * Both columns mirror the same data for btop-style dot density.\n * Each terminal row packs up to 4 step levels vertically.\n */\nconst BRAILLE_DOTS = [\n 0x40 | 0x80,\n 0x04 | 0x20,\n 0x02 | 0x10,\n 0x01 | 0x08,\n] as const; // bottom to top\nconst BRAILLE_BASE = 0x2800;\n\nexport interface DotStep {\n max: number;\n color: string;\n}\n\n/** Default 5-step config: gray baseline, green low, yellow mid, red high. */\nexport const DEFAULT_STEPS: DotStep[] = [\n { max: 0, color: \"gray\" },\n { max: 10, color: \"green\" },\n { max: 20, color: \"green\" },\n { max: 30, color: \"yellow\" },\n { max: 40, color: \"yellow\" },\n { max: 50, color: \"red\" },\n];\n\n/**\n * Stacked dot graph using braille characters.\n *\n * 1 bucket = 1 terminal character. Both braille columns mirror the same\n * data for btop-style dot density. Each character can stack up to 4 step\n * levels vertically.\n *\n * - 0 exchanges: gray baseline dot (bottom)\n * - 1-9 exchanges: green dot (bottom)\n * - 10-19 exchanges: two green dots stacked\n * - etc., stacking upward with per-level colors\n */\nexport function DotGraph({\n values,\n columns,\n steps = DEFAULT_STEPS,\n label,\n}: {\n values: number[];\n columns: number;\n steps?: DotStep[];\n label?: string;\n}) {\n const dotHeight = steps.length - 1;\n\n // Right-align: newest on right, pad left with zeros\n const data =\n values.length >= columns\n ? values.slice(values.length - columns)\n : [\n ...(new Array(columns - values.length).fill(0) as number[]),\n ...values,\n ];\n\n // Map each value to a step index (0 = baseline, 1..dotHeight)\n const heights = data.map((v) => {\n if (v <= 0) return 0;\n for (let i = 1; i < steps.length; i++) {\n if (v < steps[i]!.max) return i;\n }\n return dotHeight;\n });\n\n const termRows = Math.ceil(dotHeight / 4);\n\n // Build terminal rows from top to bottom\n const rows: JSX.Element[] = [];\n for (let tr = termRows - 1; tr >= 0; tr--) {\n const baseStep = tr * 4;\n\n // For each bucket, compute the braille bits and color for this terminal row\n const segments: { text: string; color: string }[] = [];\n\n for (let ci = 0; ci < data.length; ci++) {\n const h = heights[ci]!;\n let bits = 0;\n let color = \"\";\n\n for (let sr = 0; sr < 4; sr++) {\n const stepLevel = baseStep + sr + 1;\n if (stepLevel > dotHeight) break;\n\n // Show dot if height reaches this level, or baseline dot for zero values\n const on = h >= stepLevel || (h === 0 && stepLevel === 1);\n if (on) {\n bits |= BRAILLE_DOTS[sr]!;\n // Color: gray for baseline (zero), step color for data\n color = h === 0 ? steps[0]!.color : steps[stepLevel]!.color;\n }\n }\n\n const char = String.fromCharCode(BRAILLE_BASE + bits);\n const last = segments[segments.length - 1];\n if (last && last.color === color) {\n last.text += char;\n } else {\n segments.push({ text: char, color });\n }\n }\n\n rows.push(\n <Text key={tr}>\n {segments.map((s, i) =>\n s.color ? (\n <Text key={i} color={s.color}>\n {s.text}\n </Text>\n ) : (\n <Text key={i}>{s.text}</Text>\n ),\n )}\n </Text>,\n );\n }\n\n return (\n <>\n {rows}\n {label && <Text dimColor>{label}</Text>}\n </>\n );\n}\n","import { Text } from \"ink\";\nimport type { RouteSummary } from \"../types.js\";\nimport { statusColor, fmtNum, formatDuration } from \"../utils.js\";\n\nexport function RouteHeader({ route }: { route: RouteSummary }) {\n return (\n <>\n <Text>\n Capability:{\" \"}\n <Text bold color=\"cyan\">\n {route.id}\n </Text>\n </Text>\n <Text>\n Status:{\" \"}\n <Text bold color={statusColor(route.status)}>\n {route.status}\n </Text>\n {\" \"}Exchanges: <Text bold>{fmtNum(route.totalExchanges)}</Text>\n {\" \"}Errors:{\" \"}\n <Text\n bold\n {...(route.failedExchanges > 0 ? { color: \"red\" as const } : {})}\n >\n {fmtNum(route.failedExchanges)}\n </Text>\n {\" \"}Dropped:{\" \"}\n <Text\n bold\n {...(route.droppedExchanges > 0 ? { color: \"yellow\" as const } : {})}\n >\n {fmtNum(route.droppedExchanges)}\n </Text>\n {\" \"}Avg: <Text bold>{formatDuration(route.avgDurationMs)}</Text>\n </Text>\n </>\n );\n}\n","import { Fragment, type ReactNode } from \"react\";\nimport { Box, Text } from \"ink\";\nimport { col } from \"../utils.js\";\n\nexport interface ColumnDef<T> {\n /** Header label */\n header: string;\n /** Fixed character width, or \"flex\" to fill remaining space */\n width: number | \"flex\";\n /** Text alignment. Default: \"left\" */\n align?: \"left\" | \"right\";\n /** Render cell content. `colWidth` is the resolved width for fixed columns, undefined for flex. */\n render: (\n row: T,\n selected: boolean,\n colWidth: number | undefined,\n ) => ReactNode;\n}\n\nexport interface TableProps<T> {\n columns: ColumnDef<T>[];\n data: T[];\n /** Unique key for each row */\n rowKey: (row: T, index: number) => string;\n /** Selected row index in full data array, or -1/undefined for no selection */\n selectedIndex?: number;\n /** First visible row (scroll offset) */\n scrollOffset: number;\n /** Number of visible rows */\n visibleRows: number;\n /** Gap between columns in characters. Default: 2 */\n gap?: number;\n /** Message when data is empty */\n emptyMessage?: string;\n /**\n * Optional full-row override for special rows (e.g., group headers).\n * Return undefined to use normal column rendering.\n */\n renderFullRow?: (row: T, index: number) => ReactNode | undefined;\n}\n\nexport function Table<T>({\n columns,\n data,\n rowKey,\n selectedIndex,\n scrollOffset,\n visibleRows,\n gap = 2,\n emptyMessage = \"No data\",\n renderFullRow,\n}: TableProps<T>) {\n const gapStr = \" \".repeat(gap);\n\n // Header\n const header = (\n <Box>\n {columns.map((c, ci) => {\n const isLast = ci === columns.length - 1;\n const after = isLast ? \"\" : gapStr;\n\n if (c.width === \"flex\") {\n return (\n <Fragment key={ci}>\n <Box flexGrow={1}>\n <Text bold dimColor>\n {c.header}\n </Text>\n </Box>\n {after && <Text>{after}</Text>}\n </Fragment>\n );\n }\n\n const text =\n c.align === \"right\"\n ? c.header.padStart(c.width)\n : col(c.header, c.width);\n\n return (\n <Fragment key={ci}>\n <Text bold dimColor>\n {text}\n </Text>\n {after && <Text>{after}</Text>}\n </Fragment>\n );\n })}\n </Box>\n );\n\n if (data.length === 0) {\n return (\n <>\n {header}\n <Text dimColor>{emptyMessage}</Text>\n </>\n );\n }\n\n const visible = data.slice(scrollOffset, scrollOffset + visibleRows);\n const remaining = data.length - scrollOffset - visibleRows;\n\n return (\n <>\n {header}\n {visible.map((row, vi) => {\n const dataIndex = scrollOffset + vi;\n const selected = dataIndex === selectedIndex;\n\n // Full-row override (e.g., group headers)\n const fullRow = renderFullRow?.(row, dataIndex);\n if (fullRow !== undefined) {\n return <Box key={rowKey(row, dataIndex)}>{fullRow}</Box>;\n }\n\n return (\n <Box key={rowKey(row, dataIndex)}>\n {columns.map((c, ci) => {\n const isLast = ci === columns.length - 1;\n const after = isLast ? \"\" : gapStr;\n const resolved = c.width === \"flex\" ? undefined : c.width;\n const cell = c.render(row, selected, resolved);\n\n if (c.width === \"flex\") {\n return (\n <Fragment key={ci}>\n <Box flexGrow={1}>\n <Text wrap=\"truncate\">{cell}</Text>\n </Box>\n {after && <Text>{after}</Text>}\n </Fragment>\n );\n }\n\n return (\n <Fragment key={ci}>\n {cell}\n {after && <Text>{after}</Text>}\n </Fragment>\n );\n })}\n </Box>\n );\n })}\n <Text dimColor>{remaining > 0 ? \"\\u2193 more\" : \" \"}</Text>\n </>\n );\n}\n","import { Text } from \"ink\";\nimport type { EventRecord } from \"../types.js\";\nimport { col, formatDetailColumns, type DetailColumns } from \"../utils.js\";\nimport type { ColumnDef } from \"./table.js\";\n\n/**\n * Build the 4 standard event detail columns (Step, Adapter, Exchange, Duration).\n *\n * The accessor extracts an EventRecord from whatever row type T the table uses.\n * Returns undefined when the row has no event data (e.g., group headers).\n *\n * JSON is parsed once per row and shared across all 4 columns via a WeakMap cache.\n */\nexport function eventDetailColumns<T>(\n accessor: (row: T) => EventRecord | undefined,\n): ColumnDef<T>[] {\n const cache = new WeakMap<EventRecord, DetailColumns>();\n\n function getColumns(row: T): DetailColumns | undefined {\n const ev = accessor(row);\n if (!ev) return undefined;\n let cols = cache.get(ev);\n if (!cols) {\n cols = formatDetailColumns(ev.eventName, ev.details);\n cache.set(ev, cols);\n }\n return cols;\n }\n\n return [\n {\n header: \"Step\",\n width: 10,\n render: (row, _sel, w) => {\n const cols = getColumns(row);\n if (!cols) return <Text>{col(\"\", w)}</Text>;\n return <Text>{col(cols.step, w)}</Text>;\n },\n },\n {\n header: \"Adapter\",\n width: 10,\n render: (row, _sel, w) => {\n const cols = getColumns(row);\n if (!cols) return <Text>{col(\"\", w)}</Text>;\n return <Text>{col(cols.adapter, w)}</Text>;\n },\n },\n {\n header: \"Exchange\",\n width: 12,\n render: (row, _sel, w) => {\n const cols = getColumns(row);\n if (!cols) return <Text>{col(\"\", w)}</Text>;\n return <Text>{col(cols.exchange, w)}</Text>;\n },\n },\n {\n header: \"Duration\",\n width: 8,\n align: \"right\" as const,\n render: (row) => {\n const cols = getColumns(row);\n if (!cols) return <Text>{\"\"}</Text>;\n return <Text>{cols.duration.padStart(8)}</Text>;\n },\n },\n ];\n}\n\n/**\n * Selector column that shows \"> \" for the selected row.\n */\nexport function selectorColumn<T>(): ColumnDef<T> {\n return {\n header: \"\",\n width: 2,\n render: (_row, selected) => (\n <Text {...(selected ? { color: \"cyan\" as const } : {})} bold={selected}>\n {selected ? \"> \" : \" \"}\n </Text>\n ),\n };\n}\n","import { Box, Text } from \"ink\";\nimport type { ExchangeRecord, RouteSummary, RouteActivity } from \"../types.js\";\nimport { statusColor, formatDuration, col } from \"../utils.js\";\nimport { PANEL_TABLE_CHROME } from \"../layout.js\";\nimport { Panel } from \"./panel.js\";\nimport { RouteHeader } from \"./route-header.js\";\nimport { DotGraph, DEFAULT_STEPS } from \"./dot-graph.js\";\nimport { Table, type ColumnDef } from \"./table.js\";\nimport { selectorColumn } from \"./event-columns.js\";\n\nconst exchangeColumns: ColumnDef<ExchangeRecord>[] = [\n selectorColumn<ExchangeRecord>(),\n {\n header: \"ID\",\n width: \"flex\",\n render: (row, selected) => (\n <Text {...(selected ? { color: \"cyan\" as const } : {})} bold={selected}>\n {row.id}\n </Text>\n ),\n },\n {\n header: \"Status\",\n width: 9,\n render: (row, _sel, w) => (\n <Text color={statusColor(row.status)}>{col(row.status, w)}</Text>\n ),\n },\n {\n header: \"Duration\",\n width: 8,\n align: \"right\",\n render: (row) => <Text>{formatDuration(row.durationMs).padStart(8)}</Text>,\n },\n {\n header: \"Time\",\n width: 8,\n render: (row, _sel, w) => (\n <Text dimColor>\n {col(row.startedAt.replace(\"T\", \" \").slice(11, 19), w)}\n </Text>\n ),\n },\n];\n\nexport function CenterExchangeList({\n capabilityId,\n route,\n exchanges,\n selectedIndex,\n scrollOffset,\n width,\n height,\n color = \"gray\",\n activity,\n}: {\n capabilityId: string;\n route?: RouteSummary;\n exchanges: ExchangeRecord[];\n selectedIndex: number;\n scrollOffset: number;\n width: number;\n height: number;\n color?: string;\n activity?: RouteActivity | undefined;\n}) {\n const graphTermRows = Math.ceil((DEFAULT_STEPS.length - 1) / 4);\n const headerRows = route ? 2 + graphTermRows + 2 : 0;\n const tableRows = Math.max(height - PANEL_TABLE_CHROME - headerRows, 3);\n\n const title = route ? \"EXCHANGES\" : `EXCHANGES: ${capabilityId}`;\n\n return (\n <Box flexDirection=\"column\" width={width} flexGrow={1}>\n {route && (\n <Panel width={width}>\n <RouteHeader route={route} />\n <Text> </Text>\n <DotGraph\n values={activity ? activity.throughput : []}\n columns={width - 4}\n label=\"Exchanges per 5s bucket\"\n />\n </Panel>\n )}\n <Panel title={title} width={width} flexGrow={1} color={color}>\n <Table\n columns={exchangeColumns}\n data={exchanges}\n rowKey={(ex) => ex.id + ex.contextId}\n selectedIndex={selectedIndex}\n scrollOffset={scrollOffset}\n visibleRows={tableRows}\n emptyMessage=\"No exchanges\"\n />\n </Panel>\n </Box>\n );\n}\n","import { Text } from \"ink\";\n\n/** Token types for JSON syntax coloring. */\nexport type TokenType =\n | \"key\"\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"null\"\n | \"brace\";\n\nexport interface JsonToken {\n text: string;\n type: TokenType;\n}\n\n/**\n * Tokenize a single line of pretty-printed JSON into colored segments.\n * Handles: keys, string values, numbers, booleans, null, and structural chars.\n */\nexport function tokenizeLine(line: string): JsonToken[] {\n const tokens: JsonToken[] = [];\n const re =\n /(\"(?:[^\"\\\\]|\\\\.)*\")\\s*:|(\"(?:[^\"\\\\]|\\\\.)*\")|(-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)|(\\btrue\\b|\\bfalse\\b)|(\\bnull\\b)|([{}[\\],:])/g;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = re.exec(line)) !== null) {\n // Plain text before this match (whitespace / indent)\n if (match.index > lastIndex) {\n tokens.push({ text: line.slice(lastIndex, match.index), type: \"brace\" });\n }\n\n if (match[1] !== undefined) {\n // Key (the colon is part of the regex but we split it out)\n tokens.push({ text: match[1], type: \"key\" });\n tokens.push({ text: \":\", type: \"brace\" });\n } else if (match[2] !== undefined) {\n tokens.push({ text: match[2], type: \"string\" });\n } else if (match[3] !== undefined) {\n tokens.push({ text: match[3], type: \"number\" });\n } else if (match[4] !== undefined) {\n tokens.push({ text: match[4], type: \"boolean\" });\n } else if (match[5] !== undefined) {\n tokens.push({ text: match[5], type: \"null\" });\n } else if (match[6] !== undefined) {\n tokens.push({ text: match[6], type: \"brace\" });\n }\n\n lastIndex = match.index + match[0].length;\n }\n\n // Trailing text\n if (lastIndex < line.length) {\n tokens.push({ text: line.slice(lastIndex), type: \"brace\" });\n }\n\n return tokens;\n}\n\nexport const TOKEN_COLORS: Record<TokenType, string> = {\n key: \"cyan\",\n string: \"green\",\n number: \"yellow\",\n boolean: \"yellow\",\n null: \"red\",\n brace: \"gray\",\n};\n\n/**\n * Parse a JSON string into pretty-printed lines, truncating long lines.\n */\nexport function formatJson(raw: string, maxWidth: number): string[] {\n try {\n const parsed = JSON.parse(raw) as unknown;\n const pretty = JSON.stringify(parsed, null, 2);\n return pretty.split(\"\\n\").map((line) => {\n const clampedMax = Math.max(1, maxWidth);\n return line.length > clampedMax\n ? line.slice(0, Math.max(0, clampedMax - 1)) + \"\\u2026\"\n : line;\n });\n } catch {\n const clampedMax = Math.max(1, maxWidth);\n return raw\n .split(\"\\n\")\n .map((line) =>\n line.length > clampedMax\n ? line.slice(0, Math.max(0, clampedMax - 1)) + \"\\u2026\"\n : line,\n );\n }\n}\n\n/**\n * Render a single line of JSON with syntax coloring.\n */\nexport function ColoredJsonLine({ line }: { line: string }) {\n const tokens = tokenizeLine(line);\n if (tokens.length === 0) return <Text>{line}</Text>;\n return (\n <Text>\n {tokens.map((token, i) => (\n <Text key={i} color={TOKEN_COLORS[token.type]}>\n {token.text}\n </Text>\n ))}\n </Text>\n );\n}\n\n/**\n * Safely parse a JSON details string.\n */\nexport function parseDetails(raw: string): Record<string, unknown> | null {\n try {\n const parsed: unknown = JSON.parse(raw);\n if (\n typeof parsed !== \"object\" ||\n parsed === null ||\n Array.isArray(parsed)\n ) {\n return null;\n }\n return parsed as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n","import { Box, Text } from \"ink\";\nimport type { ExchangeRecord, EventRecord } from \"../types.js\";\nimport { statusColor, formatDuration, col, truncate } from \"../utils.js\";\nimport { DETAIL_INFO_CHROME } from \"../layout.js\";\nimport { Panel } from \"./panel.js\";\nimport { Table, type ColumnDef } from \"./table.js\";\nimport { selectorColumn, eventDetailColumns } from \"./event-columns.js\";\nimport { parseDetails } from \"./json-format.js\";\n\ntype DisplayRow = {\n type: \"header\" | \"event\";\n text?: string;\n event?: EventRecord;\n indent: number;\n};\n\n/**\n * Group events by exchangeId to show parent/child flow.\n */\nfunction groupEventsByExchange(\n events: EventRecord[],\n parentExchangeId: string,\n): { exchangeId: string; label: string; events: EventRecord[] }[] {\n const groups = new Map<\n string,\n { exchangeId: string; label: string; events: EventRecord[] }\n >();\n let childIndex = 0;\n\n groups.set(parentExchangeId, {\n exchangeId: parentExchangeId,\n label: \"parent\",\n events: [],\n });\n\n for (const ev of events) {\n const d = parseDetails(ev.details);\n const exId = d ? String(d[\"exchangeId\"] ?? \"\") : \"\";\n const key = !exId || exId === parentExchangeId ? parentExchangeId : exId;\n\n if (!groups.has(key)) {\n childIndex++;\n groups.set(key, {\n exchangeId: key,\n label: `child ${childIndex}`,\n events: [],\n });\n }\n groups.get(key)!.events.push(ev);\n }\n\n return Array.from(groups.values());\n}\n\nconst detailColumns: ColumnDef<DisplayRow>[] = [\n selectorColumn<DisplayRow>(),\n {\n header: \"Time\",\n width: 8,\n render: (row, _sel, w) => {\n if (!row.event) return <Text>{col(\"\", w)}</Text>;\n const indent = \" \".repeat(row.indent);\n return (\n <Text dimColor>\n {indent}\n {row.event.timestamp.replace(\"T\", \" \").slice(11, 19)}\n </Text>\n );\n },\n },\n {\n header: \"Event\",\n width: \"flex\",\n render: (row) => {\n if (!row.event) return <Text />;\n return <Text color=\"cyan\">{row.event.eventName}</Text>;\n },\n },\n ...eventDetailColumns<DisplayRow>((row) => row.event),\n];\n\nexport function CenterExchangeDetail({\n exchange,\n events,\n width,\n height,\n scrollOffset,\n selectedIndex = -1,\n color = \"gray\",\n}: {\n exchange: ExchangeRecord;\n events: EventRecord[];\n width: number;\n height: number;\n scrollOffset: number;\n selectedIndex?: number;\n color?: string;\n}) {\n const hasExtra = exchange.error ? 2 : 0;\n const eventRows = Math.max(height - DETAIL_INFO_CHROME - hasExtra, 3);\n\n const groups = groupEventsByExchange(events, exchange.id);\n const hasChildren = groups.length > 1;\n\n const displayRows: DisplayRow[] = [];\n for (const group of groups) {\n if (hasChildren) {\n displayRows.push({\n type: \"header\",\n text: `${group.label} (${group.exchangeId.slice(0, 8)}) - ${group.events.length} events`,\n indent: 0,\n });\n }\n for (const ev of group.events) {\n displayRows.push({\n type: \"event\",\n event: ev,\n indent: hasChildren ? 2 : 0,\n });\n }\n }\n\n const eventsTitle = hasChildren\n ? `EXCHANGE FLOW (${groups.length} exchanges, ${events.length} events)`\n : `RELATED EVENTS (${events.length})`;\n\n return (\n <Box flexDirection=\"column\" width={width} flexGrow={1}>\n <Panel width={width}>\n <Text>\n Capability:{\" \"}\n <Text bold color=\"cyan\">\n {exchange.routeId}\n </Text>\n </Text>\n <Text>\n Exchange:{\" \"}\n <Text bold color=\"cyan\">\n {truncate(exchange.id, width - 14)}\n </Text>\n </Text>\n <Text>\n Status:{\" \"}\n <Text bold color={statusColor(exchange.status)}>\n {exchange.status}\n </Text>\n {exchange.durationMs !== null && (\n <Text>\n {\" \"}Duration:{\" \"}\n <Text bold>{formatDuration(exchange.durationMs)}</Text>\n </Text>\n )}\n {\" \"}Started: <Text bold>{exchange.startedAt}</Text>\n {exchange.completedAt && (\n <Text>\n {\" \"}Completed: <Text bold>{exchange.completedAt}</Text>\n </Text>\n )}\n </Text>\n {exchange.error && exchange.status === \"failed\" && (\n <>\n <Text> </Text>\n <Text color=\"red\">Error: {exchange.error}</Text>\n </>\n )}\n {exchange.error && exchange.status === \"dropped\" && (\n <>\n <Text> </Text>\n <Text color=\"yellow\">Reason: {exchange.error}</Text>\n </>\n )}\n </Panel>\n\n <Panel title={eventsTitle} width={width} flexGrow={1} color={color}>\n <Table\n columns={detailColumns}\n data={displayRows}\n rowKey={(row, i) =>\n row.type === \"header\"\n ? `h-${i}`\n : `${row.event?.id ?? row.event?.timestamp}-${i}`\n }\n selectedIndex={selectedIndex}\n scrollOffset={scrollOffset}\n visibleRows={eventRows}\n emptyMessage=\"No related events found\"\n renderFullRow={(row) =>\n row.type === \"header\" ? (\n <Text bold color=\"yellow\">\n {row.text}\n </Text>\n ) : undefined\n }\n />\n </Panel>\n </Box>\n );\n}\n","import { Text } from \"ink\";\nimport type { EventRecord } from \"../types.js\";\nimport { col } from \"../utils.js\";\nimport { PANEL_TABLE_CHROME } from \"../layout.js\";\nimport { Panel } from \"./panel.js\";\nimport { Table, type ColumnDef } from \"./table.js\";\nimport { selectorColumn, eventDetailColumns } from \"./event-columns.js\";\n\nconst eventColumns: ColumnDef<EventRecord>[] = [\n selectorColumn<EventRecord>(),\n {\n header: \"Time\",\n width: 19,\n render: (row, selected, w) => (\n <Text {...(selected ? { color: \"cyan\" as const } : {})} bold={selected}>\n {col(row.timestamp.replace(\"T\", \" \").slice(0, 19), w)}\n </Text>\n ),\n },\n {\n header: \"Event\",\n width: \"flex\",\n render: (row) => <Text color=\"cyan\">{row.eventName}</Text>,\n },\n ...eventDetailColumns<EventRecord>((row) => row),\n];\n\nexport function EventsView({\n events,\n selectedIndex,\n scrollOffset,\n width,\n height,\n color = \"gray\",\n}: {\n events: EventRecord[];\n selectedIndex: number;\n scrollOffset: number;\n width: number;\n height: number;\n color?: string;\n}) {\n const tableRows = Math.max(height - PANEL_TABLE_CHROME, 5);\n\n return (\n <Panel\n title=\"EVENTS\"\n subtitle={<Text dimColor>({events.length} total)</Text>}\n width={width}\n flexGrow={1}\n color={color}\n >\n <Table\n columns={eventColumns}\n data={events}\n rowKey={(ev, i) =>\n ev.id !== undefined ? String(ev.id) : `${ev.timestamp}-${i}`\n }\n selectedIndex={selectedIndex}\n scrollOffset={scrollOffset}\n visibleRows={tableRows}\n emptyMessage=\"No events recorded yet.\"\n />\n </Panel>\n );\n}\n","import { Box, Text } from \"ink\";\nimport type { EventRecord } from \"../types.js\";\nimport { Panel } from \"./panel.js\";\nimport { formatJson, ColoredJsonLine, parseDetails } from \"./json-format.js\";\n\nexport function EventDetail({\n event,\n width,\n height,\n scrollOffset,\n color = \"cyan\",\n}: {\n event: EventRecord;\n width: number;\n height: number;\n scrollOffset: number;\n color?: string;\n}) {\n const d = parseDetails(event.details);\n const routeId =\n d && typeof d[\"routeId\"] === \"string\" ? d[\"routeId\"] : undefined;\n const exchangeId =\n d && typeof d[\"exchangeId\"] === \"string\" ? d[\"exchangeId\"] : undefined;\n\n // Header lines: context (always) + capability + exchange + event + time\n const headerLines = 1 + (routeId ? 1 : 0) + (exchangeId ? 1 : 0) + 2;\n // Top panel: border (2) + content lines\n const headerHeight = 2 + headerLines;\n // Bottom panel: border (2) + title/separator (2) + footer (1) = 5\n const jsonChrome = 5;\n const jsonWidth = Math.max(width - 6, 20);\n const jsonLines = formatJson(event.details, jsonWidth);\n const visibleRows = Math.max(height - headerHeight - jsonChrome, 3);\n const visible = jsonLines.slice(scrollOffset, scrollOffset + visibleRows);\n\n return (\n <Box flexDirection=\"column\" width={width} flexGrow={1}>\n <Panel width={width}>\n <Text>\n Context:{\" \"}\n <Text bold color=\"cyan\">\n {event.contextId}\n </Text>\n </Text>\n {routeId && (\n <Text>\n Capability:{\" \"}\n <Text bold color=\"cyan\">\n {routeId}\n </Text>\n </Text>\n )}\n {exchangeId && (\n <Text>\n Exchange:{\" \"}\n <Text bold color=\"cyan\">\n {exchangeId}\n </Text>\n </Text>\n )}\n <Text>\n Event:{\" \"}\n <Text bold color=\"cyan\">\n {event.eventName}\n </Text>\n </Text>\n <Text>\n Time: <Text bold>{event.timestamp.replace(\"T\", \" \")}</Text>\n </Text>\n </Panel>\n\n <Panel\n title=\"DETAILS\"\n subtitle={\n <Text dimColor>\n ({scrollOffset + 1}-\n {Math.min(scrollOffset + visibleRows, jsonLines.length)}/\n {jsonLines.length} lines)\n </Text>\n }\n width={width}\n flexGrow={1}\n color={color}\n >\n {visible.map((line, i) => (\n <ColoredJsonLine key={scrollOffset + i} line={line} />\n ))}\n {visible.length < visibleRows &&\n Array.from({ length: visibleRows - visible.length }).map((_, i) => (\n <Text key={`pad-${i}`}> </Text>\n ))}\n </Panel>\n </Box>\n );\n}\n","import { Box, Text } from \"ink\";\nimport type { ExchangeRecord, ExchangeSnapshot } from \"../types.js\";\nimport { statusColor, formatDuration, truncate } from \"../utils.js\";\nimport { Panel } from \"./panel.js\";\nimport { formatJson, ColoredJsonLine } from \"./json-format.js\";\n\n/**\n * Build the scrollable lines for the deep view: headers + body sections.\n */\nfunction buildSnapshotLines(\n snapshot: ExchangeSnapshot,\n maxWidth: number,\n): string[] {\n const lines: string[] = [];\n\n lines.push(\"HEADERS\");\n lines.push(...formatJson(snapshot.headers, maxWidth));\n lines.push(\"\");\n lines.push(\"BODY\");\n if (snapshot.body !== null) {\n lines.push(...formatJson(snapshot.body, maxWidth));\n if (snapshot.truncated) {\n lines.push(\"\");\n lines.push(\"[Body truncated to configured limit]\");\n }\n } else {\n lines.push(\"[null]\");\n }\n\n return lines;\n}\n\nexport function ExchangeDeepView({\n exchange,\n snapshot,\n width,\n height,\n scrollOffset,\n color = \"cyan\",\n}: {\n exchange: ExchangeRecord;\n snapshot: ExchangeSnapshot | null;\n width: number;\n height: number;\n scrollOffset: number;\n color?: string;\n}) {\n // Header panel: border (2) + content (3 lines: capability + exchange + status)\n const headerHeight = 5;\n // JSON panel chrome: border (2) + title (1) + separator (1) + footer (1)\n const jsonChrome = 5;\n const jsonWidth = Math.max(width - 6, 20);\n const visibleRows = Math.max(height - headerHeight - jsonChrome, 3);\n\n const hasSnapshot = snapshot !== null;\n const jsonLines = hasSnapshot\n ? buildSnapshotLines(snapshot, jsonWidth)\n : [\n \"[Snapshots not captured]\",\n \"\",\n \"Enable with:\",\n \" telemetry({ sqlite: { captureSnapshots: true } })\",\n ];\n\n const visible = jsonLines.slice(scrollOffset, scrollOffset + visibleRows);\n\n return (\n <Box flexDirection=\"column\" width={width} flexGrow={1}>\n <Panel width={width}>\n <Text>\n Capability:{\" \"}\n <Text bold color=\"cyan\">\n {exchange.routeId}\n </Text>\n </Text>\n <Text>\n Exchange:{\" \"}\n <Text bold color=\"cyan\">\n {truncate(exchange.id, width - 14)}\n </Text>\n </Text>\n <Text>\n Status:{\" \"}\n <Text bold color={statusColor(exchange.status)}>\n {exchange.status}\n </Text>\n {exchange.durationMs !== null && (\n <Text>\n {\" \"}Duration:{\" \"}\n <Text bold>{formatDuration(exchange.durationMs)}</Text>\n </Text>\n )}\n </Text>\n </Panel>\n\n <Panel\n title=\"EXCHANGE SNAPSHOT\"\n subtitle={\n <Text dimColor>\n ({scrollOffset + 1}-\n {Math.min(scrollOffset + visibleRows, jsonLines.length)}/\n {jsonLines.length} lines)\n </Text>\n }\n width={width}\n flexGrow={1}\n color={color}\n >\n {visible.map((line, i) => {\n if (line === \"HEADERS\" || line === \"BODY\") {\n return (\n <Text key={scrollOffset + i} bold color=\"yellow\">\n {line}\n </Text>\n );\n }\n if (line.startsWith(\"[\")) {\n return (\n <Text key={scrollOffset + i} dimColor>\n {line}\n </Text>\n );\n }\n return <ColoredJsonLine key={scrollOffset + i} line={line} />;\n })}\n {visible.length < visibleRows &&\n Array.from({ length: visibleRows - visible.length }).map((_, i) => (\n <Text key={`pad-${i}`}> </Text>\n ))}\n </Panel>\n </Box>\n );\n}\n","import { Text } from \"ink\";\nimport type { RouteSummary } from \"../types.js\";\nimport { truncate } from \"../utils.js\";\n\nfunction dotColor(route: RouteSummary): string {\n if (route.failedExchanges > 0) return \"red\";\n if (route.totalExchanges > 0) return \"green\";\n return \"yellow\";\n}\n\nexport function CapabilityList({\n routes,\n selectedIndex,\n listOffset,\n visibleRows,\n width,\n}: {\n routes: RouteSummary[];\n selectedIndex: number;\n listOffset: number;\n visibleRows: number;\n width: number;\n}) {\n const offset = listOffset;\n\n return (\n <>\n <Text> </Text>\n <Text bold dimColor>\n {\"\\u2500\".repeat(width + 2)}\n </Text>\n {routes.length === 0 ? (\n <Text dimColor>No capabilities</Text>\n ) : (\n routes.slice(offset, offset + visibleRows).map((route, vi) => {\n const i = offset + vi;\n return (\n <Text key={route.id} wrap=\"truncate\">\n <Text\n {...(i === selectedIndex ? { color: \"cyan\" as const } : {})}\n bold={i === selectedIndex}\n >\n {i === selectedIndex ? \"> \" : \" \"}\n </Text>\n <Text color={dotColor(route)}>{\"\\u25CF \"}</Text>\n <Text\n {...(i === selectedIndex ? { color: \"cyan\" as const } : {})}\n bold={i === selectedIndex}\n >\n {truncate(route.id, width - 2)}\n </Text>\n </Text>\n );\n })\n )}\n {routes.length > visibleRows && (\n <Text dimColor>\n {selectedIndex + 1}/{routes.length}\n </Text>\n )}\n </>\n );\n}\n","import { useState, useEffect, useCallback } from \"react\";\nimport { render, Box, Text, useInput, useApp, useStdout } from \"ink\";\nimport { TelemetryDb } from \"./db.js\";\nimport type {\n NavItem,\n RouteSummary,\n ExchangeRecord,\n ExchangeSnapshot,\n EventRecord,\n Metrics,\n RouteActivity,\n} from \"./types.js\";\nimport { NAV_SECTIONS, ALL_NAV_ITEMS } from \"./types.js\";\nimport { fmtNum, formatDuration } from \"./utils.js\";\nimport { useScrollList } from \"./hooks/use-scroll-list.js\";\nimport { PANEL_TABLE_CHROME, DETAIL_INFO_CHROME, NAV_JUMP } from \"./layout.js\";\nimport { Panel } from \"./components/panel.js\";\nimport { DotGraph, DEFAULT_STEPS } from \"./components/dot-graph.js\";\nimport { CenterExchangeList } from \"./components/center-exchange-list.js\";\nimport { CenterExchangeDetail } from \"./components/center-exchange-detail.js\";\nimport { EventsView } from \"./components/events-view.js\";\nimport { EventDetail } from \"./components/event-detail.js\";\nimport { ExchangeDeepView } from \"./components/exchange-deep-view.js\";\nimport { CapabilityList } from \"./components/capability-list.js\";\nimport { version } from \"../../package.json\";\n\n/**\n * Focus tracks which panel owns the cursor.\n * - \"nav\": left panel (route list / nav items)\n * - \"center\": center panel (exchange list, events, detail)\n */\ntype Focus = \"nav\" | \"center\";\n\nfunction App({ db }: { db: TelemetryDb }) {\n const { exit } = useApp();\n const { stdout } = useStdout();\n const width = stdout?.columns ?? 80;\n const height = stdout?.rows ?? 24;\n\n const [activeNav, setActiveNav] = useState<NavItem>(\"capabilities\");\n const [focus, setFocus] = useState<Focus>(\"nav\");\n const [showDetail, setShowDetail] = useState(false);\n\n const [routes, setRoutes] = useState<RouteSummary[]>([]);\n const [metrics, setMetrics] = useState<Metrics>({\n totalRoutes: 0,\n totalExchanges: 0,\n completedExchanges: 0,\n failedExchanges: 0,\n droppedExchanges: 0,\n errorRate: 0,\n avgDurationMs: null,\n p90DurationMs: null,\n p95DurationMs: null,\n p99DurationMs: null,\n });\n const [liveTraffic, setLiveTraffic] = useState<number[]>([]);\n const [selectedRouteActivity, setSelectedRouteActivity] = useState<\n RouteActivity | undefined\n >(undefined);\n const routeScroll = useScrollList();\n const [exchanges, setExchanges] = useState<ExchangeRecord[]>([]);\n const exchangeScroll = useScrollList();\n const [selectedExchange, setSelectedExchange] = useState<\n ExchangeRecord | undefined\n >(undefined);\n const [exchangeEvents, setExchangeEvents] = useState<EventRecord[]>([]);\n const [events, setEvents] = useState<EventRecord[]>([]);\n const eventScroll = useScrollList();\n const detailScroll = useScrollList();\n const [selectedEvent, setSelectedEvent] = useState<EventRecord | undefined>(\n undefined,\n );\n const [showEventDetail, setShowEventDetail] = useState(false);\n const [eventDetailScroll, setEventDetailScroll] = useState(0);\n const [showDeepView, setShowDeepView] = useState(false);\n const [deepViewScroll, setDeepViewScroll] = useState(0);\n const [exchangeSnapshot, setExchangeSnapshot] =\n useState<ExchangeSnapshot | null>(null);\n const PAGE_SIZE = 50;\n const JUMP = NAV_JUMP;\n\n // Layout dimensions (needed by both refresh and render)\n const leftWidth = Math.max(Math.min(Math.floor(width * 0.18), 26), 16);\n const rightWidth = Math.max(Math.min(Math.floor(width * 0.22), 30), 20);\n const centerWidth = Math.max(width - leftWidth - rightWidth, 30);\n const bodyHeight = Math.max(height - 5, 10);\n const navHeaderRows = 10;\n const navListHeight = Math.max(bodyHeight - navHeaderRows, 3);\n\n const refresh = useCallback(() => {\n try {\n // Always refresh: routes, metrics, graphs\n const routeSummary = db.getRouteSummary();\n setRoutes(routeSummary);\n setMetrics(db.getMetrics());\n const liveCols = rightWidth - 4;\n setLiveTraffic(db.getLiveTrafficBuckets(liveCols, 5));\n\n // Only load activity for the currently selected route\n const routeCols = centerWidth - 4;\n const curRoute = routeSummary[routeScroll.selectedIndex];\n if (curRoute) {\n setSelectedRouteActivity(\n db.getSingleRouteActivity(curRoute.id, routeCols, 5),\n );\n }\n\n // Skip list refresh when cursor is active (user is browsing)\n if (focus === \"center\") return;\n\n if (activeNav === \"capabilities\") {\n const route = routeSummary[routeScroll.selectedIndex];\n if (route) {\n setExchanges(db.getExchangesByRoute(route.id, PAGE_SIZE));\n }\n } else if (activeNav === \"exchanges\") {\n setExchanges(db.getAllExchanges(PAGE_SIZE));\n } else if (activeNav === \"errors\") {\n setExchanges(db.getFailedExchanges(PAGE_SIZE));\n } else if (activeNav === \"events\") {\n setEvents(db.getRecentEvents({ limit: 200 }));\n }\n } catch {\n // Database may be temporarily locked\n }\n }, [\n db,\n activeNav,\n routeScroll.selectedIndex,\n rightWidth,\n centerWidth,\n focus,\n ]);\n\n useEffect(() => {\n refresh();\n const timer = setInterval(refresh, 2000);\n return () => {\n clearInterval(timer);\n };\n }, [refresh]);\n\n const selectRoute = useCallback(\n (index: number) => {\n routeScroll.moveTo(index, routes.length, navListHeight);\n exchangeScroll.reset();\n const route = routes[index];\n if (route) {\n setExchanges(db.getExchangesByRoute(route.id, PAGE_SIZE));\n }\n },\n [db, routes, routeScroll, exchangeScroll, navListHeight],\n );\n\n const switchNav = useCallback(\n (nav: NavItem) => {\n setActiveNav(nav);\n setShowDetail(false);\n setShowEventDetail(false);\n setShowDeepView(false);\n setFocus(\"nav\");\n exchangeScroll.reset();\n if (nav === \"exchanges\") {\n setExchanges(db.getAllExchanges(PAGE_SIZE));\n } else if (nav === \"errors\") {\n setExchanges(db.getFailedExchanges(PAGE_SIZE));\n } else if (nav === \"events\") {\n eventScroll.reset();\n setEvents(db.getRecentEvents({ limit: 200 }));\n }\n },\n [db, exchangeScroll, eventScroll],\n );\n\n const selectedRoute = routes[routeScroll.selectedIndex];\n\n // Visible row counts mirror the view components\n // Must match CenterExchangeList: 2 (capability + stats) + graphTermRows + 2 (label + spacer)\n const graphTermRows = Math.ceil((DEFAULT_STEPS.length - 1) / 4);\n const exchangeHeaderRows = selectedRoute ? 2 + graphTermRows + 2 : 0;\n const exchangeTableRows = Math.max(\n bodyHeight - PANEL_TABLE_CHROME - exchangeHeaderRows,\n 3,\n );\n const eventsTableRows = Math.max(bodyHeight - PANEL_TABLE_CHROME, 5);\n\n useInput((input, key) => {\n if (input === \"q\") {\n db.close();\n exit();\n return;\n }\n\n // Number shortcuts to switch nav (always available)\n const navByShortcut = ALL_NAV_ITEMS.find((n) => n.shortcut === input);\n if (navByShortcut) {\n switchNav(navByShortcut.key);\n return;\n }\n\n // Events view: overview -> browse -> detail\n if (activeNav === \"events\") {\n if (showEventDetail) {\n // Detail view: scroll JSON, Esc to go back to list\n const step = key.ctrl ? JUMP : 1;\n if (input === \"j\" || key.downArrow) {\n setEventDetailScroll((i) => i + step);\n } else if (input === \"k\" || key.upArrow) {\n setEventDetailScroll((i) => Math.max(i - step, 0));\n } else if (key.escape || key.backspace || key.delete) {\n setShowEventDetail(false);\n setEventDetailScroll(0);\n }\n return;\n }\n if (focus === \"nav\") {\n if (key.return) {\n setFocus(\"center\");\n }\n } else {\n const step = key.ctrl ? JUMP : 1;\n if (input === \"j\" || key.downArrow) {\n eventScroll.moveBy(step, events.length, eventsTableRows);\n } else if (input === \"k\" || key.upArrow) {\n eventScroll.moveBy(-step, events.length, eventsTableRows);\n } else if (key.return) {\n const ev = events[eventScroll.selectedIndex];\n if (ev) {\n setSelectedEvent(ev);\n setEventDetailScroll(0);\n setShowEventDetail(true);\n }\n } else if (key.escape || key.backspace || key.delete) {\n setFocus(\"nav\");\n eventScroll.reset();\n }\n }\n return;\n }\n\n // Exchange deep view: scrollable JSON of headers + body\n if (showDeepView) {\n const step = key.ctrl ? JUMP : 1;\n if (input === \"j\" || key.downArrow) {\n setDeepViewScroll((i) => i + step);\n } else if (input === \"k\" || key.upArrow) {\n setDeepViewScroll((i) => Math.max(i - step, 0));\n } else if (key.escape || key.backspace || key.delete) {\n setShowDeepView(false);\n setDeepViewScroll(0);\n }\n return;\n }\n\n // Exchange detail (any nav)\n if (showDetail && !showEventDetail) {\n const hasExtra = selectedExchange?.error ? 2 : 0;\n const detailEventRows = Math.max(\n bodyHeight - DETAIL_INFO_CHROME - hasExtra,\n 3,\n );\n // Count group headers: when events span multiple exchanges, each group gets a header row\n const uniqueExchangeIds = new Set(\n exchangeEvents.map((ev) => {\n try {\n const d = JSON.parse(ev.details) as Record<string, unknown>;\n return String(d[\"exchangeId\"] ?? \"\");\n } catch {\n return \"\";\n }\n }),\n );\n const groupCount = Math.max(uniqueExchangeIds.size, 1);\n const headerRows = groupCount > 1 ? groupCount : 0;\n const totalDisplayRows = exchangeEvents.length + headerRows;\n const step = key.ctrl ? JUMP : 1;\n if (input === \"j\" || key.downArrow) {\n detailScroll.moveBy(step, totalDisplayRows, detailEventRows);\n } else if (input === \"k\" || key.upArrow) {\n detailScroll.moveBy(-step, totalDisplayRows, detailEventRows);\n } else if (key.return) {\n // Resolve the selected display row to an EventRecord (skip headers)\n // Build the same display row list the component builds\n let rowIndex = 0;\n let targetEvent: EventRecord | undefined;\n const parentId = selectedExchange?.id ?? \"\";\n const groups = new Map<string, EventRecord[]>();\n groups.set(parentId, []);\n for (const ev of exchangeEvents) {\n try {\n const d = JSON.parse(ev.details) as Record<string, unknown>;\n const exId = String(d[\"exchangeId\"] ?? \"\");\n const gKey = !exId || exId === parentId ? parentId : exId;\n if (!groups.has(gKey)) groups.set(gKey, []);\n groups.get(gKey)!.push(ev);\n } catch {\n groups.get(parentId)!.push(ev);\n }\n }\n const hasChildren = groups.size > 1;\n for (const [, groupEvents] of groups) {\n if (hasChildren) rowIndex++; // header row\n for (const ev of groupEvents) {\n if (rowIndex === detailScroll.selectedIndex) {\n targetEvent = ev;\n }\n rowIndex++;\n }\n }\n if (targetEvent) {\n setSelectedEvent(targetEvent);\n setEventDetailScroll(0);\n setShowEventDetail(true);\n }\n } else if (input === \"e\" && selectedExchange) {\n const snapshot = db.getExchangeSnapshot(selectedExchange.id);\n setExchangeSnapshot(snapshot);\n setDeepViewScroll(0);\n setShowDeepView(true);\n } else if (key.escape || key.backspace || key.delete) {\n detailScroll.reset();\n setShowDetail(false);\n }\n return;\n }\n\n // Event detail from exchange detail: Esc goes back to exchange detail\n if (showDetail && showEventDetail) {\n const step = key.ctrl ? JUMP : 1;\n if (input === \"j\" || key.downArrow) {\n setEventDetailScroll((i) => i + step);\n } else if (input === \"k\" || key.upArrow) {\n setEventDetailScroll((i) => Math.max(i - step, 0));\n } else if (key.escape || key.backspace || key.delete) {\n setShowEventDetail(false);\n setEventDetailScroll(0);\n }\n return;\n }\n\n // Capabilities: nav focus (left panel)\n if (activeNav === \"capabilities\" && focus === \"nav\") {\n if (input === \"j\" || key.downArrow) {\n selectRoute(Math.min(routeScroll.selectedIndex + 1, routes.length - 1));\n } else if (input === \"k\" || key.upArrow) {\n selectRoute(Math.max(routeScroll.selectedIndex - 1, 0));\n } else if (key.return) {\n setFocus(\"center\");\n // Load all exchanges for browsing (auto-refresh uses PAGE_SIZE)\n const route = routes[routeScroll.selectedIndex];\n if (route) {\n setExchanges(db.getExchangesByRoute(route.id));\n }\n }\n return;\n }\n\n // Capabilities: center focus (exchange list)\n if (activeNav === \"capabilities\" && focus === \"center\") {\n const step = key.ctrl ? JUMP : 1;\n if (input === \"j\" || key.downArrow) {\n exchangeScroll.moveBy(step, exchanges.length, exchangeTableRows);\n } else if (input === \"k\" || key.upArrow) {\n exchangeScroll.moveBy(-step, exchanges.length, exchangeTableRows);\n } else if (key.return) {\n const ex = exchanges[exchangeScroll.selectedIndex];\n if (ex) {\n setSelectedExchange(ex);\n setExchangeEvents(db.getEventsByExchange(ex.id, ex.correlationId));\n detailScroll.reset();\n setShowEventDetail(false);\n setShowDetail(true);\n }\n } else if (key.escape || key.backspace || key.delete) {\n setFocus(\"nav\");\n exchangeScroll.reset();\n }\n return;\n }\n\n // Exchanges / Errors: overview (nav focus) or browsing (center focus)\n if (activeNav === \"exchanges\" || activeNav === \"errors\") {\n if (focus === \"nav\") {\n // Overview mode: Enter to freeze and browse\n if (key.return) {\n setFocus(\"center\");\n // Load full data set for browsing\n if (activeNav === \"exchanges\") {\n setExchanges(db.getAllExchanges());\n } else {\n setExchanges(db.getFailedExchanges());\n }\n }\n } else {\n // Browsing mode: navigate with pointer\n const step = key.ctrl ? JUMP : 1;\n if (input === \"j\" || key.downArrow) {\n exchangeScroll.moveBy(step, exchanges.length, exchangeTableRows);\n } else if (input === \"k\" || key.upArrow) {\n exchangeScroll.moveBy(-step, exchanges.length, exchangeTableRows);\n } else if (key.return) {\n const ex = exchanges[exchangeScroll.selectedIndex];\n if (ex) {\n setSelectedExchange(ex);\n setExchangeEvents(db.getEventsByExchange(ex.id, ex.correlationId));\n detailScroll.reset();\n setShowEventDetail(false);\n setShowDetail(true);\n }\n } else if (key.escape || key.backspace || key.delete) {\n setFocus(\"nav\");\n exchangeScroll.reset();\n }\n }\n return;\n }\n });\n\n // Determine which panel is active for border highlighting\n const navActive =\n activeNav === \"capabilities\" && focus === \"nav\" && !showDetail;\n const centerActive = !navActive;\n\n // Keymap items based on context\n const keymapItems: { key: string; action: string }[] = [];\n if (showDeepView) {\n keymapItems.push({ key: \"j/k\", action: \"Scroll\" });\n keymapItems.push({ key: \"Ctrl+j/k\", action: \"Jump 10\" });\n keymapItems.push({ key: \"Esc\", action: \"Back\" });\n } else if (focus === \"center\") {\n keymapItems.push({ key: \"j/k\", action: \"Navigate\" });\n keymapItems.push({ key: \"Ctrl+j/k\", action: \"Jump 10\" });\n }\n if (!showDeepView) {\n if (focus === \"nav\") {\n if (activeNav === \"capabilities\") {\n keymapItems.push({ key: \"j/k\", action: \"Navigate\" });\n keymapItems.push({ key: \"Enter\", action: \"Exchanges\" });\n } else {\n keymapItems.push({ key: \"Enter\", action: \"Browse\" });\n }\n } else if (!showDetail && !showEventDetail) {\n keymapItems.push({ key: \"Enter\", action: \"Detail\" });\n keymapItems.push({ key: \"Esc\", action: \"Back\" });\n } else if (showDetail && !showEventDetail) {\n keymapItems.push({ key: \"Enter\", action: \"Event detail\" });\n keymapItems.push({ key: \"e\", action: \"Snapshot\" });\n keymapItems.push({ key: \"Esc\", action: \"Back\" });\n } else {\n keymapItems.push({ key: \"Esc\", action: \"Back\" });\n }\n }\n keymapItems.push({ key: \"1..4\", action: \"Switch view\" });\n keymapItems.push({ key: \"q\", action: \"Quit\" });\n\n return (\n <Box flexDirection=\"column\" width={width} height={height}>\n {/* Title bar */}\n <Box borderStyle=\"round\" borderColor=\"cyan\" paddingX={1} width={width}>\n <Text bold color=\"cyan\">\n ROUTECRAFT TUI\n </Text>\n <Text> </Text>\n <Text dimColor>v{version}</Text>\n </Box>\n\n {/* 3-column body */}\n <Box flexDirection=\"row\" width={width} flexGrow={1}>\n {/* Left column: Navigation (top) + Keymap (bottom) */}\n <Box flexDirection=\"column\" width={leftWidth}>\n <Panel\n title=\"NAVIGATION\"\n color={navActive ? \"cyan\" : \"gray\"}\n width={leftWidth}\n flexGrow={1}\n >\n {NAV_SECTIONS.map((section, si) => (\n <Box key={section.label ?? si} flexDirection=\"column\">\n {si > 0 && <Text> </Text>}\n {section.label && (\n <Text dimColor bold>\n {section.label}\n </Text>\n )}\n {section.items.map((item) => (\n <Text key={item.key}>\n <Text\n bold={activeNav === item.key}\n {...(activeNav === item.key\n ? { color: \"cyan\" as const }\n : {})}\n >\n {activeNav === item.key ? \"> \" : \" \"}\n {item.label}\n </Text>\n <Text dimColor> ({item.shortcut})</Text>\n </Text>\n ))}\n </Box>\n ))}\n\n {activeNav === \"capabilities\" && (\n <CapabilityList\n routes={routes}\n selectedIndex={routeScroll.selectedIndex}\n listOffset={routeScroll.scrollOffset}\n visibleRows={navListHeight}\n width={leftWidth - 6}\n />\n )}\n </Panel>\n </Box>\n\n {/* Center */}\n {activeNav === \"capabilities\" && !showDetail && (\n <CenterExchangeList\n capabilityId={selectedRoute?.id ?? \"\"}\n route={selectedRoute}\n exchanges={exchanges}\n selectedIndex={\n focus === \"center\" ? exchangeScroll.selectedIndex : -1\n }\n scrollOffset={focus === \"center\" ? exchangeScroll.scrollOffset : 0}\n width={centerWidth}\n height={bodyHeight}\n color={centerActive ? \"cyan\" : \"gray\"}\n activity={selectedRouteActivity}\n />\n )}\n {activeNav === \"capabilities\" && showDeepView && selectedExchange && (\n <ExchangeDeepView\n exchange={selectedExchange}\n snapshot={exchangeSnapshot}\n width={centerWidth}\n height={bodyHeight}\n scrollOffset={deepViewScroll}\n color=\"cyan\"\n />\n )}\n {activeNav === \"capabilities\" &&\n showDetail &&\n selectedExchange &&\n !showEventDetail &&\n !showDeepView && (\n <CenterExchangeDetail\n exchange={selectedExchange}\n events={exchangeEvents}\n width={centerWidth}\n height={bodyHeight}\n selectedIndex={detailScroll.selectedIndex}\n scrollOffset={detailScroll.scrollOffset}\n color=\"cyan\"\n />\n )}\n {activeNav === \"capabilities\" &&\n showDetail &&\n showEventDetail &&\n !showDeepView &&\n selectedEvent && (\n <EventDetail\n event={selectedEvent}\n width={centerWidth}\n height={bodyHeight}\n scrollOffset={eventDetailScroll}\n color=\"cyan\"\n />\n )}\n {activeNav === \"exchanges\" && !showDetail && (\n <CenterExchangeList\n capabilityId=\"All Capabilities\"\n exchanges={exchanges}\n selectedIndex={\n focus === \"center\" ? exchangeScroll.selectedIndex : -1\n }\n scrollOffset={focus === \"center\" ? exchangeScroll.scrollOffset : 0}\n width={centerWidth}\n height={bodyHeight}\n color={focus === \"center\" ? \"cyan\" : \"gray\"}\n />\n )}\n {activeNav === \"exchanges\" && showDeepView && selectedExchange && (\n <ExchangeDeepView\n exchange={selectedExchange}\n snapshot={exchangeSnapshot}\n width={centerWidth}\n height={bodyHeight}\n scrollOffset={deepViewScroll}\n color=\"cyan\"\n />\n )}\n {activeNav === \"exchanges\" &&\n showDetail &&\n selectedExchange &&\n !showEventDetail &&\n !showDeepView && (\n <CenterExchangeDetail\n exchange={selectedExchange}\n events={exchangeEvents}\n width={centerWidth}\n height={bodyHeight}\n selectedIndex={detailScroll.selectedIndex}\n scrollOffset={detailScroll.scrollOffset}\n color=\"cyan\"\n />\n )}\n {activeNav === \"exchanges\" &&\n showDetail &&\n showEventDetail &&\n !showDeepView &&\n selectedEvent && (\n <EventDetail\n event={selectedEvent}\n width={centerWidth}\n height={bodyHeight}\n scrollOffset={eventDetailScroll}\n color=\"cyan\"\n />\n )}\n {activeNav === \"errors\" && !showDetail && (\n <CenterExchangeList\n capabilityId=\"Failed Exchanges\"\n exchanges={exchanges}\n selectedIndex={\n focus === \"center\" ? exchangeScroll.selectedIndex : -1\n }\n scrollOffset={focus === \"center\" ? exchangeScroll.scrollOffset : 0}\n width={centerWidth}\n height={bodyHeight}\n color={focus === \"center\" ? \"cyan\" : \"gray\"}\n />\n )}\n {activeNav === \"errors\" && showDeepView && selectedExchange && (\n <ExchangeDeepView\n exchange={selectedExchange}\n snapshot={exchangeSnapshot}\n width={centerWidth}\n height={bodyHeight}\n scrollOffset={deepViewScroll}\n color=\"cyan\"\n />\n )}\n {activeNav === \"errors\" &&\n showDetail &&\n selectedExchange &&\n !showEventDetail &&\n !showDeepView && (\n <CenterExchangeDetail\n exchange={selectedExchange}\n events={exchangeEvents}\n width={centerWidth}\n height={bodyHeight}\n selectedIndex={detailScroll.selectedIndex}\n scrollOffset={detailScroll.scrollOffset}\n color=\"cyan\"\n />\n )}\n {activeNav === \"errors\" &&\n showDetail &&\n showEventDetail &&\n !showDeepView &&\n selectedEvent && (\n <EventDetail\n event={selectedEvent}\n width={centerWidth}\n height={bodyHeight}\n scrollOffset={eventDetailScroll}\n color=\"cyan\"\n />\n )}\n {activeNav === \"events\" && !showEventDetail && (\n <EventsView\n events={events}\n selectedIndex={focus === \"center\" ? eventScroll.selectedIndex : -1}\n scrollOffset={focus === \"center\" ? eventScroll.scrollOffset : 0}\n width={centerWidth}\n height={bodyHeight}\n color={focus === \"center\" ? \"cyan\" : \"gray\"}\n />\n )}\n {activeNav === \"events\" && showEventDetail && selectedEvent && (\n <EventDetail\n event={selectedEvent}\n width={centerWidth}\n height={bodyHeight}\n scrollOffset={eventDetailScroll}\n color=\"cyan\"\n />\n )}\n\n {/* Right: Metrics + Keymap */}\n <Box flexDirection=\"column\" width={rightWidth}>\n <Panel title=\"METRICS\" width={rightWidth} flexGrow={1}>\n <DotGraph\n values={liveTraffic}\n columns={rightWidth - 4}\n steps={[\n { max: 0, color: \"gray\" },\n ...(Array.from({ length: 7 }, (_, i) => ({\n max: (i + 1) * 5,\n color: \"green\",\n })) as { max: number; color: string }[]),\n ...(Array.from({ length: 7 }, (_, i) => ({\n max: 35 + (i + 1) * 10,\n color: \"yellow\",\n })) as { max: number; color: string }[]),\n ...(Array.from({ length: 6 }, (_, i) => ({\n max: 105 + (i + 1) * 25,\n color: \"red\",\n })) as { max: number; color: string }[]),\n ]}\n label=\"Exchanges per 5s bucket\"\n />\n <Text> </Text>\n <Text bold dimColor>\n THROUGHPUT\n </Text>\n {(\n [\n [\"Exchanges\", fmtNum(metrics.totalExchanges), \"cyan\"],\n [\"Completed\", fmtNum(metrics.completedExchanges), \"green\"],\n [\n \"Errors\",\n fmtNum(metrics.failedExchanges),\n metrics.failedExchanges > 0 ? \"red\" : \"green\",\n ],\n [\n \"Dropped\",\n fmtNum(metrics.droppedExchanges),\n metrics.droppedExchanges > 0 ? \"yellow\" : \"green\",\n ],\n [\n \"Error Rate\",\n `${(metrics.errorRate * 100).toFixed(1)}%`,\n metrics.errorRate > 0.1 ? \"red\" : \"green\",\n ],\n [\"Capabilities\", fmtNum(metrics.totalRoutes), \"\"],\n ] as [string, string, string][]\n ).map(([label, value, color]) => (\n <Box key={label}>\n <Text>{label}:</Text>\n <Box flexGrow={1} justifyContent=\"flex-end\">\n <Text bold {...(color ? { color } : {})}>\n {value}\n </Text>\n </Box>\n </Box>\n ))}\n <Text> </Text>\n <Text bold dimColor>\n LATENCY (5m)\n </Text>\n {(\n [\n [\"Avg\", formatDuration(metrics.avgDurationMs), \"\"],\n [\"p90\", formatDuration(metrics.p90DurationMs), \"\"],\n [\"p95\", formatDuration(metrics.p95DurationMs), \"\"],\n [\"p99\", formatDuration(metrics.p99DurationMs), \"\"],\n ] as [string, string, string][]\n ).map(([label, value, color]) => (\n <Box key={label}>\n <Text>{label}:</Text>\n <Box flexGrow={1} justifyContent=\"flex-end\">\n <Text bold {...(color ? { color } : {})}>\n {value}\n </Text>\n </Box>\n </Box>\n ))}\n </Panel>\n\n <Panel title=\"KEYMAP\" width={rightWidth}>\n {keymapItems.map((item) => (\n <Box key={item.key}>\n <Text>{item.action}</Text>\n <Box flexGrow={1} justifyContent=\"flex-end\">\n <Text color=\"yellow\">[{item.key}]</Text>\n </Box>\n </Box>\n ))}\n </Panel>\n </Box>\n </Box>\n </Box>\n );\n}\n\nexport async function renderTui(dbPath: string): Promise<void> {\n let db: TelemetryDb;\n try {\n db = await TelemetryDb.open(dbPath);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n process.stderr.write(`Failed to open telemetry database: ${msg}\\n`);\n process.stderr.write(`Path: ${dbPath}\\n`);\n process.stderr.write(\n \"Make sure you have a running Routecraft context with telemetry() enabled.\\n\",\n );\n process.exit(1);\n }\n\n const instance = render(<App db={db} />);\n await instance.waitUntilExit();\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@routecraft/cli",
|
|
3
|
-
"version": "0.5.0-canary.
|
|
3
|
+
"version": "0.5.0-canary.73",
|
|
4
4
|
"description": "CLI for running Routecraft routes",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@opentelemetry/sdk-trace-base": "^2.7.1",
|
|
26
|
-
"@routecraft/routecraft": "^0.5.0-canary.
|
|
26
|
+
"@routecraft/routecraft": "^0.5.0-canary.73",
|
|
27
27
|
"agent-browser": "^0.17.1",
|
|
28
28
|
"cheerio": "^1.2.0",
|
|
29
29
|
"commander": "^14.0.3",
|