@shepai/cli 1.164.0 → 1.164.1-pr515.a502bd2

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 (207) hide show
  1. package/dist/packages/core/src/application/ports/output/agents/interactive-agent-executor.interface.d.ts +3 -1
  2. package/dist/packages/core/src/application/ports/output/agents/interactive-agent-executor.interface.d.ts.map +1 -1
  3. package/dist/packages/core/src/application/ports/output/repositories/interactive-session-repository.interface.d.ts +19 -0
  4. package/dist/packages/core/src/application/ports/output/repositories/interactive-session-repository.interface.d.ts.map +1 -1
  5. package/dist/packages/core/src/application/ports/output/services/interactive-session-service.interface.d.ts +7 -1
  6. package/dist/packages/core/src/application/ports/output/services/interactive-session-service.interface.d.ts.map +1 -1
  7. package/dist/packages/core/src/application/use-cases/interactive/send-interactive-message.use-case.d.ts +2 -0
  8. package/dist/packages/core/src/application/use-cases/interactive/send-interactive-message.use-case.d.ts.map +1 -1
  9. package/dist/packages/core/src/application/use-cases/interactive/send-interactive-message.use-case.js +1 -1
  10. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/051-add-session-usage-tracking.d.ts +18 -0
  11. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/051-add-session-usage-tracking.d.ts.map +1 -0
  12. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/051-add-session-usage-tracking.js +32 -0
  13. package/dist/packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.d.ts +12 -0
  14. package/dist/packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.d.ts.map +1 -1
  15. package/dist/packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.js +31 -0
  16. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-interactive-executor.service.d.ts +38 -7
  17. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-interactive-executor.service.d.ts.map +1 -1
  18. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-interactive-executor.service.js +152 -45
  19. package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.d.ts +17 -1
  20. package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.d.ts.map +1 -1
  21. package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.js +131 -47
  22. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/messages/route.d.ts.map +1 -1
  23. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/messages/route.js +3 -1
  24. package/dist/src/presentation/web/components/assistant-ui/thread.js +8 -1
  25. package/dist/src/presentation/web/components/features/chat/ChatTab.d.ts.map +1 -1
  26. package/dist/src/presentation/web/components/features/chat/ChatTab.js +13 -7
  27. package/dist/src/presentation/web/components/features/chat/useChatRuntime.d.ts +16 -0
  28. package/dist/src/presentation/web/components/features/chat/useChatRuntime.d.ts.map +1 -1
  29. package/dist/src/presentation/web/components/features/chat/useChatRuntime.js +98 -7
  30. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/index.d.ts.map +1 -1
  31. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/index.js +1 -1
  32. package/dist/tsconfig.build.tsbuildinfo +1 -1
  33. package/package.json +2 -2
  34. package/web/.next/BUILD_ID +1 -1
  35. package/web/.next/build-manifest.json +2 -2
  36. package/web/.next/fallback-build-manifest.json +2 -2
  37. package/web/.next/prerender-manifest.json +3 -3
  38. package/web/.next/required-server-files.js +3 -3
  39. package/web/.next/required-server-files.json +3 -3
  40. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +29 -29
  41. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  42. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  43. package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +27 -27
  44. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
  45. package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
  46. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +30 -30
  47. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  48. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  49. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +37 -37
  50. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  51. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  52. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +37 -37
  53. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  54. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  55. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
  56. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  57. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  58. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
  59. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  60. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  61. package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +27 -27
  62. package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  63. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  64. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +30 -30
  65. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  66. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  67. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +37 -37
  68. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  69. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  70. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +37 -37
  71. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  72. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  73. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +27 -27
  74. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  75. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  76. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
  77. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  78. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  79. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
  80. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  81. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  82. package/web/.next/server/app/_global-error.html +2 -2
  83. package/web/.next/server/app/_global-error.rsc +1 -1
  84. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  85. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  86. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  87. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  88. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  89. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +6 -6
  90. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  91. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  92. package/web/.next/server/app/settings/page/server-reference-manifest.json +9 -9
  93. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  94. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  95. package/web/.next/server/app/skills/page/server-reference-manifest.json +11 -11
  96. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  97. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  98. package/web/.next/server/app/tools/page/server-reference-manifest.json +11 -11
  99. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  100. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  101. package/web/.next/server/app/version/page/server-reference-manifest.json +6 -6
  102. package/web/.next/server/app/version/page.js.nft.json +1 -1
  103. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  104. package/web/.next/server/chunks/[root-of-the-server]__2b71641f._.js +1 -1
  105. package/web/.next/server/chunks/[root-of-the-server]__2b71641f._.js.map +1 -1
  106. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  107. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  108. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  109. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js +2 -2
  110. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js.map +1 -1
  111. package/web/.next/server/chunks/ssr/[root-of-the-server]__1abe77bb._.js +2 -2
  112. package/web/.next/server/chunks/ssr/[root-of-the-server]__1abe77bb._.js.map +1 -1
  113. package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js +1 -1
  114. package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js.map +1 -1
  115. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  116. package/web/.next/server/chunks/ssr/[root-of-the-server]__563e4faf._.js +1 -1
  117. package/web/.next/server/chunks/ssr/[root-of-the-server]__563e4faf._.js.map +1 -1
  118. package/web/.next/server/chunks/ssr/[root-of-the-server]__7562afc6._.js +2 -2
  119. package/web/.next/server/chunks/ssr/[root-of-the-server]__7562afc6._.js.map +1 -1
  120. package/web/.next/server/chunks/ssr/[root-of-the-server]__821a11c1._.js +1 -1
  121. package/web/.next/server/chunks/ssr/[root-of-the-server]__821a11c1._.js.map +1 -1
  122. package/web/.next/server/chunks/ssr/[root-of-the-server]__86ff0bc5._.js +2 -2
  123. package/web/.next/server/chunks/ssr/[root-of-the-server]__86ff0bc5._.js.map +1 -1
  124. package/web/.next/server/chunks/ssr/[root-of-the-server]__8b0aac03._.js +1 -1
  125. package/web/.next/server/chunks/ssr/[root-of-the-server]__98740ee4._.js +1 -1
  126. package/web/.next/server/chunks/ssr/[root-of-the-server]__98740ee4._.js.map +1 -1
  127. package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js +1 -1
  128. package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js.map +1 -1
  129. package/web/.next/server/chunks/ssr/[root-of-the-server]__ba9f9e11._.js +1 -1
  130. package/web/.next/server/chunks/ssr/[root-of-the-server]__ba9f9e11._.js.map +1 -1
  131. package/web/.next/server/chunks/ssr/[root-of-the-server]__e0be67c7._.js +1 -1
  132. package/web/.next/server/chunks/ssr/[root-of-the-server]__e0be67c7._.js.map +1 -1
  133. package/web/.next/server/chunks/ssr/{_8b57edb8._.js → _0020fddd._.js} +2 -2
  134. package/web/.next/server/chunks/ssr/_0020fddd._.js.map +1 -0
  135. package/web/.next/server/chunks/ssr/_02e01240._.js +1 -1
  136. package/web/.next/server/chunks/ssr/_02e01240._.js.map +1 -1
  137. package/web/.next/server/chunks/ssr/_05c23ad9._.js +1 -1
  138. package/web/.next/server/chunks/ssr/_05c23ad9._.js.map +1 -1
  139. package/web/.next/server/chunks/ssr/_0727935d._.js +1 -1
  140. package/web/.next/server/chunks/ssr/_0727935d._.js.map +1 -1
  141. package/web/.next/server/chunks/ssr/_16eb4fec._.js +1 -1
  142. package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -1
  143. package/web/.next/server/chunks/ssr/_18886033._.js +1 -1
  144. package/web/.next/server/chunks/ssr/_18886033._.js.map +1 -1
  145. package/web/.next/server/chunks/ssr/_22e00a14._.js +1 -1
  146. package/web/.next/server/chunks/ssr/_22e00a14._.js.map +1 -1
  147. package/web/.next/server/chunks/ssr/{_52403a07._.js → _3dee6133._.js} +2 -2
  148. package/web/.next/server/chunks/ssr/{_52403a07._.js.map → _3dee6133._.js.map} +1 -1
  149. package/web/.next/server/chunks/ssr/_56b9d60f._.js +1 -1
  150. package/web/.next/server/chunks/ssr/_56b9d60f._.js.map +1 -1
  151. package/web/.next/server/chunks/ssr/{_c9f903f2._.js → _6724be74._.js} +2 -2
  152. package/web/.next/server/chunks/ssr/{_c9f903f2._.js.map → _6724be74._.js.map} +1 -1
  153. package/web/.next/server/chunks/ssr/_9215e9ec._.js +1 -1
  154. package/web/.next/server/chunks/ssr/_9215e9ec._.js.map +1 -1
  155. package/web/.next/server/chunks/ssr/_a5a5901d._.js +1 -1
  156. package/web/.next/server/chunks/ssr/_a5a5901d._.js.map +1 -1
  157. package/web/.next/server/chunks/ssr/_ad09f271._.js +1 -1
  158. package/web/.next/server/chunks/ssr/_ad09f271._.js.map +1 -1
  159. package/web/.next/server/chunks/ssr/_b883da48._.js +3 -0
  160. package/web/.next/server/chunks/ssr/{_2f8f89fb._.js.map → _b883da48._.js.map} +1 -1
  161. package/web/.next/server/chunks/ssr/_c3f595c6._.js +1 -1
  162. package/web/.next/server/chunks/ssr/_c3f595c6._.js.map +1 -1
  163. package/web/.next/server/chunks/ssr/_ea9e1556._.js +1 -1
  164. package/web/.next/server/chunks/ssr/_ea9e1556._.js.map +1 -1
  165. package/web/.next/server/chunks/ssr/_f1ba9be6._.js +2 -2
  166. package/web/.next/server/chunks/ssr/_f1ba9be6._.js.map +1 -1
  167. package/web/.next/server/chunks/ssr/_f33cd07e._.js +2 -2
  168. package/web/.next/server/chunks/ssr/_f33cd07e._.js.map +1 -1
  169. package/web/.next/server/chunks/ssr/_f8b45233._.js +1 -1
  170. package/web/.next/server/chunks/ssr/_f8b45233._.js.map +1 -1
  171. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  172. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  173. package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js +1 -1
  174. package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js.map +1 -1
  175. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
  176. package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js +1 -1
  177. package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js.map +1 -1
  178. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  179. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  180. package/web/.next/server/pages/500.html +2 -2
  181. package/web/.next/server/server-reference-manifest.js +1 -1
  182. package/web/.next/server/server-reference-manifest.json +47 -47
  183. package/web/.next/static/chunks/14b4f761dfa706d5.js +1 -0
  184. package/web/.next/static/chunks/{29f0d874b1fde3d6.js → 16eea21868510afd.js} +2 -2
  185. package/web/.next/static/chunks/{dc21cf85bfa262a7.js → 1e3134d6609f5fb8.js} +2 -2
  186. package/web/.next/static/chunks/{ce87ded6cc38b4de.js → 1f7c87bd31a89565.js} +1 -1
  187. package/web/.next/static/chunks/{498e45f8e05a5491.js → 327077491ce9ce36.js} +1 -1
  188. package/web/.next/static/chunks/{56955fa252a9f3ed.js → 35f8f085b76399d2.js} +2 -2
  189. package/web/.next/static/chunks/{d9e4d90ef254da84.js → 3b1558ed23955b9c.js} +1 -1
  190. package/web/.next/static/chunks/{ecfd93d61bf4d933.js → 98a18f10308bd60b.js} +1 -1
  191. package/web/.next/static/chunks/{2609c8fc6f14cb26.js → b6155829b6ab6615.js} +1 -1
  192. package/web/.next/static/chunks/b7670b5cffe40313.js +1 -0
  193. package/web/.next/static/chunks/{cf000ba1a3f11439.js → ce9ce94874ba41dd.js} +1 -1
  194. package/web/.next/static/chunks/{ce0316338f7e01e6.js → ddb4cdc186a38e43.js} +1 -1
  195. package/web/.next/static/chunks/{a8243f8d06bdcef0.js → dedf6ca63c5468fa.js} +2 -2
  196. package/web/.next/static/chunks/e604a9e3bcdf9c97.js +1 -0
  197. package/web/.next/static/chunks/eeadf13c0ea6cbe0.css +1 -0
  198. package/web/.next/static/chunks/{cf75fade434602c6.js → fe4cb97803ce660a.js} +3 -3
  199. package/web/.next/server/chunks/ssr/_2f8f89fb._.js +0 -3
  200. package/web/.next/server/chunks/ssr/_8b57edb8._.js.map +0 -1
  201. package/web/.next/static/chunks/25e894a1de46b5fb.js +0 -1
  202. package/web/.next/static/chunks/400e93efac983a76.css +0 -1
  203. package/web/.next/static/chunks/7f491899a2fe2fd7.js +0 -1
  204. package/web/.next/static/chunks/e6398f94cffe9bc2.js +0 -1
  205. /package/web/.next/static/{rav6zzO3q2NtCKwg9XZXP → bfgDets5xggZaWnB7pXnH}/_buildManifest.js +0 -0
  206. /package/web/.next/static/{rav6zzO3q2NtCKwg9XZXP → bfgDets5xggZaWnB7pXnH}/_clientMiddlewareManifest.json +0 -0
  207. /package/web/.next/static/{rav6zzO3q2NtCKwg9XZXP → bfgDets5xggZaWnB7pXnH}/_ssgManifest.js +0 -0
