@shepai/cli 1.38.0 → 1.40.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 +1 -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/use-cases/agents/approve-agent-run.use-case.d.ts +5 -4
- package/dist/packages/core/src/application/use-cases/agents/approve-agent-run.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/agents/approve-agent-run.use-case.js +36 -14
- package/dist/packages/core/src/application/use-cases/agents/reject-agent-run.use-case.d.ts +12 -3
- package/dist/packages/core/src/application/use-cases/agents/reject-agent-run.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/agents/reject-agent-run.use-case.js +88 -8
- package/dist/packages/core/src/application/use-cases/agents/review-feature.use-case.d.ts +35 -0
- package/dist/packages/core/src/application/use-cases/agents/review-feature.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/agents/review-feature.use-case.js +88 -0
- package/dist/packages/core/src/domain/generated/output.d.ts +102 -0
- package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -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/services/agents/common/agent-executor-factory.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-factory.service.js +5 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/agent-validator.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/agent-validator.service.js +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/gemini-cli-executor.service.d.ts +52 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/gemini-cli-executor.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/gemini-cli-executor.service.js +337 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts +51 -0
- 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 +21 -2
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts +1 -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 +3 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts +1 -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 +31 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts +19 -3
- 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 +101 -16
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/requirements.prompt.d.ts +2 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/requirements.prompt.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/requirements.prompt.js +53 -27
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/phase-timing-context.d.ts +3 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/phase-timing-context.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/phase-timing-context.js +28 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.d.ts +3 -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 +13 -0
- package/dist/src/presentation/cli/commands/agent/reject.command.js +1 -1
- package/dist/src/presentation/cli/commands/feat/reject.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/feat/reject.command.js +6 -4
- package/dist/src/presentation/cli/commands/feat/review.command.d.ts +3 -2
- package/dist/src/presentation/cli/commands/feat/review.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/feat/review.command.js +87 -12
- package/dist/src/presentation/cli/commands/feat/show.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/feat/show.command.js +38 -3
- package/dist/src/presentation/tui/prompts/agent-select.prompt.d.ts +1 -1
- package/dist/src/presentation/tui/prompts/agent-select.prompt.js +1 -1
- package/dist/src/presentation/tui/prompts/prd-review-question.prompt.d.ts +30 -0
- package/dist/src/presentation/tui/prompts/prd-review-question.prompt.d.ts.map +1 -0
- package/dist/src/presentation/tui/prompts/prd-review-question.prompt.js +23 -0
- package/dist/src/presentation/tui/prompts/prd-review-summary.prompt.d.ts +29 -0
- package/dist/src/presentation/tui/prompts/prd-review-summary.prompt.d.ts.map +1 -0
- package/dist/src/presentation/tui/prompts/prd-review-summary.prompt.js +29 -0
- package/dist/src/presentation/tui/wizards/merge-review.wizard.d.ts +13 -0
- package/dist/src/presentation/tui/wizards/merge-review.wizard.d.ts.map +1 -0
- package/dist/src/presentation/tui/wizards/merge-review.wizard.js +43 -0
- package/dist/src/presentation/tui/wizards/plan-review.wizard.d.ts +13 -0
- package/dist/src/presentation/tui/wizards/plan-review.wizard.d.ts.map +1 -0
- package/dist/src/presentation/tui/wizards/plan-review.wizard.js +43 -0
- package/dist/src/presentation/tui/wizards/prd-review.wizard.d.ts +26 -0
- package/dist/src/presentation/tui/wizards/prd-review.wizard.d.ts.map +1 -0
- package/dist/src/presentation/tui/wizards/prd-review.wizard.js +42 -0
- 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/page/server-reference-manifest.json +9 -9
- package/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__19354aea._.js +2 -2
- 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.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js.map +1 -1
- package/web/.next/server/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +10 -10
- 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/page/server-reference-manifest.json +9 -9
- package/web/.next/standalone/src/presentation/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__19354aea._.js +2 -2
- 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 +10 -10
- package/web/.next/standalone/src/presentation/web/server.js +1 -1
- package/web/.next/static/chunks/{eca1959e083d0a45.js → 8bea0ce8a07abd50.js} +1 -1
- package/web/.next/trace +1 -1
- package/web/.next/trace-build +1 -1
- /package/web/.next/static/{yvV-GEMagQiZhZAF0YqQs → o1NQgNmvCnthgfg2Ubmf_}/_buildManifest.js +0 -0
- /package/web/.next/static/{yvV-GEMagQiZhZAF0YqQs → o1NQgNmvCnthgfg2Ubmf_}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{yvV-GEMagQiZhZAF0YqQs → o1NQgNmvCnthgfg2Ubmf_}/_ssgManifest.js +0 -0
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts
CHANGED
|
@@ -35,6 +35,9 @@ export declare function createFeatureAgentGraph(depsOrExecutor: FeatureAgentGrap
|
|
|
35
35
|
validationRetries: number;
|
|
36
36
|
lastValidationTarget: string;
|
|
37
37
|
lastValidationErrors: string[];
|
|
38
|
+
_approvalAction: string | null;
|
|
39
|
+
_rejectionFeedback: string | null;
|
|
40
|
+
_needsReexecution: boolean;
|
|
38
41
|
prUrl: string | null;
|
|
39
42
|
prNumber: number | null;
|
|
40
43
|
commitHash: string | null;
|
|
@@ -53,6 +56,9 @@ export declare function createFeatureAgentGraph(depsOrExecutor: FeatureAgentGrap
|
|
|
53
56
|
validationRetries?: number | undefined;
|
|
54
57
|
lastValidationTarget?: string | undefined;
|
|
55
58
|
lastValidationErrors?: string[] | undefined;
|
|
59
|
+
_approvalAction?: string | null | undefined;
|
|
60
|
+
_rejectionFeedback?: string | null | undefined;
|
|
61
|
+
_needsReexecution?: boolean | undefined;
|
|
56
62
|
prUrl?: string | null | undefined;
|
|
57
63
|
prNumber?: number | null | undefined;
|
|
58
64
|
commitHash?: string | null | undefined;
|
|
@@ -91,6 +97,9 @@ export declare function createFeatureAgentGraph(depsOrExecutor: FeatureAgentGrap
|
|
|
91
97
|
validationRetries: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
92
98
|
lastValidationTarget: import("@langchain/langgraph").BinaryOperatorAggregate<string, string>;
|
|
93
99
|
lastValidationErrors: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
100
|
+
_approvalAction: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
101
|
+
_rejectionFeedback: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
102
|
+
_needsReexecution: import("@langchain/langgraph").BinaryOperatorAggregate<boolean, boolean>;
|
|
94
103
|
prUrl: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
95
104
|
prNumber: import("@langchain/langgraph").BinaryOperatorAggregate<number | null, number | null>;
|
|
96
105
|
commitHash: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
@@ -129,6 +138,9 @@ export declare function createFeatureAgentGraph(depsOrExecutor: FeatureAgentGrap
|
|
|
129
138
|
validationRetries: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
130
139
|
lastValidationTarget: import("@langchain/langgraph").BinaryOperatorAggregate<string, string>;
|
|
131
140
|
lastValidationErrors: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
141
|
+
_approvalAction: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
142
|
+
_rejectionFeedback: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
143
|
+
_needsReexecution: import("@langchain/langgraph").BinaryOperatorAggregate<boolean, boolean>;
|
|
132
144
|
prUrl: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
133
145
|
prNumber: import("@langchain/langgraph").BinaryOperatorAggregate<number | null, number | null>;
|
|
134
146
|
commitHash: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
@@ -168,6 +180,9 @@ export declare function createFeatureAgentGraph(depsOrExecutor: FeatureAgentGrap
|
|
|
168
180
|
validationRetries: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
169
181
|
lastValidationTarget: import("@langchain/langgraph").BinaryOperatorAggregate<string, string>;
|
|
170
182
|
lastValidationErrors: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
183
|
+
_approvalAction: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
184
|
+
_rejectionFeedback: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
185
|
+
_needsReexecution: import("@langchain/langgraph").BinaryOperatorAggregate<boolean, boolean>;
|
|
171
186
|
prUrl: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
172
187
|
prNumber: import("@langchain/langgraph").BinaryOperatorAggregate<number | null, number | null>;
|
|
173
188
|
commitHash: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
@@ -207,6 +222,9 @@ export declare function createFeatureAgentGraph(depsOrExecutor: FeatureAgentGrap
|
|
|
207
222
|
validationRetries: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
208
223
|
lastValidationTarget: import("@langchain/langgraph").BinaryOperatorAggregate<string, string>;
|
|
209
224
|
lastValidationErrors: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
225
|
+
_approvalAction: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
226
|
+
_rejectionFeedback: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
227
|
+
_needsReexecution: import("@langchain/langgraph").BinaryOperatorAggregate<boolean, boolean>;
|
|
210
228
|
prUrl: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
211
229
|
prNumber: import("@langchain/langgraph").BinaryOperatorAggregate<number | null, number | null>;
|
|
212
230
|
commitHash: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
@@ -246,6 +264,9 @@ export declare function createFeatureAgentGraph(depsOrExecutor: FeatureAgentGrap
|
|
|
246
264
|
validationRetries: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
247
265
|
lastValidationTarget: import("@langchain/langgraph").BinaryOperatorAggregate<string, string>;
|
|
248
266
|
lastValidationErrors: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
267
|
+
_approvalAction: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
268
|
+
_rejectionFeedback: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
269
|
+
_needsReexecution: import("@langchain/langgraph").BinaryOperatorAggregate<boolean, boolean>;
|
|
249
270
|
prUrl: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
250
271
|
prNumber: import("@langchain/langgraph").BinaryOperatorAggregate<number | null, number | null>;
|
|
251
272
|
commitHash: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
@@ -285,6 +306,9 @@ export declare function createFeatureAgentGraph(depsOrExecutor: FeatureAgentGrap
|
|
|
285
306
|
validationRetries: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
286
307
|
lastValidationTarget: import("@langchain/langgraph").BinaryOperatorAggregate<string, string>;
|
|
287
308
|
lastValidationErrors: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
309
|
+
_approvalAction: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
310
|
+
_rejectionFeedback: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
311
|
+
_needsReexecution: import("@langchain/langgraph").BinaryOperatorAggregate<boolean, boolean>;
|
|
288
312
|
prUrl: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
289
313
|
prNumber: import("@langchain/langgraph").BinaryOperatorAggregate<number | null, number | null>;
|
|
290
314
|
commitHash: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
@@ -324,6 +348,9 @@ export declare function createFeatureAgentGraph(depsOrExecutor: FeatureAgentGrap
|
|
|
324
348
|
validationRetries: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
325
349
|
lastValidationTarget: import("@langchain/langgraph").BinaryOperatorAggregate<string, string>;
|
|
326
350
|
lastValidationErrors: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
351
|
+
_approvalAction: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
352
|
+
_rejectionFeedback: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
353
|
+
_needsReexecution: import("@langchain/langgraph").BinaryOperatorAggregate<boolean, boolean>;
|
|
327
354
|
prUrl: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
328
355
|
prNumber: import("@langchain/langgraph").BinaryOperatorAggregate<number | null, number | null>;
|
|
329
356
|
commitHash: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
@@ -363,6 +390,9 @@ export declare function createFeatureAgentGraph(depsOrExecutor: FeatureAgentGrap
|
|
|
363
390
|
validationRetries: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
364
391
|
lastValidationTarget: import("@langchain/langgraph").BinaryOperatorAggregate<string, string>;
|
|
365
392
|
lastValidationErrors: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
393
|
+
_approvalAction: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
394
|
+
_rejectionFeedback: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
395
|
+
_needsReexecution: import("@langchain/langgraph").BinaryOperatorAggregate<boolean, boolean>;
|
|
366
396
|
prUrl: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
367
397
|
prNumber: import("@langchain/langgraph").BinaryOperatorAggregate<number | null, number | null>;
|
|
368
398
|
commitHash: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
@@ -402,6 +432,9 @@ export declare function createFeatureAgentGraph(depsOrExecutor: FeatureAgentGrap
|
|
|
402
432
|
validationRetries: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
403
433
|
lastValidationTarget: import("@langchain/langgraph").BinaryOperatorAggregate<string, string>;
|
|
404
434
|
lastValidationErrors: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
435
|
+
_approvalAction: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
436
|
+
_rejectionFeedback: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
437
|
+
_needsReexecution: import("@langchain/langgraph").BinaryOperatorAggregate<boolean, boolean>;
|
|
405
438
|
prUrl: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
406
439
|
prNumber: import("@langchain/langgraph").BinaryOperatorAggregate<number | null, number | null>;
|
|
407
440
|
commitHash: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
@@ -441,6 +474,9 @@ export declare function createFeatureAgentGraph(depsOrExecutor: FeatureAgentGrap
|
|
|
441
474
|
validationRetries: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
442
475
|
lastValidationTarget: import("@langchain/langgraph").BinaryOperatorAggregate<string, string>;
|
|
443
476
|
lastValidationErrors: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
477
|
+
_approvalAction: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
478
|
+
_rejectionFeedback: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
479
|
+
_needsReexecution: import("@langchain/langgraph").BinaryOperatorAggregate<boolean, boolean>;
|
|
444
480
|
prUrl: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
445
481
|
prNumber: import("@langchain/langgraph").BinaryOperatorAggregate<number | null, number | null>;
|
|
446
482
|
commitHash: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
@@ -480,6 +516,9 @@ export declare function createFeatureAgentGraph(depsOrExecutor: FeatureAgentGrap
|
|
|
480
516
|
validationRetries: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
481
517
|
lastValidationTarget: import("@langchain/langgraph").BinaryOperatorAggregate<string, string>;
|
|
482
518
|
lastValidationErrors: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
519
|
+
_approvalAction: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
520
|
+
_rejectionFeedback: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
521
|
+
_needsReexecution: import("@langchain/langgraph").BinaryOperatorAggregate<boolean, boolean>;
|
|
483
522
|
prUrl: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
484
523
|
prNumber: import("@langchain/langgraph").BinaryOperatorAggregate<number | null, number | null>;
|
|
485
524
|
commitHash: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
@@ -519,6 +558,9 @@ export declare function createFeatureAgentGraph(depsOrExecutor: FeatureAgentGrap
|
|
|
519
558
|
validationRetries: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
520
559
|
lastValidationTarget: import("@langchain/langgraph").BinaryOperatorAggregate<string, string>;
|
|
521
560
|
lastValidationErrors: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
561
|
+
_approvalAction: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
562
|
+
_rejectionFeedback: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
563
|
+
_needsReexecution: import("@langchain/langgraph").BinaryOperatorAggregate<boolean, boolean>;
|
|
522
564
|
prUrl: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
523
565
|
prNumber: import("@langchain/langgraph").BinaryOperatorAggregate<number | null, number | null>;
|
|
524
566
|
commitHash: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
@@ -558,6 +600,9 @@ export declare function createFeatureAgentGraph(depsOrExecutor: FeatureAgentGrap
|
|
|
558
600
|
validationRetries: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
559
601
|
lastValidationTarget: import("@langchain/langgraph").BinaryOperatorAggregate<string, string>;
|
|
560
602
|
lastValidationErrors: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
603
|
+
_approvalAction: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
604
|
+
_rejectionFeedback: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
605
|
+
_needsReexecution: import("@langchain/langgraph").BinaryOperatorAggregate<boolean, boolean>;
|
|
561
606
|
prUrl: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
562
607
|
prNumber: import("@langchain/langgraph").BinaryOperatorAggregate<number | null, number | null>;
|
|
563
608
|
commitHash: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
@@ -597,6 +642,9 @@ export declare function createFeatureAgentGraph(depsOrExecutor: FeatureAgentGrap
|
|
|
597
642
|
validationRetries: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
598
643
|
lastValidationTarget: import("@langchain/langgraph").BinaryOperatorAggregate<string, string>;
|
|
599
644
|
lastValidationErrors: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
645
|
+
_approvalAction: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
646
|
+
_rejectionFeedback: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
647
|
+
_needsReexecution: import("@langchain/langgraph").BinaryOperatorAggregate<boolean, boolean>;
|
|
600
648
|
prUrl: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
601
649
|
prNumber: import("@langchain/langgraph").BinaryOperatorAggregate<number | null, number | null>;
|
|
602
650
|
commitHash: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
@@ -636,6 +684,9 @@ export declare function createFeatureAgentGraph(depsOrExecutor: FeatureAgentGrap
|
|
|
636
684
|
validationRetries: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
637
685
|
lastValidationTarget: import("@langchain/langgraph").BinaryOperatorAggregate<string, string>;
|
|
638
686
|
lastValidationErrors: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
687
|
+
_approvalAction: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
688
|
+
_rejectionFeedback: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
689
|
+
_needsReexecution: import("@langchain/langgraph").BinaryOperatorAggregate<boolean, boolean>;
|
|
639
690
|
prUrl: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
640
691
|
prNumber: import("@langchain/langgraph").BinaryOperatorAggregate<number | null, number | null>;
|
|
641
692
|
commitHash: import("@langchain/langgraph").BinaryOperatorAggregate<string | null, string | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-agent-graph.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AAOpG,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAS5E,OAAO,EAAE,sBAAsB,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE5E;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,cAAc,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;CAC9B;
|
|
1
|
+
{"version":3,"file":"feature-agent-graph.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AAOpG,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAS5E,OAAO,EAAE,sBAAsB,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE5E;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,cAAc,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;CAC9B;AAyHD;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACrC,cAAc,EAAE,qBAAqB,GAAG,cAAc,EACtD,YAAY,CAAC,EAAE,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBA0EnC"}
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.js
CHANGED
|
@@ -14,6 +14,21 @@ import { validatePlan, validateTasks } from './nodes/schemas/plan.schema.js';
|
|
|
14
14
|
import { readSpecFile, safeYamlLoad, createNodeLogger } from './nodes/node-helpers.js';
|
|
15
15
|
// Re-export state types for consumers
|
|
16
16
|
export { FeatureAgentAnnotation } from './state.js';
|
|
17
|
+
/**
|
|
18
|
+
* Factory that creates a conditional edge function for re-execution routing.
|
|
19
|
+
*
|
|
20
|
+
* After an interruptible node resumes, it returns early with _needsReexecution
|
|
21
|
+
* set to true (rejection) or false (approval). This edge routes back to the
|
|
22
|
+
* same node on rejection for a fresh invocation, avoiding the stale interrupt
|
|
23
|
+
* replay bug caused by dual interrupt() calls.
|
|
24
|
+
*/
|
|
25
|
+
function routeReexecution(selfNode, nextNode) {
|
|
26
|
+
return (state) => {
|
|
27
|
+
if (state._needsReexecution)
|
|
28
|
+
return selfNode;
|
|
29
|
+
return nextNode;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
17
32
|
/**
|
|
18
33
|
* Factory that creates a conditional edge function for validation routing.
|
|
19
34
|
*
|
|
@@ -141,17 +156,21 @@ export function createFeatureAgentGraph(depsOrExecutor, checkpointer) {
|
|
|
141
156
|
.addNode('repair_research', createRepairNode('research.yaml', executor))
|
|
142
157
|
.addNode('repair_plan_tasks', createRepairNode(['plan.yaml', 'tasks.yaml'], executor))
|
|
143
158
|
// --- Edges: linear flow with validation gates ---
|
|
159
|
+
// Interruptible nodes (requirements, plan) use conditional edges that
|
|
160
|
+
// check _needsReexecution to loop back on rejection. This ensures each
|
|
161
|
+
// re-execution is a fresh node invocation with a clean interrupt index,
|
|
162
|
+
// avoiding the stale interrupt replay bug with dual interrupt() calls.
|
|
144
163
|
.addEdge(START, 'analyze')
|
|
145
164
|
.addEdge('analyze', 'validate_spec_analyze')
|
|
146
165
|
.addConditionalEdges('validate_spec_analyze', routeValidation('requirements', 'repair_spec_analyze'))
|
|
147
166
|
.addEdge('repair_spec_analyze', 'validate_spec_analyze')
|
|
148
|
-
.
|
|
167
|
+
.addConditionalEdges('requirements', routeReexecution('requirements', 'validate_spec_requirements'))
|
|
149
168
|
.addConditionalEdges('validate_spec_requirements', routeValidation('research', 'repair_spec_requirements'))
|
|
150
169
|
.addEdge('repair_spec_requirements', 'validate_spec_requirements')
|
|
151
170
|
.addEdge('research', 'validate_research')
|
|
152
171
|
.addConditionalEdges('validate_research', routeValidation('plan', 'repair_research'))
|
|
153
172
|
.addEdge('repair_research', 'validate_research')
|
|
154
|
-
.
|
|
173
|
+
.addConditionalEdges('plan', routeReexecution('plan', 'validate_plan_tasks'))
|
|
155
174
|
.addConditionalEdges('validate_plan_tasks', routeValidation('implement', 'repair_plan_tasks'))
|
|
156
175
|
.addEdge('repair_plan_tasks', 'validate_plan_tasks');
|
|
157
176
|
// --- Merge node: wired when deps are provided ---
|
|
@@ -18,6 +18,7 @@ export declare class FeatureAgentProcessService implements IFeatureAgentProcessS
|
|
|
18
18
|
resumeFromInterrupt?: boolean;
|
|
19
19
|
push?: boolean;
|
|
20
20
|
openPr?: boolean;
|
|
21
|
+
resumePayload?: string;
|
|
21
22
|
}): number;
|
|
22
23
|
isAlive(pid: number): boolean;
|
|
23
24
|
checkAndMarkCrashed(runId: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-agent-process.service.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,sEAAsE,CAAC;AACxH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qEAAqE,CAAC;AAC/G,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAYlF,qBAAa,0BAA2B,YAAW,2BAA2B;IAChE,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAAb,aAAa,EAAE,mBAAmB;IAE/D,KAAK,CACH,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE;QACR,aAAa,CAAC,EAAE,aAAa,CAAC;QAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,MAAM,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"feature-agent-process.service.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,sEAAsE,CAAC;AACxH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qEAAqE,CAAC;AAC/G,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAYlF,qBAAa,0BAA2B,YAAW,2BAA2B;IAChE,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAAb,aAAa,EAAE,mBAAmB;IAE/D,KAAK,CACH,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE;QACR,aAAa,CAAC,EAAE,aAAa,CAAC;QAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,GACA,MAAM;IA0DT,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IASvB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAexD"}
|
|
@@ -59,6 +59,9 @@ export class FeatureAgentProcessService {
|
|
|
59
59
|
if (options?.openPr) {
|
|
60
60
|
args.push('--open-pr');
|
|
61
61
|
}
|
|
62
|
+
if (options?.resumePayload) {
|
|
63
|
+
args.push('--resume-payload', options.resumePayload);
|
|
64
|
+
}
|
|
62
65
|
// Create log file for worker output (for debugging)
|
|
63
66
|
const logsDir = join(homedir(), '.shep', 'logs');
|
|
64
67
|
mkdirSync(logsDir, { recursive: true });
|
|
@@ -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;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;
|
|
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;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAoD1D;AAgCD;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAkM/D"}
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js
CHANGED
|
@@ -53,6 +53,10 @@ export function parseWorkerArgs(args) {
|
|
|
53
53
|
const openPr = args.includes('--open-pr');
|
|
54
54
|
const threadIdx = args.indexOf('--thread-id');
|
|
55
55
|
const threadId = threadIdx !== -1 && threadIdx + 1 < args.length ? args[threadIdx + 1] : undefined;
|
|
56
|
+
const resumePayloadIdx = args.indexOf('--resume-payload');
|
|
57
|
+
const resumePayload = resumePayloadIdx !== -1 && resumePayloadIdx + 1 < args.length
|
|
58
|
+
? args[resumePayloadIdx + 1]
|
|
59
|
+
: undefined;
|
|
56
60
|
return {
|
|
57
61
|
featureId: getArg('feature-id'),
|
|
58
62
|
runId: getArg('run-id'),
|
|
@@ -65,6 +69,7 @@ export function parseWorkerArgs(args) {
|
|
|
65
69
|
resumeFromInterrupt,
|
|
66
70
|
push,
|
|
67
71
|
openPr,
|
|
72
|
+
resumePayload,
|
|
68
73
|
};
|
|
69
74
|
}
|
|
70
75
|
/** Simple worker logger — writes to stdout which is redirected to log file by the parent. */
|
|
@@ -163,8 +168,33 @@ export async function runWorker(args) {
|
|
|
163
168
|
let result;
|
|
164
169
|
if (args.resume && args.resumeFromInterrupt) {
|
|
165
170
|
// Resume from an interrupt (human-in-the-loop approval)
|
|
171
|
+
let resumeValue = { approved: true }; // default backward-compatible
|
|
172
|
+
if (args.resumePayload) {
|
|
173
|
+
try {
|
|
174
|
+
resumeValue = JSON.parse(args.resumePayload);
|
|
175
|
+
log(`Resuming with typed payload: ${args.resumePayload.slice(0, 200)}`);
|
|
176
|
+
}
|
|
177
|
+
catch (e) {
|
|
178
|
+
log(`Warning: Failed to parse --resume-payload, using default approval: ${e}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Derive state updates from the resume payload so executeNode() can
|
|
182
|
+
// read _approvalAction from state instead of from interrupt() return
|
|
183
|
+
// value (fixes the dual-interrupt stale replay bug).
|
|
184
|
+
const stateUpdate = {};
|
|
185
|
+
if (typeof resumeValue === 'object' &&
|
|
186
|
+
resumeValue !== null &&
|
|
187
|
+
'rejected' in resumeValue &&
|
|
188
|
+
resumeValue.rejected === true) {
|
|
189
|
+
stateUpdate._approvalAction = 'rejected';
|
|
190
|
+
stateUpdate._rejectionFeedback = resumeValue.feedback ?? null;
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
stateUpdate._approvalAction = 'approved';
|
|
194
|
+
stateUpdate._rejectionFeedback = null;
|
|
195
|
+
}
|
|
166
196
|
log('Resuming graph from interrupt checkpoint...');
|
|
167
|
-
result = await graph.invoke(new Command({ resume:
|
|
197
|
+
result = await graph.invoke(new Command({ resume: resumeValue, update: stateUpdate }), graphConfig);
|
|
168
198
|
}
|
|
169
199
|
else if (args.resume) {
|
|
170
200
|
// Resume from error — re-invoke with initial state; LangGraph continues
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts
CHANGED
|
@@ -39,9 +39,8 @@ export declare function safeYamlLoad(content: string): unknown;
|
|
|
39
39
|
* - allowPlan: when true, skip interrupt after plan phase
|
|
40
40
|
* - allowMerge: when true, skip interrupt after merge phase
|
|
41
41
|
*
|
|
42
|
-
* Nodes not covered by a gate (analyze, research) never interrupt.
|
|
43
|
-
*
|
|
44
|
-
* (unless all three gates are true, meaning fully autonomous).
|
|
42
|
+
* Nodes not covered by a gate (analyze, research, implement) never interrupt.
|
|
43
|
+
* Implementation always proceeds to merge; the merge node handles its own gate.
|
|
45
44
|
*
|
|
46
45
|
*/
|
|
47
46
|
export declare function shouldInterrupt(nodeName: string, gates: ApprovalGates | undefined): boolean;
|
|
@@ -75,10 +74,27 @@ export declare function retryExecute(executor: IAgentExecutor, prompt: string, o
|
|
|
75
74
|
* Read completed phases from feature.yaml.
|
|
76
75
|
*/
|
|
77
76
|
export declare function getCompletedPhases(specDir: string): string[];
|
|
77
|
+
/**
|
|
78
|
+
* Remove a phase from completedPhases in feature.yaml.
|
|
79
|
+
* Used when a phase is rejected and needs to re-execute.
|
|
80
|
+
*/
|
|
81
|
+
export declare function clearCompletedPhase(specDir: string, phaseId: string, log?: NodeLogger): void;
|
|
82
|
+
/**
|
|
83
|
+
* Type guard to detect rejection payloads from interrupt() return value.
|
|
84
|
+
*/
|
|
85
|
+
export declare function isRejectionPayload(value: unknown): value is {
|
|
86
|
+
rejected: true;
|
|
87
|
+
feedback: string;
|
|
88
|
+
};
|
|
78
89
|
/**
|
|
79
90
|
* Mark a phase as complete in feature.yaml by adding its ID to completedPhases.
|
|
80
91
|
*/
|
|
81
92
|
export declare function markPhaseComplete(specDir: string, phaseId: string, log?: NodeLogger): void;
|
|
93
|
+
/**
|
|
94
|
+
* Write a spec file atomically using temp-file-then-rename pattern.
|
|
95
|
+
* Prevents corruption on crash mid-write.
|
|
96
|
+
*/
|
|
97
|
+
export declare function writeSpecFileAtomic(specDir: string, filename: string, content: string): void;
|
|
82
98
|
/**
|
|
83
99
|
* Execute a node with consistent logging and error handling.
|
|
84
100
|
*
|
|
@@ -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;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
|
|
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;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,SAAS,GAAG,OAAO,CAQ3F;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;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAqB5F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAOhG;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAwB1F;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAa5F;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,CAmHnE"}
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* and error handling so every node follows the same patterns.
|
|
6
6
|
*/
|
|
7
7
|
import yaml from 'js-yaml';
|
|
8
|
-
import { readFileSync, writeFileSync } from 'node:fs';
|
|
8
|
+
import { readFileSync, writeFileSync, renameSync, unlinkSync } 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';
|
|
@@ -81,9 +81,8 @@ export function safeYamlLoad(content) {
|
|
|
81
81
|
* - allowPlan: when true, skip interrupt after plan phase
|
|
82
82
|
* - allowMerge: when true, skip interrupt after merge phase
|
|
83
83
|
*
|
|
84
|
-
* Nodes not covered by a gate (analyze, research) never interrupt.
|
|
85
|
-
*
|
|
86
|
-
* (unless all three gates are true, meaning fully autonomous).
|
|
84
|
+
* Nodes not covered by a gate (analyze, research, implement) never interrupt.
|
|
85
|
+
* Implementation always proceeds to merge; the merge node handles its own gate.
|
|
87
86
|
*
|
|
88
87
|
*/
|
|
89
88
|
export function shouldInterrupt(nodeName, gates) {
|
|
@@ -97,8 +96,6 @@ export function shouldInterrupt(nodeName, gates) {
|
|
|
97
96
|
return !gates.allowPlan;
|
|
98
97
|
if (nodeName === 'merge')
|
|
99
98
|
return !gates.allowMerge;
|
|
100
|
-
if (nodeName === 'implement')
|
|
101
|
-
return true;
|
|
102
99
|
return false;
|
|
103
100
|
}
|
|
104
101
|
const API_ERROR_RE = /API Error: (400|429|5\d{2})/;
|
|
@@ -169,6 +166,38 @@ export function getCompletedPhases(specDir) {
|
|
|
169
166
|
return [];
|
|
170
167
|
}
|
|
171
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* Remove a phase from completedPhases in feature.yaml.
|
|
171
|
+
* Used when a phase is rejected and needs to re-execute.
|
|
172
|
+
*/
|
|
173
|
+
export function clearCompletedPhase(specDir, phaseId, log) {
|
|
174
|
+
try {
|
|
175
|
+
const content = readSpecFile(specDir, 'feature.yaml');
|
|
176
|
+
if (!content)
|
|
177
|
+
return;
|
|
178
|
+
const data = yaml.load(content);
|
|
179
|
+
if (!data || typeof data !== 'object')
|
|
180
|
+
return;
|
|
181
|
+
const status = (data.status ?? {});
|
|
182
|
+
const completedPhases = Array.isArray(status.completedPhases)
|
|
183
|
+
? status.completedPhases.filter((p) => p !== phaseId)
|
|
184
|
+
: [];
|
|
185
|
+
data.status = { ...status, completedPhases };
|
|
186
|
+
writeFileSync(join(specDir, 'feature.yaml'), yaml.dump(data, { indent: 2, lineWidth: -1 }), 'utf-8');
|
|
187
|
+
}
|
|
188
|
+
catch (err) {
|
|
189
|
+
log?.error(`Failed to clear completed phase: ${err instanceof Error ? err.message : String(err)}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Type guard to detect rejection payloads from interrupt() return value.
|
|
194
|
+
*/
|
|
195
|
+
export function isRejectionPayload(value) {
|
|
196
|
+
return (typeof value === 'object' &&
|
|
197
|
+
value !== null &&
|
|
198
|
+
'rejected' in value &&
|
|
199
|
+
value.rejected === true);
|
|
200
|
+
}
|
|
172
201
|
/**
|
|
173
202
|
* Mark a phase as complete in feature.yaml by adding its ID to completedPhases.
|
|
174
203
|
*/
|
|
@@ -194,6 +223,26 @@ export function markPhaseComplete(specDir, phaseId, log) {
|
|
|
194
223
|
log?.error(`Failed to mark phase complete: ${err instanceof Error ? err.message : String(err)}`);
|
|
195
224
|
}
|
|
196
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Write a spec file atomically using temp-file-then-rename pattern.
|
|
228
|
+
* Prevents corruption on crash mid-write.
|
|
229
|
+
*/
|
|
230
|
+
export function writeSpecFileAtomic(specDir, filename, content) {
|
|
231
|
+
const targetPath = join(specDir, filename);
|
|
232
|
+
const tempPath = join(specDir, `.${filename}.tmp`);
|
|
233
|
+
try {
|
|
234
|
+
writeFileSync(tempPath, content, 'utf-8');
|
|
235
|
+
renameSync(tempPath, targetPath);
|
|
236
|
+
}
|
|
237
|
+
finally {
|
|
238
|
+
try {
|
|
239
|
+
unlinkSync(tempPath);
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
// Temp file already renamed or doesn't exist
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
197
246
|
/**
|
|
198
247
|
* Execute a node with consistent logging and error handling.
|
|
199
248
|
*
|
|
@@ -210,16 +259,46 @@ export function executeNode(nodeName, executor, buildPrompt) {
|
|
|
210
259
|
// Update feature lifecycle to reflect the current phase
|
|
211
260
|
await updateNodeLifecycle(nodeName);
|
|
212
261
|
// On resume from interrupt, LangGraph re-executes the node function from
|
|
213
|
-
// the top.
|
|
214
|
-
//
|
|
215
|
-
//
|
|
262
|
+
// the top. Instead of re-executing within this invocation (which would
|
|
263
|
+
// require a second interrupt() call and trigger the stale-replay bug),
|
|
264
|
+
// we return early. Rejection sets _needsReexecution=true so a conditional
|
|
265
|
+
// edge in the graph routes back to this node for a fresh invocation.
|
|
216
266
|
const completedPhases = getCompletedPhases(state.specDir);
|
|
217
267
|
if (completedPhases.includes(nodeName)) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
268
|
+
if (shouldInterrupt(nodeName, state.approvalGates)) {
|
|
269
|
+
if (state._approvalAction === 'rejected') {
|
|
270
|
+
const feedback = state._rejectionFeedback ?? '(no feedback)';
|
|
271
|
+
log.info(`Phase rejected with feedback: "${feedback}" — scheduling re-execution`);
|
|
272
|
+
clearCompletedPhase(state.specDir, nodeName, log);
|
|
273
|
+
// Return early — the conditional edge will route back to this node
|
|
274
|
+
// for a fresh invocation with a clean interrupt index.
|
|
275
|
+
return {
|
|
276
|
+
currentNode: nodeName,
|
|
277
|
+
messages: [`[${nodeName}] Rejected — will re-execute`],
|
|
278
|
+
_approvalAction: null,
|
|
279
|
+
_rejectionFeedback: null,
|
|
280
|
+
_needsReexecution: true,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
log.info('Phase approved, skipping re-execution');
|
|
285
|
+
return {
|
|
286
|
+
currentNode: nodeName,
|
|
287
|
+
messages: [`[${nodeName}] Approved — continuing`],
|
|
288
|
+
_approvalAction: null,
|
|
289
|
+
_rejectionFeedback: null,
|
|
290
|
+
_needsReexecution: false,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
log.info('Phase already completed (no gate), skipping execution');
|
|
296
|
+
return {
|
|
297
|
+
currentNode: nodeName,
|
|
298
|
+
messages: [`[${nodeName}] Approved — continuing`],
|
|
299
|
+
_needsReexecution: false,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
223
302
|
}
|
|
224
303
|
const startTime = Date.now();
|
|
225
304
|
// Record phase start (no-op if timing context not set)
|
|
@@ -236,13 +315,19 @@ export function executeNode(nodeName, executor, buildPrompt) {
|
|
|
236
315
|
// Record phase completion
|
|
237
316
|
await recordPhaseEnd(timingId, durationMs);
|
|
238
317
|
// Mark phase complete BEFORE interrupting so that on resume the
|
|
239
|
-
// node detects the work is already done and
|
|
318
|
+
// node detects the work is already done and returns early.
|
|
240
319
|
markPhaseComplete(state.specDir, nodeName, log);
|
|
241
320
|
const nodeResult = {
|
|
242
321
|
currentNode: nodeName,
|
|
243
322
|
messages: [`[${nodeName}] Complete (${result.result.length} chars, ${elapsed}s)`],
|
|
323
|
+
_approvalAction: null,
|
|
324
|
+
_rejectionFeedback: null,
|
|
325
|
+
_needsReexecution: false,
|
|
244
326
|
};
|
|
245
|
-
// Human-in-the-loop: interrupt after node execution for review
|
|
327
|
+
// Human-in-the-loop: interrupt after node execution for review.
|
|
328
|
+
// This is the ONLY interrupt() call in the entire execution path.
|
|
329
|
+
// On resume, the node returns early (above) without calling interrupt(),
|
|
330
|
+
// so there is no stale interrupt replay.
|
|
246
331
|
if (shouldInterrupt(nodeName, state.approvalGates)) {
|
|
247
332
|
log.info('Interrupting for human approval');
|
|
248
333
|
await recordApprovalWaitStart(timingId);
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* Requirements Phase Prompt
|
|
3
3
|
*
|
|
4
4
|
* Instructs the agent to build comprehensive requirements from the analysis,
|
|
5
|
-
* including product questions with
|
|
5
|
+
* including product questions with structured QuestionOption[] arrays
|
|
6
|
+
* and AI-recommended default answers.
|
|
6
7
|
* Writes back to spec.yaml with full requirements.
|
|
7
8
|
*/
|
|
8
9
|
import type { FeatureAgentState } from '../../state.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requirements.prompt.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/requirements.prompt.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"requirements.prompt.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/requirements.prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAkKxE"}
|