@shepai/cli 1.72.6 → 1.72.7

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 (244) hide show
  1. package/dist/packages/core/src/application/use-cases/features/delete-feature.use-case.d.ts +4 -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 +20 -12
  4. package/dist/packages/core/src/application/use-cases/repositories/delete-repository.use-case.d.ts +8 -3
  5. package/dist/packages/core/src/application/use-cases/repositories/delete-repository.use-case.d.ts.map +1 -1
  6. package/dist/packages/core/src/application/use-cases/repositories/delete-repository.use-case.js +17 -4
  7. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.js +1 -1
  8. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.d.ts.map +1 -1
  9. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.js +2 -6
  10. package/dist/src/presentation/web/app/build-graph-nodes.js +11 -1
  11. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.d.ts +3 -1
  12. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.d.ts.map +1 -1
  13. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.js +8 -4
  14. package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.d.ts.map +1 -1
  15. package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.js +12 -3
  16. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
  17. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +6 -2
  18. package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.d.ts.map +1 -1
  19. package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.js +1 -1
  20. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  21. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +1 -1
  22. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  23. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +7 -2
  24. package/dist/src/presentation/web/components/common/repository-node/repository-node.d.ts.map +1 -1
  25. package/dist/src/presentation/web/components/common/repository-node/repository-node.js +6 -2
  26. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  27. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +14 -2
  28. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +3 -5
  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 +131 -196
  31. package/dist/src/presentation/web/components/ui/alert-dialog.d.ts +1 -1
  32. package/dist/src/presentation/web/components/ui/alert-dialog.d.ts.map +1 -1
  33. package/dist/src/presentation/web/components/ui/alert-dialog.js +7 -2
  34. package/dist/src/presentation/web/components/ui/dialog.d.ts.map +1 -1
  35. package/dist/src/presentation/web/components/ui/dialog.js +6 -1
  36. package/dist/src/presentation/web/lib/layout-with-dagre.d.ts +2 -0
  37. package/dist/src/presentation/web/lib/layout-with-dagre.d.ts.map +1 -1
  38. package/dist/src/presentation/web/lib/layout-with-dagre.js +86 -4
  39. package/dist/tsconfig.build.tsbuildinfo +1 -1
  40. package/package.json +1 -1
  41. package/web/.next/BUILD_ID +1 -1
  42. package/web/.next/build-manifest.json +2 -2
  43. package/web/.next/cache/.previewinfo +1 -1
  44. package/web/.next/cache/.rscinfo +1 -1
  45. package/web/.next/cache/.tsbuildinfo +1 -1
  46. package/web/.next/cache/config.json +3 -3
  47. package/web/.next/fallback-build-manifest.json +2 -2
  48. package/web/.next/prerender-manifest.json +3 -3
  49. package/web/.next/required-server-files.js +1 -1
  50. package/web/.next/required-server-files.json +1 -1
  51. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +14 -14
  52. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  53. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  54. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +17 -17
  55. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  56. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  57. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +12 -12
  58. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  59. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  60. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +14 -14
  61. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  62. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  63. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +17 -17
  64. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  65. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  66. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +12 -12
  67. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  68. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  69. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +12 -12
  70. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  71. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  72. package/web/.next/server/app/_global-error.html +2 -2
  73. package/web/.next/server/app/_global-error.rsc +1 -1
  74. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  75. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  76. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  77. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  78. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  79. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  80. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  81. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  82. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  83. package/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
  84. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  85. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  86. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  87. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  88. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  89. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_2b7834f6.js +1 -1
  90. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_2b7834f6.js.map +1 -1
  91. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_6923c575.js +1 -1
  92. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_6923c575.js.map +1 -1
  93. package/web/.next/server/chunks/ssr/[root-of-the-server]__07385073._.js +2 -2
  94. package/web/.next/server/chunks/ssr/[root-of-the-server]__07385073._.js.map +1 -1
  95. package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
  96. package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js.map +1 -1
  97. package/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  98. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  99. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  100. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +1 -1
  101. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js.map +1 -1
  102. package/web/.next/server/chunks/ssr/[root-of-the-server]__6db85a66._.js +2 -2
  103. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  104. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  105. package/web/.next/server/chunks/ssr/[root-of-the-server]__8fcb9132._.js +2 -2
  106. package/web/.next/server/chunks/ssr/_00e6c698._.js +1 -1
  107. package/web/.next/server/chunks/ssr/_00e6c698._.js.map +1 -1
  108. package/web/.next/server/chunks/ssr/_07c2a32a._.js +1 -1
  109. package/web/.next/server/chunks/ssr/_07c2a32a._.js.map +1 -1
  110. package/web/.next/server/chunks/ssr/_34a58db8._.js +1 -1
  111. package/web/.next/server/chunks/ssr/_34a58db8._.js.map +1 -1
  112. package/web/.next/server/chunks/ssr/_37259405._.js +1 -1
  113. package/web/.next/server/chunks/ssr/_37259405._.js.map +1 -1
  114. package/web/.next/server/chunks/ssr/{_85d0351b._.js → _63bfa7dd._.js} +2 -2
  115. package/web/.next/server/chunks/ssr/_63bfa7dd._.js.map +1 -0
  116. package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/_e50484ec._.js → server/chunks/ssr/_7215bb0f._.js} +2 -2
  117. package/web/.next/server/chunks/ssr/{_e50484ec._.js.map → _7215bb0f._.js.map} +1 -1
  118. package/web/.next/server/chunks/ssr/_cb5b3951._.js +1 -1
  119. package/web/.next/server/chunks/ssr/_cb5b3951._.js.map +1 -1
  120. package/web/.next/server/chunks/ssr/_fc3a6895._.js +1 -1
  121. package/web/.next/server/chunks/ssr/_fc3a6895._.js.map +1 -1
  122. package/web/.next/server/chunks/ssr/src_presentation_web_1a32dbcb._.js +2 -2
  123. package/web/.next/server/chunks/ssr/src_presentation_web_1a32dbcb._.js.map +1 -1
  124. package/web/.next/server/chunks/ssr/src_presentation_web_398553b0._.js +1 -1
  125. package/web/.next/server/chunks/ssr/src_presentation_web_398553b0._.js.map +1 -1
  126. package/web/.next/server/chunks/ssr/src_presentation_web_5c87e8e4._.js +1 -1
  127. package/web/.next/server/chunks/ssr/src_presentation_web_5c87e8e4._.js.map +1 -1
  128. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f4952172.js +1 -1
  129. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f4952172.js.map +1 -1
  130. package/web/.next/server/chunks/ssr/src_presentation_web_c1bc6240._.js +2 -2
  131. package/web/.next/server/chunks/ssr/src_presentation_web_c1bc6240._.js.map +1 -1
  132. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
  133. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +1 -1
  134. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  135. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  136. package/web/.next/server/pages/500.html +2 -2
  137. package/web/.next/server/server-reference-manifest.js +1 -1
  138. package/web/.next/server/server-reference-manifest.json +20 -20
  139. package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
  140. package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
  141. package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
  142. package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
  143. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +14 -14
  144. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  145. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  146. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +17 -17
  147. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  148. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  149. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +12 -12
  150. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  151. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  152. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +14 -14
  153. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  154. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  155. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +17 -17
  156. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  157. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  158. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +12 -12
  159. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  160. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  161. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +12 -12
  162. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  163. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  164. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
  165. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
  166. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  167. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  168. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  169. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  170. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  171. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  172. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  173. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  174. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  175. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
  176. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  177. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  178. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  179. 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
  180. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_2b7834f6.js +1 -1
  181. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_6923c575.js +1 -1
  182. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__07385073._.js +2 -2
  183. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
  184. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  185. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  186. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +1 -1
  187. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6db85a66._.js +2 -2
  188. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  189. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__8fcb9132._.js +2 -2
  190. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_00e6c698._.js +1 -1
  191. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_07c2a32a._.js +1 -1
  192. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_34a58db8._.js +1 -1
  193. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_37259405._.js +1 -1
  194. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{_85d0351b._.js → _63bfa7dd._.js} +2 -2
  195. package/web/.next/{server/chunks/ssr/_e50484ec._.js → standalone/src/presentation/web/.next/server/chunks/ssr/_7215bb0f._.js} +2 -2
  196. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_cb5b3951._.js +1 -1
  197. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_fc3a6895._.js +1 -1
  198. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_1a32dbcb._.js +2 -2
  199. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_398553b0._.js +1 -1
  200. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_5c87e8e4._.js +1 -1
  201. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f4952172.js +1 -1
  202. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_c1bc6240._.js +2 -2
  203. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
  204. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  205. package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
  206. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
  207. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +20 -20
  208. package/web/.next/standalone/src/presentation/web/app/(dashboard)/get-graph-data.ts +2 -6
  209. package/web/.next/standalone/src/presentation/web/app/build-graph-nodes.ts +14 -1
  210. package/web/.next/standalone/src/presentation/web/components/common/base-drawer/base-drawer.tsx +10 -8
  211. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/create-drawer-client.tsx +13 -3
  212. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx +6 -2
  213. package/web/.next/standalone/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.tsx +2 -0
  214. package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx +8 -5
  215. package/web/.next/standalone/src/presentation/web/components/common/feature-node/feature-node.tsx +30 -24
  216. package/web/.next/standalone/src/presentation/web/components/common/repository-node/repository-node.tsx +33 -25
  217. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +25 -3
  218. package/web/.next/standalone/src/presentation/web/components/features/control-center/use-control-center-state.ts +184 -230
  219. package/web/.next/standalone/src/presentation/web/components/ui/alert-dialog.tsx +7 -0
  220. package/web/.next/standalone/src/presentation/web/components/ui/dialog.tsx +7 -1
  221. package/web/.next/standalone/src/presentation/web/lib/layout-with-dagre.ts +93 -4
  222. package/web/.next/standalone/src/presentation/web/server.js +1 -1
  223. package/web/.next/static/chunks/0c54314c8c9c9739.js +7 -0
  224. package/web/.next/static/chunks/{5f5c607ffae8b918.js → 304c8593d0a6525d.js} +1 -1
  225. package/web/.next/static/chunks/4558d1663c6f4d2c.js +1 -0
  226. package/web/.next/static/chunks/{32957ff277daec59.js → 4df07e765b233622.js} +1 -1
  227. package/web/.next/static/chunks/{fc07834e422b1caa.js → 585ae19c520e8b72.js} +1 -1
  228. package/web/.next/static/chunks/{ecb2130572a7fbe7.js → 6e14d8bd5c005e6e.js} +1 -1
  229. package/web/.next/static/chunks/{412a3ac70c529c5b.js → 8a1eb93510e54db0.js} +1 -1
  230. package/web/.next/static/chunks/{550bf3cb8220cbf0.js → b143c7d78a6888e9.js} +1 -1
  231. package/web/.next/static/chunks/{8b36e07129a1471f.js → b45344579a43cbb8.js} +1 -1
  232. package/web/.next/static/chunks/dec13bccb136ef7c.css +2 -0
  233. package/web/.next/static/chunks/e4522f7d3134eefe.js +1 -0
  234. package/web/.next/static/chunks/{d4ecce2ac7795bd9.js → fe83a799663fd3cc.js} +1 -1
  235. package/web/.next/trace +1 -1
  236. package/web/.next/trace-build +1 -1
  237. package/web/.next/server/chunks/ssr/_85d0351b._.js.map +0 -1
  238. package/web/.next/static/chunks/06b6b02bab76aee7.js +0 -1
  239. package/web/.next/static/chunks/06dfd668334ffb4e.js +0 -7
  240. package/web/.next/static/chunks/224ed5f5dbd33154.css +0 -2
  241. package/web/.next/static/chunks/e44849eb58a3335f.js +0 -1
  242. /package/web/.next/static/{7K6dTYQIJ7__PLUYLLfZV → 9bO_bJBssG0NRxEG03iM5}/_buildManifest.js +0 -0
  243. /package/web/.next/static/{7K6dTYQIJ7__PLUYLLfZV → 9bO_bJBssG0NRxEG03iM5}/_clientMiddlewareManifest.json +0 -0
  244. /package/web/.next/static/{7K6dTYQIJ7__PLUYLLfZV → 9bO_bJBssG0NRxEG03iM5}/_ssgManifest.js +0 -0
