@code-yeongyu/senpi 2026.8.28 → 2026.8.30-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (380) hide show
  1. package/CHANGELOG.md +196 -0
  2. package/dist/cli/args.d.ts +2 -0
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +4 -0
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/core/agent-session-services.d.ts.map +1 -1
  7. package/dist/core/agent-session-services.js +2 -0
  8. package/dist/core/agent-session-services.js.map +1 -1
  9. package/dist/core/agent-session.d.ts +50 -1
  10. package/dist/core/agent-session.d.ts.map +1 -1
  11. package/dist/core/agent-session.js +330 -29
  12. package/dist/core/agent-session.js.map +1 -1
  13. package/dist/core/auth-storage.d.ts +1 -0
  14. package/dist/core/auth-storage.d.ts.map +1 -1
  15. package/dist/core/auth-storage.js +3 -0
  16. package/dist/core/auth-storage.js.map +1 -1
  17. package/dist/core/bash-executor.d.ts.map +1 -1
  18. package/dist/core/bash-executor.js +155 -37
  19. package/dist/core/bash-executor.js.map +1 -1
  20. package/dist/core/compaction/compaction-execution.d.ts +14 -0
  21. package/dist/core/compaction/compaction-execution.d.ts.map +1 -0
  22. package/dist/core/compaction/compaction-execution.js +121 -0
  23. package/dist/core/compaction/compaction-execution.js.map +1 -0
  24. package/dist/core/compaction/compaction-settings.d.ts +17 -0
  25. package/dist/core/compaction/compaction-settings.d.ts.map +1 -0
  26. package/dist/core/compaction/compaction-settings.js +17 -0
  27. package/dist/core/compaction/compaction-settings.js.map +1 -0
  28. package/dist/core/compaction/compaction.d.ts +13 -26
  29. package/dist/core/compaction/compaction.d.ts.map +1 -1
  30. package/dist/core/compaction/compaction.js +7 -136
  31. package/dist/core/compaction/compaction.js.map +1 -1
  32. package/dist/core/compaction/ideal-compaction-settings.d.ts +9 -0
  33. package/dist/core/compaction/ideal-compaction-settings.d.ts.map +1 -0
  34. package/dist/core/compaction/ideal-compaction-settings.js +7 -0
  35. package/dist/core/compaction/ideal-compaction-settings.js.map +1 -0
  36. package/dist/core/compaction-settings-access.d.ts +19 -0
  37. package/dist/core/compaction-settings-access.d.ts.map +1 -0
  38. package/dist/core/compaction-settings-access.js +10 -0
  39. package/dist/core/compaction-settings-access.js.map +1 -0
  40. package/dist/core/compaction-settings-resolver.d.ts +22 -0
  41. package/dist/core/compaction-settings-resolver.d.ts.map +1 -0
  42. package/dist/core/compaction-settings-resolver.js +46 -0
  43. package/dist/core/compaction-settings-resolver.js.map +1 -0
  44. package/dist/core/credential-accounts.d.ts.map +1 -1
  45. package/dist/core/credential-accounts.js +45 -21
  46. package/dist/core/credential-accounts.js.map +1 -1
  47. package/dist/core/credential-pool/classify.d.ts +6 -1
  48. package/dist/core/credential-pool/classify.d.ts.map +1 -1
  49. package/dist/core/credential-pool/classify.js +22 -5
  50. package/dist/core/credential-pool/classify.js.map +1 -1
  51. package/dist/core/credential-pool/env-slots.d.ts.map +1 -1
  52. package/dist/core/credential-pool/env-slots.js +2 -0
  53. package/dist/core/credential-pool/env-slots.js.map +1 -1
  54. package/dist/core/credential-pool/failover.d.ts +8 -0
  55. package/dist/core/credential-pool/failover.d.ts.map +1 -1
  56. package/dist/core/credential-pool/failover.js +24 -6
  57. package/dist/core/credential-pool/failover.js.map +1 -1
  58. package/dist/core/credential-pool/rotation-stream.d.ts +13 -2
  59. package/dist/core/credential-pool/rotation-stream.d.ts.map +1 -1
  60. package/dist/core/credential-pool/rotation-stream.js +97 -10
  61. package/dist/core/credential-pool/rotation-stream.js.map +1 -1
  62. package/dist/core/extensions/builtin/compaction/context-pipeline.d.ts +17 -0
  63. package/dist/core/extensions/builtin/compaction/context-pipeline.d.ts.map +1 -0
  64. package/dist/core/extensions/builtin/compaction/context-pipeline.js +28 -0
  65. package/dist/core/extensions/builtin/compaction/context-pipeline.js.map +1 -0
  66. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +8 -2
  67. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
  68. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +163 -48
  69. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
  70. package/dist/core/extensions/builtin/compaction/emergency-prune.d.ts +17 -0
  71. package/dist/core/extensions/builtin/compaction/emergency-prune.d.ts.map +1 -0
  72. package/dist/core/extensions/builtin/compaction/emergency-prune.js +64 -0
  73. package/dist/core/extensions/builtin/compaction/emergency-prune.js.map +1 -0
  74. package/dist/core/extensions/builtin/compaction/extension-wiring.d.ts +27 -0
  75. package/dist/core/extensions/builtin/compaction/extension-wiring.d.ts.map +1 -0
  76. package/dist/core/extensions/builtin/compaction/extension-wiring.js +84 -0
  77. package/dist/core/extensions/builtin/compaction/extension-wiring.js.map +1 -0
  78. package/dist/core/extensions/builtin/compaction/idle.d.ts +1 -0
  79. package/dist/core/extensions/builtin/compaction/idle.d.ts.map +1 -1
  80. package/dist/core/extensions/builtin/compaction/idle.js +13 -2
  81. package/dist/core/extensions/builtin/compaction/idle.js.map +1 -1
  82. package/dist/core/extensions/builtin/compaction/index.d.ts +1 -1
  83. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  84. package/dist/core/extensions/builtin/compaction/index.js +121 -147
  85. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  86. package/dist/core/extensions/builtin/compaction/log.d.ts +1 -1
  87. package/dist/core/extensions/builtin/compaction/log.d.ts.map +1 -1
  88. package/dist/core/extensions/builtin/compaction/log.js +2 -0
  89. package/dist/core/extensions/builtin/compaction/log.js.map +1 -1
  90. package/dist/core/extensions/builtin/compaction/model-selection.d.ts +14 -0
  91. package/dist/core/extensions/builtin/compaction/model-selection.d.ts.map +1 -0
  92. package/dist/core/extensions/builtin/compaction/model-selection.js +37 -0
  93. package/dist/core/extensions/builtin/compaction/model-selection.js.map +1 -0
  94. package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.d.ts +9 -0
  95. package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.d.ts.map +1 -0
  96. package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.js +2 -0
  97. package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.js.map +1 -0
  98. package/dist/core/extensions/builtin/compaction/openai-remote.d.ts +3 -6
  99. package/dist/core/extensions/builtin/compaction/openai-remote.d.ts.map +1 -1
  100. package/dist/core/extensions/builtin/compaction/openai-remote.js.map +1 -1
  101. package/dist/core/extensions/builtin/compaction/orchestration.d.ts +56 -0
  102. package/dist/core/extensions/builtin/compaction/orchestration.d.ts.map +1 -0
  103. package/dist/core/extensions/builtin/compaction/orchestration.js +136 -0
  104. package/dist/core/extensions/builtin/compaction/orchestration.js.map +1 -0
  105. package/dist/core/extensions/builtin/compaction/policy.d.ts +5 -2
  106. package/dist/core/extensions/builtin/compaction/policy.d.ts.map +1 -1
  107. package/dist/core/extensions/builtin/compaction/policy.js +43 -26
  108. package/dist/core/extensions/builtin/compaction/policy.js.map +1 -1
  109. package/dist/core/extensions/builtin/compaction/retained-message-safety.d.ts.map +1 -1
  110. package/dist/core/extensions/builtin/compaction/retained-message-safety.js +31 -8
  111. package/dist/core/extensions/builtin/compaction/retained-message-safety.js.map +1 -1
  112. package/dist/core/extensions/builtin/compaction/speculation-lead.d.ts +8 -0
  113. package/dist/core/extensions/builtin/compaction/speculation-lead.d.ts.map +1 -0
  114. package/dist/core/extensions/builtin/compaction/speculation-lead.js +17 -0
  115. package/dist/core/extensions/builtin/compaction/speculation-lead.js.map +1 -0
  116. package/dist/core/extensions/builtin/compaction/speculative-job.d.ts +22 -0
  117. package/dist/core/extensions/builtin/compaction/speculative-job.d.ts.map +1 -0
  118. package/dist/core/extensions/builtin/compaction/speculative-job.js +16 -0
  119. package/dist/core/extensions/builtin/compaction/speculative-job.js.map +1 -0
  120. package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts +22 -0
  121. package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts.map +1 -0
  122. package/dist/core/extensions/builtin/compaction/speculative-summary.js +131 -0
  123. package/dist/core/extensions/builtin/compaction/speculative-summary.js.map +1 -0
  124. package/dist/core/extensions/builtin/compaction/speculative.d.ts +8 -13
  125. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  126. package/dist/core/extensions/builtin/compaction/speculative.js +7 -196
  127. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  128. package/dist/core/extensions/builtin/compaction/token-budget-reminder.d.ts +18 -0
  129. package/dist/core/extensions/builtin/compaction/token-budget-reminder.d.ts.map +1 -0
  130. package/dist/core/extensions/builtin/compaction/token-budget-reminder.js +18 -0
  131. package/dist/core/extensions/builtin/compaction/token-budget-reminder.js.map +1 -0
  132. package/dist/core/extensions/builtin/compaction/tool-admission.d.ts +36 -0
  133. package/dist/core/extensions/builtin/compaction/tool-admission.d.ts.map +1 -0
  134. package/dist/core/extensions/builtin/compaction/tool-admission.js +92 -0
  135. package/dist/core/extensions/builtin/compaction/tool-admission.js.map +1 -0
  136. package/dist/core/extensions/builtin/cursor-cli-oauth/stream.d.ts.map +1 -1
  137. package/dist/core/extensions/builtin/cursor-cli-oauth/stream.js +8 -28
  138. package/dist/core/extensions/builtin/cursor-cli-oauth/stream.js.map +1 -1
  139. package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
  140. package/dist/core/extensions/builtin/goal/index.js +7 -0
  141. package/dist/core/extensions/builtin/goal/index.js.map +1 -1
  142. package/dist/core/extensions/builtin/permission-system/external-dir.d.ts.map +1 -1
  143. package/dist/core/extensions/builtin/permission-system/external-dir.js +15 -5
  144. package/dist/core/extensions/builtin/permission-system/external-dir.js.map +1 -1
  145. package/dist/core/extensions/builtin/permission-system/parsers.d.ts.map +1 -1
  146. package/dist/core/extensions/builtin/permission-system/parsers.js +16 -1
  147. package/dist/core/extensions/builtin/permission-system/parsers.js.map +1 -1
  148. package/dist/core/extensions/builtin/service-tier.d.ts.map +1 -1
  149. package/dist/core/extensions/builtin/service-tier.js +13 -0
  150. package/dist/core/extensions/builtin/service-tier.js.map +1 -1
  151. package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
  152. package/dist/core/extensions/builtin/terminal/extension.js +4 -2
  153. package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
  154. package/dist/core/extensions/builtin/terminal/manager.d.ts +5 -0
  155. package/dist/core/extensions/builtin/terminal/manager.d.ts.map +1 -1
  156. package/dist/core/extensions/builtin/terminal/manager.js +31 -3
  157. package/dist/core/extensions/builtin/terminal/manager.js.map +1 -1
  158. package/dist/core/extensions/builtin/terminal/monitor-permission.d.ts +8 -0
  159. package/dist/core/extensions/builtin/terminal/monitor-permission.d.ts.map +1 -0
  160. package/dist/core/extensions/builtin/terminal/monitor-permission.js +16 -0
  161. package/dist/core/extensions/builtin/terminal/monitor-permission.js.map +1 -0
  162. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +13 -0
  163. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -1
  164. package/dist/core/extensions/builtin/terminal/monitor-registry.js +403 -3
  165. package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -1
  166. package/dist/core/extensions/builtin/terminal/session-bundle.d.ts.map +1 -1
  167. package/dist/core/extensions/builtin/terminal/session-bundle.js +1 -0
  168. package/dist/core/extensions/builtin/terminal/session-bundle.js.map +1 -1
  169. package/dist/core/extensions/builtin/terminal/tools/kill-bash.d.ts.map +1 -1
  170. package/dist/core/extensions/builtin/terminal/tools/kill-bash.js +5 -2
  171. package/dist/core/extensions/builtin/terminal/tools/kill-bash.js.map +1 -1
  172. package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts +4 -0
  173. package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts.map +1 -1
  174. package/dist/core/extensions/builtin/terminal/tools/monitor.js +40 -2
  175. package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -1
  176. package/dist/core/model-config-schema.d.ts +4 -4
  177. package/dist/core/model-resolver.js +2 -2
  178. package/dist/core/model-resolver.js.map +1 -1
  179. package/dist/core/model-runtime.d.ts +2 -0
  180. package/dist/core/model-runtime.d.ts.map +1 -1
  181. package/dist/core/model-runtime.js +74 -37
  182. package/dist/core/model-runtime.js.map +1 -1
  183. package/dist/core/retry-fallback/chains.d.ts +23 -1
  184. package/dist/core/retry-fallback/chains.d.ts.map +1 -1
  185. package/dist/core/retry-fallback/chains.js +59 -3
  186. package/dist/core/retry-fallback/chains.js.map +1 -1
  187. package/dist/core/retry-fallback/controller.d.ts.map +1 -1
  188. package/dist/core/retry-fallback/controller.js +9 -2
  189. package/dist/core/retry-fallback/controller.js.map +1 -1
  190. package/dist/core/retry-fallback/settings.d.ts.map +1 -1
  191. package/dist/core/retry-fallback/settings.js +9 -0
  192. package/dist/core/retry-fallback/settings.js.map +1 -1
  193. package/dist/core/retry-fallback/validate.js +1 -1
  194. package/dist/core/retry-fallback/validate.js.map +1 -1
  195. package/dist/core/sdk.js +1 -1
  196. package/dist/core/sdk.js.map +1 -1
  197. package/dist/core/session-manager.d.ts +9 -0
  198. package/dist/core/session-manager.d.ts.map +1 -1
  199. package/dist/core/session-manager.js +40 -0
  200. package/dist/core/session-manager.js.map +1 -1
  201. package/dist/core/settings-manager.d.ts +15 -85
  202. package/dist/core/settings-manager.d.ts.map +1 -1
  203. package/dist/core/settings-manager.js +15 -17
  204. package/dist/core/settings-manager.js.map +1 -1
  205. package/dist/core/settings-public-types.d.ts +11 -0
  206. package/dist/core/settings-public-types.d.ts.map +1 -0
  207. package/dist/core/settings-public-types.js +2 -0
  208. package/dist/core/settings-public-types.js.map +1 -0
  209. package/dist/core/settings-shapes.d.ts +36 -0
  210. package/dist/core/settings-shapes.d.ts.map +1 -0
  211. package/dist/core/settings-shapes.js +2 -0
  212. package/dist/core/settings-shapes.js.map +1 -0
  213. package/dist/core/shared-host-policy.d.ts +6 -0
  214. package/dist/core/shared-host-policy.d.ts.map +1 -0
  215. package/dist/core/shared-host-policy.js +7 -0
  216. package/dist/core/shared-host-policy.js.map +1 -0
  217. package/dist/core/terminal-settings.d.ts +22 -0
  218. package/dist/core/terminal-settings.d.ts.map +1 -0
  219. package/dist/core/terminal-settings.js +2 -0
  220. package/dist/core/terminal-settings.js.map +1 -0
  221. package/dist/core/tools/bash.d.ts.map +1 -1
  222. package/dist/core/tools/bash.js +97 -15
  223. package/dist/core/tools/bash.js.map +1 -1
  224. package/dist/core/tools/index.d.ts +1 -0
  225. package/dist/core/tools/index.d.ts.map +1 -1
  226. package/dist/core/tools/index.js +8 -0
  227. package/dist/core/tools/index.js.map +1 -1
  228. package/dist/core/tools/output-accumulator.d.ts +1 -1
  229. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  230. package/dist/core/tools/output-accumulator.js +76 -34
  231. package/dist/core/tools/output-accumulator.js.map +1 -1
  232. package/dist/main.d.ts +7 -0
  233. package/dist/main.d.ts.map +1 -1
  234. package/dist/main.js +27 -6
  235. package/dist/main.js.map +1 -1
  236. package/dist/modes/interactive/components/favorite-models-selector.d.ts.map +1 -1
  237. package/dist/modes/interactive/components/favorite-models-selector.js +2 -2
  238. package/dist/modes/interactive/components/favorite-models-selector.js.map +1 -1
  239. package/dist/modes/interactive/components/footer.d.ts +7 -0
  240. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  241. package/dist/modes/interactive/components/footer.js +34 -8
  242. package/dist/modes/interactive/components/footer.js.map +1 -1
  243. package/dist/modes/interactive/grok/chrome.d.ts +2 -0
  244. package/dist/modes/interactive/grok/chrome.d.ts.map +1 -1
  245. package/dist/modes/interactive/grok/chrome.js.map +1 -1
  246. package/dist/modes/interactive/interactive-host-runtime.d.ts +121 -1
  247. package/dist/modes/interactive/interactive-host-runtime.d.ts.map +1 -1
  248. package/dist/modes/interactive/interactive-host-runtime.js +606 -45
  249. package/dist/modes/interactive/interactive-host-runtime.js.map +1 -1
  250. package/dist/modes/interactive/interactive-mode.d.ts +7 -0
  251. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  252. package/dist/modes/interactive/interactive-mode.js +390 -239
  253. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  254. package/dist/modes/rpc/connection-handler.d.ts +8 -1
  255. package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
  256. package/dist/modes/rpc/connection-handler.js +268 -63
  257. package/dist/modes/rpc/connection-handler.js.map +1 -1
  258. package/dist/modes/rpc/host-ensure.d.ts +19 -0
  259. package/dist/modes/rpc/host-ensure.d.ts.map +1 -1
  260. package/dist/modes/rpc/host-ensure.js +79 -15
  261. package/dist/modes/rpc/host-ensure.js.map +1 -1
  262. package/dist/modes/rpc/host-lifecycle.d.ts +29 -0
  263. package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
  264. package/dist/modes/rpc/host-lifecycle.js +96 -25
  265. package/dist/modes/rpc/host-lifecycle.js.map +1 -1
  266. package/dist/modes/rpc/host-watchdog.d.ts +2 -0
  267. package/dist/modes/rpc/host-watchdog.d.ts.map +1 -1
  268. package/dist/modes/rpc/host-watchdog.js +23 -12
  269. package/dist/modes/rpc/host-watchdog.js.map +1 -1
  270. package/dist/modes/rpc/multi-session-host.js +20 -8
  271. package/dist/modes/rpc/multi-session-host.js.map +1 -1
  272. package/dist/modes/rpc/rpc-client.d.ts +91 -16
  273. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  274. package/dist/modes/rpc/rpc-client.js +131 -37
  275. package/dist/modes/rpc/rpc-client.js.map +1 -1
  276. package/dist/modes/rpc/rpc-input-validation.d.ts +1 -0
  277. package/dist/modes/rpc/rpc-input-validation.d.ts.map +1 -1
  278. package/dist/modes/rpc/rpc-input-validation.js +66 -0
  279. package/dist/modes/rpc/rpc-input-validation.js.map +1 -1
  280. package/dist/modes/rpc/rpc-mode.d.ts +3 -1
  281. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  282. package/dist/modes/rpc/rpc-mode.js +3 -1
  283. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  284. package/dist/modes/rpc/rpc-types.d.ts +248 -3
  285. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  286. package/dist/modes/rpc/rpc-types.js.map +1 -1
  287. package/dist/modes/rpc/session-binding.d.ts +1 -0
  288. package/dist/modes/rpc/session-binding.d.ts.map +1 -1
  289. package/dist/modes/rpc/session-binding.js +21 -1
  290. package/dist/modes/rpc/session-binding.js.map +1 -1
  291. package/dist/modes/rpc/session-command-router.d.ts +22 -0
  292. package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
  293. package/dist/modes/rpc/session-command-router.js +148 -16
  294. package/dist/modes/rpc/session-command-router.js.map +1 -1
  295. package/dist/modes/rpc/session-event-writer.d.ts +4 -0
  296. package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
  297. package/dist/modes/rpc/session-event-writer.js +58 -7
  298. package/dist/modes/rpc/session-event-writer.js.map +1 -1
  299. package/dist/modes/rpc/session-extension-ui-requests.d.ts +1 -0
  300. package/dist/modes/rpc/session-extension-ui-requests.d.ts.map +1 -1
  301. package/dist/modes/rpc/session-extension-ui-requests.js +5 -0
  302. package/dist/modes/rpc/session-extension-ui-requests.js.map +1 -1
  303. package/dist/modes/rpc/session-registry.d.ts +17 -2
  304. package/dist/modes/rpc/session-registry.d.ts.map +1 -1
  305. package/dist/modes/rpc/session-registry.js +67 -4
  306. package/dist/modes/rpc/session-registry.js.map +1 -1
  307. package/dist/modes/rpc/socket-event-fanout.d.ts +22 -0
  308. package/dist/modes/rpc/socket-event-fanout.d.ts.map +1 -0
  309. package/dist/modes/rpc/socket-event-fanout.js +84 -0
  310. package/dist/modes/rpc/socket-event-fanout.js.map +1 -0
  311. package/docs/rpc.md +55 -2
  312. package/docs/settings.md +34 -0
  313. package/docs/windows.md +2 -0
  314. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +74 -0
  315. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  316. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-indirect-eval.js +139 -90
  317. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +4 -4
  318. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  319. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +6 -3
  320. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  321. package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  322. package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.js +40 -20
  323. package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  324. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts +3 -3
  325. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts.map +1 -1
  326. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.js.map +1 -1
  327. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/shell-output.d.ts +1 -1
  328. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/shell-output.d.ts.map +1 -1
  329. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/shell-output.js +28 -9
  330. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/shell-output.js.map +1 -1
  331. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  332. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  333. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +67 -38
  334. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  335. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.d.ts +20 -0
  336. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.d.ts.map +1 -0
  337. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.js +443 -0
  338. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.js.map +1 -0
  339. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts +2 -0
  340. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts.map +1 -1
  341. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js +2 -0
  342. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js.map +1 -1
  343. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +1 -1
  344. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  345. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +1 -0
  346. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
  347. package/node_modules/@earendil-works/pi-ai/dist/index.js +1 -0
  348. package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
  349. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  350. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  351. package/node_modules/@earendil-works/pi-ai/dist/providers/data/baseten.json +1 -1
  352. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  353. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-workers-ai.json +1 -1
  354. package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
  355. package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
  356. package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
  357. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  358. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  359. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  360. package/node_modules/@earendil-works/pi-ai/dist/providers/data/together.json +1 -1
  361. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  362. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai-coding-cn.json +1 -1
  363. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai.json +1 -1
  364. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  365. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  366. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  367. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +7 -0
  368. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
  369. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +5 -0
  370. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
  371. package/node_modules/@earendil-works/pi-tui/dist/mux.d.ts +1 -1
  372. package/node_modules/@earendil-works/pi-tui/dist/mux.d.ts.map +1 -1
  373. package/node_modules/@earendil-works/pi-tui/dist/mux.js +2 -2
  374. package/node_modules/@earendil-works/pi-tui/dist/mux.js.map +1 -1
  375. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +1 -0
  376. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
  377. package/node_modules/@earendil-works/pi-tui/dist/terminal.js +19 -0
  378. package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
  379. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  380. package/package.json +7 -7
