@bastani/atomic 0.7.17 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1233) hide show
  1. package/CHANGELOG.md +4200 -0
  2. package/README.md +655 -0
  3. package/dist/builtin/intercom/CHANGELOG.md +195 -0
  4. package/dist/builtin/intercom/LICENSE +21 -0
  5. package/dist/builtin/intercom/README.md +484 -0
  6. package/dist/builtin/intercom/broker/broker.ts +346 -0
  7. package/dist/builtin/intercom/broker/client.ts +535 -0
  8. package/dist/builtin/intercom/broker/framing.ts +57 -0
  9. package/dist/builtin/intercom/broker/paths.ts +21 -0
  10. package/dist/builtin/intercom/broker/spawn.ts +308 -0
  11. package/dist/builtin/intercom/config.ts +109 -0
  12. package/dist/builtin/intercom/index.ts +1780 -0
  13. package/dist/builtin/intercom/package.json +59 -0
  14. package/dist/builtin/intercom/reply-tracker.ts +102 -0
  15. package/dist/builtin/intercom/skills/intercom/SKILL.md +513 -0
  16. package/dist/builtin/intercom/types.ts +46 -0
  17. package/dist/builtin/intercom/ui/compose.ts +139 -0
  18. package/dist/builtin/intercom/ui/inline-message.ts +76 -0
  19. package/dist/builtin/intercom/ui/session-list.ts +162 -0
  20. package/dist/builtin/mcp/CHANGELOG.md +346 -0
  21. package/dist/builtin/mcp/LICENSE +21 -0
  22. package/dist/builtin/mcp/OAUTH.md +324 -0
  23. package/dist/builtin/mcp/README.md +373 -0
  24. package/dist/builtin/mcp/agent-dir.ts +21 -0
  25. package/dist/builtin/mcp/app-bridge.bundle.js +67 -0
  26. package/dist/builtin/mcp/cli.js +186 -0
  27. package/dist/builtin/mcp/commands.ts +420 -0
  28. package/dist/builtin/mcp/config.ts +667 -0
  29. package/dist/builtin/mcp/consent-manager.ts +64 -0
  30. package/dist/builtin/mcp/direct-tools.ts +427 -0
  31. package/dist/builtin/mcp/errors.ts +219 -0
  32. package/dist/builtin/mcp/glimpse-ui.ts +80 -0
  33. package/dist/builtin/mcp/host-html-template.ts +427 -0
  34. package/dist/builtin/mcp/index.ts +334 -0
  35. package/dist/builtin/mcp/init.ts +336 -0
  36. package/dist/builtin/mcp/lifecycle.ts +93 -0
  37. package/dist/builtin/mcp/logger.ts +169 -0
  38. package/dist/builtin/mcp/mcp-auth-flow.ts +362 -0
  39. package/dist/builtin/mcp/mcp-auth.ts +297 -0
  40. package/dist/builtin/mcp/mcp-callback-server.ts +284 -0
  41. package/dist/builtin/mcp/mcp-oauth-provider.ts +302 -0
  42. package/dist/builtin/mcp/mcp-panel.ts +826 -0
  43. package/dist/builtin/mcp/mcp-setup-panel.ts +577 -0
  44. package/dist/builtin/mcp/metadata-cache.ts +201 -0
  45. package/dist/builtin/mcp/npx-resolver.ts +424 -0
  46. package/dist/builtin/mcp/oauth-handler.ts +60 -0
  47. package/dist/builtin/mcp/onboarding-state.ts +68 -0
  48. package/dist/builtin/mcp/package.json +61 -0
  49. package/dist/builtin/mcp/proxy-modes.ts +803 -0
  50. package/dist/builtin/mcp/resource-tools.ts +17 -0
  51. package/dist/builtin/mcp/sampling-handler.ts +268 -0
  52. package/dist/builtin/mcp/server-manager.ts +375 -0
  53. package/dist/builtin/mcp/state.ts +41 -0
  54. package/dist/builtin/mcp/tool-metadata.ts +152 -0
  55. package/dist/builtin/mcp/tool-registrar.ts +46 -0
  56. package/dist/builtin/mcp/tool-result-renderer.ts +65 -0
  57. package/dist/builtin/mcp/types.ts +441 -0
  58. package/dist/builtin/mcp/ui-resource-handler.ts +145 -0
  59. package/dist/builtin/mcp/ui-server.ts +623 -0
  60. package/dist/builtin/mcp/ui-session.ts +384 -0
  61. package/dist/builtin/mcp/ui-stream-types.ts +89 -0
  62. package/dist/builtin/mcp/utils.ts +129 -0
  63. package/dist/builtin/subagents/CHANGELOG.md +1019 -0
  64. package/dist/builtin/subagents/README.md +991 -0
  65. package/dist/builtin/subagents/agents/code-simplifier.md +84 -0
  66. package/dist/builtin/subagents/agents/codebase-analyzer.md +158 -0
  67. package/dist/builtin/subagents/agents/codebase-locator.md +113 -0
  68. package/dist/builtin/subagents/agents/codebase-online-researcher.md +317 -0
  69. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +236 -0
  70. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +181 -0
  71. package/dist/builtin/subagents/agents/codebase-research-locator.md +146 -0
  72. package/dist/builtin/subagents/agents/debugger.md +92 -0
  73. package/dist/builtin/subagents/package.json +67 -0
  74. package/dist/builtin/subagents/prompts/gather-context-and-clarify.md +20 -0
  75. package/dist/builtin/subagents/prompts/parallel-cleanup.md +60 -0
  76. package/dist/builtin/subagents/prompts/parallel-context-build.md +55 -0
  77. package/dist/builtin/subagents/prompts/parallel-handoff-plan.md +77 -0
  78. package/dist/builtin/subagents/prompts/parallel-research.md +58 -0
  79. package/dist/builtin/subagents/prompts/parallel-review.md +52 -0
  80. package/dist/builtin/subagents/prompts/review-loop.md +48 -0
  81. package/dist/builtin/subagents/skills/subagent/SKILL.md +734 -0
  82. package/dist/builtin/subagents/src/agents/agent-management.ts +644 -0
  83. package/dist/builtin/subagents/src/agents/agent-scope.ts +6 -0
  84. package/dist/builtin/subagents/src/agents/agent-selection.ts +23 -0
  85. package/dist/builtin/subagents/src/agents/agent-serializer.ts +84 -0
  86. package/dist/builtin/subagents/src/agents/agents.ts +809 -0
  87. package/dist/builtin/subagents/src/agents/chain-serializer.ts +137 -0
  88. package/dist/builtin/subagents/src/agents/frontmatter.ts +29 -0
  89. package/dist/builtin/subagents/src/agents/identity.ts +30 -0
  90. package/dist/builtin/subagents/src/agents/skills.ts +630 -0
  91. package/dist/builtin/subagents/src/extension/control-notices.ts +92 -0
  92. package/dist/builtin/subagents/src/extension/doctor.ts +199 -0
  93. package/dist/builtin/subagents/src/extension/index.ts +586 -0
  94. package/dist/builtin/subagents/src/extension/schemas.ts +168 -0
  95. package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +378 -0
  96. package/dist/builtin/subagents/src/intercom/result-intercom.ts +269 -0
  97. package/dist/builtin/subagents/src/runs/background/async-execution.ts +612 -0
  98. package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +267 -0
  99. package/dist/builtin/subagents/src/runs/background/async-resume.ts +332 -0
  100. package/dist/builtin/subagents/src/runs/background/async-status.ts +295 -0
  101. package/dist/builtin/subagents/src/runs/background/completion-dedupe.ts +63 -0
  102. package/dist/builtin/subagents/src/runs/background/notify.ts +108 -0
  103. package/dist/builtin/subagents/src/runs/background/parallel-groups.ts +45 -0
  104. package/dist/builtin/subagents/src/runs/background/result-watcher.ts +250 -0
  105. package/dist/builtin/subagents/src/runs/background/run-status.ts +193 -0
  106. package/dist/builtin/subagents/src/runs/background/stale-run-reconciler.ts +291 -0
  107. package/dist/builtin/subagents/src/runs/background/subagent-runner.ts +1760 -0
  108. package/dist/builtin/subagents/src/runs/background/top-level-async.ts +13 -0
  109. package/dist/builtin/subagents/src/runs/foreground/chain-clarify.ts +1333 -0
  110. package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +932 -0
  111. package/dist/builtin/subagents/src/runs/foreground/execution.ts +902 -0
  112. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +2231 -0
  113. package/dist/builtin/subagents/src/runs/shared/completion-guard.ts +125 -0
  114. package/dist/builtin/subagents/src/runs/shared/long-running-guard.ts +175 -0
  115. package/dist/builtin/subagents/src/runs/shared/model-fallback.ts +103 -0
  116. package/dist/builtin/subagents/src/runs/shared/parallel-utils.ts +108 -0
  117. package/dist/builtin/subagents/src/runs/shared/pi-args.ts +163 -0
  118. package/dist/builtin/subagents/src/runs/shared/pi-spawn.ts +115 -0
  119. package/dist/builtin/subagents/src/runs/shared/run-history.ts +56 -0
  120. package/dist/builtin/subagents/src/runs/shared/single-output.ts +154 -0
  121. package/dist/builtin/subagents/src/runs/shared/subagent-control.ts +226 -0
  122. package/dist/builtin/subagents/src/runs/shared/subagent-prompt-runtime.ts +152 -0
  123. package/dist/builtin/subagents/src/runs/shared/worktree.ts +577 -0
  124. package/dist/builtin/subagents/src/shared/artifacts.ts +99 -0
  125. package/dist/builtin/subagents/src/shared/atomic-json.ts +16 -0
  126. package/dist/builtin/subagents/src/shared/file-coalescer.ts +40 -0
  127. package/dist/builtin/subagents/src/shared/fork-context.ts +76 -0
  128. package/dist/builtin/subagents/src/shared/formatters.ts +133 -0
  129. package/dist/builtin/subagents/src/shared/jsonl-writer.ts +81 -0
  130. package/dist/builtin/subagents/src/shared/model-info.ts +78 -0
  131. package/dist/builtin/subagents/src/shared/post-exit-stdio-guard.ts +85 -0
  132. package/dist/builtin/subagents/src/shared/session-identity.ts +10 -0
  133. package/dist/builtin/subagents/src/shared/session-tokens.ts +44 -0
  134. package/dist/builtin/subagents/src/shared/settings.ts +397 -0
  135. package/dist/builtin/subagents/src/shared/status-format.ts +49 -0
  136. package/dist/builtin/subagents/src/shared/types.ts +732 -0
  137. package/dist/builtin/subagents/src/shared/utils.ts +440 -0
  138. package/dist/builtin/subagents/src/slash/prompt-template-bridge.ts +397 -0
  139. package/dist/builtin/subagents/src/slash/slash-bridge.ts +174 -0
  140. package/dist/builtin/subagents/src/slash/slash-commands.ts +528 -0
  141. package/dist/builtin/subagents/src/slash/slash-live-state.ts +292 -0
  142. package/dist/builtin/subagents/src/tui/render-helpers.ts +80 -0
  143. package/dist/builtin/subagents/src/tui/render.ts +1257 -0
  144. package/dist/builtin/web-access/CHANGELOG.md +387 -0
  145. package/dist/builtin/web-access/LICENSE +21 -0
  146. package/dist/builtin/web-access/README.md +346 -0
  147. package/dist/builtin/web-access/activity.ts +101 -0
  148. package/dist/builtin/web-access/chrome-cookies.ts +322 -0
  149. package/dist/builtin/web-access/code-search.ts +107 -0
  150. package/dist/builtin/web-access/curator-page.ts +3359 -0
  151. package/dist/builtin/web-access/curator-server.ts +605 -0
  152. package/dist/builtin/web-access/exa.ts +521 -0
  153. package/dist/builtin/web-access/extract.ts +701 -0
  154. package/dist/builtin/web-access/gemini-api.ts +113 -0
  155. package/dist/builtin/web-access/gemini-search.ts +362 -0
  156. package/dist/builtin/web-access/gemini-url-context.ts +126 -0
  157. package/dist/builtin/web-access/gemini-web-config.ts +54 -0
  158. package/dist/builtin/web-access/gemini-web.ts +396 -0
  159. package/dist/builtin/web-access/github-api.ts +196 -0
  160. package/dist/builtin/web-access/github-extract.ts +635 -0
  161. package/dist/builtin/web-access/index.ts +2347 -0
  162. package/dist/builtin/web-access/package.json +54 -0
  163. package/dist/builtin/web-access/pdf-extract.ts +192 -0
  164. package/dist/builtin/web-access/perplexity.ts +196 -0
  165. package/dist/builtin/web-access/rsc-extract.ts +338 -0
  166. package/dist/builtin/web-access/storage.ts +72 -0
  167. package/dist/builtin/web-access/summary-review.ts +276 -0
  168. package/dist/builtin/web-access/utils.ts +44 -0
  169. package/dist/builtin/web-access/video-extract.ts +379 -0
  170. package/dist/builtin/web-access/youtube-extract.ts +311 -0
  171. package/dist/builtin/workflows/CHANGELOG.md +20 -0
  172. package/dist/builtin/workflows/README.md +323 -0
  173. package/dist/builtin/workflows/builtin/deep-research-codebase.ts +567 -0
  174. package/dist/builtin/workflows/builtin/index.ts +10 -0
  175. package/dist/builtin/workflows/builtin/open-claude-design.ts +985 -0
  176. package/dist/builtin/workflows/builtin/ralph.ts +613 -0
  177. package/dist/builtin/workflows/package.json +89 -0
  178. package/dist/builtin/workflows/skills/create-spec/SKILL.md +247 -0
  179. package/dist/builtin/workflows/skills/impeccable/SKILL.md +173 -0
  180. package/dist/builtin/workflows/skills/impeccable/reference/adapt.md +190 -0
  181. package/dist/builtin/workflows/skills/impeccable/reference/animate.md +175 -0
  182. package/dist/builtin/workflows/skills/impeccable/reference/audit.md +133 -0
  183. package/dist/builtin/workflows/skills/impeccable/reference/bolder.md +113 -0
  184. package/dist/builtin/workflows/skills/impeccable/reference/brand.md +118 -0
  185. package/dist/builtin/workflows/skills/impeccable/reference/clarify.md +174 -0
  186. package/dist/builtin/workflows/skills/impeccable/reference/codex.md +105 -0
  187. package/dist/builtin/workflows/skills/impeccable/reference/cognitive-load.md +106 -0
  188. package/dist/builtin/workflows/skills/impeccable/reference/color-and-contrast.md +105 -0
  189. package/dist/builtin/workflows/skills/impeccable/reference/colorize.md +154 -0
  190. package/dist/builtin/workflows/skills/impeccable/reference/craft.md +123 -0
  191. package/dist/builtin/workflows/skills/impeccable/reference/critique.md +261 -0
  192. package/dist/builtin/workflows/skills/impeccable/reference/delight.md +302 -0
  193. package/dist/builtin/workflows/skills/impeccable/reference/distill.md +111 -0
  194. package/dist/builtin/workflows/skills/impeccable/reference/document.md +427 -0
  195. package/dist/builtin/workflows/skills/impeccable/reference/extract.md +69 -0
  196. package/dist/builtin/workflows/skills/impeccable/reference/harden.md +347 -0
  197. package/dist/builtin/workflows/skills/impeccable/reference/heuristics-scoring.md +234 -0
  198. package/dist/builtin/workflows/skills/impeccable/reference/interaction-design.md +195 -0
  199. package/dist/builtin/workflows/skills/impeccable/reference/layout.md +141 -0
  200. package/dist/builtin/workflows/skills/impeccable/reference/live.md +622 -0
  201. package/dist/builtin/workflows/skills/impeccable/reference/motion-design.md +109 -0
  202. package/dist/builtin/workflows/skills/impeccable/reference/onboard.md +234 -0
  203. package/dist/builtin/workflows/skills/impeccable/reference/optimize.md +258 -0
  204. package/dist/builtin/workflows/skills/impeccable/reference/overdrive.md +130 -0
  205. package/dist/builtin/workflows/skills/impeccable/reference/personas.md +179 -0
  206. package/dist/builtin/workflows/skills/impeccable/reference/polish.md +242 -0
  207. package/dist/builtin/workflows/skills/impeccable/reference/product.md +62 -0
  208. package/dist/builtin/workflows/skills/impeccable/reference/quieter.md +99 -0
  209. package/dist/builtin/workflows/skills/impeccable/reference/responsive-design.md +114 -0
  210. package/dist/builtin/workflows/skills/impeccable/reference/shape.md +165 -0
  211. package/dist/builtin/workflows/skills/impeccable/reference/spatial-design.md +100 -0
  212. package/dist/builtin/workflows/skills/impeccable/reference/teach.md +156 -0
  213. package/dist/builtin/workflows/skills/impeccable/reference/typeset.md +124 -0
  214. package/dist/builtin/workflows/skills/impeccable/reference/typography.md +159 -0
  215. package/dist/builtin/workflows/skills/impeccable/reference/ux-writing.md +107 -0
  216. package/dist/builtin/workflows/skills/impeccable/scripts/cleanup-deprecated.mjs +284 -0
  217. package/dist/builtin/workflows/skills/impeccable/scripts/command-metadata.json +94 -0
  218. package/dist/builtin/workflows/skills/impeccable/scripts/critique-storage.mjs +226 -0
  219. package/dist/builtin/workflows/skills/impeccable/scripts/design-parser.mjs +820 -0
  220. package/dist/builtin/workflows/skills/impeccable/scripts/detect-csp.mjs +198 -0
  221. package/dist/builtin/workflows/skills/impeccable/scripts/impeccable-paths.mjs +110 -0
  222. package/dist/builtin/workflows/skills/impeccable/scripts/is-generated.mjs +69 -0
  223. package/dist/builtin/workflows/skills/impeccable/scripts/live-accept.mjs +646 -0
  224. package/dist/builtin/workflows/skills/impeccable/scripts/live-browser-session.js +123 -0
  225. package/dist/builtin/workflows/skills/impeccable/scripts/live-browser.js +4865 -0
  226. package/dist/builtin/workflows/skills/impeccable/scripts/live-complete.mjs +75 -0
  227. package/dist/builtin/workflows/skills/impeccable/scripts/live-completion.mjs +18 -0
  228. package/dist/builtin/workflows/skills/impeccable/scripts/live-inject.mjs +446 -0
  229. package/dist/builtin/workflows/skills/impeccable/scripts/live-poll.mjs +200 -0
  230. package/dist/builtin/workflows/skills/impeccable/scripts/live-resume.mjs +48 -0
  231. package/dist/builtin/workflows/skills/impeccable/scripts/live-server.mjs +847 -0
  232. package/dist/builtin/workflows/skills/impeccable/scripts/live-session-store.mjs +254 -0
  233. package/dist/builtin/workflows/skills/impeccable/scripts/live-status.mjs +47 -0
  234. package/dist/builtin/workflows/skills/impeccable/scripts/live-wrap.mjs +632 -0
  235. package/dist/builtin/workflows/skills/impeccable/scripts/live.mjs +247 -0
  236. package/dist/builtin/workflows/skills/impeccable/scripts/load-context.mjs +141 -0
  237. package/dist/builtin/workflows/skills/impeccable/scripts/modern-screenshot.umd.js +14 -0
  238. package/dist/builtin/workflows/skills/impeccable/scripts/pin.mjs +214 -0
  239. package/dist/builtin/workflows/skills/playwright-cli/SKILL.md +392 -0
  240. package/dist/builtin/workflows/skills/playwright-cli/references/element-attributes.md +23 -0
  241. package/dist/builtin/workflows/skills/playwright-cli/references/playwright-tests.md +39 -0
  242. package/dist/builtin/workflows/skills/playwright-cli/references/request-mocking.md +87 -0
  243. package/dist/builtin/workflows/skills/playwright-cli/references/running-code.md +241 -0
  244. package/dist/builtin/workflows/skills/playwright-cli/references/session-management.md +225 -0
  245. package/dist/builtin/workflows/skills/playwright-cli/references/spec-driven-testing.md +305 -0
  246. package/dist/builtin/workflows/skills/playwright-cli/references/storage-state.md +275 -0
  247. package/dist/builtin/workflows/skills/playwright-cli/references/test-generation.md +134 -0
  248. package/dist/builtin/workflows/skills/playwright-cli/references/tracing.md +139 -0
  249. package/dist/builtin/workflows/skills/playwright-cli/references/video-recording.md +143 -0
  250. package/dist/builtin/workflows/skills/prompt-engineer/SKILL.md +263 -0
  251. package/dist/builtin/workflows/skills/prompt-engineer/references/advanced_patterns.md +271 -0
  252. package/dist/builtin/workflows/skills/prompt-engineer/references/core_prompting.md +137 -0
  253. package/dist/builtin/workflows/skills/prompt-engineer/references/quality_improvement.md +193 -0
  254. package/dist/builtin/workflows/skills/research-codebase/SKILL.md +226 -0
  255. package/dist/builtin/workflows/skills/tdd/SKILL.md +109 -0
  256. package/dist/builtin/workflows/skills/tdd/deep-modules.md +33 -0
  257. package/dist/builtin/workflows/skills/tdd/interface-design.md +31 -0
  258. package/dist/builtin/workflows/skills/tdd/mocking.md +59 -0
  259. package/dist/builtin/workflows/skills/tdd/refactoring.md +10 -0
  260. package/dist/builtin/workflows/skills/tdd/tests.md +61 -0
  261. package/dist/builtin/workflows/skills/workflow/SKILL.md +255 -0
  262. package/dist/builtin/workflows/skills/workflow/references/context-engineering/advanced-evaluation.md +404 -0
  263. package/dist/builtin/workflows/skills/workflow/references/context-engineering/bdi-mental-states.md +313 -0
  264. package/dist/builtin/workflows/skills/workflow/references/context-engineering/context-compression.md +274 -0
  265. package/dist/builtin/workflows/skills/workflow/references/context-engineering/context-degradation.md +208 -0
  266. package/dist/builtin/workflows/skills/workflow/references/context-engineering/context-fundamentals.md +203 -0
  267. package/dist/builtin/workflows/skills/workflow/references/context-engineering/context-optimization.md +197 -0
  268. package/dist/builtin/workflows/skills/workflow/references/context-engineering/evaluation.md +253 -0
  269. package/dist/builtin/workflows/skills/workflow/references/context-engineering/filesystem-context.md +289 -0
  270. package/dist/builtin/workflows/skills/workflow/references/context-engineering/hosted-agents.md +262 -0
  271. package/dist/builtin/workflows/skills/workflow/references/context-engineering/memory-systems.md +221 -0
  272. package/dist/builtin/workflows/skills/workflow/references/context-engineering/multi-agent-patterns.md +259 -0
  273. package/dist/builtin/workflows/skills/workflow/references/context-engineering/project-development.md +293 -0
  274. package/dist/builtin/workflows/skills/workflow/references/context-engineering/tool-design.md +273 -0
  275. package/dist/builtin/workflows/skills/workflow/references/context-engineering.md +23 -0
  276. package/dist/builtin/workflows/skills/workflow/references/design-checklist.md +79 -0
  277. package/dist/builtin/workflows/skills/workflow/references/running-workflows.md +107 -0
  278. package/dist/builtin/workflows/skills/workflow/references/sdk-authoring.md +140 -0
  279. package/dist/builtin/workflows/src/extension/background-ui-adapter.ts +168 -0
  280. package/dist/builtin/workflows/src/extension/companions.ts +210 -0
  281. package/dist/builtin/workflows/src/extension/config-loader.ts +493 -0
  282. package/dist/builtin/workflows/src/extension/discovery.ts +501 -0
  283. package/dist/builtin/workflows/src/extension/dispatcher.ts +173 -0
  284. package/dist/builtin/workflows/src/extension/index.ts +2143 -0
  285. package/dist/builtin/workflows/src/extension/mcp.ts +110 -0
  286. package/dist/builtin/workflows/src/extension/render-call.ts +39 -0
  287. package/dist/builtin/workflows/src/extension/render-result.ts +214 -0
  288. package/dist/builtin/workflows/src/extension/renderers.ts +87 -0
  289. package/dist/builtin/workflows/src/extension/runtime.ts +360 -0
  290. package/dist/builtin/workflows/src/extension/status-writer.ts +167 -0
  291. package/dist/builtin/workflows/src/extension/wiring.ts +555 -0
  292. package/dist/builtin/workflows/src/extension/workflow-schema.ts +102 -0
  293. package/dist/builtin/workflows/src/index.ts +25 -0
  294. package/dist/builtin/workflows/src/intercom/intercom-bridge.ts +93 -0
  295. package/dist/builtin/workflows/src/intercom/intercom-routing.ts +125 -0
  296. package/dist/builtin/workflows/src/intercom/result-intercom.ts +240 -0
  297. package/dist/builtin/workflows/src/runs/background/cancellation-registry.ts +113 -0
  298. package/dist/builtin/workflows/src/runs/background/job-tracker.ts +81 -0
  299. package/dist/builtin/workflows/src/runs/background/runner.ts +152 -0
  300. package/dist/builtin/workflows/src/runs/background/status.ts +354 -0
  301. package/dist/builtin/workflows/src/runs/foreground/executor.ts +1522 -0
  302. package/dist/builtin/workflows/src/runs/foreground/stage-control-registry.ts +233 -0
  303. package/dist/builtin/workflows/src/runs/foreground/stage-runner.ts +712 -0
  304. package/dist/builtin/workflows/src/runs/shared/concurrency.ts +76 -0
  305. package/dist/builtin/workflows/src/runs/shared/graph-inference.ts +69 -0
  306. package/dist/builtin/workflows/src/runs/shared/model-fallback.ts +293 -0
  307. package/dist/builtin/workflows/src/runs/shared/validate-inputs.ts +83 -0
  308. package/dist/builtin/workflows/src/runs/shared/workflow-runner.ts +170 -0
  309. package/dist/builtin/workflows/src/runs/shared/worktree.ts +577 -0
  310. package/dist/builtin/workflows/src/shared/persistence-compaction-policy.ts +72 -0
  311. package/dist/builtin/workflows/src/shared/persistence-restore.ts +257 -0
  312. package/dist/builtin/workflows/src/shared/persistence-session-entries.ts +145 -0
  313. package/dist/builtin/workflows/src/shared/render-inputs-schema.ts +196 -0
  314. package/dist/builtin/workflows/src/shared/store-types.ts +160 -0
  315. package/dist/builtin/workflows/src/shared/store.ts +579 -0
  316. package/dist/builtin/workflows/src/shared/types.ts +566 -0
  317. package/dist/builtin/workflows/src/tui/chat-surface-message.ts +224 -0
  318. package/dist/builtin/workflows/src/tui/chat-surface.ts +511 -0
  319. package/dist/builtin/workflows/src/tui/color-utils.ts +64 -0
  320. package/dist/builtin/workflows/src/tui/connectors.ts +88 -0
  321. package/dist/builtin/workflows/src/tui/dispatch-confirm.ts +307 -0
  322. package/dist/builtin/workflows/src/tui/edge.ts +24 -0
  323. package/dist/builtin/workflows/src/tui/graph-canvas.ts +108 -0
  324. package/dist/builtin/workflows/src/tui/graph-theme.ts +283 -0
  325. package/dist/builtin/workflows/src/tui/graph-view.ts +1217 -0
  326. package/dist/builtin/workflows/src/tui/header.ts +172 -0
  327. package/dist/builtin/workflows/src/tui/inline-form-card.ts +421 -0
  328. package/dist/builtin/workflows/src/tui/inline-form-editor.ts +638 -0
  329. package/dist/builtin/workflows/src/tui/inline-form-overlay.ts +326 -0
  330. package/dist/builtin/workflows/src/tui/inline-form-store.ts +78 -0
  331. package/dist/builtin/workflows/src/tui/inputs-overlay.ts +163 -0
  332. package/dist/builtin/workflows/src/tui/inputs-picker.ts +888 -0
  333. package/dist/builtin/workflows/src/tui/keybindings-adapter.ts +154 -0
  334. package/dist/builtin/workflows/src/tui/layout.ts +153 -0
  335. package/dist/builtin/workflows/src/tui/node-card.ts +274 -0
  336. package/dist/builtin/workflows/src/tui/overlay-adapter.ts +277 -0
  337. package/dist/builtin/workflows/src/tui/prompt-card.ts +501 -0
  338. package/dist/builtin/workflows/src/tui/renderers.ts +15 -0
  339. package/dist/builtin/workflows/src/tui/run-detail.ts +339 -0
  340. package/dist/builtin/workflows/src/tui/session-confirm.ts +202 -0
  341. package/dist/builtin/workflows/src/tui/session-list.ts +32 -0
  342. package/dist/builtin/workflows/src/tui/session-overlays.ts +239 -0
  343. package/dist/builtin/workflows/src/tui/session-picker.ts +399 -0
  344. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +1873 -0
  345. package/dist/builtin/workflows/src/tui/status-helpers.ts +73 -0
  346. package/dist/builtin/workflows/src/tui/status-list.ts +361 -0
  347. package/dist/builtin/workflows/src/tui/store-widget-installer.ts +206 -0
  348. package/dist/builtin/workflows/src/tui/switcher.ts +121 -0
  349. package/dist/builtin/workflows/src/tui/text-helpers.ts +31 -0
  350. package/dist/builtin/workflows/src/tui/toast.ts +106 -0
  351. package/dist/builtin/workflows/src/tui/widget.ts +348 -0
  352. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +285 -0
  353. package/dist/builtin/workflows/src/tui/workflow-list.ts +224 -0
  354. package/dist/builtin/workflows/src/workflows/define-workflow.ts +150 -0
  355. package/dist/builtin/workflows/src/workflows/identity.ts +39 -0
  356. package/dist/builtin/workflows/src/workflows/registry.ts +113 -0
  357. package/dist/bun/cli.d.ts +3 -0
  358. package/dist/bun/cli.d.ts.map +1 -0
  359. package/dist/bun/cli.js +9 -0
  360. package/dist/bun/cli.js.map +1 -0
  361. package/dist/bun/register-bedrock.d.ts +2 -0
  362. package/dist/bun/register-bedrock.d.ts.map +1 -0
  363. package/dist/bun/register-bedrock.js +4 -0
  364. package/dist/bun/register-bedrock.js.map +1 -0
  365. package/dist/bun/restore-sandbox-env.d.ts +13 -0
  366. package/dist/bun/restore-sandbox-env.d.ts.map +1 -0
  367. package/dist/bun/restore-sandbox-env.js +32 -0
  368. package/dist/bun/restore-sandbox-env.js.map +1 -0
  369. package/dist/cli/args.d.ts +53 -0
  370. package/dist/cli/args.d.ts.map +1 -0
  371. package/dist/cli/args.js +341 -0
  372. package/dist/cli/args.js.map +1 -0
  373. package/dist/cli/config-selector.d.ts +14 -0
  374. package/dist/cli/config-selector.d.ts.map +1 -0
  375. package/dist/cli/config-selector.js +31 -0
  376. package/dist/cli/config-selector.js.map +1 -0
  377. package/dist/cli/file-processor.d.ts +15 -0
  378. package/dist/cli/file-processor.d.ts.map +1 -0
  379. package/dist/cli/file-processor.js +83 -0
  380. package/dist/cli/file-processor.js.map +1 -0
  381. package/dist/cli/initial-message.d.ts +18 -0
  382. package/dist/cli/initial-message.d.ts.map +1 -0
  383. package/dist/cli/initial-message.js +22 -0
  384. package/dist/cli/initial-message.js.map +1 -0
  385. package/dist/cli/list-models.d.ts +9 -0
  386. package/dist/cli/list-models.d.ts.map +1 -0
  387. package/dist/cli/list-models.js +98 -0
  388. package/dist/cli/list-models.js.map +1 -0
  389. package/dist/cli/session-picker.d.ts +9 -0
  390. package/dist/cli/session-picker.d.ts.map +1 -0
  391. package/dist/cli/session-picker.js +35 -0
  392. package/dist/cli/session-picker.js.map +1 -0
  393. package/dist/cli.d.ts +3 -0
  394. package/dist/cli.d.ts.map +1 -0
  395. package/dist/cli.js +20 -0
  396. package/dist/cli.js.map +1 -0
  397. package/dist/config.d.ts +102 -0
  398. package/dist/config.d.ts.map +1 -0
  399. package/dist/config.js +411 -0
  400. package/dist/config.js.map +1 -0
  401. package/dist/core/agent-session-runtime.d.ts +117 -0
  402. package/dist/core/agent-session-runtime.d.ts.map +1 -0
  403. package/dist/core/agent-session-runtime.js +292 -0
  404. package/dist/core/agent-session-runtime.js.map +1 -0
  405. package/dist/core/agent-session-services.d.ts +86 -0
  406. package/dist/core/agent-session-services.d.ts.map +1 -0
  407. package/dist/core/agent-session-services.js +117 -0
  408. package/dist/core/agent-session-services.js.map +1 -0
  409. package/dist/core/agent-session.d.ts +595 -0
  410. package/dist/core/agent-session.d.ts.map +1 -0
  411. package/dist/core/agent-session.js +2518 -0
  412. package/dist/core/agent-session.js.map +1 -0
  413. package/dist/core/auth-guidance.d.ts +5 -0
  414. package/dist/core/auth-guidance.d.ts.map +1 -0
  415. package/dist/core/auth-guidance.js +21 -0
  416. package/dist/core/auth-guidance.js.map +1 -0
  417. package/dist/core/auth-storage.d.ts +141 -0
  418. package/dist/core/auth-storage.d.ts.map +1 -0
  419. package/dist/core/auth-storage.js +437 -0
  420. package/dist/core/auth-storage.js.map +1 -0
  421. package/dist/core/bash-executor.d.ts +32 -0
  422. package/dist/core/bash-executor.d.ts.map +1 -0
  423. package/dist/core/bash-executor.js +111 -0
  424. package/dist/core/bash-executor.js.map +1 -0
  425. package/dist/core/builtin-packages.d.ts +14 -0
  426. package/dist/core/builtin-packages.d.ts.map +1 -0
  427. package/dist/core/builtin-packages.js +113 -0
  428. package/dist/core/builtin-packages.js.map +1 -0
  429. package/dist/core/compaction/branch-summarization.d.ts +88 -0
  430. package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
  431. package/dist/core/compaction/branch-summarization.js +243 -0
  432. package/dist/core/compaction/branch-summarization.js.map +1 -0
  433. package/dist/core/compaction/compaction.d.ts +121 -0
  434. package/dist/core/compaction/compaction.d.ts.map +1 -0
  435. package/dist/core/compaction/compaction.js +615 -0
  436. package/dist/core/compaction/compaction.js.map +1 -0
  437. package/dist/core/compaction/index.d.ts +7 -0
  438. package/dist/core/compaction/index.d.ts.map +1 -0
  439. package/dist/core/compaction/index.js +7 -0
  440. package/dist/core/compaction/index.js.map +1 -0
  441. package/dist/core/compaction/utils.d.ts +38 -0
  442. package/dist/core/compaction/utils.d.ts.map +1 -0
  443. package/dist/core/compaction/utils.js +153 -0
  444. package/dist/core/compaction/utils.js.map +1 -0
  445. package/dist/core/defaults.d.ts +3 -0
  446. package/dist/core/defaults.d.ts.map +1 -0
  447. package/dist/core/defaults.js +2 -0
  448. package/dist/core/defaults.js.map +1 -0
  449. package/dist/core/diagnostics.d.ts +15 -0
  450. package/dist/core/diagnostics.d.ts.map +1 -0
  451. package/dist/core/diagnostics.js +2 -0
  452. package/dist/core/diagnostics.js.map +1 -0
  453. package/dist/core/event-bus.d.ts +9 -0
  454. package/dist/core/event-bus.d.ts.map +1 -0
  455. package/dist/core/event-bus.js +25 -0
  456. package/dist/core/event-bus.js.map +1 -0
  457. package/dist/core/exec.d.ts +29 -0
  458. package/dist/core/exec.d.ts.map +1 -0
  459. package/dist/core/exec.js +75 -0
  460. package/dist/core/exec.js.map +1 -0
  461. package/dist/core/export-html/ansi-to-html.d.ts +22 -0
  462. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
  463. package/dist/core/export-html/ansi-to-html.js +249 -0
  464. package/dist/core/export-html/ansi-to-html.js.map +1 -0
  465. package/dist/core/export-html/index.d.ts +37 -0
  466. package/dist/core/export-html/index.d.ts.map +1 -0
  467. package/dist/core/export-html/index.js +224 -0
  468. package/dist/core/export-html/index.js.map +1 -0
  469. package/dist/core/export-html/template.css +1066 -0
  470. package/dist/core/export-html/template.html +55 -0
  471. package/dist/core/export-html/template.js +1834 -0
  472. package/dist/core/export-html/tool-renderer.d.ts +34 -0
  473. package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
  474. package/dist/core/export-html/tool-renderer.js +108 -0
  475. package/dist/core/export-html/tool-renderer.js.map +1 -0
  476. package/dist/core/export-html/vendor/highlight.min.js +1213 -0
  477. package/dist/core/export-html/vendor/marked.min.js +6 -0
  478. package/dist/core/extensions/index.d.ts +12 -0
  479. package/dist/core/extensions/index.d.ts.map +1 -0
  480. package/dist/core/extensions/index.js +9 -0
  481. package/dist/core/extensions/index.js.map +1 -0
  482. package/dist/core/extensions/loader.d.ts +24 -0
  483. package/dist/core/extensions/loader.d.ts.map +1 -0
  484. package/dist/core/extensions/loader.js +501 -0
  485. package/dist/core/extensions/loader.js.map +1 -0
  486. package/dist/core/extensions/runner.d.ts +159 -0
  487. package/dist/core/extensions/runner.d.ts.map +1 -0
  488. package/dist/core/extensions/runner.js +817 -0
  489. package/dist/core/extensions/runner.js.map +1 -0
  490. package/dist/core/extensions/types.d.ts +1173 -0
  491. package/dist/core/extensions/types.d.ts.map +1 -0
  492. package/dist/core/extensions/types.js +45 -0
  493. package/dist/core/extensions/types.js.map +1 -0
  494. package/dist/core/extensions/wrapper.d.ts +20 -0
  495. package/dist/core/extensions/wrapper.d.ts.map +1 -0
  496. package/dist/core/extensions/wrapper.js +22 -0
  497. package/dist/core/extensions/wrapper.js.map +1 -0
  498. package/dist/core/footer-data-provider.d.ts +52 -0
  499. package/dist/core/footer-data-provider.d.ts.map +1 -0
  500. package/dist/core/footer-data-provider.js +309 -0
  501. package/dist/core/footer-data-provider.js.map +1 -0
  502. package/dist/core/index.d.ts +12 -0
  503. package/dist/core/index.d.ts.map +1 -0
  504. package/dist/core/index.js +12 -0
  505. package/dist/core/index.js.map +1 -0
  506. package/dist/core/keybindings.d.ts +353 -0
  507. package/dist/core/keybindings.d.ts.map +1 -0
  508. package/dist/core/keybindings.js +294 -0
  509. package/dist/core/keybindings.js.map +1 -0
  510. package/dist/core/messages.d.ts +77 -0
  511. package/dist/core/messages.d.ts.map +1 -0
  512. package/dist/core/messages.js +123 -0
  513. package/dist/core/messages.js.map +1 -0
  514. package/dist/core/model-registry.d.ts +150 -0
  515. package/dist/core/model-registry.d.ts.map +1 -0
  516. package/dist/core/model-registry.js +726 -0
  517. package/dist/core/model-registry.js.map +1 -0
  518. package/dist/core/model-resolver.d.ts +110 -0
  519. package/dist/core/model-resolver.d.ts.map +1 -0
  520. package/dist/core/model-resolver.js +493 -0
  521. package/dist/core/model-resolver.js.map +1 -0
  522. package/dist/core/output-guard.d.ts +6 -0
  523. package/dist/core/output-guard.d.ts.map +1 -0
  524. package/dist/core/output-guard.js +59 -0
  525. package/dist/core/output-guard.js.map +1 -0
  526. package/dist/core/package-manager.d.ts +198 -0
  527. package/dist/core/package-manager.d.ts.map +1 -0
  528. package/dist/core/package-manager.js +1970 -0
  529. package/dist/core/package-manager.js.map +1 -0
  530. package/dist/core/prompt-templates.d.ts +52 -0
  531. package/dist/core/prompt-templates.d.ts.map +1 -0
  532. package/dist/core/prompt-templates.js +250 -0
  533. package/dist/core/prompt-templates.js.map +1 -0
  534. package/dist/core/provider-display-names.d.ts +2 -0
  535. package/dist/core/provider-display-names.d.ts.map +1 -0
  536. package/dist/core/provider-display-names.js +33 -0
  537. package/dist/core/provider-display-names.js.map +1 -0
  538. package/dist/core/resolve-config-value.d.ts +23 -0
  539. package/dist/core/resolve-config-value.d.ts.map +1 -0
  540. package/dist/core/resolve-config-value.js +126 -0
  541. package/dist/core/resolve-config-value.js.map +1 -0
  542. package/dist/core/resource-loader.d.ts +196 -0
  543. package/dist/core/resource-loader.d.ts.map +1 -0
  544. package/dist/core/resource-loader.js +698 -0
  545. package/dist/core/resource-loader.js.map +1 -0
  546. package/dist/core/sdk.d.ts +107 -0
  547. package/dist/core/sdk.d.ts.map +1 -0
  548. package/dist/core/sdk.js +291 -0
  549. package/dist/core/sdk.js.map +1 -0
  550. package/dist/core/session-cwd.d.ts +19 -0
  551. package/dist/core/session-cwd.d.ts.map +1 -0
  552. package/dist/core/session-cwd.js +37 -0
  553. package/dist/core/session-cwd.js.map +1 -0
  554. package/dist/core/session-manager.d.ts +333 -0
  555. package/dist/core/session-manager.d.ts.map +1 -0
  556. package/dist/core/session-manager.js +1118 -0
  557. package/dist/core/session-manager.js.map +1 -0
  558. package/dist/core/settings-manager.d.ts +261 -0
  559. package/dist/core/settings-manager.d.ts.map +1 -0
  560. package/dist/core/settings-manager.js +773 -0
  561. package/dist/core/settings-manager.js.map +1 -0
  562. package/dist/core/skills.d.ts +60 -0
  563. package/dist/core/skills.d.ts.map +1 -0
  564. package/dist/core/skills.js +404 -0
  565. package/dist/core/skills.js.map +1 -0
  566. package/dist/core/slash-commands.d.ts +14 -0
  567. package/dist/core/slash-commands.d.ts.map +1 -0
  568. package/dist/core/slash-commands.js +25 -0
  569. package/dist/core/slash-commands.js.map +1 -0
  570. package/dist/core/source-info.d.ts +18 -0
  571. package/dist/core/source-info.d.ts.map +1 -0
  572. package/dist/core/source-info.js +19 -0
  573. package/dist/core/source-info.js.map +1 -0
  574. package/dist/core/system-prompt.d.ts +28 -0
  575. package/dist/core/system-prompt.d.ts.map +1 -0
  576. package/dist/core/system-prompt.js +120 -0
  577. package/dist/core/system-prompt.js.map +1 -0
  578. package/dist/core/telemetry.d.ts +3 -0
  579. package/dist/core/telemetry.d.ts.map +1 -0
  580. package/dist/core/telemetry.js +10 -0
  581. package/dist/core/telemetry.js.map +1 -0
  582. package/dist/core/timings.d.ts +8 -0
  583. package/dist/core/timings.d.ts.map +1 -0
  584. package/dist/core/timings.js +32 -0
  585. package/dist/core/timings.js.map +1 -0
  586. package/dist/core/tools/ask-user-question/ask-user-question.d.ts +10 -0
  587. package/dist/core/tools/ask-user-question/ask-user-question.d.ts.map +1 -0
  588. package/dist/core/tools/ask-user-question/ask-user-question.js +82 -0
  589. package/dist/core/tools/ask-user-question/ask-user-question.js.map +1 -0
  590. package/dist/core/tools/ask-user-question/config.d.ts +11 -0
  591. package/dist/core/tools/ask-user-question/config.d.ts.map +1 -0
  592. package/dist/core/tools/ask-user-question/config.js +34 -0
  593. package/dist/core/tools/ask-user-question/config.js.map +1 -0
  594. package/dist/core/tools/ask-user-question/index.d.ts +19 -0
  595. package/dist/core/tools/ask-user-question/index.d.ts.map +1 -0
  596. package/dist/core/tools/ask-user-question/index.js +19 -0
  597. package/dist/core/tools/ask-user-question/index.js.map +1 -0
  598. package/dist/core/tools/ask-user-question/state/build-questionnaire.d.ts +36 -0
  599. package/dist/core/tools/ask-user-question/state/build-questionnaire.d.ts.map +1 -0
  600. package/dist/core/tools/ask-user-question/state/build-questionnaire.js +213 -0
  601. package/dist/core/tools/ask-user-question/state/build-questionnaire.js.map +1 -0
  602. package/dist/core/tools/ask-user-question/state/key-router.d.ts +53 -0
  603. package/dist/core/tools/ask-user-question/state/key-router.d.ts.map +1 -0
  604. package/dist/core/tools/ask-user-question/state/key-router.js +240 -0
  605. package/dist/core/tools/ask-user-question/state/key-router.js.map +1 -0
  606. package/dist/core/tools/ask-user-question/state/questionnaire-session.d.ts +61 -0
  607. package/dist/core/tools/ask-user-question/state/questionnaire-session.d.ts.map +1 -0
  608. package/dist/core/tools/ask-user-question/state/questionnaire-session.js +147 -0
  609. package/dist/core/tools/ask-user-question/state/questionnaire-session.js.map +1 -0
  610. package/dist/core/tools/ask-user-question/state/row-intent.d.ts +91 -0
  611. package/dist/core/tools/ask-user-question/state/row-intent.d.ts.map +1 -0
  612. package/dist/core/tools/ask-user-question/state/row-intent.js +91 -0
  613. package/dist/core/tools/ask-user-question/state/row-intent.js.map +1 -0
  614. package/dist/core/tools/ask-user-question/state/selectors/contract.d.ts +21 -0
  615. package/dist/core/tools/ask-user-question/state/selectors/contract.d.ts.map +1 -0
  616. package/dist/core/tools/ask-user-question/state/selectors/contract.js +2 -0
  617. package/dist/core/tools/ask-user-question/state/selectors/contract.js.map +1 -0
  618. package/dist/core/tools/ask-user-question/state/selectors/derivations.d.ts +44 -0
  619. package/dist/core/tools/ask-user-question/state/selectors/derivations.d.ts.map +1 -0
  620. package/dist/core/tools/ask-user-question/state/selectors/derivations.js +76 -0
  621. package/dist/core/tools/ask-user-question/state/selectors/derivations.js.map +1 -0
  622. package/dist/core/tools/ask-user-question/state/selectors/focus.d.ts +15 -0
  623. package/dist/core/tools/ask-user-question/state/selectors/focus.d.ts.map +1 -0
  624. package/dist/core/tools/ask-user-question/state/selectors/focus.js +18 -0
  625. package/dist/core/tools/ask-user-question/state/selectors/focus.js.map +1 -0
  626. package/dist/core/tools/ask-user-question/state/selectors/projections.d.ts +16 -0
  627. package/dist/core/tools/ask-user-question/state/selectors/projections.d.ts.map +1 -0
  628. package/dist/core/tools/ask-user-question/state/selectors/projections.js +71 -0
  629. package/dist/core/tools/ask-user-question/state/selectors/projections.js.map +1 -0
  630. package/dist/core/tools/ask-user-question/state/state-reducer.d.ts +44 -0
  631. package/dist/core/tools/ask-user-question/state/state-reducer.d.ts.map +1 -0
  632. package/dist/core/tools/ask-user-question/state/state-reducer.js +239 -0
  633. package/dist/core/tools/ask-user-question/state/state-reducer.js.map +1 -0
  634. package/dist/core/tools/ask-user-question/state/state.d.ts +42 -0
  635. package/dist/core/tools/ask-user-question/state/state.d.ts.map +1 -0
  636. package/dist/core/tools/ask-user-question/state/state.js +2 -0
  637. package/dist/core/tools/ask-user-question/state/state.js.map +1 -0
  638. package/dist/core/tools/ask-user-question/tool/format-answer.d.ts +30 -0
  639. package/dist/core/tools/ask-user-question/tool/format-answer.d.ts.map +1 -0
  640. package/dist/core/tools/ask-user-question/tool/format-answer.js +39 -0
  641. package/dist/core/tools/ask-user-question/tool/format-answer.js.map +1 -0
  642. package/dist/core/tools/ask-user-question/tool/response-envelope.d.ts +29 -0
  643. package/dist/core/tools/ask-user-question/tool/response-envelope.d.ts.map +1 -0
  644. package/dist/core/tools/ask-user-question/tool/response-envelope.js +46 -0
  645. package/dist/core/tools/ask-user-question/tool/response-envelope.js.map +1 -0
  646. package/dist/core/tools/ask-user-question/tool/types.d.ts +113 -0
  647. package/dist/core/tools/ask-user-question/tool/types.d.ts.map +1 -0
  648. package/dist/core/tools/ask-user-question/tool/types.js +81 -0
  649. package/dist/core/tools/ask-user-question/tool/types.js.map +1 -0
  650. package/dist/core/tools/ask-user-question/tool/validate-questionnaire.d.ts +21 -0
  651. package/dist/core/tools/ask-user-question/tool/validate-questionnaire.d.ts.map +1 -0
  652. package/dist/core/tools/ask-user-question/tool/validate-questionnaire.js +49 -0
  653. package/dist/core/tools/ask-user-question/tool/validate-questionnaire.js.map +1 -0
  654. package/dist/core/tools/ask-user-question/view/body-residual-spacer.d.ts +18 -0
  655. package/dist/core/tools/ask-user-question/view/body-residual-spacer.d.ts.map +1 -0
  656. package/dist/core/tools/ask-user-question/view/body-residual-spacer.js +21 -0
  657. package/dist/core/tools/ask-user-question/view/body-residual-spacer.js.map +1 -0
  658. package/dist/core/tools/ask-user-question/view/component-binding.d.ts +23 -0
  659. package/dist/core/tools/ask-user-question/view/component-binding.d.ts.map +1 -0
  660. package/dist/core/tools/ask-user-question/view/component-binding.js +16 -0
  661. package/dist/core/tools/ask-user-question/view/component-binding.js.map +1 -0
  662. package/dist/core/tools/ask-user-question/view/components/chat-row-view.d.ts +40 -0
  663. package/dist/core/tools/ask-user-question/view/components/chat-row-view.d.ts.map +1 -0
  664. package/dist/core/tools/ask-user-question/view/components/chat-row-view.js +31 -0
  665. package/dist/core/tools/ask-user-question/view/components/chat-row-view.js.map +1 -0
  666. package/dist/core/tools/ask-user-question/view/components/multi-select-view.d.ts +35 -0
  667. package/dist/core/tools/ask-user-question/view/components/multi-select-view.d.ts.map +1 -0
  668. package/dist/core/tools/ask-user-question/view/components/multi-select-view.js +91 -0
  669. package/dist/core/tools/ask-user-question/view/components/multi-select-view.js.map +1 -0
  670. package/dist/core/tools/ask-user-question/view/components/option-list-view.d.ts +43 -0
  671. package/dist/core/tools/ask-user-question/view/components/option-list-view.d.ts.map +1 -0
  672. package/dist/core/tools/ask-user-question/view/components/option-list-view.js +37 -0
  673. package/dist/core/tools/ask-user-question/view/components/option-list-view.js.map +1 -0
  674. package/dist/core/tools/ask-user-question/view/components/preview/markdown-content-cache.d.ts +36 -0
  675. package/dist/core/tools/ask-user-question/view/components/preview/markdown-content-cache.d.ts.map +1 -0
  676. package/dist/core/tools/ask-user-question/view/components/preview/markdown-content-cache.js +66 -0
  677. package/dist/core/tools/ask-user-question/view/components/preview/markdown-content-cache.js.map +1 -0
  678. package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.d.ts +46 -0
  679. package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.d.ts.map +1 -0
  680. package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.js +69 -0
  681. package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.js.map +1 -0
  682. package/dist/core/tools/ask-user-question/view/components/preview/preview-box-renderer.d.ts +39 -0
  683. package/dist/core/tools/ask-user-question/view/components/preview/preview-box-renderer.d.ts.map +1 -0
  684. package/dist/core/tools/ask-user-question/view/components/preview/preview-box-renderer.js +76 -0
  685. package/dist/core/tools/ask-user-question/view/components/preview/preview-box-renderer.js.map +1 -0
  686. package/dist/core/tools/ask-user-question/view/components/preview/preview-layout-decider.d.ts +116 -0
  687. package/dist/core/tools/ask-user-question/view/components/preview/preview-layout-decider.d.ts.map +1 -0
  688. package/dist/core/tools/ask-user-question/view/components/preview/preview-layout-decider.js +173 -0
  689. package/dist/core/tools/ask-user-question/view/components/preview/preview-layout-decider.js.map +1 -0
  690. package/dist/core/tools/ask-user-question/view/components/preview/preview-pane.d.ts +66 -0
  691. package/dist/core/tools/ask-user-question/view/components/preview/preview-pane.d.ts.map +1 -0
  692. package/dist/core/tools/ask-user-question/view/components/preview/preview-pane.js +124 -0
  693. package/dist/core/tools/ask-user-question/view/components/preview/preview-pane.js.map +1 -0
  694. package/dist/core/tools/ask-user-question/view/components/submit-picker.d.ts +37 -0
  695. package/dist/core/tools/ask-user-question/view/components/submit-picker.d.ts.map +1 -0
  696. package/dist/core/tools/ask-user-question/view/components/submit-picker.js +44 -0
  697. package/dist/core/tools/ask-user-question/view/components/submit-picker.js.map +1 -0
  698. package/dist/core/tools/ask-user-question/view/components/tab-bar.d.ts +32 -0
  699. package/dist/core/tools/ask-user-question/view/components/tab-bar.d.ts.map +1 -0
  700. package/dist/core/tools/ask-user-question/view/components/tab-bar.js +33 -0
  701. package/dist/core/tools/ask-user-question/view/components/tab-bar.js.map +1 -0
  702. package/dist/core/tools/ask-user-question/view/components/wrapping-select.d.ts +122 -0
  703. package/dist/core/tools/ask-user-question/view/components/wrapping-select.d.ts.map +1 -0
  704. package/dist/core/tools/ask-user-question/view/components/wrapping-select.js +161 -0
  705. package/dist/core/tools/ask-user-question/view/components/wrapping-select.js.map +1 -0
  706. package/dist/core/tools/ask-user-question/view/dialog-builder.d.ts +66 -0
  707. package/dist/core/tools/ask-user-question/view/dialog-builder.d.ts.map +1 -0
  708. package/dist/core/tools/ask-user-question/view/dialog-builder.js +85 -0
  709. package/dist/core/tools/ask-user-question/view/dialog-builder.js.map +1 -0
  710. package/dist/core/tools/ask-user-question/view/props-adapter.d.ts +58 -0
  711. package/dist/core/tools/ask-user-question/view/props-adapter.d.ts.map +1 -0
  712. package/dist/core/tools/ask-user-question/view/props-adapter.js +67 -0
  713. package/dist/core/tools/ask-user-question/view/props-adapter.js.map +1 -0
  714. package/dist/core/tools/ask-user-question/view/stateful-view.d.ts +24 -0
  715. package/dist/core/tools/ask-user-question/view/stateful-view.d.ts.map +1 -0
  716. package/dist/core/tools/ask-user-question/view/stateful-view.js +2 -0
  717. package/dist/core/tools/ask-user-question/view/stateful-view.js.map +1 -0
  718. package/dist/core/tools/ask-user-question/view/tab-components.d.ts +15 -0
  719. package/dist/core/tools/ask-user-question/view/tab-components.d.ts.map +1 -0
  720. package/dist/core/tools/ask-user-question/view/tab-components.js +2 -0
  721. package/dist/core/tools/ask-user-question/view/tab-components.js.map +1 -0
  722. package/dist/core/tools/ask-user-question/view/tab-content-strategy.d.ts +71 -0
  723. package/dist/core/tools/ask-user-question/view/tab-content-strategy.d.ts.map +1 -0
  724. package/dist/core/tools/ask-user-question/view/tab-content-strategy.js +129 -0
  725. package/dist/core/tools/ask-user-question/view/tab-content-strategy.js.map +1 -0
  726. package/dist/core/tools/bash.d.ts +68 -0
  727. package/dist/core/tools/bash.d.ts.map +1 -0
  728. package/dist/core/tools/bash.js +338 -0
  729. package/dist/core/tools/bash.js.map +1 -0
  730. package/dist/core/tools/edit-diff.d.ts +85 -0
  731. package/dist/core/tools/edit-diff.d.ts.map +1 -0
  732. package/dist/core/tools/edit-diff.js +338 -0
  733. package/dist/core/tools/edit-diff.js.map +1 -0
  734. package/dist/core/tools/edit.d.ts +49 -0
  735. package/dist/core/tools/edit.d.ts.map +1 -0
  736. package/dist/core/tools/edit.js +324 -0
  737. package/dist/core/tools/edit.js.map +1 -0
  738. package/dist/core/tools/file-mutation-queue.d.ts +6 -0
  739. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -0
  740. package/dist/core/tools/file-mutation-queue.js +37 -0
  741. package/dist/core/tools/file-mutation-queue.js.map +1 -0
  742. package/dist/core/tools/find.d.ts +35 -0
  743. package/dist/core/tools/find.d.ts.map +1 -0
  744. package/dist/core/tools/find.js +298 -0
  745. package/dist/core/tools/find.js.map +1 -0
  746. package/dist/core/tools/grep.d.ts +37 -0
  747. package/dist/core/tools/grep.d.ts.map +1 -0
  748. package/dist/core/tools/grep.js +304 -0
  749. package/dist/core/tools/grep.js.map +1 -0
  750. package/dist/core/tools/index.d.ts +42 -0
  751. package/dist/core/tools/index.d.ts.map +1 -0
  752. package/dist/core/tools/index.js +139 -0
  753. package/dist/core/tools/index.js.map +1 -0
  754. package/dist/core/tools/ls.d.ts +37 -0
  755. package/dist/core/tools/ls.d.ts.map +1 -0
  756. package/dist/core/tools/ls.js +169 -0
  757. package/dist/core/tools/ls.js.map +1 -0
  758. package/dist/core/tools/output-accumulator.d.ts +50 -0
  759. package/dist/core/tools/output-accumulator.d.ts.map +1 -0
  760. package/dist/core/tools/output-accumulator.js +172 -0
  761. package/dist/core/tools/output-accumulator.js.map +1 -0
  762. package/dist/core/tools/path-utils.d.ts +8 -0
  763. package/dist/core/tools/path-utils.d.ts.map +1 -0
  764. package/dist/core/tools/path-utils.js +81 -0
  765. package/dist/core/tools/path-utils.js.map +1 -0
  766. package/dist/core/tools/read.d.ts +35 -0
  767. package/dist/core/tools/read.d.ts.map +1 -0
  768. package/dist/core/tools/read.js +289 -0
  769. package/dist/core/tools/read.js.map +1 -0
  770. package/dist/core/tools/render-utils.d.ts +21 -0
  771. package/dist/core/tools/render-utils.d.ts.map +1 -0
  772. package/dist/core/tools/render-utils.js +49 -0
  773. package/dist/core/tools/render-utils.js.map +1 -0
  774. package/dist/core/tools/todos.d.ts +35 -0
  775. package/dist/core/tools/todos.d.ts.map +1 -0
  776. package/dist/core/tools/todos.js +906 -0
  777. package/dist/core/tools/todos.js.map +1 -0
  778. package/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
  779. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -0
  780. package/dist/core/tools/tool-definition-wrapper.js +34 -0
  781. package/dist/core/tools/tool-definition-wrapper.js.map +1 -0
  782. package/dist/core/tools/truncate.d.ts +70 -0
  783. package/dist/core/tools/truncate.d.ts.map +1 -0
  784. package/dist/core/tools/truncate.js +205 -0
  785. package/dist/core/tools/truncate.js.map +1 -0
  786. package/dist/core/tools/write.d.ts +26 -0
  787. package/dist/core/tools/write.d.ts.map +1 -0
  788. package/dist/core/tools/write.js +212 -0
  789. package/dist/core/tools/write.js.map +1 -0
  790. package/dist/index.d.ts +28 -0
  791. package/dist/index.d.ts.map +1 -0
  792. package/dist/index.js +41 -0
  793. package/dist/index.js.map +1 -0
  794. package/dist/main.d.ts +13 -0
  795. package/dist/main.d.ts.map +1 -0
  796. package/dist/main.js +586 -0
  797. package/dist/main.js.map +1 -0
  798. package/dist/migrations.d.ts +33 -0
  799. package/dist/migrations.d.ts.map +1 -0
  800. package/dist/migrations.js +281 -0
  801. package/dist/migrations.js.map +1 -0
  802. package/dist/modes/index.d.ts +9 -0
  803. package/dist/modes/index.d.ts.map +1 -0
  804. package/dist/modes/index.js +8 -0
  805. package/dist/modes/index.js.map +1 -0
  806. package/dist/modes/interactive/assets/clankolas.png +3 -0
  807. package/dist/modes/interactive/components/armin.d.ts +34 -0
  808. package/dist/modes/interactive/components/armin.d.ts.map +1 -0
  809. package/dist/modes/interactive/components/armin.js +329 -0
  810. package/dist/modes/interactive/components/armin.js.map +1 -0
  811. package/dist/modes/interactive/components/assistant-message.d.ts +20 -0
  812. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
  813. package/dist/modes/interactive/components/assistant-message.js +116 -0
  814. package/dist/modes/interactive/components/assistant-message.js.map +1 -0
  815. package/dist/modes/interactive/components/bash-execution.d.ts +34 -0
  816. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
  817. package/dist/modes/interactive/components/bash-execution.js +170 -0
  818. package/dist/modes/interactive/components/bash-execution.js.map +1 -0
  819. package/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  820. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
  821. package/dist/modes/interactive/components/bordered-loader.js +51 -0
  822. package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
  823. package/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  824. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
  825. package/dist/modes/interactive/components/branch-summary-message.js +42 -0
  826. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
  827. package/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  828. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
  829. package/dist/modes/interactive/components/compaction-summary-message.js +43 -0
  830. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
  831. package/dist/modes/interactive/components/config-selector.d.ts +71 -0
  832. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
  833. package/dist/modes/interactive/components/config-selector.js +496 -0
  834. package/dist/modes/interactive/components/config-selector.js.map +1 -0
  835. package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  836. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
  837. package/dist/modes/interactive/components/countdown-timer.js +28 -0
  838. package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
  839. package/dist/modes/interactive/components/custom-editor.d.ts +29 -0
  840. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
  841. package/dist/modes/interactive/components/custom-editor.js +113 -0
  842. package/dist/modes/interactive/components/custom-editor.js.map +1 -0
  843. package/dist/modes/interactive/components/custom-message.d.ts +20 -0
  844. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
  845. package/dist/modes/interactive/components/custom-message.js +74 -0
  846. package/dist/modes/interactive/components/custom-message.js.map +1 -0
  847. package/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  848. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -0
  849. package/dist/modes/interactive/components/daxnuts.js +138 -0
  850. package/dist/modes/interactive/components/daxnuts.js.map +1 -0
  851. package/dist/modes/interactive/components/diff.d.ts +12 -0
  852. package/dist/modes/interactive/components/diff.d.ts.map +1 -0
  853. package/dist/modes/interactive/components/diff.js +151 -0
  854. package/dist/modes/interactive/components/diff.js.map +1 -0
  855. package/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  856. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
  857. package/dist/modes/interactive/components/dynamic-border.js +20 -0
  858. package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
  859. package/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
  860. package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -0
  861. package/dist/modes/interactive/components/earendil-announcement.js +40 -0
  862. package/dist/modes/interactive/components/earendil-announcement.js.map +1 -0
  863. package/dist/modes/interactive/components/extension-editor.d.ts +20 -0
  864. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
  865. package/dist/modes/interactive/components/extension-editor.js +106 -0
  866. package/dist/modes/interactive/components/extension-editor.js.map +1 -0
  867. package/dist/modes/interactive/components/extension-input.d.ts +23 -0
  868. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
  869. package/dist/modes/interactive/components/extension-input.js +55 -0
  870. package/dist/modes/interactive/components/extension-input.js.map +1 -0
  871. package/dist/modes/interactive/components/extension-selector.d.ts +26 -0
  872. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
  873. package/dist/modes/interactive/components/extension-selector.js +75 -0
  874. package/dist/modes/interactive/components/extension-selector.js.map +1 -0
  875. package/dist/modes/interactive/components/footer.d.ts +27 -0
  876. package/dist/modes/interactive/components/footer.d.ts.map +1 -0
  877. package/dist/modes/interactive/components/footer.js +199 -0
  878. package/dist/modes/interactive/components/footer.js.map +1 -0
  879. package/dist/modes/interactive/components/index.d.ts +32 -0
  880. package/dist/modes/interactive/components/index.d.ts.map +1 -0
  881. package/dist/modes/interactive/components/index.js +33 -0
  882. package/dist/modes/interactive/components/index.js.map +1 -0
  883. package/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
  884. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
  885. package/dist/modes/interactive/components/keybinding-hints.js +36 -0
  886. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
  887. package/dist/modes/interactive/components/login-dialog.d.ts +46 -0
  888. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
  889. package/dist/modes/interactive/components/login-dialog.js +158 -0
  890. package/dist/modes/interactive/components/login-dialog.js.map +1 -0
  891. package/dist/modes/interactive/components/model-selector.d.ts +47 -0
  892. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
  893. package/dist/modes/interactive/components/model-selector.js +266 -0
  894. package/dist/modes/interactive/components/model-selector.js.map +1 -0
  895. package/dist/modes/interactive/components/oauth-selector.d.ts +31 -0
  896. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
  897. package/dist/modes/interactive/components/oauth-selector.js +156 -0
  898. package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
  899. package/dist/modes/interactive/components/scoped-models-selector.d.ts +42 -0
  900. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
  901. package/dist/modes/interactive/components/scoped-models-selector.js +286 -0
  902. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
  903. package/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  904. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
  905. package/dist/modes/interactive/components/session-selector-search.js +155 -0
  906. package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
  907. package/dist/modes/interactive/components/session-selector.d.ts +96 -0
  908. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
  909. package/dist/modes/interactive/components/session-selector.js +836 -0
  910. package/dist/modes/interactive/components/session-selector.js.map +1 -0
  911. package/dist/modes/interactive/components/settings-selector.d.ts +67 -0
  912. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
  913. package/dist/modes/interactive/components/settings-selector.js +371 -0
  914. package/dist/modes/interactive/components/settings-selector.js.map +1 -0
  915. package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  916. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
  917. package/dist/modes/interactive/components/show-images-selector.js +38 -0
  918. package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
  919. package/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  920. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
  921. package/dist/modes/interactive/components/skill-invocation-message.js +45 -0
  922. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
  923. package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  924. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
  925. package/dist/modes/interactive/components/theme-selector.js +48 -0
  926. package/dist/modes/interactive/components/theme-selector.js.map +1 -0
  927. package/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  928. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
  929. package/dist/modes/interactive/components/thinking-selector.js +50 -0
  930. package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
  931. package/dist/modes/interactive/components/tool-execution.d.ts +63 -0
  932. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
  933. package/dist/modes/interactive/components/tool-execution.js +280 -0
  934. package/dist/modes/interactive/components/tool-execution.js.map +1 -0
  935. package/dist/modes/interactive/components/tree-selector.d.ts +89 -0
  936. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
  937. package/dist/modes/interactive/components/tree-selector.js +1079 -0
  938. package/dist/modes/interactive/components/tree-selector.js.map +1 -0
  939. package/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  940. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
  941. package/dist/modes/interactive/components/user-message-selector.js +111 -0
  942. package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
  943. package/dist/modes/interactive/components/user-message.d.ts +10 -0
  944. package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
  945. package/dist/modes/interactive/components/user-message.js +28 -0
  946. package/dist/modes/interactive/components/user-message.js.map +1 -0
  947. package/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  948. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
  949. package/dist/modes/interactive/components/visual-truncate.js +33 -0
  950. package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
  951. package/dist/modes/interactive/interactive-mode.d.ts +369 -0
  952. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
  953. package/dist/modes/interactive/interactive-mode.js +4709 -0
  954. package/dist/modes/interactive/interactive-mode.js.map +1 -0
  955. package/dist/modes/interactive/theme/catppuccin-frappe.json +90 -0
  956. package/dist/modes/interactive/theme/catppuccin-latte.json +90 -0
  957. package/dist/modes/interactive/theme/catppuccin-macchiato.json +90 -0
  958. package/dist/modes/interactive/theme/catppuccin-mocha.json +90 -0
  959. package/dist/modes/interactive/theme/dark.json +85 -0
  960. package/dist/modes/interactive/theme/light.json +84 -0
  961. package/dist/modes/interactive/theme/theme-schema.json +335 -0
  962. package/dist/modes/interactive/theme/theme.d.ts +81 -0
  963. package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
  964. package/dist/modes/interactive/theme/theme.js +970 -0
  965. package/dist/modes/interactive/theme/theme.js.map +1 -0
  966. package/dist/modes/interactive/whimsical-messages.d.ts +5 -0
  967. package/dist/modes/interactive/whimsical-messages.d.ts.map +1 -0
  968. package/dist/modes/interactive/whimsical-messages.js +464 -0
  969. package/dist/modes/interactive/whimsical-messages.js.map +1 -0
  970. package/dist/modes/print-mode.d.ts +28 -0
  971. package/dist/modes/print-mode.d.ts.map +1 -0
  972. package/dist/modes/print-mode.js +131 -0
  973. package/dist/modes/print-mode.js.map +1 -0
  974. package/dist/modes/rpc/jsonl.d.ts +17 -0
  975. package/dist/modes/rpc/jsonl.d.ts.map +1 -0
  976. package/dist/modes/rpc/jsonl.js +49 -0
  977. package/dist/modes/rpc/jsonl.js.map +1 -0
  978. package/dist/modes/rpc/rpc-client.d.ts +224 -0
  979. package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
  980. package/dist/modes/rpc/rpc-client.js +409 -0
  981. package/dist/modes/rpc/rpc-client.js.map +1 -0
  982. package/dist/modes/rpc/rpc-mode.d.ts +20 -0
  983. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
  984. package/dist/modes/rpc/rpc-mode.js +601 -0
  985. package/dist/modes/rpc/rpc-mode.js.map +1 -0
  986. package/dist/modes/rpc/rpc-types.d.ts +419 -0
  987. package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
  988. package/dist/modes/rpc/rpc-types.js +8 -0
  989. package/dist/modes/rpc/rpc-types.js.map +1 -0
  990. package/dist/package-manager-cli.d.ts +4 -0
  991. package/dist/package-manager-cli.d.ts.map +1 -0
  992. package/dist/package-manager-cli.js +460 -0
  993. package/dist/package-manager-cli.js.map +1 -0
  994. package/dist/utils/ansi.d.ts +2 -0
  995. package/dist/utils/ansi.d.ts.map +1 -0
  996. package/dist/utils/ansi.js +52 -0
  997. package/dist/utils/ansi.js.map +1 -0
  998. package/dist/utils/changelog.d.ts +21 -0
  999. package/dist/utils/changelog.d.ts.map +1 -0
  1000. package/dist/utils/changelog.js +87 -0
  1001. package/dist/utils/changelog.js.map +1 -0
  1002. package/dist/utils/child-process.d.ts +12 -0
  1003. package/dist/utils/child-process.d.ts.map +1 -0
  1004. package/dist/utils/child-process.js +86 -0
  1005. package/dist/utils/child-process.js.map +1 -0
  1006. package/dist/utils/clipboard-image.d.ts +11 -0
  1007. package/dist/utils/clipboard-image.d.ts.map +1 -0
  1008. package/dist/utils/clipboard-image.js +245 -0
  1009. package/dist/utils/clipboard-image.js.map +1 -0
  1010. package/dist/utils/clipboard-native.d.ts +8 -0
  1011. package/dist/utils/clipboard-native.d.ts.map +1 -0
  1012. package/dist/utils/clipboard-native.js +14 -0
  1013. package/dist/utils/clipboard-native.js.map +1 -0
  1014. package/dist/utils/clipboard.d.ts +2 -0
  1015. package/dist/utils/clipboard.d.ts.map +1 -0
  1016. package/dist/utils/clipboard.js +117 -0
  1017. package/dist/utils/clipboard.js.map +1 -0
  1018. package/dist/utils/exif-orientation.d.ts +5 -0
  1019. package/dist/utils/exif-orientation.d.ts.map +1 -0
  1020. package/dist/utils/exif-orientation.js +158 -0
  1021. package/dist/utils/exif-orientation.js.map +1 -0
  1022. package/dist/utils/frontmatter.d.ts +8 -0
  1023. package/dist/utils/frontmatter.d.ts.map +1 -0
  1024. package/dist/utils/frontmatter.js +26 -0
  1025. package/dist/utils/frontmatter.js.map +1 -0
  1026. package/dist/utils/fs-watch.d.ts +5 -0
  1027. package/dist/utils/fs-watch.d.ts.map +1 -0
  1028. package/dist/utils/fs-watch.js +25 -0
  1029. package/dist/utils/fs-watch.js.map +1 -0
  1030. package/dist/utils/git.d.ts +26 -0
  1031. package/dist/utils/git.d.ts.map +1 -0
  1032. package/dist/utils/git.js +163 -0
  1033. package/dist/utils/git.js.map +1 -0
  1034. package/dist/utils/html.d.ts +7 -0
  1035. package/dist/utils/html.d.ts.map +1 -0
  1036. package/dist/utils/html.js +40 -0
  1037. package/dist/utils/html.js.map +1 -0
  1038. package/dist/utils/image-convert.d.ts +9 -0
  1039. package/dist/utils/image-convert.d.ts.map +1 -0
  1040. package/dist/utils/image-convert.js +39 -0
  1041. package/dist/utils/image-convert.js.map +1 -0
  1042. package/dist/utils/image-resize.d.ts +36 -0
  1043. package/dist/utils/image-resize.d.ts.map +1 -0
  1044. package/dist/utils/image-resize.js +137 -0
  1045. package/dist/utils/image-resize.js.map +1 -0
  1046. package/dist/utils/mime.d.ts +3 -0
  1047. package/dist/utils/mime.d.ts.map +1 -0
  1048. package/dist/utils/mime.js +69 -0
  1049. package/dist/utils/mime.js.map +1 -0
  1050. package/dist/utils/paths.d.ts +16 -0
  1051. package/dist/utils/paths.d.ts.map +1 -0
  1052. package/dist/utils/paths.js +50 -0
  1053. package/dist/utils/paths.js.map +1 -0
  1054. package/dist/utils/photon.d.ts +21 -0
  1055. package/dist/utils/photon.d.ts.map +1 -0
  1056. package/dist/utils/photon.js +121 -0
  1057. package/dist/utils/photon.js.map +1 -0
  1058. package/dist/utils/pi-user-agent.d.ts +2 -0
  1059. package/dist/utils/pi-user-agent.d.ts.map +1 -0
  1060. package/dist/utils/pi-user-agent.js +5 -0
  1061. package/dist/utils/pi-user-agent.js.map +1 -0
  1062. package/dist/utils/shell.d.ts +30 -0
  1063. package/dist/utils/shell.d.ts.map +1 -0
  1064. package/dist/utils/shell.js +190 -0
  1065. package/dist/utils/shell.js.map +1 -0
  1066. package/dist/utils/sleep.d.ts +5 -0
  1067. package/dist/utils/sleep.d.ts.map +1 -0
  1068. package/dist/utils/sleep.js +17 -0
  1069. package/dist/utils/sleep.js.map +1 -0
  1070. package/dist/utils/syntax-highlight.d.ts +12 -0
  1071. package/dist/utils/syntax-highlight.d.ts.map +1 -0
  1072. package/dist/utils/syntax-highlight.js +118 -0
  1073. package/dist/utils/syntax-highlight.js.map +1 -0
  1074. package/dist/utils/tools-manager.d.ts +3 -0
  1075. package/dist/utils/tools-manager.d.ts.map +1 -0
  1076. package/dist/utils/tools-manager.js +325 -0
  1077. package/dist/utils/tools-manager.js.map +1 -0
  1078. package/dist/utils/version-check.d.ts +14 -0
  1079. package/dist/utils/version-check.d.ts.map +1 -0
  1080. package/dist/utils/version-check.js +76 -0
  1081. package/dist/utils/version-check.js.map +1 -0
  1082. package/docs/compaction.md +394 -0
  1083. package/docs/custom-provider.md +646 -0
  1084. package/docs/development.md +71 -0
  1085. package/docs/docs.json +148 -0
  1086. package/docs/extensions.md +2596 -0
  1087. package/docs/images/doom-extension.png +0 -0
  1088. package/docs/images/exy.png +3 -0
  1089. package/docs/images/interactive-mode.png +0 -0
  1090. package/docs/images/tree-view.png +0 -0
  1091. package/docs/index.md +70 -0
  1092. package/docs/json.md +82 -0
  1093. package/docs/keybindings.md +197 -0
  1094. package/docs/models.md +474 -0
  1095. package/docs/packages.md +223 -0
  1096. package/docs/prompt-templates.md +88 -0
  1097. package/docs/providers.md +243 -0
  1098. package/docs/quickstart.md +142 -0
  1099. package/docs/rpc.md +1407 -0
  1100. package/docs/sdk.md +1129 -0
  1101. package/docs/session-format.md +412 -0
  1102. package/docs/sessions.md +137 -0
  1103. package/docs/settings.md +279 -0
  1104. package/docs/shell-aliases.md +13 -0
  1105. package/docs/skills.md +232 -0
  1106. package/docs/terminal-setup.md +106 -0
  1107. package/docs/termux.md +127 -0
  1108. package/docs/themes.md +299 -0
  1109. package/docs/tmux.md +61 -0
  1110. package/docs/tui.md +918 -0
  1111. package/docs/usage.md +277 -0
  1112. package/docs/windows.md +17 -0
  1113. package/examples/README.md +25 -0
  1114. package/examples/extensions/README.md +208 -0
  1115. package/examples/extensions/auto-commit-on-exit.ts +49 -0
  1116. package/examples/extensions/bash-spawn-hook.ts +30 -0
  1117. package/examples/extensions/bookmark.ts +50 -0
  1118. package/examples/extensions/border-status-editor.ts +150 -0
  1119. package/examples/extensions/built-in-tool-renderer.ts +249 -0
  1120. package/examples/extensions/claude-rules.ts +86 -0
  1121. package/examples/extensions/commands.ts +72 -0
  1122. package/examples/extensions/confirm-destructive.ts +59 -0
  1123. package/examples/extensions/custom-compaction.ts +127 -0
  1124. package/examples/extensions/custom-footer.ts +64 -0
  1125. package/examples/extensions/custom-header.ts +73 -0
  1126. package/examples/extensions/custom-provider-anthropic/index.ts +604 -0
  1127. package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
  1128. package/examples/extensions/custom-provider-anthropic/package.json +19 -0
  1129. package/examples/extensions/custom-provider-gitlab-duo/index.ts +349 -0
  1130. package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
  1131. package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
  1132. package/examples/extensions/dirty-repo-guard.ts +56 -0
  1133. package/examples/extensions/doom-overlay/README.md +46 -0
  1134. package/examples/extensions/doom-overlay/doom/build.sh +152 -0
  1135. package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
  1136. package/examples/extensions/doom-overlay/doom-component.ts +132 -0
  1137. package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
  1138. package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
  1139. package/examples/extensions/doom-overlay/index.ts +74 -0
  1140. package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
  1141. package/examples/extensions/dynamic-resources/SKILL.md +8 -0
  1142. package/examples/extensions/dynamic-resources/dynamic.json +79 -0
  1143. package/examples/extensions/dynamic-resources/dynamic.md +5 -0
  1144. package/examples/extensions/dynamic-resources/index.ts +15 -0
  1145. package/examples/extensions/dynamic-tools.ts +74 -0
  1146. package/examples/extensions/event-bus.ts +43 -0
  1147. package/examples/extensions/file-trigger.ts +41 -0
  1148. package/examples/extensions/git-checkpoint.ts +53 -0
  1149. package/examples/extensions/github-issue-autocomplete.ts +185 -0
  1150. package/examples/extensions/handoff.ts +191 -0
  1151. package/examples/extensions/hello.ts +26 -0
  1152. package/examples/extensions/hidden-thinking-label.ts +53 -0
  1153. package/examples/extensions/inline-bash.ts +94 -0
  1154. package/examples/extensions/input-transform.ts +43 -0
  1155. package/examples/extensions/interactive-shell.ts +196 -0
  1156. package/examples/extensions/mac-system-theme.ts +47 -0
  1157. package/examples/extensions/message-renderer.ts +59 -0
  1158. package/examples/extensions/minimal-mode.ts +426 -0
  1159. package/examples/extensions/modal-editor.ts +85 -0
  1160. package/examples/extensions/model-status.ts +31 -0
  1161. package/examples/extensions/notify.ts +55 -0
  1162. package/examples/extensions/overlay-qa-tests.ts +1348 -0
  1163. package/examples/extensions/overlay-test.ts +150 -0
  1164. package/examples/extensions/permission-gate.ts +34 -0
  1165. package/examples/extensions/pirate.ts +47 -0
  1166. package/examples/extensions/plan-mode/README.md +65 -0
  1167. package/examples/extensions/plan-mode/index.ts +340 -0
  1168. package/examples/extensions/plan-mode/utils.ts +168 -0
  1169. package/examples/extensions/preset.ts +430 -0
  1170. package/examples/extensions/prompt-customizer.ts +97 -0
  1171. package/examples/extensions/protected-paths.ts +30 -0
  1172. package/examples/extensions/provider-payload.ts +18 -0
  1173. package/examples/extensions/qna.ts +122 -0
  1174. package/examples/extensions/question.ts +264 -0
  1175. package/examples/extensions/questionnaire.ts +427 -0
  1176. package/examples/extensions/rainbow-editor.ts +88 -0
  1177. package/examples/extensions/reload-runtime.ts +37 -0
  1178. package/examples/extensions/rpc-demo.ts +118 -0
  1179. package/examples/extensions/sandbox/index.ts +321 -0
  1180. package/examples/extensions/sandbox/package-lock.json +92 -0
  1181. package/examples/extensions/sandbox/package.json +19 -0
  1182. package/examples/extensions/send-user-message.ts +97 -0
  1183. package/examples/extensions/session-name.ts +27 -0
  1184. package/examples/extensions/shutdown-command.ts +63 -0
  1185. package/examples/extensions/snake.ts +343 -0
  1186. package/examples/extensions/space-invaders.ts +560 -0
  1187. package/examples/extensions/ssh.ts +220 -0
  1188. package/examples/extensions/status-line.ts +32 -0
  1189. package/examples/extensions/structured-output.ts +65 -0
  1190. package/examples/extensions/subagent/README.md +172 -0
  1191. package/examples/extensions/subagent/agents/planner.md +37 -0
  1192. package/examples/extensions/subagent/agents/reviewer.md +35 -0
  1193. package/examples/extensions/subagent/agents/scout.md +50 -0
  1194. package/examples/extensions/subagent/agents/worker.md +24 -0
  1195. package/examples/extensions/subagent/agents.ts +126 -0
  1196. package/examples/extensions/subagent/index.ts +987 -0
  1197. package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
  1198. package/examples/extensions/subagent/prompts/implement.md +10 -0
  1199. package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
  1200. package/examples/extensions/summarize.ts +206 -0
  1201. package/examples/extensions/system-prompt-header.ts +17 -0
  1202. package/examples/extensions/tic-tac-toe.ts +1008 -0
  1203. package/examples/extensions/timed-confirm.ts +70 -0
  1204. package/examples/extensions/titlebar-spinner.ts +58 -0
  1205. package/examples/extensions/todo.ts +297 -0
  1206. package/examples/extensions/tool-override.ts +144 -0
  1207. package/examples/extensions/tools.ts +141 -0
  1208. package/examples/extensions/trigger-compact.ts +50 -0
  1209. package/examples/extensions/truncated-tool.ts +195 -0
  1210. package/examples/extensions/widget-placement.ts +9 -0
  1211. package/examples/extensions/with-deps/index.ts +32 -0
  1212. package/examples/extensions/with-deps/package-lock.json +31 -0
  1213. package/examples/extensions/with-deps/package.json +22 -0
  1214. package/examples/extensions/working-indicator.ts +123 -0
  1215. package/examples/extensions/working-message-test.ts +25 -0
  1216. package/examples/rpc-extension-ui.ts +632 -0
  1217. package/examples/sdk/01-minimal.ts +26 -0
  1218. package/examples/sdk/02-custom-model.ts +53 -0
  1219. package/examples/sdk/03-custom-prompt.ts +75 -0
  1220. package/examples/sdk/04-skills.ts +55 -0
  1221. package/examples/sdk/05-tools.ts +48 -0
  1222. package/examples/sdk/06-extensions.ts +99 -0
  1223. package/examples/sdk/07-context-files.ts +47 -0
  1224. package/examples/sdk/08-prompt-templates.ts +51 -0
  1225. package/examples/sdk/09-api-keys-and-oauth.ts +52 -0
  1226. package/examples/sdk/10-settings.ts +53 -0
  1227. package/examples/sdk/11-sessions.ts +52 -0
  1228. package/examples/sdk/12-full-control.ts +77 -0
  1229. package/examples/sdk/13-session-runtime.ts +67 -0
  1230. package/examples/sdk/README.md +144 -0
  1231. package/package.json +94 -19
  1232. package/bin/atomic +0 -82
  1233. /package/{LICENSE → dist/builtin/workflows/LICENSE} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-box-renderer.js","sourceRoot":"","sources":["../../../../../../../src/core/tools/ask-user-question/view/components/preview/preview-box-renderer.ts"],"names":[],"mappings":"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","sourcesContent":["import { truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\n\nconst ANSI_SGR_RE = /\\x1b\\[[0-9;]*m/g;\nconst ANSI_OSC8_RE = /\\x1b\\]8;[^\\x07\\x1b]*(?:\\x07|\\x1b\\\\)/g;\nconst FENCE_MARKER_RE = /^`{3}/;\n\n/** Top + bottom border rows consumed by `renderBorderedBox`. */\nexport const BORDER_VERTICAL_OVERHEAD = 2;\n/** Left + right vertical bar columns (`│ ... │`) consumed by `renderBorderedBox`. */\nexport const BORDER_HORIZONTAL_OVERHEAD = 2;\n/** Inner horizontal padding (1 col) between each border bar and content area. */\nexport const BORDER_INNER_PADDING_HORIZONTAL = 1;\n/** Floor for the preview box's inner content width — CC parity (`PreviewBox.minWidth`). */\nexport const BOX_MIN_CONTENT_WIDTH = 40;\n\n/**\n * Drops fenced-code-block marker lines (` ``` ` opener/closer) from rendered markdown.\n * pi-tui's Markdown emits literal opening ` ```lang ` and closing ` ``` ` lines around\n * code blocks; this strip leaves only the highlighted code body. Inline code\n * (`codespan`) is unaffected — pi-tui already renders it without backticks.\n */\nexport function stripFenceMarkers(lines: readonly string[]): string[] {\n\treturn lines.filter((line) => {\n\t\tconst clean = line.replace(ANSI_SGR_RE, \"\").replace(ANSI_OSC8_RE, \"\");\n\t\treturn !FENCE_MARKER_RE.test(clean);\n\t});\n}\n\n/**\n * Wraps `lines` in a 4-sided ASCII border with 1 col of inner horizontal padding.\n * Layout per content row: `│` + ` ` + content padded to `contentInner` + ` ` + `│`,\n * where `contentInner = width - BORDER_HORIZONTAL_OVERHEAD - 2 * BORDER_INNER_PADDING_HORIZONTAL`.\n * Top/bottom dash runs span corner-to-corner (`width - BORDER_HORIZONTAL_OVERHEAD`). When\n * `hidden > 0`, the bottom-row dash run is replaced with ` ✂ ── N lines hidden ── ` (corners stay).\n */\nexport function renderBorderedBox(\n\tlines: readonly string[],\n\twidth: number,\n\tcolorFn: (s: string) => string,\n\thidden = 0,\n): string[] {\n\tconst dashSpan = Math.max(1, width - BORDER_HORIZONTAL_OVERHEAD);\n\tconst contentInner = Math.max(1, dashSpan - 2 * BORDER_INNER_PADDING_HORIZONTAL);\n\tconst pad = \" \".repeat(BORDER_INNER_PADDING_HORIZONTAL);\n\tconst top = colorFn(`┌${\"─\".repeat(dashSpan)}┐`);\n\tconst out: string[] = [top];\n\tfor (const line of lines) {\n\t\tconst padded = truncateToWidth(line, contentInner, \"\", true);\n\t\tout.push(`${colorFn(\"│\")}${pad}${padded}${pad}${colorFn(\"│\")}`);\n\t}\n\tif (hidden > 0) {\n\t\tconst indicator = ` ✂ ── ${hidden} lines hidden ── `;\n\t\tconst space = dashSpan - indicator.length;\n\t\tconst leftFill = \"─\".repeat(Math.max(0, Math.floor(space / 2)));\n\t\tconst rightFill = \"─\".repeat(Math.max(0, dashSpan - leftFill.length - indicator.length));\n\t\tout.push(colorFn(`└${leftFill}${indicator}${rightFill}┘`));\n\t} else {\n\t\tout.push(colorFn(`└${\"─\".repeat(dashSpan)}┘`));\n\t}\n\treturn out;\n}\n\n/**\n * Compute box dimensions from content lines. Pure of args.\n *\n * CC parity:\n * contentWidth = max(minWidth, widestRenderedLine)\n * boxWidth = min(contentWidth + 4, effectiveMaxWidth)\n *\n * Trailing whitespace is stripped before measuring because pi-tui's\n * `Markdown.render(width)` pads every line to `width`, which would otherwise force\n * the box to fill the whole column allocation.\n */\nexport function computeBoxDimensions(\n\tcontentLines: readonly string[],\n\tmaxInnerWidth: number,\n): { innerWidth: number; boxWidth: number } {\n\tlet widest = Math.min(BOX_MIN_CONTENT_WIDTH, maxInnerWidth);\n\tfor (const line of contentLines) {\n\t\tconst w = visibleWidth(line.replace(/\\s+$/, \"\"));\n\t\tif (w > widest) widest = w;\n\t}\n\tconst innerWidth = Math.min(widest, maxInnerWidth);\n\tconst boxWidth = innerWidth + BORDER_HORIZONTAL_OVERHEAD + 2 * BORDER_INNER_PADDING_HORIZONTAL;\n\treturn { innerWidth, boxWidth };\n}\n"]}
@@ -0,0 +1,116 @@
1
+ import type { QuestionData } from "../../../tool/types.js";
2
+ import type { WrappingSelectItem } from "../wrapping-select.js";
3
+ /** Min terminal/pane width for the side-by-side layout to engage. */
4
+ export declare const PREVIEW_MIN_WIDTH = 100;
5
+ /** Visual gap between options column and preview column in side-by-side. */
6
+ export declare const PREVIEW_COLUMN_GAP = 2;
7
+ /** 1 col padding inside the preview column (between gap and `│`). */
8
+ export declare const PREVIEW_PADDING_LEFT = 1;
9
+ /** Empty rows between options and preview blocks in stacked (narrow) layout. */
10
+ export declare const STACKED_GAP_ROWS = 1;
11
+ /** Floor for the adaptive left column width — prevents collapse on short labels. */
12
+ export declare const MIN_LEFT = 30;
13
+ /** Ceiling ratio: left column never exceeds this fraction of pane width. */
14
+ export declare const MAX_LEFT_RATIO = 0.5;
15
+ /** Floor for the preview column width — prevents right-side collapse on narrow terminals. */
16
+ export declare const MIN_PREVIEW_WIDTH = 45;
17
+ /** visibleWidth(" ✔") = 2 (space + ✔ codepoint). Reserved on the longest-label measurement
18
+ * so a confirmed row never gets truncated when MIN_LEFT clamps the column. */
19
+ export declare const CONFIRMED_OVERHEAD = 2;
20
+ export type PreviewLayoutMode = "side-by-side" | "stacked";
21
+ /**
22
+ * Decide layout mode from terminal + pane widths. Pure of inputs.
23
+ *
24
+ * The terminal-width gate is the AND check from the previous `preview-pane.ts` —
25
+ * lifted here so the decision is computed ONCE per render and threaded explicitly
26
+ * through `previewBlockHeight`. Removes the bug class where `previewBlockHeight`
27
+ * re-derived `sideBySide` from a column width (already < pane width post-split),
28
+ * capping height too short.
29
+ */
30
+ export declare function decideLayout(terminalWidth: number, paneWidth: number): PreviewLayoutMode;
31
+ /**
32
+ * Compute the adaptive left column width from option labels.
33
+ * Pure function — deterministic for a given (items, totalForNumbering, paneWidth).
34
+ *
35
+ * Pipeline:
36
+ * 1. Measure: longest visible label width + prefix overhead + confirmed-mark overhead
37
+ * 2. Clamp: floor MIN_LEFT, ceiling paneWidth * MAX_LEFT_RATIO
38
+ * 3. Safety net: never exceed available = paneWidth - GAP - MIN_PREVIEW_WIDTH
39
+ */
40
+ export declare function adaptiveLeftWidth(items: readonly WrappingSelectItem[], totalForNumbering: number, paneWidth: number): number;
41
+ /**
42
+ * Cross-tab maximum left-column width. Aggregates `adaptiveLeftWidth` over every tab
43
+ * and returns the widest result, so the options column stays stable on tab switch.
44
+ *
45
+ * Pure function — `tabs.length` MUST equal `itemsByTab.length`. Multi-select tabs
46
+ * use `items.length` for numbering; single-select tabs add 1 for the chat row slot.
47
+ * Floor is `MIN_LEFT` so an all-empty input still produces a usable column.
48
+ */
49
+ export declare function crossTabMaxLeftWidth(tabs: ReadonlyArray<{
50
+ multiSelect?: boolean;
51
+ }>, itemsByTab: ReadonlyArray<readonly WrappingSelectItem[]>, paneWidth: number): number;
52
+ /**
53
+ * Source-line probe: measures the widest source line across all options' previews.
54
+ * Returns 0 when no option carries a preview.
55
+ *
56
+ * V1 heuristic — works well for tree/table/heading/list content where source-line
57
+ * width ≈ rendered width. Paragraphs overstate (source width "wants" the full pane);
58
+ * the worst case is "donation does nothing useful" — fallback to the label-driven path.
59
+ * Upgrade path: replace with a render-width probe that invokes Markdown at a probe width.
60
+ *
61
+ * Pure function — O(total chars) per question; no Markdown invocation, no cache interaction.
62
+ */
63
+ export declare function previewSourceWidth(question: QuestionData): number;
64
+ /**
65
+ * Cross-tab/cross-option preview budget. Iterates all questions, computes each question's
66
+ * preview appetite via `previewSourceWidth`, adds box + padding overhead (5 cols), and
67
+ * returns the widest result. Floor is `MIN_PREVIEW_WIDTH` so a previewless question still
68
+ * reserves a usable column. Ceiling ensures the left column retains its `MIN_LEFT` floor.
69
+ *
70
+ * Pure function — same cross-tab max pattern as `crossTabMaxLeftWidth`.
71
+ */
72
+ export declare function crossTabPreviewBudget(questions: readonly QuestionData[], paneWidth: number): number;
73
+ /**
74
+ * Cross-tab left-column width with slack donation. Combines the label-driven width
75
+ * (from `crossTabMaxLeftWidth`) with the slack donated by narrow previews.
76
+ *
77
+ * Pipeline:
78
+ * 1. `labelDriven` = `crossTabMaxLeftWidth(tabs, itemsByTab, paneWidth)`
79
+ * 2. `previewBudget` = `crossTabPreviewBudget(questions, paneWidth)`
80
+ * 3. `slackDonation` = `paneWidth − GAP − previewBudget`
81
+ * 4. Return `min(max(labelDriven, slackDonation), ceiling)` where `ceiling = paneWidth − GAP − MIN_PREVIEW_WIDTH`
82
+ *
83
+ * Invariants:
84
+ * - Floor: result ≥ MIN_LEFT (labelDriven ≥ MIN_LEFT)
85
+ * - Preview floor: right column ≥ MIN_PREVIEW_WIDTH (ceiling enforces this)
86
+ * - Cross-tab stability: both reductions are tab-independent
87
+ * - Determinism: pure of (questions, itemsByTab, paneWidth)
88
+ *
89
+ * `crossTabMaxLeftWidth` is NOT replaced — it continues to exist as the primitive.
90
+ * `MAX_LEFT_RATIO` caps the label-driven path inside `adaptiveLeftWidth`; donation
91
+ * operates above the cap when preview slack is available.
92
+ */
93
+ export declare function crossTabLeftWidthWithDonation(tabs: ReadonlyArray<{
94
+ multiSelect?: boolean;
95
+ }>, itemsByTab: ReadonlyArray<readonly WrappingSelectItem[]>, questions: readonly QuestionData[], paneWidth: number): number;
96
+ /**
97
+ * Width allocation for side-by-side mode.
98
+ * `adaptiveLeft` is the pre-computed left column width (from `adaptiveLeftWidth`,
99
+ * cross-tab aggregated). The Math.max(1, ...) calls keep both columns >= 1 col on
100
+ * extreme inputs.
101
+ */
102
+ export declare function columnWidths(paneWidth: number, adaptiveLeft: number): {
103
+ leftWidth: number;
104
+ rightWidth: number;
105
+ gap: number;
106
+ };
107
+ /**
108
+ * Returns the widths actually passed to `options.render` and `previewLines` inside
109
+ * `render()`. Stacked uses the full pane width for both; side-by-side splits via
110
+ * `columnWidths`, with the preview column offset by `PREVIEW_PADDING_LEFT`.
111
+ */
112
+ export declare function bodyWidths(paneWidth: number, mode: PreviewLayoutMode, adaptiveLeft: number): {
113
+ optionsWidth: number;
114
+ previewWidth: number;
115
+ };
116
+ //# sourceMappingURL=preview-layout-decider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-layout-decider.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/tools/ask-user-question/view/components/preview/preview-layout-decider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAGhE,qEAAqE;AACrE,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,4EAA4E;AAC5E,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,qEAAqE;AACrE,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC,gFAAgF;AAChF,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,oFAAoF;AACpF,eAAO,MAAM,QAAQ,KAAK,CAAC;AAC3B,4EAA4E;AAC5E,eAAO,MAAM,cAAc,MAAM,CAAC;AAClC,6FAA6F;AAC7F,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC;+EAC+E;AAC/E,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,SAAS,CAAC;AAE3D;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,iBAAiB,CAExF;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,SAAS,kBAAkB,EAAE,EACpC,iBAAiB,EAAE,MAAM,EACzB,SAAS,EAAE,MAAM,GACf,MAAM,CAYR;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CACnC,IAAI,EAAE,aAAa,CAAC;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,EAC9C,UAAU,EAAE,aAAa,CAAC,SAAS,kBAAkB,EAAE,CAAC,EACxD,SAAS,EAAE,MAAM,GACf,MAAM,CASR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAWjE;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,SAAS,YAAY,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CASnG;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,6BAA6B,CAC5C,IAAI,EAAE,aAAa,CAAC;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,EAC9C,UAAU,EAAE,aAAa,CAAC,SAAS,kBAAkB,EAAE,CAAC,EACxD,SAAS,EAAE,SAAS,YAAY,EAAE,EAClC,SAAS,EAAE,MAAM,GACf,MAAM,CAUR;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC3B,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GAClB;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAKxD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACzB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,iBAAiB,EACvB,YAAY,EAAE,MAAM,GAClB;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAIhD","sourcesContent":["import { visibleWidth } from \"@earendil-works/pi-tui\";\nimport type { QuestionData } from \"../../../tool/types.js\";\nimport type { WrappingSelectItem } from \"../wrapping-select.js\";\nimport { BORDER_HORIZONTAL_OVERHEAD, BORDER_INNER_PADDING_HORIZONTAL } from \"./preview-box-renderer.js\";\n\n/** Min terminal/pane width for the side-by-side layout to engage. */\nexport const PREVIEW_MIN_WIDTH = 100;\n/** Visual gap between options column and preview column in side-by-side. */\nexport const PREVIEW_COLUMN_GAP = 2;\n/** 1 col padding inside the preview column (between gap and `│`). */\nexport const PREVIEW_PADDING_LEFT = 1;\n/** Empty rows between options and preview blocks in stacked (narrow) layout. */\nexport const STACKED_GAP_ROWS = 1;\n\n/** Floor for the adaptive left column width — prevents collapse on short labels. */\nexport const MIN_LEFT = 30;\n/** Ceiling ratio: left column never exceeds this fraction of pane width. */\nexport const MAX_LEFT_RATIO = 0.5;\n/** Floor for the preview column width — prevents right-side collapse on narrow terminals. */\nexport const MIN_PREVIEW_WIDTH = 45;\n/** visibleWidth(\" ✔\") = 2 (space + ✔ codepoint). Reserved on the longest-label measurement\n * so a confirmed row never gets truncated when MIN_LEFT clamps the column. */\nexport const CONFIRMED_OVERHEAD = 2;\n\nexport type PreviewLayoutMode = \"side-by-side\" | \"stacked\";\n\n/**\n * Decide layout mode from terminal + pane widths. Pure of inputs.\n *\n * The terminal-width gate is the AND check from the previous `preview-pane.ts` —\n * lifted here so the decision is computed ONCE per render and threaded explicitly\n * through `previewBlockHeight`. Removes the bug class where `previewBlockHeight`\n * re-derived `sideBySide` from a column width (already < pane width post-split),\n * capping height too short.\n */\nexport function decideLayout(terminalWidth: number, paneWidth: number): PreviewLayoutMode {\n\treturn terminalWidth >= PREVIEW_MIN_WIDTH && paneWidth >= PREVIEW_MIN_WIDTH ? \"side-by-side\" : \"stacked\";\n}\n\n/**\n * Compute the adaptive left column width from option labels.\n * Pure function — deterministic for a given (items, totalForNumbering, paneWidth).\n *\n * Pipeline:\n * 1. Measure: longest visible label width + prefix overhead + confirmed-mark overhead\n * 2. Clamp: floor MIN_LEFT, ceiling paneWidth * MAX_LEFT_RATIO\n * 3. Safety net: never exceed available = paneWidth - GAP - MIN_PREVIEW_WIDTH\n */\nexport function adaptiveLeftWidth(\n\titems: readonly WrappingSelectItem[],\n\ttotalForNumbering: number,\n\tpaneWidth: number,\n): number {\n\tconst prefixW = String(Math.max(1, totalForNumbering)).length + 4; // digits + \"❯ \" + \". \"\n\tconst confirmedOverhead = CONFIRMED_OVERHEAD; // visibleWidth(\" ✔\") = 2 (space + ✔ codepoint)\n\tlet maxLabel = 0;\n\tfor (const item of items) {\n\t\tconst w = visibleWidth(item.label);\n\t\tif (w > maxLabel) maxLabel = w;\n\t}\n\tconst desired = maxLabel + prefixW + confirmedOverhead;\n\tconst ratioCapped = Math.min(desired, Math.floor(paneWidth * MAX_LEFT_RATIO));\n\tconst available = paneWidth - PREVIEW_COLUMN_GAP - MIN_PREVIEW_WIDTH;\n\treturn Math.max(MIN_LEFT, Math.min(ratioCapped, Math.max(1, available)));\n}\n\n/**\n * Cross-tab maximum left-column width. Aggregates `adaptiveLeftWidth` over every tab\n * and returns the widest result, so the options column stays stable on tab switch.\n *\n * Pure function — `tabs.length` MUST equal `itemsByTab.length`. Multi-select tabs\n * use `items.length` for numbering; single-select tabs add 1 for the chat row slot.\n * Floor is `MIN_LEFT` so an all-empty input still produces a usable column.\n */\nexport function crossTabMaxLeftWidth(\n\ttabs: ReadonlyArray<{ multiSelect?: boolean }>,\n\titemsByTab: ReadonlyArray<readonly WrappingSelectItem[]>,\n\tpaneWidth: number,\n): number {\n\tlet max = MIN_LEFT;\n\tfor (let i = 0; i < tabs.length; i++) {\n\t\tconst items = itemsByTab[i] ?? [];\n\t\tconst totalForNumbering = tabs[i]?.multiSelect ? items.length : items.length + 1;\n\t\tconst tabWidth = adaptiveLeftWidth(items, totalForNumbering, paneWidth);\n\t\tif (tabWidth > max) max = tabWidth;\n\t}\n\treturn max;\n}\n\n/**\n * Source-line probe: measures the widest source line across all options' previews.\n * Returns 0 when no option carries a preview.\n *\n * V1 heuristic — works well for tree/table/heading/list content where source-line\n * width ≈ rendered width. Paragraphs overstate (source width \"wants\" the full pane);\n * the worst case is \"donation does nothing useful\" — fallback to the label-driven path.\n * Upgrade path: replace with a render-width probe that invokes Markdown at a probe width.\n *\n * Pure function — O(total chars) per question; no Markdown invocation, no cache interaction.\n */\nexport function previewSourceWidth(question: QuestionData): number {\n\tlet max = 0;\n\tfor (const option of question.options) {\n\t\tconst text = option.preview;\n\t\tif (!text) continue;\n\t\tfor (const line of text.split(\"\\n\")) {\n\t\t\tconst w = visibleWidth(line);\n\t\t\tif (w > max) max = w;\n\t\t}\n\t}\n\treturn max;\n}\n\n/**\n * Cross-tab/cross-option preview budget. Iterates all questions, computes each question's\n * preview appetite via `previewSourceWidth`, adds box + padding overhead (5 cols), and\n * returns the widest result. Floor is `MIN_PREVIEW_WIDTH` so a previewless question still\n * reserves a usable column. Ceiling ensures the left column retains its `MIN_LEFT` floor.\n *\n * Pure function — same cross-tab max pattern as `crossTabMaxLeftWidth`.\n */\nexport function crossTabPreviewBudget(questions: readonly QuestionData[], paneWidth: number): number {\n\tlet max = MIN_PREVIEW_WIDTH;\n\tfor (const question of questions) {\n\t\tconst rawWidth = previewSourceWidth(question);\n\t\tconst capped = Math.min(rawWidth, paneWidth - PREVIEW_COLUMN_GAP - MIN_LEFT);\n\t\tconst budget = capped + BORDER_HORIZONTAL_OVERHEAD + 2 * BORDER_INNER_PADDING_HORIZONTAL + PREVIEW_PADDING_LEFT;\n\t\tif (budget > max) max = budget;\n\t}\n\treturn max;\n}\n\n/**\n * Cross-tab left-column width with slack donation. Combines the label-driven width\n * (from `crossTabMaxLeftWidth`) with the slack donated by narrow previews.\n *\n * Pipeline:\n * 1. `labelDriven` = `crossTabMaxLeftWidth(tabs, itemsByTab, paneWidth)`\n * 2. `previewBudget` = `crossTabPreviewBudget(questions, paneWidth)`\n * 3. `slackDonation` = `paneWidth − GAP − previewBudget`\n * 4. Return `min(max(labelDriven, slackDonation), ceiling)` where `ceiling = paneWidth − GAP − MIN_PREVIEW_WIDTH`\n *\n * Invariants:\n * - Floor: result ≥ MIN_LEFT (labelDriven ≥ MIN_LEFT)\n * - Preview floor: right column ≥ MIN_PREVIEW_WIDTH (ceiling enforces this)\n * - Cross-tab stability: both reductions are tab-independent\n * - Determinism: pure of (questions, itemsByTab, paneWidth)\n *\n * `crossTabMaxLeftWidth` is NOT replaced — it continues to exist as the primitive.\n * `MAX_LEFT_RATIO` caps the label-driven path inside `adaptiveLeftWidth`; donation\n * operates above the cap when preview slack is available.\n */\nexport function crossTabLeftWidthWithDonation(\n\ttabs: ReadonlyArray<{ multiSelect?: boolean }>,\n\titemsByTab: ReadonlyArray<readonly WrappingSelectItem[]>,\n\tquestions: readonly QuestionData[],\n\tpaneWidth: number,\n): number {\n\tconst labelDriven = crossTabMaxLeftWidth(tabs, itemsByTab, paneWidth);\n\t// Compact-content guard: labels at MIN_LEFT fit below the floor, so widening\n\t// the column would only inject dead space between the option list and the\n\t// preview box. Skip donation and preserve the compact intent.\n\tif (labelDriven <= MIN_LEFT) return labelDriven;\n\tconst previewBudget = crossTabPreviewBudget(questions, paneWidth);\n\tconst slackDonation = paneWidth - PREVIEW_COLUMN_GAP - previewBudget;\n\tconst ceiling = paneWidth - PREVIEW_COLUMN_GAP - MIN_PREVIEW_WIDTH;\n\treturn Math.min(Math.max(labelDriven, slackDonation), Math.max(1, ceiling));\n}\n\n/**\n * Width allocation for side-by-side mode.\n * `adaptiveLeft` is the pre-computed left column width (from `adaptiveLeftWidth`,\n * cross-tab aggregated). The Math.max(1, ...) calls keep both columns >= 1 col on\n * extreme inputs.\n */\nexport function columnWidths(\n\tpaneWidth: number,\n\tadaptiveLeft: number,\n): { leftWidth: number; rightWidth: number; gap: number } {\n\tconst gap = PREVIEW_COLUMN_GAP;\n\tconst leftWidth = Math.min(adaptiveLeft, Math.max(1, paneWidth - gap - 1));\n\tconst rightWidth = Math.max(1, paneWidth - leftWidth - gap);\n\treturn { leftWidth, rightWidth, gap };\n}\n\n/**\n * Returns the widths actually passed to `options.render` and `previewLines` inside\n * `render()`. Stacked uses the full pane width for both; side-by-side splits via\n * `columnWidths`, with the preview column offset by `PREVIEW_PADDING_LEFT`.\n */\nexport function bodyWidths(\n\tpaneWidth: number,\n\tmode: PreviewLayoutMode,\n\tadaptiveLeft: number,\n): { optionsWidth: number; previewWidth: number } {\n\tif (mode === \"stacked\") return { optionsWidth: paneWidth, previewWidth: paneWidth };\n\tconst { leftWidth, rightWidth } = columnWidths(paneWidth, adaptiveLeft);\n\treturn { optionsWidth: leftWidth, previewWidth: Math.max(1, rightWidth - PREVIEW_PADDING_LEFT) };\n}\n"]}
@@ -0,0 +1,173 @@
1
+ import { visibleWidth } from "@earendil-works/pi-tui";
2
+ import { BORDER_HORIZONTAL_OVERHEAD, BORDER_INNER_PADDING_HORIZONTAL } from "./preview-box-renderer.js";
3
+ /** Min terminal/pane width for the side-by-side layout to engage. */
4
+ export const PREVIEW_MIN_WIDTH = 100;
5
+ /** Visual gap between options column and preview column in side-by-side. */
6
+ export const PREVIEW_COLUMN_GAP = 2;
7
+ /** 1 col padding inside the preview column (between gap and `│`). */
8
+ export const PREVIEW_PADDING_LEFT = 1;
9
+ /** Empty rows between options and preview blocks in stacked (narrow) layout. */
10
+ export const STACKED_GAP_ROWS = 1;
11
+ /** Floor for the adaptive left column width — prevents collapse on short labels. */
12
+ export const MIN_LEFT = 30;
13
+ /** Ceiling ratio: left column never exceeds this fraction of pane width. */
14
+ export const MAX_LEFT_RATIO = 0.5;
15
+ /** Floor for the preview column width — prevents right-side collapse on narrow terminals. */
16
+ export const MIN_PREVIEW_WIDTH = 45;
17
+ /** visibleWidth(" ✔") = 2 (space + ✔ codepoint). Reserved on the longest-label measurement
18
+ * so a confirmed row never gets truncated when MIN_LEFT clamps the column. */
19
+ export const CONFIRMED_OVERHEAD = 2;
20
+ /**
21
+ * Decide layout mode from terminal + pane widths. Pure of inputs.
22
+ *
23
+ * The terminal-width gate is the AND check from the previous `preview-pane.ts` —
24
+ * lifted here so the decision is computed ONCE per render and threaded explicitly
25
+ * through `previewBlockHeight`. Removes the bug class where `previewBlockHeight`
26
+ * re-derived `sideBySide` from a column width (already < pane width post-split),
27
+ * capping height too short.
28
+ */
29
+ export function decideLayout(terminalWidth, paneWidth) {
30
+ return terminalWidth >= PREVIEW_MIN_WIDTH && paneWidth >= PREVIEW_MIN_WIDTH ? "side-by-side" : "stacked";
31
+ }
32
+ /**
33
+ * Compute the adaptive left column width from option labels.
34
+ * Pure function — deterministic for a given (items, totalForNumbering, paneWidth).
35
+ *
36
+ * Pipeline:
37
+ * 1. Measure: longest visible label width + prefix overhead + confirmed-mark overhead
38
+ * 2. Clamp: floor MIN_LEFT, ceiling paneWidth * MAX_LEFT_RATIO
39
+ * 3. Safety net: never exceed available = paneWidth - GAP - MIN_PREVIEW_WIDTH
40
+ */
41
+ export function adaptiveLeftWidth(items, totalForNumbering, paneWidth) {
42
+ const prefixW = String(Math.max(1, totalForNumbering)).length + 4; // digits + "❯ " + ". "
43
+ const confirmedOverhead = CONFIRMED_OVERHEAD; // visibleWidth(" ✔") = 2 (space + ✔ codepoint)
44
+ let maxLabel = 0;
45
+ for (const item of items) {
46
+ const w = visibleWidth(item.label);
47
+ if (w > maxLabel)
48
+ maxLabel = w;
49
+ }
50
+ const desired = maxLabel + prefixW + confirmedOverhead;
51
+ const ratioCapped = Math.min(desired, Math.floor(paneWidth * MAX_LEFT_RATIO));
52
+ const available = paneWidth - PREVIEW_COLUMN_GAP - MIN_PREVIEW_WIDTH;
53
+ return Math.max(MIN_LEFT, Math.min(ratioCapped, Math.max(1, available)));
54
+ }
55
+ /**
56
+ * Cross-tab maximum left-column width. Aggregates `adaptiveLeftWidth` over every tab
57
+ * and returns the widest result, so the options column stays stable on tab switch.
58
+ *
59
+ * Pure function — `tabs.length` MUST equal `itemsByTab.length`. Multi-select tabs
60
+ * use `items.length` for numbering; single-select tabs add 1 for the chat row slot.
61
+ * Floor is `MIN_LEFT` so an all-empty input still produces a usable column.
62
+ */
63
+ export function crossTabMaxLeftWidth(tabs, itemsByTab, paneWidth) {
64
+ let max = MIN_LEFT;
65
+ for (let i = 0; i < tabs.length; i++) {
66
+ const items = itemsByTab[i] ?? [];
67
+ const totalForNumbering = tabs[i]?.multiSelect ? items.length : items.length + 1;
68
+ const tabWidth = adaptiveLeftWidth(items, totalForNumbering, paneWidth);
69
+ if (tabWidth > max)
70
+ max = tabWidth;
71
+ }
72
+ return max;
73
+ }
74
+ /**
75
+ * Source-line probe: measures the widest source line across all options' previews.
76
+ * Returns 0 when no option carries a preview.
77
+ *
78
+ * V1 heuristic — works well for tree/table/heading/list content where source-line
79
+ * width ≈ rendered width. Paragraphs overstate (source width "wants" the full pane);
80
+ * the worst case is "donation does nothing useful" — fallback to the label-driven path.
81
+ * Upgrade path: replace with a render-width probe that invokes Markdown at a probe width.
82
+ *
83
+ * Pure function — O(total chars) per question; no Markdown invocation, no cache interaction.
84
+ */
85
+ export function previewSourceWidth(question) {
86
+ let max = 0;
87
+ for (const option of question.options) {
88
+ const text = option.preview;
89
+ if (!text)
90
+ continue;
91
+ for (const line of text.split("\n")) {
92
+ const w = visibleWidth(line);
93
+ if (w > max)
94
+ max = w;
95
+ }
96
+ }
97
+ return max;
98
+ }
99
+ /**
100
+ * Cross-tab/cross-option preview budget. Iterates all questions, computes each question's
101
+ * preview appetite via `previewSourceWidth`, adds box + padding overhead (5 cols), and
102
+ * returns the widest result. Floor is `MIN_PREVIEW_WIDTH` so a previewless question still
103
+ * reserves a usable column. Ceiling ensures the left column retains its `MIN_LEFT` floor.
104
+ *
105
+ * Pure function — same cross-tab max pattern as `crossTabMaxLeftWidth`.
106
+ */
107
+ export function crossTabPreviewBudget(questions, paneWidth) {
108
+ let max = MIN_PREVIEW_WIDTH;
109
+ for (const question of questions) {
110
+ const rawWidth = previewSourceWidth(question);
111
+ const capped = Math.min(rawWidth, paneWidth - PREVIEW_COLUMN_GAP - MIN_LEFT);
112
+ const budget = capped + BORDER_HORIZONTAL_OVERHEAD + 2 * BORDER_INNER_PADDING_HORIZONTAL + PREVIEW_PADDING_LEFT;
113
+ if (budget > max)
114
+ max = budget;
115
+ }
116
+ return max;
117
+ }
118
+ /**
119
+ * Cross-tab left-column width with slack donation. Combines the label-driven width
120
+ * (from `crossTabMaxLeftWidth`) with the slack donated by narrow previews.
121
+ *
122
+ * Pipeline:
123
+ * 1. `labelDriven` = `crossTabMaxLeftWidth(tabs, itemsByTab, paneWidth)`
124
+ * 2. `previewBudget` = `crossTabPreviewBudget(questions, paneWidth)`
125
+ * 3. `slackDonation` = `paneWidth − GAP − previewBudget`
126
+ * 4. Return `min(max(labelDriven, slackDonation), ceiling)` where `ceiling = paneWidth − GAP − MIN_PREVIEW_WIDTH`
127
+ *
128
+ * Invariants:
129
+ * - Floor: result ≥ MIN_LEFT (labelDriven ≥ MIN_LEFT)
130
+ * - Preview floor: right column ≥ MIN_PREVIEW_WIDTH (ceiling enforces this)
131
+ * - Cross-tab stability: both reductions are tab-independent
132
+ * - Determinism: pure of (questions, itemsByTab, paneWidth)
133
+ *
134
+ * `crossTabMaxLeftWidth` is NOT replaced — it continues to exist as the primitive.
135
+ * `MAX_LEFT_RATIO` caps the label-driven path inside `adaptiveLeftWidth`; donation
136
+ * operates above the cap when preview slack is available.
137
+ */
138
+ export function crossTabLeftWidthWithDonation(tabs, itemsByTab, questions, paneWidth) {
139
+ const labelDriven = crossTabMaxLeftWidth(tabs, itemsByTab, paneWidth);
140
+ // Compact-content guard: labels at MIN_LEFT fit below the floor, so widening
141
+ // the column would only inject dead space between the option list and the
142
+ // preview box. Skip donation and preserve the compact intent.
143
+ if (labelDriven <= MIN_LEFT)
144
+ return labelDriven;
145
+ const previewBudget = crossTabPreviewBudget(questions, paneWidth);
146
+ const slackDonation = paneWidth - PREVIEW_COLUMN_GAP - previewBudget;
147
+ const ceiling = paneWidth - PREVIEW_COLUMN_GAP - MIN_PREVIEW_WIDTH;
148
+ return Math.min(Math.max(labelDriven, slackDonation), Math.max(1, ceiling));
149
+ }
150
+ /**
151
+ * Width allocation for side-by-side mode.
152
+ * `adaptiveLeft` is the pre-computed left column width (from `adaptiveLeftWidth`,
153
+ * cross-tab aggregated). The Math.max(1, ...) calls keep both columns >= 1 col on
154
+ * extreme inputs.
155
+ */
156
+ export function columnWidths(paneWidth, adaptiveLeft) {
157
+ const gap = PREVIEW_COLUMN_GAP;
158
+ const leftWidth = Math.min(adaptiveLeft, Math.max(1, paneWidth - gap - 1));
159
+ const rightWidth = Math.max(1, paneWidth - leftWidth - gap);
160
+ return { leftWidth, rightWidth, gap };
161
+ }
162
+ /**
163
+ * Returns the widths actually passed to `options.render` and `previewLines` inside
164
+ * `render()`. Stacked uses the full pane width for both; side-by-side splits via
165
+ * `columnWidths`, with the preview column offset by `PREVIEW_PADDING_LEFT`.
166
+ */
167
+ export function bodyWidths(paneWidth, mode, adaptiveLeft) {
168
+ if (mode === "stacked")
169
+ return { optionsWidth: paneWidth, previewWidth: paneWidth };
170
+ const { leftWidth, rightWidth } = columnWidths(paneWidth, adaptiveLeft);
171
+ return { optionsWidth: leftWidth, previewWidth: Math.max(1, rightWidth - PREVIEW_PADDING_LEFT) };
172
+ }
173
+ //# sourceMappingURL=preview-layout-decider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-layout-decider.js","sourceRoot":"","sources":["../../../../../../../src/core/tools/ask-user-question/view/components/preview/preview-layout-decider.ts"],"names":[],"mappings":"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","sourcesContent":["import { visibleWidth } from \"@earendil-works/pi-tui\";\nimport type { QuestionData } from \"../../../tool/types.js\";\nimport type { WrappingSelectItem } from \"../wrapping-select.js\";\nimport { BORDER_HORIZONTAL_OVERHEAD, BORDER_INNER_PADDING_HORIZONTAL } from \"./preview-box-renderer.js\";\n\n/** Min terminal/pane width for the side-by-side layout to engage. */\nexport const PREVIEW_MIN_WIDTH = 100;\n/** Visual gap between options column and preview column in side-by-side. */\nexport const PREVIEW_COLUMN_GAP = 2;\n/** 1 col padding inside the preview column (between gap and `│`). */\nexport const PREVIEW_PADDING_LEFT = 1;\n/** Empty rows between options and preview blocks in stacked (narrow) layout. */\nexport const STACKED_GAP_ROWS = 1;\n\n/** Floor for the adaptive left column width — prevents collapse on short labels. */\nexport const MIN_LEFT = 30;\n/** Ceiling ratio: left column never exceeds this fraction of pane width. */\nexport const MAX_LEFT_RATIO = 0.5;\n/** Floor for the preview column width — prevents right-side collapse on narrow terminals. */\nexport const MIN_PREVIEW_WIDTH = 45;\n/** visibleWidth(\" ✔\") = 2 (space + ✔ codepoint). Reserved on the longest-label measurement\n * so a confirmed row never gets truncated when MIN_LEFT clamps the column. */\nexport const CONFIRMED_OVERHEAD = 2;\n\nexport type PreviewLayoutMode = \"side-by-side\" | \"stacked\";\n\n/**\n * Decide layout mode from terminal + pane widths. Pure of inputs.\n *\n * The terminal-width gate is the AND check from the previous `preview-pane.ts` —\n * lifted here so the decision is computed ONCE per render and threaded explicitly\n * through `previewBlockHeight`. Removes the bug class where `previewBlockHeight`\n * re-derived `sideBySide` from a column width (already < pane width post-split),\n * capping height too short.\n */\nexport function decideLayout(terminalWidth: number, paneWidth: number): PreviewLayoutMode {\n\treturn terminalWidth >= PREVIEW_MIN_WIDTH && paneWidth >= PREVIEW_MIN_WIDTH ? \"side-by-side\" : \"stacked\";\n}\n\n/**\n * Compute the adaptive left column width from option labels.\n * Pure function — deterministic for a given (items, totalForNumbering, paneWidth).\n *\n * Pipeline:\n * 1. Measure: longest visible label width + prefix overhead + confirmed-mark overhead\n * 2. Clamp: floor MIN_LEFT, ceiling paneWidth * MAX_LEFT_RATIO\n * 3. Safety net: never exceed available = paneWidth - GAP - MIN_PREVIEW_WIDTH\n */\nexport function adaptiveLeftWidth(\n\titems: readonly WrappingSelectItem[],\n\ttotalForNumbering: number,\n\tpaneWidth: number,\n): number {\n\tconst prefixW = String(Math.max(1, totalForNumbering)).length + 4; // digits + \"❯ \" + \". \"\n\tconst confirmedOverhead = CONFIRMED_OVERHEAD; // visibleWidth(\" ✔\") = 2 (space + ✔ codepoint)\n\tlet maxLabel = 0;\n\tfor (const item of items) {\n\t\tconst w = visibleWidth(item.label);\n\t\tif (w > maxLabel) maxLabel = w;\n\t}\n\tconst desired = maxLabel + prefixW + confirmedOverhead;\n\tconst ratioCapped = Math.min(desired, Math.floor(paneWidth * MAX_LEFT_RATIO));\n\tconst available = paneWidth - PREVIEW_COLUMN_GAP - MIN_PREVIEW_WIDTH;\n\treturn Math.max(MIN_LEFT, Math.min(ratioCapped, Math.max(1, available)));\n}\n\n/**\n * Cross-tab maximum left-column width. Aggregates `adaptiveLeftWidth` over every tab\n * and returns the widest result, so the options column stays stable on tab switch.\n *\n * Pure function — `tabs.length` MUST equal `itemsByTab.length`. Multi-select tabs\n * use `items.length` for numbering; single-select tabs add 1 for the chat row slot.\n * Floor is `MIN_LEFT` so an all-empty input still produces a usable column.\n */\nexport function crossTabMaxLeftWidth(\n\ttabs: ReadonlyArray<{ multiSelect?: boolean }>,\n\titemsByTab: ReadonlyArray<readonly WrappingSelectItem[]>,\n\tpaneWidth: number,\n): number {\n\tlet max = MIN_LEFT;\n\tfor (let i = 0; i < tabs.length; i++) {\n\t\tconst items = itemsByTab[i] ?? [];\n\t\tconst totalForNumbering = tabs[i]?.multiSelect ? items.length : items.length + 1;\n\t\tconst tabWidth = adaptiveLeftWidth(items, totalForNumbering, paneWidth);\n\t\tif (tabWidth > max) max = tabWidth;\n\t}\n\treturn max;\n}\n\n/**\n * Source-line probe: measures the widest source line across all options' previews.\n * Returns 0 when no option carries a preview.\n *\n * V1 heuristic — works well for tree/table/heading/list content where source-line\n * width ≈ rendered width. Paragraphs overstate (source width \"wants\" the full pane);\n * the worst case is \"donation does nothing useful\" — fallback to the label-driven path.\n * Upgrade path: replace with a render-width probe that invokes Markdown at a probe width.\n *\n * Pure function — O(total chars) per question; no Markdown invocation, no cache interaction.\n */\nexport function previewSourceWidth(question: QuestionData): number {\n\tlet max = 0;\n\tfor (const option of question.options) {\n\t\tconst text = option.preview;\n\t\tif (!text) continue;\n\t\tfor (const line of text.split(\"\\n\")) {\n\t\t\tconst w = visibleWidth(line);\n\t\t\tif (w > max) max = w;\n\t\t}\n\t}\n\treturn max;\n}\n\n/**\n * Cross-tab/cross-option preview budget. Iterates all questions, computes each question's\n * preview appetite via `previewSourceWidth`, adds box + padding overhead (5 cols), and\n * returns the widest result. Floor is `MIN_PREVIEW_WIDTH` so a previewless question still\n * reserves a usable column. Ceiling ensures the left column retains its `MIN_LEFT` floor.\n *\n * Pure function — same cross-tab max pattern as `crossTabMaxLeftWidth`.\n */\nexport function crossTabPreviewBudget(questions: readonly QuestionData[], paneWidth: number): number {\n\tlet max = MIN_PREVIEW_WIDTH;\n\tfor (const question of questions) {\n\t\tconst rawWidth = previewSourceWidth(question);\n\t\tconst capped = Math.min(rawWidth, paneWidth - PREVIEW_COLUMN_GAP - MIN_LEFT);\n\t\tconst budget = capped + BORDER_HORIZONTAL_OVERHEAD + 2 * BORDER_INNER_PADDING_HORIZONTAL + PREVIEW_PADDING_LEFT;\n\t\tif (budget > max) max = budget;\n\t}\n\treturn max;\n}\n\n/**\n * Cross-tab left-column width with slack donation. Combines the label-driven width\n * (from `crossTabMaxLeftWidth`) with the slack donated by narrow previews.\n *\n * Pipeline:\n * 1. `labelDriven` = `crossTabMaxLeftWidth(tabs, itemsByTab, paneWidth)`\n * 2. `previewBudget` = `crossTabPreviewBudget(questions, paneWidth)`\n * 3. `slackDonation` = `paneWidth − GAP − previewBudget`\n * 4. Return `min(max(labelDriven, slackDonation), ceiling)` where `ceiling = paneWidth − GAP − MIN_PREVIEW_WIDTH`\n *\n * Invariants:\n * - Floor: result ≥ MIN_LEFT (labelDriven ≥ MIN_LEFT)\n * - Preview floor: right column ≥ MIN_PREVIEW_WIDTH (ceiling enforces this)\n * - Cross-tab stability: both reductions are tab-independent\n * - Determinism: pure of (questions, itemsByTab, paneWidth)\n *\n * `crossTabMaxLeftWidth` is NOT replaced — it continues to exist as the primitive.\n * `MAX_LEFT_RATIO` caps the label-driven path inside `adaptiveLeftWidth`; donation\n * operates above the cap when preview slack is available.\n */\nexport function crossTabLeftWidthWithDonation(\n\ttabs: ReadonlyArray<{ multiSelect?: boolean }>,\n\titemsByTab: ReadonlyArray<readonly WrappingSelectItem[]>,\n\tquestions: readonly QuestionData[],\n\tpaneWidth: number,\n): number {\n\tconst labelDriven = crossTabMaxLeftWidth(tabs, itemsByTab, paneWidth);\n\t// Compact-content guard: labels at MIN_LEFT fit below the floor, so widening\n\t// the column would only inject dead space between the option list and the\n\t// preview box. Skip donation and preserve the compact intent.\n\tif (labelDriven <= MIN_LEFT) return labelDriven;\n\tconst previewBudget = crossTabPreviewBudget(questions, paneWidth);\n\tconst slackDonation = paneWidth - PREVIEW_COLUMN_GAP - previewBudget;\n\tconst ceiling = paneWidth - PREVIEW_COLUMN_GAP - MIN_PREVIEW_WIDTH;\n\treturn Math.min(Math.max(labelDriven, slackDonation), Math.max(1, ceiling));\n}\n\n/**\n * Width allocation for side-by-side mode.\n * `adaptiveLeft` is the pre-computed left column width (from `adaptiveLeftWidth`,\n * cross-tab aggregated). The Math.max(1, ...) calls keep both columns >= 1 col on\n * extreme inputs.\n */\nexport function columnWidths(\n\tpaneWidth: number,\n\tadaptiveLeft: number,\n): { leftWidth: number; rightWidth: number; gap: number } {\n\tconst gap = PREVIEW_COLUMN_GAP;\n\tconst leftWidth = Math.min(adaptiveLeft, Math.max(1, paneWidth - gap - 1));\n\tconst rightWidth = Math.max(1, paneWidth - leftWidth - gap);\n\treturn { leftWidth, rightWidth, gap };\n}\n\n/**\n * Returns the widths actually passed to `options.render` and `previewLines` inside\n * `render()`. Stacked uses the full pane width for both; side-by-side splits via\n * `columnWidths`, with the preview column offset by `PREVIEW_PADDING_LEFT`.\n */\nexport function bodyWidths(\n\tpaneWidth: number,\n\tmode: PreviewLayoutMode,\n\tadaptiveLeft: number,\n): { optionsWidth: number; previewWidth: number } {\n\tif (mode === \"stacked\") return { optionsWidth: paneWidth, previewWidth: paneWidth };\n\tconst { leftWidth, rightWidth } = columnWidths(paneWidth, adaptiveLeft);\n\treturn { optionsWidth: leftWidth, previewWidth: Math.max(1, rightWidth - PREVIEW_PADDING_LEFT) };\n}\n"]}
@@ -0,0 +1,66 @@
1
+ import { type Component } from "@earendil-works/pi-tui";
2
+ import type { QuestionData } from "../../../tool/types.js";
3
+ import type { StatefulView } from "../../stateful-view.js";
4
+ import type { OptionListView } from "../option-list-view.js";
5
+ import type { PreviewBlockRenderer } from "./preview-block-renderer.js";
6
+ export { MAX_PREVIEW_HEIGHT_SIDE_BY_SIDE, MAX_PREVIEW_HEIGHT_STACKED, NO_PREVIEW_TEXT, NOTES_AFFORDANCE_OVERHEAD, } from "./markdown-content-cache.js";
7
+ export { NOTES_AFFORDANCE_TEXT, PreviewBlockRenderer } from "./preview-block-renderer.js";
8
+ export { BORDER_HORIZONTAL_OVERHEAD, BORDER_INNER_PADDING_HORIZONTAL, BORDER_VERTICAL_OVERHEAD, BOX_MIN_CONTENT_WIDTH, renderBorderedBox, stripFenceMarkers, } from "./preview-box-renderer.js";
9
+ export { PREVIEW_COLUMN_GAP, PREVIEW_MIN_WIDTH, PREVIEW_PADDING_LEFT, STACKED_GAP_ROWS, } from "./preview-layout-decider.js";
10
+ /**
11
+ * Per-tick projection of PreviewPane state. Replaces the prior
12
+ * `setNotesVisible(boolean)` sliver-setter and the sibling reads of
13
+ * `optionListView.getSelectedIndex()` / `isFocused()`. The pane now reads
14
+ * `selectedIndex` and `focused` from its own props — both derived from
15
+ * canonical state via `selectPreviewPaneProps`. `OptionListView` and
16
+ * `PreviewPane` see the same source of truth without the cross-component
17
+ * live read.
18
+ */
19
+ export interface PreviewPaneProps {
20
+ notesVisible: boolean;
21
+ selectedIndex: number;
22
+ focused: boolean;
23
+ }
24
+ export interface PreviewPaneConfig {
25
+ question: QuestionData;
26
+ getTerminalWidth: () => number;
27
+ optionListView: OptionListView;
28
+ previewBlock: PreviewBlockRenderer;
29
+ }
30
+ /**
31
+ * Thin layout composer. Receives `selectedIndex` / `focused` / `notesVisible`
32
+ * via `setProps` per tick (computed by `selectPreviewPaneProps` from canonical
33
+ * state). Delegates option-side rendering to `OptionListView` (which still
34
+ * owns its render-time state — input buffer, confirmedIndex) and preview-side
35
+ * rendering to `PreviewBlockRenderer` (which owns the markdown cache and
36
+ * bordered-box composition).
37
+ *
38
+ * `naturalHeight` and `maxNaturalHeight` query both children's heights; `render`
39
+ * combines them via `decideLayout` (mode threaded into both calls — never
40
+ * re-derived).
41
+ */
42
+ export declare class PreviewPane implements StatefulView<PreviewPaneProps>, Component {
43
+ private readonly question;
44
+ private readonly getTerminalWidth;
45
+ private readonly optionListView;
46
+ private readonly previewBlock;
47
+ private props;
48
+ /**
49
+ * Cross-tab max left-width getter. Set exactly once by `buildQuestionnaire.injectGlobalLeftWidth`
50
+ * before any render. Initialized to a throwing sentinel so missing injection is a hard fail
51
+ * rather than a silent fallback to a magic constant — render is illegal until injected.
52
+ */
53
+ private globalLeftWidth;
54
+ constructor(config: PreviewPaneConfig);
55
+ setGlobalLeftWidth(getter: (paneWidth: number) => number): void;
56
+ private getAdaptiveLeft;
57
+ setProps(props: PreviewPaneProps): void;
58
+ handleInput(_data: string): void;
59
+ invalidate(): void;
60
+ render(width: number): string[];
61
+ naturalHeight(width: number): number;
62
+ maxNaturalHeight(width: number): number;
63
+ private renderSideBySide;
64
+ private renderPaddedPreviewLines;
65
+ }
66
+ //# sourceMappingURL=preview-pane.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-pane.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/tools/ask-user-question/view/components/preview/preview-pane.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAiC,MAAM,wBAAwB,CAAC;AACvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAWxE,OAAO,EACN,+BAA+B,EAC/B,0BAA0B,EAC1B,eAAe,EACf,yBAAyB,GACzB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAC1F,OAAO,EACN,0BAA0B,EAC1B,+BAA+B,EAC/B,wBAAwB,EACxB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,GACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACN,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,GAChB,MAAM,6BAA6B,CAAC;AAErC;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAChC,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IACjC,QAAQ,EAAE,YAAY,CAAC;IACvB,gBAAgB,EAAE,MAAM,MAAM,CAAC;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,EAAE,oBAAoB,CAAC;CACnC;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,WAAY,YAAW,YAAY,CAAC,gBAAgB,CAAC,EAAE,SAAS;IAC5E,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAe;IAChD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuB;IACpD,OAAO,CAAC,KAAK,CAAmB;IAChC;;;;OAIG;IACH,OAAO,CAAC,eAAe,CAErB;IAEF,YAAY,MAAM,EAAE,iBAAiB,EAMpC;IAED,kBAAkB,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAE9D;IAED,OAAO,CAAC,eAAe;IAIvB,QAAQ,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAEtC;IAED,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAG;IAEnC,UAAU,IAAI,IAAI,CAGjB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAoB9B;IAED,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUnC;IAED,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CActC;IAED,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,wBAAwB;CAYhC","sourcesContent":["import { type Component, truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport type { QuestionData } from \"../../../tool/types.js\";\nimport type { StatefulView } from \"../../stateful-view.js\";\nimport type { OptionListView } from \"../option-list-view.js\";\nimport type { PreviewBlockRenderer } from \"./preview-block-renderer.js\";\nimport {\n\tbodyWidths,\n\tcolumnWidths,\n\tdecideLayout,\n\tPREVIEW_PADDING_LEFT,\n\ttype PreviewLayoutMode,\n\tSTACKED_GAP_ROWS,\n} from \"./preview-layout-decider.js\";\n\n// ----- Re-exports for test imports — keep `./preview-pane.js` as the public surface -----\nexport {\n\tMAX_PREVIEW_HEIGHT_SIDE_BY_SIDE,\n\tMAX_PREVIEW_HEIGHT_STACKED,\n\tNO_PREVIEW_TEXT,\n\tNOTES_AFFORDANCE_OVERHEAD,\n} from \"./markdown-content-cache.js\";\nexport { NOTES_AFFORDANCE_TEXT, PreviewBlockRenderer } from \"./preview-block-renderer.js\";\nexport {\n\tBORDER_HORIZONTAL_OVERHEAD,\n\tBORDER_INNER_PADDING_HORIZONTAL,\n\tBORDER_VERTICAL_OVERHEAD,\n\tBOX_MIN_CONTENT_WIDTH,\n\trenderBorderedBox,\n\tstripFenceMarkers,\n} from \"./preview-box-renderer.js\";\nexport {\n\tPREVIEW_COLUMN_GAP,\n\tPREVIEW_MIN_WIDTH,\n\tPREVIEW_PADDING_LEFT,\n\tSTACKED_GAP_ROWS,\n} from \"./preview-layout-decider.js\";\n\n/**\n * Per-tick projection of PreviewPane state. Replaces the prior\n * `setNotesVisible(boolean)` sliver-setter and the sibling reads of\n * `optionListView.getSelectedIndex()` / `isFocused()`. The pane now reads\n * `selectedIndex` and `focused` from its own props — both derived from\n * canonical state via `selectPreviewPaneProps`. `OptionListView` and\n * `PreviewPane` see the same source of truth without the cross-component\n * live read.\n */\nexport interface PreviewPaneProps {\n\tnotesVisible: boolean;\n\tselectedIndex: number;\n\tfocused: boolean;\n}\n\nexport interface PreviewPaneConfig {\n\tquestion: QuestionData;\n\tgetTerminalWidth: () => number;\n\toptionListView: OptionListView;\n\tpreviewBlock: PreviewBlockRenderer;\n}\n\n/**\n * Thin layout composer. Receives `selectedIndex` / `focused` / `notesVisible`\n * via `setProps` per tick (computed by `selectPreviewPaneProps` from canonical\n * state). Delegates option-side rendering to `OptionListView` (which still\n * owns its render-time state — input buffer, confirmedIndex) and preview-side\n * rendering to `PreviewBlockRenderer` (which owns the markdown cache and\n * bordered-box composition).\n *\n * `naturalHeight` and `maxNaturalHeight` query both children's heights; `render`\n * combines them via `decideLayout` (mode threaded into both calls — never\n * re-derived).\n */\nexport class PreviewPane implements StatefulView<PreviewPaneProps>, Component {\n\tprivate readonly question: QuestionData;\n\tprivate readonly getTerminalWidth: () => number;\n\tprivate readonly optionListView: OptionListView;\n\tprivate readonly previewBlock: PreviewBlockRenderer;\n\tprivate props: PreviewPaneProps;\n\t/**\n\t * Cross-tab max left-width getter. Set exactly once by `buildQuestionnaire.injectGlobalLeftWidth`\n\t * before any render. Initialized to a throwing sentinel so missing injection is a hard fail\n\t * rather than a silent fallback to a magic constant — render is illegal until injected.\n\t */\n\tprivate globalLeftWidth: (paneWidth: number) => number = () => {\n\t\tthrow new Error(\"PreviewPane.setGlobalLeftWidth must be called before render()\");\n\t};\n\n\tconstructor(config: PreviewPaneConfig) {\n\t\tthis.question = config.question;\n\t\tthis.getTerminalWidth = config.getTerminalWidth;\n\t\tthis.optionListView = config.optionListView;\n\t\tthis.previewBlock = config.previewBlock;\n\t\tthis.props = { notesVisible: false, selectedIndex: 0, focused: false };\n\t}\n\n\tsetGlobalLeftWidth(getter: (paneWidth: number) => number): void {\n\t\tthis.globalLeftWidth = getter;\n\t}\n\n\tprivate getAdaptiveLeft(paneWidth: number): number {\n\t\treturn this.globalLeftWidth(paneWidth);\n\t}\n\n\tsetProps(props: PreviewPaneProps): void {\n\t\tthis.props = props;\n\t}\n\n\thandleInput(_data: string): void {}\n\n\tinvalidate(): void {\n\t\tthis.previewBlock.invalidate();\n\t\tthis.optionListView.invalidate();\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.question.multiSelect === true) return this.optionListView.render(width);\n\t\t// Spec: hide the preview pane entirely when no option carries a `preview`.\n\t\tif (!this.previewBlock.hasAnyPreview()) return this.optionListView.render(width);\n\n\t\tconst mode = decideLayout(this.getTerminalWidth(), width);\n\t\tif (mode === \"side-by-side\") return this.renderSideBySide(width, mode);\n\n\t\t// Stacked: options + blank gap + preview block.\n\t\treturn [\n\t\t\t...this.optionListView.render(width),\n\t\t\t...Array(STACKED_GAP_ROWS).fill(\"\"),\n\t\t\t...this.previewBlock.renderBlock(\n\t\t\t\twidth,\n\t\t\t\tthis.props.selectedIndex,\n\t\t\t\tmode,\n\t\t\t\tthis.props.focused,\n\t\t\t\tthis.props.notesVisible,\n\t\t\t),\n\t\t];\n\t}\n\n\tnaturalHeight(width: number): number {\n\t\tif (this.question.multiSelect === true) return this.optionListView.render(width).length;\n\t\tif (!this.previewBlock.hasAnyPreview()) return this.optionListView.render(width).length;\n\t\tconst mode = decideLayout(this.getTerminalWidth(), width);\n\t\tconst adaptiveLeft = this.getAdaptiveLeft(width);\n\t\tconst { optionsWidth, previewWidth } = bodyWidths(width, mode, adaptiveLeft);\n\t\tconst optionsHeight = this.optionListView.render(optionsWidth).length;\n\t\tconst previewBlockHeight = this.previewBlock.blockHeight(previewWidth, this.props.selectedIndex, mode);\n\t\tif (mode === \"side-by-side\") return Math.max(optionsHeight, previewBlockHeight);\n\t\treturn optionsHeight + STACKED_GAP_ROWS + previewBlockHeight;\n\t}\n\n\tmaxNaturalHeight(width: number): number {\n\t\tif (this.question.multiSelect === true) return this.optionListView.render(width).length;\n\t\tif (!this.previewBlock.hasAnyPreview()) return this.optionListView.render(width).length;\n\t\tconst mode = decideLayout(this.getTerminalWidth(), width);\n\t\tconst adaptiveLeft = this.getAdaptiveLeft(width);\n\t\tconst { optionsWidth, previewWidth } = bodyWidths(width, mode, adaptiveLeft);\n\t\tconst optionsHeight = this.optionListView.render(optionsWidth).length;\n\t\tlet maxPreviewBlock = 0;\n\t\tfor (let i = 0; i < this.question.options.length; i++) {\n\t\t\tconst h = this.previewBlock.blockHeight(previewWidth, i, mode);\n\t\t\tif (h > maxPreviewBlock) maxPreviewBlock = h;\n\t\t}\n\t\tif (mode === \"side-by-side\") return Math.max(optionsHeight, maxPreviewBlock);\n\t\treturn optionsHeight + STACKED_GAP_ROWS + maxPreviewBlock;\n\t}\n\n\tprivate renderSideBySide(width: number, mode: PreviewLayoutMode): string[] {\n\t\tconst adaptiveLeft = this.getAdaptiveLeft(width);\n\t\tconst { leftWidth, rightWidth, gap } = columnWidths(width, adaptiveLeft);\n\t\tconst leftLines = this.optionListView.render(leftWidth);\n\t\tconst rightLines = this.renderPaddedPreviewLines(rightWidth, mode);\n\t\tconst rows = Math.max(leftLines.length, rightLines.length);\n\t\tconst gapStr = \" \".repeat(gap);\n\t\tconst out: string[] = [];\n\t\tfor (let i = 0; i < rows; i++) {\n\t\t\tconst leftRaw = leftLines[i] ?? \"\";\n\t\t\tconst rightRaw = rightLines[i] ?? \"\";\n\t\t\tconst leftClamped = truncateToWidth(leftRaw, leftWidth, \"\");\n\t\t\tconst leftPad = \" \".repeat(Math.max(0, leftWidth - visibleWidth(leftClamped)));\n\t\t\tconst joined = `${leftClamped}${leftPad}${gapStr}${rightRaw}`;\n\t\t\tout.push(truncateToWidth(joined, width, \"\"));\n\t\t}\n\t\treturn out;\n\t}\n\n\tprivate renderPaddedPreviewLines(colWidth: number, mode: PreviewLayoutMode): string[] {\n\t\tconst inner = Math.max(1, colWidth - PREVIEW_PADDING_LEFT);\n\t\tconst contentLines = this.previewBlock.renderBlock(\n\t\t\tinner,\n\t\t\tthis.props.selectedIndex,\n\t\t\tmode,\n\t\t\tthis.props.focused,\n\t\t\tthis.props.notesVisible,\n\t\t);\n\t\tconst pad = \" \".repeat(PREVIEW_PADDING_LEFT);\n\t\treturn contentLines.map((l) => (l === \"\" ? \"\" : `${pad}${l}`));\n\t}\n}\n"]}
@@ -0,0 +1,124 @@
1
+ import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
2
+ import { bodyWidths, columnWidths, decideLayout, PREVIEW_PADDING_LEFT, STACKED_GAP_ROWS, } from "./preview-layout-decider.js";
3
+ // ----- Re-exports for test imports — keep `./preview-pane.js` as the public surface -----
4
+ export { MAX_PREVIEW_HEIGHT_SIDE_BY_SIDE, MAX_PREVIEW_HEIGHT_STACKED, NO_PREVIEW_TEXT, NOTES_AFFORDANCE_OVERHEAD, } from "./markdown-content-cache.js";
5
+ export { NOTES_AFFORDANCE_TEXT, PreviewBlockRenderer } from "./preview-block-renderer.js";
6
+ export { BORDER_HORIZONTAL_OVERHEAD, BORDER_INNER_PADDING_HORIZONTAL, BORDER_VERTICAL_OVERHEAD, BOX_MIN_CONTENT_WIDTH, renderBorderedBox, stripFenceMarkers, } from "./preview-box-renderer.js";
7
+ export { PREVIEW_COLUMN_GAP, PREVIEW_MIN_WIDTH, PREVIEW_PADDING_LEFT, STACKED_GAP_ROWS, } from "./preview-layout-decider.js";
8
+ /**
9
+ * Thin layout composer. Receives `selectedIndex` / `focused` / `notesVisible`
10
+ * via `setProps` per tick (computed by `selectPreviewPaneProps` from canonical
11
+ * state). Delegates option-side rendering to `OptionListView` (which still
12
+ * owns its render-time state — input buffer, confirmedIndex) and preview-side
13
+ * rendering to `PreviewBlockRenderer` (which owns the markdown cache and
14
+ * bordered-box composition).
15
+ *
16
+ * `naturalHeight` and `maxNaturalHeight` query both children's heights; `render`
17
+ * combines them via `decideLayout` (mode threaded into both calls — never
18
+ * re-derived).
19
+ */
20
+ export class PreviewPane {
21
+ constructor(config) {
22
+ /**
23
+ * Cross-tab max left-width getter. Set exactly once by `buildQuestionnaire.injectGlobalLeftWidth`
24
+ * before any render. Initialized to a throwing sentinel so missing injection is a hard fail
25
+ * rather than a silent fallback to a magic constant — render is illegal until injected.
26
+ */
27
+ this.globalLeftWidth = () => {
28
+ throw new Error("PreviewPane.setGlobalLeftWidth must be called before render()");
29
+ };
30
+ this.question = config.question;
31
+ this.getTerminalWidth = config.getTerminalWidth;
32
+ this.optionListView = config.optionListView;
33
+ this.previewBlock = config.previewBlock;
34
+ this.props = { notesVisible: false, selectedIndex: 0, focused: false };
35
+ }
36
+ setGlobalLeftWidth(getter) {
37
+ this.globalLeftWidth = getter;
38
+ }
39
+ getAdaptiveLeft(paneWidth) {
40
+ return this.globalLeftWidth(paneWidth);
41
+ }
42
+ setProps(props) {
43
+ this.props = props;
44
+ }
45
+ handleInput(_data) { }
46
+ invalidate() {
47
+ this.previewBlock.invalidate();
48
+ this.optionListView.invalidate();
49
+ }
50
+ render(width) {
51
+ if (this.question.multiSelect === true)
52
+ return this.optionListView.render(width);
53
+ // Spec: hide the preview pane entirely when no option carries a `preview`.
54
+ if (!this.previewBlock.hasAnyPreview())
55
+ return this.optionListView.render(width);
56
+ const mode = decideLayout(this.getTerminalWidth(), width);
57
+ if (mode === "side-by-side")
58
+ return this.renderSideBySide(width, mode);
59
+ // Stacked: options + blank gap + preview block.
60
+ return [
61
+ ...this.optionListView.render(width),
62
+ ...Array(STACKED_GAP_ROWS).fill(""),
63
+ ...this.previewBlock.renderBlock(width, this.props.selectedIndex, mode, this.props.focused, this.props.notesVisible),
64
+ ];
65
+ }
66
+ naturalHeight(width) {
67
+ if (this.question.multiSelect === true)
68
+ return this.optionListView.render(width).length;
69
+ if (!this.previewBlock.hasAnyPreview())
70
+ return this.optionListView.render(width).length;
71
+ const mode = decideLayout(this.getTerminalWidth(), width);
72
+ const adaptiveLeft = this.getAdaptiveLeft(width);
73
+ const { optionsWidth, previewWidth } = bodyWidths(width, mode, adaptiveLeft);
74
+ const optionsHeight = this.optionListView.render(optionsWidth).length;
75
+ const previewBlockHeight = this.previewBlock.blockHeight(previewWidth, this.props.selectedIndex, mode);
76
+ if (mode === "side-by-side")
77
+ return Math.max(optionsHeight, previewBlockHeight);
78
+ return optionsHeight + STACKED_GAP_ROWS + previewBlockHeight;
79
+ }
80
+ maxNaturalHeight(width) {
81
+ if (this.question.multiSelect === true)
82
+ return this.optionListView.render(width).length;
83
+ if (!this.previewBlock.hasAnyPreview())
84
+ return this.optionListView.render(width).length;
85
+ const mode = decideLayout(this.getTerminalWidth(), width);
86
+ const adaptiveLeft = this.getAdaptiveLeft(width);
87
+ const { optionsWidth, previewWidth } = bodyWidths(width, mode, adaptiveLeft);
88
+ const optionsHeight = this.optionListView.render(optionsWidth).length;
89
+ let maxPreviewBlock = 0;
90
+ for (let i = 0; i < this.question.options.length; i++) {
91
+ const h = this.previewBlock.blockHeight(previewWidth, i, mode);
92
+ if (h > maxPreviewBlock)
93
+ maxPreviewBlock = h;
94
+ }
95
+ if (mode === "side-by-side")
96
+ return Math.max(optionsHeight, maxPreviewBlock);
97
+ return optionsHeight + STACKED_GAP_ROWS + maxPreviewBlock;
98
+ }
99
+ renderSideBySide(width, mode) {
100
+ const adaptiveLeft = this.getAdaptiveLeft(width);
101
+ const { leftWidth, rightWidth, gap } = columnWidths(width, adaptiveLeft);
102
+ const leftLines = this.optionListView.render(leftWidth);
103
+ const rightLines = this.renderPaddedPreviewLines(rightWidth, mode);
104
+ const rows = Math.max(leftLines.length, rightLines.length);
105
+ const gapStr = " ".repeat(gap);
106
+ const out = [];
107
+ for (let i = 0; i < rows; i++) {
108
+ const leftRaw = leftLines[i] ?? "";
109
+ const rightRaw = rightLines[i] ?? "";
110
+ const leftClamped = truncateToWidth(leftRaw, leftWidth, "");
111
+ const leftPad = " ".repeat(Math.max(0, leftWidth - visibleWidth(leftClamped)));
112
+ const joined = `${leftClamped}${leftPad}${gapStr}${rightRaw}`;
113
+ out.push(truncateToWidth(joined, width, ""));
114
+ }
115
+ return out;
116
+ }
117
+ renderPaddedPreviewLines(colWidth, mode) {
118
+ const inner = Math.max(1, colWidth - PREVIEW_PADDING_LEFT);
119
+ const contentLines = this.previewBlock.renderBlock(inner, this.props.selectedIndex, mode, this.props.focused, this.props.notesVisible);
120
+ const pad = " ".repeat(PREVIEW_PADDING_LEFT);
121
+ return contentLines.map((l) => (l === "" ? "" : `${pad}${l}`));
122
+ }
123
+ }
124
+ //# sourceMappingURL=preview-pane.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-pane.js","sourceRoot":"","sources":["../../../../../../../src/core/tools/ask-user-question/view/components/preview/preview-pane.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Component, truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport type { QuestionData } from \"../../../tool/types.js\";\nimport type { StatefulView } from \"../../stateful-view.js\";\nimport type { OptionListView } from \"../option-list-view.js\";\nimport type { PreviewBlockRenderer } from \"./preview-block-renderer.js\";\nimport {\n\tbodyWidths,\n\tcolumnWidths,\n\tdecideLayout,\n\tPREVIEW_PADDING_LEFT,\n\ttype PreviewLayoutMode,\n\tSTACKED_GAP_ROWS,\n} from \"./preview-layout-decider.js\";\n\n// ----- Re-exports for test imports — keep `./preview-pane.js` as the public surface -----\nexport {\n\tMAX_PREVIEW_HEIGHT_SIDE_BY_SIDE,\n\tMAX_PREVIEW_HEIGHT_STACKED,\n\tNO_PREVIEW_TEXT,\n\tNOTES_AFFORDANCE_OVERHEAD,\n} from \"./markdown-content-cache.js\";\nexport { NOTES_AFFORDANCE_TEXT, PreviewBlockRenderer } from \"./preview-block-renderer.js\";\nexport {\n\tBORDER_HORIZONTAL_OVERHEAD,\n\tBORDER_INNER_PADDING_HORIZONTAL,\n\tBORDER_VERTICAL_OVERHEAD,\n\tBOX_MIN_CONTENT_WIDTH,\n\trenderBorderedBox,\n\tstripFenceMarkers,\n} from \"./preview-box-renderer.js\";\nexport {\n\tPREVIEW_COLUMN_GAP,\n\tPREVIEW_MIN_WIDTH,\n\tPREVIEW_PADDING_LEFT,\n\tSTACKED_GAP_ROWS,\n} from \"./preview-layout-decider.js\";\n\n/**\n * Per-tick projection of PreviewPane state. Replaces the prior\n * `setNotesVisible(boolean)` sliver-setter and the sibling reads of\n * `optionListView.getSelectedIndex()` / `isFocused()`. The pane now reads\n * `selectedIndex` and `focused` from its own props — both derived from\n * canonical state via `selectPreviewPaneProps`. `OptionListView` and\n * `PreviewPane` see the same source of truth without the cross-component\n * live read.\n */\nexport interface PreviewPaneProps {\n\tnotesVisible: boolean;\n\tselectedIndex: number;\n\tfocused: boolean;\n}\n\nexport interface PreviewPaneConfig {\n\tquestion: QuestionData;\n\tgetTerminalWidth: () => number;\n\toptionListView: OptionListView;\n\tpreviewBlock: PreviewBlockRenderer;\n}\n\n/**\n * Thin layout composer. Receives `selectedIndex` / `focused` / `notesVisible`\n * via `setProps` per tick (computed by `selectPreviewPaneProps` from canonical\n * state). Delegates option-side rendering to `OptionListView` (which still\n * owns its render-time state — input buffer, confirmedIndex) and preview-side\n * rendering to `PreviewBlockRenderer` (which owns the markdown cache and\n * bordered-box composition).\n *\n * `naturalHeight` and `maxNaturalHeight` query both children's heights; `render`\n * combines them via `decideLayout` (mode threaded into both calls — never\n * re-derived).\n */\nexport class PreviewPane implements StatefulView<PreviewPaneProps>, Component {\n\tprivate readonly question: QuestionData;\n\tprivate readonly getTerminalWidth: () => number;\n\tprivate readonly optionListView: OptionListView;\n\tprivate readonly previewBlock: PreviewBlockRenderer;\n\tprivate props: PreviewPaneProps;\n\t/**\n\t * Cross-tab max left-width getter. Set exactly once by `buildQuestionnaire.injectGlobalLeftWidth`\n\t * before any render. Initialized to a throwing sentinel so missing injection is a hard fail\n\t * rather than a silent fallback to a magic constant — render is illegal until injected.\n\t */\n\tprivate globalLeftWidth: (paneWidth: number) => number = () => {\n\t\tthrow new Error(\"PreviewPane.setGlobalLeftWidth must be called before render()\");\n\t};\n\n\tconstructor(config: PreviewPaneConfig) {\n\t\tthis.question = config.question;\n\t\tthis.getTerminalWidth = config.getTerminalWidth;\n\t\tthis.optionListView = config.optionListView;\n\t\tthis.previewBlock = config.previewBlock;\n\t\tthis.props = { notesVisible: false, selectedIndex: 0, focused: false };\n\t}\n\n\tsetGlobalLeftWidth(getter: (paneWidth: number) => number): void {\n\t\tthis.globalLeftWidth = getter;\n\t}\n\n\tprivate getAdaptiveLeft(paneWidth: number): number {\n\t\treturn this.globalLeftWidth(paneWidth);\n\t}\n\n\tsetProps(props: PreviewPaneProps): void {\n\t\tthis.props = props;\n\t}\n\n\thandleInput(_data: string): void {}\n\n\tinvalidate(): void {\n\t\tthis.previewBlock.invalidate();\n\t\tthis.optionListView.invalidate();\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.question.multiSelect === true) return this.optionListView.render(width);\n\t\t// Spec: hide the preview pane entirely when no option carries a `preview`.\n\t\tif (!this.previewBlock.hasAnyPreview()) return this.optionListView.render(width);\n\n\t\tconst mode = decideLayout(this.getTerminalWidth(), width);\n\t\tif (mode === \"side-by-side\") return this.renderSideBySide(width, mode);\n\n\t\t// Stacked: options + blank gap + preview block.\n\t\treturn [\n\t\t\t...this.optionListView.render(width),\n\t\t\t...Array(STACKED_GAP_ROWS).fill(\"\"),\n\t\t\t...this.previewBlock.renderBlock(\n\t\t\t\twidth,\n\t\t\t\tthis.props.selectedIndex,\n\t\t\t\tmode,\n\t\t\t\tthis.props.focused,\n\t\t\t\tthis.props.notesVisible,\n\t\t\t),\n\t\t];\n\t}\n\n\tnaturalHeight(width: number): number {\n\t\tif (this.question.multiSelect === true) return this.optionListView.render(width).length;\n\t\tif (!this.previewBlock.hasAnyPreview()) return this.optionListView.render(width).length;\n\t\tconst mode = decideLayout(this.getTerminalWidth(), width);\n\t\tconst adaptiveLeft = this.getAdaptiveLeft(width);\n\t\tconst { optionsWidth, previewWidth } = bodyWidths(width, mode, adaptiveLeft);\n\t\tconst optionsHeight = this.optionListView.render(optionsWidth).length;\n\t\tconst previewBlockHeight = this.previewBlock.blockHeight(previewWidth, this.props.selectedIndex, mode);\n\t\tif (mode === \"side-by-side\") return Math.max(optionsHeight, previewBlockHeight);\n\t\treturn optionsHeight + STACKED_GAP_ROWS + previewBlockHeight;\n\t}\n\n\tmaxNaturalHeight(width: number): number {\n\t\tif (this.question.multiSelect === true) return this.optionListView.render(width).length;\n\t\tif (!this.previewBlock.hasAnyPreview()) return this.optionListView.render(width).length;\n\t\tconst mode = decideLayout(this.getTerminalWidth(), width);\n\t\tconst adaptiveLeft = this.getAdaptiveLeft(width);\n\t\tconst { optionsWidth, previewWidth } = bodyWidths(width, mode, adaptiveLeft);\n\t\tconst optionsHeight = this.optionListView.render(optionsWidth).length;\n\t\tlet maxPreviewBlock = 0;\n\t\tfor (let i = 0; i < this.question.options.length; i++) {\n\t\t\tconst h = this.previewBlock.blockHeight(previewWidth, i, mode);\n\t\t\tif (h > maxPreviewBlock) maxPreviewBlock = h;\n\t\t}\n\t\tif (mode === \"side-by-side\") return Math.max(optionsHeight, maxPreviewBlock);\n\t\treturn optionsHeight + STACKED_GAP_ROWS + maxPreviewBlock;\n\t}\n\n\tprivate renderSideBySide(width: number, mode: PreviewLayoutMode): string[] {\n\t\tconst adaptiveLeft = this.getAdaptiveLeft(width);\n\t\tconst { leftWidth, rightWidth, gap } = columnWidths(width, adaptiveLeft);\n\t\tconst leftLines = this.optionListView.render(leftWidth);\n\t\tconst rightLines = this.renderPaddedPreviewLines(rightWidth, mode);\n\t\tconst rows = Math.max(leftLines.length, rightLines.length);\n\t\tconst gapStr = \" \".repeat(gap);\n\t\tconst out: string[] = [];\n\t\tfor (let i = 0; i < rows; i++) {\n\t\t\tconst leftRaw = leftLines[i] ?? \"\";\n\t\t\tconst rightRaw = rightLines[i] ?? \"\";\n\t\t\tconst leftClamped = truncateToWidth(leftRaw, leftWidth, \"\");\n\t\t\tconst leftPad = \" \".repeat(Math.max(0, leftWidth - visibleWidth(leftClamped)));\n\t\t\tconst joined = `${leftClamped}${leftPad}${gapStr}${rightRaw}`;\n\t\t\tout.push(truncateToWidth(joined, width, \"\"));\n\t\t}\n\t\treturn out;\n\t}\n\n\tprivate renderPaddedPreviewLines(colWidth: number, mode: PreviewLayoutMode): string[] {\n\t\tconst inner = Math.max(1, colWidth - PREVIEW_PADDING_LEFT);\n\t\tconst contentLines = this.previewBlock.renderBlock(\n\t\t\tinner,\n\t\t\tthis.props.selectedIndex,\n\t\t\tmode,\n\t\t\tthis.props.focused,\n\t\t\tthis.props.notesVisible,\n\t\t);\n\t\tconst pad = \" \".repeat(PREVIEW_PADDING_LEFT);\n\t\treturn contentLines.map((l) => (l === \"\" ? \"\" : `${pad}${l}`));\n\t}\n}\n"]}