@shepai/cli 1.121.0-pr360.3389500 → 1.121.0-pr375.de718bc

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 (188) hide show
  1. package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.d.ts +3 -1
  2. package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.d.ts.map +1 -1
  3. package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.js +4 -2
  4. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/fast-implement.node.d.ts.map +1 -1
  5. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/fast-implement.node.js +13 -1
  6. package/dist/packages/core/src/infrastructure/services/tool-installer/tool-installer.service.d.ts.map +1 -1
  7. package/dist/packages/core/src/infrastructure/services/tool-installer/tool-installer.service.js +3 -10
  8. package/dist/packages/core/src/infrastructure/services/tool-installer/tools/claude-code.json +4 -9
  9. package/dist/src/presentation/cli/commands/install.command.js +1 -8
  10. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.d.ts.map +1 -1
  11. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.js +2 -43
  12. package/dist/src/presentation/web/app/actions/approve-feature.d.ts.map +1 -1
  13. package/dist/src/presentation/web/app/actions/approve-feature.js +9 -0
  14. package/dist/src/presentation/web/app/actions/check-agent-auth.d.ts +0 -2
  15. package/dist/src/presentation/web/app/actions/check-agent-auth.d.ts.map +1 -1
  16. package/dist/src/presentation/web/app/actions/check-agent-auth.js +1 -8
  17. package/dist/src/presentation/web/app/actions/reject-feature.d.ts.map +1 -1
  18. package/dist/src/presentation/web/app/actions/reject-feature.js +9 -0
  19. package/dist/src/presentation/web/app/api/npm-version/route.d.ts.map +1 -1
  20. package/dist/src/presentation/web/app/api/npm-version/route.js +9 -1
  21. package/dist/src/presentation/web/app/api/sessions/route.d.ts.map +1 -1
  22. package/dist/src/presentation/web/app/api/sessions/route.js +43 -10
  23. package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.js +1 -1
  24. package/dist/src/presentation/web/components/features/tools/tool-card.stories.js +1 -1
  25. package/dist/src/presentation/web/components/features/tools/tools-page-client.stories.js +1 -1
  26. package/dist/tsconfig.build.tsbuildinfo +1 -1
  27. package/package.json +3 -5
  28. package/web/.next/BUILD_ID +1 -1
  29. package/web/.next/build-manifest.json +2 -2
  30. package/web/.next/fallback-build-manifest.json +2 -2
  31. package/web/.next/prerender-manifest.json +3 -3
  32. package/web/.next/required-server-files.js +1 -1
  33. package/web/.next/required-server-files.json +1 -1
  34. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +22 -22
  35. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  36. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  37. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
  38. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +1 -1
  39. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  40. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  41. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +28 -28
  42. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
  43. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  44. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  45. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
  46. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  47. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  48. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +22 -22
  49. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  50. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  51. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
  52. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +1 -1
  53. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  54. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  55. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +28 -28
  56. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
  57. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  58. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  59. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +20 -20
  60. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  61. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  62. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
  63. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  64. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  65. package/web/.next/server/app/_global-error.html +2 -2
  66. package/web/.next/server/app/_global-error.rsc +1 -1
  67. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  68. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  69. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  70. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  71. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  72. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  73. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  74. package/web/.next/server/app/api/sessions/route.js +1 -1
  75. package/web/.next/server/app/api/sessions/route.js.nft.json +1 -1
  76. package/web/.next/server/app/settings/page/server-reference-manifest.json +6 -6
  77. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  78. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  79. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  80. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  81. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  82. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  83. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  84. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  85. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +1 -1
  86. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +1 -1
  87. package/web/.next/server/chunks/[externals]_node:fs_ddf6f167._.js +3 -0
  88. package/web/.next/server/chunks/[externals]_node:fs_ddf6f167._.js.map +1 -0
  89. package/web/.next/server/chunks/[root-of-the-server]__3b72e8b0._.js +1 -1
  90. package/web/.next/server/chunks/[root-of-the-server]__3b72e8b0._.js.map +1 -1
  91. package/web/.next/server/chunks/[root-of-the-server]__42b7ab55._.js +1 -1
  92. package/web/.next/server/chunks/[root-of-the-server]__42b7ab55._.js.map +1 -1
  93. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  94. package/web/.next/server/chunks/[root-of-the-server]__a62bd945._.js +3 -0
  95. package/web/.next/server/chunks/[root-of-the-server]__a62bd945._.js.map +1 -0
  96. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js +1 -1
  97. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js.map +1 -1
  98. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  99. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  100. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js +1 -1
  101. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js.map +1 -1
  102. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js +1 -1
  103. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js.map +1 -1
  104. package/web/.next/server/chunks/ssr/[root-of-the-server]__06fef644._.js +1 -1
  105. package/web/.next/server/chunks/ssr/[root-of-the-server]__2698e9f4._.js +3 -0
  106. package/web/.next/server/chunks/ssr/[root-of-the-server]__2698e9f4._.js.map +1 -0
  107. package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js +1 -1
  108. package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js.map +1 -1
  109. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  110. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  111. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +2 -2
  112. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js.map +1 -1
  113. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  114. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  115. package/web/.next/server/chunks/ssr/[root-of-the-server]__8c553503._.js +2 -2
  116. package/web/.next/server/chunks/ssr/[root-of-the-server]__8e3bf5d7._.js +3 -0
  117. package/web/.next/server/chunks/ssr/[root-of-the-server]__8e3bf5d7._.js.map +1 -0
  118. package/web/.next/server/chunks/ssr/[root-of-the-server]__a022445f._.js +2 -2
  119. package/web/.next/server/chunks/ssr/[root-of-the-server]__a022445f._.js.map +1 -1
  120. package/web/.next/server/chunks/ssr/[root-of-the-server]__a7de2711._.js +2 -2
  121. package/web/.next/server/chunks/ssr/[root-of-the-server]__a7de2711._.js.map +1 -1
  122. package/web/.next/server/chunks/ssr/[root-of-the-server]__b724df9e._.js +1 -1
  123. package/web/.next/server/chunks/ssr/[root-of-the-server]__b724df9e._.js.map +1 -1
  124. package/web/.next/server/chunks/ssr/[root-of-the-server]__c07f9f79._.js +3 -0
  125. package/web/.next/server/chunks/ssr/[root-of-the-server]__c07f9f79._.js.map +1 -0
  126. package/web/.next/server/chunks/ssr/[root-of-the-server]__c605a375._.js +3 -0
  127. package/web/.next/server/chunks/ssr/[root-of-the-server]__c605a375._.js.map +1 -0
  128. package/web/.next/server/chunks/ssr/_0dc2cfd3._.js +1 -1
  129. package/web/.next/server/chunks/ssr/_0dc2cfd3._.js.map +1 -1
  130. package/web/.next/server/chunks/ssr/{_c9f9f066._.js → _0e2fa803._.js} +2 -2
  131. package/web/.next/server/chunks/ssr/{_c9f9f066._.js.map → _0e2fa803._.js.map} +1 -1
  132. package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
  133. package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
  134. package/web/.next/server/chunks/ssr/_2f6f48b8._.js +1 -1
  135. package/web/.next/server/chunks/ssr/_2f6f48b8._.js.map +1 -1
  136. package/web/.next/server/chunks/ssr/{_6adcca26._.js → _86bcd0cb._.js} +2 -2
  137. package/web/.next/server/chunks/ssr/{_6adcca26._.js.map → _86bcd0cb._.js.map} +1 -1
  138. package/web/.next/server/chunks/ssr/_9cdb9131._.js +3 -0
  139. package/web/.next/server/chunks/ssr/{_01430df5._.js.map → _9cdb9131._.js.map} +1 -1
  140. package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
  141. package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
  142. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  143. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  144. package/web/.next/server/chunks/ssr/src_presentation_web_5f039db1._.js +2 -2
  145. package/web/.next/server/chunks/ssr/src_presentation_web_5f039db1._.js.map +1 -1
  146. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js +1 -1
  147. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js.map +1 -1
  148. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
  149. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
  150. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
  151. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
  152. package/web/.next/server/chunks/ssr/src_presentation_web_c4337169._.js +2 -2
  153. package/web/.next/server/chunks/ssr/src_presentation_web_c4337169._.js.map +1 -1
  154. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
  155. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +1 -1
  156. package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
  157. package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js.map +1 -1
  158. package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
  159. package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js.map +1 -1
  160. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  161. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  162. package/web/.next/server/pages/500.html +2 -2
  163. package/web/.next/server/server-reference-manifest.js +1 -1
  164. package/web/.next/server/server-reference-manifest.json +34 -34
  165. package/web/.next/static/chunks/{180163cc1930dbd8.js → 78227a8fa0b0a44f.js} +1 -1
  166. package/web/.next/static/chunks/{08622689d65b4d39.js → 7c121b87cbc3a987.js} +1 -1
  167. package/web/.next/static/chunks/{93c52fba27d59310.js → 87e9e13dd05907a3.js} +1 -1
  168. package/web/.next/static/chunks/{02d522e9112607a4.js → d1e8c0959d9e7e38.js} +1 -1
  169. package/web/.next/static/chunks/{e250fec851ac30f4.js → d3ea72cbb1d42172.js} +1 -1
  170. package/web/.next/static/chunks/{5fe1cadeac80c82e.js → e4b05f1dc8974236.js} +1 -1
  171. package/web/.next/static/chunks/{84ab8af59015ca72.js → f357d403bf61ec3c.js} +2 -2
  172. package/web/.next/static/chunks/{c7501007ee7add77.js → f4ae633779d5324c.js} +1 -1
  173. package/web/.next/static/chunks/{2c20b129a22101a7.js → f62c2cfe34d12a8d.js} +1 -1
  174. package/web/.next/static/chunks/{394b72591bf6c3f9.js → ff286f5ef499d263.js} +1 -1
  175. package/web/.next/server/chunks/[root-of-the-server]__0fe7788d._.js +0 -3
  176. package/web/.next/server/chunks/[root-of-the-server]__0fe7788d._.js.map +0 -1
  177. package/web/.next/server/chunks/ssr/[root-of-the-server]__0424e9ef._.js +0 -3
  178. package/web/.next/server/chunks/ssr/[root-of-the-server]__0424e9ef._.js.map +0 -1
  179. package/web/.next/server/chunks/ssr/[root-of-the-server]__580db3b8._.js +0 -3
  180. package/web/.next/server/chunks/ssr/[root-of-the-server]__580db3b8._.js.map +0 -1
  181. package/web/.next/server/chunks/ssr/[root-of-the-server]__5d1a30fb._.js +0 -3
  182. package/web/.next/server/chunks/ssr/[root-of-the-server]__5d1a30fb._.js.map +0 -1
  183. package/web/.next/server/chunks/ssr/[root-of-the-server]__7e95570f._.js +0 -3
  184. package/web/.next/server/chunks/ssr/[root-of-the-server]__7e95570f._.js.map +0 -1
  185. package/web/.next/server/chunks/ssr/_01430df5._.js +0 -3
  186. /package/web/.next/static/{mBZK7AokkzzKYpu3ySb2v → FKhXOv4YGg6YioBqvMlGR}/_buildManifest.js +0 -0
  187. /package/web/.next/static/{mBZK7AokkzzKYpu3ySb2v → FKhXOv4YGg6YioBqvMlGR}/_clientMiddlewareManifest.json +0 -0
  188. /package/web/.next/static/{mBZK7AokkzzKYpu3ySb2v → FKhXOv4YGg6YioBqvMlGR}/_ssgManifest.js +0 -0
