@code-yeongyu/senpi 2026.9.23-5 → 2026.9.24-2

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 (315) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/dist/bundle/chunks/{anthropic-messages-77YBORJ5.js → anthropic-messages-UPLQFNTT.js} +2 -2
  3. package/dist/bundle/chunks/{app-server-command-BGT65PGC.js → app-server-command-UHPJ2C4D.js} +1 -1
  4. package/dist/bundle/chunks/{azure-openai-responses-PSESFNHN.js → azure-openai-responses-XAR2E66I.js} +1 -1
  5. package/dist/bundle/chunks/{chunk-WXIRFRXY.js → chunk-2PLPSKHD.js} +1 -1
  6. package/dist/bundle/chunks/{chunk-7PANH3NB.js → chunk-3WBSBDBX.js} +1 -1
  7. package/dist/bundle/chunks/{chunk-BBOQ5H4W.js → chunk-6WBYI25N.js} +1 -1
  8. package/dist/bundle/chunks/{chunk-RG3UEFSF.js → chunk-7DY7UYLL.js} +1 -1
  9. package/dist/bundle/chunks/{chunk-VKBY4F76.js → chunk-BSOJHK4W.js} +1 -1
  10. package/dist/bundle/chunks/{chunk-3XHWW7SQ.js → chunk-CLZVNQW3.js} +1 -1
  11. package/dist/bundle/chunks/{chunk-ORCF262V.js → chunk-EJKCBRYK.js} +3 -3
  12. package/dist/bundle/chunks/chunk-J7IUURQ6.js +8 -0
  13. package/dist/bundle/chunks/{chunk-PSMTQDII.js → chunk-JRQSHZPP.js} +15 -9
  14. package/dist/bundle/chunks/{chunk-DUV3UFKX.js → chunk-MKAM7IRH.js} +1 -1
  15. package/dist/bundle/chunks/chunk-MO2U7YRX.js +11 -0
  16. package/dist/bundle/chunks/{chunk-ZEFQYQOU.js → chunk-NGHOUIPR.js} +1 -1
  17. package/dist/bundle/chunks/{chunk-XDSQYM4F.js → chunk-NKVUDCGZ.js} +2 -2
  18. package/dist/bundle/chunks/{chunk-J3QXPP4T.js → chunk-ONR57UMO.js} +1 -1
  19. package/dist/bundle/chunks/{chunk-TQDWU3ZQ.js → chunk-SYQVC7UM.js} +1 -1
  20. package/dist/bundle/chunks/chunk-TTHMOL5G.js +2 -0
  21. package/dist/bundle/chunks/{chunk-NNHFMZD5.js → chunk-UBPMXBOJ.js} +1 -1
  22. package/dist/bundle/chunks/chunk-WASCMT6Y.js +2 -0
  23. package/dist/bundle/chunks/{chunk-EN6KDFY2.js → chunk-WISJJQ4K.js} +1 -1
  24. package/dist/bundle/chunks/{chunk-IVYZMSFY.js → chunk-WL5EQYNL.js} +1 -1
  25. package/dist/bundle/chunks/{chunk-LC6SZTVE.js → chunk-WTSAB6AE.js} +1 -1
  26. package/dist/bundle/chunks/{chunk-HKE42SWX.js → chunk-Y54V65MS.js} +1 -1
  27. package/dist/bundle/chunks/{chunk-3RN6BFG2.js → chunk-YBC274GY.js} +4 -4
  28. package/dist/bundle/chunks/{chunk-RRSND33J.js → chunk-YKU45B65.js} +54 -54
  29. package/dist/bundle/chunks/{chunk-WUYBEF7C.js → chunk-YWO3OBYK.js} +1 -1
  30. package/dist/bundle/chunks/cli-main-O5Y3TBID.js +3 -0
  31. package/dist/bundle/chunks/{google-generative-ai-YJHSZAY5.js → google-generative-ai-B5QMFONL.js} +1 -1
  32. package/dist/bundle/chunks/{google-vertex-JTFWEDNJ.js → google-vertex-O2TGMVWF.js} +1 -1
  33. package/dist/bundle/chunks/{help-fast-path-QXVCHTP3.js → help-fast-path-Y33OIZBU.js} +1 -1
  34. package/dist/bundle/chunks/{host-command-3PUZYQOK.js → host-command-WJOL27Q7.js} +1 -1
  35. package/dist/bundle/chunks/{host-lifecycle-OHPSU5VU.js → host-lifecycle-YBFXYFZP.js} +1 -1
  36. package/dist/bundle/chunks/{interactive-host-runtime-57LEAJPU.js → interactive-host-runtime-XVTF3NUD.js} +1 -1
  37. package/dist/bundle/chunks/interactive-mode-OO3NGM4G.js +2 -0
  38. package/dist/bundle/chunks/{list-tips-Z62FXPOJ.js → list-tips-EBRNBPBM.js} +1 -1
  39. package/dist/bundle/chunks/{mistral-conversations-VJPMPQ5T.js → mistral-conversations-AS3SAWPA.js} +1 -1
  40. package/dist/bundle/chunks/{multi-session-host-GFSDQQUJ.js → multi-session-host-6MKBBOKF.js} +1 -1
  41. package/dist/bundle/chunks/{openai-codex-responses-IQ35QACK.js → openai-codex-responses-CK7T4WNM.js} +1 -1
  42. package/dist/bundle/chunks/{openai-completions-74OLE55U.js → openai-completions-OPQKN7FH.js} +3 -3
  43. package/dist/bundle/chunks/openai-responses-QHWM3KPO.js +2 -0
  44. package/dist/bundle/chunks/{openrouter-images-T4GY3JYM.js → openrouter-images-MW5TXV7L.js} +1 -1
  45. package/dist/bundle/chunks/{package-manager-cli-J7244EJE.js → package-manager-cli-BMEWLAI2.js} +1 -1
  46. package/dist/bundle/chunks/{rotation-stream-CZT4TRPD.js → rotation-stream-ZFA6ELXJ.js} +1 -1
  47. package/dist/bundle/chunks/{rpc-mode-75CRTY24.js → rpc-mode-5653CV65.js} +1 -1
  48. package/dist/bundle/chunks/{session-picker-ZIBANFBQ.js → session-picker-PPYK56TA.js} +1 -1
  49. package/dist/bundle/chunks/session-worker.js +265 -259
  50. package/dist/bundle/cli.js +1 -1
  51. package/dist/bundle/index.js +1 -1
  52. package/dist/bundle/rpc-entry.js +1 -1
  53. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  54. package/dist/core/agent-session-runtime.js +13 -0
  55. package/dist/core/agent-session-runtime.js.map +1 -1
  56. package/dist/core/agent-session.d.ts +28 -0
  57. package/dist/core/agent-session.d.ts.map +1 -1
  58. package/dist/core/agent-session.js +75 -12
  59. package/dist/core/agent-session.js.map +1 -1
  60. package/dist/core/dynamic-prompt/build.d.ts +6 -1
  61. package/dist/core/dynamic-prompt/build.d.ts.map +1 -1
  62. package/dist/core/dynamic-prompt/build.js +0 -7
  63. package/dist/core/dynamic-prompt/build.js.map +1 -1
  64. package/dist/core/environment-context.d.ts +32 -0
  65. package/dist/core/environment-context.d.ts.map +1 -0
  66. package/dist/core/environment-context.js +63 -0
  67. package/dist/core/environment-context.js.map +1 -0
  68. package/dist/core/extensions/builtin/anthropic-subscription/session-sync.d.ts.map +1 -1
  69. package/dist/core/extensions/builtin/anthropic-subscription/session-sync.js +1 -15
  70. package/dist/core/extensions/builtin/anthropic-subscription/session-sync.js.map +1 -1
  71. package/dist/core/extensions/builtin/goal/cache-warm-renderer.js +3 -0
  72. package/dist/core/extensions/builtin/goal/cache-warm-renderer.js.map +1 -1
  73. package/dist/core/extensions/builtin/goal/cache-warm.d.ts +19 -2
  74. package/dist/core/extensions/builtin/goal/cache-warm.d.ts.map +1 -1
  75. package/dist/core/extensions/builtin/goal/cache-warm.js +28 -2
  76. package/dist/core/extensions/builtin/goal/cache-warm.js.map +1 -1
  77. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
  78. package/dist/core/extensions/builtin/goal/monitor-continuation.js +4 -2
  79. package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
  80. package/dist/core/extensions/builtin/goal/parked-wait.js +2 -0
  81. package/dist/core/extensions/builtin/goal/parked-wait.js.map +1 -1
  82. package/dist/core/extensions/builtin/goal/prompt.js +1 -1
  83. package/dist/core/extensions/builtin/goal/prompt.js.map +1 -1
  84. package/dist/core/extensions/builtin/herdr/herdr-state.d.ts +5 -0
  85. package/dist/core/extensions/builtin/herdr/herdr-state.d.ts.map +1 -1
  86. package/dist/core/extensions/builtin/herdr/herdr-state.js +28 -3
  87. package/dist/core/extensions/builtin/herdr/herdr-state.js.map +1 -1
  88. package/dist/core/extensions/builtin/herdr/index.d.ts.map +1 -1
  89. package/dist/core/extensions/builtin/herdr/index.js +7 -1
  90. package/dist/core/extensions/builtin/herdr/index.js.map +1 -1
  91. package/dist/core/extensions/builtin/hooks/index.d.ts.map +1 -1
  92. package/dist/core/extensions/builtin/hooks/index.js +3 -15
  93. package/dist/core/extensions/builtin/hooks/index.js.map +1 -1
  94. package/dist/core/extensions/builtin/hooks/stop-lifecycle.d.ts +26 -0
  95. package/dist/core/extensions/builtin/hooks/stop-lifecycle.d.ts.map +1 -0
  96. package/dist/core/extensions/builtin/hooks/stop-lifecycle.js +88 -0
  97. package/dist/core/extensions/builtin/hooks/stop-lifecycle.js.map +1 -0
  98. package/dist/core/extensions/builtin/recommended-models/index.d.ts +1 -1
  99. package/dist/core/extensions/builtin/recommended-models/index.d.ts.map +1 -1
  100. package/dist/core/extensions/builtin/recommended-models/index.js +28 -10
  101. package/dist/core/extensions/builtin/recommended-models/index.js.map +1 -1
  102. package/dist/core/extensions/builtin/rules/commands.d.ts.map +1 -1
  103. package/dist/core/extensions/builtin/rules/commands.js +5 -1
  104. package/dist/core/extensions/builtin/rules/commands.js.map +1 -1
  105. package/dist/core/extensions/builtin/rules/index.d.ts.map +1 -1
  106. package/dist/core/extensions/builtin/rules/index.js +25 -3
  107. package/dist/core/extensions/builtin/rules/index.js.map +1 -1
  108. package/dist/core/extensions/builtin/rules/rules/constants.d.ts.map +1 -1
  109. package/dist/core/extensions/builtin/rules/rules/constants.js +22 -14
  110. package/dist/core/extensions/builtin/rules/rules/constants.js.map +1 -1
  111. package/dist/core/extensions/builtin/rules/rules/engine.d.ts.map +1 -1
  112. package/dist/core/extensions/builtin/rules/rules/engine.js +39 -9
  113. package/dist/core/extensions/builtin/rules/rules/engine.js.map +1 -1
  114. package/dist/core/extensions/builtin/rules/rules/finder.js +3 -0
  115. package/dist/core/extensions/builtin/rules/rules/finder.js.map +1 -1
  116. package/dist/core/extensions/builtin/rules/rules/project-root.d.ts +17 -0
  117. package/dist/core/extensions/builtin/rules/rules/project-root.d.ts.map +1 -1
  118. package/dist/core/extensions/builtin/rules/rules/project-root.js +67 -5
  119. package/dist/core/extensions/builtin/rules/rules/project-root.js.map +1 -1
  120. package/dist/core/extensions/builtin/rules/rules/types.d.ts +2 -2
  121. package/dist/core/extensions/builtin/rules/rules/types.d.ts.map +1 -1
  122. package/dist/core/extensions/builtin/rules/rules/types.js.map +1 -1
  123. package/dist/core/extensions/builtin/rules/ui/rules-banner.d.ts +3 -1
  124. package/dist/core/extensions/builtin/rules/ui/rules-banner.d.ts.map +1 -1
  125. package/dist/core/extensions/builtin/rules/ui/rules-banner.js +1 -1
  126. package/dist/core/extensions/builtin/rules/ui/rules-banner.js.map +1 -1
  127. package/dist/core/extensions/builtin/todotools/todo-storage.d.ts.map +1 -1
  128. package/dist/core/extensions/builtin/todotools/todo-storage.js +10 -2
  129. package/dist/core/extensions/builtin/todotools/todo-storage.js.map +1 -1
  130. package/dist/core/extensions/builtin/todotools/tools/todo.d.ts.map +1 -1
  131. package/dist/core/extensions/builtin/todotools/tools/todo.js +2 -1
  132. package/dist/core/extensions/builtin/todotools/tools/todo.js.map +1 -1
  133. package/dist/core/extensions/builtin/websearch/websearch/config.d.ts.map +1 -1
  134. package/dist/core/extensions/builtin/websearch/websearch/config.js +2 -0
  135. package/dist/core/extensions/builtin/websearch/websearch/config.js.map +1 -1
  136. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.d.ts.map +1 -1
  137. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.js +2 -0
  138. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.js.map +1 -1
  139. package/dist/core/extensions/builtin/websearch/websearch/providers/kagi.d.ts +3 -0
  140. package/dist/core/extensions/builtin/websearch/websearch/providers/kagi.d.ts.map +1 -0
  141. package/dist/core/extensions/builtin/websearch/websearch/providers/kagi.js +34 -0
  142. package/dist/core/extensions/builtin/websearch/websearch/providers/kagi.js.map +1 -0
  143. package/dist/core/extensions/builtin/websearch/websearch/providers/serpdive.d.ts +3 -0
  144. package/dist/core/extensions/builtin/websearch/websearch/providers/serpdive.d.ts.map +1 -0
  145. package/dist/core/extensions/builtin/websearch/websearch/providers/serpdive.js +22 -0
  146. package/dist/core/extensions/builtin/websearch/websearch/providers/serpdive.js.map +1 -0
  147. package/dist/core/extensions/builtin/websearch/websearch/providers.d.ts.map +1 -1
  148. package/dist/core/extensions/builtin/websearch/websearch/providers.js +4 -0
  149. package/dist/core/extensions/builtin/websearch/websearch/providers.js.map +1 -1
  150. package/dist/core/extensions/builtin/websearch/websearch/types.d.ts +1 -1
  151. package/dist/core/extensions/builtin/websearch/websearch/types.d.ts.map +1 -1
  152. package/dist/core/extensions/builtin/websearch/websearch/types.js.map +1 -1
  153. package/dist/core/session-discovery.d.ts +9 -3
  154. package/dist/core/session-discovery.d.ts.map +1 -1
  155. package/dist/core/session-discovery.js +19 -8
  156. package/dist/core/session-discovery.js.map +1 -1
  157. package/dist/core/session-manager.d.ts.map +1 -1
  158. package/dist/core/session-manager.js +8 -4
  159. package/dist/core/session-manager.js.map +1 -1
  160. package/dist/core/session-summary-cache.d.ts +16 -3
  161. package/dist/core/session-summary-cache.d.ts.map +1 -1
  162. package/dist/core/session-summary-cache.js +19 -3
  163. package/dist/core/session-summary-cache.js.map +1 -1
  164. package/dist/core/session-summary-index-file.d.ts +38 -0
  165. package/dist/core/session-summary-index-file.d.ts.map +1 -0
  166. package/dist/core/session-summary-index-file.js +119 -0
  167. package/dist/core/session-summary-index-file.js.map +1 -0
  168. package/dist/core/session-summary-index.d.ts +52 -0
  169. package/dist/core/session-summary-index.d.ts.map +1 -0
  170. package/dist/core/session-summary-index.js +157 -0
  171. package/dist/core/session-summary-index.js.map +1 -0
  172. package/dist/core/session-summary.d.ts +21 -2
  173. package/dist/core/session-summary.d.ts.map +1 -1
  174. package/dist/core/session-summary.js +53 -14
  175. package/dist/core/session-summary.js.map +1 -1
  176. package/dist/core/timings.d.ts +1 -1
  177. package/dist/core/timings.d.ts.map +1 -1
  178. package/dist/core/timings.js.map +1 -1
  179. package/dist/core/tools/renderers/read.d.ts.map +1 -1
  180. package/dist/core/tools/renderers/read.js +7 -2
  181. package/dist/core/tools/renderers/read.js.map +1 -1
  182. package/dist/core/tools/renderers/skill-read-path.d.ts +9 -0
  183. package/dist/core/tools/renderers/skill-read-path.d.ts.map +1 -0
  184. package/dist/core/tools/renderers/skill-read-path.js +49 -0
  185. package/dist/core/tools/renderers/skill-read-path.js.map +1 -0
  186. package/dist/main.d.ts.map +1 -1
  187. package/dist/main.js +7 -0
  188. package/dist/main.js.map +1 -1
  189. package/dist/modes/interactive/components/exploration-call.d.ts +1 -1
  190. package/dist/modes/interactive/components/exploration-call.d.ts.map +1 -1
  191. package/dist/modes/interactive/components/exploration-call.js +3 -1
  192. package/dist/modes/interactive/components/exploration-call.js.map +1 -1
  193. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  194. package/dist/modes/interactive/components/session-selector-search.js +32 -16
  195. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  196. package/dist/modes/interactive/components/session-selector-tree.d.ts +32 -0
  197. package/dist/modes/interactive/components/session-selector-tree.d.ts.map +1 -0
  198. package/dist/modes/interactive/components/session-selector-tree.js +82 -0
  199. package/dist/modes/interactive/components/session-selector-tree.js.map +1 -0
  200. package/dist/modes/interactive/components/session-selector.d.ts +1 -0
  201. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  202. package/dist/modes/interactive/components/session-selector.js +6 -71
  203. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  204. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  205. package/dist/modes/interactive/interactive-mode.js +4 -1
  206. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  207. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +32 -0
  208. package/node_modules/@code-yeongyu/senpi-codemode/README.md +8 -4
  209. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  210. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/AGENTS.md +1 -0
  211. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/code-preview.ts +31 -0
  212. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-code.ts +34 -131
  213. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-js-ast.ts +65 -0
  214. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-js-layout.ts +90 -0
  215. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-js-mask.ts +178 -0
  216. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-js.ts +100 -0
  217. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-python-script.ts +127 -0
  218. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-python.ts +150 -0
  219. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-request.ts +18 -4
  220. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +1 -1
  221. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +9 -25
  222. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +16 -9
  223. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts +1 -1
  224. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  225. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +22 -2
  226. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  227. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
  228. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +3 -1
  229. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
  230. package/node_modules/@earendil-works/pi-agent-core/dist/tool-name-alias.d.ts +6 -0
  231. package/node_modules/@earendil-works/pi-agent-core/dist/tool-name-alias.d.ts.map +1 -1
  232. package/node_modules/@earendil-works/pi-agent-core/dist/tool-name-alias.js +6 -19
  233. package/node_modules/@earendil-works/pi-agent-core/dist/tool-name-alias.js.map +1 -1
  234. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +8 -0
  235. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
  236. package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
  237. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  238. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.d.ts.map +1 -1
  239. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.js +8 -35
  240. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.js.map +1 -1
  241. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  242. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +10 -6
  243. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  244. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
  245. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +4 -3
  246. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
  247. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
  248. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +53 -1
  249. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  250. package/node_modules/@earendil-works/pi-ai/dist/api/openrouter-images.js +1 -1
  251. package/node_modules/@earendil-works/pi-ai/dist/api/openrouter-images.js.map +1 -1
  252. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +30 -0
  253. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  254. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +30 -0
  255. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  256. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +2 -1
  257. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
  258. package/node_modules/@earendil-works/pi-ai/dist/index.js +2 -1
  259. package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
  260. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts +6 -0
  261. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  262. package/node_modules/@earendil-works/pi-ai/dist/models.js +15 -0
  263. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  264. package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.d.ts +17 -0
  265. package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.d.ts.map +1 -1
  266. package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.js +4 -1
  267. package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.js.map +1 -1
  268. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  269. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  270. package/node_modules/@earendil-works/pi-ai/dist/providers/data/chatgpt-subscription.json +1 -1
  271. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  272. package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
  273. package/node_modules/@earendil-works/pi-ai/dist/providers/data/google.json +1 -1
  274. package/node_modules/@earendil-works/pi-ai/dist/providers/data/minimax-cn.json +1 -1
  275. package/node_modules/@earendil-works/pi-ai/dist/providers/data/minimax.json +1 -1
  276. package/node_modules/@earendil-works/pi-ai/dist/providers/data/moonshotai-cn.json +1 -1
  277. package/node_modules/@earendil-works/pi-ai/dist/providers/data/moonshotai.json +1 -1
  278. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai.json +1 -1
  279. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  280. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  281. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.json +1 -1
  282. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  283. package/node_modules/@earendil-works/pi-ai/dist/providers/data/together.json +1 -1
  284. package/node_modules/@earendil-works/pi-ai/dist/providers/data/venice.json +1 -1
  285. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  286. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +6 -0
  287. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  288. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  289. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.d.ts +30 -0
  290. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.d.ts.map +1 -1
  291. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.js +71 -14
  292. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.js.map +1 -1
  293. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-name-match.d.ts +30 -0
  294. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-name-match.d.ts.map +1 -0
  295. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-name-match.js +71 -0
  296. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-name-match.js.map +1 -0
  297. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  298. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  299. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  300. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts +5 -0
  301. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts.map +1 -1
  302. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js +7 -2
  303. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js.map +1 -1
  304. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +1 -1
  305. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  306. package/node_modules/@earendil-works/pi-tui/dist/index.js +1 -1
  307. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  308. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  309. package/package.json +7 -7
  310. package/dist/bundle/chunks/chunk-KLDLZHHS.js +0 -11
  311. package/dist/bundle/chunks/chunk-LTIMMSDM.js +0 -8
  312. package/dist/bundle/chunks/chunk-XYM54ZWK.js +0 -2
  313. package/dist/bundle/chunks/cli-main-W55CWPEI.js +0 -3
  314. package/dist/bundle/chunks/interactive-mode-EDJZ4CSY.js +0 -2
  315. package/dist/bundle/chunks/openai-responses-7IGZSW33.js +0 -2
@@ -1,5 +1,5 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{readSocketSecret,resolveSocketTransportAddress,sendSocketHandshake,socketSecretPath}from"./chunk-7PANH3NB.js";import{attachJsonlLineReader,serializeJsonLine}from"./chunk-NNHFMZD5.js";import{sanitizeBinaryOutput}from"./chunk-FHXKBENX.js";import{dropFailedAssistantTurns}from"./chunk-3RN6BFG2.js";import{copyContextProvenance}from"./chunk-KLDLZHHS.js";import{APP_NAME,getAgentDir,getSessionsDir,normalizePath,resolvePath}from"./chunk-Y65WFI5H.js";import{normalizeProviderId}from"./chunk-IVYZMSFY.js";var COMPACTION_SUMMARY_PREFIX=`The conversation history before this point was compacted into the following summary:
2
+ import{readSocketSecret,resolveSocketTransportAddress,sendSocketHandshake,socketSecretPath}from"./chunk-3WBSBDBX.js";import{attachJsonlLineReader,serializeJsonLine}from"./chunk-UBPMXBOJ.js";import{sanitizeBinaryOutput}from"./chunk-FHXKBENX.js";import{dropFailedAssistantTurns}from"./chunk-YBC274GY.js";import{copyContextProvenance}from"./chunk-MO2U7YRX.js";import{APP_NAME,getAgentDir,getSessionsDir,normalizePath,resolvePath}from"./chunk-Y65WFI5H.js";import{normalizeProviderId}from"./chunk-WL5EQYNL.js";var COMPACTION_SUMMARY_PREFIX=`The conversation history before this point was compacted into the following summary:
3
3
 
4
4
  <summary>
5
5
  `,COMPACTION_SUMMARY_SUFFIX=`
@@ -15,23 +15,29 @@ ${msg.output}
15
15
 
16
16
  Command exited with code ${msg.exitCode}`),msg.truncated&&msg.fullOutputPath&&(text+=`
17
17
 
