@shepai/cli 1.128.0 → 1.129.0-pr410.ed5d9df
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/use-cases/features/delete-feature.use-case.d.ts +1 -0
- package/dist/packages/core/src/application/use-cases/features/delete-feature.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/delete-feature.use-case.js +46 -15
- package/dist/packages/core/src/application/use-cases/repositories/add-repository.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/repositories/add-repository.use-case.js +5 -2
- package/dist/packages/core/src/infrastructure/repositories/sqlite-repository.repository.js +2 -2
- package/dist/src/presentation/cli/commands/feat/del.command.d.ts +2 -1
- package/dist/src/presentation/cli/commands/feat/del.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/feat/del.command.js +28 -2
- package/dist/src/presentation/web/app/(dashboard)/get-graph-data.d.ts.map +1 -1
- package/dist/src/presentation/web/app/(dashboard)/get-graph-data.js +61 -19
- package/dist/src/presentation/web/app/actions/delete-feature.d.ts +1 -1
- package/dist/src/presentation/web/app/actions/delete-feature.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/delete-feature.js +3 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +3 -3
- package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog-config.d.ts +2 -1
- package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog-config.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.d.ts +1 -1
- package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.js +12 -2
- package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.stories.d.ts +3 -0
- package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.stories.js +17 -0
- package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node.js +3 -3
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +2 -2
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +1 -1
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +2 -2
- package/dist/src/presentation/web/hooks/use-graph-state.d.ts.map +1 -1
- package/dist/src/presentation/web/hooks/use-graph-state.js +1 -1
- package/dist/src/presentation/web/lib/derive-graph.d.ts +1 -1
- package/dist/src/presentation/web/lib/derive-graph.d.ts.map +1 -1
- package/dist/src/presentation/web/lib/derive-graph.js +5 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +2 -2
- 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/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +24 -24
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +24 -24
- 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/server-reference-manifest.json +30 -30
- 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/server-reference-manifest.json +30 -30
- 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/server-reference-manifest.json +22 -22
- 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/server-reference-manifest.json +24 -24
- 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/server-reference-manifest.json +30 -30
- 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/server-reference-manifest.json +30 -30
- 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/server-reference-manifest.json +22 -22
- 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/server-reference-manifest.json +22 -22
- 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.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/server-reference-manifest.json +3 -3
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/settings/page/server-reference-manifest.json +8 -8
- 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/server-reference-manifest.json +8 -8
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +8 -8
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +3 -3
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +1 -1
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_4e741df2.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_4e741df2.js.map +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/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_026fdffa.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_026fdffa.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_8b91e197.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_8b91e197.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0e842eba._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0e842eba._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2f886f77._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__60684242._.js +2 -2
- 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]__755cfe02._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__755cfe02._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a628fb91._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a628fb91._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__bfba58e6._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__bfba58e6._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c3ab8422._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c3ab8422._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f4a463ee._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f4a463ee._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_02ec1aea._.js +1 -1
- package/web/.next/server/chunks/ssr/_02ec1aea._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_087a3e78._.js → _0a5b0b02._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_087a3e78._.js.map → _0a5b0b02._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_7dca1882._.js +1 -1
- package/web/.next/server/chunks/ssr/_7dca1882._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_a9f57758._.js +1 -1
- package/web/.next/server/chunks/ssr/_a9f57758._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_c2314ba5._.js → _d5ed80ec._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_c2314ba5._.js.map → _d5ed80ec._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_d8575088._.js +1 -1
- package/web/.next/server/chunks/ssr/_d8575088._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_f39a1adb._.js +1 -1
- package/web/.next/server/chunks/ssr/_f39a1adb._.js.map +1 -1
- 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/src_presentation_web_53cd7c96._.js +3 -0
- package/web/.next/server/chunks/ssr/{src_presentation_web_39dc6c69._.js.map → src_presentation_web_53cd7c96._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_8e7fe0d1._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_8e7fe0d1._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_ca051134.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_ca051134.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_b9023017._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_b9023017._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +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/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +38 -38
- package/web/.next/static/chunks/{d534a122561e6231.js → 02a03be471ed7fc0.js} +1 -1
- package/web/.next/static/chunks/{3d5d625e02456fab.js → 0e8cfccaec7161e1.js} +1 -1
- package/web/.next/static/chunks/{6d8be29584ad0fdd.js → 445f9440d2e19556.js} +1 -1
- package/web/.next/static/chunks/{e22192217a4fc0d4.js → 4e973d3211708b04.js} +1 -1
- package/web/.next/static/chunks/5411615c8f376ba2.js +1 -0
- package/web/.next/static/chunks/{1ccaceb64fe9084f.js → 59ce8663d782b152.js} +1 -1
- package/web/.next/static/chunks/{4b9ea85ea5fbc162.js → 747b4087a4627544.js} +1 -1
- package/web/.next/static/chunks/{3c0cef220743905a.js → 7ad143a8a2f1c5c9.js} +1 -1
- package/web/.next/static/chunks/{eea5d09deb8afd9a.js → a6c54fd7bc04ea3f.js} +1 -1
- package/web/.next/static/chunks/{c1537a58c2e5625b.js → af2d9b6f87f1c945.js} +2 -2
- package/web/.next/static/chunks/{8f979abfe5512674.js → d3b43898d0abd644.js} +1 -1
- package/web/.next/static/chunks/f67901f8262497f5.js +2 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_39dc6c69._.js +0 -3
- package/web/.next/static/chunks/776e7f0d6b402430.js +0 -2
- package/web/.next/static/chunks/822ed01254f97121.js +0 -1
- /package/web/.next/static/{aZANFTRivKlrY7NZ-ovtr → NYA9ccZUUDf9yt_EGEyjo}/_buildManifest.js +0 -0
- /package/web/.next/static/{aZANFTRivKlrY7NZ-ovtr → NYA9ccZUUDf9yt_EGEyjo}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{aZANFTRivKlrY7NZ-ovtr → NYA9ccZUUDf9yt_EGEyjo}/_ssgManifest.js +0 -0
|
@@ -21,6 +21,7 @@ import type { IGitPrService } from '../../ports/output/services/git-pr-service.i
|
|
|
21
21
|
export interface DeleteFeatureOptions {
|
|
22
22
|
cleanup?: boolean;
|
|
23
23
|
cascadeDelete?: boolean;
|
|
24
|
+
closePr?: boolean;
|
|
24
25
|
}
|
|
25
26
|
export declare class DeleteFeatureUseCase {
|
|
26
27
|
private readonly featureRepo;
|
package/dist/packages/core/src/application/use-cases/features/delete-feature.use-case.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete-feature.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/delete-feature.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;AAEnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAC1G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2DAA2D,CAAC;AAClG,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8DAA8D,CAAC;AAChH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6DAA6D,CAAC;AACvG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yDAAyD,CAAC;AAE7F,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"delete-feature.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/delete-feature.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;AAEnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAC1G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2DAA2D,CAAC;AAClG,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8DAA8D,CAAC;AAChH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6DAA6D,CAAC;AACvG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yDAAyD,CAAC;AAE7F,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qBACa,oBAAoB;IAEC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAE5D,OAAO,CAAC,QAAQ,CAAC,cAAc;IACA,OAAO,CAAC,QAAQ,CAAC,OAAO;IAC9B,OAAO,CAAC,QAAQ,CAAC,YAAY;gBALP,WAAW,EAAE,kBAAkB,EACjC,eAAe,EAAE,gBAAgB,EAE7D,cAAc,EAAE,2BAA2B,EACZ,OAAO,EAAE,mBAAmB,EAClC,YAAY,EAAE,aAAa;IAGjE,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC;IA8BlF,oGAAoG;YACtF,gBAAgB;IAW9B,0DAA0D;YAC5C,iBAAiB;IAQ/B,6DAA6D;YAC/C,yBAAyB;IAevC,sDAAsD;YACxC,sBAAsB;IAYpC,6EAA6E;YAC/D,oBAAoB;CA+EnC"}
|
|
@@ -25,7 +25,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
25
25
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
26
26
|
};
|
|
27
27
|
import { injectable, inject } from 'tsyringe';
|
|
28
|
-
import { AgentRunStatus, SdlcLifecycle } from '../../../domain/generated/output.js';
|
|
28
|
+
import { AgentRunStatus, PrStatus, SdlcLifecycle } from '../../../domain/generated/output.js';
|
|
29
29
|
let DeleteFeatureUseCase = class DeleteFeatureUseCase {
|
|
30
30
|
featureRepo;
|
|
31
31
|
worktreeService;
|
|
@@ -93,6 +93,10 @@ let DeleteFeatureUseCase = class DeleteFeatureUseCase {
|
|
|
93
93
|
});
|
|
94
94
|
// Soft-delete: sets deletedAt, hiding from normal queries
|
|
95
95
|
await this.featureRepo.softDelete(feature.id);
|
|
96
|
+
// Sync the in-memory feature object so subsequent update() calls
|
|
97
|
+
// (e.g. PR status update in cleanup) don't overwrite deleted_at back to null.
|
|
98
|
+
feature.lifecycle = SdlcLifecycle.Deleting;
|
|
99
|
+
feature.deletedAt = new Date();
|
|
96
100
|
}
|
|
97
101
|
/** Recursively cleanup all children (depth-first). */
|
|
98
102
|
async cascadeCleanupChildren(parentId, options) {
|
|
@@ -133,22 +137,49 @@ let DeleteFeatureUseCase = class DeleteFeatureUseCase {
|
|
|
133
137
|
}
|
|
134
138
|
const cleanup = options?.cleanup !== false;
|
|
135
139
|
if (cleanup) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
140
|
+
const shouldDeleteRemote = options?.closePr !== false;
|
|
141
|
+
// Delete local branch, and also remote if closePr is enabled.
|
|
142
|
+
// deleteBranch(cwd, branch, true) deletes local then remote in one call,
|
|
143
|
+
// so we must NOT delete local separately when also deleting remote.
|
|
144
|
+
if (shouldDeleteRemote) {
|
|
145
|
+
let remoteDeleted = false;
|
|
146
|
+
try {
|
|
147
|
+
const remoteExists = await this.worktreeService.remoteBranchExists(feature.repositoryPath, feature.branch);
|
|
148
|
+
if (remoteExists) {
|
|
149
|
+
// Delete local + remote in one call (deleteBranch does local first, then remote)
|
|
150
|
+
await this.gitPrService.deleteBranch(feature.repositoryPath, feature.branch, true);
|
|
151
|
+
remoteDeleted = true;
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
// No remote branch — just delete local
|
|
155
|
+
await this.gitPrService.deleteBranch(feature.repositoryPath, feature.branch);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// Branch cleanup is best-effort
|
|
160
|
+
}
|
|
161
|
+
// Update pr.status to Closed after remote branch deletion (GitHub auto-closes the PR)
|
|
162
|
+
if (remoteDeleted && feature.pr?.status === PrStatus.Open) {
|
|
163
|
+
try {
|
|
164
|
+
await this.featureRepo.update({
|
|
165
|
+
...feature,
|
|
166
|
+
pr: { ...feature.pr, status: PrStatus.Closed },
|
|
167
|
+
updatedAt: new Date(),
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
// PR status update is best-effort
|
|
172
|
+
}
|
|
148
173
|
}
|
|
149
174
|
}
|
|
150
|
-
|
|
151
|
-
//
|
|
175
|
+
else {
|
|
176
|
+
// closePr is false — only delete local branch, preserve remote (and the PR)
|
|
177
|
+
try {
|
|
178
|
+
await this.gitPrService.deleteBranch(feature.repositoryPath, feature.branch);
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
// Branch might not exist
|
|
182
|
+
}
|
|
152
183
|
}
|
|
153
184
|
}
|
|
154
185
|
}
|
package/dist/packages/core/src/application/use-cases/repositories/add-repository.use-case.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-repository.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/repositories/add-repository.use-case.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oEAAoE,CAAC;AAEhH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAcD,qBACa,oBAAoB;IAG7B,OAAO,CAAC,QAAQ,CAAC,cAAc;gBAAd,cAAc,EAAE,qBAAqB;IAGlD,OAAO,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"add-repository.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/repositories/add-repository.use-case.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oEAAoE,CAAC;AAEhH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAcD,qBACa,oBAAoB;IAG7B,OAAO,CAAC,QAAQ,CAAC,cAAc;gBAAd,cAAc,EAAE,qBAAqB;IAGlD,OAAO,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,CAAC;CAiC9D"}
|
package/dist/packages/core/src/application/use-cases/repositories/add-repository.use-case.js
CHANGED
|
@@ -41,11 +41,14 @@ let AddRepositoryUseCase = class AddRepositoryUseCase {
|
|
|
41
41
|
if (existing) {
|
|
42
42
|
return existing;
|
|
43
43
|
}
|
|
44
|
-
// Check for soft-deleted repository — restore it instead of creating a duplicate
|
|
44
|
+
// Check for soft-deleted repository — restore it instead of creating a duplicate.
|
|
45
|
+
// Reset createdAt so the restored repo sorts as "newest" on the canvas
|
|
46
|
+
// (otherwise the old createdAt would place it above repos added later).
|
|
45
47
|
const deleted = await this.repositoryRepo.findByPathIncludingDeleted(normalizedPath);
|
|
46
48
|
if (deleted) {
|
|
49
|
+
const now = new Date();
|
|
47
50
|
await this.repositoryRepo.restore(deleted.id);
|
|
48
|
-
return { ...deleted, deletedAt: undefined, updatedAt:
|
|
51
|
+
return { ...deleted, deletedAt: undefined, createdAt: now, updatedAt: now };
|
|
49
52
|
}
|
|
50
53
|
const now = new Date();
|
|
51
54
|
const name = input.name ?? normalizedPath.split('/').pop() ?? normalizedPath;
|
|
@@ -94,8 +94,8 @@ let SQLiteRepositoryRepository = SQLiteRepositoryRepository_1 = class SQLiteRepo
|
|
|
94
94
|
}
|
|
95
95
|
async restore(id) {
|
|
96
96
|
const now = Date.now();
|
|
97
|
-
const stmt = this.db.prepare('UPDATE repositories SET deleted_at = NULL, updated_at = ? WHERE id = ?');
|
|
98
|
-
stmt.run(now, id);
|
|
97
|
+
const stmt = this.db.prepare('UPDATE repositories SET deleted_at = NULL, created_at = ?, updated_at = ? WHERE id = ?');
|
|
98
|
+
stmt.run(now, now, id);
|
|
99
99
|
}
|
|
100
100
|
static normalizeRemoteUrl(url) {
|
|
101
101
|
return url.replace(/\.git$/, '').toLowerCase();
|
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
* Deletes a feature, its worktree, and cancels any running agent.
|
|
5
5
|
* Optionally cleans up worktree and branches (local + remote).
|
|
6
6
|
*
|
|
7
|
-
* Usage: shep feat del <id> [--force] [--no-cleanup]
|
|
7
|
+
* Usage: shep feat del <id> [--force] [--no-cleanup] [--no-close-pr]
|
|
8
8
|
*
|
|
9
9
|
* @example
|
|
10
10
|
* $ shep feat del feat-123
|
|
11
11
|
* $ shep feat del feat-123 --force
|
|
12
12
|
* $ shep feat del feat-123 --force --no-cleanup
|
|
13
|
+
* $ shep feat del feat-123 --force --no-close-pr
|
|
13
14
|
*/
|
|
14
15
|
import { Command } from 'commander';
|
|
15
16
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"del.command.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/feat/del.command.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"del.command.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/feat/del.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CA2E1C"}
|
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
* Deletes a feature, its worktree, and cancels any running agent.
|
|
5
5
|
* Optionally cleans up worktree and branches (local + remote).
|
|
6
6
|
*
|
|
7
|
-
* Usage: shep feat del <id> [--force] [--no-cleanup]
|
|
7
|
+
* Usage: shep feat del <id> [--force] [--no-cleanup] [--no-close-pr]
|
|
8
8
|
*
|
|
9
9
|
* @example
|
|
10
10
|
* $ shep feat del feat-123
|
|
11
11
|
* $ shep feat del feat-123 --force
|
|
12
12
|
* $ shep feat del feat-123 --force --no-cleanup
|
|
13
|
+
* $ shep feat del feat-123 --force --no-close-pr
|
|
13
14
|
*/
|
|
14
15
|
import { Command } from 'commander';
|
|
15
16
|
import { container } from '../../../../../packages/core/src/infrastructure/di/container.js';
|
|
@@ -26,6 +27,7 @@ export function createDelCommand() {
|
|
|
26
27
|
.argument('<id>', 'Feature ID or prefix')
|
|
27
28
|
.option('-f, --force', 'Skip confirmation prompt')
|
|
28
29
|
.option('--no-cleanup', 'Skip worktree and branch cleanup')
|
|
30
|
+
.option('--no-close-pr', 'Keep the pull request open')
|
|
29
31
|
.action(async (featureId, options) => {
|
|
30
32
|
try {
|
|
31
33
|
// First show what we're about to delete
|
|
@@ -52,8 +54,29 @@ export function createDelCommand() {
|
|
|
52
54
|
default: true,
|
|
53
55
|
});
|
|
54
56
|
}
|
|
57
|
+
// Determine close-PR preference
|
|
58
|
+
const hasOpenPr = feature.pr?.status === 'Open';
|
|
59
|
+
let closePr;
|
|
60
|
+
if (options.closePr === false) {
|
|
61
|
+
closePr = false;
|
|
62
|
+
}
|
|
63
|
+
else if (hasOpenPr && cleanup) {
|
|
64
|
+
if (options.force) {
|
|
65
|
+
closePr = true;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
closePr = await confirm({
|
|
69
|
+
message: `Also close the pull request? (PR #${feature.pr.number})`,
|
|
70
|
+
default: true,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
55
74
|
const deleteUseCase = container.resolve(DeleteFeatureUseCase);
|
|
56
|
-
|
|
75
|
+
const executeOptions = { cleanup };
|
|
76
|
+
if (closePr !== undefined) {
|
|
77
|
+
executeOptions.closePr = closePr;
|
|
78
|
+
}
|
|
79
|
+
await deleteUseCase.execute(feature.id, executeOptions);
|
|
57
80
|
messages.newline();
|
|
58
81
|
messages.success('Feature deleted');
|
|
59
82
|
console.log(` ${colors.muted('Name:')} ${feature.name}`);
|
|
@@ -61,6 +84,9 @@ export function createDelCommand() {
|
|
|
61
84
|
if (cleanup) {
|
|
62
85
|
console.log(` ${colors.muted('Cleanup:')} worktree, local branch, remote branch`);
|
|
63
86
|
}
|
|
87
|
+
if (closePr && hasOpenPr) {
|
|
88
|
+
console.log(` ${colors.muted('PR:')} #${feature.pr.number} closed`);
|
|
89
|
+
}
|
|
64
90
|
messages.newline();
|
|
65
91
|
}
|
|
66
92
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-graph-data.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/(dashboard)/get-graph-data.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAE5E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAI1C,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;
|
|
1
|
+
{"version":3,"file":"get-graph-data.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/(dashboard)/get-graph-data.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAE5E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAI1C,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAqGD,wBAAsB,YAAY,IAAI,OAAO,CAAC;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAAC,CAwDxF"}
|
|
@@ -6,6 +6,11 @@ import { getSettings } from '../../../../../packages/core/src/infrastructure/ser
|
|
|
6
6
|
import { layoutWithDagre, CANVAS_LAYOUT_DEFAULTS } from '../../lib/layout-with-dagre.js';
|
|
7
7
|
import { buildGraphNodes } from '../build-graph-nodes.js';
|
|
8
8
|
const execFileAsync = promisify(execFileCb);
|
|
9
|
+
// Cache git info per repo — refreshed every GIT_INFO_TTL_MS via background-style check.
|
|
10
|
+
// getGraphData() always reads from cache (zero git calls), and only spawns git
|
|
11
|
+
// processes when the cache entry is older than the TTL.
|
|
12
|
+
const GIT_INFO_TTL_MS = 30_000;
|
|
13
|
+
const gitInfoCache = new Map();
|
|
9
14
|
async function gitCommand(cwd, args) {
|
|
10
15
|
try {
|
|
11
16
|
const opts = IS_WINDOWS ? { cwd, windowsHide: true } : { cwd };
|
|
@@ -16,22 +21,35 @@ async function gitCommand(cwd, args) {
|
|
|
16
21
|
return null;
|
|
17
22
|
}
|
|
18
23
|
}
|
|
19
|
-
|
|
24
|
+
const FIELD_SEP = '\x1f'; // ASCII Unit Separator — safe in git output and child_process
|
|
25
|
+
/** Refresh git info for a single repo (spawns git processes). */
|
|
26
|
+
async function refreshRepoGitInfo(repo) {
|
|
20
27
|
try {
|
|
21
|
-
const
|
|
28
|
+
const headSha = await gitCommand(repo.path, ['rev-parse', 'HEAD']);
|
|
29
|
+
if (!headSha)
|
|
30
|
+
return;
|
|
31
|
+
const cached = gitInfoCache.get(repo.path);
|
|
32
|
+
if (cached?.sha === headSha) {
|
|
33
|
+
// HEAD unchanged — just bump checkedAt
|
|
34
|
+
cached.checkedAt = Date.now();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
// HEAD changed — fetch branch + subject & author in parallel
|
|
38
|
+
const [currentBranch, logLine] = await Promise.all([
|
|
22
39
|
gitCommand(repo.path, ['symbolic-ref', '--short', 'HEAD']),
|
|
23
|
-
gitCommand(repo.path, ['log', '-1',
|
|
24
|
-
gitCommand(repo.path, ['log', '-1', '--format=%an']),
|
|
40
|
+
gitCommand(repo.path, ['log', '-1', `--format=%s${FIELD_SEP}%an`]),
|
|
25
41
|
]);
|
|
26
42
|
if (!currentBranch)
|
|
27
|
-
return
|
|
28
|
-
|
|
43
|
+
return;
|
|
44
|
+
const [commitMessage, committer] = (logLine ?? '').split(FIELD_SEP);
|
|
45
|
+
// Behind count
|
|
29
46
|
let behindCount = null;
|
|
30
|
-
const
|
|
47
|
+
const defaultBranchRef = await gitCommand(repo.path, [
|
|
31
48
|
'symbolic-ref',
|
|
32
49
|
'--short',
|
|
33
50
|
'refs/remotes/origin/HEAD',
|
|
34
|
-
])
|
|
51
|
+
]);
|
|
52
|
+
const defaultBranch = defaultBranchRef?.replace('origin/', '') ?? null;
|
|
35
53
|
if (defaultBranch && currentBranch !== defaultBranch) {
|
|
36
54
|
const behind = await gitCommand(repo.path, [
|
|
37
55
|
'rev-list',
|
|
@@ -42,32 +60,56 @@ async function fetchRepoGitInfo(repo) {
|
|
|
42
60
|
if (isNaN(behindCount))
|
|
43
61
|
behindCount = null;
|
|
44
62
|
}
|
|
45
|
-
else
|
|
63
|
+
else {
|
|
46
64
|
behindCount = 0;
|
|
47
65
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
66
|
+
gitInfoCache.set(repo.path, {
|
|
67
|
+
sha: headSha,
|
|
68
|
+
checkedAt: Date.now(),
|
|
69
|
+
data: {
|
|
70
|
+
branch: currentBranch,
|
|
71
|
+
commitMessage: commitMessage ?? 'unknown',
|
|
72
|
+
committer: committer ?? 'unknown',
|
|
73
|
+
behindCount,
|
|
74
|
+
},
|
|
75
|
+
});
|
|
54
76
|
}
|
|
55
77
|
catch {
|
|
78
|
+
// ignore — stale cache is better than no data
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Return cached git info for a repo. If the cache is stale (> TTL),
|
|
83
|
+
* kick off a fire-and-forget refresh so the NEXT call gets fresh data.
|
|
84
|
+
* Never blocks getGraphData() with git subprocess calls.
|
|
85
|
+
*/
|
|
86
|
+
function getRepoGitInfo(repo) {
|
|
87
|
+
const cached = gitInfoCache.get(repo.path);
|
|
88
|
+
const now = Date.now();
|
|
89
|
+
if (!cached) {
|
|
90
|
+
// First time — trigger async refresh, return null for this call
|
|
91
|
+
void refreshRepoGitInfo(repo);
|
|
56
92
|
return null;
|
|
57
93
|
}
|
|
94
|
+
if (now - cached.checkedAt >= GIT_INFO_TTL_MS) {
|
|
95
|
+
// Stale — trigger async refresh, return stale data immediately
|
|
96
|
+
void refreshRepoGitInfo(repo);
|
|
97
|
+
}
|
|
98
|
+
return cached.data;
|
|
58
99
|
}
|
|
59
100
|
export async function getGraphData() {
|
|
60
101
|
const listFeatures = resolve('ListFeaturesUseCase');
|
|
61
102
|
const listRepos = resolve('ListRepositoriesUseCase');
|
|
62
103
|
const agentRunRepo = resolve('IAgentRunRepository');
|
|
63
104
|
const [features, repositories] = await Promise.all([listFeatures.execute(), listRepos.execute()]);
|
|
64
|
-
//
|
|
105
|
+
// Read git info from cache (zero git calls). Stale entries trigger
|
|
106
|
+
// a fire-and-forget background refresh for the next poll cycle.
|
|
65
107
|
const repoGitInfoMap = new Map();
|
|
66
|
-
|
|
67
|
-
const info =
|
|
108
|
+
for (const repo of repositories) {
|
|
109
|
+
const info = getRepoGitInfo(repo);
|
|
68
110
|
if (info)
|
|
69
111
|
repoGitInfoMap.set(repo.path, info);
|
|
70
|
-
}
|
|
112
|
+
}
|
|
71
113
|
// PR/CI status is kept fresh by PrSyncWatcher (30s background poll).
|
|
72
114
|
// No live GitHub calls here — use cached DB values for fast response.
|
|
73
115
|
const featuresWithRuns = await Promise.all(features.map(async (feature) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Feature } from '../../../../../packages/core/src/domain/generated/output.js';
|
|
2
|
-
export declare function deleteFeature(featureId: string, cleanup?: boolean, cascadeDelete?: boolean): Promise<{
|
|
2
|
+
export declare function deleteFeature(featureId: string, cleanup?: boolean, cascadeDelete?: boolean, closePr?: boolean): Promise<{
|
|
3
3
|
feature?: Feature;
|
|
4
4
|
error?: string;
|
|
5
5
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/delete-feature.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAC;AAEpE,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"delete-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/delete-feature.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAC;AAEpE,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,OAAO,EACvB,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAAC;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAoBhD"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use server';
|
|
2
2
|
import { resolve } from '../../lib/server-container.js';
|
|
3
|
-
export async function deleteFeature(featureId, cleanup, cascadeDelete) {
|
|
3
|
+
export async function deleteFeature(featureId, cleanup, cascadeDelete, closePr) {
|
|
4
4
|
if (!featureId?.trim()) {
|
|
5
5
|
return { error: 'id is required' };
|
|
6
6
|
}
|
|
@@ -11,6 +11,8 @@ export async function deleteFeature(featureId, cleanup, cascadeDelete) {
|
|
|
11
11
|
options.cleanup = cleanup;
|
|
12
12
|
if (cascadeDelete !== undefined)
|
|
13
13
|
options.cascadeDelete = cascadeDelete;
|
|
14
|
+
if (closePr !== undefined)
|
|
15
|
+
options.closePr = closePr;
|
|
14
16
|
const feature = Object.keys(options).length > 0
|
|
15
17
|
? await deleteFeatureUseCase.execute(featureId, options)
|
|
16
18
|
: await deleteFeatureUseCase.execute(featureId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-drawer-client.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAI/D,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,UAAU,CAAC;IACjB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,wBAAgB,mBAAmB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,wBAAwB,
|
|
1
|
+
{"version":3,"file":"feature-drawer-client.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAI/D,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,UAAU,CAAC;IACjB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,wBAAgB,mBAAmB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,wBAAwB,2CAskB1F"}
|
package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js
CHANGED
|
@@ -256,7 +256,7 @@ export function FeatureDrawerClient({ view: initialView, urlTab }) {
|
|
|
256
256
|
}, [view, featureNode, prdData, prdSelections, onClose]);
|
|
257
257
|
const handleTechApprove = useCallback(() => handleSimpleApprove('Plan'), [handleSimpleApprove]);
|
|
258
258
|
const handleMergeApprove = useCallback(() => handleSimpleApprove('Merge'), [handleSimpleApprove]);
|
|
259
|
-
const handleDelete = useCallback(async (featureId, cleanup, cascadeDelete) => {
|
|
259
|
+
const handleDelete = useCallback(async (featureId, cleanup, cascadeDelete, closePr) => {
|
|
260
260
|
setIsDeleting(true);
|
|
261
261
|
// Close the delete dialog and drawer before the server action so the
|
|
262
262
|
// user sees immediate feedback. We dispatch a DOM event so the canvas
|
|
@@ -264,7 +264,7 @@ export function FeatureDrawerClient({ view: initialView, urlTab }) {
|
|
|
264
264
|
// mutation guard, node removal) in parallel.
|
|
265
265
|
setDeleteDialogOpen(false);
|
|
266
266
|
window.dispatchEvent(new CustomEvent('shep:feature-delete-requested', {
|
|
267
|
-
detail: { featureId, cleanup, cascadeDelete },
|
|
267
|
+
detail: { featureId, cleanup, cascadeDelete, closePr },
|
|
268
268
|
}));
|
|
269
269
|
router.push('/');
|
|
270
270
|
}, [router]);
|
|
@@ -336,7 +336,7 @@ export function FeatureDrawerClient({ view: initialView, urlTab }) {
|
|
|
336
336
|
const repoName = featureNode.repositoryName ??
|
|
337
337
|
featureNode.repositoryPath.split('/').filter(Boolean).at(-1) ??
|
|
338
338
|
'';
|
|
339
|
-
header = (_jsxs(_Fragment, { children: [_jsxs("div", { "data-testid": "feature-drawer-header", children: [_jsx(DrawerTitle, { children: featureNode.name }), repoName ? (_jsxs("div", { className: "flex items-center gap-1.5 pt-0.5", children: [_jsx(Code2, { className: "text-muted-foreground size-3.5 shrink-0" }), featureNode.remoteUrl ? (_jsxs("a", { href: featureNode.remoteUrl, target: "_blank", rel: "noopener noreferrer", className: "text-muted-foreground hover:text-foreground inline-flex items-center gap-1 text-xs transition-colors", "data-testid": "feature-drawer-repo-link", children: [repoName, _jsx(ExternalLink, { className: "size-3" })] })) : (_jsx("span", { className: "text-muted-foreground text-xs", children: repoName }))] })) : null, _jsx(DrawerDescription, { className: "sr-only", children: featureNode.name })] }), featureActionsInput ? (_jsxs("div", { className: "flex items-center gap-2 pt-2", "data-testid": "feature-drawer-actions", children: [_jsx(OpenActionMenu, { actions: featureActions, repositoryPath: featureActionsInput.repositoryPath, showSpecs: !!featureActionsInput.specPath }), featureFlags.envDeploy && featureDeployTarget ? (_jsxs(_Fragment, { children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { children: _jsx(ActionButton, { label: isFeatureDeployActive ? 'Stop Dev Server' : 'Start Dev Server', onClick: isFeatureDeployActive ? deployAction.stop : deployAction.deploy, loading: deployAction.deployLoading || deployAction.stopLoading, error: !!deployAction.deployError, icon: isFeatureDeployActive ? Square : Play, iconOnly: true, variant: "outline", size: "icon-sm" }) }) }), _jsx(TooltipContent, { children: isFeatureDeployActive ? 'Stop Dev Server' : 'Start Dev Server' })] }) }), isFeatureDeployActive ? (_jsx(DeploymentStatusBadge, { status: deployAction.status, url: deployAction.url, targetId: featureDeployTarget?.targetId })) : null] })) : null, _jsxs("div", { className: "ml-auto flex items-center gap-1.5", children: [_jsx("code", { className: "bg-muted text-muted-foreground rounded px-1.5 py-0.5 font-mono text-xs", children: shortId }), _jsx("button", { type: "button", onClick: handleCopyId, className: "text-muted-foreground hover:text-foreground inline-flex items-center rounded p-0.5 transition-colors", "aria-label": "Copy feature ID", "data-testid": "feature-drawer-copy-id", children: idCopied ? (_jsx(Check, { className: "size-3.5 text-green-600" })) : (_jsx(Copy, { className: "size-3.5" })) })] }), featureNode.featureId ? (_jsxs(_Fragment, { children: [_jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Delete feature", disabled: isDeleting, className: "text-muted-foreground hover:text-destructive", "data-testid": "feature-drawer-delete", onClick: () => setDeleteDialogOpen(true), children: isDeleting ? (_jsx(Loader2, { className: "size-4 animate-spin" })) : (_jsx(Trash2, { className: "size-4" })) }), _jsx(DeleteFeatureDialog, { open: deleteDialogOpen, onOpenChange: setDeleteDialogOpen, onConfirm: (cleanup, cascadeDelete) => handleDelete(featureNode.featureId, cleanup, cascadeDelete), isDeleting: isDeleting, featureName: featureNode.name, featureId: featureNode.featureId, hasChildren: featureNode.hasChildren })] })) : null] })) : null] }));
|
|
339
|
+
header = (_jsxs(_Fragment, { children: [_jsxs("div", { "data-testid": "feature-drawer-header", children: [_jsx(DrawerTitle, { children: featureNode.name }), repoName ? (_jsxs("div", { className: "flex items-center gap-1.5 pt-0.5", children: [_jsx(Code2, { className: "text-muted-foreground size-3.5 shrink-0" }), featureNode.remoteUrl ? (_jsxs("a", { href: featureNode.remoteUrl, target: "_blank", rel: "noopener noreferrer", className: "text-muted-foreground hover:text-foreground inline-flex items-center gap-1 text-xs transition-colors", "data-testid": "feature-drawer-repo-link", children: [repoName, _jsx(ExternalLink, { className: "size-3" })] })) : (_jsx("span", { className: "text-muted-foreground text-xs", children: repoName }))] })) : null, _jsx(DrawerDescription, { className: "sr-only", children: featureNode.name })] }), featureActionsInput ? (_jsxs("div", { className: "flex items-center gap-2 pt-2", "data-testid": "feature-drawer-actions", children: [_jsx(OpenActionMenu, { actions: featureActions, repositoryPath: featureActionsInput.repositoryPath, showSpecs: !!featureActionsInput.specPath }), featureFlags.envDeploy && featureDeployTarget ? (_jsxs(_Fragment, { children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { children: _jsx(ActionButton, { label: isFeatureDeployActive ? 'Stop Dev Server' : 'Start Dev Server', onClick: isFeatureDeployActive ? deployAction.stop : deployAction.deploy, loading: deployAction.deployLoading || deployAction.stopLoading, error: !!deployAction.deployError, icon: isFeatureDeployActive ? Square : Play, iconOnly: true, variant: "outline", size: "icon-sm" }) }) }), _jsx(TooltipContent, { children: isFeatureDeployActive ? 'Stop Dev Server' : 'Start Dev Server' })] }) }), isFeatureDeployActive ? (_jsx(DeploymentStatusBadge, { status: deployAction.status, url: deployAction.url, targetId: featureDeployTarget?.targetId })) : null] })) : null, _jsxs("div", { className: "ml-auto flex items-center gap-1.5", children: [_jsx("code", { className: "bg-muted text-muted-foreground rounded px-1.5 py-0.5 font-mono text-xs", children: shortId }), _jsx("button", { type: "button", onClick: handleCopyId, className: "text-muted-foreground hover:text-foreground inline-flex items-center rounded p-0.5 transition-colors", "aria-label": "Copy feature ID", "data-testid": "feature-drawer-copy-id", children: idCopied ? (_jsx(Check, { className: "size-3.5 text-green-600" })) : (_jsx(Copy, { className: "size-3.5" })) })] }), featureNode.featureId ? (_jsxs(_Fragment, { children: [_jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Delete feature", disabled: isDeleting, className: "text-muted-foreground hover:text-destructive", "data-testid": "feature-drawer-delete", onClick: () => setDeleteDialogOpen(true), children: isDeleting ? (_jsx(Loader2, { className: "size-4 animate-spin" })) : (_jsx(Trash2, { className: "size-4" })) }), _jsx(DeleteFeatureDialog, { open: deleteDialogOpen, onOpenChange: setDeleteDialogOpen, onConfirm: (cleanup, cascadeDelete, closePr) => handleDelete(featureNode.featureId, cleanup, cascadeDelete, closePr), isDeleting: isDeleting, featureName: featureNode.name, featureId: featureNode.featureId, hasChildren: featureNode.hasChildren, hasOpenPr: !!featureNode.pr && featureNode.pr.status === 'Open' })] })) : null] })) : null] }));
|
|
340
340
|
}
|
|
341
341
|
// ── Body ──────────────────────────────────────────────────────────────
|
|
342
342
|
let body = null;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export interface DeleteFeatureDialogProps {
|
|
2
2
|
open: boolean;
|
|
3
3
|
onOpenChange: (open: boolean) => void;
|
|
4
|
-
onConfirm: (cleanup: boolean, cascadeDelete: boolean) => void;
|
|
4
|
+
onConfirm: (cleanup: boolean, cascadeDelete: boolean, closePr: boolean) => void;
|
|
5
5
|
isDeleting: boolean;
|
|
6
6
|
featureName: string;
|
|
7
7
|
featureId: string;
|
|
8
8
|
hasChildren?: boolean;
|
|
9
|
+
hasOpenPr?: boolean;
|
|
9
10
|
}
|
|
10
11
|
//# sourceMappingURL=delete-feature-dialog-config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete-feature-dialog-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog-config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"delete-feature-dialog-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog-config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAChF,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB"}
|
package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { DeleteFeatureDialogProps } from './delete-feature-dialog-config.js';
|
|
2
|
-
export declare function DeleteFeatureDialog({ open, onOpenChange, onConfirm, isDeleting, featureName, featureId, hasChildren, }: DeleteFeatureDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function DeleteFeatureDialog({ open, onOpenChange, onConfirm, isDeleting, featureName, featureId, hasChildren, hasOpenPr, }: DeleteFeatureDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
3
3
|
//# sourceMappingURL=delete-feature-dialog.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete-feature-dialog.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAE/E,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,YAAY,EACZ,SAAS,EACT,UAAU,EACV,WAAW,EACX,SAAS,EACT,WAAW,
|
|
1
|
+
{"version":3,"file":"delete-feature-dialog.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAE/E,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,YAAY,EACZ,SAAS,EACT,UAAU,EACV,WAAW,EACX,SAAS,EACT,WAAW,EACX,SAAS,GACV,EAAE,wBAAwB,2CA+F1B"}
|
package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.js
CHANGED
|
@@ -5,14 +5,24 @@ import { Loader2 } from 'lucide-react';
|
|
|
5
5
|
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '../../ui/alert-dialog.js';
|
|
6
6
|
import { Checkbox } from '../../ui/checkbox.js';
|
|
7
7
|
import { Label } from '../../ui/label.js';
|
|
8
|
-
export function DeleteFeatureDialog({ open, onOpenChange, onConfirm, isDeleting, featureName, featureId, hasChildren, }) {
|
|
8
|
+
export function DeleteFeatureDialog({ open, onOpenChange, onConfirm, isDeleting, featureName, featureId, hasChildren, hasOpenPr, }) {
|
|
9
9
|
const [cleanup, setCleanup] = useState(true);
|
|
10
10
|
const [cascadeDelete, setCascadeDelete] = useState(false);
|
|
11
|
+
const [closePr, setClosePr] = useState(true);
|
|
11
12
|
useEffect(() => {
|
|
12
13
|
if (open) {
|
|
13
14
|
setCleanup(true);
|
|
14
15
|
setCascadeDelete(false);
|
|
16
|
+
setClosePr(true);
|
|
15
17
|
}
|
|
16
18
|
}, [open]);
|
|
17
|
-
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (cleanup) {
|
|
21
|
+
setClosePr(true);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
setClosePr(false);
|
|
25
|
+
}
|
|
26
|
+
}, [cleanup]);
|
|
27
|
+
return (_jsx(AlertDialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(AlertDialogContent, { onCloseAutoFocus: (e) => e.preventDefault(), children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Delete feature?" }), _jsxs(AlertDialogDescription, { children: ["This will permanently delete ", _jsx("strong", { children: featureName }), " (", featureId, "). This action cannot be undone."] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "cleanup-checkbox", checked: cleanup, onCheckedChange: (checked) => setCleanup(checked === true), disabled: isDeleting, "aria-label": "Clean up worktree and branches" }), _jsx(Label, { htmlFor: "cleanup-checkbox", className: "cursor-pointer text-sm", children: "Clean up worktree and branches" })] }), hasChildren ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "cascade-delete-checkbox", checked: cascadeDelete, onCheckedChange: (checked) => setCascadeDelete(checked === true), disabled: isDeleting, "aria-label": "Delete sub-features" }), _jsx(Label, { htmlFor: "cascade-delete-checkbox", className: "cursor-pointer text-sm", children: "Delete sub-features" })] })) : null, hasOpenPr ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "close-pr-checkbox", checked: closePr, onCheckedChange: (checked) => setClosePr(checked === true), disabled: isDeleting || !cleanup, "aria-label": "Close pull request" }), _jsx(Label, { htmlFor: "close-pr-checkbox", className: "cursor-pointer text-sm", children: "Close pull request" })] })) : null] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: isDeleting, onClick: () => onOpenChange(false), children: "Cancel" }), _jsx(AlertDialogAction, { variant: "destructive", disabled: isDeleting, onClick: () => onConfirm(cleanup, cascadeDelete, hasOpenPr ? closePr : false), children: isDeleting ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Deleting\u2026"] })) : ('Delete') })] })] }) }));
|
|
18
28
|
}
|
|
@@ -7,4 +7,7 @@ export declare const Default: Story;
|
|
|
7
7
|
export declare const WithChildren: Story;
|
|
8
8
|
export declare const Deleting: Story;
|
|
9
9
|
export declare const DeletingWithChildren: Story;
|
|
10
|
+
export declare const WithOpenPr: Story;
|
|
11
|
+
export declare const WithOpenPrAndChildren: Story;
|
|
12
|
+
export declare const DeletingWithOpenPr: Story;
|
|
10
13
|
//# sourceMappingURL=delete-feature-dialog.stories.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete-feature-dialog.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,mBAAmB,CAe1C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAElD,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC;AAEjC,eAAO,MAAM,YAAY,EAAE,KAI1B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAItB,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,KAKlC,CAAC"}
|
|
1
|
+
{"version":3,"file":"delete-feature-dialog.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,mBAAmB,CAe1C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAElD,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC;AAEjC,eAAO,MAAM,YAAY,EAAE,KAI1B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAItB,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,KAKlC,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAIxB,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,KAKnC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAKhC,CAAC"}
|
|
@@ -34,3 +34,20 @@ export const DeletingWithChildren = {
|
|
|
34
34
|
hasChildren: true,
|
|
35
35
|
},
|
|
36
36
|
};
|
|
37
|
+
export const WithOpenPr = {
|
|
38
|
+
args: {
|
|
39
|
+
hasOpenPr: true,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
export const WithOpenPrAndChildren = {
|
|
43
|
+
args: {
|
|
44
|
+
hasOpenPr: true,
|
|
45
|
+
hasChildren: true,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
export const DeletingWithOpenPr = {
|
|
49
|
+
args: {
|
|
50
|
+
isDeleting: true,
|
|
51
|
+
hasOpenPr: true,
|
|
52
|
+
},
|
|
53
|
+
};
|
package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts
CHANGED
|
@@ -89,7 +89,7 @@ export interface FeatureNodeData {
|
|
|
89
89
|
onAction?: () => void;
|
|
90
90
|
onSettings?: () => void;
|
|
91
91
|
hasChildren?: boolean;
|
|
92
|
-
onDelete?: (featureId: string, cleanup?: boolean, cascadeDelete?: boolean) => void;
|
|
92
|
+
onDelete?: (featureId: string, cleanup?: boolean, cascadeDelete?: boolean, closePr?: boolean) => void;
|
|
93
93
|
onRetry?: (featureId: string) => void;
|
|
94
94
|
onStart?: (featureId: string) => void;
|
|
95
95
|
onStop?: (featureId: string) => void;
|
package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-node-state-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node-state-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,UAAU,EAChB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAChG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,MAAM,gBAAgB,GACxB,UAAU,GACV,SAAS,GACT,iBAAiB,GACjB,MAAM,GACN,SAAS,GACT,SAAS,GACT,OAAO,GACP,UAAU,CAAC;AAEf,MAAM,MAAM,qBAAqB,GAC7B,SAAS,GACT,cAAc,GACd,UAAU,GACV,gBAAgB,GAChB,QAAQ,GACR,QAAQ,GACR,UAAU,CAAC;AAEf,0DAA0D;AAC1D,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,qBAAqB,EAAE,MAAM,CAQxE,CAAC;AAEF,gFAAgF;AAChF,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,qBAAqB,EAAE,MAAM,CAQvE,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,qBAAqB,CAAC;IACjC,KAAK,EAAE,gBAAgB,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,cAAc,EAAE,MAAM,CAAC;IACvB,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,EAAE,CAAC,EAAE;QACH,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,QAAQ,CAAC;QACjB,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,CAAC;IACF,yDAAyD;IACzD,aAAa,CAAC,EAAE;QACd,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,OAAO,CAAC;QACnB,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC;IACF,4DAA4D;IAC5D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gDAAgD;IAChD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,sDAAsD;IACtD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,8DAA8D;IAC9D,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,mDAAmD;IACnD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kDAAkD;IAClD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,+DAA+D;IAC/D,UAAU,CAAC,EAAE;QACX,MAAM,EAAE,eAAe,CAAC;QACxB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"feature-node-state-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node-state-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA6DnE,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,
|
|
1
|
+
{"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA6DnE,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,2CAkWA"}
|
|
@@ -73,10 +73,10 @@ export function FeatureNode({ data, selected, }) {
|
|
|
73
73
|
return (_jsxs("div", { className: "animate-in fade-in group relative duration-300", children: [data.showHandles ? (_jsx(Handle, { type: "target", position: Position.Left, isConnectable: false, className: "opacity-0!" })) : null, data.onDelete && data.featureId && data.state !== 'deleting' ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "absolute top-1/2 -left-10 -translate-y-1/2 opacity-0 transition-opacity group-hover:opacity-100", onPointerDown: (e) => e.stopPropagation(), children: _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { "aria-label": "Delete feature", "data-testid": "feature-node-delete-button", onClick: (e) => {
|
|
74
74
|
e.stopPropagation();
|
|
75
75
|
setConfirmOpen(true);
|
|
76
|
-
}, className: "bg-card text-muted-foreground hover:border-destructive hover:text-destructive flex h-7 w-7 cursor-pointer items-center justify-center rounded-full border shadow-sm transition-colors", children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Delete feature" })] }) }) }), _jsx(DeleteFeatureDialog, { open: confirmOpen, onOpenChange: setConfirmOpen, onConfirm: (cleanup, cascadeDelete) => {
|
|
76
|
+
}, className: "bg-card text-muted-foreground hover:border-destructive hover:text-destructive flex h-7 w-7 cursor-pointer items-center justify-center rounded-full border shadow-sm transition-colors", children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Delete feature" })] }) }) }), _jsx(DeleteFeatureDialog, { open: confirmOpen, onOpenChange: setConfirmOpen, onConfirm: (cleanup, cascadeDelete, closePr) => {
|
|
77
77
|
setConfirmOpen(false);
|
|
78
|
-
data.onDelete?.(data.featureId, cleanup, cascadeDelete);
|
|
79
|
-
}, isDeleting: false, featureName: data.name ?? 'this feature', featureId: data.featureId, hasChildren: data.hasChildren })] })) : null, _jsxs("div", { "data-testid": "feature-node-card", "aria-busy": data.state === 'creating' || data.state === 'deleting' ? 'true' : undefined, className: cn('bg-card flex min-h-35 w-72 cursor-pointer flex-col rounded-lg border p-3 shadow-sm', selected && 'ring-primary ring-2', data.state === 'deleting' && 'opacity-60'), children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { "data-testid": "feature-node-lifecycle-label", className: cn('text-[10px] font-semibold tracking-wider'), children: data.state === 'blocked'
|
|
78
|
+
data.onDelete?.(data.featureId, cleanup, cascadeDelete, closePr);
|
|
79
|
+
}, isDeleting: false, featureName: data.name ?? 'this feature', featureId: data.featureId, hasChildren: data.hasChildren, hasOpenPr: !!data.pr && data.pr.status === 'Open' })] })) : null, _jsxs("div", { "data-testid": "feature-node-card", "aria-busy": data.state === 'creating' || data.state === 'deleting' ? 'true' : undefined, className: cn('bg-card flex min-h-35 w-72 cursor-pointer flex-col rounded-lg border p-3 shadow-sm', selected && 'ring-primary ring-2', data.state === 'deleting' && 'opacity-60'), children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { "data-testid": "feature-node-lifecycle-label", className: cn('text-[10px] font-semibold tracking-wider'), children: data.state === 'blocked'
|
|
80
80
|
? 'BLOCKED'
|
|
81
81
|
: data.state === 'pending'
|
|
82
82
|
? 'PENDING'
|
package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-center-inner.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-inner.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AAGpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAuB5E,UAAU,uBAAuB;IAC/B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,YAAY,EAAE,IAAI,EAAE,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,uBAAuB,
|
|
1
|
+
{"version":3,"file":"control-center-inner.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-inner.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AAGpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAuB5E,UAAU,uBAAuB;IAC/B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,YAAY,EAAE,IAAI,EAAE,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,uBAAuB,2CAuWzF"}
|