@shepai/cli 1.116.3 → 1.117.0-pr367.ca5b6ac

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 (460) hide show
  1. package/apis/json-schema/AnalyzeRepoTimeouts.yaml +10 -0
  2. package/apis/json-schema/SdlcLifecycle.yaml +1 -0
  3. package/apis/json-schema/StageTimeouts.yaml +35 -0
  4. package/apis/json-schema/WorkflowConfig.yaml +6 -0
  5. package/dist/packages/core/src/application/ports/output/services/index.d.ts +2 -0
  6. package/dist/packages/core/src/application/ports/output/services/index.d.ts.map +1 -1
  7. package/dist/packages/core/src/application/ports/output/services/tunnel-service.interface.d.ts +41 -0
  8. package/dist/packages/core/src/application/ports/output/services/tunnel-service.interface.d.ts.map +1 -0
  9. package/dist/packages/core/src/application/ports/output/services/tunnel-service.interface.js +14 -0
  10. package/dist/packages/core/src/application/ports/output/services/webhook-service.interface.d.ts +65 -0
  11. package/dist/packages/core/src/application/ports/output/services/webhook-service.interface.d.ts.map +1 -0
  12. package/dist/packages/core/src/application/ports/output/services/webhook-service.interface.js +10 -0
  13. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
  14. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +17 -8
  15. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts +2 -0
  16. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts.map +1 -1
  17. package/dist/packages/core/src/application/use-cases/features/start-feature.use-case.d.ts +25 -0
  18. package/dist/packages/core/src/application/use-cases/features/start-feature.use-case.d.ts.map +1 -0
  19. package/dist/packages/core/src/application/use-cases/features/start-feature.use-case.js +116 -0
  20. package/dist/packages/core/src/domain/generated/output.d.ts +47 -0
  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/domain/lifecycle-gates.d.ts +3 -0
  24. package/dist/packages/core/src/domain/lifecycle-gates.d.ts.map +1 -1
  25. package/dist/packages/core/src/domain/lifecycle-gates.js +3 -0
  26. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  27. package/dist/packages/core/src/infrastructure/di/container.js +19 -0
  28. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts +7 -0
  29. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -1
  30. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.js +44 -0
  31. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/035-add-stage-timeout-ms.d.ts +22 -0
  32. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/035-add-stage-timeout-ms.d.ts.map +1 -0
  33. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/035-add-stage-timeout-ms.js +53 -0
  34. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.d.ts.map +1 -1
  35. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.js +15 -6
  36. package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.d.ts.map +1 -1
  37. package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.js +15 -0
  38. package/dist/packages/core/src/infrastructure/services/agents/analyze-repo/analyze-repository-graph.d.ts.map +1 -1
  39. package/dist/packages/core/src/infrastructure/services/agents/analyze-repo/analyze-repository-graph.js +15 -0
  40. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts +11 -1
  41. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts.map +1 -1
  42. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.js +42 -3
  43. package/dist/packages/core/src/infrastructure/services/tunnel/cloudflare-tunnel.service.d.ts +55 -0
  44. package/dist/packages/core/src/infrastructure/services/tunnel/cloudflare-tunnel.service.d.ts.map +1 -0
  45. package/dist/packages/core/src/infrastructure/services/tunnel/cloudflare-tunnel.service.js +203 -0
  46. package/dist/packages/core/src/infrastructure/services/webhook/github-webhook.service.d.ts +75 -0
  47. package/dist/packages/core/src/infrastructure/services/webhook/github-webhook.service.d.ts.map +1 -0
  48. package/dist/packages/core/src/infrastructure/services/webhook/github-webhook.service.js +372 -0
  49. package/dist/packages/core/src/infrastructure/services/webhook/webhook-manager.service.d.ts +82 -0
  50. package/dist/packages/core/src/infrastructure/services/webhook/webhook-manager.service.d.ts.map +1 -0
  51. package/dist/packages/core/src/infrastructure/services/webhook/webhook-manager.service.js +206 -0
  52. package/dist/src/presentation/cli/commands/feat/index.d.ts.map +1 -1
  53. package/dist/src/presentation/cli/commands/feat/index.js +2 -0
  54. package/dist/src/presentation/cli/commands/feat/ls.command.d.ts.map +1 -1
  55. package/dist/src/presentation/cli/commands/feat/ls.command.js +3 -0
  56. package/dist/src/presentation/cli/commands/feat/new.command.d.ts.map +1 -1
  57. package/dist/src/presentation/cli/commands/feat/new.command.js +9 -1
  58. package/dist/src/presentation/cli/commands/feat/start.command.d.ts +12 -0
  59. package/dist/src/presentation/cli/commands/feat/start.command.d.ts.map +1 -0
  60. package/dist/src/presentation/cli/commands/feat/start.command.js +43 -0
  61. package/dist/src/presentation/cli/commands/ui.command.d.ts.map +1 -1
  62. package/dist/src/presentation/cli/commands/ui.command.js +15 -0
  63. package/dist/src/presentation/web/app/actions/create-feature.d.ts +2 -0
  64. package/dist/src/presentation/web/app/actions/create-feature.d.ts.map +1 -1
  65. package/dist/src/presentation/web/app/actions/create-feature.js +3 -1
  66. package/dist/src/presentation/web/app/actions/load-webhook-status.d.ts +3 -0
  67. package/dist/src/presentation/web/app/actions/load-webhook-status.d.ts.map +1 -0
  68. package/dist/src/presentation/web/app/actions/load-webhook-status.js +19 -0
  69. package/dist/src/presentation/web/app/actions/start-feature.d.ts +5 -0
  70. package/dist/src/presentation/web/app/actions/start-feature.d.ts.map +1 -0
  71. package/dist/src/presentation/web/app/actions/start-feature.js +16 -0
  72. package/dist/src/presentation/web/app/api/agent-events/route.d.ts.map +1 -1
  73. package/dist/src/presentation/web/app/api/agent-events/route.js +1 -0
  74. package/dist/src/presentation/web/app/api/webhooks/deliveries/route.d.ts +9 -0
  75. package/dist/src/presentation/web/app/api/webhooks/deliveries/route.d.ts.map +1 -0
  76. package/dist/src/presentation/web/app/api/webhooks/deliveries/route.js +27 -0
  77. package/dist/src/presentation/web/app/api/webhooks/github/route.d.ts +17 -0
  78. package/dist/src/presentation/web/app/api/webhooks/github/route.d.ts.map +1 -0
  79. package/dist/src/presentation/web/app/api/webhooks/github/route.js +70 -0
  80. package/dist/src/presentation/web/app/api/webhooks/status/route.d.ts +9 -0
  81. package/dist/src/presentation/web/app/api/webhooks/status/route.d.ts.map +1 -0
  82. package/dist/src/presentation/web/app/api/webhooks/status/route.js +26 -0
  83. package/dist/src/presentation/web/app/webhooks/page.d.ts +4 -0
  84. package/dist/src/presentation/web/app/webhooks/page.d.ts.map +1 -0
  85. package/dist/src/presentation/web/app/webhooks/page.js +9 -0
  86. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.js +1 -1
  87. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.stories.js +1 -1
  88. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
  89. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +20 -1
  90. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts +2 -0
  91. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  92. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +6 -2
  93. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.d.ts.map +1 -1
  94. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.js +6 -0
  95. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +3 -2
  96. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +1 -1
  97. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.js +13 -1
  98. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  99. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +12 -3
  100. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts +2 -0
  101. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts.map +1 -1
  102. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.js +36 -2
  103. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  104. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +3 -1
  105. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +1 -0
  106. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  107. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +23 -0
  108. package/dist/src/presentation/web/components/features/settings/settings-page-client.d.ts.map +1 -1
  109. package/dist/src/presentation/web/components/features/settings/settings-page-client.js +75 -2
  110. package/dist/src/presentation/web/components/features/settings/settings-page-client.stories.d.ts +1 -0
  111. package/dist/src/presentation/web/components/features/settings/settings-page-client.stories.d.ts.map +1 -1
  112. package/dist/src/presentation/web/components/features/settings/settings-page-client.stories.js +23 -0
  113. package/dist/src/presentation/web/components/features/settings/timeout-slider.d.ts +11 -0
  114. package/dist/src/presentation/web/components/features/settings/timeout-slider.d.ts.map +1 -0
  115. package/dist/src/presentation/web/components/features/settings/timeout-slider.js +63 -0
  116. package/dist/src/presentation/web/components/features/settings/timeout-slider.stories.d.ts +10 -0
  117. package/dist/src/presentation/web/components/features/settings/timeout-slider.stories.d.ts.map +1 -0
  118. package/dist/src/presentation/web/components/features/settings/timeout-slider.stories.js +24 -0
  119. package/dist/src/presentation/web/components/features/settings/workflow-settings-section.d.ts.map +1 -1
  120. package/dist/src/presentation/web/components/features/settings/workflow-settings-section.js +97 -2
  121. package/dist/src/presentation/web/components/features/settings/workflow-settings-section.stories.d.ts.map +1 -1
  122. package/dist/src/presentation/web/components/features/settings/workflow-settings-section.stories.js +22 -0
  123. package/dist/src/presentation/web/components/features/webhooks/types.d.ts +32 -0
  124. package/dist/src/presentation/web/components/features/webhooks/types.d.ts.map +1 -0
  125. package/dist/src/presentation/web/components/features/webhooks/types.js +1 -0
  126. package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.d.ts +6 -0
  127. package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.d.ts.map +1 -0
  128. package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.js +38 -0
  129. package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.stories.d.ts +9 -0
  130. package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.stories.d.ts.map +1 -0
  131. package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.stories.js +69 -0
  132. package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.d.ts +7 -0
  133. package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.d.ts.map +1 -0
  134. package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.js +11 -0
  135. package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.stories.d.ts +9 -0
  136. package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.stories.d.ts.map +1 -0
  137. package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.stories.js +31 -0
  138. package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.d.ts +6 -0
  139. package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.d.ts.map +1 -0
  140. package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.js +21 -0
  141. package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.stories.d.ts +9 -0
  142. package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.stories.d.ts.map +1 -0
  143. package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.stories.js +56 -0
  144. package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.d.ts +6 -0
  145. package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.d.ts.map +1 -0
  146. package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.js +39 -0
  147. package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.stories.d.ts +8 -0
  148. package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.stories.d.ts.map +1 -0
  149. package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.stories.js +59 -0
  150. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.d.ts.map +1 -1
  151. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.js +2 -2
  152. package/dist/src/presentation/web/components/ui/slider.d.ts +5 -0
  153. package/dist/src/presentation/web/components/ui/slider.d.ts.map +1 -0
  154. package/dist/src/presentation/web/components/ui/slider.js +10 -0
  155. package/dist/src/presentation/web/components/ui/slider.stories.d.ts +7 -0
  156. package/dist/src/presentation/web/components/ui/slider.stories.d.ts.map +1 -0
  157. package/dist/src/presentation/web/components/ui/slider.stories.js +15 -0
  158. package/dist/src/presentation/web/dev-server.js +20 -0
  159. package/dist/src/presentation/web/hooks/sidebar-features-context.d.ts.map +1 -1
  160. package/dist/src/presentation/web/hooks/sidebar-features-context.js +1 -0
  161. package/dist/src/presentation/web/hooks/use-graph-state.d.ts.map +1 -1
  162. package/dist/src/presentation/web/hooks/use-graph-state.js +1 -0
  163. package/dist/src/presentation/web/lib/derive-graph.d.ts +2 -0
  164. package/dist/src/presentation/web/lib/derive-graph.d.ts.map +1 -1
  165. package/dist/src/presentation/web/lib/derive-graph.js +5 -0
  166. package/dist/tsconfig.build.tsbuildinfo +1 -1
  167. package/package.json +3 -1
  168. package/web/.next/BUILD_ID +1 -1
  169. package/web/.next/app-path-routes-manifest.json +5 -1
  170. package/web/.next/build-manifest.json +6 -6
  171. package/web/.next/fallback-build-manifest.json +2 -2
  172. package/web/.next/prerender-manifest.json +3 -3
  173. package/web/.next/required-server-files.js +3 -3
  174. package/web/.next/required-server-files.json +3 -3
  175. package/web/.next/routes-manifest.json +24 -0
  176. package/web/.next/server/app/(dashboard)/@drawer/create/page/build-manifest.json +4 -4
  177. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +55 -40
  178. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
  179. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  180. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  181. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/build-manifest.json +4 -4
  182. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +67 -52
  183. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +1 -1
  184. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  185. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  186. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/build-manifest.json +4 -4
  187. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +67 -52
  188. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
  189. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  190. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  191. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/build-manifest.json +4 -4
  192. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +51 -36
  193. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
  194. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  195. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  196. package/web/.next/server/app/(dashboard)/create/page/build-manifest.json +4 -4
  197. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +55 -40
  198. package/web/.next/server/app/(dashboard)/create/page.js +1 -1
  199. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  200. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  201. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/build-manifest.json +4 -4
  202. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +67 -52
  203. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +1 -1
  204. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  205. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  206. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/build-manifest.json +4 -4
  207. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +67 -52
  208. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
  209. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  210. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  211. package/web/.next/server/app/(dashboard)/page/build-manifest.json +4 -4
  212. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +51 -36
  213. package/web/.next/server/app/(dashboard)/page.js +1 -1
  214. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  215. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  216. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/build-manifest.json +4 -4
  217. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +51 -36
  218. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
  219. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  220. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  221. package/web/.next/server/app/_global-error/page/build-manifest.json +4 -4
  222. package/web/.next/server/app/_global-error.html +2 -2
  223. package/web/.next/server/app/_global-error.rsc +1 -1
  224. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  225. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  226. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  227. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  228. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  229. package/web/.next/server/app/_not-found/page/build-manifest.json +4 -4
  230. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  231. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  232. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  233. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  234. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  235. package/web/.next/server/app/api/webhooks/deliveries/route/app-paths-manifest.json +3 -0
  236. package/web/.next/server/app/api/webhooks/deliveries/route/build-manifest.json +11 -0
  237. package/web/.next/server/app/api/webhooks/deliveries/route/server-reference-manifest.json +4 -0
  238. package/web/.next/server/app/api/webhooks/deliveries/route.js +6 -0
  239. package/web/.next/server/app/api/webhooks/deliveries/route.js.map +5 -0
  240. package/web/.next/server/app/api/webhooks/deliveries/route.js.nft.json +1 -0
  241. package/web/.next/server/app/api/webhooks/deliveries/route_client-reference-manifest.js +2 -0
  242. package/web/.next/server/app/api/webhooks/github/route/app-paths-manifest.json +3 -0
  243. package/web/.next/server/app/api/webhooks/github/route/build-manifest.json +11 -0
  244. package/web/.next/server/app/api/webhooks/github/route/server-reference-manifest.json +4 -0
  245. package/web/.next/server/app/api/webhooks/github/route.js +6 -0
  246. package/web/.next/server/app/api/webhooks/github/route.js.map +5 -0
  247. package/web/.next/server/app/api/webhooks/github/route.js.nft.json +1 -0
  248. package/web/.next/server/app/api/webhooks/github/route_client-reference-manifest.js +2 -0
  249. package/web/.next/server/app/api/webhooks/status/route/app-paths-manifest.json +3 -0
  250. package/web/.next/server/app/api/webhooks/status/route/build-manifest.json +11 -0
  251. package/web/.next/server/app/api/webhooks/status/route/server-reference-manifest.json +4 -0
  252. package/web/.next/server/app/api/webhooks/status/route.js +6 -0
  253. package/web/.next/server/app/api/webhooks/status/route.js.map +5 -0
  254. package/web/.next/server/app/api/webhooks/status/route.js.nft.json +1 -0
  255. package/web/.next/server/app/api/webhooks/status/route_client-reference-manifest.js +2 -0
  256. package/web/.next/server/app/settings/page/build-manifest.json +4 -4
  257. package/web/.next/server/app/settings/page/server-reference-manifest.json +5 -5
  258. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  259. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  260. package/web/.next/server/app/skills/page/build-manifest.json +4 -4
  261. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  262. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  263. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  264. package/web/.next/server/app/tools/page/build-manifest.json +4 -4
  265. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  266. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  267. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  268. package/web/.next/server/app/version/page/build-manifest.json +4 -4
  269. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  270. package/web/.next/server/app/version/page.js.nft.json +1 -1
  271. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  272. package/web/.next/server/app/webhooks/page/app-paths-manifest.json +3 -0
  273. package/web/.next/server/app/webhooks/page/build-manifest.json +18 -0
  274. package/web/.next/server/app/webhooks/page/next-font-manifest.json +6 -0
  275. package/web/.next/server/app/webhooks/page/react-loadable-manifest.json +1 -0
  276. package/web/.next/server/app/webhooks/page/server-reference-manifest.json +35 -0
  277. package/web/.next/server/app/webhooks/page.js +16 -0
  278. package/web/.next/server/app/webhooks/page.js.map +5 -0
  279. package/web/.next/server/app/webhooks/page.js.nft.json +1 -0
  280. package/web/.next/server/app/webhooks/page_client-reference-manifest.js +2 -0
  281. package/web/.next/server/app-paths-manifest.json +5 -1
  282. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +1 -1
  283. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +1 -1
  284. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js +2 -2
  285. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js.map +1 -1
  286. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_deliveries_route_actions_d9e34c8d.js +3 -0
  287. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_deliveries_route_actions_d9e34c8d.js.map +1 -0
  288. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_github_route_actions_1b0d0c38.js +3 -0
  289. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_github_route_actions_1b0d0c38.js.map +1 -0
  290. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_status_route_actions_1a0d86a1.js +3 -0
  291. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_status_route_actions_1a0d86a1.js.map +1 -0
  292. package/web/.next/server/chunks/[root-of-the-server]__15e5d45c._.js +3 -0
  293. package/web/.next/server/chunks/[root-of-the-server]__15e5d45c._.js.map +1 -0
  294. package/web/.next/server/chunks/[root-of-the-server]__23be381e._.js +3 -0
  295. package/web/.next/server/chunks/[root-of-the-server]__23be381e._.js.map +1 -0
  296. package/web/.next/server/chunks/[root-of-the-server]__7d5492a0._.js +1 -1
  297. package/web/.next/server/chunks/[root-of-the-server]__7d5492a0._.js.map +1 -1
  298. package/web/.next/server/chunks/[root-of-the-server]__9fc760c0._.js +3 -0
  299. package/web/.next/server/chunks/[root-of-the-server]__9fc760c0._.js.map +1 -0
  300. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  301. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js +1 -1
  302. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js.map +1 -1
  303. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  304. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  305. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_activity_22f9667f.js +3 -0
  306. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_activity_22f9667f.js.map +1 -0
  307. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_ed372306.js +3 -0
  308. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_ed372306.js.map +1 -0
  309. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_32e26434.js +3 -0
  310. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_32e26434.js.map +1 -0
  311. package/web/.next/server/chunks/ssr/[root-of-the-server]__07a39ff2._.js +1 -1
  312. package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js +1 -1
  313. package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js.map +1 -1
  314. package/web/.next/server/chunks/ssr/{[root-of-the-server]__cbd8062c._.js → [root-of-the-server]__172d9576._.js} +2 -2
  315. package/web/.next/server/chunks/ssr/{[root-of-the-server]__e70c5627._.js.map → [root-of-the-server]__172d9576._.js.map} +1 -1
  316. package/web/.next/server/chunks/ssr/[root-of-the-server]__24dd0927._.js +2 -2
  317. package/web/.next/server/chunks/ssr/[root-of-the-server]__24dd0927._.js.map +1 -1
  318. package/web/.next/server/chunks/ssr/{[root-of-the-server]__039967e3._.js → [root-of-the-server]__2a5592d5._.js} +2 -2
  319. package/web/.next/server/chunks/ssr/{[root-of-the-server]__cbd8062c._.js.map → [root-of-the-server]__2a5592d5._.js.map} +1 -1
  320. package/web/.next/server/chunks/ssr/[root-of-the-server]__5d847b7b._.js +3 -0
  321. package/web/.next/server/chunks/ssr/[root-of-the-server]__5d847b7b._.js.map +1 -0
  322. package/web/.next/server/chunks/ssr/[root-of-the-server]__5d87af2e._.js +1 -1
  323. package/web/.next/server/chunks/ssr/[root-of-the-server]__87a7ae30._.js +3 -0
  324. package/web/.next/server/chunks/ssr/[root-of-the-server]__87a7ae30._.js.map +1 -0
  325. package/web/.next/server/chunks/ssr/[root-of-the-server]__89e8a5cc._.js +2 -2
  326. package/web/.next/server/chunks/ssr/[root-of-the-server]__89e8a5cc._.js.map +1 -1
  327. package/web/.next/server/chunks/ssr/[root-of-the-server]__920dccd5._.js +4 -0
  328. package/web/.next/server/chunks/ssr/[root-of-the-server]__920dccd5._.js.map +1 -0
  329. package/web/.next/server/chunks/ssr/[root-of-the-server]__a42f5a88._.js +3 -0
  330. package/web/.next/server/chunks/ssr/[root-of-the-server]__a42f5a88._.js.map +1 -0
  331. package/web/.next/server/chunks/ssr/{[root-of-the-server]__e70c5627._.js → [root-of-the-server]__a93289b0._.js} +2 -2
  332. package/web/.next/server/chunks/ssr/{[root-of-the-server]__2773312c._.js.map → [root-of-the-server]__a93289b0._.js.map} +1 -1
  333. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +2 -2
  334. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
  335. package/web/.next/server/chunks/ssr/{[root-of-the-server]__2773312c._.js → [root-of-the-server]__ac0304e7._.js} +2 -2
  336. package/web/.next/server/chunks/ssr/{[root-of-the-server]__039967e3._.js.map → [root-of-the-server]__ac0304e7._.js.map} +1 -1
  337. package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js +1 -1
  338. package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js.map +1 -1
  339. package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
  340. package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
  341. package/web/.next/server/chunks/ssr/_250a63ae._.js +1 -1
  342. package/web/.next/server/chunks/ssr/_250a63ae._.js.map +1 -1
  343. package/web/.next/server/chunks/ssr/_26b2c311._.js +3 -0
  344. package/web/.next/server/chunks/ssr/_26b2c311._.js.map +1 -0
  345. package/web/.next/server/chunks/ssr/{_6f0118a0._.js → _719ef347._.js} +2 -2
  346. package/web/.next/server/chunks/ssr/_719ef347._.js.map +1 -0
  347. package/web/.next/server/chunks/ssr/_809c53f6._.js +9 -0
  348. package/web/.next/server/chunks/ssr/_809c53f6._.js.map +1 -0
  349. package/web/.next/server/chunks/ssr/_8dacd1e7._.js +1 -1
  350. package/web/.next/server/chunks/ssr/_8dacd1e7._.js.map +1 -1
  351. package/web/.next/server/chunks/ssr/_98047ffd._.js +3 -0
  352. package/web/.next/server/chunks/ssr/_98047ffd._.js.map +1 -0
  353. package/web/.next/server/chunks/ssr/_9eea4c51._.js +3 -0
  354. package/web/.next/server/chunks/ssr/_9eea4c51._.js.map +1 -0
  355. package/web/.next/server/chunks/ssr/_a4899a76._.js +3 -0
  356. package/web/.next/server/chunks/ssr/_a4899a76._.js.map +1 -0
  357. package/web/.next/server/chunks/ssr/_b715515b._.js +3 -0
  358. package/web/.next/server/chunks/ssr/{_c5f84841._.js.map → _b715515b._.js.map} +1 -1
  359. package/web/.next/server/chunks/ssr/_b7eb93fc._.js +4 -0
  360. package/web/.next/server/chunks/ssr/_b7eb93fc._.js.map +1 -0
  361. package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
  362. package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
  363. package/web/.next/server/chunks/ssr/_e0a01382._.js +3 -0
  364. package/web/.next/server/chunks/ssr/_e0a01382._.js.map +1 -0
  365. package/web/.next/server/chunks/ssr/_f8b36e2c._.js +3 -0
  366. package/web/.next/server/chunks/ssr/_f8b36e2c._.js.map +1 -0
  367. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  368. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  369. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_webhooks_webhooks-page-client_tsx_b2662ea3._.js +3 -0
  370. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_webhooks_webhooks-page-client_tsx_b2662ea3._.js.map +1 -0
  371. package/web/.next/server/chunks/ssr/{_1bb131c4._.js → node_modules__pnpm_747b43ac._.js} +2 -2
  372. package/web/.next/server/chunks/ssr/node_modules__pnpm_747b43ac._.js.map +1 -0
  373. package/web/.next/server/chunks/ssr/src_presentation_web_0835b28e._.js +5 -0
  374. package/web/.next/server/chunks/ssr/src_presentation_web_0835b28e._.js.map +1 -0
  375. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_e99d78dd.js +3 -0
  376. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_e99d78dd.js.map +1 -0
  377. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
  378. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
  379. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
  380. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
  381. package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
  382. package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
  383. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  384. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  385. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  386. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  387. package/web/.next/server/chunks/ssr/src_presentation_web_e8034a29._.js +5 -0
  388. package/web/.next/server/chunks/ssr/src_presentation_web_e8034a29._.js.map +1 -0
  389. package/web/.next/server/middleware-build-manifest.js +4 -4
  390. package/web/.next/server/pages/500.html +2 -2
  391. package/web/.next/server/server-reference-manifest.js +1 -1
  392. package/web/.next/server/server-reference-manifest.json +323 -230
  393. package/web/.next/static/chunks/06b948216df083c1.js +1 -0
  394. package/web/.next/static/chunks/{52285fdb39925ad5.js → 2ac228556e3d1db4.js} +1 -1
  395. package/web/.next/static/chunks/31f35710932542ef.js +1 -0
  396. package/web/.next/static/chunks/40b6bcf1a2de4a0f.js +1 -0
  397. package/web/.next/static/chunks/4714eb891fa4fd81.js +1 -0
  398. package/web/.next/static/chunks/57094e1cbd326d6c.css +1 -0
  399. package/web/.next/static/chunks/{18de73b2f14204d3.js → 5856c588eb7f21fd.js} +1 -1
  400. package/web/.next/static/chunks/5f6161ceb4263319.js +1 -0
  401. package/web/.next/static/chunks/81f470d21748eafd.js +2 -0
  402. package/web/.next/static/chunks/829305a6e02eff1f.js +1 -0
  403. package/web/.next/static/chunks/97aaeeee72be634b.js +1 -0
  404. package/web/.next/static/chunks/{672e3da3ad26005b.js → 98e3a7cf58fc912a.js} +1 -1
  405. package/web/.next/static/chunks/9a7361e2365b2d8e.js +1 -0
  406. package/web/.next/static/chunks/9af45e885bd4ccef.js +1 -0
  407. package/web/.next/static/chunks/{5de387864b89e64c.js → ab8b8f80cbc8366f.js} +2 -2
  408. package/web/.next/static/chunks/c3c3f2c9eb309920.js +1 -0
  409. package/web/.next/static/chunks/c7e793951b20a67f.js +1 -0
  410. package/web/.next/static/chunks/cb2824954c3975b0.js +1 -0
  411. package/web/.next/static/chunks/{2babc8e3ae9ba6e8.js → d3db43fcdbbd9b68.js} +1 -1
  412. package/web/.next/static/chunks/e9621b096a69e4e8.js +11 -0
  413. package/web/.next/static/chunks/fb99c57e6d28a274.js +1 -0
  414. package/web/.next/static/chunks/{turbopack-426d9bc2450816ba.js → turbopack-b1685b5f87ad1d60.js} +1 -1
  415. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_a1104008.js +0 -3
  416. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_a1104008.js.map +0 -1
  417. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_92642200.js +0 -3
  418. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_92642200.js.map +0 -1
  419. package/web/.next/server/chunks/ssr/[root-of-the-server]__6367aea0._.js +0 -3
  420. package/web/.next/server/chunks/ssr/[root-of-the-server]__6367aea0._.js.map +0 -1
  421. package/web/.next/server/chunks/ssr/[root-of-the-server]__b1e68e34._.js +0 -3
  422. package/web/.next/server/chunks/ssr/[root-of-the-server]__b1e68e34._.js.map +0 -1
  423. package/web/.next/server/chunks/ssr/_1bb131c4._.js.map +0 -1
  424. package/web/.next/server/chunks/ssr/_273d4632._.js +0 -3
  425. package/web/.next/server/chunks/ssr/_273d4632._.js.map +0 -1
  426. package/web/.next/server/chunks/ssr/_6d26a08f._.js +0 -3
  427. package/web/.next/server/chunks/ssr/_6d26a08f._.js.map +0 -1
  428. package/web/.next/server/chunks/ssr/_6f0118a0._.js.map +0 -1
  429. package/web/.next/server/chunks/ssr/_a68d7e1c._.js +0 -9
  430. package/web/.next/server/chunks/ssr/_a68d7e1c._.js.map +0 -1
  431. package/web/.next/server/chunks/ssr/_b5fc318a._.js +0 -3
  432. package/web/.next/server/chunks/ssr/_b5fc318a._.js.map +0 -1
  433. package/web/.next/server/chunks/ssr/_c5f84841._.js +0 -3
  434. package/web/.next/server/chunks/ssr/_d2e408a9._.js +0 -3
  435. package/web/.next/server/chunks/ssr/_d2e408a9._.js.map +0 -1
  436. package/web/.next/server/chunks/ssr/_f5316e67._.js +0 -3
  437. package/web/.next/server/chunks/ssr/_f5316e67._.js.map +0 -1
  438. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_888633e1.js +0 -3
  439. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_888633e1.js.map +0 -1
  440. package/web/.next/server/chunks/ssr/src_presentation_web_ce7cbc3c._.js +0 -5
  441. package/web/.next/server/chunks/ssr/src_presentation_web_ce7cbc3c._.js.map +0 -1
  442. package/web/.next/server/chunks/ssr/src_presentation_web_e2604413._.js +0 -5
  443. package/web/.next/server/chunks/ssr/src_presentation_web_e2604413._.js.map +0 -1
  444. package/web/.next/static/chunks/0b3ab176958a8286.js +0 -1
  445. package/web/.next/static/chunks/242446982e8d196e.js +0 -1
  446. package/web/.next/static/chunks/303a1217006489b9.js +0 -1
  447. package/web/.next/static/chunks/3a806cf059241bc9.js +0 -1
  448. package/web/.next/static/chunks/552e0f129144b54d.js +0 -1
  449. package/web/.next/static/chunks/57b45edf86522369.css +0 -1
  450. package/web/.next/static/chunks/619af41a8d3232e5.js +0 -1
  451. package/web/.next/static/chunks/7b924c47dd2a5a53.js +0 -2
  452. package/web/.next/static/chunks/84a181ff3270fd9f.js +0 -1
  453. package/web/.next/static/chunks/b1f3c0e8e9872ef8.js +0 -1
  454. package/web/.next/static/chunks/c172f4a6010cb5b5.js +0 -1
  455. package/web/.next/static/chunks/e12f41ac3d49a7b5.js +0 -11
  456. package/web/.next/static/chunks/ed3a602003bcb31b.js +0 -1
  457. package/web/.next/static/chunks/fcde0cbb2976b933.js +0 -1
  458. /package/web/.next/static/{CStnC7-QgiTd6U99YUc1N → T6bpRqj4p37ell4NNYIUl}/_buildManifest.js +0 -0
  459. /package/web/.next/static/{CStnC7-QgiTd6U99YUc1N → T6bpRqj4p37ell4NNYIUl}/_clientMiddlewareManifest.json +0 -0
  460. /package/web/.next/static/{CStnC7-QgiTd6U99YUc1N → T6bpRqj4p37ell4NNYIUl}/_ssgManifest.js +0 -0
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Webhook Manager Service
3
+ *
4
+ * Orchestrates the Cloudflare Tunnel and GitHub Webhook lifecycle.
5
+ * Follows the singleton pattern used by NotificationWatcherService
6
+ * and PrSyncWatcherService.
7
+ *
8
+ * Lifecycle:
9
+ * 1. Start Cloudflare Tunnel to get a public URL
10
+ * 2. Register GitHub webhooks pointing to the tunnel URL
11
+ * 3. Monitor for tunnel URL changes → update webhooks
12
+ * 4. On shutdown → remove webhooks → stop tunnel
13
+ *
14
+ * The manager is optional — if cloudflared is not installed or webhook
15
+ * registration fails, the system falls back to polling gracefully.
16
+ */
17
+ import type { ITunnelService } from '../../../application/ports/output/services/tunnel-service.interface.js';
18
+ import type { IWebhookService } from '../../../application/ports/output/services/webhook-service.interface.js';
19
+ import type { RegisteredWebhook, WebhookDeliveryRecord } from './github-webhook.service.js';
20
+ export interface WebhookSystemStatus {
21
+ running: boolean;
22
+ tunnel: {
23
+ connected: boolean;
24
+ publicUrl: string | null;
25
+ };
26
+ webhooks: {
27
+ registered: readonly RegisteredWebhook[];
28
+ totalDeliveries: number;
29
+ successCount: number;
30
+ errorCount: number;
31
+ ignoredCount: number;
32
+ };
33
+ startedAt: string | null;
34
+ }
35
+ export declare class WebhookManagerService {
36
+ private readonly tunnelService;
37
+ private readonly webhookService;
38
+ private running;
39
+ private startedAt;
40
+ constructor(tunnelService: ITunnelService, webhookService: IWebhookService);
41
+ /**
42
+ * Start the tunnel and register webhooks.
43
+ * Fails gracefully — logs warnings but does not throw.
44
+ *
45
+ * @param localPort - The local web server port to tunnel
46
+ */
47
+ start(localPort: number): Promise<void>;
48
+ /**
49
+ * Stop the webhook system — remove webhooks, then stop the tunnel.
50
+ */
51
+ stop(): Promise<void>;
52
+ isRunning(): boolean;
53
+ getTunnelUrl(): string | null;
54
+ getStatus(): WebhookSystemStatus;
55
+ getDeliveryHistory(): readonly WebhookDeliveryRecord[];
56
+ }
57
+ /**
58
+ * Initialize the webhook manager singleton.
59
+ * Must be called once during web server startup.
60
+ *
61
+ * @throws Error if the manager is already initialized
62
+ */
63
+ export declare function initializeWebhookManager(tunnelService: ITunnelService, webhookService: IWebhookService): void;
64
+ /**
65
+ * Get the webhook manager singleton.
66
+ *
67
+ * @returns The webhook manager service
68
+ * @throws Error if the manager hasn't been initialized yet
69
+ */
70
+ export declare function getWebhookManager(): WebhookManagerService;
71
+ /**
72
+ * Check if the webhook manager has been initialized.
73
+ */
74
+ export declare function hasWebhookManager(): boolean;
75
+ /**
76
+ * Reset the webhook manager singleton (for testing purposes only).
77
+ * Stops the manager if running before resetting.
78
+ *
79
+ * @internal
80
+ */
81
+ export declare function resetWebhookManager(): void;
82
+ //# sourceMappingURL=webhook-manager.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook-manager.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/webhook/webhook-manager.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wEAAwE,CAAC;AAC7G,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yEAAyE,CAAC;AAC/G,OAAO,KAAK,EACV,iBAAiB,EACjB,qBAAqB,EAEtB,MAAM,6BAA6B,CAAC;AAErC,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE;QACN,SAAS,EAAE,OAAO,CAAC;QACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1B,CAAC;IACF,QAAQ,EAAE;QACR,UAAU,EAAE,SAAS,iBAAiB,EAAE,CAAC;QACzC,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAID,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiB;IAC/C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkB;IACjD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAuB;gBAE5B,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe;IAK1E;;;;;OAKG;IACG,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2C7C;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA2B3B,SAAS,IAAI,OAAO;IAIpB,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B,SAAS,IAAI,mBAAmB;IAoChC,kBAAkB,IAAI,SAAS,qBAAqB,EAAE;CAOvD;AAoBD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,cAAc,EAC7B,cAAc,EAAE,eAAe,GAC9B,IAAI,CAMN;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,qBAAqB,CASzD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAM1C"}
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Webhook Manager Service
3
+ *
4
+ * Orchestrates the Cloudflare Tunnel and GitHub Webhook lifecycle.
5
+ * Follows the singleton pattern used by NotificationWatcherService
6
+ * and PrSyncWatcherService.
7
+ *
8
+ * Lifecycle:
9
+ * 1. Start Cloudflare Tunnel to get a public URL
10
+ * 2. Register GitHub webhooks pointing to the tunnel URL
11
+ * 3. Monitor for tunnel URL changes → update webhooks
12
+ * 4. On shutdown → remove webhooks → stop tunnel
13
+ *
14
+ * The manager is optional — if cloudflared is not installed or webhook
15
+ * registration fails, the system falls back to polling gracefully.
16
+ */
17
+ const TAG = '[WebhookManager]';
18
+ export class WebhookManagerService {
19
+ tunnelService;
20
+ webhookService;
21
+ running = false;
22
+ startedAt = null;
23
+ constructor(tunnelService, webhookService) {
24
+ this.tunnelService = tunnelService;
25
+ this.webhookService = webhookService;
26
+ }
27
+ /**
28
+ * Start the tunnel and register webhooks.
29
+ * Fails gracefully — logs warnings but does not throw.
30
+ *
31
+ * @param localPort - The local web server port to tunnel
32
+ */
33
+ async start(localPort) {
34
+ if (this.running)
35
+ return;
36
+ try {
37
+ // Step 1: Start the tunnel
38
+ // eslint-disable-next-line no-console
39
+ console.log(`${TAG} Starting Cloudflare Tunnel for port ${localPort}...`);
40
+ const publicUrl = await this.tunnelService.start(localPort);
41
+ // Step 2: Listen for URL changes
42
+ this.tunnelService.onUrlChange(async (newUrl) => {
43
+ // eslint-disable-next-line no-console
44
+ console.log(`${TAG} Tunnel URL changed, updating webhooks...`);
45
+ try {
46
+ await this.webhookService.updateWebhookUrl(newUrl);
47
+ }
48
+ catch (error) {
49
+ const msg = error instanceof Error ? error.message : String(error);
50
+ // eslint-disable-next-line no-console
51
+ console.warn(`${TAG} Failed to update webhooks after URL change: ${msg}`);
52
+ }
53
+ });
54
+ // Step 3: Register webhooks with external services
55
+ await this.webhookService.registerWebhooks(publicUrl);
56
+ this.running = true;
57
+ this.startedAt = new Date().toISOString();
58
+ // eslint-disable-next-line no-console
59
+ console.log(`${TAG} Webhook system ready (tunnel: ${publicUrl})`);
60
+ }
61
+ catch (error) {
62
+ const msg = error instanceof Error ? error.message : String(error);
63
+ // eslint-disable-next-line no-console
64
+ console.warn(`${TAG} Failed to start webhook system (falling back to polling): ${msg}`);
65
+ // Clean up partial state
66
+ try {
67
+ await this.tunnelService.stop();
68
+ }
69
+ catch {
70
+ // Already stopped or never started
71
+ }
72
+ }
73
+ }
74
+ /**
75
+ * Stop the webhook system — remove webhooks, then stop the tunnel.
76
+ */
77
+ async stop() {
78
+ if (!this.running)
79
+ return;
80
+ // eslint-disable-next-line no-console
81
+ console.log(`${TAG} Shutting down webhook system...`);
82
+ try {
83
+ await this.webhookService.removeWebhooks();
84
+ }
85
+ catch (error) {
86
+ const msg = error instanceof Error ? error.message : String(error);
87
+ // eslint-disable-next-line no-console
88
+ console.warn(`${TAG} Failed to remove webhooks during shutdown: ${msg}`);
89
+ }
90
+ try {
91
+ await this.tunnelService.stop();
92
+ }
93
+ catch (error) {
94
+ const msg = error instanceof Error ? error.message : String(error);
95
+ // eslint-disable-next-line no-console
96
+ console.warn(`${TAG} Failed to stop tunnel during shutdown: ${msg}`);
97
+ }
98
+ this.running = false;
99
+ // eslint-disable-next-line no-console
100
+ console.log(`${TAG} Webhook system stopped`);
101
+ }
102
+ isRunning() {
103
+ return this.running;
104
+ }
105
+ getTunnelUrl() {
106
+ return this.tunnelService.getPublicUrl();
107
+ }
108
+ getStatus() {
109
+ const ghService = this.webhookService;
110
+ const deliveries = typeof ghService.getDeliveryHistory === 'function' ? ghService.getDeliveryHistory() : [];
111
+ const registered = typeof ghService.getRegisteredWebhooks === 'function'
112
+ ? ghService.getRegisteredWebhooks()
113
+ : [];
114
+ let successCount = 0;
115
+ let errorCount = 0;
116
+ let ignoredCount = 0;
117
+ for (const d of deliveries) {
118
+ if (d.status === 'success')
119
+ successCount++;
120
+ else if (d.status === 'error')
121
+ errorCount++;
122
+ else
123
+ ignoredCount++;
124
+ }
125
+ return {
126
+ running: this.running,
127
+ tunnel: {
128
+ connected: this.tunnelService.isRunning(),
129
+ publicUrl: this.tunnelService.getPublicUrl(),
130
+ },
131
+ webhooks: {
132
+ registered,
133
+ totalDeliveries: deliveries.length,
134
+ successCount,
135
+ errorCount,
136
+ ignoredCount,
137
+ },
138
+ startedAt: this.startedAt,
139
+ };
140
+ }
141
+ getDeliveryHistory() {
142
+ const ghService = this.webhookService;
143
+ if (typeof ghService.getDeliveryHistory === 'function') {
144
+ return ghService.getDeliveryHistory();
145
+ }
146
+ return [];
147
+ }
148
+ }
149
+ // --- Singleton accessors ---
150
+ //
151
+ // The singleton is stored on globalThis so that it survives module duplication
152
+ // across bundler contexts (e.g. Next.js Turbopack bundles API routes separately
153
+ // from the dev-server entry point, giving each its own copy of module-level
154
+ // variables). By using globalThis, the same manager instance is visible to both
155
+ // the initializer (dev-server.ts / CLI) and the API route handlers.
156
+ const GLOBAL_KEY = '__shepWebhookManager';
157
+ function getInstance() {
158
+ return globalThis[GLOBAL_KEY] ?? null;
159
+ }
160
+ function setInstance(instance) {
161
+ globalThis[GLOBAL_KEY] = instance;
162
+ }
163
+ /**
164
+ * Initialize the webhook manager singleton.
165
+ * Must be called once during web server startup.
166
+ *
167
+ * @throws Error if the manager is already initialized
168
+ */
169
+ export function initializeWebhookManager(tunnelService, webhookService) {
170
+ if (getInstance() !== null) {
171
+ throw new Error('Webhook manager already initialized. Cannot re-initialize.');
172
+ }
173
+ setInstance(new WebhookManagerService(tunnelService, webhookService));
174
+ }
175
+ /**
176
+ * Get the webhook manager singleton.
177
+ *
178
+ * @returns The webhook manager service
179
+ * @throws Error if the manager hasn't been initialized yet
180
+ */
181
+ export function getWebhookManager() {
182
+ const instance = getInstance();
183
+ if (instance === null) {
184
+ throw new Error('Webhook manager not initialized. Call initializeWebhookManager() during web server startup.');
185
+ }
186
+ return instance;
187
+ }
188
+ /**
189
+ * Check if the webhook manager has been initialized.
190
+ */
191
+ export function hasWebhookManager() {
192
+ return getInstance() !== null;
193
+ }
194
+ /**
195
+ * Reset the webhook manager singleton (for testing purposes only).
196
+ * Stops the manager if running before resetting.
197
+ *
198
+ * @internal
199
+ */
200
+ export function resetWebhookManager() {
201
+ const instance = getInstance();
202
+ if (instance !== null) {
203
+ void instance.stop();
204
+ }
205
+ setInstance(null);
206
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/feat/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAY3C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/feat/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAa3C"}
@@ -15,6 +15,7 @@ import { createLsCommand } from './ls.command.js';
15
15
  import { createShowCommand } from './show.command.js';
16
16
  import { createDelCommand } from './del.command.js';
17
17
  import { createResumeCommand } from './resume.command.js';
18
+ import { createStartCommand } from './start.command.js';
18
19
  import { createReviewCommand } from './review.command.js';
19
20
  import { createApproveCommand } from './approve.command.js';
20
21
  import { createRejectCommand } from './reject.command.js';
@@ -30,6 +31,7 @@ export function createFeatCommand() {
30
31
  .addCommand(createShowCommand())
31
32
  .addCommand(createDelCommand())
32
33
  .addCommand(createResumeCommand())
34
+ .addCommand(createStartCommand())
33
35
  .addCommand(createReviewCommand())
34
36
  .addCommand(createApproveCommand())
35
37
  .addCommand(createRejectCommand())
@@ -1 +1 @@
1
- {"version":3,"file":"ls.command.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/feat/ls.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyKpC,wBAAgB,eAAe,IAAI,OAAO,CAsGzC"}
1
+ {"version":3,"file":"ls.command.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/feat/ls.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6KpC,wBAAgB,eAAe,IAAI,OAAO,CAsGzC"}
@@ -54,6 +54,9 @@ function formatStatus(feature, run) {
54
54
  if (feature.lifecycle === 'Blocked') {
55
55
  return `${colors.warning(symbols.dotEmpty)} ${colors.warning('Blocked')}`;
56
56
  }
57
+ if (feature.lifecycle === 'Pending') {
58
+ return `${colors.muted(symbols.dotEmpty)} ${colors.muted('Pending')}`;
59
+ }
57
60
  if (!run) {
58
61
  return `${colors.muted(symbols.dotEmpty)} ${colors.muted(feature.lifecycle)}`;
59
62
  }
@@ -1 +1 @@
1
- {"version":3,"file":"new.command.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/feat/new.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4DpC;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAwI1C"}
1
+ {"version":3,"file":"new.command.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/feat/new.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6DpC;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAmJ1C"}
@@ -55,6 +55,7 @@ export function createNewCommand() {
55
55
  .option('--allow-merge', 'Auto-approve merge phase')
56
56
  .option('--allow-all', 'Run fully autonomous (no approval pauses)')
57
57
  .option('--parent <fid>', 'Parent feature ID (full or partial prefix)')
58
+ .option('--pending', 'Create feature without starting the agent')
58
59
  .option('--fast', 'Skip SDLC phases and implement directly from your prompt')
59
60
  .option('--model <model>', 'LLM model identifier for this run (e.g. claude-opus-4-6)')
60
61
  .option('--attach <path>', 'Attach a file (repeatable)', collect, [])
@@ -113,6 +114,7 @@ export function createNewCommand() {
113
114
  push,
114
115
  openPr,
115
116
  ...(parentId !== undefined && { parentId }),
117
+ ...(options.pending && { pending: true }),
116
118
  ...(options.fast && { fast: true }),
117
119
  ...(options.model !== undefined && { model: options.model }),
118
120
  ...(attachmentPaths.length > 0 && { attachmentPaths }),
@@ -129,6 +131,9 @@ export function createNewCommand() {
129
131
  if (feature.lifecycle === SdlcLifecycle.Blocked) {
130
132
  messages.info(`Feature created in Blocked state — waiting for parent to reach Implementation`);
131
133
  }
134
+ if (feature.lifecycle === SdlcLifecycle.Pending) {
135
+ messages.info(`Feature created in Pending state — run ${colors.accent(`shep feat start ${feature.id.slice(0, 8)}`)} to begin`);
136
+ }
132
137
  console.log(` ${colors.muted('ID:')} ${colors.accent(feature.id)}`);
133
138
  console.log(` ${colors.muted('Name:')} ${feature.name}`);
134
139
  console.log(` ${colors.muted('Branch:')} ${colors.accent(feature.branch)}`);
@@ -138,7 +143,10 @@ export function createNewCommand() {
138
143
  console.log(` ${colors.muted('Spec:')} ${feature.specPath}`);
139
144
  }
140
145
  if (feature.agentRunId) {
141
- console.log(` ${colors.muted('Agent:')} ${colors.success('spawned')} (run ${feature.agentRunId.slice(0, 8)})`);
146
+ const agentStatus = feature.lifecycle === SdlcLifecycle.Pending
147
+ ? colors.muted('pending')
148
+ : colors.success('spawned');
149
+ console.log(` ${colors.muted('Agent:')} ${agentStatus} (run ${feature.agentRunId.slice(0, 8)})`);
142
150
  }
143
151
  if (push || openPr) {
144
152
  const pushHint = openPr ? 'push + PR' : 'push only';
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Feature Start Command
3
+ *
4
+ * Starts a pending feature by transitioning it to its active lifecycle
5
+ * and spawning the agent.
6
+ *
7
+ * Usage:
8
+ * shep feat start <id>
9
+ */
10
+ import { Command } from 'commander';
11
+ export declare function createStartCommand(): Command;
12
+ //# sourceMappingURL=start.command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.command.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/feat/start.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,kBAAkB,IAAI,OAAO,CAgC5C"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Feature Start Command
3
+ *
4
+ * Starts a pending feature by transitioning it to its active lifecycle
5
+ * and spawning the agent.
6
+ *
7
+ * Usage:
8
+ * shep feat start <id>
9
+ */
10
+ import { Command } from 'commander';
11
+ import { container } from '../../../../../packages/core/src/infrastructure/di/container.js';
12
+ import { StartFeatureUseCase } from '../../../../../packages/core/src/application/use-cases/features/start-feature.use-case.js';
13
+ import { colors, messages, spinner } from '../../ui/index.js';
14
+ export function createStartCommand() {
15
+ return new Command('start')
16
+ .description('Start a pending feature (spawn the agent)')
17
+ .argument('<id>', 'Feature ID (or prefix)')
18
+ .action(async (id) => {
19
+ try {
20
+ const useCase = container.resolve(StartFeatureUseCase);
21
+ const { feature, agentRun } = await spinner('Starting feature', () => useCase.execute(id));
22
+ messages.newline();
23
+ if (feature.lifecycle === 'Blocked') {
24
+ messages.warning(`Feature transitioned to Blocked — parent has not reached Implementation`);
25
+ }
26
+ else {
27
+ messages.success('Feature started');
28
+ }
29
+ console.log(` ${colors.muted('Feature:')} ${feature.name}`);
30
+ console.log(` ${colors.muted('Branch:')} ${colors.accent(feature.branch)}`);
31
+ console.log(` ${colors.muted('Status:')} ${feature.lifecycle}`);
32
+ if (feature.lifecycle !== 'Blocked') {
33
+ console.log(` ${colors.muted('Agent:')} ${colors.success('spawned')} (run ${agentRun.id.slice(0, 8)})`);
34
+ }
35
+ messages.newline();
36
+ }
37
+ catch (error) {
38
+ const err = error instanceof Error ? error : new Error(String(error));
39
+ messages.error('Failed to start feature', err);
40
+ process.exitCode = 1;
41
+ }
42
+ });
43
+ }
@@ -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;AAuC1D;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAwGzC"}
@@ -23,6 +23,7 @@ import { initializeNotificationWatcher, getNotificationWatcher, } from '../../..
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
25
  import { BrowserOpenerService } from '../../../../packages/core/src/infrastructure/services/browser-opener.service.js';
26
+ import { initializeWebhookManager, getWebhookManager, hasWebhookManager, } from '../../../../packages/core/src/infrastructure/services/webhook/webhook-manager.service.js';
26
27
  import { colors, fmt, messages } from '../ui/index.js';
27
28
  function parsePort(value) {
28
29
  const port = parseInt(value, 10);
@@ -70,6 +71,17 @@ Examples:
70
71
  const db = getExistingConnection();
71
72
  initializePrSyncWatcher(featureRepo, runRepo, gitPrService, notificationService, undefined, db);
72
73
  getPrSyncWatcher().start();
74
+ // Start webhook system (optional — falls back to polling if cloudflared is not available)
75
+ try {
76
+ const tunnelService = container.resolve('ITunnelService');
77
+ const webhookService = container.resolve('IWebhookService');
78
+ initializeWebhookManager(tunnelService, webhookService);
79
+ // Start is async and non-blocking — failures are logged, not thrown
80
+ void getWebhookManager().start(port);
81
+ }
82
+ catch {
83
+ // Webhook system is optional; polling continues to work
84
+ }
73
85
  const url = `http://localhost:${port}`;
74
86
  messages.success(`Server ready at ${fmt.code(url)}`);
75
87
  messages.info('Press Ctrl+C to stop');
@@ -91,6 +103,9 @@ Examples:
91
103
  // Force exit after 5s if graceful shutdown stalls
92
104
  const forceExit = setTimeout(() => process.exit(0), 5000);
93
105
  forceExit.unref();
106
+ if (hasWebhookManager()) {
107
+ await getWebhookManager().stop();
108
+ }
94
109
  getPrSyncWatcher().stop();
95
110
  getNotificationWatcher().stop();
96
111
  await service.stop();
@@ -18,6 +18,8 @@ interface CreateFeatureInput {
18
18
  parentId?: string;
19
19
  /** When true, skip SDLC phases and implement directly from the prompt. */
20
20
  fast?: boolean;
21
+ /** When true, create the feature in pending state (no agent spawned). */
22
+ pending?: boolean;
21
23
  /** Optional agent type override for this feature run */
22
24
  agentType?: string;
23
25
  /** Optional model identifier for this feature run */
@@ -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,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,CA4EhD"}
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"}
@@ -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, agentType, model, } = input;
5
+ const { description, repositoryPath, attachments, sessionId, approvalGates, push, openPr, parentId, fast, pending, agentType, model, } = input;
6
6
  if (!description?.trim()) {
7
7
  return { error: 'description is required' };
8
8
  }
@@ -27,6 +27,7 @@ export async function createFeature(input) {
27
27
  ...(parentId ? { parentId } : {}),
28
28
  description,
29
29
  ...(fast ? { fast } : {}),
30
+ ...(pending ? { pending } : {}),
30
31
  ...(agentType ? { agentType } : {}),
31
32
  ...(model ? { model } : {}),
32
33
  });
@@ -41,6 +42,7 @@ export async function createFeature(input) {
41
42
  openPr: openPr ?? false,
42
43
  ...(parentId ? { parentId } : {}),
43
44
  ...(fast ? { fast } : {}),
45
+ ...(pending ? { pending } : {}),
44
46
  ...(agentType ? { agentType } : {}),
45
47
  ...(model ? { model } : {}),
46
48
  ...(sessionId ? { sessionId } : {}),
@@ -0,0 +1,3 @@
1
+ import type { WebhookSystemStatus } from '../../../../../packages/core/src/infrastructure/services/webhook/webhook-manager.service.js';
2
+ export declare function loadWebhookStatus(): Promise<WebhookSystemStatus>;
3
+ //# sourceMappingURL=load-webhook-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-webhook-status.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/load-webhook-status.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sEAAsE,CAAC;AAEhH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAiBtE"}
@@ -0,0 +1,19 @@
1
+ 'use server';
2
+ import { hasWebhookManager, getWebhookManager, } from '../../../../../packages/core/src/infrastructure/services/webhook/webhook-manager.service.js';
3
+ export async function loadWebhookStatus() {
4
+ if (!hasWebhookManager()) {
5
+ return {
6
+ running: false,
7
+ tunnel: { connected: false, publicUrl: null },
8
+ webhooks: {
9
+ registered: [],
10
+ totalDeliveries: 0,
11
+ successCount: 0,
12
+ errorCount: 0,
13
+ ignoredCount: 0,
14
+ },
15
+ startedAt: null,
16
+ };
17
+ }
18
+ return getWebhookManager().getStatus();
19
+ }
@@ -0,0 +1,5 @@
1
+ export declare function startFeature(featureId: string): Promise<{
2
+ started: boolean;
3
+ error?: string;
4
+ }>;
5
+ //# sourceMappingURL=start-feature.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/start-feature.ts"],"names":[],"mappings":"AAKA,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAa/C"}
@@ -0,0 +1,16 @@
1
+ 'use server';
2
+ import { resolve } from '../../lib/server-container.js';
3
+ export async function startFeature(featureId) {
4
+ if (!featureId.trim()) {
5
+ return { started: false, error: 'Feature id is required' };
6
+ }
7
+ try {
8
+ const useCase = resolve('StartFeatureUseCase');
9
+ await useCase.execute(featureId);
10
+ return { started: true };
11
+ }
12
+ catch (error) {
13
+ const message = error instanceof Error ? error.message : 'Failed to start feature';
14
+ return { started: false, error: message };
15
+ }
16
+ }
@@ -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;AAqEvC,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;AAsEvC,wBAAgB,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,CA4R9C"}
@@ -34,6 +34,7 @@ const LIFECYCLE_TO_NODE = {
34
34
  [SdlcLifecycle.Review]: 'merge',
35
35
  [SdlcLifecycle.Maintain]: 'maintain',
36
36
  [SdlcLifecycle.Blocked]: 'blocked',
37
+ [SdlcLifecycle.Pending]: 'pending',
37
38
  [SdlcLifecycle.Deleting]: 'blocked',
38
39
  };
39
40
  const STATUS_TO_EVENT = {
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Webhook Delivery History: GET /api/webhooks/deliveries
3
+ *
4
+ * Returns recent webhook delivery records with optional filtering.
5
+ * Query params: ?status=success|error|ignored&eventType=pull_request&limit=50
6
+ */
7
+ export declare const dynamic = "force-dynamic";
8
+ export declare function GET(request: Request): Promise<Response>;
9
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../../src/presentation/web/app/api/webhooks/deliveries/route.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,wBAAsB,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAsB7D"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Webhook Delivery History: GET /api/webhooks/deliveries
3
+ *
4
+ * Returns recent webhook delivery records with optional filtering.
5
+ * Query params: ?status=success|error|ignored&eventType=pull_request&limit=50
6
+ */
7
+ import { hasWebhookManager, getWebhookManager, } from '../../../../../../../packages/core/src/infrastructure/services/webhook/webhook-manager.service.js';
8
+ export const dynamic = 'force-dynamic';
9
+ export async function GET(request) {
10
+ if (!hasWebhookManager()) {
11
+ return Response.json({ deliveries: [] });
12
+ }
13
+ const url = new URL(request.url);
14
+ const statusFilter = url.searchParams.get('status');
15
+ const eventTypeFilter = url.searchParams.get('eventType');
16
+ const limitParam = url.searchParams.get('limit');
17
+ const limit = limitParam ? Math.min(parseInt(limitParam, 10) || 50, 200) : 50;
18
+ const manager = getWebhookManager();
19
+ let deliveries = [...manager.getDeliveryHistory()];
20
+ if (statusFilter) {
21
+ deliveries = deliveries.filter((d) => d.status === statusFilter);
22
+ }
23
+ if (eventTypeFilter) {
24
+ deliveries = deliveries.filter((d) => d.eventType === eventTypeFilter);
25
+ }
26
+ return Response.json({ deliveries: deliveries.slice(0, limit) });
27
+ }