@shepai/cli 1.17.0 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/eslint.config.mjs +8 -1
- package/dist/src/application/ports/output/agents/agent-executor.interface.d.ts +4 -0
- package/dist/src/application/ports/output/agents/agent-executor.interface.d.ts.map +1 -1
- package/dist/src/domain/factories/settings-defaults.factory.js +2 -2
- package/dist/src/domain/generated/output.d.ts +8 -1
- package/dist/src/domain/generated/output.d.ts.map +1 -1
- package/dist/src/domain/generated/output.js +8 -0
- package/dist/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -1
- package/dist/src/infrastructure/services/agents/common/executors/claude-code-executor.service.d.ts.map +1 -1
- package/dist/src/infrastructure/services/agents/common/executors/claude-code-executor.service.js +4 -0
- package/dist/src/infrastructure/services/agents/feature-agent/nodes/implement.node.d.ts.map +1 -1
- package/dist/src/infrastructure/services/agents/feature-agent/nodes/implement.node.js +13 -3
- package/dist/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts +35 -1
- package/dist/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts.map +1 -1
- package/dist/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.js +96 -1
- package/dist/src/infrastructure/services/ide-launchers/antigravity.launcher.d.ts +10 -0
- package/dist/src/infrastructure/services/ide-launchers/antigravity.launcher.d.ts.map +1 -0
- package/dist/src/infrastructure/services/ide-launchers/antigravity.launcher.js +21 -0
- package/dist/src/infrastructure/services/ide-launchers/cursor.launcher.d.ts +10 -0
- package/dist/src/infrastructure/services/ide-launchers/cursor.launcher.d.ts.map +1 -0
- package/dist/src/infrastructure/services/ide-launchers/cursor.launcher.js +21 -0
- package/dist/src/infrastructure/services/ide-launchers/ide-launcher.interface.d.ts +31 -0
- package/dist/src/infrastructure/services/ide-launchers/ide-launcher.interface.d.ts.map +1 -0
- package/dist/src/infrastructure/services/ide-launchers/ide-launcher.interface.js +8 -0
- package/dist/src/infrastructure/services/ide-launchers/ide-launcher.registry.d.ts +9 -0
- package/dist/src/infrastructure/services/ide-launchers/ide-launcher.registry.d.ts.map +1 -0
- package/dist/src/infrastructure/services/ide-launchers/ide-launcher.registry.js +24 -0
- package/dist/src/infrastructure/services/ide-launchers/vscode.launcher.d.ts +10 -0
- package/dist/src/infrastructure/services/ide-launchers/vscode.launcher.d.ts.map +1 -0
- package/dist/src/infrastructure/services/ide-launchers/vscode.launcher.js +21 -0
- package/dist/src/infrastructure/services/ide-launchers/windsurf.launcher.d.ts +10 -0
- package/dist/src/infrastructure/services/ide-launchers/windsurf.launcher.d.ts.map +1 -0
- package/dist/src/infrastructure/services/ide-launchers/windsurf.launcher.js +21 -0
- package/dist/src/infrastructure/services/ide-launchers/zed.launcher.d.ts +10 -0
- package/dist/src/infrastructure/services/ide-launchers/zed.launcher.d.ts.map +1 -0
- package/dist/src/infrastructure/services/ide-launchers/zed.launcher.js +21 -0
- package/dist/src/presentation/cli/commands/ide-open.command.d.ts +10 -0
- package/dist/src/presentation/cli/commands/ide-open.command.d.ts.map +1 -0
- package/dist/src/presentation/cli/commands/ide-open.command.js +77 -0
- package/dist/src/presentation/cli/commands/settings/ide.command.d.ts +15 -0
- package/dist/src/presentation/cli/commands/settings/ide.command.d.ts.map +1 -0
- package/dist/src/presentation/cli/commands/settings/ide.command.js +76 -0
- package/dist/src/presentation/cli/commands/settings/index.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/settings/index.js +3 -1
- package/dist/src/presentation/cli/index.js +2 -0
- package/dist/src/presentation/tui/prompts/ide-select.prompt.d.ts +45 -0
- package/dist/src/presentation/tui/prompts/ide-select.prompt.d.ts.map +1 -0
- package/dist/src/presentation/tui/prompts/ide-select.prompt.js +44 -0
- package/dist/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.js +1 -1
- package/dist/src/presentation/web/components/ui/alert.js +1 -1
- package/dist/src/presentation/web/components/ui/badge.js +4 -4
- package/dist/src/presentation/web/components/ui/button.js +3 -3
- package/dist/src/presentation/web/components/ui/sidebar.js +2 -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/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_not-found.html +2 -2
- package/web/.next/server/app/_not-found.rsc +8 -8
- package/web/.next/server/app/_not-found.segments/_full.segment.rsc +8 -8
- package/web/.next/server/app/_not-found.segments/_head.segment.rsc +3 -3
- package/web/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
- package/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/index.html +2 -2
- package/web/.next/server/app/index.rsc +3 -3
- package/web/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/web/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version.html +2 -2
- package/web/.next/server/app/version.rsc +3 -3
- package/web/.next/server/app/version.segments/_full.segment.rsc +3 -3
- package/web/.next/server/app/version.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/version.segments/_index.segment.rsc +2 -2
- package/web/.next/server/app/version.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/version.segments/version/__PAGE__.segment.rsc +2 -2
- package/web/.next/server/app/version.segments/version.segment.rsc +1 -1
- package/web/.next/server/chunks/ssr/_0f02ab66._.js +1 -1
- package/web/.next/server/chunks/ssr/_0f02ab66._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_19be0743._.js +1 -1
- package/web/.next/server/chunks/ssr/_4582f3c3._.js +1 -1
- package/web/.next/server/chunks/ssr/_4582f3c3._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_a0c04017._.js +1 -1
- package/web/.next/server/chunks/ssr/_a0c04017._.js.map +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_version_version-page-client_tsx_fe9db753._.js +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_version_version-page-client_tsx_fe9db753._.js.map +1 -1
- package/web/.next/server/pages/404.html +2 -2
- 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/static/chunks/{5130d7093ad39f4a.js → 26d260496abf3ed8.js} +1 -1
- package/web/.next/static/chunks/{ef1296dbe67d5aae.js → 8353f5690707d9a5.js} +1 -1
- package/web/.next/static/chunks/{523c5cfe0570712c.js → f74cb59a5a6c94f1.js} +1 -1
- package/web/.next/trace +1 -1
- package/web/.next/trace-build +1 -1
- /package/web/.next/static/{Wgd1DC_QfVhpAi62LjpwI → nw4IT0rr_mE5Tx22X9OgO}/_buildManifest.js +0 -0
- /package/web/.next/static/{Wgd1DC_QfVhpAi62LjpwI → nw4IT0rr_mE5Tx22X9OgO}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{Wgd1DC_QfVhpAi62LjpwI → nw4IT0rr_mE5Tx22X9OgO}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { spawn, execFile } from 'node:child_process';
|
|
2
|
+
import { EditorType } from '../../../domain/generated/output.js';
|
|
3
|
+
export class VsCodeLauncher {
|
|
4
|
+
name = 'VS Code';
|
|
5
|
+
editorId = EditorType.VsCode;
|
|
6
|
+
binary = 'code';
|
|
7
|
+
async launch(path) {
|
|
8
|
+
const child = spawn(this.binary, [path], {
|
|
9
|
+
detached: true,
|
|
10
|
+
stdio: 'ignore',
|
|
11
|
+
});
|
|
12
|
+
child.unref();
|
|
13
|
+
}
|
|
14
|
+
checkAvailable() {
|
|
15
|
+
return new Promise((resolve) => {
|
|
16
|
+
execFile('which', [this.binary], (err) => {
|
|
17
|
+
resolve(!err);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { EditorType } from '../../../domain/generated/output.js';
|
|
2
|
+
import type { IdeLauncher } from './ide-launcher.interface';
|
|
3
|
+
export declare class WindsurfLauncher implements IdeLauncher {
|
|
4
|
+
readonly name = "Windsurf";
|
|
5
|
+
readonly editorId = EditorType.Windsurf;
|
|
6
|
+
readonly binary = "windsurf";
|
|
7
|
+
launch(path: string): Promise<void>;
|
|
8
|
+
checkAvailable(): Promise<boolean>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=windsurf.launcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"windsurf.launcher.d.ts","sourceRoot":"","sources":["../../../../../src/infrastructure/services/ide-launchers/windsurf.launcher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,qBAAa,gBAAiB,YAAW,WAAW;IAClD,QAAQ,CAAC,IAAI,cAAc;IAC3B,QAAQ,CAAC,QAAQ,uBAAuB;IACxC,QAAQ,CAAC,MAAM,cAAc;IAEvB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQzC,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;CAOnC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { spawn, execFile } from 'node:child_process';
|
|
2
|
+
import { EditorType } from '../../../domain/generated/output.js';
|
|
3
|
+
export class WindsurfLauncher {
|
|
4
|
+
name = 'Windsurf';
|
|
5
|
+
editorId = EditorType.Windsurf;
|
|
6
|
+
binary = 'windsurf';
|
|
7
|
+
async launch(path) {
|
|
8
|
+
const child = spawn(this.binary, [path], {
|
|
9
|
+
detached: true,
|
|
10
|
+
stdio: 'ignore',
|
|
11
|
+
});
|
|
12
|
+
child.unref();
|
|
13
|
+
}
|
|
14
|
+
checkAvailable() {
|
|
15
|
+
return new Promise((resolve) => {
|
|
16
|
+
execFile('which', [this.binary], (err) => {
|
|
17
|
+
resolve(!err);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { EditorType } from '../../../domain/generated/output.js';
|
|
2
|
+
import type { IdeLauncher } from './ide-launcher.interface';
|
|
3
|
+
export declare class ZedLauncher implements IdeLauncher {
|
|
4
|
+
readonly name = "Zed";
|
|
5
|
+
readonly editorId = EditorType.Zed;
|
|
6
|
+
readonly binary = "zed";
|
|
7
|
+
launch(path: string): Promise<void>;
|
|
8
|
+
checkAvailable(): Promise<boolean>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=zed.launcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zed.launcher.d.ts","sourceRoot":"","sources":["../../../../../src/infrastructure/services/ide-launchers/zed.launcher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,qBAAa,WAAY,YAAW,WAAW;IAC7C,QAAQ,CAAC,IAAI,SAAS;IACtB,QAAQ,CAAC,QAAQ,kBAAkB;IACnC,QAAQ,CAAC,MAAM,SAAS;IAElB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQzC,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;CAOnC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { spawn, execFile } from 'node:child_process';
|
|
2
|
+
import { EditorType } from '../../../domain/generated/output.js';
|
|
3
|
+
export class ZedLauncher {
|
|
4
|
+
name = 'Zed';
|
|
5
|
+
editorId = EditorType.Zed;
|
|
6
|
+
binary = 'zed';
|
|
7
|
+
async launch(path) {
|
|
8
|
+
const child = spawn(this.binary, [path], {
|
|
9
|
+
detached: true,
|
|
10
|
+
stdio: 'ignore',
|
|
11
|
+
});
|
|
12
|
+
child.unref();
|
|
13
|
+
}
|
|
14
|
+
checkAvailable() {
|
|
15
|
+
return new Promise((resolve) => {
|
|
16
|
+
execFile('which', [this.binary], (err) => {
|
|
17
|
+
resolve(!err);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IDE Open Command
|
|
3
|
+
*
|
|
4
|
+
* Opens a feature worktree in the configured IDE.
|
|
5
|
+
*
|
|
6
|
+
* Usage: shep ide <feat-id> [--vscode|--cursor|--windsurf|--zed|--antigravity]
|
|
7
|
+
*/
|
|
8
|
+
import { Command } from 'commander';
|
|
9
|
+
export declare function createIdeOpenCommand(): Command;
|
|
10
|
+
//# sourceMappingURL=ide-open.command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ide-open.command.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/cli/commands/ide-open.command.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+CpC,wBAAgB,oBAAoB,IAAI,OAAO,CAwC9C"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IDE Open Command
|
|
3
|
+
*
|
|
4
|
+
* Opens a feature worktree in the configured IDE.
|
|
5
|
+
*
|
|
6
|
+
* Usage: shep ide <feat-id> [--vscode|--cursor|--windsurf|--zed|--antigravity]
|
|
7
|
+
*/
|
|
8
|
+
import { Command } from 'commander';
|
|
9
|
+
import { createHash } from 'node:crypto';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
import { EditorType } from '../../../domain/generated/output.js';
|
|
12
|
+
import { container } from '../../../infrastructure/di/container.js';
|
|
13
|
+
import { ShowFeatureUseCase } from '../../../application/use-cases/features/show-feature.use-case.js';
|
|
14
|
+
import { getSettings } from '../../../infrastructure/services/settings.service.js';
|
|
15
|
+
import { createLauncherRegistry } from '../../../infrastructure/services/ide-launchers/ide-launcher.registry.js';
|
|
16
|
+
import { SHEP_HOME_DIR } from '../../../infrastructure/services/filesystem/shep-directory.service.js';
|
|
17
|
+
import { messages } from '../ui/index.js';
|
|
18
|
+
function computeWorktreePath(repoPath, branch) {
|
|
19
|
+
const repoHash = createHash('sha256').update(repoPath).digest('hex').slice(0, 16);
|
|
20
|
+
const slug = branch.replace(/\//g, '-');
|
|
21
|
+
return join(SHEP_HOME_DIR, 'repos', repoHash, 'wt', slug);
|
|
22
|
+
}
|
|
23
|
+
/** IDE flag names mapped to their EditorType values. */
|
|
24
|
+
const IDE_FLAG_MAP = {
|
|
25
|
+
vscode: EditorType.VsCode,
|
|
26
|
+
cursor: EditorType.Cursor,
|
|
27
|
+
windsurf: EditorType.Windsurf,
|
|
28
|
+
zed: EditorType.Zed,
|
|
29
|
+
antigravity: EditorType.Antigravity,
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Determine which editor to use based on CLI flags and settings.
|
|
33
|
+
* Flag takes precedence over settings.
|
|
34
|
+
*/
|
|
35
|
+
function resolveEditorId(options) {
|
|
36
|
+
for (const [flag, editorType] of Object.entries(IDE_FLAG_MAP)) {
|
|
37
|
+
if (options[flag]) {
|
|
38
|
+
return editorType;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return getSettings().environment.defaultEditor;
|
|
42
|
+
}
|
|
43
|
+
export function createIdeOpenCommand() {
|
|
44
|
+
return new Command('ide')
|
|
45
|
+
.description('Open a feature worktree in your IDE')
|
|
46
|
+
.argument('<feat-id>', 'Feature ID or prefix')
|
|
47
|
+
.option('--vscode', 'Open in VS Code')
|
|
48
|
+
.option('--cursor', 'Open in Cursor')
|
|
49
|
+
.option('--windsurf', 'Open in Windsurf')
|
|
50
|
+
.option('--zed', 'Open in Zed')
|
|
51
|
+
.option('--antigravity', 'Open in Antigravity')
|
|
52
|
+
.action(async (featId, options) => {
|
|
53
|
+
try {
|
|
54
|
+
// Resolve the editor
|
|
55
|
+
const editorId = resolveEditorId(options);
|
|
56
|
+
const registry = createLauncherRegistry();
|
|
57
|
+
const launcher = registry.get(editorId);
|
|
58
|
+
if (!launcher) {
|
|
59
|
+
messages.error(`Unknown editor "${editorId}". Supported: ${[...registry.keys()].join(', ')}`, new Error(`Unknown editor: ${editorId}`));
|
|
60
|
+
process.exitCode = 1;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Resolve the feature
|
|
64
|
+
const useCase = container.resolve(ShowFeatureUseCase);
|
|
65
|
+
const feature = await useCase.execute(featId);
|
|
66
|
+
// Compute worktree path and launch
|
|
67
|
+
const worktreePath = computeWorktreePath(feature.repositoryPath, feature.branch);
|
|
68
|
+
await launcher.launch(worktreePath);
|
|
69
|
+
messages.success(`Opened ${launcher.name} at ${worktreePath}`);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
73
|
+
messages.error('Failed to open IDE', err);
|
|
74
|
+
process.exitCode = 1;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IDE Configuration Command
|
|
3
|
+
*
|
|
4
|
+
* Configures the preferred IDE/editor used by Shep.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* shep settings ide # Interactive selection
|
|
8
|
+
* shep settings ide --editor cursor # Non-interactive
|
|
9
|
+
*/
|
|
10
|
+
import { Command } from 'commander';
|
|
11
|
+
/**
|
|
12
|
+
* Create the IDE configuration command.
|
|
13
|
+
*/
|
|
14
|
+
export declare function createIdeCommand(): Command;
|
|
15
|
+
//# sourceMappingURL=ide.command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ide.command.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/settings/ide.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiBpC;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAkE1C"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IDE Configuration Command
|
|
3
|
+
*
|
|
4
|
+
* Configures the preferred IDE/editor used by Shep.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* shep settings ide # Interactive selection
|
|
8
|
+
* shep settings ide --editor cursor # Non-interactive
|
|
9
|
+
*/
|
|
10
|
+
import { Command } from 'commander';
|
|
11
|
+
import { select } from '@inquirer/prompts';
|
|
12
|
+
import { EditorType } from '../../../../domain/generated/output.js';
|
|
13
|
+
import { container } from '../../../../infrastructure/di/container.js';
|
|
14
|
+
import { UpdateSettingsUseCase } from '../../../../application/use-cases/settings/update-settings.use-case.js';
|
|
15
|
+
import { createIdeSelectConfig } from '../../../tui/prompts/ide-select.prompt.js';
|
|
16
|
+
import { getSettings, resetSettings, initializeSettings, } from '../../../../infrastructure/services/settings.service.js';
|
|
17
|
+
import { createLauncherRegistry } from '../../../../infrastructure/services/ide-launchers/ide-launcher.registry.js';
|
|
18
|
+
import { messages } from '../../ui/index.js';
|
|
19
|
+
/** Valid EditorType values for input validation. */
|
|
20
|
+
const VALID_EDITORS = new Set(Object.values(EditorType));
|
|
21
|
+
/**
|
|
22
|
+
* Create the IDE configuration command.
|
|
23
|
+
*/
|
|
24
|
+
export function createIdeCommand() {
|
|
25
|
+
return new Command('ide')
|
|
26
|
+
.description('Configure preferred IDE/editor')
|
|
27
|
+
.option('--editor <name>', 'IDE/editor name (e.g., vscode, cursor, windsurf, zed, antigravity)')
|
|
28
|
+
.addHelpText('after', `
|
|
29
|
+
Examples:
|
|
30
|
+
$ shep settings ide Interactive selection
|
|
31
|
+
$ shep settings ide --editor cursor Non-interactive
|
|
32
|
+
$ shep settings ide --editor antigravity Set Google Antigravity`)
|
|
33
|
+
.action(async (options) => {
|
|
34
|
+
try {
|
|
35
|
+
let editorValue;
|
|
36
|
+
if (options.editor !== undefined) {
|
|
37
|
+
if (!VALID_EDITORS.has(options.editor)) {
|
|
38
|
+
messages.error(`Unknown editor "${options.editor}". Valid: ${[...VALID_EDITORS].join(', ')}`, new Error(`Unknown editor: ${options.editor}`));
|
|
39
|
+
process.exitCode = 1;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
editorValue = options.editor;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
editorValue = await select(createIdeSelectConfig());
|
|
46
|
+
}
|
|
47
|
+
// PATH check via launcher registry (non-blocking warning)
|
|
48
|
+
const registry = createLauncherRegistry();
|
|
49
|
+
const launcher = registry.get(editorValue);
|
|
50
|
+
if (launcher) {
|
|
51
|
+
const available = await launcher.checkAvailable();
|
|
52
|
+
if (!available) {
|
|
53
|
+
messages.warning(`'${launcher.binary}' not found in PATH. The editor will still be saved.`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Persist settings
|
|
57
|
+
const settings = getSettings();
|
|
58
|
+
settings.environment.defaultEditor = editorValue;
|
|
59
|
+
const useCase = container.resolve(UpdateSettingsUseCase);
|
|
60
|
+
const updatedSettings = await useCase.execute(settings);
|
|
61
|
+
// Refresh in-memory singleton
|
|
62
|
+
resetSettings();
|
|
63
|
+
initializeSettings(updatedSettings);
|
|
64
|
+
messages.success(`Default editor set to: ${editorValue}`);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
68
|
+
if (err.message.includes('force closed') || err.message.includes('User force closed')) {
|
|
69
|
+
messages.info('Configuration cancelled.');
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
messages.error('Failed to configure IDE', err);
|
|
73
|
+
process.exitCode = 1;
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/settings/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/settings/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAO/C"}
|
|
@@ -12,6 +12,7 @@ import { Command } from 'commander';
|
|
|
12
12
|
import { createShowCommand } from './show.command.js';
|
|
13
13
|
import { createInitCommand } from './init.command.js';
|
|
14
14
|
import { createAgentCommand } from './agent.command.js';
|
|
15
|
+
import { createIdeCommand } from './ide.command.js';
|
|
15
16
|
/**
|
|
16
17
|
* Create the settings command group
|
|
17
18
|
*/
|
|
@@ -20,5 +21,6 @@ export function createSettingsCommand() {
|
|
|
20
21
|
.description('Manage Shep global settings')
|
|
21
22
|
.addCommand(createShowCommand())
|
|
22
23
|
.addCommand(createInitCommand())
|
|
23
|
-
.addCommand(createAgentCommand())
|
|
24
|
+
.addCommand(createAgentCommand())
|
|
25
|
+
.addCommand(createIdeCommand());
|
|
24
26
|
}
|
|
@@ -30,6 +30,7 @@ import { createUiCommand } from './commands/ui.command.js';
|
|
|
30
30
|
import { createRunCommand } from './commands/run.command.js';
|
|
31
31
|
import { createAgentCommand } from './commands/agent/index.js';
|
|
32
32
|
import { createFeatCommand } from './commands/feat/index.js';
|
|
33
|
+
import { createIdeOpenCommand } from './commands/ide-open.command.js';
|
|
33
34
|
import { messages } from './ui/index.js';
|
|
34
35
|
// DI container and settings
|
|
35
36
|
import { initializeContainer, container } from '../../infrastructure/di/container.js';
|
|
@@ -78,6 +79,7 @@ async function bootstrap() {
|
|
|
78
79
|
program.addCommand(createRunCommand());
|
|
79
80
|
program.addCommand(createAgentCommand());
|
|
80
81
|
program.addCommand(createFeatCommand());
|
|
82
|
+
program.addCommand(createIdeOpenCommand());
|
|
81
83
|
// Parse arguments (parseAsync needed for async command actions like init)
|
|
82
84
|
await program.parseAsync();
|
|
83
85
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IDE Select Prompt Configuration
|
|
3
|
+
*
|
|
4
|
+
* Configuration for the @inquirer/select prompt that lets users
|
|
5
|
+
* choose their preferred IDE/editor.
|
|
6
|
+
*/
|
|
7
|
+
import { EditorType } from '../../../domain/generated/output.js';
|
|
8
|
+
/**
|
|
9
|
+
* Creates the @inquirer/select configuration for selecting a preferred IDE.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createIdeSelectConfig(): {
|
|
12
|
+
readonly message: "Select your preferred IDE";
|
|
13
|
+
readonly choices: readonly [{
|
|
14
|
+
readonly name: "VS Code";
|
|
15
|
+
readonly value: EditorType.VsCode;
|
|
16
|
+
readonly description: "Visual Studio Code";
|
|
17
|
+
}, {
|
|
18
|
+
readonly name: "Cursor";
|
|
19
|
+
readonly value: EditorType.Cursor;
|
|
20
|
+
readonly description: "Cursor AI editor";
|
|
21
|
+
}, {
|
|
22
|
+
readonly name: "Windsurf";
|
|
23
|
+
readonly value: EditorType.Windsurf;
|
|
24
|
+
readonly description: "Windsurf editor";
|
|
25
|
+
}, {
|
|
26
|
+
readonly name: "Zed";
|
|
27
|
+
readonly value: EditorType.Zed;
|
|
28
|
+
readonly description: "Zed editor";
|
|
29
|
+
}, {
|
|
30
|
+
readonly name: "Antigravity";
|
|
31
|
+
readonly value: EditorType.Antigravity;
|
|
32
|
+
readonly description: "Google Antigravity IDE";
|
|
33
|
+
}];
|
|
34
|
+
readonly theme: {
|
|
35
|
+
readonly prefix: {
|
|
36
|
+
readonly idle: string;
|
|
37
|
+
readonly done: string;
|
|
38
|
+
};
|
|
39
|
+
readonly style: {
|
|
40
|
+
readonly highlight: import("picocolors/types.js").Formatter;
|
|
41
|
+
readonly answer: import("picocolors/types.js").Formatter;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=ide-select.prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ide-select.prompt.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/tui/prompts/ide-select.prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAGjE;;GAEG;AACH,wBAAgB,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgCpC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IDE Select Prompt Configuration
|
|
3
|
+
*
|
|
4
|
+
* Configuration for the @inquirer/select prompt that lets users
|
|
5
|
+
* choose their preferred IDE/editor.
|
|
6
|
+
*/
|
|
7
|
+
import { EditorType } from '../../../domain/generated/output.js';
|
|
8
|
+
import { shepTheme } from '../themes/shep.theme.js';
|
|
9
|
+
/**
|
|
10
|
+
* Creates the @inquirer/select configuration for selecting a preferred IDE.
|
|
11
|
+
*/
|
|
12
|
+
export function createIdeSelectConfig() {
|
|
13
|
+
return {
|
|
14
|
+
message: 'Select your preferred IDE',
|
|
15
|
+
choices: [
|
|
16
|
+
{
|
|
17
|
+
name: 'VS Code',
|
|
18
|
+
value: EditorType.VsCode,
|
|
19
|
+
description: 'Visual Studio Code',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: 'Cursor',
|
|
23
|
+
value: EditorType.Cursor,
|
|
24
|
+
description: 'Cursor AI editor',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'Windsurf',
|
|
28
|
+
value: EditorType.Windsurf,
|
|
29
|
+
description: 'Windsurf editor',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'Zed',
|
|
33
|
+
value: EditorType.Zed,
|
|
34
|
+
description: 'Zed editor',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: 'Antigravity',
|
|
38
|
+
value: EditorType.Antigravity,
|
|
39
|
+
description: 'Google Antigravity IDE',
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
theme: shepTheme,
|
|
43
|
+
};
|
|
44
|
+
}
|
package/dist/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.js
CHANGED
|
@@ -7,5 +7,5 @@ import { useSidebar } from '../../ui/sidebar';
|
|
|
7
7
|
import { cn } from '../../../lib/utils';
|
|
8
8
|
export function SidebarSectionHeader({ label, onFolderClick, onMenuClick, className, }) {
|
|
9
9
|
const { state, isMobile } = useSidebar();
|
|
10
|
-
return (_jsx(SidebarGroup, { "data-testid": "sidebar-section-header", className: cn('px-2 py-1', className), children: _jsxs("div", { className: "text-sidebar-foreground flex h-7 w-full shrink-0 items-center px-2 text-sm font-medium", children: [_jsx("span", { className: "min-w-0 flex-1 truncate", children: label }), _jsxs("span", { className: "text-sidebar-foreground/70 flex shrink-0 items-center gap-0.5", children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: onFolderClick, className: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground
|
|
10
|
+
return (_jsx(SidebarGroup, { "data-testid": "sidebar-section-header", className: cn('px-2 py-1', className), children: _jsxs("div", { className: "text-sidebar-foreground flex h-7 w-full shrink-0 items-center px-2 text-sm font-medium", children: [_jsx("span", { className: "min-w-0 flex-1 truncate", children: label }), _jsxs("span", { className: "text-sidebar-foreground/70 flex shrink-0 items-center gap-0.5", children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: onFolderClick, className: "ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground flex size-7 items-center justify-center rounded-md p-0 outline-hidden transition-colors focus-visible:ring-2 [&>svg]:size-4", "aria-label": "Open features folder", children: _jsx(Folder, { className: "size-4" }) }) }), _jsx(TooltipContent, { side: "right", align: "center", hidden: state !== 'collapsed' || isMobile, children: "Open features folder" })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: onMenuClick, className: "ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground flex size-7 items-center justify-center rounded-md p-0 outline-hidden transition-colors focus-visible:ring-2 [&>svg]:size-4", "aria-label": "Features options", children: _jsx(GripHorizontal, { className: "size-4" }) }) }), _jsx(TooltipContent, { side: "right", align: "center", hidden: state !== 'collapsed' || isMobile, children: "Features options" })] })] })] }) }));
|
|
11
11
|
}
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { cva } from 'class-variance-authority';
|
|
4
4
|
import { cn } from '../../lib/utils';
|
|
5
|
-
const alertVariants = cva('
|
|
5
|
+
const alertVariants = cva('relative w-full rounded-lg border px-4 py-3 text-sm [&>svg]:absolute [&>svg]:top-4 [&>svg]:left-4 [&>svg]:text-foreground [&>svg+div]:translate-y-[-3px] [&>svg~*]:pl-7', {
|
|
6
6
|
variants: {
|
|
7
7
|
variant: {
|
|
8
8
|
default: 'bg-background text-foreground',
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { cva } from 'class-variance-authority';
|
|
3
3
|
import { cn } from '../../lib/utils';
|
|
4
|
-
const badgeVariants = cva('
|
|
4
|
+
const badgeVariants = cva('inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-none', {
|
|
5
5
|
variants: {
|
|
6
6
|
variant: {
|
|
7
|
-
default: 'bg-primary text-primary-foreground hover:bg-primary/80
|
|
8
|
-
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80
|
|
9
|
-
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/80
|
|
7
|
+
default: 'border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80',
|
|
8
|
+
secondary: 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
|
9
|
+
destructive: 'border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80',
|
|
10
10
|
outline: 'text-foreground',
|
|
11
11
|
},
|
|
12
12
|
},
|
|
@@ -2,12 +2,12 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { cva } from 'class-variance-authority';
|
|
3
3
|
import { Slot } from 'radix-ui';
|
|
4
4
|
import { cn } from '../../lib/utils';
|
|
5
|
-
const buttonVariants = cva("
|
|
5
|
+
const buttonVariants = cva("inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
|
|
6
6
|
variants: {
|
|
7
7
|
variant: {
|
|
8
8
|
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
|
|
9
|
-
destructive: 'bg-destructive hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40
|
|
10
|
-
outline: 'bg-background hover:bg-accent hover:text-accent-foreground dark:
|
|
9
|
+
destructive: 'bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40',
|
|
10
|
+
outline: 'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50',
|
|
11
11
|
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
|
12
12
|
ghost: 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
|
|
13
13
|
link: 'text-primary underline-offset-4 hover:underline',
|
|
@@ -148,11 +148,11 @@ function SidebarMenu({ className, ...props }) {
|
|
|
148
148
|
function SidebarMenuItem({ className, ...props }) {
|
|
149
149
|
return (_jsx("li", { "data-slot": "sidebar-menu-item", "data-sidebar": "menu-item", className: cn('group/menu-item relative', className), ...props }));
|
|
150
150
|
}
|
|
151
|
-
const sidebarMenuButtonVariants = cva('peer/menu-button
|
|
151
|
+
const sidebarMenuButtonVariants = cva('peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0', {
|
|
152
152
|
variants: {
|
|
153
153
|
variant: {
|
|
154
154
|
default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',
|
|
155
|
-
outline: 'bg-background hover:bg-sidebar-accent hover:text-sidebar-accent-foreground
|
|
155
|
+
outline: 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',
|
|
156
156
|
},
|
|
157
157
|
size: {
|
|
158
158
|
default: 'h-8 text-sm',
|