@routecraft/cli 0.7.0 → 0.7.1-canary-20260923154637

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.
@@ -0,0 +1,3 @@
1
+ var t="https://bun.com/docs/installation",o="https://routecraft.dev/docs/advanced/programmatic-invocation",r=`[routecraft] The craft CLI requires Bun. Install Bun from ${t}, or embed @routecraft/routecraft programmatically (see ${o}).`;
2
+ export{t as a,r as b};//# sourceMappingURL=chunk-OKX5YME7.js.map
3
+ //# sourceMappingURL=chunk-OKX5YME7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bun-requirement.ts"],"names":["INSTALL_URL","EMBEDDING_DOC_URL","MISSING_BUN_MESSAGE"],"mappings":"AAQO,IAAMA,CAAAA,CAAc,oCAEdC,CAAAA,CACX,8DAAA,CAEWC,EACX,CAAA,0DAAA,EACoBF,CAAW,2DAC0BC,CAAiB,CAAA,EAAA","file":"chunk-OKX5YME7.js","sourcesContent":["/**\n * What the craft CLI tells someone who runs it without Bun.\n *\n * Kept apart from `runtime-gate.ts` because the entry point checks for Bun\n * before anything else, and that check must not load core: `runtime-gate.ts`\n * reads the version with core's parser, and loading core builds the logger.\n */\n\nexport const INSTALL_URL = \"https://bun.com/docs/installation\";\n\nexport const EMBEDDING_DOC_URL =\n \"https://routecraft.dev/docs/advanced/programmatic-invocation\";\n\nexport const MISSING_BUN_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"]}
@@ -0,0 +1,2 @@
1
+ var r="0.7.1-canary-20260923154637";export{r as a};//# sourceMappingURL=chunk-YFHLDGJC.js.map
2
+ //# sourceMappingURL=chunk-YFHLDGJC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../package.json"],"names":["version"],"mappings":"AAEE,IAAAA,CAAAA,CAAW","file":"chunk-YFHLDGJC.js","sourcesContent":["{\n \"name\": \"@routecraft/cli\",\n \"version\": \"0.7.1-canary-20260923154637\",\n \"description\": \"CLI for running Routecraft capabilities\",\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 \"@agentclientprotocol/sdk\": \"^1.4.0\",\n \"@opentelemetry/sdk-trace-base\": \"^2.10.0\",\n \"@routecraft/routecraft\": \"0.7.1-canary-20260923154637\",\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 \"execa\": \"^9.6.0\",\n \"fast-xml-parser\": \"^5.10.1\",\n \"imapflow\": \"^1.4.7\",\n \"ink\": \"^5.2.1\",\n \"jose\": \"^6.2.8\",\n \"mailparser\": \"^3.9.15\",\n \"nodemailer\": \"^6.10.1\",\n \"papaparse\": \"^5.5.4\",\n \"pino-pretty\": \"^13.1.3\",\n \"react\": \"^18.3.1\",\n \"shescape\": \"^3.0.2\",\n \"tsdav\": \"^2.3.1\",\n \"yaml\": \"^2.9.0\"\n },\n \"devDependencies\": {\n \"@types/mailparser\": \"^3.4.6\",\n \"@types/nodemailer\": \"^6.4.24\",\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,4 +1,4 @@
1
1
  #!/usr/bin/env bun
