open-multi-agent-kit 0.90.0 → 0.90.4

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 (307) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/README.md +22 -31
  3. package/dist/cli/args.d.ts +0 -2
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +1 -7
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/config.d.ts +3 -6
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/config.js +27 -19
  10. package/dist/config.js.map +1 -1
  11. package/dist/core/adaptorch-bridge.d.ts +257 -0
  12. package/dist/core/adaptorch-bridge.d.ts.map +1 -0
  13. package/dist/core/adaptorch-bridge.js +473 -0
  14. package/dist/core/adaptorch-bridge.js.map +1 -0
  15. package/dist/core/agent-session.d.ts +132 -0
  16. package/dist/core/agent-session.d.ts.map +1 -1
  17. package/dist/core/agent-session.js +327 -5
  18. package/dist/core/agent-session.js.map +1 -1
  19. package/dist/core/bang-skill-invocation.d.ts +26 -0
  20. package/dist/core/bang-skill-invocation.d.ts.map +1 -0
  21. package/dist/core/bang-skill-invocation.js +208 -0
  22. package/dist/core/bang-skill-invocation.js.map +1 -0
  23. package/dist/core/compaction/utils.d.ts.map +1 -1
  24. package/dist/core/compaction/utils.js +15 -2
  25. package/dist/core/compaction/utils.js.map +1 -1
  26. package/dist/core/compactor.d.ts.map +1 -1
  27. package/dist/core/compactor.js +0 -3
  28. package/dist/core/compactor.js.map +1 -1
  29. package/dist/core/context-budget-governor-v2.d.ts +2 -1
  30. package/dist/core/context-budget-governor-v2.d.ts.map +1 -1
  31. package/dist/core/context-budget-governor-v2.js +1 -0
  32. package/dist/core/context-budget-governor-v2.js.map +1 -1
  33. package/dist/core/context-budget-headroom-types.d.ts +8 -0
  34. package/dist/core/context-budget-headroom-types.d.ts.map +1 -1
  35. package/dist/core/context-budget-headroom-types.js.map +1 -1
  36. package/dist/core/context-budget-headroom.d.ts +1 -1
  37. package/dist/core/context-budget-headroom.d.ts.map +1 -1
  38. package/dist/core/context-budget-headroom.js +17 -4
  39. package/dist/core/context-budget-headroom.js.map +1 -1
  40. package/dist/core/context-budget-system-prompt.d.ts +2 -1
  41. package/dist/core/context-budget-system-prompt.d.ts.map +1 -1
  42. package/dist/core/context-budget-system-prompt.js +6 -1
  43. package/dist/core/context-budget-system-prompt.js.map +1 -1
  44. package/dist/core/context-budget-v2-cache-hash.d.ts +3 -0
  45. package/dist/core/context-budget-v2-cache-hash.d.ts.map +1 -0
  46. package/dist/core/context-budget-v2-cache-hash.js +16 -0
  47. package/dist/core/context-budget-v2-cache-hash.js.map +1 -0
  48. package/dist/core/context-budget-v2-cache-keys.d.ts +58 -0
  49. package/dist/core/context-budget-v2-cache-keys.d.ts.map +1 -0
  50. package/dist/core/context-budget-v2-cache-keys.js +128 -0
  51. package/dist/core/context-budget-v2-cache-keys.js.map +1 -0
  52. package/dist/core/context-budget-v2-cache-provider.d.ts +23 -0
  53. package/dist/core/context-budget-v2-cache-provider.d.ts.map +1 -0
  54. package/dist/core/context-budget-v2-cache-provider.js +29 -0
  55. package/dist/core/context-budget-v2-cache-provider.js.map +1 -0
  56. package/dist/core/context-budget-v2-cache-telemetry.d.ts +36 -0
  57. package/dist/core/context-budget-v2-cache-telemetry.d.ts.map +1 -0
  58. package/dist/core/context-budget-v2-cache-telemetry.js +64 -0
  59. package/dist/core/context-budget-v2-cache-telemetry.js.map +1 -0
  60. package/dist/core/context-budget-v2-cache-validation.d.ts +36 -0
  61. package/dist/core/context-budget-v2-cache-validation.d.ts.map +1 -0
  62. package/dist/core/context-budget-v2-cache-validation.js +98 -0
  63. package/dist/core/context-budget-v2-cache-validation.js.map +1 -0
  64. package/dist/core/context-budget-v2-cache.d.ts +36 -0
  65. package/dist/core/context-budget-v2-cache.d.ts.map +1 -0
  66. package/dist/core/context-budget-v2-cache.js +50 -0
  67. package/dist/core/context-budget-v2-cache.js.map +1 -0
  68. package/dist/core/context-budget-v2-plan-cache-keys.d.ts +16 -0
  69. package/dist/core/context-budget-v2-plan-cache-keys.d.ts.map +1 -0
  70. package/dist/core/context-budget-v2-plan-cache-keys.js +49 -0
  71. package/dist/core/context-budget-v2-plan-cache-keys.js.map +1 -0
  72. package/dist/core/context-budget-v2-planner.d.ts.map +1 -1
  73. package/dist/core/context-budget-v2-planner.js +55 -2
  74. package/dist/core/context-budget-v2-planner.js.map +1 -1
  75. package/dist/core/context-budget-v2-representation-cache.d.ts +27 -0
  76. package/dist/core/context-budget-v2-representation-cache.d.ts.map +1 -0
  77. package/dist/core/context-budget-v2-representation-cache.js +173 -0
  78. package/dist/core/context-budget-v2-representation-cache.js.map +1 -0
  79. package/dist/core/context-budget-v2-selection.d.ts +2 -0
  80. package/dist/core/context-budget-v2-selection.d.ts.map +1 -1
  81. package/dist/core/context-budget-v2-selection.js +12 -2
  82. package/dist/core/context-budget-v2-selection.js.map +1 -1
  83. package/dist/core/context-budget-v2-types.d.ts +107 -1
  84. package/dist/core/context-budget-v2-types.d.ts.map +1 -1
  85. package/dist/core/context-budget-v2-types.js.map +1 -1
  86. package/dist/core/domain-loadouts.d.ts.map +1 -1
  87. package/dist/core/domain-loadouts.js +1 -1
  88. package/dist/core/domain-loadouts.js.map +1 -1
  89. package/dist/core/headroom.d.ts.map +1 -1
  90. package/dist/core/headroom.js +0 -4
  91. package/dist/core/headroom.js.map +1 -1
  92. package/dist/core/hook-inventory.d.ts.map +1 -1
  93. package/dist/core/hook-inventory.js +6 -0
  94. package/dist/core/hook-inventory.js.map +1 -1
  95. package/dist/core/mcp-computer-use-presets.d.ts +64 -0
  96. package/dist/core/mcp-computer-use-presets.d.ts.map +1 -0
  97. package/dist/core/mcp-computer-use-presets.js +158 -0
  98. package/dist/core/mcp-computer-use-presets.js.map +1 -0
  99. package/dist/core/mcp-public-presets.d.ts +578 -0
  100. package/dist/core/mcp-public-presets.d.ts.map +1 -0
  101. package/dist/core/mcp-public-presets.js +647 -0
  102. package/dist/core/mcp-public-presets.js.map +1 -0
  103. package/dist/core/model-registry.d.ts.map +1 -1
  104. package/dist/core/model-registry.js +1 -0
  105. package/dist/core/model-registry.js.map +1 -1
  106. package/dist/core/pi-package-intake-candidates.d.ts +14 -1
  107. package/dist/core/pi-package-intake-candidates.d.ts.map +1 -1
  108. package/dist/core/pi-package-intake-candidates.js +182 -0
  109. package/dist/core/pi-package-intake-candidates.js.map +1 -1
  110. package/dist/core/pi-package-intake.d.ts +8 -1
  111. package/dist/core/pi-package-intake.d.ts.map +1 -1
  112. package/dist/core/pi-package-intake.js +14 -4
  113. package/dist/core/pi-package-intake.js.map +1 -1
  114. package/dist/core/reasoning-router-bias.d.ts +119 -0
  115. package/dist/core/reasoning-router-bias.d.ts.map +1 -0
  116. package/dist/core/reasoning-router-bias.js +287 -0
  117. package/dist/core/reasoning-router-bias.js.map +1 -0
  118. package/dist/core/reasoning-router-v2.d.ts +94 -0
  119. package/dist/core/reasoning-router-v2.d.ts.map +1 -0
  120. package/dist/core/reasoning-router-v2.js +288 -0
  121. package/dist/core/reasoning-router-v2.js.map +1 -0
  122. package/dist/core/reasoning-router-v3.d.ts +15 -0
  123. package/dist/core/reasoning-router-v3.d.ts.map +1 -0
  124. package/dist/core/reasoning-router-v3.js +193 -0
  125. package/dist/core/reasoning-router-v3.js.map +1 -0
  126. package/dist/core/reasoning-router-v4-weights.d.ts +124 -0
  127. package/dist/core/reasoning-router-v4-weights.d.ts.map +1 -0
  128. package/dist/core/reasoning-router-v4-weights.js +112 -0
  129. package/dist/core/reasoning-router-v4-weights.js.map +1 -0
  130. package/dist/core/reasoning-router-v4.d.ts +163 -0
  131. package/dist/core/reasoning-router-v4.d.ts.map +1 -0
  132. package/dist/core/reasoning-router-v4.js +683 -0
  133. package/dist/core/reasoning-router-v4.js.map +1 -0
  134. package/dist/core/reasoning-router-weights.d.ts +155 -0
  135. package/dist/core/reasoning-router-weights.d.ts.map +1 -0
  136. package/dist/core/reasoning-router-weights.js +204 -0
  137. package/dist/core/reasoning-router-weights.js.map +1 -0
  138. package/dist/core/reasoning-router.d.ts +44 -0
  139. package/dist/core/reasoning-router.d.ts.map +1 -0
  140. package/dist/core/reasoning-router.js +138 -0
  141. package/dist/core/reasoning-router.js.map +1 -0
  142. package/dist/core/reverse-skill.d.ts +2 -0
  143. package/dist/core/reverse-skill.d.ts.map +1 -0
  144. package/dist/core/reverse-skill.js +7 -0
  145. package/dist/core/reverse-skill.js.map +1 -0
  146. package/dist/core/router-feedback-collector.d.ts +101 -0
  147. package/dist/core/router-feedback-collector.d.ts.map +1 -0
  148. package/dist/core/router-feedback-collector.js +239 -0
  149. package/dist/core/router-feedback-collector.js.map +1 -0
  150. package/dist/core/settings-manager.d.ts +31 -3
  151. package/dist/core/settings-manager.d.ts.map +1 -1
  152. package/dist/core/settings-manager.js +16 -0
  153. package/dist/core/settings-manager.js.map +1 -1
  154. package/dist/core/slash-commands.d.ts.map +1 -1
  155. package/dist/core/slash-commands.js +4 -1
  156. package/dist/core/slash-commands.js.map +1 -1
  157. package/dist/core/system-prompt.d.ts +2 -0
  158. package/dist/core/system-prompt.d.ts.map +1 -1
  159. package/dist/core/system-prompt.js +58 -5
  160. package/dist/core/system-prompt.js.map +1 -1
  161. package/dist/index.d.ts +1 -0
  162. package/dist/index.d.ts.map +1 -1
  163. package/dist/index.js +1 -0
  164. package/dist/index.js.map +1 -1
  165. package/dist/migrations.d.ts +19 -0
  166. package/dist/migrations.d.ts.map +1 -1
  167. package/dist/migrations.js +39 -15
  168. package/dist/migrations.js.map +1 -1
  169. package/dist/modes/interactive/components/control-panel-box.d.ts +3 -3
  170. package/dist/modes/interactive/components/control-panel-box.d.ts.map +1 -1
  171. package/dist/modes/interactive/components/control-panel-box.js +10 -10
  172. package/dist/modes/interactive/components/control-panel-box.js.map +1 -1
  173. package/dist/modes/interactive/components/control-panel-gradient-motion.d.ts.map +1 -1
  174. package/dist/modes/interactive/components/control-panel-gradient-motion.js +2 -1
  175. package/dist/modes/interactive/components/control-panel-gradient-motion.js.map +1 -1
  176. package/dist/modes/interactive/components/control-panel-layout.d.ts +15 -1
  177. package/dist/modes/interactive/components/control-panel-layout.d.ts.map +1 -1
  178. package/dist/modes/interactive/components/control-panel-layout.js +212 -68
  179. package/dist/modes/interactive/components/control-panel-layout.js.map +1 -1
  180. package/dist/modes/interactive/components/control-panel-runtime-status.d.ts +15 -0
  181. package/dist/modes/interactive/components/control-panel-runtime-status.d.ts.map +1 -1
  182. package/dist/modes/interactive/components/control-panel-runtime-status.js +105 -5
  183. package/dist/modes/interactive/components/control-panel-runtime-status.js.map +1 -1
  184. package/dist/modes/interactive/components/control-panel-sparkles.d.ts +27 -0
  185. package/dist/modes/interactive/components/control-panel-sparkles.d.ts.map +1 -0
  186. package/dist/modes/interactive/components/control-panel-sparkles.js +42 -0
  187. package/dist/modes/interactive/components/control-panel-sparkles.js.map +1 -0
  188. package/dist/modes/interactive/components/control-panel.d.ts +8 -0
  189. package/dist/modes/interactive/components/control-panel.d.ts.map +1 -1
  190. package/dist/modes/interactive/components/control-panel.js +40 -8
  191. package/dist/modes/interactive/components/control-panel.js.map +1 -1
  192. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  193. package/dist/modes/interactive/components/settings-selector.js +2 -1
  194. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  195. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  196. package/dist/modes/interactive/components/thinking-selector.js +2 -1
  197. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  198. package/dist/modes/interactive/interactive-mode.d.ts +6 -0
  199. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  200. package/dist/modes/interactive/interactive-mode.js +206 -32
  201. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  202. package/dist/modes/interactive/theme/theme.d.ts +1 -1
  203. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  204. package/dist/modes/interactive/theme/theme.js +2 -0
  205. package/dist/modes/interactive/theme/theme.js.map +1 -1
  206. package/docs/loadout-domains/README.md +8 -6
  207. package/docs/loadout-domains/ai-agent-ops.md +3 -2
  208. package/docs/loadout-domains/backend-api.md +3 -2
  209. package/docs/loadout-domains/data-science.md +3 -2
  210. package/docs/loadout-domains/devops-infra.md +2 -1
  211. package/docs/loadout-domains/docs-writing.md +7 -2
  212. package/docs/loadout-domains/frontend-ui.md +42 -11
  213. package/docs/loadout-domains/korean-document.md +83 -0
  214. package/docs/loadout-domains/mobile.md +1 -1
  215. package/docs/loadout-domains/qa-testing.md +4 -2
  216. package/docs/loadout-domains/security-audit.md +2 -1
  217. package/docs/loadout-domains/visual-qa.md +94 -0
  218. package/docs/skills.md +11 -4
  219. package/docs/usage.md +39 -4
  220. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  221. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  222. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  223. package/examples/extensions/gondolin/package-lock.json +2 -2
  224. package/examples/extensions/gondolin/package.json +1 -1
  225. package/examples/extensions/preset.ts +2 -2
  226. package/examples/extensions/sandbox/package-lock.json +2 -2
  227. package/examples/extensions/sandbox/package.json +1 -1
  228. package/examples/extensions/with-deps/package-lock.json +2 -2
  229. package/examples/extensions/with-deps/package.json +1 -1
  230. package/npm-shrinkwrap.json +27 -34
  231. package/package.json +5 -5
  232. package/dist/agents/jailbreak/index.d.ts +0 -7
  233. package/dist/agents/jailbreak/index.d.ts.map +0 -1
  234. package/dist/agents/jailbreak/index.js +0 -7
  235. package/dist/agents/jailbreak/index.js.map +0 -1
  236. package/dist/agents/jailbreak/subagent-f.d.ts +0 -44
  237. package/dist/agents/jailbreak/subagent-f.d.ts.map +0 -1
  238. package/dist/agents/jailbreak/subagent-f.js +0 -60
  239. package/dist/agents/jailbreak/subagent-f.js.map +0 -1
  240. package/dist/cli/jailbreak-args.d.ts +0 -26
  241. package/dist/cli/jailbreak-args.d.ts.map +0 -1
  242. package/dist/cli/jailbreak-args.js +0 -86
  243. package/dist/cli/jailbreak-args.js.map +0 -1
  244. package/dist/commands/jailbreak.d.ts +0 -49
  245. package/dist/commands/jailbreak.d.ts.map +0 -1
  246. package/dist/commands/jailbreak.js +0 -201
  247. package/dist/commands/jailbreak.js.map +0 -1
  248. package/dist/encoding/index.d.ts +0 -6
  249. package/dist/encoding/index.d.ts.map +0 -1
  250. package/dist/encoding/index.js +0 -6
  251. package/dist/encoding/index.js.map +0 -1
  252. package/dist/encoding/l4-encoder.d.ts +0 -96
  253. package/dist/encoding/l4-encoder.d.ts.map +0 -1
  254. package/dist/encoding/l4-encoder.js +0 -474
  255. package/dist/encoding/l4-encoder.js.map +0 -1
  256. package/dist/fuzzing/index.d.ts +0 -6
  257. package/dist/fuzzing/index.d.ts.map +0 -1
  258. package/dist/fuzzing/index.js +0 -6
  259. package/dist/fuzzing/index.js.map +0 -1
  260. package/dist/fuzzing/mutation-engine.d.ts +0 -93
  261. package/dist/fuzzing/mutation-engine.d.ts.map +0 -1
  262. package/dist/fuzzing/mutation-engine.js +0 -244
  263. package/dist/fuzzing/mutation-engine.js.map +0 -1
  264. package/dist/jailbreak-extension.d.ts +0 -48
  265. package/dist/jailbreak-extension.d.ts.map +0 -1
  266. package/dist/jailbreak-extension.js +0 -47
  267. package/dist/jailbreak-extension.js.map +0 -1
  268. package/dist/modules/index.d.ts +0 -8
  269. package/dist/modules/index.d.ts.map +0 -1
  270. package/dist/modules/index.js +0 -7
  271. package/dist/modules/index.js.map +0 -1
  272. package/dist/modules/lrl-bypass.d.ts +0 -40
  273. package/dist/modules/lrl-bypass.d.ts.map +0 -1
  274. package/dist/modules/lrl-bypass.js +0 -84
  275. package/dist/modules/lrl-bypass.js.map +0 -1
  276. package/dist/modules/lrl-deps.d.ts +0 -38
  277. package/dist/modules/lrl-deps.d.ts.map +0 -1
  278. package/dist/modules/lrl-deps.js +0 -128
  279. package/dist/modules/lrl-deps.js.map +0 -1
  280. package/dist/multiturn/easl-chain.d.ts +0 -113
  281. package/dist/multiturn/easl-chain.d.ts.map +0 -1
  282. package/dist/multiturn/easl-chain.js +0 -351
  283. package/dist/multiturn/easl-chain.js.map +0 -1
  284. package/dist/multiturn/index.d.ts +0 -6
  285. package/dist/multiturn/index.d.ts.map +0 -1
  286. package/dist/multiturn/index.js +0 -6
  287. package/dist/multiturn/index.js.map +0 -1
  288. package/dist/routing/fallback-router.d.ts +0 -123
  289. package/dist/routing/fallback-router.d.ts.map +0 -1
  290. package/dist/routing/fallback-router.js +0 -355
  291. package/dist/routing/fallback-router.js.map +0 -1
  292. package/dist/routing/index.d.ts +0 -6
  293. package/dist/routing/index.d.ts.map +0 -1
  294. package/dist/routing/index.js +0 -6
  295. package/dist/routing/index.js.map +0 -1
  296. package/dist/types/jailbreak.d.ts +0 -246
  297. package/dist/types/jailbreak.d.ts.map +0 -1
  298. package/dist/types/jailbreak.js +0 -8
  299. package/dist/types/jailbreak.js.map +0 -1
  300. package/dist/utils/jailbreak/common.d.ts +0 -63
  301. package/dist/utils/jailbreak/common.d.ts.map +0 -1
  302. package/dist/utils/jailbreak/common.js +0 -130
  303. package/dist/utils/jailbreak/common.js.map +0 -1
  304. package/dist/utils/jailbreak/index.d.ts +0 -7
  305. package/dist/utils/jailbreak/index.d.ts.map +0 -1
  306. package/dist/utils/jailbreak/index.js +0 -7
  307. package/dist/utils/jailbreak/index.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * One-time migrations that run on startup.\n */\n\nimport chalk from \"chalk\";\nimport { chmodSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport { CONFIG_DIR_NAME, getAgentDir, getBinDir } from \"./config.ts\";\nimport { migrateKeybindingsConfig } from \"./core/keybindings.ts\";\nimport { isLegacyEnvVarNameConfigValue } from \"./core/resolve-config-value.ts\";\nimport { stripJsonComments } from \"./utils/json.ts\";\n\nconst MIGRATION_GUIDE_URL =\n\t\"https://github.com/dmae97/omk/blob/main/packages/coding-agent/CHANGELOG.md#extensions-migration\";\nconst EXTENSIONS_DOC_URL = \"https://github.com/dmae97/omk/blob/main/packages/coding-agent/docs/extensions.md\";\n\n/**\n * Migrate legacy oauth.json and settings.json apiKeys to auth.json.\n *\n * @returns Array of provider names that were migrated\n */\nexport function migrateAuthToAuthJson(): string[] {\n\tconst agentDir = getAgentDir();\n\tconst authPath = join(agentDir, \"auth.json\");\n\tconst oauthPath = join(agentDir, \"oauth.json\");\n\tconst settingsPath = join(agentDir, \"settings.json\");\n\n\t// Skip if auth.json already exists\n\tif (existsSync(authPath)) return [];\n\n\tconst migrated: Record<string, unknown> = {};\n\tconst providers: string[] = [];\n\n\t// Migrate oauth.json\n\tif (existsSync(oauthPath)) {\n\t\ttry {\n\t\t\tconst oauth = JSON.parse(readFileSync(oauthPath, \"utf-8\"));\n\t\t\tfor (const [provider, cred] of Object.entries(oauth)) {\n\t\t\t\tmigrated[provider] = { type: \"oauth\", ...(cred as object) };\n\t\t\t\tproviders.push(provider);\n\t\t\t}\n\t\t\trenameSync(oauthPath, `${oauthPath}.migrated`);\n\t\t} catch {\n\t\t\t// Skip on error\n\t\t}\n\t}\n\n\t// Migrate settings.json apiKeys\n\tif (existsSync(settingsPath)) {\n\t\ttry {\n\t\t\tconst content = readFileSync(settingsPath, \"utf-8\");\n\t\t\tconst settings = JSON.parse(content);\n\t\t\tif (settings.apiKeys && typeof settings.apiKeys === \"object\") {\n\t\t\t\tfor (const [provider, key] of Object.entries(settings.apiKeys)) {\n\t\t\t\t\tif (!migrated[provider] && typeof key === \"string\") {\n\t\t\t\t\t\tmigrated[provider] = { type: \"api_key\", key };\n\t\t\t\t\t\tproviders.push(provider);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdelete settings.apiKeys;\n\t\t\t\twriteFileSync(settingsPath, JSON.stringify(settings, null, 2));\n\t\t\t}\n\t\t} catch {\n\t\t\t// Skip on error\n\t\t}\n\t}\n\n\tif (Object.keys(migrated).length > 0) {\n\t\tmkdirSync(dirname(authPath), { recursive: true });\n\t\twriteFileSync(authPath, JSON.stringify(migrated, null, 2), { mode: 0o600 });\n\t}\n\n\treturn providers;\n}\n\ninterface ConfigValueMigration {\n\tlocation: string;\n\tfrom: string;\n\tto: string;\n}\n\nfunction migrateLegacyEnvVarString(value: string): string | undefined {\n\treturn isLegacyEnvVarNameConfigValue(value) ? `$${value}` : undefined;\n}\n\nfunction migrateStringProperty(\n\trecord: Record<string, unknown>,\n\tkey: string,\n\tlocation: string,\n\tmigrations: ConfigValueMigration[],\n): boolean {\n\tconst value = record[key];\n\tif (typeof value !== \"string\") return false;\n\tconst migrated = migrateLegacyEnvVarString(value);\n\tif (migrated === undefined) return false;\n\trecord[key] = migrated;\n\tmigrations.push({ location, from: value, to: migrated });\n\treturn true;\n}\n\nfunction migrateHeadersConfig(headers: unknown, location: string, migrations: ConfigValueMigration[]): boolean {\n\tif (typeof headers !== \"object\" || headers === null || Array.isArray(headers)) return false;\n\tconst headerRecord = headers as Record<string, unknown>;\n\tlet migrated = false;\n\tfor (const [key, value] of Object.entries(headerRecord)) {\n\t\tif (typeof value !== \"string\") continue;\n\t\tconst migratedValue = migrateLegacyEnvVarString(value);\n\t\tif (migratedValue === undefined) continue;\n\t\theaderRecord[key] = migratedValue;\n\t\tmigrations.push({ location: `${location}[${JSON.stringify(key)}]`, from: value, to: migratedValue });\n\t\tmigrated = true;\n\t}\n\treturn migrated;\n}\n\nfunction migrateAuthJsonConfigValues(agentDir: string): ConfigValueMigration[] {\n\tconst authPath = join(agentDir, \"auth.json\");\n\tif (!existsSync(authPath)) return [];\n\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(authPath, \"utf-8\")) as unknown;\n\t\tif (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) return [];\n\t\tconst authData = parsed as Record<string, unknown>;\n\n\t\tconst migrations: ConfigValueMigration[] = [];\n\t\tfor (const [provider, credential] of Object.entries(authData)) {\n\t\t\tif (typeof credential !== \"object\" || credential === null || Array.isArray(credential)) continue;\n\t\t\tconst credentialRecord = credential as Record<string, unknown>;\n\t\t\tif (credentialRecord.type !== \"api_key\") continue;\n\t\t\tmigrateStringProperty(credentialRecord, \"key\", `auth.json[${JSON.stringify(provider)}].key`, migrations);\n\t\t}\n\n\t\tif (migrations.length === 0) return [];\n\t\twriteFileSync(authPath, `${JSON.stringify(parsed, null, 2)}\\n`, \"utf-8\");\n\t\tchmodSync(authPath, 0o600);\n\t\treturn migrations;\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nfunction migrateModelsJsonConfigValues(agentDir: string): ConfigValueMigration[] {\n\tconst modelsPath = join(agentDir, \"models.json\");\n\tif (!existsSync(modelsPath)) return [];\n\n\tconst parsed = JSON.parse(stripJsonComments(readFileSync(modelsPath, \"utf-8\"))) as unknown;\n\tif (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) return [];\n\tconst modelsData = parsed as Record<string, unknown>;\n\tconst providers = modelsData.providers;\n\tif (typeof providers !== \"object\" || providers === null || Array.isArray(providers)) return [];\n\n\tconst migrations: ConfigValueMigration[] = [];\n\tfor (const [provider, providerConfig] of Object.entries(providers)) {\n\t\tif (typeof providerConfig !== \"object\" || providerConfig === null || Array.isArray(providerConfig)) continue;\n\t\tconst providerRecord = providerConfig as Record<string, unknown>;\n\t\tconst providerLocation = `models.json.providers[${JSON.stringify(provider)}]`;\n\t\tmigrateStringProperty(providerRecord, \"apiKey\", `${providerLocation}.apiKey`, migrations);\n\t\tmigrateHeadersConfig(providerRecord.headers, `${providerLocation}.headers`, migrations);\n\n\t\tif (Array.isArray(providerRecord.models)) {\n\t\t\tfor (let index = 0; index < providerRecord.models.length; index++) {\n\t\t\t\tconst modelConfig = providerRecord.models[index];\n\t\t\t\tif (typeof modelConfig !== \"object\" || modelConfig === null || Array.isArray(modelConfig)) continue;\n\t\t\t\tconst modelRecord = modelConfig as Record<string, unknown>;\n\t\t\t\tconst modelKey = typeof modelRecord.id === \"string\" ? JSON.stringify(modelRecord.id) : String(index);\n\t\t\t\tmigrateHeadersConfig(modelRecord.headers, `${providerLocation}.models[${modelKey}].headers`, migrations);\n\t\t\t}\n\t\t}\n\n\t\tconst modelOverrides = providerRecord.modelOverrides;\n\t\tif (typeof modelOverrides === \"object\" && modelOverrides !== null && !Array.isArray(modelOverrides)) {\n\t\t\tfor (const [modelId, modelOverride] of Object.entries(modelOverrides)) {\n\t\t\t\tif (typeof modelOverride !== \"object\" || modelOverride === null || Array.isArray(modelOverride)) continue;\n\t\t\t\tconst modelOverrideRecord = modelOverride as Record<string, unknown>;\n\t\t\t\tmigrateHeadersConfig(\n\t\t\t\t\tmodelOverrideRecord.headers,\n\t\t\t\t\t`${providerLocation}.modelOverrides[${JSON.stringify(modelId)}].headers`,\n\t\t\t\t\tmigrations,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (migrations.length === 0) return [];\n\twriteFileSync(modelsPath, `${JSON.stringify(parsed, null, 2)}\\n`, \"utf-8\");\n\treturn migrations;\n}\n\nfunction migrateExplicitEnvVarConfigValues(): void {\n\tconst agentDir = getAgentDir();\n\tconst migrations = [...migrateAuthJsonConfigValues(agentDir), ...migrateModelsJsonConfigValues(agentDir)];\n\tif (migrations.length === 0) return;\n\n\tconst details = migrations.map((migration) => ` - ${migration.location}: ${migration.from} -> ${migration.to}`);\n\tconsole.log(\n\t\tchalk.yellow(\n\t\t\t[\n\t\t\t\t\"Warning: Migrated API key/header environment references to explicit $ENV_VAR syntax. Plain strings will be treated as literals.\",\n\t\t\t\t...details,\n\t\t\t].join(\"\\n\"),\n\t\t),\n\t);\n}\n\n/**\n * Migrate sessions from ~/.omk/agent/*.jsonl to proper session directories.\n *\n * Bug in v0.30.0: Sessions were saved to ~/.omk/agent/ instead of\n * ~/.omk/agent/sessions/<encoded-cwd>/. This migration moves them\n * to the correct location based on the cwd in their session header.\n */\nexport function migrateSessionsFromAgentRoot(): void {\n\tconst agentDir = getAgentDir();\n\n\t// Find all .jsonl files directly in agentDir (not in subdirectories)\n\tlet files: string[];\n\ttry {\n\t\tfiles = readdirSync(agentDir)\n\t\t\t.filter((f) => f.endsWith(\".jsonl\"))\n\t\t\t.map((f) => join(agentDir, f));\n\t} catch {\n\t\treturn;\n\t}\n\n\tif (files.length === 0) return;\n\n\tfor (const file of files) {\n\t\ttry {\n\t\t\t// Read first line to get session header\n\t\t\tconst content = readFileSync(file, \"utf8\");\n\t\t\tconst firstLine = content.split(\"\\n\")[0];\n\t\t\tif (!firstLine?.trim()) continue;\n\n\t\t\tconst header = JSON.parse(firstLine);\n\t\t\tif (header.type !== \"session\" || !header.cwd) continue;\n\n\t\t\tconst cwd: string = header.cwd;\n\n\t\t\t// Compute the correct session directory (same encoding as session-manager.ts)\n\t\t\tconst safePath = `--${cwd.replace(/^[/\\\\]/, \"\").replace(/[/\\\\:]/g, \"-\")}--`;\n\t\t\tconst correctDir = join(agentDir, \"sessions\", safePath);\n\n\t\t\t// Create directory if needed\n\t\t\tif (!existsSync(correctDir)) {\n\t\t\t\tmkdirSync(correctDir, { recursive: true });\n\t\t\t}\n\n\t\t\t// Move the file\n\t\t\tconst fileName = file.split(\"/\").pop() || file.split(\"\\\\\").pop();\n\t\t\tconst newPath = join(correctDir, fileName!);\n\n\t\t\tif (existsSync(newPath)) continue; // Skip if target exists\n\n\t\t\trenameSync(file, newPath);\n\t\t} catch {\n\t\t\t// Skip files that can't be migrated\n\t\t}\n\t}\n}\n\n/**\n * Migrate commands/ to prompts/ if needed.\n * Works for both regular directories and symlinks.\n */\nfunction migrateCommandsToPrompts(baseDir: string, label: string): boolean {\n\tconst commandsDir = join(baseDir, \"commands\");\n\tconst promptsDir = join(baseDir, \"prompts\");\n\n\tif (existsSync(commandsDir) && !existsSync(promptsDir)) {\n\t\ttry {\n\t\t\trenameSync(commandsDir, promptsDir);\n\t\t\tconsole.log(chalk.green(`Migrated ${label} commands/ → prompts/`));\n\t\t\treturn true;\n\t\t} catch (err) {\n\t\t\tconsole.log(\n\t\t\t\tchalk.yellow(\n\t\t\t\t\t`Warning: Could not migrate ${label} commands/ to prompts/: ${err instanceof Error ? err.message : err}`,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n\treturn false;\n}\n\nfunction migrateKeybindingsConfigFile(): void {\n\tconst configPath = join(getAgentDir(), \"keybindings.json\");\n\tif (!existsSync(configPath)) return;\n\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(configPath, \"utf-8\")) as unknown;\n\t\tif (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tconst { config, migrated } = migrateKeybindingsConfig(parsed as Record<string, unknown>);\n\t\tif (!migrated) return;\n\t\twriteFileSync(configPath, `${JSON.stringify(config, null, 2)}\\n`, \"utf-8\");\n\t} catch {\n\t\t// Ignore malformed files during migration\n\t}\n}\n\n/**\n * Move fd/rg binaries from tools/ to bin/ if they exist.\n */\nfunction migrateToolsToBin(): void {\n\tconst agentDir = getAgentDir();\n\tconst toolsDir = join(agentDir, \"tools\");\n\tconst binDir = getBinDir();\n\n\tif (!existsSync(toolsDir)) return;\n\n\tconst binaries = [\"fd\", \"rg\", \"fd.exe\", \"rg.exe\"];\n\tlet movedAny = false;\n\n\tfor (const bin of binaries) {\n\t\tconst oldPath = join(toolsDir, bin);\n\t\tconst newPath = join(binDir, bin);\n\n\t\tif (existsSync(oldPath)) {\n\t\t\tif (!existsSync(binDir)) {\n\t\t\t\tmkdirSync(binDir, { recursive: true });\n\t\t\t}\n\t\t\tif (!existsSync(newPath)) {\n\t\t\t\ttry {\n\t\t\t\t\trenameSync(oldPath, newPath);\n\t\t\t\t\tmovedAny = true;\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore errors\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Target exists, just delete the old one\n\t\t\t\ttry {\n\t\t\t\t\trmSync?.(oldPath, { force: true });\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (movedAny) {\n\t\tconsole.log(chalk.green(`Migrated managed binaries tools/ → bin/`));\n\t}\n}\n\n/**\n * Check for deprecated hooks/ and tools/ directories.\n * Note: tools/ may contain legacy auto-extracted fd/rg binaries, so only warn if it has other files.\n */\nfunction checkDeprecatedExtensionDirs(baseDir: string, label: string): string[] {\n\tconst hooksDir = join(baseDir, \"hooks\");\n\tconst toolsDir = join(baseDir, \"tools\");\n\tconst warnings: string[] = [];\n\n\tif (existsSync(hooksDir)) {\n\t\twarnings.push(`${label} hooks/ directory found. Hooks have been renamed to extensions.`);\n\t}\n\n\tif (existsSync(toolsDir)) {\n\t\t// Check if tools/ contains anything other than fd/rg (which are auto-extracted binaries)\n\t\ttry {\n\t\t\tconst entries = readdirSync(toolsDir);\n\t\t\tconst customTools = entries.filter((e) => {\n\t\t\t\tconst lower = e.toLowerCase();\n\t\t\t\treturn (\n\t\t\t\t\tlower !== \"fd\" && lower !== \"rg\" && lower !== \"fd.exe\" && lower !== \"rg.exe\" && !e.startsWith(\".\") // Ignore .DS_Store and other hidden files\n\t\t\t\t);\n\t\t\t});\n\t\t\tif (customTools.length > 0) {\n\t\t\t\twarnings.push(\n\t\t\t\t\t`${label} tools/ directory contains custom tools. Custom tools have been merged into extensions.`,\n\t\t\t\t);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore read errors\n\t\t}\n\t}\n\n\treturn warnings;\n}\n\n/**\n * Run extension system migrations (commands→prompts) and collect warnings about deprecated directories.\n */\nfunction migrateExtensionSystem(cwd: string): string[] {\n\tconst agentDir = getAgentDir();\n\tconst projectDir = join(cwd, CONFIG_DIR_NAME);\n\n\t// Migrate commands/ to prompts/\n\tmigrateCommandsToPrompts(agentDir, \"Global\");\n\tmigrateCommandsToPrompts(projectDir, \"Project\");\n\n\t// Check for deprecated directories\n\tconst warnings = [\n\t\t...checkDeprecatedExtensionDirs(agentDir, \"Global\"),\n\t\t...checkDeprecatedExtensionDirs(projectDir, \"Project\"),\n\t];\n\n\treturn warnings;\n}\n\n/**\n * Print deprecation warnings and wait for keypress.\n */\nexport async function showDeprecationWarnings(warnings: string[]): Promise<void> {\n\tif (warnings.length === 0) return;\n\n\tfor (const warning of warnings) {\n\t\tconsole.log(chalk.yellow(`Warning: ${warning}`));\n\t}\n\tconsole.log(chalk.yellow(`\\nMove your extensions to the extensions/ directory.`));\n\tconsole.log(chalk.yellow(`Migration guide: ${MIGRATION_GUIDE_URL}`));\n\tconsole.log(chalk.yellow(`Documentation: ${EXTENSIONS_DOC_URL}`));\n\tconsole.log(chalk.dim(`\\nPress any key to continue...`));\n\n\tawait new Promise<void>((resolve) => {\n\t\tprocess.stdin.setRawMode?.(true);\n\t\tprocess.stdin.resume();\n\t\tprocess.stdin.once(\"data\", () => {\n\t\t\tprocess.stdin.setRawMode?.(false);\n\t\t\tprocess.stdin.pause();\n\t\t\tresolve();\n\t\t});\n\t});\n\tconsole.log();\n}\n\n/**\n * Run all migrations. Called once on startup.\n *\n * @returns Object with migration results and deprecation warnings\n */\nexport function runMigrations(cwd: string): {\n\tmigratedAuthProviders: string[];\n\tdeprecationWarnings: string[];\n} {\n\tconst migratedAuthProviders = migrateAuthToAuthJson();\n\tmigrateExplicitEnvVarConfigValues();\n\tmigrateSessionsFromAgentRoot();\n\tmigrateToolsToBin();\n\tmigrateKeybindingsConfigFile();\n\tconst deprecationWarnings = migrateExtensionSystem(cwd);\n\treturn { migratedAuthProviders, deprecationWarnings };\n}\n"]}
