open-multi-agent-kit 0.92.0 → 0.93.0

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 (116) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +2 -2
  3. package/dist/core/agent-session.d.ts +29 -0
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +81 -14
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/compaction/branch-summarization.d.ts +5 -1
  8. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  9. package/dist/core/compaction/branch-summarization.js +5 -7
  10. package/dist/core/compaction/branch-summarization.js.map +1 -1
  11. package/dist/core/compaction/compaction.d.ts +12 -3
  12. package/dist/core/compaction/compaction.d.ts.map +1 -1
  13. package/dist/core/compaction/compaction.js +28 -15
  14. package/dist/core/compaction/compaction.js.map +1 -1
  15. package/dist/core/extensions/builtin/command-safety-gate.d.ts +8 -0
  16. package/dist/core/extensions/builtin/command-safety-gate.d.ts.map +1 -1
  17. package/dist/core/extensions/builtin/command-safety-gate.js +23 -0
  18. package/dist/core/extensions/builtin/command-safety-gate.js.map +1 -1
  19. package/dist/core/extensions/runner.d.ts.map +1 -1
  20. package/dist/core/extensions/runner.js +4 -0
  21. package/dist/core/extensions/runner.js.map +1 -1
  22. package/dist/core/extensions/types.d.ts +2 -0
  23. package/dist/core/extensions/types.d.ts.map +1 -1
  24. package/dist/core/extensions/types.js.map +1 -1
  25. package/dist/core/keybindings.d.ts +5 -0
  26. package/dist/core/keybindings.d.ts.map +1 -1
  27. package/dist/core/keybindings.js +5 -0
  28. package/dist/core/keybindings.js.map +1 -1
  29. package/dist/core/model-resolver.d.ts +41 -3
  30. package/dist/core/model-resolver.d.ts.map +1 -1
  31. package/dist/core/model-resolver.js +17 -9
  32. package/dist/core/model-resolver.js.map +1 -1
  33. package/dist/core/provider-resilience.d.ts.map +1 -1
  34. package/dist/core/provider-resilience.js +3 -1
  35. package/dist/core/provider-resilience.js.map +1 -1
  36. package/dist/core/reasoning-router-v4-weights.d.ts.map +1 -1
  37. package/dist/core/reasoning-router-v4-weights.js +9 -3
  38. package/dist/core/reasoning-router-v4-weights.js.map +1 -1
  39. package/dist/core/reasoning-router-v4.d.ts.map +1 -1
  40. package/dist/core/reasoning-router-v4.js +94 -24
  41. package/dist/core/reasoning-router-v4.js.map +1 -1
  42. package/dist/core/resource-loader.d.ts.map +1 -1
  43. package/dist/core/resource-loader.js +11 -5
  44. package/dist/core/resource-loader.js.map +1 -1
  45. package/dist/core/session-file-compaction.d.ts.map +1 -1
  46. package/dist/core/session-file-compaction.js +39 -5
  47. package/dist/core/session-file-compaction.js.map +1 -1
  48. package/dist/core/session-termination.d.ts.map +1 -1
  49. package/dist/core/session-termination.js +1 -1
  50. package/dist/core/session-termination.js.map +1 -1
  51. package/dist/core/settings-manager.d.ts +3 -0
  52. package/dist/core/settings-manager.d.ts.map +1 -1
  53. package/dist/core/settings-manager.js +8 -0
  54. package/dist/core/settings-manager.js.map +1 -1
  55. package/dist/core/system-prompt.d.ts.map +1 -1
  56. package/dist/core/system-prompt.js +1 -1
  57. package/dist/core/system-prompt.js.map +1 -1
  58. package/dist/core/tools/bash.d.ts +2 -0
  59. package/dist/core/tools/bash.d.ts.map +1 -1
  60. package/dist/core/tools/bash.js +38 -11
  61. package/dist/core/tools/bash.js.map +1 -1
  62. package/dist/modes/interactive/components/control-panel-box.d.ts +27 -0
  63. package/dist/modes/interactive/components/control-panel-box.d.ts.map +1 -1
  64. package/dist/modes/interactive/components/control-panel-box.js +60 -8
  65. package/dist/modes/interactive/components/control-panel-box.js.map +1 -1
  66. package/dist/modes/interactive/components/control-panel-layout.d.ts.map +1 -1
  67. package/dist/modes/interactive/components/control-panel-layout.js +100 -45
  68. package/dist/modes/interactive/components/control-panel-layout.js.map +1 -1
  69. package/dist/modes/interactive/components/control-panel-runtime-status.d.ts +9 -0
  70. package/dist/modes/interactive/components/control-panel-runtime-status.d.ts.map +1 -1
  71. package/dist/modes/interactive/components/control-panel-runtime-status.js +10 -8
  72. package/dist/modes/interactive/components/control-panel-runtime-status.js.map +1 -1
  73. package/dist/modes/interactive/components/control-panel-sparkles.d.ts +5 -0
  74. package/dist/modes/interactive/components/control-panel-sparkles.d.ts.map +1 -1
  75. package/dist/modes/interactive/components/control-panel-sparkles.js +14 -9
  76. package/dist/modes/interactive/components/control-panel-sparkles.js.map +1 -1
  77. package/dist/modes/interactive/components/footer.d.ts +10 -0
  78. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  79. package/dist/modes/interactive/components/footer.js +3 -3
  80. package/dist/modes/interactive/components/footer.js.map +1 -1
  81. package/dist/modes/interactive/components/status-sidebar.d.ts +49 -0
  82. package/dist/modes/interactive/components/status-sidebar.d.ts.map +1 -0
  83. package/dist/modes/interactive/components/status-sidebar.js +253 -0
  84. package/dist/modes/interactive/components/status-sidebar.js.map +1 -0
  85. package/dist/modes/interactive/interactive-mode.d.ts +9 -0
  86. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  87. package/dist/modes/interactive/interactive-mode.js +94 -20
  88. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  89. package/dist/modes/interactive/theme/omk-neon-control.json +13 -13
  90. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  91. package/dist/modes/rpc/rpc-mode.js +1 -0
  92. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  93. package/dist/utils/clipboard.d.ts.map +1 -1
  94. package/dist/utils/clipboard.js +19 -8
  95. package/dist/utils/clipboard.js.map +1 -1
  96. package/docs/compaction.md +7 -0
  97. package/docs/docs.json +4 -0
  98. package/docs/environment-variables.md +90 -0
  99. package/docs/index.md +1 -0
  100. package/docs/rpc.md +5 -2
  101. package/docs/settings.md +1 -0
  102. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  103. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  104. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  105. package/examples/extensions/gondolin/package-lock.json +2 -2
  106. package/examples/extensions/gondolin/package.json +1 -1
  107. package/examples/extensions/sandbox/package-lock.json +2 -2
  108. package/examples/extensions/sandbox/package.json +1 -1
  109. package/examples/extensions/subagent/agents.test.ts +86 -0
  110. package/examples/extensions/subagent/agents.ts +18 -4
  111. package/examples/extensions/subagent/capabilities.ts +15 -1
  112. package/examples/extensions/subagent/domain-profiles.ts +272 -0
  113. package/examples/extensions/with-deps/package-lock.json +2 -2
  114. package/examples/extensions/with-deps/package.json +1 -1
  115. package/npm-shrinkwrap.json +15 -15
  116. package/package.json +10 -7
