@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
package/CHANGELOG.md CHANGED
@@ -1,21 +1,80 @@
1
1
  # Changelog
2
2
 
3
- lunR is derived from pi. The published npm package is **`@ashx-j/lunr@0.2.13`**. Versioned sections below (`0.80.x` and earlier) are **upstream pi history** and do not describe lunR releases.
3
+ lunR is derived from pi. The published npm package is **`@ashx-j/lunr@0.2.19`**. Versioned sections below (`0.80.x` and earlier) are **upstream pi history** and do not describe lunR releases.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.2.19] - 2026-09-12
8
+
9
+ ### Changed
10
+
11
+ - **Chatbox rails.** The prompt box draws `│` side rails again with the rounded top and bottom rules and thinking chip.
12
+ - **Empty chats.** New sessions no longer print an injected context card. AGENTS.md and CLAUDE.md still reach the model through the system prompt.
13
+
14
+ ## [0.2.18] - 2026-09-12
15
+
16
+ ### New Features
17
+
18
+ - **Thinking-level commands.** `/off`, `/minimal`, `/low`, `/medium`, `/high`, `/xhigh`, and `/max` set the session thinking level. Autocomplete only lists levels the current model supports.
19
+ - **Injected context.** A new empty chat lists loaded AGENTS.md and CLAUDE.md files as injected context. The model still receives those files through the system prompt.
20
+
21
+ ### Changed
22
+
23
+ - **Faster first request.** Node CLI and SDK share split bundles. Optional web, LSP, MCP, and subagent engines load on demand. Tool schemas still register before the first request.
24
+ - **Async subagent widget.** Running background children use the same description-first compact row as foreground children, separated from todos by a divider.
25
+ - **Quieter TUI.** Cycling models or thinking levels, and pasting images, no longer print status toasts. The chatbox keeps its top and bottom rules and thinking chip, without vertical side rails.
26
+
27
+ ### Fixed
28
+
29
+ - Ctrl+T cycles thinking levels for the selected model. `/thinking hide`, `show`, and `toggle` still hide thinking blocks.
30
+ - `/thinking` argument completions follow the live session model.
31
+
32
+ ## [0.2.17] - 2026-09-11
33
+
34
+ ### Fixed
35
+
36
+ - **Subagent launches.** Nested JSON Schema cleanup no longer deletes the child `description` UI label. A control `action` mixed into a launch is dropped, and dummy `tasks`/`chain` are dropped when a real `task` is present, so filling every optional field cannot turn a spawn into status or a stub chain.
37
+
38
+ ## [0.2.16] - 2026-09-08
39
+
40
+ ### Fixed
41
+
42
+ - **Codex context and compaction.** Codex OAuth uses each route's advertised default context window instead of its optional maximum. Current 272k routes compact around 255,616 tokens with the default reserve. lunR checks again after complete tool-result batches, before the next provider request. Repeated `/compact` calls at the same boundary are harmless, and the TUI waits for the active turn to settle before rebuilding compacted history.
43
+
44
+ ## [0.2.15] - 2026-09-05
45
+
46
+ ### New Features
47
+
48
+ - **Model instructions** — `/settings` Model instructions loads `~/.lunr/agent/agents/<model>/AGENTS.md` for the selected model. Instruction mode is **Both** (global then model) or **Model only**. A leftover `~/.lunr/agent/AGENTS.md` migrates into `~/.lunr/agent/agents/AGENTS.md` when the new path is empty.
49
+ - **On-demand settings tools** — `settings_load` injects four narrow tools for model tiers, subscription management, rollback, and session retention.
50
+
51
+ ### Changed
52
+
53
+ - **Required child tiers** — when model tiers are enabled, every child must select `light`, `standard`, or `heavy`. Inherit and an explicit child `model` are rejected. Missing, disabled, or unauthenticated routes fail closed.
54
+ - **Large-launch confirmation** — `/settings` Confirm large subagent launches (default on) asks before 3+ children in manual and yolo. Auto still bypasses it.
55
+ - **Global instructions path** — user-managed global instructions live at `~/.lunr/agent/agents/AGENTS.md`. `/context` still labels that file `Global AGENTS.md`.
56
+
57
+ ### Removed
58
+
59
+ - **`/swarm`** — the slash command, gateway command, and swarm prompt wrapper are gone. Parallel children still use generic `subagent` launches; 3+ children still share one confirmation.
60
+
61
+ ## [0.2.14] - 2026-09-05
62
+
7
63
  ### Documentation
8
64
 
9
65
  - User-facing shipped docs now describe lunR: `@ashx-j/lunr`, binary `lunr`, config `~/.lunr/agent` and project `.lunr/`, `/refresh` for catalogs, and baked-in features (MCP, subagents, permissions, plan, todos, cron, gateway).
10
66
 
11
67
  ### New Features
12
68
 
69
+ - **Autonomous model catalog** — Codex uses public metadata plus authenticated, version-gated discovery, with idle refresh and checksummed hourly snapshots that do not require an agent turn.
13
70
  - **Mid-message skill tags** — `/settings` Skill tag (`+`, `~`, or `$`) lists loaded skills after a space so you can insert `{char}{name}` without expanding SKILL.md. `/skill:name` remains the force-load path.
14
71
  - **Agent-managed factual memory** — Added an Agent memory setting beside the character cap. Turning it off removes memory injection and tools without deleting stored facts. Global behavior now comes only from a user-created `~/.lunr/agent/AGENTS.md`; behavior presets and `behavior.md` injection were removed.
15
72
  - **Qwen Token Plan** — Added built-in providers for QwenCloud's Credits-based Token Plan (`qwen-token-plan` international and `qwen-token-plan-cn` China), using the DashScope OpenAI-compatible endpoint with `DASHSCOPE_TOKEN_PLAN_API_KEY` / `DASHSCOPE_TOKEN_PLAN_CN_API_KEY`. Includes 15 text models and defaults to the token-plan-only `qwen3.8-max-preview`.
16
73
 
17
74
  ### Changed
18
75
 
76
+ - **Real TUI first paint** — The normal moon chatbox, header, and stats render before runtime hydration while retaining the same terminal, editor, draft, cursor, and image chips through feature attachment.
77
+ - **Offline release validation** — Routine builds no longer regenerate the live model catalog; published dependencies and standalone installer locks preserve exact reviewed resolutions.
19
78
  - **Settings menu copy** — `/settings` rows use short feature summaries instead of implementation inventories; choice-specific details stay beside the relevant option.
20
79
  - **Global AGENTS.md label** — `/context` and `/usage` label `~/.lunr/agent/AGENTS.md` as `Global AGENTS.md`; project instruction files stay `AGENTS.md`.
21
80
 
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # lunR dev
2
2
 
3
- This package contains untested builds from lunR's `dev/tui` branch. Use it to try TUI changes before they reach the stable `@ashx-j/lunr` package.
3
+ This package contains development builds from lunR's `dev/tui` branch. The current baseline is stable lunR 0.2.19 plus the native computer-use changes from PR #77.
4
+
5
+ Computer use is experimental. Automated checks pass, but live desktop acceptance and macOS hardware verification remain incomplete. Stable `@ashx-j/lunr` is unchanged.
4
6
 
5
7
  Install it once:
6
8
 
@@ -22,4 +24,8 @@ lunr-dev update
22
24
 
23
25
  Stable lunR remains available as `lunr`. Both commands use `~/.lunr/agent`, so they share credentials, settings, and sessions.
24
26
 
27
+ For computer use, run `/computer setup` in the local terminal. Windows x64/arm64 and Apple Silicon macOS receive only their matching optional runtime package. Keep optional dependencies enabled during installation. Screen and application content can enter model requests and saved sessions. GUI actions are outside file rollback.
28
+
29
+ See [computer-use setup and limitations](https://github.com/ashx-j/lunR/blob/dev/tui/packages/coding-agent/docs/computer-use.md).
30
+
25
31
  For full documentation, see [the lunR README](https://github.com/ashx-j/lunR/blob/master/packages/coding-agent/README.md).
@@ -60,6 +60,7 @@ interface ExtensionAPI {
60
60
  }): void;
61
61
  getThinkingLevel(): ThinkingLevel;
62
62
  setThinkingLevel(level: ThinkingLevel): void;
63
+ on?(event: string, handler: (event: unknown, ctx: ExtensionContextLike) => void): void;
63
64
  }
64
65
  export default function (pi: ExtensionAPI): void;