@@ -42,8 +42,10 @@ export interface InteractiveAgentSessionHandle {
42
42
  send(message: string): Promise<void>;
43
43
  /** Iterate response events from the agent */
44
44
  stream(): AsyncIterable<InteractiveAgentEvent>;
45
- /** Terminate the session */
45
+ /** Terminate the session gracefully */
46
46
  close(): Promise<void>;
47
+ /** Abort the current operation immediately (kills the agent process) */
48
+ abort(): void;
47
49
  }
48
50
  /** Executor interface for interactive agent sessions. */
49
51
  export interface IInteractiveAgentExecutor {
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-agent-executor.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/agents/interactive-agent-executor.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,kEAAkE;AAClE,MAAM,WAAW,uBAAuB;IACtC,6CAA6C;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,4DAA4D;AAC5D,MAAM,WAAW,qBAAqB;IACpC,IAAI,EACA,OAAO,GACP,UAAU,GACV,aAAa,GACb,QAAQ,GACR,MAAM,GACN,OAAO,GACP,MAAM,GACN,WAAW,GACX,YAAY,GACZ,cAAc,GACd,eAAe,GACf,WAAW,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,KAAK,CAAC,EAAE;QACN,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,kDAAkD;AAClD,MAAM,WAAW,6BAA6B;IAC5C,mDAAmD;IACnD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,uCAAuC;IACvC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,6CAA6C;IAC7C,MAAM,IAAI,aAAa,CAAC,qBAAqB,CAAC,CAAC;IAC/C,4BAA4B;IAC5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,yDAAyD;AACzD,MAAM,WAAW,yBAAyB;IACxC,aAAa,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,6BAA6B,CAAC,CAAC;IACxF,aAAa,CACX,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,6BAA6B,CAAC,CAAC;CAC3C"}
1
+ {"version":3,"file":"interactive-agent-executor.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/agents/interactive-agent-executor.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,kEAAkE;AAClE,MAAM,WAAW,uBAAuB;IACtC,6CAA6C;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,4DAA4D;AAC5D,MAAM,WAAW,qBAAqB;IACpC,IAAI,EACA,OAAO,GACP,UAAU,GACV,aAAa,GACb,QAAQ,GACR,MAAM,GACN,OAAO,GACP,MAAM,GACN,WAAW,GACX,YAAY,GACZ,cAAc,GACd,eAAe,GACf,WAAW,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,KAAK,CAAC,EAAE;QACN,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,kDAAkD;AAClD,MAAM,WAAW,6BAA6B;IAC5C,mDAAmD;IACnD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,uCAAuC;IACvC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,6CAA6C;IAC7C,MAAM,IAAI,aAAa,CAAC,qBAAqB,CAAC,CAAC;IAC/C,uCAAuC;IACvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,wEAAwE;IACxE,KAAK,IAAI,IAAI,CAAC;CACf;AAED,yDAAyD;AACzD,MAAM,WAAW,yBAAyB;IACxC,aAAa,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,6BAA6B,CAAC,CAAC;IACxF,aAAa,CACX,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,6BAA6B,CAAC,CAAC;CAC3C"}
@@ -74,5 +74,24 @@ export interface IInteractiveSessionRepository {
74
74
  * Returns a map of featureId → turnStatus (only 'processing' | 'unread' entries).
75
75
  */
76
76
  getAllActiveTurnStatuses(): Promise<Map<string, string>>;
77
+ /**
78
+ * Accumulate usage from a completed turn onto the session totals.
79
+ * All values are ADDED to the existing totals (not replaced).
80
+ */
81
+ accumulateUsage(id: string, usage: {
82
+ costUsd: number;
83
+ inputTokens: number;
84
+ outputTokens: number;
85
+ turns: number;
86
+ }): Promise<void>;
87
+ /**
88
+ * Get cumulative usage for a session.
89
+ */
90
+ getUsage(id: string): Promise<{
91
+ totalCostUsd: number;
92
+ totalInputTokens: number;
93
+ totalOutputTokens: number;
94
+ totalTurns: number;
95
+ } | null>;
77
96
  }
78
97
  //# sourceMappingURL=interactive-session-repository.interface.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-session-repository.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/repositories/interactive-session-repository.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,wCAAwC,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAEzD;;;;;OAKG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAEvE;;;OAGG;IACH,aAAa,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAE/C;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,wBAAwB,EAAE,SAAS,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5F;;OAEG;IACH,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpE;;;OAGG;IACH,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtC;;;OAGG;IACH,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAEvC;;;OAGG;IACH,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExE;;OAEG;IACH,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEtD;;;OAGG;IACH,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhE;;;OAGG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAEpE;;;OAGG;IACH,wBAAwB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC1D"}
1
+ {"version":3,"file":"interactive-session-repository.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/repositories/interactive-session-repository.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,wCAAwC,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAEzD;;;;;OAKG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAEvE;;;OAGG;IACH,aAAa,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAE/C;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,wBAAwB,EAAE,SAAS,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5F;;OAEG;IACH,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpE;;;OAGG;IACH,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtC;;;OAGG;IACH,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAEvC;;;OAGG;IACH,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExE;;OAEG;IACH,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEtD;;;OAGG;IACH,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhE;;;OAGG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAEpE;;;OAGG;IACH,wBAAwB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAEzD;;;OAGG;IACH,eAAe,CACb,EAAE,EAAE,MAAM,EACV,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GACnF,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAC5B,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI,CAAC,CAAC;CACX"}
@@ -61,6 +61,12 @@ export interface SessionInfo {
61
61
  startedAt: string;
62
62
  idleTimeoutMinutes: number;
63
63
  lastActivityAt: string;
64
+ /** Cumulative cost in USD for this session (null if not yet tracked) */
65
+ totalCostUsd: number | null;
66
+ /** Cumulative input tokens for this session */
67
+ totalInputTokens: number | null;
68
+ /** Cumulative output tokens for this session */
69
+ totalOutputTokens: number | null;
64
70
  }
65
71
  /**
66
72
  * Service interface for interactive session lifecycle management.
@@ -151,7 +157,7 @@ export interface IInteractiveSessionService {
151
157
  *
152
158
  * @returns The persisted user message
153
159
  */
154
- sendUserMessage(featureId: string, content: string, worktreePath: string): Promise<InteractiveMessage>;
160
+ sendUserMessage(featureId: string, content: string, worktreePath: string, model?: string, agentType?: string): Promise<InteractiveMessage>;
155
161
  /**
156
162
  * Get the complete chat state for a feature in a single call.
157
163
  * Merges DB messages with any in-flight streaming content.
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-session-service.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/interactive-session-service.interface.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"interactive-session-service.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/interactive-session-service.interface.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,8 @@ export interface SendInteractiveMessageInput {
15
15
  featureId: string;
16
16
  content: string;
17
17
  worktreePath: string;
18
+ model?: string;
19
+ agentType?: string;
18
20
  }
19
21
  /**
20
22
  * Use case for sending a user message to an interactive agent session.
@@ -1 +1 @@
1
- {"version":3,"file":"send-interactive-message.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/interactive/send-interactive-message.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sEAAsE,CAAC;AACvH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAE9E;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;GAMG;AACH,qBACa,6BAA6B;IAGtC,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,0BAA0B;IAGhD,OAAO,CAAC,KAAK,EAAE,2BAA2B,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAG/E"}
1
+ {"version":3,"file":"send-interactive-message.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/interactive/send-interactive-message.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sEAAsE,CAAC;AACvH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAE9E;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,qBACa,6BAA6B;IAGtC,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,0BAA0B;IAGhD,OAAO,CAAC,KAAK,EAAE,2BAA2B,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAS/E"}
@@ -32,7 +32,7 @@ let SendInteractiveMessageUseCase = class SendInteractiveMessageUseCase {
32
32
  this.service = service;
33
33
  }
34
34
  async execute(input) {
35
- return this.service.sendUserMessage(input.featureId, input.content, input.worktreePath);
35
+ return this.service.sendUserMessage(input.featureId, input.content, input.worktreePath, input.model, input.agentType);
36
36
  }
37
37
  };
38
38
  SendInteractiveMessageUseCase = __decorate([
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Migration 051: Add usage tracking columns to interactive_sessions.
3
+ *
4
+ * Tracks cumulative cost and token usage per session so users can see
5
+ * how much each chat session costs. Values are accumulated from the
6
+ * SDK's result messages on each turn completion.
7
+ *
8
+ * Columns:
9
+ * - total_cost_usd: cumulative cost in USD (REAL, default 0)
10
+ * - total_input_tokens: cumulative input tokens (INTEGER, default 0)
11
+ * - total_output_tokens: cumulative output tokens (INTEGER, default 0)
12
+ * - total_turns: cumulative SDK turns (INTEGER, default 0)
13
+ */
14
+ import type { MigrationParams } from 'umzug';
15
+ import type Database from 'better-sqlite3';
16
+ export declare function up({ context: db }: MigrationParams<Database.Database>): Promise<void>;
17
+ export declare function down({ context: db }: MigrationParams<Database.Database>): Promise<void>;
18
+ //# sourceMappingURL=051-add-session-usage-tracking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"051-add-session-usage-tracking.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/persistence/sqlite/migrations/051-add-session-usage-tracking.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,wBAAsB,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB3F;AAED,wBAAsB,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7F"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Migration 051: Add usage tracking columns to interactive_sessions.
3
+ *
4
+ * Tracks cumulative cost and token usage per session so users can see
5
+ * how much each chat session costs. Values are accumulated from the
6
+ * SDK's result messages on each turn completion.
7
+ *
8
+ * Columns:
9
+ * - total_cost_usd: cumulative cost in USD (REAL, default 0)
10
+ * - total_input_tokens: cumulative input tokens (INTEGER, default 0)
11
+ * - total_output_tokens: cumulative output tokens (INTEGER, default 0)
12
+ * - total_turns: cumulative SDK turns (INTEGER, default 0)
13
+ */
14
+ export async function up({ context: db }) {
15
+ const columns = db.pragma('table_info(interactive_sessions)');
16
+ const names = new Set(columns.map((c) => c.name));
17
+ if (!names.has('total_cost_usd')) {
18
+ db.exec('ALTER TABLE interactive_sessions ADD COLUMN total_cost_usd REAL NOT NULL DEFAULT 0');
19
+ }
20
+ if (!names.has('total_input_tokens')) {
21
+ db.exec('ALTER TABLE interactive_sessions ADD COLUMN total_input_tokens INTEGER NOT NULL DEFAULT 0');
22
+ }
23
+ if (!names.has('total_output_tokens')) {
24
+ db.exec('ALTER TABLE interactive_sessions ADD COLUMN total_output_tokens INTEGER NOT NULL DEFAULT 0');
25
+ }
26
+ if (!names.has('total_turns')) {
27
+ db.exec('ALTER TABLE interactive_sessions ADD COLUMN total_turns INTEGER NOT NULL DEFAULT 0');
28
+ }
29
+ }
30
+ export async function down({ context: db }) {
31
+ void db;
32
+ }
@@ -24,5 +24,17 @@ export declare class SQLiteInteractiveSessionRepository implements IInteractiveS
24
24
  updateTurnStatus(id: string, turnStatus: string): Promise<void>;
25
25
  getTurnStatuses(featureIds: string[]): Promise<Map<string, string>>;
26
26
  getAllActiveTurnStatuses(): Promise<Map<string, string>>;
27
+ accumulateUsage(id: string, usage: {
28
+ costUsd: number;
29
+ inputTokens: number;
30
+ outputTokens: number;
31
+ turns: number;
32
+ }): Promise<void>;
33
+ getUsage(id: string): Promise<{
34
+ totalCostUsd: number;
35
+ totalInputTokens: number;
36
+ totalOutputTokens: number;
37
+ totalTurns: number;
38
+ } | null>;
27
39
  }