@@ -19,6 +19,8 @@ export declare class ResumeFeatureUseCase {
19
19
  private readonly processService;
20
20
  private readonly worktreeService;
21
21
  constructor(featureRepo: IFeatureRepository, runRepo: IAgentRunRepository, processService: IFeatureAgentProcessService, worktreeService: IWorktreeService);
22
- execute(featureId: string): Promise<ResumeFeatureResult>;
22
+ execute(featureId: string, options?: {
23
+ promptPrefix?: string;
24
+ }): Promise<ResumeFeatureResult>;
23
25
  }
24
26
  //# sourceMappingURL=resume-feature.use-case.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resume-feature.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/resume-feature.use-case.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAE7E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAC1G,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6DAA6D,CAAC;AACvG,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8DAA8D,CAAC;AAChH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2DAA2D,CAAC;AAQlG,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,QAAQ,CAAC;CAClB;AAED,qBACa,oBAAoB;IAG7B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAE5B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAExB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAE/B,OAAO,CAAC,QAAQ,CAAC,eAAe;gBANf,WAAW,EAAE,kBAAkB,EAE/B,OAAO,EAAE,mBAAmB,EAE5B,cAAc,EAAE,2BAA2B,EAE3C,eAAe,EAAE,gBAAgB;IAG9C,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAqG/D"}
