@caupulican/pi-adaptative 0.81.40 → 0.81.41

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 (406) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts.map +1 -1
  3. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js +1 -0
  4. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js.map +1 -1
  5. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.ts +1 -0
  6. package/dist/cli/args.d.ts +2 -0
  7. package/dist/cli/args.d.ts.map +1 -1
  8. package/dist/cli/args.js +22 -1
  9. package/dist/cli/args.js.map +1 -1
  10. package/dist/core/agent-paths.d.ts +6 -0
  11. package/dist/core/agent-paths.d.ts.map +1 -1
  12. package/dist/core/agent-paths.js +12 -0
  13. package/dist/core/agent-paths.js.map +1 -1
  14. package/dist/core/agent-session-contracts.d.ts +293 -0
  15. package/dist/core/agent-session-contracts.d.ts.map +1 -0
  16. package/dist/core/agent-session-contracts.js +26 -0
  17. package/dist/core/agent-session-contracts.js.map +1 -0
  18. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  19. package/dist/core/agent-session-runtime.js +3 -0
  20. package/dist/core/agent-session-runtime.js.map +1 -1
  21. package/dist/core/agent-session.d.ts +26 -405
  22. package/dist/core/agent-session.d.ts.map +1 -1
  23. package/dist/core/agent-session.js +86 -307
  24. package/dist/core/agent-session.js.map +1 -1
  25. package/dist/core/auth-storage.d.ts.map +1 -1
  26. package/dist/core/auth-storage.js +3 -1
  27. package/dist/core/auth-storage.js.map +1 -1
  28. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
  29. package/dist/core/autonomy/lane-tool-surface.js +2 -1
  30. package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
  31. package/dist/core/background-lane-controller.d.ts +3 -1
  32. package/dist/core/background-lane-controller.d.ts.map +1 -1
  33. package/dist/core/background-lane-controller.js +1 -0
  34. package/dist/core/background-lane-controller.js.map +1 -1
  35. package/dist/core/bedrock-sso-login.d.ts +16 -0
  36. package/dist/core/bedrock-sso-login.d.ts.map +1 -0
  37. package/dist/core/bedrock-sso-login.js +98 -0
  38. package/dist/core/bedrock-sso-login.js.map +1 -0
  39. package/dist/core/compaction-controller.d.ts.map +1 -1
  40. package/dist/core/compaction-controller.js +1 -1
  41. package/dist/core/compaction-controller.js.map +1 -1
  42. package/dist/core/compaction-support.d.ts +3 -8
  43. package/dist/core/compaction-support.d.ts.map +1 -1
  44. package/dist/core/compaction-support.js +3 -3
  45. package/dist/core/compaction-support.js.map +1 -1
  46. package/dist/core/context-pipeline.d.ts +1 -1
  47. package/dist/core/context-pipeline.d.ts.map +1 -1
  48. package/dist/core/context-pipeline.js +7 -33
  49. package/dist/core/context-pipeline.js.map +1 -1
  50. package/dist/core/cost/cost-summary.d.ts.map +1 -1
  51. package/dist/core/cost/cost-summary.js +5 -3
  52. package/dist/core/cost/cost-summary.js.map +1 -1
  53. package/dist/core/cost/daily-usage.d.ts.map +1 -1
  54. package/dist/core/cost/daily-usage.js +4 -5
  55. package/dist/core/cost/daily-usage.js.map +1 -1
  56. package/dist/core/default-tool-surface.d.ts.map +1 -1
  57. package/dist/core/default-tool-surface.js +1 -0
  58. package/dist/core/default-tool-surface.js.map +1 -1
  59. package/dist/core/extension-import-authority.d.ts +6 -0
  60. package/dist/core/extension-import-authority.d.ts.map +1 -0
  61. package/dist/core/extension-import-authority.js +10 -0
  62. package/dist/core/extension-import-authority.js.map +1 -0
  63. package/dist/core/extensions/loader.d.ts.map +1 -1
  64. package/dist/core/extensions/loader.js +2 -3
  65. package/dist/core/extensions/loader.js.map +1 -1
  66. package/dist/core/extensions/runner.d.ts +3 -0
  67. package/dist/core/extensions/runner.d.ts.map +1 -1
  68. package/dist/core/extensions/runner.js +14 -5
  69. package/dist/core/extensions/runner.js.map +1 -1
  70. package/dist/core/extensions/stale-context.d.ts +2 -0
  71. package/dist/core/extensions/stale-context.d.ts.map +1 -0
  72. package/dist/core/extensions/stale-context.js +2 -0
  73. package/dist/core/extensions/stale-context.js.map +1 -0
  74. package/dist/core/extensions/types.d.ts +8 -0
  75. package/dist/core/extensions/types.d.ts.map +1 -1
  76. package/dist/core/extensions/types.js.map +1 -1
  77. package/dist/core/foreground-recovery-controller.d.ts +1 -0
  78. package/dist/core/foreground-recovery-controller.d.ts.map +1 -1
  79. package/dist/core/foreground-recovery-controller.js +13 -13
  80. package/dist/core/foreground-recovery-controller.js.map +1 -1
  81. package/dist/core/goal-loop-controller.d.ts +14 -9
  82. package/dist/core/goal-loop-controller.d.ts.map +1 -1
  83. package/dist/core/goal-loop-controller.js +47 -75
  84. package/dist/core/goal-loop-controller.js.map +1 -1
  85. package/dist/core/goals/compact-goal-context.d.ts +11 -0
  86. package/dist/core/goals/compact-goal-context.d.ts.map +1 -0
  87. package/dist/core/goals/compact-goal-context.js +59 -0
  88. package/dist/core/goals/compact-goal-context.js.map +1 -0
  89. package/dist/core/goals/goal-acceptance.d.ts.map +1 -1
  90. package/dist/core/goals/goal-acceptance.js +2 -0
  91. package/dist/core/goals/goal-acceptance.js.map +1 -1
  92. package/dist/core/goals/goal-auto-continue-controller.d.ts +2 -1
  93. package/dist/core/goals/goal-auto-continue-controller.d.ts.map +1 -1
  94. package/dist/core/goals/goal-auto-continue-controller.js +5 -8
  95. package/dist/core/goals/goal-auto-continue-controller.js.map +1 -1
  96. package/dist/core/goals/goal-continuation-controller.d.ts +2 -2
  97. package/dist/core/goals/goal-continuation-controller.d.ts.map +1 -1
  98. package/dist/core/goals/goal-continuation-controller.js +42 -11
  99. package/dist/core/goals/goal-continuation-controller.js.map +1 -1
  100. package/dist/core/goals/goal-continuation-defaults.d.ts +4 -29
  101. package/dist/core/goals/goal-continuation-defaults.d.ts.map +1 -1
  102. package/dist/core/goals/goal-continuation-defaults.js +4 -32
  103. package/dist/core/goals/goal-continuation-defaults.js.map +1 -1
  104. package/dist/core/goals/goal-continuation-prompt.d.ts +8 -18
  105. package/dist/core/goals/goal-continuation-prompt.d.ts.map +1 -1
  106. package/dist/core/goals/goal-continuation-prompt.js +9 -179
  107. package/dist/core/goals/goal-continuation-prompt.js.map +1 -1
  108. package/dist/core/goals/goal-lifecycle.d.ts +35 -12
  109. package/dist/core/goals/goal-lifecycle.d.ts.map +1 -1
  110. package/dist/core/goals/goal-lifecycle.js +98 -13
  111. package/dist/core/goals/goal-lifecycle.js.map +1 -1
  112. package/dist/core/goals/goal-record.d.ts +17 -0
  113. package/dist/core/goals/goal-record.d.ts.map +1 -0
  114. package/dist/core/goals/goal-record.js +31 -0
  115. package/dist/core/goals/goal-record.js.map +1 -0
  116. package/dist/core/goals/goal-session-controller.d.ts +42 -0
  117. package/dist/core/goals/goal-session-controller.d.ts.map +1 -0
  118. package/dist/core/goals/goal-session-controller.js +128 -0
  119. package/dist/core/goals/goal-session-controller.js.map +1 -0
  120. package/dist/core/goals/goal-state.d.ts +45 -25
  121. package/dist/core/goals/goal-state.d.ts.map +1 -1
  122. package/dist/core/goals/goal-state.js +85 -15
  123. package/dist/core/goals/goal-state.js.map +1 -1
  124. package/dist/core/goals/goal-tool-core.d.ts +1 -4
  125. package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
  126. package/dist/core/goals/goal-tool-core.js +49 -34
  127. package/dist/core/goals/goal-tool-core.js.map +1 -1
  128. package/dist/core/goals/session-goal-state.d.ts +18 -8
  129. package/dist/core/goals/session-goal-state.d.ts.map +1 -1
  130. package/dist/core/goals/session-goal-state.js +134 -11
  131. package/dist/core/goals/session-goal-state.js.map +1 -1
  132. package/dist/core/human-input-controller.d.ts +47 -0
  133. package/dist/core/human-input-controller.d.ts.map +1 -0
  134. package/dist/core/human-input-controller.js +181 -0
  135. package/dist/core/human-input-controller.js.map +1 -0
  136. package/dist/core/local-runtime-controller.d.ts +1 -1
  137. package/dist/core/local-runtime-controller.d.ts.map +1 -1
  138. package/dist/core/local-runtime-controller.js.map +1 -1
  139. package/dist/core/model-capability.d.ts +0 -19
  140. package/dist/core/model-capability.d.ts.map +1 -1
  141. package/dist/core/model-capability.js +0 -19
  142. package/dist/core/model-capability.js.map +1 -1
  143. package/dist/core/model-registry.d.ts +6 -1
  144. package/dist/core/model-registry.d.ts.map +1 -1
  145. package/dist/core/model-registry.js +13 -5
  146. package/dist/core/model-registry.js.map +1 -1
  147. package/dist/core/model-resolver.d.ts +16 -1
  148. package/dist/core/model-resolver.d.ts.map +1 -1
  149. package/dist/core/model-resolver.js +32 -16
  150. package/dist/core/model-resolver.js.map +1 -1
  151. package/dist/core/model-router-controller.d.ts +1 -1
  152. package/dist/core/model-router-controller.d.ts.map +1 -1
  153. package/dist/core/model-router-controller.js.map +1 -1
  154. package/dist/core/model-selection-controller.d.ts +1 -1
  155. package/dist/core/model-selection-controller.d.ts.map +1 -1
  156. package/dist/core/model-selection-controller.js.map +1 -1
  157. package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -1
  158. package/dist/core/orchestration/delegation-ledger.js +3 -0
  159. package/dist/core/orchestration/delegation-ledger.js.map +1 -1
  160. package/dist/core/orchestration/work-state-projection.d.ts.map +1 -1
  161. package/dist/core/orchestration/work-state-projection.js +1 -1
  162. package/dist/core/orchestration/work-state-projection.js.map +1 -1
  163. package/dist/core/package-manager.d.ts.map +1 -1
  164. package/dist/core/package-manager.js +20 -3
  165. package/dist/core/package-manager.js.map +1 -1
  166. package/dist/core/profile-filter-controller.d.ts +8 -1
  167. package/dist/core/profile-filter-controller.d.ts.map +1 -1
  168. package/dist/core/profile-filter-controller.js +23 -5
  169. package/dist/core/profile-filter-controller.js.map +1 -1
  170. package/dist/core/prompt-templates.d.ts +1 -0
  171. package/dist/core/prompt-templates.d.ts.map +1 -1
  172. package/dist/core/prompt-templates.js +18 -29
  173. package/dist/core/prompt-templates.js.map +1 -1
  174. package/dist/core/reflection-controller.d.ts +1 -1
  175. package/dist/core/reflection-controller.d.ts.map +1 -1
  176. package/dist/core/reflection-controller.js +3 -1
  177. package/dist/core/reflection-controller.js.map +1 -1
  178. package/dist/core/request-auth.d.ts +7 -0
  179. package/dist/core/request-auth.d.ts.map +1 -0
  180. package/dist/core/request-auth.js +8 -0
  181. package/dist/core/request-auth.js.map +1 -0
  182. package/dist/core/resource-loader.d.ts.map +1 -1
  183. package/dist/core/resource-loader.js +16 -6
  184. package/dist/core/resource-loader.js.map +1 -1
  185. package/dist/core/risk-classifier.d.ts.map +1 -1
  186. package/dist/core/risk-classifier.js +8 -0
  187. package/dist/core/risk-classifier.js.map +1 -1
  188. package/dist/core/runtime-builder.d.ts +15 -3
  189. package/dist/core/runtime-builder.d.ts.map +1 -1
  190. package/dist/core/runtime-builder.js +132 -79
  191. package/dist/core/runtime-builder.js.map +1 -1
  192. package/dist/core/sdk.d.ts.map +1 -1
  193. package/dist/core/sdk.js +7 -1
  194. package/dist/core/sdk.js.map +1 -1
  195. package/dist/core/secrets/credential-exposure-guard.d.ts +9 -0
  196. package/dist/core/secrets/credential-exposure-guard.d.ts.map +1 -0
  197. package/dist/core/secrets/credential-exposure-guard.js +241 -0
  198. package/dist/core/secrets/credential-exposure-guard.js.map +1 -0
  199. package/dist/core/secrets/secret-dotenv.d.ts +27 -0
  200. package/dist/core/secrets/secret-dotenv.d.ts.map +1 -0
  201. package/dist/core/secrets/secret-dotenv.js +183 -0
  202. package/dist/core/secrets/secret-dotenv.js.map +1 -0
  203. package/dist/core/secrets/secret-vault-format.d.ts +112 -0
  204. package/dist/core/secrets/secret-vault-format.d.ts.map +1 -0
  205. package/dist/core/secrets/secret-vault-format.js +397 -0
  206. package/dist/core/secrets/secret-vault-format.js.map +1 -0
  207. package/dist/core/secrets/secret-vault.d.ts +72 -0
  208. package/dist/core/secrets/secret-vault.d.ts.map +1 -0
  209. package/dist/core/secrets/secret-vault.js +671 -0
  210. package/dist/core/secrets/secret-vault.js.map +1 -0
  211. package/dist/core/session-analytics.d.ts +4 -23
  212. package/dist/core/session-analytics.d.ts.map +1 -1
  213. package/dist/core/session-analytics.js +39 -69
  214. package/dist/core/session-analytics.js.map +1 -1
  215. package/dist/core/session-role.d.ts +5 -0
  216. package/dist/core/session-role.d.ts.map +1 -1
  217. package/dist/core/session-role.js +14 -1
  218. package/dist/core/session-role.js.map +1 -1
  219. package/dist/core/session-tree-navigator.d.ts +4 -6
  220. package/dist/core/session-tree-navigator.d.ts.map +1 -1
  221. package/dist/core/session-tree-navigator.js +4 -1
  222. package/dist/core/session-tree-navigator.js.map +1 -1
  223. package/dist/core/settings-manager.d.ts +1 -1
  224. package/dist/core/settings-manager.d.ts.map +1 -1
  225. package/dist/core/settings-manager.js +1 -1
  226. package/dist/core/settings-manager.js.map +1 -1
  227. package/dist/core/slash-commands.d.ts.map +1 -1
  228. package/dist/core/slash-commands.js +2 -2
  229. package/dist/core/slash-commands.js.map +1 -1
  230. package/dist/core/tool-capability-policy.d.ts.map +1 -1
  231. package/dist/core/tool-capability-policy.js +1 -0
  232. package/dist/core/tool-capability-policy.js.map +1 -1
  233. package/dist/core/tool-gate-controller.d.ts.map +1 -1
  234. package/dist/core/tool-gate-controller.js +8 -2
  235. package/dist/core/tool-gate-controller.js.map +1 -1
  236. package/dist/core/tool-protocol-controller.d.ts +2 -4
  237. package/dist/core/tool-protocol-controller.d.ts.map +1 -1
  238. package/dist/core/tool-protocol-controller.js.map +1 -1
  239. package/dist/core/tool-recovery-stats.d.ts +21 -1
  240. package/dist/core/tool-recovery-stats.d.ts.map +1 -1
  241. package/dist/core/tool-recovery-stats.js.map +1 -1
  242. package/dist/core/tools/bash.d.ts +5 -0
  243. package/dist/core/tools/bash.d.ts.map +1 -1
  244. package/dist/core/tools/bash.js +59 -5
  245. package/dist/core/tools/bash.js.map +1 -1
  246. package/dist/core/tools/delegate-status.d.ts.map +1 -1
  247. package/dist/core/tools/delegate-status.js +6 -7
  248. package/dist/core/tools/delegate-status.js.map +1 -1
  249. package/dist/core/tools/delegate.d.ts.map +1 -1
  250. package/dist/core/tools/delegate.js +6 -8
  251. package/dist/core/tools/delegate.js.map +1 -1
  252. package/dist/core/tools/git-filter.d.ts +1 -8
  253. package/dist/core/tools/git-filter.d.ts.map +1 -1
  254. package/dist/core/tools/git-filter.js +2 -63
  255. package/dist/core/tools/git-filter.js.map +1 -1
  256. package/dist/core/tools/goal.d.ts +5 -3
  257. package/dist/core/tools/goal.d.ts.map +1 -1
  258. package/dist/core/tools/goal.js +97 -19
  259. package/dist/core/tools/goal.js.map +1 -1
  260. package/dist/core/tools/index.d.ts +1 -0
  261. package/dist/core/tools/index.d.ts.map +1 -1
  262. package/dist/core/tools/index.js +1 -0
  263. package/dist/core/tools/index.js.map +1 -1
  264. package/dist/core/tools/orchestration-panel.d.ts +1 -4
  265. package/dist/core/tools/orchestration-panel.d.ts.map +1 -1
  266. package/dist/core/tools/orchestration-panel.js +0 -44
  267. package/dist/core/tools/orchestration-panel.js.map +1 -1
  268. package/dist/core/tools/output-accumulator.d.ts +11 -0
  269. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  270. package/dist/core/tools/output-accumulator.js +36 -3
  271. package/dist/core/tools/output-accumulator.js.map +1 -1
  272. package/dist/core/tools/python.d.ts +2 -0
  273. package/dist/core/tools/python.d.ts.map +1 -1
  274. package/dist/core/tools/python.js +3 -1
  275. package/dist/core/tools/python.js.map +1 -1
  276. package/dist/core/tools/read.d.ts.map +1 -1
  277. package/dist/core/tools/read.js +1 -1
  278. package/dist/core/tools/read.js.map +1 -1
  279. package/dist/core/tools/search-command-guard.d.ts +14 -0
  280. package/dist/core/tools/search-command-guard.d.ts.map +1 -0
  281. package/dist/core/tools/search-command-guard.js +333 -0
  282. package/dist/core/tools/search-command-guard.js.map +1 -0
  283. package/dist/core/tools/secret-store.d.ts +38 -0
  284. package/dist/core/tools/secret-store.d.ts.map +1 -0
  285. package/dist/core/tools/secret-store.js +412 -0
  286. package/dist/core/tools/secret-store.js.map +1 -0
  287. package/dist/core/tools/shell-command-parser.d.ts +16 -0
  288. package/dist/core/tools/shell-command-parser.d.ts.map +1 -0
  289. package/dist/core/tools/shell-command-parser.js +113 -0
  290. package/dist/core/tools/shell-command-parser.js.map +1 -0
  291. package/dist/core/tools/task-steps.d.ts.map +1 -1
  292. package/dist/core/tools/task-steps.js +4 -7
  293. package/dist/core/tools/task-steps.js.map +1 -1
  294. package/dist/core/util/atomic-file.d.ts +6 -2
  295. package/dist/core/util/atomic-file.d.ts.map +1 -1
  296. package/dist/core/util/atomic-file.js +4 -4
  297. package/dist/core/util/atomic-file.js.map +1 -1
  298. package/dist/index.d.ts +3 -2
  299. package/dist/index.d.ts.map +1 -1
  300. package/dist/index.js +2 -1
  301. package/dist/index.js.map +1 -1
  302. package/dist/main.d.ts.map +1 -1
  303. package/dist/main.js +25 -11
  304. package/dist/main.js.map +1 -1
  305. package/dist/modes/interactive/auth-dialogs-controller.d.ts +4 -0
  306. package/dist/modes/interactive/auth-dialogs-controller.d.ts.map +1 -1
  307. package/dist/modes/interactive/auth-dialogs-controller.js +60 -1
  308. package/dist/modes/interactive/auth-dialogs-controller.js.map +1 -1
  309. package/dist/modes/interactive/components/activity-lane.d.ts +55 -0
  310. package/dist/modes/interactive/components/activity-lane.d.ts.map +1 -0
  311. package/dist/modes/interactive/components/activity-lane.js +304 -0
  312. package/dist/modes/interactive/components/activity-lane.js.map +1 -0
  313. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  314. package/dist/modes/interactive/components/assistant-message.js +19 -10
  315. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  316. package/dist/modes/interactive/components/expandable-text.d.ts +12 -0
  317. package/dist/modes/interactive/components/expandable-text.d.ts.map +1 -0
  318. package/dist/modes/interactive/components/expandable-text.js +17 -0
  319. package/dist/modes/interactive/components/expandable-text.js.map +1 -0
  320. package/dist/modes/interactive/components/extension-editor.d.ts +15 -1
  321. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  322. package/dist/modes/interactive/components/extension-editor.js +30 -21
  323. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  324. package/dist/modes/interactive/components/extension-input.d.ts +1 -0
  325. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  326. package/dist/modes/interactive/components/extension-input.js +6 -1
  327. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  328. package/dist/modes/interactive/components/scoped-models-selector.d.ts +2 -2
  329. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  330. package/dist/modes/interactive/components/scoped-models-selector.js +23 -14
  331. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  332. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  333. package/dist/modes/interactive/components/settings-selector.js +4 -4
  334. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  335. package/dist/modes/interactive/components/tool-execution.d.ts +19 -11
  336. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  337. package/dist/modes/interactive/components/tool-execution.js +53 -20
  338. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  339. package/dist/modes/interactive/components/tool-group.d.ts.map +1 -1
  340. package/dist/modes/interactive/components/tool-group.js +3 -0
  341. package/dist/modes/interactive/components/tool-group.js.map +1 -1
  342. package/dist/modes/interactive/components/usage-action-selector.d.ts +16 -0
  343. package/dist/modes/interactive/components/usage-action-selector.d.ts.map +1 -0
  344. package/dist/modes/interactive/components/usage-action-selector.js +46 -0
  345. package/dist/modes/interactive/components/usage-action-selector.js.map +1 -0
  346. package/dist/modes/interactive/extension-ui-host.d.ts.map +1 -1
  347. package/dist/modes/interactive/extension-ui-host.js +1 -0
  348. package/dist/modes/interactive/extension-ui-host.js.map +1 -1
  349. package/dist/modes/interactive/external-editor.d.ts +15 -0
  350. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  351. package/dist/modes/interactive/external-editor.js +27 -19
  352. package/dist/modes/interactive/external-editor.js.map +1 -1
  353. package/dist/modes/interactive/history-reload-math.d.ts +6 -2
  354. package/dist/modes/interactive/history-reload-math.d.ts.map +1 -1
  355. package/dist/modes/interactive/history-reload-math.js +10 -5
  356. package/dist/modes/interactive/history-reload-math.js.map +1 -1
  357. package/dist/modes/interactive/interactive-event-controller.d.ts +74 -0
  358. package/dist/modes/interactive/interactive-event-controller.d.ts.map +1 -0
  359. package/dist/modes/interactive/interactive-event-controller.js +328 -0
  360. package/dist/modes/interactive/interactive-event-controller.js.map +1 -0
  361. package/dist/modes/interactive/interactive-mode.d.ts +20 -25
  362. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  363. package/dist/modes/interactive/interactive-mode.js +196 -608
  364. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  365. package/dist/modes/interactive/loaded-resources-view.d.ts +20 -0
  366. package/dist/modes/interactive/loaded-resources-view.d.ts.map +1 -0
  367. package/dist/modes/interactive/loaded-resources-view.js +147 -0
  368. package/dist/modes/interactive/loaded-resources-view.js.map +1 -0
  369. package/dist/modes/interactive/resource-display.d.ts.map +1 -1
  370. package/dist/modes/interactive/resource-display.js +8 -2
  371. package/dist/modes/interactive/resource-display.js.map +1 -1
  372. package/dist/modes/interactive/resource-shell-commands.d.ts +1 -5
  373. package/dist/modes/interactive/resource-shell-commands.d.ts.map +1 -1
  374. package/dist/modes/interactive/resource-shell-commands.js +0 -5
  375. package/dist/modes/interactive/resource-shell-commands.js.map +1 -1
  376. package/dist/modes/interactive/session-flow-commands.d.ts +10 -6
  377. package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -1
  378. package/dist/modes/interactive/session-flow-commands.js +123 -70
  379. package/dist/modes/interactive/session-flow-commands.js.map +1 -1
  380. package/dist/modes/interactive/usage-commands.d.ts +34 -0
  381. package/dist/modes/interactive/usage-commands.d.ts.map +1 -0
  382. package/dist/modes/interactive/usage-commands.js +225 -0
  383. package/dist/modes/interactive/usage-commands.js.map +1 -0
  384. package/dist/utils/shell.d.ts.map +1 -1
  385. package/dist/utils/shell.js +5 -3
  386. package/dist/utils/shell.js.map +1 -1
  387. package/dist/utils/version-check.d.ts.map +1 -1
  388. package/dist/utils/version-check.js +3 -1
  389. package/dist/utils/version-check.js.map +1 -1
  390. package/docs/UI_POLISH_ORCHESTRATION.md +25 -31
  391. package/docs/UI_QUALITY_ORCHESTRATION.md +22 -24
  392. package/docs/providers.md +9 -1
  393. package/docs/ui-reference/README.md +6 -6
  394. package/docs/ui-reference/orchestration-after.txt +14 -7
  395. package/docs/ui-reference/orchestration-before.txt +12 -6
  396. package/docs/ui-reference/orchestration-reference.txt +15 -5
  397. package/docs/usage.md +9 -1
  398. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  399. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  400. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  401. package/examples/extensions/sandbox/package-lock.json +2 -2
  402. package/examples/extensions/sandbox/package.json +1 -1
  403. package/examples/extensions/with-deps/package-lock.json +2 -2
  404. package/examples/extensions/with-deps/package.json +1 -1
  405. package/npm-shrinkwrap.json +13 -13
  406. package/package.json +4 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-session-contracts.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-contracts.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport type {\n\tAgent,\n\tAgentEvent,\n\tAgentLoopConfig,\n\tAgentMessage,\n\tAgentTool,\n\tStreamIdleOptions,\n\tThinkingLevel,\n} from \"@caupulican/pi-agent-core\";\nimport type { CompactionResult, SessionManager } from \"@caupulican/pi-agent-core/node\";\nimport type { Api, CacheRetention, ImageContent, Message, Model, StopReason, Usage } from \"@caupulican/pi-ai\";\nimport type { LaneRecord, LaneTerminalStatus } from \"./autonomy/lane-tracker.ts\";\nimport type { WorkerRunOutcome } from \"./delegation/worker-runner.ts\";\nimport type {\n\tContextUsage,\n\tExtensionCommandContextActions,\n\tExtensionContext,\n\tExtensionErrorListener,\n\tExtensionRunner,\n\tExtensionUIContext,\n\tInputSource,\n\tSessionStartEvent,\n\tShutdownHandler,\n\tToolDefinition,\n} from \"./extensions/index.ts\";\nimport type { GoalContinuationPrompt } from \"./goals/goal-continuation-prompt.ts\";\nimport type { GoalRuntimeSnapshot } from \"./goals/goal-runtime-snapshot.ts\";\nimport type { ModelRegistry } from \"./model-registry.ts\";\nimport type { LocalRuntimeDeps } from \"./models/local-runtime.ts\";\nimport type { OrchestrationProfile } from \"./orchestration/contracts.ts\";\nimport type { ResearchRunResult } from \"./research/research-runner.ts\";\nimport type { collectWorkspaceSources } from \"./research/workspace-collector.ts\";\nimport type { ResourceLoader } from \"./resource-loader.ts\";\nimport type { ResourceProfileFilterSettings, SettingsManager } from \"./settings-manager.ts\";\nimport type { ToolArgumentValidationStats } from \"./tool-recovery-stats.ts\";\n\n/** Parsed skill block from a user message. */\nexport interface ParsedSkillBlock {\n\tname: string;\n\tlocation: string;\n\tcontent: string;\n\tuserMessage: string | undefined;\n}\n\n/** Parse a skill block from message text, or return null when none is present. */\nexport function parseSkillBlock(text: string): ParsedSkillBlock | null {\n\tconst match = text.match(/^<skill name=\"([^\"]+)\" location=\"([^\"]+)\">\\n([\\s\\S]*?)\\n<\\/skill>(?:\\n\\n([\\s\\S]+))?$/);\n\tif (!match) return null;\n\treturn {\n\t\tname: match[1],\n\t\tlocation: match[2],\n\t\tcontent: match[3],\n\t\tuserMessage: match[4]?.trim() || undefined,\n\t};\n}\n\n/** Session-specific events that extend the core AgentEvent. */\nexport type AgentSessionEvent =\n\t| Exclude<AgentEvent, { type: \"agent_end\" }>\n\t| { type: \"agent_end\"; messages: AgentMessage[]; willRetry: boolean }\n\t| {\n\t\t\ttype: \"queue_update\";\n\t\t\tsteering: readonly string[];\n\t\t\tfollowUp: readonly string[];\n\t\t\tcommands: readonly string[];\n\t }\n\t| { type: \"compaction_start\"; reason: \"manual\" | \"threshold\" | \"overflow\" }\n\t| { type: \"session_info_changed\"; name: string | undefined }\n\t| { type: \"thinking_level_changed\"; level: ThinkingLevel }\n\t| { type: \"warning\"; message: string }\n\t| {\n\t\t\ttype: \"compaction_end\";\n\t\t\treason: \"manual\" | \"threshold\" | \"overflow\";\n\t\t\tresult: CompactionResult | undefined;\n\t\t\taborted: boolean;\n\t\t\twillRetry: boolean;\n\t\t\terrorMessage?: string;\n\t\t\t/** Benign no-op explanation when compaction did not produce a result. */\n\t\t\tskipReason?: string;\n\t }\n\t| { type: \"auto_retry_start\"; attempt: number; maxAttempts: number; delayMs: number; errorMessage: string }\n\t| { type: \"auto_retry_end\"; success: boolean; attempt: number; finalError?: string }\n\t/** UI-only bracket around foreground routing/preparation. Always paired with `routing_end`. */\n\t| { type: \"routing_start\" }\n\t| { type: \"routing_end\" }\n\t| {\n\t\t\ttype: \"delegate_workers\";\n\t\t\tactive: number;\n\t\t\tqueued: number;\n\t\t\trunning: number;\n\t\t\tcompletedSinceFlush: number;\n\t\t\tfailedSinceFlush: number;\n\t\t\tterminalSinceFlush: Array<{ laneId: string; status: LaneTerminalStatus; reasonCode?: string }>;\n\t };\n\nexport type AgentSessionEventListener = (event: AgentSessionEvent) => void;\n\nexport interface AgentSessionConfig {\n\tagent: Agent;\n\tsessionManager: SessionManager;\n\tsettingsManager: SettingsManager;\n\tcwd: string;\n\t/** User-level agent state directory for generated runtime artifacts. */\n\tagentDir?: string;\n\t/** Models available to the interactive model-cycle action. */\n\tscopedModels?: Array<{ model: Model<Api>; thinkingLevel?: ThinkingLevel }>;\n\tresourceLoader: ResourceLoader;\n\t/** SDK tools registered outside extensions. */\n\tcustomTools?: ToolDefinition[];\n\tmodelRegistry: ModelRegistry;\n\t/** Initial active tool names before profile and UAC filtering. */\n\tinitialActiveToolNames?: string[];\n\t/** Optional tool allowlist. */\n\tallowedToolNames?: string[];\n\t/** Optional tool denylist. */\n\texcludedToolNames?: string[];\n\ttoolProfileFilter?: ResourceProfileFilterSettings;\n\t/** Preserve an explicit launch-time model across profile reloads. */\n\tisExplicitModel?: boolean;\n\t/** Preserve an explicit launch-time thinking level across profile reloads. */\n\tisExplicitThinking?: boolean;\n\t/** Child sessions receive the worker UAC and write ceilings. */\n\tisChildSession?: boolean;\n\t/** Alternate base tool instances for embedded/custom runtimes. */\n\tbaseToolsOverride?: Record<string, AgentTool>;\n\t/** Mutable bridge used by the agent loop to reach the current extension generation. */\n\textensionRunnerRef?: { current?: ExtensionRunner };\n\tsessionStartEvent?: SessionStartEvent;\n\t/** Injectable pointer-first workspace collector; tests use this to avoid process execution. */\n\tcollectWorkspaceSources?: typeof collectWorkspaceSources;\n\t/** Immutable owner-authored orchestration policy. */\n\torchestrationProfile?: OrchestrationProfile;\n\t/** Injectable local-runtime I/O dependencies. */\n\tlocalRuntimeDeps?: LocalRuntimeDeps;\n}\n\nexport interface ExtensionBindings {\n\tuiContext?: ExtensionUIContext;\n\tmode?: ExtensionContext[\"mode\"];\n\tcommandContextActions?: ExtensionCommandContextActions;\n\tabortHandler?: () => void;\n\tshutdownHandler?: ShutdownHandler;\n\tonError?: ExtensionErrorListener;\n}\n\nexport interface PromptOptions {\n\t/** Expand file prompt templates and skills. Defaults to true. */\n\texpandPromptTemplates?: boolean;\n\t/** Process slash commands before model submission. Defaults to `expandPromptTemplates`. */\n\tprocessSlashCommands?: boolean;\n\timages?: ImageContent[];\n\t/** Required queue behavior when a foreground turn is already streaming. */\n\tstreamingBehavior?: \"steer\" | \"followUp\";\n\tsource?: InputSource;\n\t/** Observe whether prompt preflight accepted the request. */\n\tpreflightResult?: (success: boolean) => void;\n\t/** Permit idle goal continuation after this prompt settles. Defaults to true. */\n\tautoContinueGoal?: boolean;\n\t/** Hidden internal turn persisted as a typed context marker. */\n\tinternalContextType?: string;\n}\n\nexport interface ModelCycleResult {\n\tmodel: Model<Api>;\n\tthinkingLevel: ThinkingLevel;\n\t/** Whether cycling was constrained to launch-scoped models. */\n\tisScoped: boolean;\n}\n\nexport interface CompactionGateCheckStats {\n\tfailures: number;\n\tminScore?: number;\n\tmaxScore?: number;\n\tthreshold?: number;\n\tcomparator?: \"minimum\" | \"maximum\";\n}\n\nexport interface CompactionGateStats {\n\tgateFailures: number;\n\tdeterministicGapFills: number;\n\tcompactionsWithGateFailures: number;\n\tchecks: Record<string, CompactionGateCheckStats>;\n}\n\nexport interface SessionStats {\n\tsessionFile: string | undefined;\n\tsessionId: string;\n\tuserMessages: number;\n\tassistantMessages: number;\n\ttoolCalls: number;\n\ttoolResults: number;\n\ttotalMessages: number;\n\ttokens: { input: number; output: number; cacheRead: number; cacheWrite: number; total: number };\n\tcost: number;\n\tcontextUsage?: ContextUsage;\n\ttoolArgumentValidation: ToolArgumentValidationStats;\n\tcompactionGates: CompactionGateStats;\n}\n\nexport const SPAWNED_USAGE_CUSTOM_TYPE = \"spawned_usage\";\nexport const RUNAWAY_STOP_CUSTOM_TYPE = \"runaway_stop\";\nexport const TOOL_VALIDATION_ESCALATION_CUSTOM_TYPE = \"tool_validation_escalation\";\n\nexport interface RunawayStopRecord {\n\tsignature: string;\n\trepeats: number;\n\tmodel?: string;\n\tprovider?: string;\n\tat: string;\n}\n\nexport interface ToolValidationEscalationRecord {\n\ttool: string;\n\tsignature: string;\n\trepeats: number;\n\tmodel: string;\n\tprovider: string;\n\tat: string;\n}\n\nexport interface SpawnedUsageReport {\n\t/** Cumulative child usage, including that child's already-rolled-up descendants. */\n\tusage: Usage;\n\tlabel?: string;\n\tsourceSessionId?: string;\n\t/** Stable idempotency identity for retry-safe ingestion. */\n\treportId?: string;\n}\n\nexport interface SpawnedUsageTotals {\n\tcost: number;\n\treports: number;\n}\n\nexport interface IsolatedCompletionOptions {\n\tsystemPrompt: string;\n\t/** Isolated conversation; foreground session history is never inherited. */\n\tmessages: Message[];\n\tmodel?: Model<Api>;\n\tthinkingLevel?: ThinkingLevel;\n\tmaxTokens?: number;\n\t/** Fresh child-owned tool instances. Omission preserves one-shot behavior. */\n\ttools?: AgentTool[];\n\t/** Explicit child-loop turn cap. */\n\tmaxTurns?: number;\n\t/** Optional tool-free finalization prompt after the bounded tool loop. */\n\tfinalTextPrompt?: string;\n\t/** Child-only capability/path gate. */\n\tbeforeToolCall?: AgentLoopConfig[\"beforeToolCall\"];\n\t/** Child-only result observer. */\n\tafterToolCall?: AgentLoopConfig[\"afterToolCall\"];\n\tsignal?: AbortSignal;\n\t/** Required cache policy; isolated calls never inherit a provider default implicitly. */\n\tcacheRetention: CacheRetention;\n\t/** Stable namespace used to derive provider cache affinity. */\n\tlaneKind?: string;\n}\n\nexport const DEFAULT_ISOLATED_LANE_KIND = \"isolated\";\n\nexport function computeLaneAffinityKey(laneKind: string, model: Model<Api> | undefined, systemPrompt: string): string {\n\tconst modelKey = model ? `${model.provider}/${model.id}` : \"unknown-model\";\n\tconst digest = createHash(\"sha256\")\n\t\t.update([\"pi-lane-affinity-v1\", laneKind, modelKey, systemPrompt].join(\"\\u0000\"))\n\t\t.digest(\"hex\")\n\t\t.slice(0, 32);\n\treturn `lane:${laneKind}:${digest}`;\n}\n\nexport interface IsolatedCompletionResult {\n\ttext: string;\n\tusage: Usage;\n\tstopReason: StopReason;\n}\n\nexport interface ResearchLaneRunOutcome {\n\tstarted: boolean;\n\tskipReason?: string;\n\trecord?: LaneRecord;\n\tresult?: ResearchRunResult;\n}\n\nexport interface WorkerDelegationRunOutcome {\n\tstarted: boolean;\n\tskipReason?: string;\n\trecord?: LaneRecord;\n\toutcome?: WorkerRunOutcome;\n}\n\nexport interface GoalContinuationOnceOptions {\n\t/** Consecutive non-progress passes allowed before deterministic escalation; 0 disables the gate. */\n\tmaxStallTurns: number;\n}\n\nexport interface GoalContinuationOnceResult {\n\tsubmitted: boolean;\n\tsnapshot: GoalRuntimeSnapshot;\n\tprompt?: GoalContinuationPrompt;\n}\n\nexport type GoalContinuationLoopStopReason =\n\t| \"continuation_not_allowed\"\n\t| \"max_turns_reached\"\n\t| \"wall_clock_budget_reached\"\n\t| \"goal_budget_exhausted\"\n\t| \"already_continuing\"\n\t| \"session_disposed\"\n\t| \"goal_tool_unavailable\"\n\t| \"worker_in_flight\";\n\nexport interface GoalContinuationLoopOptions extends GoalContinuationOnceOptions {\n\t/** Explicit per-invocation turn limit; 0 means unbounded. */\n\tmaxTurns: number;\n\t/** Explicit per-invocation active-time limit; 0/undefined means unbounded. */\n\tmaxWallClockMinutes?: number;\n\t/** Injectable monotonic-enough clock for deterministic tests. */\n\tnow?: () => number;\n}\n\nexport interface GoalContinuationLoopResult {\n\tturnsSubmitted: number;\n\tstopReason: GoalContinuationLoopStopReason;\n\tfinalSnapshot: GoalRuntimeSnapshot;\n}\n\n/** Test-only stream watchdog override contract retained in the public session module. */\nexport type StreamIdleOptionsOverride = Partial<StreamIdleOptions> | undefined;\n"]}
