@shepai/cli 1.106.4-pr326.f9b6ed2 → 1.106.4-pr328.6940924

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 (246) hide show
  1. package/dist/packages/core/src/application/use-cases/features/delete-feature.use-case.d.ts +1 -0
  2. package/dist/packages/core/src/application/use-cases/features/delete-feature.use-case.d.ts.map +1 -1
  3. package/dist/packages/core/src/application/use-cases/features/delete-feature.use-case.js +8 -3
  4. package/dist/src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/page.d.ts.map +1 -1
  5. package/dist/src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/page.js +48 -5
  6. package/dist/src/presentation/web/app/actions/delete-feature.d.ts +1 -1
  7. package/dist/src/presentation/web/app/actions/delete-feature.d.ts.map +1 -1
  8. package/dist/src/presentation/web/app/actions/delete-feature.js +8 -3
  9. package/dist/src/presentation/web/app/actions/get-graph-data.d.ts +10 -0
  10. package/dist/src/presentation/web/app/actions/get-graph-data.d.ts.map +1 -0
  11. package/dist/src/presentation/web/app/actions/get-graph-data.js +10 -0
  12. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
  13. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +25 -9
  14. package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog-config.d.ts +2 -1
  15. package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog-config.d.ts.map +1 -1
  16. package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.d.ts +1 -1
  17. package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.d.ts.map +1 -1
  18. package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.js +4 -2
  19. package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.stories.d.ts +2 -0
  20. package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.stories.d.ts.map +1 -1
  21. package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.stories.js +11 -0
  22. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.d.ts.map +1 -1
  23. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.js +1 -3
  24. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +2 -1
  25. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +1 -1
  26. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  27. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +3 -3
  28. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +1 -1
  29. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  30. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +15 -16
  31. package/dist/src/presentation/web/hooks/use-graph-state.d.ts.map +1 -1
  32. package/dist/src/presentation/web/hooks/use-graph-state.js +0 -26
  33. package/dist/src/presentation/web/hooks/use-sound.d.ts.map +1 -1
  34. package/dist/src/presentation/web/hooks/use-sound.js +3 -13
  35. package/dist/src/presentation/web/lib/derive-graph.d.ts +1 -1
  36. package/dist/src/presentation/web/lib/derive-graph.d.ts.map +1 -1
  37. package/dist/src/presentation/web/lib/derive-graph.js +13 -2
  38. package/dist/tsconfig.build.tsbuildinfo +1 -1
  39. package/package.json +1 -1
  40. package/web/.next/BUILD_ID +1 -1
  41. package/web/.next/app-path-routes-manifest.json +0 -1
  42. package/web/.next/build-manifest.json +2 -2
  43. package/web/.next/fallback-build-manifest.json +2 -2
  44. package/web/.next/prerender-manifest.json +3 -3
  45. package/web/.next/required-server-files.js +1 -1
  46. package/web/.next/required-server-files.json +1 -1
  47. package/web/.next/routes-manifest.json +0 -6
  48. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +53 -38
  49. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +3 -3
  50. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  51. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  52. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +63 -63
  53. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +4 -4
  54. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  55. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  56. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +63 -63
  57. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +4 -4
  58. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  59. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  60. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +49 -34
  61. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +3 -3
  62. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  63. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  64. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +53 -38
  65. package/web/.next/server/app/(dashboard)/create/page.js +3 -3
  66. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  67. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  68. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +63 -63
  69. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +4 -4
  70. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  71. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  72. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +63 -63
  73. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +4 -4
  74. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  75. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  76. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +49 -34
  77. package/web/.next/server/app/(dashboard)/page.js +3 -3
  78. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  79. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  80. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +49 -34
  81. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +3 -3
  82. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  83. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  84. package/web/.next/server/app/_global-error.html +2 -2
  85. package/web/.next/server/app/_global-error.rsc +1 -1
  86. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  87. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  88. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  89. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  90. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  91. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  92. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  93. package/web/.next/server/app/api/agent-events/route.js +2 -1
  94. package/web/.next/server/app/api/agent-events/route.js.nft.json +1 -1
  95. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  96. package/web/.next/server/app/api/attachments/upload-from-path/route.js +1 -1
  97. package/web/.next/server/app/api/attachments/upload-from-path/route.js.nft.json +1 -1
  98. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  99. package/web/.next/server/app/api/feature-logs/route.js +1 -1
  100. package/web/.next/server/app/api/feature-logs/route.js.nft.json +1 -1
  101. package/web/.next/server/app/settings/page/server-reference-manifest.json +5 -5
  102. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  103. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  104. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  105. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  106. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  107. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  108. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  109. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  110. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  111. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  112. package/web/.next/server/app-paths-manifest.json +0 -1
  113. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js +6 -0
  114. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js.map +1 -0
  115. package/web/.next/server/chunks/[root-of-the-server]__3b22a1eb._.js +3 -0
  116. package/web/.next/server/chunks/[root-of-the-server]__3b22a1eb._.js.map +1 -0
  117. package/web/.next/server/chunks/{[root-of-the-server]__d8037e14._.js → [root-of-the-server]__91d44424._.js} +2 -2
  118. package/web/.next/server/chunks/{[root-of-the-server]__a5879003._.js → [root-of-the-server]__db04ed44._.js} +2 -2
  119. package/web/.next/server/chunks/[root-of-the-server]__f47bb8a5._.js +1 -1
  120. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  121. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  122. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_0a7546ed.js +3 -0
  123. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_0a7546ed.js.map +1 -0
  124. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_978cbb4c.js +3 -0
  125. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_978cbb4c.js.map +1 -0
  126. package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js +1 -1
  127. package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js.map +1 -1
  128. package/web/.next/server/chunks/ssr/[root-of-the-server]__24dd0927._.js +2 -2
  129. package/web/.next/server/chunks/ssr/[root-of-the-server]__24dd0927._.js.map +1 -1
  130. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  131. package/web/.next/server/chunks/ssr/[root-of-the-server]__51fc98b0._.js +3 -0
  132. package/web/.next/server/chunks/ssr/[root-of-the-server]__51fc98b0._.js.map +1 -0
  133. package/web/.next/server/chunks/ssr/[root-of-the-server]__57f37786._.js +3 -0
  134. package/web/.next/server/chunks/ssr/[root-of-the-server]__57f37786._.js.map +1 -0
  135. package/web/.next/server/chunks/ssr/[root-of-the-server]__5d87af2e._.js +1 -1
  136. package/web/.next/server/chunks/ssr/[root-of-the-server]__708dcad1._.js +3 -0
  137. package/web/.next/server/chunks/ssr/[root-of-the-server]__708dcad1._.js.map +1 -0
  138. package/web/.next/server/chunks/ssr/[root-of-the-server]__845a9d2a._.js +1 -1
  139. package/web/.next/server/chunks/ssr/[root-of-the-server]__845a9d2a._.js.map +1 -1
  140. package/web/.next/server/chunks/ssr/[root-of-the-server]__89e8a5cc._.js +2 -2
  141. package/web/.next/server/chunks/ssr/[root-of-the-server]__8e002910._.js +3 -0
  142. package/web/.next/server/chunks/ssr/[root-of-the-server]__8e002910._.js.map +1 -0
  143. package/web/.next/server/chunks/ssr/[root-of-the-server]__94128fa9._.js +3 -0
  144. package/web/.next/server/chunks/ssr/[root-of-the-server]__94128fa9._.js.map +1 -0
  145. package/web/.next/server/chunks/ssr/[root-of-the-server]__9bfb8e7c._.js +3 -0
  146. package/web/.next/server/chunks/ssr/[root-of-the-server]__9bfb8e7c._.js.map +1 -0
  147. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +2 -2
  148. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
  149. package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js +1 -1
  150. package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js.map +1 -1
  151. package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
  152. package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
  153. package/web/.next/server/chunks/ssr/{_250a63ae._.js → _6e08ce21._.js} +2 -2
  154. package/web/.next/server/chunks/ssr/_6e08ce21._.js.map +1 -0
  155. package/web/.next/server/chunks/ssr/_8dacd1e7._.js +1 -1
  156. package/web/.next/server/chunks/ssr/_8dacd1e7._.js.map +1 -1
  157. package/web/.next/server/chunks/ssr/{_63920708._.js → _c567d3d1._.js} +2 -2
  158. package/web/.next/server/chunks/ssr/{_63920708._.js.map → _c567d3d1._.js.map} +1 -1
  159. package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
  160. package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
  161. package/web/.next/server/chunks/ssr/{_f479e2e8._.js → _cd8c246a._.js} +2 -2
  162. package/web/.next/server/chunks/ssr/{_f479e2e8._.js.map → _cd8c246a._.js.map} +1 -1
  163. package/web/.next/server/chunks/ssr/_e6f2da4f._.js.map +1 -1
  164. package/web/.next/server/chunks/ssr/{_4dbfa2c4._.js → _f2fff47b._.js} +2 -2
  165. package/web/.next/server/chunks/ssr/{_4dbfa2c4._.js.map → _f2fff47b._.js.map} +1 -1
  166. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  167. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  168. package/web/.next/server/chunks/ssr/{src_presentation_web_d7392251._.js → src_presentation_web_7275ce5d._.js} +3 -3
  169. package/web/.next/server/chunks/ssr/{src_presentation_web_9f444130._.js.map → src_presentation_web_7275ce5d._.js.map} +1 -1
  170. package/web/.next/server/chunks/ssr/{src_presentation_web_9f444130._.js → src_presentation_web_758dfa10._.js} +3 -3
  171. package/web/.next/server/chunks/ssr/{src_presentation_web_d7392251._.js.map → src_presentation_web_758dfa10._.js.map} +1 -1
  172. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_84803221.js +3 -0
  173. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_84803221.js.map +1 -0
  174. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
  175. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
  176. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
  177. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
  178. package/web/.next/server/chunks/ssr/src_presentation_web_app_(dashboard)_get-graph-data_ts_b018483e._.js +3 -0
  179. package/web/.next/server/chunks/ssr/src_presentation_web_app_(dashboard)_get-graph-data_ts_b018483e._.js.map +1 -0
  180. package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
  181. package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
  182. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  183. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  184. package/web/.next/server/pages/500.html +2 -2
  185. package/web/.next/server/server-reference-manifest.js +1 -1
  186. package/web/.next/server/server-reference-manifest.json +285 -250
  187. package/web/.next/static/chunks/{1efd560424f964bc.js → 1d8896de64e3ba4b.js} +1 -1
  188. package/web/.next/static/chunks/{47cb562cdfd658ee.js → 3871eeb13727c993.js} +1 -1
  189. package/web/.next/static/chunks/{01ba9af84561f1de.js → 43c5590ddd63c65a.js} +1 -1
  190. package/web/.next/static/chunks/{ec3c3274f43409e6.js → 5f08c6959431965a.js} +2 -2
  191. package/web/.next/static/chunks/{d001c315a91fa0d6.js → 73058878c9a649aa.js} +1 -1
  192. package/web/.next/static/chunks/{99ae01f6487799a3.js → 8ba5b2c15350b397.js} +2 -2
  193. package/web/.next/static/chunks/{7974892204cb77af.js → a7901df8d0187123.js} +1 -1
  194. package/web/.next/static/chunks/{1bcb9cea556264be.js → beb9f1a26ce08e6f.js} +1 -1
  195. package/web/.next/static/chunks/{bef25e3de3ccc184.js → dddf5099be94613c.js} +1 -1
  196. package/web/.next/static/chunks/{a2a134272e350be8.js → f3e7e637fa3cfefe.js} +2 -2
  197. package/dist/src/presentation/web/app/actions/get-feature-drawer-data.d.ts +0 -8
  198. package/dist/src/presentation/web/app/actions/get-feature-drawer-data.d.ts.map +0 -1
  199. package/dist/src/presentation/web/app/actions/get-feature-drawer-data.js +0 -67
  200. package/dist/src/presentation/web/app/api/graph-data/route.d.ts +0 -14
  201. package/dist/src/presentation/web/app/api/graph-data/route.d.ts.map +0 -1
  202. package/dist/src/presentation/web/app/api/graph-data/route.js +0 -14
  203. package/dist/src/presentation/web/components/common/control-center-drawer/use-drawer-sync.d.ts +0 -12
  204. package/dist/src/presentation/web/components/common/control-center-drawer/use-drawer-sync.d.ts.map +0 -1
  205. package/dist/src/presentation/web/components/common/control-center-drawer/use-drawer-sync.js +0 -75
  206. package/web/.next/server/app/api/graph-data/route/app-paths-manifest.json +0 -3
  207. package/web/.next/server/app/api/graph-data/route/build-manifest.json +0 -11
  208. package/web/.next/server/app/api/graph-data/route/server-reference-manifest.json +0 -4
  209. package/web/.next/server/app/api/graph-data/route.js +0 -8
  210. package/web/.next/server/app/api/graph-data/route.js.map +0 -5
  211. package/web/.next/server/app/api/graph-data/route.js.nft.json +0 -1
  212. package/web/.next/server/app/api/graph-data/route_client-reference-manifest.js +0 -2
  213. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +0 -3
  214. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +0 -1
  215. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_graph-data_route_actions_26df8a4e.js +0 -3
  216. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_graph-data_route_actions_26df8a4e.js.map +0 -1
  217. package/web/.next/server/chunks/[root-of-the-server]__7d5492a0._.js +0 -3
  218. package/web/.next/server/chunks/[root-of-the-server]__7d5492a0._.js.map +0 -1
  219. package/web/.next/server/chunks/[root-of-the-server]__aae14de3._.js +0 -6
  220. package/web/.next/server/chunks/[root-of-the-server]__aae14de3._.js.map +0 -1
  221. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_7fc19e0a.js +0 -3
  222. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_7fc19e0a.js.map +0 -1
  223. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_c3aca900.js +0 -3
  224. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_c3aca900.js.map +0 -1
  225. package/web/.next/server/chunks/ssr/[root-of-the-server]__13dc8e37._.js +0 -3
  226. package/web/.next/server/chunks/ssr/[root-of-the-server]__13dc8e37._.js.map +0 -1
  227. package/web/.next/server/chunks/ssr/[root-of-the-server]__3a2d3067._.js +0 -3
  228. package/web/.next/server/chunks/ssr/[root-of-the-server]__3a2d3067._.js.map +0 -1
  229. package/web/.next/server/chunks/ssr/[root-of-the-server]__5f776c10._.js +0 -3
  230. package/web/.next/server/chunks/ssr/[root-of-the-server]__5f776c10._.js.map +0 -1
  231. package/web/.next/server/chunks/ssr/[root-of-the-server]__684a868c._.js +0 -3
  232. package/web/.next/server/chunks/ssr/[root-of-the-server]__684a868c._.js.map +0 -1
  233. package/web/.next/server/chunks/ssr/[root-of-the-server]__c03a4370._.js +0 -3
  234. package/web/.next/server/chunks/ssr/[root-of-the-server]__c03a4370._.js.map +0 -1
  235. package/web/.next/server/chunks/ssr/[root-of-the-server]__c16bf5de._.js +0 -3
  236. package/web/.next/server/chunks/ssr/[root-of-the-server]__c16bf5de._.js.map +0 -1
  237. package/web/.next/server/chunks/ssr/_250a63ae._.js.map +0 -1
  238. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_85d37ebe.js +0 -3
  239. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_85d37ebe.js.map +0 -1
  240. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +0 -3
  241. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +0 -1
  242. /package/web/.next/server/chunks/{[root-of-the-server]__d8037e14._.js.map → [root-of-the-server]__91d44424._.js.map} +0 -0
  243. /package/web/.next/server/chunks/{[root-of-the-server]__a5879003._.js.map → [root-of-the-server]__db04ed44._.js.map} +0 -0
  244. /package/web/.next/static/{AKX-fGrJ4g-AmQgp32F2N → vM_hX6beWPwd9pbv9Quhc}/_buildManifest.js +0 -0
  245. /package/web/.next/static/{AKX-fGrJ4g-AmQgp32F2N → vM_hX6beWPwd9pbv9Quhc}/_clientMiddlewareManifest.json +0 -0
  246. /package/web/.next/static/{AKX-fGrJ4g-AmQgp32F2N → vM_hX6beWPwd9pbv9Quhc}/_ssgManifest.js +0 -0
