@shepai/cli 1.129.0-pr410.ed5d9df → 1.129.0-pr413.57e1c33

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.
Files changed (156) hide show
  1. package/dist/packages/core/src/application/use-cases/repositories/add-repository.use-case.d.ts.map +1 -1
  2. package/dist/packages/core/src/application/use-cases/repositories/add-repository.use-case.js +2 -5
  3. package/dist/packages/core/src/infrastructure/repositories/sqlite-repository.repository.js +2 -2
  4. package/dist/packages/core/src/infrastructure/services/agents/common/agent-validator.service.js +1 -1
  5. package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.d.ts +5 -5
  6. package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.js +8 -8
  7. package/dist/packages/core/src/infrastructure/services/deployment/deployment.service.d.ts.map +1 -1
  8. package/dist/packages/core/src/infrastructure/services/deployment/deployment.service.js +20 -6
  9. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.d.ts.map +1 -1
  10. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.js +19 -61
  11. package/dist/src/presentation/web/app/actions/check-agent-auth.js +1 -1
  12. package/dist/src/presentation/web/lib/derive-graph.d.ts.map +1 -1
  13. package/dist/src/presentation/web/lib/derive-graph.js +2 -5
  14. package/dist/tsconfig.build.tsbuildinfo +1 -1
  15. package/package.json +1 -1
  16. package/web/.next/BUILD_ID +1 -1
  17. package/web/.next/build-manifest.json +2 -2
  18. package/web/.next/fallback-build-manifest.json +2 -2
  19. package/web/.next/prerender-manifest.json +3 -3
  20. package/web/.next/required-server-files.js +1 -1
  21. package/web/.next/required-server-files.json +1 -1
  22. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +24 -24
  23. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  24. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  25. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +24 -24
  26. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  27. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  28. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +30 -30
  29. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  30. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  31. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +30 -30
  32. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  33. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  34. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +22 -22
  35. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  36. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  37. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +24 -24
  38. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  39. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  40. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +30 -30
  41. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  42. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  43. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +30 -30
  44. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  45. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  46. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +22 -22
  47. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  48. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  49. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +22 -22
  50. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  51. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  52. package/web/.next/server/app/_global-error.html +2 -2
  53. package/web/.next/server/app/_global-error.rsc +1 -1
  54. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  55. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  56. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  57. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  58. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  59. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +3 -3
  60. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  61. package/web/.next/server/app/settings/page/server-reference-manifest.json +8 -8
  62. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  63. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  64. package/web/.next/server/app/skills/page/server-reference-manifest.json +8 -8
  65. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  66. package/web/.next/server/app/tools/page/server-reference-manifest.json +8 -8
  67. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  68. package/web/.next/server/app/version/page/server-reference-manifest.json +3 -3
  69. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  70. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +1 -1
  71. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +1 -1
  72. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  73. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_4e741df2.js +1 -1
  74. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_4e741df2.js.map +1 -1
  75. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  76. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  77. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_026fdffa.js +1 -1
  78. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_026fdffa.js.map +1 -1
  79. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_8b91e197.js +1 -1
  80. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_8b91e197.js.map +1 -1
  81. package/web/.next/server/chunks/ssr/[root-of-the-server]__0e842eba._.js +1 -1
  82. package/web/.next/server/chunks/ssr/[root-of-the-server]__0e842eba._.js.map +1 -1
  83. package/web/.next/server/chunks/ssr/[root-of-the-server]__2f886f77._.js +2 -2
  84. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  85. package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js +1 -1
  86. package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js.map +1 -1
  87. package/web/.next/server/chunks/ssr/[root-of-the-server]__60684242._.js +2 -2
  88. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +2 -2
  89. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js.map +1 -1
  90. package/web/.next/server/chunks/ssr/[root-of-the-server]__755cfe02._.js +1 -1
  91. package/web/.next/server/chunks/ssr/[root-of-the-server]__755cfe02._.js.map +1 -1
  92. package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js +1 -1
  93. package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js.map +1 -1
  94. package/web/.next/server/chunks/ssr/[root-of-the-server]__a628fb91._.js +1 -1
  95. package/web/.next/server/chunks/ssr/[root-of-the-server]__a628fb91._.js.map +1 -1
  96. package/web/.next/server/chunks/ssr/[root-of-the-server]__bfba58e6._.js +1 -1
  97. package/web/.next/server/chunks/ssr/[root-of-the-server]__bfba58e6._.js.map +1 -1
  98. package/web/.next/server/chunks/ssr/[root-of-the-server]__c3ab8422._.js +1 -1
  99. package/web/.next/server/chunks/ssr/[root-of-the-server]__c3ab8422._.js.map +1 -1
  100. package/web/.next/server/chunks/ssr/[root-of-the-server]__f4a463ee._.js +2 -2
  101. package/web/.next/server/chunks/ssr/[root-of-the-server]__f4a463ee._.js.map +1 -1
  102. package/web/.next/server/chunks/ssr/_02ec1aea._.js +1 -1
  103. package/web/.next/server/chunks/ssr/_02ec1aea._.js.map +1 -1
  104. package/web/.next/server/chunks/ssr/{_d5ed80ec._.js → _4c579535._.js} +2 -2
  105. package/web/.next/server/chunks/ssr/{_d5ed80ec._.js.map → _4c579535._.js.map} +1 -1
  106. package/web/.next/server/chunks/ssr/_7dca1882._.js +1 -1
  107. package/web/.next/server/chunks/ssr/_7dca1882._.js.map +1 -1
  108. package/web/.next/server/chunks/ssr/_a9f57758._.js +1 -1
  109. package/web/.next/server/chunks/ssr/_a9f57758._.js.map +1 -1
  110. package/web/.next/server/chunks/ssr/_d8575088._.js +1 -1
  111. package/web/.next/server/chunks/ssr/_d8575088._.js.map +1 -1
  112. package/web/.next/server/chunks/ssr/{_0a5b0b02._.js → _ea5daaaf._.js} +2 -2
  113. package/web/.next/server/chunks/ssr/{_0a5b0b02._.js.map → _ea5daaaf._.js.map} +1 -1
  114. package/web/.next/server/chunks/ssr/_f39a1adb._.js +1 -1
  115. package/web/.next/server/chunks/ssr/_f39a1adb._.js.map +1 -1
  116. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  117. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  118. package/web/.next/server/chunks/ssr/src_presentation_web_8401cef2._.js +3 -0
  119. package/web/.next/server/chunks/ssr/{src_presentation_web_53cd7c96._.js.map → src_presentation_web_8401cef2._.js.map} +1 -1
  120. package/web/.next/server/chunks/ssr/src_presentation_web_8e7fe0d1._.js +2 -2
  121. package/web/.next/server/chunks/ssr/src_presentation_web_8e7fe0d1._.js.map +1 -1
  122. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_ca051134.js +1 -1
  123. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_ca051134.js.map +1 -1
  124. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js +1 -1
  125. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js.map +1 -1
  126. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js +1 -1
  127. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js.map +1 -1
  128. package/web/.next/server/chunks/ssr/src_presentation_web_b9023017._.js +2 -2
  129. package/web/.next/server/chunks/ssr/src_presentation_web_b9023017._.js.map +1 -1
  130. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
  131. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +1 -1
  132. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  133. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  134. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  135. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  136. package/web/.next/server/pages/500.html +2 -2
  137. package/web/.next/server/server-reference-manifest.js +1 -1
  138. package/web/.next/server/server-reference-manifest.json +38 -38
  139. package/web/.next/static/chunks/{59ce8663d782b152.js → 2c0f72e13873aa11.js} +1 -1
  140. package/web/.next/static/chunks/{02a03be471ed7fc0.js → 36544f2ce44008e9.js} +1 -1
  141. package/web/.next/static/chunks/{a6c54fd7bc04ea3f.js → 4fa84a327da62d41.js} +1 -1
  142. package/web/.next/static/chunks/{445f9440d2e19556.js → 5ee76a706c272a48.js} +1 -1
  143. package/web/.next/static/chunks/{0e8cfccaec7161e1.js → 8435f506faaeab86.js} +1 -1
  144. package/web/.next/static/chunks/{af2d9b6f87f1c945.js → 963c38281082498c.js} +1 -1
  145. package/web/.next/static/chunks/{747b4087a4627544.js → b4211828df7f8b84.js} +1 -1
  146. package/web/.next/static/chunks/{d3b43898d0abd644.js → e46b2039c3259c91.js} +1 -1
  147. package/web/.next/static/chunks/{7ad143a8a2f1c5c9.js → e6b6017a4788e869.js} +1 -1
  148. package/web/.next/static/chunks/{4e973d3211708b04.js → e9b5b99f78a82ff2.js} +1 -1
  149. package/web/.next/static/chunks/f0f36e5435461097.js +1 -0
  150. package/web/.next/static/chunks/fbe09387689edb43.js +2 -0
  151. package/web/.next/server/chunks/ssr/src_presentation_web_53cd7c96._.js +0 -3
  152. package/web/.next/static/chunks/5411615c8f376ba2.js +0 -1
  153. package/web/.next/static/chunks/f67901f8262497f5.js +0 -2
  154. /package/web/.next/static/{NYA9ccZUUDf9yt_EGEyjo → 2FNRt2NFwO7rgcja0AV1h}/_buildManifest.js +0 -0
  155. /package/web/.next/static/{NYA9ccZUUDf9yt_EGEyjo → 2FNRt2NFwO7rgcja0AV1h}/_clientMiddlewareManifest.json +0 -0
  156. /package/web/.next/static/{NYA9ccZUUDf9yt_EGEyjo → 2FNRt2NFwO7rgcja0AV1h}/_ssgManifest.js +0 -0
