@shepai/cli 1.72.9-pr220.e1bfec0 → 1.72.9-pr220.f17b60a

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 (278) hide show
  1. package/dist/packages/core/src/infrastructure/services/notifications/notification.service.d.ts.map +1 -1
  2. package/dist/packages/core/src/infrastructure/services/notifications/notification.service.js +2 -4
  3. package/dist/src/presentation/web/app/build-feature-node-data.d.ts.map +1 -1
  4. package/dist/src/presentation/web/app/build-feature-node-data.js +2 -26
  5. package/dist/src/presentation/web/app/build-graph-nodes.d.ts.map +1 -1
  6. package/dist/src/presentation/web/app/build-graph-nodes.js +2 -26
  7. package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.d.ts.map +1 -1
  8. package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.js +0 -2
  9. package/dist/src/presentation/web/components/common/control-center-drawer/drawer-view.d.ts +2 -0
  10. package/dist/src/presentation/web/components/common/control-center-drawer/drawer-view.d.ts.map +1 -1
  11. package/dist/src/presentation/web/components/common/control-center-drawer/drawer-view.js +11 -11
  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 +17 -27
  14. package/dist/src/presentation/web/components/common/control-center-drawer/index.d.ts +0 -1
  15. package/dist/src/presentation/web/components/common/control-center-drawer/index.d.ts.map +1 -1
  16. package/dist/src/presentation/web/components/common/control-center-drawer/index.js +0 -1
  17. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.d.ts +25 -0
  18. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.d.ts.map +1 -1
  19. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.js +45 -2
  20. package/dist/src/presentation/web/components/common/index.d.ts +1 -2
  21. package/dist/src/presentation/web/components/common/index.d.ts.map +1 -1
  22. package/dist/src/presentation/web/components/common/index.js +1 -2
  23. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  24. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +3 -4
  25. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  26. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +46 -58
  27. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts.map +1 -1
  28. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.js +2 -13
  29. package/dist/src/presentation/web/components/ui/alert-dialog.d.ts.map +1 -1
  30. package/dist/src/presentation/web/components/ui/alert-dialog.js +2 -2
  31. package/dist/src/presentation/web/components/ui/dialog.d.ts.map +1 -1
  32. package/dist/src/presentation/web/components/ui/dialog.js +2 -2
  33. package/dist/src/presentation/web/hooks/use-agent-events.d.ts.map +1 -1
  34. package/dist/src/presentation/web/hooks/use-agent-events.js +6 -3
  35. package/dist/src/presentation/web/hooks/use-graph-state.d.ts +2 -1
  36. package/dist/src/presentation/web/hooks/use-graph-state.d.ts.map +1 -1
  37. package/dist/src/presentation/web/hooks/use-graph-state.js +50 -23
  38. package/dist/src/presentation/web/hooks/use-notifications.d.ts +1 -5
  39. package/dist/src/presentation/web/hooks/use-notifications.d.ts.map +1 -1
  40. package/dist/src/presentation/web/hooks/use-notifications.js +1 -26
  41. package/dist/src/presentation/web/hooks/use-notifications.stories.d.ts.map +1 -1
  42. package/dist/src/presentation/web/hooks/use-notifications.stories.js +28 -38
  43. package/dist/tsconfig.build.tsbuildinfo +1 -1
  44. package/package.json +1 -1
  45. package/web/.next/BUILD_ID +1 -1
  46. package/web/.next/build-manifest.json +2 -2
  47. package/web/.next/cache/.previewinfo +1 -1
  48. package/web/.next/cache/.rscinfo +1 -1
  49. package/web/.next/cache/.tsbuildinfo +1 -1
  50. package/web/.next/cache/config.json +3 -3
  51. package/web/.next/fallback-build-manifest.json +2 -2
  52. package/web/.next/prerender-manifest.json +3 -3
  53. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +15 -15
  54. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  55. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  56. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +18 -18
  57. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  58. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  59. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +13 -13
  60. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  61. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  62. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +15 -15
  63. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  64. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  65. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +18 -18
  66. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  67. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  68. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +13 -13
  69. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  70. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  71. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +13 -13
  72. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  73. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  74. package/web/.next/server/app/_global-error.html +2 -2
  75. package/web/.next/server/app/_global-error.rsc +1 -1
  76. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  77. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  78. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  79. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  80. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  81. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  82. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  83. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  84. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  85. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  86. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  87. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  88. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  89. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  90. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  91. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  92. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  93. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_816618e2.js +1 -1
  94. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_816618e2.js.map +1 -1
  95. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_ba2e050f.js +1 -1
  96. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_ba2e050f.js.map +1 -1
  97. package/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js +2 -2
  98. package/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js.map +1 -1
  99. package/web/.next/server/chunks/ssr/[root-of-the-server]__2018e25f._.js +1 -1
  100. package/web/.next/server/chunks/ssr/[root-of-the-server]__2018e25f._.js.map +1 -1
  101. package/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js +2 -2
  102. package/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js.map +1 -1
  103. package/web/.next/server/chunks/ssr/[root-of-the-server]__6258349c._.js +1 -1
  104. package/web/.next/server/chunks/ssr/[root-of-the-server]__6258349c._.js.map +1 -1
  105. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  106. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  107. package/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js +2 -2
  108. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  109. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  110. package/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js +1 -1
  111. package/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js.map +1 -1
  112. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
  113. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
  114. package/web/.next/server/chunks/ssr/_07c2a32a._.js +1 -1
  115. package/web/.next/server/chunks/ssr/_07c2a32a._.js.map +1 -1
  116. package/web/.next/server/chunks/ssr/_0e9d6bf7._.js +1 -1
  117. package/web/.next/server/chunks/ssr/_0e9d6bf7._.js.map +1 -1
  118. package/web/.next/server/chunks/ssr/_250a63ae._.js +1 -1
  119. package/web/.next/server/chunks/ssr/_250a63ae._.js.map +1 -1
  120. package/web/.next/server/chunks/ssr/_61351ed3._.js +1 -1
  121. package/web/.next/server/chunks/ssr/_61351ed3._.js.map +1 -1
  122. package/web/.next/server/chunks/ssr/_8400c8bb._.js +1 -1
  123. package/web/.next/server/chunks/ssr/_8400c8bb._.js.map +1 -1
  124. package/web/.next/server/chunks/ssr/{_63688261._.js → _8e87c87b._.js} +2 -2
  125. package/web/.next/server/chunks/ssr/{_63688261._.js.map → _8e87c87b._.js.map} +1 -1
  126. package/web/.next/server/chunks/ssr/_9f940437._.js +1 -1
  127. package/web/.next/server/chunks/ssr/_9f940437._.js.map +1 -1
  128. package/web/.next/server/chunks/ssr/src_presentation_web_2b91e4ec._.js +1 -1
  129. package/web/.next/server/chunks/ssr/src_presentation_web_2b91e4ec._.js.map +1 -1
  130. package/web/.next/server/chunks/ssr/src_presentation_web_5bcc1537._.js +1 -1
  131. package/web/.next/server/chunks/ssr/src_presentation_web_5bcc1537._.js.map +1 -1
  132. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_5955c012.js +1 -1
  133. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_5955c012.js.map +1 -1
  134. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
  135. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +1 -1
  136. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  137. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  138. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  139. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  140. package/web/.next/server/chunks/ssr/src_presentation_web_d5b0cb86._.js +2 -2
  141. package/web/.next/server/chunks/ssr/src_presentation_web_d5b0cb86._.js.map +1 -1
  142. package/web/.next/server/chunks/ssr/src_presentation_web_e626b63c._.js +2 -2
  143. package/web/.next/server/chunks/ssr/src_presentation_web_e626b63c._.js.map +1 -1
  144. package/web/.next/server/pages/500.html +2 -2
  145. package/web/.next/server/server-reference-manifest.js +1 -1
  146. package/web/.next/server/server-reference-manifest.json +21 -21
  147. package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
  148. package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
  149. package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
  150. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +15 -15
  151. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  152. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  153. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +18 -18
  154. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  155. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  156. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +13 -13
  157. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  158. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  159. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +15 -15
  160. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  161. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  162. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +18 -18
  163. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  164. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  165. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +13 -13
  166. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  167. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  168. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +13 -13
  169. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  170. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  171. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
  172. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
  173. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  174. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  175. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  176. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  177. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  178. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  179. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  180. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  181. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js.nft.json +1 -1
  182. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  183. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  184. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page.js.nft.json +1 -1
  185. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  186. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  187. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  188. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  189. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_816618e2.js +1 -1
  190. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_ba2e050f.js +1 -1
  191. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js +2 -2
  192. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__2018e25f._.js +1 -1
  193. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js +2 -2
  194. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6258349c._.js +1 -1
  195. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  196. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js +2 -2
  197. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  198. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js +1 -1
  199. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
  200. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_07c2a32a._.js +1 -1
  201. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_0e9d6bf7._.js +1 -1
  202. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_250a63ae._.js +1 -1
  203. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_61351ed3._.js +1 -1
  204. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_8400c8bb._.js +1 -1
  205. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{_63688261._.js → _8e87c87b._.js} +2 -2
  206. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_9f940437._.js +1 -1
  207. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_2b91e4ec._.js +1 -1
  208. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_5bcc1537._.js +1 -1
  209. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_5955c012.js +1 -1
  210. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
  211. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  212. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  213. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_d5b0cb86._.js +2 -2
  214. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_e626b63c._.js +2 -2
  215. package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
  216. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
  217. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +21 -21
  218. package/web/.next/standalone/src/presentation/web/app/build-feature-node-data.ts +3 -30
  219. package/web/.next/standalone/src/presentation/web/app/build-graph-nodes.ts +3 -30
  220. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/create-drawer-client.tsx +0 -2
  221. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/drawer-view.ts +12 -13
  222. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx +21 -37
  223. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/index.ts +0 -1
  224. package/web/.next/standalone/src/presentation/web/components/common/feature-node/derive-feature-state.ts +63 -2
  225. package/web/.next/standalone/src/presentation/web/components/common/index.ts +1 -7
  226. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +12 -21
  227. package/web/.next/standalone/src/presentation/web/components/features/control-center/use-control-center-state.ts +65 -70
  228. package/web/.next/standalone/src/presentation/web/components/features/features-canvas/features-canvas.tsx +1 -18
  229. package/web/.next/standalone/src/presentation/web/components/ui/alert-dialog.tsx +2 -5
  230. package/web/.next/standalone/src/presentation/web/components/ui/dialog.tsx +2 -5
  231. package/web/.next/standalone/src/presentation/web/hooks/use-agent-events.ts +7 -3
  232. package/web/.next/standalone/src/presentation/web/hooks/use-graph-state.ts +104 -71
  233. package/web/.next/standalone/src/presentation/web/hooks/use-notifications.stories.tsx +2 -30
  234. package/web/.next/standalone/src/presentation/web/hooks/use-notifications.ts +2 -36
  235. package/web/.next/static/chunks/0ffccd7be73305c8.css +2 -0
  236. package/web/.next/static/chunks/3f205fd6adbfd20a.js +7 -0
  237. package/web/.next/static/chunks/76827713cb2b7333.js +1 -0
  238. package/web/.next/static/chunks/{c575ab63c138645b.js → 792aac476adb5875.js} +1 -1
  239. package/web/.next/static/chunks/7c8adcfd920a8f74.js +1 -0
  240. package/web/.next/static/chunks/{cdc92cdf81005c84.js → 83463b63971f5723.js} +1 -1
  241. package/web/.next/static/chunks/{63a80e9d4c4b0253.js → 98ca891a5c156aa5.js} +3 -3
  242. package/web/.next/static/chunks/{638824249d103905.js → 9b1770f05f1d95e5.js} +1 -1
  243. package/web/.next/static/chunks/a7f52757dff0cea0.js +1 -0
  244. package/web/.next/static/chunks/b6becf0de992842a.js +1 -0
  245. package/web/.next/static/chunks/{f32c98a709949c5b.js → cb41849bcfaa304e.js} +1 -1
  246. package/web/.next/static/chunks/d5e95c4482029a39.js +1 -0
  247. package/web/.next/trace +1 -1
  248. package/web/.next/trace-build +1 -1
  249. package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.d.ts +0 -12
  250. package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.d.ts.map +0 -1
  251. package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.js +0 -337
  252. package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.d.ts +0 -33
  253. package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.d.ts.map +0 -1
  254. package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.js +0 -214
  255. package/dist/src/presentation/web/components/common/notification-permission-banner/index.d.ts +0 -2
  256. package/dist/src/presentation/web/components/common/notification-permission-banner/index.d.ts.map +0 -1
  257. package/dist/src/presentation/web/components/common/notification-permission-banner/index.js +0 -1
  258. package/dist/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.d.ts +0 -2
  259. package/dist/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.d.ts.map +0 -1
  260. package/dist/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.js +0 -33
  261. package/dist/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.stories.d.ts +0 -6
  262. package/dist/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.stories.d.ts.map +0 -1
  263. package/dist/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.stories.js +0 -24
  264. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.tsx +0 -293
  265. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/control-center-drawer.tsx +0 -745
  266. package/web/.next/standalone/src/presentation/web/components/common/notification-permission-banner/index.ts +0 -1
  267. package/web/.next/standalone/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.stories.tsx +0 -52
  268. package/web/.next/standalone/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.tsx +0 -55
  269. package/web/.next/static/chunks/0a883e2efecfd563.js +0 -1
  270. package/web/.next/static/chunks/0c54314c8c9c9739.js +0 -7
  271. package/web/.next/static/chunks/596ca28d78baae25.js +0 -1
  272. package/web/.next/static/chunks/71c9ecdceac1939f.css +0 -2
  273. package/web/.next/static/chunks/a040b058d79f4ade.js +0 -1
  274. package/web/.next/static/chunks/e05eb1cc84ee254a.js +0 -1
  275. package/web/.next/static/chunks/ef8f8940eac6c542.js +0 -1
  276. /package/web/.next/static/{uMxPSDPwZCludF5408rWJ → eg0FTlsA4z_7CXbFfMgAr}/_buildManifest.js +0 -0
  277. /package/web/.next/static/{uMxPSDPwZCludF5408rWJ → eg0FTlsA4z_7CXbFfMgAr}/_clientMiddlewareManifest.json +0 -0
  278. /package/web/.next/static/{uMxPSDPwZCludF5408rWJ → eg0FTlsA4z_7CXbFfMgAr}/_ssgManifest.js +0 -0
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { useCallback, useEffect, useRef } from 'react';
2
+ import { useCallback, useEffect, useMemo, useRef } from 'react';
3
3
  import { useRouter } from 'next/navigation';