65
66
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"ashxj-thinking.d.ts","sourceRoot":"","sources":["../../src/builtin-extensions/ashxj-thinking.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;GAiBG;AAUH,qEAAqE;AAErE,KAAK,aAAa,GAAG,KAAK,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAErF,iEAAiE;AACjE,UAAU,gBAAgB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wEAAsE;AACtE,UAAU,SAAS;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;CACjD;AAED,8EAA4E;AAC5E,UAAU,oBAAoB;IAC7B,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;IACvC,KAAK,EAAE,SAAS,GAAG,SAAS,CAAC;IAC7B,EAAE,EAAE;QACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,IAAI,CAAC;QACnE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE,WAAW,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;KACzH,CAAC;CACF;AAED,qFAAmF;AACnF,UAAU,2BAA4B,SAAQ,oBAAoB;IACjE,gBAAgB,IAAI,aAAa,CAAC;IAClC;;;kFAG4E;IAC5E,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,oEAAkE;AAClE,UAAU,YAAY;IACrB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;QACtC,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,sBAAsB,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,EAAE,GAAG,IAAI,GAAG,OAAO,CAAC,gBAAgB,EAAE,GAAG,IAAI,CAAC,CAAC;QACxG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;KAC9E,GAAG,IAAI,CAAC;IACT,gBAAgB,IAAI,aAAa,CAAC;IAClC,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;CAC7C;AAqLD,MAAM,CAAC,OAAO,WAAW,EAAE,EAAE,YAAY,GAAG,IAAI,CA2H/C","sourcesContent":["// @ts-nocheck\n// Vendored from https://github.com/ashx-j/ashxj-thinking @ 0330a34\n// (\"Remove custom footer — keep only /thinking command\"), single-file ashxj\n// convention. lunR patches are marked `// lunr:`.\n/**\n * batxj-thinking extension\n *\n * `/thinking [level]` slash command to view or set the reasoning level,\n * plus `/thinking show|hide|toggle` for thinking-block visibility.\n * `/effort` and `/reasoning` are full-parity aliases.\n *\n * Loaded by pi via jiti — no build step, plain TypeScript.\n *\n * NOTE on type imports: this file deliberately declares structural types\n * rather than importing from `@ashx-j/lunr-dev` (or\n * `@ashx-j/lunr-tui`). pi-coding-agent's `index.d.ts` re-exports\n * from internal `.d.ts` files that contain subpath imports like\n * `@ashx-j/lunr-ai/compat`, which fail to resolve under the default\n * `tsc` settings when a file argument is passed (the spec'd\n * `tsc --noEmit index.ts` script). Declaring the types we use inline\n * keeps the typecheck self-contained.\n */\n\nimport { readFileSync, writeFileSync, existsSync, renameSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\n// ---------------------------------------------------------------------------\n// Minimal structural types (see file header for why these are inline)\n// ---------------------------------------------------------------------------\n\n/** Mirrored from `@ashx-j/lunr-agent` `ThinkingLevel`. */\n// lunr: added \"max\" — lunR's ThinkingLevel union includes it.\ntype ThinkingLevel = \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\n/** Mirrored from `@ashx-j/lunr-tui` `AutocompleteItem`. */\ninterface AutocompleteItem {\n\tvalue: string;\n\tlabel: string;\n\tdescription?: string;\n}\n\n/** A trimmed view of a `Model` — only the fields the picker reads. */\ninterface ModelLike {\n\tid?: string;\n\treasoning?: boolean;\n\tthinkingLevelMap?: Record<string, string | null>;\n}\n\n/** A trimmed view of `ExtensionContext` — only the methods/props we use. */\ninterface ExtensionContextLike {\n\tmode: \"tui\" | \"rpc\" | \"json\" | \"print\";\n\tmodel: ModelLike | undefined;\n\tui: {\n\t\tnotify(message: string, type?: \"info\" | \"warning\" | \"error\"): void;\n\t\tselect(title: string, options: string[], opts?: { signal?: AbortSignal; timeout?: number }): Promise<string | undefined>;\n\t};\n}\n\n/** A trimmed view of `ExtensionCommandContext` — only the methods/props we use. */\ninterface ExtensionCommandContextLike extends ExtensionContextLike {\n\tgetThinkingLevel(): ThinkingLevel;\n\t/** Reload extensions, skills, prompts, and themes. Re-reads settings.json\n\t * from disk (session.reload() → settingsManager.reload()), so persisted\n\t * runtime settings like `hideThinkingBlock` are live-applied. The captured\n\t * `ctx`/`pi` are stale after this resolves — do not use them afterward. */\n\treload(): Promise<void>;\n}\n\n/** A trimmed view of `ExtensionAPI` — only the methods we use. */\ninterface ExtensionAPI {\n\tregisterCommand(name: string, options: {\n\t\tdescription?: string;\n\t\tgetArgumentCompletions?(prefix: string): AutocompleteItem[] | null | Promise<AutocompleteItem[] | null>;\n\t\thandler(args: string, ctx: ExtensionCommandContextLike): Promise<void> | void;\n\t}): void;\n\tgetThinkingLevel(): ThinkingLevel;\n\tsetThinkingLevel(level: ThinkingLevel): void;\n}\n\n// ---------------------------------------------------------------------------\n// Thinking level config\n// ---------------------------------------------------------------------------\n\n/** All known levels, in display order. Mirrors `EXTENDED_THINKING_LEVELS` in pi-ai. */\nconst ALL_LEVELS: readonly ThinkingLevel[] = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"];\n/** Default 5 — used when the active model is undefined (we don't know whether `xhigh`/`max` are supported). */\nconst ALL_LEVELS_5: readonly ThinkingLevel[] = [\"off\", \"minimal\", \"low\", \"medium\", \"high\"];\n\n/** Per-level descriptions. Mirrored from `THINKING_DESCRIPTIONS` in settings-selector.ts. */\nconst THINKING_DESCRIPTIONS: Record<ThinkingLevel, string> = {\n\toff: \"No reasoning\",\n\tminimal: \"Very brief reasoning\",\n\tlow: \"Light reasoning\",\n\tmedium: \"Moderate reasoning\",\n\thigh: \"Deep reasoning\",\n\txhigh: \"Extra-high reasoning\",\n\t// lunr: added — mirrors settings-selector.ts.\n\tmax: \"Maximum reasoning\",\n};\n\n/** Returns the levels valid for the given model, in display order.\n * Mirrors `getSupportedThinkingLevels` in pi-ai: `xhigh`/`max` are opt-in\n * (non-null map entry); other levels drop only on an explicit null. */\nfunction availableLevelsFor(model: ModelLike | undefined): readonly ThinkingLevel[] {\n\tif (!model) return ALL_LEVELS_5;\n\tif (model.reasoning === false) return [\"off\" as const];\n\treturn ALL_LEVELS.filter((level) => {\n\t\tconst mapped = model.thinkingLevelMap?.[level];\n\t\tif (mapped === null) return false;\n\t\tif (level === \"xhigh\" || level === \"max\") return mapped !== undefined;\n\t\treturn true;\n\t});\n}\n\n/** Builds the inline `<padded level> — <description>` label for a level. */\nfunction formatLevelLabel(level: ThinkingLevel): string {\n\treturn `${level.padEnd(8)} \\u2014 ${THINKING_DESCRIPTIONS[level]}`;\n}\n\n// ---------------------------------------------------------------------------\n// Persisted thinking-block visibility (hideThinkingBlock)\n//\n// pi has no public extension API to toggle thinking-block visibility live.\n// The live in-session toggle is `app.thinking.toggle` (default Ctrl+T) wired to\n// `toggleThinkingBlockVisibility()` in interactive-mode.js, which calls\n// `SettingsManager.setHideThinkingBlock()` + rebuilds the chat. That method is\n// not exposed on ExtensionContext / ExtensionCommandContext / ExtensionAPI.\n//\n// What extensions CAN do is persist the `hideThinkingBlock` boolean to the\n// global agent settings file (`~/.lunr/agent/settings.json`); the\n// `SettingsManager` reads it on startup. And because `ctx.reload()` drives\n// `session.reload()` → `settingsManager.reload()` (re-reads disk) →\n// `restoreChatBeforeSessionStart()` copies the new value into\n// `this.hideThinkingBlock` and calls `rebuildChatFromMessages()` (which\n// reconstructs every AssistantMessageComponent with the new hide flag), the\n// persisted value IS live-applied within the session by `await ctx.reload()`\n// (verified against pi 0.80.3). In non-TUI modes `ctx.reload()` is a no-op,\n// so the setting simply applies on next start.\n//\n// The instant keybinding path (Ctrl+T) still works and is the lowest-latency\n// toggle; the command is the discoverable, persistable, completions-friendly\n// equivalent.\n// ---------------------------------------------------------------------------\n\n/** Returns the path to lunR's global agent settings file.\n * lunr: lunR's agent dir is `~/.lunr/agent` (upstream hardcoded `~/.pi/agent`).\n * Honors the `PI_CODING_AGENT_DIR` env override like core config.ts does;\n * a custom agent dir is not exposed to extensions, so this is the only\n * location we can write to be picked up by\n * `SettingsManager.tryLoadFromStorage(\"global\")`. */\nfunction agentSettingsPath(): string {\n\tconst envDir = process.env.PI_CODING_AGENT_DIR;\n\tif (envDir) {\n\t\t// Match core normalizePath(): expand a leading ~ (~/ and, on win32, ~\\).\n\t\tconst home = homedir();\n\t\tconst expanded =\n\t\t\tenvDir === \"~\"\n\t\t\t\t? home\n\t\t\t\t: envDir.startsWith(\"~/\") || (process.platform === \"win32\" && envDir.startsWith(\"~\\\\\"))\n\t\t\t\t\t? join(home, envDir.slice(2))\n\t\t\t\t\t: envDir;\n\t\treturn join(expanded, \"settings.json\");\n\t}\n\treturn join(homedir(), \".lunr\", \"agent\", \"settings.json\");\n}\n\n// ---------------------------------------------------------------------------\n// lunR customize bridge for persisted thinking-block visibility.\n// When the bridge is present (TUI / gateway sessions), reads/writes go through\n// SettingsManager (lockfile + merge). Falls back to direct file I/O when the\n// extension loads in a context without the bridge (e.g. upstream pi).\n// ---------------------------------------------------------------------------\ninterface CustomizeBridge {\n\tgetHideThinkingBlock(): boolean;\n\tsetHideThinkingBlock(hide: boolean): void;\n}\n\nfunction getCustomizeBridge(): CustomizeBridge | undefined {\n\treturn (globalThis as Record<symbol, unknown>)[Symbol.for(\"@lunr/customize\")] as CustomizeBridge | undefined;\n}\n\n/** Returns the persisted `hideThinkingBlock` value (default false, matching\n * `getHideThinkingBlock()` which returns `this.settings.hideThinkingBlock ?? false`).\n * Never throws — on any error (missing file, bad JSON) returns false. */\nfunction readHideThinkingBlock(): boolean {\n\tconst bridge = getCustomizeBridge();\n\tif (bridge) return bridge.getHideThinkingBlock();\n\ttry {\n\t\tconst p = agentSettingsPath();\n\t\tif (!existsSync(p)) return false;\n\t\tconst cfg = JSON.parse(readFileSync(p, \"utf8\")) as { hideThinkingBlock?: boolean };\n\t\treturn cfg.hideThinkingBlock === true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Persist `hideThinkingBlock` to the global agent settings file (safe merge).\n *\n * - Preserves all other keys (merge, never overwrite the whole file).\n * - Matches pi's 2-space indentation + trailing newline.\n * - On invalid JSON in the existing file, backs it up to `settings.json.bak`\n * before writing a fresh file, so a corrupted file is never written back.\n * - Never throws; on any error `ok` is false and the caller notifies the user.\n *\n * `createdFresh` is true when the file didn't exist (or was corrupt and backed\n * up) before this write — the handler uses it to warn that a global settings\n * file was created here.\n */\nfunction writeHideThinkingBlock(hide: boolean): {\n\tok: boolean;\n\tcreatedFresh: boolean;\n} {\n\tconst bridge = getCustomizeBridge();\n\tif (bridge) {\n\t\ttry {\n\t\t\tbridge.setHideThinkingBlock(hide);\n\t\t\treturn { ok: true, createdFresh: false };\n\t\t} catch {\n\t\t\treturn { ok: false, createdFresh: false };\n\t\t}\n\t}\n\ttry {\n\t\tconst p = agentSettingsPath();\n\t\tlet cfg: Record<string, unknown> = {};\n\t\tlet createdFresh = false;\n\t\tif (existsSync(p)) {\n\t\t\ttry {\n\t\t\t\tcfg = JSON.parse(readFileSync(p, \"utf8\")) as Record<string, unknown>;\n\t\t\t} catch {\n\t\t\t\t// Existing file is corrupt — back it up, then start fresh.\n\t\t\t\ttry {\n\t\t\t\t\trenameSync(p, `${p}.bak`);\n\t\t\t\t} catch {\n\t\t\t\t\t// If backup fails, still proceed to overwrite (best effort).\n\t\t\t\t}\n\t\t\t\tcfg = {};\n\t\t\t\tcreatedFresh = true;\n\t\t\t}\n\t\t} else {\n\t\t\tcreatedFresh = true;\n\t\t}\n\t\tcfg.hideThinkingBlock = hide;\n\t\twriteFileSync(p, JSON.stringify(cfg, null, 2) + \"\\n\", \"utf8\");\n\t\treturn { ok: true, createdFresh };\n\t} catch {\n\t\treturn { ok: false, createdFresh: false };\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Extension entry point\n// ---------------------------------------------------------------------------\n\nconst THINKING_COMMAND_DESCRIPTION =\n\t\"View or set the reasoning level for the current model, or toggle thinking-block visibility with show/hide/toggle\";\n\nexport default function (pi: ExtensionAPI): void {\n\tconst thinkingSpec = {\n\t\tdescription: THINKING_COMMAND_DESCRIPTION,\n\t\tgetArgumentCompletions(prefix: string): AutocompleteItem[] {\n\t\t\tconst lower = prefix.toLowerCase();\n\t\t\t// Visibility sub-options first, filtered by prefix, alongside the levels.\n\t\t\tconst visibility: AutocompleteItem[] = [\n\t\t\t\t{ value: \"show\", label: \"show\", description: \"Show thinking blocks (persisted to settings.json)\" },\n\t\t\t\t{ value: \"hide\", label: \"hide\", description: \"Hide thinking blocks (persisted to settings.json)\" },\n\t\t\t\t{ value: \"toggle\", label: \"toggle\", description: \"Toggle thinking blocks (persisted to settings.json)\" },\n\t\t\t];\n\t\t\tconst levels = availableLevelsFor(currentModel(pi));\n\t\t\tconst levelItems = levels\n\t\t\t\t.filter((lvl) => lvl.startsWith(lower))\n\t\t\t\t.map((lvl) => ({ value: lvl, label: lvl, description: THINKING_DESCRIPTIONS[lvl] }));\n\t\t\treturn [\n\t\t\t\t...visibility.filter((v) => v.value.startsWith(lower)),\n\t\t\t\t...levelItems,\n\t\t\t];\n\t\t},\n\t\thandler: async (args: string, ctx: ExtensionCommandContextLike) => {\n\t\t\tconst trimmed = args.trim();\n\t\t\tconst lower = trimmed.toLowerCase();\n\n\t\t\t// ---- Visibility sub-options: /thinking show | hide | toggle ----\n\t\t\t// Caught first so `hide`/`show`/`toggle` are never parsed as levels.\n\t\t\t// Works in every mode: only uses ctx.ui.notify + file I/O + ctx.reload().\n\t\t\tif (lower === \"show\" || lower === \"hide\" || lower === \"toggle\") {\n\t\t\t\tconst current = readHideThinkingBlock();\n\t\t\t\tconst next = lower === \"toggle\" ? !current : lower === \"hide\";\n\t\t\t\tif (next === current) {\n\t\t\t\t\tctx.ui.notify(`Thinking blocks already ${current ? \"hidden\" : \"shown\"}.`, \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst result = writeHideThinkingBlock(next);\n\t\t\t\tif (!result.ok) {\n\t\t\t\t\t// lunr: settings path is lunR's (see agentSettingsPath).\n\t\t\t\t\tctx.ui.notify(`Failed to update ${agentSettingsPath()}`, \"error\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// The notify MUST run before `await ctx.reload()`: after reload the\n\t\t\t\t// loader invalidates this `ctx`/`pi` as stale. ctx.reload() live-\n\t\t\t\t// applies the setting (verified against pi 0.80.3: it drives\n\t\t\t\t// session.reload() → settingsManager.reload() re-reads disk →\n\t\t\t\t// restoreChatBeforeSessionStart copies the new value into\n\t\t\t\t// this.hideThinkingBlock → rebuildChatFromMessages() rebuilds every\n\t\t\t\t// AssistantMessageComponent with the new hide flag). In non-TUI\n\t\t\t\t// modes ctx.reload() is a no-op; the setting then applies on next\n\t\t\t\t// start. The instant keybinding path (Ctrl+T) also still works.\n\t\t\t\tconst verb = next ? \"hidden\" : \"shown\";\n\t\t\t\tconst note = result.createdFresh\n\t\t\t\t\t? `Thinking blocks ${verb}. (Created ${agentSettingsPath()} with this setting.)`\n\t\t\t\t\t: `Thinking blocks ${verb}.`;\n\t\t\t\tctx.ui.notify(note, \"info\");\n\t\t\t\tawait ctx.reload();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst levels = availableLevelsFor(ctx.model);\n\t\t\tconst currentLevel: ThinkingLevel = pi.getThinkingLevel();\n\t\t\tconst validSet = new Set<ThinkingLevel>(levels);\n\n\t\t\t// No-arg form → open a picker. Skip in non-TUI modes — same pattern\n\t\t\t// as batxj-animations per AGENTS.md §5.\n\t\t\tif (trimmed === \"\") {\n\t\t\t\tif (ctx.mode !== \"tui\") {\n\t\t\t\t\tctx.ui.notify(`Thinking level: ${currentLevel}`, \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (levels.length === 0) {\n\t\t\t\t\tctx.ui.notify(\"No thinking levels available for this model.\", \"warning\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst options = levels.map((lvl) =>\n\t\t\t\t\t(lvl === currentLevel ? \"\\u25CF \" : \" \") + formatLevelLabel(lvl),\n\t\t\t\t);\n\t\t\t\tconst chosen = await ctx.ui.select(\n\t\t\t\t\t`Thinking level (current: ${currentLevel})`,\n\t\t\t\t\toptions,\n\t\t\t\t);\n\t\t\t\tif (chosen === undefined) return;\n\t\t\t\t// Chosen string starts with the current-marker (\"● \") or two-space\n\t\t\t\t// gutter; strip the prefix and extract the first token (the level).\n\t\t\t\tconst stripped = chosen.replace(/^[\\u25CF ]\\s?/, \"\").trimStart();\n\t\t\t\tconst level = stripped.split(/\\s+/)[0] as ThinkingLevel;\n\t\t\t\tif (!validSet.has(level)) {\n\t\t\t\t\tctx.ui.notify(`Unsupported thinking level: ${level}`, \"error\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (level === currentLevel) return; // no-op\n\t\t\t\tpi.setThinkingLevel(level);\n\t\t\t\tctx.ui.notify(`Thinking level: ${pi.getThinkingLevel()}`, \"info\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Direct-set form: `/thinking <level>`\n\t\t\tconst requested = trimmed.toLowerCase() as ThinkingLevel;\n\t\t\tif (!validSet.has(requested)) {\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Invalid thinking level: \"${trimmed}\". Valid: ${levels.join(\", \")}`,\n\t\t\t\t\t\"error\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (requested === currentLevel) {\n\t\t\t\tctx.ui.notify(`Thinking level: ${requested} (unchanged)`, \"info\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tpi.setThinkingLevel(requested);\n\t\t\tctx.ui.notify(`Thinking level: ${pi.getThinkingLevel()}`, \"info\");\n\t\t},\n\t};\n\n\tpi.registerCommand(\"thinking\", thinkingSpec);\n\t// lunr: /effort and /reasoning are full-parity aliases (same handler + completions).\n\tpi.registerCommand(\"effort\", {\n\t\t...thinkingSpec,\n\t\tdescription: `${THINKING_COMMAND_DESCRIPTION} (alias of /thinking)`,\n\t});\n\tpi.registerCommand(\"reasoning\", {\n\t\t...thinkingSpec,\n\t\tdescription: `${THINKING_COMMAND_DESCRIPTION} (alias of /thinking)`,\n\t});\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Read the current model from the ExtensionAPI runtime. The spec mentions\n * `pi.getModel()`; pi doesn't expose that name on the API object itself, but\n * the bound `ExtensionContextActions` (which the runtime decorates onto\n * events) does include `getModel()`. We duck-type against the loader so this\n * file stays decoupled from non-public internals. When unavailable (e.g.\n * during autocomplete, before any session has bound), returns undefined and\n * the caller falls back to the default 5-level set.\n */\nfunction currentModel(pi: ExtensionAPI): ModelLike | undefined {\n\tconst fn = (pi as unknown as { getModel?: () => unknown }).getModel;\n\tif (typeof fn === \"function\") {\n\t\treturn fn.call(pi) as ModelLike | undefined;\n\t}\n\treturn undefined;\n}\n"]}
1
+ {"version":3,"file":"ashxj-thinking.d.ts","sourceRoot":"","sources":["../../src/builtin-extensions/ashxj-thinking.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;GAiBG;AAUH,qEAAqE;AAErE,KAAK,aAAa,GAAG,KAAK,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAErF,iEAAiE;AACjE,UAAU,gBAAgB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wEAAsE;AACtE,UAAU,SAAS;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;CACjD;AAED,8EAA4E;AAC5E,UAAU,oBAAoB;IAC7B,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;IACvC,KAAK,EAAE,SAAS,GAAG,SAAS,CAAC;IAC7B,EAAE,EAAE;QACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,IAAI,CAAC;QACnE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE,WAAW,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;KACzH,CAAC;CACF;AAED,qFAAmF;AACnF,UAAU,2BAA4B,SAAQ,oBAAoB;IACjE,gBAAgB,IAAI,aAAa,CAAC;IAClC;;;kFAG4E;IAC5E,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,oEAAkE;AAClE,UAAU,YAAY;IACrB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;QACtC,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,sBAAsB,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,EAAE,GAAG,IAAI,GAAG,OAAO,CAAC,gBAAgB,EAAE,GAAG,IAAI,CAAC,CAAC;QACxG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;KAC9E,GAAG,IAAI,CAAC;IACT,gBAAgB,IAAI,aAAa,CAAC;IAClC,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7C,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,oBAAoB,KAAK,IAAI,GAAG,IAAI,CAAC;CACvF;AAoLD,MAAM,CAAC,OAAO,WAAW,EAAE,EAAE,YAAY,GAAG,IAAI,CAmJ/C","sourcesContent":["// @ts-nocheck\n// Vendored from https://github.com/ashx-j/ashxj-thinking @ 0330a34\n// (\"Remove custom footer — keep only /thinking command\"), single-file ashxj\n// convention. lunR patches are marked `// lunr:`.\n/**\n * batxj-thinking extension\n *\n * `/thinking [level]` slash command to view or set the reasoning level,\n * plus `/thinking show|hide|toggle` for thinking-block visibility.\n * `/effort` and `/reasoning` are full-parity aliases.\n *\n * Loaded by pi via jiti — no build step, plain TypeScript.\n *\n * NOTE on type imports: this file deliberately declares structural types\n * rather than importing from `@ashx-j/lunr-dev` (or\n * `@ashx-j/lunr-tui`). pi-coding-agent's `index.d.ts` re-exports\n * from internal `.d.ts` files that contain subpath imports like\n * `@ashx-j/lunr-ai/compat`, which fail to resolve under the default\n * `tsc` settings when a file argument is passed (the spec'd\n * `tsc --noEmit index.ts` script). Declaring the types we use inline\n * keeps the typecheck self-contained.\n */\n\nimport { readFileSync, writeFileSync, existsSync, renameSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\n// ---------------------------------------------------------------------------\n// Minimal structural types (see file header for why these are inline)\n// ---------------------------------------------------------------------------\n\n/** Mirrored from `@ashx-j/lunr-agent` `ThinkingLevel`. */\n// lunr: added \"max\" — lunR's ThinkingLevel union includes it.\ntype ThinkingLevel = \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\n/** Mirrored from `@ashx-j/lunr-tui` `AutocompleteItem`. */\ninterface AutocompleteItem {\n\tvalue: string;\n\tlabel: string;\n\tdescription?: string;\n}\n\n/** A trimmed view of a `Model` — only the fields the picker reads. */\ninterface ModelLike {\n\tid?: string;\n\treasoning?: boolean;\n\tthinkingLevelMap?: Record<string, string | null>;\n}\n\n/** A trimmed view of `ExtensionContext` — only the methods/props we use. */\ninterface ExtensionContextLike {\n\tmode: \"tui\" | \"rpc\" | \"json\" | \"print\";\n\tmodel: ModelLike | undefined;\n\tui: {\n\t\tnotify(message: string, type?: \"info\" | \"warning\" | \"error\"): void;\n\t\tselect(title: string, options: string[], opts?: { signal?: AbortSignal; timeout?: number }): Promise<string | undefined>;\n\t};\n}\n\n/** A trimmed view of `ExtensionCommandContext` — only the methods/props we use. */\ninterface ExtensionCommandContextLike extends ExtensionContextLike {\n\tgetThinkingLevel(): ThinkingLevel;\n\t/** Reload extensions, skills, prompts, and themes. Re-reads settings.json\n\t * from disk (session.reload() → settingsManager.reload()), so persisted\n\t * runtime settings like `hideThinkingBlock` are live-applied. The captured\n\t * `ctx`/`pi` are stale after this resolves — do not use them afterward. */\n\treload(): Promise<void>;\n}\n\n/** A trimmed view of `ExtensionAPI` — only the methods we use. */\ninterface ExtensionAPI {\n\tregisterCommand(name: string, options: {\n\t\tdescription?: string;\n\t\tgetArgumentCompletions?(prefix: string): AutocompleteItem[] | null | Promise<AutocompleteItem[] | null>;\n\t\thandler(args: string, ctx: ExtensionCommandContextLike): Promise<void> | void;\n\t}): void;\n\tgetThinkingLevel(): ThinkingLevel;\n\tsetThinkingLevel(level: ThinkingLevel): void;\n\ton?(event: string, handler: (event: unknown, ctx: ExtensionContextLike) => void): void;\n}\n\n// ---------------------------------------------------------------------------\n// Thinking level config\n// ---------------------------------------------------------------------------\n\n/** All known levels, in display order. Mirrors `EXTENDED_THINKING_LEVELS` in pi-ai. */\nconst ALL_LEVELS: readonly ThinkingLevel[] = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"];\n/** Default 5 — used when the active model is undefined (we don't know whether `xhigh`/`max` are supported). */\nconst ALL_LEVELS_5: readonly ThinkingLevel[] = [\"off\", \"minimal\", \"low\", \"medium\", \"high\"];\n\n/** Per-level descriptions. Mirrored from `THINKING_DESCRIPTIONS` in settings-selector.ts. */\nconst THINKING_DESCRIPTIONS: Record<ThinkingLevel, string> = {\n\toff: \"No reasoning\",\n\tminimal: \"Very brief reasoning\",\n\tlow: \"Light reasoning\",\n\tmedium: \"Moderate reasoning\",\n\thigh: \"Deep reasoning\",\n\txhigh: \"Extra-high reasoning\",\n\t// lunr: added — mirrors settings-selector.ts.\n\tmax: \"Maximum reasoning\",\n};\n\n/** Returns the levels valid for the given model, in display order.\n * Mirrors `getSupportedThinkingLevels` in pi-ai: `xhigh`/`max` are opt-in\n * (non-null map entry); other levels drop only on an explicit null. */\nfunction availableLevelsFor(model: ModelLike | undefined): readonly ThinkingLevel[] {\n\tif (!model) return ALL_LEVELS_5;\n\tif (model.reasoning === false) return [\"off\" as const];\n\treturn ALL_LEVELS.filter((level) => {\n\t\tconst mapped = model.thinkingLevelMap?.[level];\n\t\tif (mapped === null) return false;\n\t\tif (level === \"xhigh\" || level === \"max\") return mapped !== undefined;\n\t\treturn true;\n\t});\n}\n\n/** Builds the inline `<padded level> — <description>` label for a level. */\nfunction formatLevelLabel(level: ThinkingLevel): string {\n\treturn `${level.padEnd(8)} \\u2014 ${THINKING_DESCRIPTIONS[level]}`;\n}\n\n// ---------------------------------------------------------------------------\n// Persisted thinking-block visibility (hideThinkingBlock)\n//\n// pi has no public extension API to toggle thinking-block visibility live.\n// The live in-session toggle is `app.thinking.toggle` (unbound by default) wired to\n// `toggleThinkingBlockVisibility()` in interactive-mode.js, which calls\n// `SettingsManager.setHideThinkingBlock()` + rebuilds the chat. That method is\n// not exposed on ExtensionContext / ExtensionCommandContext / ExtensionAPI.\n// Ctrl+T cycles thinking level (`app.thinking.cycle`).\n//\n// What extensions CAN do is persist the `hideThinkingBlock` boolean to the\n// global agent settings file (`~/.lunr/agent/settings.json`); the\n// `SettingsManager` reads it on startup. And because `ctx.reload()` drives\n// `session.reload()` → `settingsManager.reload()` (re-reads disk) →\n// `restoreChatBeforeSessionStart()` copies the new value into\n// `this.hideThinkingBlock` and calls `rebuildChatFromMessages()` (which\n// reconstructs every AssistantMessageComponent with the new hide flag), the\n// persisted value IS live-applied within the session by `await ctx.reload()`\n// (verified against pi 0.80.3). In non-TUI modes `ctx.reload()` is a no-op,\n// so the setting simply applies on next start.\n//\n// `/thinking show|hide|toggle` is the discoverable, persistable path.\n// ---------------------------------------------------------------------------\n\n/** Returns the path to lunR's global agent settings file.\n * lunr: lunR's agent dir is `~/.lunr/agent` (upstream hardcoded `~/.pi/agent`).\n * Honors the `PI_CODING_AGENT_DIR` env override like core config.ts does;\n * a custom agent dir is not exposed to extensions, so this is the only\n * location we can write to be picked up by\n * `SettingsManager.tryLoadFromStorage(\"global\")`. */\nfunction agentSettingsPath(): string {\n\tconst envDir = process.env.PI_CODING_AGENT_DIR;\n\tif (envDir) {\n\t\t// Match core normalizePath(): expand a leading ~ (~/ and, on win32, ~\\).\n\t\tconst home = homedir();\n\t\tconst expanded =\n\t\t\tenvDir === \"~\"\n\t\t\t\t? home\n\t\t\t\t: envDir.startsWith(\"~/\") || (process.platform === \"win32\" && envDir.startsWith(\"~\\\\\"))\n\t\t\t\t\t? join(home, envDir.slice(2))\n\t\t\t\t\t: envDir;\n\t\treturn join(expanded, \"settings.json\");\n\t}\n\treturn join(homedir(), \".lunr\", \"agent\", \"settings.json\");\n}\n\n// ---------------------------------------------------------------------------\n// lunR customize bridge for persisted thinking-block visibility.\n// When the bridge is present (TUI / gateway sessions), reads/writes go through\n// SettingsManager (lockfile + merge). Falls back to direct file I/O when the\n// extension loads in a context without the bridge (e.g. upstream pi).\n// ---------------------------------------------------------------------------\ninterface CustomizeBridge {\n\tgetHideThinkingBlock(): boolean;\n\tsetHideThinkingBlock(hide: boolean): void;\n}\n\nfunction getCustomizeBridge(): CustomizeBridge | undefined {\n\treturn (globalThis as Record<symbol, unknown>)[Symbol.for(\"@lunr/customize\")] as CustomizeBridge | undefined;\n}\n\n/** Returns the persisted `hideThinkingBlock` value (default false, matching\n * `getHideThinkingBlock()` which returns `this.settings.hideThinkingBlock ?? false`).\n * Never throws — on any error (missing file, bad JSON) returns false. */\nfunction readHideThinkingBlock(): boolean {\n\tconst bridge = getCustomizeBridge();\n\tif (bridge) return bridge.getHideThinkingBlock();\n\ttry {\n\t\tconst p = agentSettingsPath();\n\t\tif (!existsSync(p)) return false;\n\t\tconst cfg = JSON.parse(readFileSync(p, \"utf8\")) as { hideThinkingBlock?: boolean };\n\t\treturn cfg.hideThinkingBlock === true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Persist `hideThinkingBlock` to the global agent settings file (safe merge).\n *\n * - Preserves all other keys (merge, never overwrite the whole file).\n * - Matches pi's 2-space indentation + trailing newline.\n * - On invalid JSON in the existing file, backs it up to `settings.json.bak`\n * before writing a fresh file, so a corrupted file is never written back.\n * - Never throws; on any error `ok` is false and the caller notifies the user.\n *\n * `createdFresh` is true when the file didn't exist (or was corrupt and backed\n * up) before this write — the handler uses it to warn that a global settings\n * file was created here.\n */\nfunction writeHideThinkingBlock(hide: boolean): {\n\tok: boolean;\n\tcreatedFresh: boolean;\n} {\n\tconst bridge = getCustomizeBridge();\n\tif (bridge) {\n\t\ttry {\n\t\t\tbridge.setHideThinkingBlock(hide);\n\t\t\treturn { ok: true, createdFresh: false };\n\t\t} catch {\n\t\t\treturn { ok: false, createdFresh: false };\n\t\t}\n\t}\n\ttry {\n\t\tconst p = agentSettingsPath();\n\t\tlet cfg: Record<string, unknown> = {};\n\t\tlet createdFresh = false;\n\t\tif (existsSync(p)) {\n\t\t\ttry {\n\t\t\t\tcfg = JSON.parse(readFileSync(p, \"utf8\")) as Record<string, unknown>;\n\t\t\t} catch {\n\t\t\t\t// Existing file is corrupt — back it up, then start fresh.\n\t\t\t\ttry {\n\t\t\t\t\trenameSync(p, `${p}.bak`);\n\t\t\t\t} catch {\n\t\t\t\t\t// If backup fails, still proceed to overwrite (best effort).\n\t\t\t\t}\n\t\t\t\tcfg = {};\n\t\t\t\tcreatedFresh = true;\n\t\t\t}\n\t\t} else {\n\t\t\tcreatedFresh = true;\n\t\t}\n\t\tcfg.hideThinkingBlock = hide;\n\t\twriteFileSync(p, JSON.stringify(cfg, null, 2) + \"\\n\", \"utf8\");\n\t\treturn { ok: true, createdFresh };\n\t} catch {\n\t\treturn { ok: false, createdFresh: false };\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Extension entry point\n// ---------------------------------------------------------------------------\n\nconst THINKING_COMMAND_DESCRIPTION =\n\t\"View or set the reasoning level for the current model, or toggle thinking-block visibility with show/hide/toggle\";\n\nexport default function (pi: ExtensionAPI): void {\n\tsessionModel = undefined;\n\tif (typeof pi.on === \"function\") {\n\t\tpi.on(\"session_start\", (_event, ctx) => {\n\t\t\tsessionModel = ctx.model;\n\t\t});\n\t\tpi.on(\"model_select\", (event, ctx) => {\n\t\t\tconst selected = (event as { model?: ModelLike } | undefined)?.model;\n\t\t\tsessionModel = ctx.model ?? selected;\n\t\t});\n\t}\n\n\tconst thinkingSpec = {\n\t\tdescription: THINKING_COMMAND_DESCRIPTION,\n\t\tgetArgumentCompletions(prefix: string): AutocompleteItem[] {\n\t\t\tconst lower = prefix.toLowerCase();\n\t\t\t// Visibility sub-options first, filtered by prefix, alongside the levels.\n\t\t\tconst visibility: AutocompleteItem[] = [\n\t\t\t\t{ value: \"show\", label: \"show\", description: \"Show thinking blocks (persisted to settings.json)\" },\n\t\t\t\t{ value: \"hide\", label: \"hide\", description: \"Hide thinking blocks (persisted to settings.json)\" },\n\t\t\t\t{ value: \"toggle\", label: \"toggle\", description: \"Toggle thinking blocks (persisted to settings.json)\" },\n\t\t\t];\n\t\t\tconst levels = availableLevelsFor(currentModel(pi));\n\t\t\tconst levelItems = levels\n\t\t\t\t.filter((lvl) => lvl.startsWith(lower))\n\t\t\t\t.map((lvl) => ({ value: lvl, label: lvl, description: THINKING_DESCRIPTIONS[lvl] }));\n\t\t\treturn [\n\t\t\t\t...visibility.filter((v) => v.value.startsWith(lower)),\n\t\t\t\t...levelItems,\n\t\t\t];\n\t\t},\n\t\thandler: async (args: string, ctx: ExtensionCommandContextLike) => {\n\t\t\tconst trimmed = args.trim();\n\t\t\tconst lower = trimmed.toLowerCase();\n\n\t\t\t// ---- Visibility sub-options: /thinking show | hide | toggle ----\n\t\t\t// Caught first so `hide`/`show`/`toggle` are never parsed as levels.\n\t\t\t// Works in every mode: only uses ctx.ui.notify + file I/O + ctx.reload().\n\t\t\tif (lower === \"show\" || lower === \"hide\" || lower === \"toggle\") {\n\t\t\t\tconst current = readHideThinkingBlock();\n\t\t\t\tconst next = lower === \"toggle\" ? !current : lower === \"hide\";\n\t\t\t\tif (next === current) {\n\t\t\t\t\tctx.ui.notify(`Thinking blocks already ${current ? \"hidden\" : \"shown\"}.`, \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst result = writeHideThinkingBlock(next);\n\t\t\t\tif (!result.ok) {\n\t\t\t\t\t// lunr: settings path is lunR's (see agentSettingsPath).\n\t\t\t\t\tctx.ui.notify(`Failed to update ${agentSettingsPath()}`, \"error\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// The notify MUST run before `await ctx.reload()`: after reload the\n\t\t\t\t// loader invalidates this `ctx`/`pi` as stale. ctx.reload() live-\n\t\t\t\t// applies the setting (verified against pi 0.80.3: it drives\n\t\t\t\t// session.reload() → settingsManager.reload() re-reads disk →\n\t\t\t\t// restoreChatBeforeSessionStart copies the new value into\n\t\t\t\t// this.hideThinkingBlock → rebuildChatFromMessages() rebuilds every\n\t\t\t\t// AssistantMessageComponent with the new hide flag). In non-TUI\n\t\t\t\t// modes ctx.reload() is a no-op; the setting then applies on next\n\t\t\t\t// start.\n\t\t\t\tconst verb = next ? \"hidden\" : \"shown\";\n\t\t\t\tconst note = result.createdFresh\n\t\t\t\t\t? `Thinking blocks ${verb}. (Created ${agentSettingsPath()} with this setting.)`\n\t\t\t\t\t: `Thinking blocks ${verb}.`;\n\t\t\t\tctx.ui.notify(note, \"info\");\n\t\t\t\tawait ctx.reload();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst levels = availableLevelsFor(ctx.model);\n\t\t\tconst currentLevel: ThinkingLevel = pi.getThinkingLevel();\n\t\t\tconst validSet = new Set<ThinkingLevel>(levels);\n\n\t\t\t// No-arg form → open a picker. Skip in non-TUI modes — same pattern\n\t\t\t// as batxj-animations per AGENTS.md §5.\n\t\t\tif (trimmed === \"\") {\n\t\t\t\tif (ctx.mode !== \"tui\") {\n\t\t\t\t\tctx.ui.notify(`Thinking level: ${currentLevel}`, \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (levels.length === 0) {\n\t\t\t\t\tctx.ui.notify(\"No thinking levels available for this model.\", \"warning\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst options = levels.map((lvl) =>\n\t\t\t\t\t(lvl === currentLevel ? \"\\u25CF \" : \" \") + formatLevelLabel(lvl),\n\t\t\t\t);\n\t\t\t\tconst chosen = await ctx.ui.select(\n\t\t\t\t\t`Thinking level (current: ${currentLevel})`,\n\t\t\t\t\toptions,\n\t\t\t\t);\n\t\t\t\tif (chosen === undefined) return;\n\t\t\t\t// Chosen string starts with the current-marker (\"● \") or two-space\n\t\t\t\t// gutter; strip the prefix and extract the first token (the level).\n\t\t\t\tconst stripped = chosen.replace(/^[\\u25CF ]\\s?/, \"\").trimStart();\n\t\t\t\tconst level = stripped.split(/\\s+/)[0] as ThinkingLevel;\n\t\t\t\tif (!validSet.has(level)) {\n\t\t\t\t\tctx.ui.notify(`Unsupported thinking level: ${level}`, \"error\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (level === currentLevel) return; // no-op\n\t\t\t\tpi.setThinkingLevel(level);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Direct-set form: `/thinking <level>`\n\t\t\tconst requested = trimmed.toLowerCase() as ThinkingLevel;\n\t\t\tif (!validSet.has(requested)) {\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Invalid thinking level: \"${trimmed}\". Valid: ${levels.join(\", \")}`,\n\t\t\t\t\t\"error\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (requested === currentLevel) return;\n\t\t\tpi.setThinkingLevel(requested);\n\t\t},\n\t};\n\n\tpi.registerCommand(\"thinking\", thinkingSpec);\n\t// lunr: /effort and /reasoning are full-parity aliases (same handler + completions).\n\tpi.registerCommand(\"effort\", {\n\t\t...thinkingSpec,\n\t\tdescription: `${THINKING_COMMAND_DESCRIPTION} (alias of /thinking)`,\n\t});\n\tpi.registerCommand(\"reasoning\", {\n\t\t...thinkingSpec,\n\t\tdescription: `${THINKING_COMMAND_DESCRIPTION} (alias of /thinking)`,\n\t});\n\n\tfor (const level of ALL_LEVELS) {\n\t\tpi.registerCommand(level, {\n\t\t\tdescription: `Set thinking level to ${level}`,\n\t\t\thandler: async (_args, ctx) => {\n\t\t\t\tconst levels = availableLevelsFor(ctx.model);\n\t\t\t\tif (!levels.includes(level)) {\n\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t`Invalid thinking level: \"${level}\". Valid: ${levels.join(\", \")}`,\n\t\t\t\t\t\t\"error\",\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (pi.getThinkingLevel() === level) return;\n\t\t\t\tpi.setThinkingLevel(level);\n\t\t\t},\n\t\t});\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Live session model for `/thinking ` completions.\n * `getArgumentCompletions` runs on the extension `pi` object, which has no\n * `getModel`. Cache the model from session_start / model_select, and still\n * duck-type `getModel` when a test or future API exposes it.\n */\nlet sessionModel: ModelLike | undefined;\n\nfunction currentModel(pi: ExtensionAPI): ModelLike | undefined {\n\tconst fn = (pi as unknown as { getModel?: () => unknown }).getModel;\n\tif (typeof fn === \"function\") {\n\t\ttry {\n\t\t\tconst model = fn.call(pi) as ModelLike | undefined;\n\t\t\tif (model) return model;\n\t\t} catch {\n\t\t\t// runtime not bound yet\n\t\t}\n\t}\n\treturn sessionModel;\n}\n"]}
@@ -66,10 +66,11 @@ function formatLevelLabel(level) {
66
66
  // Persisted thinking-block visibility (hideThinkingBlock)
67
67
  //
68
68
  // pi has no public extension API to toggle thinking-block visibility live.
69
- // The live in-session toggle is `app.thinking.toggle` (default Ctrl+T) wired to
69
+ // The live in-session toggle is `app.thinking.toggle` (unbound by default) wired to
70
70
  // `toggleThinkingBlockVisibility()` in interactive-mode.js, which calls
71
71
  // `SettingsManager.setHideThinkingBlock()` + rebuilds the chat. That method is
72
72
  // not exposed on ExtensionContext / ExtensionCommandContext / ExtensionAPI.
73
+ // Ctrl+T cycles thinking level (`app.thinking.cycle`).
73
74
  //
74
75
  // What extensions CAN do is persist the `hideThinkingBlock` boolean to the
75
76
  // global agent settings file (`~/.lunr/agent/settings.json`); the
@@ -82,9 +83,7 @@ function formatLevelLabel(level) {
82
83
  // (verified against pi 0.80.3). In non-TUI modes `ctx.reload()` is a no-op,
83
84
  // so the setting simply applies on next start.
84
85
  //
85
- // The instant keybinding path (Ctrl+T) still works and is the lowest-latency
86
- // toggle; the command is the discoverable, persistable, completions-friendly
87
- // equivalent.
86
+ // `/thinking show|hide|toggle` is the discoverable, persistable path.
88
87
  // ---------------------------------------------------------------------------
89
88
  /** Returns the path to lunR's global agent settings file.
90
89
  * lunr: lunR's agent dir is `~/.lunr/agent` (upstream hardcoded `~/.pi/agent`).
@@ -187,6 +186,16 @@ function writeHideThinkingBlock(hide) {
187
186
  // ---------------------------------------------------------------------------
188
187
  const THINKING_COMMAND_DESCRIPTION = "View or set the reasoning level for the current model, or toggle thinking-block visibility with show/hide/toggle";
189
188
  export default function (pi) {
189
+ sessionModel = undefined;
190
+ if (typeof pi.on === "function") {
191
+ pi.on("session_start", (_event, ctx) => {
192
+ sessionModel = ctx.model;
193
+ });
194
+ pi.on("model_select", (event, ctx) => {
195
+ const selected = event?.model;
196
+ sessionModel = ctx.model ?? selected;
197
+ });
198
+ }
190
199
  const thinkingSpec = {
191
200
  description: THINKING_COMMAND_DESCRIPTION,
192
201
  getArgumentCompletions(prefix) {
@@ -233,7 +242,7 @@ export default function (pi) {
233
242
  // this.hideThinkingBlock → rebuildChatFromMessages() rebuilds every
234
243
  // AssistantMessageComponent with the new hide flag). In non-TUI
235
244
  // modes ctx.reload() is a no-op; the setting then applies on next
236
- // start. The instant keybinding path (Ctrl+T) also still works.
245
+ // start.
237
246
  const verb = next ? "hidden" : "shown";
238
247
  const note = result.createdFresh
239
248
  ? `Thinking blocks ${verb}. (Created ${agentSettingsPath()} with this setting.)`
@@ -271,7 +280,6 @@ export default function (pi) {
271
280
  if (level === currentLevel)
272
281
  return; // no-op
273
282
  pi.setThinkingLevel(level);
274
- ctx.ui.notify(`Thinking level: ${pi.getThinkingLevel()}`, "info");
275
283
  return;
276
284
  }
277
285
  // Direct-set form: `/thinking <level>`
@@ -280,12 +288,9 @@ export default function (pi) {
280
288
  ctx.ui.notify(`Invalid thinking level: "${trimmed}". Valid: ${levels.join(", ")}`, "error");
281
289
  return;
282
290
  }
283
- if (requested === currentLevel) {
284
- ctx.ui.notify(`Thinking level: ${requested} (unchanged)`, "info");
291
+ if (requested === currentLevel)
285
292
  return;
286
- }
287
293
  pi.setThinkingLevel(requested);
288
- ctx.ui.notify(`Thinking level: ${pi.getThinkingLevel()}`, "info");
289
294
  },
290
295
  };
291
296
  pi.registerCommand("thinking", thinkingSpec);
@@ -298,24 +303,44 @@ export default function (pi) {
298
303
  ...thinkingSpec,
299
304
  description: `${THINKING_COMMAND_DESCRIPTION} (alias of /thinking)`,
300
305
  });
306
+ for (const level of ALL_LEVELS) {
307
+ pi.registerCommand(level, {
308
+ description: `Set thinking level to ${level}`,
309
+ handler: async (_args, ctx) => {
310
+ const levels = availableLevelsFor(ctx.model);
311
+ if (!levels.includes(level)) {
312
+ ctx.ui.notify(`Invalid thinking level: "${level}". Valid: ${levels.join(", ")}`, "error");
313
+ return;
314
+ }
315
+ if (pi.getThinkingLevel() === level)
316
+ return;
317
+ pi.setThinkingLevel(level);
318
+ },
319
+ });
320
+ }
301
321
  }
302
322
  // ---------------------------------------------------------------------------
303
323
  // Helpers
304
324
  // ---------------------------------------------------------------------------
305
325
  /**
306
- * Read the current model from the ExtensionAPI runtime. The spec mentions
307
- * `pi.getModel()`; pi doesn't expose that name on the API object itself, but
308
- * the bound `ExtensionContextActions` (which the runtime decorates onto
309
- * events) does include `getModel()`. We duck-type against the loader so this
310
- * file stays decoupled from non-public internals. When unavailable (e.g.
311
- * during autocomplete, before any session has bound), returns undefined and
312
- * the caller falls back to the default 5-level set.
326
+ * Live session model for `/thinking ` completions.
327
+ * `getArgumentCompletions` runs on the extension `pi` object, which has no
328
+ * `getModel`. Cache the model from session_start / model_select, and still
329
+ * duck-type `getModel` when a test or future API exposes it.
313
330
  */
331
+ let sessionModel;
314
332
  function currentModel(pi) {
315
333
  const fn = pi.getModel;
316
334
  if (typeof fn === "function") {
317
- return fn.call(pi);
335
+ try {
336
+ const model = fn.call(pi);
337
+ if (model)
338
+ return model;
339
+ }
340
+ catch {
341
+ // runtime not bound yet
342
+ }
318
343
  }
319
- return undefined;
344
+ return sessionModel;
320
345
  }
321
346
  //# sourceMappingURL=ashxj-thinking.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ashxj-thinking.js","sourceRoot":"","sources":["../../src/builtin-extensions/ashxj-thinking.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\n// Vendored from https://github.com/ashx-j/ashxj-thinking @ 0330a34\n// (\"Remove custom footer — keep only /thinking command\"), single-file ashxj\n// convention. lunR patches are marked `// lunr:`.\n/**\n * batxj-thinking extension\n *\n * `/thinking [level]` slash command to view or set the reasoning level,\n * plus `/thinking show|hide|toggle` for thinking-block visibility.\n * `/effort` and `/reasoning` are full-parity aliases.\n *\n * Loaded by pi via jiti — no build step, plain TypeScript.\n *\n * NOTE on type imports: this file deliberately declares structural types\n * rather than importing from `@ashx-j/lunr-dev` (or\n * `@ashx-j/lunr-tui`). pi-coding-agent's `index.d.ts` re-exports\n * from internal `.d.ts` files that contain subpath imports like\n * `@ashx-j/lunr-ai/compat`, which fail to resolve under the default\n * `tsc` settings when a file argument is passed (the spec'd\n * `tsc --noEmit index.ts` script). Declaring the types we use inline\n * keeps the typecheck self-contained.\n */\n\nimport { readFileSync, writeFileSync, existsSync, renameSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\n// ---------------------------------------------------------------------------\n// Minimal structural types (see file header for why these are inline)\n// ---------------------------------------------------------------------------\n\n/** Mirrored from `@ashx-j/lunr-agent` `ThinkingLevel`. */\n// lunr: added \"max\" — lunR's ThinkingLevel union includes it.\ntype ThinkingLevel = \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\n/** Mirrored from `@ashx-j/lunr-tui` `AutocompleteItem`. */\ninterface AutocompleteItem {\n\tvalue: string;\n\tlabel: string;\n\tdescription?: string;\n}\n\n/** A trimmed view of a `Model` — only the fields the picker reads. */\ninterface ModelLike {\n\tid?: string;\n\treasoning?: boolean;\n\tthinkingLevelMap?: Record<string, string | null>;\n}\n\n/** A trimmed view of `ExtensionContext` — only the methods/props we use. */\ninterface ExtensionContextLike {\n\tmode: \"tui\" | \"rpc\" | \"json\" | \"print\";\n\tmodel: ModelLike | undefined;\n\tui: {\n\t\tnotify(message: string, type?: \"info\" | \"warning\" | \"error\"): void;\n\t\tselect(title: string, options: string[], opts?: { signal?: AbortSignal; timeout?: number }): Promise<string | undefined>;\n\t};\n}\n\n/** A trimmed view of `ExtensionCommandContext` — only the methods/props we use. */\ninterface ExtensionCommandContextLike extends ExtensionContextLike {\n\tgetThinkingLevel(): ThinkingLevel;\n\t/** Reload extensions, skills, prompts, and themes. Re-reads settings.json\n\t * from disk (session.reload() → settingsManager.reload()), so persisted\n\t * runtime settings like `hideThinkingBlock` are live-applied. The captured\n\t * `ctx`/`pi` are stale after this resolves — do not use them afterward. */\n\treload(): Promise<void>;\n}\n\n/** A trimmed view of `ExtensionAPI` — only the methods we use. */\ninterface ExtensionAPI {\n\tregisterCommand(name: string, options: {\n\t\tdescription?: string;\n\t\tgetArgumentCompletions?(prefix: string): AutocompleteItem[] | null | Promise<AutocompleteItem[] | null>;\n\t\thandler(args: string, ctx: ExtensionCommandContextLike): Promise<void> | void;\n\t}): void;\n\tgetThinkingLevel(): ThinkingLevel;\n\tsetThinkingLevel(level: ThinkingLevel): void;\n}\n\n// ---------------------------------------------------------------------------\n// Thinking level config\n// ---------------------------------------------------------------------------\n\n/** All known levels, in display order. Mirrors `EXTENDED_THINKING_LEVELS` in pi-ai. */\nconst ALL_LEVELS: readonly ThinkingLevel[] = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"];\n/** Default 5 — used when the active model is undefined (we don't know whether `xhigh`/`max` are supported). */\nconst ALL_LEVELS_5: readonly ThinkingLevel[] = [\"off\", \"minimal\", \"low\", \"medium\", \"high\"];\n\n/** Per-level descriptions. Mirrored from `THINKING_DESCRIPTIONS` in settings-selector.ts. */\nconst THINKING_DESCRIPTIONS: Record<ThinkingLevel, string> = {\n\toff: \"No reasoning\",\n\tminimal: \"Very brief reasoning\",\n\tlow: \"Light reasoning\",\n\tmedium: \"Moderate reasoning\",\n\thigh: \"Deep reasoning\",\n\txhigh: \"Extra-high reasoning\",\n\t// lunr: added — mirrors settings-selector.ts.\n\tmax: \"Maximum reasoning\",\n};\n\n/** Returns the levels valid for the given model, in display order.\n * Mirrors `getSupportedThinkingLevels` in pi-ai: `xhigh`/`max` are opt-in\n * (non-null map entry); other levels drop only on an explicit null. */\nfunction availableLevelsFor(model: ModelLike | undefined): readonly ThinkingLevel[] {\n\tif (!model) return ALL_LEVELS_5;\n\tif (model.reasoning === false) return [\"off\" as const];\n\treturn ALL_LEVELS.filter((level) => {\n\t\tconst mapped = model.thinkingLevelMap?.[level];\n\t\tif (mapped === null) return false;\n\t\tif (level === \"xhigh\" || level === \"max\") return mapped !== undefined;\n\t\treturn true;\n\t});\n}\n\n/** Builds the inline `<padded level> — <description>` label for a level. */\nfunction formatLevelLabel(level: ThinkingLevel): string {\n\treturn `${level.padEnd(8)} \\u2014 ${THINKING_DESCRIPTIONS[level]}`;\n}\n\n// ---------------------------------------------------------------------------\n// Persisted thinking-block visibility (hideThinkingBlock)\n//\n// pi has no public extension API to toggle thinking-block visibility live.\n// The live in-session toggle is `app.thinking.toggle` (default Ctrl+T) wired to\n// `toggleThinkingBlockVisibility()` in interactive-mode.js, which calls\n// `SettingsManager.setHideThinkingBlock()` + rebuilds the chat. That method is\n// not exposed on ExtensionContext / ExtensionCommandContext / ExtensionAPI.\n//\n// What extensions CAN do is persist the `hideThinkingBlock` boolean to the\n// global agent settings file (`~/.lunr/agent/settings.json`); the\n// `SettingsManager` reads it on startup. And because `ctx.reload()` drives\n// `session.reload()` → `settingsManager.reload()` (re-reads disk) →\n// `restoreChatBeforeSessionStart()` copies the new value into\n// `this.hideThinkingBlock` and calls `rebuildChatFromMessages()` (which\n// reconstructs every AssistantMessageComponent with the new hide flag), the\n// persisted value IS live-applied within the session by `await ctx.reload()`\n// (verified against pi 0.80.3). In non-TUI modes `ctx.reload()` is a no-op,\n// so the setting simply applies on next start.\n//\n// The instant keybinding path (Ctrl+T) still works and is the lowest-latency\n// toggle; the command is the discoverable, persistable, completions-friendly\n// equivalent.\n// ---------------------------------------------------------------------------\n\n/** Returns the path to lunR's global agent settings file.\n * lunr: lunR's agent dir is `~/.lunr/agent` (upstream hardcoded `~/.pi/agent`).\n * Honors the `PI_CODING_AGENT_DIR` env override like core config.ts does;\n * a custom agent dir is not exposed to extensions, so this is the only\n * location we can write to be picked up by\n * `SettingsManager.tryLoadFromStorage(\"global\")`. */\nfunction agentSettingsPath(): string {\n\tconst envDir = process.env.PI_CODING_AGENT_DIR;\n\tif (envDir) {\n\t\t// Match core normalizePath(): expand a leading ~ (~/ and, on win32, ~\\).\n\t\tconst home = homedir();\n\t\tconst expanded =\n\t\t\tenvDir === \"~\"\n\t\t\t\t? home\n\t\t\t\t: envDir.startsWith(\"~/\") || (process.platform === \"win32\" && envDir.startsWith(\"~\\\\\"))\n\t\t\t\t\t? join(home, envDir.slice(2))\n\t\t\t\t\t: envDir;\n\t\treturn join(expanded, \"settings.json\");\n\t}\n\treturn join(homedir(), \".lunr\", \"agent\", \"settings.json\");\n}\n\n// ---------------------------------------------------------------------------\n// lunR customize bridge for persisted thinking-block visibility.\n// When the bridge is present (TUI / gateway sessions), reads/writes go through\n// SettingsManager (lockfile + merge). Falls back to direct file I/O when the\n// extension loads in a context without the bridge (e.g. upstream pi).\n// ---------------------------------------------------------------------------\ninterface CustomizeBridge {\n\tgetHideThinkingBlock(): boolean;\n\tsetHideThinkingBlock(hide: boolean): void;\n}\n\nfunction getCustomizeBridge(): CustomizeBridge | undefined {\n\treturn (globalThis as Record<symbol, unknown>)[Symbol.for(\"@lunr/customize\")] as CustomizeBridge | undefined;\n}\n\n/** Returns the persisted `hideThinkingBlock` value (default false, matching\n * `getHideThinkingBlock()` which returns `this.settings.hideThinkingBlock ?? false`).\n * Never throws — on any error (missing file, bad JSON) returns false. */\nfunction readHideThinkingBlock(): boolean {\n\tconst bridge = getCustomizeBridge();\n\tif (bridge) return bridge.getHideThinkingBlock();\n\ttry {\n\t\tconst p = agentSettingsPath();\n\t\tif (!existsSync(p)) return false;\n\t\tconst cfg = JSON.parse(readFileSync(p, \"utf8\")) as { hideThinkingBlock?: boolean };\n\t\treturn cfg.hideThinkingBlock === true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Persist `hideThinkingBlock` to the global agent settings file (safe merge).\n *\n * - Preserves all other keys (merge, never overwrite the whole file).\n * - Matches pi's 2-space indentation + trailing newline.\n * - On invalid JSON in the existing file, backs it up to `settings.json.bak`\n * before writing a fresh file, so a corrupted file is never written back.\n * - Never throws; on any error `ok` is false and the caller notifies the user.\n *\n * `createdFresh` is true when the file didn't exist (or was corrupt and backed\n * up) before this write — the handler uses it to warn that a global settings\n * file was created here.\n */\nfunction writeHideThinkingBlock(hide: boolean): {\n\tok: boolean;\n\tcreatedFresh: boolean;\n} {\n\tconst bridge = getCustomizeBridge();\n\tif (bridge) {\n\t\ttry {\n\t\t\tbridge.setHideThinkingBlock(hide);\n\t\t\treturn { ok: true, createdFresh: false };\n\t\t} catch {\n\t\t\treturn { ok: false, createdFresh: false };\n\t\t}\n\t}\n\ttry {\n\t\tconst p = agentSettingsPath();\n\t\tlet cfg: Record<string, unknown> = {};\n\t\tlet createdFresh = false;\n\t\tif (existsSync(p)) {\n\t\t\ttry {\n\t\t\t\tcfg = JSON.parse(readFileSync(p, \"utf8\")) as Record<string, unknown>;\n\t\t\t} catch {\n\t\t\t\t// Existing file is corrupt — back it up, then start fresh.\n\t\t\t\ttry {\n\t\t\t\t\trenameSync(p, `${p}.bak`);\n\t\t\t\t} catch {\n\t\t\t\t\t// If backup fails, still proceed to overwrite (best effort).\n\t\t\t\t}\n\t\t\t\tcfg = {};\n\t\t\t\tcreatedFresh = true;\n\t\t\t}\n\t\t} else {\n\t\t\tcreatedFresh = true;\n\t\t}\n\t\tcfg.hideThinkingBlock = hide;\n\t\twriteFileSync(p, JSON.stringify(cfg, null, 2) + \"\\n\", \"utf8\");\n\t\treturn { ok: true, createdFresh };\n\t} catch {\n\t\treturn { ok: false, createdFresh: false };\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Extension entry point\n// ---------------------------------------------------------------------------\n\nconst THINKING_COMMAND_DESCRIPTION =\n\t\"View or set the reasoning level for the current model, or toggle thinking-block visibility with show/hide/toggle\";\n\nexport default function (pi: ExtensionAPI): void {\n\tconst thinkingSpec = {\n\t\tdescription: THINKING_COMMAND_DESCRIPTION,\n\t\tgetArgumentCompletions(prefix: string): AutocompleteItem[] {\n\t\t\tconst lower = prefix.toLowerCase();\n\t\t\t// Visibility sub-options first, filtered by prefix, alongside the levels.\n\t\t\tconst visibility: AutocompleteItem[] = [\n\t\t\t\t{ value: \"show\", label: \"show\", description: \"Show thinking blocks (persisted to settings.json)\" },\n\t\t\t\t{ value: \"hide\", label: \"hide\", description: \"Hide thinking blocks (persisted to settings.json)\" },\n\t\t\t\t{ value: \"toggle\", label: \"toggle\", description: \"Toggle thinking blocks (persisted to settings.json)\" },\n\t\t\t];\n\t\t\tconst levels = availableLevelsFor(currentModel(pi));\n\t\t\tconst levelItems = levels\n\t\t\t\t.filter((lvl) => lvl.startsWith(lower))\n\t\t\t\t.map((lvl) => ({ value: lvl, label: lvl, description: THINKING_DESCRIPTIONS[lvl] }));\n\t\t\treturn [\n\t\t\t\t...visibility.filter((v) => v.value.startsWith(lower)),\n\t\t\t\t...levelItems,\n\t\t\t];\n\t\t},\n\t\thandler: async (args: string, ctx: ExtensionCommandContextLike) => {\n\t\t\tconst trimmed = args.trim();\n\t\t\tconst lower = trimmed.toLowerCase();\n\n\t\t\t// ---- Visibility sub-options: /thinking show | hide | toggle ----\n\t\t\t// Caught first so `hide`/`show`/`toggle` are never parsed as levels.\n\t\t\t// Works in every mode: only uses ctx.ui.notify + file I/O + ctx.reload().\n\t\t\tif (lower === \"show\" || lower === \"hide\" || lower === \"toggle\") {\n\t\t\t\tconst current = readHideThinkingBlock();\n\t\t\t\tconst next = lower === \"toggle\" ? !current : lower === \"hide\";\n\t\t\t\tif (next === current) {\n\t\t\t\t\tctx.ui.notify(`Thinking blocks already ${current ? \"hidden\" : \"shown\"}.`, \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst result = writeHideThinkingBlock(next);\n\t\t\t\tif (!result.ok) {\n\t\t\t\t\t// lunr: settings path is lunR's (see agentSettingsPath).\n\t\t\t\t\tctx.ui.notify(`Failed to update ${agentSettingsPath()}`, \"error\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// The notify MUST run before `await ctx.reload()`: after reload the\n\t\t\t\t// loader invalidates this `ctx`/`pi` as stale. ctx.reload() live-\n\t\t\t\t// applies the setting (verified against pi 0.80.3: it drives\n\t\t\t\t// session.reload() → settingsManager.reload() re-reads disk →\n\t\t\t\t// restoreChatBeforeSessionStart copies the new value into\n\t\t\t\t// this.hideThinkingBlock → rebuildChatFromMessages() rebuilds every\n\t\t\t\t// AssistantMessageComponent with the new hide flag). In non-TUI\n\t\t\t\t// modes ctx.reload() is a no-op; the setting then applies on next\n\t\t\t\t// start. The instant keybinding path (Ctrl+T) also still works.\n\t\t\t\tconst verb = next ? \"hidden\" : \"shown\";\n\t\t\t\tconst note = result.createdFresh\n\t\t\t\t\t? `Thinking blocks ${verb}. (Created ${agentSettingsPath()} with this setting.)`\n\t\t\t\t\t: `Thinking blocks ${verb}.`;\n\t\t\t\tctx.ui.notify(note, \"info\");\n\t\t\t\tawait ctx.reload();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst levels = availableLevelsFor(ctx.model);\n\t\t\tconst currentLevel: ThinkingLevel = pi.getThinkingLevel();\n\t\t\tconst validSet = new Set<ThinkingLevel>(levels);\n\n\t\t\t// No-arg form → open a picker. Skip in non-TUI modes — same pattern\n\t\t\t// as batxj-animations per AGENTS.md §5.\n\t\t\tif (trimmed === \"\") {\n\t\t\t\tif (ctx.mode !== \"tui\") {\n\t\t\t\t\tctx.ui.notify(`Thinking level: ${currentLevel}`, \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (levels.length === 0) {\n\t\t\t\t\tctx.ui.notify(\"No thinking levels available for this model.\", \"warning\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst options = levels.map((lvl) =>\n\t\t\t\t\t(lvl === currentLevel ? \"\\u25CF \" : \" \") + formatLevelLabel(lvl),\n\t\t\t\t);\n\t\t\t\tconst chosen = await ctx.ui.select(\n\t\t\t\t\t`Thinking level (current: ${currentLevel})`,\n\t\t\t\t\toptions,\n\t\t\t\t);\n\t\t\t\tif (chosen === undefined) return;\n\t\t\t\t// Chosen string starts with the current-marker (\"● \") or two-space\n\t\t\t\t// gutter; strip the prefix and extract the first token (the level).\n\t\t\t\tconst stripped = chosen.replace(/^[\\u25CF ]\\s?/, \"\").trimStart();\n\t\t\t\tconst level = stripped.split(/\\s+/)[0] as ThinkingLevel;\n\t\t\t\tif (!validSet.has(level)) {\n\t\t\t\t\tctx.ui.notify(`Unsupported thinking level: ${level}`, \"error\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (level === currentLevel) return; // no-op\n\t\t\t\tpi.setThinkingLevel(level);\n\t\t\t\tctx.ui.notify(`Thinking level: ${pi.getThinkingLevel()}`, \"info\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Direct-set form: `/thinking <level>`\n\t\t\tconst requested = trimmed.toLowerCase() as ThinkingLevel;\n\t\t\tif (!validSet.has(requested)) {\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Invalid thinking level: \"${trimmed}\". Valid: ${levels.join(\", \")}`,\n\t\t\t\t\t\"error\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (requested === currentLevel) {\n\t\t\t\tctx.ui.notify(`Thinking level: ${requested} (unchanged)`, \"info\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tpi.setThinkingLevel(requested);\n\t\t\tctx.ui.notify(`Thinking level: ${pi.getThinkingLevel()}`, \"info\");\n\t\t},\n\t};\n\n\tpi.registerCommand(\"thinking\", thinkingSpec);\n\t// lunr: /effort and /reasoning are full-parity aliases (same handler + completions).\n\tpi.registerCommand(\"effort\", {\n\t\t...thinkingSpec,\n\t\tdescription: `${THINKING_COMMAND_DESCRIPTION} (alias of /thinking)`,\n\t});\n\tpi.registerCommand(\"reasoning\", {\n\t\t...thinkingSpec,\n\t\tdescription: `${THINKING_COMMAND_DESCRIPTION} (alias of /thinking)`,\n\t});\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Read the current model from the ExtensionAPI runtime. The spec mentions\n * `pi.getModel()`; pi doesn't expose that name on the API object itself, but\n * the bound `ExtensionContextActions` (which the runtime decorates onto\n * events) does include `getModel()`. We duck-type against the loader so this\n * file stays decoupled from non-public internals. When unavailable (e.g.\n * during autocomplete, before any session has bound), returns undefined and\n * the caller falls back to the default 5-level set.\n */\nfunction currentModel(pi: ExtensionAPI): ModelLike | undefined {\n\tconst fn = (pi as unknown as { getModel?: () => unknown }).getModel;\n\tif (typeof fn === \"function\") {\n\t\treturn fn.call(pi) as ModelLike | undefined;\n\t}\n\treturn undefined;\n}\n"]}
1
+ {"version":3,"file":"ashxj-thinking.js","sourceRoot":"","sources":["../../src/builtin-extensions/ashxj-thinking.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\n// Vendored from https://github.com/ashx-j/ashxj-thinking @ 0330a34\n// (\"Remove custom footer — keep only /thinking command\"), single-file ashxj\n// convention. lunR patches are marked `// lunr:`.\n/**\n * batxj-thinking extension\n *\n * `/thinking [level]` slash command to view or set the reasoning level,\n * plus `/thinking show|hide|toggle` for thinking-block visibility.\n * `/effort` and `/reasoning` are full-parity aliases.\n *\n * Loaded by pi via jiti — no build step, plain TypeScript.\n *\n * NOTE on type imports: this file deliberately declares structural types\n * rather than importing from `@ashx-j/lunr-dev` (or\n * `@ashx-j/lunr-tui`). pi-coding-agent's `index.d.ts` re-exports\n * from internal `.d.ts` files that contain subpath imports like\n * `@ashx-j/lunr-ai/compat`, which fail to resolve under the default\n * `tsc` settings when a file argument is passed (the spec'd\n * `tsc --noEmit index.ts` script). Declaring the types we use inline\n * keeps the typecheck self-contained.\n */\n\nimport { readFileSync, writeFileSync, existsSync, renameSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\n// ---------------------------------------------------------------------------\n// Minimal structural types (see file header for why these are inline)\n// ---------------------------------------------------------------------------\n\n/** Mirrored from `@ashx-j/lunr-agent` `ThinkingLevel`. */\n// lunr: added \"max\" — lunR's ThinkingLevel union includes it.\ntype ThinkingLevel = \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\n/** Mirrored from `@ashx-j/lunr-tui` `AutocompleteItem`. */\ninterface AutocompleteItem {\n\tvalue: string;\n\tlabel: string;\n\tdescription?: string;\n}\n\n/** A trimmed view of a `Model` — only the fields the picker reads. */\ninterface ModelLike {\n\tid?: string;\n\treasoning?: boolean;\n\tthinkingLevelMap?: Record<string, string | null>;\n}\n\n/** A trimmed view of `ExtensionContext` — only the methods/props we use. */\ninterface ExtensionContextLike {\n\tmode: \"tui\" | \"rpc\" | \"json\" | \"print\";\n\tmodel: ModelLike | undefined;\n\tui: {\n\t\tnotify(message: string, type?: \"info\" | \"warning\" | \"error\"): void;\n\t\tselect(title: string, options: string[], opts?: { signal?: AbortSignal; timeout?: number }): Promise<string | undefined>;\n\t};\n}\n\n/** A trimmed view of `ExtensionCommandContext` — only the methods/props we use. */\ninterface ExtensionCommandContextLike extends ExtensionContextLike {\n\tgetThinkingLevel(): ThinkingLevel;\n\t/** Reload extensions, skills, prompts, and themes. Re-reads settings.json\n\t * from disk (session.reload() → settingsManager.reload()), so persisted\n\t * runtime settings like `hideThinkingBlock` are live-applied. The captured\n\t * `ctx`/`pi` are stale after this resolves — do not use them afterward. */\n\treload(): Promise<void>;\n}\n\n/** A trimmed view of `ExtensionAPI` — only the methods we use. */\ninterface ExtensionAPI {\n\tregisterCommand(name: string, options: {\n\t\tdescription?: string;\n\t\tgetArgumentCompletions?(prefix: string): AutocompleteItem[] | null | Promise<AutocompleteItem[] | null>;\n\t\thandler(args: string, ctx: ExtensionCommandContextLike): Promise<void> | void;\n\t}): void;\n\tgetThinkingLevel(): ThinkingLevel;\n\tsetThinkingLevel(level: ThinkingLevel): void;\n\ton?(event: string, handler: (event: unknown, ctx: ExtensionContextLike) => void): void;\n}\n\n// ---------------------------------------------------------------------------\n// Thinking level config\n// ---------------------------------------------------------------------------\n\n/** All known levels, in display order. Mirrors `EXTENDED_THINKING_LEVELS` in pi-ai. */\nconst ALL_LEVELS: readonly ThinkingLevel[] = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"];\n/** Default 5 — used when the active model is undefined (we don't know whether `xhigh`/`max` are supported). */\nconst ALL_LEVELS_5: readonly ThinkingLevel[] = [\"off\", \"minimal\", \"low\", \"medium\", \"high\"];\n\n/** Per-level descriptions. Mirrored from `THINKING_DESCRIPTIONS` in settings-selector.ts. */\nconst THINKING_DESCRIPTIONS: Record<ThinkingLevel, string> = {\n\toff: \"No reasoning\",\n\tminimal: \"Very brief reasoning\",\n\tlow: \"Light reasoning\",\n\tmedium: \"Moderate reasoning\",\n\thigh: \"Deep reasoning\",\n\txhigh: \"Extra-high reasoning\",\n\t// lunr: added — mirrors settings-selector.ts.\n\tmax: \"Maximum reasoning\",\n};\n\n/** Returns the levels valid for the given model, in display order.\n * Mirrors `getSupportedThinkingLevels` in pi-ai: `xhigh`/`max` are opt-in\n * (non-null map entry); other levels drop only on an explicit null. */\nfunction availableLevelsFor(model: ModelLike | undefined): readonly ThinkingLevel[] {\n\tif (!model) return ALL_LEVELS_5;\n\tif (model.reasoning === false) return [\"off\" as const];\n\treturn ALL_LEVELS.filter((level) => {\n\t\tconst mapped = model.thinkingLevelMap?.[level];\n\t\tif (mapped === null) return false;\n\t\tif (level === \"xhigh\" || level === \"max\") return mapped !== undefined;\n\t\treturn true;\n\t});\n}\n\n/** Builds the inline `<padded level> — <description>` label for a level. */\nfunction formatLevelLabel(level: ThinkingLevel): string {\n\treturn `${level.padEnd(8)} \\u2014 ${THINKING_DESCRIPTIONS[level]}`;\n}\n\n// ---------------------------------------------------------------------------\n// Persisted thinking-block visibility (hideThinkingBlock)\n//\n// pi has no public extension API to toggle thinking-block visibility live.\n// The live in-session toggle is `app.thinking.toggle` (unbound by default) wired to\n// `toggleThinkingBlockVisibility()` in interactive-mode.js, which calls\n// `SettingsManager.setHideThinkingBlock()` + rebuilds the chat. That method is\n// not exposed on ExtensionContext / ExtensionCommandContext / ExtensionAPI.\n// Ctrl+T cycles thinking level (`app.thinking.cycle`).\n//\n// What extensions CAN do is persist the `hideThinkingBlock` boolean to the\n// global agent settings file (`~/.lunr/agent/settings.json`); the\n// `SettingsManager` reads it on startup. And because `ctx.reload()` drives\n// `session.reload()` → `settingsManager.reload()` (re-reads disk) →\n// `restoreChatBeforeSessionStart()` copies the new value into\n// `this.hideThinkingBlock` and calls `rebuildChatFromMessages()` (which\n// reconstructs every AssistantMessageComponent with the new hide flag), the\n// persisted value IS live-applied within the session by `await ctx.reload()`\n// (verified against pi 0.80.3). In non-TUI modes `ctx.reload()` is a no-op,\n// so the setting simply applies on next start.\n//\n// `/thinking show|hide|toggle` is the discoverable, persistable path.\n// ---------------------------------------------------------------------------\n\n/** Returns the path to lunR's global agent settings file.\n * lunr: lunR's agent dir is `~/.lunr/agent` (upstream hardcoded `~/.pi/agent`).\n * Honors the `PI_CODING_AGENT_DIR` env override like core config.ts does;\n * a custom agent dir is not exposed to extensions, so this is the only\n * location we can write to be picked up by\n * `SettingsManager.tryLoadFromStorage(\"global\")`. */\nfunction agentSettingsPath(): string {\n\tconst envDir = process.env.PI_CODING_AGENT_DIR;\n\tif (envDir) {\n\t\t// Match core normalizePath(): expand a leading ~ (~/ and, on win32, ~\\).\n\t\tconst home = homedir();\n\t\tconst expanded =\n\t\t\tenvDir === \"~\"\n\t\t\t\t? home\n\t\t\t\t: envDir.startsWith(\"~/\") || (process.platform === \"win32\" && envDir.startsWith(\"~\\\\\"))\n\t\t\t\t\t? join(home, envDir.slice(2))\n\t\t\t\t\t: envDir;\n\t\treturn join(expanded, \"settings.json\");\n\t}\n\treturn join(homedir(), \".lunr\", \"agent\", \"settings.json\");\n}\n\n// ---------------------------------------------------------------------------\n// lunR customize bridge for persisted thinking-block visibility.\n// When the bridge is present (TUI / gateway sessions), reads/writes go through\n// SettingsManager (lockfile + merge). Falls back to direct file I/O when the\n// extension loads in a context without the bridge (e.g. upstream pi).\n// ---------------------------------------------------------------------------\ninterface CustomizeBridge {\n\tgetHideThinkingBlock(): boolean;\n\tsetHideThinkingBlock(hide: boolean): void;\n}\n\nfunction getCustomizeBridge(): CustomizeBridge | undefined {\n\treturn (globalThis as Record<symbol, unknown>)[Symbol.for(\"@lunr/customize\")] as CustomizeBridge | undefined;\n}\n\n/** Returns the persisted `hideThinkingBlock` value (default false, matching\n * `getHideThinkingBlock()` which returns `this.settings.hideThinkingBlock ?? false`).\n * Never throws — on any error (missing file, bad JSON) returns false. */\nfunction readHideThinkingBlock(): boolean {\n\tconst bridge = getCustomizeBridge();\n\tif (bridge) return bridge.getHideThinkingBlock();\n\ttry {\n\t\tconst p = agentSettingsPath();\n\t\tif (!existsSync(p)) return false;\n\t\tconst cfg = JSON.parse(readFileSync(p, \"utf8\")) as { hideThinkingBlock?: boolean };\n\t\treturn cfg.hideThinkingBlock === true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Persist `hideThinkingBlock` to the global agent settings file (safe merge).\n *\n * - Preserves all other keys (merge, never overwrite the whole file).\n * - Matches pi's 2-space indentation + trailing newline.\n * - On invalid JSON in the existing file, backs it up to `settings.json.bak`\n * before writing a fresh file, so a corrupted file is never written back.\n * - Never throws; on any error `ok` is false and the caller notifies the user.\n *\n * `createdFresh` is true when the file didn't exist (or was corrupt and backed\n * up) before this write — the handler uses it to warn that a global settings\n * file was created here.\n */\nfunction writeHideThinkingBlock(hide: boolean): {\n\tok: boolean;\n\tcreatedFresh: boolean;\n} {\n\tconst bridge = getCustomizeBridge();\n\tif (bridge) {\n\t\ttry {\n\t\t\tbridge.setHideThinkingBlock(hide);\n\t\t\treturn { ok: true, createdFresh: false };\n\t\t} catch {\n\t\t\treturn { ok: false, createdFresh: false };\n\t\t}\n\t}\n\ttry {\n\t\tconst p = agentSettingsPath();\n\t\tlet cfg: Record<string, unknown> = {};\n\t\tlet createdFresh = false;\n\t\tif (existsSync(p)) {\n\t\t\ttry {\n\t\t\t\tcfg = JSON.parse(readFileSync(p, \"utf8\")) as Record<string, unknown>;\n\t\t\t} catch {\n\t\t\t\t// Existing file is corrupt — back it up, then start fresh.\n\t\t\t\ttry {\n\t\t\t\t\trenameSync(p, `${p}.bak`);\n\t\t\t\t} catch {\n\t\t\t\t\t// If backup fails, still proceed to overwrite (best effort).\n\t\t\t\t}\n\t\t\t\tcfg = {};\n\t\t\t\tcreatedFresh = true;\n\t\t\t}\n\t\t} else {\n\t\t\tcreatedFresh = true;\n\t\t}\n\t\tcfg.hideThinkingBlock = hide;\n\t\twriteFileSync(p, JSON.stringify(cfg, null, 2) + \"\\n\", \"utf8\");\n\t\treturn { ok: true, createdFresh };\n\t} catch {\n\t\treturn { ok: false, createdFresh: false };\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Extension entry point\n// ---------------------------------------------------------------------------\n\nconst THINKING_COMMAND_DESCRIPTION =\n\t\"View or set the reasoning level for the current model, or toggle thinking-block visibility with show/hide/toggle\";\n\nexport default function (pi: ExtensionAPI): void {\n\tsessionModel = undefined;\n\tif (typeof pi.on === \"function\") {\n\t\tpi.on(\"session_start\", (_event, ctx) => {\n\t\t\tsessionModel = ctx.model;\n\t\t});\n\t\tpi.on(\"model_select\", (event, ctx) => {\n\t\t\tconst selected = (event as { model?: ModelLike } | undefined)?.model;\n\t\t\tsessionModel = ctx.model ?? selected;\n\t\t});\n\t}\n\n\tconst thinkingSpec = {\n\t\tdescription: THINKING_COMMAND_DESCRIPTION,\n\t\tgetArgumentCompletions(prefix: string): AutocompleteItem[] {\n\t\t\tconst lower = prefix.toLowerCase();\n\t\t\t// Visibility sub-options first, filtered by prefix, alongside the levels.\n\t\t\tconst visibility: AutocompleteItem[] = [\n\t\t\t\t{ value: \"show\", label: \"show\", description: \"Show thinking blocks (persisted to settings.json)\" },\n\t\t\t\t{ value: \"hide\", label: \"hide\", description: \"Hide thinking blocks (persisted to settings.json)\" },\n\t\t\t\t{ value: \"toggle\", label: \"toggle\", description: \"Toggle thinking blocks (persisted to settings.json)\" },\n\t\t\t];\n\t\t\tconst levels = availableLevelsFor(currentModel(pi));\n\t\t\tconst levelItems = levels\n\t\t\t\t.filter((lvl) => lvl.startsWith(lower))\n\t\t\t\t.map((lvl) => ({ value: lvl, label: lvl, description: THINKING_DESCRIPTIONS[lvl] }));\n\t\t\treturn [\n\t\t\t\t...visibility.filter((v) => v.value.startsWith(lower)),\n\t\t\t\t...levelItems,\n\t\t\t];\n\t\t},\n\t\thandler: async (args: string, ctx: ExtensionCommandContextLike) => {\n\t\t\tconst trimmed = args.trim();\n\t\t\tconst lower = trimmed.toLowerCase();\n\n\t\t\t// ---- Visibility sub-options: /thinking show | hide | toggle ----\n\t\t\t// Caught first so `hide`/`show`/`toggle` are never parsed as levels.\n\t\t\t// Works in every mode: only uses ctx.ui.notify + file I/O + ctx.reload().\n\t\t\tif (lower === \"show\" || lower === \"hide\" || lower === \"toggle\") {\n\t\t\t\tconst current = readHideThinkingBlock();\n\t\t\t\tconst next = lower === \"toggle\" ? !current : lower === \"hide\";\n\t\t\t\tif (next === current) {\n\t\t\t\t\tctx.ui.notify(`Thinking blocks already ${current ? \"hidden\" : \"shown\"}.`, \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst result = writeHideThinkingBlock(next);\n\t\t\t\tif (!result.ok) {\n\t\t\t\t\t// lunr: settings path is lunR's (see agentSettingsPath).\n\t\t\t\t\tctx.ui.notify(`Failed to update ${agentSettingsPath()}`, \"error\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// The notify MUST run before `await ctx.reload()`: after reload the\n\t\t\t\t// loader invalidates this `ctx`/`pi` as stale. ctx.reload() live-\n\t\t\t\t// applies the setting (verified against pi 0.80.3: it drives\n\t\t\t\t// session.reload() → settingsManager.reload() re-reads disk →\n\t\t\t\t// restoreChatBeforeSessionStart copies the new value into\n\t\t\t\t// this.hideThinkingBlock → rebuildChatFromMessages() rebuilds every\n\t\t\t\t// AssistantMessageComponent with the new hide flag). In non-TUI\n\t\t\t\t// modes ctx.reload() is a no-op; the setting then applies on next\n\t\t\t\t// start.\n\t\t\t\tconst verb = next ? \"hidden\" : \"shown\";\n\t\t\t\tconst note = result.createdFresh\n\t\t\t\t\t? `Thinking blocks ${verb}. (Created ${agentSettingsPath()} with this setting.)`\n\t\t\t\t\t: `Thinking blocks ${verb}.`;\n\t\t\t\tctx.ui.notify(note, \"info\");\n\t\t\t\tawait ctx.reload();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst levels = availableLevelsFor(ctx.model);\n\t\t\tconst currentLevel: ThinkingLevel = pi.getThinkingLevel();\n\t\t\tconst validSet = new Set<ThinkingLevel>(levels);\n\n\t\t\t// No-arg form → open a picker. Skip in non-TUI modes — same pattern\n\t\t\t// as batxj-animations per AGENTS.md §5.\n\t\t\tif (trimmed === \"\") {\n\t\t\t\tif (ctx.mode !== \"tui\") {\n\t\t\t\t\tctx.ui.notify(`Thinking level: ${currentLevel}`, \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (levels.length === 0) {\n\t\t\t\t\tctx.ui.notify(\"No thinking levels available for this model.\", \"warning\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst options = levels.map((lvl) =>\n\t\t\t\t\t(lvl === currentLevel ? \"\\u25CF \" : \" \") + formatLevelLabel(lvl),\n\t\t\t\t);\n\t\t\t\tconst chosen = await ctx.ui.select(\n\t\t\t\t\t`Thinking level (current: ${currentLevel})`,\n\t\t\t\t\toptions,\n\t\t\t\t);\n\t\t\t\tif (chosen === undefined) return;\n\t\t\t\t// Chosen string starts with the current-marker (\"● \") or two-space\n\t\t\t\t// gutter; strip the prefix and extract the first token (the level).\n\t\t\t\tconst stripped = chosen.replace(/^[\\u25CF ]\\s?/, \"\").trimStart();\n\t\t\t\tconst level = stripped.split(/\\s+/)[0] as ThinkingLevel;\n\t\t\t\tif (!validSet.has(level)) {\n\t\t\t\t\tctx.ui.notify(`Unsupported thinking level: ${level}`, \"error\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (level === currentLevel) return; // no-op\n\t\t\t\tpi.setThinkingLevel(level);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Direct-set form: `/thinking <level>`\n\t\t\tconst requested = trimmed.toLowerCase() as ThinkingLevel;\n\t\t\tif (!validSet.has(requested)) {\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Invalid thinking level: \"${trimmed}\". Valid: ${levels.join(\", \")}`,\n\t\t\t\t\t\"error\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (requested === currentLevel) return;\n\t\t\tpi.setThinkingLevel(requested);\n\t\t},\n\t};\n\n\tpi.registerCommand(\"thinking\", thinkingSpec);\n\t// lunr: /effort and /reasoning are full-parity aliases (same handler + completions).\n\tpi.registerCommand(\"effort\", {\n\t\t...thinkingSpec,\n\t\tdescription: `${THINKING_COMMAND_DESCRIPTION} (alias of /thinking)`,\n\t});\n\tpi.registerCommand(\"reasoning\", {\n\t\t...thinkingSpec,\n\t\tdescription: `${THINKING_COMMAND_DESCRIPTION} (alias of /thinking)`,\n\t});\n\n\tfor (const level of ALL_LEVELS) {\n\t\tpi.registerCommand(level, {\n\t\t\tdescription: `Set thinking level to ${level}`,\n\t\t\thandler: async (_args, ctx) => {\n\t\t\t\tconst levels = availableLevelsFor(ctx.model);\n\t\t\t\tif (!levels.includes(level)) {\n\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t`Invalid thinking level: \"${level}\". Valid: ${levels.join(\", \")}`,\n\t\t\t\t\t\t\"error\",\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (pi.getThinkingLevel() === level) return;\n\t\t\t\tpi.setThinkingLevel(level);\n\t\t\t},\n\t\t});\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Live session model for `/thinking ` completions.\n * `getArgumentCompletions` runs on the extension `pi` object, which has no\n * `getModel`. Cache the model from session_start / model_select, and still\n * duck-type `getModel` when a test or future API exposes it.\n */\nlet sessionModel: ModelLike | undefined;\n\nfunction currentModel(pi: ExtensionAPI): ModelLike | undefined {\n\tconst fn = (pi as unknown as { getModel?: () => unknown }).getModel;\n\tif (typeof fn === \"function\") {\n\t\ttry {\n\t\t\tconst model = fn.call(pi) as ModelLike | undefined;\n\t\t\tif (model) return model;\n\t\t} catch {\n\t\t\t// runtime not bound yet\n\t\t}\n\t}\n\treturn sessionModel;\n}\n"]}
@@ -30,6 +30,7 @@
30
30
  * re-exports main.ts which imports this file — a circular import that crashes
31
31
  * under vite-node (`Class extends value undefined`).
32
32
  */
33
+ import { CustomEditor } from "../modes/interactive/components/custom-editor.js";
33
34
  export declare function lunrPromptGlyph(theme: Theme | undefined): string;
34
35
  type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
35
36
  /** Theme token for the chatbox thinking-level border / effort chip. */
@@ -143,7 +144,20 @@ interface FooterComponentLike {
143
144
  dispose?(): void;
144
145
  invalidate?(): void;
145
146
  }
147
+ export declare class ChatboxEditor extends CustomEditor {
148
+ private ctx;
149
+ private pi;
150
+ bind(ctx: ExtensionContextLike, pi: ExtensionAPI): void;
151
+ /** Keep the displayed values while /new or /resume replaces the old runtime. */
152
+ unbind(): void;
153
+ constructor(tui: TUIHandle, theme: EditorThemeLike, keybindings: KeybindingsLike, ctx: ExtensionContextLike, pi: ExtensionAPI);
154
+ private color;
155
+ render(width: number): string[];
156
+ private renderBottomBorder;
157
+ }
146
158
  export declare function renderStatsLine(width: number, ctx: ExtensionContextLike, theme: Theme, footerData: ReadonlyFooterDataProvider): string[];
159
+ /** The startup view and extension bind the same editor, preserving its complete draft state. */
160
+ export declare function getChatboxEditor(tui: TUIHandle, theme: EditorThemeLike, keybindings: KeybindingsLike, ctx: ExtensionContextLike, pi: ExtensionAPI): ChatboxEditor;
147
161
  export default function (pi: ExtensionAPI): void;
148
162
  export {};
149
163
  //# sourceMappingURL=ashxj-tui.d.ts.map