@shepai/cli 1.120.0 → 1.121.0-pr375.8009cc7

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 (278) hide show
  1. package/apis/json-schema/PhaseTiming.yaml +17 -0
  2. package/dist/packages/core/src/application/ports/output/agents/agent-executor.interface.d.ts +19 -5
  3. package/dist/packages/core/src/application/ports/output/agents/agent-executor.interface.d.ts.map +1 -1
  4. package/dist/packages/core/src/application/ports/output/agents/phase-timing-repository.interface.d.ts +1 -1
  5. package/dist/packages/core/src/application/ports/output/agents/phase-timing-repository.interface.d.ts.map +1 -1
  6. package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.d.ts +3 -1
  7. package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.d.ts.map +1 -1
  8. package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.js +4 -2
  9. package/dist/packages/core/src/domain/generated/output.d.ts +22 -0
  10. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  11. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/039-add-phase-timing-extended-stats.d.ts +11 -0
  12. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/039-add-phase-timing-extended-stats.d.ts.map +1 -0
  13. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/039-add-phase-timing-extended-stats.js +25 -0
  14. package/dist/packages/core/src/infrastructure/repositories/sqlite-phase-timing.repository.d.ts +1 -1
  15. package/dist/packages/core/src/infrastructure/repositories/sqlite-phase-timing.repository.d.ts.map +1 -1
  16. package/dist/packages/core/src/infrastructure/repositories/sqlite-phase-timing.repository.js +42 -2
  17. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.d.ts +5 -0
  18. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.d.ts.map +1 -1
  19. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.js +38 -13
  20. package/dist/packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.d.ts.map +1 -1
  21. package/dist/packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.js +23 -2
  22. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/fast-implement.node.d.ts.map +1 -1
  23. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/fast-implement.node.js +34 -1
  24. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.d.ts.map +1 -1
  25. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.js +12 -0
  26. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts.map +1 -1
  27. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.js +5 -0
  28. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/fast-implement.prompt.d.ts.map +1 -1
  29. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/fast-implement.prompt.js +4 -1
  30. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/phase-timing-context.d.ts +5 -0
  31. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/phase-timing-context.d.ts.map +1 -1
  32. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/phase-timing-context.js +9 -0
  33. package/dist/src/presentation/tui/prompts/prd-review-question.prompt.d.ts +1 -1
  34. package/dist/src/presentation/tui/prompts/prd-review-question.prompt.d.ts.map +1 -1
  35. package/dist/src/presentation/tui/prompts/prd-review-question.prompt.js +5 -2
  36. package/dist/src/presentation/tui/wizards/prd-review.wizard.d.ts.map +1 -1
  37. package/dist/src/presentation/tui/wizards/prd-review.wizard.js +4 -2
  38. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.d.ts.map +1 -1
  39. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.js +2 -43
  40. package/dist/src/presentation/web/app/actions/approve-feature.d.ts.map +1 -1
  41. package/dist/src/presentation/web/app/actions/approve-feature.js +9 -0
  42. package/dist/src/presentation/web/app/actions/get-feature-phase-timings.d.ts +5 -0
  43. package/dist/src/presentation/web/app/actions/get-feature-phase-timings.d.ts.map +1 -1
  44. package/dist/src/presentation/web/app/actions/get-feature-phase-timings.js +5 -0
  45. package/dist/src/presentation/web/app/actions/reject-feature.d.ts.map +1 -1
  46. package/dist/src/presentation/web/app/actions/reject-feature.js +9 -0
  47. package/dist/src/presentation/web/app/actions/stop-feature.d.ts +5 -0
  48. package/dist/src/presentation/web/app/actions/stop-feature.d.ts.map +1 -0
  49. package/dist/src/presentation/web/app/actions/stop-feature.js +30 -0
  50. package/dist/src/presentation/web/app/api/npm-version/route.d.ts.map +1 -1
  51. package/dist/src/presentation/web/app/api/npm-version/route.js +9 -1
  52. package/dist/src/presentation/web/app/api/sessions/route.d.ts.map +1 -1
  53. package/dist/src/presentation/web/app/api/sessions/route.js +43 -10
  54. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.d.ts.map +1 -1
  55. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.js +15 -6
  56. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.d.ts.map +1 -1
  57. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.js +35 -0
  58. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.d.ts.map +1 -1
  59. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.js +2 -2
  60. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts +2 -0
  61. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts.map +1 -1
  62. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.js +4 -0
  63. package/dist/src/presentation/web/components/common/feature-list-item/feature-list-item.stories.d.ts +1 -0
  64. package/dist/src/presentation/web/components/common/feature-list-item/feature-list-item.stories.d.ts.map +1 -1
  65. package/dist/src/presentation/web/components/common/feature-list-item/feature-list-item.stories.js +8 -0
  66. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +1 -0
  67. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +1 -1
  68. package/dist/src/presentation/web/components/common/feature-status-badges/feature-status-badges.stories.js +6 -6
  69. package/dist/src/presentation/web/components/common/feature-status-config.d.ts +1 -1
  70. package/dist/src/presentation/web/components/common/feature-status-config.d.ts.map +1 -1
  71. package/dist/src/presentation/web/components/common/feature-status-config.js +8 -1
  72. package/dist/src/presentation/web/components/common/feature-status-group/feature-status-group.stories.d.ts +1 -0
  73. package/dist/src/presentation/web/components/common/feature-status-group/feature-status-group.stories.d.ts.map +1 -1
  74. package/dist/src/presentation/web/components/common/feature-status-group/feature-status-group.stories.js +7 -0
  75. package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.js +1 -1
  76. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  77. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +3 -1
  78. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +1 -0
  79. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  80. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +18 -0
  81. package/dist/src/presentation/web/hooks/sidebar-features-context.js +1 -1
  82. package/dist/src/presentation/web/lib/derive-graph.d.ts +2 -0
  83. package/dist/src/presentation/web/lib/derive-graph.d.ts.map +1 -1
  84. package/dist/src/presentation/web/lib/derive-graph.js +5 -0
  85. package/dist/tsconfig.build.tsbuildinfo +1 -1
  86. package/package.json +3 -5
  87. package/web/.next/BUILD_ID +1 -1
  88. package/web/.next/build-manifest.json +2 -2
  89. package/web/.next/fallback-build-manifest.json +2 -2
  90. package/web/.next/prerender-manifest.json +3 -3
  91. package/web/.next/required-server-files.js +3 -3
  92. package/web/.next/required-server-files.json +3 -3
  93. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +57 -42
  94. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
  95. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  96. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  97. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +69 -54
  98. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +1 -1
  99. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  100. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  101. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +69 -54
  102. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
  103. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  104. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  105. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +53 -38
  106. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
  107. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  108. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  109. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +57 -42
  110. package/web/.next/server/app/(dashboard)/create/page.js +1 -1
  111. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  112. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  113. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +69 -54
  114. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +1 -1
  115. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  116. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  117. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +69 -54
  118. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
  119. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  120. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  121. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +53 -38
  122. package/web/.next/server/app/(dashboard)/page.js +1 -1
  123. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  124. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  125. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +53 -38
  126. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
  127. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  128. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  129. package/web/.next/server/app/_global-error.html +2 -2
  130. package/web/.next/server/app/_global-error.rsc +1 -1
  131. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  132. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  133. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  134. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  135. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  136. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  137. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  138. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  139. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  140. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  141. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  142. package/web/.next/server/app/api/sessions/route.js +1 -1
  143. package/web/.next/server/app/api/sessions/route.js.nft.json +1 -1
  144. package/web/.next/server/app/settings/page/server-reference-manifest.json +6 -6
  145. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  146. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  147. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  148. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  149. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  150. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  151. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  152. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  153. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  154. package/web/.next/server/app/version/page.js.nft.json +1 -1
  155. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  156. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +1 -1
  157. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +1 -1
  158. package/web/.next/server/chunks/[externals]_node:fs_ddf6f167._.js +3 -0
  159. package/web/.next/server/chunks/[externals]_node:fs_ddf6f167._.js.map +1 -0
  160. package/web/.next/server/chunks/[root-of-the-server]__3b72e8b0._.js +1 -1
  161. package/web/.next/server/chunks/[root-of-the-server]__3b72e8b0._.js.map +1 -1
  162. package/web/.next/server/chunks/[root-of-the-server]__42b7ab55._.js +1 -1
  163. package/web/.next/server/chunks/[root-of-the-server]__42b7ab55._.js.map +1 -1
  164. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  165. package/web/.next/server/chunks/[root-of-the-server]__a62bd945._.js +3 -0
  166. package/web/.next/server/chunks/[root-of-the-server]__a62bd945._.js.map +1 -0
  167. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js +1 -1
  168. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js.map +1 -1
  169. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  170. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  171. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js +3 -0
  172. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js.map +1 -0
  173. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js +3 -0
  174. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js.map +1 -0
  175. package/web/.next/server/chunks/ssr/[root-of-the-server]__06fef644._.js +1 -1
  176. package/web/.next/server/chunks/ssr/[root-of-the-server]__2698e9f4._.js +3 -0
  177. package/web/.next/server/chunks/ssr/[root-of-the-server]__2698e9f4._.js.map +1 -0
  178. package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js +1 -1
  179. package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js.map +1 -1
  180. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  181. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  182. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +2 -2
  183. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js.map +1 -1
  184. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  185. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  186. package/web/.next/server/chunks/ssr/[root-of-the-server]__8c553503._.js +2 -2
  187. package/web/.next/server/chunks/ssr/[root-of-the-server]__8e3bf5d7._.js +3 -0
  188. package/web/.next/server/chunks/ssr/[root-of-the-server]__8e3bf5d7._.js.map +1 -0
  189. package/web/.next/server/chunks/ssr/[root-of-the-server]__a022445f._.js +2 -2
  190. package/web/.next/server/chunks/ssr/[root-of-the-server]__a022445f._.js.map +1 -1
  191. package/web/.next/server/chunks/ssr/[root-of-the-server]__a7de2711._.js +2 -2
  192. package/web/.next/server/chunks/ssr/[root-of-the-server]__a7de2711._.js.map +1 -1
  193. package/web/.next/server/chunks/ssr/[root-of-the-server]__b724df9e._.js +1 -1
  194. package/web/.next/server/chunks/ssr/[root-of-the-server]__b724df9e._.js.map +1 -1
  195. package/web/.next/server/chunks/ssr/[root-of-the-server]__c07f9f79._.js +3 -0
  196. package/web/.next/server/chunks/ssr/[root-of-the-server]__c07f9f79._.js.map +1 -0
  197. package/web/.next/server/chunks/ssr/[root-of-the-server]__c605a375._.js +3 -0
  198. package/web/.next/server/chunks/ssr/[root-of-the-server]__c605a375._.js.map +1 -0
  199. package/web/.next/server/chunks/ssr/_0dc2cfd3._.js +3 -0
  200. package/web/.next/server/chunks/ssr/_0dc2cfd3._.js.map +1 -0
  201. package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
  202. package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
  203. package/web/.next/server/chunks/ssr/_1bb131c4._.js.map +1 -1
  204. package/web/.next/server/chunks/ssr/_2f6f48b8._.js +1 -1
  205. package/web/.next/server/chunks/ssr/_2f6f48b8._.js.map +1 -1
  206. package/web/.next/server/chunks/ssr/{_16e2ff25._.js → _53db828c._.js} +2 -2
  207. package/web/.next/server/chunks/ssr/{_16e2ff25._.js.map → _53db828c._.js.map} +1 -1
  208. package/web/.next/server/chunks/ssr/{_c93f4352._.js → _5764932e._.js} +2 -2
  209. package/web/.next/server/chunks/ssr/{_c93f4352._.js.map → _5764932e._.js.map} +1 -1
  210. package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
  211. package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
  212. package/web/.next/server/chunks/ssr/_d8fc93b2._.js +3 -0
  213. package/web/.next/server/chunks/ssr/{_503b26e9._.js.map → _d8fc93b2._.js.map} +1 -1
  214. package/web/.next/server/chunks/ssr/{_f605354c._.js → _f1a649e3._.js} +3 -3
  215. package/web/.next/server/chunks/ssr/_f1a649e3._.js.map +1 -0
  216. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  217. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  218. package/web/.next/server/chunks/ssr/{src_presentation_web_0835b28e._.js → src_presentation_web_5f039db1._.js} +3 -3
  219. package/web/.next/server/chunks/ssr/{src_presentation_web_0835b28e._.js.map → src_presentation_web_5f039db1._.js.map} +1 -1
  220. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js +3 -0
  221. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js.map +1 -0
  222. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
  223. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
  224. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
  225. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
  226. package/web/.next/server/chunks/ssr/{src_presentation_web_e8034a29._.js → src_presentation_web_c4337169._.js} +3 -3
  227. package/web/.next/server/chunks/ssr/{src_presentation_web_e8034a29._.js.map → src_presentation_web_c4337169._.js.map} +1 -1
  228. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
  229. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +1 -1
  230. package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
  231. package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
  232. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  233. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  234. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  235. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  236. package/web/.next/server/pages/500.html +2 -2
  237. package/web/.next/server/server-reference-manifest.js +1 -1
  238. package/web/.next/server/server-reference-manifest.json +311 -240
  239. package/web/.next/static/chunks/0d2af96e64960ef5.css +1 -0
  240. package/web/.next/static/chunks/{a5ff70a7709ec5af.js → 0ddd3c5bdd31b657.js} +1 -1
  241. package/web/.next/static/chunks/163d6a459fbd4ca9.js +2 -0
  242. package/web/.next/static/chunks/{57e0b981e00941e4.js → 26f004e398a1cc47.js} +1 -1
  243. package/web/.next/static/chunks/{51244236801cad96.js → 44ab35cce93382c6.js} +1 -1
  244. package/web/.next/static/chunks/8648eef2b88ba722.js +1 -0
  245. package/web/.next/static/chunks/{71161130b2462279.js → 96eeeb28e06de78c.js} +1 -1
  246. package/web/.next/static/chunks/{700fc491c912dd68.js → aa40e7080c580de0.js} +1 -1
  247. package/web/.next/static/chunks/b8ad0dc86c98f19b.js +1 -0
  248. package/web/.next/static/chunks/c7de66a0adceba46.js +11 -0
  249. package/web/.next/static/chunks/{abb2b485cb0da264.js → e4c5025d3927266a.js} +1 -1
  250. package/web/.next/static/chunks/{263497416e5198a3.js → f6fdcb68b8db7962.js} +1 -1
  251. package/web/.next/server/chunks/[root-of-the-server]__0fe7788d._.js +0 -3
  252. package/web/.next/server/chunks/[root-of-the-server]__0fe7788d._.js.map +0 -1
  253. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_ed372306.js +0 -3
  254. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_ed372306.js.map +0 -1
  255. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_32e26434.js +0 -3
  256. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_32e26434.js.map +0 -1
  257. package/web/.next/server/chunks/ssr/[root-of-the-server]__3b14e5a0._.js +0 -3
  258. package/web/.next/server/chunks/ssr/[root-of-the-server]__3b14e5a0._.js.map +0 -1
  259. package/web/.next/server/chunks/ssr/[root-of-the-server]__8b59c03e._.js +0 -3
  260. package/web/.next/server/chunks/ssr/[root-of-the-server]__8b59c03e._.js.map +0 -1
  261. package/web/.next/server/chunks/ssr/[root-of-the-server]__994ad9fe._.js +0 -3
  262. package/web/.next/server/chunks/ssr/[root-of-the-server]__994ad9fe._.js.map +0 -1
  263. package/web/.next/server/chunks/ssr/[root-of-the-server]__c9c1cfee._.js +0 -3
  264. package/web/.next/server/chunks/ssr/[root-of-the-server]__c9c1cfee._.js.map +0 -1
  265. package/web/.next/server/chunks/ssr/_503b26e9._.js +0 -3
  266. package/web/.next/server/chunks/ssr/_ab069e13._.js +0 -3
  267. package/web/.next/server/chunks/ssr/_ab069e13._.js.map +0 -1
  268. package/web/.next/server/chunks/ssr/_f605354c._.js.map +0 -1
  269. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_e99d78dd.js +0 -3
  270. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_e99d78dd.js.map +0 -1
  271. package/web/.next/static/chunks/027d779d1dd1535e.js +0 -1
  272. package/web/.next/static/chunks/844405e9e0f44c8b.js +0 -11
  273. package/web/.next/static/chunks/943a2b78e452a2fb.js +0 -2
  274. package/web/.next/static/chunks/d2739454715e5ef2.css +0 -1
  275. package/web/.next/static/chunks/f518c011aaa1941e.js +0 -1
  276. /package/web/.next/static/{oxdz8EAvGqpg8JW3gRSSs → evj2MTyodPYvffFcGF31H}/_buildManifest.js +0 -0
  277. /package/web/.next/static/{oxdz8EAvGqpg8JW3gRSSs → evj2MTyodPYvffFcGF31H}/_clientMiddlewareManifest.json +0 -0
  278. /package/web/.next/static/{oxdz8EAvGqpg8JW3gRSSs → evj2MTyodPYvffFcGF31H}/_ssgManifest.js +0 -0
