@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.
- package/dist/packages/core/src/application/ports/output/services/index.d.ts +2 -0
- package/dist/packages/core/src/application/ports/output/services/index.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/tunnel-service.interface.d.ts +41 -0
- package/dist/packages/core/src/application/ports/output/services/tunnel-service.interface.d.ts.map +1 -0
- package/dist/packages/core/src/application/ports/output/services/tunnel-service.interface.js +14 -0
- package/dist/packages/core/src/application/ports/output/services/webhook-service.interface.d.ts +65 -0
- package/dist/packages/core/src/application/ports/output/services/webhook-service.interface.d.ts.map +1 -0
- package/dist/packages/core/src/application/ports/output/services/webhook-service.interface.js +10 -0
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +14 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.js +21 -4
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.d.ts +7 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.js +24 -2
- package/dist/packages/core/src/infrastructure/services/tunnel/cloudflare-tunnel.service.d.ts +55 -0
- package/dist/packages/core/src/infrastructure/services/tunnel/cloudflare-tunnel.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/tunnel/cloudflare-tunnel.service.js +203 -0
- package/dist/packages/core/src/infrastructure/services/webhook/github-webhook.service.d.ts +75 -0
- package/dist/packages/core/src/infrastructure/services/webhook/github-webhook.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/webhook/github-webhook.service.js +372 -0
- package/dist/packages/core/src/infrastructure/services/webhook/webhook-manager.service.d.ts +82 -0
- package/dist/packages/core/src/infrastructure/services/webhook/webhook-manager.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/webhook/webhook-manager.service.js +206 -0
- package/dist/src/presentation/cli/commands/ui.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/ui.command.js +15 -0
- package/dist/src/presentation/web/app/actions/load-webhook-status.d.ts +3 -0
- package/dist/src/presentation/web/app/actions/load-webhook-status.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/load-webhook-status.js +19 -0
- package/dist/src/presentation/web/app/api/webhooks/deliveries/route.d.ts +9 -0
- package/dist/src/presentation/web/app/api/webhooks/deliveries/route.d.ts.map +1 -0
- package/dist/src/presentation/web/app/api/webhooks/deliveries/route.js +27 -0
- package/dist/src/presentation/web/app/api/webhooks/github/route.d.ts +17 -0
- package/dist/src/presentation/web/app/api/webhooks/github/route.d.ts.map +1 -0
- package/dist/src/presentation/web/app/api/webhooks/github/route.js +70 -0
- package/dist/src/presentation/web/app/api/webhooks/status/route.d.ts +9 -0
- package/dist/src/presentation/web/app/api/webhooks/status/route.d.ts.map +1 -0
- package/dist/src/presentation/web/app/api/webhooks/status/route.js +26 -0
- package/dist/src/presentation/web/app/webhooks/page.d.ts +4 -0
- package/dist/src/presentation/web/app/webhooks/page.d.ts.map +1 -0
- package/dist/src/presentation/web/app/webhooks/page.js +9 -0
- package/dist/src/presentation/web/components/features/webhooks/types.d.ts +32 -0
- package/dist/src/presentation/web/components/features/webhooks/types.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/webhooks/types.js +1 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.d.ts +6 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.js +38 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.stories.d.ts +9 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.stories.js +69 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.d.ts +7 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.js +11 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.stories.d.ts +9 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.stories.js +31 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.d.ts +6 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.js +21 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.stories.d.ts +9 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.stories.js +56 -0
- package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.d.ts +6 -0
- package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.js +39 -0
- package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.stories.d.ts +8 -0
- package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.stories.js +59 -0
- package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.d.ts.map +1 -1
- package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.js +2 -2
- package/dist/src/presentation/web/dev-server.js +20 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +3 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/app-path-routes-manifest.json +5 -1
- package/web/.next/build-manifest.json +6 -6
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +3 -3
- package/web/.next/required-server-files.json +3 -3
- package/web/.next/routes-manifest.json +24 -0
- package/web/.next/server/app/(dashboard)/@drawer/create/page/build-manifest.json +4 -4
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +22 -22
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/build-manifest.json +4 -4
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/build-manifest.json +4 -4
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/build-manifest.json +4 -4
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page/build-manifest.json +4 -4
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +22 -22
- package/web/.next/server/app/(dashboard)/create/page.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/build-manifest.json +4 -4
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/build-manifest.json +4 -4
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page/build-manifest.json +4 -4
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +20 -20
- package/web/.next/server/app/(dashboard)/page.js +1 -1
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/build-manifest.json +4 -4
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error/page/build-manifest.json +4 -4
- package/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/build-manifest.json +4 -4
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/_not-found/page.js +1 -1
- package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/api/attachments/preview/route.js +1 -1
- package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
- package/web/.next/server/app/api/evidence/route.js +1 -1
- package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
- package/web/.next/server/app/api/graph-data/route.js +1 -1
- package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
- package/web/.next/server/app/api/webhooks/deliveries/route/app-paths-manifest.json +3 -0
- package/web/.next/server/app/api/webhooks/deliveries/route/build-manifest.json +11 -0
- package/web/.next/server/app/api/webhooks/deliveries/route/server-reference-manifest.json +4 -0
- package/web/.next/server/app/api/webhooks/deliveries/route.js +6 -0
- package/web/.next/server/app/api/webhooks/deliveries/route.js.map +5 -0
- package/web/.next/server/app/api/webhooks/deliveries/route.js.nft.json +1 -0
- package/web/.next/server/app/api/webhooks/deliveries/route_client-reference-manifest.js +2 -0
- package/web/.next/server/app/api/webhooks/github/route/app-paths-manifest.json +3 -0
- package/web/.next/server/app/api/webhooks/github/route/build-manifest.json +11 -0
- package/web/.next/server/app/api/webhooks/github/route/server-reference-manifest.json +4 -0
- package/web/.next/server/app/api/webhooks/github/route.js +6 -0
- package/web/.next/server/app/api/webhooks/github/route.js.map +5 -0
- package/web/.next/server/app/api/webhooks/github/route.js.nft.json +1 -0
- package/web/.next/server/app/api/webhooks/github/route_client-reference-manifest.js +2 -0
- package/web/.next/server/app/api/webhooks/status/route/app-paths-manifest.json +3 -0
- package/web/.next/server/app/api/webhooks/status/route/build-manifest.json +11 -0
- package/web/.next/server/app/api/webhooks/status/route/server-reference-manifest.json +4 -0
- package/web/.next/server/app/api/webhooks/status/route.js +6 -0
- package/web/.next/server/app/api/webhooks/status/route.js.map +5 -0
- package/web/.next/server/app/api/webhooks/status/route.js.nft.json +1 -0
- package/web/.next/server/app/api/webhooks/status/route_client-reference-manifest.js +2 -0
- package/web/.next/server/app/settings/page/build-manifest.json +4 -4
- package/web/.next/server/app/settings/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/settings/page.js +1 -1
- package/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/build-manifest.json +4 -4
- package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/skills/page.js +1 -1
- package/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/build-manifest.json +4 -4
- package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/tools/page.js +1 -1
- package/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/build-manifest.json +4 -4
- package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/version/page.js +2 -2
- package/web/.next/server/app/version/page.js.nft.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/webhooks/page/app-paths-manifest.json +3 -0
- package/web/.next/server/app/webhooks/page/build-manifest.json +18 -0
- package/web/.next/server/app/webhooks/page/next-font-manifest.json +6 -0
- package/web/.next/server/app/webhooks/page/react-loadable-manifest.json +1 -0
- package/web/.next/server/app/webhooks/page/server-reference-manifest.json +35 -0
- package/web/.next/server/app/webhooks/page.js +16 -0
- package/web/.next/server/app/webhooks/page.js.map +5 -0
- package/web/.next/server/app/webhooks/page.js.nft.json +1 -0
- package/web/.next/server/app/webhooks/page_client-reference-manifest.js +2 -0
- package/web/.next/server/app-paths-manifest.json +5 -1
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_deliveries_route_actions_d9e34c8d.js +3 -0
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_deliveries_route_actions_d9e34c8d.js.map +1 -0
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_github_route_actions_1b0d0c38.js +3 -0
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_github_route_actions_1b0d0c38.js.map +1 -0
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_status_route_actions_1a0d86a1.js +3 -0
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_status_route_actions_1a0d86a1.js.map +1 -0
- package/web/.next/server/chunks/[root-of-the-server]__15e5d45c._.js +3 -0
- package/web/.next/server/chunks/[root-of-the-server]__15e5d45c._.js.map +1 -0
- package/web/.next/server/chunks/[root-of-the-server]__23be381e._.js +3 -0
- package/web/.next/server/chunks/[root-of-the-server]__23be381e._.js.map +1 -0
- package/web/.next/server/chunks/{[root-of-the-server]__42b7ab55._.js → [root-of-the-server]__3baec744._.js} +2 -2
- package/web/.next/server/chunks/{[root-of-the-server]__42b7ab55._.js.map → [root-of-the-server]__3baec744._.js.map} +1 -1
- package/web/.next/server/chunks/{[root-of-the-server]__53013576._.js → [root-of-the-server]__7d63f9a4._.js} +2 -2
- package/web/.next/server/chunks/[root-of-the-server]__9fc760c0._.js +3 -0
- package/web/.next/server/chunks/[root-of-the-server]__9fc760c0._.js.map +1 -0
- package/web/.next/server/chunks/{[root-of-the-server]__92078db6._.js → [root-of-the-server]__a1c7c02a._.js} +2 -2
- package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_activity_22f9667f.js +3 -0
- package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_activity_22f9667f.js.map +1 -0
- package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_rocket_1575cd4d.js +3 -0
- package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_rocket_1575cd4d.js.map +1 -0
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js +4 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__6b17a22d._.js.map → [root-of-the-server]__11033878._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__06fef644._.js → [root-of-the-server]__12c2ab7d._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__06fef644._.js.map → [root-of-the-server]__12c2ab7d._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2698e9f4._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2698e9f4._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__3c16bf85._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__3c16bf85._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__610f06df._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__610f06df._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__76915230._.js +4 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__8c553503._.js.map → [root-of-the-server]__76915230._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7a939e4e._.js +4 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__a022445f._.js.map → [root-of-the-server]__7a939e4e._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__87a7ae30._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__87a7ae30._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8e3bf5d7._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8e3bf5d7._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__920dccd5._.js +4 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__920dccd5._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c07f9f79._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c07f9f79._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c4dc1b5a._.js +4 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__a7de2711._.js.map → [root-of-the-server]__c4dc1b5a._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c605a375._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c605a375._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js +4 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__804c006d._.js.map → [root-of-the-server]__fdc75809._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_07f57bd0._.js +3 -0
- package/web/.next/server/chunks/ssr/_07f57bd0._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
- package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_15a756dd._.js +3 -0
- package/web/.next/server/chunks/ssr/_15a756dd._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_26b2c311._.js +3 -0
- package/web/.next/server/chunks/ssr/_26b2c311._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_2f6f48b8._.js +1 -1
- package/web/.next/server/chunks/ssr/_2f6f48b8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_92d851b4._.js → _3d1ed2a7._.js} +2 -2
- package/web/.next/server/chunks/ssr/_3d1ed2a7._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_3eca2297._.js +3 -0
- package/web/.next/server/chunks/ssr/{_b294a667._.js.map → _3eca2297._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_4470c218._.js +3 -0
- package/web/.next/server/chunks/ssr/_4470c218._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_462cc3a6._.js +3 -0
- package/web/.next/server/chunks/ssr/_462cc3a6._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_961cb4b2._.js +3 -0
- package/web/.next/server/chunks/ssr/_961cb4b2._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_a4899a76._.js +3 -0
- package/web/.next/server/chunks/ssr/_a4899a76._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_b5babdfc._.js +9 -0
- package/web/.next/server/chunks/ssr/_b5babdfc._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_b7eb93fc._.js +4 -0
- package/web/.next/server/chunks/ssr/_b7eb93fc._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
- package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_f8b36e2c._.js +3 -0
- package/web/.next/server/chunks/ssr/_f8b36e2c._.js.map +1 -0
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_webhooks_webhooks-page-client_tsx_b2662ea3._.js +3 -0
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_webhooks_webhooks-page-client_tsx_b2662ea3._.js.map +1 -0
- package/web/.next/server/chunks/ssr/{_1bb131c4._.js → node_modules__pnpm_747b43ac._.js} +2 -2
- package/web/.next/server/chunks/ssr/node_modules__pnpm_747b43ac._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_5f039db1._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_5f039db1._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_c4337169._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_c4337169._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
- package/web/.next/server/middleware-build-manifest.js +4 -4
- package/web/.next/server/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +57 -35
- package/web/.next/static/chunks/0c76de69325ef923.js +1 -0
- package/web/.next/static/chunks/{658fc2f5f65cf3b5.js → 1b9d34af4064dafe.js} +2 -2
- package/web/.next/static/chunks/{50dd80c8aafa3b20.js → 293ccfbe777d995a.js} +1 -1
- package/web/.next/static/chunks/3835a408dbf8d0bb.js +1 -0
- package/web/.next/static/chunks/{941c13dcdb1978a4.js → 3f0773d9b56e04a2.js} +2 -2
- package/web/.next/static/chunks/40b6bcf1a2de4a0f.js +1 -0
- package/web/.next/static/chunks/4c5b31a2c65d4aa5.js +11 -0
- package/web/.next/static/chunks/59a0709f1b080353.js +1 -0
- package/web/.next/static/chunks/5f6161ceb4263319.js +1 -0
- package/web/.next/static/chunks/77ff1b7b725b7780.js +1 -0
- package/web/.next/static/chunks/{672e3da3ad26005b.js → 98e3a7cf58fc912a.js} +1 -1
- package/web/.next/static/chunks/9af45e885bd4ccef.js +1 -0
- package/web/.next/static/chunks/a57dc2afcf67304a.js +1 -0
- package/web/.next/static/chunks/b4f502a76ba10e4b.js +1 -0
- package/web/.next/static/chunks/b5d8e8100e310d9f.css +1 -0
- package/web/.next/static/chunks/{df85e52b1afb7340.js → b747e59ebdcbd917.js} +1 -1
- package/web/.next/static/chunks/c04ce6760f349f3e.js +1 -0
- package/web/.next/static/chunks/{78ab7b134f0649ac.js → c3c68de2392a9071.js} +1 -1
- package/web/.next/static/chunks/c7e793951b20a67f.js +1 -0
- package/web/.next/static/chunks/cf30e300568abf0f.js +1 -0
- package/web/.next/static/chunks/d43dff89384fb60a.js +1 -0
- package/web/.next/static/chunks/{37ac7fe1cd493293.js → e087f3e5c46c0756.js} +1 -1
- package/web/.next/static/chunks/{turbopack-426d9bc2450816ba.js → turbopack-b1685b5f87ad1d60.js} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8c553503._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9f155c0e._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9f155c0e._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a022445f._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a7de2711._.js +0 -4
- package/web/.next/server/chunks/ssr/_0dc2cfd3._.js +0 -3
- package/web/.next/server/chunks/ssr/_0dc2cfd3._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_1bb131c4._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_1bb79fe8._.js +0 -3
- package/web/.next/server/chunks/ssr/_1bb79fe8._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_469c5451._.js +0 -3
- package/web/.next/server/chunks/ssr/_469c5451._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_6d26a08f._.js +0 -3
- package/web/.next/server/chunks/ssr/_6d26a08f._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_75f4ccb3._.js +0 -3
- package/web/.next/server/chunks/ssr/_75f4ccb3._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_92d851b4._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_b294a667._.js +0 -3
- package/web/.next/server/chunks/ssr/_b5fc318a._.js +0 -3
- package/web/.next/server/chunks/ssr/_b5fc318a._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_f1a649e3._.js +0 -9
- package/web/.next/server/chunks/ssr/_f1a649e3._.js.map +0 -1
- package/web/.next/server/chunks/ssr/node_modules__pnpm_b59e4b16._.js +0 -3
- package/web/.next/server/chunks/ssr/node_modules__pnpm_b59e4b16._.js.map +0 -1
- package/web/.next/static/chunks/0d2af96e64960ef5.css +0 -1
- package/web/.next/static/chunks/11e4439096f8d652.js +0 -1
- package/web/.next/static/chunks/303a1217006489b9.js +0 -1
- package/web/.next/static/chunks/4562ee849ea13c3a.js +0 -1
- package/web/.next/static/chunks/845d8e58a91014e6.js +0 -1
- package/web/.next/static/chunks/84a181ff3270fd9f.js +0 -1
- package/web/.next/static/chunks/96eeeb28e06de78c.js +0 -1
- package/web/.next/static/chunks/9df4681de92ebfc3.js +0 -11
- package/web/.next/static/chunks/cca0f5112a9260d8.js +0 -1
- package/web/.next/static/chunks/e2ef95d904c360f3.js +0 -1
- package/web/.next/static/chunks/e6a2fb8707e079ff.js +0 -1
- package/web/.next/static/chunks/e9c3fbbeb418cbfa.js +0 -1
- package/web/.next/static/chunks/ed3a602003bcb31b.js +0 -1
- /package/web/.next/server/chunks/{[root-of-the-server]__53013576._.js.map → [root-of-the-server]__7d63f9a4._.js.map} +0 -0
- /package/web/.next/server/chunks/{[root-of-the-server]__92078db6._.js.map → [root-of-the-server]__a1c7c02a._.js.map} +0 -0
- /package/web/.next/static/{hsK1x0unrjI_pUsvQhn6P → svtG6xX1MdaGWkml8eX53}/_buildManifest.js +0 -0
- /package/web/.next/static/{hsK1x0unrjI_pUsvQhn6P → svtG6xX1MdaGWkml8eX53}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{hsK1x0unrjI_pUsvQhn6P → svtG6xX1MdaGWkml8eX53}/_ssgManifest.js +0 -0
|
@@ -17,4 +17,6 @@ export { GitPrError, GitPrErrorCode } from './git-pr-service.interface.js';
|
|
|
17
17
|
export type { IIdeLauncherService, LaunchIdeInput, LaunchIdeResult, LaunchIdeSuccess, LaunchIdeFailed, } from './ide-launcher-service.interface.js';
|
|
18
18
|
export type { IDaemonService, DaemonState } from './daemon-service.interface.js';
|
|
19
19
|
export type { IDeploymentService, DeploymentStatus } from './deployment-service.interface.js';
|
|
20
|
+
export type { ITunnelService, TunnelUrlChangeHandler } from './tunnel-service.interface.js';
|
|
21
|
+
export type { IWebhookService, WebhookEvent, WebhookValidationResult, } from './webhook-service.interface.js';
|
|
20
22
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AAClG,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,uCAAuC,CAAC;AAC/C,YAAY,EACV,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,iCAAiC,CAAC;AACzC,YAAY,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,YAAY,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACtF,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACnF,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,YAAY,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAChF,YAAY,EACV,aAAa,EACb,QAAQ,EACR,cAAc,EACd,WAAW,EACX,aAAa,EACb,cAAc,GACf,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC3E,YAAY,EACV,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,GAChB,MAAM,qCAAqC,CAAC;AAC7C,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjF,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AAClG,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,uCAAuC,CAAC;AAC/C,YAAY,EACV,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,iCAAiC,CAAC;AACzC,YAAY,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,YAAY,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACtF,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACnF,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,YAAY,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAChF,YAAY,EACV,aAAa,EACb,QAAQ,EACR,cAAc,EACd,WAAW,EACX,aAAa,EACb,cAAc,GACf,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC3E,YAAY,EACV,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,GAChB,MAAM,qCAAqC,CAAC;AAC7C,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjF,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC9F,YAAY,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5F,YAAY,EACV,eAAe,EACf,YAAY,EACZ,uBAAuB,GACxB,MAAM,gCAAgC,CAAC"}
|
package/dist/packages/core/src/application/ports/output/services/tunnel-service.interface.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tunnel Service Interface
|
|
3
|
+
*
|
|
4
|
+
* Output port for managing a reverse tunnel that exposes local endpoints
|
|
5
|
+
* to the public internet. Used to receive webhooks from external services
|
|
6
|
+
* (e.g., GitHub) when running locally.
|
|
7
|
+
*
|
|
8
|
+
* Implementations must:
|
|
9
|
+
* - Start a tunnel process pointing at a local port
|
|
10
|
+
* - Expose only a specific URL path (e.g., /api/webhooks)
|
|
11
|
+
* - Detect when the public URL changes (tunnel reconnection)
|
|
12
|
+
* - Support graceful shutdown
|
|
13
|
+
*/
|
|
14
|
+
export type TunnelUrlChangeHandler = (newUrl: string) => void | Promise<void>;
|
|
15
|
+
export interface ITunnelService {
|
|
16
|
+
/**
|
|
17
|
+
* Start the tunnel, exposing a local port to the internet.
|
|
18
|
+
*
|
|
19
|
+
* @param localPort - Local port to tunnel traffic to
|
|
20
|
+
* @returns The public URL assigned by the tunnel provider
|
|
21
|
+
*/
|
|
22
|
+
start(localPort: number): Promise<string>;
|
|
23
|
+
/**
|
|
24
|
+
* Stop the tunnel and clean up the child process.
|
|
25
|
+
*/
|
|
26
|
+
stop(): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Get the current public URL, or null if the tunnel is not running.
|
|
29
|
+
*/
|
|
30
|
+
getPublicUrl(): string | null;
|
|
31
|
+
/**
|
|
32
|
+
* Register a callback that fires when the tunnel URL changes
|
|
33
|
+
* (e.g., after a reconnection assigns a new random subdomain).
|
|
34
|
+
*/
|
|
35
|
+
onUrlChange(handler: TunnelUrlChangeHandler): void;
|
|
36
|
+
/**
|
|
37
|
+
* Whether the tunnel process is currently running.
|
|
38
|
+
*/
|
|
39
|
+
isRunning(): boolean;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=tunnel-service.interface.d.ts.map
|
package/dist/packages/core/src/application/ports/output/services/tunnel-service.interface.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel-service.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/tunnel-service.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE9E,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1C;;OAEG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;OAEG;IACH,YAAY,IAAI,MAAM,GAAG,IAAI,CAAC;IAE9B;;;OAGG;IACH,WAAW,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAEnD;;OAEG;IACH,SAAS,IAAI,OAAO,CAAC;CACtB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tunnel Service Interface
|
|
3
|
+
*
|
|
4
|
+
* Output port for managing a reverse tunnel that exposes local endpoints
|
|
5
|
+
* to the public internet. Used to receive webhooks from external services
|
|
6
|
+
* (e.g., GitHub) when running locally.
|
|
7
|
+
*
|
|
8
|
+
* Implementations must:
|
|
9
|
+
* - Start a tunnel process pointing at a local port
|
|
10
|
+
* - Expose only a specific URL path (e.g., /api/webhooks)
|
|
11
|
+
* - Detect when the public URL changes (tunnel reconnection)
|
|
12
|
+
* - Support graceful shutdown
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
package/dist/packages/core/src/application/ports/output/services/webhook-service.interface.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook Service Interface
|
|
3
|
+
*
|
|
4
|
+
* Output port for managing webhook registrations with external services
|
|
5
|
+
* (e.g., GitHub) and processing incoming webhook events.
|
|
6
|
+
*
|
|
7
|
+
* Works alongside the polling-based PrSyncWatcher to provide near-instant
|
|
8
|
+
* event delivery when a tunnel is available, with polling as fallback.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Parsed webhook event from an external service.
|
|
12
|
+
*/
|
|
13
|
+
export interface WebhookEvent {
|
|
14
|
+
/** Source service (e.g., 'github') */
|
|
15
|
+
source: string;
|
|
16
|
+
/** Event type (e.g., 'pull_request', 'check_suite') */
|
|
17
|
+
eventType: string;
|
|
18
|
+
/** Delivery ID for deduplication */
|
|
19
|
+
deliveryId: string;
|
|
20
|
+
/** Full event payload */
|
|
21
|
+
payload: Record<string, unknown>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Result of webhook signature validation.
|
|
25
|
+
*/
|
|
26
|
+
export interface WebhookValidationResult {
|
|
27
|
+
valid: boolean;
|
|
28
|
+
error?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface IWebhookService {
|
|
31
|
+
/**
|
|
32
|
+
* Register webhooks for all tracked repositories.
|
|
33
|
+
*
|
|
34
|
+
* @param publicUrl - The public tunnel URL where webhooks will be received
|
|
35
|
+
*/
|
|
36
|
+
registerWebhooks(publicUrl: string): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Update the webhook URL for all registered webhooks.
|
|
39
|
+
* Called when the tunnel reconnects with a new URL.
|
|
40
|
+
*
|
|
41
|
+
* @param newUrl - The new public tunnel URL
|
|
42
|
+
*/
|
|
43
|
+
updateWebhookUrl(newUrl: string): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Remove all registered webhooks (cleanup on shutdown).
|
|
46
|
+
*/
|
|
47
|
+
removeWebhooks(): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Validate an incoming webhook request signature.
|
|
50
|
+
*
|
|
51
|
+
* @param payload - Raw request body
|
|
52
|
+
* @param signature - Signature header value
|
|
53
|
+
* @param secret - The webhook secret used for HMAC
|
|
54
|
+
* @returns Validation result
|
|
55
|
+
*/
|
|
56
|
+
validateSignature(payload: string, signature: string, secret: string): WebhookValidationResult;
|
|
57
|
+
/**
|
|
58
|
+
* Process an incoming webhook event.
|
|
59
|
+
* Routes the event to the appropriate handler (e.g., PR status update).
|
|
60
|
+
*
|
|
61
|
+
* @param event - The parsed webhook event
|
|
62
|
+
*/
|
|
63
|
+
handleEvent(event: WebhookEvent): Promise<void>;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=webhook-service.interface.d.ts.map
|
package/dist/packages/core/src/application/ports/output/services/webhook-service.interface.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-service.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/webhook-service.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD;;;;;OAKG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhD;;OAEG;IACH,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhC;;;;;;;OAOG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,uBAAuB,CAAC;IAE/F;;;;;OAKG;IACH,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook Service Interface
|
|
3
|
+
*
|
|
4
|
+
* Output port for managing webhook registrations with external services
|
|
5
|
+
* (e.g., GitHub) and processing incoming webhook events.
|
|
6
|
+
*
|
|
7
|
+
* Works alongside the polling-based PrSyncWatcher to provide near-instant
|
|
8
|
+
* event delivery when a tunnel is available, with polling as fallback.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/src/infrastructure/di/container.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/src/infrastructure/di/container.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAwHrC;;;;;;GAMG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,OAAO,SAAS,CAAC,CA+UrE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -27,6 +27,8 @@ import { JsonDrivenIdeLauncherService } from '../services/ide-launchers/json-dri
|
|
|
27
27
|
import { DaemonPidService } from '../services/daemon/daemon-pid.service.js';
|
|
28
28
|
import { DeploymentService } from '../services/deployment/deployment.service.js';
|
|
29
29
|
import { AttachmentStorageService } from '../services/attachment-storage.service.js';
|
|
30
|
+
import { CloudflareTunnelService } from '../services/tunnel/cloudflare-tunnel.service.js';
|
|
31
|
+
import { GitHubWebhookService } from '../services/webhook/github-webhook.service.js';
|
|
30
32
|
import { AgentExecutorFactory } from '../services/agents/common/agent-executor-factory.service.js';
|
|
31
33
|
import { AgentExecutorProvider } from '../services/agents/common/agent-executor-provider.service.js';
|
|
32
34
|
import { StructuredAgentCallerService } from '../services/agents/common/structured-agent-caller.service.js';
|
|
@@ -170,6 +172,18 @@ export async function initializeContainer() {
|
|
|
170
172
|
container.register('AttachmentStorageService', { useToken: AttachmentStorageService });
|
|
171
173
|
const deploymentService = new DeploymentService();
|
|
172
174
|
container.registerInstance('IDeploymentService', deploymentService);
|
|
175
|
+
// Register tunnel and webhook services
|
|
176
|
+
container.register('ITunnelService', {
|
|
177
|
+
useFactory: () => new CloudflareTunnelService(),
|
|
178
|
+
});
|
|
179
|
+
container.register('IWebhookService', {
|
|
180
|
+
useFactory: (c) => {
|
|
181
|
+
const featureRepo = c.resolve('IFeatureRepository');
|
|
182
|
+
const gitPrService = c.resolve('IGitPrService');
|
|
183
|
+
const notifService = c.resolve('INotificationService');
|
|
184
|
+
return new GitHubWebhookService(featureRepo, gitPrService, notifService, execFn);
|
|
185
|
+
},
|
|
186
|
+
});
|
|
173
187
|
// Register agent infrastructure
|
|
174
188
|
container.register('IAgentRunRepository', {
|
|
175
189
|
useFactory: (c) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-agent-graph.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AAOpG,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"feature-agent-graph.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AAOpG,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAclF,OAAO,EAAE,sBAAsB,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE5E;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,cAAc,CAAC;IACzB,aAAa,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;CACjD;AAwID;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACrC,cAAc,EAAE,qBAAqB,GAAG,cAAc,EACtD,YAAY,CAAC,EAAE,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAgFnC"}
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.js
CHANGED
|
@@ -11,7 +11,7 @@ import { createRepairNode } from './nodes/repair.node.js';
|
|
|
11
11
|
import { validateSpecAnalyze, validateSpecRequirements } from './nodes/schemas/spec.schema.js';
|
|
12
12
|
import { validateResearch } from './nodes/schemas/research.schema.js';
|
|
13
13
|
import { validatePlan, validateTasks } from './nodes/schemas/plan.schema.js';
|
|
14
|
-
import { readSpecFile, safeYamlLoad, createNodeLogger } from './nodes/node-helpers.js';
|
|
14
|
+
import { readSpecFile, safeYamlLoad, createNodeLogger, getCompletedPhases, } from './nodes/node-helpers.js';
|
|
15
15
|
// Re-export state types for consumers
|
|
16
16
|
export { FeatureAgentAnnotation } from './state.js';
|
|
17
17
|
/**
|
|
@@ -54,6 +54,18 @@ function createPlanTasksValidator() {
|
|
|
54
54
|
const log = createNodeLogger('validate:plan+tasks');
|
|
55
55
|
return async (state) => {
|
|
56
56
|
log.activate();
|
|
57
|
+
// Skip validation when the successor phase (implement) is already completed.
|
|
58
|
+
// This proves validation already passed and the pipeline progressed beyond it.
|
|
59
|
+
// Same logic as createValidateNode's successorPhase guard.
|
|
60
|
+
if (getCompletedPhases(state.specDir).includes('implement')) {
|
|
61
|
+
log.info("Successor phase 'implement' already completed, skipping validation");
|
|
62
|
+
return {
|
|
63
|
+
lastValidationTarget: 'plan.yaml+tasks.yaml',
|
|
64
|
+
lastValidationErrors: [],
|
|
65
|
+
validationRetries: 0,
|
|
66
|
+
messages: ["[validate:plan+tasks] SKIP (successor 'implement' already completed)"],
|
|
67
|
+
};
|
|
68
|
+
}
|
|
57
69
|
log.info('Validating plan.yaml and tasks.yaml');
|
|
58
70
|
const allErrors = [];
|
|
59
71
|
// Validate plan.yaml
|
|
@@ -145,9 +157,14 @@ export function createFeatureAgentGraph(depsOrExecutor, checkpointer) {
|
|
|
145
157
|
.addNode('plan', createPlanNode(executor))
|
|
146
158
|
.addNode('implement', createImplementNode(executor))
|
|
147
159
|
// --- Validate nodes ---
|
|
148
|
-
|
|
149
|
-
.
|
|
150
|
-
|
|
160
|
+
// Each validate node receives its SUCCESSOR phase name (the phase that runs
|
|
161
|
+
// after validation passes). On resume, validation is skipped only when the
|
|
162
|
+
// successor is already completed — proving this validation already passed.
|
|
163
|
+
// Using the successor (not the producer) avoids skipping validation when the
|
|
164
|
+
// producer ran successfully but validation itself failed.
|
|
165
|
+
.addNode('validate_spec_analyze', createValidateNode('spec.yaml', validateSpecAnalyze, 'requirements'))
|
|
166
|
+
.addNode('validate_spec_requirements', createValidateNode('spec.yaml', validateSpecRequirements, 'research'))
|
|
167
|
+
.addNode('validate_research', createValidateNode('research.yaml', validateResearch, 'plan'))
|
|
151
168
|
.addNode('validate_plan_tasks', createPlanTasksValidator())
|
|
152
169
|
// --- Repair nodes ---
|
|
153
170
|
.addNode('repair_spec_analyze', createRepairNode('spec.yaml', executor))
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.d.ts
CHANGED
|
@@ -6,7 +6,13 @@ type SchemaValidator = (data: unknown) => ValidationResult;
|
|
|
6
6
|
*
|
|
7
7
|
* On success: resets validationRetries to 0, clears errors.
|
|
8
8
|
* On failure: increments validationRetries, sets errors for repair node.
|
|
9
|
+
*
|
|
10
|
+
* @param successorPhase - The phase that runs AFTER this validation passes.
|
|
11
|
+
* If provided, skip validation when the successor is already completed — this
|
|
12
|
+
* proves the validation already passed in a prior run and the pipeline progressed
|
|
13
|
+
* beyond it. Checking the successor (not the producer) avoids skipping validation
|
|
14
|
+
* when the producer ran but validation itself failed.
|
|
9
15
|
*/
|
|
10
|
-
export declare function createValidateNode(filename: string, schema: SchemaValidator): (state: FeatureAgentState) => Promise<Partial<FeatureAgentState>>;
|
|
16
|
+
export declare function createValidateNode(filename: string, schema: SchemaValidator, successorPhase?: string): (state: FeatureAgentState) => Promise<Partial<FeatureAgentState>>;
|
|
11
17
|
export {};
|
|
12
18
|
//# sourceMappingURL=validate.node.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"validate.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAQhE,KAAK,eAAe,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,gBAAgB,CAAC;AAE3D;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,eAAe,EACvB,cAAc,CAAC,EAAE,MAAM,GACtB,CAAC,KAAK,EAAE,iBAAiB,KAAK,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAyEnE"}
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.js
CHANGED
|
@@ -1,14 +1,36 @@
|
|
|
1
|
-
import { readSpecFile, safeYamlLoad, createNodeLogger } from './node-helpers.js';
|
|
1
|
+
import { readSpecFile, safeYamlLoad, createNodeLogger, getCompletedPhases, } from './node-helpers.js';
|
|
2
2
|
/**
|
|
3
3
|
* Factory that creates a validate node for a specific YAML file.
|
|
4
4
|
*
|
|
5
5
|
* On success: resets validationRetries to 0, clears errors.
|
|
6
6
|
* On failure: increments validationRetries, sets errors for repair node.
|
|
7
|
+
*
|
|
8
|
+
* @param successorPhase - The phase that runs AFTER this validation passes.
|
|
9
|
+
* If provided, skip validation when the successor is already completed — this
|
|
10
|
+
* proves the validation already passed in a prior run and the pipeline progressed
|
|
11
|
+
* beyond it. Checking the successor (not the producer) avoids skipping validation
|
|
12
|
+
* when the producer ran but validation itself failed.
|
|
7
13
|
*/
|
|
8
|
-
export function createValidateNode(filename, schema) {
|
|
14
|
+
export function createValidateNode(filename, schema, successorPhase) {
|
|
9
15
|
const log = createNodeLogger(`validate:${filename}`);
|
|
10
16
|
return async (state) => {
|
|
11
17
|
log.activate();
|
|
18
|
+
// Skip validation when the successor phase is already completed.
|
|
19
|
+
// This means: the validation already passed in a prior run AND the next phase
|
|
20
|
+
// ran successfully. On resume, LangGraph replays nodes from the last checkpoint.
|
|
21
|
+
// The producer node skips (via getCompletedPhases), but if we only checked the
|
|
22
|
+
// producer we'd also skip validation when it previously FAILED (since
|
|
23
|
+
// markPhaseComplete runs before validation). Checking the successor is safe:
|
|
24
|
+
// if the successor completed, this validation must have passed to get there.
|
|
25
|
+
if (successorPhase && getCompletedPhases(state.specDir).includes(successorPhase)) {
|
|
26
|
+
log.info(`Successor phase '${successorPhase}' already completed, skipping validation`);
|
|
27
|
+
return {
|
|
28
|
+
lastValidationTarget: filename,
|
|
29
|
+
lastValidationErrors: [],
|
|
30
|
+
validationRetries: 0,
|
|
31
|
+
messages: [`[validate:${filename}] SKIP (successor '${successorPhase}' already completed)`],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
12
34
|
log.info(`Validating ${filename}`);
|
|
13
35
|
const content = readSpecFile(state.specDir, filename);
|
|
14
36
|
if (!content) {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare Tunnel Service
|
|
3
|
+
*
|
|
4
|
+
* Manages a `cloudflared` quick-tunnel that exposes ONLY the webhook
|
|
5
|
+
* API routes to the public internet via a random *.trycloudflare.com
|
|
6
|
+
* subdomain.
|
|
7
|
+
*
|
|
8
|
+
* Uses the `cloudflared` npm package which handles binary installation
|
|
9
|
+
* and provides a typed Tunnel API — no need for the user to install
|
|
10
|
+
* cloudflared separately.
|
|
11
|
+
*
|
|
12
|
+
* Security: A lightweight proxy HTTP server is started on a random port
|
|
13
|
+
* that only forwards requests matching the allowed path prefix
|
|
14
|
+
* (/api/webhooks) to the main app. The tunnel connects to this proxy,
|
|
15
|
+
* not the main app server. All other paths return 404.
|
|
16
|
+
*/
|
|
17
|
+
import type { ITunnelService, TunnelUrlChangeHandler } from '../../../application/ports/output/services/tunnel-service.interface.js';
|
|
18
|
+
export interface CloudflareTunnelDeps {
|
|
19
|
+
createTunnel: (origin: string) => TunnelLike | Promise<TunnelLike>;
|
|
20
|
+
}
|
|
21
|
+
export interface TunnelLike {
|
|
22
|
+
on(event: 'url', handler: (url: string) => void): void;
|
|
23
|
+
on(event: 'connected', handler: (connection: {
|
|
24
|
+
id: string;
|
|
25
|
+
ip: string;
|
|
26
|
+
location: string;
|
|
27
|
+
}) => void): void;
|
|
28
|
+
on(event: 'error', handler: (error: Error) => void): void;
|
|
29
|
+
on(event: 'exit', handler: (code: number | null, signal: string | null) => void): void;
|
|
30
|
+
once(event: string, handler: (...args: unknown[]) => void): void;
|
|
31
|
+
stop(): void;
|
|
32
|
+
}
|
|
33
|
+
export declare class CloudflareTunnelService implements ITunnelService {
|
|
34
|
+
private tunnel;
|
|
35
|
+
private proxyServer;
|
|
36
|
+
private publicUrl;
|
|
37
|
+
private readonly urlChangeHandlers;
|
|
38
|
+
private readonly deps;
|
|
39
|
+
constructor(deps?: Partial<CloudflareTunnelDeps>);
|
|
40
|
+
start(localPort: number): Promise<string>;
|
|
41
|
+
stop(): Promise<void>;
|
|
42
|
+
getPublicUrl(): string | null;
|
|
43
|
+
onUrlChange(handler: TunnelUrlChangeHandler): void;
|
|
44
|
+
isRunning(): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Start a lightweight HTTP proxy on a random port that only forwards
|
|
47
|
+
* requests with paths starting with ALLOWED_PATH_PREFIX to the main app.
|
|
48
|
+
* Everything else gets a 404.
|
|
49
|
+
*/
|
|
50
|
+
private startProxyServer;
|
|
51
|
+
private stopProxyServer;
|
|
52
|
+
private stopTunnel;
|
|
53
|
+
private notifyUrlChange;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=cloudflare-tunnel.service.d.ts.map
|
package/dist/packages/core/src/infrastructure/services/tunnel/cloudflare-tunnel.service.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare-tunnel.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/tunnel/cloudflare-tunnel.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EACV,cAAc,EACd,sBAAsB,EACvB,MAAM,wEAAwE,CAAC;AAMhF,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACpE;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IACvD,EAAE,CACA,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,CAAC,UAAU,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAC1E,IAAI,CAAC;IACR,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IAC1D,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC;IACvF,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IACjE,IAAI,IAAI,IAAI,CAAC;CACd;AAWD,qBAAa,uBAAwB,YAAW,cAAc;IAC5D,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAgC;IAClE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAuB;gBAEhC,IAAI,GAAE,OAAO,CAAC,oBAAoB,CAAM;IAI9C,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuEzC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3B,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B,WAAW,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI;IAIlD,SAAS,IAAI,OAAO;IAIpB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IA0DxB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,eAAe;CAgBxB"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare Tunnel Service
|
|
3
|
+
*
|
|
4
|
+
* Manages a `cloudflared` quick-tunnel that exposes ONLY the webhook
|
|
5
|
+
* API routes to the public internet via a random *.trycloudflare.com
|
|
6
|
+
* subdomain.
|
|
7
|
+
*
|
|
8
|
+
* Uses the `cloudflared` npm package which handles binary installation
|
|
9
|
+
* and provides a typed Tunnel API — no need for the user to install
|
|
10
|
+
* cloudflared separately.
|
|
11
|
+
*
|
|
12
|
+
* Security: A lightweight proxy HTTP server is started on a random port
|
|
13
|
+
* that only forwards requests matching the allowed path prefix
|
|
14
|
+
* (/api/webhooks) to the main app. The tunnel connects to this proxy,
|
|
15
|
+
* not the main app server. All other paths return 404.
|
|
16
|
+
*/
|
|
17
|
+
import { createServer, request as httpRequest } from 'node:http';
|
|
18
|
+
const TAG = '[CloudflareTunnel]';
|
|
19
|
+
const STARTUP_TIMEOUT_MS = 30_000;
|
|
20
|
+
const ALLOWED_PATH_PREFIX = '/api/webhooks';
|
|
21
|
+
async function defaultCreateTunnel(origin) {
|
|
22
|
+
const { Tunnel } = await import('cloudflared');
|
|
23
|
+
return Tunnel.quick(origin);
|
|
24
|
+
}
|
|
25
|
+
const defaultDeps = {
|
|
26
|
+
createTunnel: defaultCreateTunnel,
|
|
27
|
+
};
|
|
28
|
+
export class CloudflareTunnelService {
|
|
29
|
+
tunnel = null;
|
|
30
|
+
proxyServer = null;
|
|
31
|
+
publicUrl = null;
|
|
32
|
+
urlChangeHandlers = [];
|
|
33
|
+
deps;
|
|
34
|
+
constructor(deps = {}) {
|
|
35
|
+
this.deps = { ...defaultDeps, ...deps };
|
|
36
|
+
}
|
|
37
|
+
async start(localPort) {
|
|
38
|
+
if (this.tunnel) {
|
|
39
|
+
throw new Error(`${TAG} Tunnel already running at ${this.publicUrl}`);
|
|
40
|
+
}
|
|
41
|
+
// Start a proxy server that only forwards webhook routes
|
|
42
|
+
const proxyPort = await this.startProxyServer(localPort);
|
|
43
|
+
let tunnel;
|
|
44
|
+
try {
|
|
45
|
+
tunnel = await Promise.resolve(this.deps.createTunnel(`http://localhost:${proxyPort}`));
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
this.stopProxyServer();
|
|
49
|
+
throw new Error(`${TAG} Failed to create tunnel: ${err.message}`);
|
|
50
|
+
}
|
|
51
|
+
this.tunnel = tunnel;
|
|
52
|
+
return new Promise((resolve, reject) => {
|
|
53
|
+
const timeout = setTimeout(() => {
|
|
54
|
+
this.stopTunnel();
|
|
55
|
+
reject(new Error(`${TAG} Timed out waiting for tunnel URL (${STARTUP_TIMEOUT_MS}ms)`));
|
|
56
|
+
}, STARTUP_TIMEOUT_MS);
|
|
57
|
+
tunnel.on('url', (url) => {
|
|
58
|
+
if (!this.publicUrl) {
|
|
59
|
+
// First URL — startup complete
|
|
60
|
+
this.publicUrl = url;
|
|
61
|
+
clearTimeout(timeout);
|
|
62
|
+
// eslint-disable-next-line no-console
|
|
63
|
+
console.log(`${TAG} Tunnel ready: ${url} (proxying ${ALLOWED_PATH_PREFIX}/* to port ${localPort})`);
|
|
64
|
+
resolve(url);
|
|
65
|
+
}
|
|
66
|
+
else if (url !== this.publicUrl) {
|
|
67
|
+
// URL changed — reconnection with new subdomain
|
|
68
|
+
const oldUrl = this.publicUrl;
|
|
69
|
+
this.publicUrl = url;
|
|
70
|
+
// eslint-disable-next-line no-console
|
|
71
|
+
console.log(`${TAG} Tunnel URL changed: ${oldUrl} -> ${url}`);
|
|
72
|
+
this.notifyUrlChange(url);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
tunnel.on('error', (err) => {
|
|
76
|
+
clearTimeout(timeout);
|
|
77
|
+
this.tunnel = null;
|
|
78
|
+
this.publicUrl = null;
|
|
79
|
+
this.stopProxyServer();
|
|
80
|
+
reject(new Error(`${TAG} Failed to start tunnel: ${err.message}`));
|
|
81
|
+
});
|
|
82
|
+
tunnel.on('exit', (code) => {
|
|
83
|
+
clearTimeout(timeout);
|
|
84
|
+
if (this.tunnel === tunnel) {
|
|
85
|
+
this.tunnel = null;
|
|
86
|
+
const wasRunning = this.publicUrl !== null;
|
|
87
|
+
this.publicUrl = null;
|
|
88
|
+
this.stopProxyServer();
|
|
89
|
+
if (wasRunning) {
|
|
90
|
+
// eslint-disable-next-line no-console
|
|
91
|
+
console.log(`${TAG} Tunnel process exited (code ${code})`);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
reject(new Error(`${TAG} cloudflared exited with code ${code} before producing a URL`));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
async stop() {
|
|
101
|
+
this.stopTunnel();
|
|
102
|
+
this.publicUrl = null;
|
|
103
|
+
}
|
|
104
|
+
getPublicUrl() {
|
|
105
|
+
return this.publicUrl;
|
|
106
|
+
}
|
|
107
|
+
onUrlChange(handler) {
|
|
108
|
+
this.urlChangeHandlers.push(handler);
|
|
109
|
+
}
|
|
110
|
+
isRunning() {
|
|
111
|
+
return this.tunnel !== null && this.publicUrl !== null;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Start a lightweight HTTP proxy on a random port that only forwards
|
|
115
|
+
* requests with paths starting with ALLOWED_PATH_PREFIX to the main app.
|
|
116
|
+
* Everything else gets a 404.
|
|
117
|
+
*/
|
|
118
|
+
startProxyServer(targetPort) {
|
|
119
|
+
return new Promise((resolve, reject) => {
|
|
120
|
+
const server = createServer((req, res) => {
|
|
121
|
+
const url = req.url ?? '';
|
|
122
|
+
if (!url.startsWith(ALLOWED_PATH_PREFIX)) {
|
|
123
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
124
|
+
res.end(JSON.stringify({ error: 'Not found' }));
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
// Proxy the request to the main app
|
|
128
|
+
const proxyReq = httpRequest({
|
|
129
|
+
hostname: 'localhost',
|
|
130
|
+
port: targetPort,
|
|
131
|
+
path: url,
|
|
132
|
+
method: req.method,
|
|
133
|
+
headers: req.headers,
|
|
134
|
+
}, (proxyRes) => {
|
|
135
|
+
res.writeHead(proxyRes.statusCode ?? 502, proxyRes.headers);
|
|
136
|
+
proxyRes.pipe(res);
|
|
137
|
+
});
|
|
138
|
+
proxyReq.on('error', (err) => {
|
|
139
|
+
// eslint-disable-next-line no-console
|
|
140
|
+
console.warn(`${TAG} Proxy error: ${err.message}`);
|
|
141
|
+
if (!res.headersSent) {
|
|
142
|
+
res.writeHead(502, { 'Content-Type': 'application/json' });
|
|
143
|
+
}
|
|
144
|
+
res.end(JSON.stringify({ error: 'Bad gateway' }));
|
|
145
|
+
});
|
|
146
|
+
req.pipe(proxyReq);
|
|
147
|
+
});
|
|
148
|
+
// Listen on port 0 = OS assigns a random available port
|
|
149
|
+
server.listen(0, '127.0.0.1', () => {
|
|
150
|
+
const addr = server.address();
|
|
151
|
+
if (addr && typeof addr === 'object') {
|
|
152
|
+
this.proxyServer = server;
|
|
153
|
+
// eslint-disable-next-line no-console
|
|
154
|
+
console.log(`${TAG} Webhook proxy listening on port ${addr.port}`);
|
|
155
|
+
resolve(addr.port);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
server.close();
|
|
159
|
+
reject(new Error(`${TAG} Failed to start proxy server`));
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
server.on('error', (err) => {
|
|
163
|
+
reject(new Error(`${TAG} Proxy server error: ${err.message}`));
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
stopProxyServer() {
|
|
168
|
+
if (this.proxyServer) {
|
|
169
|
+
this.proxyServer.close();
|
|
170
|
+
this.proxyServer = null;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
stopTunnel() {
|
|
174
|
+
if (this.tunnel) {
|
|
175
|
+
const tunnel = this.tunnel;
|
|
176
|
+
this.tunnel = null;
|
|
177
|
+
try {
|
|
178
|
+
tunnel.stop();
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
// Tunnel already stopped
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
this.stopProxyServer();
|
|
185
|
+
}
|
|
186
|
+
notifyUrlChange(newUrl) {
|
|
187
|
+
for (const handler of this.urlChangeHandlers) {
|
|
188
|
+
try {
|
|
189
|
+
const result = handler(newUrl);
|
|
190
|
+
if (result instanceof Promise) {
|
|
191
|
+
result.catch((err) => {
|
|
192
|
+
// eslint-disable-next-line no-console
|
|
193
|
+
console.warn(`${TAG} URL change handler failed:`, err);
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
catch (err) {
|
|
198
|
+
// eslint-disable-next-line no-console
|
|
199
|
+
console.warn(`${TAG} URL change handler threw:`, err);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
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 type { IWebhookService, WebhookEvent, WebhookValidationResult } from '../../../application/ports/output/services/webhook-service.interface.js';
|
|
14
|
+
import type { IFeatureRepository } from '../../../application/ports/output/repositories/feature-repository.interface.js';
|
|
15
|
+
import type { IGitPrService } from '../../../application/ports/output/services/git-pr-service.interface.js';
|
|
16
|
+
import type { INotificationService } from '../../../application/ports/output/services/notification-service.interface.js';
|
|
17
|
+
export type ExecFunction = (file: string, args: string[], options?: object) => Promise<{
|
|
18
|
+
stdout: string;
|
|
19
|
+
stderr: string;
|
|
20
|
+
}>;
|
|
21
|
+
export interface RegisteredWebhook {
|
|
22
|
+
repoFullName: string;
|
|
23
|
+
webhookId: number;
|
|
24
|
+
repositoryPath: string;
|
|
25
|
+
}
|
|
26
|
+
export type WebhookDeliveryStatus = 'success' | 'ignored' | 'error';
|
|
27
|
+
export interface WebhookDeliveryRecord {
|
|
28
|
+
deliveryId: string;
|
|
29
|
+
eventType: string;
|
|
30
|
+
source: string;
|
|
31
|
+
receivedAt: string;
|
|
32
|
+
status: WebhookDeliveryStatus;
|
|
33
|
+
statusMessage: string;
|
|
34
|
+
durationMs: number;
|
|
35
|
+
payload: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
export declare class GitHubWebhookService implements IWebhookService {
|
|
38
|
+
private readonly featureRepo;
|
|
39
|
+
private readonly gitPrService;
|
|
40
|
+
private readonly notificationService;
|
|
41
|
+
private readonly execFn;
|
|
42
|
+
private readonly registeredWebhooks;
|
|
43
|
+
private readonly deliveryHistory;
|
|
44
|
+
private webhookSecret;
|
|
45
|
+
constructor(featureRepo: IFeatureRepository, gitPrService: IGitPrService, notificationService: INotificationService, execFn: ExecFunction);
|
|
46
|
+
/**
|
|
47
|
+
* Get the webhook secret for signature validation.
|
|
48
|
+
* Exposed so the API route can validate incoming requests.
|
|
49
|
+
*/
|
|
50
|
+
getSecret(): string;
|
|
51
|
+
/**
|
|
52
|
+
* Get the list of registered webhooks (for dashboard display).
|
|
53
|
+
*/
|
|
54
|
+
getRegisteredWebhooks(): readonly RegisteredWebhook[];
|
|
55
|
+
/**
|
|
56
|
+
* Get recent delivery history (newest first).
|
|
57
|
+
*/
|
|
58
|
+
getDeliveryHistory(): readonly WebhookDeliveryRecord[];
|
|
59
|
+
registerWebhooks(publicUrl: string): Promise<void>;
|
|
60
|
+
updateWebhookUrl(newUrl: string): Promise<void>;
|
|
61
|
+
removeWebhooks(): Promise<void>;
|
|
62
|
+
validateSignature(payload: string, signature: string, secret: string): WebhookValidationResult;
|
|
63
|
+
handleEvent(event: WebhookEvent): Promise<void>;
|
|
64
|
+
private recordDelivery;
|
|
65
|
+
private handlePullRequestEvent;
|
|
66
|
+
private handleCheckSuiteEvent;
|
|
67
|
+
private handleCheckRunEvent;
|
|
68
|
+
private findFeatureByPrOrBranch;
|
|
69
|
+
private findFeatureByBranch;
|
|
70
|
+
private updateFeaturePrStatus;
|
|
71
|
+
private updateFeatureCiStatus;
|
|
72
|
+
private registerWebhookForRepo;
|
|
73
|
+
private getRepoFullName;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=github-webhook.service.d.ts.map
|