@shepai/cli 1.175.1-pr537.fc6a92c → 1.176.0

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 (764) hide show
  1. package/apis/json-schema/AgentConfig.yaml +0 -3
  2. package/apis/json-schema/AgentType.yaml +0 -1
  3. package/dist/packages/core/src/application/ports/output/agents/agent-executor.interface.d.ts +1 -3
  4. package/dist/packages/core/src/application/ports/output/agents/agent-executor.interface.d.ts.map +1 -1
  5. package/dist/packages/core/src/application/ports/output/agents/agent-run-repository.interface.d.ts +0 -7
  6. package/dist/packages/core/src/application/ports/output/agents/agent-run-repository.interface.d.ts.map +1 -1
  7. package/dist/packages/core/src/application/ports/output/agents/phase-timing-repository.interface.d.ts +0 -7
  8. package/dist/packages/core/src/application/ports/output/agents/phase-timing-repository.interface.d.ts.map +1 -1
  9. package/dist/packages/core/src/application/ports/output/services/index.d.ts +0 -3
  10. package/dist/packages/core/src/application/ports/output/services/index.d.ts.map +1 -1
  11. package/dist/packages/core/src/application/use-cases/agents/get-agent-session.use-case.d.ts +1 -3
  12. package/dist/packages/core/src/application/use-cases/agents/get-agent-session.use-case.d.ts.map +1 -1
  13. package/dist/packages/core/src/application/use-cases/agents/get-agent-session.use-case.js +4 -6
  14. package/dist/packages/core/src/application/use-cases/agents/list-agent-sessions.use-case.d.ts +1 -3
  15. package/dist/packages/core/src/application/use-cases/agents/list-agent-sessions.use-case.d.ts.map +1 -1
  16. package/dist/packages/core/src/application/use-cases/agents/list-agent-sessions.use-case.js +4 -6
  17. package/dist/packages/core/src/application/use-cases/agents/reject-agent-run.use-case.js +1 -1
  18. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts +1 -3
  19. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
  20. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +7 -9
  21. package/dist/packages/core/src/application/use-cases/features/rebase-feature-on-main.use-case.js +2 -2
  22. package/dist/packages/core/src/application/use-cases/settings/check-onboarding-status.use-case.d.ts +2 -5
  23. package/dist/packages/core/src/application/use-cases/settings/check-onboarding-status.use-case.d.ts.map +1 -1
  24. package/dist/packages/core/src/application/use-cases/settings/check-onboarding-status.use-case.js +6 -28
  25. package/dist/packages/core/src/domain/generated/output.d.ts +35 -42
  26. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  27. package/dist/packages/core/src/domain/generated/output.js +1 -7
  28. package/dist/packages/core/src/infrastructure/di/container.d.ts +0 -3
  29. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  30. package/dist/packages/core/src/infrastructure/di/container.js +501 -27
  31. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/agent-run.mapper.d.ts.map +1 -1
  32. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/agent-run.mapper.js +2 -2
  33. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts +0 -1
  34. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -1
  35. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.js +2 -6
  36. package/dist/packages/core/src/infrastructure/repositories/agent-run.repository.d.ts +0 -1
  37. package/dist/packages/core/src/infrastructure/repositories/agent-run.repository.d.ts.map +1 -1
  38. package/dist/packages/core/src/infrastructure/repositories/agent-run.repository.js +0 -8
  39. package/dist/packages/core/src/infrastructure/repositories/sqlite-phase-timing.repository.d.ts +0 -1
  40. package/dist/packages/core/src/infrastructure/repositories/sqlite-phase-timing.repository.d.ts.map +1 -1
  41. package/dist/packages/core/src/infrastructure/repositories/sqlite-phase-timing.repository.js +3 -11
  42. package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.d.ts.map +1 -1
  43. package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.js +2 -3
  44. package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-factory.service.d.ts.map +1 -1
  45. package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-factory.service.js +0 -10
  46. package/dist/packages/core/src/infrastructure/services/agents/common/agent-runner.service.d.ts.map +1 -1
  47. package/dist/packages/core/src/infrastructure/services/agents/common/agent-runner.service.js +4 -4
  48. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.d.ts +7 -3
  49. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.d.ts.map +1 -1
  50. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.js +35 -19
  51. package/dist/packages/core/src/infrastructure/services/agents/common/executors/codex-cli-executor.service.d.ts +7 -3
  52. package/dist/packages/core/src/infrastructure/services/agents/common/executors/codex-cli-executor.service.d.ts.map +1 -1
  53. package/dist/packages/core/src/infrastructure/services/agents/common/executors/codex-cli-executor.service.js +30 -17
  54. package/dist/packages/core/src/infrastructure/services/agents/common/executors/copilot-cli-executor.service.d.ts +7 -3
  55. package/dist/packages/core/src/infrastructure/services/agents/common/executors/copilot-cli-executor.service.d.ts.map +1 -1
  56. package/dist/packages/core/src/infrastructure/services/agents/common/executors/copilot-cli-executor.service.js +34 -23
  57. package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.d.ts +7 -3
  58. package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.d.ts.map +1 -1
  59. package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.js +16 -21
  60. package/dist/packages/core/src/infrastructure/services/agents/common/executors/gemini-cli-executor.service.d.ts +7 -3
  61. package/dist/packages/core/src/infrastructure/services/agents/common/executors/gemini-cli-executor.service.d.ts.map +1 -1
  62. package/dist/packages/core/src/infrastructure/services/agents/common/executors/gemini-cli-executor.service.js +33 -21
  63. package/dist/packages/core/src/infrastructure/services/agents/common/types.d.ts +0 -5
  64. package/dist/packages/core/src/infrastructure/services/agents/common/types.d.ts.map +1 -1
  65. package/dist/packages/core/src/infrastructure/services/agents/common/types.js +1 -5
  66. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts +1 -1
  67. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.js +1 -1
  68. package/dist/packages/core/src/infrastructure/services/external/github-repository.service.d.ts.map +1 -1
  69. package/dist/packages/core/src/infrastructure/services/external/github-repository.service.js +7 -16
  70. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts +47 -44
  71. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts.map +1 -1
  72. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +853 -121
  73. package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.d.ts +70 -19
  74. package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.d.ts.map +1 -1
  75. package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.js +991 -44
  76. package/dist/packages/core/src/infrastructure/services/notifications/notification-watcher.service.js +3 -3
  77. package/dist/packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.js +1 -1
  78. package/dist/src/presentation/cli/commands/agent/show.command.js +2 -3
  79. package/dist/src/presentation/cli/commands/feat/new.command.js +1 -1
  80. package/dist/src/presentation/cli/commands/feat/show.command.js +1 -1
  81. package/dist/src/presentation/tui/prompts/agent-select.prompt.d.ts.map +1 -1
  82. package/dist/src/presentation/tui/prompts/agent-select.prompt.js +0 -5
  83. package/dist/src/presentation/web/app/actions/agent-setup-flag.d.ts.map +1 -1
  84. package/dist/src/presentation/web/app/actions/agent-setup-flag.js +2 -3
  85. package/dist/src/presentation/web/app/actions/check-agent-auth.d.ts.map +1 -1
  86. package/dist/src/presentation/web/app/actions/check-agent-auth.js +2 -18
  87. package/dist/src/presentation/web/app/actions/get-all-agent-models.d.ts.map +1 -1
  88. package/dist/src/presentation/web/app/actions/get-all-agent-models.js +0 -2
  89. package/dist/src/presentation/web/app/actions/get-feature-phase-timings.d.ts.map +1 -1
  90. package/dist/src/presentation/web/app/actions/get-feature-phase-timings.js +3 -4
  91. package/dist/src/presentation/web/app/actions/get-supported-models.js +3 -2
  92. package/dist/src/presentation/web/app/actions/get-workflow-defaults.d.ts.map +1 -1
  93. package/dist/src/presentation/web/app/actions/get-workflow-defaults.js +2 -3
  94. package/dist/src/presentation/web/app/actions/open-ide.js +3 -2
  95. package/dist/src/presentation/web/app/actions/open-shell.d.ts.map +1 -1
  96. package/dist/src/presentation/web/app/actions/open-shell.js +0 -15
  97. package/dist/src/presentation/web/app/actions/update-model.d.ts.map +1 -1
  98. package/dist/src/presentation/web/app/actions/update-model.js +2 -3
  99. package/dist/src/presentation/web/app/api/agent-events/health/route.d.ts.map +1 -1
  100. package/dist/src/presentation/web/app/api/agent-events/health/route.js +12 -9
  101. package/dist/src/presentation/web/app/api/agent-events/route.d.ts +14 -7
  102. package/dist/src/presentation/web/app/api/agent-events/route.d.ts.map +1 -1
  103. package/dist/src/presentation/web/app/api/agent-events/route.js +301 -20
  104. package/dist/src/presentation/web/app/api/attachments/preview/route.d.ts.map +1 -1
  105. package/dist/src/presentation/web/app/api/attachments/preview/route.js +1 -5
  106. package/dist/src/presentation/web/app/api/attachments/upload/route.d.ts.map +1 -1
  107. package/dist/src/presentation/web/app/api/attachments/upload/route.js +2 -2
  108. package/dist/src/presentation/web/app/api/attachments/upload-from-path/route.d.ts.map +1 -1
  109. package/dist/src/presentation/web/app/api/attachments/upload-from-path/route.js +2 -2
  110. package/dist/src/presentation/web/app/api/cli-upgrade/route.d.ts.map +1 -1
  111. package/dist/src/presentation/web/app/api/cli-upgrade/route.js +1 -3
  112. package/dist/src/presentation/web/app/api/deployment-logs/route.d.ts.map +1 -1
  113. package/dist/src/presentation/web/app/api/deployment-logs/route.js +6 -2
  114. package/dist/src/presentation/web/app/api/dialog/pick-files/route.d.ts.map +1 -1
  115. package/dist/src/presentation/web/app/api/dialog/pick-files/route.js +2 -3
  116. package/dist/src/presentation/web/app/api/directory/list/route.d.ts.map +1 -1
  117. package/dist/src/presentation/web/app/api/directory/list/route.js +5 -8
  118. package/dist/src/presentation/web/app/api/feature-logs/route.d.ts.map +1 -1
  119. package/dist/src/presentation/web/app/api/feature-logs/route.js +6 -2
  120. package/dist/src/presentation/web/app/api/graph-data/route.d.ts +4 -1
  121. package/dist/src/presentation/web/app/api/graph-data/route.d.ts.map +1 -1
  122. package/dist/src/presentation/web/app/api/graph-data/route.js +2 -8
  123. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/mark-read/route.d.ts.map +1 -1
  124. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/mark-read/route.js +3 -2
  125. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/messages/route.d.ts.map +1 -1
  126. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/messages/route.js +10 -5
  127. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/respond/route.d.ts.map +1 -1
  128. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/respond/route.js +5 -5
  129. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/stop/route.d.ts.map +1 -1
  130. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/stop/route.js +3 -2
  131. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/stream/route.d.ts.map +1 -1
  132. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/stream/route.js +6 -2
  133. package/dist/src/presentation/web/app/api/interactive/chat/turn-statuses/route.d.ts.map +1 -1
  134. package/dist/src/presentation/web/app/api/interactive/chat/turn-statuses/route.js +3 -2
  135. package/dist/src/presentation/web/app/api/interactive/sessions/[id]/messages/route.d.ts.map +1 -1
  136. package/dist/src/presentation/web/app/api/interactive/sessions/[id]/messages/route.js +10 -5
  137. package/dist/src/presentation/web/app/api/interactive/sessions/[id]/route.d.ts.map +1 -1
  138. package/dist/src/presentation/web/app/api/interactive/sessions/[id]/route.js +6 -3
  139. package/dist/src/presentation/web/app/api/interactive/sessions/[id]/stream/route.d.ts.map +1 -1
  140. package/dist/src/presentation/web/app/api/interactive/sessions/[id]/stream/route.js +6 -2
  141. package/dist/src/presentation/web/app/api/interactive/sessions/route.d.ts.map +1 -1
  142. package/dist/src/presentation/web/app/api/interactive/sessions/route.js +3 -2
  143. package/dist/src/presentation/web/app/api/npm-version/route.d.ts.map +1 -1
  144. package/dist/src/presentation/web/app/api/npm-version/route.js +2 -2
  145. package/dist/src/presentation/web/app/api/sessions/route.d.ts +15 -1
  146. package/dist/src/presentation/web/app/api/sessions/route.d.ts.map +1 -1
  147. package/dist/src/presentation/web/app/api/sessions/route.js +3 -2
  148. package/dist/src/presentation/web/app/api/sessions-batch/route.d.ts +8 -1
  149. package/dist/src/presentation/web/app/api/sessions-batch/route.d.ts.map +1 -1
  150. package/dist/src/presentation/web/app/api/sessions-batch/route.js +3 -2
  151. package/dist/src/presentation/web/app/api/tools/[id]/install/route.d.ts.map +1 -1
  152. package/dist/src/presentation/web/app/api/tools/[id]/install/route.js +2 -2
  153. package/dist/src/presentation/web/app/api/tools/[id]/install/stream/route.d.ts.map +1 -1
  154. package/dist/src/presentation/web/app/api/tools/[id]/install/stream/route.js +1 -3
  155. package/dist/src/presentation/web/app/api/tools/[id]/launch/route.d.ts.map +1 -1
  156. package/dist/src/presentation/web/app/api/tools/[id]/launch/route.js +2 -2
  157. package/dist/src/presentation/web/app/api/tools/route.d.ts.map +1 -1
  158. package/dist/src/presentation/web/app/api/tools/route.js +2 -2
  159. package/dist/src/presentation/web/app/layout.d.ts.map +1 -1
  160. package/dist/src/presentation/web/app/layout.js +1 -2
  161. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.d.ts.map +1 -1
  162. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.js +0 -12
  163. package/dist/src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.d.ts.map +1 -1
  164. package/dist/src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.js +2 -2
  165. package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.d.ts.map +1 -1
  166. package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.js +1 -1
  167. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  168. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +1 -1
  169. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.d.ts +1 -1
  170. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.d.ts.map +1 -1
  171. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.js +0 -2
  172. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.stories.d.ts.map +1 -1
  173. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.stories.js +0 -1
  174. package/dist/src/presentation/web/components/features/chat/ChatSheet.d.ts.map +1 -1
  175. package/dist/src/presentation/web/components/features/chat/ChatSheet.js +1 -1
  176. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/index.d.ts.map +1 -1
  177. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/index.js +3 -7
  178. package/dist/src/presentation/web/components/features/settings/ModelPicker/index.d.ts.map +1 -1
  179. package/dist/src/presentation/web/components/features/settings/ModelPicker/index.js +2 -2
  180. package/dist/src/presentation/web/components/features/settings/agent-settings-section.d.ts.map +1 -1
  181. package/dist/src/presentation/web/components/features/settings/agent-settings-section.js +0 -1
  182. package/dist/src/presentation/web/hooks/use-agent-events.js +1 -5
  183. package/dist/src/presentation/web/lib/is-same-shep-instance.d.ts.map +1 -1
  184. package/dist/src/presentation/web/lib/is-same-shep-instance.js +5 -2
  185. package/dist/translations/ar/common.json +1 -0
  186. package/dist/translations/ar/tui.json +0 -4
  187. package/dist/translations/ar/web.json +0 -1
  188. package/dist/translations/de/common.json +1 -0
  189. package/dist/translations/de/tui.json +0 -1
  190. package/dist/translations/de/web.json +0 -1
  191. package/dist/translations/en/common.json +1 -0
  192. package/dist/translations/en/tui.json +0 -4
  193. package/dist/translations/en/web.json +0 -1
  194. package/dist/translations/es/common.json +1 -0
  195. package/dist/translations/es/tui.json +0 -4
  196. package/dist/translations/es/web.json +0 -1
  197. package/dist/translations/fr/common.json +1 -0
  198. package/dist/translations/fr/tui.json +0 -4
  199. package/dist/translations/fr/web.json +0 -1
  200. package/dist/translations/he/common.json +1 -0
  201. package/dist/translations/he/tui.json +0 -4
  202. package/dist/translations/he/web.json +0 -1
  203. package/dist/translations/pt/common.json +1 -0
  204. package/dist/translations/pt/tui.json +0 -4
  205. package/dist/translations/pt/web.json +0 -1
  206. package/dist/translations/ru/common.json +1 -0
  207. package/dist/translations/ru/tui.json +0 -4
  208. package/dist/translations/ru/web.json +0 -1
  209. package/dist/translations/uk/cli.json +631 -0
  210. package/dist/translations/uk/common.json +56 -0
  211. package/dist/translations/uk/tui.json +134 -0
  212. package/dist/translations/uk/web.json +615 -0
  213. package/dist/tsconfig.build.tsbuildinfo +1 -1
  214. package/package.json +3 -7
  215. package/web/.next/BUILD_ID +1 -1
  216. package/web/.next/build-manifest.json +2 -2
  217. package/web/.next/fallback-build-manifest.json +2 -2
  218. package/web/.next/prerender-manifest.json +3 -3
  219. package/web/.next/required-server-files.js +2 -2
  220. package/web/.next/required-server-files.json +2 -2
  221. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +58 -73
  222. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +5 -5
  223. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  224. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  225. package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +54 -69
  226. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js +5 -5
  227. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
  228. package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
  229. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +60 -75
  230. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +5 -5
  231. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  232. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  233. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +76 -91
  234. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +5 -5
  235. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  236. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  237. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +76 -91
  238. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +5 -5
  239. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  240. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  241. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +56 -71
  242. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js +5 -5
  243. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  244. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  245. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +56 -71
  246. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +5 -5
  247. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  248. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  249. package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +54 -69
  250. package/web/.next/server/app/(dashboard)/chat/page.js +5 -5
  251. package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  252. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  253. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +60 -75
  254. package/web/.next/server/app/(dashboard)/create/page.js +5 -5
  255. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  256. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  257. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +76 -91
  258. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +5 -5
  259. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  260. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  261. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +76 -91
  262. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +5 -5
  263. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  264. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  265. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +54 -69
  266. package/web/.next/server/app/(dashboard)/page.js +5 -5
  267. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  268. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  269. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +56 -71
  270. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js +5 -5
  271. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  272. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  273. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +56 -71
  274. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +5 -5
  275. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  276. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  277. package/web/.next/server/app/_global-error/page.js +1 -1
  278. package/web/.next/server/app/_global-error/page.js.nft.json +1 -1
  279. package/web/.next/server/app/_global-error.html +2 -2
  280. package/web/.next/server/app/_global-error.rsc +1 -1
  281. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  282. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  283. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  284. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  285. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  286. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +12 -27
  287. package/web/.next/server/app/_not-found/page.js +3 -3
  288. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  289. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  290. package/web/.next/server/app/api/agent-events/route.js +2 -2
  291. package/web/.next/server/app/api/agent-events/route.js.nft.json +1 -1
  292. package/web/.next/server/app/api/attachments/preview/route.js +1 -1
  293. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  294. package/web/.next/server/app/api/attachments/upload/route.js +1 -1
  295. package/web/.next/server/app/api/attachments/upload/route.js.nft.json +1 -1
  296. package/web/.next/server/app/api/attachments/upload-from-path/route.js +1 -1
  297. package/web/.next/server/app/api/attachments/upload-from-path/route.js.nft.json +1 -1
  298. package/web/.next/server/app/api/deployment-logs/route.js +1 -2
  299. package/web/.next/server/app/api/deployment-logs/route.js.nft.json +1 -1
  300. package/web/.next/server/app/api/directory/list/route.js +1 -1
  301. package/web/.next/server/app/api/directory/list/route.js.nft.json +1 -1
  302. package/web/.next/server/app/api/evidence/route.js +1 -1
  303. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  304. package/web/.next/server/app/api/feature-logs/route.js +1 -2
  305. package/web/.next/server/app/api/feature-logs/route.js.nft.json +1 -1
  306. package/web/.next/server/app/api/graph-data/route.js +1 -1
  307. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  308. package/web/.next/server/app/api/interactive/chat/[featureId]/mark-read/route.js +1 -1
  309. package/web/.next/server/app/api/interactive/chat/[featureId]/mark-read/route.js.nft.json +1 -1
  310. package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js +1 -1
  311. package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
  312. package/web/.next/server/app/api/interactive/chat/[featureId]/respond/route.js +1 -1
  313. package/web/.next/server/app/api/interactive/chat/[featureId]/respond/route.js.nft.json +1 -1
  314. package/web/.next/server/app/api/interactive/chat/[featureId]/stop/route.js +1 -1
  315. package/web/.next/server/app/api/interactive/chat/[featureId]/stop/route.js.nft.json +1 -1
  316. package/web/.next/server/app/api/interactive/chat/[featureId]/stream/route.js +1 -2
  317. package/web/.next/server/app/api/interactive/chat/[featureId]/stream/route.js.nft.json +1 -1
  318. package/web/.next/server/app/api/interactive/chat/turn-statuses/route.js +1 -1
  319. package/web/.next/server/app/api/interactive/chat/turn-statuses/route.js.nft.json +1 -1
  320. package/web/.next/server/app/api/interactive/sessions/[id]/messages/route.js +1 -1
  321. package/web/.next/server/app/api/interactive/sessions/[id]/messages/route.js.nft.json +1 -1
  322. package/web/.next/server/app/api/interactive/sessions/[id]/route.js +1 -1
  323. package/web/.next/server/app/api/interactive/sessions/[id]/route.js.nft.json +1 -1
  324. package/web/.next/server/app/api/interactive/sessions/[id]/stream/route.js +1 -2
  325. package/web/.next/server/app/api/interactive/sessions/[id]/stream/route.js.nft.json +1 -1
  326. package/web/.next/server/app/api/interactive/sessions/route.js +1 -1
  327. package/web/.next/server/app/api/interactive/sessions/route.js.nft.json +1 -1
  328. package/web/.next/server/app/api/npm-version/route.js +1 -1
  329. package/web/.next/server/app/api/npm-version/route.js.nft.json +1 -1
  330. package/web/.next/server/app/api/sessions/route.js +1 -1
  331. package/web/.next/server/app/api/sessions/route.js.nft.json +1 -1
  332. package/web/.next/server/app/api/sessions-batch/route.js +1 -1
  333. package/web/.next/server/app/api/sessions-batch/route.js.nft.json +1 -1
  334. package/web/.next/server/app/api/tools/[id]/install/route.js +1 -1
  335. package/web/.next/server/app/api/tools/[id]/install/route.js.nft.json +1 -1
  336. package/web/.next/server/app/api/tools/[id]/launch/route.js +1 -1
  337. package/web/.next/server/app/api/tools/[id]/launch/route.js.nft.json +1 -1
  338. package/web/.next/server/app/api/tools/route.js +1 -1
  339. package/web/.next/server/app/api/tools/route.js.nft.json +1 -1
  340. package/web/.next/server/app/features/page/server-reference-manifest.json +12 -27
  341. package/web/.next/server/app/features/page.js +3 -3
  342. package/web/.next/server/app/features/page.js.nft.json +1 -1
  343. package/web/.next/server/app/features/page_client-reference-manifest.js +1 -1
  344. package/web/.next/server/app/settings/page/server-reference-manifest.json +18 -33
  345. package/web/.next/server/app/settings/page.js +3 -4
  346. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  347. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  348. package/web/.next/server/app/skills/page/server-reference-manifest.json +26 -41
  349. package/web/.next/server/app/skills/page.js +4 -4
  350. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  351. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  352. package/web/.next/server/app/tools/page/server-reference-manifest.json +22 -37
  353. package/web/.next/server/app/tools/page.js +4 -4
  354. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  355. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  356. package/web/.next/server/app/version/page/server-reference-manifest.json +12 -27
  357. package/web/.next/server/app/version/page.js +4 -4
  358. package/web/.next/server/app/version/page.js.nft.json +1 -1
  359. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  360. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +1 -1
  361. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +1 -1
  362. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js +12 -0
  363. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js.map +1 -0
  364. package/web/.next/server/chunks/[root-of-the-server]__0866d2b5._.js +3 -0
  365. package/web/.next/server/chunks/[root-of-the-server]__0866d2b5._.js.map +1 -0
  366. package/web/.next/server/chunks/[root-of-the-server]__10852c5c._.js +3 -0
  367. package/web/.next/server/chunks/[root-of-the-server]__10852c5c._.js.map +1 -0
  368. package/web/.next/server/chunks/[root-of-the-server]__2b1074db._.js +12 -0
  369. package/web/.next/server/chunks/[root-of-the-server]__2b1074db._.js.map +1 -0
  370. package/web/.next/server/chunks/[root-of-the-server]__2b71641f._.js +3 -0
  371. package/web/.next/server/chunks/[root-of-the-server]__2b71641f._.js.map +1 -0
  372. package/web/.next/server/chunks/[root-of-the-server]__2bb675ff._.js +3 -0
  373. package/web/.next/server/chunks/[root-of-the-server]__2bb675ff._.js.map +1 -0
  374. package/web/.next/server/chunks/[root-of-the-server]__2f61738a._.js +3 -0
  375. package/web/.next/server/chunks/[root-of-the-server]__2f61738a._.js.map +1 -0
  376. package/web/.next/server/chunks/[root-of-the-server]__31598852._.js +3 -0
  377. package/web/.next/server/chunks/[root-of-the-server]__31598852._.js.map +1 -0
  378. package/web/.next/server/chunks/[root-of-the-server]__31944fa2._.js +3 -0
  379. package/web/.next/server/chunks/[root-of-the-server]__31944fa2._.js.map +1 -0
  380. package/web/.next/server/chunks/[root-of-the-server]__32b04219._.js +3 -0
  381. package/web/.next/server/chunks/[root-of-the-server]__32b04219._.js.map +1 -0
  382. package/web/.next/server/chunks/[root-of-the-server]__332c8d91._.js +1 -1
  383. package/web/.next/server/chunks/[root-of-the-server]__332c8d91._.js.map +1 -1
  384. package/web/.next/server/chunks/[root-of-the-server]__3b72e8b0._.js +3 -0
  385. package/web/.next/server/chunks/[root-of-the-server]__3b72e8b0._.js.map +1 -0
  386. package/web/.next/server/chunks/[root-of-the-server]__4408a5ba._.js +12 -0
  387. package/web/.next/server/chunks/[root-of-the-server]__4408a5ba._.js.map +1 -0
  388. package/web/.next/server/chunks/[root-of-the-server]__6565a045._.js +3 -0
  389. package/web/.next/server/chunks/[root-of-the-server]__6565a045._.js.map +1 -0
  390. package/web/.next/server/chunks/[root-of-the-server]__8a281f8d._.js +24 -0
  391. package/web/.next/server/chunks/[root-of-the-server]__8a281f8d._.js.map +1 -0
  392. package/web/.next/server/chunks/[root-of-the-server]__8f8d6afe._.js +3 -0
  393. package/web/.next/server/chunks/[root-of-the-server]__8f8d6afe._.js.map +1 -0
  394. package/web/.next/server/chunks/[root-of-the-server]__9191749c._.js +3 -0
  395. package/web/.next/server/chunks/[root-of-the-server]__9191749c._.js.map +1 -0
  396. package/web/.next/server/chunks/[root-of-the-server]__9a136c79._.js +9 -0
  397. package/web/.next/server/chunks/[root-of-the-server]__9a136c79._.js.map +1 -0
  398. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  399. package/web/.next/server/chunks/[root-of-the-server]__ab4951b1._.js +3 -0
  400. package/web/.next/server/chunks/[root-of-the-server]__ab4951b1._.js.map +1 -0
  401. package/web/.next/server/chunks/[root-of-the-server]__acea6565._.js +3 -0
  402. package/web/.next/server/chunks/[root-of-the-server]__acea6565._.js.map +1 -0
  403. package/web/.next/server/chunks/[root-of-the-server]__b2f9a412._.js +3 -0
  404. package/web/.next/server/chunks/{[root-of-the-server]__f1aeae12._.js.map → [root-of-the-server]__b2f9a412._.js.map} +1 -1
  405. package/web/.next/server/chunks/[root-of-the-server]__b4102cc7._.js +3 -0
  406. package/web/.next/server/chunks/[root-of-the-server]__b4102cc7._.js.map +1 -0
  407. package/web/.next/server/chunks/[root-of-the-server]__c78383b1._.js +3 -0
  408. package/web/.next/server/chunks/[root-of-the-server]__c78383b1._.js.map +1 -0
  409. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js +3 -0
  410. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js.map +1 -0
  411. package/web/.next/server/chunks/[root-of-the-server]__d2c18946._.js +3 -3
  412. package/web/.next/server/chunks/[root-of-the-server]__d2c18946._.js.map +1 -1
  413. package/web/.next/server/chunks/[root-of-the-server]__d9d410a8._.js +1 -1
  414. package/web/.next/server/chunks/[root-of-the-server]__d9d410a8._.js.map +1 -1
  415. package/web/.next/server/chunks/[root-of-the-server]__e247a485._.js +3 -3
  416. package/web/.next/server/chunks/[root-of-the-server]__e247a485._.js.map +1 -1
  417. package/web/.next/server/chunks/{[root-of-the-server]__937ba94e._.js → [root-of-the-server]__e3692208._.js} +2 -2
  418. package/web/.next/server/chunks/[root-of-the-server]__ea653642._.js +3 -0
  419. package/web/.next/server/chunks/[root-of-the-server]__ea653642._.js.map +1 -0
  420. package/web/.next/server/chunks/[root-of-the-server]__fc6fd958._.js +3 -0
  421. package/web/.next/server/chunks/[root-of-the-server]__fc6fd958._.js.map +1 -0
  422. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_ad0071c9.js +3 -0
  423. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_ad0071c9.js.map +1 -0
  424. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_90d98b2b.js +3 -0
  425. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_90d98b2b.js.map +1 -0
  426. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_chat_page_actions_d3828105.js +3 -0
  427. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_chat_page_actions_d3828105.js.map +1 -0
  428. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  429. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  430. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js +2 -2
  431. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js.map +1 -1
  432. package/web/.next/server/chunks/ssr/[root-of-the-server]__1cd4327c._.js +4 -0
  433. package/web/.next/server/chunks/ssr/[root-of-the-server]__1cd4327c._.js.map +1 -0
  434. package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js +4 -0
  435. package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js.map +1 -0
  436. package/web/.next/server/chunks/ssr/{[root-of-the-server]__08e7a080._.js → [root-of-the-server]__22d17c66._.js} +2 -2
  437. package/web/.next/server/chunks/ssr/{[root-of-the-server]__08e7a080._.js.map → [root-of-the-server]__22d17c66._.js.map} +1 -1
  438. package/web/.next/server/chunks/ssr/[root-of-the-server]__23b5ca2c._.js +1 -1
  439. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +3 -0
  440. package/web/.next/server/chunks/ssr/{[root-of-the-server]__ff332bfb._.js.map → [root-of-the-server]__357d99f9._.js.map} +1 -1
  441. package/web/.next/server/chunks/ssr/[root-of-the-server]__51ec77a8._.js +3 -0
  442. package/web/.next/server/chunks/ssr/[root-of-the-server]__51ec77a8._.js.map +1 -0
  443. package/web/.next/server/chunks/ssr/[root-of-the-server]__540c615f._.js +4 -0
  444. package/web/.next/server/chunks/ssr/[root-of-the-server]__540c615f._.js.map +1 -0
  445. package/web/.next/server/chunks/ssr/[root-of-the-server]__66047a1b._.js +3 -0
  446. package/web/.next/server/chunks/ssr/[root-of-the-server]__66047a1b._.js.map +1 -0
  447. package/web/.next/server/chunks/ssr/{[root-of-the-server]__16c1388b._.js → [root-of-the-server]__69dd3217._.js} +2 -2
  448. package/web/.next/server/chunks/ssr/{[root-of-the-server]__16c1388b._.js.map → [root-of-the-server]__69dd3217._.js.map} +1 -1
  449. package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js +4 -0
  450. package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js.map +1 -0
  451. package/web/.next/server/chunks/ssr/[root-of-the-server]__7528eb6f._.js +1 -1
  452. package/web/.next/server/chunks/ssr/[root-of-the-server]__a932cd3a._.js +3 -0
  453. package/web/.next/server/chunks/ssr/[root-of-the-server]__a932cd3a._.js.map +1 -0
  454. package/web/.next/server/chunks/ssr/[root-of-the-server]__aa72e794._.js +3 -0
  455. package/web/.next/server/chunks/ssr/[root-of-the-server]__aa72e794._.js.map +1 -0
  456. package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js +4 -0
  457. package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js.map +1 -0
  458. package/web/.next/server/chunks/ssr/[root-of-the-server]__d1040bd1._.js +3 -0
  459. package/web/.next/server/chunks/ssr/{[root-of-the-server]__f5614810._.js.map → [root-of-the-server]__d1040bd1._.js.map} +1 -1
  460. package/web/.next/server/chunks/ssr/[root-of-the-server]__efeeaed4._.js +3 -0
  461. package/web/.next/server/chunks/ssr/{[root-of-the-server]__d5e22d1a._.js.map → [root-of-the-server]__efeeaed4._.js.map} +1 -1
  462. package/web/.next/server/chunks/ssr/_05c23ad9._.js +1 -1
  463. package/web/.next/server/chunks/ssr/_05c23ad9._.js.map +1 -1
  464. package/web/.next/server/chunks/ssr/_16eb4fec._.js +1 -1
  465. package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -1
  466. package/web/.next/server/chunks/ssr/{_5747febb._.js → _1e08a336._.js} +2 -2
  467. package/web/.next/server/chunks/ssr/_1e08a336._.js.map +1 -0
  468. package/web/.next/server/chunks/ssr/{_ed2f2799._.js → _295fffde._.js} +2 -2
  469. package/web/.next/server/chunks/ssr/_295fffde._.js.map +1 -0
  470. package/web/.next/server/chunks/ssr/{_4db4ac1e._.js → _388d1127._.js} +2 -2
  471. package/web/.next/server/chunks/ssr/{_4db4ac1e._.js.map → _388d1127._.js.map} +1 -1
  472. package/web/.next/server/chunks/ssr/_45496654._.js +1 -1
  473. package/web/.next/server/chunks/ssr/_45496654._.js.map +1 -1
  474. package/web/.next/server/chunks/ssr/_4cbb7f95._.js +1 -1
  475. package/web/.next/server/chunks/ssr/_4cbb7f95._.js.map +1 -1
  476. package/web/.next/server/chunks/ssr/_56b9d60f._.js +1 -1
  477. package/web/.next/server/chunks/ssr/_56b9d60f._.js.map +1 -1
  478. package/web/.next/server/chunks/ssr/_6abfa39e._.js +1 -1
  479. package/web/.next/server/chunks/ssr/_6abfa39e._.js.map +1 -1
  480. package/web/.next/server/chunks/ssr/{_080b0309._.js → _8f0d3f07._.js} +2 -2
  481. package/web/.next/server/chunks/ssr/{_080b0309._.js.map → _8f0d3f07._.js.map} +1 -1
  482. package/web/.next/server/chunks/ssr/{_31b68712._.js → _98d94927._.js} +2 -2
  483. package/web/.next/server/chunks/ssr/{_31b68712._.js.map → _98d94927._.js.map} +1 -1
  484. package/web/.next/server/chunks/ssr/{_819f193a._.js → _d9c0a97a._.js} +2 -2
  485. package/web/.next/server/chunks/ssr/_d9c0a97a._.js.map +1 -0
  486. package/web/.next/server/chunks/ssr/_e680c57c._.js.map +1 -1
  487. package/web/.next/server/chunks/ssr/_f8c55130._.js +1 -1
  488. package/web/.next/server/chunks/ssr/_f8c55130._.js.map +1 -1
  489. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  490. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  491. package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js +1 -1
  492. package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js.map +1 -1
  493. package/web/.next/server/chunks/ssr/src_presentation_web_17d39233._.js +3 -0
  494. package/web/.next/server/chunks/ssr/src_presentation_web_17d39233._.js.map +1 -0
  495. package/web/.next/server/chunks/ssr/src_presentation_web_54b02639._.js +5 -0
  496. package/web/.next/server/chunks/ssr/src_presentation_web_54b02639._.js.map +1 -0
  497. package/web/.next/server/chunks/ssr/src_presentation_web_7b7b9e3b._.js +5 -0
  498. package/web/.next/server/chunks/ssr/src_presentation_web_7b7b9e3b._.js.map +1 -0
  499. package/web/.next/server/chunks/ssr/src_presentation_web_807cba76._.js +3 -0
  500. package/web/.next/server/chunks/ssr/src_presentation_web_807cba76._.js.map +1 -0
  501. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_90b5e66e.js +3 -0
  502. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_90b5e66e.js.map +1 -0
  503. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_4ce30db7.js +3 -0
  504. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_4ce30db7.js.map +1 -0
  505. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_e4032193.js +3 -0
  506. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_e4032193.js.map +1 -0
  507. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
  508. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js.map +1 -1
  509. package/web/.next/server/chunks/ssr/{src_presentation_web_components_349d9f24._.js → src_presentation_web_components_895e5bfa._.js} +2 -2
  510. package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js.map +1 -0
  511. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  512. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  513. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js +1 -1
  514. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js.map +1 -1
  515. package/web/.next/server/chunks/ssr/src_presentation_web_e1cd1869._.js +3 -0
  516. package/web/.next/server/chunks/ssr/src_presentation_web_e1cd1869._.js.map +1 -0
  517. package/web/.next/server/chunks/ssr/src_presentation_web_e3a30e30._.js +3 -0
  518. package/web/.next/server/chunks/ssr/src_presentation_web_e3a30e30._.js.map +1 -0
  519. package/web/.next/server/chunks/ssr/translations_23dd5e7e._.js +1 -1
  520. package/web/.next/server/chunks/ssr/translations_23dd5e7e._.js.map +1 -1
  521. package/web/.next/server/pages/500.html +2 -2
  522. package/web/.next/server/server-reference-manifest.js +1 -1
  523. package/web/.next/server/server-reference-manifest.json +535 -683
  524. package/web/.next/static/chunks/{10383f321355e09b.js → 0ffb3738269e15c3.js} +1 -1
  525. package/web/.next/static/chunks/236744ff71b1aadf.js +1 -0
  526. package/web/.next/static/chunks/{05c0a8ed7621ea2a.js → 2cfc6022d74e2716.js} +3 -3
  527. package/web/.next/static/chunks/302f474e4978cc80.js +3 -0
  528. package/web/.next/static/chunks/{316b0e4597f2083d.js → 46e2693dbc9262fd.js} +2 -2
  529. package/web/.next/static/chunks/{6853929058e53d1a.js → 476873a9bac35ec8.js} +1 -1
  530. package/web/.next/static/chunks/{81347e69998eef38.js → 4ff21d16947ec853.js} +1 -1
  531. package/web/.next/static/chunks/626277ca9a4cc477.js +1 -0
  532. package/web/.next/static/chunks/{a1ad19e21b6ad1ad.js → 6304540c7cf2b46a.js} +2 -2
  533. package/web/.next/static/chunks/{fd319c0e5f3cc20a.js → 71a07df9dcb42227.js} +1 -1
  534. package/web/.next/static/chunks/{71ad5a4155ddd207.js → 885bb8fc631bf477.js} +1 -1
  535. package/web/.next/static/chunks/a20f2d6f76f469b7.css +1 -0
  536. package/web/.next/static/chunks/{8bf91dcd1b3077d7.js → afa7e5d2a48cabc7.js} +1 -1
  537. package/web/.next/static/chunks/c10c0d6d458453bc.js +1 -0
  538. package/web/.next/static/chunks/{8a68402c32c6a206.js → e8444bf5f6c35f8b.js} +1 -1
  539. package/web/.next/static/chunks/eab3d361f7a24510.js +1 -0
  540. package/web/.next/static/chunks/{6bfcb5d1b3eafd81.js → eda9ee3c22b71a69.js} +1 -1
  541. package/web/.next/static/chunks/{e610f5d703696b34.js → f17d2d0279b8db35.js} +1 -1
  542. package/web/.next/static/chunks/f9d948464ed409cb.js +1 -0
  543. package/apis/json-schema/PermissionMode.yaml +0 -8
  544. package/dist/packages/core/src/application/ports/output/services/file-system.interface.d.ts +0 -68
  545. package/dist/packages/core/src/application/ports/output/services/file-system.interface.d.ts.map +0 -1
  546. package/dist/packages/core/src/application/ports/output/services/file-system.interface.js +0 -12
  547. package/dist/packages/core/src/application/ports/output/services/process-monitor.interface.d.ts +0 -29
  548. package/dist/packages/core/src/application/ports/output/services/process-monitor.interface.d.ts.map +0 -1
  549. package/dist/packages/core/src/application/ports/output/services/process-monitor.interface.js +0 -12
  550. package/dist/packages/core/src/application/ports/output/services/settings-reader.interface.d.ts +0 -35
  551. package/dist/packages/core/src/application/ports/output/services/settings-reader.interface.d.ts.map +0 -1
  552. package/dist/packages/core/src/application/ports/output/services/settings-reader.interface.js +0 -12
  553. package/dist/packages/core/src/application/use-cases/notifications/poll-agent-events.use-case.d.ts +0 -61
  554. package/dist/packages/core/src/application/use-cases/notifications/poll-agent-events.use-case.d.ts.map +0 -1
  555. package/dist/packages/core/src/application/use-cases/notifications/poll-agent-events.use-case.js +0 -381
  556. package/dist/packages/core/src/infrastructure/di/modules/agent-infrastructure.module.d.ts +0 -7
  557. package/dist/packages/core/src/infrastructure/di/modules/agent-infrastructure.module.d.ts.map +0 -1
  558. package/dist/packages/core/src/infrastructure/di/modules/agent-infrastructure.module.js +0 -83
  559. package/dist/packages/core/src/infrastructure/di/modules/database.module.d.ts +0 -12
  560. package/dist/packages/core/src/infrastructure/di/modules/database.module.d.ts.map +0 -1
  561. package/dist/packages/core/src/infrastructure/di/modules/database.module.js +0 -16
  562. package/dist/packages/core/src/infrastructure/di/modules/interactive.module.d.ts +0 -10
  563. package/dist/packages/core/src/infrastructure/di/modules/interactive.module.d.ts.map +0 -1
  564. package/dist/packages/core/src/infrastructure/di/modules/interactive.module.js +0 -43
  565. package/dist/packages/core/src/infrastructure/di/modules/notifications.module.d.ts +0 -6
  566. package/dist/packages/core/src/infrastructure/di/modules/notifications.module.d.ts.map +0 -1
  567. package/dist/packages/core/src/infrastructure/di/modules/notifications.module.js +0 -20
  568. package/dist/packages/core/src/infrastructure/di/modules/repositories.module.d.ts +0 -6
  569. package/dist/packages/core/src/infrastructure/di/modules/repositories.module.d.ts.map +0 -1
  570. package/dist/packages/core/src/infrastructure/di/modules/repositories.module.js +0 -26
  571. package/dist/packages/core/src/infrastructure/di/modules/services.module.d.ts +0 -8
  572. package/dist/packages/core/src/infrastructure/di/modules/services.module.d.ts.map +0 -1
  573. package/dist/packages/core/src/infrastructure/di/modules/services.module.js +0 -93
  574. package/dist/packages/core/src/infrastructure/di/modules/use-cases.module.d.ts +0 -6
  575. package/dist/packages/core/src/infrastructure/di/modules/use-cases.module.d.ts.map +0 -1
  576. package/dist/packages/core/src/infrastructure/di/modules/use-cases.module.js +0 -164
  577. package/dist/packages/core/src/infrastructure/di/modules/web-tokens.module.d.ts +0 -10
  578. package/dist/packages/core/src/infrastructure/di/modules/web-tokens.module.d.ts.map +0 -1
  579. package/dist/packages/core/src/infrastructure/di/modules/web-tokens.module.js +0 -200
  580. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/056-add-agent-permission-mode.d.ts +0 -14
  581. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/056-add-agent-permission-mode.d.ts.map +0 -1
  582. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/056-add-agent-permission-mode.js +0 -19
  583. package/dist/packages/core/src/infrastructure/services/agents/common/executors/abstract-agent-executor.d.ts +0 -37
  584. package/dist/packages/core/src/infrastructure/services/agents/common/executors/abstract-agent-executor.d.ts.map +0 -1
  585. package/dist/packages/core/src/infrastructure/services/agents/common/executors/abstract-agent-executor.js +0 -59
  586. package/dist/packages/core/src/infrastructure/services/agents/common/executors/rovo-dev-executor.service.d.ts +0 -52
  587. package/dist/packages/core/src/infrastructure/services/agents/common/executors/rovo-dev-executor.service.d.ts.map +0 -1
  588. package/dist/packages/core/src/infrastructure/services/agents/common/executors/rovo-dev-executor.service.js +0 -350
  589. package/dist/packages/core/src/infrastructure/services/filesystem/file-system.service.d.ts +0 -26
  590. package/dist/packages/core/src/infrastructure/services/filesystem/file-system.service.d.ts.map +0 -1
  591. package/dist/packages/core/src/infrastructure/services/filesystem/file-system.service.js +0 -47
  592. package/dist/packages/core/src/infrastructure/services/filesystem/path-sanitizers.d.ts +0 -19
  593. package/dist/packages/core/src/infrastructure/services/filesystem/path-sanitizers.d.ts.map +0 -1
  594. package/dist/packages/core/src/infrastructure/services/filesystem/path-sanitizers.js +0 -38
  595. package/dist/packages/core/src/infrastructure/services/git/branch-discovery.service.d.ts +0 -23
  596. package/dist/packages/core/src/infrastructure/services/git/branch-discovery.service.d.ts.map +0 -1
  597. package/dist/packages/core/src/infrastructure/services/git/branch-discovery.service.js +0 -185
  598. package/dist/packages/core/src/infrastructure/services/git/ci-status.service.d.ts +0 -24
  599. package/dist/packages/core/src/infrastructure/services/git/ci-status.service.d.ts.map +0 -1
  600. package/dist/packages/core/src/infrastructure/services/git/ci-status.service.js +0 -202
  601. package/dist/packages/core/src/infrastructure/services/git/diff-analyzer.service.d.ts +0 -19
  602. package/dist/packages/core/src/infrastructure/services/git/diff-analyzer.service.d.ts.map +0 -1
  603. package/dist/packages/core/src/infrastructure/services/git/diff-analyzer.service.js +0 -173
  604. package/dist/packages/core/src/infrastructure/services/git/merge-strategy.service.d.ts +0 -30
  605. package/dist/packages/core/src/infrastructure/services/git/merge-strategy.service.d.ts.map +0 -1
  606. package/dist/packages/core/src/infrastructure/services/git/merge-strategy.service.js +0 -341
  607. package/dist/packages/core/src/infrastructure/services/git/pr-creation.service.d.ts +0 -34
  608. package/dist/packages/core/src/infrastructure/services/git/pr-creation.service.d.ts.map +0 -1
  609. package/dist/packages/core/src/infrastructure/services/git/pr-creation.service.js +0 -180
  610. package/dist/packages/core/src/infrastructure/services/interactive/chat-state-builder.d.ts +0 -21
  611. package/dist/packages/core/src/infrastructure/services/interactive/chat-state-builder.d.ts.map +0 -1
  612. package/dist/packages/core/src/infrastructure/services/interactive/chat-state-builder.js +0 -112
  613. package/dist/packages/core/src/infrastructure/services/interactive/session-boot-sequence.d.ts +0 -47
  614. package/dist/packages/core/src/infrastructure/services/interactive/session-boot-sequence.d.ts.map +0 -1
  615. package/dist/packages/core/src/infrastructure/services/interactive/session-boot-sequence.js +0 -381
  616. package/dist/packages/core/src/infrastructure/services/interactive/session-state-manager.d.ts +0 -28
  617. package/dist/packages/core/src/infrastructure/services/interactive/session-state-manager.d.ts.map +0 -1
  618. package/dist/packages/core/src/infrastructure/services/interactive/session-state-manager.js +0 -105
  619. package/dist/packages/core/src/infrastructure/services/interactive/session-state.d.ts +0 -46
  620. package/dist/packages/core/src/infrastructure/services/interactive/session-state.d.ts.map +0 -1
  621. package/dist/packages/core/src/infrastructure/services/interactive/session-state.js +0 -10
  622. package/dist/packages/core/src/infrastructure/services/interactive/subscriber-notifier.d.ts +0 -36
  623. package/dist/packages/core/src/infrastructure/services/interactive/subscriber-notifier.d.ts.map +0 -1
  624. package/dist/packages/core/src/infrastructure/services/interactive/subscriber-notifier.js +0 -60
  625. package/dist/packages/core/src/infrastructure/services/interactive/turn-executor.d.ts +0 -57
  626. package/dist/packages/core/src/infrastructure/services/interactive/turn-executor.d.ts.map +0 -1
  627. package/dist/packages/core/src/infrastructure/services/interactive/turn-executor.js +0 -503
  628. package/dist/packages/core/src/infrastructure/services/process/process-monitor.service.d.ts +0 -25
  629. package/dist/packages/core/src/infrastructure/services/process/process-monitor.service.d.ts.map +0 -1
  630. package/dist/packages/core/src/infrastructure/services/process/process-monitor.service.js +0 -45
  631. package/dist/packages/core/src/infrastructure/services/settings-reader.adapter.d.ts +0 -15
  632. package/dist/packages/core/src/infrastructure/services/settings-reader.adapter.d.ts.map +0 -1
  633. package/dist/packages/core/src/infrastructure/services/settings-reader.adapter.js +0 -28
  634. package/dist/src/presentation/web/app/actions/check-agent-auth-for-type.d.ts +0 -11
  635. package/dist/src/presentation/web/app/actions/check-agent-auth-for-type.d.ts.map +0 -1
  636. package/dist/src/presentation/web/app/actions/check-agent-auth-for-type.js +0 -147
  637. package/dist/src/presentation/web/components/common/route-announcer.d.ts +0 -2
  638. package/dist/src/presentation/web/components/common/route-announcer.d.ts.map +0 -1
  639. package/dist/src/presentation/web/components/common/route-announcer.js +0 -7
  640. package/dist/src/presentation/web/components/features/settings/AgentAvailabilityBadge.d.ts +0 -7
  641. package/dist/src/presentation/web/components/features/settings/AgentAvailabilityBadge.d.ts.map +0 -1
  642. package/dist/src/presentation/web/components/features/settings/AgentAvailabilityBadge.js +0 -26
  643. package/dist/src/presentation/web/components/features/settings/AgentAvailabilityBadge.stories.d.ts +0 -11
  644. package/dist/src/presentation/web/components/features/settings/AgentAvailabilityBadge.stories.d.ts.map +0 -1
  645. package/dist/src/presentation/web/components/features/settings/AgentAvailabilityBadge.stories.js +0 -24
  646. package/dist/src/presentation/web/hooks/use-agent-availability.d.ts +0 -13
  647. package/dist/src/presentation/web/hooks/use-agent-availability.d.ts.map +0 -1
  648. package/dist/src/presentation/web/hooks/use-agent-availability.js +0 -75
  649. package/dist/src/presentation/web/hooks/use-route-announcer.d.ts +0 -2
  650. package/dist/src/presentation/web/hooks/use-route-announcer.d.ts.map +0 -1
  651. package/dist/src/presentation/web/hooks/use-route-announcer.js +0 -16
  652. package/dist/src/presentation/web/lib/api-error.d.ts +0 -7
  653. package/dist/src/presentation/web/lib/api-error.d.ts.map +0 -1
  654. package/dist/src/presentation/web/lib/api-error.js +0 -11
  655. package/web/.next/server/chunks/[root-of-the-server]__0b88f5f0._.js +0 -3
  656. package/web/.next/server/chunks/[root-of-the-server]__0b88f5f0._.js.map +0 -1
  657. package/web/.next/server/chunks/[root-of-the-server]__0d0a9973._.js +0 -3
  658. package/web/.next/server/chunks/[root-of-the-server]__0d0a9973._.js.map +0 -1
  659. package/web/.next/server/chunks/[root-of-the-server]__1f18a881._.js +0 -3
  660. package/web/.next/server/chunks/[root-of-the-server]__1f18a881._.js.map +0 -1
  661. package/web/.next/server/chunks/[root-of-the-server]__3d08be55._.js +0 -9
  662. package/web/.next/server/chunks/[root-of-the-server]__3d08be55._.js.map +0 -1
  663. package/web/.next/server/chunks/[root-of-the-server]__419be0d1._.js +0 -3
  664. package/web/.next/server/chunks/[root-of-the-server]__419be0d1._.js.map +0 -1
  665. package/web/.next/server/chunks/[root-of-the-server]__4747e669._.js +0 -3
  666. package/web/.next/server/chunks/[root-of-the-server]__4747e669._.js.map +0 -1
  667. package/web/.next/server/chunks/[root-of-the-server]__475afd97._.js +0 -3
  668. package/web/.next/server/chunks/[root-of-the-server]__475afd97._.js.map +0 -1
  669. package/web/.next/server/chunks/[root-of-the-server]__483ccc90._.js +0 -9
  670. package/web/.next/server/chunks/[root-of-the-server]__483ccc90._.js.map +0 -1
  671. package/web/.next/server/chunks/[root-of-the-server]__5e90f1e9._.js +0 -3
  672. package/web/.next/server/chunks/[root-of-the-server]__5e90f1e9._.js.map +0 -1
  673. package/web/.next/server/chunks/[root-of-the-server]__62634db9._.js +0 -12
  674. package/web/.next/server/chunks/[root-of-the-server]__62634db9._.js.map +0 -1
  675. package/web/.next/server/chunks/[root-of-the-server]__645a6d08._.js +0 -12
  676. package/web/.next/server/chunks/[root-of-the-server]__645a6d08._.js.map +0 -1
  677. package/web/.next/server/chunks/[root-of-the-server]__74f3dc5c._.js +0 -3
  678. package/web/.next/server/chunks/[root-of-the-server]__74f3dc5c._.js.map +0 -1
  679. package/web/.next/server/chunks/[root-of-the-server]__810add7c._.js +0 -3
  680. package/web/.next/server/chunks/[root-of-the-server]__810add7c._.js.map +0 -1
  681. package/web/.next/server/chunks/[root-of-the-server]__8cfd9f70._.js +0 -24
  682. package/web/.next/server/chunks/[root-of-the-server]__8cfd9f70._.js.map +0 -1
  683. package/web/.next/server/chunks/[root-of-the-server]__8ec23770._.js +0 -3
  684. package/web/.next/server/chunks/[root-of-the-server]__8ec23770._.js.map +0 -1
  685. package/web/.next/server/chunks/[root-of-the-server]__93c391fe._.js +0 -3
  686. package/web/.next/server/chunks/[root-of-the-server]__93c391fe._.js.map +0 -1
  687. package/web/.next/server/chunks/[root-of-the-server]__9e8fc40c._.js +0 -3
  688. package/web/.next/server/chunks/[root-of-the-server]__9e8fc40c._.js.map +0 -1
  689. package/web/.next/server/chunks/[root-of-the-server]__a2426aa4._.js +0 -3
  690. package/web/.next/server/chunks/[root-of-the-server]__a2426aa4._.js.map +0 -1
  691. package/web/.next/server/chunks/[root-of-the-server]__a96ee39d._.js +0 -3
  692. package/web/.next/server/chunks/[root-of-the-server]__a96ee39d._.js.map +0 -1
  693. package/web/.next/server/chunks/[root-of-the-server]__e10befc1._.js +0 -3
  694. package/web/.next/server/chunks/[root-of-the-server]__e10befc1._.js.map +0 -1
  695. package/web/.next/server/chunks/[root-of-the-server]__e94a4a75._.js +0 -3
  696. package/web/.next/server/chunks/[root-of-the-server]__e94a4a75._.js.map +0 -1
  697. package/web/.next/server/chunks/[root-of-the-server]__ea7e9dc2._.js +0 -3
  698. package/web/.next/server/chunks/[root-of-the-server]__ea7e9dc2._.js.map +0 -1
  699. package/web/.next/server/chunks/[root-of-the-server]__f1aeae12._.js +0 -3
  700. package/web/.next/server/chunks/[root-of-the-server]__f7b38c05._.js +0 -3
  701. package/web/.next/server/chunks/[root-of-the-server]__f7b38c05._.js.map +0 -1
  702. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_f57e8323.js +0 -3
  703. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_f57e8323.js.map +0 -1
  704. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_c2027d57.js +0 -3
  705. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_c2027d57.js.map +0 -1
  706. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_chat_page_actions_f70a6774.js +0 -3
  707. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_chat_page_actions_f70a6774.js.map +0 -1
  708. package/web/.next/server/chunks/ssr/[root-of-the-server]__0e34e896._.js +0 -4
  709. package/web/.next/server/chunks/ssr/[root-of-the-server]__0e34e896._.js.map +0 -1
  710. package/web/.next/server/chunks/ssr/[root-of-the-server]__1eb031d8._.js +0 -3
  711. package/web/.next/server/chunks/ssr/[root-of-the-server]__1eb031d8._.js.map +0 -1
  712. package/web/.next/server/chunks/ssr/[root-of-the-server]__35e7da6b._.js +0 -4
  713. package/web/.next/server/chunks/ssr/[root-of-the-server]__35e7da6b._.js.map +0 -1
  714. package/web/.next/server/chunks/ssr/[root-of-the-server]__36eb7673._.js +0 -3
  715. package/web/.next/server/chunks/ssr/[root-of-the-server]__36eb7673._.js.map +0 -1
  716. package/web/.next/server/chunks/ssr/[root-of-the-server]__4576a805._.js +0 -4
  717. package/web/.next/server/chunks/ssr/[root-of-the-server]__4576a805._.js.map +0 -1
  718. package/web/.next/server/chunks/ssr/[root-of-the-server]__b51b0071._.js +0 -4
  719. package/web/.next/server/chunks/ssr/[root-of-the-server]__b51b0071._.js.map +0 -1
  720. package/web/.next/server/chunks/ssr/[root-of-the-server]__bd113e97._.js +0 -4
  721. package/web/.next/server/chunks/ssr/[root-of-the-server]__bd113e97._.js.map +0 -1
  722. package/web/.next/server/chunks/ssr/[root-of-the-server]__c6f02c81._.js +0 -3
  723. package/web/.next/server/chunks/ssr/[root-of-the-server]__c6f02c81._.js.map +0 -1
  724. package/web/.next/server/chunks/ssr/[root-of-the-server]__d5e22d1a._.js +0 -3
  725. package/web/.next/server/chunks/ssr/[root-of-the-server]__f13f6a81._.js +0 -3
  726. package/web/.next/server/chunks/ssr/[root-of-the-server]__f13f6a81._.js.map +0 -1
  727. package/web/.next/server/chunks/ssr/[root-of-the-server]__f5614810._.js +0 -3
  728. package/web/.next/server/chunks/ssr/[root-of-the-server]__ff332bfb._.js +0 -3
  729. package/web/.next/server/chunks/ssr/_5747febb._.js.map +0 -1
  730. package/web/.next/server/chunks/ssr/_819f193a._.js.map +0 -1
  731. package/web/.next/server/chunks/ssr/_ed2f2799._.js.map +0 -1
  732. package/web/.next/server/chunks/ssr/src_presentation_web_064c7e73._.js +0 -3
  733. package/web/.next/server/chunks/ssr/src_presentation_web_064c7e73._.js.map +0 -1
  734. package/web/.next/server/chunks/ssr/src_presentation_web_1726dc84._.js +0 -5
  735. package/web/.next/server/chunks/ssr/src_presentation_web_1726dc84._.js.map +0 -1
  736. package/web/.next/server/chunks/ssr/src_presentation_web_28c682ee._.js +0 -3
  737. package/web/.next/server/chunks/ssr/src_presentation_web_28c682ee._.js.map +0 -1
  738. package/web/.next/server/chunks/ssr/src_presentation_web_2d7b0e7b._.js +0 -5
  739. package/web/.next/server/chunks/ssr/src_presentation_web_2d7b0e7b._.js.map +0 -1
  740. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_bcef11e0.js +0 -3
  741. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_bcef11e0.js.map +0 -1
  742. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_02d5029f.js +0 -3
  743. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_02d5029f.js.map +0 -1
  744. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_67ca1f81.js +0 -3
  745. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_67ca1f81.js.map +0 -1
  746. package/web/.next/server/chunks/ssr/src_presentation_web_b1110b54._.js +0 -3
  747. package/web/.next/server/chunks/ssr/src_presentation_web_b1110b54._.js.map +0 -1
  748. package/web/.next/server/chunks/ssr/src_presentation_web_components_349d9f24._.js.map +0 -1
  749. package/web/.next/server/chunks/ssr/src_presentation_web_d388fcb0._.js +0 -3
  750. package/web/.next/server/chunks/ssr/src_presentation_web_d388fcb0._.js.map +0 -1
  751. package/web/.next/server/chunks/ssr/src_presentation_web_da61a4f3._.js +0 -3
  752. package/web/.next/server/chunks/ssr/src_presentation_web_da61a4f3._.js.map +0 -1
  753. package/web/.next/static/chunks/1f232a3618b82ac1.css +0 -1
  754. package/web/.next/static/chunks/2621b35c0c9da177.js +0 -1
  755. package/web/.next/static/chunks/2a3edcf98f609bb7.js +0 -1
  756. package/web/.next/static/chunks/3370f8dc24c64ce4.js +0 -1
  757. package/web/.next/static/chunks/47ed89fae0f1542e.js +0 -1
  758. package/web/.next/static/chunks/6c1664f584f34e6f.js +0 -1
  759. package/web/.next/static/chunks/f952f152ac0a4abe.js +0 -3
  760. package/web/public/icons/agents/rovo-dev.svg +0 -6
  761. /package/web/.next/server/chunks/{[root-of-the-server]__937ba94e._.js.map → [root-of-the-server]__e3692208._.js.map} +0 -0
  762. /package/web/.next/static/{8CNKMABoDvNDVQD3DEuB4 → 36ONyC02R4wfFe7iWMQLU}/_buildManifest.js +0 -0
  763. /package/web/.next/static/{8CNKMABoDvNDVQD3DEuB4 → 36ONyC02R4wfFe7iWMQLU}/_clientMiddlewareManifest.json +0 -0
  764. /package/web/.next/static/{8CNKMABoDvNDVQD3DEuB4 → 36ONyC02R4wfFe7iWMQLU}/_ssgManifest.js +0 -0