18
- [Output truncated. Full output: ${msg.fullOutputPath}]`),text}function createBranchSummaryMessage(summary,fromId,timestamp){return{role:"branchSummary",summary,fromId,timestamp:new Date(timestamp).getTime()}}function createCompactionSummaryMessage(summary,tokensBefore,timestamp,details){return{role:"compactionSummary",summary,tokensBefore,details,timestamp:new Date(timestamp).getTime()}}function createCustomMessage(customType,content,display,details,timestamp){return{role:"custom",customType,content,display,details,timestamp:new Date(timestamp).getTime()}}function convertToLlm(messages){let withContextProvenance=(source,target)=>copyContextProvenance(source,target),converted=messages.map(m=>{switch(m.role){case"bashExecution":return m.excludeFromContext?void 0:withContextProvenance(m,{role:"user",content:[{type:"text",text:bashExecutionToText(m)}],timestamp:m.timestamp});case"custom":{if(isContextExcludedCustomMessage(m.customType))return;let content=typeof m.content=="string"?[{type:"text",text:m.content}]:m.content;return withContextProvenance(m,{role:"user",content,timestamp:m.timestamp})}case"branchSummary":return withContextProvenance(m,{role:"user",content:[{type:"text",text:BRANCH_SUMMARY_PREFIX+m.summary+BRANCH_SUMMARY_SUFFIX}],timestamp:m.timestamp});case"compactionSummary":return withContextProvenance(m,{role:"user",content:[{type:"text",text:COMPACTION_SUMMARY_PREFIX+m.summary+COMPACTION_SUMMARY_SUFFIX}],timestamp:m.timestamp});case"configurationUpdate":return m;case"user":case"assistant":case"toolResult":return m;default:let _exhaustiveCheck=m;return}}).filter(m=>m!==void 0);return dropFailedAssistantTurns(converted)}var TRANSPORT_IMAGE_BUDGET_BYTES=24*1024*1024,IMAGE_ELISION_PLACEHOLDER="[Image elided: an older image was removed to keep the request within the provider's size limit. Re-read the source file if you need to view it again.]",BLOCKED_IMAGE_PLACEHOLDER="Image reading is disabled.";function dedupeConsecutivePlaceholder(content,placeholder){return content.filter((block,index,blocks)=>!(block.type==="text"&&block.text===placeholder&&index>0&&blocks[index-1].type==="text"&&blocks[index-1].text===placeholder))}function elideOldImages(messages,options){let budgetBytes=options?.budgetBytes??TRANSPORT_IMAGE_BUDGET_BYTES,alwaysKeepNewest=options?.alwaysKeepNewest??1,maxHistoricalImages=options?.maxHistoricalImages,limitHistory=maxHistoricalImages!==void 0,lastAssistantIndex=messages.findLastIndex(message=>message.role==="assistant"),imagesToElide=new Set,keptImages=0,keptHistoricalImages=0,imageBytes=0,cutoffReached=!1;for(let messageIndex=messages.length-1;messageIndex>=0;messageIndex--){let message=messages[messageIndex];if(!(message.role!=="user"&&message.role!=="toolResult"||!Array.isArray(message.content)))for(let blockIndex=message.content.length-1;blockIndex>=0;blockIndex--){let block=message.content[blockIndex];if(block.type!=="image")continue;let isCurrentTurn=limitHistory&&messageIndex>lastAssistantIndex,isProtectedHistory=limitHistory&&!isCurrentTurn&&keptHistoricalImages<maxHistoricalImages;if(limitHistory&&!isCurrentTurn&&!isProtectedHistory||cutoffReached&&!isCurrentTurn&&!isProtectedHistory){imagesToElide.add(`${messageIndex}:${blockIndex}`);continue}if(isCurrentTurn||isProtectedHistory||keptImages<alwaysKeepNewest||imageBytes+block.data.length<=budgetBytes){keptImages++,isCurrentTurn||keptHistoricalImages++,imageBytes+=block.data.length;continue}cutoffReached=!0,imagesToElide.add(`${messageIndex}:${blockIndex}`)}}return imagesToElide.size===0?messages:messages.map((message,messageIndex)=>{if(message.role!=="user"&&message.role!=="toolResult"||!Array.isArray(message.content)||!message.content.some((_block,blockIndex)=>imagesToElide.has(`${messageIndex}:${blockIndex}`)))return message;let replaced=message.content.map((block,blockIndex)=>imagesToElide.has(`${messageIndex}:${blockIndex}`)?{type:"text",text:IMAGE_ELISION_PLACEHOLDER}:block);return{...message,content:dedupeConsecutivePlaceholder(replaced,IMAGE_ELISION_PLACEHOLDER)}})}function convertToLlmForTransport(messages,options){let converted=convertToLlm(messages);return options.blockImages?converted.map(message=>{if(message.role!=="user"&&message.role!=="toolResult"||!Array.isArray(message.content)||!message.content.some(block=>block.type==="image"))return message;let replaced=message.content.map(block=>block.type==="image"?{type:"text",text:BLOCKED_IMAGE_PLACEHOLDER}:block);return{...message,content:dedupeConsecutivePlaceholder(replaced,BLOCKED_IMAGE_PLACEHOLDER)}}):elideOldImages(converted,options)}import{randomBytes,randomUUID}from"crypto";import{appendFileSync,closeSync,existsSync as existsSync3,mkdirSync as mkdirSync2,openSync,readdirSync,readFileSync as readFileSync2,readSync,rmSync as rmSync2,statSync,writeFileSync as writeFileSync2}from"fs";import{readdir as readdir2}from"fs/promises";import{join as join3,resolve as resolve2}from"path";import{StringDecoder}from"string_decoder";import{existsSync}from"fs";import{readdir}from"fs/promises";import{join}from"path";import{stat}from"fs/promises";import{resolve}from"path";import{createReadStream}from"fs";import{createInterface}from"readline";function parseEntryLine(line){if(!line.trim())return null;try{return JSON.parse(line)}catch{return null}}function isMessageWithContent(message){return typeof message=="object"&&message!==null&&typeof message.role=="string"&&"content"in message}function extractTextContent(message){let content=message.content;return typeof content=="string"?content:content.filter(block=>block.type==="text").map(block=>block.text).join(" ")}function visibleMessage(entry){if(entry.type!=="message")return null;let message=entry.message;if(!isMessageWithContent(message)||message.role!=="user"&&message.role!=="assistant")return null;let messageTime=message.timestamp,entryTime=Date.parse(entry.timestamp),time=typeof messageTime=="number"?messageTime:Number.isNaN(entryTime)?void 0:entryTime;return{text:extractTextContent(message),role:message.role,time}}function sessionInfoName(entry){return entry.type!=="session_info"?null:entry.name?.trim()||void 0}function newAccumulator(){return{header:null,name:void 0,firstUserMessage:"",messageCount:0,lastActivityTime:void 0,texts:[]}}function accumulateLine(accumulator,line){let entry=parseEntryLine(line);if(!entry)return!0;if(!accumulator.header)return entry.type!=="session"||typeof entry.id!="string"?!1:(accumulator.header=entry,!0);let infoName=sessionInfoName(entry);if(infoName!==null)return accumulator.name=infoName,!0;if(entry.type!=="message")return!0;accumulator.messageCount++;let visible=visibleMessage(entry);return!visible||(typeof visible.time=="number"&&(accumulator.lastActivityTime=Math.max(accumulator.lastActivityTime??0,visible.time)),!visible.text)||(accumulator.texts.push(visible.text),!accumulator.firstUserMessage&&visible.role==="user"&&(accumulator.firstUserMessage=visible.text)),!0}async function readSessionSummary(filePath){let accumulator=newAccumulator(),stream=createReadStream(filePath,{encoding:"utf8"}),lines=createInterface({input:stream,crlfDelay:Number.POSITIVE_INFINITY});try{for await(let line of lines)if(!accumulateLine(accumulator,line))return null}catch(error){if(error instanceof Error)return null;throw error}finally{lines.close(),stream.destroy()}let header=accumulator.header;return header?{header,name:accumulator.name,firstUserMessage:accumulator.firstUserMessage,messageCount:accumulator.messageCount,lastActivityTime:accumulator.lastActivityTime,allMessagesText:accumulator.texts.join(" ")}:null}var SessionSummaryLru=class{constructor(budget){this.entries=new Map,this.retainedTextBytes=0,this.budget=budget}get size(){return this.entries.size}get textBytes(){return this.retainedTextBytes}get(key){let retained=this.entries.get(key);if(retained)return this.entries.delete(key),this.entries.set(key,retained),retained.entry}drop(key){let retained=this.entries.get(key);retained&&(this.entries.delete(key),this.retainedTextBytes-=retained.textBytes)}retain(key,entry){this.drop(key);let textBytes=Buffer.byteLength(entry.summary.allMessagesText,"utf8");textBytes>this.budget.maxTextBytes||(this.entries.set(key,{entry,textBytes}),this.retainedTextBytes+=textBytes,this.evictUntilWithinBudget())}clear(){this.entries.clear(),this.retainedTextBytes=0}evictUntilWithinBudget(){for(;this.entries.size>this.budget.maxEntries||this.retainedTextBytes>this.budget.maxTextBytes;){let oldest=this.entries.keys().next();if(oldest.done)break;this.drop(oldest.value)}}};var SESSION_SUMMARY_CACHE_LIMIT=4096,SESSION_SUMMARY_CACHE_MAX_TEXT_BYTES=64*1024*1024,cache=new SessionSummaryLru({maxEntries:SESSION_SUMMARY_CACHE_LIMIT,maxTextBytes:SESSION_SUMMARY_CACHE_MAX_TEXT_BYTES});function stampsMatch(left,right){return left.size===right.size&&left.mtimeMs===right.mtimeMs}async function readCachedSessionSummary(filePath){let key=resolve(filePath),stamp,mtime;try{let stats=await stat(filePath);stamp={size:stats.size,mtimeMs:stats.mtimeMs},mtime=stats.mtime}catch(error){if(!(error instanceof Error))throw error;return cache.drop(key),null}let cached=cache.get(key);if(cached&&stampsMatch(cached.stamp,stamp))return{summary:cached.summary,mtime:cached.mtime};let summary=await readSessionSummary(filePath);return summary?(cache.retain(key,{stamp,summary,mtime}),{summary,mtime}):(cache.drop(key),null)}var MAX_CONCURRENT_SESSION_INFO_LOADS=10;function resolveModified(activityTime,header,mtime){if(typeof activityTime=="number"&&activityTime>0)return new Date(activityTime);let headerTime=typeof header.timestamp=="string"?Date.parse(header.timestamp):Number.NaN;return Number.isNaN(headerTime)?mtime:new Date(headerTime)}async function buildSessionInfo(filePath){let cached=await readCachedSessionSummary(filePath);if(!cached)return null;let{summary,mtime}=cached,header=summary.header;return{path:filePath,id:header.id,cwd:typeof header.cwd=="string"?header.cwd:"",name:summary.name,parentSessionPath:header.parentSession,created:new Date(header.timestamp),modified:resolveModified(summary.lastActivityTime,header,mtime),messageCount:summary.messageCount,firstMessage:summary.firstUserMessage||"(no messages)",allMessagesText:summary.allMessagesText}}async function buildSessionInfosWithConcurrency(files,onLoaded){let results=new Array(files.length).fill(null),inFlight=new Set,nextIndex=0,startNext=()=>{let index=nextIndex++,file=files[index];if(!file)return;let task;task=buildSessionInfo(file).then(info=>{results[index]=info}).catch(()=>{results[index]=null}).finally(()=>{inFlight.delete(task),onLoaded()}),inFlight.add(task)};for(;nextIndex<files.length||inFlight.size>0;){for(;nextIndex<files.length&&inFlight.size<MAX_CONCURRENT_SESSION_INFO_LOADS;)startNext();inFlight.size>0&&await Promise.race(inFlight)}return results}async function listSessionInfos(files,onLoaded){let results=await buildSessionInfosWithConcurrency(files,onLoaded),sessions=[];for(let info of results)info&&sessions.push(info);return sessions}async function listSessionsFromDir(dir,onProgress,progressOffset=0,progressTotal){if(!existsSync(dir))return[];try{let files=(await readdir(dir)).filter(name=>name.endsWith(".jsonl")).map(name=>join(dir,name)),total=progressTotal??files.length,loaded=0;return await listSessionInfos(files,()=>{loaded++,onProgress?.(progressOffset+loaded,total)})}catch{return[]}}function materializeSessionEntries(entries,options){let{residentStore,loadHistoryEntries,onMaterialized}=options,missingEntryIds=new Set,materialized=entries.map(entry=>residentStore.materialize(entry,()=>{missingEntryIds.add(entry.id)}));if(missingEntryIds.size===0){for(let entry of materialized)onMaterialized(entry);return materialized}let persistedById=new Map(loadHistoryEntries().filter(entry=>entry.type!=="session").map(entry=>[entry.id,entry])),repaired=materialized.map(entry=>{if(!missingEntryIds.has(entry.id))return entry;let persisted=persistedById.get(entry.id);return persisted===void 0?entry:residentStore.materialize(persisted)});for(let entry of repaired)onMaterialized(entry);return repaired}import{createHash}from"node:crypto";import{existsSync as existsSync2,mkdirSync,readFileSync,renameSync,rmSync,writeFileSync}from"node:fs";import{join as join2}from"node:path";import{Buffer as Buffer2}from"buffer";var RESIDENT_STRING_MIN_BYTES=32*1024,DEFAULT_RESIDENT_STRING_BUDGET_BYTES=64*1024*1024,RESIDENT_STRING_PREFIX="\0senpi-resident-string:v1:",OMIT_JSON_VALUE=Symbol("omit-json-value"),ResidentStringStore=class{constructor(options={}){this.strings=new Map,this.bytes=0,this.evictedCount=0,this.evictedBytes=0,this.maxBytes=options.maxBytes??DEFAULT_RESIDENT_STRING_BUDGET_BYTES,this.blobsDir=options.blobsDir}configure(options){this.blobsDir=options.blobsDir}clear(){this.strings.clear(),this.bytes=0,this.evictedCount=0,this.evictedBytes=0;let dir=this.blobsDir?.();if(dir)try{rmSync(dir,{force:!0,recursive:!0})}catch{}}spillResident(){if(this.blobsDir?.())for(let[id,text]of this.strings)this._writeBlob(id,text)&&(this.strings.delete(id),this.bytes-=Buffer2.byteLength(text,"utf8"))}stats(){return{blobCount:this.strings.size,blobBytes:this.bytes,evictedCount:this.evictedCount,evictedBytes:this.evictedBytes}}externalize(value){return transformJson(value,text=>this.externalizeString(text))}materialize(value,onMissing){return transformJson(value,text=>this.materializeString(text,onMissing))}resolvedBlobsDir(){return this.blobsDir?.()}externalizeInPlace(value){this._mutateStringsInPlace(value,new Set,text=>this.externalizeString(text))}materializeInPlace(value){this._mutateStringsInPlace(value,new Set,text=>this.materializeString(text))}_mutateStringsInPlace(value,seen,mutate){if(typeof value!="object"||value===null||seen.has(value))return;seen.add(value);let record=value;for(let key of Object.keys(record)){let current=record[key];typeof current=="string"?record[key]=mutate(current):typeof current=="object"&&current!==null&&this._mutateStringsInPlace(current,seen,mutate)}}externalizeString(text){if(text.length<RESIDENT_STRING_MIN_BYTES||text.startsWith(RESIDENT_STRING_PREFIX))return text;let id=createHash("sha256").update(text,"utf8").digest("hex"),token=`${RESIDENT_STRING_PREFIX}${id}`;return this.strings.has(id)?(this.strings.delete(id),this.strings.set(id,text),token):(this.strings.set(id,text),this.bytes+=Buffer2.byteLength(text,"utf8"),this._enforceBudget(),token)}materializeString(text,onMissing){if(!text.startsWith(RESIDENT_STRING_PREFIX))return text;let id=text.slice(RESIDENT_STRING_PREFIX.length),resident=this.strings.get(id);if(resident!==void 0)return this.strings.delete(id),this.strings.set(id,resident),resident;let hydrated=this._readBlob(id);return hydrated!==void 0?hydrated:onMissing?.(id)??text}_enforceBudget(){for(;this.bytes>this.maxBytes&&this.strings.size>0;){let[oldestId,oldest]=this.strings.entries().next().value;if(!this._writeBlob(oldestId,oldest))return;this.strings.delete(oldestId),this.bytes-=Buffer2.byteLength(oldest,"utf8")}}_writeBlob(id,text){let dir=this.blobsDir?.();if(!dir)return!1;let final=join2(dir,`${id}.blob`),temp=`${final}.tmp`;try{mkdirSync(dir,{recursive:!0}),existsSync2(final)||(writeFileSync(temp,JSON.stringify({v:1,text}),"utf8"),renameSync(temp,final))}catch{try{rmSync(temp,{force:!0})}catch{}return!1}return this.evictedCount++,this.evictedBytes+=Buffer2.byteLength(text,"utf8"),!0}_readBlob(id){let dir=this.blobsDir?.();if(!dir)return;let file=join2(dir,`${id}.blob`);try{let parsed=JSON.parse(readFileSync(file,"utf8"));if(typeof parsed.text=="string")return parsed.text}catch{}try{rmSync(file,{force:!0})}catch{}}};function transformJson(value,transformString){let transformed=transformJsonValue(value,transformString,"",new WeakSet);if(transformed===OMIT_JSON_VALUE){let serialized=JSON.stringify(value);if(serialized===void 0)throw new SyntaxError("JSON-compatible value expected");return JSON.parse(serialized)}return transformed}function transformJsonValue(value,transformString,key,seen){if(typeof value=="string")return transformString(value);if(typeof value=="number")return Number.isFinite(value)?value:null;if(value===null||typeof value=="boolean")return value;if(typeof value=="bigint")throw new TypeError("Do not know how to serialize a BigInt");if(typeof value>"u"||typeof value=="function"||typeof value=="symbol")return OMIT_JSON_VALUE;if(seen.has(value))throw new TypeError("Converting circular structure to JSON");seen.add(value);let jsonValue=hasJsonSerializer(value)?value.toJSON(key):value;if(jsonValue!==value){let transformed2=transformJsonValue(jsonValue,transformString,key,seen);return seen.delete(value),transformed2}if(Array.isArray(value)){let transformed2=Array.from({length:value.length},(_item,index)=>{let item=value[index],transformedItem=transformJsonValue(item,transformString,String(index),seen);return transformedItem===OMIT_JSON_VALUE?null:transformedItem});return seen.delete(value),transformed2}let transformed={};for(let[key2,item]of Object.entries(value)){let transformedItem=transformJsonValue(item,transformString,String(key2),seen);transformedItem!==OMIT_JSON_VALUE&&Object.defineProperty(transformed,key2,{configurable:!0,enumerable:!0,value:transformedItem,writable:!0})}return seen.delete(value),transformed}function hasJsonSerializer(value){return"toJSON"in value&&typeof value.toJSON=="function"}var reserve;function reserveSessionWrite(path){reserve?.(path)}var liveWriters=new Set,writerRefs=new WeakMap;function registerSessionWriter(owner){if(writerRefs.has(owner))return;let ref=new WeakRef(owner);writerRefs.set(owner,ref),liveWriters.add(ref)}function unregisterSessionWriter(owner){let ref=writerRefs.get(owner);ref&&(writerRefs.delete(owner),liveWriters.delete(ref))}function hasOtherLiveSessionWriter(path,self){for(let ref of liveWriters){let owner=ref.deref();if(!owner){liveWriters.delete(ref);continue}if(owner!==self&&owner.isPersisted()&&owner.getSessionFile()===path)return!0}return!1}function uuidv7(){let ts=BigInt(Date.now()),bytes=randomBytes(10),hex=[(ts>>40n&0xffn).toString(16).padStart(2,"0"),(ts>>32n&0xffn).toString(16).padStart(2,"0"),(ts>>24n&0xffn).toString(16).padStart(2,"0"),(ts>>16n&0xffn).toString(16).padStart(2,"0"),(ts>>8n&0xffn).toString(16).padStart(2,"0"),(ts&0xffn).toString(16).padStart(2,"0"),(112|bytes[0]&15).toString(16).padStart(2,"0"),bytes[1].toString(16).padStart(2,"0"),(128|bytes[2]&63).toString(16).padStart(2,"0"),bytes[3].toString(16).padStart(2,"0"),...Array.from(bytes.slice(4),b=>b.toString(16).padStart(2,"0"))].join("");return`${hex.slice(0,8)}-${hex.slice(8,12)}-${hex.slice(12,16)}-${hex.slice(16,20)}-${hex.slice(20,32)}`}var contextMessageEntryIds=new WeakMap,SESSION_CONTEXT_ENTRY_ID="__piSessionContextEntryId";function withContextEntryId(entryId,message){return contextMessageEntryIds.set(message,entryId),message}function getSessionContextEntryId(message){return contextMessageEntryIds.get(message)}var CURRENT_SESSION_VERSION=3;function createSessionId(){return uuidv7()}function assertValidSessionId(id){if(!/^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(id))throw new Error("Session id must be non-empty, contain only alphanumeric characters, '-', '_', and '.', and start and end with an alphanumeric character")}function generateId(byId){for(let i=0;i<100;i++){let id=randomUUID().slice(0,8);if(!byId.has(id))return id}return randomUUID()}function migrateV1ToV2(entries){let ids=new Set,prevId=null;for(let entry of entries){if(entry.type==="session"){entry.version=2;continue}if(entry.id=generateId(ids),entry.parentId=prevId,prevId=entry.id,entry.type==="compaction"){let comp=entry;if(typeof comp.firstKeptEntryIndex=="number"){let targetEntry=entries[comp.firstKeptEntryIndex];targetEntry&&targetEntry.type!=="session"&&(comp.firstKeptEntryId=targetEntry.id),delete comp.firstKeptEntryIndex}}}}function migrateV2ToV3(entries){for(let entry of entries){if(entry.type==="session"){entry.version=3;continue}if(entry.type==="message"){let msgEntry=entry;msgEntry.message&&msgEntry.message.role==="hookMessage"&&(msgEntry.message.role="custom")}}}function migrateToCurrentVersion(entries){let version=entries.find(e=>e.type==="session")?.version??1;return version>=CURRENT_SESSION_VERSION?!1:(version<2&&migrateV1ToV2(entries),version<3&&migrateV2ToV3(entries),!0)}function migrateSessionEntries(entries){migrateToCurrentVersion(entries)}function parseSessionEntries(content){let entries=[],lines=content.trim().split(`
19
- `);for(let line of lines)if(line.trim())try{let entry=JSON.parse(line);entries.push(entry)}catch{}return entries}function getLatestCompactionEntry(entries){for(let i=entries.length-1;i>=0;i--)if(entries[i].type==="compaction")return entries[i];return null}function buildEntryIndex(entries,byId){if(byId)return byId;let index=new Map;for(let entry of entries)index.set(entry.id,entry);return index}function buildSessionPath(entries,leafId,byId){let index=buildEntryIndex(entries,byId),leaf;if(leafId===null)return[];if(leafId&&(leaf=index.get(leafId)),leaf??=entries[entries.length-1],!leaf)return[];let path=[],current=leaf;for(;current;)path.push(current),current=current.parentId?index.get(current.parentId):void 0;return path.reverse(),path}function getSessionContextSettings(path){let thinkingLevel="off",thinkingSelection,configurationUpdate,model=null,isModelSelectionExplicit=!1,isInFallbackWindow=!1,preFallbackThinkingLevel=thinkingLevel,preFallbackThinkingSelection=thinkingSelection;for(let entry of path)if(entry.type==="thinking_level_change")thinkingLevel=entry.thinkingLevel,thinkingSelection=entry.thinkingSelection;else if(entry.type==="configuration_update")configurationUpdate={effort:entry.reasoning.effort};else if(entry.type==="model_change")entry.reason==="fallback"?(isInFallbackWindow||(preFallbackThinkingLevel=thinkingLevel,preFallbackThinkingSelection=thinkingSelection,entry.originalProvider&&entry.originalModelId&&(model={provider:normalizeProviderId(entry.originalProvider),modelId:entry.originalModelId},isModelSelectionExplicit=!0)),isInFallbackWindow=!0):entry.reason==="fallback-revert"?(isInFallbackWindow&&(thinkingLevel=preFallbackThinkingLevel,thinkingSelection=preFallbackThinkingSelection),isInFallbackWindow=!1):(isInFallbackWindow=!1,entry.provider&&entry.modelId&&(model={provider:normalizeProviderId(entry.provider),modelId:entry.modelId},isModelSelectionExplicit=!0));else if(entry.type==="message"&&entry.message.role==="assistant"&&!isInFallbackWindow){if(isModelSelectionExplicit&&model?.provider===normalizeProviderId(entry.message.provider))continue;model={provider:normalizeProviderId(entry.message.provider),modelId:entry.message.model},isModelSelectionExplicit=!1}return isInFallbackWindow&&(thinkingLevel=preFallbackThinkingLevel,thinkingSelection=preFallbackThinkingSelection),{thinkingLevel,thinkingSelection,configurationUpdate,model}}function sessionEntryToContextMessages(entry){if(entry.type==="message"){let message=entry.message;return(message.role==="user"||message.role==="assistant"||message.role==="toolResult")&&message.content==null?[withContextEntryId(entry.id,{...message,content:[]})]:[withContextEntryId(entry.id,message)]}return entry.type==="configuration_update"?[withContextEntryId(entry.id,{role:"configurationUpdate",content:[],effort:entry.reasoning.effort,timestamp:new Date(entry.timestamp).getTime()})]:entry.type==="custom_message"?[withContextEntryId(entry.id,createCustomMessage(entry.customType,entry.content??[],entry.display,entry.details,entry.timestamp))]:entry.type==="branch_summary"&&entry.summary?[withContextEntryId(entry.id,createBranchSummaryMessage(entry.summary,entry.fromId,entry.timestamp))]:entry.type==="compaction"?[withContextEntryId(entry.id,createCompactionSummaryMessage(entry.summary,entry.tokensBefore,entry.timestamp,entry.details))]:[]}function buildContextEntries(entries,leafId,byId){let path=buildSessionPath(entries,leafId,byId),compaction=null;for(let entry of path)entry.type==="compaction"&&(compaction=entry);if(!compaction)return path;let compactionIdx=path.findIndex(entry=>entry.id===compaction.id);if(compactionIdx<0)return path;let contextEntries=[compaction],foundFirstKept=!1;for(let i=0;i<compactionIdx;i++){let entry=path[i];entry.type!=="compaction"&&(entry.id===compaction.firstKeptEntryId&&(foundFirstKept=!0),foundFirstKept&&contextEntries.push(entry))}return contextEntries.push(...path.slice(compactionIdx+1)),contextEntries}function buildSessionContext(entries,leafId,byId){let path=buildSessionPath(entries,leafId,byId),{thinkingLevel,thinkingSelection,model,configurationUpdate}=getSessionContextSettings(path);return{messages:buildContextEntries(entries,leafId,byId).flatMap(sessionEntryToContextMessages),thinkingLevel,thinkingSelection,model,configurationUpdate}}function getDefaultSessionDirPath(cwd,agentDir=getAgentDir()){let resolvedCwd=resolvePath(cwd),resolvedAgentDir=resolvePath(agentDir),safePath=`--${resolvedCwd.replace(/^[/\\]/,"").replace(/[/\\:]/g,"-")}--`;return join3(resolvedAgentDir,"sessions",safePath)}function getDefaultSessionDir(cwd,agentDir=getAgentDir()){let sessionDir=getDefaultSessionDirPath(cwd,agentDir);return existsSync3(sessionDir)||mkdirSync2(sessionDir,{recursive:!0}),sessionDir}var SESSION_READ_BUFFER_SIZE=1024*1024,SESSION_HEADER_READ_BUFFER_SIZE=4096,MAX_SESSION_HEADER_SCAN_BYTES=1024*1024,SessionHeaderScanLimitError=class extends Error{constructor(filePath){super(`Session header exceeds ${MAX_SESSION_HEADER_SCAN_BYTES}-byte scan limit: ${filePath}`),this.name="SessionHeaderScanLimitError"}};function parseSessionEntryLine(line){if(!line.trim())return null;try{return JSON.parse(line)}catch{return null}}function loadEntriesFromFile(filePath){let resolvedFilePath=normalizePath(filePath);if(!existsSync3(resolvedFilePath))return[];let entries=[],pending="",fd=openSync(resolvedFilePath,"r");try{let decoder=new StringDecoder("utf8"),buffer=Buffer.allocUnsafe(SESSION_READ_BUFFER_SIZE);for(;;){let bytesRead=readSync(fd,buffer,0,buffer.length,null);if(bytesRead===0)break;pending+=decoder.write(buffer.subarray(0,bytesRead));let lineStart=0,newlineIndex=pending.indexOf(`
18
+ [Output truncated. Full output: ${msg.fullOutputPath}]`),text}function createBranchSummaryMessage(summary,fromId,timestamp){return{role:"branchSummary",summary,fromId,timestamp:new Date(timestamp).getTime()}}function createCompactionSummaryMessage(summary,tokensBefore,timestamp,details){return{role:"compactionSummary",summary,tokensBefore,details,timestamp:new Date(timestamp).getTime()}}function createCustomMessage(customType,content,display,details,timestamp){return{role:"custom",customType,content,display,details,timestamp:new Date(timestamp).getTime()}}function convertToLlm(messages){let withContextProvenance=(source,target)=>copyContextProvenance(source,target),converted=messages.map(m=>{switch(m.role){case"bashExecution":return m.excludeFromContext?void 0:withContextProvenance(m,{role:"user",content:[{type:"text",text:bashExecutionToText(m)}],timestamp:m.timestamp});case"custom":{if(isContextExcludedCustomMessage(m.customType))return;let content=typeof m.content=="string"?[{type:"text",text:m.content}]:m.content;return withContextProvenance(m,{role:"user",content,timestamp:m.timestamp})}case"branchSummary":return withContextProvenance(m,{role:"user",content:[{type:"text",text:BRANCH_SUMMARY_PREFIX+m.summary+BRANCH_SUMMARY_SUFFIX}],timestamp:m.timestamp});case"compactionSummary":return withContextProvenance(m,{role:"user",content:[{type:"text",text:COMPACTION_SUMMARY_PREFIX+m.summary+COMPACTION_SUMMARY_SUFFIX}],timestamp:m.timestamp});case"configurationUpdate":return m;case"user":case"assistant":case"toolResult":return m;default:let _exhaustiveCheck=m;return}}).filter(m=>m!==void 0);return dropFailedAssistantTurns(converted)}var TRANSPORT_IMAGE_BUDGET_BYTES=24*1024*1024,IMAGE_ELISION_PLACEHOLDER="[Image elided: an older image was removed to keep the request within the provider's size limit. Re-read the source file if you need to view it again.]",BLOCKED_IMAGE_PLACEHOLDER="Image reading is disabled.";function dedupeConsecutivePlaceholder(content,placeholder){return content.filter((block,index,blocks)=>!(block.type==="text"&&block.text===placeholder&&index>0&&blocks[index-1].type==="text"&&blocks[index-1].text===placeholder))}function elideOldImages(messages,options){let budgetBytes=options?.budgetBytes??TRANSPORT_IMAGE_BUDGET_BYTES,alwaysKeepNewest=options?.alwaysKeepNewest??1,maxHistoricalImages=options?.maxHistoricalImages,limitHistory=maxHistoricalImages!==void 0,lastAssistantIndex=messages.findLastIndex(message=>message.role==="assistant"),imagesToElide=new Set,keptImages=0,keptHistoricalImages=0,imageBytes=0,cutoffReached=!1;for(let messageIndex=messages.length-1;messageIndex>=0;messageIndex--){let message=messages[messageIndex];if(!(message.role!=="user"&&message.role!=="toolResult"||!Array.isArray(message.content)))for(let blockIndex=message.content.length-1;blockIndex>=0;blockIndex--){let block=message.content[blockIndex];if(block.type!=="image")continue;let isCurrentTurn=limitHistory&&messageIndex>lastAssistantIndex,isProtectedHistory=limitHistory&&!isCurrentTurn&&keptHistoricalImages<maxHistoricalImages;if(limitHistory&&!isCurrentTurn&&!isProtectedHistory||cutoffReached&&!isCurrentTurn&&!isProtectedHistory){imagesToElide.add(`${messageIndex}:${blockIndex}`);continue}if(isCurrentTurn||isProtectedHistory||keptImages<alwaysKeepNewest||imageBytes+block.data.length<=budgetBytes){keptImages++,isCurrentTurn||keptHistoricalImages++,imageBytes+=block.data.length;continue}cutoffReached=!0,imagesToElide.add(`${messageIndex}:${blockIndex}`)}}return imagesToElide.size===0?messages:messages.map((message,messageIndex)=>{if(message.role!=="user"&&message.role!=="toolResult"||!Array.isArray(message.content)||!message.content.some((_block,blockIndex)=>imagesToElide.has(`${messageIndex}:${blockIndex}`)))return message;let replaced=message.content.map((block,blockIndex)=>imagesToElide.has(`${messageIndex}:${blockIndex}`)?{type:"text",text:IMAGE_ELISION_PLACEHOLDER}:block);return{...message,content:dedupeConsecutivePlaceholder(replaced,IMAGE_ELISION_PLACEHOLDER)}})}function convertToLlmForTransport(messages,options){let converted=convertToLlm(messages);return options.blockImages?converted.map(message=>{if(message.role!=="user"&&message.role!=="toolResult"||!Array.isArray(message.content)||!message.content.some(block=>block.type==="image"))return message;let replaced=message.content.map(block=>block.type==="image"?{type:"text",text:BLOCKED_IMAGE_PLACEHOLDER}:block);return{...message,content:dedupeConsecutivePlaceholder(replaced,BLOCKED_IMAGE_PLACEHOLDER)}}):elideOldImages(converted,options)}import{randomBytes,randomUUID}from"crypto";import{appendFileSync,closeSync,existsSync as existsSync3,mkdirSync as mkdirSync2,openSync,readdirSync,readFileSync as readFileSync2,readSync,rmSync as rmSync2,statSync,writeFileSync as writeFileSync2}from"fs";import{readdir as readdir2}from"fs/promises";import{join as join4,resolve as resolve2}from"path";import{StringDecoder as StringDecoder2}from"string_decoder";import{existsSync}from"fs";import{readdir}from"fs/promises";import{join as join2}from"path";import{stat as stat2}from"fs/promises";import{resolve}from"path";import{open}from"fs/promises";import{StringDecoder}from"string_decoder";function parseEntryLine(line){if(!line.trim())return null;try{return JSON.parse(line)}catch{return null}}function isMessageWithContent(message){return typeof message=="object"&&message!==null&&typeof message.role=="string"&&"content"in message}function extractTextContent(message){let content=message.content;return typeof content=="string"?content:content.filter(block=>block.type==="text").map(block=>block.text).join(" ")}function visibleMessage(entry){if(entry.type!=="message")return null;let message=entry.message;if(!isMessageWithContent(message)||message.role!=="user"&&message.role!=="assistant")return null;let messageTime=message.timestamp,entryTime=Date.parse(entry.timestamp),time=typeof messageTime=="number"?messageTime:Number.isNaN(entryTime)?void 0:entryTime;return{text:extractTextContent(message),role:message.role,time}}function sessionInfoName(entry){return entry.type!=="session_info"?null:entry.name?.trim()||void 0}function newAccumulator(){return{header:null,name:void 0,firstUserMessage:"",messageCount:0,lastActivityTime:void 0,texts:[]}}function accumulateLine(accumulator,line){let entry=parseEntryLine(line);if(!entry)return!0;if(!accumulator.header)return entry.type!=="session"||typeof entry.id!="string"?!1:(accumulator.header=entry,!0);let infoName=sessionInfoName(entry);if(infoName!==null)return accumulator.name=infoName,!0;if(entry.type!=="message")return!0;accumulator.messageCount++;let visible=visibleMessage(entry);return!visible||(typeof visible.time=="number"&&(accumulator.lastActivityTime=Math.max(accumulator.lastActivityTime??0,visible.time)),!visible.text)||(accumulator.texts.push(visible.text),!accumulator.firstUserMessage&&visible.role==="user"&&(accumulator.firstUserMessage=visible.text)),!0}var LINE_READ_BUFFER_SIZE=1024*1024;async function readFileLines(filePath,onLine){let handle=await open(filePath,"r");try{let decoder=new StringDecoder("utf8"),buffer=Buffer.allocUnsafe(LINE_READ_BUFFER_SIZE),pending="",bytes=0,lastByte=-1,emit=line=>onLine(line.endsWith("\r")?line.slice(0,-1):line);for(;;){let{bytesRead}=await handle.read(buffer,0,buffer.length,null);if(bytesRead===0)break;bytes+=bytesRead,lastByte=buffer[bytesRead-1]??-1;let searchFrom=pending.length;pending+=decoder.write(buffer.subarray(0,bytesRead));let lineStart=0,newlineIndex=pending.indexOf(`
19
+ `,searchFrom);for(;newlineIndex!==-1;){if(!emit(pending.slice(lineStart,newlineIndex)))return{completed:!1,bytes,endsWithNewline:!1};lineStart=newlineIndex+1,newlineIndex=pending.indexOf(`
20
+ `,lineStart)}pending=pending.slice(lineStart)}return pending+=decoder.end(),pending&&!emit(pending)?{completed:!1,bytes,endsWithNewline:!1}:{completed:!0,bytes,endsWithNewline:lastByte===10}}finally{await handle.close()}}async function readSessionSummary(filePath){let accumulator=newAccumulator();try{if(!(await readFileLines(filePath,line=>accumulateLine(accumulator,line))).completed)return null}catch(error){if(error instanceof Error)return null;throw error}let header=accumulator.header;return header?{header,name:accumulator.name,firstUserMessage:accumulator.firstUserMessage,messageCount:accumulator.messageCount,lastActivityTime:accumulator.lastActivityTime,allMessagesText:accumulator.texts.join(" ")}:null}import{stat}from"fs/promises";import{basename,join}from"path";import{appendFile,rename,rm,writeFile}from"fs/promises";var SESSION_SUMMARY_INDEX_FILE=".session-summaries.index",INDEX_VERSION=1,HEADER_LINE=`${JSON.stringify({version:INDEX_VERSION})}
21
+ `,UNUSABLE={usable:!1,entries:new Map,entryBytes:0,endsWithNewline:!0};function isObject(value){return typeof value=="object"&&value!==null}function isOptional(value,type){return value===void 0||typeof value===type}function isSessionSummary(value){return!isObject(value)||!isObject(value.header)?!1:value.header.type==="session"&&typeof value.header.id=="string"&&typeof value.firstUserMessage=="string"&&typeof value.messageCount=="number"&&typeof value.allMessagesText=="string"&&isOptional(value.name,"string")&&isOptional(value.lastActivityTime,"number")}function isFiniteNumber(value){return typeof value=="number"&&Number.isFinite(value)}function toIndexEntry(file,stamp,summary){if(!(summary.lastActivityTime!==void 0&&!Number.isFinite(summary.lastActivityTime)))return withLine(file,stamp,summary,`${JSON.stringify({file,size:stamp.size,mtimeMs:stamp.mtimeMs,summary})}
22
+ `)}function withLine(file,stamp,summary,line){return{file,stamp,summary,line,lineBytes:Buffer.byteLength(line,"utf8")}}function parseEntryLine2(line){let parsed;try{parsed=JSON.parse(line)}catch{return}if(!(!isObject(parsed)||typeof parsed.file!="string"||parsed.file.includes("/"))&&!(!isFiniteNumber(parsed.size)||!isFiniteNumber(parsed.mtimeMs)||!isSessionSummary(parsed.summary)))return withLine(parsed.file,{size:parsed.size,mtimeMs:parsed.mtimeMs},parsed.summary,`${line}
23
+ `)}function isCurrentHeader(line){try{let parsed=JSON.parse(line);return isObject(parsed)&&parsed.version===INDEX_VERSION}catch{return!1}}async function loadIndexFile(path){let entries=new Map,headerSeen=!1,headerBytes=0;try{let read=await readFileLines(path,line=>{if(!headerSeen)return headerSeen=!0,headerBytes=Buffer.byteLength(line,"utf8")+1,isCurrentHeader(line);let entry=parseEntryLine2(line);return entry&&entries.set(entry.file,entry),!0});return!read.completed||!headerSeen?UNUSABLE:{usable:!0,entries,entryBytes:Math.max(0,read.bytes-headerBytes),endsWithNewline:read.endsWithNewline}}catch(error){if(error instanceof Error)return UNUSABLE;throw error}}async function appendIndexEntries(path,entries,endsWithNewline){let prefix=endsWithNewline?"":`
24
+ `;for(let entry of entries)await appendFile(path,prefix+entry.line),prefix=""}async function rewriteIndexFile(path,entries){let temp=`${path}.tmp-${process.pid}-${Math.random().toString(36).slice(2)}`;try{await writeFile(temp,HEADER_LINE+entries.map(entry=>entry.line).join("")),await rename(temp,path)}catch(error){throw await rm(temp,{force:!0}).catch(()=>{}),error}}var SESSION_SUMMARY_INDEX_MAX_BYTES=256*1024*1024,snapshots=new Map;function stampsMatch(left,right){return left.size===right.size&&left.mtimeMs===right.mtimeMs}async function statStamp(path){try{let stats=await stat(path);return{size:stats.size,mtimeMs:stats.mtimeMs}}catch(error){if(error instanceof Error)return;throw error}}function recency(entry){let headerTime=Date.parse(entry.summary.header.timestamp);return entry.summary.lastActivityTime??(Number.isNaN(headerTime)?0:headerTime)}function selectWithinBudget(entries,maxBytes){let kept=[],bytes=0;for(let entry of[...entries].sort((left,right)=>recency(right)-recency(left)))if(!(entry.lineBytes>maxBytes)){if(bytes+entry.lineBytes>maxBytes)break;kept.push(entry),bytes+=entry.lineBytes}return kept}var SessionSummaryIndex=class{constructor(dir,options={}){this.recorded=[],this.path=join(dir,SESSION_SUMMARY_INDEX_FILE),this.maxBytes=options.maxBytes??SESSION_SUMMARY_INDEX_MAX_BYTES}async lookup(filePath,stamp){let file=basename(filePath);if(!this.loading){this.snapshot??=this.currentSnapshot();let known=await this.snapshot,indexed=known?.entryStamps.get(file);if(known&&!(indexed&&stampsMatch(indexed,stamp)))return}this.loading??=this.load();let entry=(await this.loading).entries.get(file);return entry&&stampsMatch(entry.stamp,stamp)?entry.summary:void 0}record(filePath,stamp,summary){this.recorded.push({file:basename(filePath),stamp,summary})}async persist(presentFiles){if(!this.loading)return;let loaded=await this.loading,entries=new Map(loaded.entries),added=new Set;for(let{file,stamp,summary}of this.recorded){let existing=entries.get(file);if(existing&&stampsMatch(existing.stamp,stamp))continue;let entry=toIndexEntry(file,stamp,summary);entry&&(entries.set(file,entry),added.add(entry))}let present=new Set(presentFiles.map(path=>basename(path))),live=[...entries.values()].filter(entry=>present.has(entry.file)),kept=selectWithinBudget(live,this.maxBytes),keptBytes=kept.reduce((total,entry)=>total+entry.lineBytes,0),appended=kept.filter(entry=>added.has(entry)),appendedBytes=appended.reduce((total,entry)=>total+entry.lineBytes,0);try{if(!loaded.usable&&kept.length>0||loaded.usable&&loaded.entryBytes+appendedBytes>2*keptBytes)await rewriteIndexFile(this.path,kept),this.remember(await statStamp(this.path),kept);else if(loaded.usable&&appended.length>0){await appendIndexEntries(this.path,appended,loaded.endsWithNewline);let inFile=new Map(loaded.entries);for(let entry of appended)inFile.set(entry.file,entry);this.remember(await statStamp(this.path),inFile.values())}}catch(error){if(!(error instanceof Error))throw error;snapshots.delete(this.path)}}async currentSnapshot(){let recorded=snapshots.get(this.path);if(!recorded)return;let current=await statStamp(this.path);return current&&stampsMatch(current,recorded.indexStamp)?recorded:void 0}async load(){let before=await statStamp(this.path),loaded=await loadIndexFile(this.path);return this.remember(before,loaded.usable?loaded.entries.values():void 0),loaded}remember(indexStamp,entries){if(!indexStamp||!entries){snapshots.delete(this.path);return}let entryStamps=new Map;for(let entry of entries)entryStamps.set(entry.file,entry.stamp);snapshots.set(this.path,{indexStamp,entryStamps})}};var SessionSummaryLru=class{constructor(budget){this.entries=new Map,this.retainedTextBytes=0,this.budget=budget}get size(){return this.entries.size}get textBytes(){return this.retainedTextBytes}get(key){let retained=this.entries.get(key);if(retained)return this.entries.delete(key),this.entries.set(key,retained),retained.entry}drop(key){let retained=this.entries.get(key);retained&&(this.entries.delete(key),this.retainedTextBytes-=retained.textBytes)}retain(key,entry){this.drop(key);let textBytes=Buffer.byteLength(entry.summary.allMessagesText,"utf8");textBytes>this.budget.maxTextBytes||(this.entries.set(key,{entry,textBytes}),this.retainedTextBytes+=textBytes,this.evictUntilWithinBudget())}clear(){this.entries.clear(),this.retainedTextBytes=0}evictUntilWithinBudget(){for(;this.entries.size>this.budget.maxEntries||this.retainedTextBytes>this.budget.maxTextBytes;){let oldest=this.entries.keys().next();if(oldest.done)break;this.drop(oldest.value)}}};var SESSION_SUMMARY_CACHE_LIMIT=4096,SESSION_SUMMARY_CACHE_MAX_TEXT_BYTES=64*1024*1024,cache=new SessionSummaryLru({maxEntries:SESSION_SUMMARY_CACHE_LIMIT,maxTextBytes:SESSION_SUMMARY_CACHE_MAX_TEXT_BYTES}),streamedSummaries=0;function stampsMatch2(left,right){return left.size===right.size&&left.mtimeMs===right.mtimeMs}async function readCachedSessionSummary(filePath,store){let key=resolve(filePath),stamp,mtime;try{let stats=await stat2(filePath);stamp={size:stats.size,mtimeMs:stats.mtimeMs},mtime=stats.mtime}catch(error){if(!(error instanceof Error))throw error;return cache.drop(key),null}let cached=cache.get(key);if(cached&&stampsMatch2(cached.stamp,stamp))return store?.record(filePath,stamp,cached.summary),{summary:cached.summary,mtime:cached.mtime};let stored=await store?.lookup(filePath,stamp);if(stored)return cache.retain(key,{stamp,summary:stored,mtime}),{summary:stored,mtime};streamedSummaries++;let summary=await readSessionSummary(filePath);return summary?(cache.retain(key,{stamp,summary,mtime}),store?.record(filePath,stamp,summary),{summary,mtime}):(cache.drop(key),null)}var MAX_CONCURRENT_SESSION_INFO_LOADS=10;function resolveModified(activityTime,header,mtime){if(typeof activityTime=="number"&&activityTime>0)return new Date(activityTime);let headerTime=typeof header.timestamp=="string"?Date.parse(header.timestamp):Number.NaN;return Number.isNaN(headerTime)?mtime:new Date(headerTime)}async function buildSessionInfo(filePath,store){let cached=await readCachedSessionSummary(filePath,store);if(!cached)return null;let{summary,mtime}=cached,header=summary.header;return{path:filePath,id:header.id,cwd:typeof header.cwd=="string"?header.cwd:"",name:summary.name,parentSessionPath:header.parentSession,created:new Date(header.timestamp),modified:resolveModified(summary.lastActivityTime,header,mtime),messageCount:summary.messageCount,firstMessage:summary.firstUserMessage||"(no messages)",allMessagesText:summary.allMessagesText}}async function buildSessionInfosWithConcurrency(files,onLoaded,store){let results=new Array(files.length).fill(null),inFlight=new Set,nextIndex=0,startNext=()=>{let index=nextIndex++,file=files[index];if(!file)return;let task;task=buildSessionInfo(file,store).then(info=>{results[index]=info}).catch(()=>{results[index]=null}).finally(()=>{inFlight.delete(task),onLoaded()}),inFlight.add(task)};for(;nextIndex<files.length||inFlight.size>0;){for(;nextIndex<files.length&&inFlight.size<MAX_CONCURRENT_SESSION_INFO_LOADS;)startNext();inFlight.size>0&&await Promise.race(inFlight)}return results}async function listSessionInfos(files,onLoaded,store){let results=await buildSessionInfosWithConcurrency(files,onLoaded,store),sessions=[];for(let info of results)info&&sessions.push(info);return sessions}async function listSessionFilesInDir(dir,files,onLoaded){let index=new SessionSummaryIndex(dir),sessions=await listSessionInfos(files,onLoaded,index);return await index.persist(files),sessions}async function listSessionsFromDir(dir,onProgress,progressOffset=0,progressTotal){if(!existsSync(dir))return[];try{let files=(await readdir(dir)).filter(name=>name.endsWith(".jsonl")).map(name=>join2(dir,name)),total=progressTotal??files.length,loaded=0;return await listSessionFilesInDir(dir,files,()=>{loaded++,onProgress?.(progressOffset+loaded,total)})}catch{return[]}}function materializeSessionEntries(entries,options){let{residentStore,loadHistoryEntries,onMaterialized}=options,missingEntryIds=new Set,materialized=entries.map(entry=>residentStore.materialize(entry,()=>{missingEntryIds.add(entry.id)}));if(missingEntryIds.size===0){for(let entry of materialized)onMaterialized(entry);return materialized}let persistedById=new Map(loadHistoryEntries().filter(entry=>entry.type!=="session").map(entry=>[entry.id,entry])),repaired=materialized.map(entry=>{if(!missingEntryIds.has(entry.id))return entry;let persisted=persistedById.get(entry.id);return persisted===void 0?entry:residentStore.materialize(persisted)});for(let entry of repaired)onMaterialized(entry);return repaired}import{createHash}from"node:crypto";import{existsSync as existsSync2,mkdirSync,readFileSync,renameSync,rmSync,writeFileSync}from"node:fs";import{join as join3}from"node:path";import{Buffer as Buffer2}from"buffer";var RESIDENT_STRING_MIN_BYTES=32*1024,DEFAULT_RESIDENT_STRING_BUDGET_BYTES=64*1024*1024,RESIDENT_STRING_PREFIX="\0senpi-resident-string:v1:",OMIT_JSON_VALUE=Symbol("omit-json-value"),ResidentStringStore=class{constructor(options={}){this.strings=new Map,this.bytes=0,this.evictedCount=0,this.evictedBytes=0,this.maxBytes=options.maxBytes??DEFAULT_RESIDENT_STRING_BUDGET_BYTES,this.blobsDir=options.blobsDir}configure(options){this.blobsDir=options.blobsDir}clear(){this.strings.clear(),this.bytes=0,this.evictedCount=0,this.evictedBytes=0;let dir=this.blobsDir?.();if(dir)try{rmSync(dir,{force:!0,recursive:!0})}catch{}}spillResident(){if(this.blobsDir?.())for(let[id,text]of this.strings)this._writeBlob(id,text)&&(this.strings.delete(id),this.bytes-=Buffer2.byteLength(text,"utf8"))}stats(){return{blobCount:this.strings.size,blobBytes:this.bytes,evictedCount:this.evictedCount,evictedBytes:this.evictedBytes}}externalize(value){return transformJson(value,text=>this.externalizeString(text))}materialize(value,onMissing){return transformJson(value,text=>this.materializeString(text,onMissing))}resolvedBlobsDir(){return this.blobsDir?.()}externalizeInPlace(value){this._mutateStringsInPlace(value,new Set,text=>this.externalizeString(text))}materializeInPlace(value){this._mutateStringsInPlace(value,new Set,text=>this.materializeString(text))}_mutateStringsInPlace(value,seen,mutate){if(typeof value!="object"||value===null||seen.has(value))return;seen.add(value);let record=value;for(let key of Object.keys(record)){let current=record[key];typeof current=="string"?record[key]=mutate(current):typeof current=="object"&&current!==null&&this._mutateStringsInPlace(current,seen,mutate)}}externalizeString(text){if(text.length<RESIDENT_STRING_MIN_BYTES||text.startsWith(RESIDENT_STRING_PREFIX))return text;let id=createHash("sha256").update(text,"utf8").digest("hex"),token=`${RESIDENT_STRING_PREFIX}${id}`;return this.strings.has(id)?(this.strings.delete(id),this.strings.set(id,text),token):(this.strings.set(id,text),this.bytes+=Buffer2.byteLength(text,"utf8"),this._enforceBudget(),token)}materializeString(text,onMissing){if(!text.startsWith(RESIDENT_STRING_PREFIX))return text;let id=text.slice(RESIDENT_STRING_PREFIX.length),resident=this.strings.get(id);if(resident!==void 0)return this.strings.delete(id),this.strings.set(id,resident),resident;let hydrated=this._readBlob(id);return hydrated!==void 0?hydrated:onMissing?.(id)??text}_enforceBudget(){for(;this.bytes>this.maxBytes&&this.strings.size>0;){let[oldestId,oldest]=this.strings.entries().next().value;if(!this._writeBlob(oldestId,oldest))return;this.strings.delete(oldestId),this.bytes-=Buffer2.byteLength(oldest,"utf8")}}_writeBlob(id,text){let dir=this.blobsDir?.();if(!dir)return!1;let final=join3(dir,`${id}.blob`),temp=`${final}.tmp`;try{mkdirSync(dir,{recursive:!0}),existsSync2(final)||(writeFileSync(temp,JSON.stringify({v:1,text}),"utf8"),renameSync(temp,final))}catch{try{rmSync(temp,{force:!0})}catch{}return!1}return this.evictedCount++,this.evictedBytes+=Buffer2.byteLength(text,"utf8"),!0}_readBlob(id){let dir=this.blobsDir?.();if(!dir)return;let file=join3(dir,`${id}.blob`);try{let parsed=JSON.parse(readFileSync(file,"utf8"));if(typeof parsed.text=="string")return parsed.text}catch{}try{rmSync(file,{force:!0})}catch{}}};function transformJson(value,transformString){let transformed=transformJsonValue(value,transformString,"",new WeakSet);if(transformed===OMIT_JSON_VALUE){let serialized=JSON.stringify(value);if(serialized===void 0)throw new SyntaxError("JSON-compatible value expected");return JSON.parse(serialized)}return transformed}function transformJsonValue(value,transformString,key,seen){if(typeof value=="string")return transformString(value);if(typeof value=="number")return Number.isFinite(value)?value:null;if(value===null||typeof value=="boolean")return value;if(typeof value=="bigint")throw new TypeError("Do not know how to serialize a BigInt");if(typeof value>"u"||typeof value=="function"||typeof value=="symbol")return OMIT_JSON_VALUE;if(seen.has(value))throw new TypeError("Converting circular structure to JSON");seen.add(value);let jsonValue=hasJsonSerializer(value)?value.toJSON(key):value;if(jsonValue!==value){let transformed2=transformJsonValue(jsonValue,transformString,key,seen);return seen.delete(value),transformed2}if(Array.isArray(value)){let transformed2=Array.from({length:value.length},(_item,index)=>{let item=value[index],transformedItem=transformJsonValue(item,transformString,String(index),seen);return transformedItem===OMIT_JSON_VALUE?null:transformedItem});return seen.delete(value),transformed2}let transformed={};for(let[key2,item]of Object.entries(value)){let transformedItem=transformJsonValue(item,transformString,String(key2),seen);transformedItem!==OMIT_JSON_VALUE&&Object.defineProperty(transformed,key2,{configurable:!0,enumerable:!0,value:transformedItem,writable:!0})}return seen.delete(value),transformed}function hasJsonSerializer(value){return"toJSON"in value&&typeof value.toJSON=="function"}var reserve;function reserveSessionWrite(path){reserve?.(path)}var liveWriters=new Set,writerRefs=new WeakMap;function registerSessionWriter(owner){if(writerRefs.has(owner))return;let ref=new WeakRef(owner);writerRefs.set(owner,ref),liveWriters.add(ref)}function unregisterSessionWriter(owner){let ref=writerRefs.get(owner);ref&&(writerRefs.delete(owner),liveWriters.delete(ref))}function hasOtherLiveSessionWriter(path,self){for(let ref of liveWriters){let owner=ref.deref();if(!owner){liveWriters.delete(ref);continue}if(owner!==self&&owner.isPersisted()&&owner.getSessionFile()===path)return!0}return!1}function uuidv7(){let ts=BigInt(Date.now()),bytes=randomBytes(10),hex=[(ts>>40n&0xffn).toString(16).padStart(2,"0"),(ts>>32n&0xffn).toString(16).padStart(2,"0"),(ts>>24n&0xffn).toString(16).padStart(2,"0"),(ts>>16n&0xffn).toString(16).padStart(2,"0"),(ts>>8n&0xffn).toString(16).padStart(2,"0"),(ts&0xffn).toString(16).padStart(2,"0"),(112|bytes[0]&15).toString(16).padStart(2,"0"),bytes[1].toString(16).padStart(2,"0"),(128|bytes[2]&63).toString(16).padStart(2,"0"),bytes[3].toString(16).padStart(2,"0"),...Array.from(bytes.slice(4),b=>b.toString(16).padStart(2,"0"))].join("");return`${hex.slice(0,8)}-${hex.slice(8,12)}-${hex.slice(12,16)}-${hex.slice(16,20)}-${hex.slice(20,32)}`}var contextMessageEntryIds=new WeakMap,SESSION_CONTEXT_ENTRY_ID="__piSessionContextEntryId";function withContextEntryId(entryId,message){return contextMessageEntryIds.set(message,entryId),message}function getSessionContextEntryId(message){return contextMessageEntryIds.get(message)}var CURRENT_SESSION_VERSION=3;function createSessionId(){return uuidv7()}function assertValidSessionId(id){if(!/^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(id))throw new Error("Session id must be non-empty, contain only alphanumeric characters, '-', '_', and '.', and start and end with an alphanumeric character")}function generateId(byId){for(let i=0;i<100;i++){let id=randomUUID().slice(0,8);if(!byId.has(id))return id}return randomUUID()}function migrateV1ToV2(entries){let ids=new Set,prevId=null;for(let entry of entries){if(entry.type==="session"){entry.version=2;continue}if(entry.id=generateId(ids),entry.parentId=prevId,prevId=entry.id,entry.type==="compaction"){let comp=entry;if(typeof comp.firstKeptEntryIndex=="number"){let targetEntry=entries[comp.firstKeptEntryIndex];targetEntry&&targetEntry.type!=="session"&&(comp.firstKeptEntryId=targetEntry.id),delete comp.firstKeptEntryIndex}}}}function migrateV2ToV3(entries){for(let entry of entries){if(entry.type==="session"){entry.version=3;continue}if(entry.type==="message"){let msgEntry=entry;msgEntry.message&&msgEntry.message.role==="hookMessage"&&(msgEntry.message.role="custom")}}}function migrateToCurrentVersion(entries){let version=entries.find(e=>e.type==="session")?.version??1;return version>=CURRENT_SESSION_VERSION?!1:(version<2&&migrateV1ToV2(entries),version<3&&migrateV2ToV3(entries),!0)}function migrateSessionEntries(entries){migrateToCurrentVersion(entries)}function parseSessionEntries(content){let entries=[],lines=content.trim().split(`
25
+ `);for(let line of lines)if(line.trim())try{let entry=JSON.parse(line);entries.push(entry)}catch{}return entries}function getLatestCompactionEntry(entries){for(let i=entries.length-1;i>=0;i--)if(entries[i].type==="compaction")return entries[i];return null}function buildEntryIndex(entries,byId){if(byId)return byId;let index=new Map;for(let entry of entries)index.set(entry.id,entry);return index}function buildSessionPath(entries,leafId,byId){let index=buildEntryIndex(entries,byId),leaf;if(leafId===null)return[];if(leafId&&(leaf=index.get(leafId)),leaf??=entries[entries.length-1],!leaf)return[];let path=[],current=leaf;for(;current;)path.push(current),current=current.parentId?index.get(current.parentId):void 0;return path.reverse(),path}function getSessionContextSettings(path){let thinkingLevel="off",thinkingSelection,configurationUpdate,model=null,isModelSelectionExplicit=!1,isInFallbackWindow=!1,preFallbackThinkingLevel=thinkingLevel,preFallbackThinkingSelection=thinkingSelection;for(let entry of path)if(entry.type==="thinking_level_change")thinkingLevel=entry.thinkingLevel,thinkingSelection=entry.thinkingSelection;else if(entry.type==="configuration_update")configurationUpdate={effort:entry.reasoning.effort};else if(entry.type==="model_change")entry.reason==="fallback"?(isInFallbackWindow||(preFallbackThinkingLevel=thinkingLevel,preFallbackThinkingSelection=thinkingSelection,entry.originalProvider&&entry.originalModelId&&(model={provider:normalizeProviderId(entry.originalProvider),modelId:entry.originalModelId},isModelSelectionExplicit=!0)),isInFallbackWindow=!0):entry.reason==="fallback-revert"?(isInFallbackWindow&&(thinkingLevel=preFallbackThinkingLevel,thinkingSelection=preFallbackThinkingSelection),isInFallbackWindow=!1):(isInFallbackWindow=!1,entry.provider&&entry.modelId&&(model={provider:normalizeProviderId(entry.provider),modelId:entry.modelId},isModelSelectionExplicit=!0));else if(entry.type==="message"&&entry.message.role==="assistant"&&!isInFallbackWindow){if(isModelSelectionExplicit&&model?.provider===normalizeProviderId(entry.message.provider))continue;model={provider:normalizeProviderId(entry.message.provider),modelId:entry.message.model},isModelSelectionExplicit=!1}return isInFallbackWindow&&(thinkingLevel=preFallbackThinkingLevel,thinkingSelection=preFallbackThinkingSelection),{thinkingLevel,thinkingSelection,configurationUpdate,model}}function sessionEntryToContextMessages(entry){if(entry.type==="message"){let message=entry.message;return(message.role==="user"||message.role==="assistant"||message.role==="toolResult")&&message.content==null?[withContextEntryId(entry.id,{...message,content:[]})]:[withContextEntryId(entry.id,message)]}return entry.type==="configuration_update"?[withContextEntryId(entry.id,{role:"configurationUpdate",content:[],effort:entry.reasoning.effort,timestamp:new Date(entry.timestamp).getTime()})]:entry.type==="custom_message"?[withContextEntryId(entry.id,createCustomMessage(entry.customType,entry.content??[],entry.display,entry.details,entry.timestamp))]:entry.type==="branch_summary"&&entry.summary?[withContextEntryId(entry.id,createBranchSummaryMessage(entry.summary,entry.fromId,entry.timestamp))]:entry.type==="compaction"?[withContextEntryId(entry.id,createCompactionSummaryMessage(entry.summary,entry.tokensBefore,entry.timestamp,entry.details))]:[]}function buildContextEntries(entries,leafId,byId){let path=buildSessionPath(entries,leafId,byId),compaction=null;for(let entry of path)entry.type==="compaction"&&(compaction=entry);if(!compaction)return path;let compactionIdx=path.findIndex(entry=>entry.id===compaction.id);if(compactionIdx<0)return path;let contextEntries=[compaction],foundFirstKept=!1;for(let i=0;i<compactionIdx;i++){let entry=path[i];entry.type!=="compaction"&&(entry.id===compaction.firstKeptEntryId&&(foundFirstKept=!0),foundFirstKept&&contextEntries.push(entry))}return contextEntries.push(...path.slice(compactionIdx+1)),contextEntries}function buildSessionContext(entries,leafId,byId){let path=buildSessionPath(entries,leafId,byId),{thinkingLevel,thinkingSelection,model,configurationUpdate}=getSessionContextSettings(path);return{messages:buildContextEntries(entries,leafId,byId).flatMap(sessionEntryToContextMessages),thinkingLevel,thinkingSelection,model,configurationUpdate}}function getDefaultSessionDirPath(cwd,agentDir=getAgentDir()){let resolvedCwd=resolvePath(cwd),resolvedAgentDir=resolvePath(agentDir),safePath=`--${resolvedCwd.replace(/^[/\\]/,"").replace(/[/\\:]/g,"-")}--`;return join4(resolvedAgentDir,"sessions",safePath)}function getDefaultSessionDir(cwd,agentDir=getAgentDir()){let sessionDir=getDefaultSessionDirPath(cwd,agentDir);return existsSync3(sessionDir)||mkdirSync2(sessionDir,{recursive:!0}),sessionDir}var SESSION_READ_BUFFER_SIZE=1024*1024,SESSION_HEADER_READ_BUFFER_SIZE=4096,MAX_SESSION_HEADER_SCAN_BYTES=1024*1024,SessionHeaderScanLimitError=class extends Error{constructor(filePath){super(`Session header exceeds ${MAX_SESSION_HEADER_SCAN_BYTES}-byte scan limit: ${filePath}`),this.name="SessionHeaderScanLimitError"}};function parseSessionEntryLine(line){if(!line.trim())return null;try{return JSON.parse(line)}catch{return null}}function loadEntriesFromFile(filePath){let resolvedFilePath=normalizePath(filePath);if(!existsSync3(resolvedFilePath))return[];let entries=[],pending="",fd=openSync(resolvedFilePath,"r");try{let decoder=new StringDecoder2("utf8"),buffer=Buffer.allocUnsafe(SESSION_READ_BUFFER_SIZE);for(;;){let bytesRead=readSync(fd,buffer,0,buffer.length,null);if(bytesRead===0)break;pending+=decoder.write(buffer.subarray(0,bytesRead));let lineStart=0,newlineIndex=pending.indexOf(`
20
26
  `,lineStart);for(;newlineIndex!==-1;){let entry=parseSessionEntryLine(pending.slice(lineStart,newlineIndex));entry&&entries.push(entry),lineStart=newlineIndex+1,newlineIndex=pending.indexOf(`