@@ -0,0 +1,26 @@
1
+ import { createHash } from "node:crypto";
2
+ /** Parse a skill block from message text, or return null when none is present. */
3
+ export function parseSkillBlock(text) {
4
+ const match = text.match(/^<skill name="([^"]+)" location="([^"]+)">\n([\s\S]*?)\n<\/skill>(?:\n\n([\s\S]+))?$/);
5
+ if (!match)
6
+ return null;
7
+ return {
8
+ name: match[1],
9
+ location: match[2],
10
+ content: match[3],
11
+ userMessage: match[4]?.trim() || undefined,
12
+ };
13
+ }
14
+ export const SPAWNED_USAGE_CUSTOM_TYPE = "spawned_usage";
15
+ export const RUNAWAY_STOP_CUSTOM_TYPE = "runaway_stop";
16
+ export const TOOL_VALIDATION_ESCALATION_CUSTOM_TYPE = "tool_validation_escalation";
17
+ export const DEFAULT_ISOLATED_LANE_KIND = "isolated";
18
+ export function computeLaneAffinityKey(laneKind, model, systemPrompt) {
19
+ const modelKey = model ? `${model.provider}/${model.id}` : "unknown-model";
20
+ const digest = createHash("sha256")
21
+ .update(["pi-lane-affinity-v1", laneKind, modelKey, systemPrompt].join("\u0000"))
22
+ .digest("hex")
23
+ .slice(0, 32);
24
+ return `lane:${laneKind}:${digest}`;
25
+ }
26
+ //# sourceMappingURL=agent-session-contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-session-contracts.js","sourceRoot":"","sources":["../../src/core/agent-session-contracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA6CzC,kFAAkF;AAClF,MAAM,UAAU,eAAe,CAAC,IAAY,EAA2B;IACtE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,sFAAsF,CAAC,CAAC;IACjH,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO;QACN,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;QACd,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;QAClB,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;QACjB,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,SAAS;KAC1C,CAAC;AAAA,CACF;AAiJD,MAAM,CAAC,MAAM,yBAAyB,GAAG,eAAe,CAAC;AACzD,MAAM,CAAC,MAAM,wBAAwB,GAAG,cAAc,CAAC;AACvD,MAAM,CAAC,MAAM,sCAAsC,GAAG,4BAA4B,CAAC;AAyDnF,MAAM,CAAC,MAAM,0BAA0B,GAAG,UAAU,CAAC;AAErD,MAAM,UAAU,sBAAsB,CAAC,QAAgB,EAAE,KAA6B,EAAE,YAAoB,EAAU;IACrH,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC;IAC3E,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC;SACjC,MAAM,CAAC,CAAC,qBAAqB,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;SAChF,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACf,OAAO,QAAQ,QAAQ,IAAI,MAAM,EAAE,CAAC;AAAA,CACpC","sourcesContent":["import { createHash } from \"node:crypto\";\nimport type {\n\tAgent,\n\tAgentEvent,\n\tAgentLoopConfig,\n\tAgentMessage,\n\tAgentTool,\n\tStreamIdleOptions,\n\tThinkingLevel,\n} from \"@caupulican/pi-agent-core\";\nimport type { CompactionResult, SessionManager } from \"@caupulican/pi-agent-core/node\";\nimport type { Api, CacheRetention, ImageContent, Message, Model, StopReason, Usage } from \"@caupulican/pi-ai\";\nimport type { LaneRecord, LaneTerminalStatus } from \"./autonomy/lane-tracker.ts\";\nimport type { WorkerRunOutcome } from \"./delegation/worker-runner.ts\";\nimport type {\n\tContextUsage,\n\tExtensionCommandContextActions,\n\tExtensionContext,\n\tExtensionErrorListener,\n\tExtensionRunner,\n\tExtensionUIContext,\n\tInputSource,\n\tSessionStartEvent,\n\tShutdownHandler,\n\tToolDefinition,\n} from \"./extensions/index.ts\";\nimport type { GoalContinuationPrompt } from \"./goals/goal-continuation-prompt.ts\";\nimport type { GoalRuntimeSnapshot } from \"./goals/goal-runtime-snapshot.ts\";\nimport type { ModelRegistry } from \"./model-registry.ts\";\nimport type { LocalRuntimeDeps } from \"./models/local-runtime.ts\";\nimport type { OrchestrationProfile } from \"./orchestration/contracts.ts\";\nimport type { ResearchRunResult } from \"./research/research-runner.ts\";\nimport type { collectWorkspaceSources } from \"./research/workspace-collector.ts\";\nimport type { ResourceLoader } from \"./resource-loader.ts\";\nimport type { ResourceProfileFilterSettings, SettingsManager } from \"./settings-manager.ts\";\nimport type { ToolArgumentValidationStats } from \"./tool-recovery-stats.ts\";\n\n/** Parsed skill block from a user message. */\nexport interface ParsedSkillBlock {\n\tname: string;\n\tlocation: string;\n\tcontent: string;\n\tuserMessage: string | undefined;\n}\n\n/** Parse a skill block from message text, or return null when none is present. */\nexport function parseSkillBlock(text: string): ParsedSkillBlock | null {\n\tconst match = text.match(/^<skill name=\"([^\"]+)\" location=\"([^\"]+)\">\\n([\\s\\S]*?)\\n<\\/skill>(?:\\n\\n([\\s\\S]+))?$/);\n\tif (!match) return null;\n\treturn {\n\t\tname: match[1],\n\t\tlocation: match[2],\n\t\tcontent: match[3],\n\t\tuserMessage: match[4]?.trim() || undefined,\n\t};\n}\n\n/** Session-specific events that extend the core AgentEvent. */\nexport type AgentSessionEvent =\n\t| Exclude<AgentEvent, { type: \"agent_end\" }>\n\t| { type: \"agent_end\"; messages: AgentMessage[]; willRetry: boolean }\n\t| {\n\t\t\ttype: \"queue_update\";\n\t\t\tsteering: readonly string[];\n\t\t\tfollowUp: readonly string[];\n\t\t\tcommands: readonly string[];\n\t }\n\t| { type: \"compaction_start\"; reason: \"manual\" | \"threshold\" | \"overflow\" }\n\t| { type: \"session_info_changed\"; name: string | undefined }\n\t| { type: \"thinking_level_changed\"; level: ThinkingLevel }\n\t| { type: \"warning\"; message: string }\n\t| {\n\t\t\ttype: \"compaction_end\";\n\t\t\treason: \"manual\" | \"threshold\" | \"overflow\";\n\t\t\tresult: CompactionResult | undefined;\n\t\t\taborted: boolean;\n\t\t\twillRetry: boolean;\n\t\t\terrorMessage?: string;\n\t\t\t/** Benign no-op explanation when compaction did not produce a result. */\n\t\t\tskipReason?: string;\n\t }\n\t| { type: \"auto_retry_start\"; attempt: number; maxAttempts: number; delayMs: number; errorMessage: string }\n\t| { type: \"auto_retry_end\"; success: boolean; attempt: number; finalError?: string }\n\t/** UI-only bracket around foreground routing/preparation. Always paired with `routing_end`. */\n\t| { type: \"routing_start\" }\n\t| { type: \"routing_end\" }\n\t| {\n\t\t\ttype: \"delegate_workers\";\n\t\t\tactive: number;\n\t\t\tqueued: number;\n\t\t\trunning: number;\n\t\t\tcompletedSinceFlush: number;\n\t\t\tfailedSinceFlush: number;\n\t\t\tterminalSinceFlush: Array<{ laneId: string; status: LaneTerminalStatus; reasonCode?: string }>;\n\t };\n\nexport type AgentSessionEventListener = (event: AgentSessionEvent) => void;\n\nexport interface AgentSessionConfig {\n\tagent: Agent;\n\tsessionManager: SessionManager;\n\tsettingsManager: SettingsManager;\n\tcwd: string;\n\t/** User-level agent state directory for generated runtime artifacts. */\n\tagentDir?: string;\n\t/** Models available to the interactive model-cycle action. */\n\tscopedModels?: Array<{ model: Model<Api>; thinkingLevel?: ThinkingLevel }>;\n\tresourceLoader: ResourceLoader;\n\t/** SDK tools registered outside extensions. */\n\tcustomTools?: ToolDefinition[];\n\tmodelRegistry: ModelRegistry;\n\t/** Initial active tool names before profile and UAC filtering. */\n\tinitialActiveToolNames?: string[];\n\t/** Optional tool allowlist. */\n\tallowedToolNames?: string[];\n\t/** Optional tool denylist. */\n\texcludedToolNames?: string[];\n\ttoolProfileFilter?: ResourceProfileFilterSettings;\n\t/** Preserve an explicit launch-time model across profile reloads. */\n\tisExplicitModel?: boolean;\n\t/** Preserve an explicit launch-time thinking level across profile reloads. */\n\tisExplicitThinking?: boolean;\n\t/** Child sessions receive the worker UAC and write ceilings. */\n\tisChildSession?: boolean;\n\t/** Alternate base tool instances for embedded/custom runtimes. */\n\tbaseToolsOverride?: Record<string, AgentTool>;\n\t/** Mutable bridge used by the agent loop to reach the current extension generation. */\n\textensionRunnerRef?: { current?: ExtensionRunner };\n\tsessionStartEvent?: SessionStartEvent;\n\t/** Injectable pointer-first workspace collector; tests use this to avoid process execution. */\n\tcollectWorkspaceSources?: typeof collectWorkspaceSources;\n\t/** Immutable owner-authored orchestration policy. */\n\torchestrationProfile?: OrchestrationProfile;\n\t/** Injectable local-runtime I/O dependencies. */\n\tlocalRuntimeDeps?: LocalRuntimeDeps;\n}\n\nexport interface ExtensionBindings {\n\tuiContext?: ExtensionUIContext;\n\tmode?: ExtensionContext[\"mode\"];\n\tcommandContextActions?: ExtensionCommandContextActions;\n\tabortHandler?: () => void;\n\tshutdownHandler?: ShutdownHandler;\n\tonError?: ExtensionErrorListener;\n}\n\nexport interface PromptOptions {\n\t/** Expand file prompt templates and skills. Defaults to true. */\n\texpandPromptTemplates?: boolean;\n\t/** Process slash commands before model submission. Defaults to `expandPromptTemplates`. */\n\tprocessSlashCommands?: boolean;\n\timages?: ImageContent[];\n\t/** Required queue behavior when a foreground turn is already streaming. */\n\tstreamingBehavior?: \"steer\" | \"followUp\";\n\tsource?: InputSource;\n\t/** Observe whether prompt preflight accepted the request. */\n\tpreflightResult?: (success: boolean) => void;\n\t/** Permit idle goal continuation after this prompt settles. Defaults to true. */\n\tautoContinueGoal?: boolean;\n\t/** Hidden internal turn persisted as a typed context marker. */\n\tinternalContextType?: string;\n}\n\nexport interface ModelCycleResult {\n\tmodel: Model<Api>;\n\tthinkingLevel: ThinkingLevel;\n\t/** Whether cycling was constrained to launch-scoped models. */\n\tisScoped: boolean;\n}\n\nexport interface CompactionGateCheckStats {\n\tfailures: number;\n\tminScore?: number;\n\tmaxScore?: number;\n\tthreshold?: number;\n\tcomparator?: \"minimum\" | \"maximum\";\n}\n\nexport interface CompactionGateStats {\n\tgateFailures: number;\n\tdeterministicGapFills: number;\n\tcompactionsWithGateFailures: number;\n\tchecks: Record<string, CompactionGateCheckStats>;\n}\n\nexport interface SessionStats {\n\tsessionFile: string | undefined;\n\tsessionId: string;\n\tuserMessages: number;\n\tassistantMessages: number;\n\ttoolCalls: number;\n\ttoolResults: number;\n\ttotalMessages: number;\n\ttokens: { input: number; output: number; cacheRead: number; cacheWrite: number; total: number };\n\tcost: number;\n\tcontextUsage?: ContextUsage;\n\ttoolArgumentValidation: ToolArgumentValidationStats;\n\tcompactionGates: CompactionGateStats;\n}\n\nexport const SPAWNED_USAGE_CUSTOM_TYPE = \"spawned_usage\";\nexport const RUNAWAY_STOP_CUSTOM_TYPE = \"runaway_stop\";\nexport const TOOL_VALIDATION_ESCALATION_CUSTOM_TYPE = \"tool_validation_escalation\";\n\nexport interface RunawayStopRecord {\n\tsignature: string;\n\trepeats: number;\n\tmodel?: string;\n\tprovider?: string;\n\tat: string;\n}\n\nexport interface ToolValidationEscalationRecord {\n\ttool: string;\n\tsignature: string;\n\trepeats: number;\n\tmodel: string;\n\tprovider: string;\n\tat: string;\n}\n\nexport interface SpawnedUsageReport {\n\t/** Cumulative child usage, including that child's already-rolled-up descendants. */\n\tusage: Usage;\n\tlabel?: string;\n\tsourceSessionId?: string;\n\t/** Stable idempotency identity for retry-safe ingestion. */\n\treportId?: string;\n}\n\nexport interface SpawnedUsageTotals {\n\tcost: number;\n\treports: number;\n}\n\nexport interface IsolatedCompletionOptions {\n\tsystemPrompt: string;\n\t/** Isolated conversation; foreground session history is never inherited. */\n\tmessages: Message[];\n\tmodel?: Model<Api>;\n\tthinkingLevel?: ThinkingLevel;\n\tmaxTokens?: number;\n\t/** Fresh child-owned tool instances. Omission preserves one-shot behavior. */\n\ttools?: AgentTool[];\n\t/** Explicit child-loop turn cap. */\n\tmaxTurns?: number;\n\t/** Optional tool-free finalization prompt after the bounded tool loop. */\n\tfinalTextPrompt?: string;\n\t/** Child-only capability/path gate. */\n\tbeforeToolCall?: AgentLoopConfig[\"beforeToolCall\"];\n\t/** Child-only result observer. */\n\tafterToolCall?: AgentLoopConfig[\"afterToolCall\"];\n\tsignal?: AbortSignal;\n\t/** Required cache policy; isolated calls never inherit a provider default implicitly. */\n\tcacheRetention: CacheRetention;\n\t/** Stable namespace used to derive provider cache affinity. */\n\tlaneKind?: string;\n}\n\nexport const DEFAULT_ISOLATED_LANE_KIND = \"isolated\";\n\nexport function computeLaneAffinityKey(laneKind: string, model: Model<Api> | undefined, systemPrompt: string): string {\n\tconst modelKey = model ? `${model.provider}/${model.id}` : \"unknown-model\";\n\tconst digest = createHash(\"sha256\")\n\t\t.update([\"pi-lane-affinity-v1\", laneKind, modelKey, systemPrompt].join(\"\\u0000\"))\n\t\t.digest(\"hex\")\n\t\t.slice(0, 32);\n\treturn `lane:${laneKind}:${digest}`;\n}\n\nexport interface IsolatedCompletionResult {\n\ttext: string;\n\tusage: Usage;\n\tstopReason: StopReason;\n}\n\nexport interface ResearchLaneRunOutcome {\n\tstarted: boolean;\n\tskipReason?: string;\n\trecord?: LaneRecord;\n\tresult?: ResearchRunResult;\n}\n\nexport interface WorkerDelegationRunOutcome {\n\tstarted: boolean;\n\tskipReason?: string;\n\trecord?: LaneRecord;\n\toutcome?: WorkerRunOutcome;\n}\n\nexport interface GoalContinuationOnceOptions {\n\t/** Consecutive non-progress passes allowed before deterministic escalation; 0 disables the gate. */\n\tmaxStallTurns: number;\n}\n\nexport interface GoalContinuationOnceResult {\n\tsubmitted: boolean;\n\tsnapshot: GoalRuntimeSnapshot;\n\tprompt?: GoalContinuationPrompt;\n}\n\nexport type GoalContinuationLoopStopReason =\n\t| \"continuation_not_allowed\"\n\t| \"max_turns_reached\"\n\t| \"wall_clock_budget_reached\"\n\t| \"goal_budget_exhausted\"\n\t| \"already_continuing\"\n\t| \"session_disposed\"\n\t| \"goal_tool_unavailable\"\n\t| \"worker_in_flight\";\n\nexport interface GoalContinuationLoopOptions extends GoalContinuationOnceOptions {\n\t/** Explicit per-invocation turn limit; 0 means unbounded. */\n\tmaxTurns: number;\n\t/** Explicit per-invocation active-time limit; 0/undefined means unbounded. */\n\tmaxWallClockMinutes?: number;\n\t/** Injectable monotonic-enough clock for deterministic tests. */\n\tnow?: () => number;\n}\n\nexport interface GoalContinuationLoopResult {\n\tturnsSubmitted: number;\n\tstopReason: GoalContinuationLoopStopReason;\n\tfinalSnapshot: GoalRuntimeSnapshot;\n}\n\n/** Test-only stream watchdog override contract retained in the public session module. */\nexport type StreamIdleOptionsOverride = Partial<StreamIdleOptions> | undefined;\n"]}
@@ -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, constants as fsConstants, mkdirSync, unlinkSync } from \"node:fs\";\nimport { basename, join, resolve } from \"node:path\";\nimport { SessionManager } from \"@caupulican/pi-agent-core/node\";\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\";\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\ninterface AgentSessionRuntimeState {\n\tsession: AgentSession;\n\tservices: AgentSessionServices;\n\tdiagnostics: AgentSessionRuntimeDiagnostic[];\n\tmodelFallbackMessage?: string;\n}\n\ninterface RuntimeShutdownProgress {\n\tshutdownEventEmitted: boolean;\n\tstoppedResources: Set<AgentSessionRuntimeResource>;\n\thostInvalidated: boolean;\n\tsessionDisposed: boolean;\n}\n\n/** Session-owned background runtime that must not survive a session replacement. */\nexport interface AgentSessionRuntimeResource {\n\tstart(session: AgentSession): Promise<void>;\n\tstop(): Promise<void> | void;\n}\n\n/** Internal activation hooks used by the interactive session-resume flow. */\nexport interface AgentSessionSwitchOptions {\n\tcwdOverride?: string;\n\t/** Runs against the installed replacement after host rebind and before supervisors restart. */\n\tbeforeSessionResourcesStart?: (session: AgentSession) => Promise<void> | void;\n\twithSession?: (ctx: ReplacedSessionContext) => Promise<void>;\n}\n\ninterface SessionReplacementCommitOptions {\n\treason: SessionShutdownEvent[\"reason\"];\n\ttargetSessionFile: string | undefined;\n\tbeforeSessionResourcesStart?: (session: AgentSession) => Promise<void> | void;\n\twithSession?: (ctx: ReplacedSessionContext) => Promise<void>;\n\tonDiscard?: () => void;\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\n/** A teardown or activation failure at the replacement boundary, including rollback outcome. */\nexport class SessionReplacementRuntimeError extends Error {\n\treadonly phase: \"teardown\" | \"activation\";\n\treadonly recovered: boolean;\n\treadonly transitionError: unknown;\n\treadonly recoveryError: unknown | undefined;\n\n\tconstructor(\n\t\tphase: \"teardown\" | \"activation\",\n\t\ttransitionError: unknown,\n\t\trecovered: boolean,\n\t\trecoveryError?: unknown,\n\t) {\n\t\tconst transitionMessage = transitionError instanceof Error ? transitionError.message : String(transitionError);\n\t\tsuper(\n\t\t\trecovered\n\t\t\t\t? `Session replacement ${phase} failed; the previous session was restored: ${transitionMessage}`\n\t\t\t\t: `Session replacement ${phase} failed and the previous session could not be restored safely: ${transitionMessage}`,\n\t\t);\n\t\tthis.name = \"SessionReplacementRuntimeError\";\n\t\tthis.phase = phase;\n\t\tthis.recovered = recovered;\n\t\tthis.transitionError = transitionError;\n\t\tthis.recoveryError = recoveryError;\n\t}\n}\n\n/** A post-commit extension callback failed; the replacement itself remains the active session. */\nexport class SessionReplacementCallbackError extends Error {\n\treadonly replacementCommitted = true;\n\treadonly callbackError: unknown;\n\n\tconstructor(callbackError: unknown) {\n\t\tconst callbackMessage = callbackError instanceof Error ? callbackError.message : String(callbackError);\n\t\tsuper(`Session replacement completed, but its withSession callback failed: ${callbackMessage}`);\n\t\tthis.name = \"SessionReplacementCallbackError\";\n\t\tthis.callbackError = callbackError;\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 construct the candidate runtime before retiring\n * the current one. If preparation fails, the working session remains active.\n */\nexport class AgentSessionRuntime {\n\tprivate rebindSession?: (session: AgentSession) => 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\tprivate _replacementInFlight: Promise<unknown> | undefined;\n\tprivate _disposeInFlight: Promise<void> | undefined;\n\tprivate _disposeStarted = false;\n\tprivate _disposed = false;\n\tprivate readonly disposeProgress: RuntimeShutdownProgress = {\n\t\tshutdownEventEmitted: false,\n\t\tstoppedResources: new Set(),\n\t\thostInvalidated: false,\n\t\tsessionDisposed: false,\n\t};\n\tprivate readonly sessionResources: AgentSessionRuntimeResource[] = [];\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\t/** True from replacement admission until rebind and replacement callbacks have settled. */\n\tget isReplacing(): boolean {\n\t\treturn this._replacementInFlight !== undefined;\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\t/** Register a resource whose lifecycle follows the active session (supervisors, watchers). */\n\tregisterSessionResource(resource: AgentSessionRuntimeResource): void {\n\t\tif (this.sessionResources.includes(resource)) return;\n\t\tthis.sessionResources.push(resource);\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\tconst errors = await this.shutdownRuntime(this.session, reason, targetSessionFile, {\n\t\t\tstopResources: true,\n\t\t\tinvalidateHost: true,\n\t\t});\n\t\tif (errors.length === 1) throw errors[0];\n\t\tif (errors.length > 1) throw new AggregateError(errors, \"Session runtime teardown failed.\");\n\t}\n\n\tprivate async discardPrepared(result: CreateAgentSessionRuntimeResult): Promise<void> {\n\t\tawait result.session.disposeAndWait();\n\t}\n\n\tprivate removeCreatedSessionFile(sessionFile: string | undefined): void {\n\t\tif (!sessionFile || sessionFile === this.session.sessionFile || !existsSync(sessionFile)) return;\n\t\ttry {\n\t\t\tunlinkSync(sessionFile);\n\t\t} catch {\n\t\t\t// Best-effort rollback of an artifact created solely for the rejected replacement.\n\t\t}\n\t}\n\n\tprivate async prepareReplacement(\n\t\tsessionManager: SessionManager,\n\t\tsessionStartEvent: SessionStartEvent,\n\t): Promise<CreateAgentSessionRuntimeResult> {\n\t\treturn this.createRuntime({\n\t\t\tcwd: sessionManager.getCwd(),\n\t\t\tagentDir: this.services.agentDir,\n\t\t\tsessionManager,\n\t\t\tsessionStartEvent,\n\t\t});\n\t}\n\n\tprivate async commitReplacement(\n\t\tresult: CreateAgentSessionRuntimeResult,\n\t\toptions: SessionReplacementCommitOptions,\n\t): Promise<void> {\n\t\tconst previous = this.snapshot();\n\t\ttry {\n\t\t\tawait this.teardownCurrent(options.reason, options.targetSessionFile);\n\t\t} catch (transitionError: unknown) {\n\t\t\tconst recoveryError = await this.restorePreviousAfterRuntimeFailure(previous, result, options, false);\n\t\t\tthrow new SessionReplacementRuntimeError(\n\t\t\t\t\"teardown\",\n\t\t\t\ttransitionError,\n\t\t\t\trecoveryError === undefined,\n\t\t\t\trecoveryError,\n\t\t\t);\n\t\t}\n\t\tthis.apply(result);\n\t\ttry {\n\t\t\tawait this.activateReplacement(options);\n\t\t} catch (activationError: unknown) {\n\t\t\tconst recoveryError = await this.restorePreviousAfterRuntimeFailure(previous, result, options, true);\n\t\t\tthrow new SessionReplacementRuntimeError(\n\t\t\t\t\"activation\",\n\t\t\t\tactivationError,\n\t\t\t\trecoveryError === undefined,\n\t\t\t\trecoveryError,\n\t\t\t);\n\t\t}\n\t\tif (options.withSession) {\n\t\t\ttry {\n\t\t\t\tawait options.withSession(this.session.createReplacedSessionContext());\n\t\t\t} catch (callbackError: unknown) {\n\t\t\t\tthrow new SessionReplacementCallbackError(callbackError);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate snapshot(): AgentSessionRuntimeState {\n\t\treturn {\n\t\t\tsession: this._session,\n\t\t\tservices: this._services,\n\t\t\tdiagnostics: [...this._diagnostics],\n\t\t\t...(this._modelFallbackMessage !== undefined ? { modelFallbackMessage: this._modelFallbackMessage } : {}),\n\t\t};\n\t}\n\n\tprivate apply(result: AgentSessionRuntimeState): 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 activateReplacement(options: SessionReplacementCommitOptions): Promise<void> {\n\t\tif (this.rebindSession) {\n\t\t\tawait this.rebindSession(this.session);\n\t\t}\n\t\tawait options.beforeSessionResourcesStart?.(this.session);\n\t\tfor (const resource of this.sessionResources) await resource.start(this.session);\n\t}\n\n\tprivate async restorePreviousAfterRuntimeFailure(\n\t\tprevious: AgentSessionRuntimeState,\n\t\tfailed: CreateAgentSessionRuntimeResult,\n\t\toptions: SessionReplacementCommitOptions,\n\t\tcandidateActivated: boolean,\n\t): Promise<unknown | undefined> {\n\t\tconst cleanupErrors = await this.shutdownRuntime(failed.session, options.reason, previous.session.sessionFile, {\n\t\t\tstopResources: candidateActivated,\n\t\t\tinvalidateHost: candidateActivated,\n\t\t});\n\t\t// The old AgentSession was disposed at the commit boundary, but its SessionManager remains the\n\t\t// durable reconstruction source. Restore the old snapshot temporarily so rollback-only artifact\n\t\t// cleanup cannot mistake the failed candidate for the active session.\n\t\tthis.apply(previous);\n\t\ttry {\n\t\t\toptions.onDiscard?.();\n\t\t} catch (error: unknown) {\n\t\t\tcleanupErrors.push(error);\n\t\t}\n\n\t\tlet restored: CreateAgentSessionRuntimeResult | undefined;\n\t\ttry {\n\t\t\trestored = await this.createRuntime({\n\t\t\t\tcwd: previous.services.cwd,\n\t\t\t\tagentDir: previous.services.agentDir,\n\t\t\t\tsessionManager: previous.session.sessionManager,\n\t\t\t\tsessionStartEvent: {\n\t\t\t\t\ttype: \"session_start\",\n\t\t\t\t\treason: \"resume\",\n\t\t\t\t\tpreviousSessionFile: failed.session.sessionFile,\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis.apply(restored);\n\t\t\tif (this.rebindSession) await this.rebindSession(this.session);\n\t\t\tfor (const resource of this.sessionResources) await resource.start(this.session);\n\t\t} catch (recoveryError: unknown) {\n\t\t\tif (restored) {\n\t\t\t\tcleanupErrors.push(\n\t\t\t\t\t...(await this.shutdownRuntime(restored.session, \"resume\", failed.session.sessionFile, {\n\t\t\t\t\t\tstopResources: true,\n\t\t\t\t\t\tinvalidateHost: true,\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.apply(previous);\n\t\t\treturn cleanupErrors.length > 0\n\t\t\t\t? new AggregateError([...cleanupErrors, recoveryError], \"Session rollback and cleanup failed.\")\n\t\t\t\t: recoveryError;\n\t\t}\n\n\t\treturn cleanupErrors.length > 0\n\t\t\t? new AggregateError(\n\t\t\t\t\tcleanupErrors,\n\t\t\t\t\t\"The previous session was restored, but failed replacement cleanup was incomplete.\",\n\t\t\t\t)\n\t\t\t: undefined;\n\t}\n\n\tprivate async shutdownRuntime(\n\t\tsession: AgentSession,\n\t\treason: SessionShutdownEvent[\"reason\"],\n\t\ttargetSessionFile: string | undefined,\n\t\toptions: { stopResources: boolean; invalidateHost: boolean; progress?: RuntimeShutdownProgress },\n\t): Promise<unknown[]> {\n\t\tconst errors: unknown[] = [];\n\t\tconst progress =\n\t\t\toptions.progress ??\n\t\t\t({\n\t\t\t\tshutdownEventEmitted: false,\n\t\t\t\tstoppedResources: new Set(),\n\t\t\t\thostInvalidated: false,\n\t\t\t\tsessionDisposed: false,\n\t\t\t} satisfies RuntimeShutdownProgress);\n\t\tif (!progress.shutdownEventEmitted) {\n\t\t\ttry {\n\t\t\t\tawait emitSessionShutdownEvent(session.extensionRunner, {\n\t\t\t\t\ttype: \"session_shutdown\",\n\t\t\t\t\treason,\n\t\t\t\t\ttargetSessionFile,\n\t\t\t\t});\n\t\t\t\tprogress.shutdownEventEmitted = true;\n\t\t\t} catch (error: unknown) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t}\n\t\tif (options.stopResources) {\n\t\t\tfor (const resource of this.sessionResources) {\n\t\t\t\tif (progress.stoppedResources.has(resource)) continue;\n\t\t\t\ttry {\n\t\t\t\t\tawait resource.stop();\n\t\t\t\t\tprogress.stoppedResources.add(resource);\n\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\terrors.push(error);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (options.invalidateHost && !progress.hostInvalidated) {\n\t\t\ttry {\n\t\t\t\tthis.beforeSessionInvalidate?.();\n\t\t\t\tprogress.hostInvalidated = true;\n\t\t\t} catch (error: unknown) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t}\n\t\tif (!progress.sessionDisposed) {\n\t\t\ttry {\n\t\t\t\tawait session.disposeAndWait();\n\t\t\t\tprogress.sessionDisposed = true;\n\t\t\t} catch (error: unknown) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t}\n\t\treturn errors;\n\t}\n\n\tprivate runSessionReplacement<T>(operation: () => Promise<T>): Promise<T> {\n\t\tif (this._disposeStarted) {\n\t\t\treturn Promise.reject(new Error(\"The session runtime has already been disposed.\"));\n\t\t}\n\t\tif (this._replacementInFlight) {\n\t\t\treturn Promise.reject(new Error(\"A session replacement is already in progress.\"));\n\t\t}\n\t\tconst replacement = Promise.resolve().then(operation);\n\t\tthis._replacementInFlight = replacement;\n\t\treturn replacement.finally(() => {\n\t\t\tif (this._replacementInFlight === replacement) this._replacementInFlight = undefined;\n\t\t});\n\t}\n\n\tasync switchSession(sessionPath: string, options?: AgentSessionSwitchOptions): Promise<{ cancelled: boolean }> {\n\t\treturn this.runSessionReplacement(() => this.switchSessionUnserialized(sessionPath, options));\n\t}\n\n\tprivate async switchSessionUnserialized(\n\t\tsessionPath: string,\n\t\toptions?: AgentSessionSwitchOptions,\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, this.services.agentDir, undefined, options?.cwdOverride);\n\t\tassertSessionCwdExists(sessionManager, this.cwd);\n\t\tconst prepared = await this.prepareReplacement(sessionManager, {\n\t\t\ttype: \"session_start\",\n\t\t\treason: \"resume\",\n\t\t\tpreviousSessionFile,\n\t\t});\n\t\tawait this.commitReplacement(prepared, {\n\t\t\treason: \"resume\",\n\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\tbeforeSessionResourcesStart: options?.beforeSessionResourcesStart,\n\t\t\twithSession: options?.withSession,\n\t\t});\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\treturn this.runSessionReplacement(() => this.newSessionUnserialized(options));\n\t}\n\n\tprivate async newSessionUnserialized(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, this.services.agentDir, sessionDir);\n\t\tif (options?.parentSession) {\n\t\t\tsessionManager.newSession({ parentSession: options.parentSession });\n\t\t}\n\n\t\tlet prepared: CreateAgentSessionRuntimeResult;\n\t\ttry {\n\t\t\tprepared = await this.prepareReplacement(sessionManager, {\n\t\t\t\ttype: \"session_start\",\n\t\t\t\treason: \"new\",\n\t\t\t\tpreviousSessionFile,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis.removeCreatedSessionFile(sessionManager.getSessionFile());\n\t\t\tthrow error;\n\t\t}\n\t\tif (options?.setup) {\n\t\t\ttry {\n\t\t\t\tawait options.setup(prepared.session.sessionManager);\n\t\t\t\tprepared.session.agent.state.messages = prepared.session.sessionManager.buildSessionContext().messages;\n\t\t\t} catch (error) {\n\t\t\t\tawait this.discardPrepared(prepared);\n\t\t\t\tthis.removeCreatedSessionFile(sessionManager.getSessionFile());\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\tawait this.commitReplacement(prepared, {\n\t\t\treason: \"new\",\n\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\twithSession: options?.withSession,\n\t\t\tonDiscard: () => this.removeCreatedSessionFile(sessionManager.getSessionFile()),\n\t\t});\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\treturn this.runSessionReplacement(() => this.forkUnserialized(entryId, options));\n\t}\n\n\tprivate async forkUnserialized(\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, this.services.agentDir, sessionDir);\n\t\t\t\tsessionManager.newSession({ parentSession: currentSessionFile });\n\t\t\t\tlet prepared: CreateAgentSessionRuntimeResult;\n\t\t\t\ttry {\n\t\t\t\t\tprepared = await this.prepareReplacement(sessionManager, {\n\t\t\t\t\t\ttype: \"session_start\",\n\t\t\t\t\t\treason: \"fork\",\n\t\t\t\t\t\tpreviousSessionFile,\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.removeCreatedSessionFile(sessionManager.getSessionFile());\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tawait this.commitReplacement(prepared, {\n\t\t\t\t\treason: \"fork\",\n\t\t\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\t\t\twithSession: options?.withSession,\n\t\t\t\t\tonDiscard: () => this.removeCreatedSessionFile(sessionManager.getSessionFile()),\n\t\t\t\t});\n\t\t\t\treturn { cancelled: false, selectedText };\n\t\t\t}\n\n\t\t\tconst sourceSessionManager = SessionManager.open(currentSessionFile, this.services.agentDir, sessionDir);\n\t\t\tconst sessionManager = sourceSessionManager.createBranchedSessionManager(targetLeafId);\n\t\t\tconst forkedSessionPath = sessionManager.getSessionFile();\n\t\t\tif (!forkedSessionPath) {\n\t\t\t\tthrow new Error(\"Failed to create forked session\");\n\t\t\t}\n\t\t\tlet prepared: CreateAgentSessionRuntimeResult;\n\t\t\ttry {\n\t\t\t\tprepared = await this.prepareReplacement(sessionManager, {\n\t\t\t\t\ttype: \"session_start\",\n\t\t\t\t\treason: \"fork\",\n\t\t\t\t\tpreviousSessionFile,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tthis.removeCreatedSessionFile(forkedSessionPath);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tawait this.commitReplacement(prepared, {\n\t\t\t\treason: \"fork\",\n\t\t\t\ttargetSessionFile: forkedSessionPath,\n\t\t\t\twithSession: options?.withSession,\n\t\t\t\tonDiscard: () => this.removeCreatedSessionFile(forkedSessionPath),\n\t\t\t});\n\t\t\treturn { cancelled: false, selectedText };\n\t\t}\n\n\t\tlet sessionManager: SessionManager;\n\t\tif (!targetLeafId) {\n\t\t\tsessionManager = SessionManager.inMemory(this.cwd);\n\t\t\tsessionManager.newSession({ parentSession: this.session.sessionFile });\n\t\t} else {\n\t\t\tsessionManager = this.session.sessionManager.createBranchedSessionManager(targetLeafId);\n\t\t}\n\t\tconst prepared = await this.prepareReplacement(sessionManager, {\n\t\t\ttype: \"session_start\",\n\t\t\treason: \"fork\",\n\t\t\tpreviousSessionFile,\n\t\t});\n\t\tawait this.commitReplacement(prepared, {\n\t\t\treason: \"fork\",\n\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\twithSession: options?.withSession,\n\t\t});\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\treturn this.runSessionReplacement(() => this.importFromJsonlUnserialized(inputPath, cwdOverride));\n\t}\n\n\tprivate async importFromJsonlUnserialized(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\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\tlet copied = false;\n\t\tif (resolve(destinationPath) !== resolvedPath) {\n\t\t\tif (!existsSync(sessionDir)) mkdirSync(sessionDir, { recursive: true });\n\t\t\tcopyFileSync(resolvedPath, destinationPath, fsConstants.COPYFILE_EXCL);\n\t\t\tcopied = true;\n\t\t}\n\n\t\tlet sessionManager: SessionManager;\n\t\tlet prepared: CreateAgentSessionRuntimeResult;\n\t\ttry {\n\t\t\tsessionManager = SessionManager.open(destinationPath, this.services.agentDir, sessionDir, cwdOverride);\n\t\t\tassertSessionCwdExists(sessionManager, this.cwd);\n\t\t\tprepared = await this.prepareReplacement(sessionManager, {\n\t\t\t\ttype: \"session_start\",\n\t\t\t\treason: \"resume\",\n\t\t\t\tpreviousSessionFile,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (copied) this.removeCreatedSessionFile(destinationPath);\n\t\t\tthrow error;\n\t\t}\n\t\tawait this.commitReplacement(prepared, {\n\t\t\treason: \"resume\",\n\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\tonDiscard: copied ? () => this.removeCreatedSessionFile(destinationPath) : undefined,\n\t\t});\n\t\treturn { cancelled: false };\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tif (this._disposeInFlight) return this._disposeInFlight;\n\t\tif (this._disposed) return;\n\t\tthis._disposeStarted = true;\n\t\tconst replacement = this._replacementInFlight;\n\t\tconst disposal = (async () => {\n\t\t\tif (replacement) {\n\t\t\t\ttry {\n\t\t\t\t\tawait replacement;\n\t\t\t\t} catch {\n\t\t\t\t\t// Replacement already reports its own error; dispose whichever runtime it left active.\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst errors = await this.shutdownRuntime(this.session, \"quit\", undefined, {\n\t\t\t\tstopResources: true,\n\t\t\t\tinvalidateHost: true,\n\t\t\t\tprogress: this.disposeProgress,\n\t\t\t});\n\t\t\tif (errors.length === 1) throw errors[0];\n\t\t\tif (errors.length > 1) throw new AggregateError(errors, \"Session runtime disposal failed.\");\n\t\t\tthis._disposed = true;\n\t\t})();\n\t\tthis._disposeInFlight = disposal;\n\t\ttry {\n\t\t\tawait disposal;\n\t\t} finally {\n\t\t\tthis._disposeInFlight = undefined;\n\t\t}\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
+ {"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, constants as fsConstants, mkdirSync, unlinkSync } from \"node:fs\";\nimport { basename, join, resolve } from \"node:path\";\nimport { SessionManager } from \"@caupulican/pi-agent-core/node\";\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\";\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\ninterface AgentSessionRuntimeState {\n\tsession: AgentSession;\n\tservices: AgentSessionServices;\n\tdiagnostics: AgentSessionRuntimeDiagnostic[];\n\tmodelFallbackMessage?: string;\n}\n\ninterface RuntimeShutdownProgress {\n\tshutdownEventEmitted: boolean;\n\tstoppedResources: Set<AgentSessionRuntimeResource>;\n\thostInvalidated: boolean;\n\tsessionDisposed: boolean;\n}\n\n/** Session-owned background runtime that must not survive a session replacement. */\nexport interface AgentSessionRuntimeResource {\n\tstart(session: AgentSession): Promise<void>;\n\tstop(): Promise<void> | void;\n}\n\n/** Internal activation hooks used by the interactive session-resume flow. */\nexport interface AgentSessionSwitchOptions {\n\tcwdOverride?: string;\n\t/** Runs against the installed replacement after host rebind and before supervisors restart. */\n\tbeforeSessionResourcesStart?: (session: AgentSession) => Promise<void> | void;\n\twithSession?: (ctx: ReplacedSessionContext) => Promise<void>;\n}\n\ninterface SessionReplacementCommitOptions {\n\treason: SessionShutdownEvent[\"reason\"];\n\ttargetSessionFile: string | undefined;\n\tbeforeSessionResourcesStart?: (session: AgentSession) => Promise<void> | void;\n\twithSession?: (ctx: ReplacedSessionContext) => Promise<void>;\n\tonDiscard?: () => void;\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\n/** A teardown or activation failure at the replacement boundary, including rollback outcome. */\nexport class SessionReplacementRuntimeError extends Error {\n\treadonly phase: \"teardown\" | \"activation\";\n\treadonly recovered: boolean;\n\treadonly transitionError: unknown;\n\treadonly recoveryError: unknown | undefined;\n\n\tconstructor(\n\t\tphase: \"teardown\" | \"activation\",\n\t\ttransitionError: unknown,\n\t\trecovered: boolean,\n\t\trecoveryError?: unknown,\n\t) {\n\t\tconst transitionMessage = transitionError instanceof Error ? transitionError.message : String(transitionError);\n\t\tsuper(\n\t\t\trecovered\n\t\t\t\t? `Session replacement ${phase} failed; the previous session was restored: ${transitionMessage}`\n\t\t\t\t: `Session replacement ${phase} failed and the previous session could not be restored safely: ${transitionMessage}`,\n\t\t);\n\t\tthis.name = \"SessionReplacementRuntimeError\";\n\t\tthis.phase = phase;\n\t\tthis.recovered = recovered;\n\t\tthis.transitionError = transitionError;\n\t\tthis.recoveryError = recoveryError;\n\t}\n}\n\n/** A post-commit extension callback failed; the replacement itself remains the active session. */\nexport class SessionReplacementCallbackError extends Error {\n\treadonly replacementCommitted = true;\n\treadonly callbackError: unknown;\n\n\tconstructor(callbackError: unknown) {\n\t\tconst callbackMessage = callbackError instanceof Error ? callbackError.message : String(callbackError);\n\t\tsuper(`Session replacement completed, but its withSession callback failed: ${callbackMessage}`);\n\t\tthis.name = \"SessionReplacementCallbackError\";\n\t\tthis.callbackError = callbackError;\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 construct the candidate runtime before retiring\n * the current one. If preparation fails, the working session remains active.\n */\nexport class AgentSessionRuntime {\n\tprivate rebindSession?: (session: AgentSession) => 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\tprivate _replacementInFlight: Promise<unknown> | undefined;\n\tprivate _disposeInFlight: Promise<void> | undefined;\n\tprivate _disposeStarted = false;\n\tprivate _disposed = false;\n\tprivate readonly disposeProgress: RuntimeShutdownProgress = {\n\t\tshutdownEventEmitted: false,\n\t\tstoppedResources: new Set(),\n\t\thostInvalidated: false,\n\t\tsessionDisposed: false,\n\t};\n\tprivate readonly sessionResources: AgentSessionRuntimeResource[] = [];\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\t/** True from replacement admission until rebind and replacement callbacks have settled. */\n\tget isReplacing(): boolean {\n\t\treturn this._replacementInFlight !== undefined;\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\t/** Register a resource whose lifecycle follows the active session (supervisors, watchers). */\n\tregisterSessionResource(resource: AgentSessionRuntimeResource): void {\n\t\tif (this.sessionResources.includes(resource)) return;\n\t\tthis.sessionResources.push(resource);\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\tconst errors = await this.shutdownRuntime(this.session, reason, targetSessionFile, {\n\t\t\tstopResources: true,\n\t\t\tinvalidateHost: true,\n\t\t});\n\t\tif (errors.length === 1) throw errors[0];\n\t\tif (errors.length > 1) throw new AggregateError(errors, \"Session runtime teardown failed.\");\n\t}\n\n\tprivate async discardPrepared(result: CreateAgentSessionRuntimeResult): Promise<void> {\n\t\tawait result.session.disposeAndWait();\n\t}\n\n\tprivate removeCreatedSessionFile(sessionFile: string | undefined): void {\n\t\tif (!sessionFile || sessionFile === this.session.sessionFile || !existsSync(sessionFile)) return;\n\t\ttry {\n\t\t\tunlinkSync(sessionFile);\n\t\t} catch {\n\t\t\t// Best-effort rollback of an artifact created solely for the rejected replacement.\n\t\t}\n\t}\n\n\tprivate async prepareReplacement(\n\t\tsessionManager: SessionManager,\n\t\tsessionStartEvent: SessionStartEvent,\n\t): Promise<CreateAgentSessionRuntimeResult> {\n\t\treturn this.createRuntime({\n\t\t\tcwd: sessionManager.getCwd(),\n\t\t\tagentDir: this.services.agentDir,\n\t\t\tsessionManager,\n\t\t\tsessionStartEvent,\n\t\t});\n\t}\n\n\tprivate async commitReplacement(\n\t\tresult: CreateAgentSessionRuntimeResult,\n\t\toptions: SessionReplacementCommitOptions,\n\t): Promise<void> {\n\t\tconst previous = this.snapshot();\n\t\ttry {\n\t\t\tawait this.teardownCurrent(options.reason, options.targetSessionFile);\n\t\t} catch (transitionError: unknown) {\n\t\t\tconst recoveryError = await this.restorePreviousAfterRuntimeFailure(previous, result, options, false);\n\t\t\tthrow new SessionReplacementRuntimeError(\n\t\t\t\t\"teardown\",\n\t\t\t\ttransitionError,\n\t\t\t\trecoveryError === undefined,\n\t\t\t\trecoveryError,\n\t\t\t);\n\t\t}\n\t\tthis.apply(result);\n\t\ttry {\n\t\t\tawait this.activateReplacement(options);\n\t\t} catch (activationError: unknown) {\n\t\t\tconst recoveryError = await this.restorePreviousAfterRuntimeFailure(previous, result, options, true);\n\t\t\tthrow new SessionReplacementRuntimeError(\n\t\t\t\t\"activation\",\n\t\t\t\tactivationError,\n\t\t\t\trecoveryError === undefined,\n\t\t\t\trecoveryError,\n\t\t\t);\n\t\t}\n\t\tif (options.withSession) {\n\t\t\ttry {\n\t\t\t\tawait options.withSession(this.session.createReplacedSessionContext());\n\t\t\t} catch (callbackError: unknown) {\n\t\t\t\tthrow new SessionReplacementCallbackError(callbackError);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate snapshot(): AgentSessionRuntimeState {\n\t\treturn {\n\t\t\tsession: this._session,\n\t\t\tservices: this._services,\n\t\t\tdiagnostics: [...this._diagnostics],\n\t\t\t...(this._modelFallbackMessage !== undefined ? { modelFallbackMessage: this._modelFallbackMessage } : {}),\n\t\t};\n\t}\n\n\tprivate apply(result: AgentSessionRuntimeState): 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 activateReplacement(options: SessionReplacementCommitOptions): Promise<void> {\n\t\tif (this.rebindSession) {\n\t\t\tawait this.rebindSession(this.session);\n\t\t}\n\t\tawait options.beforeSessionResourcesStart?.(this.session);\n\t\tfor (const resource of this.sessionResources) await resource.start(this.session);\n\t}\n\n\tprivate async restorePreviousAfterRuntimeFailure(\n\t\tprevious: AgentSessionRuntimeState,\n\t\tfailed: CreateAgentSessionRuntimeResult,\n\t\toptions: SessionReplacementCommitOptions,\n\t\tcandidateActivated: boolean,\n\t): Promise<unknown | undefined> {\n\t\tconst cleanupErrors = await this.shutdownRuntime(failed.session, options.reason, previous.session.sessionFile, {\n\t\t\tstopResources: candidateActivated,\n\t\t\tinvalidateHost: candidateActivated,\n\t\t});\n\t\t// The old AgentSession was disposed at the commit boundary, but its SessionManager remains the\n\t\t// durable reconstruction source. Restore the old snapshot temporarily so rollback-only artifact\n\t\t// cleanup cannot mistake the failed candidate for the active session.\n\t\tthis.apply(previous);\n\t\ttry {\n\t\t\toptions.onDiscard?.();\n\t\t} catch (error: unknown) {\n\t\t\tcleanupErrors.push(error);\n\t\t}\n\n\t\tlet restored: CreateAgentSessionRuntimeResult | undefined;\n\t\ttry {\n\t\t\trestored = await this.createRuntime({\n\t\t\t\tcwd: previous.services.cwd,\n\t\t\t\tagentDir: previous.services.agentDir,\n\t\t\t\tsessionManager: previous.session.sessionManager,\n\t\t\t\tsessionStartEvent: {\n\t\t\t\t\ttype: \"session_start\",\n\t\t\t\t\treason: \"resume\",\n\t\t\t\t\tpreviousSessionFile: failed.session.sessionFile,\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis.apply(restored);\n\t\t\tif (this.rebindSession) await this.rebindSession(this.session);\n\t\t\tfor (const resource of this.sessionResources) await resource.start(this.session);\n\t\t} catch (recoveryError: unknown) {\n\t\t\tif (restored) {\n\t\t\t\tcleanupErrors.push(\n\t\t\t\t\t...(await this.shutdownRuntime(restored.session, \"resume\", failed.session.sessionFile, {\n\t\t\t\t\t\tstopResources: true,\n\t\t\t\t\t\tinvalidateHost: true,\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.apply(previous);\n\t\t\treturn cleanupErrors.length > 0\n\t\t\t\t? new AggregateError([...cleanupErrors, recoveryError], \"Session rollback and cleanup failed.\")\n\t\t\t\t: recoveryError;\n\t\t}\n\n\t\treturn cleanupErrors.length > 0\n\t\t\t? new AggregateError(\n\t\t\t\t\tcleanupErrors,\n\t\t\t\t\t\"The previous session was restored, but failed replacement cleanup was incomplete.\",\n\t\t\t\t)\n\t\t\t: undefined;\n\t}\n\n\tprivate async shutdownRuntime(\n\t\tsession: AgentSession,\n\t\treason: SessionShutdownEvent[\"reason\"],\n\t\ttargetSessionFile: string | undefined,\n\t\toptions: { stopResources: boolean; invalidateHost: boolean; progress?: RuntimeShutdownProgress },\n\t): Promise<unknown[]> {\n\t\tconst errors: unknown[] = [];\n\t\tconst progress =\n\t\t\toptions.progress ??\n\t\t\t({\n\t\t\t\tshutdownEventEmitted: false,\n\t\t\t\tstoppedResources: new Set(),\n\t\t\t\thostInvalidated: false,\n\t\t\t\tsessionDisposed: false,\n\t\t\t} satisfies RuntimeShutdownProgress);\n\t\tif (!progress.shutdownEventEmitted) {\n\t\t\ttry {\n\t\t\t\tawait emitSessionShutdownEvent(session.extensionRunner, {\n\t\t\t\t\ttype: \"session_shutdown\",\n\t\t\t\t\treason,\n\t\t\t\t\ttargetSessionFile,\n\t\t\t\t});\n\t\t\t\tprogress.shutdownEventEmitted = true;\n\t\t\t} catch (error: unknown) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t}\n\t\tif (options.stopResources) {\n\t\t\tfor (const resource of this.sessionResources) {\n\t\t\t\tif (progress.stoppedResources.has(resource)) continue;\n\t\t\t\ttry {\n\t\t\t\t\tawait resource.stop();\n\t\t\t\t\tprogress.stoppedResources.add(resource);\n\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\terrors.push(error);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (options.invalidateHost && !progress.hostInvalidated) {\n\t\t\ttry {\n\t\t\t\tthis.beforeSessionInvalidate?.();\n\t\t\t\tprogress.hostInvalidated = true;\n\t\t\t} catch (error: unknown) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t}\n\t\tif (!progress.sessionDisposed) {\n\t\t\ttry {\n\t\t\t\tawait session.disposeAndWait();\n\t\t\t\tprogress.sessionDisposed = true;\n\t\t\t} catch (error: unknown) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t}\n\t\treturn errors;\n\t}\n\n\tprivate runSessionReplacement<T>(operation: () => Promise<T>): Promise<T> {\n\t\tif (this._disposeStarted) {\n\t\t\treturn Promise.reject(new Error(\"The session runtime has already been disposed.\"));\n\t\t}\n\t\tif (this._replacementInFlight) {\n\t\t\treturn Promise.reject(new Error(\"A session replacement is already in progress.\"));\n\t\t}\n\t\tconst replacement = Promise.resolve().then(operation);\n\t\tthis._replacementInFlight = replacement;\n\t\treturn replacement.finally(() => {\n\t\t\tif (this._replacementInFlight === replacement) this._replacementInFlight = undefined;\n\t\t});\n\t}\n\n\tasync switchSession(sessionPath: string, options?: AgentSessionSwitchOptions): Promise<{ cancelled: boolean }> {\n\t\treturn this.runSessionReplacement(() => this.switchSessionUnserialized(sessionPath, options));\n\t}\n\n\tprivate async switchSessionUnserialized(\n\t\tsessionPath: string,\n\t\toptions?: AgentSessionSwitchOptions,\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, this.services.agentDir, undefined, options?.cwdOverride);\n\t\tassertSessionCwdExists(sessionManager, this.cwd);\n\t\tconst prepared = await this.prepareReplacement(sessionManager, {\n\t\t\ttype: \"session_start\",\n\t\t\treason: \"resume\",\n\t\t\tpreviousSessionFile,\n\t\t});\n\t\tawait this.commitReplacement(prepared, {\n\t\t\treason: \"resume\",\n\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\tbeforeSessionResourcesStart: options?.beforeSessionResourcesStart,\n\t\t\twithSession: options?.withSession,\n\t\t});\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\treturn this.runSessionReplacement(() => this.newSessionUnserialized(options));\n\t}\n\n\tprivate async newSessionUnserialized(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, this.services.agentDir, sessionDir);\n\t\tif (options?.parentSession) {\n\t\t\tsessionManager.newSession({ parentSession: options.parentSession });\n\t\t}\n\n\t\tlet prepared: CreateAgentSessionRuntimeResult;\n\t\ttry {\n\t\t\tprepared = await this.prepareReplacement(sessionManager, {\n\t\t\t\ttype: \"session_start\",\n\t\t\t\treason: \"new\",\n\t\t\t\tpreviousSessionFile,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis.removeCreatedSessionFile(sessionManager.getSessionFile());\n\t\t\tthrow error;\n\t\t}\n\t\tif (options?.setup) {\n\t\t\ttry {\n\t\t\t\tawait options.setup(prepared.session.sessionManager);\n\t\t\t\tprepared.session.agent.state.messages = prepared.session.sessionManager.buildSessionContext().messages;\n\t\t\t} catch (error) {\n\t\t\t\tawait this.discardPrepared(prepared);\n\t\t\t\tthis.removeCreatedSessionFile(sessionManager.getSessionFile());\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\tawait this.commitReplacement(prepared, {\n\t\t\treason: \"new\",\n\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\twithSession: options?.withSession,\n\t\t\tonDiscard: () => this.removeCreatedSessionFile(sessionManager.getSessionFile()),\n\t\t});\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\treturn this.runSessionReplacement(() => this.forkUnserialized(entryId, options));\n\t}\n\n\tprivate async forkUnserialized(\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, this.services.agentDir, sessionDir);\n\t\t\t\tsessionManager.newSession({ parentSession: currentSessionFile });\n\t\t\t\tlet prepared: CreateAgentSessionRuntimeResult;\n\t\t\t\ttry {\n\t\t\t\t\tprepared = await this.prepareReplacement(sessionManager, {\n\t\t\t\t\t\ttype: \"session_start\",\n\t\t\t\t\t\treason: \"fork\",\n\t\t\t\t\t\tpreviousSessionFile,\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.removeCreatedSessionFile(sessionManager.getSessionFile());\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tawait this.commitReplacement(prepared, {\n\t\t\t\t\treason: \"fork\",\n\t\t\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\t\t\twithSession: options?.withSession,\n\t\t\t\t\tonDiscard: () => this.removeCreatedSessionFile(sessionManager.getSessionFile()),\n\t\t\t\t});\n\t\t\t\treturn { cancelled: false, selectedText };\n\t\t\t}\n\t\t\tif (!existsSync(currentSessionFile)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"This session has not been saved yet. Wait for the first assistant response before cloning or forking it.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst sourceSessionManager = SessionManager.open(currentSessionFile, this.services.agentDir, sessionDir);\n\t\t\tconst sessionManager = sourceSessionManager.createBranchedSessionManager(targetLeafId);\n\t\t\tconst forkedSessionPath = sessionManager.getSessionFile();\n\t\t\tif (!forkedSessionPath) {\n\t\t\t\tthrow new Error(\"Failed to create forked session\");\n\t\t\t}\n\t\t\tlet prepared: CreateAgentSessionRuntimeResult;\n\t\t\ttry {\n\t\t\t\tprepared = await this.prepareReplacement(sessionManager, {\n\t\t\t\t\ttype: \"session_start\",\n\t\t\t\t\treason: \"fork\",\n\t\t\t\t\tpreviousSessionFile,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tthis.removeCreatedSessionFile(forkedSessionPath);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tawait this.commitReplacement(prepared, {\n\t\t\t\treason: \"fork\",\n\t\t\t\ttargetSessionFile: forkedSessionPath,\n\t\t\t\twithSession: options?.withSession,\n\t\t\t\tonDiscard: () => this.removeCreatedSessionFile(forkedSessionPath),\n\t\t\t});\n\t\t\treturn { cancelled: false, selectedText };\n\t\t}\n\n\t\tlet sessionManager: SessionManager;\n\t\tif (!targetLeafId) {\n\t\t\tsessionManager = SessionManager.inMemory(this.cwd);\n\t\t\tsessionManager.newSession({ parentSession: this.session.sessionFile });\n\t\t} else {\n\t\t\tsessionManager = this.session.sessionManager.createBranchedSessionManager(targetLeafId);\n\t\t}\n\t\tconst prepared = await this.prepareReplacement(sessionManager, {\n\t\t\ttype: \"session_start\",\n\t\t\treason: \"fork\",\n\t\t\tpreviousSessionFile,\n\t\t});\n\t\tawait this.commitReplacement(prepared, {\n\t\t\treason: \"fork\",\n\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\twithSession: options?.withSession,\n\t\t});\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\treturn this.runSessionReplacement(() => this.importFromJsonlUnserialized(inputPath, cwdOverride));\n\t}\n\n\tprivate async importFromJsonlUnserialized(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\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\tlet copied = false;\n\t\tif (resolve(destinationPath) !== resolvedPath) {\n\t\t\tif (!existsSync(sessionDir)) mkdirSync(sessionDir, { recursive: true });\n\t\t\tcopyFileSync(resolvedPath, destinationPath, fsConstants.COPYFILE_EXCL);\n\t\t\tcopied = true;\n\t\t}\n\n\t\tlet sessionManager: SessionManager;\n\t\tlet prepared: CreateAgentSessionRuntimeResult;\n\t\ttry {\n\t\t\tsessionManager = SessionManager.open(destinationPath, this.services.agentDir, sessionDir, cwdOverride);\n\t\t\tassertSessionCwdExists(sessionManager, this.cwd);\n\t\t\tprepared = await this.prepareReplacement(sessionManager, {\n\t\t\t\ttype: \"session_start\",\n\t\t\t\treason: \"resume\",\n\t\t\t\tpreviousSessionFile,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (copied) this.removeCreatedSessionFile(destinationPath);\n\t\t\tthrow error;\n\t\t}\n\t\tawait this.commitReplacement(prepared, {\n\t\t\treason: \"resume\",\n\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\tonDiscard: copied ? () => this.removeCreatedSessionFile(destinationPath) : undefined,\n\t\t});\n\t\treturn { cancelled: false };\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tif (this._disposeInFlight) return this._disposeInFlight;\n\t\tif (this._disposed) return;\n\t\tthis._disposeStarted = true;\n\t\tconst replacement = this._replacementInFlight;\n\t\tconst disposal = (async () => {\n\t\t\tif (replacement) {\n\t\t\t\ttry {\n\t\t\t\t\tawait replacement;\n\t\t\t\t} catch {\n\t\t\t\t\t// Replacement already reports its own error; dispose whichever runtime it left active.\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst errors = await this.shutdownRuntime(this.session, \"quit\", undefined, {\n\t\t\t\tstopResources: true,\n\t\t\t\tinvalidateHost: true,\n\t\t\t\tprogress: this.disposeProgress,\n\t\t\t});\n\t\t\tif (errors.length === 1) throw errors[0];\n\t\t\tif (errors.length > 1) throw new AggregateError(errors, \"Session runtime disposal failed.\");\n\t\t\tthis._disposed = true;\n\t\t})();\n\t\tthis._disposeInFlight = disposal;\n\t\ttry {\n\t\t\tawait disposal;\n\t\t} finally {\n\t\t\tthis._disposeInFlight = undefined;\n\t\t}\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"]}
@@ -469,6 +469,9 @@ export class AgentSessionRuntime {
469
469
  });
