@shepai/cli 1.122.2-pr381.7d9e407 → 1.122.2-pr390.b1ef40f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-factory.service.js +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.d.ts +8 -28
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.js +29 -187
- 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 +0 -9
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.d.ts +0 -5
- 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 +54 -82
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.js +2 -2
- package/dist/src/presentation/web/app/(dashboard)/get-graph-data.d.ts +6 -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 +60 -0
- package/dist/src/presentation/web/app/build-graph-nodes.d.ts +7 -0
- package/dist/src/presentation/web/app/build-graph-nodes.d.ts.map +1 -1
- package/dist/src/presentation/web/app/build-graph-nodes.js +7 -0
- package/dist/src/presentation/web/components/common/repository-node/repository-node-config.d.ts +8 -0
- package/dist/src/presentation/web/components/common/repository-node/repository-node-config.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-node.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-node.js +6 -6
- package/dist/src/presentation/web/components/common/repository-node/repository-node.stories.d.ts +2 -0
- package/dist/src/presentation/web/components/common/repository-node/repository-node.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-node.stories.js +107 -17
- package/dist/src/presentation/web/lib/layout-with-dagre.js +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +1 -1
- package/web/.next/required-server-files.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +22 -22
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js +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 +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +3 -3
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +3 -3
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +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 +22 -22
- 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 +28 -28
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +3 -3
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +3 -3
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +20 -20
- package/web/.next/server/app/(dashboard)/page.js +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 +20 -20
- 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 +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/api/graph-data/route.js +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 +6 -6
- package/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/tools/page.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 +1 -1
- 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]__dcd4f847._.js +3 -0
- package/web/.next/server/chunks/{[root-of-the-server]__42b7ab55._.js.map → [root-of-the-server]__dcd4f847._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/403f9_next_dist_31ea46d3._.js +1 -1
- package/web/.next/server/chunks/ssr/403f9_next_dist_c9d9b4d7._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__06fef644._.js +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__a022445f._.js → [root-of-the-server]__14664e9b._.js} +3 -3
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__a022445f._.js.map → [root-of-the-server]__14664e9b._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6677a82c._.js +3 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__b724df9e._.js.map → [root-of-the-server]__6677a82c._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__8e3bf5d7._.js → [root-of-the-server]__7cbda1ea._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__8e3bf5d7._.js.map → [root-of-the-server]__7cbda1ea._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8c553503._.js +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__2698e9f4._.js → [root-of-the-server]__9e8b25ad._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__2698e9f4._.js.map → [root-of-the-server]__9e8b25ad._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a7de2711._.js +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__c07f9f79._.js → [root-of-the-server]__aed1d6f8._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__c07f9f79._.js.map → [root-of-the-server]__aed1d6f8._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__c605a375._.js → [root-of-the-server]__ce6057f6._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__c605a375._.js.map → [root-of-the-server]__ce6057f6._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__e7258841._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__e7258841._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
- package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_434878d3._.js → _15fe9326._.js} +2 -2
- package/web/.next/server/chunks/ssr/_15fe9326._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_2f6f48b8._.js +1 -1
- package/web/.next/server/chunks/ssr/_2f6f48b8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_3a4c94e3._.js +1 -1
- package/web/.next/server/chunks/ssr/_90a34ae9._.js +3 -0
- package/web/.next/server/chunks/ssr/{_204ecb5a._.js.map → _90a34ae9._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_b56e7571._.js +3 -0
- package/web/.next/server/chunks/ssr/_b56e7571._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
- package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_e9703421._.js +3 -0
- package/web/.next/server/chunks/ssr/_e9703421._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_f096ab6a._.js +3 -0
- package/web/.next/server/chunks/ssr/_f096ab6a._.js.map +1 -0
- 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/node_modules__pnpm_bc66dcc6._.js +3 -0
- package/web/.next/server/chunks/ssr/node_modules__pnpm_bc66dcc6._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_5f039db1._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_5f039db1._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_c4337169._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_c4337169._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_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_bf50c527._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.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 +34 -34
- package/web/.next/static/chunks/{89ffd07cdb158389.js → 24a0b215d72d8f26.js} +1 -1
- package/web/.next/static/chunks/{50bf223ed146d4ed.js → 2c0cf874cda01236.js} +1 -1
- package/web/.next/static/chunks/4232eb19944a519e.js +1 -0
- package/web/.next/static/chunks/4443ee9c7733399b.js +1 -0
- package/web/.next/static/chunks/6b8c3e3d8d4ee08e.js +1 -0
- package/web/.next/static/chunks/{df88f3e08b196bbf.js → 9fba6bb38ff0cb38.js} +2 -2
- package/web/.next/static/chunks/a58429fc5be52aad.js +1 -0
- package/web/.next/static/chunks/b200a40ffcc15eb7.css +1 -0
- package/web/.next/static/chunks/{2c0191c062d5f7ae.js → b67d183d3c074a4c.js} +2 -2
- package/web/.next/static/chunks/ca946dcbfbb2df74.js +1 -0
- package/web/.next/static/chunks/{19401b65e1298cb0.js → cd2bb43fe9138791.js} +1 -1
- package/web/.next/static/chunks/d2bfdee31e1a7d8d.js +1 -0
- package/web/.next/static/chunks/{4da275e6ef808c4d.js → fadc79bbbae100a7.js} +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__42b7ab55._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9f155c0e._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9f155c0e._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b724df9e._.js +0 -3
- package/web/.next/server/chunks/ssr/_0dc2cfd3._.js +0 -3
- package/web/.next/server/chunks/ssr/_0dc2cfd3._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_204ecb5a._.js +0 -3
- package/web/.next/server/chunks/ssr/_434878d3._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_510be09a._.js +0 -3
- package/web/.next/server/chunks/ssr/_510be09a._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_75f4ccb3._.js +0 -3
- package/web/.next/server/chunks/ssr/_75f4ccb3._.js.map +0 -1
- package/web/.next/server/chunks/ssr/node_modules__pnpm_b59e4b16._.js +0 -3
- package/web/.next/server/chunks/ssr/node_modules__pnpm_b59e4b16._.js.map +0 -1
- package/web/.next/static/chunks/0d2af96e64960ef5.css +0 -1
- package/web/.next/static/chunks/4562ee849ea13c3a.js +0 -1
- package/web/.next/static/chunks/5a9e671eb04de758.js +0 -1
- package/web/.next/static/chunks/6a8fb1992b738cc9.js +0 -1
- package/web/.next/static/chunks/845d8e58a91014e6.js +0 -1
- package/web/.next/static/chunks/a637e16d364af323.js +0 -1
- package/web/.next/static/chunks/bc1ce100834f414a.js +0 -1
- /package/web/.next/static/{NKkt3_PEmNxKD_ihRAzNE → Fr059mDxLxW71ARoHnB8W}/_buildManifest.js +0 -0
- /package/web/.next/static/{NKkt3_PEmNxKD_ihRAzNE → Fr059mDxLxW71ARoHnB8W}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{NKkt3_PEmNxKD_ihRAzNE → Fr059mDxLxW71ARoHnB8W}/_ssgManifest.js +0 -0
|
@@ -98,94 +98,66 @@ export function createMergeNode(deps) {
|
|
|
98
98
|
: undefined;
|
|
99
99
|
// --- Agent Call 1: Commit + Push + PR (skip on approval resume) ---
|
|
100
100
|
if (!isResumeAfterInterrupt) {
|
|
101
|
+
if (!remoteAvailable) {
|
|
102
|
+
log.info('No git remote configured — skipping push and PR, will merge locally');
|
|
103
|
+
}
|
|
101
104
|
const effectiveState = remoteAvailable ? state : { ...state, push: false, openPr: false };
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
105
|
+
log.info('Agent call 1: commit + push + PR');
|
|
106
|
+
const commitPushPrPrompt = buildCommitPushPrPrompt(effectiveState, branch, baseBranch, repoUrl);
|
|
107
|
+
const commitResult = await retryExecute(executor, commitPushPrPrompt, options, {
|
|
108
|
+
logger: log,
|
|
109
|
+
});
|
|
110
|
+
totalInputTokens += commitResult.usage?.inputTokens ?? 0;
|
|
111
|
+
totalOutputTokens += commitResult.usage?.outputTokens ?? 0;
|
|
112
|
+
totalCostUsd += commitResult.usage?.costUsd ?? 0;
|
|
113
|
+
totalNumTurns += commitResult.usage?.numTurns ?? 0;
|
|
114
|
+
totalDurationApiMs += commitResult.usage?.durationApiMs ?? 0;
|
|
115
|
+
commitHash = parseCommitHash(commitResult.result) ?? state.commitHash;
|
|
116
|
+
messages.push(`[merge] Agent completed commit/push/PR operations`);
|
|
117
|
+
if (effectiveState.openPr) {
|
|
118
|
+
const prResult = parsePrUrl(commitResult.result);
|
|
119
|
+
if (prResult) {
|
|
120
|
+
prUrl = prResult.url;
|
|
121
|
+
prNumber = prResult.number;
|
|
122
|
+
// Cross-validate agent-parsed PR URL against authoritative source.
|
|
123
|
+
// The agent may hallucinate the repo URL or PR number, so we look up
|
|
124
|
+
// the real PR for this branch via the GitHub API.
|
|
125
|
+
try {
|
|
126
|
+
const prStatuses = await deps.gitPrService.listPrStatuses(cwd);
|
|
127
|
+
const matchingPr = prStatuses.find((pr) => pr.headRefName === branch);
|
|
128
|
+
if (matchingPr) {
|
|
129
|
+
prUrl = matchingPr.url;
|
|
130
|
+
prNumber = matchingPr.number;
|
|
131
|
+
}
|
|
116
132
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
messages.push(`[merge] No changes to commit`);
|
|
133
|
+
catch {
|
|
134
|
+
// gh CLI unavailable or API failure — fall back to agent-parsed URL
|
|
120
135
|
}
|
|
121
|
-
|
|
122
|
-
catch (commitErr) {
|
|
123
|
-
const errMsg = commitErr instanceof Error ? commitErr.message : String(commitErr);
|
|
124
|
-
log.info(`Programmatic commit failed: ${errMsg} — falling back to agent`);
|
|
125
|
-
messages.push(`[merge] Programmatic commit failed, falling back to agent`);
|
|
126
|
-
// Fall through — needsAgentCall stays false so agent won't run either.
|
|
127
|
-
// The localMergeSquash will handle uncommitted changes via --squash.
|
|
136
|
+
messages.push(`[merge] PR created: ${prUrl}`);
|
|
128
137
|
}
|
|
129
138
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
139
|
+
// --- CI watch/fix loop (when push or openPr is enabled and CI watch is not disabled) ---
|
|
140
|
+
const ciWatchEnabled = getSettings().workflow?.ciWatchEnabled !== false;
|
|
141
|
+
if (ciWatchEnabled && (effectiveState.push || effectiveState.openPr)) {
|
|
142
|
+
const ciResult = await runCiWatchFixLoop({
|
|
143
|
+
executor,
|
|
144
|
+
gitPrService: deps.gitPrService,
|
|
145
|
+
featureRepository: deps.featureRepository,
|
|
146
|
+
}, {
|
|
147
|
+
cwd,
|
|
148
|
+
branch,
|
|
149
|
+
options,
|
|
150
|
+
feature,
|
|
151
|
+
prUrl,
|
|
152
|
+
prNumber,
|
|
153
|
+
existingAttempts: ciFixAttempts,
|
|
154
|
+
messages,
|
|
155
|
+
log,
|
|
138
156
|
});
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
totalDurationApiMs += commitResult.usage?.durationApiMs ?? 0;
|
|
144
|
-
commitHash = parseCommitHash(commitResult.result) ?? state.commitHash;
|
|
145
|
-
messages.push(`[merge] Agent completed commit/push/PR operations`);
|
|
146
|
-
if (effectiveState.openPr) {
|
|
147
|
-
const prResult = parsePrUrl(commitResult.result);
|
|
148
|
-
if (prResult) {
|
|
149
|
-
prUrl = prResult.url;
|
|
150
|
-
prNumber = prResult.number;
|
|
151
|
-
// Cross-validate agent-parsed PR URL against authoritative source.
|
|
152
|
-
try {
|
|
153
|
-
const prStatuses = await deps.gitPrService.listPrStatuses(cwd);
|
|
154
|
-
const matchingPr = prStatuses.find((pr) => pr.headRefName === branch);
|
|
155
|
-
if (matchingPr) {
|
|
156
|
-
prUrl = matchingPr.url;
|
|
157
|
-
prNumber = matchingPr.number;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
catch {
|
|
161
|
-
// gh CLI unavailable or API failure — fall back to agent-parsed URL
|
|
162
|
-
}
|
|
163
|
-
messages.push(`[merge] PR created: ${prUrl}`);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
// --- CI watch/fix loop (when push or openPr is enabled and CI watch is not disabled) ---
|
|
167
|
-
const ciWatchEnabled = getSettings().workflow?.ciWatchEnabled !== false;
|
|
168
|
-
if (ciWatchEnabled && (effectiveState.push || effectiveState.openPr)) {
|
|
169
|
-
const ciResult = await runCiWatchFixLoop({
|
|
170
|
-
executor,
|
|
171
|
-
gitPrService: deps.gitPrService,
|
|
172
|
-
featureRepository: deps.featureRepository,
|
|
173
|
-
}, {
|
|
174
|
-
cwd,
|
|
175
|
-
branch,
|
|
176
|
-
options,
|
|
177
|
-
feature,
|
|
178
|
-
prUrl,
|
|
179
|
-
prNumber,
|
|
180
|
-
existingAttempts: ciFixAttempts,
|
|
181
|
-
messages,
|
|
182
|
-
log,
|
|
183
|
-
});
|
|
184
|
-
ciStatus = ciResult.ciStatus;
|
|
185
|
-
ciFixAttempts = ciResult.ciFixAttempts;
|
|
186
|
-
ciFixHistory = ciResult.ciFixHistory;
|
|
187
|
-
ciFixStatus = ciResult.ciFixStatus;
|
|
188
|
-
}
|
|
157
|
+
ciStatus = ciResult.ciStatus;
|
|
158
|
+
ciFixAttempts = ciResult.ciFixAttempts;
|
|
159
|
+
ciFixHistory = ciResult.ciFixHistory;
|
|
160
|
+
ciFixStatus = ciResult.ciFixStatus;
|
|
189
161
|
}
|
|
190
162
|
// --- Persist lifecycle + PR data before approval gate ---
|
|
191
163
|
// Setting lifecycle to Review serves as the resume detection marker
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts
CHANGED
|
@@ -32,7 +32,7 @@ export declare function getStageTimeoutMs(nodeName: string): number;
|
|
|
32
32
|
/**
|
|
33
33
|
* Build executor options with cwd. Each node gets a clean agent context.
|
|
34
34
|
* The timeout is resolved per-stage from settings (workflow.stageTimeouts)
|
|
35
|
-
* with a fallback to DEFAULT_STAGE_TIMEOUT_MS (10 min
|
|
35
|
+
* with a fallback to DEFAULT_STAGE_TIMEOUT_MS (10 min).
|
|
36
36
|
*
|
|
37
37
|
* When no `nodeName` is provided, the current node from state is used.
|
|
38
38
|
*/
|
package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.js
CHANGED
|
@@ -46,7 +46,7 @@ export function readSpecFile(specDir, filename) {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
/** Default timeout per agent call (30 minutes) — prevents infinite hangs. */
|
|
49
|
-
const DEFAULT_STAGE_TIMEOUT_MS =
|
|
49
|
+
const DEFAULT_STAGE_TIMEOUT_MS = 1_800_000;
|
|
50
50
|
/**
|
|
51
51
|
* Map from node name to the corresponding StageTimeouts field.
|
|
52
52
|
* `fast-implement` reuses the implement timeout; `evidence` also reuses implement.
|
|
@@ -80,7 +80,7 @@ export function getStageTimeoutMs(nodeName) {
|
|
|
80
80
|
/**
|
|
81
81
|
* Build executor options with cwd. Each node gets a clean agent context.
|
|
82
82
|
* The timeout is resolved per-stage from settings (workflow.stageTimeouts)
|
|
83
|
-
* with a fallback to DEFAULT_STAGE_TIMEOUT_MS (10 min
|
|
83
|
+
* with a fallback to DEFAULT_STAGE_TIMEOUT_MS (10 min).
|
|
84
84
|
*
|
|
85
85
|
* When no `nodeName` is provided, the current node from state is used.
|
|
86
86
|
*/
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { CanvasNodeType } from '../../components/features/features-canvas/index.js';
|
|
2
2
|
import type { Edge } from '@xyflow/react';
|
|
3
|
+
export interface RepoGitInfo {
|
|
4
|
+
branch: string;
|
|
5
|
+
commitMessage: string;
|
|
6
|
+
committer: string;
|
|
7
|
+
behindCount: number | null;
|
|
8
|
+
}
|
|
3
9
|
export declare function getGraphData(): Promise<{
|
|
4
10
|
nodes: CanvasNodeType[];
|
|
5
11
|
edges: Edge[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-graph-data.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/(dashboard)/get-graph-data.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"get-graph-data.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/(dashboard)/get-graph-data.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAE5E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAI1C,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAoDD,wBAAsB,YAAY,IAAI,OAAO,CAAC;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAAC,CAyDxF"}
|
|
@@ -1,12 +1,71 @@
|
|
|
1
|
+
import { execFile as execFileCb } from 'node:child_process';
|
|
2
|
+
import { promisify } from 'node:util';
|
|
1
3
|
import { resolve } from '../../lib/server-container.js';
|
|
2
4
|
import { getSettings } from '../../../../../packages/core/src/infrastructure/services/settings.service.js';
|
|
3
5
|
import { layoutWithDagre, CANVAS_LAYOUT_DEFAULTS } from '../../lib/layout-with-dagre.js';
|
|
4
6
|
import { buildGraphNodes } from '../build-graph-nodes.js';
|
|
7
|
+
const execFileAsync = promisify(execFileCb);
|
|
8
|
+
async function gitCommand(cwd, args) {
|
|
9
|
+
try {
|
|
10
|
+
const { stdout } = await execFileAsync('git', args, { cwd });
|
|
11
|
+
return stdout.trim();
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
async function fetchRepoGitInfo(repo) {
|
|
18
|
+
try {
|
|
19
|
+
const [currentBranch, commitMessage, committer] = await Promise.all([
|
|
20
|
+
gitCommand(repo.path, ['symbolic-ref', '--short', 'HEAD']),
|
|
21
|
+
gitCommand(repo.path, ['log', '-1', '--format=%s']),
|
|
22
|
+
gitCommand(repo.path, ['log', '-1', '--format=%an']),
|
|
23
|
+
]);
|
|
24
|
+
if (!currentBranch)
|
|
25
|
+
return null;
|
|
26
|
+
// Try to determine the default branch to compute behind count
|
|
27
|
+
let behindCount = null;
|
|
28
|
+
const defaultBranch = await gitCommand(repo.path, [
|
|
29
|
+
'symbolic-ref',
|
|
30
|
+
'--short',
|
|
31
|
+
'refs/remotes/origin/HEAD',
|
|
32
|
+
]).then((ref) => ref?.replace('origin/', '') ?? null);
|
|
33
|
+
if (defaultBranch && currentBranch !== defaultBranch) {
|
|
34
|
+
const behind = await gitCommand(repo.path, [
|
|
35
|
+
'rev-list',
|
|
36
|
+
'--count',
|
|
37
|
+
`${currentBranch}..origin/${defaultBranch}`,
|
|
38
|
+
]);
|
|
39
|
+
behindCount = behind !== null ? parseInt(behind, 10) : null;
|
|
40
|
+
if (isNaN(behindCount))
|
|
41
|
+
behindCount = null;
|
|
42
|
+
}
|
|
43
|
+
else if (!defaultBranch || currentBranch === defaultBranch) {
|
|
44
|
+
behindCount = 0;
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
branch: currentBranch,
|
|
48
|
+
commitMessage: commitMessage ?? 'unknown',
|
|
49
|
+
committer: committer ?? 'unknown',
|
|
50
|
+
behindCount,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
5
57
|
export async function getGraphData() {
|
|
6
58
|
const listFeatures = resolve('ListFeaturesUseCase');
|
|
7
59
|
const listRepos = resolve('ListRepositoriesUseCase');
|
|
8
60
|
const agentRunRepo = resolve('IAgentRunRepository');
|
|
9
61
|
const [features, repositories] = await Promise.all([listFeatures.execute(), listRepos.execute()]);
|
|
62
|
+
// Fetch git info (branch, commit, behind count) for each repository
|
|
63
|
+
const repoGitInfoMap = new Map();
|
|
64
|
+
await Promise.all(repositories.map(async (repo) => {
|
|
65
|
+
const info = await fetchRepoGitInfo(repo);
|
|
66
|
+
if (info)
|
|
67
|
+
repoGitInfoMap.set(repo.path, info);
|
|
68
|
+
}));
|
|
10
69
|
// PR/CI status is kept fresh by PrSyncWatcher (30s background poll).
|
|
11
70
|
// No live GitHub calls here — use cached DB values for fast response.
|
|
12
71
|
const featuresWithRuns = await Promise.all(features.map(async (feature) => {
|
|
@@ -18,6 +77,7 @@ export async function getGraphData() {
|
|
|
18
77
|
enableEvidence: workflow.enableEvidence,
|
|
19
78
|
commitEvidence: workflow.commitEvidence,
|
|
20
79
|
ciWatchEnabled: workflow.ciWatchEnabled,
|
|
80
|
+
repoGitInfo: repoGitInfoMap,
|
|
21
81
|
});
|
|
22
82
|
// Enrich feature nodes with deployment status
|
|
23
83
|
let deploymentService = null;
|
|
@@ -20,6 +20,13 @@ export interface BuildGraphNodesOptions {
|
|
|
20
20
|
commitEvidence?: boolean;
|
|
21
21
|
/** Whether CI watch/fix loop is enabled (global workflow setting) */
|
|
22
22
|
ciWatchEnabled?: boolean;
|
|
23
|
+
/** Git info (branch, commit message, committer, behind count) keyed by repository path */
|
|
24
|
+
repoGitInfo?: Map<string, {
|
|
25
|
+
branch: string;
|
|
26
|
+
commitMessage: string;
|
|
27
|
+
committer: string;
|
|
28
|
+
behindCount: number | null;
|
|
29
|
+
}>;
|
|
23
30
|
}
|
|
24
31
|
export declare function buildGraphNodes(repositories: Repository[], featuresWithRuns: FeatureWithRun[], options?: BuildGraphNodesOptions): {
|
|
25
32
|
nodes: CanvasNodeType[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-graph-nodes.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/app/build-graph-nodes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAS1F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAU1C,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,QAAQ,GAAG,IAAI,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,sBAAsB;IACrC,uEAAuE;IACvE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,6EAA6E;IAC7E,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qEAAqE;IACrE,cAAc,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"build-graph-nodes.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/app/build-graph-nodes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAS1F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAU1C,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,QAAQ,GAAG,IAAI,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,sBAAsB;IACrC,uEAAuE;IACvE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,6EAA6E;IAC7E,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qEAAqE;IACrE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,0FAA0F;IAC1F,WAAW,CAAC,EAAE,GAAG,CACf,MAAM,EACN;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CACzF,CAAC;CACH;AAED,wBAAgB,eAAe,CAC7B,YAAY,EAAE,UAAU,EAAE,EAC1B,gBAAgB,EAAE,cAAc,EAAE,EAClC,OAAO,CAAC,EAAE,sBAAsB,GAC/B;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAkG5C"}
|
|
@@ -31,6 +31,7 @@ export function buildGraphNodes(repositories, featuresWithRuns, options) {
|
|
|
31
31
|
const normalizedRepoPath = normalizePath(repo.path);
|
|
32
32
|
coveredPaths.add(normalizedRepoPath);
|
|
33
33
|
const repoNodeId = `repo-${repo.id}`;
|
|
34
|
+
const gitInfo = options?.repoGitInfo?.get(repo.path);
|
|
34
35
|
nodes.push({
|
|
35
36
|
id: repoNodeId,
|
|
36
37
|
type: 'repositoryNode',
|
|
@@ -40,6 +41,12 @@ export function buildGraphNodes(repositories, featuresWithRuns, options) {
|
|
|
40
41
|
repositoryPath: normalizedRepoPath,
|
|
41
42
|
id: repo.id,
|
|
42
43
|
createdAt: repo.createdAt instanceof Date ? repo.createdAt.getTime() : Number(repo.createdAt),
|
|
44
|
+
...(gitInfo && {
|
|
45
|
+
branch: gitInfo.branch,
|
|
46
|
+
commitMessage: gitInfo.commitMessage,
|
|
47
|
+
committer: gitInfo.committer,
|
|
48
|
+
behindCount: gitInfo.behindCount,
|
|
49
|
+
}),
|
|
43
50
|
},
|
|
44
51
|
});
|
|
45
52
|
const repoFeatures = featuresByRepo[normalizedRepoPath] ?? [];
|
package/dist/src/presentation/web/components/common/repository-node/repository-node-config.d.ts
CHANGED
|
@@ -9,6 +9,14 @@ export interface RepositoryNodeData {
|
|
|
9
9
|
repositoryPath?: string;
|
|
10
10
|
/** Creation timestamp (epoch ms) — used for stable vertical ordering. */
|
|
11
11
|
createdAt?: number;
|
|
12
|
+
/** Current git branch name (e.g. "main", "feat/my-feature") */
|
|
13
|
+
branch?: string;
|
|
14
|
+
/** Commit message of the branch HEAD (first line only) */
|
|
15
|
+
commitMessage?: string;
|
|
16
|
+
/** Name of the person who made the latest commit */
|
|
17
|
+
committer?: string;
|
|
18
|
+
/** Number of commits the current branch is behind the default branch. null if on default branch or unknown. */
|
|
19
|
+
behindCount?: number | null;
|
|
12
20
|
onClick?: () => void;
|
|
13
21
|
onAdd?: () => void;
|
|
14
22
|
onDelete?: (repositoryId: string) => void;
|
package/dist/src/presentation/web/components/common/repository-node/repository-node-config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository-node-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,WAAW,kBAAkB;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,qEAAqE;IACrE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"repository-node-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,WAAW,kBAAkB;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,qEAAqE;IACrE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+GAA+G;IAC/G,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,CAAC"}
|
package/dist/src/presentation/web/components/common/repository-node/repository-node.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"repository-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node.tsx"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAOnE,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,2CA+U5F"}
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { useState, useCallback } from 'react';
|
|
4
4
|
import { Handle, Position } from '@xyflow/react';
|
|
5
5
|
import { useRouter } from 'next/navigation';
|
|
6
|
-
import { Github, Plus, Code2, Terminal, FolderOpen, Trash2, Play, Square } from 'lucide-react';
|
|
6
|
+
import { Github, Plus, Code2, Terminal, FolderOpen, Trash2, Play, Square, GitBranch, GitCommitHorizontal, ArrowDown, User, } from 'lucide-react';
|
|
7
7
|
import { cn } from '../../../lib/utils.js';
|
|
8
8
|
import { ActionButton } from '../../common/action-button/index.js';
|
|
9
9
|
import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '../../ui/dialog.js';
|
|
@@ -72,9 +72,9 @@ export function RepositoryNode({ data }) {
|
|
|
72
72
|
e.stopPropagation();
|
|
73
73
|
data.onClick?.();
|
|
74
74
|
}
|
|
75
|
-
}, className: "nodrag bg-card flex
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
}, className: "nodrag bg-card flex w-[26rem] cursor-pointer flex-col overflow-hidden rounded-xl border shadow-sm", children: [_jsxs("div", { className: "flex items-center gap-3 px-4 py-3", children: [_jsx(Github, { className: "text-muted-foreground h-5 w-5 shrink-0" }), _jsx("span", { "data-testid": "repository-node-name", className: "min-w-0 truncate text-sm font-medium", children: data.name }), _jsxs("div", { className: cn('flex shrink-0 items-center gap-2', (data.repositoryPath ?? data.onAdd) && 'ml-auto'), onClick: (e) => e.stopPropagation(), children: [data.repositoryPath ? (_jsxs(_Fragment, { children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open in IDE", onClick: actions.openInIde, loading: actions.ideLoading, error: !!actions.ideError, icon: Code2, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open in IDE" })] }) }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open in Shell", onClick: actions.openInShell, loading: actions.shellLoading, error: !!actions.shellError, icon: Terminal, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open in Shell" })] }) }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open Folder", onClick: actions.openFolder, loading: actions.folderLoading, error: !!actions.folderError, icon: FolderOpen, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open Folder" })] }) }), _jsx(FeatureSessionsDropdown, { repositoryPath: data.repositoryPath, onCreateFromSession: handleCreateFromSession }), featureFlags.envDeploy ? (_jsxs(_Fragment, { children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: isDeploymentActive ? 'Stop Dev Server' : 'Start Dev Server', onClick: isDeploymentActive ? deployAction.stop : deployAction.deploy, loading: deployAction.deployLoading || deployAction.stopLoading, error: !!deployAction.deployError, icon: isDeploymentActive ? Square : Play, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: isDeploymentActive ? 'Stop Dev Server' : 'Start Dev Server' })] }) }), isDeploymentActive ? (_jsx(DeploymentStatusBadge, { status: deployAction.status, url: deployAction.url, targetId: data.repositoryPath })) : null] })) : null] })) : null, data.onAdd ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { "aria-label": "Add feature", "data-testid": "repository-node-add-button", onClick: (e) => {
|
|
76
|
+
e.stopPropagation();
|
|
77
|
+
data.onAdd?.();
|
|
78
|
+
}, className: cn('text-muted-foreground hover:bg-accent dark:hover:bg-accent/50 flex h-6 w-6 shrink-0 cursor-pointer items-center justify-center rounded-full transition-colors hover:text-blue-500', data.pulseAdd &&
|
|
79
|
+
'animate-pulse-cta bg-blue-100 text-blue-500 dark:bg-blue-900/40'), children: _jsx(Plus, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Add feature" })] }) })) : null] })] }), data.branch ? (_jsx("div", { "data-testid": "repository-node-git-info", className: "text-muted-foreground border-t px-4 py-2", children: _jsxs("div", { className: "flex items-center gap-3 text-xs", children: [_jsxs("span", { className: "flex items-center gap-1 truncate", "data-testid": "repository-node-branch", children: [_jsx(GitBranch, { className: "h-3 w-3 shrink-0" }), _jsx("span", { className: "truncate", children: data.branch })] }), data.behindCount != null && data.behindCount > 0 ? (_jsxs("span", { className: "flex shrink-0 items-center gap-1 whitespace-nowrap text-amber-500", "data-testid": "repository-node-behind", children: [_jsx(ArrowDown, { className: "h-3 w-3 shrink-0" }), data.behindCount, " behind"] })) : null] }) })) : null, data.commitMessage ? (_jsx("div", { "data-testid": "repository-node-commit-info", className: "text-muted-foreground border-t px-4 py-2", children: _jsxs("div", { className: "flex items-center gap-2 text-xs", children: [_jsx(GitCommitHorizontal, { className: "h-3 w-3 shrink-0" }), _jsx("span", { className: "min-w-0 truncate", "data-testid": "repository-node-commit-message", children: data.commitMessage }), data.committer ? (_jsxs("span", { className: "text-muted-foreground/70 ml-auto flex shrink-0 items-center gap-1", "data-testid": "repository-node-committer", children: [_jsx(User, { className: "h-3 w-3 shrink-0" }), _jsx("span", { children: data.committer })] })) : null] }) })) : null] }), data.onAdd || data.showHandles ? (_jsx(Handle, { type: "source", position: Position.Right, isConnectable: !data.showHandles, className: "opacity-0!" })) : null] }));
|
|
80
80
|
}
|
package/dist/src/presentation/web/components/common/repository-node/repository-node.stories.d.ts
CHANGED
|
@@ -14,4 +14,6 @@ export declare const WithActions: Story;
|
|
|
14
14
|
export declare const WithActionsAndAddButton: Story;
|
|
15
15
|
export declare const WithDeleteButton: Story;
|
|
16
16
|
export declare const MultipleWithActions: Story;
|
|
17
|
+
export declare const WithGitInfo: Story;
|
|
18
|
+
export declare const WithGitInfoBehind: Story;
|
|
17
19
|
//# sourceMappingURL=repository-node.stories.d.ts.map
|
package/dist/src/presentation/web/components/common/repository-node/repository-node.stories.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository-node.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,KAAK,EAAE,kBAAkB,EAAsB,MAAM,0BAA0B,CAAC;AAgCvF,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,kBAAkB,
|
|
1
|
+
{"version":3,"file":"repository-node.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,KAAK,EAAE,kBAAkB,EAAsB,MAAM,0BAA0B,CAAC;AAgCvF,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,kBAAkB,CAYlC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,kBAAkB,CAAC,CAAC;AAE1C,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAK3B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAKzB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAKtB,CAAC;AAiCF,eAAO,MAAM,QAAQ,EAAE,KAwBtB,CAAC;AAkCF,eAAO,MAAM,kBAAkB,EAAE,KAwBhC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAS1B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAKzB,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,KAQrC,CAAC;AAIF,eAAO,MAAM,gBAAgB,EAAE,KAS9B,CAAC;AA+CF,eAAO,MAAM,mBAAmB,EAAE,KAwBjC,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KASzB,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAS/B,CAAC"}
|
package/dist/src/presentation/web/components/common/repository-node/repository-node.stories.js
CHANGED
|
@@ -3,7 +3,7 @@ import { useMemo } from 'react';
|
|
|
3
3
|
import { ReactFlowProvider, ReactFlow } from '@xyflow/react';
|
|
4
4
|
import { RepositoryNode } from './repository-node.js';
|
|
5
5
|
const nodeTypes = { repositoryNode: RepositoryNode };
|
|
6
|
-
function RepositoryNodeCanvas({ data, style = { width:
|
|
6
|
+
function RepositoryNodeCanvas({ data, style = { width: 550, height: 300 }, }) {
|
|
7
7
|
const nodes = useMemo(() => [{ id: 'node-1', type: 'repositoryNode', position: { x: 0, y: 0 }, data }], [data]);
|
|
8
8
|
return (_jsx("div", { style: style, children: _jsx(ReactFlowProvider, { children: _jsx(ReactFlow, { nodes: nodes, nodeTypes: nodeTypes, nodesDraggable: false, nodesConnectable: false, proOptions: { hideAttribution: true }, fitView: true }) }) }));
|
|
9
9
|
}
|
|
@@ -15,6 +15,9 @@ const meta = {
|
|
|
15
15
|
},
|
|
16
16
|
args: {
|
|
17
17
|
name: 'shep-ai/cli',
|
|
18
|
+
branch: 'main',
|
|
19
|
+
commitMessage: 'feat: add dark mode toggle',
|
|
20
|
+
committer: 'Jane Doe',
|
|
18
21
|
},
|
|
19
22
|
};
|
|
20
23
|
export default meta;
|
|
@@ -41,37 +44,84 @@ export const LongName = {
|
|
|
41
44
|
};
|
|
42
45
|
const onAdd = () => undefined;
|
|
43
46
|
const multipleRepos = [
|
|
44
|
-
{
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
{
|
|
48
|
+
name: 'shep-ai/cli',
|
|
49
|
+
branch: 'main',
|
|
50
|
+
commitMessage: 'feat: add dark mode toggle',
|
|
51
|
+
committer: 'Jane Doe',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'vercel/edge-runtime',
|
|
55
|
+
branch: 'feat/streaming',
|
|
56
|
+
commitMessage: 'fix: handle edge cases in streaming',
|
|
57
|
+
committer: 'John Smith',
|
|
58
|
+
behindCount: 3,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: 'acme-corp/web-dashboard-v2',
|
|
62
|
+
branch: 'develop',
|
|
63
|
+
commitMessage: 'chore: update dependencies',
|
|
64
|
+
committer: 'Bot',
|
|
65
|
+
behindCount: 12,
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'openai/tiktoken',
|
|
69
|
+
branch: 'main',
|
|
70
|
+
commitMessage: 'perf: optimize token encoding',
|
|
71
|
+
committer: 'Alice Chen',
|
|
72
|
+
},
|
|
48
73
|
];
|
|
49
74
|
export const Multiple = {
|
|
50
75
|
render: () => {
|
|
51
76
|
const nodes = multipleRepos.map((data, i) => ({
|
|
52
77
|
id: `repo-${i}`,
|
|
53
78
|
type: 'repositoryNode',
|
|
54
|
-
position: { x: 0, y: i *
|
|
79
|
+
position: { x: 0, y: i * 140 },
|
|
55
80
|
data,
|
|
56
81
|
}));
|
|
57
|
-
return (_jsx("div", { style: { width:
|
|
82
|
+
return (_jsx("div", { style: { width: 600, height: 750 }, children: _jsx(ReactFlowProvider, { children: _jsx(ReactFlow, { nodes: nodes, nodeTypes: nodeTypes, nodesDraggable: false, nodesConnectable: false, proOptions: { hideAttribution: true }, fitView: true }) }) }));
|
|
58
83
|
},
|
|
59
84
|
};
|
|
60
85
|
const multipleReposWithButton = [
|
|
61
|
-
{
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
86
|
+
{
|
|
87
|
+
name: 'shep-ai/cli',
|
|
88
|
+
onAdd,
|
|
89
|
+
branch: 'main',
|
|
90
|
+
commitMessage: 'feat: add dark mode toggle',
|
|
91
|
+
committer: 'Jane Doe',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: 'vercel/edge-runtime',
|
|
95
|
+
onAdd,
|
|
96
|
+
branch: 'feat/streaming',
|
|
97
|
+
commitMessage: 'fix: handle edge cases in streaming',
|
|
98
|
+
committer: 'John Smith',
|
|
99
|
+
behindCount: 3,
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: 'acme-corp/web-dashboard-v2',
|
|
103
|
+
onAdd,
|
|
104
|
+
branch: 'develop',
|
|
105
|
+
commitMessage: 'chore: update dependencies',
|
|
106
|
+
committer: 'Bot',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: 'openai/tiktoken',
|
|
110
|
+
onAdd,
|
|
111
|
+
branch: 'main',
|
|
112
|
+
commitMessage: 'perf: optimize token encoding',
|
|
113
|
+
committer: 'Alice Chen',
|
|
114
|
+
},
|
|
65
115
|
];
|
|
66
116
|
export const MultipleWithButton = {
|
|
67
117
|
render: () => {
|
|
68
118
|
const nodes = multipleReposWithButton.map((data, i) => ({
|
|
69
119
|
id: `repo-${i}`,
|
|
70
120
|
type: 'repositoryNode',
|
|
71
|
-
position: { x: 0, y: i *
|
|
121
|
+
position: { x: 0, y: i * 140 },
|
|
72
122
|
data,
|
|
73
123
|
}));
|
|
74
|
-
return (_jsx("div", { style: { width:
|
|
124
|
+
return (_jsx("div", { style: { width: 600, height: 750 }, children: _jsx(ReactFlowProvider, { children: _jsx(ReactFlow, { nodes: nodes, nodeTypes: nodeTypes, nodesDraggable: false, nodesConnectable: false, proOptions: { hideAttribution: true }, fitView: true }) }) }));
|
|
75
125
|
},
|
|
76
126
|
};
|
|
77
127
|
export const WithPulseAdd = {
|
|
@@ -108,16 +158,29 @@ export const WithDeleteButton = {
|
|
|
108
158
|
argTypes: {
|
|
109
159
|
onDelete: { action: 'onDelete' },
|
|
110
160
|
},
|
|
111
|
-
render: (args) => _jsx(RepositoryNodeCanvas, { data: args, style: { width:
|
|
161
|
+
render: (args) => _jsx(RepositoryNodeCanvas, { data: args, style: { width: 600, height: 300 } }),
|
|
112
162
|
};
|
|
113
163
|
const multipleReposWithActions = [
|
|
114
|
-
{
|
|
164
|
+
{
|
|
165
|
+
id: 'r1',
|
|
166
|
+
name: 'shep-ai/cli',
|
|
167
|
+
repositoryPath: '/home/user/shep-ai/cli',
|
|
168
|
+
onAdd,
|
|
169
|
+
onDelete,
|
|
170
|
+
branch: 'main',
|
|
171
|
+
commitMessage: 'feat(web): enrich repository node with branch and commit info',
|
|
172
|
+
committer: 'Ariel Shadkhan',
|
|
173
|
+
},
|
|
115
174
|
{
|
|
116
175
|
id: 'r2',
|
|
117
176
|
name: 'vercel/edge-runtime',
|
|
118
177
|
repositoryPath: '/home/user/vercel/edge-runtime',
|
|
119
178
|
onAdd,
|
|
120
179
|
onDelete,
|
|
180
|
+
branch: 'feat/streaming-v2',
|
|
181
|
+
commitMessage: 'fix: handle edge cases in streaming response',
|
|
182
|
+
committer: 'John Smith',
|
|
183
|
+
behindCount: 5,
|
|
121
184
|
},
|
|
122
185
|
{
|
|
123
186
|
id: 'r3',
|
|
@@ -125,6 +188,10 @@ const multipleReposWithActions = [
|
|
|
125
188
|
repositoryPath: '/home/user/acme-corp/web-dashboard-v2',
|
|
126
189
|
onAdd,
|
|
127
190
|
onDelete,
|
|
191
|
+
branch: 'develop',
|
|
192
|
+
commitMessage: 'chore(deps): update all dependencies to latest',
|
|
193
|
+
committer: 'Renovate Bot',
|
|
194
|
+
behindCount: 23,
|
|
128
195
|
},
|
|
129
196
|
{
|
|
130
197
|
id: 'r4',
|
|
@@ -132,6 +199,9 @@ const multipleReposWithActions = [
|
|
|
132
199
|
repositoryPath: '/home/user/openai/tiktoken',
|
|
133
200
|
onAdd,
|
|
134
201
|
onDelete,
|
|
202
|
+
branch: 'main',
|
|
203
|
+
commitMessage: 'perf: optimize token encoding for large inputs',
|
|
204
|
+
committer: 'Alice Chen',
|
|
135
205
|
},
|
|
136
206
|
];
|
|
137
207
|
export const MultipleWithActions = {
|
|
@@ -139,9 +209,29 @@ export const MultipleWithActions = {
|
|
|
139
209
|
const nodes = multipleReposWithActions.map((data, i) => ({
|
|
140
210
|
id: `repo-${i}`,
|
|
141
211
|
type: 'repositoryNode',
|
|
142
|
-
position: { x: 0, y: i *
|
|
212
|
+
position: { x: 0, y: i * 140 },
|
|
143
213
|
data,
|
|
144
214
|
}));
|
|
145
|
-
return (_jsx("div", { style: { width:
|
|
215
|
+
return (_jsx("div", { style: { width: 600, height: 800 }, children: _jsx(ReactFlowProvider, { children: _jsx(ReactFlow, { nodes: nodes, nodeTypes: nodeTypes, nodesDraggable: false, nodesConnectable: false, proOptions: { hideAttribution: true }, fitView: true }) }) }));
|
|
216
|
+
},
|
|
217
|
+
};
|
|
218
|
+
export const WithGitInfo = {
|
|
219
|
+
args: {
|
|
220
|
+
repositoryPath: '/home/user/shep-ai/cli',
|
|
221
|
+
branch: 'feat/repo-node-enrichment',
|
|
222
|
+
commitMessage: 'feat(web): enrich repository node with branch and commit info',
|
|
223
|
+
committer: 'Ariel Shadkhan',
|
|
224
|
+
behindCount: 0,
|
|
146
225
|
},
|
|
226
|
+
render: (args) => _jsx(RepositoryNodeCanvas, { data: args }),
|
|
227
|
+
};
|
|
228
|
+
export const WithGitInfoBehind = {
|
|
229
|
+
args: {
|
|
230
|
+
repositoryPath: '/home/user/shep-ai/cli',
|
|
231
|
+
branch: 'feat/old-feature-branch',
|
|
232
|
+
commitMessage: 'fix: resolve merge conflict in auth module',
|
|
233
|
+
committer: 'Jane Doe',
|
|
234
|
+
behindCount: 7,
|
|
235
|
+
},
|
|
236
|
+
render: (args) => _jsx(RepositoryNodeCanvas, { data: args }),
|
|
147
237
|
};
|
|
@@ -8,7 +8,7 @@ export const CANVAS_LAYOUT_DEFAULTS = {
|
|
|
8
8
|
/** Known node-type dimensions for the canvas node types */
|
|
9
9
|
const NODE_DIMENSIONS = {
|
|
10
10
|
featureNode: { width: 288, height: 140 },
|
|
11
|
-
repositoryNode: { width:
|
|
11
|
+
repositoryNode: { width: 400, height: 110 },
|
|
12
12
|
};
|
|
13
13
|
function getNodeSize(node, defaultSize) {
|
|
14
14
|
// Prefer per-node size from data, then type-based lookup, then default
|