pi-ui-extend 0.1.1

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 (420) hide show
  1. package/README.md +307 -0
  2. package/bin/pix.mjs +219 -0
  3. package/dist/app/app.d.ts +96 -0
  4. package/dist/app/app.js +871 -0
  5. package/dist/app/blink-controller.d.ts +23 -0
  6. package/dist/app/blink-controller.js +82 -0
  7. package/dist/app/cli.d.ts +8 -0
  8. package/dist/app/cli.js +83 -0
  9. package/dist/app/clipboard.d.ts +1 -0
  10. package/dist/app/clipboard.js +24 -0
  11. package/dist/app/command-controller.d.ts +18 -0
  12. package/dist/app/command-controller.js +58 -0
  13. package/dist/app/command-host.d.ts +44 -0
  14. package/dist/app/command-host.js +1 -0
  15. package/dist/app/command-model-actions.d.ts +12 -0
  16. package/dist/app/command-model-actions.js +176 -0
  17. package/dist/app/command-navigation-actions.d.ts +19 -0
  18. package/dist/app/command-navigation-actions.js +267 -0
  19. package/dist/app/command-registry.d.ts +32 -0
  20. package/dist/app/command-registry.js +225 -0
  21. package/dist/app/command-runtime.d.ts +5 -0
  22. package/dist/app/command-runtime.js +32 -0
  23. package/dist/app/command-session-actions.d.ts +20 -0
  24. package/dist/app/command-session-actions.js +295 -0
  25. package/dist/app/constants.d.ts +52 -0
  26. package/dist/app/constants.js +103 -0
  27. package/dist/app/conversation-entry-renderer.d.ts +21 -0
  28. package/dist/app/conversation-entry-renderer.js +81 -0
  29. package/dist/app/conversation-shell-renderer.d.ts +5 -0
  30. package/dist/app/conversation-shell-renderer.js +43 -0
  31. package/dist/app/conversation-tool-renderer.d.ts +16 -0
  32. package/dist/app/conversation-tool-renderer.js +216 -0
  33. package/dist/app/conversation-viewport.d.ts +55 -0
  34. package/dist/app/conversation-viewport.js +252 -0
  35. package/dist/app/dcp-stats.d.ts +2 -0
  36. package/dist/app/dcp-stats.js +116 -0
  37. package/dist/app/editor-layout-renderer.d.ts +31 -0
  38. package/dist/app/editor-layout-renderer.js +211 -0
  39. package/dist/app/editor-panels.d.ts +4 -0
  40. package/dist/app/editor-panels.js +130 -0
  41. package/dist/app/extension-actions-controller.d.ts +22 -0
  42. package/dist/app/extension-actions-controller.js +60 -0
  43. package/dist/app/extension-event-bus.d.ts +3 -0
  44. package/dist/app/extension-event-bus.js +23 -0
  45. package/dist/app/extension-ui-controller.d.ts +57 -0
  46. package/dist/app/extension-ui-controller.js +532 -0
  47. package/dist/app/file-link-opener.d.ts +2 -0
  48. package/dist/app/file-link-opener.js +66 -0
  49. package/dist/app/file-links.d.ts +10 -0
  50. package/dist/app/file-links.js +117 -0
  51. package/dist/app/guards.d.ts +3 -0
  52. package/dist/app/guards.js +9 -0
  53. package/dist/app/icons.d.ts +37 -0
  54. package/dist/app/icons.js +97 -0
  55. package/dist/app/id.d.ts +1 -0
  56. package/dist/app/id.js +4 -0
  57. package/dist/app/image-click-targets.d.ts +5 -0
  58. package/dist/app/image-click-targets.js +32 -0
  59. package/dist/app/image-opener.d.ts +2 -0
  60. package/dist/app/image-opener.js +64 -0
  61. package/dist/app/input-action-controller.d.ts +47 -0
  62. package/dist/app/input-action-controller.js +209 -0
  63. package/dist/app/input-controller.d.ts +60 -0
  64. package/dist/app/input-controller.js +425 -0
  65. package/dist/app/input-paste-handler.d.ts +27 -0
  66. package/dist/app/input-paste-handler.js +146 -0
  67. package/dist/app/menu-items-controller.d.ts +32 -0
  68. package/dist/app/menu-items-controller.js +182 -0
  69. package/dist/app/message-content.d.ts +8 -0
  70. package/dist/app/message-content.js +115 -0
  71. package/dist/app/model-ref.d.ts +13 -0
  72. package/dist/app/model-ref.js +50 -0
  73. package/dist/app/model-usage-controller.d.ts +35 -0
  74. package/dist/app/model-usage-controller.js +99 -0
  75. package/dist/app/model-usage-status.d.ts +125 -0
  76. package/dist/app/model-usage-status.js +749 -0
  77. package/dist/app/mouse-controller.d.ts +182 -0
  78. package/dist/app/mouse-controller.js +968 -0
  79. package/dist/app/native-modifiers.d.ts +3 -0
  80. package/dist/app/native-modifiers.js +60 -0
  81. package/dist/app/nerd-font-controller.d.ts +11 -0
  82. package/dist/app/nerd-font-controller.js +90 -0
  83. package/dist/app/popup-action-controller.d.ts +44 -0
  84. package/dist/app/popup-action-controller.js +278 -0
  85. package/dist/app/popup-menu-controller.d.ts +183 -0
  86. package/dist/app/popup-menu-controller.js +1070 -0
  87. package/dist/app/prompt-enhancer-controller.d.ts +40 -0
  88. package/dist/app/prompt-enhancer-controller.js +215 -0
  89. package/dist/app/queued-message-controller.d.ts +62 -0
  90. package/dist/app/queued-message-controller.js +377 -0
  91. package/dist/app/render-controller.d.ts +41 -0
  92. package/dist/app/render-controller.js +378 -0
  93. package/dist/app/render-text.d.ts +19 -0
  94. package/dist/app/render-text.js +67 -0
  95. package/dist/app/request-history.d.ts +23 -0
  96. package/dist/app/request-history.js +131 -0
  97. package/dist/app/runtime.d.ts +39 -0
  98. package/dist/app/runtime.js +195 -0
  99. package/dist/app/screen-selection.d.ts +6 -0
  100. package/dist/app/screen-selection.js +9 -0
  101. package/dist/app/screen-styler.d.ts +34 -0
  102. package/dist/app/screen-styler.js +168 -0
  103. package/dist/app/scroll-controller.d.ts +51 -0
  104. package/dist/app/scroll-controller.js +207 -0
  105. package/dist/app/session-event-controller.d.ts +69 -0
  106. package/dist/app/session-event-controller.js +338 -0
  107. package/dist/app/session-history.d.ts +23 -0
  108. package/dist/app/session-history.js +164 -0
  109. package/dist/app/session-lifecycle-controller.d.ts +55 -0
  110. package/dist/app/session-lifecycle-controller.js +116 -0
  111. package/dist/app/session-search.d.ts +24 -0
  112. package/dist/app/session-search.js +215 -0
  113. package/dist/app/shell-command.d.ts +27 -0
  114. package/dist/app/shell-command.js +176 -0
  115. package/dist/app/shell-controller.d.ts +28 -0
  116. package/dist/app/shell-controller.js +124 -0
  117. package/dist/app/slash-commands.d.ts +6 -0
  118. package/dist/app/slash-commands.js +75 -0
  119. package/dist/app/startup-checks.d.ts +8 -0
  120. package/dist/app/startup-checks.js +59 -0
  121. package/dist/app/startup-info.d.ts +3 -0
  122. package/dist/app/startup-info.js +176 -0
  123. package/dist/app/status-controller.d.ts +35 -0
  124. package/dist/app/status-controller.js +105 -0
  125. package/dist/app/status-line-renderer.d.ts +68 -0
  126. package/dist/app/status-line-renderer.js +453 -0
  127. package/dist/app/subagents-files.d.ts +10 -0
  128. package/dist/app/subagents-files.js +193 -0
  129. package/dist/app/subagents-model.d.ts +23 -0
  130. package/dist/app/subagents-model.js +224 -0
  131. package/dist/app/subagents-widget-controller.d.ts +43 -0
  132. package/dist/app/subagents-widget-controller.js +311 -0
  133. package/dist/app/tab-line-renderer.d.ts +26 -0
  134. package/dist/app/tab-line-renderer.js +222 -0
  135. package/dist/app/tabs-controller.d.ts +100 -0
  136. package/dist/app/tabs-controller.js +885 -0
  137. package/dist/app/terminal-controller.d.ts +40 -0
  138. package/dist/app/terminal-controller.js +135 -0
  139. package/dist/app/terminal-edit-shortcuts.d.ts +23 -0
  140. package/dist/app/terminal-edit-shortcuts.js +138 -0
  141. package/dist/app/terminal-output-buffer.d.ts +20 -0
  142. package/dist/app/terminal-output-buffer.js +52 -0
  143. package/dist/app/toast-controller.d.ts +13 -0
  144. package/dist/app/toast-controller.js +40 -0
  145. package/dist/app/toast-renderer.d.ts +9 -0
  146. package/dist/app/toast-renderer.js +79 -0
  147. package/dist/app/todo-model.d.ts +22 -0
  148. package/dist/app/todo-model.js +179 -0
  149. package/dist/app/todo-widget-controller.d.ts +21 -0
  150. package/dist/app/todo-widget-controller.js +59 -0
  151. package/dist/app/tool-block-renderer.d.ts +26 -0
  152. package/dist/app/tool-block-renderer.js +439 -0
  153. package/dist/app/types.d.ts +550 -0
  154. package/dist/app/types.js +1 -0
  155. package/dist/app/update.d.ts +36 -0
  156. package/dist/app/update.js +315 -0
  157. package/dist/app/voice-controller.d.ts +52 -0
  158. package/dist/app/voice-controller.js +600 -0
  159. package/dist/app/workspace-actions-controller.d.ts +40 -0
  160. package/dist/app/workspace-actions-controller.js +215 -0
  161. package/dist/app/workspace-undo.d.ts +44 -0
  162. package/dist/app/workspace-undo.js +215 -0
  163. package/dist/config.d.ts +62 -0
  164. package/dist/config.js +527 -0
  165. package/dist/context-progress-bar.d.ts +17 -0
  166. package/dist/context-progress-bar.js +48 -0
  167. package/dist/default-pix-config.d.ts +1 -0
  168. package/dist/default-pix-config.js +375 -0
  169. package/dist/fuzzy.d.ts +23 -0
  170. package/dist/fuzzy.js +165 -0
  171. package/dist/input-editor-files.d.ts +15 -0
  172. package/dist/input-editor-files.js +62 -0
  173. package/dist/input-editor.d.ts +186 -0
  174. package/dist/input-editor.js +835 -0
  175. package/dist/main.d.ts +1 -0
  176. package/dist/main.js +12 -0
  177. package/dist/markdown-format.d.ts +22 -0
  178. package/dist/markdown-format.js +542 -0
  179. package/dist/sdk.d.ts +3 -0
  180. package/dist/sdk.js +1 -0
  181. package/dist/syntax-highlight.d.ts +22 -0
  182. package/dist/syntax-highlight.js +528 -0
  183. package/dist/terminal-width.d.ts +6 -0
  184. package/dist/terminal-width.js +245 -0
  185. package/dist/theme.d.ts +56 -0
  186. package/dist/theme.js +118 -0
  187. package/dist/tool-renderers/apply-patch.d.ts +2 -0
  188. package/dist/tool-renderers/apply-patch.js +36 -0
  189. package/dist/tool-renderers/ast.d.ts +2 -0
  190. package/dist/tool-renderers/ast.js +5 -0
  191. package/dist/tool-renderers/compress.d.ts +2 -0
  192. package/dist/tool-renderers/compress.js +126 -0
  193. package/dist/tool-renderers/index.d.ts +3 -0
  194. package/dist/tool-renderers/index.js +44 -0
  195. package/dist/tool-renderers/question.d.ts +2 -0
  196. package/dist/tool-renderers/question.js +88 -0
  197. package/dist/tool-renderers/read.d.ts +2 -0
  198. package/dist/tool-renderers/read.js +36 -0
  199. package/dist/tool-renderers/repo.d.ts +2 -0
  200. package/dist/tool-renderers/repo.js +13 -0
  201. package/dist/tool-renderers/shell.d.ts +3 -0
  202. package/dist/tool-renderers/shell.js +27 -0
  203. package/dist/tool-renderers/skill.d.ts +2 -0
  204. package/dist/tool-renderers/skill.js +132 -0
  205. package/dist/tool-renderers/subagents.d.ts +2 -0
  206. package/dist/tool-renderers/subagents.js +51 -0
  207. package/dist/tool-renderers/todo.d.ts +2 -0
  208. package/dist/tool-renderers/todo.js +9 -0
  209. package/dist/tool-renderers/types.d.ts +42 -0
  210. package/dist/tool-renderers/types.js +1 -0
  211. package/dist/tool-renderers/utils.d.ts +31 -0
  212. package/dist/tool-renderers/utils.js +230 -0
  213. package/dist/tool-renderers/web.d.ts +3 -0
  214. package/dist/tool-renderers/web.js +9 -0
  215. package/dist/tool-renderers/write.d.ts +2 -0
  216. package/dist/tool-renderers/write.js +42 -0
  217. package/dist/ui.d.ts +56 -0
  218. package/dist/ui.js +94 -0
  219. package/docs/release.md +81 -0
  220. package/extensions/question/contract.ts +100 -0
  221. package/extensions/question/index.ts +34 -0
  222. package/extensions/question/render.ts +28 -0
  223. package/extensions/question/result.ts +86 -0
  224. package/extensions/question/tool-description.ts +11 -0
  225. package/extensions/question/tui.ts +629 -0
  226. package/extensions/question/types.ts +123 -0
  227. package/extensions/session-title/config.ts +169 -0
  228. package/extensions/session-title/index.ts +459 -0
  229. package/extensions/terminal-bell/index.ts +315 -0
  230. package/external/pi-tools-suite/README.md +242 -0
  231. package/external/pi-tools-suite/index.ts +1 -0
  232. package/external/pi-tools-suite/licenses/ollama-pi-web-search.MIT +21 -0
  233. package/external/pi-tools-suite/licenses/opencode-mystatus-MIT.txt +21 -0
  234. package/external/pi-tools-suite/package.json +53 -0
  235. package/external/pi-tools-suite/src/antigravity-auth/auth-store.ts +194 -0
  236. package/external/pi-tools-suite/src/antigravity-auth/commands.ts +80 -0
  237. package/external/pi-tools-suite/src/antigravity-auth/constants.ts +26 -0
  238. package/external/pi-tools-suite/src/antigravity-auth/headers.ts +20 -0
  239. package/external/pi-tools-suite/src/antigravity-auth/index.ts +104 -0
  240. package/external/pi-tools-suite/src/antigravity-auth/models.ts +86 -0
  241. package/external/pi-tools-suite/src/antigravity-auth/oauth.ts +305 -0
  242. package/external/pi-tools-suite/src/antigravity-auth/payload.ts +423 -0
  243. package/external/pi-tools-suite/src/antigravity-auth/status.ts +78 -0
  244. package/external/pi-tools-suite/src/antigravity-auth/stream.ts +302 -0
  245. package/external/pi-tools-suite/src/antigravity-auth/types.ts +113 -0
  246. package/external/pi-tools-suite/src/ast-grep/index.ts +6 -0
  247. package/external/pi-tools-suite/src/ast-grep/render.ts +70 -0
  248. package/external/pi-tools-suite/src/ast-grep/schema.ts +109 -0
  249. package/external/pi-tools-suite/src/ast-grep/tool.ts +345 -0
  250. package/external/pi-tools-suite/src/ast-grep/types.ts +55 -0
  251. package/external/pi-tools-suite/src/ast-grep/utils.ts +65 -0
  252. package/external/pi-tools-suite/src/async-subagents/async-subagents.sample.jsonc +222 -0
  253. package/external/pi-tools-suite/src/async-subagents/commands.ts +518 -0
  254. package/external/pi-tools-suite/src/async-subagents/constants.ts +11 -0
  255. package/external/pi-tools-suite/src/async-subagents/core/agent-strategy.ts +74 -0
  256. package/external/pi-tools-suite/src/async-subagents/core/attachment-bridge.ts +133 -0
  257. package/external/pi-tools-suite/src/async-subagents/core/cleanup.ts +66 -0
  258. package/external/pi-tools-suite/src/async-subagents/core/concurrency.ts +90 -0
  259. package/external/pi-tools-suite/src/async-subagents/core/config.ts +819 -0
  260. package/external/pi-tools-suite/src/async-subagents/core/log-limits.ts +166 -0
  261. package/external/pi-tools-suite/src/async-subagents/core/model-fallback.ts +133 -0
  262. package/external/pi-tools-suite/src/async-subagents/core/paths.ts +47 -0
  263. package/external/pi-tools-suite/src/async-subagents/core/pi-invocation.ts +35 -0
  264. package/external/pi-tools-suite/src/async-subagents/core/presets.ts +67 -0
  265. package/external/pi-tools-suite/src/async-subagents/core/process.ts +15 -0
  266. package/external/pi-tools-suite/src/async-subagents/core/prompt.ts +66 -0
  267. package/external/pi-tools-suite/src/async-subagents/core/registry.ts +224 -0
  268. package/external/pi-tools-suite/src/async-subagents/core/retry.ts +191 -0
  269. package/external/pi-tools-suite/src/async-subagents/core/routing.ts +259 -0
  270. package/external/pi-tools-suite/src/async-subagents/core/sessions.ts +138 -0
  271. package/external/pi-tools-suite/src/async-subagents/core/spawn.ts +688 -0
  272. package/external/pi-tools-suite/src/async-subagents/core/state.ts +281 -0
  273. package/external/pi-tools-suite/src/async-subagents/core/stop.ts +131 -0
  274. package/external/pi-tools-suite/src/async-subagents/core/structured-result.ts +237 -0
  275. package/external/pi-tools-suite/src/async-subagents/core/tool-guard.ts +34 -0
  276. package/external/pi-tools-suite/src/async-subagents/core/types.ts +150 -0
  277. package/external/pi-tools-suite/src/async-subagents/core/ultrawork-auto.ts +184 -0
  278. package/external/pi-tools-suite/src/async-subagents/core/utils.ts +11 -0
  279. package/external/pi-tools-suite/src/async-subagents/format.ts +41 -0
  280. package/external/pi-tools-suite/src/async-subagents/index.ts +422 -0
  281. package/external/pi-tools-suite/src/async-subagents/lib.ts +88 -0
  282. package/external/pi-tools-suite/src/async-subagents/live.ts +10 -0
  283. package/external/pi-tools-suite/src/async-subagents/polling.ts +83 -0
  284. package/external/pi-tools-suite/src/async-subagents/render.ts +230 -0
  285. package/external/pi-tools-suite/src/async-subagents/subagent-overlay.ts +77 -0
  286. package/external/pi-tools-suite/src/async-subagents/tasks.ts +120 -0
  287. package/external/pi-tools-suite/src/async-subagents/tools/cleanup.ts +99 -0
  288. package/external/pi-tools-suite/src/async-subagents/tools/result.ts +179 -0
  289. package/external/pi-tools-suite/src/async-subagents/tools/spawn.ts +372 -0
  290. package/external/pi-tools-suite/src/async-subagents/tools/status.ts +60 -0
  291. package/external/pi-tools-suite/src/async-subagents/tools/stop.ts +79 -0
  292. package/external/pi-tools-suite/src/async-subagents/tools/subagents.ts +152 -0
  293. package/external/pi-tools-suite/src/async-subagents/tools/wait.ts +67 -0
  294. package/external/pi-tools-suite/src/async-subagents/types.ts +45 -0
  295. package/external/pi-tools-suite/src/async-subagents/ui.ts +5 -0
  296. package/external/pi-tools-suite/src/compress/commands.ts +440 -0
  297. package/external/pi-tools-suite/src/compress/compress-tool.ts +368 -0
  298. package/external/pi-tools-suite/src/compress/compression-blocks.ts +524 -0
  299. package/external/pi-tools-suite/src/compress/config.ts +310 -0
  300. package/external/pi-tools-suite/src/compress/dcp-tui-filter.ts +498 -0
  301. package/external/pi-tools-suite/src/compress/index.ts +397 -0
  302. package/external/pi-tools-suite/src/compress/prompts.ts +269 -0
  303. package/external/pi-tools-suite/src/compress/pruner-candidates.ts +176 -0
  304. package/external/pi-tools-suite/src/compress/pruner-compression-blocks.ts +260 -0
  305. package/external/pi-tools-suite/src/compress/pruner-message-ids.ts +147 -0
  306. package/external/pi-tools-suite/src/compress/pruner-metadata.ts +268 -0
  307. package/external/pi-tools-suite/src/compress/pruner-nudge.ts +315 -0
  308. package/external/pi-tools-suite/src/compress/pruner-tools.ts +263 -0
  309. package/external/pi-tools-suite/src/compress/pruner-types.ts +25 -0
  310. package/external/pi-tools-suite/src/compress/pruner.ts +92 -0
  311. package/external/pi-tools-suite/src/compress/state.ts +486 -0
  312. package/external/pi-tools-suite/src/compress/ui.ts +308 -0
  313. package/external/pi-tools-suite/src/config.ts +176 -0
  314. package/external/pi-tools-suite/src/context-usage.ts +31 -0
  315. package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +355 -0
  316. package/external/pi-tools-suite/src/index.ts +46 -0
  317. package/external/pi-tools-suite/src/lib/lsp.ts +62 -0
  318. package/external/pi-tools-suite/src/lib/project.ts +42 -0
  319. package/external/pi-tools-suite/src/lib/tool-args.ts +137 -0
  320. package/external/pi-tools-suite/src/lsp/_shared/config.ts +156 -0
  321. package/external/pi-tools-suite/src/lsp/_shared/glob.ts +60 -0
  322. package/external/pi-tools-suite/src/lsp/_shared/output.ts +102 -0
  323. package/external/pi-tools-suite/src/lsp/_shared/paths.ts +138 -0
  324. package/external/pi-tools-suite/src/lsp/_shared/runner.ts +64 -0
  325. package/external/pi-tools-suite/src/lsp/_shared/template.ts +23 -0
  326. package/external/pi-tools-suite/src/lsp/_shared/trust.ts +116 -0
  327. package/external/pi-tools-suite/src/lsp/_shared/types.ts +98 -0
  328. package/external/pi-tools-suite/src/lsp/async.ts +29 -0
  329. package/external/pi-tools-suite/src/lsp/child-process.ts +81 -0
  330. package/external/pi-tools-suite/src/lsp/client.ts +340 -0
  331. package/external/pi-tools-suite/src/lsp/constants.ts +9 -0
  332. package/external/pi-tools-suite/src/lsp/diagnostics-store.ts +64 -0
  333. package/external/pi-tools-suite/src/lsp/documents.ts +24 -0
  334. package/external/pi-tools-suite/src/lsp/index.ts +31 -0
  335. package/external/pi-tools-suite/src/lsp/lsp-utils.ts +37 -0
  336. package/external/pi-tools-suite/src/lsp/manager.ts +190 -0
  337. package/external/pi-tools-suite/src/lsp/mutation-events.ts +78 -0
  338. package/external/pi-tools-suite/src/lsp/renderer.ts +1 -0
  339. package/external/pi-tools-suite/src/lsp/tool-result.ts +6 -0
  340. package/external/pi-tools-suite/src/lsp/tsserver.ts +107 -0
  341. package/external/pi-tools-suite/src/lsp/types.ts +15 -0
  342. package/external/pi-tools-suite/src/model-tools/apply-patch.ts +590 -0
  343. package/external/pi-tools-suite/src/model-tools/index.ts +430 -0
  344. package/external/pi-tools-suite/src/model-tools/path-utils.ts +6 -0
  345. package/external/pi-tools-suite/src/model-tools/tool-args.ts +11 -0
  346. package/external/pi-tools-suite/src/prompt-commands/index.ts +349 -0
  347. package/external/pi-tools-suite/src/repo-discovery/index.ts +384 -0
  348. package/external/pi-tools-suite/src/repo-discovery/project.ts +7 -0
  349. package/external/pi-tools-suite/src/startup-section.ts +13 -0
  350. package/external/pi-tools-suite/src/terminal-bell/index.ts +309 -0
  351. package/external/pi-tools-suite/src/todo/index.ts +201 -0
  352. package/external/pi-tools-suite/src/todo/state/auto-clear.ts +13 -0
  353. package/external/pi-tools-suite/src/todo/state/invariants.ts +21 -0
  354. package/external/pi-tools-suite/src/todo/state/persistence.ts +94 -0
  355. package/external/pi-tools-suite/src/todo/state/replay.ts +38 -0
  356. package/external/pi-tools-suite/src/todo/state/selectors.ts +49 -0
  357. package/external/pi-tools-suite/src/todo/state/state-reducer.ts +362 -0
  358. package/external/pi-tools-suite/src/todo/state/state.ts +18 -0
  359. package/external/pi-tools-suite/src/todo/state/store.ts +52 -0
  360. package/external/pi-tools-suite/src/todo/state/task-graph.ts +57 -0
  361. package/external/pi-tools-suite/src/todo/todo.ts +487 -0
  362. package/external/pi-tools-suite/src/todo/tool/response-envelope.ts +143 -0
  363. package/external/pi-tools-suite/src/todo/tool/types.ts +188 -0
  364. package/external/pi-tools-suite/src/todo/view/format.ts +18 -0
  365. package/external/pi-tools-suite/src/todo/view/labels.ts +13 -0
  366. package/external/pi-tools-suite/src/tool-descriptions.ts +369 -0
  367. package/external/pi-tools-suite/src/usage/index.ts +152 -0
  368. package/external/pi-tools-suite/src/usage/lib/copilot.ts +535 -0
  369. package/external/pi-tools-suite/src/usage/lib/google.ts +478 -0
  370. package/external/pi-tools-suite/src/usage/lib/openai.ts +268 -0
  371. package/external/pi-tools-suite/src/usage/lib/types.ts +114 -0
  372. package/external/pi-tools-suite/src/usage/lib/utils.ts +134 -0
  373. package/external/pi-tools-suite/src/usage/lib/zhipu.ts +228 -0
  374. package/external/pi-tools-suite/src/web-search/index.ts +397 -0
  375. package/package.json +89 -0
  376. package/skills/context7/SKILL.md +69 -0
  377. package/skills/context7/scripts/context7.sh +73 -0
  378. package/skills/handoff/SKILL.md +15 -0
  379. package/skills/pdf/LICENSE.txt +30 -0
  380. package/skills/pdf/SKILL.md +314 -0
  381. package/skills/pdf/forms.md +294 -0
  382. package/skills/pdf/reference.md +612 -0
  383. package/skills/pdf/scripts/check_bounding_boxes.py +65 -0
  384. package/skills/pdf/scripts/check_fillable_fields.py +11 -0
  385. package/skills/pdf/scripts/convert_pdf_to_images.py +33 -0
  386. package/skills/pdf/scripts/create_validation_image.py +37 -0
  387. package/skills/pdf/scripts/extract_form_field_info.py +122 -0
  388. package/skills/pdf/scripts/extract_form_structure.py +115 -0
  389. package/skills/pdf/scripts/fill_fillable_fields.py +98 -0
  390. package/skills/pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
  391. package/skills/playwright-cli/SKILL.md +388 -0
  392. package/skills/playwright-cli/references/element-attributes.md +23 -0
  393. package/skills/playwright-cli/references/playwright-tests.md +39 -0
  394. package/skills/playwright-cli/references/request-mocking.md +87 -0
  395. package/skills/playwright-cli/references/running-code.md +241 -0
  396. package/skills/playwright-cli/references/session-management.md +225 -0
  397. package/skills/playwright-cli/references/spec-driven-testing.md +305 -0
  398. package/skills/playwright-cli/references/storage-state.md +275 -0
  399. package/skills/playwright-cli/references/test-generation.md +134 -0
  400. package/skills/playwright-cli/references/tracing.md +139 -0
  401. package/skills/playwright-cli/references/video-recording.md +143 -0
  402. package/skills/simplify/SKILL.md +51 -0
  403. package/skills/skill-creator/LICENSE.txt +202 -0
  404. package/skills/skill-creator/SKILL.md +485 -0
  405. package/skills/skill-creator/agents/analyzer.md +274 -0
  406. package/skills/skill-creator/agents/comparator.md +202 -0
  407. package/skills/skill-creator/agents/grader.md +223 -0
  408. package/skills/skill-creator/assets/eval_review.html +146 -0
  409. package/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  410. package/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  411. package/skills/skill-creator/references/schemas.md +430 -0
  412. package/skills/skill-creator/scripts/__init__.py +0 -0
  413. package/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  414. package/skills/skill-creator/scripts/generate_report.py +326 -0
  415. package/skills/skill-creator/scripts/improve_description.py +247 -0
  416. package/skills/skill-creator/scripts/package_skill.py +136 -0
  417. package/skills/skill-creator/scripts/quick_validate.py +103 -0
  418. package/skills/skill-creator/scripts/run_eval.py +310 -0
  419. package/skills/skill-creator/scripts/run_loop.py +328 -0
  420. package/skills/skill-creator/scripts/utils.py +47 -0
