terminal-pilot 0.0.30 → 0.0.32

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 (329) hide show
  1. package/dist/cli.js +1599 -497
  2. package/dist/cli.js.map +4 -4
  3. package/dist/commands/close-session.js +489 -6
  4. package/dist/commands/close-session.js.map +4 -4
  5. package/dist/commands/create-session.js +489 -6
  6. package/dist/commands/create-session.js.map +4 -4
  7. package/dist/commands/fill.js +489 -6
  8. package/dist/commands/fill.js.map +4 -4
  9. package/dist/commands/get-session.js +489 -6
  10. package/dist/commands/get-session.js.map +4 -4
  11. package/dist/commands/index.js +630 -44
  12. package/dist/commands/index.js.map +4 -4
  13. package/dist/commands/install.js +626 -40
  14. package/dist/commands/install.js.map +4 -4
  15. package/dist/commands/installer.js +68 -17
  16. package/dist/commands/installer.js.map +4 -4
  17. package/dist/commands/list-sessions.js +489 -6
  18. package/dist/commands/list-sessions.js.map +4 -4
  19. package/dist/commands/press-key.js +489 -6
  20. package/dist/commands/press-key.js.map +4 -4
  21. package/dist/commands/read-history.js +489 -6
  22. package/dist/commands/read-history.js.map +4 -4
  23. package/dist/commands/read-screen.js +489 -6
  24. package/dist/commands/read-screen.js.map +4 -4
  25. package/dist/commands/resize.js +489 -6
  26. package/dist/commands/resize.js.map +4 -4
  27. package/dist/commands/runtime.js.map +1 -1
  28. package/dist/commands/screenshot.js +489 -6
  29. package/dist/commands/screenshot.js.map +4 -4
  30. package/dist/commands/send-signal.js +489 -6
  31. package/dist/commands/send-signal.js.map +4 -4
  32. package/dist/commands/type.js +489 -6
  33. package/dist/commands/type.js.map +4 -4
  34. package/dist/commands/uninstall.js +554 -20
  35. package/dist/commands/uninstall.js.map +4 -4
  36. package/dist/commands/wait-for-exit.js +489 -6
  37. package/dist/commands/wait-for-exit.js.map +4 -4
  38. package/dist/commands/wait-for.js +489 -6
  39. package/dist/commands/wait-for.js.map +4 -4
  40. package/dist/testing/cli-repl.js +1599 -497
  41. package/dist/testing/cli-repl.js.map +4 -4
  42. package/dist/testing/qa-cli.js +1609 -507
  43. package/dist/testing/qa-cli.js.map +4 -4
  44. package/node_modules/@poe-code/agent-defs/README.md +35 -0
  45. package/node_modules/@poe-code/agent-defs/dist/agents/claude-code.d.ts +2 -0
  46. package/node_modules/@poe-code/agent-defs/dist/agents/claude-code.js +21 -0
  47. package/node_modules/@poe-code/agent-defs/dist/agents/claude-desktop.d.ts +2 -0
  48. package/node_modules/@poe-code/agent-defs/dist/agents/claude-desktop.js +18 -0
  49. package/node_modules/@poe-code/agent-defs/dist/agents/codex.d.ts +2 -0
  50. package/node_modules/@poe-code/agent-defs/dist/agents/codex.js +25 -0
  51. package/node_modules/@poe-code/agent-defs/dist/agents/cursor.d.ts +2 -0
  52. package/node_modules/@poe-code/agent-defs/dist/agents/cursor.js +15 -0
  53. package/node_modules/@poe-code/agent-defs/dist/agents/gemini-cli.d.ts +2 -0
  54. package/node_modules/@poe-code/agent-defs/dist/agents/gemini-cli.js +16 -0
  55. package/node_modules/@poe-code/agent-defs/dist/agents/goose.d.ts +2 -0
  56. package/node_modules/@poe-code/agent-defs/dist/agents/goose.js +16 -0
  57. package/node_modules/@poe-code/agent-defs/dist/agents/index.d.ts +9 -0
  58. package/node_modules/@poe-code/agent-defs/dist/agents/index.js +9 -0
  59. package/node_modules/@poe-code/agent-defs/dist/agents/kimi.d.ts +2 -0
  60. package/node_modules/@poe-code/agent-defs/dist/agents/kimi.js +16 -0
  61. package/node_modules/@poe-code/agent-defs/dist/agents/opencode.d.ts +2 -0
  62. package/node_modules/@poe-code/agent-defs/dist/agents/opencode.js +20 -0
  63. package/node_modules/@poe-code/agent-defs/dist/agents/poe-agent.d.ts +2 -0
  64. package/node_modules/@poe-code/agent-defs/dist/agents/poe-agent.js +14 -0
  65. package/node_modules/@poe-code/agent-defs/dist/index.d.ts +5 -0
  66. package/node_modules/@poe-code/agent-defs/dist/index.js +3 -0
  67. package/node_modules/@poe-code/agent-defs/dist/registry.d.ts +3 -0
  68. package/node_modules/@poe-code/agent-defs/dist/registry.js +45 -0
  69. package/node_modules/@poe-code/agent-defs/dist/specifier.d.ts +7 -0
  70. package/node_modules/@poe-code/agent-defs/dist/specifier.js +40 -0
  71. package/node_modules/@poe-code/agent-defs/dist/types.d.ts +28 -0
  72. package/node_modules/@poe-code/agent-defs/dist/types.js +1 -0
  73. package/node_modules/@poe-code/agent-defs/package.json +20 -0
  74. package/node_modules/@poe-code/agent-skill-config/dist/apply.js +2 -1
  75. package/node_modules/@poe-code/agent-skill-config/dist/bridge-active-skills.d.ts +1 -0
  76. package/node_modules/@poe-code/agent-skill-config/dist/bridge-active-skills.js +37 -18
  77. package/node_modules/@poe-code/agent-skill-config/dist/resolve-skill-reference.js +8 -4
  78. package/node_modules/@poe-code/agent-skill-config/package.json +1 -5
  79. package/node_modules/@poe-code/config-mutations/README.md +55 -0
  80. package/node_modules/@poe-code/config-mutations/dist/error-codes.d.ts +1 -0
  81. package/node_modules/@poe-code/config-mutations/dist/error-codes.js +6 -0
  82. package/node_modules/@poe-code/config-mutations/dist/execution/apply-mutation.d.ts +6 -0
  83. package/node_modules/@poe-code/config-mutations/dist/execution/apply-mutation.js +829 -0
  84. package/node_modules/@poe-code/config-mutations/dist/execution/path-utils.d.ts +17 -0
  85. package/node_modules/@poe-code/config-mutations/dist/execution/path-utils.js +64 -0
  86. package/node_modules/@poe-code/config-mutations/dist/execution/run-mutations.d.ts +7 -0
  87. package/node_modules/@poe-code/config-mutations/dist/execution/run-mutations.js +39 -0
  88. package/node_modules/@poe-code/config-mutations/dist/formats/index.d.ts +13 -0
  89. package/node_modules/@poe-code/config-mutations/dist/formats/index.js +49 -0
  90. package/node_modules/@poe-code/config-mutations/dist/formats/json.d.ts +32 -0
  91. package/node_modules/@poe-code/config-mutations/dist/formats/json.js +171 -0
  92. package/node_modules/@poe-code/config-mutations/dist/formats/object.d.ts +4 -0
  93. package/node_modules/@poe-code/config-mutations/dist/formats/object.js +27 -0
  94. package/node_modules/@poe-code/config-mutations/dist/formats/toml.d.ts +2 -0
  95. package/node_modules/@poe-code/config-mutations/dist/formats/toml.js +75 -0
  96. package/node_modules/@poe-code/config-mutations/dist/formats/yaml.d.ts +2 -0
  97. package/node_modules/@poe-code/config-mutations/dist/formats/yaml.js +76 -0
  98. package/node_modules/@poe-code/config-mutations/dist/fs-utils.d.ts +18 -0
  99. package/node_modules/@poe-code/config-mutations/dist/fs-utils.js +43 -0
  100. package/node_modules/@poe-code/config-mutations/dist/index.d.ts +8 -0
  101. package/node_modules/@poe-code/config-mutations/dist/index.js +8 -0
  102. package/node_modules/@poe-code/config-mutations/dist/mutations/config-mutation.d.ts +47 -0
  103. package/node_modules/@poe-code/config-mutations/dist/mutations/config-mutation.js +34 -0
  104. package/node_modules/@poe-code/config-mutations/dist/mutations/file-mutation.d.ts +62 -0
  105. package/node_modules/@poe-code/config-mutations/dist/mutations/file-mutation.js +55 -0
  106. package/node_modules/@poe-code/config-mutations/dist/mutations/template-mutation.d.ts +40 -0
  107. package/node_modules/@poe-code/config-mutations/dist/mutations/template-mutation.js +32 -0
  108. package/node_modules/@poe-code/config-mutations/dist/template/render.d.ts +6 -0
  109. package/node_modules/@poe-code/config-mutations/dist/template/render.js +8 -0
  110. package/node_modules/@poe-code/config-mutations/dist/testing/format-utils.d.ts +7 -0
  111. package/node_modules/@poe-code/config-mutations/dist/testing/format-utils.js +21 -0
  112. package/node_modules/@poe-code/config-mutations/dist/testing/index.d.ts +3 -0
  113. package/node_modules/@poe-code/config-mutations/dist/testing/index.js +2 -0
  114. package/node_modules/@poe-code/config-mutations/dist/testing/mock-fs.d.ts +25 -0
  115. package/node_modules/@poe-code/config-mutations/dist/testing/mock-fs.js +194 -0
  116. package/node_modules/@poe-code/config-mutations/dist/types.d.ts +168 -0
  117. package/node_modules/@poe-code/config-mutations/dist/types.js +6 -0
  118. package/node_modules/@poe-code/config-mutations/package.json +29 -0
  119. package/node_modules/@poe-code/frontmatter/README.md +35 -0
  120. package/node_modules/@poe-code/frontmatter/dist/fences.d.ts +25 -0
  121. package/node_modules/@poe-code/frontmatter/dist/fences.js +100 -0
  122. package/node_modules/@poe-code/frontmatter/dist/index.d.ts +3 -0
  123. package/node_modules/@poe-code/frontmatter/dist/index.js +3 -0
  124. package/node_modules/@poe-code/frontmatter/dist/parse.d.ts +20 -0
  125. package/node_modules/@poe-code/frontmatter/dist/parse.js +209 -0
  126. package/node_modules/@poe-code/frontmatter/dist/stringify.d.ts +1 -0
  127. package/node_modules/@poe-code/frontmatter/dist/stringify.js +48 -0
  128. package/node_modules/@poe-code/frontmatter/package.json +25 -0
  129. package/node_modules/toolcraft-design/README.md +160 -0
  130. package/node_modules/toolcraft-design/dist/acp/components.d.ts +12 -0
  131. package/node_modules/toolcraft-design/dist/acp/components.js +137 -0
  132. package/node_modules/toolcraft-design/dist/acp/index.d.ts +3 -0
  133. package/node_modules/toolcraft-design/dist/acp/index.js +2 -0
  134. package/node_modules/toolcraft-design/dist/acp/writer.d.ts +13 -0
  135. package/node_modules/toolcraft-design/dist/acp/writer.js +21 -0
  136. package/node_modules/toolcraft-design/dist/components/browser.d.ts +15 -0
  137. package/node_modules/toolcraft-design/dist/components/browser.js +31 -0
  138. package/node_modules/toolcraft-design/dist/components/catalog.d.ts +26 -0
  139. package/node_modules/toolcraft-design/dist/components/catalog.js +95 -0
  140. package/node_modules/toolcraft-design/dist/components/color.d.ts +31 -0
  141. package/node_modules/toolcraft-design/dist/components/color.js +102 -0
  142. package/node_modules/toolcraft-design/dist/components/command-errors.d.ts +16 -0
  143. package/node_modules/toolcraft-design/dist/components/command-errors.js +23 -0
  144. package/node_modules/toolcraft-design/dist/components/detail-card.d.ts +22 -0
  145. package/node_modules/toolcraft-design/dist/components/detail-card.js +45 -0
  146. package/node_modules/toolcraft-design/dist/components/help-formatter-plain.d.ts +5 -0
  147. package/node_modules/toolcraft-design/dist/components/help-formatter-plain.js +132 -0
  148. package/node_modules/toolcraft-design/dist/components/help-formatter.d.ts +33 -0
  149. package/node_modules/toolcraft-design/dist/components/help-formatter.js +213 -0
  150. package/node_modules/toolcraft-design/dist/components/index.d.ts +16 -0
  151. package/node_modules/toolcraft-design/dist/components/index.js +10 -0
  152. package/node_modules/toolcraft-design/dist/components/logger.d.ts +11 -0
  153. package/node_modules/toolcraft-design/dist/components/logger.js +60 -0
  154. package/node_modules/toolcraft-design/dist/components/symbols.d.ts +12 -0
  155. package/node_modules/toolcraft-design/dist/components/symbols.js +71 -0
  156. package/node_modules/toolcraft-design/dist/components/table.d.ts +15 -0
  157. package/node_modules/toolcraft-design/dist/components/table.js +302 -0
  158. package/node_modules/toolcraft-design/dist/components/template.d.ts +10 -0
  159. package/node_modules/toolcraft-design/dist/components/template.js +437 -0
  160. package/node_modules/toolcraft-design/dist/components/text.d.ts +16 -0
  161. package/node_modules/toolcraft-design/dist/components/text.js +145 -0
  162. package/node_modules/toolcraft-design/dist/dashboard/ansi.d.ts +18 -0
  163. package/node_modules/toolcraft-design/dist/dashboard/ansi.js +343 -0
  164. package/node_modules/toolcraft-design/dist/dashboard/buffer.d.ts +25 -0
  165. package/node_modules/toolcraft-design/dist/dashboard/buffer.js +219 -0
  166. package/node_modules/toolcraft-design/dist/dashboard/components/border.d.ts +9 -0
  167. package/node_modules/toolcraft-design/dist/dashboard/components/border.js +123 -0
  168. package/node_modules/toolcraft-design/dist/dashboard/components/footer.d.ts +8 -0
  169. package/node_modules/toolcraft-design/dist/dashboard/components/footer.js +56 -0
  170. package/node_modules/toolcraft-design/dist/dashboard/components/output-pane.d.ts +12 -0
  171. package/node_modules/toolcraft-design/dist/dashboard/components/output-pane.js +268 -0
  172. package/node_modules/toolcraft-design/dist/dashboard/components/stats-pane.d.ts +7 -0
  173. package/node_modules/toolcraft-design/dist/dashboard/components/stats-pane.js +107 -0
  174. package/node_modules/toolcraft-design/dist/dashboard/dashboard.d.ts +20 -0
  175. package/node_modules/toolcraft-design/dist/dashboard/dashboard.js +167 -0
  176. package/node_modules/toolcraft-design/dist/dashboard/demo.d.ts +13 -0
  177. package/node_modules/toolcraft-design/dist/dashboard/demo.js +145 -0
  178. package/node_modules/toolcraft-design/dist/dashboard/index.d.ts +8 -0
  179. package/node_modules/toolcraft-design/dist/dashboard/index.js +4 -0
  180. package/node_modules/toolcraft-design/dist/dashboard/keymap.d.ts +8 -0
  181. package/node_modules/toolcraft-design/dist/dashboard/keymap.js +233 -0
  182. package/node_modules/toolcraft-design/dist/dashboard/layout.d.ts +25 -0
  183. package/node_modules/toolcraft-design/dist/dashboard/layout.js +79 -0
  184. package/node_modules/toolcraft-design/dist/dashboard/should-use-dashboard.d.ts +10 -0
  185. package/node_modules/toolcraft-design/dist/dashboard/should-use-dashboard.js +7 -0
  186. package/node_modules/toolcraft-design/dist/dashboard/snapshot.d.ts +10 -0
  187. package/node_modules/toolcraft-design/dist/dashboard/snapshot.js +68 -0
  188. package/node_modules/toolcraft-design/dist/dashboard/store.d.ts +8 -0
  189. package/node_modules/toolcraft-design/dist/dashboard/store.js +51 -0
  190. package/node_modules/toolcraft-design/dist/dashboard/terminal-width.d.ts +4 -0
  191. package/node_modules/toolcraft-design/dist/dashboard/terminal-width.js +71 -0
  192. package/node_modules/toolcraft-design/dist/dashboard/terminal.d.ts +37 -0
  193. package/node_modules/toolcraft-design/dist/dashboard/terminal.js +264 -0
  194. package/node_modules/toolcraft-design/dist/dashboard/types.d.ts +38 -0
  195. package/node_modules/toolcraft-design/dist/dashboard/types.js +1 -0
  196. package/node_modules/toolcraft-design/dist/explorer/actions.d.ts +16 -0
  197. package/node_modules/toolcraft-design/dist/explorer/actions.js +39 -0
  198. package/node_modules/toolcraft-design/dist/explorer/demo.d.ts +13 -0
  199. package/node_modules/toolcraft-design/dist/explorer/demo.js +297 -0
  200. package/node_modules/toolcraft-design/dist/explorer/events.d.ts +67 -0
  201. package/node_modules/toolcraft-design/dist/explorer/events.js +1 -0
  202. package/node_modules/toolcraft-design/dist/explorer/filter.d.ts +10 -0
  203. package/node_modules/toolcraft-design/dist/explorer/filter.js +95 -0
  204. package/node_modules/toolcraft-design/dist/explorer/index.d.ts +8 -0
  205. package/node_modules/toolcraft-design/dist/explorer/index.js +8 -0
  206. package/node_modules/toolcraft-design/dist/explorer/jobs.d.ts +7 -0
  207. package/node_modules/toolcraft-design/dist/explorer/jobs.js +59 -0
  208. package/node_modules/toolcraft-design/dist/explorer/keymap.d.ts +21 -0
  209. package/node_modules/toolcraft-design/dist/explorer/keymap.js +376 -0
  210. package/node_modules/toolcraft-design/dist/explorer/layout.d.ts +20 -0
  211. package/node_modules/toolcraft-design/dist/explorer/layout.js +73 -0
  212. package/node_modules/toolcraft-design/dist/explorer/reducer.d.ts +9 -0
  213. package/node_modules/toolcraft-design/dist/explorer/reducer.js +782 -0
  214. package/node_modules/toolcraft-design/dist/explorer/render/detail.d.ts +4 -0
  215. package/node_modules/toolcraft-design/dist/explorer/render/detail.js +97 -0
  216. package/node_modules/toolcraft-design/dist/explorer/render/footer.d.ts +4 -0
  217. package/node_modules/toolcraft-design/dist/explorer/render/footer.js +73 -0
  218. package/node_modules/toolcraft-design/dist/explorer/render/header.d.ts +4 -0
  219. package/node_modules/toolcraft-design/dist/explorer/render/header.js +49 -0
  220. package/node_modules/toolcraft-design/dist/explorer/render/index.d.ts +8 -0
  221. package/node_modules/toolcraft-design/dist/explorer/render/index.js +53 -0
  222. package/node_modules/toolcraft-design/dist/explorer/render/list.d.ts +4 -0
  223. package/node_modules/toolcraft-design/dist/explorer/render/list.js +116 -0
  224. package/node_modules/toolcraft-design/dist/explorer/render/modal.d.ts +3 -0
  225. package/node_modules/toolcraft-design/dist/explorer/render/modal.js +87 -0
  226. package/node_modules/toolcraft-design/dist/explorer/render/test-fixtures.d.ts +8 -0
  227. package/node_modules/toolcraft-design/dist/explorer/render/test-fixtures.js +156 -0
  228. package/node_modules/toolcraft-design/dist/explorer/render/text.d.ts +12 -0
  229. package/node_modules/toolcraft-design/dist/explorer/render/text.js +81 -0
  230. package/node_modules/toolcraft-design/dist/explorer/runtime.d.ts +2 -0
  231. package/node_modules/toolcraft-design/dist/explorer/runtime.js +340 -0
  232. package/node_modules/toolcraft-design/dist/explorer/runtime.test-helpers.d.ts +50 -0
  233. package/node_modules/toolcraft-design/dist/explorer/runtime.test-helpers.js +101 -0
  234. package/node_modules/toolcraft-design/dist/explorer/state.d.ts +137 -0
  235. package/node_modules/toolcraft-design/dist/explorer/state.js +86 -0
  236. package/node_modules/toolcraft-design/dist/explorer/theme.d.ts +27 -0
  237. package/node_modules/toolcraft-design/dist/explorer/theme.js +29 -0
  238. package/node_modules/toolcraft-design/dist/index.d.ts +50 -0
  239. package/node_modules/toolcraft-design/dist/index.js +43 -0
  240. package/node_modules/toolcraft-design/dist/internal/color-support.d.ts +9 -0
  241. package/node_modules/toolcraft-design/dist/internal/color-support.js +12 -0
  242. package/node_modules/toolcraft-design/dist/internal/output-format.d.ts +6 -0
  243. package/node_modules/toolcraft-design/dist/internal/output-format.js +22 -0
  244. package/node_modules/toolcraft-design/dist/internal/strip-ansi.d.ts +1 -0
  245. package/node_modules/toolcraft-design/dist/internal/strip-ansi.js +50 -0
  246. package/node_modules/toolcraft-design/dist/internal/theme-detect.d.ts +12 -0
  247. package/node_modules/toolcraft-design/dist/internal/theme-detect.js +71 -0
  248. package/node_modules/toolcraft-design/dist/internal/theme-state.d.ts +12 -0
  249. package/node_modules/toolcraft-design/dist/internal/theme-state.js +35 -0
  250. package/node_modules/toolcraft-design/dist/prompts/index.d.ts +91 -0
  251. package/node_modules/toolcraft-design/dist/prompts/index.js +137 -0
  252. package/node_modules/toolcraft-design/dist/prompts/interactive/cancel-symbol.d.ts +2 -0
  253. package/node_modules/toolcraft-design/dist/prompts/interactive/cancel-symbol.js +4 -0
  254. package/node_modules/toolcraft-design/dist/prompts/interactive/confirm.d.ts +9 -0
  255. package/node_modules/toolcraft-design/dist/prompts/interactive/confirm.js +47 -0
  256. package/node_modules/toolcraft-design/dist/prompts/interactive/core.d.ts +55 -0
  257. package/node_modules/toolcraft-design/dist/prompts/interactive/core.js +274 -0
  258. package/node_modules/toolcraft-design/dist/prompts/interactive/glyphs.d.ts +20 -0
  259. package/node_modules/toolcraft-design/dist/prompts/interactive/glyphs.js +53 -0
  260. package/node_modules/toolcraft-design/dist/prompts/interactive/index.d.ts +6 -0
  261. package/node_modules/toolcraft-design/dist/prompts/interactive/index.js +6 -0
  262. package/node_modules/toolcraft-design/dist/prompts/interactive/keys.d.ts +2 -0
  263. package/node_modules/toolcraft-design/dist/prompts/interactive/keys.js +28 -0
  264. package/node_modules/toolcraft-design/dist/prompts/interactive/multiselect.d.ts +13 -0
  265. package/node_modules/toolcraft-design/dist/prompts/interactive/multiselect.js +131 -0
  266. package/node_modules/toolcraft-design/dist/prompts/interactive/pagination.d.ts +10 -0
  267. package/node_modules/toolcraft-design/dist/prompts/interactive/pagination.js +52 -0
  268. package/node_modules/toolcraft-design/dist/prompts/interactive/password.d.ts +10 -0
  269. package/node_modules/toolcraft-design/dist/prompts/interactive/password.js +55 -0
  270. package/node_modules/toolcraft-design/dist/prompts/interactive/select.d.ts +18 -0
  271. package/node_modules/toolcraft-design/dist/prompts/interactive/select.js +89 -0
  272. package/node_modules/toolcraft-design/dist/prompts/interactive/test-helpers.d.ts +21 -0
  273. package/node_modules/toolcraft-design/dist/prompts/interactive/test-helpers.js +32 -0
  274. package/node_modules/toolcraft-design/dist/prompts/interactive/text.d.ts +12 -0
  275. package/node_modules/toolcraft-design/dist/prompts/interactive/text.js +60 -0
  276. package/node_modules/toolcraft-design/dist/prompts/interactive/wrap.d.ts +4 -0
  277. package/node_modules/toolcraft-design/dist/prompts/interactive/wrap.js +18 -0
  278. package/node_modules/toolcraft-design/dist/prompts/primitives/cancel.d.ts +2 -0
  279. package/node_modules/toolcraft-design/dist/prompts/primitives/cancel.js +9 -0
  280. package/node_modules/toolcraft-design/dist/prompts/primitives/intro.d.ts +1 -0
  281. package/node_modules/toolcraft-design/dist/prompts/primitives/intro.js +16 -0
  282. package/node_modules/toolcraft-design/dist/prompts/primitives/log.d.ts +18 -0
  283. package/node_modules/toolcraft-design/dist/prompts/primitives/log.js +104 -0
  284. package/node_modules/toolcraft-design/dist/prompts/primitives/note.d.ts +1 -0
  285. package/node_modules/toolcraft-design/dist/prompts/primitives/note.js +39 -0
  286. package/node_modules/toolcraft-design/dist/prompts/primitives/outro.d.ts +1 -0
  287. package/node_modules/toolcraft-design/dist/prompts/primitives/outro.js +16 -0
  288. package/node_modules/toolcraft-design/dist/prompts/primitives/spinner.d.ts +6 -0
  289. package/node_modules/toolcraft-design/dist/prompts/primitives/spinner.js +74 -0
  290. package/node_modules/toolcraft-design/dist/prompts/theme.d.ts +11 -0
  291. package/node_modules/toolcraft-design/dist/prompts/theme.js +15 -0
  292. package/node_modules/toolcraft-design/dist/static/index.d.ts +4 -0
  293. package/node_modules/toolcraft-design/dist/static/index.js +2 -0
  294. package/node_modules/toolcraft-design/dist/static/menu.d.ts +11 -0
  295. package/node_modules/toolcraft-design/dist/static/menu.js +42 -0
  296. package/node_modules/toolcraft-design/dist/static/spinner.d.ts +14 -0
  297. package/node_modules/toolcraft-design/dist/static/spinner.js +52 -0
  298. package/node_modules/toolcraft-design/dist/terminal-markdown/ast.d.ts +92 -0
  299. package/node_modules/toolcraft-design/dist/terminal-markdown/ast.js +1 -0
  300. package/node_modules/toolcraft-design/dist/terminal-markdown/demo-content.d.ts +2 -0
  301. package/node_modules/toolcraft-design/dist/terminal-markdown/demo-content.js +139 -0
  302. package/node_modules/toolcraft-design/dist/terminal-markdown/index.d.ts +6 -0
  303. package/node_modules/toolcraft-design/dist/terminal-markdown/index.js +8 -0
  304. package/node_modules/toolcraft-design/dist/terminal-markdown/parser/block.d.ts +7 -0
  305. package/node_modules/toolcraft-design/dist/terminal-markdown/parser/block.js +1495 -0
  306. package/node_modules/toolcraft-design/dist/terminal-markdown/parser/frontmatter.d.ts +8 -0
  307. package/node_modules/toolcraft-design/dist/terminal-markdown/parser/frontmatter.js +36 -0
  308. package/node_modules/toolcraft-design/dist/terminal-markdown/parser/inline.d.ts +10 -0
  309. package/node_modules/toolcraft-design/dist/terminal-markdown/parser/inline.js +1190 -0
  310. package/node_modules/toolcraft-design/dist/terminal-markdown/parser.d.ts +5 -0
  311. package/node_modules/toolcraft-design/dist/terminal-markdown/parser.js +42 -0
  312. package/node_modules/toolcraft-design/dist/terminal-markdown/renderer.d.ts +6 -0
  313. package/node_modules/toolcraft-design/dist/terminal-markdown/renderer.js +615 -0
  314. package/node_modules/toolcraft-design/dist/terminal-markdown/testing/theme-render-fixture.d.ts +1 -0
  315. package/node_modules/toolcraft-design/dist/terminal-markdown/testing/theme-render-fixture.js +27 -0
  316. package/node_modules/toolcraft-design/dist/tokens/brand.d.ts +5 -0
  317. package/node_modules/toolcraft-design/dist/tokens/brand.js +5 -0
  318. package/node_modules/toolcraft-design/dist/tokens/colors.d.ts +37 -0
  319. package/node_modules/toolcraft-design/dist/tokens/colors.js +85 -0
  320. package/node_modules/toolcraft-design/dist/tokens/index.d.ts +6 -0
  321. package/node_modules/toolcraft-design/dist/tokens/index.js +5 -0
  322. package/node_modules/toolcraft-design/dist/tokens/spacing.d.ts +6 -0
  323. package/node_modules/toolcraft-design/dist/tokens/spacing.js +6 -0
  324. package/node_modules/toolcraft-design/dist/tokens/typography.d.ts +7 -0
  325. package/node_modules/toolcraft-design/dist/tokens/typography.js +8 -0
  326. package/node_modules/toolcraft-design/dist/tokens/widths.d.ts +5 -0
  327. package/node_modules/toolcraft-design/dist/tokens/widths.js +5 -0
  328. package/node_modules/toolcraft-design/package.json +44 -0
  329. package/package.json +15 -5
