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,60 @@
1
+ import { InputEditor } from "../input-editor.js";
2
+ import type { ExtensionTerminalInputResult } from "./extension-ui-controller.js";
3
+ import type { MouseEvent, ActivePopupMenu } from "./types.js";
4
+ type DirectPopupMenu = Exclude<ActivePopupMenu, "slash">;
5
+ export type InputControllerHost = {
6
+ readonly inputEditor: InputEditor;
7
+ readonly cwd: string;
8
+ handleExtensionTerminalInput(data: string): ExtensionTerminalInputResult;
9
+ extensionInputUsesEditor?(): boolean;
10
+ isShiftPressed?(): boolean;
11
+ getInput(): string;
12
+ getDirectPopupMenu(): DirectPopupMenu | undefined;
13
+ resetRequestHistoryNavigation(): void;
14
+ resetInputMenuDismissals(): void;
15
+ render(): void;
16
+ moveActivePopupMenuSelection(delta: number): boolean;
17
+ navigateRequestHistory(delta: number): boolean;
18
+ scrollByLines(delta: number): void;
19
+ scrollByPage(delta: number): void;
20
+ handleMouse(event: MouseEvent): void;
21
+ handleEnter(): void;
22
+ handleInterrupt(): Promise<void>;
23
+ handleEscape(): Promise<void>;
24
+ handleDirectPopupInput(char: string): boolean;
25
+ autocompleteModel(): boolean;
26
+ autocompleteThinking(): boolean;
27
+ autocompleteSlashCommand(): void;
28
+ toggleVoiceRecording(): void;
29
+ stop(): Promise<void>;
30
+ };
31
+ export declare class AppInputController {
32
+ private readonly host;
33
+ private inputBuffer;
34
+ private readonly pasteHandler;
35
+ constructor(host: InputControllerHost);
36
+ handleChunk(chunk: Buffer): void;
37
+ private consumeSharedEditorShiftEnter;
38
+ private drainInputBuffer;
39
+ private getEscapeSequences;
40
+ private isPendingEscapeSequence;
41
+ private consumeEscapeSequence;
42
+ private consumeCommandBackspaceSequence;
43
+ private consumeCommandArrowPageSequence;
44
+ private consumeCommandArrowPageMatch;
45
+ private consumeTerminalEditShortcutSequence;
46
+ private consumeTerminalInterruptSequence;
47
+ private handleArrowUp;
48
+ private handleArrowDown;
49
+ private handleArrowLeft;
50
+ private handleArrowRight;
51
+ private orderedEditorSelection;
52
+ private insertInputNewline;
53
+ private undoInput;
54
+ private redoInput;
55
+ private handleEditShortcutChar;
56
+ private deleteCurrentInputLine;
57
+ private handleChar;
58
+ private isShiftPressed;
59
+ }
60
+ export {};
@@ -0,0 +1,425 @@
1
+ import { InputPasteHandler } from "./input-paste-handler.js";
2
+ import { hasTerminalCommandModifier, isNativeCommandPressed, isNativeShiftPressed } from "./native-modifiers.js";
3
+ import { parseTerminalEditShortcutSequence, parseTerminalInterruptSequence, terminalEditShortcutForControlChar } from "./terminal-edit-shortcuts.js";
4
+ export class AppInputController {
5
+ host;
6
+ inputBuffer = "";
7
+ pasteHandler;
8
+ constructor(host) {
9
+ this.host = host;
10
+ this.pasteHandler = new InputPasteHandler(host);
11
+ }
12
+ handleChunk(chunk) {
13
+ let data = chunk.toString("utf8");
14
+ if (this.inputBuffer.startsWith("\x1b[<") || data.startsWith("\x1b[<")) {
15
+ this.inputBuffer += data;
16
+ this.drainInputBuffer();
17
+ return;
18
+ }
19
+ if (this.consumeSharedEditorShiftEnter(data))
20
+ return;
21
+ const extensionInput = this.host.handleExtensionTerminalInput(data);
22
+ if (extensionInput.consume)
23
+ return;
24
+ if (extensionInput.data !== undefined)
25
+ data = extensionInput.data;
26
+ if (this.pasteHandler.handlePlainData(data))
27
+ return;
28
+ this.inputBuffer += data;
29
+ this.drainInputBuffer();
30
+ }
31
+ consumeSharedEditorShiftEnter(data) {
32
+ if (this.host.extensionInputUsesEditor?.() !== true)
33
+ return false;
34
+ if (this.host.inputEditor.isInBracketedPaste)
35
+ return false;
36
+ if (!this.isShiftPressed())
37
+ return false;
38
+ if (data !== "\r" && data !== "\n")
39
+ return false;
40
+ this.insertInputNewline();
41
+ return true;
42
+ }
43
+ drainInputBuffer() {
44
+ while (this.inputBuffer.length > 0) {
45
+ const mouseMatch = /^\x1b\[<(\d+);(\d+);(\d+)([mM])/.exec(this.inputBuffer);
46
+ if (mouseMatch) {
47
+ this.inputBuffer = this.inputBuffer.slice(mouseMatch[0].length);
48
+ this.host.handleMouse({
49
+ button: Number(mouseMatch[1]),
50
+ x: Number(mouseMatch[2]),
51
+ y: Number(mouseMatch[3]),
52
+ released: mouseMatch[4] === "m",
53
+ });
54
+ continue;
55
+ }
56
+ if (this.inputBuffer.startsWith("\x1b[<"))
57
+ return;
58
+ const commandBackspaceSequence = this.consumeCommandBackspaceSequence();
59
+ if (commandBackspaceSequence === "consumed")
60
+ continue;
61
+ if (commandBackspaceSequence === "pending")
62
+ return;
63
+ const commandArrowPageSequence = this.consumeCommandArrowPageSequence();
64
+ if (commandArrowPageSequence === "consumed")
65
+ continue;
66
+ if (commandArrowPageSequence === "pending")
67
+ return;
68
+ const terminalInterruptSequence = this.consumeTerminalInterruptSequence();
69
+ if (terminalInterruptSequence === "consumed")
70
+ continue;
71
+ if (terminalInterruptSequence === "pending")
72
+ return;
73
+ const terminalEditShortcutSequence = this.consumeTerminalEditShortcutSequence();
74
+ if (terminalEditShortcutSequence === "consumed")
75
+ continue;
76
+ if (terminalEditShortcutSequence === "pending")
77
+ return;
78
+ if (this.consumeEscapeSequence())
79
+ continue;
80
+ if (this.isPendingEscapeSequence())
81
+ return;
82
+ const char = this.inputBuffer[0];
83
+ this.inputBuffer = this.inputBuffer.slice(1);
84
+ if (char)
85
+ this.handleChar(char);
86
+ }
87
+ }
88
+ getEscapeSequences() {
89
+ return [
90
+ ["\x1b[13;2u", () => this.insertInputNewline()],
91
+ ["\x1b[13;2~", () => this.insertInputNewline()],
92
+ ["\x1b[27;2;13~", () => this.insertInputNewline()],
93
+ ["\x1b[13u", () => this.host.handleEnter()],
94
+ ["\x1b[13;1u", () => this.host.handleEnter()],
95
+ ["\x1b\r", () => this.insertInputNewline()],
96
+ ["\x1b\n", () => this.insertInputNewline()],
97
+ ["\x1b[5~", () => this.host.scrollByPage(-1)],
98
+ ["\x1b[6~", () => this.host.scrollByPage(1)],
99
+ ["\x1b[A", () => this.handleArrowUp()],
100
+ ["\x1b[B", () => this.handleArrowDown()],
101
+ ["\x1b[C", () => this.handleArrowRight()],
102
+ ["\x1b[D", () => this.handleArrowLeft()],
103
+ ["\x1b[1;2A", () => { this.host.inputEditor.moveUpExtend(); this.host.render(); }],
104
+ ["\x1b[1;2B", () => { this.host.inputEditor.moveDownExtend(); this.host.render(); }],
105
+ ["\x1b[1;2C", () => { this.host.inputEditor.moveRightExtend(); this.host.render(); }],
106
+ ["\x1b[1;2D", () => { this.host.inputEditor.moveLeftExtend(); this.host.render(); }],
107
+ ["\x1b[H", () => { this.host.inputEditor.moveToLineStart(); this.host.render(); }],
108
+ ["\x1b[F", () => { this.host.inputEditor.moveToLineEnd(); this.host.render(); }],
109
+ ["\x1b[1~", () => { this.host.inputEditor.moveToLineStart(); this.host.render(); }],
110
+ ["\x1b[4~", () => { this.host.inputEditor.moveToLineEnd(); this.host.render(); }],
111
+ ["\x1b[1;5H", () => { this.host.inputEditor.moveToStart(); this.host.render(); }],
112
+ ["\x1b[1;5F", () => { this.host.inputEditor.moveToEnd(); this.host.render(); }],
113
+ ["\x1b[3~", () => { this.host.resetRequestHistoryNavigation(); this.host.inputEditor.deleteForward(); this.host.render(); }],
114
+ ["\x1b[1;3D", () => { this.host.inputEditor.moveWordLeft(); this.host.render(); }],
115
+ ["\x1b[1;3C", () => { this.host.inputEditor.moveWordRight(); this.host.render(); }],
116
+ ["\x1bb", () => { this.host.inputEditor.moveWordLeft(); this.host.render(); }],
117
+ ["\x1bf", () => { this.host.inputEditor.moveWordRight(); this.host.render(); }],
118
+ ["\x1b[3;3~", () => { this.host.resetRequestHistoryNavigation(); this.host.inputEditor.deleteWordForward(); this.host.render(); }],
119
+ ["\x1b[200~", () => this.pasteHandler.beginBracketedPaste()],
120
+ ["\x1b[201~", () => this.pasteHandler.endBracketedPaste()],
121
+ ["\x1b[1;2H", () => { this.host.inputEditor.moveToLineStartExtend(); this.host.render(); }],
122
+ ["\x1b[1;2F", () => { this.host.inputEditor.moveToLineEndExtend(); this.host.render(); }],
123
+ ["\x1b[118;5u", () => { void this.pasteHandler.handleClipboardImagePaste(); }],
124
+ ["\x1b[27;5;118~", () => { void this.pasteHandler.handleClipboardImagePaste(); }],
125
+ ["\x1b[122;9u", () => this.undoInput()],
126
+ ["\x1b[27;9;122~", () => this.undoInput()],
127
+ ["\x1b[90;10u", () => this.redoInput()],
128
+ ["\x1b[122;10u", () => this.redoInput()],
129
+ ["\x1b[27;10;90~", () => this.redoInput()],
130
+ ["\x1b[27;10;122~", () => this.redoInput()],
131
+ ["\x1b[121;9u", () => this.redoInput()],
132
+ ["\x1b[27;9;121~", () => this.redoInput()],
133
+ ["\x1b[97;5u", () => { this.host.inputEditor.selectAll(); this.host.render(); }],
134
+ ["\x1b[107;5u", () => this.deleteCurrentInputLine()],
135
+ ];
136
+ }
137
+ isPendingEscapeSequence() {
138
+ return this.inputBuffer.length > 1 && this.getEscapeSequences().some(([sequence]) => sequence.startsWith(this.inputBuffer));
139
+ }
140
+ consumeEscapeSequence() {
141
+ const sequences = this.getEscapeSequences();
142
+ for (const [sequence, handler] of sequences) {
143
+ if (this.inputBuffer.startsWith(sequence)) {
144
+ this.inputBuffer = this.inputBuffer.slice(sequence.length);
145
+ handler();
146
+ return true;
147
+ }
148
+ }
149
+ if (this.inputBuffer.startsWith("\x1b") && this.inputBuffer.length < 6)
150
+ return false;
151
+ if (this.inputBuffer.startsWith("\x1b")) {
152
+ this.inputBuffer = this.inputBuffer.slice(1);
153
+ return true;
154
+ }
155
+ return false;
156
+ }
157
+ consumeCommandBackspaceSequence() {
158
+ if (!this.inputBuffer.startsWith("\x1b["))
159
+ return "none";
160
+ const match = /^\x1b\[(?:(?:8|127);(\d+)u|27;(\d+);(?:8|127)~)/.exec(this.inputBuffer);
161
+ if (match) {
162
+ const modifierValue = Number(match[1] ?? match[2]);
163
+ this.inputBuffer = this.inputBuffer.slice(match[0].length);
164
+ if (!hasTerminalCommandModifier(modifierValue)) {
165
+ this.host.resetRequestHistoryNavigation();
166
+ this.host.inputEditor.deleteBackward();
167
+ this.host.render();
168
+ return "consumed";
169
+ }
170
+ this.deleteCurrentInputLine();
171
+ return "consumed";
172
+ }
173
+ if (/^\x1b\[(?:8|127);\d*$/.test(this.inputBuffer))
174
+ return "pending";
175
+ if (this.inputBuffer.startsWith("\x1b[27;") && !this.inputBuffer.includes("~"))
176
+ return "pending";
177
+ return "none";
178
+ }
179
+ consumeCommandArrowPageSequence() {
180
+ if (!this.inputBuffer.startsWith("\x1b["))
181
+ return "none";
182
+ const legacyMatch = /^\x1b\[1;(\d+)([AB])/.exec(this.inputBuffer);
183
+ if (legacyMatch)
184
+ return this.consumeCommandArrowPageMatch(legacyMatch[0].length, Number(legacyMatch[1]), legacyMatch[2]);
185
+ const xtermMatch = /^\x1b\[27;(\d+);(65|66)~/.exec(this.inputBuffer);
186
+ if (xtermMatch)
187
+ return this.consumeCommandArrowPageMatch(xtermMatch[0].length, Number(xtermMatch[1]), xtermMatch[2] === "65" ? "A" : "B");
188
+ if (/^\x1b\[1;\d*$/.test(this.inputBuffer))
189
+ return "pending";
190
+ if (/^\x1b\[27;\d*(?:;\d*)?$/.test(this.inputBuffer))
191
+ return "pending";
192
+ return "none";
193
+ }
194
+ consumeCommandArrowPageMatch(length, modifierValue, arrow) {
195
+ if (!hasTerminalCommandModifier(modifierValue))
196
+ return "none";
197
+ this.inputBuffer = this.inputBuffer.slice(length);
198
+ this.host.scrollByPage(arrow === "A" ? -1 : 1);
199
+ return "consumed";
200
+ }
201
+ consumeTerminalEditShortcutSequence() {
202
+ const result = parseTerminalEditShortcutSequence(this.inputBuffer);
203
+ if (result.kind === "pending")
204
+ return "pending";
205
+ if (result.kind === "none")
206
+ return "none";
207
+ this.inputBuffer = this.inputBuffer.slice(result.length);
208
+ if (result.kind === "shortcut") {
209
+ if (result.shortcut === "undo")
210
+ this.undoInput();
211
+ else
212
+ this.redoInput();
213
+ }
214
+ return "consumed";
215
+ }
216
+ consumeTerminalInterruptSequence() {
217
+ const result = parseTerminalInterruptSequence(this.inputBuffer);
218
+ if (result.kind === "pending")
219
+ return "pending";
220
+ if (result.kind === "none")
221
+ return "none";
222
+ this.inputBuffer = this.inputBuffer.slice(result.length);
223
+ void this.host.handleInterrupt();
224
+ return "consumed";
225
+ }
226
+ handleArrowUp() {
227
+ if (isNativeCommandPressed()) {
228
+ this.host.scrollByPage(-1);
229
+ return;
230
+ }
231
+ if (this.host.moveActivePopupMenuSelection(-1))
232
+ return;
233
+ if (this.host.getInput().includes("\n")) {
234
+ const pos = this.host.inputEditor.cursor;
235
+ const beforeCursor = this.host.getInput().slice(0, pos);
236
+ const lineIndex = beforeCursor.split("\n").length - 1;
237
+ if (lineIndex > 0) {
238
+ this.host.inputEditor.moveUp();
239
+ this.host.render();
240
+ return;
241
+ }
242
+ }
243
+ if (this.host.navigateRequestHistory(-1))
244
+ return;
245
+ this.host.scrollByLines(-1);
246
+ }
247
+ handleArrowDown() {
248
+ if (isNativeCommandPressed()) {
249
+ this.host.scrollByPage(1);
250
+ return;
251
+ }
252
+ if (this.host.moveActivePopupMenuSelection(1))
253
+ return;
254
+ if (this.host.getInput().includes("\n")) {
255
+ const pos = this.host.inputEditor.cursor;
256
+ const beforeCursor = this.host.getInput().slice(0, pos);
257
+ const lineIndex = beforeCursor.split("\n").length - 1;
258
+ const totalLines = this.host.getInput().split("\n").length;
259
+ if (lineIndex < totalLines - 1) {
260
+ this.host.inputEditor.moveDown();
261
+ this.host.render();
262
+ return;
263
+ }
264
+ }
265
+ if (this.host.navigateRequestHistory(1))
266
+ return;
267
+ this.host.scrollByLines(1);
268
+ }
269
+ handleArrowLeft() {
270
+ if (this.host.inputEditor.hasSelection) {
271
+ const [start] = this.orderedEditorSelection();
272
+ this.host.inputEditor.clearSelection();
273
+ this.host.inputEditor.setText(this.host.inputEditor.text, start);
274
+ this.host.render();
275
+ return;
276
+ }
277
+ if (this.host.inputEditor.cursor > 0) {
278
+ this.host.inputEditor.moveLeft();
279
+ this.host.render();
280
+ }
281
+ }
282
+ handleArrowRight() {
283
+ if (this.host.inputEditor.hasSelection) {
284
+ const [, end] = this.orderedEditorSelection();
285
+ this.host.inputEditor.clearSelection();
286
+ this.host.inputEditor.setText(this.host.inputEditor.text, end);
287
+ this.host.render();
288
+ return;
289
+ }
290
+ if (this.host.inputEditor.cursor < this.host.inputEditor.text.length) {
291
+ this.host.inputEditor.moveRight();
292
+ this.host.render();
293
+ }
294
+ }
295
+ orderedEditorSelection() {
296
+ const sel = this.host.inputEditor.selection;
297
+ if (!sel)
298
+ return [this.host.inputEditor.cursor, this.host.inputEditor.cursor];
299
+ return sel.anchor < sel.active ? [sel.anchor, sel.active] : [sel.active, sel.anchor];
300
+ }
301
+ insertInputNewline() {
302
+ this.host.resetRequestHistoryNavigation();
303
+ this.host.inputEditor.insert("\n");
304
+ this.host.render();
305
+ }
306
+ undoInput() {
307
+ this.host.resetRequestHistoryNavigation();
308
+ if (this.host.inputEditor.undo())
309
+ this.host.resetInputMenuDismissals();
310
+ this.host.render();
311
+ }
312
+ redoInput() {
313
+ this.host.resetRequestHistoryNavigation();
314
+ if (this.host.inputEditor.redo())
315
+ this.host.resetInputMenuDismissals();
316
+ this.host.render();
317
+ }
318
+ handleEditShortcutChar(char) {
319
+ const controlShortcut = terminalEditShortcutForControlChar(char, this.isShiftPressed());
320
+ if (controlShortcut) {
321
+ if (controlShortcut === "undo")
322
+ this.undoInput();
323
+ else
324
+ this.redoInput();
325
+ return true;
326
+ }
327
+ if (!isNativeCommandPressed())
328
+ return false;
329
+ const lower = char.toLowerCase();
330
+ if (lower === "z") {
331
+ if (char === "Z" || this.isShiftPressed())
332
+ this.redoInput();
333
+ else
334
+ this.undoInput();
335
+ return true;
336
+ }
337
+ if (lower === "y") {
338
+ this.redoInput();
339
+ return true;
340
+ }
341
+ return false;
342
+ }
343
+ deleteCurrentInputLine() {
344
+ this.host.resetRequestHistoryNavigation();
345
+ this.host.inputEditor.deleteToLineStartOrPreviousLineEnd();
346
+ this.host.render();
347
+ }
348
+ handleChar(char) {
349
+ if (char === "\u0003") {
350
+ void this.host.handleInterrupt();
351
+ return;
352
+ }
353
+ if (char === "\x1b") {
354
+ void this.host.handleEscape();
355
+ return;
356
+ }
357
+ if (char === "\t") {
358
+ if (this.host.getDirectPopupMenu() === "sdk-menu")
359
+ return;
360
+ if (this.host.autocompleteModel())
361
+ return;
362
+ if (this.host.autocompleteThinking())
363
+ return;
364
+ this.host.autocompleteSlashCommand();
365
+ return;
366
+ }
367
+ if (!this.host.inputEditor.isInBracketedPaste && this.handleEditShortcutChar(char))
368
+ return;
369
+ if (this.host.handleDirectPopupInput(char))
370
+ return;
371
+ if (char === "\u0004" && this.host.getInput().length === 0) {
372
+ void this.host.stop();
373
+ return;
374
+ }
375
+ if (char === "\u000c") {
376
+ this.host.render();
377
+ return;
378
+ }
379
+ if (char === "\u0007") {
380
+ this.host.toggleVoiceRecording();
381
+ return;
382
+ }
383
+ if (char === "\r" || char === "\n") {
384
+ if (this.host.inputEditor.isInBracketedPaste) {
385
+ this.pasteHandler.appendBracketedPasteText("\n");
386
+ return;
387
+ }
388
+ if (this.isShiftPressed()) {
389
+ this.insertInputNewline();
390
+ return;
391
+ }
392
+ this.host.handleEnter();
393
+ return;
394
+ }
395
+ if (char === "\u0015" || ((char === "\u007f" || char === "\b") && isNativeCommandPressed())) {
396
+ this.deleteCurrentInputLine();
397
+ return;
398
+ }
399
+ if (char === "\x16") {
400
+ void this.pasteHandler.handleClipboardImagePaste();
401
+ return;
402
+ }
403
+ if (char === "\u007f" || char === "\b") {
404
+ if (this.host.inputEditor.isInBracketedPaste)
405
+ return;
406
+ this.host.resetRequestHistoryNavigation();
407
+ this.host.inputEditor.deleteBackward();
408
+ this.host.render();
409
+ return;
410
+ }
411
+ if (char >= " ") {
412
+ if (this.host.inputEditor.isInBracketedPaste) {
413
+ this.pasteHandler.appendBracketedPasteText(char);
414
+ }
415
+ else {
416
+ this.host.resetRequestHistoryNavigation();
417
+ this.host.inputEditor.insert(char);
418
+ }
419
+ this.host.render();
420
+ }
421
+ }
422
+ isShiftPressed() {
423
+ return this.host.isShiftPressed?.() ?? isNativeShiftPressed();
424
+ }
425
+ }
@@ -0,0 +1,27 @@
1
+ import { InputEditor } from "../input-editor.js";
2
+ export type InputPasteHost = {
3
+ readonly inputEditor: InputEditor;
4
+ readonly cwd: string;
5
+ resetRequestHistoryNavigation(): void;
6
+ render(): void;
7
+ };
8
+ export declare class InputPasteHandler {
9
+ private readonly host;
10
+ private pasteBuffer;
11
+ private readonly recentPasteFingerprints;
12
+ private suppressImagePathPasteUntil;
13
+ constructor(host: InputPasteHost);
14
+ handlePlainData(data: string): boolean;
15
+ beginBracketedPaste(): void;
16
+ appendBracketedPasteText(text: string): void;
17
+ endBracketedPaste(): void;
18
+ handleClipboardImagePaste(): Promise<void>;
19
+ private isPlainMultilinePasteChunk;
20
+ private plainPasteFilePath;
21
+ private isDuplicatePaste;
22
+ private handlePasteEnd;
23
+ private handleFilePaste;
24
+ private filePathForInput;
25
+ private displayPathForInput;
26
+ private insertPastedPathText;
27
+ }
@@ -0,0 +1,146 @@
1
+ import { createHash } from "node:crypto";
2
+ import { stat } from "node:fs/promises";
3
+ import { isAbsolute, relative, resolve } from "node:path";
4
+ import { isImagePath, looksLikeFilePath, quoteFilePathForInput, readClipboardImage } from "../input-editor.js";
5
+ import { PASTE_DUPLICATE_WINDOW_MS } from "./constants.js";
6
+ import { normalizePastedTextForDuplicateKey } from "./render-text.js";
7
+ export class InputPasteHandler {
8
+ host;
9
+ pasteBuffer = "";
10
+ recentPasteFingerprints = new Map();
11
+ suppressImagePathPasteUntil = 0;
12
+ constructor(host) {
13
+ this.host = host;
14
+ }
15
+ handlePlainData(data) {
16
+ const plainFilePath = !this.host.inputEditor.isInBracketedPaste && this.plainPasteFilePath(data);
17
+ if (plainFilePath) {
18
+ if (isImagePath(plainFilePath) && Date.now() < this.suppressImagePathPasteUntil) {
19
+ this.host.render();
20
+ return true;
21
+ }
22
+ void this.handleFilePaste(plainFilePath);
23
+ return true;
24
+ }
25
+ if (!this.host.inputEditor.isInBracketedPaste && this.isPlainMultilinePasteChunk(data)) {
26
+ if (this.isDuplicatePaste("text", data)) {
27
+ this.host.render();
28
+ return true;
29
+ }
30
+ this.host.resetRequestHistoryNavigation();
31
+ this.host.inputEditor.attachPastedText(data);
32
+ this.host.render();
33
+ return true;
34
+ }
35
+ return false;
36
+ }
37
+ beginBracketedPaste() {
38
+ this.host.inputEditor.beginBracketedPaste();
39
+ this.pasteBuffer = "";
40
+ }
41
+ appendBracketedPasteText(text) {
42
+ this.pasteBuffer += text;
43
+ }
44
+ endBracketedPaste() {
45
+ this.host.inputEditor.endBracketedPaste();
46
+ this.handlePasteEnd();
47
+ }
48
+ async handleClipboardImagePaste() {
49
+ const image = await readClipboardImage();
50
+ if (!image)
51
+ return;
52
+ if (this.isDuplicatePaste(`image:${image.mimeType}`, image.data)) {
53
+ this.host.render();
54
+ return;
55
+ }
56
+ this.host.resetRequestHistoryNavigation();
57
+ this.host.inputEditor.attachImage(image.data, image.mimeType);
58
+ this.suppressImagePathPasteUntil = Date.now() + 1000;
59
+ this.host.render();
60
+ }
61
+ isPlainMultilinePasteChunk(data) {
62
+ if (data.length <= 1)
63
+ return false;
64
+ if (data.includes("\x1b"))
65
+ return false;
66
+ if (!data.includes("\n") && !data.includes("\r"))
67
+ return false;
68
+ return true;
69
+ }
70
+ plainPasteFilePath(data) {
71
+ if (data.length <= 1)
72
+ return null;
73
+ if (data.includes("\x1b"))
74
+ return null;
75
+ if (data.includes("\n") || data.includes("\r"))
76
+ return null;
77
+ return looksLikeFilePath(data);
78
+ }
79
+ isDuplicatePaste(kind, payload) {
80
+ const now = Date.now();
81
+ for (const [fingerprint, timestamp] of this.recentPasteFingerprints) {
82
+ if (now - timestamp > PASTE_DUPLICATE_WINDOW_MS)
83
+ this.recentPasteFingerprints.delete(fingerprint);
84
+ }
85
+ const normalizedPayload = kind === "text" ? normalizePastedTextForDuplicateKey(payload) : payload;
86
+ const fingerprint = `${kind}:${createHash("sha256").update(normalizedPayload).digest("hex")}`;
87
+ const previousTimestamp = this.recentPasteFingerprints.get(fingerprint);
88
+ if (previousTimestamp !== undefined && now - previousTimestamp <= PASTE_DUPLICATE_WINDOW_MS)
89
+ return true;
90
+ this.recentPasteFingerprints.set(fingerprint, now);
91
+ return false;
92
+ }
93
+ handlePasteEnd() {
94
+ const text = this.pasteBuffer;
95
+ this.pasteBuffer = "";
96
+ if (!text)
97
+ return;
98
+ const filePath = this.plainPasteFilePath(text);
99
+ if (filePath) {
100
+ if (isImagePath(filePath) && Date.now() < this.suppressImagePathPasteUntil) {
101
+ this.host.render();
102
+ return;
103
+ }
104
+ void this.handleFilePaste(filePath);
105
+ return;
106
+ }
107
+ if (this.isDuplicatePaste("text", text)) {
108
+ this.host.render();
109
+ return;
110
+ }
111
+ this.host.resetRequestHistoryNavigation();
112
+ this.host.inputEditor.attachPastedText(text);
113
+ this.host.render();
114
+ }
115
+ async handleFilePaste(filePath) {
116
+ const inputPath = await this.filePathForInput(filePath);
117
+ this.insertPastedPathText(inputPath);
118
+ this.host.render();
119
+ }
120
+ async filePathForInput(filePath) {
121
+ const resolved = resolve(this.host.cwd, filePath);
122
+ try {
123
+ const s = await stat(resolved);
124
+ if (s.isFile())
125
+ return this.displayPathForInput(resolved);
126
+ }
127
+ catch {
128
+ // The terminal can still paste a file-looking path before the file is
129
+ // visible to us. Insert the path text instead of trying to attach content.
130
+ }
131
+ return this.displayPathForInput(resolved);
132
+ }
133
+ displayPathForInput(resolvedPath) {
134
+ const cwd = resolve(this.host.cwd);
135
+ const rel = relative(cwd, resolvedPath);
136
+ if (rel && !rel.startsWith("..") && !isAbsolute(rel))
137
+ return rel;
138
+ return resolvedPath;
139
+ }
140
+ insertPastedPathText(filePath) {
141
+ if (this.isDuplicatePaste("text", filePath))
142
+ return;
143
+ this.host.resetRequestHistoryNavigation();
144
+ this.host.inputEditor.insert(quoteFilePathForInput(filePath));
145
+ }
146
+ }
@@ -0,0 +1,32 @@
1
+ import type { AgentSessionRuntime, SessionInfo } from "@earendil-works/pi-coding-agent";
2
+ import type { PopupMenuItem } from "../ui.js";
3
+ import type { Entry, ModelMenuValue, QueueMessageMenuValue, ResumeMenuValue, ScopedSessionModel, SessionModel, SlashCommand, ThinkingMenuValue, UserMessageJumpMenuValue, UserMessageMenuValue } from "./types.js";
4
+ export type AppMenuItemsControllerHost = {
5
+ runtime(): AgentSessionRuntime | undefined;
6
+ getBuiltinSlashCommands(): readonly SlashCommand[];
7
+ getEntries(): readonly Entry[];
8
+ getResumeSessions(): readonly SessionInfo[];
9
+ };
10
+ export declare class AppMenuItemsController {
11
+ private readonly host;
12
+ private resumeMenuLoaderCache;
13
+ constructor(host: AppMenuItemsControllerHost);
14
+ parseSlashInput(text: string): import("./types.js").ParsedSlashInput | undefined;
15
+ getResourceSlashCommands(): SlashCommand[];
16
+ getSlashCommandMatches(query: string, limit?: number): import("../fuzzy.js").FuzzyMatch<SlashCommand>[];
17
+ getSlashCommandMenuItems(query: string): PopupMenuItem<SlashCommand>[];
18
+ modelRef(model: SessionModel): string;
19
+ getFavoriteScopedModels(): ScopedSessionModel[];
20
+ getModelMenuItems(query: string): PopupMenuItem<ModelMenuValue>[];
21
+ getThinkingMenuItems(query: string): PopupMenuItem<ThinkingMenuValue>[];
22
+ getUserMessageMenuItems(): PopupMenuItem<UserMessageMenuValue>[];
23
+ getUserMessageJumpMenuItems(query: string): PopupMenuItem<UserMessageJumpMenuValue>[];
24
+ getQueueMessageMenuItems(): PopupMenuItem<QueueMessageMenuValue>[];
25
+ getResumeMenuItems(query: string, limit?: number): PopupMenuItem<ResumeMenuValue>[];
26
+ private getResumeMenuItemsLoader;
27
+ private getAllSlashCommands;
28
+ private isCurrentModel;
29
+ private resolveScopedModelRefs;
30
+ private getModelMenuModels;
31
+ private thinkingLevelDescription;
32
+ }