@shepai/cli 1.142.0 → 1.142.1-pr454.60f0445

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 (259) hide show
  1. package/apis/json-schema/Feature.yaml +10 -0
  2. package/apis/json-schema/PullRequest.yaml +11 -0
  3. package/apis/json-schema/SdlcLifecycle.yaml +1 -0
  4. package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts +2 -0
  5. package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts.map +1 -1
  6. package/dist/packages/core/src/application/ports/output/services/git-fork-service.interface.d.ts +33 -0
  7. package/dist/packages/core/src/application/ports/output/services/git-fork-service.interface.d.ts.map +1 -0
  8. package/dist/packages/core/src/application/ports/output/services/git-fork-service.interface.js +24 -0
  9. package/dist/packages/core/src/application/use-cases/features/adopt-branch.use-case.d.ts.map +1 -1
  10. package/dist/packages/core/src/application/use-cases/features/adopt-branch.use-case.js +2 -0
  11. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
  12. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +16 -1
  13. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts +2 -0
  14. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts.map +1 -1
  15. package/dist/packages/core/src/application/use-cases/features/poll-upstream-pr.use-case.d.ts +29 -0
  16. package/dist/packages/core/src/application/use-cases/features/poll-upstream-pr.use-case.d.ts.map +1 -0
  17. package/dist/packages/core/src/application/use-cases/features/poll-upstream-pr.use-case.js +105 -0
  18. package/dist/packages/core/src/application/use-cases/features/start-feature.use-case.d.ts.map +1 -1
  19. package/dist/packages/core/src/application/use-cases/features/start-feature.use-case.js +2 -0
  20. package/dist/packages/core/src/domain/generated/output.d.ts +22 -1
  21. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  22. package/dist/packages/core/src/domain/generated/output.js +1 -0
  23. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  24. package/dist/packages/core/src/infrastructure/di/container.js +2 -0
  25. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts +2 -0
  26. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts.map +1 -1
  27. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.js +4 -0
  28. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/045-add-fork-and-pr-fields.d.ts +11 -0
  29. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/045-add-fork-and-pr-fields.d.ts.map +1 -0
  30. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/045-add-fork-and-pr-fields.js +28 -0
  31. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.d.ts.map +1 -1
  32. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.js +6 -2
  33. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/fast-feature-agent-graph.d.ts +10 -0
  34. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/fast-feature-agent-graph.d.ts.map +1 -1
  35. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts +34 -0
  36. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts.map +1 -1
  37. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts +2 -0
  38. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts.map +1 -1
  39. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.js +6 -0
  40. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts +2 -0
  41. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts.map +1 -1
  42. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js +12 -0
  43. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.d.ts +2 -0
  44. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.d.ts.map +1 -1
  45. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.js +89 -49
  46. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.d.ts +2 -0
  47. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.d.ts.map +1 -1
  48. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.js +8 -0
  49. package/dist/packages/core/src/infrastructure/services/git/git-fork.service.d.ts +29 -0
  50. package/dist/packages/core/src/infrastructure/services/git/git-fork.service.d.ts.map +1 -0
  51. package/dist/packages/core/src/infrastructure/services/git/git-fork.service.js +204 -0
  52. package/dist/packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.d.ts +13 -3
  53. package/dist/packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.d.ts.map +1 -1
  54. package/dist/packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.js +39 -10
  55. package/dist/src/presentation/cli/commands/ui.command.d.ts.map +1 -1
  56. package/dist/src/presentation/cli/commands/ui.command.js +3 -1
  57. package/dist/src/presentation/web/app/actions/create-feature.d.ts +2 -0
  58. package/dist/src/presentation/web/app/actions/create-feature.d.ts.map +1 -1
  59. package/dist/src/presentation/web/app/actions/create-feature.js +5 -1
  60. package/dist/src/presentation/web/app/api/agent-events/route.d.ts.map +1 -1
  61. package/dist/src/presentation/web/app/api/agent-events/route.js +1 -0
  62. package/dist/src/presentation/web/app/api/sessions/route.d.ts.map +1 -1
  63. package/dist/src/presentation/web/app/api/sessions/route.js +45 -13
  64. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts +2 -0
  65. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  66. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +22 -5
  67. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts +18 -0
  68. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts.map +1 -1
  69. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.js +52 -0
  70. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.d.ts.map +1 -1
  71. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.js +1 -0
  72. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  73. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +1 -1
  74. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts +7 -0
  75. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts.map +1 -1
  76. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.js +29 -0
  77. package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.d.ts +3 -1
  78. package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.d.ts.map +1 -1
  79. package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.js +13 -5
  80. package/dist/src/presentation/web/components/common/repository-node/repository-node.d.ts.map +1 -1
  81. package/dist/src/presentation/web/components/common/repository-node/repository-node.js +1 -1
  82. package/dist/src/presentation/web/dev-server.js +3 -1
  83. package/dist/src/presentation/web/next.config.d.ts.map +1 -1
  84. package/dist/src/presentation/web/next.config.js +4 -0
  85. package/dist/tsconfig.build.tsbuildinfo +1 -1
  86. package/package.json +1 -1
  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 +6 -4
  92. package/web/.next/required-server-files.json +6 -4
  93. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +28 -28
  94. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +1 -1
  95. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  96. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  97. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +28 -28
  98. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
  99. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  100. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  101. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
  102. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +1 -1
  103. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  104. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  105. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +36 -36
  106. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
  107. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  108. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  109. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
  110. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
  111. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  112. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  113. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +28 -28
  114. package/web/.next/server/app/(dashboard)/create/page.js +1 -1
  115. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  116. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  117. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
  118. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +1 -1
  119. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  120. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  121. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +36 -36
  122. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
  123. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  124. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  125. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +26 -26
  126. package/web/.next/server/app/(dashboard)/page.js +1 -1
  127. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  128. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  129. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
  130. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
  131. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  132. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  133. package/web/.next/server/app/_global-error.html +2 -2
  134. package/web/.next/server/app/_global-error.rsc +1 -1
  135. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  136. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  137. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  138. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  139. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  140. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +3 -3
  141. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  142. package/web/.next/server/app/api/sessions/route.js +3 -2
  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 +8 -8
  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 +8 -8
  148. package/web/.next/server/app/skills/page.js +1 -1
  149. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  150. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  151. package/web/.next/server/app/tools/page/server-reference-manifest.json +8 -8
  152. package/web/.next/server/app/tools/page.js +1 -1
  153. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  154. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  155. package/web/.next/server/app/version/page/server-reference-manifest.json +3 -3
  156. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  157. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +1 -1
  158. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +1 -1
  159. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js +2 -2
  160. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js.map +1 -1
  161. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_ff60e4a5.js +3 -0
  162. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_ff60e4a5.js.map +1 -0
  163. package/web/.next/server/chunks/[externals]__448264a3._.js +3 -0
  164. package/web/.next/server/chunks/[externals]__448264a3._.js.map +1 -0
  165. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  166. package/web/.next/server/chunks/[root-of-the-server]__c6e32a23._.js +1 -1
  167. package/web/.next/server/chunks/[root-of-the-server]__c6e32a23._.js.map +1 -1
  168. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js +1 -1
  169. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js.map +1 -1
  170. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  171. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  172. package/web/.next/server/chunks/ssr/[root-of-the-server]__0b150ddf._.js +3 -0
  173. package/web/.next/server/chunks/ssr/[root-of-the-server]__0b150ddf._.js.map +1 -0
  174. package/web/.next/server/chunks/ssr/{[root-of-the-server]__a5f9c6e5._.js → [root-of-the-server]__2138fa7e._.js} +3 -3
  175. package/web/.next/server/chunks/ssr/{[root-of-the-server]__a5f9c6e5._.js.map → [root-of-the-server]__2138fa7e._.js.map} +1 -1
  176. package/web/.next/server/chunks/ssr/[root-of-the-server]__29580090._.js +1 -1
  177. package/web/.next/server/chunks/ssr/[root-of-the-server]__29580090._.js.map +1 -1
  178. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  179. package/web/.next/server/chunks/ssr/[root-of-the-server]__3ef34e4c._.js +1 -1
  180. package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js +1 -1
  181. package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js.map +1 -1
  182. package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js +1 -1
  183. package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js.map +1 -1
  184. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +2 -2
  185. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
  186. package/web/.next/server/chunks/ssr/[root-of-the-server]__c094882b._.js +1 -1
  187. package/web/.next/server/chunks/ssr/[root-of-the-server]__c094882b._.js.map +1 -1
  188. package/web/.next/server/chunks/ssr/[root-of-the-server]__d48c5b11._.js +1 -1
  189. package/web/.next/server/chunks/ssr/[root-of-the-server]__d48c5b11._.js.map +1 -1
  190. package/web/.next/server/chunks/ssr/[root-of-the-server]__dac5dbf1._.js +1 -1
  191. package/web/.next/server/chunks/ssr/[root-of-the-server]__dac5dbf1._.js.map +1 -1
  192. package/web/.next/server/chunks/ssr/[root-of-the-server]__fae8b355._.js +1 -1
  193. package/web/.next/server/chunks/ssr/[root-of-the-server]__fae8b355._.js.map +1 -1
  194. package/web/.next/server/chunks/ssr/_0c5f56e3._.js +2 -2
  195. package/web/.next/server/chunks/ssr/_0c5f56e3._.js.map +1 -1
  196. package/web/.next/server/chunks/ssr/_1b719e7f._.js +1 -1
  197. package/web/.next/server/chunks/ssr/_1b719e7f._.js.map +1 -1
  198. package/web/.next/server/chunks/ssr/_37e8548b._.js +1 -1
  199. package/web/.next/server/chunks/ssr/_37e8548b._.js.map +1 -1
  200. package/web/.next/server/chunks/ssr/_55d763e2._.js +1 -1
  201. package/web/.next/server/chunks/ssr/_55d763e2._.js.map +1 -1
  202. package/web/.next/server/chunks/ssr/_6256a985._.js +1 -1
  203. package/web/.next/server/chunks/ssr/_6256a985._.js.map +1 -1
  204. package/web/.next/server/chunks/ssr/_64bdfc6f._.js +2 -2
  205. package/web/.next/server/chunks/ssr/_64bdfc6f._.js.map +1 -1
  206. package/web/.next/server/chunks/ssr/_67104d9e._.js +1 -1
  207. package/web/.next/server/chunks/ssr/_7dca1882._.js +1 -1
  208. package/web/.next/server/chunks/ssr/_7dca1882._.js.map +1 -1
  209. package/web/.next/server/chunks/ssr/{_7e5c4d9c._.js → _a8a2233a._.js} +2 -2
  210. package/web/.next/server/chunks/ssr/{_7e5c4d9c._.js.map → _a8a2233a._.js.map} +1 -1
  211. package/web/.next/server/chunks/ssr/_a9f57758._.js +1 -1
  212. package/web/.next/server/chunks/ssr/_b71645b4._.js +1 -1
  213. package/web/.next/server/chunks/ssr/_b71645b4._.js.map +1 -1
  214. package/web/.next/server/chunks/ssr/_cfbd1d7e._.js +1 -1
  215. package/web/.next/server/chunks/ssr/_d4b20e29._.js.map +1 -1
  216. package/web/.next/server/chunks/ssr/_d8575088._.js +1 -1
  217. package/web/.next/server/chunks/ssr/_d8575088._.js.map +1 -1
  218. package/web/.next/server/chunks/ssr/_f39a1adb._.js +1 -1
  219. package/web/.next/server/chunks/ssr/_f39a1adb._.js.map +1 -1
  220. package/web/.next/server/chunks/ssr/{_1c6fbecf._.js → _f4d19ff3._.js} +2 -2
  221. package/web/.next/server/chunks/ssr/{_1c6fbecf._.js.map → _f4d19ff3._.js.map} +1 -1
  222. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  223. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  224. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js +1 -1
  225. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js.map +1 -1
  226. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js +1 -1
  227. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js.map +1 -1
  228. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
  229. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  230. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  231. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  232. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  233. package/web/.next/server/chunks/ssr/{src_presentation_web_7bda2f00._.js → src_presentation_web_d50bc654._.js} +2 -2
  234. package/web/.next/server/chunks/ssr/{src_presentation_web_7bda2f00._.js.map → src_presentation_web_d50bc654._.js.map} +1 -1
  235. package/web/.next/server/pages/500.html +2 -2
  236. package/web/.next/server/server-reference-manifest.js +1 -1
  237. package/web/.next/server/server-reference-manifest.json +44 -44
  238. package/web/.next/static/chunks/{4d7e25ef4b8e2f62.js → 00fd65dc10f3da0a.js} +1 -1
  239. package/web/.next/static/chunks/{ea9969f79b2162ec.js → 024575217799dac8.js} +1 -1
  240. package/web/.next/static/chunks/101d4334f60ec83f.js +1 -0
  241. package/web/.next/static/chunks/{73889aad2b3356b1.js → 4c543e4daf8755a3.js} +2 -2
  242. package/web/.next/static/chunks/{e599050b1f6466fe.js → 72e48a32d1f244b9.js} +1 -1
  243. package/web/.next/static/chunks/{13978ecd00a81172.js → 8a42aa668b401526.js} +1 -1
  244. package/web/.next/static/chunks/94bb64cb067c785e.js +1 -0
  245. package/web/.next/static/chunks/{74eef53714ab461d.js → 9e93ecdd1b445607.js} +1 -1
  246. package/web/.next/static/chunks/a230d5954cc322fd.js +1 -0
  247. package/web/.next/static/chunks/{2eec9756f5220e22.js → a4c2c8c731b0875f.js} +1 -1
  248. package/web/.next/static/chunks/{21ddf1d59c98adf0.js → d5bb1d4f97abcdd7.js} +1 -1
  249. package/web/.next/static/chunks/{4adda8dd11458a46.js → d7425a1e8e823fb1.js} +2 -2
  250. package/web/.next/server/chunks/[root-of-the-server]__a62bd945._.js +0 -3
  251. package/web/.next/server/chunks/[root-of-the-server]__a62bd945._.js.map +0 -1
  252. package/web/.next/server/chunks/ssr/[root-of-the-server]__6ec59045._.js +0 -3
  253. package/web/.next/server/chunks/ssr/[root-of-the-server]__6ec59045._.js.map +0 -1
  254. package/web/.next/static/chunks/3f18dfdd07d48ecd.js +0 -1
  255. package/web/.next/static/chunks/6ad8d8682f4836c9.js +0 -1
  256. package/web/.next/static/chunks/a6a6a8387bae31f0.js +0 -1
  257. /package/web/.next/static/{G2BdtwIuunZEcXQ0FjJJF → zv3n0xrL5vsVhyfYT8O1w}/_buildManifest.js +0 -0
  258. /package/web/.next/static/{G2BdtwIuunZEcXQ0FjJJF → zv3n0xrL5vsVhyfYT8O1w}/_clientMiddlewareManifest.json +0 -0
  259. /package/web/.next/static/{G2BdtwIuunZEcXQ0FjJJF → zv3n0xrL5vsVhyfYT8O1w}/_ssgManifest.js +0 -0
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Git Fork Service Implementation
3
+ *
4
+ * Manages GitHub fork operations: forking repos, pushing to forks,
5
+ * and creating/querying upstream PRs.
6
+ * Uses constructor dependency injection for the command executor.
7
+ */
8
+ import type { IGitForkService, UpstreamPrStatus } from '../../../application/ports/output/services/git-fork-service.interface.js';
9
+ import type { ExecFunction } from './worktree.service.js';
10
+ export declare class GitForkService implements IGitForkService {
11
+ private readonly execFile;
12
+ constructor(execFile: ExecFunction);
13
+ forkRepository(cwd: string): Promise<void>;
14
+ /** Ensure that an `upstream` remote exists pointing to `nameWithOwner`. */
15
+ private _ensureUpstreamRemote;
16
+ pushToFork(cwd: string, branch: string): Promise<void>;
17
+ createUpstreamPr(cwd: string, title: string, body: string, head: string, base: string): Promise<{
18
+ url: string;
19
+ number: number;
20
+ }>;
21
+ getUpstreamPrStatus(upstreamRepo: string, prNumber: number): Promise<UpstreamPrStatus>;
22
+ /**
23
+ * Resolve the upstream repo as "owner/repo".
24
+ * 1. Try `git remote get-url upstream` and parse it.
25
+ * 2. Fall back to `gh repo view --json parent`.
26
+ */
27
+ private _getUpstreamRepo;
28
+ }
29
+ //# sourceMappingURL=git-fork.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-fork.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/git-fork.service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EACjB,MAAM,0EAA0E,CAAC;AAKlF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AA2C1D,qBACa,cAAe,YAAW,eAAe;IAChB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAMrE,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2ChD,2EAA2E;YAC7D,qBAAqB;IAmB7B,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBtD,gBAAgB,CACpB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IA6CrC,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAyC5F;;;;OAIG;YACW,gBAAgB;CAiB/B"}
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Git Fork Service Implementation
3
+ *
4
+ * Manages GitHub fork operations: forking repos, pushing to forks,
5
+ * and creating/querying upstream PRs.
6
+ * Uses constructor dependency injection for the command executor.
7
+ */
8
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
9
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
10
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
11
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
12
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
13
+ };
14
+ var __metadata = (this && this.__metadata) || function (k, v) {
15
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
16
+ };
17
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
18
+ return function (target, key) { decorator(target, key, paramIndex); }
19
+ };
20
+ import { injectable, inject } from 'tsyringe';
21
+ import { GitForkError, GitForkErrorCode, } from '../../../application/ports/output/services/git-fork-service.interface.js';
22
+ /** Keywords indicating an authentication failure in error messages. */
23
+ const AUTH_KEYWORDS = ['auth', 'credential', 'forbidden', '401', '403'];
24
+ /** Returns true when the error message suggests an authentication problem. */
25
+ function isAuthError(err) {
26
+ const msg = err instanceof Error ? err.message.toLowerCase() : String(err).toLowerCase();
27
+ return AUTH_KEYWORDS.some((kw) => msg.includes(kw));
28
+ }
29
+ /** Parse owner/repo from a GitHub URL or nameWithOwner string. */
30
+ function parseOwnerRepo(raw) {
31
+ // Handle https://github.com/owner/repo[.git]
32
+ const httpsMatch = raw.match(/github\.com[/:]([\w.-]+\/[\w.-]+?)(?:\.git)?$/);
33
+ if (httpsMatch)
34
+ return httpsMatch[1];
35
+ // Handle git@github.com:owner/repo[.git]
36
+ const sshMatch = raw.match(/git@github\.com:([\w.-]+\/[\w.-]+?)(?:\.git)?$/);
37
+ if (sshMatch)
38
+ return sshMatch[1];
39
+ // Assume it's already "owner/repo"
40
+ return raw.replace(/\.git$/, '');
41
+ }
42
+ /** Extract the PR number from a GitHub PR URL. */
43
+ function extractPrNumber(url) {
44
+ const match = url.match(/\/pull\/(\d+)/);
45
+ if (!match)
46
+ throw new Error(`Cannot parse PR number from URL: ${url}`);
47
+ return parseInt(match[1], 10);
48
+ }
49
+ /** Normalise GitHub GraphQL state strings (OPEN/MERGED/CLOSED) to lowercase union. */
50
+ function normaliseState(state) {
51
+ switch (state.toUpperCase()) {
52
+ case 'OPEN':
53
+ return 'open';
54
+ case 'MERGED':
55
+ return 'merged';
56
+ case 'CLOSED':
57
+ default:
58
+ return 'closed';
59
+ }
60
+ }
61
+ let GitForkService = class GitForkService {
62
+ execFile;
63
+ constructor(execFile) {
64
+ this.execFile = execFile;
65
+ }
66
+ // ---------------------------------------------------------------------------
67
+ // forkRepository
68
+ // ---------------------------------------------------------------------------
69
+ async forkRepository(cwd) {
70
+ // Check if the current origin is already a fork.
71
+ const viewResult = await this.execFile('gh', ['repo', 'view', '--json', 'isFork,parent'], {
72
+ cwd,
73
+ });
74
+ const repoInfo = JSON.parse(viewResult.stdout);
75
+ if (repoInfo.isFork && repoInfo.parent) {
76
+ // Origin is already a fork — just make sure `upstream` remote points to the parent.
77
+ await this._ensureUpstreamRemote(cwd, repoInfo.parent.nameWithOwner);
78
+ return;
79
+ }
80
+ // Not yet a fork — create one and remap remotes.
81
+ try {
82
+ const { stderr } = await this.execFile('gh', ['repo', 'fork', '--remote', '--remote-name', 'origin'], { cwd });
83
+ // gh exits 0 even for "already exists" — treat it as success.
84
+ if (stderr?.toLowerCase().includes('already exists')) {
85
+ return;
86
+ }
87
+ }
88
+ catch (err) {
89
+ if (isAuthError(err)) {
90
+ throw new GitForkError(`Authentication failed while forking repository: ${err.message}`, GitForkErrorCode.AUTH_FAILURE, err instanceof Error ? err : undefined);
91
+ }
92
+ throw new GitForkError(`Failed to fork repository: ${err.message}`, GitForkErrorCode.FORK_FAILED, err instanceof Error ? err : undefined);
93
+ }
94
+ }
95
+ /** Ensure that an `upstream` remote exists pointing to `nameWithOwner`. */
96
+ async _ensureUpstreamRemote(cwd, nameWithOwner) {
97
+ const { stdout } = await this.execFile('git', ['remote'], { cwd });
98
+ const remotes = stdout
99
+ .split('\n')
100
+ .map((r) => r.trim())
101
+ .filter(Boolean);
102
+ if (!remotes.includes('upstream')) {
103
+ await this.execFile('git', ['remote', 'add', 'upstream', `https://github.com/${nameWithOwner}.git`], { cwd });
104
+ }
105
+ }
106
+ // ---------------------------------------------------------------------------
107
+ // pushToFork
108
+ // ---------------------------------------------------------------------------
109
+ async pushToFork(cwd, branch) {
110
+ try {
111
+ await this.execFile('git', ['push', '-u', 'origin', branch], { cwd });
112
+ }
113
+ catch (err) {
114
+ if (isAuthError(err)) {
115
+ throw new GitForkError(`Authentication failed while pushing to fork: ${err.message}`, GitForkErrorCode.AUTH_FAILURE, err instanceof Error ? err : undefined);
116
+ }
117
+ throw new GitForkError(`Failed to push branch "${branch}" to fork: ${err.message}`, GitForkErrorCode.PUSH_FAILED, err instanceof Error ? err : undefined);
118
+ }
119
+ }
120
+ // ---------------------------------------------------------------------------
121
+ // createUpstreamPr
122
+ // ---------------------------------------------------------------------------
123
+ async createUpstreamPr(cwd, title, body, head, base) {
124
+ const upstreamRepo = await this._getUpstreamRepo(cwd);
125
+ try {
126
+ const { stdout } = await this.execFile('gh', [
127
+ 'pr',
128
+ 'create',
129
+ '--repo',
130
+ upstreamRepo,
131
+ '--title',
132
+ title,
133
+ '--body',
134
+ body,
135
+ '--head',
136
+ head,
137
+ '--base',
138
+ base,
139
+ ], { cwd });
140
+ const url = stdout.trim();
141
+ const number = extractPrNumber(url);
142
+ return { url, number };
143
+ }
144
+ catch (err) {
145
+ if (isAuthError(err)) {
146
+ throw new GitForkError(`Authentication failed while creating upstream PR: ${err.message}`, GitForkErrorCode.AUTH_FAILURE, err instanceof Error ? err : undefined);
147
+ }
148
+ throw new GitForkError(`Failed to create upstream PR: ${err.message}`, GitForkErrorCode.UPSTREAM_PR_FAILED, err instanceof Error ? err : undefined);
149
+ }
150
+ }
151
+ // ---------------------------------------------------------------------------
152
+ // getUpstreamPrStatus
153
+ // ---------------------------------------------------------------------------
154
+ async getUpstreamPrStatus(upstreamRepo, prNumber) {
155
+ try {
156
+ const { stdout } = await this.execFile('gh', ['pr', 'view', String(prNumber), '--repo', upstreamRepo, '--json', 'state,url,number'], {});
157
+ const data = JSON.parse(stdout);
158
+ return {
159
+ state: normaliseState(data.state),
160
+ url: data.url,
161
+ number: data.number,
162
+ };
163
+ }
164
+ catch (err) {
165
+ const msg = err instanceof Error ? err.message.toLowerCase() : String(err).toLowerCase();
166
+ if (isAuthError(err)) {
167
+ throw new GitForkError(`Authentication failed while fetching upstream PR status: ${err.message}`, GitForkErrorCode.AUTH_FAILURE, err instanceof Error ? err : undefined);
168
+ }
169
+ if (msg.includes('not found') || msg.includes('no pull requests found')) {
170
+ throw new GitForkError(`Upstream PR #${prNumber} not found in ${upstreamRepo}`, GitForkErrorCode.UPSTREAM_PR_NOT_FOUND, err instanceof Error ? err : undefined);
171
+ }
172
+ throw new GitForkError(`Failed to fetch upstream PR status: ${err.message}`, GitForkErrorCode.UPSTREAM_PR_NOT_FOUND, err instanceof Error ? err : undefined);
173
+ }
174
+ }
175
+ // ---------------------------------------------------------------------------
176
+ // Private helpers
177
+ // ---------------------------------------------------------------------------
178
+ /**
179
+ * Resolve the upstream repo as "owner/repo".
180
+ * 1. Try `git remote get-url upstream` and parse it.
181
+ * 2. Fall back to `gh repo view --json parent`.
182
+ */
183
+ async _getUpstreamRepo(cwd) {
184
+ try {
185
+ const { stdout } = await this.execFile('git', ['remote', 'get-url', 'upstream'], { cwd });
186
+ return parseOwnerRepo(stdout.trim());
187
+ }
188
+ catch {
189
+ // No upstream remote — try to infer from gh repo view parent.
190
+ const { stdout } = await this.execFile('gh', ['repo', 'view', '--json', 'parent'], { cwd });
191
+ const data = JSON.parse(stdout);
192
+ if (data.parent?.nameWithOwner) {
193
+ return data.parent.nameWithOwner;
194
+ }
195
+ throw new GitForkError('Cannot determine upstream repository. No upstream remote configured and repo has no parent.', GitForkErrorCode.UPSTREAM_PR_FAILED);
196
+ }
197
+ }
198
+ };
199
+ GitForkService = __decorate([
200
+ injectable(),
201
+ __param(0, inject('ExecFunction')),
202
+ __metadata("design:paramtypes", [Function])
203
+ ], GitForkService);
204
+ export { GitForkService };
@@ -3,7 +3,9 @@
3
3
  *