@@ -0,0 +1,782 @@
1
+ import { buildActionContext, resolveAction } from "./actions.js";
2
+ import { filterRows } from "./filter.js";
3
+ import { REGION_ALL, REGION_DETAIL, REGION_FOOTER, REGION_HEADER, REGION_LIST, REGION_MODAL, resolveExplorerLayoutMode } from "./state.js";
4
+ const NO_EFFECTS = [];
5
+ const DEFAULT_ACTION_HANDLES = {
6
+ refresh: async () => undefined,
7
+ suspendAnd: async (fn) => fn(),
8
+ toast: () => undefined,
9
+ confirm: async () => false,
10
+ exit: () => undefined
11
+ };
12
+ export function step(state, event, runtimeHandles = DEFAULT_ACTION_HANDLES) {
13
+ switch (event.type) {
14
+ case "key":
15
+ return stepKey(state, event.key, runtimeHandles);
16
+ case "resize":
17
+ return resize(state, event.cols, event.rows);
18
+ case "rowsLoaded":
19
+ return rowsLoaded(state, event.rows);
20
+ case "detailLoading":
21
+ return detailLoading(state, event.rowId, event.token);
22
+ case "detailLoaded":
23
+ return detailLoaded(state, event.rowId, event.token, event.items);
24
+ case "detailItemRendered":
25
+ return detailItemRendered(state, event.rowId, event.token, event.itemIndex, event.content);
26
+ case "detailError":
27
+ return detailError(state, event.rowId, event.token, event.error);
28
+ case "actionResolved":
29
+ return actionResolved(state, event.actionId);
30
+ case "toastExpired":
31
+ return expireToast(state);
32
+ case "suspendResumed":
33
+ return suspendResumed(state, event.emit, runtimeHandles);
34
+ case "modalDismissed":
35
+ return modalDismissed(state, event.result, runtimeHandles);
36
+ }
37
+ }
38
+ function stepKey(state, key, runtimeHandles) {
39
+ const target = state.bindings.resolve(key);
40
+ if (state.modal !== null) {
41
+ return stepModalKey(state, key, target, runtimeHandles);
42
+ }
43
+ if (state.filterFocused) {
44
+ return stepFilterKey(state, key, target, runtimeHandles);
45
+ }
46
+ if (target?.type === "action") {
47
+ if (state.actionState.get(target.id)?.source === "detail" && state.focused !== "detail") {
48
+ return mark(state, 0);
49
+ }
50
+ const action = resolveAction(state, key);
51
+ return action === null ? mark(state, 0) : dispatchAction(state, action, false, runtimeHandles);
52
+ }
53
+ if (target?.type === "builtin") {
54
+ switch (target.id) {
55
+ case "quit":
56
+ return { state: markDirty(state, 0), effects: [{ type: "exit", result: null }] };
57
+ case "filter":
58
+ return focusFilter(state);
59
+ case "help":
60
+ return setModal(state, { kind: "help" });
61
+ case "palette":
62
+ return setModal(state, { kind: "palette", query: "", cursor: 0 });
63
+ case "cursorUp":
64
+ return moveCursor(state, -1);
65
+ case "cursorDown":
66
+ return moveCursor(state, 1);
67
+ case "top":
68
+ return setCursor(state, 0);
69
+ case "bottom":
70
+ return setCursor(state, state.filtered.length - 1);
71
+ case "pageUp":
72
+ return moveCursor(state, -pageSize(state));
73
+ case "pageDown":
74
+ return moveCursor(state, pageSize(state));
75
+ case "focusNext":
76
+ return focusNext(state);
77
+ case "escape":
78
+ return escape(state, runtimeHandles);
79
+ case "confirm":
80
+ return confirmKey(state, runtimeHandles);
81
+ case "toggleSelect":
82
+ return toggleSelect(state);
83
+ case "selectAll":
84
+ return selectAll(state);
85
+ case "clearSelection":
86
+ return clearSelection(state);
87
+ case "detailScrollDown":
88
+ return detailScroll(state, 1);
89
+ case "detailScrollUp":
90
+ return detailScroll(state, -1);
91
+ case "extendSelectionUp":
92
+ return extendSelection(state, -1);
93
+ case "extendSelectionDown":
94
+ return extendSelection(state, 1);
95
+ case "reorderUp":
96
+ return reorder(state, -1);
97
+ case "reorderDown":
98
+ return reorder(state, 1);
99
+ }
100
+ }
101
+ if (isBackspace(key)) {
102
+ return updateFilter(state, state.filter.slice(0, -1));
103
+ }
104
+ if (!state.multiSelect && isSelectionSpace(key)) {
105
+ return mark(state, 0);
106
+ }
107
+ if (isPrintable(key)) {
108
+ return updateFilter(state, `${state.filter}${key.ch}`);
109
+ }
110
+ return mark(state, 0);
111
+ }
112
+ function stepFilterKey(state, key, target, runtimeHandles) {
113
+ if (target?.type === "builtin" && target.id === "escape") {
114
+ return escape(state, runtimeHandles);
115
+ }
116
+ if (target?.type === "builtin" && target.id === "confirm") {
117
+ return {
118
+ state: { ...state, filterFocused: false, dirty: REGION_HEADER | REGION_FOOTER },
119
+ effects: NO_EFFECTS
120
+ };
121
+ }
122
+ if (isBackspace(key)) {
123
+ return updateFilter(state, state.filter.slice(0, -1));
124
+ }
125
+ if (isPrintable(key)) {
126
+ return updateFilter(state, `${state.filter}${key.ch}`);
127
+ }
128
+ return mark(state, 0);
129
+ }
130
+ function stepModalKey(state, key, target, runtimeHandles) {
131
+ if (state.modal?.kind === "confirm") {
132
+ if (target?.type === "builtin" && target.id === "escape") {
133
+ return modalDismissed(state, false, runtimeHandles);
134
+ }
135
+ if (target?.type === "builtin" && target.id === "confirm") {
136
+ return modalDismissed(state, true, runtimeHandles);
137
+ }
138
+ if (isConfirmNo(key)) {
139
+ return modalDismissed(state, false, runtimeHandles);
140
+ }
141
+ if (isConfirmYes(key)) {
142
+ return modalDismissed(state, true, runtimeHandles);
143
+ }
144
+ return mark(state, 0);
145
+ }
146
+ if (state.modal?.kind === "help") {
147
+ if (target?.type === "builtin" && (target.id === "escape" || target.id === "help")) {
148
+ return modalDismissed(state, false, runtimeHandles);
149
+ }
150
+ return mark(state, 0);
151
+ }
152
+ if (state.modal?.kind === "palette") {
153
+ if (target?.type === "builtin") {
154
+ switch (target.id) {
155
+ case "escape":
156
+ return modalDismissed(state, false, runtimeHandles);
157
+ case "confirm":
158
+ return dispatchPaletteAction(state, runtimeHandles);
159
+ case "cursorUp":
160
+ return movePaletteCursor(state, -1);
161
+ case "cursorDown":
162
+ return movePaletteCursor(state, 1);
163
+ }
164
+ }
165
+ return paletteInput(state, key);
166
+ }
167
+ return mark(state, 0);
168
+ }
169
+ function resize(state, cols, rows) {
170
+ const size = { cols: normalizeSize(cols), rows: normalizeSize(rows) };
171
+ const layout = resolveExplorerLayoutMode(size.cols);
172
+ if (state.size.cols === size.cols && state.size.rows === size.rows && state.layout === layout) {
173
+ return mark(state, 0);
174
+ }
175
+ return {
176
+ state: clampDetailScroll({ ...state, size, layout, dirty: REGION_ALL }),
177
+ effects: NO_EFFECTS
178
+ };
179
+ }
180
+ function rowsLoaded(state, rows) {
181
+ const rowIds = new Set();
182
+ for (const row of rows) {
183
+ if (rowIds.has(row.id)) {
184
+ throw new Error(`Duplicate explorer row id: ${row.id}`);
185
+ }
186
+ rowIds.add(row.id);
187
+ }
188
+ const matches = filterRows(state.filter, rows);
189
+ const filtered = matches.map((match) => match.index);
190
+ const matchPositions = createMatchPositions(matches);
191
+ const cursor = clamp(state.cursor, 0, Math.max(0, filtered.length - 1));
192
+ const selected = state.multiSelect ? pruneSelection(state.selected, rows) : new Set();
193
+ const detail = resetDetailForCursor(state, rows, filtered, cursor);
194
+ const modal = modalStillValid(state.modal, rows);
195
+ if (state.modal?.kind === "confirm" && modal === null) {
196
+ state.modal.resolver(false);
197
+ }
198
+ const nextView = { ...state, rows, filtered, matchPositions, cursor, selected, detail, modal };
199
+ const next = {
200
+ ...nextView,
201
+ actionState: recomputeActionState(nextView),
202
+ dirty: REGION_HEADER | REGION_LIST | REGION_DETAIL | REGION_FOOTER | REGION_MODAL
203
+ };
204
+ const effect = detailEffect(next);
205
+ return { state: next, effects: effect === undefined ? NO_EFFECTS : [effect] };
206
+ }
207
+ function detailLoading(state, rowId, token) {
208
+ if (state.detail.rowId !== rowId || state.detail.token !== token) {
209
+ return mark(state, 0);
210
+ }
211
+ if (state.detail.loading) {
212
+ return mark(state, 0);
213
+ }
214
+ return {
215
+ state: { ...state, detail: { ...state.detail, loading: true }, dirty: REGION_DETAIL },
216
+ effects: NO_EFFECTS
217
+ };
218
+ }
219
+ function detailLoaded(state, rowId, token, items) {
220
+ if (state.detail.rowId !== rowId || state.detail.token !== token) {
221
+ return mark(state, 0);
222
+ }
223
+ const detail = {
224
+ ...state.detail,
225
+ items,
226
+ cursor: clamp(state.detail.cursor, 0, Math.max(0, items.length - 1)),
227
+ scroll: 0,
228
+ loading: false
229
+ };
230
+ return {
231
+ state: {
232
+ ...state,
233
+ detail,
234
+ actionState: recomputeActionState({ ...state, detail }),
235
+ dirty: REGION_DETAIL | REGION_FOOTER
236
+ },
237
+ effects: NO_EFFECTS
238
+ };
239
+ }
240
+ function detailItemRendered(state, rowId, token, itemIndex, content) {
241
+ if (state.detail.rowId !== rowId || state.detail.token !== token || state.detail.items?.[itemIndex] === undefined) {
242
+ return mark(state, 0);
243
+ }
244
+ const items = state.detail.items.map((item, index) => index === itemIndex ? { ...item, renderedContent: content } : item);
245
+ const detail = { ...state.detail, items };
246
+ return {
247
+ state: clampDetailScroll({ ...state, detail, dirty: REGION_DETAIL }),
248
+ effects: NO_EFFECTS
249
+ };
250
+ }
251
+ function detailError(state, rowId, token, error) {
252
+ if (state.detail.rowId !== rowId || state.detail.token !== token) {
253
+ return mark(state, 0);
254
+ }
255
+ return detailLoaded(state, rowId, token, [
256
+ {
257
+ id: `${rowId}:error`,
258
+ title: "Error",
259
+ badge: { text: "error", tone: "error" },
260
+ render: () => error.message
261
+ }
262
+ ]);
263
+ }
264
+ function actionResolved(state, actionId) {
265
+ const current = state.actionState.get(actionId);
266
+ if (current === undefined || current.running !== true) {
267
+ return mark(state, 0);
268
+ }
269
+ const actionState = new Map(state.actionState);
270
+ actionState.set(actionId, { ...current, running: false });
271
+ return { state: { ...state, actionState, dirty: REGION_FOOTER }, effects: NO_EFFECTS };
272
+ }
273
+ function expireToast(state) {
274
+ if (state.toast === null) {
275
+ return mark(state, 0);
276
+ }
277
+ return { state: { ...state, toast: null, dirty: REGION_FOOTER }, effects: NO_EFFECTS };
278
+ }
279
+ function suspendResumed(state, emit, runtimeHandles) {
280
+ const next = step(state, emit, runtimeHandles);
281
+ return {
282
+ state: { ...next.state, dirty: next.state.dirty | REGION_ALL },
283
+ effects: next.effects
284
+ };
285
+ }
286
+ function modalDismissed(state, result, runtimeHandles) {
287
+ const modal = state.modal;
288
+ const closed = { ...state, modal: null, dirty: REGION_MODAL | REGION_FOOTER };
289
+ if (modal?.kind === "confirm") {
290
+ modal.resolver(result === true);
291
+ }
292
+ if (modal?.kind !== "confirm" || result !== true) {
293
+ return { state: closed, effects: NO_EFFECTS };
294
+ }
295
+ return dispatchAction(closed, modal.action, true, runtimeHandles, modal.rows);
296
+ }
297
+ function moveCursor(state, delta) {
298
+ if (state.focused === "detail" && hasDetailCursor(state)) {
299
+ return moveDetailCursor(state, delta);
300
+ }
301
+ return setCursor(state, state.cursor + delta);
302
+ }
303
+ function moveDetailCursor(state, delta) {
304
+ const max = Math.max(0, (state.detail.items?.length ?? 0) - 1);
305
+ const cursor = clamp(state.detail.cursor + delta, 0, max);
306
+ if (cursor === state.detail.cursor) {
307
+ return mark(state, 0);
308
+ }
309
+ const detail = { ...state.detail, cursor };
310
+ return {
311
+ state: {
312
+ ...state,
313
+ detail,
314
+ actionState: recomputeActionState({ ...state, detail }),
315
+ dirty: REGION_DETAIL | REGION_FOOTER
316
+ },
317
+ effects: NO_EFFECTS
318
+ };
319
+ }
320
+ function hasDetailCursor(state) {
321
+ const items = state.detail.items ?? [];
322
+ return items.some((item) => item.title !== undefined);
323
+ }
324
+ function setCursor(state, cursor) {
325
+ const nextCursor = clamp(cursor, 0, Math.max(0, state.filtered.length - 1));
326
+ if (nextCursor === state.cursor) {
327
+ return mark(state, 0);
328
+ }
329
+ const detail = resetDetailForCursor(state, state.rows, state.filtered, nextCursor);
330
+ const next = {
331
+ ...state,
332
+ cursor: nextCursor,
333
+ detail,
334
+ actionState: recomputeActionState({ ...state, cursor: nextCursor, detail }),
335
+ dirty: REGION_LIST | REGION_DETAIL | REGION_FOOTER
336
+ };
337
+ const effect = detailEffect(next);
338
+ return { state: next, effects: effect === undefined ? NO_EFFECTS : [effect] };
339
+ }
340
+ function updateFilter(state, filter) {
341
+ if (filter === state.filter) {
342
+ return mark(state, 0);
343
+ }
344
+ const matches = filterRows(filter, state.rows);
345
+ const filtered = matches.map((match) => match.index);
346
+ const matchPositions = createMatchPositions(matches);
347
+ const cursor = clamp(0, 0, Math.max(0, filtered.length - 1));
348
+ const detail = resetDetailForCursor({ ...state, filter }, state.rows, filtered, cursor);
349
+ const next = {
350
+ ...state,
351
+ filter,
352
+ filterFocused: filter === "" ? false : state.filterFocused,
353
+ filtered,
354
+ matchPositions,
355
+ cursor,
356
+ detail,
357
+ actionState: recomputeActionState({ ...state, filter, filtered, matchPositions, cursor, detail }),
358
+ dirty: REGION_HEADER | REGION_LIST | REGION_DETAIL | REGION_FOOTER
359
+ };
360
+ const effect = detailEffect(next);
361
+ return { state: next, effects: effect === undefined ? NO_EFFECTS : [effect] };
362
+ }
363
+ function focusFilter(state) {
364
+ if (state.filterFocused) {
365
+ return mark(state, 0);
366
+ }
367
+ return {
368
+ state: { ...state, filterFocused: true, dirty: REGION_HEADER | REGION_FOOTER },
369
+ effects: NO_EFFECTS
370
+ };
371
+ }
372
+ function focusNext(state) {
373
+ const focused = state.focused === "list" ? "detail" : "list";
374
+ return {
375
+ state: {
376
+ ...state,
377
+ focused,
378
+ actionState: recomputeActionState({ ...state, focused }),
379
+ dirty: REGION_LIST | REGION_DETAIL | REGION_FOOTER
380
+ },
381
+ effects: NO_EFFECTS
382
+ };
383
+ }
384
+ function escape(state, runtimeHandles) {
385
+ if (state.filterFocused || state.filter.length > 0) {
386
+ const cleared = updateFilter({ ...state, filterFocused: false }, "");
387
+ return {
388
+ state: { ...cleared.state, filterFocused: false, dirty: cleared.state.dirty | REGION_HEADER | REGION_FOOTER },
389
+ effects: cleared.effects
390
+ };
391
+ }
392
+ if (state.selected.size > 0) {
393
+ return clearSelection(state);
394
+ }
395
+ if (state.modal !== null) {
396
+ return modalDismissed(state, false, runtimeHandles);
397
+ }
398
+ return { state: markDirty(state, 0), effects: [{ type: "exit", result: null }] };
399
+ }
400
+ function confirmKey(state, runtimeHandles) {
401
+ if (state.modal?.kind === "confirm") {
402
+ return modalDismissed(state, true, runtimeHandles);
403
+ }
404
+ return dispatchPrimary(state, runtimeHandles);
405
+ }
406
+ function toggleSelect(state) {
407
+ if (!state.multiSelect) {
408
+ return mark(state, 0);
409
+ }
410
+ const row = currentRow(state);
411
+ if (row === undefined) {
412
+ return mark(state, 0);
413
+ }
414
+ const selected = new Set(state.selected);
415
+ if (selected.has(row.id)) {
416
+ selected.delete(row.id);
417
+ }
418
+ else {
419
+ selected.add(row.id);
420
+ }
421
+ return selectionChanged(state, selected);
422
+ }
423
+ function selectAll(state) {
424
+ if (!state.multiSelect) {
425
+ return mark(state, 0);
426
+ }
427
+ const selected = new Set(state.selected);
428
+ for (const index of state.filtered) {
429
+ const row = state.rows[index];
430
+ if (row !== undefined) {
431
+ selected.add(row.id);
432
+ }
433
+ }
434
+ return selectionChanged(state, selected);
435
+ }
436
+ function clearSelection(state) {
437
+ if (state.selected.size === 0) {
438
+ return mark(state, 0);
439
+ }
440
+ return selectionChanged(state, new Set());
441
+ }
442
+ function selectionChanged(state, selected) {
443
+ const normalized = state.multiSelect ? selected : new Set();
444
+ if (setsEqual(state.selected, normalized)) {
445
+ return mark(state, 0);
446
+ }
447
+ const next = {
448
+ ...state,
449
+ selected: normalized,
450
+ actionState: recomputeActionState({ ...state, selected: normalized }),
451
+ dirty: REGION_LIST | REGION_FOOTER
452
+ };
453
+ return { state: next, effects: NO_EFFECTS };
454
+ }
455
+ function detailScroll(state, delta) {
456
+ if (state.focused !== "detail") {
457
+ return mark(state, 0);
458
+ }
459
+ const scroll = clamp(state.detail.scroll + delta, 0, maxDetailScroll(state));
460
+ if (scroll === state.detail.scroll) {
461
+ return mark(state, 0);
462
+ }
463
+ return {
464
+ state: { ...state, detail: { ...state.detail, scroll }, dirty: REGION_DETAIL },
465
+ effects: NO_EFFECTS
466
+ };
467
+ }
468
+ function clampDetailScroll(state) {
469
+ const scroll = clamp(state.detail.scroll, 0, maxDetailScroll(state));
470
+ if (scroll === state.detail.scroll) {
471
+ return state;
472
+ }
473
+ return { ...state, detail: { ...state.detail, scroll } };
474
+ }
475
+ function maxDetailScroll(state) {
476
+ const items = state.detail.items;
477
+ if (items === null || items.length === 0) {
478
+ return 0;
479
+ }
480
+ if (items.length === 1 && items[0]?.title === undefined) {
481
+ const visibleHeight = detailBodyHeight(state);
482
+ if (visibleHeight <= 0) {
483
+ return 0;
484
+ }
485
+ return Math.max(0, detailContentLineCount(items[0]) - visibleHeight);
486
+ }
487
+ return Math.max(0, items.length - 1);
488
+ }
489
+ function detailContentLineCount(item) {
490
+ return (item.renderedContent ?? "").split("\n").length;
491
+ }
492
+ function detailBodyHeight(state) {
493
+ if (state.layout === "too-narrow" || state.layout === "narrow-list-only") {
494
+ return 0;
495
+ }
496
+ const rows = normalizeSize(state.size.rows);
497
+ const footerHeight = rows > 0 ? Math.min(1, rows) : 0;
498
+ const headerHeight = Math.min(3, Math.max(0, rows - footerHeight));
499
+ const contentHeight = Math.max(0, rows - headerHeight - footerHeight);
500
+ if (state.layout === "narrow-vertical") {
501
+ const listHeight = Math.ceil(contentHeight / 2);
502
+ const detailHeight = contentHeight - listHeight;
503
+ return Math.max(0, detailHeight - 1);
504
+ }
505
+ return contentHeight;
506
+ }
507
+ function extendSelection(state, delta) {
508
+ if (!state.multiSelect) {
509
+ return moveCursor(state, delta);
510
+ }
511
+ const moved = moveCursor(state, delta);
512
+ const row = currentRow(moved.state);
513
+ if (row === undefined) {
514
+ return moved;
515
+ }
516
+ const selected = new Set(moved.state.selected);
517
+ selected.add(row.id);
518
+ return {
519
+ state: {
520
+ ...moved.state,
521
+ selected,
522
+ actionState: recomputeActionState({ ...moved.state, selected }),
523
+ dirty: moved.state.dirty
524
+ },
525
+ effects: moved.effects
526
+ };
527
+ }
528
+ function reorder(state, delta) {
529
+ if (state.filter !== "" || state.focused !== "list" || state.modal !== null) {
530
+ return mark(state, 0);
531
+ }
532
+ const rowIndex = state.filtered[state.cursor];
533
+ if (rowIndex === undefined) {
534
+ return mark(state, 0);
535
+ }
536
+ const targetIndex = rowIndex + delta;
537
+ if (targetIndex < 0 || targetIndex >= state.rows.length) {
538
+ return mark(state, 0);
539
+ }
540
+ const rows = [...state.rows];
541
+ const current = rows[rowIndex];
542
+ const target = rows[targetIndex];
543
+ if (current === undefined || target === undefined) {
544
+ return mark(state, 0);
545
+ }
546
+ rows[rowIndex] = target;
547
+ rows[targetIndex] = current;
548
+ const filtered = rows.map((_, index) => index);
549
+ const matchPositions = new Map();
550
+ const cursor = targetIndex;
551
+ const next = {
552
+ ...state,
553
+ rows,
554
+ filtered,
555
+ matchPositions,
556
+ cursor,
557
+ actionState: recomputeActionState({ ...state, rows, filtered, matchPositions, cursor }),
558
+ dirty: REGION_LIST | REGION_FOOTER
559
+ };
560
+ return { state: next, effects: [{ type: "persistOrder", orderedIds: rows.map((row) => row.id) }] };
561
+ }
562
+ function paletteInput(state, key) {
563
+ if (state.modal?.kind !== "palette") {
564
+ return mark(state, 0);
565
+ }
566
+ if (isBackspace(key)) {
567
+ return setPaletteQuery(state, state.modal.query.slice(0, -1));
568
+ }
569
+ if (isPrintable(key)) {
570
+ return setPaletteQuery(state, `${state.modal.query}${key.ch}`);
571
+ }
572
+ return mark(state, 0);
573
+ }
574
+ function setPaletteQuery(state, query) {
575
+ if (state.modal?.kind !== "palette") {
576
+ return mark(state, 0);
577
+ }
578
+ const entries = paletteEntries({ ...state, modal: { ...state.modal, query } });
579
+ return setModal(state, {
580
+ ...state.modal,
581
+ query,
582
+ cursor: clamp(state.modal.cursor, 0, Math.max(0, entries.length - 1))
583
+ });
584
+ }
585
+ function movePaletteCursor(state, delta) {
586
+ if (state.modal?.kind !== "palette") {
587
+ return mark(state, 0);
588
+ }
589
+ const max = Math.max(0, paletteEntries(state).length - 1);
590
+ const cursor = clamp(state.modal.cursor + delta, 0, max);
591
+ if (cursor === state.modal.cursor) {
592
+ return mark(state, 0);
593
+ }
594
+ return setModal(state, { ...state.modal, cursor });
595
+ }
596
+ function dispatchPaletteAction(state, runtimeHandles) {
597
+ if (state.modal?.kind !== "palette") {
598
+ return mark(state, 0);
599
+ }
600
+ const entry = paletteEntries(state)[state.modal.cursor];
601
+ if (entry === undefined) {
602
+ return mark(state, 0);
603
+ }
604
+ return dispatchActionById({ ...state, modal: null, dirty: REGION_MODAL | REGION_FOOTER }, entry.id, false, runtimeHandles);
605
+ }
606
+ function dispatchPrimary(state, runtimeHandles) {
607
+ for (const [id, entry] of state.actionState.entries()) {
608
+ if (entry.action?.primary === true && entry.available === true && entry.running !== true) {
609
+ return dispatchActionById(state, id, false, runtimeHandles);
610
+ }
611
+ }
612
+ return mark(state, 0);
613
+ }
614
+ function dispatchActionById(state, actionId, confirmed, runtimeHandles) {
615
+ const entry = state.actionState.get(actionId);
616
+ if (entry?.available !== true || entry.running === true || entry.action === undefined) {
617
+ return mark(state, 0);
618
+ }
619
+ return dispatchAction(state, entry.action, confirmed, runtimeHandles);
620
+ }
621
+ function dispatchAction(state, action, confirmed, runtimeHandles, modalRows) {
622
+ const rows = modalRows ?? selectedRows(state);
623
+ if (rows.length === 0) {
624
+ return mark(state, 0);
625
+ }
626
+ if (action.destructive === true && !confirmed) {
627
+ return {
628
+ state: {
629
+ ...state,
630
+ modal: { kind: "confirm", action, rows, resolver: () => undefined },
631
+ dirty: REGION_MODAL | REGION_FOOTER
632
+ },
633
+ effects: NO_EFFECTS
634
+ };
635
+ }
636
+ const actionState = new Map(state.actionState);
637
+ const current = actionState.get(action.id);
638
+ if (current !== undefined) {
639
+ actionState.set(action.id, { ...current, running: true });
640
+ }
641
+ const next = { ...state, actionState, dirty: state.dirty | REGION_FOOTER };
642
+ return {
643
+ state: next,
644
+ effects: [
645
+ {
646
+ type: "suspend",
647
+ fn: async () => action.handler(buildActionContext(next, action, current?.source ?? actionSource(next, action), runtimeHandles, rows)),
648
+ resumeWith: () => ({ type: "actionResolved", actionId: action.id })
649
+ }
650
+ ]
651
+ };
652
+ }
653
+ function recomputeActionState(view) {
654
+ const next = new Map();
655
+ for (const [id, entry] of view.actionState.entries()) {
656
+ const { action } = entry;
657
+ if (action === undefined) {
658
+ next.set(id, entry);
659
+ continue;
660
+ }
661
+ const ctx = buildActionContext(view, action, entry.source ?? actionSource(view, action), DEFAULT_ACTION_HANDLES);
662
+ const available = action.predicate === undefined ? entry.available : action.predicate(ctx);
663
+ const label = typeof action.label === "function" ? action.label() : action.label;
664
+ next.set(id, { ...entry, available, label });
665
+ }
666
+ return next;
667
+ }
668
+ function resetDetailForCursor(state, rows, filtered, cursor) {
669
+ const row = rows[filtered[cursor] ?? -1];
670
+ if (row === undefined) {
671
+ return {
672
+ rowId: null,
673
+ items: null,
674
+ cursor: 0,
675
+ scroll: 0,
676
+ token: state.detail.token + 1,
677
+ loading: false
678
+ };
679
+ }
680
+ return {
681
+ rowId: row.id,
682
+ items: null,
683
+ cursor: 0,
684
+ scroll: 0,
685
+ token: state.detail.token + 1,
686
+ loading: false
687
+ };
688
+ }
689
+ function detailEffect(state) {
690
+ if (state.detail.rowId === null) {
691
+ return undefined;
692
+ }
693
+ return { type: "renderDetail", rowId: state.detail.rowId, token: state.detail.token };
694
+ }
695
+ function currentRow(state) {
696
+ return state.rows[state.filtered[state.cursor] ?? -1];
697
+ }
698
+ function actionSource(state, action) {
699
+ return state.actionState.get(action.id)?.source ?? "row";
700
+ }
701
+ function selectedRows(state) {
702
+ if (!state.multiSelect || state.selected.size === 0) {
703
+ const row = currentRow(state);
704
+ return row === undefined ? [] : [row];
705
+ }
706
+ return state.rows.filter((row) => state.selected.has(row.id));
707
+ }
708
+ function paletteEntries(state) {
709
+ const query = state.modal?.kind === "palette" ? state.modal.query.toLocaleLowerCase() : "";
710
+ const entries = [];
711
+ for (const [id, entry] of state.actionState.entries()) {
712
+ if (entry.available !== true || entry.running === true || entry.action === undefined) {
713
+ continue;
714
+ }
715
+ if (query !== "" && !entry.label.toLocaleLowerCase().includes(query)) {
716
+ continue;
717
+ }
718
+ entries.push({ id, label: entry.label });
719
+ }
720
+ return entries;
721
+ }
722
+ function setModal(state, modal) {
723
+ return { state: { ...state, modal, dirty: REGION_MODAL | REGION_FOOTER }, effects: NO_EFFECTS };
724
+ }
725
+ function mark(state, dirty) {
726
+ return { state: markDirty(state, dirty), effects: NO_EFFECTS };
727
+ }
728
+ function markDirty(state, dirty) {
729
+ return state.dirty === dirty ? state : { ...state, dirty };
730
+ }
731
+ function pageSize(state) {
732
+ return Math.max(1, Math.floor(state.size.rows / 2));
733
+ }
734
+ function pruneSelection(selected, rows) {
735
+ const ids = new Set(rows.map((row) => row.id));
736
+ return new Set([...selected].filter((id) => ids.has(id)));
737
+ }
738
+ function modalStillValid(modal, rows) {
739
+ if (modal?.kind !== "confirm") {
740
+ return modal;
741
+ }
742
+ const ids = new Set(rows.map((row) => row.id));
743
+ return modal.rows.every((row) => ids.has(row.id)) ? modal : null;
744
+ }
745
+ function normalizeSize(value) {
746
+ if (!Number.isFinite(value)) {
747
+ return 0;
748
+ }
749
+ return Math.max(0, Math.floor(value));
750
+ }
751
+ function clamp(value, min, max) {
752
+ return Math.min(max, Math.max(min, value));
753
+ }
754
+ function createMatchPositions(matches) {
755
+ return new Map(matches.map((match) => [match.index, match.positions]));
756
+ }
757
+ function setsEqual(left, right) {
758
+ if (left.size !== right.size) {
759
+ return false;
760
+ }
761
+ for (const value of left) {
762
+ if (!right.has(value)) {
763
+ return false;
764
+ }
765
+ }
766
+ return true;
767
+ }
768
+ function isPrintable(key) {
769
+ return key.ch !== undefined && !key.ctrl && !key.meta;
770
+ }
771
+ function isBackspace(key) {
772
+ return key.name === "backspace" || key.name === "delete";
773
+ }
774
+ function isSelectionSpace(key) {
775
+ return key.name === "space" || key.ch === " ";
776
+ }
777
+ function isConfirmYes(key) {
778
+ return key.ch === "y" || key.ch === "Y";
779
+ }
780
+ function isConfirmNo(key) {
781
+ return key.ch === "n" || key.ch === "N";
782
+ }