@@ -1 +1 @@
1
- {"version":3,"file":"control-panel-layout.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/control-panel-layout.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,EAAkB,KAAK,SAAS,EAA0B,MAAM,6BAA6B,CAAC;AAgBrG,eAAO,MAAM,uBAAuB,UAQnC,CAAC;AAEF,eAAO,MAAM,+BAA+B,MAAM,CAAC;AACnD,eAAO,MAAM,4BAA4B,QAAsC,CAAC;AAChF,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAC9C,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAKzC,MAAM,WAAW,mBAAmB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,EAAE,MAAM,MAAM,CAAC;IAClC,oBAAoB,EAAE,MAAM,MAAM,CAAC;IACnC,iBAAiB,EAAE,MAAM,MAAM,CAAC;IAChC,UAAU,EAAE,MAAM,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,0BAA0B,CAAC;CAClD;AAED,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,CAAC,EAAE,sBAAsB,CAAC;IAChD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IAC/B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,wBAAgB,wBAAwB,CACvC,OAAO,EAAE,mBAAmB,EAC5B,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,EAAE,EACtB,SAAS,SAAI,GACX,MAAM,EAAE,CAKV;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAGjG","sourcesContent":["import { truncateToWidth, visibleWidth } from \"omk-tui\";\nimport type { PiPackageIntakeSummary } from \"../../../core/pi-package-intake.ts\";\nimport { nextActiveTodo, type TodoState, summary as todoSummary } from \"../../../core/todo-state.ts\";\nimport { type ThemeColor, theme } from \"../theme/theme.ts\";\nimport {\n\tboxBottom,\n\tboxCenteredLine,\n\tboxTextLine,\n\tboxTop,\n\tcenterLine,\n\tcomposeColumns,\n\tdivider,\n\tfitLine,\n\tsidebarRule,\n\ttextLine,\n} from \"./control-panel-box.ts\";\nimport { SPARKLE_ROW_BOTTOM, SPARKLE_ROW_TOP, sparkleRow } from \"./control-panel-sparkles.ts\";\n\nexport const CONTROL_PANEL_ASCII_ART = [\n\t\" ███████ ██ ██ ██ ██\",\n\t\"██ ██ ███ ███ ██ ██ \",\n\t\"██ ██ ████ ████ ██ ██ \",\n\t\"██ ██ ██ ██ ██ ██ █████ \",\n\t\"██ ██ ██ ███ ██ ██ ██ \",\n\t\"██ ██ ██ █ ██ ██ ██ \",\n\t\" ███████ ██ ██ ██ ██\",\n];\nconst META_WIDTH = 31;\nexport const CONTROL_PANEL_OVERLAY_MIN_WIDTH = 112;\nexport const CONTROL_PANEL_DECK_MIN_WIDTH = CONTROL_PANEL_OVERLAY_MIN_WIDTH + 1;\nexport const CONTROL_PANEL_SIDEBAR_WIDTH = 38;\nexport const CONTROL_PANEL_GAP_WIDTH = 2;\nconst CONTEXT_METER_CELLS = 12;\nconst SPARKLINE_WIDTH = 16;\nconst SPARKLINE_GLYPHS = \"▁▂▃▄▅▆▇█\";\n\nexport interface ControlPanelContent {\n\tappName: string;\n\tversion: string;\n\tcompactInstructions: () => string;\n\texpandedInstructions: () => string;\n\tcompactOnboarding: () => string;\n\tonboarding: () => string;\n\tstatusSnapshot?: () => ControlPanelStatusSnapshot;\n}\n\nexport interface ControlPanelStatusSnapshot {\n\treadonly modelId?: string;\n\treadonly modelProvider?: string;\n\treadonly thinkingLevel?: string;\n\treadonly contextPercent?: number | null;\n\treadonly contextWindowTokens?: number;\n\treadonly contextTokens?: number | null;\n\treadonly headroomStatus?: string;\n\treadonly optimizerPolicy?: string;\n\treadonly skillCount?: number;\n\treadonly mcpCount?: number;\n\treadonly packageIntake?: PiPackageIntakeSummary;\n\treadonly cwdLabel?: string;\n\treadonly gitBranch?: string | null;\n\treadonly todoState?: TodoState;\n\treadonly runtimeState?: string;\n\treadonly routeState?: string;\n\treadonly evidenceState?: string;\n\treadonly controlState?: string;\n\treadonly dagOrchestrationState?: string;\n\treadonly ansiColorState?: string;\n\treadonly startupState?: string;\n\treadonly linkState?: string;\n\treadonly sidebarState?: string;\n}\n\nexport function renderControlPanelLayout(\n\tcontent: ControlPanelContent,\n\texpanded: boolean,\n\twidth: number,\n\tbannerFrame?: string[],\n\tsparkleMs = 0,\n): string[] {\n\tif (width <= 0) return [];\n\treturn expanded\n\t\t? renderExpanded(content, width, bannerFrame, sparkleMs)\n\t\t: renderCompact(content, width, bannerFrame, sparkleMs);\n}\n\nexport function renderControlPanelRightPane(content: ControlPanelContent, width: number): string[] {\n\tif (width <= 0) return [];\n\treturn sidebarPanel(content, width);\n}\n\nfunction renderCompact(content: ControlPanelContent, width: number, bannerFrame?: string[], sparkleMs = 0): string[] {\n\tif (width >= CONTROL_PANEL_DECK_MIN_WIDTH) {\n\t\tconst deck = renderDeck(content, width, bannerFrame, sparkleMs);\n\t\tif (deck.length > 0) return deck;\n\t}\n\treturn [\n\t\tdivider(width, \"OMK//CONTROL PANEL\", \"accent\"),\n\t\tstatusLine(content, width),\n\t\ttextLine(width, content.compactInstructions()),\n\t\ttextLine(width, content.compactOnboarding(), \"dim\"),\n\t];\n}\n\nfunction renderDeck(content: ControlPanelContent, width: number, bannerFrame?: string[], sparkleMs = 0): string[] {\n\tconst { leftWidth, sidebarWidth } = deckWidths(width);\n\tif (leftWidth < 72) return [];\n\tconst lines = composeColumns(\n\t\theroPanel(content, leftWidth, bannerFrame, sparkleMs),\n\t\tleftWidth,\n\t\tsidebarPanel(content, sidebarWidth),\n\t\tsidebarWidth,\n\t\tCONTROL_PANEL_GAP_WIDTH,\n\t\twidth,\n\t);\n\tlines.push(controlStripLine(content, width));\n\tlines.push(centerLine(width, content.compactOnboarding(), \"dim\"));\n\treturn lines;\n}\n\nfunction deckWidths(width: number): { leftWidth: number; sidebarWidth: number } {\n\tconst sidebarWidth = Math.min(CONTROL_PANEL_SIDEBAR_WIDTH, Math.max(34, Math.floor(width * 0.28)));\n\treturn { leftWidth: width - CONTROL_PANEL_GAP_WIDTH - sidebarWidth, sidebarWidth };\n}\n\nfunction heroPanel(content: ControlPanelContent, width: number, bannerFrame?: string[], sparkleMs = 0): string[] {\n\tconst snapshot = statusSnapshot(content);\n\tconst innerWidth = Math.max(0, width - 4);\n\treturn [\n\t\tboxTop(width, `omk v${content.version} · OMK://CONTROL`),\n\t\tboxCenteredLine(width, theme.bold(theme.fg(\"accent\", \"OMK\"))),\n\t\tboxCenteredLine(width, theme.fg(\"muted\", \"route · verify · loop · control\")),\n\t\tboxTextLine(width, sparkleRow(innerWidth, SPARKLE_ROW_TOP, sparkleMs)),\n\t\t...(bannerFrame ?? CONTROL_PANEL_ASCII_ART).map((line, index) => {\n\t\t\tif (bannerFrame) return boxCenteredLine(width, line);\n\t\t\tconst color: ThemeColor = index < 2 ? \"mdCode\" : index < 4 ? \"accent\" : index < 6 ? \"success\" : \"warning\";\n\t\t\treturn boxCenteredLine(width, theme.fg(color, line));\n\t\t}),\n\t\tboxTextLine(width, sparkleRow(innerWidth, SPARKLE_ROW_BOTTOM, sparkleMs)),\n\t\tboxCenteredLine(\n\t\t\twidth,\n\t\t\t`${theme.fg(\"warning\", \"●\")} ${theme.bold(\"OMK\")} / ${theme.fg(\"success\", heroModelLabel(snapshot))}`,\n\t\t),\n\t\tboxCenteredLine(\n\t\t\twidth,\n\t\t\t`${theme.fg(\"mdCode\", \"◇\")} omk-control · ${theme.fg(\"accent\", \"route\")} · ${theme.fg(\"warning\", \"verify\")} · ${theme.fg(\"success\", \"loop\")} · ${theme.fg(\"mdCode\", \"control\")}`,\n\t\t),\n\t\tboxBottom(width),\n\t];\n}\n\nfunction heroModelLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tif (!snapshot.modelId) return \"no-model\";\n\tconst think = snapshot.thinkingLevel;\n\treturn think && think !== \"off\" ? `${snapshot.modelId}:${think}` : snapshot.modelId;\n}\n\nfunction sidebarPanel(content: ControlPanelContent, width: number): string[] {\n\tconst snapshot = statusSnapshot(content);\n\tconst headroomLabel = snapshot.headroomStatus ?? snapshot.optimizerPolicy ?? \"unknown\";\n\tconst mcpCount = snapshot.mcpCount;\n\tconst skillCount = snapshot.skillCount;\n\tconst packageIntakeLabel = packageIntakeStatusLabel(snapshot.packageIntake);\n\tconst contextMeter = contextMeterLabel(snapshot);\n\tconst activitySparkline = activitySparklineLabel(snapshot);\n\treturn [\n\t\tsidebarTabs(width),\n\t\tboxCenteredLine(width, theme.bold(theme.fg(\"accent\", \"OMK://CONTROL\"))),\n\t\tboxCenteredLine(width, theme.bold(theme.fg(\"warning\", \"CYBERPUNK OPS CORE\"))),\n\t\tboxCenteredLine(width, `${theme.fg(\"mdCode\", \"MATRIX RAIN\")} // ${theme.fg(\"success\", \"NEON GRID ONLINE\")}`),\n\t\tboxCenteredLine(width, theme.fg(\"text\", \"NIGHT-CITY-MATRIX-V3\")),\n\t\tsidebarRule(width, \"STATUS\", \"accent\"),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"state:\")} ${coloredStatus(snapshot.runtimeState ?? \"unknown\")}`),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"route:\")} ${coloredStatus(snapshot.routeState ?? \"unknown\")}`),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"evidence:\")} ${coloredStatus(snapshot.evidenceState ?? \"unknown\")}`),\n\t\tsidebarRule(width, \"TODO\", \"accent\"),\n\t\t...todoSidebarLines(snapshot.todoState, width),\n\t\tsidebarRule(width, \"SESSION\", \"accent\"),\n\t\tsemanticBoxTextLine(width, \"cwd\", snapshot.cwdLabel ?? \"?\", \"end\"),\n\t\tsemanticBoxTextLine(width, \"git\", snapshot.gitBranch ?? \"?\", \"start\"),\n\t\tsidebarRule(width, \"MODEL / CTX\", \"accent\"),\n\t\tsemanticBoxTextLine(width, \"model\", modelStatusLabel(snapshot), \"end\"),\n\t\tsemanticBoxTextLine(width, \"think\", snapshot.thinkingLevel ?? \"off\", \"start\"),\n\t\tboxTextLine(\n\t\t\twidth,\n\t\t\t`${theme.fg(\"muted\", \"ctx:\")} ${theme.fg(statusColor(snapshot.contextPercent === undefined || snapshot.contextPercent === null ? \"unknown\" : \"ready\"), contextStatusLabel(snapshot))}`,\n\t\t),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"meter:\")} ${contextMeter}`),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"pulse:\")} ${activitySparkline}`),\n\t\tsidebarRule(width, \"RUNTIME / MCP / SKILLS\", \"accent\"),\n\t\tsemanticBoxTextLine(width, \"headroom\", headroomLabel, \"end\"),\n\t\tsemanticBoxTextLine(width, \"omk\", snapshot.dagOrchestrationState ?? \"unknown\", \"end\"),\n\t\tsemanticBoxTextLine(width, \"sidebar\", snapshot.sidebarState ?? \"unknown\", \"start\"),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"res:\")} MCP:${mcpCount ?? \"?\"} skills:${skillCount ?? \"?\"}`),\n\t\tsemanticBoxTextLine(width, \"pkg\", packageIntakeLabel, \"end\"),\n\t\tsidebarRule(width, \"CONTROL\", \"accent\"),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"route:\")} ${coloredStatus(snapshot.routeState ?? \"unknown\")}`),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"verify:\")} ${coloredStatus(snapshot.evidenceState ?? \"unknown\")}`),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"control:\")} ${coloredStatus(snapshot.controlState ?? \"unknown\")}`),\n\t\tboxBottom(width, \"accent\"),\n\t];\n}\n\nfunction semanticBoxTextLine(\n\twidth: number,\n\tlabel: string,\n\tvalue: string,\n\tpreserve: \"start\" | \"middle\" | \"end\",\n): string {\n\tconst prefix = `${theme.fg(\"muted\", `${label}:`)} `;\n\tconst availableWidth = Math.max(0, width - 4 - visibleWidth(prefix));\n\treturn boxTextLine(width, `${prefix}${semanticTruncate(value, availableWidth, preserve)}`);\n}\n\nfunction semanticTruncate(value: string, maxWidth: number, preserve: \"start\" | \"middle\" | \"end\"): string {\n\tif (visibleWidth(value) <= maxWidth) return value;\n\tif (maxWidth <= 0) return \"\";\n\tif (preserve === \"start\") return truncateToWidth(value, maxWidth, \"…\");\n\tconst ellipsis = \"…\";\n\tconst targetWidth = maxWidth - visibleWidth(ellipsis);\n\tif (targetWidth <= 0) return truncateToWidth(ellipsis, maxWidth, \"\");\n\tif (preserve === \"middle\") {\n\t\tconst headWidth = Math.max(1, Math.floor(targetWidth / 2));\n\t\tconst tailWidth = Math.max(1, targetWidth - headWidth);\n\t\treturn `${takeStart(value, headWidth)}${ellipsis}${takeEnd(value, tailWidth)}`;\n\t}\n\treturn `${ellipsis}${takeEnd(value, targetWidth)}`;\n}\n\nfunction takeStart(value: string, maxWidth: number): string {\n\tlet prefix = \"\";\n\tfor (const char of Array.from(value)) {\n\t\tif (visibleWidth(prefix + char) > maxWidth) break;\n\t\tprefix += char;\n\t}\n\treturn prefix;\n}\n\nfunction takeEnd(value: string, maxWidth: number): string {\n\tlet suffix = \"\";\n\tfor (const char of Array.from(value).reverse()) {\n\t\tif (visibleWidth(char + suffix) > maxWidth) break;\n\t\tsuffix = char + suffix;\n\t}\n\treturn suffix;\n}\n\nfunction statusToken(label: string, value: string | undefined): string {\n\tconst state = value ?? \"unknown\";\n\treturn theme.fg(statusColor(state), `${label}:${state.toUpperCase()}`);\n}\n\nfunction coloredStatus(value: string): string {\n\treturn theme.fg(statusColor(value), value);\n}\n\nfunction statusColor(value: string): ThemeColor {\n\tconst normalized = value.toLowerCase();\n\tif ([\"ready\", \"on\", \"active\", \"available\", \"linked\", \"tracking\", \"pinned\"].includes(normalized)) return \"success\";\n\tif ([\"degraded\", \"limited\", \"blocked\", \"off\"].includes(normalized)) return \"warning\";\n\treturn \"muted\";\n}\n\nfunction todoSidebarLines(state: TodoState | undefined, width: number): string[] {\n\tif (!state || state.items.length === 0) {\n\t\treturn [\n\t\t\tboxTextLine(width, `${theme.fg(\"muted\", \"todo:\")} empty`),\n\t\t\tboxTextLine(width, `${theme.fg(\"muted\", \"next:\")} no active todos`),\n\t\t];\n\t}\n\tconst counts = todoSummary(state);\n\tconst next = nextActiveTodo(state);\n\treturn [\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"todo:\")} ${counts.done}/${counts.total} done`),\n\t\tsemanticBoxTextLine(width, \"next\", next?.label ?? \"complete\", \"middle\"),\n\t];\n}\n\nfunction packageIntakeStatusLabel(summary: PiPackageIntakeSummary | undefined): string {\n\tif (!summary) return \"ports:pending\";\n\tconst ready =\n\t\tsummary.acceptedNative + summary.acceptedReference + summary.acceptedMeasurement + summary.acceptedAdvisory;\n\tconst review = summary.deferred + summary.reject;\n\treturn `ports:${ready}/${summary.total} review:${review} block:${summary.hardForkBlocked}`;\n}\n\nfunction renderExpanded(content: ControlPanelContent, width: number, bannerFrame?: string[], sparkleMs = 0): string[] {\n\tif (width >= CONTROL_PANEL_DECK_MIN_WIDTH) {\n\t\tconst { leftWidth, sidebarWidth } = deckWidths(width);\n\t\tconst resourceLines = [\"\", ...content.onboarding().split(\"\\n\")];\n\t\tconst rightRail = blankSidebarRail(sidebarWidth, resourceLines.length);\n\t\tconst lines = [...renderDeck(content, width, bannerFrame, sparkleMs)];\n\t\tlines.push(...composeColumns(resourceLines, leftWidth, rightRail, sidebarWidth, CONTROL_PANEL_GAP_WIDTH, width));\n\t\treturn lines;\n\t}\n\n\tconst lines = [divider(width, \"OMK//CONTROL PANEL\", \"accent\"), statusLine(content, width)];\n\tif (width >= 32) lines.push(...brandLines(content, width, bannerFrame));\n\tlines.push(divider(width, \"SYSTEM MAP\", \"mdHeading\"));\n\tfor (const instruction of content.expandedInstructions().split(\"\\n\")) lines.push(textLine(width, instruction));\n\tlines.push(divider(width, \"STARTUP LINK\", \"success\"));\n\tfor (const onboardingLine of content.onboarding().split(\"\\n\")) lines.push(textLine(width, onboardingLine, \"dim\"));\n\tlines.push(divider(width, \"END\", \"borderMuted\"));\n\treturn lines;\n}\n\nfunction blankSidebarRail(width: number, lineCount: number): string[] {\n\treturn Array.from({ length: lineCount }, () => boxTextLine(width, \"\"));\n}\n\nfunction statusSnapshot(content: ControlPanelContent): ControlPanelStatusSnapshot {\n\treturn content.statusSnapshot?.() ?? {};\n}\n\nfunction modelStatusLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tif (!snapshot.modelId) return \"no-model\";\n\treturn snapshot.modelProvider ? `${snapshot.modelProvider}/${snapshot.modelId}` : snapshot.modelId;\n}\n\nfunction contextStatusLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tconst windowTokens = snapshot.contextWindowTokens ?? 0;\n\tconst windowLabel = windowTokens > 0 ? formatTokens(windowTokens) : \"?\";\n\treturn snapshot.contextPercent === null || snapshot.contextPercent === undefined\n\t\t? `?/${windowLabel}`\n\t\t: `${snapshot.contextPercent.toFixed(1)}%/${windowLabel}`;\n}\n\nfunction contextMeterLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tconst percent = normalizePercent(snapshot.contextPercent);\n\tif (percent === undefined) {\n\t\treturn `${theme.fg(\"borderMuted\", \"░\".repeat(CONTEXT_METER_CELLS))} ${theme.fg(\"muted\", \"??%\")}`;\n\t}\n\tconst filled = Math.max(0, Math.min(CONTEXT_METER_CELLS, Math.round((percent / 100) * CONTEXT_METER_CELLS)));\n\tconst color: ThemeColor = percent >= 85 ? \"warning\" : percent >= 65 ? \"mdCode\" : \"success\";\n\treturn `${theme.fg(color, \"█\".repeat(filled))}${theme.fg(\"borderMuted\", \"░\".repeat(CONTEXT_METER_CELLS - filled))} ${theme.fg(color, `${Math.round(percent)}%`)}`;\n}\n\nfunction activitySparklineLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tconst seed = hashSnapshot(snapshot);\n\tconst glyphs = Array.from(SPARKLINE_GLYPHS);\n\tconst parts: string[] = [];\n\tfor (let index = 0; index < SPARKLINE_WIDTH; index++) {\n\t\tconst glyph = glyphs[(seed + index * 5 + index * index) % glyphs.length] ?? \"▁\";\n\t\tconst color: ThemeColor = index % 5 === 0 ? \"accent\" : index % 3 === 0 ? \"warning\" : \"success\";\n\t\tparts.push(theme.fg(color, glyph));\n\t}\n\treturn parts.join(\"\");\n}\n\nfunction normalizePercent(value: number | null | undefined): number | undefined {\n\tif (value === null || value === undefined || !Number.isFinite(value)) return undefined;\n\tif (value < 0) return 0;\n\tif (value > 100) return 100;\n\treturn value;\n}\n\nfunction hashSnapshot(snapshot: ControlPanelStatusSnapshot): number {\n\tconst source = [\n\t\tsnapshot.modelProvider,\n\t\tsnapshot.modelId,\n\t\tsnapshot.contextPercent?.toFixed(1),\n\t\tsnapshot.contextTokens,\n\t\tsnapshot.contextWindowTokens,\n\t\tsnapshot.cwdLabel,\n\t\tsnapshot.gitBranch,\n\t].join(\"|\");\n\tlet hash = 2166136261;\n\tfor (let index = 0; index < source.length; index++) {\n\t\thash ^= source.charCodeAt(index);\n\t\thash = Math.imul(hash, 16777619);\n\t}\n\treturn hash >>> 0;\n}\n\nfunction formatTokens(count: number): string {\n\tif (count < 1000) return count.toString();\n\tif (count < 10000) return `${(count / 1000).toFixed(1)}k`;\n\tif (count < 1000000) return `${Math.round(count / 1000)}k`;\n\tif (count < 10000000) return `${(count / 1000000).toFixed(1)}M`;\n\treturn `${Math.round(count / 1000000)}M`;\n}\n\nfunction sidebarTabs(width: number): string {\n\treturn boxTextLine(\n\t\twidth,\n\t\tfitLine(\n\t\t\t`${theme.bold(theme.fg(\"accent\", \"1:CONTROL\"))} ${theme.fg(\"muted\", \"2:HISTORY\")}`,\n\t\t\tMath.max(0, width - 4),\n\t\t),\n\t);\n}\n\nfunction controlStripLine(content: ControlPanelContent, width: number): string {\n\treturn centerLine(\n\t\twidth,\n\t\t`${theme.bold(theme.fg(\"accent\", \"OMK://CONTROL READ\"))} ${theme.fg(\"accent\", \"route/verify/loop/control\")} · ${content.compactInstructions()}`,\n\t);\n}\n\nfunction brandLines(content: ControlPanelContent, width: number, bannerFrame?: string[]): string[] {\n\tconst art = bannerFrame ?? CONTROL_PANEL_ASCII_ART;\n\tif (bannerFrame) return art.map((line) => textLine(width, line));\n\tconst leftWidth = Math.max(...art.map((line) => visibleWidth(line)));\n\tconst minWideWidth = visibleWidth(\"| \") + leftWidth + visibleWidth(\" | \") + META_WIDTH;\n\tif (width < minWideWidth) return art.map((line) => textLine(width, theme.fg(\"accent\", line)));\n\tconst snapshot = statusSnapshot(content);\n\treturn art.map((line, index) =>\n\t\ttextLine(\n\t\t\twidth,\n\t\t\t`${fitLine(theme.fg(\"accent\", line), leftWidth)}${theme.fg(\"borderMuted\", \" | \")}${metadataLines(snapshot)[index] ?? \"\"}`,\n\t\t),\n\t);\n}\n\nfunction metadataLines(snapshot: ControlPanelStatusSnapshot): string[] {\n\tconst rawThemeName = theme.name ?? \"live\";\n\tconst themeName = (rawThemeName.startsWith(\"omk-\") ? rawThemeName.slice(4) : rawThemeName).toUpperCase();\n\treturn [\n\t\t`${theme.fg(\"mdCode\", \"PANEL\")} ${coloredStatus(snapshot.runtimeState ?? \"unknown\")}`,\n\t\t`${theme.fg(\"mdCode\", \"THEME\")} ${theme.fg(\"accent\", themeName)}`,\n\t\t`${theme.fg(\"mdCode\", \"STARTUP\")} ${coloredStatus(snapshot.startupState ?? \"unknown\")}`,\n\t\t`${theme.fg(\"mdCode\", \"LINK\")} ${coloredStatus(snapshot.linkState ?? \"unknown\")}`,\n\t];\n}\n\nfunction statusLine(content: ControlPanelContent, width: number): string {\n\tconst snapshot = statusSnapshot(content);\n\tconst segments = [\n\t\ttheme.bold(theme.fg(\"accent\", `${content.appName.toUpperCase()} v${content.version}`)),\n\t\tstatusToken(\"CORE\", snapshot.runtimeState),\n\t\tstatusToken(\"ANSI\", snapshot.ansiColorState),\n\t\tstatusToken(\"STARTUP\", snapshot.startupState),\n\t\tstatusToken(\"LINK\", snapshot.linkState),\n\t\ttheme.fg(\"muted\", \"THEME:LIVE\"),\n\t];\n\treturn textLine(width, segments.join(theme.fg(\"borderMuted\", \" | \")));\n}\n"]}
1
+ {"version":3,"file":"control-panel-layout.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/control-panel-layout.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,EAAkB,KAAK,SAAS,EAA0B,MAAM,6BAA6B,CAAC;AAmBrG,eAAO,MAAM,uBAAuB,UAQnC,CAAC;AAEF,eAAO,MAAM,+BAA+B,MAAM,CAAC;AACnD,eAAO,MAAM,4BAA4B,QAAsC,CAAC;AAChF,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAC9C,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAKzC,MAAM,WAAW,mBAAmB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,EAAE,MAAM,MAAM,CAAC;IAClC,oBAAoB,EAAE,MAAM,MAAM,CAAC;IACnC,iBAAiB,EAAE,MAAM,MAAM,CAAC;IAChC,UAAU,EAAE,MAAM,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,0BAA0B,CAAC;CAClD;AAED,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,CAAC,EAAE,sBAAsB,CAAC;IAChD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IAC/B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,wBAAgB,wBAAwB,CACvC,OAAO,EAAE,mBAAmB,EAC5B,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,EAAE,EACtB,SAAS,SAAI,GACX,MAAM,EAAE,CAKV;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAGjG","sourcesContent":["import { truncateToWidth, visibleWidth } from \"omk-tui\";\nimport type { PiPackageIntakeSummary } from \"../../../core/pi-package-intake.ts\";\nimport { nextActiveTodo, type TodoState, summary as todoSummary } from \"../../../core/todo-state.ts\";\nimport { type ThemeColor, theme } from \"../theme/theme.ts\";\nimport {\n\tboxBottom,\n\tboxCenteredLine,\n\tboxRuleLine,\n\tboxTextLine,\n\tboxTop,\n\tcenterLine,\n\tcomposeColumns,\n\tdivider,\n\tfitLine,\n\tlabelCell,\n\tpadBoxColumn,\n\tsidebarRule,\n\ttextLine,\n} from \"./control-panel-box.ts\";\nimport { SPARKLE_ROW_BOTTOM, SPARKLE_ROW_TOP, sparkleRow } from \"./control-panel-sparkles.ts\";\n\nexport const CONTROL_PANEL_ASCII_ART = [\n\t\" ███████ ██ ██ ██ ██\",\n\t\"██ ██ ███ ███ ██ ██ \",\n\t\"██ ██ ████ ████ ██ ██ \",\n\t\"██ ██ ██ ██ ██ ██ █████ \",\n\t\"██ ██ ██ ███ ██ ██ ██ \",\n\t\"██ ██ ██ █ ██ ██ ██ \",\n\t\" ███████ ██ ██ ██ ██\",\n];\nconst META_WIDTH = 31;\nexport const CONTROL_PANEL_OVERLAY_MIN_WIDTH = 112;\nexport const CONTROL_PANEL_DECK_MIN_WIDTH = CONTROL_PANEL_OVERLAY_MIN_WIDTH + 1;\nexport const CONTROL_PANEL_SIDEBAR_WIDTH = 38;\nexport const CONTROL_PANEL_GAP_WIDTH = 2;\nconst CONTEXT_METER_CELLS = 12;\nconst SPARKLINE_WIDTH = 16;\nconst SPARKLINE_GLYPHS = \"▁▂▃▄▅▆▇█\";\n\nexport interface ControlPanelContent {\n\tappName: string;\n\tversion: string;\n\tcompactInstructions: () => string;\n\texpandedInstructions: () => string;\n\tcompactOnboarding: () => string;\n\tonboarding: () => string;\n\tstatusSnapshot?: () => ControlPanelStatusSnapshot;\n}\n\nexport interface ControlPanelStatusSnapshot {\n\treadonly modelId?: string;\n\treadonly modelProvider?: string;\n\treadonly thinkingLevel?: string;\n\treadonly contextPercent?: number | null;\n\treadonly contextWindowTokens?: number;\n\treadonly contextTokens?: number | null;\n\treadonly headroomStatus?: string;\n\treadonly optimizerPolicy?: string;\n\treadonly skillCount?: number;\n\treadonly mcpCount?: number;\n\treadonly packageIntake?: PiPackageIntakeSummary;\n\treadonly cwdLabel?: string;\n\treadonly gitBranch?: string | null;\n\treadonly todoState?: TodoState;\n\treadonly runtimeState?: string;\n\treadonly routeState?: string;\n\treadonly evidenceState?: string;\n\treadonly controlState?: string;\n\treadonly dagOrchestrationState?: string;\n\treadonly ansiColorState?: string;\n\treadonly startupState?: string;\n\treadonly linkState?: string;\n\treadonly sidebarState?: string;\n}\n\nexport function renderControlPanelLayout(\n\tcontent: ControlPanelContent,\n\texpanded: boolean,\n\twidth: number,\n\tbannerFrame?: string[],\n\tsparkleMs = 0,\n): string[] {\n\tif (width <= 0) return [];\n\treturn expanded\n\t\t? renderExpanded(content, width, bannerFrame, sparkleMs)\n\t\t: renderCompact(content, width, bannerFrame, sparkleMs);\n}\n\nexport function renderControlPanelRightPane(content: ControlPanelContent, width: number): string[] {\n\tif (width <= 0) return [];\n\treturn sidebarPanel(content, width);\n}\n\nfunction renderCompact(content: ControlPanelContent, width: number, bannerFrame?: string[], sparkleMs = 0): string[] {\n\tif (width >= CONTROL_PANEL_DECK_MIN_WIDTH) {\n\t\tconst deck = renderDeck(content, width, bannerFrame, sparkleMs);\n\t\tif (deck.length > 0) return deck;\n\t}\n\treturn [\n\t\tdivider(width, \"OMK//CONTROL PANEL\", \"accent\"),\n\t\tstatusLine(content, width),\n\t\ttextLine(width, content.compactInstructions()),\n\t\ttextLine(width, content.compactOnboarding(), \"dim\"),\n\t];\n}\n\nfunction renderDeck(content: ControlPanelContent, width: number, bannerFrame?: string[], sparkleMs = 0): string[] {\n\tconst { leftWidth, sidebarWidth } = deckWidths(width);\n\tif (leftWidth < 72) return [];\n\tconst hero = heroPanel(content, leftWidth, bannerFrame, sparkleMs);\n\tconst rail = sidebarPanel(content, sidebarWidth);\n\t// Both framed columns close on the same row so the deck reads as one block\n\t// instead of a short hero beside a long ragged rail.\n\tconst deckHeight = Math.max(hero.length, rail.length);\n\tconst lines = composeColumns(\n\t\tpadBoxColumn(hero, deckHeight, leftWidth, \"center\"),\n\t\tleftWidth,\n\t\tpadBoxColumn(rail, deckHeight, sidebarWidth),\n\t\tsidebarWidth,\n\t\tCONTROL_PANEL_GAP_WIDTH,\n\t\twidth,\n\t);\n\tlines.push(controlStripLine(content, width));\n\tlines.push(centerLine(width, content.compactOnboarding(), \"dim\"));\n\treturn lines;\n}\n\nfunction deckWidths(width: number): { leftWidth: number; sidebarWidth: number } {\n\tconst sidebarWidth = Math.min(CONTROL_PANEL_SIDEBAR_WIDTH, Math.max(34, Math.floor(width * 0.28)));\n\treturn { leftWidth: width - CONTROL_PANEL_GAP_WIDTH - sidebarWidth, sidebarWidth };\n}\n\nfunction heroPanel(content: ControlPanelContent, width: number, bannerFrame?: string[], sparkleMs = 0): string[] {\n\tconst snapshot = statusSnapshot(content);\n\tconst innerWidth = Math.max(0, width - 4);\n\treturn [\n\t\t// One wordmark only: the framed title chip carries the product name, so the\n\t\t// hero body is the block mark plus live state, not a second text logotype.\n\t\tboxTop(width, `omk v${content.version} · OMK://CONTROL`),\n\t\tboxTextLine(width, sparkleRow(innerWidth, SPARKLE_ROW_TOP, sparkleMs)),\n\t\t...(bannerFrame ?? CONTROL_PANEL_ASCII_ART).map((line, index, rows) => {\n\t\t\tif (bannerFrame) return boxCenteredLine(width, line);\n\t\t\t// Single-tone wordmark: the top and bottom scanlines fall back to the\n\t\t\t// dim ink so the mark reads as one lit object rather than a four-colour\n\t\t\t// stack. Accent stays the only hue in the hero.\n\t\t\tconst isEdge = index === 0 || index === rows.length - 1;\n\t\t\tconst isCore = index === Math.floor(rows.length / 2);\n\t\t\tconst painted = theme.fg(isEdge ? \"dim\" : \"accent\", line);\n\t\t\treturn boxCenteredLine(width, isCore ? theme.bold(painted) : painted);\n\t\t}),\n\t\tboxTextLine(width, sparkleRow(innerWidth, SPARKLE_ROW_BOTTOM, sparkleMs)),\n\t\tboxCenteredLine(\n\t\t\twidth,\n\t\t\t`${theme.fg(\"success\", \"●\")} ${theme.fg(\"muted\", \"MODEL\")} ${theme.fg(\"text\", heroModelLabel(snapshot))}`,\n\t\t),\n\t\tboxCenteredLine(\n\t\t\twidth,\n\t\t\t[\"route\", \"verify\", \"loop\", \"control\"]\n\t\t\t\t.map((stage) => theme.fg(\"dim\", stage))\n\t\t\t\t.join(theme.fg(\"borderMuted\", \" · \")),\n\t\t),\n\t\tboxTextLine(width, \"\"),\n\t\tboxRuleLine(width, Math.max(4, Math.floor(innerWidth * 0.18))),\n\t\tboxCenteredLine(width, heroMetaStrip(snapshot)),\n\t\tboxBottom(width),\n\t];\n}\n\n/**\n * Compact meta strip under the wordmark: the same signals the narrow layout\n * shows beside the banner, rendered as one centred row so the hero carries\n * real state instead of empty deck height.\n */\nfunction heroMetaStrip(snapshot: ControlPanelStatusSnapshot): string {\n\tconst rawThemeName = theme.name ?? \"live\";\n\tconst themeName = (rawThemeName.startsWith(\"omk-\") ? rawThemeName.slice(4) : rawThemeName).toUpperCase();\n\tconst cells: Array<[string, string]> = [\n\t\t[\"PANEL\", snapshot.runtimeState ?? \"unknown\"],\n\t\t[\"THEME\", themeName],\n\t\t[\"STARTUP\", snapshot.startupState ?? \"unknown\"],\n\t\t[\"LINK\", snapshot.linkState ?? \"unknown\"],\n\t];\n\treturn cells\n\t\t.map(([label, value]) => `${theme.fg(\"muted\", label)} ${coloredStatus(value)}`)\n\t\t.join(theme.fg(\"borderMuted\", \" · \"));\n}\n\nfunction heroModelLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tif (!snapshot.modelId) return \"no-model\";\n\tconst think = snapshot.thinkingLevel;\n\treturn think && think !== \"off\" ? `${snapshot.modelId}:${think}` : snapshot.modelId;\n}\n\n/**\n * Label gutters are aligned per section rather than across the whole rail: a\n * global gutter would indent short labels so far that long values (todo text,\n * model ids) lose characters at rail widths of 34-38 columns.\n */\nconst RAIL_COLUMNS = {\n\tstatus: 8,\n\ttodo: 4,\n\tsession: 3,\n\tmodel: 5,\n\truntime: 8,\n\tcontrol: 7,\n} as const;\n\nfunction sidebarPanel(content: ControlPanelContent, width: number): string[] {\n\tconst snapshot = statusSnapshot(content);\n\tconst headroomLabel = snapshot.headroomStatus ?? snapshot.optimizerPolicy ?? \"unknown\";\n\tconst mcpCount = snapshot.mcpCount;\n\tconst skillCount = snapshot.skillCount;\n\tconst packageIntakeLabel = packageIntakeStatusLabel(snapshot.packageIntake);\n\tconst contextMeter = contextMeterLabel(snapshot);\n\tconst activitySparkline = activitySparklineLabel(snapshot);\n\treturn [\n\t\tsidebarTabs(width),\n\t\tboxCenteredLine(width, theme.bold(theme.fg(\"accent\", \"OMK://CONTROL\"))),\n\t\tboxCenteredLine(width, theme.fg(\"dim\", \"CYBERPUNK OPS CORE\")),\n\t\tboxCenteredLine(\n\t\t\twidth,\n\t\t\t`${theme.fg(\"muted\", \"MATRIX RAIN\")}${theme.fg(\"borderMuted\", \" // \")}${theme.fg(\"muted\", \"NEON GRID ONLINE\")}`,\n\t\t),\n\t\tboxCenteredLine(width, theme.fg(\"dim\", \"NIGHT-CITY-MATRIX-V3\")),\n\t\tsidebarRule(width, \"STATUS\"),\n\t\tboxTextLine(\n\t\t\twidth,\n\t\t\t`${labelCell(\"state\", RAIL_COLUMNS.status)} ${coloredStatus(snapshot.runtimeState ?? \"unknown\")}`,\n\t\t),\n\t\tboxTextLine(\n\t\t\twidth,\n\t\t\t`${labelCell(\"route\", RAIL_COLUMNS.status)} ${coloredStatus(snapshot.routeState ?? \"unknown\")}`,\n\t\t),\n\t\tboxTextLine(\n\t\t\twidth,\n\t\t\t`${labelCell(\"evidence\", RAIL_COLUMNS.status)} ${coloredStatus(snapshot.evidenceState ?? \"unknown\")}`,\n\t\t),\n\t\tsidebarRule(width, \"TODO\"),\n\t\t...todoSidebarLines(snapshot.todoState, width),\n\t\tsidebarRule(width, \"SESSION\"),\n\t\tsemanticBoxTextLine(width, \"cwd\", snapshot.cwdLabel ?? \"?\", \"end\", RAIL_COLUMNS.session),\n\t\tsemanticBoxTextLine(width, \"git\", snapshot.gitBranch ?? \"?\", \"start\", RAIL_COLUMNS.session),\n\t\tsidebarRule(width, \"MODEL / CTX\"),\n\t\tsemanticBoxTextLine(width, \"model\", modelStatusLabel(snapshot), \"end\", RAIL_COLUMNS.model),\n\t\tsemanticBoxTextLine(width, \"think\", snapshot.thinkingLevel ?? \"off\", \"start\", RAIL_COLUMNS.model),\n\t\tboxTextLine(\n\t\t\twidth,\n\t\t\t`${labelCell(\"ctx\", RAIL_COLUMNS.model)} ${theme.fg(statusColor(snapshot.contextPercent === undefined || snapshot.contextPercent === null ? \"unknown\" : \"ready\"), contextStatusLabel(snapshot))}`,\n\t\t),\n\t\tboxTextLine(width, `${labelCell(\"meter\", RAIL_COLUMNS.model)} ${contextMeter}`),\n\t\tboxTextLine(width, `${labelCell(\"pulse\", RAIL_COLUMNS.model)} ${activitySparkline}`),\n\t\tsidebarRule(width, \"RUNTIME / MCP / SKILLS\"),\n\t\tsemanticBoxTextLine(width, \"headroom\", headroomLabel, \"end\", RAIL_COLUMNS.runtime),\n\t\tsemanticBoxTextLine(width, \"omk\", snapshot.dagOrchestrationState ?? \"unknown\", \"end\", RAIL_COLUMNS.runtime),\n\t\tsemanticBoxTextLine(width, \"sidebar\", snapshot.sidebarState ?? \"unknown\", \"start\", RAIL_COLUMNS.runtime),\n\t\tboxTextLine(\n\t\t\twidth,\n\t\t\t`${labelCell(\"res\", RAIL_COLUMNS.runtime)} MCP:${mcpCount ?? \"?\"} skills:${skillCount ?? \"?\"}`,\n\t\t),\n\t\tsemanticBoxTextLine(width, \"pkg\", packageIntakeLabel, \"end\", RAIL_COLUMNS.runtime),\n\t\t// CONTROL previously repeated STATUS's route row verbatim; the rail now\n\t\t// carries each signal exactly once.\n\t\tsidebarRule(width, \"CONTROL\"),\n\t\tboxTextLine(\n\t\t\twidth,\n\t\t\t`${labelCell(\"verify\", RAIL_COLUMNS.control)} ${coloredStatus(snapshot.evidenceState ?? \"unknown\")}`,\n\t\t),\n\t\tboxTextLine(\n\t\t\twidth,\n\t\t\t`${labelCell(\"control\", RAIL_COLUMNS.control)} ${coloredStatus(snapshot.controlState ?? \"unknown\")}`,\n\t\t),\n\t\tboxBottom(width),\n\t];\n}\n\nfunction semanticBoxTextLine(\n\twidth: number,\n\tlabel: string,\n\tvalue: string,\n\tpreserve: \"start\" | \"middle\" | \"end\",\n\tcolumn?: number,\n): string {\n\t// Alignment is a courtesy, not a cost: if the gutter indent would truncate the\n\t// value, this row drops back to a flush label so the data survives intact.\n\tconst aligned = `${labelCell(label, column)} `;\n\tconst flush = `${labelCell(label, label.length)} `;\n\tconst alignedRoom = Math.max(0, width - 4 - visibleWidth(aligned));\n\tconst prefix = visibleWidth(value) <= alignedRoom ? aligned : flush;\n\tconst availableWidth = Math.max(0, width - 4 - visibleWidth(prefix));\n\treturn boxTextLine(width, `${prefix}${semanticTruncate(value, availableWidth, preserve)}`);\n}\n\nfunction semanticTruncate(value: string, maxWidth: number, preserve: \"start\" | \"middle\" | \"end\"): string {\n\tif (visibleWidth(value) <= maxWidth) return value;\n\tif (maxWidth <= 0) return \"\";\n\tif (preserve === \"start\") return truncateToWidth(value, maxWidth, \"…\");\n\tconst ellipsis = \"…\";\n\tconst targetWidth = maxWidth - visibleWidth(ellipsis);\n\tif (targetWidth <= 0) return truncateToWidth(ellipsis, maxWidth, \"\");\n\tif (preserve === \"middle\") {\n\t\tconst headWidth = Math.max(1, Math.floor(targetWidth / 2));\n\t\tconst tailWidth = Math.max(1, targetWidth - headWidth);\n\t\treturn `${takeStart(value, headWidth)}${ellipsis}${takeEnd(value, tailWidth)}`;\n\t}\n\treturn `${ellipsis}${takeEnd(value, targetWidth)}`;\n}\n\nfunction takeStart(value: string, maxWidth: number): string {\n\tlet prefix = \"\";\n\tfor (const char of Array.from(value)) {\n\t\tif (visibleWidth(prefix + char) > maxWidth) break;\n\t\tprefix += char;\n\t}\n\treturn prefix;\n}\n\nfunction takeEnd(value: string, maxWidth: number): string {\n\tlet suffix = \"\";\n\tfor (const char of Array.from(value).reverse()) {\n\t\tif (visibleWidth(char + suffix) > maxWidth) break;\n\t\tsuffix = char + suffix;\n\t}\n\treturn suffix;\n}\n\nfunction statusToken(label: string, value: string | undefined): string {\n\tconst state = value ?? \"unknown\";\n\treturn theme.fg(statusColor(state), `${label}:${state.toUpperCase()}`);\n}\n\nfunction coloredStatus(value: string): string {\n\treturn theme.fg(statusColor(value), value);\n}\n\nfunction statusColor(value: string): ThemeColor {\n\tconst normalized = value.toLowerCase();\n\tif ([\"ready\", \"on\", \"active\", \"available\", \"linked\", \"tracking\", \"pinned\"].includes(normalized)) return \"success\";\n\tif ([\"degraded\", \"limited\", \"blocked\", \"off\"].includes(normalized)) return \"warning\";\n\treturn \"muted\";\n}\n\nfunction todoSidebarLines(state: TodoState | undefined, width: number): string[] {\n\tif (!state || state.items.length === 0) {\n\t\treturn [\n\t\t\tboxTextLine(width, `${labelCell(\"todo\", RAIL_COLUMNS.todo)} ${theme.fg(\"dim\", \"empty\")}`),\n\t\t\tboxTextLine(width, `${labelCell(\"next\", RAIL_COLUMNS.todo)} ${theme.fg(\"dim\", \"no active todos\")}`),\n\t\t];\n\t}\n\tconst counts = todoSummary(state);\n\tconst next = nextActiveTodo(state);\n\treturn [\n\t\tboxTextLine(width, `${labelCell(\"todo\", RAIL_COLUMNS.todo)} ${counts.done}/${counts.total} done`),\n\t\tsemanticBoxTextLine(width, \"next\", next?.label ?? \"complete\", \"middle\", RAIL_COLUMNS.todo),\n\t];\n}\n\nfunction packageIntakeStatusLabel(summary: PiPackageIntakeSummary | undefined): string {\n\tif (!summary) return \"ports:pending\";\n\tconst ready =\n\t\tsummary.acceptedNative + summary.acceptedReference + summary.acceptedMeasurement + summary.acceptedAdvisory;\n\tconst review = summary.deferred + summary.reject;\n\treturn `ports:${ready}/${summary.total} review:${review} block:${summary.hardForkBlocked}`;\n}\n\nfunction renderExpanded(content: ControlPanelContent, width: number, bannerFrame?: string[], sparkleMs = 0): string[] {\n\tif (width >= CONTROL_PANEL_DECK_MIN_WIDTH) {\n\t\tconst { leftWidth, sidebarWidth } = deckWidths(width);\n\t\tconst resourceLines = [\"\", ...content.onboarding().split(\"\\n\")];\n\t\tconst rightRail = blankSidebarRail(sidebarWidth, resourceLines.length);\n\t\tconst lines = [...renderDeck(content, width, bannerFrame, sparkleMs)];\n\t\tlines.push(...composeColumns(resourceLines, leftWidth, rightRail, sidebarWidth, CONTROL_PANEL_GAP_WIDTH, width));\n\t\treturn lines;\n\t}\n\n\tconst lines = [divider(width, \"OMK//CONTROL PANEL\", \"accent\"), statusLine(content, width)];\n\tif (width >= 32) lines.push(...brandLines(content, width, bannerFrame));\n\tlines.push(divider(width, \"SYSTEM MAP\", \"mdHeading\"));\n\tfor (const instruction of content.expandedInstructions().split(\"\\n\")) lines.push(textLine(width, instruction));\n\tlines.push(divider(width, \"STARTUP LINK\", \"success\"));\n\tfor (const onboardingLine of content.onboarding().split(\"\\n\")) lines.push(textLine(width, onboardingLine, \"dim\"));\n\tlines.push(divider(width, \"END\", \"borderMuted\"));\n\treturn lines;\n}\n\nfunction blankSidebarRail(width: number, lineCount: number): string[] {\n\treturn Array.from({ length: lineCount }, () => boxTextLine(width, \"\"));\n}\n\nfunction statusSnapshot(content: ControlPanelContent): ControlPanelStatusSnapshot {\n\treturn content.statusSnapshot?.() ?? {};\n}\n\nfunction modelStatusLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tif (!snapshot.modelId) return \"no-model\";\n\treturn snapshot.modelProvider ? `${snapshot.modelProvider}/${snapshot.modelId}` : snapshot.modelId;\n}\n\nfunction contextStatusLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tconst windowTokens = snapshot.contextWindowTokens ?? 0;\n\tconst windowLabel = windowTokens > 0 ? formatTokens(windowTokens) : \"?\";\n\treturn snapshot.contextPercent === null || snapshot.contextPercent === undefined\n\t\t? `?/${windowLabel}`\n\t\t: `${snapshot.contextPercent.toFixed(1)}%/${windowLabel}`;\n}\n\nfunction contextMeterLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tconst percent = normalizePercent(snapshot.contextPercent);\n\tif (percent === undefined) {\n\t\treturn `${theme.fg(\"borderMuted\", \"░\".repeat(CONTEXT_METER_CELLS))} ${theme.fg(\"muted\", \"??%\")}`;\n\t}\n\tconst filled = Math.max(0, Math.min(CONTEXT_METER_CELLS, Math.round((percent / 100) * CONTEXT_METER_CELLS)));\n\tconst color: ThemeColor = percent >= 85 ? \"warning\" : percent >= 65 ? \"mdCode\" : \"success\";\n\treturn `${theme.fg(color, \"█\".repeat(filled))}${theme.fg(\"borderMuted\", \"░\".repeat(CONTEXT_METER_CELLS - filled))} ${theme.fg(color, `${Math.round(percent)}%`)}`;\n}\n\nfunction activitySparklineLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tconst seed = hashSnapshot(snapshot);\n\tconst glyphs = Array.from(SPARKLINE_GLYPHS);\n\tconst parts: string[] = [];\n\tfor (let index = 0; index < SPARKLINE_WIDTH; index++) {\n\t\tconst level = (seed + index * 5 + index * index) % glyphs.length;\n\t\tconst glyph = glyphs[level] ?? \"▁\";\n\t\t// Colour follows amplitude instead of column index, so the pulse reads as\n\t\t// one signal in the accent hue rather than a rotating three-colour pattern.\n\t\tconst color: ThemeColor = level >= glyphs.length - 2 ? \"accent\" : level >= 3 ? \"muted\" : \"dim\";\n\t\tparts.push(theme.fg(color, glyph));\n\t}\n\treturn parts.join(\"\");\n}\n\nfunction normalizePercent(value: number | null | undefined): number | undefined {\n\tif (value === null || value === undefined || !Number.isFinite(value)) return undefined;\n\tif (value < 0) return 0;\n\tif (value > 100) return 100;\n\treturn value;\n}\n\nfunction hashSnapshot(snapshot: ControlPanelStatusSnapshot): number {\n\tconst source = [\n\t\tsnapshot.modelProvider,\n\t\tsnapshot.modelId,\n\t\tsnapshot.contextPercent?.toFixed(1),\n\t\tsnapshot.contextTokens,\n\t\tsnapshot.contextWindowTokens,\n\t\tsnapshot.cwdLabel,\n\t\tsnapshot.gitBranch,\n\t].join(\"|\");\n\tlet hash = 2166136261;\n\tfor (let index = 0; index < source.length; index++) {\n\t\thash ^= source.charCodeAt(index);\n\t\thash = Math.imul(hash, 16777619);\n\t}\n\treturn hash >>> 0;\n}\n\nfunction formatTokens(count: number): string {\n\tif (count < 1000) return count.toString();\n\tif (count < 10000) return `${(count / 1000).toFixed(1)}k`;\n\tif (count < 1000000) return `${Math.round(count / 1000)}k`;\n\tif (count < 10000000) return `${(count / 1000000).toFixed(1)}M`;\n\treturn `${Math.round(count / 1000000)}M`;\n}\n\nfunction sidebarTabs(width: number): string {\n\treturn boxTextLine(\n\t\twidth,\n\t\tfitLine(\n\t\t\t`${theme.bold(theme.fg(\"accent\", \"1:CONTROL\"))} ${theme.fg(\"muted\", \"2:HISTORY\")}`,\n\t\t\tMath.max(0, width - 4),\n\t\t),\n\t);\n}\n\nfunction controlStripLine(content: ControlPanelContent, width: number): string {\n\treturn centerLine(\n\t\twidth,\n\t\t`${theme.bold(theme.fg(\"accent\", \"OMK://CONTROL READ\"))} ${theme.fg(\"accent\", \"route/verify/loop/control\")} · ${content.compactInstructions()}`,\n\t);\n}\n\nfunction brandLines(content: ControlPanelContent, width: number, bannerFrame?: string[]): string[] {\n\tconst art = bannerFrame ?? CONTROL_PANEL_ASCII_ART;\n\tif (bannerFrame) return art.map((line) => textLine(width, line));\n\tconst leftWidth = Math.max(...art.map((line) => visibleWidth(line)));\n\tconst minWideWidth = visibleWidth(\"| \") + leftWidth + visibleWidth(\" | \") + META_WIDTH;\n\tif (width < minWideWidth) return art.map((line) => textLine(width, theme.fg(\"accent\", line)));\n\tconst snapshot = statusSnapshot(content);\n\treturn art.map((line, index) =>\n\t\ttextLine(\n\t\t\twidth,\n\t\t\t`${fitLine(theme.fg(\"accent\", line), leftWidth)}${theme.fg(\"borderMuted\", \" | \")}${metadataLines(snapshot)[index] ?? \"\"}`,\n\t\t),\n\t);\n}\n\nfunction metadataLines(snapshot: ControlPanelStatusSnapshot): string[] {\n\tconst rawThemeName = theme.name ?? \"live\";\n\tconst themeName = (rawThemeName.startsWith(\"omk-\") ? rawThemeName.slice(4) : rawThemeName).toUpperCase();\n\treturn [\n\t\t`${theme.fg(\"mdCode\", \"PANEL\")} ${coloredStatus(snapshot.runtimeState ?? \"unknown\")}`,\n\t\t`${theme.fg(\"mdCode\", \"THEME\")} ${theme.fg(\"accent\", themeName)}`,\n\t\t`${theme.fg(\"mdCode\", \"STARTUP\")} ${coloredStatus(snapshot.startupState ?? \"unknown\")}`,\n\t\t`${theme.fg(\"mdCode\", \"LINK\")} ${coloredStatus(snapshot.linkState ?? \"unknown\")}`,\n\t];\n}\n\nfunction statusLine(content: ControlPanelContent, width: number): string {\n\tconst snapshot = statusSnapshot(content);\n\tconst segments = [\n\t\ttheme.bold(theme.fg(\"accent\", `${content.appName.toUpperCase()} v${content.version}`)),\n\t\tstatusToken(\"CORE\", snapshot.runtimeState),\n\t\tstatusToken(\"ANSI\", snapshot.ansiColorState),\n\t\tstatusToken(\"STARTUP\", snapshot.startupState),\n\t\tstatusToken(\"LINK\", snapshot.linkState),\n\t\ttheme.fg(\"muted\", \"THEME:LIVE\"),\n\t];\n\treturn textLine(width, segments.join(theme.fg(\"borderMuted\", \" | \")));\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { truncateToWidth, visibleWidth } from "omk-tui";
2
2
  import { nextActiveTodo, summary as todoSummary } from "../../../core/todo-state.js";
3
3
  import { theme } from "../theme/theme.js";
4
- import { boxBottom, boxCenteredLine, boxTextLine, boxTop, centerLine, composeColumns, divider, fitLine, sidebarRule, textLine, } from "./control-panel-box.js";
4
+ import { boxBottom, boxCenteredLine, boxRuleLine, boxTextLine, boxTop, centerLine, composeColumns, divider, fitLine, labelCell, padBoxColumn, sidebarRule, textLine, } from "./control-panel-box.js";
5
5
  import { SPARKLE_ROW_BOTTOM, SPARKLE_ROW_TOP, sparkleRow } from "./control-panel-sparkles.js";
6
6
  export const CONTROL_PANEL_ASCII_ART = [
7
7
  " ███████ ██ ██ ██ ██",
@@ -49,7 +49,12 @@ function renderDeck(content, width, bannerFrame, sparkleMs = 0) {
49
49
  const { leftWidth, sidebarWidth } = deckWidths(width);
50
50
  if (leftWidth < 72)
51
51
  return [];
52
- const lines = composeColumns(heroPanel(content, leftWidth, bannerFrame, sparkleMs), leftWidth, sidebarPanel(content, sidebarWidth), sidebarWidth, CONTROL_PANEL_GAP_WIDTH, width);
52
+ const hero = heroPanel(content, leftWidth, bannerFrame, sparkleMs);
53
+ const rail = sidebarPanel(content, sidebarWidth);
54
+ // Both framed columns close on the same row so the deck reads as one block
55
+ // instead of a short hero beside a long ragged rail.
56
+ const deckHeight = Math.max(hero.length, rail.length);
57
+ const lines = composeColumns(padBoxColumn(hero, deckHeight, leftWidth, "center"), leftWidth, padBoxColumn(rail, deckHeight, sidebarWidth), sidebarWidth, CONTROL_PANEL_GAP_WIDTH, width);
53
58
  lines.push(controlStripLine(content, width));
54
59
  lines.push(centerLine(width, content.compactOnboarding(), "dim"));
55
60
  return lines;
@@ -62,28 +67,69 @@ function heroPanel(content, width, bannerFrame, sparkleMs = 0) {
62
67
  const snapshot = statusSnapshot(content);
63
68
  const innerWidth = Math.max(0, width - 4);
64
69
  return [
70
+ // One wordmark only: the framed title chip carries the product name, so the
71
+ // hero body is the block mark plus live state, not a second text logotype.
65
72
  boxTop(width, `omk v${content.version} · OMK://CONTROL`),
66
- boxCenteredLine(width, theme.bold(theme.fg("accent", "OMK"))),
67
- boxCenteredLine(width, theme.fg("muted", "route · verify · loop · control")),
68
73
  boxTextLine(width, sparkleRow(innerWidth, SPARKLE_ROW_TOP, sparkleMs)),
69
- ...(bannerFrame ?? CONTROL_PANEL_ASCII_ART).map((line, index) => {
74
+ ...(bannerFrame ?? CONTROL_PANEL_ASCII_ART).map((line, index, rows) => {
70
75
  if (bannerFrame)
71
76
  return boxCenteredLine(width, line);
72
- const color = index < 2 ? "mdCode" : index < 4 ? "accent" : index < 6 ? "success" : "warning";
73
- return boxCenteredLine(width, theme.fg(color, line));
77
+ // Single-tone wordmark: the top and bottom scanlines fall back to the
78
+ // dim ink so the mark reads as one lit object rather than a four-colour
79
+ // stack. Accent stays the only hue in the hero.
80
+ const isEdge = index === 0 || index === rows.length - 1;
81
+ const isCore = index === Math.floor(rows.length / 2);
82
+ const painted = theme.fg(isEdge ? "dim" : "accent", line);
83
+ return boxCenteredLine(width, isCore ? theme.bold(painted) : painted);
74
84
  }),
75
85
  boxTextLine(width, sparkleRow(innerWidth, SPARKLE_ROW_BOTTOM, sparkleMs)),
76
- boxCenteredLine(width, `${theme.fg("warning", "●")} ${theme.bold("OMK")} / ${theme.fg("success", heroModelLabel(snapshot))}`),
77
- boxCenteredLine(width, `${theme.fg("mdCode", "◇")} omk-control · ${theme.fg("accent", "route")} · ${theme.fg("warning", "verify")} · ${theme.fg("success", "loop")} · ${theme.fg("mdCode", "control")}`),
86
+ boxCenteredLine(width, `${theme.fg("success", "●")} ${theme.fg("muted", "MODEL")} ${theme.fg("text", heroModelLabel(snapshot))}`),
87
+ boxCenteredLine(width, ["route", "verify", "loop", "control"]
88
+ .map((stage) => theme.fg("dim", stage))
89
+ .join(theme.fg("borderMuted", " · "))),
90
+ boxTextLine(width, ""),
91
+ boxRuleLine(width, Math.max(4, Math.floor(innerWidth * 0.18))),
92
+ boxCenteredLine(width, heroMetaStrip(snapshot)),
78
93
  boxBottom(width),
79
94
  ];
80
95
  }
96
+ /**
97
+ * Compact meta strip under the wordmark: the same signals the narrow layout
98
+ * shows beside the banner, rendered as one centred row so the hero carries
99
+ * real state instead of empty deck height.
100
+ */
101
+ function heroMetaStrip(snapshot) {
102
+ const rawThemeName = theme.name ?? "live";
103
+ const themeName = (rawThemeName.startsWith("omk-") ? rawThemeName.slice(4) : rawThemeName).toUpperCase();
104
+ const cells = [
105
+ ["PANEL", snapshot.runtimeState ?? "unknown"],
106
+ ["THEME", themeName],
107
+ ["STARTUP", snapshot.startupState ?? "unknown"],
108
+ ["LINK", snapshot.linkState ?? "unknown"],
109
+ ];
110
+ return cells
111
+ .map(([label, value]) => `${theme.fg("muted", label)} ${coloredStatus(value)}`)
112
+ .join(theme.fg("borderMuted", " · "));
113
+ }
81
114
  function heroModelLabel(snapshot) {
82
115
  if (!snapshot.modelId)
83
116
  return "no-model";
84
117
  const think = snapshot.thinkingLevel;
85
118
  return think && think !== "off" ? `${snapshot.modelId}:${think}` : snapshot.modelId;
86
119
  }
120
+ /**
121
+ * Label gutters are aligned per section rather than across the whole rail: a
122
+ * global gutter would indent short labels so far that long values (todo text,
123
+ * model ids) lose characters at rail widths of 34-38 columns.
124
+ */
125
+ const RAIL_COLUMNS = {
126
+ status: 8,
127
+ todo: 4,
128
+ session: 3,
129
+ model: 5,
130
+ runtime: 8,
131
+ control: 7,
132
+ };
87
133
  function sidebarPanel(content, width) {
88
134
  const snapshot = statusSnapshot(content);
89
135
  const headroomLabel = snapshot.headroomStatus ?? snapshot.optimizerPolicy ?? "unknown";
@@ -95,39 +141,45 @@ function sidebarPanel(content, width) {
95
141
  return [
96
142
  sidebarTabs(width),
97
143
  boxCenteredLine(width, theme.bold(theme.fg("accent", "OMK://CONTROL"))),
98
- boxCenteredLine(width, theme.bold(theme.fg("warning", "CYBERPUNK OPS CORE"))),
99
- boxCenteredLine(width, `${theme.fg("mdCode", "MATRIX RAIN")} // ${theme.fg("success", "NEON GRID ONLINE")}`),
100
- boxCenteredLine(width, theme.fg("text", "NIGHT-CITY-MATRIX-V3")),
101
- sidebarRule(width, "STATUS", "accent"),
102
- boxTextLine(width, `${theme.fg("muted", "state:")} ${coloredStatus(snapshot.runtimeState ?? "unknown")}`),
103
- boxTextLine(width, `${theme.fg("muted", "route:")} ${coloredStatus(snapshot.routeState ?? "unknown")}`),
104
- boxTextLine(width, `${theme.fg("muted", "evidence:")} ${coloredStatus(snapshot.evidenceState ?? "unknown")}`),
105
- sidebarRule(width, "TODO", "accent"),
144
+ boxCenteredLine(width, theme.fg("dim", "CYBERPUNK OPS CORE")),
145
+ boxCenteredLine(width, `${theme.fg("muted", "MATRIX RAIN")}${theme.fg("borderMuted", " // ")}${theme.fg("muted", "NEON GRID ONLINE")}`),
146
+ boxCenteredLine(width, theme.fg("dim", "NIGHT-CITY-MATRIX-V3")),
147
+ sidebarRule(width, "STATUS"),
148
+ boxTextLine(width, `${labelCell("state", RAIL_COLUMNS.status)} ${coloredStatus(snapshot.runtimeState ?? "unknown")}`),
149
+ boxTextLine(width, `${labelCell("route", RAIL_COLUMNS.status)} ${coloredStatus(snapshot.routeState ?? "unknown")}`),
150
+ boxTextLine(width, `${labelCell("evidence", RAIL_COLUMNS.status)} ${coloredStatus(snapshot.evidenceState ?? "unknown")}`),
151
+ sidebarRule(width, "TODO"),
106
152
  ...todoSidebarLines(snapshot.todoState, width),
107
- sidebarRule(width, "SESSION", "accent"),
108
- semanticBoxTextLine(width, "cwd", snapshot.cwdLabel ?? "?", "end"),
109
- semanticBoxTextLine(width, "git", snapshot.gitBranch ?? "?", "start"),
110
- sidebarRule(width, "MODEL / CTX", "accent"),
111
- semanticBoxTextLine(width, "model", modelStatusLabel(snapshot), "end"),
112
- semanticBoxTextLine(width, "think", snapshot.thinkingLevel ?? "off", "start"),
113
- boxTextLine(width, `${theme.fg("muted", "ctx:")} ${theme.fg(statusColor(snapshot.contextPercent === undefined || snapshot.contextPercent === null ? "unknown" : "ready"), contextStatusLabel(snapshot))}`),
114
- boxTextLine(width, `${theme.fg("muted", "meter:")} ${contextMeter}`),
115
- boxTextLine(width, `${theme.fg("muted", "pulse:")} ${activitySparkline}`),
116
- sidebarRule(width, "RUNTIME / MCP / SKILLS", "accent"),
117
- semanticBoxTextLine(width, "headroom", headroomLabel, "end"),
118
- semanticBoxTextLine(width, "omk", snapshot.dagOrchestrationState ?? "unknown", "end"),
119
- semanticBoxTextLine(width, "sidebar", snapshot.sidebarState ?? "unknown", "start"),
120
- boxTextLine(width, `${theme.fg("muted", "res:")} MCP:${mcpCount ?? "?"} skills:${skillCount ?? "?"}`),
121
- semanticBoxTextLine(width, "pkg", packageIntakeLabel, "end"),
122
- sidebarRule(width, "CONTROL", "accent"),
123
- boxTextLine(width, `${theme.fg("muted", "route:")} ${coloredStatus(snapshot.routeState ?? "unknown")}`),
124
- boxTextLine(width, `${theme.fg("muted", "verify:")} ${coloredStatus(snapshot.evidenceState ?? "unknown")}`),
125
- boxTextLine(width, `${theme.fg("muted", "control:")} ${coloredStatus(snapshot.controlState ?? "unknown")}`),
126
- boxBottom(width, "accent"),
153
+ sidebarRule(width, "SESSION"),
154
+ semanticBoxTextLine(width, "cwd", snapshot.cwdLabel ?? "?", "end", RAIL_COLUMNS.session),
155
+ semanticBoxTextLine(width, "git", snapshot.gitBranch ?? "?", "start", RAIL_COLUMNS.session),
156
+ sidebarRule(width, "MODEL / CTX"),
157
+ semanticBoxTextLine(width, "model", modelStatusLabel(snapshot), "end", RAIL_COLUMNS.model),
158
+ semanticBoxTextLine(width, "think", snapshot.thinkingLevel ?? "off", "start", RAIL_COLUMNS.model),
159
+ boxTextLine(width, `${labelCell("ctx", RAIL_COLUMNS.model)} ${theme.fg(statusColor(snapshot.contextPercent === undefined || snapshot.contextPercent === null ? "unknown" : "ready"), contextStatusLabel(snapshot))}`),
160
+ boxTextLine(width, `${labelCell("meter", RAIL_COLUMNS.model)} ${contextMeter}`),
161
+ boxTextLine(width, `${labelCell("pulse", RAIL_COLUMNS.model)} ${activitySparkline}`),
162
+ sidebarRule(width, "RUNTIME / MCP / SKILLS"),
163
+ semanticBoxTextLine(width, "headroom", headroomLabel, "end", RAIL_COLUMNS.runtime),
164
+ semanticBoxTextLine(width, "omk", snapshot.dagOrchestrationState ?? "unknown", "end", RAIL_COLUMNS.runtime),
165
+ semanticBoxTextLine(width, "sidebar", snapshot.sidebarState ?? "unknown", "start", RAIL_COLUMNS.runtime),
166
+ boxTextLine(width, `${labelCell("res", RAIL_COLUMNS.runtime)} MCP:${mcpCount ?? "?"} skills:${skillCount ?? "?"}`),
167
+ semanticBoxTextLine(width, "pkg", packageIntakeLabel, "end", RAIL_COLUMNS.runtime),
168
+ // CONTROL previously repeated STATUS's route row verbatim; the rail now
169
+ // carries each signal exactly once.
170
+ sidebarRule(width, "CONTROL"),
171
+ boxTextLine(width, `${labelCell("verify", RAIL_COLUMNS.control)} ${coloredStatus(snapshot.evidenceState ?? "unknown")}`),
172
+ boxTextLine(width, `${labelCell("control", RAIL_COLUMNS.control)} ${coloredStatus(snapshot.controlState ?? "unknown")}`),
173
+ boxBottom(width),
127
174
  ];
128
175
  }
129
- function semanticBoxTextLine(width, label, value, preserve) {
130
- const prefix = `${theme.fg("muted", `${label}:`)} `;
176
+ function semanticBoxTextLine(width, label, value, preserve, column) {
177
+ // Alignment is a courtesy, not a cost: if the gutter indent would truncate the
178
+ // value, this row drops back to a flush label so the data survives intact.
179
+ const aligned = `${labelCell(label, column)} `;
180
+ const flush = `${labelCell(label, label.length)} `;
181
+ const alignedRoom = Math.max(0, width - 4 - visibleWidth(aligned));
182
+ const prefix = visibleWidth(value) <= alignedRoom ? aligned : flush;
131
183
  const availableWidth = Math.max(0, width - 4 - visibleWidth(prefix));
132
184
  return boxTextLine(width, `${prefix}${semanticTruncate(value, availableWidth, preserve)}`);
133
185
  }
@@ -185,15 +237,15 @@ function statusColor(value) {
185
237
  function todoSidebarLines(state, width) {
186
238
  if (!state || state.items.length === 0) {
187
239
  return [
188
- boxTextLine(width, `${theme.fg("muted", "todo:")} empty`),
189
- boxTextLine(width, `${theme.fg("muted", "next:")} no active todos`),
240
+ boxTextLine(width, `${labelCell("todo", RAIL_COLUMNS.todo)} ${theme.fg("dim", "empty")}`),
241
+ boxTextLine(width, `${labelCell("next", RAIL_COLUMNS.todo)} ${theme.fg("dim", "no active todos")}`),
190
242
  ];
191
243
  }
192
244
  const counts = todoSummary(state);
193
245
  const next = nextActiveTodo(state);
194
246
  return [
195
- boxTextLine(width, `${theme.fg("muted", "todo:")} ${counts.done}/${counts.total} done`),
196
- semanticBoxTextLine(width, "next", next?.label ?? "complete", "middle"),
247
+ boxTextLine(width, `${labelCell("todo", RAIL_COLUMNS.todo)} ${counts.done}/${counts.total} done`),
248
+ semanticBoxTextLine(width, "next", next?.label ?? "complete", "middle", RAIL_COLUMNS.todo),
197
249
  ];
198
250
  }
199
251
  function packageIntakeStatusLabel(summary) {
@@ -256,8 +308,11 @@ function activitySparklineLabel(snapshot) {
256
308
  const glyphs = Array.from(SPARKLINE_GLYPHS);
257
309
  const parts = [];
258
310
  for (let index = 0; index < SPARKLINE_WIDTH; index++) {
259
- const glyph = glyphs[(seed + index * 5 + index * index) % glyphs.length] ?? "▁";
260
- const color = index % 5 === 0 ? "accent" : index % 3 === 0 ? "warning" : "success";
311
+ const level = (seed + index * 5 + index * index) % glyphs.length;
312
+ const glyph = glyphs[level] ?? "";
313
+ // Colour follows amplitude instead of column index, so the pulse reads as
314
+ // one signal in the accent hue rather than a rotating three-colour pattern.
315
+ const color = level >= glyphs.length - 2 ? "accent" : level >= 3 ? "muted" : "dim";
261
316
  parts.push(theme.fg(color, glyph));
262
317
  }
263
318
  return parts.join("");
@@ -1 +1 @@
1
- {"version":3,"file":"control-panel-layout.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/control-panel-layout.ts"],"names":[],"mappings":"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","sourcesContent":["import { truncateToWidth, visibleWidth } from \"omk-tui\";\nimport type { PiPackageIntakeSummary } from \"../../../core/pi-package-intake.ts\";\nimport { nextActiveTodo, type TodoState, summary as todoSummary } from \"../../../core/todo-state.ts\";\nimport { type ThemeColor, theme } from \"../theme/theme.ts\";\nimport {\n\tboxBottom,\n\tboxCenteredLine,\n\tboxTextLine,\n\tboxTop,\n\tcenterLine,\n\tcomposeColumns,\n\tdivider,\n\tfitLine,\n\tsidebarRule,\n\ttextLine,\n} from \"./control-panel-box.ts\";\nimport { SPARKLE_ROW_BOTTOM, SPARKLE_ROW_TOP, sparkleRow } from \"./control-panel-sparkles.ts\";\n\nexport const CONTROL_PANEL_ASCII_ART = [\n\t\" ███████ ██ ██ ██ ██\",\n\t\"██ ██ ███ ███ ██ ██ \",\n\t\"██ ██ ████ ████ ██ ██ \",\n\t\"██ ██ ██ ██ ██ ██ █████ \",\n\t\"██ ██ ██ ███ ██ ██ ██ \",\n\t\"██ ██ ██ █ ██ ██ ██ \",\n\t\" ███████ ██ ██ ██ ██\",\n];\nconst META_WIDTH = 31;\nexport const CONTROL_PANEL_OVERLAY_MIN_WIDTH = 112;\nexport const CONTROL_PANEL_DECK_MIN_WIDTH = CONTROL_PANEL_OVERLAY_MIN_WIDTH + 1;\nexport const CONTROL_PANEL_SIDEBAR_WIDTH = 38;\nexport const CONTROL_PANEL_GAP_WIDTH = 2;\nconst CONTEXT_METER_CELLS = 12;\nconst SPARKLINE_WIDTH = 16;\nconst SPARKLINE_GLYPHS = \"▁▂▃▄▅▆▇█\";\n\nexport interface ControlPanelContent {\n\tappName: string;\n\tversion: string;\n\tcompactInstructions: () => string;\n\texpandedInstructions: () => string;\n\tcompactOnboarding: () => string;\n\tonboarding: () => string;\n\tstatusSnapshot?: () => ControlPanelStatusSnapshot;\n}\n\nexport interface ControlPanelStatusSnapshot {\n\treadonly modelId?: string;\n\treadonly modelProvider?: string;\n\treadonly thinkingLevel?: string;\n\treadonly contextPercent?: number | null;\n\treadonly contextWindowTokens?: number;\n\treadonly contextTokens?: number | null;\n\treadonly headroomStatus?: string;\n\treadonly optimizerPolicy?: string;\n\treadonly skillCount?: number;\n\treadonly mcpCount?: number;\n\treadonly packageIntake?: PiPackageIntakeSummary;\n\treadonly cwdLabel?: string;\n\treadonly gitBranch?: string | null;\n\treadonly todoState?: TodoState;\n\treadonly runtimeState?: string;\n\treadonly routeState?: string;\n\treadonly evidenceState?: string;\n\treadonly controlState?: string;\n\treadonly dagOrchestrationState?: string;\n\treadonly ansiColorState?: string;\n\treadonly startupState?: string;\n\treadonly linkState?: string;\n\treadonly sidebarState?: string;\n}\n\nexport function renderControlPanelLayout(\n\tcontent: ControlPanelContent,\n\texpanded: boolean,\n\twidth: number,\n\tbannerFrame?: string[],\n\tsparkleMs = 0,\n): string[] {\n\tif (width <= 0) return [];\n\treturn expanded\n\t\t? renderExpanded(content, width, bannerFrame, sparkleMs)\n\t\t: renderCompact(content, width, bannerFrame, sparkleMs);\n}\n\nexport function renderControlPanelRightPane(content: ControlPanelContent, width: number): string[] {\n\tif (width <= 0) return [];\n\treturn sidebarPanel(content, width);\n}\n\nfunction renderCompact(content: ControlPanelContent, width: number, bannerFrame?: string[], sparkleMs = 0): string[] {\n\tif (width >= CONTROL_PANEL_DECK_MIN_WIDTH) {\n\t\tconst deck = renderDeck(content, width, bannerFrame, sparkleMs);\n\t\tif (deck.length > 0) return deck;\n\t}\n\treturn [\n\t\tdivider(width, \"OMK//CONTROL PANEL\", \"accent\"),\n\t\tstatusLine(content, width),\n\t\ttextLine(width, content.compactInstructions()),\n\t\ttextLine(width, content.compactOnboarding(), \"dim\"),\n\t];\n}\n\nfunction renderDeck(content: ControlPanelContent, width: number, bannerFrame?: string[], sparkleMs = 0): string[] {\n\tconst { leftWidth, sidebarWidth } = deckWidths(width);\n\tif (leftWidth < 72) return [];\n\tconst lines = composeColumns(\n\t\theroPanel(content, leftWidth, bannerFrame, sparkleMs),\n\t\tleftWidth,\n\t\tsidebarPanel(content, sidebarWidth),\n\t\tsidebarWidth,\n\t\tCONTROL_PANEL_GAP_WIDTH,\n\t\twidth,\n\t);\n\tlines.push(controlStripLine(content, width));\n\tlines.push(centerLine(width, content.compactOnboarding(), \"dim\"));\n\treturn lines;\n}\n\nfunction deckWidths(width: number): { leftWidth: number; sidebarWidth: number } {\n\tconst sidebarWidth = Math.min(CONTROL_PANEL_SIDEBAR_WIDTH, Math.max(34, Math.floor(width * 0.28)));\n\treturn { leftWidth: width - CONTROL_PANEL_GAP_WIDTH - sidebarWidth, sidebarWidth };\n}\n\nfunction heroPanel(content: ControlPanelContent, width: number, bannerFrame?: string[], sparkleMs = 0): string[] {\n\tconst snapshot = statusSnapshot(content);\n\tconst innerWidth = Math.max(0, width - 4);\n\treturn [\n\t\tboxTop(width, `omk v${content.version} · OMK://CONTROL`),\n\t\tboxCenteredLine(width, theme.bold(theme.fg(\"accent\", \"OMK\"))),\n\t\tboxCenteredLine(width, theme.fg(\"muted\", \"route · verify · loop · control\")),\n\t\tboxTextLine(width, sparkleRow(innerWidth, SPARKLE_ROW_TOP, sparkleMs)),\n\t\t...(bannerFrame ?? CONTROL_PANEL_ASCII_ART).map((line, index) => {\n\t\t\tif (bannerFrame) return boxCenteredLine(width, line);\n\t\t\tconst color: ThemeColor = index < 2 ? \"mdCode\" : index < 4 ? \"accent\" : index < 6 ? \"success\" : \"warning\";\n\t\t\treturn boxCenteredLine(width, theme.fg(color, line));\n\t\t}),\n\t\tboxTextLine(width, sparkleRow(innerWidth, SPARKLE_ROW_BOTTOM, sparkleMs)),\n\t\tboxCenteredLine(\n\t\t\twidth,\n\t\t\t`${theme.fg(\"warning\", \"●\")} ${theme.bold(\"OMK\")} / ${theme.fg(\"success\", heroModelLabel(snapshot))}`,\n\t\t),\n\t\tboxCenteredLine(\n\t\t\twidth,\n\t\t\t`${theme.fg(\"mdCode\", \"◇\")} omk-control · ${theme.fg(\"accent\", \"route\")} · ${theme.fg(\"warning\", \"verify\")} · ${theme.fg(\"success\", \"loop\")} · ${theme.fg(\"mdCode\", \"control\")}`,\n\t\t),\n\t\tboxBottom(width),\n\t];\n}\n\nfunction heroModelLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tif (!snapshot.modelId) return \"no-model\";\n\tconst think = snapshot.thinkingLevel;\n\treturn think && think !== \"off\" ? `${snapshot.modelId}:${think}` : snapshot.modelId;\n}\n\nfunction sidebarPanel(content: ControlPanelContent, width: number): string[] {\n\tconst snapshot = statusSnapshot(content);\n\tconst headroomLabel = snapshot.headroomStatus ?? snapshot.optimizerPolicy ?? \"unknown\";\n\tconst mcpCount = snapshot.mcpCount;\n\tconst skillCount = snapshot.skillCount;\n\tconst packageIntakeLabel = packageIntakeStatusLabel(snapshot.packageIntake);\n\tconst contextMeter = contextMeterLabel(snapshot);\n\tconst activitySparkline = activitySparklineLabel(snapshot);\n\treturn [\n\t\tsidebarTabs(width),\n\t\tboxCenteredLine(width, theme.bold(theme.fg(\"accent\", \"OMK://CONTROL\"))),\n\t\tboxCenteredLine(width, theme.bold(theme.fg(\"warning\", \"CYBERPUNK OPS CORE\"))),\n\t\tboxCenteredLine(width, `${theme.fg(\"mdCode\", \"MATRIX RAIN\")} // ${theme.fg(\"success\", \"NEON GRID ONLINE\")}`),\n\t\tboxCenteredLine(width, theme.fg(\"text\", \"NIGHT-CITY-MATRIX-V3\")),\n\t\tsidebarRule(width, \"STATUS\", \"accent\"),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"state:\")} ${coloredStatus(snapshot.runtimeState ?? \"unknown\")}`),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"route:\")} ${coloredStatus(snapshot.routeState ?? \"unknown\")}`),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"evidence:\")} ${coloredStatus(snapshot.evidenceState ?? \"unknown\")}`),\n\t\tsidebarRule(width, \"TODO\", \"accent\"),\n\t\t...todoSidebarLines(snapshot.todoState, width),\n\t\tsidebarRule(width, \"SESSION\", \"accent\"),\n\t\tsemanticBoxTextLine(width, \"cwd\", snapshot.cwdLabel ?? \"?\", \"end\"),\n\t\tsemanticBoxTextLine(width, \"git\", snapshot.gitBranch ?? \"?\", \"start\"),\n\t\tsidebarRule(width, \"MODEL / CTX\", \"accent\"),\n\t\tsemanticBoxTextLine(width, \"model\", modelStatusLabel(snapshot), \"end\"),\n\t\tsemanticBoxTextLine(width, \"think\", snapshot.thinkingLevel ?? \"off\", \"start\"),\n\t\tboxTextLine(\n\t\t\twidth,\n\t\t\t`${theme.fg(\"muted\", \"ctx:\")} ${theme.fg(statusColor(snapshot.contextPercent === undefined || snapshot.contextPercent === null ? \"unknown\" : \"ready\"), contextStatusLabel(snapshot))}`,\n\t\t),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"meter:\")} ${contextMeter}`),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"pulse:\")} ${activitySparkline}`),\n\t\tsidebarRule(width, \"RUNTIME / MCP / SKILLS\", \"accent\"),\n\t\tsemanticBoxTextLine(width, \"headroom\", headroomLabel, \"end\"),\n\t\tsemanticBoxTextLine(width, \"omk\", snapshot.dagOrchestrationState ?? \"unknown\", \"end\"),\n\t\tsemanticBoxTextLine(width, \"sidebar\", snapshot.sidebarState ?? \"unknown\", \"start\"),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"res:\")} MCP:${mcpCount ?? \"?\"} skills:${skillCount ?? \"?\"}`),\n\t\tsemanticBoxTextLine(width, \"pkg\", packageIntakeLabel, \"end\"),\n\t\tsidebarRule(width, \"CONTROL\", \"accent\"),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"route:\")} ${coloredStatus(snapshot.routeState ?? \"unknown\")}`),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"verify:\")} ${coloredStatus(snapshot.evidenceState ?? \"unknown\")}`),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"control:\")} ${coloredStatus(snapshot.controlState ?? \"unknown\")}`),\n\t\tboxBottom(width, \"accent\"),\n\t];\n}\n\nfunction semanticBoxTextLine(\n\twidth: number,\n\tlabel: string,\n\tvalue: string,\n\tpreserve: \"start\" | \"middle\" | \"end\",\n): string {\n\tconst prefix = `${theme.fg(\"muted\", `${label}:`)} `;\n\tconst availableWidth = Math.max(0, width - 4 - visibleWidth(prefix));\n\treturn boxTextLine(width, `${prefix}${semanticTruncate(value, availableWidth, preserve)}`);\n}\n\nfunction semanticTruncate(value: string, maxWidth: number, preserve: \"start\" | \"middle\" | \"end\"): string {\n\tif (visibleWidth(value) <= maxWidth) return value;\n\tif (maxWidth <= 0) return \"\";\n\tif (preserve === \"start\") return truncateToWidth(value, maxWidth, \"…\");\n\tconst ellipsis = \"…\";\n\tconst targetWidth = maxWidth - visibleWidth(ellipsis);\n\tif (targetWidth <= 0) return truncateToWidth(ellipsis, maxWidth, \"\");\n\tif (preserve === \"middle\") {\n\t\tconst headWidth = Math.max(1, Math.floor(targetWidth / 2));\n\t\tconst tailWidth = Math.max(1, targetWidth - headWidth);\n\t\treturn `${takeStart(value, headWidth)}${ellipsis}${takeEnd(value, tailWidth)}`;\n\t}\n\treturn `${ellipsis}${takeEnd(value, targetWidth)}`;\n}\n\nfunction takeStart(value: string, maxWidth: number): string {\n\tlet prefix = \"\";\n\tfor (const char of Array.from(value)) {\n\t\tif (visibleWidth(prefix + char) > maxWidth) break;\n\t\tprefix += char;\n\t}\n\treturn prefix;\n}\n\nfunction takeEnd(value: string, maxWidth: number): string {\n\tlet suffix = \"\";\n\tfor (const char of Array.from(value).reverse()) {\n\t\tif (visibleWidth(char + suffix) > maxWidth) break;\n\t\tsuffix = char + suffix;\n\t}\n\treturn suffix;\n}\n\nfunction statusToken(label: string, value: string | undefined): string {\n\tconst state = value ?? \"unknown\";\n\treturn theme.fg(statusColor(state), `${label}:${state.toUpperCase()}`);\n}\n\nfunction coloredStatus(value: string): string {\n\treturn theme.fg(statusColor(value), value);\n}\n\nfunction statusColor(value: string): ThemeColor {\n\tconst normalized = value.toLowerCase();\n\tif ([\"ready\", \"on\", \"active\", \"available\", \"linked\", \"tracking\", \"pinned\"].includes(normalized)) return \"success\";\n\tif ([\"degraded\", \"limited\", \"blocked\", \"off\"].includes(normalized)) return \"warning\";\n\treturn \"muted\";\n}\n\nfunction todoSidebarLines(state: TodoState | undefined, width: number): string[] {\n\tif (!state || state.items.length === 0) {\n\t\treturn [\n\t\t\tboxTextLine(width, `${theme.fg(\"muted\", \"todo:\")} empty`),\n\t\t\tboxTextLine(width, `${theme.fg(\"muted\", \"next:\")} no active todos`),\n\t\t];\n\t}\n\tconst counts = todoSummary(state);\n\tconst next = nextActiveTodo(state);\n\treturn [\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"todo:\")} ${counts.done}/${counts.total} done`),\n\t\tsemanticBoxTextLine(width, \"next\", next?.label ?? \"complete\", \"middle\"),\n\t];\n}\n\nfunction packageIntakeStatusLabel(summary: PiPackageIntakeSummary | undefined): string {\n\tif (!summary) return \"ports:pending\";\n\tconst ready =\n\t\tsummary.acceptedNative + summary.acceptedReference + summary.acceptedMeasurement + summary.acceptedAdvisory;\n\tconst review = summary.deferred + summary.reject;\n\treturn `ports:${ready}/${summary.total} review:${review} block:${summary.hardForkBlocked}`;\n}\n\nfunction renderExpanded(content: ControlPanelContent, width: number, bannerFrame?: string[], sparkleMs = 0): string[] {\n\tif (width >= CONTROL_PANEL_DECK_MIN_WIDTH) {\n\t\tconst { leftWidth, sidebarWidth } = deckWidths(width);\n\t\tconst resourceLines = [\"\", ...content.onboarding().split(\"\\n\")];\n\t\tconst rightRail = blankSidebarRail(sidebarWidth, resourceLines.length);\n\t\tconst lines = [...renderDeck(content, width, bannerFrame, sparkleMs)];\n\t\tlines.push(...composeColumns(resourceLines, leftWidth, rightRail, sidebarWidth, CONTROL_PANEL_GAP_WIDTH, width));\n\t\treturn lines;\n\t}\n\n\tconst lines = [divider(width, \"OMK//CONTROL PANEL\", \"accent\"), statusLine(content, width)];\n\tif (width >= 32) lines.push(...brandLines(content, width, bannerFrame));\n\tlines.push(divider(width, \"SYSTEM MAP\", \"mdHeading\"));\n\tfor (const instruction of content.expandedInstructions().split(\"\\n\")) lines.push(textLine(width, instruction));\n\tlines.push(divider(width, \"STARTUP LINK\", \"success\"));\n\tfor (const onboardingLine of content.onboarding().split(\"\\n\")) lines.push(textLine(width, onboardingLine, \"dim\"));\n\tlines.push(divider(width, \"END\", \"borderMuted\"));\n\treturn lines;\n}\n\nfunction blankSidebarRail(width: number, lineCount: number): string[] {\n\treturn Array.from({ length: lineCount }, () => boxTextLine(width, \"\"));\n}\n\nfunction statusSnapshot(content: ControlPanelContent): ControlPanelStatusSnapshot {\n\treturn content.statusSnapshot?.() ?? {};\n}\n\nfunction modelStatusLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tif (!snapshot.modelId) return \"no-model\";\n\treturn snapshot.modelProvider ? `${snapshot.modelProvider}/${snapshot.modelId}` : snapshot.modelId;\n}\n\nfunction contextStatusLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tconst windowTokens = snapshot.contextWindowTokens ?? 0;\n\tconst windowLabel = windowTokens > 0 ? formatTokens(windowTokens) : \"?\";\n\treturn snapshot.contextPercent === null || snapshot.contextPercent === undefined\n\t\t? `?/${windowLabel}`\n\t\t: `${snapshot.contextPercent.toFixed(1)}%/${windowLabel}`;\n}\n\nfunction contextMeterLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tconst percent = normalizePercent(snapshot.contextPercent);\n\tif (percent === undefined) {\n\t\treturn `${theme.fg(\"borderMuted\", \"░\".repeat(CONTEXT_METER_CELLS))} ${theme.fg(\"muted\", \"??%\")}`;\n\t}\n\tconst filled = Math.max(0, Math.min(CONTEXT_METER_CELLS, Math.round((percent / 100) * CONTEXT_METER_CELLS)));\n\tconst color: ThemeColor = percent >= 85 ? \"warning\" : percent >= 65 ? \"mdCode\" : \"success\";\n\treturn `${theme.fg(color, \"█\".repeat(filled))}${theme.fg(\"borderMuted\", \"░\".repeat(CONTEXT_METER_CELLS - filled))} ${theme.fg(color, `${Math.round(percent)}%`)}`;\n}\n\nfunction activitySparklineLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tconst seed = hashSnapshot(snapshot);\n\tconst glyphs = Array.from(SPARKLINE_GLYPHS);\n\tconst parts: string[] = [];\n\tfor (let index = 0; index < SPARKLINE_WIDTH; index++) {\n\t\tconst glyph = glyphs[(seed + index * 5 + index * index) % glyphs.length] ?? \"▁\";\n\t\tconst color: ThemeColor = index % 5 === 0 ? \"accent\" : index % 3 === 0 ? \"warning\" : \"success\";\n\t\tparts.push(theme.fg(color, glyph));\n\t}\n\treturn parts.join(\"\");\n}\n\nfunction normalizePercent(value: number | null | undefined): number | undefined {\n\tif (value === null || value === undefined || !Number.isFinite(value)) return undefined;\n\tif (value < 0) return 0;\n\tif (value > 100) return 100;\n\treturn value;\n}\n\nfunction hashSnapshot(snapshot: ControlPanelStatusSnapshot): number {\n\tconst source = [\n\t\tsnapshot.modelProvider,\n\t\tsnapshot.modelId,\n\t\tsnapshot.contextPercent?.toFixed(1),\n\t\tsnapshot.contextTokens,\n\t\tsnapshot.contextWindowTokens,\n\t\tsnapshot.cwdLabel,\n\t\tsnapshot.gitBranch,\n\t].join(\"|\");\n\tlet hash = 2166136261;\n\tfor (let index = 0; index < source.length; index++) {\n\t\thash ^= source.charCodeAt(index);\n\t\thash = Math.imul(hash, 16777619);\n\t}\n\treturn hash >>> 0;\n}\n\nfunction formatTokens(count: number): string {\n\tif (count < 1000) return count.toString();\n\tif (count < 10000) return `${(count / 1000).toFixed(1)}k`;\n\tif (count < 1000000) return `${Math.round(count / 1000)}k`;\n\tif (count < 10000000) return `${(count / 1000000).toFixed(1)}M`;\n\treturn `${Math.round(count / 1000000)}M`;\n}\n\nfunction sidebarTabs(width: number): string {\n\treturn boxTextLine(\n\t\twidth,\n\t\tfitLine(\n\t\t\t`${theme.bold(theme.fg(\"accent\", \"1:CONTROL\"))} ${theme.fg(\"muted\", \"2:HISTORY\")}`,\n\t\t\tMath.max(0, width - 4),\n\t\t),\n\t);\n}\n\nfunction controlStripLine(content: ControlPanelContent, width: number): string {\n\treturn centerLine(\n\t\twidth,\n\t\t`${theme.bold(theme.fg(\"accent\", \"OMK://CONTROL READ\"))} ${theme.fg(\"accent\", \"route/verify/loop/control\")} · ${content.compactInstructions()}`,\n\t);\n}\n\nfunction brandLines(content: ControlPanelContent, width: number, bannerFrame?: string[]): string[] {\n\tconst art = bannerFrame ?? CONTROL_PANEL_ASCII_ART;\n\tif (bannerFrame) return art.map((line) => textLine(width, line));\n\tconst leftWidth = Math.max(...art.map((line) => visibleWidth(line)));\n\tconst minWideWidth = visibleWidth(\"| \") + leftWidth + visibleWidth(\" | \") + META_WIDTH;\n\tif (width < minWideWidth) return art.map((line) => textLine(width, theme.fg(\"accent\", line)));\n\tconst snapshot = statusSnapshot(content);\n\treturn art.map((line, index) =>\n\t\ttextLine(\n\t\t\twidth,\n\t\t\t`${fitLine(theme.fg(\"accent\", line), leftWidth)}${theme.fg(\"borderMuted\", \" | \")}${metadataLines(snapshot)[index] ?? \"\"}`,\n\t\t),\n\t);\n}\n\nfunction metadataLines(snapshot: ControlPanelStatusSnapshot): string[] {\n\tconst rawThemeName = theme.name ?? \"live\";\n\tconst themeName = (rawThemeName.startsWith(\"omk-\") ? rawThemeName.slice(4) : rawThemeName).toUpperCase();\n\treturn [\n\t\t`${theme.fg(\"mdCode\", \"PANEL\")} ${coloredStatus(snapshot.runtimeState ?? \"unknown\")}`,\n\t\t`${theme.fg(\"mdCode\", \"THEME\")} ${theme.fg(\"accent\", themeName)}`,\n\t\t`${theme.fg(\"mdCode\", \"STARTUP\")} ${coloredStatus(snapshot.startupState ?? \"unknown\")}`,\n\t\t`${theme.fg(\"mdCode\", \"LINK\")} ${coloredStatus(snapshot.linkState ?? \"unknown\")}`,\n\t];\n}\n\nfunction statusLine(content: ControlPanelContent, width: number): string {\n\tconst snapshot = statusSnapshot(content);\n\tconst segments = [\n\t\ttheme.bold(theme.fg(\"accent\", `${content.appName.toUpperCase()} v${content.version}`)),\n\t\tstatusToken(\"CORE\", snapshot.runtimeState),\n\t\tstatusToken(\"ANSI\", snapshot.ansiColorState),\n\t\tstatusToken(\"STARTUP\", snapshot.startupState),\n\t\tstatusToken(\"LINK\", snapshot.linkState),\n\t\ttheme.fg(\"muted\", \"THEME:LIVE\"),\n\t];\n\treturn textLine(width, segments.join(theme.fg(\"borderMuted\", \" | \")));\n}\n"]}
1
+ {"version":3,"file":"control-panel-layout.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/control-panel-layout.ts"],"names":[],"mappings":"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","sourcesContent":["import { truncateToWidth, visibleWidth } from \"omk-tui\";\nimport type { PiPackageIntakeSummary } from \"../../../core/pi-package-intake.ts\";\nimport { nextActiveTodo, type TodoState, summary as todoSummary } from \"../../../core/todo-state.ts\";\nimport { type ThemeColor, theme } from \"../theme/theme.ts\";\nimport {\n\tboxBottom,\n\tboxCenteredLine,\n\tboxRuleLine,\n\tboxTextLine,\n\tboxTop,\n\tcenterLine,\n\tcomposeColumns,\n\tdivider,\n\tfitLine,\n\tlabelCell,\n\tpadBoxColumn,\n\tsidebarRule,\n\ttextLine,\n} from \"./control-panel-box.ts\";\nimport { SPARKLE_ROW_BOTTOM, SPARKLE_ROW_TOP, sparkleRow } from \"./control-panel-sparkles.ts\";\n\nexport const CONTROL_PANEL_ASCII_ART = [\n\t\" ███████ ██ ██ ██ ██\",\n\t\"██ ██ ███ ███ ██ ██ \",\n\t\"██ ██ ████ ████ ██ ██ \",\n\t\"██ ██ ██ ██ ██ ██ █████ \",\n\t\"██ ██ ██ ███ ██ ██ ██ \",\n\t\"██ ██ ██ █ ██ ██ ██ \",\n\t\" ███████ ██ ██ ██ ██\",\n];\nconst META_WIDTH = 31;\nexport const CONTROL_PANEL_OVERLAY_MIN_WIDTH = 112;\nexport const CONTROL_PANEL_DECK_MIN_WIDTH = CONTROL_PANEL_OVERLAY_MIN_WIDTH + 1;\nexport const CONTROL_PANEL_SIDEBAR_WIDTH = 38;\nexport const CONTROL_PANEL_GAP_WIDTH = 2;\nconst CONTEXT_METER_CELLS = 12;\nconst SPARKLINE_WIDTH = 16;\nconst SPARKLINE_GLYPHS = \"▁▂▃▄▅▆▇█\";\n\nexport interface ControlPanelContent {\n\tappName: string;\n\tversion: string;\n\tcompactInstructions: () => string;\n\texpandedInstructions: () => string;\n\tcompactOnboarding: () => string;\n\tonboarding: () => string;\n\tstatusSnapshot?: () => ControlPanelStatusSnapshot;\n}\n\nexport interface ControlPanelStatusSnapshot {\n\treadonly modelId?: string;\n\treadonly modelProvider?: string;\n\treadonly thinkingLevel?: string;\n\treadonly contextPercent?: number | null;\n\treadonly contextWindowTokens?: number;\n\treadonly contextTokens?: number | null;\n\treadonly headroomStatus?: string;\n\treadonly optimizerPolicy?: string;\n\treadonly skillCount?: number;\n\treadonly mcpCount?: number;\n\treadonly packageIntake?: PiPackageIntakeSummary;\n\treadonly cwdLabel?: string;\n\treadonly gitBranch?: string | null;\n\treadonly todoState?: TodoState;\n\treadonly runtimeState?: string;\n\treadonly routeState?: string;\n\treadonly evidenceState?: string;\n\treadonly controlState?: string;\n\treadonly dagOrchestrationState?: string;\n\treadonly ansiColorState?: string;\n\treadonly startupState?: string;\n\treadonly linkState?: string;\n\treadonly sidebarState?: string;\n}\n\nexport function renderControlPanelLayout(\n\tcontent: ControlPanelContent,\n\texpanded: boolean,\n\twidth: number,\n\tbannerFrame?: string[],\n\tsparkleMs = 0,\n): string[] {\n\tif (width <= 0) return [];\n\treturn expanded\n\t\t? renderExpanded(content, width, bannerFrame, sparkleMs)\n\t\t: renderCompact(content, width, bannerFrame, sparkleMs);\n}\n\nexport function renderControlPanelRightPane(content: ControlPanelContent, width: number): string[] {\n\tif (width <= 0) return [];\n\treturn sidebarPanel(content, width);\n}\n\nfunction renderCompact(content: ControlPanelContent, width: number, bannerFrame?: string[], sparkleMs = 0): string[] {\n\tif (width >= CONTROL_PANEL_DECK_MIN_WIDTH) {\n\t\tconst deck = renderDeck(content, width, bannerFrame, sparkleMs);\n\t\tif (deck.length > 0) return deck;\n\t}\n\treturn [\n\t\tdivider(width, \"OMK//CONTROL PANEL\", \"accent\"),\n\t\tstatusLine(content, width),\n\t\ttextLine(width, content.compactInstructions()),\n\t\ttextLine(width, content.compactOnboarding(), \"dim\"),\n\t];\n}\n\nfunction renderDeck(content: ControlPanelContent, width: number, bannerFrame?: string[], sparkleMs = 0): string[] {\n\tconst { leftWidth, sidebarWidth } = deckWidths(width);\n\tif (leftWidth < 72) return [];\n\tconst hero = heroPanel(content, leftWidth, bannerFrame, sparkleMs);\n\tconst rail = sidebarPanel(content, sidebarWidth);\n\t// Both framed columns close on the same row so the deck reads as one block\n\t// instead of a short hero beside a long ragged rail.\n\tconst deckHeight = Math.max(hero.length, rail.length);\n\tconst lines = composeColumns(\n\t\tpadBoxColumn(hero, deckHeight, leftWidth, \"center\"),\n\t\tleftWidth,\n\t\tpadBoxColumn(rail, deckHeight, sidebarWidth),\n\t\tsidebarWidth,\n\t\tCONTROL_PANEL_GAP_WIDTH,\n\t\twidth,\n\t);\n\tlines.push(controlStripLine(content, width));\n\tlines.push(centerLine(width, content.compactOnboarding(), \"dim\"));\n\treturn lines;\n}\n\nfunction deckWidths(width: number): { leftWidth: number; sidebarWidth: number } {\n\tconst sidebarWidth = Math.min(CONTROL_PANEL_SIDEBAR_WIDTH, Math.max(34, Math.floor(width * 0.28)));\n\treturn { leftWidth: width - CONTROL_PANEL_GAP_WIDTH - sidebarWidth, sidebarWidth };\n}\n\nfunction heroPanel(content: ControlPanelContent, width: number, bannerFrame?: string[], sparkleMs = 0): string[] {\n\tconst snapshot = statusSnapshot(content);\n\tconst innerWidth = Math.max(0, width - 4);\n\treturn [\n\t\t// One wordmark only: the framed title chip carries the product name, so the\n\t\t// hero body is the block mark plus live state, not a second text logotype.\n\t\tboxTop(width, `omk v${content.version} · OMK://CONTROL`),\n\t\tboxTextLine(width, sparkleRow(innerWidth, SPARKLE_ROW_TOP, sparkleMs)),\n\t\t...(bannerFrame ?? CONTROL_PANEL_ASCII_ART).map((line, index, rows) => {\n\t\t\tif (bannerFrame) return boxCenteredLine(width, line);\n\t\t\t// Single-tone wordmark: the top and bottom scanlines fall back to the\n\t\t\t// dim ink so the mark reads as one lit object rather than a four-colour\n\t\t\t// stack. Accent stays the only hue in the hero.\n\t\t\tconst isEdge = index === 0 || index === rows.length - 1;\n\t\t\tconst isCore = index === Math.floor(rows.length / 2);\n\t\t\tconst painted = theme.fg(isEdge ? \"dim\" : \"accent\", line);\n\t\t\treturn boxCenteredLine(width, isCore ? theme.bold(painted) : painted);\n\t\t}),\n\t\tboxTextLine(width, sparkleRow(innerWidth, SPARKLE_ROW_BOTTOM, sparkleMs)),\n\t\tboxCenteredLine(\n\t\t\twidth,\n\t\t\t`${theme.fg(\"success\", \"●\")} ${theme.fg(\"muted\", \"MODEL\")} ${theme.fg(\"text\", heroModelLabel(snapshot))}`,\n\t\t),\n\t\tboxCenteredLine(\n\t\t\twidth,\n\t\t\t[\"route\", \"verify\", \"loop\", \"control\"]\n\t\t\t\t.map((stage) => theme.fg(\"dim\", stage))\n\t\t\t\t.join(theme.fg(\"borderMuted\", \" · \")),\n\t\t),\n\t\tboxTextLine(width, \"\"),\n\t\tboxRuleLine(width, Math.max(4, Math.floor(innerWidth * 0.18))),\n\t\tboxCenteredLine(width, heroMetaStrip(snapshot)),\n\t\tboxBottom(width),\n\t];\n}\n\n/**\n * Compact meta strip under the wordmark: the same signals the narrow layout\n * shows beside the banner, rendered as one centred row so the hero carries\n * real state instead of empty deck height.\n */\nfunction heroMetaStrip(snapshot: ControlPanelStatusSnapshot): string {\n\tconst rawThemeName = theme.name ?? \"live\";\n\tconst themeName = (rawThemeName.startsWith(\"omk-\") ? rawThemeName.slice(4) : rawThemeName).toUpperCase();\n\tconst cells: Array<[string, string]> = [\n\t\t[\"PANEL\", snapshot.runtimeState ?? \"unknown\"],\n\t\t[\"THEME\", themeName],\n\t\t[\"STARTUP\", snapshot.startupState ?? \"unknown\"],\n\t\t[\"LINK\", snapshot.linkState ?? \"unknown\"],\n\t];\n\treturn cells\n\t\t.map(([label, value]) => `${theme.fg(\"muted\", label)} ${coloredStatus(value)}`)\n\t\t.join(theme.fg(\"borderMuted\", \" · \"));\n}\n\nfunction heroModelLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tif (!snapshot.modelId) return \"no-model\";\n\tconst think = snapshot.thinkingLevel;\n\treturn think && think !== \"off\" ? `${snapshot.modelId}:${think}` : snapshot.modelId;\n}\n\n/**\n * Label gutters are aligned per section rather than across the whole rail: a\n * global gutter would indent short labels so far that long values (todo text,\n * model ids) lose characters at rail widths of 34-38 columns.\n */\nconst RAIL_COLUMNS = {\n\tstatus: 8,\n\ttodo: 4,\n\tsession: 3,\n\tmodel: 5,\n\truntime: 8,\n\tcontrol: 7,\n} as const;\n\nfunction sidebarPanel(content: ControlPanelContent, width: number): string[] {\n\tconst snapshot = statusSnapshot(content);\n\tconst headroomLabel = snapshot.headroomStatus ?? snapshot.optimizerPolicy ?? \"unknown\";\n\tconst mcpCount = snapshot.mcpCount;\n\tconst skillCount = snapshot.skillCount;\n\tconst packageIntakeLabel = packageIntakeStatusLabel(snapshot.packageIntake);\n\tconst contextMeter = contextMeterLabel(snapshot);\n\tconst activitySparkline = activitySparklineLabel(snapshot);\n\treturn [\n\t\tsidebarTabs(width),\n\t\tboxCenteredLine(width, theme.bold(theme.fg(\"accent\", \"OMK://CONTROL\"))),\n\t\tboxCenteredLine(width, theme.fg(\"dim\", \"CYBERPUNK OPS CORE\")),\n\t\tboxCenteredLine(\n\t\t\twidth,\n\t\t\t`${theme.fg(\"muted\", \"MATRIX RAIN\")}${theme.fg(\"borderMuted\", \" // \")}${theme.fg(\"muted\", \"NEON GRID ONLINE\")}`,\n\t\t),\n\t\tboxCenteredLine(width, theme.fg(\"dim\", \"NIGHT-CITY-MATRIX-V3\")),\n\t\tsidebarRule(width, \"STATUS\"),\n\t\tboxTextLine(\n\t\t\twidth,\n\t\t\t`${labelCell(\"state\", RAIL_COLUMNS.status)} ${coloredStatus(snapshot.runtimeState ?? \"unknown\")}`,\n\t\t),\n\t\tboxTextLine(\n\t\t\twidth,\n\t\t\t`${labelCell(\"route\", RAIL_COLUMNS.status)} ${coloredStatus(snapshot.routeState ?? \"unknown\")}`,\n\t\t),\n\t\tboxTextLine(\n\t\t\twidth,\n\t\t\t`${labelCell(\"evidence\", RAIL_COLUMNS.status)} ${coloredStatus(snapshot.evidenceState ?? \"unknown\")}`,\n\t\t),\n\t\tsidebarRule(width, \"TODO\"),\n\t\t...todoSidebarLines(snapshot.todoState, width),\n\t\tsidebarRule(width, \"SESSION\"),\n\t\tsemanticBoxTextLine(width, \"cwd\", snapshot.cwdLabel ?? \"?\", \"end\", RAIL_COLUMNS.session),\n\t\tsemanticBoxTextLine(width, \"git\", snapshot.gitBranch ?? \"?\", \"start\", RAIL_COLUMNS.session),\n\t\tsidebarRule(width, \"MODEL / CTX\"),\n\t\tsemanticBoxTextLine(width, \"model\", modelStatusLabel(snapshot), \"end\", RAIL_COLUMNS.model),\n\t\tsemanticBoxTextLine(width, \"think\", snapshot.thinkingLevel ?? \"off\", \"start\", RAIL_COLUMNS.model),\n\t\tboxTextLine(\n\t\t\twidth,\n\t\t\t`${labelCell(\"ctx\", RAIL_COLUMNS.model)} ${theme.fg(statusColor(snapshot.contextPercent === undefined || snapshot.contextPercent === null ? \"unknown\" : \"ready\"), contextStatusLabel(snapshot))}`,\n\t\t),\n\t\tboxTextLine(width, `${labelCell(\"meter\", RAIL_COLUMNS.model)} ${contextMeter}`),\n\t\tboxTextLine(width, `${labelCell(\"pulse\", RAIL_COLUMNS.model)} ${activitySparkline}`),\n\t\tsidebarRule(width, \"RUNTIME / MCP / SKILLS\"),\n\t\tsemanticBoxTextLine(width, \"headroom\", headroomLabel, \"end\", RAIL_COLUMNS.runtime),\n\t\tsemanticBoxTextLine(width, \"omk\", snapshot.dagOrchestrationState ?? \"unknown\", \"end\", RAIL_COLUMNS.runtime),\n\t\tsemanticBoxTextLine(width, \"sidebar\", snapshot.sidebarState ?? \"unknown\", \"start\", RAIL_COLUMNS.runtime),\n\t\tboxTextLine(\n\t\t\twidth,\n\t\t\t`${labelCell(\"res\", RAIL_COLUMNS.runtime)} MCP:${mcpCount ?? \"?\"} skills:${skillCount ?? \"?\"}`,\n\t\t),\n\t\tsemanticBoxTextLine(width, \"pkg\", packageIntakeLabel, \"end\", RAIL_COLUMNS.runtime),\n\t\t// CONTROL previously repeated STATUS's route row verbatim; the rail now\n\t\t// carries each signal exactly once.\n\t\tsidebarRule(width, \"CONTROL\"),\n\t\tboxTextLine(\n\t\t\twidth,\n\t\t\t`${labelCell(\"verify\", RAIL_COLUMNS.control)} ${coloredStatus(snapshot.evidenceState ?? \"unknown\")}`,\n\t\t),\n\t\tboxTextLine(\n\t\t\twidth,\n\t\t\t`${labelCell(\"control\", RAIL_COLUMNS.control)} ${coloredStatus(snapshot.controlState ?? \"unknown\")}`,\n\t\t),\n\t\tboxBottom(width),\n\t];\n}\n\nfunction semanticBoxTextLine(\n\twidth: number,\n\tlabel: string,\n\tvalue: string,\n\tpreserve: \"start\" | \"middle\" | \"end\",\n\tcolumn?: number,\n): string {\n\t// Alignment is a courtesy, not a cost: if the gutter indent would truncate the\n\t// value, this row drops back to a flush label so the data survives intact.\n\tconst aligned = `${labelCell(label, column)} `;\n\tconst flush = `${labelCell(label, label.length)} `;\n\tconst alignedRoom = Math.max(0, width - 4 - visibleWidth(aligned));\n\tconst prefix = visibleWidth(value) <= alignedRoom ? aligned : flush;\n\tconst availableWidth = Math.max(0, width - 4 - visibleWidth(prefix));\n\treturn boxTextLine(width, `${prefix}${semanticTruncate(value, availableWidth, preserve)}`);\n}\n\nfunction semanticTruncate(value: string, maxWidth: number, preserve: \"start\" | \"middle\" | \"end\"): string {\n\tif (visibleWidth(value) <= maxWidth) return value;\n\tif (maxWidth <= 0) return \"\";\n\tif (preserve === \"start\") return truncateToWidth(value, maxWidth, \"…\");\n\tconst ellipsis = \"…\";\n\tconst targetWidth = maxWidth - visibleWidth(ellipsis);\n\tif (targetWidth <= 0) return truncateToWidth(ellipsis, maxWidth, \"\");\n\tif (preserve === \"middle\") {\n\t\tconst headWidth = Math.max(1, Math.floor(targetWidth / 2));\n\t\tconst tailWidth = Math.max(1, targetWidth - headWidth);\n\t\treturn `${takeStart(value, headWidth)}${ellipsis}${takeEnd(value, tailWidth)}`;\n\t}\n\treturn `${ellipsis}${takeEnd(value, targetWidth)}`;\n}\n\nfunction takeStart(value: string, maxWidth: number): string {\n\tlet prefix = \"\";\n\tfor (const char of Array.from(value)) {\n\t\tif (visibleWidth(prefix + char) > maxWidth) break;\n\t\tprefix += char;\n\t}\n\treturn prefix;\n}\n\nfunction takeEnd(value: string, maxWidth: number): string {\n\tlet suffix = \"\";\n\tfor (const char of Array.from(value).reverse()) {\n\t\tif (visibleWidth(char + suffix) > maxWidth) break;\n\t\tsuffix = char + suffix;\n\t}\n\treturn suffix;\n}\n\nfunction statusToken(label: string, value: string | undefined): string {\n\tconst state = value ?? \"unknown\";\n\treturn theme.fg(statusColor(state), `${label}:${state.toUpperCase()}`);\n}\n\nfunction coloredStatus(value: string): string {\n\treturn theme.fg(statusColor(value), value);\n}\n\nfunction statusColor(value: string): ThemeColor {\n\tconst normalized = value.toLowerCase();\n\tif ([\"ready\", \"on\", \"active\", \"available\", \"linked\", \"tracking\", \"pinned\"].includes(normalized)) return \"success\";\n\tif ([\"degraded\", \"limited\", \"blocked\", \"off\"].includes(normalized)) return \"warning\";\n\treturn \"muted\";\n}\n\nfunction todoSidebarLines(state: TodoState | undefined, width: number): string[] {\n\tif (!state || state.items.length === 0) {\n\t\treturn [\n\t\t\tboxTextLine(width, `${labelCell(\"todo\", RAIL_COLUMNS.todo)} ${theme.fg(\"dim\", \"empty\")}`),\n\t\t\tboxTextLine(width, `${labelCell(\"next\", RAIL_COLUMNS.todo)} ${theme.fg(\"dim\", \"no active todos\")}`),\n\t\t];\n\t}\n\tconst counts = todoSummary(state);\n\tconst next = nextActiveTodo(state);\n\treturn [\n\t\tboxTextLine(width, `${labelCell(\"todo\", RAIL_COLUMNS.todo)} ${counts.done}/${counts.total} done`),\n\t\tsemanticBoxTextLine(width, \"next\", next?.label ?? \"complete\", \"middle\", RAIL_COLUMNS.todo),\n\t];\n}\n\nfunction packageIntakeStatusLabel(summary: PiPackageIntakeSummary | undefined): string {\n\tif (!summary) return \"ports:pending\";\n\tconst ready =\n\t\tsummary.acceptedNative + summary.acceptedReference + summary.acceptedMeasurement + summary.acceptedAdvisory;\n\tconst review = summary.deferred + summary.reject;\n\treturn `ports:${ready}/${summary.total} review:${review} block:${summary.hardForkBlocked}`;\n}\n\nfunction renderExpanded(content: ControlPanelContent, width: number, bannerFrame?: string[], sparkleMs = 0): string[] {\n\tif (width >= CONTROL_PANEL_DECK_MIN_WIDTH) {\n\t\tconst { leftWidth, sidebarWidth } = deckWidths(width);\n\t\tconst resourceLines = [\"\", ...content.onboarding().split(\"\\n\")];\n\t\tconst rightRail = blankSidebarRail(sidebarWidth, resourceLines.length);\n\t\tconst lines = [...renderDeck(content, width, bannerFrame, sparkleMs)];\n\t\tlines.push(...composeColumns(resourceLines, leftWidth, rightRail, sidebarWidth, CONTROL_PANEL_GAP_WIDTH, width));\n\t\treturn lines;\n\t}\n\n\tconst lines = [divider(width, \"OMK//CONTROL PANEL\", \"accent\"), statusLine(content, width)];\n\tif (width >= 32) lines.push(...brandLines(content, width, bannerFrame));\n\tlines.push(divider(width, \"SYSTEM MAP\", \"mdHeading\"));\n\tfor (const instruction of content.expandedInstructions().split(\"\\n\")) lines.push(textLine(width, instruction));\n\tlines.push(divider(width, \"STARTUP LINK\", \"success\"));\n\tfor (const onboardingLine of content.onboarding().split(\"\\n\")) lines.push(textLine(width, onboardingLine, \"dim\"));\n\tlines.push(divider(width, \"END\", \"borderMuted\"));\n\treturn lines;\n}\n\nfunction blankSidebarRail(width: number, lineCount: number): string[] {\n\treturn Array.from({ length: lineCount }, () => boxTextLine(width, \"\"));\n}\n\nfunction statusSnapshot(content: ControlPanelContent): ControlPanelStatusSnapshot {\n\treturn content.statusSnapshot?.() ?? {};\n}\n\nfunction modelStatusLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tif (!snapshot.modelId) return \"no-model\";\n\treturn snapshot.modelProvider ? `${snapshot.modelProvider}/${snapshot.modelId}` : snapshot.modelId;\n}\n\nfunction contextStatusLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tconst windowTokens = snapshot.contextWindowTokens ?? 0;\n\tconst windowLabel = windowTokens > 0 ? formatTokens(windowTokens) : \"?\";\n\treturn snapshot.contextPercent === null || snapshot.contextPercent === undefined\n\t\t? `?/${windowLabel}`\n\t\t: `${snapshot.contextPercent.toFixed(1)}%/${windowLabel}`;\n}\n\nfunction contextMeterLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tconst percent = normalizePercent(snapshot.contextPercent);\n\tif (percent === undefined) {\n\t\treturn `${theme.fg(\"borderMuted\", \"░\".repeat(CONTEXT_METER_CELLS))} ${theme.fg(\"muted\", \"??%\")}`;\n\t}\n\tconst filled = Math.max(0, Math.min(CONTEXT_METER_CELLS, Math.round((percent / 100) * CONTEXT_METER_CELLS)));\n\tconst color: ThemeColor = percent >= 85 ? \"warning\" : percent >= 65 ? \"mdCode\" : \"success\";\n\treturn `${theme.fg(color, \"█\".repeat(filled))}${theme.fg(\"borderMuted\", \"░\".repeat(CONTEXT_METER_CELLS - filled))} ${theme.fg(color, `${Math.round(percent)}%`)}`;\n}\n\nfunction activitySparklineLabel(snapshot: ControlPanelStatusSnapshot): string {\n\tconst seed = hashSnapshot(snapshot);\n\tconst glyphs = Array.from(SPARKLINE_GLYPHS);\n\tconst parts: string[] = [];\n\tfor (let index = 0; index < SPARKLINE_WIDTH; index++) {\n\t\tconst level = (seed + index * 5 + index * index) % glyphs.length;\n\t\tconst glyph = glyphs[level] ?? \"▁\";\n\t\t// Colour follows amplitude instead of column index, so the pulse reads as\n\t\t// one signal in the accent hue rather than a rotating three-colour pattern.\n\t\tconst color: ThemeColor = level >= glyphs.length - 2 ? \"accent\" : level >= 3 ? \"muted\" : \"dim\";\n\t\tparts.push(theme.fg(color, glyph));\n\t}\n\treturn parts.join(\"\");\n}\n\nfunction normalizePercent(value: number | null | undefined): number | undefined {\n\tif (value === null || value === undefined || !Number.isFinite(value)) return undefined;\n\tif (value < 0) return 0;\n\tif (value > 100) return 100;\n\treturn value;\n}\n\nfunction hashSnapshot(snapshot: ControlPanelStatusSnapshot): number {\n\tconst source = [\n\t\tsnapshot.modelProvider,\n\t\tsnapshot.modelId,\n\t\tsnapshot.contextPercent?.toFixed(1),\n\t\tsnapshot.contextTokens,\n\t\tsnapshot.contextWindowTokens,\n\t\tsnapshot.cwdLabel,\n\t\tsnapshot.gitBranch,\n\t].join(\"|\");\n\tlet hash = 2166136261;\n\tfor (let index = 0; index < source.length; index++) {\n\t\thash ^= source.charCodeAt(index);\n\t\thash = Math.imul(hash, 16777619);\n\t}\n\treturn hash >>> 0;\n}\n\nfunction formatTokens(count: number): string {\n\tif (count < 1000) return count.toString();\n\tif (count < 10000) return `${(count / 1000).toFixed(1)}k`;\n\tif (count < 1000000) return `${Math.round(count / 1000)}k`;\n\tif (count < 10000000) return `${(count / 1000000).toFixed(1)}M`;\n\treturn `${Math.round(count / 1000000)}M`;\n}\n\nfunction sidebarTabs(width: number): string {\n\treturn boxTextLine(\n\t\twidth,\n\t\tfitLine(\n\t\t\t`${theme.bold(theme.fg(\"accent\", \"1:CONTROL\"))} ${theme.fg(\"muted\", \"2:HISTORY\")}`,\n\t\t\tMath.max(0, width - 4),\n\t\t),\n\t);\n}\n\nfunction controlStripLine(content: ControlPanelContent, width: number): string {\n\treturn centerLine(\n\t\twidth,\n\t\t`${theme.bold(theme.fg(\"accent\", \"OMK://CONTROL READ\"))} ${theme.fg(\"accent\", \"route/verify/loop/control\")} · ${content.compactInstructions()}`,\n\t);\n}\n\nfunction brandLines(content: ControlPanelContent, width: number, bannerFrame?: string[]): string[] {\n\tconst art = bannerFrame ?? CONTROL_PANEL_ASCII_ART;\n\tif (bannerFrame) return art.map((line) => textLine(width, line));\n\tconst leftWidth = Math.max(...art.map((line) => visibleWidth(line)));\n\tconst minWideWidth = visibleWidth(\"| \") + leftWidth + visibleWidth(\" | \") + META_WIDTH;\n\tif (width < minWideWidth) return art.map((line) => textLine(width, theme.fg(\"accent\", line)));\n\tconst snapshot = statusSnapshot(content);\n\treturn art.map((line, index) =>\n\t\ttextLine(\n\t\t\twidth,\n\t\t\t`${fitLine(theme.fg(\"accent\", line), leftWidth)}${theme.fg(\"borderMuted\", \" | \")}${metadataLines(snapshot)[index] ?? \"\"}`,\n\t\t),\n\t);\n}\n\nfunction metadataLines(snapshot: ControlPanelStatusSnapshot): string[] {\n\tconst rawThemeName = theme.name ?? \"live\";\n\tconst themeName = (rawThemeName.startsWith(\"omk-\") ? rawThemeName.slice(4) : rawThemeName).toUpperCase();\n\treturn [\n\t\t`${theme.fg(\"mdCode\", \"PANEL\")} ${coloredStatus(snapshot.runtimeState ?? \"unknown\")}`,\n\t\t`${theme.fg(\"mdCode\", \"THEME\")} ${theme.fg(\"accent\", themeName)}`,\n\t\t`${theme.fg(\"mdCode\", \"STARTUP\")} ${coloredStatus(snapshot.startupState ?? \"unknown\")}`,\n\t\t`${theme.fg(\"mdCode\", \"LINK\")} ${coloredStatus(snapshot.linkState ?? \"unknown\")}`,\n\t];\n}\n\nfunction statusLine(content: ControlPanelContent, width: number): string {\n\tconst snapshot = statusSnapshot(content);\n\tconst segments = [\n\t\ttheme.bold(theme.fg(\"accent\", `${content.appName.toUpperCase()} v${content.version}`)),\n\t\tstatusToken(\"CORE\", snapshot.runtimeState),\n\t\tstatusToken(\"ANSI\", snapshot.ansiColorState),\n\t\tstatusToken(\"STARTUP\", snapshot.startupState),\n\t\tstatusToken(\"LINK\", snapshot.linkState),\n\t\ttheme.fg(\"muted\", \"THEME:LIVE\"),\n\t];\n\treturn textLine(width, segments.join(theme.fg(\"borderMuted\", \" | \")));\n}\n"]}
@@ -15,6 +15,15 @@ export declare function countRoutableNonHubSkills(skills: readonly {
15
15
  readonly name: string;
16
16
  }[]): number;
17
17
  export declare function countStableMcpServers(entries: readonly McpStabilityInput[]): number;
18
+ /**
19
+ * Classify a single MCP server entry for status display.
20
+ *
21
+ * - `stable`: configured, healthy, and safe to surface as an active server.
22
+ * - `overridden`: a higher-precedence source replaced this entry.
23
+ * - `unstable`: malformed, privileged, or blocked by an auth/network policy.
24
+ */
25
+ export type McpStability = "stable" | "overridden" | "unstable";
26
+ export declare function classifyMcpStability(entry: McpStabilityInput): McpStability;
18
27
  export declare function parseHeadroomVersionOutput(output: string): string | null;
19
28
  export declare function createControlPanelStatusSnapshot(session: AgentSession, sessionManager: SessionManager, footerData?: ReadonlyFooterDataProvider): ControlPanelStatusSnapshot;
20
29
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"control-panel-runtime-status.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/control-panel-runtime-status.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAEnE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AACxF,OAAO,EAAoB,KAAK,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAEvF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAEvE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AA0B5E,UAAU,iBAAiB;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,eAAe,EAAE,IAAI,CAAC,cAAc,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC,CAAC;IAC1E,QAAQ,CAAC,kBAAkB,EAAE,IAAI,CAAC,cAAc,CAAC,oBAAoB,CAAC,EAAE,WAAW,GAAG,qBAAqB,CAAC,CAAC;IAC7G,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC;CACpE;AAED,wBAAgB,yBAAyB,IAAI,MAAM,CAGlD;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,MAAM,CAE9F;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,GAAG,MAAM,CAEnF;AAiDD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGxE;AAED,wBAAgB,gCAAgC,CAC/C,OAAO,EAAE,YAAY,EACrB,cAAc,EAAE,cAAc,EAC9B,UAAU,CAAC,EAAE,0BAA0B,GACrC,0BAA0B,CAiC5B","sourcesContent":["import { spawnSync } from \"node:child_process\";\nimport type { AgentSession } from \"../../../core/agent-session.ts\";\nimport { getHeadroomRuntimeStatus } from \"../../../core/context-budget-headroom.ts\";\nimport type { ReadonlyFooterDataProvider } from \"../../../core/footer-data-provider.ts\";\nimport { loadMcpInventory, type McpServerEntry } from \"../../../core/mcp-inventory.ts\";\nimport { evaluatePiPackageIntake } from \"../../../core/pi-package-intake.ts\";\nimport type { SessionManager } from \"../../../core/session-manager.ts\";\nimport { getCurrentTodoState } from \"../../../core/todo-runtime-state.ts\";\nimport type { ControlPanelStatusSnapshot } from \"./control-panel-layout.ts\";\nimport { formatCwdForFooter } from \"./footer.ts\";\n\nconst OMK_HUB_SKILL_NAMES = new Set([\n\t\"omk-skills\",\n\t\"omk-engineering\",\n\t\"omk-backend-data\",\n\t\"omk-security\",\n\t\"omk-devops-release\",\n\t\"omk-research-docs\",\n\t\"omk-design-media\",\n\t\"omk-agent-ops\",\n\t\"omk-product-ops\",\n\t\"omk-workspace-ops\",\n\t\"omk-frontend\",\n\t\"omk-loop\",\n\t\"omk-plan\",\n]);\n\nconst INVALID_MCP_NETWORK_RULES = new Set([\"mcp.network.invalid_mode\", \"mcp.network.empty_allowlist\"]);\nconst PRIVILEGED_MCP_COMMANDS = new Set([\"sudo\", \"su\"]);\nconst VERSION_COMMAND_TIMEOUT_MS = 750;\nconst HEADROOM_PYTHON_DISTRIBUTIONS = [\"headroom\", \"headroom-ai\"] as const;\n\nlet cachedHeadroomVersion: string | null | undefined;\n\ninterface McpStabilityInput {\n\treadonly commandSummary: string;\n\treadonly overriddenBy?: string;\n\treadonly networkDecision: Pick<McpServerEntry[\"networkDecision\"], \"rule\">;\n\treadonly capabilityDecision: Pick<McpServerEntry[\"capabilityDecision\"], \"malformed\" | \"unknownCapabilities\">;\n\treadonly authDecision: Pick<McpServerEntry[\"authDecision\"], \"rule\">;\n}\n\nexport function formatHeadroomStatusLabel(): string {\n\tconst version = getInstalledHeadroomVersion();\n\treturn version ? `headroom:${version}` : getHeadroomRuntimeStatus().policyId;\n}\n\nexport function countRoutableNonHubSkills(skills: readonly { readonly name: string }[]): number {\n\treturn skills.filter((skill) => !OMK_HUB_SKILL_NAMES.has(skill.name)).length;\n}\n\nexport function countStableMcpServers(entries: readonly McpStabilityInput[]): number {\n\treturn entries.filter(isStableMcpEntry).length;\n}\n\nfunction isStableMcpEntry(entry: McpStabilityInput): boolean {\n\tif (entry.overriddenBy) return false;\n\tif (entry.commandSummary === \"<unknown>\") return false;\n\tif (entry.authDecision.rule === \"mcp.auth.invalid\") return false;\n\tif (INVALID_MCP_NETWORK_RULES.has(entry.networkDecision.rule)) return false;\n\tif (entry.capabilityDecision.malformed || entry.capabilityDecision.unknownCapabilities.length > 0) return false;\n\tconst command = entry.commandSummary.split(/\\s+/, 1)[0] ?? \"\";\n\treturn !PRIVILEGED_MCP_COMMANDS.has(command);\n}\n\nfunction getInstalledHeadroomVersion(): string | null {\n\tif (cachedHeadroomVersion !== undefined) return cachedHeadroomVersion;\n\tcachedHeadroomVersion = readVersionFromCommand(\"headroom\", [\"--version\"]);\n\tif (cachedHeadroomVersion) return cachedHeadroomVersion;\n\tcachedHeadroomVersion = readVersionFromCommand(\"headroom\", [\"version\"]);\n\tif (cachedHeadroomVersion) return cachedHeadroomVersion;\n\tfor (const distribution of HEADROOM_PYTHON_DISTRIBUTIONS) {\n\t\tcachedHeadroomVersion = readPythonDistributionVersion(distribution);\n\t\tif (cachedHeadroomVersion) return cachedHeadroomVersion;\n\t}\n\tcachedHeadroomVersion = null;\n\treturn cachedHeadroomVersion;\n}\n\nfunction readPythonDistributionVersion(distribution: (typeof HEADROOM_PYTHON_DISTRIBUTIONS)[number]): string | null {\n\treturn readVersionFromCommand(\"python3\", [\n\t\t\"-c\",\n\t\t`import importlib.metadata as m; print(m.version('${distribution}'))`,\n\t]);\n}\n\nfunction readVersionFromCommand(command: string, args: readonly string[]): string | null {\n\ttry {\n\t\tconst result = spawnSync(command, [...args], {\n\t\t\tencoding: \"utf8\",\n\t\t\ttimeout: VERSION_COMMAND_TIMEOUT_MS,\n\t\t\tshell: false,\n\t\t\twindowsHide: true,\n\t\t\tenv: { PATH: process.env.PATH ?? \"\" },\n\t\t});\n\t\tif (result.error || result.status !== 0) return null;\n\t\treturn parseHeadroomVersionOutput(`${result.stdout}\\n${result.stderr}`);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport function parseHeadroomVersionOutput(output: string): string | null {\n\tconst match = /\\bv?(\\d+\\.\\d+(?:\\.\\d+)?(?:[-+][0-9A-Za-z.-]+)?)\\b/.exec(output);\n\treturn match?.[1] ?? null;\n}\n\nexport function createControlPanelStatusSnapshot(\n\tsession: AgentSession,\n\tsessionManager: SessionManager,\n\tfooterData?: ReadonlyFooterDataProvider,\n): ControlPanelStatusSnapshot {\n\tconst contextUsage = session.getContextUsage();\n\tconst contextWindow = contextUsage?.contextWindow ?? session.state.model?.contextWindow ?? 0;\n\tconst mcpInventory = loadMcpInventory(sessionManager.getCwd());\n\tconst loadedSkills = session.resourceLoader.getSkills().skills;\n\tconst packageIntake = evaluatePiPackageIntake().summary;\n\tconst ansiColorState = process.env.NO_COLOR ? \"off\" : \"on\";\n\tconst cwdLabel = formatCwdForFooter(sessionManager.getCwd(), process.env.HOME || process.env.USERPROFILE);\n\treturn {\n\t\tmodelId: session.state.model?.id,\n\t\tmodelProvider: session.state.model?.provider,\n\t\tthinkingLevel: session.state.thinkingLevel ?? \"off\",\n\t\tcontextPercent: contextUsage?.percent ?? null,\n\t\tcontextWindowTokens: contextWindow,\n\t\tcontextTokens: contextUsage?.tokens ?? null,\n\t\theadroomStatus: formatHeadroomStatusLabel(),\n\t\toptimizerPolicy: getHeadroomRuntimeStatus().selector,\n\t\tmcpCount: countStableMcpServers(mcpInventory.entries),\n\t\tskillCount: countRoutableNonHubSkills(loadedSkills),\n\t\tpackageIntake,\n\t\tcwdLabel,\n\t\tgitBranch: footerData?.getGitBranch(),\n\t\ttodoState: getCurrentTodoState(),\n\t\truntimeState: \"ready\",\n\t\trouteState: \"active\",\n\t\tevidenceState: \"tracking\",\n\t\tcontrolState: \"ready\",\n\t\tdagOrchestrationState: \"DAG:omk-parallel-orchestrator\",\n\t\tansiColorState,\n\t\tstartupState: \"linked\",\n\t\tlinkState: \"ready\",\n\t\tsidebarState: \"pinned\",\n\t};\n}\n"]}
1
+ {"version":3,"file":"control-panel-runtime-status.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/control-panel-runtime-status.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAEnE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AACxF,OAAO,EAAoB,KAAK,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAEvF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAEvE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AA0B5E,UAAU,iBAAiB;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,eAAe,EAAE,IAAI,CAAC,cAAc,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC,CAAC;IAC1E,QAAQ,CAAC,kBAAkB,EAAE,IAAI,CAAC,cAAc,CAAC,oBAAoB,CAAC,EAAE,WAAW,GAAG,qBAAqB,CAAC,CAAC;IAC7G,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC;CACpE;AAED,wBAAgB,yBAAyB,IAAI,MAAM,CAGlD;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,MAAM,CAE9F;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,GAAG,MAAM,CAEnF;AAED;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,YAAY,GAAG,UAAU,CAAC;AAEhE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAS3E;AAuCD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGxE;AAED,wBAAgB,gCAAgC,CAC/C,OAAO,EAAE,YAAY,EACrB,cAAc,EAAE,cAAc,EAC9B,UAAU,CAAC,EAAE,0BAA0B,GACrC,0BAA0B,CAiC5B","sourcesContent":["import { spawnSync } from \"node:child_process\";\nimport type { AgentSession } from \"../../../core/agent-session.ts\";\nimport { getHeadroomRuntimeStatus } from \"../../../core/context-budget-headroom.ts\";\nimport type { ReadonlyFooterDataProvider } from \"../../../core/footer-data-provider.ts\";\nimport { loadMcpInventory, type McpServerEntry } from \"../../../core/mcp-inventory.ts\";\nimport { evaluatePiPackageIntake } from \"../../../core/pi-package-intake.ts\";\nimport type { SessionManager } from \"../../../core/session-manager.ts\";\nimport { getCurrentTodoState } from \"../../../core/todo-runtime-state.ts\";\nimport type { ControlPanelStatusSnapshot } from \"./control-panel-layout.ts\";\nimport { formatCwdForFooter } from \"./footer.ts\";\n\nconst OMK_HUB_SKILL_NAMES = new Set([\n\t\"omk-skills\",\n\t\"omk-engineering\",\n\t\"omk-backend-data\",\n\t\"omk-security\",\n\t\"omk-devops-release\",\n\t\"omk-research-docs\",\n\t\"omk-design-media\",\n\t\"omk-agent-ops\",\n\t\"omk-product-ops\",\n\t\"omk-workspace-ops\",\n\t\"omk-frontend\",\n\t\"omk-loop\",\n\t\"omk-plan\",\n]);\n\nconst INVALID_MCP_NETWORK_RULES = new Set([\"mcp.network.invalid_mode\", \"mcp.network.empty_allowlist\"]);\nconst PRIVILEGED_MCP_COMMANDS = new Set([\"sudo\", \"su\"]);\nconst VERSION_COMMAND_TIMEOUT_MS = 750;\nconst HEADROOM_PYTHON_DISTRIBUTIONS = [\"headroom\", \"headroom-ai\"] as const;\n\nlet cachedHeadroomVersion: string | null | undefined;\n\ninterface McpStabilityInput {\n\treadonly commandSummary: string;\n\treadonly overriddenBy?: string;\n\treadonly networkDecision: Pick<McpServerEntry[\"networkDecision\"], \"rule\">;\n\treadonly capabilityDecision: Pick<McpServerEntry[\"capabilityDecision\"], \"malformed\" | \"unknownCapabilities\">;\n\treadonly authDecision: Pick<McpServerEntry[\"authDecision\"], \"rule\">;\n}\n\nexport function formatHeadroomStatusLabel(): string {\n\tconst version = getInstalledHeadroomVersion();\n\treturn version ? `headroom:${version}` : getHeadroomRuntimeStatus().policyId;\n}\n\nexport function countRoutableNonHubSkills(skills: readonly { readonly name: string }[]): number {\n\treturn skills.filter((skill) => !OMK_HUB_SKILL_NAMES.has(skill.name)).length;\n}\n\nexport function countStableMcpServers(entries: readonly McpStabilityInput[]): number {\n\treturn entries.filter((entry) => classifyMcpStability(entry) === \"stable\").length;\n}\n\n/**\n * Classify a single MCP server entry for status display.\n *\n * - `stable`: configured, healthy, and safe to surface as an active server.\n * - `overridden`: a higher-precedence source replaced this entry.\n * - `unstable`: malformed, privileged, or blocked by an auth/network policy.\n */\nexport type McpStability = \"stable\" | \"overridden\" | \"unstable\";\n\nexport function classifyMcpStability(entry: McpStabilityInput): McpStability {\n\tif (entry.overriddenBy) return \"overridden\";\n\tif (entry.commandSummary === \"<unknown>\") return \"unstable\";\n\tif (entry.authDecision.rule === \"mcp.auth.invalid\") return \"unstable\";\n\tif (INVALID_MCP_NETWORK_RULES.has(entry.networkDecision.rule)) return \"unstable\";\n\tif (entry.capabilityDecision.malformed || entry.capabilityDecision.unknownCapabilities.length > 0) return \"unstable\";\n\tconst command = entry.commandSummary.split(/\\s+/, 1)[0] ?? \"\";\n\tif (PRIVILEGED_MCP_COMMANDS.has(command)) return \"unstable\";\n\treturn \"stable\";\n}\n\nfunction getInstalledHeadroomVersion(): string | null {\n\tif (cachedHeadroomVersion !== undefined) return cachedHeadroomVersion;\n\tcachedHeadroomVersion = readVersionFromCommand(\"headroom\", [\"--version\"]);\n\tif (cachedHeadroomVersion) return cachedHeadroomVersion;\n\tcachedHeadroomVersion = readVersionFromCommand(\"headroom\", [\"version\"]);\n\tif (cachedHeadroomVersion) return cachedHeadroomVersion;\n\tfor (const distribution of HEADROOM_PYTHON_DISTRIBUTIONS) {\n\t\tcachedHeadroomVersion = readPythonDistributionVersion(distribution);\n\t\tif (cachedHeadroomVersion) return cachedHeadroomVersion;\n\t}\n\tcachedHeadroomVersion = null;\n\treturn cachedHeadroomVersion;\n}\n\nfunction readPythonDistributionVersion(distribution: (typeof HEADROOM_PYTHON_DISTRIBUTIONS)[number]): string | null {\n\treturn readVersionFromCommand(\"python3\", [\n\t\t\"-c\",\n\t\t`import importlib.metadata as m; print(m.version('${distribution}'))`,\n\t]);\n}\n\nfunction readVersionFromCommand(command: string, args: readonly string[]): string | null {\n\ttry {\n\t\tconst result = spawnSync(command, [...args], {\n\t\t\tencoding: \"utf8\",\n\t\t\ttimeout: VERSION_COMMAND_TIMEOUT_MS,\n\t\t\tshell: false,\n\t\t\twindowsHide: true,\n\t\t\tenv: { PATH: process.env.PATH ?? \"\" },\n\t\t});\n\t\tif (result.error || result.status !== 0) return null;\n\t\treturn parseHeadroomVersionOutput(`${result.stdout}\\n${result.stderr}`);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport function parseHeadroomVersionOutput(output: string): string | null {\n\tconst match = /\\bv?(\\d+\\.\\d+(?:\\.\\d+)?(?:[-+][0-9A-Za-z.-]+)?)\\b/.exec(output);\n\treturn match?.[1] ?? null;\n}\n\nexport function createControlPanelStatusSnapshot(\n\tsession: AgentSession,\n\tsessionManager: SessionManager,\n\tfooterData?: ReadonlyFooterDataProvider,\n): ControlPanelStatusSnapshot {\n\tconst contextUsage = session.getContextUsage();\n\tconst contextWindow = contextUsage?.contextWindow ?? session.state.model?.contextWindow ?? 0;\n\tconst mcpInventory = loadMcpInventory(sessionManager.getCwd());\n\tconst loadedSkills = session.resourceLoader.getSkills().skills;\n\tconst packageIntake = evaluatePiPackageIntake().summary;\n\tconst ansiColorState = process.env.NO_COLOR ? \"off\" : \"on\";\n\tconst cwdLabel = formatCwdForFooter(sessionManager.getCwd(), process.env.HOME || process.env.USERPROFILE);\n\treturn {\n\t\tmodelId: session.state.model?.id,\n\t\tmodelProvider: session.state.model?.provider,\n\t\tthinkingLevel: session.state.thinkingLevel ?? \"off\",\n\t\tcontextPercent: contextUsage?.percent ?? null,\n\t\tcontextWindowTokens: contextWindow,\n\t\tcontextTokens: contextUsage?.tokens ?? null,\n\t\theadroomStatus: formatHeadroomStatusLabel(),\n\t\toptimizerPolicy: getHeadroomRuntimeStatus().selector,\n\t\tmcpCount: countStableMcpServers(mcpInventory.entries),\n\t\tskillCount: countRoutableNonHubSkills(loadedSkills),\n\t\tpackageIntake,\n\t\tcwdLabel,\n\t\tgitBranch: footerData?.getGitBranch(),\n\t\ttodoState: getCurrentTodoState(),\n\t\truntimeState: \"ready\",\n\t\trouteState: \"active\",\n\t\tevidenceState: \"tracking\",\n\t\tcontrolState: \"ready\",\n\t\tdagOrchestrationState: \"DAG:omk-parallel-orchestrator\",\n\t\tansiColorState,\n\t\tstartupState: \"linked\",\n\t\tlinkState: \"ready\",\n\t\tsidebarState: \"pinned\",\n\t};\n}\n"]}