@sheason/pi-coding-agent 0.74.1-sheason.0 → 0.78.0-sheason.0.6.0-alpha.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 (516) hide show
  1. package/CHANGELOG.md +256 -4
  2. package/README.md +16 -8
  3. package/dist/bun/cli.d.ts.map +1 -1
  4. package/dist/bun/cli.js.map +1 -1
  5. package/dist/cli/args.d.ts +7 -2
  6. package/dist/cli/args.d.ts.map +1 -1
  7. package/dist/cli/args.js +49 -1
  8. package/dist/cli/args.js.map +1 -1
  9. package/dist/cli/config-selector.d.ts +2 -2
  10. package/dist/cli/config-selector.d.ts.map +1 -1
  11. package/dist/cli/config-selector.js +1 -1
  12. package/dist/cli/config-selector.js.map +1 -1
  13. package/dist/cli/file-processor.d.ts.map +1 -1
  14. package/dist/cli/file-processor.js +2 -3
  15. package/dist/cli/file-processor.js.map +1 -1
  16. package/dist/cli/initial-message.d.ts +1 -1
  17. package/dist/cli/initial-message.d.ts.map +1 -1
  18. package/dist/cli/initial-message.js.map +1 -1
  19. package/dist/cli/list-models.d.ts +1 -1
  20. package/dist/cli/list-models.d.ts.map +1 -1
  21. package/dist/cli/list-models.js.map +1 -1
  22. package/dist/cli/session-picker.d.ts +1 -1
  23. package/dist/cli/session-picker.d.ts.map +1 -1
  24. package/dist/cli/session-picker.js.map +1 -1
  25. package/dist/cli.d.ts.map +1 -1
  26. package/dist/cli.js +4 -6
  27. package/dist/cli.js.map +1 -1
  28. package/dist/config.d.ts.map +1 -1
  29. package/dist/config.js +61 -32
  30. package/dist/config.js.map +1 -1
  31. package/dist/core/agent-session-proxy.d.ts +268 -0
  32. package/dist/core/agent-session-proxy.d.ts.map +1 -0
  33. package/dist/core/agent-session-proxy.js +2 -0
  34. package/dist/core/agent-session-proxy.js.map +1 -0
  35. package/dist/core/agent-session-runtime.d.ts +10 -10
  36. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  37. package/dist/core/agent-session-runtime.js +14 -14
  38. package/dist/core/agent-session-runtime.js.map +1 -1
  39. package/dist/core/agent-session-services.d.ts +8 -7
  40. package/dist/core/agent-session-services.d.ts.map +1 -1
  41. package/dist/core/agent-session-services.js +4 -2
  42. package/dist/core/agent-session-services.js.map +1 -1
  43. package/dist/core/agent-session.d.ts +60 -27
  44. package/dist/core/agent-session.d.ts.map +1 -1
  45. package/dist/core/agent-session.js +303 -177
  46. package/dist/core/agent-session.js.map +1 -1
  47. package/dist/core/auth-guidance.d.ts.map +1 -1
  48. package/dist/core/auth-guidance.js.map +1 -1
  49. package/dist/core/auth-storage.d.ts +1 -1
  50. package/dist/core/auth-storage.d.ts.map +1 -1
  51. package/dist/core/auth-storage.js +3 -2
  52. package/dist/core/auth-storage.js.map +1 -1
  53. package/dist/core/bash-executor.d.ts +1 -1
  54. package/dist/core/bash-executor.d.ts.map +1 -1
  55. package/dist/core/bash-executor.js.map +1 -1
  56. package/dist/core/compaction/branch-summarization.d.ts +3 -3
  57. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  58. package/dist/core/compaction/branch-summarization.js.map +1 -1
  59. package/dist/core/compaction/compaction.d.ts +5 -5
  60. package/dist/core/compaction/compaction.d.ts.map +1 -1
  61. package/dist/core/compaction/compaction.js +41 -37
  62. package/dist/core/compaction/compaction.js.map +1 -1
  63. package/dist/core/compaction/index.d.ts +3 -3
  64. package/dist/core/compaction/index.d.ts.map +1 -1
  65. package/dist/core/compaction/index.js.map +1 -1
  66. package/dist/core/exec.d.ts.map +1 -1
  67. package/dist/core/exec.js.map +1 -1
  68. package/dist/core/export-html/index.d.ts +1 -1
  69. package/dist/core/export-html/index.d.ts.map +1 -1
  70. package/dist/core/export-html/index.js +8 -6
  71. package/dist/core/export-html/index.js.map +1 -1
  72. package/dist/core/export-html/template.js +23 -6
  73. package/dist/core/export-html/tool-renderer.d.ts +2 -2
  74. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  75. package/dist/core/export-html/tool-renderer.js.map +1 -1
  76. package/dist/core/extensions/index.d.ts +8 -8
  77. package/dist/core/extensions/index.d.ts.map +1 -1
  78. package/dist/core/extensions/index.js.map +1 -1
  79. package/dist/core/extensions/loader.d.ts +2 -2
  80. package/dist/core/extensions/loader.d.ts.map +1 -1
  81. package/dist/core/extensions/loader.js +17 -34
  82. package/dist/core/extensions/loader.js.map +1 -1
  83. package/dist/core/extensions/runner.d.ts +12 -7
  84. package/dist/core/extensions/runner.d.ts.map +1 -1
  85. package/dist/core/extensions/runner.js +36 -2
  86. package/dist/core/extensions/runner.js.map +1 -1
  87. package/dist/core/extensions/types.d.ts +26 -24
  88. package/dist/core/extensions/types.d.ts.map +1 -1
  89. package/dist/core/extensions/types.js.map +1 -1
  90. package/dist/core/extensions/wrapper.d.ts +2 -2
  91. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  92. package/dist/core/extensions/wrapper.js.map +1 -1
  93. package/dist/core/footer-data-provider.d.ts +3 -1
  94. package/dist/core/footer-data-provider.d.ts.map +1 -1
  95. package/dist/core/footer-data-provider.js +4 -0
  96. package/dist/core/footer-data-provider.js.map +1 -1
  97. package/dist/core/http-dispatcher.d.ts +21 -0
  98. package/dist/core/http-dispatcher.d.ts.map +1 -0
  99. package/dist/core/http-dispatcher.js +48 -0
  100. package/dist/core/http-dispatcher.js.map +1 -0
  101. package/dist/core/index.d.ts +8 -8
  102. package/dist/core/index.d.ts.map +1 -1
  103. package/dist/core/index.js.map +1 -1
  104. package/dist/core/keybindings.d.ts.map +1 -1
  105. package/dist/core/keybindings.js.map +1 -1
  106. package/dist/core/local-agent-session-proxy.d.ts +82 -0
  107. package/dist/core/local-agent-session-proxy.d.ts.map +1 -0
  108. package/dist/core/local-agent-session-proxy.js +531 -0
  109. package/dist/core/local-agent-session-proxy.js.map +1 -0
  110. package/dist/core/messages.d.ts +0 -9
  111. package/dist/core/messages.d.ts.map +1 -1
  112. package/dist/core/messages.js +0 -10
  113. package/dist/core/messages.js.map +1 -1
  114. package/dist/core/model-registry.d.ts +4 -4
  115. package/dist/core/model-registry.d.ts.map +1 -1
  116. package/dist/core/model-registry.js +72 -16
  117. package/dist/core/model-registry.js.map +1 -1
  118. package/dist/core/model-resolver.d.ts +1 -1
  119. package/dist/core/model-resolver.d.ts.map +1 -1
  120. package/dist/core/model-resolver.js +1 -1
  121. package/dist/core/model-resolver.js.map +1 -1
  122. package/dist/core/output-guard.d.ts +1 -0
  123. package/dist/core/output-guard.d.ts.map +1 -1
  124. package/dist/core/output-guard.js +52 -22
  125. package/dist/core/output-guard.js.map +1 -1
  126. package/dist/core/package-manager.d.ts +7 -1
  127. package/dist/core/package-manager.d.ts.map +1 -1
  128. package/dist/core/package-manager.js +129 -64
  129. package/dist/core/package-manager.js.map +1 -1
  130. package/dist/core/prompt-templates.d.ts +1 -1
  131. package/dist/core/prompt-templates.d.ts.map +1 -1
  132. package/dist/core/prompt-templates.js +12 -24
  133. package/dist/core/prompt-templates.js.map +1 -1
  134. package/dist/core/provider-display-names.d.ts.map +1 -1
  135. package/dist/core/provider-display-names.js +0 -1
  136. package/dist/core/provider-display-names.js.map +1 -1
  137. package/dist/core/resolve-config-value.d.ts +9 -1
  138. package/dist/core/resolve-config-value.d.ts.map +1 -1
  139. package/dist/core/resolve-config-value.js +134 -11
  140. package/dist/core/resolve-config-value.js.map +1 -1
  141. package/dist/core/resource-loader.d.ts +13 -10
  142. package/dist/core/resource-loader.d.ts.map +1 -1
  143. package/dist/core/resource-loader.js +41 -33
  144. package/dist/core/resource-loader.js.map +1 -1
  145. package/dist/core/sdk.d.ts +15 -13
  146. package/dist/core/sdk.d.ts.map +1 -1
  147. package/dist/core/sdk.js +24 -17
  148. package/dist/core/sdk.js.map +1 -1
  149. package/dist/core/session-manager.d.ts +20 -10
  150. package/dist/core/session-manager.d.ts.map +1 -1
  151. package/dist/core/session-manager.js +201 -106
  152. package/dist/core/session-manager.js.map +1 -1
  153. package/dist/core/settings-manager.d.ts +5 -0
  154. package/dist/core/settings-manager.d.ts.map +1 -1
  155. package/dist/core/settings-manager.js +31 -13
  156. package/dist/core/settings-manager.js.map +1 -1
  157. package/dist/core/skills.d.ts +2 -2
  158. package/dist/core/skills.d.ts.map +1 -1
  159. package/dist/core/skills.js +10 -27
  160. package/dist/core/skills.js.map +1 -1
  161. package/dist/core/slash-commands.d.ts +1 -1
  162. package/dist/core/slash-commands.d.ts.map +1 -1
  163. package/dist/core/slash-commands.js.map +1 -1
  164. package/dist/core/source-info.d.ts +1 -1
  165. package/dist/core/source-info.d.ts.map +1 -1
  166. package/dist/core/source-info.js.map +1 -1
  167. package/dist/core/system-prompt.d.ts +1 -1
  168. package/dist/core/system-prompt.d.ts.map +1 -1
  169. package/dist/core/system-prompt.js +16 -9
  170. package/dist/core/system-prompt.js.map +1 -1
  171. package/dist/core/telemetry.d.ts +1 -1
  172. package/dist/core/telemetry.d.ts.map +1 -1
  173. package/dist/core/telemetry.js.map +1 -1
  174. package/dist/core/tools/bash.d.ts +2 -2
  175. package/dist/core/tools/bash.d.ts.map +1 -1
  176. package/dist/core/tools/bash.js +55 -54
  177. package/dist/core/tools/bash.js.map +1 -1
  178. package/dist/core/tools/edit-diff.d.ts +3 -1
  179. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  180. package/dist/core/tools/edit-diff.js +8 -1
  181. package/dist/core/tools/edit-diff.js.map +1 -1
  182. package/dist/core/tools/edit.d.ts +5 -3
  183. package/dist/core/tools/edit.d.ts.map +1 -1
  184. package/dist/core/tools/edit.js +51 -91
  185. package/dist/core/tools/edit.js.map +1 -1
  186. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  187. package/dist/core/tools/file-mutation-queue.js +27 -12
  188. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  189. package/dist/core/tools/find.d.ts +2 -2
  190. package/dist/core/tools/find.d.ts.map +1 -1
  191. package/dist/core/tools/find.js +2 -3
  192. package/dist/core/tools/find.js.map +1 -1
  193. package/dist/core/tools/grep.d.ts +2 -2
  194. package/dist/core/tools/grep.d.ts.map +1 -1
  195. package/dist/core/tools/grep.js +3 -3
  196. package/dist/core/tools/grep.js.map +1 -1
  197. package/dist/core/tools/index.d.ts +17 -17
  198. package/dist/core/tools/index.d.ts.map +1 -1
  199. package/dist/core/tools/index.js.map +1 -1
  200. package/dist/core/tools/ls.d.ts +2 -2
  201. package/dist/core/tools/ls.d.ts.map +1 -1
  202. package/dist/core/tools/ls.js +10 -12
  203. package/dist/core/tools/ls.js.map +1 -1
  204. package/dist/core/tools/output-accumulator.d.ts +3 -1
  205. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  206. package/dist/core/tools/output-accumulator.js +9 -3
  207. package/dist/core/tools/output-accumulator.js.map +1 -1
  208. package/dist/core/tools/path-utils.d.ts +2 -0
  209. package/dist/core/tools/path-utils.d.ts.map +1 -1
  210. package/dist/core/tools/path-utils.js +39 -21
  211. package/dist/core/tools/path-utils.js.map +1 -1
  212. package/dist/core/tools/read.d.ts +2 -2
  213. package/dist/core/tools/read.d.ts.map +1 -1
  214. package/dist/core/tools/read.js +15 -15
  215. package/dist/core/tools/read.js.map +1 -1
  216. package/dist/core/tools/render-utils.d.ts +5 -2
  217. package/dist/core/tools/render-utils.d.ts.map +1 -1
  218. package/dist/core/tools/render-utils.js +17 -1
  219. package/dist/core/tools/render-utils.js.map +1 -1
  220. package/dist/core/tools/tool-definition-wrapper.d.ts +1 -1
  221. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  222. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  223. package/dist/core/tools/truncate.d.ts.map +1 -1
  224. package/dist/core/tools/truncate.js +12 -2
  225. package/dist/core/tools/truncate.js.map +1 -1
  226. package/dist/core/tools/write.d.ts +1 -1
  227. package/dist/core/tools/write.d.ts.map +1 -1
  228. package/dist/core/tools/write.js +25 -41
  229. package/dist/core/tools/write.js.map +1 -1
  230. package/dist/d-pi-worker.d.ts +12 -0
  231. package/dist/d-pi-worker.d.ts.map +1 -0
  232. package/dist/d-pi-worker.js +9 -0
  233. package/dist/d-pi-worker.js.map +1 -0
  234. package/dist/index.d.ts +30 -28
  235. package/dist/index.d.ts.map +1 -1
  236. package/dist/index.js +5 -3
  237. package/dist/index.js.map +1 -1
  238. package/dist/main.d.ts +1 -1
  239. package/dist/main.d.ts.map +1 -1
  240. package/dist/main.js +100 -39
  241. package/dist/main.js.map +1 -1
  242. package/dist/migrations.d.ts.map +1 -1
  243. package/dist/migrations.js +118 -1
  244. package/dist/migrations.js.map +1 -1
  245. package/dist/modes/connect/auth-headers.d.ts +2 -0
  246. package/dist/modes/connect/auth-headers.d.ts.map +1 -0
  247. package/dist/modes/connect/auth-headers.js +2 -0
  248. package/dist/modes/connect/auth-headers.js.map +1 -0
  249. package/dist/modes/connect/client-extension-sync.d.ts +13 -0
  250. package/dist/modes/connect/client-extension-sync.d.ts.map +1 -0
  251. package/dist/modes/connect/client-extension-sync.js +51 -0
  252. package/dist/modes/connect/client-extension-sync.js.map +1 -0
  253. package/dist/modes/connect/connect-mode.d.ts +6 -0
  254. package/dist/modes/connect/connect-mode.d.ts.map +1 -0
  255. package/dist/modes/connect/connect-mode.js +29 -0
  256. package/dist/modes/connect/connect-mode.js.map +1 -0
  257. package/dist/modes/connect/remote-agent-session-proxy.d.ts +81 -0
  258. package/dist/modes/connect/remote-agent-session-proxy.d.ts.map +1 -0
  259. package/dist/modes/connect/remote-agent-session-proxy.js +326 -0
  260. package/dist/modes/connect/remote-agent-session-proxy.js.map +1 -0
  261. package/dist/modes/connect/sse-client.d.ts +18 -0
  262. package/dist/modes/connect/sse-client.d.ts.map +1 -0
  263. package/dist/modes/connect/sse-client.js +90 -0
  264. package/dist/modes/connect/sse-client.js.map +1 -0
  265. package/dist/modes/index.d.ts +5 -5
  266. package/dist/modes/index.d.ts.map +1 -1
  267. package/dist/modes/index.js.map +1 -1
  268. package/dist/modes/interactive/components/armin.d.ts.map +1 -1
  269. package/dist/modes/interactive/components/armin.js.map +1 -1
  270. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  271. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  272. package/dist/modes/interactive/components/bash-execution.d.ts +1 -1
  273. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  274. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  275. package/dist/modes/interactive/components/bordered-loader.d.ts +1 -1
  276. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  277. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  278. package/dist/modes/interactive/components/branch-summary-message.d.ts +1 -1
  279. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  280. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  281. package/dist/modes/interactive/components/compaction-summary-message.d.ts +1 -1
  282. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  283. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  284. package/dist/modes/interactive/components/config-selector.d.ts +4 -4
  285. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  286. package/dist/modes/interactive/components/config-selector.js +8 -5
  287. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  288. package/dist/modes/interactive/components/countdown-timer.d.ts +2 -2
  289. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
  290. package/dist/modes/interactive/components/countdown-timer.js +2 -2
  291. package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
  292. package/dist/modes/interactive/components/custom-editor.d.ts +1 -1
  293. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  294. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  295. package/dist/modes/interactive/components/custom-message.d.ts +2 -2
  296. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  297. package/dist/modes/interactive/components/custom-message.js +0 -1
  298. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  299. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
  300. package/dist/modes/interactive/components/daxnuts.js.map +1 -1
  301. package/dist/modes/interactive/components/diff.d.ts.map +1 -1
  302. package/dist/modes/interactive/components/diff.js.map +1 -1
  303. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  304. package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  305. package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
  306. package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
  307. package/dist/modes/interactive/components/extension-editor.d.ts +1 -1
  308. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  309. package/dist/modes/interactive/components/extension-editor.js +14 -6
  310. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  311. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  312. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  313. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  314. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  315. package/dist/modes/interactive/components/footer.d.ts +15 -4
  316. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  317. package/dist/modes/interactive/components/footer.js +126 -8
  318. package/dist/modes/interactive/components/footer.js.map +1 -1
  319. package/dist/modes/interactive/components/index.d.ts +31 -31
  320. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  321. package/dist/modes/interactive/components/index.js.map +1 -1
  322. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  323. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  324. package/dist/modes/interactive/components/login-dialog.d.ts +7 -1
  325. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  326. package/dist/modes/interactive/components/login-dialog.js +28 -5
  327. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  328. package/dist/modes/interactive/components/model-selector.d.ts +2 -2
  329. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  330. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  331. package/dist/modes/interactive/components/oauth-selector.d.ts +1 -1
  332. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  333. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  334. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  335. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  336. package/dist/modes/interactive/components/session-selector-search.d.ts +1 -1
  337. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  338. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  339. package/dist/modes/interactive/components/session-selector.d.ts +3 -3
  340. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  341. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  342. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  343. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  344. package/dist/modes/interactive/components/settings-selector.js +15 -0
  345. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  346. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  347. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  348. package/dist/modes/interactive/components/skill-invocation-message.d.ts +1 -1
  349. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  350. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  351. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  352. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  353. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  354. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  355. package/dist/modes/interactive/components/tool-execution.d.ts +1 -1
  356. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  357. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  358. package/dist/modes/interactive/components/tree-selector.d.ts +1 -1
  359. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  360. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  361. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  362. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  363. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  364. package/dist/modes/interactive/components/user-message.js.map +1 -1
  365. package/dist/modes/interactive/interactive-mode.d.ts +53 -7
  366. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  367. package/dist/modes/interactive/interactive-mode.js +1247 -205
  368. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  369. package/dist/modes/interactive/theme/dark.json +5 -4
  370. package/dist/modes/interactive/theme/light.json +5 -4
  371. package/dist/modes/interactive/theme/theme.d.ts +22 -3
  372. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  373. package/dist/modes/interactive/theme/theme.js +130 -69
  374. package/dist/modes/interactive/theme/theme.js.map +1 -1
  375. package/dist/modes/print-mode.d.ts +1 -1
  376. package/dist/modes/print-mode.d.ts.map +1 -1
  377. package/dist/modes/print-mode.js.map +1 -1
  378. package/dist/modes/rpc/rpc-client.d.ts +8 -5
  379. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  380. package/dist/modes/rpc/rpc-client.js +65 -8
  381. package/dist/modes/rpc/rpc-client.js.map +1 -1
  382. package/dist/modes/rpc/rpc-mode.d.ts +2 -2
  383. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  384. package/dist/modes/rpc/rpc-mode.js +18 -4
  385. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  386. package/dist/modes/rpc/rpc-types.d.ts +5 -4
  387. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  388. package/dist/modes/rpc/rpc-types.js.map +1 -1
  389. package/dist/modes/serve/api-handlers.d.ts +4 -0
  390. package/dist/modes/serve/api-handlers.d.ts.map +1 -0
  391. package/dist/modes/serve/api-handlers.js +324 -0
  392. package/dist/modes/serve/api-handlers.js.map +1 -0
  393. package/dist/modes/serve/http-server.d.ts +14 -0
  394. package/dist/modes/serve/http-server.d.ts.map +1 -0
  395. package/dist/modes/serve/http-server.js +94 -0
  396. package/dist/modes/serve/http-server.js.map +1 -0
  397. package/dist/modes/serve/serve-mode.d.ts +10 -0
  398. package/dist/modes/serve/serve-mode.d.ts.map +1 -0
  399. package/dist/modes/serve/serve-mode.js +217 -0
  400. package/dist/modes/serve/serve-mode.js.map +1 -0
  401. package/dist/package-manager-cli.d.ts.map +1 -1
  402. package/dist/package-manager-cli.js +62 -7
  403. package/dist/package-manager-cli.js.map +1 -1
  404. package/dist/utils/ansi.d.ts.map +1 -1
  405. package/dist/utils/ansi.js +47 -72
  406. package/dist/utils/ansi.js.map +1 -1
  407. package/dist/utils/changelog.d.ts +1 -1
  408. package/dist/utils/changelog.d.ts.map +1 -1
  409. package/dist/utils/changelog.js.map +1 -1
  410. package/dist/utils/child-process.d.ts +5 -2
  411. package/dist/utils/child-process.d.ts.map +1 -1
  412. package/dist/utils/child-process.js +9 -7
  413. package/dist/utils/child-process.js.map +1 -1
  414. package/dist/utils/clipboard-image.d.ts.map +1 -1
  415. package/dist/utils/clipboard-image.js.map +1 -1
  416. package/dist/utils/clipboard-native.d.ts +3 -1
  417. package/dist/utils/clipboard-native.d.ts.map +1 -1
  418. package/dist/utils/clipboard-native.js +14 -8
  419. package/dist/utils/clipboard-native.js.map +1 -1
  420. package/dist/utils/clipboard.d.ts.map +1 -1
  421. package/dist/utils/clipboard.js.map +1 -1
  422. package/dist/utils/deprecation.d.ts +4 -0
  423. package/dist/utils/deprecation.d.ts.map +1 -0
  424. package/dist/utils/deprecation.js +13 -0
  425. package/dist/utils/deprecation.js.map +1 -0
  426. package/dist/utils/exif-orientation.d.ts +1 -1
  427. package/dist/utils/exif-orientation.d.ts.map +1 -1
  428. package/dist/utils/exif-orientation.js.map +1 -1
  429. package/dist/utils/html.d.ts +7 -0
  430. package/dist/utils/html.d.ts.map +1 -0
  431. package/dist/utils/html.js +40 -0
  432. package/dist/utils/html.js.map +1 -0
  433. package/dist/utils/image-convert.d.ts.map +1 -1
  434. package/dist/utils/image-convert.js.map +1 -1
  435. package/dist/utils/image-resize-core.d.ts +30 -0
  436. package/dist/utils/image-resize-core.d.ts.map +1 -0
  437. package/dist/utils/image-resize-core.js +124 -0
  438. package/dist/utils/image-resize-core.js.map +1 -0
  439. package/dist/utils/image-resize-worker.d.ts +2 -0
  440. package/dist/utils/image-resize-worker.d.ts.map +1 -0
  441. package/dist/utils/image-resize-worker.js +31 -0
  442. package/dist/utils/image-resize-worker.js.map +1 -0
  443. package/dist/utils/image-resize.d.ts +7 -27
  444. package/dist/utils/image-resize.d.ts.map +1 -1
  445. package/dist/utils/image-resize.js +75 -131
  446. package/dist/utils/image-resize.js.map +1 -1
  447. package/dist/utils/json.d.ts +3 -0
  448. package/dist/utils/json.d.ts.map +1 -0
  449. package/dist/utils/json.js +7 -0
  450. package/dist/utils/json.js.map +1 -0
  451. package/dist/utils/paths.d.ts +16 -1
  452. package/dist/utils/paths.d.ts.map +1 -1
  453. package/dist/utils/paths.js +49 -7
  454. package/dist/utils/paths.js.map +1 -1
  455. package/dist/utils/shell.d.ts.map +1 -1
  456. package/dist/utils/shell.js +6 -1
  457. package/dist/utils/shell.js.map +1 -1
  458. package/dist/utils/syntax-highlight.d.ts +12 -0
  459. package/dist/utils/syntax-highlight.d.ts.map +1 -0
  460. package/dist/utils/syntax-highlight.js +118 -0
  461. package/dist/utils/syntax-highlight.js.map +1 -0
  462. package/dist/utils/tools-manager.d.ts.map +1 -1
  463. package/dist/utils/tools-manager.js +4 -1
  464. package/dist/utils/tools-manager.js.map +1 -1
  465. package/dist/utils/version-check.d.ts +2 -1
  466. package/dist/utils/version-check.d.ts.map +1 -1
  467. package/dist/utils/version-check.js +9 -4
  468. package/dist/utils/version-check.js.map +1 -1
  469. package/dist/utils/windows-self-update.d.ts +3 -0
  470. package/dist/utils/windows-self-update.d.ts.map +1 -0
  471. package/dist/utils/windows-self-update.js +77 -0
  472. package/dist/utils/windows-self-update.js.map +1 -0
  473. package/docs/custom-provider.md +111 -21
  474. package/docs/development.md +1 -1
  475. package/docs/extensions.md +13 -7
  476. package/docs/index.md +13 -3
  477. package/docs/models.md +32 -13
  478. package/docs/packages.md +9 -6
  479. package/docs/providers.md +13 -5
  480. package/docs/quickstart.md +24 -1
  481. package/docs/rpc.md +2 -1
  482. package/docs/sdk.md +8 -0
  483. package/docs/session-format.md +1 -1
  484. package/docs/sessions.md +8 -0
  485. package/docs/settings.md +8 -6
  486. package/docs/skills.md +3 -4
  487. package/docs/terminal-setup.md +8 -0
  488. package/docs/termux.md +3 -3
  489. package/docs/tui.md +2 -2
  490. package/docs/usage.md +13 -2
  491. package/examples/extensions/README.md +1 -0
  492. package/examples/extensions/custom-provider-anthropic/index.ts +1 -1
  493. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  494. package/examples/extensions/custom-provider-anthropic/package.json +2 -2
  495. package/examples/extensions/custom-provider-gitlab-duo/index.ts +54 -3
  496. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  497. package/examples/extensions/custom-provider-gitlab-duo/test.ts +1 -1
  498. package/examples/extensions/doom-overlay/doom-component.ts +2 -2
  499. package/examples/extensions/doom-overlay/index.ts +3 -3
  500. package/examples/extensions/git-merge-and-resolve.ts +115 -0
  501. package/examples/extensions/input-transform-streaming.ts +39 -0
  502. package/examples/extensions/overlay-qa-tests.ts +97 -66
  503. package/examples/extensions/overlay-test.ts +7 -4
  504. package/examples/extensions/plan-mode/index.ts +1 -1
  505. package/examples/extensions/sandbox/package-lock.json +2 -2
  506. package/examples/extensions/sandbox/package.json +2 -2
  507. package/examples/extensions/subagent/README.md +3 -0
  508. package/examples/extensions/subagent/index.ts +42 -20
  509. package/examples/extensions/with-deps/package-lock.json +2 -2
  510. package/examples/extensions/with-deps/package.json +3 -3
  511. package/npm-shrinkwrap.json +1790 -0
  512. package/package.json +39 -32
  513. package/dist/utils/uuid.d.ts +0 -2
  514. package/dist/utils/uuid.d.ts.map +0 -1
  515. package/dist/utils/uuid.js +0 -40
  516. package/dist/utils/uuid.js.map +0 -1
