@shepai/cli 1.29.1 → 1.31.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/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts +4 -0
- package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts +165 -0
- package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts.map +1 -0
- package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.js +34 -0
- package/dist/packages/core/src/application/ports/output/services/index.d.ts +2 -0
- package/dist/packages/core/src/application/ports/output/services/index.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/index.js +1 -0
- 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 +5 -0
- package/dist/packages/core/src/application/use-cases/features/create/types.d.ts +2 -0
- package/dist/packages/core/src/application/use-cases/features/create/types.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.js +3 -0
- package/dist/packages/core/src/domain/factories/settings-defaults.factory.d.ts.map +1 -1
- package/dist/packages/core/src/domain/factories/settings-defaults.factory.js +5 -0
- package/dist/packages/core/src/domain/generated/output.d.ts +70 -1
- package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
- package/dist/packages/core/src/domain/generated/output.js +15 -1
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +2 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts +10 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.js +24 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts +2 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.js +10 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.js +27 -0
- package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.js +18 -2
- package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.js +7 -3
- 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 +5 -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 +4 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts +148 -3
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.js +20 -5
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts +4 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.js +12 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts +4 -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 +29 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.d.ts +27 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.js +146 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts +5 -2
- 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 +9 -3
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/pr-yaml-generator.d.ts +17 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/pr-yaml-generator.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/pr-yaml-generator.js +43 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge.prompt.d.ts +17 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge.prompt.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge.prompt.js +42 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.d.ts +8 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.js +33 -0
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts +28 -0
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +182 -0
- package/dist/src/presentation/cli/commands/feat/new.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/feat/new.command.js +33 -2
- package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts +1 -0
- package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.js +70 -7
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -3
- 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 +9 -9
- package/web/.next/server/app/_not-found.segments/_full.segment.rsc +9 -9
- package/web/.next/server/app/_not-found.segments/_head.segment.rsc +3 -3
- package/web/.next/server/app/_not-found.segments/_index.segment.rsc +5 -5
- 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/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 +4 -4
- package/web/.next/server/app/version.segments/_full.segment.rsc +4 -4
- package/web/.next/server/app/version.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/version.segments/_index.segment.rsc +3 -3
- 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/403f9_next_dist_esm_build_templates_app-route_12059e3e.js +1 -1
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_12059e3e.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f12b60be._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.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/9993505b2a26c454.js +1 -0
- package/web/.next/trace +1 -1
- package/web/.next/trace-build +1 -1
- package/web/.next/static/chunks/b32b17f102226f32.js +0 -1
- /package/web/.next/static/{xfxn0ObmVPrJQ_jxVxePe → zHWQYn5H7ZmzuYWmx7b2E}/_buildManifest.js +0 -0
- /package/web/.next/static/{xfxn0ObmVPrJQ_jxVxePe → zHWQYn5H7ZmzuYWmx7b2E}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{xfxn0ObmVPrJQ_jxVxePe → zHWQYn5H7ZmzuYWmx7b2E}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git PR Service Implementation
|
|
3
|
+
*
|
|
4
|
+
* Manages git operations for PR creation, merging, and CI status checks.
|
|
5
|
+
* Uses constructor dependency injection for the command executor.
|
|
6
|
+
*/
|
|
7
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
8
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
10
|
+
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;
|
|
11
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
12
|
+
};
|
|
13
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
14
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
15
|
+
};
|
|
16
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
17
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
18
|
+
};
|
|
19
|
+
import { injectable, inject } from 'tsyringe';
|
|
20
|
+
import { GitPrError, GitPrErrorCode, } from '../../../application/ports/output/services/git-pr-service.interface.js';
|
|
21
|
+
let GitPrService = class GitPrService {
|
|
22
|
+
execFile;
|
|
23
|
+
constructor(execFile) {
|
|
24
|
+
this.execFile = execFile;
|
|
25
|
+
}
|
|
26
|
+
async hasUncommittedChanges(cwd) {
|
|
27
|
+
const { stdout } = await this.execFile('git', ['status', '--porcelain'], { cwd });
|
|
28
|
+
return stdout.trim().length > 0;
|
|
29
|
+
}
|
|
30
|
+
async commitAll(cwd, message) {
|
|
31
|
+
try {
|
|
32
|
+
await this.execFile('git', ['add', '-A'], { cwd });
|
|
33
|
+
await this.execFile('git', ['commit', '-m', message], { cwd });
|
|
34
|
+
const { stdout } = await this.execFile('git', ['rev-parse', 'HEAD'], { cwd });
|
|
35
|
+
return stdout.trim();
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
throw this.parseGitError(error);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async push(cwd, branch, setUpstream) {
|
|
42
|
+
const args = ['push'];
|
|
43
|
+
if (setUpstream)
|
|
44
|
+
args.push('--set-upstream');
|
|
45
|
+
args.push('origin', branch);
|
|
46
|
+
try {
|
|
47
|
+
await this.execFile('git', args, { cwd });
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
throw this.parseGitError(error);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async createPr(cwd, prYamlPath) {
|
|
54
|
+
try {
|
|
55
|
+
const { stdout } = await this.execFile('gh', ['pr', 'create', '--title', prYamlPath, '--body-file', prYamlPath], { cwd });
|
|
56
|
+
const url = stdout.trim();
|
|
57
|
+
const number = this.parsePrNumberFromUrl(url);
|
|
58
|
+
return { url, number };
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
throw this.parseGhError(error);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async mergePr(cwd, prNumber, strategy = 'squash') {
|
|
65
|
+
try {
|
|
66
|
+
await this.execFile('gh', ['pr', 'merge', String(prNumber), `--${strategy}`], { cwd });
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
70
|
+
const cause = error instanceof Error ? error : undefined;
|
|
71
|
+
throw new GitPrError(message, GitPrErrorCode.MERGE_FAILED, cause);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async mergeBranch(cwd, sourceBranch, targetBranch) {
|
|
75
|
+
try {
|
|
76
|
+
await this.execFile('git', ['checkout', targetBranch], { cwd });
|
|
77
|
+
await this.execFile('git', ['merge', sourceBranch], { cwd });
|
|
78
|
+
await this.execFile('git', ['push'], { cwd });
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
throw this.parseGitError(error);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async getCiStatus(cwd, branch) {
|
|
85
|
+
const { stdout } = await this.execFile('gh', ['run', 'list', '--branch', branch, '--json', 'conclusion,url', '--limit', '1'], { cwd });
|
|
86
|
+
const runs = JSON.parse(stdout);
|
|
87
|
+
if (runs.length === 0 || !runs[0].conclusion) {
|
|
88
|
+
return { status: 'pending', runUrl: runs[0]?.url };
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
status: runs[0].conclusion === 'success' ? 'success' : 'failure',
|
|
92
|
+
runUrl: runs[0].url,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
async watchCi(cwd, branch, timeoutMs) {
|
|
96
|
+
try {
|
|
97
|
+
const args = ['run', 'watch', '--branch', branch];
|
|
98
|
+
const { stdout } = await this.execFile('gh', args, {
|
|
99
|
+
cwd,
|
|
100
|
+
...(timeoutMs ? { timeout: timeoutMs } : {}),
|
|
101
|
+
});
|
|
102
|
+
const isSuccess = stdout.includes('success') || stdout.includes('completed');
|
|
103
|
+
return {
|
|
104
|
+
status: isSuccess ? 'success' : 'failure',
|
|
105
|
+
logExcerpt: stdout.trim(),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
110
|
+
const cause = error instanceof Error ? error : undefined;
|
|
111
|
+
if (message.includes('timed out') || message.includes('timeout')) {
|
|
112
|
+
throw new GitPrError(message, GitPrErrorCode.CI_TIMEOUT, cause);
|
|
113
|
+
}
|
|
114
|
+
throw new GitPrError(message, GitPrErrorCode.GIT_ERROR, cause);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async deleteBranch(cwd, branch, deleteRemote) {
|
|
118
|
+
try {
|
|
119
|
+
await this.execFile('git', ['branch', '-d', branch], { cwd });
|
|
120
|
+
if (deleteRemote) {
|
|
121
|
+
await this.execFile('git', ['push', 'origin', '--delete', branch], { cwd });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
throw this.parseGitError(error);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
async getPrDiffSummary(cwd, baseBranch) {
|
|
129
|
+
const { stdout: diffStat } = await this.execFile('git', ['diff', '--stat', `${baseBranch}...HEAD`], { cwd });
|
|
130
|
+
const { stdout: logOutput } = await this.execFile('git', ['log', '--oneline', `${baseBranch}...HEAD`], { cwd });
|
|
131
|
+
return this.parseDiffStat(diffStat, logOutput);
|
|
132
|
+
}
|
|
133
|
+
parseGitError(error) {
|
|
134
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
135
|
+
const cause = error instanceof Error ? error : undefined;
|
|
136
|
+
if (message.includes('rejected') || message.includes('conflict')) {
|
|
137
|
+
return new GitPrError(message, GitPrErrorCode.MERGE_CONFLICT, cause);
|
|
138
|
+
}
|
|
139
|
+
if (message.includes('Authentication') || message.includes('auth') || message.includes('403')) {
|
|
140
|
+
return new GitPrError(message, GitPrErrorCode.AUTH_FAILURE, cause);
|
|
141
|
+
}
|
|
142
|
+
return new GitPrError(message, GitPrErrorCode.GIT_ERROR, cause);
|
|
143
|
+
}
|
|
144
|
+
parseGhError(error) {
|
|
145
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
146
|
+
const cause = error instanceof Error ? error : undefined;
|
|
147
|
+
const errnoCode = error?.code;
|
|
148
|
+
if (errnoCode === 'ENOENT' || message.includes('ENOENT')) {
|
|
149
|
+
return new GitPrError(message, GitPrErrorCode.GH_NOT_FOUND, cause);
|
|
150
|
+
}
|
|
151
|
+
if (message.includes('Authentication') || message.includes('auth') || message.includes('403')) {
|
|
152
|
+
return new GitPrError(message, GitPrErrorCode.AUTH_FAILURE, cause);
|
|
153
|
+
}
|
|
154
|
+
return new GitPrError(message, GitPrErrorCode.GIT_ERROR, cause);
|
|
155
|
+
}
|
|
156
|
+
parsePrNumberFromUrl(url) {
|
|
157
|
+
const match = url.match(/\/pull\/(\d+)/);
|
|
158
|
+
return match ? parseInt(match[1], 10) : 0;
|
|
159
|
+
}
|
|
160
|
+
parseDiffStat(diffStat, logOutput) {
|
|
161
|
+
const summaryLine = diffStat.trim().split('\n').pop() ?? '';
|
|
162
|
+
const filesMatch = summaryLine.match(/(\d+)\s+files?\s+changed/);
|
|
163
|
+
const addMatch = summaryLine.match(/(\d+)\s+insertions?\(\+\)/);
|
|
164
|
+
const delMatch = summaryLine.match(/(\d+)\s+deletions?\(-\)/);
|
|
165
|
+
const commitCount = logOutput
|
|
166
|
+
.trim()
|
|
167
|
+
.split('\n')
|
|
168
|
+
.filter((l) => l.trim()).length;
|
|
169
|
+
return {
|
|
170
|
+
filesChanged: filesMatch ? parseInt(filesMatch[1], 10) : 0,
|
|
171
|
+
additions: addMatch ? parseInt(addMatch[1], 10) : 0,
|
|
172
|
+
deletions: delMatch ? parseInt(delMatch[1], 10) : 0,
|
|
173
|
+
commitCount,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
GitPrService = __decorate([
|
|
178
|
+
injectable(),
|
|
179
|
+
__param(0, inject('ExecFunction')),
|
|
180
|
+
__metadata("design:paramtypes", [Function])
|
|
181
|
+
], GitPrService);
|
|
182
|
+
export { GitPrService };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"new.command.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/feat/new.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"new.command.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/feat/new.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkCpC;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAsF1C"}
|
|
@@ -16,6 +16,20 @@ import { container } from '../../../../../packages/core/src/infrastructure/di/co
|
|
|
16
16
|
import { CreateFeatureUseCase } from '../../../../../packages/core/src/application/use-cases/features/create/create-feature.use-case.js';
|
|
17
17
|
import { colors, messages, spinner } from '../../ui/index.js';
|
|
18
18
|
import { getShepHomeDir } from '../../../../../packages/core/src/infrastructure/services/filesystem/shep-directory.service.js';
|
|
19
|
+
import { getSettings, hasSettings } from '../../../../../packages/core/src/infrastructure/services/settings.service.js';
|
|
20
|
+
/**
|
|
21
|
+
* Read workflow defaults from settings, falling back to false if settings unavailable.
|
|
22
|
+
*/
|
|
23
|
+
function getWorkflowDefaults() {
|
|
24
|
+
if (!hasSettings()) {
|
|
25
|
+
return { openPr: false, autoMerge: false };
|
|
26
|
+
}
|
|
27
|
+
const settings = getSettings();
|
|
28
|
+
return {
|
|
29
|
+
openPr: settings.workflow.openPrOnImplementationComplete,
|
|
30
|
+
autoMerge: settings.workflow.autoMergeOnImplementationComplete,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
19
33
|
/**
|
|
20
34
|
* Create the feat new command
|
|
21
35
|
*/
|
|
@@ -24,26 +38,43 @@ export function createNewCommand() {
|
|
|
24
38
|
.description('Create a new feature')
|
|
25
39
|
.argument('<description>', 'Feature description')
|
|
26
40
|
.option('-r, --repo <path>', 'Repository path (defaults to current directory)')
|
|
41
|
+
.option('--pr', 'Open PR on implementation complete')
|
|
42
|
+
.option('--no-pr', 'Do not open PR on implementation complete')
|
|
43
|
+
.option('--auto-merge', 'Auto-merge on implementation complete')
|
|
44
|
+
.option('--no-auto-merge', 'Do not auto-merge on implementation complete')
|
|
27
45
|
.option('--allow-prd', 'Auto-approve through requirements, pause after')
|
|
28
46
|
.option('--allow-plan', 'Auto-approve through planning, pause at implementation')
|
|
47
|
+
.option('--allow-merge', 'Auto-approve merge phase')
|
|
29
48
|
.option('--allow-all', 'Run fully autonomous (no approval pauses)')
|
|
30
49
|
.action(async (description, options) => {
|
|
31
50
|
try {
|
|
32
51
|
const useCase = container.resolve(CreateFeatureUseCase);
|
|
33
52
|
const repoPath = options.repo ?? process.cwd();
|
|
53
|
+
// Resolve openPr and autoMerge from CLI flags or settings defaults
|
|
54
|
+
const defaults = getWorkflowDefaults();
|
|
55
|
+
const openPr = options.pr ?? defaults.openPr;
|
|
56
|
+
const autoMerge = options.autoMerge ?? defaults.autoMerge;
|
|
34
57
|
// Build approval gates from flags (default: pause after every phase)
|
|
35
58
|
let approvalGates = {
|
|
36
59
|
allowPrd: !!options.allowPrd,
|
|
37
60
|
allowPlan: !!options.allowPlan,
|
|
38
61
|
allowMerge: false,
|
|
39
62
|
};
|
|
40
|
-
if (options.
|
|
63
|
+
if (options.allowPlan)
|
|
64
|
+
approvalGates = { allowPrd: true, allowPlan: true, allowMerge: approvalGates.allowMerge };
|
|
65
|
+
if (options.allowMerge)
|
|
66
|
+
approvalGates = { ...approvalGates, allowMerge: true };
|
|
67
|
+
// --auto-merge implies --allow-merge
|
|
68
|
+
if (autoMerge)
|
|
69
|
+
approvalGates = { ...approvalGates, allowMerge: true };
|
|
70
|
+
if (options.allowAll)
|
|
41
71
|
approvalGates = undefined; // no gates = fully autonomous
|
|
42
|
-
}
|
|
43
72
|
const result = await spinner('Thinking', () => useCase.execute({
|
|
44
73
|
userInput: description,
|
|
45
74
|
repositoryPath: repoPath,
|
|
46
75
|
approvalGates,
|
|
76
|
+
openPr,
|
|
77
|
+
autoMerge,
|
|
47
78
|
}));
|
|
48
79
|
const { feature, warning } = result;
|
|
49
80
|
const repoHash = createHash('sha256').update(repoPath).digest('hex').slice(0, 16);
|
|
@@ -6,6 +6,7 @@ type Story = StoryObj<FeatureNodeData>;
|
|
|
6
6
|
export declare const Default: Story;
|
|
7
7
|
export declare const AllStates: Story;
|
|
8
8
|
export declare const AllLifecycles: Story;
|
|
9
|
+
export declare const AllAgentTypes: Story;
|
|
9
10
|
export declare const WithAction: Story;
|
|
10
11
|
export declare const LongContent: Story;
|
|
11
12
|
export declare const DoneWithRuntime: Story;
|
package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-node.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"feature-node.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAKvD,OAAO,KAAK,EACV,eAAe,EAIhB,MAAM,6BAA6B,CAAC;AAiCrC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,eAAe,CAc/B,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAC;AAEvC,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AA0DF,eAAO,MAAM,SAAS,EAAE,KAQvB,CAAC;AAWF,eAAO,MAAM,aAAa,EAAE,KAqB3B,CAAC;AAsEF,eAAO,MAAM,aAAa,EAAE,KAQ3B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAMxB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAW7B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AA4EF,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC"}
|
|
@@ -22,14 +22,10 @@ const meta = {
|
|
|
22
22
|
lifecycle: 'requirements',
|
|
23
23
|
state: 'running',
|
|
24
24
|
progress: 45,
|
|
25
|
-
agentName: 'Planner',
|
|
26
25
|
},
|
|
27
26
|
};
|
|
28
27
|
export default meta;
|
|
29
28
|
export const Default = {
|
|
30
|
-
args: {
|
|
31
|
-
agentName: 'claude-code',
|
|
32
|
-
},
|
|
33
29
|
render: (args) => _jsx(FeatureNodeCanvas, { data: args }),
|
|
34
30
|
};
|
|
35
31
|
const allStatesData = [
|
|
@@ -40,7 +36,6 @@ const allStatesData = [
|
|
|
40
36
|
lifecycle: 'implementation',
|
|
41
37
|
state: 'running',
|
|
42
38
|
progress: 45,
|
|
43
|
-
agentName: 'Planner',
|
|
44
39
|
repositoryPath: '/home/user/my-repo',
|
|
45
40
|
branch: 'feat/auth-module',
|
|
46
41
|
},
|
|
@@ -107,11 +102,80 @@ export const AllLifecycles = {
|
|
|
107
102
|
lifecycle,
|
|
108
103
|
state: 'running',
|
|
109
104
|
progress: [10, 25, 50, 70, 90, 100][i],
|
|
110
|
-
agentName: 'Researcher',
|
|
111
105
|
repositoryPath: '/home/user/my-repo',
|
|
112
106
|
branch: 'feat/feature-name',
|
|
113
107
|
} }, lifecycle))) })),
|
|
114
108
|
};
|
|
109
|
+
const allAgentTypesData = [
|
|
110
|
+
{
|
|
111
|
+
name: 'Claude Code Agent',
|
|
112
|
+
description: 'Running with Claude Code executor',
|
|
113
|
+
featureId: '#a1',
|
|
114
|
+
lifecycle: 'implementation',
|
|
115
|
+
state: 'running',
|
|
116
|
+
progress: 50,
|
|
117
|
+
agentType: 'claude-code',
|
|
118
|
+
repositoryPath: '/home/user/my-repo',
|
|
119
|
+
branch: 'feat/claude-code',
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: 'Cursor Agent',
|
|
123
|
+
description: 'Running with Cursor executor',
|
|
124
|
+
featureId: '#a2',
|
|
125
|
+
lifecycle: 'implementation',
|
|
126
|
+
state: 'running',
|
|
127
|
+
progress: 50,
|
|
128
|
+
agentType: 'cursor',
|
|
129
|
+
repositoryPath: '/home/user/my-repo',
|
|
130
|
+
branch: 'feat/cursor',
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: 'Gemini CLI Agent',
|
|
134
|
+
description: 'Running with Gemini CLI executor',
|
|
135
|
+
featureId: '#a3',
|
|
136
|
+
lifecycle: 'implementation',
|
|
137
|
+
state: 'running',
|
|
138
|
+
progress: 50,
|
|
139
|
+
agentType: 'gemini-cli',
|
|
140
|
+
repositoryPath: '/home/user/my-repo',
|
|
141
|
+
branch: 'feat/gemini-cli',
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: 'Aider Agent',
|
|
145
|
+
description: 'Running with Aider executor',
|
|
146
|
+
featureId: '#a4',
|
|
147
|
+
lifecycle: 'implementation',
|
|
148
|
+
state: 'running',
|
|
149
|
+
progress: 50,
|
|
150
|
+
agentType: 'aider',
|
|
151
|
+
repositoryPath: '/home/user/my-repo',
|
|
152
|
+
branch: 'feat/aider',
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
name: 'Continue Agent',
|
|
156
|
+
description: 'Running with Continue executor',
|
|
157
|
+
featureId: '#a5',
|
|
158
|
+
lifecycle: 'implementation',
|
|
159
|
+
state: 'running',
|
|
160
|
+
progress: 50,
|
|
161
|
+
agentType: 'continue',
|
|
162
|
+
repositoryPath: '/home/user/my-repo',
|
|
163
|
+
branch: 'feat/continue',
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
name: 'Default (No Agent)',
|
|
167
|
+
description: 'Running with no agent type set',
|
|
168
|
+
featureId: '#a6',
|
|
169
|
+
lifecycle: 'implementation',
|
|
170
|
+
state: 'running',
|
|
171
|
+
progress: 50,
|
|
172
|
+
repositoryPath: '/home/user/my-repo',
|
|
173
|
+
branch: 'feat/default',
|
|
174
|
+
},
|
|
175
|
+
];
|
|
176
|
+
export const AllAgentTypes = {
|
|
177
|
+
render: () => (_jsx("div", { className: "flex flex-wrap gap-6", children: allAgentTypesData.map((data) => (_jsx(FeatureNodeCanvas, { style: { width: 500, height: 350 }, data: data }, data.featureId))) })),
|
|
178
|
+
};
|
|
115
179
|
export const WithAction = {
|
|
116
180
|
argTypes: {
|
|
117
181
|
onAction: { action: 'onAction' },
|
|
@@ -175,7 +239,6 @@ const interactiveInitialNodes = [
|
|
|
175
239
|
lifecycle: 'implementation',
|
|
176
240
|
state: 'running',
|
|
177
241
|
progress: 45,
|
|
178
|
-
agentName: 'Planner',
|
|
179
242
|
repositoryPath: '/home/user/my-repo',
|
|
180
243
|
branch: 'feat/auth-module',
|
|
181
244
|
},
|