21
- `,lineStart)}pending=pending.slice(lineStart)}pending+=decoder.end();let finalEntry=parseSessionEntryLine(pending);finalEntry&&entries.push(finalEntry)}finally{closeSync(fd)}if(entries.length===0)return entries;let header=entries[0];return header.type!=="session"||typeof header.id!="string"?[]:entries}function parseSessionHeaderCandidate(line){if(!line.trim())return;let entry=parseSessionEntryLine(line);if(entry)return entry.type!=="session"||typeof entry.id!="string"?null:entry}function readSessionHeader(filePath){let fd=openSync(filePath,"r");try{let decoder=new StringDecoder("utf8"),buffer=Buffer.allocUnsafe(SESSION_HEADER_READ_BUFFER_SIZE),lineChunks=[],scannedBytes=0;for(;scannedBytes<MAX_SESSION_HEADER_SCAN_BYTES;){let readLength=Math.min(buffer.length,MAX_SESSION_HEADER_SCAN_BYTES-scannedBytes),bytesRead=readSync(fd,buffer,0,readLength,null);if(bytesRead===0)return lineChunks.push(decoder.end()),parseSessionHeaderCandidate(lineChunks.join(""))??null;scannedBytes+=bytesRead;let chunk=decoder.write(buffer.subarray(0,bytesRead)),lineStart=0,newlineIndex=chunk.indexOf(`
27
+ `,lineStart)}pending=pending.slice(lineStart)}pending+=decoder.end();let finalEntry=parseSessionEntryLine(pending);finalEntry&&entries.push(finalEntry)}finally{closeSync(fd)}if(entries.length===0)return entries;let header=entries[0];return header.type!=="session"||typeof header.id!="string"?[]:entries}function parseSessionHeaderCandidate(line){if(!line.trim())return;let entry=parseSessionEntryLine(line);if(entry)return entry.type!=="session"||typeof entry.id!="string"?null:entry}function readSessionHeader(filePath){let fd=openSync(filePath,"r");try{let decoder=new StringDecoder2("utf8"),buffer=Buffer.allocUnsafe(SESSION_HEADER_READ_BUFFER_SIZE),lineChunks=[],scannedBytes=0;for(;scannedBytes<MAX_SESSION_HEADER_SCAN_BYTES;){let readLength=Math.min(buffer.length,MAX_SESSION_HEADER_SCAN_BYTES-scannedBytes),bytesRead=readSync(fd,buffer,0,readLength,null);if(bytesRead===0)return lineChunks.push(decoder.end()),parseSessionHeaderCandidate(lineChunks.join(""))??null;scannedBytes+=bytesRead;let chunk=decoder.write(buffer.subarray(0,bytesRead)),lineStart=0,newlineIndex=chunk.indexOf(`
22
28
  `,lineStart);for(;newlineIndex!==-1;){lineChunks.push(chunk.slice(lineStart,newlineIndex));let header=parseSessionHeaderCandidate(lineChunks.join(""));if(header!==void 0)return header;lineChunks.length=0,lineStart=newlineIndex+1,newlineIndex=chunk.indexOf(`
