@shepai/cli 1.107.1 → 1.107.2-pr335.e03c737
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts +2 -1
- package/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/cleanup-feature-worktree.use-case.js +1 -1
- package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +2 -2
- package/dist/packages/core/src/application/use-cases/features/create/metadata-generator.d.ts +5 -0
- package/dist/packages/core/src/application/use-cases/features/create/metadata-generator.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/create/metadata-generator.js +31 -13
- package/dist/packages/core/src/application/use-cases/features/delete-feature.use-case.js +1 -1
- 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 +6 -2
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +14 -3
- package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.js +4 -4
- package/dist/packages/core/src/infrastructure/repositories/sqlite-repository.repository.js +4 -4
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.js +9 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.js +26 -7
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.js +5 -3
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/gemini-cli-executor.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/gemini-cli-executor.service.js +7 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.js +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/evidence-prompts.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/evidence-prompts.js +4 -3
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/repair.node.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/repair.node.js +2 -1
- package/dist/packages/core/src/infrastructure/services/agents/sessions/claude-code-session.repository.js +1 -1
- package/dist/packages/core/src/infrastructure/services/attachment-storage.service.js +3 -3
- package/dist/packages/core/src/infrastructure/services/deployment/deployment.service.d.ts +1 -1
- package/dist/packages/core/src/infrastructure/services/deployment/deployment.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/deployment/deployment.service.js +8 -7
- package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts +1 -1
- package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/git/worktree.service.js +23 -8
- package/dist/packages/core/src/infrastructure/services/ide-launchers/compute-worktree-path.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/ide-launchers/compute-worktree-path.js +4 -2
- package/dist/packages/core/src/infrastructure/services/ide-launchers/json-driven-ide-launcher.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/ide-launchers/json-driven-ide-launcher.service.js +11 -9
- package/dist/packages/core/src/infrastructure/services/process/tree-kill.d.ts +12 -0
- package/dist/packages/core/src/infrastructure/services/process/tree-kill.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/process/tree-kill.js +11 -0
- package/dist/packages/core/src/infrastructure/services/tool-installer/binary-exists.d.ts +25 -0
- package/dist/packages/core/src/infrastructure/services/tool-installer/binary-exists.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/tool-installer/binary-exists.js +32 -0
- package/dist/packages/core/src/infrastructure/services/tool-installer/tool-installer.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/tool-installer/tool-installer.service.js +4 -27
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/alacritty.json +3 -2
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/claude-code.json +3 -2
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/cursor-cli.json +3 -2
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/cursor.json +2 -1
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/gh.json +2 -1
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/git.json +2 -1
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/vscode.json +2 -1
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/warp.json +3 -2
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/windsurf.json +3 -2
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/zed.json +3 -2
- package/dist/src/presentation/cli/commands/daemon/start-daemon.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/daemon/start-daemon.js +1 -0
- package/dist/src/presentation/cli/commands/daemon/stop-daemon.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/daemon/stop-daemon.js +5 -4
- package/dist/src/presentation/cli/commands/upgrade.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/upgrade.command.js +4 -0
- package/dist/src/presentation/web/app/actions/deploy-repository.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/deploy-repository.js +2 -1
- package/dist/src/presentation/web/app/actions/open-folder.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/open-folder.js +4 -2
- package/dist/src/presentation/web/app/actions/open-ide.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/open-ide.js +2 -1
- package/dist/src/presentation/web/app/actions/open-shell.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/open-shell.js +4 -2
- package/dist/src/presentation/web/app/build-graph-nodes.d.ts.map +1 -1
- package/dist/src/presentation/web/app/build-graph-nodes.js +8 -5
- 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 +10 -20
- package/dist/src/presentation/web/components/common/merge-review/diff-view.js +1 -1
- 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 +12 -0
- 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 +32 -8
- package/dist/src/presentation/web/hooks/use-graph-state.d.ts +14 -0
- package/dist/src/presentation/web/hooks/use-graph-state.d.ts.map +1 -1
- package/dist/src/presentation/web/hooks/use-graph-state.js +35 -1
- package/dist/src/presentation/web/lib/derive-graph.d.ts.map +1 -1
- package/dist/src/presentation/web/lib/derive-graph.js +4 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +10 -6
- 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/create/page/server-reference-manifest.json +20 -20
- 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 +26 -26
- 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 +26 -26
- 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 +18 -18
- 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 +20 -20
- 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 +26 -26
- 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 +26 -26
- 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 +18 -18
- 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 +18 -18
- 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 +1 -1
- 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 +5 -5
- 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 +6 -6
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- 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_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_a1104008.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_a1104008.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_92642200.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_92642200.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__039967e3._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__039967e3._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__07a39ff2._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__24dd0927._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__24dd0927._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2773312c._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2773312c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__5d87af2e._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__845a9d2a._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__845a9d2a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__89e8a5cc._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__89e8a5cc._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__cbd8062c._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__cbd8062c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__e70c5627._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__e70c5627._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_4d49c223._.js → _0314f5ef._.js} +2 -2
- package/web/.next/server/chunks/ssr/_0314f5ef._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
- package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_89745126._.js → _5cceebc2._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_89745126._.js.map → _5cceebc2._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_8dacd1e7._.js +1 -1
- package/web/.next/server/chunks/ssr/_8dacd1e7._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
- package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_3c0076bc._.js → _e7f4342a._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_3c0076bc._.js.map → _e7f4342a._.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__next-internal_server_app_(dashboard)_page_actions_888633e1.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_888633e1.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_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_ce7cbc3c._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_ce7cbc3c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.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/chunks/ssr/src_presentation_web_e2604413._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_e2604413._.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 +31 -31
- package/web/.next/static/chunks/{5ebc63ae73de50a3.js → 12debbecf940f9f4.js} +1 -1
- package/web/.next/static/chunks/{2eab3bb5550eccac.js → 1fa5f5d8cacab7a6.js} +1 -1
- package/web/.next/static/chunks/{9751a0c871920841.js → 28c2de3064d1f7f7.js} +1 -1
- package/web/.next/static/chunks/{e429067d6277ac20.js → 542837b8eafc1f70.js} +1 -1
- package/web/.next/static/chunks/{2c6298885de1484c.js → 83b8f1c9045f3f0c.js} +1 -1
- package/web/.next/static/chunks/{f28d2411c36c308b.js → 9177b327b379b61f.js} +1 -1
- package/web/.next/static/chunks/a1703e2e9adb6b7c.js +2 -0
- package/web/.next/static/chunks/{fa27e698e0daf727.js → a949fc447e78e19d.js} +1 -1
- package/web/.next/static/chunks/{eed22af4cf55faea.js → ccb531223ea544c6.js} +1 -1
- package/web/.next/static/chunks/{dd30ae99bcec5f69.js → d89266ba8c9b4e53.js} +2 -2
- package/web/.next/server/chunks/ssr/_4d49c223._.js.map +0 -1
- package/web/.next/static/chunks/281782a712ea79cb.js +0 -2
- /package/web/.next/static/{OYucSKP83TUMTV1zRbeB8 → -tvtxsxGKXaQ4TutMyzMz}/_buildManifest.js +0 -0
- /package/web/.next/static/{OYucSKP83TUMTV1zRbeB8 → -tvtxsxGKXaQ4TutMyzMz}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{OYucSKP83TUMTV1zRbeB8 → -tvtxsxGKXaQ4TutMyzMz}/_ssgManifest.js +0 -0
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { spawn } from 'node:child_process';
|
|
10
10
|
import { EventEmitter } from 'node:events';
|
|
11
|
+
import treeKill from 'tree-kill';
|
|
11
12
|
import { DeploymentState } from '../../../domain/generated/output.js';
|
|
12
13
|
import { detectDevScript } from './detect-dev-script.js';
|
|
13
14
|
import { createDeploymentLogger } from './deployment-logger.js';
|
|
@@ -19,7 +20,7 @@ const MAX_WAIT_MS = 5000;
|
|
|
19
20
|
const defaultDeps = {
|
|
20
21
|
spawn,
|
|
21
22
|
detectDevScript,
|
|
22
|
-
kill: (pid, signal) =>
|
|
23
|
+
kill: (pid, signal) => treeKill(pid, signal),
|
|
23
24
|
isAlive: (pid) => {
|
|
24
25
|
try {
|
|
25
26
|
process.kill(pid, 0);
|
|
@@ -123,11 +124,11 @@ export class DeploymentService {
|
|
|
123
124
|
log.info(`stop("${targetId}") — no deployment found, nothing to stop`);
|
|
124
125
|
return;
|
|
125
126
|
}
|
|
126
|
-
log.info(`stop("${targetId}") — sending SIGTERM to process
|
|
127
|
+
log.info(`stop("${targetId}") — sending SIGTERM to process tree (pid=${entry.pid})`);
|
|
127
128
|
entry.logs.clear();
|
|
128
|
-
// Send SIGTERM to process
|
|
129
|
+
// Send SIGTERM to process tree (tree-kill handles child processes)
|
|
129
130
|
try {
|
|
130
|
-
this.deps.kill(
|
|
131
|
+
this.deps.kill(entry.pid, 'SIGTERM');
|
|
131
132
|
}
|
|
132
133
|
catch {
|
|
133
134
|
log.info(`stop("${targetId}") — process already dead on SIGTERM`);
|
|
@@ -140,7 +141,7 @@ export class DeploymentService {
|
|
|
140
141
|
log.warn(`stop("${targetId}") — process did not exit after ${MAX_WAIT_MS}ms, escalating to SIGKILL`);
|
|
141
142
|
// Escalate to SIGKILL
|
|
142
143
|
try {
|
|
143
|
-
this.deps.kill(
|
|
144
|
+
this.deps.kill(entry.pid, 'SIGKILL');
|
|
144
145
|
}
|
|
145
146
|
catch {
|
|
146
147
|
// Process may have exited between check and kill
|
|
@@ -183,11 +184,11 @@ export class DeploymentService {
|
|
|
183
184
|
this.emitter.off(event, handler);
|
|
184
185
|
}
|
|
185
186
|
/**
|
|
186
|
-
* Send SIGKILL to a process
|
|
187
|
+
* Send SIGKILL to a process tree.
|
|
187
188
|
*/
|
|
188
189
|
killProcess(entry) {
|
|
189
190
|
try {
|
|
190
|
-
this.deps.kill(
|
|
191
|
+
this.deps.kill(entry.pid, 'SIGKILL');
|
|
191
192
|
}
|
|
192
193
|
catch {
|
|
193
194
|
// Process may already be dead
|
|
@@ -18,7 +18,7 @@ export declare class WorktreeService implements IWorktreeService {
|
|
|
18
18
|
private readonly execFile;
|
|
19
19
|
constructor(execFile: ExecFunction);
|
|
20
20
|
create(repoPath: string, branch: string, worktreePath: string, startPoint?: string): Promise<WorktreeInfo>;
|
|
21
|
-
remove(worktreePath: string, force?: boolean): Promise<void>;
|
|
21
|
+
remove(repoPath: string, worktreePath: string, force?: boolean): Promise<void>;
|
|
22
22
|
prune(repoPath: string): Promise<void>;
|
|
23
23
|
list(repoPath: string): Promise<WorktreeInfo[]>;
|
|
24
24
|
exists(repoPath: string, branch: string): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worktree.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/worktree.service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACb,MAAM,0EAA0E,CAAC;AAOlF;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEjD,qBACa,eAAgB,YAAW,gBAAgB;IAClB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAErE,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"worktree.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/worktree.service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACb,MAAM,0EAA0E,CAAC;AAOlF;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEjD,qBACa,eAAgB,YAAW,gBAAgB;IAClB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAErE,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC;IAuBlB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAW9E,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAO/C,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK1D,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWhE,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWtE,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqC1D,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IAQzD,OAAO,CAAC,mBAAmB;IA2B3B,OAAO,CAAC,aAAa;IAgCrB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,qBAAqB;CAsB9B"}
|
|
@@ -18,7 +18,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
18
18
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
19
19
|
};
|
|
20
20
|
import { createHash } from 'node:crypto';
|
|
21
|
-
import { mkdirSync } from 'node:fs';
|
|
21
|
+
import { mkdirSync, realpathSync } from 'node:fs';
|
|
22
22
|
import path from 'node:path';
|
|
23
23
|
import { injectable, inject } from 'tsyringe';
|
|
24
24
|
const GIT_AUTO_INIT_USER = 'shep-ai[bot]';
|
|
@@ -40,21 +40,22 @@ let WorktreeService = class WorktreeService {
|
|
|
40
40
|
catch (error) {
|
|
41
41
|
throw this.parseGitError(error);
|
|
42
42
|
}
|
|
43
|
-
// Get info about the created worktree
|
|
43
|
+
// Get info about the created worktree — match by branch (reliable) then path
|
|
44
44
|
const worktrees = await this.list(repoPath);
|
|
45
|
-
const created = worktrees.find((w) =>
|
|
45
|
+
const created = worktrees.find((w) => w.branch === branch) ??
|
|
46
|
+
worktrees.find((w) => this.arePathsEquivalent(w.path, worktreePath));
|
|
46
47
|
if (!created) {
|
|
47
48
|
throw new WorktreeError('Worktree created but not found in list', WorktreeErrorCode.GIT_ERROR);
|
|
48
49
|
}
|
|
49
50
|
return created;
|
|
50
51
|
}
|
|
51
|
-
async remove(worktreePath, force) {
|
|
52
|
+
async remove(repoPath, worktreePath, force) {
|
|
52
53
|
try {
|
|
53
54
|
const args = ['worktree', 'remove'];
|
|
54
55
|
if (force)
|
|
55
56
|
args.push('--force');
|
|
56
57
|
args.push(worktreePath);
|
|
57
|
-
await this.execFile('git', args, {});
|
|
58
|
+
await this.execFile('git', args, { cwd: repoPath });
|
|
58
59
|
}
|
|
59
60
|
catch (error) {
|
|
60
61
|
throw this.parseGitError(error);
|
|
@@ -123,7 +124,7 @@ let WorktreeService = class WorktreeService {
|
|
|
123
124
|
try {
|
|
124
125
|
if (!isExistingRepo) {
|
|
125
126
|
mkdirSync(repoPath, { recursive: true });
|
|
126
|
-
await this.execFile('git', ['init'], { cwd: repoPath });
|
|
127
|
+
await this.execFile('git', ['init', '-b', 'main'], { cwd: repoPath });
|
|
127
128
|
}
|
|
128
129
|
await this.execFile('git', ['config', 'user.name', GIT_AUTO_INIT_USER], { cwd: repoPath });
|
|
129
130
|
await this.execFile('git', ['config', 'user.email', GIT_AUTO_INIT_EMAIL], { cwd: repoPath });
|
|
@@ -134,9 +135,11 @@ let WorktreeService = class WorktreeService {
|
|
|
134
135
|
}
|
|
135
136
|
}
|
|
136
137
|
getWorktreePath(repoPath, branch) {
|
|
137
|
-
|
|
138
|
+
// Normalize separators before hashing so C:\foo and C:/foo produce the same hash
|
|
139
|
+
const normalizedRepoPath = repoPath.replace(/\\/g, '/');
|
|
140
|
+
const repoHash = createHash('sha256').update(normalizedRepoPath).digest('hex').slice(0, 16);
|
|
138
141
|
const slug = branch.replace(/\//g, '-');
|
|
139
|
-
return path.join(getShepHomeDir(), 'repos', repoHash, 'wt', slug);
|
|
142
|
+
return path.join(getShepHomeDir(), 'repos', repoHash, 'wt', slug).replace(/\\/g, '/');
|
|
140
143
|
}
|
|
141
144
|
parseWorktreeOutput(output) {
|
|
142
145
|
if (!output.trim())
|
|
@@ -178,6 +181,18 @@ let WorktreeService = class WorktreeService {
|
|
|
178
181
|
return this.normalizeWorktreePath(a) === this.normalizeWorktreePath(b);
|
|
179
182
|
}
|
|
180
183
|
normalizeWorktreePath(input) {
|
|
184
|
+
// On Windows, git outputs forward slashes but path.normalize uses backslashes.
|
|
185
|
+
// Normalize to forward slashes before comparing, case-insensitive.
|
|
186
|
+
if (process.platform === 'win32') {
|
|
187
|
+
let normalized = path.normalize(input).replace(/\\/g, '/').replace(/\/+$/, '');
|
|
188
|
+
try {
|
|
189
|
+
normalized = realpathSync(normalized).replace(/\\/g, '/');
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
// Path may not exist yet — use as-is
|
|
193
|
+
}
|
|
194
|
+
return normalized.toLowerCase();
|
|
195
|
+
}
|
|
181
196
|
const normalized = path.normalize(input).replace(/\/+$/, '');
|
|
182
197
|
// On macOS, git can report /private/var/... while callers use /var/...
|
|
183
198
|
if (process.platform === 'darwin' && normalized.startsWith('/private/var/')) {
|
package/dist/packages/core/src/infrastructure/services/ide-launchers/compute-worktree-path.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compute-worktree-path.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/ide-launchers/compute-worktree-path.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"compute-worktree-path.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/ide-launchers/compute-worktree-path.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAM5E"}
|
package/dist/packages/core/src/infrastructure/services/ide-launchers/compute-worktree-path.js
CHANGED
|
@@ -17,7 +17,9 @@ import { getShepHomeDir } from '../filesystem/shep-directory.service.js';
|
|
|
17
17
|
* @returns Absolute path to the worktree directory under ~/.shep/repos/
|
|
18
18
|
*/
|
|
19
19
|
export function computeWorktreePath(repoPath, branch) {
|
|
20
|
-
|
|
20
|
+
// Normalize separators before hashing so C:\foo and C:/foo produce the same hash
|
|
21
|
+
const normalizedRepoPath = repoPath.replace(/\\/g, '/');
|
|
22
|
+
const repoHash = createHash('sha256').update(normalizedRepoPath).digest('hex').slice(0, 16);
|
|
21
23
|
const slug = branch.replace(/\//g, '-');
|
|
22
|
-
return join(getShepHomeDir(), 'repos', repoHash, 'wt', slug);
|
|
24
|
+
return join(getShepHomeDir(), 'repos', repoHash, 'wt', slug).replace(/\\/g, '/');
|
|
23
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-driven-ide-launcher.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/ide-launchers/json-driven-ide-launcher.service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"json-driven-ide-launcher.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/ide-launchers/json-driven-ide-launcher.service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EAChB,MAAM,8EAA8E,CAAC;AAetF;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAGnF;AAED,qBACa,4BAA6B,YAAW,mBAAmB;IACtE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;;IAiB1C,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAC/B,OAAO,CAAC,eAAe,CAAC;IAkErB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAQ5D"}
|
|
@@ -16,8 +16,9 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
16
16
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
17
17
|
};
|
|
18
18
|
import { injectable } from 'tsyringe';
|
|
19
|
-
import { spawn
|
|
19
|
+
import { spawn } from 'node:child_process';
|
|
20
20
|
import { platform } from 'node:os';
|
|
21
|
+
import { checkBinaryExists } from '../tool-installer/binary-exists.js';
|
|
21
22
|
import { TOOL_METADATA } from '../tool-installer/tool-metadata.js';
|
|
22
23
|
/**
|
|
23
24
|
* Resolve a platform-specific value from a string or per-platform record.
|
|
@@ -82,7 +83,11 @@ let JsonDrivenIdeLauncherService = class JsonDrivenIdeLauncherService {
|
|
|
82
83
|
child = spawn(resolved, [], opts);
|
|
83
84
|
}
|
|
84
85
|
else {
|
|
85
|
-
|
|
86
|
+
// Split the template BEFORE substituting {dir} so that directory
|
|
87
|
+
// paths containing spaces are kept as a single argument.
|
|
88
|
+
const parts = openCmd.split(/\s+/);
|
|
89
|
+
const command = parts[0].replace('{dir}', directoryPath);
|
|
90
|
+
const args = parts.slice(1).map((p) => p.replace('{dir}', directoryPath));
|
|
86
91
|
child = spawn(command, args, opts);
|
|
87
92
|
}
|
|
88
93
|
if (opts.detached)
|
|
@@ -101,16 +106,13 @@ let JsonDrivenIdeLauncherService = class JsonDrivenIdeLauncherService {
|
|
|
101
106
|
};
|
|
102
107
|
}
|
|
103
108
|
}
|
|
104
|
-
checkAvailability(editorId) {
|
|
109
|
+
async checkAvailability(editorId) {
|
|
105
110
|
const entry = this.editors.get(editorId);
|
|
106
111
|
if (!entry)
|
|
107
|
-
return
|
|
112
|
+
return false;
|
|
108
113
|
const binary = resolvePlatformValue(entry.binary);
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
resolve(!err);
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
+
const result = await checkBinaryExists(binary);
|
|
115
|
+
return result.found;
|
|
114
116
|
}
|
|
115
117
|
};
|
|
116
118
|
JsonDrivenIdeLauncherService = __decorate([
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform process tree termination.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the npm `tree-kill` package for use by the presentation layer,
|
|
5
|
+
* which cannot resolve packages installed in packages/core/node_modules
|
|
6
|
+
* directly (pnpm workspace isolation).
|
|
7
|
+
*
|
|
8
|
+
* Uses taskkill /T /F on Windows, kill/ps/pgrep on Unix.
|
|
9
|
+
*/
|
|
10
|
+
import treeKill from 'tree-kill';
|
|
11
|
+
export { treeKill };
|
|
12
|
+
//# sourceMappingURL=tree-kill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-kill.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/process/tree-kill.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,QAAQ,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform process tree termination.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the npm `tree-kill` package for use by the presentation layer,
|
|
5
|
+
* which cannot resolve packages installed in packages/core/node_modules
|
|
6
|
+
* directly (pnpm workspace isolation).
|
|
7
|
+
*
|
|
8
|
+
* Uses taskkill /T /F on Windows, kill/ps/pgrep on Unix.
|
|
9
|
+
*/
|
|
10
|
+
import treeKill from 'tree-kill';
|
|
11
|
+
export { treeKill };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform binary existence check.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the npm `which` package to provide a single cross-platform API
|
|
5
|
+
* for checking if a binary exists in the system PATH. Works on Unix
|
|
6
|
+
* (which) and Windows (where.exe + PATHEXT resolution) without platform
|
|
7
|
+
* branching.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Check if a binary exists in the system PATH.
|
|
11
|
+
*
|
|
12
|
+
* Uses the npm `which` package which handles Windows PATHEXT resolution
|
|
13
|
+
* internally (.exe, .cmd, .bat extensions).
|
|
14
|
+
*
|
|
15
|
+
* Returns:
|
|
16
|
+
* - `{ found: true }` when the binary is on PATH
|
|
17
|
+
* - `{ found: false, notInPath: true }` when the binary is not on PATH
|
|
18
|
+
* - `{ found: false, error }` for genuine errors (e.g. permission denied)
|
|
19
|
+
*/
|
|
20
|
+
export declare const checkBinaryExists: (binary: string) => Promise<{
|
|
21
|
+
found: boolean;
|
|
22
|
+
notInPath?: boolean;
|
|
23
|
+
error?: Error;
|
|
24
|
+
}>;
|
|
25
|
+
//# sourceMappingURL=binary-exists.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binary-exists.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/tool-installer/binary-exists.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,MAAM,KACb,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAUhE,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform binary existence check.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the npm `which` package to provide a single cross-platform API
|
|
5
|
+
* for checking if a binary exists in the system PATH. Works on Unix
|
|
6
|
+
* (which) and Windows (where.exe + PATHEXT resolution) without platform
|
|
7
|
+
* branching.
|
|
8
|
+
*/
|
|
9
|
+
import which from 'which';
|
|
10
|
+
/**
|
|
11
|
+
* Check if a binary exists in the system PATH.
|
|
12
|
+
*
|
|
13
|
+
* Uses the npm `which` package which handles Windows PATHEXT resolution
|
|
14
|
+
* internally (.exe, .cmd, .bat extensions).
|
|
15
|
+
*
|
|
16
|
+
* Returns:
|
|
17
|
+
* - `{ found: true }` when the binary is on PATH
|
|
18
|
+
* - `{ found: false, notInPath: true }` when the binary is not on PATH
|
|
19
|
+
* - `{ found: false, error }` for genuine errors (e.g. permission denied)
|
|
20
|
+
*/
|
|
21
|
+
export const checkBinaryExists = async (binary) => {
|
|
22
|
+
try {
|
|
23
|
+
const result = await which(binary, { nothrow: true });
|
|
24
|
+
if (result !== null) {
|
|
25
|
+
return { found: true };
|
|
26
|
+
}
|
|
27
|
+
return { found: false, notInPath: true };
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
return { found: false, error: error instanceof Error ? error : new Error(String(error)) };
|
|
31
|
+
}
|
|
32
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-installer.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/tool-installer/tool-installer.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sEAAsE,CAAC;AAClH,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EAEnB,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"tool-installer.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/tool-installer/tool-installer.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sEAAsE,CAAC;AAClH,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EAEnB,MAAM,qCAAqC,CAAC;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;;OAEG;IACH,OAAO,CAAC,6BAA6B;CA4BtC"}
|
package/dist/packages/core/src/infrastructure/services/tool-installer/tool-installer.service.js
CHANGED
|
@@ -18,10 +18,11 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
18
18
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
19
19
|
};
|
|
20
20
|
import { injectable } from 'tsyringe';
|
|
21
|
-
import { exec,
|
|
21
|
+
import { exec, spawn } from 'node:child_process';
|
|
22
22
|
import { platform } from 'node:os';
|
|
23
23
|
import { createAvailableStatus, createMissingStatus, createErrorStatus, } from '../../../domain/value-objects/tool-installation-status.js';
|
|
24
24
|
import { TOOL_METADATA } from './tool-metadata.js';
|
|
25
|
+
import { checkBinaryExists } from './binary-exists.js';
|
|
25
26
|
/**
|
|
26
27
|
* Resolve binary name for the current platform.
|
|
27
28
|
* Supports both simple string binaries and per-platform maps.
|
|
@@ -31,30 +32,6 @@ function resolveBinary(metadata) {
|
|
|
31
32
|
return metadata.binary;
|
|
32
33
|
return metadata.binary[platform()] ?? Object.values(metadata.binary)[0];
|
|
33
34
|
}
|
|
34
|
-
/**
|
|
35
|
-
* Check if a binary exists in the system PATH using 'which' command.
|
|
36
|
-
*
|
|
37
|
-
* `which` exits with code 1 when the binary is simply not in PATH.
|
|
38
|
-
* Node's execFile wraps that as an Error, but it's a normal "not found"
|
|
39
|
-
* result. Only truly unexpected failures (ENOENT for `which` itself,
|
|
40
|
-
* EACCES, signals, etc.) are surfaced via the `error` field.
|
|
41
|
-
*/
|
|
42
|
-
const checkBinaryExists = (binary) => {
|
|
43
|
-
return new Promise((resolve) => {
|
|
44
|
-
execFile('which', [binary], (err) => {
|
|
45
|
-
if (!err)
|
|
46
|
-
return resolve({ found: true });
|
|
47
|
-
// execFile errors from a non-zero exit code have a numeric `code` property.
|
|
48
|
-
// That's the normal "binary not found in PATH" case.
|
|
49
|
-
const code = err.code;
|
|
50
|
-
if (code === undefined || typeof code === 'number') {
|
|
51
|
-
return resolve({ found: false, notInPath: true });
|
|
52
|
-
}
|
|
53
|
-
// Anything else (ENOENT for `which` itself, EACCES, etc.) is a real error.
|
|
54
|
-
resolve({ found: false, error: err });
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
};
|
|
58
35
|
/**
|
|
59
36
|
* Run a shell command and resolve true when it exits 0, false otherwise.
|
|
60
37
|
* Used as a fallback for GUI apps whose binary isn't in PATH (e.g. Warp, iTerm2).
|
|
@@ -130,8 +107,8 @@ let ToolInstallerServiceImpl = class ToolInstallerServiceImpl {
|
|
|
130
107
|
}
|
|
131
108
|
return new Promise((resolve) => {
|
|
132
109
|
let output = '';
|
|
133
|
-
const child = spawn(
|
|
134
|
-
shell:
|
|
110
|
+
const child = spawn(installCommand.command, [], {
|
|
111
|
+
shell: true,
|
|
135
112
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
136
113
|
env: {
|
|
137
114
|
...process.env,
|
|
@@ -5,13 +5,14 @@
|
|
|
5
5
|
"tags": ["terminal"],
|
|
6
6
|
"author": "Alacritty Contributors",
|
|
7
7
|
"website": "https://alacritty.org",
|
|
8
|
-
"platforms": ["linux", "darwin"],
|
|
8
|
+
"platforms": ["linux", "darwin", "win32"],
|
|
9
9
|
"iconUrl": "https://cdn.simpleicons.org/alacritty",
|
|
10
10
|
"binary": "alacritty",
|
|
11
11
|
"packageManager": "brew",
|
|
12
12
|
"commands": {
|
|
13
13
|
"darwin": "brew install --cask alacritty",
|
|
14
|
-
"linux": "sudo apt-get update && sudo apt-get install -y alacritty"
|
|
14
|
+
"linux": "sudo apt-get update && sudo apt-get install -y alacritty",
|
|
15
|
+
"win32": "winget install --id Alacritty.Alacritty -e --source winget"
|
|
15
16
|
},
|
|
16
17
|
"timeout": 300000,
|
|
17
18
|
"documentationUrl": "https://alacritty.org/",
|
package/dist/packages/core/src/infrastructure/services/tool-installer/tools/claude-code.json
CHANGED
|
@@ -5,13 +5,14 @@
|
|
|
5
5
|
"tags": ["cli-agent"],
|
|
6
6
|
"author": "Anthropic",
|
|
7
7
|
"website": "https://claude.ai/code",
|
|
8
|
-
"platforms": ["linux", "darwin"],
|
|
8
|
+
"platforms": ["linux", "darwin", "win32"],
|
|
9
9
|
"iconUrl": "https://cdn.simpleicons.org/claude",
|
|
10
10
|
"binary": "claude",
|
|
11
11
|
"packageManager": "curl",
|
|
12
12
|
"commands": {
|
|
13
13
|
"linux": "curl -fsSL https://claude.ai/install.sh | bash",
|
|
14
|
-
"darwin": "curl -fsSL https://claude.ai/install.sh | bash"
|
|
14
|
+
"darwin": "curl -fsSL https://claude.ai/install.sh | bash",
|
|
15
|
+
"win32": "npm install -g @anthropic-ai/claude-code"
|
|
15
16
|
},
|
|
16
17
|
"timeout": 300000,
|
|
17
18
|
"documentationUrl": "https://code.claude.com/docs/en/overview",
|
|
@@ -5,13 +5,14 @@
|
|
|
5
5
|
"tags": ["cli-agent"],
|
|
6
6
|
"author": "Anysphere",
|
|
7
7
|
"website": "https://cursor.com",
|
|
8
|
-
"platforms": ["linux", "darwin"],
|
|
8
|
+
"platforms": ["linux", "darwin", "win32"],
|
|
9
9
|
"iconUrl": "https://cdn.simpleicons.org/cursor",
|
|
10
10
|
"binary": "cursor-agent",
|
|
11
11
|
"packageManager": "curl",
|
|
12
12
|
"commands": {
|
|
13
13
|
"linux": "curl https://cursor.com/install -fsS | bash",
|
|
14
|
-
"darwin": "curl https://cursor.com/install -fsS | bash"
|
|
14
|
+
"darwin": "curl https://cursor.com/install -fsS | bash",
|
|
15
|
+
"win32": "powershell -Command \"irm 'https://cursor.com/install?win32=true' | iex\""
|
|
15
16
|
},
|
|
16
17
|
"timeout": 300000,
|
|
17
18
|
"documentationUrl": "https://www.codecademy.com/article/getting-started-with-cursor-cli",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"packageManager": "manual",
|
|
12
12
|
"commands": {
|
|
13
13
|
"linux": "Download from https://cursor.com/download and install the AppImage manually",
|
|
14
|
-
"darwin": "Download from https://cursor.com/download or use: brew install --cask cursor"
|
|
14
|
+
"darwin": "Download from https://cursor.com/download or use: brew install --cask cursor",
|
|
15
|
+
"win32": "winget install --id Anysphere.Cursor -e --source winget"
|
|
15
16
|
},
|
|
16
17
|
"timeout": 600000,
|
|
17
18
|
"documentationUrl": "https://cursor.com/download",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"packageManager": "apt",
|
|
12
12
|
"commands": {
|
|
13
13
|
"linux": "(type -p wget >/dev/null || (sudo apt update && sudo apt-get install wget -y)) && sudo mkdir -p -m 755 /etc/apt/keyrings && out=$(mktemp) && wget -nv -O$out https://cli.github.com/packages/githubcli-archive-keyring.gpg && cat $out | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null && sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg && echo \"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main\" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null && sudo apt update && sudo apt install gh -y",
|
|
14
|
-
"darwin": "brew install gh"
|
|
14
|
+
"darwin": "brew install gh",
|
|
15
|
+
"win32": "winget install --id GitHub.cli -e --source winget"
|
|
15
16
|
},
|
|
16
17
|
"timeout": 300000,
|
|
17
18
|
"documentationUrl": "https://cli.github.com/manual/",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"packageManager": "apt",
|
|
12
12
|
"commands": {
|
|
13
13
|
"linux": "sudo apt-get update && sudo apt-get install -y git",
|
|
14
|
-
"darwin": "xcode-select --install"
|
|
14
|
+
"darwin": "xcode-select --install",
|
|
15
|
+
"win32": "winget install --id Git.Git -e --source winget"
|
|
15
16
|
},
|
|
16
17
|
"timeout": 300000,
|
|
17
18
|
"documentationUrl": "https://git-scm.com/doc",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"packageManager": "apt",
|
|
12
12
|
"commands": {
|
|
13
13
|
"linux": "curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | sudo gpg --yes --dearmor -o /usr/share/keyrings/packages.microsoft.gpg && echo \"deb [arch=amd64 signed-by=/usr/share/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main\" | sudo tee /etc/apt/sources.list.d/vscode.list > /dev/null && sudo apt-get update && sudo apt-get install -y code",
|
|
14
|
-
"darwin": "brew install visual-studio-code"
|
|
14
|
+
"darwin": "brew install visual-studio-code",
|
|
15
|
+
"win32": "winget install --id Microsoft.VisualStudioCode -e --source winget"
|
|
15
16
|
},
|
|
16
17
|
"timeout": 300000,
|
|
17
18
|
"documentationUrl": "https://code.visualstudio.com/docs/setup/linux",
|
|
@@ -5,12 +5,13 @@
|
|
|
5
5
|
"tags": ["terminal"],
|
|
6
6
|
"author": "Warp",
|
|
7
7
|
"website": "https://www.warp.dev",
|
|
8
|
-
"platforms": ["darwin"],
|
|
8
|
+
"platforms": ["darwin", "win32"],
|
|
9
9
|
"iconUrl": "https://cdn.simpleicons.org/warp",
|
|
10
10
|
"binary": "warp",
|
|
11
11
|
"packageManager": "brew",
|
|
12
12
|
"commands": {
|
|
13
|
-
"darwin": "brew install --cask warp"
|
|
13
|
+
"darwin": "brew install --cask warp",
|
|
14
|
+
"win32": "winget install --id Warp.Warp -e --source winget"
|
|
14
15
|
},
|
|
15
16
|
"timeout": 300000,
|
|
16
17
|
"documentationUrl": "https://docs.warp.dev/",
|
|
@@ -5,13 +5,14 @@
|
|
|
5
5
|
"tags": ["ide"],
|
|
6
6
|
"author": "Codeium",
|
|
7
7
|
"website": "https://codeium.com/windsurf",
|
|
8
|
-
"platforms": ["linux", "darwin"],
|
|
8
|
+
"platforms": ["linux", "darwin", "win32"],
|
|
9
9
|
"iconUrl": "https://cdn.simpleicons.org/windsurf",
|
|
10
10
|
"binary": "windsurf",
|
|
11
11
|
"packageManager": "apt",
|
|
12
12
|
"commands": {
|
|
13
13
|
"linux": "curl -fsSL \"https://windsurf-stable.codeiumdata.com/wVxQEIWkwPUEAGf3/windsurf.gpg\" | sudo gpg --yes --dearmor -o /usr/share/keyrings/windsurf-stable-archive-keyring.gpg && echo \"deb [signed-by=/usr/share/keyrings/windsurf-stable-archive-keyring.gpg arch=amd64] https://windsurf-stable.codeiumdata.com/wVxQEIWkwPUEAGf3/apt stable main\" | sudo tee /etc/apt/sources.list.d/windsurf.list > /dev/null && sudo apt-get update && sudo apt-get install -y windsurf",
|
|
14
|
-
"darwin": "brew install --cask windsurf"
|
|
14
|
+
"darwin": "brew install --cask windsurf",
|
|
15
|
+
"win32": "winget install --id Codeium.Windsurf -e --source winget"
|
|
15
16
|
},
|
|
16
17
|
"timeout": 300000,
|
|
17
18
|
"documentationUrl": "https://docs.windsurf.com/windsurf/getting-started",
|
|
@@ -5,13 +5,14 @@
|
|
|
5
5
|
"tags": ["ide"],
|
|
6
6
|
"author": "Zed Industries",
|
|
7
7
|
"website": "https://zed.dev",
|
|
8
|
-
"platforms": ["linux", "darwin"],
|
|
8
|
+
"platforms": ["linux", "darwin", "win32"],
|
|
9
9
|
"iconUrl": "https://cdn.simpleicons.org/zedindustries",
|
|
10
10
|
"binary": "zed",
|
|
11
11
|
"packageManager": "curl",
|
|
12
12
|
"commands": {
|
|
13
13
|
"linux": "curl -f https://zed.dev/install.sh | sh",
|
|
14
|
-
"darwin": "curl -f https://zed.dev/install.sh | sh"
|
|
14
|
+
"darwin": "curl -f https://zed.dev/install.sh | sh",
|
|
15
|
+
"win32": "winget install --id ZedIndustries.Zed -e --source winget"
|
|
15
16
|
},
|
|
16
17
|
"timeout": 300000,
|
|
17
18
|
"documentationUrl": "https://zed.dev/docs/installation",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-daemon.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/daemon/start-daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAoBH,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"start-daemon.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/daemon/start-daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAoBH,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgG9E"}
|
|
@@ -67,6 +67,7 @@ export async function startDaemon(opts = {}) {
|
|
|
67
67
|
const child = spawn(process.execPath, [...process.execArgv, process.argv[1], '_serve', '--port', String(port)], {
|
|
68
68
|
detached: true,
|
|
69
69
|
stdio: ['ignore', logFd, logFd],
|
|
70
|
+
windowsHide: true,
|
|
70
71
|
});
|
|
71
72
|
// Wait briefly for the child to either settle or crash.
|
|
72
73
|
const exitCode = await Promise.race([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stop-daemon.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/daemon/stop-daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;
|
|
1
|
+
{"version":3,"file":"stop-daemon.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/daemon/stop-daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iEAAiE,CAAC;AA0BtG;;;GAGG;AACH,wBAAsB,UAAU,CAAC,aAAa,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAyC7E"}
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
*
|
|
19
19
|
* @param daemonService - IDaemonService instance (injected by caller for testability, NFR-4)
|
|
20
20
|
*/
|
|
21
|
+
import { treeKill } from '../../../../../packages/core/src/infrastructure/services/process/tree-kill.js';
|
|
21
22
|
import { messages } from '../../ui/index.js';
|
|
22
23
|
const POLL_INTERVAL_MS = 200;
|
|
23
24
|
const MAX_WAIT_MS = 5000;
|
|
@@ -54,15 +55,15 @@ export async function stopDaemon(daemonService) {
|
|
|
54
55
|
}
|
|
55
56
|
try {
|
|
56
57
|
messages.info(`Stopping Shep daemon (PID ${pid})...`);
|
|
57
|
-
// Send SIGTERM — request graceful shutdown
|
|
58
|
-
|
|
58
|
+
// Send SIGTERM to process tree — request graceful shutdown
|
|
59
|
+
treeKill(pid, 'SIGTERM');
|
|
59
60
|
// Poll for up to 5s waiting for the process to exit
|
|
60
61
|
const died = await pollUntilDead(daemonService, pid, MAX_WAIT_MS, POLL_INTERVAL_MS);
|
|
61
62
|
if (!died) {
|
|
62
|
-
// Graceful shutdown timed out — force kill
|
|
63
|
+
// Graceful shutdown timed out — force kill process tree
|
|
63
64
|
messages.info('Daemon did not stop gracefully, sending SIGKILL...');
|
|
64
65
|
try {
|
|
65
|
-
|
|
66
|
+
treeKill(pid, 'SIGKILL');
|
|
66
67
|
}
|
|
67
68
|
catch {
|
|
68
69
|
// Process may have exited between the check and the kill — ignore
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade.command.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/cli/commands/upgrade.command.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,IAAI,YAAY,EAAqB,MAAM,oBAAoB,CAAC;AAQ9E,KAAK,OAAO,GAAG,OAAO,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"upgrade.command.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/cli/commands/upgrade.command.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,IAAI,YAAY,EAAqB,MAAM,oBAAoB,CAAC;AAQ9E,KAAK,OAAO,GAAG,OAAO,YAAY,CAAC;AA8EnC;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,OAAsB,GAAG,OAAO,CA+D7E"}
|
|
@@ -13,6 +13,8 @@ import { messages } from '../ui/index.js';
|
|
|
13
13
|
import { stopDaemon } from './daemon/stop-daemon.js';
|
|
14
14
|
import { startDaemon } from './daemon/start-daemon.js';
|
|
15
15
|
const VERSION_CHECK_TIMEOUT_MS = 10_000;
|
|
16
|
+
/** On Windows, npm is a .cmd batch file — spawn() needs shell: true to resolve it. */
|
|
17
|
+
const IS_WINDOWS = process.platform === 'win32';
|
|
16
18
|
/**
|
|
17
19
|
* Get the latest published version of @shepai/cli from npm registry.
|
|
18
20
|
* Returns null if the check fails (fail-open).
|
|
@@ -23,6 +25,7 @@ function getLatestVersion(spawnFn) {
|
|
|
23
25
|
let settled = false;
|
|
24
26
|
const child = spawnFn('npm', ['view', '@shepai/cli', 'version'], {
|
|
25
27
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
28
|
+
...(IS_WINDOWS && { shell: true }),
|
|
26
29
|
});
|
|
27
30
|
const timeout = setTimeout(() => {
|
|
28
31
|
if (!settled) {
|
|
@@ -65,6 +68,7 @@ function runNpmInstall(spawnFn) {
|
|
|
65
68
|
return new Promise((resolve, reject) => {
|
|
66
69
|
const child = spawnFn('npm', ['i', '-g', '@shepai/cli@latest'], {
|
|
67
70
|
stdio: 'inherit',
|
|
71
|
+
...(IS_WINDOWS && { shell: true }),
|
|
68
72
|
});
|
|
69
73
|
child.on('close', (code) => {
|
|
70
74
|
resolve(code ?? 1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy-repository.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/deploy-repository.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"deploy-repository.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/deploy-repository.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAIvE,wBAAsB,gBAAgB,CACpC,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,eAAe,CAAA;CAAE,CAAC,CAyBxE"}
|