@@ -20,6 +20,7 @@ import type { IAgentRunRepository } from '../../ports/output/agents/agent-run-re
20
20
  import type { IGitPrService } from '../../ports/output/services/git-pr-service.interface.js';
21
21
  export interface DeleteFeatureOptions {
22
22
  cleanup?: boolean;
23
+ cascadeDelete?: boolean;
23
24
  }
24
25
  export declare class DeleteFeatureUseCase {
25
26
  private readonly featureRepo;
@@ -1 +1 @@
1
- {"version":3,"file":"delete-feature.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/delete-feature.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;AAEnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAC1G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2DAA2D,CAAC;AAClG,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8DAA8D,CAAC;AAChH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6DAA6D,CAAC;AACvG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yDAAyD,CAAC;AAE7F,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qBACa,oBAAoB;IAEC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAE5D,OAAO,CAAC,QAAQ,CAAC,cAAc;IACA,OAAO,CAAC,QAAQ,CAAC,OAAO;IAC9B,OAAO,CAAC,QAAQ,CAAC,YAAY;gBALP,WAAW,EAAE,kBAAkB,EACjC,eAAe,EAAE,gBAAgB,EAE7D,cAAc,EAAE,2BAA2B,EACZ,OAAO,EAAE,mBAAmB,EAClC,YAAY,EAAE,aAAa;IAGjE,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC;IAqBlF,0DAA0D;YAC5C,iBAAiB;IAQ/B,6DAA6D;YAC/C,yBAAyB;IAWvC,sDAAsD;YACxC,sBAAsB;IAYpC,6EAA6E;YAC/D,oBAAoB;CAsDnC"}
1
+ {"version":3,"file":"delete-feature.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/delete-feature.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;AAEnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAC1G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2DAA2D,CAAC;AAClG,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8DAA8D,CAAC;AAChH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6DAA6D,CAAC;AACvG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yDAAyD,CAAC;AAE7F,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,qBACa,oBAAoB;IAEC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAE5D,OAAO,CAAC,QAAQ,CAAC,cAAc;IACA,OAAO,CAAC,QAAQ,CAAC,OAAO;IAC9B,OAAO,CAAC,QAAQ,CAAC,YAAY;gBALP,WAAW,EAAE,kBAAkB,EACjC,eAAe,EAAE,gBAAgB,EAE7D,cAAc,EAAE,2BAA2B,EACZ,OAAO,EAAE,mBAAmB,EAClC,YAAY,EAAE,aAAa;IAGjE,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC;IA2BlF,0DAA0D;YAC5C,iBAAiB;IAQ/B,6DAA6D;YAC/C,yBAAyB;IAWvC,sDAAsD;YACxC,sBAAsB;IAYpC,6EAA6E;YAC/D,oBAAoB;CAsDnC"}
@@ -46,12 +46,17 @@ let DeleteFeatureUseCase = class DeleteFeatureUseCase {
46
46
  if (!feature) {
47
47
  throw new Error(`Feature not found: "${featureId}"`);
48
48
  }
49
- // 2. Immediately soft-delete the feature and all children
49
+ const cascadeDelete = options?.cascadeDelete !== false;
50
+ // 2. Immediately soft-delete the feature (and children if cascading)
50
51
  // This makes them vanish from all queries right away (no reappear bug)
51
- await this.cascadeSoftDelete(feature.id);
52
+ if (cascadeDelete) {
53
+ await this.cascadeSoftDelete(feature.id);
54
+ }
52
55
  await this.markDeletingAndSoftDelete(feature);
53
56
  // 3. Then perform cleanup (best-effort, feature is already hidden)
54
- await this.cascadeCleanupChildren(feature.id, options);
57
+ if (cascadeDelete) {
58
+ await this.cascadeCleanupChildren(feature.id, options);
59
+ }
55
60
  await this.cleanupSingleFeature(feature, options);
56
61
  return feature;
57
62
  }
@@ -1 +1 @@
1
- {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/page.tsx"],"names":[],"mappings":"AAOA,oEAAoE;AACpE,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,UAAU,sBAAsB;IAC9B,MAAM,EAAE,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxC;AAED,wBAA8B,iBAAiB,CAAC,EAAE,MAAM,EAAE,EAAE,sBAAsB,2DAmCjF"}
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/page.tsx"],"names":[],"mappings":"AAiBA,oEAAoE;AACpE,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,UAAU,sBAAsB;IAC9B,MAAM,EAAE,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxC;AAED,wBAA8B,iBAAiB,CAAC,EAAE,MAAM,EAAE,EAAE,sBAAsB,2DAyEjF"}
@@ -1,8 +1,14 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { resolve } from '../../../../../lib/server-container.js';
3
+ import { CiStatus } from '../../../../../../../../packages/core/src/domain/generated/output.js';
3
4
  import { buildFeatureNodeData } from '../../../../build-feature-node-data.js';
4
5
  import { computeDrawerView } from '../../../../../components/common/control-center-drawer/drawer-view.js';
5
6
  import { FeatureDrawerClient } from '../../../../../components/common/control-center-drawer/feature-drawer-client.js';
7
+ const CI_STATUS_MAP = {
8
+ success: CiStatus.Success,
9
+ failure: CiStatus.Failure,
10
+ pending: CiStatus.Pending,
11
+ };
6
12
  /** Skip static pre-rendering since we need runtime DI container. */
7
13
  export const dynamic = 'force-dynamic';
8
14
  export default async function FeatureDrawerPage({ params }) {
@@ -10,15 +16,52 @@ export default async function FeatureDrawerPage({ params }) {
10
16
  try {
11
17
  const featureRepo = resolve('IFeatureRepository');
12
18
  const agentRunRepo = resolve('IAgentRunRepository');
13
- // Critical path only: feature + agent run (fast DB lookups).
14
- // Expensive operations (git remote URL, GitHub CI/mergeable status,
15
- // artifact, repo name, base branch) are deferred to useDrawerSync
16
- // which runs client-side after the drawer is already visible.
19
+ const repoRepo = resolve('IRepositoryRepository');
20
+ const gitPrService = resolve('IGitPrService');
17
21
  const feature = await featureRepo.findById(featureId);
18
22
  if (!feature)
19
23
  return null;
20
24
  const run = feature.agentRunId ? await agentRunRepo.findById(feature.agentRunId) : null;
21
- const nodeData = buildFeatureNodeData(feature, run);
25
+ // Resolve repository name, base branch, and one-liner for the overview tab
26
+ const getArtifact = resolve('GetFeatureArtifactUseCase');
27
+ const [repo, baseBranch, artifact, remoteUrl, liveMergeable, liveCiResult] = await Promise.all([
28
+ repoRepo.findByPath(feature.repositoryPath).catch(() => null),
29
+ gitPrService.getDefaultBranch(feature.repositoryPath).catch(() => 'main'),
30
+ getArtifact.execute(featureId).catch(() => null),
31
+ gitPrService.getRemoteUrl(feature.repositoryPath).catch(() => null),
32
+ feature.pr?.number
33
+ ? gitPrService
34
+ .getMergeableStatus(feature.repositoryPath, feature.pr.number)
35
+ .catch(() => undefined)
36
+ : Promise.resolve(undefined),
37
+ feature.branch
38
+ ? gitPrService.getCiStatus(feature.repositoryPath, feature.branch).catch(() => undefined)
39
+ : Promise.resolve(undefined),
40
+ ]);
41
+ // Merge live PR status into feature data so the UI always reflects
42
+ // the current GitHub state, even if the background watcher hasn't polled yet.
43
+ if (feature.pr) {
44
+ const liveCiStatus = liveCiResult
45
+ ? (CI_STATUS_MAP[liveCiResult.status] ?? CiStatus.Pending)
46
+ : undefined;
47
+ const updates = {};
48
+ if (liveMergeable !== undefined)
49
+ updates.mergeable = liveMergeable;
50
+ if (liveCiStatus !== undefined)
51
+ updates.ciStatus = liveCiStatus;
52
+ if (Object.keys(updates).length > 0) {
53
+ feature.pr = { ...feature.pr, ...updates };
54
+ featureRepo.update(feature).catch(() => {
55
+ /* best-effort persist */
56
+ });
57
+ }
58
+ }
59
+ const nodeData = buildFeatureNodeData(feature, run, {
60
+ repositoryName: repo?.name,
61
+ baseBranch,
62
+ oneLiner: artifact?.oneLiner,
63
+ remoteUrl: remoteUrl ?? undefined,
64
+ });
22
65
  const view = computeDrawerView({
23
66
  selectedNode: nodeData,
24
67
  isCreateDrawerOpen: false,
@@ -1,5 +1,5 @@
1
1
  import type { Feature } from '../../../../../packages/core/src/domain/generated/output.js';
2
- export declare function deleteFeature(featureId: string, cleanup?: boolean): Promise<{
2
+ export declare function deleteFeature(featureId: string, cleanup?: boolean, cascadeDelete?: boolean): Promise<{
3
3
  feature?: Feature;
4
4
  error?: string;
5
5
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"delete-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/delete-feature.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAC;AAEpE,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAAC;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAgBhD"}
1
+ {"version":3,"file":"delete-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/delete-feature.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAC;AAEpE,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,OAAO,GACtB,OAAO,CAAC;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAmBhD"}
@@ -1,13 +1,18 @@
1
1
  'use server';
2
2
  import { resolve } from '../../lib/server-container.js';
3
- export async function deleteFeature(featureId, cleanup) {
3
+ export async function deleteFeature(featureId, cleanup, cascadeDelete) {
4
4
  if (!featureId?.trim()) {
5
5
  return { error: 'id is required' };
6
6
  }
7
7
  try {
8
8
  const deleteFeatureUseCase = resolve('DeleteFeatureUseCase');
9
- const feature = cleanup !== undefined
10
- ? await deleteFeatureUseCase.execute(featureId, { cleanup })
9
+ const options = {};
10
+ if (cleanup !== undefined)
11
+ options.cleanup = cleanup;
12
+ if (cascadeDelete !== undefined)
13
+ options.cascadeDelete = cascadeDelete;
14
+ const feature = Object.keys(options).length > 0
15
+ ? await deleteFeatureUseCase.execute(featureId, options)
11
16
  : await deleteFeatureUseCase.execute(featureId);
12
17
  return { feature };
13
18
  }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Server action that fetches fresh graph nodes and edges.
3
+ * Used as a lightweight polling fallback for active features,
4
+ * avoiding full router.refresh() page re-renders.
5
+ */
6
+ export declare function fetchGraphData(): Promise<{
7
+ nodes: import("../../components/features/features-canvas/index.js").CanvasNodeType[];
8
+ edges: import("@xyflow/react").Edge[];
9
+ }>;
10
+ //# sourceMappingURL=get-graph-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-graph-data.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/get-graph-data.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAsB,cAAc;;;GAEnC"}
@@ -0,0 +1,10 @@
1
+ 'use server';
2
+ import { getGraphData } from '../(dashboard)/get-graph-data.js';
3
+ /**
4
+ * Server action that fetches fresh graph nodes and edges.
5
+ * Used as a lightweight polling fallback for active features,
6
+ * avoiding full router.refresh() page re-renders.
7
+ */
8
+ export async function fetchGraphData() {
9
+ return getGraphData();
10
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"feature-drawer-client.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAI/D,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,UAAU,CAAC;IACjB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,wBAAgB,mBAAmB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,wBAAwB,2CA0hB1F"}
1
+ {"version":3,"file":"feature-drawer-client.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG/D,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,UAAU,CAAC;IACjB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,wBAAgB,mBAAmB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,wBAAwB,2CA6iB1F"}
@@ -28,7 +28,6 @@ import { useFeatureActions } from '../../common/feature-drawer/use-feature-actio
28
28
  import { resolveSseEventUpdates } from '../../common/feature-node/derive-feature-state.js';
29
29
  import { deriveInitialTab } from './drawer-view.js';
30
30
  import { useArtifactFetch } from './use-artifact-fetch.js';
31
- import { useDrawerSync } from './use-drawer-sync.js';
32
31
  export function FeatureDrawerClient({ view: initialView, urlTab }) {
33
32
  const featureFlags = useFeatureFlags();
34
33
  const router = useRouter();
@@ -36,7 +35,7 @@ export function FeatureDrawerClient({ view: initialView, urlTab }) {
36
35
  const rejectSound = useSoundAction('reject');
37
36
  // Track the view locally so SSE events can update the drawer type in real-time
38
37
  const [view, setView] = useState(initialView);
39
- // Sync when server re-renders with new props (e.g. after navigation)
38
+ // Sync when server re-renders with new props (e.g. after router.refresh())
40
39
  useEffect(() => {
41
40
  setView(initialView);
42
41
  }, [initialView]);
@@ -61,9 +60,15 @@ export function FeatureDrawerClient({ view: initialView, urlTab }) {
61
60
  // fetches (which would fail with "not found" for soft-deleted features).
62
61
  if (featureNode.state === 'deleting')
63
62
  continue;
63
+ // Trigger a server refresh to get the latest drawer view,
64
+ // but skip when the drawer is closed, the user has unsaved changes,
65
+ // or a rejection is in-flight to avoid unnecessary refreshes.
66
+ if (isOpenRef.current && !isDirtyRef.current && !isRejectingRef.current)
67
+ router.refresh();
64
68
  if (update.state !== undefined || update.lifecycle !== undefined) {
65
- // Update the node data AND re-derive the initial tab so the drawer
66
- // switches immediately (e.g. prd-review → overview when agent resumes).
69
+ // Optimistically update the node data AND re-derive the initial tab so the
70
+ // drawer switches immediately (e.g. prd-review → overview when agent resumes)
71
+ // without waiting for the router.refresh() round-trip.
67
72
  setView((prev) => {
68
73
  if (prev.type !== 'feature')
69
74
  return prev;
@@ -76,17 +81,24 @@ export function FeatureDrawerClient({ view: initialView, urlTab }) {
76
81
  });
77
82
  }
78
83
  }
79
- }, [events, featureNode]);
84
+ }, [events, featureNode, router]);
80
85
  // Derive open state from the URL. Next.js parallel routes preserve slot
81
86
  // content during soft navigation, so this component is NOT unmounted when
82
87
  // navigating to `/`. Instead, we watch the pathname and let Vaul handle
83
88
  // the close animation when the path no longer matches a feature route.
84
89
  const pathname = usePathname();
85
90
  const isOpen = pathname.startsWith('/feature/');
86
- // Targeted data sync: fetches fresh FeatureNodeData on drawer open and
87
- // periodically while open. Replaces router.refresh() to avoid full-page
88
- // re-renders that cause visible flashing and can reset form state.
89
- useDrawerSync(isOpen, featureNode?.featureId ?? null, setView);
91
+ const isOpenRef = useRef(isOpen);
92
+ const wasOpenRef = useRef(isOpen);
93
+ // When the drawer re-opens, force a server refresh so the view is always fresh.
94
+ // SSE skips router.refresh() while the drawer is closed, so data can go stale.
95
+ useEffect(() => {
96
+ if (isOpen && !wasOpenRef.current) {
97
+ router.refresh();
98
+ }
99
+ wasOpenRef.current = isOpen;
100
+ }, [isOpen, router]);
101
+ isOpenRef.current = isOpen;
90
102
  const onClose = useCallback(() => {
91
103
  router.push('/');
92
104
  }, [router]);
@@ -170,6 +182,10 @@ export function FeatureDrawerClient({ view: initialView, urlTab }) {
170
182
  featureNode?.state === 'action-required' &&
171
183
  Object.keys(prdDefaultSelections).some((k) => prdDefaultSelections[k] !== prdSelections[k]);
172
184
  const isDirty = isChatDirty || isPrdDirty;
185
+ // Keep dirty state in a ref so the SSE handler can read the latest value
186
+ // without re-running the effect on every keystroke.
187
+ const isDirtyRef = useRef(isDirty);
188
+ isDirtyRef.current = isDirty;
173
189
  const onReset = useCallback(() => {
174
190
  setChatInput('');
175
191
  setPrdSelections({ ...prdDefaultSelections });
@@ -1,9 +1,10 @@
1
1
  export interface DeleteFeatureDialogProps {
2
2
  open: boolean;
3
3
  onOpenChange: (open: boolean) => void;
4
- onConfirm: (cleanup: boolean) => void;
4
+ onConfirm: (cleanup: boolean, cascadeDelete: boolean) => void;
5
5
  isDeleting: boolean;
6
6
  featureName: string;
7
7
  featureId: string;
8
+ hasChildren?: boolean;
8
9
  }
9
10
  //# sourceMappingURL=delete-feature-dialog-config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"delete-feature-dialog-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog-config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB"}
1
+ {"version":3,"file":"delete-feature-dialog-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog-config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9D,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB"}
@@ -1,3 +1,3 @@
1
1
  import type { DeleteFeatureDialogProps } from './delete-feature-dialog-config.js';
2
- export declare function DeleteFeatureDialog({ open, onOpenChange, onConfirm, isDeleting, featureName, featureId, }: DeleteFeatureDialogProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function DeleteFeatureDialog({ open, onOpenChange, onConfirm, isDeleting, featureName, featureId, hasChildren, }: DeleteFeatureDialogProps): import("react/jsx-runtime").JSX.Element;
3
3
  //# sourceMappingURL=delete-feature-dialog.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"delete-feature-dialog.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAE/E,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,YAAY,EACZ,SAAS,EACT,UAAU,EACV,WAAW,EACX,SAAS,GACV,EAAE,wBAAwB,2CAqD1B"}
1
+ {"version":3,"file":"delete-feature-dialog.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAE/E,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,YAAY,EACZ,SAAS,EACT,UAAU,EACV,WAAW,EACX,SAAS,EACT,WAAW,GACZ,EAAE,wBAAwB,2CAuE1B"}
@@ -5,12 +5,14 @@ import { Loader2 } from 'lucide-react';
5
5
  import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '../../ui/alert-dialog.js';
6
6
  import { Checkbox } from '../../ui/checkbox.js';
7
7
  import { Label } from '../../ui/label.js';
8
- export function DeleteFeatureDialog({ open, onOpenChange, onConfirm, isDeleting, featureName, featureId, }) {
8
+ export function DeleteFeatureDialog({ open, onOpenChange, onConfirm, isDeleting, featureName, featureId, hasChildren, }) {
9
9
  const [cleanup, setCleanup] = useState(true);
10
+ const [cascadeDelete, setCascadeDelete] = useState(true);
10
11
  useEffect(() => {
11
12
  if (open) {
12
13
  setCleanup(true);
14
+ setCascadeDelete(true);
13
15
  }
14
16
  }, [open]);
15
- return (_jsx(AlertDialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(AlertDialogContent, { onCloseAutoFocus: (e) => e.preventDefault(), children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Delete feature?" }), _jsxs(AlertDialogDescription, { children: ["This will permanently delete ", _jsx("strong", { children: featureName }), " (", featureId, "). This action cannot be undone."] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "cleanup-checkbox", checked: cleanup, onCheckedChange: (checked) => setCleanup(checked === true), disabled: isDeleting, "aria-label": "Clean up worktree and branches" }), _jsx(Label, { htmlFor: "cleanup-checkbox", className: "cursor-pointer text-sm", children: "Clean up worktree and branches" })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: isDeleting, onClick: () => onOpenChange(false), children: "Cancel" }), _jsx(AlertDialogAction, { variant: "destructive", disabled: isDeleting, onClick: () => onConfirm(cleanup), children: isDeleting ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Deleting\u2026"] })) : ('Delete') })] })] }) }));
17
+ return (_jsx(AlertDialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(AlertDialogContent, { onCloseAutoFocus: (e) => e.preventDefault(), children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Delete feature?" }), _jsxs(AlertDialogDescription, { children: ["This will permanently delete ", _jsx("strong", { children: featureName }), " (", featureId, "). This action cannot be undone."] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [hasChildren ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "cascade-delete-checkbox", checked: cascadeDelete, onCheckedChange: (checked) => setCascadeDelete(checked === true), disabled: isDeleting, "aria-label": "Also delete sub-features" }), _jsx(Label, { htmlFor: "cascade-delete-checkbox", className: "cursor-pointer text-sm", children: "Also delete sub-features" })] })) : null, _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "cleanup-checkbox", checked: cleanup, onCheckedChange: (checked) => setCleanup(checked === true), disabled: isDeleting, "aria-label": "Clean up worktree and branches" }), _jsx(Label, { htmlFor: "cleanup-checkbox", className: "cursor-pointer text-sm", children: "Clean up worktree and branches" })] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: isDeleting, onClick: () => onOpenChange(false), children: "Cancel" }), _jsx(AlertDialogAction, { variant: "destructive", disabled: isDeleting, onClick: () => onConfirm(cleanup, cascadeDelete), children: isDeleting ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Deleting\u2026"] })) : ('Delete') })] })] }) }));
16
18
  }