23
- `,lineStart)}lineChunks.push(chunk.slice(lineStart))}let probe=Buffer.allocUnsafe(1);if(readSync(fd,probe,0,probe.length,null)===0)return lineChunks.push(decoder.end()),parseSessionHeaderCandidate(lineChunks.join(""))??null;throw new SessionHeaderScanLimitError(filePath)}finally{closeSync(fd)}}function readSessionHeaderForDiscovery(filePath){try{return readSessionHeader(filePath)}catch{return null}}function getSessionHeaderCwd(header){let cwd=header.cwd;return typeof cwd=="string"?cwd:void 0}function sessionCwdMatches(cwd,resolvedCwd){return cwd!==void 0&&cwd!==""&&resolvePath(cwd)===resolvedCwd}function findMostRecentSession(sessionDir,cwd){let resolvedSessionDir=normalizePath(sessionDir),resolvedCwd=cwd?resolvePath(cwd):void 0;try{return readdirSync(resolvedSessionDir).filter(f=>f.endsWith(".jsonl")).map(f=>join3(resolvedSessionDir,f)).map(path=>({path,header:readSessionHeaderForDiscovery(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}catch{return null}}var sessionEntryLoader=loadEntriesFromFile;var SessionManager=class _SessionManager{constructor(cwd,sessionDir,sessionFile,persist,newSessionOptions,preloadedFileEntries){this.sessionId="",this.flushed=!1,this.fileEntries=[],this.byId=new Map,this.entryOrdersById=new Map,this.messageEntryPositions=new WeakMap,this.labelsById=new Map,this.labelTimestampsById=new Map,this.leafId=null,this.residentStore=new ResidentStringStore,this.mirrorTrimmed=!1,this.fullEntryCount=0,this.compactEntriesCache=null,this.mutationCount=0,this.entriesCache=null,this.branchCache=null,this.sessionNameCache=void 0,this.usageTotals={input:0,output:0,cacheRead:0,cacheWrite:0,cost:0,latestCacheHitRate:void 0},this.cwd=resolvePath(cwd),this.sessionDir=normalizePath(sessionDir),this.persist=persist,persist&&registerSessionWriter(this),persist&&this.sessionDir&&!existsSync3(this.sessionDir)&&mkdirSync2(this.sessionDir,{recursive:!0}),this.residentStore.configure({blobsDir:()=>this.persist&&this.sessionId?join3(this.sessionDir,"resident-blobs",this.sessionId):void 0}),sessionFile?this._setSessionFile(sessionFile,preloadedFileEntries,newSessionOptions):preloadedFileEntries?.length?this._loadEntries(preloadedFileEntries,newSessionOptions):this.newSession(newSessionOptions)}reloadFromDisk(){if(!this.sessionFile||!existsSync3(this.sessionFile))return;let fileEntries=loadEntriesFromFile(this.sessionFile);if(fileEntries.length===0){if(statSync(this.sessionFile).size===0)return;throw new Error(`Session file is not a valid ${APP_NAME} session: ${this.sessionFile}`)}this._setSessionFile(this.sessionFile,fileEntries)}setSessionFile(sessionFile){this._setSessionFile(sessionFile)}_setSessionFile(sessionFile,preloadedFileEntries,newSessionOptions){if(this.persist&&reserveSessionWrite(resolvePath(sessionFile)),this.sessionFile=resolvePath(sessionFile),this.mirrorTrimmed=!1,this.residentStore.clear(),existsSync3(this.sessionFile)){let entries=preloadedFileEntries??loadEntriesFromFile(this.sessionFile);if(entries.length===0){let explicitPath=this.sessionFile;if(statSync(explicitPath).size>0)throw new Error(`Session file is not a valid ${APP_NAME} session: ${explicitPath}`);this._resetToNewSession(newSessionOptions),this._rewriteFile(),this.flushed=!0;return}this.fileEntries=entries;let header=this.fileEntries.find(e=>e.type==="session");this.sessionId=header?.id??createSessionId(),this._releaseBlobsDirUnlessShared(),migrateToCurrentVersion(this.fileEntries)&&this._rewriteFile(),this.fileEntries=this.fileEntries.map(entry=>this.residentStore.externalize(entry)),this._buildIndex(),this.mutationCount++,this.flushed=!0}else this._resetToNewSession(newSessionOptions),newSessionOptions?.id!==void 0&&(this._rewriteFile(),this.flushed=!0)}newSession(options){let timestamp=this._resetToNewSession(options);if(this.persist){let fileTimestamp=timestamp.replace(/[:.]/g,"-"),path=join3(this.getSessionDir(),`${fileTimestamp}_${this.sessionId}.jsonl`);reserveSessionWrite(path),this.sessionFile=path}return this.sessionFile}_resetToNewSession(options){options?.id!==void 0&&assertValidSessionId(options.id);let previousBlobsDir=this.residentStore.resolvedBlobsDir();this.sessionId=options?.id??createSessionId();let timestamp=new Date().toISOString(),header={type:"session",version:CURRENT_SESSION_VERSION,id:this.sessionId,timestamp,cwd:this.cwd,parentSession:options?.parentSession};return this.fileEntries=[header],this.mirrorTrimmed=!1,this.fullEntryCount=0,this.residentStore.clear(),previousBlobsDir&&this._removeBlobsDir(previousBlobsDir),this.byId.clear(),this.entryOrdersById.clear(),this.messageEntryPositions=new WeakMap,this.labelsById.clear(),this.labelTimestampsById.clear(),this.leafId=null,this.sessionNameCache=void 0,this.usageTotals={input:0,output:0,cacheRead:0,cacheWrite:0,cost:0,latestCacheHitRate:void 0},this.mutationCount++,this.flushed=!1,timestamp}_loadEntries(entries,options){let header=entries.find(e=>e.type==="session");header?(this.fileEntries=entries,this.sessionId=header.id,migrateToCurrentVersion(this.fileEntries)&&this._rewriteFile()):(this.newSession(options),this.fileEntries=this.fileEntries.concat(entries)),this.fileEntries=this.fileEntries.map(entry=>this.residentStore.externalize(entry)),this._buildIndex(),this.mutationCount++}_buildIndex(){this.byId.clear(),this.entryOrdersById.clear(),this.messageEntryPositions=new WeakMap,this.labelsById.clear(),this.labelTimestampsById.clear(),this.leafId=null,this.sessionNameCache=void 0,this.usageTotals={input:0,output:0,cacheRead:0,cacheWrite:0,cost:0,latestCacheHitRate:void 0};let fullEntryCount=0;for(let[order,entry]of this.fileEntries.entries())entry.type!=="session"&&(fullEntryCount++,this.byId.set(entry.id,entry),this.entryOrdersById.set(entry.id,order),this.leafId=entry.id,this._accumulateUsage(entry),entry.type==="session_info"&&(this.sessionNameCache=entry.name?.trim()||void 0),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))));this.mirrorTrimmed||(this.fullEntryCount=fullEntryCount)}_rewriteFile(){if(!this.persist||!this.sessionFile)return;reserveSessionWrite(this.sessionFile);let fd=openSync(this.sessionFile,"w");try{for(let entry of this.fileEntries)writeFileSync2(fd,`${JSON.stringify(this.residentStore.materialize(entry))}
29
+ `,lineStart)}lineChunks.push(chunk.slice(lineStart))}let probe=Buffer.allocUnsafe(1);if(readSync(fd,probe,0,probe.length,null)===0)return lineChunks.push(decoder.end()),parseSessionHeaderCandidate(lineChunks.join(""))??null;throw new SessionHeaderScanLimitError(filePath)}finally{closeSync(fd)}}function readSessionHeaderForDiscovery(filePath){try{return readSessionHeader(filePath)}catch{return null}}function getSessionHeaderCwd(header){let cwd=header.cwd;return typeof cwd=="string"?cwd:void 0}function sessionCwdMatches(cwd,resolvedCwd){return cwd!==void 0&&cwd!==""&&resolvePath(cwd)===resolvedCwd}function findMostRecentSession(sessionDir,cwd){let resolvedSessionDir=normalizePath(sessionDir),resolvedCwd=cwd?resolvePath(cwd):void 0;try{return readdirSync(resolvedSessionDir).filter(f=>f.endsWith(".jsonl")).map(f=>join4(resolvedSessionDir,f)).map(path=>({path,header:readSessionHeaderForDiscovery(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}catch{return null}}var sessionEntryLoader=loadEntriesFromFile;var SessionManager=class _SessionManager{constructor(cwd,sessionDir,sessionFile,persist,newSessionOptions,preloadedFileEntries){this.sessionId="",this.flushed=!1,this.fileEntries=[],this.byId=new Map,this.entryOrdersById=new Map,this.messageEntryPositions=new WeakMap,this.labelsById=new Map,this.labelTimestampsById=new Map,this.leafId=null,this.residentStore=new ResidentStringStore,this.mirrorTrimmed=!1,this.fullEntryCount=0,this.compactEntriesCache=null,this.mutationCount=0,this.entriesCache=null,this.branchCache=null,this.sessionNameCache=void 0,this.usageTotals={input:0,output:0,cacheRead:0,cacheWrite:0,cost:0,latestCacheHitRate:void 0},this.cwd=resolvePath(cwd),this.sessionDir=normalizePath(sessionDir),this.persist=persist,persist&&registerSessionWriter(this),persist&&this.sessionDir&&!existsSync3(this.sessionDir)&&mkdirSync2(this.sessionDir,{recursive:!0}),this.residentStore.configure({blobsDir:()=>this.persist&&this.sessionId?join4(this.sessionDir,"resident-blobs",this.sessionId):void 0}),sessionFile?this._setSessionFile(sessionFile,preloadedFileEntries,newSessionOptions):preloadedFileEntries?.length?this._loadEntries(preloadedFileEntries,newSessionOptions):this.newSession(newSessionOptions)}reloadFromDisk(){if(!this.sessionFile||!existsSync3(this.sessionFile))return;let fileEntries=loadEntriesFromFile(this.sessionFile);if(fileEntries.length===0){if(statSync(this.sessionFile).size===0)return;throw new Error(`Session file is not a valid ${APP_NAME} session: ${this.sessionFile}`)}this._setSessionFile(this.sessionFile,fileEntries)}setSessionFile(sessionFile){this._setSessionFile(sessionFile)}_setSessionFile(sessionFile,preloadedFileEntries,newSessionOptions){if(this.persist&&reserveSessionWrite(resolvePath(sessionFile)),this.sessionFile=resolvePath(sessionFile),this.mirrorTrimmed=!1,this.residentStore.clear(),existsSync3(this.sessionFile)){let entries=preloadedFileEntries??loadEntriesFromFile(this.sessionFile);if(entries.length===0){let explicitPath=this.sessionFile;if(statSync(explicitPath).size>0)throw new Error(`Session file is not a valid ${APP_NAME} session: ${explicitPath}`);this._resetToNewSession(newSessionOptions),this._rewriteFile(),this.flushed=!0;return}this.fileEntries=entries;let header=this.fileEntries.find(e=>e.type==="session");this.sessionId=header?.id??createSessionId(),this._releaseBlobsDirUnlessShared(),migrateToCurrentVersion(this.fileEntries)&&this._rewriteFile(),this.fileEntries=this.fileEntries.map(entry=>this.residentStore.externalize(entry)),this._buildIndex(),this.mutationCount++,this.flushed=!0}else this._resetToNewSession(newSessionOptions),newSessionOptions?.id!==void 0&&(this._rewriteFile(),this.flushed=!0)}newSession(options){let timestamp=this._resetToNewSession(options);if(this.persist){let fileTimestamp=timestamp.replace(/[:.]/g,"-"),path=join4(this.getSessionDir(),`${fileTimestamp}_${this.sessionId}.jsonl`);reserveSessionWrite(path),this.sessionFile=path}return this.sessionFile}_resetToNewSession(options){options?.id!==void 0&&assertValidSessionId(options.id);let previousBlobsDir=this.residentStore.resolvedBlobsDir();this.sessionId=options?.id??createSessionId();let timestamp=new Date().toISOString(),header={type:"session",version:CURRENT_SESSION_VERSION,id:this.sessionId,timestamp,cwd:this.cwd,parentSession:options?.parentSession};return this.fileEntries=[header],this.mirrorTrimmed=!1,this.fullEntryCount=0,this.residentStore.clear(),previousBlobsDir&&this._removeBlobsDir(previousBlobsDir),this.byId.clear(),this.entryOrdersById.clear(),this.messageEntryPositions=new WeakMap,this.labelsById.clear(),this.labelTimestampsById.clear(),this.leafId=null,this.sessionNameCache=void 0,this.usageTotals={input:0,output:0,cacheRead:0,cacheWrite:0,cost:0,latestCacheHitRate:void 0},this.mutationCount++,this.flushed=!1,timestamp}_loadEntries(entries,options){let header=entries.find(e=>e.type==="session");header?(this.fileEntries=entries,this.sessionId=header.id,migrateToCurrentVersion(this.fileEntries)&&this._rewriteFile()):(this.newSession(options),this.fileEntries=this.fileEntries.concat(entries)),this.fileEntries=this.fileEntries.map(entry=>this.residentStore.externalize(entry)),this._buildIndex(),this.mutationCount++}_buildIndex(){this.byId.clear(),this.entryOrdersById.clear(),this.messageEntryPositions=new WeakMap,this.labelsById.clear(),this.labelTimestampsById.clear(),this.leafId=null,this.sessionNameCache=void 0,this.usageTotals={input:0,output:0,cacheRead:0,cacheWrite:0,cost:0,latestCacheHitRate:void 0};let fullEntryCount=0;for(let[order,entry]of this.fileEntries.entries())entry.type!=="session"&&(fullEntryCount++,this.byId.set(entry.id,entry),this.entryOrdersById.set(entry.id,order),this.leafId=entry.id,this._accumulateUsage(entry),entry.type==="session_info"&&(this.sessionNameCache=entry.name?.trim()||void 0),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))));this.mirrorTrimmed||(this.fullEntryCount=fullEntryCount)}_rewriteFile(){if(!this.persist||!this.sessionFile)return;reserveSessionWrite(this.sessionFile);let fd=openSync(this.sessionFile,"w");try{for(let entry of this.fileEntries)writeFileSync2(fd,`${JSON.stringify(this.residentStore.materialize(entry))}
24
30
  `)}finally{closeSync(fd)}}isPersisted(){return this.persist}getCwd(){return this.cwd}getSessionDir(){return this.sessionDir}usesDefaultSessionDir(){return this.sessionDir===getDefaultSessionDirPath(this.cwd)}getSessionId(){return this.sessionId}getSessionFile(){return this.sessionFile}getResidentStore(){return this.residentStore}getResidentStoreStats(){return this.residentStore.stats()}_persist(entry){if(!this.persist||!this.sessionFile)return;reserveSessionWrite(this.sessionFile);let persistedEntry=this.residentStore.materialize(entry);if(!this.fileEntries.some(e=>e.type==="message"&&e.message.role==="assistant")){this.flushed?appendFileSync(this.sessionFile,`${JSON.stringify(persistedEntry)}
25
31
  `):this.flushed=!1;return}if(this.flushed)appendFileSync(this.sessionFile,`${JSON.stringify(persistedEntry)}
26
32
  `);else{let fd=openSync(this.sessionFile,"wx");try{for(let e of this.fileEntries)writeFileSync2(fd,`${JSON.stringify(this.residentStore.materialize(e))}