28
40
  //# sourceMappingURL=sqlite-interactive-session.repository.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite-interactive-session.repository.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,yFAAyF,CAAC;AAC7I,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAO5E,qBACa,kCAAmC,YAAW,6BAA6B;IAC1E,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ,CAAC,QAAQ;IAE5C,MAAM,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYlD,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAOxD,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAStE,aAAa,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAO9C,YAAY,CAChB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,wBAAwB,EAChC,SAAS,CAAC,EAAE,IAAI,GACf,OAAO,CAAC,IAAI,CAAC;IAeV,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAUnE,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAUrC,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;IAStC,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQvE,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAOrD,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ/D,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAyBnE,wBAAwB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAkB/D"}
1
+ {"version":3,"file":"sqlite-interactive-session.repository.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,yFAAyF,CAAC;AAC7I,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAO5E,qBACa,kCAAmC,YAAW,6BAA6B;IAC1E,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ,CAAC,QAAQ;IAE5C,MAAM,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYlD,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAOxD,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAStE,aAAa,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAO9C,YAAY,CAChB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,wBAAwB,EAChC,SAAS,CAAC,EAAE,IAAI,GACf,OAAO,CAAC,IAAI,CAAC;IAeV,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAUnE,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAUrC,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;IAStC,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQvE,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAOrD,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ/D,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAyBnE,wBAAwB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAmBxD,eAAe,CACnB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GACnF,OAAO,CAAC,IAAI,CAAC;IAqBV,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAClC,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI,CAAC;CAqBV"}
@@ -129,6 +129,37 @@ let SQLiteInteractiveSessionRepository = class SQLiteInteractiveSessionRepositor
129
129
  }