@@ -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;CAiC9D"}
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;CA8B9D"}
@@ -41,14 +41,11 @@ 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.
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).
44
+ // Check for soft-deleted repository — restore it instead of creating a duplicate
47
45
  const deleted = await this.repositoryRepo.findByPathIncludingDeleted(normalizedPath);
48
46
  if (deleted) {
49
- const now = new Date();
50
47
  await this.repositoryRepo.restore(deleted.id);
51
- return { ...deleted, deletedAt: undefined, createdAt: now, updatedAt: now };
48
+ return { ...deleted, deletedAt: undefined, updatedAt: new Date() };
52
49
  }
53
50
  const now = new Date();
54
51
  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, created_at = ?, updated_at = ? WHERE id = ?');
98
- stmt.run(now, now, id);
97
+ const stmt = this.db.prepare('UPDATE repositories SET deleted_at = NULL, updated_at = ? WHERE id = ?');
98
+ stmt.run(now, id);
99
99
  }
100
100
  static normalizeRemoteUrl(url) {
101
101
  return url.replace(/\.git$/, '').toLowerCase();
@@ -26,7 +26,7 @@ import { injectable, inject } from 'tsyringe';
26
26
  */
27
27
  const AGENT_BINARY_MAP = {
28
28
  'claude-code': 'claude',
29
- cursor: 'agent',
29
+ cursor: 'cursor-agent',
30
30
  'gemini-cli': 'gemini',
31
31
  };
32
32
  /**
@@ -2,7 +2,7 @@
2
2
  * Cursor Executor Service
3
3
  *
4
4
  * Infrastructure implementation of IAgentExecutor for the Cursor agent.
5
- * Executes prompts via the `agent` CLI subprocess with JSON and stream-json
5
+ * Executes prompts via the `cursor-agent` CLI subprocess with JSON and stream-json
6
6
  * output formats.
7
7
  *
8
8
  * Uses constructor dependency injection for the spawn function
@@ -13,7 +13,7 @@ import type { IAgentExecutor, AgentExecutionOptions, AgentExecutionResult, Agent
13
13
  import type { SpawnFunction } from '../types.js';
14
14
  /**
15
15
  * Executor service for Cursor agent.
16
- * Uses subprocess spawning to interact with the `agent` CLI.
16
+ * Uses subprocess spawning to interact with the `cursor-agent` CLI.
17
17
  */
18
18
  export declare class CursorExecutorService implements IAgentExecutor {
19
19
  private readonly spawn;
@@ -35,13 +35,13 @@ export declare class CursorExecutorService implements IAgentExecutor {
35
35
  /**
36
36
  * Spawn the agent process, handling Windows specially via PowerShell.
37
37
  *
38
- * On Windows, cursor CLI ships as `agent.cmd` which requires `shell: true`,
38
+ * On Windows, cursor CLI ships as `cursor-agent.cmd` which requires `shell: true`,
39
39
  * but cmd.exe mangles long `-p` arguments (8191-char limit + special chars).
40
- * Solution: write prompt to a temp file, invoke agent via PowerShell which
40
+ * Solution: write prompt to a temp file, invoke cursor-agent via PowerShell which
41
41
  * reads the file and passes the content as `-p`. PowerShell handles long
42
42
  * strings natively (32K limit) and doesn't mangle arguments.
43
43
  *
44
- * On Linux/macOS, spawn `agent` directly — no shell needed.
44
+ * On Linux/macOS, spawn `cursor-agent` directly — no shell needed.
45
45
  */
46
46
  private spawnAgent;
47
47
  private parseStreamLine;
@@ -2,7 +2,7 @@
2
2
  * Cursor Executor Service
3
3
  *
4
4
  * Infrastructure implementation of IAgentExecutor for the Cursor agent.
5
- * Executes prompts via the `agent` CLI subprocess with JSON and stream-json
5
+ * Executes prompts via the `cursor-agent` CLI subprocess with JSON and stream-json
6
6
  * output formats.
7
7
  *
8
8
  * Uses constructor dependency injection for the spawn function
@@ -32,7 +32,7 @@ function toCursorModelName(model) {
32
32
  const SUPPORTED_FEATURES = new Set(['session-resume', 'streaming']);
33
33
  /**
34
34
  * Executor service for Cursor agent.
35
- * Uses subprocess spawning to interact with the `agent` CLI.
35
+ * Uses subprocess spawning to interact with the `cursor-agent` CLI.
36
36
  */
37
37
  export class CursorExecutorService {
38
38
  spawn;
@@ -312,13 +312,13 @@ export class CursorExecutorService {
312
312
  /**
313
313
  * Spawn the agent process, handling Windows specially via PowerShell.
314
314
  *
315
- * On Windows, cursor CLI ships as `agent.cmd` which requires `shell: true`,
315
+ * On Windows, cursor CLI ships as `cursor-agent.cmd` which requires `shell: true`,
316
316
  * but cmd.exe mangles long `-p` arguments (8191-char limit + special chars).
317
- * Solution: write prompt to a temp file, invoke agent via PowerShell which
317
+ * Solution: write prompt to a temp file, invoke cursor-agent via PowerShell which
318
318
  * reads the file and passes the content as `-p`. PowerShell handles long
319
319
  * strings natively (32K limit) and doesn't mangle arguments.
320
320
  *
321
- * On Linux/macOS, spawn `agent` directly — no shell needed.
321
+ * On Linux/macOS, spawn `cursor-agent` directly — no shell needed.
322
322
  */
323
323
  spawnAgent(prompt, args, options) {
324
324
  const { CLAUDECODE: _, ...cleanEnv } = process.env;
@@ -330,7 +330,7 @@ export class CursorExecutorService {
330
330
  // Build the agent args WITHOUT -p and the prompt (they go via temp file)
331
331
  const agentFlags = args.filter((a) => a !== '-p' && a !== prompt).join(' ');
332
332
  const safePath = tmpFile.replace(/'/g, "''");
333
- const psCmd = `$p = Get-Content -Raw '${safePath}'; & agent ${agentFlags} -p $p`;
333
+ const psCmd = `$p = Get-Content -Raw '${safePath}'; & cursor-agent ${agentFlags} -p $p`;
334
334
  this.log(`Windows PowerShell mode: wrote ${prompt.length} chars to ${tmpFile}`);
335
335
  this.log(`PS command: ${psCmd.replace(prompt, `<${prompt.length} chars>`)}`);
336
336
  const proc = this.spawn('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', psCmd], {
@@ -351,9 +351,9 @@ export class CursorExecutorService {
351
351
  };
352
352
  if (cwd)
353
353
  spawnOpts.cwd = cwd;
354
- this.log(`Spawning: agent ${args.map((a) => (a.length > 80 ? `${a.slice(0, 77)}...` : a)).join(' ')}`);
354
+ this.log(`Spawning: cursor-agent ${args.map((a) => (a.length > 80 ? `${a.slice(0, 77)}...` : a)).join(' ')}`);
355
355
  this.log(`Spawn cwd: ${cwd ?? '(inherited)'}`);
356
- const proc = this.spawn('agent', args, spawnOpts);
356
+ const proc = this.spawn('cursor-agent', args, spawnOpts);
357
357
  this.log(`Subprocess PID: ${proc.pid ?? 'undefined (spawn may have failed)'}`);
358
358
  if (proc.stdin)
359
359
  proc.stdin.end();
@@ -1 +1 @@
1
- {"version":3,"file":"deployment.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/deployment/deployment.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;AAE9D,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAO3C,OAAO,KAAK,EACV,kBAAkB,EAClB,gBAAgB,EAChB,QAAQ,EACT,MAAM,qEAAqE,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAgCzD,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,eAAe,EAAE,OAAO,eAAe,CAAC;IACxC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;IAC7D,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACnC;AA6BD,qBAAa,iBAAkB,YAAW,kBAAkB;IAC1D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsC;IAClE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAwB;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,EAAE,CAAkC;gBAEhC,IAAI,GAAE,OAAO,CAAC,qBAAqB,CAAM;IAIrD;;OAEG;IACH,WAAW,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI;IAIxC;;;OAGG;IACH,UAAU,IAAI,IAAI;IA4ClB;;;OAGG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,SAAe,GAAG,IAAI;IAqF5E;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IA4CpD;;OAEG;IACG,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0D3C;;OAEG;IACH,OAAO,IAAI,IAAI;IAef;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,EAAE,GAAG,IAAI;IAM5C;;OAEG;IACH,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,IAAI;IAI1D;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,IAAI;IAM3D,OAAO,CAAC,QAAQ;IAuBhB,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,MAAM;IAed,OAAO,CAAC,WAAW;IAQnB;;;OAGG;IACH,OAAO,CAAC,oBAAoB;YA4Dd,aAAa;IAW3B,OAAO,CAAC,WAAW;CASpB"}
1
+ {"version":3,"file":"deployment.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/deployment/deployment.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAmC,MAAM,oBAAoB,CAAC;AAE5E,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAK3C,OAAO,KAAK,EACV,kBAAkB,EAClB,gBAAgB,EAChB,QAAQ,EACT,MAAM,qEAAqE,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAiCzD,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,eAAe,EAAE,OAAO,eAAe,CAAC;IACxC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;IAC7D,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACnC;AA0CD,qBAAa,iBAAkB,YAAW,kBAAkB;IAC1D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsC;IAClE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAwB;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,EAAE,CAAkC;gBAEhC,IAAI,GAAE,OAAO,CAAC,qBAAqB,CAAM;IAIrD;;OAEG;IACH,WAAW,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI;IAIxC;;;OAGG;IACH,UAAU,IAAI,IAAI;IA4ClB;;;OAGG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,SAAe,GAAG,IAAI;IAsF5E;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IA4CpD;;OAEG;IACG,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0D3C;;OAEG;IACH,OAAO,IAAI,IAAI;IAef;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,EAAE,GAAG,IAAI;IAM5C;;OAEG;IACH,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,IAAI;IAI1D;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,IAAI;IAM3D,OAAO,CAAC,QAAQ;IAuBhB,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,MAAM;IAed,OAAO,CAAC,WAAW;IAQnB;;;OAGG;IACH,OAAO,CAAC,oBAAoB;YA4Dd,aAAa;IAW3B,OAAO,CAAC,WAAW;CASpB"}
@@ -9,18 +9,17 @@
9
9
  * On startup, call `recoverAll()` to reconcile the DB with actual
10
10
  * process state (clean up dead PIDs, re-adopt live ones).
11
11
  */
12
- import { spawn } from 'node:child_process';
12
+ import { spawn, execFileSync } from 'node:child_process';
13
13
  import { EventEmitter } from 'node:events';
14
- // NOTE: We intentionally do NOT use tree-kill here. tree-kill traverses
15
- // /proc to find child processes which can accidentally kill parent processes
16
- // (including the Shep web UI). Instead, we use process.kill(-pid) to send
17
- // signals to the process GROUP (since we spawn with detached: true, the
18
- // child gets its own process group via setsid()).
14
+ // On Unix we use process.kill(-pid) to send signals to the process GROUP
15
+ // (detached: true puts the child in its own group via setsid()).
16
+ // On Windows, negative PIDs are not supported use taskkill /T for tree kill.
19
17
  import { DeploymentState } from '../../../domain/generated/output.js';
20
18
  import { detectDevScript } from './detect-dev-script.js';
21
19
  import { createDeploymentLogger } from './deployment-logger.js';
22
20
  import { parsePort } from './parse-port.js';
23
21
  import { LogRingBuffer } from './log-ring-buffer.js';
22
+ import { IS_WINDOWS } from '../../platform.js';
24
23
  const log = createDeploymentLogger('[DeploymentService]');
25
24
  const POLL_INTERVAL_MS = 200;
26
25
  const MAX_WAIT_MS = 5000;
@@ -28,6 +27,20 @@ const defaultDeps = {
28
27
  spawn,
29
28
  detectDevScript,
30
29
  kill: (pid, signal) => {
30
+ if (IS_WINDOWS) {
31
+ // On Windows, negative PIDs are not supported. Use taskkill /T to
32
+ // kill the entire process tree (shell + child dev server).
33
+ try {
34
+ execFileSync('taskkill', ['/F', '/T', '/PID', String(pid)], {
35
+ stdio: 'ignore',
36
+ windowsHide: true,
37
+ });
38
+ }
39
+ catch {
40
+ // Process already dead
41
+ }
42
+ return;
43
+ }
31
44
  try {
32
45
  // Kill the entire process group (negative PID) — safe because
33
46
  // detached: true puts the child in its own group via setsid().
@@ -140,6 +153,7 @@ export class DeploymentService {
140
153
  cwd: targetPath,
141
154
  detached: true,
142
155
  stdio: ['ignore', 'pipe', 'pipe'],
156
+ ...(IS_WINDOWS ? { windowsHide: true } : {}),
143
157
  });
144
158
  if (!child.pid) {
145
159
  log.error('spawn() returned no PID — process failed to start');
@@ -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;AAqGD,wBAAsB,YAAY,IAAI,OAAO,CAAC;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAAC,CAwDxF"}
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;AAqDD,wBAAsB,YAAY,IAAI,OAAO,CAAC;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAAC,CAyDxF"}
@@ -6,11 +6,6 @@ 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();
14
9
  async function gitCommand(cwd, args) {
15
10
  try {
16
11
  const opts = IS_WINDOWS ? { cwd, windowsHide: true } : { cwd };
@@ -21,35 +16,22 @@ async function gitCommand(cwd, args) {
21
16
  return null;
22
17
  }
23
18
  }
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) {
19
+ async function fetchRepoGitInfo(repo) {
27
20
  try {
28
- const headSha = await gitCommand(repo.path, ['rev-parse', 'HEAD']);
29
- if (!headSha)
30
- return;
31
- const cached = gitInfoCache.get(repo.path);
32
- if (cached?.sha === headSha) {
33
- // HEAD unchanged — just bump checkedAt
34
- cached.checkedAt = Date.now();
35
- return;
36
- }
37
- // HEAD changed — fetch branch + subject & author in parallel
38
- const [currentBranch, logLine] = await Promise.all([
21
+ const [currentBranch, commitMessage, committer] = await Promise.all([
39
22
  gitCommand(repo.path, ['symbolic-ref', '--short', 'HEAD']),
40
- gitCommand(repo.path, ['log', '-1', `--format=%s${FIELD_SEP}%an`]),
23
+ gitCommand(repo.path, ['log', '-1', '--format=%s']),
24
+ gitCommand(repo.path, ['log', '-1', '--format=%an']),
41
25
  ]);
42
26
  if (!currentBranch)
43
- return;
44
- const [commitMessage, committer] = (logLine ?? '').split(FIELD_SEP);
45
- // Behind count
27
+ return null;
28
+ // Try to determine the default branch to compute behind count
46
29
  let behindCount = null;
47
- const defaultBranchRef = await gitCommand(repo.path, [
30
+ const defaultBranch = await gitCommand(repo.path, [
48
31
  'symbolic-ref',
49
32
  '--short',
50
33
  'refs/remotes/origin/HEAD',
51
- ]);
52
- const defaultBranch = defaultBranchRef?.replace('origin/', '') ?? null;
34
+ ]).then((ref) => ref?.replace('origin/', '') ?? null);
53
35
  if (defaultBranch && currentBranch !== defaultBranch) {
54
36
  const behind = await gitCommand(repo.path, [
55
37
  'rev-list',
@@ -60,56 +42,32 @@ async function refreshRepoGitInfo(repo) {
60
42
  if (isNaN(behindCount))
61
43
  behindCount = null;
62
44
  }
63
- else {
45
+ else if (!defaultBranch || currentBranch === defaultBranch) {
64
46
  behindCount = 0;
65
47
  }
66
- gitInfoCache.set(repo.path, {
67
- sha: headSha,
68
- checkedAt: Date.now(),
69
- data: {
70
- branch: currentBranch,
71
- commitMessage: commitMessage ?? 'unknown',
72
- committer: committer ?? 'unknown',
73
- behindCount,
74
- },
75
- });
48
+ return {
49
+ branch: currentBranch,
50
+ commitMessage: commitMessage ?? 'unknown',
51
+ committer: committer ?? 'unknown',
52
+ behindCount,
53
+ };
76
54
  }
77
55
  catch {
78
- // ignore — stale cache is better than no data
79
- }
80
- }
81
- /**
82
- * Return cached git info for a repo. If the cache is stale (> TTL),
83
- * kick off a fire-and-forget refresh so the NEXT call gets fresh data.
84
- * Never blocks getGraphData() with git subprocess calls.
85
- */
86
- function getRepoGitInfo(repo) {
87
- const cached = gitInfoCache.get(repo.path);
88
- const now = Date.now();
89
- if (!cached) {
90
- // First time — trigger async refresh, return null for this call
91
- void refreshRepoGitInfo(repo);
92
56
  return null;
93
57
  }
94
- if (now - cached.checkedAt >= GIT_INFO_TTL_MS) {
95
- // Stale — trigger async refresh, return stale data immediately
96
- void refreshRepoGitInfo(repo);
97
- }
98
- return cached.data;
99
58
  }
100
59
  export async function getGraphData() {
101
60
  const listFeatures = resolve('ListFeaturesUseCase');
102
61
  const listRepos = resolve('ListRepositoriesUseCase');
103
62
  const agentRunRepo = resolve('IAgentRunRepository');
104
63
  const [features, repositories] = await Promise.all([listFeatures.execute(), listRepos.execute()]);
105
- // Read git info from cache (zero git calls). Stale entries trigger
106
- // a fire-and-forget background refresh for the next poll cycle.
64
+ // Fetch git info (branch, commit, behind count) for each repository
107
65
  const repoGitInfoMap = new Map();
108
- for (const repo of repositories) {
109
- const info = getRepoGitInfo(repo);
66
+ await Promise.all(repositories.map(async (repo) => {
67
+ const info = await fetchRepoGitInfo(repo);
110
68
  if (info)
111
69
  repoGitInfoMap.set(repo.path, info);
112
- }
70
+ }));
113
71
  // PR/CI status is kept fresh by PrSyncWatcher (30s background poll).
114
72
  // No live GitHub calls here — use cached DB values for fast response.
115
73
  const featuresWithRuns = await Promise.all(features.map(async (feature) => {
@@ -21,7 +21,7 @@ const AGENT_TOOL_MAP = {
21
21
  };
22
22
  const AGENT_BINARY_MAP = {
23
23
  'claude-code': 'claude',
24
- cursor: 'agent',
24
+ cursor: 'cursor-agent',
25
25
  'gemini-cli': 'gemini',
26
26
  };
27
27
  /**
@@ -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,CAiK5C"}
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,CA8J5C"}
@@ -46,12 +46,9 @@ 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).
50
49
  const sortedRepoEntries = [...repoMap.entries()].sort((a, b) => {
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;
50
+ const aTime = a[1].data.createdAt ?? 0;
51
+ const bTime = b[1].data.createdAt ?? 0;
55
52
  return aTime - bTime;
56
53
  });
57
54
  for (const [nodeId, entry] of sortedRepoEntries) {