@shepai/cli 1.129.0 → 1.129.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/packages/core/src/application/use-cases/repositories/add-repository.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/repositories/add-repository.use-case.js +5 -2
- package/dist/packages/core/src/infrastructure/repositories/sqlite-repository.repository.js +2 -2
- package/dist/src/presentation/web/app/(dashboard)/get-graph-data.d.ts +8 -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 +75 -22
- package/dist/src/presentation/web/app/build-graph-nodes.d.ts +2 -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 +2 -0
- package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node.js +3 -3
- package/dist/src/presentation/web/components/common/repository-node/repository-node-config.d.ts +2 -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 +7 -3
- 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 +14 -0
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +1 -0
- package/dist/src/presentation/web/lib/derive-graph.d.ts.map +1 -1
- package/dist/src/presentation/web/lib/derive-graph.js +5 -2
- package/dist/src/presentation/web/lib/layout-with-dagre.js +2 -2
- 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 +2 -2
- package/web/.next/required-server-files.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +24 -24
- 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 +24 -24
- 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 +30 -30
- 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 +30 -30
- 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 +22 -22
- 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 +24 -24
- 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 +30 -30
- 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 +30 -30
- 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 +22 -22
- 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 +22 -22
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +3 -3
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/settings/page/server-reference-manifest.json +8 -8
- package/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +8 -8
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +8 -8
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +3 -3
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +1 -1
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_4e741df2.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_4e741df2.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/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_026fdffa.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_026fdffa.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_8b91e197.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_8b91e197.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]__2f886f77._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__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]__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]__755cfe02._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__755cfe02._.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]__a628fb91._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a628fb91._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__bfba58e6._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__bfba58e6._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c3ab8422._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c3ab8422._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f4a463ee._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f4a463ee._.js.map +1 -1
- 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/_7dca1882._.js +1 -1
- package/web/.next/server/chunks/ssr/_7dca1882._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_ade68272._.js → _92acff95._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_ade68272._.js.map → _92acff95._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{_04c9e229._.js → _a11d42e8._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_04c9e229._.js.map → _a11d42e8._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_a9f57758._.js +1 -1
- package/web/.next/server/chunks/ssr/_d8575088._.js +1 -1
- package/web/.next/server/chunks/ssr/_d8575088._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_f39a1adb._.js +1 -1
- package/web/.next/server/chunks/ssr/_f39a1adb._.js.map +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_8e7fe0d1._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_8e7fe0d1._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_ca051134.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_ca051134.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_b9023017._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_b9023017._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{src_presentation_web_12d7d3c5._.js → src_presentation_web_efa91543._.js} +2 -2
- package/web/.next/server/chunks/ssr/{src_presentation_web_12d7d3c5._.js.map → src_presentation_web_efa91543._.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 +38 -38
- package/web/.next/static/chunks/0a83031808867bca.js +1 -0
- package/web/.next/static/chunks/{6c6ab4d42b07fb4b.js → 2672ec79b6eb1b94.js} +1 -1
- package/web/.next/static/chunks/{20ff528aadba66aa.js → 475b22f4bf14af2d.js} +1 -1
- package/web/.next/static/chunks/{c975a20b880c47ea.js → 4ee40070e69205bc.js} +1 -1
- package/web/.next/static/chunks/{278f99f8cc87ab17.js → 5da0c2f16502fddd.js} +1 -1
- package/web/.next/static/chunks/{ab3f7ac1960397d9.js → 5e11fe79741cd049.js} +1 -1
- package/web/.next/static/chunks/{29535b9b36889453.js → 792cdceb624c561d.js} +1 -1
- package/web/.next/static/chunks/{60fabfee2f9ae935.js → cc974a8f14de58d0.js} +1 -1
- package/web/.next/static/chunks/{83ae4f574f3dee4d.js → e4ff24651224d4d2.js} +1 -1
- package/web/.next/static/chunks/f569a6dc0496430f.css +1 -0
- package/web/.next/static/chunks/{60464e75e7dff8f4.js → f84bbfe2662f35ed.js} +2 -2
- package/web/.next/static/chunks/fd2ccf8f2022f2fb.js +1 -0
- package/web/.next/static/chunks/{98b6ea0af565042f.js → fdff2d35956e7448.js} +2 -2
- package/web/.next/static/chunks/114347d98fd69f40.js +0 -1
- package/web/.next/static/chunks/6cba93f351d29ae4.js +0 -1
- package/web/.next/static/chunks/98dfbecc5ee30ce1.css +0 -1
- /package/web/.next/static/{_hAwvNHgk12VPT5IIxRV6 → yH8b83VvOS2P5F2XwxoFX}/_buildManifest.js +0 -0
- /package/web/.next/static/{_hAwvNHgk12VPT5IIxRV6 → yH8b83VvOS2P5F2XwxoFX}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{_hAwvNHgk12VPT5IIxRV6 → yH8b83VvOS2P5F2XwxoFX}/_ssgManifest.js +0 -0
package/dist/packages/core/src/application/use-cases/repositories/add-repository.use-case.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-repository.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/repositories/add-repository.use-case.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oEAAoE,CAAC;AAEhH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAcD,qBACa,oBAAoB;IAG7B,OAAO,CAAC,QAAQ,CAAC,cAAc;gBAAd,cAAc,EAAE,qBAAqB;IAGlD,OAAO,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"add-repository.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/repositories/add-repository.use-case.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oEAAoE,CAAC;AAEhH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAcD,qBACa,oBAAoB;IAG7B,OAAO,CAAC,QAAQ,CAAC,cAAc;gBAAd,cAAc,EAAE,qBAAqB;IAGlD,OAAO,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,CAAC;CAiC9D"}
|
package/dist/packages/core/src/application/use-cases/repositories/add-repository.use-case.js
CHANGED
|
@@ -41,11 +41,14 @@ let AddRepositoryUseCase = class AddRepositoryUseCase {
|
|
|
41
41
|
if (existing) {
|
|
42
42
|
return existing;
|
|
43
43
|
}
|
|
44
|
-
// Check for soft-deleted repository — restore it instead of creating a duplicate
|
|
44
|
+
// Check for soft-deleted repository — restore it instead of creating a duplicate.
|
|
45
|
+
// Reset createdAt so the restored repo sorts as "newest" on the canvas
|
|
46
|
+
// (otherwise the old createdAt would place it above repos added later).
|
|
45
47
|
const deleted = await this.repositoryRepo.findByPathIncludingDeleted(normalizedPath);
|
|
46
48
|
if (deleted) {
|
|
49
|
+
const now = new Date();
|
|
47
50
|
await this.repositoryRepo.restore(deleted.id);
|
|
48
|
-
return { ...deleted, deletedAt: undefined, updatedAt:
|
|
51
|
+
return { ...deleted, deletedAt: undefined, createdAt: now, updatedAt: now };
|
|
49
52
|
}
|
|
50
53
|
const now = new Date();
|
|
51
54
|
const name = input.name ?? normalizedPath.split('/').pop() ?? normalizedPath;
|
|
@@ -94,8 +94,8 @@ let SQLiteRepositoryRepository = SQLiteRepositoryRepository_1 = class SQLiteRepo
|
|
|
94
94
|
}
|
|
95
95
|
async restore(id) {
|
|
96
96
|
const now = Date.now();
|
|
97
|
-
const stmt = this.db.prepare('UPDATE repositories SET deleted_at = NULL, updated_at = ? WHERE id = ?');
|
|
98
|
-
stmt.run(now, id);
|
|
97
|
+
const stmt = this.db.prepare('UPDATE repositories SET deleted_at = NULL, created_at = ?, updated_at = ? WHERE id = ?');
|
|
98
|
+
stmt.run(now, now, id);
|
|
99
99
|
}
|
|
100
100
|
static normalizeRemoteUrl(url) {
|
|
101
101
|
return url.replace(/\.git$/, '').toLowerCase();
|
|
@@ -6,6 +6,14 @@ export interface RepoGitInfo {
|
|
|
6
6
|
committer: string;
|
|
7
7
|
behindCount: number | null;
|
|
8
8
|
}
|
|
9
|
+
export type GitInfoResult = {
|
|
10
|
+
status: 'loading';
|
|
11
|
+
} | {
|
|
12
|
+
status: 'ready';
|
|
13
|
+
data: RepoGitInfo;
|
|
14
|
+
} | {
|
|
15
|
+
status: 'not-a-repo';
|
|
16
|
+
};
|
|
9
17
|
export declare function getGraphData(): Promise<{
|
|
10
18
|
nodes: CanvasNodeType[];
|
|
11
19
|
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":"AAYA,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;
|
|
1
|
+
{"version":3,"file":"get-graph-data.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/(dashboard)/get-graph-data.ts"],"names":[],"mappings":"AAYA,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;AAwFD,MAAM,MAAM,aAAa,GACrB;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GACtC;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,CAAC;AA6B7B,wBAAsB,YAAY,IAAI,OAAO,CAAC;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAAC,CA6DxF"}
|
|
@@ -6,6 +6,11 @@ import { getSettings } from '../../../../../packages/core/src/infrastructure/ser
|
|
|
6
6
|
import { layoutWithDagre, CANVAS_LAYOUT_DEFAULTS } from '../../lib/layout-with-dagre.js';
|
|
7
7
|
import { buildGraphNodes } from '../build-graph-nodes.js';
|
|
8
8
|
const execFileAsync = promisify(execFileCb);
|
|
9
|
+
// Cache git info per repo — refreshed every GIT_INFO_TTL_MS via background-style check.
|
|
10
|
+
// getGraphData() always reads from cache (zero git calls), and only spawns git
|
|
11
|
+
// processes when the cache entry is older than the TTL.
|
|
12
|
+
const GIT_INFO_TTL_MS = 30_000;
|
|
13
|
+
const gitInfoCache = new Map();
|
|
9
14
|
async function gitCommand(cwd, args) {
|
|
10
15
|
try {
|
|
11
16
|
const opts = IS_WINDOWS ? { cwd, windowsHide: true } : { cwd };
|
|
@@ -16,22 +21,38 @@ async function gitCommand(cwd, args) {
|
|
|
16
21
|
return null;
|
|
17
22
|
}
|
|
18
23
|
}
|
|
19
|
-
|
|
24
|
+
const FIELD_SEP = '\x1f'; // ASCII Unit Separator — safe in git output and child_process
|
|
25
|
+
/** Refresh git info for a single repo (spawns git processes). */
|
|
26
|
+
async function refreshRepoGitInfo(repo) {
|
|
20
27
|
try {
|
|
21
|
-
const
|
|
28
|
+
const headSha = await gitCommand(repo.path, ['rev-parse', 'HEAD']);
|
|
29
|
+
if (!headSha) {
|
|
30
|
+
// Not a git repo (or bare/broken) — cache this so the UI can show it
|
|
31
|
+
gitInfoCache.set(repo.path, { kind: 'not-a-repo', checkedAt: Date.now() });
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const cached = gitInfoCache.get(repo.path);
|
|
35
|
+
if (cached?.kind === 'repo' && cached.sha === headSha) {
|
|
36
|
+
// HEAD unchanged — just bump checkedAt
|
|
37
|
+
cached.checkedAt = Date.now();
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
// HEAD changed — fetch branch + subject & author in parallel
|
|
41
|
+
const [currentBranch, logLine] = await Promise.all([
|
|
22
42
|
gitCommand(repo.path, ['symbolic-ref', '--short', 'HEAD']),
|
|
23
|
-
gitCommand(repo.path, ['log', '-1',
|
|
24
|
-
gitCommand(repo.path, ['log', '-1', '--format=%an']),
|
|
43
|
+
gitCommand(repo.path, ['log', '-1', `--format=%s${FIELD_SEP}%an`]),
|
|
25
44
|
]);
|
|
26
45
|
if (!currentBranch)
|
|
27
|
-
return
|
|
28
|
-
|
|
46
|
+
return;
|
|
47
|
+
const [commitMessage, committer] = (logLine ?? '').split(FIELD_SEP);
|
|
48
|
+
// Behind count
|
|
29
49
|
let behindCount = null;
|
|
30
|
-
const
|
|
50
|
+
const defaultBranchRef = await gitCommand(repo.path, [
|
|
31
51
|
'symbolic-ref',
|
|
32
52
|
'--short',
|
|
33
53
|
'refs/remotes/origin/HEAD',
|
|
34
|
-
])
|
|
54
|
+
]);
|
|
55
|
+
const defaultBranch = defaultBranchRef?.replace('origin/', '') ?? null;
|
|
35
56
|
if (defaultBranch && currentBranch !== defaultBranch) {
|
|
36
57
|
const behind = await gitCommand(repo.path, [
|
|
37
58
|
'rev-list',
|
|
@@ -42,32 +63,63 @@ async function fetchRepoGitInfo(repo) {
|
|
|
42
63
|
if (isNaN(behindCount))
|
|
43
64
|
behindCount = null;
|
|
44
65
|
}
|
|
45
|
-
else
|
|
66
|
+
else {
|
|
46
67
|
behindCount = 0;
|
|
47
68
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
69
|
+
gitInfoCache.set(repo.path, {
|
|
70
|
+
kind: 'repo',
|
|
71
|
+
sha: headSha,
|
|
72
|
+
checkedAt: Date.now(),
|
|
73
|
+
data: {
|
|
74
|
+
branch: currentBranch,
|
|
75
|
+
commitMessage: commitMessage ?? 'unknown',
|
|
76
|
+
committer: committer ?? 'unknown',
|
|
77
|
+
behindCount,
|
|
78
|
+
},
|
|
79
|
+
});
|
|
54
80
|
}
|
|
55
81
|
catch {
|
|
56
|
-
|
|
82
|
+
// ignore — stale cache is better than no data
|
|
57
83
|
}
|
|
58
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Return cached git info for a repo. If the cache is stale (> TTL),
|
|
87
|
+
* kick off a fire-and-forget refresh so the NEXT call gets fresh data.
|
|
88
|
+
* Never blocks getGraphData() with git subprocess calls.
|
|
89
|
+
*/
|
|
90
|
+
function getRepoGitInfo(repo) {
|
|
91
|
+
const cached = gitInfoCache.get(repo.path);
|
|
92
|
+
const now = Date.now();
|
|
93
|
+
if (!cached) {
|
|
94
|
+
// First time — trigger async refresh, return loading for this call
|
|
95
|
+
void refreshRepoGitInfo(repo);
|
|
96
|
+
return { status: 'loading' };
|
|
97
|
+
}
|
|
98
|
+
if (now - cached.checkedAt >= GIT_INFO_TTL_MS) {
|
|
99
|
+
// Stale — trigger async refresh, return current data immediately
|
|
100
|
+
void refreshRepoGitInfo(repo);
|
|
101
|
+
}
|
|
102
|
+
if (cached.kind === 'not-a-repo') {
|
|
103
|
+
return { status: 'not-a-repo' };
|
|
104
|
+
}
|
|
105
|
+
return { status: 'ready', data: cached.data };
|
|
106
|
+
}
|
|
59
107
|
export async function getGraphData() {
|
|
60
108
|
const listFeatures = resolve('ListFeaturesUseCase');
|
|
61
109
|
const listRepos = resolve('ListRepositoriesUseCase');
|
|
62
110
|
const agentRunRepo = resolve('IAgentRunRepository');
|
|
63
111
|
const [features, repositories] = await Promise.all([listFeatures.execute(), listRepos.execute()]);
|
|
64
|
-
//
|
|
112
|
+
// Read git info from cache (zero git calls). Stale entries trigger
|
|
113
|
+
// a fire-and-forget background refresh for the next poll cycle.
|
|
65
114
|
const repoGitInfoMap = new Map();
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
115
|
+
const repoGitStatusMap = new Map();
|
|
116
|
+
for (const repo of repositories) {
|
|
117
|
+
const result = getRepoGitInfo(repo);
|
|
118
|
+
repoGitStatusMap.set(repo.path, result.status);
|
|
119
|
+
if (result.status === 'ready') {
|
|
120
|
+
repoGitInfoMap.set(repo.path, result.data);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
71
123
|
// PR/CI status is kept fresh by PrSyncWatcher (30s background poll).
|
|
72
124
|
// No live GitHub calls here — use cached DB values for fast response.
|
|
73
125
|
const featuresWithRuns = await Promise.all(features.map(async (feature) => {
|
|
@@ -80,6 +132,7 @@ export async function getGraphData() {
|
|
|
80
132
|
commitEvidence: workflow.commitEvidence,
|
|
81
133
|
ciWatchEnabled: workflow.ciWatchEnabled,
|
|
82
134
|
repoGitInfo: repoGitInfoMap,
|
|
135
|
+
repoGitStatus: repoGitStatusMap,
|
|
83
136
|
});
|
|
84
137
|
// Enrich feature nodes with deployment status
|
|
85
138
|
let deploymentService = null;
|
|
@@ -27,6 +27,8 @@ export interface BuildGraphNodesOptions {
|
|
|
27
27
|
committer: string;
|
|
28
28
|
behindCount: number | null;
|
|
29
29
|
}>;
|
|
30
|
+
/** Git info resolution status keyed by repository path */
|
|
31
|
+
repoGitStatus?: Map<string, 'loading' | 'ready' | 'not-a-repo'>;
|
|
30
32
|
}
|
|
31
33
|
export declare function buildGraphNodes(repositories: Repository[], featuresWithRuns: FeatureWithRun[], options?: BuildGraphNodesOptions): {
|
|
32
34
|
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;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;
|
|
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;IACF,0DAA0D;IAC1D,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,YAAY,CAAC,CAAC;CACjE;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,CAoG5C"}
|
|
@@ -32,6 +32,7 @@ export function buildGraphNodes(repositories, featuresWithRuns, options) {
|
|
|
32
32
|
coveredPaths.add(normalizedRepoPath);
|
|
33
33
|
const repoNodeId = `repo-${repo.id}`;
|
|
34
34
|
const gitInfo = options?.repoGitInfo?.get(repo.path);
|
|
35
|
+
const gitInfoStatus = options?.repoGitStatus?.get(repo.path) ?? 'loading';
|
|
35
36
|
nodes.push({
|
|
36
37
|
id: repoNodeId,
|
|
37
38
|
type: 'repositoryNode',
|
|
@@ -41,6 +42,7 @@ export function buildGraphNodes(repositories, featuresWithRuns, options) {
|
|
|
41
42
|
repositoryPath: normalizedRepoPath,
|
|
42
43
|
id: repo.id,
|
|
43
44
|
createdAt: repo.createdAt instanceof Date ? repo.createdAt.getTime() : Number(repo.createdAt),
|
|
45
|
+
gitInfoStatus,
|
|
44
46
|
...(gitInfo && {
|
|
45
47
|
branch: gitInfo.branch,
|
|
46
48
|
commitMessage: gitInfo.commitMessage,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA6DnE,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,
|
|
1
|
+
{"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA6DnE,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,2CAqWA"}
|
|
@@ -70,7 +70,7 @@ export function FeatureNode({ data, selected, }) {
|
|
|
70
70
|
const config = featureNodeStateConfig[data.state];
|
|
71
71
|
const Icon = config.icon;
|
|
72
72
|
const [confirmOpen, setConfirmOpen] = useState(false);
|
|
73
|
-
return (_jsxs("div", { className: "animate-in fade-in group relative duration-300", children: [data.showHandles ? (_jsx(Handle, { type: "target", position: Position.Left, isConnectable: false, className: "opacity-0!" })) : null, data.onDelete && data.featureId && data.state !== 'deleting' ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "absolute top-1/2 -left-10 -translate-y-1/2 opacity-0 transition-opacity group-hover:opacity-100", onPointerDown: (e) => e.stopPropagation(), children: _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { "aria-label": "Delete feature", "data-testid": "feature-node-delete-button", onClick: (e) => {
|
|
73
|
+
return (_jsxs("div", { className: "animate-in fade-in group relative duration-300", children: [data.showHandles ? (_jsx(Handle, { type: "target", position: Position.Left, isConnectable: false, className: "opacity-0!", style: { top: 70 } })) : null, data.onDelete && data.featureId && data.state !== 'deleting' ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "absolute top-1/2 -left-10 -translate-y-1/2 opacity-0 transition-opacity group-hover:opacity-100", onPointerDown: (e) => e.stopPropagation(), children: _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { "aria-label": "Delete feature", "data-testid": "feature-node-delete-button", onClick: (e) => {
|
|
74
74
|
e.stopPropagation();
|
|
75
75
|
setConfirmOpen(true);
|
|
76
76
|
}, className: "bg-card text-muted-foreground hover:border-destructive hover:text-destructive flex h-7 w-7 cursor-pointer items-center justify-center rounded-full border shadow-sm transition-colors", children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Delete feature" })] }) }) }), _jsx(DeleteFeatureDialog, { open: confirmOpen, onOpenChange: setConfirmOpen, onConfirm: (cleanup, cascadeDelete, closePr) => {
|
|
@@ -109,8 +109,8 @@ export function FeatureNode({ data, selected, }) {
|
|
|
109
109
|
}, className: "nodrag flex shrink-0 cursor-pointer items-center gap-1 rounded-full bg-red-100 px-2.5 py-1 text-[11px] font-medium text-red-700 transition-colors hover:bg-red-200", children: [_jsx(RotateCcw, { className: "h-3 w-3" }), "Retry"] })) : null, data.state === 'pending' && data.onStart ? (_jsxs("button", { type: "button", "aria-label": "Start feature", "data-testid": "feature-node-start-button", onClick: (e) => {
|
|
110
110
|
e.stopPropagation();
|
|
111
111
|
data.onStart(data.featureId);
|
|
112
|
-
}, className: "nodrag flex shrink-0 cursor-pointer items-center gap-1 rounded-full bg-slate-100 px-2.5 py-1 text-[11px] font-medium text-slate-700 transition-colors hover:bg-slate-200", children: [_jsx(Play, { className: "h-3 w-3" }), "Start"] })) : null] })] })) })] }), data.onAction && data.state !== 'deleting' ? (_jsx(Handle, { type: "source", position: Position.Right, className: "h-0! w-0! border-0! bg-transparent!", children: _jsx("button", { type: "button", "aria-label": "Add", "data-testid": "feature-node-action-button", onClick: (e) => {
|
|
112
|
+
}, className: "nodrag flex shrink-0 cursor-pointer items-center gap-1 rounded-full bg-slate-100 px-2.5 py-1 text-[11px] font-medium text-slate-700 transition-colors hover:bg-slate-200", children: [_jsx(Play, { className: "h-3 w-3" }), "Start"] })) : null] })] })) })] }), data.onAction && data.state !== 'deleting' ? (_jsx(Handle, { type: "source", position: Position.Right, className: "h-0! w-0! border-0! bg-transparent!", style: { top: 70 }, children: _jsx("button", { type: "button", "aria-label": "Add", "data-testid": "feature-node-action-button", onClick: (e) => {
|
|
113
113
|
e.stopPropagation();
|
|
114
114
|
data.onAction?.();
|
|
115
|
-
}, className: "nodrag absolute top-1/2 left-1/2 flex h-6 w-6 -translate-x-1/2 -translate-y-1/2 cursor-pointer items-center justify-center rounded-full bg-blue-500 text-white opacity-0 shadow-md transition-opacity group-hover:opacity-100 hover:bg-blue-600", children: _jsx(Plus, { className: "h-3.5 w-3.5" }) }) })) : data.showHandles ? (_jsx(Handle, { type: "source", position: Position.Right, isConnectable: false, className: "opacity-0!" })) : null] }));
|
|
115
|
+
}, className: "nodrag absolute top-1/2 left-1/2 flex h-6 w-6 -translate-x-1/2 -translate-y-1/2 cursor-pointer items-center justify-center rounded-full bg-blue-500 text-white opacity-0 shadow-md transition-opacity group-hover:opacity-100 hover:bg-blue-600", children: _jsx(Plus, { className: "h-3.5 w-3.5" }) }) })) : data.showHandles ? (_jsx(Handle, { type: "source", position: Position.Right, isConnectable: false, className: "opacity-0!", style: { top: 70 } })) : null] }));
|
|
116
116
|
}
|
package/dist/src/presentation/web/components/common/repository-node/repository-node-config.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ export interface RepositoryNodeData {
|
|
|
17
17
|
committer?: string;
|
|
18
18
|
/** Number of commits the current branch is behind the default branch. null if on default branch or unknown. */
|
|
19
19
|
behindCount?: number | null;
|
|
20
|
+
/** Git info resolution status. undefined/'loading' = fetching, 'ready' = resolved, 'not-a-repo' = not a git repo */
|
|
21
|
+
gitInfoStatus?: 'loading' | 'ready' | 'not-a-repo';
|
|
20
22
|
onClick?: () => void;
|
|
21
23
|
onAdd?: () => void;
|
|
22
24
|
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,+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"}
|
|
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,oHAAoH;IACpH,aAAa,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,YAAY,CAAC;IACnD,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":"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,
|
|
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,2CA2Z5F"}
|
|
@@ -56,7 +56,7 @@ export function RepositoryNode({ data }) {
|
|
|
56
56
|
});
|
|
57
57
|
router.push(`/create?${params.toString()}`);
|
|
58
58
|
}, [data.repositoryPath, router]);
|
|
59
|
-
return (_jsxs("div", { className: cn('group relative', data.onDelete && data.id && 'pl-10'), children: [data.showHandles ? (_jsx(Handle, { type: "target", position: Position.Left, isConnectable: false, className: "opacity-0!" })) : null, data.onDelete && data.id ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "absolute top-1/2 left-0 -translate-y-1/2 opacity-0 transition-opacity group-hover:opacity-100", children: _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { "aria-label": "Remove repository", "data-testid": "repository-node-delete-button", onClick: (e) => {
|
|
59
|
+
return (_jsxs("div", { className: cn('group relative', data.onDelete && data.id && 'pl-10'), children: [data.showHandles ? (_jsx(Handle, { type: "target", position: Position.Left, isConnectable: false, className: "opacity-0!", style: { top: 70 } })) : null, data.onDelete && data.id ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "absolute top-1/2 left-0 -translate-y-1/2 opacity-0 transition-opacity group-hover:opacity-100", children: _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { "aria-label": "Remove repository", "data-testid": "repository-node-delete-button", onClick: (e) => {
|
|
60
60
|
e.stopPropagation();
|
|
61
61
|
setConfirmOpen(true);
|
|
62
62
|
}, className: "bg-card text-muted-foreground hover:border-destructive hover:text-destructive flex h-7 w-7 cursor-pointer items-center justify-center rounded-full border shadow-sm transition-colors", children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Remove repository" })] }) }) }), _jsx(Dialog, { open: confirmOpen, onOpenChange: setConfirmOpen, children: _jsxs(DialogContent, { className: "max-w-xs", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Remove repository?" }), _jsxs(DialogDescription, { children: ["This will remove ", _jsx("strong", { children: data.name }), " and all its features from your workspace. The repository files on disk won't be affected."] })] }), _jsxs(DialogFooter, { className: "grid grid-cols-2 gap-2 sm:flex-none", children: [_jsx(DialogClose, { asChild: true, children: _jsx(Button, { variant: "outline", children: "Cancel" }) }), _jsx(Button, { variant: "destructive", onClick: () => {
|
|
@@ -75,9 +75,13 @@ export function RepositoryNode({ data }) {
|
|
|
75
75
|
e.stopPropagation();
|
|
76
76
|
data.onAdd?.();
|
|
77
77
|
}, 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 &&
|
|
78
|
-
'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] }) })
|
|
78
|
+
'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 ? (_jsxs(_Fragment, { children: [_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] }) }), 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.gitInfoStatus === 'not-a-repo' ? (
|
|
79
|
+
/* Not a git repo — two rows for consistency with loading/ready states */
|
|
80
|
+
_jsxs(_Fragment, { children: [_jsx("div", { "data-testid": "repository-node-not-repo", className: "text-muted-foreground border-t px-4 py-2", children: _jsxs("div", { className: "flex items-center gap-2 text-xs", children: [_jsx(FolderOpen, { className: "h-3 w-3 shrink-0" }), _jsx("span", { className: "min-w-0 truncate opacity-60", children: data.repositoryPath ?? 'Unknown path' })] }) }), _jsx("div", { className: "text-muted-foreground border-t px-4 py-2", children: _jsxs("div", { className: "flex items-center gap-2 text-xs opacity-40", children: [_jsx(GitBranch, { className: "h-3 w-3 shrink-0" }), _jsx("span", { children: "Not a git repository" })] }) })] })) : data.gitInfoStatus !== 'ready' ? (
|
|
81
|
+
/* Loading — show skeleton placeholders for both rows */
|
|
82
|
+
_jsxs(_Fragment, { children: [_jsx("div", { "data-testid": "repository-node-git-loading", className: "border-t px-4 py-2", children: _jsxs("div", { className: "flex h-4 items-center gap-2 text-xs", children: [_jsx(GitBranch, { className: "text-muted-foreground h-3 w-3 shrink-0" }), _jsx("span", { className: "bg-muted h-3 w-20 animate-pulse rounded" })] }) }), _jsx("div", { className: "border-t px-4 py-2", children: _jsxs("div", { className: "flex h-4 items-center gap-2 text-xs", children: [_jsx(GitCommitHorizontal, { className: "text-muted-foreground h-3 w-3 shrink-0" }), _jsx("span", { className: "bg-muted h-3 w-36 animate-pulse rounded" })] }) })] })) : null, featureFlags.envDeploy && data.repositoryPath ? (_jsx("div", { "data-testid": "repository-node-dev-preview", className: "border-t px-4 py-2", onClick: (e) => e.stopPropagation(), children: _jsxs("div", { className: "flex items-center gap-2 text-xs", children: [deployAction.deployError ? (_jsx("span", { className: "truncate text-xs text-red-500", children: deployAction.deployError })) : isDeploymentActive ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "mr-0.5 inline-block h-2 w-2 shrink-0 rounded-full bg-green-500" }), deployAction.url ? (_jsx("a", { href: deployAction.url, target: "_blank", rel: "noopener noreferrer", className: "truncate text-green-700 hover:underline dark:text-green-400", children: deployAction.url })) : (_jsx("span", { className: "text-muted-foreground", children: "Starting..." }))] })) : (_jsxs("span", { className: "text-muted-foreground", children: ["Run", _jsx("span", { className: "text-muted-foreground/50 ml-2 text-[10px]", children: "start local environment" })] })), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "ml-auto flex items-center", children: _jsx(ActionButton, { label: deployAction.deployError
|
|
79
83
|
? 'Retry'
|
|
80
84
|
: isDeploymentActive
|
|
81
85
|
? 'Stop Dev Server'
|
|
82
|
-
: 'Start Dev Server', onClick: isDeploymentActive ? deployAction.stop : deployAction.deploy, loading: deployAction.deployLoading || deployAction.stopLoading, error: false, icon: deployAction.deployError ? RotateCcw : isDeploymentActive ? Square : Play, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: isDeploymentActive ? 'Stop Dev Server' : 'Start Dev Server' })] }) })] }) })) : null] }), data.onAdd || data.showHandles ? (_jsx(Handle, { type: "source", position: Position.Right, isConnectable: !data.showHandles, className: "opacity-0!" })) : null] }));
|
|
86
|
+
: 'Start Dev Server', onClick: isDeploymentActive ? deployAction.stop : deployAction.deploy, loading: deployAction.deployLoading || deployAction.stopLoading, error: false, icon: deployAction.deployError ? RotateCcw : isDeploymentActive ? Square : Play, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: isDeploymentActive ? 'Stop Dev Server' : 'Start Dev Server' })] }) })] }) })) : null] }), data.onAdd || data.showHandles ? (_jsx(Handle, { type: "source", position: Position.Right, isConnectable: !data.showHandles, className: "opacity-0!", style: { top: 70 } })) : null] }));
|
|
83
87
|
}
|
package/dist/src/presentation/web/components/common/repository-node/repository-node.stories.d.ts
CHANGED
|
@@ -16,4 +16,6 @@ export declare const WithDeleteButton: Story;
|
|
|
16
16
|
export declare const MultipleWithActions: Story;
|
|
17
17
|
export declare const WithGitInfo: Story;
|
|
18
18
|
export declare const WithGitInfoBehind: Story;
|
|
19
|
+
export declare const GitInfoLoading: Story;
|
|
20
|
+
export declare const NotAGitRepo: Story;
|
|
19
21
|
//# 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,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"}
|
|
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;AAEF,eAAO,MAAM,cAAc,EAAE,KAM5B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAMzB,CAAC"}
|
package/dist/src/presentation/web/components/common/repository-node/repository-node.stories.js
CHANGED
|
@@ -235,3 +235,17 @@ export const WithGitInfoBehind = {
|
|
|
235
235
|
},
|
|
236
236
|
render: (args) => _jsx(RepositoryNodeCanvas, { data: args }),
|
|
237
237
|
};
|
|
238
|
+
export const GitInfoLoading = {
|
|
239
|
+
args: {
|
|
240
|
+
repositoryPath: '/home/user/shep-ai/cli',
|
|
241
|
+
gitInfoStatus: 'loading',
|
|
242
|
+
},
|
|
243
|
+
render: (args) => _jsx(RepositoryNodeCanvas, { data: args }),
|
|
244
|
+
};
|
|
245
|
+
export const NotAGitRepo = {
|
|
246
|
+
args: {
|
|
247
|
+
repositoryPath: '/home/user/my-project',
|
|
248
|
+
gitInfoStatus: 'not-a-repo',
|
|
249
|
+
},
|
|
250
|
+
render: (args) => _jsx(RepositoryNodeCanvas, { data: args }),
|
|
251
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-control-center-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/use-control-center-state.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAgBjC,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAM7E,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/D,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAChD,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/E,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,mBAAmB,EAAE,CACnB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,OAAO,EACvB,OAAO,CAAC,EAAE,OAAO,KACd,IAAI,CAAC;IACV,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,sBAAsB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,iBAAiB,EAAE,CACjB,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,EACvC,QAAQ,CAAC,EAAE,MAAM,KACd,MAAM,CAAC;IACZ,wDAAwD;IACxD,wBAAwB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACxE,gDAAgD;IAChD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,kBAAkB,GAAG,SAAS,CAAC;IACtE,0EAA0E;IAC1E,YAAY,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;CACnD;AAQD,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"use-control-center-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/use-control-center-state.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAgBjC,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAM7E,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/D,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAChD,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/E,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,mBAAmB,EAAE,CACnB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,OAAO,EACvB,OAAO,CAAC,EAAE,OAAO,KACd,IAAI,CAAC;IACV,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,sBAAsB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,iBAAiB,EAAE,CACjB,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,EACvC,QAAQ,CAAC,EAAE,MAAM,KACd,MAAM,CAAC;IACZ,wDAAwD;IACxD,wBAAwB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACxE,gDAAgD;IAChD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,kBAAkB,GAAG,SAAS,CAAC;IACtE,0EAA0E;IAC1E,YAAY,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;CACnD;AAQD,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,kBAAkB,CAwhBpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive-graph.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/lib/derive-graph.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,qDAAqD;AACrD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,eAAe,CAAC;IACtB,sGAAsG;IACtG,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wDAAwD;AACxD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,kBAAkB,CAAC;CAC1B;AAED,gFAAgF;AAChF,MAAM,WAAW,cAAc;IAC7B,4FAA4F;IAC5F,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,qEAAqE;IACrE,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,8CAA8C;IAC9C,eAAe,CAAC,EAAE,CAChB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,OAAO,EACvB,OAAO,CAAC,EAAE,OAAO,KACd,IAAI,CAAC;IACV,6EAA6E;IAC7E,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,iDAAiD;IACjD,kBAAkB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,qDAAqD;IACrD,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,qDAAqD;IACrD,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,oDAAoD;IACpD,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACrC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,EAC/B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACrC,SAAS,CAAC,EAAE,cAAc,GACzB;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"derive-graph.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/lib/derive-graph.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,qDAAqD;AACrD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,eAAe,CAAC;IACtB,sGAAsG;IACtG,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wDAAwD;AACxD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,kBAAkB,CAAC;CAC1B;AAED,gFAAgF;AAChF,MAAM,WAAW,cAAc;IAC7B,4FAA4F;IAC5F,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,qEAAqE;IACrE,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,8CAA8C;IAC9C,eAAe,CAAC,EAAE,CAChB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,OAAO,EACvB,OAAO,CAAC,EAAE,OAAO,KACd,IAAI,CAAC;IACV,6EAA6E;IAC7E,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,iDAAiD;IACjD,kBAAkB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,qDAAqD;IACrD,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,qDAAqD;IACrD,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,oDAAoD;IACpD,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACrC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,EAC/B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACrC,SAAS,CAAC,EAAE,cAAc,GACzB;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAiK5C"}
|
|
@@ -46,9 +46,12 @@ export function deriveGraph(featureMap, repoMap, pendingMap, callbacks) {
|
|
|
46
46
|
// Add repo nodes (real ones) — sorted by createdAt for stable vertical order.
|
|
47
47
|
// The server-side layoutWithDagre may reorder the node array (connected vs
|
|
48
48
|
// disconnected split), so we cannot rely on Map insertion order alone.
|
|
49
|
+
// Use Infinity fallback so repos without createdAt sort last (appear at bottom).
|
|
49
50
|
const sortedRepoEntries = [...repoMap.entries()].sort((a, b) => {
|
|
50
|
-
const
|
|
51
|
-
const
|
|
51
|
+
const aRaw = a[1].data.createdAt;
|
|
52
|
+
const bRaw = b[1].data.createdAt;
|
|
53
|
+
const aTime = typeof aRaw === 'number' && !Number.isNaN(aRaw) ? aRaw : Infinity;
|
|
54
|
+
const bTime = typeof bRaw === 'number' && !Number.isNaN(bRaw) ? bRaw : Infinity;
|
|
52
55
|
return aTime - bTime;
|
|
53
56
|
});
|
|
54
57
|
for (const [nodeId, entry] of sortedRepoEntries) {
|
|
@@ -7,8 +7,8 @@ export const CANVAS_LAYOUT_DEFAULTS = {
|
|
|
7
7
|
};
|
|
8
8
|
/** Known node-type dimensions for the canvas node types */
|
|
9
9
|
const NODE_DIMENSIONS = {
|
|
10
|
-
featureNode: { width: 288, height:
|
|
11
|
-
repositoryNode: { width: 400, height:
|
|
10
|
+
featureNode: { width: 288, height: 140 },
|
|
11
|
+
repositoryNode: { width: 400, height: 140 },
|
|
12
12
|
};
|
|
13
13
|
function getNodeSize(node, defaultSize) {
|
|
14
14
|
// Prefer per-node size from data, then type-based lookup, then default
|