1
+ {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * One-time migrations that run on startup.\n */\n\nimport chalk from \"chalk\";\nimport { chmodSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport { CONFIG_DIR_NAME, getAgentDir, getBinDir } from \"./config.ts\";\nimport { migrateKeybindingsConfig } from \"./core/keybindings.ts\";\nimport { isLegacyEnvVarNameConfigValue } from \"./core/resolve-config-value.ts\";\nimport { stripJsonComments } from \"./utils/json.ts\";\n\nconst MIGRATION_GUIDE_URL =\n\t\"https://github.com/dmae97/omk/blob/main/packages/coding-agent/CHANGELOG.md#extensions-migration\";\nconst EXTENSIONS_DOC_URL = \"https://github.com/dmae97/omk/blob/main/packages/coding-agent/docs/extensions.md\";\n\n/**\n * Migrate legacy oauth.json and settings.json apiKeys to auth.json.\n *\n * @returns Array of provider names that were migrated\n */\nexport function migrateAuthToAuthJson(): string[] {\n\tconst agentDir = getAgentDir();\n\tconst authPath = join(agentDir, \"auth.json\");\n\tconst oauthPath = join(agentDir, \"oauth.json\");\n\tconst settingsPath = join(agentDir, \"settings.json\");\n\n\t// Skip if auth.json already exists\n\tif (existsSync(authPath)) return [];\n\n\tconst migrated: Record<string, unknown> = {};\n\tconst providers: string[] = [];\n\n\t// Migrate oauth.json\n\tif (existsSync(oauthPath)) {\n\t\ttry {\n\t\t\tconst oauth = JSON.parse(readFileSync(oauthPath, \"utf-8\"));\n\t\t\tfor (const [provider, cred] of Object.entries(oauth)) {\n\t\t\t\tmigrated[provider] = { type: \"oauth\", ...(cred as object) };\n\t\t\t\tproviders.push(provider);\n\t\t\t}\n\t\t\trenameSync(oauthPath, `${oauthPath}.migrated`);\n\t\t} catch {\n\t\t\t// Skip on error\n\t\t}\n\t}\n\n\t// Migrate settings.json apiKeys\n\tif (existsSync(settingsPath)) {\n\t\ttry {\n\t\t\tconst content = readFileSync(settingsPath, \"utf-8\");\n\t\t\tconst settings = JSON.parse(content);\n\t\t\tif (settings.apiKeys && typeof settings.apiKeys === \"object\") {\n\t\t\t\tfor (const [provider, key] of Object.entries(settings.apiKeys)) {\n\t\t\t\t\tif (!migrated[provider] && typeof key === \"string\") {\n\t\t\t\t\t\tmigrated[provider] = { type: \"api_key\", key };\n\t\t\t\t\t\tproviders.push(provider);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdelete settings.apiKeys;\n\t\t\t\twriteFileSync(settingsPath, JSON.stringify(settings, null, 2));\n\t\t\t}\n\t\t} catch {\n\t\t\t// Skip on error\n\t\t}\n\t}\n\n\tif (Object.keys(migrated).length > 0) {\n\t\tmkdirSync(dirname(authPath), { recursive: true });\n\t\twriteFileSync(authPath, JSON.stringify(migrated, null, 2), { mode: 0o600 });\n\t}\n\n\treturn providers;\n}\n\ninterface ConfigValueMigration {\n\tlocation: string;\n\tfrom: string;\n\tto: string;\n}\n\nfunction migrateLegacyEnvVarString(value: string): string | undefined {\n\treturn isLegacyEnvVarNameConfigValue(value) ? `$${value}` : undefined;\n}\n\nfunction migrateStringProperty(\n\trecord: Record<string, unknown>,\n\tkey: string,\n\tlocation: string,\n\tmigrations: ConfigValueMigration[],\n): boolean {\n\tconst value = record[key];\n\tif (typeof value !== \"string\") return false;\n\tconst migrated = migrateLegacyEnvVarString(value);\n\tif (migrated === undefined) return false;\n\trecord[key] = migrated;\n\tmigrations.push({ location, from: value, to: migrated });\n\treturn true;\n}\n\nfunction migrateHeadersConfig(headers: unknown, location: string, migrations: ConfigValueMigration[]): boolean {\n\tif (typeof headers !== \"object\" || headers === null || Array.isArray(headers)) return false;\n\tconst headerRecord = headers as Record<string, unknown>;\n\tlet migrated = false;\n\tfor (const [key, value] of Object.entries(headerRecord)) {\n\t\tif (typeof value !== \"string\") continue;\n\t\tconst migratedValue = migrateLegacyEnvVarString(value);\n\t\tif (migratedValue === undefined) continue;\n\t\theaderRecord[key] = migratedValue;\n\t\tmigrations.push({ location: `${location}[${JSON.stringify(key)}]`, from: value, to: migratedValue });\n\t\tmigrated = true;\n\t}\n\treturn migrated;\n}\n\nfunction migrateAuthJsonConfigValues(agentDir: string): ConfigValueMigration[] {\n\tconst authPath = join(agentDir, \"auth.json\");\n\tif (!existsSync(authPath)) return [];\n\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(authPath, \"utf-8\")) as unknown;\n\t\tif (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) return [];\n\t\tconst authData = parsed as Record<string, unknown>;\n\n\t\tconst migrations: ConfigValueMigration[] = [];\n\t\tfor (const [provider, credential] of Object.entries(authData)) {\n\t\t\tif (typeof credential !== \"object\" || credential === null || Array.isArray(credential)) continue;\n\t\t\tconst credentialRecord = credential as Record<string, unknown>;\n\t\t\tif (credentialRecord.type !== \"api_key\") continue;\n\t\t\tmigrateStringProperty(credentialRecord, \"key\", `auth.json[${JSON.stringify(provider)}].key`, migrations);\n\t\t}\n\n\t\tif (migrations.length === 0) return [];\n\t\twriteFileSync(authPath, `${JSON.stringify(parsed, null, 2)}\\n`, \"utf-8\");\n\t\tchmodSync(authPath, 0o600);\n\t\treturn migrations;\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nfunction migrateModelsJsonConfigValues(agentDir: string): ConfigValueMigration[] {\n\tconst modelsPath = join(agentDir, \"models.json\");\n\tif (!existsSync(modelsPath)) return [];\n\n\tconst parsed = JSON.parse(stripJsonComments(readFileSync(modelsPath, \"utf-8\"))) as unknown;\n\tif (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) return [];\n\tconst modelsData = parsed as Record<string, unknown>;\n\tconst providers = modelsData.providers;\n\tif (typeof providers !== \"object\" || providers === null || Array.isArray(providers)) return [];\n\n\tconst migrations: ConfigValueMigration[] = [];\n\tfor (const [provider, providerConfig] of Object.entries(providers)) {\n\t\tif (typeof providerConfig !== \"object\" || providerConfig === null || Array.isArray(providerConfig)) continue;\n\t\tconst providerRecord = providerConfig as Record<string, unknown>;\n\t\tconst providerLocation = `models.json.providers[${JSON.stringify(provider)}]`;\n\t\tmigrateStringProperty(providerRecord, \"apiKey\", `${providerLocation}.apiKey`, migrations);\n\t\tmigrateHeadersConfig(providerRecord.headers, `${providerLocation}.headers`, migrations);\n\n\t\tif (Array.isArray(providerRecord.models)) {\n\t\t\tfor (let index = 0; index < providerRecord.models.length; index++) {\n\t\t\t\tconst modelConfig = providerRecord.models[index];\n\t\t\t\tif (typeof modelConfig !== \"object\" || modelConfig === null || Array.isArray(modelConfig)) continue;\n\t\t\t\tconst modelRecord = modelConfig as Record<string, unknown>;\n\t\t\t\tconst modelKey = typeof modelRecord.id === \"string\" ? JSON.stringify(modelRecord.id) : String(index);\n\t\t\t\tmigrateHeadersConfig(modelRecord.headers, `${providerLocation}.models[${modelKey}].headers`, migrations);\n\t\t\t}\n\t\t}\n\n\t\tconst modelOverrides = providerRecord.modelOverrides;\n\t\tif (typeof modelOverrides === \"object\" && modelOverrides !== null && !Array.isArray(modelOverrides)) {\n\t\t\tfor (const [modelId, modelOverride] of Object.entries(modelOverrides)) {\n\t\t\t\tif (typeof modelOverride !== \"object\" || modelOverride === null || Array.isArray(modelOverride)) continue;\n\t\t\t\tconst modelOverrideRecord = modelOverride as Record<string, unknown>;\n\t\t\t\tmigrateHeadersConfig(\n\t\t\t\t\tmodelOverrideRecord.headers,\n\t\t\t\t\t`${providerLocation}.modelOverrides[${JSON.stringify(modelId)}].headers`,\n\t\t\t\t\tmigrations,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (migrations.length === 0) return [];\n\twriteFileSync(modelsPath, `${JSON.stringify(parsed, null, 2)}\\n`, \"utf-8\");\n\treturn migrations;\n}\n\nfunction migrateExplicitEnvVarConfigValues(): void {\n\tconst agentDir = getAgentDir();\n\tconst migrations = [...migrateAuthJsonConfigValues(agentDir), ...migrateModelsJsonConfigValues(agentDir)];\n\tif (migrations.length === 0) return;\n\n\tconst details = migrations.map((migration) => ` - ${migration.location}: ${migration.from} -> ${migration.to}`);\n\tconsole.log(\n\t\tchalk.yellow(\n\t\t\t[\n\t\t\t\t\"Warning: Migrated API key/header environment references to explicit $ENV_VAR syntax. Plain strings will be treated as literals.\",\n\t\t\t\t...details,\n\t\t\t].join(\"\\n\"),\n\t\t),\n\t);\n}\n\n/**\n * Migrate sessions from ~/.omk/agent/*.jsonl to proper session directories.\n *\n * Bug in v0.30.0: Sessions were saved to ~/.omk/agent/ instead of\n * ~/.omk/agent/sessions/<encoded-cwd>/. This migration moves them\n * to the correct location based on the cwd in their session header.\n */\nexport function migrateSessionsFromAgentRoot(): void {\n\tconst agentDir = getAgentDir();\n\n\t// Find all .jsonl files directly in agentDir (not in subdirectories)\n\tlet files: string[];\n\ttry {\n\t\tfiles = readdirSync(agentDir)\n\t\t\t.filter((f) => f.endsWith(\".jsonl\"))\n\t\t\t.map((f) => join(agentDir, f));\n\t} catch {\n\t\treturn;\n\t}\n\n\tif (files.length === 0) return;\n\n\tfor (const file of files) {\n\t\ttry {\n\t\t\t// Read first line to get session header\n\t\t\tconst content = readFileSync(file, \"utf8\");\n\t\t\tconst firstLine = content.split(\"\\n\")[0];\n\t\t\tif (!firstLine?.trim()) continue;\n\n\t\t\tconst header = JSON.parse(firstLine);\n\t\t\tif (header.type !== \"session\" || !header.cwd) continue;\n\n\t\t\tconst cwd: string = header.cwd;\n\n\t\t\t// Compute the correct session directory (same encoding as session-manager.ts)\n\t\t\tconst safePath = `--${cwd.replace(/^[/\\\\]/, \"\").replace(/[/\\\\:]/g, \"-\")}--`;\n\t\t\tconst correctDir = join(agentDir, \"sessions\", safePath);\n\n\t\t\t// Create directory if needed\n\t\t\tif (!existsSync(correctDir)) {\n\t\t\t\tmkdirSync(correctDir, { recursive: true });\n\t\t\t}\n\n\t\t\t// Move the file\n\t\t\tconst fileName = file.split(\"/\").pop() || file.split(\"\\\\\").pop();\n\t\t\tconst newPath = join(correctDir, fileName!);\n\n\t\t\tif (existsSync(newPath)) continue; // Skip if target exists\n\n\t\t\trenameSync(file, newPath);\n\t\t} catch {\n\t\t\t// Skip files that can't be migrated\n\t\t}\n\t}\n}\n\n/**\n * Migrate commands/ to prompts/ if needed.\n * Works for both regular directories and symlinks.\n */\nfunction migrateCommandsToPrompts(baseDir: string, label: string): boolean {\n\tconst commandsDir = join(baseDir, \"commands\");\n\tconst promptsDir = join(baseDir, \"prompts\");\n\n\tif (existsSync(commandsDir) && !existsSync(promptsDir)) {\n\t\ttry {\n\t\t\trenameSync(commandsDir, promptsDir);\n\t\t\tconsole.log(chalk.green(`Migrated ${label} commands/ → prompts/`));\n\t\t\treturn true;\n\t\t} catch (err) {\n\t\t\tconsole.log(\n\t\t\t\tchalk.yellow(\n\t\t\t\t\t`Warning: Could not migrate ${label} commands/ to prompts/: ${err instanceof Error ? err.message : err}`,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n\treturn false;\n}\n\nfunction migrateKeybindingsConfigFile(): void {\n\tconst configPath = join(getAgentDir(), \"keybindings.json\");\n\tif (!existsSync(configPath)) return;\n\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(configPath, \"utf-8\")) as unknown;\n\t\tif (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tconst { config, migrated } = migrateKeybindingsConfig(parsed as Record<string, unknown>);\n\t\tif (!migrated) return;\n\t\twriteFileSync(configPath, `${JSON.stringify(config, null, 2)}\\n`, \"utf-8\");\n\t} catch {\n\t\t// Ignore malformed files during migration\n\t}\n}\n\n/**\n * Move fd/rg binaries from tools/ to bin/ if they exist.\n */\nfunction migrateToolsToBin(): void {\n\tconst agentDir = getAgentDir();\n\tconst toolsDir = join(agentDir, \"tools\");\n\tconst binDir = getBinDir();\n\n\tif (!existsSync(toolsDir)) return;\n\n\tconst binaries = [\"fd\", \"rg\", \"fd.exe\", \"rg.exe\"];\n\tlet movedAny = false;\n\n\tfor (const bin of binaries) {\n\t\tconst oldPath = join(toolsDir, bin);\n\t\tconst newPath = join(binDir, bin);\n\n\t\tif (existsSync(oldPath)) {\n\t\t\tif (!existsSync(binDir)) {\n\t\t\t\tmkdirSync(binDir, { recursive: true });\n\t\t\t}\n\t\t\tif (!existsSync(newPath)) {\n\t\t\t\ttry {\n\t\t\t\t\trenameSync(oldPath, newPath);\n\t\t\t\t\tmovedAny = true;\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore errors\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Target exists, just delete the old one\n\t\t\t\ttry {\n\t\t\t\t\trmSync?.(oldPath, { force: true });\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (movedAny) {\n\t\tconsole.log(chalk.green(`Migrated managed binaries tools/ → bin/`));\n\t}\n}\n\n/**\n * Archive a legacy `hooks/` directory by renaming it to `hooks.migrated/`.\n *\n * Used for project-level hooks, which are never loaded or executed: the shell-hook\n * inventory only scans the global agent directory, and built-in hooks take precedence\n * on name collisions. Renaming is reversible and preserves the scripts.\n *\n * @returns The archived directory path, or null if there was nothing to archive (or the rename failed).\n */\nexport function archiveLegacyHooksDir(baseDir: string): string | null {\n\tconst hooksDir = join(baseDir, \"hooks\");\n\tif (!existsSync(hooksDir)) return null;\n\n\tlet target = join(baseDir, \"hooks.migrated\");\n\tif (existsSync(target)) {\n\t\ttarget = join(baseDir, `hooks.migrated.${Date.now()}`);\n\t}\n\n\ttry {\n\t\trenameSync(hooksDir, target);\n\t\treturn target;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Check for deprecated hooks/ and tools/ directories.\n * Project-level hooks/ (`autoArchiveHooks`) are archived automatically because project shell hooks\n * are never executed; global hooks/ may still be live via the hook inventory, so it stays a warning.\n * Note: tools/ may contain legacy auto-extracted fd/rg binaries, so only warn if it has other files.\n */\nexport function checkDeprecatedExtensionDirs(\n\tbaseDir: string,\n\tlabel: string,\n\toptions?: { autoArchiveHooks?: boolean },\n): string[] {\n\tconst hooksDir = join(baseDir, \"hooks\");\n\tconst toolsDir = join(baseDir, \"tools\");\n\tconst warnings: string[] = [];\n\n\tif (existsSync(hooksDir)) {\n\t\tconst archived = options?.autoArchiveHooks ? archiveLegacyHooksDir(baseDir) : null;\n\t\tif (archived) {\n\t\t\tconsole.log(\n\t\t\t\tchalk.dim(\n\t\t\t\t\t`Archived legacy ${label.toLowerCase()} hooks/ directory to ${archived} (shell hooks are superseded by extensions).`,\n\t\t\t\t),\n\t\t\t);\n\t\t} else {\n\t\t\twarnings.push(`${label} hooks/ directory found. Hooks have been renamed to extensions.`);\n\t\t}\n\t}\n\n\tif (existsSync(toolsDir)) {\n\t\t// Check if tools/ contains anything other than fd/rg (which are auto-extracted binaries)\n\t\ttry {\n\t\t\tconst entries = readdirSync(toolsDir);\n\t\t\tconst customTools = entries.filter((e) => {\n\t\t\t\tconst lower = e.toLowerCase();\n\t\t\t\treturn (\n\t\t\t\t\tlower !== \"fd\" && lower !== \"rg\" && lower !== \"fd.exe\" && lower !== \"rg.exe\" && !e.startsWith(\".\") // Ignore .DS_Store and other hidden files\n\t\t\t\t);\n\t\t\t});\n\t\t\tif (customTools.length > 0) {\n\t\t\t\twarnings.push(\n\t\t\t\t\t`${label} tools/ directory contains custom tools. Custom tools have been merged into extensions.`,\n\t\t\t\t);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore read errors\n\t\t}\n\t}\n\n\treturn warnings;\n}\n\n/**\n * Run extension system migrations (commands→prompts) and collect warnings about deprecated directories.\n */\nfunction migrateExtensionSystem(cwd: string): string[] {\n\tconst agentDir = getAgentDir();\n\tconst projectDir = join(cwd, CONFIG_DIR_NAME);\n\n\t// Migrate commands/ to prompts/\n\tmigrateCommandsToPrompts(agentDir, \"Global\");\n\tmigrateCommandsToPrompts(projectDir, \"Project\");\n\n\t// Check for deprecated directories. Project hooks/ are archived automatically (never executed);\n\t// global hooks/ may still be live, so it remains a non-blocking warning.\n\tconst warnings = [\n\t\t...checkDeprecatedExtensionDirs(agentDir, \"Global\", { autoArchiveHooks: false }),\n\t\t...checkDeprecatedExtensionDirs(projectDir, \"Project\", { autoArchiveHooks: true }),\n\t];\n\n\treturn warnings;\n}\n\n/**\n * Print deprecation warnings and wait for keypress.\n */\nexport async function showDeprecationWarnings(warnings: string[]): Promise<void> {\n\tif (warnings.length === 0) return;\n\n\tfor (const warning of warnings) {\n\t\tconsole.log(chalk.yellow(`Warning: ${warning}`));\n\t}\n\tconsole.log(chalk.yellow(`\\nMove your extensions to the extensions/ directory.`));\n\tconsole.log(chalk.yellow(`Migration guide: ${MIGRATION_GUIDE_URL}`));\n\tconsole.log(chalk.yellow(`Documentation: ${EXTENSIONS_DOC_URL}`));\n\tconsole.log();\n}\n\n/**\n * Run all migrations. Called once on startup.\n *\n * @returns Object with migration results and deprecation warnings\n */\nexport function runMigrations(cwd: string): {\n\tmigratedAuthProviders: string[];\n\tdeprecationWarnings: string[];\n} {\n\tconst migratedAuthProviders = migrateAuthToAuthJson();\n\tmigrateExplicitEnvVarConfigValues();\n\tmigrateSessionsFromAgentRoot();\n\tmigrateToolsToBin();\n\tmigrateKeybindingsConfigFile();\n\tconst deprecationWarnings = migrateExtensionSystem(cwd);\n\treturn { migratedAuthProviders, deprecationWarnings };\n}\n"]}
@@ -1,8 +1,8 @@
1
1
  import { type ThemeColor } from "../theme/theme.ts";