4
4
  * Polls GitHub PR status and CI status for features in the Review lifecycle
5
5
  * stage, updating feature records and emitting notifications when transitions
6
- * are detected. Follows the NotificationWatcherService polling pattern.
6
+ * are detected. Also polls features in the AwaitingUpstream lifecycle stage,
7
+ * delegating to PollUpstreamPrUseCase to check upstream fork PR status.
8
+ * Follows the NotificationWatcherService polling pattern.
7
9
  *
8
10
  * Maintains in-memory tracking of last-known PR and CI status per feature
9
11
  * to avoid duplicate updates and notifications. Features are grouped by
@@ -13,12 +15,18 @@ import type { IFeatureRepository } from '../../../application/ports/output/repos
13
15
  import type { IAgentRunRepository } from '../../../application/ports/output/agents/agent-run-repository.interface.js';
14
16
  import type { IGitPrService } from '../../../application/ports/output/services/git-pr-service.interface.js';
15
17
  import type { INotificationService } from '../../../application/ports/output/services/notification-service.interface.js';
18
+ import type { PollUpstreamPrInput, PollUpstreamPrOutput } from '../../../application/use-cases/features/poll-upstream-pr.use-case.js';
16
19
  import type Database from 'better-sqlite3';
20
+ /** Minimal interface satisfied by PollUpstreamPrUseCase */
21
+ interface IPollUpstreamPrUseCase {
22
+ execute(input: PollUpstreamPrInput): Promise<PollUpstreamPrOutput>;
23
+ }
17
24
  export declare class PrSyncWatcherService {
18
25
  private readonly featureRepo;
19
26
  private readonly agentRunRepo;
20
27
  private readonly gitPrService;
21
28
  private readonly notificationService;
29
+ private readonly pollUpstreamPrUseCase;
22
30
  private readonly pollIntervalMs;
23
31
  private readonly trackedFeatures;
24
32
  private readonly skippedRepos;
@@ -27,7 +35,7 @@ export declare class PrSyncWatcherService {
27
35
  private readonly processId;
28
36
  private intervalId;
29
37
  private pollCycle;
30
- constructor(featureRepo: IFeatureRepository, agentRunRepo: IAgentRunRepository, gitPrService: IGitPrService, notificationService: INotificationService, pollIntervalMs?: number, db?: Database.Database | null);
38
+ constructor(featureRepo: IFeatureRepository, agentRunRepo: IAgentRunRepository, gitPrService: IGitPrService, notificationService: INotificationService, pollIntervalMs?: number, db?: Database.Database | null, pollUpstreamPrUseCase?: IPollUpstreamPrUseCase | null);
31
39
  isRunning(): boolean;
32
40
  start(): void;
33
41
  stop(): void;
@@ -38,6 +46,7 @@ export declare class PrSyncWatcherService {
38
46
  private poll;
39
47
  private isRateLimited;
40
48
  private handleRateLimitError;
49
+ private processAwaitingUpstreamFeature;
41
50
  private processRepository;
42
51
  private processFeature;
43
52
  /** Mark associated agent run as completed so the UI reflects "done" state. */
@@ -50,7 +59,7 @@ export declare class PrSyncWatcherService {
50
59
  *
51
60
  * @throws Error if the watcher is already initialized
52
61
  */
53
- export declare function initializePrSyncWatcher(featureRepo: IFeatureRepository, agentRunRepo: IAgentRunRepository, gitPrService: IGitPrService, notificationService: INotificationService, pollIntervalMs?: number, db?: Database.Database | null): void;
62
+ export declare function initializePrSyncWatcher(featureRepo: IFeatureRepository, agentRunRepo: IAgentRunRepository, gitPrService: IGitPrService, notificationService: INotificationService, pollIntervalMs?: number, db?: Database.Database | null, pollUpstreamPrUseCase?: IPollUpstreamPrUseCase | null): void;
54
63
  /**
55
64
  * Get the PR sync watcher singleton.
56
65
  *
@@ -69,4 +78,5 @@ export declare function hasPrSyncWatcher(): boolean;
69
78
  * @internal
70
79
  */
71
80
  export declare function resetPrSyncWatcher(): void;
81
+ export {};
72
82
  //# sourceMappingURL=pr-sync-watcher.service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pr-sync-watcher.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gFAAgF,CAAC;AACzH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4EAA4E,CAAC;AACtH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wEAAwE,CAAC;AAK5G,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8EAA8E,CAAC;AACzH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAqB3C,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IACnD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;IAC7C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAuB;IAC3D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqC;IACrE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA6B;IAC9D,OAAO,CAAC,QAAQ,CAAC,EAAE,CAA2B;IAC9C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,SAAS,CAAK;gBAGpB,WAAW,EAAE,kBAAkB,EAC/B,YAAY,EAAE,mBAAmB,EACjC,YAAY,EAAE,aAAa,EAC3B,mBAAmB,EAAE,oBAAoB,EACzC,cAAc,GAAE,MAAiC,EACjD,EAAE,GAAE,QAAQ,CAAC,QAAQ,GAAG,IAAW;IAWrC,SAAS,IAAI,OAAO;IAIpB,KAAK,IAAI,IAAI;IAcb,IAAI,IAAI,IAAI;IASZ,gFAAgF;IAChF,OAAO,CAAC,cAAc;IAiBtB,0FAA0F;IAC1F,OAAO,CAAC,iBAAiB;YAUX,IAAI;IA6ClB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,oBAAoB;YAYd,iBAAiB;YA+CjB,cAAc;IAkM5B,8EAA8E;YAChE,gBAAgB;IAW9B,OAAO,CAAC,gBAAgB;CAoBzB;AAMD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,kBAAkB,EAC/B,YAAY,EAAE,mBAAmB,EACjC,YAAY,EAAE,aAAa,EAC3B,mBAAmB,EAAE,oBAAoB,EACzC,cAAc,CAAC,EAAE,MAAM,EACvB,EAAE,CAAC,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,GAC5B,IAAI,CAaN;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,oBAAoB,CAQvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAKzC"}
1
+ {"version":3,"file":"pr-sync-watcher.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAWH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gFAAgF,CAAC;AACzH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4EAA4E,CAAC;AACtH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wEAAwE,CAAC;AAK5G,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8EAA8E,CAAC;AACzH,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,sEAAsE,CAAC;AAC9E,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,2DAA2D;AAC3D,UAAU,sBAAsB;IAC9B,OAAO,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;CACpE;AAqBD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IACnD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;IAC7C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAuB;IAC3D,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAgC;IACtE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqC;IACrE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA6B;IAC9D,OAAO,CAAC,QAAQ,CAAC,EAAE,CAA2B;IAC9C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,SAAS,CAAK;gBAGpB,WAAW,EAAE,kBAAkB,EAC/B,YAAY,EAAE,mBAAmB,EACjC,YAAY,EAAE,aAAa,EAC3B,mBAAmB,EAAE,oBAAoB,EACzC,cAAc,GAAE,MAAiC,EACjD,EAAE,GAAE,QAAQ,CAAC,QAAQ,GAAG,IAAW,EACnC,qBAAqB,GAAE,sBAAsB,GAAG,IAAW;IAY7D,SAAS,IAAI,OAAO;IAIpB,KAAK,IAAI,IAAI;IAcb,IAAI,IAAI,IAAI;IASZ,gFAAgF;IAChF,OAAO,CAAC,cAAc;IAiBtB,0FAA0F;IAC1F,OAAO,CAAC,iBAAiB;YAUX,IAAI;IAyDlB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,oBAAoB;YAYd,8BAA8B;YAgB9B,iBAAiB;YA+CjB,cAAc;IAkM5B,8EAA8E;YAChE,gBAAgB;IAW9B,OAAO,CAAC,gBAAgB;CAoBzB;AAMD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,kBAAkB,EAC/B,YAAY,EAAE,mBAAmB,EACjC,YAAY,EAAE,aAAa,EAC3B,mBAAmB,EAAE,oBAAoB,EACzC,cAAc,CAAC,EAAE,MAAM,EACvB,EAAE,CAAC,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,EAC7B,qBAAqB,CAAC,EAAE,sBAAsB,GAAG,IAAI,GACpD,IAAI,CAcN;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,oBAAoB,CAQvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAKzC"}
@@ -3,7 +3,9 @@
3
3
  *
4
4
  * Polls GitHub PR status and CI status for features in the Review lifecycle
5
5
  * stage, updating feature records and emitting notifications when transitions
6
- * are detected. Follows the NotificationWatcherService polling pattern.
6
+ * are detected. Also polls features in the AwaitingUpstream lifecycle stage,
7
+ * delegating to PollUpstreamPrUseCase to check upstream fork PR status.
8
+ * Follows the NotificationWatcherService polling pattern.
7
9
  *
8
10
  * Maintains in-memory tracking of last-known PR and CI status per feature
9
11
  * to avoid duplicate updates and notifications. Features are grouped by
@@ -24,6 +26,7 @@ export class PrSyncWatcherService {
24
26
  agentRunRepo;
25
27
  gitPrService;
26
28
  notificationService;
29
+ pollUpstreamPrUseCase;
27
30
  pollIntervalMs;
28
31
  trackedFeatures = new Map();
29
32
  skippedRepos = new Set();
@@ -32,11 +35,12 @@ export class PrSyncWatcherService {
32
35
  processId;
33
36
  intervalId = null;
34
37
  pollCycle = 0;
35
- constructor(featureRepo, agentRunRepo, gitPrService, notificationService, pollIntervalMs = DEFAULT_POLL_INTERVAL_MS, db = null) {
38
+ constructor(featureRepo, agentRunRepo, gitPrService, notificationService, pollIntervalMs = DEFAULT_POLL_INTERVAL_MS, db = null, pollUpstreamPrUseCase = null) {
36
39
  this.featureRepo = featureRepo;
37
40
  this.agentRunRepo = agentRunRepo;
38
41
  this.gitPrService = gitPrService;
39
42
  this.notificationService = notificationService;
43
+ this.pollUpstreamPrUseCase = pollUpstreamPrUseCase;
40
44
  this.pollIntervalMs = pollIntervalMs;
41
45
  this.db = db;
42
46
  this.processId = `${process.pid}-${Date.now()}`;
@@ -97,25 +101,36 @@ export class PrSyncWatcherService {
97
101
  return; // another process holds the lock — skip this cycle
98
102
  }
99
103
  this.pollCycle++;
100
- const allFeatures = await this.featureRepo.list({ lifecycle: SdlcLifecycle.Review });
104
+ const [reviewFeaturesFull, awaitingFeaturesFull] = await Promise.all([
105
+ this.featureRepo.list({ lifecycle: SdlcLifecycle.Review }),
106
+ this.featureRepo.list({ lifecycle: SdlcLifecycle.AwaitingUpstream }),
107
+ ]);
101
108
  // Include features with a valid repositoryPath (with or without PR data)
102
- const features = allFeatures.filter((f) => f.repositoryPath);
109
+ const reviewFeatures = reviewFeaturesFull.filter((f) => f.repositoryPath);
110
+ const awaitingFeatures = awaitingFeaturesFull.filter((f) => f.repositoryPath);
111
+ const features = [...reviewFeatures, ...awaitingFeatures];
103
112
  if (features.length === 0) {
104
113
  this.trackedFeatures.clear();
105
114
  return;
106
115
  }
107
- // Group features by repositoryPath for batch queries
116
+ // Process AwaitingUpstream features via PollUpstreamPrUseCase
117
+ if (this.pollUpstreamPrUseCase) {
118
+ for (const feature of awaitingFeatures) {
119
+ await this.processAwaitingUpstreamFeature(feature);
120
+ }
121
+ }
122
+ // Group Review features by repositoryPath for batch queries
108
123
  const byRepo = new Map();
109
- for (const feature of features) {
124
+ for (const feature of reviewFeatures) {
110
125
  const group = byRepo.get(feature.repositoryPath) ?? [];
111
126
  group.push(feature);
112
127
  byRepo.set(feature.repositoryPath, group);
113
128
  }
114
- // Process each repository
129
+ // Process each repository (Review lifecycle)
115
130
  for (const [repoPath, repoFeatures] of byRepo) {
116
131
  await this.processRepository(repoPath, repoFeatures);
117
132
  }
118
- // Prune features no longer in Review
133
+ // Prune features no longer in Review or AwaitingUpstream
119
134
  const currentFeatureIds = new Set(features.map((f) => f.id));
120
135
  for (const trackedId of this.trackedFeatures.keys()) {
121
136
  if (!currentFeatureIds.has(trackedId)) {
@@ -150,6 +165,20 @@ export class PrSyncWatcherService {
150
165
  console.warn(`${TAG} Rate limited for ${repoPath}, backing off until ${new Date(backoffUntil).toISOString()}`);
151
166
  }
152
167
  }
168
+ async processAwaitingUpstreamFeature(feature) {
169
+ if (!this.pollUpstreamPrUseCase)
170
+ return;
171
+ try {
172
+ const result = await this.pollUpstreamPrUseCase.execute({ featureId: feature.id });
173
+ // eslint-disable-next-line no-console
174
+ console.log(`${TAG} AwaitingUpstream poll for "${feature.name}": status=${result.status} transitioned=${result.transitioned}`);
175
+ }
176
+ catch (error) {
177
+ const msg = error instanceof Error ? error.message : String(error);
178
+ // eslint-disable-next-line no-console
179
+ console.warn(`${TAG} PollUpstreamPrUseCase failed for "${feature.name}": ${msg}`);
180
+ }
181
+ }
153
182
  async processRepository(repoPath, features) {
154
183
  if (this.skippedRepos.has(repoPath))
155
184
  return;
@@ -353,11 +382,11 @@ let watcherInstance = null;
353
382
  *
354
383
  * @throws Error if the watcher is already initialized
355
384
  */
356
- export function initializePrSyncWatcher(featureRepo, agentRunRepo, gitPrService, notificationService, pollIntervalMs, db) {
385
+ export function initializePrSyncWatcher(featureRepo, agentRunRepo, gitPrService, notificationService, pollIntervalMs, db, pollUpstreamPrUseCase) {
357
386
  if (watcherInstance !== null) {
358
387
  throw new Error('PR sync watcher already initialized. Cannot re-initialize.');
359
388
  }
360
- watcherInstance = new PrSyncWatcherService(featureRepo, agentRunRepo, gitPrService, notificationService, pollIntervalMs, db ?? null);
389
+ watcherInstance = new PrSyncWatcherService(featureRepo, agentRunRepo, gitPrService, notificationService, pollIntervalMs, db ?? null, pollUpstreamPrUseCase ?? null);
361
390
  }
362
391
  /**
363
392
  * Get the PR sync watcher singleton.
@@ -1 +1 @@
1
- {"version":3,"file":"ui.command.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/cli/commands/ui.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,OAAO,EAAwB,MAAM,WAAW,CAAC;AAgC1D;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CA0FzC"}
1
+ {"version":3,"file":"ui.command.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/cli/commands/ui.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,OAAO,EAAwB,MAAM,WAAW,CAAC;AAiC1D;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CA4FzC"}
@@ -22,6 +22,7 @@ import { resolveWebDir } from '../../../../packages/core/src/infrastructure/serv
22
22
  import { initializeNotificationWatcher, getNotificationWatcher, } from '../../../../packages/core/src/infrastructure/services/notifications/notification-watcher.service.js';
23
23
  import { initializePrSyncWatcher, getPrSyncWatcher, } from '../../../../packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.js';
24
24
  import { getExistingConnection } from '../../../../packages/core/src/infrastructure/persistence/sqlite/connection.js';
25
+ import { PollUpstreamPrUseCase } from '../../../../packages/core/src/application/use-cases/features/poll-upstream-pr.use-case.js';
25
26
  import { BrowserOpenerService } from '../../../../packages/core/src/infrastructure/services/browser-opener.service.js';
26
27
  import { colors, fmt, messages } from '../ui/index.js';
27
28
  function parsePort(value) {
@@ -68,7 +69,8 @@ Examples:
68
69
  // Start PR sync watcher to detect PR/CI status transitions on GitHub
69
70
  const gitPrService = container.resolve('IGitPrService');
70
71
  const db = getExistingConnection();
71
- initializePrSyncWatcher(featureRepo, runRepo, gitPrService, notificationService, undefined, db);
72
+ const pollUpstreamPrUseCase = container.resolve(PollUpstreamPrUseCase);
73
+ initializePrSyncWatcher(featureRepo, runRepo, gitPrService, notificationService, undefined, db, pollUpstreamPrUseCase);
72
74
  getPrSyncWatcher().start();
73
75
  const url = `http://localhost:${port}`;
74
76
  messages.success(`Server ready at ${fmt.code(url)}`);
@@ -15,6 +15,8 @@ interface CreateFeatureInput {
15
15
  };
16
16
  push?: boolean;
17
17
  openPr?: boolean;
18
+ forkAndPr?: boolean;
19
+ commitSpecs?: boolean;
18
20
  parentId?: string;
19
21
  /** When true, skip SDLC phases and implement directly from the prompt. */
20
22
  fast?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"create-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/create-feature.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAC;AAGpE,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAQD,UAAU,kBAAkB;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE;QACd,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,OAAO,CAAC;QACnB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA+EhD"}
1
+ {"version":3,"file":"create-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/create-feature.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAC;AAGpE,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAQD,UAAU,kBAAkB;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE;QACd,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,OAAO,CAAC;QACnB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAqFhD"}
@@ -2,7 +2,7 @@
2
2
  import { resolve } from '../../lib/server-container.js';
3
3
  import { composeUserInput } from './compose-user-input.js';
4
4
  export async function createFeature(input) {
5
- const { description, repositoryPath, attachments, sessionId, approvalGates, push, openPr, parentId, fast, pending, agentType, model, } = input;
5
+ const { description, repositoryPath, attachments, sessionId, approvalGates, push, openPr, forkAndPr, commitSpecs, parentId, fast, pending, agentType, model, } = input;
6
6
  if (!description?.trim()) {
7
7
  return { error: 'description is required' };
8
8
  }
@@ -24,6 +24,8 @@ export async function createFeature(input) {
24
24
  approvalGates: gates,
25
25
  push: push ?? false,
26
26
  openPr: openPr ?? false,
27
+ ...(forkAndPr ? { forkAndPr } : {}),
28
+ ...(commitSpecs !== undefined ? { commitSpecs } : {}),
27
29
  ...(parentId ? { parentId } : {}),
28
30
  description,
29
31
  ...(fast ? { fast } : {}),
@@ -40,6 +42,8 @@ export async function createFeature(input) {
40
42
  approvalGates: gates,
41
43
  push: push ?? false,
42
44
  openPr: openPr ?? false,
45
+ ...(forkAndPr ? { forkAndPr } : {}),
46
+ ...(commitSpecs !== undefined ? { commitSpecs } : {}),
43
47
  ...(parentId ? { parentId } : {}),
44
48
  ...(fast ? { fast } : {}),
45
49
  ...(pending ? { pending } : {}),
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/app/api/agent-events/route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAiBH,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAuEvC,wBAAgB,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,CA4R9C"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/app/api/agent-events/route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAiBH,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAwEvC,wBAAgB,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,CA4R9C"}
@@ -37,6 +37,7 @@ const LIFECYCLE_TO_NODE = {
37
37
  [SdlcLifecycle.Pending]: 'pending',
38
38
  [SdlcLifecycle.Deleting]: 'blocked',
39
39
  [SdlcLifecycle.Archived]: 'archived',
40
+ [SdlcLifecycle.AwaitingUpstream]: 'merge',
40
41
  };
41
42
  const STATUS_TO_EVENT = {
42
43
  [AgentRunStatus.running]: {
@@ -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;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
+ {"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;AAM3C,eAAO,MAAM,OAAO,kBAAkB,CAAC;AA2VvC;;;;;GAKG;AACH,wBAAsB,GAAG,CAAC,OAAO,EAAE,OAAO;;;;YA9VpC,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;;IAoXjB"}
@@ -1,4 +1,5 @@
1
1
  import { NextResponse } from 'next/server';
2
+ import { createHash } from 'node:crypto';
2
3
  import { homedir } from 'node:os';
3
4
  import { join } from 'node:path';
4
5
  import { readdir, stat } from 'node:fs/promises';
@@ -20,28 +21,58 @@ function cursorEncodePath(p) {
20
21
  return p.replace(/^\//, '').replace(/\./g, '').replace(/[/\\]/g, '-');
21
22
  }
22
23
  // ── Claude Code session scanner ───────────────────────────────────────
23
- async function scanClaudeSessions(repositoryPath, limit) {
24
- const dirName = claudeEncodePath(repositoryPath);
25
- const projectDir = join(homedir(), '.claude', 'projects', dirName);
26
- let files;
24
+ /**
25
+ * Collect .jsonl session files from a single Claude project directory.
26
+ */
27
+ async function collectJsonlFiles(projectDir) {
28
+ let entries;
27
29
  try {
28
- const entries = await readdir(projectDir);
29
- files = entries.filter((e) => e.endsWith('.jsonl'));
30
+ entries = await readdir(projectDir);
30
31
  }
31
32
  catch {
32
33
  return [];
33
34
  }
34
- // Stat all files for mtime sorting
35
- const fileInfos = await Promise.allSettled(files.map(async (name) => {
35
+ const jsonlFiles = entries.filter((e) => e.endsWith('.jsonl'));
36
+ const fileInfos = await Promise.allSettled(jsonlFiles.map(async (name) => {
36
37
  const filePath = join(projectDir, name);
37
38
  const s = await stat(filePath);
38
39
  return { name, filePath, mtime: s.mtime.getTime() };
39
40
  }));
40
- const valid = fileInfos
41
+ return fileInfos
41
42
  .filter((r) => r.status === 'fulfilled')
42
- .map((r) => r.value)
43
- .sort((a, b) => b.mtime - a.mtime)
44
- .slice(0, limit);
43
+ .map((r) => r.value);
44
+ }
45
+ async function scanClaudeSessions(repositoryPath, limit, includeWorktrees = false) {
46
+ const dirName = claudeEncodePath(repositoryPath);
47
+ const projectsRoot = join(homedir(), '.claude', 'projects');
48
+ // Collect files from the exact directory
49
+ const primaryDir = join(projectsRoot, dirName);
50
+ let allFiles = await collectJsonlFiles(primaryDir);
51
+ // When includeWorktrees is set, also scan:
52
+ // 1. Directories whose name starts with the encoded repo path (git worktrees, .worktrees)
53
+ // 2. Shep worktree directories (~/.shep/repos/<hash>/wt/*) which use a hash of the repo path
54
+ if (includeWorktrees) {
55
+ try {
56
+ const allDirs = await readdir(projectsRoot);
57
+ // Match git-style worktrees (same prefix as repo path)
58
+ const prefixMatches = allDirs.filter((d) => d !== dirName && d.startsWith(dirName));
59
+ // Match shep worktrees: compute repo hash → find dirs starting with encoded shep path
60
+ const normalizedRepoPath = repositoryPath.replace(/\\/g, '/');
61
+ const repoHash = createHash('sha256').update(normalizedRepoPath).digest('hex').slice(0, 16);
62
+ const shepHome = join(homedir(), '.shep').replace(/\\/g, '/');
63
+ const shepWorktreePrefix = claudeEncodePath(join(shepHome, 'repos', repoHash));
64
+ const shepMatches = allDirs.filter((d) => d.startsWith(shepWorktreePrefix) && !prefixMatches.includes(d) && d !== dirName);
65
+ const worktreeDirs = [...prefixMatches, ...shepMatches];
66
+ const worktreeResults = await Promise.all(worktreeDirs.map((d) => collectJsonlFiles(join(projectsRoot, d))));
67
+ for (const files of worktreeResults) {
68
+ allFiles = allFiles.concat(files);
69
+ }
70
+ }
71
+ catch {
72
+ // projectsRoot doesn't exist — no sessions at all
73
+ }
74
+ }
75
+ const valid = allFiles.sort((a, b) => b.mtime - a.mtime).slice(0, limit);
45
76
  // Parse each file
46
77
  const results = await Promise.allSettled(valid.map(async (fi) => parseClaudeSession(fi.filePath, fi.name, fi.mtime, repositoryPath)));
47
78
  return results
@@ -238,13 +269,14 @@ export async function GET(request) {
238
269
  const url = new URL(request.url);
239
270
  const repositoryPath = url.searchParams.get('repositoryPath');
240
271
  const limit = parseInt(url.searchParams.get('limit') ?? '10', 10);
272
+ const includeWorktrees = url.searchParams.get('includeWorktrees') === 'true';
241
273
  if (!repositoryPath?.trim()) {
242
274
  return NextResponse.json({ error: 'repositoryPath is required' }, { status: 400 });
243
275
  }
244
276
  try {
245
277
  // Scan all providers in parallel
246
278
  const [claudeSessions, cursorSessions] = await Promise.all([
247
- scanClaudeSessions(repositoryPath, limit),
279
+ scanClaudeSessions(repositoryPath, limit, includeWorktrees),
248
280
  scanCursorSessions(repositoryPath, limit),
249
281
  ]);
250
282
  // Merge and sort by mtime descending, apply limit
@@ -34,6 +34,8 @@ export interface FeatureCreatePayload {
34
34
  ciWatchEnabled: boolean;
35
35
  enableEvidence: boolean;
36
36
  commitEvidence: boolean;
37
+ forkAndPr: boolean;
38
+ commitSpecs: boolean;
37
39
  parentId?: string;
38
40
  /** When true, skip SDLC phases and implement directly from the prompt. */
39
41
  fast: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"feature-create-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAS5E,YAAY,EAAE,cAAc,EAAE,MAAM,0DAA0D,CAAC;AAE/F,uFAAuF;AACvF,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,0DAA0D;AAC1D,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,iEAAiE;AACjE,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE;QACb,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,OAAO,CAAC;QACnB,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC;IACF,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,IAAI,EAAE,OAAO,CAAC;IACd,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA+ED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC/C,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACjC,+EAA+E;IAC/E,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAClC,kGAAkG;IAClG,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8CAA8C;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yCAAyC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,cAAc,EACd,YAAoB,EACpB,gBAAgB,EAChB,QAAQ,EACR,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,GACnB,EAAE,wBAAwB,2CAwzB1B;AAmJD,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAC7C,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACnD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,kBAAkB,CAAC,EACjC,YAAY,EACZ,KAAK,EACL,QAAQ,EACR,eAAe,EACf,QAAQ,GACT,EAAE,uBAAuB,2CAiNzB"}
1
+ {"version":3,"file":"feature-create-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx"],"names":[],"mappings":"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"}