1
+ {"version":3,"file":"resume-feature.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/resume-feature.use-case.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAE7E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAC1G,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6DAA6D,CAAC;AACvG,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8DAA8D,CAAC;AAChH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2DAA2D,CAAC;AAQlG,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,QAAQ,CAAC;CAClB;AAED,qBACa,oBAAoB;IAG7B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAE5B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAExB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAE/B,OAAO,CAAC,QAAQ,CAAC,eAAe;gBANf,WAAW,EAAE,kBAAkB,EAE/B,OAAO,EAAE,mBAAmB,EAE5B,cAAc,EAAE,2BAA2B,EAE3C,eAAe,EAAE,gBAAgB;IAG9C,OAAO,CACX,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAClC,OAAO,CAAC,mBAAmB,CAAC;CAuGhC"}
@@ -35,7 +35,7 @@ let ResumeFeatureUseCase = class ResumeFeatureUseCase {
35
35
  this.processService = processService;
36
36
  this.worktreeService = worktreeService;
37
37
  }
38
- async execute(featureId) {
38
+ async execute(featureId, options) {
39
39
  // Resolve feature by exact ID or prefix
40
40
  const feature = (await this.featureRepo.findById(featureId)) ??
41
41
  (await this.featureRepo.findByIdPrefix(featureId));
@@ -79,7 +79,9 @@ let ResumeFeatureUseCase = class ResumeFeatureUseCase {
79
79
  agentType: lastRun.agentType,
80
80
  agentName: lastRun.agentName,
81
81
  status: AgentRunStatus.pending,
82
- prompt: lastRun.prompt,
82
+ prompt: options?.promptPrefix
83
+ ? `${options.promptPrefix}\n\n${lastRun.prompt}`
84
+ : lastRun.prompt,
83
85
  threadId: lastRun.threadId, // Same thread for checkpoint continuity
84
86
  featureId: feature.id,
85
87
  repositoryPath: feature.repositoryPath,
@@ -1 +1 @@
1
- {"version":3,"file":"fast-implement.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/fast-implement.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AAEpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAUrD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,cAAc,IAGhD,OAAO,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAoD7E"}
1
+ {"version":3,"file":"fast-implement.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/fast-implement.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AAEpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAgBrD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,cAAc,IAGhD,OAAO,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAkE7E"}
@@ -12,7 +12,7 @@
12
12
  import { mkdirSync, writeFileSync } from 'node:fs';
13
13
  import { join, dirname } from 'node:path';
14
14
  import { isGraphBubbleUp } from '@langchain/langgraph';
15
- import { createNodeLogger, buildExecutorOptions, retryExecute } from './node-helpers.js';
15
+ import { createNodeLogger, buildExecutorOptions, retryExecute, getCompletedPhases, markPhaseComplete, } from './node-helpers.js';
16
16
  import { reportNodeStart } from '../heartbeat.js';
17
17
  import { recordPhaseStart, recordPhaseEnd } from '../phase-timing-context.js';
18
18
  import { updateNodeLifecycle } from '../lifecycle-context.js';
@@ -33,6 +33,16 @@ export function createFastImplementNode(executor) {
33
33
  log.info('Starting fast implementation');
34
34
  reportNodeStart('fast-implement');
35
35
  await updateNodeLifecycle('fast-implement');
36
+ // Skip if already completed (resume from error path)
37
+ const completedPhases = getCompletedPhases(state.specDir);
38
+ if (completedPhases.includes('fast-implement')) {
39
+ log.info('Phase already completed, skipping execution');
40
+ return {
41
+ currentNode: 'fast-implement',
42
+ messages: ['[fast-implement] already completed — skipping'],
43
+ _needsReexecution: false,
44
+ };
45
+ }
36
46
  const startTime = Date.now();
37
47
  const timingId = await recordPhaseStart('fast-implement');
38
48
  try {
@@ -51,6 +61,8 @@ export function createFastImplementNode(executor) {
51
61
  log.info('Evidence collection disabled via settings — skipping');
52
62
  }
53
63
  await recordPhaseEnd(timingId, durationMs);
64
+ // Mark phase complete so resume from error skips re-execution
65
+ markPhaseComplete(state.specDir, 'fast-implement', log);
54
66
  return {
55
67
  currentNode: 'fast-implement',
56
68
  evidence,
@@ -1 +1 @@
1
- {"version":3,"file":"tool-installer.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/tool-installer/tool-installer.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sEAAsE,CAAC;AAClH,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EAEnB,MAAM,qCAAqC,CAAC;AA2B7C,qBACa,wBAAyB,YAAW,qBAAqB;IACpE;;;OAGG;IACG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAoC1E;;;OAGG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI;IAqB9D;;;OAGG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAChC,OAAO,CAAC,sBAAsB,CAAC;IAwFlC;;OAEG;IACH,OAAO,CAAC,6BAA6B;CA4BtC"}
1
+ {"version":3,"file":"tool-installer.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/tool-installer/tool-installer.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sEAAsE,CAAC;AAClH,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EAEnB,MAAM,qCAAqC,CAAC;AA2B7C,qBACa,wBAAyB,YAAW,qBAAqB;IACpE;;;OAGG;IACG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAoC1E;;;OAGG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI;IAqB9D;;;OAGG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAChC,OAAO,CAAC,sBAAsB,CAAC;IAgFlC;;OAEG;IACH,OAAO,CAAC,6BAA6B;CA4BtC"}
@@ -107,14 +107,9 @@ let ToolInstallerServiceImpl = class ToolInstallerServiceImpl {
107
107
  }
108
108
  return new Promise((resolve) => {
109
109
  let output = '';
110
- // Inherit stdin when running in an interactive terminal so that commands
111
- // requiring sudo can prompt the user for a password. In non-interactive
112
- // contexts (web UI, CI) stdin is piped and closed immediately to prevent
113
- // the process from hanging waiting for input.
114
- const isInteractive = process.stdin.isTTY === true;
115
110
  const child = spawn(installCommand.command, [], {
116
111
  shell: true,
117
- stdio: [isInteractive ? 'inherit' : 'pipe', 'pipe', 'pipe'],
112
+ stdio: ['pipe', 'pipe', 'pipe'],
118
113
  env: {
119
114
  ...process.env,
120
115
  DEBIAN_FRONTEND: 'noninteractive',
@@ -122,10 +117,8 @@ let ToolInstallerServiceImpl = class ToolInstallerServiceImpl {
122
117
  GPG_TTY: '',
123
118
  },
124
119
  });
125
- // Close stdin in non-interactive mode to prevent prompts from hanging
126
- if (!isInteractive) {
127
- child.stdin?.end();
128
- }
120
+ // Close stdin immediately to prevent interactive prompts
121
+ child.stdin?.end();
129
122
  // Stream output from stdout and stderr
130
123
  const pipeOutput = (stream) => {
131
124
  if (!stream)
@@ -12,17 +12,13 @@
12
12
  "commands": {
13
13
  "linux": "curl -fsSL https://claude.ai/install.sh | bash",
14
14
  "darwin": "curl -fsSL https://claude.ai/install.sh | bash",
15
- "win32": "powershell -Command \"iwr -useb https://claude.ai/install.ps1 | iex\""
15
+ "win32": "npm install -g @anthropic-ai/claude-code"
16
16
  },
17
17
  "timeout": 300000,
18
- "documentationUrl": "https://docs.anthropic.com/en/docs/claude-code/overview",
18
+ "documentationUrl": "https://code.claude.com/docs/en/overview",
19
19
  "verifyCommand": "claude --version",
20
20
  "autoInstall": true,
21
- "openDirectory": {
22
- "linux": "cd {dir} && exec claude",
23
- "darwin": "cd {dir} && exec claude",
24
- "win32": "cd /d {dir} && claude"
25
- },
21
+ "openDirectory": "cd {dir} && exec claude",
26
22
  "spawnOptions": {
27
23
  "shell": true,
28
24
  "stdio": "inherit",
@@ -30,7 +26,6 @@
30
26
  },
31
27
  "terminalCommand": {
32
28
  "linux": "x-terminal-emulator -e bash -c 'cd {dir} && exec claude'",
33
- "darwin": "osascript -e 'tell application \"Terminal\" to do script \"cd {dir} && exec claude\"'",
34
- "win32": "start cmd /k \"cd /d {dir} && claude\""
29
+ "darwin": "open -a Terminal.app bash -c 'cd {dir} && exec claude'"
35
30
  }
36
31
  }
@@ -117,14 +117,7 @@ function printInstallInstructions(metadata) {
117
117
  // Print open directory command if available
118
118
  if (metadata.openDirectory) {
119
119
  console.log(fmt.heading('Open Directory'));
120
- if (typeof metadata.openDirectory === 'string') {
121
- console.log(`${colors.muted('$')} ${metadata.openDirectory}`);
122
- }
123
- else {
124
- for (const [platform, cmd] of Object.entries(metadata.openDirectory)) {
125
- console.log(`${colors.muted(`[${platform}]`)} ${cmd}`);
126
- }
127
- }
120
+ console.log(`${colors.muted('$')} ${metadata.openDirectory}`);
128
121
  console.log();
129
122
  }
130
123
  // Print documentation link
@@ -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) {
@@ -10,8 +10,6 @@ export interface AgentAuthStatus {
10
10
  binaryName: string | null;
11
11
  /** Instructions to authenticate if not authenticated */
12
12
  authCommand: string | null;
13
- /** Platform-resolved install command (e.g. "npm install -g @google/gemini-cli") */
14
- installCommand: string | null;
15
13
  }
16
14
  /**
17
15
  * Check agent tool installation + auth status.
@@ -1 +1 @@
1
- {"version":3,"file":"check-agent-auth.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/check-agent-auth.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,SAAS,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,aAAa,EAAE,OAAO,CAAC;IACvB,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,wDAAwD;IACxD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,mFAAmF;IACnF,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AA4FD;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,eAAe,CAAC,CAwF/D"}
1
+ {"version":3,"file":"check-agent-auth.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/check-agent-auth.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,SAAS,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,aAAa,EAAE,OAAO,CAAC;IACvB,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,wDAAwD;IACxD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AA4FD;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,eAAe,CAAC,CAiF/D"}
@@ -20,7 +20,7 @@ const AGENT_TOOL_MAP = {
20
20
  };
21
21
  const AGENT_BINARY_MAP = {
22
22
  'claude-code': 'claude',
23
- cursor: 'cursor-agent',
23
+ cursor: 'agent',
24
24
  'gemini-cli': 'gemini',
25
25
  };
26
26
  /**
@@ -113,7 +113,6 @@ export async function checkAgentAuth() {
113
113
  label: 'Unknown',
114
114
  binaryName: null,
115
115
  authCommand: null,
116
- installCommand: null,
117
116
  };
118
117
  }
119
118
  const label = AGENT_LABELS[agentType] ?? agentType;
@@ -128,18 +127,15 @@ export async function checkAgentAuth() {
128
127
  label,
129
128
  binaryName: null,
130
129
  authCommand: null,
131
- installCommand: null,
132
130
  };
133
131
  }
134
132
  // Check if tool is installed
135
133
  let installed = false;
136
- let installCommand = null;
137
134
  try {
138
135
  const useCase = resolve('ListToolsUseCase');
139
136
  const tools = await useCase.execute();
140
137
  const tool = tools.find((t) => t.id === toolId);
141
138
  installed = tool?.status.status === 'available';
142
- installCommand = tool?.installCommand ?? null;
143
139
  }
144
140
  catch {
145
141
  installed = false;
@@ -152,7 +148,6 @@ export async function checkAgentAuth() {
152
148
  label,
153
149
  binaryName,
154
150
  authCommand: binaryName ? `Install ${label} first` : null,
155
- installCommand,
156
151
  };
157
152
  }
158
153
  // Tier 1: instant file/env check
@@ -165,7 +160,6 @@ export async function checkAgentAuth() {
165
160
  label,
166
161
  binaryName,
167
162
  authCommand: binaryName,
168
- installCommand,
169
163
  };
170
164
  }
171
165
  // Tier 2: subprocess verify (best effort, ~200ms)
@@ -180,6 +174,5 @@ export async function checkAgentAuth() {
180
174
  label,
181
175
  binaryName,
182
176
  authCommand: authenticated ? null : binaryName,
183
- installCommand,
184
177
  };
185
178
  }
@@ -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) {
@@ -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);
@@ -70,7 +70,7 @@ function AgentAuthBanner({ status, onRetry, }) {
70
70
  }
71
71
  // Not installed
72
72
  if (!status.installed) {
73
- return (_jsxs("div", { className: "flex w-full flex-col gap-2 rounded-md bg-amber-500/10 px-3 py-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(AlertCircle, { className: "h-3 w-3 text-amber-600 dark:text-amber-400" }), _jsxs("span", { className: "text-[10px] font-medium text-amber-700 dark:text-amber-300", children: [status.label, " not installed"] })] }), status.installCommand ? (_jsxs("div", { className: "rounded bg-zinc-900 px-2 py-1 font-mono text-[10px] text-zinc-300", children: [_jsx("span", { className: "text-zinc-500 select-none", children: "$ " }), status.installCommand] })) : null, _jsx("button", { type: "button", onClick: onRetry, className: "self-start text-[10px] font-medium text-amber-700 underline underline-offset-2 hover:text-amber-900 dark:text-amber-300 dark:hover:text-amber-100", children: "Re-check" })] }));
73
+ return (_jsxs("div", { className: "flex w-full flex-col gap-2 rounded-md bg-amber-500/10 px-3 py-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(AlertCircle, { className: "h-3 w-3 text-amber-600 dark:text-amber-400" }), _jsxs("span", { className: "text-[10px] font-medium text-amber-700 dark:text-amber-300", children: [status.label, " not installed"] })] }), status.binaryName ? (_jsxs("div", { className: "rounded bg-zinc-900 px-2 py-1 font-mono text-[10px] text-zinc-300", children: [_jsx("span", { className: "text-zinc-500 select-none", children: "$ " }), "npm install -g ", status.binaryName] })) : null, _jsx("button", { type: "button", onClick: onRetry, className: "self-start text-[10px] font-medium text-amber-700 underline underline-offset-2 hover:text-amber-900 dark:text-amber-300 dark:hover:text-amber-100", children: "Re-check" })] }));
74
74
  }
75
75
  // Installed but not authenticated
76
76
  return (_jsxs("div", { className: "flex w-full flex-col gap-2 rounded-md bg-amber-500/10 px-3 py-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(AlertCircle, { className: "h-3 w-3 text-amber-600 dark:text-amber-400" }), _jsxs("span", { className: "text-[10px] font-medium text-amber-700 dark:text-amber-300", children: [status.label, " needs authentication"] })] }), status.authCommand ? (_jsxs("div", { className: "rounded bg-zinc-900 px-2 py-1 font-mono text-[10px] text-zinc-300", children: [_jsx("span", { className: "text-zinc-500 select-none", children: "$ " }), status.authCommand] })) : null, _jsxs("div", { className: "flex items-center gap-2", children: [status.binaryName ? (_jsxs("button", { type: "button", "data-testid": "auth-banner-open-terminal", onClick: async () => {
@@ -28,7 +28,7 @@ const installedNoLaunchTool = {
28
28
  required: false,
29
29
  openDirectory: undefined,
30
30
  documentationUrl: 'https://claude.ai',
31
- installCommand: 'curl -fsSL https://claude.ai/install.sh | bash',
31
+ installCommand: 'npm install -g @anthropic-ai/claude-code',
32
32
  status: { status: 'available', toolName: 'claude-code' },
33
33
  author: 'Anthropic',
34
34
  website: 'https://claude.ai/code',
@@ -45,7 +45,7 @@ const mockTools = [
45
45
  required: false,
46
46
  openDirectory: undefined,
47
47
  documentationUrl: 'https://claude.ai/code',
48
- installCommand: 'curl -fsSL https://claude.ai/install.sh | bash',
48
+ installCommand: 'npm install -g @anthropic-ai/claude-code',
49
49
  status: { status: 'available', toolName: 'claude-code' },
50
50
  author: 'Anthropic',
51
51
  website: 'https://claude.ai/code',