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,39 @@
1
+ import { type EventBus, type AgentSessionRuntime, type LoadExtensionsResult } from "@earendil-works/pi-coding-agent";
2
+ import type { AppOptions } from "./types.js";
3
+ export type PiToolsSuiteInstallAction = "installed" | "already-installed" | "existing-kept" | "missing-source";
4
+ export type PiToolsSuiteInstallResult = {
5
+ action: PiToolsSuiteInstallAction;
6
+ sourcePath: string;
7
+ targetPath: string;
8
+ };
9
+ export type PiToolsSuiteInstallOptions = {
10
+ agentDir?: string;
11
+ sourcePath?: string;
12
+ targetPath?: string;
13
+ };
14
+ export type BundledSkillsInstallAction = "installed" | "already-installed" | "missing-source";
15
+ export type BundledSkillsInstallResult = {
16
+ action: BundledSkillsInstallAction;
17
+ sourcePath: string;
18
+ targetPath: string;
19
+ };
20
+ export type BundledSkillsInstallOptions = {
21
+ homeDir?: string;
22
+ sourcePath?: string;
23
+ targetPath?: string;
24
+ };
25
+ export declare function bundledQuestionExtensionPath(): string;
26
+ export declare function bundledSessionTitleExtensionPath(): string;
27
+ export declare function bundledTerminalBellExtensionPath(): string;
28
+ export declare function piToolsSuiteExtensionSourcePath(): string;
29
+ export declare function piToolsSuiteExtensionInstallPath(agentDir?: string): string;
30
+ export declare function bundledSkillsSourcePath(): string;
31
+ export declare function bundledSkillsInstallPath(homeDir?: string): string;
32
+ export declare function ensurePiToolsSuiteExtensionInstalled(options?: PiToolsSuiteInstallOptions): Promise<PiToolsSuiteInstallResult>;
33
+ export declare function ensureBundledSkillsInstalled(options?: BundledSkillsInstallOptions): Promise<BundledSkillsInstallResult>;
34
+ export declare function getBundledExtensionPaths(): string[];
35
+ export declare function prioritizeBundledQuestionExtension(base: LoadExtensionsResult, questionExtensionPath?: string): LoadExtensionsResult;
36
+ export type CreatePixRuntimeOptions = {
37
+ eventBus?: EventBus;
38
+ };
39
+ export declare function createPixRuntime(options: AppOptions, runtimeOptions?: CreatePixRuntimeOptions): Promise<AgentSessionRuntime>;
@@ -0,0 +1,195 @@
1
+ import { existsSync } from "node:fs";
2
+ import { cp, lstat, mkdir, readlink, realpath, rm, symlink } from "node:fs/promises";
3
+ import { homedir } from "node:os";
4
+ import { dirname, isAbsolute, join, relative, resolve } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ import { createAgentSessionFromServices, createAgentSessionRuntime, createAgentSessionServices, getAgentDir, SessionManager, } from "@earendil-works/pi-coding-agent";
7
+ import { PI_FAVORITE_MODEL_REFS } from "./constants.js";
8
+ import { parseModelRef, parseScopedModelRef } from "./model-ref.js";
9
+ const BUNDLED_QUESTION_EXTENSION_NAME = "question";
10
+ const PI_TOOLS_SUITE_EXTENSION_NAME = "pi-tools-suite";
11
+ const BUNDLED_EXTENSIONS_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "../..", "extensions");
12
+ const BUNDLED_QUESTION_EXTENSION_DIR = resolve(BUNDLED_EXTENSIONS_DIR, BUNDLED_QUESTION_EXTENSION_NAME);
13
+ const BUNDLED_SESSION_TITLE_EXTENSION_DIR = resolve(BUNDLED_EXTENSIONS_DIR, "session-title");
14
+ const BUNDLED_TERMINAL_BELL_EXTENSION_DIR = resolve(BUNDLED_EXTENSIONS_DIR, "terminal-bell");
15
+ const PI_TOOLS_SUITE_SOURCE_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "../..", "external", PI_TOOLS_SUITE_EXTENSION_NAME);
16
+ const BUNDLED_SKILLS_SOURCE_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "../..", "skills");
17
+ export function bundledQuestionExtensionPath() {
18
+ return BUNDLED_QUESTION_EXTENSION_DIR;
19
+ }
20
+ export function bundledSessionTitleExtensionPath() {
21
+ return BUNDLED_SESSION_TITLE_EXTENSION_DIR;
22
+ }
23
+ export function bundledTerminalBellExtensionPath() {
24
+ return BUNDLED_TERMINAL_BELL_EXTENSION_DIR;
25
+ }
26
+ export function piToolsSuiteExtensionSourcePath() {
27
+ return PI_TOOLS_SUITE_SOURCE_DIR;
28
+ }
29
+ export function piToolsSuiteExtensionInstallPath(agentDir = getAgentDir()) {
30
+ return join(agentDir, "extensions", PI_TOOLS_SUITE_EXTENSION_NAME);
31
+ }
32
+ export function bundledSkillsSourcePath() {
33
+ return BUNDLED_SKILLS_SOURCE_DIR;
34
+ }
35
+ export function bundledSkillsInstallPath(homeDir = homedir()) {
36
+ return join(homeDir, ".agents", "skills");
37
+ }
38
+ export async function ensurePiToolsSuiteExtensionInstalled(options = {}) {
39
+ const sourcePath = resolve(options.sourcePath ?? piToolsSuiteExtensionSourcePath());
40
+ const targetPath = resolve(options.targetPath ?? piToolsSuiteExtensionInstallPath(options.agentDir));
41
+ if (!extensionEntryExists(sourcePath)) {
42
+ return { action: "missing-source", sourcePath, targetPath };
43
+ }
44
+ await mkdir(dirname(targetPath), { recursive: true });
45
+ const targetStat = await lstat(targetPath).catch(() => undefined);
46
+ if (!targetStat) {
47
+ await symlink(sourcePath, targetPath, extensionSymlinkType());
48
+ return { action: "installed", sourcePath, targetPath };
49
+ }
50
+ if (targetStat.isSymbolicLink()) {
51
+ const currentTarget = resolve(dirname(targetPath), await readlink(targetPath));
52
+ if (await pathsReferToSameEntry(currentTarget, sourcePath)) {
53
+ return { action: "already-installed", sourcePath, targetPath };
54
+ }
55
+ await rm(targetPath, { force: true });
56
+ await symlink(sourcePath, targetPath, extensionSymlinkType());
57
+ return { action: "installed", sourcePath, targetPath };
58
+ }
59
+ if (await pathsReferToSameEntry(targetPath, sourcePath)) {
60
+ return { action: "already-installed", sourcePath, targetPath };
61
+ }
62
+ return { action: "existing-kept", sourcePath, targetPath };
63
+ }
64
+ export async function ensureBundledSkillsInstalled(options = {}) {
65
+ const sourcePath = resolve(options.sourcePath ?? bundledSkillsSourcePath());
66
+ const targetPath = resolve(options.targetPath ?? bundledSkillsInstallPath(options.homeDir));
67
+ const sourceStat = await lstat(sourcePath).catch(() => undefined);
68
+ if (!sourceStat?.isDirectory()) {
69
+ return { action: "missing-source", sourcePath, targetPath };
70
+ }
71
+ if (await pathsReferToSameEntry(sourcePath, targetPath)) {
72
+ return { action: "already-installed", sourcePath, targetPath };
73
+ }
74
+ await mkdir(dirname(targetPath), { recursive: true });
75
+ await cp(sourcePath, targetPath, { recursive: true, force: true });
76
+ return { action: "installed", sourcePath, targetPath };
77
+ }
78
+ export function getBundledExtensionPaths() {
79
+ return [
80
+ bundledQuestionExtensionPath(),
81
+ bundledSessionTitleExtensionPath(),
82
+ bundledTerminalBellExtensionPath(),
83
+ ].filter(extensionEntryExists);
84
+ }
85
+ export function prioritizeBundledQuestionExtension(base, questionExtensionPath = bundledQuestionExtensionPath()) {
86
+ const bundledQuestionExtensions = base.extensions.filter((extension) => isBundledQuestionExtension(extension, questionExtensionPath));
87
+ if (bundledQuestionExtensions.length === 0)
88
+ return base;
89
+ const bundledExtensionPaths = new Set(bundledQuestionExtensions.map((extension) => extension.path));
90
+ return {
91
+ ...base,
92
+ extensions: [
93
+ ...bundledQuestionExtensions,
94
+ ...base.extensions.filter((extension) => !bundledExtensionPaths.has(extension.path)),
95
+ ],
96
+ errors: base.errors.filter((error) => !isBundledQuestionConflict(error, bundledExtensionPaths)),
97
+ };
98
+ }
99
+ function extensionEntryExists(extensionPath) {
100
+ return existsSync(join(extensionPath, "index.ts")) || existsSync(join(extensionPath, "index.js"));
101
+ }
102
+ function extensionSymlinkType() {
103
+ return process.platform === "win32" ? "junction" : "dir";
104
+ }
105
+ async function pathsReferToSameEntry(leftPath, rightPath) {
106
+ try {
107
+ const [leftRealPath, rightRealPath] = await Promise.all([realpath(leftPath), realpath(rightPath)]);
108
+ return normalizePathForCompare(leftRealPath) === normalizePathForCompare(rightRealPath);
109
+ }
110
+ catch {
111
+ return normalizePathForCompare(resolve(leftPath)) === normalizePathForCompare(resolve(rightPath));
112
+ }
113
+ }
114
+ function normalizePathForCompare(pathValue) {
115
+ const normalized = resolve(pathValue);
116
+ return process.platform === "win32" ? normalized.toLowerCase() : normalized;
117
+ }
118
+ function isBundledQuestionExtension(extension, questionExtensionPath) {
119
+ return extension.tools.has(BUNDLED_QUESTION_EXTENSION_NAME) && pathIsInside(extension.resolvedPath, questionExtensionPath);
120
+ }
121
+ function pathIsInside(candidatePath, parentPath) {
122
+ const relativePath = relative(resolve(parentPath), resolve(candidatePath));
123
+ return relativePath === "" || (!relativePath.startsWith("..") && !isAbsolute(relativePath));
124
+ }
125
+ function isBundledQuestionConflict(error, bundledExtensionPaths) {
126
+ if (!error.error.startsWith(`Tool "${BUNDLED_QUESTION_EXTENSION_NAME}" conflicts with `))
127
+ return false;
128
+ for (const bundledExtensionPath of bundledExtensionPaths) {
129
+ if (error.path === bundledExtensionPath || error.error.endsWith(bundledExtensionPath))
130
+ return true;
131
+ }
132
+ return false;
133
+ }
134
+ export async function createPixRuntime(options, runtimeOptions = {}) {
135
+ const parsedModel = options.modelRef ? parseModelRef(options.modelRef) : undefined;
136
+ const agentDir = getAgentDir();
137
+ const createRuntime = async ({ cwd, sessionManager, sessionStartEvent }) => {
138
+ await ensureBundledSkillsInstalled();
139
+ await ensurePiToolsSuiteExtensionInstalled({ agentDir });
140
+ const bundledExtensionPaths = getBundledExtensionPaths();
141
+ const services = await createAgentSessionServices({
142
+ cwd,
143
+ agentDir,
144
+ resourceLoaderOptions: {
145
+ ...(runtimeOptions.eventBus === undefined ? {} : { eventBus: runtimeOptions.eventBus }),
146
+ ...(bundledExtensionPaths.length === 0 ? {} : {
147
+ additionalExtensionPaths: bundledExtensionPaths,
148
+ extensionsOverride: prioritizeBundledQuestionExtension,
149
+ }),
150
+ },
151
+ });
152
+ services.modelRegistry.refresh();
153
+ const model = parsedModel ? services.modelRegistry.find(parsedModel.provider, parsedModel.modelId) : undefined;
154
+ if (parsedModel && !model) {
155
+ throw new Error(`Model not found: ${parsedModel.provider}/${parsedModel.modelId}`);
156
+ }
157
+ const enabledModelRefs = services.settingsManager.getEnabledModels();
158
+ const favoriteModelRefs = enabledModelRefs && enabledModelRefs.length > 0 ? enabledModelRefs : PI_FAVORITE_MODEL_REFS;
159
+ const scopedModels = favoriteModelRefs.flatMap((modelRef) => {
160
+ const scoped = parseScopedModelRef(modelRef);
161
+ if (!scoped)
162
+ return [];
163
+ const scopedModel = services.modelRegistry.find(scoped.provider, scoped.modelId);
164
+ if (!scopedModel)
165
+ return [];
166
+ return [
167
+ {
168
+ model: scopedModel,
169
+ ...(scoped.thinkingLevel === undefined ? {} : { thinkingLevel: scoped.thinkingLevel }),
170
+ },
171
+ ];
172
+ });
173
+ return {
174
+ ...(await createAgentSessionFromServices({
175
+ services,
176
+ sessionManager,
177
+ ...(sessionStartEvent === undefined ? {} : { sessionStartEvent }),
178
+ ...(model === undefined ? {} : { model }),
179
+ ...(parsedModel?.thinkingLevel === undefined ? {} : { thinkingLevel: parsedModel.thinkingLevel }),
180
+ ...(scopedModels.length === 0 ? {} : { scopedModels }),
181
+ })),
182
+ services,
183
+ diagnostics: services.diagnostics,
184
+ };
185
+ };
186
+ return await createAgentSessionRuntime(createRuntime, {
187
+ cwd: options.cwd,
188
+ agentDir,
189
+ sessionManager: options.noSession
190
+ ? SessionManager.inMemory(options.cwd)
191
+ : options.sessionPath
192
+ ? SessionManager.open(options.sessionPath, undefined, options.cwd)
193
+ : SessionManager.create(options.cwd),
194
+ });
195
+ }
@@ -0,0 +1,6 @@
1
+ import type { ScreenPoint } from "./types.js";
2
+ export declare function samePoint(left: ScreenPoint, right: ScreenPoint): boolean;
3
+ export declare function orderedSelection(anchor: ScreenPoint, current: ScreenPoint): {
4
+ start: ScreenPoint;
5
+ end: ScreenPoint;
6
+ };
@@ -0,0 +1,9 @@
1
+ export function samePoint(left, right) {
2
+ return left.x === right.x && left.y === right.y;
3
+ }
4
+ export function orderedSelection(anchor, current) {
5
+ if (anchor.y < current.y || (anchor.y === current.y && anchor.x <= current.x)) {
6
+ return { start: anchor, end: current };
7
+ }
8
+ return { start: current, end: anchor };
9
+ }
@@ -0,0 +1,34 @@
1
+ import { type Theme } from "../theme.js";
2
+ import type { MouseSelection, RenderedLine, StyledSegment } from "./types.js";
3
+ export type ScreenStylerHost = {
4
+ readonly theme: Theme;
5
+ readonly cwd?: string;
6
+ readonly mouseSelection: MouseSelection | undefined;
7
+ };
8
+ export declare class ScreenStyler {
9
+ private readonly host;
10
+ constructor(host: ScreenStylerHost);
11
+ styleBaseLine(row: number, line: RenderedLine | undefined, width: number): string;
12
+ styleLineSegments(row: number, text: string, width: number, baseOptions: {
13
+ foreground?: string;
14
+ background?: string;
15
+ bold?: boolean;
16
+ underline?: boolean;
17
+ }, segments: readonly StyledSegment[]): string;
18
+ styleLine(row: number, text: string, width: number, options: {
19
+ foreground?: string;
20
+ background?: string;
21
+ bold?: boolean;
22
+ underline?: boolean;
23
+ }): string;
24
+ styleInputLine(row: number, text: string, tagSpans: readonly {
25
+ start: number;
26
+ end: number;
27
+ }[] | undefined, width: number, tagColor: string, frameColor?: string): string;
28
+ private styleAnsiLine;
29
+ selectionRangeForRow(row: number, width: number): {
30
+ startIndex: number;
31
+ endIndex: number;
32
+ } | undefined;
33
+ private baseLineForeground;
34
+ }
@@ -0,0 +1,168 @@
1
+ import { ANSI_RESET, colorize } from "../theme.js";
2
+ import { renderMarkdownLine } from "../markdown-format.js";
3
+ import { syntaxHighlightSegmentsForLine } from "../syntax-highlight.js";
4
+ import { padOrTrimPlain } from "./render-text.js";
5
+ import { orderedSelection } from "./screen-selection.js";
6
+ export class ScreenStyler {
7
+ host;
8
+ constructor(host) {
9
+ this.host = host;
10
+ }
11
+ styleBaseLine(row, line, width) {
12
+ const foreground = line?.colorOverride ?? this.baseLineForeground(line?.variant);
13
+ const options = {
14
+ foreground,
15
+ ...(line?.backgroundOverride === undefined ? {} : { background: line.backgroundOverride }),
16
+ };
17
+ const colors = this.host.theme.colors;
18
+ const markdownLine = line?.syntaxHighlight?.language === "markdown"
19
+ ? renderMarkdownDisplayLine(line.text, width, line.syntaxHighlight.start)
20
+ : undefined;
21
+ const text = markdownLine?.text ?? line?.text ?? "";
22
+ if (line?.syntaxHighlight && !this.selectionRangeForRow(row, width)) {
23
+ const syntaxHighlight = markdownLine ? { ...line.syntaxHighlight, start: Math.min(line.syntaxHighlight.start, markdownLine.text.length) } : line.syntaxHighlight;
24
+ const segments = [
25
+ ...syntaxHighlightSegmentsForLine(text, syntaxHighlight, colors),
26
+ ...(markdownLine?.segments ?? []),
27
+ ...(line.segments ?? []),
28
+ ];
29
+ if (segments.length > 0)
30
+ return this.styleLineSegments(row, text, width, options, segments);
31
+ }
32
+ if (line?.segments && line.segments.length > 0) {
33
+ return this.styleLineSegments(row, text, width, options, line.segments);
34
+ }
35
+ return this.styleLine(row, text, width, options);
36
+ }
37
+ styleLineSegments(row, text, width, baseOptions, segments) {
38
+ if (this.selectionRangeForRow(row, width))
39
+ return this.styleLine(row, text, width, baseOptions);
40
+ const plain = padOrTrimPlain(text, width);
41
+ const chunks = [];
42
+ let offset = 0;
43
+ const endOffset = plain.length;
44
+ for (const segment of [...segments].sort((a, b) => a.start - b.start)) {
45
+ const start = Math.max(offset, Math.min(endOffset, segment.start));
46
+ const end = Math.max(start, Math.min(endOffset, segment.end));
47
+ if (start > offset)
48
+ chunks.push(colorize(plain.slice(offset, start), baseOptions));
49
+ if (end > start)
50
+ chunks.push(colorize(plain.slice(start, end), { ...baseOptions, ...segment }));
51
+ offset = end;
52
+ }
53
+ if (offset < endOffset)
54
+ chunks.push(colorize(plain.slice(offset, endOffset), baseOptions));
55
+ return chunks.join("");
56
+ }
57
+ styleLine(row, text, width, options) {
58
+ const plain = padOrTrimPlain(text, width);
59
+ const range = this.selectionRangeForRow(row, width);
60
+ if (!range)
61
+ return colorize(plain, options);
62
+ const before = plain.slice(0, range.startIndex);
63
+ const selected = plain.slice(range.startIndex, range.endIndex);
64
+ const after = plain.slice(range.endIndex);
65
+ return [
66
+ colorize(before, options),
67
+ colorize(selected, {
68
+ foreground: this.host.theme.colors.selectionForeground,
69
+ background: this.host.theme.colors.selectionBackground,
70
+ bold: true,
71
+ }),
72
+ colorize(after, options),
73
+ ].join("");
74
+ }
75
+ styleInputLine(row, text, tagSpans, width, tagColor, frameColor) {
76
+ const colors = this.host.theme.colors;
77
+ const baseOptions = { foreground: colors.inputForeground };
78
+ if (this.selectionRangeForRow(row, width))
79
+ return this.styleLine(row, text, width, baseOptions);
80
+ const plain = padOrTrimPlain(text, width);
81
+ const frameSpans = inputFrameSpans(plain, width, frameColor);
82
+ if ((!tagSpans || tagSpans.length === 0) && frameSpans.length === 0) {
83
+ return hasAnsi(plain) ? this.styleAnsiLine(plain, baseOptions) : colorize(plain, baseOptions);
84
+ }
85
+ const chunks = [];
86
+ let offset = 0;
87
+ const endOffset = plain.length;
88
+ const spans = [
89
+ ...frameSpans,
90
+ ...(tagSpans ?? []).map((span) => ({ ...span, foreground: tagColor, bold: true })),
91
+ ].sort((a, b) => a.start - b.start || a.end - b.end);
92
+ for (const span of spans) {
93
+ const start = Math.max(offset, Math.min(endOffset, span.start));
94
+ const end = Math.max(start, Math.min(endOffset, span.end));
95
+ if (start > offset)
96
+ chunks.push(colorize(plain.slice(offset, start), baseOptions));
97
+ if (end > start)
98
+ chunks.push(colorize(plain.slice(start, end), { ...baseOptions, ...span }));
99
+ offset = end;
100
+ }
101
+ if (offset < endOffset)
102
+ chunks.push(colorize(plain.slice(offset), baseOptions));
103
+ return chunks.join("");
104
+ }
105
+ styleAnsiLine(text, options) {
106
+ const prefix = colorize("", options).replace(new RegExp(`${escapeRegExp(ANSI_RESET)}$`), "");
107
+ if (!prefix)
108
+ return text;
109
+ return `${prefix}${text.replaceAll(ANSI_RESET, `${ANSI_RESET}${prefix}`)}${ANSI_RESET}`;
110
+ }
111
+ selectionRangeForRow(row, width) {
112
+ if (!this.host.mouseSelection)
113
+ return undefined;
114
+ const anchor = this.host.mouseSelection.screenAnchor ?? this.host.mouseSelection.anchor;
115
+ const current = this.host.mouseSelection.screenCurrent ?? this.host.mouseSelection.current;
116
+ const { start, end } = orderedSelection(anchor, current);
117
+ if (row < start.y || row > end.y)
118
+ return undefined;
119
+ const startColumn = row === start.y ? start.x : 1;
120
+ const endColumn = row === end.y ? end.x : width + 1;
121
+ const startIndex = Math.max(0, Math.min(width, startColumn - 1));
122
+ const endIndex = Math.max(startIndex, Math.min(width, endColumn - 1));
123
+ return endIndex > startIndex ? { startIndex, endIndex } : undefined;
124
+ }
125
+ baseLineForeground(variant) {
126
+ const colors = this.host.theme.colors;
127
+ switch (variant) {
128
+ case "accent":
129
+ return colors.accent;
130
+ case "error":
131
+ return colors.error;
132
+ case "muted":
133
+ return colors.muted;
134
+ case "normal":
135
+ case undefined:
136
+ return colors.foreground;
137
+ }
138
+ }
139
+ }
140
+ function hasAnsi(text) {
141
+ return text.includes("\x1b[");
142
+ }
143
+ function renderMarkdownDisplayLine(text, width, start) {
144
+ if (width > 1 && text[0] === "│" && text[width - 1] === "│" && start > 0) {
145
+ const innerWidth = Math.max(0, width - 2);
146
+ const inner = renderMarkdownLine(text.slice(1, width - 1), start - 1);
147
+ return {
148
+ text: `│${padOrTrimPlain(inner.text, innerWidth)}│`,
149
+ segments: inner.segments.map((segment) => ({ ...segment, start: segment.start + 1, end: segment.end + 1 })),
150
+ };
151
+ }
152
+ const line = renderMarkdownLine(text, start);
153
+ return { text: line.text, segments: [...line.segments] };
154
+ }
155
+ function inputFrameSpans(text, width, frameColor) {
156
+ if (!frameColor || width <= 0 || text.length === 0)
157
+ return [];
158
+ const spans = [];
159
+ if (text[0] === "│")
160
+ spans.push({ start: 0, end: 1, foreground: frameColor });
161
+ if (width > 1 && text[Math.min(width, text.length) - 1] === "│") {
162
+ spans.push({ start: width - 1, end: width, foreground: frameColor });
163
+ }
164
+ return spans;
165
+ }
166
+ function escapeRegExp(value) {
167
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
168
+ }
@@ -0,0 +1,51 @@
1
+ import type { ConversationViewport } from "./conversation-viewport.js";
2
+ import type { EditorLayoutRenderer } from "./editor-layout-renderer.js";
3
+ import type { RenderedLine } from "./types.js";
4
+ export type AppScrollMetrics = {
5
+ bodyHeight: number;
6
+ viewportColumns: number;
7
+ conversationLineCount: number;
8
+ maxScroll: number;
9
+ start: number;
10
+ };
11
+ export type AppScrollBarMetrics = {
12
+ thumbStartRow: number;
13
+ thumbEndRow: number;
14
+ };
15
+ export type ConversationTextScrollTarget = {
16
+ entryId?: string;
17
+ needles: readonly string[];
18
+ };
19
+ export type AppScrollControllerHost = {
20
+ conversationViewport(): ConversationViewport;
21
+ editorLayoutRenderer(): EditorLayoutRenderer;
22
+ terminalColumns(): number;
23
+ terminalRows(): number;
24
+ tabPanelRows(terminalRows: number): number;
25
+ render(): void;
26
+ };
27
+ export declare class AppScrollController {
28
+ private readonly host;
29
+ private scrollFromBottom;
30
+ private detachedScrollStart;
31
+ constructor(host: AppScrollControllerHost);
32
+ reset(): void;
33
+ conversationView(columns: number, bodyHeight: number): {
34
+ lines: RenderedLine[];
35
+ metrics: AppScrollMetrics;
36
+ };
37
+ visibleConversationLines(columns: number, bodyHeight: number): RenderedLine[];
38
+ scrollMetrics(columns: number, bodyHeight: number): AppScrollMetrics;
39
+ scrollBarForMetrics(metrics: AppScrollMetrics): AppScrollBarMetrics | undefined;
40
+ scrollBarMetrics(columns: number, bodyHeight: number): AppScrollBarMetrics | undefined;
41
+ scrollByPage(direction: -1 | 1): void;
42
+ scrollByLines(delta: number, options?: {
43
+ render?: boolean;
44
+ }): boolean;
45
+ scrollToScrollbarPosition(bodyRow: number): boolean;
46
+ scrollToConversationEntry(entryId: string): boolean;
47
+ scrollToConversationText(target: ConversationTextScrollTarget): boolean;
48
+ private scrollToStart;
49
+ private setScrollStart;
50
+ private viewportColumns;
51
+ }