@akon-labs/nexus-cli 0.1.11-rc.2 → 0.1.11

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.
Files changed (57) hide show
  1. package/dist/cli.js +588 -63
  2. package/dist/core/graph-rail-store.d.ts +10 -0
  3. package/dist/core/graph-rail-store.d.ts.map +1 -1
  4. package/dist/core/graph-rail-store.js +9 -0
  5. package/dist/core/graph-rail-store.js.map +1 -1
  6. package/dist/core/keybindings.d.ts +2 -1
  7. package/dist/core/keybindings.d.ts.map +1 -1
  8. package/dist/core/keybindings.js +4 -1
  9. package/dist/core/keybindings.js.map +1 -1
  10. package/dist/extensions/gitnexus/client.d.ts.map +1 -1
  11. package/dist/extensions/gitnexus/client.js +45 -14
  12. package/dist/extensions/gitnexus/client.js.map +1 -1
  13. package/dist/extensions/gitnexus/hub-api.d.ts +56 -0
  14. package/dist/extensions/gitnexus/hub-api.d.ts.map +1 -0
  15. package/dist/extensions/gitnexus/hub-api.js +105 -0
  16. package/dist/extensions/gitnexus/hub-api.js.map +1 -0
  17. package/dist/extensions/gitnexus/index-repo.d.ts +50 -0
  18. package/dist/extensions/gitnexus/index-repo.d.ts.map +1 -0
  19. package/dist/extensions/gitnexus/index-repo.js +162 -0
  20. package/dist/extensions/gitnexus/index-repo.js.map +1 -0
  21. package/dist/extensions/gitnexus/index.d.ts.map +1 -1
  22. package/dist/extensions/gitnexus/index.js +135 -15
  23. package/dist/extensions/gitnexus/index.js.map +1 -1
  24. package/dist/extensions/gitnexus/resolve.d.ts +9 -0
  25. package/dist/extensions/gitnexus/resolve.d.ts.map +1 -1
  26. package/dist/extensions/gitnexus/resolve.js +52 -2
  27. package/dist/extensions/gitnexus/resolve.js.map +1 -1
  28. package/dist/index.js +588 -63
  29. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  30. package/dist/modes/interactive/components/assistant-message.js +2 -0
  31. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  32. package/dist/modes/interactive/components/command-palette.d.ts +2 -1
  33. package/dist/modes/interactive/components/command-palette.d.ts.map +1 -1
  34. package/dist/modes/interactive/components/command-palette.js +11 -4
  35. package/dist/modes/interactive/components/command-palette.js.map +1 -1
  36. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  37. package/dist/modes/interactive/components/footer.js +9 -3
  38. package/dist/modes/interactive/components/footer.js.map +1 -1
  39. package/dist/modes/interactive/components/graph-rail.d.ts.map +1 -1
  40. package/dist/modes/interactive/components/graph-rail.js +18 -3
  41. package/dist/modes/interactive/components/graph-rail.js.map +1 -1
  42. package/dist/modes/interactive/components/keybinding-hints.d.ts +1 -0
  43. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  44. package/dist/modes/interactive/components/keybinding-hints.js +7 -1
  45. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  46. package/dist/modes/interactive/components/landing-panel.d.ts.map +1 -1
  47. package/dist/modes/interactive/components/landing-panel.js +15 -2
  48. package/dist/modes/interactive/components/landing-panel.js.map +1 -1
  49. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  50. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  51. package/dist/modes/interactive/interactive-mode.js +35 -5
  52. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  53. package/dist/rpc-entry.js +588 -63
  54. package/dist/vendor/ai.js +14 -14
  55. package/dist/vendor/tui.js +1 -1
  56. package/npm-shrinkwrap.json +2 -2
  57. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"graph-rail.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/graph-rail.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Component } from \"@earendil-works/pi-tui\";\nimport { visibleWidth } from \"@earendil-works/pi-tui\";\nimport { type GraphRailState, graphRailStore } from \"../../../core/graph-rail-store.ts\";\nimport { diagonalFill, gradientText } from \"../theme/brand.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { NEXUS_SMALL } from \"./nexus-logo.ts\";\n\n/**\n * GitNexus side rail (fullscreen UI mode, terminals >= MIN_TERMINAL_WIDTH).\n * Renders repo status, the latest blast radius, latest flows, and session\n * changes as stacked cards. Pure view over graphRailStore.\n */\n\nexport const RAIL_WIDTH = 36;\nexport const MIN_TERMINAL_WIDTH = 110;\n\nfunction clipVisible(line: string, width: number): string {\n\tif (visibleWidth(line) <= width) return line;\n\tlet out = \"\";\n\tlet visible = 0;\n\tfor (let i = 0; i < line.length; i++) {\n\t\tif (line[i] === \"\\x1b\") {\n\t\t\tconst match = line.slice(i).match(/^\\x1b\\[[0-9;]*m/);\n\t\t\tif (match) {\n\t\t\t\tout += match[0];\n\t\t\t\ti += match[0].length - 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tif (visible >= width) break;\n\t\tout += line[i];\n\t\tvisible++;\n\t}\n\treturn `${out}\\x1b[0m`;\n}\n\nfunction basename(filePath: string | undefined): string {\n\tif (!filePath) return \"\";\n\treturn filePath.split(\"/\").pop() ?? filePath;\n}\n\nexport type GraphRailCard = \"status\" | \"repos\" | \"impact\" | \"flows\" | \"changes\" | \"skills\";\n\n/** Dim low-confidence graph edges below this threshold. */\nconst CONFIDENCE_DIM_THRESHOLD = 0.7;\n\nfunction formatSymbolCount(symbols: string): string {\n\tconst n = Number(symbols.replace(/,/g, \"\"));\n\tif (Number.isNaN(n)) return symbols;\n\tif (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n\tif (n >= 1_000) return `${Math.round(n / 1_000)}k`;\n\treturn String(n);\n}\n\nexport interface GraphRailSessionStatus {\n\ttitle?: string;\n\tcwd?: string;\n\tmodel?: string;\n\tprovider?: string;\n\treasoning?: string;\n\tcontext?: string;\n\tcost?: string;\n}\n\nexport interface GraphRailHostInfo {\n\tskills: string[];\n\tversion: string;\n\t/** Live session status for the crush-style sidebar header. */\n\tgetSessionStatus?: () => GraphRailSessionStatus;\n}\n\nexport class GraphRailComponent implements Component {\n\t/** Set by the host: invoked when a card is clicked (fullscreen mouse routing). */\n\tonCardClick: ((card: GraphRailCard) => void) | undefined;\n\n\tprivate hostInfo: GraphRailHostInfo | undefined;\n\n\tsetHostInfo(info: GraphRailHostInfo): void {\n\t\tthis.hostInfo = info;\n\t}\n\n\tgetHostInfo(): GraphRailHostInfo | undefined {\n\t\treturn this.hostInfo;\n\t}\n\n\tprivate cardRanges: Array<{ start: number; end: number; card: GraphRailCard }> = [];\n\n\tinvalidate(): void {\n\t\t// Stateless view over graphRailStore — nothing cached.\n\t}\n\n\thandleClick(_x: number, y: number): boolean {\n\t\tconst hit = this.cardRanges.find((range) => y >= range.start && y < range.end);\n\t\tif (!hit || !this.onCardClick) return false;\n\t\tthis.onCardClick(hit.card);\n\t\treturn true;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (width < 20) return [];\n\t\tconst inner = Math.min(width, RAIL_WIDTH) - 2;\n\t\tconst s = graphRailStore.getState();\n\t\tconst lines: string[] = [];\n\t\tthis.cardRanges = [];\n\t\tlet cardStart = 0;\n\t\tconst beginCard = () => {\n\t\t\tcardStart = lines.length;\n\t\t};\n\t\tconst commitCard = (card: GraphRailCard) => {\n\t\t\tthis.cardRanges.push({ start: cardStart, end: lines.length, card });\n\t\t};\n\t\t// Crush-style section header: `Title ────────` (no card frames).\n\t\tconst rule = (title: string) =>\n\t\t\tlines.push(\n\t\t\t\t`${theme.fg(\"muted\", title)} ${theme.fg(\"dim\", \"─\".repeat(Math.max(0, inner - [...title].length - 1)))}`,\n\t\t\t);\n\t\tconst row = (text: string) => lines.push(clipVisible(text, inner));\n\t\tconst end = () => lines.push(\"\");\n\n\t\t// Logo band (small crush-style: hatch, wordmark, version).\n\t\tconst hatch = diagonalFill(inner + 2);\n\t\tlines.push(hatch);\n\t\tfor (const logoLine of NEXUS_SMALL) lines.push(` ${gradientText(logoLine)}`);\n\t\tif (this.hostInfo?.version) {\n\t\t\tlines.push(` ${theme.fg(\"muted\", `v${this.hostInfo.version}`)}`);\n\t\t}\n\t\tlines.push(hatch);\n\t\tlines.push(\"\");\n\n\t\t// Session header: title, cwd, model block (crush sidebar order).\n\t\tconst status = this.hostInfo?.getSessionStatus?.();\n\t\tif (status) {\n\t\t\tif (status.title) {\n\t\t\t\trow(theme.bold(status.title));\n\t\t\t\tlines.push(\"\");\n\t\t\t}\n\t\t\tif (status.cwd) {\n\t\t\t\trow(theme.fg(\"muted\", status.cwd));\n\t\t\t\tlines.push(\"\");\n\t\t\t}\n\t\t\tif (status.model) {\n\t\t\t\trow(\n\t\t\t\t\t`${theme.fg(\"muted\", \"◇\")} ${theme.bold(status.model)}${status.provider ? theme.fg(\"muted\", ` via ${status.provider}`) : \"\"}`,\n\t\t\t\t);\n\t\t\t\tif (status.reasoning) row(` ${theme.fg(\"muted\", `Reasoning ${status.reasoning}`)}`);\n\t\t\t\tif (status.context || status.cost) {\n\t\t\t\t\trow(` ${theme.fg(\"muted\", [status.context, status.cost].filter(Boolean).join(\" \"))}`);\n\t\t\t\t}\n\t\t\t\tlines.push(\"\");\n\t\t\t}\n\t\t}\n\n\t\tbeginCard();\n\t\tthis.renderChanges(s, rule, row, end);\n\t\tcommitCard(\"changes\");\n\t\tbeginCard();\n\t\tthis.renderStatus(s, rule, row, end);\n\t\tcommitCard(\"status\");\n\t\tbeginCard();\n\t\tthis.renderRepos(s, rule, row, end);\n\t\tcommitCard(\"repos\");\n\t\tbeginCard();\n\t\tthis.renderImpact(s, rule, row, end);\n\t\tcommitCard(\"impact\");\n\t\tbeginCard();\n\t\tthis.renderQuery(s, rule, row, end);\n\t\tcommitCard(\"flows\");\n\t\tbeginCard();\n\t\tthis.renderSkills(rule, row, end);\n\t\tcommitCard(\"skills\");\n\t\treturn lines;\n\t}\n\n\tprivate renderRepos(\n\t\ts: Readonly<GraphRailState>,\n\t\trule: (t: string) => void,\n\t\trow: (t: string) => void,\n\t\tend: () => void,\n\t): void {\n\t\tif (s.repos.length === 0) return;\n\t\trule(\"Repos\");\n\t\tconst activeName = s.repo?.name;\n\t\tfor (const repo of s.repos.slice(0, 5)) {\n\t\t\tconst short = repo.name.split(\"/\").pop() ?? repo.name;\n\t\t\tconst count = theme.fg(\"muted\", formatSymbolCount(repo.symbols));\n\t\t\tif (repo.name === activeName) {\n\t\t\t\trow(`${theme.fg(\"accent\", \"●\")} ${theme.fg(\"accent\", short)} ${count}`);\n\t\t\t} else {\n\t\t\t\trow(`${theme.fg(\"muted\", \"○\")} ${theme.fg(\"muted\", short)} ${count}`);\n\t\t\t}\n\t\t}\n\t\tif (s.repos.length > 5) row(theme.fg(\"muted\", ` … +${s.repos.length - 5} more`));\n\t\tend();\n\t}\n\n\tprivate renderStatus(\n\t\ts: Readonly<GraphRailState>,\n\t\trule: (t: string) => void,\n\t\trow: (t: string) => void,\n\t\tend: () => void,\n\t): void {\n\t\trule(\"GitNexus\");\n\t\tif (!s.repo) {\n\t\t\trow(theme.fg(\"muted\", \"not connected\"));\n\t\t\tend();\n\t\t\treturn;\n\t\t}\n\t\tif (s.currentIndexed) {\n\t\t\trow(theme.bold(s.repo.name.split(\"/\").pop() ?? s.repo.name));\n\t\t\trow(theme.fg(\"muted\", `${s.repo.symbols} symbols · ${s.repo.repoCount} repos`));\n\t\t\trow(theme.fg(\"muted\", `indexed ${s.repo.indexedAt.split(\" GMT\")[0] ?? s.repo.indexedAt}`));\n\t\t} else {\n\t\t\trow(theme.fg(\"warning\", \"repo not indexed\"));\n\t\t\trow(theme.fg(\"muted\", `${s.repo.repoCount} repos queryable`));\n\t\t}\n\t\trow(theme.fg(\"muted\", `graph calls ${s.graphCalls} · impact ${s.impactChecks}`));\n\t\tend();\n\t}\n\n\tprivate renderImpact(\n\t\ts: Readonly<GraphRailState>,\n\t\trule: (t: string) => void,\n\t\trow: (t: string) => void,\n\t\tend: () => void,\n\t): void {\n\t\tconst impact = s.impact;\n\t\tif (!impact) return;\n\t\trule(\"Blast Radius\");\n\t\tconst risk = impact.risk.toUpperCase();\n\t\tconst riskColor = risk === \"HIGH\" || risk === \"CRITICAL\" ? \"error\" : risk === \"MEDIUM\" ? \"warning\" : \"success\";\n\t\trow(`${theme.fg(\"accent\", \"◉\")} ${theme.bold(impact.target)}`);\n\t\trow(theme.fg(riskColor, `risk: ${risk}`));\n\t\tconst depths = Object.keys(impact.byDepth)\n\t\t\t.map(Number)\n\t\t\t.filter((d) => !Number.isNaN(d))\n\t\t\t.sort((a, b) => a - b);\n\t\tfor (const depth of depths.slice(0, 3)) {\n\t\t\tconst nodes = impact.byDepth[String(depth)] ?? [];\n\t\t\tif (nodes.length === 0) continue;\n\t\t\tconst color = depth === 1 ? \"error\" : depth === 2 ? \"warning\" : \"muted\";\n\t\t\tconst label = depth === 1 ? \"breaks\" : depth === 2 ? \"test\" : \"transitive\";\n\t\t\trow(theme.fg(color, `d${depth} ${label} (${nodes.length})`));\n\t\t\tfor (const node of nodes.slice(0, 3)) {\n\t\t\t\tconst lowConfidence = node.confidence !== undefined && node.confidence < CONFIDENCE_DIM_THRESHOLD;\n\t\t\t\tconst name = lowConfidence ? theme.fg(\"dim\", `${node.name}?`) : node.name;\n\t\t\t\trow(` ${theme.fg(lowConfidence ? \"dim\" : color, depth === 1 ? \"●\" : \"○\")} ${name}`);\n\t\t\t}\n\t\t\tif (nodes.length > 3) row(theme.fg(\"muted\", ` … +${nodes.length - 3}`));\n\t\t}\n\t\tif (impact.processes.length > 0) row(theme.fg(\"muted\", `flows: ${impact.processes.slice(0, 2).join(\", \")}`));\n\t\tif (impact.modules.length > 0) {\n\t\t\tconst maxHits = Math.max(...impact.modules.map((m) => m.hits), 1);\n\t\t\tfor (const module of impact.modules.slice(0, 3)) {\n\t\t\t\tconst filled = Math.max(1, Math.round((module.hits / maxHits) * 5));\n\t\t\t\tconst bar =\n\t\t\t\t\ttheme.fg(module.direct ? \"accent\" : \"muted\", \"▮\".repeat(filled)) +\n\t\t\t\t\ttheme.fg(\"dim\", \"▯\".repeat(5 - filled));\n\t\t\t\trow(`${bar} ${theme.fg(\"muted\", module.name)} ${theme.fg(\"dim\", String(module.hits))}`);\n\t\t\t}\n\t\t}\n\t\tend();\n\t}\n\n\tprivate renderQuery(\n\t\ts: Readonly<GraphRailState>,\n\t\trule: (t: string) => void,\n\t\trow: (t: string) => void,\n\t\tend: () => void,\n\t): void {\n\t\tconst query = s.query;\n\t\tif (!query) return;\n\t\trule(\"Flows\");\n\t\trow(theme.fg(\"muted\", clipQuery(query.query)));\n\t\tquery.flows.slice(0, 3).forEach((flow, i) => {\n\t\t\tconst marker = i === 0 ? theme.fg(\"accent\", \"◉\") : theme.fg(\"muted\", \"○\");\n\t\t\tconst steps = flow.stepCount ? theme.fg(\"muted\", ` ·${flow.stepCount}`) : \"\";\n\t\t\trow(`${marker} ${flow.summary}${steps}`);\n\t\t});\n\t\tend();\n\t}\n\n\tprivate renderSkills(rule: (t: string) => void, row: (t: string) => void, end: () => void): void {\n\t\tconst skills = this.hostInfo?.skills ?? [];\n\t\tif (skills.length === 0) return;\n\t\trule(\"Skills\");\n\t\tfor (const skill of skills.slice(0, 8)) {\n\t\t\trow(`${theme.fg(\"success\", \"\\u25cf\")} ${theme.fg(\"muted\", skill)}`);\n\t\t}\n\t\tif (skills.length > 8) row(theme.fg(\"muted\", ` \\u2026 +${skills.length - 8} more`));\n\t\tend();\n\t}\n\n\tprivate renderChanges(\n\t\ts: Readonly<GraphRailState>,\n\t\trule: (t: string) => void,\n\t\trow: (t: string) => void,\n\t\tend: () => void,\n\t): void {\n\t\trule(\"Modified Files\");\n\t\tif (s.changes.length === 0) {\n\t\t\trow(theme.fg(\"muted\", \"None\"));\n\t\t\tend();\n\t\t\treturn;\n\t\t}\n\t\tfor (const change of s.changes.slice(-5)) {\n\t\t\trow(\n\t\t\t\t`${basename(change.path)} ${theme.fg(\"success\", `+${change.added}`)} ${theme.fg(\"error\", `-${change.removed}`)}`,\n\t\t\t);\n\t\t}\n\t\tend();\n\t}\n}\n\nfunction clipQuery(query: string): string {\n\treturn query.length > 30 ? `${query.slice(0, 29)}…` : `“${query}”`;\n}\n\n/** Full-width expansion of a rail card, appended to the transcript on click. */\nexport function renderExpandedCard(card: GraphRailCard, hostInfo?: GraphRailHostInfo): string | undefined {\n\tconst s = graphRailStore.getState();\n\tconst header = (title: string) => theme.bold(theme.fg(\"accent\", `── GitNexus · ${title} ──`));\n\tif (card === \"repos\" && s.repos.length > 0) {\n\t\tconst lines: string[] = [header(\"indexed repos\")];\n\t\tfor (const repo of s.repos) {\n\t\t\tconst marker = repo.name === s.repo?.name ? theme.fg(\"accent\", \"●\") : theme.fg(\"muted\", \"○\");\n\t\t\tlines.push(`${marker} ${repo.name} ${theme.fg(\"muted\", `${repo.symbols} symbols`)}`);\n\t\t}\n\t\treturn lines.join(\"\\n\");\n\t}\n\tif (card === \"skills\" && hostInfo && hostInfo.skills.length > 0) {\n\t\tconst lines: string[] = [header(\"skills\")];\n\t\tfor (const skill of hostInfo.skills) {\n\t\t\tlines.push(`${theme.fg(\"success\", \"●\")} ${skill}`);\n\t\t}\n\t\treturn lines.join(\"\\n\");\n\t}\n\tif (card === \"impact\" && s.impact) {\n\t\tconst lines: string[] = [header(\"blast radius\")];\n\t\tconst risk = s.impact.risk.toUpperCase();\n\t\tconst riskColor = risk === \"HIGH\" || risk === \"CRITICAL\" ? \"error\" : risk === \"MEDIUM\" ? \"warning\" : \"success\";\n\t\tlines.push(\n\t\t\t`${theme.fg(\"accent\", \"◉\")} ${theme.bold(s.impact.target)} ${theme.fg(\"muted\", s.impact.filePath ?? \"\")} ${theme.bold(theme.fg(riskColor, `RISK: ${risk}`))}`,\n\t\t);\n\t\tconst depths = Object.keys(s.impact.byDepth)\n\t\t\t.map(Number)\n\t\t\t.filter((d) => !Number.isNaN(d))\n\t\t\t.sort((a, b) => a - b);\n\t\tfor (const depth of depths) {\n\t\t\tconst nodes = s.impact.byDepth[String(depth)] ?? [];\n\t\t\tif (nodes.length === 0) continue;\n\t\t\tconst color = depth === 1 ? \"error\" : depth === 2 ? \"warning\" : \"muted\";\n\t\t\tconst label = depth === 1 ? \"WILL BREAK\" : depth === 2 ? \"should test\" : \"transitive\";\n\t\t\tlines.push(theme.fg(color, `d=${depth} ${label} (${nodes.length})`));\n\t\t\tfor (const node of nodes) {\n\t\t\t\tconst rel = node.relationType ? theme.fg(\"muted\", ` (${node.relationType})`) : \"\";\n\t\t\t\tlines.push(\n\t\t\t\t\t` ${theme.fg(color, depth === 1 ? \"●\" : \"○\")} ${node.name} ${theme.fg(\"muted\", node.filePath ?? \"\")}${rel}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tif (s.impact.processes.length > 0)\n\t\t\tlines.push(theme.fg(\"muted\", `flows affected: ${s.impact.processes.join(\", \")}`));\n\t\tif (s.impact.modules.length > 0)\n\t\t\tlines.push(\n\t\t\t\ttheme.fg(\n\t\t\t\t\t\"muted\",\n\t\t\t\t\t`modules: ${s.impact.modules.map((m) => `${m.name} (${m.hits}${m.direct ? \", direct\" : \"\"})`).join(\", \")}`,\n\t\t\t\t),\n\t\t\t);\n\t\treturn lines.join(\"\\n\");\n\t}\n\tif (card === \"flows\" && s.query) {\n\t\tconst lines: string[] = [header(\"flows\"), theme.fg(\"muted\", `query: “${s.query.query}”`)];\n\t\ts.query.flows.forEach((flow, i) => {\n\t\t\tconst marker = i === 0 ? theme.fg(\"accent\", \"◉\") : theme.fg(\"muted\", \"○\");\n\t\t\tlines.push(\n\t\t\t\t`${marker} ${flow.summary}${flow.stepCount ? theme.fg(\"muted\", ` · ${flow.stepCount} steps`) : \"\"}`,\n\t\t\t);\n\t\t});\n\t\treturn lines.join(\"\\n\");\n\t}\n\tif (card === \"changes\" && s.changes.length > 0) {\n\t\tconst lines: string[] = [header(\"session changes\")];\n\t\tfor (const change of s.changes) {\n\t\t\tlines.push(\n\t\t\t\t`${theme.fg(\"success\", `+${change.added}`)} ${theme.fg(\"error\", `-${change.removed}`)} ${change.path}`,\n\t\t\t);\n\t\t}\n\t\treturn lines.join(\"\\n\");\n\t}\n\tif (card === \"status\" && s.repo) {\n\t\treturn [\n\t\t\theader(\"status\"),\n\t\t\t`repo: ${s.repo.name || \"(current dir not indexed)\"} · ${s.repo.symbols} symbols`,\n\t\t\t`indexed: ${s.repo.indexedAt || \"n/a\"} · ${s.repo.repoCount} repos on hub`,\n\t\t\t`graph calls: ${s.graphCalls} · impact checks: ${s.impactChecks}`,\n\t\t].join(\"\\n\");\n\t}\n\treturn undefined;\n}\n"]}