4
4
  import { toast } from 'sonner';
5
5
  import { layoutWithDagre, CANVAS_LAYOUT_DEFAULTS, } from '../../../lib/layout-with-dagre.js';
@@ -9,9 +9,10 @@ import { deleteRepository } from '../../../app/actions/delete-repository.js';
9
9
  import { getFeatureMetadata } from '../../../app/actions/get-feature-metadata.js';
10
10
  import { useAgentEventsContext } from '../../../hooks/agent-events-provider.js';
11
11
  import { useSoundAction } from '../../../hooks/use-sound-action.js';
12
- import { mapEventTypeToState, mapPhaseNameToLifecycle, } from '../../common/feature-node/derive-feature-state.js';
13
- import { NotificationEventType } from '../../../../../../packages/core/src/domain/generated/output.js';
12
+ import { mapEventTypeToState, resolveSseEventUpdates, } from '../../common/feature-node/derive-feature-state.js';
14
13
  import { useGraphState } from '../../../hooks/use-graph-state.js';
14
+ /** Must match the message string emitted by the SSE route in agent-events/route.ts */
15
+ const METADATA_UPDATED_MESSAGE = 'Feature metadata updated';
15
16
  let nextFeatureId = 0;
16
17
  export function useControlCenterState(initialNodes, initialEdges) {
17
18
  const router = useRouter();
@@ -20,18 +21,18 @@ export function useControlCenterState(initialNodes, initialEdges) {
20
21
  const { nodes, edges, reconcile, updateFeature, addPendingFeature, removeFeature, restoreFeature, addRepository: addRepositoryToMap, removeRepository, replaceRepository, getFeatureRepositoryPath, getRepositoryData, setCallbacks, } = useGraphState(initialNodes, initialEdges);
21
22
  // Sync server props into domain Maps when initialNodes/initialEdges change.
22
23
  // Keyed by a stable string so we don't re-reconcile on every render.
23
- const initialNodeKey = initialNodes
24
+ const initialNodeKey = useMemo(() => initialNodes
24
25
  .map((n) => n.id)
25
26
  .sort()
26
- .join(',');
27
- const initialDataKey = initialNodes
27
+ .join(','), [initialNodes]);
28
+ const initialDataKey = useMemo(() => initialNodes
28
29
  .filter((n) => n.type === 'featureNode')
29
30
  .map((n) => {
30
31
  const d = n.data;
31
32
  return `${n.id}:${d.state}:${d.lifecycle}`;
32
33
  })
33
34
  .sort()
34
- .join(',');
35
+ .join(','), [initialNodes]);
35
36
  const prevReconcileKey = useRef('');
36
37
  useEffect(() => {
37
38
  const key = `${initialNodeKey}|${initialDataKey}`;
@@ -42,14 +43,6 @@ export function useControlCenterState(initialNodes, initialEdges) {
42
43
  }, [initialNodeKey, initialDataKey, initialNodes, initialEdges, reconcile]);
43
44
  // Track previous feature states for fallback notifications
44
45
  const prevFeatureStatesRef = useRef(new Map());
45
- const initialFeatureDataKey = initialNodes
46
- .filter((n) => n.type === 'featureNode')
47
- .map((n) => {
48
- const d = n.data;
49
- return `${n.id}:${d.state}`;
50
- })
51
- .sort()
52
- .join(',');
53
46
  const { events } = useAgentEventsContext();
54
47
  useEffect(() => {
55
48
  const prevStates = prevFeatureStatesRef.current;
@@ -80,7 +73,7 @@ export function useControlCenterState(initialNodes, initialEdges) {
80
73
  }
81
74
  prevStates.set(node.id, data.state);
82
75
  }
83
- }, [initialFeatureDataKey, initialNodes, events, router]);
76
+ }, [initialDataKey, initialNodes, events, router]);
84
77
  // SSE effect: only state + lifecycle updates