@@ -2,12 +2,14 @@
2
2
  * Delete Feature Use Case
3
3
  *
4
4
  * Orchestrates feature deletion including:
5
+ * - Cascade deleting all sub-features (children, grandchildren, etc.)
5
6
  * - Cancelling any running/pending agent runs
6
7
  * - Removing the git worktree
7
8
  * - Deleting the feature record
8
9
  *
9
10
  * Business Rules:
10
11
  * - Throws if the feature does not exist
12
+ * - Cascade deletes all sub-features before deleting the parent
11
13
  * - Cancels running/pending agent runs before deletion
12
14
  * - Gracefully handles worktree removal failures
13
15
  */
@@ -23,5 +25,7 @@ export declare class DeleteFeatureUseCase {
23
25
  private readonly runRepo;
24
26
  constructor(featureRepo: IFeatureRepository, worktreeService: IWorktreeService, processService: IFeatureAgentProcessService, runRepo: IAgentRunRepository);
25
27
  execute(featureId: string): Promise<Feature>;
28
+ private cascadeDeleteChildren;
29
+ private deleteSingleFeature;
26
30
  }
27
31
  //# sourceMappingURL=delete-feature.use-case.d.ts.map
@@ -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;;;;;;;;;;;;GAYG;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;AAEvG,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;gBAJR,WAAW,EAAE,kBAAkB,EACjC,eAAe,EAAE,gBAAgB,EAE7D,cAAc,EAAE,2BAA2B,EACZ,OAAO,EAAE,mBAAmB;IAGxE,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAqDnD"}
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;;;;;;;;;;;;;;GAcG;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;AAEvG,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;gBAJR,WAAW,EAAE,kBAAkB,EACjC,eAAe,EAAE,gBAAgB,EAE7D,cAAc,EAAE,2BAA2B,EACZ,OAAO,EAAE,mBAAmB;IAGxE,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YAkBpC,qBAAqB;YASrB,mBAAmB;CA8BlC"}
@@ -2,12 +2,14 @@
2
2
  * Delete Feature Use Case
3
3
  *
4
4
  * Orchestrates feature deletion including:
5
+ * - Cascade deleting all sub-features (children, grandchildren, etc.)
5
6
  * - Cancelling any running/pending agent runs
6
7
  * - Removing the git worktree
7
8
  * - Deleting the feature record
8
9
  *
9
10
  * Business Rules:
10
11
  * - Throws if the feature does not exist
12
+ * - Cascade deletes all sub-features before deleting the parent
11
13
  * - Cancels running/pending agent runs before deletion
12
14
  * - Gracefully handles worktree removal failures
13
15
  */
@@ -24,7 +26,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
24
26
  return function (target, key) { decorator(target, key, paramIndex); }
25
27
  };
26
28
  import { injectable, inject } from 'tsyringe';
