@shepai/cli 1.55.3 → 1.57.0
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/apis/json-schema/NotificationEventConfig.yaml +20 -0
- package/apis/json-schema/NotificationEventType.yaml +4 -0
- package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts +22 -0
- package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/ide-launcher-service.interface.d.ts +3 -1
- package/dist/packages/core/src/application/ports/output/services/ide-launcher-service.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/tools/launch-tool.use-case.d.ts +29 -0
- package/dist/packages/core/src/application/use-cases/tools/launch-tool.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/tools/launch-tool.use-case.js +60 -0
- package/dist/packages/core/src/application/use-cases/tools/list-tools.use-case.d.ts +31 -0
- package/dist/packages/core/src/application/use-cases/tools/list-tools.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/tools/list-tools.use-case.js +70 -0
- package/dist/packages/core/src/domain/factories/settings-defaults.factory.d.ts.map +1 -1
- package/dist/packages/core/src/domain/factories/settings-defaults.factory.js +4 -0
- package/dist/packages/core/src/domain/generated/output.d.ts +21 -1
- package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
- package/dist/packages/core/src/domain/generated/output.js +4 -0
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +13 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts +4 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.js +8 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.js +18 -0
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts +3 -1
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +28 -0
- package/dist/packages/core/src/infrastructure/services/ide-launchers/json-driven-ide-launcher.service.d.ts +3 -1
- package/dist/packages/core/src/infrastructure/services/ide-launchers/json-driven-ide-launcher.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/ide-launchers/json-driven-ide-launcher.service.js +11 -5
- package/dist/packages/core/src/infrastructure/services/notifications/notification.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/notifications/notification.service.js +4 -0
- package/dist/packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.d.ts +61 -0
- package/dist/packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.js +286 -0
- package/dist/packages/core/src/infrastructure/services/tool-installer/tool-installer.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/tool-installer/tool-installer.service.js +18 -7
- package/dist/packages/core/src/infrastructure/services/tool-installer/tool-metadata.d.ts +11 -1
- package/dist/packages/core/src/infrastructure/services/tool-installer/tool-metadata.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/CLAUDE.md +63 -0
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/antigravity.json +3 -2
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/claude-code.json +5 -0
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/cursor-cli.json +6 -1
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/cursor.json +1 -0
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/gemini-cli.json +27 -0
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/gh.json +18 -0
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/git.json +18 -0
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/vscode.json +1 -0
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/windsurf.json +1 -0
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/zed.json +1 -0
- package/dist/src/presentation/cli/commands/install.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/install.command.js +6 -13
- package/dist/src/presentation/cli/commands/tools.command.d.ts +14 -0
- package/dist/src/presentation/cli/commands/tools.command.d.ts.map +1 -0
- package/dist/src/presentation/cli/commands/tools.command.js +36 -0
- package/dist/src/presentation/cli/commands/ui.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/ui.command.js +6 -0
- package/dist/src/presentation/cli/index.js +2 -0
- package/dist/src/presentation/web/app/api/tools/[id]/install/route.d.ts +7 -0
- package/dist/src/presentation/web/app/api/tools/[id]/install/route.d.ts.map +1 -0
- package/dist/src/presentation/web/app/api/tools/[id]/install/route.js +18 -0
- package/dist/src/presentation/web/app/api/tools/[id]/launch/route.d.ts +7 -0
- package/dist/src/presentation/web/app/api/tools/[id]/launch/route.d.ts.map +1 -0
- package/dist/src/presentation/web/app/api/tools/[id]/launch/route.js +28 -0
- package/dist/src/presentation/web/app/api/tools/route.d.ts +3 -0
- package/dist/src/presentation/web/app/api/tools/route.d.ts.map +1 -0
- package/dist/src/presentation/web/app/api/tools/route.js +13 -0
- package/dist/src/presentation/web/app/tools/page.d.ts +4 -0
- package/dist/src/presentation/web/app/tools/page.d.ts.map +1 -0
- package/dist/src/presentation/web/app/tools/page.js +10 -0
- package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.js +6 -0
- package/dist/src/presentation/web/components/features/index.d.ts +3 -0
- package/dist/src/presentation/web/components/features/index.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/index.js +3 -0
- package/dist/src/presentation/web/components/features/tools/index.d.ts +4 -0
- package/dist/src/presentation/web/components/features/tools/index.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/tools/index.js +3 -0
- package/dist/src/presentation/web/components/features/tools/install-instructions.d.ts +9 -0
- package/dist/src/presentation/web/components/features/tools/install-instructions.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/tools/install-instructions.js +19 -0
- package/dist/src/presentation/web/components/features/tools/install-instructions.stories.d.ts +12 -0
- package/dist/src/presentation/web/components/features/tools/install-instructions.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/tools/install-instructions.stories.js +77 -0
- package/dist/src/presentation/web/components/features/tools/tool-card.d.ts +8 -0
- package/dist/src/presentation/web/components/features/tools/tool-card.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/tools/tool-card.js +39 -0
- package/dist/src/presentation/web/components/features/tools/tool-card.stories.d.ts +15 -0
- package/dist/src/presentation/web/components/features/tools/tool-card.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/tools/tool-card.stories.js +136 -0
- package/dist/src/presentation/web/components/features/tools/tools-page-client.d.ts +7 -0
- package/dist/src/presentation/web/components/features/tools/tools-page-client.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/tools/tools-page-client.js +31 -0
- package/dist/src/presentation/web/components/features/tools/tools-page-client.stories.d.ts +13 -0
- package/dist/src/presentation/web/components/features/tools/tools-page-client.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/tools/tools-page-client.stories.js +122 -0
- package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.js +2 -2
- package/dist/src/presentation/web/dev-server.js +11 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/app-path-routes-manifest.json +4 -0
- package/web/.next/build-manifest.json +5 -5
- package/web/.next/cache/.previewinfo +1 -1
- package/web/.next/cache/.rscinfo +1 -1
- package/web/.next/cache/.tsbuildinfo +1 -1
- package/web/.next/cache/config.json +3 -3
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +1 -1
- package/web/.next/required-server-files.json +1 -1
- package/web/.next/routes-manifest.json +30 -1
- package/web/.next/server/app/_global-error/page/build-manifest.json +3 -3
- package/web/.next/server/app/_global-error/page.js +1 -1
- package/web/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- 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 +3 -3
- 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/dialog/pick-files/route.js +2 -2
- package/web/.next/server/app/api/dialog/pick-files/route.js.nft.json +1 -1
- package/web/.next/server/app/api/tools/[id]/install/route/app-paths-manifest.json +3 -0
- package/web/.next/server/app/api/tools/[id]/install/route/build-manifest.json +11 -0
- package/web/.next/server/app/api/tools/[id]/install/route/server-reference-manifest.json +4 -0
- package/web/.next/server/app/api/tools/[id]/install/route.js +7 -0
- package/web/.next/server/app/api/tools/[id]/install/route.js.map +5 -0
- package/web/.next/server/app/api/tools/[id]/install/route.js.nft.json +1 -0
- package/web/.next/server/app/api/tools/[id]/install/route_client-reference-manifest.js +2 -0
- package/web/.next/server/app/api/tools/[id]/launch/route/app-paths-manifest.json +3 -0
- package/web/.next/server/app/api/tools/[id]/launch/route/build-manifest.json +11 -0
- package/web/.next/server/app/api/tools/[id]/launch/route/server-reference-manifest.json +4 -0
- package/web/.next/server/app/api/tools/[id]/launch/route.js +7 -0
- package/web/.next/server/app/api/tools/[id]/launch/route.js.map +5 -0
- package/web/.next/server/app/api/tools/[id]/launch/route.js.nft.json +1 -0
- package/web/.next/server/app/api/tools/[id]/launch/route_client-reference-manifest.js +2 -0
- package/web/.next/server/app/api/tools/route/app-paths-manifest.json +3 -0
- package/web/.next/server/app/api/tools/route/build-manifest.json +11 -0
- package/web/.next/server/app/api/tools/route/server-reference-manifest.json +4 -0
- package/web/.next/server/app/api/tools/route.js +7 -0
- package/web/.next/server/app/api/tools/route.js.map +5 -0
- package/web/.next/server/app/api/tools/route.js.nft.json +1 -0
- package/web/.next/server/app/api/tools/route_client-reference-manifest.js +2 -0
- package/web/.next/server/app/page/build-manifest.json +3 -3
- package/web/.next/server/app/page/server-reference-manifest.json +14 -14
- package/web/.next/server/app/page.js +2 -2
- package/web/.next/server/app/page.js.nft.json +1 -1
- package/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/app-paths-manifest.json +3 -0
- package/web/.next/server/app/tools/page/build-manifest.json +17 -0
- package/web/.next/server/app/tools/page/next-font-manifest.json +6 -0
- package/web/.next/server/app/tools/page/react-loadable-manifest.json +1 -0
- package/web/.next/server/app/tools/page/server-reference-manifest.json +4 -0
- package/web/.next/server/app/tools/page.js +15 -0
- package/web/.next/server/app/tools/page.js.map +5 -0
- package/web/.next/server/app/tools/page.js.nft.json +1 -0
- package/web/.next/server/app/tools/page_client-reference-manifest.js +2 -0
- package/web/.next/server/app/version/page/build-manifest.json +3 -3
- 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-paths-manifest.json +4 -0
- package/web/.next/server/chunks/{403f9_next_435614de._.js → 403f9_next_567de315._.js} +6 -7
- package/web/.next/server/chunks/403f9_next_567de315._.js.map +1 -0
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js +2 -2
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js.map +1 -1
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_tools_[id]_install_route_actions_ad71fb5e.js +3 -0
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_tools_[id]_launch_route_actions_0501a9ac.js +3 -0
- package/web/.next/server/chunks/[root-of-the-server]__332c8d91._.js +4 -0
- package/web/.next/server/chunks/[root-of-the-server]__332c8d91._.js.map +1 -0
- package/web/.next/server/chunks/[root-of-the-server]__9191749c._.js +3 -0
- package/web/.next/server/chunks/[root-of-the-server]__9191749c._.js.map +1 -0
- package/web/.next/server/chunks/[root-of-the-server]__b4102cc7._.js +3 -0
- package/web/.next/server/chunks/[root-of-the-server]__b4102cc7._.js.map +1 -0
- package/web/.next/server/chunks/[root-of-the-server]__bb619083._.js +3 -0
- package/web/.next/server/chunks/[root-of-the-server]__bb619083._.js.map +1 -0
- package/web/.next/server/chunks/src_presentation_web__next-internal_server_app_api_tools_route_actions_b8d6f9a0.js +3 -0
- package/web/.next/server/chunks/src_presentation_web__next-internal_server_app_api_tools_route_actions_b8d6f9a0.js.map +1 -0
- package/web/.next/server/chunks/ssr/6769f_@radix-ui_react-roving-focus_dist_index_mjs_b3be3d8e._.js +3 -0
- package/web/.next/server/chunks/ssr/6769f_@radix-ui_react-roving-focus_dist_index_mjs_b3be3d8e._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1efeb0eb._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1efeb0eb._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2d1a8e37._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__48c68a96._.js +12 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__48c68a96._.js.map +1 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__32472b89._.js → [root-of-the-server]__685eaa45._.js} +2 -2
- package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__f47a461b._.js → server/chunks/ssr/[root-of-the-server]__757c7912._.js} +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__847521e6._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__847521e6._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__950afd5e._.js +3 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__d8fbe735._.js.map → [root-of-the-server]__950afd5e._.js.map} +1 -1
- package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__e1c44885._.js → server/chunks/ssr/[root-of-the-server]__dbd220d2._.js} +2 -2
- package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6e8b5181._.js → server/chunks/ssr/[root-of-the-server]__fbc89707._.js} +2 -2
- package/web/.next/server/chunks/ssr/_0e2c2b4f._.js +6 -0
- package/web/.next/server/chunks/ssr/_0e2c2b4f._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_2900ed94._.js +3 -0
- package/web/.next/server/chunks/ssr/_2900ed94._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_ad8a094f._.js +4 -0
- package/web/.next/server/chunks/ssr/_ad8a094f._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_e242b954._.js +3 -0
- package/web/.next/server/chunks/ssr/_e242b954._.js.map +1 -0
- package/web/.next/server/chunks/ssr/node_modules__pnpm_0ce0b44d._.js +3 -0
- package/web/.next/server/chunks/ssr/node_modules__pnpm_0ce0b44d._.js.map +1 -0
- package/web/.next/server/chunks/ssr/node_modules__pnpm_d26a7485._.js +7 -0
- package/web/.next/server/chunks/ssr/node_modules__pnpm_d26a7485._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_f1dd7791.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_f1dd7791.js.map +1 -0
- 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_ec3b0a65._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_components_ec3b0a65._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js.map +1 -1
- package/web/.next/server/middleware-build-manifest.js +3 -3
- 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 +15 -15
- package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/src/presentation/web/.next/app-path-routes-manifest.json +4 -0
- package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +5 -5
- package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/routes-manifest.json +30 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error/page/build-manifest.json +3 -3
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error/page.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/build-manifest.json +3 -3
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/dialog/pick-files/route.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/dialog/pick-files/route.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/install/route/app-paths-manifest.json +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/install/route/build-manifest.json +11 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/install/route/server-reference-manifest.json +4 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/install/route.js +7 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/install/route.js.map +5 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/install/route.js.nft.json +1 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/install/route_client-reference-manifest.js +2 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/launch/route/app-paths-manifest.json +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/launch/route/build-manifest.json +11 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/launch/route/server-reference-manifest.json +4 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/launch/route.js +7 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/launch/route.js.map +5 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/launch/route.js.nft.json +1 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/launch/route_client-reference-manifest.js +2 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/route/app-paths-manifest.json +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/route/build-manifest.json +11 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/route/server-reference-manifest.json +4 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/route.js +7 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/route.js.map +5 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/route.js.nft.json +1 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/route_client-reference-manifest.js +2 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/page/build-manifest.json +3 -3
- package/web/.next/standalone/src/presentation/web/.next/server/app/page/server-reference-manifest.json +14 -14
- package/web/.next/standalone/src/presentation/web/.next/server/app/page.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/app/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/app-paths-manifest.json +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/build-manifest.json +17 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/next-font-manifest.json +6 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/react-loadable-manifest.json +1 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +4 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page.js +15 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page.js.map +5 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page.js.nft.json +1 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +2 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/build-manifest.json +3 -3
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app-paths-manifest.json +4 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/{403f9_next_435614de._.js → 403f9_next_567de315._.js} +6 -7
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/744ca_web__next-internal_server_app_api_tools_[id]_install_route_actions_ad71fb5e.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/744ca_web__next-internal_server_app_api_tools_[id]_launch_route_actions_0501a9ac.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/[root-of-the-server]__332c8d91._.js +4 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/[root-of-the-server]__9191749c._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/[root-of-the-server]__b4102cc7._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/[root-of-the-server]__bb619083._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/src_presentation_web__next-internal_server_app_api_tools_route_actions_b8d6f9a0.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/6769f_@radix-ui_react-roving-focus_dist_index_mjs_b3be3d8e._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__1efeb0eb._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__2d1a8e37._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__48c68a96._.js +12 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{[root-of-the-server]__32472b89._.js → [root-of-the-server]__685eaa45._.js} +2 -2
- package/web/.next/{server/chunks/ssr/[root-of-the-server]__f47a461b._.js → standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__757c7912._.js} +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__847521e6._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__950afd5e._.js +3 -0
- package/web/.next/{server/chunks/ssr/[root-of-the-server]__e1c44885._.js → standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__dbd220d2._.js} +2 -2
- package/web/.next/{server/chunks/ssr/[root-of-the-server]__6e8b5181._.js → standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__fbc89707._.js} +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_0e2c2b4f._.js +6 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_2900ed94._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_ad8a094f._.js +4 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_e242b954._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/node_modules__pnpm_0ce0b44d._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/node_modules__pnpm_d26a7485._.js +7 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_f1dd7791.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_ec3b0a65._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/middleware-build-manifest.js +3 -3
- package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +15 -15
- package/web/.next/standalone/src/presentation/web/app/api/tools/[id]/install/route.ts +24 -0
- package/web/.next/standalone/src/presentation/web/app/api/tools/[id]/launch/route.ts +38 -0
- package/web/.next/standalone/src/presentation/web/app/api/tools/route.ts +14 -0
- package/web/.next/standalone/src/presentation/web/app/tools/page.tsx +17 -0
- package/web/.next/standalone/src/presentation/web/components/common/feature-node/derive-feature-state.ts +6 -0
- package/web/.next/standalone/src/presentation/web/components/features/index.ts +3 -0
- package/web/.next/standalone/src/presentation/web/components/features/tools/index.ts +3 -0
- package/web/.next/standalone/src/presentation/web/components/features/tools/install-instructions.stories.tsx +89 -0
- package/web/.next/standalone/src/presentation/web/components/features/tools/install-instructions.tsx +109 -0
- package/web/.next/standalone/src/presentation/web/components/features/tools/tool-card.stories.tsx +181 -0
- package/web/.next/standalone/src/presentation/web/components/features/tools/tool-card.tsx +188 -0
- package/web/.next/standalone/src/presentation/web/components/features/tools/tools-page-client.stories.tsx +141 -0
- package/web/.next/standalone/src/presentation/web/components/features/tools/tools-page-client.tsx +100 -0
- package/web/.next/standalone/src/presentation/web/components/layouts/app-sidebar/app-sidebar.tsx +5 -5
- package/web/.next/standalone/src/presentation/web/dev-server.ts +15 -0
- package/web/.next/standalone/src/presentation/web/server.js +1 -1
- package/web/.next/static/chunks/0cd7c513169faee3.js +1 -0
- package/web/.next/static/chunks/1887af4ad3781531.js +2 -0
- package/web/.next/static/chunks/225de19e886a62ab.js +10 -0
- package/web/.next/static/chunks/35f41ba0a6d626d7.js +1 -0
- package/web/.next/static/chunks/3d4dcf0be654a331.js +5 -0
- package/web/.next/static/chunks/4651f20be1a3b7d7.css +2 -0
- package/web/.next/static/chunks/7138c478667158d0.js +1 -0
- package/web/.next/static/chunks/a1f2befd62b321c0.js +1 -0
- package/web/.next/static/chunks/a9c2b889c8749a94.js +1 -0
- package/web/.next/static/chunks/cda11a2491d519fc.js +1 -0
- package/web/.next/static/chunks/ef237b70209d9853.js +1 -0
- package/web/.next/static/chunks/{turbopack-35ff53de4dab1e56.js → turbopack-6a11f2f1634ff6e0.js} +1 -1
- package/web/.next/trace +1 -1
- package/web/.next/trace-build +1 -1
- package/web/.next/types/link.d.ts +5 -1
- package/web/.next/types/routes.d.ts +6 -2
- package/web/.next/types/validator.ts +36 -0
- package/web/.next/server/chunks/403f9_next_435614de._.js.map +0 -1
- package/web/.next/server/chunks/[externals]__ba6223e5._.js +0 -3
- package/web/.next/server/chunks/ssr/[externals]_node:path_d28a9bfe._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js +0 -12
- package/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__d8fbe735._.js +0 -3
- package/web/.next/server/chunks/ssr/_1632a21f._.js +0 -10
- package/web/.next/server/chunks/ssr/_1632a21f._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_a35f2870._.js +0 -3
- package/web/.next/server/chunks/ssr/_a35f2870._.js.map +0 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_version_version-page-client_tsx_fe9db753._.js +0 -3
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_version_version-page-client_tsx_fe9db753._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_ui_badge_tsx_964c2a3b._.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web_components_ui_badge_tsx_964c2a3b._.js.map +0 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/[externals]__ba6223e5._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[externals]_node:path_d28a9bfe._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js +0 -12
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__d8fbe735._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_1632a21f._.js +0 -10
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_a35f2870._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_version_version-page-client_tsx_fe9db753._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_ui_badge_tsx_964c2a3b._.js +0 -3
- package/web/.next/static/chunks/00f6ac2dde225eb7.js +0 -1
- package/web/.next/static/chunks/084314470f2144d2.js +0 -2
- package/web/.next/static/chunks/1f13bc20e938335c.css +0 -2
- package/web/.next/static/chunks/8f4461aee9a05741.js +0 -5
- package/web/.next/static/chunks/958c51856b8d6ed7.js +0 -10
- package/web/.next/static/chunks/9a82d8c76f175235.js +0 -1
- package/web/.next/static/chunks/b13aa397579082e7.js +0 -1
- package/web/.next/static/chunks/e21d644e5a584136.js +0 -1
- package/web/.next/static/chunks/f023fd36b47a5baa.js +0 -1
- /package/web/.next/server/chunks/{[externals]__ba6223e5._.js.map → 744ca_web__next-internal_server_app_api_tools_[id]_install_route_actions_ad71fb5e.js.map} +0 -0
- /package/web/.next/server/chunks/{ssr/[externals]_node:path_d28a9bfe._.js.map → 744ca_web__next-internal_server_app_api_tools_[id]_launch_route_actions_0501a9ac.js.map} +0 -0
- /package/web/.next/server/chunks/ssr/{[root-of-the-server]__32472b89._.js.map → [root-of-the-server]__685eaa45._.js.map} +0 -0
- /package/web/.next/server/chunks/ssr/{[root-of-the-server]__f47a461b._.js.map → [root-of-the-server]__757c7912._.js.map} +0 -0
- /package/web/.next/server/chunks/ssr/{[root-of-the-server]__e1c44885._.js.map → [root-of-the-server]__dbd220d2._.js.map} +0 -0
- /package/web/.next/server/chunks/ssr/{[root-of-the-server]__6e8b5181._.js.map → [root-of-the-server]__fbc89707._.js.map} +0 -0
- /package/web/.next/static/{cqDB25f0Vxmh-LBw_64mT → V2579MPjpJ_hqKjPsmMlR}/_buildManifest.js +0 -0
- /package/web/.next/static/{cqDB25f0Vxmh-LBw_64mT → V2579MPjpJ_hqKjPsmMlR}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{cqDB25f0Vxmh-LBw_64mT → V2579MPjpJ_hqKjPsmMlR}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-pr.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/git-pr.service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wEAAwE,CAAC;AAC5G,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,aAAa,EACb,cAAc,
|
|
1
|
+
{"version":3,"file":"git-pr.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/git-pr.service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wEAAwE,CAAC;AAC5G,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,aAAa,EACb,cAAc,EACd,YAAY,EACb,MAAM,wEAAwE,CAAC;AAQhF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,qBACa,YAAa,YAAW,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAErE,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKxC,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuC9C,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKpD,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAWxD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAYvE,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAuClE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAE,aAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IAUzF,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUnF,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAkBjE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAwCjF,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAWhF,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAevE,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAkCpD,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWrF,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAW3F,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,oBAAoB;IAK5B,OAAO,CAAC,aAAa;CAiBtB"}
|
|
@@ -203,6 +203,30 @@ let GitPrService = class GitPrService {
|
|
|
203
203
|
const { stdout: logOutput } = await this.execFile('git', ['log', '--oneline', `${baseBranch}...HEAD`], { cwd });
|
|
204
204
|
return this.parseDiffStat(diffStat, logOutput);
|
|
205
205
|
}
|
|
206
|
+
async listPrStatuses(cwd) {
|
|
207
|
+
try {
|
|
208
|
+
const { stdout } = await this.execFile('gh', [
|
|
209
|
+
'pr',
|
|
210
|
+
'list',
|
|
211
|
+
'--json',
|
|
212
|
+
'number,state,url,headRefName',
|
|
213
|
+
'--state',
|
|
214
|
+
'all',
|
|
215
|
+
'--limit',
|
|
216
|
+
'100',
|
|
217
|
+
], { cwd });
|
|
218
|
+
const prs = JSON.parse(stdout);
|
|
219
|
+
return prs.map((pr) => ({
|
|
220
|
+
number: pr.number,
|
|
221
|
+
state: this.normalizeGhState(pr.state),
|
|
222
|
+
url: pr.url,
|
|
223
|
+
headRefName: pr.headRefName,
|
|
224
|
+
}));
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
throw this.parseGhError(error);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
206
230
|
async verifyMerge(cwd, featureBranch, baseBranch) {
|
|
207
231
|
try {
|
|
208
232
|
await this.execFile('git', ['merge-base', '--is-ancestor', featureBranch, baseBranch], {
|
|
@@ -230,6 +254,10 @@ let GitPrService = class GitPrService {
|
|
|
230
254
|
return output;
|
|
231
255
|
return `${output.slice(0, maxChars)}\n[Log truncated at ${maxChars} chars — full log available via gh run view ${runId}]`;
|
|
232
256
|
}
|
|
257
|
+
normalizeGhState(state) {
|
|
258
|
+
const normalized = state.charAt(0).toUpperCase() + state.slice(1).toLowerCase();
|
|
259
|
+
return normalized;
|
|
260
|
+
}
|
|
233
261
|
parseGitError(error) {
|
|
234
262
|
const message = error instanceof Error ? error.message : String(error);
|
|
235
263
|
const cause = error instanceof Error ? error : undefined;
|
|
@@ -17,7 +17,9 @@ export declare function resolvePlatformValue(value: string | Record<string, stri
|
|
|
17
17
|
export declare class JsonDrivenIdeLauncherService implements IIdeLauncherService {
|
|
18
18
|
private readonly editors;
|
|
19
19
|
constructor();
|
|
20
|
-
launch(editorId: string, directoryPath: string
|
|
20
|
+
launch(editorId: string, directoryPath: string, options?: {
|
|
21
|
+
headless?: boolean;
|
|
22
|
+
}): Promise<LaunchIdeResult>;
|
|
21
23
|
checkAvailability(editorId: string): Promise<boolean>;
|
|
22
24
|
}
|
|
23
25
|
//# sourceMappingURL=json-driven-ide-launcher.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-driven-ide-launcher.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/ide-launchers/json-driven-ide-launcher.service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EAChB,MAAM,8EAA8E,CAAC;
|
|
1
|
+
{"version":3,"file":"json-driven-ide-launcher.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/ide-launchers/json-driven-ide-launcher.service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EAChB,MAAM,8EAA8E,CAAC;AAetF;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAGnF;AAED,qBACa,4BAA6B,YAAW,mBAAmB;IACtE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;;IAiB1C,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAC/B,OAAO,CAAC,eAAe,CAAC;IA8D3B,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAWtD"}
|
|
@@ -40,12 +40,13 @@ let JsonDrivenIdeLauncherService = class JsonDrivenIdeLauncherService {
|
|
|
40
40
|
name: meta.name,
|
|
41
41
|
binary: meta.binary,
|
|
42
42
|
openDirectory: meta.openDirectory,
|
|
43
|
+
terminalCommand: meta.terminalCommand,
|
|
43
44
|
spawnOptions: meta.spawnOptions,
|
|
44
45
|
});
|
|
45
46
|
}
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
|
-
async launch(editorId, directoryPath) {
|
|
49
|
+
async launch(editorId, directoryPath, options) {
|
|
49
50
|
const entry = this.editors.get(editorId);
|
|
50
51
|
if (!entry) {
|
|
51
52
|
const available = [...this.editors.keys()].join(', ');
|
|
@@ -55,7 +56,11 @@ let JsonDrivenIdeLauncherService = class JsonDrivenIdeLauncherService {
|
|
|
55
56
|
message: `No launcher found for editor: ${editorId}. Available: ${available}`,
|
|
56
57
|
};
|
|
57
58
|
}
|
|
58
|
-
|
|
59
|
+
// In headless mode (web UI), use terminalCommand to open CLI agents
|
|
60
|
+
// in a new terminal window instead of inheriting the server's stdio.
|
|
61
|
+
const useTerminal = options?.headless === true && entry.terminalCommand != null;
|
|
62
|
+
const cmdSource = useTerminal ? entry.terminalCommand : entry.openDirectory;
|
|
63
|
+
const openCmd = resolvePlatformValue(cmdSource);
|
|
59
64
|
if (!openCmd.includes('{dir}')) {
|
|
60
65
|
return {
|
|
61
66
|
ok: false,
|
|
@@ -64,10 +69,11 @@ let JsonDrivenIdeLauncherService = class JsonDrivenIdeLauncherService {
|
|
|
64
69
|
};
|
|
65
70
|
}
|
|
66
71
|
const resolved = openCmd.replace('{dir}', directoryPath);
|
|
67
|
-
|
|
72
|
+
// Terminal commands always use shell mode and detach
|
|
73
|
+
const useShell = useTerminal || entry.spawnOptions?.shell === true;
|
|
68
74
|
const opts = {
|
|
69
|
-
detached: entry.spawnOptions?.detached ?? !useShell,
|
|
70
|
-
stdio: (entry.spawnOptions?.stdio ?? 'ignore'),
|
|
75
|
+
detached: useTerminal ? true : (entry.spawnOptions?.detached ?? !useShell),
|
|
76
|
+
stdio: (useTerminal ? 'ignore' : (entry.spawnOptions?.stdio ?? 'ignore')),
|
|
71
77
|
shell: useShell,
|
|
72
78
|
};
|
|
73
79
|
try {
|
package/dist/packages/core/src/infrastructure/services/notifications/notification.service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/notifications/notification.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,iBAAiB,EAElB,MAAM,qCAAqC,CAAC;AAE7C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8EAA8E,CAAC;AAEzH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"notification.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/notifications/notification.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,iBAAiB,EAElB,MAAM,qCAAqC,CAAC;AAE7C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8EAA8E,CAAC;AAEzH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAc7D,qBAAa,mBAAoB,YAAW,oBAAoB;IAC9D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAkB;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;gBAEtC,GAAG,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe;IAKlE,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;CAmBvC"}
|
package/dist/packages/core/src/infrastructure/services/notifications/notification.service.js
CHANGED
|
@@ -16,6 +16,10 @@ const EVENT_TYPE_TO_CONFIG_KEY = {
|
|
|
16
16
|
[NotificationEventType.WaitingApproval]: 'waitingApproval',
|
|
17
17
|
[NotificationEventType.AgentCompleted]: 'agentCompleted',
|
|
18
18
|
[NotificationEventType.AgentFailed]: 'agentFailed',
|
|
19
|
+
[NotificationEventType.PrMerged]: 'prMerged',
|
|
20
|
+
[NotificationEventType.PrClosed]: 'prClosed',
|
|
21
|
+
[NotificationEventType.PrChecksPassed]: 'prChecksPassed',
|
|
22
|
+
[NotificationEventType.PrChecksFailed]: 'prChecksFailed',
|
|
19
23
|
};
|
|
20
24
|
export class NotificationService {
|
|
21
25
|
bus;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PR Sync Watcher Service
|
|
3
|
+
*
|
|
4
|
+
* Polls GitHub PR status and CI status for features in the Review lifecycle
|
|
5
|
+
* stage, updating feature records and emitting notifications when transitions
|
|
6
|
+
* are detected. Follows the NotificationWatcherService polling pattern.
|
|
7
|
+
*
|
|
8
|
+
* Maintains in-memory tracking of last-known PR and CI status per feature
|
|
9
|
+
* to avoid duplicate updates and notifications. Features are grouped by
|
|
10
|
+
* repositoryPath for batch `gh pr list` queries.
|
|
11
|
+
*/
|
|
12
|
+
import type { IFeatureRepository } from '../../../application/ports/output/repositories/feature-repository.interface.js';
|
|
13
|
+
import type { IAgentRunRepository } from '../../../application/ports/output/agents/agent-run-repository.interface.js';
|
|
14
|
+
import type { IGitPrService } from '../../../application/ports/output/services/git-pr-service.interface.js';
|
|
15
|
+
import type { INotificationService } from '../../../application/ports/output/services/notification-service.interface.js';
|
|
16
|
+
export declare class PrSyncWatcherService {
|
|
17
|
+
private readonly featureRepo;
|
|
18
|
+
private readonly agentRunRepo;
|
|
19
|
+
private readonly gitPrService;
|
|
20
|
+
private readonly notificationService;
|
|
21
|
+
private readonly pollIntervalMs;
|
|
22
|
+
private readonly trackedFeatures;
|
|
23
|
+
private readonly skippedRepos;
|
|
24
|
+
private intervalId;
|
|
25
|
+
constructor(featureRepo: IFeatureRepository, agentRunRepo: IAgentRunRepository, gitPrService: IGitPrService, notificationService: INotificationService, pollIntervalMs?: number);
|
|
26
|
+
isRunning(): boolean;
|
|
27
|
+
start(): void;
|
|
28
|
+
stop(): void;
|
|
29
|
+
private poll;
|
|
30
|
+
private processRepository;
|
|
31
|
+
private processFeature;
|
|
32
|
+
/** Mark associated agent run as completed so the UI reflects "done" state. */
|
|
33
|
+
private completeAgentRun;
|
|
34
|
+
private emitNotification;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Initialize the PR sync watcher singleton.
|
|
38
|
+
* Must be called once during web server startup.
|
|
39
|
+
*
|
|
40
|
+
* @throws Error if the watcher is already initialized
|
|
41
|
+
*/
|
|
42
|
+
export declare function initializePrSyncWatcher(featureRepo: IFeatureRepository, agentRunRepo: IAgentRunRepository, gitPrService: IGitPrService, notificationService: INotificationService, pollIntervalMs?: number): void;
|
|
43
|
+
/**
|
|
44
|
+
* Get the PR sync watcher singleton.
|
|
45
|
+
*
|
|
46
|
+
* @returns The PR sync watcher service
|
|
47
|
+
* @throws Error if the watcher hasn't been initialized yet
|
|
48
|
+
*/
|
|
49
|
+
export declare function getPrSyncWatcher(): PrSyncWatcherService;
|
|
50
|
+
/**
|
|
51
|
+
* Check if the PR sync watcher has been initialized.
|
|
52
|
+
*/
|
|
53
|
+
export declare function hasPrSyncWatcher(): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Reset the PR sync watcher singleton (for testing purposes only).
|
|
56
|
+
* Stops the watcher if running before resetting.
|
|
57
|
+
*
|
|
58
|
+
* @internal
|
|
59
|
+
*/
|
|
60
|
+
export declare function resetPrSyncWatcher(): void;
|
|
61
|
+
//# sourceMappingURL=pr-sync-watcher.service.d.ts.map
|
package/dist/packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr-sync-watcher.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gFAAgF,CAAC;AACzH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4EAA4E,CAAC;AACtH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wEAAwE,CAAC;AAK5G,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8EAA8E,CAAC;AAiBzH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IACnD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;IAC7C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAuB;IAC3D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqC;IACrE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,UAAU,CAA+C;gBAG/D,WAAW,EAAE,kBAAkB,EAC/B,YAAY,EAAE,mBAAmB,EACjC,YAAY,EAAE,aAAa,EAC3B,mBAAmB,EAAE,oBAAoB,EACzC,cAAc,GAAE,MAAiC;IASnD,SAAS,IAAI,OAAO;IAIpB,KAAK,IAAI,IAAI;IAcb,IAAI,IAAI,IAAI;YASE,IAAI;YAuCJ,iBAAiB;YA6CjB,cAAc;IA4I5B,8EAA8E;YAChE,gBAAgB;IAW9B,OAAO,CAAC,gBAAgB;CAoBzB;AAMD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,kBAAkB,EAC/B,YAAY,EAAE,mBAAmB,EACjC,YAAY,EAAE,aAAa,EAC3B,mBAAmB,EAAE,oBAAoB,EACzC,cAAc,CAAC,EAAE,MAAM,GACtB,IAAI,CAYN;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,oBAAoB,CAQvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAKzC"}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PR Sync Watcher Service
|
|
3
|
+
*
|
|
4
|
+
* Polls GitHub PR status and CI status for features in the Review lifecycle
|
|
5
|
+
* stage, updating feature records and emitting notifications when transitions
|
|
6
|
+
* are detected. Follows the NotificationWatcherService polling pattern.
|
|
7
|
+
*
|
|
8
|
+
* Maintains in-memory tracking of last-known PR and CI status per feature
|
|
9
|
+
* to avoid duplicate updates and notifications. Features are grouped by
|
|
10
|
+
* repositoryPath for batch `gh pr list` queries.
|
|
11
|
+
*/
|
|
12
|
+
import { SdlcLifecycle, PrStatus, CiStatus, AgentRunStatus, NotificationEventType, NotificationSeverity, } from '../../../domain/generated/output.js';
|
|
13
|
+
const DEFAULT_POLL_INTERVAL_MS = 3000;
|
|
14
|
+
const TAG = '[PrSyncWatcher]';
|
|
15
|
+
const CI_STATUS_MAP = {
|
|
16
|
+
success: CiStatus.Success,
|
|
17
|
+
failure: CiStatus.Failure,
|
|
18
|
+
pending: CiStatus.Pending,
|
|
19
|
+
};
|
|
20
|
+
export class PrSyncWatcherService {
|
|
21
|
+
featureRepo;
|
|
22
|
+
agentRunRepo;
|
|
23
|
+
gitPrService;
|
|
24
|
+
notificationService;
|
|
25
|
+
pollIntervalMs;
|
|
26
|
+
trackedFeatures = new Map();
|
|
27
|
+
skippedRepos = new Set();
|
|
28
|
+
intervalId = null;
|
|
29
|
+
constructor(featureRepo, agentRunRepo, gitPrService, notificationService, pollIntervalMs = DEFAULT_POLL_INTERVAL_MS) {
|
|
30
|
+
this.featureRepo = featureRepo;
|
|
31
|
+
this.agentRunRepo = agentRunRepo;
|
|
32
|
+
this.gitPrService = gitPrService;
|
|
33
|
+
this.notificationService = notificationService;
|
|
34
|
+
this.pollIntervalMs = pollIntervalMs;
|
|
35
|
+
}
|
|
36
|
+
isRunning() {
|
|
37
|
+
return this.intervalId !== null;
|
|
38
|
+
}
|
|
39
|
+
start() {
|
|
40
|
+
if (this.intervalId !== null)
|
|
41
|
+
return;
|
|
42
|
+
// eslint-disable-next-line no-console
|
|
43
|
+
console.log(`${TAG} Starting (poll every ${this.pollIntervalMs}ms)`);
|
|
44
|
+
// Run first poll immediately
|
|
45
|
+
void this.poll();
|
|
46
|
+
this.intervalId = setInterval(() => {
|
|
47
|
+
void this.poll();
|
|
48
|
+
}, this.pollIntervalMs);
|
|
49
|
+
}
|
|
50
|
+
stop() {
|
|
51
|
+
if (this.intervalId !== null) {
|
|
52
|
+
clearInterval(this.intervalId);
|
|
53
|
+
this.intervalId = null;
|
|
54
|
+
// eslint-disable-next-line no-console
|
|
55
|
+
console.log(`${TAG} Stopped`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async poll() {
|
|
59
|
+
try {
|
|
60
|
+
const allFeatures = await this.featureRepo.list({ lifecycle: SdlcLifecycle.Review });
|
|
61
|
+
// Include features with a valid repositoryPath (with or without PR data)
|
|
62
|
+
const features = allFeatures.filter((f) => f.repositoryPath);
|
|
63
|
+
if (features.length === 0) {
|
|
64
|
+
this.trackedFeatures.clear();
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// Group features by repositoryPath for batch queries
|
|
68
|
+
const byRepo = new Map();
|
|
69
|
+
for (const feature of features) {
|
|
70
|
+
const group = byRepo.get(feature.repositoryPath) ?? [];
|
|
71
|
+
group.push(feature);
|
|
72
|
+
byRepo.set(feature.repositoryPath, group);
|
|
73
|
+
}
|
|
74
|
+
// Process each repository
|
|
75
|
+
for (const [repoPath, repoFeatures] of byRepo) {
|
|
76
|
+
await this.processRepository(repoPath, repoFeatures);
|
|
77
|
+
}
|
|
78
|
+
// Prune features no longer in Review
|
|
79
|
+
const currentFeatureIds = new Set(features.map((f) => f.id));
|
|
80
|
+
for (const trackedId of this.trackedFeatures.keys()) {
|
|
81
|
+
if (!currentFeatureIds.has(trackedId)) {
|
|
82
|
+
this.trackedFeatures.delete(trackedId);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
88
|
+
// eslint-disable-next-line no-console
|
|
89
|
+
console.warn(`${TAG} Poll failed: ${msg}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async processRepository(repoPath, features) {
|
|
93
|
+
if (this.skippedRepos.has(repoPath))
|
|
94
|
+
return;
|
|
95
|
+
// Skip repos without a git remote — gh pr list will always fail
|
|
96
|
+
try {
|
|
97
|
+
if (!(await this.gitPrService.hasRemote(repoPath))) {
|
|
98
|
+
// eslint-disable-next-line no-console
|
|
99
|
+
console.log(`${TAG} Skipping ${repoPath} (no git remote)`);
|
|
100
|
+
this.skippedRepos.add(repoPath);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
let prStatuses;
|
|
108
|
+
try {
|
|
109
|
+
prStatuses = await this.gitPrService.listPrStatuses(repoPath);
|
|
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} listPrStatuses failed for ${repoPath}: ${msg}`);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
// Build lookups by PR number and by head branch name.
|
|
118
|
+
// Multiple PRs can share the same headRefName (e.g. old merged PR + new open PR).
|
|
119
|
+
// Prefer Open PRs so we don't match stale merged/closed ones.
|
|
120
|
+
const statusByNumber = new Map();
|
|
121
|
+
const statusByBranch = new Map();
|
|
122
|
+
for (const pr of prStatuses) {
|
|
123
|
+
statusByNumber.set(pr.number, pr);
|
|
124
|
+
if (pr.headRefName) {
|
|
125
|
+
const existing = statusByBranch.get(pr.headRefName);
|
|
126
|
+
if (!existing || (existing.state !== PrStatus.Open && pr.state === PrStatus.Open)) {
|
|
127
|
+
statusByBranch.set(pr.headRefName, pr);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
for (const feature of features) {
|
|
132
|
+
await this.processFeature(feature, statusByNumber, statusByBranch);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async processFeature(feature, statusByNumber, statusByBranch) {
|
|
136
|
+
// If feature has no PR data, try to discover an Open PR by matching branch name.
|
|
137
|
+
// Only link Open PRs — merged/closed PRs with the same branch are likely stale
|
|
138
|
+
// from a previous iteration. The watcher will catch Open→Merged transitions
|
|
139
|
+
// on subsequent polls once the PR is linked.
|
|
140
|
+
if (!feature.pr) {
|
|
141
|
+
const matchedPr = statusByBranch.get(feature.branch);
|
|
142
|
+
if (matchedPr?.state !== PrStatus.Open)
|
|
143
|
+
return;
|
|
144
|
+
// eslint-disable-next-line no-console
|
|
145
|
+
console.log(`${TAG} Discovered PR #${matchedPr.number} for "${feature.name}" via branch "${feature.branch}"`);
|
|
146
|
+
feature.pr = {
|
|
147
|
+
url: matchedPr.url,
|
|
148
|
+
number: matchedPr.number,
|
|
149
|
+
status: PrStatus.Open,
|
|
150
|
+
};
|
|
151
|
+
this.trackedFeatures.set(feature.id, {
|
|
152
|
+
prStatus: PrStatus.Open,
|
|
153
|
+
ciStatus: undefined,
|
|
154
|
+
featureName: feature.name,
|
|
155
|
+
});
|
|
156
|
+
await this.featureRepo.update(feature);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const pr = feature.pr;
|
|
160
|
+
const prStatusInfo = statusByNumber.get(pr.number);
|
|
161
|
+
let needsUpdate = false;
|
|
162
|
+
// Initialize or retrieve tracked state
|
|
163
|
+
const prevState = this.trackedFeatures.get(feature.id);
|
|
164
|
+
if (!prevState) {
|
|
165
|
+
// First time seeing this feature — initialize tracking
|
|
166
|
+
this.trackedFeatures.set(feature.id, {
|
|
167
|
+
prStatus: pr.status,
|
|
168
|
+
ciStatus: pr.ciStatus,
|
|
169
|
+
featureName: feature.name,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
const tracked = this.trackedFeatures.get(feature.id);
|
|
173
|
+
// Check PR status transition
|
|
174
|
+
if (prStatusInfo && prStatusInfo.state !== tracked.prStatus) {
|
|
175
|
+
const newPrStatus = prStatusInfo.state;
|
|
176
|
+
// eslint-disable-next-line no-console
|
|
177
|
+
console.log(`${TAG} PR #${pr.number} status changed: ${tracked.prStatus} -> ${newPrStatus} for "${feature.name}"`);
|
|
178
|
+
feature.pr = { ...pr, status: newPrStatus };
|
|
179
|
+
if (newPrStatus === PrStatus.Merged) {
|
|
180
|
+
feature.lifecycle = SdlcLifecycle.Maintain;
|
|
181
|
+
await this.completeAgentRun(feature);
|
|
182
|
+
this.emitNotification(NotificationEventType.PrMerged, feature.id, feature.agentRunId ?? '', feature.name, `PR #${pr.number} merged for ${feature.name}`, NotificationSeverity.Success);
|
|
183
|
+
}
|
|
184
|
+
else if (newPrStatus === PrStatus.Closed) {
|
|
185
|
+
this.emitNotification(NotificationEventType.PrClosed, feature.id, feature.agentRunId ?? '', feature.name, `PR #${pr.number} closed for ${feature.name}`, NotificationSeverity.Warning);
|
|
186
|
+
}
|
|
187
|
+
tracked.prStatus = newPrStatus;
|
|
188
|
+
needsUpdate = true;
|
|
189
|
+
}
|
|
190
|
+
// Check CI status transition
|
|
191
|
+
try {
|
|
192
|
+
const ciResult = await this.gitPrService.getCiStatus(feature.repositoryPath, feature.branch);
|
|
193
|
+
const newCiStatus = CI_STATUS_MAP[ciResult.status] ?? CiStatus.Pending;
|
|
194
|
+
if (newCiStatus !== tracked.ciStatus) {
|
|
195
|
+
// eslint-disable-next-line no-console
|
|
196
|
+
console.log(`${TAG} CI status changed: ${tracked.ciStatus ?? 'none'} -> ${newCiStatus} for "${feature.name}"`);
|
|
197
|
+
feature.pr = { ...(feature.pr ?? pr), ciStatus: newCiStatus };
|
|
198
|
+
if (newCiStatus === CiStatus.Success) {
|
|
199
|
+
this.emitNotification(NotificationEventType.PrChecksPassed, feature.id, feature.agentRunId ?? '', feature.name, `CI checks passed for ${feature.name}`, NotificationSeverity.Success);
|
|
200
|
+
}
|
|
201
|
+
else if (newCiStatus === CiStatus.Failure) {
|
|
202
|
+
this.emitNotification(NotificationEventType.PrChecksFailed, feature.id, feature.agentRunId ?? '', feature.name, `CI checks failed for ${feature.name}`, NotificationSeverity.Error);
|
|
203
|
+
}
|
|
204
|
+
tracked.ciStatus = newCiStatus;
|
|
205
|
+
needsUpdate = true;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
210
|
+
// eslint-disable-next-line no-console
|
|
211
|
+
console.warn(`${TAG} getCiStatus failed for "${feature.name}": ${msg}`);
|
|
212
|
+
}
|
|
213
|
+
if (needsUpdate) {
|
|
214
|
+
await this.featureRepo.update(feature);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/** Mark associated agent run as completed so the UI reflects "done" state. */
|
|
218
|
+
async completeAgentRun(feature) {
|
|
219
|
+
if (!feature.agentRunId)
|
|
220
|
+
return;
|
|
221
|
+
try {
|
|
222
|
+
await this.agentRunRepo.updateStatus(feature.agentRunId, AgentRunStatus.completed);
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
226
|
+
// eslint-disable-next-line no-console
|
|
227
|
+
console.warn(`${TAG} Failed to complete agent run ${feature.agentRunId}: ${msg}`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
emitNotification(eventType, featureId, agentRunId, featureName, message, severity) {
|
|
231
|
+
const event = {
|
|
232
|
+
eventType,
|
|
233
|
+
featureId,
|
|
234
|
+
agentRunId,
|
|
235
|
+
featureName,
|
|
236
|
+
message,
|
|
237
|
+
severity,
|
|
238
|
+
timestamp: new Date().toISOString(),
|
|
239
|
+
};
|
|
240
|
+
this.notificationService.notify(event);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// --- Singleton accessors (follows NotificationWatcherService pattern) ---
|
|
244
|
+
let watcherInstance = null;
|
|
245
|
+
/**
|
|
246
|
+
* Initialize the PR sync watcher singleton.
|
|
247
|
+
* Must be called once during web server startup.
|
|
248
|
+
*
|
|
249
|
+
* @throws Error if the watcher is already initialized
|
|
250
|
+
*/
|
|
251
|
+
export function initializePrSyncWatcher(featureRepo, agentRunRepo, gitPrService, notificationService, pollIntervalMs) {
|
|
252
|
+
if (watcherInstance !== null) {
|
|
253
|
+
throw new Error('PR sync watcher already initialized. Cannot re-initialize.');
|
|
254
|
+
}
|
|
255
|
+
watcherInstance = new PrSyncWatcherService(featureRepo, agentRunRepo, gitPrService, notificationService, pollIntervalMs);
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Get the PR sync watcher singleton.
|
|
259
|
+
*
|
|
260
|
+
* @returns The PR sync watcher service
|
|
261
|
+
* @throws Error if the watcher hasn't been initialized yet
|
|
262
|
+
*/
|
|
263
|
+
export function getPrSyncWatcher() {
|
|
264
|
+
if (watcherInstance === null) {
|
|
265
|
+
throw new Error('PR sync watcher not initialized. Call initializePrSyncWatcher() during web server startup.');
|
|
266
|
+
}
|
|
267
|
+
return watcherInstance;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Check if the PR sync watcher has been initialized.
|
|
271
|
+
*/
|
|
272
|
+
export function hasPrSyncWatcher() {
|
|
273
|
+
return watcherInstance !== null;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Reset the PR sync watcher singleton (for testing purposes only).
|
|
277
|
+
* Stops the watcher if running before resetting.
|
|
278
|
+
*
|
|
279
|
+
* @internal
|
|
280
|
+
*/
|
|
281
|
+
export function resetPrSyncWatcher() {
|
|
282
|
+
if (watcherInstance !== null) {
|
|
283
|
+
watcherInstance.stop();
|
|
284
|
+
}
|
|
285
|
+
watcherInstance = null;
|
|
286
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-installer.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/tool-installer/tool-installer.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sEAAsE,CAAC;AAClH,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EAEnB,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"tool-installer.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/tool-installer/tool-installer.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sEAAsE,CAAC;AAClH,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EAEnB,MAAM,qCAAqC,CAAC;AA6C7C,qBACa,wBAAyB,YAAW,qBAAqB;IACpE;;OAEG;IACG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IA4B1E;;;OAGG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI;IAqB9D;;;OAGG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAChC,OAAO,CAAC,sBAAsB,CAAC;IAuElC;;OAEG;IACH,OAAO,CAAC,6BAA6B;CA4BtC"}
|
package/dist/packages/core/src/infrastructure/services/tool-installer/tool-installer.service.js
CHANGED
|
@@ -33,12 +33,25 @@ function resolveBinary(metadata) {
|
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* Check if a binary exists in the system PATH using 'which' command.
|
|
36
|
-
*
|
|
36
|
+
*
|
|
37
|
+
* `which` exits with code 1 when the binary is simply not in PATH.
|
|
38
|
+
* Node's execFile wraps that as an Error, but it's a normal "not found"
|
|
39
|
+
* result. Only truly unexpected failures (ENOENT for `which` itself,
|
|
40
|
+
* EACCES, signals, etc.) are surfaced via the `error` field.
|
|
37
41
|
*/
|
|
38
42
|
const checkBinaryExists = (binary) => {
|
|
39
43
|
return new Promise((resolve) => {
|
|
40
44
|
execFile('which', [binary], (err) => {
|
|
41
|
-
|
|
45
|
+
if (!err)
|
|
46
|
+
return resolve({ found: true });
|
|
47
|
+
// execFile errors from a non-zero exit code have a numeric `code` property.
|
|
48
|
+
// That's the normal "binary not found in PATH" case.
|
|
49
|
+
const code = err.code;
|
|
50
|
+
if (code === undefined || typeof code === 'number') {
|
|
51
|
+
return resolve({ found: false, notInPath: true });
|
|
52
|
+
}
|
|
53
|
+
// Anything else (ENOENT for `which` itself, EACCES, etc.) is a real error.
|
|
54
|
+
resolve({ found: false, error: err });
|
|
42
55
|
});
|
|
43
56
|
});
|
|
44
57
|
};
|
|
@@ -56,15 +69,13 @@ let ToolInstallerServiceImpl = class ToolInstallerServiceImpl {
|
|
|
56
69
|
if (result.found) {
|
|
57
70
|
return createAvailableStatus(toolName);
|
|
58
71
|
}
|
|
59
|
-
|
|
60
|
-
if (result.error?.message.includes('not found')) {
|
|
61
|
-
// Binary doesn't exist in PATH - create suggestions for installation
|
|
72
|
+
if (result.notInPath) {
|
|
62
73
|
const suggestions = this.createInstallationSuggestions(metadata);
|
|
63
74
|
return createMissingStatus(toolName, suggestions);
|
|
64
75
|
}
|
|
65
|
-
//
|
|
76
|
+
// Genuine error (e.g. `which` binary missing, permission denied)
|
|
66
77
|
const errorMessage = result.error?.message ?? 'Unknown error checking availability';
|
|
67
|
-
return createErrorStatus(toolName,
|
|
78
|
+
return createErrorStatus(toolName, errorMessage);
|
|
68
79
|
}
|
|
69
80
|
catch (error) {
|
|
70
81
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
@@ -15,7 +15,9 @@ export interface ToolMetadata {
|
|
|
15
15
|
/** Detailed description */
|
|
16
16
|
description: string;
|
|
17
17
|
/** Tool tags for grouping in listings. A tool can belong to multiple categories. */
|
|
18
|
-
tags: ('ide' | 'cli-agent')[];
|
|
18
|
+
tags: ('ide' | 'cli-agent' | 'vcs')[];
|
|
19
|
+
/** URL to the tool's icon/logo image */
|
|
20
|
+
iconUrl?: string;
|
|
19
21
|
/** Binary name to check with 'which' command (string or per-platform map) */
|
|
20
22
|
binary: string | Record<string, string>;
|
|
21
23
|
/** Package manager or installation method */
|
|
@@ -30,6 +32,8 @@ export interface ToolMetadata {
|
|
|
30
32
|
verifyCommand: string;
|
|
31
33
|
/** Whether the tool supports automated installation (default: true) */
|
|
32
34
|
autoInstall?: boolean;
|
|
35
|
+
/** Whether this tool is required for the platform to function (default: false) */
|
|
36
|
+
required?: boolean;
|
|
33
37
|
/** Command to open a directory in this tool.
|
|
34
38
|
* String format: "code {dir}" — single command for all platforms.
|
|
35
39
|
* Object format: { "linux": "antigravity {dir}", "darwin": "agy {dir}" } — per-platform commands. */
|
|
@@ -42,6 +46,12 @@ export interface ToolMetadata {
|
|
|
42
46
|
stdio?: 'ignore' | 'inherit' | 'pipe';
|
|
43
47
|
detached?: boolean;
|
|
44
48
|
};
|
|
49
|
+
/** Platform-specific command to launch this tool in a new terminal window.
|
|
50
|
+
* Used when launching from the web UI where no terminal is available.
|
|
51
|
+
* When set, the launcher spawns a new terminal window with this command.
|
|
52
|
+
* Supports {dir} placeholder like openDirectory.
|
|
53
|
+
* Example: "x-terminal-emulator -e bash -c 'cd {dir} && claude'" */
|
|
54
|
+
terminalCommand?: string | Record<string, string>;
|
|
45
55
|
}
|
|
46
56
|
export declare const TOOL_METADATA: Record<string, ToolMetadata>;
|
|
47
57
|
/**
|
package/dist/packages/core/src/infrastructure/services/tool-installer/tool-metadata.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-metadata.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/tool-installer/tool-metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,YAAY;IAC3B,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IAEb,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAEhB,2BAA2B;IAC3B,WAAW,EAAE,MAAM,CAAC;IAEpB,oFAAoF;IACpF,IAAI,EAAE,CAAC,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"tool-metadata.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/tool-installer/tool-metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,YAAY;IAC3B,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IAEb,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAEhB,2BAA2B;IAC3B,WAAW,EAAE,MAAM,CAAC;IAEpB,oFAAoF;IACpF,IAAI,EAAE,CAAC,KAAK,GAAG,WAAW,GAAG,KAAK,CAAC,EAAE,CAAC;IAEtC,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,6EAA6E;IAC7E,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAExC,6CAA6C;IAC7C,cAAc,EAAE,MAAM,CAAC;IAEvB,wFAAwF;IACxF,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAEhB,iCAAiC;IACjC,gBAAgB,EAAE,MAAM,CAAC;IAEzB,8DAA8D;IAC9D,aAAa,EAAE,MAAM,CAAC;IAEtB,uEAAuE;IACvE,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;yGAEqG;IACrG,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEhD;;iGAE6F;IAC7F,YAAY,CAAC,EAAE;QACb,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,KAAK,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;QACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC;IAEF;;;;wEAIoE;IACpE,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnD;AA8CD,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAsB,CAAC;AAE9E;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,CAExD"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Tool JSON Definitions
|
|
2
|
+
|
|
3
|
+
Each `.json` file defines a development tool that shep can install, verify, and launch.
|
|
4
|
+
Files are loaded dynamically by `tool-metadata.ts` — the filename (minus `.json`) becomes the tool ID.
|
|
5
|
+
|
|
6
|
+
## Schema
|
|
7
|
+
|
|
8
|
+
| Field | Type | Required | Description |
|
|
9
|
+
| ------------------ | --------------------------------- | -------- | ------------------------------------------------------------------------ |
|
|
10
|
+
| `name` | `string` | Yes | Human-readable display name |
|
|
11
|
+
| `summary` | `string` | Yes | One-line description |
|
|
12
|
+
| `description` | `string` | Yes | Detailed description |
|
|
13
|
+
| `tags` | `("ide"\|"cli-agent"\|"vcs")[]` | Yes | Categories for filtering in UI and CLI |
|
|
14
|
+
| `iconUrl` | `string` | No | URL to SVG/PNG icon (use cdn.simpleicons.org when possible) |
|
|
15
|
+
| `binary` | `string \| Record<string,string>` | Yes | Binary name for `which` check. Per-platform map if differs |
|
|
16
|
+
| `packageManager` | `string` | Yes | Install method label (apt, brew, curl, manual, download) |
|
|
17
|
+
| `commands` | `Record<string,string>` | Yes | Platform-keyed install commands (`linux`, `darwin`) |
|
|
18
|
+
| `timeout` | `number` | Yes | Install timeout in ms (typically 300000) |
|
|
19
|
+
| `documentationUrl` | `string` | Yes | Official docs URL |
|
|
20
|
+
| `verifyCommand` | `string` | Yes | Command to verify installation (e.g. `git --version`) |
|
|
21
|
+
| `autoInstall` | `boolean` | No | `true` (default) = run commands automatically. `false` = manual download |
|
|
22
|
+
| `required` | `boolean` | No | `true` = tool is required for platform to function |
|
|
23
|
+
| `openDirectory` | `string \| Record<string,string>` | No | Command to open a directory. Use `{dir}` placeholder |
|
|
24
|
+
| `spawnOptions` | `object` | No | Override spawn behavior (see below) |
|
|
25
|
+
| `terminalCommand` | `string \| Record<string,string>` | No | Command to open tool in a **new terminal window** from web UI |
|
|
26
|
+
|
|
27
|
+
## Spawn Options
|
|
28
|
+
|
|
29
|
+
GUI tools (IDEs) use defaults: `{ detached: true, stdio: "ignore" }` — fire and forget.
|
|
30
|
+
CLI agents need: `{ shell: true, stdio: "inherit", detached: false }` — run in current terminal.
|
|
31
|
+
|
|
32
|
+
## Terminal Command
|
|
33
|
+
|
|
34
|
+
CLI agents launched from the web UI have no terminal to inherit. The `terminalCommand` field
|
|
35
|
+
provides a platform-specific command that opens a new terminal window:
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
"terminalCommand": {
|
|
39
|
+
"linux": "x-terminal-emulator -e bash -c 'cd {dir} && exec claude'",
|
|
40
|
+
"darwin": "open -a Terminal.app bash -c 'cd {dir} && exec claude'"
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The launcher auto-detects TTY: CLI launch uses `openDirectory`, web launch uses `terminalCommand`.
|
|
45
|
+
|
|
46
|
+
## Adding a New Tool
|
|
47
|
+
|
|
48
|
+
1. Create `<tool-id>.json` in this directory
|
|
49
|
+
2. Fill all required fields
|
|
50
|
+
3. Validate icon URL returns 200: `curl -sI <url> | head -1`
|
|
51
|
+
4. For manual-install tools: set `autoInstall: false`, use plain text in `commands` (no `echo`)
|
|
52
|
+
5. For CLI agents: add `spawnOptions` + `terminalCommand`
|
|
53
|
+
6. Run `pnpm build && pnpm test:unit` to verify
|
|
54
|
+
|
|
55
|
+
## Tags
|
|
56
|
+
|
|
57
|
+
| Tag | Meaning | Examples |
|
|
58
|
+
| ----------- | ------------------------------ | ----------------------- |
|
|
59
|
+
| `ide` | GUI code editor | VS Code, Cursor, Zed |
|
|
60
|
+
| `cli-agent` | Terminal-based AI coding agent | Claude Code, Cursor CLI |
|
|
61
|
+
| `vcs` | Version control tool | Git, GitHub CLI |
|
|
62
|
+
|
|
63
|
+
Tools can have multiple tags. A tool appears in all matching filter tabs in the UI.
|