@@ -4,5 +4,7 @@ declare const meta: Meta<typeof DeleteFeatureDialog>;
4
4
  export default meta;
5
5
  type Story = StoryObj<typeof DeleteFeatureDialog>;
6
6
  export declare const Default: Story;
7
+ export declare const WithChildren: Story;
7
8
  export declare const Deleting: Story;
9
+ export declare const DeletingWithChildren: Story;
8
10
  //# sourceMappingURL=delete-feature-dialog.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"delete-feature-dialog.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,mBAAmB,CAe1C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAElD,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC;AAEjC,eAAO,MAAM,QAAQ,EAAE,KAItB,CAAC"}
1
+ {"version":3,"file":"delete-feature-dialog.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,mBAAmB,CAe1C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAElD,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC;AAEjC,eAAO,MAAM,YAAY,EAAE,KAI1B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAItB,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,KAKlC,CAAC"}
@@ -18,8 +18,19 @@ const meta = {
18
18
  };
19
19
  export default meta;
20
20
  export const Default = {};
21
+ export const WithChildren = {
22
+ args: {
23
+ hasChildren: true,
24
+ },
25
+ };
21
26
  export const Deleting = {
22
27
  args: {
23
28
  isDeleting: true,
24
29
  },
25
30
  };
31
+ export const DeletingWithChildren = {
32
+ args: {
33
+ isDeleting: true,
34
+ hasChildren: true,
35
+ },
36
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"feature-drawer-tabs.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAS9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACzF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,+CAA+C,CAAC;AACjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAMxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAQ9E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uDAAuD,CAAC;AAiD3F,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,eAAe,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,gFAAgF;IAChF,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,mFAAmF;IACnF,SAAS,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAGzC,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7D,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC1E,YAAY,CAAC,EAAE,OAAO,CAAC;IAGvB,QAAQ,CAAC,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC1C,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC3E,aAAa,CAAC,EAAE,OAAO,CAAC;IAGxB,WAAW,CAAC,EAAE,2BAA2B,GAAG,IAAI,CAAC;IAGjD,SAAS,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC5E,cAAc,CAAC,EAAE,OAAO,CAAC;IAGzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAwBD,wBAAgB,iBAAiB,CAAC,EAChC,WAAW,EACX,SAAS,EACT,UAAU,EACV,MAAM,EACN,OAAO,EACP,aAAa,EACb,WAAW,EACX,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,aAAa,EACb,WAAW,EACX,SAAS,EACT,cAAc,EACd,aAAa,EACb,cAAc,EACd,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,SAAS,GACV,EAAE,sBAAsB,2CA2TxB"}
1
+ {"version":3,"file":"feature-drawer-tabs.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAS9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACzF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,+CAA+C,CAAC;AACjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAMxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAQ9E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uDAAuD,CAAC;AAiD3F,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,eAAe,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,gFAAgF;IAChF,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,mFAAmF;IACnF,SAAS,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAGzC,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7D,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC1E,YAAY,CAAC,EAAE,OAAO,CAAC;IAGvB,QAAQ,CAAC,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC1C,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC3E,aAAa,CAAC,EAAE,OAAO,CAAC;IAGxB,WAAW,CAAC,EAAE,2BAA2B,GAAG,IAAI,CAAC;IAGjD,SAAS,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC5E,cAAc,CAAC,EAAE,OAAO,CAAC;IAGzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAwBD,wBAAgB,iBAAiB,CAAC,EAChC,WAAW,EACX,SAAS,EACT,UAAU,EACV,MAAM,EACN,OAAO,EACP,aAAa,EACb,WAAW,EACX,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,aAAa,EACb,WAAW,EACX,SAAS,EACT,cAAc,EACd,aAAa,EACb,cAAc,EACd,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,SAAS,GACV,EAAE,sBAAsB,2CAwTxB"}
@@ -66,6 +66,7 @@ const TAB_FETCHERS = {
66
66
  };
