@ashx-j/lunr-dev 0.2.13-dev.8.1 → 0.2.16-dev.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (339) hide show
  1. package/CHANGELOG.md +29 -1
  2. package/dist/builtin-extensions/ashxj-tui.d.ts +14 -0
  3. package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
  4. package/dist/builtin-extensions/ashxj-tui.js +37 -3
  5. package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
  6. package/dist/builtin-extensions/index.d.ts +1 -15
  7. package/dist/builtin-extensions/index.d.ts.map +1 -1
  8. package/dist/builtin-extensions/index.js +7 -21
  9. package/dist/builtin-extensions/index.js.map +1 -1
  10. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.d.ts.map +1 -1
  11. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js +6 -2
  12. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js.map +1 -1
  13. package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts +4 -0
  14. package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts.map +1 -1
  15. package/dist/builtin-extensions/pi-lsp-extension/src/index.js +163 -169
  16. package/dist/builtin-extensions/pi-lsp-extension/src/index.js.map +1 -1
  17. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.d.ts +46 -0
  18. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.d.ts.map +1 -0
  19. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.js +109 -0
  20. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.js.map +1 -0
  21. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.d.ts +7 -0
  22. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.d.ts.map +1 -0
  23. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js +211 -0
  24. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js.map +1 -0
  25. package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.d.ts +0 -5
  26. package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.d.ts.map +1 -1
  27. package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.js +0 -202
  28. package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.js.map +1 -1
  29. package/dist/builtin-extensions/pi-mcp-adapter/index.d.ts.map +1 -1
  30. package/dist/builtin-extensions/pi-mcp-adapter/index.js +251 -94
  31. package/dist/builtin-extensions/pi-mcp-adapter/index.js.map +1 -1
  32. package/dist/builtin-extensions/pi-mcp-adapter/init.d.ts +4 -1
  33. package/dist/builtin-extensions/pi-mcp-adapter/init.d.ts.map +1 -1
  34. package/dist/builtin-extensions/pi-mcp-adapter/init.js +10 -3
  35. package/dist/builtin-extensions/pi-mcp-adapter/init.js.map +1 -1
  36. package/dist/builtin-extensions/pi-mcp-adapter/metadata-cache.d.ts.map +1 -1
  37. package/dist/builtin-extensions/pi-mcp-adapter/metadata-cache.js +6 -1
  38. package/dist/builtin-extensions/pi-mcp-adapter/metadata-cache.js.map +1 -1
  39. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts.map +1 -1
  40. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js +2 -1
  41. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js.map +1 -1
  42. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.d.ts +1 -1
  43. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.d.ts.map +1 -1
  44. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js +1 -1
  45. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js.map +1 -1
  46. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts +1 -1
  47. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  48. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +38 -14
  49. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  50. package/dist/builtin-extensions/pi-subagents/src/shared/fork-context.d.ts.map +1 -1
  51. package/dist/builtin-extensions/pi-subagents/src/shared/fork-context.js +1 -1
  52. package/dist/builtin-extensions/pi-subagents/src/shared/fork-context.js.map +1 -1
  53. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts +1 -1
  54. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
  55. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +1 -1
  56. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
  57. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +1 -1
  58. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  59. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +2 -1
  60. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  61. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.d.ts +1 -1
  62. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.d.ts.map +1 -1
  63. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js +2 -1
  64. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js.map +1 -1
  65. package/dist/builtin-extensions/pi-web-access/extract.d.ts.map +1 -1
  66. package/dist/builtin-extensions/pi-web-access/extract.js +105 -54
  67. package/dist/builtin-extensions/pi-web-access/extract.js.map +1 -1
  68. package/dist/builtin-extensions/pi-web-access/gemini-search.d.ts +1 -1
  69. package/dist/builtin-extensions/pi-web-access/gemini-search.d.ts.map +1 -1
  70. package/dist/builtin-extensions/pi-web-access/gemini-search.js +82 -65
  71. package/dist/builtin-extensions/pi-web-access/gemini-search.js.map +1 -1
  72. package/dist/builtin-extensions/pi-web-access/github-extract.d.ts.map +1 -1
  73. package/dist/builtin-extensions/pi-web-access/github-extract.js +2 -0
  74. package/dist/builtin-extensions/pi-web-access/github-extract.js.map +1 -1
  75. package/dist/builtin-extensions/pi-web-access/index.d.ts.map +1 -1
  76. package/dist/builtin-extensions/pi-web-access/index.js +167 -77
  77. package/dist/builtin-extensions/pi-web-access/index.js.map +1 -1
  78. package/dist/builtin-extensions/pi-web-access/lazy.d.ts +18 -0
  79. package/dist/builtin-extensions/pi-web-access/lazy.d.ts.map +1 -0
  80. package/dist/builtin-extensions/pi-web-access/lazy.js +19 -0
  81. package/dist/builtin-extensions/pi-web-access/lazy.js.map +1 -0
  82. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts +6 -0
  83. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts.map +1 -0
  84. package/dist/builtin-extensions/pi-web-access/session-cleanup.js +17 -0
  85. package/dist/builtin-extensions/pi-web-access/session-cleanup.js.map +1 -0
  86. package/dist/catalog/publication.json +12 -12
  87. package/dist/cli-runtime.d.ts +3 -0
  88. package/dist/cli-runtime.d.ts.map +1 -0
  89. package/dist/cli-runtime.js +73 -0
  90. package/dist/cli-runtime.js.map +1 -0
  91. package/dist/cli.d.ts.map +1 -1
  92. package/dist/cli.js +14 -53
  93. package/dist/cli.js.map +1 -1
  94. package/dist/config.d.ts +1 -0
  95. package/dist/config.d.ts.map +1 -1
  96. package/dist/config.js +1 -0
  97. package/dist/config.js.map +1 -1
  98. package/dist/core/agent-session.d.ts +3 -0
  99. package/dist/core/agent-session.d.ts.map +1 -1
  100. package/dist/core/agent-session.js +56 -12
  101. package/dist/core/agent-session.js.map +1 -1
  102. package/dist/core/compaction/compaction.d.ts.map +1 -1
  103. package/dist/core/compaction/compaction.js +10 -5
  104. package/dist/core/compaction/compaction.js.map +1 -1
  105. package/dist/core/extensions/host-static.d.ts.map +1 -1
  106. package/dist/core/extensions/host-static.js +34 -12
  107. package/dist/core/extensions/host-static.js.map +1 -1
  108. package/dist/core/extensions/loader.d.ts +1 -2
  109. package/dist/core/extensions/loader.d.ts.map +1 -1
  110. package/dist/core/extensions/loader.js +10 -64
  111. package/dist/core/extensions/loader.js.map +1 -1
  112. package/dist/core/extensions/types.d.ts +2 -2
  113. package/dist/core/extensions/types.d.ts.map +1 -1
  114. package/dist/core/extensions/types.js.map +1 -1
  115. package/dist/core/footer-data-provider.d.ts.map +1 -1
  116. package/dist/core/footer-data-provider.js +2 -0
  117. package/dist/core/footer-data-provider.js.map +1 -1
  118. package/dist/core/permissions.d.ts +0 -2
  119. package/dist/core/permissions.d.ts.map +1 -1
  120. package/dist/core/permissions.js +10 -18
  121. package/dist/core/permissions.js.map +1 -1
  122. package/dist/core/sdk.d.ts +1 -1
  123. package/dist/core/sdk.d.ts.map +1 -1
  124. package/dist/core/sdk.js +1 -1
  125. package/dist/core/sdk.js.map +1 -1
  126. package/dist/core/slash-commands.d.ts.map +1 -1
  127. package/dist/core/slash-commands.js +0 -1
  128. package/dist/core/slash-commands.js.map +1 -1
  129. package/dist/core/timings.d.ts +2 -1
  130. package/dist/core/timings.d.ts.map +1 -1
  131. package/dist/core/timings.js +17 -2
  132. package/dist/core/timings.js.map +1 -1
  133. package/dist/gateway/commands.d.ts +1 -1
  134. package/dist/gateway/commands.d.ts.map +1 -1
  135. package/dist/gateway/commands.js +1 -18
  136. package/dist/gateway/commands.js.map +1 -1
  137. package/dist/main.d.ts +2 -2
  138. package/dist/main.d.ts.map +1 -1
  139. package/dist/main.js +57 -48
  140. package/dist/main.js.map +1 -1
  141. package/dist/modes/interactive/interactive-mode.d.ts +12 -21
  142. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  143. package/dist/modes/interactive/interactive-mode.js +120 -144
  144. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  145. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  146. package/dist/modes/interactive/theme/theme.js +95 -84
  147. package/dist/modes/interactive/theme/theme.js.map +1 -1
  148. package/dist/node-runtime/agent-session-services-IFJMSX7Z.js +36 -0
  149. package/dist/node-runtime/benchmark-request-UC7PD3V3.js +57 -0
  150. package/dist/node-runtime/brave-UWDA3I22.js +143 -0
  151. package/dist/node-runtime/builtin-extensions-LYZ3BFWQ.js +28 -0
  152. package/dist/node-runtime/chunk-2QKLKMKC.js +173 -0
  153. package/dist/node-runtime/chunk-3GHXVUAK.js +21 -0
  154. package/dist/node-runtime/chunk-3RCWXWAY.js +466 -0
  155. package/dist/node-runtime/chunk-3WFAEVKS.js +115 -0
  156. package/dist/node-runtime/chunk-3X3KZKMI.js +49 -0
  157. package/dist/node-runtime/chunk-4HXHDDCF.js +16 -0
  158. package/dist/node-runtime/chunk-4TLO4PO2.js +3427 -0
  159. package/dist/node-runtime/chunk-4ZWGEEAS.js +69 -0
  160. package/dist/node-runtime/chunk-53YJI7JU.js +137 -0
  161. package/dist/node-runtime/chunk-5P7PZMRU.js +610 -0
  162. package/dist/node-runtime/chunk-7N3YHTYF.js +26 -0
  163. package/dist/node-runtime/chunk-7NBZ5P7I.js +24 -0
  164. package/dist/node-runtime/chunk-A2KQXUJD.js +105 -0
  165. package/dist/node-runtime/chunk-AD6VXAO7.js +342 -0
  166. package/dist/node-runtime/chunk-AHSTJBIB.js +64 -0
  167. package/dist/node-runtime/chunk-AJX357CL.js +20211 -0
  168. package/dist/node-runtime/chunk-ARC4KOTI.js +11178 -0
  169. package/dist/node-runtime/chunk-AUXVGBO4.js +19 -0
  170. package/dist/node-runtime/chunk-AY6CAJSL.js +30 -0
  171. package/dist/node-runtime/chunk-BHO7O6E5.js +296 -0
  172. package/dist/node-runtime/chunk-BI3DHYCN.js +8845 -0
  173. package/dist/node-runtime/chunk-BR7YDUKA.js +109 -0
  174. package/dist/node-runtime/chunk-BRJX2PRC.js +53 -0
  175. package/dist/node-runtime/chunk-C4O2RSQQ.js +37 -0
  176. package/dist/node-runtime/chunk-CCZJ3PYY.js +17 -0
  177. package/dist/node-runtime/chunk-CDFZEWPU.js +8388 -0
  178. package/dist/node-runtime/chunk-CGBXPL3E.js +1171 -0
  179. package/dist/node-runtime/chunk-CJECDQKP.js +19 -0
  180. package/dist/node-runtime/chunk-DAPBPCBP.js +53 -0
  181. package/dist/node-runtime/chunk-DDGMHUOW.js +305 -0
  182. package/dist/node-runtime/chunk-DMMTJQMQ.js +43 -0
  183. package/dist/node-runtime/chunk-DVGWF6A2.js +1180 -0
  184. package/dist/node-runtime/chunk-ECD5L7YI.js +1369 -0
  185. package/dist/node-runtime/chunk-EDBJNRSM.js +46 -0
  186. package/dist/node-runtime/chunk-F4VQFJI2.js +1269 -0
  187. package/dist/node-runtime/chunk-FVDOXRUD.js +96 -0
  188. package/dist/node-runtime/chunk-GZQHMEWL.js +126 -0
  189. package/dist/node-runtime/chunk-H2EOZYMP.js +57 -0
  190. package/dist/node-runtime/chunk-HQCKFM2O.js +56 -0
  191. package/dist/node-runtime/chunk-HYHJIRDW.js +19 -0
  192. package/dist/node-runtime/chunk-I6R76AG7.js +22 -0
  193. package/dist/node-runtime/chunk-IPA627GP.js +296 -0
  194. package/dist/node-runtime/chunk-JHYKXIMM.js +378 -0
  195. package/dist/node-runtime/chunk-KKSIVROT.js +88 -0
  196. package/dist/node-runtime/chunk-LZAW4ZX3.js +633 -0
  197. package/dist/node-runtime/chunk-M3LZLQW2.js +98 -0
  198. package/dist/node-runtime/chunk-MGWCVY6Y.js +47 -0
  199. package/dist/node-runtime/chunk-MJQDX3BA.js +72 -0
  200. package/dist/node-runtime/chunk-MKKH27PH.js +8956 -0
  201. package/dist/node-runtime/chunk-MX3GJNXJ.js +986 -0
  202. package/dist/node-runtime/chunk-N77MY65L.js +966 -0
  203. package/dist/node-runtime/chunk-NUIFPZWX.js +209 -0
  204. package/dist/node-runtime/chunk-OBMWP3I5.js +68 -0
  205. package/dist/node-runtime/chunk-OR4L3IB2.js +42 -0
  206. package/dist/node-runtime/chunk-PBC2Y6GS.js +903 -0
  207. package/dist/node-runtime/chunk-PCGNAY2O.js +1324 -0
  208. package/dist/node-runtime/chunk-PCIGF2XK.js +250 -0
  209. package/dist/node-runtime/chunk-PGAJ5MO5.js +7558 -0
  210. package/dist/node-runtime/chunk-PL6JKXWI.js +3622 -0
  211. package/dist/node-runtime/chunk-PVCDKGR6.js +55 -0
  212. package/dist/node-runtime/chunk-Q4Q6D4IY.js +364 -0
  213. package/dist/node-runtime/chunk-Q5ZU2VRT.js +83 -0
  214. package/dist/node-runtime/chunk-QFWG2RVL.js +5477 -0
  215. package/dist/node-runtime/chunk-QH42CDX3.js +9451 -0
  216. package/dist/node-runtime/chunk-RQ2Q5IYR.js +72 -0
  217. package/dist/node-runtime/chunk-RQ5DNUNG.js +429 -0
  218. package/dist/node-runtime/chunk-RRIZE6QQ.js +17 -0
  219. package/dist/node-runtime/chunk-SN6G4OU6.js +4753 -0
  220. package/dist/node-runtime/chunk-SWSN6HAB.js +53 -0
  221. package/dist/node-runtime/chunk-TQNSPERU.js +949 -0
  222. package/dist/node-runtime/chunk-VRB2IYGG.js +53 -0
  223. package/dist/node-runtime/chunk-VSELYKWU.js +772 -0
  224. package/dist/node-runtime/chunk-W3CVH5RX.js +62 -0
  225. package/dist/node-runtime/chunk-WJVFOIB5.js +24921 -0
  226. package/dist/node-runtime/chunk-WOVTOV5P.js +5653 -0
  227. package/dist/node-runtime/chunk-XBWPBZBN.js +125 -0
  228. package/dist/node-runtime/chunk-XTHQ7XR7.js +509 -0
  229. package/dist/node-runtime/chunk-YF63P5ZT.js +864 -0
  230. package/dist/node-runtime/chunk-YSKSB3BJ.js +295 -0
  231. package/dist/node-runtime/chunk-ZCHMJ34K.js +130 -0
  232. package/dist/node-runtime/chunk-ZKMFUD3Q.js +2834 -0
  233. package/dist/node-runtime/cli-runtime.js +81 -0
  234. package/dist/node-runtime/clipboard-OZ63BBC6.js +12 -0
  235. package/dist/node-runtime/clipboard-image-7QR6GXVA.js +13 -0
  236. package/dist/node-runtime/command-L3LAHDIH.js +13 -0
  237. package/dist/node-runtime/commands-RL5YBW5I.js +291 -0
  238. package/dist/node-runtime/config-FMEOZSWE.js +77 -0
  239. package/dist/node-runtime/curator-server-XCM43VEF.js +3816 -0
  240. package/dist/node-runtime/customize-XEXL2DGQ.js +12 -0
  241. package/dist/node-runtime/direct-tool-executor-JVDXTO7A.js +188 -0
  242. package/dist/node-runtime/exa-LL64QZR2.js +329 -0
  243. package/dist/node-runtime/export-html-KR26FOUZ.js +150 -0
  244. package/dist/node-runtime/extension-input-RV5N6APL.js +14 -0
  245. package/dist/node-runtime/extension-selector-CPD5LWDD.js +14 -0
  246. package/dist/node-runtime/extract-XLQSJN4V.js +17 -0
  247. package/dist/node-runtime/file-sync-HCOP2QVF.js +117 -0
  248. package/dist/node-runtime/gateway-X2TI5X7F.js +2484 -0
  249. package/dist/node-runtime/gemini-api-QE7ANVDZ.js +29 -0
  250. package/dist/node-runtime/gemini-search-U7SUMPQA.js +330 -0
  251. package/dist/node-runtime/gemini-url-context-PXWCBQHK.js +103 -0
  252. package/dist/node-runtime/gemini-web-MM446SEH.js +14 -0
  253. package/dist/node-runtime/github-extract-F64RZOEA.js +619 -0
  254. package/dist/node-runtime/goal-CZQ7FFQJ.js +1831 -0
  255. package/dist/node-runtime/index.js +859 -0
  256. package/dist/node-runtime/init-NJV2T55N.js +28 -0
  257. package/dist/node-runtime/install-cli-TH7IJJQQ.js +308 -0
  258. package/dist/node-runtime/interactive-mode-KOM35YF2.js +56 -0
  259. package/dist/node-runtime/interactive-view-U6OILKF3.js +249 -0
  260. package/dist/node-runtime/lsp-manager-3ASUSO4T.js +1104 -0
  261. package/dist/node-runtime/lunr-cron-YJ5UHYRD.js +268 -0
  262. package/dist/node-runtime/main.js +54 -0
  263. package/dist/node-runtime/mcp-auth-flow-QIXHW6QN.js +32 -0
  264. package/dist/node-runtime/mcp-panel-IIGMXQGP.js +501 -0
  265. package/dist/node-runtime/mcp-setup-panel-FEK7663I.js +355 -0
  266. package/dist/node-runtime/memory-cap-3S4XRLNP.js +20 -0
  267. package/dist/node-runtime/model-tiers-NJLHUEGK.js +20 -0
  268. package/dist/node-runtime/openai-search-B3MSNCQA.js +288 -0
  269. package/dist/node-runtime/package-manager-cli-TZZHJCVI.js +749 -0
  270. package/dist/node-runtime/parallel-AI2MNSCU.js +265 -0
  271. package/dist/node-runtime/parser-manager-TQHWYDH7.js +152 -0
  272. package/dist/node-runtime/pdf-extract-IPE6H4HP.js +57 -0
  273. package/dist/node-runtime/perplexity-QVJW3I35.js +12 -0
  274. package/dist/node-runtime/pi-intercom-EEMBGQID.js +2215 -0
  275. package/dist/node-runtime/pi-mcp-adapter-QFB37AVN.js +422 -0
  276. package/dist/node-runtime/pi-ollama-cloud-4VZRMULP.js +1440 -0
  277. package/dist/node-runtime/pi-prompt-template-model-4QT4LLXF.js +3946 -0
  278. package/dist/node-runtime/pi-subagents-7XJ4H53P.js +6023 -0
  279. package/dist/node-runtime/pi-web-access-DPGAVKOA.js +1864 -0
  280. package/dist/node-runtime/print-mode-VWIRFDAC.js +12 -0
  281. package/dist/node-runtime/proxy-modes-HEEFK4KC.js +685 -0
  282. package/dist/node-runtime/rpc-entry.js +62 -0
  283. package/dist/node-runtime/rpc-mode-SJNSOA4G.js +13 -0
  284. package/dist/node-runtime/runtime-bridges-PPHNBFWL.js +14 -0
  285. package/dist/node-runtime/session-manager-MQNBYACL.js +35 -0
  286. package/dist/node-runtime/session-selector-5AZLJS6U.js +14 -0
  287. package/dist/node-runtime/settings-manager-5LF2VQWC.js +21 -0
  288. package/dist/node-runtime/src-Y7JSCK64.js +2407 -0
  289. package/dist/node-runtime/subagent-executor-5RNDEPIJ.js +8483 -0
  290. package/dist/node-runtime/summary-review-YSMXKITO.js +228 -0
  291. package/dist/node-runtime/tavily-WEZFVFP7.js +154 -0
  292. package/dist/node-runtime/timings-UAD5BEAS.js +16 -0
  293. package/dist/node-runtime/tool-renderer-MV5O452K.js +204 -0
  294. package/dist/node-runtime/update-cli-A253SZ7P.js +73 -0
  295. package/dist/node-runtime/v4-5MNC3H7G.js +424 -0
  296. package/dist/node-runtime/video-extract-OYT5WKS5.js +304 -0
  297. package/dist/node-runtime/workspace-index-6DBXSTJ6.js +163 -0
  298. package/dist/node-runtime/youtube-extract-TQYKGFGS.js +264 -0
  299. package/dist/startup/benchmark-request.d.ts +3 -0
  300. package/dist/startup/benchmark-request.d.ts.map +1 -0
  301. package/dist/startup/benchmark-request.js +65 -0
  302. package/dist/startup/benchmark-request.js.map +1 -0
  303. package/dist/startup/interactive-view.d.ts +55 -0
  304. package/dist/startup/interactive-view.d.ts.map +1 -0
  305. package/dist/startup/interactive-view.js +332 -0
  306. package/dist/startup/interactive-view.js.map +1 -0
  307. package/dist/startup/launch-routing.d.ts.map +1 -1
  308. package/dist/startup/launch-routing.js +9 -10
  309. package/dist/startup/launch-routing.js.map +1 -1
  310. package/dist/startup/startup-milestones.d.ts +1 -1
  311. package/dist/startup/startup-milestones.d.ts.map +1 -1
  312. package/dist/startup/startup-milestones.js +3 -2
  313. package/dist/startup/startup-milestones.js.map +1 -1
  314. package/dist/utils/await-with-abort.d.ts +2 -0
  315. package/dist/utils/await-with-abort.d.ts.map +1 -0
  316. package/dist/utils/await-with-abort.js +19 -0
  317. package/dist/utils/await-with-abort.js.map +1 -0
  318. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  319. package/dist/utils/syntax-highlight.js +10 -4
  320. package/dist/utils/syntax-highlight.js.map +1 -1
  321. package/docs/compaction.md +5 -3
  322. package/docs/development.md +5 -1
  323. package/docs/features.md +0 -1
  324. package/docs/interactive-startup.md +98 -0
  325. package/docs/usage.md +0 -1
  326. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  327. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  328. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  329. package/examples/extensions/gondolin/package-lock.json +2 -2
  330. package/examples/extensions/gondolin/package.json +1 -1
  331. package/examples/extensions/sandbox/package-lock.json +2 -2
  332. package/examples/extensions/sandbox/package.json +1 -1
  333. package/examples/extensions/with-deps/package-lock.json +2 -2
  334. package/examples/extensions/with-deps/package.json +1 -1
  335. package/package.json +20 -20
  336. package/dist/core/swarm.d.ts +0 -23
  337. package/dist/core/swarm.d.ts.map +0 -1
  338. package/dist/core/swarm.js +0 -45
  339. package/dist/core/swarm.js.map +0 -1