@@ -1,13 +1,26 @@
1
1
  /**
2
- * Interactive Session Service (Facade)
2
+ * Interactive Session Service
3
3
  *
4
- * Thin facade that delegates to focused sub-classes:
5
- * - SubscriberNotifier real-time subscription management
6
- * - SessionStateManager session CRUD, stop, markRead, turn statuses
7
- * - ChatStateBuilder chat UI state reconstruction
8
- * - TurnExecutor — turn execution, message persistence, user interactions
9
- * - SessionBootSequence — session initialization and agent boot
4
+ * Singleton service that owns the lifecycle of all interactive agent sessions.
5
+ * Uses the IAgentExecutorFactory to create interactive executors that manage
6
+ * persistent sessions via the agent SDK. Multi-turn context is maintained
7
+ * by the SDK session handle internally.
10
8
  *
9
+ * Dependencies are injected via constructor for testability (no real processes
10
+ * are spawned in unit tests — the factory is replaced with a test double).
11
+ */
12
+ import * as crypto from 'node:crypto';
13
+ import { InteractiveSessionStatus, InteractiveMessageRole, AgentType, AgentAuthMethod, } from '../../../domain/generated/output.js';
14
+ import { ConcurrentSessionLimitError } from '../../../domain/errors/concurrent-session-limit.error.js';
15
+ import { getSettings, hasSettings } from '../settings.service.js';
16
+ /** Default idle timeout if no settings are loaded (15 minutes). */
17
+ const DEFAULT_TIMEOUT_MS = 15 * 60 * 1000;
18
+ /** Default concurrent session cap. */
19
+ const DEFAULT_CAP = 3;
20
+ /** Maximum time to wait for the agent to become ready (60 seconds). */
21
+ const BOOT_TIMEOUT_MS = 60_000;
22
+ /**
23
+ * Core service managing interactive agent session lifecycles.
11
24
  * Must be registered as a singleton in the DI container.
12
25
  *
13
26
  * **Polymorphic `featureId` scope key:** The `featureId` parameter accepted
@@ -18,87 +31,1014 @@
18
31
  * - Global chat: literal string `"global"`
19
32
  *
20
33
  * Sessions and messages are isolated by this key regardless of chat type.
34
+ *
35
+ * @todo Consider renaming to `scopeId` + adding a `scopeType` discriminator.
21
36
  */
