@shepai/cli 1.122.1 → 1.122.2-pr360.dfb75fe
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/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 -4
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.d.ts +7 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.js +24 -2
- package/dist/packages/core/src/infrastructure/services/tool-installer/tool-installer.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/tool-installer/tool-installer.service.js +10 -3
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/claude-code.json +9 -4
- package/dist/src/presentation/cli/commands/install.command.js +8 -1
- package/dist/src/presentation/web/app/actions/check-agent-auth.d.ts +2 -0
- package/dist/src/presentation/web/app/actions/check-agent-auth.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/check-agent-auth.js +8 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.js +1 -1
- package/dist/src/presentation/web/components/features/tools/tool-card.stories.js +1 -1
- package/dist/src/presentation/web/components/features/tools/tools-page-client.stories.js +1 -1
- 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/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +3 -3
- package/web/.next/required-server-files.json +3 -3
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +22 -22
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +22 -22
- package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +20 -20
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/settings/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__06fef644._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2698e9f4._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2698e9f4._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8c553503._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8e3bf5d7._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8e3bf5d7._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a022445f._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a022445f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a7de2711._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c07f9f79._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c07f9f79._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c605a375._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c605a375._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_b294a667._.js → _004b791b._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_b294a667._.js.map → _004b791b._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_0dc2cfd3._.js +1 -1
- package/web/.next/server/chunks/ssr/_0dc2cfd3._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_469c5451._.js → _0ee2702f._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_469c5451._.js.map → _0ee2702f._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
- package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_92d851b4._.js → _1c4cecde._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_92d851b4._.js.map → _1c4cecde._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_2f6f48b8._.js +1 -1
- package/web/.next/server/chunks/ssr/_2f6f48b8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
- package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_5f039db1._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_5f039db1._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_c4337169._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_c4337169._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
- package/web/.next/server/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +34 -34
- package/web/.next/static/chunks/{df85e52b1afb7340.js → 0dd2d4fcafd8772b.js} +1 -1
- package/web/.next/static/chunks/{e6a2fb8707e079ff.js → 1b5419c02d253fae.js} +1 -1
- package/web/.next/static/chunks/{37ac7fe1cd493293.js → 1e6bfbd7936bba25.js} +1 -1
- package/web/.next/static/chunks/{e9c3fbbeb418cbfa.js → 349c47b3b993ae54.js} +1 -1
- package/web/.next/static/chunks/{658fc2f5f65cf3b5.js → 37634985311cc4c6.js} +2 -2
- package/web/.next/static/chunks/{9df4681de92ebfc3.js → 6c4aa963056c0bc2.js} +1 -1
- package/web/.next/static/chunks/{941c13dcdb1978a4.js → 8e816c7f48f7653d.js} +2 -2
- package/web/.next/static/chunks/{50dd80c8aafa3b20.js → 9eb4f613f1e35899.js} +1 -1
- package/web/.next/static/chunks/{11e4439096f8d652.js → d05a044cbbedbd56.js} +1 -1
- package/web/.next/static/chunks/{78ab7b134f0649ac.js → eb165ab35b356164.js} +1 -1
- /package/web/.next/static/{hsK1x0unrjI_pUsvQhn6P → CMhbAJyvRj6ct2bZgc0Yp}/_buildManifest.js +0 -0
- /package/web/.next/static/{hsK1x0unrjI_pUsvQhn6P → CMhbAJyvRj6ct2bZgc0Yp}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{hsK1x0unrjI_pUsvQhn6P → CMhbAJyvRj6ct2bZgc0Yp}/_ssgManifest.js +0 -0
|
@@ -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,6BAA6B,CAAC;
|
|
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,6BAA6B,CAAC;AAclF,OAAO,EAAE,sBAAsB,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE5E;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,cAAc,CAAC;IACzB,aAAa,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;CACjD;AAwID;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACrC,cAAc,EAAE,qBAAqB,GAAG,cAAc,EACtD,YAAY,CAAC,EAAE,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAgFnC"}
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.js
CHANGED
|
@@ -11,7 +11,7 @@ import { createRepairNode } from './nodes/repair.node.js';
|
|
|
11
11
|
import { validateSpecAnalyze, validateSpecRequirements } from './nodes/schemas/spec.schema.js';
|
|
12
12
|
import { validateResearch } from './nodes/schemas/research.schema.js';
|
|
13
13
|
import { validatePlan, validateTasks } from './nodes/schemas/plan.schema.js';
|
|
14
|
-
import { readSpecFile, safeYamlLoad, createNodeLogger } from './nodes/node-helpers.js';
|
|
14
|
+
import { readSpecFile, safeYamlLoad, createNodeLogger, getCompletedPhases, } from './nodes/node-helpers.js';
|
|
15
15
|
// Re-export state types for consumers
|
|
16
16
|
export { FeatureAgentAnnotation } from './state.js';
|
|
17
17
|
/**
|
|
@@ -54,6 +54,18 @@ function createPlanTasksValidator() {
|
|
|
54
54
|
const log = createNodeLogger('validate:plan+tasks');
|
|
55
55
|
return async (state) => {
|
|
56
56
|
log.activate();
|
|
57
|
+
// Skip validation when the successor phase (implement) is already completed.
|
|
58
|
+
// This proves validation already passed and the pipeline progressed beyond it.
|
|
59
|
+
// Same logic as createValidateNode's successorPhase guard.
|
|
60
|
+
if (getCompletedPhases(state.specDir).includes('implement')) {
|
|
61
|
+
log.info("Successor phase 'implement' already completed, skipping validation");
|
|
62
|
+
return {
|
|
63
|
+
lastValidationTarget: 'plan.yaml+tasks.yaml',
|
|
64
|
+
lastValidationErrors: [],
|
|
65
|
+
validationRetries: 0,
|
|
66
|
+
messages: ["[validate:plan+tasks] SKIP (successor 'implement' already completed)"],
|
|
67
|
+
};
|
|
68
|
+
}
|
|
57
69
|
log.info('Validating plan.yaml and tasks.yaml');
|
|
58
70
|
const allErrors = [];
|
|
59
71
|
// Validate plan.yaml
|
|
@@ -145,9 +157,14 @@ export function createFeatureAgentGraph(depsOrExecutor, checkpointer) {
|
|
|
145
157
|
.addNode('plan', createPlanNode(executor))
|
|
146
158
|
.addNode('implement', createImplementNode(executor))
|
|
147
159
|
// --- Validate nodes ---
|
|
148
|
-
|
|
149
|
-
.
|
|
150
|
-
|
|
160
|
+
// Each validate node receives its SUCCESSOR phase name (the phase that runs
|
|
161
|
+
// after validation passes). On resume, validation is skipped only when the
|
|
162
|
+
// successor is already completed — proving this validation already passed.
|
|
163
|
+
// Using the successor (not the producer) avoids skipping validation when the
|
|
164
|
+
// producer ran successfully but validation itself failed.
|
|
165
|
+
.addNode('validate_spec_analyze', createValidateNode('spec.yaml', validateSpecAnalyze, 'requirements'))
|
|
166
|
+
.addNode('validate_spec_requirements', createValidateNode('spec.yaml', validateSpecRequirements, 'research'))
|
|
167
|
+
.addNode('validate_research', createValidateNode('research.yaml', validateResearch, 'plan'))
|
|
151
168
|
.addNode('validate_plan_tasks', createPlanTasksValidator())
|
|
152
169
|
// --- Repair nodes ---
|
|
153
170
|
.addNode('repair_spec_analyze', createRepairNode('spec.yaml', executor))
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.d.ts
CHANGED
|
@@ -6,7 +6,13 @@ type SchemaValidator = (data: unknown) => ValidationResult;
|
|
|
6
6
|
*
|
|
7
7
|
* On success: resets validationRetries to 0, clears errors.
|
|
8
8
|
* On failure: increments validationRetries, sets errors for repair node.
|
|
9
|
+
*
|
|
10
|
+
* @param successorPhase - The phase that runs AFTER this validation passes.
|
|
11
|
+
* If provided, skip validation when the successor is already completed — this
|
|
12
|
+
* proves the validation already passed in a prior run and the pipeline progressed
|
|
13
|
+
* beyond it. Checking the successor (not the producer) avoids skipping validation
|
|
14
|
+
* when the producer ran but validation itself failed.
|
|
9
15
|
*/
|
|
10
|
-
export declare function createValidateNode(filename: string, schema: SchemaValidator): (state: FeatureAgentState) => Promise<Partial<FeatureAgentState>>;
|
|
16
|
+
export declare function createValidateNode(filename: string, schema: SchemaValidator, successorPhase?: string): (state: FeatureAgentState) => Promise<Partial<FeatureAgentState>>;
|
|
11
17
|
export {};
|
|
12
18
|
//# sourceMappingURL=validate.node.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"validate.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAQhE,KAAK,eAAe,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,gBAAgB,CAAC;AAE3D;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,eAAe,EACvB,cAAc,CAAC,EAAE,MAAM,GACtB,CAAC,KAAK,EAAE,iBAAiB,KAAK,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAyEnE"}
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.js
CHANGED
|
@@ -1,14 +1,36 @@
|
|
|
1
|
-
import { readSpecFile, safeYamlLoad, createNodeLogger } from './node-helpers.js';
|
|
1
|
+
import { readSpecFile, safeYamlLoad, createNodeLogger, getCompletedPhases, } from './node-helpers.js';
|
|
2
2
|
/**
|
|
3
3
|
* Factory that creates a validate node for a specific YAML file.
|
|
4
4
|
*
|
|
5
5
|
* On success: resets validationRetries to 0, clears errors.
|
|
6
6
|
* On failure: increments validationRetries, sets errors for repair node.
|
|
7
|
+
*
|
|
8
|
+
* @param successorPhase - The phase that runs AFTER this validation passes.
|
|
9
|
+
* If provided, skip validation when the successor is already completed — this
|
|
10
|
+
* proves the validation already passed in a prior run and the pipeline progressed
|
|
11
|
+
* beyond it. Checking the successor (not the producer) avoids skipping validation
|
|
12
|
+
* when the producer ran but validation itself failed.
|
|
7
13
|
*/
|
|
8
|
-
export function createValidateNode(filename, schema) {
|
|
14
|
+
export function createValidateNode(filename, schema, successorPhase) {
|
|
9
15
|
const log = createNodeLogger(`validate:${filename}`);
|
|
10
16
|
return async (state) => {
|
|
11
17
|
log.activate();
|
|
18
|
+
// Skip validation when the successor phase is already completed.
|
|
19
|
+
// This means: the validation already passed in a prior run AND the next phase
|
|
20
|
+
// ran successfully. On resume, LangGraph replays nodes from the last checkpoint.
|
|
21
|
+
// The producer node skips (via getCompletedPhases), but if we only checked the
|
|
22
|
+
// producer we'd also skip validation when it previously FAILED (since
|
|
23
|
+
// markPhaseComplete runs before validation). Checking the successor is safe:
|
|
24
|
+
// if the successor completed, this validation must have passed to get there.
|
|
25
|
+
if (successorPhase && getCompletedPhases(state.specDir).includes(successorPhase)) {
|
|
26
|
+
log.info(`Successor phase '${successorPhase}' already completed, skipping validation`);
|
|
27
|
+
return {
|
|
28
|
+
lastValidationTarget: filename,
|
|
29
|
+
lastValidationErrors: [],
|
|
30
|
+
validationRetries: 0,
|
|
31
|
+
messages: [`[validate:${filename}] SKIP (successor '${successorPhase}' already completed)`],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
12
34
|
log.info(`Validating ${filename}`);
|
|
13
35
|
const content = readSpecFile(state.specDir, filename);
|
|
14
36
|
if (!content) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-installer.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/tool-installer/tool-installer.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sEAAsE,CAAC;AAClH,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EAEnB,MAAM,qCAAqC,CAAC;AA2B7C,qBACa,wBAAyB,YAAW,qBAAqB;IACpE;;;OAGG;IACG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAoC1E;;;OAGG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI;IAqB9D;;;OAGG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAChC,OAAO,CAAC,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"tool-installer.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/tool-installer/tool-installer.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sEAAsE,CAAC;AAClH,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EAEnB,MAAM,qCAAqC,CAAC;AA2B7C,qBACa,wBAAyB,YAAW,qBAAqB;IACpE;;;OAGG;IACG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAoC1E;;;OAGG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI;IAqB9D;;;OAGG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAChC,OAAO,CAAC,sBAAsB,CAAC;IAwFlC;;OAEG;IACH,OAAO,CAAC,6BAA6B;CA4BtC"}
|
package/dist/packages/core/src/infrastructure/services/tool-installer/tool-installer.service.js
CHANGED
|
@@ -107,9 +107,14 @@ let ToolInstallerServiceImpl = class ToolInstallerServiceImpl {
|
|
|
107
107
|
}
|
|
108
108
|
return new Promise((resolve) => {
|
|
109
109
|
let output = '';
|
|
110
|
+
// Inherit stdin when running in an interactive terminal so that commands
|
|
111
|
+
// requiring sudo can prompt the user for a password. In non-interactive
|
|
112
|
+
// contexts (web UI, CI) stdin is piped and closed immediately to prevent
|
|
113
|
+
// the process from hanging waiting for input.
|
|
114
|
+
const isInteractive = process.stdin.isTTY === true;
|
|
110
115
|
const child = spawn(installCommand.command, [], {
|
|
111
116
|
shell: true,
|
|
112
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
117
|
+
stdio: [isInteractive ? 'inherit' : 'pipe', 'pipe', 'pipe'],
|
|
113
118
|
env: {
|
|
114
119
|
...process.env,
|
|
115
120
|
DEBIAN_FRONTEND: 'noninteractive',
|
|
@@ -117,8 +122,10 @@ let ToolInstallerServiceImpl = class ToolInstallerServiceImpl {
|
|
|
117
122
|
GPG_TTY: '',
|
|
118
123
|
},
|
|
119
124
|
});
|
|
120
|
-
// Close stdin
|
|
121
|
-
|
|
125
|
+
// Close stdin in non-interactive mode to prevent prompts from hanging
|
|
126
|
+
if (!isInteractive) {
|
|
127
|
+
child.stdin?.end();
|
|
128
|
+
}
|
|
122
129
|
// Stream output from stdout and stderr
|
|
123
130
|
const pipeOutput = (stream) => {
|
|
124
131
|
if (!stream)
|
package/dist/packages/core/src/infrastructure/services/tool-installer/tools/claude-code.json
CHANGED
|
@@ -12,13 +12,17 @@
|
|
|
12
12
|
"commands": {
|
|
13
13
|
"linux": "curl -fsSL https://claude.ai/install.sh | bash",
|
|
14
14
|
"darwin": "curl -fsSL https://claude.ai/install.sh | bash",
|
|
15
|
-
"win32": "
|
|
15
|
+
"win32": "powershell -Command \"iwr -useb https://claude.ai/install.ps1 | iex\""
|
|
16
16
|
},
|
|
17
17
|
"timeout": 300000,
|
|
18
|
-
"documentationUrl": "https://
|
|
18
|
+
"documentationUrl": "https://docs.anthropic.com/en/docs/claude-code/overview",
|
|
19
19
|
"verifyCommand": "claude --version",
|
|
20
20
|
"autoInstall": true,
|
|
21
|
-
"openDirectory":
|
|
21
|
+
"openDirectory": {
|
|
22
|
+
"linux": "cd {dir} && exec claude",
|
|
23
|
+
"darwin": "cd {dir} && exec claude",
|
|
24
|
+
"win32": "cd /d {dir} && claude"
|
|
25
|
+
},
|
|
22
26
|
"spawnOptions": {
|
|
23
27
|
"shell": true,
|
|
24
28
|
"stdio": "inherit",
|
|
@@ -26,6 +30,7 @@
|
|
|
26
30
|
},
|
|
27
31
|
"terminalCommand": {
|
|
28
32
|
"linux": "x-terminal-emulator -e bash -c 'cd {dir} && exec claude'",
|
|
29
|
-
"darwin": "
|
|
33
|
+
"darwin": "osascript -e 'tell application \"Terminal\" to do script \"cd {dir} && exec claude\"'",
|
|
34
|
+
"win32": "start cmd /k \"cd /d {dir} && claude\""
|
|
30
35
|
}
|
|
31
36
|
}
|
|
@@ -117,7 +117,14 @@ function printInstallInstructions(metadata) {
|
|
|
117
117
|
// Print open directory command if available
|
|
118
118
|
if (metadata.openDirectory) {
|
|
119
119
|
console.log(fmt.heading('Open Directory'));
|
|
120
|
-
|
|
120
|
+
if (typeof metadata.openDirectory === 'string') {
|
|
121
|
+
console.log(`${colors.muted('$')} ${metadata.openDirectory}`);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
for (const [platform, cmd] of Object.entries(metadata.openDirectory)) {
|
|
125
|
+
console.log(`${colors.muted(`[${platform}]`)} ${cmd}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
121
128
|
console.log();
|
|
122
129
|
}
|
|
123
130
|
// Print documentation link
|
|
@@ -10,6 +10,8 @@ export interface AgentAuthStatus {
|
|
|
10
10
|
binaryName: string | null;
|
|
11
11
|
/** Instructions to authenticate if not authenticated */
|
|
12
12
|
authCommand: string | null;
|
|
13
|
+
/** Platform-resolved install command (e.g. "npm install -g @google/gemini-cli") */
|
|
14
|
+
installCommand: string | null;
|
|
13
15
|
}
|
|
14
16
|
/**
|
|
15
17
|
* Check agent tool installation + auth status.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-agent-auth.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/check-agent-auth.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,SAAS,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,aAAa,EAAE,OAAO,CAAC;IACvB,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,wDAAwD;IACxD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"check-agent-auth.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/check-agent-auth.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,SAAS,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,aAAa,EAAE,OAAO,CAAC;IACvB,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,wDAAwD;IACxD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,mFAAmF;IACnF,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AA4FD;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,eAAe,CAAC,CAwF/D"}
|
|
@@ -20,7 +20,7 @@ const AGENT_TOOL_MAP = {
|
|
|
20
20
|
};
|
|
21
21
|
const AGENT_BINARY_MAP = {
|
|
22
22
|
'claude-code': 'claude',
|
|
23
|
-
cursor: 'agent',
|
|
23
|
+
cursor: 'cursor-agent',
|
|
24
24
|
'gemini-cli': 'gemini',
|
|
25
25
|
};
|
|
26
26
|
/**
|
|
@@ -113,6 +113,7 @@ export async function checkAgentAuth() {
|
|
|
113
113
|
label: 'Unknown',
|
|
114
114
|
binaryName: null,
|
|
115
115
|
authCommand: null,
|
|
116
|
+
installCommand: null,
|
|
116
117
|
};
|
|
117
118
|
}
|
|
118
119
|
const label = AGENT_LABELS[agentType] ?? agentType;
|
|
@@ -127,15 +128,18 @@ export async function checkAgentAuth() {
|
|
|
127
128
|
label,
|
|
128
129
|
binaryName: null,
|
|
129
130
|
authCommand: null,
|
|
131
|
+
installCommand: null,
|
|
130
132
|
};
|
|
131
133
|
}
|
|
132
134
|
// Check if tool is installed
|
|
133
135
|
let installed = false;
|
|
136
|
+
let installCommand = null;
|
|
134
137
|
try {
|
|
135
138
|
const useCase = resolve('ListToolsUseCase');
|
|
136
139
|
const tools = await useCase.execute();
|
|
137
140
|
const tool = tools.find((t) => t.id === toolId);
|
|
138
141
|
installed = tool?.status.status === 'available';
|
|
142
|
+
installCommand = tool?.installCommand ?? null;
|
|
139
143
|
}
|
|
140
144
|
catch {
|
|
141
145
|
installed = false;
|
|
@@ -148,6 +152,7 @@ export async function checkAgentAuth() {
|
|
|
148
152
|
label,
|
|
149
153
|
binaryName,
|
|
150
154
|
authCommand: binaryName ? `Install ${label} first` : null,
|
|
155
|
+
installCommand,
|
|
151
156
|
};
|
|
152
157
|
}
|
|
153
158
|
// Tier 1: instant file/env check
|
|
@@ -160,6 +165,7 @@ export async function checkAgentAuth() {
|
|
|
160
165
|
label,
|
|
161
166
|
binaryName,
|
|
162
167
|
authCommand: binaryName,
|
|
168
|
+
installCommand,
|
|
163
169
|
};
|
|
164
170
|
}
|
|
165
171
|
// Tier 2: subprocess verify (best effort, ~200ms)
|
|
@@ -174,5 +180,6 @@ export async function checkAgentAuth() {
|
|
|
174
180
|
label,
|
|
175
181
|
binaryName,
|
|
176
182
|
authCommand: authenticated ? null : binaryName,
|
|
183
|
+
installCommand,
|
|
177
184
|
};
|
|
178
185
|
}
|
package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.js
CHANGED
|
@@ -70,7 +70,7 @@ function AgentAuthBanner({ status, onRetry, }) {
|
|
|
70
70
|
}
|
|
71
71
|
// Not installed
|
|
72
72
|
if (!status.installed) {
|
|
73
|
-
return (_jsxs("div", { className: "flex w-full flex-col gap-2 rounded-md bg-amber-500/10 px-3 py-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(AlertCircle, { className: "h-3 w-3 text-amber-600 dark:text-amber-400" }), _jsxs("span", { className: "text-[10px] font-medium text-amber-700 dark:text-amber-300", children: [status.label, " not installed"] })] }), status.
|
|
73
|
+
return (_jsxs("div", { className: "flex w-full flex-col gap-2 rounded-md bg-amber-500/10 px-3 py-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(AlertCircle, { className: "h-3 w-3 text-amber-600 dark:text-amber-400" }), _jsxs("span", { className: "text-[10px] font-medium text-amber-700 dark:text-amber-300", children: [status.label, " not installed"] })] }), status.installCommand ? (_jsxs("div", { className: "rounded bg-zinc-900 px-2 py-1 font-mono text-[10px] text-zinc-300", children: [_jsx("span", { className: "text-zinc-500 select-none", children: "$ " }), status.installCommand] })) : null, _jsx("button", { type: "button", onClick: onRetry, className: "self-start text-[10px] font-medium text-amber-700 underline underline-offset-2 hover:text-amber-900 dark:text-amber-300 dark:hover:text-amber-100", children: "Re-check" })] }));
|
|
74
74
|
}
|
|
75
75
|
// Installed but not authenticated
|
|
76
76
|
return (_jsxs("div", { className: "flex w-full flex-col gap-2 rounded-md bg-amber-500/10 px-3 py-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(AlertCircle, { className: "h-3 w-3 text-amber-600 dark:text-amber-400" }), _jsxs("span", { className: "text-[10px] font-medium text-amber-700 dark:text-amber-300", children: [status.label, " needs authentication"] })] }), status.authCommand ? (_jsxs("div", { className: "rounded bg-zinc-900 px-2 py-1 font-mono text-[10px] text-zinc-300", children: [_jsx("span", { className: "text-zinc-500 select-none", children: "$ " }), status.authCommand] })) : null, _jsxs("div", { className: "flex items-center gap-2", children: [status.binaryName ? (_jsxs("button", { type: "button", "data-testid": "auth-banner-open-terminal", onClick: async () => {
|
|
@@ -28,7 +28,7 @@ const installedNoLaunchTool = {
|
|
|
28
28
|
required: false,
|
|
29
29
|
openDirectory: undefined,
|
|
30
30
|
documentationUrl: 'https://claude.ai',
|
|
31
|
-
installCommand: '
|
|
31
|
+
installCommand: 'curl -fsSL https://claude.ai/install.sh | bash',
|
|
32
32
|
status: { status: 'available', toolName: 'claude-code' },
|
|
33
33
|
author: 'Anthropic',
|
|
34
34
|
website: 'https://claude.ai/code',
|
|
@@ -45,7 +45,7 @@ const mockTools = [
|
|
|
45
45
|
required: false,
|
|
46
46
|
openDirectory: undefined,
|
|
47
47
|
documentationUrl: 'https://claude.ai/code',
|
|
48
|
-
installCommand: '
|
|
48
|
+
installCommand: 'curl -fsSL https://claude.ai/install.sh | bash',
|
|
49
49
|
status: { status: 'available', toolName: 'claude-code' },
|
|
50
50
|
author: 'Anthropic',
|
|
51
51
|
website: 'https://claude.ai/code',
|