67
67
  export function FeatureDrawerTabs({ featureNode, featureId, initialTab, urlTab, prdData, prdSelections, onPrdSelect, onPrdApprove, onPrdReject, isPrdLoading, techData, onTechApprove, onTechReject, isTechLoading, productData, mergeData, onMergeApprove, onMergeReject, isMergeLoading, isRejecting, chatInput, onChatInputChange, sseEvents, }) {
68
68
  const pathname = usePathname();
69
+ const featureLogs = useFeatureLogs(featureId);
69
70
  const visibleTabs = useMemo(() => computeVisibleTabs(featureNode), [featureNode]);
70
71
  const visibleTabDefs = useMemo(() => ALL_TABS.filter((t) => visibleTabs.includes(t.key)), [visibleTabs]);
71
72
  // Derive the base path (without tab segment) from the current pathname.
@@ -85,9 +86,6 @@ export function FeatureDrawerTabs({ featureNode, featureId, initialTab, urlTab,
85
86
  // eslint-disable-next-line react-hooks/exhaustive-deps
86
87
  }, []);
87
88
  const [activeTab, setActiveTab] = useState(effectiveInitial);
88
- // Only subscribe to log SSE when the log tab is active to avoid
89
- // opening an EventSource connection on every drawer open.
90
- const featureLogs = useFeatureLogs(activeTab === 'log' ? featureId : null);
91
89
  const { tabs, fetchTab, refreshTab } = useTabDataFetch(featureId, TAB_FETCHERS);
92
90
  // Sync URL when active tab changes via user interaction.
93
91
  // Use window.history.pushState instead of router.push to avoid triggering a
@@ -66,7 +66,8 @@ export interface FeatureNodeData {
66
66
  };
67
67
  onAction?: () => void;
68
68
  onSettings?: () => void;
69
- onDelete?: (featureId: string, cleanup?: boolean) => void;
69
+ hasChildren?: boolean;
70
+ onDelete?: (featureId: string, cleanup?: boolean, cascadeDelete?: boolean) => void;
70
71
  showHandles?: boolean;
71
72
  }