22
- import { DEFAULT_TIMEOUT_MS } from './session-state.js';
23
- import { SubscriberNotifier } from './subscriber-notifier.js';
24
- import { SessionStateManager } from './session-state-manager.js';
25
- import { ChatStateBuilder } from './chat-state-builder.js';
26
- import { TurnExecutor } from './turn-executor.js';
27
- import { SessionBootSequence } from './session-boot-sequence.js';
28
- import { getSettings, hasSettings } from '../settings.service.js';
29
37
  export class InteractiveSessionService {
38
+ sessionRepo;
39
+ messageRepo;
40
+ executorFactory;
41
+ featureRepo;
42
+ contextBuilder;
30
43
  /** Live sessions indexed by sessionId. */
31
44
  sessions = new Map();
32
45
  /** Cached agentSessionIds from stopped sessions, keyed by featureId. */
33
46
  stoppedAgentSessionIds = new Map();
34
- // Sub-services
35
- notifier;
36
- stateManager;
37
- chatStateBuilder;
38
- turnExecutor;
39
- bootSequence;
47
+ /**
48
+ * Feature-level subscribers that survive session restarts.
49
+ *
50
+ * Unlike session-level subscribers (in SessionState.subscribers), these
51
+ * persist when a session dies and a new one boots. SSE connections
52
+ * subscribe here so they continue receiving events from new sessions.
53
+ */
54
+ featureSubscribers = new Map();
40
55
  constructor(sessionRepo, messageRepo, executorFactory, featureRepo, contextBuilder) {
41
- this.notifier = new SubscriberNotifier();
42
- this.stateManager = new SessionStateManager(sessionRepo, messageRepo);
43
- this.chatStateBuilder = new ChatStateBuilder(sessionRepo, messageRepo);
44
- // Bind resetTimer so sub-classes can use it
45
- const resetTimer = (state) => this.resetTimer(state);
46
- this.turnExecutor = new TurnExecutor(sessionRepo, messageRepo, this.notifier, resetTimer);
47
- this.bootSequence = new SessionBootSequence(sessionRepo, messageRepo, executorFactory, featureRepo, contextBuilder, this.notifier, this.turnExecutor, resetTimer);
56
+ this.sessionRepo = sessionRepo;
57
+ this.messageRepo = messageRepo;
58
+ this.executorFactory = executorFactory;
59
+ this.featureRepo = featureRepo;
60
+ this.contextBuilder = contextBuilder;
48
61
  }
49
62
  // ---------------------------------------------------------------------------
50
- // Public API — delegates to sub-classes
63
+ // Public API
51
64
  // ---------------------------------------------------------------------------
52
65
  async startSession(featureId, worktreePath, model, agentType) {
53
- return this.bootSequence.startSession(featureId, worktreePath, this.sessions, this.stoppedAgentSessionIds, model, agentType);
66
+ const cap = this.getCap();
67
+ const activeCount = await this.sessionRepo.countActiveSessions();
68
+ if (activeCount >= cap) {
69
+ throw new ConcurrentSessionLimitError(activeCount, cap);
70
+ }
71
+ // Create DB record with booting status
72
+ const now = new Date();
73
+ const session = {
74
+ id: crypto.randomUUID(),
75
+ featureId,
76
+ status: InteractiveSessionStatus.booting,
77
+ startedAt: now,
78
+ lastActivityAt: now,
79
+ createdAt: now,
80
+ updatedAt: now,
81
+ };
82
+ await this.sessionRepo.create(session);
83
+ // Mark as processing immediately so the FAB shows the spinner during boot
84
+ void this.sessionRepo.updateTurnStatus(session.id, 'processing');
85
+ // Carry over agentSessionId from previous session so resumption works
86
+ let previousAgentSessionId;
87
+ for (const [, s] of this.sessions) {
88
+ if (s.featureId === featureId && s.agentSessionId) {
89
+ previousAgentSessionId = s.agentSessionId;
90
+ break;
91
+ }
92
+ }
93
+ // Also check stoppedSessions cache (populated on stop)
94
+ previousAgentSessionId ??= this.stoppedAgentSessionIds.get(featureId);
95
+ // Fall back to DB — the in-memory cache may be empty after service restart
96
+ if (!previousAgentSessionId) {
97
+ const latestDbSession = await this.sessionRepo.findByFeatureId(featureId);
98
+ if (latestDbSession) {
99
+ previousAgentSessionId =
100
+ (await this.sessionRepo.getAgentSessionId(latestDbSession.id)) ?? undefined;
101
+ }
102
+ }
103
+ // Set up in-memory state
104
+ const state = {
105
+ sessionId: session.id,
106
+ featureId,
107
+ worktreePath,
108
+ model,
109
+ agentType,
110
+ handle: null,
111
+ agentSessionId: previousAgentSessionId,
112
+ timer: null,
113
+ currentAssistantBuffer: '',
114
+ toolEventsLog: [],
115
+ subscribers: new Set(),
116
+ turnInProgress: false,
117
+ turnQueue: [],
118
+ pendingInteraction: null,
119
+ pendingInteractionResolver: null,
120
+ };
121
+ this.sessions.set(session.id, state);
122
+ // Fire-and-forget the async boot sequence. The API returns the session
123
+ // immediately in "booting" status; the frontend polls until "ready".
124
+ void this.completeBootAsync(state, featureId, worktreePath);
125
+ return session;
126
+ }
127
+ /**
128
+ * Asynchronously complete the boot sequence: build feature context,
129
+ * create an SDK session via the interactive executor, send the boot
130
+ * prompt, iterate the stream for the greeting, persist the greeting,
131
+ * and transition the session to "ready".
132
+ */
133
+ async completeBootAsync(state, featureId, worktreePath) {
134
+ try {
135
+ // Build the feature context prompt
136
+ const feature = await this.featureRepo.findById(featureId);
137
+ const openPRs = feature?.pr?.url ? [feature.pr.url] : [];
138
+ const context = this.contextBuilder.buildContext(feature ??
139
+ { id: featureId, name: featureId }, worktreePath, openPRs);
140
+ // Include previous conversation history so the agent has context
141
+ // from prior sessions with this feature.
142
+ const previousMessages = await this.messageRepo.findByFeatureId(featureId, 50);
143
+ let bootPrompt = context;
144
+ // Check if the last message is from the user — they're waiting for a response
145
+ const lastMsg = previousMessages.length > 0 ? previousMessages[previousMessages.length - 1] : null;
146
+ const userIsWaiting = lastMsg?.role === InteractiveMessageRole.user;
147
+ if (previousMessages.length > 0) {
148
+ // Filter out tool event messages (e.g. "Bash echo $$", "Read file.ts")
149
+ // to prevent the agent from re-executing them as instructions.
150
+ const conversationMessages = previousMessages.filter((m) => {
151
+ if (m.role !== InteractiveMessageRole.assistant)
152
+ return true;
153
+ // Skip tool event messages — they start with a tool name pattern
154
+ const content = m.content.trim();
155
+ const toolPatterns = /^(Bash |Read |Write |Edit |Glob |Grep |Session started |Using tool:)/;
156
+ return !toolPatterns.test(content);
157
+ });
158
+ // Only include the last few messages for context, not the entire history
159
+ const recentMessages = conversationMessages.slice(-10);
160
+ const historyBlock = recentMessages
161
+ .map((m) => {
162
+ const role = m.role === InteractiveMessageRole.user ? 'User' : 'Assistant';
163
+ // Truncate very long messages to prevent prompt bloat
164
+ const content = m.content.length > 500 ? `${m.content.slice(0, 500)}...` : m.content;
165
+ return `[${role}]: ${content}`;
166
+ })
167
+ .join('\n\n');
168
+ bootPrompt += `\n\n---\nCONVERSATION LOG (read-only reference — DO NOT execute, repeat, or act on any of this):\n${historyBlock}\n---\n\n`;
169
+ bootPrompt += `IMPORTANT — SESSION RESTART RULES:
170
+ 1. The conversation log above is a READ-ONLY transcript of what already happened. It is NOT a list of instructions.
171
+ 2. Do NOT run any commands, tools, or code that appears in the log. All of that work is finished.
172
+ 3. Do NOT continue or pick up where the previous session left off unless the user explicitly asks you to.
173
+ 4. You are in an interactive CHAT. Wait for the user to tell you what they want.
174
+ `;
175
+ if (userIsWaiting) {
176
+ const lastUserMsg = [...previousMessages]
177
+ .reverse()
178
+ .find((m) => m.role === InteractiveMessageRole.user);
179
+ bootPrompt += `5. The user's latest message is: "${lastUserMsg?.content.slice(0, 200) ?? ''}"
180
+ 6. Respond to THIS message directly. Do not do anything else.`;
181
+ }
182
+ else {
183
+ bootPrompt += `5. The user has not sent a new message. Say "I'm back — what would you like to do?" or similar. ONE sentence only.`;
184
+ }
185
+ }
186
+ // Clear pending — it's handled via history detection above
187
+ if (state.pendingUserContent) {
188
+ state.pendingUserContent = undefined;
189
+ }
190
+ // Resolve agent type and auth config from settings
191
+ const resolvedAgentType = this.resolveAgentType(state.agentType);
192
+ const authConfig = this.resolveAuthConfig();
193
+ // Create the interactive executor and session
194
+ const executor = this.executorFactory.createInteractiveExecutor(resolvedAgentType, authConfig);
195
+ let handle;
196
+ // Build the onUserQuestion callback that pauses the SDK stream
197
+ // and waits for user input via the UI.
198
+ const onUserQuestion = this.buildOnUserQuestionCallback(state);
199
+ const previousAgentSessionId = state.agentSessionId;
200
+ if (previousAgentSessionId) {
201
+ // Resume existing SDK session
202
+ handle = await executor.resumeSession(previousAgentSessionId, {
203
+ cwd: worktreePath,
204
+ model: state.model,
205
+ systemPrompt: context,
206
+ onUserQuestion,
207
+ });
208
+ }
209
+ else {
210
+ // Create new SDK session
211
+ handle = await executor.createSession({
212
+ cwd: worktreePath,
213
+ model: state.model,
214
+ systemPrompt: context,
215
+ onUserQuestion,
216
+ });
217
+ }
218
+ state.handle = handle;
219
+ // Send the boot prompt and iterate stream for the greeting
220
+ await handle.send(bootPrompt);
221
+ let greetingText = '';
222
+ const bootAbort = new AbortController();
223
+ state.streamAbort = bootAbort;
224
+ // Set up boot timeout
225
+ const bootTimeout = setTimeout(() => {
226
+ bootAbort.abort();
227
+ }, BOOT_TIMEOUT_MS);
228
+ try {
229
+ for await (const event of handle.stream()) {
230
+ if (bootAbort.signal.aborted) {
231
+ throw new Error(`Agent boot timed out after ${BOOT_TIMEOUT_MS / 1000}s`);
232
+ }
233
+ this.resetTimer(state);
234
+ switch (event.type) {
235
+ case 'delta':
236
+ if (event.content) {
237
+ greetingText += event.content;
238
+ state.currentAssistantBuffer += event.content;
239
+ this.notify(state, { delta: event.content, done: false });
240
+ }
241
+ break;
242
+ case 'tool_use':
243
+ if (event.label) {
244
+ const toolLabel = event.label;
245
+ const toolDetail = event.detail;
246
+ void this.persistToolEvent(state, toolLabel, toolDetail);
247
+ this.notify(state, {
248
+ delta: '',
249
+ done: false,
250
+ log: `Using tool: ${toolLabel}`,
251
+ activity: { kind: 'tool_use', label: toolLabel, detail: toolDetail },
252
+ });
253
+ }
254
+ break;
255
+ case 'tool_result':
256
+ if (event.label) {
257
+ const resultLabel = event.label;
258
+ const resultDetail = event.detail;
259
+ void this.persistToolEvent(state, resultLabel, resultDetail);
260
+ this.notify(state, {
261
+ delta: '',
262
+ done: false,
263
+ log: `Completed: ${resultLabel}`,
264
+ activity: { kind: 'tool_result', label: resultLabel, detail: resultDetail },
265
+ });
266
+ }
267
+ break;
268
+ case 'status':
269
+ if (event.content) {
270
+ const statusContent = event.content;
271
+ this.notify(state, { delta: '', done: false, log: statusContent });
272
+ }
273
+ break;
274
+ case 'done': {
275
+ // Use result text if provided and non-empty, otherwise use accumulated buffer
276
+ const resultText = event.content && event.content.length > 0 ? event.content : greetingText;
277
+ // Capture the SDK session ID (available after first message exchange)
278
+ const sdkSessionId = handle.sessionId;
279
+ if (sdkSessionId) {
280
+ // Detect CWD mismatch: if we tried to resume but got a different
281
+ // session ID, the SDK silently created a fresh session (typically
282
+ // because the cwd changed or session JSONL was lost).
283
+ if (previousAgentSessionId && sdkSessionId !== previousAgentSessionId) {
284
+ // eslint-disable-next-line no-console
285
+ console.warn(`[InteractiveSession] Session resume mismatch for feature ${featureId}: ` +
286
+ `expected ${previousAgentSessionId}, got ${sdkSessionId}. ` +
287
+ `SDK created a fresh session (likely cwd changed or session expired).`);
288
+ }
289
+ state.agentSessionId = sdkSessionId;
290
+ // Persist to DB so it survives service restarts
291
+ void this.sessionRepo.updateAgentSessionId(state.sessionId, sdkSessionId);
292
+ }
293
+ // Persist greeting and mark session ready
294
+ const greetingMsg = {
295
+ id: crypto.randomUUID(),
296
+ featureId,
297
+ sessionId: state.sessionId,
298
+ role: InteractiveMessageRole.assistant,
299
+ content: resultText,
300
+ createdAt: new Date(),
301
+ updatedAt: new Date(),
302
+ };
303
+ await this.messageRepo.create(greetingMsg);
304
+ await this.sessionRepo.updateStatus(state.sessionId, InteractiveSessionStatus.ready);
305
+ // If there's a pending user message, the next turn will set 'processing'.
306
+ // Otherwise boot greeting is expected — mark idle.
307
+ if (!state.pendingUserContent) {
308
+ void this.sessionRepo.updateTurnStatus(state.sessionId, 'idle');
309
+ }
310
+ state.currentAssistantBuffer = '';
311
+ state.toolEventsLog = [];
312
+ // Notify subscribers of end-of-turn
313
+ this.notify(state, { delta: '', done: true });
314
+ // Start idle timer now that the session is live
315
+ this.resetTimer(state);
316
+ return; // Boot complete
317
+ }
318
+ case 'error':
319
+ throw new Error(`Agent error during boot: ${event.content ?? 'unknown'}`);
320
+ }
321
+ }
322
+ }
323
+ finally {
324
+ clearTimeout(bootTimeout);
325
+ state.streamAbort = undefined;
326
+ }
327
+ // If we get here without a 'done' event, use whatever text we accumulated
328
+ if (greetingText) {
329
+ const greetingMsg = {
330
+ id: crypto.randomUUID(),
331
+ featureId,
332
+ sessionId: state.sessionId,
333
+ role: InteractiveMessageRole.assistant,
334
+ content: greetingText,
335
+ createdAt: new Date(),
336
+ updatedAt: new Date(),
337
+ };
338
+ await this.messageRepo.create(greetingMsg);
339
+ }
340
+ await this.sessionRepo.updateStatus(state.sessionId, InteractiveSessionStatus.ready);
341
+ if (!state.pendingUserContent) {
342
+ void this.sessionRepo.updateTurnStatus(state.sessionId, 'idle');
343
+ }
344
+ state.currentAssistantBuffer = '';
345
+ state.toolEventsLog = [];
346
+ this.resetTimer(state);
347
+ }
348
+ catch (err) {
349
+ // If session was already cleaned up by stopSession, nothing more to do
350
+ if (!this.sessions.has(state.sessionId))
351
+ return;
352
+ // Boot failed — mark session as error so the frontend can show the failure
353
+ // eslint-disable-next-line no-console
354
+ console.error(`[InteractiveSession] boot failed for session ${state.sessionId}:`, err);
355
+ try {
356
+ await this.sessionRepo.updateStatus(state.sessionId, InteractiveSessionStatus.error);
357
+ }
358
+ catch {
359
+ // Best-effort DB update
360
+ }
361
+ if (state.agentSessionId) {
362
+ this.stoppedAgentSessionIds.set(state.featureId, state.agentSessionId);
363
+ }
364
+ this.sessions.delete(state.sessionId);
365
+ }
54
366
  }
55
367
  async stopSession(sessionId) {
56
- return this.stateManager.stopSession(sessionId, this.sessions, this.stoppedAgentSessionIds);
368
+ const state = this.sessions.get(sessionId);
369
+ if (!state) {
370
+ // Already stopped — idempotent
371
+ return;
372
+ }
373
+ // eslint-disable-next-line no-console
374
+ console.log(`[InteractiveSession] stopSession called for ${sessionId} (feature: ${state.featureId})`, new Error().stack?.split('\n').slice(1, 4).join(' <- '));
375
+ // Abort any active stream iteration and clear pending turns
376
+ if (state.streamAbort) {
377
+ state.streamAbort.abort();
378
+ state.streamAbort = undefined;
379
+ }
380
+ state.turnQueue.length = 0;
381
+ state.turnInProgress = false;
382
+ this.clearTimer(state);
383
+ // Cache agentSessionId so resumption works when session restarts
384
+ if (state.agentSessionId) {
385
+ this.stoppedAgentSessionIds.set(state.featureId, state.agentSessionId);
386
+ }
387
+ this.sessions.delete(sessionId);
388
+ // Close the SDK session handle
389
+ if (state.handle) {
390
+ try {
391
+ await state.handle.close();
392
+ }
393
+ catch {
394
+ // Session may already be closed
395
+ }
396
+ state.handle = null;
397
+ }
398
+ await this.sessionRepo.updateStatus(sessionId, InteractiveSessionStatus.stopped, new Date());
399
+ void this.sessionRepo.updateTurnStatus(sessionId, 'idle');
57
400
  }
58
401
  async sendMessage(sessionId, content) {
59
- return this.turnExecutor.sendMessage(sessionId, content, this.sessions, this.stoppedAgentSessionIds);
402
+ const dbSession = await this.sessionRepo.findById(sessionId);
403
+ if (!dbSession || dbSession.status !== InteractiveSessionStatus.ready) {
404
+ throw new Error(`Session ${sessionId} is not ready — cannot send message`);
405
+ }
406
+ const state = this.sessions.get(sessionId);
407
+ if (!state) {
408
+ throw new Error(`Session ${sessionId} is not ready — cannot send message`);
409
+ }
410
+ // Persist user message
411
+ const now = new Date();
412
+ const message = {
413
+ id: crypto.randomUUID(),
414
+ featureId: state.featureId,
415
+ sessionId,
416
+ role: InteractiveMessageRole.user,
417
+ content,
418
+ createdAt: now,
419
+ updatedAt: now,
420
+ };
421
+ await this.messageRepo.create(message);
422
+ // Reset idle timer on user activity
423
+ this.resetTimer(state);
424
+ await this.sessionRepo.updateLastActivity(sessionId, now);
425
+ // Guard: only one turn at a time per session (SDK stream is not concurrent-safe)
426
+ if (state.turnInProgress) {
427
+ state.turnQueue.push(content);
428
+ }
429
+ else {
430
+ state.turnInProgress = true;
431
+ void this.executeAndPersistTurn(state, content);
432
+ }
433
+ return message;
434
+ }
435
+ /**
436
+ * Execute a turn via the SDK session handle and persist the assistant response.
437
+ */
438
+ async executeAndPersistTurn(state, prompt) {
439
+ try {
440
+ if (!state.handle) {
441
+ throw new Error('No active session handle — cannot execute turn');
442
+ }
443
+ state.currentAssistantBuffer = '';
444
+ state.toolEventsLog = [];
445
+ // Mark turn as processing for dot indicator
446
+ void this.sessionRepo.updateTurnStatus(state.sessionId, 'processing');
447
+ // Send the message to the SDK session
448
+ await state.handle.send(prompt);
449
+ // Set up abort controller for this stream
450
+ const abort = new AbortController();
451
+ state.streamAbort = abort;
452
+ let responseText = '';
453
+ try {
454
+ for await (const event of state.handle.stream()) {
455
+ if (abort.signal.aborted)
456
+ break;
457
+ // Reset idle timer on each event received
458
+ this.resetTimer(state);
459
+ switch (event.type) {
460
+ case 'delta':
461
+ if (event.content) {
462
+ responseText += event.content;
463
+ state.currentAssistantBuffer += event.content;
464
+ this.notify(state, { delta: event.content, done: false });
465
+ }
466
+ break;
467
+ case 'tool_use':
468
+ if (event.label) {
469
+ const toolLabel = event.label;
470
+ const toolDetail = event.detail;
471
+ void this.persistToolEvent(state, toolLabel, toolDetail);
472
+ this.notify(state, {
473
+ delta: '',
474
+ done: false,
475
+ log: `Using tool: ${toolLabel}`,
476
+ activity: { kind: 'tool_use', label: toolLabel, detail: toolDetail },
477
+ });
478
+ }
479
+ break;
480
+ case 'tool_result':
481
+ if (event.label) {
482
+ const resultLabel = event.label;
483
+ const resultDetail = event.detail;
484
+ void this.persistToolEvent(state, resultLabel, resultDetail);
485
+ this.notify(state, {
486
+ delta: '',
487
+ done: false,
488
+ log: `Completed: ${resultLabel}`,
489
+ activity: { kind: 'tool_result', label: resultLabel, detail: resultDetail },
490
+ });
491
+ }
492
+ break;
493
+ case 'status':
494
+ if (event.content) {
495
+ const statusContent = event.content;
496
+ this.notify(state, { delta: '', done: false, log: statusContent });
497
+ }
498
+ break;
499
+ case 'done': {
500
+ // Use result text if provided and non-empty, otherwise use accumulated buffer
501
+ const resultText = event.content && event.content.length > 0 ? event.content : responseText;
502
+ // Persist assistant message
503
+ const now = new Date();
504
+ const msg = {
505
+ id: crypto.randomUUID(),
506
+ featureId: state.featureId,
507
+ sessionId: state.sessionId,
508
+ role: InteractiveMessageRole.assistant,
509
+ content: resultText,
510
+ createdAt: now,
511
+ updatedAt: now,
512
+ };
513
+ await this.messageRepo.create(msg);
514
+ state.currentAssistantBuffer = '';
515
+ state.toolEventsLog = [];
516
+ // Accumulate usage from this turn
517
+ if (event.usage) {
518
+ void this.sessionRepo.accumulateUsage(state.sessionId, {
519
+ costUsd: event.usage.costUsd ?? 0,
520
+ inputTokens: event.usage.inputTokens ?? 0,
521
+ outputTokens: event.usage.outputTokens ?? 0,
522
+ turns: event.usage.numTurns ?? 1,
523
+ });
524
+ }
525
+ // Mark as unread — if user has the chat open, the frontend
526
+ // will immediately call markRead to clear it
527
+ void this.sessionRepo.updateTurnStatus(state.sessionId, 'unread');
528
+ // Notify subscribers of end-of-turn
529
+ this.notify(state, { delta: '', done: true });
530
+ return; // Turn complete
531
+ }
532
+ case 'error':
533
+ // eslint-disable-next-line no-console
534
+ console.error(`[InteractiveSession] agent error during turn for session ${state.sessionId}:`, event.content);
535
+ // Accumulate usage even on errors — cost was still incurred
536
+ if (event.usage) {
537
+ void this.sessionRepo.accumulateUsage(state.sessionId, {
538
+ costUsd: event.usage.costUsd ?? 0,
539
+ inputTokens: event.usage.inputTokens ?? 0,
540
+ outputTokens: event.usage.outputTokens ?? 0,
541
+ turns: event.usage.numTurns ?? 1,
542
+ });
543
+ }
544
+ this.notify(state, {
545
+ delta: '',
546
+ done: true,
547
+ log: `Error: ${event.content ?? 'unknown'}`,
548
+ });
549
+ break;
550
+ case 'init':
551
+ // The SDK emits init on every turn, but we only show "Session started"
552
+ // during boot (handled in completeBootAsync). Ignore it here to avoid
553
+ // spamming the chat with repeated session-started messages.
554
+ break;
555
+ case 'api_retry':
556
+ this.notify(state, {
557
+ delta: '',
558
+ done: false,
559
+ log: event.content ?? 'Retrying API call...',
560
+ });
561
+ break;
562
+ case 'rate_limit':
563
+ this.notify(state, { delta: '', done: false, log: event.content ?? 'Rate limited' });
564
+ break;
565
+ case 'task_started':
566
+ if (event.content) {
567
+ void this.persistToolEvent(state, 'Subtask started', event.content);
568
+ this.notify(state, {
569
+ delta: '',
570
+ done: false,
571
+ log: `Subtask: ${event.content}`,
572
+ activity: { kind: 'system', label: 'Subtask started', detail: event.content },
573
+ });
574
+ }
575
+ break;
576
+ case 'task_progress':
577
+ if (event.content) {
578
+ this.notify(state, { delta: '', done: false, log: `Subtask: ${event.content}` });
579
+ }
580
+ break;
581
+ case 'task_done':
582
+ if (event.content) {
583
+ const taskStatus = event.detail ?? 'completed';
584
+ void this.persistToolEvent(state, `Subtask ${taskStatus}`, event.content);
585
+ this.notify(state, {
586
+ delta: '',
587
+ done: false,
588
+ log: `Subtask ${taskStatus}: ${event.content}`,
589
+ activity: {
590
+ kind: 'system',
591
+ label: `Subtask ${taskStatus}`,
592
+ detail: event.content,
593
+ },
594
+ });
595
+ }
596
+ break;
597
+ case 'user_question':
598
+ // AskUserQuestion is now handled by the canUseTool callback
599
+ // (buildOnUserQuestionCallback) which pauses the SDK stream.
600
+ // This event should not appear in the stream anymore, but if it
601
+ // does (e.g. from a different code path), ignore it here.
602
+ break;
603
+ }
604
+ }
605
+ }
606
+ finally {
607
+ state.streamAbort = undefined;
608
+ }
609
+ // If we exit the stream loop without a 'done' event (stream ended),
610
+ // persist whatever text we accumulated
611
+ if (responseText && state.currentAssistantBuffer) {
612
+ const now = new Date();
613
+ const msg = {
614
+ id: crypto.randomUUID(),
615
+ featureId: state.featureId,
616
+ sessionId: state.sessionId,
617
+ role: InteractiveMessageRole.assistant,
618
+ content: responseText,
619
+ createdAt: now,
620
+ updatedAt: now,
621
+ };
622
+ await this.messageRepo.create(msg);
623
+ state.currentAssistantBuffer = '';
624
+ state.toolEventsLog = [];
625
+ this.notify(state, { delta: '', done: true });
626
+ }
627
+ else if (!responseText) {
628
+ // Stream ended without any response — SDK session likely died.
629
+ // Mark as error so the next message triggers a fresh session.
630
+ // eslint-disable-next-line no-console
631
+ console.error(`[InteractiveSession] stream ended without response for session ${state.sessionId} — session may have died`);
632
+ this.notify(state, {
633
+ delta: '',
634
+ done: true,
635
+ log: 'Session disconnected — will restart on next message',
636
+ });
637
+ if (state.agentSessionId) {
638
+ this.stoppedAgentSessionIds.set(state.featureId, state.agentSessionId);
639
+ }
640
+ this.sessions.delete(state.sessionId);
641
+ try {
642
+ await this.sessionRepo.updateStatus(state.sessionId, InteractiveSessionStatus.error);
643
+ }
644
+ catch {
645
+ // Best-effort DB update
646
+ }
647
+ return; // Skip queue drain — session is dead
648
+ }
649
+ }
650
+ catch (err) {
651
+ // If session was already stopped, ignore
652
+ if (!this.sessions.has(state.sessionId))
653
+ return;
654
+ // eslint-disable-next-line no-console
655
+ console.error(`[InteractiveSession] turn failed for session ${state.sessionId}:`, err);
656
+ }
657
+ finally {
658
+ // Release the turn lock and drain the queue
659
+ state.turnInProgress = false;
660
+ if (this.sessions.has(state.sessionId) && state.turnQueue.length > 0) {
661
+ const nextContent = state.turnQueue.shift();
662
+ state.turnInProgress = true;
663
+ void this.executeAndPersistTurn(state, nextContent);
664
+ }
665
+ }
60
666
  }
61
667
  async getMessages(featureId, limit) {
62
- return this.stateManager.getMessages(featureId, limit);
668
+ return this.messageRepo.findByFeatureId(featureId, limit);
63
669
  }
64
670
  async clearMessages(featureId) {
65
- return this.stateManager.clearMessages(featureId, this.sessions, this.stoppedAgentSessionIds, (sessionId) => this.stopSession(sessionId));
671
+ // Stop any active session so the agent doesn't retain old context
672
+ const state = this.findActiveStateForFeature(featureId);
673
+ if (state) {
674
+ await this.stopSession(state.sessionId);
675
+ }
676
+ // Also clear the cached agentSessionId so next session starts fresh
677
+ this.stoppedAgentSessionIds.delete(featureId);
678
+ return this.messageRepo.deleteByFeatureId(featureId);
66
679
  }
67
680
  async getSession(sessionId) {
68
- return this.stateManager.getSession(sessionId);
681
+ return this.sessionRepo.findById(sessionId);
69
682
  }
70
683
  subscribe(sessionId, onChunk) {
71
- return this.notifier.subscribeBySession(sessionId, this.sessions, onChunk);
684
+ const state = this.sessions.get(sessionId);
685
+ if (!state) {
686
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
687
+ return () => { };
688
+ }
689
+ state.subscribers.add(onChunk);
690
+ return () => state.subscribers.delete(onChunk);
72
691
  }
73
692
  // ---------------------------------------------------------------------------
74
693
  // Feature-scoped API (frontend doesn't manage sessions)
75
694
  // ---------------------------------------------------------------------------
76
695
  async sendUserMessage(featureId, content, worktreePath, model, agentType) {
77
- return this.turnExecutor.sendUserMessage(featureId, content, worktreePath, this.sessions, this.stoppedAgentSessionIds, (fId, wPath, m, aType) => this.startSession(fId, wPath, m, aType), (fId) => this.stateManager.findActiveStateForFeature(fId, this.sessions), model, agentType);
696
+ // 1. Persist user message to DB immediately this is the source of truth
697
+ const now = new Date();
698
+ const userMsg = {
699
+ id: crypto.randomUUID(),
700
+ featureId,
701
+ role: InteractiveMessageRole.user,
702
+ content,
703
+ createdAt: now,
704
+ updatedAt: now,
705
+ };
706
+ await this.messageRepo.create(userMsg);
707
+ // 2. Find active session for this feature
708
+ let state = this.findActiveStateForFeature(featureId);
709
+ // If the caller requested a different model/agent than the running session,
710
+ // silently stop the current session so a new one boots with the new config.
711
+ // Also clear the cached agentSessionId so we create a fresh SDK session
712
+ // instead of resuming the old one (which would keep the old model).
713
+ if (state && model && state.model !== model) {
714
+ await this.stopSession(state.sessionId);
715
+ this.stoppedAgentSessionIds.delete(featureId);
716
+ state = undefined;
717
+ }
718
+ else if (state && agentType && state.agentType !== agentType) {
719
+ await this.stopSession(state.sessionId);
720
+ this.stoppedAgentSessionIds.delete(featureId);
721
+ state = undefined;
722
+ }
723
+ if (state) {
724
+ const dbSession = await this.sessionRepo.findById(state.sessionId);
725
+ if (dbSession?.status === InteractiveSessionStatus.ready) {
726
+ // Session ready — send to agent (guarded: one turn at a time)
727
+ this.resetTimer(state);
728
+ await this.sessionRepo.updateLastActivity(state.sessionId, now);
729
+ if (state.turnInProgress) {
730
+ state.turnQueue.push(content);
731
+ }
732
+ else {
733
+ state.turnInProgress = true;
734
+ void this.executeAndPersistTurn(state, content);
735
+ }
736
+ }
737
+ else if (dbSession?.status === InteractiveSessionStatus.booting) {
738
+ // Session booting — queue the message
739
+ state.pendingUserContent = content;
740
+ }
741
+ }
742
+ else {
743
+ // No in-memory session — check DB for an orphaned active session (e.g. after
744
+ // service restart / hot-reload) and mark it stopped before booting a new one.
745
+ // The agentSessionId is persisted in DB so startSession will pick it up for
746
+ // SDK session resumption.
747
+ const dbSession = await this.sessionRepo.findByFeatureId(featureId);
748
+ if (dbSession &&
749
+ (dbSession.status === InteractiveSessionStatus.ready ||
750
+ dbSession.status === InteractiveSessionStatus.booting)) {
751
+ await this.sessionRepo.updateStatus(dbSession.id, InteractiveSessionStatus.stopped, new Date());
752
+ }
753
+ // Boot a new session — startSession will find the agentSessionId from DB
754
+ const session = await this.startSession(featureId, worktreePath, model, agentType);
755
+ const newState = this.sessions.get(session.id);
756
+ if (newState) {
757
+ newState.pendingUserContent = content;
758
+ }
759
+ }
760
+ return userMsg;
78
761
  }
79
762
  async getChatState(featureId) {
80
- return this.chatStateBuilder.getChatState(featureId, this.sessions);
763
+ // DB messages
764
+ const messages = await this.messageRepo.findByFeatureId(featureId);
765
+ // Find active in-memory session
766
+ const state = this.findActiveStateForFeature(featureId);
767
+ let sessionStatus = null;
768
+ let streamingText = null;
769
+ let sessionInfo = null;
770
+ if (state) {
771
+ const dbSession = await this.sessionRepo.findById(state.sessionId);
772
+ sessionStatus = dbSession?.status ?? null;
773
+ if (state.currentAssistantBuffer) {
774
+ streamingText = state.currentAssistantBuffer;
775
+ }
776
+ // Resolve model display: explicit override > default
777
+ const displayModel = state.model ?? 'claude-sonnet-4-6';
778
+ const usage = await this.sessionRepo.getUsage(state.sessionId);
779
+ sessionInfo = {
780
+ pid: null, // SDK manages process internally
781
+ sessionId: state.agentSessionId ?? state.sessionId,
782
+ model: displayModel,
783
+ startedAt: dbSession?.startedAt
784
+ ? new Date(dbSession.startedAt).toISOString()
785
+ : new Date().toISOString(),
786
+ idleTimeoutMinutes: Math.round(this.getTimeoutMs() / 60_000),
787
+ lastActivityAt: dbSession?.lastActivityAt
788
+ ? new Date(dbSession.lastActivityAt).toISOString()
789
+ : new Date().toISOString(),
790
+ totalCostUsd: usage?.totalCostUsd ?? null,
791
+ totalInputTokens: usage?.totalInputTokens ?? null,
792
+ totalOutputTokens: usage?.totalOutputTokens ?? null,
793
+ };
794
+ }
795
+ else {
796
+ // No in-memory state — check DB for last session (e.g. after server restart / hot-reload)
797
+ const latest = await this.sessionRepo.findByFeatureId(featureId);
798
+ if (latest) {
799
+ sessionStatus = latest.status;
800
+ // Show DB info even without live process (process was lost on restart)
801
+ if (latest.status !== InteractiveSessionStatus.stopped &&
802
+ latest.status !== InteractiveSessionStatus.error) {
803
+ const latestUsage = await this.sessionRepo.getUsage(latest.id);
804
+ sessionInfo = {
805
+ pid: null,
806
+ sessionId: latest.id,
807
+ model: null,
808
+ startedAt: latest.startedAt
809
+ ? new Date(latest.startedAt).toISOString()
810
+ : new Date().toISOString(),
811
+ idleTimeoutMinutes: Math.round(this.getTimeoutMs() / 60_000),
812
+ lastActivityAt: latest.lastActivityAt
813
+ ? new Date(latest.lastActivityAt).toISOString()
814
+ : new Date().toISOString(),
815
+ totalCostUsd: latestUsage?.totalCostUsd ?? null,
816
+ totalInputTokens: latestUsage?.totalInputTokens ?? null,
817
+ totalOutputTokens: latestUsage?.totalOutputTokens ?? null,
818
+ };
819
+ }
820
+ }
821
+ }
822
+ // Resolve turn status from DB
823
+ let turnStatus = 'idle';
824
+ const activeState = state;
825
+ if (activeState) {
826
+ const statuses = await this.sessionRepo.getTurnStatuses([featureId]);
827
+ turnStatus = statuses.get(featureId) ?? 'idle';
828
+ }
829
+ else {
830
+ // Check DB for the latest session's turn status
831
+ const latest = await this.sessionRepo.findByFeatureId(featureId);
832
+ if (latest) {
833
+ const statuses = await this.sessionRepo.getTurnStatuses([featureId]);
834
+ turnStatus = statuses.get(featureId) ?? 'idle';
835
+ }
836
+ }
837
+ // Include pending interaction if one exists
838
+ const pendingInteraction = state?.pendingInteraction ?? null;
839
+ return { messages, sessionStatus, streamingText, sessionInfo, turnStatus, pendingInteraction };
81
840
  }
82
841
  subscribeByFeature(featureId, onChunk) {
83
- return this.notifier.subscribeByFeature(featureId, onChunk);
842
+ // Subscribe at the feature level so the callback survives session restarts.
843
+ // When a session dies (idle timeout, error) and a new one boots, the SSE
844
+ // connection keeps receiving events from the new session automatically.
845
+ let subs = this.featureSubscribers.get(featureId);
846
+ if (!subs) {
847
+ subs = new Set();
848
+ this.featureSubscribers.set(featureId, subs);
849
+ }
850
+ subs.add(onChunk);
851
+ return () => {
852
+ subs.delete(onChunk);
853
+ if (subs.size === 0) {
854
+ this.featureSubscribers.delete(featureId);
855
+ }
856
+ };
84
857
  }
85
858
  async stopByFeature(featureId) {
86
- return this.stateManager.stopByFeature(featureId, this.sessions, this.stoppedAgentSessionIds);
859
+ const state = this.findActiveStateForFeature(featureId);
860
+ if (!state)
861
+ return;
862
+ await this.stopSession(state.sessionId);
87
863
  }
88
864
  async markRead(featureId) {
89
- return this.stateManager.markRead(featureId, this.sessions);
865
+ // Find the active session for this feature and clear unread status
866
+ const state = this.findActiveStateForFeature(featureId);
867
+ if (state) {
868
+ void this.sessionRepo.updateTurnStatus(state.sessionId, 'idle');
869
+ return;
870
+ }
871
+ // Fallback: check DB for the latest active session
872
+ const latest = await this.sessionRepo.findByFeatureId(featureId);
873
+ if (latest) {
874
+ void this.sessionRepo.updateTurnStatus(latest.id, 'idle');
875
+ }
90
876
  }
91
877
  async getTurnStatuses(featureIds) {
92
- return this.stateManager.getTurnStatuses(featureIds);
878
+ return this.sessionRepo.getTurnStatuses(featureIds);
93
879
  }
94
880
  async getAllActiveTurnStatuses() {
95
- return this.stateManager.getAllActiveTurnStatuses();
881
+ return this.sessionRepo.getAllActiveTurnStatuses();
96
882
  }
97
883
  async respondToInteraction(featureId, answers) {
98
- return this.turnExecutor.respondToInteraction(featureId, answers, (fId) => this.stateManager.findActiveStateForFeature(fId, this.sessions));
884
+ const state = this.findActiveStateForFeature(featureId);
885
+ if (!state?.pendingInteraction || !state.pendingInteractionResolver) {
886
+ throw new Error(`No pending interaction for feature ${featureId}`);
887
+ }
888
+ // Persist the user's answers as a structured user message.
889
+ // The {{interaction}} prefix lets the frontend detect and render it
890
+ // as a compact green bubble instead of a regular text message.
891
+ const interactionPayload = {
892
+ questions: state.pendingInteraction.questions.map((q) => ({
893
+ header: q.header,
894
+ question: q.question,
895
+ })),
896
+ answers,
897
+ };
898
+ const now = new Date();
899
+ const userMsg = {
900
+ id: crypto.randomUUID(),
901
+ featureId: state.featureId,
902
+ sessionId: state.sessionId,
903
+ role: InteractiveMessageRole.user,
904
+ content: `{{interaction}}${JSON.stringify(interactionPayload)}`,
905
+ createdAt: now,
906
+ updatedAt: now,
907
+ };
908
+ await this.messageRepo.create(userMsg);
909
+ // Resolve the Promise that the canUseTool callback is awaiting.
910
+ // This unblocks the SDK stream — the agent resumes with the user's answers.
911
+ state.pendingInteractionResolver(answers);
912
+ // Clear pending interaction state
913
+ state.pendingInteraction = null;
914
+ state.pendingInteractionResolver = null;
915
+ // Update turn status back to processing
916
+ void this.sessionRepo.updateTurnStatus(state.sessionId, 'processing');
917
+ // Clear the "Waiting for your response..." log
918
+ state.subscribers.forEach((sub) => sub({ delta: '', done: false }));
919
+ }
920
+ /**
921
+ * Build the onUserQuestion callback for a session.
922
+ * Called by the SDK's canUseTool when the agent invokes AskUserQuestion.
923
+ * Returns a Promise that doesn't resolve until the user submits their answers.
924
+ */
925
+ buildOnUserQuestionCallback(state) {
926
+ return async (interaction) => {
927
+ // Flush any accumulated assistant text as a separate message BEFORE
928
+ // the interaction. This ensures the agent's question text appears
929
+ // above the green answer bubble in the conversation history.
930
+ if (state.currentAssistantBuffer.trim()) {
931
+ const now = new Date();
932
+ const msg = {
933
+ id: crypto.randomUUID(),
934
+ featureId: state.featureId,
935
+ sessionId: state.sessionId,
936
+ role: InteractiveMessageRole.assistant,
937
+ content: state.currentAssistantBuffer,
938
+ createdAt: now,
939
+ updatedAt: now,
940
+ };
941
+ await this.messageRepo.create(msg);
942
+ state.currentAssistantBuffer = '';
943
+ state.toolEventsLog = [];
944
+ // Notify subscribers so the frontend picks up the new message
945
+ state.subscribers.forEach((sub) => sub({ delta: '', done: true }));
946
+ // Small delay so the refetch completes before the interaction appears
947
+ await new Promise((r) => setTimeout(r, 100));
948
+ }
949
+ // Store the interaction data for the frontend
950
+ state.pendingInteraction = interaction;
951
+ // Update turn status so the dot indicator shows amber
952
+ void this.sessionRepo.updateTurnStatus(state.sessionId, 'awaiting_input');
953
+ // Notify subscribers so SSE pushes the interaction to the frontend
954
+ state.subscribers.forEach((sub) => sub({
955
+ delta: '',
956
+ done: false,
957
+ log: 'Waiting for your response...',
958
+ interaction,
959
+ }));
960
+ // Create a Promise that will be resolved when the user calls respondToInteraction
961
+ return new Promise((resolve) => {
962
+ state.pendingInteractionResolver = resolve;
963
+ });
964
+ };
965
+ }
966
+ /** Find the in-memory state for an active session for a feature. */
967
+ findActiveStateForFeature(featureId) {
968
+ for (const state of this.sessions.values()) {
969
+ if (state.featureId === featureId)
970
+ return state;
971
+ }
972
+ return undefined;
973
+ }
974
+ // ---------------------------------------------------------------------------
975
+ // Agent resolution helpers
976
+ // ---------------------------------------------------------------------------
977
+ /** Resolve the agent type from an explicit override or settings. */
978
+ resolveAgentType(agentTypeOverride) {
979
+ if (agentTypeOverride) {
980
+ return agentTypeOverride;
981
+ }
982
+ if (hasSettings()) {
983
+ return getSettings().agent.type;
984
+ }
985
+ return AgentType.ClaudeCode;
986
+ }
987
+ /** Resolve the auth config from settings, with a safe fallback. */
988
+ resolveAuthConfig() {
989
+ if (hasSettings()) {
990
+ return getSettings().agent;
991
+ }
992
+ // Fallback for when settings haven't been initialized yet
993
+ return {
994
+ type: AgentType.ClaudeCode,
995
+ authMethod: AgentAuthMethod.Session,
996
+ };
997
+ }
998
+ // ---------------------------------------------------------------------------
999
+ // Tool detail extraction
1000
+ // ---------------------------------------------------------------------------
1001
+ /**
1002
+ * Persist a tool/system event as its own assistant message in the DB.
1003
+ * Each event gets its own bubble in the chat thread.
1004
+ */
1005
+ async persistToolEvent(state, label, detail) {
1006
+ try {
1007
+ const content = detail ? `**${label}** \`${detail}\`` : `**${label}**`;
1008
+ const msg = {
1009
+ id: crypto.randomUUID(),
1010
+ featureId: state.featureId,
1011
+ sessionId: state.sessionId,
1012
+ role: InteractiveMessageRole.assistant,
1013
+ content,
1014
+ createdAt: new Date(),
1015
+ updatedAt: new Date(),
1016
+ };
1017
+ await this.messageRepo.create(msg);
1018
+ }
1019
+ catch {
1020
+ // Non-critical — don't fail the turn for a tool event
1021
+ }
99
1022
  }
100
1023
  // ---------------------------------------------------------------------------
101
- // Timer helpers (shared by sub-classes via bound callback)
1024
+ // Event dispatch
1025
+ // ---------------------------------------------------------------------------
1026
+ /**
1027
+ * Dispatch a StreamChunk to all subscribers for a session.
1028
+ *
1029
+ * Sends to both session-level subscribers (legacy, for sessionId-based
1030
+ * subscribe()) and feature-level subscribers (for SSE connections that
1031
+ * must survive session restarts).
1032
+ */
1033
+ notify(state, chunk) {
1034
+ state.subscribers.forEach((sub) => sub(chunk));
1035
+ const featureSubs = this.featureSubscribers.get(state.featureId);
1036
+ if (featureSubs) {
1037
+ featureSubs.forEach((sub) => sub(chunk));
1038
+ }
1039
+ }
1040
+ // ---------------------------------------------------------------------------
1041
+ // Timer helpers
102
1042
  // ---------------------------------------------------------------------------
103
1043
  /** Start or restart the idle timeout timer for a session. */
104
1044
  resetTimer(state) {
@@ -123,4 +1063,11 @@ export class InteractiveSessionService {
123
1063
  const minutes = settings.interactiveAgent?.autoTimeoutMinutes ?? 15;
124
1064
  return minutes * 60 * 1000;
125
1065
  }
1066
+ /** Read the concurrent session cap from settings or fall back to default. */
1067
+ getCap() {
1068
+ if (!hasSettings())
1069
+ return DEFAULT_CAP;
1070
+ const settings = getSettings();
1071
+ return settings.interactiveAgent?.maxConcurrentSessions ?? DEFAULT_CAP;
1072
+ }
126
1073
  }