@ashx-j/lunr 0.2.17 → 0.2.18

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 (339) hide show
  1. package/CHANGELOG.md +19 -1
  2. package/README.md +2 -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 +2 -2
  8. package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
  9. package/dist/builtin-extensions/ashxj-tui.js +8 -11
  10. package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
  11. package/dist/builtin-extensions/index.d.ts.map +1 -1
  12. package/dist/builtin-extensions/index.js +2 -1
  13. package/dist/builtin-extensions/index.js.map +1 -1
  14. package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts +4 -0
  15. package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts.map +1 -1
  16. package/dist/builtin-extensions/pi-lsp-extension/src/index.js +172 -171
  17. package/dist/builtin-extensions/pi-lsp-extension/src/index.js.map +1 -1
  18. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.d.ts +50 -0
  19. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.d.ts.map +1 -0
  20. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.js +131 -0
  21. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.js.map +1 -0
  22. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.d.ts +7 -0
  23. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.d.ts.map +1 -0
  24. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js +211 -0
  25. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js.map +1 -0
  26. package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.d.ts +0 -5
  27. package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.d.ts.map +1 -1
  28. package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.js +0 -202
  29. package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.js.map +1 -1
  30. package/dist/builtin-extensions/pi-mcp-adapter/index.d.ts.map +1 -1
  31. package/dist/builtin-extensions/pi-mcp-adapter/index.js +276 -109
  32. package/dist/builtin-extensions/pi-mcp-adapter/index.js.map +1 -1
  33. package/dist/builtin-extensions/pi-mcp-adapter/init.d.ts +4 -1
  34. package/dist/builtin-extensions/pi-mcp-adapter/init.d.ts.map +1 -1
  35. package/dist/builtin-extensions/pi-mcp-adapter/init.js +10 -3
  36. package/dist/builtin-extensions/pi-mcp-adapter/init.js.map +1 -1
  37. package/dist/builtin-extensions/pi-mcp-adapter/metadata-cache.d.ts.map +1 -1
  38. package/dist/builtin-extensions/pi-mcp-adapter/metadata-cache.js +6 -1
  39. package/dist/builtin-extensions/pi-mcp-adapter/metadata-cache.js.map +1 -1
  40. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts +6 -1
  41. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts.map +1 -1
  42. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js +33 -8
  43. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js.map +1 -1
  44. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts.map +1 -1
  45. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js +2 -1
  46. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js.map +1 -1
  47. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.d.ts +1 -1
  48. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.d.ts.map +1 -1
  49. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js +1 -1
  50. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js.map +1 -1
  51. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts +1 -1
  52. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  53. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +68 -15
  54. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  55. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts +1 -1
  56. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts.map +1 -1
  57. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js +5 -2
  58. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js.map +1 -1
  59. package/dist/builtin-extensions/pi-subagents/src/shared/fork-context.d.ts.map +1 -1
  60. package/dist/builtin-extensions/pi-subagents/src/shared/fork-context.js +1 -1
  61. package/dist/builtin-extensions/pi-subagents/src/shared/fork-context.js.map +1 -1
  62. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts +1 -1
  63. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
  64. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +1 -1
  65. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
  66. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +2 -1
  67. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  68. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +72 -31
  69. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  70. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.d.ts +1 -1
  71. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.d.ts.map +1 -1
  72. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js +2 -1
  73. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js.map +1 -1
  74. package/dist/builtin-extensions/pi-web-access/extract.d.ts.map +1 -1
  75. package/dist/builtin-extensions/pi-web-access/extract.js +105 -54
  76. package/dist/builtin-extensions/pi-web-access/extract.js.map +1 -1
  77. package/dist/builtin-extensions/pi-web-access/gemini-search.d.ts +1 -1
  78. package/dist/builtin-extensions/pi-web-access/gemini-search.d.ts.map +1 -1
  79. package/dist/builtin-extensions/pi-web-access/gemini-search.js +82 -65
  80. package/dist/builtin-extensions/pi-web-access/gemini-search.js.map +1 -1
  81. package/dist/builtin-extensions/pi-web-access/github-extract.d.ts.map +1 -1
  82. package/dist/builtin-extensions/pi-web-access/github-extract.js +2 -0
  83. package/dist/builtin-extensions/pi-web-access/github-extract.js.map +1 -1
  84. package/dist/builtin-extensions/pi-web-access/index.d.ts.map +1 -1
  85. package/dist/builtin-extensions/pi-web-access/index.js +259 -168
  86. package/dist/builtin-extensions/pi-web-access/index.js.map +1 -1
  87. package/dist/builtin-extensions/pi-web-access/lazy.d.ts +18 -0
  88. package/dist/builtin-extensions/pi-web-access/lazy.d.ts.map +1 -0
  89. package/dist/builtin-extensions/pi-web-access/lazy.js +19 -0
  90. package/dist/builtin-extensions/pi-web-access/lazy.js.map +1 -0
  91. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts +6 -0
  92. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts.map +1 -0
  93. package/dist/builtin-extensions/pi-web-access/session-cleanup.js +17 -0
  94. package/dist/builtin-extensions/pi-web-access/session-cleanup.js.map +1 -0
  95. package/dist/cli-runtime.d.ts +3 -0
  96. package/dist/cli-runtime.d.ts.map +1 -0
  97. package/dist/cli-runtime.js +72 -0
  98. package/dist/cli-runtime.js.map +1 -0
  99. package/dist/cli.d.ts.map +1 -1
  100. package/dist/cli.js +11 -60
  101. package/dist/cli.js.map +1 -1
  102. package/dist/config.d.ts +1 -0
  103. package/dist/config.d.ts.map +1 -1
  104. package/dist/config.js +1 -0
  105. package/dist/config.js.map +1 -1
  106. package/dist/core/agent-session.d.ts.map +1 -1
  107. package/dist/core/agent-session.js +6 -3
  108. package/dist/core/agent-session.js.map +1 -1
  109. package/dist/core/extensions/host-static.d.ts.map +1 -1
  110. package/dist/core/extensions/host-static.js +34 -12
  111. package/dist/core/extensions/host-static.js.map +1 -1
  112. package/dist/core/extensions/loader.d.ts +1 -2
  113. package/dist/core/extensions/loader.d.ts.map +1 -1
  114. package/dist/core/extensions/loader.js +10 -64
  115. package/dist/core/extensions/loader.js.map +1 -1
  116. package/dist/core/keybindings.d.ts +2 -2
  117. package/dist/core/keybindings.d.ts.map +1 -1
  118. package/dist/core/keybindings.js +2 -2
  119. package/dist/core/keybindings.js.map +1 -1
  120. package/dist/core/package-manager.d.ts.map +1 -1
  121. package/dist/core/package-manager.js +1 -1
  122. package/dist/core/package-manager.js.map +1 -1
  123. package/dist/core/sdk.d.ts +1 -1
  124. package/dist/core/sdk.d.ts.map +1 -1
  125. package/dist/core/sdk.js +1 -1
  126. package/dist/core/sdk.js.map +1 -1
  127. package/dist/core/timings.d.ts +2 -1
  128. package/dist/core/timings.d.ts.map +1 -1
  129. package/dist/core/timings.js +17 -2
  130. package/dist/core/timings.js.map +1 -1
  131. package/dist/gateway/agent-bridge.d.ts +6 -1
  132. package/dist/gateway/agent-bridge.d.ts.map +1 -1
  133. package/dist/gateway/agent-bridge.js +23 -6
  134. package/dist/gateway/agent-bridge.js.map +1 -1
  135. package/dist/gateway/cron.d.ts +1 -1
  136. package/dist/gateway/cron.d.ts.map +1 -1
  137. package/dist/gateway/cron.js +3 -1
  138. package/dist/gateway/cron.js.map +1 -1
  139. package/dist/main.d.ts.map +1 -1
  140. package/dist/main.js +20 -14
  141. package/dist/main.js.map +1 -1
  142. package/dist/modes/interactive/injected-context.d.ts +2 -0
  143. package/dist/modes/interactive/injected-context.d.ts.map +1 -0
  144. package/dist/modes/interactive/injected-context.js +7 -0
  145. package/dist/modes/interactive/injected-context.js.map +1 -0
  146. package/dist/modes/interactive/interactive-mode.d.ts +2 -0
  147. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  148. package/dist/modes/interactive/interactive-mode.js +32 -8
  149. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  150. package/dist/modes/interactive/thinking-level-slash.d.ts +4 -0
  151. package/dist/modes/interactive/thinking-level-slash.d.ts.map +1 -0
  152. package/dist/modes/interactive/thinking-level-slash.js +23 -0
  153. package/dist/modes/interactive/thinking-level-slash.js.map +1 -0
  154. package/dist/node-runtime/agent-session-services-35WNVGMR.js +36 -0
  155. package/dist/node-runtime/benchmark-request-UC7PD3V3.js +57 -0
  156. package/dist/node-runtime/brave-UWDA3I22.js +143 -0
  157. package/dist/node-runtime/builtin-extensions-QATGXENO.js +28 -0
  158. package/dist/node-runtime/chunk-2SJB2AWP.js +47 -0
  159. package/dist/node-runtime/chunk-3NMWLTPV.js +64 -0
  160. package/dist/node-runtime/chunk-3WFAEVKS.js +115 -0
  161. package/dist/node-runtime/chunk-3X3KZKMI.js +49 -0
  162. package/dist/node-runtime/chunk-4CSFRBCN.js +7558 -0
  163. package/dist/node-runtime/chunk-4DJ6HEGH.js +296 -0
  164. package/dist/node-runtime/chunk-4HXHDDCF.js +16 -0
  165. package/dist/node-runtime/chunk-4I23VTC4.js +429 -0
  166. package/dist/node-runtime/chunk-4TLO4PO2.js +3427 -0
  167. package/dist/node-runtime/chunk-4ZWGEEAS.js +69 -0
  168. package/dist/node-runtime/chunk-53YJI7JU.js +137 -0
  169. package/dist/node-runtime/chunk-5EFIU3OM.js +295 -0
  170. package/dist/node-runtime/chunk-6BEIBLQ3.js +53 -0
  171. package/dist/node-runtime/chunk-6KDIOJL3.js +72 -0
  172. package/dist/node-runtime/chunk-7N3YHTYF.js +26 -0
  173. package/dist/node-runtime/chunk-7NBZ5P7I.js +24 -0
  174. package/dist/node-runtime/chunk-AD6VXAO7.js +342 -0
  175. package/dist/node-runtime/chunk-ARC4KOTI.js +11178 -0
  176. package/dist/node-runtime/chunk-AROOY4BB.js +173 -0
  177. package/dist/node-runtime/chunk-ATGA2WLC.js +5646 -0
  178. package/dist/node-runtime/chunk-AUXVGBO4.js +19 -0
  179. package/dist/node-runtime/chunk-AY6CAJSL.js +30 -0
  180. package/dist/node-runtime/chunk-BHO7O6E5.js +296 -0
  181. package/dist/node-runtime/chunk-BI3DHYCN.js +8845 -0
  182. package/dist/node-runtime/chunk-BOHIDQT4.js +21 -0
  183. package/dist/node-runtime/chunk-BRJX2PRC.js +53 -0
  184. package/dist/node-runtime/chunk-CBGB57XT.js +20211 -0
  185. package/dist/node-runtime/chunk-CCZJ3PYY.js +17 -0
  186. package/dist/node-runtime/chunk-CGBXPL3E.js +1171 -0
  187. package/dist/node-runtime/chunk-CJECDQKP.js +19 -0
  188. package/dist/node-runtime/chunk-CSFI6YXL.js +130 -0
  189. package/dist/node-runtime/chunk-DAPBPCBP.js +53 -0
  190. package/dist/node-runtime/chunk-DDWHZ633.js +37 -0
  191. package/dist/node-runtime/chunk-DMMTJQMQ.js +43 -0
  192. package/dist/node-runtime/chunk-DVGWF6A2.js +1180 -0
  193. package/dist/node-runtime/chunk-EBF6COVM.js +1734 -0
  194. package/dist/node-runtime/chunk-FQMM2EZ2.js +248 -0
  195. package/dist/node-runtime/chunk-FVDOXRUD.js +96 -0
  196. package/dist/node-runtime/chunk-G4P75AIS.js +9471 -0
  197. package/dist/node-runtime/chunk-G6LRAP36.js +105 -0
  198. package/dist/node-runtime/chunk-GKLEQ3I4.js +860 -0
  199. package/dist/node-runtime/chunk-H2EOZYMP.js +57 -0
  200. package/dist/node-runtime/chunk-HQCKFM2O.js +56 -0
  201. package/dist/node-runtime/chunk-HYHJIRDW.js +19 -0
  202. package/dist/node-runtime/chunk-I6R76AG7.js +22 -0
  203. package/dist/node-runtime/chunk-IRPJXI6U.js +1269 -0
  204. package/dist/node-runtime/chunk-J26TSGDL.js +633 -0
  205. package/dist/node-runtime/chunk-JZQ7F36T.js +610 -0
  206. package/dist/node-runtime/chunk-KBKMCJDU.js +126 -0
  207. package/dist/node-runtime/chunk-KWA4OC2J.js +100 -0
  208. package/dist/node-runtime/chunk-M3LZLQW2.js +98 -0
  209. package/dist/node-runtime/chunk-MCUNIRD5.js +8388 -0
  210. package/dist/node-runtime/chunk-NI6OTSBH.js +966 -0
  211. package/dist/node-runtime/chunk-NUIFPZWX.js +209 -0
  212. package/dist/node-runtime/chunk-OBMWP3I5.js +68 -0
  213. package/dist/node-runtime/chunk-OCVIXVTZ.js +88 -0
  214. package/dist/node-runtime/chunk-OPEK5RRY.js +466 -0
  215. package/dist/node-runtime/chunk-OR4L3IB2.js +42 -0
  216. package/dist/node-runtime/chunk-PL6JKXWI.js +3622 -0
  217. package/dist/node-runtime/chunk-PNJSG3IZ.js +807 -0
  218. package/dist/node-runtime/chunk-PVCDKGR6.js +55 -0
  219. package/dist/node-runtime/chunk-Q4Q6D4IY.js +364 -0
  220. package/dist/node-runtime/chunk-Q5ZU2VRT.js +83 -0
  221. package/dist/node-runtime/chunk-QFWG2RVL.js +5477 -0
  222. package/dist/node-runtime/chunk-QZMODZQ2.js +305 -0
  223. package/dist/node-runtime/chunk-R5EDISSV.js +375 -0
  224. package/dist/node-runtime/chunk-RNBHABBA.js +986 -0
  225. package/dist/node-runtime/chunk-RQ2Q5IYR.js +72 -0
  226. package/dist/node-runtime/chunk-RRIZE6QQ.js +17 -0
  227. package/dist/node-runtime/chunk-SN6G4OU6.js +4753 -0
  228. package/dist/node-runtime/chunk-STERBGUB.js +949 -0
  229. package/dist/node-runtime/chunk-UWQYRSYQ.js +8973 -0
  230. package/dist/node-runtime/chunk-VRB2IYGG.js +53 -0
  231. package/dist/node-runtime/chunk-VSELYKWU.js +772 -0
  232. package/dist/node-runtime/chunk-W3CVH5RX.js +62 -0
  233. package/dist/node-runtime/chunk-WJVFOIB5.js +24921 -0
  234. package/dist/node-runtime/chunk-WKDK4C5P.js +2834 -0
  235. package/dist/node-runtime/chunk-XATUM2HK.js +46 -0
  236. package/dist/node-runtime/chunk-XBWPBZBN.js +125 -0
  237. package/dist/node-runtime/chunk-XTHQ7XR7.js +509 -0
  238. package/dist/node-runtime/chunk-ZBV7FAHG.js +1345 -0
  239. package/dist/node-runtime/cli-runtime.js +80 -0
  240. package/dist/node-runtime/clipboard-OZ63BBC6.js +12 -0
  241. package/dist/node-runtime/clipboard-image-7QR6GXVA.js +13 -0
  242. package/dist/node-runtime/command-AAV3YRR5.js +13 -0
  243. package/dist/node-runtime/commands-MV5KOZ64.js +291 -0
  244. package/dist/node-runtime/config-QDD5PUE2.js +73 -0
  245. package/dist/node-runtime/curator-server-XCM43VEF.js +3816 -0
  246. package/dist/node-runtime/customize-XEXL2DGQ.js +12 -0
  247. package/dist/node-runtime/direct-tool-executor-BK7CLEBX.js +188 -0
  248. package/dist/node-runtime/exa-LL64QZR2.js +329 -0
  249. package/dist/node-runtime/export-html-TEXVV5RP.js +150 -0
  250. package/dist/node-runtime/extension-input-O4HSAEM4.js +14 -0
  251. package/dist/node-runtime/extension-selector-X5FCX43D.js +14 -0
  252. package/dist/node-runtime/extract-XLQSJN4V.js +17 -0
  253. package/dist/node-runtime/file-sync-HCOP2QVF.js +117 -0
  254. package/dist/node-runtime/gateway-OAC4OBBL.js +2137 -0
  255. package/dist/node-runtime/gemini-api-QE7ANVDZ.js +29 -0
  256. package/dist/node-runtime/gemini-search-U7SUMPQA.js +330 -0
  257. package/dist/node-runtime/gemini-url-context-PXWCBQHK.js +103 -0
  258. package/dist/node-runtime/gemini-web-MM446SEH.js +14 -0
  259. package/dist/node-runtime/github-extract-F64RZOEA.js +619 -0
  260. package/dist/node-runtime/goal-NJEE5CTU.js +1831 -0
  261. package/dist/node-runtime/index.js +859 -0
  262. package/dist/node-runtime/init-3C7Z24OI.js +28 -0
  263. package/dist/node-runtime/install-cli-EXMJQESX.js +308 -0
  264. package/dist/node-runtime/interactive-mode-2SZUO53H.js +56 -0
  265. package/dist/node-runtime/interactive-view-S6J3QHEF.js +247 -0
  266. package/dist/node-runtime/lsp-manager-3ASUSO4T.js +1104 -0
  267. package/dist/node-runtime/lunr-cron-AUUYP4N4.js +272 -0
  268. package/dist/node-runtime/main.js +54 -0
  269. package/dist/node-runtime/mcp-auth-flow-QIXHW6QN.js +32 -0
  270. package/dist/node-runtime/mcp-panel-IIGMXQGP.js +501 -0
  271. package/dist/node-runtime/mcp-setup-panel-FEK7663I.js +355 -0
  272. package/dist/node-runtime/memory-cap-3S4XRLNP.js +20 -0
  273. package/dist/node-runtime/model-tiers-NJLHUEGK.js +20 -0
  274. package/dist/node-runtime/openai-search-B3MSNCQA.js +288 -0
  275. package/dist/node-runtime/package-manager-cli-7RKSZGEN.js +749 -0
  276. package/dist/node-runtime/parallel-AI2MNSCU.js +265 -0
  277. package/dist/node-runtime/parser-manager-TQHWYDH7.js +152 -0
  278. package/dist/node-runtime/pdf-extract-IPE6H4HP.js +57 -0
  279. package/dist/node-runtime/perplexity-QVJW3I35.js +12 -0
  280. package/dist/node-runtime/pi-intercom-EEMBGQID.js +2215 -0
  281. package/dist/node-runtime/pi-mcp-adapter-GUFZWW54.js +428 -0
  282. package/dist/node-runtime/pi-ollama-cloud-2F3Y2QNM.js +1440 -0
  283. package/dist/node-runtime/pi-prompt-template-model-QWTCGLJU.js +3946 -0
  284. package/dist/node-runtime/pi-subagents-7YJ3I4VE.js +6048 -0
  285. package/dist/node-runtime/pi-web-access-2CQGFLT2.js +1867 -0
  286. package/dist/node-runtime/print-mode-XSFM26EL.js +12 -0
  287. package/dist/node-runtime/proxy-modes-V6YVFH3C.js +685 -0
  288. package/dist/node-runtime/rpc-entry.js +62 -0
  289. package/dist/node-runtime/rpc-mode-W5ZTLTMZ.js +13 -0
  290. package/dist/node-runtime/runtime-bridges-3RKBDLNA.js +14 -0
  291. package/dist/node-runtime/session-manager-E7AREDTV.js +33 -0
  292. package/dist/node-runtime/session-selector-FJ7M2AIX.js +14 -0
  293. package/dist/node-runtime/settings-manager-GHPTUN7R.js +21 -0
  294. package/dist/node-runtime/src-BPQFJR76.js +2427 -0
  295. package/dist/node-runtime/subagent-executor-5Q5A4HJ2.js +8499 -0
  296. package/dist/node-runtime/summary-review-YSMXKITO.js +228 -0
  297. package/dist/node-runtime/tavily-WEZFVFP7.js +154 -0
  298. package/dist/node-runtime/timings-UAD5BEAS.js +16 -0
  299. package/dist/node-runtime/tool-renderer-MV5O452K.js +204 -0
  300. package/dist/node-runtime/update-cli-L3JIBH2U.js +70 -0
  301. package/dist/node-runtime/v4-5MNC3H7G.js +424 -0
  302. package/dist/node-runtime/video-extract-OYT5WKS5.js +304 -0
  303. package/dist/node-runtime/workspace-index-6DBXSTJ6.js +163 -0
  304. package/dist/node-runtime/youtube-extract-TQYKGFGS.js +264 -0
  305. package/dist/rpc.d.ts +3 -0
  306. package/dist/rpc.d.ts.map +1 -0
  307. package/dist/rpc.js +18 -0
  308. package/dist/rpc.js.map +1 -0
  309. package/dist/startup/benchmark-request.d.ts +3 -0
  310. package/dist/startup/benchmark-request.d.ts.map +1 -0
  311. package/dist/startup/benchmark-request.js +65 -0
  312. package/dist/startup/benchmark-request.js.map +1 -0
  313. package/dist/startup/interactive-view.d.ts.map +1 -1
  314. package/dist/startup/interactive-view.js +1 -2
  315. package/dist/startup/interactive-view.js.map +1 -1
  316. package/dist/startup/startup-milestones.d.ts +1 -1
  317. package/dist/startup/startup-milestones.d.ts.map +1 -1
  318. package/dist/startup/startup-milestones.js.map +1 -1
  319. package/dist/utils/await-with-abort.d.ts +2 -0
  320. package/dist/utils/await-with-abort.d.ts.map +1 -0
  321. package/dist/utils/await-with-abort.js +19 -0
  322. package/dist/utils/await-with-abort.js.map +1 -0
  323. package/docs/development.md +5 -1
  324. package/docs/features.md +2 -2
  325. package/docs/interactive-startup.md +95 -48
  326. package/docs/keybindings.md +2 -2
  327. package/docs/terminal-setup.md +1 -1
  328. package/docs/usage.md +1 -1
  329. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  330. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  331. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  332. package/examples/extensions/gondolin/package-lock.json +2 -2
  333. package/examples/extensions/gondolin/package.json +1 -1
  334. package/examples/extensions/hidden-thinking-label.ts +1 -1
  335. package/examples/extensions/sandbox/package-lock.json +2 -2
  336. package/examples/extensions/sandbox/package.json +1 -1
  337. package/examples/extensions/with-deps/package-lock.json +2 -2
  338. package/examples/extensions/with-deps/package.json +1 -1
  339. package/package.json +8 -8