27
- `)}finally{closeSync(fd)}this.flushed=!0}}_appendEntry(entry){let residentEntry=this.residentStore.externalize(entry);this.fileEntries.push(residentEntry),this.byId.set(residentEntry.id,residentEntry),this.entryOrdersById.set(residentEntry.id,this.fileEntries.length-1),this.leafId=residentEntry.id,this.fullEntryCount++,this._accumulateUsage(residentEntry),this.mutationCount++,this._persist(residentEntry)}appendEntry(entry){this._appendEntry(entry);let order=this.entryOrdersById.get(entry.id);entry.type==="message"&&order!==void 0&&this.messageEntryPositions.set(entry.message,{entryId:entry.id,order}),entry.type==="session_info"&&(this.sessionNameCache=entry.name?.trim()||void 0),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)))}_materializeEntry(entry){let missingResidentString=!1,materialized=this.residentStore.materialize(entry,()=>{missingResidentString=!0});if(missingResidentString&&this.sessionFile){let persisted=loadEntriesFromFile(this.sessionFile).find(candidate=>candidate.id===entry.id);if(persisted)return persisted}if(materialized.type==="message"){let order=this.entryOrdersById.get(materialized.id);order!==void 0&&this.messageEntryPositions.set(materialized.message,{entryId:materialized.id,order})}return materialized}_accumulateUsage(entry){if(entry.type!=="message"||entry.message.role!=="assistant")return;let usage=entry.message.usage;if(!usage)return;this.usageTotals.input+=usage.input,this.usageTotals.output+=usage.output,this.usageTotals.cacheRead+=usage.cacheRead,this.usageTotals.cacheWrite+=usage.cacheWrite,this.usageTotals.cost+=usage.cost?.total??0;let latestPromptTokens=usage.input+usage.cacheRead+usage.cacheWrite;this.usageTotals.latestCacheHitRate=latestPromptTokens>0?usage.cacheRead/latestPromptTokens*100:void 0}getUsageTotals(){return this.usageTotals}appendMessage(message){let entry={type:"message",id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString(),message};this._appendEntry(entry);let order=this.entryOrdersById.get(entry.id);return order!==void 0&&this.messageEntryPositions.set(message,{entryId:entry.id,order}),entry.id}getMessageEntryPosition(message){return this.messageEntryPositions.get(message)}getEntryOrder(entryId){return this.entryOrdersById.get(entryId)}appendThinkingLevelChange(thinkingLevel,thinkingSelection){let entry={type:"thinking_level_change",id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString(),thinkingLevel,thinkingSelection};return this._appendEntry(entry),entry.id}appendConfigurationUpdate(effort){let entry={type:"configuration_update",id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString(),reasoning:{effort}};return this._appendEntry(entry),entry.id}appendModelChangeRejected(details){let entry={type:"model_change_rejected",id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString(),...details};return this._appendEntry(entry),entry.id}appendModelChange(provider,modelId,reason,originalProvider,originalModelId){let entry={type:"model_change",id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString(),provider,modelId,reason,originalProvider,originalModelId};return this._appendEntry(entry),entry.id}appendCompaction(summary,firstKeptEntryId,tokensBefore,details,fromHook,usage){let entry={type:"compaction",id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString(),summary,firstKeptEntryId,tokensBefore,details,usage,fromHook};return this._appendEntry(entry),this._trimMirrorAfterCompaction(entry),entry.id}dispose(){unregisterSessionWriter(this),this._releaseBlobsDirUnlessShared()}_releaseBlobsDirUnlessShared(){let blobsDir=this.residentStore.resolvedBlobsDir();blobsDir&&(this.sessionFile&&hasOtherLiveSessionWriter(this.sessionFile,this)||this._removeBlobsDir(blobsDir))}_removeBlobsDir(dir){try{rmSync2(dir,{force:!0,recursive:!0})}catch{}}_trimMirrorAfterCompaction(compaction){if(!this.persist)return;let firstKeptIndex=this.fileEntries.findIndex(entry=>entry.id===compaction.firstKeptEntryId),compactionIndex=this.fileEntries.findIndex(entry=>entry.id===compaction.id);if(firstKeptIndex<0||compactionIndex<firstKeptIndex)return;let header=this.fileEntries.find(entry=>entry.type==="session"),retained=[...this.fileEntries.slice(0,firstKeptIndex).filter(entry=>entry.type!=="message"),...this.fileEntries.slice(firstKeptIndex,compactionIndex+1)],parentId=null;for(let entry of retained)entry.type!=="session"&&(entry.parentId=parentId),parentId=entry.type==="session"?null:entry.id;this.residentStore.spillResident(),this.mirrorTrimmed=!0,this.fileEntries=[header,...retained].filter(entry=>entry!==void 0).map(entry=>this.residentStore.externalize(entry)),this._buildIndex(),this.mutationCount++}appendCustomEntry(customType,data){let entry={type:"custom",customType,data,id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString()};return this._appendEntry(entry),entry.id}appendSessionInfo(name){let sanitizedName=name.replace(/[\r\n]+/g," ").trim(),entry={type:"session_info",id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString(),name:sanitizedName};return this.sessionNameCache=sanitizedName||void 0,this._appendEntry(entry),entry.id}getSessionName(){return this.sessionNameCache}appendCustomMessageEntry(customType,content,display,details){let entry={type:"custom_message",customType,content,display,details,id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString()};return this._appendEntry(entry),entry.id}getLeafId(){return this.leafId}getLeafEntry(){let entry=this.leafId?this.byId.get(this.leafId):void 0;return entry?this._materializeEntry(entry):void 0}getEntry(id){let entry=this.byId.get(id);if(entry)return this._materializeEntry(entry);if(this.mirrorTrimmed&&this.sessionFile){let persisted=this._loadFullHistoryEntries().find(candidate=>candidate.id===id);return persisted?this.residentStore.materialize(persisted):void 0}}getChildren(parentId){let children=[];for(let entry of this.byId.values())entry.parentId===parentId&&children.push(this._materializeEntry(entry));return children}getLabel(id){return this.labelsById.get(id)}appendLabelChange(targetId,label){if(!this.byId.has(targetId))throw new Error(`Entry ${targetId} not found`);let entry={type:"label",id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString(),targetId,label};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}getBranch(fromId){if(fromId===void 0&&this.branchCache!==null&&this.branchCache.leafId===this.leafId&&this.branchCache.mutation===this.mutationCount)return this.branchCache.entries;let path=[],startId=fromId??this.leafId,entriesById=this.byId;fromId!==void 0&&!entriesById.has(fromId)&&this.mirrorTrimmed&&this.sessionFile&&(entriesById=new Map(this._loadFullHistoryEntries().filter(entry=>entry.type!=="session").map(entry=>[entry.id,this.residentStore.materialize(entry)])));let current=startId?entriesById.get(startId):void 0;for(;current;)path.unshift(current),current=current.parentId?entriesById.get(current.parentId):void 0;let materializedPath=this._materializeEntries(path);return fromId===void 0&&(this.branchCache={leafId:this.leafId,mutation:this.mutationCount,entries:materializedPath}),materializedPath}buildContextEntries(){return buildContextEntries(this._getCompactEntries(),this.leafId)}buildSessionContext(){return buildSessionContext(this._getCompactEntries(),this.leafId)}hasContextMessages(){return this.hasBranchEntry(entry=>entry.type==="message"||entry.type==="custom_message"||entry.type==="compaction"||entry.type==="branch_summary"&&!!entry.summary)}hasThinkingLevelChanges(){return this.hasBranchEntry(entry=>entry.type==="thinking_level_change")}countCompactions(){let count=0;for(let entry of this.fileEntries)entry.type==="compaction"&&count++;return count}hasBranchEntry(predicate){let current=this.leafId?this.byId.get(this.leafId):void 0;for(;current;){if(predicate(current))return!0;current=current.parentId?this.byId.get(current.parentId):void 0}return!1}getHeader(){let h=this.fileEntries.find(e=>e.type==="session");return h?this.residentStore.materialize(h):null}getEntries(){if(this.mirrorTrimmed&&this.sessionFile)return this._loadFullHistoryEntries().filter(e=>e.type!=="session").map(entry=>this.residentStore.materialize(entry));if(this.entriesCache!==null&&this.entriesCache.mutation===this.mutationCount)return this.entriesCache.entries;let entries=this.fileEntries.filter(e=>e.type!=="session"),materializedEntries=this._materializeEntries(entries);return this.entriesCache={mutation:this.mutationCount,entries:materializedEntries},materializedEntries}getEntryCount(){return this.fullEntryCount}dropMaterializedCaches(){this.entriesCache=null,this.branchCache=null,this.compactEntriesCache=null}_materializeEntries(entries){return materializeSessionEntries(entries,{residentStore:this.residentStore,loadHistoryEntries:()=>this._loadFullHistoryEntries(),onMaterialized:entry=>{if(entry.type!=="message")return;let order=this.entryOrdersById.get(entry.id);order!==void 0&&this.messageEntryPositions.set(entry.message,{entryId:entry.id,order})}})}_getCompactEntries(){this.compactEntriesCache?.mutation!==this.mutationCount&&(this.compactEntriesCache={mutation:this.mutationCount,entries:this.fileEntries.filter(e=>e.type!=="session")});let entries=this.compactEntriesCache.entries,missingEntryIds=new Set;for(let entry of entries)this.residentStore.materialize(entry,()=>{missingEntryIds.add(entry.id)});if(missingEntryIds.size>0&&this.sessionFile){let persistedById=new Map(this._loadFullHistoryEntries().map(entry=>[entry.id,entry]));for(let index=0;index<entries.length;index++){let entry=entries[index];if(!missingEntryIds.has(entry.id))continue;let persisted=persistedById.get(entry.id);persisted&&(entries[index]=this.residentStore.externalize(persisted))}}let materialized=entries.map(entry=>this.residentStore.materialize(entry));for(let entry of materialized){if(entry.type!=="message")continue;let order=this.entryOrdersById.get(entry.id);order!==void 0&&this.messageEntryPositions.set(entry.message,{entryId:entry.id,order})}return materialized}_loadFullHistoryEntries(){return this.sessionFile?sessionEntryLoader(this.sessionFile):this.fileEntries}getTree(){let entries=this.getEntries(),nodeMap=new Map,roots=[];for(let entry of entries){let label=this.labelsById.get(entry.id),labelTimestamp=this.labelTimestampsById.get(entry.id);nodeMap.set(entry.id,{entry,children:[],label,labelTimestamp})}for(let entry of entries){let node=nodeMap.get(entry.id);if(entry.parentId===null||entry.parentId===entry.id)roots.push(node);else{let parent=nodeMap.get(entry.parentId);parent?parent.children.push(node):roots.push(node)}}let stack=[...roots];for(;stack.length>0;){let node=stack.pop();node.children.sort((a,b)=>new Date(a.entry.timestamp).getTime()-new Date(b.entry.timestamp).getTime()),stack.push(...node.children)}return roots}branch(branchFromId){if(!this.byId.has(branchFromId)&&this.sessionFile&&this.reloadFromDisk(),!this.byId.has(branchFromId))throw new Error(`Entry ${branchFromId} not found`);this.leafId=branchFromId,this.mutationCount++}resetLeaf(){this.leafId=null,this.mutationCount++}branchWithSummary(branchFromId,summary,details,fromHook,usage){if(branchFromId!==null&&!this.byId.has(branchFromId))throw new Error(`Entry ${branchFromId} not found`);let fromId=this.leafId??"root";this.leafId=branchFromId;let entry={type:"branch_summary",id:generateId(this.byId),parentId:branchFromId,timestamp:new Date().toISOString(),fromId,summary,details,usage,fromHook};return this._appendEntry(entry),entry.id}createBranchedSession(leafId){let previousSessionFile=this.sessionFile,path=this.getBranch(leafId);if(path.length===0)throw new Error(`Entry ${leafId} not found`);let pathWithoutLabels=[],replacementByLabelId=new Map,pendingLabelIds=[],pathParentId=null;for(let entry of path){if(entry.type==="label"){pendingLabelIds.push(entry.id);continue}for(let labelId of pendingLabelIds)replacementByLabelId.set(labelId,entry.id);pendingLabelIds.length=0,pathWithoutLabels.push(entry.type==="compaction"?{...entry,parentId:pathParentId,firstKeptEntryId:replacementByLabelId.get(entry.firstKeptEntryId)??entry.firstKeptEntryId}:{...entry,parentId:pathParentId}),pathParentId=entry.id}let newSessionId=createSessionId(),timestamp=new Date().toISOString(),fileTimestamp=timestamp.replace(/[:.]/g,"-"),newSessionFile=join3(this.getSessionDir(),`${fileTimestamp}_${newSessionId}.jsonl`),header={type:"session",version:CURRENT_SESSION_VERSION,id:newSessionId,timestamp,cwd:this.cwd,parentSession:this.persist?previousSessionFile:void 0},pathEntryIds=new Set(pathWithoutLabels.map(e=>e.id)),labelsToWrite=[];for(let[targetId,label]of this.labelsById)pathEntryIds.has(targetId)&&labelsToWrite.push({targetId,label,timestamp:this.labelTimestampsById.get(targetId)});if(this.persist){let parentId2=pathWithoutLabels[pathWithoutLabels.length-1]?.id||null,labelEntries2=[];for(let{targetId,label,timestamp:labelTimestamp}of labelsToWrite){let labelEntry={type:"label",id:generateId(new Set(pathEntryIds)),parentId:parentId2,timestamp:labelTimestamp,targetId,label};pathEntryIds.add(labelEntry.id),labelEntries2.push(labelEntry),parentId2=labelEntry.id}reserveSessionWrite(newSessionFile);let branchedEntries2=this._materializeEntries([...pathWithoutLabels,...labelEntries2]),previousBlobsDir=this.residentStore.resolvedBlobsDir();return this.residentStore.clear(),previousBlobsDir&&this._removeBlobsDir(previousBlobsDir),this.mirrorTrimmed=!1,this.sessionId=newSessionId,this.sessionFile=newSessionFile,this.fileEntries=[header,...branchedEntries2.map(entry=>this.residentStore.externalize(entry))],this._buildIndex(),this.mutationCount++,this.fileEntries.some(e=>e.type==="message"&&e.message.role==="assistant")?(this._rewriteFile(),this.flushed=!0):this.flushed=!1,newSessionFile}let labelEntries=[],parentId=pathWithoutLabels[pathWithoutLabels.length-1]?.id||null;for(let{targetId,label,timestamp:labelTimestamp}of labelsToWrite){let labelEntry={type:"label",id:generateId(new Set([...pathEntryIds,...labelEntries.map(e=>e.id)])),parentId,timestamp:labelTimestamp,targetId,label};labelEntries.push(labelEntry),parentId=labelEntry.id}let branchedEntries=this._materializeEntries([...pathWithoutLabels,...labelEntries]);this.residentStore.clear(),this.fileEntries=[header,...branchedEntries.map(entry=>this.residentStore.externalize(entry))],this.sessionId=newSessionId,this._buildIndex(),this.mutationCount++}static create(cwd,sessionDir,options){let dir=sessionDir?normalizePath(sessionDir):getDefaultSessionDir(cwd);return new _SessionManager(cwd,dir,void 0,!0,options)}static open(path,sessionDir,cwdOverride,options){let resolvedPath=resolvePath(path);reserveSessionWrite(resolvedPath);let header=null,preloadedFileEntries;if(cwdOverride===void 0&&existsSync3(resolvedPath))try{header=readSessionHeader(resolvedPath)}catch(error){if(!(error instanceof SessionHeaderScanLimitError))throw error;preloadedFileEntries=loadEntriesFromFile(resolvedPath);let firstEntry=preloadedFileEntries[0];header=firstEntry?.type==="session"?firstEntry:null}if(existsSync3(resolvedPath)){let content=readFileSync2(resolvedPath);content.length>0&&content[content.length-1]!==10&&appendFileSync(resolvedPath,`
28
- `)}let cwd=cwdOverride??(header?getSessionHeaderCwd(header):void 0)??process.cwd(),dir=sessionDir?normalizePath(sessionDir):resolve2(resolvedPath,"..");return new _SessionManager(cwd,dir,resolvedPath,!0,options,preloadedFileEntries)}static continueRecent(cwd,sessionDir){let dir=sessionDir?normalizePath(sessionDir):getDefaultSessionDir(cwd),filterCwd=sessionDir!==void 0&&dir!==getDefaultSessionDirPath(cwd),mostRecent=findMostRecentSession(dir,filterCwd?cwd:void 0);return mostRecent?new _SessionManager(cwd,dir,mostRecent,!0):new _SessionManager(cwd,dir,void 0,!0)}static inMemory(cwd=process.cwd(),options,entries){return new _SessionManager(cwd,"",void 0,!1,options,entries)}static forkFrom(sourcePath,targetCwd,sessionDir,options){let resolvedSourcePath=resolvePath(sourcePath),resolvedTargetCwd=resolvePath(targetCwd),sourceEntries=loadEntriesFromFile(resolvedSourcePath);if(sourceEntries.length===0)throw new Error(`Cannot fork: source session file is empty or invalid: ${resolvedSourcePath}`);if(!sourceEntries.find(e=>e.type==="session"))throw new Error(`Cannot fork: source session has no header: ${resolvedSourcePath}`);let dir=sessionDir?normalizePath(sessionDir):getDefaultSessionDir(resolvedTargetCwd);existsSync3(dir)||mkdirSync2(dir,{recursive:!0}),options?.id!==void 0&&assertValidSessionId(options.id);let newSessionId=options?.id??createSessionId(),timestamp=new Date().toISOString(),fileTimestamp=timestamp.replace(/[:.]/g,"-"),newSessionFile=join3(dir,`${fileTimestamp}_${newSessionId}.jsonl`),newHeader={type:"session",version:CURRENT_SESSION_VERSION,id:newSessionId,timestamp,cwd:resolvedTargetCwd,parentSession:resolvedSourcePath};reserveSessionWrite(newSessionFile),writeFileSync2(newSessionFile,`${JSON.stringify(newHeader)}
33
+ `)}finally{closeSync(fd)}this.flushed=!0}}_appendEntry(entry){let residentEntry=this.residentStore.externalize(entry);this.fileEntries.push(residentEntry),this.byId.set(residentEntry.id,residentEntry),this.entryOrdersById.set(residentEntry.id,this.fileEntries.length-1),this.leafId=residentEntry.id,this.fullEntryCount++,this._accumulateUsage(residentEntry),this.mutationCount++,this._persist(residentEntry)}appendEntry(entry){this._appendEntry(entry);let order=this.entryOrdersById.get(entry.id);entry.type==="message"&&order!==void 0&&this.messageEntryPositions.set(entry.message,{entryId:entry.id,order}),entry.type==="session_info"&&(this.sessionNameCache=entry.name?.trim()||void 0),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)))}_materializeEntry(entry){let missingResidentString=!1,materialized=this.residentStore.materialize(entry,()=>{missingResidentString=!0});if(missingResidentString&&this.sessionFile){let persisted=loadEntriesFromFile(this.sessionFile).find(candidate=>candidate.id===entry.id);if(persisted)return persisted}if(materialized.type==="message"){let order=this.entryOrdersById.get(materialized.id);order!==void 0&&this.messageEntryPositions.set(materialized.message,{entryId:materialized.id,order})}return materialized}_accumulateUsage(entry){if(entry.type!=="message"||entry.message.role!=="assistant")return;let usage=entry.message.usage;if(!usage)return;this.usageTotals.input+=usage.input,this.usageTotals.output+=usage.output,this.usageTotals.cacheRead+=usage.cacheRead,this.usageTotals.cacheWrite+=usage.cacheWrite,this.usageTotals.cost+=usage.cost?.total??0;let latestPromptTokens=usage.input+usage.cacheRead+usage.cacheWrite;this.usageTotals.latestCacheHitRate=latestPromptTokens>0?usage.cacheRead/latestPromptTokens*100:void 0}getUsageTotals(){return this.usageTotals}appendMessage(message){let entry={type:"message",id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString(),message};this._appendEntry(entry);let order=this.entryOrdersById.get(entry.id);return order!==void 0&&this.messageEntryPositions.set(message,{entryId:entry.id,order}),entry.id}getMessageEntryPosition(message){return this.messageEntryPositions.get(message)}getEntryOrder(entryId){return this.entryOrdersById.get(entryId)}appendThinkingLevelChange(thinkingLevel,thinkingSelection){let entry={type:"thinking_level_change",id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString(),thinkingLevel,thinkingSelection};return this._appendEntry(entry),entry.id}appendConfigurationUpdate(effort){let entry={type:"configuration_update",id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString(),reasoning:{effort}};return this._appendEntry(entry),entry.id}appendModelChangeRejected(details){let entry={type:"model_change_rejected",id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString(),...details};return this._appendEntry(entry),entry.id}appendModelChange(provider,modelId,reason,originalProvider,originalModelId){let entry={type:"model_change",id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString(),provider,modelId,reason,originalProvider,originalModelId};return this._appendEntry(entry),entry.id}appendCompaction(summary,firstKeptEntryId,tokensBefore,details,fromHook,usage){let entry={type:"compaction",id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString(),summary,firstKeptEntryId,tokensBefore,details,usage,fromHook};return this._appendEntry(entry),this._trimMirrorAfterCompaction(entry),entry.id}dispose(){unregisterSessionWriter(this),this._releaseBlobsDirUnlessShared()}_releaseBlobsDirUnlessShared(){let blobsDir=this.residentStore.resolvedBlobsDir();blobsDir&&(this.sessionFile&&hasOtherLiveSessionWriter(this.sessionFile,this)||this._removeBlobsDir(blobsDir))}_removeBlobsDir(dir){try{rmSync2(dir,{force:!0,recursive:!0})}catch{}}_trimMirrorAfterCompaction(compaction){if(!this.persist)return;let firstKeptIndex=this.fileEntries.findIndex(entry=>entry.id===compaction.firstKeptEntryId),compactionIndex=this.fileEntries.findIndex(entry=>entry.id===compaction.id);if(firstKeptIndex<0||compactionIndex<firstKeptIndex)return;let header=this.fileEntries.find(entry=>entry.type==="session"),retained=[...this.fileEntries.slice(0,firstKeptIndex).filter(entry=>entry.type!=="message"),...this.fileEntries.slice(firstKeptIndex,compactionIndex+1)],parentId=null;for(let entry of retained)entry.type!=="session"&&(entry.parentId=parentId),parentId=entry.type==="session"?null:entry.id;this.residentStore.spillResident(),this.mirrorTrimmed=!0,this.fileEntries=[header,...retained].filter(entry=>entry!==void 0).map(entry=>this.residentStore.externalize(entry)),this._buildIndex(),this.mutationCount++}appendCustomEntry(customType,data){let entry={type:"custom",customType,data,id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString()};return this._appendEntry(entry),entry.id}appendSessionInfo(name){let sanitizedName=name.replace(/[\r\n]+/g," ").trim(),entry={type:"session_info",id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString(),name:sanitizedName};return this.sessionNameCache=sanitizedName||void 0,this._appendEntry(entry),entry.id}getSessionName(){return this.sessionNameCache}appendCustomMessageEntry(customType,content,display,details){let entry={type:"custom_message",customType,content,display,details,id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString()};return this._appendEntry(entry),entry.id}getLeafId(){return this.leafId}getLeafEntry(){let entry=this.leafId?this.byId.get(this.leafId):void 0;return entry?this._materializeEntry(entry):void 0}getEntry(id){let entry=this.byId.get(id);if(entry)return this._materializeEntry(entry);if(this.mirrorTrimmed&&this.sessionFile){let persisted=this._loadFullHistoryEntries().find(candidate=>candidate.id===id);return persisted?this.residentStore.materialize(persisted):void 0}}getChildren(parentId){let children=[];for(let entry of this.byId.values())entry.parentId===parentId&&children.push(this._materializeEntry(entry));return children}getLabel(id){return this.labelsById.get(id)}appendLabelChange(targetId,label){if(!this.byId.has(targetId))throw new Error(`Entry ${targetId} not found`);let entry={type:"label",id:generateId(this.byId),parentId:this.leafId,timestamp:new Date().toISOString(),targetId,label};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}getBranch(fromId){if(fromId===void 0&&this.branchCache!==null&&this.branchCache.leafId===this.leafId&&this.branchCache.mutation===this.mutationCount)return this.branchCache.entries;let path=[],startId=fromId??this.leafId,entriesById=this.byId;fromId!==void 0&&!entriesById.has(fromId)&&this.mirrorTrimmed&&this.sessionFile&&(entriesById=new Map(this._loadFullHistoryEntries().filter(entry=>entry.type!=="session").map(entry=>[entry.id,this.residentStore.materialize(entry)])));let current=startId?entriesById.get(startId):void 0;for(;current;)path.unshift(current),current=current.parentId?entriesById.get(current.parentId):void 0;let materializedPath=this._materializeEntries(path);return fromId===void 0&&(this.branchCache={leafId:this.leafId,mutation:this.mutationCount,entries:materializedPath}),materializedPath}buildContextEntries(){return buildContextEntries(this._getCompactEntries(),this.leafId)}buildSessionContext(){return buildSessionContext(this._getCompactEntries(),this.leafId)}hasContextMessages(){return this.hasBranchEntry(entry=>entry.type==="message"||entry.type==="custom_message"||entry.type==="compaction"||entry.type==="branch_summary"&&!!entry.summary)}hasThinkingLevelChanges(){return this.hasBranchEntry(entry=>entry.type==="thinking_level_change")}countCompactions(){let count=0;for(let entry of this.fileEntries)entry.type==="compaction"&&count++;return count}hasBranchEntry(predicate){let current=this.leafId?this.byId.get(this.leafId):void 0;for(;current;){if(predicate(current))return!0;current=current.parentId?this.byId.get(current.parentId):void 0}return!1}getHeader(){let h=this.fileEntries.find(e=>e.type==="session");return h?this.residentStore.materialize(h):null}getEntries(){if(this.mirrorTrimmed&&this.sessionFile)return this._loadFullHistoryEntries().filter(e=>e.type!=="session").map(entry=>this.residentStore.materialize(entry));if(this.entriesCache!==null&&this.entriesCache.mutation===this.mutationCount)return this.entriesCache.entries;let entries=this.fileEntries.filter(e=>e.type!=="session"),materializedEntries=this._materializeEntries(entries);return this.entriesCache={mutation:this.mutationCount,entries:materializedEntries},materializedEntries}getEntryCount(){return this.fullEntryCount}dropMaterializedCaches(){this.entriesCache=null,this.branchCache=null,this.compactEntriesCache=null}_materializeEntries(entries){return materializeSessionEntries(entries,{residentStore:this.residentStore,loadHistoryEntries:()=>this._loadFullHistoryEntries(),onMaterialized:entry=>{if(entry.type!=="message")return;let order=this.entryOrdersById.get(entry.id);order!==void 0&&this.messageEntryPositions.set(entry.message,{entryId:entry.id,order})}})}_getCompactEntries(){this.compactEntriesCache?.mutation!==this.mutationCount&&(this.compactEntriesCache={mutation:this.mutationCount,entries:this.fileEntries.filter(e=>e.type!=="session")});let entries=this.compactEntriesCache.entries,missingEntryIds=new Set;for(let entry of entries)this.residentStore.materialize(entry,()=>{missingEntryIds.add(entry.id)});if(missingEntryIds.size>0&&this.sessionFile){let persistedById=new Map(this._loadFullHistoryEntries().map(entry=>[entry.id,entry]));for(let index=0;index<entries.length;index++){let entry=entries[index];if(!missingEntryIds.has(entry.id))continue;let persisted=persistedById.get(entry.id);persisted&&(entries[index]=this.residentStore.externalize(persisted))}}let materialized=entries.map(entry=>this.residentStore.materialize(entry));for(let entry of materialized){if(entry.type!=="message")continue;let order=this.entryOrdersById.get(entry.id);order!==void 0&&this.messageEntryPositions.set(entry.message,{entryId:entry.id,order})}return materialized}_loadFullHistoryEntries(){return this.sessionFile?sessionEntryLoader(this.sessionFile):this.fileEntries}getTree(){let entries=this.getEntries(),nodeMap=new Map,roots=[];for(let entry of entries){let label=this.labelsById.get(entry.id),labelTimestamp=this.labelTimestampsById.get(entry.id);nodeMap.set(entry.id,{entry,children:[],label,labelTimestamp})}for(let entry of entries){let node=nodeMap.get(entry.id);if(entry.parentId===null||entry.parentId===entry.id)roots.push(node);else{let parent=nodeMap.get(entry.parentId);parent?parent.children.push(node):roots.push(node)}}let stack=[...roots];for(;stack.length>0;){let node=stack.pop();node.children.sort((a,b)=>new Date(a.entry.timestamp).getTime()-new Date(b.entry.timestamp).getTime()),stack.push(...node.children)}return roots}branch(branchFromId){if(!this.byId.has(branchFromId)&&this.sessionFile&&this.reloadFromDisk(),!this.byId.has(branchFromId))throw new Error(`Entry ${branchFromId} not found`);this.leafId=branchFromId,this.mutationCount++}resetLeaf(){this.leafId=null,this.mutationCount++}branchWithSummary(branchFromId,summary,details,fromHook,usage){if(branchFromId!==null&&!this.byId.has(branchFromId))throw new Error(`Entry ${branchFromId} not found`);let fromId=this.leafId??"root";this.leafId=branchFromId;let entry={type:"branch_summary",id:generateId(this.byId),parentId:branchFromId,timestamp:new Date().toISOString(),fromId,summary,details,usage,fromHook};return this._appendEntry(entry),entry.id}createBranchedSession(leafId){let previousSessionFile=this.sessionFile,path=this.getBranch(leafId);if(path.length===0)throw new Error(`Entry ${leafId} not found`);let pathWithoutLabels=[],replacementByLabelId=new Map,pendingLabelIds=[],pathParentId=null;for(let entry of path){if(entry.type==="label"){pendingLabelIds.push(entry.id);continue}for(let labelId of pendingLabelIds)replacementByLabelId.set(labelId,entry.id);pendingLabelIds.length=0,pathWithoutLabels.push(entry.type==="compaction"?{...entry,parentId:pathParentId,firstKeptEntryId:replacementByLabelId.get(entry.firstKeptEntryId)??entry.firstKeptEntryId}:{...entry,parentId:pathParentId}),pathParentId=entry.id}let newSessionId=createSessionId(),timestamp=new Date().toISOString(),fileTimestamp=timestamp.replace(/[:.]/g,"-"),newSessionFile=join4(this.getSessionDir(),`${fileTimestamp}_${newSessionId}.jsonl`),header={type:"session",version:CURRENT_SESSION_VERSION,id:newSessionId,timestamp,cwd:this.cwd,parentSession:this.persist?previousSessionFile:void 0},pathEntryIds=new Set(pathWithoutLabels.map(e=>e.id)),labelsToWrite=[];for(let[targetId,label]of this.labelsById)pathEntryIds.has(targetId)&&labelsToWrite.push({targetId,label,timestamp:this.labelTimestampsById.get(targetId)});if(this.persist){let parentId2=pathWithoutLabels[pathWithoutLabels.length-1]?.id||null,labelEntries2=[];for(let{targetId,label,timestamp:labelTimestamp}of labelsToWrite){let labelEntry={type:"label",id:generateId(new Set(pathEntryIds)),parentId:parentId2,timestamp:labelTimestamp,targetId,label};pathEntryIds.add(labelEntry.id),labelEntries2.push(labelEntry),parentId2=labelEntry.id}reserveSessionWrite(newSessionFile);let branchedEntries2=this._materializeEntries([...pathWithoutLabels,...labelEntries2]),previousBlobsDir=this.residentStore.resolvedBlobsDir();return this.residentStore.clear(),previousBlobsDir&&this._removeBlobsDir(previousBlobsDir),this.mirrorTrimmed=!1,this.sessionId=newSessionId,this.sessionFile=newSessionFile,this.fileEntries=[header,...branchedEntries2.map(entry=>this.residentStore.externalize(entry))],this._buildIndex(),this.mutationCount++,this.fileEntries.some(e=>e.type==="message"&&e.message.role==="assistant")?(this._rewriteFile(),this.flushed=!0):this.flushed=!1,newSessionFile}let labelEntries=[],parentId=pathWithoutLabels[pathWithoutLabels.length-1]?.id||null;for(let{targetId,label,timestamp:labelTimestamp}of labelsToWrite){let labelEntry={type:"label",id:generateId(new Set([...pathEntryIds,...labelEntries.map(e=>e.id)])),parentId,timestamp:labelTimestamp,targetId,label};labelEntries.push(labelEntry),parentId=labelEntry.id}let branchedEntries=this._materializeEntries([...pathWithoutLabels,...labelEntries]);this.residentStore.clear(),this.fileEntries=[header,...branchedEntries.map(entry=>this.residentStore.externalize(entry))],this.sessionId=newSessionId,this._buildIndex(),this.mutationCount++}static create(cwd,sessionDir,options){let dir=sessionDir?normalizePath(sessionDir):getDefaultSessionDir(cwd);return new _SessionManager(cwd,dir,void 0,!0,options)}static open(path,sessionDir,cwdOverride,options){let resolvedPath=resolvePath(path);reserveSessionWrite(resolvedPath);let header=null,preloadedFileEntries;if(cwdOverride===void 0&&existsSync3(resolvedPath))try{header=readSessionHeader(resolvedPath)}catch(error){if(!(error instanceof SessionHeaderScanLimitError))throw error;preloadedFileEntries=loadEntriesFromFile(resolvedPath);let firstEntry=preloadedFileEntries[0];header=firstEntry?.type==="session"?firstEntry:null}if(existsSync3(resolvedPath)){let content=readFileSync2(resolvedPath);content.length>0&&content[content.length-1]!==10&&appendFileSync(resolvedPath,`
34
+ `)}let cwd=cwdOverride??(header?getSessionHeaderCwd(header):void 0)??process.cwd(),dir=sessionDir?normalizePath(sessionDir):resolve2(resolvedPath,"..");return new _SessionManager(cwd,dir,resolvedPath,!0,options,preloadedFileEntries)}static continueRecent(cwd,sessionDir){let dir=sessionDir?normalizePath(sessionDir):getDefaultSessionDir(cwd),filterCwd=sessionDir!==void 0&&dir!==getDefaultSessionDirPath(cwd),mostRecent=findMostRecentSession(dir,filterCwd?cwd:void 0);return mostRecent?new _SessionManager(cwd,dir,mostRecent,!0):new _SessionManager(cwd,dir,void 0,!0)}static inMemory(cwd=process.cwd(),options,entries){return new _SessionManager(cwd,"",void 0,!1,options,entries)}static forkFrom(sourcePath,targetCwd,sessionDir,options){let resolvedSourcePath=resolvePath(sourcePath),resolvedTargetCwd=resolvePath(targetCwd),sourceEntries=loadEntriesFromFile(resolvedSourcePath);if(sourceEntries.length===0)throw new Error(`Cannot fork: source session file is empty or invalid: ${resolvedSourcePath}`);if(!sourceEntries.find(e=>e.type==="session"))throw new Error(`Cannot fork: source session has no header: ${resolvedSourcePath}`);let dir=sessionDir?normalizePath(sessionDir):getDefaultSessionDir(resolvedTargetCwd);existsSync3(dir)||mkdirSync2(dir,{recursive:!0}),options?.id!==void 0&&assertValidSessionId(options.id);let newSessionId=options?.id??createSessionId(),timestamp=new Date().toISOString(),fileTimestamp=timestamp.replace(/[:.]/g,"-"),newSessionFile=join4(dir,`${fileTimestamp}_${newSessionId}.jsonl`),newHeader={type:"session",version:CURRENT_SESSION_VERSION,id:newSessionId,timestamp,cwd:resolvedTargetCwd,parentSession:resolvedSourcePath};reserveSessionWrite(newSessionFile),writeFileSync2(newSessionFile,`${JSON.stringify(newHeader)}
29
35
  `,{flag:"wx"});for(let entry of sourceEntries)entry.type!=="session"&&appendFileSync(newSessionFile,`${JSON.stringify(entry)}