2
- import {a as a$1}from'./chunk-ILBYIHLE.js';import {parseRuntimeVersion,compareRuntimeVersion}from'@routecraft/routecraft';var p={major:1,minor:1,patch:0},g="https://bun.com/docs/installation",O="https://routecraft.dev/docs/advanced/programmatic-invocation";function v(e=process.versions.bun??null){let t=e;if(!t)return {ok:false,message:`[routecraft] The craft CLI requires Bun. Install Bun from ${g}, or embed @routecraft/routecraft programmatically (see ${O}).`};let o=parseRuntimeVersion(t);return o===void 0?{ok:false,message:`[routecraft] Could not parse Bun version "${t}". Routecraft requires Bun ${w(p)} or later. Upgrade Bun: ${g}.`}:compareRuntimeVersion(o,p)<0?{ok:false,message:`[routecraft] Bun ${t} is not supported. Routecraft requires Bun ${w(p)} or later. Upgrade Bun: ${g}.`}:{ok:true}}function w(e){return `${e.major}.${e.minor}.${e.patch}`}var y=v();y.ok||(console.error(y.message),process.exit(1));var{Command:S}=await import('commander'),a=new S;a.name("craft").description("A modern routing framework for TypeScript").version(a$1).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&&a.help({error:false});function s(e={}){let t=a.opts(),o=e.logLevel??t.logLevel,n=e.logFile??t.logFile;o!==void 0&&(process.env.LOG_LEVEL=o,process.env.CRAFT_LOG_LEVEL=o),n!==void 0&&(process.env.LOG_FILE=n,process.env.CRAFT_LOG_FILE=n);}function b(e){return e.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")}async function L(e,t){let{loadEnvironment:o}=await import('./util-XVJ6ODCT.js'),{resolveSettings:n,SettingsError:i}=await import('./settings-W2CHBN4F.js');try{let r=n({cwd:t,...e.profile===void 0?{}:{profile:e.profile}});return o({explicit:e.env,profile:r.profile?.value,env:r.env?.value,defaultsFrom:t}),{}}catch(r){if(r instanceof i)return {error:r.message};throw r}}b(a.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)").option("--profile <name>","Settings profile to select")).passThroughOptions().action(async(e,t,o)=>{s(o);let n=await L(o,process.cwd());if(n.error!==void 0){c({code:2,error:n.error});return}let{runCommand:i}=await import('./run-N7QNCQ6G.js'),r=await i(e,t);if(!r.success){r.message&&console.error(r.message);let d=r.code??1;setImmediate(()=>process.exit(d));return}});b(a.command("start").description("Start a project from its folder convention (capabilities, plugins, agents, skills)").argument("[dir]","Project root (default: current directory)").option("--env <path>","Load environment variables from a .env file (default: .env)").option("--once","Shut down after the first exchange reaches a terminal outcome").option("--timeout <duration>",'With --once, give up and exit non-zero after this long (milliseconds, or a duration string like "30s")').option("--profile <name>","Settings profile to select")).action(async(e,t)=>{s(t);let{resolve:o}=await import('path'),n=o(process.cwd(),e??"."),i=await L(t,n);if(i.error!==void 0){c({code:2,error:i.error});return}let{startCommand:r}=await import('./start-YASUN2DJ.js'),d;if(t.timeout!==void 0){let{parseDuration:f}=await import('@routecraft/routecraft'),C=/^\d+(\.\d+)?$/.test(t.timeout.trim())?Number(t.timeout):t.timeout;try{d=f(C,"--timeout");}catch{console.error(`--timeout must be a number of milliseconds (at least 1) or a duration string like "30s". Received "${String(t.timeout)}".`),setImmediate(()=>process.exit(1));return}}if(d!==void 0&&t.once!==true){console.error("--timeout bounds the wait for the first exchange, which only --once waits for. Add --once, or drop --timeout."),setImmediate(()=>process.exit(1));return}let l=await r(e,{once:t.once===true,...d===void 0?{}:{timeoutMs:d}});if(!l.success){l.message&&console.error(l.message);let f=l.code??1;setImmediate(()=>process.exit(f));return}});function c(e){let t=[];e.output!==void 0&&t.push([process.stdout,e.output]),e.error!==void 0&&t.push([process.stderr,e.error]);let o=()=>{setImmediate(()=>process.exit(e.code));};if(t.length===0){o();return}process.exitCode=e.code;let n=t.length;for(let[i,r]of t)i.write(`${r}
3
- `,()=>{n-=1,n===0&&o();});}async function x(){let{fstatSync:e}=await import('fs');try{let n=e(0);if(!n.isFIFO()&&!n.isFile())return}catch{return}let t=[];for await(let n of process.stdin)t.push(Buffer.from(n));let o=Buffer.concat(t).toString("utf8");return o.length===0?void 0:o}a.command("exec").description("Dispatch to a route on a running instance and print the result").argument("[route]","Route id to dispatch to; omit for the endpoint list").argument("[args...]","Route input as --field=value pairs").option("--profile <name>","Settings profile to select").option("--url <url>","Ops server base URL of the target instance").option("--token <token>","Bearer credential for the management door").option("--format <format>","pretty (default), json, or raw").passThroughOptions().allowUnknownOption().action(async(e,t,o)=>{s();let{execCommand:n}=await import('./exec-XCYDOTN2.js'),i=e===void 0||t.length>0?void 0:await x();c(await n(e,t,{...o,...i===void 0?{}:{stdin:i}}));});a.command("acp").description("Bridge an editor to an instance over the Agent Client Protocol").option("--profile <name>","Settings profile to select").option("--url <url>","Ops server base URL of the target instance").option("--token <token>","Bearer credential for the management door").option("--agent <name>","Agent to talk to; the instance's default otherwise").action(async e=>{s();let{acpCommand:t}=await import('./acp-JCKR7JQK.js');c(await t(e));});var m=a.command("ops").description("Inspect a running instance: health, readiness, routes, deferrals, indicators");function u(e){return e.option("--profile <name>","Settings profile to select").option("--url <url>","Ops server base URL of the target instance").option("--token <token>","Bearer credential for the management door").option("--format <format>","pretty (default), json, or raw")}u(m.command("health").description("Operational health: every component, whatever its domain")).action(async e=>{s();let{healthCommand:t}=await import('./ops-MUE3PMNS.js');c(await t(e));});u(m.command("ready").description("Readiness: whether this replica should receive traffic")).action(async e=>{s();let{readyCommand:t}=await import('./ops-MUE3PMNS.js');c(await t(e));});u(m.command("routes").description("List routes, or describe one").argument("[id]","Route id; omit to list").option("--dispatchable","Only routes that can be dispatched to").option("--source <kind>","Only routes carrying a source of this kind")).action(async(e,t)=>{s();let{routesCommand:o,routeCommand:n}=await import('./ops-MUE3PMNS.js');c(e===void 0?await o(t):await n(e,t));});u(m.command("deferrals").description("List what is waiting, or describe one deferral").argument("[id]","Deferral id; omit to list").option("--state <state>","waiting (default), settled, or all").option("--route <id>","Only deferrals belonging to this route").option("--limit <n>","Rows in one page").option("--after <cursor>","Continue from a previous page's cursor")).action(async(e,t)=>{s();let{deferralsCommand:o,deferralCommand:n}=await import('./ops-MUE3PMNS.js');c(e===void 0?await o(t):await n(e,t));});u(m.command("indicators").description("List indicators, or read one").argument("[name]","Indicator name; omit to list")).action(async(e,t)=>{s();let{indicatorsCommand:o,indicatorCommand:n}=await import('./ops-MUE3PMNS.js');c(e===void 0?await o(t):await n(e,t));});a.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:t,isAbsolute:o}=await import('path'),n=o(e.db)?e.db:t(process.cwd(),e.db),{renderTui:i}=await import('./tui/app.js');await i(n);});a.parse();//# sourceMappingURL=index.js.map
2
+ import {a as a$1}from'./chunk-YFHLDGJC.js';import {b as b$1}from'./chunk-OKX5YME7.js';process.versions.bun||(console.error(b$1),process.exit(1));var{Command:v}=await import('commander'),a=new v;p(a.name("craft").description("A modern routing framework for TypeScript").version(a$1).enablePositionalOptions()).showSuggestionAfterError().showHelpAfterError().exitOverride(e=>{e.code==="commander.unknownCommand"&&process.exit(0);});a.hook("preAction",async(e,t)=>{await y(t.opts());});process.argv.length<=2&&a.help({error:false});async function y(e){b(e);let{checkBunRuntime:t}=await import('./runtime-gate-NEYB2HPB.js'),o=t();o.ok||(console.error(o.message),process.exit(1));}function b(e){let t=a.opts(),o=e.logLevel??t.logLevel,n=e.logFile??t.logFile;o!==void 0&&(process.env.LOG_LEVEL=o,process.env.CRAFT_LOG_LEVEL=o),n!==void 0&&(process.env.LOG_FILE=n,process.env.CRAFT_LOG_FILE=n);}function p(e){return e.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")}async function h(e,t){let{loadEnvironment:o}=await import('./util-XVJ6ODCT.js'),{resolveSettings:n,SettingsError:i}=await import('./settings-W2CHBN4F.js');try{let r=n({cwd:t,...e.profile===void 0?{}:{profile:e.profile}});return o({explicit:e.env,profile:r.profile?.value,env:r.env?.value,defaultsFrom:t}),{}}catch(r){if(r instanceof i)return {error:r.message};throw r}}p(a.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)").option("--profile <name>","Settings profile to select")).passThroughOptions().action(async(e,t,o)=>{let n=await h(o,process.cwd());if(n.error!==void 0){s({code:2,error:n.error});return}let{runCommand:i}=await import('./run-N7QNCQ6G.js'),r=await i(e,t);if(!r.success){r.message&&console.error(r.message);let c=r.code??1;setImmediate(()=>process.exit(c));return}});p(a.command("start").description("Start a project from its folder convention (capabilities, plugins, agents, skills)").argument("[dir]","Project root (default: current directory)").option("--env <path>","Load environment variables from a .env file (default: .env)").option("--once","Shut down after the first exchange reaches a terminal outcome").option("--timeout <duration>",'With --once, give up and exit non-zero after this long (milliseconds, or a duration string like "30s")').option("--profile <name>","Settings profile to select")).action(async(e,t)=>{let{resolve:o}=await import('path'),n=o(process.cwd(),e??"."),i=await h(t,n);if(i.error!==void 0){s({code:2,error:i.error});return}let{startCommand:r}=await import('./start-YASUN2DJ.js'),c;if(t.timeout!==void 0){let{parseDuration:l}=await import('@routecraft/routecraft'),w=/^\d+(\.\d+)?$/.test(t.timeout.trim())?Number(t.timeout):t.timeout;try{c=l(w,"--timeout");}catch{console.error(`--timeout must be a number of milliseconds (at least 1) or a duration string like "30s". Received "${String(t.timeout)}".`),setImmediate(()=>process.exit(1));return}}if(c!==void 0&&t.once!==true){console.error("--timeout bounds the wait for the first exchange, which only --once waits for. Add --once, or drop --timeout."),setImmediate(()=>process.exit(1));return}let u=await r(e,{once:t.once===true,...c===void 0?{}:{timeoutMs:c}});if(!u.success){u.message&&console.error(u.message);let l=u.code??1;setImmediate(()=>process.exit(l));return}});function s(e){let t=[];e.output!==void 0&&t.push([process.stdout,e.output]),e.error!==void 0&&t.push([process.stderr,e.error]);let o=()=>{setImmediate(()=>process.exit(e.code));};if(t.length===0){o();return}process.exitCode=e.code;let n=t.length;for(let[i,r]of t)i.write(`${r}
3
+ `,()=>{n-=1,n===0&&o();});}async function L(){let{fstatSync:e}=await import('fs');try{let n=e(0);if(!n.isFIFO()&&!n.isFile())return}catch{return}let t=[];for await(let n of process.stdin)t.push(Buffer.from(n));let o=Buffer.concat(t).toString("utf8");return o.length===0?void 0:o}a.command("exec").description("Dispatch to a route on a running instance and print the result").argument("[route]","Route id to dispatch to; omit for the endpoint list").argument("[args...]","Route input as --field=value pairs").option("--profile <name>","Settings profile to select").option("--url <url>","Ops server base URL of the target instance").option("--token <token>","Bearer credential for the management door").option("--format <format>","pretty (default), json, or raw").passThroughOptions().allowUnknownOption().action(async(e,t,o)=>{let{execCommand:n}=await import('./exec-XCYDOTN2.js'),i=e===void 0||t.length>0?void 0:await L();s(await n(e,t,{...o,...i===void 0?{}:{stdin:i}}));});a.command("acp").description("Bridge an editor to an instance over the Agent Client Protocol").option("--profile <name>","Settings profile to select").option("--url <url>","Ops server base URL of the target instance").option("--token <token>","Bearer credential for the management door").option("--agent <name>","Agent to talk to; the instance's default otherwise").action(async e=>{let{acpCommand:t}=await import('./acp-JCKR7JQK.js');s(await t(e));});var d=a.command("ops").description("Inspect a running instance: health, readiness, routes, deferrals, indicators");function m(e){return e.option("--profile <name>","Settings profile to select").option("--url <url>","Ops server base URL of the target instance").option("--token <token>","Bearer credential for the management door").option("--format <format>","pretty (default), json, or raw")}m(d.command("health").description("Operational health: every component, whatever its domain")).action(async e=>{let{healthCommand:t}=await import('./ops-MUE3PMNS.js');s(await t(e));});m(d.command("ready").description("Readiness: whether this replica should receive traffic")).action(async e=>{let{readyCommand:t}=await import('./ops-MUE3PMNS.js');s(await t(e));});m(d.command("routes").description("List routes, or describe one").argument("[id]","Route id; omit to list").option("--dispatchable","Only routes that can be dispatched to").option("--source <kind>","Only routes carrying a source of this kind")).action(async(e,t)=>{let{routesCommand:o,routeCommand:n}=await import('./ops-MUE3PMNS.js');s(e===void 0?await o(t):await n(e,t));});m(d.command("deferrals").description("List what is waiting, or describe one deferral").argument("[id]","Deferral id; omit to list").option("--state <state>","waiting (default), settled, or all").option("--route <id>","Only deferrals belonging to this route").option("--limit <n>","Rows in one page").option("--after <cursor>","Continue from a previous page's cursor")).action(async(e,t)=>{let{deferralsCommand:o,deferralCommand:n}=await import('./ops-MUE3PMNS.js');s(e===void 0?await o(t):await n(e,t));});m(d.command("indicators").description("List indicators, or read one").argument("[name]","Indicator name; omit to list")).action(async(e,t)=>{let{indicatorsCommand:o,indicatorCommand:n}=await import('./ops-MUE3PMNS.js');s(e===void 0?await o(t):await n(e,t));});a.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:t,isAbsolute:o}=await import('path'),n=o(e.db)?e.db:t(process.cwd(),e.db),{renderTui:i}=await import('./tui/app.js');await i(n);});await a.parseAsync();//# sourceMappingURL=index.js.map
4
4
  //# 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","parsed","parseRuntimeVersion","formatVersion","compareRuntimeVersion","v","gate","Command","program","err","applyGlobalLogOptions","local","globalOpts","level","file","withLogOptions","command","selectEnvironment","options","projectRoot","loadEnvironment","resolveSettings","SettingsError","settings","error","filePath","args","selected","settle","runCommand","result","code","dir","resolvePath","startCommand","timeoutMs","parseDuration","raw","writes","finish","pending","stream","text","readStdin","fstatSync","stat","chunks","chunk","route","execCommand","stdin","acpCommand","ops","opsOption","healthCommand","readyCommand","id","routesCommand","routeCommand","deferralsCommand","deferralCommand","name","indicatorsCommand","indicatorCommand","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 * The version itself is read by `parseRuntimeVersion` from core, shared\n * with the ops client's own Bun check: written twice, the two parsers\n * disagreed on the same string within one release.\n */\n\nimport {\n compareRuntimeVersion,\n parseRuntimeVersion,\n type RuntimeVersion,\n} from \"@routecraft/routecraft\";\n\nconst MIN_BUN_VERSION: RuntimeVersion = { major: 1, minor: 1, patch: 0 };\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 const parsed = parseRuntimeVersion(version);\n\n if (parsed === undefined) {\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 if (compareRuntimeVersion(parsed, MIN_BUN_VERSION) < 0) {\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: RuntimeVersion): 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 * Push the global log options onto the environment before any import\n * that constructs the logger. The logger reads env at module load, so\n * this has to happen inside a command action but ahead of the lazy\n * `run` / `start` imports.\n */\nfunction applyGlobalLogOptions(local: LogOptions = {}): void {\n const globalOpts = program.opts();\n // The command's own flag wins, so `craft --log-level warn start --log-level\n // debug` reads the way a reader expects: the nearer one.\n const level = local.logLevel ?? globalOpts[\"logLevel\"];\n const file = local.logFile ?? globalOpts[\"logFile\"];\n if (level !== undefined) {\n process.env[\"LOG_LEVEL\"] = level;\n process.env[\"CRAFT_LOG_LEVEL\"] = level;\n }\n if (file !== undefined) {\n process.env[\"LOG_FILE\"] = file;\n process.env[\"CRAFT_LOG_FILE\"] = file;\n }\n}\n\n/**\n * The logging flags a command may carry as well as the program.\n *\n * `enablePositionalOptions()` confines a global option to the space before\n * the subcommand, so `craft start --log-level info` died on \"unknown\n * option\" and `craft run app.ts --log-level info` was swallowed whole by the\n * pass-through and handed to the route. That is the spelling everyone\n * reaches for, and the rule bought nothing here but a lesson every user had\n * to learn once.\n *\n * `run` keeps its pass-through contract: a flag written after the file still\n * belongs to the route, because that is the only way a CLI-adapter route can\n * own a flag the CLI also defines.\n */\ninterface LogOptions {\n logLevel?: string;\n logFile?: string;\n}\n\ntype CommanderCommand = InstanceType<typeof Command>;\n\n/** Attach the logging flags to a command that boots a context. */\nfunction withLogOptions(command: CommanderCommand): CommanderCommand {\n return command\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}\n\n/**\n * Resolve the selected profile and load the environment it names, before\n * anything imports the project's configuration.\n *\n * Ordering is the whole point: a config file reads `process.env` at module\n * scope, so the environment has to be in place before the import, and the\n * profile is what says which environment that is.\n *\n * A settings file that cannot be used stops the command rather than\n * falling back to the defaults, because an operator who wrote a profile\n * and silently got the loopback default would have no way to tell.\n */\nasync function selectEnvironment(\n options: { env?: string; profile?: string },\n projectRoot: string,\n): Promise<{ error?: string }> {\n const { loadEnvironment } = await import(\"./util.js\");\n const { resolveSettings, SettingsError } = await import(\"./settings.js\");\n try {\n // Resolved under the project root, not the shell's directory: the file\n // that declares a profile and the env files that profile selects have\n // to be the same project's, or `craft start ./apps/acme` reads one\n // project's profile and another's environment.\n const settings = resolveSettings({\n cwd: projectRoot,\n ...(options.profile === undefined ? {} : { profile: options.profile }),\n });\n loadEnvironment({\n explicit: options.env,\n profile: settings.profile?.value,\n env: settings.env?.value,\n defaultsFrom: projectRoot,\n });\n return {};\n } catch (error: unknown) {\n if (error instanceof SettingsError) return { error: error.message };\n throw error;\n }\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 */\nwithLogOptions(\n program\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 .option(\"--profile <name>\", \"Settings profile to select\"),\n)\n .passThroughOptions()\n .action(async (filePath, args: string[], options) => {\n applyGlobalLogOptions(options as LogOptions);\n\n const selected = await selectEnvironment(options, process.cwd());\n if (selected.error !== undefined) {\n settle({ code: 2, error: selected.error });\n return;\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 'start' command boots a whole project from the folder convention.\n *\n * Example:\n * craft start\n * craft start ./apps/acme --once\n */\nwithLogOptions(\n program\n .command(\"start\")\n .description(\n \"Start a project from its folder convention (capabilities, plugins, agents, skills)\",\n )\n .argument(\"[dir]\", \"Project root (default: current directory)\")\n .option(\n \"--env <path>\",\n \"Load environment variables from a .env file (default: .env)\",\n )\n .option(\n \"--once\",\n \"Shut down after the first exchange reaches a terminal outcome\",\n )\n .option(\n \"--timeout <duration>\",\n 'With --once, give up and exit non-zero after this long (milliseconds, or a duration string like \"30s\")',\n )\n .option(\"--profile <name>\", \"Settings profile to select\"),\n).action(\n async (\n dir: string | undefined,\n options: {\n env?: string;\n once?: boolean;\n timeout?: string;\n profile?: string;\n } & LogOptions,\n ) => {\n applyGlobalLogOptions(options);\n\n const { resolve: resolvePath } = await import(\"node:path\");\n const projectRoot = resolvePath(process.cwd(), dir ?? \".\");\n\n // The conventional files belong to the project being started, not to\n // whatever directory the shell happens to sit in. Resolved and\n // loaded before `craft.config.ts` is imported, because config files\n // read `process.env` at module scope.\n const selected = await selectEnvironment(options, projectRoot);\n if (selected.error !== undefined) {\n settle({ code: 2, error: selected.error });\n return;\n }\n\n const { startCommand } = await import(\"./start.js\");\n // A bare number stays milliseconds, so every existing invocation keeps\n // working; anything else goes through the framework's duration grammar\n // so `--timeout 30s` means what it reads as.\n let timeoutMs: number | undefined;\n if (options.timeout !== undefined) {\n const { parseDuration } = await import(\"@routecraft/routecraft\");\n const raw = /^\\d+(\\.\\d+)?$/.test(options.timeout.trim())\n ? Number(options.timeout)\n : (options.timeout as `${number}s`);\n try {\n timeoutMs = parseDuration(raw, \"--timeout\");\n } catch {\n // eslint-disable-next-line no-console\n console.error(\n `--timeout must be a number of milliseconds (at least 1) or a duration string like \"30s\". Received \"${String(options.timeout)}\".`,\n );\n setImmediate(() => process.exit(1));\n return;\n }\n }\n if (timeoutMs !== undefined && options.once !== true) {\n // eslint-disable-next-line no-console\n console.error(\n `--timeout bounds the wait for the first exchange, which only --once waits for. Add --once, or drop --timeout.`,\n );\n setImmediate(() => process.exit(1));\n return;\n }\n const result = await startCommand(dir, {\n once: options.once === true,\n ...(timeoutMs === undefined ? {} : { timeoutMs }),\n });\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\n // \"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 },\n);\n\n/**\n * Print a command's result and exit with its code.\n *\n * The write is awaited rather than fired and forgotten. `process.stdout` is\n * asynchronous when it is a pipe, and `process.exit` discards whatever is\n * still queued, so `craft exec --format json | jq` would lose the tail of a\n * large result. Exiting from the write callback is what makes the payload\n * whole; the exit itself stays deferred so pino/sonic-boom can finish\n * initialising, the same reason `run` and `start` defer theirs.\n */\nfunction settle(result: {\n code: number;\n output?: string;\n error?: string;\n}): void {\n const writes: Array<[NodeJS.WriteStream, string]> = [];\n if (result.output !== undefined) writes.push([process.stdout, result.output]);\n if (result.error !== undefined) writes.push([process.stderr, result.error]);\n\n const finish = (): void => {\n setImmediate(() => process.exit(result.code));\n };\n if (writes.length === 0) {\n finish();\n return;\n }\n // Set early so a stream that never drains still exits with the right code\n // rather than reporting success on the way out.\n process.exitCode = result.code;\n let pending = writes.length;\n for (const [stream, text] of writes) {\n stream.write(`${text}\\n`, () => {\n pending -= 1;\n if (pending === 0) finish();\n });\n }\n}\n\n/**\n * Read route input piped on stdin, or undefined when none was.\n *\n * Gated on stdin actually being a redirect (a pipe or a file) rather than\n * on it not being a TTY. The two are not the same: a process launched by\n * CI, a supervisor, or another program routinely inherits a socket on fd 0\n * that is neither a terminal nor ever going to close, and reading it waits\n * for an EOF that never comes. `craft exec` would hang with no output,\n * which is the worst way to fail.\n */\nasync function readStdin(): Promise<string | undefined> {\n const { fstatSync } = await import(\"node:fs\");\n try {\n const stat = fstatSync(0);\n if (!stat.isFIFO() && !stat.isFile()) return undefined;\n } catch {\n return undefined;\n }\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(Buffer.from(chunk as Buffer));\n }\n const text = Buffer.concat(chunks).toString(\"utf8\");\n return text.length === 0 ? undefined : text;\n}\n\n/**\n * The 'exec' command dispatches to a route on a running instance.\n *\n * Craft's own flags come before the route name and the route's input comes\n * after it, the same split `craft run` uses, so a route field can never\n * collide with a CLI flag.\n *\n * Example:\n * craft exec greet --name World\n * craft exec --url http://10.0.0.5:8080 --token \"$TOKEN\" greet --name World\n */\nprogram\n .command(\"exec\")\n .description(\"Dispatch to a route on a running instance and print the result\")\n .argument(\"[route]\", \"Route id to dispatch to; omit for the endpoint list\")\n .argument(\"[args...]\", \"Route input as --field=value pairs\")\n .option(\"--profile <name>\", \"Settings profile to select\")\n .option(\"--url <url>\", \"Ops server base URL of the target instance\")\n .option(\"--token <token>\", \"Bearer credential for the management door\")\n .option(\"--format <format>\", \"pretty (default), json, or raw\")\n .passThroughOptions()\n .allowUnknownOption()\n .action(\n async (\n route: string | undefined,\n args: string[],\n options: {\n profile?: string;\n url?: string;\n token?: string;\n format?: string;\n },\n ) => {\n applyGlobalLogOptions();\n const { execCommand } = await import(\"./exec.js\");\n // Args and stdin are mutually exclusive, so a command that already\n // carries args must not read stdin at all: in `tail -f x | while read\n // l; do craft exec r --line=\\\"$l\\\"; done` the inherited pipe never\n // closes, and reading it would hang and swallow the loop's own input.\n const stdin =\n route === undefined || args.length > 0 ? undefined : await readStdin();\n settle(\n await execCommand(route, args, {\n ...options,\n ...(stdin === undefined ? {} : { stdin }),\n }),\n );\n },\n );\n\n/**\n * The 'acp' command is the pipe an editor runs.\n *\n * An editor starts it and speaks the Agent Client Protocol over its\n * standard input and output; it forwards every message to the instance the\n * profile names, and forwards everything the instance says back. It never\n * starts an app: `craft start` owns running, which is what lets one editor\n * entry reach a laptop or a company instance by switching a profile.\n *\n * Example:\n * craft acp\n * craft acp --profile company\n * craft acp --url https://acme.example --token \"$TOKEN\" --agent aria\n */\nprogram\n .command(\"acp\")\n .description(\"Bridge an editor to an instance over the Agent Client Protocol\")\n .option(\"--profile <name>\", \"Settings profile to select\")\n .option(\"--url <url>\", \"Ops server base URL of the target instance\")\n .option(\"--token <token>\", \"Bearer credential for the management door\")\n .option(\n \"--agent <name>\",\n \"Agent to talk to; the instance's default otherwise\",\n )\n .action(\n async (options: {\n profile?: string;\n url?: string;\n token?: string;\n agent?: string;\n }) => {\n applyGlobalLogOptions();\n const { acpCommand } = await import(\"./acp.js\");\n // Standard output is the protocol's, and `settle` writes there only\n // for a result carrying `output`, which this one never does. What it\n // adds is the awaited write: an editor spawns this with a pipe on\n // standard error, where an exit discards whatever is still queued.\n settle(await acpCommand(options));\n },\n );\n\n/**\n * The 'ops' command family reads a running instance's own state.\n *\n * Grouped by operator task rather than by URL prefix: `craft ops health`\n * reads `/health/**` while `craft ops routes` reads `/ops/routes`, because\n * the two surfaces have deliberately different auth postures and the\n * command family answers a different question from the path layout.\n *\n * Example:\n * craft ops health\n * craft ops routes --dispatchable\n */\nconst ops = program\n .command(\"ops\")\n .description(\n \"Inspect a running instance: health, readiness, routes, deferrals, indicators\",\n );\n\nfunction opsOption<T extends import(\"commander\").Command>(command: T): T {\n return command\n .option(\"--profile <name>\", \"Settings profile to select\")\n .option(\"--url <url>\", \"Ops server base URL of the target instance\")\n .option(\"--token <token>\", \"Bearer credential for the management door\")\n .option(\"--format <format>\", \"pretty (default), json, or raw\") as T;\n}\n\nopsOption(\n ops\n .command(\"health\")\n .description(\"Operational health: every component, whatever its domain\"),\n).action(async (options: Record<string, string>) => {\n applyGlobalLogOptions();\n const { healthCommand } = await import(\"./ops.js\");\n settle(await healthCommand(options));\n});\n\nopsOption(\n ops\n .command(\"ready\")\n .description(\"Readiness: whether this replica should receive traffic\"),\n).action(async (options: Record<string, string>) => {\n applyGlobalLogOptions();\n const { readyCommand } = await import(\"./ops.js\");\n settle(await readyCommand(options));\n});\n\nopsOption(\n ops\n .command(\"routes\")\n .description(\"List routes, or describe one\")\n .argument(\"[id]\", \"Route id; omit to list\")\n .option(\"--dispatchable\", \"Only routes that can be dispatched to\")\n .option(\"--source <kind>\", \"Only routes carrying a source of this kind\"),\n).action(\n async (\n id: string | undefined,\n options: {\n dispatchable?: boolean;\n source?: string;\n profile?: string;\n url?: string;\n token?: string;\n format?: string;\n },\n ) => {\n applyGlobalLogOptions();\n const { routesCommand, routeCommand } = await import(\"./ops.js\");\n settle(\n id === undefined\n ? await routesCommand(options)\n : await routeCommand(id, options),\n );\n },\n);\n\nopsOption(\n ops\n .command(\"deferrals\")\n .description(\"List what is waiting, or describe one deferral\")\n .argument(\"[id]\", \"Deferral id; omit to list\")\n .option(\"--state <state>\", \"waiting (default), settled, or all\")\n .option(\"--route <id>\", \"Only deferrals belonging to this route\")\n .option(\"--limit <n>\", \"Rows in one page\")\n .option(\"--after <cursor>\", \"Continue from a previous page's cursor\"),\n).action(\n async (\n id: string | undefined,\n options: {\n state?: string;\n route?: string;\n limit?: string;\n after?: string;\n profile?: string;\n url?: string;\n token?: string;\n format?: string;\n },\n ) => {\n applyGlobalLogOptions();\n const { deferralsCommand, deferralCommand } = await import(\"./ops.js\");\n settle(\n id === undefined\n ? await deferralsCommand(options)\n : await deferralCommand(id, options),\n );\n },\n);\n\nopsOption(\n ops\n .command(\"indicators\")\n .description(\"List indicators, or read one\")\n .argument(\"[name]\", \"Indicator name; omit to list\"),\n).action(async (name: string | undefined, options: Record<string, string>) => {\n applyGlobalLogOptions();\n const { indicatorsCommand, indicatorCommand } = await import(\"./ops.js\");\n settle(\n name === undefined\n ? await indicatorsCommand(options)\n : await indicatorCommand(name, options),\n );\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/index.ts"],"names":["MISSING_BUN_MESSAGE","Command","program","withLogOptions","version","err","_program","actionCommand","prepareCommand","local","applyLogOptions","checkBunRuntime","gate","globalOpts","level","file","command","selectEnvironment","options","projectRoot","loadEnvironment","resolveSettings","SettingsError","settings","error","filePath","args","selected","settle","runCommand","result","code","dir","resolvePath","startCommand","timeoutMs","parseDuration","raw","writes","finish","pending","stream","text","readStdin","fstatSync","stat","chunks","chunk","route","execCommand","stdin","acpCommand","ops","opsOption","healthCommand","readyCommand","id","routesCommand","routeCommand","deferralsCommand","deferralCommand","name","indicatorsCommand","indicatorCommand","resolve","isAbsolute","dbPath","renderTui"],"mappings":"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","file":"index.js","sourcesContent":["#!/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 * Nothing here may import `@routecraft/routecraft` at module scope. Core builds\n * its logger when it loads, from the environment as it stands then, so a core\n * import that runs before a command has applied `--log-level` and\n * `--log-file` fixes the logger to the defaults for the life of the process.\n * The program's `preAction` hook runs `prepareCommand()` before every\n * command: it applies the logging flags first and only then runs the Bun\n * version check, the first thing that loads core. Whether Bun is present at\n * all is checked here, before anything, without core.\n */\n\nimport { version } from \"../package.json\";\nimport { MISSING_BUN_MESSAGE } from \"./bun-requirement.js\";\n\nif (!process.versions[\"bun\"]) {\n // eslint-disable-next-line no-console\n console.error(MISSING_BUN_MESSAGE);\n process.exit(1);\n}\n\nconst { Command } = await import(\"commander\");\nconst program = new Command();\n\nwithLogOptions(\n program\n .name(\"craft\")\n .description(\"A modern routing framework for TypeScript\")\n .version(version)\n .enablePositionalOptions(),\n)\n .showSuggestionAfterError()\n .showHelpAfterError()\n .exitOverride((err) => {\n if (err.code === \"commander.unknownCommand\") {\n process.exit(0);\n }\n });\n\nprogram.hook(\"preAction\", async (_program, actionCommand) => {\n await prepareCommand(actionCommand.opts() as LogOptions);\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 * Ready a command to run: push the logging flags onto the environment, then\n * refuse a Bun below the supported floor. Runs from the `preAction` hook, so\n * no command can skip it.\n *\n * The order is the contract. The gate reads the version with core's parser,\n * and loading core builds the logger, so the flags must be in the\n * environment before the gate is imported.\n */\nasync function prepareCommand(local: LogOptions): Promise<void> {\n applyLogOptions(local);\n const { checkBunRuntime } = await import(\"./runtime-gate.js\");\n const gate = checkBunRuntime();\n if (!gate.ok) {\n // eslint-disable-next-line no-console\n console.error(gate.message);\n process.exit(1);\n }\n}\n\n/** Push the logging flags onto the environment the logger is built from. */\nfunction applyLogOptions(local: LogOptions): void {\n const globalOpts = program.opts();\n // The command's own flag wins, so `craft --log-level warn start --log-level\n // debug` reads the way a reader expects: the nearer one.\n const level = local.logLevel ?? globalOpts[\"logLevel\"];\n const file = local.logFile ?? globalOpts[\"logFile\"];\n if (level !== undefined) {\n process.env[\"LOG_LEVEL\"] = level;\n process.env[\"CRAFT_LOG_LEVEL\"] = level;\n }\n if (file !== undefined) {\n process.env[\"LOG_FILE\"] = file;\n process.env[\"CRAFT_LOG_FILE\"] = file;\n }\n}\n\n/**\n * The logging flags a command may carry as well as the program.\n *\n * `enablePositionalOptions()` confines a global option to the space before\n * the subcommand, so `craft start --log-level info` died on \"unknown\n * option\" and `craft run app.ts --log-level info` was swallowed whole by the\n * pass-through and handed to the route. That is the spelling everyone\n * reaches for, and the rule bought nothing here but a lesson every user had\n * to learn once.\n *\n * `run` keeps its pass-through contract: a flag written after the file still\n * belongs to the route, because that is the only way a CLI-adapter route can\n * own a flag the CLI also defines.\n */\ninterface LogOptions {\n logLevel?: string;\n logFile?: string;\n}\n\ntype CommanderCommand = InstanceType<typeof Command>;\n\n/** Attach the logging flags to a command that boots a context. */\nfunction withLogOptions(command: CommanderCommand): CommanderCommand {\n return command\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}\n\n/**\n * Resolve the selected profile and load the environment it names, before\n * anything imports the project's configuration.\n *\n * Ordering is the whole point: a config file reads `process.env` at module\n * scope, so the environment has to be in place before the import, and the\n * profile is what says which environment that is.\n *\n * A settings file that cannot be used stops the command rather than\n * falling back to the defaults, because an operator who wrote a profile\n * and silently got the loopback default would have no way to tell.\n */\nasync function selectEnvironment(\n options: { env?: string; profile?: string },\n projectRoot: string,\n): Promise<{ error?: string }> {\n const { loadEnvironment } = await import(\"./util.js\");\n const { resolveSettings, SettingsError } = await import(\"./settings.js\");\n try {\n // Resolved under the project root, not the shell's directory: the file\n // that declares a profile and the env files that profile selects have\n // to be the same project's, or `craft start ./apps/acme` reads one\n // project's profile and another's environment.\n const settings = resolveSettings({\n cwd: projectRoot,\n ...(options.profile === undefined ? {} : { profile: options.profile }),\n });\n loadEnvironment({\n explicit: options.env,\n profile: settings.profile?.value,\n env: settings.env?.value,\n defaultsFrom: projectRoot,\n });\n return {};\n } catch (error: unknown) {\n if (error instanceof SettingsError) return { error: error.message };\n throw error;\n }\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 */\nwithLogOptions(\n program\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 .option(\"--profile <name>\", \"Settings profile to select\"),\n)\n .passThroughOptions()\n .action(async (filePath, args: string[], options) => {\n const selected = await selectEnvironment(options, process.cwd());\n if (selected.error !== undefined) {\n settle({ code: 2, error: selected.error });\n return;\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 'start' command boots a whole project from the folder convention.\n *\n * Example:\n * craft start\n * craft start ./apps/acme --once\n */\nwithLogOptions(\n program\n .command(\"start\")\n .description(\n \"Start a project from its folder convention (capabilities, plugins, agents, skills)\",\n )\n .argument(\"[dir]\", \"Project root (default: current directory)\")\n .option(\n \"--env <path>\",\n \"Load environment variables from a .env file (default: .env)\",\n )\n .option(\n \"--once\",\n \"Shut down after the first exchange reaches a terminal outcome\",\n )\n .option(\n \"--timeout <duration>\",\n 'With --once, give up and exit non-zero after this long (milliseconds, or a duration string like \"30s\")',\n )\n .option(\"--profile <name>\", \"Settings profile to select\"),\n).action(\n async (\n dir: string | undefined,\n options: {\n env?: string;\n once?: boolean;\n timeout?: string;\n profile?: string;\n } & LogOptions,\n ) => {\n const { resolve: resolvePath } = await import(\"node:path\");\n const projectRoot = resolvePath(process.cwd(), dir ?? \".\");\n\n // The conventional files belong to the project being started, not to\n // whatever directory the shell happens to sit in. Resolved and\n // loaded before `craft.config.ts` is imported, because config files\n // read `process.env` at module scope.\n const selected = await selectEnvironment(options, projectRoot);\n if (selected.error !== undefined) {\n settle({ code: 2, error: selected.error });\n return;\n }\n\n const { startCommand } = await import(\"./start.js\");\n // A bare number stays milliseconds, so every existing invocation keeps\n // working; anything else goes through the framework's duration grammar\n // so `--timeout 30s` means what it reads as.\n let timeoutMs: number | undefined;\n if (options.timeout !== undefined) {\n const { parseDuration } = await import(\"@routecraft/routecraft\");\n const raw = /^\\d+(\\.\\d+)?$/.test(options.timeout.trim())\n ? Number(options.timeout)\n : (options.timeout as `${number}s`);\n try {\n timeoutMs = parseDuration(raw, \"--timeout\");\n } catch {\n // eslint-disable-next-line no-console\n console.error(\n `--timeout must be a number of milliseconds (at least 1) or a duration string like \"30s\". Received \"${String(options.timeout)}\".`,\n );\n setImmediate(() => process.exit(1));\n return;\n }\n }\n if (timeoutMs !== undefined && options.once !== true) {\n // eslint-disable-next-line no-console\n console.error(\n `--timeout bounds the wait for the first exchange, which only --once waits for. Add --once, or drop --timeout.`,\n );\n setImmediate(() => process.exit(1));\n return;\n }\n const result = await startCommand(dir, {\n once: options.once === true,\n ...(timeoutMs === undefined ? {} : { timeoutMs }),\n });\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\n // \"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 },\n);\n\n/**\n * Print a command's result and exit with its code.\n *\n * The write is awaited rather than fired and forgotten. `process.stdout` is\n * asynchronous when it is a pipe, and `process.exit` discards whatever is\n * still queued, so `craft exec --format json | jq` would lose the tail of a\n * large result. Exiting from the write callback is what makes the payload\n * whole; the exit itself stays deferred so pino/sonic-boom can finish\n * initialising, the same reason `run` and `start` defer theirs.\n */\nfunction settle(result: {\n code: number;\n output?: string;\n error?: string;\n}): void {\n const writes: Array<[NodeJS.WriteStream, string]> = [];\n if (result.output !== undefined) writes.push([process.stdout, result.output]);\n if (result.error !== undefined) writes.push([process.stderr, result.error]);\n\n const finish = (): void => {\n setImmediate(() => process.exit(result.code));\n };\n if (writes.length === 0) {\n finish();\n return;\n }\n // Set early so a stream that never drains still exits with the right code\n // rather than reporting success on the way out.\n process.exitCode = result.code;\n let pending = writes.length;\n for (const [stream, text] of writes) {\n stream.write(`${text}\\n`, () => {\n pending -= 1;\n if (pending === 0) finish();\n });\n }\n}\n\n/**\n * Read route input piped on stdin, or undefined when none was.\n *\n * Gated on stdin actually being a redirect (a pipe or a file) rather than\n * on it not being a TTY. The two are not the same: a process launched by\n * CI, a supervisor, or another program routinely inherits a socket on fd 0\n * that is neither a terminal nor ever going to close, and reading it waits\n * for an EOF that never comes. `craft exec` would hang with no output,\n * which is the worst way to fail.\n */\nasync function readStdin(): Promise<string | undefined> {\n const { fstatSync } = await import(\"node:fs\");\n try {\n const stat = fstatSync(0);\n if (!stat.isFIFO() && !stat.isFile()) return undefined;\n } catch {\n return undefined;\n }\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(Buffer.from(chunk as Buffer));\n }\n const text = Buffer.concat(chunks).toString(\"utf8\");\n return text.length === 0 ? undefined : text;\n}\n\n/**\n * The 'exec' command dispatches to a route on a running instance.\n *\n * Craft's own flags come before the route name and the route's input comes\n * after it, the same split `craft run` uses, so a route field can never\n * collide with a CLI flag.\n *\n * Example:\n * craft exec greet --name World\n * craft exec --url http://10.0.0.5:8080 --token \"$TOKEN\" greet --name World\n */\nprogram\n .command(\"exec\")\n .description(\"Dispatch to a route on a running instance and print the result\")\n .argument(\"[route]\", \"Route id to dispatch to; omit for the endpoint list\")\n .argument(\"[args...]\", \"Route input as --field=value pairs\")\n .option(\"--profile <name>\", \"Settings profile to select\")\n .option(\"--url <url>\", \"Ops server base URL of the target instance\")\n .option(\"--token <token>\", \"Bearer credential for the management door\")\n .option(\"--format <format>\", \"pretty (default), json, or raw\")\n .passThroughOptions()\n .allowUnknownOption()\n .action(\n async (\n route: string | undefined,\n args: string[],\n options: {\n profile?: string;\n url?: string;\n token?: string;\n format?: string;\n },\n ) => {\n const { execCommand } = await import(\"./exec.js\");\n // Args and stdin are mutually exclusive, so a command that already\n // carries args must not read stdin at all: in `tail -f x | while read\n // l; do craft exec r --line=\\\"$l\\\"; done` the inherited pipe never\n // closes, and reading it would hang and swallow the loop's own input.\n const stdin =\n route === undefined || args.length > 0 ? undefined : await readStdin();\n settle(\n await execCommand(route, args, {\n ...options,\n ...(stdin === undefined ? {} : { stdin }),\n }),\n );\n },\n );\n\n/**\n * The 'acp' command is the pipe an editor runs.\n *\n * An editor starts it and speaks the Agent Client Protocol over its\n * standard input and output; it forwards every message to the instance the\n * profile names, and forwards everything the instance says back. It never\n * starts an app: `craft start` owns running, which is what lets one editor\n * entry reach a laptop or a company instance by switching a profile.\n *\n * Example:\n * craft acp\n * craft acp --profile company\n * craft acp --url https://acme.example --token \"$TOKEN\" --agent aria\n */\nprogram\n .command(\"acp\")\n .description(\"Bridge an editor to an instance over the Agent Client Protocol\")\n .option(\"--profile <name>\", \"Settings profile to select\")\n .option(\"--url <url>\", \"Ops server base URL of the target instance\")\n .option(\"--token <token>\", \"Bearer credential for the management door\")\n .option(\n \"--agent <name>\",\n \"Agent to talk to; the instance's default otherwise\",\n )\n .action(\n async (options: {\n profile?: string;\n url?: string;\n token?: string;\n agent?: string;\n }) => {\n const { acpCommand } = await import(\"./acp.js\");\n // Standard output is the protocol's, and `settle` writes there only\n // for a result carrying `output`, which this one never does. What it\n // adds is the awaited write: an editor spawns this with a pipe on\n // standard error, where an exit discards whatever is still queued.\n settle(await acpCommand(options));\n },\n );\n\n/**\n * The 'ops' command family reads a running instance's own state.\n *\n * Grouped by operator task rather than by URL prefix: `craft ops health`\n * reads `/health/**` while `craft ops routes` reads `/ops/routes`, because\n * the two surfaces have deliberately different auth postures and the\n * command family answers a different question from the path layout.\n *\n * Example:\n * craft ops health\n * craft ops routes --dispatchable\n */\nconst ops = program\n .command(\"ops\")\n .description(\n \"Inspect a running instance: health, readiness, routes, deferrals, indicators\",\n );\n\nfunction opsOption<T extends import(\"commander\").Command>(command: T): T {\n return command\n .option(\"--profile <name>\", \"Settings profile to select\")\n .option(\"--url <url>\", \"Ops server base URL of the target instance\")\n .option(\"--token <token>\", \"Bearer credential for the management door\")\n .option(\"--format <format>\", \"pretty (default), json, or raw\") as T;\n}\n\nopsOption(\n ops\n .command(\"health\")\n .description(\"Operational health: every component, whatever its domain\"),\n).action(async (options: Record<string, string>) => {\n const { healthCommand } = await import(\"./ops.js\");\n settle(await healthCommand(options));\n});\n\nopsOption(\n ops\n .command(\"ready\")\n .description(\"Readiness: whether this replica should receive traffic\"),\n).action(async (options: Record<string, string>) => {\n const { readyCommand } = await import(\"./ops.js\");\n settle(await readyCommand(options));\n});\n\nopsOption(\n ops\n .command(\"routes\")\n .description(\"List routes, or describe one\")\n .argument(\"[id]\", \"Route id; omit to list\")\n .option(\"--dispatchable\", \"Only routes that can be dispatched to\")\n .option(\"--source <kind>\", \"Only routes carrying a source of this kind\"),\n).action(\n async (\n id: string | undefined,\n options: {\n dispatchable?: boolean;\n source?: string;\n profile?: string;\n url?: string;\n token?: string;\n format?: string;\n },\n ) => {\n const { routesCommand, routeCommand } = await import(\"./ops.js\");\n settle(\n id === undefined\n ? await routesCommand(options)\n : await routeCommand(id, options),\n );\n },\n);\n\nopsOption(\n ops\n .command(\"deferrals\")\n .description(\"List what is waiting, or describe one deferral\")\n .argument(\"[id]\", \"Deferral id; omit to list\")\n .option(\"--state <state>\", \"waiting (default), settled, or all\")\n .option(\"--route <id>\", \"Only deferrals belonging to this route\")\n .option(\"--limit <n>\", \"Rows in one page\")\n .option(\"--after <cursor>\", \"Continue from a previous page's cursor\"),\n).action(\n async (\n id: string | undefined,\n options: {\n state?: string;\n route?: string;\n limit?: string;\n after?: string;\n profile?: string;\n url?: string;\n token?: string;\n format?: string;\n },\n ) => {\n const { deferralsCommand, deferralCommand } = await import(\"./ops.js\");\n settle(\n id === undefined\n ? await deferralsCommand(options)\n : await deferralCommand(id, options),\n );\n },\n);\n\nopsOption(\n ops\n .command(\"indicators\")\n .description(\"List indicators, or read one\")\n .argument(\"[name]\", \"Indicator name; omit to list\"),\n).action(async (name: string | undefined, options: Record<string, string>) => {\n const { indicatorsCommand, indicatorCommand } = await import(\"./ops.js\");\n settle(\n name === undefined\n ? await indicatorsCommand(options)\n : await indicatorCommand(name, options),\n );\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\nawait program.parseAsync();\n"]}
