@shepai/cli 1.122.1 → 1.122.2-pr367.fdba557

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 (378) hide show
  1. package/dist/packages/core/src/application/ports/output/services/index.d.ts +2 -0
  2. package/dist/packages/core/src/application/ports/output/services/index.d.ts.map +1 -1
  3. package/dist/packages/core/src/application/ports/output/services/tunnel-service.interface.d.ts +41 -0
  4. package/dist/packages/core/src/application/ports/output/services/tunnel-service.interface.d.ts.map +1 -0
  5. package/dist/packages/core/src/application/ports/output/services/tunnel-service.interface.js +14 -0
  6. package/dist/packages/core/src/application/ports/output/services/webhook-service.interface.d.ts +65 -0
  7. package/dist/packages/core/src/application/ports/output/services/webhook-service.interface.d.ts.map +1 -0
  8. package/dist/packages/core/src/application/ports/output/services/webhook-service.interface.js +10 -0
  9. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  10. package/dist/packages/core/src/infrastructure/di/container.js +14 -0
  11. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts.map +1 -1
  12. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.js +21 -4
  13. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.d.ts +7 -1
  14. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.d.ts.map +1 -1
  15. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.js +24 -2
  16. package/dist/packages/core/src/infrastructure/services/tunnel/cloudflare-tunnel.service.d.ts +55 -0
  17. package/dist/packages/core/src/infrastructure/services/tunnel/cloudflare-tunnel.service.d.ts.map +1 -0
  18. package/dist/packages/core/src/infrastructure/services/tunnel/cloudflare-tunnel.service.js +203 -0
  19. package/dist/packages/core/src/infrastructure/services/webhook/github-webhook.service.d.ts +75 -0
  20. package/dist/packages/core/src/infrastructure/services/webhook/github-webhook.service.d.ts.map +1 -0
  21. package/dist/packages/core/src/infrastructure/services/webhook/github-webhook.service.js +372 -0
  22. package/dist/packages/core/src/infrastructure/services/webhook/webhook-manager.service.d.ts +82 -0
  23. package/dist/packages/core/src/infrastructure/services/webhook/webhook-manager.service.d.ts.map +1 -0
  24. package/dist/packages/core/src/infrastructure/services/webhook/webhook-manager.service.js +206 -0
  25. package/dist/src/presentation/cli/commands/ui.command.d.ts.map +1 -1
  26. package/dist/src/presentation/cli/commands/ui.command.js +15 -0
  27. package/dist/src/presentation/web/app/actions/load-webhook-status.d.ts +3 -0
  28. package/dist/src/presentation/web/app/actions/load-webhook-status.d.ts.map +1 -0
  29. package/dist/src/presentation/web/app/actions/load-webhook-status.js +19 -0
  30. package/dist/src/presentation/web/app/api/webhooks/deliveries/route.d.ts +9 -0
  31. package/dist/src/presentation/web/app/api/webhooks/deliveries/route.d.ts.map +1 -0
  32. package/dist/src/presentation/web/app/api/webhooks/deliveries/route.js +27 -0
  33. package/dist/src/presentation/web/app/api/webhooks/github/route.d.ts +17 -0
  34. package/dist/src/presentation/web/app/api/webhooks/github/route.d.ts.map +1 -0
  35. package/dist/src/presentation/web/app/api/webhooks/github/route.js +70 -0
  36. package/dist/src/presentation/web/app/api/webhooks/status/route.d.ts +9 -0
  37. package/dist/src/presentation/web/app/api/webhooks/status/route.d.ts.map +1 -0
  38. package/dist/src/presentation/web/app/api/webhooks/status/route.js +26 -0
  39. package/dist/src/presentation/web/app/webhooks/page.d.ts +4 -0
  40. package/dist/src/presentation/web/app/webhooks/page.d.ts.map +1 -0
  41. package/dist/src/presentation/web/app/webhooks/page.js +9 -0
  42. package/dist/src/presentation/web/components/features/webhooks/types.d.ts +32 -0
  43. package/dist/src/presentation/web/components/features/webhooks/types.d.ts.map +1 -0
  44. package/dist/src/presentation/web/components/features/webhooks/types.js +1 -0
  45. package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.d.ts +6 -0
  46. package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.d.ts.map +1 -0
  47. package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.js +38 -0
  48. package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.stories.d.ts +9 -0
  49. package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.stories.d.ts.map +1 -0
  50. package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.stories.js +69 -0
  51. package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.d.ts +7 -0
  52. package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.d.ts.map +1 -0
  53. package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.js +11 -0
  54. package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.stories.d.ts +9 -0
  55. package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.stories.d.ts.map +1 -0
  56. package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.stories.js +31 -0
  57. package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.d.ts +6 -0
  58. package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.d.ts.map +1 -0
  59. package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.js +21 -0
  60. package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.stories.d.ts +9 -0
  61. package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.stories.d.ts.map +1 -0
  62. package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.stories.js +56 -0
  63. package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.d.ts +6 -0
  64. package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.d.ts.map +1 -0
  65. package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.js +39 -0
  66. package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.stories.d.ts +8 -0
  67. package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.stories.d.ts.map +1 -0
  68. package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.stories.js +59 -0
  69. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.d.ts.map +1 -1
  70. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.js +2 -2
  71. package/dist/src/presentation/web/dev-server.js +20 -0
  72. package/dist/tsconfig.build.tsbuildinfo +1 -1
  73. package/package.json +3 -1
  74. package/web/.next/BUILD_ID +1 -1
  75. package/web/.next/app-path-routes-manifest.json +5 -1
  76. package/web/.next/build-manifest.json +6 -6
  77. package/web/.next/fallback-build-manifest.json +2 -2
  78. package/web/.next/prerender-manifest.json +3 -3
  79. package/web/.next/required-server-files.js +3 -3
  80. package/web/.next/required-server-files.json +3 -3
  81. package/web/.next/routes-manifest.json +24 -0
  82. package/web/.next/server/app/(dashboard)/@drawer/create/page/build-manifest.json +4 -4
  83. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +22 -22
  84. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
  85. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  86. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  87. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/build-manifest.json +4 -4
  88. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
  89. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +1 -1
  90. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  91. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  92. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/build-manifest.json +4 -4
  93. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +28 -28
  94. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
  95. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  96. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  97. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/build-manifest.json +4 -4
  98. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
  99. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
  100. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  101. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  102. package/web/.next/server/app/(dashboard)/create/page/build-manifest.json +4 -4
  103. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +22 -22
  104. package/web/.next/server/app/(dashboard)/create/page.js +1 -1
  105. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  106. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  107. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/build-manifest.json +4 -4
  108. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
  109. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +1 -1
  110. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  111. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  112. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/build-manifest.json +4 -4
  113. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +28 -28
  114. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
  115. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  116. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  117. package/web/.next/server/app/(dashboard)/page/build-manifest.json +4 -4
  118. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +20 -20
  119. package/web/.next/server/app/(dashboard)/page.js +1 -1
  120. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  121. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  122. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/build-manifest.json +4 -4
  123. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
  124. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
  125. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  126. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  127. package/web/.next/server/app/_global-error/page/build-manifest.json +4 -4
  128. package/web/.next/server/app/_global-error.html +2 -2
  129. package/web/.next/server/app/_global-error.rsc +1 -1
  130. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  131. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  132. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  133. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  134. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  135. package/web/.next/server/app/_not-found/page/build-manifest.json +4 -4
  136. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  137. package/web/.next/server/app/_not-found/page.js +1 -1
  138. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  139. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  140. package/web/.next/server/app/api/attachments/preview/route.js +1 -1
  141. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  142. package/web/.next/server/app/api/evidence/route.js +1 -1
  143. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  144. package/web/.next/server/app/api/graph-data/route.js +1 -1
  145. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  146. package/web/.next/server/app/api/webhooks/deliveries/route/app-paths-manifest.json +3 -0
  147. package/web/.next/server/app/api/webhooks/deliveries/route/build-manifest.json +11 -0
  148. package/web/.next/server/app/api/webhooks/deliveries/route/server-reference-manifest.json +4 -0
  149. package/web/.next/server/app/api/webhooks/deliveries/route.js +6 -0
  150. package/web/.next/server/app/api/webhooks/deliveries/route.js.map +5 -0
  151. package/web/.next/server/app/api/webhooks/deliveries/route.js.nft.json +1 -0
  152. package/web/.next/server/app/api/webhooks/deliveries/route_client-reference-manifest.js +2 -0
  153. package/web/.next/server/app/api/webhooks/github/route/app-paths-manifest.json +3 -0
  154. package/web/.next/server/app/api/webhooks/github/route/build-manifest.json +11 -0
  155. package/web/.next/server/app/api/webhooks/github/route/server-reference-manifest.json +4 -0
  156. package/web/.next/server/app/api/webhooks/github/route.js +6 -0
  157. package/web/.next/server/app/api/webhooks/github/route.js.map +5 -0
  158. package/web/.next/server/app/api/webhooks/github/route.js.nft.json +1 -0
  159. package/web/.next/server/app/api/webhooks/github/route_client-reference-manifest.js +2 -0
  160. package/web/.next/server/app/api/webhooks/status/route/app-paths-manifest.json +3 -0
  161. package/web/.next/server/app/api/webhooks/status/route/build-manifest.json +11 -0
  162. package/web/.next/server/app/api/webhooks/status/route/server-reference-manifest.json +4 -0
  163. package/web/.next/server/app/api/webhooks/status/route.js +6 -0
  164. package/web/.next/server/app/api/webhooks/status/route.js.map +5 -0
  165. package/web/.next/server/app/api/webhooks/status/route.js.nft.json +1 -0
  166. package/web/.next/server/app/api/webhooks/status/route_client-reference-manifest.js +2 -0
  167. package/web/.next/server/app/settings/page/build-manifest.json +4 -4
  168. package/web/.next/server/app/settings/page/server-reference-manifest.json +6 -6
  169. package/web/.next/server/app/settings/page.js +1 -1
  170. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  171. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  172. package/web/.next/server/app/skills/page/build-manifest.json +4 -4
  173. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  174. package/web/.next/server/app/skills/page.js +1 -1
  175. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  176. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  177. package/web/.next/server/app/tools/page/build-manifest.json +4 -4
  178. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  179. package/web/.next/server/app/tools/page.js +1 -1
  180. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  181. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  182. package/web/.next/server/app/version/page/build-manifest.json +4 -4
  183. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  184. package/web/.next/server/app/version/page.js +2 -2
  185. package/web/.next/server/app/version/page.js.nft.json +1 -1
  186. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  187. package/web/.next/server/app/webhooks/page/app-paths-manifest.json +3 -0
  188. package/web/.next/server/app/webhooks/page/build-manifest.json +18 -0
  189. package/web/.next/server/app/webhooks/page/next-font-manifest.json +6 -0
  190. package/web/.next/server/app/webhooks/page/react-loadable-manifest.json +1 -0
  191. package/web/.next/server/app/webhooks/page/server-reference-manifest.json +35 -0
  192. package/web/.next/server/app/webhooks/page.js +16 -0
  193. package/web/.next/server/app/webhooks/page.js.map +5 -0
  194. package/web/.next/server/app/webhooks/page.js.nft.json +1 -0
  195. package/web/.next/server/app/webhooks/page_client-reference-manifest.js +2 -0
  196. package/web/.next/server/app-paths-manifest.json +5 -1
  197. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_deliveries_route_actions_d9e34c8d.js +3 -0
  198. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_deliveries_route_actions_d9e34c8d.js.map +1 -0
  199. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_github_route_actions_1b0d0c38.js +3 -0
  200. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_github_route_actions_1b0d0c38.js.map +1 -0
  201. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_status_route_actions_1a0d86a1.js +3 -0
  202. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_status_route_actions_1a0d86a1.js.map +1 -0
  203. package/web/.next/server/chunks/[root-of-the-server]__15e5d45c._.js +3 -0
  204. package/web/.next/server/chunks/[root-of-the-server]__15e5d45c._.js.map +1 -0
  205. package/web/.next/server/chunks/[root-of-the-server]__23be381e._.js +3 -0
  206. package/web/.next/server/chunks/[root-of-the-server]__23be381e._.js.map +1 -0
  207. package/web/.next/server/chunks/{[root-of-the-server]__42b7ab55._.js → [root-of-the-server]__3baec744._.js} +2 -2
  208. package/web/.next/server/chunks/{[root-of-the-server]__42b7ab55._.js.map → [root-of-the-server]__3baec744._.js.map} +1 -1
  209. package/web/.next/server/chunks/{[root-of-the-server]__53013576._.js → [root-of-the-server]__7d63f9a4._.js} +2 -2
  210. package/web/.next/server/chunks/[root-of-the-server]__9fc760c0._.js +3 -0
  211. package/web/.next/server/chunks/[root-of-the-server]__9fc760c0._.js.map +1 -0
  212. package/web/.next/server/chunks/{[root-of-the-server]__92078db6._.js → [root-of-the-server]__a1c7c02a._.js} +2 -2
  213. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  214. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  215. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  216. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_activity_22f9667f.js +3 -0
  217. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_activity_22f9667f.js.map +1 -0
  218. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_rocket_1575cd4d.js +3 -0
  219. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_rocket_1575cd4d.js.map +1 -0
  220. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js +1 -1
  221. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js.map +1 -1
  222. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js +1 -1
  223. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js.map +1 -1
  224. package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js +4 -0
  225. package/web/.next/server/chunks/ssr/{[root-of-the-server]__6b17a22d._.js.map → [root-of-the-server]__11033878._.js.map} +1 -1
  226. package/web/.next/server/chunks/ssr/{[root-of-the-server]__06fef644._.js → [root-of-the-server]__12c2ab7d._.js} +2 -2
  227. package/web/.next/server/chunks/ssr/{[root-of-the-server]__06fef644._.js.map → [root-of-the-server]__12c2ab7d._.js.map} +1 -1
  228. package/web/.next/server/chunks/ssr/[root-of-the-server]__2698e9f4._.js +1 -1
  229. package/web/.next/server/chunks/ssr/[root-of-the-server]__2698e9f4._.js.map +1 -1
  230. package/web/.next/server/chunks/ssr/[root-of-the-server]__3c16bf85._.js +3 -0
  231. package/web/.next/server/chunks/ssr/[root-of-the-server]__3c16bf85._.js.map +1 -0
  232. package/web/.next/server/chunks/ssr/[root-of-the-server]__610f06df._.js +3 -0
  233. package/web/.next/server/chunks/ssr/[root-of-the-server]__610f06df._.js.map +1 -0
  234. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +2 -2
  235. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js.map +1 -1
  236. package/web/.next/server/chunks/ssr/[root-of-the-server]__76915230._.js +4 -0
  237. package/web/.next/server/chunks/ssr/{[root-of-the-server]__8c553503._.js.map → [root-of-the-server]__76915230._.js.map} +1 -1
  238. package/web/.next/server/chunks/ssr/[root-of-the-server]__7a939e4e._.js +4 -0
  239. package/web/.next/server/chunks/ssr/{[root-of-the-server]__a022445f._.js.map → [root-of-the-server]__7a939e4e._.js.map} +1 -1
  240. package/web/.next/server/chunks/ssr/[root-of-the-server]__87a7ae30._.js +3 -0
  241. package/web/.next/server/chunks/ssr/[root-of-the-server]__87a7ae30._.js.map +1 -0
  242. package/web/.next/server/chunks/ssr/[root-of-the-server]__8e3bf5d7._.js +1 -1
  243. package/web/.next/server/chunks/ssr/[root-of-the-server]__8e3bf5d7._.js.map +1 -1
  244. package/web/.next/server/chunks/ssr/[root-of-the-server]__920dccd5._.js +4 -0
  245. package/web/.next/server/chunks/ssr/[root-of-the-server]__920dccd5._.js.map +1 -0
  246. package/web/.next/server/chunks/ssr/[root-of-the-server]__c07f9f79._.js +1 -1
  247. package/web/.next/server/chunks/ssr/[root-of-the-server]__c07f9f79._.js.map +1 -1
  248. package/web/.next/server/chunks/ssr/[root-of-the-server]__c4dc1b5a._.js +4 -0
  249. package/web/.next/server/chunks/ssr/{[root-of-the-server]__a7de2711._.js.map → [root-of-the-server]__c4dc1b5a._.js.map} +1 -1
  250. package/web/.next/server/chunks/ssr/[root-of-the-server]__c605a375._.js +1 -1
  251. package/web/.next/server/chunks/ssr/[root-of-the-server]__c605a375._.js.map +1 -1
  252. package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js +4 -0
  253. package/web/.next/server/chunks/ssr/{[root-of-the-server]__804c006d._.js.map → [root-of-the-server]__fdc75809._.js.map} +1 -1
  254. package/web/.next/server/chunks/ssr/_07f57bd0._.js +3 -0
  255. package/web/.next/server/chunks/ssr/_07f57bd0._.js.map +1 -0
  256. package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
  257. package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
  258. package/web/.next/server/chunks/ssr/_15a756dd._.js +3 -0
  259. package/web/.next/server/chunks/ssr/_15a756dd._.js.map +1 -0
  260. package/web/.next/server/chunks/ssr/_26b2c311._.js +3 -0
  261. package/web/.next/server/chunks/ssr/_26b2c311._.js.map +1 -0
  262. package/web/.next/server/chunks/ssr/_2f6f48b8._.js +1 -1
  263. package/web/.next/server/chunks/ssr/_2f6f48b8._.js.map +1 -1
  264. package/web/.next/server/chunks/ssr/{_92d851b4._.js → _3d1ed2a7._.js} +2 -2
  265. package/web/.next/server/chunks/ssr/_3d1ed2a7._.js.map +1 -0
  266. package/web/.next/server/chunks/ssr/_3eca2297._.js +3 -0
  267. package/web/.next/server/chunks/ssr/{_b294a667._.js.map → _3eca2297._.js.map} +1 -1
  268. package/web/.next/server/chunks/ssr/_4470c218._.js +3 -0
  269. package/web/.next/server/chunks/ssr/_4470c218._.js.map +1 -0
  270. package/web/.next/server/chunks/ssr/_462cc3a6._.js +3 -0
  271. package/web/.next/server/chunks/ssr/_462cc3a6._.js.map +1 -0
  272. package/web/.next/server/chunks/ssr/_961cb4b2._.js +3 -0
  273. package/web/.next/server/chunks/ssr/_961cb4b2._.js.map +1 -0
  274. package/web/.next/server/chunks/ssr/_a4899a76._.js +3 -0
  275. package/web/.next/server/chunks/ssr/_a4899a76._.js.map +1 -0
  276. package/web/.next/server/chunks/ssr/_b5babdfc._.js +9 -0
  277. package/web/.next/server/chunks/ssr/_b5babdfc._.js.map +1 -0
  278. package/web/.next/server/chunks/ssr/_b7eb93fc._.js +4 -0
  279. package/web/.next/server/chunks/ssr/_b7eb93fc._.js.map +1 -0
  280. package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
  281. package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
  282. package/web/.next/server/chunks/ssr/_f8b36e2c._.js +3 -0
  283. package/web/.next/server/chunks/ssr/_f8b36e2c._.js.map +1 -0
  284. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  285. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  286. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_webhooks_webhooks-page-client_tsx_b2662ea3._.js +3 -0
  287. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_webhooks_webhooks-page-client_tsx_b2662ea3._.js.map +1 -0
  288. package/web/.next/server/chunks/ssr/{_1bb131c4._.js → node_modules__pnpm_747b43ac._.js} +2 -2
  289. package/web/.next/server/chunks/ssr/node_modules__pnpm_747b43ac._.js.map +1 -0
  290. package/web/.next/server/chunks/ssr/src_presentation_web_5f039db1._.js +2 -2
  291. package/web/.next/server/chunks/ssr/src_presentation_web_5f039db1._.js.map +1 -1
  292. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js +1 -1
  293. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js.map +1 -1
  294. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
  295. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
  296. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
  297. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
  298. package/web/.next/server/chunks/ssr/src_presentation_web_c4337169._.js +2 -2
  299. package/web/.next/server/chunks/ssr/src_presentation_web_c4337169._.js.map +1 -1
  300. package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
  301. package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
  302. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  303. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  304. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  305. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  306. package/web/.next/server/middleware-build-manifest.js +4 -4
  307. package/web/.next/server/pages/500.html +2 -2
  308. package/web/.next/server/server-reference-manifest.js +1 -1
  309. package/web/.next/server/server-reference-manifest.json +57 -35
  310. package/web/.next/static/chunks/0c76de69325ef923.js +1 -0
  311. package/web/.next/static/chunks/{658fc2f5f65cf3b5.js → 1b9d34af4064dafe.js} +2 -2
  312. package/web/.next/static/chunks/{50dd80c8aafa3b20.js → 293ccfbe777d995a.js} +1 -1
  313. package/web/.next/static/chunks/3835a408dbf8d0bb.js +1 -0
  314. package/web/.next/static/chunks/{941c13dcdb1978a4.js → 3f0773d9b56e04a2.js} +2 -2
  315. package/web/.next/static/chunks/40b6bcf1a2de4a0f.js +1 -0
  316. package/web/.next/static/chunks/4c5b31a2c65d4aa5.js +11 -0
  317. package/web/.next/static/chunks/59a0709f1b080353.js +1 -0
  318. package/web/.next/static/chunks/5f6161ceb4263319.js +1 -0
  319. package/web/.next/static/chunks/77ff1b7b725b7780.js +1 -0
  320. package/web/.next/static/chunks/{672e3da3ad26005b.js → 98e3a7cf58fc912a.js} +1 -1
  321. package/web/.next/static/chunks/9af45e885bd4ccef.js +1 -0
  322. package/web/.next/static/chunks/a57dc2afcf67304a.js +1 -0
  323. package/web/.next/static/chunks/b4f502a76ba10e4b.js +1 -0
  324. package/web/.next/static/chunks/b5d8e8100e310d9f.css +1 -0
  325. package/web/.next/static/chunks/{df85e52b1afb7340.js → b747e59ebdcbd917.js} +1 -1
  326. package/web/.next/static/chunks/c04ce6760f349f3e.js +1 -0
  327. package/web/.next/static/chunks/{78ab7b134f0649ac.js → c3c68de2392a9071.js} +1 -1
  328. package/web/.next/static/chunks/c7e793951b20a67f.js +1 -0
  329. package/web/.next/static/chunks/cf30e300568abf0f.js +1 -0
  330. package/web/.next/static/chunks/d43dff89384fb60a.js +1 -0
  331. package/web/.next/static/chunks/{37ac7fe1cd493293.js → e087f3e5c46c0756.js} +1 -1
  332. package/web/.next/static/chunks/{turbopack-426d9bc2450816ba.js → turbopack-b1685b5f87ad1d60.js} +1 -1
  333. package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js +0 -3
  334. package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js.map +0 -1
  335. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +0 -4
  336. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +0 -4
  337. package/web/.next/server/chunks/ssr/[root-of-the-server]__8c553503._.js +0 -4
  338. package/web/.next/server/chunks/ssr/[root-of-the-server]__9f155c0e._.js +0 -3
  339. package/web/.next/server/chunks/ssr/[root-of-the-server]__9f155c0e._.js.map +0 -1
  340. package/web/.next/server/chunks/ssr/[root-of-the-server]__a022445f._.js +0 -4
  341. package/web/.next/server/chunks/ssr/[root-of-the-server]__a7de2711._.js +0 -4
  342. package/web/.next/server/chunks/ssr/_0dc2cfd3._.js +0 -3
  343. package/web/.next/server/chunks/ssr/_0dc2cfd3._.js.map +0 -1
  344. package/web/.next/server/chunks/ssr/_1bb131c4._.js.map +0 -1
  345. package/web/.next/server/chunks/ssr/_1bb79fe8._.js +0 -3
  346. package/web/.next/server/chunks/ssr/_1bb79fe8._.js.map +0 -1
  347. package/web/.next/server/chunks/ssr/_469c5451._.js +0 -3
  348. package/web/.next/server/chunks/ssr/_469c5451._.js.map +0 -1
  349. package/web/.next/server/chunks/ssr/_6d26a08f._.js +0 -3
  350. package/web/.next/server/chunks/ssr/_6d26a08f._.js.map +0 -1
  351. package/web/.next/server/chunks/ssr/_75f4ccb3._.js +0 -3
  352. package/web/.next/server/chunks/ssr/_75f4ccb3._.js.map +0 -1
  353. package/web/.next/server/chunks/ssr/_92d851b4._.js.map +0 -1
  354. package/web/.next/server/chunks/ssr/_b294a667._.js +0 -3
  355. package/web/.next/server/chunks/ssr/_b5fc318a._.js +0 -3
  356. package/web/.next/server/chunks/ssr/_b5fc318a._.js.map +0 -1
  357. package/web/.next/server/chunks/ssr/_f1a649e3._.js +0 -9
  358. package/web/.next/server/chunks/ssr/_f1a649e3._.js.map +0 -1
  359. package/web/.next/server/chunks/ssr/node_modules__pnpm_b59e4b16._.js +0 -3
  360. package/web/.next/server/chunks/ssr/node_modules__pnpm_b59e4b16._.js.map +0 -1
  361. package/web/.next/static/chunks/0d2af96e64960ef5.css +0 -1
  362. package/web/.next/static/chunks/11e4439096f8d652.js +0 -1
  363. package/web/.next/static/chunks/303a1217006489b9.js +0 -1
  364. package/web/.next/static/chunks/4562ee849ea13c3a.js +0 -1
  365. package/web/.next/static/chunks/845d8e58a91014e6.js +0 -1
  366. package/web/.next/static/chunks/84a181ff3270fd9f.js +0 -1
  367. package/web/.next/static/chunks/96eeeb28e06de78c.js +0 -1
  368. package/web/.next/static/chunks/9df4681de92ebfc3.js +0 -11
  369. package/web/.next/static/chunks/cca0f5112a9260d8.js +0 -1
  370. package/web/.next/static/chunks/e2ef95d904c360f3.js +0 -1
  371. package/web/.next/static/chunks/e6a2fb8707e079ff.js +0 -1
  372. package/web/.next/static/chunks/e9c3fbbeb418cbfa.js +0 -1
  373. package/web/.next/static/chunks/ed3a602003bcb31b.js +0 -1
  374. /package/web/.next/server/chunks/{[root-of-the-server]__53013576._.js.map → [root-of-the-server]__7d63f9a4._.js.map} +0 -0
  375. /package/web/.next/server/chunks/{[root-of-the-server]__92078db6._.js.map → [root-of-the-server]__a1c7c02a._.js.map} +0 -0
  376. /package/web/.next/static/{hsK1x0unrjI_pUsvQhn6P → svtG6xX1MdaGWkml8eX53}/_buildManifest.js +0 -0
  377. /package/web/.next/static/{hsK1x0unrjI_pUsvQhn6P → svtG6xX1MdaGWkml8eX53}/_clientMiddlewareManifest.json +0 -0
  378. /package/web/.next/static/{hsK1x0unrjI_pUsvQhn6P → svtG6xX1MdaGWkml8eX53}/_ssgManifest.js +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-webhook.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/webhook/github-webhook.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,uBAAuB,EACxB,MAAM,yEAAyE,CAAC;AACjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gFAAgF,CAAC;AACzH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wEAAwE,CAAC;AAC5G,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8EAA8E,CAAC;AASzH,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAEpE,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,qBAAa,oBAAqB,YAAW,eAAe;IAC1D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;IAC7C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAuB;IAC3D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA2B;IAC9D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA+B;IAC/D,OAAO,CAAC,aAAa,CAAS;gBAG5B,WAAW,EAAE,kBAAkB,EAC/B,YAAY,EAAE,aAAa,EAC3B,mBAAmB,EAAE,oBAAoB,EACzC,MAAM,EAAE,YAAY;IAStB;;;OAGG;IACH,SAAS,IAAI,MAAM;IAInB;;OAEG;IACH,qBAAqB,IAAI,SAAS,iBAAiB,EAAE;IAIrD;;OAEG;IACH,kBAAkB,IAAI,SAAS,qBAAqB,EAAE;IAIhD,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBlD,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkC/C,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IA4BrC,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,uBAAuB;IAgCxF,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IA4CrD,OAAO,CAAC,cAAc;YAOR,sBAAsB;YAsBtB,qBAAqB;YAiBrB,mBAAmB;YAoBnB,uBAAuB;YAWvB,mBAAmB;YAKnB,qBAAqB;YA6CrB,qBAAqB;YA4BrB,sBAAsB;YAqDtB,eAAe;CAe9B"}