27
- import { AgentRunStatus, SdlcLifecycle } from '../../../domain/generated/output.js';
29
+ import { AgentRunStatus } from '../../../domain/generated/output.js';
28
30
  let DeleteFeatureUseCase = class DeleteFeatureUseCase {
29
31
  featureRepo;
30
32
  worktreeService;
@@ -43,18 +45,25 @@ let DeleteFeatureUseCase = class DeleteFeatureUseCase {
43
45
  if (!feature) {
44
46
  throw new Error(`Feature not found: "${featureId}"`);
45
47
  }
46
- // 2. Guard: reject deletion if blocked children exist (FR-29)
47
- const blockedChildren = (await this.featureRepo.findByParentId(feature.id)).filter((child) => child.lifecycle === SdlcLifecycle.Blocked);
48
- if (blockedChildren.length > 0) {
49
- const list = blockedChildren.map((c) => `${c.id} (${c.name})`).join(', ');
50
- throw new Error(`Cannot delete feature "${feature.name}" because it has blocked children: ${list}. ` +
51
- `Remove or re-parent the blocked children before deleting this feature.`);
48
+ // 2. Cascade delete all sub-features (depth-first)
49
+ await this.cascadeDeleteChildren(feature.id);
50
+ // 3. Delete the feature itself
51
+ await this.deleteSingleFeature(feature);
52
+ return feature;
53
+ }
54
+ async cascadeDeleteChildren(parentId) {
55
+ const children = await this.featureRepo.findByParentId(parentId);
56
+ for (const child of children) {
57
+ // Recurse into grandchildren first (depth-first)
58
+ await this.cascadeDeleteChildren(child.id);
59
+ await this.deleteSingleFeature(child);
52
60
  }
53
- // 3. Cancel running/pending agent run if present
61
+ }
62
+ async deleteSingleFeature(feature) {
63
+ // Cancel running/pending agent run if present
54
64
  if (feature.agentRunId) {
55
65
  const run = await this.runRepo.findById(feature.agentRunId);
56
66
  if (run && (run.status === AgentRunStatus.running || run.status === AgentRunStatus.pending)) {
57
- // Kill the OS process if still alive
58
67
  if (run.pid && this.processService.isAlive(run.pid)) {
59
68
  try {
60
69
  process.kill(run.pid);
@@ -66,7 +75,7 @@ let DeleteFeatureUseCase = class DeleteFeatureUseCase {
66
75
  await this.runRepo.updateStatus(run.id, AgentRunStatus.cancelled);
67
76
  }
68
77
  }
69
- // 4. Remove worktree (ignore errors if already removed)
78
+ // Remove worktree (ignore errors if already removed)
70
79
  const worktreePath = this.worktreeService.getWorktreePath(feature.repositoryPath, feature.branch);
71
80
  try {
72
81
  await this.worktreeService.remove(worktreePath);
@@ -74,9 +83,8 @@ let DeleteFeatureUseCase = class DeleteFeatureUseCase {
74
83
  catch {
75
84
  // Worktree might already be removed - that's fine
76
85
  }
77
- // 5. Delete feature record
86
+ // Delete feature record
78
87
  await this.featureRepo.delete(feature.id);
79
- return feature;
80
88
  }
81
89
  };
82
90
  DeleteFeatureUseCase = __decorate([
@@ -1,13 +1,18 @@
1
1
  /**
2
2
  * Delete Repository Use Case
3
3
  *
4
- * Soft-deletes a Repository by setting its deletedAt timestamp.
5
- * The repository data remains in the database for potential recovery.
4
+ * Deletes a Repository and all its child features.
5
+ * Each feature is properly cleaned up (agent runs cancelled, worktrees removed)
6
+ * via DeleteFeatureUseCase before the repository is soft-deleted.
6
7
  */
7
8
  import type { IRepositoryRepository } from '../../ports/output/repositories/repository-repository.interface.js';
9
+ import type { IFeatureRepository } from '../../ports/output/repositories/feature-repository.interface.js';
10
+ import { DeleteFeatureUseCase } from '../features/delete-feature.use-case.js';
8
11
  export declare class DeleteRepositoryUseCase {
9
12
  private readonly repositoryRepo;
10
- constructor(repositoryRepo: IRepositoryRepository);
13
+ private readonly featureRepo;
14
+ private readonly deleteFeature;
15
+ constructor(repositoryRepo: IRepositoryRepository, featureRepo: IFeatureRepository, deleteFeature: DeleteFeatureUseCase);
11
16
  execute(id: string): Promise<void>;
12
17
  }
13
18
  //# sourceMappingURL=delete-repository.use-case.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"delete-repository.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/repositories/delete-repository.use-case.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oEAAoE,CAAC;AAEhH,qBACa,uBAAuB;IAGhC,OAAO,CAAC,QAAQ,CAAC,cAAc;gBAAd,cAAc,EAAE,qBAAqB;IAGlD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAQzC"}
1
+ {"version":3,"file":"delete-repository.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/repositories/delete-repository.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oEAAoE,CAAC;AAChH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAC1G,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAE9E,qBACa,uBAAuB;IAGhC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAE/B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAE5B,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAJb,cAAc,EAAE,qBAAqB,EAErC,WAAW,EAAE,kBAAkB,EAE/B,aAAa,EAAE,oBAAoB;IAGhD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAczC"}
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * Delete Repository Use Case
3
3
  *
4
- * Soft-deletes a Repository by setting its deletedAt timestamp.
5
- * The repository data remains in the database for potential recovery.
4
+ * Deletes a Repository and all its child features.
5
+ * Each feature is properly cleaned up (agent runs cancelled, worktrees removed)
6
+ * via DeleteFeatureUseCase before the repository is soft-deleted.
6
7
  */
7
8
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
8
9
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -17,22 +18,34 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
17
18
  return function (target, key) { decorator(target, key, paramIndex); }
18
19
  };
19
20
  import { injectable, inject } from 'tsyringe';
21
+ import { DeleteFeatureUseCase } from '../features/delete-feature.use-case.js';
20
22
  let DeleteRepositoryUseCase = class DeleteRepositoryUseCase {
21
23
  repositoryRepo;
22
- constructor(repositoryRepo) {
24
+ featureRepo;
25
+ deleteFeature;
26
+ constructor(repositoryRepo, featureRepo, deleteFeature) {
23
27
  this.repositoryRepo = repositoryRepo;
28
+ this.featureRepo = featureRepo;
29
+ this.deleteFeature = deleteFeature;
24
30
  }
25
31
  async execute(id) {
26
32
  const repository = await this.repositoryRepo.findById(id);
27
33
  if (!repository) {
28
34
  throw new Error(`Repository not found: "${id}"`);
29
35
  }
36
+ // Delete all child features (cancels agent runs, removes worktrees)
37
+ const features = await this.featureRepo.list({ repositoryPath: repository.path });
38
+ for (const feature of features) {
39
+ await this.deleteFeature.execute(feature.id);
40
+ }
30
41
  await this.repositoryRepo.softDelete(id);
31
42
  }
32
43
  };
33
44
  DeleteRepositoryUseCase = __decorate([
34
45
  injectable(),
35
46
  __param(0, inject('IRepositoryRepository')),
36
- __metadata("design:paramtypes", [Object])
47
+ __param(1, inject('IFeatureRepository')),
48
+ __param(2, inject(DeleteFeatureUseCase)),
49
+ __metadata("design:paramtypes", [Object, Object, DeleteFeatureUseCase])
37
50
  ], DeleteRepositoryUseCase);
38
51
  export { DeleteRepositoryUseCase };
@@ -87,7 +87,7 @@ let SQLiteFeatureRepository = class SQLiteFeatureRepository {
87
87
  params.push(filters.lifecycle);
88
88
  }
89
89
  const where = conditions.length > 0 ? ` WHERE ${conditions.join(' AND ')}` : '';
90
- const stmt = this.db.prepare(`SELECT * FROM features${where}`);
90
+ const stmt = this.db.prepare(`SELECT * FROM features${where} ORDER BY created_at ASC`);
91
91
  const rows = stmt.all(...params);
92
92
  return rows.map(fromDatabase);
93
93
  }
@@ -1 +1 @@
1
- {"version":3,"file":"get-graph-data.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/(dashboard)/get-graph-data.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,wBAAsB,YAAY,IAAI,OAAO,CAAC;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAAC,CAqBxF"}
1
+ {"version":3,"file":"get-graph-data.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/(dashboard)/get-graph-data.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,wBAAsB,YAAY,IAAI,OAAO,CAAC;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAAC,CAiBxF"}
@@ -1,5 +1,5 @@
1
1
  import { resolve } from '../../lib/server-container.js';
2
- import { layoutWithDagre } from '../../lib/layout-with-dagre.js';
2
+ import { layoutWithDagre, CANVAS_LAYOUT_DEFAULTS } from '../../lib/layout-with-dagre.js';
3
3
  import { buildGraphNodes } from '../build-graph-nodes.js';
4
4
  export async function getGraphData() {
5
5
  const listFeatures = resolve('ListFeaturesUseCase');
@@ -11,9 +11,5 @@ export async function getGraphData() {
11
11
  return { feature, run };
12
12
  }));
13
13
  const { nodes, edges } = buildGraphNodes(repositories, featuresWithRuns);
14
- return layoutWithDagre(nodes, edges, {
15
- direction: 'LR',
16
- ranksep: 200,
17
- nodesep: 15,
18
- });
14
+ return layoutWithDagre(nodes, edges, CANVAS_LAYOUT_DEFAULTS);
19
15
  }
@@ -84,7 +84,17 @@ export function buildGraphNodes(repositories, featuresWithRuns) {
84
84
  return { nodes, edges };
85
85
  }
86
86
  function appendFeatureNodes(repoFeatures, repoNodeId, allFeaturesWithRuns, nodes, edges) {
87
- repoFeatures.forEach(({ feature, run }) => {
87
+ // Sort by createdAt so newest features appear last (bottom) in the layout
88
+ const sorted = [...repoFeatures].sort((a, b) => {
89
+ const aTime = a.feature.createdAt instanceof Date
90
+ ? a.feature.createdAt.getTime()
91
+ : Number(a.feature.createdAt);
92
+ const bTime = b.feature.createdAt instanceof Date
93
+ ? b.feature.createdAt.getTime()
94
+ : Number(b.feature.createdAt);
95
+ return aTime - bTime;
96
+ });
97
+ sorted.forEach(({ feature, run }) => {
88
98
  const agentNode = run?.result?.startsWith('node:') ? run.result.slice(5) : undefined;
89
99
  const lifecycle = run?.status === 'completed'
90
100
  ? 'maintain'
@@ -7,6 +7,8 @@ export interface BaseDrawerProps extends VariantProps<typeof drawerVariants> {
7
7
  open: boolean;
8
8
  onClose: () => void;
9
9
  modal?: boolean;
10
+ /** When true, clicking anywhere outside the drawer closes it, ignoring `data-no-drawer-close` guards. */
11
+ dismissOnOutsideClick?: boolean;
10
12
  header?: React.ReactNode;
11
13
  children: React.ReactNode;
12
14
  footer?: React.ReactNode;
@@ -14,6 +16,6 @@ export interface BaseDrawerProps extends VariantProps<typeof drawerVariants> {
14
16
  'data-testid'?: string;
15
17
  deployTarget?: DeployActionInput;
16
18
  }
17
- export declare function BaseDrawer({ open, onClose, modal, size, header, children, footer, className, 'data-testid': testId, deployTarget, }: BaseDrawerProps): import("react/jsx-runtime").JSX.Element;
19
+ export declare function BaseDrawer({ open, onClose, modal, dismissOnOutsideClick, size, header, children, footer, className, 'data-testid': testId, deployTarget, }: BaseDrawerProps): import("react/jsx-runtime").JSX.Element;
18
20
  export {};
19
21
  //# sourceMappingURL=base-drawer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"base-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/base-drawer/base-drawer.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAalE,OAAO,EAAmB,KAAK,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAGpF,QAAA,MAAM,cAAc;;8EAUlB,CAAC;AAEH,MAAM,WAAW,eAAgB,SAAQ,YAAY,CAAC,OAAO,cAAc,CAAC;IAC1E,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,iBAAiB,CAAC;CAClC;AAED,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,OAAO,EACP,KAAa,EACb,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,MAAM,EACN,SAAS,EACT,aAAa,EAAE,MAAM,EACrB,YAAY,GACb,EAAE,eAAe,2CA8EjB"}
1
+ {"version":3,"file":"base-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/base-drawer/base-drawer.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAalE,OAAO,EAAmB,KAAK,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAGpF,QAAA,MAAM,cAAc;;8EAUlB,CAAC;AAEH,MAAM,WAAW,eAAgB,SAAQ,YAAY,CAAC,OAAO,cAAc,CAAC;IAC1E,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yGAAyG;IACzG,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,iBAAiB,CAAC;CAClC;AAED,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,OAAO,EACP,KAAa,EACb,qBAA6B,EAC7B,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,MAAM,EACN,SAAS,EACT,aAAa,EAAE,MAAM,EACrB,YAAY,GACb,EAAE,eAAe,2CA6EjB"}
@@ -22,7 +22,7 @@ const drawerVariants = cva('', {
22
22
  size: 'sm',
23
23
  },
24
24
  });
25
- export function BaseDrawer({ open, onClose, modal = false, size, header, children, footer, className, 'data-testid': testId, deployTarget, }) {
25
+ export function BaseDrawer({ open, onClose, modal = false, dismissOnOutsideClick = false, size, header, children, footer, className, 'data-testid': testId, deployTarget, }) {
26
26
  const contentRef = useRef(null);
27
27
  // Close when clicking outside the drawer panel (no overlay needed — canvas stays draggable).
28
28
  // Uses `click` (not `pointerdown`) so canvas drags don't trigger this.
@@ -38,14 +38,18 @@ export function BaseDrawer({ open, onClose, modal = false, size, header, childre
38
38
  return;
39
39
  if (contentRef.current?.contains(target))
40
40
  return;
41
- // Don't close when clicking inside the canvas or other Radix overlays
42
- if (target.closest('[data-no-drawer-close], [role="alertdialog"], [role="menu"], [role="listbox"], [data-radix-popper-content-wrapper]'))
41
+ // Don't close when clicking inside Radix overlays.
42
+ // When dismissOnOutsideClick is false (default), also respect data-no-drawer-close guards.
43
+ const ignoreSelector = dismissOnOutsideClick
44
+ ? '[role="alertdialog"], [role="dialog"], [role="menu"], [role="listbox"], [data-radix-popper-content-wrapper]'
45
+ : '[data-no-drawer-close], [role="alertdialog"], [role="dialog"], [role="menu"], [role="listbox"], [data-radix-popper-content-wrapper]';
46
+ if (target.closest(ignoreSelector))
43
47
  return;
44
48
  onClose();
45
49
  };
46
50
  document.addEventListener('click', handleClick);
47
51
  return () => document.removeEventListener('click', handleClick);
48
- }, [open, modal, onClose]);
52
+ }, [open, modal, onClose, dismissOnOutsideClick]);
49
53
  return (_jsxs(Drawer, { direction: "right", modal: modal, handleOnly: true, open: open, onOpenChange: (isOpen) => {
50
54
  if (!isOpen)
51
55
  onClose();
@@ -1 +1 @@
1
- {"version":3,"file":"create-drawer-client.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/control-center-drawer/create-drawer-client.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iEAAiE,CAAC;AAC3G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAG5E,MAAM,WAAW,uBAAuB;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED,wBAAgB,kBAAkB,CAAC,EACjC,cAAc,EACd,eAAe,EACf,QAAQ,EACR,gBAAgB,GACjB,EAAE,uBAAuB,2CAqEzB"}
1
+ {"version":3,"file":"create-drawer-client.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/control-center-drawer/create-drawer-client.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iEAAiE,CAAC;AAC3G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAG5E,MAAM,WAAW,uBAAuB;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED,wBAAgB,kBAAkB,CAAC,EACjC,cAAc,EACd,eAAe,EACf,QAAQ,EACR,gBAAgB,GACjB,EAAE,uBAAuB,2CA+EzB"}
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import { useState, useCallback } from 'react';
3
+ import { useState, useCallback, useEffect } from 'react';
4
4
  import { useRouter, usePathname } from 'next/navigation';
5
5
  import { toast } from 'sonner';
6
6
  import { createFeature } from '../../../app/actions/create-feature.js';
@@ -14,8 +14,17 @@ export function CreateDrawerClient({ repositoryPath, initialParentId, features,
14
14
  // content during soft navigation, so this component is NOT unmounted when
15
15
  // navigating to `/`. We watch the pathname and let Vaul handle the close
16
16
  // animation when the path no longer matches the create route.
17
+ // When submitting, force the drawer closed immediately — router.push('/')
18
+ // is async and the pathname may not update before the next render.
17
19
  const pathname = usePathname();
18
- const isOpen = pathname.startsWith('/create');
20
+ const isOpen = !isSubmitting && pathname.startsWith('/create');
21
+ // Safety net: if the drawer is closed (e.g. via form submit + isSubmitting)
22
+ // but router.push('/') hasn't taken effect yet, force-clear the route.
23
+ useEffect(() => {
24
+ if (!isOpen && pathname.startsWith('/create')) {
25
+ router.replace('/');
26
+ }
27
+ }, [isOpen, pathname, router]);
19
28
  const onClose = useCallback(() => {
20
29
  router.push('/');
21
30
  }, [router]);
@@ -27,6 +36,7 @@ export function CreateDrawerClient({ repositoryPath, initialParentId, features,
27
36
  name: data.name,
28
37
  description: data.description,
29
38
  repositoryPath: data.repositoryPath,
39
+ parentId: data.parentId,
30
40
  },
31
41
  }));
32
42
  // Close the drawer immediately for responsive UI
@@ -41,7 +51,6 @@ export function CreateDrawerClient({ repositoryPath, initialParentId, features,
41
51
  return;
42
52
  }
43
53
  createSound.play();
44
- router.refresh();
45
54
  })
46
55
  .catch(() => {
47
56
  toast.error('Failed to create feature');
@@ -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":"AA2DA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,UAAU,CAAC;CAClB;AAED,wBAAgB,mBAAmB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,wBAAwB,2CA6lBlF"}
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":"AA2DA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,UAAU,CAAC;CAClB;AAED,wBAAgB,mBAAmB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,wBAAwB,2CAimBlF"}
@@ -65,8 +65,9 @@ export function FeatureDrawerClient({ view: initialView }) {
65
65
  const newState = mapEventTypeToState(event.eventType);
66
66
  const newLifecycle = mapPhaseNameToLifecycle(event.phaseName);
67
67
  // Trigger a server refresh to get the latest drawer view,
68
- // but skip when the user has unsaved changes to avoid losing form state.
69
- if (!isDirtyRef.current)
68
+ // but skip when the user has unsaved changes or a rejection is in-flight
69
+ // to avoid the refresh interfering with the reject handler's navigation.
70
+ if (!isDirtyRef.current && !isRejectingRef.current)
70
71
  router.refresh();
71
72
  // Optimistically update the node data for immediate UI feedback
72
73
  setView((prev) => {
@@ -115,6 +116,7 @@ export function FeatureDrawerClient({ view: initialView }) {
115
116
  const [isDeleting, setIsDeleting] = useState(false);
116
117
  // ── Shared reject state ────────────────────────────────────────────────
117
118
  const [isRejecting, setIsRejecting] = useState(false);
119
+ const isRejectingRef = useRef(false);
118
120
  // Reset chat input whenever the view type changes
119
121
  const viewType = view.type;
120
122
  useEffect(() => {
@@ -267,6 +269,7 @@ export function FeatureDrawerClient({ view: initialView }) {
267
269
  const handleReject = useCallback(async (feedback, label, onDone) => {
268
270
  if (!reviewNode?.featureId)
269
271
  return;
272
+ isRejectingRef.current = true;
270
273
  setIsRejecting(true);
271
274
  try {
272
275
  const result = await rejectFeature(reviewNode.featureId, feedback);
@@ -284,6 +287,7 @@ export function FeatureDrawerClient({ view: initialView }) {
284
287
  onDone?.();
285
288
  }
286
289
  finally {
290
+ isRejectingRef.current = false;
287
291
  setIsRejecting(false);
288
292
  }
289
293
  }, [reviewNode, onClose, rejectSound]);
@@ -1 +1 @@
1
- {"version":3,"file":"drawer-action-bar.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAEvE,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,mBAAmB,EACnB,YAAoB,EACpB,WAAmB,EACnB,QAAQ,EACR,SAAS,EAAE,mBAAmB,EAC9B,iBAAiB,GAClB,EAAE,oBAAoB,2CAoEtB"}
1
+ {"version":3,"file":"drawer-action-bar.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAEvE,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,mBAAmB,EACnB,YAAoB,EACpB,WAAmB,EACnB,QAAQ,EACR,SAAS,EAAE,mBAAmB,EAC9B,iBAAiB,GAClB,EAAE,oBAAoB,2CAsEtB"}
@@ -19,7 +19,7 @@ export function DrawerActionBar({ onReject, onApprove, approveLabel, approveIcon
19
19
  onReject(text);
20
20
  setChatInput('');
21
21
  }
22
- return (_jsxs("div", { className: "border-border shrink-0 border-t", children: [children, onReject ? (_jsxs("form", { onSubmit: handleRevisionSubmit, className: "flex items-center gap-2 p-4", children: [_jsx(Input, { type: "text", placeholder: revisionPlaceholder ?? 'Ask AI to revise...', "aria-label": revisionPlaceholder ?? 'Ask AI to revise...', disabled: disabled, value: chatInput, onChange: (e) => setChatInput(e.target.value), className: "flex-1" }), _jsx(Button, { type: "submit", variant: "secondary", size: "icon", "aria-label": "Send", disabled: disabled, children: _jsx(Send, {}) }), _jsxs(Button, { type: "button", disabled: disabled, onClick: () => {
22
+ return (_jsxs("div", { className: "border-border shrink-0 border-t", children: [children, onReject ? (_jsxs("form", { onSubmit: handleRevisionSubmit, className: "flex items-center gap-2 p-4", children: [_jsx(Input, { type: "text", placeholder: revisionPlaceholder ?? 'Ask AI to revise...', "aria-label": revisionPlaceholder ?? 'Ask AI to revise...', disabled: disabled, value: chatInput, onChange: (e) => setChatInput(e.target.value), className: "flex-1", "data-testid": "drawer-chat-input" }), _jsx(Button, { type: "submit", variant: "secondary", size: "icon", "aria-label": "Send", disabled: disabled, "data-testid": "drawer-chat-send", children: _jsx(Send, {}) }), _jsxs(Button, { type: "button", disabled: disabled, onClick: () => {
23
23
  approveSound.play();
24
24
  onApprove();
25
25
  }, children: [approveIcon, approveLabel] })] })) : (_jsx("div", { className: "flex items-center gap-2 px-4 pb-4", children: _jsxs(Button, { type: "button", className: "flex-1", disabled: disabled, onClick: () => {
@@ -1 +1 @@
1
- {"version":3,"file":"feature-create-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0DAA0D,CAAC;AAC/F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAG5E,YAAY,EAAE,cAAc,EAAE,MAAM,0DAA0D,CAAC;AAE/F,0DAA0D;AAC1D,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE;QACb,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,OAAO,CAAC;QACnB,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC;IACF,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAcD,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC/C,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACjC,kGAAkG;IAClG,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,cAAc,EACd,YAAoB,EACpB,gBAAgB,EAChB,QAAQ,EACR,eAAe,GAChB,EAAE,wBAAwB,2CA2Q1B"}
1
+ {"version":3,"file":"feature-create-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0DAA0D,CAAC;AAC/F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAG5E,YAAY,EAAE,cAAc,EAAE,MAAM,0DAA0D,CAAC;AAE/F,0DAA0D;AAC1D,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE;QACb,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,OAAO,CAAC;QACnB,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC;IACF,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAcD,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC/C,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACjC,kGAAkG;IAClG,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,cAAc,EACd,YAAoB,EACpB,gBAAgB,EAChB,QAAQ,EACR,eAAe,GAChB,EAAE,wBAAwB,2CA8Q1B"}
@@ -114,7 +114,7 @@ export function FeatureCreateDrawer({ open, onClose, onSubmit, repositoryPath, i
114
114
  setAttachments((prev) => prev.filter((f) => f.path !== path));
115
115
  }, []);
116
116
  const hasFeatures = features && features.length > 0;
117
- return (_jsx(BaseDrawer, { open: open, onClose: attemptClose, size: "md", modal: false, "data-testid": "feature-create-drawer", header: _jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "h-2.5 w-2.5 shrink-0 rounded-full bg-blue-500" }), _jsx(DrawerTitle, { children: "NEW FEATURE" })] }), _jsx(DrawerDescription, { asChild: true, children: _jsx("div", { children: _jsx(Badge, { variant: "secondary", children: "Creating..." }) }) })] }), footer: _jsxs("div", { className: "flex flex-row justify-end gap-2", children: [_jsx(Button, { variant: "outline", onClick: attemptClose, disabled: isSubmitting, children: "Cancel" }), _jsx(Button, { type: "submit", form: "create-feature-form", disabled: !name.trim() || isSubmitting, children: isSubmitting ? 'Creating...' : '+ Create Feature' })] }), children: _jsx("div", { className: "overflow-y-auto p-4", children: _jsxs("form", { id: "create-feature-form", onSubmit: handleSubmit, className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { htmlFor: "feature-name", className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "FEATURE NAME" }), _jsx(Input, { id: "feature-name", placeholder: "e.g. GitHub OAuth Login", value: name, onChange: (e) => setName(e.target.value), required: true, disabled: isSubmitting })] }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { htmlFor: "feature-description", className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "DESCRIPTION" }), _jsx(Textarea, { id: "feature-description", placeholder: "Describe what this feature does...", value: description, onChange: (e) => setDescription(e.target.value), rows: 4, disabled: isSubmitting })] }), hasFeatures ? (_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { htmlFor: "parent-feature", className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "PARENT FEATURE" }), _jsx(ParentFeatureCombobox, { features: features, value: parentId, onChange: setParentId, disabled: isSubmitting })] })) : null, _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "APPROVE" }), _jsx(CheckboxGroup, { label: "Autonomous Mode", description: "YOLO!", parentAriaLabel: "Auto approve all", options: AUTO_APPROVE_OPTIONS, value: approvalGates, onValueChange: setApprovalGates, disabled: isSubmitting })] }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "GIT" }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(CheckboxGroupItem, { id: "push", label: "Push", description: "Push branch to remote after implementation.", checked: push || openPr, onCheckedChange: setPush, disabled: openPr || isSubmitting }), _jsx(CheckboxGroupItem, { id: "open-pr", label: "Create PR", description: "Open a pull request after pushing.", checked: openPr, onCheckedChange: setOpenPr, disabled: isSubmitting })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs(Label, { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: ["ATTACHMENTS", attachments.length > 0 && (_jsxs("span", { className: "text-muted-foreground/60 ml-1.5", children: ["(", attachments.length, ")"] }))] }), _jsxs(Button, { type: "button", variant: "outline", size: "xs", onClick: handleAddFiles, disabled: isSubmitting, children: [_jsx(PlusIcon, { className: "size-3" }), "Add Files"] })] }), attachments.length > 0 && (_jsx("div", { className: "flex flex-col gap-2", children: attachments.map((file) => (_jsx(AttachmentCard, { file: file, onRemove: () => handleRemoveFile(file.path), disabled: isSubmitting }, file.path))) }))] })] }) }) }));
117
+ return (_jsx(BaseDrawer, { open: open, onClose: attemptClose, size: "md", modal: false, dismissOnOutsideClick: true, "data-testid": "feature-create-drawer", header: _jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "h-2.5 w-2.5 shrink-0 rounded-full bg-blue-500" }), _jsx(DrawerTitle, { children: "NEW FEATURE" })] }), isSubmitting ? (_jsx(DrawerDescription, { asChild: true, children: _jsx("div", { children: _jsx(Badge, { variant: "secondary", children: "Creating..." }) }) })) : null] }), footer: _jsxs("div", { className: "flex flex-row justify-end gap-2", children: [_jsx(Button, { variant: "outline", onClick: attemptClose, disabled: isSubmitting, children: "Cancel" }), _jsx(Button, { type: "submit", form: "create-feature-form", disabled: !name.trim() || isSubmitting, children: isSubmitting ? 'Creating...' : '+ Create Feature' })] }), children: _jsx("div", { className: "overflow-y-auto p-4", children: _jsxs("form", { id: "create-feature-form", onSubmit: handleSubmit, className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { htmlFor: "feature-name", className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "FEATURE NAME" }), _jsx(Input, { id: "feature-name", placeholder: "e.g. GitHub OAuth Login", value: name, onChange: (e) => setName(e.target.value), required: true, disabled: isSubmitting })] }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { htmlFor: "feature-description", className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "DESCRIPTION" }), _jsx(Textarea, { id: "feature-description", placeholder: "Describe what this feature does...", value: description, onChange: (e) => setDescription(e.target.value), rows: 4, disabled: isSubmitting })] }), hasFeatures ? (_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { htmlFor: "parent-feature", className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "PARENT FEATURE" }), _jsx(ParentFeatureCombobox, { features: features, value: parentId, onChange: setParentId, disabled: isSubmitting })] })) : null, _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "APPROVE" }), _jsx(CheckboxGroup, { label: "Autonomous Mode", description: "YOLO!", parentAriaLabel: "Auto approve all", options: AUTO_APPROVE_OPTIONS, value: approvalGates, onValueChange: setApprovalGates, disabled: isSubmitting })] }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "GIT" }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(CheckboxGroupItem, { id: "push", label: "Push", description: "Push branch to remote after implementation.", checked: push || openPr, onCheckedChange: setPush, disabled: openPr || isSubmitting }), _jsx(CheckboxGroupItem, { id: "open-pr", label: "Create PR", description: "Open a pull request after pushing.", checked: openPr, onCheckedChange: setOpenPr, disabled: isSubmitting })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs(Label, { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: ["ATTACHMENTS", attachments.length > 0 && (_jsxs("span", { className: "text-muted-foreground/60 ml-1.5", children: ["(", attachments.length, ")"] }))] }), _jsxs(Button, { type: "button", variant: "outline", size: "xs", onClick: handleAddFiles, disabled: isSubmitting, children: [_jsx(PlusIcon, { className: "size-3" }), "Add Files"] })] }), attachments.length > 0 && (_jsx("div", { className: "flex flex-col gap-2", children: attachments.map((file) => (_jsx(AttachmentCard, { file: file, onRemove: () => handleRemoveFile(file.path), disabled: isSubmitting }, file.path))) }))] })] }) }) }));
118
118
  }
