@shepai/cli 1.144.0 → 1.145.0-pr452.8b628a7
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/apis/json-schema/Feature.yaml +25 -0
- package/apis/json-schema/PullRequest.yaml +11 -0
- package/apis/json-schema/SdlcLifecycle.yaml +1 -0
- package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts +5 -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-fork-service.interface.d.ts +79 -0
- package/dist/packages/core/src/application/ports/output/services/git-fork-service.interface.d.ts.map +1 -0
- package/dist/packages/core/src/application/ports/output/services/git-fork-service.interface.js +31 -0
- package/dist/packages/core/src/application/use-cases/features/adopt-branch.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/adopt-branch.use-case.js +5 -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 +10 -0
- package/dist/packages/core/src/application/use-cases/features/create/types.d.ts +10 -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/poll-upstream-pr.use-case.d.ts +23 -0
- package/dist/packages/core/src/application/use-cases/features/poll-upstream-pr.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/features/poll-upstream-pr.use-case.js +84 -0
- 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 +2 -0
- package/dist/packages/core/src/domain/generated/output.d.ts +33 -0
- package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
- package/dist/packages/core/src/domain/generated/output.js +1 -0
- 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 +8 -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 +18 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/045-add-fork-and-pr-columns.d.ts +13 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/045-add-fork-and-pr-columns.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/045-add-fork-and-pr-columns.js +30 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/046-add-per-feature-workflow-columns.d.ts +12 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/046-add-per-feature-workflow-columns.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/046-add-per-feature-workflow-columns.js +23 -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 +23 -4
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/fast-feature-agent-graph.d.ts +25 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/fast-feature-agent-graph.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts +85 -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-process.service.d.ts +5 -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 +15 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts +5 -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 +23 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.d.ts +6 -3
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.js +104 -66
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge-output-parser.d.ts +12 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge-output-parser.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge-output-parser.js +33 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.d.ts +2 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.js +50 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts +8 -0
- 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 +40 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/analyze.prompt.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/analyze.prompt.js +11 -9
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.d.ts +10 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.js +68 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/plan.prompt.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/plan.prompt.js +8 -6
- 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 +11 -9
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/research.prompt.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/research.prompt.js +8 -6
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/schemas/spec.schema.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/schemas/spec.schema.js +3 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/schemas/validation.d.ts +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/schemas/validation.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/schemas/validation.js +9 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.d.ts +5 -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 +20 -0
- package/dist/packages/core/src/infrastructure/services/git/git-fork.service.d.ts +25 -0
- package/dist/packages/core/src/infrastructure/services/git/git-fork.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/git/git-fork.service.js +145 -0
- package/dist/packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.d.ts +17 -3
- package/dist/packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.js +98 -15
- package/dist/src/presentation/cli/commands/ui.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/ui.command.js +2 -1
- package/dist/src/presentation/web/app/actions/create-feature.d.ts +10 -0
- package/dist/src/presentation/web/app/actions/create-feature.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/create-feature.js +8 -1
- package/dist/src/presentation/web/app/api/agent-events/route.d.ts.map +1 -1
- package/dist/src/presentation/web/app/api/agent-events/route.js +1 -0
- package/dist/src/presentation/web/app/build-feature-node-data.d.ts.map +1 -1
- package/dist/src/presentation/web/app/build-feature-node-data.js +5 -3
- package/dist/src/presentation/web/app/build-graph-nodes.js +5 -3
- package/dist/src/presentation/web/components/common/base-drawer/base-drawer.js +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts +4 -0
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +24 -7
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts +12 -0
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.js +35 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.js +7 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +5 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.js +12 -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 +1 -0
- package/dist/src/presentation/web/dev-server.js +2 -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/adopt/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +28 -28
- 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 +36 -36
- 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 +36 -36
- 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 +26 -26
- 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 +28 -28
- 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 +36 -36
- 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 +36 -36
- 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 +26 -26
- 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 +26 -26
- 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 +3 -3
- 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 +8 -8
- 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 +8 -8
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +8 -8
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +3 -3
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +1 -1
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +1 -1
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js +2 -2
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js.map +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__c6e32a23._.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__c6e32a23._.js.map +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js.map +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/[root-of-the-server]__0b150ddf._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0b150ddf._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2138fa7e._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2138fa7e._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__29580090._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__29580090._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__3ef34e4c._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c094882b._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c094882b._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__d48c5b11._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__d48c5b11._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__dac5dbf1._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__dac5dbf1._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__df7c1cd3._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__df7c1cd3._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fae8b355._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fae8b355._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_0c5f56e3._.js +2 -2
- package/web/.next/server/chunks/ssr/_0c5f56e3._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_1b719e7f._.js +1 -1
- package/web/.next/server/chunks/ssr/_1b719e7f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_37e8548b._.js +1 -1
- package/web/.next/server/chunks/ssr/_37e8548b._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_55d763e2._.js +1 -1
- package/web/.next/server/chunks/ssr/_55d763e2._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_6256a985._.js +1 -1
- package/web/.next/server/chunks/ssr/_6256a985._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_64bdfc6f._.js +2 -2
- package/web/.next/server/chunks/ssr/_64bdfc6f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_c64f06d5._.js → _6601673c._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_c64f06d5._.js.map → _6601673c._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_7dca1882._.js +1 -1
- package/web/.next/server/chunks/ssr/_7dca1882._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_8fcc39d4._.js +3 -0
- package/web/.next/server/chunks/ssr/_8fcc39d4._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_9bbe1097._.js +3 -0
- package/web/.next/server/chunks/ssr/{_c67ad133._.js.map → _9bbe1097._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_b71645b4._.js +1 -1
- package/web/.next/server/chunks/ssr/_b71645b4._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_d4b20e29._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_d8575088._.js +1 -1
- package/web/.next/server/chunks/ssr/_d8575088._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_f39a1adb._.js +1 -1
- package/web/.next/server/chunks/ssr/_f39a1adb._.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__next-internal_server_app_skills_page_actions_1b176e3c.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
- package/web/.next/server/chunks/ssr/{src_presentation_web_dd85ad88._.js → src_presentation_web_bb760f63._.js} +2 -2
- package/web/.next/server/chunks/ssr/{src_presentation_web_dd85ad88._.js.map → src_presentation_web_bb760f63._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +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_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 +44 -44
- package/web/.next/static/chunks/{74ee98538b63a4b2.css → 0b18c50740356276.css} +1 -1
- package/web/.next/static/chunks/{53478ed65db63030.js → 272969a3ec45bfb1.js} +2 -2
- package/web/.next/static/chunks/{904cdf4c47654f32.js → 2d74811df2aeea52.js} +1 -1
- package/web/.next/static/chunks/{8cc1aea0d82835be.js → 3a870fad0361102a.js} +1 -1
- package/web/.next/static/chunks/{60c6c3c30fba3b7c.js → 3f340791cd48969f.js} +1 -1
- package/web/.next/static/chunks/4f69aeac8fb161bb.js +1 -0
- package/web/.next/static/chunks/{1867fdb7f2c6035f.js → 4fbbaffba82909cc.js} +1 -1
- package/web/.next/static/chunks/{21502baa33ad728a.js → 7026524b541ba6e0.js} +2 -2
- package/web/.next/static/chunks/{de0704c3e73118cf.js → 7ca459865dbadc14.js} +1 -1
- package/web/.next/static/chunks/831b9f0d3f8c7d0a.js +1 -0
- package/web/.next/static/chunks/{ecfbc35ad11c83bb.js → a3a4ba7b54a09726.js} +1 -1
- package/web/.next/static/chunks/{88300dbc7c91abb2.js → b82119f8bb1d93e3.js} +1 -1
- package/web/.next/static/chunks/{683ec435a34ca112.js → d39caafcb2ac4843.js} +1 -1
- package/web/.next/static/chunks/fa556c575c788679.js +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__cb850066._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__cb850066._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_a9f57758._.js +0 -3
- package/web/.next/server/chunks/ssr/_a9f57758._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_c67ad133._.js +0 -3
- package/web/.next/static/chunks/0bce83a11c7a9383.js +0 -1
- package/web/.next/static/chunks/6a370f2709c81d83.js +0 -1
- package/web/.next/static/chunks/9e3e916a22d1121f.js +0 -1
- /package/web/.next/static/{rsS9eOHzCHbGCCwBS1fRh → iMG6ZbET-956f-LkX_CmQ}/_buildManifest.js +0 -0
- /package/web/.next/static/{rsS9eOHzCHbGCCwBS1fRh → iMG6ZbET-956f-LkX_CmQ}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{rsS9eOHzCHbGCCwBS1fRh → iMG6ZbET-956f-LkX_CmQ}/_ssgManifest.js +0 -0
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js
CHANGED
|
@@ -54,6 +54,11 @@ export function parseWorkerArgs(args) {
|
|
|
54
54
|
const resumeFromInterrupt = args.includes('--resume-from-interrupt');
|
|
55
55
|
const push = args.includes('--push');
|
|
56
56
|
const openPr = args.includes('--open-pr');
|
|
57
|
+
const forkAndPr = args.includes('--fork-and-pr');
|
|
58
|
+
const commitSpecs = !args.includes('--no-commit-specs');
|
|
59
|
+
const ciWatchEnabled = !args.includes('--no-ci-watch');
|
|
60
|
+
const enableEvidence = args.includes('--enable-evidence');
|
|
61
|
+
const commitEvidence = args.includes('--commit-evidence');
|
|
57
62
|
const fast = args.includes('--fast');
|
|
58
63
|
const threadIdx = args.indexOf('--thread-id');
|
|
59
64
|
const threadId = threadIdx !== -1 && threadIdx + 1 < args.length ? args[threadIdx + 1] : undefined;
|
|
@@ -83,6 +88,11 @@ export function parseWorkerArgs(args) {
|
|
|
83
88
|
resumeFromInterrupt,
|
|
84
89
|
push,
|
|
85
90
|
openPr,
|
|
91
|
+
forkAndPr,
|
|
92
|
+
commitSpecs,
|
|
93
|
+
ciWatchEnabled,
|
|
94
|
+
enableEvidence,
|
|
95
|
+
commitEvidence,
|
|
86
96
|
resumePayload,
|
|
87
97
|
agentType,
|
|
88
98
|
fast,
|
|
@@ -143,6 +153,8 @@ export async function runWorker(args) {
|
|
|
143
153
|
...(args.resumeFromInterrupt ? ['--resume-from-interrupt'] : []),
|
|
144
154
|
...(args.push ? ['--push'] : []),
|
|
145
155
|
...(args.openPr ? ['--open-pr'] : []),
|
|
156
|
+
...(args.forkAndPr ? ['--fork-and-pr'] : []),
|
|
157
|
+
...(args.commitSpecs === false ? ['--no-commit-specs'] : []),
|
|
146
158
|
...(args.resumePayload ? ['--resume-payload', args.resumePayload] : []),
|
|
147
159
|
...(args.agentType ? ['--agent-type', args.agentType] : []),
|
|
148
160
|
...(args.fast ? ['--fast'] : []),
|
|
@@ -185,6 +197,7 @@ export async function runWorker(args) {
|
|
|
185
197
|
localMergeSquash: (cwd, featureBranch, baseBranch, commitMessage, hasRemote) => gitPrService.localMergeSquash(cwd, featureBranch, baseBranch, commitMessage, hasRemote),
|
|
186
198
|
featureRepository,
|
|
187
199
|
gitPrService,
|
|
200
|
+
gitForkService: container.resolve('IGitForkService'),
|
|
188
201
|
cleanupFeatureWorktreeUseCase,
|
|
189
202
|
},
|
|
190
203
|
};
|
|
@@ -274,6 +287,11 @@ export async function runWorker(args) {
|
|
|
274
287
|
...(args.resumeReason ? { resumeReason: args.resumeReason } : {}),
|
|
275
288
|
push: args.push ?? false,
|
|
276
289
|
openPr: args.openPr ?? false,
|
|
290
|
+
forkAndPr: args.forkAndPr ?? false,
|
|
291
|
+
commitSpecs: args.commitSpecs ?? true,
|
|
292
|
+
ciWatchEnabled: args.ciWatchEnabled ?? true,
|
|
293
|
+
enableEvidence: args.enableEvidence ?? false,
|
|
294
|
+
commitEvidence: args.commitEvidence ?? false,
|
|
277
295
|
}, graphConfig);
|
|
278
296
|
}
|
|
279
297
|
else {
|
|
@@ -287,6 +305,11 @@ export async function runWorker(args) {
|
|
|
287
305
|
...(args.model ? { model: args.model } : {}),
|
|
288
306
|
push: args.push ?? false,
|
|
289
307
|
openPr: args.openPr ?? false,
|
|
308
|
+
forkAndPr: args.forkAndPr ?? false,
|
|
309
|
+
commitSpecs: args.commitSpecs ?? true,
|
|
310
|
+
ciWatchEnabled: args.ciWatchEnabled ?? true,
|
|
311
|
+
enableEvidence: args.enableEvidence ?? false,
|
|
312
|
+
commitEvidence: args.commitEvidence ?? false,
|
|
290
313
|
}, graphConfig);
|
|
291
314
|
}
|
|
292
315
|
log(`Graph invocation completed. Error: ${result.error ?? 'none'}`);
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* CI Watch/Fix Loop
|
|
3
3
|
*
|
|
4
|
-
* After a push, watches CI status
|
|
4
|
+
* After a push, watches CI status using an agent-based approach and attempts
|
|
5
|
+
* automatic fixes when CI fails. The agent follows CI/CD best practices:
|
|
6
|
+
* checks ALL runs, waits for ALL to complete, and reports accurate status.
|
|
7
|
+
*
|
|
5
8
|
* Respects configurable max attempts, timeout, and log size from settings.
|
|
6
9
|
*/
|
|
7
10
|
import type { IAgentExecutor } from '../../../../../../application/ports/output/agents/agent-executor.interface.js';
|
|
@@ -34,8 +37,8 @@ export interface CiWatchFixResult {
|
|
|
34
37
|
ciFixStatus: CiFixStatusValue;
|
|
35
38
|
}
|
|
36
39
|
/**
|
|
37
|
-
* Run the CI watch/fix loop. Watches for the initial CI result
|
|
38
|
-
* iteratively attempts fixes up to the configured maximum.
|
|
40
|
+
* Run the CI watch/fix loop. Watches for the initial CI result using an
|
|
41
|
+
* agent-based approach, then iteratively attempts fixes up to the configured maximum.
|
|
39
42
|
*
|
|
40
43
|
* Throws on timeout or exhausted attempts (after updating feature state).
|
|
41
44
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ci-watch-fix-loop.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ci-watch-fix-loop.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AACpG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yEAAyE,CAAC;AAClH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iEAAiE,CAAC;AACrG,OAAO,EAAE,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+DAA+D,CAAC;AAO3G,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,cAAc,CAAC;IACzB,YAAY,EAAE,aAAa,CAAC;IAC5B,iBAAiB,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC;CACpE;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,qBAAqB,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC/E,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,EAAE,UAAU,CAAC;CACjB;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAEpG,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,QAAQ,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,WAAW,EAAE,gBAAgB,CAAC;CAC/B;AAyED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CA4K3B"}
|
|
@@ -1,18 +1,70 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* CI Watch/Fix Loop
|
|
3
3
|
*
|
|
4
|
-
* After a push, watches CI status
|
|
4
|
+
* After a push, watches CI status using an agent-based approach and attempts
|
|
5
|
+
* automatic fixes when CI fails. The agent follows CI/CD best practices:
|
|
6
|
+
* checks ALL runs, waits for ALL to complete, and reports accurate status.
|
|
7
|
+
*
|
|
5
8
|
* Respects configurable max attempts, timeout, and log size from settings.
|
|
6
9
|
*/
|
|
7
|
-
import { GitPrError, GitPrErrorCode, } from '../../../../../../application/ports/output/services/git-pr-service.interface.js';
|
|
8
10
|
import { CiStatus } from '../../../../../../domain/generated/output.js';
|
|
9
11
|
import { retryExecute } from '../node-helpers.js';
|
|
10
|
-
import { buildCiWatchFixPrompt } from '../prompts/merge-prompts.js';
|
|
12
|
+
import { buildCiWatchFixPrompt, buildCiWatchPrompt } from '../prompts/merge-prompts.js';
|
|
13
|
+
import { parseCiWatchResult } from './merge-output-parser.js';
|
|
11
14
|
import { extractRunId, handleCiTerminalFailure, buildCiExhaustedError } from './ci-helpers.js';
|
|
12
15
|
import { getSettings } from '../../../../../services/settings.service.js';
|
|
16
|
+
import { recordPhaseStart, recordPhaseEnd } from '../../phase-timing-context.js';
|
|
13
17
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
18
|
+
* Watch CI using an agent call. The agent checks ALL runs for the branch,
|
|
19
|
+
* waits for ALL to complete, and reports structured CI_STATUS.
|
|
20
|
+
*
|
|
21
|
+
* Records a phase timing entry for the activity timeline.
|
|
22
|
+
*
|
|
23
|
+
* @returns Parsed CI status result with usage metrics
|
|
24
|
+
*/
|
|
25
|
+
async function watchCiViaAgent(executor, branch, options, timeoutMs, log) {
|
|
26
|
+
const watchOptions = { ...options, timeout: timeoutMs };
|
|
27
|
+
const watchPrompt = buildCiWatchPrompt(branch);
|
|
28
|
+
const watchStart = Date.now();
|
|
29
|
+
const timingId = await recordPhaseStart('merge:ci-watch', {
|
|
30
|
+
agentType: executor.agentType,
|
|
31
|
+
prompt: watchPrompt,
|
|
32
|
+
});
|
|
33
|
+
try {
|
|
34
|
+
const result = await retryExecute(executor, watchPrompt, watchOptions, {
|
|
35
|
+
maxAttempts: 1,
|
|
36
|
+
logger: log,
|
|
37
|
+
});
|
|
38
|
+
const elapsed = Date.now() - watchStart;
|
|
39
|
+
await recordPhaseEnd(timingId, elapsed, {
|
|
40
|
+
inputTokens: result.usage?.inputTokens,
|
|
41
|
+
outputTokens: result.usage?.outputTokens,
|
|
42
|
+
costUsd: result.usage?.costUsd,
|
|
43
|
+
numTurns: result.usage?.numTurns,
|
|
44
|
+
durationApiMs: result.usage?.durationApiMs,
|
|
45
|
+
exitCode: 'success',
|
|
46
|
+
});
|
|
47
|
+
const parsed = parseCiWatchResult(result.result);
|
|
48
|
+
return { ...parsed, usage: result.usage };
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
const elapsed = Date.now() - watchStart;
|
|
52
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
53
|
+
await recordPhaseEnd(timingId, elapsed, {
|
|
54
|
+
exitCode: 'error',
|
|
55
|
+
errorMessage: errMsg.slice(0, 500),
|
|
56
|
+
});
|
|
57
|
+
// Check if this is a timeout
|
|
58
|
+
if (errMsg.includes('timed out') || errMsg.includes('timeout')) {
|
|
59
|
+
return { status: 'failure', summary: 'CI watch timed out', timedOut: true };
|
|
60
|
+
}
|
|
61
|
+
// For other errors, treat as indeterminate (failure)
|
|
62
|
+
return { status: 'failure', summary: `CI watch agent error: ${errMsg.slice(0, 200)}` };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Run the CI watch/fix loop. Watches for the initial CI result using an
|
|
67
|
+
* agent-based approach, then iteratively attempts fixes up to the configured maximum.
|
|
16
68
|
*
|
|
17
69
|
* Throws on timeout or exhausted attempts (after updating feature state).
|
|
18
70
|
*/
|
|
@@ -23,12 +75,11 @@ export async function runCiWatchFixLoop(deps, params) {
|
|
|
23
75
|
const maxAttempts = settings.workflow?.ciMaxFixAttempts ?? 3;
|
|
24
76
|
const timeoutMs = settings.workflow?.ciWatchTimeoutMs ?? 600_000;
|
|
25
77
|
const logMaxChars = settings.workflow?.ciLogMaxChars ?? 50_000;
|
|
26
|
-
const pollInterval = settings.workflow?.ciWatchPollIntervalSeconds ?? 30;
|
|
27
78
|
let ciFixAttempts = params.existingAttempts;
|
|
28
79
|
const ciFixHistory = [];
|
|
29
80
|
let ciFixStatus;
|
|
30
81
|
log.info(`Starting CI watch (maxAttempts=${maxAttempts}, timeout=${timeoutMs}ms)`);
|
|
31
|
-
// Check if any CI run exists for this branch
|
|
82
|
+
// Check if any CI run exists for this branch (lightweight check before spawning agent)
|
|
32
83
|
let initialCiStatus;
|
|
33
84
|
try {
|
|
34
85
|
initialCiStatus = await gitPrService.getCiStatus(cwd, branch);
|
|
@@ -65,30 +116,22 @@ export async function runCiWatchFixLoop(deps, params) {
|
|
|
65
116
|
return { ciStatus: CiStatus.Success, ciFixAttempts, ciFixHistory, ciFixStatus: 'idle' };
|
|
66
117
|
}
|
|
67
118
|
let runUrl = initialCiStatus.runUrl;
|
|
68
|
-
// Initial CI watch
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
watchResult = await gitPrService.watchCi(cwd, branch, timeoutMs, pollInterval);
|
|
72
|
-
}
|
|
73
|
-
catch (err) {
|
|
74
|
-
if (err instanceof GitPrError && err.code === GitPrErrorCode.CI_TIMEOUT) {
|
|
75
|
-
log.info('Initial CI watch timed out');
|
|
76
|
-
ciFixHistory.push({
|
|
77
|
-
attempt: ciFixAttempts + 1,
|
|
78
|
-
startedAt: new Date().toISOString(),
|
|
79
|
-
failureSummary: 'CI watch timed out',
|
|
80
|
-
outcome: 'timeout',
|
|
81
|
-
});
|
|
82
|
-
await handleCiTerminalFailure(feature, prUrl, prNumber, deps.featureRepository, messages);
|
|
83
|
-
throw buildCiExhaustedError(ciFixAttempts + 1, ciFixHistory, 'timeout');
|
|
84
|
-
}
|
|
85
|
-
throw err;
|
|
86
|
-
}
|
|
87
|
-
// Use the run URL from watchCi — it reflects the actual run watched,
|
|
88
|
-
// which may differ from the initial getCiStatus() result when multiple
|
|
89
|
-
// workflow runs exist for the same branch.
|
|
119
|
+
// Initial CI watch via agent
|
|
120
|
+
log.info('Watching CI via agent (checks ALL runs)');
|
|
121
|
+
const watchResult = await watchCiViaAgent(executor, branch, options, timeoutMs, log);
|
|
90
122
|
if (watchResult.runUrl)
|
|
91
123
|
runUrl = watchResult.runUrl;
|
|
124
|
+
if (watchResult.timedOut) {
|
|
125
|
+
log.info('Initial CI watch timed out');
|
|
126
|
+
ciFixHistory.push({
|
|
127
|
+
attempt: ciFixAttempts + 1,
|
|
128
|
+
startedAt: new Date().toISOString(),
|
|
129
|
+
failureSummary: 'CI watch timed out',
|
|
130
|
+
outcome: 'timeout',
|
|
131
|
+
});
|
|
132
|
+
await handleCiTerminalFailure(feature, prUrl, prNumber, deps.featureRepository, messages);
|
|
133
|
+
throw buildCiExhaustedError(ciFixAttempts + 1, ciFixHistory, 'timeout');
|
|
134
|
+
}
|
|
92
135
|
if (watchResult.status === 'success') {
|
|
93
136
|
log.info('CI passed on first watch');
|
|
94
137
|
return { ciStatus: CiStatus.Success, ciFixAttempts, ciFixHistory, ciFixStatus: 'success' };
|
|
@@ -101,23 +144,40 @@ export async function runCiWatchFixLoop(deps, params) {
|
|
|
101
144
|
ciFixStatus = 'exhausted';
|
|
102
145
|
break;
|
|
103
146
|
}
|
|
104
|
-
// Fetch failure logs
|
|
147
|
+
// Fetch failure logs for context
|
|
105
148
|
const runId = extractRunId(runUrl) ?? '';
|
|
106
149
|
const failureLogs = await gitPrService.getFailureLogs(cwd, runId, branch, logMaxChars);
|
|
107
150
|
const startedAt = new Date().toISOString();
|
|
108
151
|
log.info(`CI fix attempt ${ciFixAttempts + 1}/${maxAttempts} for run ${runId}`);
|
|
152
|
+
// Record fix phase timing
|
|
153
|
+
const fixStart = Date.now();
|
|
154
|
+
const fixTimingId = await recordPhaseStart('merge:ci-fix', {
|
|
155
|
+
agentType: executor.agentType,
|
|
156
|
+
});
|
|
109
157
|
// Invoke fix executor — maxAttempts:1 prevents retryExecute's internal
|
|
110
158
|
// retry logic from consuming CI fix attempts behind the outer loop's back.
|
|
111
|
-
// Each CI fix is a unique attempt with distinct failure logs and prompt;
|
|
112
|
-
// the outer loop already handles iteration.
|
|
113
159
|
const fixPrompt = buildCiWatchFixPrompt(failureLogs, ciFixAttempts + 1, maxAttempts, branch);
|
|
114
160
|
try {
|
|
115
|
-
await retryExecute(executor, fixPrompt, options, {
|
|
161
|
+
const fixResult = await retryExecute(executor, fixPrompt, options, {
|
|
162
|
+
maxAttempts: 1,
|
|
163
|
+
logger: log,
|
|
164
|
+
});
|
|
165
|
+
await recordPhaseEnd(fixTimingId, Date.now() - fixStart, {
|
|
166
|
+
inputTokens: fixResult.usage?.inputTokens,
|
|
167
|
+
outputTokens: fixResult.usage?.outputTokens,
|
|
168
|
+
costUsd: fixResult.usage?.costUsd,
|
|
169
|
+
numTurns: fixResult.usage?.numTurns,
|
|
170
|
+
durationApiMs: fixResult.usage?.durationApiMs,
|
|
171
|
+
exitCode: 'success',
|
|
172
|
+
});
|
|
116
173
|
}
|
|
117
174
|
catch (execErr) {
|
|
118
175
|
// If the fix executor fails, count it as a failed attempt and continue
|
|
119
|
-
// the loop rather than killing the entire CI fix process.
|
|
120
176
|
const execMsg = execErr instanceof Error ? execErr.message : String(execErr);
|
|
177
|
+
await recordPhaseEnd(fixTimingId, Date.now() - fixStart, {
|
|
178
|
+
exitCode: 'error',
|
|
179
|
+
errorMessage: execMsg.slice(0, 500),
|
|
180
|
+
});
|
|
121
181
|
log.info(`CI fix executor failed on attempt ${ciFixAttempts + 1}: ${execMsg}`);
|
|
122
182
|
ciFixAttempts++;
|
|
123
183
|
ciFixHistory.push({
|
|
@@ -130,44 +190,22 @@ export async function runCiWatchFixLoop(deps, params) {
|
|
|
130
190
|
continue;
|
|
131
191
|
}
|
|
132
192
|
ciFixAttempts++;
|
|
133
|
-
//
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
fixWatchResult = await gitPrService.watchCi(cwd, branch, timeoutMs, pollInterval);
|
|
141
|
-
}
|
|
142
|
-
catch (err) {
|
|
143
|
-
if (err instanceof GitPrError && err.code === GitPrErrorCode.CI_TIMEOUT) {
|
|
144
|
-
log.info(`CI watch timed out during fix attempt ${ciFixAttempts}`);
|
|
145
|
-
ciFixHistory.push({
|
|
146
|
-
attempt: ciFixAttempts,
|
|
147
|
-
startedAt,
|
|
148
|
-
failureSummary: failureLogs.slice(0, 500),
|
|
149
|
-
outcome: 'timeout',
|
|
150
|
-
});
|
|
151
|
-
ciFixStatus = 'timeout';
|
|
152
|
-
break;
|
|
153
|
-
}
|
|
154
|
-
// For non-timeout watchCi errors (e.g. GIT_ERROR), treat as a failed
|
|
155
|
-
// attempt and continue the loop instead of killing it.
|
|
156
|
-
const watchMsg = err instanceof Error ? err.message : String(err);
|
|
157
|
-
log.info(`CI watch failed during fix attempt ${ciFixAttempts}: ${watchMsg}`);
|
|
193
|
+
// Watch CI after fix via agent (agent checks ALL runs for updated branch)
|
|
194
|
+
log.info('Watching CI after fix via agent');
|
|
195
|
+
const fixWatchResult = await watchCiViaAgent(executor, branch, options, timeoutMs, log);
|
|
196
|
+
if (fixWatchResult.runUrl)
|
|
197
|
+
runUrl = fixWatchResult.runUrl;
|
|
198
|
+
if (fixWatchResult.timedOut) {
|
|
199
|
+
log.info(`CI watch timed out during fix attempt ${ciFixAttempts}`);
|
|
158
200
|
ciFixHistory.push({
|
|
159
201
|
attempt: ciFixAttempts,
|
|
160
202
|
startedAt,
|
|
161
203
|
failureSummary: failureLogs.slice(0, 500),
|
|
162
|
-
outcome: '
|
|
204
|
+
outcome: 'timeout',
|
|
163
205
|
});
|
|
164
|
-
|
|
165
|
-
|
|
206
|
+
ciFixStatus = 'timeout';
|
|
207
|
+
break;
|
|
166
208
|
}
|
|
167
|
-
// Update runUrl to the run that was actually watched (avoids mismatch
|
|
168
|
-
// when multiple workflow runs exist for the same branch).
|
|
169
|
-
if (fixWatchResult.runUrl)
|
|
170
|
-
runUrl = fixWatchResult.runUrl;
|
|
171
209
|
const outcome = fixWatchResult.status === 'success' ? 'fixed' : 'failed';
|
|
172
210
|
ciFixHistory.push({
|
|
173
211
|
attempt: ciFixAttempts,
|
|
@@ -8,6 +8,11 @@ export interface PrParseResult {
|
|
|
8
8
|
url: string;
|
|
9
9
|
number: number;
|
|
10
10
|
}
|
|
11
|
+
export interface CiWatchParseResult {
|
|
12
|
+
status: 'success' | 'failure';
|
|
13
|
+
summary?: string;
|
|
14
|
+
runUrl?: string;
|
|
15
|
+
}
|
|
11
16
|
/**
|
|
12
17
|
* Extract the first commit SHA from agent output text.
|
|
13
18
|
* Looks for git commit output format `[branch SHA]` or `commit SHA`.
|
|
@@ -19,4 +24,11 @@ export declare function parseCommitHash(output: string): string | null;
|
|
|
19
24
|
* Returns null if no PR URL found.
|
|
20
25
|
*/
|
|
21
26
|
export declare function parsePrUrl(output: string): PrParseResult | null;
|
|
27
|
+
/**
|
|
28
|
+
* Extract CI watch result from agent output text.
|
|
29
|
+
* Looks for CI_STATUS: PASSED or CI_STATUS: FAILED markers.
|
|
30
|
+
* When multiple CI_STATUS markers appear, uses the last one.
|
|
31
|
+
* Returns failure with diagnostic summary if no marker found.
|
|
32
|
+
*/
|
|
33
|
+
export declare function parseCiWatchResult(output: string): CiWatchParseResult;
|
|
22
34
|
//# sourceMappingURL=merge-output-parser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge-output-parser.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge-output-parser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI7D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAI/D"}
|
|
1
|
+
{"version":3,"file":"merge-output-parser.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge-output-parser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AASD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI7D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAI/D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,CAuBrE"}
|
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
const COMMIT_SHA_RE = /\[[\w/.-]+\s+([0-9a-f]{7,40})\]|(?:commit\s+)([0-9a-f]{7,40})/i;
|
|
10
10
|
// Matches GitHub PR URL: https://github.com/owner/repo/pull/123
|
|
11
11
|
const PR_URL_RE = /(https:\/\/github\.com\/[\w.-]+\/[\w.-]+\/pull\/(\d+))/;
|
|
12
|
+
// Matches CI_STATUS: PASSED or CI_STATUS: FAILED — <summary>
|
|
13
|
+
const CI_STATUS_PASSED_RE = /CI_STATUS:\s*PASSED/;
|
|
14
|
+
const CI_STATUS_FAILED_RE = /CI_STATUS:\s*FAILED(?:\s*—\s*(.+))?/;
|
|
15
|
+
// Matches GitHub Actions run URL
|
|
16
|
+
const RUN_URL_RE = /(https:\/\/github\.com\/[\w.-]+\/[\w.-]+\/actions\/runs\/\d+)/;
|
|
12
17
|
/**
|
|
13
18
|
* Extract the first commit SHA from agent output text.
|
|
14
19
|
* Looks for git commit output format `[branch SHA]` or `commit SHA`.
|
|
@@ -30,3 +35,31 @@ export function parsePrUrl(output) {
|
|
|
30
35
|
return null;
|
|
31
36
|
return { url: match[1], number: parseInt(match[2], 10) };
|
|
32
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Extract CI watch result from agent output text.
|
|
40
|
+
* Looks for CI_STATUS: PASSED or CI_STATUS: FAILED markers.
|
|
41
|
+
* When multiple CI_STATUS markers appear, uses the last one.
|
|
42
|
+
* Returns failure with diagnostic summary if no marker found.
|
|
43
|
+
*/
|
|
44
|
+
export function parseCiWatchResult(output) {
|
|
45
|
+
const runUrlMatch = output.match(RUN_URL_RE);
|
|
46
|
+
const runUrl = runUrlMatch ? runUrlMatch[1] : undefined;
|
|
47
|
+
// Split into lines and check from bottom up (last status wins)
|
|
48
|
+
const lines = output.split('\n');
|
|
49
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
50
|
+
const line = lines[i];
|
|
51
|
+
if (CI_STATUS_PASSED_RE.test(line)) {
|
|
52
|
+
return { status: 'success', runUrl };
|
|
53
|
+
}
|
|
54
|
+
const failedMatch = line.match(CI_STATUS_FAILED_RE);
|
|
55
|
+
if (failedMatch) {
|
|
56
|
+
const summary = failedMatch[1]?.trim() || 'CI failed (no details provided)';
|
|
57
|
+
return { status: 'failure', summary, runUrl };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
status: 'failure',
|
|
62
|
+
summary: 'CI status could not be determined from agent output',
|
|
63
|
+
runUrl,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
@@ -17,6 +17,7 @@ import type { FeatureAgentState } from '../../state.js';
|
|
|
17
17
|
import type { IFeatureRepository } from '../../../../../../application/ports/output/repositories/feature-repository.interface.js';
|
|
18
18
|
import type { DiffSummary, IGitPrService } from '../../../../../../application/ports/output/services/git-pr-service.interface.js';
|
|
19
19
|
import type { CleanupFeatureWorktreeUseCase } from '../../../../../../application/use-cases/features/cleanup-feature-worktree.use-case.js';
|
|
20
|
+
import type { IGitForkService } from '../../../../../../application/ports/output/services/git-fork-service.interface.js';
|
|
20
21
|
export interface MergeNodeDeps {
|
|
21
22
|
executor: IAgentExecutor;
|
|
22
23
|
getDiffSummary: (cwd: string, baseBranch: string) => Promise<DiffSummary>;
|
|
@@ -37,6 +38,7 @@ export interface MergeNodeDeps {
|
|
|
37
38
|
*/
|
|
38
39
|
revParse: (cwd: string, ref: string) => Promise<string>;
|
|
39
40
|
gitPrService: IGitPrService;
|
|
41
|
+
gitForkService?: IGitForkService;
|
|
40
42
|
cleanupFeatureWorktreeUseCase: Pick<CleanupFeatureWorktreeUseCase, 'execute'>;
|
|
41
43
|
}
|
|
42
44
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AACpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yEAAyE,CAAC;AAClH,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACd,MAAM,iEAAiE,CAAC;AAoBzE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,uEAAuE,CAAC;
|
|
1
|
+
{"version":3,"file":"merge.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AACpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yEAAyE,CAAC;AAClH,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACd,MAAM,iEAAiE,CAAC;AAoBzE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,uEAAuE,CAAC;AAC3H,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mEAAmE,CAAC;AAEzG,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,cAAc,CAAC;IACzB,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1E,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD,iBAAiB,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC;IACnE;;OAEG;IACH,gBAAgB,EAAE,CAChB,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EACrB,SAAS,CAAC,EAAE,OAAO,KAChB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB;;;OAGG;IACH,WAAW,EAAE,CACX,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,eAAe,CAAC,EAAE,MAAM,KACrB,OAAO,CAAC,OAAO,CAAC,CAAC;IACtB;;OAEG;IACH,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACxD,YAAY,EAAE,aAAa,CAAC;IAC5B,cAAc,CAAC,EAAE,eAAe,CAAC;IACjC,6BAA6B,EAAE,IAAI,CAAC,6BAA6B,EAAE,SAAS,CAAC,CAAC;CAC/E;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,IAGnC,OAAO,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAgY7E"}
|
|
@@ -220,6 +220,56 @@ export function createMergeNode(deps) {
|
|
|
220
220
|
ciStatus = feature.pr.ciStatus ?? ciStatus;
|
|
221
221
|
}
|
|
222
222
|
}
|
|
223
|
+
// --- Fork-and-PR flow ---
|
|
224
|
+
// When forkAndPr=true, fork the repo, push to the fork, create upstream PR,
|
|
225
|
+
// then transition to AwaitingUpstream instead of merging.
|
|
226
|
+
if (state.forkAndPr && deps.gitForkService) {
|
|
227
|
+
log.info('Fork-and-PR flow: forking repo and creating upstream PR');
|
|
228
|
+
await deps.gitForkService.forkRepository(cwd);
|
|
229
|
+
log.info('Repository forked, remotes remapped');
|
|
230
|
+
await deps.gitForkService.pushToFork(cwd, branch);
|
|
231
|
+
log.info(`Branch ${branch} pushed to fork`);
|
|
232
|
+
const upstreamPr = await deps.gitForkService.createUpstreamPr(cwd, feature?.name ?? branch, feature?.description ?? '', branch, baseBranch);
|
|
233
|
+
log.info(`Upstream PR created: ${upstreamPr.url}`);
|
|
234
|
+
messages.push(`[merge] Upstream PR created: ${upstreamPr.url}`);
|
|
235
|
+
if (feature) {
|
|
236
|
+
await deps.featureRepository.update({
|
|
237
|
+
...feature,
|
|
238
|
+
lifecycle: SdlcLifecycle.AwaitingUpstream,
|
|
239
|
+
pr: {
|
|
240
|
+
...(feature.pr ?? { url: '', number: 0, status: PrStatus.Open }),
|
|
241
|
+
...(commitHash ? { commitHash } : {}),
|
|
242
|
+
upstreamPrUrl: upstreamPr.url,
|
|
243
|
+
upstreamPrNumber: upstreamPr.number,
|
|
244
|
+
upstreamPrStatus: PrStatus.Open,
|
|
245
|
+
},
|
|
246
|
+
updatedAt: new Date(),
|
|
247
|
+
});
|
|
248
|
+
messages.push(`[merge] Feature lifecycle → AwaitingUpstream`);
|
|
249
|
+
}
|
|
250
|
+
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
251
|
+
await recordPhaseEnd(mergeTimingId, Date.now() - startTime, {
|
|
252
|
+
inputTokens: totalInputTokens || undefined,
|
|
253
|
+
outputTokens: totalOutputTokens || undefined,
|
|
254
|
+
exitCode: 'success',
|
|
255
|
+
});
|
|
256
|
+
messages.push(`[merge] Complete (${elapsed}s)`);
|
|
257
|
+
log.info(`Fork-and-PR merge flow complete (${elapsed}s)`);
|
|
258
|
+
return {
|
|
259
|
+
currentNode: 'merge',
|
|
260
|
+
messages,
|
|
261
|
+
commitHash,
|
|
262
|
+
prUrl,
|
|
263
|
+
prNumber,
|
|
264
|
+
ciStatus,
|
|
265
|
+
ciFixAttempts,
|
|
266
|
+
ciFixHistory,
|
|
267
|
+
ciFixStatus,
|
|
268
|
+
_approvalAction: null,
|
|
269
|
+
_rejectionFeedback: null,
|
|
270
|
+
_needsReexecution: false,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
223
273
|
// --- Merge ---
|
|
224
274
|
// Merge when: allowMerge is true (auto-merge), OR user explicitly
|
|
225
275
|
// approved at the merge gate (isResumeAfterInterrupt means they
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts
CHANGED
|
@@ -159,6 +159,14 @@ export declare function buildCommitPushBlock(opts: {
|
|
|
159
159
|
* context so the agent knows to check existing work before proceeding.
|
|
160
160
|
*/
|
|
161
161
|
export declare function buildResumeContext(resumeReason: string | undefined): string;
|
|
162
|
+
/**
|
|
163
|
+
* Safety net: remove spec-file commits the agent made despite being told not to.
|
|
164
|
+
*
|
|
165
|
+
* When commitSpecs=false and the agent ignored the "do NOT commit" instruction,
|
|
166
|
+
* this function finds the most recent commit that touches the spec directory and
|
|
167
|
+
* soft-resets it so the files remain on disk (for local use) but are not committed.
|
|
168
|
+
*/
|
|
169
|
+
export declare function removeSpecCommitsIfNeeded(state: FeatureAgentState, nodeName: string, log: NodeLogger): void;
|
|
162
170
|
/**
|
|
163
171
|
* Execute a node with consistent logging and error handling.
|
|
164
172
|
*
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"node-helpers.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.js
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import yaml from 'js-yaml';
|
|
8
8
|
import { mkdirSync, readFileSync, writeFileSync, renameSync, unlinkSync } from 'node:fs';
|
|
9
|
-
import {
|
|
9
|
+
import { execSync } from 'node:child_process';
|
|
10
|
+
import { join, dirname, relative } from 'node:path';
|
|
10
11
|
import { interrupt, isGraphBubbleUp } from '@langchain/langgraph';
|
|
11
12
|
import { hasSettings, getSettings } from '../../../../services/settings.service.js';
|
|
12
13
|
import { reportNodeStart } from '../heartbeat.js';
|
|
@@ -394,6 +395,42 @@ Before proceeding with this phase:
|
|
|
394
395
|
|
|
395
396
|
`;
|
|
396
397
|
}
|
|
398
|
+
/** Spec-only phases whose commits should be removed when commitSpecs=false. */
|
|
399
|
+
const SPEC_PHASE_NODES = new Set(['analyze', 'requirements', 'research', 'plan']);
|
|
400
|
+
/**
|
|
401
|
+
* Safety net: remove spec-file commits the agent made despite being told not to.
|
|
402
|
+
*
|
|
403
|
+
* When commitSpecs=false and the agent ignored the "do NOT commit" instruction,
|
|
404
|
+
* this function finds the most recent commit that touches the spec directory and
|
|
405
|
+
* soft-resets it so the files remain on disk (for local use) but are not committed.
|
|
406
|
+
*/
|
|
407
|
+
export function removeSpecCommitsIfNeeded(state, nodeName, log) {
|
|
408
|
+
if (state.commitSpecs)
|
|
409
|
+
return;
|
|
410
|
+
if (!SPEC_PHASE_NODES.has(nodeName))
|
|
411
|
+
return;
|
|
412
|
+
const cwd = state.worktreePath || state.repositoryPath;
|
|
413
|
+
const specRelDir = relative(cwd, state.specDir).replaceAll('\\', '/');
|
|
414
|
+
try {
|
|
415
|
+
// Check if HEAD commit touches spec files
|
|
416
|
+
const filesInHead = execSync(`git diff --name-only HEAD~1 HEAD -- "${specRelDir}"`, {
|
|
417
|
+
cwd,
|
|
418
|
+
encoding: 'utf-8',
|
|
419
|
+
windowsHide: true,
|
|
420
|
+
}).trim();
|
|
421
|
+
if (!filesInHead)
|
|
422
|
+
return;
|
|
423
|
+
log.info(`commitSpecs=false but agent committed spec files: ${filesInHead.split('\n').join(', ')}. Soft-resetting to undo.`);
|
|
424
|
+
// Soft-reset the last commit so spec files are unstaged but kept on disk
|
|
425
|
+
execSync('git reset --soft HEAD~1', { cwd, windowsHide: true });
|
|
426
|
+
// Unstage the spec files (keep them as untracked/modified on disk)
|
|
427
|
+
execSync(`git reset HEAD -- "${specRelDir}"`, { cwd, windowsHide: true });
|
|
428
|
+
}
|
|
429
|
+
catch {
|
|
430
|
+
// If git commands fail (e.g., no prior commit, detached HEAD), log and continue
|
|
431
|
+
log.info('Failed to check/remove spec commits — continuing');
|
|
432
|
+
}
|
|
433
|
+
}
|
|
397
434
|
/**
|
|
398
435
|
* Execute a node with consistent logging and error handling.
|
|
399
436
|
*
|
|
@@ -480,6 +517,8 @@ export function executeNode(nodeName, executor, buildPrompt) {
|
|
|
480
517
|
durationApiMs: result.usage?.durationApiMs,
|
|
481
518
|
exitCode: 'success',
|
|
482
519
|
});
|
|
520
|
+
// Safety net: undo spec commits if commitSpecs=false
|
|
521
|
+
removeSpecCommitsIfNeeded(state, nodeName, log);
|
|
483
522
|
// Mark phase complete BEFORE interrupting so that on resume the
|
|
484
523
|
// node detects the work is already done and returns early.
|
|
485
524
|
markPhaseComplete(state.specDir, nodeName, log);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyze.prompt.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/analyze.prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"analyze.prompt.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/analyze.prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAiHnE"}
|
|
@@ -36,9 +36,9 @@ Write your analysis to: ${state.specDir}/spec.yaml
|
|
|
36
36
|
|
|
37
37
|
You MUST write the COMPLETE file (not a partial update). Preserve the existing name/number/branch fields and update everything else. Use this YAML structure:
|
|
38
38
|
|
|
39
|
-
name: (keep existing)
|
|
40
|
-
number: (keep existing)
|
|
41
|
-
branch: (keep existing)
|
|
39
|
+
name: (keep existing — string)
|
|
40
|
+
number: (keep existing — MUST be a bare integer, e.g. 2, NOT "002" or "2")
|
|
41
|
+
branch: (keep existing — string)
|
|
42
42
|
oneLiner: (concise one-line description of the feature)
|
|
43
43
|
summary: >
|
|
44
44
|
(2-3 sentence summary of what this feature involves based on your analysis)
|
|
@@ -107,10 +107,12 @@ You MUST write the COMPLETE file (not a partial update). Preserve the existing n
|
|
|
107
107
|
- Do NOT start implementing the feature
|
|
108
108
|
- Keep your analysis thorough but concise
|
|
109
109
|
|
|
110
|
-
${
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
110
|
+
${state.commitSpecs
|
|
111
|
+
? buildCommitPushBlock({
|
|
112
|
+
push: state.push,
|
|
113
|
+
files: [`${state.specDir}/spec.yaml`],
|
|
114
|
+
commitHint: 'docs(specs): analyze repository and define spec',
|
|
115
|
+
skipVerification: true,
|
|
116
|
+
})
|
|
117
|
+
: `## Git Operations\n\nDo NOT commit or push any spec files. Spec files are managed locally only.`}`;
|
|
116
118
|
}
|
|
@@ -44,4 +44,14 @@ export declare function buildCommitPushPrPrompt(state: FeatureAgentState, branch
|
|
|
44
44
|
* @param branch - Feature branch name to push to after fixing
|
|
45
45
|
*/
|
|
46
46
|
export declare function buildCiWatchFixPrompt(failureLogs: string, attemptNumber: number, maxAttempts: number, branch: string): string;
|
|
47
|
+
/**
|
|
48
|
+
* Build a prompt for the CI watch agent call.
|
|
49
|
+
*
|
|
50
|
+
* Instructs the agent to check ALL CI runs for a branch, wait for all
|
|
51
|
+
* to complete, verify every run passed, and report structured status.
|
|
52
|
+
* Generic — works with any git/gh repo, not tied to specific workflows.
|
|
53
|
+
*
|
|
54
|
+
* @param branch - Feature branch name to watch CI for
|
|
55
|
+
*/
|
|
56
|
+
export declare function buildCiWatchPrompt(branch: string): string;
|
|
47
57
|
//# sourceMappingURL=merge-prompts.d.ts.map
|