@ashx-j/lunr-dev 0.2.13-dev.8.1 → 0.2.19-dev.10.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 (484) hide show
  1. package/CHANGELOG.md +60 -1
  2. package/README.md +7 -1
  3. package/dist/builtin-extensions/ashxj-thinking.d.ts +1 -0
  4. package/dist/builtin-extensions/ashxj-thinking.d.ts.map +1 -1
  5. package/dist/builtin-extensions/ashxj-thinking.js +44 -19
  6. package/dist/builtin-extensions/ashxj-thinking.js.map +1 -1
  7. package/dist/builtin-extensions/ashxj-tui.d.ts +14 -0
  8. package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
  9. package/dist/builtin-extensions/ashxj-tui.js +37 -3
  10. package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
  11. package/dist/builtin-extensions/index.d.ts +1 -15
  12. package/dist/builtin-extensions/index.d.ts.map +1 -1
  13. package/dist/builtin-extensions/index.js +8 -21
  14. package/dist/builtin-extensions/index.js.map +1 -1
  15. package/dist/builtin-extensions/lunr-computer-use.d.ts +3 -0
  16. package/dist/builtin-extensions/lunr-computer-use.d.ts.map +1 -0
  17. package/dist/builtin-extensions/lunr-computer-use.js +157 -0
  18. package/dist/builtin-extensions/lunr-computer-use.js.map +1 -0
  19. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.d.ts.map +1 -1
  20. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js +6 -2
  21. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js.map +1 -1
  22. package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts +4 -0
  23. package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts.map +1 -1
  24. package/dist/builtin-extensions/pi-lsp-extension/src/index.js +172 -171
  25. package/dist/builtin-extensions/pi-lsp-extension/src/index.js.map +1 -1
  26. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.d.ts +50 -0
  27. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.d.ts.map +1 -0
  28. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.js +131 -0
  29. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.js.map +1 -0
  30. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.d.ts +7 -0
  31. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.d.ts.map +1 -0
  32. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js +211 -0
  33. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js.map +1 -0
  34. package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.d.ts +0 -5
  35. package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.d.ts.map +1 -1
  36. package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.js +0 -202
  37. package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.js.map +1 -1
  38. package/dist/builtin-extensions/pi-mcp-adapter/index.d.ts.map +1 -1
  39. package/dist/builtin-extensions/pi-mcp-adapter/index.js +276 -109
  40. package/dist/builtin-extensions/pi-mcp-adapter/index.js.map +1 -1
  41. package/dist/builtin-extensions/pi-mcp-adapter/init.d.ts +4 -1
  42. package/dist/builtin-extensions/pi-mcp-adapter/init.d.ts.map +1 -1
  43. package/dist/builtin-extensions/pi-mcp-adapter/init.js +10 -3
  44. package/dist/builtin-extensions/pi-mcp-adapter/init.js.map +1 -1
  45. package/dist/builtin-extensions/pi-mcp-adapter/metadata-cache.d.ts.map +1 -1
  46. package/dist/builtin-extensions/pi-mcp-adapter/metadata-cache.js +6 -1
  47. package/dist/builtin-extensions/pi-mcp-adapter/metadata-cache.js.map +1 -1
  48. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts +6 -1
  49. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts.map +1 -1
  50. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js +33 -8
  51. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js.map +1 -1
  52. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts.map +1 -1
  53. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js +2 -1
  54. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js.map +1 -1
  55. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.d.ts +1 -1
  56. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.d.ts.map +1 -1
  57. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js +1 -1
  58. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js.map +1 -1
  59. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts +1 -1
  60. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  61. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +68 -15
  62. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  63. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
  64. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +6 -2
  65. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
  66. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts +1 -1
  67. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts.map +1 -1
  68. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js +5 -2
  69. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js.map +1 -1
  70. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.d.ts +10 -0
  71. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.d.ts.map +1 -0
  72. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.js +38 -0
  73. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.js.map +1 -0
  74. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  75. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +3 -16
  76. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
  77. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts +1 -1
  78. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts.map +1 -1
  79. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js +2 -0
  80. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js.map +1 -1
  81. package/dist/builtin-extensions/pi-subagents/src/shared/fork-context.d.ts.map +1 -1
  82. package/dist/builtin-extensions/pi-subagents/src/shared/fork-context.js +1 -1
  83. package/dist/builtin-extensions/pi-subagents/src/shared/fork-context.js.map +1 -1
  84. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts +1 -1
  85. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
  86. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +1 -1
  87. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
  88. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +2 -1
  89. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  90. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +72 -31
  91. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  92. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.d.ts +1 -1
  93. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.d.ts.map +1 -1
  94. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js +2 -1
  95. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js.map +1 -1
  96. package/dist/builtin-extensions/pi-web-access/extract.d.ts.map +1 -1
  97. package/dist/builtin-extensions/pi-web-access/extract.js +105 -54
  98. package/dist/builtin-extensions/pi-web-access/extract.js.map +1 -1
  99. package/dist/builtin-extensions/pi-web-access/gemini-search.d.ts +1 -1
  100. package/dist/builtin-extensions/pi-web-access/gemini-search.d.ts.map +1 -1
  101. package/dist/builtin-extensions/pi-web-access/gemini-search.js +82 -65
  102. package/dist/builtin-extensions/pi-web-access/gemini-search.js.map +1 -1
  103. package/dist/builtin-extensions/pi-web-access/github-extract.d.ts.map +1 -1
  104. package/dist/builtin-extensions/pi-web-access/github-extract.js +2 -0
  105. package/dist/builtin-extensions/pi-web-access/github-extract.js.map +1 -1
  106. package/dist/builtin-extensions/pi-web-access/index.d.ts.map +1 -1
  107. package/dist/builtin-extensions/pi-web-access/index.js +259 -168
  108. package/dist/builtin-extensions/pi-web-access/index.js.map +1 -1
  109. package/dist/builtin-extensions/pi-web-access/lazy.d.ts +18 -0
  110. package/dist/builtin-extensions/pi-web-access/lazy.d.ts.map +1 -0
  111. package/dist/builtin-extensions/pi-web-access/lazy.js +19 -0
  112. package/dist/builtin-extensions/pi-web-access/lazy.js.map +1 -0
  113. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts +6 -0
  114. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts.map +1 -0
  115. package/dist/builtin-extensions/pi-web-access/session-cleanup.js +17 -0
  116. package/dist/builtin-extensions/pi-web-access/session-cleanup.js.map +1 -0
  117. package/dist/catalog/publication.json +12 -12
  118. package/dist/cli-runtime.d.ts +3 -0
  119. package/dist/cli-runtime.d.ts.map +1 -0
  120. package/dist/cli-runtime.js +73 -0
  121. package/dist/cli-runtime.js.map +1 -0
  122. package/dist/cli.d.ts.map +1 -1
  123. package/dist/cli.js +14 -53
  124. package/dist/cli.js.map +1 -1
  125. package/dist/config.d.ts +1 -0
  126. package/dist/config.d.ts.map +1 -1
  127. package/dist/config.js +1 -0
  128. package/dist/config.js.map +1 -1
  129. package/dist/core/agent-session-services.d.ts.map +1 -1
  130. package/dist/core/agent-session-services.js +1 -1
  131. package/dist/core/agent-session-services.js.map +1 -1
  132. package/dist/core/agent-session.d.ts +3 -0
  133. package/dist/core/agent-session.d.ts.map +1 -1
  134. package/dist/core/agent-session.js +56 -12
  135. package/dist/core/agent-session.js.map +1 -1
  136. package/dist/core/compaction/compaction.d.ts.map +1 -1
  137. package/dist/core/compaction/compaction.js +10 -5
  138. package/dist/core/compaction/compaction.js.map +1 -1
  139. package/dist/core/computer-use/adapter.d.ts +23 -0
  140. package/dist/core/computer-use/adapter.d.ts.map +1 -0
  141. package/dist/core/computer-use/adapter.js +116 -0
  142. package/dist/core/computer-use/adapter.js.map +1 -0
  143. package/dist/core/computer-use/lease.d.ts +18 -0
  144. package/dist/core/computer-use/lease.d.ts.map +1 -0
  145. package/dist/core/computer-use/lease.js +129 -0
  146. package/dist/core/computer-use/lease.js.map +1 -0
  147. package/dist/core/computer-use/macos-runtime.d.ts +14 -0
  148. package/dist/core/computer-use/macos-runtime.d.ts.map +1 -0
  149. package/dist/core/computer-use/macos-runtime.js +148 -0
  150. package/dist/core/computer-use/macos-runtime.js.map +1 -0
  151. package/dist/core/computer-use/policy.d.ts +19 -0
  152. package/dist/core/computer-use/policy.d.ts.map +1 -0
  153. package/dist/core/computer-use/policy.js +66 -0
  154. package/dist/core/computer-use/policy.js.map +1 -0
  155. package/dist/core/computer-use/release.generated.d.ts +31 -0
  156. package/dist/core/computer-use/release.generated.d.ts.map +1 -0
  157. package/dist/core/computer-use/release.generated.js +36 -0
  158. package/dist/core/computer-use/release.generated.js.map +1 -0
  159. package/dist/core/computer-use/runtime.d.ts +13 -0
  160. package/dist/core/computer-use/runtime.d.ts.map +1 -0
  161. package/dist/core/computer-use/runtime.js +158 -0
  162. package/dist/core/computer-use/runtime.js.map +1 -0
  163. package/dist/core/computer-use/schemas.d.ts +88 -0
  164. package/dist/core/computer-use/schemas.d.ts.map +1 -0
  165. package/dist/core/computer-use/schemas.js +80 -0
  166. package/dist/core/computer-use/schemas.js.map +1 -0
  167. package/dist/core/computer-use/windows-desktop.d.ts +3 -0
  168. package/dist/core/computer-use/windows-desktop.d.ts.map +1 -0
  169. package/dist/core/computer-use/windows-desktop.js +48 -0
  170. package/dist/core/computer-use/windows-desktop.js.map +1 -0
  171. package/dist/core/computer-use/workflow.d.ts +24 -0
  172. package/dist/core/computer-use/workflow.d.ts.map +1 -0
  173. package/dist/core/computer-use/workflow.js +330 -0
  174. package/dist/core/computer-use/workflow.js.map +1 -0
  175. package/dist/core/extensions/host-static.d.ts.map +1 -1
  176. package/dist/core/extensions/host-static.js +34 -12
  177. package/dist/core/extensions/host-static.js.map +1 -1
  178. package/dist/core/extensions/loader.d.ts +1 -2
  179. package/dist/core/extensions/loader.d.ts.map +1 -1
  180. package/dist/core/extensions/loader.js +10 -64
  181. package/dist/core/extensions/loader.js.map +1 -1
  182. package/dist/core/extensions/types.d.ts +2 -2
  183. package/dist/core/extensions/types.d.ts.map +1 -1
  184. package/dist/core/extensions/types.js.map +1 -1
  185. package/dist/core/footer-data-provider.d.ts.map +1 -1
  186. package/dist/core/footer-data-provider.js +2 -0
  187. package/dist/core/footer-data-provider.js.map +1 -1
  188. package/dist/core/keybindings.d.ts +2 -2
  189. package/dist/core/keybindings.d.ts.map +1 -1
  190. package/dist/core/keybindings.js +2 -2
  191. package/dist/core/keybindings.js.map +1 -1
  192. package/dist/core/model-runtime.d.ts +0 -3
  193. package/dist/core/model-runtime.d.ts.map +1 -1
  194. package/dist/core/model-runtime.js +1 -10
  195. package/dist/core/model-runtime.js.map +1 -1
  196. package/dist/core/package-manager.d.ts.map +1 -1
  197. package/dist/core/package-manager.js +1 -1
  198. package/dist/core/package-manager.js.map +1 -1
  199. package/dist/core/permissions.d.ts +1 -3
  200. package/dist/core/permissions.d.ts.map +1 -1
  201. package/dist/core/permissions.js +33 -25
  202. package/dist/core/permissions.js.map +1 -1
  203. package/dist/core/plan-mode.d.ts.map +1 -1
  204. package/dist/core/plan-mode.js +9 -0
  205. package/dist/core/plan-mode.js.map +1 -1
  206. package/dist/core/rollback.d.ts.map +1 -1
  207. package/dist/core/rollback.js +13 -90
  208. package/dist/core/rollback.js.map +1 -1
  209. package/dist/core/sdk.d.ts +1 -1
  210. package/dist/core/sdk.d.ts.map +1 -1
  211. package/dist/core/sdk.js +1 -1
  212. package/dist/core/sdk.js.map +1 -1
  213. package/dist/core/session-manager.d.ts +0 -1
  214. package/dist/core/session-manager.d.ts.map +1 -1
  215. package/dist/core/session-manager.js +21 -79
  216. package/dist/core/session-manager.js.map +1 -1
  217. package/dist/core/settings-manager.d.ts +6 -0
  218. package/dist/core/settings-manager.d.ts.map +1 -1
  219. package/dist/core/settings-manager.js +19 -0
  220. package/dist/core/settings-manager.js.map +1 -1
  221. package/dist/core/slash-commands.d.ts.map +1 -1
  222. package/dist/core/slash-commands.js +0 -1
  223. package/dist/core/slash-commands.js.map +1 -1
  224. package/dist/core/timings.d.ts +2 -1
  225. package/dist/core/timings.d.ts.map +1 -1
  226. package/dist/core/timings.js +17 -2
  227. package/dist/core/timings.js.map +1 -1
  228. package/dist/dev-cli.js +0 -0
  229. package/dist/gateway/agent-bridge.d.ts +6 -1
  230. package/dist/gateway/agent-bridge.d.ts.map +1 -1
  231. package/dist/gateway/agent-bridge.js +23 -6
  232. package/dist/gateway/agent-bridge.js.map +1 -1
  233. package/dist/gateway/commands.d.ts +1 -1
  234. package/dist/gateway/commands.d.ts.map +1 -1
  235. package/dist/gateway/commands.js +1 -18
  236. package/dist/gateway/commands.js.map +1 -1
  237. package/dist/gateway/cron.d.ts +1 -1
  238. package/dist/gateway/cron.d.ts.map +1 -1
  239. package/dist/gateway/cron.js +23 -7
  240. package/dist/gateway/cron.js.map +1 -1
  241. package/dist/main.d.ts +2 -2
  242. package/dist/main.d.ts.map +1 -1
  243. package/dist/main.js +57 -48
  244. package/dist/main.js.map +1 -1
  245. package/dist/modes/interactive/components/footer.d.ts +4 -2
  246. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  247. package/dist/modes/interactive/components/footer.js +23 -32
  248. package/dist/modes/interactive/components/footer.js.map +1 -1
  249. package/dist/modes/interactive/components/processes-selector.d.ts +2 -3
  250. package/dist/modes/interactive/components/processes-selector.d.ts.map +1 -1
  251. package/dist/modes/interactive/components/processes-selector.js +5 -10
  252. package/dist/modes/interactive/components/processes-selector.js.map +1 -1
  253. package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
  254. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  255. package/dist/modes/interactive/components/settings-selector.js +20 -0
  256. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  257. package/dist/modes/interactive/interactive-mode.d.ts +12 -21
  258. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  259. package/dist/modes/interactive/interactive-mode.js +138 -152
  260. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  261. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  262. package/dist/modes/interactive/theme/theme.js +95 -84
  263. package/dist/modes/interactive/theme/theme.js.map +1 -1
  264. package/dist/modes/interactive/thinking-level-slash.d.ts +4 -0
  265. package/dist/modes/interactive/thinking-level-slash.d.ts.map +1 -0
  266. package/dist/modes/interactive/thinking-level-slash.js +23 -0
  267. package/dist/modes/interactive/thinking-level-slash.js.map +1 -0
  268. package/dist/node-runtime/adapter-AZMY335J.js +279 -0
  269. package/dist/node-runtime/agent-session-services-RSGP5GDN.js +39 -0
  270. package/dist/node-runtime/benchmark-request-UC7PD3V3.js +57 -0
  271. package/dist/node-runtime/brave-UWDA3I22.js +143 -0
  272. package/dist/node-runtime/builtin-extensions-7STLFW3A.js +29 -0
  273. package/dist/node-runtime/chunk-2IDTZAG5.js +1415 -0
  274. package/dist/node-runtime/chunk-3GHXVUAK.js +21 -0
  275. package/dist/node-runtime/chunk-3RCWXWAY.js +466 -0
  276. package/dist/node-runtime/chunk-3WFAEVKS.js +115 -0
  277. package/dist/node-runtime/chunk-3X3KZKMI.js +49 -0
  278. package/dist/node-runtime/chunk-4HXHDDCF.js +16 -0
  279. package/dist/node-runtime/chunk-4SJWFTUP.js +24 -0
  280. package/dist/node-runtime/chunk-4ZWGEEAS.js +69 -0
  281. package/dist/node-runtime/chunk-53YJI7JU.js +137 -0
  282. package/dist/node-runtime/chunk-5NWQCSKR.js +19218 -0
  283. package/dist/node-runtime/chunk-5OLJGVCB.js +68 -0
  284. package/dist/node-runtime/chunk-5Q45AVQG.js +108 -0
  285. package/dist/node-runtime/chunk-5SQDLSZJ.js +949 -0
  286. package/dist/node-runtime/chunk-6SPPH4FY.js +1269 -0
  287. package/dist/node-runtime/chunk-6UB6NKA3.js +860 -0
  288. package/dist/node-runtime/chunk-7AFOFSDY.js +105 -0
  289. package/dist/node-runtime/chunk-7N3YHTYF.js +26 -0
  290. package/dist/node-runtime/chunk-ARC4KOTI.js +11178 -0
  291. package/dist/node-runtime/chunk-AUXVGBO4.js +19 -0
  292. package/dist/node-runtime/chunk-AY6CAJSL.js +30 -0
  293. package/dist/node-runtime/chunk-BHO7O6E5.js +296 -0
  294. package/dist/node-runtime/chunk-BI3DHYCN.js +8845 -0
  295. package/dist/node-runtime/chunk-BKAZ6BKX.js +2185 -0
  296. package/dist/node-runtime/chunk-BR7YDUKA.js +109 -0
  297. package/dist/node-runtime/chunk-BRJX2PRC.js +53 -0
  298. package/dist/node-runtime/chunk-C4O2RSQQ.js +37 -0
  299. package/dist/node-runtime/chunk-CCZJ3PYY.js +17 -0
  300. package/dist/node-runtime/chunk-CGBXPL3E.js +1171 -0
  301. package/dist/node-runtime/chunk-CH6OL6P2.js +295 -0
  302. package/dist/node-runtime/chunk-CJECDQKP.js +19 -0
  303. package/dist/node-runtime/chunk-DAPBPCBP.js +53 -0
  304. package/dist/node-runtime/chunk-DDGMHUOW.js +305 -0
  305. package/dist/node-runtime/chunk-DMMTJQMQ.js +43 -0
  306. package/dist/node-runtime/chunk-DVGWF6A2.js +1180 -0
  307. package/dist/node-runtime/chunk-EH2LJQPM.js +64 -0
  308. package/dist/node-runtime/chunk-EHMBW7FA.js +772 -0
  309. package/dist/node-runtime/chunk-FLYMHKCS.js +966 -0
  310. package/dist/node-runtime/chunk-FVDOXRUD.js +96 -0
  311. package/dist/node-runtime/chunk-GZQHMEWL.js +126 -0
  312. package/dist/node-runtime/chunk-H2EOZYMP.js +57 -0
  313. package/dist/node-runtime/chunk-HQCKFM2O.js +56 -0
  314. package/dist/node-runtime/chunk-HRS4HMDX.js +610 -0
  315. package/dist/node-runtime/chunk-HYHJIRDW.js +19 -0
  316. package/dist/node-runtime/chunk-I6R76AG7.js +22 -0
  317. package/dist/node-runtime/chunk-ISQDQIZN.js +296 -0
  318. package/dist/node-runtime/chunk-J7QGQD45.js +24921 -0
  319. package/dist/node-runtime/chunk-JHYKXIMM.js +378 -0
  320. package/dist/node-runtime/chunk-JT6YCS5B.js +5648 -0
  321. package/dist/node-runtime/chunk-JZHEUQRL.js +180 -0
  322. package/dist/node-runtime/chunk-K72NVGUB.js +2834 -0
  323. package/dist/node-runtime/chunk-KKSIVROT.js +88 -0
  324. package/dist/node-runtime/chunk-LCACDWHJ.js +1743 -0
  325. package/dist/node-runtime/chunk-LTXUQJI4.js +173 -0
  326. package/dist/node-runtime/chunk-LWJXTA6Z.js +6814 -0
  327. package/dist/node-runtime/chunk-M3LZLQW2.js +98 -0
  328. package/dist/node-runtime/chunk-MGSB2C3M.js +46 -0
  329. package/dist/node-runtime/chunk-MGWCVY6Y.js +47 -0
  330. package/dist/node-runtime/chunk-MJQDX3BA.js +72 -0
  331. package/dist/node-runtime/chunk-MUMMMTW4.js +8392 -0
  332. package/dist/node-runtime/chunk-MX3GJNXJ.js +986 -0
  333. package/dist/node-runtime/chunk-NUIFPZWX.js +209 -0
  334. package/dist/node-runtime/chunk-OBMWP3I5.js +68 -0
  335. package/dist/node-runtime/chunk-OR4L3IB2.js +42 -0
  336. package/dist/node-runtime/chunk-OTT6JMPU.js +807 -0
  337. package/dist/node-runtime/chunk-PCIGF2XK.js +250 -0
  338. package/dist/node-runtime/chunk-PL6JKXWI.js +3622 -0
  339. package/dist/node-runtime/chunk-PVCDKGR6.js +55 -0
  340. package/dist/node-runtime/chunk-Q4Q6D4IY.js +364 -0
  341. package/dist/node-runtime/chunk-Q5ZU2VRT.js +83 -0
  342. package/dist/node-runtime/chunk-QFWG2RVL.js +5477 -0
  343. package/dist/node-runtime/chunk-RQ2Q5IYR.js +72 -0
  344. package/dist/node-runtime/chunk-RQ5DNUNG.js +429 -0
  345. package/dist/node-runtime/chunk-RRIZE6QQ.js +17 -0
  346. package/dist/node-runtime/chunk-SN6G4OU6.js +4753 -0
  347. package/dist/node-runtime/chunk-SWSN6HAB.js +53 -0
  348. package/dist/node-runtime/chunk-T5GM5BFH.js +7558 -0
  349. package/dist/node-runtime/chunk-TAP7QTUT.js +1346 -0
  350. package/dist/node-runtime/chunk-U6C7VTR5.js +2033 -0
  351. package/dist/node-runtime/chunk-URD2SLIT.js +1019 -0
  352. package/dist/node-runtime/chunk-VRB2IYGG.js +53 -0
  353. package/dist/node-runtime/chunk-W3CVH5RX.js +62 -0
  354. package/dist/node-runtime/chunk-W7S2REEG.js +9478 -0
  355. package/dist/node-runtime/chunk-XBWPBZBN.js +125 -0
  356. package/dist/node-runtime/chunk-XTHQ7XR7.js +509 -0
  357. package/dist/node-runtime/chunk-ZCHMJ34K.js +130 -0
  358. package/dist/node-runtime/chunk-ZRDIMBEQ.js +651 -0
  359. package/dist/node-runtime/chunk-ZSEZY3II.js +247 -0
  360. package/dist/node-runtime/cli-runtime.js +81 -0
  361. package/dist/node-runtime/clipboard-OZ63BBC6.js +12 -0
  362. package/dist/node-runtime/clipboard-image-7QR6GXVA.js +13 -0
  363. package/dist/node-runtime/command-6UXQ6XZN.js +13 -0
  364. package/dist/node-runtime/commands-LGR5VT5X.js +293 -0
  365. package/dist/node-runtime/config-FMEOZSWE.js +77 -0
  366. package/dist/node-runtime/curator-server-XCM43VEF.js +3816 -0
  367. package/dist/node-runtime/customize-XEXL2DGQ.js +12 -0
  368. package/dist/node-runtime/direct-tool-executor-TDJS7TBD.js +191 -0
  369. package/dist/node-runtime/exa-LL64QZR2.js +329 -0
  370. package/dist/node-runtime/export-html-E4DT6ZJQ.js +150 -0
  371. package/dist/node-runtime/extension-input-RV5N6APL.js +14 -0
  372. package/dist/node-runtime/extension-selector-CPD5LWDD.js +14 -0
  373. package/dist/node-runtime/extract-IUCVZCWC.js +17 -0
  374. package/dist/node-runtime/file-sync-HCOP2QVF.js +117 -0
  375. package/dist/node-runtime/gateway-3OLC4GQN.js +2139 -0
  376. package/dist/node-runtime/gemini-api-QE7ANVDZ.js +29 -0
  377. package/dist/node-runtime/gemini-search-NCIDF7NE.js +330 -0
  378. package/dist/node-runtime/gemini-url-context-OKIN7AIP.js +103 -0
  379. package/dist/node-runtime/gemini-web-MM446SEH.js +14 -0
  380. package/dist/node-runtime/github-extract-F64RZOEA.js +619 -0
  381. package/dist/node-runtime/goal-CZQ7FFQJ.js +1831 -0
  382. package/dist/node-runtime/image-resize-6ZPBFMWW.js +11 -0
  383. package/dist/node-runtime/index.js +863 -0
  384. package/dist/node-runtime/init-EKE277AG.js +30 -0
  385. package/dist/node-runtime/install-cli-TH7IJJQQ.js +308 -0
  386. package/dist/node-runtime/interactive-mode-S5M26CQ7.js +59 -0
  387. package/dist/node-runtime/interactive-view-N6F4KUIT.js +247 -0
  388. package/dist/node-runtime/lsp-manager-3ASUSO4T.js +1104 -0
  389. package/dist/node-runtime/lunr-computer-use-4X3KUNF4.js +206 -0
  390. package/dist/node-runtime/lunr-cron-KKBOGAEF.js +274 -0
  391. package/dist/node-runtime/main.js +57 -0
  392. package/dist/node-runtime/mcp-auth-flow-YL6RWPYG.js +33 -0
  393. package/dist/node-runtime/mcp-panel-IIGMXQGP.js +501 -0
  394. package/dist/node-runtime/mcp-setup-panel-FEK7663I.js +355 -0
  395. package/dist/node-runtime/memory-cap-3S4XRLNP.js +20 -0
  396. package/dist/node-runtime/model-tiers-NJLHUEGK.js +20 -0
  397. package/dist/node-runtime/openai-search-B3MSNCQA.js +288 -0
  398. package/dist/node-runtime/package-manager-cli-C4EJOO5Q.js +751 -0
  399. package/dist/node-runtime/parallel-AI2MNSCU.js +265 -0
  400. package/dist/node-runtime/parser-manager-TQHWYDH7.js +152 -0
  401. package/dist/node-runtime/pdf-extract-IPE6H4HP.js +57 -0
  402. package/dist/node-runtime/perplexity-QVJW3I35.js +12 -0
  403. package/dist/node-runtime/pi-intercom-EEMBGQID.js +2215 -0
  404. package/dist/node-runtime/pi-mcp-adapter-DPTJGAAL.js +428 -0
  405. package/dist/node-runtime/pi-ollama-cloud-4VZRMULP.js +1440 -0
  406. package/dist/node-runtime/pi-prompt-template-model-4QT4LLXF.js +3946 -0
  407. package/dist/node-runtime/pi-subagents-VKCLYIBY.js +6050 -0
  408. package/dist/node-runtime/pi-web-access-BV6DSZOP.js +1867 -0
  409. package/dist/node-runtime/print-mode-VWIRFDAC.js +12 -0
  410. package/dist/node-runtime/proxy-modes-R64LU6WZ.js +688 -0
  411. package/dist/node-runtime/rpc-entry.js +65 -0
  412. package/dist/node-runtime/rpc-mode-SJNSOA4G.js +13 -0
  413. package/dist/node-runtime/runtime-3SB5ATHQ.js +21 -0
  414. package/dist/node-runtime/runtime-bridges-UJ5WJJLN.js +14 -0
  415. package/dist/node-runtime/session-manager-QEMZBMTM.js +33 -0
  416. package/dist/node-runtime/session-selector-URVJLOTK.js +14 -0
  417. package/dist/node-runtime/settings-manager-K6IPIQTI.js +23 -0
  418. package/dist/node-runtime/src-GPFAU3N6.js +2427 -0
  419. package/dist/node-runtime/subagent-executor-EFLTO32A.js +8501 -0
  420. package/dist/node-runtime/summary-review-YSMXKITO.js +228 -0
  421. package/dist/node-runtime/tavily-WEZFVFP7.js +154 -0
  422. package/dist/node-runtime/timings-UAD5BEAS.js +16 -0
  423. package/dist/node-runtime/tool-renderer-MV5O452K.js +204 -0
  424. package/dist/node-runtime/update-cli-I6OVDRPL.js +75 -0
  425. package/dist/node-runtime/v4-5MNC3H7G.js +424 -0
  426. package/dist/node-runtime/video-extract-ETA5RA7U.js +304 -0
  427. package/dist/node-runtime/workflow-SA34S4VX.js +325 -0
  428. package/dist/node-runtime/workspace-index-6DBXSTJ6.js +163 -0
  429. package/dist/node-runtime/youtube-extract-SRVGNN26.js +264 -0
  430. package/dist/rpc.d.ts +3 -0
  431. package/dist/rpc.d.ts.map +1 -0
  432. package/dist/rpc.js +18 -0
  433. package/dist/rpc.js.map +1 -0
  434. package/dist/startup/benchmark-request.d.ts +3 -0
  435. package/dist/startup/benchmark-request.d.ts.map +1 -0
  436. package/dist/startup/benchmark-request.js +65 -0
  437. package/dist/startup/benchmark-request.js.map +1 -0
  438. package/dist/startup/{interactive-shell.d.ts → interactive-view.d.ts} +18 -18
  439. package/dist/startup/interactive-view.d.ts.map +1 -0
  440. package/dist/startup/{interactive-shell.js → interactive-view.js} +119 -52
  441. package/dist/startup/interactive-view.js.map +1 -0
  442. package/dist/startup/launch-routing.d.ts.map +1 -1
  443. package/dist/startup/launch-routing.js +9 -10
  444. package/dist/startup/launch-routing.js.map +1 -1
  445. package/dist/startup/startup-milestones.d.ts +1 -1
  446. package/dist/startup/startup-milestones.d.ts.map +1 -1
  447. package/dist/startup/startup-milestones.js +3 -2
  448. package/dist/startup/startup-milestones.js.map +1 -1
  449. package/dist/utils/await-with-abort.d.ts +2 -0
  450. package/dist/utils/await-with-abort.d.ts.map +1 -0
  451. package/dist/utils/await-with-abort.js +19 -0
  452. package/dist/utils/await-with-abort.js.map +1 -0
  453. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  454. package/dist/utils/syntax-highlight.js +10 -4
  455. package/dist/utils/syntax-highlight.js.map +1 -1
  456. package/docs/compaction.md +5 -3
  457. package/docs/computer-use.md +277 -0
  458. package/docs/development.md +5 -33
  459. package/docs/features.md +2 -3
  460. package/docs/interactive-startup.md +105 -0
  461. package/docs/keybindings.md +2 -2
  462. package/docs/terminal-setup.md +1 -1
  463. package/docs/usage.md +1 -2
  464. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  465. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  466. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  467. package/examples/extensions/gondolin/package-lock.json +2 -2
  468. package/examples/extensions/gondolin/package.json +1 -1
  469. package/examples/extensions/hidden-thinking-label.ts +1 -1
  470. package/examples/extensions/sandbox/package-lock.json +2 -2
  471. package/examples/extensions/sandbox/package.json +1 -1
  472. package/examples/extensions/with-deps/package-lock.json +2 -2
  473. package/examples/extensions/with-deps/package.json +1 -1
  474. package/install-lock/package-lock.json +3827 -0
  475. package/install-lock/package.json +18 -0
  476. package/native/computer-use/LICENSE.md +21 -0
  477. package/npm-shrinkwrap.json +3808 -0
  478. package/package.json +30 -24
  479. package/dist/core/swarm.d.ts +0 -23
  480. package/dist/core/swarm.d.ts.map +0 -1
  481. package/dist/core/swarm.js +0 -45
  482. package/dist/core/swarm.js.map +0 -1
  483. package/dist/startup/interactive-shell.d.ts.map +0 -1
  484. package/dist/startup/interactive-shell.js.map +0 -1