@@ -0,0 +1,2 @@
1
+ import {b,a}from'./chunk-OKX5YME7.js';import {parseRuntimeVersion,compareRuntimeVersion}from'@routecraft/routecraft';var n={major:1,minor:1,patch:0};function p(e=process.versions.bun??null){let r=e;if(!r)return {ok:false,message:b};let o=parseRuntimeVersion(r);return o===void 0?{ok:false,message:`[routecraft] Could not parse Bun version "${r}". Routecraft requires Bun ${u(n)} or later. Upgrade Bun: ${a}.`}:compareRuntimeVersion(o,n)<0?{ok:false,message:`[routecraft] Bun ${r} is not supported. Routecraft requires Bun ${u(n)} or later. Upgrade Bun: ${a}.`}:{ok:true}}function u(e){return `${e.major}.${e.minor}.${e.patch}`}export{p as checkBunRuntime};//# sourceMappingURL=runtime-gate-NEYB2HPB.js.map
2
+ //# sourceMappingURL=runtime-gate-NEYB2HPB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime-gate.ts"],"names":["MIN_BUN_VERSION","checkBunRuntime","bunVersion","version","MISSING_BUN_MESSAGE","parsed","parseRuntimeVersion","formatVersion","INSTALL_URL","compareRuntimeVersion","v"],"mappings":"qHAqBA,IAAMA,CAAAA,CAAkC,CAAE,KAAA,CAAO,CAAA,CAAG,MAAO,CAAA,CAAG,KAAA,CAAO,CAAE,CAAA,CAQhE,SAASC,EACdC,CAAAA,CAA4B,OAAA,CAAQ,QAAA,CAAS,GAAA,EAAU,IAAA,CACpC,CACnB,IAAMC,CAAAA,CAAUD,CAAAA,CAEhB,GAAI,CAACC,CAAAA,CACH,OAAO,CACL,EAAA,CAAI,MACJ,OAAA,CAASC,CACX,EAGF,IAAMC,CAAAA,CAASC,oBAAoBH,CAAO,CAAA,CAE1C,OAAIE,CAAAA,GAAW,MAAA,CACN,CACL,EAAA,CAAI,KAAA,CACJ,OAAA,CACE,6CAA6CF,CAAO,CAAA,2BAAA,EACzBI,EAAcP,CAAe,CAAC,2BACzCQ,CAAW,CAAA,CAAA,CAC/B,EAGEC,qBAAAA,CAAsBJ,CAAAA,CAAQL,CAAe,CAAA,CAAI,CAAA,CAC5C,CACL,EAAA,CAAI,KAAA,CACJ,QACE,CAAA,iBAAA,EAAoBG,CAAO,CAAA,2CAAA,EACAI,CAAAA,CAAcP,CAAe,CAAC,2BACzCQ,CAAW,CAAA,CAAA,CAC/B,EAGK,CAAE,EAAA,CAAI,IAAK,CACpB,CAEA,SAASD,CAAAA,CAAcG,CAAAA,CAA2B,CAChD,OAAO,CAAA,EAAGA,EAAE,KAAK,CAAA,CAAA,EAAIA,EAAE,KAAK,CAAA,CAAA,EAAIA,CAAAA,CAAE,KAAK,CAAA,CACzC","file":"runtime-gate-NEYB2HPB.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 * The version itself is read by `parseRuntimeVersion` from core, shared\n * with the ops client's own Bun check: written twice, the two parsers\n * disagreed on the same string within one release.\n */\n\nimport {\n compareRuntimeVersion,\n parseRuntimeVersion,\n type RuntimeVersion,\n} from \"@routecraft/routecraft\";\nimport { INSTALL_URL, MISSING_BUN_MESSAGE } from \"./bun-requirement.js\";\n\nconst MIN_BUN_VERSION: RuntimeVersion = { major: 1, minor: 1, patch: 0 };\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: MISSING_BUN_MESSAGE,\n };\n }\n\n const parsed = parseRuntimeVersion(version);\n\n if (parsed === undefined) {\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 if (compareRuntimeVersion(parsed, MIN_BUN_VERSION) < 0) {\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: RuntimeVersion): string {\n return `${v.major}.${v.minor}.${v.patch}`;\n}\n"]}
package/dist/tui/app.js CHANGED
@@ -1,4 +1,4 @@
1
- import {a}from'../chunk-ILBYIHLE.js';import {a as a$1}from'../chunk-2EEA43OX.js';import {useState,useCallback,useEffect,useMemo,Fragment as Fragment$1}from'react';import {useApp,useStdout,useInput,Box,Text,render}from'ink';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var Ut=[{items:[{key:"capabilities",label:"Capabilities",shortcut:"1"}]},{items:[{key:"agents",label:"Agents",shortcut:"2"},{key:"tools",label:"Tools",shortcut:"3"}]},{items:[{key:"exchanges",label:"Exchanges",shortcut:"4"},{key:"errors",label:"Errors",shortcut:"5"},{key:"events",label:"Events",shortcut:"6"}]}],Xt=Ut.flatMap(e=>e.items);function Re(e,t){return t<=0?"":e.length>t?e.slice(0,t-1)+"\u2026":e}function M(e){return e==null||!Number.isFinite(e)||e<0?"-":e===0?"<1ms":e<1e3?`${Math.round(e)}ms`:`${(e/1e3).toFixed(1)}s`}function Z(e){switch(e){case "completed":case "started":case "finished":case "running":return "green";case "failed":case "error":return "red";case "stopped":case "dropped":return "yellow";default:return "white"}}function vo(e){return e<1e5?ee(e):e<1e6?`${Math.round(e/1e3)}k`:`${(e/1e6).toFixed(1)}M`}function Ye(e){switch(e){case "result":return "green";case "error":return "red";default:return "yellow"}}function R(e,t){return t===void 0?e:t<=0?"":e.length>t?e.slice(0,t-1)+"\u2026":e.padEnd(t)}function ln(e){try{let t=JSON.parse(e),o="exchangeId"in t?`${String(t.exchangeId).slice(0,8)}`:"",l="duration"in t?M(t.duration):"";if("operation"in t&&"routeId"in t){let s="adapter"in t?`(${t.adapter})`:"adapterId"in t?`(${t.adapterId})`:"",n="";if("metadata"in t&&typeof t.metadata=="object"&&t.metadata!==null){let f=t.metadata,m=Object.keys(f).slice(0,2);m.length>0&&(n=m.map(g=>`${g}=${f[g]}`).join(" "));}return {step:String(t.operation),adapter:s,exchange:o,duration:l,meta:n}}if("routeId"in t&&"exchangeId"in t){let s="error"in t?"(err)":"reason"in t?`(${String(t.reason).slice(0,8)})`:"";return {step:String(t.routeId),adapter:s,exchange:o,duration:l,meta:""}}if("route"in t&&typeof t.route=="object"&&t.route!==null){let s=t.route;return {step:s.routeId??s.definition?.id??"?",adapter:"",exchange:"",duration:"",meta:""}}if("pluginId"in t)return {step:`plugin=${t.pluginId}`,adapter:"",exchange:"",duration:"",meta:""};if("error"in t){let s=t.error;return {step:typeof s=="object"&&s!==null&&"message"in s?String(s.message):String(s),adapter:"",exchange:"",duration:"",meta:""}}return null}catch{return null}}function Io(e,t){let o=ln(t);return o||{step:t,adapter:"",exchange:"",duration:"",meta:""}}function ee(e){return e.toLocaleString("en-US")}function Wt(e,t,o){return o<=0?t:e<t?e:e>=t+o?e-o+1:t}function we(e=0){let[t,o]=useState(e),[l,s]=useState(0),n=useCallback((g,u,x)=>{let T=Math.max(0,Math.min(g,u-1));o(T),s(i=>Wt(T,i,x));},[]),f=useCallback((g,u,x)=>{o(T=>{let i=Math.max(0,Math.min(T+g,u-1));return s(h=>Wt(i,h,x)),i});},[]),m=useCallback(()=>{o(0),s(0);},[]);return {selectedIndex:t,scrollOffset:l,moveBy:f,moveTo:n,reset:m}}var c={accent:"#7482ff",accentSoft:"#9ea8fd",success:"green",error:"red",warn:"yellow",muted:"gray"};function _(e){return e?{color:c.accent,bold:true}:{}}function w({title:e,subtitle:t,color:o=c.muted,width:l,flexGrow:s,paddingX:n=1,children:f}){let m=l?l-2-n*2:20;return jsxs(Box,{flexDirection:"column",borderStyle:"single",borderColor:o,paddingX:n,width:l,flexGrow:s,children:[e&&jsxs(Fragment,{children:[jsxs(Text,{bold:true,dimColor:true,children:[e,t&&jsxs(Fragment,{children:[" ",t]})]}),jsx(Text,{dimColor:true,children:"\u2500".repeat(Math.max(m,1))})]}),f]})}var un=[192,36,18,9],dn=10240,ft=[{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 Dt({values:e,columns:t,steps:o=ft,label:l}){let s=o.length-1,n=e.length>=t?e.slice(e.length-t):[...new Array(t-e.length).fill(0),...e],f=n.map(u=>{if(u<=0)return 0;for(let x=1;x<o.length;x++)if(u<o[x].max)return x;return s}),m=Math.ceil(s/4),g=[];for(let u=m-1;u>=0;u--){let x=u*4,T=[];for(let i=0;i<n.length;i++){let h=f[i],p=0,y="";for(let D=0;D<4;D++){let ie=x+D+1;if(ie>s)break;(h>=ie||h===0&&ie===1)&&(p|=un[D],y=h===0?o[0].color:o[ie].color);}let H=String.fromCharCode(dn+p),F=T[T.length-1];F&&F.color===y?F.text+=H:T.push({text:H,color:y});}g.push(jsx(Text,{children:T.map((i,h)=>i.color?jsx(Text,{color:i.color,children:i.text},h):jsx(Text,{children:i.text},h))},u));}return jsxs(Fragment,{children:[g,l&&jsx(Text,{dimColor:true,wrap:"truncate",children:l})]})}function ko({route:e}){return jsxs(Fragment,{children:[jsxs(Text,{wrap:"truncate",children:["Capability:"," ",jsx(Text,{bold:true,color:c.accent,children:e.id})]}),jsxs(Text,{wrap:"truncate",children:["Status:"," ",jsx(Text,{bold:true,color:Z(e.status),children:e.status})," ","Exchanges: ",jsx(Text,{bold:true,children:ee(e.totalExchanges)})," ","Errors:"," ",jsx(Text,{bold:true,...e.failedExchanges>0?{color:"red"}:{},children:ee(e.failedExchanges)})," ","Dropped:"," ",jsx(Text,{bold:true,...e.droppedExchanges>0?{color:"yellow"}:{},children:ee(e.droppedExchanges)})," ","Avg: ",jsx(Text,{bold:true,children:M(e.avgDurationMs)})]})]})}function te({columns:e,data:t,rowKey:o,selectedIndex:l,scrollOffset:s,visibleRows:n,gap:f=2,emptyMessage:m="No data",renderFullRow:g}){let u=" ".repeat(f),x=jsx(Box,{children:e.map((h,p)=>{let H=p===e.length-1?"":u;if(h.width==="flex")return jsxs(Fragment$1,{children:[jsx(Box,{flexGrow:1,flexBasis:0,minWidth:0,children:jsx(Text,{bold:true,dimColor:true,wrap:"truncate",children:h.header})}),H&&jsx(Box,{flexShrink:0,children:jsx(Text,{children:H})})]},p);let F=h.align==="right"?h.header.padStart(h.width):R(h.header,h.width);return jsxs(Box,{flexShrink:0,children:[jsx(Text,{bold:true,dimColor:true,children:F}),H&&jsx(Text,{children:H})]},p)})});if(t.length===0)return jsxs(Fragment,{children:[x,jsx(Text,{dimColor:true,children:m})]});let T=t.slice(s,s+n),i=t.length-s-n;return jsxs(Fragment,{children:[x,T.map((h,p)=>{let y=s+p,H=y===l,F=g?.(h,y);return F!==void 0?jsx(Box,{children:F},o(h,y)):jsx(Box,{children:e.map((D,ie)=>{let v=ie===e.length-1?"":u,j=D.width==="flex"?void 0:D.width,rt=D.render(h,H,j);return D.width==="flex"?jsxs(Fragment$1,{children:[jsx(Box,{flexGrow:1,flexBasis:0,minWidth:0,children:jsx(Text,{wrap:"truncate",children:rt})}),v&&jsx(Box,{flexShrink:0,children:jsx(Text,{children:v})})]},ie):jsxs(Box,{flexShrink:0,children:[rt,v&&jsx(Text,{children:v})]},ie)})},o(h,y))}),jsx(Text,{dimColor:true,children:i>0?"\u2193 more":" "})]})}function kt(e,t={adapter:true,exchange:true}){let o=new WeakMap;function l(s){let n=e(s);if(!n)return;let f=o.get(n);return f||(f=Io(n.eventName,n.details),o.set(n,f)),f}return [{header:"Step",width:10,render:(s,n,f)=>{let m=l(s);return m?jsx(Text,{children:R(m.step,f)}):jsx(Text,{children:R("",f)})}},...t.adapter?[{header:"Adapter",width:10,render:(s,n,f)=>{let m=l(s);return m?jsx(Text,{children:R(m.adapter,f)}):jsx(Text,{children:R("",f)})}}]:[],...t.exchange?[{header:"Exchange",width:12,render:(s,n,f)=>{let m=l(s);return m?jsx(Text,{children:R(m.exchange,f)}):jsx(Text,{children:R("",f)})}}]:[],{header:"Duration",width:8,align:"right",render:s=>{let n=l(s);return n?jsx(Text,{children:n.duration.padStart(8)}):jsx(Text,{children:""})}}]}function oe(){return {header:"",width:2,render:(e,t)=>jsx(Text,{..._(t),children:t?"> ":" "})}}var pn=[oe(),{header:"ID",width:"flex",render:(e,t)=>jsx(Text,{..._(t),children:e.id})},{header:"Status",width:9,render:(e,t,o)=>jsx(Text,{color:Z(e.status),children:R(e.status,o)})},{header:"Duration",width:8,align:"right",render:e=>jsx(Text,{children:M(e.durationMs).padStart(8)})},{header:"Time",width:8,render:(e,t,o)=>jsx(Text,{dimColor:true,children:R(e.startedAt.replace("T"," ").slice(11,19),o)})}];function Lo({capabilityId:e,route:t,exchanges:o,selectedIndex:l,scrollOffset:s,width:n,height:f,color:m=c.muted,activity:g,title:u}){let x=Math.ceil((ft.length-1)/4),T=t?2+x+2:0,i=Math.max(f-6-T,3),h=u??(t?"EXCHANGES":`EXCHANGES: ${e}`);return jsxs(Box,{flexDirection:"column",width:n,flexGrow:1,children:[t&&jsxs(w,{width:n,children:[jsx(ko,{route:t}),jsx(Text,{children:" "}),jsx(Dt,{values:g?g.throughput:[],columns:n-4,label:"Exchanges per 5s bucket"})]}),jsx(w,{title:h,width:n,flexGrow:1,color:m,children:jsx(te,{columns:pn,data:o,rowKey:p=>`${p.id}:${p.contextId}`,selectedIndex:l,scrollOffset:s,visibleRows:i,emptyMessage:"No exchanges"})})]})}function gn(e){let t=[],o=/("(?:[^"\\]|\\.)*")\s*:|("(?:[^"\\]|\\.)*")|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)|(\btrue\b|\bfalse\b)|(\bnull\b)|([{}[\],:])/g,l=0,s;for(;(s=o.exec(e))!==null;)s.index>l&&t.push({text:e.slice(l,s.index),type:"brace"}),s[1]!==void 0?(t.push({text:s[1],type:"key"}),t.push({text:":",type:"brace"})):s[2]!==void 0?t.push({text:s[2],type:"string"}):s[3]!==void 0?t.push({text:s[3],type:"number"}):s[4]!==void 0?t.push({text:s[4],type:"boolean"}):s[5]!==void 0?t.push({text:s[5],type:"null"}):s[6]!==void 0&&t.push({text:s[6],type:"brace"}),l=s.index+s[0].length;return l<e.length&&t.push({text:e.slice(l),type:"brace"}),t}var Tn={key:"white",string:c.accentSoft,number:c.warn,boolean:c.warn,null:c.error,brace:c.muted};function xe(e,t){try{let o=JSON.parse(e);return JSON.stringify(o,null,2).split(`
1
+ import {a}from'../chunk-YFHLDGJC.js';import {a as a$1}from'../chunk-2EEA43OX.js';import {useState,useCallback,useEffect,useMemo,Fragment as Fragment$1}from'react';import {useApp,useStdout,useInput,Box,Text,render}from'ink';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var Ut=[{items:[{key:"capabilities",label:"Capabilities",shortcut:"1"}]},{items:[{key:"agents",label:"Agents",shortcut:"2"},{key:"tools",label:"Tools",shortcut:"3"}]},{items:[{key:"exchanges",label:"Exchanges",shortcut:"4"},{key:"errors",label:"Errors",shortcut:"5"},{key:"events",label:"Events",shortcut:"6"}]}],Xt=Ut.flatMap(e=>e.items);function Re(e,t){return t<=0?"":e.length>t?e.slice(0,t-1)+"\u2026":e}function M(e){return e==null||!Number.isFinite(e)||e<0?"-":e===0?"<1ms":e<1e3?`${Math.round(e)}ms`:`${(e/1e3).toFixed(1)}s`}function Z(e){switch(e){case "completed":case "started":case "finished":case "running":return "green";case "failed":case "error":return "red";case "stopped":case "dropped":return "yellow";default:return "white"}}function vo(e){return e<1e5?ee(e):e<1e6?`${Math.round(e/1e3)}k`:`${(e/1e6).toFixed(1)}M`}function Ye(e){switch(e){case "result":return "green";case "error":return "red";default:return "yellow"}}function R(e,t){return t===void 0?e:t<=0?"":e.length>t?e.slice(0,t-1)+"\u2026":e.padEnd(t)}function ln(e){try{let t=JSON.parse(e),o="exchangeId"in t?`${String(t.exchangeId).slice(0,8)}`:"",l="duration"in t?M(t.duration):"";if("operation"in t&&"routeId"in t){let s="adapter"in t?`(${t.adapter})`:"adapterId"in t?`(${t.adapterId})`:"",n="";if("metadata"in t&&typeof t.metadata=="object"&&t.metadata!==null){let f=t.metadata,m=Object.keys(f).slice(0,2);m.length>0&&(n=m.map(g=>`${g}=${f[g]}`).join(" "));}return {step:String(t.operation),adapter:s,exchange:o,duration:l,meta:n}}if("routeId"in t&&"exchangeId"in t){let s="error"in t?"(err)":"reason"in t?`(${String(t.reason).slice(0,8)})`:"";return {step:String(t.routeId),adapter:s,exchange:o,duration:l,meta:""}}if("route"in t&&typeof t.route=="object"&&t.route!==null){let s=t.route;return {step:s.routeId??s.definition?.id??"?",adapter:"",exchange:"",duration:"",meta:""}}if("pluginId"in t)return {step:`plugin=${t.pluginId}`,adapter:"",exchange:"",duration:"",meta:""};if("error"in t){let s=t.error;return {step:typeof s=="object"&&s!==null&&"message"in s?String(s.message):String(s),adapter:"",exchange:"",duration:"",meta:""}}return null}catch{return null}}function Io(e,t){let o=ln(t);return o||{step:t,adapter:"",exchange:"",duration:"",meta:""}}function ee(e){return e.toLocaleString("en-US")}function Wt(e,t,o){return o<=0?t:e<t?e:e>=t+o?e-o+1:t}function we(e=0){let[t,o]=useState(e),[l,s]=useState(0),n=useCallback((g,u,x)=>{let T=Math.max(0,Math.min(g,u-1));o(T),s(i=>Wt(T,i,x));},[]),f=useCallback((g,u,x)=>{o(T=>{let i=Math.max(0,Math.min(T+g,u-1));return s(h=>Wt(i,h,x)),i});},[]),m=useCallback(()=>{o(0),s(0);},[]);return {selectedIndex:t,scrollOffset:l,moveBy:f,moveTo:n,reset:m}}var c={accent:"#7482ff",accentSoft:"#9ea8fd",success:"green",error:"red",warn:"yellow",muted:"gray"};function _(e){return e?{color:c.accent,bold:true}:{}}function w({title:e,subtitle:t,color:o=c.muted,width:l,flexGrow:s,paddingX:n=1,children:f}){let m=l?l-2-n*2:20;return jsxs(Box,{flexDirection:"column",borderStyle:"single",borderColor:o,paddingX:n,width:l,flexGrow:s,children:[e&&jsxs(Fragment,{children:[jsxs(Text,{bold:true,dimColor:true,children:[e,t&&jsxs(Fragment,{children:[" ",t]})]}),jsx(Text,{dimColor:true,children:"\u2500".repeat(Math.max(m,1))})]}),f]})}var un=[192,36,18,9],dn=10240,ft=[{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 Dt({values:e,columns:t,steps:o=ft,label:l}){let s=o.length-1,n=e.length>=t?e.slice(e.length-t):[...new Array(t-e.length).fill(0),...e],f=n.map(u=>{if(u<=0)return 0;for(let x=1;x<o.length;x++)if(u<o[x].max)return x;return s}),m=Math.ceil(s/4),g=[];for(let u=m-1;u>=0;u--){let x=u*4,T=[];for(let i=0;i<n.length;i++){let h=f[i],p=0,y="";for(let D=0;D<4;D++){let ie=x+D+1;if(ie>s)break;(h>=ie||h===0&&ie===1)&&(p|=un[D],y=h===0?o[0].color:o[ie].color);}let H=String.fromCharCode(dn+p),F=T[T.length-1];F&&F.color===y?F.text+=H:T.push({text:H,color:y});}g.push(jsx(Text,{children:T.map((i,h)=>i.color?jsx(Text,{color:i.color,children:i.text},h):jsx(Text,{children:i.text},h))},u));}return jsxs(Fragment,{children:[g,l&&jsx(Text,{dimColor:true,wrap:"truncate",children:l})]})}function ko({route:e}){return jsxs(Fragment,{children:[jsxs(Text,{wrap:"truncate",children:["Capability:"," ",jsx(Text,{bold:true,color:c.accent,children:e.id})]}),jsxs(Text,{wrap:"truncate",children:["Status:"," ",jsx(Text,{bold:true,color:Z(e.status),children:e.status})," ","Exchanges: ",jsx(Text,{bold:true,children:ee(e.totalExchanges)})," ","Errors:"," ",jsx(Text,{bold:true,...e.failedExchanges>0?{color:"red"}:{},children:ee(e.failedExchanges)})," ","Dropped:"," ",jsx(Text,{bold:true,...e.droppedExchanges>0?{color:"yellow"}:{},children:ee(e.droppedExchanges)})," ","Avg: ",jsx(Text,{bold:true,children:M(e.avgDurationMs)})]})]})}function te({columns:e,data:t,rowKey:o,selectedIndex:l,scrollOffset:s,visibleRows:n,gap:f=2,emptyMessage:m="No data",renderFullRow:g}){let u=" ".repeat(f),x=jsx(Box,{children:e.map((h,p)=>{let H=p===e.length-1?"":u;if(h.width==="flex")return jsxs(Fragment$1,{children:[jsx(Box,{flexGrow:1,flexBasis:0,minWidth:0,children:jsx(Text,{bold:true,dimColor:true,wrap:"truncate",children:h.header})}),H&&jsx(Box,{flexShrink:0,children:jsx(Text,{children:H})})]},p);let F=h.align==="right"?h.header.padStart(h.width):R(h.header,h.width);return jsxs(Box,{flexShrink:0,children:[jsx(Text,{bold:true,dimColor:true,children:F}),H&&jsx(Text,{children:H})]},p)})});if(t.length===0)return jsxs(Fragment,{children:[x,jsx(Text,{dimColor:true,children:m})]});let T=t.slice(s,s+n),i=t.length-s-n;return jsxs(Fragment,{children:[x,T.map((h,p)=>{let y=s+p,H=y===l,F=g?.(h,y);return F!==void 0?jsx(Box,{children:F},o(h,y)):jsx(Box,{children:e.map((D,ie)=>{let v=ie===e.length-1?"":u,j=D.width==="flex"?void 0:D.width,rt=D.render(h,H,j);return D.width==="flex"?jsxs(Fragment$1,{children:[jsx(Box,{flexGrow:1,flexBasis:0,minWidth:0,children:jsx(Text,{wrap:"truncate",children:rt})}),v&&jsx(Box,{flexShrink:0,children:jsx(Text,{children:v})})]},ie):jsxs(Box,{flexShrink:0,children:[rt,v&&jsx(Text,{children:v})]},ie)})},o(h,y))}),jsx(Text,{dimColor:true,children:i>0?"\u2193 more":" "})]})}function kt(e,t={adapter:true,exchange:true}){let o=new WeakMap;function l(s){let n=e(s);if(!n)return;let f=o.get(n);return f||(f=Io(n.eventName,n.details),o.set(n,f)),f}return [{header:"Step",width:10,render:(s,n,f)=>{let m=l(s);return m?jsx(Text,{children:R(m.step,f)}):jsx(Text,{children:R("",f)})}},...t.adapter?[{header:"Adapter",width:10,render:(s,n,f)=>{let m=l(s);return m?jsx(Text,{children:R(m.adapter,f)}):jsx(Text,{children:R("",f)})}}]:[],...t.exchange?[{header:"Exchange",width:12,render:(s,n,f)=>{let m=l(s);return m?jsx(Text,{children:R(m.exchange,f)}):jsx(Text,{children:R("",f)})}}]:[],{header:"Duration",width:8,align:"right",render:s=>{let n=l(s);return n?jsx(Text,{children:n.duration.padStart(8)}):jsx(Text,{children:""})}}]}function oe(){return {header:"",width:2,render:(e,t)=>jsx(Text,{..._(t),children:t?"> ":" "})}}var pn=[oe(),{header:"ID",width:"flex",render:(e,t)=>jsx(Text,{..._(t),children:e.id})},{header:"Status",width:9,render:(e,t,o)=>jsx(Text,{color:Z(e.status),children:R(e.status,o)})},{header:"Duration",width:8,align:"right",render:e=>jsx(Text,{children:M(e.durationMs).padStart(8)})},{header:"Time",width:8,render:(e,t,o)=>jsx(Text,{dimColor:true,children:R(e.startedAt.replace("T"," ").slice(11,19),o)})}];function Lo({capabilityId:e,route:t,exchanges:o,selectedIndex:l,scrollOffset:s,width:n,height:f,color:m=c.muted,activity:g,title:u}){let x=Math.ceil((ft.length-1)/4),T=t?2+x+2:0,i=Math.max(f-6-T,3),h=u??(t?"EXCHANGES":`EXCHANGES: ${e}`);return jsxs(Box,{flexDirection:"column",width:n,flexGrow:1,children:[t&&jsxs(w,{width:n,children:[jsx(ko,{route:t}),jsx(Text,{children:" "}),jsx(Dt,{values:g?g.throughput:[],columns:n-4,label:"Exchanges per 5s bucket"})]}),jsx(w,{title:h,width:n,flexGrow:1,color:m,children:jsx(te,{columns:pn,data:o,rowKey:p=>`${p.id}:${p.contextId}`,selectedIndex:l,scrollOffset:s,visibleRows:i,emptyMessage:"No exchanges"})})]})}function gn(e){let t=[],o=/("(?:[^"\\]|\\.)*")\s*:|("(?:[^"\\]|\\.)*")|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)|(\btrue\b|\bfalse\b)|(\bnull\b)|([{}[\],:])/g,l=0,s;for(;(s=o.exec(e))!==null;)s.index>l&&t.push({text:e.slice(l,s.index),type:"brace"}),s[1]!==void 0?(t.push({text:s[1],type:"key"}),t.push({text:":",type:"brace"})):s[2]!==void 0?t.push({text:s[2],type:"string"}):s[3]!==void 0?t.push({text:s[3],type:"number"}):s[4]!==void 0?t.push({text:s[4],type:"boolean"}):s[5]!==void 0?t.push({text:s[5],type:"null"}):s[6]!==void 0&&t.push({text:s[6],type:"brace"}),l=s.index+s[0].length;return l<e.length&&t.push({text:e.slice(l),type:"brace"}),t}var Tn={key:"white",string:c.accentSoft,number:c.warn,boolean:c.warn,null:c.error,brace:c.muted};function xe(e,t){try{let o=JSON.parse(e);return JSON.stringify(o,null,2).split(`
2
2
  `).map(s=>{let n=Math.max(1,t);return s.length>n?s.slice(0,Math.max(0,n-1))+"\u2026":s})}catch{let o=Math.max(1,t);return e.split(`
3
3
  `).map(l=>l.length>o?l.slice(0,Math.max(0,o-1))+"\u2026":l)}}function et({line:e}){let t=gn(e);return t.length===0?jsx(Text,{children:e}):jsx(Text,{children:t.map((o,l)=>jsx(Text,{color:Tn[o.type],children:o.text},l))})}function At(e){try{let t=JSON.parse(e);return typeof t!="object"||t===null||Array.isArray(t)?null:t}catch{return null}}function En(e,t){let o=new Map,l=0;o.set(t,{exchangeId:t,label:"parent",events:[]});for(let s of e){let n=At(s.details),f=n?String(n.exchangeId??""):"",m=!f||f===t?t:f;o.has(m)||(l++,o.set(m,{exchangeId:m,label:`child ${l}`,events:[]})),o.get(m).events.push(s);}return Array.from(o.values())}function Rn(e){return [oe(),{header:"Time",width:10,render:(t,o,l)=>{if(!t.event)return jsx(Text,{children:R("",l)});let s=" ".repeat(t.indent);return jsx(Text,{dimColor:true,children:R(s+t.event.timestamp.replace("T"," ").slice(11,19),l)})}},{header:"Event",width:"flex",render:t=>t.event?jsx(Text,{children:t.event.eventName}):jsx(Text,{})},...kt(t=>t.event,{adapter:e>=80,exchange:e>=68})]}function _o({exchange:e,events:t,width:o,height:l,scrollOffset:s,selectedIndex:n=-1,color:f=c.muted}){let m=e.error?2:0,g=Math.max(l-9-m,3),u=useMemo(()=>Rn(o-4),[o]),x=En(t,e.id),T=x.length>1,i=[];for(let p of x){T&&i.push({type:"header",text:`${p.label} (${p.exchangeId.slice(0,8)}) - ${p.events.length} events`,indent:0});for(let y of p.events)i.push({type:"event",event:y,indent:T?2:0});}let h=T?`EXCHANGE FLOW (${x.length} exchanges, ${t.length} events)`:`RELATED EVENTS (${t.length})`;return jsxs(Box,{flexDirection:"column",width:o,flexGrow:1,children:[jsxs(w,{width:o,children:[jsxs(Text,{children:["Capability:"," ",jsx(Text,{bold:true,color:c.accent,children:e.routeId})]}),jsxs(Text,{children:["Exchange:"," ",jsx(Text,{bold:true,color:c.accent,children:Re(e.id,o-14)})]}),jsxs(Text,{children:["Status:"," ",jsx(Text,{bold:true,color:Z(e.status),children:e.status}),e.durationMs!==null&&jsxs(Text,{children:[" ","Duration:"," ",jsx(Text,{bold:true,children:M(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(w,{title:h,width:o,flexGrow:1,color:f,children:jsx(te,{columns:u,data:i,rowKey:(p,y)=>p.type==="header"?`h-${y}`:`${p.event?.id??p.event?.timestamp}-${y}`,selectedIndex:n,scrollOffset:s,visibleRows:g,emptyMessage:"No related events found",renderFullRow:p=>p.type==="header"?jsx(Text,{bold:true,color:c.accent,children:p.text}):void 0})})]})}function Cn(e){return [oe(),{header:"Time",width:8,render:(t,o,l)=>jsx(Text,{..._(o),children:R(t.timestamp.replace("T"," ").slice(11,19),l)})},{header:"Event",width:"flex",render:t=>jsx(Text,{children:t.eventName})},...kt(t=>t,{adapter:e>=80,exchange:e>=68})]}function Po({events:e,selectedIndex:t,scrollOffset:o,width:l,height:s,color:n=c.muted}){let f=Math.max(s-6,5),m=useMemo(()=>Cn(l-4),[l]);return jsx(w,{title:"EVENTS",subtitle:jsxs(Text,{dimColor:true,children:["(",e.length," total)"]}),width:l,flexGrow:1,color:n,children:jsx(te,{columns:m,data:e,rowKey:(g,u)=>g.id!==void 0?String(g.id):`${g.timestamp}-${u}`,selectedIndex:t,scrollOffset:o,visibleRows:f,emptyMessage:"No events recorded yet."})})}function $o({event:e,width:t,height:o,scrollOffset:l,color:s=c.accent}){let n=At(e.details),f=n&&typeof n.routeId=="string"?n.routeId:void 0,m=n&&typeof n.exchangeId=="string"?n.exchangeId:void 0,u=2+(1+(f?1:0)+(m?1:0)+2),x=5,T=Math.max(t-6,20),i=xe(e.details,T),h=Math.max(o-u-x,3),p=Math.max(0,Math.min(l,Math.max(i.length-h,0))),y=i.slice(p,p+h);return jsxs(Box,{flexDirection:"column",width:t,flexGrow:1,children:[jsxs(w,{width:t,children:[jsxs(Text,{children:["Context:"," ",jsx(Text,{bold:true,color:c.accent,children:e.contextId})]}),f&&jsxs(Text,{children:["Capability:"," ",jsx(Text,{bold:true,color:c.accent,children:f})]}),m&&jsxs(Text,{children:["Exchange:"," ",jsx(Text,{bold:true,color:c.accent,children:m})]}),jsxs(Text,{children:["Event:"," ",jsx(Text,{bold:true,color:c.accent,children:e.eventName})]}),jsxs(Text,{children:["Time: ",jsx(Text,{bold:true,children:e.timestamp.replace("T"," ")})]})]}),jsxs(w,{title:"DETAILS",subtitle:jsxs(Text,{dimColor:true,children:["(",p+1,"-",Math.min(p+h,i.length),"/",i.length," lines)"]}),width:t,flexGrow:1,color:s,children:[y.map((H,F)=>jsx(et,{line:H},p+F)),y.length<h&&Array.from({length:h-y.length}).map((H,F)=>jsx(Text,{children:" "},`pad-${F}`))]})]})}function Mn(e,t){let o=[];return o.push("HEADERS"),o.push(...xe(e.headers,t)),o.push(""),o.push("BODY"),e.body!==null?(o.push(...xe(e.body,t)),e.truncated&&(o.push(""),o.push("[Body truncated to configured limit]"))):o.push("[null]"),o}function Go({exchange:e,snapshot:t,width:o,height:l,scrollOffset:s,color:n=c.accent}){let g=Math.max(o-6,20),u=Math.max(l-5-5,3),T=t!==null?Mn(t,g):["[Snapshots not captured]","","Enable with:"," telemetry({ sqlite: { captureSnapshots: true } })"],i=Math.max(0,Math.min(s,Math.max(T.length-u,0))),h=T.slice(i,i+u);return jsxs(Box,{flexDirection:"column",width:o,flexGrow:1,children:[jsxs(w,{width:o,children:[jsxs(Text,{children:["Capability:"," ",jsx(Text,{bold:true,color:c.accent,children:e.routeId})]}),jsxs(Text,{children:["Exchange:"," ",jsx(Text,{bold:true,color:c.accent,children:Re(e.id,o-14)})]}),jsxs(Text,{children:["Status:"," ",jsx(Text,{bold:true,color:Z(e.status),children:e.status}),e.durationMs!==null&&jsxs(Text,{children:[" ","Duration:"," ",jsx(Text,{bold:true,children:M(e.durationMs)})]})]})]}),jsxs(w,{title:"EXCHANGE SNAPSHOT",subtitle:jsxs(Text,{dimColor:true,children:["(",i+1,"-",Math.min(i+u,T.length),"/",T.length," lines)"]}),width:o,flexGrow:1,color:n,children:[h.map((p,y)=>p==="HEADERS"||p==="BODY"?jsx(Text,{bold:true,color:c.accent,children:p},i+y):p.startsWith("[")?jsx(Text,{dimColor:true,children:p},i+y):jsx(et,{line:p},i+y)),h.length<u&&Array.from({length:u-h.length}).map((p,y)=>jsx(Text,{children:" "},`pad-${y}`))]})]})}function Lt({items:e,itemKey:t,label:o,dotColor:l,emptyText:s,selectedIndex:n,listOffset:f,visibleRows:m,width:g}){let u=Math.max(0,Math.min(f,Math.max(e.length-m,0)));return jsxs(Fragment,{children:[jsx(Text,{children:" "}),jsx(Text,{bold:true,dimColor:true,children:"\u2500".repeat(g+2)}),e.length===0?jsx(Text,{dimColor:true,children:s}):e.slice(u,u+m).map((x,T)=>{let h=u+T===n;return jsxs(Text,{wrap:"truncate",children:[jsx(Text,{..._(h),children:h?"> ":" "}),jsx(Text,{color:l(x),children:"\u25CF "}),jsx(Text,{..._(h),children:Re(o(x),g-2)})]},t(x))}),e.length>m&&jsxs(Text,{dimColor:true,children:[n+1,"/",e.length]})]})}function Ho({agentKey:e,runs:t,infos:o,selectedIndex:l,scrollOffset:s,width:n,height:f,color:m}){let g=Math.max(f-6,3),u=e?`RUNS: ${e}`:"RUNS",x=n-4>=66,T=[oe(),{header:"Run",width:"flex",render:(i,h)=>jsx(Text,{..._(h),children:i.id})},{header:"Status",width:9,render:(i,h,p)=>{let y=o.get(i.id)?.status??i.status;return jsx(Text,{color:Z(y),children:R(y,p)})}},{header:"Model",width:"flex",render:i=>jsx(Text,{dimColor:true,children:o.get(i.id)?.model??"-"})},{header:"Tokens",width:6,align:"right",render:i=>{let h=o.get(i.id)?.totalTokens;return jsx(Text,{children:(h!=null?vo(h):"-").padStart(6)})}},{header:"Duration",width:8,align:"right",render:i=>jsx(Text,{children:M(i.durationMs).padStart(8)})},...x?[{header:"Time",width:8,render:(i,h,p)=>jsx(Text,{dimColor:true,children:R(i.startedAt.replace("T"," ").slice(11,19),p)})}]:[]];return jsx(Box,{flexDirection:"column",width:n,flexGrow:1,children:jsx(w,{title:u,width:n,flexGrow:1,...m?{color:m}:{},children:jsx(te,{columns:T,data:t,rowKey:i=>`${i.id}:${i.contextId}`,selectedIndex:l,scrollOffset:s,visibleRows:g,emptyMessage:"No runs"})})})}var Nn=[oe(),{header:"Tool",width:"flex",render:(e,t)=>jsx(Text,{..._(t),children:e.toolName})},{header:"Status",width:8,render:(e,t,o)=>jsx(Text,{color:Ye(e.status),children:R(e.status,o)})},{header:"I/O",width:3,render:e=>jsx(Text,{dimColor:true,children:(e.hasInput?"i":"-")+(e.hasOutput?"o":"-")})},{header:"Duration",width:8,align:"right",render:e=>jsx(Text,{children:M(e.durationMs).padStart(8)})}];function Fo({agentKey:e,run:t,info:o,toolCalls:l,selectedIndex:s,scrollOffset:n,width:f,height:m,color:g=c.accent}){let x=Math.max(m-6-6,3),T=o&&(o.inputTokens!==null||o.outputTokens!==null)?`${o.inputTokens??"?"} in / ${o.outputTokens??"?"} out`+(o.totalTokens!==null?` (${o.totalTokens} total)`:""):o&&o.totalTokens!==null?`${o.totalTokens} total`:"-";return jsxs(Box,{flexDirection:"column",width:f,flexGrow:1,children:[jsxs(w,{width:f,children:[jsxs(Text,{children:["Agent:"," ",jsx(Text,{bold:true,color:c.accent,children:e})]}),jsxs(Text,{children:["Model: ",jsx(Text,{bold:true,children:o?.model??"-"})]}),jsxs(Text,{children:["Status:"," ",jsx(Text,{bold:true,color:Z(o?.status??t.status),children:o?.status??t.status}),o?.finishReason&&jsxs(Text,{children:[" ","Finish: ",jsx(Text,{bold:true,children:o.finishReason})]})]}),jsxs(Text,{children:["Tokens: ",jsx(Text,{bold:true,children:T})]})]}),jsx(w,{title:"TOOL CALLS",width:f,flexGrow:1,color:g,children:jsx(te,{columns:Nn,data:l,rowKey:i=>i.toolCallId,selectedIndex:s,scrollOffset:n,visibleRows:x,emptyMessage:"No tool calls"})})]})}function Ln(e){return [oe(),{header:"Route",width:"flex",render:(t,o)=>jsx(Text,{..._(o),children:t.routeId||"-"})},...e>=68?[{header:"Agent",width:12,render:(t,o,l)=>jsx(Text,{dimColor:true,children:R(t.agentName??"-",l)})}]:[],{header:"Status",width:8,render:(t,o,l)=>jsx(Text,{color:Ye(t.status),children:R(t.status,l)})},{header:"Exchange",width:12,render:(t,o,l)=>jsx(Text,{dimColor:true,children:R(t.exchangeId.slice(0,8),l)})},{header:"Duration",width:8,align:"right",render:t=>jsx(Text,{children:M(t.durationMs).padStart(8)})},...e>=82?[{header:"Time",width:8,render:(t,o,l)=>jsx(Text,{dimColor:true,children:R(t.timestamp.slice(11,19),l)})}]:[]]}function jo({toolName:e,calls:t,selectedIndex:o,scrollOffset:l,width:s,height:n,color:f=c.muted}){let m=Math.max(n-6,3),g=e?`TOOL CALLS: ${e}`:"TOOL CALLS";return jsx(Box,{flexDirection:"column",width:s,flexGrow:1,children:jsx(w,{title:g,width:s,flexGrow:1,color:f,children:jsx(te,{columns:Ln(s-4),data:t,rowKey:u=>u.toolCallId,selectedIndex:o,scrollOffset:l,visibleRows:m,emptyMessage:"No tool calls"})})})}function _n(e,t){let o=[];return o.push("INPUT"),e.hasInput&&e.input!==null?o.push(...xe(e.input,t)):o.push("[Not captured - enable snapshots]"),o.push(""),o.push("OUTPUT"),e.status==="invoked"?o.push("[Pending - tool still running or not recorded]"):e.hasOutput&&e.output!==null?o.push(...xe(e.output,t)):e.status==="error"?o.push("[No output - call errored]"):o.push("[Not captured - enable snapshots]"),e.status==="error"?(o.push(""),o.push("ERROR"),e.error!==null?o.push(...xe(e.error,t)):o.push(`[${e.errorName??"Error"} - enable snapshots for details]`)):e.error!==null&&(o.push(""),o.push("ERROR"),o.push(...xe(e.error,t))),o}function Jo({call:e,width:t,height:o,scrollOffset:l,color:s=c.accent}){let m=Math.max(t-6,20),g=Math.max(o-5-5,3),u=_n(e,m),x=Math.max(0,Math.min(l,Math.max(u.length-g,0))),T=u.slice(x,x+g);return jsxs(Box,{flexDirection:"column",width:t,flexGrow:1,children:[jsxs(w,{width:t,children:[jsxs(Text,{children:["Tool:"," ",jsx(Text,{bold:true,color:c.accent,children:Re(e.toolName,t-10)})]}),jsxs(Text,{children:["Exchange:"," ",jsx(Text,{bold:true,color:c.accent,children:Re(e.exchangeId,t-14)})]}),jsxs(Text,{children:["Status:"," ",jsx(Text,{bold:true,color:Ye(e.status),children:e.status}),e.durationMs!==null&&jsxs(Text,{children:[" ","Duration:"," ",jsx(Text,{bold:true,children:M(e.durationMs)})]})]})]}),jsxs(w,{title:"TOOL CALL",subtitle:jsxs(Text,{dimColor:true,children:["(",x+1,"-",Math.min(x+g,u.length),"/",u.length," lines)"]}),width:t,flexGrow:1,color:s,children:[T.map((i,h)=>i==="INPUT"||i==="OUTPUT"||i==="ERROR"?jsx(Text,{bold:true,color:c.accent,children:i},x+h):i.startsWith("[")?jsx(Text,{dimColor:true,children:i},x+h):jsx(et,{line:i},x+h)),T.length<g&&Array.from({length:g-T.length}).map((i,h)=>jsx(Text,{children:" "},`pad-${h}`))]})]})}function Jn(e){return e.failedExchanges>0?c.error:e.totalExchanges>0?c.success:c.warn}function Kn(e){return e.errorCount>0?c.error:e.runCount>0?c.success:c.warn}function Vn(e){return e.errorCount>0?c.error:e.callCount>0?c.success:c.warn}var to=[...Array.from({length:7},(e,t)=>({max:(t+1)*5,color:"green"})),...Array.from({length:7},(e,t)=>({max:35+(t+1)*10,color:"yellow"})),...Array.from({length:6},(e,t)=>({max:105+(t+1)*25,color:"red"}))];function Un(e){let t=Array.from({length:e},(o,l)=>{let s=Math.min(Math.ceil((l+1)*to.length/e)-1,to.length-1);return to[s]});return [{max:0,color:"gray"},...t]}var Ko=new Set(["event","snapshot","tool-call"]);function Uo(e,t){let o=new Map;o.set(t,[]);for(let l of e)try{let s=JSON.parse(l.details),n=String(s.exchangeId??""),f=!n||n===t?t:n;o.has(f)||o.set(f,[]),o.get(f).push(l);}catch{o.get(t).push(l);}return o}function Vo(e,t){let o=Uo(e,t);return e.length+(o.size>1?o.size:0)}function Xn({db:e}){let{exit:t}=useApp(),{stdout:o}=useStdout(),l=o?.columns??80,s=o?.rows??24,[n,f]=useState("capabilities"),[m,g]=useState([]),u=m.at(-1)??"root",[x,T]=useState([]),[i,h]=useState({totalRoutes:0,totalExchanges:0,completedExchanges:0,failedExchanges:0,droppedExchanges:0,errorRate:0,avgDurationMs:null,p90DurationMs:null,p95DurationMs:null,p99DurationMs:null}),[p,y]=useState([]),[H,F]=useState(void 0),D=we(),[ie,U]=useState([]),v=we(),[j,rt]=useState(void 0),[Bt,oo]=useState([]),[no,ro]=useState([]),pe=we(),me=we(),[xt,so]=useState(void 0),[_t,st]=useState(0),[Xo,Wo]=useState(null),[ge,lo]=useState([]),J=we(),[je,io]=useState(void 0),[qo,ao]=useState(null),[zo,co]=useState(new Map),[pt,uo]=useState([]),Te=we(),[Pt,lt]=useState(""),[$t,gt]=useState(false),[Ne,z]=useState(false),[Oe,mo]=useState([]),X=we(),[fo,Tt]=useState([]),Y=we(),[Le,bt]=useState(void 0),be=50,Yo=10,W=useCallback(r=>{g(a=>[...a,r]),st(0);},[]),yt=useCallback(()=>{g(r=>r.slice(0,-1)),st(0);},[]),Xe=Math.max(Math.min(Math.floor(l*.18),26),16),We=Math.max(Math.min(Math.floor(l*.22),30),20),ae=Math.max(l-Xe-We,30),O=Math.max(s-4,10),ye=Math.max(O-10,3),Qo=Math.max(Math.min(O-19,5),1)*4,Et=Math.max(O-6-6,3),it=m.includes("exchange")?j?.id:void 0,ho=m.includes("exchange")?j?.correlationId:void 0,at=m.includes("agent-run")?je?.id:void 0,ct=u==="tool-call"?Le?.toolCallId:void 0,Gt=u==="tool-call"?Le?.toolName:void 0,Ht=ge[J.selectedIndex]?.key,Ft=ge[J.selectedIndex]?.source,xo=Oe[X.selectedIndex]?.name,Je=useCallback((r,a)=>{if(!r){U([]),co(new Map);return}let S=a!==void 0?e.getAgentRuns(r.key,r.source,a):e.getAgentRuns(r.key,r.source);U(S),co(e.getAgentRunInfos(S.map(N=>N.id)));},[e]),jt=useCallback(()=>{try{let r=e.getRouteSummary();T(r),h(e.getMetrics());let a=We-4;y(e.getLiveTrafficBuckets(a,5));let S=ae-4,N=r[D.selectedIndex];N&&F(e.getSingleRouteActivity(N.id,S,5));let L,B;m.length===0&&(n==="agents"?(L=e.getAgents(),lo(L)):n==="tools"&&(B=e.getTools(),mo(B)));let Be=m.at(-1);if(it){let d=e.getExchangeById(it);d&&rt(d);let $=e.getEventsByExchange(it,ho??"");if(oo($),Ne&&Be==="exchange"){let Ke=d?.error?2:0,ze=Math.max(O-9-Ke,3),he=Vo($,it);me.moveTo(he-1,he,ze);}}if(at){let d=e.getExchangeById(at);d&&io(d),ao(e.getAgentRunInfo(at));let $=e.getAgentRunToolCalls(at);if(uo($),Ne&&Be==="agent-run"&&Te.moveTo($.length-1,$.length,Et),ct){let Ke=$.find(ze=>ze.toolCallId===ct);Ke&&bt(Ke);}}else if(ct&&Gt){let d=e.getToolCalls(Gt).find($=>$.toolCallId===ct);d&&bt(d);}if(m.length>0&&!(Ne&&Be==="browse"))return;if(n==="capabilities"){let d=r[D.selectedIndex];d&&U(e.getExchangesByRoute(d.id,be));}else if(n==="agents"){let d=L?L[J.selectedIndex]:Ht&&Ft?{key:Ht,source:Ft}:void 0;Je(d,be);}else if(n==="tools"){let d=B?B[X.selectedIndex]?.name:xo;Tt(d?e.getToolCalls(d):[]);}else n==="exchanges"?U(e.getAllExchanges(be)):n==="errors"?U(e.getFailedExchanges(be)):n==="events"&&ro(e.getRecentEvents({limit:200}));}catch{}},[e,n,D.selectedIndex,J.selectedIndex,X.selectedIndex,We,ae,O,Et,m,Ne,Je,it,ho,at,ct,Gt,Ht,Ft,xo,me.moveTo,Te.moveTo]);useEffect(()=>{jt();let r=setInterval(jt,2e3);return ()=>{clearInterval(r);}},[jt]);let po=useCallback(r=>{D.moveTo(r,x.length,ye),v.reset();let a=x[r];a&&U(e.getExchangesByRoute(a.id,be));},[e,x,D,v,ye]),go=useCallback(r=>{J.moveTo(r,ge.length,ye),v.reset(),Je(ge[r],be);},[ge,J,v,ye,Je]),To=useCallback(r=>{X.moveTo(r,Oe.length,ye),Y.reset();let a=Oe[r];a&&Tt(e.getToolCalls(a.name));},[e,Oe,X,Y,ye]),Zo=useCallback(r=>{if(f(r),g([]),st(0),lt(""),gt(false),z(false),v.reset(),r==="agents"){J.reset();let a=e.getAgents();lo(a),Je(a[0],be);}else if(r==="tools"){X.reset(),Y.reset();let a=e.getTools();mo(a);let S=a[0];Tt(S?e.getToolCalls(S.name):[]);}else r==="exchanges"?U(e.getAllExchanges(be)):r==="errors"?U(e.getFailedExchanges(be)):r==="events"&&(pe.reset(),ro(e.getRecentEvents({limit:200})));},[e,v,pe,J,X,Y,Je]),ut=Pt.trim().toLowerCase(),Jt=(...r)=>ut===""||r.some(a=>a!==null&&a.toLowerCase().includes(ut)),Ee=ut?ie.filter(r=>Jt(r.id,r.routeId,r.status)):ie,dt=ut?fo.filter(r=>Jt(r.toolName,r.routeId,r.exchangeId,r.status)):fo,Rt=ut?no.filter(r=>Jt(r.eventName,r.details)):no,wt=useCallback(()=>{v.reset(),Y.reset(),pe.reset();},[v,Y,pe]),qe=x[D.selectedIndex],Ct=ge[J.selectedIndex],Kt=Oe[X.selectedIndex],en=Math.ceil((ft.length-1)/4),tn=qe?2+en+2:0,bo=Math.max(O-6-tn,3),yo=Math.max(O-6,5),vt=Math.max(O-6,3),mt=useCallback(r=>{rt(r),oo(e.getEventsByExchange(r.id,r.correlationId)),me.reset(),z(r.status==="started"),W("exchange");},[e,me,W]),Eo=useCallback(r=>{if(!r.exchangeId)return;let a=e.getExchangeById(r.exchangeId)??{id:r.exchangeId,routeId:r.routeId,contextId:"",correlationId:"",status:"started",startedAt:r.timestamp,completedAt:null,durationMs:null,error:null};mt(a);},[e,mt]);useInput((r,a)=>{if($t){a.return?gt(false):a.escape?(gt(false),lt(""),wt()):a.backspace||a.delete?(lt(d=>d.slice(0,-1)),wt()):r&&!a.ctrl&&!a.meta&&(lt(d=>d+r),wt());return}if(r==="q"){e.close(),t();return}let S=Xt.find(d=>d.shortcut===r);if(S){Zo(S.key);return}let N=a.ctrl?Yo:1,L=r==="j"||a.downArrow,B=r==="k"||a.upArrow,Be=a.escape||a.backspace||a.delete;if(u==="browse"){if(r==="/"){gt(true);return}if(r==="f"){z(d=>!d);return}if((L||B)&&Ne&&z(false),Be){yt(),lt(""),z(false),wt();return}}if(u!=="root"&&Ko.has(u)){if(r==="x"&&u==="tool-call"&&Le){Eo(Le);return}L?st(d=>d+N):B?st(d=>Math.max(d-N,0)):Be&&yt();return}if(u==="agent-run"){if(r==="f"){z(d=>!d);return}if(r==="x"&&je){mt(je);return}if((L||B)&&Ne&&z(false),L)Te.moveBy(N,pt.length,Et);else if(B)Te.moveBy(-N,pt.length,Et);else if(a.return){let d=pt[Te.selectedIndex];d&&(bt(d),W("tool-call"));}else Be&&(yt(),z(false),Te.reset());return}if(u==="exchange"){if(r==="f"){z(he=>!he);return}(L||B)&&Ne&&z(false);let d=j?.error?2:0,$=Math.max(O-9-d,3),Ke=j?.id??"",ze=Vo(Bt,Ke);if(L)me.moveBy(N,ze,$);else if(B)me.moveBy(-N,ze,$);else if(a.return){let he=0,Vt,Ro=Uo(Bt,Ke),nn=Ro.size>1;for(let[,rn]of Ro){nn&&he++;for(let sn of rn)he===me.selectedIndex&&(Vt=sn),he++;}Vt&&(so(Vt),W("event"));}else if(r==="e"&&j){let he=e.getExchangeSnapshot(j.id);Wo(he),W("snapshot");}else Be&&(me.reset(),z(false),yt());return}if(n==="events"){if(u==="root"){a.return&&W("browse");return}if(L)pe.moveBy(N,Rt.length,yo);else if(B)pe.moveBy(-N,Rt.length,yo);else if(a.return){let d=Rt[pe.selectedIndex];d&&(so(d),W("event"));}return}if(n==="agents"){if(u==="root"){L?go(Math.min(J.selectedIndex+1,ge.length-1)):B?go(Math.max(J.selectedIndex-1,0)):a.return&&(W("browse"),Je(ge[J.selectedIndex]));return}if(L)v.moveBy(N,Ee.length,vt);else if(B)v.moveBy(-N,Ee.length,vt);else if(a.return){let d=Ee[v.selectedIndex];if(d){io(d);let $=e.getAgentRunInfo(d.id);ao($),uo(e.getAgentRunToolCalls(d.id)),Te.reset(),z(d.status==="started"||$?.status==="running"),W("agent-run");}}else if(r==="x"){let d=Ee[v.selectedIndex];d&&mt(d);}return}if(n==="tools"){if(u==="root"){if(L)To(Math.min(X.selectedIndex+1,Oe.length-1));else if(B)To(Math.max(X.selectedIndex-1,0));else if(a.return){W("browse");let d=Oe[X.selectedIndex];d&&Tt(e.getToolCalls(d.name));}return}if(L)Y.moveBy(N,dt.length,vt);else if(B)Y.moveBy(-N,dt.length,vt);else if(a.return){let d=dt[Y.selectedIndex];d&&(bt(d),W("tool-call"));}else if(r==="x"){let d=dt[Y.selectedIndex];d&&Eo(d);}return}if(u==="root"){if(n==="capabilities"){if(L)po(Math.min(D.selectedIndex+1,x.length-1));else if(B)po(Math.max(D.selectedIndex-1,0));else if(a.return){W("browse");let d=x[D.selectedIndex];d&&U(e.getExchangesByRoute(d.id));}}else a.return&&(W("browse"),U(n==="exchanges"?e.getAllExchanges():e.getFailedExchanges()));return}if(L)v.moveBy(N,Ee.length,bo);else if(B)v.moveBy(-N,Ee.length,bo);else if(a.return){let d=Ee[v.selectedIndex];d&&mt(d);}});let on=(n==="capabilities"||n==="agents"||n==="tools")&&u==="root",q=u==="browse",E=[];u!=="root"&&Ko.has(u)?(E.push({key:"j/k",action:"Scroll"}),E.push({key:"C-j/k",action:"Jump"}),u==="tool-call"&&E.push({key:"x",action:"Exchange"}),E.push({key:"Esc",action:"Back"})):u==="agent-run"?(E.push({key:"j/k",action:"Navigate"}),E.push({key:"Enter",action:"Tool I/O"}),E.push({key:"x",action:"Exchange"}),E.push({key:"f",action:"Follow"}),E.push({key:"Esc",action:"Back"})):u==="exchange"?(E.push({key:"j/k",action:"Navigate"}),E.push({key:"Enter",action:"Event"}),E.push({key:"e",action:"Snapshot"}),E.push({key:"f",action:"Follow"}),E.push({key:"Esc",action:"Back"})):q?(E.push({key:"j/k",action:"Navigate"}),E.push({key:"C-j/k",action:"Jump"}),E.push({key:"Enter",action:"Detail"}),(n==="agents"||n==="tools")&&E.push({key:"x",action:"Exchange"}),E.push({key:"/",action:"Filter"}),E.push({key:"f",action:"Follow"}),E.push({key:"Esc",action:"Back"})):(E.push({key:"j/k",action:"Navigate"}),n==="capabilities"?E.push({key:"Enter",action:"Exchanges"}):n==="agents"?E.push({key:"Enter",action:"Runs"}):n==="tools"?E.push({key:"Enter",action:"Calls"}):E.push({key:"Enter",action:"Browse"})),E.push({key:"1-6",action:"View"}),E.push({key:"q",action:"Quit"});let Q=[];{let r=Xt.find(a=>a.key===n)?.label??n;Q.push(r),m.length>0&&(n==="capabilities"&&qe?Q.push(qe.id):n==="agents"&&Ct?Q.push(Ct.key):n==="tools"&&Kt&&Q.push(Kt.name));for(let a of m)a==="exchange"&&j?Q.push(j.id.slice(0,8)):a==="agent-run"&&je?Q.push(`run ${je.id.slice(0,8)}`):a==="tool-call"&&Le?Q.push(Le.toolName):a==="event"&&xt?Q.push(xt.eventName):a==="snapshot"&&Q.push("snapshot");}let fe;return u==="event"&&xt?fe=jsx($o,{event:xt,width:ae,height:O,scrollOffset:_t}):u==="snapshot"&&j?fe=jsx(Go,{exchange:j,snapshot:Xo,width:ae,height:O,scrollOffset:_t}):u==="tool-call"&&Le?fe=jsx(Jo,{call:Le,width:ae,height:O,scrollOffset:_t}):u==="agent-run"&&je?fe=jsx(Fo,{agentKey:Ct?.key??"",run:je,info:qo,toolCalls:pt,selectedIndex:Te.selectedIndex,scrollOffset:Te.scrollOffset,width:ae,height:O}):u==="exchange"&&j?fe=jsx(_o,{exchange:j,events:Bt,width:ae,height:O,selectedIndex:me.selectedIndex,scrollOffset:me.scrollOffset,color:c.accent}):n==="events"?fe=jsx(Po,{events:Rt,selectedIndex:q?pe.selectedIndex:-1,scrollOffset:q?pe.scrollOffset:0,width:ae,height:O,color:q?c.accent:c.muted}):n==="agents"?fe=jsx(Ho,{agentKey:Ct?.key??"",runs:Ee,infos:zo,selectedIndex:q?v.selectedIndex:-1,scrollOffset:q?v.scrollOffset:0,width:ae,height:O,color:q?c.accent:c.muted}):n==="tools"?fe=jsx(jo,{toolName:Kt?.name??"",calls:dt,selectedIndex:q?Y.selectedIndex:-1,scrollOffset:q?Y.scrollOffset:0,width:ae,height:O,color:q?c.accent:c.muted}):fe=jsx(Lo,{capabilityId:n==="capabilities"?qe?.id??"":n==="exchanges"?"All Capabilities":"Failed Exchanges",...n==="capabilities"&&qe?{route:qe}:{},activity:n==="capabilities"?H:void 0,exchanges:Ee,selectedIndex:q?v.selectedIndex:-1,scrollOffset:q?v.scrollOffset:0,width:ae,height:O,color:q?c.accent:c.muted}),jsxs(Box,{flexDirection:"column",width:l,height:s,children:[jsxs(Box,{paddingX:1,width:l,children:[jsx(Text,{bold:true,children:"Routecraft"}),jsxs(Text,{dimColor:true,children:[" ","craft tui"," ","v",a]}),jsx(Box,{flexGrow:1,justifyContent:"flex-end",children:jsx(Text,{wrap:"truncate",children:Q.map((r,a)=>jsxs(Text,{children:[a>0&&jsx(Text,{dimColor:true,children:" \u203A "}),jsx(Text,{...a===Q.length-1&&Q.length>1?{color:c.accent}:{dimColor:true},children:r})]},`${r}-${a}`))})})]}),jsxs(Box,{flexDirection:"row",width:l,flexGrow:1,children:[jsx(Box,{flexDirection:"column",width:Xe,children:jsxs(w,{title:"NAVIGATION",color:on?c.accent:c.muted,width:Xe,flexGrow:1,children:[Ut.map((r,a)=>jsxs(Box,{flexDirection:"column",children:[a>0&&jsx(Text,{children:" "}),r.label&&jsx(Text,{dimColor:true,bold:true,children:r.label}),r.items.map(S=>jsxs(Text,{wrap:"truncate",children:[jsxs(Text,{..._(n===S.key),children:[n===S.key?"> ":" ",S.label]}),jsxs(Text,{dimColor:true,children:[" (",S.shortcut,")"]}),S.key==="errors"&&i.failedExchanges>0&&jsxs(Text,{color:c.error,children:[" ",ee(i.failedExchanges)]})]},S.key))]},r.label??a)),n==="capabilities"&&jsx(Lt,{items:x,itemKey:r=>r.id,label:r=>r.id,dotColor:Jn,emptyText:"No capabilities",selectedIndex:D.selectedIndex,listOffset:D.scrollOffset,visibleRows:ye,width:Xe-6}),n==="agents"&&jsx(Lt,{items:ge,itemKey:r=>r.key,label:r=>r.key,dotColor:Kn,emptyText:"No agents",selectedIndex:J.selectedIndex,listOffset:J.scrollOffset,visibleRows:ye,width:Xe-6}),n==="tools"&&jsx(Lt,{items:Oe,itemKey:r=>r.name,label:r=>r.name,dotColor:Vn,emptyText:"No tools",selectedIndex:X.selectedIndex,listOffset:X.scrollOffset,visibleRows:ye,width:Xe-6})]})}),fe,jsx(Box,{flexDirection:"column",width:We,children:jsxs(w,{title:"METRICS",width:We,flexGrow:1,children:[jsx(Dt,{values:p,columns:We-4,steps:Un(Qo),label:"Exchanges per 5s bucket"}),jsx(Text,{children:" "}),jsx(Text,{bold:true,dimColor:true,children:"THROUGHPUT"}),[["Exchanges",ee(i.totalExchanges),c.accent],["Completed",ee(i.completedExchanges),"green"],["Errors",ee(i.failedExchanges),i.failedExchanges>0?"red":"green"],["Dropped",ee(i.droppedExchanges),i.droppedExchanges>0?"yellow":"green"],["Error Rate",`${(i.errorRate*100).toFixed(1)}%`,i.errorRate>.1?"red":"green"],["Capabilities",ee(i.totalRoutes),""]].map(([r,a,S])=>jsxs(Box,{children:[jsx(Box,{flexGrow:1,children:jsxs(Text,{wrap:"truncate",children:[r,":"]})}),jsx(Text,{bold:true,...S?{color:S}:{},children:a})]},r)),jsx(Text,{children:" "}),jsx(Text,{bold:true,dimColor:true,children:"LATENCY (5m)"}),[["Avg",M(i.avgDurationMs),""],["p90",M(i.p90DurationMs),""],["p95",M(i.p95DurationMs),""],["p99",M(i.p99DurationMs),""]].map(([r,a,S])=>jsxs(Box,{children:[jsx(Box,{flexGrow:1,children:jsxs(Text,{wrap:"truncate",children:[r,":"]})}),jsx(Text,{bold:true,...S?{color:S}:{},children:a})]},r))]})})]}),jsx(Box,{paddingX:1,width:l,children:jsxs(Text,{wrap:"truncate",children:[($t||Pt!=="")&&jsxs(Text,{color:c.accent,children:["/",Pt,$t?"\u258F":""," "]}),Ne&&jsxs(Text,{color:c.success,children:["\u25CF follow"," "]}),E.map((r,a)=>jsxs(Text,{children:[a>0&&jsx(Text,{children:" "}),jsx(Text,{color:c.accentSoft,children:r.key}),jsxs(Text,{dimColor:true,children:[" ",r.action]})]},r.key))]})})]})}async function vl(e){let t;try{t=await a$1.open(e);}catch(l){let s=l instanceof Error?l.message:String(l);process.stderr.write(`Failed to open telemetry database: ${s}
4
4
  `),process.stderr.write(`Path: ${e}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@routecraft/cli",
3
- "version": "0.7.0",
3
+ "version": "0.7.1-canary-20260923154637",
4
4
  "description": "CLI for running Routecraft capabilities",
5
5
  "private": false,
6
6
  "type": "module",
@@ -24,7 +24,7 @@
24
24
  "dependencies": {
25
25
  "@agentclientprotocol/sdk": "^1.4.0",
26
26
  "@opentelemetry/sdk-trace-base": "^2.10.0",
27
- "@routecraft/routecraft": "^0.7.0",
27
+ "@routecraft/routecraft": "0.7.1-canary-20260923154637",
28
28
  "agent-browser": "^0.17.1",
29
29
  "cheerio": "^1.2.0",
30
30
  "commander": "^14.0.3",
@@ -1,2 +0,0 @@
1
- var s="0.7.0";export{s as a};//# sourceMappingURL=chunk-ILBYIHLE.js.map
2
- //# sourceMappingURL=chunk-ILBYIHLE.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../package.json"],"names":["version"],"mappings":"AAEE,IAAAA,CAAAA,CAAW","file":"chunk-ILBYIHLE.js","sourcesContent":["{\n \"name\": \"@routecraft/cli\",\n \"version\": \"0.7.0\",\n \"description\": \"CLI for running Routecraft capabilities\",\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 \"@agentclientprotocol/sdk\": \"^1.4.0\",\n \"@opentelemetry/sdk-trace-base\": \"^2.10.0\",\n \"@routecraft/routecraft\": \"^0.7.0\",\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 \"execa\": \"^9.6.0\",\n \"fast-xml-parser\": \"^5.10.1\",\n \"imapflow\": \"^1.4.7\",\n \"ink\": \"^5.2.1\",\n \"jose\": \"^6.2.8\",\n \"mailparser\": \"^3.9.15\",\n \"nodemailer\": \"^6.10.1\",\n \"papaparse\": \"^5.5.4\",\n \"pino-pretty\": \"^13.1.3\",\n \"react\": \"^18.3.1\",\n \"shescape\": \"^3.0.2\",\n \"tsdav\": \"^2.3.1\",\n \"yaml\": \"^2.9.0\"\n },\n \"devDependencies\": {\n \"@types/mailparser\": \"^3.4.6\",\n \"@types/nodemailer\": \"^6.4.24\",\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"]}