470
470
  return { cancelled: false, selectedText };
471
471
  }
472
+ if (!existsSync(currentSessionFile)) {
473
+ throw new Error("This session has not been saved yet. Wait for the first assistant response before cloning or forking it.");
474
+ }
472
475
  const sourceSessionManager = SessionManager.open(currentSessionFile, this.services.agentDir, sessionDir);
473
476
  const sessionManager = sourceSessionManager.createBranchedSessionManager(targetLeafId);
474
477
  const forkedSessionPath = sessionManager.getSessionFile();
@@ -1 +1 @@
1
- {"version":3,"file":"agent-session-runtime.js","sourceRoot":"","sources":["../../src/core/agent-session-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { copyFileSync, existsSync, constants as fsConstants, mkdirSync, unlinkSync } from \"node:fs\";\nimport { basename, join, resolve } from \"node:path\";\nimport { SessionManager } from \"@caupulican/pi-agent-core/node\";\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\";\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\ninterface AgentSessionRuntimeState {\n\tsession: AgentSession;\n\tservices: AgentSessionServices;\n\tdiagnostics: AgentSessionRuntimeDiagnostic[];\n\tmodelFallbackMessage?: string;\n}\n\ninterface RuntimeShutdownProgress {\n\tshutdownEventEmitted: boolean;\n\tstoppedResources: Set<AgentSessionRuntimeResource>;\n\thostInvalidated: boolean;\n\tsessionDisposed: boolean;\n}\n\n/** Session-owned background runtime that must not survive a session replacement. */\nexport interface AgentSessionRuntimeResource {\n\tstart(session: AgentSession): Promise<void>;\n\tstop(): Promise<void> | void;\n}\n\n/** Internal activation hooks used by the interactive session-resume flow. */\nexport interface AgentSessionSwitchOptions {\n\tcwdOverride?: string;\n\t/** Runs against the installed replacement after host rebind and before supervisors restart. */\n\tbeforeSessionResourcesStart?: (session: AgentSession) => Promise<void> | void;\n\twithSession?: (ctx: ReplacedSessionContext) => Promise<void>;\n}\n\ninterface SessionReplacementCommitOptions {\n\treason: SessionShutdownEvent[\"reason\"];\n\ttargetSessionFile: string | undefined;\n\tbeforeSessionResourcesStart?: (session: AgentSession) => Promise<void> | void;\n\twithSession?: (ctx: ReplacedSessionContext) => Promise<void>;\n\tonDiscard?: () => void;\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\n/** A teardown or activation failure at the replacement boundary, including rollback outcome. */\nexport class SessionReplacementRuntimeError extends Error {\n\treadonly phase: \"teardown\" | \"activation\";\n\treadonly recovered: boolean;\n\treadonly transitionError: unknown;\n\treadonly recoveryError: unknown | undefined;\n\n\tconstructor(\n\t\tphase: \"teardown\" | \"activation\",\n\t\ttransitionError: unknown,\n\t\trecovered: boolean,\n\t\trecoveryError?: unknown,\n\t) {\n\t\tconst transitionMessage = transitionError instanceof Error ? transitionError.message : String(transitionError);\n\t\tsuper(\n\t\t\trecovered\n\t\t\t\t? `Session replacement ${phase} failed; the previous session was restored: ${transitionMessage}`\n\t\t\t\t: `Session replacement ${phase} failed and the previous session could not be restored safely: ${transitionMessage}`,\n\t\t);\n\t\tthis.name = \"SessionReplacementRuntimeError\";\n\t\tthis.phase = phase;\n\t\tthis.recovered = recovered;\n\t\tthis.transitionError = transitionError;\n\t\tthis.recoveryError = recoveryError;\n\t}\n}\n\n/** A post-commit extension callback failed; the replacement itself remains the active session. */\nexport class SessionReplacementCallbackError extends Error {\n\treadonly replacementCommitted = true;\n\treadonly callbackError: unknown;\n\n\tconstructor(callbackError: unknown) {\n\t\tconst callbackMessage = callbackError instanceof Error ? callbackError.message : String(callbackError);\n\t\tsuper(`Session replacement completed, but its withSession callback failed: ${callbackMessage}`);\n\t\tthis.name = \"SessionReplacementCallbackError\";\n\t\tthis.callbackError = callbackError;\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 construct the candidate runtime before retiring\n * the current one. If preparation fails, the working session remains active.\n */\nexport class AgentSessionRuntime {\n\tprivate rebindSession?: (session: AgentSession) => 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\tprivate _replacementInFlight: Promise<unknown> | undefined;\n\tprivate _disposeInFlight: Promise<void> | undefined;\n\tprivate _disposeStarted = false;\n\tprivate _disposed = false;\n\tprivate readonly disposeProgress: RuntimeShutdownProgress = {\n\t\tshutdownEventEmitted: false,\n\t\tstoppedResources: new Set(),\n\t\thostInvalidated: false,\n\t\tsessionDisposed: false,\n\t};\n\tprivate readonly sessionResources: AgentSessionRuntimeResource[] = [];\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\t/** True from replacement admission until rebind and replacement callbacks have settled. */\n\tget isReplacing(): boolean {\n\t\treturn this._replacementInFlight !== undefined;\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\t/** Register a resource whose lifecycle follows the active session (supervisors, watchers). */\n\tregisterSessionResource(resource: AgentSessionRuntimeResource): void {\n\t\tif (this.sessionResources.includes(resource)) return;\n\t\tthis.sessionResources.push(resource);\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\tconst errors = await this.shutdownRuntime(this.session, reason, targetSessionFile, {\n\t\t\tstopResources: true,\n\t\t\tinvalidateHost: true,\n\t\t});\n\t\tif (errors.length === 1) throw errors[0];\n\t\tif (errors.length > 1) throw new AggregateError(errors, \"Session runtime teardown failed.\");\n\t}\n\n\tprivate async discardPrepared(result: CreateAgentSessionRuntimeResult): Promise<void> {\n\t\tawait result.session.disposeAndWait();\n\t}\n\n\tprivate removeCreatedSessionFile(sessionFile: string | undefined): void {\n\t\tif (!sessionFile || sessionFile === this.session.sessionFile || !existsSync(sessionFile)) return;\n\t\ttry {\n\t\t\tunlinkSync(sessionFile);\n\t\t} catch {\n\t\t\t// Best-effort rollback of an artifact created solely for the rejected replacement.\n\t\t}\n\t}\n\n\tprivate async prepareReplacement(\n\t\tsessionManager: SessionManager,\n\t\tsessionStartEvent: SessionStartEvent,\n\t): Promise<CreateAgentSessionRuntimeResult> {\n\t\treturn this.createRuntime({\n\t\t\tcwd: sessionManager.getCwd(),\n\t\t\tagentDir: this.services.agentDir,\n\t\t\tsessionManager,\n\t\t\tsessionStartEvent,\n\t\t});\n\t}\n\n\tprivate async commitReplacement(\n\t\tresult: CreateAgentSessionRuntimeResult,\n\t\toptions: SessionReplacementCommitOptions,\n\t): Promise<void> {\n\t\tconst previous = this.snapshot();\n\t\ttry {\n\t\t\tawait this.teardownCurrent(options.reason, options.targetSessionFile);\n\t\t} catch (transitionError: unknown) {\n\t\t\tconst recoveryError = await this.restorePreviousAfterRuntimeFailure(previous, result, options, false);\n\t\t\tthrow new SessionReplacementRuntimeError(\n\t\t\t\t\"teardown\",\n\t\t\t\ttransitionError,\n\t\t\t\trecoveryError === undefined,\n\t\t\t\trecoveryError,\n\t\t\t);\n\t\t}\n\t\tthis.apply(result);\n\t\ttry {\n\t\t\tawait this.activateReplacement(options);\n\t\t} catch (activationError: unknown) {\n\t\t\tconst recoveryError = await this.restorePreviousAfterRuntimeFailure(previous, result, options, true);\n\t\t\tthrow new SessionReplacementRuntimeError(\n\t\t\t\t\"activation\",\n\t\t\t\tactivationError,\n\t\t\t\trecoveryError === undefined,\n\t\t\t\trecoveryError,\n\t\t\t);\n\t\t}\n\t\tif (options.withSession) {\n\t\t\ttry {\n\t\t\t\tawait options.withSession(this.session.createReplacedSessionContext());\n\t\t\t} catch (callbackError: unknown) {\n\t\t\t\tthrow new SessionReplacementCallbackError(callbackError);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate snapshot(): AgentSessionRuntimeState {\n\t\treturn {\n\t\t\tsession: this._session,\n\t\t\tservices: this._services,\n\t\t\tdiagnostics: [...this._diagnostics],\n\t\t\t...(this._modelFallbackMessage !== undefined ? { modelFallbackMessage: this._modelFallbackMessage } : {}),\n\t\t};\n\t}\n\n\tprivate apply(result: AgentSessionRuntimeState): 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 activateReplacement(options: SessionReplacementCommitOptions): Promise<void> {\n\t\tif (this.rebindSession) {\n\t\t\tawait this.rebindSession(this.session);\n\t\t}\n\t\tawait options.beforeSessionResourcesStart?.(this.session);\n\t\tfor (const resource of this.sessionResources) await resource.start(this.session);\n\t}\n\n\tprivate async restorePreviousAfterRuntimeFailure(\n\t\tprevious: AgentSessionRuntimeState,\n\t\tfailed: CreateAgentSessionRuntimeResult,\n\t\toptions: SessionReplacementCommitOptions,\n\t\tcandidateActivated: boolean,\n\t): Promise<unknown | undefined> {\n\t\tconst cleanupErrors = await this.shutdownRuntime(failed.session, options.reason, previous.session.sessionFile, {\n\t\t\tstopResources: candidateActivated,\n\t\t\tinvalidateHost: candidateActivated,\n\t\t});\n\t\t// The old AgentSession was disposed at the commit boundary, but its SessionManager remains the\n\t\t// durable reconstruction source. Restore the old snapshot temporarily so rollback-only artifact\n\t\t// cleanup cannot mistake the failed candidate for the active session.\n\t\tthis.apply(previous);\n\t\ttry {\n\t\t\toptions.onDiscard?.();\n\t\t} catch (error: unknown) {\n\t\t\tcleanupErrors.push(error);\n\t\t}\n\n\t\tlet restored: CreateAgentSessionRuntimeResult | undefined;\n\t\ttry {\n\t\t\trestored = await this.createRuntime({\n\t\t\t\tcwd: previous.services.cwd,\n\t\t\t\tagentDir: previous.services.agentDir,\n\t\t\t\tsessionManager: previous.session.sessionManager,\n\t\t\t\tsessionStartEvent: {\n\t\t\t\t\ttype: \"session_start\",\n\t\t\t\t\treason: \"resume\",\n\t\t\t\t\tpreviousSessionFile: failed.session.sessionFile,\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis.apply(restored);\n\t\t\tif (this.rebindSession) await this.rebindSession(this.session);\n\t\t\tfor (const resource of this.sessionResources) await resource.start(this.session);\n\t\t} catch (recoveryError: unknown) {\n\t\t\tif (restored) {\n\t\t\t\tcleanupErrors.push(\n\t\t\t\t\t...(await this.shutdownRuntime(restored.session, \"resume\", failed.session.sessionFile, {\n\t\t\t\t\t\tstopResources: true,\n\t\t\t\t\t\tinvalidateHost: true,\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.apply(previous);\n\t\t\treturn cleanupErrors.length > 0\n\t\t\t\t? new AggregateError([...cleanupErrors, recoveryError], \"Session rollback and cleanup failed.\")\n\t\t\t\t: recoveryError;\n\t\t}\n\n\t\treturn cleanupErrors.length > 0\n\t\t\t? new AggregateError(\n\t\t\t\t\tcleanupErrors,\n\t\t\t\t\t\"The previous session was restored, but failed replacement cleanup was incomplete.\",\n\t\t\t\t)\n\t\t\t: undefined;\n\t}\n\n\tprivate async shutdownRuntime(\n\t\tsession: AgentSession,\n\t\treason: SessionShutdownEvent[\"reason\"],\n\t\ttargetSessionFile: string | undefined,\n\t\toptions: { stopResources: boolean; invalidateHost: boolean; progress?: RuntimeShutdownProgress },\n\t): Promise<unknown[]> {\n\t\tconst errors: unknown[] = [];\n\t\tconst progress =\n\t\t\toptions.progress ??\n\t\t\t({\n\t\t\t\tshutdownEventEmitted: false,\n\t\t\t\tstoppedResources: new Set(),\n\t\t\t\thostInvalidated: false,\n\t\t\t\tsessionDisposed: false,\n\t\t\t} satisfies RuntimeShutdownProgress);\n\t\tif (!progress.shutdownEventEmitted) {\n\t\t\ttry {\n\t\t\t\tawait emitSessionShutdownEvent(session.extensionRunner, {\n\t\t\t\t\ttype: \"session_shutdown\",\n\t\t\t\t\treason,\n\t\t\t\t\ttargetSessionFile,\n\t\t\t\t});\n\t\t\t\tprogress.shutdownEventEmitted = true;\n\t\t\t} catch (error: unknown) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t}\n\t\tif (options.stopResources) {\n\t\t\tfor (const resource of this.sessionResources) {\n\t\t\t\tif (progress.stoppedResources.has(resource)) continue;\n\t\t\t\ttry {\n\t\t\t\t\tawait resource.stop();\n\t\t\t\t\tprogress.stoppedResources.add(resource);\n\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\terrors.push(error);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (options.invalidateHost && !progress.hostInvalidated) {\n\t\t\ttry {\n\t\t\t\tthis.beforeSessionInvalidate?.();\n\t\t\t\tprogress.hostInvalidated = true;\n\t\t\t} catch (error: unknown) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t}\n\t\tif (!progress.sessionDisposed) {\n\t\t\ttry {\n\t\t\t\tawait session.disposeAndWait();\n\t\t\t\tprogress.sessionDisposed = true;\n\t\t\t} catch (error: unknown) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t}\n\t\treturn errors;\n\t}\n\n\tprivate runSessionReplacement<T>(operation: () => Promise<T>): Promise<T> {\n\t\tif (this._disposeStarted) {\n\t\t\treturn Promise.reject(new Error(\"The session runtime has already been disposed.\"));\n\t\t}\n\t\tif (this._replacementInFlight) {\n\t\t\treturn Promise.reject(new Error(\"A session replacement is already in progress.\"));\n\t\t}\n\t\tconst replacement = Promise.resolve().then(operation);\n\t\tthis._replacementInFlight = replacement;\n\t\treturn replacement.finally(() => {\n\t\t\tif (this._replacementInFlight === replacement) this._replacementInFlight = undefined;\n\t\t});\n\t}\n\n\tasync switchSession(sessionPath: string, options?: AgentSessionSwitchOptions): Promise<{ cancelled: boolean }> {\n\t\treturn this.runSessionReplacement(() => this.switchSessionUnserialized(sessionPath, options));\n\t}\n\n\tprivate async switchSessionUnserialized(\n\t\tsessionPath: string,\n\t\toptions?: AgentSessionSwitchOptions,\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, this.services.agentDir, undefined, options?.cwdOverride);\n\t\tassertSessionCwdExists(sessionManager, this.cwd);\n\t\tconst prepared = await this.prepareReplacement(sessionManager, {\n\t\t\ttype: \"session_start\",\n\t\t\treason: \"resume\",\n\t\t\tpreviousSessionFile,\n\t\t});\n\t\tawait this.commitReplacement(prepared, {\n\t\t\treason: \"resume\",\n\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\tbeforeSessionResourcesStart: options?.beforeSessionResourcesStart,\n\t\t\twithSession: options?.withSession,\n\t\t});\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\treturn this.runSessionReplacement(() => this.newSessionUnserialized(options));\n\t}\n\n\tprivate async newSessionUnserialized(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, this.services.agentDir, sessionDir);\n\t\tif (options?.parentSession) {\n\t\t\tsessionManager.newSession({ parentSession: options.parentSession });\n\t\t}\n\n\t\tlet prepared: CreateAgentSessionRuntimeResult;\n\t\ttry {\n\t\t\tprepared = await this.prepareReplacement(sessionManager, {\n\t\t\t\ttype: \"session_start\",\n\t\t\t\treason: \"new\",\n\t\t\t\tpreviousSessionFile,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis.removeCreatedSessionFile(sessionManager.getSessionFile());\n\t\t\tthrow error;\n\t\t}\n\t\tif (options?.setup) {\n\t\t\ttry {\n\t\t\t\tawait options.setup(prepared.session.sessionManager);\n\t\t\t\tprepared.session.agent.state.messages = prepared.session.sessionManager.buildSessionContext().messages;\n\t\t\t} catch (error) {\n\t\t\t\tawait this.discardPrepared(prepared);\n\t\t\t\tthis.removeCreatedSessionFile(sessionManager.getSessionFile());\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\tawait this.commitReplacement(prepared, {\n\t\t\treason: \"new\",\n\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\twithSession: options?.withSession,\n\t\t\tonDiscard: () => this.removeCreatedSessionFile(sessionManager.getSessionFile()),\n\t\t});\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\treturn this.runSessionReplacement(() => this.forkUnserialized(entryId, options));\n\t}\n\n\tprivate async forkUnserialized(\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, this.services.agentDir, sessionDir);\n\t\t\t\tsessionManager.newSession({ parentSession: currentSessionFile });\n\t\t\t\tlet prepared: CreateAgentSessionRuntimeResult;\n\t\t\t\ttry {\n\t\t\t\t\tprepared = await this.prepareReplacement(sessionManager, {\n\t\t\t\t\t\ttype: \"session_start\",\n\t\t\t\t\t\treason: \"fork\",\n\t\t\t\t\t\tpreviousSessionFile,\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.removeCreatedSessionFile(sessionManager.getSessionFile());\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tawait this.commitReplacement(prepared, {\n\t\t\t\t\treason: \"fork\",\n\t\t\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\t\t\twithSession: options?.withSession,\n\t\t\t\t\tonDiscard: () => this.removeCreatedSessionFile(sessionManager.getSessionFile()),\n\t\t\t\t});\n\t\t\t\treturn { cancelled: false, selectedText };\n\t\t\t}\n\n\t\t\tconst sourceSessionManager = SessionManager.open(currentSessionFile, this.services.agentDir, sessionDir);\n\t\t\tconst sessionManager = sourceSessionManager.createBranchedSessionManager(targetLeafId);\n\t\t\tconst forkedSessionPath = sessionManager.getSessionFile();\n\t\t\tif (!forkedSessionPath) {\n\t\t\t\tthrow new Error(\"Failed to create forked session\");\n\t\t\t}\n\t\t\tlet prepared: CreateAgentSessionRuntimeResult;\n\t\t\ttry {\n\t\t\t\tprepared = await this.prepareReplacement(sessionManager, {\n\t\t\t\t\ttype: \"session_start\",\n\t\t\t\t\treason: \"fork\",\n\t\t\t\t\tpreviousSessionFile,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tthis.removeCreatedSessionFile(forkedSessionPath);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tawait this.commitReplacement(prepared, {\n\t\t\t\treason: \"fork\",\n\t\t\t\ttargetSessionFile: forkedSessionPath,\n\t\t\t\twithSession: options?.withSession,\n\t\t\t\tonDiscard: () => this.removeCreatedSessionFile(forkedSessionPath),\n\t\t\t});\n\t\t\treturn { cancelled: false, selectedText };\n\t\t}\n\n\t\tlet sessionManager: SessionManager;\n\t\tif (!targetLeafId) {\n\t\t\tsessionManager = SessionManager.inMemory(this.cwd);\n\t\t\tsessionManager.newSession({ parentSession: this.session.sessionFile });\n\t\t} else {\n\t\t\tsessionManager = this.session.sessionManager.createBranchedSessionManager(targetLeafId);\n\t\t}\n\t\tconst prepared = await this.prepareReplacement(sessionManager, {\n\t\t\ttype: \"session_start\",\n\t\t\treason: \"fork\",\n\t\t\tpreviousSessionFile,\n\t\t});\n\t\tawait this.commitReplacement(prepared, {\n\t\t\treason: \"fork\",\n\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\twithSession: options?.withSession,\n\t\t});\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\treturn this.runSessionReplacement(() => this.importFromJsonlUnserialized(inputPath, cwdOverride));\n\t}\n\n\tprivate async importFromJsonlUnserialized(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\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\tlet copied = false;\n\t\tif (resolve(destinationPath) !== resolvedPath) {\n\t\t\tif (!existsSync(sessionDir)) mkdirSync(sessionDir, { recursive: true });\n\t\t\tcopyFileSync(resolvedPath, destinationPath, fsConstants.COPYFILE_EXCL);\n\t\t\tcopied = true;\n\t\t}\n\n\t\tlet sessionManager: SessionManager;\n\t\tlet prepared: CreateAgentSessionRuntimeResult;\n\t\ttry {\n\t\t\tsessionManager = SessionManager.open(destinationPath, this.services.agentDir, sessionDir, cwdOverride);\n\t\t\tassertSessionCwdExists(sessionManager, this.cwd);\n\t\t\tprepared = await this.prepareReplacement(sessionManager, {\n\t\t\t\ttype: \"session_start\",\n\t\t\t\treason: \"resume\",\n\t\t\t\tpreviousSessionFile,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (copied) this.removeCreatedSessionFile(destinationPath);\n\t\t\tthrow error;\n\t\t}\n\t\tawait this.commitReplacement(prepared, {\n\t\t\treason: \"resume\",\n\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\tonDiscard: copied ? () => this.removeCreatedSessionFile(destinationPath) : undefined,\n\t\t});\n\t\treturn { cancelled: false };\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tif (this._disposeInFlight) return this._disposeInFlight;\n\t\tif (this._disposed) return;\n\t\tthis._disposeStarted = true;\n\t\tconst replacement = this._replacementInFlight;\n\t\tconst disposal = (async () => {\n\t\t\tif (replacement) {\n\t\t\t\ttry {\n\t\t\t\t\tawait replacement;\n\t\t\t\t} catch {\n\t\t\t\t\t// Replacement already reports its own error; dispose whichever runtime it left active.\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst errors = await this.shutdownRuntime(this.session, \"quit\", undefined, {\n\t\t\t\tstopResources: true,\n\t\t\t\tinvalidateHost: true,\n\t\t\t\tprogress: this.disposeProgress,\n\t\t\t});\n\t\t\tif (errors.length === 1) throw errors[0];\n\t\t\tif (errors.length > 1) throw new AggregateError(errors, \"Session runtime disposal failed.\");\n\t\t\tthis._disposed = true;\n\t\t})();\n\t\tthis._disposeInFlight = disposal;\n\t\ttry {\n\t\t\tawait disposal;\n\t\t} finally {\n\t\t\tthis._disposeInFlight = undefined;\n\t\t}\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
+ {"version":3,"file":"agent-session-runtime.js","sourceRoot":"","sources":["../../src/core/agent-session-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { copyFileSync, existsSync, constants as fsConstants, mkdirSync, unlinkSync } from \"node:fs\";\nimport { basename, join, resolve } from \"node:path\";\nimport { SessionManager } from \"@caupulican/pi-agent-core/node\";\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\";\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\ninterface AgentSessionRuntimeState {\n\tsession: AgentSession;\n\tservices: AgentSessionServices;\n\tdiagnostics: AgentSessionRuntimeDiagnostic[];\n\tmodelFallbackMessage?: string;\n}\n\ninterface RuntimeShutdownProgress {\n\tshutdownEventEmitted: boolean;\n\tstoppedResources: Set<AgentSessionRuntimeResource>;\n\thostInvalidated: boolean;\n\tsessionDisposed: boolean;\n}\n\n/** Session-owned background runtime that must not survive a session replacement. */\nexport interface AgentSessionRuntimeResource {\n\tstart(session: AgentSession): Promise<void>;\n\tstop(): Promise<void> | void;\n}\n\n/** Internal activation hooks used by the interactive session-resume flow. */\nexport interface AgentSessionSwitchOptions {\n\tcwdOverride?: string;\n\t/** Runs against the installed replacement after host rebind and before supervisors restart. */\n\tbeforeSessionResourcesStart?: (session: AgentSession) => Promise<void> | void;\n\twithSession?: (ctx: ReplacedSessionContext) => Promise<void>;\n}\n\ninterface SessionReplacementCommitOptions {\n\treason: SessionShutdownEvent[\"reason\"];\n\ttargetSessionFile: string | undefined;\n\tbeforeSessionResourcesStart?: (session: AgentSession) => Promise<void> | void;\n\twithSession?: (ctx: ReplacedSessionContext) => Promise<void>;\n\tonDiscard?: () => void;\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\n/** A teardown or activation failure at the replacement boundary, including rollback outcome. */\nexport class SessionReplacementRuntimeError extends Error {\n\treadonly phase: \"teardown\" | \"activation\";\n\treadonly recovered: boolean;\n\treadonly transitionError: unknown;\n\treadonly recoveryError: unknown | undefined;\n\n\tconstructor(\n\t\tphase: \"teardown\" | \"activation\",\n\t\ttransitionError: unknown,\n\t\trecovered: boolean,\n\t\trecoveryError?: unknown,\n\t) {\n\t\tconst transitionMessage = transitionError instanceof Error ? transitionError.message : String(transitionError);\n\t\tsuper(\n\t\t\trecovered\n\t\t\t\t? `Session replacement ${phase} failed; the previous session was restored: ${transitionMessage}`\n\t\t\t\t: `Session replacement ${phase} failed and the previous session could not be restored safely: ${transitionMessage}`,\n\t\t);\n\t\tthis.name = \"SessionReplacementRuntimeError\";\n\t\tthis.phase = phase;\n\t\tthis.recovered = recovered;\n\t\tthis.transitionError = transitionError;\n\t\tthis.recoveryError = recoveryError;\n\t}\n}\n\n/** A post-commit extension callback failed; the replacement itself remains the active session. */\nexport class SessionReplacementCallbackError extends Error {\n\treadonly replacementCommitted = true;\n\treadonly callbackError: unknown;\n\n\tconstructor(callbackError: unknown) {\n\t\tconst callbackMessage = callbackError instanceof Error ? callbackError.message : String(callbackError);\n\t\tsuper(`Session replacement completed, but its withSession callback failed: ${callbackMessage}`);\n\t\tthis.name = \"SessionReplacementCallbackError\";\n\t\tthis.callbackError = callbackError;\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 construct the candidate runtime before retiring\n * the current one. If preparation fails, the working session remains active.\n */\nexport class AgentSessionRuntime {\n\tprivate rebindSession?: (session: AgentSession) => 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\tprivate _replacementInFlight: Promise<unknown> | undefined;\n\tprivate _disposeInFlight: Promise<void> | undefined;\n\tprivate _disposeStarted = false;\n\tprivate _disposed = false;\n\tprivate readonly disposeProgress: RuntimeShutdownProgress = {\n\t\tshutdownEventEmitted: false,\n\t\tstoppedResources: new Set(),\n\t\thostInvalidated: false,\n\t\tsessionDisposed: false,\n\t};\n\tprivate readonly sessionResources: AgentSessionRuntimeResource[] = [];\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\t/** True from replacement admission until rebind and replacement callbacks have settled. */\n\tget isReplacing(): boolean {\n\t\treturn this._replacementInFlight !== undefined;\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\t/** Register a resource whose lifecycle follows the active session (supervisors, watchers). */\n\tregisterSessionResource(resource: AgentSessionRuntimeResource): void {\n\t\tif (this.sessionResources.includes(resource)) return;\n\t\tthis.sessionResources.push(resource);\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\tconst errors = await this.shutdownRuntime(this.session, reason, targetSessionFile, {\n\t\t\tstopResources: true,\n\t\t\tinvalidateHost: true,\n\t\t});\n\t\tif (errors.length === 1) throw errors[0];\n\t\tif (errors.length > 1) throw new AggregateError(errors, \"Session runtime teardown failed.\");\n\t}\n\n\tprivate async discardPrepared(result: CreateAgentSessionRuntimeResult): Promise<void> {\n\t\tawait result.session.disposeAndWait();\n\t}\n\n\tprivate removeCreatedSessionFile(sessionFile: string | undefined): void {\n\t\tif (!sessionFile || sessionFile === this.session.sessionFile || !existsSync(sessionFile)) return;\n\t\ttry {\n\t\t\tunlinkSync(sessionFile);\n\t\t} catch {\n\t\t\t// Best-effort rollback of an artifact created solely for the rejected replacement.\n\t\t}\n\t}\n\n\tprivate async prepareReplacement(\n\t\tsessionManager: SessionManager,\n\t\tsessionStartEvent: SessionStartEvent,\n\t): Promise<CreateAgentSessionRuntimeResult> {\n\t\treturn this.createRuntime({\n\t\t\tcwd: sessionManager.getCwd(),\n\t\t\tagentDir: this.services.agentDir,\n\t\t\tsessionManager,\n\t\t\tsessionStartEvent,\n\t\t});\n\t}\n\n\tprivate async commitReplacement(\n\t\tresult: CreateAgentSessionRuntimeResult,\n\t\toptions: SessionReplacementCommitOptions,\n\t): Promise<void> {\n\t\tconst previous = this.snapshot();\n\t\ttry {\n\t\t\tawait this.teardownCurrent(options.reason, options.targetSessionFile);\n\t\t} catch (transitionError: unknown) {\n\t\t\tconst recoveryError = await this.restorePreviousAfterRuntimeFailure(previous, result, options, false);\n\t\t\tthrow new SessionReplacementRuntimeError(\n\t\t\t\t\"teardown\",\n\t\t\t\ttransitionError,\n\t\t\t\trecoveryError === undefined,\n\t\t\t\trecoveryError,\n\t\t\t);\n\t\t}\n\t\tthis.apply(result);\n\t\ttry {\n\t\t\tawait this.activateReplacement(options);\n\t\t} catch (activationError: unknown) {\n\t\t\tconst recoveryError = await this.restorePreviousAfterRuntimeFailure(previous, result, options, true);\n\t\t\tthrow new SessionReplacementRuntimeError(\n\t\t\t\t\"activation\",\n\t\t\t\tactivationError,\n\t\t\t\trecoveryError === undefined,\n\t\t\t\trecoveryError,\n\t\t\t);\n\t\t}\n\t\tif (options.withSession) {\n\t\t\ttry {\n\t\t\t\tawait options.withSession(this.session.createReplacedSessionContext());\n\t\t\t} catch (callbackError: unknown) {\n\t\t\t\tthrow new SessionReplacementCallbackError(callbackError);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate snapshot(): AgentSessionRuntimeState {\n\t\treturn {\n\t\t\tsession: this._session,\n\t\t\tservices: this._services,\n\t\t\tdiagnostics: [...this._diagnostics],\n\t\t\t...(this._modelFallbackMessage !== undefined ? { modelFallbackMessage: this._modelFallbackMessage } : {}),\n\t\t};\n\t}\n\n\tprivate apply(result: AgentSessionRuntimeState): 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 activateReplacement(options: SessionReplacementCommitOptions): Promise<void> {\n\t\tif (this.rebindSession) {\n\t\t\tawait this.rebindSession(this.session);\n\t\t}\n\t\tawait options.beforeSessionResourcesStart?.(this.session);\n\t\tfor (const resource of this.sessionResources) await resource.start(this.session);\n\t}\n\n\tprivate async restorePreviousAfterRuntimeFailure(\n\t\tprevious: AgentSessionRuntimeState,\n\t\tfailed: CreateAgentSessionRuntimeResult,\n\t\toptions: SessionReplacementCommitOptions,\n\t\tcandidateActivated: boolean,\n\t): Promise<unknown | undefined> {\n\t\tconst cleanupErrors = await this.shutdownRuntime(failed.session, options.reason, previous.session.sessionFile, {\n\t\t\tstopResources: candidateActivated,\n\t\t\tinvalidateHost: candidateActivated,\n\t\t});\n\t\t// The old AgentSession was disposed at the commit boundary, but its SessionManager remains the\n\t\t// durable reconstruction source. Restore the old snapshot temporarily so rollback-only artifact\n\t\t// cleanup cannot mistake the failed candidate for the active session.\n\t\tthis.apply(previous);\n\t\ttry {\n\t\t\toptions.onDiscard?.();\n\t\t} catch (error: unknown) {\n\t\t\tcleanupErrors.push(error);\n\t\t}\n\n\t\tlet restored: CreateAgentSessionRuntimeResult | undefined;\n\t\ttry {\n\t\t\trestored = await this.createRuntime({\n\t\t\t\tcwd: previous.services.cwd,\n\t\t\t\tagentDir: previous.services.agentDir,\n\t\t\t\tsessionManager: previous.session.sessionManager,\n\t\t\t\tsessionStartEvent: {\n\t\t\t\t\ttype: \"session_start\",\n\t\t\t\t\treason: \"resume\",\n\t\t\t\t\tpreviousSessionFile: failed.session.sessionFile,\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis.apply(restored);\n\t\t\tif (this.rebindSession) await this.rebindSession(this.session);\n\t\t\tfor (const resource of this.sessionResources) await resource.start(this.session);\n\t\t} catch (recoveryError: unknown) {\n\t\t\tif (restored) {\n\t\t\t\tcleanupErrors.push(\n\t\t\t\t\t...(await this.shutdownRuntime(restored.session, \"resume\", failed.session.sessionFile, {\n\t\t\t\t\t\tstopResources: true,\n\t\t\t\t\t\tinvalidateHost: true,\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.apply(previous);\n\t\t\treturn cleanupErrors.length > 0\n\t\t\t\t? new AggregateError([...cleanupErrors, recoveryError], \"Session rollback and cleanup failed.\")\n\t\t\t\t: recoveryError;\n\t\t}\n\n\t\treturn cleanupErrors.length > 0\n\t\t\t? new AggregateError(\n\t\t\t\t\tcleanupErrors,\n\t\t\t\t\t\"The previous session was restored, but failed replacement cleanup was incomplete.\",\n\t\t\t\t)\n\t\t\t: undefined;\n\t}\n\n\tprivate async shutdownRuntime(\n\t\tsession: AgentSession,\n\t\treason: SessionShutdownEvent[\"reason\"],\n\t\ttargetSessionFile: string | undefined,\n\t\toptions: { stopResources: boolean; invalidateHost: boolean; progress?: RuntimeShutdownProgress },\n\t): Promise<unknown[]> {\n\t\tconst errors: unknown[] = [];\n\t\tconst progress =\n\t\t\toptions.progress ??\n\t\t\t({\n\t\t\t\tshutdownEventEmitted: false,\n\t\t\t\tstoppedResources: new Set(),\n\t\t\t\thostInvalidated: false,\n\t\t\t\tsessionDisposed: false,\n\t\t\t} satisfies RuntimeShutdownProgress);\n\t\tif (!progress.shutdownEventEmitted) {\n\t\t\ttry {\n\t\t\t\tawait emitSessionShutdownEvent(session.extensionRunner, {\n\t\t\t\t\ttype: \"session_shutdown\",\n\t\t\t\t\treason,\n\t\t\t\t\ttargetSessionFile,\n\t\t\t\t});\n\t\t\t\tprogress.shutdownEventEmitted = true;\n\t\t\t} catch (error: unknown) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t}\n\t\tif (options.stopResources) {\n\t\t\tfor (const resource of this.sessionResources) {\n\t\t\t\tif (progress.stoppedResources.has(resource)) continue;\n\t\t\t\ttry {\n\t\t\t\t\tawait resource.stop();\n\t\t\t\t\tprogress.stoppedResources.add(resource);\n\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\terrors.push(error);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (options.invalidateHost && !progress.hostInvalidated) {\n\t\t\ttry {\n\t\t\t\tthis.beforeSessionInvalidate?.();\n\t\t\t\tprogress.hostInvalidated = true;\n\t\t\t} catch (error: unknown) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t}\n\t\tif (!progress.sessionDisposed) {\n\t\t\ttry {\n\t\t\t\tawait session.disposeAndWait();\n\t\t\t\tprogress.sessionDisposed = true;\n\t\t\t} catch (error: unknown) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t}\n\t\treturn errors;\n\t}\n\n\tprivate runSessionReplacement<T>(operation: () => Promise<T>): Promise<T> {\n\t\tif (this._disposeStarted) {\n\t\t\treturn Promise.reject(new Error(\"The session runtime has already been disposed.\"));\n\t\t}\n\t\tif (this._replacementInFlight) {\n\t\t\treturn Promise.reject(new Error(\"A session replacement is already in progress.\"));\n\t\t}\n\t\tconst replacement = Promise.resolve().then(operation);\n\t\tthis._replacementInFlight = replacement;\n\t\treturn replacement.finally(() => {\n\t\t\tif (this._replacementInFlight === replacement) this._replacementInFlight = undefined;\n\t\t});\n\t}\n\n\tasync switchSession(sessionPath: string, options?: AgentSessionSwitchOptions): Promise<{ cancelled: boolean }> {\n\t\treturn this.runSessionReplacement(() => this.switchSessionUnserialized(sessionPath, options));\n\t}\n\n\tprivate async switchSessionUnserialized(\n\t\tsessionPath: string,\n\t\toptions?: AgentSessionSwitchOptions,\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, this.services.agentDir, undefined, options?.cwdOverride);\n\t\tassertSessionCwdExists(sessionManager, this.cwd);\n\t\tconst prepared = await this.prepareReplacement(sessionManager, {\n\t\t\ttype: \"session_start\",\n\t\t\treason: \"resume\",\n\t\t\tpreviousSessionFile,\n\t\t});\n\t\tawait this.commitReplacement(prepared, {\n\t\t\treason: \"resume\",\n\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\tbeforeSessionResourcesStart: options?.beforeSessionResourcesStart,\n\t\t\twithSession: options?.withSession,\n\t\t});\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\treturn this.runSessionReplacement(() => this.newSessionUnserialized(options));\n\t}\n\n\tprivate async newSessionUnserialized(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, this.services.agentDir, sessionDir);\n\t\tif (options?.parentSession) {\n\t\t\tsessionManager.newSession({ parentSession: options.parentSession });\n\t\t}\n\n\t\tlet prepared: CreateAgentSessionRuntimeResult;\n\t\ttry {\n\t\t\tprepared = await this.prepareReplacement(sessionManager, {\n\t\t\t\ttype: \"session_start\",\n\t\t\t\treason: \"new\",\n\t\t\t\tpreviousSessionFile,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis.removeCreatedSessionFile(sessionManager.getSessionFile());\n\t\t\tthrow error;\n\t\t}\n\t\tif (options?.setup) {\n\t\t\ttry {\n\t\t\t\tawait options.setup(prepared.session.sessionManager);\n\t\t\t\tprepared.session.agent.state.messages = prepared.session.sessionManager.buildSessionContext().messages;\n\t\t\t} catch (error) {\n\t\t\t\tawait this.discardPrepared(prepared);\n\t\t\t\tthis.removeCreatedSessionFile(sessionManager.getSessionFile());\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\tawait this.commitReplacement(prepared, {\n\t\t\treason: \"new\",\n\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\twithSession: options?.withSession,\n\t\t\tonDiscard: () => this.removeCreatedSessionFile(sessionManager.getSessionFile()),\n\t\t});\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\treturn this.runSessionReplacement(() => this.forkUnserialized(entryId, options));\n\t}\n\n\tprivate async forkUnserialized(\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, this.services.agentDir, sessionDir);\n\t\t\t\tsessionManager.newSession({ parentSession: currentSessionFile });\n\t\t\t\tlet prepared: CreateAgentSessionRuntimeResult;\n\t\t\t\ttry {\n\t\t\t\t\tprepared = await this.prepareReplacement(sessionManager, {\n\t\t\t\t\t\ttype: \"session_start\",\n\t\t\t\t\t\treason: \"fork\",\n\t\t\t\t\t\tpreviousSessionFile,\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.removeCreatedSessionFile(sessionManager.getSessionFile());\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tawait this.commitReplacement(prepared, {\n\t\t\t\t\treason: \"fork\",\n\t\t\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\t\t\twithSession: options?.withSession,\n\t\t\t\t\tonDiscard: () => this.removeCreatedSessionFile(sessionManager.getSessionFile()),\n\t\t\t\t});\n\t\t\t\treturn { cancelled: false, selectedText };\n\t\t\t}\n\t\t\tif (!existsSync(currentSessionFile)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"This session has not been saved yet. Wait for the first assistant response before cloning or forking it.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst sourceSessionManager = SessionManager.open(currentSessionFile, this.services.agentDir, sessionDir);\n\t\t\tconst sessionManager = sourceSessionManager.createBranchedSessionManager(targetLeafId);\n\t\t\tconst forkedSessionPath = sessionManager.getSessionFile();\n\t\t\tif (!forkedSessionPath) {\n\t\t\t\tthrow new Error(\"Failed to create forked session\");\n\t\t\t}\n\t\t\tlet prepared: CreateAgentSessionRuntimeResult;\n\t\t\ttry {\n\t\t\t\tprepared = await this.prepareReplacement(sessionManager, {\n\t\t\t\t\ttype: \"session_start\",\n\t\t\t\t\treason: \"fork\",\n\t\t\t\t\tpreviousSessionFile,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tthis.removeCreatedSessionFile(forkedSessionPath);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tawait this.commitReplacement(prepared, {\n\t\t\t\treason: \"fork\",\n\t\t\t\ttargetSessionFile: forkedSessionPath,\n\t\t\t\twithSession: options?.withSession,\n\t\t\t\tonDiscard: () => this.removeCreatedSessionFile(forkedSessionPath),\n\t\t\t});\n\t\t\treturn { cancelled: false, selectedText };\n\t\t}\n\n\t\tlet sessionManager: SessionManager;\n\t\tif (!targetLeafId) {\n\t\t\tsessionManager = SessionManager.inMemory(this.cwd);\n\t\t\tsessionManager.newSession({ parentSession: this.session.sessionFile });\n\t\t} else {\n\t\t\tsessionManager = this.session.sessionManager.createBranchedSessionManager(targetLeafId);\n\t\t}\n\t\tconst prepared = await this.prepareReplacement(sessionManager, {\n\t\t\ttype: \"session_start\",\n\t\t\treason: \"fork\",\n\t\t\tpreviousSessionFile,\n\t\t});\n\t\tawait this.commitReplacement(prepared, {\n\t\t\treason: \"fork\",\n\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\twithSession: options?.withSession,\n\t\t});\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\treturn this.runSessionReplacement(() => this.importFromJsonlUnserialized(inputPath, cwdOverride));\n\t}\n\n\tprivate async importFromJsonlUnserialized(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\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\tlet copied = false;\n\t\tif (resolve(destinationPath) !== resolvedPath) {\n\t\t\tif (!existsSync(sessionDir)) mkdirSync(sessionDir, { recursive: true });\n\t\t\tcopyFileSync(resolvedPath, destinationPath, fsConstants.COPYFILE_EXCL);\n\t\t\tcopied = true;\n\t\t}\n\n\t\tlet sessionManager: SessionManager;\n\t\tlet prepared: CreateAgentSessionRuntimeResult;\n\t\ttry {\n\t\t\tsessionManager = SessionManager.open(destinationPath, this.services.agentDir, sessionDir, cwdOverride);\n\t\t\tassertSessionCwdExists(sessionManager, this.cwd);\n\t\t\tprepared = await this.prepareReplacement(sessionManager, {\n\t\t\t\ttype: \"session_start\",\n\t\t\t\treason: \"resume\",\n\t\t\t\tpreviousSessionFile,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (copied) this.removeCreatedSessionFile(destinationPath);\n\t\t\tthrow error;\n\t\t}\n\t\tawait this.commitReplacement(prepared, {\n\t\t\treason: \"resume\",\n\t\t\ttargetSessionFile: sessionManager.getSessionFile(),\n\t\t\tonDiscard: copied ? () => this.removeCreatedSessionFile(destinationPath) : undefined,\n\t\t});\n\t\treturn { cancelled: false };\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tif (this._disposeInFlight) return this._disposeInFlight;\n\t\tif (this._disposed) return;\n\t\tthis._disposeStarted = true;\n\t\tconst replacement = this._replacementInFlight;\n\t\tconst disposal = (async () => {\n\t\t\tif (replacement) {\n\t\t\t\ttry {\n\t\t\t\t\tawait replacement;\n\t\t\t\t} catch {\n\t\t\t\t\t// Replacement already reports its own error; dispose whichever runtime it left active.\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst errors = await this.shutdownRuntime(this.session, \"quit\", undefined, {\n\t\t\t\tstopResources: true,\n\t\t\t\tinvalidateHost: true,\n\t\t\t\tprogress: this.disposeProgress,\n\t\t\t});\n\t\t\tif (errors.length === 1) throw errors[0];\n\t\t\tif (errors.length > 1) throw new AggregateError(errors, \"Session runtime disposal failed.\");\n\t\t\tthis._disposed = true;\n\t\t})();\n\t\tthis._disposeInFlight = disposal;\n\t\ttry {\n\t\t\tawait disposal;\n\t\t} finally {\n\t\t\tthis._disposeInFlight = undefined;\n\t\t}\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"]}