@shepai/cli 1.129.3 → 1.129.4-pr396.5d604d5
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/FeatureFlags.yaml +5 -0
- package/dist/packages/core/src/application/ports/output/agents/phase-timing-repository.interface.d.ts +1 -1
- package/dist/packages/core/src/application/ports/output/agents/phase-timing-repository.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts +73 -5
- package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.js +6 -4
- package/dist/packages/core/src/application/use-cases/features/rebase-feature-on-main.use-case.d.ts +28 -0
- package/dist/packages/core/src/application/use-cases/features/rebase-feature-on-main.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/features/rebase-feature-on-main.use-case.js +81 -0
- package/dist/packages/core/src/application/use-cases/repositories/sync-repository-main.use-case.d.ts +16 -0
- package/dist/packages/core/src/application/use-cases/repositories/sync-repository-main.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/repositories/sync-repository-main.use-case.js +43 -0
- package/dist/packages/core/src/domain/factories/settings-defaults.factory.d.ts.map +1 -1
- package/dist/packages/core/src/domain/factories/settings-defaults.factory.js +1 -0
- package/dist/packages/core/src/domain/generated/output.d.ts +4 -0
- package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +15 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts +1 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.js +2 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/042-add-feature-flag-git-rebase-sync.d.ts +11 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/042-add-feature-flag-git-rebase-sync.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/042-add-feature-flag-git-rebase-sync.js +17 -0
- package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.js +3 -2
- package/dist/packages/core/src/infrastructure/services/agents/conflict-resolution/conflict-resolution.prompt.d.ts +35 -0
- package/dist/packages/core/src/infrastructure/services/agents/conflict-resolution/conflict-resolution.prompt.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/conflict-resolution/conflict-resolution.prompt.js +66 -0
- package/dist/packages/core/src/infrastructure/services/agents/conflict-resolution/conflict-resolution.service.d.ts +42 -0
- package/dist/packages/core/src/infrastructure/services/agents/conflict-resolution/conflict-resolution.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/conflict-resolution/conflict-resolution.service.js +169 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/evidence.node.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/evidence.node.js +21 -5
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/fast-implement.node.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/fast-implement.node.js +20 -4
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/implement.node.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/implement.node.js +71 -10
- 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 +2 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/phase-timing-context.d.ts +8 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/phase-timing-context.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/phase-timing-context.js +16 -0
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts +6 -0
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +134 -0
- package/dist/src/presentation/web/app/(dashboard)/get-graph-data.d.ts.map +1 -1
- package/dist/src/presentation/web/app/(dashboard)/get-graph-data.js +5 -12
- package/dist/src/presentation/web/app/actions/get-feature-phase-timings.d.ts +1 -0
- package/dist/src/presentation/web/app/actions/get-feature-phase-timings.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/get-feature-phase-timings.js +1 -0
- package/dist/src/presentation/web/app/actions/rebase-feature.d.ts +5 -0
- package/dist/src/presentation/web/app/actions/rebase-feature.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/rebase-feature.js +16 -0
- package/dist/src/presentation/web/app/actions/sync-repository.d.ts +5 -0
- package/dist/src/presentation/web/app/actions/sync-repository.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/sync-repository.js +16 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +22 -5
- package/dist/src/presentation/web/components/common/control-center-drawer/repository-drawer-client.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/repository-drawer-client.js +4 -4
- package/dist/src/presentation/web/components/common/control-center-drawer/use-artifact-fetch.d.ts +2 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/use-artifact-fetch.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/use-artifact-fetch.js +3 -2
- package/dist/src/presentation/web/components/common/feature-drawer/use-feature-actions.d.ts +4 -0
- package/dist/src/presentation/web/components/common/feature-drawer/use-feature-actions.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer/use-feature-actions.js +32 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.js +17 -4
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.d.ts +4 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.js +3 -3
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.d.ts +4 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.js +8 -3
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts +6 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.js +30 -0
- package/dist/src/presentation/web/components/common/open-action-menu/open-action-menu.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/open-action-menu/open-action-menu.stories.js +3 -0
- package/dist/src/presentation/web/components/common/repository-node/repository-drawer.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-drawer.js +5 -3
- package/dist/src/presentation/web/components/common/repository-node/repository-node.js +1 -1
- package/dist/src/presentation/web/components/common/repository-node/use-repository-actions.d.ts +4 -0
- package/dist/src/presentation/web/components/common/repository-node/use-repository-actions.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/repository-node/use-repository-actions.js +11 -0
- package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.js +3 -0
- package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.stories.js +3 -0
- package/dist/src/presentation/web/components/features/settings/settings-page-client.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/settings-page-client.js +5 -0
- package/dist/src/presentation/web/components/features/settings/settings-page-client.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/settings-page-client.stories.js +1 -0
- package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.stories.js +1 -0
- package/dist/src/presentation/web/hooks/feature-flags-context.d.ts.map +1 -1
- package/dist/src/presentation/web/hooks/feature-flags-context.js +1 -0
- package/dist/src/presentation/web/lib/feature-flags.d.ts +2 -0
- package/dist/src/presentation/web/lib/feature-flags.d.ts.map +1 -1
- package/dist/src/presentation/web/lib/feature-flags.js +5 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/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 +63 -48
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +2 -2
- 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 +63 -48
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js +2 -2
- 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 +90 -60
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +2 -2
- 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 +90 -60
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +2 -2
- 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 +59 -44
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +2 -2
- 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 +63 -48
- package/web/.next/server/app/(dashboard)/create/page.js +2 -2
- 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 +90 -60
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +2 -2
- 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 +90 -60
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +2 -2
- 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 +59 -44
- package/web/.next/server/app/(dashboard)/page.js +2 -2
- 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 +59 -44
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +2 -2
- 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/api/attachments/preview/route.js.nft.json +1 -1
- package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
- package/web/.next/server/app/api/graph-data/route.js.nft.json +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.js.nft.json +1 -1
- 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.js.nft.json +1 -1
- 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/[root-of-the-server]__a402b567._.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__bc532286._.js.map +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]__0e842eba._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0e842eba._.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]__39ecb785._.js +4 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__39ecb785._.js.map +1 -0
- 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]__465c0deb._.js +4 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__465c0deb._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__60684242._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__60684242._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__62cdea24._.js +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]__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]__8b6d1e18._.js +4 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8b6d1e18._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8f6c27af._.js +6 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8f6c27af._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__910e9de5._.js +4 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__910e9de5._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a04af228._.js +4 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a04af228._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a21eef5a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a32728d0._.js +4 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a32728d0._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__d6ab9c36._.js +6 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__d6ab9c36._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f2eb7d62._.js +4 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f2eb7d62._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f3036814._.js +4 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f3036814._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_0020fddd._.js +1 -1
- package/web/.next/server/chunks/ssr/_0020fddd._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_01046927._.js +2 -2
- package/web/.next/server/chunks/ssr/_02ec1aea._.js +1 -1
- package/web/.next/server/chunks/ssr/_02ec1aea._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_6f295a50._.js +3 -0
- package/web/.next/server/chunks/ssr/_6f295a50._.js.map +1 -0
- 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/_a37f5f18._.js +1 -1
- package/web/.next/server/chunks/ssr/_a37f5f18._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_a9f57758._.js +1 -1
- package/web/.next/server/chunks/ssr/_a9f57758._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_324f08fa._.js → _b09cd608._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_324f08fa._.js.map → _b09cd608._.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/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js +1 -1
- package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.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_a751c99b._.js +3 -0
- package/web/.next/server/chunks/ssr/{src_presentation_web_79c5e358._.js.map → src_presentation_web_a751c99b._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js.map +1 -0
- 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 +410 -296
- package/web/.next/static/chunks/{a4d0f5c8adbd573e.js → 1469da8ddd6eea90.js} +1 -1
- package/web/.next/static/chunks/1642a69a3baf7820.js +2 -0
- package/web/.next/static/chunks/31ddce9ebee38ab1.css +1 -0
- package/web/.next/static/chunks/{75424b9eb679261a.js → 4aeed32883643436.js} +1 -1
- package/web/.next/static/chunks/{4d40135dc75a7412.js → 74fde105df75b977.js} +1 -1
- package/web/.next/static/chunks/{97778646dde1a546.js → 997a568d8ad04a23.js} +1 -1
- package/web/.next/static/chunks/{ef48a6beeb40b304.js → a063447a4428f722.js} +1 -1
- package/web/.next/static/chunks/{d2b3baac392d5097.js → a495659415f138d6.js} +1 -1
- package/web/.next/static/chunks/{21a98ed37526a704.js → b9e557204db8d0b3.js} +1 -1
- package/web/.next/static/chunks/bfda4e4194a4a633.js +1 -0
- package/web/.next/static/chunks/{140810c2538c85aa.js → df75002e2d1c7531.js} +2 -2
- package/web/.next/static/chunks/{a36ddda5a860c371.js → e5c346dccbba2214.js} +1 -1
- package/web/.next/static/chunks/{d1238d67f4b7fa61.js → f1801a777780b4e9.js} +1 -1
- package/web/.next/static/chunks/{d34a91958ca566fa.js → fb3e66702c475c87.js} +1 -1
- package/web/.next/static/chunks/{d0fb8a76a89bd016.js → febbfdc31eef505b.js} +1 -1
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_4e741df2.js +0 -3
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_4e741df2.js.map +0 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_026fdffa.js +0 -3
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_026fdffa.js.map +0 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_8b91e197.js +0 -3
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_8b91e197.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__755cfe02._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__755cfe02._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__99ab2519._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__99ab2519._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a628fb91._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a628fb91._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__bfba58e6._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__bfba58e6._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c3ab8422._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c3ab8422._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_8302fcae._.js +0 -3
- package/web/.next/server/chunks/ssr/_8302fcae._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_79c5e358._.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web_8e7fe0d1._.js +0 -5
- package/web/.next/server/chunks/ssr/src_presentation_web_8e7fe0d1._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_ca051134.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_ca051134.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_b9023017._.js +0 -5
- package/web/.next/server/chunks/ssr/src_presentation_web_b9023017._.js.map +0 -1
- package/web/.next/static/chunks/da484d44874006a2.css +0 -1
- package/web/.next/static/chunks/dc314fb7519088cf.js +0 -2
- package/web/.next/static/chunks/eb9841ec4d80af01.js +0 -1
- /package/web/.next/static/{8qbj3kELZ61JA30sTIVee → 9XEfk6BBAe6EEGca_Yisr}/_buildManifest.js +0 -0
- /package/web/.next/static/{8qbj3kELZ61JA30sTIVee → 9XEfk6BBAe6EEGca_Yisr}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{8qbj3kELZ61JA30sTIVee → 9XEfk6BBAe6EEGca_Yisr}/_ssgManifest.js +0 -0
|
@@ -64,7 +64,7 @@ let SQLiteSettingsRepository = class SQLiteSettingsRepository {
|
|
|
64
64
|
onboarding_complete,
|
|
65
65
|
approval_gate_allow_prd, approval_gate_allow_plan,
|
|
66
66
|
approval_gate_allow_merge, approval_gate_push_on_impl_complete,
|
|
67
|
-
feature_flag_skills, feature_flag_env_deploy, feature_flag_debug, feature_flag_github_import, feature_flag_adopt_branch,
|
|
67
|
+
feature_flag_skills, feature_flag_env_deploy, feature_flag_debug, feature_flag_github_import, feature_flag_adopt_branch, feature_flag_git_rebase_sync,
|
|
68
68
|
workflow_enable_evidence, workflow_commit_evidence
|
|
69
69
|
) VALUES (
|
|
70
70
|
@id, @created_at, @updated_at,
|
|
@@ -88,7 +88,7 @@ let SQLiteSettingsRepository = class SQLiteSettingsRepository {
|
|
|
88
88
|
@onboarding_complete,
|
|
89
89
|
@approval_gate_allow_prd, @approval_gate_allow_plan,
|
|
90
90
|
@approval_gate_allow_merge, @approval_gate_push_on_impl_complete,
|
|
91
|
-
@feature_flag_skills, @feature_flag_env_deploy, @feature_flag_debug, @feature_flag_github_import, @feature_flag_adopt_branch,
|
|
91
|
+
@feature_flag_skills, @feature_flag_env_deploy, @feature_flag_debug, @feature_flag_github_import, @feature_flag_adopt_branch, @feature_flag_git_rebase_sync,
|
|
92
92
|
@workflow_enable_evidence, @workflow_commit_evidence
|
|
93
93
|
)
|
|
94
94
|
`);
|
|
@@ -182,6 +182,7 @@ let SQLiteSettingsRepository = class SQLiteSettingsRepository {
|
|
|
182
182
|
feature_flag_debug = @feature_flag_debug,
|
|
183
183
|
feature_flag_github_import = @feature_flag_github_import,
|
|
184
184
|
feature_flag_adopt_branch = @feature_flag_adopt_branch,
|
|
185
|
+
feature_flag_git_rebase_sync = @feature_flag_git_rebase_sync,
|
|
185
186
|
workflow_enable_evidence = @workflow_enable_evidence,
|
|
186
187
|
workflow_commit_evidence = @workflow_commit_evidence
|
|
187
188
|
WHERE id = @id
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conflict Resolution Prompt Builder
|
|
3
|
+
*
|
|
4
|
+
* Builds prompts for the AI agent to resolve git rebase conflicts.
|
|
5
|
+
* Follows the merge-prompts.ts pattern of pure functions returning
|
|
6
|
+
* markdown strings.
|
|
7
|
+
*/
|
|
8
|
+
export interface ConflictedFile {
|
|
9
|
+
/** Relative file path from repo root */
|
|
10
|
+
path: string;
|
|
11
|
+
/** Full file contents including conflict markers */
|
|
12
|
+
content: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ConflictResolutionPromptParams {
|
|
15
|
+
/** Files with conflict markers */
|
|
16
|
+
conflictedFiles: ConflictedFile[];
|
|
17
|
+
/** The feature branch being rebased */
|
|
18
|
+
featureBranch: string;
|
|
19
|
+
/** The base branch being rebased onto */
|
|
20
|
+
baseBranch: string;
|
|
21
|
+
/** 1-based attempt number */
|
|
22
|
+
attemptNumber: number;
|
|
23
|
+
/** Maximum allowed attempts */
|
|
24
|
+
maxAttempts: number;
|
|
25
|
+
/** Feedback from previous failed attempt (remaining markers info) */
|
|
26
|
+
previousFeedback?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Build a prompt for the conflict resolution agent.
|
|
30
|
+
*
|
|
31
|
+
* The agent receives conflicted file contents and instructions to resolve
|
|
32
|
+
* all conflict markers by editing files in the working directory.
|
|
33
|
+
*/
|
|
34
|
+
export declare function buildConflictResolutionPrompt(params: ConflictResolutionPromptParams): string;
|
|
35
|
+
//# sourceMappingURL=conflict-resolution.prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conflict-resolution.prompt.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/services/agents/conflict-resolution/conflict-resolution.prompt.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,cAAc;IAC7B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,8BAA8B;IAC7C,kCAAkC;IAClC,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,uCAAuC;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,+BAA+B;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,8BAA8B,GAAG,MAAM,CAgE5F"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conflict Resolution Prompt Builder
|
|
3
|
+
*
|
|
4
|
+
* Builds prompts for the AI agent to resolve git rebase conflicts.
|
|
5
|
+
* Follows the merge-prompts.ts pattern of pure functions returning
|
|
6
|
+
* markdown strings.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Build a prompt for the conflict resolution agent.
|
|
10
|
+
*
|
|
11
|
+
* The agent receives conflicted file contents and instructions to resolve
|
|
12
|
+
* all conflict markers by editing files in the working directory.
|
|
13
|
+
*/
|
|
14
|
+
export function buildConflictResolutionPrompt(params) {
|
|
15
|
+
const { conflictedFiles, featureBranch, baseBranch, attemptNumber, maxAttempts, previousFeedback, } = params;
|
|
16
|
+
const fileSection = conflictedFiles
|
|
17
|
+
.map((f) => `### \`${f.path}\`
|
|
18
|
+
|
|
19
|
+
\`\`\`
|
|
20
|
+
${f.content}
|
|
21
|
+
\`\`\``)
|
|
22
|
+
.join('\n\n');
|
|
23
|
+
const feedbackSection = previousFeedback
|
|
24
|
+
? `
|
|
25
|
+
## Previous Attempt Feedback
|
|
26
|
+
|
|
27
|
+
Your previous resolution attempt (${attemptNumber - 1}/${maxAttempts}) was incomplete:
|
|
28
|
+
|
|
29
|
+
${previousFeedback}
|
|
30
|
+
|
|
31
|
+
You MUST resolve all remaining conflict markers in this attempt.
|
|
32
|
+
`
|
|
33
|
+
: '';
|
|
34
|
+
return `You are resolving git rebase conflicts (attempt ${attemptNumber}/${maxAttempts}).
|
|
35
|
+
|
|
36
|
+
## Branch Context
|
|
37
|
+
|
|
38
|
+
- Feature branch: \`${featureBranch}\`
|
|
39
|
+
- Base branch: \`${baseBranch}\`
|
|
40
|
+
- The feature branch is being rebased onto the latest \`${baseBranch}\`.
|
|
41
|
+
${feedbackSection}
|
|
42
|
+
## Conflicted Files
|
|
43
|
+
|
|
44
|
+
The following files contain conflict markers that must be resolved:
|
|
45
|
+
|
|
46
|
+
${fileSection}
|
|
47
|
+
|
|
48
|
+
## Instructions
|
|
49
|
+
|
|
50
|
+
1. Read each conflicted file listed above
|
|
51
|
+
2. Resolve ALL conflict markers (\`<<<<<<<\`, \`=======\`, \`>>>>>>>\`) by editing the files
|
|
52
|
+
3. For each conflict, determine the correct resolution by understanding the intent of both sides:
|
|
53
|
+
- The \`<<<<<<< HEAD\` section contains changes from \`${baseBranch}\` (theirs during rebase)
|
|
54
|
+
- The \`>>>>>>> ...\` section contains changes from \`${featureBranch}\` (ours during rebase)
|
|
55
|
+
4. Produce a merged result that preserves the intent of both sides where possible
|
|
56
|
+
5. If the changes conflict logically (not just textually), prefer the feature branch changes but ensure compatibility with the base branch
|
|
57
|
+
|
|
58
|
+
## Constraints
|
|
59
|
+
|
|
60
|
+
- Edit ONLY the conflicted files listed above — do NOT modify any other files
|
|
61
|
+
- Remove ALL conflict markers (\`<<<<<<<\`, \`=======\`, \`>>>>>>>\`) from every conflicted file
|
|
62
|
+
- Do NOT add new files or delete files
|
|
63
|
+
- Do NOT run git commands — only edit files to resolve conflicts
|
|
64
|
+
- Do NOT run tests, builds, or linters — only resolve the conflict markers
|
|
65
|
+
- Every conflicted file must have zero remaining conflict markers when you are done`;
|
|
66
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conflict Resolution Service
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates agent-powered conflict resolution during git rebase.
|
|
5
|
+
* Follows the CI watch/fix loop pattern: detect conflict → invoke agent →
|
|
6
|
+
* validate resolution → stage files → continue rebase, with retry logic.
|
|
7
|
+
*/
|
|
8
|
+
import type { IAgentExecutorProvider } from '../../../../application/ports/output/agents/agent-executor-provider.interface.js';
|
|
9
|
+
import type { IGitPrService } from '../../../../application/ports/output/services/git-pr-service.interface.js';
|
|
10
|
+
export declare class ConflictResolutionService {
|
|
11
|
+
private readonly agentProvider;
|
|
12
|
+
private readonly gitPrService;
|
|
13
|
+
constructor(agentProvider: IAgentExecutorProvider, gitPrService: IGitPrService);
|
|
14
|
+
/**
|
|
15
|
+
* Resolve all conflicts during a rebase operation.
|
|
16
|
+
*
|
|
17
|
+
* Handles multi-commit rebases where each commit may introduce conflicts.
|
|
18
|
+
* For each conflicted commit: reads conflicted files, invokes agent to
|
|
19
|
+
* resolve, validates no remaining markers, stages resolved files, and
|
|
20
|
+
* continues the rebase. Retries up to MAX_RETRIES_PER_COMMIT times.
|
|
21
|
+
*
|
|
22
|
+
* If retries are exhausted, aborts the rebase and throws REBASE_CONFLICT.
|
|
23
|
+
*
|
|
24
|
+
* @param cwd - Working directory (repo root or worktree path)
|
|
25
|
+
* @param featureBranch - Feature branch being rebased
|
|
26
|
+
* @param baseBranch - Base branch being rebased onto
|
|
27
|
+
*/
|
|
28
|
+
resolve(cwd: string, featureBranch: string, baseBranch: string): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Read the contents of conflicted files from the working directory.
|
|
31
|
+
*/
|
|
32
|
+
private readConflictedFileContents;
|
|
33
|
+
/**
|
|
34
|
+
* Validate that no conflict markers remain in the previously-conflicted files.
|
|
35
|
+
*/
|
|
36
|
+
private validateResolution;
|
|
37
|
+
/**
|
|
38
|
+
* Build feedback about remaining conflict markers for retry attempts.
|
|
39
|
+
*/
|
|
40
|
+
private buildFeedbackFromRemainingMarkers;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=conflict-resolution.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conflict-resolution.service.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/services/agents/conflict-resolution/conflict-resolution.service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wEAAwE,CAAC;AACrH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iEAAiE,CAAC;AAerG,qBACa,yBAAyB;IAGlC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAE9B,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAFZ,aAAa,EAAE,sBAAsB,EAErC,YAAY,EAAE,aAAa;IAG9C;;;;;;;;;;;;;OAaG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkEpF;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAWlC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAgB1B;;OAEG;IACH,OAAO,CAAC,iCAAiC;CAyB1C"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conflict Resolution Service
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates agent-powered conflict resolution during git rebase.
|
|
5
|
+
* Follows the CI watch/fix loop pattern: detect conflict → invoke agent →
|
|
6
|
+
* validate resolution → stage files → continue rebase, with retry logic.
|
|
7
|
+
*/
|
|
8
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
9
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
10
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
11
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
12
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
13
|
+
};
|
|
14
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
15
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
16
|
+
};
|
|
17
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
18
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
19
|
+
};
|
|
20
|
+
import { injectable, inject } from 'tsyringe';
|
|
21
|
+
import { readFileSync } from 'node:fs';
|
|
22
|
+
import { join } from 'node:path';
|
|
23
|
+
import { GitPrError, GitPrErrorCode, } from '../../../../application/ports/output/services/git-pr-service.interface.js';
|
|
24
|
+
import { buildConflictResolutionPrompt, } from './conflict-resolution.prompt.js';
|
|
25
|
+
const MAX_RETRIES_PER_COMMIT = 3;
|
|
26
|
+
/** Conflict markers that indicate unresolved conflicts */
|
|
27
|
+
const CONFLICT_MARKERS = ['<<<<<<<', '=======', '>>>>>>>'];
|
|
28
|
+
let ConflictResolutionService = class ConflictResolutionService {
|
|
29
|
+
agentProvider;
|
|
30
|
+
gitPrService;
|
|
31
|
+
constructor(agentProvider, gitPrService) {
|
|
32
|
+
this.agentProvider = agentProvider;
|
|
33
|
+
this.gitPrService = gitPrService;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Resolve all conflicts during a rebase operation.
|
|
37
|
+
*
|
|
38
|
+
* Handles multi-commit rebases where each commit may introduce conflicts.
|
|
39
|
+
* For each conflicted commit: reads conflicted files, invokes agent to
|
|
40
|
+
* resolve, validates no remaining markers, stages resolved files, and
|
|
41
|
+
* continues the rebase. Retries up to MAX_RETRIES_PER_COMMIT times.
|
|
42
|
+
*
|
|
43
|
+
* If retries are exhausted, aborts the rebase and throws REBASE_CONFLICT.
|
|
44
|
+
*
|
|
45
|
+
* @param cwd - Working directory (repo root or worktree path)
|
|
46
|
+
* @param featureBranch - Feature branch being rebased
|
|
47
|
+
* @param baseBranch - Base branch being rebased onto
|
|
48
|
+
*/
|
|
49
|
+
async resolve(cwd, featureBranch, baseBranch) {
|
|
50
|
+
const executor = await this.agentProvider.getExecutor();
|
|
51
|
+
// Outer loop: handle multi-commit rebases where rebaseContinue
|
|
52
|
+
// may reveal conflicts on the next commit
|
|
53
|
+
while (true) {
|
|
54
|
+
const conflictedFiles = await this.gitPrService.getConflictedFiles(cwd);
|
|
55
|
+
if (conflictedFiles.length === 0) {
|
|
56
|
+
return; // No conflicts — rebase is complete
|
|
57
|
+
}
|
|
58
|
+
// Inner loop: retry agent resolution for the current commit's conflicts
|
|
59
|
+
let resolved = false;
|
|
60
|
+
for (let attempt = 1; attempt <= MAX_RETRIES_PER_COMMIT; attempt++) {
|
|
61
|
+
const fileContents = this.readConflictedFileContents(cwd, conflictedFiles);
|
|
62
|
+
const previousFeedback = attempt > 1 ? this.buildFeedbackFromRemainingMarkers(cwd, conflictedFiles) : undefined;
|
|
63
|
+
const prompt = buildConflictResolutionPrompt({
|
|
64
|
+
conflictedFiles: fileContents,
|
|
65
|
+
featureBranch,
|
|
66
|
+
baseBranch,
|
|
67
|
+
attemptNumber: attempt,
|
|
68
|
+
maxAttempts: MAX_RETRIES_PER_COMMIT,
|
|
69
|
+
previousFeedback,
|
|
70
|
+
});
|
|
71
|
+
await executor.execute(prompt, { cwd });
|
|
72
|
+
// Validate: check no conflict markers remain
|
|
73
|
+
if (this.validateResolution(cwd, conflictedFiles)) {
|
|
74
|
+
resolved = true;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (!resolved) {
|
|
79
|
+
// Exhausted retries — abort and report
|
|
80
|
+
await this.gitPrService.rebaseAbort(cwd);
|
|
81
|
+
const remaining = conflictedFiles.join(', ');
|
|
82
|
+
throw new GitPrError(`Failed to resolve conflicts after ${MAX_RETRIES_PER_COMMIT} attempts. ` +
|
|
83
|
+
`Unresolved files: ${remaining}. The rebase has been aborted.`, GitPrErrorCode.REBASE_CONFLICT);
|
|
84
|
+
}
|
|
85
|
+
// Resolution succeeded — stage files and continue rebase
|
|
86
|
+
await this.gitPrService.stageFiles(cwd, conflictedFiles);
|
|
87
|
+
try {
|
|
88
|
+
await this.gitPrService.rebaseContinue(cwd);
|
|
89
|
+
// rebaseContinue succeeded — check if there are more conflicts
|
|
90
|
+
// from subsequent commits (loop continues)
|
|
91
|
+
return; // No more conflicts
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
if (error instanceof GitPrError && error.code === GitPrErrorCode.REBASE_CONFLICT) {
|
|
95
|
+
// Next commit has conflicts — loop back to resolve them
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
throw error; // Unexpected error
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Read the contents of conflicted files from the working directory.
|
|
104
|
+
*/
|
|
105
|
+
readConflictedFileContents(cwd, filePaths) {
|
|
106
|
+
return filePaths.map((filePath) => {
|
|
107
|
+
try {
|
|
108
|
+
const content = readFileSync(join(cwd, filePath), 'utf-8');
|
|
109
|
+
return { path: filePath, content };
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return { path: filePath, content: '(unable to read file)' };
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Validate that no conflict markers remain in the previously-conflicted files.
|
|
118
|
+
*/
|
|
119
|
+
validateResolution(cwd, filePaths) {
|
|
120
|
+
for (const filePath of filePaths) {
|
|
121
|
+
try {
|
|
122
|
+
const content = readFileSync(join(cwd, filePath), 'utf-8');
|
|
123
|
+
for (const marker of CONFLICT_MARKERS) {
|
|
124
|
+
if (content.includes(marker)) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Build feedback about remaining conflict markers for retry attempts.
|
|
137
|
+
*/
|
|
138
|
+
buildFeedbackFromRemainingMarkers(cwd, filePaths) {
|
|
139
|
+
const remaining = [];
|
|
140
|
+
for (const filePath of filePaths) {
|
|
141
|
+
try {
|
|
142
|
+
const content = readFileSync(join(cwd, filePath), 'utf-8');
|
|
143
|
+
const lines = content.split('\n');
|
|
144
|
+
const markerLines = [];
|
|
145
|
+
lines.forEach((line, index) => {
|
|
146
|
+
if (CONFLICT_MARKERS.some((marker) => line.includes(marker))) {
|
|
147
|
+
markerLines.push(index + 1);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
if (markerLines.length > 0) {
|
|
151
|
+
remaining.push(`- \`${filePath}\`: conflict markers remain on lines ${markerLines.join(', ')}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
remaining.push(`- \`${filePath}\`: unable to read file`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return remaining.length > 0
|
|
159
|
+
? remaining.join('\n')
|
|
160
|
+
: 'No specific markers found, but validation failed.';
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
ConflictResolutionService = __decorate([
|
|
164
|
+
injectable(),
|
|
165
|
+
__param(0, inject('IAgentExecutorProvider')),
|
|
166
|
+
__param(1, inject('IGitPrService')),
|
|
167
|
+
__metadata("design:paramtypes", [Object, Object])
|
|
168
|
+
], ConflictResolutionService);
|
|
169
|
+
export { ConflictResolutionService };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evidence.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/evidence.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AAEpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAerD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,IAG3C,OAAO,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"evidence.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/evidence.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AAEpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAerD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,IAG3C,OAAO,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAkG7E"}
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/evidence.node.js
CHANGED
|
@@ -48,10 +48,14 @@ export function createEvidenceNode(executor) {
|
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
50
|
const startTime = Date.now();
|
|
51
|
-
const
|
|
51
|
+
const commitEvidence = hasSettings() && getSettings().workflow.commitEvidence;
|
|
52
|
+
const prompt = buildEvidencePrompt(state, { commitEvidence });
|
|
53
|
+
const timingId = await recordPhaseStart('evidence', {
|
|
54
|
+
prompt,
|
|
55
|
+
modelId: state.model,
|
|
56
|
+
agentType: executor.agentType,
|
|
57
|
+
});
|
|
52
58
|
try {
|
|
53
|
-
const commitEvidence = hasSettings() && getSettings().workflow.commitEvidence;
|
|
54
|
-
const prompt = buildEvidencePrompt(state, { commitEvidence });
|
|
55
59
|
const options = buildExecutorOptions(state);
|
|
56
60
|
log.info(`Executing agent at cwd=${options.cwd}`);
|
|
57
61
|
log.info(`Prompt length: ${prompt.length} chars`);
|
|
@@ -79,7 +83,16 @@ export function createEvidenceNode(executor) {
|
|
|
79
83
|
validationMessages.push(`[evidence] Warning: ${warning}`);
|
|
80
84
|
}
|
|
81
85
|
}
|
|
82
|
-
await recordPhaseEnd(timingId, durationMs
|
|
86
|
+
await recordPhaseEnd(timingId, durationMs, {
|
|
87
|
+
inputTokens: result.usage?.inputTokens,
|
|
88
|
+
outputTokens: result.usage?.outputTokens,
|
|
89
|
+
cacheCreationInputTokens: result.usage?.cacheCreationInputTokens,
|
|
90
|
+
cacheReadInputTokens: result.usage?.cacheReadInputTokens,
|
|
91
|
+
costUsd: result.usage?.costUsd,
|
|
92
|
+
numTurns: result.usage?.numTurns,
|
|
93
|
+
durationApiMs: result.usage?.durationApiMs,
|
|
94
|
+
exitCode: 'success',
|
|
95
|
+
});
|
|
83
96
|
markPhaseComplete(state.specDir, 'evidence', log);
|
|
84
97
|
return {
|
|
85
98
|
currentNode: 'evidence',
|
|
@@ -102,7 +115,10 @@ export function createEvidenceNode(executor) {
|
|
|
102
115
|
const durationMs = Date.now() - startTime;
|
|
103
116
|
const elapsed = (durationMs / 1000).toFixed(1);
|
|
104
117
|
log.error(`Evidence collection failed: ${message} (${elapsed}s)`);
|
|
105
|
-
await recordPhaseEnd(timingId, durationMs
|
|
118
|
+
await recordPhaseEnd(timingId, durationMs, {
|
|
119
|
+
exitCode: 'error',
|
|
120
|
+
errorMessage: message.slice(0, 1000),
|
|
121
|
+
});
|
|
106
122
|
throw new Error(`[evidence] ${message}`);
|
|
107
123
|
}
|
|
108
124
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fast-implement.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/fast-implement.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AAEpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAgBrD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,cAAc,IAGhD,OAAO,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"fast-implement.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/fast-implement.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AAEpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAgBrD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,cAAc,IAGhD,OAAO,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CA0F7E"}
|
|
@@ -45,9 +45,13 @@ export function createFastImplementNode(executor) {
|
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
const startTime = Date.now();
|
|
48
|
-
const
|
|
48
|
+
const prompt = buildFastImplementPrompt(state);
|
|
49
|
+
const timingId = await recordPhaseStart('fast-implement', {
|
|
50
|
+
prompt,
|
|
51
|
+
modelId: state.model,
|
|
52
|
+
agentType: executor.agentType,
|
|
53
|
+
});
|
|
49
54
|
try {
|
|
50
|
-
const prompt = buildFastImplementPrompt(state);
|
|
51
55
|
const options = buildExecutorOptions(state);
|
|
52
56
|
log.info(`Executing agent at cwd=${options.cwd}`);
|
|
53
57
|
log.info(`Prompt length: ${prompt.length} chars`);
|
|
@@ -66,7 +70,16 @@ export function createFastImplementNode(executor) {
|
|
|
66
70
|
if (!evidenceEnabled) {
|
|
67
71
|
log.info('Evidence collection disabled via settings — skipping');
|
|
68
72
|
}
|
|
69
|
-
await recordPhaseEnd(timingId, durationMs
|
|
73
|
+
await recordPhaseEnd(timingId, durationMs, {
|
|
74
|
+
inputTokens: result.usage?.inputTokens,
|
|
75
|
+
outputTokens: result.usage?.outputTokens,
|
|
76
|
+
cacheCreationInputTokens: result.usage?.cacheCreationInputTokens,
|
|
77
|
+
cacheReadInputTokens: result.usage?.cacheReadInputTokens,
|
|
78
|
+
costUsd: result.usage?.costUsd,
|
|
79
|
+
numTurns: result.usage?.numTurns,
|
|
80
|
+
durationApiMs: result.usage?.durationApiMs,
|
|
81
|
+
exitCode: 'success',
|
|
82
|
+
});
|
|
70
83
|
// Mark phase complete so resume from error skips re-execution
|
|
71
84
|
markPhaseComplete(state.specDir, 'fast-implement', log);
|
|
72
85
|
return {
|
|
@@ -86,7 +99,10 @@ export function createFastImplementNode(executor) {
|
|
|
86
99
|
const durationMs = Date.now() - startTime;
|
|
87
100
|
const elapsed = (durationMs / 1000).toFixed(1);
|
|
88
101
|
log.error(`${message} (after ${elapsed}s)`);
|
|
89
|
-
await recordPhaseEnd(timingId, durationMs
|
|
102
|
+
await recordPhaseEnd(timingId, durationMs, {
|
|
103
|
+
exitCode: 'error',
|
|
104
|
+
errorMessage: message.slice(0, 1000),
|
|
105
|
+
});
|
|
90
106
|
// Throw so LangGraph does NOT checkpoint this node as "completed".
|
|
91
107
|
throw new Error(`[fast-implement] ${message}`);
|
|
92
108
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"implement.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/implement.node.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AAEpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"implement.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/implement.node.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AAEpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAyErD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,cAAc,IAG5C,OAAO,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAsP7E"}
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/implement.node.js
CHANGED
|
@@ -12,7 +12,7 @@ import { join, dirname } from 'node:path';
|
|
|
12
12
|
import { interrupt, isGraphBubbleUp } from '@langchain/langgraph';
|
|
13
13
|
import { createNodeLogger, readSpecFile, buildExecutorOptions, shouldInterrupt, safeYamlLoad, retryExecute, getCompletedPhases, markPhaseComplete, } from './node-helpers.js';
|
|
14
14
|
import { reportNodeStart } from '../heartbeat.js';
|
|
15
|
-
import { recordPhaseStart, recordPhaseEnd, recordApprovalWaitStart, } from '../phase-timing-context.js';
|
|
15
|
+
import { recordPhaseStart, recordPhaseEnd, recordApprovalWaitStart, updatePhasePrompt, } from '../phase-timing-context.js';
|
|
16
16
|
import { updateNodeLifecycle } from '../lifecycle-context.js';
|
|
17
17
|
import { buildImplementPhasePrompt, } from './prompts/implement.prompt.js';
|
|
18
18
|
import { buildEvidencePrompt } from './prompts/evidence-prompts.js';
|
|
@@ -59,7 +59,16 @@ export function createImplementNode(executor) {
|
|
|
59
59
|
const startTime = Date.now();
|
|
60
60
|
const messages = [];
|
|
61
61
|
// Record top-level implement phase timing (sub-phases are recorded individually below)
|
|
62
|
-
const implementTimingId = await recordPhaseStart('implement'
|
|
62
|
+
const implementTimingId = await recordPhaseStart('implement', {
|
|
63
|
+
modelId: state.model,
|
|
64
|
+
agentType: executor.agentType,
|
|
65
|
+
});
|
|
66
|
+
// Accumulate token usage across all sub-phases for the top-level timing
|
|
67
|
+
let totalInputTokens = 0;
|
|
68
|
+
let totalOutputTokens = 0;
|
|
69
|
+
let totalCostUsd = 0;
|
|
70
|
+
let totalNumTurns = 0;
|
|
71
|
+
let totalDurationApiMs = 0;
|
|
63
72
|
try {
|
|
64
73
|
// --- Parse plan & tasks ---
|
|
65
74
|
const planContent = readSpecFile(state.specDir, 'plan.yaml');
|
|
@@ -108,32 +117,69 @@ export function createImplementNode(executor) {
|
|
|
108
117
|
const options = buildExecutorOptions(state);
|
|
109
118
|
const promptContext = { isLastPhase, phaseIndex: i, totalPhases };
|
|
110
119
|
const phaseStartTime = Date.now();
|
|
111
|
-
const phaseTimingId = await recordPhaseStart(`implement:${phase.id}
|
|
120
|
+
const phaseTimingId = await recordPhaseStart(`implement:${phase.id}`, {
|
|
121
|
+
modelId: state.model,
|
|
122
|
+
agentType: executor.agentType,
|
|
123
|
+
});
|
|
124
|
+
// Collect usage from all executor calls in this phase
|
|
125
|
+
let phaseInputTokens = 0;
|
|
126
|
+
let phaseOutputTokens = 0;
|
|
127
|
+
let phaseCostUsd = 0;
|
|
128
|
+
let phaseNumTurns = 0;
|
|
129
|
+
let phaseDurationApiMs = 0;
|
|
112
130
|
if (phase.parallel && phaseTasks.length > 1) {
|
|
113
131
|
// Parallel: one executor call per task
|
|
114
132
|
log.info(`Spawning ${phaseTasks.length} parallel executor calls`);
|
|
115
|
-
|
|
133
|
+
// Build all prompts up front so we can record them before execution
|
|
134
|
+
const taskPrompts = phaseTasks.map((task) => {
|
|
116
135
|
const singleTaskPhase = {
|
|
117
136
|
...phase,
|
|
118
137
|
taskIds: [task.id],
|
|
119
138
|
};
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
139
|
+
return buildImplementPhasePrompt(state, singleTaskPhase, [task], promptContext);
|
|
140
|
+
});
|
|
141
|
+
await updatePhasePrompt(phaseTimingId, taskPrompts.join('\n\n---\n\n'));
|
|
142
|
+
const results = await Promise.all(phaseTasks.map((task, idx) => {
|
|
143
|
+
log.info(` [parallel] Task ${task.id}: "${task.title}" — ${taskPrompts[idx].length} chars`);
|
|
144
|
+
return retryExecute(executor, taskPrompts[idx], options, retryOpts);
|
|
123
145
|
}));
|
|
124
146
|
for (let j = 0; j < results.length; j++) {
|
|
125
147
|
log.info(` [parallel] Task ${phaseTasks[j].id} complete (${results[j].result.length} chars)`);
|
|
148
|
+
phaseInputTokens += results[j].usage?.inputTokens ?? 0;
|
|
149
|
+
phaseOutputTokens += results[j].usage?.outputTokens ?? 0;
|
|
150
|
+
phaseCostUsd += results[j].usage?.costUsd ?? 0;
|
|
151
|
+
phaseNumTurns += results[j].usage?.numTurns ?? 0;
|
|
152
|
+
phaseDurationApiMs += results[j].usage?.durationApiMs ?? 0;
|
|
126
153
|
}
|
|
127
154
|
}
|
|
128
155
|
else {
|
|
129
156
|
// Sequential: single executor call with all phase tasks
|
|
130
157
|
const prompt = buildImplementPhasePrompt(state, phase, phaseTasks, promptContext);
|
|
158
|
+
await updatePhasePrompt(phaseTimingId, prompt);
|
|
131
159
|
log.info(`Executing phase prompt — ${prompt.length} chars`);
|
|
132
160
|
const result = await retryExecute(executor, prompt, options, retryOpts);
|
|
133
161
|
log.info(`Phase complete (${result.result.length} chars)`);
|
|
162
|
+
phaseInputTokens = result.usage?.inputTokens ?? 0;
|
|
163
|
+
phaseOutputTokens = result.usage?.outputTokens ?? 0;
|
|
164
|
+
phaseCostUsd = result.usage?.costUsd ?? 0;
|
|
165
|
+
phaseNumTurns = result.usage?.numTurns ?? 0;
|
|
166
|
+
phaseDurationApiMs = result.usage?.durationApiMs ?? 0;
|
|
134
167
|
}
|
|
168
|
+
// Accumulate into top-level totals
|
|
169
|
+
totalInputTokens += phaseInputTokens;
|
|
170
|
+
totalOutputTokens += phaseOutputTokens;
|
|
171
|
+
totalCostUsd += phaseCostUsd;
|
|
172
|
+
totalNumTurns += phaseNumTurns;
|
|
173
|
+
totalDurationApiMs += phaseDurationApiMs;
|
|
135
174
|
const phaseDurationMs = Date.now() - phaseStartTime;
|
|
136
|
-
await recordPhaseEnd(phaseTimingId, phaseDurationMs
|
|
175
|
+
await recordPhaseEnd(phaseTimingId, phaseDurationMs, {
|
|
176
|
+
inputTokens: phaseInputTokens || undefined,
|
|
177
|
+
outputTokens: phaseOutputTokens || undefined,
|
|
178
|
+
costUsd: phaseCostUsd || undefined,
|
|
179
|
+
numTurns: phaseNumTurns || undefined,
|
|
180
|
+
durationApiMs: phaseDurationApiMs || undefined,
|
|
181
|
+
exitCode: 'success',
|
|
182
|
+
});
|
|
137
183
|
completedTasks += phaseTasks.length;
|
|
138
184
|
markPhaseComplete(state.specDir, phase.id, log);
|
|
139
185
|
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
@@ -153,7 +199,14 @@ export function createImplementNode(executor) {
|
|
|
153
199
|
}
|
|
154
200
|
messages.push(`[implement] Evidence: ${evidence.length} record(s) captured`);
|
|
155
201
|
// Record top-level implement phase completion
|
|
156
|
-
await recordPhaseEnd(implementTimingId, Date.now() - startTime
|
|
202
|
+
await recordPhaseEnd(implementTimingId, Date.now() - startTime, {
|
|
203
|
+
inputTokens: totalInputTokens || undefined,
|
|
204
|
+
outputTokens: totalOutputTokens || undefined,
|
|
205
|
+
costUsd: totalCostUsd || undefined,
|
|
206
|
+
numTurns: totalNumTurns || undefined,
|
|
207
|
+
durationApiMs: totalDurationApiMs || undefined,
|
|
208
|
+
exitCode: 'success',
|
|
209
|
+
});
|
|
157
210
|
if (shouldInterrupt('implement', state.approvalGates)) {
|
|
158
211
|
log.info('Interrupting for human approval');
|
|
159
212
|
await recordApprovalWaitStart(implementTimingId);
|
|
@@ -171,7 +224,15 @@ export function createImplementNode(executor) {
|
|
|
171
224
|
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
172
225
|
log.error(`${message} (after ${elapsed}s)`);
|
|
173
226
|
// Record phase end even on failure so timing shows duration, not "running"
|
|
174
|
-
await recordPhaseEnd(implementTimingId, Date.now() - startTime
|
|
227
|
+
await recordPhaseEnd(implementTimingId, Date.now() - startTime, {
|
|
228
|
+
inputTokens: totalInputTokens || undefined,
|
|
229
|
+
outputTokens: totalOutputTokens || undefined,
|
|
230
|
+
costUsd: totalCostUsd || undefined,
|
|
231
|
+
numTurns: totalNumTurns || undefined,
|
|
232
|
+
durationApiMs: totalDurationApiMs || undefined,
|
|
233
|
+
exitCode: 'error',
|
|
234
|
+
errorMessage: message.slice(0, 1000),
|
|
235
|
+
});
|
|
175
236
|
// Throw so LangGraph does NOT checkpoint this node as "completed".
|
|
176
237
|
// The worker catch block marks the run as failed, and on resume
|
|
177
238
|
// LangGraph re-executes from the last successfully checkpointed node.
|
|
@@ -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;
|
|
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;AAE3H,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,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,CAiU7E"}
|
|
@@ -16,7 +16,7 @@ import { interrupt, isGraphBubbleUp } from '@langchain/langgraph';
|
|
|
16
16
|
import { SdlcLifecycle, PrStatus } from '../../../../../../domain/generated/output.js';
|
|
17
17
|
import { createNodeLogger, shouldInterrupt, retryExecute, buildExecutorOptions, } from '../node-helpers.js';
|
|
18
18
|
import { reportNodeStart } from '../../heartbeat.js';
|
|
19
|
-
import { recordPhaseStart, recordPhaseEnd, recordApprovalWaitStart, } from '../../phase-timing-context.js';
|
|
19
|
+
import { recordPhaseStart, recordPhaseEnd, recordApprovalWaitStart, updatePhasePrompt, } from '../../phase-timing-context.js';
|
|
20
20
|
import { updateNodeLifecycle } from '../../lifecycle-context.js';
|
|
21
21
|
import { buildCommitPushPrPrompt } from '../prompts/merge-prompts.js';
|
|
22
22
|
import { parseCommitHash, parsePrUrl } from './merge-output-parser.js';
|
|
@@ -104,6 +104,7 @@ export function createMergeNode(deps) {
|
|
|
104
104
|
const effectiveState = remoteAvailable ? state : { ...state, push: false, openPr: false };
|
|
105
105
|
log.info('Agent call 1: commit + push + PR');
|
|
106
106
|
const commitPushPrPrompt = buildCommitPushPrPrompt(effectiveState, branch, baseBranch, repoUrl);
|
|
107
|
+
await updatePhasePrompt(mergeTimingId, commitPushPrPrompt);
|
|
107
108
|
const commitResult = await retryExecute(executor, commitPushPrPrompt, options, {
|
|
108
109
|
logger: log,
|
|
109
110
|
});
|
|
@@ -46,6 +46,8 @@ export interface PhaseEndMetadata {
|
|
|
46
46
|
durationApiMs?: number;
|
|
47
47
|
exitCode?: string;
|
|
48
48
|
errorMessage?: string;
|
|
49
|
+
/** Prompt can be recorded at end time when it's built after recordPhaseStart */
|
|
50
|
+
prompt?: string;
|
|
49
51
|
}
|
|
50
52
|
/**
|
|
51
53
|
* Record the end of a phase. Updates the timing record with completedAt, durationMs,
|
|
@@ -61,6 +63,12 @@ export declare function recordPhaseEnd(timingId: string | null, durationMs: numb
|
|
|
61
63
|
* e.g., from use cases like StopAgentRunUseCase or ResumeFeatureUseCase).
|
|
62
64
|
*/
|
|
63
65
|
export declare function recordLifecycleEvent(phase: string, explicitRunId?: string, explicitRepo?: IPhaseTimingRepository): Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* Update a phase timing record with the prompt text.
|
|
68
|
+
* Useful when the prompt is built after recordPhaseStart (e.g. merge node).
|
|
69
|
+
* No-op if timingId is null or context is not set.
|
|
70
|
+
*/
|
|
71
|
+
export declare function updatePhasePrompt(timingId: string | null, prompt: string): Promise<void>;
|
|
64
72
|
/**
|
|
65
73
|
* Record the start of an approval wait. Sets waitingApprovalAt on the timing record.
|
|
66
74
|
* No-op if timingId is null or context is not set.
|