@@ -0,0 +1,268 @@
1
+ import type { AgentMessage, ThinkingLevel } from "@sheason/pi-agent-core";
2
+ import type { Api } from "@sheason/pi-ai";
3
+ import type { AgentSessionEvent } from "./agent-session.ts";
4
+ import type { SourceInfo } from "./source-info.ts";
5
+ export interface ProxyPromptOptions {
6
+ images?: Array<{
7
+ url: string;
8
+ mediaType?: string;
9
+ }>;
10
+ streamingBehavior?: "steer" | "followUp";
11
+ }
12
+ /** A single keybinding hint entry for the startup banner. */
13
+ export interface BannerKeyHint {
14
+ /** Display text for the key (e.g. "Ctrl+C", "/", "!!") */
15
+ key: string;
16
+ /** Description of what the key does (e.g. "to interrupt", "for commands") */
17
+ description: string;
18
+ }
19
+ /** A loaded resource section (Context, Skills, Prompts, Extensions, Themes). */
20
+ export interface LoadedResourceSection {
21
+ /** Section name (e.g. "Context", "Skills", "Prompts", "Extensions", "Themes") */
22
+ name: string;
23
+ /** Compact display (single line, comma-separated) */
24
+ compactList: string;
25
+ /** Expanded display (one item per line, with paths) */
26
+ expandedList: string;
27
+ }
28
+ /** A diagnostic entry for resource conflicts/errors. */
29
+ export interface ResourceDiagnosticEntry {
30
+ /** Diagnostic type */
31
+ type: "warning" | "error" | "collision";
32
+ /** Human-readable message */
33
+ message: string;
34
+ /** File path if applicable */
35
+ path?: string;
36
+ /** Collision details if type is "collision" */
37
+ collision?: {
38
+ resourceType: "extension" | "skill" | "prompt" | "theme";
39
+ name: string;
40
+ winnerPath: string;
41
+ loserPath: string;
42
+ winnerSource?: string;
43
+ loserSource?: string;
44
+ };
45
+ }
46
+ /** Structured banner data, theme-independent so connect clients can render with their own theme. */
47
+ export interface BannerData {
48
+ /** App name */
49
+ appName: string;
50
+ /** Version string (e.g. "0.76.0") */
51
+ version: string;
52
+ /** Expanded keybinding hints (shown when banner is expanded) */
53
+ expandedHints: BannerKeyHint[];
54
+ /** Compact keybinding hints (shown when banner is collapsed) */
55
+ compactHints: BannerKeyHint[];
56
+ /** Compact onboarding text */
57
+ compactOnboarding: string;
58
+ /** Full onboarding text */
59
+ onboarding: string;
60
+ /** Loaded resource sections (Context, Skills, Prompts, etc.) */
61
+ loadedResources: LoadedResourceSection[];
62
+ /** Diagnostics (Skill conflicts, Prompt conflicts, Extension issues, etc.) */
63
+ diagnostics: Array<{
64
+ /** Section label (e.g. "Skill conflicts", "Prompt conflicts", "Extension issues") */
65
+ label: string;
66
+ /** Diagnostic entries */
67
+ entries: ResourceDiagnosticEntry[];
68
+ }>;
69
+ /** Changelog markdown for "What's New" section, or undefined if no new entries */
70
+ changelogMarkdown: string | undefined;
71
+ }
72
+ /** Cumulative token usage across all assistant messages in the session. */
73
+ export interface TokenUsage {
74
+ input: number;
75
+ output: number;
76
+ cacheRead: number;
77
+ cacheWrite: number;
78
+ cost: number;
79
+ usingSubscription: boolean;
80
+ }
81
+ /** Context window usage info for the current branch. */
82
+ export interface ContextUsageInfo {
83
+ tokens: number | null;
84
+ contextWindow: number;
85
+ percent: number | null;
86
+ }
87
+ /** Model details needed by the footer and UI. */
88
+ export interface ModelInfo {
89
+ id: string;
90
+ provider: string;
91
+ reasoning: boolean;
92
+ contextWindow: number;
93
+ }
94
+ /**
95
+ * Model item for remote model selector. Field-compatible with `Model<any>`
96
+ * (the upstream `ScopedModelsSelectorComponent`'s expected input type) so
97
+ * connect-mode callers can cast `ModelItemData[]` to `Model<any>[]` without
98
+ * fabricating missing fields. Fields mirror the relevant subset of
99
+ * `packages/ai/src/types.ts#Model`.
100
+ */
101
+ export interface ModelItemData {
102
+ id: string;
103
+ name: string;
104
+ provider: string;
105
+ api: Api;
106
+ baseUrl: string;
107
+ cost: {
108
+ input: number;
109
+ output: number;
110
+ cacheRead: number;
111
+ cacheWrite: number;
112
+ };
113
+ reasoning: boolean;
114
+ contextWindow: number;
115
+ maxTokens: number;
116
+ input: ("text" | "image")[];
117
+ }
118
+ /** Settings that can be read and modified remotely via serve mode. */
119
+ export interface RemoteSettings {
120
+ autoCompact: boolean;
121
+ thinkingLevel: ThinkingLevel;
122
+ availableThinkingLevels: readonly ThinkingLevel[];
123
+ steeringMode: "all" | "one-at-a-time";
124
+ followUpMode: "all" | "one-at-a-time";
125
+ enableSkillCommands: boolean;
126
+ doubleEscapeAction: "fork" | "tree" | "none";
127
+ showImages: boolean;
128
+ imageWidthCells: number;
129
+ autoResizeImages: boolean;
130
+ blockImages: boolean;
131
+ transport: string;
132
+ httpIdleTimeoutMs: number;
133
+ currentTheme: string;
134
+ availableThemes: string[];
135
+ hideThinkingBlock: boolean;
136
+ collapseChangelog: boolean;
137
+ enableInstallTelemetry: boolean;
138
+ treeFilterMode: string;
139
+ showHardwareCursor: boolean;
140
+ editorPaddingX: number;
141
+ autocompleteMaxVisible: number;
142
+ quietStartup: boolean;
143
+ clearOnShrink: boolean;
144
+ showTerminalProgress: boolean;
145
+ warnings: Record<string, unknown>;
146
+ }
147
+ /** Lightweight tree node for wire transport (no full message content). */
148
+ export interface TreeNodeData {
149
+ id: string;
150
+ type: string;
151
+ parentId: string | null;
152
+ timestamp: string;
153
+ label?: string;
154
+ /** Preview text for message entries */
155
+ preview?: string;
156
+ children: TreeNodeData[];
157
+ }
158
+ /** User message item for fork selector. */
159
+ export interface UserMessageItem {
160
+ id: string;
161
+ text: string;
162
+ }
163
+ /** Session info for session selector. */
164
+ export interface SessionItemData {
165
+ path: string;
166
+ id: string;
167
+ cwd: string;
168
+ name?: string;
169
+ parentSessionPath?: string;
170
+ created: string;
171
+ modified: string;
172
+ messageCount: number;
173
+ firstMessage: string;
174
+ }
175
+ /** Slash command exposed via serve mode for connect mode autocomplete. */
176
+ export interface ServeSlashCommand {
177
+ /** Command name (without leading slash) */
178
+ name: string;
179
+ /** Human-readable description */
180
+ description?: string;
181
+ /** Argument hint (e.g. "<provider/model-id>") */
182
+ argumentHint?: string;
183
+ /** What kind of command this is */
184
+ source: "builtin" | "extension" | "prompt" | "skill";
185
+ /** Source metadata (absent for builtin commands) */
186
+ sourceInfo?: SourceInfo;
187
+ }
188
+ export interface SessionStateSnapshot {
189
+ model: string;
190
+ thinkingLevel: ThinkingLevel;
191
+ isStreaming: boolean;
192
+ isCompacting: boolean;
193
+ isBashRunning: boolean;
194
+ steeringMessages: readonly string[];
195
+ followUpMessages: readonly string[];
196
+ sessionFile: string | undefined;
197
+ sessionName: string | undefined;
198
+ messages: readonly AgentMessage[];
199
+ banner: BannerData | undefined;
200
+ tokenUsage: TokenUsage;
201
+ contextUsage: ContextUsageInfo;
202
+ modelInfo: ModelInfo;
203
+ autoCompactEnabled: boolean;
204
+ cwd: string;
205
+ availableProviderCount: number;
206
+ remoteSettings: RemoteSettings;
207
+ /** Currently scoped model IDs for Ctrl+P cycling (null = all enabled) */
208
+ scopedModelIds: string[] | null;
209
+ /** Persisted enabled model patterns from settings */
210
+ enabledModelPatterns: string[] | undefined;
211
+ /** Extension paths loaded on the server — client can load the same extensions for UI */
212
+ extensionPaths: string[];
213
+ }
214
+ export interface AgentSessionProxy {
215
+ subscribe(listener: (event: AgentSessionEvent) => void): () => void;
216
+ prompt(text: string, options?: ProxyPromptOptions): Promise<void>;
217
+ steer(text: string, images?: Array<{
218
+ url: string;
219
+ mediaType?: string;
220
+ }>): void;
221
+ followUp(text: string, images?: Array<{
222
+ url: string;
223
+ mediaType?: string;
224
+ }>): void;
225
+ abort(): void;
226
+ abortBash(): void;
227
+ readonly model: string;
228
+ readonly thinkingLevel: ThinkingLevel;
229
+ readonly isStreaming: boolean;
230
+ readonly isCompacting: boolean;
231
+ readonly isBashRunning: boolean;
232
+ readonly steeringMessages: readonly string[];
233
+ readonly followUpMessages: readonly string[];
234
+ readonly sessionFile: string | undefined;
235
+ readonly sessionName: string | undefined;
236
+ readonly messages: readonly AgentMessage[];
237
+ compact(customInstructions?: string): Promise<void>;
238
+ setModel(modelId: string): void;
239
+ cycleModel(direction: 1 | -1): void;
240
+ setThinkingLevel(level: ThinkingLevel): void;
241
+ cycleThinkingLevel(direction: 1 | -1): void;
242
+ setAutoCompactEnabled(enabled: boolean): void;
243
+ setSteeringMode(mode: "all" | "one-at-a-time"): void;
244
+ setFollowUpMode(mode: "all" | "one-at-a-time"): void;
245
+ newSession(): Promise<void>;
246
+ switchSession(sessionFile: string): Promise<void>;
247
+ fork(entryId?: string): Promise<void>;
248
+ renameSession(name: string): void;
249
+ setLabel(entryId: string, label: string | undefined): void;
250
+ reload(): Promise<void>;
251
+ setScopedModels(enabledIds: string[] | null): void;
252
+ setEnabledModels(patterns: string[] | undefined): void;
253
+ /** Generic settings update — applies a batch of key/value pairs to the server's SettingsManager */
254
+ updateSettings(updates: Record<string, unknown>): void;
255
+ getTree(): TreeNodeData[];
256
+ getUserMessagesForForking(): UserMessageItem[];
257
+ getSessions(): Promise<SessionItemData[]>;
258
+ /** Async variants for remote proxies — local impl wraps sync methods */
259
+ fetchTree(): Promise<TreeNodeData[]>;
260
+ fetchUserMessages(): Promise<UserMessageItem[]>;
261
+ fetchCommands(): Promise<ServeSlashCommand[]>;
262
+ fetchModels(): Promise<ModelItemData[]>;
263
+ getCommands(): ServeSlashCommand[];
264
+ getModels(): ModelItemData[];
265
+ dispose(): void;
266
+ getSnapshot(): SessionStateSnapshot;
267
+ }
268
+ //# sourceMappingURL=agent-session-proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-session-proxy.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage, ThinkingLevel } from \"@sheason/pi-agent-core\";\nimport type { Api } from \"@sheason/pi-ai\";\nimport type { AgentSessionEvent } from \"./agent-session.ts\";\nimport type { SourceInfo } from \"./source-info.ts\";\n\nexport interface ProxyPromptOptions {\n\timages?: Array<{ url: string; mediaType?: string }>;\n\tstreamingBehavior?: \"steer\" | \"followUp\";\n}\n\n/** A single keybinding hint entry for the startup banner. */\nexport interface BannerKeyHint {\n\t/** Display text for the key (e.g. \"Ctrl+C\", \"/\", \"!!\") */\n\tkey: string;\n\t/** Description of what the key does (e.g. \"to interrupt\", \"for commands\") */\n\tdescription: string;\n}\n\n/** A loaded resource section (Context, Skills, Prompts, Extensions, Themes). */\nexport interface LoadedResourceSection {\n\t/** Section name (e.g. \"Context\", \"Skills\", \"Prompts\", \"Extensions\", \"Themes\") */\n\tname: string;\n\t/** Compact display (single line, comma-separated) */\n\tcompactList: string;\n\t/** Expanded display (one item per line, with paths) */\n\texpandedList: string;\n}\n\n/** A diagnostic entry for resource conflicts/errors. */\nexport interface ResourceDiagnosticEntry {\n\t/** Diagnostic type */\n\ttype: \"warning\" | \"error\" | \"collision\";\n\t/** Human-readable message */\n\tmessage: string;\n\t/** File path if applicable */\n\tpath?: string;\n\t/** Collision details if type is \"collision\" */\n\tcollision?: {\n\t\tresourceType: \"extension\" | \"skill\" | \"prompt\" | \"theme\";\n\t\tname: string;\n\t\twinnerPath: string;\n\t\tloserPath: string;\n\t\twinnerSource?: string;\n\t\tloserSource?: string;\n\t};\n}\n\n/** Structured banner data, theme-independent so connect clients can render with their own theme. */\nexport interface BannerData {\n\t/** App name */\n\tappName: string;\n\t/** Version string (e.g. \"0.76.0\") */\n\tversion: string;\n\t/** Expanded keybinding hints (shown when banner is expanded) */\n\texpandedHints: BannerKeyHint[];\n\t/** Compact keybinding hints (shown when banner is collapsed) */\n\tcompactHints: BannerKeyHint[];\n\t/** Compact onboarding text */\n\tcompactOnboarding: string;\n\t/** Full onboarding text */\n\tonboarding: string;\n\t/** Loaded resource sections (Context, Skills, Prompts, etc.) */\n\tloadedResources: LoadedResourceSection[];\n\t/** Diagnostics (Skill conflicts, Prompt conflicts, Extension issues, etc.) */\n\tdiagnostics: Array<{\n\t\t/** Section label (e.g. \"Skill conflicts\", \"Prompt conflicts\", \"Extension issues\") */\n\t\tlabel: string;\n\t\t/** Diagnostic entries */\n\t\tentries: ResourceDiagnosticEntry[];\n\t}>;\n\t/** Changelog markdown for \"What's New\" section, or undefined if no new entries */\n\tchangelogMarkdown: string | undefined;\n}\n\n/** Cumulative token usage across all assistant messages in the session. */\nexport interface TokenUsage {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\tcost: number;\n\tusingSubscription: boolean;\n}\n\n/** Context window usage info for the current branch. */\nexport interface ContextUsageInfo {\n\ttokens: number | null;\n\tcontextWindow: number;\n\tpercent: number | null;\n}\n\n/** Model details needed by the footer and UI. */\nexport interface ModelInfo {\n\tid: string;\n\tprovider: string;\n\treasoning: boolean;\n\tcontextWindow: number;\n}\n\n/**\n * Model item for remote model selector. Field-compatible with `Model<any>`\n * (the upstream `ScopedModelsSelectorComponent`'s expected input type) so\n * connect-mode callers can cast `ModelItemData[]` to `Model<any>[]` without\n * fabricating missing fields. Fields mirror the relevant subset of\n * `packages/ai/src/types.ts#Model`.\n */\nexport interface ModelItemData {\n\tid: string;\n\tname: string;\n\tprovider: string;\n\tapi: Api;\n\tbaseUrl: string;\n\tcost: {\n\t\tinput: number;\n\t\toutput: number;\n\t\tcacheRead: number;\n\t\tcacheWrite: number;\n\t};\n\treasoning: boolean;\n\tcontextWindow: number;\n\tmaxTokens: number;\n\tinput: (\"text\" | \"image\")[];\n}\n\n/** Settings that can be read and modified remotely via serve mode. */\nexport interface RemoteSettings {\n\tautoCompact: boolean;\n\tthinkingLevel: ThinkingLevel;\n\tavailableThinkingLevels: readonly ThinkingLevel[];\n\tsteeringMode: \"all\" | \"one-at-a-time\";\n\tfollowUpMode: \"all\" | \"one-at-a-time\";\n\tenableSkillCommands: boolean;\n\tdoubleEscapeAction: \"fork\" | \"tree\" | \"none\";\n\t// Extended server-side settings\n\tshowImages: boolean;\n\timageWidthCells: number;\n\tautoResizeImages: boolean;\n\tblockImages: boolean;\n\ttransport: string;\n\thttpIdleTimeoutMs: number;\n\tcurrentTheme: string;\n\tavailableThemes: string[];\n\thideThinkingBlock: boolean;\n\tcollapseChangelog: boolean;\n\tenableInstallTelemetry: boolean;\n\ttreeFilterMode: string;\n\tshowHardwareCursor: boolean;\n\teditorPaddingX: number;\n\tautocompleteMaxVisible: number;\n\tquietStartup: boolean;\n\tclearOnShrink: boolean;\n\tshowTerminalProgress: boolean;\n\twarnings: Record<string, unknown>;\n}\n\n/** Lightweight tree node for wire transport (no full message content). */\nexport interface TreeNodeData {\n\tid: string;\n\ttype: string;\n\tparentId: string | null;\n\ttimestamp: string;\n\tlabel?: string;\n\t/** Preview text for message entries */\n\tpreview?: string;\n\tchildren: TreeNodeData[];\n}\n\n/** User message item for fork selector. */\nexport interface UserMessageItem {\n\tid: string;\n\ttext: string;\n}\n\n/** Session info for session selector. */\nexport interface SessionItemData {\n\tpath: string;\n\tid: string;\n\tcwd: string;\n\tname?: string;\n\tparentSessionPath?: string;\n\tcreated: string;\n\tmodified: string;\n\tmessageCount: number;\n\tfirstMessage: string;\n}\n\n/** Slash command exposed via serve mode for connect mode autocomplete. */\nexport interface ServeSlashCommand {\n\t/** Command name (without leading slash) */\n\tname: string;\n\t/** Human-readable description */\n\tdescription?: string;\n\t/** Argument hint (e.g. \"<provider/model-id>\") */\n\targumentHint?: string;\n\t/** What kind of command this is */\n\tsource: \"builtin\" | \"extension\" | \"prompt\" | \"skill\";\n\t/** Source metadata (absent for builtin commands) */\n\tsourceInfo?: SourceInfo;\n}\n\nexport interface SessionStateSnapshot {\n\tmodel: string;\n\tthinkingLevel: ThinkingLevel;\n\tisStreaming: boolean;\n\tisCompacting: boolean;\n\tisBashRunning: boolean;\n\tsteeringMessages: readonly string[];\n\tfollowUpMessages: readonly string[];\n\tsessionFile: string | undefined;\n\tsessionName: string | undefined;\n\tmessages: readonly AgentMessage[];\n\tbanner: BannerData | undefined;\n\ttokenUsage: TokenUsage;\n\tcontextUsage: ContextUsageInfo;\n\tmodelInfo: ModelInfo;\n\tautoCompactEnabled: boolean;\n\tcwd: string;\n\tavailableProviderCount: number;\n\tremoteSettings: RemoteSettings;\n\t/** Currently scoped model IDs for Ctrl+P cycling (null = all enabled) */\n\tscopedModelIds: string[] | null;\n\t/** Persisted enabled model patterns from settings */\n\tenabledModelPatterns: string[] | undefined;\n\t/** Extension paths loaded on the server — client can load the same extensions for UI */\n\textensionPaths: string[];\n}\n\nexport interface AgentSessionProxy {\n\t// Event subscription\n\tsubscribe(listener: (event: AgentSessionEvent) => void): () => void;\n\n\t// Commands\n\tprompt(text: string, options?: ProxyPromptOptions): Promise<void>;\n\tsteer(text: string, images?: Array<{ url: string; mediaType?: string }>): void;\n\tfollowUp(text: string, images?: Array<{ url: string; mediaType?: string }>): void;\n\tabort(): void;\n\tabortBash(): void;\n\n\t// State queries\n\treadonly model: string;\n\treadonly thinkingLevel: ThinkingLevel;\n\treadonly isStreaming: boolean;\n\treadonly isCompacting: boolean;\n\treadonly isBashRunning: boolean;\n\treadonly steeringMessages: readonly string[];\n\treadonly followUpMessages: readonly string[];\n\treadonly sessionFile: string | undefined;\n\treadonly sessionName: string | undefined;\n\treadonly messages: readonly AgentMessage[];\n\n\t// Session operations\n\tcompact(customInstructions?: string): Promise<void>;\n\tsetModel(modelId: string): void;\n\tcycleModel(direction: 1 | -1): void;\n\tsetThinkingLevel(level: ThinkingLevel): void;\n\tcycleThinkingLevel(direction: 1 | -1): void;\n\tsetAutoCompactEnabled(enabled: boolean): void;\n\tsetSteeringMode(mode: \"all\" | \"one-at-a-time\"): void;\n\tsetFollowUpMode(mode: \"all\" | \"one-at-a-time\"): void;\n\n\t// Runtime operations\n\tnewSession(): Promise<void>;\n\tswitchSession(sessionFile: string): Promise<void>;\n\tfork(entryId?: string): Promise<void>;\n\trenameSession(name: string): void;\n\tsetLabel(entryId: string, label: string | undefined): void;\n\treload(): Promise<void>;\n\n\t// Scoped model management\n\tsetScopedModels(enabledIds: string[] | null): void;\n\tsetEnabledModels(patterns: string[] | undefined): void;\n\n\t/** Generic settings update — applies a batch of key/value pairs to the server's SettingsManager */\n\tupdateSettings(updates: Record<string, unknown>): void;\n\n\t// Data queries (for connect mode selectors)\n\tgetTree(): TreeNodeData[];\n\tgetUserMessagesForForking(): UserMessageItem[];\n\tgetSessions(): Promise<SessionItemData[]>;\n\n\t/** Async variants for remote proxies — local impl wraps sync methods */\n\tfetchTree(): Promise<TreeNodeData[]>;\n\tfetchUserMessages(): Promise<UserMessageItem[]>;\n\tfetchCommands(): Promise<ServeSlashCommand[]>;\n\tfetchModels(): Promise<ModelItemData[]>;\n\n\t// Command discovery\n\tgetCommands(): ServeSlashCommand[];\n\n\t// Model discovery\n\tgetModels(): ModelItemData[];\n\n\t// Lifecycle\n\tdispose(): void;\n\n\t// Snapshot\n\tgetSnapshot(): SessionStateSnapshot;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=agent-session-proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-session-proxy.js","sourceRoot":"","sources":["../../src/core/agent-session-proxy.ts"],"names":[],"mappings":"","sourcesContent":["import type { AgentMessage, ThinkingLevel } from \"@sheason/pi-agent-core\";\nimport type { Api } from \"@sheason/pi-ai\";\nimport type { AgentSessionEvent } from \"./agent-session.ts\";\nimport type { SourceInfo } from \"./source-info.ts\";\n\nexport interface ProxyPromptOptions {\n\timages?: Array<{ url: string; mediaType?: string }>;\n\tstreamingBehavior?: \"steer\" | \"followUp\";\n}\n\n/** A single keybinding hint entry for the startup banner. */\nexport interface BannerKeyHint {\n\t/** Display text for the key (e.g. \"Ctrl+C\", \"/\", \"!!\") */\n\tkey: string;\n\t/** Description of what the key does (e.g. \"to interrupt\", \"for commands\") */\n\tdescription: string;\n}\n\n/** A loaded resource section (Context, Skills, Prompts, Extensions, Themes). */\nexport interface LoadedResourceSection {\n\t/** Section name (e.g. \"Context\", \"Skills\", \"Prompts\", \"Extensions\", \"Themes\") */\n\tname: string;\n\t/** Compact display (single line, comma-separated) */\n\tcompactList: string;\n\t/** Expanded display (one item per line, with paths) */\n\texpandedList: string;\n}\n\n/** A diagnostic entry for resource conflicts/errors. */\nexport interface ResourceDiagnosticEntry {\n\t/** Diagnostic type */\n\ttype: \"warning\" | \"error\" | \"collision\";\n\t/** Human-readable message */\n\tmessage: string;\n\t/** File path if applicable */\n\tpath?: string;\n\t/** Collision details if type is \"collision\" */\n\tcollision?: {\n\t\tresourceType: \"extension\" | \"skill\" | \"prompt\" | \"theme\";\n\t\tname: string;\n\t\twinnerPath: string;\n\t\tloserPath: string;\n\t\twinnerSource?: string;\n\t\tloserSource?: string;\n\t};\n}\n\n/** Structured banner data, theme-independent so connect clients can render with their own theme. */\nexport interface BannerData {\n\t/** App name */\n\tappName: string;\n\t/** Version string (e.g. \"0.76.0\") */\n\tversion: string;\n\t/** Expanded keybinding hints (shown when banner is expanded) */\n\texpandedHints: BannerKeyHint[];\n\t/** Compact keybinding hints (shown when banner is collapsed) */\n\tcompactHints: BannerKeyHint[];\n\t/** Compact onboarding text */\n\tcompactOnboarding: string;\n\t/** Full onboarding text */\n\tonboarding: string;\n\t/** Loaded resource sections (Context, Skills, Prompts, etc.) */\n\tloadedResources: LoadedResourceSection[];\n\t/** Diagnostics (Skill conflicts, Prompt conflicts, Extension issues, etc.) */\n\tdiagnostics: Array<{\n\t\t/** Section label (e.g. \"Skill conflicts\", \"Prompt conflicts\", \"Extension issues\") */\n\t\tlabel: string;\n\t\t/** Diagnostic entries */\n\t\tentries: ResourceDiagnosticEntry[];\n\t}>;\n\t/** Changelog markdown for \"What's New\" section, or undefined if no new entries */\n\tchangelogMarkdown: string | undefined;\n}\n\n/** Cumulative token usage across all assistant messages in the session. */\nexport interface TokenUsage {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\tcost: number;\n\tusingSubscription: boolean;\n}\n\n/** Context window usage info for the current branch. */\nexport interface ContextUsageInfo {\n\ttokens: number | null;\n\tcontextWindow: number;\n\tpercent: number | null;\n}\n\n/** Model details needed by the footer and UI. */\nexport interface ModelInfo {\n\tid: string;\n\tprovider: string;\n\treasoning: boolean;\n\tcontextWindow: number;\n}\n\n/**\n * Model item for remote model selector. Field-compatible with `Model<any>`\n * (the upstream `ScopedModelsSelectorComponent`'s expected input type) so\n * connect-mode callers can cast `ModelItemData[]` to `Model<any>[]` without\n * fabricating missing fields. Fields mirror the relevant subset of\n * `packages/ai/src/types.ts#Model`.\n */\nexport interface ModelItemData {\n\tid: string;\n\tname: string;\n\tprovider: string;\n\tapi: Api;\n\tbaseUrl: string;\n\tcost: {\n\t\tinput: number;\n\t\toutput: number;\n\t\tcacheRead: number;\n\t\tcacheWrite: number;\n\t};\n\treasoning: boolean;\n\tcontextWindow: number;\n\tmaxTokens: number;\n\tinput: (\"text\" | \"image\")[];\n}\n\n/** Settings that can be read and modified remotely via serve mode. */\nexport interface RemoteSettings {\n\tautoCompact: boolean;\n\tthinkingLevel: ThinkingLevel;\n\tavailableThinkingLevels: readonly ThinkingLevel[];\n\tsteeringMode: \"all\" | \"one-at-a-time\";\n\tfollowUpMode: \"all\" | \"one-at-a-time\";\n\tenableSkillCommands: boolean;\n\tdoubleEscapeAction: \"fork\" | \"tree\" | \"none\";\n\t// Extended server-side settings\n\tshowImages: boolean;\n\timageWidthCells: number;\n\tautoResizeImages: boolean;\n\tblockImages: boolean;\n\ttransport: string;\n\thttpIdleTimeoutMs: number;\n\tcurrentTheme: string;\n\tavailableThemes: string[];\n\thideThinkingBlock: boolean;\n\tcollapseChangelog: boolean;\n\tenableInstallTelemetry: boolean;\n\ttreeFilterMode: string;\n\tshowHardwareCursor: boolean;\n\teditorPaddingX: number;\n\tautocompleteMaxVisible: number;\n\tquietStartup: boolean;\n\tclearOnShrink: boolean;\n\tshowTerminalProgress: boolean;\n\twarnings: Record<string, unknown>;\n}\n\n/** Lightweight tree node for wire transport (no full message content). */\nexport interface TreeNodeData {\n\tid: string;\n\ttype: string;\n\tparentId: string | null;\n\ttimestamp: string;\n\tlabel?: string;\n\t/** Preview text for message entries */\n\tpreview?: string;\n\tchildren: TreeNodeData[];\n}\n\n/** User message item for fork selector. */\nexport interface UserMessageItem {\n\tid: string;\n\ttext: string;\n}\n\n/** Session info for session selector. */\nexport interface SessionItemData {\n\tpath: string;\n\tid: string;\n\tcwd: string;\n\tname?: string;\n\tparentSessionPath?: string;\n\tcreated: string;\n\tmodified: string;\n\tmessageCount: number;\n\tfirstMessage: string;\n}\n\n/** Slash command exposed via serve mode for connect mode autocomplete. */\nexport interface ServeSlashCommand {\n\t/** Command name (without leading slash) */\n\tname: string;\n\t/** Human-readable description */\n\tdescription?: string;\n\t/** Argument hint (e.g. \"<provider/model-id>\") */\n\targumentHint?: string;\n\t/** What kind of command this is */\n\tsource: \"builtin\" | \"extension\" | \"prompt\" | \"skill\";\n\t/** Source metadata (absent for builtin commands) */\n\tsourceInfo?: SourceInfo;\n}\n\nexport interface SessionStateSnapshot {\n\tmodel: string;\n\tthinkingLevel: ThinkingLevel;\n\tisStreaming: boolean;\n\tisCompacting: boolean;\n\tisBashRunning: boolean;\n\tsteeringMessages: readonly string[];\n\tfollowUpMessages: readonly string[];\n\tsessionFile: string | undefined;\n\tsessionName: string | undefined;\n\tmessages: readonly AgentMessage[];\n\tbanner: BannerData | undefined;\n\ttokenUsage: TokenUsage;\n\tcontextUsage: ContextUsageInfo;\n\tmodelInfo: ModelInfo;\n\tautoCompactEnabled: boolean;\n\tcwd: string;\n\tavailableProviderCount: number;\n\tremoteSettings: RemoteSettings;\n\t/** Currently scoped model IDs for Ctrl+P cycling (null = all enabled) */\n\tscopedModelIds: string[] | null;\n\t/** Persisted enabled model patterns from settings */\n\tenabledModelPatterns: string[] | undefined;\n\t/** Extension paths loaded on the server — client can load the same extensions for UI */\n\textensionPaths: string[];\n}\n\nexport interface AgentSessionProxy {\n\t// Event subscription\n\tsubscribe(listener: (event: AgentSessionEvent) => void): () => void;\n\n\t// Commands\n\tprompt(text: string, options?: ProxyPromptOptions): Promise<void>;\n\tsteer(text: string, images?: Array<{ url: string; mediaType?: string }>): void;\n\tfollowUp(text: string, images?: Array<{ url: string; mediaType?: string }>): void;\n\tabort(): void;\n\tabortBash(): void;\n\n\t// State queries\n\treadonly model: string;\n\treadonly thinkingLevel: ThinkingLevel;\n\treadonly isStreaming: boolean;\n\treadonly isCompacting: boolean;\n\treadonly isBashRunning: boolean;\n\treadonly steeringMessages: readonly string[];\n\treadonly followUpMessages: readonly string[];\n\treadonly sessionFile: string | undefined;\n\treadonly sessionName: string | undefined;\n\treadonly messages: readonly AgentMessage[];\n\n\t// Session operations\n\tcompact(customInstructions?: string): Promise<void>;\n\tsetModel(modelId: string): void;\n\tcycleModel(direction: 1 | -1): void;\n\tsetThinkingLevel(level: ThinkingLevel): void;\n\tcycleThinkingLevel(direction: 1 | -1): void;\n\tsetAutoCompactEnabled(enabled: boolean): void;\n\tsetSteeringMode(mode: \"all\" | \"one-at-a-time\"): void;\n\tsetFollowUpMode(mode: \"all\" | \"one-at-a-time\"): void;\n\n\t// Runtime operations\n\tnewSession(): Promise<void>;\n\tswitchSession(sessionFile: string): Promise<void>;\n\tfork(entryId?: string): Promise<void>;\n\trenameSession(name: string): void;\n\tsetLabel(entryId: string, label: string | undefined): void;\n\treload(): Promise<void>;\n\n\t// Scoped model management\n\tsetScopedModels(enabledIds: string[] | null): void;\n\tsetEnabledModels(patterns: string[] | undefined): void;\n\n\t/** Generic settings update — applies a batch of key/value pairs to the server's SettingsManager */\n\tupdateSettings(updates: Record<string, unknown>): void;\n\n\t// Data queries (for connect mode selectors)\n\tgetTree(): TreeNodeData[];\n\tgetUserMessagesForForking(): UserMessageItem[];\n\tgetSessions(): Promise<SessionItemData[]>;\n\n\t/** Async variants for remote proxies — local impl wraps sync methods */\n\tfetchTree(): Promise<TreeNodeData[]>;\n\tfetchUserMessages(): Promise<UserMessageItem[]>;\n\tfetchCommands(): Promise<ServeSlashCommand[]>;\n\tfetchModels(): Promise<ModelItemData[]>;\n\n\t// Command discovery\n\tgetCommands(): ServeSlashCommand[];\n\n\t// Model discovery\n\tgetModels(): ModelItemData[];\n\n\t// Lifecycle\n\tdispose(): void;\n\n\t// Snapshot\n\tgetSnapshot(): SessionStateSnapshot;\n}\n"]}
@@ -1,8 +1,8 @@
1
- import type { AgentSession } from "./agent-session.js";
2
- import type { AgentSessionRuntimeDiagnostic, AgentSessionServices } from "./agent-session-services.js";
3
- import type { ReplacedSessionContext, SessionStartEvent } from "./extensions/index.js";
4
- import type { CreateAgentSessionResult } from "./sdk.js";
5
- import { SessionManager } from "./session-manager.js";
1
+ import type { AgentSession } from "./agent-session.ts";
2
+ import type { AgentSessionRuntimeDiagnostic, AgentSessionServices } from "./agent-session-services.ts";
3
+ import type { ReplacedSessionContext, SessionStartEvent } from "./extensions/index.ts";
4
+ import type { CreateAgentSessionResult } from "./sdk.ts";
5
+ import { SessionManager } from "./session-manager.ts";
6
6
  /**
7
7
  * Result returned by runtime creation.
8
8
  *
@@ -41,20 +41,20 @@ export declare class SessionImportFileNotFoundError extends Error {
41
41
  * caller. The caller is responsible for user-facing error handling.
42
42
  */