1
+ {"version":3,"file":"graph-rail.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/graph-rail.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Component } from \"@earendil-works/pi-tui\";\nimport { visibleWidth } from \"@earendil-works/pi-tui\";\nimport { formatCompactIndexPhase, type GraphRailState, graphRailStore } from \"../../../core/graph-rail-store.ts\";\nimport { diagonalFill, gradientText } from \"../theme/brand.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { NEXUS_SMALL } from \"./nexus-logo.ts\";\n\n/**\n * GitNexus side rail (fullscreen UI mode, terminals >= MIN_TERMINAL_WIDTH).\n * Renders repo status, the latest blast radius, latest flows, and session\n * changes as stacked cards. Pure view over graphRailStore.\n */\n\nexport const RAIL_WIDTH = 36;\nexport const MIN_TERMINAL_WIDTH = 110;\n\nfunction clipVisible(line: string, width: number): string {\n\tif (visibleWidth(line) <= width) return line;\n\tlet out = \"\";\n\tlet visible = 0;\n\tfor (let i = 0; i < line.length; i++) {\n\t\tif (line[i] === \"\\x1b\") {\n\t\t\tconst match = line.slice(i).match(/^\\x1b\\[[0-9;]*m/);\n\t\t\tif (match) {\n\t\t\t\tout += match[0];\n\t\t\t\ti += match[0].length - 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tif (visible >= width) break;\n\t\tout += line[i];\n\t\tvisible++;\n\t}\n\treturn `${out}\\x1b[0m`;\n}\n\nfunction basename(filePath: string | undefined): string {\n\tif (!filePath) return \"\";\n\treturn filePath.split(\"/\").pop() ?? filePath;\n}\n\nexport type GraphRailCard = \"status\" | \"repos\" | \"impact\" | \"flows\" | \"changes\" | \"skills\";\n\n/** Dim low-confidence graph edges below this threshold. */\nconst CONFIDENCE_DIM_THRESHOLD = 0.7;\n\nfunction formatSymbolCount(symbols: string): string {\n\tconst n = Number(symbols.replace(/,/g, \"\"));\n\tif (Number.isNaN(n)) return symbols;\n\tif (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n\tif (n >= 1_000) return `${Math.round(n / 1_000)}k`;\n\treturn String(n);\n}\n\nexport interface GraphRailSessionStatus {\n\ttitle?: string;\n\tcwd?: string;\n\tmodel?: string;\n\tprovider?: string;\n\treasoning?: string;\n\tcontext?: string;\n\tcost?: string;\n}\n\nexport interface GraphRailHostInfo {\n\tskills: string[];\n\tversion: string;\n\t/** Live session status for the crush-style sidebar header. */\n\tgetSessionStatus?: () => GraphRailSessionStatus;\n}\n\nexport class GraphRailComponent implements Component {\n\t/** Set by the host: invoked when a card is clicked (fullscreen mouse routing). */\n\tonCardClick: ((card: GraphRailCard) => void) | undefined;\n\n\tprivate hostInfo: GraphRailHostInfo | undefined;\n\n\tsetHostInfo(info: GraphRailHostInfo): void {\n\t\tthis.hostInfo = info;\n\t}\n\n\tgetHostInfo(): GraphRailHostInfo | undefined {\n\t\treturn this.hostInfo;\n\t}\n\n\tprivate cardRanges: Array<{ start: number; end: number; card: GraphRailCard }> = [];\n\n\tinvalidate(): void {\n\t\t// Stateless view over graphRailStore — nothing cached.\n\t}\n\n\thandleClick(_x: number, y: number): boolean {\n\t\tconst hit = this.cardRanges.find((range) => y >= range.start && y < range.end);\n\t\tif (!hit || !this.onCardClick) return false;\n\t\tthis.onCardClick(hit.card);\n\t\treturn true;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (width < 20) return [];\n\t\tconst inner = Math.min(width, RAIL_WIDTH) - 2;\n\t\tconst s = graphRailStore.getState();\n\t\tconst lines: string[] = [];\n\t\tthis.cardRanges = [];\n\t\tlet cardStart = 0;\n\t\tconst beginCard = () => {\n\t\t\tcardStart = lines.length;\n\t\t};\n\t\tconst commitCard = (card: GraphRailCard) => {\n\t\t\tthis.cardRanges.push({ start: cardStart, end: lines.length, card });\n\t\t};\n\t\t// Crush-style section header: `Title ────────` (no card frames).\n\t\tconst rule = (title: string) =>\n\t\t\tlines.push(\n\t\t\t\t`${theme.fg(\"muted\", title)} ${theme.fg(\"dim\", \"─\".repeat(Math.max(0, inner - [...title].length - 1)))}`,\n\t\t\t);\n\t\tconst row = (text: string) => lines.push(clipVisible(text, inner));\n\t\tconst end = () => lines.push(\"\");\n\n\t\t// Logo band (small crush-style: hatch, wordmark, version).\n\t\tconst hatch = diagonalFill(inner + 2);\n\t\tlines.push(hatch);\n\t\tfor (const logoLine of NEXUS_SMALL) lines.push(` ${gradientText(logoLine)}`);\n\t\tif (this.hostInfo?.version) {\n\t\t\tlines.push(` ${theme.fg(\"muted\", `v${this.hostInfo.version}`)}`);\n\t\t}\n\t\tlines.push(hatch);\n\t\tlines.push(\"\");\n\n\t\t// Session header: title, cwd, model block (crush sidebar order).\n\t\tconst status = this.hostInfo?.getSessionStatus?.();\n\t\tif (status) {\n\t\t\tif (status.title) {\n\t\t\t\trow(theme.bold(status.title));\n\t\t\t\tlines.push(\"\");\n\t\t\t}\n\t\t\tif (status.cwd) {\n\t\t\t\trow(theme.fg(\"muted\", status.cwd));\n\t\t\t\tlines.push(\"\");\n\t\t\t}\n\t\t\tif (status.model) {\n\t\t\t\trow(\n\t\t\t\t\t`${theme.fg(\"muted\", \"◇\")} ${theme.bold(status.model)}${status.provider ? theme.fg(\"muted\", ` via ${status.provider}`) : \"\"}`,\n\t\t\t\t);\n\t\t\t\tif (status.reasoning) row(` ${theme.fg(\"muted\", `Reasoning ${status.reasoning}`)}`);\n\t\t\t\tif (status.context || status.cost) {\n\t\t\t\t\trow(` ${theme.fg(\"muted\", [status.context, status.cost].filter(Boolean).join(\" \"))}`);\n\t\t\t\t}\n\t\t\t\tlines.push(\"\");\n\t\t\t}\n\t\t}\n\n\t\tbeginCard();\n\t\tthis.renderChanges(s, rule, row, end);\n\t\tcommitCard(\"changes\");\n\t\tbeginCard();\n\t\tthis.renderStatus(s, inner, rule, row, end);\n\t\tcommitCard(\"status\");\n\t\tbeginCard();\n\t\tthis.renderRepos(s, rule, row, end);\n\t\tcommitCard(\"repos\");\n\t\tbeginCard();\n\t\tthis.renderImpact(s, rule, row, end);\n\t\tcommitCard(\"impact\");\n\t\tbeginCard();\n\t\tthis.renderQuery(s, rule, row, end);\n\t\tcommitCard(\"flows\");\n\t\tbeginCard();\n\t\tthis.renderSkills(rule, row, end);\n\t\tcommitCard(\"skills\");\n\t\treturn lines;\n\t}\n\n\tprivate renderRepos(\n\t\ts: Readonly<GraphRailState>,\n\t\trule: (t: string) => void,\n\t\trow: (t: string) => void,\n\t\tend: () => void,\n\t): void {\n\t\tif (s.repos.length === 0) return;\n\t\trule(\"Repos\");\n\t\tconst activeName = s.repo?.name;\n\t\tfor (const repo of s.repos.slice(0, 5)) {\n\t\t\tconst short = repo.name.split(\"/\").pop() ?? repo.name;\n\t\t\tconst count = theme.fg(\"muted\", formatSymbolCount(repo.symbols));\n\t\t\tif (repo.name === activeName) {\n\t\t\t\trow(`${theme.fg(\"accent\", \"●\")} ${theme.fg(\"accent\", short)} ${count}`);\n\t\t\t} else {\n\t\t\t\trow(`${theme.fg(\"muted\", \"○\")} ${theme.fg(\"muted\", short)} ${count}`);\n\t\t\t}\n\t\t}\n\t\tif (s.repos.length > 5) row(theme.fg(\"muted\", ` … +${s.repos.length - 5} more`));\n\t\tend();\n\t}\n\n\tprivate renderStatus(\n\t\ts: Readonly<GraphRailState>,\n\t\twidth: number,\n\t\trule: (t: string) => void,\n\t\trow: (t: string) => void,\n\t\tend: () => void,\n\t): void {\n\t\trule(\"GitNexus\");\n\t\tif (s.indexProgress) {\n\t\t\tconst progress = s.indexProgress;\n\t\t\tconst phase = formatCompactIndexPhase(progress.phase);\n\t\t\trow(theme.bold(progress.fullName.split(\"/\").pop() ?? progress.fullName));\n\t\t\tconst percent =\n\t\t\t\tprogress.percent === undefined ? undefined : Math.max(0, Math.min(100, Math.round(progress.percent)));\n\t\t\trow(\n\t\t\t\tpercent === undefined\n\t\t\t\t\t? theme.fg(\"muted\", phase)\n\t\t\t\t\t: `${theme.fg(\"muted\", phase)} ${theme.fg(\"accent\", `${percent}%`)}`,\n\t\t\t);\n\t\t\tif (percent !== undefined) {\n\t\t\t\tconst filled = Math.round((percent / 100) * width);\n\t\t\t\trow(theme.fg(\"accent\", \"━\".repeat(filled)) + theme.fg(\"dim\", \"─\".repeat(width - filled)));\n\t\t\t}\n\t\t\tend();\n\t\t\treturn;\n\t\t}\n\t\tif (!s.repo) {\n\t\t\trow(theme.fg(\"muted\", \"not connected\"));\n\t\t\tend();\n\t\t\treturn;\n\t\t}\n\t\tif (s.currentIndexed) {\n\t\t\trow(theme.bold(s.repo.name.split(\"/\").pop() ?? s.repo.name));\n\t\t\trow(theme.fg(\"muted\", `${s.repo.symbols} symbols · ${s.repo.repoCount} repos`));\n\t\t\trow(theme.fg(\"muted\", `indexed ${s.repo.indexedAt.split(\" GMT\")[0] ?? s.repo.indexedAt}`));\n\t\t} else {\n\t\t\trow(theme.fg(\"warning\", \"repo not indexed\"));\n\t\t\trow(theme.fg(\"muted\", `${s.repo.repoCount} repos queryable`));\n\t\t}\n\t\trow(theme.fg(\"muted\", `graph calls ${s.graphCalls} · impact ${s.impactChecks}`));\n\t\tend();\n\t}\n\n\tprivate renderImpact(\n\t\ts: Readonly<GraphRailState>,\n\t\trule: (t: string) => void,\n\t\trow: (t: string) => void,\n\t\tend: () => void,\n\t): void {\n\t\tconst impact = s.impact;\n\t\tif (!impact) return;\n\t\trule(\"Blast Radius\");\n\t\tconst risk = impact.risk.toUpperCase();\n\t\tconst riskColor = risk === \"HIGH\" || risk === \"CRITICAL\" ? \"error\" : risk === \"MEDIUM\" ? \"warning\" : \"success\";\n\t\trow(`${theme.fg(\"accent\", \"◉\")} ${theme.bold(impact.target)}`);\n\t\trow(theme.fg(riskColor, `risk: ${risk}`));\n\t\tconst depths = Object.keys(impact.byDepth)\n\t\t\t.map(Number)\n\t\t\t.filter((d) => !Number.isNaN(d))\n\t\t\t.sort((a, b) => a - b);\n\t\tfor (const depth of depths.slice(0, 3)) {\n\t\t\tconst nodes = impact.byDepth[String(depth)] ?? [];\n\t\t\tif (nodes.length === 0) continue;\n\t\t\tconst color = depth === 1 ? \"error\" : depth === 2 ? \"warning\" : \"muted\";\n\t\t\tconst label = depth === 1 ? \"breaks\" : depth === 2 ? \"test\" : \"transitive\";\n\t\t\trow(theme.fg(color, `d${depth} ${label} (${nodes.length})`));\n\t\t\tfor (const node of nodes.slice(0, 3)) {\n\t\t\t\tconst lowConfidence = node.confidence !== undefined && node.confidence < CONFIDENCE_DIM_THRESHOLD;\n\t\t\t\tconst name = lowConfidence ? theme.fg(\"dim\", `${node.name}?`) : node.name;\n\t\t\t\trow(` ${theme.fg(lowConfidence ? \"dim\" : color, depth === 1 ? \"●\" : \"○\")} ${name}`);\n\t\t\t}\n\t\t\tif (nodes.length > 3) row(theme.fg(\"muted\", ` … +${nodes.length - 3}`));\n\t\t}\n\t\tif (impact.processes.length > 0) row(theme.fg(\"muted\", `flows: ${impact.processes.slice(0, 2).join(\", \")}`));\n\t\tif (impact.modules.length > 0) {\n\t\t\tconst maxHits = Math.max(...impact.modules.map((m) => m.hits), 1);\n\t\t\tfor (const module of impact.modules.slice(0, 3)) {\n\t\t\t\tconst filled = Math.max(1, Math.round((module.hits / maxHits) * 5));\n\t\t\t\tconst bar =\n\t\t\t\t\ttheme.fg(module.direct ? \"accent\" : \"muted\", \"▮\".repeat(filled)) +\n\t\t\t\t\ttheme.fg(\"dim\", \"▯\".repeat(5 - filled));\n\t\t\t\trow(`${bar} ${theme.fg(\"muted\", module.name)} ${theme.fg(\"dim\", String(module.hits))}`);\n\t\t\t}\n\t\t}\n\t\tend();\n\t}\n\n\tprivate renderQuery(\n\t\ts: Readonly<GraphRailState>,\n\t\trule: (t: string) => void,\n\t\trow: (t: string) => void,\n\t\tend: () => void,\n\t): void {\n\t\tconst query = s.query;\n\t\tif (!query) return;\n\t\trule(\"Flows\");\n\t\trow(theme.fg(\"muted\", clipQuery(query.query)));\n\t\tquery.flows.slice(0, 3).forEach((flow, i) => {\n\t\t\tconst marker = i === 0 ? theme.fg(\"accent\", \"◉\") : theme.fg(\"muted\", \"○\");\n\t\t\tconst steps = flow.stepCount ? theme.fg(\"muted\", ` ·${flow.stepCount}`) : \"\";\n\t\t\trow(`${marker} ${flow.summary}${steps}`);\n\t\t});\n\t\tend();\n\t}\n\n\tprivate renderSkills(rule: (t: string) => void, row: (t: string) => void, end: () => void): void {\n\t\tconst skills = this.hostInfo?.skills ?? [];\n\t\tif (skills.length === 0) return;\n\t\trule(\"Skills\");\n\t\tfor (const skill of skills.slice(0, 8)) {\n\t\t\trow(`${theme.fg(\"success\", \"\\u25cf\")} ${theme.fg(\"muted\", skill)}`);\n\t\t}\n\t\tif (skills.length > 8) row(theme.fg(\"muted\", ` \\u2026 +${skills.length - 8} more`));\n\t\tend();\n\t}\n\n\tprivate renderChanges(\n\t\ts: Readonly<GraphRailState>,\n\t\trule: (t: string) => void,\n\t\trow: (t: string) => void,\n\t\tend: () => void,\n\t): void {\n\t\trule(\"Modified Files\");\n\t\tif (s.changes.length === 0) {\n\t\t\trow(theme.fg(\"muted\", \"None\"));\n\t\t\tend();\n\t\t\treturn;\n\t\t}\n\t\tfor (const change of s.changes.slice(-5)) {\n\t\t\trow(\n\t\t\t\t`${basename(change.path)} ${theme.fg(\"success\", `+${change.added}`)} ${theme.fg(\"error\", `-${change.removed}`)}`,\n\t\t\t);\n\t\t}\n\t\tend();\n\t}\n}\n\nfunction clipQuery(query: string): string {\n\treturn query.length > 30 ? `${query.slice(0, 29)}…` : `“${query}”`;\n}\n\n/** Full-width expansion of a rail card, appended to the transcript on click. */\nexport function renderExpandedCard(card: GraphRailCard, hostInfo?: GraphRailHostInfo): string | undefined {\n\tconst s = graphRailStore.getState();\n\tconst header = (title: string) => theme.bold(theme.fg(\"accent\", `── GitNexus · ${title} ──`));\n\tif (card === \"repos\" && s.repos.length > 0) {\n\t\tconst lines: string[] = [header(\"indexed repos\")];\n\t\tfor (const repo of s.repos) {\n\t\t\tconst marker = repo.name === s.repo?.name ? theme.fg(\"accent\", \"●\") : theme.fg(\"muted\", \"○\");\n\t\t\tlines.push(`${marker} ${repo.name} ${theme.fg(\"muted\", `${repo.symbols} symbols`)}`);\n\t\t}\n\t\treturn lines.join(\"\\n\");\n\t}\n\tif (card === \"skills\" && hostInfo && hostInfo.skills.length > 0) {\n\t\tconst lines: string[] = [header(\"skills\")];\n\t\tfor (const skill of hostInfo.skills) {\n\t\t\tlines.push(`${theme.fg(\"success\", \"●\")} ${skill}`);\n\t\t}\n\t\treturn lines.join(\"\\n\");\n\t}\n\tif (card === \"impact\" && s.impact) {\n\t\tconst lines: string[] = [header(\"blast radius\")];\n\t\tconst risk = s.impact.risk.toUpperCase();\n\t\tconst riskColor = risk === \"HIGH\" || risk === \"CRITICAL\" ? \"error\" : risk === \"MEDIUM\" ? \"warning\" : \"success\";\n\t\tlines.push(\n\t\t\t`${theme.fg(\"accent\", \"◉\")} ${theme.bold(s.impact.target)} ${theme.fg(\"muted\", s.impact.filePath ?? \"\")} ${theme.bold(theme.fg(riskColor, `RISK: ${risk}`))}`,\n\t\t);\n\t\tconst depths = Object.keys(s.impact.byDepth)\n\t\t\t.map(Number)\n\t\t\t.filter((d) => !Number.isNaN(d))\n\t\t\t.sort((a, b) => a - b);\n\t\tfor (const depth of depths) {\n\t\t\tconst nodes = s.impact.byDepth[String(depth)] ?? [];\n\t\t\tif (nodes.length === 0) continue;\n\t\t\tconst color = depth === 1 ? \"error\" : depth === 2 ? \"warning\" : \"muted\";\n\t\t\tconst label = depth === 1 ? \"WILL BREAK\" : depth === 2 ? \"should test\" : \"transitive\";\n\t\t\tlines.push(theme.fg(color, `d=${depth} ${label} (${nodes.length})`));\n\t\t\tfor (const node of nodes) {\n\t\t\t\tconst rel = node.relationType ? theme.fg(\"muted\", ` (${node.relationType})`) : \"\";\n\t\t\t\tlines.push(\n\t\t\t\t\t` ${theme.fg(color, depth === 1 ? \"●\" : \"○\")} ${node.name} ${theme.fg(\"muted\", node.filePath ?? \"\")}${rel}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tif (s.impact.processes.length > 0)\n\t\t\tlines.push(theme.fg(\"muted\", `flows affected: ${s.impact.processes.join(\", \")}`));\n\t\tif (s.impact.modules.length > 0)\n\t\t\tlines.push(\n\t\t\t\ttheme.fg(\n\t\t\t\t\t\"muted\",\n\t\t\t\t\t`modules: ${s.impact.modules.map((m) => `${m.name} (${m.hits}${m.direct ? \", direct\" : \"\"})`).join(\", \")}`,\n\t\t\t\t),\n\t\t\t);\n\t\treturn lines.join(\"\\n\");\n\t}\n\tif (card === \"flows\" && s.query) {\n\t\tconst lines: string[] = [header(\"flows\"), theme.fg(\"muted\", `query: “${s.query.query}”`)];\n\t\ts.query.flows.forEach((flow, i) => {\n\t\t\tconst marker = i === 0 ? theme.fg(\"accent\", \"◉\") : theme.fg(\"muted\", \"○\");\n\t\t\tlines.push(\n\t\t\t\t`${marker} ${flow.summary}${flow.stepCount ? theme.fg(\"muted\", ` · ${flow.stepCount} steps`) : \"\"}`,\n\t\t\t);\n\t\t});\n\t\treturn lines.join(\"\\n\");\n\t}\n\tif (card === \"changes\" && s.changes.length > 0) {\n\t\tconst lines: string[] = [header(\"session changes\")];\n\t\tfor (const change of s.changes) {\n\t\t\tlines.push(\n\t\t\t\t`${theme.fg(\"success\", `+${change.added}`)} ${theme.fg(\"error\", `-${change.removed}`)} ${change.path}`,\n\t\t\t);\n\t\t}\n\t\treturn lines.join(\"\\n\");\n\t}\n\tif (card === \"status\" && s.repo) {\n\t\treturn [\n\t\t\theader(\"status\"),\n\t\t\t`repo: ${s.repo.name || \"(current dir not indexed)\"} · ${s.repo.symbols} symbols`,\n\t\t\t`indexed: ${s.repo.indexedAt || \"n/a\"} · ${s.repo.repoCount} repos on hub`,\n\t\t\t`graph calls: ${s.graphCalls} · impact checks: ${s.impactChecks}`,\n\t\t].join(\"\\n\");\n\t}\n\treturn undefined;\n}\n"]}
@@ -4,6 +4,7 @@
4
4
  import { type Keybinding } from "@earendil-works/pi-tui";