@@ -0,0 +1,372 @@
1
+ /**
2
+ * GitHub Webhook Service
3
+ *
4
+ * Manages GitHub webhook registration and incoming event processing.
5
+ * Uses the GitHub CLI (`gh api`) for webhook CRUD operations.
6
+ *
7
+ * Webhook events supplement the existing PR sync polling:
8
+ * - Webhooks provide near-instant event delivery
9
+ * - Polling remains as a fallback for missed events
10
+ *
11
+ * Registered events: pull_request, check_suite, check_run
12
+ */
13
+ import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
14
+ import { SdlcLifecycle, PrStatus, CiStatus } from '../../../domain/generated/output.js';
15
+ import { NotificationEventType, NotificationSeverity } from '../../../domain/generated/output.js';
16
+ const TAG = '[GitHubWebhook]';
17
+ const WEBHOOK_EVENTS = ['pull_request', 'check_suite', 'check_run'];
18
+ const MAX_EVENT_HISTORY = 200;
19
+ export class GitHubWebhookService {
20
+ featureRepo;
21
+ gitPrService;
22
+ notificationService;
23
+ execFn;
24
+ registeredWebhooks = [];
25
+ deliveryHistory = [];
26
+ webhookSecret;
27
+ constructor(featureRepo, gitPrService, notificationService, execFn) {
28
+ this.featureRepo = featureRepo;
29
+ this.gitPrService = gitPrService;
30
+ this.notificationService = notificationService;
31
+ this.execFn = execFn;
32
+ this.webhookSecret = randomBytes(32).toString('hex');
33
+ }
34
+ /**
35
+ * Get the webhook secret for signature validation.
36
+ * Exposed so the API route can validate incoming requests.
37
+ */
38
+ getSecret() {
39
+ return this.webhookSecret;
40
+ }
41
+ /**
42
+ * Get the list of registered webhooks (for dashboard display).
43
+ */
44
+ getRegisteredWebhooks() {
45
+ return this.registeredWebhooks;
46
+ }
47
+ /**
48
+ * Get recent delivery history (newest first).
49
+ */
50
+ getDeliveryHistory() {
51
+ return this.deliveryHistory;
52
+ }
53
+ async registerWebhooks(publicUrl) {
54
+ const webhookUrl = `${publicUrl}/api/webhooks/github`;
55
+ // Find all repos with features in Review lifecycle
56
+ const features = await this.featureRepo.list({ lifecycle: SdlcLifecycle.Review });
57
+ const repoPaths = new Set();
58
+ for (const feature of features) {
59
+ if (feature.repositoryPath) {
60
+ repoPaths.add(feature.repositoryPath);
61
+ }
62
+ }
63
+ for (const repoPath of repoPaths) {
64
+ await this.registerWebhookForRepo(repoPath, webhookUrl);
65
+ }
66
+ // eslint-disable-next-line no-console
67
+ console.log(`${TAG} Registered webhooks for ${this.registeredWebhooks.length} repositories`);
68
+ }
69
+ async updateWebhookUrl(newUrl) {
70
+ const webhookUrl = `${newUrl}/api/webhooks/github`;
71
+ for (const webhook of this.registeredWebhooks) {
72
+ try {
73
+ await this.execFn('gh', [
74
+ 'api',
75
+ '--method',
76
+ 'PATCH',
77
+ `-H`,
78
+ 'Accept: application/vnd.github+json',
79
+ `/repos/${webhook.repoFullName}/hooks/${webhook.webhookId}`,
80
+ '-f',
81
+ `config[url]=${webhookUrl}`,
82
+ '-f',
83
+ `config[content_type]=json`,
84
+ '-f',
85
+ `config[secret]=${this.webhookSecret}`,
86
+ ], { cwd: webhook.repositoryPath });
87
+ // eslint-disable-next-line no-console
88
+ console.log(`${TAG} Updated webhook URL for ${webhook.repoFullName}`);
89
+ }
90
+ catch (error) {
91
+ const msg = error instanceof Error ? error.message : String(error);
92
+ // eslint-disable-next-line no-console
93
+ console.warn(`${TAG} Failed to update webhook for ${webhook.repoFullName}: ${msg}`);
94
+ }
95
+ }
96
+ }
97
+ async removeWebhooks() {
98
+ for (const webhook of this.registeredWebhooks) {
99
+ try {
100
+ await this.execFn('gh', [
101
+ 'api',
102
+ '--method',
103
+ 'DELETE',
104
+ `-H`,
105
+ 'Accept: application/vnd.github+json',
106
+ `/repos/${webhook.repoFullName}/hooks/${webhook.webhookId}`,
107
+ ], { cwd: webhook.repositoryPath });
108
+ // eslint-disable-next-line no-console
109
+ console.log(`${TAG} Removed webhook for ${webhook.repoFullName}`);
110
+ }
111
+ catch (error) {
112
+ const msg = error instanceof Error ? error.message : String(error);
113
+ // eslint-disable-next-line no-console
114
+ console.warn(`${TAG} Failed to remove webhook for ${webhook.repoFullName}: ${msg}`);
115
+ }
116
+ }
117
+ this.registeredWebhooks.length = 0;
118
+ }
119
+ validateSignature(payload, signature, secret) {
120
+ if (!signature) {
121
+ return { valid: false, error: 'Missing signature header' };
122
+ }
123
+ const parts = signature.split('=');
124
+ if (parts.length !== 2 || parts[0] !== 'sha256') {
125
+ return { valid: false, error: 'Invalid signature format (expected sha256=...)' };
126
+ }
127
+ const expected = createHmac('sha256', secret).update(payload).digest('hex');
128
+ const actual = parts[1];
129
+ // Use timing-safe comparison to prevent timing attacks
130
+ try {
131
+ const expectedBuf = Buffer.from(expected, 'hex');
132
+ const actualBuf = Buffer.from(actual, 'hex');
133
+ if (expectedBuf.length !== actualBuf.length) {
134
+ return { valid: false, error: 'Signature length mismatch' };
135
+ }
136
+ if (!timingSafeEqual(expectedBuf, actualBuf)) {
137
+ return { valid: false, error: 'Signature mismatch' };
138
+ }
139
+ return { valid: true };
140
+ }
141
+ catch {
142
+ return { valid: false, error: 'Invalid signature encoding' };
143
+ }
144
+ }
145
+ async handleEvent(event) {
146
+ const startTime = Date.now();
147
+ // eslint-disable-next-line no-console
148
+ console.log(`${TAG} Received ${event.source}/${event.eventType} (delivery: ${event.deliveryId})`);
149
+ let status = 'success';
150
+ let statusMessage = 'Processed successfully';
151
+ try {
152
+ switch (event.eventType) {
153
+ case 'pull_request':
154
+ await this.handlePullRequestEvent(event.payload);
155
+ break;
156
+ case 'check_suite':
157
+ await this.handleCheckSuiteEvent(event.payload);
158
+ break;
159
+ case 'check_run':
160
+ await this.handleCheckRunEvent(event.payload);
161
+ break;
162
+ default:
163
+ status = 'ignored';
164
+ statusMessage = `Unhandled event type: ${event.eventType}`;
165
+ // eslint-disable-next-line no-console
166
+ console.log(`${TAG} Ignoring unhandled event type: ${event.eventType}`);
167
+ }
168
+ }
169
+ catch (error) {
170
+ status = 'error';
171
+ statusMessage = error instanceof Error ? error.message : String(error);
172
+ }
173
+ this.recordDelivery({
174
+ deliveryId: event.deliveryId,
175
+ eventType: event.eventType,
176
+ source: event.source,
177
+ receivedAt: new Date().toISOString(),
178
+ status,
179
+ statusMessage,
180
+ durationMs: Date.now() - startTime,
181
+ payload: event.payload,
182
+ });
183
+ }
184
+ recordDelivery(record) {
185
+ this.deliveryHistory.unshift(record);
186
+ if (this.deliveryHistory.length > MAX_EVENT_HISTORY) {
187
+ this.deliveryHistory.length = MAX_EVENT_HISTORY;
188
+ }
189
+ }
190
+ async handlePullRequestEvent(payload) {
191
+ const action = payload.action;
192
+ const pr = payload.pull_request;
193
+ if (!pr)
194
+ return;
195
+ const prNumber = pr.number;
196
+ const prUrl = pr.html_url ?? '';
197
+ const headBranch = pr.head?.ref;
198
+ // Find feature by PR number or branch
199
+ const feature = await this.findFeatureByPrOrBranch(prNumber, headBranch);
200
+ if (!feature)
201
+ return;
202
+ if (action === 'closed' && pr.merged === true) {
203
+ await this.updateFeaturePrStatus(feature, PrStatus.Merged, prNumber, prUrl);
204
+ }
205
+ else if (action === 'closed') {
206
+ await this.updateFeaturePrStatus(feature, PrStatus.Closed, prNumber, prUrl);
207
+ }
208
+ else if (action === 'reopened') {
209
+ await this.updateFeaturePrStatus(feature, PrStatus.Open, prNumber, prUrl);
210
+ }
211
+ }
212
+ async handleCheckSuiteEvent(payload) {
213
+ const action = payload.action;
214
+ if (action !== 'completed')
215
+ return;
216
+ const checkSuite = payload.check_suite;
217
+ if (!checkSuite)
218
+ return;
219
+ const conclusion = checkSuite.conclusion;
220
+ const headBranch = checkSuite.head_branch;
221
+ const feature = await this.findFeatureByBranch(headBranch);
222
+ if (!feature)
223
+ return;
224
+ const ciStatus = conclusion === 'success' ? CiStatus.Success : CiStatus.Failure;
225
+ await this.updateFeatureCiStatus(feature, ciStatus);
226
+ }
227
+ async handleCheckRunEvent(payload) {
228
+ const action = payload.action;
229
+ if (action !== 'completed')
230
+ return;
231
+ const checkRun = payload.check_run;
232
+ if (!checkRun)
233
+ return;
234
+ const conclusion = checkRun.conclusion;
235
+ const checkSuite = checkRun.check_suite;
236
+ const headBranch = checkSuite?.head_branch;
237
+ if (!headBranch)
238
+ return;
239
+ const feature = await this.findFeatureByBranch(headBranch);
240
+ if (!feature)
241
+ return;
242
+ const ciStatus = conclusion === 'success' ? CiStatus.Success : CiStatus.Failure;
243
+ await this.updateFeatureCiStatus(feature, ciStatus);
244
+ }
245
+ async findFeatureByPrOrBranch(prNumber, branch) {
246
+ const features = await this.featureRepo.list({ lifecycle: SdlcLifecycle.Review });
247
+ // Try matching by PR number first
248
+ const byPr = features.find((f) => f.pr?.number === prNumber);
249
+ if (byPr)
250
+ return byPr;
251
+ // Fall back to branch matching
252
+ return features.find((f) => f.branch === branch) ?? null;
253
+ }
254
+ async findFeatureByBranch(branch) {
255
+ const features = await this.featureRepo.list({ lifecycle: SdlcLifecycle.Review });
256
+ return features.find((f) => f.branch === branch) ?? null;
257
+ }
258
+ async updateFeaturePrStatus(feature, status, prNumber, prUrl) {
259
+ const oldStatus = feature.pr?.status;
260
+ if (oldStatus === status)
261
+ return;
262
+ feature.pr = { ...feature.pr, status, url: prUrl, number: prNumber };
263
+ if (status === PrStatus.Merged) {
264
+ feature.lifecycle = SdlcLifecycle.Maintain;
265
+ }
266
+ await this.featureRepo.update(feature);
267
+ // Emit notification
268
+ const eventType = status === PrStatus.Merged
269
+ ? NotificationEventType.PrMerged
270
+ : status === PrStatus.Closed
271
+ ? NotificationEventType.PrClosed
272
+ : NotificationEventType.PrChecksPassed; // reopened
273
+ const severity = status === PrStatus.Merged
274
+ ? NotificationSeverity.Success
275
+ : status === PrStatus.Closed
276
+ ? NotificationSeverity.Warning
277
+ : NotificationSeverity.Info;
278
+ const event = {
279
+ eventType,
280
+ featureId: feature.id,
281
+ agentRunId: feature.agentRunId ?? '',
282
+ featureName: feature.name,
283
+ message: `PR #${prNumber} ${status.toLowerCase()} for ${feature.name} (via webhook)`,
284
+ severity,
285
+ timestamp: new Date().toISOString(),
286
+ };
287
+ this.notificationService.notify(event);
288
+ }
289
+ async updateFeatureCiStatus(feature, ciStatus) {
290
+ if (!feature.pr)
291
+ return;
292
+ if (feature.pr.ciStatus === ciStatus)
293
+ return;
294
+ feature.pr = { ...feature.pr, ciStatus };
295
+ await this.featureRepo.update(feature);
296
+ const eventType = ciStatus === CiStatus.Success
297
+ ? NotificationEventType.PrChecksPassed
298
+ : NotificationEventType.PrChecksFailed;
299
+ const severity = ciStatus === CiStatus.Success ? NotificationSeverity.Success : NotificationSeverity.Error;
300
+ const event = {
301
+ eventType,
302
+ featureId: feature.id,
303
+ agentRunId: feature.agentRunId ?? '',
304
+ featureName: feature.name,
305
+ message: `CI ${ciStatus === CiStatus.Success ? 'passed' : 'failed'} for ${feature.name} (via webhook)`,
306
+ severity,
307
+ timestamp: new Date().toISOString(),
308
+ };
309
+ this.notificationService.notify(event);
310
+ }
311
+ async registerWebhookForRepo(repoPath, webhookUrl) {
312
+ try {
313
+ // Get the repo full name (owner/repo) from the remote URL
314
+ const repoFullName = await this.getRepoFullName(repoPath);
315
+ if (!repoFullName) {
316
+ // eslint-disable-next-line no-console
317
+ console.warn(`${TAG} Could not determine repo name for ${repoPath}`);
318
+ return;
319
+ }
320
+ // Create webhook via GitHub API
321
+ const { stdout } = await this.execFn('gh', [
322
+ 'api',
323
+ '--method',
324
+ 'POST',
325
+ `-H`,
326
+ 'Accept: application/vnd.github+json',
327
+ `/repos/${repoFullName}/hooks`,
328
+ '-f',
329
+ 'name=web',
330
+ '-f',
331
+ `config[url]=${webhookUrl}`,
332
+ '-f',
333
+ 'config[content_type]=json',
334
+ '-f',
335
+ `config[secret]=${this.webhookSecret}`,
336
+ ...WEBHOOK_EVENTS.flatMap((e) => ['-f', `events[]=${e}`]),
337
+ '-F',
338
+ 'active=true',
339
+ ], { cwd: repoPath });
340
+ const response = JSON.parse(stdout);
341
+ const webhookId = response.id;
342
+ this.registeredWebhooks.push({
343
+ repoFullName,
344
+ webhookId,
345
+ repositoryPath: repoPath,
346
+ });
347
+ // eslint-disable-next-line no-console
348
+ console.log(`${TAG} Registered webhook #${webhookId} for ${repoFullName}`);
349
+ }
350
+ catch (error) {
351
+ const msg = error instanceof Error ? error.message : String(error);
352
+ // eslint-disable-next-line no-console
353
+ console.warn(`${TAG} Failed to register webhook for ${repoPath}: ${msg}`);
354
+ }
355
+ }
356
+ async getRepoFullName(repoPath) {
357
+ try {
358
+ const remoteUrl = await this.gitPrService.getRemoteUrl(repoPath);
359
+ if (!remoteUrl)
360
+ return null;
361
+ // Parse owner/repo from URL
362
+ // Handles both https://github.com/owner/repo and git@github.com:owner/repo.git
363
+ const match = remoteUrl.match(/github\.com[/:]([\w.-]+)\/([\w.-]+?)(?:\.git)?$/);
364
+ if (!match)
365
+ return null;
366
+ return `${match[1]}/${match[2]}`;
367
+ }
368
+ catch {
369
+ return null;
370
+ }
371
+ }
372
+ }
@@ -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":"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"}