72
73
  export type FeatureNodeType = Node<FeatureNodeData, 'featureNode'>;
@@ -1 +1 @@
1
- {"version":3,"file":"feature-node-state-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node-state-config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"feature-node-state-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node-state-config.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA0DnE,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,2CAoSA"}
1
+ {"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA0DnE,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,2CAqSA"}
@@ -70,10 +70,10 @@ export function FeatureNode({ data, selected, }) {
70
70
  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) => {
71
71
  e.stopPropagation();
72
72
  setConfirmOpen(true);
73
- }, 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) => {
73
+ }, 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) => {
74
74
  setConfirmOpen(false);
75
- data.onDelete?.(data.featureId, cleanup);
76
- }, isDeleting: false, featureName: data.name ?? 'this feature', featureId: data.featureId })] })) : null, _jsxs("div", { "data-testid": "feature-node-card", "aria-busy": data.state === 'creating' || data.state === 'deleting' ? 'true' : undefined, className: cn('bg-card flex min-h-35 w-72 cursor-pointer flex-col rounded-lg border p-3 shadow-sm', selected && 'ring-primary ring-2', data.state === 'deleting' && 'opacity-60'), children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { "data-testid": "feature-node-lifecycle-label", className: cn('text-[10px] font-semibold tracking-wider'), children: data.state === 'blocked' ? 'BLOCKED' : lifecycleDisplayLabels[data.lifecycle] }), _jsxs("div", { className: "flex items-center gap-0.5", children: [data.fastMode ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { "data-testid": "feature-node-fast-mode-badge", className: "-mt-1 p-1", children: _jsx(Zap, { className: "h-3.5 w-3.5 text-amber-500" }) }) }), _jsx(TooltipContent, { side: "bottom", children: "Fast Mode" })] }) })) : null, data.agentType ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": agentTypeLabels[data.agentType] ?? data.agentType, "data-testid": "feature-node-agent-badge", onClick: (e) => {
75
+ data.onDelete?.(data.featureId, cleanup, cascadeDelete);
76
+ }, isDeleting: false, featureName: data.name ?? 'this feature', featureId: data.featureId, hasChildren: data.hasChildren })] })) : null, _jsxs("div", { "data-testid": "feature-node-card", "aria-busy": data.state === 'creating' || data.state === 'deleting' ? 'true' : undefined, className: cn('bg-card flex min-h-35 w-72 cursor-pointer flex-col rounded-lg border p-3 shadow-sm', selected && 'ring-primary ring-2', data.state === 'deleting' && 'opacity-60'), children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { "data-testid": "feature-node-lifecycle-label", className: cn('text-[10px] font-semibold tracking-wider'), children: data.state === 'blocked' ? 'BLOCKED' : lifecycleDisplayLabels[data.lifecycle] }), _jsxs("div", { className: "flex items-center gap-0.5", children: [data.fastMode ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { "data-testid": "feature-node-fast-mode-badge", className: "-mt-1 p-1", children: _jsx(Zap, { className: "h-3.5 w-3.5 text-amber-500" }) }) }), _jsx(TooltipContent, { side: "bottom", children: "Fast Mode" })] }) })) : null, data.agentType ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": agentTypeLabels[data.agentType] ?? data.agentType, "data-testid": "feature-node-agent-badge", onClick: (e) => {
77
77
  e.stopPropagation();