@@ -0,0 +1,264 @@
1
+ import { createRequire as __lunrRequire } from "node:module"; const require = __lunrRequire(import.meta.url);
2
+ import {
3
+ isGeminiWebAvailable,
4
+ queryWithCookies
5
+ } from "./chunk-XTHQ7XR7.js";
6
+ import "./chunk-DMMTJQMQ.js";
7
+ import {
8
+ isGeminiApiAvailable,
9
+ queryGeminiApiWithVideo
10
+ } from "./chunk-3WFAEVKS.js";
11
+ import {
12
+ isPerplexityAvailable,
13
+ searchWithPerplexity
14
+ } from "./chunk-XBWPBZBN.js";
15
+ import {
16
+ extractHeadingTitle
17
+ } from "./chunk-J7QGQD45.js";
18
+ import "./chunk-4SJWFTUP.js";
19
+ import {
20
+ activityMonitor
21
+ } from "./chunk-DAPBPCBP.js";
22
+ import {
23
+ formatSeconds,
24
+ getWebSearchConfigPath,
25
+ isTimeoutError,
26
+ mapFfmpegError,
27
+ readExecError,
28
+ trimErrorText
29
+ } from "./chunk-VRB2IYGG.js";
30
+ import "./chunk-BRJX2PRC.js";
31
+
32
+ // packages/coding-agent/dist/builtin-extensions/pi-web-access/youtube-extract.js
33
+ import { execFileSync } from "node:child_process";
34
+ import { existsSync, readFileSync } from "node:fs";
35
+ var CONFIG_PATH = getWebSearchConfigPath(), YOUTUBE_PROMPT = `Extract the complete content of this YouTube video. Include:
36
+ 1. Video title, channel name, and duration
37
+ 2. A brief summary (2-3 sentences)
38
+ 3. Full transcript with timestamps
39
+ 4. Descriptions of any code, terminal commands, diagrams, slides, or UI shown on screen
40
+
41
+ Format as markdown.`, YOUTUBE_REGEX = /(?:(?:www\.|m\.)?youtube\.com\/(?:watch\?.*v=|shorts\/|live\/|embed\/|v\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})/;
42
+ function errorMessage(err) {
43
+ return err instanceof Error ? err.message : String(err);
44
+ }
45
+ function shouldRethrow(err) {
46
+ return errorMessage(err).startsWith("Failed to parse ");
47
+ }
48
+ function addAttemptError(errors, label, err) {
49
+ let message = errorMessage(err).replace(/\s+/g, " ").trim();
50
+ message && errors.push(`${label}: ${message}`);
51
+ }
52
+ function normalizePreferredModel(value, fallback) {
53
+ if (typeof value != "string")
54
+ return fallback;
55
+ let normalized = value.trim();
56
+ return normalized.length > 0 ? normalized : fallback;
57
+ }
58
+ function normalizeEnabled(value, fallback) {
59
+ return typeof value == "boolean" ? value : fallback;
60
+ }
61
+ var defaults = { enabled: !0, preferredModel: "gemini-3-flash-preview" }, cachedConfig = null;
62
+ function loadYouTubeConfig() {
63
+ if (cachedConfig)
64
+ return cachedConfig;
65
+ if (!existsSync(CONFIG_PATH))
66
+ return cachedConfig = { ...defaults }, cachedConfig;
67
+ let rawText = readFileSync(CONFIG_PATH, "utf-8"), raw;
68
+ try {
69
+ raw = JSON.parse(rawText);
70
+ } catch (err) {
71
+ let message = err instanceof Error ? err.message : String(err);
72
+ throw new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);
73
+ }
74
+ let yt = raw.youtube ?? {};
75
+ return cachedConfig = {
76
+ enabled: normalizeEnabled(yt.enabled, defaults.enabled),
77
+ preferredModel: normalizePreferredModel(yt.preferredModel, defaults.preferredModel)
78
+ }, cachedConfig;
79
+ }
80
+ function isYouTubeURL(url) {
81
+ try {
82
+ if (new URL(url).pathname === "/playlist")
83
+ return { isYouTube: !1, videoId: null };
84
+ } catch {
85
+ }
86
+ let match = url.match(YOUTUBE_REGEX);
87
+ return match ? { isYouTube: !0, videoId: match[1] } : { isYouTube: !1, videoId: null };
88
+ }
89
+ function isYouTubeEnabled() {
90
+ return loadYouTubeConfig().enabled;
91
+ }
92
+ async function extractYouTube(url, signal, prompt, model) {
93
+ let config = loadYouTubeConfig(), { videoId } = isYouTubeURL(url), canonicalUrl = videoId ? `https://www.youtube.com/watch?v=${videoId}` : url, effectivePrompt = prompt ?? YOUTUBE_PROMPT, effectiveModel = model ?? config.preferredModel, activityId = activityMonitor.logStart({ type: "fetch", url: `youtube.com/${videoId ?? "video"}` }), attemptErrors = [], result = await tryGeminiWeb(canonicalUrl, effectivePrompt, effectiveModel, signal, attemptErrors) ?? await tryGeminiApi(canonicalUrl, effectivePrompt, effectiveModel, signal, attemptErrors) ?? await tryPerplexity(url, effectivePrompt, signal, attemptErrors);
94
+ if (result) {
95
+ if (result.url = url, !result.error && videoId) {
96
+ let thumb = await fetchYouTubeThumbnail(videoId);
97
+ thumb && (result.thumbnail = thumb);
98
+ }
99
+ return activityMonitor.logComplete(activityId, result.error ? 0 : 200), result;
100
+ }
101
+ if (signal?.aborted)
102
+ return activityMonitor.logComplete(activityId, 0), null;
103
+ let error = attemptErrors.length > 0 ? ["Could not extract YouTube video content.", "", ...attemptErrors.map((message) => `- ${message}`)].join(`
104
+ `) : "Could not extract YouTube video content. Sign into Google in Chrome for automatic access, or set GEMINI_API_KEY.";
105
+ return activityMonitor.logError(activityId, error), { url, title: "", content: "", error };
106
+ }
107
+ function mapYtDlpError(err) {
108
+ let { code, stderr, message } = readExecError(err);
109
+ if (code === "ENOENT")
110
+ return "yt-dlp is not installed. Install with: brew install yt-dlp";
111
+ if (isTimeoutError(err))
112
+ return "yt-dlp timed out fetching video info";
113
+ let lower = stderr.toLowerCase();
114
+ if (lower.includes("private"))
115
+ return "Video is private or unavailable";
116
+ if (lower.includes("sign in"))
117
+ return "Video is age-restricted and requires authentication";
118
+ if (lower.includes("not available"))
119
+ return "Video is unavailable in your region or has been removed";
120
+ if (lower.includes("live"))
121
+ return "Cannot extract frames from a live stream";
122
+ let snippet = trimErrorText(stderr || message);
123
+ return snippet ? `yt-dlp failed: ${snippet}` : "yt-dlp failed";
124
+ }
125
+ async function getYouTubeStreamInfo(videoId) {
126
+ try {
127
+ let lines = execFileSync("yt-dlp", [
128
+ "--print",
129
+ "duration",
130
+ "-g",
131
+ `https://www.youtube.com/watch?v=${videoId}`
132
+ ], { timeout: 15e3, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim().split(/\r?\n/), rawDuration = lines[0]?.trim(), streamUrl = lines[1]?.trim();
133
+ if (!streamUrl)
134
+ return { error: "yt-dlp failed: missing stream URL" };
135
+ let parsedDuration = rawDuration && rawDuration !== "NA" ? Number.parseFloat(rawDuration) : NaN, duration = Number.isFinite(parsedDuration) ? parsedDuration : null;
136
+ return { streamUrl, duration };
137
+ } catch (err) {
138
+ return { error: mapYtDlpError(err) };
139
+ }
140
+ }
141
+ async function extractFrameFromStream(streamUrl, seconds) {
142
+ try {
143
+ let buffer = execFileSync("ffmpeg", [
144
+ "-ss",
145
+ String(seconds),
146
+ "-i",
147
+ streamUrl,
148
+ "-frames:v",
149
+ "1",
150
+ "-f",
151
+ "image2pipe",
152
+ "-vcodec",
153
+ "mjpeg",
154
+ "pipe:1"
155
+ ], { maxBuffer: 5242880, timeout: 3e4, stdio: ["pipe", "pipe", "pipe"] });
156
+ return buffer.length === 0 ? { error: "ffmpeg failed: empty output" } : { data: buffer.toString("base64"), mimeType: "image/jpeg" };
157
+ } catch (err) {
158
+ return { error: mapFfmpegError(err) };
159
+ }
160
+ }
161
+ async function extractYouTubeFrame(videoId, seconds, streamInfo) {
162
+ let info = streamInfo ?? await getYouTubeStreamInfo(videoId);
163
+ return "error" in info ? info : extractFrameFromStream(info.streamUrl, seconds);
164
+ }
165
+ async function extractYouTubeFrames(videoId, timestamps, streamInfo) {
166
+ let info = streamInfo ?? await getYouTubeStreamInfo(videoId);
167
+ if ("error" in info)
168
+ return { frames: [], duration: null, error: info.error };
169
+ let results = await Promise.all(timestamps.map(async (t) => {
170
+ let frame = await extractFrameFromStream(info.streamUrl, t);
171
+ return "error" in frame ? { error: frame.error } : { ...frame, timestamp: formatSeconds(t) };
172
+ })), frames = results.filter((f) => "data" in f), errorResult = results.find((f) => "error" in f);
173
+ return { frames, duration: info.duration, error: frames.length === 0 && errorResult ? errorResult.error : null };
174
+ }
175
+ async function fetchYouTubeThumbnail(videoId) {
176
+ try {
177
+ let res = await fetch(`https://img.youtube.com/vi/${videoId}/hqdefault.jpg`, {
178
+ signal: AbortSignal.timeout(5e3)
179
+ });
180
+ if (!res.ok)
181
+ return null;
182
+ let buffer = Buffer.from(await res.arrayBuffer());
183
+ return buffer.length === 0 ? null : { data: buffer.toString("base64"), mimeType: "image/jpeg" };
184
+ } catch {
185
+ return null;
186
+ }
187
+ }
188
+ async function tryGeminiWeb(url, prompt, model, signal, attemptErrors) {
189
+ try {
190
+ let cookies = await isGeminiWebAvailable();
191
+ if (!cookies || signal?.aborted)
192
+ return null;
193
+ let text = await queryWithCookies(prompt, cookies, {
194
+ youtubeUrl: url,
195
+ model,
196
+ signal,
197
+ timeoutMs: 12e4
198
+ });
199
+ return {
200
+ url,
201
+ title: extractHeadingTitle(text) ?? "YouTube Video",
202
+ content: text,
203
+ error: null
204
+ };
205
+ } catch (err) {
206
+ if (shouldRethrow(err))
207
+ throw err;
208
+ return signal?.aborted || addAttemptError(attemptErrors, "Gemini Web", err), null;
209
+ }
210
+ }
211
+ async function tryGeminiApi(url, prompt, model, signal, attemptErrors) {
212
+ try {
213
+ if (!isGeminiApiAvailable() || signal?.aborted)
214
+ return null;
215
+ let text = await queryGeminiApiWithVideo(prompt, url, {
216
+ model,
217
+ signal,
218
+ timeoutMs: 12e4
219
+ });
220
+ return {
221
+ url,
222
+ title: extractHeadingTitle(text) ?? "YouTube Video",
223
+ content: text,
224
+ error: null
225
+ };
226
+ } catch (err) {
227
+ if (shouldRethrow(err))
228
+ throw err;
229
+ return signal?.aborted || addAttemptError(attemptErrors, "Gemini API", err), null;
230
+ }
231
+ }
232
+ async function tryPerplexity(url, prompt, signal, attemptErrors) {
233
+ try {
234
+ if (signal?.aborted || !isPerplexityAvailable())
235
+ return null;
236
+ let perplexityQuery = prompt === YOUTUBE_PROMPT ? `Summarize this YouTube video in detail: ${url}` : `${prompt} YouTube video: ${url}`, { answer } = await searchWithPerplexity(perplexityQuery, { signal });
237
+ if (!answer)
238
+ return null;
239
+ let content = `# Video Summary (via Perplexity)
240
+
241
+ ${answer}
242
+
243
+ *Full video understanding requires Gemini access. Set GEMINI_API_KEY or sign into Google in Chrome.*`;
244
+ return {
245
+ url,
246
+ title: "Video Summary (via Perplexity)",
247
+ content,
248
+ error: null
249
+ };
250
+ } catch (err) {
251
+ if (shouldRethrow(err))
252
+ throw err;
253
+ return signal?.aborted || addAttemptError(attemptErrors, "Perplexity", err), null;
254
+ }
255
+ }
256
+ export {
257
+ extractYouTube,
258
+ extractYouTubeFrame,
259
+ extractYouTubeFrames,
260
+ fetchYouTubeThumbnail,
261
+ getYouTubeStreamInfo,
262
+ isYouTubeEnabled,
263
+ isYouTubeURL
264
+ };
package/dist/rpc.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=rpc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env node\nimport { existsSync } from \"node:fs\";\n\nconst bundled = new URL(\"./node-runtime/rpc-entry.js\", import.meta.url);\nif (existsSync(bundled)) {\n\tawait import(bundled.href);\n} else {\n\tawait import(\"./rpc-entry.ts\");\n}\n"]}
package/dist/rpc.js ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
3
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
4
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
5
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
6
+ });
7
+ }
8
+ return path;
9
+ };
10
+ import { existsSync } from "node:fs";
11
+ const bundled = new URL("./node-runtime/rpc-entry.js", import.meta.url);
12
+ if (existsSync(bundled)) {
13
+ await import(__rewriteRelativeImportExtension(bundled.href));
14
+ }
15
+ else {
16
+ await import("./rpc-entry.js");
17
+ }
18
+ //# sourceMappingURL=rpc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc.js","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,6BAA6B,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;AACxE,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;IACzB,MAAM,MAAM,kCAAC,OAAO,CAAC,IAAI,EAAC,CAAC;AAC5B,CAAC;KAAM,CAAC;IACP,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAChC,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { existsSync } from \"node:fs\";\n\nconst bundled = new URL(\"./node-runtime/rpc-entry.js\", import.meta.url);\nif (existsSync(bundled)) {\n\tawait import(bundled.href);\n} else {\n\tawait import(\"./rpc-entry.ts\");\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import type { AgentSession } from "../core/agent-session.ts";
2
+ export declare function prepareBenchmarkRequest(session: AgentSession): () => Promise<void>;
3
+ //# sourceMappingURL=benchmark-request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"benchmark-request.d.ts","sourceRoot":"","sources":["../../src/startup/benchmark-request.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG7D,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAiElF","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { createFauxCore, fauxAssistantMessage, fauxToolCall } from \"@ashx-j/lunr-ai\";\nimport type { AgentSession } from \"../core/agent-session.ts\";\nimport { markStartupMilestone } from \"./startup-milestones.ts\";\n\nexport function prepareBenchmarkRequest(session: AgentSession): () => Promise<void> {\n\tsession.setSessionName(\"Startup benchmark\");\n\tconst faux = createFauxCore({ provider: \"lunr-startup-benchmark\" });\n\tconst toolUrl = process.env.PI_STARTUP_BENCHMARK_TOOL_URL;\n\tif (toolUrl && new URL(toolUrl).hostname !== \"127.0.0.1\") throw new Error(\"Startup tool fixture must be local\");\n\tconst requestedTool = process.env.PI_STARTUP_BENCHMARK_TOOL;\n\tlet toolCall = toolUrl ? fauxToolCall(\"fetch_content\", { url: toolUrl }) : undefined;\n\tif (requestedTool === \"mcp\") toolCall = fauxToolCall(\"mcp\", {});\n\telse if (requestedTool === \"subagent\") toolCall = fauxToolCall(\"subagent\", { action: \"status\", view: \"fleet\" });\n\telse if (requestedTool === \"lsp\") toolCall = fauxToolCall(\"code_overview\", { path: \".\" });\n\telse if (requestedTool) throw new Error(`Unknown startup fixture tool: ${requestedTool}`);\n\tfaux.setResponses([\n\t\t(context) => {\n\t\t\tmarkStartupMilestone(\"first_request_dispatched\");\n\t\t\tconst expected = session.agent.state.tools.map((tool) => tool.name).sort();\n\t\t\tconst actual = context.tools?.map((tool) => tool.name).sort() ?? [];\n\t\t\tif (JSON.stringify(actual) !== JSON.stringify(expected) || !context.systemPrompt) {\n\t\t\t\tthrow new Error(\"Startup request lost registered tools or instructions\");\n\t\t\t}\n\t\t\tconst toolSchemaHash = createHash(\"sha256\").update(JSON.stringify(context.tools)).digest(\"hex\");\n\t\t\tprocess.stderr.write(\n\t\t\t\t`LUNR_STARTUP_REQUEST ${JSON.stringify({ tools: actual, toolSchemaHash, hasSystemPrompt: true })}\\n`,\n\t\t\t);\n\t\t\treturn toolCall\n\t\t\t\t? fauxAssistantMessage([toolCall], { stopReason: \"toolUse\" })\n\t\t\t\t: fauxAssistantMessage(\"startup-request-ok\");\n\t\t},\n\t\t(context) => {\n\t\t\tconst result = context.messages.at(-1);\n\t\t\tif (\n\t\t\t\tresult?.role !== \"toolResult\" ||\n\t\t\t\tresult.isError ||\n\t\t\t\tresult.toolName !== toolCall?.name ||\n\t\t\t\t(toolUrl && !JSON.stringify(result.content).includes(\"This local article verifies\")) ||\n\t\t\t\t(requestedTool === \"lsp\" && !JSON.stringify(result.content).includes(\"increment\"))\n\t\t\t) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Startup tool ${toolCall?.name} did not complete its local fixture: ${JSON.stringify(result?.content)}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tmarkStartupMilestone(\"first_tool_completed\");\n\t\t\treturn fauxAssistantMessage(\"startup-request-ok\");\n\t\t},\n\t]);\n\tsession.modelRuntime.registerProvider(\"lunr-startup-benchmark\", {\n\t\tapi: faux.api,\n\t\tapiKey: \"local-benchmark-only\",\n\t\tmodels: faux.models,\n\t\tstreamSimple: faux.streamSimple,\n\t});\n\tsession.agent.state.model = faux.getModel();\n\treturn async () => {\n\t\tawait session.prompt(\n\t\t\ttoolCall ? \"Use the local startup fixture tool.\" : \"Reply with startup-request-ok. Do not use tools.\",\n\t\t);\n\t\tconst last = session.state.messages.at(-1);\n\t\tif (last?.role !== \"assistant\" || last.stopReason === \"error\" || faux.state.callCount !== (toolCall ? 2 : 1)) {\n\t\t\tconst error = new Error(\n\t\t\t\t`Startup benchmark did not complete its local provider request: ${last?.role === \"assistant\" ? (last.errorMessage ?? last.stopReason) : last?.role}, calls=${faux.state.callCount}`,\n\t\t\t);\n\t\t\tconsole.error(error.message);\n\t\t\tthrow error;\n\t\t}\n\t\tmarkStartupMilestone(\"first_response_completed\");\n\t};\n}\n"]}
@@ -0,0 +1,65 @@
1
+ import { createHash } from "node:crypto";
2
+ import { createFauxCore, fauxAssistantMessage, fauxToolCall } from "@ashx-j/lunr-ai";
3
+ import { markStartupMilestone } from "./startup-milestones.js";
4
+ export function prepareBenchmarkRequest(session) {
5
+ session.setSessionName("Startup benchmark");
6
+ const faux = createFauxCore({ provider: "lunr-startup-benchmark" });
7
+ const toolUrl = process.env.PI_STARTUP_BENCHMARK_TOOL_URL;
8
+ if (toolUrl && new URL(toolUrl).hostname !== "127.0.0.1")
9
+ throw new Error("Startup tool fixture must be local");
10
+ const requestedTool = process.env.PI_STARTUP_BENCHMARK_TOOL;
11
+ let toolCall = toolUrl ? fauxToolCall("fetch_content", { url: toolUrl }) : undefined;
12
+ if (requestedTool === "mcp")
13
+ toolCall = fauxToolCall("mcp", {});
14
+ else if (requestedTool === "subagent")
15
+ toolCall = fauxToolCall("subagent", { action: "status", view: "fleet" });
16
+ else if (requestedTool === "lsp")
17
+ toolCall = fauxToolCall("code_overview", { path: "." });
18
+ else if (requestedTool)
19
+ throw new Error(`Unknown startup fixture tool: ${requestedTool}`);
20
+ faux.setResponses([
21
+ (context) => {
22
+ markStartupMilestone("first_request_dispatched");
23
+ const expected = session.agent.state.tools.map((tool) => tool.name).sort();
24
+ const actual = context.tools?.map((tool) => tool.name).sort() ?? [];
25
+ if (JSON.stringify(actual) !== JSON.stringify(expected) || !context.systemPrompt) {
26
+ throw new Error("Startup request lost registered tools or instructions");
27
+ }
28
+ const toolSchemaHash = createHash("sha256").update(JSON.stringify(context.tools)).digest("hex");
29
+ process.stderr.write(`LUNR_STARTUP_REQUEST ${JSON.stringify({ tools: actual, toolSchemaHash, hasSystemPrompt: true })}\n`);
30
+ return toolCall
31
+ ? fauxAssistantMessage([toolCall], { stopReason: "toolUse" })
32
+ : fauxAssistantMessage("startup-request-ok");
33
+ },
34
+ (context) => {
35
+ const result = context.messages.at(-1);
36
+ if (result?.role !== "toolResult" ||
37
+ result.isError ||
38
+ result.toolName !== toolCall?.name ||
39
+ (toolUrl && !JSON.stringify(result.content).includes("This local article verifies")) ||
40
+ (requestedTool === "lsp" && !JSON.stringify(result.content).includes("increment"))) {
41
+ throw new Error(`Startup tool ${toolCall?.name} did not complete its local fixture: ${JSON.stringify(result?.content)}`);
42
+ }
43
+ markStartupMilestone("first_tool_completed");
44
+ return fauxAssistantMessage("startup-request-ok");
45
+ },
46
+ ]);
47
+ session.modelRuntime.registerProvider("lunr-startup-benchmark", {
48
+ api: faux.api,
49
+ apiKey: "local-benchmark-only",
50
+ models: faux.models,
51
+ streamSimple: faux.streamSimple,
52
+ });
53
+ session.agent.state.model = faux.getModel();
54
+ return async () => {
55
+ await session.prompt(toolCall ? "Use the local startup fixture tool." : "Reply with startup-request-ok. Do not use tools.");
56
+ const last = session.state.messages.at(-1);
57
+ if (last?.role !== "assistant" || last.stopReason === "error" || faux.state.callCount !== (toolCall ? 2 : 1)) {
58
+ const error = new Error(`Startup benchmark did not complete its local provider request: ${last?.role === "assistant" ? (last.errorMessage ?? last.stopReason) : last?.role}, calls=${faux.state.callCount}`);
59
+ console.error(error.message);
60
+ throw error;
61
+ }
62
+ markStartupMilestone("first_response_completed");
63
+ };
64
+ }
65
+ //# sourceMappingURL=benchmark-request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"benchmark-request.js","sourceRoot":"","sources":["../../src/startup/benchmark-request.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { createFauxCore, fauxAssistantMessage, fauxToolCall } from \"@ashx-j/lunr-ai\";\nimport type { AgentSession } from \"../core/agent-session.ts\";\nimport { markStartupMilestone } from \"./startup-milestones.ts\";\n\nexport function prepareBenchmarkRequest(session: AgentSession): () => Promise<void> {\n\tsession.setSessionName(\"Startup benchmark\");\n\tconst faux = createFauxCore({ provider: \"lunr-startup-benchmark\" });\n\tconst toolUrl = process.env.PI_STARTUP_BENCHMARK_TOOL_URL;\n\tif (toolUrl && new URL(toolUrl).hostname !== \"127.0.0.1\") throw new Error(\"Startup tool fixture must be local\");\n\tconst requestedTool = process.env.PI_STARTUP_BENCHMARK_TOOL;\n\tlet toolCall = toolUrl ? fauxToolCall(\"fetch_content\", { url: toolUrl }) : undefined;\n\tif (requestedTool === \"mcp\") toolCall = fauxToolCall(\"mcp\", {});\n\telse if (requestedTool === \"subagent\") toolCall = fauxToolCall(\"subagent\", { action: \"status\", view: \"fleet\" });\n\telse if (requestedTool === \"lsp\") toolCall = fauxToolCall(\"code_overview\", { path: \".\" });\n\telse if (requestedTool) throw new Error(`Unknown startup fixture tool: ${requestedTool}`);\n\tfaux.setResponses([\n\t\t(context) => {\n\t\t\tmarkStartupMilestone(\"first_request_dispatched\");\n\t\t\tconst expected = session.agent.state.tools.map((tool) => tool.name).sort();\n\t\t\tconst actual = context.tools?.map((tool) => tool.name).sort() ?? [];\n\t\t\tif (JSON.stringify(actual) !== JSON.stringify(expected) || !context.systemPrompt) {\n\t\t\t\tthrow new Error(\"Startup request lost registered tools or instructions\");\n\t\t\t}\n\t\t\tconst toolSchemaHash = createHash(\"sha256\").update(JSON.stringify(context.tools)).digest(\"hex\");\n\t\t\tprocess.stderr.write(\n\t\t\t\t`LUNR_STARTUP_REQUEST ${JSON.stringify({ tools: actual, toolSchemaHash, hasSystemPrompt: true })}\\n`,\n\t\t\t);\n\t\t\treturn toolCall\n\t\t\t\t? fauxAssistantMessage([toolCall], { stopReason: \"toolUse\" })\n\t\t\t\t: fauxAssistantMessage(\"startup-request-ok\");\n\t\t},\n\t\t(context) => {\n\t\t\tconst result = context.messages.at(-1);\n\t\t\tif (\n\t\t\t\tresult?.role !== \"toolResult\" ||\n\t\t\t\tresult.isError ||\n\t\t\t\tresult.toolName !== toolCall?.name ||\n\t\t\t\t(toolUrl && !JSON.stringify(result.content).includes(\"This local article verifies\")) ||\n\t\t\t\t(requestedTool === \"lsp\" && !JSON.stringify(result.content).includes(\"increment\"))\n\t\t\t) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Startup tool ${toolCall?.name} did not complete its local fixture: ${JSON.stringify(result?.content)}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tmarkStartupMilestone(\"first_tool_completed\");\n\t\t\treturn fauxAssistantMessage(\"startup-request-ok\");\n\t\t},\n\t]);\n\tsession.modelRuntime.registerProvider(\"lunr-startup-benchmark\", {\n\t\tapi: faux.api,\n\t\tapiKey: \"local-benchmark-only\",\n\t\tmodels: faux.models,\n\t\tstreamSimple: faux.streamSimple,\n\t});\n\tsession.agent.state.model = faux.getModel();\n\treturn async () => {\n\t\tawait session.prompt(\n\t\t\ttoolCall ? \"Use the local startup fixture tool.\" : \"Reply with startup-request-ok. Do not use tools.\",\n\t\t);\n\t\tconst last = session.state.messages.at(-1);\n\t\tif (last?.role !== \"assistant\" || last.stopReason === \"error\" || faux.state.callCount !== (toolCall ? 2 : 1)) {\n\t\t\tconst error = new Error(\n\t\t\t\t`Startup benchmark did not complete its local provider request: ${last?.role === \"assistant\" ? (last.errorMessage ?? last.stopReason) : last?.role}, calls=${faux.state.callCount}`,\n\t\t\t);\n\t\t\tconsole.error(error.message);\n\t\t\tthrow error;\n\t\t}\n\t\tmarkStartupMilestone(\"first_response_completed\");\n\t};\n}\n"]}
@@ -1,25 +1,20 @@
1
- import { type EditorImageAttachment, TUI } from "@ashx-j/lunr-tui";
1
+ import { type Component, Container, type EditorComponent, TUI } from "@ashx-j/lunr-tui";
2
+ import { getChatboxEditor } from "../builtin-extensions/ashxj-tui.ts";
2
3
  import { KeybindingsManager } from "../core/keybindings.ts";