package/CHANGELOG.md CHANGED
@@ -1,9 +1,27 @@
1
1
  # Changelog
2
2
 
3
- lunR is derived from pi. The published npm package is **`@ashx-j/lunr@0.2.16`**. 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.17`**. 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.18] - 2026-09-12
8
+
9
+ ### New Features
10
+
11
+ - **Thinking-level commands.** `/off`, `/minimal`, `/low`, `/medium`, `/high`, `/xhigh`, and `/max` set the session thinking level. Autocomplete only lists levels the current model supports.
12
+ - **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.
13
+
14
+ ### Changed
15
+
16
+ - **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.
17
+ - **Async subagent widget.** Running background children use the same description-first compact row as foreground children, separated from todos by a divider.
18
+ - **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.
19
+
20
+ ### Fixed
21
+
22
+ - Ctrl+T cycles thinking levels for the selected model. `/thinking hide`, `show`, and `toggle` still hide thinking blocks.
23
+ - `/thinking` argument completions follow the live session model.
24
+
7
25
  ## [0.2.17] - 2026-09-11
8
26
 
9
27
  ### Fixed
package/README.md CHANGED
@@ -161,6 +161,7 @@ Type `/` in the editor to trigger commands. [Extensions](#extensions) can regist
161
161
  | `/scoped-models` | Enable/disable models for Ctrl+P cycling |
162
162
  | `/settings` | Theme, thinking, agent memory, message delivery, transport |
163
163
  | `/thinking`, `/effort`, `/reasoning` | Set thinking level (`xhigh`/`max` are opt-in when the model supports them) |
164
+ | `/off`, `/minimal`, `/low`, `/medium`, `/high`, `/xhigh`, `/max` | Set that thinking level when the current model supports it |
164
165
  | `/mode` | Set permission mode: `manual`, `yolo`, `plan`, or `auto` (Shift+Tab cycles) |
165
166
  | `/plan` | Switch to plan mode, or `/plan <task>` to plan a task |
166
167
  | `/manual`, `/yolo`, `/auto` | Activate that permission mode |
@@ -209,7 +210,7 @@ See `/hotkeys` for the full list. Customize via `~/.lunr/agent/keybindings.json`
209
210
  | Ctrl+P / Shift+Ctrl+P | Cycle scoped models forward/backward |
210
211
  | Shift+Tab | Cycle permission mode (`manual` → `yolo` → `plan` → `auto`) |
211
212
  | Ctrl+O | Cycle `/tree` filters (not tool expand) |
212
- | Ctrl+T | Collapse/expand thinking blocks |
213
+ | Ctrl+T | Cycle thinking level for the selected model |
213
214
  | Ctrl+X | Copy the last assistant message |
214
215
 
215
216
  Click a thinking or tool card to expand or collapse that item. `app.tools.expand` is unbound.
@@ -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` (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` (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` (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` (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"]}
@@ -2,8 +2,8 @@
2
2
  * ashxj-tui — a custom slim chatbox for pi.
3
3
  *
4
4
  * Replaces pi-zentui's prompt box + statusline with:
5
- * - A rounded prompt box that auto-expands as the typed message wraps to
6
- * multiple rows (the sides extend; height grows with content).
5
+ * - A rounded prompt box that auto-expands as the typed message wraps.
6
+ * Top and bottom rules only; no side rails.
7
7
  * - A right-aligned chip on the box's BOTTOM border:
8
8
  * model · provider · effort (e.g. `glm-5.2 · Ollama Cloud · xhigh`)
9
9
  * - A slim stats line (extension statuses · context% · ↑↓; each segment