43
43
  export declare class AgentSessionRuntime {
44
+ private rebindSession?;
45
+ private beforeSessionInvalidate?;
44
46
  private _session;
45
47
  private _services;
46
48
  private readonly createRuntime;
47
49
  private _diagnostics;
48
50
  private _modelFallbackMessage?;
49
- private rebindSession?;
50
- private beforeSessionInvalidate?;
51
- constructor(_session: AgentSession, _services: AgentSessionServices, createRuntime: CreateAgentSessionRuntimeFactory, _diagnostics?: AgentSessionRuntimeDiagnostic[], _modelFallbackMessage?: string | undefined);
51
+ constructor(_session: AgentSession, _services: AgentSessionServices, createRuntime: CreateAgentSessionRuntimeFactory, _diagnostics?: AgentSessionRuntimeDiagnostic[], _modelFallbackMessage?: string);
52
52
  get services(): AgentSessionServices;
53
53
  get session(): AgentSession;
54
54
  get cwd(): string;
55
55
  get diagnostics(): readonly AgentSessionRuntimeDiagnostic[];
56
56
  get modelFallbackMessage(): string | undefined;
57
- setRebindSession(rebindSession?: (session: AgentSession) => Promise<void>): void;
57
+ setRebindSession(rebindSession?: (session: AgentSession, reason: "new" | "resume" | "fork") => Promise<void>): void;
58
58
  /**
59
59
  * Set a synchronous callback that runs after `session_shutdown` handlers finish
60
60
  * but before the current session is invalidated.
@@ -113,5 +113,5 @@ export declare function createAgentSessionRuntime(createRuntime: CreateAgentSess
113
113
  sessionManager: SessionManager;
114
114
  sessionStartEvent?: SessionStartEvent;
115
115
  }): Promise<AgentSessionRuntime>;
116
- export { type AgentSessionRuntimeDiagnostic, type AgentSessionServices, type CreateAgentSessionFromServicesOptions, type CreateAgentSessionServicesOptions, createAgentSessionFromServices, createAgentSessionServices, } from "./agent-session-services.js";
116
+ export { type AgentSessionRuntimeDiagnostic, type AgentSessionServices, type CreateAgentSessionFromServicesOptions, type CreateAgentSessionServicesOptions, createAgentSessionFromServices, createAgentSessionServices, } from "./agent-session-services.ts";
117
117
  //# sourceMappingURL=agent-session-runtime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-session-runtime.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { copyFileSync, existsSync, mkdirSync } from \"node:fs\";\nimport { basename, join, resolve } from \"node:path\";\nimport type { AgentSession } from \"./agent-session.js\";\nimport type { AgentSessionRuntimeDiagnostic, AgentSessionServices } from \"./agent-session-services.js\";\nimport type { ReplacedSessionContext, SessionShutdownEvent, SessionStartEvent } from \"./extensions/index.js\";\nimport { emitSessionShutdownEvent } from \"./extensions/runner.js\";\nimport type { CreateAgentSessionResult } from \"./sdk.js\";\nimport { assertSessionCwdExists } from \"./session-cwd.js\";\nimport { SessionManager } from \"./session-manager.js\";\n\n/**\n * Result returned by runtime creation.\n *\n * The caller gets the created session, its cwd-bound services, and all\n * diagnostics collected during setup.\n */\nexport interface CreateAgentSessionRuntimeResult extends CreateAgentSessionResult {\n\tservices: AgentSessionServices;\n\tdiagnostics: AgentSessionRuntimeDiagnostic[];\n}\n\n/**\n * Creates a full runtime for a target cwd and session manager.\n *\n * The factory closes over process-global fixed inputs, recreates cwd-bound\n * services for the effective cwd, resolves session options against those\n * services, and finally creates the AgentSession.\n */\nexport type CreateAgentSessionRuntimeFactory = (options: {\n\tcwd: string;\n\tagentDir: string;\n\tsessionManager: SessionManager;\n\tsessionStartEvent?: SessionStartEvent;\n}) => Promise<CreateAgentSessionRuntimeResult>;\n\n/**\n * Thrown when /import references a JSONL file path that does not exist.\n */\nexport class SessionImportFileNotFoundError extends Error {\n\treadonly filePath: string;\n\n\tconstructor(filePath: string) {\n\t\tsuper(`File not found: ${filePath}`);\n\t\tthis.name = \"SessionImportFileNotFoundError\";\n\t\tthis.filePath = filePath;\n\t}\n}\n\nfunction extractUserMessageText(content: string | Array<{ type: string; text?: string }>): string {\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\n\treturn content\n\t\t.filter((part): part is { type: \"text\"; text: string } => part.type === \"text\" && typeof part.text === \"string\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\");\n}\n\n/**\n * Owns the current AgentSession plus its cwd-bound services.\n *\n * Session replacement methods tear down the current runtime first, then create\n * and apply the next runtime. If creation fails, the error is propagated to the\n * caller. The caller is responsible for user-facing error handling.\n */\nexport class AgentSessionRuntime {\n\tprivate rebindSession?: (session: AgentSession) => Promise<void>;\n\tprivate beforeSessionInvalidate?: () => void;\n\n\tconstructor(\n\t\tprivate _session: AgentSession,\n\t\tprivate _services: AgentSessionServices,\n\t\tprivate readonly createRuntime: CreateAgentSessionRuntimeFactory,\n\t\tprivate _diagnostics: AgentSessionRuntimeDiagnostic[] = [],\n\t\tprivate _modelFallbackMessage?: string,\n\t) {}\n\n\tget services(): AgentSessionServices {\n\t\treturn this._services;\n\t}\n\n\tget session(): AgentSession {\n\t\treturn this._session;\n\t}\n\n\tget cwd(): string {\n\t\treturn this._services.cwd;\n\t}\n\n\tget diagnostics(): readonly AgentSessionRuntimeDiagnostic[] {\n\t\treturn this._diagnostics;\n\t}\n\n\tget modelFallbackMessage(): string | undefined {\n\t\treturn this._modelFallbackMessage;\n\t}\n\n\tsetRebindSession(rebindSession?: (session: AgentSession) => Promise<void>): void {\n\t\tthis.rebindSession = rebindSession;\n\t}\n\n\t/**\n\t * Set a synchronous callback that runs after `session_shutdown` handlers finish\n\t * but before the current session is invalidated.\n\t *\n\t * This is for host-owned UI teardown that must not yield to the event loop,\n\t * such as detaching extension-provided TUI components before the old extension\n\t * context becomes stale.\n\t */\n\tsetBeforeSessionInvalidate(beforeSessionInvalidate?: () => void): void {\n\t\tthis.beforeSessionInvalidate = beforeSessionInvalidate;\n\t}\n\n\tprivate async emitBeforeSwitch(\n\t\treason: \"new\" | \"resume\",\n\t\ttargetSessionFile?: string,\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst runner = this.session.extensionRunner;\n\t\tif (!runner.hasHandlers(\"session_before_switch\")) {\n\t\t\treturn { cancelled: false };\n\t\t}\n\n\t\tconst result = await runner.emit({\n\t\t\ttype: \"session_before_switch\",\n\t\t\treason,\n\t\t\ttargetSessionFile,\n\t\t});\n\t\treturn { cancelled: result?.cancel === true };\n\t}\n\n\tprivate async emitBeforeFork(\n\t\tentryId: string,\n\t\toptions: { position: \"before\" | \"at\" },\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst runner = this.session.extensionRunner;\n\t\tif (!runner.hasHandlers(\"session_before_fork\")) {\n\t\t\treturn { cancelled: false };\n\t\t}\n\n\t\tconst result = await runner.emit({\n\t\t\ttype: \"session_before_fork\",\n\t\t\tentryId,\n\t\t\t...options,\n\t\t});\n\t\treturn { cancelled: result?.cancel === true };\n\t}\n\n\tprivate async teardownCurrent(reason: SessionShutdownEvent[\"reason\"], targetSessionFile?: string): Promise<void> {\n\t\tawait emitSessionShutdownEvent(this.session.extensionRunner, {\n\t\t\ttype: \"session_shutdown\",\n\t\t\treason,\n\t\t\ttargetSessionFile,\n\t\t});\n\t\tthis.beforeSessionInvalidate?.();\n\t\tthis.session.dispose();\n\t}\n\n\tprivate apply(result: CreateAgentSessionRuntimeResult): void {\n\t\tthis._session = result.session;\n\t\tthis._services = result.services;\n\t\tthis._diagnostics = result.diagnostics;\n\t\tthis._modelFallbackMessage = result.modelFallbackMessage;\n\t}\n\n\tprivate async finishSessionReplacement(withSession?: (ctx: ReplacedSessionContext) => Promise<void>): Promise<void> {\n\t\tif (this.rebindSession) {\n\t\t\tawait this.rebindSession(this.session);\n\t\t}\n\t\tif (withSession) {\n\t\t\tawait withSession(this.session.createReplacedSessionContext());\n\t\t}\n\t}\n\n\tasync switchSession(\n\t\tsessionPath: string,\n\t\toptions?: { cwdOverride?: string; withSession?: (ctx: ReplacedSessionContext) => Promise<void> },\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst beforeResult = await this.emitBeforeSwitch(\"resume\", sessionPath);\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn beforeResult;\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tconst sessionManager = SessionManager.open(sessionPath, undefined, options?.cwdOverride);\n\t\tassertSessionCwdExists(sessionManager, this.cwd);\n\t\tawait this.teardownCurrent(\"resume\", sessionManager.getSessionFile());\n\t\tthis.apply(\n\t\t\tawait this.createRuntime({\n\t\t\t\tcwd: sessionManager.getCwd(),\n\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\tsessionManager,\n\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"resume\", previousSessionFile },\n\t\t\t}),\n\t\t);\n\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\treturn { cancelled: false };\n\t}\n\n\tasync newSession(options?: {\n\t\tparentSession?: string;\n\t\tsetup?: (sessionManager: SessionManager) => Promise<void>;\n\t\twithSession?: (ctx: ReplacedSessionContext) => Promise<void>;\n\t}): Promise<{ cancelled: boolean }> {\n\t\tconst beforeResult = await this.emitBeforeSwitch(\"new\");\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn beforeResult;\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tconst sessionDir = this.session.sessionManager.getSessionDir();\n\t\tconst sessionManager = SessionManager.create(this.cwd, sessionDir);\n\t\tif (options?.parentSession) {\n\t\t\tsessionManager.newSession({ parentSession: options.parentSession });\n\t\t}\n\n\t\tawait this.teardownCurrent(\"new\", sessionManager.getSessionFile());\n\t\tthis.apply(\n\t\t\tawait this.createRuntime({\n\t\t\t\tcwd: this.cwd,\n\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\tsessionManager,\n\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"new\", previousSessionFile },\n\t\t\t}),\n\t\t);\n\t\tif (options?.setup) {\n\t\t\tawait options.setup(this.session.sessionManager);\n\t\t\tthis.session.agent.state.messages = this.session.sessionManager.buildSessionContext().messages;\n\t\t}\n\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\treturn { cancelled: false };\n\t}\n\n\tasync fork(\n\t\tentryId: string,\n\t\toptions?: { position?: \"before\" | \"at\"; withSession?: (ctx: ReplacedSessionContext) => Promise<void> },\n\t): Promise<{ cancelled: boolean; selectedText?: string }> {\n\t\tconst position = options?.position ?? \"before\";\n\t\tconst beforeResult = await this.emitBeforeFork(entryId, { position });\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn { cancelled: true };\n\t\t}\n\t\tlet targetLeafId: string | null;\n\t\tlet selectedText: string | undefined;\n\n\t\tconst selectedEntry = this.session.sessionManager.getEntry(entryId);\n\t\tif (!selectedEntry) {\n\t\t\tthrow new Error(\"Invalid entry ID for forking\");\n\t\t}\n\n\t\tif (position === \"at\") {\n\t\t\ttargetLeafId = selectedEntry.id;\n\t\t} else {\n\t\t\tif (selectedEntry.type !== \"message\" || selectedEntry.message.role !== \"user\") {\n\t\t\t\tthrow new Error(\"Invalid entry ID for forking\");\n\t\t\t}\n\t\t\ttargetLeafId = selectedEntry.parentId;\n\t\t\tselectedText = extractUserMessageText(selectedEntry.message.content);\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tif (this.session.sessionManager.isPersisted()) {\n\t\t\tconst currentSessionFile = this.session.sessionFile;\n\t\t\tif (!currentSessionFile) {\n\t\t\t\tthrow new Error(\"Persisted session is missing a session file\");\n\t\t\t}\n\t\t\tconst sessionDir = this.session.sessionManager.getSessionDir();\n\t\t\tif (!targetLeafId) {\n\t\t\t\tconst sessionManager = SessionManager.create(this.cwd, sessionDir);\n\t\t\t\tsessionManager.newSession({ parentSession: currentSessionFile });\n\t\t\t\tawait this.teardownCurrent(\"fork\", sessionManager.getSessionFile());\n\t\t\t\tthis.apply(\n\t\t\t\t\tawait this.createRuntime({\n\t\t\t\t\t\tcwd: this.cwd,\n\t\t\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\t\t\tsessionManager,\n\t\t\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"fork\", previousSessionFile },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\t\t\treturn { cancelled: false, selectedText };\n\t\t\t}\n\n\t\t\tconst sourceManager = SessionManager.open(currentSessionFile, sessionDir);\n\t\t\tconst forkedSessionPath = sourceManager.createBranchedSession(targetLeafId);\n\t\t\tif (!forkedSessionPath) {\n\t\t\t\tthrow new Error(\"Failed to create forked session\");\n\t\t\t}\n\t\t\tconst sessionManager = SessionManager.open(forkedSessionPath, sessionDir);\n\t\t\tawait this.teardownCurrent(\"fork\", sessionManager.getSessionFile());\n\t\t\tthis.apply(\n\t\t\t\tawait this.createRuntime({\n\t\t\t\t\tcwd: sessionManager.getCwd(),\n\t\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\t\tsessionManager,\n\t\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"fork\", previousSessionFile },\n\t\t\t\t}),\n\t\t\t);\n\t\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\t\treturn { cancelled: false, selectedText };\n\t\t}\n\n\t\tconst sessionManager = this.session.sessionManager;\n\t\tif (!targetLeafId) {\n\t\t\tsessionManager.newSession({ parentSession: this.session.sessionFile });\n\t\t} else {\n\t\t\tsessionManager.createBranchedSession(targetLeafId);\n\t\t}\n\t\tawait this.teardownCurrent(\"fork\", sessionManager.getSessionFile());\n\t\tthis.apply(\n\t\t\tawait this.createRuntime({\n\t\t\t\tcwd: this.cwd,\n\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\tsessionManager,\n\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"fork\", previousSessionFile },\n\t\t\t}),\n\t\t);\n\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\treturn { cancelled: false, selectedText };\n\t}\n\n\t/**\n\t * Import a session JSONL file and switch runtime state to the imported session.\n\t *\n\t * @returns `{ cancelled: true }` when cancelled by `session_before_switch`, otherwise `{ cancelled: false }`.\n\t * @throws {SessionImportFileNotFoundError} When the input path does not exist.\n\t * @throws {MissingSessionCwdError} When the imported session cwd cannot be resolved and no override is provided.\n\t */\n\tasync importFromJsonl(inputPath: string, cwdOverride?: string): Promise<{ cancelled: boolean }> {\n\t\tconst resolvedPath = resolve(inputPath);\n\t\tif (!existsSync(resolvedPath)) {\n\t\t\tthrow new SessionImportFileNotFoundError(resolvedPath);\n\t\t}\n\n\t\tconst sessionDir = this.session.sessionManager.getSessionDir();\n\t\tif (!existsSync(sessionDir)) {\n\t\t\tmkdirSync(sessionDir, { recursive: true });\n\t\t}\n\n\t\tconst destinationPath = join(sessionDir, basename(resolvedPath));\n\t\tconst beforeResult = await this.emitBeforeSwitch(\"resume\", destinationPath);\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn beforeResult;\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tif (resolve(destinationPath) !== resolvedPath) {\n\t\t\tcopyFileSync(resolvedPath, destinationPath);\n\t\t}\n\n\t\tconst sessionManager = SessionManager.open(destinationPath, sessionDir, cwdOverride);\n\t\tassertSessionCwdExists(sessionManager, this.cwd);\n\t\tawait this.teardownCurrent(\"resume\", sessionManager.getSessionFile());\n\t\tthis.apply(\n\t\t\tawait this.createRuntime({\n\t\t\t\tcwd: sessionManager.getCwd(),\n\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\tsessionManager,\n\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"resume\", previousSessionFile },\n\t\t\t}),\n\t\t);\n\t\tawait this.finishSessionReplacement();\n\t\treturn { cancelled: false };\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tawait emitSessionShutdownEvent(this.session.extensionRunner, {\n\t\t\ttype: \"session_shutdown\",\n\t\t\treason: \"quit\",\n\t\t});\n\t\tthis.beforeSessionInvalidate?.();\n\t\tthis.session.dispose();\n\t}\n}\n\n/**\n * Create the initial runtime from a runtime factory and initial session target.\n *\n * The same factory is stored on the returned AgentSessionRuntime and reused for\n * later /new, /resume, /fork, and import flows.\n */\nexport async function createAgentSessionRuntime(\n\tcreateRuntime: CreateAgentSessionRuntimeFactory,\n\toptions: {\n\t\tcwd: string;\n\t\tagentDir: string;\n\t\tsessionManager: SessionManager;\n\t\tsessionStartEvent?: SessionStartEvent;\n\t},\n): Promise<AgentSessionRuntime> {\n\tassertSessionCwdExists(options.sessionManager, options.cwd);\n\tconst result = await createRuntime(options);\n\treturn new AgentSessionRuntime(\n\t\tresult.session,\n\t\tresult.services,\n\t\tcreateRuntime,\n\t\tresult.diagnostics,\n\t\tresult.modelFallbackMessage,\n\t);\n}\n\nexport {\n\ttype AgentSessionRuntimeDiagnostic,\n\ttype AgentSessionServices,\n\ttype CreateAgentSessionFromServicesOptions,\n\ttype CreateAgentSessionServicesOptions,\n\tcreateAgentSessionFromServices,\n\tcreateAgentSessionServices,\n} from \"./agent-session-services.js\";\n"]}
1
+ {"version":3,"file":"agent-session-runtime.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { copyFileSync, existsSync, mkdirSync } from \"node:fs\";\nimport { basename, join, resolve } from \"node:path\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport type { AgentSession } from \"./agent-session.ts\";\nimport type { AgentSessionRuntimeDiagnostic, AgentSessionServices } from \"./agent-session-services.ts\";\nimport type { ReplacedSessionContext, SessionShutdownEvent, SessionStartEvent } from \"./extensions/index.ts\";\nimport { emitSessionShutdownEvent } from \"./extensions/runner.ts\";\nimport type { CreateAgentSessionResult } from \"./sdk.ts\";\nimport { assertSessionCwdExists } from \"./session-cwd.ts\";\nimport { SessionManager } from \"./session-manager.ts\";\n\n/**\n * Result returned by runtime creation.\n *\n * The caller gets the created session, its cwd-bound services, and all\n * diagnostics collected during setup.\n */\nexport interface CreateAgentSessionRuntimeResult extends CreateAgentSessionResult {\n\tservices: AgentSessionServices;\n\tdiagnostics: AgentSessionRuntimeDiagnostic[];\n}\n\n/**\n * Creates a full runtime for a target cwd and session manager.\n *\n * The factory closes over process-global fixed inputs, recreates cwd-bound\n * services for the effective cwd, resolves session options against those\n * services, and finally creates the AgentSession.\n */\nexport type CreateAgentSessionRuntimeFactory = (options: {\n\tcwd: string;\n\tagentDir: string;\n\tsessionManager: SessionManager;\n\tsessionStartEvent?: SessionStartEvent;\n}) => Promise<CreateAgentSessionRuntimeResult>;\n\n/**\n * Thrown when /import references a JSONL file path that does not exist.\n */\nexport class SessionImportFileNotFoundError extends Error {\n\treadonly filePath: string;\n\n\tconstructor(filePath: string) {\n\t\tsuper(`File not found: ${filePath}`);\n\t\tthis.name = \"SessionImportFileNotFoundError\";\n\t\tthis.filePath = filePath;\n\t}\n}\n\nfunction extractUserMessageText(content: string | Array<{ type: string; text?: string }>): string {\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\n\treturn content\n\t\t.filter((part): part is { type: \"text\"; text: string } => part.type === \"text\" && typeof part.text === \"string\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\");\n}\n\n/**\n * Owns the current AgentSession plus its cwd-bound services.\n *\n * Session replacement methods tear down the current runtime first, then create\n * and apply the next runtime. If creation fails, the error is propagated to the\n * caller. The caller is responsible for user-facing error handling.\n */\nexport class AgentSessionRuntime {\n\tprivate rebindSession?: (session: AgentSession, reason: \"new\" | \"resume\" | \"fork\") => Promise<void>;\n\tprivate beforeSessionInvalidate?: () => void;\n\tprivate _session: AgentSession;\n\tprivate _services: AgentSessionServices;\n\tprivate readonly createRuntime: CreateAgentSessionRuntimeFactory;\n\tprivate _diagnostics: AgentSessionRuntimeDiagnostic[];\n\tprivate _modelFallbackMessage?: string;\n\n\tconstructor(\n\t\t_session: AgentSession,\n\t\t_services: AgentSessionServices,\n\t\tcreateRuntime: CreateAgentSessionRuntimeFactory,\n\t\t_diagnostics: AgentSessionRuntimeDiagnostic[] = [],\n\t\t_modelFallbackMessage?: string,\n\t) {\n\t\tthis._session = _session;\n\t\tthis._services = _services;\n\t\tthis.createRuntime = createRuntime;\n\t\tthis._diagnostics = _diagnostics;\n\t\tthis._modelFallbackMessage = _modelFallbackMessage;\n\t}\n\n\tget services(): AgentSessionServices {\n\t\treturn this._services;\n\t}\n\n\tget session(): AgentSession {\n\t\treturn this._session;\n\t}\n\n\tget cwd(): string {\n\t\treturn this._services.cwd;\n\t}\n\n\tget diagnostics(): readonly AgentSessionRuntimeDiagnostic[] {\n\t\treturn this._diagnostics;\n\t}\n\n\tget modelFallbackMessage(): string | undefined {\n\t\treturn this._modelFallbackMessage;\n\t}\n\n\tsetRebindSession(rebindSession?: (session: AgentSession, reason: \"new\" | \"resume\" | \"fork\") => Promise<void>): void {\n\t\tthis.rebindSession = rebindSession;\n\t}\n\n\t/**\n\t * Set a synchronous callback that runs after `session_shutdown` handlers finish\n\t * but before the current session is invalidated.\n\t *\n\t * This is for host-owned UI teardown that must not yield to the event loop,\n\t * such as detaching extension-provided TUI components before the old extension\n\t * context becomes stale.\n\t */\n\tsetBeforeSessionInvalidate(beforeSessionInvalidate?: () => void): void {\n\t\tthis.beforeSessionInvalidate = beforeSessionInvalidate;\n\t}\n\n\tprivate async emitBeforeSwitch(\n\t\treason: \"new\" | \"resume\",\n\t\ttargetSessionFile?: string,\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst runner = this.session.extensionRunner;\n\t\tif (!runner.hasHandlers(\"session_before_switch\")) {\n\t\t\treturn { cancelled: false };\n\t\t}\n\n\t\tconst result = await runner.emit({\n\t\t\ttype: \"session_before_switch\",\n\t\t\treason,\n\t\t\ttargetSessionFile,\n\t\t});\n\t\treturn { cancelled: result?.cancel === true };\n\t}\n\n\tprivate async emitBeforeFork(\n\t\tentryId: string,\n\t\toptions: { position: \"before\" | \"at\" },\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst runner = this.session.extensionRunner;\n\t\tif (!runner.hasHandlers(\"session_before_fork\")) {\n\t\t\treturn { cancelled: false };\n\t\t}\n\n\t\tconst result = await runner.emit({\n\t\t\ttype: \"session_before_fork\",\n\t\t\tentryId,\n\t\t\t...options,\n\t\t});\n\t\treturn { cancelled: result?.cancel === true };\n\t}\n\n\tprivate async teardownCurrent(reason: SessionShutdownEvent[\"reason\"], targetSessionFile?: string): Promise<void> {\n\t\tawait emitSessionShutdownEvent(this.session.extensionRunner, {\n\t\t\ttype: \"session_shutdown\",\n\t\t\treason,\n\t\t\ttargetSessionFile,\n\t\t});\n\t\tthis.beforeSessionInvalidate?.();\n\t\tthis.session.dispose();\n\t}\n\n\tprivate apply(result: CreateAgentSessionRuntimeResult): void {\n\t\tthis._session = result.session;\n\t\tthis._services = result.services;\n\t\tthis._diagnostics = result.diagnostics;\n\t\tthis._modelFallbackMessage = result.modelFallbackMessage;\n\t}\n\n\tprivate async finishSessionReplacement(\n\t\treason: \"new\" | \"resume\" | \"fork\",\n\t\twithSession?: (ctx: ReplacedSessionContext) => Promise<void>,\n\t): Promise<void> {\n\t\tif (this.rebindSession) {\n\t\t\tawait this.rebindSession(this.session, reason);\n\t\t}\n\t\tif (withSession) {\n\t\t\tawait withSession(this.session.createReplacedSessionContext());\n\t\t}\n\t}\n\n\tasync switchSession(\n\t\tsessionPath: string,\n\t\toptions?: { cwdOverride?: string; withSession?: (ctx: ReplacedSessionContext) => Promise<void> },\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst beforeResult = await this.emitBeforeSwitch(\"resume\", sessionPath);\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn beforeResult;\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tconst sessionManager = SessionManager.open(sessionPath, undefined, options?.cwdOverride);\n\t\tassertSessionCwdExists(sessionManager, this.cwd);\n\t\tawait this.teardownCurrent(\"resume\", sessionManager.getSessionFile());\n\t\tthis.apply(\n\t\t\tawait this.createRuntime({\n\t\t\t\tcwd: sessionManager.getCwd(),\n\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\tsessionManager,\n\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"resume\", previousSessionFile },\n\t\t\t}),\n\t\t);\n\t\tawait this.finishSessionReplacement(\"resume\", options?.withSession);\n\t\treturn { cancelled: false };\n\t}\n\n\tasync newSession(options?: {\n\t\tparentSession?: string;\n\t\tsetup?: (sessionManager: SessionManager) => Promise<void>;\n\t\twithSession?: (ctx: ReplacedSessionContext) => Promise<void>;\n\t}): Promise<{ cancelled: boolean }> {\n\t\tconst beforeResult = await this.emitBeforeSwitch(\"new\");\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn beforeResult;\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tconst sessionDir = this.session.sessionManager.getSessionDir();\n\t\tconst sessionManager = SessionManager.create(this.cwd, sessionDir);\n\t\tif (options?.parentSession) {\n\t\t\tsessionManager.newSession({ parentSession: options.parentSession });\n\t\t}\n\n\t\tawait this.teardownCurrent(\"new\", sessionManager.getSessionFile());\n\t\tthis.apply(\n\t\t\tawait this.createRuntime({\n\t\t\t\tcwd: this.cwd,\n\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\tsessionManager,\n\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"new\", previousSessionFile },\n\t\t\t}),\n\t\t);\n\t\tif (options?.setup) {\n\t\t\tawait options.setup(this.session.sessionManager);\n\t\t\tthis.session.agent.state.messages = this.session.sessionManager.buildSessionContext().messages;\n\t\t}\n\t\tawait this.finishSessionReplacement(\"new\", options?.withSession);\n\t\treturn { cancelled: false };\n\t}\n\n\tasync fork(\n\t\tentryId: string,\n\t\toptions?: { position?: \"before\" | \"at\"; withSession?: (ctx: ReplacedSessionContext) => Promise<void> },\n\t): Promise<{ cancelled: boolean; selectedText?: string }> {\n\t\tconst position = options?.position ?? \"before\";\n\t\tconst beforeResult = await this.emitBeforeFork(entryId, { position });\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn { cancelled: true };\n\t\t}\n\t\tlet targetLeafId: string | null;\n\t\tlet selectedText: string | undefined;\n\n\t\tconst selectedEntry = this.session.sessionManager.getEntry(entryId);\n\t\tif (!selectedEntry) {\n\t\t\tthrow new Error(\"Invalid entry ID for forking\");\n\t\t}\n\n\t\tif (position === \"at\") {\n\t\t\ttargetLeafId = selectedEntry.id;\n\t\t} else {\n\t\t\tif (selectedEntry.type !== \"message\" || selectedEntry.message.role !== \"user\") {\n\t\t\t\tthrow new Error(\"Invalid entry ID for forking\");\n\t\t\t}\n\t\t\ttargetLeafId = selectedEntry.parentId;\n\t\t\tselectedText = extractUserMessageText(selectedEntry.message.content);\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tif (this.session.sessionManager.isPersisted()) {\n\t\t\tconst currentSessionFile = this.session.sessionFile;\n\t\t\tif (!currentSessionFile) {\n\t\t\t\tthrow new Error(\"Persisted session is missing a session file\");\n\t\t\t}\n\t\t\tconst sessionDir = this.session.sessionManager.getSessionDir();\n\t\t\tif (!targetLeafId) {\n\t\t\t\tconst sessionManager = SessionManager.create(this.cwd, sessionDir);\n\t\t\t\tsessionManager.newSession({ parentSession: currentSessionFile });\n\t\t\t\tawait this.teardownCurrent(\"fork\", sessionManager.getSessionFile());\n\t\t\t\tthis.apply(\n\t\t\t\t\tawait this.createRuntime({\n\t\t\t\t\t\tcwd: this.cwd,\n\t\t\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\t\t\tsessionManager,\n\t\t\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"fork\", previousSessionFile },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tawait this.finishSessionReplacement(\"fork\", options?.withSession);\n\t\t\t\treturn { cancelled: false, selectedText };\n\t\t\t}\n\n\t\t\tconst sessionManager = SessionManager.open(currentSessionFile, sessionDir);\n\t\t\tconst forkedSessionPath = sessionManager.createBranchedSession(targetLeafId);\n\t\t\tif (!forkedSessionPath) {\n\t\t\t\tthrow new Error(\"Failed to create forked session\");\n\t\t\t}\n\t\t\tawait this.teardownCurrent(\"fork\", sessionManager.getSessionFile());\n\t\t\tthis.apply(\n\t\t\t\tawait this.createRuntime({\n\t\t\t\t\tcwd: sessionManager.getCwd(),\n\t\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\t\tsessionManager,\n\t\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"fork\", previousSessionFile },\n\t\t\t\t}),\n\t\t\t);\n\t\t\tawait this.finishSessionReplacement(\"fork\", options?.withSession);\n\t\t\treturn { cancelled: false, selectedText };\n\t\t}\n\n\t\tconst sessionManager = this.session.sessionManager;\n\t\tif (!targetLeafId) {\n\t\t\tsessionManager.newSession({ parentSession: this.session.sessionFile });\n\t\t} else {\n\t\t\tsessionManager.createBranchedSession(targetLeafId);\n\t\t}\n\t\tawait this.teardownCurrent(\"fork\", sessionManager.getSessionFile());\n\t\tthis.apply(\n\t\t\tawait this.createRuntime({\n\t\t\t\tcwd: this.cwd,\n\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\tsessionManager,\n\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"fork\", previousSessionFile },\n\t\t\t}),\n\t\t);\n\t\tawait this.finishSessionReplacement(\"fork\", options?.withSession);\n\t\treturn { cancelled: false, selectedText };\n\t}\n\n\t/**\n\t * Import a session JSONL file and switch runtime state to the imported session.\n\t *\n\t * @returns `{ cancelled: true }` when cancelled by `session_before_switch`, otherwise `{ cancelled: false }`.\n\t * @throws {SessionImportFileNotFoundError} When the input path does not exist.\n\t * @throws {MissingSessionCwdError} When the imported session cwd cannot be resolved and no override is provided.\n\t */\n\tasync importFromJsonl(inputPath: string, cwdOverride?: string): Promise<{ cancelled: boolean }> {\n\t\tconst resolvedPath = resolvePath(inputPath);\n\t\tif (!existsSync(resolvedPath)) {\n\t\t\tthrow new SessionImportFileNotFoundError(resolvedPath);\n\t\t}\n\n\t\tconst sessionDir = this.session.sessionManager.getSessionDir();\n\t\tif (!existsSync(sessionDir)) {\n\t\t\tmkdirSync(sessionDir, { recursive: true });\n\t\t}\n\n\t\tconst destinationPath = join(sessionDir, basename(resolvedPath));\n\t\tconst beforeResult = await this.emitBeforeSwitch(\"resume\", destinationPath);\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn beforeResult;\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tif (resolve(destinationPath) !== resolvedPath) {\n\t\t\tcopyFileSync(resolvedPath, destinationPath);\n\t\t}\n\n\t\tconst sessionManager = SessionManager.open(destinationPath, sessionDir, cwdOverride);\n\t\tassertSessionCwdExists(sessionManager, this.cwd);\n\t\tawait this.teardownCurrent(\"resume\", sessionManager.getSessionFile());\n\t\tthis.apply(\n\t\t\tawait this.createRuntime({\n\t\t\t\tcwd: sessionManager.getCwd(),\n\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\tsessionManager,\n\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"resume\", previousSessionFile },\n\t\t\t}),\n\t\t);\n\t\tawait this.finishSessionReplacement(\"resume\");\n\t\treturn { cancelled: false };\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tawait emitSessionShutdownEvent(this.session.extensionRunner, {\n\t\t\ttype: \"session_shutdown\",\n\t\t\treason: \"quit\",\n\t\t});\n\t\tthis.beforeSessionInvalidate?.();\n\t\tthis.session.dispose();\n\t}\n}\n\n/**\n * Create the initial runtime from a runtime factory and initial session target.\n *\n * The same factory is stored on the returned AgentSessionRuntime and reused for\n * later /new, /resume, /fork, and import flows.\n */\nexport async function createAgentSessionRuntime(\n\tcreateRuntime: CreateAgentSessionRuntimeFactory,\n\toptions: {\n\t\tcwd: string;\n\t\tagentDir: string;\n\t\tsessionManager: SessionManager;\n\t\tsessionStartEvent?: SessionStartEvent;\n\t},\n): Promise<AgentSessionRuntime> {\n\tassertSessionCwdExists(options.sessionManager, options.cwd);\n\tconst result = await createRuntime(options);\n\treturn new AgentSessionRuntime(\n\t\tresult.session,\n\t\tresult.services,\n\t\tcreateRuntime,\n\t\tresult.diagnostics,\n\t\tresult.modelFallbackMessage,\n\t);\n}\n\nexport {\n\ttype AgentSessionRuntimeDiagnostic,\n\ttype AgentSessionServices,\n\ttype CreateAgentSessionFromServicesOptions,\n\ttype CreateAgentSessionServicesOptions,\n\tcreateAgentSessionFromServices,\n\tcreateAgentSessionServices,\n} from \"./agent-session-services.ts\";\n"]}
@@ -1,5 +1,6 @@
1
1
  import { copyFileSync, existsSync, mkdirSync } from "node:fs";
