@shepai/cli 1.118.0 → 1.119.0-pr381.415b252

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 (362) hide show
  1. package/apis/json-schema/PhaseTiming.yaml +22 -1
  2. package/apis/json-schema/WorkflowConfig.yaml +10 -0
  3. package/dist/packages/core/src/application/ports/output/agents/agent-session-repository.interface.d.ts +2 -0
  4. package/dist/packages/core/src/application/ports/output/agents/agent-session-repository.interface.d.ts.map +1 -1
  5. package/dist/packages/core/src/application/ports/output/agents/phase-timing-repository.interface.d.ts +3 -3
  6. package/dist/packages/core/src/application/ports/output/agents/phase-timing-repository.interface.d.ts.map +1 -1
  7. package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts +2 -1
  8. package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts.map +1 -1
  9. package/dist/packages/core/src/domain/factories/settings-defaults.factory.d.ts.map +1 -1
  10. package/dist/packages/core/src/domain/factories/settings-defaults.factory.js +1 -0
  11. package/dist/packages/core/src/domain/generated/output.d.ts +37 -1
  12. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  13. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts +1 -0
  14. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -1
  15. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.js +2 -0
  16. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/037-add-ci-watch-enabled.d.ts +11 -0
  17. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/037-add-ci-watch-enabled.d.ts.map +1 -0
  18. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/037-add-ci-watch-enabled.js +15 -0
  19. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/038-add-phase-execution-metadata.d.ts +11 -0
  20. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/038-add-phase-execution-metadata.d.ts.map +1 -0
  21. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/038-add-phase-execution-metadata.js +27 -0
  22. package/dist/packages/core/src/infrastructure/repositories/sqlite-phase-timing.repository.d.ts +1 -1
  23. package/dist/packages/core/src/infrastructure/repositories/sqlite-phase-timing.repository.d.ts.map +1 -1
  24. package/dist/packages/core/src/infrastructure/repositories/sqlite-phase-timing.repository.js +32 -0
  25. package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-factory.service.js +1 -1
  26. package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.d.ts +28 -8
  27. package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.d.ts.map +1 -1
  28. package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.js +117 -20
  29. package/dist/packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.d.ts.map +1 -1
  30. package/dist/packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.js +8 -1
  31. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.d.ts.map +1 -1
  32. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.js +3 -2
  33. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.d.ts.map +1 -1
  34. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.js +29 -7
  35. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts.map +1 -1
  36. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.js +19 -8
  37. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.d.ts +5 -10
  38. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.d.ts.map +1 -1
  39. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.js +5 -73
  40. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/phase-timing-context.d.ts +17 -3
  41. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/phase-timing-context.d.ts.map +1 -1
  42. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/phase-timing-context.js +11 -3
  43. package/dist/packages/core/src/infrastructure/services/agents/sessions/claude-code-session.repository.d.ts +7 -0
  44. package/dist/packages/core/src/infrastructure/services/agents/sessions/claude-code-session.repository.d.ts.map +1 -1
  45. package/dist/packages/core/src/infrastructure/services/agents/sessions/claude-code-session.repository.js +35 -11
  46. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts +1 -1
  47. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts.map +1 -1
  48. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +12 -3
  49. package/dist/src/presentation/web/app/(dashboard)/@drawer/create/page.d.ts +1 -0
  50. package/dist/src/presentation/web/app/(dashboard)/@drawer/create/page.d.ts.map +1 -1
  51. package/dist/src/presentation/web/app/(dashboard)/@drawer/create/page.js +2 -2
  52. package/dist/src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.d.ts.map +1 -1
  53. package/dist/src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +1 -0
  54. package/dist/src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/page.d.ts.map +1 -1
  55. package/dist/src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -0
  56. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.d.ts.map +1 -1
  57. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.js +1 -0
  58. package/dist/src/presentation/web/app/actions/get-feature-phase-timings.d.ts +2 -0
  59. package/dist/src/presentation/web/app/actions/get-feature-phase-timings.d.ts.map +1 -1
  60. package/dist/src/presentation/web/app/actions/get-feature-phase-timings.js +2 -0
  61. package/dist/src/presentation/web/app/actions/get-merge-review-data.d.ts.map +1 -1
  62. package/dist/src/presentation/web/app/actions/get-merge-review-data.js +49 -13
  63. package/dist/src/presentation/web/app/actions/get-workflow-defaults.d.ts +1 -0
  64. package/dist/src/presentation/web/app/actions/get-workflow-defaults.d.ts.map +1 -1
  65. package/dist/src/presentation/web/app/actions/get-workflow-defaults.js +1 -0
  66. package/dist/src/presentation/web/app/api/sessions/route.d.ts +24 -0
  67. package/dist/src/presentation/web/app/api/sessions/route.d.ts.map +1 -0
  68. package/dist/src/presentation/web/app/api/sessions/route.js +230 -0
  69. package/dist/src/presentation/web/app/build-feature-node-data.d.ts +2 -0
  70. package/dist/src/presentation/web/app/build-feature-node-data.d.ts.map +1 -1
  71. package/dist/src/presentation/web/app/build-feature-node-data.js +1 -0
  72. package/dist/src/presentation/web/app/build-graph-nodes.d.ts +2 -0
  73. package/dist/src/presentation/web/app/build-graph-nodes.d.ts.map +1 -1
  74. package/dist/src/presentation/web/app/build-graph-nodes.js +11 -0
  75. package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.d.ts +2 -1
  76. package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.d.ts.map +1 -1
  77. package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.js +2 -2
  78. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts +4 -1
  79. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  80. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +16 -3
  81. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts.map +1 -1
  82. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.js +1 -0
  83. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.d.ts.map +1 -1
  84. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.js +36 -10
  85. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.d.ts.map +1 -1
  86. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.js +7 -2
  87. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.js +2 -1
  88. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +4 -0
  89. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +1 -1
  90. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  91. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +2 -1
  92. package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.d.ts +21 -0
  93. package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.d.ts.map +1 -0
  94. package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.js +138 -0
  95. package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.stories.d.ts +9 -0
  96. package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.stories.d.ts.map +1 -0
  97. package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.stories.js +77 -0
  98. package/dist/src/presentation/web/components/common/merge-review/merge-review-config.d.ts +3 -3
  99. package/dist/src/presentation/web/components/common/merge-review/merge-review-config.d.ts.map +1 -1
  100. package/dist/src/presentation/web/components/common/merge-review/merge-review.d.ts +1 -1
  101. package/dist/src/presentation/web/components/common/merge-review/merge-review.d.ts.map +1 -1
  102. package/dist/src/presentation/web/components/common/merge-review/merge-review.js +14 -20
  103. package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.d.ts +6 -0
  104. package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.d.ts.map +1 -1
  105. package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.js +74 -0
  106. package/dist/src/presentation/web/components/common/repository-node/repository-node.d.ts.map +1 -1
  107. package/dist/src/presentation/web/components/common/repository-node/repository-node.js +35 -2
  108. package/dist/src/presentation/web/components/features/settings/settings-page-client.d.ts.map +1 -1
  109. package/dist/src/presentation/web/components/features/settings/settings-page-client.js +16 -1
  110. package/dist/src/presentation/web/components/features/settings/workflow-settings-section.d.ts.map +1 -1
  111. package/dist/src/presentation/web/components/features/settings/workflow-settings-section.js +6 -1
  112. package/dist/src/presentation/web/components/features/settings/workflow-settings-section.stories.d.ts.map +1 -1
  113. package/dist/src/presentation/web/components/features/settings/workflow-settings-section.stories.js +3 -0
  114. package/dist/tsconfig.build.tsbuildinfo +1 -1
  115. package/package.json +1 -1
  116. package/web/.next/BUILD_ID +1 -1
  117. package/web/.next/app-path-routes-manifest.json +1 -0
  118. package/web/.next/build-manifest.json +2 -2
  119. package/web/.next/fallback-build-manifest.json +2 -2
  120. package/web/.next/prerender-manifest.json +3 -3
  121. package/web/.next/required-server-files.js +3 -3
  122. package/web/.next/required-server-files.json +3 -3
  123. package/web/.next/routes-manifest.json +6 -0
  124. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +21 -21
  125. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +2 -2
  126. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  127. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  128. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +27 -27
  129. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +3 -3
  130. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  131. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  132. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +27 -27
  133. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +3 -3
  134. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  135. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  136. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +19 -19
  137. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +2 -2
  138. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  139. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  140. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +21 -21
  141. package/web/.next/server/app/(dashboard)/create/page.js +2 -2
  142. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  143. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  144. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +27 -27
  145. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +3 -3
  146. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  147. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  148. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +27 -27
  149. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +3 -3
  150. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  151. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  152. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +19 -19
  153. package/web/.next/server/app/(dashboard)/page.js +2 -2
  154. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  155. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  156. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +19 -19
  157. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +2 -2
  158. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  159. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  160. package/web/.next/server/app/_global-error.html +2 -2
  161. package/web/.next/server/app/_global-error.rsc +1 -1
  162. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  163. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  164. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  165. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  166. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  167. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  168. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  169. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  170. package/web/.next/server/app/api/attachments/preview/route.js +1 -1
  171. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  172. package/web/.next/server/app/api/evidence/route.js +1 -1
  173. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  174. package/web/.next/server/app/api/graph-data/route.js +1 -1
  175. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  176. package/web/.next/server/app/api/sessions/route/app-paths-manifest.json +3 -0
  177. package/web/.next/server/app/api/sessions/route/build-manifest.json +11 -0
  178. package/web/.next/server/app/api/sessions/route/server-reference-manifest.json +4 -0
  179. package/web/.next/server/app/api/sessions/route.js +7 -0
  180. package/web/.next/server/app/api/sessions/route.js.map +5 -0
  181. package/web/.next/server/app/api/sessions/route.js.nft.json +1 -0
  182. package/web/.next/server/app/api/sessions/route_client-reference-manifest.js +2 -0
  183. package/web/.next/server/app/settings/page/server-reference-manifest.json +6 -6
  184. package/web/.next/server/app/settings/page.js +1 -1
  185. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  186. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  187. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  188. package/web/.next/server/app/skills/page.js +1 -1
  189. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  190. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  191. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  192. package/web/.next/server/app/tools/page.js +1 -1
  193. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  194. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  195. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  196. package/web/.next/server/app/version/page.js +1 -1
  197. package/web/.next/server/app/version/page.js.nft.json +1 -1
  198. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  199. package/web/.next/server/app-paths-manifest.json +1 -0
  200. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +1 -1
  201. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +1 -1
  202. package/web/.next/server/chunks/[root-of-the-server]__0fe7788d._.js +3 -0
  203. package/web/.next/server/chunks/[root-of-the-server]__0fe7788d._.js.map +1 -0
  204. package/web/.next/server/chunks/[root-of-the-server]__42b7ab55._.js +3 -0
  205. package/web/.next/server/chunks/[root-of-the-server]__42b7ab55._.js.map +1 -0
  206. package/web/.next/server/chunks/{[root-of-the-server]__7d63f9a4._.js → [root-of-the-server]__53013576._.js} +2 -2
  207. package/web/.next/server/chunks/{[root-of-the-server]__a1c7c02a._.js → [root-of-the-server]__92078db6._.js} +2 -2
  208. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  209. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js.map +1 -1
  210. package/web/.next/server/chunks/b1a17_presentation_web__next-internal_server_app_api_sessions_route_actions_c041a889.js +3 -0
  211. package/web/.next/server/chunks/b1a17_presentation_web__next-internal_server_app_api_sessions_route_actions_c041a889.js.map +1 -0
  212. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  213. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  214. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_ed372306.js +1 -1
  215. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_ed372306.js.map +1 -1
  216. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_32e26434.js +1 -1
  217. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_32e26434.js.map +1 -1
  218. package/web/.next/server/chunks/ssr/{[root-of-the-server]__07a39ff2._.js → [root-of-the-server]__06fef644._.js} +2 -2
  219. package/web/.next/server/chunks/ssr/{[root-of-the-server]__07a39ff2._.js.map → [root-of-the-server]__06fef644._.js.map} +1 -1
  220. package/web/.next/server/chunks/ssr/[root-of-the-server]__3b14e5a0._.js +3 -0
  221. package/web/.next/server/chunks/ssr/[root-of-the-server]__3b14e5a0._.js.map +1 -0
  222. package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js +3 -0
  223. package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js.map +1 -0
  224. package/web/.next/server/chunks/ssr/[root-of-the-server]__684a868c._.js +1 -1
  225. package/web/.next/server/chunks/ssr/[root-of-the-server]__684a868c._.js.map +1 -1
  226. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  227. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  228. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +2 -2
  229. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js.map +1 -1
  230. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  231. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  232. package/web/.next/server/chunks/ssr/[root-of-the-server]__8b59c03e._.js +3 -0
  233. package/web/.next/server/chunks/ssr/[root-of-the-server]__8b59c03e._.js.map +1 -0
  234. package/web/.next/server/chunks/ssr/[root-of-the-server]__8c553503._.js +4 -0
  235. package/web/.next/server/chunks/ssr/{[root-of-the-server]__2ff2daf6._.js.map → [root-of-the-server]__8c553503._.js.map} +1 -1
  236. package/web/.next/server/chunks/ssr/[root-of-the-server]__994ad9fe._.js +3 -0
  237. package/web/.next/server/chunks/ssr/[root-of-the-server]__994ad9fe._.js.map +1 -0
  238. package/web/.next/server/chunks/ssr/[root-of-the-server]__9f155c0e._.js +3 -0
  239. package/web/.next/server/chunks/ssr/[root-of-the-server]__9f155c0e._.js.map +1 -0
  240. package/web/.next/server/chunks/ssr/[root-of-the-server]__a022445f._.js +4 -0
  241. package/web/.next/server/chunks/ssr/[root-of-the-server]__a022445f._.js.map +1 -0
  242. package/web/.next/server/chunks/ssr/[root-of-the-server]__a7de2711._.js +4 -0
  243. package/web/.next/server/chunks/ssr/[root-of-the-server]__a7de2711._.js.map +1 -0
  244. package/web/.next/server/chunks/ssr/[root-of-the-server]__b724df9e._.js +3 -0
  245. package/web/.next/server/chunks/ssr/[root-of-the-server]__b724df9e._.js.map +1 -0
  246. package/web/.next/server/chunks/ssr/[root-of-the-server]__c16bf5de._.js +1 -1
  247. package/web/.next/server/chunks/ssr/[root-of-the-server]__c16bf5de._.js.map +1 -1
  248. package/web/.next/server/chunks/ssr/[root-of-the-server]__c9777776._.js +1 -1
  249. package/web/.next/server/chunks/ssr/[root-of-the-server]__c9777776._.js.map +1 -1
  250. package/web/.next/server/chunks/ssr/[root-of-the-server]__c9c1cfee._.js +3 -0
  251. package/web/.next/server/chunks/ssr/[root-of-the-server]__c9c1cfee._.js.map +1 -0
  252. package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
  253. package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
  254. package/web/.next/server/chunks/ssr/_1bb131c4._.js.map +1 -1
  255. package/web/.next/server/chunks/ssr/_1bb79fe8._.js +3 -0
  256. package/web/.next/server/chunks/ssr/_1bb79fe8._.js.map +1 -0
  257. package/web/.next/server/chunks/ssr/_2f6f48b8._.js +1 -1
  258. package/web/.next/server/chunks/ssr/_2f6f48b8._.js.map +1 -1
  259. package/web/.next/server/chunks/ssr/_435cd61a._.js +3 -0
  260. package/web/.next/server/chunks/ssr/_435cd61a._.js.map +1 -0
  261. package/web/.next/server/chunks/ssr/_75f4ccb3._.js +3 -0
  262. package/web/.next/server/chunks/ssr/_75f4ccb3._.js.map +1 -0
  263. package/web/.next/server/chunks/ssr/_ab069e13._.js +3 -0
  264. package/web/.next/server/chunks/ssr/_ab069e13._.js.map +1 -0
  265. package/web/.next/server/chunks/ssr/_c016175b._.js +3 -0
  266. package/web/.next/server/chunks/ssr/_c016175b._.js.map +1 -0
  267. package/web/.next/server/chunks/ssr/{_5f868392._.js → _c6b80726._.js} +2 -2
  268. package/web/.next/server/chunks/ssr/_c6b80726._.js.map +1 -0
  269. package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
  270. package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
  271. package/web/.next/server/chunks/ssr/_f605354c._.js +9 -0
  272. package/web/.next/server/chunks/ssr/_f605354c._.js.map +1 -0
  273. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  274. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  275. package/web/.next/server/chunks/ssr/node_modules__pnpm_b59e4b16._.js +3 -0
  276. package/web/.next/server/chunks/ssr/node_modules__pnpm_b59e4b16._.js.map +1 -0
  277. package/web/.next/server/chunks/ssr/src_presentation_web_0835b28e._.js +2 -2
  278. package/web/.next/server/chunks/ssr/src_presentation_web_0835b28e._.js.map +1 -1
  279. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_e99d78dd.js +1 -1
  280. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_e99d78dd.js.map +1 -1
  281. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
  282. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
  283. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
  284. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
  285. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
  286. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +1 -1
  287. package/web/.next/server/chunks/ssr/src_presentation_web_components_bdcfba35._.js +3 -0
  288. package/web/.next/server/chunks/ssr/src_presentation_web_components_bdcfba35._.js.map +1 -0
  289. package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
  290. package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
  291. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  292. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  293. package/web/.next/server/chunks/ssr/src_presentation_web_e8034a29._.js +2 -2
  294. package/web/.next/server/chunks/ssr/src_presentation_web_e8034a29._.js.map +1 -1
  295. package/web/.next/server/pages/500.html +2 -2
  296. package/web/.next/server/server-reference-manifest.js +1 -1
  297. package/web/.next/server/server-reference-manifest.json +33 -33
  298. package/web/.next/static/chunks/{bf46b5bf0d9d43b3.js → 0f070bdb053b3579.js} +2 -2
  299. package/web/.next/static/chunks/{9285299c4fb0f020.js → 139f46d14f2be0a6.js} +1 -1
  300. package/web/.next/static/chunks/{dc81cb5172953533.js → 3b27bd39bf11f076.js} +1 -1
  301. package/web/.next/static/chunks/418128e3931a55f3.js +1 -0
  302. package/web/.next/static/chunks/4562ee849ea13c3a.js +1 -0
  303. package/web/.next/static/chunks/{169d4ce4e5fa10d2.js → 485dfa2b1ba874ef.js} +1 -1
  304. package/web/.next/static/chunks/{da24af4a494de11a.js → 66c4848bc7b13df8.js} +1 -1
  305. package/web/.next/static/chunks/{7ce5aacd9b492e8c.js → 7eb1d12ff4e0a545.js} +1 -1
  306. package/web/.next/static/chunks/845d8e58a91014e6.js +1 -0
  307. package/web/.next/static/chunks/96049ca80ceb10f0.js +11 -0
  308. package/web/.next/static/chunks/bb03051ee7c01e64.js +2 -0
  309. package/web/.next/static/chunks/cca0f5112a9260d8.js +1 -0
  310. package/web/.next/static/chunks/d2739454715e5ef2.css +1 -0
  311. package/web/.next/static/chunks/d8d23303021cea22.js +1 -0
  312. package/web/.next/server/chunks/[root-of-the-server]__7d5492a0._.js +0 -3
  313. package/web/.next/server/chunks/[root-of-the-server]__7d5492a0._.js.map +0 -1
  314. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_rocket_1575cd4d.js +0 -3
  315. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_rocket_1575cd4d.js.map +0 -1
  316. package/web/.next/server/chunks/ssr/[root-of-the-server]__2ff2daf6._.js +0 -4
  317. package/web/.next/server/chunks/ssr/[root-of-the-server]__3155add4._.js +0 -3
  318. package/web/.next/server/chunks/ssr/[root-of-the-server]__3155add4._.js.map +0 -1
  319. package/web/.next/server/chunks/ssr/[root-of-the-server]__6367aea0._.js +0 -3
  320. package/web/.next/server/chunks/ssr/[root-of-the-server]__6367aea0._.js.map +0 -1
  321. package/web/.next/server/chunks/ssr/[root-of-the-server]__7b707feb._.js +0 -4
  322. package/web/.next/server/chunks/ssr/[root-of-the-server]__7b707feb._.js.map +0 -1
  323. package/web/.next/server/chunks/ssr/[root-of-the-server]__8763fd7a._.js +0 -4
  324. package/web/.next/server/chunks/ssr/[root-of-the-server]__8763fd7a._.js.map +0 -1
  325. package/web/.next/server/chunks/ssr/[root-of-the-server]__9c56d724._.js +0 -3
  326. package/web/.next/server/chunks/ssr/[root-of-the-server]__9c56d724._.js.map +0 -1
  327. package/web/.next/server/chunks/ssr/[root-of-the-server]__cfc116d5._.js +0 -3
  328. package/web/.next/server/chunks/ssr/[root-of-the-server]__cfc116d5._.js.map +0 -1
  329. package/web/.next/server/chunks/ssr/[root-of-the-server]__d3841d9e._.js +0 -3
  330. package/web/.next/server/chunks/ssr/[root-of-the-server]__d3841d9e._.js.map +0 -1
  331. package/web/.next/server/chunks/ssr/[root-of-the-server]__db9afe04._.js +0 -3
  332. package/web/.next/server/chunks/ssr/[root-of-the-server]__db9afe04._.js.map +0 -1
  333. package/web/.next/server/chunks/ssr/_250a63ae._.js +0 -3
  334. package/web/.next/server/chunks/ssr/_250a63ae._.js.map +0 -1
  335. package/web/.next/server/chunks/ssr/_273d4632._.js +0 -3
  336. package/web/.next/server/chunks/ssr/_273d4632._.js.map +0 -1
  337. package/web/.next/server/chunks/ssr/_5f868392._.js.map +0 -1
  338. package/web/.next/server/chunks/ssr/_922aa39f._.js +0 -3
  339. package/web/.next/server/chunks/ssr/_922aa39f._.js.map +0 -1
  340. package/web/.next/server/chunks/ssr/_a68d7e1c._.js +0 -9
  341. package/web/.next/server/chunks/ssr/_a68d7e1c._.js.map +0 -1
  342. package/web/.next/server/chunks/ssr/_c6ec0fa4._.js +0 -3
  343. package/web/.next/server/chunks/ssr/_c6ec0fa4._.js.map +0 -1
  344. package/web/.next/server/chunks/ssr/_ca5a8b32._.js +0 -3
  345. package/web/.next/server/chunks/ssr/_ca5a8b32._.js.map +0 -1
  346. package/web/.next/server/chunks/ssr/_f5316e67._.js +0 -3
  347. package/web/.next/server/chunks/ssr/_f5316e67._.js.map +0 -1
  348. package/web/.next/server/chunks/ssr/src_presentation_web_components_a5e6c910._.js +0 -3
  349. package/web/.next/server/chunks/ssr/src_presentation_web_components_a5e6c910._.js.map +0 -1
  350. package/web/.next/static/chunks/15a2249cbec45bee.js +0 -11
  351. package/web/.next/static/chunks/3a806cf059241bc9.js +0 -1
  352. package/web/.next/static/chunks/3fb7682246dbaf45.js +0 -1
  353. package/web/.next/static/chunks/55c131b6fc504375.js +0 -1
  354. package/web/.next/static/chunks/59e6b9b540f05bf1.js +0 -1
  355. package/web/.next/static/chunks/62a8173911f8f130.css +0 -1
  356. package/web/.next/static/chunks/b1f3c0e8e9872ef8.js +0 -1
  357. package/web/.next/static/chunks/f7577de2f653acfc.js +0 -2
  358. /package/web/.next/server/chunks/{[root-of-the-server]__7d63f9a4._.js.map → [root-of-the-server]__53013576._.js.map} +0 -0
  359. /package/web/.next/server/chunks/{[root-of-the-server]__a1c7c02a._.js.map → [root-of-the-server]__92078db6._.js.map} +0 -0
  360. /package/web/.next/static/{akrvSvVQ4BzHsJ1sA0rS7 → VKrxBSI0iPzA7QL_Xgt6y}/_buildManifest.js +0 -0
  361. /package/web/.next/static/{akrvSvVQ4BzHsJ1sA0rS7 → VKrxBSI0iPzA7QL_Xgt6y}/_clientMiddlewareManifest.json +0 -0
  362. /package/web/.next/static/{akrvSvVQ4BzHsJ1sA0rS7 → VKrxBSI0iPzA7QL_Xgt6y}/_ssgManifest.js +0 -0