85
78
  const processedEventCountRef = useRef(0);
86
79
  useEffect(() => {
@@ -88,33 +81,34 @@ export function useControlCenterState(initialNodes, initialEdges) {
88
81
  return;
89
82
  const newEvents = events.slice(processedEventCountRef.current);
90
83
  processedEventCountRef.current = events.length;
91
- // PhaseCompleted must NOT set state when WaitingApproval is in the same poll batch —
92
- // they arrive together and PhaseCompleted 'running' would revert 'action-required'.
93
- // But when PhaseCompleted arrives WITHOUT WaitingApproval (e.g. after approval), we
94
- // must allow it to update state as a fallback for any missed AgentStarted event.
95
- const waitingApprovalFeatures = new Set(newEvents
96
- .filter((e) => e.eventType === NotificationEventType.WaitingApproval)
97
- .map((e) => e.featureId));
98
- for (const event of newEvents) {
99
- const newState = event.eventType === NotificationEventType.PhaseCompleted &&
100
- waitingApprovalFeatures.has(event.featureId)
101
- ? undefined
102
- : mapEventTypeToState(event.eventType);
103
- const newLifecycle = mapPhaseNameToLifecycle(event.phaseName);
104
- const nodeId = `feat-${event.featureId}`;
105
- if (newState !== undefined || newLifecycle !== undefined) {
106
- updateFeature(nodeId, {
107
- ...(newState !== undefined && { state: newState }),
108
- ...(newLifecycle !== undefined && { lifecycle: newLifecycle }),
84
+ for (const { featureId, state, lifecycle } of resolveSseEventUpdates(newEvents)) {
85
+ if (state !== undefined || lifecycle !== undefined) {
86
+ updateFeature(`feat-${featureId}`, {
87
+ ...(state !== undefined && { state }),
88
+ ...(lifecycle !== undefined && { lifecycle }),
109
89
  });
110
90
  }
111
91
  }
112
92
  }, [events, updateFeature]);
93
+ // Listen for optimistic approval events from the drawer (fires before SSE arrives)
94
+ useEffect(() => {
95
+ const handler = (e) => {
96
+ const { featureId } = e.detail;
97
+ updateFeature(`feat-${featureId}`, { state: 'running' });
98
+ };
99
+ window.addEventListener('shep:feature-approved', handler);
100
+ return () => window.removeEventListener('shep:feature-approved', handler);
101
+ }, [updateFeature]);
113
102
  // Separate effect: fetch metadata (name + description) when SSE reports it changed
114
103
  const metadataFetchedRef = useRef(new Set());
104
+ const processedMetadataCountRef = useRef(0);
115
105
  useEffect(() => {
116
- for (const event of events) {
117
- if (event.message !== 'Feature metadata updated')
106
+ if (events.length <= processedMetadataCountRef.current)
107
+ return;
108
+ const newEvents = events.slice(processedMetadataCountRef.current);
109
+ processedMetadataCountRef.current = events.length;
110
+ for (const event of newEvents) {
111
+ if (event.message !== METADATA_UPDATED_MESSAGE)
118
112
  continue;
119
113
  if (metadataFetchedRef.current.has(event.featureId))
120
114
  continue;
@@ -193,6 +187,20 @@ export function useControlCenterState(initialNodes, initialEdges) {
193
187
  const childFeatureIds = new Set(edges.filter((e) => e.source === repoNodeId).map((e) => e.target));
194
188
  // Snapshot for rollback
195
189
  const prevRepoData = getRepositoryData(repoNodeId);
190
+ const childSnapshots = new Map();
191
+ for (const childId of childFeatureIds) {
192
+ const childNode = nodes.find((n) => n.id === childId);
193
+ if (childNode) {
194
+ childSnapshots.set(childId, { nodeId: childId, data: childNode.data });
195
+ }
196
+ }
197
+ const rollback = () => {
198
+ if (prevRepoData)
199
+ addRepositoryToMap(repoNodeId, prevRepoData);
200
+ for (const [childId, entry] of childSnapshots) {
201
+ restoreFeature(childId, entry);
202
+ }
203
+ };
196
204
  // Optimistic: remove repo + children
197
205
  removeRepository(repoNodeId);
198
206
  for (const childId of childFeatureIds) {
@@ -202,17 +210,7 @@ export function useControlCenterState(initialNodes, initialEdges) {
202
210
  const result = await deleteRepository(repositoryId);
203
211
  if (!result.success) {
204
212
  toast.error(result.error ?? 'Failed to remove repository');
205
- if (prevRepoData)
206
- addRepositoryToMap(repoNodeId, prevRepoData);
207
- for (const childId of childFeatureIds) {
208
- const childNode = nodes.find((n) => n.id === childId);
209
- if (childNode) {
210
- restoreFeature(childId, {
211
- nodeId: childId,
212
- data: childNode.data,
213
- });
214
- }
215
- }
213
+ rollback();
216
214
  return;
217
215
  }
218
216
  deleteSound.play();
@@ -220,17 +218,7 @@ export function useControlCenterState(initialNodes, initialEdges) {
220
218
  }
221
219
  catch {
222
220
  toast.error('Failed to remove repository');
223
- if (prevRepoData)
224
- addRepositoryToMap(repoNodeId, prevRepoData);
225
- for (const childId of childFeatureIds) {
226
- const childNode = nodes.find((n) => n.id === childId);
227
- if (childNode) {
228
- restoreFeature(childId, {
229
- nodeId: childId,
230
- data: childNode.data,
231
- });
232
- }
233
- }
221
+ rollback();
234
222
  }
235
223
  }, [
236
224
  edges,
@@ -1 +1 @@
1
- {"version":3,"file":"features-canvas.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/features-canvas.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAKlE,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,kCAAkC,CAAC;AAEzF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAG9E,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAElE,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAChE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACtE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAChD,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B;AAED,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,KAAK,EACL,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,SAAS,EACT,WAAW,EACX,WAAW,EACX,YAAY,EACZ,OAAO,EACP,UAAU,GACX,EAAE,mBAAmB,2CAmGrB"}
1
+ {"version":3,"file":"features-canvas.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/features-canvas.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAKlE,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,kCAAkC,CAAC;AAEzF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAG9E,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAElE,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAChE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACtE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAChD,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B;AAED,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,KAAK,EACL,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,SAAS,EACT,WAAW,EACX,WAAW,EACX,YAAY,EACZ,OAAO,EACP,UAAU,GACX,EAAE,mBAAmB,2CAkFrB"}
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useMemo, useCallback } from 'react';
3
+ import { useMemo } from 'react';
4
4
  import { ReactFlow, Background, Controls } from '@xyflow/react';
5
5
  import { Plus } from 'lucide-react';
6
6
  import { Button } from '../../ui/button.js';
@@ -16,17 +16,6 @@ export function FeaturesCanvas({ nodes, edges, selectedFeatureId, onNodesChange,
16
16
  const edgeTypes = useMemo(() => ({
17
17
  dependencyEdge: DependencyEdge,
18
18
  }), []);
19
- // Prevent a feature from having more than one source repository
20
- const isValidConnection = useCallback((connection) => {
21
- const sourceNode = nodes.find((n) => n.id === connection.source);
22
- if (sourceNode?.type !== 'repositoryNode')
23
- return true;
24
- const targetAlreadyHasRepo = edges.some((e) => {
25
- const edgeSourceNode = nodes.find((n) => n.id === e.source);
26
- return edgeSourceNode?.type === 'repositoryNode' && e.target === connection.target;
27
- });
28
- return !targetAlreadyHasRepo;
29
- }, [nodes, edges]);
30
19
  // Callbacks and showHandles are already injected into node.data by deriveGraph.
31
20
  // Only selectedFeatureId highlighting needs to be applied here.
32
21
  const enrichedNodes = useMemo(() => selectedFeatureId == null
@@ -41,5 +30,5 @@ export function FeaturesCanvas({ nodes, edges, selectedFeatureId, onNodesChange,
41
30
  }
42
31
  return (_jsx("div", { "data-testid": "features-canvas-empty", children: _jsx(EmptyState, { title: "No features yet", description: "Get started by creating your first feature.", action: _jsxs(Button, { onClick: onAddFeature, children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), "New Feature"] }) }) }));
43
32
  }
44
- return (_jsx("div", { "data-testid": "features-canvas", "data-no-drawer-close": true, className: "pointer-events-auto h-full w-full", children: _jsxs(ReactFlow, { nodes: enrichedNodes, edges: edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, isValidConnection: isValidConnection, onConnect: onConnect, onNodesChange: onNodesChange, onNodeClick: onNodeClick, onPaneClick: onPaneClick, onMoveStart: onCanvasDrag, defaultViewport: { x: 30, y: 30, zoom: 0.85 }, nodesDraggable: false, nodesConnectable: false, elementsSelectable: false, children: [_jsx(Background, {}), _jsx(Controls, {}), toolbar] }) }));
33
+ return (_jsx("div", { "data-testid": "features-canvas", "data-no-drawer-close": true, className: "pointer-events-auto h-full w-full", children: _jsxs(ReactFlow, { nodes: enrichedNodes, edges: edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, onConnect: onConnect, onNodesChange: onNodesChange, onNodeClick: onNodeClick, onPaneClick: onPaneClick, onMoveStart: onCanvasDrag, defaultViewport: { x: 30, y: 30, zoom: 0.85 }, nodesDraggable: false, nodesConnectable: false, elementsSelectable: false, children: [_jsx(Background, {}), _jsx(Controls, {}), toolbar] }) }));
45
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"alert-dialog.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/ui/alert-dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,WAAW,IAAI,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAG/D,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEhD,iBAAS,WAAW,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,IAAI,CAAC,2CAExF;AAED,iBAAS,kBAAkB,CAAC,EAC1B,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,OAAO,CAAC,2CAE3D;AAED,iBAAS,iBAAiB,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,MAAM,CAAC,2CAEhG;AAED,iBAAS,kBAAkB,CAAC,EAC1B,SAAS,EACT,OAAO,EACP,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,OAAO,CAAC,2CAiB3D;AAED,iBAAS,kBAAkB,CAAC,EAC1B,SAAS,EACT,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,OAAO,CAAC,GAAG;IAC7D,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;CACzB,2CAeA;AAED,iBAAS,iBAAiB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAW9E;AAED,iBAAS,iBAAiB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAW9E;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,KAAK,CAAC,2CAWzD;AAED,iBAAS,sBAAsB,CAAC,EAC9B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,WAAW,CAAC,2CAQ/D;AAED,iBAAS,gBAAgB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAW7E;AAED,iBAAS,iBAAiB,CAAC,EACzB,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,MAAM,CAAC,GACzD,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC,2CAU9D;AAED,iBAAS,iBAAiB,CAAC,EACzB,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,MAAM,CAAC,GACzD,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC,2CAU9D;AAED,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,GACnB,CAAC"}
1
+ {"version":3,"file":"alert-dialog.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/ui/alert-dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,WAAW,IAAI,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAG/D,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEhD,iBAAS,WAAW,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,IAAI,CAAC,2CAExF;AAED,iBAAS,kBAAkB,CAAC,EAC1B,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,OAAO,CAAC,2CAE3D;AAED,iBAAS,iBAAiB,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,MAAM,CAAC,2CAEhG;AAED,iBAAS,kBAAkB,CAAC,EAC1B,SAAS,EACT,OAAO,EACP,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,OAAO,CAAC,2CAc3D;AAED,iBAAS,kBAAkB,CAAC,EAC1B,SAAS,EACT,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,OAAO,CAAC,GAAG;IAC7D,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;CACzB,2CAeA;AAED,iBAAS,iBAAiB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAW9E;AAED,iBAAS,iBAAiB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAW9E;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,KAAK,CAAC,2CAWzD;AAED,iBAAS,sBAAsB,CAAC,EAC9B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,WAAW,CAAC,2CAQ/D;AAED,iBAAS,gBAAgB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAW7E;AAED,iBAAS,iBAAiB,CAAC,EACzB,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,MAAM,CAAC,GACzD,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC,2CAU9D;AAED,iBAAS,iBAAiB,CAAC,EACzB,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,MAAM,CAAC,GACzD,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC,2CAU9D;AAED,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,GACnB,CAAC"}
@@ -13,7 +13,7 @@ function AlertDialogPortal({ ...props }) {
13
13
  return _jsx(AlertDialogPrimitive.Portal, { "data-slot": "alert-dialog-portal", ...props });
14
14
  }
15
15
  function AlertDialogOverlay({ className, onClick, ...props }) {
16
- return (_jsx(AlertDialogPrimitive.Overlay, { "data-slot": "alert-dialog-overlay", className: cn('data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50', className), onClick: (e) => {
16
+ return (_jsx(AlertDialogPrimitive.Overlay, { "data-slot": "alert-dialog-overlay", className: cn('fixed inset-0 z-50 bg-black/50', className), onClick: (e) => {
17
17
  // Prevent overlay clicks from propagating to document-level handlers
18
18
  // (e.g. BaseDrawer outside-click) — only the dialog should dismiss.
19
19
  e.stopPropagation();
@@ -21,7 +21,7 @@ function AlertDialogOverlay({ className, onClick, ...props }) {
21
21
  }, ...props }));
22
22
  }
23
23
  function AlertDialogContent({ className, size = 'default', ...props }) {
24
- return (_jsxs(AlertDialogPortal, { children: [_jsx(AlertDialogOverlay, {}), _jsx(AlertDialogPrimitive.Content, { "data-slot": "alert-dialog-content", "data-size": size, className: cn('bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 group/alert-dialog-content fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-lg', className), ...props })] }));
24
+ return (_jsxs(AlertDialogPortal, { children: [_jsx(AlertDialogOverlay, {}), _jsx(AlertDialogPrimitive.Content, { "data-slot": "alert-dialog-content", "data-size": size, className: cn('bg-background group/alert-dialog-content fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-lg', className), ...props })] }));
25
25
  }
26
26
  function AlertDialogHeader({ className, ...props }) {
27
27
  return (_jsx("div", { "data-slot": "alert-dialog-header", className: cn('grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-6 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]', className), ...props }));
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/ui/dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,UAAU,CAAC;AAKrD,QAAA,MAAM,MAAM,uCAAuB,CAAC;AAEpC,QAAA,MAAM,aAAa,8GAA0B,CAAC;AAE9C,QAAA,MAAM,YAAY,6CAAyB,CAAC;AAE5C,QAAA,MAAM,WAAW,4GAAwB,CAAC;AAE1C,QAAA,MAAM,aAAa,8JAkBjB,CAAC;AAGH,QAAA,MAAM,aAAa,8JAqBjB,CAAC;AAGH,QAAA,MAAM,YAAY;8BAA6B,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;;CAElF,CAAC;AAGF,QAAA,MAAM,YAAY;8BAA6B,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;;CAKlF,CAAC;AAGF,QAAA,MAAM,WAAW,oKASf,CAAC;AAGH,QAAA,MAAM,iBAAiB,8KASrB,CAAC;AAGH,OAAO,EACL,MAAM,EACN,YAAY,EACZ,aAAa,EACb,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,iBAAiB,GAClB,CAAC"}
1
+ {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/ui/dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,UAAU,CAAC;AAKrD,QAAA,MAAM,MAAM,uCAAuB,CAAC;AAEpC,QAAA,MAAM,aAAa,8GAA0B,CAAC;AAE9C,QAAA,MAAM,YAAY,6CAAyB,CAAC;AAE5C,QAAA,MAAM,WAAW,4GAAwB,CAAC;AAE1C,QAAA,MAAM,aAAa,8JAejB,CAAC;AAGH,QAAA,MAAM,aAAa,8JAqBjB,CAAC;AAGH,QAAA,MAAM,YAAY;8BAA6B,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;;CAElF,CAAC;AAGF,QAAA,MAAM,YAAY;8BAA6B,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;;CAKlF,CAAC;AAGF,QAAA,MAAM,WAAW,oKASf,CAAC;AAGH,QAAA,MAAM,iBAAiB,8KASrB,CAAC;AAGH,OAAO,EACL,MAAM,EACN,YAAY,EACZ,aAAa,EACb,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,iBAAiB,GAClB,CAAC"}
@@ -8,14 +8,14 @@ const Dialog = DialogPrimitive.Root;
8
8
  const DialogTrigger = DialogPrimitive.Trigger;
9
9
  const DialogPortal = DialogPrimitive.Portal;
10
10
  const DialogClose = DialogPrimitive.Close;
11
- const DialogOverlay = React.forwardRef(({ className, onClick, ...props }, ref) => (_jsx(DialogPrimitive.Overlay, { ref: ref, className: cn('data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80', className), onClick: (e) => {
11
+ const DialogOverlay = React.forwardRef(({ className, onClick, ...props }, ref) => (_jsx(DialogPrimitive.Overlay, { ref: ref, className: cn('fixed inset-0 z-50 bg-black/80', className), onClick: (e) => {
12
12
  // Prevent overlay clicks from propagating to document-level handlers
13
13
  // (e.g. BaseDrawer outside-click) — only the dialog should dismiss.
14
14
  e.stopPropagation();
15
15
  onClick?.(e);
16
16
  }, ...props })));
17
17
  DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
18
- const DialogContent = React.forwardRef(({ className, children, ...props }, ref) => (_jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Content, { ref: ref, className: cn('bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg', className), ...props, children: [children, _jsxs(DialogPrimitive.Close, { className: "ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-none disabled:pointer-events-none", children: [_jsx(X, { className: "h-4 w-4" }), _jsx("span", { className: "sr-only", children: "Close" })] })] })] })));
18
+ const DialogContent = React.forwardRef(({ className, children, ...props }, ref) => (_jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Content, { ref: ref, className: cn('bg-background fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg sm:rounded-lg', className), ...props, children: [children, _jsxs(DialogPrimitive.Close, { className: "ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-none disabled:pointer-events-none", children: [_jsx(X, { className: "h-4 w-4" }), _jsx("span", { className: "sr-only", children: "Close" })] })] })] })));
19
19
  DialogContent.displayName = DialogPrimitive.Content.displayName;
20
20
  const DialogHeader = ({ className, ...props }) => (_jsx("div", { className: cn('flex flex-col space-y-1.5 text-center sm:text-left', className), ...props }));
21
21
  DialogHeader.displayName = 'DialogHeader';
@@ -1 +1 @@
1
- {"version":3,"file":"use-agent-events.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-agent-events.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAE9E,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,YAAY,GAAG,cAAc,CAAC;AAE3E,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACpC,gBAAgB,EAAE,gBAAgB,CAAC;CACpC;AAID;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,oBAAoB,CA2GpF"}
1
+ {"version":3,"file":"use-agent-events.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-agent-events.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAE9E,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,YAAY,GAAG,cAAc,CAAC;AAE3E,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACpC,gBAAgB,EAAE,gBAAgB,CAAC;CACpC;AAID;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,oBAAoB,CA+GpF"}
@@ -75,10 +75,13 @@ export function useAgentEvents(options) {
75
75
  subscribeToWorker(sw);
76
76
  }
77
77
  else {
78
- sw.addEventListener('statechange', () => {
79
- if (sw.state === 'activated')
78
+ const onStateChange = () => {
79
+ if (sw.state === 'activated') {
80
+ sw.removeEventListener('statechange', onStateChange);
80
81
  subscribeToWorker(sw);
81
- });
82
+ }
83
+ };
84
+ sw.addEventListener('statechange', onStateChange);
82
85
  }
83
86
  })
84
87
  .catch(() => {
@@ -15,7 +15,7 @@ export interface UseGraphStateReturn {
15
15
  */
16
16
  reconcile: (newNodes: CanvasNodeType[], newEdges: Edge[]) => void;
17
17
  /** Update a feature's state/lifecycle/name (e.g., from SSE events). */
18
- updateFeature: (featureNodeId: string, updates: Partial<Pick<FeatureNodeData, 'state' | 'lifecycle' | 'name' | 'description'>>) => void;
18
+ updateFeature: (featureNodeId: string, updates: FeatureDataUpdates) => void;
19
19
  /** Add a pending (optimistic) feature node (state='creating'). */
20
20
  addPendingFeature: (nodeId: string, data: FeatureNodeData, parentNodeId?: string) => void;
21
21
  /** Remove a pending feature node (e.g., on rollback). */
@@ -37,5 +37,6 @@ export interface UseGraphStateReturn {
37
37
  /** Update callbacks injected into node data (does NOT trigger re-render). */
38
38
  setCallbacks: (callbacks: GraphCallbacks) => void;
39
39
  }
40
+ type FeatureDataUpdates = Partial<Pick<FeatureNodeData, 'state' | 'lifecycle' | 'name' | 'description'>>;
40
41
  export declare function useGraphState(initialNodes: CanvasNodeType[], initialEdges: Edge[]): UseGraphStateReturn;
41
42
  //# sourceMappingURL=use-graph-state.d.ts.map
@@ -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,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,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,CACb,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,WAAW,GAAG,MAAM,GAAG,aAAa,CAAC,CAAC,KACpF,IAAI,CAAC;IACV,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,6EAA6E;IAC7E,YAAY,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;CACnD;AAuCD,wBAAgB,aAAa,CAC3B,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,mBAAmB,CAwPrB"}
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,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,CA+QrB"}
@@ -7,7 +7,7 @@ function parseMaps(initialNodes, initialEdges) {
7
7
  // Build parentNodeId map from dependency edges
8
8
  const parentByChild = new Map();
9
9
  for (const edge of initialEdges) {
10
- if (edge.type === 'dependencyEdge' || edge.id.startsWith('dep-')) {
10
+ if (edge.type === 'dependencyEdge') {
11
11
  parentByChild.set(edge.target, edge.source);
12
12
  }
13
13
  }
@@ -30,6 +30,12 @@ function parseMaps(initialNodes, initialEdges) {
30
30
  }
31
31
  return { featureMap, repoMap };
32
32
  }
33
+ function isFeatureDataUnchanged(data, updates) {
34
+ return ((updates.state === undefined || updates.state === data.state) &&
35
+ (updates.lifecycle === undefined || updates.lifecycle === data.lifecycle) &&
36
+ (updates.name === undefined || updates.name === data.name) &&
37
+ (updates.description === undefined || updates.description === data.description));
38
+ }
33
39
  export function useGraphState(initialNodes, initialEdges) {
34
40
  // eslint-disable-next-line react-hooks/exhaustive-deps -- intentional: parse only on mount (like useState initializer)
35
41
  const init = useMemo(() => parseMaps(initialNodes, initialEdges), []);
@@ -55,23 +61,55 @@ export function useGraphState(initialNodes, initialEdges) {
55
61
  featureMapRef.current = featureMap;
56
62
  const repoMapRef = useRef(repoMap);
57
63
  repoMapRef.current = repoMap;
58
- // Derived nodes/edges only re-runs when domain Maps change (not callbacks)
64
+ // Derive graph from domain Maps (runs on every Map change, but dagre only on topology change)
65
+ const derived = useMemo(() => deriveGraph(featureMap, repoMap, pendingMap, stableCallbacks), [featureMap, repoMap, pendingMap, stableCallbacks]);
66
+ // Cache dagre layout positions — only re-run when node set or edge connections change
67
+ const layoutCacheRef = useRef({ key: '', positions: new Map() });
59
68
  const { nodes, edges } = useMemo(() => {
60
- const derived = deriveGraph(featureMap, repoMap, pendingMap, stableCallbacks);
61
- return layoutWithDagre(derived.nodes, derived.edges, CANVAS_LAYOUT_DEFAULTS);
62
- }, [featureMap, repoMap, pendingMap, stableCallbacks]);
69
+ const nodeIds = derived.nodes
70
+ .map((n) => n.id)
71
+ .sort()
72
+ .join(',');
73
+ const edgeKeys = derived.edges
74
+ .map((e) => `${e.source}-${e.target}`)
75
+ .sort()
76
+ .join(',');
77
+ const topologyKey = `${nodeIds}|${edgeKeys}`;
78
+ if (topologyKey !== layoutCacheRef.current.key) {
79
+ // Topology changed — re-run dagre
80
+ const result = layoutWithDagre(derived.nodes, derived.edges, CANVAS_LAYOUT_DEFAULTS);
81
+ const positions = new Map();
82
+ for (const node of result.nodes) {
83
+ positions.set(node.id, {
84
+ position: node.position,
85
+ targetPosition: node.targetPosition,
86
+ sourcePosition: node.sourcePosition,
87
+ });
88
+ }
89
+ layoutCacheRef.current = { key: topologyKey, positions };
90
+ return result;
91
+ }
92
+ // Data-only change — apply cached positions without re-running dagre
93
+ const { positions } = layoutCacheRef.current;
94
+ const nodes = derived.nodes.map((node) => {
95
+ const cached = positions.get(node.id);
96
+ return cached ? { ...node, ...cached } : node;
97
+ });
98
+ return { nodes, edges: derived.edges };
99
+ }, [derived]);
63
100
  // --- Mutations ---
64
101
  const reconcile = useCallback((newNodes, newEdges) => {
65
102
  const { featureMap: newFeatureMap, repoMap: newRepoMap } = parseMaps(newNodes, newEdges);
103
+ // Precompute match keys so we don't scan newFeatureMap.values() per pending entry
104
+ const realFeatureKeys = new Set([...newFeatureMap.values()].map((e) => `${e.data.name}\0${e.data.repositoryPath}`));
66
105
  setFeatureMap((currentFeatureMap) => {
67
106
  // Preserve pending (creating) nodes unless matched by name+repositoryPath from newFeatureMap
68
107
  const pendingEntries = [...currentFeatureMap.entries()].filter(([, e]) => e.data.state === 'creating');
69
108
  const merged = new Map(newFeatureMap);
70
109
  // Keep pending nodes that don't have a real counterpart in new data
71
110
  for (const [tempId, pendingEntry] of pendingEntries) {
72
- const matched = [...newFeatureMap.values()].some((e) => e.data.name === pendingEntry.data.name &&
73
- e.data.repositoryPath === pendingEntry.data.repositoryPath);
74
- if (!matched) {
111
+ const key = `${pendingEntry.data.name}\0${pendingEntry.data.repositoryPath}`;
112
+ if (!realFeatureKeys.has(key)) {
75
113
  merged.set(tempId, pendingEntry);
76
114
  }
77
115
  }
@@ -92,9 +130,8 @@ export function useGraphState(initialNodes, initialEdges) {
92
130
  let changed = false;
93
131
  const next = new Map(currentPendingMap);
94
132
  for (const [tempId, pendingEntry] of currentPendingMap) {
95
- const matched = [...newFeatureMap.values()].some((e) => e.data.name === pendingEntry.data.name &&
96
- e.data.repositoryPath === pendingEntry.data.repositoryPath);
97
- if (matched) {
133
+ const key = `${pendingEntry.data.name}\0${pendingEntry.data.repositoryPath}`;
134
+ if (realFeatureKeys.has(key)) {
98
135
  next.delete(tempId);
99
136
  changed = true;
100
137
  }
@@ -116,14 +153,8 @@ export function useGraphState(initialNodes, initialEdges) {
116
153
  }
117
154
  // Clear any buffered update for this feature since it's now in the map
118
155
  pendingUpdatesRef.current.delete(featureNodeId);
119
- // Skip if no actual change (prevents unnecessary re-renders on event replay)
120
- const stateUnchanged = updates.state === undefined || updates.state === entry.data.state;
121
- const lifecycleUnchanged = updates.lifecycle === undefined || updates.lifecycle === entry.data.lifecycle;
122
- const nameUnchanged = updates.name === undefined || updates.name === entry.data.name;
123
- const descUnchanged = updates.description === undefined || updates.description === entry.data.description;
124
- if (stateUnchanged && lifecycleUnchanged && nameUnchanged && descUnchanged) {
156
+ if (isFeatureDataUnchanged(entry.data, updates))
125
157
  return prev;
126
- }
127
158
  const next = new Map(prev);
128
159
  next.set(featureNodeId, { ...entry, data: { ...entry.data, ...updates } });
129
160
  return next;
@@ -133,11 +164,7 @@ export function useGraphState(initialNodes, initialEdges) {
133
164
  const entry = prev.get(featureNodeId);
134
165
  if (!entry)
135
166
  return prev;
136
- const stateUnchanged = updates.state === undefined || updates.state === entry.data.state;
137
- const lifecycleUnchanged = updates.lifecycle === undefined || updates.lifecycle === entry.data.lifecycle;
138
- const nameUnchanged = updates.name === undefined || updates.name === entry.data.name;
139
- const descUnchanged = updates.description === undefined || updates.description === entry.data.description;
140
- if (stateUnchanged && lifecycleUnchanged && nameUnchanged && descUnchanged)
167
+ if (isFeatureDataUnchanged(entry.data, updates))
141
168
  return prev;
142
169
  const next = new Map(prev);
143
170
  next.set(featureNodeId, { ...entry, data: { ...entry.data, ...updates } });
@@ -1,6 +1,2 @@
1
- export interface UseNotificationsResult {
2
- requestBrowserPermission: () => Promise<void>;
3
- browserPermissionState: NotificationPermission;
4
- }
5
- export declare function useNotifications(): UseNotificationsResult;
1
+ export declare function useNotifications(): void;
6
2
  //# sourceMappingURL=use-notifications.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-notifications.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-notifications.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,sBAAsB;IACrC,wBAAwB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,sBAAsB,EAAE,sBAAsB,CAAC;CAChD;AA2CD,wBAAgB,gBAAgB,IAAI,sBAAsB,CAiEzD"}
1
+ {"version":3,"file":"use-notifications.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-notifications.ts"],"names":[],"mappings":"AA0CA,wBAAgB,gBAAgB,IAAI,IAAI,CA8CvC"}
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
+ import { useEffect, useMemo, useRef } from 'react';
3
3
  import { useRouter } from 'next/navigation';
4
4
  import { toast } from 'sonner';
5
5
  import { NotificationEventType, NotificationSeverity } from '../../../../packages/core/src/domain/generated/output.js';
@@ -27,15 +27,6 @@ function dispatchToast(event, navigate) {
27
27
  }),
28
28
  });
29
29
  }
30
- function dispatchBrowserNotification(event) {
31
- if (globalThis.Notification?.permission !== 'granted') {
32
- return;
33
- }
34
- new Notification(`Shep: ${event.featureName}`, {
35
- body: event.message,
36
- icon: '/favicon-light.svg',
37
- });
38
- }
39
30
  const SEVERITY_TO_ACTION = {
40
31
  [NotificationSeverity.Success]: 'notification-success',
41
32
  [NotificationSeverity.Error]: 'notification-error',
@@ -55,11 +46,6 @@ export function useNotifications() {
55
46
  'notification-warning': warningSound,
56
47
  'notification-info': infoSound,
57
48
  }), [successSound, errorSound, warningSound, infoSound]);
58
- const [browserPermissionState, setBrowserPermissionState] = useState(() => {
59
- if (typeof globalThis.Notification === 'undefined')
60
- return 'default';
61
- return globalThis.Notification.permission;
62
- });
63
49
  // Track how many events from the array we've already processed.
64
50
  // Using the array index (instead of lastEvent) prevents React batching
65
51
  // from silently dropping events when multiple SSE messages arrive together.
@@ -77,19 +63,8 @@ export function useNotifications() {
77
63
  continue;
78
64
  }
79
65
  dispatchToast(event, (path) => router.push(path));
80
- dispatchBrowserNotification(event);
81
66
  const actionName = SEVERITY_TO_ACTION[event.severity];
82
67
  soundsByAction[actionName]?.play();
83
68
  }
84
69
  }, [events, soundsByAction, router]);
85
- const requestBrowserPermission = useCallback(async () => {
86
- if (typeof globalThis.Notification === 'undefined')
87
- return;
88
- const result = await globalThis.Notification.requestPermission();
89
- setBrowserPermissionState(result);
90
- }, []);
91
- return {
92
- requestBrowserPermission,
93
- browserPermissionState,
94
- };
95
70
  }
@@ -1 +1 @@
1
- {"version":3,"file":"use-notifications.stories.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-notifications.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAqKvD,QAAA,MAAM,IAAI,EAAE,IAcX,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC;AAEtB,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC"}
1
+ {"version":3,"file":"use-notifications.stories.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-notifications.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAyIvD,QAAA,MAAM,IAAI,EAAE,IAcX,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC;AAEtB,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC"}