2
2
  import { basename, join, resolve } from "node:path";
3
+ import { resolvePath } from "../utils/paths.js";
3
4
  import { emitSessionShutdownEvent } from "./extensions/runner.js";
4
5
  import { assertSessionCwdExists } from "./session-cwd.js";
5
6
  import { SessionManager } from "./session-manager.js";
@@ -31,13 +32,13 @@ function extractUserMessageText(content) {
31
32
  * caller. The caller is responsible for user-facing error handling.
32
33
  */
33
34
  export class AgentSessionRuntime {
35
+ rebindSession;
36
+ beforeSessionInvalidate;
34
37
  _session;
35
38
  _services;
36
39
  createRuntime;
37
40
  _diagnostics;
38
41
  _modelFallbackMessage;
39
- rebindSession;
40
- beforeSessionInvalidate;
41
42
  constructor(_session, _services, createRuntime, _diagnostics = [], _modelFallbackMessage) {
42
43
  this._session = _session;
43
44
  this._services = _services;
@@ -113,9 +114,9 @@ export class AgentSessionRuntime {
113
114
  this._diagnostics = result.diagnostics;
114
115
  this._modelFallbackMessage = result.modelFallbackMessage;
115
116
  }
116
- async finishSessionReplacement(withSession) {
117
+ async finishSessionReplacement(reason, withSession) {
117
118
  if (this.rebindSession) {
118
- await this.rebindSession(this.session);
119
+ await this.rebindSession(this.session, reason);
119
120
  }
120
121
  if (withSession) {
121
122
  await withSession(this.session.createReplacedSessionContext());
@@ -136,7 +137,7 @@ export class AgentSessionRuntime {
136
137
  sessionManager,
137
138
  sessionStartEvent: { type: "session_start", reason: "resume", previousSessionFile },
138
139
  }));
139
- await this.finishSessionReplacement(options?.withSession);
140
+ await this.finishSessionReplacement("resume", options?.withSession);
140
141
  return { cancelled: false };
141
142
  }
142
143
  async newSession(options) {
@@ -161,7 +162,7 @@ export class AgentSessionRuntime {
161
162
  await options.setup(this.session.sessionManager);
162
163
  this.session.agent.state.messages = this.session.sessionManager.buildSessionContext().messages;
163
164
  }
164
- await this.finishSessionReplacement(options?.withSession);
165
+ await this.finishSessionReplacement("new", options?.withSession);
165
166
  return { cancelled: false };
166
167
  }
167
168
  async fork(entryId, options) {
@@ -203,15 +204,14 @@ export class AgentSessionRuntime {
203
204
  sessionManager,
204
205
  sessionStartEvent: { type: "session_start", reason: "fork", previousSessionFile },
205
206
  }));
206
- await this.finishSessionReplacement(options?.withSession);
207
+ await this.finishSessionReplacement("fork", options?.withSession);
207
208
  return { cancelled: false, selectedText };
208
209
  }
209
- const sourceManager = SessionManager.open(currentSessionFile, sessionDir);
210
- const forkedSessionPath = sourceManager.createBranchedSession(targetLeafId);
210
+ const sessionManager = SessionManager.open(currentSessionFile, sessionDir);
211
+ const forkedSessionPath = sessionManager.createBranchedSession(targetLeafId);
211
212
  if (!forkedSessionPath) {
212
213
  throw new Error("Failed to create forked session");
213
214
  }
214
- const sessionManager = SessionManager.open(forkedSessionPath, sessionDir);
215
215
  await this.teardownCurrent("fork", sessionManager.getSessionFile());
216
216
  this.apply(await this.createRuntime({
217
217
  cwd: sessionManager.getCwd(),
@@ -219,7 +219,7 @@ export class AgentSessionRuntime {
219
219
  sessionManager,
220
220
  sessionStartEvent: { type: "session_start", reason: "fork", previousSessionFile },
221
221
  }));
222
- await this.finishSessionReplacement(options?.withSession);
222
+ await this.finishSessionReplacement("fork", options?.withSession);
223
223
  return { cancelled: false, selectedText };
224
224
  }
225
225
  const sessionManager = this.session.sessionManager;
@@ -236,7 +236,7 @@ export class AgentSessionRuntime {
236
236
  sessionManager,
237
237
  sessionStartEvent: { type: "session_start", reason: "fork", previousSessionFile },
238
238
  }));
239
- await this.finishSessionReplacement(options?.withSession);
239
+ await this.finishSessionReplacement("fork", options?.withSession);
240
240
  return { cancelled: false, selectedText };
241
241
  }
242
242
  /**
@@ -247,7 +247,7 @@ export class AgentSessionRuntime {
247
247
  * @throws {MissingSessionCwdError} When the imported session cwd cannot be resolved and no override is provided.
248
248
  */
249
249
  async importFromJsonl(inputPath, cwdOverride) {
250
- const resolvedPath = resolve(inputPath);
250
+ const resolvedPath = resolvePath(inputPath);
251
251
  if (!existsSync(resolvedPath)) {
252
252
  throw new SessionImportFileNotFoundError(resolvedPath);
253
253
  }
@@ -273,7 +273,7 @@ export class AgentSessionRuntime {
273
273
  sessionManager,
274
274
  sessionStartEvent: { type: "session_start", reason: "resume", previousSessionFile },
275
275
  }));
276
- await this.finishSessionReplacement();
276
+ await this.finishSessionReplacement("resume");
277
277
  return { cancelled: false };
278
278
  }
279
279
  async dispose() {