119
119
  function ParentFeatureCombobox({ features, value, onChange, disabled, }) {
120
120
  const [open, setOpen] = useState(false);
@@ -1 +1 @@
1
- {"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAwDnE,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,2CA4NA"}
1
+ {"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAwDnE,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,2CAkOA"}
@@ -4,7 +4,8 @@ import { useState } from 'react';
4
4
  import { Handle, Position } from '@xyflow/react';
5
5
  import { Settings, Plus, FileText, Wrench, GitMerge, Trash2 } from 'lucide-react';
6
6
  import { cn } from '../../../lib/utils.js';
7
- import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '../../ui/alert-dialog.js';
7
+ import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '../../ui/dialog.js';
8
+ import { Button } from '../../ui/button.js';
8
9
  import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../ui/tooltip.js';
9
10
  import { featureNodeStateConfig, lifecycleDisplayLabels, lifecycleRunningVerbs, } from './feature-node-state-config.js';
10
11
  import { getAgentTypeIcon } from './agent-type-icons.js';
@@ -68,7 +69,11 @@ export function FeatureNode({ data, selected, }) {
68
69
  return (_jsxs("div", { className: "group relative", children: [data.showHandles ? (_jsx(Handle, { type: "target", position: Position.Left, isConnectable: false, className: "opacity-0!" })) : null, data.onDelete && data.featureId ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "absolute top-1/2 -left-10 -translate-y-1/2 opacity-0 transition-opacity group-hover:opacity-100", children: _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { "aria-label": "Delete feature", "data-testid": "feature-node-delete-button", onClick: (e) => {
69
70
  e.stopPropagation();
70
71
  setConfirmOpen(true);
71
- }, 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(AlertDialog, { open: confirmOpen, onOpenChange: setConfirmOpen, children: _jsxs(AlertDialogContent, { size: "sm", children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Delete feature?" }), _jsxs(AlertDialogDescription, { children: ["This will permanently delete ", _jsx("strong", { children: data.name }), " and all associated data including specs, branches, and progress."] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: "Cancel" }), _jsx(AlertDialogAction, { variant: "destructive", onClick: () => data.onDelete?.(data.featureId), children: "Delete" })] })] }) })] })) : null, _jsxs("div", { "data-testid": "feature-node-card", "aria-busy": data.state === 'creating' ? 'true' : undefined, className: cn('bg-card flex min-h-35 w-72 flex-col rounded-lg border p-3 shadow-sm', selected && 'ring-primary ring-2'), 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] }), data.onSettings ? (_jsx("button", { type: "button", "aria-label": "Settings", "data-testid": "feature-node-settings-button", onClick: (e) => {
72
+ }, 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(Dialog, { open: confirmOpen, onOpenChange: setConfirmOpen, children: _jsxs(DialogContent, { className: "max-w-xs", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Delete feature?" }), _jsxs(DialogDescription, { children: ["This will permanently delete ", _jsx("strong", { children: data.name }), " and all associated data including specs, branches, and progress."] })] }), _jsxs(DialogFooter, { className: "grid grid-cols-2 gap-2 sm:flex-none", children: [_jsx(DialogClose, { asChild: true, children: _jsx(Button, { variant: "outline", children: "Cancel" }) }), _jsx(Button, { variant: "destructive", onClick: (e) => {
73
+ e.stopPropagation();
74
+ setConfirmOpen(false);
75
+ data.onDelete?.(data.featureId);
76
+ }, children: "Delete" })] })] }) })] })) : null, _jsxs("div", { "data-testid": "feature-node-card", "aria-busy": data.state === 'creating' ? 'true' : undefined, className: cn('bg-card flex min-h-35 w-72 flex-col rounded-lg border p-3 shadow-sm', selected && 'ring-primary ring-2'), 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] }), data.onSettings ? (_jsx("button", { type: "button", "aria-label": "Settings", "data-testid": "feature-node-settings-button", onClick: (e) => {
72
77
  e.stopPropagation();
73
78
  data.onSettings?.();
74
79
  }, className: "nodrag text-muted-foreground hover:text-foreground -mt-1 -mr-1 p-1", children: _jsx(Settings, { className: "h-3.5 w-3.5" }) })) : null] }), _jsx("h3", { className: "mt-1 truncate text-sm font-bold", children: data.name }), data.description ? (_jsx("p", { "data-testid": "feature-node-description", className: "text-muted-foreground mt-0.5 truncate text-xs", children: data.description })) : null, _jsx("div", { className: "mt-auto pt-2", children: data.state === 'creating' ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mt-1.5 flex items-center gap-1.5 text-xs", children: [_jsx(Icon, { className: "h-3.5 w-3.5 shrink-0 animate-spin" }), _jsx("span", { className: "text-muted-foreground", children: getBadgeText(data) })] }), _jsx("div", { "data-testid": "feature-node-progress-bar", className: "bg-muted mt-1.5 h-1 w-full overflow-hidden rounded-full", children: _jsx("div", { className: "motion-safe:animate-indeterminate-progress bg-foreground/30 h-full w-1/3 rounded-full" }) })] })) : data.state === 'running' ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mt-1.5 flex items-center gap-1.5 text-xs", children: [_jsx(AgentIcon, { agentType: data.agentType, className: "h-3.5 w-3.5 shrink-0" }), _jsx("span", { className: "text-muted-foreground", children: getBadgeText(data) })] }), _jsx("div", { "data-testid": "feature-node-progress-bar", className: "bg-muted mt-1.5 h-1 w-full overflow-hidden rounded-full", children: _jsx("div", { className: "animate-indeterminate-progress bg-foreground/30 h-full w-1/3 rounded-full" }) })] })) : config.showProgressBar ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "text-muted-foreground flex items-center justify-end text-[10px]", children: _jsxs("span", { children: [data.progress, "%"] }) }), _jsx("div", { "data-testid": "feature-node-progress-bar", className: "bg-muted mt-1.5 h-1 w-full overflow-hidden rounded-full", children: _jsx("div", { className: cn('h-full rounded-full transition-all', config.progressClass), style: { width: `${data.progress}%` } }) })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "text-muted-foreground text-[10px]", children: _jsx("span", { children: data.featureId }) }), _jsxs("div", { "data-testid": "feature-node-badge", className: (() => {
@@ -1 +1 @@
1
- {"version":3,"file":"repository-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAGnE,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,2CAqO5F"}
1
+ {"version":3,"file":"repository-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAGnE,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,2CA6O5F"}
@@ -5,7 +5,8 @@ import { Handle, Position } from '@xyflow/react';
5
5
  import { Github, Plus, Code2, Terminal, FolderOpen, Trash2, Play, Square } from 'lucide-react';
6
6
  import { cn } from '../../../lib/utils.js';
7
7
  import { ActionButton } from '../../common/action-button/index.js';
8
- import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '../../ui/alert-dialog.js';
8
+ import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '../../ui/dialog.js';
9
+ import { Button } from '../../ui/button.js';
9
10
  import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../ui/tooltip.js';
10
11
  import { DeploymentStatusBadge } from '../../common/deployment-status-badge/index.js';
11
12
  import { useDeployAction } from '../../../hooks/use-deploy-action.js';
@@ -25,7 +26,10 @@ export function RepositoryNode({ data }) {
25
26
  return (_jsxs("div", { className: "group relative", children: [data.showHandles ? (_jsx(Handle, { type: "target", position: Position.Left, isConnectable: false, className: "opacity-0!" })) : null, data.onDelete && data.id ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "absolute top-1/2 -left-10 -translate-y-1/2 opacity-0 transition-opacity group-hover:opacity-100", children: _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { "aria-label": "Remove repository", "data-testid": "repository-node-delete-button", onClick: (e) => {
26
27
  e.stopPropagation();
27
28
  setConfirmOpen(true);
28
- }, className: "bg-card text-muted-foreground hover:border-destructive hover:text-destructive flex h-7 w-7 cursor-pointer items-center justify-center rounded-full border shadow-sm transition-colors", children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Remove repository" })] }) }) }), _jsx(AlertDialog, { open: confirmOpen, onOpenChange: setConfirmOpen, children: _jsxs(AlertDialogContent, { size: "sm", children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Remove repository?" }), _jsxs(AlertDialogDescription, { children: ["This will remove ", _jsx("strong", { children: data.name }), " from your workspace. The repository files on disk won't be affected."] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: "Cancel" }), _jsx(AlertDialogAction, { variant: "destructive", onClick: () => data.onDelete?.(data.id), children: "Remove" })] })] }) })] })) : null, _jsxs("div", { role: "button", tabIndex: 0, "data-testid": "repository-node-card", "data-repo-name": data.name, onClick: (e) => {
29
+ }, className: "bg-card text-muted-foreground hover:border-destructive hover:text-destructive flex h-7 w-7 cursor-pointer items-center justify-center rounded-full border shadow-sm transition-colors", children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Remove repository" })] }) }) }), _jsx(Dialog, { open: confirmOpen, onOpenChange: setConfirmOpen, children: _jsxs(DialogContent, { className: "max-w-xs", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Remove repository?" }), _jsxs(DialogDescription, { children: ["This will remove ", _jsx("strong", { children: data.name }), " and all its features from your workspace. The repository files on disk won't be affected."] })] }), _jsxs(DialogFooter, { className: "grid grid-cols-2 gap-2 sm:flex-none", children: [_jsx(DialogClose, { asChild: true, children: _jsx(Button, { variant: "outline", children: "Cancel" }) }), _jsx(Button, { variant: "destructive", onClick: () => {
30
+ setConfirmOpen(false);
31
+ data.onDelete?.(data.id);
32
+ }, children: "Remove" })] })] }) })] })) : null, _jsxs("div", { role: "button", tabIndex: 0, "data-testid": "repository-node-card", "data-repo-name": data.name, onClick: (e) => {
29
33
  e.stopPropagation();
30
34
  data.onClick?.();
31
35
  }, onKeyDown: (e) => {
@@ -1 +1 @@
1
- {"version":3,"file":"control-center-inner.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-inner.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAc5E,UAAU,uBAAuB;IAC/B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,YAAY,EAAE,IAAI,EAAE,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,uBAAuB,2CAsMzF"}
1
+ {"version":3,"file":"control-center-inner.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-inner.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAc5E,UAAU,uBAAuB;IAC/B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,YAAY,EAAE,IAAI,EAAE,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,uBAAuB,2CA4NzF"}
@@ -15,8 +15,8 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
15
15
  const pathname = usePathname();
16
16
  const selectedFeatureId = useSelectedFeatureId();
17
17
  const clickSound = useSoundAction('click');
18
- const { guardedNavigate, getIsDirty } = useDrawerCloseGuard();
19
- const { nodes, edges, onNodesChange, handleConnect, handleAddRepository, handleDeleteFeature, handleDeleteRepository, createFeatureNode, } = useControlCenterState(initialNodes, initialEdges, getIsDirty);
18
+ const { guardedNavigate } = useDrawerCloseGuard();
19
+ const { nodes, edges, onNodesChange, handleConnect, handleAddRepository, handleDeleteFeature, handleDeleteRepository, createFeatureNode, } = useControlCenterState(initialNodes, initialEdges);
20
20
  // Publish sidebar features to context whenever feature node data changes
21
21
  const { setFeatures: setSidebarFeatures } = useSidebarFeaturesContext();
22
22
  const sidebarKey = useMemo(() => {
@@ -116,6 +116,18 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
116
116
  useEffect(() => {
117
117
  const handler = (e) => {
118
118
  const detail = e.detail;
119
+ // When a parentId is provided, connect to the parent feature node
120
+ // via a dependency edge instead of the repo node.
121
+ if (detail.parentId) {
122
+ const parentNodeId = `feat-${detail.parentId}`;
123
+ createFeatureNode(parentNodeId, {
124
+ state: 'creating',
125
+ name: detail.name,
126
+ description: detail.description,
127
+ repositoryPath: detail.repositoryPath,
128
+ }, 'dependencyEdge');
129
+ return;
130
+ }
119
131
  // Find the repo node to connect to
120
132
  const repoNode = nodes.find((n) => n.type === 'repositoryNode' &&
121
133
  n.data.repositoryPath === detail.repositoryPath);
@@ -9,11 +9,9 @@ export interface ControlCenterState {
9
9
  handleConnect: (connection: Connection) => void;
10
10
  handleAddRepository: (path: string) => void;
11
11
  handleLayout: (direction: LayoutDirection) => void;
12
- handleDeleteFeature: (featureId: string) => Promise<void>;
12
+ handleDeleteFeature: (featureId: string) => void;
13
13
  handleDeleteRepository: (repositoryId: string) => Promise<void>;
14
- createFeatureNode: (sourceNodeId: string | null, dataOverride?: Partial<FeatureNodeData>) => string;
14
+ createFeatureNode: (sourceNodeId: string | null, dataOverride?: Partial<FeatureNodeData>, edgeType?: string) => string;
15
15
  }
16
- export declare function useControlCenterState(initialNodes: CanvasNodeType[], initialEdges: Edge[],
17
- /** When true, background router.refresh() calls (polling / SSE debounce) are suppressed. */
18
- isRefreshBlocked?: () => boolean): ControlCenterState;
16
+ export declare function useControlCenterState(initialNodes: CanvasNodeType[], initialEdges: Edge[]): ControlCenterState;
19
17
  //# sourceMappingURL=use-control-center-state.d.ts.map
@@ -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":"AAMA,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,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAWhF,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,IAAI,CAAC;IAC5C,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,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,KACpC,MAAM,CAAC;CACb;AAID,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE;AACpB,4FAA4F;AAC5F,gBAAgB,CAAC,EAAE,MAAM,OAAO,GAC/B,kBAAkB,CAgiBpB"}
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":"AAMA,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,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAWjC,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,IAAI,CAAC;IAC5C,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,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;CACb;AAID,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,kBAAkB,CA+epB"}