78
78
  data.onSettings?.();
79
79
  }, className: cn('nodrag -mt-1 -mr-1 p-1', data.onSettings
@@ -14,7 +14,7 @@ export interface ControlCenterState {
14
14
  repoPath: string;
15
15
  };
16
16
  handleLayout: (direction: LayoutDirection) => void;
17
- handleDeleteFeature: (featureId: string, cleanup?: boolean) => void;
17
+ handleDeleteFeature: (featureId: string, cleanup?: boolean, cascadeDelete?: boolean) => void;
18
18
  handleDeleteRepository: (repositoryId: string) => Promise<void>;
19
19
  createFeatureNode: (sourceNodeId: string | null, dataOverride?: Partial<FeatureNodeData>, edgeType?: string) => string;
20
20
  /** Stable lookup: repositoryPath for a feature node. */
@@ -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;AAajC,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,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACpE,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,CAqapB"}
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;AAcjC,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,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7F,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,CAoapB"}
@@ -7,6 +7,7 @@ import { deleteFeature } from '../../../app/actions/delete-feature.js';
7
7
  import { addRepository } from '../../../app/actions/add-repository.js';
8
8
  import { deleteRepository } from '../../../app/actions/delete-repository.js';
9
9
  import { getFeatureMetadata } from '../../../app/actions/get-feature-metadata.js';
10
+ import { fetchGraphData } from '../../../app/actions/get-graph-data.js';
10
11
  import { useAgentEventsContext } from '../../../hooks/agent-events-provider.js';
11
12
  import { useSoundAction } from '../../../hooks/use-sound-action.js';
12
13
  import { createLogger } from '../../../lib/logger.js';
@@ -156,12 +157,7 @@ export function useControlCenterState(initialNodes, initialEdges) {
156
157
  log.debug(`polling enabled (${POLL_INTERVAL_MS}ms interval)`);
157
158
  const timer = setInterval(async () => {
158
159
  try {
159
- // Use a plain fetch instead of a server action so the poll
160
- // doesn't trigger the Next.js "Rendering…" indicator.
161
- const res = await fetch('/api/graph-data');
162
- if (!res.ok)
163
- throw new Error(`status ${res.status}`);
164
- const { nodes: freshNodes, edges: freshEdges } = await res.json();
160
+ const { nodes: freshNodes, edges: freshEdges } = await fetchGraphData();
165
161
  reconcile(freshNodes, freshEdges);
166
162
  }
167
163
  catch {
@@ -201,17 +197,20 @@ export function useControlCenterState(initialNodes, initialEdges) {
201
197
  addPendingFeature(id, newFeatureData, parentNodeId);
202
198
  return id;
203
199
  }, [addPendingFeature]);
204
- const handleDeleteFeature = useCallback((featureId, cleanup) => {
200
+ const handleDeleteFeature = useCallback((featureId, cleanup, cascadeDelete) => {
205
201
  const nodeId = `feat-${featureId}`;
202
+ const shouldCascade = cascadeDelete !== false;
206
203
  // Collect all descendant feature node IDs (children, grandchildren, etc.)
207
204
  const descendants = [];
208
- const queue = [nodeId];
209
- while (queue.length > 0) {
210
- const current = queue.shift();
211
- for (const edge of edgesRef.current) {
212
- if (edge.type === 'dependencyEdge' && edge.source === current) {
213
- descendants.push(edge.target);
214
- queue.push(edge.target);
205
+ if (shouldCascade) {
206
+ const queue = [nodeId];
207
+ while (queue.length > 0) {
208
+ const current = queue.shift();
209
+ for (const edge of edgesRef.current) {
210
+ if (edge.type === 'dependencyEdge' && edge.source === current) {
211
+ descendants.push(edge.target);
212
+ queue.push(edge.target);
213
+ }
215
214
  }
216
215
  }
217
216
  }
@@ -223,14 +222,14 @@ export function useControlCenterState(initialNodes, initialEdges) {
223
222
  prevStates.set(nid, node.data.state);
224
223
  }
225
224
  }
226
- // Optimistic: show "deleting" state on parent AND all descendants
225
+ // Optimistic: show "deleting" state on parent (and descendants if cascading)
227
226
  updateFeature(nodeId, { state: 'deleting' });
228
227
  for (const childId of descendants) {
229
228
  updateFeature(childId, { state: 'deleting' });
230
229
  }
231
230
  deleteSound.play();
232
231
  router.push('/');
233
- deleteFeature(featureId, cleanup)
232
+ deleteFeature(featureId, cleanup, cascadeDelete)
234
233
  .then((result) => {
235
234
  if (result.error) {
236
235
  // Rollback all to previous states
@@ -1 +1 @@
1
- {"version":3,"file":"use-graph-state.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-graph-state.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AACpD,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,OAAO,EAEL,KAAK,YAAY,EAEjB,KAAK,cAAc,EACpB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,mDAAmD;IACnD,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,mDAAmD;IACnD,KAAK,EAAE,IAAI,EAAE,CAAC;IACd;;;OAGG;IACH,SAAS,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IAClE,uEAAuE;IACvE,aAAa,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC5E,kEAAkE;IAClE,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1F,yDAAyD;IACzD,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,sDAAsD;IACtD,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,uDAAuD;IACvD,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAC9D,2DAA2D;IAC3D,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAClE,gCAAgC;IAChC,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,yDAAyD;IACzD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACtF,gEAAgE;IAChE,wBAAwB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACxE,yDAAyD;IACzD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,kBAAkB,GAAG,SAAS,CAAC;IACtE,+EAA+E;IAC/E,cAAc,EAAE,MAAM,MAAM,CAAC;IAC7B,6EAA6E;IAC7E,YAAY,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;CACnD;AAuCD,KAAK,kBAAkB,GAAG,OAAO,CAC/B,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,WAAW,GAAG,MAAM,GAAG,aAAa,CAAC,CACtE,CAAC;AA8BF,wBAAgB,aAAa,CAC3B,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,mBAAmB,CAsXrB"}
1
+ {"version":3,"file":"use-graph-state.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-graph-state.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AACpD,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,OAAO,EAEL,KAAK,YAAY,EAEjB,KAAK,cAAc,EACpB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,mDAAmD;IACnD,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,mDAAmD;IACnD,KAAK,EAAE,IAAI,EAAE,CAAC;IACd;;;OAGG;IACH,SAAS,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IAClE,uEAAuE;IACvE,aAAa,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC5E,kEAAkE;IAClE,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1F,yDAAyD;IACzD,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,sDAAsD;IACtD,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,uDAAuD;IACvD,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAC9D,2DAA2D;IAC3D,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAClE,gCAAgC;IAChC,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,yDAAyD;IACzD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACtF,gEAAgE;IAChE,wBAAwB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACxE,yDAAyD;IACzD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,kBAAkB,GAAG,SAAS,CAAC;IACtE,+EAA+E;IAC/E,cAAc,EAAE,MAAM,MAAM,CAAC;IAC7B,6EAA6E;IAC7E,YAAY,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;CACnD;AAuCD,KAAK,kBAAkB,GAAG,OAAO,CAC/B,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,WAAW,GAAG,MAAM,GAAG,aAAa,CAAC,CACtE,CAAC;AAWF,wBAAgB,aAAa,CAC3B,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,mBAAmB,CAkXrB"}
@@ -36,26 +36,6 @@ function isFeatureDataUnchanged(data, updates) {
36
36
  (updates.name === undefined || updates.name === data.name) &&
37
37
  (updates.description === undefined || updates.description === data.description));
38
38
  }
39
- /**
40
- * Shallow-compare two Maps by key set and entry data (JSON equality).
41
- * Returns true if they are structurally identical, avoiding unnecessary re-renders.
42
- */
43
- function mapsEqual(a, b) {
44
- if (a.size !== b.size)
45
- return false;
46
- for (const [key, aEntry] of a) {
47
- const bEntry = b.get(key);
48
- if (!bEntry)
49
- return false;
50
- if (aEntry.parentNodeId !== bEntry.parentNodeId)
51
- return false;
52
- if (aEntry.data === bEntry.data)
53
- continue;
54
- if (JSON.stringify(aEntry.data) !== JSON.stringify(bEntry.data))
55
- return false;
56
- }
57
- return true;
58
- }
59
39
  export function useGraphState(initialNodes, initialEdges) {
60
40
  // eslint-disable-next-line react-hooks/exhaustive-deps -- intentional: parse only on mount (like useState initializer)
61
41
  const init = useMemo(() => parseMaps(initialNodes, initialEdges), []);
@@ -198,9 +178,6 @@ export function useGraphState(initialNodes, initialEdges) {
198
178
  pendingUpdatesRef.current.delete(nodeId);
199
179
  }
200
180
  }
201
- // Avoid re-render when polling returns identical data
202
- if (mapsEqual(currentFeatureMap, merged))
203
- return currentFeatureMap;
204
181
  return merged;
205
182
  });
206
183
  // Clean pendingMap entries that now have a real counterpart in server data
@@ -243,9 +220,6 @@ export function useGraphState(initialNodes, initialEdges) {
243
220
  merged.set(id, entry);
244
221
  }
245
222
  }
246
- // Avoid re-render when polling returns identical data
247
- if (mapsEqual(currentRepoMap, merged))
248
- return currentRepoMap;
249
223
  return merged;
250
224
  });
251
225
  }, []);
@@ -1 +1 @@
1
- {"version":3,"file":"use-sound.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-sound.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,WAAW,oWA6BP,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACpB;AAgBD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,GAAE,eAAoB,GAAG,cAAc,CA8CvF;AAED,qEAAqE;AACrE,OAAO,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"use-sound.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-sound.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,WAAW,oWA6BP,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,GAAE,eAAoB,GAAG,cAAc,CAgDvF;AAED,qEAAqE;AACrE,OAAO,EAAE,WAAW,EAAE,CAAC"}