UNPKG

kestrel.markets

Version:

A typed, token-efficient language + runtime for agentic trading: agents author bounded plans, the runtime fires them at the tick. CLI + typed library + MCP server.

634 lines (623 loc) 26.3 kB
import { HOSTED_STORE_BASENAME, defaultHostedStorePath, isPlanDigest, readHostedRunsMerged } from "./bin-m9a64j9t.js"; import { loadHeavy } from "./bin-6676fry4.js"; import { parseArgs } from "./bin-1gc4zavq.js"; import { CliError, EXIT } from "./bin-t9ggwnv5.js"; import { __require } from "./bin-wckvcay0.js"; // src/cli/commands/registry.ts import { existsSync } from "node:fs"; import { dirname, join } from "node:path"; // src/cli/render/tables.ts var GREEN = "[32m"; var RED = "[31m"; var DIM = "[2m"; var BOLD = "[1m"; var RESET = "[0m"; function pad(s, w) { return s.length >= w ? s : s + " ".repeat(w - s.length); } function padL(s, w) { return s.length >= w ? s : " ".repeat(w - s.length) + s; } function usd(n) { return (n >= 0 ? "+" : "") + n.toFixed(2); } function shortId(id) { return id.slice(0, 12); } function compactStrategy(strategy) { if (strategy === undefined || strategy === "") return "—"; const head = strategy.split(" — ")[0]; return head.slice(head.lastIndexOf("/") + 1); } function shortDigest(digest) { return isPlanDigest(digest) ? digest.slice(0, 8) : "—"; } function glyphTable(cols, rows, ctx) { const headers = cols.map((c) => c.header); const body = rows.map((r) => cols.map((c) => c.cell(r))); const widths = headers.map((h, c) => Math.max(h.length, ...body.map((row) => (row[c] ?? "").length))); const colorCell = (raw, c, r) => { if (!ctx.color) return raw; const col = cols[c]; if (col.money && col.json !== undefined) { const v = col.json(r); if (typeof v === "number") return v >= 0 ? `${GREEN}${raw}${RESET}` : `${RED}${raw}${RESET}`; } return raw; }; const fmtHeader = headers.map((h, c) => cols[c].right ? padL(h, widths[c]) : pad(h, widths[c])); const headerLine = ctx.color ? fmtHeader.map((h) => `${BOLD}${h}${RESET}`).join(" ") : fmtHeader.join(" "); const sepRaw = widths.map((w) => "─".repeat(w)).join(" "); const sep = ctx.color ? `${DIM}${sepRaw}${RESET}` : sepRaw; const bodyLines = rows.map((r, ri) => cols.map((col, c) => { const raw = body[ri][c]; const padded = col.right ? padL(raw, widths[c]) : pad(raw, widths[c]); return colorCell(padded, c, r); }).join(" ")); return [headerLine, sep, ...bodyLines].join(` `); } function tsv(cols, rows) { return rows.map((r) => cols.map((c) => c.cell(r)).join("\t")).join(` `); } function jsonRowObjs(cols, rows) { return rows.map((r) => { const o = {}; for (const c of cols) o[c.jsonKey] = c.json(r); return sortKeys(o); }); } function jsonRows(schema, cols, rows) { return JSON.stringify({ schema, rows: jsonRowObjs(cols, rows) }); } function sortKeys(o) { const out = {}; for (const k of Object.keys(o).sort()) out[k] = o[k]; return out; } var RUN_COLS = [ { header: "source", right: false, cell: () => "local", jsonKey: "source", json: () => "local" }, { header: "run_id", right: false, cell: (r) => shortId(r.run_id), jsonKey: "run_id", json: (r) => r.run_id }, { header: "date", right: false, cell: (r) => r.session_date, jsonKey: "session_date", json: (r) => r.session_date }, { header: "mode", right: false, cell: (r) => r.mode, jsonKey: "mode", json: (r) => r.mode }, { header: "fill_model", right: false, cell: (r) => r.fill_model, jsonKey: "fill_model", json: (r) => r.fill_model }, { header: "cal", right: false, cell: (r) => r.calibrated ? "✓" : "", jsonKey: "calibrated", json: (r) => Boolean(r.calibrated) }, { header: "realized", right: true, money: true, cell: (r) => usd(r.realized_floor_usd), jsonKey: "realized_floor_usd", json: (r) => r.realized_floor_usd }, { header: "expected", right: true, money: true, cell: (r) => usd(r.expected_usd), jsonKey: "expected_usd", json: (r) => r.expected_usd }, { header: "premium", right: true, cell: (r) => r.premium_spent.toFixed(2), jsonKey: "premium_spent", json: (r) => r.premium_spent }, { header: "events", right: true, cell: (r) => String(r.bus_events), jsonKey: "bus_events", json: (r) => r.bus_events } ]; var HOSTED_COLS = [ { header: "source", right: false, cell: (h) => h.source }, { header: "scenario", right: false, cell: (h) => h.slug }, { header: "strategy", right: false, cell: (h) => compactStrategy(h.strategy) }, { header: "digest", right: false, cell: (h) => shortDigest(h.strategy_digest) }, { header: "operation", right: false, cell: (h) => h.operation_id }, { header: "orders", right: true, cell: (h) => String(h.order_count) }, { header: "fills", right: true, cell: (h) => String(h.fill_count) }, { header: "realized", right: true, money: true, cell: (h) => usd(h.realized_pnl), json: (h) => h.realized_pnl }, { header: "proof", right: false, cell: (h) => h.proof_url } ]; function renderRuns(rows, ctx, hosted = []) { if (ctx.mode === "json") { const local = jsonRowObjs(RUN_COLS, rows); const hostedObjs = hosted.map((h) => sortKeys({ ...h })); return JSON.stringify({ schema: "kestrel.runs/v1", rows: [...local, ...hostedObjs] }) + ` `; } if (ctx.mode === "text") { const parts2 = []; if (rows.length > 0) parts2.push(tsv(RUN_COLS, rows)); if (hosted.length > 0) parts2.push(tsv(HOSTED_COLS, hosted)); return parts2.length === 0 ? "" : parts2.join(` `) + ` `; } if (rows.length === 0 && hosted.length === 0) return `(no runs) `; const parts = []; if (rows.length > 0) parts.push(glyphTable(RUN_COLS, rows, ctx) + ` ${rows.length} run(s)`); if (hosted.length > 0) parts.push(glyphTable(HOSTED_COLS, hosted, ctx) + ` ${hosted.length} hosted run(s)`); return parts.join(` `) + ` `; } var PLAN_COLS = [ { header: "plan", right: false, cell: (p) => p.name, jsonKey: "name", json: (p) => p.name }, { header: "final_state", right: false, cell: (p) => p.final_state, jsonKey: "final_state", json: (p) => p.final_state }, { header: "outcome", right: false, cell: (p) => p.outcome ?? "—", jsonKey: "outcome", json: (p) => p.outcome }, { header: "fired", right: true, cell: (p) => p.fired ? "yes" : "no", jsonKey: "fired", json: (p) => Boolean(p.fired) }, { header: "orders", right: true, cell: (p) => String(p.orders), jsonKey: "orders", json: (p) => p.orders }, { header: "fills", right: true, cell: (p) => String(p.fills), jsonKey: "fills", json: (p) => p.fills }, { header: "realized", right: true, money: true, cell: (p) => usd(p.realized_usd), jsonKey: "realized_usd", json: (p) => p.realized_usd }, { header: "expected", right: true, money: true, cell: (p) => usd(p.expected_usd), jsonKey: "expected_usd", json: (p) => p.expected_usd } ]; function renderRunShow(rec, ctx) { const r = rec.run; if (ctx.mode === "json") { const run = { run_id: r.run_id, session_date: r.session_date, mode: r.mode, instruments: r.instruments, fill_model: r.fill_model, calibrated: Boolean(r.calibrated), recorded_at: r.recorded_at, r_usd: r.r_usd, realized_floor_usd: r.realized_floor_usd, expected_usd: r.expected_usd, premium_spent: r.premium_spent, bus_events: r.bus_events, bus_sha256: r.bus_sha256, plans_sha256: r.plans_sha256, determinism_hash: r.determinism_hash, report_path: r.report_path }; const plans = rec.plans.map((p) => sortKeys({ name: p.name, final_state: p.final_state, outcome: p.outcome, fired: Boolean(p.fired), orders: p.orders, fills: p.fills, realized_usd: p.realized_usd, expected_usd: p.expected_usd })); return JSON.stringify({ schema: "kestrel.run/v1", run: sortKeys(run), plans }) + ` `; } if (ctx.mode === "text") { const lines = [ `run_id ${r.run_id}`, `session_date ${r.session_date}`, `mode ${r.mode}`, `instruments ${r.instruments}`, `fill_model ${r.fill_model}`, `calibrated ${Boolean(r.calibrated)}`, `recorded_at ${r.recorded_at}`, `r_usd ${r.r_usd}`, `realized_floor_usd ${r.realized_floor_usd}`, `expected_usd ${r.expected_usd}`, `premium_spent ${r.premium_spent}`, `bus_events ${r.bus_events}`, `bus_sha256 ${r.bus_sha256}`, `determinism_hash ${r.determinism_hash}`, `report_path ${r.report_path ?? ""}` ]; const plansTsv = rec.plans.length === 0 ? "" : ` ` + tsv(PLAN_COLS, rec.plans); return lines.join(` `) + plansTsv + ` `; } const head = [ `run_id ${r.run_id}`, `session ${r.session_date} ${r.mode} [${r.instruments}]`, `fill_model ${r.fill_model}${r.calibrated ? " (calibrated)" : ""}`, `recorded_at ${r.recorded_at} (settle ts, injected)`, `r_usd ${r.r_usd.toFixed(2)}`, `totals realized ${usd(r.realized_floor_usd)} expected ${usd(r.expected_usd)} premium ${r.premium_spent.toFixed(2)}`, `bus ${r.bus_events} events sha ${shortId(r.bus_sha256)} det ${shortId(r.determinism_hash)}`, r.report_path !== null ? `report_path ${r.report_path}` : "report_path (none)", "" ].join(` `); const plansTable = rec.plans.length === 0 ? `(no plan instances) ` : glyphTable(PLAN_COLS, rec.plans, ctx) + ` `; return head + ` ` + plansTable; } function renderHostedRunShow(h, ctx) { if (ctx.mode === "json") { return JSON.stringify({ schema: "kestrel.hosted-run/v1", hosted_run: sortKeys({ ...h }) }) + ` `; } if (ctx.mode === "text") { return [ `source ${h.source}`, `operation_id ${h.operation_id}`, `slug ${h.slug}`, `requested_slug ${h.requested_slug}`, `strategy ${h.strategy ?? ""}`, `strategy_digest ${isPlanDigest(h.strategy_digest) ? h.strategy_digest : ""}`, `order_count ${h.order_count}`, `fill_count ${h.fill_count}`, `realized_pnl ${h.realized_pnl}`, ...h.never_fired_reason !== undefined ? [`never_fired_reason ${h.never_fired_reason}`] : [], `grade_artifact_id ${h.grade_artifact_id}`, `bus_artifact_id ${h.bus_artifact_id}`, `manifest_artifact_id ${h.manifest_artifact_id}`, `issued_at ${h.issued_at}`, ...h.copy_token !== undefined ? [`continues_copy_token ${h.copy_token}`] : [], `proof_url ${h.proof_url}` ].join(` `) + ` `; } const aliasLine = h.requested_slug !== h.slug ? [`alias ${h.requested_slug}${h.slug}`] : []; const lineageLine = h.copy_token !== undefined ? [`continues copy-token ${h.copy_token}`] : []; return [ `operation ${h.operation_id} (source: hosted)`, `scenario ${h.slug}`, ...aliasLine, `strategy ${h.strategy ?? "(unknown — receipt predates the plan field)"}`, `plan digest ${isPlanDigest(h.strategy_digest) ? h.strategy_digest : "(unknown — predates the plan digest, or unusable)"}`, `grade order_count=${h.order_count} fill_count=${h.fill_count} realized_pnl=${usd(h.realized_pnl)}`, ...h.never_fired_reason !== undefined ? [`why no orders fired — ${h.never_fired_reason}`] : [], `evidence manifest=${h.manifest_artifact_id} bus=${h.bus_artifact_id} grade=${h.grade_artifact_id}`, ...lineageLine, `issued_at ${h.issued_at === "" ? "(unstamped)" : h.issued_at}`, `proof ${h.proof_url}`, "" ].join(` `); } function signedInt(n) { return (n > 0 ? "+" : "") + String(n); } function signedUsd(n) { return usd(n); } function samePlan(a, b) { if (!isPlanDigest(a.strategy_digest) || !isPlanDigest(b.strategy_digest)) return null; return a.strategy_digest === b.strategy_digest; } function renderRunsCompare(a, b, ctx) { const dOrders = b.order_count - a.order_count; const dFills = b.fill_count - a.fill_count; const dPnl = b.realized_pnl - a.realized_pnl; const stratA = a.strategy ?? "(unknown)"; const stratB = b.strategy ?? "(unknown)"; const sameScenario = a.slug === b.slug; const same = samePlan(a, b); if (ctx.mode === "json") { return JSON.stringify({ schema: "kestrel.runs-compare/v1", same_scenario: sameScenario, same_plan: same, a: sortKeys({ ...a }), b: sortKeys({ ...b }), delta: sortKeys({ order_count: dOrders, fill_count: dFills, realized_pnl: dPnl }) }) + ` `; } if (ctx.mode === "text") { const lines = [ `a_operation_id ${a.operation_id}`, `b_operation_id ${b.operation_id}`, `a_scenario ${a.slug}`, `b_scenario ${b.slug}`, `same_scenario ${sameScenario}`, `a_strategy ${a.strategy ?? ""}`, `b_strategy ${b.strategy ?? ""}`, `a_strategy_digest ${isPlanDigest(a.strategy_digest) ? a.strategy_digest : ""}`, `b_strategy_digest ${isPlanDigest(b.strategy_digest) ? b.strategy_digest : ""}`, `same_plan ${same === null ? "unknown" : same}`, `metric a b delta`, `order_count ${a.order_count} ${b.order_count} ${dOrders}`, `fill_count ${a.fill_count} ${b.fill_count} ${dFills}`, `realized_pnl ${a.realized_pnl} ${b.realized_pnl} ${dPnl}` ]; return lines.join(` `) + ` `; } const metrics = [ { label: "orders", a: String(a.order_count), b: String(b.order_count), d: signedInt(dOrders) }, { label: "fills", a: String(a.fill_count), b: String(b.fill_count), d: signedInt(dFills) }, { label: "realized", a: usd(a.realized_pnl), b: usd(b.realized_pnl), d: signedUsd(dPnl) } ]; const wLabel = Math.max(6, ...metrics.map((m) => m.label.length)); const wA = Math.max(1, "A".length, ...metrics.map((m) => m.a.length)); const wB = Math.max(1, "B".length, ...metrics.map((m) => m.b.length)); const wD = Math.max(1, "Δ".length, ...metrics.map((m) => m.d.length)); const planNote = same === null ? "plan content identity UNKNOWN (a receipt predates the plan digest, or carries an unusable one)" : same ? "plan A and B ran the SAME plan content (digests match)" : "plan A and B ran DIFFERENT plan content (digests differ) — a real tweak"; const head = [ `compare · ${sameScenario ? a.slug : `${a.slug}${b.slug}`}`, `A ${shortId(a.operation_id)} ${a.slug}`, ` plan ${stratA} #${shortDigest(a.strategy_digest)}`, `B ${shortId(b.operation_id)} ${b.slug}`, ` plan ${stratB} #${shortDigest(b.strategy_digest)}`, planNote, ...sameScenario ? [] : ["note different scenarios — P&L is not directly comparable"], "", `${pad("metric", wLabel)} ${padL("A", wA)} ${padL("B", wB)} ${padL("Δ", wD)}`, `${"─".repeat(wLabel)} ${"─".repeat(wA)} ${"─".repeat(wB)} ${"─".repeat(wD)}` ]; const rows = metrics.map((m) => `${pad(m.label, wLabel)} ${padL(m.a, wA)} ${padL(m.b, wB)} ${padL(m.d, wD)}`); return [...head, ...rows, ""].join(` `); } var LINEAGE_COLS = [ { header: "date", right: false, cell: (i) => i.session_date, jsonKey: "session_date", json: (i) => i.session_date }, { header: "mode", right: false, cell: (i) => i.mode, jsonKey: "mode", json: (i) => i.mode }, { header: "fill_model", right: false, cell: (i) => i.fill_model, jsonKey: "fill_model", json: (i) => i.fill_model }, { header: "final_state", right: false, cell: (i) => i.final_state, jsonKey: "final_state", json: (i) => i.final_state }, { header: "outcome", right: false, cell: (i) => i.outcome ?? "—", jsonKey: "outcome", json: (i) => i.outcome }, { header: "fired", right: true, cell: (i) => i.fired ? "yes" : "no", jsonKey: "fired", json: (i) => Boolean(i.fired) }, { header: "fills", right: true, cell: (i) => String(i.fills), jsonKey: "fills", json: (i) => i.fills }, { header: "realized", right: true, money: true, cell: (i) => usd(i.realized_usd), jsonKey: "realized_usd", json: (i) => i.realized_usd }, { header: "expected", right: true, money: true, cell: (i) => usd(i.expected_usd), jsonKey: "expected_usd", json: (i) => i.expected_usd } ]; function renderLineage(name, rows, ctx, coverage) { if (ctx.mode === "json") { const body = JSON.parse(jsonRows("kestrel.lineage/v1", LINEAGE_COLS, rows)); return JSON.stringify({ schema: body.schema, name, rows: body.rows, ...coverage !== undefined ? { coverage } : {} }) + ` `; } if (ctx.mode === "text") return rows.length === 0 ? "" : tsv(LINEAGE_COLS, rows) + ` `; if (rows.length === 0) return `lineage: ${name} (no instances) ${coverage !== undefined ? ` ${coverage} ` : ""}`; const realizedSum = rows.reduce((s, i) => s + i.realized_usd, 0); const expectedSum = rows.reduce((s, i) => s + i.expected_usd, 0); return `lineage: ${name} ` + glyphTable(LINEAGE_COLS, rows, ctx) + ` ${rows.length} instance(s) realized ${usd(realizedSum)} expected ${usd(expectedSum)} `; } var LEADER_COLS = [ { header: "lineage", right: false, cell: (r) => r.name, jsonKey: "name", json: (r) => r.name }, { header: "runs", right: true, cell: (r) => String(r.runs), jsonKey: "runs", json: (r) => r.runs }, { header: "fired", right: true, cell: (r) => String(r.fired), jsonKey: "fired", json: (r) => r.fired }, { header: "fills", right: true, cell: (r) => String(r.fills), jsonKey: "fills", json: (r) => r.fills }, { header: "realized_sum", right: true, money: true, cell: (r) => usd(r.realized_sum), jsonKey: "realized_sum", json: (r) => r.realized_sum }, { header: "expected_sum", right: true, money: true, cell: (r) => usd(r.expected_sum), jsonKey: "expected_sum", json: (r) => r.expected_sum }, { header: "realized_avg", right: true, money: true, cell: (r) => usd(r.realized_avg), jsonKey: "realized_avg", json: (r) => r.realized_avg }, { header: "expected_avg", right: true, money: true, cell: (r) => usd(r.expected_avg), jsonKey: "expected_avg", json: (r) => r.expected_avg } ]; function renderLeaderboard(rows, ctx) { if (ctx.mode === "json") return jsonRows("kestrel.leaderboard/v1", LEADER_COLS, rows) + ` `; if (ctx.mode === "text") return rows.length === 0 ? "" : tsv(LEADER_COLS, rows) + ` `; if (rows.length === 0) return `(no lineages) `; return glyphTable(LEADER_COLS, rows, ctx) + ` ${rows.length} lineage(s) `; } // src/cli/commands/registry.ts var DEFAULT_DB = "data/kestrel.db"; var NO_STORE_HINT = "no runs recorded yet — `kestrel sim` / `kestrel prove` record to your identity-bound home ledger (~/.kestrel/hosted-runs.jsonl, found from any directory), and `kestrel run` / `kestrel day` auto-record into ./data/kestrel.db (this folder)"; function readHostedForDb(dbPath) { return readHostedRunsMerged({ home: defaultHostedStorePath(), fallbacks: [join(dirname(dbPath), HOSTED_STORE_BASENAME)] }); } function usageErr(message) { return new CliError({ code: "USAGE", exit: EXIT.USAGE, message }); } async function openRegForRead(dbPath) { const registry = await loadHeavy(() => import("./heavy-v95qw596.js")); const db = existsSync(dbPath) ? registry.openRegistry(dbPath) : null; return { registry, db }; } function emitNoStoreHint(ctx) { if (ctx.mode === "human") process.stdout.write(`hint: ${NO_STORE_HINT} `); } function emitNoMatchHint(ctx) { if (ctx.mode === "human") process.stdout.write("hint: no recorded run matched the given filter(s) — `kestrel runs list` (no filter) shows the full ledger; `--session-date <YYYY-MM-DD>`/`--lineage <plan|digest>` narrow it (hosted `sim` rows carry no fill model, so `--fill` matches only local `run`/`day` runs)\n"); } function hostedRowPassesFilters(h, f) { if (f.fill !== undefined) return false; if (f.sessionDate !== undefined && h.issued_at.slice(0, 10) !== f.sessionDate) return false; if (f.lineage !== undefined) { const inLineage = h.strategy === f.lineage || h.strategy_digest === f.lineage || h.strategy_digest !== undefined && h.strategy_digest.startsWith(f.lineage); if (!inLineage) return false; } return true; } async function runsListCommand(argv, ctx) { const { flags, bools } = parseArgs(argv, new Set(["hosted"]), new Set(["session-date", "fill", "lineage", "db"])); const dbPath = flags.get("db") ?? DEFAULT_DB; const hostedOnly = bools.has("hosted"); const filters = { ...flags.get("session-date") !== undefined ? { sessionDate: flags.get("session-date") } : {}, ...flags.get("fill") !== undefined ? { fill: flags.get("fill") } : {}, ...flags.get("lineage") !== undefined ? { lineage: flags.get("lineage") } : {} }; const hasFilter = filters.sessionDate !== undefined || filters.fill !== undefined || filters.lineage !== undefined; const hosted = readHostedForDb(dbPath).filter((h) => hostedRowPassesFilters(h, filters)); let rows = []; if (!hostedOnly) { const { registry, db } = await openRegForRead(dbPath); if (db !== null) { try { rows = registry.listRuns(db, { ...filters.sessionDate !== undefined ? { sessionDate: filters.sessionDate } : {}, ...filters.fill !== undefined ? { fillModel: filters.fill } : {}, ...filters.lineage !== undefined ? { lineage: filters.lineage } : {} }); } finally { db.close(); } } } process.stdout.write(renderRuns(rows, ctx, hosted)); if (rows.length === 0 && hosted.length === 0) { if (hasFilter) emitNoMatchHint(ctx); else emitNoStoreHint(ctx); } return 0; } function normalizeRunKey(raw) { const m = raw.match(/\/proof\/([A-Za-z0-9_-]+)\/?$/); return m !== null ? m[1] : raw; } function hostedRunMatches(h, key) { return h.operation_id === key || h.operation_id.startsWith(key) || h.grade_artifact_id === key || h.grade_artifact_id.startsWith(key); } async function runsShowCommand(argv, ctx) { const { positionals, flags } = parseArgs(argv, new Set, new Set(["db"])); const rawId = positionals[0]; if (rawId === undefined) throw usageErr("runs show needs a <run_id>"); const runId = normalizeRunKey(rawId); const dbPath = flags.get("db") ?? DEFAULT_DB; const hostedMatch = readHostedForDb(dbPath).filter((h) => hostedRunMatches(h, runId)); const opened = existsSync(dbPath) ? await openRegForRead(dbPath) : null; const db = opened?.db ?? null; try { const localMatch = opened !== null && db !== null ? opened.registry.listRuns(db).filter((r) => r.run_id === runId || r.run_id.startsWith(runId)) : []; const total = localMatch.length + hostedMatch.length; if (total === 0) throw new CliError({ code: "NOT_FOUND", exit: EXIT.NOT_FOUND, message: `no run matching ${JSON.stringify(rawId)}`, hint: "the id may be an operation id (op_…), a local run id, OR the art_ proof id from your saved proof URL (…/proof/art_…) — `kestrel runs list` shows both" }); if (total > 1) throw usageErr(`ambiguous run prefix ${JSON.stringify(rawId)}${total} matches`); if (hostedMatch.length === 1) { process.stdout.write(renderHostedRunShow(hostedMatch[0], ctx)); } else { const rec = opened.registry.getRun(db, localMatch[0].run_id); process.stdout.write(renderRunShow(rec, ctx)); } } finally { db?.close(); } return 0; } function resolveHostedOne(hosted, rawId) { const key = normalizeRunKey(rawId); const matches = hosted.filter((h) => hostedRunMatches(h, key)); if (matches.length === 0) throw new CliError({ code: "NOT_FOUND", exit: EXIT.NOT_FOUND, message: `no hosted run matching ${JSON.stringify(rawId)}`, hint: "the id may be an operation id (op_…) OR the art_ proof id from your saved proof URL (…/proof/art_…) — `kestrel runs list` shows both, and `runs show`/`verify`/`replay` accept the same forms" }); if (matches.length > 1) throw usageErr(`ambiguous run prefix ${JSON.stringify(rawId)}${matches.length} matches`); return matches[0]; } async function runsCompareCommand(argv, ctx) { const { positionals, flags } = parseArgs(argv, new Set, new Set(["db"])); const [idA, idB] = positionals; if (idA === undefined || idB === undefined) throw usageErr("runs compare needs two run ids: `kestrel runs compare <runA> <runB>`"); const dbPath = flags.get("db") ?? DEFAULT_DB; const hosted = readHostedForDb(dbPath); const rowA = resolveHostedOne(hosted, idA); const rowB = resolveHostedOne(hosted, idB); process.stdout.write(renderRunsCompare(rowA, rowB, ctx)); return 0; } var LINEAGE_COVERAGE = "lineage covers LOCAL `run`/`day` sessions (the plan-name ledger in ./data/kestrel.db) — hosted `sim` runs are NOT plan-lineage-tracked; find them with `kestrel runs list --hosted` (or `kestrel runs show <op_…|art_…>`)"; function emitLineageCoverage(ctx) { if (ctx.mode === "text") process.stderr.write(`notice: ${LINEAGE_COVERAGE} `); } async function lineageCommand(argv, ctx) { const { positionals, flags } = parseArgs(argv, new Set, new Set(["db"])); const name = positionals[0]; if (name === undefined) throw usageErr("lineage needs a <name>"); const dbPath = flags.get("db") ?? DEFAULT_DB; const { registry, db } = await openRegForRead(dbPath); if (db === null) { process.stdout.write(renderLineage(name, [], ctx, LINEAGE_COVERAGE)); emitLineageCoverage(ctx); return 0; } try { const rows = registry.lineage(db, name); process.stdout.write(renderLineage(name, rows, ctx, rows.length === 0 ? LINEAGE_COVERAGE : undefined)); if (rows.length === 0) emitLineageCoverage(ctx); } finally { db.close(); } return 0; } async function leaderboardCommand(argv, ctx) { const { flags } = parseArgs(argv, new Set, new Set(["since", "mode", "db"])); const dbPath = flags.get("db") ?? DEFAULT_DB; let since; const sinceRaw = flags.get("since"); if (sinceRaw !== undefined) { since = Number(sinceRaw); if (!Number.isFinite(since)) throw usageErr(`--since must be a number (ms), got ${JSON.stringify(sinceRaw)}`); } const { registry, db } = await openRegForRead(dbPath); if (db === null) { process.stdout.write(renderLeaderboard([], ctx)); emitNoStoreHint(ctx); return 0; } try { const rows = registry.leaderboard(db, { ...flags.get("mode") !== undefined ? { mode: flags.get("mode") } : {}, ...since !== undefined ? { since } : {} }); process.stdout.write(renderLeaderboard(rows, ctx)); } finally { db.close(); } return 0; } export { runsShowCommand, runsListCommand, runsCompareCommand, normalizeRunKey, lineageCommand, leaderboardCommand };