@@ -9,10 +9,11 @@
9
9
  * Follows the same factory pattern as other nodes: takes executor
10
10
  * dependency, returns async (state) => Partial<FeatureAgentState>.
11
11
  */
12
+ import { execSync } from 'node:child_process';
12
13
  import { mkdirSync, writeFileSync } from 'node:fs';
13
14
  import { join, dirname } from 'node:path';
14
15
  import { isGraphBubbleUp } from '@langchain/langgraph';
15
- import { createNodeLogger, buildExecutorOptions, retryExecute } from './node-helpers.js';
16
+ import { createNodeLogger, buildExecutorOptions, retryExecute, getCompletedPhases, markPhaseComplete, } from './node-helpers.js';
16
17
  import { reportNodeStart } from '../heartbeat.js';
17
18
  import { recordPhaseStart, recordPhaseEnd } from '../phase-timing-context.js';
18
19
  import { updateNodeLifecycle } from '../lifecycle-context.js';
@@ -33,6 +34,16 @@ export function createFastImplementNode(executor) {
33
34
  log.info('Starting fast implementation');
34
35
  reportNodeStart('fast-implement');
35
36
  await updateNodeLifecycle('fast-implement');
37
+ // Skip if already completed (resume from error path)
38
+ const completedPhases = getCompletedPhases(state.specDir);
39
+ if (completedPhases.includes('fast-implement')) {
40
+ log.info('Phase already completed, skipping execution');
41
+ return {
42
+ currentNode: 'fast-implement',
43
+ messages: ['[fast-implement] already completed — skipping'],
44
+ _needsReexecution: false,
45
+ };
46
+ }
36
47
  const startTime = Date.now();
37
48
  const timingId = await recordPhaseStart('fast-implement');
38
49
  try {
@@ -44,6 +55,11 @@ export function createFastImplementNode(executor) {
44
55
  const durationMs = Date.now() - startTime;
45
56
  const elapsed = (durationMs / 1000).toFixed(1);
46
57
  log.info(`Complete (${result.result.length} chars, ${elapsed}s)`);
58
+ // Validate that the executor actually produced file changes
59
+ const cwd = state.worktreePath || state.repositoryPath;
60
+ if (!hasWorktreeChanges(cwd)) {
61
+ throw new Error('[fast-implement] Agent produced no file changes — it may have entered plan mode or asked questions instead of implementing. Retrying.');
62
+ }
47
63
  // --- Evidence sub-agent: capture proof of completion (settings-gated) ---
48
64
  const evidenceEnabled = hasSettings() && getSettings().workflow.enableEvidence;
49
65
  const evidence = evidenceEnabled ? await collectEvidence(executor, state, log) : [];
@@ -51,6 +67,8 @@ export function createFastImplementNode(executor) {
51
67
  log.info('Evidence collection disabled via settings — skipping');
52
68
  }
53
69
  await recordPhaseEnd(timingId, durationMs);
70
+ // Mark phase complete so resume from error skips re-execution
71
+ markPhaseComplete(state.specDir, 'fast-implement', log);
54
72
  return {
55
73
  currentNode: 'fast-implement',
56
74
  evidence,
@@ -107,6 +125,21 @@ async function collectEvidence(executor, state, log) {
107
125
  return [];
108
126
  }
109
127
  }
128
+ /**
129
+ * Check whether the worktree has any uncommitted changes (new, modified, or deleted files).
130
+ * Uses `git status --porcelain` which outputs one line per changed file, or empty if clean.
131
+ * Returns false if the git command fails (e.g. not a git repo).
132
+ */
133
+ function hasWorktreeChanges(cwd) {
134
+ try {
135
+ const output = execSync('git status --porcelain', { cwd, encoding: 'utf-8' });
136
+ return output.trim().length > 0;
137
+ }
138
+ catch {
139
+ // If git command fails, assume no changes (conservative — will trigger the error)
140
+ return false;
141
+ }
142
+ }
110
143
  /**
111
144
  * Save evidence manifest to the shep home evidence folder so the
112
145
  * merge review UI can read it without accessing graph state.
@@ -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;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"}
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,CA+T7E"}
@@ -70,6 +70,9 @@ export function createMergeNode(deps) {
70
70
  const startTime = Date.now();
71
71
  let totalInputTokens = 0;
72
72
  let totalOutputTokens = 0;
73
+ let totalCostUsd = 0;
74
+ let totalNumTurns = 0;
75
+ let totalDurationApiMs = 0;
73
76
  const { executor } = deps;
74
77
  const mergeTimingId = await recordPhaseStart('merge', {
75
78
  agentType: executor.agentType,
@@ -106,6 +109,9 @@ export function createMergeNode(deps) {
106
109
  });
107
110
  totalInputTokens += commitResult.usage?.inputTokens ?? 0;
108
111
  totalOutputTokens += commitResult.usage?.outputTokens ?? 0;
112
+ totalCostUsd += commitResult.usage?.costUsd ?? 0;
113
+ totalNumTurns += commitResult.usage?.numTurns ?? 0;
114
+ totalDurationApiMs += commitResult.usage?.durationApiMs ?? 0;
109
115
  commitHash = parseCommitHash(commitResult.result) ?? state.commitHash;
110
116
  messages.push(`[merge] Agent completed commit/push/PR operations`);
111
117
  if (effectiveState.openPr) {
@@ -183,6 +189,9 @@ export function createMergeNode(deps) {
183
189
  await recordPhaseEnd(mergeTimingId, Date.now() - startTime, {
184
190
  inputTokens: totalInputTokens || undefined,
185
191
  outputTokens: totalOutputTokens || undefined,
192
+ costUsd: totalCostUsd || undefined,
193
+ numTurns: totalNumTurns || undefined,
194
+ durationApiMs: totalDurationApiMs || undefined,
186
195
  exitCode: 'success',
187
196
  });
188
197
  await recordApprovalWaitStart(mergeTimingId);
@@ -294,6 +303,9 @@ export function createMergeNode(deps) {
294
303
  await recordPhaseEnd(mergeTimingId, Date.now() - startTime, {
295
304
  inputTokens: totalInputTokens || undefined,
296
305
  outputTokens: totalOutputTokens || undefined,
306
+ costUsd: totalCostUsd || undefined,
307
+ numTurns: totalNumTurns || undefined,
308
+ durationApiMs: totalDurationApiMs || undefined,
297
309
  exitCode: 'error',
298
310
  errorMessage: message.slice(0, 1000),
299
311
  });
@@ -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":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACrB,MAAM,+DAA+D,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAUrD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM;IAE7C,4DAA4D;gBAChD,IAAI;kBAGF,MAAM,GAAG,IAAI;mBAIZ,MAAM,GAAG,IAAI;EAK/B;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE7D;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMtE;AAoBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAO1D;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,iBAAiB,EACxB,SAAS,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE,SAAS,CAAC,CAAC,EAC3D,QAAQ,CAAC,EAAE,MAAM,GAChB,qBAAqB,CAUvB;AAeD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAQrD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,SAAS,GAAG,OAAO,CAQ3F;AAMD,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG,mBAAmB,GAAG,eAAe,GAAG,SAAS,CAAC;AAMhG;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,CAKjE;AAED,MAAM,WAAW,YAAY;IAC3B,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,qBAAqB,EAC9B,SAAS,CAAC,EAAE,YAAY,GACvB,OAAO,CAAC,oBAAoB,CAAC,CA6B/B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAW5D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAqB5F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAOhG;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAwB1F;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAa5F;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,6FAA6F;IAC7F,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,GAAG,MAAM,CAiCT;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAa3E;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,cAAc,EACxB,WAAW,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,UAAU,KAAK,MAAM,GACjE,CAAC,KAAK,EAAE,iBAAiB,KAAK,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAqInE"}
@@ -427,6 +427,11 @@ export function executeNode(nodeName, executor, buildPrompt) {
427
427
  await recordPhaseEnd(timingId, durationMs, {
428
428
  inputTokens: result.usage?.inputTokens,
429
429
  outputTokens: result.usage?.outputTokens,
430
+ cacheCreationInputTokens: result.usage?.cacheCreationInputTokens,
431
+ cacheReadInputTokens: result.usage?.cacheReadInputTokens,
432
+ costUsd: result.usage?.costUsd,
433
+ numTurns: result.usage?.numTurns,
434
+ durationApiMs: result.usage?.durationApiMs,
430
435
  exitCode: 'success',
431
436
  });
432
437
  // Mark phase complete BEFORE interrupting so that on resume the
@@ -1 +1 @@
1
- {"version":3,"file":"fast-implement.prompt.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/fast-implement.prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAwIxD;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAoEzE"}
1
+ {"version":3,"file":"fast-implement.prompt.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/fast-implement.prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAwIxD;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAuEzE"}
@@ -211,6 +211,9 @@ ${dirListing}
211
211
  - Follow existing codebase conventions and patterns
212
212
  - Do NOT commit, push, or create pull requests
213
213
  - Do NOT modify any spec YAML files
214
- - Keep changes focused and minimal`);
214
+ - Keep changes focused and minimal
215
+ - Do NOT enter plan mode — implement directly without planning phases
216
+ - Do NOT ask the user questions or use AskUserQuestion — make reasonable decisions and proceed
217
+ - You MUST create or modify actual code files — a plan or summary alone is not acceptable output`);
215
218
  return sections.join('\n\n');
216
219
  }
@@ -39,6 +39,11 @@ export declare function recordPhaseStart(phase: string, metadata?: PhaseStartMet
39
39
  export interface PhaseEndMetadata {
40
40
  inputTokens?: number;
41
41
  outputTokens?: number;
42
+ cacheCreationInputTokens?: number;
43
+ cacheReadInputTokens?: number;
44
+ costUsd?: number;
45
+ numTurns?: number;
46
+ durationApiMs?: number;
42
47
  exitCode?: string;
43
48
  errorMessage?: string;
44
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"phase-timing-context.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/phase-timing-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wEAAwE,CAAC;AAMrH;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAE/C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,sBAAsB,GAAG,IAAI,CAG7F;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAI9C;AA+BD,sDAAsD;AACtD,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,kBAAkB,GAC5B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyBxB;AAED,qDAAqD;AACrD,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,MAAM,EACb,aAAa,CAAC,EAAE,MAAM,EACtB,YAAY,CAAC,EAAE,sBAAsB,GACpC,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAUpF"}
1
+ {"version":3,"file":"phase-timing-context.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/phase-timing-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wEAAwE,CAAC;AAMrH;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAE/C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,sBAAsB,GAAG,IAAI,CAG7F;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAI9C;AA+BD,sDAAsD;AACtD,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,kBAAkB,GAC5B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyBxB;AAED,qDAAqD;AACrD,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,MAAM,EACb,aAAa,CAAC,EAAE,MAAM,EACtB,YAAY,CAAC,EAAE,sBAAsB,GACpC,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAUpF"}
@@ -103,6 +103,15 @@ export async function recordPhaseEnd(timingId, durationMs, metadata) {
103
103
  durationMs: BigInt(durationMs),
104
104
  ...(metadata?.inputTokens != null && { inputTokens: BigInt(metadata.inputTokens) }),
105
105
  ...(metadata?.outputTokens != null && { outputTokens: BigInt(metadata.outputTokens) }),
106
+ ...(metadata?.cacheCreationInputTokens != null && {
107
+ cacheCreationInputTokens: BigInt(metadata.cacheCreationInputTokens),
108
+ }),
109
+ ...(metadata?.cacheReadInputTokens != null && {
110
+ cacheReadInputTokens: BigInt(metadata.cacheReadInputTokens),
111
+ }),
112
+ ...(metadata?.costUsd != null && { costUsd: metadata.costUsd }),
113
+ ...(metadata?.numTurns != null && { numTurns: metadata.numTurns }),
114
+ ...(metadata?.durationApiMs != null && { durationApiMs: BigInt(metadata.durationApiMs) }),
106
115
  ...(metadata?.exitCode != null && { exitCode: metadata.exitCode }),
107
116
  ...(metadata?.errorMessage != null && { errorMessage: metadata.errorMessage }),
108
117
  });
@@ -8,7 +8,7 @@ import type { QuestionOption } from '../../../../packages/core/src/domain/genera
8
8
  /**
9
9
  * Creates the @inquirer/select configuration for a single open question.
10
10
  */
11
- export declare function createQuestionSelectConfig(question: string, options: QuestionOption[], currentAnswer?: string): {
11
+ export declare function createQuestionSelectConfig(question: string, options: QuestionOption[], currentAnswer?: string, questionNumber?: number, totalQuestions?: number): {
12
12
  message: string;
13
13
  choices: {
14
14
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"prd-review-question.prompt.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/tui/prompts/prd-review-question.prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,cAAc,EAAE,EACzB,aAAa,CAAC,EAAE,MAAM;;;;;;;;;;;;;;;;;;EAcvB"}
1
+ {"version":3,"file":"prd-review-question.prompt.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/tui/prompts/prd-review-question.prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,cAAc,EAAE,EACzB,aAAa,CAAC,EAAE,MAAM,EACtB,cAAc,CAAC,EAAE,MAAM,EACvB,cAAc,CAAC,EAAE,MAAM;;;;;;;;;;;;;;;;;;EAmBxB"}
@@ -8,14 +8,17 @@ import { shepTheme } from '../themes/shep.theme.js';
8
8
  /**
9
9
  * Creates the @inquirer/select configuration for a single open question.
10
10
  */
11
- export function createQuestionSelectConfig(question, options, currentAnswer) {
11
+ export function createQuestionSelectConfig(question, options, currentAnswer, questionNumber, totalQuestions) {
12
12
  const choices = options.map((opt) => ({
13
13
  name: opt.option,
14
14
  value: opt.option,
15
15
  description: opt.description,
16
16
  }));
17
+ const prefix = questionNumber != null && totalQuestions != null
18
+ ? `[${questionNumber}/${totalQuestions}] `
19
+ : '';
17
20
  return {
18
- message: question,
21
+ message: `${prefix}${question}`,
19
22
  choices,
20
23
  default: currentAnswer,
21
24
  theme: shepTheme,
@@ -1 +1 @@
1
- {"version":3,"file":"prd-review.wizard.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/tui/wizards/prd-review.wizard.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2DAA2D,CAAC;AAC9F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAG5E,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,YAAY,CAAC;IACrB,iBAAiB,EAAE,uBAAuB,EAAE,CAAC;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA4B/F"}
1
+ {"version":3,"file":"prd-review.wizard.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/tui/wizards/prd-review.wizard.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2DAA2D,CAAC;AAC9F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAG5E,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,YAAY,CAAC;IACrB,iBAAiB,EAAE,uBAAuB,EAAE,CAAC;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA8B/F"}
@@ -20,8 +20,10 @@ import { shepTheme } from '../themes/shep.theme.js';
20
20
  */
21
21
  export async function prdReviewWizard(questions) {
22
22
  const changedSelections = [];
23
- for (const q of questions) {
24
- const selected = await select(createQuestionSelectConfig(q.question, q.options, q.selectedOption));
23
+ const total = questions.length;
24
+ for (let i = 0; i < total; i++) {
25
+ const q = questions[i];
26
+ const selected = await select(createQuestionSelectConfig(q.question, q.options, q.selectedOption, i + 1, total));
25
27
  if (selected !== q.selectedOption) {
26
28
  changedSelections.push({
27
29
  questionId: q.question,
@@ -1 +1 @@
1
- {"version":3,"file":"get-graph-data.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/(dashboard)/get-graph-data.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAE5E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAQ1C,wBAAsB,YAAY,IAAI,OAAO,CAAC;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAAC,CAuFxF"}
1
+ {"version":3,"file":"get-graph-data.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/(dashboard)/get-graph-data.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAE5E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,wBAAsB,YAAY,IAAI,OAAO,CAAC;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAAC,CA+CxF"}
@@ -1,55 +1,14 @@
1
1
  import { resolve } from '../../lib/server-container.js';
2
- import { CiStatus } from '../../../../../packages/core/src/domain/generated/output.js';
3
2
  import { getSettings } from '../../../../../packages/core/src/infrastructure/services/settings.service.js';
4
3
  import { layoutWithDagre, CANVAS_LAYOUT_DEFAULTS } from '../../lib/layout-with-dagre.js';
5
4
  import { buildGraphNodes } from '../build-graph-nodes.js';
6
- const CI_STATUS_MAP = {
7
- success: CiStatus.Success,
8
- failure: CiStatus.Failure,
9
- pending: CiStatus.Pending,
10
- };
11
5
  export async function getGraphData() {
12
6
  const listFeatures = resolve('ListFeaturesUseCase');
13
7
  const listRepos = resolve('ListRepositoriesUseCase');
14
8
  const agentRunRepo = resolve('IAgentRunRepository');
15
- const gitPrService = resolve('IGitPrService');
16
- const featureRepo = resolve('IFeatureRepository');
17
9
  const [features, repositories] = await Promise.all([listFeatures.execute(), listRepos.execute()]);
18
- // Fetch live PR status for features with open PRs so the canvas
19
- // reflects the current GitHub state without waiting for the background watcher.
20
- await Promise.all(features
21
- .filter((f) => f.pr?.number)
22
- .map(async (feature) => {
23
- try {
24
- const updates = {};
25
- // Live mergeable status (only if not yet known)
26
- if (feature.pr.mergeable === undefined) {
27
- const mergeable = await gitPrService.getMergeableStatus(feature.repositoryPath, feature.pr.number);
28
- if (mergeable !== undefined)
29
- updates.mergeable = mergeable;
30
- }
31
- // Live CI status
32
- if (feature.branch) {
33
- const ciResult = await gitPrService
34
- .getCiStatus(feature.repositoryPath, feature.branch)
35
- .catch(() => undefined);
36
- if (ciResult) {
37
- const ciStatus = CI_STATUS_MAP[ciResult.status] ?? CiStatus.Pending;
38
- if (ciStatus !== feature.pr.ciStatus)
39
- updates.ciStatus = ciStatus;
40
- }
41
- }
42
- if (Object.keys(updates).length > 0) {
43
- feature.pr = { ...feature.pr, ...updates };
44
- featureRepo.update(feature).catch(() => {
45
- /* best-effort persist */
46
- });
47
- }
48
- }
49
- catch {
50
- // GitHub fetch failed — use cached value
51
- }
52
- }));
10
+ // PR/CI status is kept fresh by PrSyncWatcher (30s background poll).
11
+ // No live GitHub calls here use cached DB values for fast response.
53
12
  const featuresWithRuns = await Promise.all(features.map(async (feature) => {
54
13
  const run = feature.agentRunId ? await agentRunRepo.findById(feature.agentRunId) : null;
55
14
  return { feature, run };
@@ -1 +1 @@
1
- {"version":3,"file":"approve-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/approve-feature.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAE/E,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA6BhD"}
1
+ {"version":3,"file":"approve-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/approve-feature.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAK/E,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAsChD"}
@@ -1,5 +1,7 @@
1
1
  'use server';
2
2
  import { resolve } from '../../lib/server-container.js';
3
+ import { AgentRunStatus } from '../../../../../packages/core/src/domain/generated/output.js';
4
+ const ERROR_STATUSES = new Set([AgentRunStatus.failed, AgentRunStatus.interrupted]);
3
5
  export async function approveFeature(featureId, payload) {
4
6
  if (!featureId.trim()) {
5
7
  return { approved: false, error: 'Feature id is required' };
@@ -13,6 +15,13 @@ export async function approveFeature(featureId, payload) {
13
15
  if (!feature.agentRunId) {
14
16
  return { approved: false, error: 'Feature has no agent run' };
15
17
  }
18
+ const runRepo = resolve('IAgentRunRepository');
19
+ const run = await runRepo.findById(feature.agentRunId);
20
+ if (run && ERROR_STATUSES.has(run.status)) {
21
+ const resumeUseCase = resolve('ResumeFeatureUseCase');
22
+ await resumeUseCase.execute(featureId, { promptPrefix: 'User approved. Please continue.' });
23
+ return { approved: true };
24
+ }
16
25
  const approveUseCase = resolve('ApproveAgentRunUseCase');
17
26
  const result = await approveUseCase.execute(feature.agentRunId, payload);
18
27
  if (!result.approved) {
@@ -8,6 +8,11 @@ export interface PhaseTimingData {
8
8
  approvalWaitMs?: number;
9
9
  inputTokens?: number;
10
10
  outputTokens?: number;
11
+ cacheCreationInputTokens?: number;
12
+ cacheReadInputTokens?: number;
13
+ costUsd?: number;
14
+ numTurns?: number;
15
+ durationApiMs?: number;
11
16
  }
12
17
  export interface RejectionFeedbackData {
13
18
  iteration: number;
@@ -1 +1 @@
1
- {"version":3,"file":"get-feature-phase-timings.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/get-feature-phase-timings.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,KAAK,qBAAqB,GACtB;IAAE,OAAO,EAAE,eAAe,EAAE,CAAC;IAAC,iBAAiB,EAAE,qBAAqB,EAAE,CAAA;CAAE,GAC1E;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtB,wBAAsB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA6B9F"}
1
+ {"version":3,"file":"get-feature-phase-timings.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/get-feature-phase-timings.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,KAAK,qBAAqB,GACtB;IAAE,OAAO,EAAE,eAAe,EAAE,CAAC;IAAC,iBAAiB,EAAE,qBAAqB,EAAE,CAAA;CAAE,GAC1E;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtB,wBAAsB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAoC9F"}
@@ -17,6 +17,11 @@ export async function getFeaturePhaseTimings(featureId) {
17
17
  approvalWaitMs: t.approvalWaitMs != null ? Number(t.approvalWaitMs) : undefined,
18
18
  inputTokens: t.inputTokens != null ? Number(t.inputTokens) : undefined,
19
19
  outputTokens: t.outputTokens != null ? Number(t.outputTokens) : undefined,
20
+ cacheCreationInputTokens: t.cacheCreationInputTokens != null ? Number(t.cacheCreationInputTokens) : undefined,
21
+ cacheReadInputTokens: t.cacheReadInputTokens != null ? Number(t.cacheReadInputTokens) : undefined,
22
+ costUsd: t.costUsd != null ? Number(t.costUsd) : undefined,
23
+ numTurns: t.numTurns ?? undefined,
24
+ durationApiMs: t.durationApiMs != null ? Number(t.durationApiMs) : undefined,
20
25
  }));
21
26
  // Read rejection feedback from spec.yaml
22
27
  const rejectionFeedback = await readRejectionFeedback(featureId);
@@ -1 +1 @@
1
- {"version":3,"file":"reject-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/reject-feature.ts"],"names":[],"mappings":"AAMA,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC;IACT,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CAqCD"}
1
+ {"version":3,"file":"reject-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/reject-feature.ts"],"names":[],"mappings":"AAWA,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC;IACT,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CA8CD"}
@@ -1,5 +1,7 @@
1
1
  'use server';
2
2
  import { resolve } from '../../lib/server-container.js';
3
+ import { AgentRunStatus } from '../../../../../packages/core/src/domain/generated/output.js';
4
+ const ERROR_STATUSES = new Set([AgentRunStatus.failed, AgentRunStatus.interrupted]);
3
5
  export async function rejectFeature(featureId, feedback, attachments) {
4
6
  if (!featureId.trim()) {
5
7
  return { rejected: false, error: 'Feature id is required' };
@@ -16,6 +18,13 @@ export async function rejectFeature(featureId, feedback, attachments) {
16
18
  if (!feature.agentRunId) {
17
19
  return { rejected: false, error: 'Feature has no agent run' };
18
20
  }
21
+ const runRepo = resolve('IAgentRunRepository');
22
+ const run = await runRepo.findById(feature.agentRunId);
23
+ if (run && ERROR_STATUSES.has(run.status)) {
24
+ const resumeUseCase = resolve('ResumeFeatureUseCase');
25
+ await resumeUseCase.execute(featureId, { promptPrefix: feedback });
26
+ return { rejected: true, iteration: 1 };
27
+ }
19
28
  const rejectUseCase = resolve('RejectAgentRunUseCase');
20
29
  const result = await rejectUseCase.execute(feature.agentRunId, feedback, attachments);
21
30
  if (!result.rejected) {
@@ -0,0 +1,5 @@
1
+ export declare function stopFeature(featureId: string): Promise<{
2
+ stopped: boolean;
3
+ error?: string;
4
+ }>;
5
+ //# sourceMappingURL=stop-feature.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/stop-feature.ts"],"names":[],"mappings":"AAMA,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAiC/C"}
@@ -0,0 +1,30 @@
1
+ 'use server';
2
+ import { resolve } from '../../lib/server-container.js';
3
+ export async function stopFeature(featureId) {
4
+ if (!featureId.trim()) {
5
+ return { stopped: false, error: 'Feature id is required' };
6
+ }
7
+ try {
8
+ // Find the active agent run for this feature
9
+ const runRepo = resolve('IAgentRunRepository');
10
+ const allRuns = await runRepo.list();
11
+ const activeRun = allRuns.find((r) => r.featureId === featureId &&
12
+ r.status !== 'completed' &&
13
+ r.status !== 'failed' &&
14
+ r.status !== 'interrupted' &&
15
+ r.status !== 'cancelled');
16
+ if (!activeRun) {
17
+ return { stopped: false, error: 'No active agent run found for this feature' };
18
+ }
19
+ const useCase = resolve('StopAgentRunUseCase');
20
+ const result = await useCase.execute(activeRun.id);
21
+ if (!result.stopped) {
22
+ return { stopped: false, error: result.reason };
23
+ }
24
+ return { stopped: true };
25
+ }
26
+ catch (error) {
27
+ const message = error instanceof Error ? error.message : 'Failed to stop agent';
28
+ return { stopped: false, error: message };
29
+ }
30
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/app/api/npm-version/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,wBAAsB,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC,CAejD"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/app/api/npm-version/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAK3C,wBAAsB,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC,CAsBjD"}
@@ -1,5 +1,11 @@
1
1
  import { NextResponse } from 'next/server';
2
+ const CACHE_TTL_MS = 5 * 60_000; // 5 minutes
3
+ let cachedVersion = null;
2
4
  export async function GET() {
5
+ // Return cached value if fresh
6
+ if (cachedVersion && Date.now() - cachedVersion.fetchedAt < CACHE_TTL_MS) {
7
+ return NextResponse.json({ latest: cachedVersion.latest });
8
+ }
3
9
  const packageName = '@shepai/cli';
4
10
  try {
5
11
  const res = await fetch(`https://registry.npmjs.org/${packageName}/latest`, {
@@ -9,7 +15,9 @@ export async function GET() {
9
15
  return NextResponse.json({ error: `npm registry returned ${res.status}` }, { status: 502 });
10
16
  }
11
17
  const data = (await res.json());
12
- return NextResponse.json({ latest: data.version ?? null });
18
+ const latest = data.version ?? null;
19
+ cachedVersion = { latest, fetchedAt: Date.now() };
20
+ return NextResponse.json({ latest });
13
21
  }
14
22
  catch (error) {
15
23
  const message = error instanceof Error ? error.message : 'Failed to check npm version';
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/app/api/sessions/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAK3C,eAAO,MAAM,OAAO,kBAAkB,CAAC;AA4QvC;;;;;GAKG;AACH,wBAAsB,GAAG,CAAC,OAAO,EAAE,OAAO;;;;YA/QpC,MAAM;mBACC,MAAM;iBACR,MAAM,GAAG,IAAI;sBACR,MAAM;wBACJ,MAAM,GAAG,IAAI;uBACd,MAAM,GAAG,IAAI;mBACjB,MAAM,GAAG,IAAI;qBACX,MAAM;kBACT,MAAM;;IAoSjB"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/app/api/sessions/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAK3C,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAgTvC;;;;;GAKG;AACH,wBAAsB,GAAG,CAAC,OAAO,EAAE,OAAO;;;;YAnTpC,MAAM;mBACC,MAAM;iBACR,MAAM,GAAG,IAAI;sBACR,MAAM;wBACJ,MAAM,GAAG,IAAI;uBACd,MAAM,GAAG,IAAI;mBACjB,MAAM,GAAG,IAAI;qBACX,MAAM;kBACT,MAAM;;IAwUjB"}
@@ -1,7 +1,7 @@
1
1
  import { NextResponse } from 'next/server';
2
2
  import { homedir } from 'node:os';
3
3
  import { join } from 'node:path';
4
- import { readdir, stat, readFile } from 'node:fs/promises';
4
+ import { readdir, stat } from 'node:fs/promises';
5
5
  export const dynamic = 'force-dynamic';
6
6
  // ── Path encoding helpers ─────────────────────────────────────────────
7
7
  /**
@@ -49,14 +49,32 @@ async function scanClaudeSessions(repositoryPath, limit) {
49
49
  .map((r) => r.value)
50
50
  .filter((s) => s !== null);
51
51
  }
52
+ /**
53
+ * Read the first N bytes of a file to extract preview and timestamps
54
+ * without loading the entire (potentially multi-MB) session file.
55
+ */
56
+ const PREVIEW_READ_BYTES = 8_192; // 8KB is enough for first few messages
52
57
  async function parseClaudeSession(filePath, fileName, mtime, repositoryPath) {
53
- const content = await readFile(filePath, 'utf-8');
54
- const lines = content.split('\n').filter((l) => l.trim());
58
+ const { createReadStream } = await import('node:fs');
55
59
  const id = fileName.replace('.jsonl', '');
60
+ // Read only the first chunk to extract preview and first timestamp
56
61
  let preview = null;
57
- let messageCount = 0;
58
62
  let firstTimestamp = null;
59
- let lastTimestamp = null;
63
+ let messageCount = 0;
64
+ const head = await new Promise((resolve) => {
65
+ const chunks = [];
66
+ let size = 0;
67
+ const stream = createReadStream(filePath, { end: PREVIEW_READ_BYTES - 1 });
68
+ stream.on('data', (chunk) => {
69
+ chunks.push(chunk);
70
+ size += chunk.length;
71
+ });
72
+ stream.on('end', () => resolve(Buffer.concat(chunks, size).toString('utf-8')));
73
+ stream.on('error', () => resolve(''));
74
+ });
75
+ if (!head)
76
+ return null;
77
+ const lines = head.split('\n').filter((l) => l.trim());
60
78
  for (const line of lines) {
61
79
  try {
62
80
  const entry = JSON.parse(line);
@@ -66,7 +84,6 @@ async function parseClaudeSession(filePath, fileName, mtime, repositoryPath) {
66
84
  messageCount++;
67
85
  if (entry.timestamp) {
68
86
  firstTimestamp ??= entry.timestamp;
69
- lastTimestamp = entry.timestamp;
70
87
  }
71
88
  if (role === 'user' && preview === null) {
72
89
  preview = extractText(entry.message?.content);
@@ -80,14 +97,16 @@ async function parseClaudeSession(filePath, fileName, mtime, repositoryPath) {
80
97
  }
81
98
  if (messageCount === 0)
82
99
  return null;
100
+ // Use mtime as lastMessageAt — avoids reading entire file for last line
101
+ const mtimeIso = new Date(mtime).toISOString();
83
102
  return {
84
103
  id,
85
104
  agentType: 'claude-code',
86
105
  preview,
87
106
  messageCount,
88
107
  firstMessageAt: firstTimestamp,
89
- lastMessageAt: lastTimestamp,
90
- createdAt: firstTimestamp ?? new Date(mtime).toISOString(),
108
+ lastMessageAt: mtimeIso,
109
+ createdAt: firstTimestamp ?? mtimeIso,
91
110
  projectPath: repositoryPath,
92
111
  filePath,
93
112
  _mtime: mtime,
@@ -144,11 +163,25 @@ async function scanCursorSessions(repositoryPath, limit) {
144
163
  .filter((s) => s !== null);
145
164
  }
146
165
  async function parseCursorSession(filePath, fileName, mtime, repositoryPath) {
147
- const content = await readFile(filePath, 'utf-8');
148
- const lines = content.split('\n').filter((l) => l.trim());
166
+ const { createReadStream } = await import('node:fs');
149
167
  const id = fileName.replace('.jsonl', '');
168
+ // Read only the first chunk for preview extraction
169
+ const head = await new Promise((resolve) => {
170
+ const chunks = [];
171
+ let size = 0;
172
+ const stream = createReadStream(filePath, { end: PREVIEW_READ_BYTES - 1 });
173
+ stream.on('data', (chunk) => {
174
+ chunks.push(chunk);
175
+ size += chunk.length;
176
+ });
177
+ stream.on('end', () => resolve(Buffer.concat(chunks, size).toString('utf-8')));
178
+ stream.on('error', () => resolve(''));
179
+ });
180
+ if (!head)
181
+ return null;
150
182
  let preview = null;
151
183
  let messageCount = 0;
184
+ const lines = head.split('\n').filter((l) => l.trim());
152
185
  for (const line of lines) {
153
186
  try {
154
187
  const entry = JSON.parse(line);
@@ -1 +1 @@
1
- {"version":3,"file":"activity-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/activity-tab.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACtB,MAAM,yCAAyC,CAAC;AAqDjD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iBAAiB,CAAC,EAAE,qBAAqB,EAAE,CAAC;CAC7C;AA6BD;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8DAA8D;IAC9D,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,eAAe,EAAE,EAC1B,QAAQ,CAAC,EAAE,qBAAqB,EAAE,GACjC,iBAAiB,EAAE,CAgErB;AAMD,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,gBAAgB,2CAmE3F"}
1
+ {"version":3,"file":"activity-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/activity-tab.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACtB,MAAM,yCAAyC,CAAC;AA4DjD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iBAAiB,CAAC,EAAE,qBAAqB,EAAE,CAAC;CAC7C;AA6BD;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8DAA8D;IAC9D,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,eAAe,EAAE,EAC1B,QAAQ,CAAC,EAAE,qBAAqB,EAAE,GACjC,iBAAiB,EAAE,CAgErB;AAMD,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,gBAAgB,2CAqE3F"}