@shepai/cli 1.135.0-pr430.5b0b699 → 1.135.0-pr431.2cf26cc
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/FeatureFlags.yaml +1 -1
- package/dist/packages/core/src/application/ports/output/services/tool-installer.service.d.ts +15 -0
- package/dist/packages/core/src/application/ports/output/services/tool-installer.service.d.ts.map +1 -1
- package/dist/packages/core/src/domain/factories/settings-defaults.factory.js +1 -1
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +0 -5
- package/dist/packages/core/src/infrastructure/services/tool-installer/tool-installer.service.d.ts +2 -1
- 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 +14 -0
- package/dist/src/presentation/cli/commands/feat/new.command.d.ts +0 -1
- package/dist/src/presentation/cli/commands/feat/new.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/feat/new.command.js +7 -88
- package/dist/src/presentation/web/app/actions/open-shell.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/open-shell.js +32 -36
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +4 -18
- package/dist/src/presentation/web/components/common/feature-create-drawer/repository-combobox.stories.d.ts +0 -6
- package/dist/src/presentation/web/components/common/feature-create-drawer/repository-combobox.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/repository-combobox.stories.js +2 -35
- package/dist/src/presentation/web/lib/feature-flags.js +1 -1
- 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 +1 -1
- package/web/.next/required-server-files.json +1 -1
- 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 +1 -1
- 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 +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +30 -30
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +2 -2
- 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 +2 -2
- 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 +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +24 -24
- package/web/.next/server/app/(dashboard)/create/page.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +30 -30
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +2 -2
- 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 +2 -2
- 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 +1 -1
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +22 -22
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error.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.js.nft.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
- package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
- package/web/.next/server/app/api/graph-data/route.js.nft.json +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.js.nft.json +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +8 -8
- package/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +3 -3
- 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/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]__c3ab8422._.js → [root-of-the-server]__31bc28da._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__bfba58e6._.js.map → [root-of-the-server]__31bc28da._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__755cfe02._.js → [root-of-the-server]__32ecbed9._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__c3ab8422._.js.map → [root-of-the-server]__32ecbed9._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__3ef34e4c._.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]__7894f27f._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7894f27f._.js.map +1 -0
- 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]__bfba58e6._.js → [root-of-the-server]__90ce4b6d._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__a628fb91._.js.map → [root-of-the-server]__90ce4b6d._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__a628fb91._.js → [root-of-the-server]__90f9ae71._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__755cfe02._.js.map → [root-of-the-server]__90f9ae71._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__96670392._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +4 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__6bb00d90._.js.map → [root-of-the-server]__aad040c0._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b3dbadca._.js +3 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__d61bd462._.js.map → [root-of-the-server]__b3dbadca._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_01046927._.js +9 -0
- package/web/.next/server/chunks/ssr/_01046927._.js.map +1 -0
- 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/{_93a801f1._.js → _521c0c72._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_93a801f1._.js.map → _521c0c72._.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/{_d1c40d87._.js → _987ce846._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_d1c40d87._.js.map → _987ce846._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_a37f5f18._.js +1 -1
- package/web/.next/server/chunks/ssr/_a37f5f18._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_a9f57758._.js +1 -1
- package/web/.next/server/chunks/ssr/_b6960ca0._.js +4 -0
- package/web/.next/server/chunks/ssr/_b6960ca0._.js.map +1 -0
- 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_7daab21a._.js → src_presentation_web_361087cb._.js} +2 -2
- package/web/.next/server/chunks/ssr/{src_presentation_web_7daab21a._.js.map → src_presentation_web_361087cb._.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_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/0b7fe2ac4f078f54.js +13 -0
- package/web/.next/static/chunks/{c99297cbb9c20255.js → 113be538d779ab6e.js} +1 -1
- package/web/.next/static/chunks/{6c628cd7f8e54b37.js → 18369a21077f6669.js} +1 -1
- package/web/.next/static/chunks/2971cf4cf8234b38.js +1 -0
- package/web/.next/static/chunks/{eb8bb6289b905648.js → 455b6a3823f08481.js} +1 -1
- package/web/.next/static/chunks/4b6ee0b6a2a418e4.js +1 -0
- package/web/.next/static/chunks/52a289f2f66b93c0.js +1 -0
- package/web/.next/static/chunks/{ecbbae4d5e4cfab2.js → 6069c464fee54e1a.js} +1 -1
- package/web/.next/static/chunks/6ed229a6de29ab66.js +1 -0
- package/web/.next/static/chunks/{49f9ce1e2953f293.js → ab6e5061a876ed23.js} +1 -1
- package/web/.next/static/chunks/{ebe7f939b642b667.js → cbd902cd6ba446ab.js} +1 -1
- package/web/.next/static/chunks/d00f9add06c476d8.js +1 -0
- package/web/.next/static/chunks/{9e35dfeb65fbb0ff.js → e0e8dbc30806446b.js} +2 -2
- package/dist/packages/core/src/application/use-cases/features/create/create-feature-from-remote.use-case.d.ts +0 -82
- package/dist/packages/core/src/application/use-cases/features/create/create-feature-from-remote.use-case.d.ts.map +0 -1
- package/dist/packages/core/src/application/use-cases/features/create/create-feature-from-remote.use-case.js +0 -96
- package/dist/src/presentation/web/app/actions/create-feature-from-remote.d.ts +0 -29
- package/dist/src/presentation/web/app/actions/create-feature-from-remote.d.ts.map +0 -1
- package/dist/src/presentation/web/app/actions/create-feature-from-remote.js +0 -72
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2c791c42._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2c791c42._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8fae3a20._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8fae3a20._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__d61bd462._.js +0 -3
- package/web/.next/server/chunks/ssr/_2e03c237._.js +0 -3
- package/web/.next/server/chunks/ssr/_2e03c237._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_7acd7690._.js +0 -9
- package/web/.next/server/chunks/ssr/_7acd7690._.js.map +0 -1
- package/web/.next/static/chunks/9d55dd03daac8bb2.js +0 -3
- package/web/.next/static/chunks/a20470eee309dc12.js +0 -1
- package/web/.next/static/chunks/abbc9bc0ecff7cac.js +0 -1
- package/web/.next/static/chunks/c0bc54eda21bbcf1.js +0 -1
- package/web/.next/static/chunks/cc54a5316b728fd9.js +0 -1
- package/web/.next/static/chunks/e95018ef71b4083d.js +0 -11
- /package/web/.next/static/{5_A91ycYn-g6phGM-k_v- → oAOSdejOwu4NpD7o-Gf4s}/_buildManifest.js +0 -0
- /package/web/.next/static/{5_A91ycYn-g6phGM-k_v- → oAOSdejOwu4NpD7o-Gf4s}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{5_A91ycYn-g6phGM-k_v- → oAOSdejOwu4NpD7o-Gf4s}/_ssgManifest.js +0 -0
package/dist/packages/core/src/application/ports/output/services/tool-installer.service.d.ts
CHANGED
|
@@ -10,6 +10,12 @@ export interface AvailableTerminalEntry {
|
|
|
10
10
|
name: string;
|
|
11
11
|
available: boolean;
|
|
12
12
|
}
|
|
13
|
+
export interface TerminalOpenConfig {
|
|
14
|
+
/** Platform-resolved openDirectory command string, still containing {dir} placeholder */
|
|
15
|
+
openDirectory: string;
|
|
16
|
+
/** Whether to spawn with shell: true */
|
|
17
|
+
shell: boolean;
|
|
18
|
+
}
|
|
13
19
|
/**
|
|
14
20
|
* Service interface for tool installation management.
|
|
15
21
|
*/
|
|
@@ -44,5 +50,14 @@ export interface IToolInstallerService {
|
|
|
44
50
|
* @returns Array of terminal entries with id, name, and availability
|
|
45
51
|
*/
|
|
46
52
|
listAvailableTerminals(): Promise<AvailableTerminalEntry[]>;
|
|
53
|
+
/**
|
|
54
|
+
* Get the open-directory configuration for a terminal by its tool ID.
|
|
55
|
+
* Returns the platform-resolved openDirectory command and shell preference.
|
|
56
|
+
* Safe to call from Next.js server actions via DI (no import.meta.url dependency).
|
|
57
|
+
*
|
|
58
|
+
* @param terminalId - Tool ID (e.g. 'warp', 'iterm2', 'system-terminal')
|
|
59
|
+
* @returns Config with openDirectory command and shell flag, or null if not found
|
|
60
|
+
*/
|
|
61
|
+
getTerminalOpenConfig(terminalId: string): TerminalOpenConfig | null;
|
|
47
62
|
}
|
|
48
63
|
//# sourceMappingURL=tool-installer.service.d.ts.map
|
package/dist/packages/core/src/application/ports/output/services/tool-installer.service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-installer.service.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/tool-installer.service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EACnB,MAAM,wCAAwC,CAAC;AAEhD,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAErE;;;;;OAKG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAAC;IAE/D;;;;;;OAMG;IACH,cAAc,CACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAChC,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAEnC;;;;;;OAMG;IACH,sBAAsB,IAAI,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"tool-installer.service.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/tool-installer.service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EACnB,MAAM,wCAAwC,CAAC;AAEhD,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,yFAAyF;IACzF,aAAa,EAAE,MAAM,CAAC;IACtB,wCAAwC;IACxC,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAErE;;;;;OAKG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAAC;IAE/D;;;;;;OAMG;IACH,cAAc,CACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAChC,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAEnC;;;;;;OAMG;IACH,sBAAsB,IAAI,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC;IAE5D;;;;;;;OAOG;IACH,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAAC;CACtE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/src/infrastructure/di/container.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/src/infrastructure/di/container.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAyHrC;;;;;;GAMG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,OAAO,SAAS,CAAC,CAmVrE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -59,7 +59,6 @@ import { ApproveAgentRunUseCase } from '../../application/use-cases/agents/appro
|
|
|
59
59
|
import { RejectAgentRunUseCase } from '../../application/use-cases/agents/reject-agent-run.use-case.js';
|
|
60
60
|
import { ReviewFeatureUseCase } from '../../application/use-cases/agents/review-feature.use-case.js';
|
|
61
61
|
import { CreateFeatureUseCase } from '../../application/use-cases/features/create/create-feature.use-case.js';
|
|
62
|
-
import { CreateFeatureFromRemoteUseCase } from '../../application/use-cases/features/create/create-feature-from-remote.use-case.js';
|
|
63
62
|
import { MetadataGenerator } from '../../application/use-cases/features/create/metadata-generator.js';
|
|
64
63
|
import { SlugResolver } from '../../application/use-cases/features/create/slug-resolver.js';
|
|
65
64
|
import { ListFeaturesUseCase } from '../../application/use-cases/features/list-features.use-case.js';
|
|
@@ -281,7 +280,6 @@ export async function initializeContainer() {
|
|
|
281
280
|
container.registerSingleton(MetadataGenerator);
|
|
282
281
|
container.registerSingleton(SlugResolver);
|
|
283
282
|
container.registerSingleton(CreateFeatureUseCase);
|
|
284
|
-
container.registerSingleton(CreateFeatureFromRemoteUseCase);
|
|
285
283
|
container.registerSingleton(ListFeaturesUseCase);
|
|
286
284
|
container.registerSingleton(ShowFeatureUseCase);
|
|
287
285
|
container.registerSingleton(DeleteFeatureUseCase);
|
|
@@ -325,9 +323,6 @@ export async function initializeContainer() {
|
|
|
325
323
|
container.register('CreateFeatureUseCase', {
|
|
326
324
|
useFactory: (c) => c.resolve(CreateFeatureUseCase),
|
|
327
325
|
});
|
|
328
|
-
container.register('CreateFeatureFromRemoteUseCase', {
|
|
329
|
-
useFactory: (c) => c.resolve(CreateFeatureFromRemoteUseCase),
|
|
330
|
-
});
|
|
331
326
|
container.register('ListFeaturesUseCase', {
|
|
332
327
|
useFactory: (c) => c.resolve(ListFeaturesUseCase),
|
|
333
328
|
});
|
package/dist/packages/core/src/infrastructure/services/tool-installer/tool-installer.service.d.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* - Automatic timeout handling with process termination
|
|
12
12
|
* - Immutable status objects via value object factory functions
|
|
13
13
|
*/
|
|
14
|
-
import type { IToolInstallerService, AvailableTerminalEntry } from '../../../application/ports/output/services/tool-installer.service.js';
|
|
14
|
+
import type { IToolInstallerService, AvailableTerminalEntry, TerminalOpenConfig } from '../../../application/ports/output/services/tool-installer.service.js';
|
|
15
15
|
import type { ToolInstallationStatus, ToolInstallCommand } from '../../../domain/generated/output.js';
|
|
16
16
|
export declare class ToolInstallerServiceImpl implements IToolInstallerService {
|
|
17
17
|
/**
|
|
@@ -35,6 +35,7 @@ export declare class ToolInstallerServiceImpl implements IToolInstallerService {
|
|
|
35
35
|
* DI container even when the Next.js standalone bundle cannot resolve tools/ via import.meta.url.
|
|
36
36
|
*/
|
|
37
37
|
listAvailableTerminals(): Promise<AvailableTerminalEntry[]>;
|
|
38
|
+
getTerminalOpenConfig(terminalId: string): TerminalOpenConfig | null;
|
|
38
39
|
/**
|
|
39
40
|
* Create installation suggestions for a tool based on its metadata
|
|
40
41
|
*/
|
|
@@ -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,EACV,qBAAqB,EACrB,sBAAsB,
|
|
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,EACV,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EACnB,MAAM,sEAAsE,CAAC;AAC9E,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EAEnB,MAAM,qCAAqC,CAAC;AA2B7C,qBACa,wBAAyB,YAAW,qBAAqB;IACpE;;;OAGG;IACG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAoC1E;;;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;IAgFlC;;;;OAIG;IACG,sBAAsB,IAAI,OAAO,CAAC,sBAAsB,EAAE,CAAC;IAuCjE,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI;IAiBpE;;OAEG;IACH,OAAO,CAAC,6BAA6B;CA4BtC"}
|
package/dist/packages/core/src/infrastructure/services/tool-installer/tool-installer.service.js
CHANGED
|
@@ -208,6 +208,20 @@ let ToolInstallerServiceImpl = class ToolInstallerServiceImpl {
|
|
|
208
208
|
}
|
|
209
209
|
return results;
|
|
210
210
|
}
|
|
211
|
+
getTerminalOpenConfig(terminalId) {
|
|
212
|
+
const meta = TOOL_METADATA[terminalId];
|
|
213
|
+
if (!meta?.openDirectory)
|
|
214
|
+
return null;
|
|
215
|
+
const openDirectory = typeof meta.openDirectory === 'string'
|
|
216
|
+
? meta.openDirectory
|
|
217
|
+
: (meta.openDirectory[platform()] ?? Object.values(meta.openDirectory)[0]);
|
|
218
|
+
if (!openDirectory)
|
|
219
|
+
return null;
|
|
220
|
+
return {
|
|
221
|
+
openDirectory,
|
|
222
|
+
shell: meta.spawnOptions?.shell === true,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
211
225
|
/**
|
|
212
226
|
* Create installation suggestions for a tool based on its metadata
|
|
213
227
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"new.command.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/feat/new.command.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"new.command.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/feat/new.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6DpC;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAmJ1C"}
|
|
@@ -8,18 +8,15 @@
|
|
|
8
8
|
* @example
|
|
9
9
|
* $ shep feat new "Add user authentication"
|
|
10
10
|
* $ shep feat new "Add login page" --repo /path/to/project
|
|
11
|
-
* $ shep feat new "Add dark mode" --remote owner/repo
|
|
12
11
|
*/
|
|
13
|
-
import { Command
|
|
12
|
+
import { Command } from 'commander';
|
|
14
13
|
import { createHash } from 'node:crypto';
|
|
15
14
|
import { existsSync } from 'node:fs';
|
|
16
15
|
import { join, resolve } from 'node:path';
|
|
17
16
|
import { container } from '../../../../../packages/core/src/infrastructure/di/container.js';
|
|
18
17
|
import { CreateFeatureUseCase } from '../../../../../packages/core/src/application/use-cases/features/create/create-feature.use-case.js';
|
|
19
|
-
import { CreateFeatureFromRemoteUseCase } from '../../../../../packages/core/src/application/use-cases/features/create/create-feature-from-remote.use-case.js';
|
|
20
18
|
import { SdlcLifecycle } from '../../../../../packages/core/src/domain/generated/output.js';
|
|
21
|
-
import {
|
|
22
|
-
import { colors, messages, symbols, spinner } from '../../ui/index.js';
|
|
19
|
+
import { colors, messages, spinner } from '../../ui/index.js';
|
|
23
20
|
import { getShepHomeDir } from '../../../../../packages/core/src/infrastructure/services/filesystem/shep-directory.service.js';
|
|
24
21
|
import { getSettings, hasSettings } from '../../../../../packages/core/src/infrastructure/services/settings.service.js';
|
|
25
22
|
import { CheckOnboardingStatusUseCase } from '../../../../../packages/core/src/application/use-cases/settings/check-onboarding-status.use-case.js';
|
|
@@ -50,7 +47,6 @@ export function createNewCommand() {
|
|
|
50
47
|
.description('Create a new feature')
|
|
51
48
|
.argument('<description>', 'Feature description')
|
|
52
49
|
.option('-r, --repo <path>', 'Repository path (defaults to current directory)')
|
|
53
|
-
.addOption(new Option('--remote <url>', 'GitHub URL or owner/repo shorthand to clone and create feature on').conflicts('repo'))
|
|
54
50
|
.option('--push', 'Push branch to remote after implementation')
|
|
55
51
|
.option('--pr', 'Open PR on implementation complete (implies --push)')
|
|
56
52
|
.option('--no-pr', 'Do not open PR on implementation complete')
|
|
@@ -72,6 +68,8 @@ export function createNewCommand() {
|
|
|
72
68
|
await onboardingWizard();
|
|
73
69
|
}
|
|
74
70
|
}
|
|
71
|
+
const useCase = container.resolve(CreateFeatureUseCase);
|
|
72
|
+
const repoPath = options.repo ?? process.cwd();
|
|
75
73
|
// Resolve openPr from CLI flags or settings defaults
|
|
76
74
|
const defaults = getWorkflowDefaults();
|
|
77
75
|
const openPr = options.pr ?? defaults.openPr;
|
|
@@ -109,9 +107,9 @@ export function createNewCommand() {
|
|
|
109
107
|
attachmentPaths.push(resolved);
|
|
110
108
|
}
|
|
111
109
|
}
|
|
112
|
-
|
|
113
|
-
const commonInput = {
|
|
110
|
+
const result = await spinner('Thinking', () => useCase.execute({
|
|
114
111
|
userInput: description,
|
|
112
|
+
repositoryPath: repoPath,
|
|
115
113
|
approvalGates,
|
|
116
114
|
push,
|
|
117
115
|
openPr,
|
|
@@ -120,70 +118,8 @@ export function createNewCommand() {
|
|
|
120
118
|
...(options.fast && { fast: true }),
|
|
121
119
|
...(options.model !== undefined && { model: options.model }),
|
|
122
120
|
...(attachmentPaths.length > 0 && { attachmentPaths }),
|
|
123
|
-
};
|
|
124
|
-
let result;
|
|
125
|
-
if (options.remote) {
|
|
126
|
-
// Remote flow: import GitHub repo then create feature
|
|
127
|
-
const remoteUseCase = container.resolve(CreateFeatureFromRemoteUseCase);
|
|
128
|
-
// Read defaultCloneDir from settings
|
|
129
|
-
const settings = getSettings();
|
|
130
|
-
const defaultCloneDir = settings.environment?.defaultCloneDirectory;
|
|
131
|
-
// Dynamic spinner with clone progress updates
|
|
132
|
-
const frames = symbols.spinner;
|
|
133
|
-
let frameIdx = 0;
|
|
134
|
-
let spinnerLabel = 'Cloning repository';
|
|
135
|
-
let maxLabelLen = spinnerLabel.length;
|
|
136
|
-
const writeSpinner = () => {
|
|
137
|
-
const frame = frames[frameIdx % frames.length];
|
|
138
|
-
process.stderr.write(`\r${colors.muted(`${frame} ${spinnerLabel}...`)}`);
|
|
139
|
-
frameIdx++;
|
|
140
|
-
};
|
|
141
|
-
writeSpinner();
|
|
142
|
-
const spinnerInterval = setInterval(writeSpinner, 80);
|
|
143
|
-
const clearSpinner = () => {
|
|
144
|
-
clearInterval(spinnerInterval);
|
|
145
|
-
process.stderr.write(`\r${' '.repeat(maxLabelLen + 6)}\r`);
|
|
146
|
-
};
|
|
147
|
-
try {
|
|
148
|
-
result = await remoteUseCase.execute({
|
|
149
|
-
...commonInput,
|
|
150
|
-
remoteUrl: options.remote,
|
|
151
|
-
...(defaultCloneDir !== undefined && { defaultCloneDir }),
|
|
152
|
-
cloneOptions: {
|
|
153
|
-
onProgress: (data) => {
|
|
154
|
-
// Parse clone progress from gh CLI stderr
|
|
155
|
-
const progressMatch = data.match(/(?:Cloning|Receiving objects|Resolving deltas|Updating files)[^]*?(?:\d+%|\.{3})/);
|
|
156
|
-
if (progressMatch) {
|
|
157
|
-
// Sanitize: take the first meaningful line, trim whitespace
|
|
158
|
-
const line = progressMatch[0].split('\n')[0].trim();
|
|
159
|
-
if (line.length > 0) {
|
|
160
|
-
spinnerLabel = line;
|
|
161
|
-
if (spinnerLabel.length > maxLabelLen) {
|
|
162
|
-
maxLabelLen = spinnerLabel.length;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
},
|
|
167
|
-
},
|
|
168
|
-
});
|
|
169
|
-
clearSpinner();
|
|
170
|
-
}
|
|
171
|
-
catch (error) {
|
|
172
|
-
clearSpinner();
|
|
173
|
-
throw error;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
else {
|
|
177
|
-
// Local flow: use existing repository
|
|
178
|
-
const useCase = container.resolve(CreateFeatureUseCase);
|
|
179
|
-
const repoPath = options.repo ?? process.cwd();
|
|
180
|
-
result = await spinner('Thinking', () => useCase.execute({
|
|
181
|
-
...commonInput,
|
|
182
|
-
repositoryPath: repoPath,
|
|
183
|
-
}));
|
|
184
|
-
}
|
|
121
|
+
}));
|
|
185
122
|
const { feature, warning } = result;
|
|
186
|
-
const repoPath = options.remote ? feature.repositoryPath : (options.repo ?? process.cwd());
|
|
187
123
|
const repoHash = createHash('sha256').update(repoPath).digest('hex').slice(0, 16);
|
|
188
124
|
const wtSlug = feature.branch.replace(/\//g, '-');
|
|
189
125
|
const worktreePath = join(getShepHomeDir(), 'repos', repoHash, 'wt', wtSlug);
|
|
@@ -230,23 +166,6 @@ export function createNewCommand() {
|
|
|
230
166
|
messages.newline();
|
|
231
167
|
}
|
|
232
168
|
catch (error) {
|
|
233
|
-
// Handle GitHub-specific errors with actionable messages
|
|
234
|
-
if (error instanceof GitHubAuthError) {
|
|
235
|
-
messages.error('GitHub CLI is not authenticated. Run `gh auth login` to sign in.');
|
|
236
|
-
process.exitCode = 1;
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
if (error instanceof GitHubUrlParseError) {
|
|
240
|
-
messages.error(`Invalid GitHub URL: ${error.message}`);
|
|
241
|
-
messages.info('Supported formats: https://github.com/owner/repo, git@github.com:owner/repo.git, or owner/repo');
|
|
242
|
-
process.exitCode = 1;
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
if (error instanceof GitHubCloneError) {
|
|
246
|
-
messages.error(`Clone failed: ${error.message}`);
|
|
247
|
-
process.exitCode = 1;
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
169
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
251
170
|
messages.error('Failed to create feature', err);
|
|
252
171
|
process.exitCode = 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open-shell.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/open-shell.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"open-shell.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/open-shell.ts"],"names":[],"mappings":"AA0BA,UAAU,cAAc;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,SAAS,CAC7B,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA4E9E"}
|
|
@@ -5,13 +5,7 @@ import { isAbsolute } from 'node:path';
|
|
|
5
5
|
import { spawn } from 'node:child_process';
|
|
6
6
|
import { getSettings } from '../../../../../packages/core/src/infrastructure/services/settings.service.js';
|
|
7
7
|
import { computeWorktreePath } from '../../../../../packages/core/src/infrastructure/services/ide-launchers/compute-worktree-path.js';
|
|
8
|
-
import {
|
|
9
|
-
/** Resolves a platform-keyed value to the current platform string. */
|
|
10
|
-
function resolvePlatformValue(value) {
|
|
11
|
-
if (typeof value === 'string')
|
|
12
|
-
return value;
|
|
13
|
-
return value[platform()] ?? Object.values(value)[0];
|
|
14
|
-
}
|
|
8
|
+
import { resolve } from '../../lib/server-container.js';
|
|
15
9
|
// Fallback commands for the "system" terminal when no tool metadata entry exists.
|
|
16
10
|
// Uses a record lookup instead of if/else to prevent the bundler from
|
|
17
11
|
// tree-shaking platform branches at build time. Turbopack evaluates
|
|
@@ -38,39 +32,41 @@ export async function openShell(input) {
|
|
|
38
32
|
if (!existsSync(targetPath)) {
|
|
39
33
|
return { success: false, error: `Path does not exist: ${targetPath}` };
|
|
40
34
|
}
|
|
41
|
-
// Try to find the terminal in tool metadata
|
|
35
|
+
// Try to find the terminal in tool metadata via DI container.
|
|
36
|
+
// Using DI (not a direct import from tool-metadata) ensures that
|
|
37
|
+
// TOOL_METADATA is read from the correct tools/ directory path — it is loaded once
|
|
38
|
+
// in the Node.js CLI bootstrap context where import.meta.url resolves correctly.
|
|
39
|
+
// Direct imports of tool-metadata break in standalone production builds.
|
|
42
40
|
if (terminalPref !== 'system') {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
stdio: 'ignore',
|
|
66
|
-
});
|
|
67
|
-
child.on('error', () => undefined);
|
|
68
|
-
child.unref();
|
|
69
|
-
}
|
|
70
|
-
return { success: true, path: targetPath, shell };
|
|
41
|
+
try {
|
|
42
|
+
const service = resolve('IToolInstallerService');
|
|
43
|
+
const config = service.getTerminalOpenConfig(terminalPref);
|
|
44
|
+
if (config?.openDirectory.includes('{dir}')) {
|
|
45
|
+
const resolved = config.openDirectory.replace('{dir}', targetPath);
|
|
46
|
+
if (config.shell) {
|
|
47
|
+
const child = spawn(resolved, [], {
|
|
48
|
+
detached: true,
|
|
49
|
+
stdio: 'ignore',
|
|
50
|
+
shell: true,
|
|
51
|
+
});
|
|
52
|
+
child.on('error', () => undefined);
|
|
53
|
+
child.unref();
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
const [command, ...args] = resolved.split(/\s+/);
|
|
57
|
+
const child = spawn(command, args, {
|
|
58
|
+
detached: true,
|
|
59
|
+
stdio: 'ignore',
|
|
60
|
+
});
|
|
61
|
+
child.on('error', () => undefined);
|
|
62
|
+
child.unref();
|
|
71
63
|
}
|
|
64
|
+
return { success: true, path: targetPath, shell };
|
|
72
65
|
}
|
|
73
66
|
}
|
|
67
|
+
catch {
|
|
68
|
+
// DI container not available — fall through to system terminal
|
|
69
|
+
}
|
|
74
70
|
}
|
|
75
71
|
// Fallback to system terminal
|
|
76
72
|
const entry = SYSTEM_TERMINAL_COMMANDS[platform()];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-create-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"feature-create-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAS5E,YAAY,EAAE,cAAc,EAAE,MAAM,0DAA0D,CAAC;AAE/F,uFAAuF;AACvF,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,0DAA0D;AAC1D,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,iEAAiE;AACjE,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE;QACb,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,OAAO,CAAC;QACnB,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC;IACF,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,IAAI,EAAE,OAAO,CAAC;IACd,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA+ED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC/C,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACjC,+EAA+E;IAC/E,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAClC,kGAAkG;IAClG,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8CAA8C;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yCAAyC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,cAAc,EACd,YAAoB,EACpB,gBAAgB,EAChB,QAAQ,EACR,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,GACnB,EAAE,wBAAwB,2CAwzB1B;AAmJD,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAC7C,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACnD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,kBAAkB,CAAC,EACjC,YAAY,EACZ,KAAK,EACL,QAAQ,EACR,eAAe,EACf,QAAQ,GACT,EAAE,uBAAuB,2CAiNzB"}
|
package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useCallback, useEffect, useRef } from 'react';
|
|
4
|
-
import { PaperclipIcon, ChevronsUpDown, CheckIcon, Zap, Clock, FolderPlus, Loader2,
|
|
4
|
+
import { PaperclipIcon, ChevronsUpDown, CheckIcon, Zap, Clock, FolderPlus, Loader2, } from 'lucide-react';
|
|
5
5
|
import { cn } from '../../../lib/utils.js';
|
|
6
6
|
import { useSoundAction } from '../../../hooks/use-sound-action.js';
|
|
7
7
|
import { BaseDrawer } from '../../common/base-drawer/index.js';
|
|
@@ -22,7 +22,6 @@ import { pickFolder } from '../../common/add-repository-button/pick-folder.js';
|
|
|
22
22
|
import { ReactFileManagerDialog } from '../../common/react-file-manager-dialog/index.js';
|
|
23
23
|
import { useFeatureFlags } from '../../../hooks/feature-flags-context.js';
|
|
24
24
|
import { addRepository } from '../../../app/actions/add-repository.js';
|
|
25
|
-
import { GitHubImportDialog } from '../../common/github-import-dialog/index.js';
|
|
26
25
|
import { pickFiles } from './pick-files.js';
|
|
27
26
|
const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10 MB
|
|
28
27
|
const ALLOWED_EXTENSIONS = new Set([
|
|
@@ -496,9 +495,8 @@ export function RepositoryCombobox({ repositories, value, onChange, onAddReposit
|
|
|
496
495
|
const [isAdding, setIsAdding] = useState(false);
|
|
497
496
|
const [addError, setAddError] = useState(null);
|
|
498
497
|
const [showReactPicker, setShowReactPicker] = useState(false);
|
|
499
|
-
const [showGitHubImport, setShowGitHubImport] = useState(false);
|
|
500
498
|
const inputRef = useRef(null);
|
|
501
|
-
const { reactFileManager: useReactFileManager
|
|
499
|
+
const { reactFileManager: useReactFileManager } = useFeatureFlags();
|
|
502
500
|
const selectedRepo = repositories.find((r) => r.path === value);
|
|
503
501
|
const filtered = query.trim()
|
|
504
502
|
? repositories.filter((r) => r.name.toLowerCase().includes(query.toLowerCase()) ||
|
|
@@ -553,18 +551,6 @@ export function RepositoryCombobox({ repositories, value, onChange, onAddReposit
|
|
|
553
551
|
setIsAdding(false);
|
|
554
552
|
}
|
|
555
553
|
}, [isAdding, useReactFileManager, addRepoFromPath]);
|
|
556
|
-
const handleGitHubImportComplete = useCallback((repository) => {
|
|
557
|
-
const newRepo = {
|
|
558
|
-
id: repository.id,
|
|
559
|
-
name: repository.name,
|
|
560
|
-
path: repository.path,
|
|
561
|
-
};
|
|
562
|
-
onAddRepository?.(newRepo);
|
|
563
|
-
onChange(newRepo.path);
|
|
564
|
-
setOpen(false);
|
|
565
|
-
setQuery('');
|
|
566
|
-
setShowGitHubImport(false);
|
|
567
|
-
}, [onAddRepository, onChange]);
|
|
568
554
|
const handleReactPickerSelect = useCallback(async (path) => {
|
|
569
555
|
setShowReactPicker(false);
|
|
570
556
|
if (!path)
|
|
@@ -589,8 +575,8 @@ export function RepositoryCombobox({ repositories, value, onChange, onAddReposit
|
|
|
589
575
|
setQuery('');
|
|
590
576
|
}
|
|
591
577
|
}, [open]);
|
|
592
|
-
return (_jsxs(_Fragment, { children: [_jsxs(Popover, { open: open, onOpenChange: setOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("button", { type: "button", role: "combobox", "aria-expanded": open, "aria-label": "Repository", disabled: disabled, "data-testid": "repository-combobox", className: cn('border-input bg-background ring-offset-background focus:ring-ring flex h-9 w-full items-center justify-between rounded-md border px-3 py-2 text-sm focus:ring-2 focus:ring-offset-2 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50', !selectedRepo && 'text-muted-foreground'), children: [_jsx("span", { className: "truncate", children: selectedRepo ? selectedRepo.name : 'Select repository...' }), _jsx(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })] }) }), _jsx(PopoverContent, { className: "w-80 p-0", align: "start", "data-testid": "repository-combobox-content", children: _jsxs("div", { className: "flex flex-col", children: [_jsx("div", { className: "border-b p-2", children: _jsx(Input, { ref: inputRef, placeholder: "Search repositories...", value: query, onChange: (e) => setQuery(e.target.value), className: "h-8 border-0 p-0 text-sm shadow-none focus-visible:ring-0", "data-testid": "repository-search" }) }), _jsx("div", { className: "max-h-48 overflow-y-auto py-1", role: "listbox", "aria-label": "Repositories", children: filtered.length === 0 ? (_jsx("p", { className: "text-muted-foreground px-3 py-2 text-sm", "data-testid": "repository-empty", children: "No repositories found." })) : (filtered.map((r) => (_jsxs("button", { type: "button", role: "option", "aria-selected": value === r.path, onClick: () => handleSelect(r.path), className: cn('hover:bg-accent hover:text-accent-foreground flex w-full items-center gap-2 px-3 py-2 text-sm', value === r.path && 'bg-accent/50'), "data-testid": `repository-option-${r.id}`, children: [_jsx(CheckIcon, { className: cn('h-4 w-4 shrink-0', value !== r.path && 'invisible') }), _jsxs("span", { className: "flex flex-col items-start truncate", children: [_jsx("span", { className: "truncate", children: r.name }), _jsx("span", { className: "text-muted-foreground truncate text-xs", children: r.path })] })] }, r.id)))) }), _jsx(Separator, {}),
|
|
578
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Popover, { open: open, onOpenChange: setOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("button", { type: "button", role: "combobox", "aria-expanded": open, "aria-label": "Repository", disabled: disabled, "data-testid": "repository-combobox", className: cn('border-input bg-background ring-offset-background focus:ring-ring flex h-9 w-full items-center justify-between rounded-md border px-3 py-2 text-sm focus:ring-2 focus:ring-offset-2 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50', !selectedRepo && 'text-muted-foreground'), children: [_jsx("span", { className: "truncate", children: selectedRepo ? selectedRepo.name : 'Select repository...' }), _jsx(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })] }) }), _jsx(PopoverContent, { className: "w-80 p-0", align: "start", "data-testid": "repository-combobox-content", children: _jsxs("div", { className: "flex flex-col", children: [_jsx("div", { className: "border-b p-2", children: _jsx(Input, { ref: inputRef, placeholder: "Search repositories...", value: query, onChange: (e) => setQuery(e.target.value), className: "h-8 border-0 p-0 text-sm shadow-none focus-visible:ring-0", "data-testid": "repository-search" }) }), _jsx("div", { className: "max-h-48 overflow-y-auto py-1", role: "listbox", "aria-label": "Repositories", children: filtered.length === 0 ? (_jsx("p", { className: "text-muted-foreground px-3 py-2 text-sm", "data-testid": "repository-empty", children: "No repositories found." })) : (filtered.map((r) => (_jsxs("button", { type: "button", role: "option", "aria-selected": value === r.path, onClick: () => handleSelect(r.path), className: cn('hover:bg-accent hover:text-accent-foreground flex w-full items-center gap-2 px-3 py-2 text-sm', value === r.path && 'bg-accent/50'), "data-testid": `repository-option-${r.id}`, children: [_jsx(CheckIcon, { className: cn('h-4 w-4 shrink-0', value !== r.path && 'invisible') }), _jsxs("span", { className: "flex flex-col items-start truncate", children: [_jsx("span", { className: "truncate", children: r.name }), _jsx("span", { className: "text-muted-foreground truncate text-xs", children: r.path })] })] }, r.id)))) }), _jsx(Separator, {}), _jsxs("button", { type: "button", onClick: handleAddRepository, disabled: isAdding, className: "hover:bg-accent hover:text-accent-foreground flex w-full items-center gap-2 px-3 py-2 text-sm", "data-testid": "add-repository-item", children: [isAdding ? (_jsx(Loader2, { className: "h-4 w-4 shrink-0 animate-spin" })) : (_jsx(FolderPlus, { className: "h-4 w-4 shrink-0" })), _jsx("span", { children: "Add new repository..." })] }), addError ? (_jsx("p", { className: "px-3 pb-2 text-xs text-red-500", "data-testid": "add-repository-error", children: addError })) : null] }) })] }), _jsx(ReactFileManagerDialog, { open: showReactPicker, onOpenChange: (isOpen) => {
|
|
593
579
|
if (!isOpen)
|
|
594
580
|
setShowReactPicker(false);
|
|
595
|
-
}, onSelect: handleReactPickerSelect })
|
|
581
|
+
}, onSelect: handleReactPickerSelect })] }));
|
|
596
582
|
}
|
|
@@ -11,10 +11,4 @@ export declare const EmptyList: Story;
|
|
|
11
11
|
export declare const PreSelected: Story;
|
|
12
12
|
/** Disabled state — combobox trigger button is non-interactive. */
|
|
13
13
|
export declare const Disabled: Story;
|
|
14
|
-
/** GitHub import enabled — "Import from GitHub..." button visible in dropdown. */
|
|
15
|
-
export declare const WithGitHubImport: Story;
|
|
16
|
-
/** GitHub import disabled — "Import from GitHub..." button hidden. */
|
|
17
|
-
export declare const WithGitHubImportDisabled: Story;
|
|
18
|
-
/** Empty list with GitHub import — shows import option alongside add repository. */
|
|
19
|
-
export declare const EmptyWithGitHubImport: Story;
|
|
20
14
|
//# sourceMappingURL=repository-combobox.stories.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository-combobox.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-create-drawer/repository-combobox.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"repository-combobox.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-create-drawer/repository-combobox.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAU7D,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,kBAAkB,CAOzC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,kBAAkB,CAAC,CAAC;AA+BjD,wEAAwE;AACxE,eAAO,MAAM,gBAAgB,EAAE,KAE9B,CAAC;AAEF,8FAA8F;AAC9F,eAAO,MAAM,SAAS,EAAE,KAEvB,CAAC;AAEF,6EAA6E;AAC7E,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC;AAEF,mEAAmE;AACnE,eAAO,MAAM,QAAQ,EAAE,KAEtB,CAAC"}
|
|
@@ -1,29 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { RepositoryCombobox } from './feature-create-drawer.js';
|
|
4
|
-
import { FeatureFlagsProvider } from '../../../hooks/feature-flags-context.js';
|
|
5
4
|
const SAMPLE_REPOSITORIES = [
|
|
6
5
|
{ id: 'repo-001', name: 'my-app', path: '/Users/dev/projects/my-app' },
|
|
7
6
|
{ id: 'repo-002', name: 'api-service', path: '/Users/dev/projects/api-service' },
|
|
8
7
|
{ id: 'repo-003', name: 'shared-lib', path: '/Users/dev/libs/shared-lib' },
|
|
9
8
|
{ id: 'repo-004', name: 'docs-site', path: '/Users/dev/projects/docs-site' },
|
|
10
9
|
];
|
|
11
|
-
const flagsWithGitHubImport = {
|
|
12
|
-
skills: false,
|
|
13
|
-
envDeploy: false,
|
|
14
|
-
debug: false,
|
|
15
|
-
githubImport: true,
|
|
16
|
-
adoptBranch: false,
|
|
17
|
-
reactFileManager: false,
|
|
18
|
-
};
|
|
19
|
-
const flagsWithoutGitHubImport = {
|
|
20
|
-
skills: false,
|
|
21
|
-
envDeploy: false,
|
|
22
|
-
debug: false,
|
|
23
|
-
githubImport: false,
|
|
24
|
-
adoptBranch: false,
|
|
25
|
-
reactFileManager: false,
|
|
26
|
-
};
|
|
27
10
|
const meta = {
|
|
28
11
|
title: 'Drawers/Feature/RepositoryCombobox',
|
|
29
12
|
component: RepositoryCombobox,
|
|
@@ -33,17 +16,13 @@ const meta = {
|
|
|
33
16
|
},
|
|
34
17
|
};
|
|
35
18
|
export default meta;
|
|
36
|
-
function RepositoryComboboxWrapper({ repositories: initialRepos, initialValue, disabled,
|
|
19
|
+
function RepositoryComboboxWrapper({ repositories: initialRepos, initialValue, disabled, }) {
|
|
37
20
|
const [repos, setRepos] = useState(initialRepos);
|
|
38
21
|
const [value, setValue] = useState(initialValue);
|
|
39
|
-
|
|
22
|
+
return (_jsxs("div", { className: "w-80", children: [_jsx(RepositoryCombobox, { repositories: repos, value: value, onChange: setValue, onAddRepository: (repo) => {
|
|
40
23
|
setRepos((prev) => [...prev, repo]);
|
|
41
24
|
setValue(repo.path);
|
|
42
25
|
}, disabled: disabled }), value ? _jsxs("p", { className: "text-muted-foreground mt-2 text-xs", children: ["Selected: ", value] }) : null] }));
|
|
43
|
-
if (flags) {
|
|
44
|
-
return _jsx(FeatureFlagsProvider, { flags: flags, children: combobox });
|
|
45
|
-
}
|
|
46
|
-
return combobox;
|
|
47
26
|
}
|
|
48
27
|
/** Default state with multiple repositories available for selection. */
|
|
49
28
|
export const WithRepositories = {
|
|
@@ -61,15 +40,3 @@ export const PreSelected = {
|
|
|
61
40
|
export const Disabled = {
|
|
62
41
|
render: () => _jsx(RepositoryComboboxWrapper, { repositories: SAMPLE_REPOSITORIES, disabled: true }),
|
|
63
42
|
};
|
|
64
|
-
/** GitHub import enabled — "Import from GitHub..." button visible in dropdown. */
|
|
65
|
-
export const WithGitHubImport = {
|
|
66
|
-
render: () => (_jsx(RepositoryComboboxWrapper, { repositories: SAMPLE_REPOSITORIES, flags: flagsWithGitHubImport })),
|
|
67
|
-
};
|
|
68
|
-
/** GitHub import disabled — "Import from GitHub..." button hidden. */
|
|
69
|
-
export const WithGitHubImportDisabled = {
|
|
70
|
-
render: () => (_jsx(RepositoryComboboxWrapper, { repositories: SAMPLE_REPOSITORIES, flags: flagsWithoutGitHubImport })),
|
|
71
|
-
};
|
|
72
|
-
/** Empty list with GitHub import — shows import option alongside add repository. */
|
|
73
|
-
export const EmptyWithGitHubImport = {
|
|
74
|
-
render: () => _jsx(RepositoryComboboxWrapper, { repositories: [], flags: flagsWithGitHubImport }),
|
|
75
|
-
};
|
|
@@ -34,7 +34,7 @@ export function getFeatureFlags() {
|
|
|
34
34
|
? isEnabled(process.env.NEXT_PUBLIC_FLAG_ENV_DEPLOY)
|
|
35
35
|
: true,
|
|
36
36
|
debug: false,
|
|
37
|
-
githubImport:
|
|
37
|
+
githubImport: false,
|
|
38
38
|
adoptBranch: false,
|
|
39
39
|
reactFileManager: isEnabled(process.env.NEXT_PUBLIC_FLAG_REACT_FILE_MANAGER),
|
|
40
40
|
};
|