5
5
  export interface KeyTextFormatOptions {
6
6
  capitalize?: boolean;
7
+ platform?: NodeJS.Platform;
7
8
  }
8
9
  export declare function formatKeyText(key: string, options?: KeyTextFormatOptions): string;
9
10
  export declare function keyText(keybinding: Keybinding): string;
@@ -1 +1 @@
1
- {"version":3,"file":"keybinding-hints.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/keybinding-hints.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAkB,KAAK,UAAU,EAAc,MAAM,wBAAwB,CAAC;AAGrF,MAAM,WAAW,oBAAoB;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAOD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,GAAG,MAAM,CAUrF;AAOD,wBAAgB,OAAO,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAEtD;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAE7D;AAED,wBAAgB,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAEnE","sourcesContent":["/**\n * Utilities for formatting keybinding hints in the UI.\n */\n\nimport { getKeybindings, type Keybinding, type KeyId } from \"@earendil-works/pi-tui\";\nimport { theme } from \"../theme/theme.ts\";\n\nexport interface KeyTextFormatOptions {\n\tcapitalize?: boolean;\n}\n\nfunction formatKeyPart(part: string, options: KeyTextFormatOptions): string {\n\tconst displayPart = process.platform === \"darwin\" && part.toLowerCase() === \"alt\" ? \"option\" : part;\n\treturn options.capitalize ? displayPart.charAt(0).toUpperCase() + displayPart.slice(1) : displayPart;\n}\n\nexport function formatKeyText(key: string, options: KeyTextFormatOptions = {}): string {\n\treturn key\n\t\t.split(\"/\")\n\t\t.map((k) =>\n\t\t\tk\n\t\t\t\t.split(\"+\")\n\t\t\t\t.map((part) => formatKeyPart(part, options))\n\t\t\t\t.join(\"+\"),\n\t\t)\n\t\t.join(\"/\");\n}\n\nfunction formatKeys(keys: KeyId[], options: KeyTextFormatOptions = {}): string {\n\tif (keys.length === 0) return \"\";\n\treturn formatKeyText(keys.join(\"/\"), options);\n}\n\nexport function keyText(keybinding: Keybinding): string {\n\treturn formatKeys(getKeybindings().getKeys(keybinding));\n}\n\nexport function keyDisplayText(keybinding: Keybinding): string {\n\treturn formatKeys(getKeybindings().getKeys(keybinding), { capitalize: true });\n}\n\nexport function keyHint(keybinding: Keybinding, description: string): string {\n\treturn theme.fg(\"dim\", keyText(keybinding)) + theme.fg(\"muted\", ` ${description}`);\n}\n\nexport function rawKeyHint(key: string, description: string): string {\n\treturn theme.fg(\"dim\", formatKeyText(key)) + theme.fg(\"muted\", ` ${description}`);\n}\n"]}
1
+ {"version":3,"file":"keybinding-hints.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/keybinding-hints.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAkB,KAAK,UAAU,EAAc,MAAM,wBAAwB,CAAC;AAGrF,MAAM,WAAW,oBAAoB;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;CAC3B;AAcD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,GAAG,MAAM,CAUrF;AAOD,wBAAgB,OAAO,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAEtD;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAE7D;AAED,wBAAgB,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAEnE","sourcesContent":["/**\n * Utilities for formatting keybinding hints in the UI.\n */\n\nimport { getKeybindings, type Keybinding, type KeyId } from \"@earendil-works/pi-tui\";\nimport { theme } from \"../theme/theme.ts\";\n\nexport interface KeyTextFormatOptions {\n\tcapitalize?: boolean;\n\tplatform?: NodeJS.Platform;\n}\n\nfunction formatKeyPart(part: string, options: KeyTextFormatOptions): string {\n\tconst platform = options.platform ?? process.platform;\n\tconst normalizedPart = part.toLowerCase();\n\tconst displayPart =\n\t\tplatform === \"darwin\" && normalizedPart === \"alt\"\n\t\t\t? \"option\"\n\t\t\t: platform === \"darwin\" && normalizedPart === \"super\"\n\t\t\t\t? \"cmd\"\n\t\t\t\t: part;\n\treturn options.capitalize ? displayPart.charAt(0).toUpperCase() + displayPart.slice(1) : displayPart;\n}\n\nexport function formatKeyText(key: string, options: KeyTextFormatOptions = {}): string {\n\treturn key\n\t\t.split(\"/\")\n\t\t.map((k) =>\n\t\t\tk\n\t\t\t\t.split(\"+\")\n\t\t\t\t.map((part) => formatKeyPart(part, options))\n\t\t\t\t.join(\"+\"),\n\t\t)\n\t\t.join(\"/\");\n}\n\nfunction formatKeys(keys: KeyId[], options: KeyTextFormatOptions = {}): string {\n\tif (keys.length === 0) return \"\";\n\treturn formatKeyText(keys.join(\"/\"), options);\n}\n\nexport function keyText(keybinding: Keybinding): string {\n\treturn formatKeys(getKeybindings().getKeys(keybinding));\n}\n\nexport function keyDisplayText(keybinding: Keybinding): string {\n\treturn formatKeys(getKeybindings().getKeys(keybinding), { capitalize: true });\n}\n\nexport function keyHint(keybinding: Keybinding, description: string): string {\n\treturn theme.fg(\"dim\", keyText(keybinding)) + theme.fg(\"muted\", ` ${description}`);\n}\n\nexport function rawKeyHint(key: string, description: string): string {\n\treturn theme.fg(\"dim\", formatKeyText(key)) + theme.fg(\"muted\", ` ${description}`);\n}\n"]}
@@ -4,7 +4,13 @@
4
4
  import { getKeybindings } from "@earendil-works/pi-tui";