2
2
  export declare function composeColumns(leftLines: string[], leftWidth: number, rightLines: string[], rightWidth: number, gapWidth: number, width: number): string[];
3
- export declare function sidebarRule(width: number, label: string): string;
4
- export declare function boxTop(width: number, label: string): string;
5
- export declare function boxBottom(width: number): string;
3
+ export declare function sidebarRule(width: number, label: string, borderColor?: ThemeColor): string;
4
+ export declare function boxTop(width: number, label: string, borderColor?: ThemeColor): string;
5
+ export declare function boxBottom(width: number, borderColor?: ThemeColor): string;
6
6
  export declare function boxBlankLine(width: number): string;
7
7
  export declare function boxCenteredLine(width: number, text: string, color?: ThemeColor): string;
8
8
  export declare function boxTextLine(width: number, text: string, color?: ThemeColor): string;
@@ -1 +1 @@
1
- {"version":3,"file":"control-panel-box.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/control-panel-box.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAS,MAAM,mBAAmB,CAAC;AAE3D,wBAAgB,cAAc,CAC7B,SAAS,EAAE,MAAM,EAAE,EACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAAE,EACpB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACX,MAAM,EAAE,CAOV;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAUhE;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAO3D;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,CAEvF;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,CAMnF;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,CAElF;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAI9D;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM,CAM/E;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,CAGhF;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE5D","sourcesContent":["import { truncateToWidth, visibleWidth } from \"omk-tui\";\nimport { type ThemeColor, theme } from \"../theme/theme.ts\";\n\nexport function composeColumns(\n\tleftLines: string[],\n\tleftWidth: number,\n\trightLines: string[],\n\trightWidth: number,\n\tgapWidth: number,\n\twidth: number,\n): string[] {\n\treturn Array.from({ length: Math.max(leftLines.length, rightLines.length) }, (_, index) =>\n\t\tclipLine(\n\t\t\t`${fitLine(leftLines[index] ?? \"\", leftWidth)}${\" \".repeat(gapWidth)}${fitLine(rightLines[index] ?? \"\", rightWidth)}`,\n\t\t\twidth,\n\t\t),\n\t);\n}\n\nexport function sidebarRule(width: number, label: string): string {\n\tconst bodyWidth = Math.max(0, width - 2);\n\tconst labelText = ` ${label} `;\n\tconst fill = Math.max(0, bodyWidth - visibleWidth(labelText));\n\tconst left = Math.floor(fill / 2);\n\tconst right = fill - left;\n\treturn clipLine(\n\t\t`${theme.fg(\"border\", \"|\")}${theme.fg(\"borderMuted\", \"-\".repeat(left))}${theme.bold(theme.fg(\"accent\", labelText))}${theme.fg(\"borderMuted\", \"-\".repeat(right))}${theme.fg(\"border\", \"|\")}`,\n\t\twidth,\n\t);\n}\n\nexport function boxTop(width: number, label: string): string {\n\tconst text = ` ${label} `;\n\tconst fillWidth = Math.max(0, width - visibleWidth(\"+\") - visibleWidth(text) - visibleWidth(\"+\"));\n\treturn clipLine(\n\t\t`${theme.fg(\"border\", \"+\")}${theme.bold(theme.fg(\"accent\", text))}${theme.fg(\"border\", \"-\".repeat(fillWidth))}${theme.fg(\"border\", \"+\")}`,\n\t\twidth,\n\t);\n}\n\nexport function boxBottom(width: number): string {\n\treturn clipLine(theme.fg(\"border\", `+${\"-\".repeat(Math.max(0, width - 2))}+`), width);\n}\n\nexport function boxBlankLine(width: number): string {\n\treturn boxTextLine(width, \"\");\n}\n\nexport function boxCenteredLine(width: number, text: string, color?: ThemeColor): string {\n\treturn boxTextLine(width, centerText(Math.max(0, width - 4), color ? theme.fg(color, text) : text));\n}\n\nexport function boxTextLine(width: number, text: string, color?: ThemeColor): string {\n\tconst body = color ? theme.fg(color, text) : text;\n\treturn clipLine(\n\t\t`${theme.fg(\"border\", \"| \")}${fitLine(body, Math.max(0, width - 4))}${theme.fg(\"border\", \" |\")}`,\n\t\twidth,\n\t);\n}\n\nexport function centerLine(width: number, text: string, color?: ThemeColor): string {\n\treturn clipLine(centerText(width, color ? theme.fg(color, text) : text), width);\n}\n\nexport function centerText(width: number, text: string): string {\n\tconst fitted = truncateToWidth(text, width, \"\");\n\tconst remaining = Math.max(0, width - visibleWidth(fitted));\n\treturn `${\" \".repeat(Math.floor(remaining / 2))}${fitted}${\" \".repeat(Math.ceil(remaining / 2))}`;\n}\n\nexport function divider(width: number, label: string, color: ThemeColor): string {\n\tconst fillWidth = Math.max(0, width - visibleWidth(\"+-- \") - visibleWidth(label) - 1);\n\treturn clipLine(\n\t\t`${theme.fg(\"border\", \"+-- \")}${theme.bold(theme.fg(color, label))}${theme.fg(\"border\", ` ${\"-\".repeat(fillWidth)}`)}`,\n\t\twidth,\n\t);\n}\n\nexport function textLine(width: number, text: string, color?: ThemeColor): string {\n\tconst body = color ? theme.fg(color, text) : text;\n\treturn clipLine(`${theme.fg(\"borderMuted\", \"| \")}${body}`, width);\n}\n\nexport function fitLine(line: string, width: number): string {\n\tconst clipped = truncateToWidth(line, width, \"\");\n\treturn `${clipped}${\" \".repeat(Math.max(0, width - visibleWidth(clipped)))}`;\n}\n\nexport function clipLine(line: string, width: number): string {\n\treturn visibleWidth(line) <= width ? line : truncateToWidth(line, width, \"\");\n}\n"]}
1
+ {"version":3,"file":"control-panel-box.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/control-panel-box.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAS,MAAM,mBAAmB,CAAC;AAE3D,wBAAgB,cAAc,CAC7B,SAAS,EAAE,MAAM,EAAE,EACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAAE,EACpB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACX,MAAM,EAAE,CAOV;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,GAAE,UAA2B,GAAG,MAAM,CAU1G;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,GAAE,UAA2B,GAAG,MAAM,CAOrG;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,GAAE,UAA2B,GAAG,MAAM,CAEzF;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,CAEvF;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,CAMnF;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,CAElF;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAI9D;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM,CAM/E;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,CAMhF;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE5D","sourcesContent":["import { truncateToWidth, visibleWidth } from \"omk-tui\";\nimport { type ThemeColor, theme } from \"../theme/theme.ts\";\n\nexport function composeColumns(\n\tleftLines: string[],\n\tleftWidth: number,\n\trightLines: string[],\n\trightWidth: number,\n\tgapWidth: number,\n\twidth: number,\n): string[] {\n\treturn Array.from({ length: Math.max(leftLines.length, rightLines.length) }, (_, index) =>\n\t\tclipLine(\n\t\t\t`${fitLine(leftLines[index] ?? \"\", leftWidth)}${\" \".repeat(gapWidth)}${fitLine(rightLines[index] ?? \"\", rightWidth)}`,\n\t\t\twidth,\n\t\t),\n\t);\n}\n\nexport function sidebarRule(width: number, label: string, borderColor: ThemeColor = \"borderAccent\"): string {\n\tconst bodyWidth = Math.max(0, width - 2);\n\tconst labelText = ` ${label} `;\n\tconst fill = Math.max(0, bodyWidth - visibleWidth(labelText));\n\tconst left = Math.floor(fill / 2);\n\tconst right = fill - left;\n\treturn clipLine(\n\t\t`${theme.fg(borderColor, \"\\u2502\")}${theme.fg(\"borderMuted\", \"\\u2500\".repeat(left))}${theme.bold(theme.fg(\"accent\", labelText))}${theme.fg(\"borderMuted\", \"\\u2500\".repeat(right))}${theme.fg(borderColor, \"\\u2502\")}`,\n\t\twidth,\n\t);\n}\n\nexport function boxTop(width: number, label: string, borderColor: ThemeColor = \"borderAccent\"): string {\n\tconst text = ` ${label} `;\n\tconst fillWidth = Math.max(0, width - visibleWidth(\"+\") - visibleWidth(text) - visibleWidth(\"+\"));\n\treturn clipLine(\n\t\t`${theme.fg(borderColor, \"\\u256d\")}${theme.bold(theme.fg(\"accent\", text))}${theme.fg(borderColor, \"\\u2500\".repeat(fillWidth))}${theme.fg(borderColor, \"\\u256e\")}`,\n\t\twidth,\n\t);\n}\n\nexport function boxBottom(width: number, borderColor: ThemeColor = \"borderAccent\"): string {\n\treturn clipLine(theme.fg(borderColor, `\\u2570${\"\\u2500\".repeat(Math.max(0, width - 2))}\\u256f`), width);\n}\n\nexport function boxBlankLine(width: number): string {\n\treturn boxTextLine(width, \"\");\n}\n\nexport function boxCenteredLine(width: number, text: string, color?: ThemeColor): string {\n\treturn boxTextLine(width, centerText(Math.max(0, width - 4), color ? theme.fg(color, text) : text));\n}\n\nexport function boxTextLine(width: number, text: string, color?: ThemeColor): string {\n\tconst body = color ? theme.fg(color, text) : text;\n\treturn clipLine(\n\t\t`${theme.fg(\"borderAccent\", \"\\u2502 \")}${fitLine(body, Math.max(0, width - 4))}${theme.fg(\"borderAccent\", \" \\u2502\")}`,\n\t\twidth,\n\t);\n}\n\nexport function centerLine(width: number, text: string, color?: ThemeColor): string {\n\treturn clipLine(centerText(width, color ? theme.fg(color, text) : text), width);\n}\n\nexport function centerText(width: number, text: string): string {\n\tconst fitted = truncateToWidth(text, width, \"\");\n\tconst remaining = Math.max(0, width - visibleWidth(fitted));\n\treturn `${\" \".repeat(Math.floor(remaining / 2))}${fitted}${\" \".repeat(Math.ceil(remaining / 2))}`;\n}\n\nexport function divider(width: number, label: string, color: ThemeColor): string {\n\tconst fillWidth = Math.max(0, width - visibleWidth(\"+-- \") - visibleWidth(label) - visibleWidth(\" +\"));\n\treturn clipLine(\n\t\t`${theme.fg(\"border\", \"+-- \")}${theme.bold(theme.fg(color, label))}${theme.fg(\"border\", ` ${\"-\".repeat(fillWidth)}+`)}`,\n\t\twidth,\n\t);\n}\n\nexport function textLine(width: number, text: string, color?: ThemeColor): string {\n\tconst body = color ? theme.fg(color, text) : text;\n\treturn clipLine(\n\t\t`${theme.fg(\"borderMuted\", \"\\u2502 \")}${fitLine(body, Math.max(0, width - 4))}${theme.fg(\"borderMuted\", \" \\u2502\")}`,\n\t\twidth,\n\t);\n}\n\nexport function fitLine(line: string, width: number): string {\n\tconst clipped = truncateToWidth(line, width, \"\");\n\treturn `${clipped}${\" \".repeat(Math.max(0, width - visibleWidth(clipped)))}`;\n}\n\nexport function clipLine(line: string, width: number): string {\n\treturn visibleWidth(line) <= width ? line : truncateToWidth(line, width, \"\");\n}\n"]}
@@ -3,21 +3,21 @@ import { theme } from "../theme/theme.js";
3
3
  export function composeColumns(leftLines, leftWidth, rightLines, rightWidth, gapWidth, width) {
4
4
  return Array.from({ length: Math.max(leftLines.length, rightLines.length) }, (_, index) => clipLine(`${fitLine(leftLines[index] ?? "", leftWidth)}${" ".repeat(gapWidth)}${fitLine(rightLines[index] ?? "", rightWidth)}`, width));
5
5
  }