@@ -8,7 +8,7 @@
8
8
  * Uses constructor dependency injection for the spawn function
9
9
  * to enable testability without mocking node:child_process directly.
10
10
  */
11
- import { writeFileSync, unlinkSync } from 'node:fs';
11
+ import { writeFileSync, unlinkSync, readdirSync, existsSync } from 'node:fs';
12
12
  import { execFileSync } from 'node:child_process';
13
13
  import { tmpdir } from 'node:os';
14
14
  import { join } from 'node:path';
@@ -36,11 +36,13 @@ const SUPPORTED_FEATURES = new Set(['session-resume', 'streaming']);
36
36
  */
37
37
  export class CursorExecutorService {
38
38
  spawn;
39
+ authConfig;
39
40
  agentType = 'cursor';
40
41
  /** When true, suppresses debug logging (set per-call via options.silent) */
41
42
  silent = false;
42
- constructor(spawn) {
43
+ constructor(spawn, authConfig) {
43
44
  this.spawn = spawn;
45
+ this.authConfig = authConfig;
44
46
  }
45
47
  /** Debug logging — writes to stdout so it appears in the worker log file */
46
48
  log(message) {
@@ -58,19 +60,34 @@ export class CursorExecutorService {
58
60
  // stream-json is unreliable on Windows where shell: true can mangle args.
59
61
  const args = this.buildArgs(prompt, options);
60
62
  const { proc, tmpFile } = this.spawnAgent(prompt, args, options);
63
+ // Diagnostic: verify streams are connected and process is alive
64
+ this.log(`[diag] proc.pid=${proc.pid}, killed=${proc.killed}`);
65
+ this.log(`[diag] stdout=${!!proc.stdout}, stderr=${!!proc.stderr}, stdin=${!!proc.stdin}`);
66
+ this.log(`[diag] CURSOR_API_KEY set=${!!process.env.CURSOR_API_KEY}, len=${process.env.CURSOR_API_KEY?.length ?? 0}`);
67
+ this.log(`[diag] authConfig.token set=${!!this.authConfig?.token}, method=${this.authConfig?.authMethod ?? 'none'}`);
68
+ this.log(`[diag] platform=${process.platform}, cwd=${options?.cwd ?? '(inherited)'}`);
61
69
  return new Promise((resolve, reject) => {
62
70
  let lineBuffer = '';
63
71
  let stderr = '';
64
72
  let timedOut = false;
65
73
  let timeoutId;
74
+ let stdoutChunks = 0;
75
+ let stderrChunks = 0;
76
+ const startTime = Date.now();
66
77
  // Accumulated from JSON events or raw text fallback
67
78
  let resultText = '';
68
79
  let rawText = '';
69
80
  let sessionId;
70
81
  let metadata;
82
+ // Periodic heartbeat to prove the executor is alive and waiting
83
+ const heartbeatId = setInterval(() => {
84
+ const elapsed = Math.round((Date.now() - startTime) / 1000);
85
+ this.log(`[diag] heartbeat ${elapsed}s: stdout_chunks=${stdoutChunks}, stderr_chunks=${stderrChunks}, pid_killed=${proc.killed}`);
86
+ }, 15_000);
71
87
  if (options?.timeout) {
72
88
  timeoutId = setTimeout(() => {
73
89
  timedOut = true;
90
+ this.log(`[diag] TIMEOUT after ${options.timeout}ms — killing process tree`);
74
91
  // On Windows, proc.kill() may not kill the entire process tree
75
92
  // (PowerShell + child agent process). Use taskkill /T for tree kill.
76
93
  if (process.platform === 'win32' && proc.pid) {
@@ -78,9 +95,11 @@ export class CursorExecutorService {
78
95
  execFileSync('taskkill', ['/F', '/T', '/PID', String(proc.pid)], {
79
96
  stdio: 'ignore',
80
97
  });
98
+ this.log(`[diag] taskkill /T /PID ${proc.pid} succeeded`);
81
99
  }
82
100
  catch {
83
101
  proc.kill();
102
+ this.log(`[diag] taskkill failed, fell back to proc.kill()`);
84
103
  }
85
104
  }
86
105
  else {
@@ -117,7 +136,12 @@ export class CursorExecutorService {
117
136
  }
118
137
  };
119
138
  proc.stdout?.on('data', (chunk) => {
120
- lineBuffer += chunk.toString();
139
+ stdoutChunks++;
140
+ const data = chunk.toString();
141
+ if (stdoutChunks <= 3) {
142
+ this.log(`[diag] stdout chunk #${stdoutChunks}: ${data.length} bytes, first 200: ${data.slice(0, 200).replace(/\n/g, '\\n')}`);
143
+ }
144
+ lineBuffer += data;
121
145
  const lines = lineBuffer.split('\n');
122
146
  lineBuffer = lines.pop() ?? '';
123
147
  for (const line of lines) {
@@ -127,19 +151,22 @@ export class CursorExecutorService {
127
151
  }
128
152
  });
129
153
  proc.stderr?.on('data', (chunk) => {
154
+ stderrChunks++;
130
155
  const data = chunk.toString();
131
156
  stderr += data;
132
- this.log(`stderr: ${data.trimEnd()}`);
157
+ this.log(`[diag] stderr chunk #${stderrChunks}: ${data.trimEnd()}`);
133
158
  // Detect fatal errors early so callers don't waste time retrying
134
159
  if (data.includes('Cannot use this model')) {
135
160
  if (timeoutId)
136
161
  clearTimeout(timeoutId);
162
+ clearInterval(heartbeatId);
137
163
  proc.kill();
138
164
  reject(new Error(data.trim()));
139
165
  }
140
166
  });
141
167
  proc.on('error', (error) => {
142
- this.log(`Process error event: ${error.message}`);
168
+ this.log(`[diag] Process ERROR event: ${error.message} (code=${error.code})`);
169
+ clearInterval(heartbeatId);
143
170
  if (timeoutId)
144
171
  clearTimeout(timeoutId);
145
172
  if (error.code === 'ENOENT') {
@@ -150,6 +177,8 @@ export class CursorExecutorService {
150
177
  }
151
178
  });
152
179
  proc.on('close', (code) => {
180
+ const elapsed = Math.round((Date.now() - startTime) / 1000);
181
+ clearInterval(heartbeatId);
153
182
  // Clean up temp file on Windows
154
183
  if (tmpFile) {
155
184
  try {
@@ -163,7 +192,7 @@ export class CursorExecutorService {
163
192
  processLine(lineBuffer.trim());
164
193
  // Use raw text as fallback when no JSON result was captured
165
194
  const finalText = resultText || rawText.trim();
166
- this.log(`Process closed with code ${code}, result=${finalText.length} chars`);
195
+ this.log(`[diag] Process CLOSE: code=${code}, elapsed=${elapsed}s, stdout_chunks=${stdoutChunks}, stderr_chunks=${stderrChunks}, result=${finalText.length} chars, raw=${rawText.length} chars`);
167
196
  if (timeoutId)
168
197
  clearTimeout(timeoutId);
169
198
  if (timedOut) {
@@ -310,36 +339,104 @@ export class CursorExecutorService {
310
339
  return args;
311
340
  }
312
341
  /**
313
- * Spawn the agent process, handling Windows specially via PowerShell.
342
+ * Resolve the cursor CLI's bundled node.exe and index.js paths on Windows.
343
+ *
344
+ * The cursor CLI installs to `%LOCALAPPDATA%\cursor-agent\` with:
345
+ * - `agent.cmd` / `cursor-agent.ps1` (shell wrappers)
346
+ * - `versions/<YYYY.MM.DD-commit>/node.exe` + `index.js`
347
+ *
348
+ * Spawning via agent.cmd creates a problematic nesting chain:
349
+ * PowerShell → agent.cmd → PowerShell → cursor-agent.ps1 → node.exe
350
+ * This chain hangs on Windows CI runners. Direct invocation bypasses it.
351
+ *
352
+ * @returns `{ nodePath, indexPath }` or `undefined` if not found
353
+ */
354
+ resolveCursorBinary() {
355
+ const localAppData = process.env.LOCALAPPDATA;
356
+ if (!localAppData)
357
+ return undefined;
358
+ const versionsDir = join(localAppData, 'cursor-agent', 'versions');
359
+ if (!existsSync(versionsDir))
360
+ return undefined;
361
+ // Find the latest version directory (format: YYYY.MM.DD-commit)
362
+ const versionPattern = /^\d{4}\.\d{1,2}\.\d{1,2}-[a-f0-9]+$/;
363
+ const versions = readdirSync(versionsDir)
364
+ .filter((d) => versionPattern.test(d))
365
+ .sort()
366
+ .reverse();
367
+ if (versions.length === 0)
368
+ return undefined;
369
+ const versionDir = join(versionsDir, versions[0]);
370
+ const nodePath = join(versionDir, 'node.exe');
371
+ const indexPath = join(versionDir, 'index.js');
372
+ if (!existsSync(nodePath) || !existsSync(indexPath))
373
+ return undefined;
374
+ return { nodePath, indexPath };
375
+ }
376
+ /**
377
+ * Spawn the agent process, handling Windows specially.
314
378
  *
315
- * On Windows, cursor CLI ships as `agent.cmd` which requires `shell: true`,
316
- * but cmd.exe mangles long `-p` arguments (8191-char limit + special chars).
317
- * Solution: write prompt to a temp file, invoke agent via PowerShell which
318
- * reads the file and passes the content as `-p`. PowerShell handles long
319
- * strings natively (32K limit) and doesn't mangle arguments.
379
+ * On Windows, the cursor CLI ships as `agent.cmd` which spawns PowerShell
380
+ * which runs `cursor-agent.ps1` which runs `node.exe index.js`. This triple
381
+ * nesting (PowerShell cmd.exe PowerShell node.exe) hangs on Windows
382
+ * CI runners. Solution: resolve the cursor CLI's bundled `node.exe` and
383
+ * `index.js` directly, bypassing all shell wrappers.
320
384
  *
321
385
  * On Linux/macOS, spawn `agent` directly — no shell needed.
322
386
  */
323
- spawnAgent(prompt, args, options) {
387
+ /**
388
+ * Build the subprocess environment: strip CLAUDECODE, inject CURSOR_API_KEY
389
+ * from authConfig when token auth is configured.
390
+ */
391
+ buildEnv(extra) {
324
392
  const { CLAUDECODE: _, ...cleanEnv } = process.env;
393
+ // Inject CURSOR_API_KEY from stored settings so the cursor CLI authenticates
394
+ // even when the env var isn't inherited (e.g. direct node.exe invocation on Windows).
395
+ if (this.authConfig?.authMethod === 'token' && this.authConfig.token) {
396
+ cleanEnv.CURSOR_API_KEY = this.authConfig.token;
397
+ this.log(`[diag] buildEnv: injected CURSOR_API_KEY from authConfig (${this.authConfig.token.length} chars)`);
398
+ }
399
+ else {
400
+ this.log(`[diag] buildEnv: NO token injection (authMethod=${this.authConfig?.authMethod ?? 'none'}, hasToken=${!!this.authConfig?.token}, envKey=${!!cleanEnv.CURSOR_API_KEY})`);
401
+ }
402
+ const env = extra ? { ...cleanEnv, ...extra } : cleanEnv;
403
+ this.log(`[diag] buildEnv: final CURSOR_API_KEY in env=${!!env.CURSOR_API_KEY}, len=${env.CURSOR_API_KEY?.length ?? 0}`);
404
+ return env;
405
+ }
406
+ spawnAgent(prompt, args, options) {
325
407
  const cwd = options?.cwd;
326
408
  if (IS_WINDOWS) {
327
- // Write prompt to temp file to bypass cmd.exe argument mangling
409
+ const resolved = this.resolveCursorBinary();
410
+ if (resolved) {
411
+ // Direct invocation: node.exe index.js <args>
412
+ // No shell wrappers, no nesting, no hangs.
413
+ const directArgs = [resolved.indexPath, ...args];
414
+ this.log(`Windows direct mode: ${resolved.nodePath}`);
415
+ this.log(`Args: ${directArgs.map((a) => (a.length > 80 ? `${a.slice(0, 77)}...` : a)).join(' ')}`);
416
+ const proc = this.spawn(resolved.nodePath, directArgs, {
417
+ cwd,
418
+ stdio: ['pipe', 'pipe', 'pipe'],
419
+ windowsHide: true,
420
+ env: this.buildEnv({ CURSOR_INVOKED_AS: 'agent' }),
421
+ });
422
+ this.log(`Direct PID: ${proc.pid ?? 'undefined (spawn may have failed)'}`);
423
+ if (proc.stdin)
424
+ proc.stdin.end();
425
+ return { proc, tmpFile: undefined };
426
+ }
427
+ // Fallback: if direct resolution fails, use PowerShell + temp file
428
+ this.log('Windows fallback: cursor binary not resolved, using PowerShell');
328
429
  const tmpFile = join(tmpdir(), `shep-cursor-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.txt`);
329
430
  writeFileSync(tmpFile, prompt, 'utf8');
330
- // Build the agent args WITHOUT -p and the prompt (they go via temp file)
331
431
  const agentFlags = args.filter((a) => a !== '-p' && a !== prompt).join(' ');
332
432
  const safePath = tmpFile.replace(/'/g, "''");
333
433
  const psCmd = `$p = Get-Content -Raw '${safePath}'; & agent ${agentFlags} -p $p`;
334
- this.log(`Windows PowerShell mode: wrote ${prompt.length} chars to ${tmpFile}`);
335
- this.log(`PS command: ${psCmd.replace(prompt, `<${prompt.length} chars>`)}`);
336
434
  const proc = this.spawn('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', psCmd], {
337
435
  cwd,
338
436
  stdio: ['pipe', 'pipe', 'pipe'],
339
437
  windowsHide: true,
340
- env: cleanEnv,
438
+ env: this.buildEnv(),
341
439
  });
342
- this.log(`PowerShell PID: ${proc.pid ?? 'undefined (spawn may have failed)'}`);
343
440
  if (proc.stdin)
344
441
  proc.stdin.end();
345
442
  return { proc, tmpFile };
@@ -347,7 +444,7 @@ export class CursorExecutorService {
347
444
  // Linux/macOS: spawn agent directly, no shell needed
348
445
  const spawnOpts = {
349
446
  stdio: ['pipe', 'pipe', 'pipe'],
350
- env: cleanEnv,
447
+ env: this.buildEnv(),
351
448
  };
352
449
  if (cwd)
353
450
  spawnOpts.cwd = cwd;
@@ -1 +1 @@
1
- {"version":3,"file":"dev-executor.service.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AACzF,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,EAC1B,MAAM,4EAA4E,CAAC;AAwIpF,qBAAa,uBAAwB,YAAW,cAAc;IAC5D,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAsB;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;;IAM3B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAOvF,aAAa,CAClB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B,aAAa,CAAC,yBAAyB,CAAC;IAK3C,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO;IAIhD,OAAO,CAAC,QAAQ;CAmEjB"}
1
+ {"version":3,"file":"dev-executor.service.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AACzF,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,EAC1B,MAAM,4EAA4E,CAAC;AAwIpF,qBAAa,uBAAwB,YAAW,cAAc;IAC5D,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAsB;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;;IAM3B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAcvF,aAAa,CAClB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B,aAAa,CAAC,yBAAyB,CAAC;IAK3C,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO;IAIhD,OAAO,CAAC,QAAQ;CAmEjB"}
@@ -131,7 +131,14 @@ export class DevAgentExecutorService {
131
131
  if (this.delayMs > 0) {
132
132
  await new Promise((resolve) => setTimeout(resolve, this.delayMs));
133
133
  }
134
- return { result: this.dispatch(prompt) };
134
+ const result = this.dispatch(prompt);
135
+ return {
136
+ result,
137
+ usage: {
138
+ inputTokens: Math.floor(prompt.length * 1.3),
139
+ outputTokens: Math.floor(result.length * 1.3),
140
+ },
141
+ };
135
142
  }
136
143
  async *executeStream(prompt, options) {
137
144
  const result = await this.execute(prompt, options);
@@ -1 +1 @@
1
- {"version":3,"file":"ci-watch-fix-loop.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AACpG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yEAAyE,CAAC;AAClH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iEAAiE,CAAC;AAKrG,OAAO,EAAE,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+DAA+D,CAAC;AAK3G,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,cAAc,CAAC;IACzB,YAAY,EAAE,aAAa,CAAC;IAC5B,iBAAiB,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC;CACpE;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,qBAAqB,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC/E,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,EAAE,UAAU,CAAC;CACjB;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAEpG,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,QAAQ,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,WAAW,EAAE,gBAAgB,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CA6I3B"}
1
+ {"version":3,"file":"ci-watch-fix-loop.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AACpG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yEAAyE,CAAC;AAClH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iEAAiE,CAAC;AAKrG,OAAO,EAAE,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+DAA+D,CAAC;AAK3G,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,cAAc,CAAC;IACzB,YAAY,EAAE,aAAa,CAAC;IAC5B,iBAAiB,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC;CACpE;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,qBAAqB,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC/E,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,EAAE,UAAU,CAAC;CACjB;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAEpG,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,QAAQ,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,WAAW,EAAE,gBAAgB,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CA8I3B"}
@@ -23,6 +23,7 @@ export async function runCiWatchFixLoop(deps, params) {
23
23
  const maxAttempts = settings.workflow?.ciMaxFixAttempts ?? 3;
24
24
  const timeoutMs = settings.workflow?.ciWatchTimeoutMs ?? 600_000;
25
25
  const logMaxChars = settings.workflow?.ciLogMaxChars ?? 50_000;
26
+ const pollInterval = settings.workflow?.ciWatchPollIntervalSeconds ?? 30;
26
27
  let ciFixAttempts = params.existingAttempts;
27
28
  const ciFixHistory = [];
28
29
  let ciFixStatus;
@@ -67,7 +68,7 @@ export async function runCiWatchFixLoop(deps, params) {
67
68
  // Initial CI watch
68
69
  let watchResult;
69
70
  try {
70
- watchResult = await gitPrService.watchCi(cwd, branch, timeoutMs);
71
+ watchResult = await gitPrService.watchCi(cwd, branch, timeoutMs, pollInterval);
71
72
  }
72
73
  catch (err) {
73
74
  if (err instanceof GitPrError && err.code === GitPrErrorCode.CI_TIMEOUT) {
@@ -111,7 +112,7 @@ export async function runCiWatchFixLoop(deps, params) {
111
112
  // Watch CI after fix
112
113
  let fixWatchResult;
113
114
  try {
114
- fixWatchResult = await gitPrService.watchCi(cwd, branch, timeoutMs);
115
+ fixWatchResult = await gitPrService.watchCi(cwd, branch, timeoutMs, pollInterval);
115
116
  }
116
117
  catch (err) {
117
118
  if (err instanceof GitPrError && err.code === GitPrErrorCode.CI_TIMEOUT) {
@@ -1 +1 @@
1
- {"version":3,"file":"merge.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AACpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yEAAyE,CAAC;AAClH,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACd,MAAM,iEAAiE,CAAC;AAkBzE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,uEAAuE,CAAC;AAE3H,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,cAAc,CAAC;IACzB,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1E,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD,iBAAiB,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC;IACnE;;OAEG;IACH,gBAAgB,EAAE,CAChB,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EACrB,SAAS,CAAC,EAAE,OAAO,KAChB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB;;;OAGG;IACH,WAAW,EAAE,CACX,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,eAAe,CAAC,EAAE,MAAM,KACrB,OAAO,CAAC,OAAO,CAAC,CAAC;IACtB;;OAEG;IACH,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACxD,YAAY,EAAE,aAAa,CAAC;IAC5B,6BAA6B,EAAE,IAAI,CAAC,6BAA6B,EAAE,SAAS,CAAC,CAAC;CAC/E;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,IAGnC,OAAO,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CA8R7E"}
1
+ {"version":3,"file":"merge.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AACpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yEAAyE,CAAC;AAClH,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACd,MAAM,iEAAiE,CAAC;AAmBzE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,uEAAuE,CAAC;AAE3H,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,cAAc,CAAC;IACzB,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1E,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD,iBAAiB,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC;IACnE;;OAEG;IACH,gBAAgB,EAAE,CAChB,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EACrB,SAAS,CAAC,EAAE,OAAO,KAChB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB;;;OAGG;IACH,WAAW,EAAE,CACX,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,eAAe,CAAC,EAAE,MAAM,KACrB,OAAO,CAAC,OAAO,CAAC,CAAC;IACtB;;OAEG;IACH,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACxD,YAAY,EAAE,aAAa,CAAC;IAC5B,6BAA6B,EAAE,IAAI,CAAC,6BAA6B,EAAE,SAAS,CAAC,CAAC;CAC/E;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,IAGnC,OAAO,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAmT7E"}
@@ -21,6 +21,7 @@ import { updateNodeLifecycle } from '../../lifecycle-context.js';
21
21
  import { buildCommitPushPrPrompt } from '../prompts/merge-prompts.js';
22
22
  import { parseCommitHash, parsePrUrl } from './merge-output-parser.js';
23
23
  import { runCiWatchFixLoop } from './ci-watch-fix-loop.js';
24
+ import { getSettings } from '../../../../../services/settings.service.js';
24
25
  /**
25
26
  * Factory that creates the merge node function.
26
27
  *
@@ -67,9 +68,14 @@ export function createMergeNode(deps) {
67
68
  }
68
69
  const messages = [];
69
70
  const startTime = Date.now();
70
- const mergeTimingId = await recordPhaseStart('merge');
71
+ let totalInputTokens = 0;
72
+ let totalOutputTokens = 0;
73
+ const { executor } = deps;
74
+ const mergeTimingId = await recordPhaseStart('merge', {
75
+ agentType: executor.agentType,
76
+ modelId: state.model,
77
+ });
71
78
  try {
72
- const { executor } = deps;
73
79
  const cwd = state.worktreePath;
74
80
  const feature = await deps.featureRepository.findById(state.featureId);
75
81
  const branch = feature?.branch ?? `feat/${state.featureId}`;
@@ -98,6 +104,8 @@ export function createMergeNode(deps) {
98
104
  const commitResult = await retryExecute(executor, commitPushPrPrompt, options, {
99
105
  logger: log,
100
106
  });
107
+ totalInputTokens += commitResult.usage?.inputTokens ?? 0;
108
+ totalOutputTokens += commitResult.usage?.outputTokens ?? 0;
101
109
  commitHash = parseCommitHash(commitResult.result) ?? state.commitHash;
102
110
  messages.push(`[merge] Agent completed commit/push/PR operations`);
103
111
  if (effectiveState.openPr) {
@@ -122,8 +130,9 @@ export function createMergeNode(deps) {
122
130
  messages.push(`[merge] PR created: ${prUrl}`);
123
131
  }
124
132
  }
125
- // --- CI watch/fix loop (when push or openPr is enabled) ---
126
- if (effectiveState.push || effectiveState.openPr) {
133
+ // --- CI watch/fix loop (when push or openPr is enabled and CI watch is not disabled) ---
134
+ const ciWatchEnabled = getSettings().workflow?.ciWatchEnabled !== false;
135
+ if (ciWatchEnabled && (effectiveState.push || effectiveState.openPr)) {
127
136
  const ciResult = await runCiWatchFixLoop({
128
137
  executor,
129
138
  gitPrService: deps.gitPrService,
@@ -171,7 +180,11 @@ export function createMergeNode(deps) {
171
180
  // --- Merge approval gate ---
172
181
  if (shouldInterrupt('merge', state.approvalGates)) {
173
182
  log.info('Interrupting for merge approval');
174
- await recordPhaseEnd(mergeTimingId, Date.now() - startTime);
183
+ await recordPhaseEnd(mergeTimingId, Date.now() - startTime, {
184
+ inputTokens: totalInputTokens || undefined,
185
+ outputTokens: totalOutputTokens || undefined,
186
+ exitCode: 'success',
187
+ });
175
188
  await recordApprovalWaitStart(mergeTimingId);
176
189
  const diffSummary = await deps.getDiffSummary(cwd, baseBranch);
177
190
  interrupt({
@@ -250,7 +263,11 @@ export function createMergeNode(deps) {
250
263
  }
251
264
  }
252
265
  const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
253
- await recordPhaseEnd(mergeTimingId, Date.now() - startTime);
266
+ await recordPhaseEnd(mergeTimingId, Date.now() - startTime, {
267
+ inputTokens: totalInputTokens || undefined,
268
+ outputTokens: totalOutputTokens || undefined,
269
+ exitCode: 'success',
270
+ });
254
271
  messages.push(`[merge] Complete (${elapsed}s)`);
255
272
  log.info(`Merge flow complete (${elapsed}s)`);
256
273
  return {
@@ -274,7 +291,12 @@ export function createMergeNode(deps) {
274
291
  const message = err instanceof Error ? err.message : String(err);
275
292
  const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
276
293
  log.error(`Merge failed: ${message} (${elapsed}s)`);
277
- await recordPhaseEnd(mergeTimingId, Date.now() - startTime);
294
+ await recordPhaseEnd(mergeTimingId, Date.now() - startTime, {
295
+ inputTokens: totalInputTokens || undefined,
296
+ outputTokens: totalOutputTokens || undefined,
297
+ exitCode: 'error',
298
+ errorMessage: message.slice(0, 1000),
299
+ });
278
300
  throw err;
279
301
  }
280
302
  };
@@ -1 +1 @@
1
- {"version":3,"file":"node-helpers.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"node-helpers.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.ts"],"names":[],"mappings":"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"}
@@ -407,20 +407,28 @@ export function executeNode(nodeName, executor, buildPrompt) {
407
407
  }
408
408
  }
409
409
  const startTime = Date.now();
410
- // Record phase start (no-op if timing context not set)
411
- const timingId = await recordPhaseStart(nodeName);
410
+ const resumePrefix = buildResumeContext(state.resumeReason);
411
+ const prompt = resumePrefix + buildPrompt(state, log);
412
+ const options = buildExecutorOptions(state, undefined, nodeName);
413
+ // Record phase start with pre-execution metadata
414
+ const timingId = await recordPhaseStart(nodeName, {
415
+ prompt,
416
+ modelId: state.model,
417
+ agentType: executor.agentType,
418
+ });
412
419
  try {
413
- const resumePrefix = buildResumeContext(state.resumeReason);
414
- const prompt = resumePrefix + buildPrompt(state, log);
415
- const options = buildExecutorOptions(state, undefined, nodeName);
416
420
  log.info(`Executing agent at cwd=${options.cwd}`);
417
421
  log.info(`Prompt length: ${prompt.length} chars`);
418
422
  const result = await executor.execute(prompt, options);
419
423
  const durationMs = Date.now() - startTime;
420
424
  const elapsed = (durationMs / 1000).toFixed(1);
421
425
  log.info(`Complete (${result.result.length} chars, ${elapsed}s)`);
422
- // Record phase completion
423
- await recordPhaseEnd(timingId, durationMs);
426
+ // Record phase completion with post-execution metadata
427
+ await recordPhaseEnd(timingId, durationMs, {
428
+ inputTokens: result.usage?.inputTokens,
429
+ outputTokens: result.usage?.outputTokens,
430
+ exitCode: 'success',
431
+ });
424
432
  // Mark phase complete BEFORE interrupting so that on resume the
425
433
  // node detects the work is already done and returns early.
426
434
  markPhaseComplete(state.specDir, nodeName, log);
@@ -455,7 +463,10 @@ export function executeNode(nodeName, executor, buildPrompt) {
455
463
  const elapsed = (durationMs / 1000).toFixed(1);
456
464
  log.error(`${message} (after ${elapsed}s)`);
457
465
  // Record phase end even on failure so timing shows duration, not "running"
458
- await recordPhaseEnd(timingId, durationMs);
466
+ await recordPhaseEnd(timingId, durationMs, {
467
+ exitCode: 'error',
468
+ errorMessage: message.slice(0, 1000),
469
+ });
459
470
  // Throw so LangGraph does NOT checkpoint this node as "completed".
460
471
  // The worker catch block marks the run as failed, and on resume
461
472
  // LangGraph re-executes from the last successfully checkpointed node.
@@ -1,9 +1,12 @@
1
1
  /**
2
2
  * Merge Node Prompt Builders
3
3
  *
4
- * Builds prompts for the two agent calls in the merge node:
4
+ * Builds prompts for agent calls in the merge node:
5
5
  * 1. buildCommitPushPrPrompt — commit (always), push (conditional), PR create (conditional)
6
- * 2. buildMergeSquashPromptmerge/squash PR or branch
6
+ * 2. buildCiWatchFixPromptdiagnose and fix CI failures
7
+ *
8
+ * NOTE: The actual PR merge and local squash-merge are handled directly by
9
+ * GitPrService.mergePr() and GitPrService.localMergeSquash() — not via agent prompts.
7
10
  */
8
11
  import { type Evidence } from '../../../../../../domain/generated/output.js';
9
12
  import type { FeatureAgentState } from '../../state.js';
@@ -41,12 +44,4 @@ export declare function buildCommitPushPrPrompt(state: FeatureAgentState, branch
41
44
  * @param branch - Feature branch name to push to after fixing
42
45
  */
43
46
  export declare function buildCiWatchFixPrompt(failureLogs: string, attemptNumber: number, maxAttempts: number, branch: string): string;
44
- /**
45
- * Build a prompt for the merge/squash agent call.
46
- *
47
- * When a PR exists, uses `gh pr merge` (remote operation — no local merge needed).
48
- * When no PR exists, performs a local merge in the ORIGINAL repo directory
49
- * (not the worktree, which IS the feature branch).
50
- */
51
- export declare function buildMergeSquashPrompt(state: FeatureAgentState, branch: string, baseBranch: string, hasRemote?: boolean): string;
52
47
  //# sourceMappingURL=merge-prompts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"merge-prompts.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAE3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAwCxD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAU9F;AAuCD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,QAAQ,EAAE,EACpB,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAUR;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAmER;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,GACb,MAAM,CA0BR;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,SAAS,UAAQ,GAChB,MAAM,CAkER"}
1
+ {"version":3,"file":"merge-prompts.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAE3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAwCxD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAU9F;AAuCD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,QAAQ,EAAE,EACpB,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAUR;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAmER;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,GACb,MAAM,CA0BR"}
@@ -1,9 +1,12 @@
1
1
  /**
2
2
  * Merge Node Prompt Builders
3
3
  *
4
- * Builds prompts for the two agent calls in the merge node:
4
+ * Builds prompts for agent calls in the merge node:
5
5
  * 1. buildCommitPushPrPrompt — commit (always), push (conditional), PR create (conditional)
6
- * 2. buildMergeSquashPromptmerge/squash PR or branch
6
+ * 2. buildCiWatchFixPromptdiagnose and fix CI failures
7
+ *
8
+ * NOTE: The actual PR merge and local squash-merge are handled directly by
9
+ * GitPrService.mergePr() and GitPrService.localMergeSquash() — not via agent prompts.
7
10
  */
8
11
  import yaml from 'js-yaml';
9
12
  import { EvidenceType } from '../../../../../../domain/generated/output.js';
@@ -215,74 +218,3 @@ ${failureLogs}
215
218
  - Do NOT create a new branch — push directly to \`${branch}\`
216
219
  - If the failure is unclear, make your best diagnosis and explain your reasoning in the commit message`;
217
220
  }
218
- /**
219
- * Build a prompt for the merge/squash agent call.
220
- *
221
- * When a PR exists, uses `gh pr merge` (remote operation — no local merge needed).
222
- * When no PR exists, performs a local merge in the ORIGINAL repo directory
223
- * (not the worktree, which IS the feature branch).
224
- */
225
- export function buildMergeSquashPrompt(state, branch, baseBranch, hasRemote = false) {
226
- if (state.prUrl && state.prNumber) {
227
- // PR path: remote merge via GitHub CLI — no local merge needed
228
- return `You are merging a pull request via the GitHub CLI.
229
-
230
- ## PR to Merge
231
-
232
- - PR URL: ${state.prUrl}
233
- - PR Number: #${state.prNumber}
234
-
235
- ## Instructions
236
-
237
- 1. Merge the PR using squash merge with auto-merge: \`gh pr merge ${state.prNumber} --squash --delete-branch --auto\`
238
- - The --auto flag queues the merge to execute automatically once all branch protection requirements (CI checks, reviews, etc.) are satisfied
239
- 2. If the merge command fails, report the error clearly
240
-
241
- ## Constraints
242
-
243
- - Use squash merge strategy to keep history clean
244
- - Report the merge result clearly`;
245
- }
246
- // Non-PR path: local merge in the ORIGINAL repo (not the worktree)
247
- const originalRepo = state.repositoryPath;
248
- const fetchSteps = hasRemote
249
- ? `2. Fetch latest: \`git fetch origin\`
250
- 3. Checkout the base branch: \`git checkout ${baseBranch}\`
251
- 4. Pull latest base: \`git pull origin ${baseBranch}\`
252
- 5. Merge the feature branch: \`git merge --squash ${branch}\`
253
- 6. If merge conflicts are encountered, resolve them manually and complete the merge
254
- 7. Commit the squash merge with a descriptive conventional commit message
255
- 8. Delete the feature branch after successful merge: \`git branch -d ${branch}\``
256
- : `2. Checkout the base branch: \`git checkout ${baseBranch}\`
257
- 3. Merge the feature branch: \`git merge --squash ${branch}\`
258
- 4. If merge conflicts are encountered, resolve them manually and complete the merge
259
- 5. Commit the squash merge with a descriptive conventional commit message
260
- 6. Delete the feature branch after successful merge: \`git branch -d ${branch}\``;
261
- return `You are performing a local merge in the original repository directory.
262
-
263
- IMPORTANT: You MUST run all git commands in the original repository directory, NOT in any worktree.
264
-
265
- ## Branch to Merge
266
-
267
- - Feature branch: \`${branch}\`
268
- - Base branch: \`${baseBranch}\`
269
-
270
- ## Working Directory
271
-
272
- ${originalRepo}
273
-
274
- ## Instructions
275
-
276
- 1. Change to the original repository: \`cd ${originalRepo}\`
277
- ${fetchSteps}
278
-
279
- ## Constraints
280
-
281
- - Use squash merge strategy to keep history clean
282
- - All commands MUST run in \`${originalRepo}\` (the original repo), NOT in the worktree
283
- - NEVER remove, modify, or prune git worktrees — they are managed by the system
284
- - Do NOT try to \`git checkout\` the feature branch — \`git merge --squash\` reads from it without checking it out
285
- - If conflicts arise during merge, attempt to resolve them intelligently
286
- - Do NOT modify any source code beyond what is needed for conflict resolution
287
- - Report the merge result clearly`;
288
- }
@@ -21,6 +21,12 @@ export declare function setPhaseTimingContext(runId: string, repository: IPhaseT
21
21
  * Clear the phase timing context. Useful for testing.
22
22
  */
23
23
  export declare function clearPhaseTimingContext(): void;
24
+ /** Pre-execution metadata recorded at phase start. */
25
+ export interface PhaseStartMetadata {
26
+ prompt?: string;
27
+ modelId?: string;
28
+ agentType?: string;
29
+ }
24
30
  /**
25
31
  * Record the start of a phase. Returns the timing record ID (for later update)
26
32
  * or null if context is not set or save fails.
@@ -28,12 +34,20 @@ export declare function clearPhaseTimingContext(): void;
28
34
  * Automatically appends an iteration suffix (`:2`, `:3`, …) when the same
29
35
  * phase has already been recorded for this run (e.g. after a rejection loop).
30
36
  */
31
- export declare function recordPhaseStart(phase: string): Promise<string | null>;
37
+ export declare function recordPhaseStart(phase: string, metadata?: PhaseStartMetadata): Promise<string | null>;
38
+ /** Post-execution metadata recorded at phase end. */
39
+ export interface PhaseEndMetadata {
40
+ inputTokens?: number;
41
+ outputTokens?: number;
42
+ exitCode?: string;
43
+ errorMessage?: string;
44
+ }
32
45
  /**
33
- * Record the end of a phase. Updates the timing record with completedAt and durationMs.
46
+ * Record the end of a phase. Updates the timing record with completedAt, durationMs,
47
+ * and optional execution metadata (token usage, exit code, error).
34
48
  * No-op if timingId is null (phase start was skipped or failed).
35
49
  */
36
- export declare function recordPhaseEnd(timingId: string | null, durationMs: number): Promise<void>;
50
+ export declare function recordPhaseEnd(timingId: string | null, durationMs: number, metadata?: PhaseEndMetadata): Promise<void>;
37
51
  /**
38
52
  * Record an instant lifecycle event (e.g., run:started, run:stopped, run:crashed).
39
53
  * These are phase timing records with zero duration, used to mark events in the timeline.