@@ -0,0 +1,40 @@
1
+ import type { AgentSessionRuntime } from "@earendil-works/pi-coding-agent";
2
+ export type AppTerminalControllerHost = {
3
+ isRunning(): boolean;
4
+ setRunning(running: boolean): void;
5
+ runtime(): AgentSessionRuntime | undefined;
6
+ saveInputStateForQuit(): Promise<void>;
7
+ disposeInactiveRuntimesForQuit(): Promise<void>;
8
+ render(): void;
9
+ handleInputChunk(chunk: Buffer): void;
10
+ closeSdkMenuForStop(): void;
11
+ clearToastTimers(): void;
12
+ stopBlinking(): void;
13
+ stopSubagentsPolling(): void;
14
+ stopModelUsagePolling(): void;
15
+ stopVoiceInput(): Promise<void>;
16
+ stopShellCommand(): void;
17
+ unsubscribeSession(): void;
18
+ clearExtensionWidgets(): void;
19
+ resetRenderOutputBuffer(): void;
20
+ };
21
+ export declare class AppTerminalController {
22
+ private readonly host;
23
+ private terminalEnabled;
24
+ private interactiveSuspended;
25
+ private stopPromise;
26
+ constructor(host: AppTerminalControllerHost);
27
+ isSuspended(): boolean;
28
+ enableTerminal(): void;
29
+ stop(): Promise<void>;
30
+ disposeRuntimeForQuit(runtime: AgentSessionRuntime): Promise<void>;
31
+ disposeRuntime(runtime: AgentSessionRuntime): Promise<void>;
32
+ runWithInteractiveTerminal<T>(callback: () => Promise<T>): Promise<T>;
33
+ private readonly restoreTerminal;
34
+ private suspendForInteractiveProcess;
35
+ private resumeAfterInteractiveProcess;
36
+ private stopInternal;
37
+ private scheduleForcedProcessExit;
38
+ private readonly onResize;
39
+ private readonly onInputData;
40
+ }
@@ -0,0 +1,135 @@
1
+ import { ANSI_RESET } from "../theme.js";
2
+ import { DISABLE_BRACKETED_PASTE, DISABLE_TERMINAL_KEY_REPORTING, DISABLE_TERMINAL_WRAP, CLEAR_TERMINAL, ENABLE_BRACKETED_PASTE, ENABLE_TERMINAL_KEY_REPORTING, ENABLE_TERMINAL_WRAP, HIDE_CURSOR, RUNTIME_DISPOSE_GRACE_MS, SHOW_CURSOR, } from "./constants.js";
3
+ export class AppTerminalController {
4
+ host;
5
+ terminalEnabled = false;
6
+ interactiveSuspended = false;
7
+ stopPromise;
8
+ constructor(host) {
9
+ this.host = host;
10
+ }
11
+ isSuspended() {
12
+ return this.interactiveSuspended;
13
+ }
14
+ enableTerminal() {
15
+ if (this.terminalEnabled)
16
+ return;
17
+ this.terminalEnabled = true;
18
+ process.stdin.setRawMode(true);
19
+ process.stdin.resume();
20
+ process.stdin.on("data", this.onInputData);
21
+ process.stdout.on("resize", this.onResize);
22
+ process.stdout.write(`${ANSI_RESET}${CLEAR_TERMINAL}\x1b[?1049h${CLEAR_TERMINAL}${ENABLE_TERMINAL_KEY_REPORTING}${ENABLE_BRACKETED_PASTE}${DISABLE_TERMINAL_WRAP}\x1b[?1002h\x1b[?1006h${HIDE_CURSOR}`);
23
+ process.on("exit", this.restoreTerminal);
24
+ }
25
+ async stop() {
26
+ if (this.stopPromise) {
27
+ await this.stopPromise;
28
+ return;
29
+ }
30
+ this.stopPromise = this.stopInternal();
31
+ await this.stopPromise;
32
+ }
33
+ async disposeRuntimeForQuit(runtime) {
34
+ let timeout;
35
+ const dispose = runtime.dispose().then(() => "disposed", () => "failed");
36
+ const timeoutPromise = new Promise((resolveTimeout) => {
37
+ timeout = setTimeout(() => resolveTimeout("timeout"), RUNTIME_DISPOSE_GRACE_MS);
38
+ });
39
+ const result = await Promise.race([dispose, timeoutPromise]);
40
+ if (timeout)
41
+ clearTimeout(timeout);
42
+ if (result !== "disposed")
43
+ runtime.session.dispose();
44
+ }
45
+ async disposeRuntime(runtime) {
46
+ try {
47
+ await runtime.dispose();
48
+ }
49
+ catch {
50
+ // Best-effort tab cleanup: extension shutdown errors are surfaced through
51
+ // the SDK onError path, and tab switching should not produce unhandled
52
+ // promise rejections if a disposed runtime is already half-torn down.
53
+ }
54
+ }
55
+ async runWithInteractiveTerminal(callback) {
56
+ this.suspendForInteractiveProcess();
57
+ try {
58
+ return await callback();
59
+ }
60
+ finally {
61
+ this.resumeAfterInteractiveProcess();
62
+ }
63
+ }
64
+ restoreTerminal = () => {
65
+ if (!this.terminalEnabled)
66
+ return;
67
+ this.terminalEnabled = false;
68
+ this.interactiveSuspended = false;
69
+ process.stdout.write(`${ANSI_RESET}${DISABLE_TERMINAL_KEY_REPORTING}${DISABLE_BRACKETED_PASTE}${ENABLE_TERMINAL_WRAP}\x1b[?1006l\x1b[?1002l\x1b[?1049l${SHOW_CURSOR}`);
70
+ if (process.stdin.isTTY)
71
+ process.stdin.setRawMode(false);
72
+ };
73
+ suspendForInteractiveProcess() {
74
+ if (!this.terminalEnabled || this.interactiveSuspended)
75
+ return;
76
+ this.interactiveSuspended = true;
77
+ process.stdin.off("data", this.onInputData);
78
+ process.stdin.pause();
79
+ process.stdout.off("resize", this.onResize);
80
+ process.stdout.write(`${ANSI_RESET}${DISABLE_TERMINAL_KEY_REPORTING}${DISABLE_BRACKETED_PASTE}${ENABLE_TERMINAL_WRAP}\x1b[?1006l\x1b[?1002l\x1b[?1049l${SHOW_CURSOR}`);
81
+ if (process.stdin.isTTY)
82
+ process.stdin.setRawMode(false);
83
+ }
84
+ resumeAfterInteractiveProcess() {
85
+ if (!this.terminalEnabled || !this.interactiveSuspended)
86
+ return;
87
+ this.interactiveSuspended = false;
88
+ if (process.stdin.isTTY)
89
+ process.stdin.setRawMode(true);
90
+ process.stdin.resume();
91
+ process.stdin.on("data", this.onInputData);
92
+ process.stdout.on("resize", this.onResize);
93
+ this.host.resetRenderOutputBuffer();
94
+ process.stdout.write(`${ANSI_RESET}${CLEAR_TERMINAL}\x1b[?1049h${CLEAR_TERMINAL}${ENABLE_TERMINAL_KEY_REPORTING}${ENABLE_BRACKETED_PASTE}${DISABLE_TERMINAL_WRAP}\x1b[?1002h\x1b[?1006h${HIDE_CURSOR}`);
95
+ this.host.render();
96
+ }
97
+ async stopInternal() {
98
+ if (!this.host.isRunning())
99
+ return;
100
+ this.host.setRunning(false);
101
+ this.host.closeSdkMenuForStop();
102
+ this.host.clearToastTimers();
103
+ this.host.stopBlinking();
104
+ this.host.stopSubagentsPolling();
105
+ this.host.stopModelUsagePolling();
106
+ await this.host.stopVoiceInput();
107
+ this.host.stopShellCommand();
108
+ process.stdin.off("data", this.onInputData);
109
+ process.stdin.pause();
110
+ process.stdout.off("resize", this.onResize);
111
+ process.off("exit", this.restoreTerminal);
112
+ this.host.unsubscribeSession();
113
+ this.host.clearExtensionWidgets();
114
+ await this.host.saveInputStateForQuit();
115
+ this.restoreTerminal();
116
+ this.scheduleForcedProcessExit();
117
+ await this.host.disposeInactiveRuntimesForQuit();
118
+ const runtime = this.host.runtime();
119
+ if (runtime)
120
+ await this.disposeRuntimeForQuit(runtime);
121
+ }
122
+ scheduleForcedProcessExit() {
123
+ const exitCode = typeof process.exitCode === "number" ? process.exitCode : 0;
124
+ const timer = setTimeout(() => {
125
+ process.exit(exitCode);
126
+ }, RUNTIME_DISPOSE_GRACE_MS);
127
+ timer.unref();
128
+ }
129
+ onResize = () => {
130
+ this.host.render();
131
+ };
132
+ onInputData = (chunk) => {
133
+ this.host.handleInputChunk(chunk);
134
+ };
135
+ }
@@ -0,0 +1,23 @@
1
+ export type TerminalEditShortcut = "undo" | "redo";
2
+ export type TerminalEditShortcutSequenceResult = {
3
+ readonly kind: "shortcut";
4
+ readonly shortcut: TerminalEditShortcut;
5
+ readonly length: number;
6
+ } | {
7
+ readonly kind: "ignore";
8
+ readonly length: number;
9
+ } | {
10
+ readonly kind: "pending";
11
+ } | {
12
+ readonly kind: "none";
13
+ };
14
+ export declare function parseTerminalEditShortcutSequence(input: string): TerminalEditShortcutSequenceResult;
15
+ export declare function parseTerminalInterruptSequence(input: string): {
16
+ readonly kind: "interrupt";
17
+ readonly length: number;
18
+ } | {
19
+ readonly kind: "pending";
20
+ } | {
21
+ readonly kind: "none";
22
+ };
23
+ export declare function terminalEditShortcutForControlChar(char: string, shiftPressed: boolean): TerminalEditShortcut | undefined;
@@ -0,0 +1,138 @@
1
+ const SHIFT_MODIFIER_FLAG = 1;
2
+ const CONTROL_MODIFIER_FLAG = 4;
3
+ const COMMAND_MODIFIER_FLAG = 8;
4
+ const LOCK_MODIFIER_MASK = 64 + 128;
5
+ const KEY_CODE_C = 99;
6
+ const KEY_CODE_Y = 121;
7
+ const KEY_CODE_Z = 122;
8
+ const CYRILLIC_SMALL_ES_CODE = 1089;
9
+ const CYRILLIC_CAPITAL_ES_CODE = 1057;
10
+ const KITTY_CSI_U_SEQUENCE = /^\x1b\[(\d+)(?::(\d*))?(?::(\d+))?(?:;(\d+))?(?::(\d+))?u/;
11
+ const XTERM_MODIFY_OTHER_KEYS_SEQUENCE = /^\x1b\[27;(\d+);(\d+)~/;
12
+ export function parseTerminalEditShortcutSequence(input) {
13
+ const kitty = parseKittyCsiUSequence(input);
14
+ if (kitty)
15
+ return terminalEditShortcutResult(kitty);
16
+ const xterm = parseXtermModifyOtherKeysSequence(input);
17
+ if (xterm)
18
+ return terminalEditShortcutResult(xterm);
19
+ if (isPotentialEditShortcutPrefix(input))
20
+ return { kind: "pending" };
21
+ return { kind: "none" };
22
+ }
23
+ export function parseTerminalInterruptSequence(input) {
24
+ const kitty = parseKittyCsiUSequence(input);
25
+ if (kitty && terminalKeyIsControlC(kitty))
26
+ return { kind: "interrupt", length: kitty.length };
27
+ const xterm = parseXtermModifyOtherKeysSequence(input);
28
+ if (xterm && terminalKeyIsControlC(xterm))
29
+ return { kind: "interrupt", length: xterm.length };
30
+ if (isPotentialInterruptPrefix(input))
31
+ return { kind: "pending" };
32
+ return { kind: "none" };
33
+ }
34
+ export function terminalEditShortcutForControlChar(char, shiftPressed) {
35
+ if (char === "\u001a")
36
+ return shiftPressed ? "redo" : "undo";
37
+ if (char === "\u0019")
38
+ return "redo";
39
+ return undefined;
40
+ }
41
+ function parseKittyCsiUSequence(input) {
42
+ const match = KITTY_CSI_U_SEQUENCE.exec(input);
43
+ if (!match)
44
+ return undefined;
45
+ const codepoint = Number.parseInt(match[1] ?? "", 10);
46
+ const baseLayoutKey = match[3] ? Number.parseInt(match[3], 10) : undefined;
47
+ const modifierValue = match[4] ? Number.parseInt(match[4], 10) : 1;
48
+ const eventType = match[5] ? Number.parseInt(match[5], 10) : undefined;
49
+ if (!Number.isFinite(codepoint) || !Number.isFinite(modifierValue))
50
+ return undefined;
51
+ return {
52
+ codepoint,
53
+ baseLayoutKey: Number.isFinite(baseLayoutKey) ? baseLayoutKey : undefined,
54
+ modifier: modifierValue - 1,
55
+ eventType: Number.isFinite(eventType) ? eventType : undefined,
56
+ length: match[0].length,
57
+ };
58
+ }
59
+ function parseXtermModifyOtherKeysSequence(input) {
60
+ const match = XTERM_MODIFY_OTHER_KEYS_SEQUENCE.exec(input);
61
+ if (!match)
62
+ return undefined;
63
+ const modifierValue = Number.parseInt(match[1] ?? "", 10);
64
+ const codepoint = Number.parseInt(match[2] ?? "", 10);
65
+ if (!Number.isFinite(codepoint) || !Number.isFinite(modifierValue))
66
+ return undefined;
67
+ return {
68
+ codepoint,
69
+ baseLayoutKey: undefined,
70
+ modifier: modifierValue - 1,
71
+ eventType: undefined,
72
+ length: match[0].length,
73
+ };
74
+ }
75
+ function terminalEditShortcutResult(key) {
76
+ const effectiveModifier = key.modifier & ~LOCK_MODIFIER_MASK;
77
+ if ((effectiveModifier & COMMAND_MODIFIER_FLAG) === 0)
78
+ return { kind: "none" };
79
+ // Kitty keyboard protocol flag 2 appends event types. Press/repeat are action-worthy;
80
+ // release must be swallowed so the release packet is not inserted into the editor.
81
+ if (key.eventType === 3)
82
+ return { kind: "ignore", length: key.length };
83
+ const shortcut = terminalEditShortcutForKey(key, effectiveModifier);
84
+ if (!shortcut)
85
+ return { kind: "ignore", length: key.length };
86
+ return { kind: "shortcut", shortcut, length: key.length };
87
+ }
88
+ function terminalKeyIsControlC(key) {
89
+ const effectiveModifier = key.modifier & ~LOCK_MODIFIER_MASK;
90
+ if ((effectiveModifier & CONTROL_MODIFIER_FLAG) === 0)
91
+ return false;
92
+ return interruptCodepointIsC(key.codepoint) || interruptCodepointIsC(key.baseLayoutKey ?? key.codepoint);
93
+ }
94
+ function interruptCodepointIsC(codepoint) {
95
+ const normalized = normalizeLetterCodepoint(codepoint);
96
+ return normalized === KEY_CODE_C || normalized === CYRILLIC_SMALL_ES_CODE || normalized === CYRILLIC_CAPITAL_ES_CODE;
97
+ }
98
+ function terminalEditShortcutForKey(key, effectiveModifier) {
99
+ const codepoint = editShortcutCodepoint(key);
100
+ if (codepoint === KEY_CODE_Y)
101
+ return "redo";
102
+ if (codepoint !== KEY_CODE_Z)
103
+ return undefined;
104
+ return (effectiveModifier & SHIFT_MODIFIER_FLAG) !== 0 ? "redo" : "undo";
105
+ }
106
+ function editShortcutCodepoint(key) {
107
+ const primary = normalizeLetterCodepoint(key.codepoint);
108
+ if (primary === KEY_CODE_Z || primary === KEY_CODE_Y)
109
+ return primary;
110
+ return normalizeLetterCodepoint(key.baseLayoutKey ?? key.codepoint);
111
+ }
112
+ function normalizeLetterCodepoint(codepoint) {
113
+ if (codepoint >= 65 && codepoint <= 90)
114
+ return codepoint + 32;
115
+ return codepoint;
116
+ }
117
+ function isPotentialEditShortcutPrefix(input) {
118
+ if (!input.startsWith("\x1b["))
119
+ return false;
120
+ if (input.includes("u") || input.includes("~"))
121
+ return false;
122
+ const body = input.slice(2);
123
+ if (!/^[\d:;]*$/.test(body))
124
+ return false;
125
+ const possibleStarts = ["122", "121", "90", "27;"];
126
+ return possibleStarts.some((start) => start.startsWith(body) || body.startsWith(start));
127
+ }
128
+ function isPotentialInterruptPrefix(input) {
129
+ if (!input.startsWith("\x1b["))
130
+ return false;
131
+ if (input.includes("u") || input.includes("~"))
132
+ return false;
133
+ const body = input.slice(2);
134
+ if (!/^[\d:;]*$/.test(body))
135
+ return false;
136
+ const possibleStarts = ["99", "67", "1089", "1057", "27;"];
137
+ return possibleStarts.some((start) => start.startsWith(body) || body.startsWith(start));
138
+ }
@@ -0,0 +1,20 @@
1
+ export declare const DISABLE_TERMINAL_OUTPUT_BUFFER_ENV = "PIX_DISABLE_TERMINAL_OUTPUT_BUFFER";
2
+ export declare const TERMINAL_OUTPUT_BUFFER_ENV = "PIX_TERMINAL_OUTPUT_BUFFER";
3
+ declare const FRAME_REGIONS: readonly ["tabs", "conversation", "inputStatus"];
4
+ export type TerminalOutputFrameRegion = typeof FRAME_REGIONS[number];
5
+ export type TerminalOutputRegion = TerminalOutputFrameRegion | "statusLine";
6
+ export type TerminalOutputFrame = Partial<Record<TerminalOutputFrameRegion, string>>;
7
+ export type TerminalOutputBufferOptions = {
8
+ enabled?: boolean;
9
+ env?: Record<string, string | undefined>;
10
+ };
11
+ export declare class TerminalOutputBuffer {
12
+ private readonly enabled;
13
+ private readonly previousByRegion;
14
+ constructor(options?: TerminalOutputBufferOptions);
15
+ diffFrame(frame: TerminalOutputFrame): string;
16
+ diff(region: TerminalOutputRegion, output: string): string;
17
+ reset(): void;
18
+ }
19
+ export declare function terminalOutputBufferDisabled(env?: Record<string, string | undefined>): boolean;
20
+ export {};
@@ -0,0 +1,52 @@
1
+ export const DISABLE_TERMINAL_OUTPUT_BUFFER_ENV = "PIX_DISABLE_TERMINAL_OUTPUT_BUFFER";
2
+ export const TERMINAL_OUTPUT_BUFFER_ENV = "PIX_TERMINAL_OUTPUT_BUFFER";
3
+ const FRAME_REGIONS = ["tabs", "conversation", "inputStatus"];
4
+ export class TerminalOutputBuffer {
5
+ enabled;
6
+ previousByRegion = new Map();
7
+ constructor(options = {}) {
8
+ this.enabled = options.enabled ?? !terminalOutputBufferDisabled(options.env ?? process.env);
9
+ }
10
+ diffFrame(frame) {
11
+ const outputByRegion = {
12
+ tabs: frame.tabs ?? "",
13
+ conversation: frame.conversation ?? "",
14
+ inputStatus: frame.inputStatus ?? "",
15
+ };
16
+ if (!this.enabled)
17
+ return FRAME_REGIONS.map((region) => outputByRegion[region]).join("");
18
+ const chunks = [];
19
+ for (const region of FRAME_REGIONS) {
20
+ const output = outputByRegion[region];
21
+ if (this.previousByRegion.get(region) === output)
22
+ continue;
23
+ this.previousByRegion.set(region, output);
24
+ if (output.length > 0)
25
+ chunks.push(output);
26
+ }
27
+ return chunks.join("");
28
+ }
29
+ diff(region, output) {
30
+ if (!this.enabled)
31
+ return output;
32
+ if (this.previousByRegion.get(region) === output)
33
+ return "";
34
+ this.previousByRegion.set(region, output);
35
+ return output;
36
+ }
37
+ reset() {
38
+ this.previousByRegion.clear();
39
+ }
40
+ }
41
+ export function terminalOutputBufferDisabled(env = process.env) {
42
+ const disabled = env[DISABLE_TERMINAL_OUTPUT_BUFFER_ENV];
43
+ if (disabled !== undefined)
44
+ return !isFalseEnvValue(disabled);
45
+ const enabled = env[TERMINAL_OUTPUT_BUFFER_ENV];
46
+ if (enabled !== undefined)
47
+ return isFalseEnvValue(enabled);
48
+ return false;
49
+ }
50
+ function isFalseEnvValue(value) {
51
+ return /^(?:0|false|off|no)$/iu.test(value.trim());
52
+ }
@@ -0,0 +1,13 @@
1
+ import { Toast, type ToastKind } from "../ui.js";
2
+ export type AppToastControllerHost = {
3
+ render(): void;
4
+ };
5
+ export declare class AppToastController {
6
+ private readonly host;
7
+ readonly toast: Toast;
8
+ private readonly timers;
9
+ constructor(host: AppToastControllerHost);
10
+ showToast(message: string, kind?: ToastKind): void;
11
+ dismissToast(toastId: number): void;
12
+ clearToastTimers(): void;
13
+ }
@@ -0,0 +1,40 @@
1
+ import { Toast } from "../ui.js";
2
+ import { TOAST_DURATION_MS } from "./constants.js";
3
+ export class AppToastController {
4
+ host;
5
+ toast = new Toast();
6
+ timers = new Map();
7
+ constructor(host) {
8
+ this.host = host;
9
+ }
10
+ showToast(message, kind = "info") {
11
+ const toastId = this.toast.show(message, kind);
12
+ if (kind === "error") {
13
+ this.host.render();
14
+ return;
15
+ }
16
+ const timer = setTimeout(() => {
17
+ this.toast.hide(toastId);
18
+ this.timers.delete(toastId);
19
+ this.host.render();
20
+ }, TOAST_DURATION_MS);
21
+ this.timers.set(toastId, timer);
22
+ timer.unref();
23
+ this.host.render();
24
+ }
25
+ dismissToast(toastId) {
26
+ const timer = this.timers.get(toastId);
27
+ if (timer) {
28
+ clearTimeout(timer);
29
+ this.timers.delete(toastId);
30
+ }
31
+ this.toast.hide(toastId);
32
+ this.host.render();
33
+ }
34
+ clearToastTimers() {
35
+ for (const timer of this.timers.values())
36
+ clearTimeout(timer);
37
+ this.timers.clear();
38
+ this.toast.hide();
39
+ }
40
+ }
@@ -0,0 +1,9 @@
1
+ import { type Theme } from "../theme.js";
2
+ import type { ToastEntry } from "../ui.js";
3
+ export type ToastOverlay = {
4
+ id: number;
5
+ row: number;
6
+ text: string;
7
+ output: string;
8
+ };
9
+ export declare function renderToastOverlays(states: readonly ToastEntry[], width: number, maxRows: number, theme: Theme): ToastOverlay[];
@@ -0,0 +1,79 @@
1
+ import { colorLine } from "../theme.js";
2
+ import { stringDisplayWidth, wrapDisplayLine } from "../terminal-width.js";
3
+ import { APP_ICONS } from "./icons.js";
4
+ import { padOrTrimPlain, sanitizeText } from "./render-text.js";
5
+ export function renderToastOverlays(states, width, maxRows, theme) {
6
+ if (maxRows <= 0)
7
+ return [];
8
+ const overlays = [];
9
+ for (const state of [...states].reverse()) {
10
+ if (overlays.length >= maxRows)
11
+ break;
12
+ const icon = toastKindIcon(state.kind);
13
+ const lines = toastMessageLines(state.message, icon, Math.max(1, width - 6));
14
+ const visibleLines = lines.slice(0, Math.max(0, maxRows - overlays.length));
15
+ if (visibleLines.length === 0)
16
+ continue;
17
+ const contentWidth = Math.max(...visibleLines.map((line) => stringDisplayWidth(line)));
18
+ const toastWidth = Math.min(Math.max(12, contentWidth + 2), Math.max(1, width - 4));
19
+ const leftWidth = Math.max(0, width - toastWidth - 2);
20
+ const rightWidth = Math.max(0, width - leftWidth - toastWidth);
21
+ for (const line of visibleLines) {
22
+ const message = ` ${padOrTrimPlain(line, Math.max(0, toastWidth - 2))} `;
23
+ const text = `${" ".repeat(leftWidth)}${padOrTrimPlain(message, toastWidth)}${" ".repeat(rightWidth)}`;
24
+ const output = [
25
+ colorLine("", leftWidth, { background: theme.colors.background }),
26
+ colorLine(message, toastWidth, {
27
+ ...toastKindStyle(state.kind, theme),
28
+ bold: true,
29
+ }),
30
+ colorLine("", rightWidth, { background: theme.colors.background }),
31
+ ].join("");
32
+ overlays.push({ id: state.id, row: overlays.length + 1, text, output });
33
+ }
34
+ }
35
+ return overlays;
36
+ }
37
+ function toastMessageLines(message, icon, maxWidth) {
38
+ const firstPrefix = `${icon} `;
39
+ const continuationPrefix = " ".repeat(stringDisplayWidth(firstPrefix));
40
+ const safeMaxWidth = Math.max(1, maxWidth);
41
+ const safeContinuationPrefix = stringDisplayWidth(continuationPrefix) < safeMaxWidth ? continuationPrefix : "";
42
+ const lines = [];
43
+ const logicalLines = sanitizeText(message).split("\n");
44
+ for (const [index, logicalLine] of logicalLines.entries()) {
45
+ const prefix = index === 0 ? firstPrefix : continuationPrefix;
46
+ const prefixWidth = stringDisplayWidth(prefix);
47
+ const effectivePrefix = prefixWidth < safeMaxWidth ? prefix : "";
48
+ const wrapWidth = Math.max(1, safeMaxWidth - stringDisplayWidth(effectivePrefix));
49
+ const wrappedLines = wrapDisplayLine(logicalLine, wrapWidth);
50
+ for (const [wrappedIndex, wrappedLine] of wrappedLines.entries()) {
51
+ lines.push(`${wrappedIndex === 0 ? effectivePrefix : safeContinuationPrefix}${wrappedLine}`);
52
+ }
53
+ }
54
+ return lines.length > 0 ? lines : [firstPrefix.trimEnd()];
55
+ }
56
+ function toastKindIcon(kind) {
57
+ switch (kind) {
58
+ case "success":
59
+ return APP_ICONS.checkCircle;
60
+ case "error":
61
+ return APP_ICONS.closeCircle;
62
+ case "warning":
63
+ return APP_ICONS.alert;
64
+ case "info":
65
+ return APP_ICONS.info;
66
+ }
67
+ }
68
+ function toastKindStyle(kind, theme) {
69
+ switch (kind) {
70
+ case "success":
71
+ return { foreground: theme.colors.toastForeground, background: theme.colors.toastBackground };
72
+ case "error":
73
+ return { foreground: theme.colors.background, background: theme.colors.error };
74
+ case "warning":
75
+ return { foreground: theme.colors.background, background: theme.colors.warning };
76
+ case "info":
77
+ return { foreground: theme.colors.background, background: theme.colors.info };
78
+ }
79
+ }
@@ -0,0 +1,22 @@
1
+ import type { StyledSegment, TodoAction, TodoDetails, TodoLiveStateEvent, TodoPriority, TodoStatus, TodoTask, TodoTaskLinePart, TodoTaskRow } from "./types.js";
2
+ export declare function isTodoAction(value: unknown): value is TodoAction;
3
+ export declare function isTodoStatus(value: unknown): value is TodoStatus;
4
+ export declare function isTodoPriority(value: unknown): value is TodoPriority;
5
+ export declare function isTodoTask(value: unknown): value is TodoTask;
6
+ export declare function isTodoDetails(value: unknown): value is TodoDetails;
7
+ export declare function isTodoLiveStateEvent(value: unknown): value is TodoLiveStateEvent;
8
+ export declare function todoStatusIcon(status: TodoStatus): string;
9
+ export declare function visibleTodoTasks(details: TodoDetails, showDeleted?: boolean): TodoTask[];
10
+ export declare function hasOpenTodoTasks(details: TodoDetails): boolean;
11
+ export declare function visibleTodoTaskRows(details: TodoDetails, showDeleted?: boolean): TodoTaskRow[];
12
+ export declare function todoTaskLineParts(task: TodoTask, options?: {
13
+ depth?: number;
14
+ }): TodoTaskLinePart[];
15
+ export declare function formatTodoTaskLine(task: TodoTask, options?: {
16
+ depth?: number;
17
+ }): string;
18
+ export declare function todoTaskLineSegments(task: TodoTask, mutedColor: string, options?: {
19
+ depth?: number;
20
+ }): StyledSegment[];
21
+ export declare function shiftSegmentsToSlice(segments: readonly StyledSegment[], start: number, length: number): StyledSegment[];
22
+ export declare function formatTodoPanelStats(tasks: readonly TodoTask[]): string;