6
- export function sidebarRule(width, label) {
6
+ export function sidebarRule(width, label, borderColor = "borderAccent") {
7
7
  const bodyWidth = Math.max(0, width - 2);
8
8
  const labelText = ` ${label} `;
9
9
  const fill = Math.max(0, bodyWidth - visibleWidth(labelText));
10
10
  const left = Math.floor(fill / 2);
11
11
  const right = fill - left;
12
- return clipLine(`${theme.fg("border", "|")}${theme.fg("borderMuted", "-".repeat(left))}${theme.bold(theme.fg("accent", labelText))}${theme.fg("borderMuted", "-".repeat(right))}${theme.fg("border", "|")}`, width);
12
+ return clipLine(`${theme.fg(borderColor, "\u2502")}${theme.fg("borderMuted", "\u2500".repeat(left))}${theme.bold(theme.fg("accent", labelText))}${theme.fg("borderMuted", "\u2500".repeat(right))}${theme.fg(borderColor, "\u2502")}`, width);
13
13
  }
14
- export function boxTop(width, label) {
14
+ export function boxTop(width, label, borderColor = "borderAccent") {
15
15
  const text = ` ${label} `;
16
16
  const fillWidth = Math.max(0, width - visibleWidth("+") - visibleWidth(text) - visibleWidth("+"));
17
- return clipLine(`${theme.fg("border", "+")}${theme.bold(theme.fg("accent", text))}${theme.fg("border", "-".repeat(fillWidth))}${theme.fg("border", "+")}`, width);
17
+ return clipLine(`${theme.fg(borderColor, "\u256d")}${theme.bold(theme.fg("accent", text))}${theme.fg(borderColor, "\u2500".repeat(fillWidth))}${theme.fg(borderColor, "\u256e")}`, width);
18
18
  }
19
- export function boxBottom(width) {
20
- return clipLine(theme.fg("border", `+${"-".repeat(Math.max(0, width - 2))}+`), width);
19
+ export function boxBottom(width, borderColor = "borderAccent") {
20
+ return clipLine(theme.fg(borderColor, `\u2570${"\u2500".repeat(Math.max(0, width - 2))}\u256f`), width);
21
21
  }
22
22
  export function boxBlankLine(width) {
23
23
  return boxTextLine(width, "");
@@ -27,7 +27,7 @@ export function boxCenteredLine(width, text, color) {
27
27
  }
28
28
  export function boxTextLine(width, text, color) {
29
29
  const body = color ? theme.fg(color, text) : text;
30
- return clipLine(`${theme.fg("border", "| ")}${fitLine(body, Math.max(0, width - 4))}${theme.fg("border", " |")}`, width);
30
+ return clipLine(`${theme.fg("borderAccent", "\u2502 ")}${fitLine(body, Math.max(0, width - 4))}${theme.fg("borderAccent", " \u2502")}`, width);
31
31
  }
32
32
  export function centerLine(width, text, color) {
33
33
  return clipLine(centerText(width, color ? theme.fg(color, text) : text), width);
@@ -38,12 +38,12 @@ export function centerText(width, text) {
38
38
  return `${" ".repeat(Math.floor(remaining / 2))}${fitted}${" ".repeat(Math.ceil(remaining / 2))}`;
39
39
  }
40
40
  export function divider(width, label, color) {
41
- const fillWidth = Math.max(0, width - visibleWidth("+-- ") - visibleWidth(label) - 1);
42
- return clipLine(`${theme.fg("border", "+-- ")}${theme.bold(theme.fg(color, label))}${theme.fg("border", ` ${"-".repeat(fillWidth)}`)}`, width);
41
+ const fillWidth = Math.max(0, width - visibleWidth("+-- ") - visibleWidth(label) - visibleWidth(" +"));
42
+ return clipLine(`${theme.fg("border", "+-- ")}${theme.bold(theme.fg(color, label))}${theme.fg("border", ` ${"-".repeat(fillWidth)}+`)}`, width);
43
43
  }
44
44
  export function textLine(width, text, color) {
45
45
  const body = color ? theme.fg(color, text) : text;
46
- return clipLine(`${theme.fg("borderMuted", "| ")}${body}`, width);
46
+ return clipLine(`${theme.fg("borderMuted", "\u2502 ")}${fitLine(body, Math.max(0, width - 4))}${theme.fg("borderMuted", " \u2502")}`, width);
47
47
  }
48
48
  export function fitLine(line, width) {
49
49
  const clipped = truncateToWidth(line, width, "");
@@ -1 +1 @@
1
- {"version":3,"file":"control-panel-box.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/control-panel-box.ts"],"names":[],"mappings":"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","sourcesContent":["import { truncateToWidth, visibleWidth } from \"omk-tui\";\nimport { type ThemeColor, theme } from \"../theme/theme.ts\";\n\nexport function composeColumns(\n\tleftLines: string[],\n\tleftWidth: number,\n\trightLines: string[],\n\trightWidth: number,\n\tgapWidth: number,\n\twidth: number,\n): string[] {\n\treturn Array.from({ length: Math.max(leftLines.length, rightLines.length) }, (_, index) =>\n\t\tclipLine(\n\t\t\t`${fitLine(leftLines[index] ?? \"\", leftWidth)}${\" \".repeat(gapWidth)}${fitLine(rightLines[index] ?? \"\", rightWidth)}`,\n\t\t\twidth,\n\t\t),\n\t);\n}\n\nexport function sidebarRule(width: number, label: string): string {\n\tconst bodyWidth = Math.max(0, width - 2);\n\tconst labelText = ` ${label} `;\n\tconst fill = Math.max(0, bodyWidth - visibleWidth(labelText));\n\tconst left = Math.floor(fill / 2);\n\tconst right = fill - left;\n\treturn clipLine(\n\t\t`${theme.fg(\"border\", \"|\")}${theme.fg(\"borderMuted\", \"-\".repeat(left))}${theme.bold(theme.fg(\"accent\", labelText))}${theme.fg(\"borderMuted\", \"-\".repeat(right))}${theme.fg(\"border\", \"|\")}`,\n\t\twidth,\n\t);\n}\n\nexport function boxTop(width: number, label: string): string {\n\tconst text = ` ${label} `;\n\tconst fillWidth = Math.max(0, width - visibleWidth(\"+\") - visibleWidth(text) - visibleWidth(\"+\"));\n\treturn clipLine(\n\t\t`${theme.fg(\"border\", \"+\")}${theme.bold(theme.fg(\"accent\", text))}${theme.fg(\"border\", \"-\".repeat(fillWidth))}${theme.fg(\"border\", \"+\")}`,\n\t\twidth,\n\t);\n}\n\nexport function boxBottom(width: number): string {\n\treturn clipLine(theme.fg(\"border\", `+${\"-\".repeat(Math.max(0, width - 2))}+`), width);\n}\n\nexport function boxBlankLine(width: number): string {\n\treturn boxTextLine(width, \"\");\n}\n\nexport function boxCenteredLine(width: number, text: string, color?: ThemeColor): string {\n\treturn boxTextLine(width, centerText(Math.max(0, width - 4), color ? theme.fg(color, text) : text));\n}\n\nexport function boxTextLine(width: number, text: string, color?: ThemeColor): string {\n\tconst body = color ? theme.fg(color, text) : text;\n\treturn clipLine(\n\t\t`${theme.fg(\"border\", \"| \")}${fitLine(body, Math.max(0, width - 4))}${theme.fg(\"border\", \" |\")}`,\n\t\twidth,\n\t);\n}\n\nexport function centerLine(width: number, text: string, color?: ThemeColor): string {\n\treturn clipLine(centerText(width, color ? theme.fg(color, text) : text), width);\n}\n\nexport function centerText(width: number, text: string): string {\n\tconst fitted = truncateToWidth(text, width, \"\");\n\tconst remaining = Math.max(0, width - visibleWidth(fitted));\n\treturn `${\" \".repeat(Math.floor(remaining / 2))}${fitted}${\" \".repeat(Math.ceil(remaining / 2))}`;\n}\n\nexport function divider(width: number, label: string, color: ThemeColor): string {\n\tconst fillWidth = Math.max(0, width - visibleWidth(\"+-- \") - visibleWidth(label) - 1);\n\treturn clipLine(\n\t\t`${theme.fg(\"border\", \"+-- \")}${theme.bold(theme.fg(color, label))}${theme.fg(\"border\", ` ${\"-\".repeat(fillWidth)}`)}`,\n\t\twidth,\n\t);\n}\n\nexport function textLine(width: number, text: string, color?: ThemeColor): string {\n\tconst body = color ? theme.fg(color, text) : text;\n\treturn clipLine(`${theme.fg(\"borderMuted\", \"| \")}${body}`, width);\n}\n\nexport function fitLine(line: string, width: number): string {\n\tconst clipped = truncateToWidth(line, width, \"\");\n\treturn `${clipped}${\" \".repeat(Math.max(0, width - visibleWidth(clipped)))}`;\n}\n\nexport function clipLine(line: string, width: number): string {\n\treturn visibleWidth(line) <= width ? line : truncateToWidth(line, width, \"\");\n}\n"]}
1
+ {"version":3,"file":"control-panel-box.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/control-panel-box.ts"],"names":[],"mappings":"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","sourcesContent":["import { truncateToWidth, visibleWidth } from \"omk-tui\";\nimport { type ThemeColor, theme } from \"../theme/theme.ts\";\n\nexport function composeColumns(\n\tleftLines: string[],\n\tleftWidth: number,\n\trightLines: string[],\n\trightWidth: number,\n\tgapWidth: number,\n\twidth: number,\n): string[] {\n\treturn Array.from({ length: Math.max(leftLines.length, rightLines.length) }, (_, index) =>\n\t\tclipLine(\n\t\t\t`${fitLine(leftLines[index] ?? \"\", leftWidth)}${\" \".repeat(gapWidth)}${fitLine(rightLines[index] ?? \"\", rightWidth)}`,\n\t\t\twidth,\n\t\t),\n\t);\n}\n\nexport function sidebarRule(width: number, label: string, borderColor: ThemeColor = \"borderAccent\"): string {\n\tconst bodyWidth = Math.max(0, width - 2);\n\tconst labelText = ` ${label} `;\n\tconst fill = Math.max(0, bodyWidth - visibleWidth(labelText));\n\tconst left = Math.floor(fill / 2);\n\tconst right = fill - left;\n\treturn clipLine(\n\t\t`${theme.fg(borderColor, \"\\u2502\")}${theme.fg(\"borderMuted\", \"\\u2500\".repeat(left))}${theme.bold(theme.fg(\"accent\", labelText))}${theme.fg(\"borderMuted\", \"\\u2500\".repeat(right))}${theme.fg(borderColor, \"\\u2502\")}`,\n\t\twidth,\n\t);\n}\n\nexport function boxTop(width: number, label: string, borderColor: ThemeColor = \"borderAccent\"): string {\n\tconst text = ` ${label} `;\n\tconst fillWidth = Math.max(0, width - visibleWidth(\"+\") - visibleWidth(text) - visibleWidth(\"+\"));\n\treturn clipLine(\n\t\t`${theme.fg(borderColor, \"\\u256d\")}${theme.bold(theme.fg(\"accent\", text))}${theme.fg(borderColor, \"\\u2500\".repeat(fillWidth))}${theme.fg(borderColor, \"\\u256e\")}`,\n\t\twidth,\n\t);\n}\n\nexport function boxBottom(width: number, borderColor: ThemeColor = \"borderAccent\"): string {\n\treturn clipLine(theme.fg(borderColor, `\\u2570${\"\\u2500\".repeat(Math.max(0, width - 2))}\\u256f`), width);\n}\n\nexport function boxBlankLine(width: number): string {\n\treturn boxTextLine(width, \"\");\n}\n\nexport function boxCenteredLine(width: number, text: string, color?: ThemeColor): string {\n\treturn boxTextLine(width, centerText(Math.max(0, width - 4), color ? theme.fg(color, text) : text));\n}\n\nexport function boxTextLine(width: number, text: string, color?: ThemeColor): string {\n\tconst body = color ? theme.fg(color, text) : text;\n\treturn clipLine(\n\t\t`${theme.fg(\"borderAccent\", \"\\u2502 \")}${fitLine(body, Math.max(0, width - 4))}${theme.fg(\"borderAccent\", \" \\u2502\")}`,\n\t\twidth,\n\t);\n}\n\nexport function centerLine(width: number, text: string, color?: ThemeColor): string {\n\treturn clipLine(centerText(width, color ? theme.fg(color, text) : text), width);\n}\n\nexport function centerText(width: number, text: string): string {\n\tconst fitted = truncateToWidth(text, width, \"\");\n\tconst remaining = Math.max(0, width - visibleWidth(fitted));\n\treturn `${\" \".repeat(Math.floor(remaining / 2))}${fitted}${\" \".repeat(Math.ceil(remaining / 2))}`;\n}\n\nexport function divider(width: number, label: string, color: ThemeColor): string {\n\tconst fillWidth = Math.max(0, width - visibleWidth(\"+-- \") - visibleWidth(label) - visibleWidth(\" +\"));\n\treturn clipLine(\n\t\t`${theme.fg(\"border\", \"+-- \")}${theme.bold(theme.fg(color, label))}${theme.fg(\"border\", ` ${\"-\".repeat(fillWidth)}+`)}`,\n\t\twidth,\n\t);\n}\n\nexport function textLine(width: number, text: string, color?: ThemeColor): string {\n\tconst body = color ? theme.fg(color, text) : text;\n\treturn clipLine(\n\t\t`${theme.fg(\"borderMuted\", \"\\u2502 \")}${fitLine(body, Math.max(0, width - 4))}${theme.fg(\"borderMuted\", \" \\u2502\")}`,\n\t\twidth,\n\t);\n}\n\nexport function fitLine(line: string, width: number): string {\n\tconst clipped = truncateToWidth(line, width, \"\");\n\treturn `${clipped}${\" \".repeat(Math.max(0, width - visibleWidth(clipped)))}`;\n}\n\nexport function clipLine(line: string, width: number): string {\n\treturn visibleWidth(line) <= width ? line : truncateToWidth(line, width, \"\");\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"control-panel-gradient-motion.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/control-panel-gradient-motion.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,KAAK,iBAAiB,EAItB,MAAM,6BAA6B,CAAC;AAErC,eAAO,MAAM,QAAQ,MAAM,CAAC;AAC5B,eAAO,MAAM,OAAO,OAAO,CAAC;AAuC5B;;;GAGG;AACH,wBAAgB,kBAAkB,CACjC,GAAG,EAAE,MAAM,EAAE,EACb,IAAI,EAAE,iBAAiB,EACvB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GACf,MAAM,EAAE,CAsCV;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAChC,GAAG,EAAE,MAAM,EAAE,EACb,IAAI,EAAE,iBAAiB,EACvB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GACf,MAAM,EAAE,CAmBV;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE;IACtC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,iBAAiB,EAAE,OAAO,CAAC;IAC3B,gBAAgB,EAAE,OAAO,CAAC;CAC1B,GAAG,OAAO,CAKV","sourcesContent":["import {\n\tcolorAt,\n\tcomposeStaticBanner,\n\ttype GradientColorMode,\n\ttype GradientGeom,\n\tpaintGlyph,\n\tshouldGradient,\n} from \"./control-panel-gradient.ts\";\n\nexport const INTRO_MS = 900;\nexport const IDLE_MS = 6000;\nconst IDLE_PERIOD_MS = 4200;\nconst REVEAL_BAND = 0.16;\nconst DEFAULT_SHEAR = 2.2;\n\nfunction clamp01(value: number): number {\n\tif (value < 0) return 0;\n\tif (value > 1) return 1;\n\treturn value;\n}\n\nfunction easeOutCubic(t: number): number {\n\tconst u = clamp01(t);\n\treturn 1 - (1 - u) * (1 - u) * (1 - u);\n}\n\nfunction diagonalPosition(x: number, y: number, geom: GradientGeom): number {\n\tconst span = geom.cols - 1 + (geom.rows - 1) * geom.shear;\n\tif (span <= 0) return 0;\n\treturn clamp01((x + (geom.rows - 1 - y) * geom.shear) / span);\n}\n\nconst SCRAMBLE_CHARS = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@#$%&*+=<>[]{}|/\\\\~^\";\nconst SCRAMBLE_LEN = SCRAMBLE_CHARS.length;\n\nfunction scrambleGlyph(x: number, y: number, seed: number): string {\n\t// Deterministic scramble from position + seed (no Math.random)\n\tconst hash = ((x * 374761393 + y * 668265263 + seed * 1274126177) >>> 0) % SCRAMBLE_LEN;\n\treturn SCRAMBLE_CHARS[hash]!;\n}\n\nfunction dimRgb(r: number, g: number, b: number, factor: number): { r: number; g: number; b: number } {\n\treturn {\n\t\tr: Math.round(r * factor),\n\t\tg: Math.round(g * factor),\n\t\tb: Math.round(b * factor),\n\t};\n}\n\n/**\n * Phase 2: one-shot intro reveal. Diagonal wipe using easeOutCubic.\n * At elapsed >= INTRO_MS the output is byte-identical to composeStaticBanner.\n */\nexport function composeIntroBanner(\n\tart: string[],\n\tmode: GradientColorMode,\n\tnoColor: boolean,\n\telapsedMs: number,\n): string[] {\n\tif (elapsedMs >= INTRO_MS) {\n\t\treturn composeStaticBanner(art, mode, noColor);\n\t}\n\n\tconst geom: GradientGeom = {\n\t\tcols: Math.max(0, ...art.map((line) => Array.from(line).length)),\n\t\trows: art.length,\n\t\tshear: DEFAULT_SHEAR,\n\t};\n\n\tconst p = easeOutCubic(elapsedMs / INTRO_MS);\n\tconst seed = Math.floor(elapsedMs / 100); // changes every 100ms tick\n\n\treturn art.map((line, y) => {\n\t\tconst glyphs = Array.from(line);\n\t\tlet rendered = \"\";\n\t\tfor (let x = 0; x < glyphs.length; x++) {\n\t\t\tconst glyph = glyphs[x]!;\n\t\t\tif (glyph === \" \") {\n\t\t\t\trendered += \" \";\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst d = diagonalPosition(x, y, geom);\n\t\t\tconst cell = clamp01((p - d + REVEAL_BAND) / REVEAL_BAND);\n\t\t\tconst { r, g, b } = colorAt(x, y, 0, geom);\n\t\t\tif (cell >= 1) {\n\t\t\t\trendered += paintGlyph(glyph, r, g, b, mode, noColor);\n\t\t\t} else {\n\t\t\t\t// Scramble with dimmed color\n\t\t\t\tconst scramble = scrambleGlyph(x, y, seed);\n\t\t\t\tconst dimFactor = 0.3 + 0.7 * cell;\n\t\t\t\tconst { r: dr, g: dg, b: db } = dimRgb(r, g, b, dimFactor);\n\t\t\t\trendered += paintGlyph(scramble, dr, dg, db, mode, noColor);\n\t\t\t}\n\t\t}\n\t\treturn rendered;\n\t});\n}\n\n/**\n * Phase 3: opt-in idle drift. Reuses colorAt(x,y,t) DRIFT math.\n */\nexport function composeIdleBanner(\n\tart: string[],\n\tmode: GradientColorMode,\n\tnoColor: boolean,\n\telapsedMs: number,\n): string[] {\n\tconst geom: GradientGeom = {\n\t\tcols: Math.max(0, ...art.map((line) => Array.from(line).length)),\n\t\trows: art.length,\n\t\tshear: DEFAULT_SHEAR,\n\t};\n\n\tconst t = (elapsedMs % IDLE_PERIOD_MS) / IDLE_PERIOD_MS;\n\n\treturn art.map((line, y) => {\n\t\tconst glyphs = Array.from(line);\n\t\tlet rendered = \"\";\n\t\tfor (let x = 0; x < glyphs.length; x++) {\n\t\t\tconst glyph = glyphs[x]!;\n\t\t\tconst { r, g, b } = colorAt(x, y, t, geom);\n\t\t\trendered += paintGlyph(glyph, r, g, b, mode, noColor);\n\t\t}\n\t\treturn rendered;\n\t});\n}\n\n/**\n * Gate: should we animate the banner for this phase?\n */\nexport function shouldAnimate(options: {\n\tphase: \"intro\" | \"idle\";\n\tisTTY: boolean;\n\tnoColor: boolean;\n\tcolorMode: GradientColorMode;\n\texpanded: boolean;\n\twidth: number;\n\treducedMotion: boolean;\n\tbusy: boolean;\n\theaderVisibleHint: boolean;\n\tidleDriftEnabled: boolean;\n}): boolean {\n\tif (!shouldGradient(options)) return false;\n\tif (options.reducedMotion || options.busy || !options.headerVisibleHint) return false;\n\tif (options.phase === \"idle\" && !options.idleDriftEnabled) return false;\n\treturn true;\n}\n"]}
1
+ {"version":3,"file":"control-panel-gradient-motion.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/control-panel-gradient-motion.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,KAAK,iBAAiB,EAItB,MAAM,6BAA6B,CAAC;AAErC,eAAO,MAAM,QAAQ,MAAM,CAAC;AAC5B,eAAO,MAAM,OAAO,OAAO,CAAC;AAuC5B;;;GAGG;AACH,wBAAgB,kBAAkB,CACjC,GAAG,EAAE,MAAM,EAAE,EACb,IAAI,EAAE,iBAAiB,EACvB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GACf,MAAM,EAAE,CAsCV;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAChC,GAAG,EAAE,MAAM,EAAE,EACb,IAAI,EAAE,iBAAiB,EACvB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GACf,MAAM,EAAE,CAmBV;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE;IACtC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,iBAAiB,EAAE,OAAO,CAAC;IAC3B,gBAAgB,EAAE,OAAO,CAAC;CAC1B,GAAG,OAAO,CAMV","sourcesContent":["import {\n\tcolorAt,\n\tcomposeStaticBanner,\n\ttype GradientColorMode,\n\ttype GradientGeom,\n\tpaintGlyph,\n\tshouldGradient,\n} from \"./control-panel-gradient.ts\";\n\nexport const INTRO_MS = 900;\nexport const IDLE_MS = 6000;\nconst IDLE_PERIOD_MS = 4200;\nconst REVEAL_BAND = 0.16;\nconst DEFAULT_SHEAR = 2.2;\n\nfunction clamp01(value: number): number {\n\tif (value < 0) return 0;\n\tif (value > 1) return 1;\n\treturn value;\n}\n\nfunction easeOutCubic(t: number): number {\n\tconst u = clamp01(t);\n\treturn 1 - (1 - u) * (1 - u) * (1 - u);\n}\n\nfunction diagonalPosition(x: number, y: number, geom: GradientGeom): number {\n\tconst span = geom.cols - 1 + (geom.rows - 1) * geom.shear;\n\tif (span <= 0) return 0;\n\treturn clamp01((x + (geom.rows - 1 - y) * geom.shear) / span);\n}\n\nconst SCRAMBLE_CHARS = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@#$%&*+=<>[]{}|/\\\\~^\";\nconst SCRAMBLE_LEN = SCRAMBLE_CHARS.length;\n\nfunction scrambleGlyph(x: number, y: number, seed: number): string {\n\t// Deterministic scramble from position + seed (no Math.random)\n\tconst hash = ((x * 374761393 + y * 668265263 + seed * 1274126177) >>> 0) % SCRAMBLE_LEN;\n\treturn SCRAMBLE_CHARS[hash]!;\n}\n\nfunction dimRgb(r: number, g: number, b: number, factor: number): { r: number; g: number; b: number } {\n\treturn {\n\t\tr: Math.round(r * factor),\n\t\tg: Math.round(g * factor),\n\t\tb: Math.round(b * factor),\n\t};\n}\n\n/**\n * Phase 2: one-shot intro reveal. Diagonal wipe using easeOutCubic.\n * At elapsed >= INTRO_MS the output is byte-identical to composeStaticBanner.\n */\nexport function composeIntroBanner(\n\tart: string[],\n\tmode: GradientColorMode,\n\tnoColor: boolean,\n\telapsedMs: number,\n): string[] {\n\tif (elapsedMs >= INTRO_MS) {\n\t\treturn composeStaticBanner(art, mode, noColor);\n\t}\n\n\tconst geom: GradientGeom = {\n\t\tcols: Math.max(0, ...art.map((line) => Array.from(line).length)),\n\t\trows: art.length,\n\t\tshear: DEFAULT_SHEAR,\n\t};\n\n\tconst p = easeOutCubic(elapsedMs / INTRO_MS);\n\tconst seed = Math.floor(elapsedMs / 100); // changes every 100ms tick\n\n\treturn art.map((line, y) => {\n\t\tconst glyphs = Array.from(line);\n\t\tlet rendered = \"\";\n\t\tfor (let x = 0; x < glyphs.length; x++) {\n\t\t\tconst glyph = glyphs[x]!;\n\t\t\tif (glyph === \" \") {\n\t\t\t\trendered += \" \";\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst d = diagonalPosition(x, y, geom);\n\t\t\tconst cell = clamp01((p - d + REVEAL_BAND) / REVEAL_BAND);\n\t\t\tconst { r, g, b } = colorAt(x, y, 0, geom);\n\t\t\tif (cell >= 1) {\n\t\t\t\trendered += paintGlyph(glyph, r, g, b, mode, noColor);\n\t\t\t} else {\n\t\t\t\t// Scramble with dimmed color\n\t\t\t\tconst scramble = scrambleGlyph(x, y, seed);\n\t\t\t\tconst dimFactor = 0.3 + 0.7 * cell;\n\t\t\t\tconst { r: dr, g: dg, b: db } = dimRgb(r, g, b, dimFactor);\n\t\t\t\trendered += paintGlyph(scramble, dr, dg, db, mode, noColor);\n\t\t\t}\n\t\t}\n\t\treturn rendered;\n\t});\n}\n\n/**\n * Phase 3: opt-in idle drift. Reuses colorAt(x,y,t) DRIFT math.\n */\nexport function composeIdleBanner(\n\tart: string[],\n\tmode: GradientColorMode,\n\tnoColor: boolean,\n\telapsedMs: number,\n): string[] {\n\tconst geom: GradientGeom = {\n\t\tcols: Math.max(0, ...art.map((line) => Array.from(line).length)),\n\t\trows: art.length,\n\t\tshear: DEFAULT_SHEAR,\n\t};\n\n\tconst t = (elapsedMs % IDLE_PERIOD_MS) / IDLE_PERIOD_MS;\n\n\treturn art.map((line, y) => {\n\t\tconst glyphs = Array.from(line);\n\t\tlet rendered = \"\";\n\t\tfor (let x = 0; x < glyphs.length; x++) {\n\t\t\tconst glyph = glyphs[x]!;\n\t\t\tconst { r, g, b } = colorAt(x, y, t, geom);\n\t\t\trendered += paintGlyph(glyph, r, g, b, mode, noColor);\n\t\t}\n\t\treturn rendered;\n\t});\n}\n\n/**\n * Gate: should we animate the banner for this phase?\n */\nexport function shouldAnimate(options: {\n\tphase: \"intro\" | \"idle\";\n\tisTTY: boolean;\n\tnoColor: boolean;\n\tcolorMode: GradientColorMode;\n\texpanded: boolean;\n\twidth: number;\n\treducedMotion: boolean;\n\tbusy: boolean;\n\theaderVisibleHint: boolean;\n\tidleDriftEnabled: boolean;\n}): boolean {\n\tconst forceColor = process.env.FORCE_COLOR !== undefined;\n\tif (!shouldGradient({ ...options, isTTY: options.isTTY || forceColor })) return false;\n\tif (options.reducedMotion || options.busy || !options.headerVisibleHint) return false;\n\tif (options.phase === \"idle\" && !options.idleDriftEnabled) return false;\n\treturn true;\n}\n"]}
@@ -101,7 +101,8 @@ export function composeIdleBanner(art, mode, noColor, elapsedMs) {
101
101
  * Gate: should we animate the banner for this phase?
102
102
  */
103
103
  export function shouldAnimate(options) {
104
- if (!shouldGradient(options))
104
+ const forceColor = process.env.FORCE_COLOR !== undefined;
105
+ if (!shouldGradient({ ...options, isTTY: options.isTTY || forceColor }))
105
106
  return false;
106
107
  if (options.reducedMotion || options.busy || !options.headerVisibleHint)
107
108
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"control-panel-gradient-motion.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/control-panel-gradient-motion.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tcolorAt,\n\tcomposeStaticBanner,\n\ttype GradientColorMode,\n\ttype GradientGeom,\n\tpaintGlyph,\n\tshouldGradient,\n} from \"./control-panel-gradient.ts\";\n\nexport const INTRO_MS = 900;\nexport const IDLE_MS = 6000;\nconst IDLE_PERIOD_MS = 4200;\nconst REVEAL_BAND = 0.16;\nconst DEFAULT_SHEAR = 2.2;\n\nfunction clamp01(value: number): number {\n\tif (value < 0) return 0;\n\tif (value > 1) return 1;\n\treturn value;\n}\n\nfunction easeOutCubic(t: number): number {\n\tconst u = clamp01(t);\n\treturn 1 - (1 - u) * (1 - u) * (1 - u);\n}\n\nfunction diagonalPosition(x: number, y: number, geom: GradientGeom): number {\n\tconst span = geom.cols - 1 + (geom.rows - 1) * geom.shear;\n\tif (span <= 0) return 0;\n\treturn clamp01((x + (geom.rows - 1 - y) * geom.shear) / span);\n}\n\nconst SCRAMBLE_CHARS = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@#$%&*+=<>[]{}|/\\\\~^\";\nconst SCRAMBLE_LEN = SCRAMBLE_CHARS.length;\n\nfunction scrambleGlyph(x: number, y: number, seed: number): string {\n\t// Deterministic scramble from position + seed (no Math.random)\n\tconst hash = ((x * 374761393 + y * 668265263 + seed * 1274126177) >>> 0) % SCRAMBLE_LEN;\n\treturn SCRAMBLE_CHARS[hash]!;\n}\n\nfunction dimRgb(r: number, g: number, b: number, factor: number): { r: number; g: number; b: number } {\n\treturn {\n\t\tr: Math.round(r * factor),\n\t\tg: Math.round(g * factor),\n\t\tb: Math.round(b * factor),\n\t};\n}\n\n/**\n * Phase 2: one-shot intro reveal. Diagonal wipe using easeOutCubic.\n * At elapsed >= INTRO_MS the output is byte-identical to composeStaticBanner.\n */\nexport function composeIntroBanner(\n\tart: string[],\n\tmode: GradientColorMode,\n\tnoColor: boolean,\n\telapsedMs: number,\n): string[] {\n\tif (elapsedMs >= INTRO_MS) {\n\t\treturn composeStaticBanner(art, mode, noColor);\n\t}\n\n\tconst geom: GradientGeom = {\n\t\tcols: Math.max(0, ...art.map((line) => Array.from(line).length)),\n\t\trows: art.length,\n\t\tshear: DEFAULT_SHEAR,\n\t};\n\n\tconst p = easeOutCubic(elapsedMs / INTRO_MS);\n\tconst seed = Math.floor(elapsedMs / 100); // changes every 100ms tick\n\n\treturn art.map((line, y) => {\n\t\tconst glyphs = Array.from(line);\n\t\tlet rendered = \"\";\n\t\tfor (let x = 0; x < glyphs.length; x++) {\n\t\t\tconst glyph = glyphs[x]!;\n\t\t\tif (glyph === \" \") {\n\t\t\t\trendered += \" \";\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst d = diagonalPosition(x, y, geom);\n\t\t\tconst cell = clamp01((p - d + REVEAL_BAND) / REVEAL_BAND);\n\t\t\tconst { r, g, b } = colorAt(x, y, 0, geom);\n\t\t\tif (cell >= 1) {\n\t\t\t\trendered += paintGlyph(glyph, r, g, b, mode, noColor);\n\t\t\t} else {\n\t\t\t\t// Scramble with dimmed color\n\t\t\t\tconst scramble = scrambleGlyph(x, y, seed);\n\t\t\t\tconst dimFactor = 0.3 + 0.7 * cell;\n\t\t\t\tconst { r: dr, g: dg, b: db } = dimRgb(r, g, b, dimFactor);\n\t\t\t\trendered += paintGlyph(scramble, dr, dg, db, mode, noColor);\n\t\t\t}\n\t\t}\n\t\treturn rendered;\n\t});\n}\n\n/**\n * Phase 3: opt-in idle drift. Reuses colorAt(x,y,t) DRIFT math.\n */\nexport function composeIdleBanner(\n\tart: string[],\n\tmode: GradientColorMode,\n\tnoColor: boolean,\n\telapsedMs: number,\n): string[] {\n\tconst geom: GradientGeom = {\n\t\tcols: Math.max(0, ...art.map((line) => Array.from(line).length)),\n\t\trows: art.length,\n\t\tshear: DEFAULT_SHEAR,\n\t};\n\n\tconst t = (elapsedMs % IDLE_PERIOD_MS) / IDLE_PERIOD_MS;\n\n\treturn art.map((line, y) => {\n\t\tconst glyphs = Array.from(line);\n\t\tlet rendered = \"\";\n\t\tfor (let x = 0; x < glyphs.length; x++) {\n\t\t\tconst glyph = glyphs[x]!;\n\t\t\tconst { r, g, b } = colorAt(x, y, t, geom);\n\t\t\trendered += paintGlyph(glyph, r, g, b, mode, noColor);\n\t\t}\n\t\treturn rendered;\n\t});\n}\n\n/**\n * Gate: should we animate the banner for this phase?\n */\nexport function shouldAnimate(options: {\n\tphase: \"intro\" | \"idle\";\n\tisTTY: boolean;\n\tnoColor: boolean;\n\tcolorMode: GradientColorMode;\n\texpanded: boolean;\n\twidth: number;\n\treducedMotion: boolean;\n\tbusy: boolean;\n\theaderVisibleHint: boolean;\n\tidleDriftEnabled: boolean;\n}): boolean {\n\tif (!shouldGradient(options)) return false;\n\tif (options.reducedMotion || options.busy || !options.headerVisibleHint) return false;\n\tif (options.phase === \"idle\" && !options.idleDriftEnabled) return false;\n\treturn true;\n}\n"]}
1
+ {"version":3,"file":"control-panel-gradient-motion.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/control-panel-gradient-motion.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tcolorAt,\n\tcomposeStaticBanner,\n\ttype GradientColorMode,\n\ttype GradientGeom,\n\tpaintGlyph,\n\tshouldGradient,\n} from \"./control-panel-gradient.ts\";\n\nexport const INTRO_MS = 900;\nexport const IDLE_MS = 6000;\nconst IDLE_PERIOD_MS = 4200;\nconst REVEAL_BAND = 0.16;\nconst DEFAULT_SHEAR = 2.2;\n\nfunction clamp01(value: number): number {\n\tif (value < 0) return 0;\n\tif (value > 1) return 1;\n\treturn value;\n}\n\nfunction easeOutCubic(t: number): number {\n\tconst u = clamp01(t);\n\treturn 1 - (1 - u) * (1 - u) * (1 - u);\n}\n\nfunction diagonalPosition(x: number, y: number, geom: GradientGeom): number {\n\tconst span = geom.cols - 1 + (geom.rows - 1) * geom.shear;\n\tif (span <= 0) return 0;\n\treturn clamp01((x + (geom.rows - 1 - y) * geom.shear) / span);\n}\n\nconst SCRAMBLE_CHARS = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@#$%&*+=<>[]{}|/\\\\~^\";\nconst SCRAMBLE_LEN = SCRAMBLE_CHARS.length;\n\nfunction scrambleGlyph(x: number, y: number, seed: number): string {\n\t// Deterministic scramble from position + seed (no Math.random)\n\tconst hash = ((x * 374761393 + y * 668265263 + seed * 1274126177) >>> 0) % SCRAMBLE_LEN;\n\treturn SCRAMBLE_CHARS[hash]!;\n}\n\nfunction dimRgb(r: number, g: number, b: number, factor: number): { r: number; g: number; b: number } {\n\treturn {\n\t\tr: Math.round(r * factor),\n\t\tg: Math.round(g * factor),\n\t\tb: Math.round(b * factor),\n\t};\n}\n\n/**\n * Phase 2: one-shot intro reveal. Diagonal wipe using easeOutCubic.\n * At elapsed >= INTRO_MS the output is byte-identical to composeStaticBanner.\n */\nexport function composeIntroBanner(\n\tart: string[],\n\tmode: GradientColorMode,\n\tnoColor: boolean,\n\telapsedMs: number,\n): string[] {\n\tif (elapsedMs >= INTRO_MS) {\n\t\treturn composeStaticBanner(art, mode, noColor);\n\t}\n\n\tconst geom: GradientGeom = {\n\t\tcols: Math.max(0, ...art.map((line) => Array.from(line).length)),\n\t\trows: art.length,\n\t\tshear: DEFAULT_SHEAR,\n\t};\n\n\tconst p = easeOutCubic(elapsedMs / INTRO_MS);\n\tconst seed = Math.floor(elapsedMs / 100); // changes every 100ms tick\n\n\treturn art.map((line, y) => {\n\t\tconst glyphs = Array.from(line);\n\t\tlet rendered = \"\";\n\t\tfor (let x = 0; x < glyphs.length; x++) {\n\t\t\tconst glyph = glyphs[x]!;\n\t\t\tif (glyph === \" \") {\n\t\t\t\trendered += \" \";\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst d = diagonalPosition(x, y, geom);\n\t\t\tconst cell = clamp01((p - d + REVEAL_BAND) / REVEAL_BAND);\n\t\t\tconst { r, g, b } = colorAt(x, y, 0, geom);\n\t\t\tif (cell >= 1) {\n\t\t\t\trendered += paintGlyph(glyph, r, g, b, mode, noColor);\n\t\t\t} else {\n\t\t\t\t// Scramble with dimmed color\n\t\t\t\tconst scramble = scrambleGlyph(x, y, seed);\n\t\t\t\tconst dimFactor = 0.3 + 0.7 * cell;\n\t\t\t\tconst { r: dr, g: dg, b: db } = dimRgb(r, g, b, dimFactor);\n\t\t\t\trendered += paintGlyph(scramble, dr, dg, db, mode, noColor);\n\t\t\t}\n\t\t}\n\t\treturn rendered;\n\t});\n}\n\n/**\n * Phase 3: opt-in idle drift. Reuses colorAt(x,y,t) DRIFT math.\n */\nexport function composeIdleBanner(\n\tart: string[],\n\tmode: GradientColorMode,\n\tnoColor: boolean,\n\telapsedMs: number,\n): string[] {\n\tconst geom: GradientGeom = {\n\t\tcols: Math.max(0, ...art.map((line) => Array.from(line).length)),\n\t\trows: art.length,\n\t\tshear: DEFAULT_SHEAR,\n\t};\n\n\tconst t = (elapsedMs % IDLE_PERIOD_MS) / IDLE_PERIOD_MS;\n\n\treturn art.map((line, y) => {\n\t\tconst glyphs = Array.from(line);\n\t\tlet rendered = \"\";\n\t\tfor (let x = 0; x < glyphs.length; x++) {\n\t\t\tconst glyph = glyphs[x]!;\n\t\t\tconst { r, g, b } = colorAt(x, y, t, geom);\n\t\t\trendered += paintGlyph(glyph, r, g, b, mode, noColor);\n\t\t}\n\t\treturn rendered;\n\t});\n}\n\n/**\n * Gate: should we animate the banner for this phase?\n */\nexport function shouldAnimate(options: {\n\tphase: \"intro\" | \"idle\";\n\tisTTY: boolean;\n\tnoColor: boolean;\n\tcolorMode: GradientColorMode;\n\texpanded: boolean;\n\twidth: number;\n\treducedMotion: boolean;\n\tbusy: boolean;\n\theaderVisibleHint: boolean;\n\tidleDriftEnabled: boolean;\n}): boolean {\n\tconst forceColor = process.env.FORCE_COLOR !== undefined;\n\tif (!shouldGradient({ ...options, isTTY: options.isTTY || forceColor })) return false;\n\tif (options.reducedMotion || options.busy || !options.headerVisibleHint) return false;\n\tif (options.phase === \"idle\" && !options.idleDriftEnabled) return false;\n\treturn true;\n}\n"]}
@@ -1,6 +1,10 @@
1
1
  import type { PiPackageIntakeSummary } from "../../../core/pi-package-intake.ts";
2
2
  import { type TodoState } from "../../../core/todo-state.ts";
3
3
  export declare const CONTROL_PANEL_ASCII_ART: string[];
4
+ export declare const CONTROL_PANEL_OVERLAY_MIN_WIDTH = 112;
5
+ export declare const CONTROL_PANEL_DECK_MIN_WIDTH: number;
6
+ export declare const CONTROL_PANEL_SIDEBAR_WIDTH = 38;
7
+ export declare const CONTROL_PANEL_GAP_WIDTH = 2;
4
8
  export interface ControlPanelContent {
5
9
  appName: string;
6
10
  version: string;
@@ -25,6 +29,16 @@ export interface ControlPanelStatusSnapshot {
25
29
  readonly cwdLabel?: string;
26
30
  readonly gitBranch?: string | null;
27
31
  readonly todoState?: TodoState;
32
+ readonly runtimeState?: string;
33
+ readonly routeState?: string;
34
+ readonly evidenceState?: string;
35
+ readonly controlState?: string;
36
+ readonly dagOrchestrationState?: string;
37
+ readonly ansiColorState?: string;
38
+ readonly startupState?: string;
39
+ readonly linkState?: string;
40
+ readonly sidebarState?: string;
28
41
  }
29
- export declare function renderControlPanelLayout(content: ControlPanelContent, expanded: boolean, width: number, bannerFrame?: string[]): string[];
42
+ export declare function renderControlPanelLayout(content: ControlPanelContent, expanded: boolean, width: number, bannerFrame?: string[], sparkleMs?: number): string[];
43
+ export declare function renderControlPanelRightPane(content: ControlPanelContent, width: number): string[];
30
44
  //# sourceMappingURL=control-panel-layout.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"control-panel-layout.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/control-panel-layout.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,EAAkB,KAAK,SAAS,EAA0B,MAAM,6BAA6B,CAAC;AAgBrG,eAAO,MAAM,uBAAuB,UAKnC,CAAC;AAMF,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;CAC/B;AAED,wBAAgB,wBAAwB,CACvC,OAAO,EAAE,mBAAmB,EAC5B,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,EAAE,GACpB,MAAM,EAAE,CAGV","sourcesContent":["import { visibleWidth } from \"omk-tui\";\nimport { getHeadroomRuntimeStatus } from \"../../../core/context-budget-headroom.ts\";\nimport { loadMcpInventory } from \"../../../core/mcp-inventory.ts\";\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\tboxBlankLine,\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\";\n\nexport const CONTROL_PANEL_ASCII_ART = [\n\t\" ____ __ __ __ __\",\n\t\" / __ \\\\ / |/ / / //_/\",\n\t\" / /_/ // /|_/ / / ,< \",\n\t\" \\\\____//_/ /_/ /_/|_| \",\n];\nconst META_WIDTH = 31;\nconst DECK_MIN_WIDTH = 112;\nconst SIDEBAR_WIDTH = 38;\nconst GAP_WIDTH = 2;\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}\n\nexport function renderControlPanelLayout(\n\tcontent: ControlPanelContent,\n\texpanded: boolean,\n\twidth: number,\n\tbannerFrame?: string[],\n): string[] {\n\tif (width <= 0) return [];\n\treturn expanded ? renderExpanded(content, width, bannerFrame) : renderCompact(content, width, bannerFrame);\n}\n\nfunction renderCompact(content: ControlPanelContent, width: number, bannerFrame?: string[]): string[] {\n\tif (width >= DECK_MIN_WIDTH) {\n\t\tconst deck = renderDeck(content, width, bannerFrame);\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[]): string[] {\n\tconst sidebarWidth = Math.min(SIDEBAR_WIDTH, Math.max(34, Math.floor(width * 0.28)));\n\tconst leftWidth = width - GAP_WIDTH - sidebarWidth;\n\tif (leftWidth < 72) return [];\n\tconst lines = composeColumns(\n\t\theroPanel(content, leftWidth, bannerFrame),\n\t\tleftWidth,\n\t\tsidebarPanel(content, sidebarWidth),\n\t\tsidebarWidth,\n\t\tGAP_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 heroPanel(content: ControlPanelContent, width: number, bannerFrame?: string[]): string[] {\n\tconst rawThemeName = theme.name ?? \"live\";\n\tconst themeName = (rawThemeName.startsWith(\"omk-\") ? rawThemeName.slice(4) : rawThemeName).toUpperCase();\n\tconst modelLabel = modelStatusLabel(statusSnapshot(content));\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\tboxBlankLine(width),\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 =\n\t\t\t\tindex === 0 ? \"accent\" : index === 1 ? \"warning\" : index === 2 ? \"success\" : \"mdCode\";\n\t\t\treturn boxCenteredLine(width, theme.fg(color, line));\n\t\t}),\n\t\tboxBlankLine(width),\n\t\tboxCenteredLine(width, `${theme.fg(\"warning\", \"*\")} ${theme.bold(\"OMK\")} / ${theme.fg(\"success\", modelLabel)}`),\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\", themeName)}`,\n\t\t),\n\t\tboxBottom(width),\n\t];\n}\n\nfunction sidebarPanel(content: ControlPanelContent, width: number): string[] {\n\tconst snapshot = statusSnapshot(content);\n\tconst headroomLabel = snapshot.headroomStatus ?? snapshot.optimizerPolicy ?? getHeadroomRuntimeStatus().policyId;\n\tconst mcpCount = snapshot.mcpCount ?? loadMcpInventory().entries.length;\n\tconst skillCount = snapshot.skillCount ?? 0;\n\tconst packageIntakeLabel = packageIntakeStatusLabel(snapshot.packageIntake);\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(\"accent\", \"MATRIX RAIN\")} // ${theme.fg(\"success\", \"NEON GRID ONLINE\")}`),\n\t\tboxCenteredLine(width, theme.fg(\"mdCode\", \"NIGHT-CITY-MATRIX-V3\")),\n\t\tsidebarRule(width, \"STATUS\"),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"state:\")} ${theme.fg(\"success\", \"* ready\")}`),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"route:\")} route · evidence · loop · control`),\n\t\tsidebarRule(width, \"TODO\"),\n\t\t...todoSidebarLines(snapshot.todoState, width),\n\t\tsidebarRule(width, \"SESSION\"),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"cwd:\")} ${snapshot.cwdLabel ?? \"?\"}`),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"git:\")} ${snapshot.gitBranch ?? \"?\"}`),\n\t\tsidebarRule(width, \"MODEL / CTX\"),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"model:\")} ${modelStatusLabel(snapshot)}`),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"think:\")} ${snapshot.thinkingLevel ?? \"off\"}`),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"ctx:\")} ${theme.fg(\"success\", contextStatusLabel(snapshot))}`),\n\t\tsidebarRule(width, \"RUNTIME / MCP / SKILLS\"),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"headroom:\")} ${headroomLabel}`),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"omk:\")} DAG:omk-parallel-orchestrator`),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"res:\")} MCP:${mcpCount} skills:${skillCount}`),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"pkg:\")} ${packageIntakeLabel}`),\n\t\tsidebarRule(width, \"CONTROL\"),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"route:\")} ${theme.fg(\"success\", \"armed\")}`),\n\t\tboxTextLine(width, `${theme.fg(\"muted\", \"verify:\")} ${theme.fg(\"success\", \"evidence gated\")}`),\n\t\tboxBottom(width),\n\t];\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\tboxTextLine(width, `${theme.fg(\"muted\", \"next:\")} ${next?.label ?? \"complete\"}`),\n\t];\n}\n\nfunction packageIntakeStatusLabel(summary: PiPackageIntakeSummary | undefined): string {\n\tif (!summary) return \"ports:pending\";\n\tconst ready = summary.acceptedNative + summary.acceptedReference + summary.acceptedMeasurement;\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[]): string[] {\n\tconst lines = [divider(width, \"OMK//CONTROL PANEL\", \"accent\"), statusLine(content, width)];\n\tif (width >= 32) lines.push(...brandLines(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 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 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(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\treturn art.map((line, index) =>\n\t\ttextLine(\n\t\t\twidth,\n\t\t\t`${theme.fg(\"accent\", line.padEnd(leftWidth))}${theme.fg(\"borderMuted\", \" | \")}${metadataLines()[index] ?? \"\"}`,\n\t\t),\n\t);\n}\n\nfunction metadataLines(): 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\")} ${theme.fg(\"success\", \"ONLINE\")}`,\n\t\t`${theme.fg(\"mdCode\", \"THEME\")} ${theme.fg(\"accent\", themeName)}`,\n\t\t`${theme.fg(\"mdCode\", \"STARTUP\")} ${theme.fg(\"warning\", \"ARMED\")}`,\n\t\t`${theme.fg(\"mdCode\", \"LINK\")} ${theme.fg(\"success\", \"READY\")}`,\n\t];\n}\n\nfunction statusLine(content: ControlPanelContent, width: number): string {\n\tconst segments = [\n\t\ttheme.bold(theme.fg(\"accent\", `${content.appName.toUpperCase()} v${content.version}`)),\n\t\ttheme.fg(\"success\", \"CORE:READY\"),\n\t\ttheme.fg(\"mdCode\", \"ANSI:ON\"),\n\t\ttheme.fg(\"warning\", \"ASCII:ARMED\"),\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;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 = summary.acceptedNative + summary.acceptedReference + summary.acceptedMeasurement;\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"]}