@@ -0,0 +1,903 @@
1
+ import { createRequire as __lunrRequire } from "node:module"; const require = __lunrRequire(import.meta.url);
2
+ import {
3
+ createBranchSummaryMessage,
4
+ createCompactionSummaryMessage,
5
+ createCustomMessage
6
+ } from "./chunk-FVDOXRUD.js";
7
+ import {
8
+ getAgentDir,
9
+ getSessionsDir,
10
+ normalizePath,
11
+ resolvePath
12
+ } from "./chunk-PCIGF2XK.js";
13
+
14
+ // packages/coding-agent/dist/core/session-manager.js
15
+ import { uuidv7 } from "@ashx-j/lunr-agent";
16
+ import { randomUUID } from "crypto";
17
+ import { appendFileSync, closeSync, createReadStream, existsSync, mkdirSync, openSync, readdirSync, readSync, statSync, writeFileSync } from "fs";
18
+ import { readdir, stat } from "fs/promises";
19
+ import { join, resolve } from "path";
20
+ import { createInterface } from "readline";
21
+ import { StringDecoder } from "string_decoder";
22
+ var CURRENT_SESSION_VERSION = 3;
23
+ function createSessionId() {
24
+ return uuidv7();
25
+ }
26
+ function assertValidSessionId(id) {
27
+ if (!/^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(id))
28
+ throw new Error("Session id must be non-empty, contain only alphanumeric characters, '-', '_', and '.', and start and end with an alphanumeric character");
29
+ }
30
+ function generateId(byId) {
31
+ for (let i = 0; i < 100; i++) {
32
+ let id = randomUUID().slice(0, 8);
33
+ if (!byId.has(id))
34
+ return id;
35
+ }
36
+ return randomUUID();
37
+ }
38
+ function migrateV1ToV2(entries) {
39
+ let ids = /* @__PURE__ */ new Set(), prevId = null;
40
+ for (let entry of entries) {
41
+ if (entry.type === "session") {
42
+ entry.version = 2;
43
+ continue;
44
+ }
45
+ if (entry.id = generateId(ids), entry.parentId = prevId, prevId = entry.id, entry.type === "compaction") {
46
+ let comp = entry;
47
+ if (typeof comp.firstKeptEntryIndex == "number") {
48
+ let targetEntry = entries[comp.firstKeptEntryIndex];
49
+ targetEntry && targetEntry.type !== "session" && (comp.firstKeptEntryId = targetEntry.id), delete comp.firstKeptEntryIndex;
50
+ }
51
+ }
52
+ }
53
+ }
54
+ function migrateV2ToV3(entries) {
55
+ for (let entry of entries) {
56
+ if (entry.type === "session") {
57
+ entry.version = 3;
58
+ continue;
59
+ }
60
+ if (entry.type === "message") {
61
+ let msgEntry = entry;
62
+ msgEntry.message && msgEntry.message.role === "hookMessage" && (msgEntry.message.role = "custom");
63
+ }
64
+ }
65
+ }
66
+ function migrateToCurrentVersion(entries) {
67
+ let version = entries.find((e) => e.type === "session")?.version ?? 1;
68
+ return version >= CURRENT_SESSION_VERSION ? !1 : (version < 2 && migrateV1ToV2(entries), version < 3 && migrateV2ToV3(entries), !0);
69
+ }
70
+ function migrateSessionEntries(entries) {
71
+ migrateToCurrentVersion(entries);
72
+ }
73
+ function parseSessionEntries(content) {
74
+ let entries = [], lines = content.trim().split(`
75
+ `);
76
+ for (let [index, line] of lines.entries()) {
77
+ if (!line.trim())
78
+ continue;
79
+ let entry = parseSessionEntryLine(line, `line ${index + 1}`);
80
+ entry && entries.push(entry);
81
+ }
82
+ return entries;
83
+ }
84
+ function getLatestCompactionEntry(entries) {
85
+ for (let i = entries.length - 1; i >= 0; i--)
86
+ if (entries[i].type === "compaction")
87
+ return entries[i];
88
+ return null;
89
+ }
90
+ function validateSessionGraph(entries) {
91
+ let index = /* @__PURE__ */ new Map();
92
+ for (let entry of entries) {
93
+ if (typeof entry.id != "string" || !entry.id)
94
+ throw new Error("Session graph is corrupt: every entry must have a non-empty id");
95
+ if (index.has(entry.id))
96
+ throw new Error(`Session graph is corrupt: duplicate entry id "${entry.id}"`);
97
+ index.set(entry.id, entry);
98
+ }
99
+ for (let entry of entries) {
100
+ if (entry.parentId === entry.id)
101
+ throw new Error(`Session graph is corrupt: entry "${entry.id}" links to itself`);
102
+ if (entry.parentId !== null && !index.has(entry.parentId))
103
+ throw new Error(`Session graph is corrupt: entry "${entry.id}" has missing parent "${entry.parentId}"`);
104
+ }
105
+ let complete = /* @__PURE__ */ new Set();
106
+ for (let entry of entries) {
107
+ if (complete.has(entry.id))
108
+ continue;
109
+ let path = [], positions = /* @__PURE__ */ new Map(), current = entry;
110
+ for (; current && !complete.has(current.id); ) {
111
+ let position = positions.get(current.id);
112
+ if (position !== void 0) {
113
+ let cycle = [...path.slice(position), current.id].join(" -> ");
114
+ throw new Error(`Session graph is corrupt: parent cycle detected (${cycle})`);
115
+ }
116
+ positions.set(current.id, path.length), path.push(current.id), current = current.parentId === null ? void 0 : index.get(current.parentId);
117
+ }
118
+ for (let id of path)
119
+ complete.add(id);
120
+ }
121
+ }
122
+ function buildEntryIndex(entries, byId) {
123
+ return byId || (validateSessionGraph(entries), new Map(entries.map((entry) => [entry.id, entry])));
124
+ }
125
+ function buildSessionPath(entries, leafId, byId) {
126
+ let index = buildEntryIndex(entries, byId), leaf;
127
+ if (leafId === null)
128
+ return [];
129
+ if (leafId && (leaf = index.get(leafId)), leaf ??= entries[entries.length - 1], !leaf)
130
+ return [];
131
+ let path = [], visited = /* @__PURE__ */ new Set(), current = leaf;
132
+ for (; current; ) {
133
+ if (visited.has(current.id))
134
+ throw new Error(`Session graph is corrupt: parent cycle detected at entry "${current.id}"`);
135
+ if (visited.add(current.id), path.push(current), current.parentId && !index.has(current.parentId))
136
+ throw new Error(`Session graph is corrupt: entry "${current.id}" has missing parent "${current.parentId}"`);
137
+ current = current.parentId ? index.get(current.parentId) : void 0;
138
+ }
139
+ return path.reverse(), path;
140
+ }
141
+ function getSessionContextSettings(path) {
142
+ let thinkingLevel = "off", model = null;
143
+ for (let entry of path)
144
+ entry.type === "thinking_level_change" ? thinkingLevel = entry.thinkingLevel : entry.type === "model_change" ? model = { provider: entry.provider, modelId: entry.modelId } : entry.type === "message" && entry.message.role === "assistant" && (model = { provider: entry.message.provider, modelId: entry.message.model });
145
+ return { thinkingLevel, model };
146
+ }
147
+ function sessionEntryToContextMessages(entry) {
148
+ if (entry.type === "message") {
149
+ let message = entry.message;
150
+ return (message.role === "user" || message.role === "assistant" || message.role === "toolResult") && message.content == null ? [{ ...message, content: [] }] : [message];
151
+ }
152
+ return entry.type === "custom_message" ? [
153
+ createCustomMessage(entry.customType, entry.content ?? [], entry.display, entry.details, entry.timestamp)
154
+ ] : entry.type === "branch_summary" && entry.summary ? [createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp)] : entry.type === "compaction" ? [createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp)] : [];
155
+ }
156
+ function buildContextEntries(entries, leafId, byId) {
157
+ let path = buildSessionPath(entries, leafId, byId), compaction = null;
158
+ for (let entry of path)
159
+ entry.type === "compaction" && (compaction = entry);
160
+ if (!compaction)
161
+ return path;
162
+ let compactionIdx = path.findIndex((entry) => entry.id === compaction.id);
163
+ if (compactionIdx < 0)
164
+ return path;
165
+ let contextEntries = [compaction], foundFirstKept = !1;
166
+ for (let i = 0; i < compactionIdx; i++) {
167
+ let entry = path[i];
168
+ entry.id === compaction.firstKeptEntryId && (foundFirstKept = !0), foundFirstKept && contextEntries.push(entry);
169
+ }
170
+ return contextEntries.push(...path.slice(compactionIdx + 1)), contextEntries;
171
+ }
172
+ function buildSessionContext(entries, leafId, byId) {
173
+ let path = buildSessionPath(entries, leafId, byId), { thinkingLevel, model } = getSessionContextSettings(path);
174
+ return { messages: buildContextEntries(entries, leafId, byId).flatMap(sessionEntryToContextMessages), thinkingLevel, model };
175
+ }
176
+ function getDefaultSessionDirPath(cwd, agentDir = getAgentDir()) {
177
+ let resolvedCwd = resolvePath(cwd), resolvedAgentDir = resolvePath(agentDir), safePath = `--${resolvedCwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
178
+ return join(resolvedAgentDir, "sessions", safePath);
179
+ }
180
+ function getDefaultSessionDir(cwd, agentDir = getAgentDir()) {
181
+ let sessionDir = getDefaultSessionDirPath(cwd, agentDir);
182
+ return existsSync(sessionDir) || mkdirSync(sessionDir, { recursive: !0 }), sessionDir;
183
+ }
184
+ var SESSION_READ_BUFFER_SIZE = 1024 * 1024;
185
+ function parseSessionEntryLine(line, location) {
186
+ let trimmed = line.replace(/\u0000/g, "").trim();
187
+ if (!trimmed)
188
+ return null;
189
+ try {
190
+ return JSON.parse(trimmed);
191
+ } catch {
192
+ throw new Error(location ? `Malformed session line ${location}` : "Malformed session line");
193
+ }
194
+ }
195
+ function loadEntriesFromFile(filePath) {
196
+ let resolvedFilePath = normalizePath(filePath);
197
+ if (!existsSync(resolvedFilePath))
198
+ return [];
199
+ let entries = [], fd = openSync(resolvedFilePath, "r");
200
+ try {
201
+ let decoder = new StringDecoder("utf8"), buffer = Buffer.allocUnsafe(SESSION_READ_BUFFER_SIZE), pending = "", lineNumber = 0;
202
+ for (; ; ) {
203
+ let bytesRead = readSync(fd, buffer, 0, buffer.length, null);
204
+ if (bytesRead === 0)
205
+ break;
206
+ pending += decoder.write(buffer.subarray(0, bytesRead));
207
+ let lineStart = 0, newlineIndex = pending.indexOf(`
208
+ `, lineStart);
209
+ for (; newlineIndex !== -1; ) {
210
+ lineNumber++;
211
+ let entry = parseSessionEntryLine(pending.slice(lineStart, newlineIndex), `in ${resolvedFilePath}:${lineNumber}`);
212
+ entry && entries.push(entry), lineStart = newlineIndex + 1, newlineIndex = pending.indexOf(`
213
+ `, lineStart);
214
+ }
215
+ pending = pending.slice(lineStart);
216
+ }
217
+ if (pending += decoder.end(), pending.trim()) {
218
+ lineNumber++;
219
+ let finalEntry = parseSessionEntryLine(pending, `in ${resolvedFilePath}:${lineNumber}`);
220
+ finalEntry && entries.push(finalEntry);
221
+ }
222
+ } finally {
223
+ closeSync(fd);
224
+ }
225
+ if (entries.length === 0)
226
+ return entries;
227
+ let header = entries[0];
228
+ return header.type !== "session" || typeof header.id != "string" ? [] : entries;
229
+ }
230
+ function readSessionHeader(filePath) {
231
+ try {
232
+ let fd = openSync(filePath, "r"), buffer = Buffer.alloc(512), bytesRead = readSync(fd, buffer, 0, 512, 0);
233
+ closeSync(fd);
234
+ let firstLine = buffer.toString("utf8", 0, bytesRead).split(`
235
+ `)[0];
236
+ if (!firstLine)
237
+ return null;
238
+ let header = JSON.parse(firstLine);
239
+ return header.type !== "session" || typeof header.id != "string" ? null : header;
240
+ } catch {
241
+ return null;
242
+ }
243
+ }
244
+ function getSessionHeaderCwd(header) {
245
+ let cwd = header.cwd;
246
+ return typeof cwd == "string" ? cwd : void 0;
247
+ }
248
+ function sessionCwdMatches(cwd, resolvedCwd) {
249
+ return cwd !== void 0 && cwd !== "" && resolvePath(cwd) === resolvedCwd;
250
+ }
251
+ function findMostRecentSession(sessionDir, cwd) {
252
+ let resolvedSessionDir = normalizePath(sessionDir), resolvedCwd = cwd ? resolvePath(cwd) : void 0;
253
+ try {
254
+ return readdirSync(resolvedSessionDir).filter((f) => f.endsWith(".jsonl")).map((f) => join(resolvedSessionDir, f)).map((path) => ({ path, header: readSessionHeader(path) })).filter((file) => file.header !== null && (!resolvedCwd || sessionCwdMatches(getSessionHeaderCwd(file.header), resolvedCwd))).map(({ path }) => ({ path, mtime: statSync(path).mtime })).sort((a, b) => b.mtime.getTime() - a.mtime.getTime())[0]?.path || null;
255
+ } catch {
256
+ return null;
257
+ }
258
+ }
259
+ function isMessageWithContent(message) {
260
+ return typeof message.role == "string" && "content" in message;
261
+ }
262
+ function extractTextContent(message) {
263
+ let content = message.content;
264
+ return typeof content == "string" ? content : content.filter((block) => block.type === "text").map((block) => block.text).join(" ");
265
+ }
266
+ function getMessageActivityTime(entry) {
267
+ let message = entry.message;
268
+ if (!isMessageWithContent(message) || message.role !== "user" && message.role !== "assistant")
269
+ return;
270
+ let msgTimestamp = message.timestamp;
271
+ if (typeof msgTimestamp == "number")
272
+ return msgTimestamp;
273
+ let t = new Date(entry.timestamp).getTime();
274
+ return Number.isNaN(t) ? void 0 : t;
275
+ }
276
+ async function buildSessionInfo(filePath) {
277
+ try {
278
+ let stats = await stat(filePath), header = null, messageCount = 0, firstMessage = "", allMessages = [], name, lastActivityTime, rl = createInterface({
279
+ input: createReadStream(filePath, { encoding: "utf8" }),
280
+ crlfDelay: 1 / 0
281
+ });
282
+ for await (let line of rl) {
283
+ let entry = parseSessionEntryLine(line);
284
+ if (!entry)
285
+ continue;
286
+ if (!header) {
287
+ if (entry.type !== "session")
288
+ return null;
289
+ header = entry;
290
+ continue;
291
+ }
292
+ if (entry.type === "session_info" && (name = entry.name?.trim() || void 0), entry.type !== "message")
293
+ continue;
294
+ messageCount++;
295
+ let activityTime = getMessageActivityTime(entry);
296
+ typeof activityTime == "number" && (lastActivityTime = Math.max(lastActivityTime ?? 0, activityTime));
297
+ let message = entry.message;
298
+ if (!isMessageWithContent(message) || message.role !== "user" && message.role !== "assistant")
299
+ continue;
300
+ let textContent = extractTextContent(message);
301
+ textContent && (allMessages.push(textContent), !firstMessage && message.role === "user" && (firstMessage = textContent));
302
+ }
303
+ if (!header)
304
+ return null;
305
+ let cwd = typeof header.cwd == "string" ? header.cwd : "", parentSessionPath = header.parentSession, headerTime = typeof header.timestamp == "string" ? new Date(header.timestamp).getTime() : NaN, modified = typeof lastActivityTime == "number" && lastActivityTime > 0 ? new Date(lastActivityTime) : Number.isNaN(headerTime) ? stats.mtime : new Date(headerTime);
306
+ return {
307
+ path: filePath,
308
+ id: header.id,
309
+ cwd,
310
+ name,
311
+ parentSessionPath,
312
+ created: new Date(header.timestamp),
313
+ modified,
314
+ messageCount,
315
+ firstMessage: firstMessage || "(no messages)",
316
+ allMessagesText: allMessages.join(" ")
317
+ };
318
+ } catch {
319
+ return null;
320
+ }
321
+ }
322
+ var MAX_CONCURRENT_SESSION_INFO_LOADS = 10;
323
+ async function buildSessionInfosWithConcurrency(files, onLoaded) {
324
+ let results = new Array(files.length).fill(null), inFlight = /* @__PURE__ */ new Set(), nextIndex = 0, startNext = () => {
325
+ let index = nextIndex++, file = files[index];
326
+ if (!file)
327
+ return;
328
+ let task;
329
+ task = buildSessionInfo(file).then((info) => {
330
+ results[index] = info;
331
+ }).catch(() => {
332
+ results[index] = null;
333
+ }).finally(() => {
334
+ inFlight.delete(task), onLoaded();
335
+ }), inFlight.add(task);
336
+ };
337
+ for (; nextIndex < files.length || inFlight.size > 0; ) {
338
+ for (; nextIndex < files.length && inFlight.size < MAX_CONCURRENT_SESSION_INFO_LOADS; )
339
+ startNext();
340
+ inFlight.size > 0 && await Promise.race(inFlight);
341
+ }
342
+ return results;
343
+ }
344
+ async function listSessionsFromDir(dir, onProgress, progressOffset = 0, progressTotal) {
345
+ let sessions = [];
346
+ if (!existsSync(dir))
347
+ return sessions;
348
+ try {
349
+ let files = (await readdir(dir)).filter((f) => f.endsWith(".jsonl")).map((f) => join(dir, f)), total = progressTotal ?? files.length, loaded = 0, results = await buildSessionInfosWithConcurrency(files, () => {
350
+ loaded++, onProgress?.(progressOffset + loaded, total);
351
+ });
352
+ for (let info of results)
353
+ info && sessions.push(info);
354
+ } catch {
355
+ }
356
+ return sessions;
357
+ }
358
+ var SessionManager = class _SessionManager {
359
+ sessionId = "";
360
+ sessionFile;
361
+ sessionDir;
362
+ cwd;
363
+ persist;
364
+ flushed = !1;
365
+ fileEntries = [];
366
+ byId = /* @__PURE__ */ new Map();
367
+ labelsById = /* @__PURE__ */ new Map();
368
+ labelTimestampsById = /* @__PURE__ */ new Map();
369
+ leafId = null;
370
+ constructor(cwd, sessionDir, sessionFile, persist, newSessionOptions) {
371
+ this.cwd = resolvePath(cwd), this.sessionDir = normalizePath(sessionDir), this.persist = persist, persist && this.sessionDir && !existsSync(this.sessionDir) && mkdirSync(this.sessionDir, { recursive: !0 }), sessionFile ? this.setSessionFile(sessionFile) : this.newSession(newSessionOptions);
372
+ }
373
+ /** Switch to a different session file (used for resume and branching) */
374
+ setSessionFile(sessionFile) {
375
+ if (this.sessionFile = resolvePath(sessionFile), existsSync(this.sessionFile)) {
376
+ if (this.fileEntries = loadEntriesFromFile(this.sessionFile), this.fileEntries.length === 0) {
377
+ let explicitPath = this.sessionFile;
378
+ if (statSync(explicitPath).size > 0)
379
+ throw new Error(`Session file is not a valid pi session: ${explicitPath}`);
380
+ this.newSession(), this.sessionFile = explicitPath, this._rewriteFile(), this.flushed = !0;
381
+ return;
382
+ }
383
+ let header = this.fileEntries.find((e) => e.type === "session");
384
+ if (!header)
385
+ throw new Error(`Session file is not a valid pi session: ${this.sessionFile}`);
386
+ this.sessionId = header.id, migrateToCurrentVersion(this.fileEntries) && this._rewriteFile(), this._buildIndex(), this.flushed = !0;
387
+ } else {
388
+ let explicitPath = this.sessionFile;
389
+ this.newSession(), this.sessionFile = explicitPath;
390
+ }
391
+ }
392
+ newSession(options) {
393
+ options?.id !== void 0 && assertValidSessionId(options.id), this.sessionId = options?.id ?? createSessionId();
394
+ let timestamp = (/* @__PURE__ */ new Date()).toISOString(), header = {
395
+ type: "session",
396
+ version: CURRENT_SESSION_VERSION,
397
+ id: this.sessionId,
398
+ timestamp,
399
+ cwd: this.cwd,
400
+ parentSession: options?.parentSession
401
+ };
402
+ if (this.fileEntries = [header], this.byId.clear(), this.labelsById.clear(), this.labelTimestampsById.clear(), this.leafId = null, this.flushed = !1, this.persist) {
403
+ let fileTimestamp = timestamp.replace(/[:.]/g, "-");
404
+ this.sessionFile = join(this.getSessionDir(), `${fileTimestamp}_${this.sessionId}.jsonl`);
405
+ }
406
+ return this.sessionFile;
407
+ }
408
+ _buildIndex() {
409
+ validateSessionGraph(this.fileEntries.filter((entry) => entry.type !== "session")), this.byId.clear(), this.labelsById.clear(), this.labelTimestampsById.clear(), this.leafId = null;
410
+ for (let entry of this.fileEntries)
411
+ entry.type !== "session" && (this.byId.set(entry.id, entry), this.leafId = entry.id, entry.type === "label" && (entry.label ? (this.labelsById.set(entry.targetId, entry.label), this.labelTimestampsById.set(entry.targetId, entry.timestamp)) : (this.labelsById.delete(entry.targetId), this.labelTimestampsById.delete(entry.targetId))));
412
+ }
413
+ _rewriteFile() {
414
+ if (!this.persist || !this.sessionFile)
415
+ return;
416
+ let fd = openSync(this.sessionFile, "w");
417
+ try {
418
+ for (let entry of this.fileEntries)
419
+ writeFileSync(fd, `${JSON.stringify(entry)}
420
+ `);
421
+ } finally {
422
+ closeSync(fd);
423
+ }
424
+ }
425
+ isPersisted() {
426
+ return this.persist;
427
+ }
428
+ getCwd() {
429
+ return this.cwd;
430
+ }
431
+ getSessionDir() {
432
+ return this.sessionDir;
433
+ }
434
+ usesDefaultSessionDir() {
435
+ return this.sessionDir === getDefaultSessionDirPath(this.cwd);
436
+ }
437
+ getSessionId() {
438
+ return this.sessionId;
439
+ }
440
+ getSessionFile() {
441
+ return this.sessionFile;
442
+ }
443
+ _persist(entry) {
444
+ if (!this.persist || !this.sessionFile)
445
+ return;
446
+ if (!this.fileEntries.some((e) => e.type === "message" && e.message.role === "assistant")) {
447
+ this.flushed ? appendFileSync(this.sessionFile, `${JSON.stringify(entry)}
448
+ `) : this.flushed = !1;
449
+ return;
450
+ }
451
+ if (this.flushed)
452
+ appendFileSync(this.sessionFile, `${JSON.stringify(entry)}
453
+ `);
454
+ else {
455
+ let fd = openSync(this.sessionFile, "wx");
456
+ try {
457
+ for (let e of this.fileEntries)
458
+ writeFileSync(fd, `${JSON.stringify(e)}
459
+ `);
460
+ } finally {
461
+ closeSync(fd);
462
+ }
463
+ this.flushed = !0;
464
+ }
465
+ }
466
+ _appendEntry(entry) {
467
+ this.fileEntries.push(entry), this.byId.set(entry.id, entry), this.leafId = entry.id, this._persist(entry);
468
+ }
469
+ /** Append a message as child of current leaf, then advance leaf. Returns entry id.
470
+ * Does not allow writing CompactionSummaryMessage and BranchSummaryMessage directly.
471
+ * Reason: we want these to be top-level entries in the session, not message session entries,
472
+ * so it is easier to find them.
473
+ * These need to be appended via appendCompaction() and appendBranchSummary() methods.
474
+ */
475
+ appendMessage(message) {
476
+ let entry = {
477
+ type: "message",
478
+ id: generateId(this.byId),
479
+ parentId: this.leafId,
480
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
481
+ message
482
+ };
483
+ return this._appendEntry(entry), entry.id;
484
+ }
485
+ /** Append a thinking level change as child of current leaf, then advance leaf. Returns entry id. */
486
+ appendThinkingLevelChange(thinkingLevel) {
487
+ let entry = {
488
+ type: "thinking_level_change",
489
+ id: generateId(this.byId),
490
+ parentId: this.leafId,
491
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
492
+ thinkingLevel
493
+ };
494
+ return this._appendEntry(entry), entry.id;
495
+ }
496
+ /** Append a model change as child of current leaf, then advance leaf. Returns entry id. */
497
+ appendModelChange(provider, modelId) {
498
+ let entry = {
499
+ type: "model_change",
500
+ id: generateId(this.byId),
501
+ parentId: this.leafId,
502
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
503
+ provider,
504
+ modelId
505
+ };
506
+ return this._appendEntry(entry), entry.id;
507
+ }
508
+ /** Append a compaction summary as child of current leaf, then advance leaf. Returns entry id. */
509
+ appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromHook) {
510
+ let entry = {
511
+ type: "compaction",
512
+ id: generateId(this.byId),
513
+ parentId: this.leafId,
514
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
515
+ summary,
516
+ firstKeptEntryId,
517
+ tokensBefore,
518
+ details,
519
+ fromHook
520
+ };
521
+ return this._appendEntry(entry), entry.id;
522
+ }
523
+ /** Append a custom entry (for extensions) as child of current leaf, then advance leaf. Returns entry id. */
524
+ appendCustomEntry(customType, data) {
525
+ let entry = {
526
+ type: "custom",
527
+ customType,
528
+ data,
529
+ id: generateId(this.byId),
530
+ parentId: this.leafId,
531
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
532
+ };
533
+ return this._appendEntry(entry), entry.id;
534
+ }
535
+ /** Append a session info entry (e.g., display name). Returns entry id. */
536
+ appendSessionInfo(name) {
537
+ let sanitizedName = name.replace(/[\r\n]+/g, " ").trim(), entry = {
538
+ type: "session_info",
539
+ id: generateId(this.byId),
540
+ parentId: this.leafId,
541
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
542
+ name: sanitizedName
543
+ };
544
+ return this._appendEntry(entry), entry.id;
545
+ }
546
+ /** Get the current session name from the latest session_info entry, if any. */
547
+ getSessionName() {
548
+ let entries = this.getEntries();
549
+ for (let i = entries.length - 1; i >= 0; i--) {
550
+ let entry = entries[i];
551
+ if (entry.type === "session_info")
552
+ return entry.name?.trim() || void 0;
553
+ }
554
+ }
555
+ /**
556
+ * Append a custom message entry (for extensions) that participates in LLM context.
557
+ * @param customType Extension identifier for filtering on reload
558
+ * @param content Message content (string or TextContent/ImageContent array)
559
+ * @param display Whether to show in TUI (true = styled display, false = hidden)
560
+ * @param details Optional extension-specific metadata (not sent to LLM)
561
+ * @returns Entry id
562
+ */
563
+ appendCustomMessageEntry(customType, content, display, details) {
564
+ let entry = {
565
+ type: "custom_message",
566
+ customType,
567
+ content,
568
+ display,
569
+ details,
570
+ id: generateId(this.byId),
571
+ parentId: this.leafId,
572
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
573
+ };
574
+ return this._appendEntry(entry), entry.id;
575
+ }
576
+ // =========================================================================
577
+ // Tree Traversal
578
+ // =========================================================================
579
+ getLeafId() {
580
+ return this.leafId;
581
+ }
582
+ getLeafEntry() {
583
+ return this.leafId ? this.byId.get(this.leafId) : void 0;
584
+ }
585
+ getEntry(id) {
586
+ return this.byId.get(id);
587
+ }
588
+ /**
589
+ * Get all direct children of an entry.
590
+ */
591
+ getChildren(parentId) {
592
+ let children = [];
593
+ for (let entry of this.byId.values())
594
+ entry.parentId === parentId && children.push(entry);
595
+ return children;
596
+ }
597
+ /**
598
+ * Get the label for an entry, if any.
599
+ */
600
+ getLabel(id) {
601
+ return this.labelsById.get(id);
602
+ }
603
+ /**
604
+ * Set or clear a label on an entry.
605
+ * Labels are user-defined markers for bookmarking/navigation.
606
+ * Pass undefined or empty string to clear the label.
607
+ */
608
+ appendLabelChange(targetId, label) {
609
+ if (!this.byId.has(targetId))
610
+ throw new Error(`Entry ${targetId} not found`);
611
+ let entry = {
612
+ type: "label",
613
+ id: generateId(this.byId),
614
+ parentId: this.leafId,
615
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
616
+ targetId,
617
+ label
618
+ };
619
+ return this._appendEntry(entry), label ? (this.labelsById.set(targetId, label), this.labelTimestampsById.set(targetId, entry.timestamp)) : (this.labelsById.delete(targetId), this.labelTimestampsById.delete(targetId)), entry.id;
620
+ }
621
+ /**
622
+ * Walk from entry to root, returning all entries in path order.
623
+ * Includes all entry types (messages, compaction, model changes, etc.).
624
+ * Use buildSessionContext() to get the resolved messages for the LLM.
625
+ */
626
+ getBranch(fromId) {
627
+ let path = [], visited = /* @__PURE__ */ new Set(), startId = fromId ?? this.leafId, current = startId ? this.byId.get(startId) : void 0;
628
+ for (; current; ) {
629
+ if (visited.has(current.id))
630
+ throw new Error(`Session graph is corrupt: parent cycle detected at entry "${current.id}"`);
631
+ if (visited.add(current.id), path.push(current), current.parentId && !this.byId.has(current.parentId))
632
+ throw new Error(`Session graph is corrupt: entry "${current.id}" has missing parent "${current.parentId}"`);
633
+ current = current.parentId ? this.byId.get(current.parentId) : void 0;
634
+ }
635
+ return path.reverse(), path;
636
+ }
637
+ /**
638
+ * Build the active, compaction-aware entry list for context/rendering.
639
+ * Uses tree traversal from current leaf.
640
+ */
641
+ buildContextEntries() {
642
+ return buildContextEntries(this.getEntries(), this.leafId, this.byId);
643
+ }
644
+ /**
645
+ * Build the session context (what gets sent to the LLM).
646
+ * Uses tree traversal from current leaf.
647
+ */
648
+ buildSessionContext() {
649
+ return buildSessionContext(this.getEntries(), this.leafId, this.byId);
650
+ }
651
+ /**
652
+ * Get session header.
653
+ */
654
+ getHeader() {
655
+ let h = this.fileEntries.find((e) => e.type === "session");
656
+ return h || null;
657
+ }
658
+ /**
659
+ * Get all session entries (excludes header). Returns a shallow copy.
660
+ * The session is append-only: use appendXXX() to add entries, branch() to
661
+ * change the leaf pointer. Entries cannot be modified or deleted.
662
+ */
663
+ getEntries() {
664
+ return this.fileEntries.filter((e) => e.type !== "session");
665
+ }
666
+ /**
667
+ * Get the session as a tree structure. Returns a shallow defensive copy of all entries.
668
+ * A well-formed session has exactly one root (first entry with parentId === null).
669
+ * Orphaned entries (broken parent chain) are also returned as roots.
670
+ */
671
+ getTree() {
672
+ let entries = this.getEntries(), nodeMap = /* @__PURE__ */ new Map(), roots = [];
673
+ for (let entry of entries) {
674
+ let label = this.labelsById.get(entry.id), labelTimestamp = this.labelTimestampsById.get(entry.id);
675
+ nodeMap.set(entry.id, { entry, children: [], label, labelTimestamp });
676
+ }
677
+ for (let entry of entries) {
678
+ let node = nodeMap.get(entry.id);
679
+ if (entry.parentId === null || entry.parentId === entry.id)
680
+ roots.push(node);
681
+ else {
682
+ let parent = nodeMap.get(entry.parentId);
683
+ parent ? parent.children.push(node) : roots.push(node);
684
+ }
685
+ }
686
+ let stack = [...roots];
687
+ for (; stack.length > 0; ) {
688
+ let node = stack.pop();
689
+ node.children.sort((a, b) => new Date(a.entry.timestamp).getTime() - new Date(b.entry.timestamp).getTime()), stack.push(...node.children);
690
+ }
691
+ return roots;
692
+ }
693
+ // =========================================================================
694
+ // Branching
695
+ // =========================================================================
696
+ /**
697
+ * Start a new branch from an earlier entry.
698
+ * Moves the leaf pointer to the specified entry. The next appendXXX() call
699
+ * will create a child of that entry, forming a new branch. Existing entries
700
+ * are not modified or deleted.
701
+ */
702
+ branch(branchFromId) {
703
+ if (!this.byId.has(branchFromId))
704
+ throw new Error(`Entry ${branchFromId} not found`);
705
+ this.leafId = branchFromId;
706
+ }
707
+ /**
708
+ * Reset the leaf pointer to null (before any entries).
709
+ * The next appendXXX() call will create a new root entry (parentId = null).
710
+ * Use this when navigating to re-edit the first user message.
711
+ */
712
+ resetLeaf() {
713
+ this.leafId = null;
714
+ }
715
+ /**
716
+ * Start a new branch with a summary of the abandoned path.
717
+ * Same as branch(), but also appends a branch_summary entry that captures
718
+ * context from the abandoned conversation path.
719
+ */
720
+ branchWithSummary(branchFromId, summary, details, fromHook) {
721
+ if (branchFromId !== null && !this.byId.has(branchFromId))
722
+ throw new Error(`Entry ${branchFromId} not found`);
723
+ this.leafId = branchFromId;
724
+ let entry = {
725
+ type: "branch_summary",
726
+ id: generateId(this.byId),
727
+ parentId: branchFromId,
728
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
729
+ fromId: branchFromId ?? "root",
730
+ summary,
731
+ details,
732
+ fromHook
733
+ };
734
+ return this._appendEntry(entry), entry.id;
735
+ }
736
+ /**
737
+ * Create a new session file containing only the path from root to the specified leaf.
738
+ * Useful for extracting a single conversation path from a branched session.
739
+ * Returns the new session file path, or undefined if not persisting.
740
+ */
741
+ createBranchedSession(leafId) {
742
+ let previousSessionFile = this.sessionFile, path = this.getBranch(leafId);
743
+ if (path.length === 0)
744
+ throw new Error(`Entry ${leafId} not found`);
745
+ let pathWithoutLabels = [], pathParentId = null;
746
+ for (let entry of path)
747
+ entry.type !== "label" && (pathWithoutLabels.push({ ...entry, parentId: pathParentId }), pathParentId = entry.id);
748
+ let newSessionId = createSessionId(), timestamp = (/* @__PURE__ */ new Date()).toISOString(), fileTimestamp = timestamp.replace(/[:.]/g, "-"), newSessionFile = join(this.getSessionDir(), `${fileTimestamp}_${newSessionId}.jsonl`), header = {
749
+ type: "session",
750
+ version: CURRENT_SESSION_VERSION,
751
+ id: newSessionId,
752
+ timestamp,
753
+ cwd: this.cwd,
754
+ parentSession: this.persist ? previousSessionFile : void 0
755
+ }, pathEntryIds = new Set(pathWithoutLabels.map((e) => e.id)), labelsToWrite = [];
756
+ for (let [targetId, label] of this.labelsById)
757
+ pathEntryIds.has(targetId) && labelsToWrite.push({ targetId, label, timestamp: this.labelTimestampsById.get(targetId) });
758
+ if (this.persist) {
759
+ let parentId2 = pathWithoutLabels[pathWithoutLabels.length - 1]?.id || null, labelEntries2 = [];
760
+ for (let { targetId, label, timestamp: labelTimestamp } of labelsToWrite) {
761
+ let labelEntry = {
762
+ type: "label",
763
+ id: generateId(new Set(pathEntryIds)),
764
+ parentId: parentId2,
765
+ timestamp: labelTimestamp,
766
+ targetId,
767
+ label
768
+ };
769
+ pathEntryIds.add(labelEntry.id), labelEntries2.push(labelEntry), parentId2 = labelEntry.id;
770
+ }
771
+ return this.fileEntries = [header, ...pathWithoutLabels, ...labelEntries2], this.sessionId = newSessionId, this.sessionFile = newSessionFile, this._buildIndex(), this.fileEntries.some((e) => e.type === "message" && e.message.role === "assistant") ? (this._rewriteFile(), this.flushed = !0) : this.flushed = !1, newSessionFile;
772
+ }
773
+ let labelEntries = [], parentId = pathWithoutLabels[pathWithoutLabels.length - 1]?.id || null;
774
+ for (let { targetId, label, timestamp: labelTimestamp } of labelsToWrite) {
775
+ let labelEntry = {
776
+ type: "label",
777
+ id: generateId(/* @__PURE__ */ new Set([...pathEntryIds, ...labelEntries.map((e) => e.id)])),
778
+ parentId,
779
+ timestamp: labelTimestamp,
780
+ targetId,
781
+ label
782
+ };
783
+ labelEntries.push(labelEntry), parentId = labelEntry.id;
784
+ }
785
+ this.fileEntries = [header, ...pathWithoutLabels, ...labelEntries], this.sessionId = newSessionId, this._buildIndex();
786
+ }
787
+ /**
788
+ * Create a new session.
789
+ * @param cwd Working directory (stored in session header)
790
+ * @param sessionDir Optional session directory. If omitted, uses default (~/.pi/agent/sessions/<encoded-cwd>/).
791
+ */
792
+ static create(cwd, sessionDir, options) {
793
+ let dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(cwd);
794
+ return new _SessionManager(cwd, dir, void 0, !0, options);
795
+ }
796
+ /**
797
+ * Open a specific session file.
798
+ * @param path Path to session file
799
+ * @param sessionDir Optional session directory for /new or /branch. If omitted, derives from file's parent.
800
+ * @param cwdOverride Optional cwd override instead of the session header cwd.
801
+ */
802
+ static open(path, sessionDir, cwdOverride) {
803
+ let resolvedPath = resolvePath(path), header = loadEntriesFromFile(resolvedPath).find((e) => e.type === "session"), cwd = cwdOverride ?? header?.cwd ?? process.cwd(), dir = sessionDir ? normalizePath(sessionDir) : resolve(resolvedPath, "..");
804
+ return new _SessionManager(cwd, dir, resolvedPath, !0);
805
+ }
806
+ /**
807
+ * Continue the most recent session, or create new if none.
808
+ * @param cwd Working directory
809
+ * @param sessionDir Optional session directory. If omitted, uses default (~/.pi/agent/sessions/<encoded-cwd>/).
810
+ */
811
+ static continueRecent(cwd, sessionDir) {
812
+ let dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(cwd), filterCwd = sessionDir !== void 0 && dir !== getDefaultSessionDirPath(cwd), mostRecent = findMostRecentSession(dir, filterCwd ? cwd : void 0);
813
+ return mostRecent ? new _SessionManager(cwd, dir, mostRecent, !0) : new _SessionManager(cwd, dir, void 0, !0);
814
+ }
815
+ /** Create an in-memory session (no file persistence) */
816
+ static inMemory(cwd = process.cwd(), options) {
817
+ return new _SessionManager(cwd, "", void 0, !1, options);
818
+ }
819
+ /**
820
+ * Fork a session from another project directory into the current project.
821
+ * Creates a new session in the target cwd with the full history from the source session.
822
+ * @param sourcePath Path to the source session file
823
+ * @param targetCwd Target working directory (where the new session will be stored)
824
+ * @param sessionDir Optional session directory. If omitted, uses default for targetCwd.
825
+ */
826
+ static forkFrom(sourcePath, targetCwd, sessionDir, options) {
827
+ let resolvedSourcePath = resolvePath(sourcePath), resolvedTargetCwd = resolvePath(targetCwd), sourceEntries = loadEntriesFromFile(resolvedSourcePath);
828
+ if (sourceEntries.length === 0)
829
+ throw new Error(`Cannot fork: source session file is empty or invalid: ${resolvedSourcePath}`);
830
+ if (!sourceEntries.find((e) => e.type === "session"))
831
+ throw new Error(`Cannot fork: source session has no header: ${resolvedSourcePath}`);
832
+ let dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(resolvedTargetCwd);
833
+ existsSync(dir) || mkdirSync(dir, { recursive: !0 }), options?.id !== void 0 && assertValidSessionId(options.id);
834
+ let newSessionId = options?.id ?? createSessionId(), timestamp = (/* @__PURE__ */ new Date()).toISOString(), fileTimestamp = timestamp.replace(/[:.]/g, "-"), newSessionFile = join(dir, `${fileTimestamp}_${newSessionId}.jsonl`);
835
+ writeFileSync(newSessionFile, `${JSON.stringify({
836
+ type: "session",
837
+ version: CURRENT_SESSION_VERSION,
838
+ id: newSessionId,
839
+ timestamp,
840
+ cwd: resolvedTargetCwd,
841
+ parentSession: resolvedSourcePath
842
+ })}
843
+ `, { flag: "wx" });
844
+ for (let entry of sourceEntries)
845
+ entry.type !== "session" && appendFileSync(newSessionFile, `${JSON.stringify(entry)}
846
+ `);
847
+ return new _SessionManager(resolvedTargetCwd, dir, newSessionFile, !0);
848
+ }
849
+ /**
850
+ * List all sessions for a directory.
851
+ * @param cwd Working directory (used to compute default session directory)
852
+ * @param sessionDir Optional session directory. If omitted, uses default (~/.pi/agent/sessions/<encoded-cwd>/).
853
+ * @param onProgress Optional callback for progress updates (loaded, total)
854
+ */
855
+ static async list(cwd, sessionDir, onProgress) {
856
+ let dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(cwd), filterCwd = sessionDir !== void 0 && dir !== getDefaultSessionDirPath(cwd), resolvedCwd = resolvePath(cwd), sessions = (await listSessionsFromDir(dir, onProgress)).filter((session) => !filterCwd || sessionCwdMatches(session.cwd, resolvedCwd));
857
+ return sessions.sort((a, b) => b.modified.getTime() - a.modified.getTime()), sessions;
858
+ }
859
+ static async listAll(sessionDirOrOnProgress, onProgress) {
860
+ let customSessionDir = typeof sessionDirOrOnProgress == "string" ? normalizePath(sessionDirOrOnProgress) : void 0, progress = typeof sessionDirOrOnProgress == "function" ? sessionDirOrOnProgress : onProgress;
861
+ if (customSessionDir) {
862
+ let sessions = await listSessionsFromDir(customSessionDir, progress);
863
+ return sessions.sort((a, b) => b.modified.getTime() - a.modified.getTime()), sessions;
864
+ }
865
+ let sessionsDir = getSessionsDir();
866
+ try {
867
+ if (!existsSync(sessionsDir))
868
+ return [];
869
+ let dirs = (await readdir(sessionsDir, { withFileTypes: !0 })).filter((e) => e.isDirectory()).map((e) => join(sessionsDir, e.name)), totalFiles = 0, dirFiles = [];
870
+ for (let dir of dirs)
871
+ try {
872
+ let files = (await readdir(dir)).filter((f) => f.endsWith(".jsonl"));
873
+ dirFiles.push(files.map((f) => join(dir, f))), totalFiles += files.length;
874
+ } catch {
875
+ dirFiles.push([]);
876
+ }
877
+ let loaded = 0, sessions = [], allFiles = dirFiles.flat(), results = await buildSessionInfosWithConcurrency(allFiles, () => {
878
+ loaded++, progress?.(loaded, totalFiles);
879
+ });
880
+ for (let info of results)
881
+ info && sessions.push(info);
882
+ return sessions.sort((a, b) => b.modified.getTime() - a.modified.getTime()), sessions;
883
+ } catch {
884
+ return [];
885
+ }
886
+ }
887
+ };
888
+
889
+ export {
890
+ CURRENT_SESSION_VERSION,
891
+ assertValidSessionId,
892
+ migrateSessionEntries,
893
+ parseSessionEntries,
894
+ getLatestCompactionEntry,
895
+ validateSessionGraph,
896
+ sessionEntryToContextMessages,
897
+ buildContextEntries,
898
+ buildSessionContext,
899
+ getDefaultSessionDir,
900
+ loadEntriesFromFile,
901
+ findMostRecentSession,
902
+ SessionManager
903
+ };