@@ -14,6 +14,7 @@
14
14
  * go to `sink.writeRaw` instead of `writeRawStdout`, and the caller decides how
15
15
  * (and whether) to end the process.
16
16
  */
17
+ import type { AgentAbortSource } from "../../core/agent-abort-provenance.ts";
17
18
  import type { AgentSession } from "../../core/agent-session.ts";
18
19
  import type { AgentSessionRuntime } from "../../core/agent-session-runtime.ts";
19
20
  import type { RpcSessionState } from "./rpc-types.ts";
@@ -50,6 +51,8 @@ export interface RpcConnectionHandler {
50
51
  * host polls this after each command and decides how to tear down.
51
52
  */
52
53
  isShutdownRequested(): boolean;
54
+ /** Cancel UI requests that can no longer be answered by this connection. */
55
+ cancelPendingExtensionUiRequests(): void;
53
56
  /** Tear down subscriptions and dispose the runtime. Never calls process.exit. */
54
57
  dispose(): Promise<void>;
55
58
  }
@@ -59,8 +62,12 @@ export interface RpcConnectionHandler {
59
62
  * Shared with `open_session` (session-command-router) so both surfaces answer with the SAME
60
63
  * fields: a second hand-rolled literal silently drifts, which is how `serviceTier`/`fastMode`
61
64
  * would otherwise be missing from an opened session's initial state.
65
+ *
66
+ * `lastAbortSource` is passed in rather than read from the session: `session.currentAbortSource`
67
+ * is cleared once the turn settles, so only the caller that observed `agent_end` still knows
68
+ * who owned the abort.
62
69
  */
63
- export declare function buildRpcSessionState(session: AgentSession): RpcSessionState;
70
+ export declare function buildRpcSessionState(session: AgentSession, lastAbortSource?: AgentAbortSource): RpcSessionState;
64
71
  /**
65
72
  * Create a per-connection RPC handler bound to one runtime host and one sink.
66
73
  *
@@ -1 +1 @@
1
- {"version":3,"file":"connection-handler.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/connection-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAqB,MAAM,6BAA6B,CAAC;AACnF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAwC/E,OAAO,KAAK,EAWX,eAAe,EAEf,MAAM,gBAAgB,CAAC;AAGxB,kFAAkF;AAClF,MAAM,WAAW,oBAAoB;IACpC,mFAAmF;IACnF,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,iFAAiF;IACjF,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,0DAA0D;IAC1D,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,oBAAoB;IACpC;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,sEAAsE;IACtE,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C;;;OAGG;IACH,mBAAmB,IAAI,OAAO,CAAC;IAC/B,iFAAiF;IACjF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AA4BD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,GAAG,eAAe,CAiB3E;AA4BD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACzC,WAAW,EAAE,mBAAmB,EAChC,IAAI,EAAE,iBAAiB,EACvB,OAAO,GAAE,oBAAyB,GAChC,oBAAoB,CAyiCtB"}
1
+ {"version":3,"file":"connection-handler.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/connection-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAqB,MAAM,6BAA6B,CAAC;AACnF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAyC/E,OAAO,KAAK,EAYX,eAAe,EAEf,MAAM,gBAAgB,CAAC;AAGxB,kFAAkF;AAClF,MAAM,WAAW,oBAAoB;IACpC,mFAAmF;IACnF,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,iFAAiF;IACjF,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,0DAA0D;IAC1D,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,oBAAoB;IACpC;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,sEAAsE;IACtE,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C;;;OAGG;IACH,mBAAmB,IAAI,OAAO,CAAC;IAC/B,4EAA4E;IAC5E,gCAAgC,IAAI,IAAI,CAAC;IACzC,iFAAiF;IACjF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AA4BD;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,eAAe,CAAC,EAAE,gBAAgB,GAAG,eAAe,CAkD/G;AA4BD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACzC,WAAW,EAAE,mBAAmB,EAChC,IAAI,EAAE,iBAAiB,EACvB,OAAO,GAAE,oBAAyB,GAChC,oBAAoB,CA4uCtB"}
@@ -15,6 +15,7 @@
15
15
  * (and whether) to end the process.
16
16
  */
17
17
  import * as crypto from "node:crypto";
18
+ import { existsSync } from "node:fs";
18
19
  import { basename, dirname, extname } from "node:path";
19
20
  import { VERSION } from "../../config.js";
20
21
  import { buildLoginProviderInfos } from "../../core/auth-providers.js";
@@ -24,11 +25,12 @@ import { CLAUDE_SDK_OAUTH_PROVIDER_ID } from "../../core/extensions/builtin/clau
24
25
  import { isMcpControlInventoryChanged, MCP_CONTROL_INVENTORY_CHANGED_EVENT, MCP_CONTROL_INVENTORY_REQUEST_EVENT, } from "../../core/extensions/builtin/mcp/control-inventory.js";
25
26
  import { applyFastMode, resolveServiceTierMemoryModel, } from "../../core/extensions/builtin/service-tier.js";
26
27
  import { getSupportedThinkingLevels } from "../../core/thinking-levels.js";
28
+ import { ProjectTrustStore } from "../../core/trust-manager.js";
27
29
  import { theme } from "../interactive/theme/theme.js";
28
30
  import { buildCustomUnsupportedRequest, DEFAULT_CUSTOM_EXTENSION_LABEL, EXTENSION_EVENTS_CAPABILITY, } from "./custom-capability.js";
29
31
  import { createRpcEventOutputBuffer } from "./event-output-buffer.js";
30
32
  import { buildRpcCommandsForSession, createCommandsChangedEvent, rpcCommandListDigest } from "./rpc-command-surface.js";
31
- import { rpcCommandShapeError, rpcMessageLengthError } from "./rpc-input-validation.js";
33
+ import { rpcCommandPayloadError, rpcCommandShapeError, rpcMessageLengthError } from "./rpc-input-validation.js";
32
34
  import { SessionExtensionUiRequests } from "./session-extension-ui-requests.js";
33
35
  function loadedExtensionName(path) {
34
36
  const synthetic = /^<(?:builtin|inline):([^>]+)>$/.exec(path);
@@ -64,23 +66,56 @@ function loadedMcpStatus(server) {
64
66
  * Shared with `open_session` (session-command-router) so both surfaces answer with the SAME
65
67
  * fields: a second hand-rolled literal silently drifts, which is how `serviceTier`/`fastMode`
66
68
  * would otherwise be missing from an opened session's initial state.
69
+ *
70
+ * `lastAbortSource` is passed in rather than read from the session: `session.currentAbortSource`
71
+ * is cleared once the turn settles, so only the caller that observed `agent_end` still knows
72
+ * who owned the abort.
67
73
  */
68
- export function buildRpcSessionState(session) {
74
+ export function buildRpcSessionState(session, lastAbortSource) {
75
+ const cwd = session.sessionManager.getCwd();
76
+ // Trust gates project-source settings (shell prefixes, project resources), so every
77
+ // session state projection must have an authoritative store to consult.
78
+ if (!session.agentDir) {
79
+ throw new Error("RPC session invariant violated: agentDir is required");
80
+ }
81
+ const projectTrusted = new ProjectTrustStore(session.agentDir).get(cwd) === true;
69
82
  return {
70
83
  model: session.model,
71
84
  thinkingLevel: session.thinkingLevel,
85
+ ...(session.thinkingSelection ? { thinkingSelection: session.thinkingSelection } : {}),
86
+ ...(lastAbortSource ? { lastAbortSource } : {}),
72
87
  serviceTier: session.effectiveServiceTier,
73
88
  fastMode: session.isFastModeActive(),
74
89
  isStreaming: session.isStreaming,
75
90
  isCompacting: session.isCompacting,
91
+ retryAttempt: session.retryAttempt,
92
+ isBashRunning: session.isBashRunning,
76
93
  steeringMode: session.steeringMode,
77
94
  followUpMode: session.followUpMode,
78
95
  sessionFile: session.sessionFile,
79
96
  sessionId: session.sessionId,
80
97
  sessionName: session.sessionName,
98
+ cwd,
99
+ projectTrusted,
100
+ ...(session.sessionFile &&
101
+ !existsSync(session.sessionFile) &&
102
+ session.sessionManager
103
+ .getEntries()
104
+ .some((entry) => entry.type !== "model_change" && entry.type !== "thinking_level_change")
105
+ ? { entries: session.sessionManager.getEntries() }
106
+ : {}),
107
+ steering: typeof session.getSteeringMessages === "function" ? [...session.getSteeringMessages()] : [],
108
+ followUp: typeof session.getFollowUpMessages === "function" ? [...session.getFollowUpMessages()] : [],
109
+ ordered: [
110
+ ...(session._queuedInputOrder ?? []),
111
+ ].sort((a, b) => a.enqueueOrder - b.enqueueOrder),
81
112
  autoCompactionEnabled: session.autoCompactionEnabled,
82
113
  messageCount: session.messages.length,
83
114
  pendingMessageCount: session.pendingMessageCount,
115
+ usageTotals: session.sessionManager.getUsageTotals(),
116
+ contextUsage: typeof session.getContextUsage === "function" ? session.getContextUsage() : undefined,
117
+ favoriteModels: session.favoriteModels?.map((entry) => ({ ...entry })) ?? [],
118
+ scopedModels: session.scopedModels?.map((entry) => ({ ...entry })) ?? [],
84
119
  };
85
120
  }
86
121
  function loadedMcpServers(snapshot) {
@@ -113,12 +148,17 @@ function loadedSurfacesFingerprint(session, extensions, mcpServers) {
113
148
  export function createRpcConnectionHandler(runtimeHost, sink, options = {}) {
114
149
  const clientCapabilities = options.capabilities;
115
150
  const routingSessionId = options.sessionId;
151
+ // True only while THIS connection's own command drives a replacement; the issuer
152
+ // already learns the new identity from its command response.
153
+ let replacementIssuedHere = false;
116
154
  let session = runtimeHost.session;
117
155
  let unsubscribe;
118
156
  let unsubscribeBackpressure;
119
157
  let unsubscribeLoadedSurfaces;
120
158
  let unsubscribeExtensionEvents;
121
159
  let mcpWireStatus = { servers: [] };
160
+ /** Abort owner of the last settled turn; `session.currentAbortSource` clears on settle. */
161
+ let lastAbortSource;
122
162
  let loadedSurfacesDigest;
123
163
  let rpcCommandsDigest;
124
164
  let suppressLoadedSurfaceEvents = false;
@@ -191,8 +231,16 @@ export function createRpcConnectionHandler(runtimeHost, sink, options = {}) {
191
231
  }
192
232
  return { id, type: "response", command, success: true, data };
193
233
  };
194
- const error = (id, command, message) => {
195
- return { id, type: "response", command, success: false, error: message };
234
+ const error = (id, command, message, errorCode, errorData) => {
235
+ return {
236
+ id,
237
+ type: "response",
238
+ command,
239
+ success: false,
240
+ error: message,
241
+ ...(errorCode ? { errorCode } : {}),
242
+ ...(errorData === undefined ? {} : { errorData }),
243
+ };
196
244
  };
197
245
  // Pending extension UI requests waiting for response
198
246
  const pendingExtensionRequests = new SessionExtensionUiRequests();
@@ -280,7 +328,6 @@ export function createRpcConnectionHandler(runtimeHost, sink, options = {}) {
280
328
  // Hidden thinking label not supported in RPC mode - requires TUI message rendering access
281
329
  },
282
330
  setWidget(key, content, options) {
283
- // Only support string arrays in RPC mode - factory functions are ignored
284
331
  if (content === undefined || Array.isArray(content)) {
285
332
  output({
286
333
  type: "extension_ui_request",
@@ -290,8 +337,14 @@ export function createRpcConnectionHandler(runtimeHost, sink, options = {}) {
290
337
  widgetLines: content,
291
338
  widgetPlacement: options?.placement,
292
339
  });
340
+ return;
293
341
  }
294
- // Component factories are not supported in RPC mode - would need TUI access
342
+ // A component factory closes over live TUI/theme state and cannot cross
343
+ // the RPC boundary. Never drop it silently: an opted-in client can show
344
+ // the same explicit degradation notice used by ctx.ui.custom.
345
+ const request = buildCustomUnsupportedRequest(clientCapabilities, "widget component");
346
+ if (request)
347
+ output(request);
295
348
  },
296
349
  setFooter(_factory) {
297
350
  // Custom footer not supported in RPC mode - requires TUI access
@@ -417,19 +470,49 @@ export function createRpcConnectionHandler(runtimeHost, sink, options = {}) {
417
470
  }
418
471
  };
419
472
  runtimeHost.setRebindSession(async () => {
420
- await rebindSession();
473
+ // AgentSessionRuntime invokes this callback while completing a replacement.
474
+ // Do not await extension binding here: extensions may wait for session work
475
+ // that the replacement still owns. The command response must acknowledge the
476
+ // committed replacement; derived surfaces refresh out of band afterwards.
477
+ await rebindSession(true);
421
478
  });
422
- const rebindSession = async () => {
479
+ const rebindAfterLocalReplacement = async () => {
480
+ replacementIssuedHere = true;
481
+ try {
482
+ await rebindSession();
483
+ }
484
+ finally {
485
+ replacementIssuedHere = false;
486
+ }
487
+ };
488
+ const rebindSession = async (deferRefresh = false) => {
423
489
  unsubscribeLoadedSurfaces?.();
424
490
  unsubscribeExtensionEvents?.();
491
+ const replacedSession = session !== runtimeHost.session;
425
492
  session = runtimeHost.session;
493
+ if (replacedSession) {
494
+ lastAbortSource = undefined;
495
+ if (routingSessionId !== undefined || !replacementIssuedHere) {
496
+ // A replacement can be driven by ANY attached client, so every connection must be
497
+ // told the live binding moved and given the new authoritative identity. Emitted
498
+ // before the derived-surface refresh so a client cannot act on the old identity in
499
+ // the window the refresh takes.
500
+ outputEvent({
501
+ type: "session_replaced",
502
+ durableSessionId: session.sessionId,
503
+ sessionFile: session.sessionFile,
504
+ cwd: session.sessionManager.getCwd(),
505
+ sessionName: session.sessionName,
506
+ });
507
+ }
508
+ }
426
509
  unsubscribeExtensionEvents = clientCapabilities?.includes(EXTENSION_EVENTS_CAPABILITY)
427
510
  ? session.extensionRunner.onRpcEvent(({ name, data }) => {
428
511
  outputEvent({ type: "extension_event", name, data });
429
512
  })
430
513
  : undefined;
431
514
  subscribeLoadedSurfaceEvents();
432
- await refreshLoadedSurfacesAfter(() => session.bindExtensions({
515
+ const refresh = refreshLoadedSurfacesAfter(() => session.bindExtensions({
433
516
  uiContext: createExtensionUIContext(),
434
517
  mode: "rpc",
435
518
  commandContextActions: {
@@ -474,22 +557,50 @@ export function createRpcConnectionHandler(runtimeHost, sink, options = {}) {
474
557
  });
475
558
  },
476
559
  }), true);
477
- unsubscribe?.();
478
- unsubscribeBackpressure?.();
479
- unsubscribe = session.subscribe((event) => {
480
- if (event.type === "skill_invocation") {
481
- outputEvent(event);
482
- return;
483
- }
484
- if (event.type === "command_invocation") {
560
+ const installSessionSubscriptions = () => {
561
+ unsubscribe?.();
562
+ unsubscribeBackpressure?.();
563
+ unsubscribe = session.subscribe((event) => {
564
+ if (event.type === "skill_invocation") {
565
+ outputEvent(event);
566
+ return;
567
+ }
568
+ if (event.type === "command_invocation") {
569
+ outputEvent(event);
570
+ return;
571
+ }
572
+ if (event.type === "thinking_level_changed" || event.type === "model_changed") {
573
+ // Core emits the effective level only; the selection provenance lives beside it
574
+ // on the session and is what distinguishes an explicit choice from a default.
575
+ const thinkingSelection = session.thinkingSelection;
576
+ outputEvent(thinkingSelection === undefined ? event : { ...event, thinkingSelection });
577
+ return;
578
+ }
579
+ if (event.type === "agent_end") {
580
+ // The subscribe-path `agent_end` carries only { type, messages, willRetry };
581
+ // the abort provenance the extension hook receives is stripped from it. Read
582
+ // it from the session, which still reports the owner at this point, and retain
583
+ // it for `get_state` because the getter clears once the turn settles.
584
+ const abortSource = session.currentAbortSource;
585
+ if (abortSource !== undefined)
586
+ lastAbortSource = abortSource;
587
+ outputEvent(abortSource === undefined ? event : { ...event, aborted: true, abortSource });
588
+ return;
589
+ }
485
590
  outputEvent(event);
486
- return;
487
- }
488
- outputEvent(event);
489
- });
490
- unsubscribeBackpressure = session.agent.subscribe(async () => {
491
- await waitForRpcBackpressure();
492
- });
591
+ });
592
+ unsubscribeBackpressure = session.agent.subscribe(async () => {
593
+ await waitForRpcBackpressure();
594
+ });
595
+ };
596
+ if (deferRefresh) {
597
+ void refresh.then(installSessionSubscriptions, (cause) => {
598
+ outputEvent({ type: "rpc_error", error: String(cause) });
599
+ });
600
+ return;
601
+ }
602
+ await refresh;
603
+ installSessionSubscriptions();
493
604
  };
494
605
  /**
495
606
  * Drive an OAuth login for one provider as fire-command-then-subscribe.
@@ -597,6 +708,8 @@ export function createRpcConnectionHandler(runtimeHost, sink, options = {}) {
597
708
  images: command.images,
598
709
  streamingBehavior: command.streamingBehavior,
599
710
  thinkingLevel: command.thinkingLevel,
711
+ sessionTitlePrompt: command.sessionTitlePrompt,
712
+ expandPromptTemplates: command.expandPromptTemplates,
600
713
  source: "rpc",
601
714
  promptDisposition: (nextDisposition) => {
602
715
  disposition = nextDisposition;
@@ -615,34 +728,78 @@ export function createRpcConnectionHandler(runtimeHost, sink, options = {}) {
615
728
  });
616
729
  return undefined;
617
730
  }
731
+ case "append_user_message": {
732
+ const content = command.content;
733
+ const message = typeof content === "string"
734
+ ? { role: "user", content, timestamp: Date.now() }
735
+ : { role: "user", content, timestamp: Date.now() };
736
+ session.sessionManager.appendMessage(message);
737
+ session.agent.state.messages = session.sessionManager.buildSessionContext().messages;
738
+ return success(id, "append_user_message");
739
+ }
740
+ case "append_session_entry": {
741
+ session.appendSessionEntry(command.entry);
742
+ return success(id, "append_session_entry");
743
+ }
744
+ case "send_custom_message": {
745
+ await session.sendCustomMessage({
746
+ customType: command.customType,
747
+ content: command.content,
748
+ display: command.display,
749
+ details: command.details,
750
+ }, { triggerTurn: command.triggerTurn, deliverAs: command.deliverAs });
751
+ return success(id, "send_custom_message");
752
+ }
618
753
  case "steer": {
619
- await session.steer(command.message, command.images);
754
+ await session.steer(command.message, command.images, { enqueueOrder: command.enqueueOrder });
620
755
  return success(id, "steer");
621
756
  }
622
757
  case "follow_up": {
623
- await session.followUp(command.message, command.images);
758
+ await session.followUp(command.message, command.images, { enqueueOrder: command.enqueueOrder });
624
759
  return success(id, "follow_up");
625
760
  }
626
761
  case "abort": {
627
762
  await session.abort();
628
763
  return success(id, "abort");
629
764
  }
765
+ case "abort_compaction": {
766
+ session.abortCompaction();
767
+ return success(id, "abort_compaction");
768
+ }
769
+ case "reload": {
770
+ const result = await session.reload();
771
+ return success(id, "reload", result);
772
+ }
773
+ case "check_reload_veto": {
774
+ return success(id, "check_reload_veto", await session.checkReloadVeto());
775
+ }
630
776
  case "clear_queue": {
631
- return success(id, "clear_queue", session.clearQueue());
777
+ const cleared = session.clearQueue({ abortWillFollow: command.abortWillFollow ?? false });
778
+ return success(id, "clear_queue", {
779
+ steering: cleared.steering,
780
+ followUp: cleared.followUp,
781
+ ordered: [...cleared.ordered],
782
+ });
632
783
  }
784
+ case "get_steering_messages":
785
+ return success(id, "get_steering_messages", { messages: [...session.getSteeringMessages()] });
786
+ case "get_follow_up_messages":
787
+ return success(id, "get_follow_up_messages", { messages: [...session.getFollowUpMessages()] });
788
+ case "abort_branch_summary":
789
+ session.abortBranchSummary();
790
+ return success(id, "abort_branch_summary");
633
791
  case "new_session": {
634
792
  const options = command.parentSession ? { parentSession: command.parentSession } : undefined;
635
793
  const result = await runtimeHost.newSession(options);
636
- if (!result.cancelled) {
637
- await rebindSession();
638
- }
794
+ if (routingSessionId === undefined && !result.cancelled && session !== runtimeHost.session)
795
+ await rebindAfterLocalReplacement();
639
796
  return success(id, "new_session", result);
640
797
  }
641
798
  // =================================================================
642
799
  // State
643
800
  // =================================================================
644
801
  case "get_state":
645
- return success(id, "get_state", buildRpcSessionState(session));
802
+ return success(id, "get_state", buildRpcSessionState(session, lastAbortSource));
646
803
  // =================================================================
647
804
  // Model
648
805
  // =================================================================
@@ -652,11 +809,17 @@ export function createRpcConnectionHandler(runtimeHost, sink, options = {}) {
652
809
  if (!model) {
653
810
  return error(id, "set_model", `Model not found: ${command.provider}/${command.modelId}`);
654
811
  }
655
- await session.setModel(model);
656
- return success(id, "set_model", model);
812
+ const systemPromptChange = await session.setModel(model);
813
+ return success(id, "set_model", { ...model, systemPromptName: systemPromptChange?.systemPromptName });
657
814
  }
815
+ case "set_favorite_models":
816
+ session.setFavoriteModels(command.models);
817
+ return success(id, "set_favorite_models");
818
+ case "set_scoped_models":
819
+ session.setScopedModels(command.models);
820
+ return success(id, "set_scoped_models");
658
821
  case "cycle_model": {
659
- const result = await session.cycleModel();
822
+ const result = await session.cycleModel(command.direction);
660
823
  if (!result) {
661
824
  return success(id, "cycle_model", null);
662
825
  }
@@ -769,29 +932,60 @@ export function createRpcConnectionHandler(runtimeHost, sink, options = {}) {
769
932
  // =================================================================
770
933
  // Bash
771
934
  // =================================================================
772
- case "bash": {
773
- const eventResult = await session.extensionRunner.emitUserBash({
774
- type: "user_bash",
775
- command: command.command,
776
- excludeFromContext: command.excludeFromContext ?? false,
777
- cwd: session.sessionManager.getCwd(),
935
+ case "navigate_tree": {
936
+ const result = await session.navigateTree(command.targetId, {
937
+ summarize: command.summarize,
938
+ customInstructions: command.customInstructions,
939
+ replaceInstructions: command.replaceInstructions,
940
+ label: command.label,
778
941
  });
779
- if (eventResult?.result) {
780
- session.recordBashResult(command.command, eventResult.result, {
942
+ return success(id, "navigate_tree", result);
943
+ }
944
+ case "record_bash_result":
945
+ session.recordBashResult(command.command, command.result, {
946
+ excludeFromContext: command.excludeFromContext,
947
+ });
948
+ return success(id, "record_bash_result");
949
+ case "set_label":
950
+ session.sessionManager.appendLabelChange(command.entryId, command.label);
951
+ return success(id, "set_label");
952
+ case "bash": {
953
+ if (routingSessionId !== undefined)
954
+ outputEvent({ type: "bash_start" });
955
+ try {
956
+ const eventResult = await session.extensionRunner.emitUserBash({
957
+ type: "user_bash",
958
+ command: command.command,
959
+ excludeFromContext: command.excludeFromContext ?? false,
960
+ cwd: session.sessionManager.getCwd(),
961
+ });
962
+ if (eventResult?.result) {
963
+ session.recordBashResult(command.command, eventResult.result, {
964
+ excludeFromContext: command.excludeFromContext,
965
+ });
966
+ return success(id, "bash", eventResult.result);
967
+ }
968
+ const result = await session.executeBash(command.command, undefined, {
781
969
  excludeFromContext: command.excludeFromContext,
970
+ id: command.executionId,
971
+ // Functions cannot cross JSONL. Host extensions may still provide the
972
+ // executable operations object; client-supplied data is only a wire-safe hint.
973
+ operations: eventResult?.operations,
782
974
  });
783
- return success(id, "bash", eventResult.result);
975
+ return success(id, "bash", result);
976
+ }
977
+ finally {
978
+ if (routingSessionId !== undefined)
979
+ outputEvent({ type: "bash_end" });
784
980
  }
785
- const result = await session.executeBash(command.command, undefined, {
786
- excludeFromContext: command.excludeFromContext,
787
- operations: eventResult?.operations,
788
- });
789
- return success(id, "bash", result);
790
981
  }
791
982
  case "abort_bash": {
792
983
  session.abortBash();
793
984
  return success(id, "abort_bash");
794
985
  }
986
+ case "cleanup_bash_output":
987
+ await session.cleanupBashOutput(command.path);
988
+ return success(id, "cleanup_bash_output");
795
989
  // =================================================================
796
990
  // Session
797
991
  // =================================================================
@@ -800,21 +994,22 @@ export function createRpcConnectionHandler(runtimeHost, sink, options = {}) {
800
994
  return success(id, "get_session_stats", stats);
801
995
  }
802
996
  case "export_html": {
803
- const path = await session.exportToHtml(command.outputPath);
997
+ const path = await session.exportToHtml(command.outputPath, { themeName: command.themeName });
804
998
  return success(id, "export_html", { path });
805
999
  }
1000
+ case "export_jsonl": {
1001
+ return success(id, "export_jsonl", { path: session.exportToJsonl(command.outputPath) });
1002
+ }
806
1003
  case "switch_session": {
807
- const result = await runtimeHost.switchSession(command.sessionPath);
808
- if (!result.cancelled) {
809
- await rebindSession();
810
- }
1004
+ const result = await runtimeHost.switchSession(command.sessionPath, { cwdOverride: command.cwdOverride });
1005
+ if (routingSessionId === undefined && !result.cancelled && session !== runtimeHost.session)
1006
+ await rebindAfterLocalReplacement();
811
1007
  return success(id, "switch_session", result);
812
1008
  }
813
1009
  case "fork": {
814
- const result = await runtimeHost.fork(command.entryId);
815
- if (!result.cancelled) {
816
- await rebindSession();
817
- }
1010
+ const result = await runtimeHost.fork(command.entryId, { position: command.position });
1011
+ if (routingSessionId === undefined && !result.cancelled && session !== runtimeHost.session)
1012
+ await rebindAfterLocalReplacement();
818
1013
  return success(id, "fork", { text: result.selectedText, cancelled: result.cancelled });
819
1014
  }
820
1015
  case "clone": {
@@ -823,9 +1018,8 @@ export function createRpcConnectionHandler(runtimeHost, sink, options = {}) {
823
1018
  return error(id, "clone", "Cannot clone session: no current entry selected");
824
1019
  }
825
1020
  const result = await runtimeHost.fork(leafId, { position: "at" });
826
- if (!result.cancelled) {
827
- await rebindSession();
828
- }
1021
+ if (routingSessionId === undefined && !result.cancelled && session !== runtimeHost.session)
1022
+ await rebindAfterLocalReplacement();
829
1023
  return success(id, "clone", { cancelled: result.cancelled });
830
1024
  }
831
1025
  case "get_fork_messages": {
@@ -852,6 +1046,12 @@ export function createRpcConnectionHandler(runtimeHost, sink, options = {}) {
852
1046
  const text = session.getLastAssistantText();
853
1047
  return success(id, "get_last_assistant_text", { text });
854
1048
  }
1049
+ case "import_jsonl": {
1050
+ const result = await runtimeHost.importFromJsonl(command.inputPath, command.cwdOverride);
1051
+ if (routingSessionId === undefined && !result.cancelled && session !== runtimeHost.session)
1052
+ await rebindAfterLocalReplacement();
1053
+ return success(id, "import_jsonl", result);
1054
+ }
855
1055
  case "set_session_name": {
856
1056
  const name = command.name.trim();
857
1057
  if (!name) {
@@ -971,9 +1171,10 @@ export function createRpcConnectionHandler(runtimeHost, sink, options = {}) {
971
1171
  return;
972
1172
  }
973
1173
  const command = parsed;
1174
+ const payloadError = rpcCommandPayloadError(command);
974
1175
  const messageLengthError = rpcMessageLengthError(command);
975
- if (messageLengthError) {
976
- output(error(command.id, command.type, messageLengthError));
1176
+ if (payloadError || messageLengthError) {
1177
+ output(error(command.id, command.type, payloadError ?? messageLengthError));
977
1178
  await waitForRpcBackpressure();
978
1179
  return;
979
1180
  }
@@ -985,7 +1186,8 @@ export function createRpcConnectionHandler(runtimeHost, sink, options = {}) {
985
1186
  }
986
1187
  }
987
1188
  catch (commandError) {
988
- output(error(command.id, command.type, commandError instanceof Error ? commandError.message : String(commandError)));
1189
+ const missingCwd = commandError instanceof Error && commandError.name === "MissingSessionCwdError" && "issue" in commandError;
1190
+ output(error(command.id, command.type, commandError instanceof Error ? commandError.message : String(commandError), missingCwd ? "missing_session_cwd" : undefined, missingCwd ? commandError.issue : undefined));
989
1191
  await waitForRpcBackpressure();
990
1192
  }
991
1193
  };
@@ -1016,6 +1218,9 @@ export function createRpcConnectionHandler(runtimeHost, sink, options = {}) {
1016
1218
  isShutdownRequested() {
1017
1219
  return shutdownRequested;
1018
1220
  },
1221
+ cancelPendingExtensionUiRequests() {
1222
+ pendingExtensionRequests.cancelAll();
1223
+ },
1019
1224
  async dispose() {
1020
1225
  await ready;
1021
1226
  await dispose();