30
- `);return new _SessionManager(resolvedTargetCwd,dir,newSessionFile,!0)}static async list(cwd,sessionDir,onProgress){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));return sessions.sort((a,b)=>b.modified.getTime()-a.modified.getTime()),sessions}static async listAll(sessionDirOrOnProgress,onProgress){let customSessionDir=typeof sessionDirOrOnProgress=="string"?normalizePath(sessionDirOrOnProgress):void 0,progress=typeof sessionDirOrOnProgress=="function"?sessionDirOrOnProgress:onProgress;if(customSessionDir){let sessions=await listSessionsFromDir(customSessionDir,progress);return sessions.sort((a,b)=>b.modified.getTime()-a.modified.getTime()),sessions}let sessionsDir=getSessionsDir();try{if(!existsSync3(sessionsDir))return[];let dirs=(await readdir2(sessionsDir,{withFileTypes:!0})).filter(entry=>entry.isDirectory()||entry.isSymbolicLink()).map(entry=>join3(sessionsDir,entry.name)),totalFiles=0,dirFiles=[];for(let dir of dirs)try{let files=(await readdir2(dir)).filter(f=>f.endsWith(".jsonl"));dirFiles.push(files.map(f=>join3(dir,f))),totalFiles+=files.length}catch{dirFiles.push([])}let loaded=0,sessions=await listSessionInfos(dirFiles.flat(),()=>{loaded++,progress?.(loaded,totalFiles)});return sessions.sort((a,b)=>b.modified.getTime()-a.modified.getTime()),sessions}catch{return[]}}};var DEFAULT_MAX_LINES=2e3,DEFAULT_MAX_BYTES=51200;function splitLinesForCounting(content){if(content.length===0)return[];let lines=content.split(`
36
+ `);return new _SessionManager(resolvedTargetCwd,dir,newSessionFile,!0)}static async list(cwd,sessionDir,onProgress){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));return sessions.sort((a,b)=>b.modified.getTime()-a.modified.getTime()),sessions}static async listAll(sessionDirOrOnProgress,onProgress){let customSessionDir=typeof sessionDirOrOnProgress=="string"?normalizePath(sessionDirOrOnProgress):void 0,progress=typeof sessionDirOrOnProgress=="function"?sessionDirOrOnProgress:onProgress;if(customSessionDir){let sessions=await listSessionsFromDir(customSessionDir,progress);return sessions.sort((a,b)=>b.modified.getTime()-a.modified.getTime()),sessions}let sessionsDir=getSessionsDir();try{if(!existsSync3(sessionsDir))return[];let dirs=(await readdir2(sessionsDir,{withFileTypes:!0})).filter(entry=>entry.isDirectory()||entry.isSymbolicLink()).map(entry=>join4(sessionsDir,entry.name)),totalFiles=0,dirFiles=[];for(let dir of dirs)try{let files=(await readdir2(dir)).filter(f=>f.endsWith(".jsonl"));dirFiles.push(files.map(f=>join4(dir,f))),totalFiles+=files.length}catch{dirFiles.push([])}let loaded=0,onLoaded=()=>{loaded++,progress?.(loaded,totalFiles)},sessions=[];for(let[index,dir]of dirs.entries())sessions.push(...await listSessionFilesInDir(dir,dirFiles[index]??[],onLoaded));return sessions.sort((a,b)=>b.modified.getTime()-a.modified.getTime()),sessions}catch{return[]}}};var DEFAULT_MAX_LINES=2e3,DEFAULT_MAX_BYTES=51200;function splitLinesForCounting(content){if(content.length===0)return[];let lines=content.split(`
31
37
  `);return content.endsWith(`
32
38
  `)&&lines.pop(),lines}function formatSize(bytes){return bytes<1024?`${bytes}B`:bytes<1024*1024?`${(bytes/1024).toFixed(1)}KB`:`${(bytes/(1024*1024)).toFixed(1)}MB`}function truncateHead(content,options={}){let maxLines=options.maxLines??2e3,maxBytes=options.maxBytes??51200,totalBytes=Buffer.byteLength(content,"utf-8"),lines=splitLinesForCounting(content),totalLines=lines.length;if(totalLines<=maxLines&&totalBytes<=maxBytes)return{content,truncated:!1,truncatedBy:null,totalLines,totalBytes,outputLines:totalLines,outputBytes:totalBytes,lastLinePartial:!1,firstLineExceedsLimit:!1,maxLines,maxBytes};if(Buffer.byteLength(lines[0],"utf-8")>maxBytes)return{content:"",truncated:!0,truncatedBy:"bytes",totalLines,totalBytes,outputLines:0,outputBytes:0,lastLinePartial:!1,firstLineExceedsLimit:!0,maxLines,maxBytes};let outputLinesArr=[],outputBytesCount=0,truncatedBy="lines";for(let i=0;i<lines.length&&i<maxLines;i++){let line=lines[i],lineBytes=Buffer.byteLength(line,"utf-8")+(i>0?1:0);if(outputBytesCount+lineBytes>maxBytes){truncatedBy="bytes";break}outputLinesArr.push(line),outputBytesCount+=lineBytes}outputLinesArr.length>=maxLines&&outputBytesCount<=maxBytes&&(truncatedBy="lines");let outputContent=outputLinesArr.join(`
33
39
  `),finalOutputBytes=Buffer.byteLength(outputContent,"utf-8");return{content:outputContent,truncated:!0,truncatedBy,totalLines,totalBytes,outputLines:outputLinesArr.length,outputBytes:finalOutputBytes,lastLinePartial:!1,firstLineExceedsLimit:!1,maxLines,maxBytes}}function truncateTail(content,options={}){let maxLines=options.maxLines??2e3,maxBytes=options.maxBytes??51200,totalBytes=Buffer.byteLength(content,"utf-8"),lines=splitLinesForCounting(content),totalLines=lines.length;if(totalLines<=maxLines&&totalBytes<=maxBytes)return{content,truncated:!1,truncatedBy:null,totalLines,totalBytes,outputLines:totalLines,outputBytes:totalBytes,lastLinePartial:!1,firstLineExceedsLimit:!1,maxLines,maxBytes};let outputLinesArr=[],outputBytesCount=0,truncatedBy="lines",lastLinePartial=!1;for(let i=lines.length-1;i>=0&&outputLinesArr.length<maxLines;i--){let line=lines[i],lineBytes=Buffer.byteLength(line,"utf-8")+(outputLinesArr.length>0?1:0);if(outputBytesCount+lineBytes>maxBytes){if(truncatedBy="bytes",outputLinesArr.length===0){let truncatedLine=truncateStringToBytesFromEnd(line,maxBytes);outputLinesArr.unshift(truncatedLine),outputBytesCount=Buffer.byteLength(truncatedLine,"utf-8"),lastLinePartial=!0}break}outputLinesArr.unshift(line),outputBytesCount+=lineBytes}outputLinesArr.length>=maxLines&&outputBytesCount<=maxBytes&&(truncatedBy="lines");let outputContent=outputLinesArr.join(`