130
130
  return result;
131
131
  }
132
+ async accumulateUsage(id, usage) {
133
+ this.db
134
+ .prepare(`UPDATE interactive_sessions SET
135
+ total_cost_usd = total_cost_usd + @cost_usd,
136
+ total_input_tokens = total_input_tokens + @input_tokens,
137
+ total_output_tokens = total_output_tokens + @output_tokens,
138
+ total_turns = total_turns + @turns,
139
+ updated_at = @updated_at
140
+ WHERE id = @id`)
141
+ .run({
142
+ id,
143
+ cost_usd: usage.costUsd,
144
+ input_tokens: usage.inputTokens,
145
+ output_tokens: usage.outputTokens,
146
+ turns: usage.turns,
147
+ updated_at: Date.now(),
148
+ });
149
+ }
150
+ async getUsage(id) {
151
+ const row = this.db
152
+ .prepare('SELECT total_cost_usd, total_input_tokens, total_output_tokens, total_turns FROM interactive_sessions WHERE id = ?')
153
+ .get(id);
154
+ if (!row)
155
+ return null;
156
+ return {
157
+ totalCostUsd: row.total_cost_usd,
158
+ totalInputTokens: row.total_input_tokens,
159
+ totalOutputTokens: row.total_output_tokens,
160
+ totalTurns: row.total_turns,
161
+ };
162
+ }
132
163
  };