5
5
  import { theme } from "../theme/theme.js";
6
6
  function formatKeyPart(part, options) {
7
- const displayPart = process.platform === "darwin" && part.toLowerCase() === "alt" ? "option" : part;
7
+ const platform = options.platform ?? process.platform;
8
+ const normalizedPart = part.toLowerCase();
9
+ const displayPart = platform === "darwin" && normalizedPart === "alt"
10
+ ? "option"
11
+ : platform === "darwin" && normalizedPart === "super"
12
+ ? "cmd"
13
+ : part;
8
14
  return options.capitalize ? displayPart.charAt(0).toUpperCase() + displayPart.slice(1) : displayPart;
9
15
  }
10
16
  export function formatKeyText(key, options = {}) {
@@ -1 +1 @@
1
- {"version":3,"file":"keybinding-hints.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/keybinding-hints.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAA+B,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAM1C,SAAS,aAAa,CAAC,IAAY,EAAE,OAA6B,EAAU;IAC3E,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,KAAK,QAAQ,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;IACpG,OAAO,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;AAAA,CACrG;AAED,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,OAAO,GAAyB,EAAE,EAAU;IACtF,OAAO,GAAG;SACR,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACV,CAAC;SACC,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;SAC3C,IAAI,CAAC,GAAG,CAAC,CACX;SACA,IAAI,CAAC,GAAG,CAAC,CAAC;AAAA,CACZ;AAED,SAAS,UAAU,CAAC,IAAa,EAAE,OAAO,GAAyB,EAAE,EAAU;IAC9E,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AAAA,CAC9C;AAED,MAAM,UAAU,OAAO,CAAC,UAAsB,EAAU;IACvD,OAAO,UAAU,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;AAAA,CACxD;AAED,MAAM,UAAU,cAAc,CAAC,UAAsB,EAAU;IAC9D,OAAO,UAAU,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;AAAA,CAC9E;AAED,MAAM,UAAU,OAAO,CAAC,UAAsB,EAAE,WAAmB,EAAU;IAC5E,OAAO,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,WAAW,EAAE,CAAC,CAAC;AAAA,CACnF;AAED,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,WAAmB,EAAU;IACpE,OAAO,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,WAAW,EAAE,CAAC,CAAC;AAAA,CAClF","sourcesContent":["/**\n * Utilities for formatting keybinding hints in the UI.\n */\n\nimport { getKeybindings, type Keybinding, type KeyId } from \"@earendil-works/pi-tui\";\nimport { theme } from \"../theme/theme.ts\";\n\nexport interface KeyTextFormatOptions {\n\tcapitalize?: boolean;\n}\n\nfunction formatKeyPart(part: string, options: KeyTextFormatOptions): string {\n\tconst displayPart = process.platform === \"darwin\" && part.toLowerCase() === \"alt\" ? \"option\" : part;\n\treturn options.capitalize ? displayPart.charAt(0).toUpperCase() + displayPart.slice(1) : displayPart;\n}\n\nexport function formatKeyText(key: string, options: KeyTextFormatOptions = {}): string {\n\treturn key\n\t\t.split(\"/\")\n\t\t.map((k) =>\n\t\t\tk\n\t\t\t\t.split(\"+\")\n\t\t\t\t.map((part) => formatKeyPart(part, options))\n\t\t\t\t.join(\"+\"),\n\t\t)\n\t\t.join(\"/\");\n}\n\nfunction formatKeys(keys: KeyId[], options: KeyTextFormatOptions = {}): string {\n\tif (keys.length === 0) return \"\";\n\treturn formatKeyText(keys.join(\"/\"), options);\n}\n\nexport function keyText(keybinding: Keybinding): string {\n\treturn formatKeys(getKeybindings().getKeys(keybinding));\n}\n\nexport function keyDisplayText(keybinding: Keybinding): string {\n\treturn formatKeys(getKeybindings().getKeys(keybinding), { capitalize: true });\n}\n\nexport function keyHint(keybinding: Keybinding, description: string): string {\n\treturn theme.fg(\"dim\", keyText(keybinding)) + theme.fg(\"muted\", ` ${description}`);\n}\n\nexport function rawKeyHint(key: string, description: string): string {\n\treturn theme.fg(\"dim\", formatKeyText(key)) + theme.fg(\"muted\", ` ${description}`);\n}\n"]}
1
+ {"version":3,"file":"keybinding-hints.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/keybinding-hints.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAA+B,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAO1C,SAAS,aAAa,CAAC,IAAY,EAAE,OAA6B,EAAU;IAC3E,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IACtD,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAC1C,MAAM,WAAW,GAChB,QAAQ,KAAK,QAAQ,IAAI,cAAc,KAAK,KAAK;QAChD,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,cAAc,KAAK,OAAO;YACpD,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,IAAI,CAAC;IACV,OAAO,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;AAAA,CACrG;AAED,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,OAAO,GAAyB,EAAE,EAAU;IACtF,OAAO,GAAG;SACR,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACV,CAAC;SACC,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;SAC3C,IAAI,CAAC,GAAG,CAAC,CACX;SACA,IAAI,CAAC,GAAG,CAAC,CAAC;AAAA,CACZ;AAED,SAAS,UAAU,CAAC,IAAa,EAAE,OAAO,GAAyB,EAAE,EAAU;IAC9E,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AAAA,CAC9C;AAED,MAAM,UAAU,OAAO,CAAC,UAAsB,EAAU;IACvD,OAAO,UAAU,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;AAAA,CACxD;AAED,MAAM,UAAU,cAAc,CAAC,UAAsB,EAAU;IAC9D,OAAO,UAAU,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;AAAA,CAC9E;AAED,MAAM,UAAU,OAAO,CAAC,UAAsB,EAAE,WAAmB,EAAU;IAC5E,OAAO,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,WAAW,EAAE,CAAC,CAAC;AAAA,CACnF;AAED,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,WAAmB,EAAU;IACpE,OAAO,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,WAAW,EAAE,CAAC,CAAC;AAAA,CAClF","sourcesContent":["/**\n * Utilities for formatting keybinding hints in the UI.\n */\n\nimport { getKeybindings, type Keybinding, type KeyId } from \"@earendil-works/pi-tui\";\nimport { theme } from \"../theme/theme.ts\";\n\nexport interface KeyTextFormatOptions {\n\tcapitalize?: boolean;\n\tplatform?: NodeJS.Platform;\n}\n\nfunction formatKeyPart(part: string, options: KeyTextFormatOptions): string {\n\tconst platform = options.platform ?? process.platform;\n\tconst normalizedPart = part.toLowerCase();\n\tconst displayPart =\n\t\tplatform === \"darwin\" && normalizedPart === \"alt\"\n\t\t\t? \"option\"\n\t\t\t: platform === \"darwin\" && normalizedPart === \"super\"\n\t\t\t\t? \"cmd\"\n\t\t\t\t: part;\n\treturn options.capitalize ? displayPart.charAt(0).toUpperCase() + displayPart.slice(1) : displayPart;\n}\n\nexport function formatKeyText(key: string, options: KeyTextFormatOptions = {}): string {\n\treturn key\n\t\t.split(\"/\")\n\t\t.map((k) =>\n\t\t\tk\n\t\t\t\t.split(\"+\")\n\t\t\t\t.map((part) => formatKeyPart(part, options))\n\t\t\t\t.join(\"+\"),\n\t\t)\n\t\t.join(\"/\");\n}\n\nfunction formatKeys(keys: KeyId[], options: KeyTextFormatOptions = {}): string {\n\tif (keys.length === 0) return \"\";\n\treturn formatKeyText(keys.join(\"/\"), options);\n}\n\nexport function keyText(keybinding: Keybinding): string {\n\treturn formatKeys(getKeybindings().getKeys(keybinding));\n}\n\nexport function keyDisplayText(keybinding: Keybinding): string {\n\treturn formatKeys(getKeybindings().getKeys(keybinding), { capitalize: true });\n}\n\nexport function keyHint(keybinding: Keybinding, description: string): string {\n\treturn theme.fg(\"dim\", keyText(keybinding)) + theme.fg(\"muted\", ` ${description}`);\n}\n\nexport function rawKeyHint(key: string, description: string): string {\n\treturn theme.fg(\"dim\", formatKeyText(key)) + theme.fg(\"muted\", ` ${description}`);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"landing-panel.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/landing-panel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAgCxD,qBAAa,qBAAsB,YAAW,SAAS;IACtD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAC3C,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,SAAS,CAA6C;IAC9D,OAAO,CAAC,gBAAgB,CAAc;IAEtC,YAAY,SAAS,EAAE,MAAM,MAAM,EAAE,EAAE,aAAa,EAAE,MAAM,IAAI,EAW/D;IAED,OAAO,CAAC,aAAa;IAKrB,OAAO,IAAI,IAAI,CAId;IAED,UAAU,IAAI,IAAI,CAEjB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ9B;IAED,OAAO,CAAC,YAAY;CAwDpB","sourcesContent":["import type { Component } from \"@earendil-works/pi-tui\";\nimport { visibleWidth } from \"@earendil-works/pi-tui\";\nimport { type GraphRailState, graphRailStore } from \"../../../core/graph-rail-store.ts\";\nimport { tryLoadObservatoryCache } from \"../../../core/observatory-cache.ts\";\nimport { theme } from \"../theme/theme.ts\";\n\n/** Startup resource summary: GitNexus graph, skills, and indexed repositories. */\n\nconst COLUMN_GAP = 3;\nconst MIN_COLUMN_WIDTH = 22;\nconst MAX_COLUMN_WIDTH = 32;\n\nfunction clipTo(text: string, width: number): string {\n\tif (visibleWidth(text) <= width) return text;\n\tlet out = \"\";\n\tlet visible = 0;\n\tfor (let i = 0; i < text.length; i++) {\n\t\tif (text[i] === \"\\x1b\") {\n\t\t\tconst match = text.slice(i).match(/^\\x1b\\[[0-9;]*m/);\n\t\t\tif (match) {\n\t\t\t\tout += match[0];\n\t\t\t\ti += match[0].length - 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tif (visible >= width - 1) break;\n\t\tout += text[i];\n\t\tvisible++;\n\t}\n\treturn `${out}…\\x1b[0m`;\n}\n\nexport class LandingPanelComponent implements Component {\n\tprivate readonly getSkills: () => string[];\n\tprivate unsubscribe: (() => void) | undefined;\n\tprivate cachePoll: ReturnType<typeof setInterval> | undefined;\n\tprivate cachePollStarted = Date.now();\n\n\tconstructor(getSkills: () => string[], onDataChanged: () => void) {\n\t\tthis.getSkills = getSkills;\n\t\tthis.unsubscribe = graphRailStore.subscribe(onDataChanged);\n\t\tthis.cachePoll = setInterval(() => {\n\t\t\tconst s = graphRailStore.getState();\n\t\t\tif (Date.now() - this.cachePollStarted > 60_000) {\n\t\t\t\tthis.stopCachePoll();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (s.repo?.name && s.currentIndexed) tryLoadObservatoryCache(s.repo.name);\n\t\t}, 1500);\n\t}\n\n\tprivate stopCachePoll(): void {\n\t\tif (this.cachePoll) clearInterval(this.cachePoll);\n\t\tthis.cachePoll = undefined;\n\t}\n\n\tdispose(): void {\n\t\tthis.unsubscribe?.();\n\t\tthis.unsubscribe = undefined;\n\t\tthis.stopCachePoll();\n\t}\n\n\tinvalidate(): void {\n\t\t// Pure view over graphRailStore and loaded skills.\n\t}\n\n\trender(width: number): string[] {\n\t\tconst s = graphRailStore.getState();\n\t\tconst skillNames = this.getSkills();\n\t\tif (!s.repo && s.repos.length === 0 && skillNames.length === 0) return [];\n\t\tif (s.repo?.name && s.currentIndexed) tryLoadObservatoryCache(s.repo.name);\n\n\t\tconst lines: string[] = [\"\", ...this.buildColumns(s, width, skillNames)];\n\t\treturn lines.map((line) => clipTo(line, width));\n\t}\n\n\tprivate buildColumns(s: Readonly<GraphRailState>, width: number, skillNames: string[]): string[] {\n\t\tconst columnWidth = Math.min(\n\t\t\tMAX_COLUMN_WIDTH,\n\t\t\tMath.max(MIN_COLUMN_WIDTH, Math.floor((width - 2 * COLUMN_GAP) / 3)),\n\t\t);\n\t\tconst graph: string[] = [theme.fg(\"muted\", \"Graph\")];\n\t\tif (s.repo && s.currentIndexed) {\n\t\t\tgraph.push(`${theme.fg(\"success\", \"●\")} ${theme.bold(s.repo.name.split(\"/\").pop() ?? s.repo.name)}`);\n\t\t\tgraph.push(theme.fg(\"muted\", `${s.repo.symbols} symbols`));\n\t\t\tgraph.push(theme.fg(\"muted\", `${s.repo.relationships} relationships`));\n\t\t\tif (s.observatory) {\n\t\t\t\tconst flows = s.observatory.flowCount !== undefined ? ` · ${s.observatory.flowCount} flows` : \"\";\n\t\t\t\tgraph.push(theme.fg(\"muted\", `${s.observatory.communities.length} communities${flows}`));\n\t\t\t}\n\t\t} else if (s.repo) {\n\t\t\tgraph.push(`${theme.fg(\"warning\", \"○\")} ${theme.fg(\"warning\", \"repo not indexed\")}`);\n\t\t\tgraph.push(theme.fg(\"muted\", `${s.repo.repoCount} repos queryable`));\n\t\t} else {\n\t\t\tgraph.push(theme.fg(\"muted\", \"not connected\"));\n\t\t}\n\n\t\tconst skills: string[] = [theme.fg(\"muted\", \"Skills\")];\n\t\tfor (const name of skillNames.slice(0, 6)) {\n\t\t\tskills.push(`${theme.fg(\"success\", \"●\")} ${name}`);\n\t\t}\n\t\tif (skillNames.length > 6) skills.push(theme.fg(\"muted\", ` +${skillNames.length - 6} more`));\n\t\tif (skillNames.length === 0) skills.push(theme.fg(\"muted\", \"none\"));\n\n\t\tconst repos: string[] = [theme.fg(\"muted\", \"Indexed repos\")];\n\t\tconst activeName = s.repo?.name;\n\t\tconst ordered = activeName\n\t\t\t? [\n\t\t\t\t\t...s.repos.filter((repo) => repo.name === activeName),\n\t\t\t\t\t...s.repos.filter((repo) => repo.name !== activeName),\n\t\t\t\t]\n\t\t\t: s.repos;\n\t\tfor (const repo of ordered.slice(0, 6)) {\n\t\t\tconst short = repo.name.split(\"/\").pop() ?? repo.name;\n\t\t\tconst active = repo.name === s.repo?.name;\n\t\t\tconst marker = active ? theme.fg(\"accent\", \"●\") : theme.fg(\"muted\", \"○\");\n\t\t\tconst label = active ? theme.fg(\"accent\", short) : short;\n\t\t\trepos.push(`${marker} ${label} ${theme.fg(\"dim\", formatCount(repo.symbols))}`);\n\t\t}\n\t\tif (s.repos.length > 6) repos.push(theme.fg(\"muted\", ` +${s.repos.length - 6} more`));\n\t\tif (s.repos.length === 0) repos.push(theme.fg(\"muted\", \"none\"));\n\n\t\tconst rows = Math.max(graph.length, skills.length, repos.length);\n\t\tconst lines: string[] = [];\n\t\tfor (let i = 0; i < rows; i++) {\n\t\t\tconst graphCell = padTo(clipTo(graph[i] ?? \"\", columnWidth), columnWidth);\n\t\t\tconst skillCell = padTo(clipTo(skills[i] ?? \"\", columnWidth), columnWidth);\n\t\t\tconst repoCell = clipTo(repos[i] ?? \"\", columnWidth);\n\t\t\tlines.push(` ${graphCell}${\" \".repeat(COLUMN_GAP)}${skillCell}${\" \".repeat(COLUMN_GAP)}${repoCell}`);\n\t\t}\n\t\treturn lines;\n\t}\n}\n\nfunction padTo(text: string, width: number): string {\n\treturn text + \" \".repeat(Math.max(0, width - visibleWidth(text)));\n}\n\nfunction formatCount(symbols: string): string {\n\tconst count = Number(symbols.replace(/,/g, \"\"));\n\tif (Number.isNaN(count)) return symbols;\n\tif (count >= 1_000_000) return `${(count / 1_000_000).toFixed(1)}M`;\n\tif (count >= 1_000) return `${Math.round(count / 1_000)}k`;\n\treturn String(count);\n}\n"]}
1
+ {"version":3,"file":"landing-panel.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/landing-panel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAgCxD,qBAAa,qBAAsB,YAAW,SAAS;IACtD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAC3C,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,SAAS,CAA6C;IAC9D,OAAO,CAAC,gBAAgB,CAAc;IAEtC,YAAY,SAAS,EAAE,MAAM,MAAM,EAAE,EAAE,aAAa,EAAE,MAAM,IAAI,EAW/D;IAED,OAAO,CAAC,aAAa;IAKrB,OAAO,IAAI,IAAI,CAId;IAED,UAAU,IAAI,IAAI,CAEjB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ9B;IAED,OAAO,CAAC,YAAY;CAyEpB","sourcesContent":["import type { Component } from \"@earendil-works/pi-tui\";\nimport { visibleWidth } from \"@earendil-works/pi-tui\";\nimport { formatCompactIndexPhase, type GraphRailState, graphRailStore } from \"../../../core/graph-rail-store.ts\";\nimport { tryLoadObservatoryCache } from \"../../../core/observatory-cache.ts\";\nimport { theme } from \"../theme/theme.ts\";\n\n/** Startup resource summary: GitNexus graph, skills, and indexed repositories. */\n\nconst COLUMN_GAP = 3;\nconst MIN_COLUMN_WIDTH = 22;\nconst MAX_COLUMN_WIDTH = 32;\n\nfunction clipTo(text: string, width: number): string {\n\tif (visibleWidth(text) <= width) return text;\n\tlet out = \"\";\n\tlet visible = 0;\n\tfor (let i = 0; i < text.length; i++) {\n\t\tif (text[i] === \"\\x1b\") {\n\t\t\tconst match = text.slice(i).match(/^\\x1b\\[[0-9;]*m/);\n\t\t\tif (match) {\n\t\t\t\tout += match[0];\n\t\t\t\ti += match[0].length - 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tif (visible >= width - 1) break;\n\t\tout += text[i];\n\t\tvisible++;\n\t}\n\treturn `${out}…\\x1b[0m`;\n}\n\nexport class LandingPanelComponent implements Component {\n\tprivate readonly getSkills: () => string[];\n\tprivate unsubscribe: (() => void) | undefined;\n\tprivate cachePoll: ReturnType<typeof setInterval> | undefined;\n\tprivate cachePollStarted = Date.now();\n\n\tconstructor(getSkills: () => string[], onDataChanged: () => void) {\n\t\tthis.getSkills = getSkills;\n\t\tthis.unsubscribe = graphRailStore.subscribe(onDataChanged);\n\t\tthis.cachePoll = setInterval(() => {\n\t\t\tconst s = graphRailStore.getState();\n\t\t\tif (Date.now() - this.cachePollStarted > 60_000) {\n\t\t\t\tthis.stopCachePoll();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (s.repo?.name && s.currentIndexed) tryLoadObservatoryCache(s.repo.name);\n\t\t}, 1500);\n\t}\n\n\tprivate stopCachePoll(): void {\n\t\tif (this.cachePoll) clearInterval(this.cachePoll);\n\t\tthis.cachePoll = undefined;\n\t}\n\n\tdispose(): void {\n\t\tthis.unsubscribe?.();\n\t\tthis.unsubscribe = undefined;\n\t\tthis.stopCachePoll();\n\t}\n\n\tinvalidate(): void {\n\t\t// Pure view over graphRailStore and loaded skills.\n\t}\n\n\trender(width: number): string[] {\n\t\tconst s = graphRailStore.getState();\n\t\tconst skillNames = this.getSkills();\n\t\tif (!s.repo && s.repos.length === 0 && skillNames.length === 0) return [];\n\t\tif (s.repo?.name && s.currentIndexed) tryLoadObservatoryCache(s.repo.name);\n\n\t\tconst lines: string[] = [\"\", ...this.buildColumns(s, width, skillNames)];\n\t\treturn lines.map((line) => clipTo(line, width));\n\t}\n\n\tprivate buildColumns(s: Readonly<GraphRailState>, width: number, skillNames: string[]): string[] {\n\t\tconst columnWidth = Math.min(\n\t\t\tMAX_COLUMN_WIDTH,\n\t\t\tMath.max(MIN_COLUMN_WIDTH, Math.floor((width - 2 * COLUMN_GAP) / 3)),\n\t\t);\n\t\tconst graph: string[] = [theme.fg(\"muted\", \"Graph\")];\n\t\tif (s.indexProgress) {\n\t\t\tconst progress = s.indexProgress;\n\t\t\tconst phase = formatCompactIndexPhase(progress.phase);\n\t\t\tgraph.push(\n\t\t\t\t`${theme.fg(\"accent\", \"●\")} ${theme.bold(progress.fullName.split(\"/\").pop() ?? progress.fullName)}`,\n\t\t\t);\n\t\t\tconst percent =\n\t\t\t\tprogress.percent === undefined ? undefined : Math.max(0, Math.min(100, Math.round(progress.percent)));\n\t\t\tgraph.push(\n\t\t\t\tpercent === undefined\n\t\t\t\t\t? theme.fg(\"muted\", phase)\n\t\t\t\t\t: `${theme.fg(\"muted\", phase)} ${theme.fg(\"accent\", `${percent}%`)}`,\n\t\t\t);\n\t\t\tif (percent !== undefined) {\n\t\t\t\tconst filled = Math.round((percent / 100) * columnWidth);\n\t\t\t\tgraph.push(theme.fg(\"accent\", \"━\".repeat(filled)) + theme.fg(\"dim\", \"─\".repeat(columnWidth - filled)));\n\t\t\t}\n\t\t} else if (s.repo && s.currentIndexed) {\n\t\t\tgraph.push(`${theme.fg(\"success\", \"●\")} ${theme.bold(s.repo.name.split(\"/\").pop() ?? s.repo.name)}`);\n\t\t\tgraph.push(theme.fg(\"muted\", `${s.repo.symbols} symbols`));\n\t\t\tgraph.push(theme.fg(\"muted\", `${s.repo.relationships} relationships`));\n\t\t\tif (s.observatory) {\n\t\t\t\tconst flows = s.observatory.flowCount !== undefined ? ` · ${s.observatory.flowCount} flows` : \"\";\n\t\t\t\tgraph.push(theme.fg(\"muted\", `${s.observatory.communities.length} communities${flows}`));\n\t\t\t}\n\t\t} else if (s.repo) {\n\t\t\tgraph.push(`${theme.fg(\"warning\", \"○\")} ${theme.fg(\"warning\", \"repo not indexed\")}`);\n\t\t\tgraph.push(theme.fg(\"muted\", `${s.repo.repoCount} repos queryable`));\n\t\t} else {\n\t\t\tgraph.push(theme.fg(\"muted\", \"not connected\"));\n\t\t}\n\n\t\tconst skills: string[] = [theme.fg(\"muted\", \"Skills\")];\n\t\tfor (const name of skillNames.slice(0, 6)) {\n\t\t\tskills.push(`${theme.fg(\"success\", \"●\")} ${name}`);\n\t\t}\n\t\tif (skillNames.length > 6) skills.push(theme.fg(\"muted\", ` +${skillNames.length - 6} more`));\n\t\tif (skillNames.length === 0) skills.push(theme.fg(\"muted\", \"none\"));\n\n\t\tconst repos: string[] = [theme.fg(\"muted\", \"Indexed repos\")];\n\t\tconst activeName = s.repo?.name;\n\t\tconst ordered = activeName\n\t\t\t? [\n\t\t\t\t\t...s.repos.filter((repo) => repo.name === activeName),\n\t\t\t\t\t...s.repos.filter((repo) => repo.name !== activeName),\n\t\t\t\t]\n\t\t\t: s.repos;\n\t\tfor (const repo of ordered.slice(0, 6)) {\n\t\t\tconst short = repo.name.split(\"/\").pop() ?? repo.name;\n\t\t\tconst active = repo.name === s.repo?.name;\n\t\t\tconst marker = active ? theme.fg(\"accent\", \"●\") : theme.fg(\"muted\", \"○\");\n\t\t\tconst label = active ? theme.fg(\"accent\", short) : short;\n\t\t\trepos.push(`${marker} ${label} ${theme.fg(\"dim\", formatCount(repo.symbols))}`);\n\t\t}\n\t\tif (s.repos.length > 6) repos.push(theme.fg(\"muted\", ` +${s.repos.length - 6} more`));\n\t\tif (s.repos.length === 0) repos.push(theme.fg(\"muted\", \"none\"));\n\n\t\tconst rows = Math.max(graph.length, skills.length, repos.length);\n\t\tconst lines: string[] = [];\n\t\tfor (let i = 0; i < rows; i++) {\n\t\t\tconst graphCell = padTo(clipTo(graph[i] ?? \"\", columnWidth), columnWidth);\n\t\t\tconst skillCell = padTo(clipTo(skills[i] ?? \"\", columnWidth), columnWidth);\n\t\t\tconst repoCell = clipTo(repos[i] ?? \"\", columnWidth);\n\t\t\tlines.push(` ${graphCell}${\" \".repeat(COLUMN_GAP)}${skillCell}${\" \".repeat(COLUMN_GAP)}${repoCell}`);\n\t\t}\n\t\treturn lines;\n\t}\n}\n\nfunction padTo(text: string, width: number): string {\n\treturn text + \" \".repeat(Math.max(0, width - visibleWidth(text)));\n}\n\nfunction formatCount(symbols: string): string {\n\tconst count = Number(symbols.replace(/,/g, \"\"));\n\tif (Number.isNaN(count)) return symbols;\n\tif (count >= 1_000_000) return `${(count / 1_000_000).toFixed(1)}M`;\n\tif (count >= 1_000) return `${Math.round(count / 1_000)}k`;\n\treturn String(count);\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { visibleWidth } from "@earendil-works/pi-tui";
2
- import { graphRailStore } from "../../../core/graph-rail-store.js";
2
+ import { formatCompactIndexPhase, graphRailStore } from "../../../core/graph-rail-store.js";
3
3
  import { tryLoadObservatoryCache } from "../../../core/observatory-cache.js";
4
4
  import { theme } from "../theme/theme.js";
5
5
  /** Startup resource summary: GitNexus graph, skills, and indexed repositories. */
@@ -71,7 +71,20 @@ export class LandingPanelComponent {
71
71
  buildColumns(s, width, skillNames) {
72
72
  const columnWidth = Math.min(MAX_COLUMN_WIDTH, Math.max(MIN_COLUMN_WIDTH, Math.floor((width - 2 * COLUMN_GAP) / 3)));
73
73
  const graph = [theme.fg("muted", "Graph")];
74
- if (s.repo && s.currentIndexed) {
74
+ if (s.indexProgress) {
75
+ const progress = s.indexProgress;
76
+ const phase = formatCompactIndexPhase(progress.phase);
77
+ graph.push(`${theme.fg("accent", "●")} ${theme.bold(progress.fullName.split("/").pop() ?? progress.fullName)}`);
78
+ const percent = progress.percent === undefined ? undefined : Math.max(0, Math.min(100, Math.round(progress.percent)));
79
+ graph.push(percent === undefined
80
+ ? theme.fg("muted", phase)
81
+ : `${theme.fg("muted", phase)} ${theme.fg("accent", `${percent}%`)}`);
82
+ if (percent !== undefined) {
83
+ const filled = Math.round((percent / 100) * columnWidth);
84
+ graph.push(theme.fg("accent", "━".repeat(filled)) + theme.fg("dim", "─".repeat(columnWidth - filled)));
85
+ }
86
+ }
87
+ else if (s.repo && s.currentIndexed) {
75
88
  graph.push(`${theme.fg("success", "●")} ${theme.bold(s.repo.name.split("/").pop() ?? s.repo.name)}`);
76
89
  graph.push(theme.fg("muted", `${s.repo.symbols} symbols`));
77
90
  graph.push(theme.fg("muted", `${s.repo.relationships} relationships`));
@@ -1 +1 @@
1
- {"version":3,"file":"landing-panel.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/landing-panel.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Component } from \"@earendil-works/pi-tui\";\nimport { visibleWidth } from \"@earendil-works/pi-tui\";\nimport { type GraphRailState, graphRailStore } from \"../../../core/graph-rail-store.ts\";\nimport { tryLoadObservatoryCache } from \"../../../core/observatory-cache.ts\";\nimport { theme } from \"../theme/theme.ts\";\n\n/** Startup resource summary: GitNexus graph, skills, and indexed repositories. */\n\nconst COLUMN_GAP = 3;\nconst MIN_COLUMN_WIDTH = 22;\nconst MAX_COLUMN_WIDTH = 32;\n\nfunction clipTo(text: string, width: number): string {\n\tif (visibleWidth(text) <= width) return text;\n\tlet out = \"\";\n\tlet visible = 0;\n\tfor (let i = 0; i < text.length; i++) {\n\t\tif (text[i] === \"\\x1b\") {\n\t\t\tconst match = text.slice(i).match(/^\\x1b\\[[0-9;]*m/);\n\t\t\tif (match) {\n\t\t\t\tout += match[0];\n\t\t\t\ti += match[0].length - 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tif (visible >= width - 1) break;\n\t\tout += text[i];\n\t\tvisible++;\n\t}\n\treturn `${out}…\\x1b[0m`;\n}\n\nexport class LandingPanelComponent implements Component {\n\tprivate readonly getSkills: () => string[];\n\tprivate unsubscribe: (() => void) | undefined;\n\tprivate cachePoll: ReturnType<typeof setInterval> | undefined;\n\tprivate cachePollStarted = Date.now();\n\n\tconstructor(getSkills: () => string[], onDataChanged: () => void) {\n\t\tthis.getSkills = getSkills;\n\t\tthis.unsubscribe = graphRailStore.subscribe(onDataChanged);\n\t\tthis.cachePoll = setInterval(() => {\n\t\t\tconst s = graphRailStore.getState();\n\t\t\tif (Date.now() - this.cachePollStarted > 60_000) {\n\t\t\t\tthis.stopCachePoll();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (s.repo?.name && s.currentIndexed) tryLoadObservatoryCache(s.repo.name);\n\t\t}, 1500);\n\t}\n\n\tprivate stopCachePoll(): void {\n\t\tif (this.cachePoll) clearInterval(this.cachePoll);\n\t\tthis.cachePoll = undefined;\n\t}\n\n\tdispose(): void {\n\t\tthis.unsubscribe?.();\n\t\tthis.unsubscribe = undefined;\n\t\tthis.stopCachePoll();\n\t}\n\n\tinvalidate(): void {\n\t\t// Pure view over graphRailStore and loaded skills.\n\t}\n\n\trender(width: number): string[] {\n\t\tconst s = graphRailStore.getState();\n\t\tconst skillNames = this.getSkills();\n\t\tif (!s.repo && s.repos.length === 0 && skillNames.length === 0) return [];\n\t\tif (s.repo?.name && s.currentIndexed) tryLoadObservatoryCache(s.repo.name);\n\n\t\tconst lines: string[] = [\"\", ...this.buildColumns(s, width, skillNames)];\n\t\treturn lines.map((line) => clipTo(line, width));\n\t}\n\n\tprivate buildColumns(s: Readonly<GraphRailState>, width: number, skillNames: string[]): string[] {\n\t\tconst columnWidth = Math.min(\n\t\t\tMAX_COLUMN_WIDTH,\n\t\t\tMath.max(MIN_COLUMN_WIDTH, Math.floor((width - 2 * COLUMN_GAP) / 3)),\n\t\t);\n\t\tconst graph: string[] = [theme.fg(\"muted\", \"Graph\")];\n\t\tif (s.repo && s.currentIndexed) {\n\t\t\tgraph.push(`${theme.fg(\"success\", \"●\")} ${theme.bold(s.repo.name.split(\"/\").pop() ?? s.repo.name)}`);\n\t\t\tgraph.push(theme.fg(\"muted\", `${s.repo.symbols} symbols`));\n\t\t\tgraph.push(theme.fg(\"muted\", `${s.repo.relationships} relationships`));\n\t\t\tif (s.observatory) {\n\t\t\t\tconst flows = s.observatory.flowCount !== undefined ? ` · ${s.observatory.flowCount} flows` : \"\";\n\t\t\t\tgraph.push(theme.fg(\"muted\", `${s.observatory.communities.length} communities${flows}`));\n\t\t\t}\n\t\t} else if (s.repo) {\n\t\t\tgraph.push(`${theme.fg(\"warning\", \"○\")} ${theme.fg(\"warning\", \"repo not indexed\")}`);\n\t\t\tgraph.push(theme.fg(\"muted\", `${s.repo.repoCount} repos queryable`));\n\t\t} else {\n\t\t\tgraph.push(theme.fg(\"muted\", \"not connected\"));\n\t\t}\n\n\t\tconst skills: string[] = [theme.fg(\"muted\", \"Skills\")];\n\t\tfor (const name of skillNames.slice(0, 6)) {\n\t\t\tskills.push(`${theme.fg(\"success\", \"●\")} ${name}`);\n\t\t}\n\t\tif (skillNames.length > 6) skills.push(theme.fg(\"muted\", ` +${skillNames.length - 6} more`));\n\t\tif (skillNames.length === 0) skills.push(theme.fg(\"muted\", \"none\"));\n\n\t\tconst repos: string[] = [theme.fg(\"muted\", \"Indexed repos\")];\n\t\tconst activeName = s.repo?.name;\n\t\tconst ordered = activeName\n\t\t\t? [\n\t\t\t\t\t...s.repos.filter((repo) => repo.name === activeName),\n\t\t\t\t\t...s.repos.filter((repo) => repo.name !== activeName),\n\t\t\t\t]\n\t\t\t: s.repos;\n\t\tfor (const repo of ordered.slice(0, 6)) {\n\t\t\tconst short = repo.name.split(\"/\").pop() ?? repo.name;\n\t\t\tconst active = repo.name === s.repo?.name;\n\t\t\tconst marker = active ? theme.fg(\"accent\", \"●\") : theme.fg(\"muted\", \"○\");\n\t\t\tconst label = active ? theme.fg(\"accent\", short) : short;\n\t\t\trepos.push(`${marker} ${label} ${theme.fg(\"dim\", formatCount(repo.symbols))}`);\n\t\t}\n\t\tif (s.repos.length > 6) repos.push(theme.fg(\"muted\", ` +${s.repos.length - 6} more`));\n\t\tif (s.repos.length === 0) repos.push(theme.fg(\"muted\", \"none\"));\n\n\t\tconst rows = Math.max(graph.length, skills.length, repos.length);\n\t\tconst lines: string[] = [];\n\t\tfor (let i = 0; i < rows; i++) {\n\t\t\tconst graphCell = padTo(clipTo(graph[i] ?? \"\", columnWidth), columnWidth);\n\t\t\tconst skillCell = padTo(clipTo(skills[i] ?? \"\", columnWidth), columnWidth);\n\t\t\tconst repoCell = clipTo(repos[i] ?? \"\", columnWidth);\n\t\t\tlines.push(` ${graphCell}${\" \".repeat(COLUMN_GAP)}${skillCell}${\" \".repeat(COLUMN_GAP)}${repoCell}`);\n\t\t}\n\t\treturn lines;\n\t}\n}\n\nfunction padTo(text: string, width: number): string {\n\treturn text + \" \".repeat(Math.max(0, width - visibleWidth(text)));\n}\n\nfunction formatCount(symbols: string): string {\n\tconst count = Number(symbols.replace(/,/g, \"\"));\n\tif (Number.isNaN(count)) return symbols;\n\tif (count >= 1_000_000) return `${(count / 1_000_000).toFixed(1)}M`;\n\tif (count >= 1_000) return `${Math.round(count / 1_000)}k`;\n\treturn String(count);\n}\n"]}
1
+ {"version":3,"file":"landing-panel.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/landing-panel.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Component } from \"@earendil-works/pi-tui\";\nimport { visibleWidth } from \"@earendil-works/pi-tui\";\nimport { formatCompactIndexPhase, type GraphRailState, graphRailStore } from \"../../../core/graph-rail-store.ts\";\nimport { tryLoadObservatoryCache } from \"../../../core/observatory-cache.ts\";\nimport { theme } from \"../theme/theme.ts\";\n\n/** Startup resource summary: GitNexus graph, skills, and indexed repositories. */\n\nconst COLUMN_GAP = 3;\nconst MIN_COLUMN_WIDTH = 22;\nconst MAX_COLUMN_WIDTH = 32;\n\nfunction clipTo(text: string, width: number): string {\n\tif (visibleWidth(text) <= width) return text;\n\tlet out = \"\";\n\tlet visible = 0;\n\tfor (let i = 0; i < text.length; i++) {\n\t\tif (text[i] === \"\\x1b\") {\n\t\t\tconst match = text.slice(i).match(/^\\x1b\\[[0-9;]*m/);\n\t\t\tif (match) {\n\t\t\t\tout += match[0];\n\t\t\t\ti += match[0].length - 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tif (visible >= width - 1) break;\n\t\tout += text[i];\n\t\tvisible++;\n\t}\n\treturn `${out}…\\x1b[0m`;\n}\n\nexport class LandingPanelComponent implements Component {\n\tprivate readonly getSkills: () => string[];\n\tprivate unsubscribe: (() => void) | undefined;\n\tprivate cachePoll: ReturnType<typeof setInterval> | undefined;\n\tprivate cachePollStarted = Date.now();\n\n\tconstructor(getSkills: () => string[], onDataChanged: () => void) {\n\t\tthis.getSkills = getSkills;\n\t\tthis.unsubscribe = graphRailStore.subscribe(onDataChanged);\n\t\tthis.cachePoll = setInterval(() => {\n\t\t\tconst s = graphRailStore.getState();\n\t\t\tif (Date.now() - this.cachePollStarted > 60_000) {\n\t\t\t\tthis.stopCachePoll();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (s.repo?.name && s.currentIndexed) tryLoadObservatoryCache(s.repo.name);\n\t\t}, 1500);\n\t}\n\n\tprivate stopCachePoll(): void {\n\t\tif (this.cachePoll) clearInterval(this.cachePoll);\n\t\tthis.cachePoll = undefined;\n\t}\n\n\tdispose(): void {\n\t\tthis.unsubscribe?.();\n\t\tthis.unsubscribe = undefined;\n\t\tthis.stopCachePoll();\n\t}\n\n\tinvalidate(): void {\n\t\t// Pure view over graphRailStore and loaded skills.\n\t}\n\n\trender(width: number): string[] {\n\t\tconst s = graphRailStore.getState();\n\t\tconst skillNames = this.getSkills();\n\t\tif (!s.repo && s.repos.length === 0 && skillNames.length === 0) return [];\n\t\tif (s.repo?.name && s.currentIndexed) tryLoadObservatoryCache(s.repo.name);\n\n\t\tconst lines: string[] = [\"\", ...this.buildColumns(s, width, skillNames)];\n\t\treturn lines.map((line) => clipTo(line, width));\n\t}\n\n\tprivate buildColumns(s: Readonly<GraphRailState>, width: number, skillNames: string[]): string[] {\n\t\tconst columnWidth = Math.min(\n\t\t\tMAX_COLUMN_WIDTH,\n\t\t\tMath.max(MIN_COLUMN_WIDTH, Math.floor((width - 2 * COLUMN_GAP) / 3)),\n\t\t);\n\t\tconst graph: string[] = [theme.fg(\"muted\", \"Graph\")];\n\t\tif (s.indexProgress) {\n\t\t\tconst progress = s.indexProgress;\n\t\t\tconst phase = formatCompactIndexPhase(progress.phase);\n\t\t\tgraph.push(\n\t\t\t\t`${theme.fg(\"accent\", \"●\")} ${theme.bold(progress.fullName.split(\"/\").pop() ?? progress.fullName)}`,\n\t\t\t);\n\t\t\tconst percent =\n\t\t\t\tprogress.percent === undefined ? undefined : Math.max(0, Math.min(100, Math.round(progress.percent)));\n\t\t\tgraph.push(\n\t\t\t\tpercent === undefined\n\t\t\t\t\t? theme.fg(\"muted\", phase)\n\t\t\t\t\t: `${theme.fg(\"muted\", phase)} ${theme.fg(\"accent\", `${percent}%`)}`,\n\t\t\t);\n\t\t\tif (percent !== undefined) {\n\t\t\t\tconst filled = Math.round((percent / 100) * columnWidth);\n\t\t\t\tgraph.push(theme.fg(\"accent\", \"━\".repeat(filled)) + theme.fg(\"dim\", \"─\".repeat(columnWidth - filled)));\n\t\t\t}\n\t\t} else if (s.repo && s.currentIndexed) {\n\t\t\tgraph.push(`${theme.fg(\"success\", \"●\")} ${theme.bold(s.repo.name.split(\"/\").pop() ?? s.repo.name)}`);\n\t\t\tgraph.push(theme.fg(\"muted\", `${s.repo.symbols} symbols`));\n\t\t\tgraph.push(theme.fg(\"muted\", `${s.repo.relationships} relationships`));\n\t\t\tif (s.observatory) {\n\t\t\t\tconst flows = s.observatory.flowCount !== undefined ? ` · ${s.observatory.flowCount} flows` : \"\";\n\t\t\t\tgraph.push(theme.fg(\"muted\", `${s.observatory.communities.length} communities${flows}`));\n\t\t\t}\n\t\t} else if (s.repo) {\n\t\t\tgraph.push(`${theme.fg(\"warning\", \"○\")} ${theme.fg(\"warning\", \"repo not indexed\")}`);\n\t\t\tgraph.push(theme.fg(\"muted\", `${s.repo.repoCount} repos queryable`));\n\t\t} else {\n\t\t\tgraph.push(theme.fg(\"muted\", \"not connected\"));\n\t\t}\n\n\t\tconst skills: string[] = [theme.fg(\"muted\", \"Skills\")];\n\t\tfor (const name of skillNames.slice(0, 6)) {\n\t\t\tskills.push(`${theme.fg(\"success\", \"●\")} ${name}`);\n\t\t}\n\t\tif (skillNames.length > 6) skills.push(theme.fg(\"muted\", ` +${skillNames.length - 6} more`));\n\t\tif (skillNames.length === 0) skills.push(theme.fg(\"muted\", \"none\"));\n\n\t\tconst repos: string[] = [theme.fg(\"muted\", \"Indexed repos\")];\n\t\tconst activeName = s.repo?.name;\n\t\tconst ordered = activeName\n\t\t\t? [\n\t\t\t\t\t...s.repos.filter((repo) => repo.name === activeName),\n\t\t\t\t\t...s.repos.filter((repo) => repo.name !== activeName),\n\t\t\t\t]\n\t\t\t: s.repos;\n\t\tfor (const repo of ordered.slice(0, 6)) {\n\t\t\tconst short = repo.name.split(\"/\").pop() ?? repo.name;\n\t\t\tconst active = repo.name === s.repo?.name;\n\t\t\tconst marker = active ? theme.fg(\"accent\", \"●\") : theme.fg(\"muted\", \"○\");\n\t\t\tconst label = active ? theme.fg(\"accent\", short) : short;\n\t\t\trepos.push(`${marker} ${label} ${theme.fg(\"dim\", formatCount(repo.symbols))}`);\n\t\t}\n\t\tif (s.repos.length > 6) repos.push(theme.fg(\"muted\", ` +${s.repos.length - 6} more`));\n\t\tif (s.repos.length === 0) repos.push(theme.fg(\"muted\", \"none\"));\n\n\t\tconst rows = Math.max(graph.length, skills.length, repos.length);\n\t\tconst lines: string[] = [];\n\t\tfor (let i = 0; i < rows; i++) {\n\t\t\tconst graphCell = padTo(clipTo(graph[i] ?? \"\", columnWidth), columnWidth);\n\t\t\tconst skillCell = padTo(clipTo(skills[i] ?? \"\", columnWidth), columnWidth);\n\t\t\tconst repoCell = clipTo(repos[i] ?? \"\", columnWidth);\n\t\t\tlines.push(` ${graphCell}${\" \".repeat(COLUMN_GAP)}${skillCell}${\" \".repeat(COLUMN_GAP)}${repoCell}`);\n\t\t}\n\t\treturn lines;\n\t}\n}\n\nfunction padTo(text: string, width: number): string {\n\treturn text + \" \".repeat(Math.max(0, width - visibleWidth(text)));\n}\n\nfunction formatCount(symbols: string): string {\n\tconst count = Number(symbols.replace(/,/g, \"\"));\n\tif (Number.isNaN(count)) return symbols;\n\tif (count >= 1_000_000) return `${(count / 1_000_000).toFixed(1)}M`;\n\tif (count >= 1_000) return `${Math.round(count / 1_000)}k`;\n\treturn String(count);\n}\n"]}
@@ -84,6 +84,7 @@ export declare class InteractiveMode {
84
84
  private readonly defaultHiddenThinkingLabel;
85
85
  private hiddenThinkingLabel;
86
86
  private lastSigintTime;
87
+ private quitConfirmationTimer;
87
88
  private lastEscapeTime;
88
89
  private anthropicSubscriptionWarningShown;
89
90
  private lastStatusSpacer;