34
- `),finalOutputBytes=Buffer.byteLength(outputContent,"utf-8");return{content:outputContent,truncated:!0,truncatedBy,totalLines,totalBytes,outputLines:outputLinesArr.length,outputBytes:finalOutputBytes,lastLinePartial,firstLineExceedsLimit:!1,maxLines,maxBytes}}function truncateStringToBytesFromEnd(str,maxBytes){let buf=Buffer.from(str,"utf-8");if(buf.length<=maxBytes)return str;let start=buf.length-maxBytes;for(;start<buf.length&&(buf[start]&192)===128;)start++;return buf.slice(start).toString("utf-8")}function truncateLine(line,maxChars=500){return line.length<=maxChars?{text:line,wasTruncated:!1}:{text:`${line.slice(0,maxChars)}... [truncated]`,wasTruncated:!0}}import{randomBytes as randomBytes2}from"node:crypto";import{createWriteStream}from"node:fs";import{rm}from"node:fs/promises";import{tmpdir}from"node:os";import{join as join4}from"node:path";function ansiRegex({onlyFirst=!1}={}){let pattern="(?:\\u001B\\][\\s\\S]*?(?:\\u0007|\\u001B\\u005C|\\u009C))|[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]";return new RegExp(pattern,onlyFirst?void 0:"g")}var regex=ansiRegex();function stripAnsi(value){if(typeof value!="string")throw new TypeError(`Expected a \`string\`, got \`${typeof value}\``);return!value.includes("\x1B")&&!value.includes("\x9B")?value:value.replace(regex,"")}var NORMAL_CALLBACK_SETTLEMENT_TIMEOUT_MS=5e3;async function executeBashWithOperations(command,cwd,operations,options){let outputChunks=[],callbackAbortController=new AbortController,executionSignal=options?.signal?AbortSignal.any([options.signal,callbackAbortController.signal]):callbackAbortController.signal,callbackError,hasCallbackError=!1,callbacksAbandoned=!1,callbackPromises=new Set,waitForCallbacks=async allowAbandonment=>{if(callbackPromises.size===0)return!0;let settled=Promise.allSettled([...callbackPromises]).then(()=>!0),timeout,bounded=new Promise(resolve3=>{timeout=setTimeout(resolve3,allowAbandonment?100:NORMAL_CALLBACK_SETTLEMENT_TIMEOUT_MS,!1),timeout.unref?.()});try{return await Promise.race([settled,bounded])}finally{timeout&&clearTimeout(timeout)}},outputChunkStart=0,outputBytes=0,maxOutputBytes=51200*2,tempFilePath,tempFileStream,tempFileError,totalBytes=0,compactOutputChunks=()=>{outputChunkStart<64||(outputChunks.splice(0,outputChunkStart),outputChunkStart=0)},outputText=()=>outputChunks.slice(outputChunkStart).join(""),ensureTempFile=()=>{if(tempFilePath)return;let id=randomBytes2(8).toString("hex");tempFilePath=join4(tmpdir(),`pi-bash-${id}.log`),tempFileStream=createWriteStream(tempFilePath),tempFileStream.on("error",error=>{tempFileError??=error});for(let i=outputChunkStart;i<outputChunks.length;i++){let chunk=outputChunks[i];chunk!==void 0&&tempFileStream.write(chunk)}},closeTempFileStream=async()=>{let stream=tempFileStream;if(tempFileStream=void 0,!!stream){if(tempFileError)throw await new Promise(resolve3=>{if(stream.closed){resolve3();return}stream.once("close",resolve3),stream.destroy()}),tempFileError;await new Promise((resolve3,reject)=>{let finished=!1,closed=!1,streamError,settle=()=>{closed&&(stream.off("finish",onFinish),stream.off("error",onError),stream.off("close",onClose),streamError?reject(streamError):finished?resolve3():reject(new Error("Bash spill stream closed before finish")))},onError=error=>{streamError??=error},onFinish=()=>{finished=!0},onClose=()=>{closed=!0,!finished&&!stream.destroyed&&stream.destroy(),settle()};stream.once("error",onError),stream.once("finish",onFinish),stream.once("close",onClose),stream.end()})}},removeTempFile=async()=>{if(!tempFilePath)return;await rm(tempFilePath,{force:!0}),tempFilePath=void 0},closeTempFileAndCleanup=async primaryError=>{let finalError=primaryError;try{await closeTempFileStream()}catch(closeError){finalError=new AggregateError([primaryError,closeError],"Bash output cleanup failed")}try{await removeTempFile()}catch(unlinkError){finalError=new AggregateError([finalError,unlinkError],"Bash output cleanup failed")}throw finalError},decoder=new TextDecoder,onData=data=>{if(callbackAbortController.signal.aborted)return;totalBytes+=data.length;let text=sanitizeBinaryOutput(stripAnsi(decoder.decode(data,{stream:!0}))).replace(/\r/g,"");for(totalBytes>51200&&ensureTempFile(),tempFileStream&&tempFileStream.write(text),outputChunks.push(text),outputBytes+=text.length;outputBytes>maxOutputBytes&&outputChunkStart<outputChunks.length-1;){let removed=outputChunks[outputChunkStart];if(removed===void 0)break;outputBytes-=removed.length,outputChunkStart++}if(compactOutputChunks(),options?.onChunk)try{let callbackResult=options.onChunk(text);if(callbackResult&&typeof callbackResult.then=="function"){let callbackPromise=Promise.resolve(callbackResult).then(()=>{},error=>{throw hasCallbackError||(callbackError=error,hasCallbackError=!0),callbacksAbandoned&&process.emitWarning(`Bash output callback rejected after the command timeout: ${error instanceof Error?error.message:String(error)}`,{code:"BASH_CALLBACK_ERROR"}),callbackAbortController.abort(),error});return callbackPromises.add(callbackPromise),callbackPromise.catch(()=>{}).finally(()=>callbackPromises.delete(callbackPromise)),callbackPromise}}catch(error){throw hasCallbackError||(callbackError=error,hasCallbackError=!0),callbackAbortController.abort(),error}},finishDecoder=()=>{let finalText=sanitizeBinaryOutput(stripAnsi(decoder.decode())).replace(/\r/g,"");finalText.length>0&&onData(Buffer.from(finalText,"utf-8"))},prepareFinalOutput=async()=>{try{finishDecoder();let fullOutput2=outputText(),truncationResult2=truncateTail(fullOutput2);return truncationResult2.truncated&&ensureTempFile(),{fullOutput:fullOutput2,truncationResult:truncationResult2}}catch(error){return await closeTempFileAndCleanup(error)}},result;try{result=await operations.exec(command,cwd,{onData,signal:executionSignal})}catch(err){if(await waitForCallbacks(options?.signal?.aborted===!0),hasCallbackError)return await closeTempFileAndCleanup(callbackError);if(options?.signal?.aborted){let{fullOutput:fullOutput2,truncationResult:truncationResult2}=await prepareFinalOutput();try{await closeTempFileStream()}catch(error){return await closeTempFileAndCleanup(error)}try{await removeTempFile()}catch(cleanupError){throw new AggregateError([cleanupError],"Bash output cleanup failed")}return{output:truncationResult2.truncated?truncationResult2.content:fullOutput2,exitCode:void 0,cancelled:!0,truncated:truncationResult2.truncated}}return await closeTempFileAndCleanup(err)}if(!await waitForCallbacks(!1))return callbacksAbandoned=!0,await closeTempFileAndCleanup(new Error(`Bash output callback did not settle within ${NORMAL_CALLBACK_SETTLEMENT_TIMEOUT_MS}ms`));if(hasCallbackError)return await closeTempFileAndCleanup(callbackError);let{fullOutput,truncationResult}=await prepareFinalOutput();try{await closeTempFileStream()}catch(error){return await closeTempFileAndCleanup(error)}let cancelled=options?.signal?.aborted??!1;return{output:truncationResult.truncated?truncationResult.content:fullOutput,exitCode:cancelled?void 0:result.exitCode??void 0,cancelled,truncated:truncationResult.truncated,fullOutputPath:tempFilePath}}import{existsSync as existsSync4}from"node:fs";function getMissingSessionCwdIssue(sessionManager,fallbackCwd){let sessionFile=sessionManager.getSessionFile();if(!sessionFile)return;let sessionCwd=sessionManager.getCwd();if(!(!sessionCwd||existsSync4(sessionCwd)))return{sessionFile,sessionCwd,fallbackCwd}}function formatMissingSessionCwdError(issue){let sessionFile=issue.sessionFile?`
40
+ `),finalOutputBytes=Buffer.byteLength(outputContent,"utf-8");return{content:outputContent,truncated:!0,truncatedBy,totalLines,totalBytes,outputLines:outputLinesArr.length,outputBytes:finalOutputBytes,lastLinePartial,firstLineExceedsLimit:!1,maxLines,maxBytes}}function truncateStringToBytesFromEnd(str,maxBytes){let buf=Buffer.from(str,"utf-8");if(buf.length<=maxBytes)return str;let start=buf.length-maxBytes;for(;start<buf.length&&(buf[start]&192)===128;)start++;return buf.slice(start).toString("utf-8")}function truncateLine(line,maxChars=500){return line.length<=maxChars?{text:line,wasTruncated:!1}:{text:`${line.slice(0,maxChars)}... [truncated]`,wasTruncated:!0}}import{randomBytes as randomBytes2}from"node:crypto";import{createWriteStream}from"node:fs";import{rm as rm2}from"node:fs/promises";import{tmpdir}from"node:os";import{join as join5}from"node:path";function ansiRegex({onlyFirst=!1}={}){let pattern="(?:\\u001B\\][\\s\\S]*?(?:\\u0007|\\u001B\\u005C|\\u009C))|[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]";return new RegExp(pattern,onlyFirst?void 0:"g")}var regex=ansiRegex();function stripAnsi(value){if(typeof value!="string")throw new TypeError(`Expected a \`string\`, got \`${typeof value}\``);return!value.includes("\x1B")&&!value.includes("\x9B")?value:value.replace(regex,"")}var NORMAL_CALLBACK_SETTLEMENT_TIMEOUT_MS=5e3;async function executeBashWithOperations(command,cwd,operations,options){let outputChunks=[],callbackAbortController=new AbortController,executionSignal=options?.signal?AbortSignal.any([options.signal,callbackAbortController.signal]):callbackAbortController.signal,callbackError,hasCallbackError=!1,callbacksAbandoned=!1,callbackPromises=new Set,waitForCallbacks=async allowAbandonment=>{if(callbackPromises.size===0)return!0;let settled=Promise.allSettled([...callbackPromises]).then(()=>!0),timeout,bounded=new Promise(resolve3=>{timeout=setTimeout(resolve3,allowAbandonment?100:NORMAL_CALLBACK_SETTLEMENT_TIMEOUT_MS,!1),timeout.unref?.()});try{return await Promise.race([settled,bounded])}finally{timeout&&clearTimeout(timeout)}},outputChunkStart=0,outputBytes=0,maxOutputBytes=51200*2,tempFilePath,tempFileStream,tempFileError,totalBytes=0,compactOutputChunks=()=>{outputChunkStart<64||(outputChunks.splice(0,outputChunkStart),outputChunkStart=0)},outputText=()=>outputChunks.slice(outputChunkStart).join(""),ensureTempFile=()=>{if(tempFilePath)return;let id=randomBytes2(8).toString("hex");tempFilePath=join5(tmpdir(),`pi-bash-${id}.log`),tempFileStream=createWriteStream(tempFilePath),tempFileStream.on("error",error=>{tempFileError??=error});for(let i=outputChunkStart;i<outputChunks.length;i++){let chunk=outputChunks[i];chunk!==void 0&&tempFileStream.write(chunk)}},closeTempFileStream=async()=>{let stream=tempFileStream;if(tempFileStream=void 0,!!stream){if(tempFileError)throw await new Promise(resolve3=>{if(stream.closed){resolve3();return}stream.once("close",resolve3),stream.destroy()}),tempFileError;await new Promise((resolve3,reject)=>{let finished=!1,closed=!1,streamError,settle=()=>{closed&&(stream.off("finish",onFinish),stream.off("error",onError),stream.off("close",onClose),streamError?reject(streamError):finished?resolve3():reject(new Error("Bash spill stream closed before finish")))},onError=error=>{streamError??=error},onFinish=()=>{finished=!0},onClose=()=>{closed=!0,!finished&&!stream.destroyed&&stream.destroy(),settle()};stream.once("error",onError),stream.once("finish",onFinish),stream.once("close",onClose),stream.end()})}},removeTempFile=async()=>{if(!tempFilePath)return;await rm2(tempFilePath,{force:!0}),tempFilePath=void 0},closeTempFileAndCleanup=async primaryError=>{let finalError=primaryError;try{await closeTempFileStream()}catch(closeError){finalError=new AggregateError([primaryError,closeError],"Bash output cleanup failed")}try{await removeTempFile()}catch(unlinkError){finalError=new AggregateError([finalError,unlinkError],"Bash output cleanup failed")}throw finalError},decoder=new TextDecoder,onData=data=>{if(callbackAbortController.signal.aborted)return;totalBytes+=data.length;let text=sanitizeBinaryOutput(stripAnsi(decoder.decode(data,{stream:!0}))).replace(/\r/g,"");for(totalBytes>51200&&ensureTempFile(),tempFileStream&&tempFileStream.write(text),outputChunks.push(text),outputBytes+=text.length;outputBytes>maxOutputBytes&&outputChunkStart<outputChunks.length-1;){let removed=outputChunks[outputChunkStart];if(removed===void 0)break;outputBytes-=removed.length,outputChunkStart++}if(compactOutputChunks(),options?.onChunk)try{let callbackResult=options.onChunk(text);if(callbackResult&&typeof callbackResult.then=="function"){let callbackPromise=Promise.resolve(callbackResult).then(()=>{},error=>{throw hasCallbackError||(callbackError=error,hasCallbackError=!0),callbacksAbandoned&&process.emitWarning(`Bash output callback rejected after the command timeout: ${error instanceof Error?error.message:String(error)}`,{code:"BASH_CALLBACK_ERROR"}),callbackAbortController.abort(),error});return callbackPromises.add(callbackPromise),callbackPromise.catch(()=>{}).finally(()=>callbackPromises.delete(callbackPromise)),callbackPromise}}catch(error){throw hasCallbackError||(callbackError=error,hasCallbackError=!0),callbackAbortController.abort(),error}},finishDecoder=()=>{let finalText=sanitizeBinaryOutput(stripAnsi(decoder.decode())).replace(/\r/g,"");finalText.length>0&&onData(Buffer.from(finalText,"utf-8"))},prepareFinalOutput=async()=>{try{finishDecoder();let fullOutput2=outputText(),truncationResult2=truncateTail(fullOutput2);return truncationResult2.truncated&&ensureTempFile(),{fullOutput:fullOutput2,truncationResult:truncationResult2}}catch(error){return await closeTempFileAndCleanup(error)}},result;try{result=await operations.exec(command,cwd,{onData,signal:executionSignal})}catch(err){if(await waitForCallbacks(options?.signal?.aborted===!0),hasCallbackError)return await closeTempFileAndCleanup(callbackError);if(options?.signal?.aborted){let{fullOutput:fullOutput2,truncationResult:truncationResult2}=await prepareFinalOutput();try{await closeTempFileStream()}catch(error){return await closeTempFileAndCleanup(error)}try{await removeTempFile()}catch(cleanupError){throw new AggregateError([cleanupError],"Bash output cleanup failed")}return{output:truncationResult2.truncated?truncationResult2.content:fullOutput2,exitCode:void 0,cancelled:!0,truncated:truncationResult2.truncated}}return await closeTempFileAndCleanup(err)}if(!await waitForCallbacks(!1))return callbacksAbandoned=!0,await closeTempFileAndCleanup(new Error(`Bash output callback did not settle within ${NORMAL_CALLBACK_SETTLEMENT_TIMEOUT_MS}ms`));if(hasCallbackError)return await closeTempFileAndCleanup(callbackError);let{fullOutput,truncationResult}=await prepareFinalOutput();try{await closeTempFileStream()}catch(error){return await closeTempFileAndCleanup(error)}let cancelled=options?.signal?.aborted??!1;return{output:truncationResult.truncated?truncationResult.content:fullOutput,exitCode:cancelled?void 0:result.exitCode??void 0,cancelled,truncated:truncationResult.truncated,fullOutputPath:tempFilePath}}import{existsSync as existsSync4}from"node:fs";function getMissingSessionCwdIssue(sessionManager,fallbackCwd){let sessionFile=sessionManager.getSessionFile();if(!sessionFile)return;let sessionCwd=sessionManager.getCwd();if(!(!sessionCwd||existsSync4(sessionCwd)))return{sessionFile,sessionCwd,fallbackCwd}}function formatMissingSessionCwdError(issue){let sessionFile=issue.sessionFile?`
35
41
  Session file: ${issue.sessionFile}`:"";return`Stored session working directory does not exist: ${issue.sessionCwd}${sessionFile}
36
42
  Current working directory: ${issue.fallbackCwd}`}function formatMissingSessionCwdPrompt(issue){return`cwd from session file does not exist
37
43
  ${issue.sessionCwd}
@@ -1,5 +1,5 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{HOST_PROTOCOL_VERSION,HostEnsureRefusedError,REQUIRED_HOST_CAPABILITIES,decideHostAction,ensureHost,handoffHost,probeProtocolInfo,requestOnSocket,stopHost}from"./chunk-3XHWW7SQ.js";import{createHostDaemonPaths,parseJson,pruneDeadGenerations,readFileOrUndefined,readGenerationRows,readHostProcessMetrics,writeStateFile}from"./chunk-7PANH3NB.js";import{engineBuildIdentity}from"./chunk-NNHFMZD5.js";import{isSessionRuntimeKind}from"./chunk-VKBY4F76.js";import{APP_NAME,envValue,getAgentDir}from"./chunk-Y65WFI5H.js";import{writeSync}from"node:fs";import{resolve as resolve2}from"node:path";import{readFile,realpath,stat}from"node:fs/promises";import{dirname,isAbsolute,relative,resolve}from"node:path";var SPEC_ENV_NAME=/^(SENPI|OMO|PI)_[A-Z0-9_]+$/u,HostLaunchSpecError=class extends Error{constructor(reason,detail){super(`${reason}: ${detail}`),this.name="HostLaunchSpecError",this.reason=reason,this.detail=detail}},DEFAULT_HOST_LAUNCH_SPEC={hostArgs:[],policy:{},env:{}};async function loadHostLaunchSpec(specPath,platform=process.platform){let absolute=resolve(specPath);await assertTrustedFile(absolute,platform);let spec=parseHostLaunchSpec(await readSpecText(absolute)),env=trustedEnv(spec.env),extensions=await resolveExtensions(spec.core.extensions,dirname(absolute));return{hostArgs:["--session-runtime",spec.core.session_runtime,...extensions.flatMap(path=>["--extension",path])],policy:{...spec.tunables?.idleExitMs!==void 0&&{idleExitMs:spec.tunables.idleExitMs},...spec.tunables?.coldStart!==void 0&&{coldStart:spec.tunables.coldStart}},env}}function parseHostLaunchSpec(text){let parsed;try{parsed=JSON.parse(text)}catch(error){throw new HostLaunchSpecError("launch_spec_invalid",error instanceof Error?error.message:"not JSON")}if(!isRecord(parsed))throw new HostLaunchSpecError("launch_spec_invalid","the spec is not a JSON object");if(parsed.spec_version!==1)throw new HostLaunchSpecError("launch_spec_invalid",`unsupported spec_version ${String(parsed.spec_version)}`);let core=parsed.core;if(!isRecord(core))throw new HostLaunchSpecError("launch_spec_invalid","core must be an object");if(typeof core.session_runtime!="string"||!isSessionRuntimeKind(core.session_runtime))throw new HostLaunchSpecError("launch_spec_invalid","core.session_runtime must be in-process or worker");if(core.multi_session!==!0)throw new HostLaunchSpecError("launch_spec_invalid","core.multi_session must be true");if(!Array.isArray(core.extensions)||!core.extensions.every(entry=>typeof entry=="string"))throw new HostLaunchSpecError("launch_spec_invalid","core.extensions must be an array of strings");let tunables=parsedTunables(parsed.tunables);return{spec_version:1,core:{session_runtime:core.session_runtime,multi_session:!0,extensions:core.extensions},...tunables&&{tunables},...isRecord(parsed.env)&&{env:parsedEnv(parsed.env)}}}async function readSpecText(absolute){try{return await readFile(absolute,"utf8")}catch(error){throw new HostLaunchSpecError("launch_spec_unreadable",error instanceof Error?error.message:absolute)}}async function assertTrustedFile(absolute,platform){if(platform==="win32")return;let stats=await stat(absolute).catch(error=>{throw new HostLaunchSpecError("launch_spec_unreadable",error instanceof Error?error.message:absolute)}),uid=process.getuid?.();if(uid!==void 0&&stats.uid!==uid)throw new HostLaunchSpecError("launch_spec_insecure",`${absolute} is owned by uid ${stats.uid}, not ${uid}`);if((stats.mode&18)!==0)throw new HostLaunchSpecError("launch_spec_insecure",`${absolute} is group/world writable (mode ${(stats.mode&511).toString(8)})`)}function trustedEnv(env){for(let name of Object.keys(env??{}))if(!SPEC_ENV_NAME.test(name))throw new HostLaunchSpecError("launch_spec_env_denied",`${name} is outside ${SPEC_ENV_NAME.source}`);return env??{}}async function resolveExtensions(extensions,specDir){let rootReal=await realpath(specDir).catch(()=>specDir),resolved=[];for(let entry of extensions){let target=resolve(specDir,entry);if(escapes(specDir,target))throw new HostLaunchSpecError("launch_spec_path_escape",`${entry} resolves outside ${specDir}`);let real=await realpath(target).catch(()=>{});if(real===void 0)throw new HostLaunchSpecError("launch_spec_missing_extension",`${target} does not exist`);if(escapes(rootReal,real))throw new HostLaunchSpecError("launch_spec_path_escape",`${entry} links outside ${specDir}`);resolved.push(real)}return resolved}function escapes(root,target){let step=relative(root,target);return step.startsWith("..")||isAbsolute(step)}function parsedTunables(value){if(!isRecord(value))return;let idleExitMs=value.idleExitMs,coldStart=value.coldStart;return{...typeof idleExitMs=="number"&&Number.isFinite(idleExitMs)&&idleExitMs>0&&{idleExitMs},...(coldStart==="transient"||coldStart==="persistent")&&{coldStart}}}function parsedEnv(value){let env={};for(let[name,entry]of Object.entries(value)){if(typeof entry!="string")throw new HostLaunchSpecError("launch_spec_invalid",`env.${name} must be a string`);env[name]=entry}return env}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}import{join}from"node:path";var ALLOWED_ENV_NAMES=[/^(PATH|HOME|USER|LOGNAME|SHELL|TMPDIR|TERM|LANG)$/u,/^(LC|XDG)_/u,/^(SENPI|OMO|PI)_/u,/^(HTTPS?_PROXY|NO_PROXY)$/u,/^[A-Z0-9_]+_API_KEY$/u,/^(ANTHROPIC|OPENAI|GOOGLE|GEMINI|AZURE|AWS|OPENROUTER|XAI|MISTRAL|DEEPSEEK|GROQ|CEREBRAS|MINIMAX)_/u],WINDOWS_SYSTEM_ENV_NAMES=new Set(["SYSTEMROOT","SYSTEMDRIVE","WINDIR","COMSPEC","PATHEXT","TEMP","TMP","USERPROFILE","APPDATA","LOCALAPPDATA","PROGRAMFILES","PROGRAMFILES(X86)","PROGRAMDATA","HOMEDRIVE","HOMEPATH","NUMBER_OF_PROCESSORS","PROCESSOR_ARCHITECTURE","OS"]);function daemonEnvIsAllowed(name,platform=process.platform){if(platform!=="win32")return ALLOWED_ENV_NAMES.some(pattern=>pattern.test(name));let upper=name.toUpperCase();return WINDOWS_SYSTEM_ENV_NAMES.has(upper)||ALLOWED_ENV_NAMES.some(pattern=>pattern.test(upper))}function daemonEnvOverrides(processEnv,specEnv={},platform=process.platform){let overrides={};for(let name of Object.keys(processEnv))daemonEnvIsAllowed(name,platform)||(overrides[name]=null);for(let[name,value]of Object.entries(specEnv))overrides[name]=value;return overrides}function daemonEnvKeys(processEnv,specEnv={},platform=process.platform){let kept=Object.keys(processEnv).filter(name=>daemonEnvIsAllowed(name,platform));return[...new Set([...kept,...Object.keys(specEnv)])].sort()}async function writeDaemonEnvKeys(paths,keys){await writeStateFile(daemonEnvKeysFile(paths),{env_keys:keys})}async function readDaemonEnvKeys(paths){let keys=parseJson(await readFileOrUndefined(daemonEnvKeysFile(paths)))?.env_keys;return Array.isArray(keys)?keys.filter(key=>typeof key=="string"):[]}function daemonEnvKeysFile(paths){return join(paths.dir,"env-keys.json")}var STATUS_PROBE_TIMEOUT_MS=1e4;async function readHostStatus(options){let paths=createHostDaemonPaths({socket:options.socket,...options.agentDir?{agentDir:options.agentDir}:{}}),host=await probeProtocolInfo(options.socket,STATUS_PROBE_TIMEOUT_MS);await pruneDeadGenerations(paths);let generations=await readGenerationRows(paths),current=generations.find(row=>row.current),metrics=current?await readHostProcessMetrics(current.pid):UNOBSERVED_METRICS;return{reachable:host!==void 0,socket:options.socket,pid:current?.pid??null,instanceId:host?.instanceId??current?.instanceId??null,generation:host?.generation??current?.generation??null,engineVersion:host?.engineVersion??current?.engineVersion??null,capabilities:host?.capabilities??[],launchProfile:host?.launch_profile??null,sessions:await readSessionCounts(options.socket,options.includeWorkers===!0),zombies:metrics.zombies,rss_mb:metrics.rss_mb,open_fds:metrics.open_fds,env_keys:await readDaemonEnvKeys(paths),generations}}async function readSessionCounts(socket,includeWorkers){let reply=await requestOnSocket(socket,{type:"list_sessions",...includeWorkers?{include_workers:!0}:{}},STATUS_PROBE_TIMEOUT_MS),rows=sessionRows(reply),attached=rows.filter(row=>row.attachments>0).length,retained=rows.length-attached;return{total:rows.length,interactive:rows.filter(row=>row.kind!=="worker").length,worker:rows.filter(row=>row.kind==="worker").length,retained,foreign_attached:attached,foreign_retained:retained}}function hostSummary(host){return host===void 0?null:{protocolVersion:host.protocolVersion,serverVersion:host.serverVersion,capabilities:host.capabilities,instanceId:host.instanceId??null,generation:host.generation??null,engineVersion:host.engineVersion??null,launchProfileId:host.launch_profile?.profile_id??null}}var UNOBSERVED_METRICS={rss_mb:null,open_fds:null,zombies:null};function sessionRows(reply){return!isRecord2(reply)||!Array.isArray(reply.sessions)?[]:reply.sessions.flatMap(entry=>isRecord2(entry)?[{kind:typeof entry.kind=="string"?entry.kind:"interactive",attachments:typeof entry.attachments=="number"?entry.attachments:0}]:[])}function isRecord2(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}var HOST_EXIT_OK=0,HOST_EXIT_ERROR=1,HOST_EXIT_USAGE=2,HOST_EXIT_REFUSED=3,HOST_EXIT_FALLBACK=4,PROBE_TIMEOUT_MS=1e4;async function runHostRequest(request){switch(request.action){case"ensure":return ensureOutcome(request.target,request.spec,request.policy);case"status":return statusOutcome(request.target,request.includeWorkers);case"stop":return stopOutcome(request.target,request.drain,request.force);case"handoff":return handoffOutcome(request.target,request.spec);default:return assertNever(request)}}async function ensureOutcome(target,spec,policy){let before=await probeProtocolInfo(target.socket,PROBE_TIMEOUT_MS);if(policy==="fallback"){let decision=decideHostAction(decisionClient(),before,"fallback");if(decision.action==="fallback")return refusal("fallback",before,{reason:decision.reason,socket:target.socket})}let ensured;try{ensured=await ensureHost({socket:target.socket,agentDir:target.agentDir,hostArgs:spec.hostArgs,env:daemonEnvOverrides(process.env,spec.env),policy:spec.policy,upgrade:policy==="upgrade"?"if-engine-differs":"never"})}catch(error){if(!(error instanceof HostEnsureRefusedError))throw error;return refusal("refuse",before,{reason:error.reason,socket:target.socket})}let host=await probeProtocolInfo(target.socket,PROBE_TIMEOUT_MS);return ensured.reused||await recordEnvScope(target,spec),{exitCode:HOST_EXIT_OK,payload:{action:ensureAction(ensured.reused,before,host),...identityPayload(target.socket,ensured.pid,host),reused:ensured.reused}}}function ensureAction(reused,before,after){return reused?"reuse":before!==void 0&&before.instanceId!==after?.instanceId?"handoff":"start"}async function statusOutcome(target,includeWorkers){let status=await readHostStatus({socket:target.socket,agentDir:target.agentDir,includeWorkers});return{exitCode:status.reachable?HOST_EXIT_OK:HOST_EXIT_REFUSED,payload:{...status}}}async function stopOutcome(target,drain,force){let host=await probeProtocolInfo(target.socket,PROBE_TIMEOUT_MS),sessions=await readSessionCounts(target.socket,!0),occupied=sessions.foreign_attached+sessions.foreign_retained>0;if(!drain&&!force&&occupied)return refusal("refuse",host,{reason:"sessions_live",socket:target.socket,sessions});let result=await stopHost({socket:target.socket,agentDir:target.agentDir,drain,force});return result.action==="refuse"?refusal("refuse",host,{reason:result.reason,socket:target.socket,sessions}):{exitCode:HOST_EXIT_OK,payload:{action:result.action,socket:target.socket,pid:result.pid,sessions}}}async function handoffOutcome(target,spec){let before=await probeProtocolInfo(target.socket,PROBE_TIMEOUT_MS),result=await handoffHost({socket:target.socket,agentDir:target.agentDir,hostArgs:spec.hostArgs,env:daemonEnvOverrides(process.env,spec.env),policy:spec.policy});if(result.action==="refuse")return refusal("refuse",before,{reason:upgradeRefusal(result.reason),socket:target.socket,detail:result.reason,upgradeable:result.upgradeable});await recordEnvScope(target,spec);let host=await probeProtocolInfo(target.socket,PROBE_TIMEOUT_MS);return{exitCode:HOST_EXIT_OK,payload:{action:"handoff",...identityPayload(target.socket,result.pid,host),reused:!1}}}function upgradeRefusal(reason){return reason==="handoff_unsupported"?"upgrade_unsupported":reason}function identityPayload(socket,pid,host){return{socket,pid,instanceId:host?.instanceId??null,generation:host?.generation??null,engineVersion:host?.engineVersion??null,engineOrdinal:host?.engineOrdinal??null,capabilities:host?.capabilities??[],launchProfileId:host?.launch_profile?.profile_id??null,upgradeable:decideHostAction(decisionClient(),host,"upgrade").upgradeable}}function refusal(kind,host,body){return{exitCode:kind==="refuse"?HOST_EXIT_REFUSED:HOST_EXIT_FALLBACK,payload:{action:kind,...body,host:hostSummary(host)}}}async function recordEnvScope(target,spec){let paths=createHostDaemonPaths({socket:target.socket,agentDir:target.agentDir});await writeDaemonEnvKeys(paths,daemonEnvKeys(process.env,spec.env))}function decisionClient(){return{protocolVersion:HOST_PROTOCOL_VERSION,requiredCapabilities:REQUIRED_HOST_CAPABILITIES,identity:engineBuildIdentity(),startedByUs:!1,platform:process.platform}}function assertNever(value){throw new Error(`unreachable host request: ${JSON.stringify(value)}`)}var SUBCOMMANDS=["ensure","status","stop","handoff"],POLICIES=["upgrade","fallback","never"],USAGE=`usage: ${APP_NAME} host <ensure|status|stop|handoff> [options]
2
+ import{HOST_PROTOCOL_VERSION,HostEnsureRefusedError,REQUIRED_HOST_CAPABILITIES,decideHostAction,ensureHost,handoffHost,probeProtocolInfo,requestOnSocket,stopHost}from"./chunk-CLZVNQW3.js";import{createHostDaemonPaths,parseJson,pruneDeadGenerations,readFileOrUndefined,readGenerationRows,readHostProcessMetrics,writeStateFile}from"./chunk-3WBSBDBX.js";import{engineBuildIdentity}from"./chunk-UBPMXBOJ.js";import{isSessionRuntimeKind}from"./chunk-BSOJHK4W.js";import{APP_NAME,envValue,getAgentDir}from"./chunk-Y65WFI5H.js";import{writeSync}from"node:fs";import{resolve as resolve2}from"node:path";import{readFile,realpath,stat}from"node:fs/promises";import{dirname,isAbsolute,relative,resolve}from"node:path";var SPEC_ENV_NAME=/^(SENPI|OMO|PI)_[A-Z0-9_]+$/u,HostLaunchSpecError=class extends Error{constructor(reason,detail){super(`${reason}: ${detail}`),this.name="HostLaunchSpecError",this.reason=reason,this.detail=detail}},DEFAULT_HOST_LAUNCH_SPEC={hostArgs:[],policy:{},env:{}};async function loadHostLaunchSpec(specPath,platform=process.platform){let absolute=resolve(specPath);await assertTrustedFile(absolute,platform);let spec=parseHostLaunchSpec(await readSpecText(absolute)),env=trustedEnv(spec.env),extensions=await resolveExtensions(spec.core.extensions,dirname(absolute));return{hostArgs:["--session-runtime",spec.core.session_runtime,...extensions.flatMap(path=>["--extension",path])],policy:{...spec.tunables?.idleExitMs!==void 0&&{idleExitMs:spec.tunables.idleExitMs},...spec.tunables?.coldStart!==void 0&&{coldStart:spec.tunables.coldStart}},env}}function parseHostLaunchSpec(text){let parsed;try{parsed=JSON.parse(text)}catch(error){throw new HostLaunchSpecError("launch_spec_invalid",error instanceof Error?error.message:"not JSON")}if(!isRecord(parsed))throw new HostLaunchSpecError("launch_spec_invalid","the spec is not a JSON object");if(parsed.spec_version!==1)throw new HostLaunchSpecError("launch_spec_invalid",`unsupported spec_version ${String(parsed.spec_version)}`);let core=parsed.core;if(!isRecord(core))throw new HostLaunchSpecError("launch_spec_invalid","core must be an object");if(typeof core.session_runtime!="string"||!isSessionRuntimeKind(core.session_runtime))throw new HostLaunchSpecError("launch_spec_invalid","core.session_runtime must be in-process or worker");if(core.multi_session!==!0)throw new HostLaunchSpecError("launch_spec_invalid","core.multi_session must be true");if(!Array.isArray(core.extensions)||!core.extensions.every(entry=>typeof entry=="string"))throw new HostLaunchSpecError("launch_spec_invalid","core.extensions must be an array of strings");let tunables=parsedTunables(parsed.tunables);return{spec_version:1,core:{session_runtime:core.session_runtime,multi_session:!0,extensions:core.extensions},...tunables&&{tunables},...isRecord(parsed.env)&&{env:parsedEnv(parsed.env)}}}async function readSpecText(absolute){try{return await readFile(absolute,"utf8")}catch(error){throw new HostLaunchSpecError("launch_spec_unreadable",error instanceof Error?error.message:absolute)}}async function assertTrustedFile(absolute,platform){if(platform==="win32")return;let stats=await stat(absolute).catch(error=>{throw new HostLaunchSpecError("launch_spec_unreadable",error instanceof Error?error.message:absolute)}),uid=process.getuid?.();if(uid!==void 0&&stats.uid!==uid)throw new HostLaunchSpecError("launch_spec_insecure",`${absolute} is owned by uid ${stats.uid}, not ${uid}`);if((stats.mode&18)!==0)throw new HostLaunchSpecError("launch_spec_insecure",`${absolute} is group/world writable (mode ${(stats.mode&511).toString(8)})`)}function trustedEnv(env){for(let name of Object.keys(env??{}))if(!SPEC_ENV_NAME.test(name))throw new HostLaunchSpecError("launch_spec_env_denied",`${name} is outside ${SPEC_ENV_NAME.source}`);return env??{}}async function resolveExtensions(extensions,specDir){let rootReal=await realpath(specDir).catch(()=>specDir),resolved=[];for(let entry of extensions){let target=resolve(specDir,entry);if(escapes(specDir,target))throw new HostLaunchSpecError("launch_spec_path_escape",`${entry} resolves outside ${specDir}`);let real=await realpath(target).catch(()=>{});if(real===void 0)throw new HostLaunchSpecError("launch_spec_missing_extension",`${target} does not exist`);if(escapes(rootReal,real))throw new HostLaunchSpecError("launch_spec_path_escape",`${entry} links outside ${specDir}`);resolved.push(real)}return resolved}function escapes(root,target){let step=relative(root,target);return step.startsWith("..")||isAbsolute(step)}function parsedTunables(value){if(!isRecord(value))return;let idleExitMs=value.idleExitMs,coldStart=value.coldStart;return{...typeof idleExitMs=="number"&&Number.isFinite(idleExitMs)&&idleExitMs>0&&{idleExitMs},...(coldStart==="transient"||coldStart==="persistent")&&{coldStart}}}function parsedEnv(value){let env={};for(let[name,entry]of Object.entries(value)){if(typeof entry!="string")throw new HostLaunchSpecError("launch_spec_invalid",`env.${name} must be a string`);env[name]=entry}return env}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}import{join}from"node:path";var ALLOWED_ENV_NAMES=[/^(PATH|HOME|USER|LOGNAME|SHELL|TMPDIR|TERM|LANG)$/u,/^(LC|XDG)_/u,/^(SENPI|OMO|PI)_/u,/^(HTTPS?_PROXY|NO_PROXY)$/u,/^[A-Z0-9_]+_API_KEY$/u,/^(ANTHROPIC|OPENAI|GOOGLE|GEMINI|AZURE|AWS|OPENROUTER|XAI|MISTRAL|DEEPSEEK|GROQ|CEREBRAS|MINIMAX)_/u],WINDOWS_SYSTEM_ENV_NAMES=new Set(["SYSTEMROOT","SYSTEMDRIVE","WINDIR","COMSPEC","PATHEXT","TEMP","TMP","USERPROFILE","APPDATA","LOCALAPPDATA","PROGRAMFILES","PROGRAMFILES(X86)","PROGRAMDATA","HOMEDRIVE","HOMEPATH","NUMBER_OF_PROCESSORS","PROCESSOR_ARCHITECTURE","OS"]);function daemonEnvIsAllowed(name,platform=process.platform){if(platform!=="win32")return ALLOWED_ENV_NAMES.some(pattern=>pattern.test(name));let upper=name.toUpperCase();return WINDOWS_SYSTEM_ENV_NAMES.has(upper)||ALLOWED_ENV_NAMES.some(pattern=>pattern.test(upper))}function daemonEnvOverrides(processEnv,specEnv={},platform=process.platform){let overrides={};for(let name of Object.keys(processEnv))daemonEnvIsAllowed(name,platform)||(overrides[name]=null);for(let[name,value]of Object.entries(specEnv))overrides[name]=value;return overrides}function daemonEnvKeys(processEnv,specEnv={},platform=process.platform){let kept=Object.keys(processEnv).filter(name=>daemonEnvIsAllowed(name,platform));return[...new Set([...kept,...Object.keys(specEnv)])].sort()}async function writeDaemonEnvKeys(paths,keys){await writeStateFile(daemonEnvKeysFile(paths),{env_keys:keys})}async function readDaemonEnvKeys(paths){let keys=parseJson(await readFileOrUndefined(daemonEnvKeysFile(paths)))?.env_keys;return Array.isArray(keys)?keys.filter(key=>typeof key=="string"):[]}function daemonEnvKeysFile(paths){return join(paths.dir,"env-keys.json")}var STATUS_PROBE_TIMEOUT_MS=1e4;async function readHostStatus(options){let paths=createHostDaemonPaths({socket:options.socket,...options.agentDir?{agentDir:options.agentDir}:{}}),host=await probeProtocolInfo(options.socket,STATUS_PROBE_TIMEOUT_MS);await pruneDeadGenerations(paths);let generations=await readGenerationRows(paths),current=generations.find(row=>row.current),metrics=current?await readHostProcessMetrics(current.pid):UNOBSERVED_METRICS;return{reachable:host!==void 0,socket:options.socket,pid:current?.pid??null,instanceId:host?.instanceId??current?.instanceId??null,generation:host?.generation??current?.generation??null,engineVersion:host?.engineVersion??current?.engineVersion??null,capabilities:host?.capabilities??[],launchProfile:host?.launch_profile??null,sessions:await readSessionCounts(options.socket,options.includeWorkers===!0),zombies:metrics.zombies,rss_mb:metrics.rss_mb,open_fds:metrics.open_fds,env_keys:await readDaemonEnvKeys(paths),generations}}async function readSessionCounts(socket,includeWorkers){let reply=await requestOnSocket(socket,{type:"list_sessions",...includeWorkers?{include_workers:!0}:{}},STATUS_PROBE_TIMEOUT_MS),rows=sessionRows(reply),attached=rows.filter(row=>row.attachments>0).length,retained=rows.length-attached;return{total:rows.length,interactive:rows.filter(row=>row.kind!=="worker").length,worker:rows.filter(row=>row.kind==="worker").length,retained,foreign_attached:attached,foreign_retained:retained}}function hostSummary(host){return host===void 0?null:{protocolVersion:host.protocolVersion,serverVersion:host.serverVersion,capabilities:host.capabilities,instanceId:host.instanceId??null,generation:host.generation??null,engineVersion:host.engineVersion??null,launchProfileId:host.launch_profile?.profile_id??null}}var UNOBSERVED_METRICS={rss_mb:null,open_fds:null,zombies:null};function sessionRows(reply){return!isRecord2(reply)||!Array.isArray(reply.sessions)?[]:reply.sessions.flatMap(entry=>isRecord2(entry)?[{kind:typeof entry.kind=="string"?entry.kind:"interactive",attachments:typeof entry.attachments=="number"?entry.attachments:0}]:[])}function isRecord2(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}var HOST_EXIT_OK=0,HOST_EXIT_ERROR=1,HOST_EXIT_USAGE=2,HOST_EXIT_REFUSED=3,HOST_EXIT_FALLBACK=4,PROBE_TIMEOUT_MS=1e4;async function runHostRequest(request){switch(request.action){case"ensure":return ensureOutcome(request.target,request.spec,request.policy);case"status":return statusOutcome(request.target,request.includeWorkers);case"stop":return stopOutcome(request.target,request.drain,request.force);case"handoff":return handoffOutcome(request.target,request.spec);default:return assertNever(request)}}async function ensureOutcome(target,spec,policy){let before=await probeProtocolInfo(target.socket,PROBE_TIMEOUT_MS);if(policy==="fallback"){let decision=decideHostAction(decisionClient(),before,"fallback");if(decision.action==="fallback")return refusal("fallback",before,{reason:decision.reason,socket:target.socket})}let ensured;try{ensured=await ensureHost({socket:target.socket,agentDir:target.agentDir,hostArgs:spec.hostArgs,env:daemonEnvOverrides(process.env,spec.env),policy:spec.policy,upgrade:policy==="upgrade"?"if-engine-differs":"never"})}catch(error){if(!(error instanceof HostEnsureRefusedError))throw error;return refusal("refuse",before,{reason:error.reason,socket:target.socket})}let host=await probeProtocolInfo(target.socket,PROBE_TIMEOUT_MS);return ensured.reused||await recordEnvScope(target,spec),{exitCode:HOST_EXIT_OK,payload:{action:ensureAction(ensured.reused,before,host),...identityPayload(target.socket,ensured.pid,host),reused:ensured.reused}}}function ensureAction(reused,before,after){return reused?"reuse":before!==void 0&&before.instanceId!==after?.instanceId?"handoff":"start"}async function statusOutcome(target,includeWorkers){let status=await readHostStatus({socket:target.socket,agentDir:target.agentDir,includeWorkers});return{exitCode:status.reachable?HOST_EXIT_OK:HOST_EXIT_REFUSED,payload:{...status}}}async function stopOutcome(target,drain,force){let host=await probeProtocolInfo(target.socket,PROBE_TIMEOUT_MS),sessions=await readSessionCounts(target.socket,!0),occupied=sessions.foreign_attached+sessions.foreign_retained>0;if(!drain&&!force&&occupied)return refusal("refuse",host,{reason:"sessions_live",socket:target.socket,sessions});let result=await stopHost({socket:target.socket,agentDir:target.agentDir,drain,force});return result.action==="refuse"?refusal("refuse",host,{reason:result.reason,socket:target.socket,sessions}):{exitCode:HOST_EXIT_OK,payload:{action:result.action,socket:target.socket,pid:result.pid,sessions}}}async function handoffOutcome(target,spec){let before=await probeProtocolInfo(target.socket,PROBE_TIMEOUT_MS),result=await handoffHost({socket:target.socket,agentDir:target.agentDir,hostArgs:spec.hostArgs,env:daemonEnvOverrides(process.env,spec.env),policy:spec.policy});if(result.action==="refuse")return refusal("refuse",before,{reason:upgradeRefusal(result.reason),socket:target.socket,detail:result.reason,upgradeable:result.upgradeable});await recordEnvScope(target,spec);let host=await probeProtocolInfo(target.socket,PROBE_TIMEOUT_MS);return{exitCode:HOST_EXIT_OK,payload:{action:"handoff",...identityPayload(target.socket,result.pid,host),reused:!1}}}function upgradeRefusal(reason){return reason==="handoff_unsupported"?"upgrade_unsupported":reason}function identityPayload(socket,pid,host){return{socket,pid,instanceId:host?.instanceId??null,generation:host?.generation??null,engineVersion:host?.engineVersion??null,engineOrdinal:host?.engineOrdinal??null,capabilities:host?.capabilities??[],launchProfileId:host?.launch_profile?.profile_id??null,upgradeable:decideHostAction(decisionClient(),host,"upgrade").upgradeable}}function refusal(kind,host,body){return{exitCode:kind==="refuse"?HOST_EXIT_REFUSED:HOST_EXIT_FALLBACK,payload:{action:kind,...body,host:hostSummary(host)}}}async function recordEnvScope(target,spec){let paths=createHostDaemonPaths({socket:target.socket,agentDir:target.agentDir});await writeDaemonEnvKeys(paths,daemonEnvKeys(process.env,spec.env))}function decisionClient(){return{protocolVersion:HOST_PROTOCOL_VERSION,requiredCapabilities:REQUIRED_HOST_CAPABILITIES,identity:engineBuildIdentity(),startedByUs:!1,platform:process.platform}}function assertNever(value){throw new Error(`unreachable host request: ${JSON.stringify(value)}`)}var SUBCOMMANDS=["ensure","status","stop","handoff"],POLICIES=["upgrade","fallback","never"],USAGE=`usage: ${APP_NAME} host <ensure|status|stop|handoff> [options]
3
3
 
4
4
  ensure [--launch-spec <file>] [--policy upgrade|fallback|never] [--socket <path>]
5
5
  status [--include-workers] [--socket <path>]
@@ -0,0 +1,11 @@
1
+ import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
+ import{appendGrammarToolInputJsonDelta,calculateCost,getGrammarToolInput,getJsonSchemaToolParameters,resolveGrammarConstrainedSampling,resolveJsonSchemaStrictSampling,shortHash,supportsConfigurationUpdate,transformMessages}from"./chunk-WL5EQYNL.js";import{sanitizeSurrogates}from"./chunk-WDTJ6JKE.js";import{parseStreamingJson}from"./chunk-3W47LTXQ.js";var CONTEXT_PROVENANCE_FIELD="__piContextProvenance";function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function getContextProvenance(value){if(!isRecord(value))return;let provenance=value[CONTEXT_PROVENANCE_FIELD];return isRecord(provenance)?provenance:void 0}function copyContextProvenance(source,target){let provenance=getContextProvenance(source);return provenance?Object.assign(target,{[CONTEXT_PROVENANCE_FIELD]:provenance}):target}function contextProvenanceFingerprint(value){if(!isRecord(value))return;let clone={...value};return delete clone[CONTEXT_PROVENANCE_FIELD],JSON.stringify(clone)}function formatResponsesCompletionStall(graceMs){return`Provider stream stalled after the last output item: response.completed timed out after ${graceMs}ms`}var ResponsesCompletionStallError=class extends Error{constructor(graceMs){super(formatResponsesCompletionStall(graceMs)),this.name="ResponsesCompletionStallError",this.graceMs=graceMs}},GRACE_EXPIRED=Symbol("responses-completion-grace-expired");function withResponsesCompletionGrace(source,graceMs=6e4){return{[Symbol.asyncIterator](){let iterator=source[Symbol.asyncIterator](),openItems=0,sawItemDone=!1,finished=!1,observe=event=>{event.type==="response.output_item.added"?openItems++:event.type==="response.output_item.done"&&(openItems=Math.max(0,openItems-1),sawItemDone=!0)},boundedNext=async()=>{let next=iterator.next();if(!sawItemDone||openItems>0||graceMs<=0)return next;let timer,deadline=new Promise(resolve=>{timer=setTimeout(()=>resolve(GRACE_EXPIRED),graceMs)});try{let winner=await Promise.race([next,deadline]);if(winner===GRACE_EXPIRED)throw finished=!0,iterator.return?.().catch(()=>{}),new ResponsesCompletionStallError(graceMs);return winner}finally{timer!==void 0&&clearTimeout(timer)}};return{async next(){if(finished)return{done:!0,value:void 0};let result=await boundedNext();return result.done?finished=!0:observe(result.value),result},async return(value){return finished=!0,await iterator.return?.(value),{done:!0,value:void 0}},async throw(error){if(finished=!0,iterator.throw)return iterator.throw(error);throw error}}}}}function encodeTextSignatureV1(id,phase){let payload={v:1,id};return phase&&(payload.phase=phase),JSON.stringify(payload)}function parseTextSignature(signature){if(signature){if(signature.startsWith("{"))try{let parsed=JSON.parse(signature);if(parsed.v===1&&typeof parsed.id=="string")return parsed.phase==="commentary"||parsed.phase==="final_answer"?{id:parsed.id,phase:parsed.phase}:{id:parsed.id}}catch{}return{id:signature}}}function parseReasoningSignature(signature){if(signature)try{let parsed=JSON.parse(signature);return parsed?.type==="reasoning"?parsed:void 0}catch{return}}function convertToolResultOutput(model,content){let textResult=content.filter(c=>c.type==="text").map(c=>c.text).join(`
3
+ `),images=content.filter(c=>c.type==="image"),hasText=textResult.length>0;if(images.length===0||!model.input.includes("image"))return sanitizeSurrogates(hasText?textResult:images.length>0?"(see attached image)":"(no tool output)");let output=[];hasText&&output.push({type:"input_text",text:sanitizeSurrogates(textResult)});for(let image of images)output.push({type:"input_image",detail:"auto",image_url:`data:${image.mimeType};base64,${image.data}`});return output}var CUSTOM_TOOL_CALL_ITEM_ID_SENTINEL="custom";function isResponseCustomToolCallItem(item){return item.type==="custom_tool_call"}function isFreeformTool(tool){return tool.freeform!==void 0}function isFreeformToolName(toolName,tools){return tools?.some(tool=>tool.name===toolName&&isFreeformTool(tool))??!1}function getFreeformToolInput(argumentsValue){return typeof argumentsValue.input=="string"?argumentsValue.input:JSON.stringify(argumentsValue)}function contextProvenanceForInput(message,seal){let provenance=getContextProvenance(message);if(!provenance)return;let fingerprint=contextProvenanceFingerprint(message);if(fingerprint===void 0)return;let stored=provenance.integrity;return stored===void 0&&seal?(provenance.integrity=fingerprint,provenance):stored===fingerprint?provenance:void 0}function withContextProvenance(item,message,seal){let provenance=contextProvenanceForInput(message,seal);return provenance&&Object.defineProperty(item,CONTEXT_PROVENANCE_FIELD,{value:provenance,enumerable:!1}),item}function convertResponsesMessages(model,context,allowedToolCallProviders,options){let messages=[],loadedToolNames=new Set,normalizeIdPart=part=>{let sanitized=part.replace(/[^a-zA-Z0-9_-]/g,"_");return(sanitized.length>64?sanitized.slice(0,64):sanitized).replace(/_+$/,"")},buildForeignResponsesItemId=itemId=>{let normalized=`fc_${shortHash(itemId)}`;return normalized.length>64?normalized.slice(0,64):normalized},normalizeToolCallId=(id,_targetModel,source)=>{if(!id.includes("|"))return normalizeIdPart(id);let[callId,itemId]=id.split("|"),normalizedCallId=normalizeIdPart(callId);if(itemId===CUSTOM_TOOL_CALL_ITEM_ID_SENTINEL)return`${normalizedCallId}|${CUSTOM_TOOL_CALL_ITEM_ID_SENTINEL}`;if(!allowedToolCallProviders.has(model.provider))return normalizeIdPart(id);let normalizedItemId=source.provider!==model.provider||source.api!==model.api?buildForeignResponsesItemId(itemId):normalizeIdPart(itemId);return normalizedItemId.startsWith("fc_")||(normalizedItemId=normalizeIdPart(`fc_${normalizedItemId}`)),`${normalizedCallId}|${normalizedItemId}`},transformedMessages=transformMessages(context.messages,model,normalizeToolCallId,{preserveThinking:options?.preserveThinking,preserveTextSignatures:options?.preserveTextSignatures});if((options?.includeSystemPrompt??!0)&&context.systemPrompt){let compat=model.compat,role=model.reasoning&&compat?.supportsDeveloperRole!==!1?"developer":"system";messages.push({role,content:sanitizeSurrogates(context.systemPrompt)})}let msgIndex=0;for(let msg of transformedMessages){if(msg.role==="configurationUpdate"){if(!supportsConfigurationUpdate(model))continue;messages[messages.length-1]?.type==="configuration_update"?messages[messages.length-1]={type:"configuration_update",reasoning:{effort:msg.effort}}:messages.push({type:"configuration_update",reasoning:{effort:msg.effort}});continue}if(msg.role==="user")if(typeof msg.content=="string")messages.push(withContextProvenance({role:"user",content:[{type:"input_text",text:sanitizeSurrogates(msg.content)}]},msg,options?.sealContextProvenance));else{let content=msg.content.map(item=>item.type==="text"?{type:"input_text",text:sanitizeSurrogates(item.text)}:{type:"input_image",detail:"auto",image_url:`data:${item.mimeType};base64,${item.data}`});if(content.length===0)continue;messages.push(withContextProvenance({role:"user",content},msg,options?.sealContextProvenance))}else if(msg.role==="assistant"){let output=[],assistantMsg=msg,isSameProviderAndApi=assistantMsg.provider===model.provider&&assistantMsg.api===model.api,isSameModel=isSameProviderAndApi&&assistantMsg.model===model.id,isDifferentModel=isSameProviderAndApi&&assistantMsg.model!==model.id,textBlockIndex=0,pushAssistantText=(text,textSignature)=>{let parsedSignature=parseTextSignature(textSignature),fallbackMessageId=textBlockIndex===0?`msg_pi_${msgIndex}`:`msg_pi_${msgIndex}_${textBlockIndex}`;textBlockIndex++;let msgId=parsedSignature?.id;msgId?msgId.length>64&&(msgId=`msg_${shortHash(msgId)}`):msgId=fallbackMessageId,output.push({type:"message",role:"assistant",content:[{type:"output_text",text:sanitizeSurrogates(text),annotations:[]}],status:"completed",id:msgId,phase:parsedSignature?.phase})};for(let block of msg.content)if(block.type==="thinking"){let reasoningItem=parseReasoningSignature(block.thinkingSignature);reasoningItem?output.push(reasoningItem):block.thinkingSignature&&block.thinking.trim()!==""&&pushAssistantText(block.thinking)}else if(block.type!=="providerNative"){if(block.type==="text"){let textBlock=block;pushAssistantText(textBlock.text,textBlock.textSignature)}else if(block.type==="toolCall"){let toolCall=block,[callId,itemIdRaw]=toolCall.id.split("|"),customInputProperty=options?.grammarToolInputProperties?.get(toolCall.name),isPersistedFreeform=itemIdRaw===CUSTOM_TOOL_CALL_ITEM_ID_SENTINEL,isFreeform=isFreeformToolName(toolCall.name,context.tools)||isPersistedFreeform,itemId=isPersistedFreeform?void 0:itemIdRaw;(isDifferentModel&&itemId?.startsWith("fc_")||!isFreeform&&customInputProperty===void 0&&!itemId?.startsWith("fc_"))&&(itemId=void 0);let canReplayNamespace=isSameModel||options?.deferredTools?.has(toolCall.name)===!0;customInputProperty!==void 0?output.push({type:"custom_tool_call",...itemId!==void 0?{id:itemId}:{},call_id:callId,name:toolCall.name,input:sanitizeSurrogates(getGrammarToolInput(toolCall.name,toolCall.arguments,customInputProperty)),...canReplayNamespace&&toolCall.namespace!==void 0?{namespace:toolCall.namespace}:{}}):isFreeform?output.push({type:"custom_tool_call",call_id:callId,name:toolCall.name,input:getFreeformToolInput(toolCall.arguments),...canReplayNamespace&&toolCall.namespace!==void 0?{namespace:toolCall.namespace}:{}}):output.push({type:"function_call",...itemId?.startsWith("fc_")?{id:itemId}:{},call_id:callId,name:toolCall.name,arguments:JSON.stringify(toolCall.arguments),...canReplayNamespace&&toolCall.namespace!==void 0?{namespace:toolCall.namespace}:{}})}}if(output.length===0)continue;messages.push(...output.map(item=>withContextProvenance(item,msg,options?.sealContextProvenance)))}else if(msg.role==="toolResult"){let[callId,itemIdRaw]=msg.toolCallId.split("|"),output=convertToolResultOutput(model,msg.content),customInputProperty=options?.grammarToolInputProperties?.get(msg.toolName),isPersistedFreeform=itemIdRaw===CUSTOM_TOOL_CALL_ITEM_ID_SENTINEL;customInputProperty!==void 0?messages.push(withContextProvenance({type:"custom_tool_call_output",call_id:callId,output},msg,options?.sealContextProvenance)):isFreeformToolName(msg.toolName,context.tools)||isPersistedFreeform?messages.push(withContextProvenance({type:"custom_tool_call_output",call_id:callId,name:msg.toolName,output},msg,options?.sealContextProvenance)):messages.push(withContextProvenance({type:"function_call_output",call_id:callId,output},msg,options?.sealContextProvenance));let deferredTools=[];for(let name of msg.addedToolNames??[]){let tool=options?.deferredTools?.get(name);!tool||loadedToolNames.has(name)||(loadedToolNames.add(name),deferredTools.push(tool))}if(deferredTools.length>0&&options?.deferredToolsMode==="additional-tools")messages.push(withContextProvenance({type:"additional_tools",role:"developer",tools:convertResponsesTools(deferredTools,options.toolOptions)},msg,options.sealContextProvenance));else if(deferredTools.length>0&&options?.deferredToolsMode==="tool-search"){let names=deferredTools.map(tool=>tool.name),searchCallId=`pi_tool_load_${shortHash(`${msg.toolCallId}:${names.join(",")}`)}`;messages.push(withContextProvenance({type:"tool_search_call",call_id:searchCallId,execution:"client",status:"completed",arguments:{query:names.join(" "),limit:names.length}},msg,options?.sealContextProvenance)),messages.push(withContextProvenance({type:"tool_search_output",call_id:searchCallId,execution:"client",status:"completed",tools:convertResponsesTools(deferredTools,{...options?.toolOptions,deferLoading:!0})},msg,options?.sealContextProvenance))}}msgIndex++}return messages}function convertResponsesTools(tools,options){let defaultStrict=options?.strict===void 0?!1:options.strict,supportsStrictMode=options?.supportsStrictMode??!0,supportsOpenAIGrammarTools=options?.supportsOpenAIGrammarTools??!1;return tools.map(tool=>{let grammar=resolveGrammarConstrainedSampling(tool,supportsOpenAIGrammarTools);if(grammar)return{type:"custom",name:tool.name,description:tool.description,format:{type:"grammar",syntax:grammar.format,definition:grammar.definition},...options?.deferLoading?{defer_loading:!0}:{}};if(tool.freeform)return{type:"custom",name:tool.name,description:tool.description,format:tool.freeform,...options?.deferLoading?{defer_loading:!0}:{}};let strict=resolveJsonSchemaStrictSampling(tool,supportsStrictMode)??defaultStrict,functionTool={type:"function",name:tool.name,description:tool.description,parameters:getJsonSchemaToolParameters(tool,strict===!0),...options?.deferLoading?{defer_loading:!0}:{}};return supportsStrictMode&&(functionTool.strict=strict),functionTool})}function getCustomToolCallInput(block){let property=block.customInput?.property;if(property===void 0)return"";let value=block.arguments[property];return typeof value=="string"?value:""}function appendCustomToolCallInput(block,nextInput,close){let customInput=block.customInput;if(!customInput)return;let delta=appendGrammarToolInputJsonDelta(customInput.jsonBuffer,customInput.property,nextInput,close);return block.arguments={[customInput.property]:nextInput},delta}var MAX_NATIVE_IMAGE_BASE64_CHARS=24*1024*1024;function readNativeImageGenerationCall(value){if(!(typeof value!="object"||value===null||!("type"in value)||!("status"in value))&&!(value.type!=="image_generation_call"||typeof value.status!="string"))return{type:"image_generation_call",..."id"in value&&typeof value.id=="string"?{id:value.id}:{},status:value.status,..."result"in value&&(typeof value.result=="string"||value.result===null)?{result:value.result}:{},..."revised_prompt"in value&&typeof value.revised_prompt=="string"?{revised_prompt:value.revised_prompt}:{}}}function isValidBase64(value){return value.length>0&&value.length%4===0&&/^[A-Za-z0-9+/]*={0,2}$/.test(value)}function reconcileNativeImageGenerationCall(item){return item.status!=="completed"?{type:"image_generation_call",...item.id!==void 0?{id:item.id}:{},status:item.status}:typeof item.result!="string"||!isValidBase64(item.result)?{type:"image_generation_call",...item.id!==void 0?{id:item.id}:{},status:"malformed"}:{type:"image_generation_call",...item.id!==void 0?{id:item.id}:{},status:"completed",result:item.result,...item.revised_prompt?.trim()?{revised_prompt:item.revised_prompt}:{}}}async function processResponsesStream(openaiStream,output,stream,model,options){let sawTerminalResponseEvent=!1,nativeImageBase64Chars=0,outputSlots=new Map,reasoningBlocksById=new Map,nativeImageCharsByOutputIndex=new Map,finalizedNativeImageOutputIndexes=new Set,applyMessagePhaseStopReason=item=>{item.type==="message"&&item.phase==="final_answer"&&(output.stopReason="stop")},getSlot=(outputIndex,type)=>{let slot=outputSlots.get(outputIndex);return slot?.type===type?slot:void 0},pushToolCallDelta=(slot,delta)=>{delta!==void 0&&stream.push({type:"toolcall_delta",contentIndex:slot.contentIndex,delta,partial:output})},createSlot=(outputIndex,item)=>{if(item.type==="reasoning"){let block2={type:"thinking",thinking:""};output.content.push(block2);let slot2={type:"thinking",block:block2,contentIndex:output.content.length-1};return outputSlots.set(outputIndex,slot2),stream.push({type:"thinking_start",contentIndex:slot2.contentIndex,partial:output}),slot2}if(item.type==="message"){applyMessagePhaseStopReason(item);let block2={type:"text",text:""};output.content.push(block2);let slot2={type:"text",block:block2,contentIndex:output.content.length-1};return outputSlots.set(outputIndex,slot2),stream.push({type:"text_start",contentIndex:slot2.contentIndex,partial:output}),slot2}if(item.type==="function_call"){let block2={type:"toolCall",id:`${item.call_id}|${item.id}`,name:item.name,arguments:{},...item.namespace!==void 0?{namespace:item.namespace}:{},partialJson:item.arguments||""};output.content.push(block2);let slot2={type:"toolCall",block:block2,contentIndex:output.content.length-1};return outputSlots.set(outputIndex,slot2),stream.push({type:"toolcall_start",contentIndex:slot2.contentIndex,partial:output}),slot2}if(isResponseCustomToolCallItem(item)){let inputProperty=options?.grammarToolInputProperties?.get(item.name)??"input",input=item.input||"",block2={type:"toolCall",id:`${item.call_id}|${item.id??CUSTOM_TOOL_CALL_ITEM_ID_SENTINEL}`,name:item.name,arguments:{[inputProperty]:input},...item.namespace!==void 0?{namespace:item.namespace}:{},customInput:{property:inputProperty,jsonBuffer:{input:"",started:!1,closed:!1}}};output.content.push(block2);let slot2={type:"toolCall",block:block2,contentIndex:output.content.length-1};return outputSlots.set(outputIndex,slot2),stream.push({type:"toolcall_start",contentIndex:slot2.contentIndex,partial:output}),slot2}let imageItem=readNativeImageGenerationCall(item),block={type:"providerNative",subtype:item.type,raw:imageItem?reconcileNativeImageGenerationCall(imageItem):item},slot={type:"providerNative",block,contentIndex:output.content.length};return imageItem&&reconcileNativeImageSlot(outputIndex,slot,imageItem),output.content.push(block),outputSlots.set(outputIndex,slot),slot},getOrCreateSlot=(outputIndex,item)=>outputSlots.get(outputIndex)??createSlot(outputIndex,item);function scrubNativeImageResults(){for(let block of output.content){if(block.type!=="providerNative"||block.subtype!=="image_generation_call")continue;let item=readNativeImageGenerationCall(block.raw);typeof item?.result=="string"&&(block.raw={type:"image_generation_call",...item.id!==void 0?{id:item.id}:{},status:"malformed"})}nativeImageBase64Chars=0,nativeImageCharsByOutputIndex.clear()}function reconcileNativeImageSlot(outputIndex,slot,item){let reconciled=reconcileNativeImageGenerationCall(item),previousChars=nativeImageCharsByOutputIndex.get(outputIndex)??0,nextChars=typeof reconciled.result=="string"?reconciled.result.length:0,nextTotal=nativeImageBase64Chars-previousChars+nextChars;if(nextTotal>MAX_NATIVE_IMAGE_BASE64_CHARS)throw scrubNativeImageResults(),new Error("Native image generation results exceed the 24 MiB base64 limit");nativeImageBase64Chars=nextTotal,nextChars>0?nativeImageCharsByOutputIndex.set(outputIndex,nextChars):nativeImageCharsByOutputIndex.delete(outputIndex),slot.block.subtype="image_generation_call",slot.block.raw=reconciled}let backfillNativeImageGenerationCalls=responseOutput=>{for(let[outputIndex,outputItem]of responseOutput.entries()){if(finalizedNativeImageOutputIndexes.has(outputIndex))continue;let imageItem=readNativeImageGenerationCall(outputItem);if(!imageItem)continue;let existingSlot=getSlot(outputIndex,"providerNative");existingSlot?reconcileNativeImageSlot(outputIndex,existingSlot,imageItem):createSlot(outputIndex,outputItem),outputSlots.delete(outputIndex)}},backfillReasoningSignatures=responseOutput=>{for(let item of responseOutput){if(item.type!=="reasoning"||!item.encrypted_content)continue;let block=reasoningBlocksById.get(item.id);if(!block?.thinkingSignature)continue;let storedItem=parseReasoningSignature(block.thinkingSignature);!storedItem||storedItem.encrypted_content||(block.thinkingSignature=JSON.stringify({...storedItem,encrypted_content:item.encrypted_content}))}},finalizeResponse=response=>{if(sawTerminalResponseEvent=!0,backfillReasoningSignatures(response.output??[]),backfillNativeImageGenerationCalls(response.output??[]),response?.id&&(output.responseId=response.id),response?.usage){let inputDetails=response.usage.input_tokens_details,cachedTokens=inputDetails?.cached_tokens||0,cacheWriteTokens=inputDetails?.cache_write_tokens??inputDetails?.cache_creation_tokens??0;output.usage={input:Math.max(0,(response.usage.input_tokens||0)-cachedTokens-cacheWriteTokens),output:response.usage.output_tokens||0,cacheRead:cachedTokens,cacheWrite:cacheWriteTokens,reasoning:response.usage.output_tokens_details?.reasoning_tokens||0,totalTokens:response.usage.total_tokens||0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}}}if(calculateCost(model,output.usage),options?.applyServiceTierPricing){let serviceTier=options.resolveServiceTier?options.resolveServiceTier(response?.service_tier,options.serviceTier):response?.service_tier??options.serviceTier;options.applyServiceTierPricing(output.usage,serviceTier)}let status=response?.status,incompleteDetails=response?.incomplete_details,incompleteReason=typeof incompleteDetails?.reason=="string"?incompleteDetails.reason:void 0;output.rawStopReason=incompleteReason?`${status}.${incompleteReason}`:status;let mappedStop=mapStopReason(status,incompleteReason);output.stopReason=mappedStop.stopReason,mappedStop.errorMessage===void 0?delete output.errorMessage:output.errorMessage=mappedStop.errorMessage,output.content.some(b=>b.type==="toolCall")&&output.stopReason==="stop"&&(output.stopReason="toolUse")};for await(let event of withResponsesCompletionGrace(openaiStream))if(event.type==="response.created")output.responseId=event.response.id;else if(event.type==="response.output_item.added")createSlot(event.output_index,event.item);else if(event.type==="response.reasoning_summary_text.delta"){let slot=getSlot(event.output_index,"thinking");if(!slot)continue;slot.block.thinking+=event.delta,stream.push({type:"thinking_delta",contentIndex:slot.contentIndex,delta:event.delta,partial:output})}else if(event.type==="response.reasoning_summary_part.done"){let slot=getSlot(event.output_index,"thinking");if(!slot)continue;slot.block.thinking+=`
4
+
5
+ `,stream.push({type:"thinking_delta",contentIndex:slot.contentIndex,delta:`
6
+
7
+ `,partial:output})}else if(event.type==="response.reasoning_text.delta"){let slot=getSlot(event.output_index,"thinking");if(!slot)continue;slot.block.thinking+=event.delta,stream.push({type:"thinking_delta",contentIndex:slot.contentIndex,delta:event.delta,partial:output})}else if(event.type==="response.output_text.delta"){let slot=getSlot(event.output_index,"text");if(!slot)continue;slot.block.text+=event.delta,stream.push({type:"text_delta",contentIndex:slot.contentIndex,delta:event.delta,partial:output})}else if(event.type==="response.refusal.delta"){let slot=getSlot(event.output_index,"text");if(!slot)continue;slot.block.text+=event.delta,stream.push({type:"text_delta",contentIndex:slot.contentIndex,delta:event.delta,partial:output})}else if(event.type==="response.function_call_arguments.delta"){let slot=getSlot(event.output_index,"toolCall");if(!slot||slot.block.partialJson===void 0)continue;slot.block.partialJson+=event.delta,slot.block.arguments=parseStreamingJson(slot.block.partialJson),pushToolCallDelta(slot,event.delta)}else if(event.type==="response.function_call_arguments.done"){let slot=getSlot(event.output_index,"toolCall");if(!slot||slot.block.partialJson===void 0)continue;let previousPartialJson=slot.block.partialJson;if(slot.block.partialJson=event.arguments,slot.block.arguments=parseStreamingJson(slot.block.partialJson),event.arguments.startsWith(previousPartialJson)){let delta=event.arguments.slice(previousPartialJson.length);delta.length>0&&pushToolCallDelta(slot,delta)}}else if(event.type==="response.custom_tool_call_input.delta"){let slot=getSlot(event.output_index,"toolCall");if(!slot?.block.customInput)continue;pushToolCallDelta(slot,appendCustomToolCallInput(slot.block,getCustomToolCallInput(slot.block)+event.delta,!1))}else if(event.type==="response.custom_tool_call_input.done"){let slot=getSlot(event.output_index,"toolCall");if(!slot?.block.customInput)continue;pushToolCallDelta(slot,appendCustomToolCallInput(slot.block,event.input,!0))}else if(event.type==="response.output_item.done"){let item=event.item;applyMessagePhaseStopReason(item);let slot=getOrCreateSlot(event.output_index,item),imageItem=readNativeImageGenerationCall(item);if(imageItem&&slot?.type==="providerNative")reconcileNativeImageSlot(event.output_index,slot,imageItem),finalizedNativeImageOutputIndexes.add(event.output_index),outputSlots.delete(event.output_index);else if(item.type==="reasoning"&&slot?.type==="thinking"){let summaryText=item.summary?.map(s=>s.text).join(`
8
+
9
+ `)||"",contentText=item.content?.map(c=>c.text).join(`
10
+
11
+ `)||"";slot.block.thinking=summaryText||contentText||slot.block.thinking,slot.block.thinkingSignature=JSON.stringify(item),reasoningBlocksById.set(item.id,slot.block),stream.push({type:"thinking_end",contentIndex:slot.contentIndex,content:slot.block.thinking,partial:output}),outputSlots.delete(event.output_index)}else if(item.type==="message"&&slot?.type==="text")slot.block.text=item.content?.map(c=>c.type==="output_text"?c.text:c.refusal).join("")||"",slot.block.textSignature=encodeTextSignatureV1(item.id,item.phase??void 0),stream.push({type:"text_end",contentIndex:slot.contentIndex,content:slot.block.text,partial:output}),outputSlots.delete(event.output_index);else if(item.type==="function_call"&&slot?.type==="toolCall"&&slot.block.partialJson!==void 0)slot.block.arguments=parseStreamingJson(item.arguments||slot.block.partialJson||"{}"),item.namespace!==void 0&&(slot.block.namespace=item.namespace),delete slot.block.partialJson,stream.push({type:"toolcall_end",contentIndex:slot.contentIndex,toolCall:slot.block,partial:output}),outputSlots.delete(event.output_index);else if(item.type==="custom_tool_call"&&slot?.type==="toolCall"&&slot.block.customInput)pushToolCallDelta(slot,appendCustomToolCallInput(slot.block,item.input??getCustomToolCallInput(slot.block),!0)),item.namespace!==void 0&&(slot.block.namespace=item.namespace),delete slot.block.customInput,stream.push({type:"toolcall_end",contentIndex:slot.contentIndex,toolCall:slot.block,partial:output}),outputSlots.delete(event.output_index);else if(isResponseCustomToolCallItem(item)&&slot?.type==="toolCall"){let input=typeof item.input=="string"?item.input:"";slot.block.arguments={input},delete slot.block.partialJson,stream.push({type:"toolcall_end",contentIndex:slot.contentIndex,toolCall:slot.block,partial:output}),outputSlots.delete(event.output_index)}else slot?.type==="providerNative"&&(slot.block.subtype=item.type,slot.block.raw=item,outputSlots.delete(event.output_index))}else if(event.type==="response.completed"||event.type==="response.incomplete")finalizeResponse(event.response);else{if(event.type==="error")throw new Error(`Error Code ${event.code}: ${event.message}`||"Unknown error");if(event.type==="response.failed"){sawTerminalResponseEvent=!0,output.rawStopReason=event.response?.status;let error=event.response?.error,details=event.response?.incomplete_details,msg=error?`${error.code||"unknown"}: ${error.message||"no message"}`:details?.reason?`incomplete: ${details.reason}`:"Unknown error (no error details in response)";throw new Error(msg)}}let hasFinalizedToolCall=output.content.some(block=>block.type==="toolCall"&&!("partialJson"in block));if(!sawTerminalResponseEvent&&!hasFinalizedToolCall)throw new Error("OpenAI Responses stream ended before a terminal response event")}function mapStopReason(status,incompleteReason){if(!status)return{stopReason:"stop"};switch(status){case"completed":return{stopReason:"stop"};case"incomplete":return incompleteReason==="max_output_tokens"?{stopReason:"length"}:{stopReason:"error",errorMessage:incompleteReason?`Response incomplete: ${incompleteReason}`:"Response incomplete without a provider reason"};case"failed":case"cancelled":return{stopReason:"error"};case"in_progress":case"queued":return{stopReason:"stop"};default:{let _exhaustive=status;throw new Error(`Unhandled stop reason: ${_exhaustive}`)}}}export{CONTEXT_PROVENANCE_FIELD,getContextProvenance,copyContextProvenance,contextProvenanceFingerprint,convertResponsesMessages,convertResponsesTools,processResponsesStream};