3
4
  import type { SessionInfo, SessionListProgress } from "../core/session-manager.ts";
4
- import { CustomEditor } from "../modes/interactive/components/custom-editor.ts";
5
- export interface StartupShellSubmission {
6
- text: string;
7
- attachments: EditorImageAttachment[];
8
- }
9
- export interface InteractiveShellBinding {
10
- ui: TUI;
11
- editor: CustomEditor;
12
- keybindings: KeybindingsManager;
13
- pendingSubmissions: StartupShellSubmission[];
14
- }
15
5
  type SessionsLoader = (onProgress?: SessionListProgress) => Promise<SessionInfo[]>;
16
- export declare class InteractiveStartupShell {
6
+ export declare class InteractiveView {
17
7
  readonly ui: TUI;
18
- readonly editor: CustomEditor;
8
+ readonly editor: ReturnType<typeof getChatboxEditor>;
19
9
  readonly keybindings: KeybindingsManager;
20
- readonly pendingSubmissions: StartupShellSubmission[];
10
+ private submitRequested;
11
+ private inputUnsubscribe?;
12
+ private modalActive;
21
13
  private readonly terminal;
22
14
  private readonly status;
15
+ readonly header: Component;
16
+ readonly footer: Component;
17
+ readonly statusContainer: Container;
23
18
  private readonly editorContainer;
24
19
  private firstFramePromise;
25
20
  private resolveFirstFrame;
@@ -29,13 +24,18 @@ export declare class InteractiveStartupShell {
29
24
  private handedOff;
30
25
  private exitRequested;
31
26
  private lastClearAt;
27
+ private currentEditor;
32
28
  constructor();
33
29
  get isExitRequested(): boolean;
34
30
  start(): void;
35
31
  pause(): void;
36
32
  resume(): void;
37
33
  waitForFirstFrame(): Promise<void>;
38
- binding(): InteractiveShellBinding;
34
+ waitForExit(): Promise<void>;
35
+ binding(): InteractiveView;
36
+ setCurrentEditor(getEditor: () => EditorComponent): void;
37
+ /** Called only after the normal submit handler and all extensions are ready. */
38
+ activate(): void;
39
39
  showError(error: unknown): void;
40
40
  fail(error: unknown): Promise<void>;
41
41
  stop(): void;
@@ -47,9 +47,9 @@ export declare class InteractiveStartupShell {
47
47
  input(title: string, placeholder?: string): Promise<string | undefined>;
48
48
  selectSession(currentSessionsLoader: SessionsLoader, allSessionsLoader: SessionsLoader): Promise<string | null>;
49
49
  private showModal;
50
- private restoreShellLayout;
50
+ private restoreLayout;
51
51
  private installInputHandlers;
52
52
  private pasteClipboard;
53
53
  }
54
54
  export {};
55
- //# sourceMappingURL=interactive-shell.d.ts.map
55
+ //# sourceMappingURL=interactive-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive-view.d.ts","sourceRoot":"","sources":["../../src/startup/interactive-view.ts"],"names":[],"mappings":"AAIA,OAAO,EACN,KAAK,SAAS,EACd,SAAS,EACT,KAAK,eAAe,EAMpB,GAAG,EACH,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAuC,MAAM,oCAAoC,CAAC;AAE3G,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAMnF,KAAK,cAAc,GAAG,CAAC,UAAU,CAAC,EAAE,mBAAmB,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;AAsCnF,qBAAa,eAAe;IAC3B,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC;IACjB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;IACrD,QAAQ,CAAC,WAAW,EAAE,kBAAkB,CAAC;IACzC,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,gBAAgB,CAAC,CAAa;IACtC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyB;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,eAAe,YAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmB;IACnD,OAAO,CAAC,iBAAiB,CAAgB;IACzC,OAAO,CAAC,iBAAiB,CAAc;IACvC,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,aAAa,CAA4C;IAEjE,cAsDC;IAED,IAAI,eAAe,IAAI,OAAO,CAE7B;IAED,KAAK,IAAI,IAAI,CAMZ;IAED,KAAK,IAAI,IAAI,CAIZ;IAED,MAAM,IAAI,IAAI,CAKb;IAED,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAEjC;IAED,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3B;IAED,OAAO,IAAI,eAAe,CAGzB;IAED,gBAAgB,CAAC,SAAS,EAAE,MAAM,eAAe,GAAG,IAAI,CAEvD;IAED,gFAAgF;IAChF,QAAQ,IAAI,IAAI,CAYf;IAED,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAS9B;IAEK,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAOxC;IAED,IAAI,IAAI,IAAI,CAUX;IAEK,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,CAAC,CAAA;KAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAmBlG;IAEK,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO9D;IAEK,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAgB5E;IAEK,aAAa,CAClB,qBAAqB,EAAE,cAAc,EACrC,iBAAiB,EAAE,cAAc,GAC/B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAqBxB;IAED,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,oBAAoB;YA0Bd,cAAc;CA2B5B","sourcesContent":["import * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport {\n\ttype Component,\n\tContainer,\n\ttype EditorComponent,\n\tisFocusable,\n\tProcessTerminal,\n\tSpacer,\n\tsetKeybindings,\n\tText,\n\tTUI,\n} from \"@ashx-j/lunr-tui\";\nimport { getChatboxEditor, renderStatsLine, thinkingThemeToken } from \"../builtin-extensions/ashxj-tui.ts\";\nimport { APP_NAME, getAgentDir, VERSION } from \"../config.ts\";\nimport { KeybindingsManager } from \"../core/keybindings.ts\";\nimport { registerPermissionModeBridge } from \"../core/permission-mode.ts\";\nimport type { SessionInfo, SessionListProgress } from \"../core/session-manager.ts\";\nimport type { Settings } from \"../core/settings-manager.ts\";\nimport { BootScreenComponent } from \"../modes/interactive/components/boot-screen.ts\";\nimport { getEditorTheme, getThemeName, initTheme, theme } from \"../modes/interactive/theme/theme.ts\";\nimport { markStartupMilestone } from \"./startup-milestones.ts\";\n\ntype SessionsLoader = (onProgress?: SessionListProgress) => Promise<SessionInfo[]>;\n\n// Read display preferences only: no auth, models, resources, migrations, or writes.\nfunction readDisplaySettings(): Partial<Settings> {\n\ttry {\n\t\tconst value = JSON.parse(fs.readFileSync(path.join(getAgentDir(), \"settings.json\"), \"utf8\"));\n\t\treturn value && typeof value === \"object\" && !Array.isArray(value) ? value : {};\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nclass StartupProcessTerminal extends ProcessTerminal {\n\tprivate watchForFirstFrame = false;\n\tprivate firstFrameCallback: (() => void) | undefined;\n\n\tsetFirstFrameCallback(callback: () => void): void {\n\t\tthis.firstFrameCallback = callback;\n\t\tthis.watchForFirstFrame = true;\n\t}\n\n\toverride start(onInput: (data: string) => void, onResize: () => void): void {\n\t\tsuper.start(onInput, onResize);\n\t\tmarkStartupMilestone(\"input_handler_armed\");\n\t\tif (process.stdin.isTTY) markStartupMilestone(\"raw_mode_active\");\n\t}\n\n\toverride write(data: string): void {\n\t\tsuper.write(data);\n\t\t// TUI ends each content frame with synchronized-output end. Setup writes do not count.\n\t\tif (this.watchForFirstFrame && data.includes(\"\\x1b[?2026l\")) {\n\t\t\tthis.watchForFirstFrame = false;\n\t\t\tmarkStartupMilestone(\"first_frame_committed\");\n\t\t\tthis.firstFrameCallback?.();\n\t\t}\n\t}\n}\n\nexport class InteractiveView {\n\treadonly ui: TUI;\n\treadonly editor: ReturnType<typeof getChatboxEditor>;\n\treadonly keybindings: KeybindingsManager;\n\tprivate submitRequested = false;\n\tprivate inputUnsubscribe?: () => void;\n\tprivate modalActive = false;\n\tprivate readonly terminal: StartupProcessTerminal;\n\tprivate readonly status = new Text(\"\", 1, 0);\n\treadonly header: Component;\n\treadonly footer: Component;\n\treadonly statusContainer = new Container();\n\tprivate readonly editorContainer = new Container();\n\tprivate firstFramePromise: Promise<void>;\n\tprivate resolveFirstFrame!: () => void;\n\tprivate exitPromise: Promise<void>;\n\tprivate resolveExit!: () => void;\n\tprivate started = false;\n\tprivate handedOff = false;\n\tprivate exitRequested = false;\n\tprivate lastClearAt = 0;\n\tprivate currentEditor: () => EditorComponent = () => this.editor;\n\n\tconstructor() {\n\t\tconst settings = readDisplaySettings();\n\t\tconst permission = settings.defaultPermissionMode;\n\t\tregisterPermissionModeBridge(() =>\n\t\t\tpermission === \"auto\" || permission === \"yolo\" || permission === \"plan\" ? permission : \"manual\",\n\t\t);\n\t\tinitTheme(typeof settings.theme === \"string\" ? settings.theme : undefined);\n\t\tthis.terminal = new StartupProcessTerminal();\n\t\tthis.ui = new TUI(this.terminal, settings.showHardwareCursor);\n\t\tthis.ui.setClearOnShrink(settings.terminal?.clearOnShrink ?? false);\n\t\tthis.keybindings = KeybindingsManager.create();\n\t\tsetKeybindings(this.keybindings);\n\t\tconst ctx = {\n\t\t\tmode: \"tui\" as const,\n\t\t\thasUI: true,\n\t\t\tmodel: settings.defaultModel ? { id: settings.defaultModel, provider: settings.defaultProvider } : undefined,\n\t\t\tsessionManager: { getEntries: () => [] },\n\t\t\tgetContextUsage: () => undefined,\n\t\t\tui: { theme, setEditorComponent() {}, setFooter() {} },\n\t\t};\n\t\tconst effort = settings.defaultThinkingLevel ?? \"off\";\n\t\tthis.editor = getChatboxEditor(this.ui, getEditorTheme(), this.keybindings as never, ctx, {\n\t\t\tgetThinkingLevel: () => effort,\n\t\t\ton() {},\n\t\t});\n\t\tthis.editor.borderColor = (text) => theme.fg(thinkingThemeToken(effort) as Parameters<typeof theme.fg>[0], text);\n\t\tthis.editor.disableSubmit = true;\n\t\tthis.header = settings.quietStartup\n\t\t\t? new Text(\"\", 0, 0)\n\t\t\t: new BootScreenComponent(theme.bold(theme.fg(\"accent\", APP_NAME)) + theme.fg(\"dim\", ` v${VERSION}`), [\n\t\t\t\t\t{ label: \"directory\", value: process.cwd() },\n\t\t\t\t\t{ label: \"config\", value: getAgentDir() },\n\t\t\t\t\t{ label: \"theme\", value: getThemeName() },\n\t\t\t\t]);\n\t\tthis.footer = {\n\t\t\tinvalidate() {},\n\t\t\trender: (width) =>\n\t\t\t\trenderStatsLine(width, ctx, theme, {\n\t\t\t\t\tgetGitBranch: () => null,\n\t\t\t\t\tgetExtensionStatuses: () => new Map(),\n\t\t\t\t\tgetAvailableProviderCount: () => 0,\n\t\t\t\t\tonBranchChange: () => () => {},\n\t\t\t\t}),\n\t\t};\n\t\tthis.editorContainer.addChild(this.editor);\n\t\tthis.statusContainer.addChild(this.status);\n\t\tthis.firstFramePromise = new Promise((resolve) => {\n\t\t\tthis.resolveFirstFrame = resolve;\n\t\t});\n\t\tthis.exitPromise = new Promise((resolve) => {\n\t\t\tthis.resolveExit = resolve;\n\t\t});\n\t\tthis.terminal.setFirstFrameCallback(this.resolveFirstFrame);\n\t\tthis.installInputHandlers();\n\t}\n\n\tget isExitRequested(): boolean {\n\t\treturn this.exitRequested;\n\t}\n\n\tstart(): void {\n\t\tif (this.started) return;\n\t\tthis.restoreLayout();\n\t\tthis.ui.setAlternateScreen(true);\n\t\tthis.ui.start();\n\t\tthis.started = true;\n\t}\n\n\tpause(): void {\n\t\tif (!this.started || this.handedOff) return;\n\t\tthis.ui.stop();\n\t\tthis.started = false;\n\t}\n\n\tresume(): void {\n\t\tif (this.started || this.handedOff || this.exitRequested) return;\n\t\tthis.restoreLayout();\n\t\tthis.ui.start();\n\t\tthis.started = true;\n\t}\n\n\twaitForFirstFrame(): Promise<void> {\n\t\treturn this.firstFramePromise;\n\t}\n\n\twaitForExit(): Promise<void> {\n\t\treturn this.exitPromise;\n\t}\n\n\tbinding(): InteractiveView {\n\t\tthis.handedOff = true;\n\t\treturn this;\n\t}\n\n\tsetCurrentEditor(getEditor: () => EditorComponent): void {\n\t\tthis.currentEditor = getEditor;\n\t}\n\n\t/** Called only after the normal submit handler and all extensions are ready. */\n\tactivate(): void {\n\t\tif (this.exitRequested) return;\n\t\tthis.inputUnsubscribe?.();\n\t\tthis.inputUnsubscribe = undefined;\n\t\tthis.editor.onPasteImage = undefined;\n\t\tthis.editor.disableSubmit = false;\n\t\tthis.status.setText(\"\");\n\t\tif (this.submitRequested) {\n\t\t\tthis.submitRequested = false;\n\t\t\tthis.currentEditor().handleInput(\"\\r\");\n\t\t}\n\t\tthis.ui.requestRender();\n\t}\n\n\tshowError(error: unknown): void {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tthis.status.setText(\n\t\t\t`Startup failed: ${message}\\nYour draft is intact. Press Ctrl+C twice or Ctrl+D on an empty draft to exit.`,\n\t\t);\n\t\tthis.editor.disableSubmit = true;\n\t\tthis.statusContainer.clear();\n\t\tthis.statusContainer.addChild(this.status);\n\t\tthis.ui.requestRender();\n\t}\n\n\tasync fail(error: unknown): Promise<void> {\n\t\tthis.showError(error);\n\t\tif (process.env.PI_STARTUP_BENCHMARK === \"1\") {\n\t\t\tthis.stop();\n\t\t\treturn;\n\t\t}\n\t\tawait this.exitPromise;\n\t}\n\n\tstop(): void {\n\t\tif (this.exitRequested) return;\n\t\tthis.exitRequested = true;\n\t\tif (this.started) {\n\t\t\tthis.ui.stop();\n\t\t\tthis.started = false;\n\t\t}\n\t\tthis.inputUnsubscribe?.();\n\t\tthis.resolveFirstFrame();\n\t\tthis.resolveExit();\n\t}\n\n\tasync select<T>(title: string, options: Array<{ label: string; value: T }>): Promise<T | undefined> {\n\t\tconst { ExtensionSelectorComponent } = await import(\"../modes/interactive/components/extension-selector.ts\");\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tconst finish = (value: T | undefined) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tthis.restoreLayout();\n\t\t\t\tresolve(value);\n\t\t\t};\n\t\t\tconst selector = new ExtensionSelectorComponent(\n\t\t\t\ttitle,\n\t\t\t\toptions.map((option) => option.label),\n\t\t\t\t(label) => finish(options.find((option) => option.label === label)?.value),\n\t\t\t\t() => finish(undefined),\n\t\t\t\t{ tui: this.ui },\n\t\t\t);\n\t\t\tthis.showModal(selector, selector);\n\t\t});\n\t}\n\n\tasync confirm(title: string, message: string): Promise<boolean> {\n\t\treturn (\n\t\t\t(await this.select(`${title}\\n${message}`, [\n\t\t\t\t{ label: \"Yes\", value: true },\n\t\t\t\t{ label: \"No\", value: false },\n\t\t\t])) ?? false\n\t\t);\n\t}\n\n\tasync input(title: string, placeholder?: string): Promise<string | undefined> {\n\t\tconst { ExtensionInputComponent } = await import(\"../modes/interactive/components/extension-input.ts\");\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tconst finish = (value: string | undefined) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tinput.dispose();\n\t\t\t\tthis.restoreLayout();\n\t\t\t\tresolve(value);\n\t\t\t};\n\t\t\tconst input = new ExtensionInputComponent(title, placeholder, finish, () => finish(undefined), {\n\t\t\t\ttui: this.ui,\n\t\t\t});\n\t\t\tthis.showModal(input, input);\n\t\t});\n\t}\n\n\tasync selectSession(\n\t\tcurrentSessionsLoader: SessionsLoader,\n\t\tallSessionsLoader: SessionsLoader,\n\t): Promise<string | null> {\n\t\tconst { SessionSelectorComponent } = await import(\"../modes/interactive/components/session-selector.ts\");\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tconst finish = (path: string | null) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tthis.restoreLayout();\n\t\t\t\tresolve(path);\n\t\t\t};\n\t\t\tconst selector = new SessionSelectorComponent(\n\t\t\t\tcurrentSessionsLoader,\n\t\t\t\tallSessionsLoader,\n\t\t\t\t(path) => finish(path),\n\t\t\t\t() => finish(null),\n\t\t\t\t() => this.stop(),\n\t\t\t\t() => this.ui.requestRender(),\n\t\t\t\t{ showRenameHint: false, keybindings: this.keybindings },\n\t\t\t);\n\t\t\tthis.showModal(selector, selector.getSessionList());\n\t\t});\n\t}\n\n\tprivate showModal(component: Parameters<TUI[\"addChild\"]>[0], focus: Parameters<TUI[\"setFocus\"]>[0]): void {\n\t\tthis.modalActive = true;\n\t\tthis.ui.pinFrom(null);\n\t\tthis.ui.clear();\n\t\tthis.ui.addChild(component);\n\t\tthis.ui.setFocus(focus);\n\t\tthis.ui.requestRender(true);\n\t}\n\n\tprivate restoreLayout(): void {\n\t\tthis.modalActive = false;\n\t\tthis.ui.pinFrom(null);\n\t\tthis.ui.clear();\n\t\tthis.ui.addChild(new Spacer(1));\n\t\tthis.ui.addChild(this.header);\n\t\tthis.ui.addChild(new Spacer(1));\n\t\tthis.ui.addChild(this.statusContainer);\n\t\tthis.ui.addChild(this.editorContainer);\n\t\tthis.ui.addChild(this.footer);\n\t\tthis.ui.pinFrom(this.editorContainer);\n\t\tthis.ui.setFocus(this.editor);\n\t\tthis.ui.requestRender(true);\n\t}\n\n\tprivate installInputHandlers(): void {\n\t\tthis.editor.onAction(\"app.clear\", () => {\n\t\t\tconst now = Date.now();\n\t\t\tif (this.editor.getText().length === 0 && now - this.lastClearAt < 500) {\n\t\t\t\tthis.stop();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.editor.setText(\"\");\n\t\t\tthis.lastClearAt = now;\n\t\t});\n\t\tthis.editor.onCtrlD = () => this.stop();\n\t\tthis.editor.onPasteImage = () => void this.pasteClipboard();\n\t\tthis.inputUnsubscribe = this.ui.addInputListener((data) => {\n\t\t\tconst editor = this.currentEditor();\n\t\t\tif (this.modalActive || !isFocusable(editor) || !editor.focused) return;\n\t\t\tif (this.keybindings.matches(data, \"tui.input.submit\")) {\n\t\t\t\tthis.submitRequested = editor.getText().trim().length > 0;\n\t\t\t\treturn { consume: true };\n\t\t\t}\n\t\t\tif (this.keybindings.matches(data, \"app.interrupt\") || this.keybindings.matches(data, \"app.clear\")) {\n\t\t\t\tthis.submitRequested = false;\n\t\t\t}\n\t\t\treturn undefined;\n\t\t});\n\t}\n\n\tprivate async pasteClipboard(): Promise<void> {\n\t\ttry {\n\t\t\tconst [{ readClipboardText }, { extensionForImageMimeType, readClipboardImage }] = await Promise.all([\n\t\t\t\timport(\"../utils/clipboard.ts\"),\n\t\t\t\timport(\"../utils/clipboard-image.ts\"),\n\t\t\t]);\n\t\t\tconst image = await readClipboardImage();\n\t\t\tif (image) {\n\t\t\t\tconst extension = extensionForImageMimeType(image.mimeType) ?? \"png\";\n\t\t\t\tconst filePath = path.join(os.tmpdir(), `lunr-clipboard-${crypto.randomUUID()}.${extension}`);\n\t\t\t\tfs.writeFileSync(filePath, Buffer.from(image.bytes));\n\t\t\t\tthis.editor.insertImageMarker({ path: filePath, mimeType: image.mimeType });\n\t\t\t\tthis.ui.requestRender();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst text = await readClipboardText();\n\t\t\tif (text) {\n\t\t\t\tthis.editor.insertTextAtCursor(text);\n\t\t\t\tthis.ui.requestRender();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.status.setText(\"Clipboard contains no image or text.\");\n\t\t} catch (error) {\n\t\t\tthis.status.setText(`Clipboard paste failed: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\t\tthis.ui.requestRender();\n\t}\n}\n"]}