133
164
  SQLiteInteractiveSessionRepository = __decorate([
134
165
  injectable(),
@@ -5,6 +5,28 @@
5
5
  * @anthropic-ai/claude-agent-sdk V2 session API. This is the ONLY file
6
6
  * that imports from the SDK.
7
7
  *
8
+ * ## V2 API Stability Notice
9
+ *
10
+ * This file uses the `unstable_v2_*` session API. The V2 API is chosen over
11
+ * the stable V1 `query()` API because V2 maintains a persistent agent process
12
+ * across turns, providing near-instant turn responses. V1 `query()` spawns a
13
+ * new process per turn with `resume`, adding 5-15s latency — unacceptable
14
+ * for interactive chat.
15
+ *
16
+ * The SDK version is pinned exactly in package.json to prevent surprise
17
+ * breakage. If Anthropic removes the V2 API, migrate to V1 `query()` with
18
+ * `resume: sessionId` — the InteractiveAgentSessionHandle interface is
19
+ * designed to support either backend transparently.
20
+ *
21
+ * ## V2 Limitations (vs V1 query())
22
+ *
23
+ * SDKSessionOptions does NOT support: `cwd`, `maxTurns`, `maxBudgetUsd`,
24
+ * `abortController`, `settingSources`, `persistSession`, `effort`.
25
+ * These must be handled at the service layer:
26
+ * - cwd: Handled via process.chdir() mutex (see withCwd)
27
+ * - abort: Handled via SDKSession.close() which kills the process
28
+ * - maxTurns/maxBudgetUsd: Should be tracked by InteractiveSessionService
29
+ *
8
30
  * Design decisions:
9
31
  * - The CLAUDECODE env var is stripped to prevent nested-session detection
10
32
  * errors when shep itself is running inside a Claude Code session.
@@ -16,14 +38,22 @@ export declare class ClaudeCodeInteractiveExecutor implements IInteractiveAgentE
16
38
  createSession(options: InteractiveAgentOptions): Promise<InteractiveAgentSessionHandle>;
17
39
  resumeSession(sessionId: string, options: InteractiveAgentOptions): Promise<InteractiveAgentSessionHandle>;
18
40
  /**
19
- * SDKSessionOptions (V2) does not support a `cwd` parameter.
20
- * Temporarily change process.cwd() for session creation, then restore.
21
- * This is safe because Node.js is single-threaded and SDK session creation
22
- * is synchronous (returns immediately, spawns process in background).
41
+ * Acquire a process-level mutex, change cwd, run the synchronous factory
42
+ * function, restore cwd, and release the mutex.
43
+ *
44
+ * This prevents concurrent session creations from seeing each other's cwd.
45
+ * The mutex is async to serialize across concurrent API request handlers.
23
46
  */
24
47
  private withCwd;
25
48
  private buildSdkOptions;
26
49
  private wrapSession;
50
+ /**
51
+ * Map the SDK message stream to domain events.
52
+ *
53
+ * Tracks whether streaming deltas (`stream_event`) have been emitted for
54
+ * the current turn. When deltas are available, the `assistant` message's
55
+ * text blocks are skipped to prevent double-emission of the same content.
56
+ */
27
57
  private mapStream;
28
58
  /**
29
59
  * Map a single SDK message to zero or more InteractiveAgentEvents.
@@ -31,12 +61,13 @@ export declare class ClaudeCodeInteractiveExecutor implements IInteractiveAgentE
31
61
  * SDK message types we handle:
32
62
  * - stream_event (SDKPartialAssistantMessage): streaming content deltas
33
63
  * - assistant (SDKAssistantMessage): complete assistant turn with tool_use blocks
34
- * - result (SDKResultMessage): success or error result
35
- * - system (SDKStatusMessage / SDKSystemMessage): status updates
64
+ * - result (SDKResultMessage): success or error result with distinct subtypes
65
+ * - system (SDKStatusMessage / SDKSystemMessage): status updates, compaction
36
66
  * - tool_use_summary: tool execution summaries
37
67
  * - tool_progress: tool execution progress
68
+ * - rate_limit_event: rate limit notifications
38
69
  *
39
- * Other message types are silently ignored (user replays, auth, etc.)
70
+ * Other message types are silently ignored (user replays, auth, hooks, etc.)
40
71
  */
41
72
  private mapSdkMessage;
42
73
  }
@@ -1 +1 @@
1
- {"version":3,"file":"claude-code-interactive-executor.service.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/common/executors/claude-code-interactive-executor.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,OAAO,KAAK,EACV,yBAAyB,EACzB,uBAAuB,EACvB,6BAA6B,EAE9B,MAAM,wFAAwF,CAAC;AAKhG,qBAAa,6BAA8B,YAAW,yBAAyB;IACvE,aAAa,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,6BAA6B,CAAC;IAOvF,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,6BAA6B,CAAC;IAOzC;;;;;OAKG;IACH,OAAO,CAAC,OAAO;IAUf,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,WAAW;YAiBJ,SAAS;IASxB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,aAAa;CA0MtB"}
1
+ {"version":3,"file":"claude-code-interactive-executor.service.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/common/executors/claude-code-interactive-executor.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAOH,OAAO,KAAK,EACV,yBAAyB,EACzB,uBAAuB,EACvB,6BAA6B,EAE9B,MAAM,wFAAwF,CAAC;AAgBhG,qBAAa,6BAA8B,YAAW,yBAAyB;IACvE,aAAa,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,6BAA6B,CAAC;IAOvF,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,6BAA6B,CAAC;IAOzC;;;;;;OAMG;IACH,OAAO,CAAC,OAAO;IAmBf,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,WAAW;IAoBnB;;;;;;OAMG;YACY,SAAS;IA6BxB;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,aAAa;CAuPtB"}
@@ -5,6 +5,28 @@
5
5
  * @anthropic-ai/claude-agent-sdk V2 session API. This is the ONLY file
6
6
  * that imports from the SDK.
7
7
  *
8
+ * ## V2 API Stability Notice
9
+ *
10
+ * This file uses the `unstable_v2_*` session API. The V2 API is chosen over
11
+ * the stable V1 `query()` API because V2 maintains a persistent agent process
12
+ * across turns, providing near-instant turn responses. V1 `query()` spawns a
13
+ * new process per turn with `resume`, adding 5-15s latency — unacceptable
14
+ * for interactive chat.
15
+ *
16
+ * The SDK version is pinned exactly in package.json to prevent surprise
17
+ * breakage. If Anthropic removes the V2 API, migrate to V1 `query()` with
18
+ * `resume: sessionId` — the InteractiveAgentSessionHandle interface is
19
+ * designed to support either backend transparently.
20
+ *
21
+ * ## V2 Limitations (vs V1 query())
22
+ *
23
+ * SDKSessionOptions does NOT support: `cwd`, `maxTurns`, `maxBudgetUsd`,
24
+ * `abortController`, `settingSources`, `persistSession`, `effort`.
25
+ * These must be handled at the service layer:
26
+ * - cwd: Handled via process.chdir() mutex (see withCwd)
27
+ * - abort: Handled via SDKSession.close() which kills the process
28
+ * - maxTurns/maxBudgetUsd: Should be tracked by InteractiveSessionService
29
+ *
8
30
  * Design decisions:
9
31
  * - The CLAUDECODE env var is stripped to prevent nested-session detection
10
32
  * errors when shep itself is running inside a Claude Code session.
@@ -14,30 +36,49 @@
14
36
  import { unstable_v2_createSession, unstable_v2_resumeSession, } from '@anthropic-ai/claude-agent-sdk';
15
37
  /** Default model used when options.model is not specified. */
16
38
  const DEFAULT_MODEL = 'claude-sonnet-4-6';
39
+ /**
40
+ * Process-level mutex for process.chdir().
41
+ *
42
+ * SDKSessionOptions (V2) does not support a `cwd` parameter, so we
43
+ * temporarily change process.cwd() during session creation. Although
44
+ * session creation itself is synchronous, concurrent API requests can
45
+ * interleave between chdir calls. This mutex serializes all chdir
46
+ * operations to prevent one session from inheriting another's cwd.
47
+ */
48
+ let cwdMutexPromise = Promise.resolve();
17
49
  export class ClaudeCodeInteractiveExecutor {
18
50
  async createSession(options) {
19
- const sdkSession = this.withCwd(options.cwd, () => unstable_v2_createSession(this.buildSdkOptions(options)));
51
+ const sdkSession = await this.withCwd(options.cwd, () => unstable_v2_createSession(this.buildSdkOptions(options)));
20
52
  return this.wrapSession(sdkSession);
21
53
  }
22
54
  async resumeSession(sessionId, options) {
23
- const sdkSession = this.withCwd(options.cwd, () => unstable_v2_resumeSession(sessionId, this.buildSdkOptions(options)));
55
+ const sdkSession = await this.withCwd(options.cwd, () => unstable_v2_resumeSession(sessionId, this.buildSdkOptions(options)));
24
56
  return this.wrapSession(sdkSession);
25
57
  }
26
58
  /**
27
- * SDKSessionOptions (V2) does not support a `cwd` parameter.
28
- * Temporarily change process.cwd() for session creation, then restore.
29
- * This is safe because Node.js is single-threaded and SDK session creation
30
- * is synchronous (returns immediately, spawns process in background).
59
+ * Acquire a process-level mutex, change cwd, run the synchronous factory
60
+ * function, restore cwd, and release the mutex.
61
+ *
62
+ * This prevents concurrent session creations from seeing each other's cwd.
63
+ * The mutex is async to serialize across concurrent API request handlers.
31
64
  */
32
65
  withCwd(cwd, fn) {
33
- const originalCwd = process.cwd();
34
- try {
35
- process.chdir(cwd);
36
- return fn();
37
- }
38
- finally {
39
- process.chdir(originalCwd);
40
- }
66
+ const prev = cwdMutexPromise;
67
+ let resolve;
68
+ cwdMutexPromise = new Promise((r) => {
69
+ resolve = r;
70
+ });
71
+ return prev.then(() => {
72
+ const originalCwd = process.cwd();
73
+ try {
74
+ process.chdir(cwd);
75
+ return fn();
76
+ }
77
+ finally {
78
+ process.chdir(originalCwd);
79
+ resolve();
80
+ }
81
+ });
41
82
  }
42
83
  buildSdkOptions(options) {
43
84
  // Strip CLAUDECODE env var to prevent nested-session detection errors.
@@ -57,28 +98,49 @@ export class ClaudeCodeInteractiveExecutor {
57
98
  };
58
99
  }
59
100
  wrapSession(sdkSession) {
101
+ // SDK session ID is not available until after the first message exchange.
102
+ // Track it via a mutable variable updated by the stream mapper.
103
+ let resolvedSessionId = '';
60
104
  return {
61
105
  get sessionId() {
62
- // SDK session ID is not available until after the first message exchange.
63
- // Return empty string before that — callers should read it after streaming.
64
- try {
65
- return sdkSession.sessionId;
66
- }
67
- catch {
68
- return '';
69
- }
106
+ return resolvedSessionId;
70
107
  },
71
108
  send: (message) => sdkSession.send(message),
72
- stream: () => this.mapStream(sdkSession),
109
+ stream: () => this.mapStream(sdkSession, (id) => (resolvedSessionId = id)),
73
110
  close: async () => sdkSession.close(),
111
+ abort: () => {
112
+ // V2 SDKSession.close() synchronously kills the agent process.
113
+ // This is the only abort mechanism V2 provides.
114
+ sdkSession.close();
115
+ },
74
116
  };
75
117
  }
76
- async *mapStream(sdkSession) {
118
+ /**
119
+ * Map the SDK message stream to domain events.
120
+ *
121
+ * Tracks whether streaming deltas (`stream_event`) have been emitted for
122
+ * the current turn. When deltas are available, the `assistant` message's
123
+ * text blocks are skipped to prevent double-emission of the same content.
124
+ */
125
+ async *mapStream(sdkSession, onSessionId) {
126
+ let hasStreamedDeltas = false;
77
127
  for await (const msg of sdkSession.stream()) {
78
- const events = this.mapSdkMessage(msg);
128
+ // Capture sessionId from messages that carry it
129
+ if ('session_id' in msg && typeof msg.session_id === 'string' && msg.session_id) {
130
+ onSessionId(msg.session_id);
131
+ }
132
+ const events = this.mapSdkMessage(msg, hasStreamedDeltas);
79
133
  for (const event of events) {
80
134
  yield event;
81
135
  }
136
+ // Track whether we've seen streaming deltas for this turn
137
+ if (msg.type === 'stream_event') {
138
+ hasStreamedDeltas = true;
139
+ }
140
+ // Reset delta tracking on turn boundaries
141
+ if (msg.type === 'result') {
142
+ hasStreamedDeltas = false;
143
+ }
82
144
  }
83
145
  }
84
146
  /**
@@ -87,14 +149,15 @@ export class ClaudeCodeInteractiveExecutor {
87
149
  * SDK message types we handle:
88
150
  * - stream_event (SDKPartialAssistantMessage): streaming content deltas
89
151
  * - assistant (SDKAssistantMessage): complete assistant turn with tool_use blocks
90
- * - result (SDKResultMessage): success or error result
91
- * - system (SDKStatusMessage / SDKSystemMessage): status updates
152
+ * - result (SDKResultMessage): success or error result with distinct subtypes
153
+ * - system (SDKStatusMessage / SDKSystemMessage): status updates, compaction
92
154
  * - tool_use_summary: tool execution summaries
93
155
  * - tool_progress: tool execution progress
156
+ * - rate_limit_event: rate limit notifications
94
157
  *
95
- * Other message types are silently ignored (user replays, auth, etc.)
158
+ * Other message types are silently ignored (user replays, auth, hooks, etc.)
96
159
  */
97
- mapSdkMessage(msg) {
160
+ mapSdkMessage(msg, hasStreamedDeltas) {
98
161
  const events = [];
99
162
  switch (msg.type) {
100
163
  case 'stream_event': {
@@ -113,16 +176,17 @@ export class ClaudeCodeInteractiveExecutor {
113
176
  }
114
177
  case 'assistant': {
115
178
  // SDKAssistantMessage — complete assistant turn with text + tool_use blocks.
116
- // Text blocks contain the agent's reasoning between tool calls (e.g.,
117
- // "Let me read that file..." or "I see, now I'll..."). These MUST be
118
- // emitted as deltas — stream_event deltas may not be available in V2.
119
179
  if ('message' in msg && msg.message?.content) {
120
180
  for (const block of msg.message.content) {
121
181
  if (block.type === 'text' && block.text) {
122
- events.push({
123
- type: 'delta',
124
- content: block.text,
125
- });
182
+ // Skip text blocks if we already emitted streaming deltas for
183
+ // this turn — otherwise the same content appears twice.
184
+ if (!hasStreamedDeltas) {
185
+ events.push({
186
+ type: 'delta',
187
+ content: block.text,
188
+ });
189
+ }
126
190
  }
127
191
  else if (block.type === 'tool_use') {
128
192
  events.push({
@@ -143,7 +207,7 @@ export class ClaudeCodeInteractiveExecutor {
143
207
  break;
144
208
  }
145
209
  case 'result': {
146
- // SDKResultMessage — success or error
210
+ // SDKResultMessage — success or error with distinct subtypes
147
211
  if (msg.subtype === 'success') {
148
212
  events.push({
149
213
  type: 'done',
@@ -158,11 +222,35 @@ export class ClaudeCodeInteractiveExecutor {
158
222
  });
159
223
  }
160
224
  else {
161
- // SDKResultError
162
- const errorMsg = 'errors' in msg && Array.isArray(msg.errors) ? msg.errors.join('; ') : msg.subtype;
225
+ // Distinguish error subtypes so the UI can show specific messages
226
+ const errorMessages = 'errors' in msg && Array.isArray(msg.errors) ? msg.errors.join('; ') : '';
227
+ let content;
228
+ switch (msg.subtype) {
229
+ case 'error_max_turns':
230
+ content = `Agent reached the maximum number of turns${errorMessages ? `: ${errorMessages}` : ''}`;
231
+ break;
232
+ case 'error_max_budget_usd':
233
+ content = `Agent exceeded the budget limit${errorMessages ? `: ${errorMessages}` : ''}`;
234
+ break;
235
+ case 'error_max_structured_output_retries':
236
+ content = `Agent exceeded structured output retries${errorMessages ? `: ${errorMessages}` : ''}`;
237
+ break;
238
+ case 'error_during_execution':
239
+ default:
240
+ content = errorMessages || 'Agent encountered an error during execution';
241
+ break;
242
+ }
163
243
  events.push({
164
244
  type: 'error',
165
- content: errorMsg,
245
+ content,
246
+ // Attach usage data even on errors — cost was still incurred
247
+ usage: {
248
+ costUsd: msg.total_cost_usd,
249
+ inputTokens: msg.usage?.input_tokens,
250
+ outputTokens: msg.usage?.output_tokens,
251
+ numTurns: msg.num_turns,
252
+ durationMs: msg.duration_ms,
253
+ },
166
254
  });
167
255
  }
168
256
  break;
@@ -184,14 +272,23 @@ export class ClaudeCodeInteractiveExecutor {
184
272
  });
185
273
  }
186
274
  break;
187
- case 'status':
188
- if ('status' in msg) {
275
+ case 'status': {
276
+ // Status updates including context compaction
277
+ const status = 'status' in msg ? msg.status : null;
278
+ if (status === 'compacting') {
189
279
  events.push({
190
280
  type: 'status',
191
- content: String(msg.status ?? 'ready'),
281
+ content: 'Compacting context — older conversation will be summarized',
282
+ });
283
+ }
284
+ else if (status !== null) {
285
+ events.push({
286
+ type: 'status',
287
+ content: String(status),
192
288
  });
193
289
  }
194
290
  break;
291
+ }
195
292
  case 'api_retry':
196
293
  // API retry — let user know agent is retrying
197
294
  if ('attempt' in msg) {
@@ -277,11 +374,21 @@ export class ClaudeCodeInteractiveExecutor {
277
374
  }
278
375
  break;
279
376
  }
280
- default:
281
- // Ignore: user, user_replay, auth_status, compact_boundary,
377
+ default: {
378
+ // SDKCompactBoundaryMessage context was compacted.
379
+ // Not in the TS discriminant union, so handle via string check.
380
+ const msgType = msg.type;
381
+ if (msgType === 'compact_boundary') {
382
+ events.push({
383
+ type: 'status',
384
+ content: 'Context compacted — older conversation has been summarized',
385
+ });
386
+ }
387
+ // Otherwise ignore: user, user_replay, auth_status,
282
388
  // local_command_output, hook_*, files_persisted,
283
389
  // elicitation_complete, prompt_suggestion
284
390
  break;
391
+ }
285
392
  }
286
393
  return events;
287
394
  }