@shepai/cli 1.36.0 → 1.37.1
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/ide-launcher-service.interface.d.ts +64 -0
- package/dist/packages/core/src/application/ports/output/services/ide-launcher-service.interface.d.ts.map +1 -0
- package/dist/packages/core/src/application/ports/output/services/ide-launcher-service.interface.js +7 -0
- package/dist/packages/core/src/application/ports/output/services/index.d.ts +1 -0
- package/dist/packages/core/src/application/ports/output/services/index.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/ide/launch-ide.use-case.d.ts +20 -0
- package/dist/packages/core/src/application/use-cases/ide/launch-ide.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/ide/launch-ide.use-case.js +54 -0
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +7 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js +1 -3
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/implement.node.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/implement.node.js +2 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.js +4 -1
- 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 +2 -1
- package/dist/packages/core/src/infrastructure/services/ide-launchers/json-driven-ide-launcher.service.d.ts +23 -0
- package/dist/packages/core/src/infrastructure/services/ide-launchers/json-driven-ide-launcher.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/ide-launchers/json-driven-ide-launcher.service.js +114 -0
- package/dist/packages/core/src/infrastructure/services/tool-installer/tool-metadata.d.ts +20 -4
- package/dist/packages/core/src/infrastructure/services/tool-installer/tool-metadata.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/tool-installer/tool-metadata.js +9 -1
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/antigravity.json +5 -2
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/claude-code.json +8 -2
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/cursor-cli.json +8 -2
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/cursor.json +2 -2
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/vscode.json +2 -2
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/windsurf.json +2 -2
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/zed.json +2 -2
- package/dist/src/presentation/cli/commands/feat/show.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/feat/show.command.js +21 -2
- package/dist/src/presentation/cli/commands/ide-open.command.d.ts +3 -1
- package/dist/src/presentation/cli/commands/ide-open.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/ide-open.command.js +27 -28
- package/dist/src/presentation/cli/commands/install.command.js +3 -3
- package/dist/src/presentation/cli/commands/settings/ide.command.d.ts +1 -0
- package/dist/src/presentation/cli/commands/settings/ide.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/settings/ide.command.js +10 -13
- package/dist/src/presentation/tui/prompts/ide-select.prompt.d.ts +9 -25
- package/dist/src/presentation/tui/prompts/ide-select.prompt.d.ts.map +1 -1
- package/dist/src/presentation/tui/prompts/ide-select.prompt.js +9 -29
- package/dist/src/presentation/web/app/api/ide/open/route.d.ts.map +1 -1
- package/dist/src/presentation/web/app/api/ide/open/route.js +3 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/cache/.previewinfo +1 -1
- package/web/.next/cache/.rscinfo +1 -1
- package/web/.next/cache/.tsbuildinfo +1 -1
- package/web/.next/cache/config.json +3 -3
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +1 -1
- package/web/.next/required-server-files.json +1 -1
- package/web/.next/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/api/ide/open/route.js +1 -2
- package/web/.next/server/app/api/ide/open/route.js.nft.json +1 -1
- package/web/.next/server/app/api/shell/open/route.js +1 -1
- package/web/.next/server/app/api/shell/open/route.js.nft.json +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__04ae3a77._.js +3 -0
- package/web/.next/server/chunks/[root-of-the-server]__04ae3a77._.js.map +1 -0
- package/web/.next/server/chunks/[root-of-the-server]__f32c280c._.js +3 -0
- package/web/.next/server/chunks/[root-of-the-server]__f32c280c._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f12b60be._.js +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 +1 -1
- package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/ide/open/route.js +1 -2
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/ide/open/route.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/shell/open/route.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/shell/open/route.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/[root-of-the-server]__04ae3a77._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/[root-of-the-server]__f32c280c._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__f12b60be._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/app/api/ide/open/route.ts +4 -2
- package/web/.next/standalone/src/presentation/web/server.js +1 -1
- package/web/.next/trace +1 -1
- package/web/.next/trace-build +1 -1
- package/dist/packages/core/src/infrastructure/services/ide-launchers/antigravity.launcher.d.ts +0 -10
- package/dist/packages/core/src/infrastructure/services/ide-launchers/antigravity.launcher.d.ts.map +0 -1
- package/dist/packages/core/src/infrastructure/services/ide-launchers/antigravity.launcher.js +0 -21
- package/dist/packages/core/src/infrastructure/services/ide-launchers/cursor.launcher.d.ts +0 -10
- package/dist/packages/core/src/infrastructure/services/ide-launchers/cursor.launcher.d.ts.map +0 -1
- package/dist/packages/core/src/infrastructure/services/ide-launchers/cursor.launcher.js +0 -21
- package/dist/packages/core/src/infrastructure/services/ide-launchers/ide-launcher.interface.d.ts +0 -31
- package/dist/packages/core/src/infrastructure/services/ide-launchers/ide-launcher.interface.d.ts.map +0 -1
- package/dist/packages/core/src/infrastructure/services/ide-launchers/ide-launcher.interface.js +0 -8
- package/dist/packages/core/src/infrastructure/services/ide-launchers/ide-launcher.registry.d.ts +0 -9
- package/dist/packages/core/src/infrastructure/services/ide-launchers/ide-launcher.registry.d.ts.map +0 -1
- package/dist/packages/core/src/infrastructure/services/ide-launchers/ide-launcher.registry.js +0 -24
- package/dist/packages/core/src/infrastructure/services/ide-launchers/launch-ide.d.ts +0 -30
- package/dist/packages/core/src/infrastructure/services/ide-launchers/launch-ide.d.ts.map +0 -1
- package/dist/packages/core/src/infrastructure/services/ide-launchers/launch-ide.js +0 -43
- package/dist/packages/core/src/infrastructure/services/ide-launchers/vscode.launcher.d.ts +0 -10
- package/dist/packages/core/src/infrastructure/services/ide-launchers/vscode.launcher.d.ts.map +0 -1
- package/dist/packages/core/src/infrastructure/services/ide-launchers/vscode.launcher.js +0 -21
- package/dist/packages/core/src/infrastructure/services/ide-launchers/windsurf.launcher.d.ts +0 -10
- package/dist/packages/core/src/infrastructure/services/ide-launchers/windsurf.launcher.d.ts.map +0 -1
- package/dist/packages/core/src/infrastructure/services/ide-launchers/windsurf.launcher.js +0 -21
- package/dist/packages/core/src/infrastructure/services/ide-launchers/zed.launcher.d.ts +0 -10
- package/dist/packages/core/src/infrastructure/services/ide-launchers/zed.launcher.d.ts.map +0 -1
- package/dist/packages/core/src/infrastructure/services/ide-launchers/zed.launcher.js +0 -21
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_12059e3e.js +0 -3
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_12059e3e.js.map +0 -1
- package/web/.next/server/chunks/[root-of-the-server]__0af905fe._.js +0 -3
- package/web/.next/server/chunks/[root-of-the-server]__0af905fe._.js.map +0 -1
- package/web/.next/server/chunks/[root-of-the-server]__72567d8d._.js +0 -3
- package/web/.next/server/chunks/[root-of-the-server]__72567d8d._.js.map +0 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_12059e3e.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/[root-of-the-server]__0af905fe._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/[root-of-the-server]__72567d8d._.js +0 -3
- /package/web/.next/static/{TkrzrZBiArd9QW2xebsyW → UemLwbVtqCGOm4FHNOp05}/_buildManifest.js +0 -0
- /package/web/.next/static/{TkrzrZBiArd9QW2xebsyW → UemLwbVtqCGOm4FHNOp05}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{TkrzrZBiArd9QW2xebsyW → UemLwbVtqCGOm4FHNOp05}/_ssgManifest.js +0 -0
package/dist/packages/core/src/application/ports/output/services/ide-launcher-service.interface.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IDE Launcher Service Interface
|
|
3
|
+
*
|
|
4
|
+
* Output port for launching IDE editors in a target directory.
|
|
5
|
+
* Implementations resolve editor commands from metadata and spawn detached processes.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Input for the LaunchIdeUseCase.
|
|
9
|
+
*/
|
|
10
|
+
export interface LaunchIdeInput {
|
|
11
|
+
/** Which editor to launch (e.g., "vscode", "cursor"). */
|
|
12
|
+
editorId: string;
|
|
13
|
+
/** Absolute path to the repository root. */
|
|
14
|
+
repositoryPath: string;
|
|
15
|
+
/** Git branch name. When omitted, repositoryPath is used directly. */
|
|
16
|
+
branch?: string;
|
|
17
|
+
/** Whether to verify binary availability before launching. Default: false. */
|
|
18
|
+
checkAvailability?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Successful IDE launch result.
|
|
22
|
+
*/
|
|
23
|
+
export interface LaunchIdeSuccess {
|
|
24
|
+
ok: true;
|
|
25
|
+
/** Display name of the editor that was launched. */
|
|
26
|
+
editorName: string;
|
|
27
|
+
/** Absolute path that was opened in the editor. */
|
|
28
|
+
worktreePath: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Failed IDE launch result.
|
|
32
|
+
*/
|
|
33
|
+
export interface LaunchIdeFailed {
|
|
34
|
+
ok: false;
|
|
35
|
+
/** Error classification for consumer error handling. */
|
|
36
|
+
code: 'unknown_editor' | 'editor_unavailable' | 'launch_failed';
|
|
37
|
+
/** Human-readable error description. */
|
|
38
|
+
message: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Discriminated union result for IDE launch operations.
|
|
42
|
+
*/
|
|
43
|
+
export type LaunchIdeResult = LaunchIdeSuccess | LaunchIdeFailed;
|
|
44
|
+
/**
|
|
45
|
+
* Service interface for launching IDE editors.
|
|
46
|
+
*/
|
|
47
|
+
export interface IIdeLauncherService {
|
|
48
|
+
/**
|
|
49
|
+
* Launch an IDE editor in the specified directory.
|
|
50
|
+
*
|
|
51
|
+
* @param editorId - Editor identifier (e.g., "vscode", "cursor")
|
|
52
|
+
* @param directoryPath - Absolute path to open in the editor
|
|
53
|
+
* @returns Launch result indicating success or failure with error details
|
|
54
|
+
*/
|
|
55
|
+
launch(editorId: string, directoryPath: string): Promise<LaunchIdeResult>;
|
|
56
|
+
/**
|
|
57
|
+
* Check whether an editor's binary is available on the system PATH.
|
|
58
|
+
*
|
|
59
|
+
* @param editorId - Editor identifier (e.g., "vscode", "cursor")
|
|
60
|
+
* @returns True if the editor binary is found and executable
|
|
61
|
+
*/
|
|
62
|
+
checkAvailability(editorId: string): Promise<boolean>;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=ide-launcher-service.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ide-launcher-service.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/ide-launcher-service.interface.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,cAAc,EAAE,MAAM,CAAC;IACvB,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,IAAI,CAAC;IACT,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,KAAK,CAAC;IACV,wDAAwD;IACxD,IAAI,EAAE,gBAAgB,GAAG,oBAAoB,GAAG,eAAe,CAAC;IAChE,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,gBAAgB,GAAG,eAAe,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;;OAMG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAE1E;;;;;OAKG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACvD"}
|
|
@@ -14,4 +14,5 @@ export type { IToolInstallerService } from './tool-installer.service.js';
|
|
|
14
14
|
export type { INotificationService } from './notification-service.interface.js';
|
|
15
15
|
export type { IGitPrService, CiStatus, CiStatusResult, DiffSummary, MergeStrategy, PrCreateResult, } from './git-pr-service.interface.js';
|
|
16
16
|
export { GitPrError, GitPrErrorCode } from './git-pr-service.interface.js';
|
|
17
|
+
export type { IIdeLauncherService, LaunchIdeInput, LaunchIdeResult, LaunchIdeSuccess, LaunchIdeFailed, } from './ide-launcher-service.interface.js';
|
|
17
18
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AAClG,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,uCAAuC,CAAC;AAC/C,YAAY,EACV,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,iCAAiC,CAAC;AACzC,YAAY,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,YAAY,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACtF,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACnF,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,YAAY,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAChF,YAAY,EACV,aAAa,EACb,QAAQ,EACR,cAAc,EACd,WAAW,EACX,aAAa,EACb,cAAc,GACf,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AAClG,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,uCAAuC,CAAC;AAC/C,YAAY,EACV,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,iCAAiC,CAAC;AACzC,YAAY,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,YAAY,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACtF,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACnF,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,YAAY,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAChF,YAAY,EACV,aAAa,EACb,QAAQ,EACR,cAAc,EACd,WAAW,EACX,aAAa,EACb,cAAc,GACf,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC3E,YAAY,EACV,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,GAChB,MAAM,qCAAqC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LaunchIdeUseCase
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates IDE launching: computes the target directory path (worktree when
|
|
5
|
+
* a branch is specified), optionally checks editor availability, and delegates
|
|
6
|
+
* to IIdeLauncherService for the actual spawn.
|
|
7
|
+
*/
|
|
8
|
+
import type { IIdeLauncherService, LaunchIdeInput, LaunchIdeResult } from '../../ports/output/services/ide-launcher-service.interface.js';
|
|
9
|
+
export declare class LaunchIdeUseCase {
|
|
10
|
+
private readonly ideLauncherService;
|
|
11
|
+
constructor(ideLauncherService: IIdeLauncherService);
|
|
12
|
+
/**
|
|
13
|
+
* Launch an IDE editor for the given repository/branch.
|
|
14
|
+
*
|
|
15
|
+
* @param input - Editor ID, repository path, optional branch and availability check flag
|
|
16
|
+
* @returns Launch result indicating success or failure with error details
|
|
17
|
+
*/
|
|
18
|
+
execute(input: LaunchIdeInput): Promise<LaunchIdeResult>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=launch-ide.use-case.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch-ide.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/ide/launch-ide.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EACd,eAAe,EAChB,MAAM,+DAA+D,CAAC;AAGvE,qBACa,gBAAgB;IAGzB,OAAO,CAAC,QAAQ,CAAC,kBAAkB;gBAAlB,kBAAkB,EAAE,mBAAmB;IAG1D;;;;;OAKG;IACG,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;CAkB/D"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LaunchIdeUseCase
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates IDE launching: computes the target directory path (worktree when
|
|
5
|
+
* a branch is specified), optionally checks editor availability, and delegates
|
|
6
|
+
* to IIdeLauncherService for the actual spawn.
|
|
7
|
+
*/
|
|
8
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
9
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
10
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
11
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
12
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
13
|
+
};
|
|
14
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
15
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
16
|
+
};
|
|
17
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
18
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
19
|
+
};
|
|
20
|
+
import { injectable, inject } from 'tsyringe';
|
|
21
|
+
import { computeWorktreePath } from '../../../infrastructure/services/ide-launchers/compute-worktree-path.js';
|
|
22
|
+
let LaunchIdeUseCase = class LaunchIdeUseCase {
|
|
23
|
+
ideLauncherService;
|
|
24
|
+
constructor(ideLauncherService) {
|
|
25
|
+
this.ideLauncherService = ideLauncherService;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Launch an IDE editor for the given repository/branch.
|
|
29
|
+
*
|
|
30
|
+
* @param input - Editor ID, repository path, optional branch and availability check flag
|
|
31
|
+
* @returns Launch result indicating success or failure with error details
|
|
32
|
+
*/
|
|
33
|
+
async execute(input) {
|
|
34
|
+
const { editorId, repositoryPath, branch, checkAvailability } = input;
|
|
35
|
+
const directoryPath = branch ? computeWorktreePath(repositoryPath, branch) : repositoryPath;
|
|
36
|
+
if (checkAvailability) {
|
|
37
|
+
const available = await this.ideLauncherService.checkAvailability(editorId);
|
|
38
|
+
if (!available) {
|
|
39
|
+
return {
|
|
40
|
+
ok: false,
|
|
41
|
+
code: 'editor_unavailable',
|
|
42
|
+
message: `Editor '${editorId}' is not available on the system PATH`,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return this.ideLauncherService.launch(editorId, directoryPath);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
LaunchIdeUseCase = __decorate([
|
|
50
|
+
injectable(),
|
|
51
|
+
__param(0, inject('IIdeLauncherService')),
|
|
52
|
+
__metadata("design:paramtypes", [Object])
|
|
53
|
+
], LaunchIdeUseCase);
|
|
54
|
+
export { LaunchIdeUseCase };
|
|
@@ -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;AA0FrC;;;;;;GAMG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,OAAO,SAAS,CAAC,CAuLrE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -22,6 +22,7 @@ import { WebServerService } from '../services/web-server.service.js';
|
|
|
22
22
|
import { WorktreeService } from '../services/git/worktree.service.js';
|
|
23
23
|
import { ToolInstallerServiceImpl } from '../services/tool-installer/tool-installer.service.js';
|
|
24
24
|
import { GitPrService } from '../services/git/git-pr.service.js';
|
|
25
|
+
import { JsonDrivenIdeLauncherService } from '../services/ide-launchers/json-driven-ide-launcher.service.js';
|
|
25
26
|
import { AgentExecutorFactory } from '../services/agents/common/agent-executor-factory.service.js';
|
|
26
27
|
import { AgentExecutorProvider } from '../services/agents/common/agent-executor-provider.service.js';
|
|
27
28
|
import { StructuredAgentCallerService } from '../services/agents/common/structured-agent-caller.service.js';
|
|
@@ -59,6 +60,7 @@ import { DeleteFeatureUseCase } from '../../application/use-cases/features/delet
|
|
|
59
60
|
import { ResumeFeatureUseCase } from '../../application/use-cases/features/resume-feature.use-case.js';
|
|
60
61
|
import { ValidateToolAvailabilityUseCase } from '../../application/use-cases/tools/validate-tool-availability.use-case.js';
|
|
61
62
|
import { InstallToolUseCase } from '../../application/use-cases/tools/install-tool.use-case.js';
|
|
63
|
+
import { LaunchIdeUseCase } from '../../application/use-cases/ide/launch-ide.use-case.js';
|
|
62
64
|
// Database connection
|
|
63
65
|
import { getSQLiteConnection } from '../persistence/sqlite/connection.js';
|
|
64
66
|
import { runSQLiteMigrations } from '../persistence/sqlite/migrations.js';
|
|
@@ -105,6 +107,7 @@ export async function initializeContainer() {
|
|
|
105
107
|
container.registerSingleton('IWorktreeService', WorktreeService);
|
|
106
108
|
container.registerSingleton('IToolInstallerService', ToolInstallerServiceImpl);
|
|
107
109
|
container.registerSingleton('IGitPrService', GitPrService);
|
|
110
|
+
container.registerSingleton('IIdeLauncherService', JsonDrivenIdeLauncherService);
|
|
108
111
|
// Register agent infrastructure
|
|
109
112
|
container.register('IAgentRunRepository', {
|
|
110
113
|
useFactory: (c) => {
|
|
@@ -206,6 +209,7 @@ export async function initializeContainer() {
|
|
|
206
209
|
container.registerSingleton(ResumeFeatureUseCase);
|
|
207
210
|
container.registerSingleton(ValidateToolAvailabilityUseCase);
|
|
208
211
|
container.registerSingleton(InstallToolUseCase);
|
|
212
|
+
container.registerSingleton(LaunchIdeUseCase);
|
|
209
213
|
// String-token aliases for web routes (Turbopack can't resolve .js→.ts
|
|
210
214
|
// imports inside @shepai/core, so routes use string tokens instead of class refs)
|
|
211
215
|
container.register('CreateFeatureUseCase', {
|
|
@@ -217,6 +221,9 @@ export async function initializeContainer() {
|
|
|
217
221
|
container.register('DeleteFeatureUseCase', {
|
|
218
222
|
useFactory: (c) => c.resolve(DeleteFeatureUseCase),
|
|
219
223
|
});
|
|
224
|
+
container.register('LaunchIdeUseCase', {
|
|
225
|
+
useFactory: (c) => c.resolve(LaunchIdeUseCase),
|
|
226
|
+
});
|
|
220
227
|
_initialized = true;
|
|
221
228
|
return container;
|
|
222
229
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-agent-worker.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AAEH,OAAO,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"feature-agent-worker.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AAEH,OAAO,kBAAkB,CAAC;AAqB1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CA6C1D;AAgCD;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA0J/D"}
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js
CHANGED
|
@@ -19,7 +19,7 @@ import { AgentRunStatus } from '../../../../domain/generated/output.js';
|
|
|
19
19
|
import { initializeSettings } from '../../../services/settings.service.js';
|
|
20
20
|
import { InitializeSettingsUseCase } from '../../../../application/use-cases/settings/initialize-settings.use-case.js';
|
|
21
21
|
import { setHeartbeatContext } from './heartbeat.js';
|
|
22
|
-
import { setPhaseTimingContext
|
|
22
|
+
import { setPhaseTimingContext } from './phase-timing-context.js';
|
|
23
23
|
import { setLifecycleContext } from './lifecycle-context.js';
|
|
24
24
|
import { generatePrYaml } from './nodes/pr-yaml-generator.js';
|
|
25
25
|
/**
|
|
@@ -193,8 +193,6 @@ export async function runWorker(args) {
|
|
|
193
193
|
// Check if graph was interrupted (human-in-the-loop approval needed)
|
|
194
194
|
const interruptPayload = result.__interrupt__;
|
|
195
195
|
if (interruptPayload && interruptPayload.length > 0) {
|
|
196
|
-
// Record approval wait start on the last phase timing
|
|
197
|
-
await recordApprovalWaitStart(getLastTimingId());
|
|
198
196
|
const now = new Date();
|
|
199
197
|
await runRepository.updateStatus(args.runId, AgentRunStatus.waitingApproval, {
|
|
200
198
|
updatedAt: now,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"implement.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/implement.node.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AACpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"implement.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/implement.node.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AACpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAqErD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,cAAc,IAG5C,OAAO,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAgL7E"}
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/implement.node.js
CHANGED
|
@@ -12,7 +12,7 @@ import { join } from 'node:path';
|
|
|
12
12
|
import { interrupt, isGraphBubbleUp } from '@langchain/langgraph';
|
|
13
13
|
import { createNodeLogger, readSpecFile, buildExecutorOptions, shouldInterrupt, safeYamlLoad, retryExecute, getCompletedPhases, markPhaseComplete, } from './node-helpers.js';
|
|
14
14
|
import { reportNodeStart } from '../heartbeat.js';
|
|
15
|
-
import { recordPhaseStart, recordPhaseEnd } from '../phase-timing-context.js';
|
|
15
|
+
import { recordPhaseStart, recordPhaseEnd, recordApprovalWaitStart, } from '../phase-timing-context.js';
|
|
16
16
|
import { updateNodeLifecycle } from '../lifecycle-context.js';
|
|
17
17
|
import { buildImplementPhasePrompt, } from './prompts/implement.prompt.js';
|
|
18
18
|
/**
|
|
@@ -145,6 +145,7 @@ export function createImplementNode(executor) {
|
|
|
145
145
|
await recordPhaseEnd(implementTimingId, Date.now() - startTime);
|
|
146
146
|
if (shouldInterrupt('implement', state.approvalGates)) {
|
|
147
147
|
log.info('Interrupting for human approval');
|
|
148
|
+
await recordApprovalWaitStart(implementTimingId);
|
|
148
149
|
interrupt({
|
|
149
150
|
node: 'implement',
|
|
150
151
|
message: `Implementation complete: ${totalTasks} tasks across ${totalPhases} phases. Approve to finish.`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iEAAiE,CAAC;AACrG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yEAAyE,CAAC;
|
|
1
|
+
{"version":3,"file":"merge.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iEAAiE,CAAC;AACrG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yEAAyE,CAAC;AAWlH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,aAAa,CAAC;IAC5B,cAAc,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IAChF,iBAAiB,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC;CACpE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,IAGnC,OAAO,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAwJ7E"}
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.js
CHANGED
|
@@ -13,7 +13,7 @@ import { interrupt, isGraphBubbleUp } from '@langchain/langgraph';
|
|
|
13
13
|
import { SdlcLifecycle, PrStatus } from '../../../../../domain/generated/output.js';
|
|
14
14
|
import { createNodeLogger, shouldInterrupt } from './node-helpers.js';
|
|
15
15
|
import { reportNodeStart } from '../heartbeat.js';
|
|
16
|
-
import { recordPhaseStart, recordPhaseEnd } from '../phase-timing-context.js';
|
|
16
|
+
import { recordPhaseStart, recordPhaseEnd, recordApprovalWaitStart, } from '../phase-timing-context.js';
|
|
17
17
|
import { updateNodeLifecycle } from '../lifecycle-context.js';
|
|
18
18
|
/**
|
|
19
19
|
* Factory that creates the merge node function.
|
|
@@ -82,6 +82,9 @@ export function createMergeNode(deps) {
|
|
|
82
82
|
// --- Step 4: Merge approval gate ---
|
|
83
83
|
if (shouldInterrupt('merge', state.approvalGates)) {
|
|
84
84
|
log.info('Interrupting for merge approval');
|
|
85
|
+
// Close timing before interrupt so the pre-approval work has a duration
|
|
86
|
+
await recordPhaseEnd(mergeTimingId, Date.now() - startTime);
|
|
87
|
+
await recordApprovalWaitStart(mergeTimingId);
|
|
85
88
|
const diffSummary = await gitPrService.getPrDiffSummary(cwd, baseBranch);
|
|
86
89
|
interrupt({
|
|
87
90
|
node: 'merge',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-helpers.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACrB,MAAM,+DAA+D,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"node-helpers.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACrB,MAAM,+DAA+D,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AASrD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM;kBAE/B,MAAM,GAAG,IAAI;mBAIZ,MAAM,GAAG,IAAI;EAK/B;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE7D;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMtE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,iBAAiB,GAAG,qBAAqB,CAMpF;AAeD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAQrD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,SAAS,GAAG,OAAO,CAS3F;AAMD,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG,mBAAmB,GAAG,eAAe,GAAG,SAAS,CAAC;AAMhG;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,CAKjE;AAED,MAAM,WAAW,YAAY;IAC3B,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,qBAAqB,EAC9B,SAAS,CAAC,EAAE,YAAY,GACvB,OAAO,CAAC,oBAAoB,CAAC,CA6B/B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAW5D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAwB1F;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,cAAc,EACxB,WAAW,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,UAAU,KAAK,MAAM,GACjE,CAAC,KAAK,EAAE,iBAAiB,KAAK,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAiFnE"}
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.js
CHANGED
|
@@ -9,7 +9,7 @@ import { readFileSync, writeFileSync } from 'node:fs';
|
|
|
9
9
|
import { join } from 'node:path';
|
|
10
10
|
import { interrupt, isGraphBubbleUp } from '@langchain/langgraph';
|
|
11
11
|
import { reportNodeStart } from '../heartbeat.js';
|
|
12
|
-
import { recordPhaseStart, recordPhaseEnd } from '../phase-timing-context.js';
|
|
12
|
+
import { recordPhaseStart, recordPhaseEnd, recordApprovalWaitStart, } from '../phase-timing-context.js';
|
|
13
13
|
import { updateNodeLifecycle } from '../lifecycle-context.js';
|
|
14
14
|
/**
|
|
15
15
|
* Create a scoped logger that prefixes messages with the node name.
|
|
@@ -245,6 +245,7 @@ export function executeNode(nodeName, executor, buildPrompt) {
|
|
|
245
245
|
// Human-in-the-loop: interrupt after node execution for review
|
|
246
246
|
if (shouldInterrupt(nodeName, state.approvalGates)) {
|
|
247
247
|
log.info('Interrupting for human approval');
|
|
248
|
+
await recordApprovalWaitStart(timingId);
|
|
248
249
|
interrupt({
|
|
249
250
|
node: nodeName,
|
|
250
251
|
result: result.result.slice(0, 500),
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON-Driven IDE Launcher Service
|
|
3
|
+
*
|
|
4
|
+
* Replaces the 5 hard-coded IDE launcher classes with a single service that
|
|
5
|
+
* derives editor commands from the JSON tool metadata files. Reads from the
|
|
6
|
+
* already-loaded TOOL_METADATA record, filters by category "ide" and presence
|
|
7
|
+
* of openDirectory, and performs {dir} placeholder substitution at launch time.
|
|
8
|
+
*/
|
|
9
|
+
import type { IIdeLauncherService, LaunchIdeResult } from '../../../application/ports/output/services/ide-launcher-service.interface.js';
|
|
10
|
+
/**
|
|
11
|
+
* Resolve a platform-specific value from a string or per-platform record.
|
|
12
|
+
* When the value is a plain string, returns it directly.
|
|
13
|
+
* When the value is a record, returns the entry for the current os.platform(),
|
|
14
|
+
* falling back to the first value if the current platform is not present.
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolvePlatformValue(value: string | Record<string, string>): string;
|
|
17
|
+
export declare class JsonDrivenIdeLauncherService implements IIdeLauncherService {
|
|
18
|
+
private readonly editors;
|
|
19
|
+
constructor();
|
|
20
|
+
launch(editorId: string, directoryPath: string): Promise<LaunchIdeResult>;
|
|
21
|
+
checkAvailability(editorId: string): Promise<boolean>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=json-driven-ide-launcher.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-driven-ide-launcher.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/ide-launchers/json-driven-ide-launcher.service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EAChB,MAAM,8EAA8E,CAAC;AActF;;;;;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;;IAgB1C,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAoD/E,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAWtD"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON-Driven IDE Launcher Service
|
|
3
|
+
*
|
|
4
|
+
* Replaces the 5 hard-coded IDE launcher classes with a single service that
|
|
5
|
+
* derives editor commands from the JSON tool metadata files. Reads from the
|
|
6
|
+
* already-loaded TOOL_METADATA record, filters by category "ide" and presence
|
|
7
|
+
* of openDirectory, and performs {dir} placeholder substitution at launch time.
|
|
8
|
+
*/
|
|
9
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
10
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
11
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
12
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
13
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
14
|
+
};
|
|
15
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
16
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
17
|
+
};
|
|
18
|
+
import { injectable } from 'tsyringe';
|
|
19
|
+
import { spawn, execFile } from 'node:child_process';
|
|
20
|
+
import { platform } from 'node:os';
|
|
21
|
+
import { TOOL_METADATA } from '../tool-installer/tool-metadata.js';
|
|
22
|
+
/**
|
|
23
|
+
* Resolve a platform-specific value from a string or per-platform record.
|
|
24
|
+
* When the value is a plain string, returns it directly.
|
|
25
|
+
* When the value is a record, returns the entry for the current os.platform(),
|
|
26
|
+
* falling back to the first value if the current platform is not present.
|
|
27
|
+
*/
|
|
28
|
+
export function resolvePlatformValue(value) {
|
|
29
|
+
if (typeof value === 'string')
|
|
30
|
+
return value;
|
|
31
|
+
return value[platform()] ?? Object.values(value)[0];
|
|
32
|
+
}
|
|
33
|
+
let JsonDrivenIdeLauncherService = class JsonDrivenIdeLauncherService {
|
|
34
|
+
editors;
|
|
35
|
+
constructor() {
|
|
36
|
+
this.editors = new Map();
|
|
37
|
+
for (const [id, meta] of Object.entries(TOOL_METADATA)) {
|
|
38
|
+
if (meta.openDirectory != null) {
|
|
39
|
+
this.editors.set(id, {
|
|
40
|
+
name: meta.name,
|
|
41
|
+
binary: meta.binary,
|
|
42
|
+
openDirectory: meta.openDirectory,
|
|
43
|
+
spawnOptions: meta.spawnOptions,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async launch(editorId, directoryPath) {
|
|
49
|
+
const entry = this.editors.get(editorId);
|
|
50
|
+
if (!entry) {
|
|
51
|
+
const available = [...this.editors.keys()].join(', ');
|
|
52
|
+
return {
|
|
53
|
+
ok: false,
|
|
54
|
+
code: 'unknown_editor',
|
|
55
|
+
message: `No launcher found for editor: ${editorId}. Available: ${available}`,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const openCmd = resolvePlatformValue(entry.openDirectory);
|
|
59
|
+
if (!openCmd.includes('{dir}')) {
|
|
60
|
+
return {
|
|
61
|
+
ok: false,
|
|
62
|
+
code: 'launch_failed',
|
|
63
|
+
message: `openDirectory for "${editorId}" is missing {dir} placeholder: "${openCmd}"`,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const resolved = openCmd.replace('{dir}', directoryPath);
|
|
67
|
+
const useShell = entry.spawnOptions?.shell === true;
|
|
68
|
+
const opts = {
|
|
69
|
+
detached: entry.spawnOptions?.detached ?? !useShell,
|
|
70
|
+
stdio: (entry.spawnOptions?.stdio ?? 'ignore'),
|
|
71
|
+
shell: useShell,
|
|
72
|
+
};
|
|
73
|
+
try {
|
|
74
|
+
let child;
|
|
75
|
+
if (useShell) {
|
|
76
|
+
child = spawn(resolved, [], opts);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
const [command, ...args] = resolved.split(/\s+/);
|
|
80
|
+
child = spawn(command, args, opts);
|
|
81
|
+
}
|
|
82
|
+
if (opts.detached)
|
|
83
|
+
child.unref();
|
|
84
|
+
return {
|
|
85
|
+
ok: true,
|
|
86
|
+
editorName: entry.name,
|
|
87
|
+
worktreePath: directoryPath,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
return {
|
|
92
|
+
ok: false,
|
|
93
|
+
code: 'launch_failed',
|
|
94
|
+
message: error instanceof Error ? error.message : 'Failed to launch IDE',
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
checkAvailability(editorId) {
|
|
99
|
+
const entry = this.editors.get(editorId);
|
|
100
|
+
if (!entry)
|
|
101
|
+
return Promise.resolve(false);
|
|
102
|
+
const binary = resolvePlatformValue(entry.binary);
|
|
103
|
+
return new Promise((resolve) => {
|
|
104
|
+
execFile('which', [binary], (err) => {
|
|
105
|
+
resolve(!err);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
JsonDrivenIdeLauncherService = __decorate([
|
|
111
|
+
injectable(),
|
|
112
|
+
__metadata("design:paramtypes", [])
|
|
113
|
+
], JsonDrivenIdeLauncherService);
|
|
114
|
+
export { JsonDrivenIdeLauncherService };
|
|
@@ -14,8 +14,8 @@ export interface ToolMetadata {
|
|
|
14
14
|
summary: string;
|
|
15
15
|
/** Detailed description */
|
|
16
16
|
description: string;
|
|
17
|
-
/** Tool
|
|
18
|
-
|
|
17
|
+
/** Tool tags for grouping in listings. A tool can belong to multiple categories. */
|
|
18
|
+
tags: ('ide' | 'cli-agent')[];
|
|
19
19
|
/** Binary name to check with 'which' command (string or per-platform map) */
|
|
20
20
|
binary: string | Record<string, string>;
|
|
21
21
|
/** Package manager or installation method */
|
|
@@ -30,8 +30,24 @@ export interface ToolMetadata {
|
|
|
30
30
|
verifyCommand: string;
|
|
31
31
|
/** Whether the tool supports automated installation (default: true) */
|
|
32
32
|
autoInstall?: boolean;
|
|
33
|
-
/** Command to open a directory in this tool
|
|
34
|
-
|
|
33
|
+
/** Command to open a directory in this tool.
|
|
34
|
+
* String format: "code {dir}" — single command for all platforms.
|
|
35
|
+
* Object format: { "linux": "antigravity {dir}", "darwin": "agy {dir}" } — per-platform commands. */
|
|
36
|
+
openDirectory?: string | Record<string, string>;
|
|
37
|
+
/** Override default spawn options for the launch process.
|
|
38
|
+
* Defaults: { detached: true, stdio: "ignore" } (GUI IDEs).
|
|
39
|
+
* CLI agents should use { shell: true, stdio: "inherit" } to run in the current terminal. */
|
|
40
|
+
spawnOptions?: {
|
|
41
|
+
shell?: boolean;
|
|
42
|
+
stdio?: 'ignore' | 'inherit' | 'pipe';
|
|
43
|
+
detached?: boolean;
|
|
44
|
+
};
|
|
35
45
|
}
|
|
36
46
|
export declare const TOOL_METADATA: Record<string, ToolMetadata>;
|
|
47
|
+
/**
|
|
48
|
+
* Returns entries from TOOL_METADATA that can open a directory as an IDE.
|
|
49
|
+
* A tool qualifies if it has an `openDirectory` field, regardless of category.
|
|
50
|
+
* Each entry is [toolId, metadata].
|
|
51
|
+
*/
|
|
52
|
+
export declare function getIdeEntries(): [string, ToolMetadata][];
|
|
37
53
|
//# sourceMappingURL=tool-metadata.d.ts.map
|
package/dist/packages/core/src/infrastructure/services/tool-installer/tool-metadata.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-metadata.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/tool-installer/tool-metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,YAAY;IAC3B,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IAEb,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAEhB,2BAA2B;IAC3B,WAAW,EAAE,MAAM,CAAC;IAEpB,
|
|
1
|
+
{"version":3,"file":"tool-metadata.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/tool-installer/tool-metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,YAAY;IAC3B,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IAEb,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAEhB,2BAA2B;IAC3B,WAAW,EAAE,MAAM,CAAC;IAEpB,oFAAoF;IACpF,IAAI,EAAE,CAAC,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC;IAE9B,6EAA6E;IAC7E,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAExC,6CAA6C;IAC7C,cAAc,EAAE,MAAM,CAAC;IAEvB,wFAAwF;IACxF,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAEhB,iCAAiC;IACjC,gBAAgB,EAAE,MAAM,CAAC;IAEzB,8DAA8D;IAC9D,aAAa,EAAE,MAAM,CAAC;IAEtB,uEAAuE;IACvE,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;yGAEqG;IACrG,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEhD;;iGAE6F;IAC7F,YAAY,CAAC,EAAE;QACb,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,KAAK,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;QACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC;CACH;AA8CD,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAsB,CAAC;AAE9E;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,CAExD"}
|
|
@@ -14,7 +14,7 @@ const REQUIRED_FIELDS = [
|
|
|
14
14
|
'name',
|
|
15
15
|
'summary',
|
|
16
16
|
'description',
|
|
17
|
-
'
|
|
17
|
+
'tags',
|
|
18
18
|
'binary',
|
|
19
19
|
'packageManager',
|
|
20
20
|
'commands',
|
|
@@ -50,3 +50,11 @@ function loadToolMetadata() {
|
|
|
50
50
|
return metadata;
|
|
51
51
|
}
|
|
52
52
|
export const TOOL_METADATA = loadToolMetadata();
|
|
53
|
+
/**
|
|
54
|
+
* Returns entries from TOOL_METADATA that can open a directory as an IDE.
|
|
55
|
+
* A tool qualifies if it has an `openDirectory` field, regardless of category.
|
|
56
|
+
* Each entry is [toolId, metadata].
|
|
57
|
+
*/
|
|
58
|
+
export function getIdeEntries() {
|
|
59
|
+
return Object.entries(TOOL_METADATA).filter(([, meta]) => meta.openDirectory != null);
|
|
60
|
+
}
|
package/dist/packages/core/src/infrastructure/services/tool-installer/tools/antigravity.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "Google Antigravity",
|
|
3
3
|
"summary": "AI-powered agentic development platform",
|
|
4
4
|
"description": "Google Antigravity is an AI-powered platform that enables agentic development workflows, helping developers build intelligent applications with autonomous agents.",
|
|
5
|
-
"
|
|
5
|
+
"tags": ["ide"],
|
|
6
6
|
"binary": {
|
|
7
7
|
"linux": "antigravity",
|
|
8
8
|
"darwin": "agy"
|
|
@@ -16,5 +16,8 @@
|
|
|
16
16
|
"documentationUrl": "https://codelabs.developers.google.com/getting-started-google-antigravity",
|
|
17
17
|
"verifyCommand": "agy --version",
|
|
18
18
|
"autoInstall": false,
|
|
19
|
-
"openDirectory":
|
|
19
|
+
"openDirectory": {
|
|
20
|
+
"linux": "antigravity {dir}",
|
|
21
|
+
"darwin": "agy {dir}"
|
|
22
|
+
}
|
|
20
23
|
}
|
package/dist/packages/core/src/infrastructure/services/tool-installer/tools/claude-code.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "Claude Code",
|
|
3
3
|
"summary": "AI-powered code assistant from Anthropic",
|
|
4
4
|
"description": "Claude Code is an AI-powered code assistant from Anthropic that helps you write, understand, and debug code with advanced AI capabilities.",
|
|
5
|
-
"
|
|
5
|
+
"tags": ["ide", "cli-agent"],
|
|
6
6
|
"binary": "claude",
|
|
7
7
|
"packageManager": "curl",
|
|
8
8
|
"commands": {
|
|
@@ -12,5 +12,11 @@
|
|
|
12
12
|
"timeout": 300000,
|
|
13
13
|
"documentationUrl": "https://code.claude.com/docs/en/overview",
|
|
14
14
|
"verifyCommand": "claude --version",
|
|
15
|
-
"autoInstall": true
|
|
15
|
+
"autoInstall": true,
|
|
16
|
+
"openDirectory": "cd {dir} && exec claude",
|
|
17
|
+
"spawnOptions": {
|
|
18
|
+
"shell": true,
|
|
19
|
+
"stdio": "inherit",
|
|
20
|
+
"detached": false
|
|
21
|
+
}
|
|
16
22
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "Cursor CLI",
|
|
3
3
|
"summary": "AI-powered terminal coding agent",
|
|
4
4
|
"description": "Cursor CLI is a terminal-based AI coding agent that brings conversational AI assistance directly to your command line for any IDE or terminal.",
|
|
5
|
-
"
|
|
5
|
+
"tags": ["ide", "cli-agent"],
|
|
6
6
|
"binary": "cursor-agent",
|
|
7
7
|
"packageManager": "curl",
|
|
8
8
|
"commands": {
|
|
@@ -12,5 +12,11 @@
|
|
|
12
12
|
"timeout": 300000,
|
|
13
13
|
"documentationUrl": "https://www.codecademy.com/article/getting-started-with-cursor-cli",
|
|
14
14
|
"verifyCommand": "cursor-agent --version",
|
|
15
|
-
"autoInstall": true
|
|
15
|
+
"autoInstall": true,
|
|
16
|
+
"openDirectory": "cd {dir} && exec cursor-agent",
|
|
17
|
+
"spawnOptions": {
|
|
18
|
+
"shell": true,
|
|
19
|
+
"stdio": "inherit",
|
|
20
|
+
"detached": false
|
|
21
|
+
}
|
|
16
22
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "Cursor",
|
|
3
3
|
"summary": "AI-powered code editor for efficient development",
|
|
4
4
|
"description": "Cursor is an AI-powered code editor built on VS Code, designed to streamline development workflows with advanced AI-assisted coding capabilities.",
|
|
5
|
-
"
|
|
5
|
+
"tags": ["ide"],
|
|
6
6
|
"binary": "cursor",
|
|
7
7
|
"packageManager": "manual",
|
|
8
8
|
"commands": {
|
|
@@ -13,5 +13,5 @@
|
|
|
13
13
|
"documentationUrl": "https://cursor.com/download",
|
|
14
14
|
"verifyCommand": "cursor --version",
|
|
15
15
|
"autoInstall": false,
|
|
16
|
-
"openDirectory": "cursor
|
|
16
|
+
"openDirectory": "cursor {dir}"
|
|
17
17
|
}
|