@shepai/cli 1.22.1 → 1.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. package/dist/packages/core/src/infrastructure/services/file-dialog.service.d.ts +28 -0
  2. package/dist/packages/core/src/infrastructure/services/file-dialog.service.d.ts.map +1 -0
  3. package/dist/packages/core/src/infrastructure/services/file-dialog.service.js +63 -0
  4. package/dist/src/presentation/web/app/api/dialog/pick-files/route.d.ts +11 -0
  5. package/dist/src/presentation/web/app/api/dialog/pick-files/route.d.ts.map +1 -0
  6. package/dist/src/presentation/web/app/api/dialog/pick-files/route.js +16 -0
  7. package/dist/src/presentation/web/app/derive-state.d.ts +12 -0
  8. package/dist/src/presentation/web/app/derive-state.d.ts.map +1 -0
  9. package/dist/src/presentation/web/app/derive-state.js +21 -0
  10. package/dist/src/presentation/web/app/page.d.ts.map +1 -1
  11. package/dist/src/presentation/web/app/page.js +23 -12
  12. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts +15 -0
  13. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -0
  14. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +102 -0
  15. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts +63 -0
  16. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts.map +1 -0
  17. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.js +164 -0
  18. package/dist/src/presentation/web/components/common/feature-create-drawer/index.d.ts +2 -0
  19. package/dist/src/presentation/web/components/common/feature-create-drawer/index.d.ts.map +1 -0
  20. package/dist/src/presentation/web/components/common/feature-create-drawer/index.js +1 -0
  21. package/dist/src/presentation/web/components/common/feature-create-drawer/pick-files.d.ts +7 -0
  22. package/dist/src/presentation/web/components/common/feature-create-drawer/pick-files.d.ts.map +1 -0
  23. package/dist/src/presentation/web/components/common/feature-create-drawer/pick-files.js +13 -0
  24. package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.d.ts +7 -0
  25. package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.d.ts.map +1 -0
  26. package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.js +28 -0
  27. package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.stories.d.ts +19 -0
  28. package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.stories.d.ts.map +1 -0
  29. package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.stories.js +167 -0
  30. package/dist/src/presentation/web/components/common/feature-drawer/index.d.ts +2 -0
  31. package/dist/src/presentation/web/components/common/feature-drawer/index.d.ts.map +1 -0
  32. package/dist/src/presentation/web/components/common/feature-drawer/index.js +1 -0
  33. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +2 -5
  34. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +1 -1
  35. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.js +4 -13
  36. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  37. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +7 -9
  38. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts +0 -1
  39. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts.map +1 -1
  40. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.js +4 -23
  41. package/dist/src/presentation/web/components/common/feature-node/index.d.ts +1 -3
  42. package/dist/src/presentation/web/components/common/feature-node/index.d.ts.map +1 -1
  43. package/dist/src/presentation/web/components/common/feature-node/index.js +1 -3
  44. package/dist/src/presentation/web/components/common/index.d.ts +2 -0
  45. package/dist/src/presentation/web/components/common/index.d.ts.map +1 -1
  46. package/dist/src/presentation/web/components/common/index.js +2 -0
  47. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  48. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +11 -3
  49. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +4 -0
  50. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  51. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +20 -4
  52. package/dist/src/presentation/web/components/layouts/app-shell/app-shell.d.ts +1 -1
  53. package/dist/src/presentation/web/components/layouts/app-shell/app-shell.d.ts.map +1 -1
  54. package/dist/src/presentation/web/components/layouts/app-shell/app-shell.js +5 -1
  55. package/dist/src/presentation/web/components/ui/button.d.ts +1 -1
  56. package/dist/src/presentation/web/components/ui/drawer.d.ts +17 -0
  57. package/dist/src/presentation/web/components/ui/drawer.d.ts.map +1 -0
  58. package/dist/src/presentation/web/components/ui/drawer.js +45 -0
  59. package/dist/src/presentation/web/components/ui/drawer.stories.d.ts +17 -0
  60. package/dist/src/presentation/web/components/ui/drawer.stories.d.ts.map +1 -0
  61. package/dist/src/presentation/web/components/ui/drawer.stories.js +29 -0
  62. package/dist/src/presentation/web/components/ui/textarea.d.ts +4 -0
  63. package/dist/src/presentation/web/components/ui/textarea.d.ts.map +1 -0
  64. package/dist/src/presentation/web/components/ui/textarea.js +6 -0
  65. package/dist/src/presentation/web/components/ui/textarea.stories.d.ts +10 -0
  66. package/dist/src/presentation/web/components/ui/textarea.stories.d.ts.map +1 -0
  67. package/dist/src/presentation/web/components/ui/textarea.stories.js +28 -0
  68. package/dist/src/presentation/web/lib/features.d.ts +30 -0
  69. package/dist/src/presentation/web/lib/features.d.ts.map +1 -0
  70. package/dist/src/presentation/web/lib/features.js +50 -0
  71. package/dist/tsconfig.build.tsbuildinfo +1 -1
  72. package/package.json +2 -2
  73. package/web/.next/BUILD_ID +1 -1
  74. package/web/.next/app-path-routes-manifest.json +1 -0
  75. package/web/.next/build-manifest.json +5 -5
  76. package/web/.next/cache/.previewinfo +1 -1
  77. package/web/.next/cache/.rscinfo +1 -1
  78. package/web/.next/cache/.tsbuildinfo +1 -1
  79. package/web/.next/cache/config.json +3 -3
  80. package/web/.next/fallback-build-manifest.json +2 -2
  81. package/web/.next/prerender-manifest.json +3 -3
  82. package/web/.next/required-server-files.js +1 -1
  83. package/web/.next/required-server-files.json +1 -1
  84. package/web/.next/routes-manifest.json +6 -0
  85. package/web/.next/server/app/_global-error/page/build-manifest.json +3 -3
  86. package/web/.next/server/app/_global-error/page.js +1 -1
  87. package/web/.next/server/app/_global-error/page.js.nft.json +1 -1
  88. package/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  89. package/web/.next/server/app/_global-error.html +2 -2
  90. package/web/.next/server/app/_global-error.rsc +1 -1
  91. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  92. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  93. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  94. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  95. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  96. package/web/.next/server/app/_not-found/page/build-manifest.json +3 -3
  97. package/web/.next/server/app/_not-found/page.js +1 -1
  98. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  99. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  100. package/web/.next/server/app/_not-found.html +2 -2
  101. package/web/.next/server/app/_not-found.rsc +9 -9
  102. package/web/.next/server/app/_not-found.segments/_full.segment.rsc +9 -9
  103. package/web/.next/server/app/_not-found.segments/_head.segment.rsc +3 -3
  104. package/web/.next/server/app/_not-found.segments/_index.segment.rsc +5 -5
  105. package/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  106. package/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  107. package/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  108. package/web/.next/server/app/api/dialog/pick-files/route/app-paths-manifest.json +3 -0
  109. package/web/.next/server/app/api/dialog/pick-files/route/build-manifest.json +11 -0
  110. package/web/.next/server/app/api/dialog/pick-files/route/server-reference-manifest.json +4 -0
  111. package/web/.next/server/app/api/dialog/pick-files/route.js +6 -0
  112. package/web/.next/server/app/api/dialog/pick-files/route.js.map +5 -0
  113. package/web/.next/server/app/api/dialog/pick-files/route.js.nft.json +1 -0
  114. package/web/.next/server/app/api/dialog/pick-files/route_client-reference-manifest.js +2 -0
  115. package/web/.next/server/app/api/dialog/pick-folder/route.js +2 -2
  116. package/web/.next/server/app/api/dialog/pick-folder/route.js.nft.json +1 -1
  117. package/web/.next/server/app/index.html +2 -2
  118. package/web/.next/server/app/index.rsc +4 -4
  119. package/web/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  120. package/web/.next/server/app/index.segments/_full.segment.rsc +4 -4
  121. package/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
  122. package/web/.next/server/app/index.segments/_index.segment.rsc +3 -3
  123. package/web/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  124. package/web/.next/server/app/page/build-manifest.json +3 -3
  125. package/web/.next/server/app/page.js +3 -3
  126. package/web/.next/server/app/page.js.nft.json +1 -1
  127. package/web/.next/server/app/page_client-reference-manifest.js +1 -1
  128. package/web/.next/server/app/version/page/build-manifest.json +3 -3
  129. package/web/.next/server/app/version/page.js +1 -1
  130. package/web/.next/server/app/version/page.js.nft.json +1 -1
  131. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  132. package/web/.next/server/app/version.html +2 -2
  133. package/web/.next/server/app/version.rsc +4 -4
  134. package/web/.next/server/app/version.segments/_full.segment.rsc +4 -4
  135. package/web/.next/server/app/version.segments/_head.segment.rsc +1 -1
  136. package/web/.next/server/app/version.segments/_index.segment.rsc +3 -3
  137. package/web/.next/server/app/version.segments/_tree.segment.rsc +2 -2
  138. package/web/.next/server/app/version.segments/version/__PAGE__.segment.rsc +2 -2
  139. package/web/.next/server/app/version.segments/version.segment.rsc +1 -1
  140. package/web/.next/server/app-paths-manifest.json +1 -0
  141. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_dialog_pick-files_route_actions_f9868286.js +3 -0
  142. package/web/.next/server/chunks/[root-of-the-server]__00833626._.js +21 -0
  143. package/web/.next/server/chunks/[root-of-the-server]__00833626._.js.map +1 -0
  144. package/web/.next/server/chunks/[root-of-the-server]__22cabd43._.js +4 -0
  145. package/web/.next/server/chunks/[root-of-the-server]__22cabd43._.js.map +1 -0
  146. package/web/.next/server/chunks/[root-of-the-server]__95785ac7._.js +3 -0
  147. package/web/.next/server/chunks/[root-of-the-server]__95785ac7._.js.map +1 -0
  148. package/web/.next/server/chunks/ssr/403f9_next_dist_esm_build_templates_app-page_dbf21e04.js +1 -1
  149. package/web/.next/server/chunks/ssr/[root-of-the-server]__1eade43f._.js +3 -0
  150. package/web/.next/server/chunks/ssr/[root-of-the-server]__1eade43f._.js.map +1 -0
  151. package/web/.next/server/chunks/ssr/{[root-of-the-server]__6b3c1f2b._.js → [root-of-the-server]__685eaa45._.js} +2 -2
  152. package/web/.next/server/chunks/ssr/[root-of-the-server]__71515c64._.js +3 -0
  153. package/web/.next/server/chunks/ssr/[root-of-the-server]__757c7912._.js +3 -0
  154. package/web/.next/server/chunks/ssr/[root-of-the-server]__7c64f85c._.js +3 -0
  155. package/web/.next/server/chunks/ssr/[root-of-the-server]__7c64f85c._.js.map +1 -0
  156. package/web/.next/server/chunks/ssr/[root-of-the-server]__8507ac68._.js +3 -0
  157. package/web/.next/server/chunks/ssr/[root-of-the-server]__8507ac68._.js.map +1 -0
  158. package/web/.next/server/chunks/ssr/{[root-of-the-server]__e55e9c7f._.js → [root-of-the-server]__dbd220d2._.js} +2 -2
  159. package/web/.next/server/chunks/ssr/[root-of-the-server]__f12b60be._.js +1 -1
  160. package/web/.next/server/chunks/ssr/[root-of-the-server]__fa87595c._.js +1 -1
  161. package/web/.next/server/chunks/ssr/_09afa42a._.js +1 -1
  162. package/web/.next/server/chunks/ssr/_09afa42a._.js.map +1 -1
  163. package/web/.next/server/chunks/ssr/_1f9347c8._.js +7 -0
  164. package/web/.next/server/chunks/ssr/_1f9347c8._.js.map +1 -0
  165. package/web/.next/server/chunks/ssr/_884ddade._.js +1 -1
  166. package/web/.next/server/chunks/ssr/_937b37e2._.js +3 -0
  167. package/web/.next/server/chunks/ssr/_937b37e2._.js.map +1 -0
  168. package/web/.next/server/chunks/ssr/_a0c04017._.js +1 -5
  169. package/web/.next/server/chunks/ssr/_a0c04017._.js.map +1 -1
  170. package/web/.next/server/chunks/ssr/_c5d377cc._.js +1 -1
  171. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_version_version-page-client_tsx_fe9db753._.js +1 -1
  172. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_version_version-page-client_tsx_fe9db753._.js.map +1 -1
  173. package/web/.next/server/chunks/ssr/src_presentation_web_components_ui_badge_tsx_964c2a3b._.js +3 -0
  174. package/web/.next/server/chunks/ssr/src_presentation_web_components_ui_badge_tsx_964c2a3b._.js.map +1 -0
  175. package/web/.next/server/middleware-build-manifest.js +3 -3
  176. package/web/.next/server/pages/404.html +2 -2
  177. package/web/.next/server/pages/500.html +2 -2
  178. package/web/.next/server/server-reference-manifest.js +1 -1
  179. package/web/.next/server/server-reference-manifest.json +1 -1
  180. package/web/.next/static/chunks/4431cc2d3628b6f6.js +1 -0
  181. package/web/.next/static/chunks/49488cbe99543598.css +1 -0
  182. package/web/.next/static/chunks/70993ebedee7eab0.js +2 -0
  183. package/web/.next/static/chunks/8bc34062bc0f4ddc.js +1 -0
  184. package/web/.next/static/chunks/c95b4cf170b7f301.js +1 -0
  185. package/web/.next/static/chunks/df7d29673e0ac11d.js +1 -0
  186. package/web/.next/static/chunks/e78d1b265b8110c3.js +1 -0
  187. package/web/.next/static/chunks/f5099c5888ef9a74.js +5 -0
  188. package/web/.next/static/chunks/{b29c0572633eb9e4.js → f6b5484377f4e78e.js} +2 -2
  189. package/web/.next/static/chunks/{turbopack-e0a0178ee911c212.js → turbopack-a5a88a85e7ac8e8d.js} +1 -1
  190. package/web/.next/trace +1 -1
  191. package/web/.next/trace-build +1 -1
  192. package/web/.next/types/link.d.ts +1 -0
  193. package/web/.next/types/routes.d.ts +2 -1
  194. package/web/.next/types/validator.ts +9 -0
  195. package/web/next.config.mjs +1 -1
  196. package/web/package.json +3 -3
  197. package/web/.next/server/chunks/[externals]_next_dist_a6d89067._.js +0 -3
  198. package/web/.next/server/chunks/[root-of-the-server]__ebcd3642._.js +0 -21
  199. package/web/.next/server/chunks/[root-of-the-server]__ebcd3642._.js.map +0 -1
  200. package/web/.next/server/chunks/ssr/[root-of-the-server]__2127336f._.js +0 -3
  201. package/web/.next/server/chunks/ssr/[root-of-the-server]__44c4e191._.js +0 -3
  202. package/web/.next/server/chunks/ssr/[root-of-the-server]__44c4e191._.js.map +0 -1
  203. package/web/.next/server/chunks/ssr/[root-of-the-server]__492e833d._.js +0 -3
  204. package/web/.next/server/chunks/ssr/[root-of-the-server]__492e833d._.js.map +0 -1
  205. package/web/.next/server/chunks/ssr/[root-of-the-server]__80e5bed2._.js +0 -3
  206. package/web/.next/server/chunks/ssr/_3d152196._.js +0 -3
  207. package/web/.next/server/chunks/ssr/_3d152196._.js.map +0 -1
  208. package/web/.next/server/chunks/ssr/node_modules__pnpm_b11d5ad4._.js +0 -3
  209. package/web/.next/server/chunks/ssr/node_modules__pnpm_b11d5ad4._.js.map +0 -1
  210. package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js +0 -3
  211. package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js.map +0 -1
  212. package/web/.next/static/chunks/3701b9d5749e6143.css +0 -1
  213. package/web/.next/static/chunks/a8030d19b4d73c95.js +0 -1
  214. package/web/.next/static/chunks/b0d13220be9ac29c.js +0 -1
  215. package/web/.next/static/chunks/be34161188b4e0a0.js +0 -2
  216. package/web/.next/static/chunks/c87445f8cbe36c74.js +0 -1
  217. package/web/.next/static/chunks/f220dad9d38bff95.js +0 -5
  218. package/web/.next/static/chunks/f74cb59a5a6c94f1.js +0 -1
  219. /package/web/.next/server/chunks/{[externals]_next_dist_a6d89067._.js.map → 744ca_web__next-internal_server_app_api_dialog_pick-files_route_actions_f9868286.js.map} +0 -0
  220. /package/web/.next/server/chunks/ssr/{[root-of-the-server]__6b3c1f2b._.js.map → [root-of-the-server]__685eaa45._.js.map} +0 -0
  221. /package/web/.next/server/chunks/ssr/{[root-of-the-server]__80e5bed2._.js.map → [root-of-the-server]__71515c64._.js.map} +0 -0
  222. /package/web/.next/server/chunks/ssr/{[root-of-the-server]__2127336f._.js.map → [root-of-the-server]__757c7912._.js.map} +0 -0
  223. /package/web/.next/server/chunks/ssr/{[root-of-the-server]__e55e9c7f._.js.map → [root-of-the-server]__dbd220d2._.js.map} +0 -0
  224. /package/web/.next/static/{Ox87EvwGC4i-5d3Y6mR8W → GicjIYHwLgPQhRVKOwkGc}/_buildManifest.js +0 -0
  225. /package/web/.next/static/{Ox87EvwGC4i-5d3Y6mR8W → GicjIYHwLgPQhRVKOwkGc}/_clientMiddlewareManifest.json +0 -0
  226. /package/web/.next/static/{Ox87EvwGC4i-5d3Y6mR8W → GicjIYHwLgPQhRVKOwkGc}/_ssgManifest.js +0 -0
@@ -0,0 +1,7 @@
1
+ import type { FeatureNodeData } from '../../common/feature-node/index.js';
2
+ export interface FeatureDrawerProps {
3
+ selectedNode: FeatureNodeData | null;
4
+ onClose: () => void;
5
+ }
6
+ export declare function FeatureDrawer({ selectedNode, onClose }: FeatureDrawerProps): import("react/jsx-runtime").JSX.Element;
7
+ //# sourceMappingURL=feature-drawer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer/feature-drawer.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAExE,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,eAAe,GAAG,IAAI,CAAC;IACrC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,aAAa,CAAC,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,kBAAkB,2CAmE1E"}
@@ -0,0 +1,28 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { XIcon } from 'lucide-react';
4
+ import { cn } from '../../../lib/utils.js';
5
+ import { Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerDescription, } from '../../ui/drawer.js';
6
+ import { Separator } from '../../ui/separator.js';
7
+ import { CometSpinner } from '../../ui/comet-spinner.js';
8
+ import { featureNodeStateConfig, lifecycleDisplayLabels } from '../../common/feature-node/index.js';
9
+ export function FeatureDrawer({ selectedNode, onClose }) {
10
+ return (_jsx(Drawer, { direction: "right", modal: false, open: selectedNode !== null, onOpenChange: (open) => {
11
+ if (!open)
12
+ onClose();
13
+ }, children: _jsx(DrawerContent, { direction: "right", className: "w-96", showCloseButton: false, children: selectedNode ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", "aria-label": "Close", onClick: onClose, className: "ring-offset-background focus:ring-ring absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden", children: _jsx(XIcon, { className: "size-4" }) }), _jsxs(DrawerHeader, { "data-testid": "feature-drawer-header", children: [_jsx(DrawerTitle, { children: selectedNode.name }), _jsx(DrawerDescription, { children: selectedNode.featureId })] }), _jsx(Separator, {}), _jsxs("div", { "data-testid": "feature-drawer-status", className: "flex flex-col gap-3 p-4", children: [_jsx("div", { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: lifecycleDisplayLabels[selectedNode.lifecycle] }), _jsx(StateBadge, { data: selectedNode }), selectedNode.progress > 0 ? (_jsxs("div", { "data-testid": "feature-drawer-progress", className: "flex flex-col gap-1", children: [_jsxs("div", { className: "text-muted-foreground flex items-center justify-between text-xs", children: [_jsx("span", { children: "Progress" }), _jsxs("span", { children: [selectedNode.progress, "%"] })] }), _jsx("div", { className: "bg-muted h-2 w-full overflow-hidden rounded-full", children: _jsx("div", { className: cn('h-full rounded-full transition-all', featureNodeStateConfig[selectedNode.state].progressClass), style: { width: `${selectedNode.progress}%` } }) })] })) : null] }), _jsx(Separator, {}), _jsx(DetailsSection, { data: selectedNode })] })) : null }) }));
14
+ }
15
+ function StateBadge({ data }) {
16
+ const config = featureNodeStateConfig[data.state];
17
+ const Icon = config.icon;
18
+ return (_jsxs("div", { className: cn('flex items-center gap-2 rounded-full px-3 py-1.5 text-sm font-medium', config.badgeBgClass, config.badgeClass), children: [data.state === 'running' ? (_jsx(CometSpinner, { size: "sm", className: "shrink-0" })) : (_jsx(Icon, { className: "h-4 w-4 shrink-0" })), _jsx("span", { children: config.label })] }));
19
+ }
20
+ function DetailsSection({ data }) {
21
+ const hasAnyDetail = data.description ?? data.agentName ?? data.runtime ?? data.blockedBy ?? data.errorMessage;
22
+ if (!hasAnyDetail)
23
+ return null;
24
+ return (_jsxs("div", { "data-testid": "feature-drawer-details", className: "flex flex-col gap-3 p-4", children: [data.description ? _jsx(DetailRow, { label: "Description", value: data.description }) : null, data.agentName ? _jsx(DetailRow, { label: "Agent", value: data.agentName }) : null, data.runtime ? _jsx(DetailRow, { label: "Runtime", value: data.runtime }) : null, data.blockedBy ? _jsx(DetailRow, { label: "Blocked by", value: data.blockedBy }) : null, data.errorMessage ? _jsx(DetailRow, { label: "Error", value: data.errorMessage }) : null] }));
25
+ }
26
+ function DetailRow({ label, value }) {
27
+ return (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: label }), _jsx("span", { className: "text-sm", children: value })] }));
28
+ }
@@ -0,0 +1,19 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { FeatureDrawer } from './feature-drawer.js';
3
+ declare const meta: Meta<typeof FeatureDrawer>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof FeatureDrawer>;
6
+ export declare const Running: Story;
7
+ export declare const ActionRequired: Story;
8
+ export declare const Done: Story;
9
+ export declare const Blocked: Story;
10
+ export declare const Error: Story;
11
+ /** Minimal data — only required fields, no optional details section. */
12
+ export declare const MinimalData: Story;
13
+ /** All optional fields populated — description, agent, runtime, blockedBy, error. */
14
+ export declare const AllFields: Story;
15
+ /** Cycle through all 5 states at a glance via buttons. */
16
+ export declare const AllStates: Story;
17
+ /** Cycle through all 6 lifecycle phases via buttons. */
18
+ export declare const AllLifecycles: Story;
19
+ //# sourceMappingURL=feature-drawer.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-drawer.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer/feature-drawer.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAKjD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,aAAa,CAOpC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,aAAa,CAAC,CAAC;AAoF5C,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAE5B,CAAC;AAEF,eAAO,MAAM,IAAI,EAAE,KAElB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAEnB,CAAC;AAMF,wEAAwE;AACxE,eAAO,MAAM,WAAW,EAAE,KAEzB,CAAC;AAEF,qFAAqF;AACrF,eAAO,MAAM,SAAS,EAAE,KAmBvB,CAAC;AAuDF,0DAA0D;AAC1D,eAAO,MAAM,SAAS,EAAE,KAEvB,CAAC;AA2CF,wDAAwD;AACxD,eAAO,MAAM,aAAa,EAAE,KAE3B,CAAC"}
@@ -0,0 +1,167 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { FeatureDrawer } from './feature-drawer.js';
4
+ import { Button } from '../../ui/button.js';
5
+ const meta = {
6
+ title: 'Composed/FeatureDrawer',
7
+ component: FeatureDrawer,
8
+ tags: ['autodocs'],
9
+ parameters: {
10
+ layout: 'fullscreen',
11
+ },
12
+ };
13
+ export default meta;
14
+ /* ---------------------------------------------------------------------------
15
+ * Data fixtures
16
+ * ------------------------------------------------------------------------- */
17
+ const baseData = {
18
+ name: 'Auth Module',
19
+ featureId: '#f1',
20
+ lifecycle: 'implementation',
21
+ state: 'running',
22
+ progress: 45,
23
+ };
24
+ const runningData = {
25
+ name: 'Auth Module',
26
+ description: 'Implement OAuth2 authentication flow',
27
+ featureId: '#f1',
28
+ lifecycle: 'implementation',
29
+ state: 'running',
30
+ progress: 45,
31
+ agentName: 'Planner',
32
+ };
33
+ const actionRequiredData = {
34
+ name: 'API Rate Limiting',
35
+ description: 'Implement sliding window rate limiting for public endpoints',
36
+ featureId: '#bi1',
37
+ lifecycle: 'requirements',
38
+ state: 'action-required',
39
+ progress: 22,
40
+ };
41
+ const doneData = {
42
+ name: 'Payment Gateway',
43
+ description: 'Stripe integration for subscriptions',
44
+ featureId: '#f3',
45
+ lifecycle: 'deploy',
46
+ state: 'done',
47
+ progress: 100,
48
+ runtime: '1h 42m',
49
+ };
50
+ const blockedData = {
51
+ name: 'Search Index',
52
+ description: 'Elasticsearch full-text search setup',
53
+ featureId: '#f4',
54
+ lifecycle: 'implementation',
55
+ state: 'blocked',
56
+ progress: 20,
57
+ blockedBy: 'Auth Module',
58
+ };
59
+ const errorData = {
60
+ name: 'Email Service',
61
+ description: 'Transactional email with SendGrid',
62
+ featureId: '#f5',
63
+ lifecycle: 'review',
64
+ state: 'error',
65
+ progress: 30,
66
+ errorMessage: 'Build failed: type mismatch',
67
+ };
68
+ /* ---------------------------------------------------------------------------
69
+ * Trigger wrapper — starts closed, click to open
70
+ * ------------------------------------------------------------------------- */
71
+ function DrawerTrigger({ data, label }) {
72
+ const [selected, setSelected] = useState(null);
73
+ return (_jsxs("div", { className: "flex h-screen items-start p-4", children: [_jsx(Button, { variant: "outline", onClick: () => setSelected(data), children: label }), _jsx(FeatureDrawer, { selectedNode: selected, onClose: () => setSelected(null) })] }));
74
+ }
75
+ /* ---------------------------------------------------------------------------
76
+ * Per-state stories
77
+ * ------------------------------------------------------------------------- */
78
+ export const Running = {
79
+ render: () => _jsx(DrawerTrigger, { data: runningData, label: "Open Running" }),
80
+ };
81
+ export const ActionRequired = {
82
+ render: () => _jsx(DrawerTrigger, { data: actionRequiredData, label: "Open Action Required" }),
83
+ };
84
+ export const Done = {
85
+ render: () => _jsx(DrawerTrigger, { data: doneData, label: "Open Done" }),
86
+ };
87
+ export const Blocked = {
88
+ render: () => _jsx(DrawerTrigger, { data: blockedData, label: "Open Blocked" }),
89
+ };
90
+ export const Error = {
91
+ render: () => _jsx(DrawerTrigger, { data: errorData, label: "Open Error" }),
92
+ };
93
+ /* ---------------------------------------------------------------------------
94
+ * Edge-case stories
95
+ * ------------------------------------------------------------------------- */
96
+ /** Minimal data — only required fields, no optional details section. */
97
+ export const MinimalData = {
98
+ render: () => _jsx(DrawerTrigger, { data: { ...baseData, progress: 0 }, label: "Open Minimal" }),
99
+ };
100
+ /** All optional fields populated — description, agent, runtime, blockedBy, error. */
101
+ export const AllFields = {
102
+ render: () => (_jsx(DrawerTrigger, { data: {
103
+ name: 'Enterprise Authentication Module',
104
+ description: 'Implement a comprehensive OAuth2 authentication flow with support for multiple identity providers including Google, GitHub, and custom SAML-based enterprise SSO.',
105
+ featureId: '#f99',
106
+ lifecycle: 'implementation',
107
+ state: 'running',
108
+ progress: 68,
109
+ agentName: 'Implementer',
110
+ runtime: '3h 15m',
111
+ blockedBy: 'Database Migration',
112
+ errorMessage: 'Token refresh failed: invalid_grant',
113
+ }, label: "Open All Fields" })),
114
+ };
115
+ /* ---------------------------------------------------------------------------
116
+ * Matrix stories — interactive state/lifecycle switcher
117
+ * ------------------------------------------------------------------------- */
118
+ const stateFixtures = {
119
+ running: runningData,
120
+ 'action-required': actionRequiredData,
121
+ done: doneData,
122
+ blocked: blockedData,
123
+ error: errorData,
124
+ };
125
+ const allLifecycles = [
126
+ 'requirements',
127
+ 'research',
128
+ 'implementation',
129
+ 'review',
130
+ 'deploy',
131
+ 'maintain',
132
+ ];
133
+ function AllStatesRender() {
134
+ const [state, setState] = useState('running');
135
+ const [selected, setSelected] = useState(null);
136
+ const _data = stateFixtures[state];
137
+ return (_jsxs("div", { className: "flex h-screen", children: [_jsxs("div", { className: "flex flex-col gap-2 p-4", children: [_jsx("span", { className: "text-muted-foreground mb-2 text-xs font-semibold tracking-wider uppercase", children: "Select state" }), Object.keys(stateFixtures).map((s) => (_jsx("button", { type: "button", onClick: () => {
138
+ setState(s);
139
+ setSelected(stateFixtures[s]);
140
+ }, className: `rounded-md px-3 py-1.5 text-left text-sm ${s === state ? 'bg-primary text-primary-foreground' : 'bg-muted hover:bg-muted/80'}`, children: s }, s)))] }), _jsx(FeatureDrawer, { selectedNode: selected, onClose: () => setSelected(null) })] }));
141
+ }
142
+ /** Cycle through all 5 states at a glance via buttons. */
143
+ export const AllStates = {
144
+ render: () => _jsx(AllStatesRender, {}),
145
+ };
146
+ function AllLifecyclesRender() {
147
+ const [lifecycle, setLifecycle] = useState('requirements');
148
+ const [selected, setSelected] = useState(null);
149
+ return (_jsxs("div", { className: "flex h-screen", children: [_jsxs("div", { className: "flex flex-col gap-2 p-4", children: [_jsx("span", { className: "text-muted-foreground mb-2 text-xs font-semibold tracking-wider uppercase", children: "Select phase" }), allLifecycles.map((phase) => (_jsx("button", { type: "button", onClick: () => {
150
+ setLifecycle(phase);
151
+ setSelected({
152
+ name: 'Feature Name',
153
+ description: `Currently in ${phase} phase`,
154
+ featureId: '#f1',
155
+ lifecycle: phase,
156
+ state: 'running',
157
+ progress: 50,
158
+ agentName: 'Agent',
159
+ });
160
+ }, className: `rounded-md px-3 py-1.5 text-left text-sm ${phase === lifecycle
161
+ ? 'bg-primary text-primary-foreground'
162
+ : 'bg-muted hover:bg-muted/80'}`, children: phase }, phase)))] }), _jsx(FeatureDrawer, { selectedNode: selected, onClose: () => setSelected(null) })] }));
163
+ }
164
+ /** Cycle through all 6 lifecycle phases via buttons. */
165
+ export const AllLifecycles = {
166
+ render: () => _jsx(AllLifecyclesRender, {}),
167
+ };
@@ -0,0 +1,2 @@
1
+ export { FeatureDrawer, type FeatureDrawerProps } from './feature-drawer.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1 @@
1
+ export { FeatureDrawer } from './feature-drawer.js';
@@ -1,12 +1,9 @@
1
1
  import { type LucideIcon } from 'lucide-react';
2
2
  import type { Node } from '@xyflow/react';
3
- import type { AgentTypeValue } from './agent-type-icons.js';
4
3
  export type FeatureNodeState = 'running' | 'action-required' | 'done' | 'blocked' | 'error';
5
4
  export type FeatureLifecyclePhase = 'requirements' | 'research' | 'implementation' | 'review' | 'deploy' | 'maintain';
6
5
  /** Human-readable display labels for lifecycle phases. */
7
6
  export declare const lifecycleDisplayLabels: Record<FeatureLifecyclePhase, string>;
8
- /** Present-participle verbs for the running badge, keyed by lifecycle phase. */
9
- export declare const lifecycleRunningVerbs: Record<FeatureLifecyclePhase, string>;
10
7
  export interface FeatureNodeData {
11
8
  [key: string]: unknown;
12
9
  name: string;
@@ -21,8 +18,8 @@ export interface FeatureNodeData {
21
18
  blockedBy?: string;
22
19
  /** Short error message for error state */
23
20
  errorMessage?: string;
24
- /** Agent executor type (e.g. "claude-code", "cursor"). */
25
- agentType?: AgentTypeValue;
21
+ /** Agent name shown in the running badge (e.g. "Planner") */
22
+ agentName?: string;
26
23
  onAction?: () => void;
27
24
  onSettings?: () => void;
28
25
  showHandles?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"feature-node-state-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node-state-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqD,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAClG,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,iBAAiB,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;AAE5F,MAAM,MAAM,qBAAqB,GAC7B,cAAc,GACd,UAAU,GACV,gBAAgB,GAChB,QAAQ,GACR,QAAQ,GACR,UAAU,CAAC;AAEf,0DAA0D;AAC1D,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,qBAAqB,EAAE,MAAM,CAOxE,CAAC;AAEF,gFAAgF;AAChF,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,qBAAqB,EAAE,MAAM,CAOvE,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,qBAAqB,CAAC;IACjC,KAAK,EAAE,gBAAgB,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;AAEnE,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,gBAAgB,EAAE,sBAAsB,CAmDnF,CAAC"}
1
+ {"version":3,"file":"feature-node-state-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node-state-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmD,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAChG,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,iBAAiB,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;AAE5F,MAAM,MAAM,qBAAqB,GAC7B,cAAc,GACd,UAAU,GACV,gBAAgB,GAChB,QAAQ,GACR,QAAQ,GACR,UAAU,CAAC;AAEf,0DAA0D;AAC1D,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,qBAAqB,EAAE,MAAM,CAOxE,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,qBAAqB,CAAC;IACjC,KAAK,EAAE,gBAAgB,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;AAEnE,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,gBAAgB,EAAE,sBAAsB,CAmDnF,CAAC"}
@@ -1,4 +1,4 @@
1
- import { Loader2, AlertTriangle, CircleCheck, Ban, CircleX } from 'lucide-react';
1
+ import { Loader2, CircleAlert, CircleCheck, Ban, CircleX } from 'lucide-react';
2
2
  /** Human-readable display labels for lifecycle phases. */
3
3
  export const lifecycleDisplayLabels = {
4
4
  requirements: 'REQUIREMENTS',
@@ -8,15 +8,6 @@ export const lifecycleDisplayLabels = {
8
8
  deploy: 'DEPLOY & QA',
9
9
  maintain: 'COMPLETED',
10
10
  };
11
- /** Present-participle verbs for the running badge, keyed by lifecycle phase. */
12
- export const lifecycleRunningVerbs = {
13
- requirements: 'Analyzing',
14
- research: 'Researching',
15
- implementation: 'Implementing',
16
- review: 'Reviewing',
17
- deploy: 'Deploying',
18
- maintain: 'Maintaining',
19
- };
20
11
  export const featureNodeStateConfig = {
21
12
  running: {
22
13
  icon: Loader2,
@@ -29,12 +20,12 @@ export const featureNodeStateConfig = {
29
20
  showProgressBar: false,
30
21
  },
31
22
  'action-required': {
32
- icon: AlertTriangle,
23
+ icon: CircleAlert,
33
24
  borderClass: 'border-l-amber-500',
34
25
  labelClass: 'text-amber-500',
35
26
  progressClass: 'bg-amber-500',
36
- badgeClass: 'text-amber-800',
37
- badgeBgClass: 'bg-amber-50 border border-amber-200',
27
+ badgeClass: 'text-amber-700',
28
+ badgeBgClass: 'bg-amber-50',
38
29
  label: 'User action required',
39
30
  showProgressBar: false,
40
31
  },
@@ -1 +1 @@
1
- {"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAwBnE,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,2CA6IA"}
1
+ {"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAoBnE,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,2CA0IA"}
@@ -3,17 +3,15 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
3
3
  import { Handle, Position } from '@xyflow/react';
4
4
  import { Settings, Plus } from 'lucide-react';
5
5
  import { cn } from '../../../lib/utils.js';
6
- import { featureNodeStateConfig, lifecycleDisplayLabels, lifecycleRunningVerbs, } from './feature-node-state-config.js';
7
- import { getAgentTypeIcon } from './agent-type-icons.js';
8
- function AgentIcon({ agentType, className }) {
9
- const IconComponent = getAgentTypeIcon(agentType);
10
- return _jsx(IconComponent, { className: className });
11
- }
6
+ import { CometSpinner } from '../../ui/comet-spinner.js';
7
+ import { featureNodeStateConfig, lifecycleDisplayLabels } from './feature-node-state-config.js';
12
8
  function getBadgeText(data) {
13
9
  const config = featureNodeStateConfig[data.state];
14
10
  switch (data.state) {
15
- case 'running':
16
- return lifecycleRunningVerbs[data.lifecycle];
11
+ case 'running': {
12
+ const agent = data.agentName ?? 'Agent';
13
+ return `${agent} ${data.featureId} running`;
14
+ }
17
15
  case 'done':
18
16
  return data.runtime ? `Completed in ${data.runtime}` : 'Completed';
19
17
  case 'blocked':
@@ -30,7 +28,7 @@ export function FeatureNode({ data, selected, }) {
30
28
  return (_jsxs("div", { className: "group relative", children: [data.showHandles ? (_jsx(Handle, { type: "target", position: Position.Left, isConnectable: false, className: "opacity-0!" })) : null, _jsxs("div", { "data-testid": "feature-node-card", 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: lifecycleDisplayLabels[data.lifecycle] }), data.onSettings ? (_jsx("button", { type: "button", "aria-label": "Settings", "data-testid": "feature-node-settings-button", onClick: (e) => {
31
29
  e.stopPropagation();
32
30
  data.onSettings?.();
33
- }, 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 === '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("div", { "data-testid": "feature-node-badge", className: cn('mt-1.5 flex items-center justify-center gap-1.5 rounded-full px-2.5 py-1 text-[11px] font-medium', config.badgeBgClass, config.badgeClass), children: [_jsx(Icon, { className: "h-3.5 w-3.5 shrink-0" }), _jsx("span", { className: "truncate", children: getBadgeText(data) })] })) })] }), data.onAction ? (_jsx(Handle, { type: "source", position: Position.Right, className: "h-0! w-0! border-0! bg-transparent!", children: _jsx("button", { type: "button", "aria-label": "Add", "data-testid": "feature-node-action-button", onClick: (e) => {
31
+ }, 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: config.showProgressBar ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "text-muted-foreground flex items-center justify-between text-[10px]", children: [_jsx("span", { children: data.featureId }), _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: cn('mt-1.5 flex items-center justify-center gap-1.5 rounded-full px-2.5 py-1 text-[11px] font-medium', config.badgeBgClass, config.badgeClass), children: [data.state === 'running' ? (_jsx(CometSpinner, { size: "sm", className: "shrink-0" })) : (_jsx(Icon, { className: "h-3.5 w-3.5 shrink-0" })), _jsx("span", { className: "truncate", children: getBadgeText(data) })] })] })) })] }), data.onAction ? (_jsx(Handle, { type: "source", position: Position.Right, className: "h-0! w-0! border-0! bg-transparent!", children: _jsx("button", { type: "button", "aria-label": "Add", "data-testid": "feature-node-action-button", onClick: (e) => {
34
32
  e.stopPropagation();
35
33
  data.onAction?.();
36
34
  }, className: "nodrag absolute top-1/2 left-1/2 flex h-6 w-6 -translate-x-1/2 -translate-y-1/2 cursor-pointer items-center justify-center rounded-full bg-blue-500 text-white opacity-0 shadow-md transition-opacity group-hover:opacity-100 hover:bg-blue-600", children: _jsx(Plus, { className: "h-3.5 w-3.5" }) }) })) : data.showHandles ? (_jsx(Handle, { type: "source", position: Position.Right, isConnectable: false, className: "opacity-0!" })) : null] }));
@@ -11,6 +11,5 @@ export declare const LongContent: Story;
11
11
  export declare const DoneWithRuntime: Story;
12
12
  export declare const BlockedByFeature: Story;
13
13
  export declare const ErrorWithMessage: Story;
14
- export declare const AllAgentTypes: Story;
15
14
  export declare const Interactive: Story;
16
15
  //# sourceMappingURL=feature-node.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"feature-node.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAIvD,OAAO,KAAK,EACV,eAAe,EAIhB,MAAM,6BAA6B,CAAC;AAkCrC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,eAAe,CAe/B,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAC;AAEvC,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAiDF,eAAO,MAAM,SAAS,EAAE,KAQvB,CAAC;AAWF,eAAO,MAAM,aAAa,EAAE,KAoB3B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAMxB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAW7B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AAWF,eAAO,MAAM,aAAa,EAAE,KAoB3B,CAAC;AAuEF,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC"}
1
+ {"version":3,"file":"feature-node.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAIvD,OAAO,KAAK,EACV,eAAe,EAIhB,MAAM,6BAA6B,CAAC;AAiCrC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,eAAe,CAe/B,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAC;AAEvC,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAiDF,eAAO,MAAM,SAAS,EAAE,KAQvB,CAAC;AAWF,eAAO,MAAM,aAAa,EAAE,KAoB3B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAMxB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAW7B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AAuEF,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC"}
@@ -22,7 +22,7 @@ const meta = {
22
22
  lifecycle: 'requirements',
23
23
  state: 'running',
24
24
  progress: 45,
25
- agentType: 'claude-code',
25
+ agentName: 'Planner',
26
26
  },
27
27
  };
28
28
  export default meta;
@@ -37,7 +37,7 @@ const allStatesData = [
37
37
  lifecycle: 'implementation',
38
38
  state: 'running',
39
39
  progress: 45,
40
- agentType: 'claude-code',
40
+ agentName: 'Planner',
41
41
  },
42
42
  {
43
43
  name: 'API Rate Limiting',
@@ -94,7 +94,7 @@ export const AllLifecycles = {
94
94
  lifecycle,
95
95
  state: 'running',
96
96
  progress: [10, 25, 50, 70, 90, 100][i],
97
- agentType: 'claude-code',
97
+ agentName: 'Researcher',
98
98
  } }, lifecycle))) })),
99
99
  };
100
100
  export const WithAction = {
@@ -147,25 +147,6 @@ export const ErrorWithMessage = {
147
147
  },
148
148
  render: (args) => _jsx(FeatureNodeCanvas, { data: args }),
149
149
  };
150
- const allAgentTypes = [
151
- 'claude-code',
152
- 'cursor',
153
- 'gemini-cli',
154
- 'aider',
155
- 'continue',
156
- undefined,
157
- ];
158
- export const AllAgentTypes = {
159
- render: () => (_jsx("div", { className: "flex flex-wrap gap-6", children: allAgentTypes.map((agentType, i) => (_jsx(FeatureNodeCanvas, { style: { width: 500, height: 350 }, data: {
160
- name: agentType ?? 'Unknown Agent',
161
- description: agentType ? `Running with ${agentType}` : 'Fallback icon',
162
- featureId: `#f${i + 1}`,
163
- lifecycle: 'implementation',
164
- state: 'running',
165
- progress: 45,
166
- agentType,
167
- } }, agentType ?? 'fallback'))) })),
168
- };
169
150
  const interactiveInitialNodes = [
170
151
  {
171
152
  id: 'node-1',
@@ -179,7 +160,7 @@ const interactiveInitialNodes = [
179
160
  lifecycle: 'implementation',
180
161
  state: 'running',
181
162
  progress: 45,
182
- agentType: 'claude-code',
163
+ agentName: 'Planner',
183
164
  },
184
165
  },
185
166
  {
@@ -1,5 +1,3 @@
1
1
  export { FeatureNode } from './feature-node.js';
2
- export { featureNodeStateConfig, lifecycleDisplayLabels, lifecycleRunningVerbs, type FeatureNodeState, type FeatureLifecyclePhase, type FeatureNodeData, type FeatureNodeType, type FeatureNodeStateConfig, } from './feature-node-state-config.js';
3
- export { getAgentTypeIcon, type AgentTypeValue } from './agent-type-icons.js';
4
- export { deriveNodeState, deriveProgress } from './derive-feature-state.js';
2
+ export { featureNodeStateConfig, lifecycleDisplayLabels, type FeatureNodeState, type FeatureLifecyclePhase, type FeatureNodeData, type FeatureNodeType, type FeatureNodeStateConfig, } from './feature-node-state-config.js';
5
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,sBAAsB,GAC5B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,sBAAsB,GAC5B,MAAM,6BAA6B,CAAC"}
@@ -1,4 +1,2 @@
1
1
  export { FeatureNode } from './feature-node.js';
2
- export { featureNodeStateConfig, lifecycleDisplayLabels, lifecycleRunningVerbs, } from './feature-node-state-config.js';
3
- export { getAgentTypeIcon } from './agent-type-icons.js';
4
- export { deriveNodeState, deriveProgress } from './derive-feature-state.js';
2
+ export { featureNodeStateConfig, lifecycleDisplayLabels, } from './feature-node-state-config.js';
@@ -1,6 +1,8 @@
1
1
  export { AddRepositoryNode, type AddRepositoryNodeData, type AddRepositoryNodeType, } from './add-repository-node/index.js';
2
2
  export { ElapsedTime, formatElapsed } from './elapsed-time/index.js';
3
3
  export { EmptyState, type EmptyStateProps } from './empty-state/index.js';
4
+ export { FeatureCreateDrawer, type FeatureCreateDrawerProps, type CreateFeatureFormData, } from './feature-create-drawer/index.js';
5
+ export { FeatureDrawer, type FeatureDrawerProps } from './feature-drawer/index.js';
4
6
  export { FeatureListItem, type FeatureListItemProps } from './feature-list-item/index.js';
5
7
  export { FeatureNode, featureNodeStateConfig, type FeatureNodeState, type FeatureLifecyclePhase, type FeatureNodeData, type FeatureNodeType, type FeatureNodeStateConfig, } from './feature-node/index.js';
6
8
  export { FeatureStatusBadges, type FeatureStatusBadgesProps } from './feature-status-badges/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/common/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EACL,WAAW,EACX,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,sBAAsB,GAC5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,KAAK,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAC7F,OAAO,EAAE,kBAAkB,EAAE,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAC1F,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,cAAc,EACd,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,KAAK,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACnG,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,KAAK,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAChG,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/common/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EACL,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,GAC3B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EACL,WAAW,EACX,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,sBAAsB,GAC5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,KAAK,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAC7F,OAAO,EAAE,kBAAkB,EAAE,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAC1F,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,cAAc,EACd,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,KAAK,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACnG,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,KAAK,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAChG,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
@@ -1,6 +1,8 @@
1
1
  export { AddRepositoryNode, } from './add-repository-node/index.js';
2
2
  export { ElapsedTime, formatElapsed } from './elapsed-time/index.js';
3
3
  export { EmptyState } from './empty-state/index.js';
4
+ export { FeatureCreateDrawer, } from './feature-create-drawer/index.js';
5
+ export { FeatureDrawer } from './feature-drawer/index.js';
4
6
  export { FeatureListItem } from './feature-list-item/index.js';
5
7
  export { FeatureNode, featureNodeStateConfig, } from './feature-node/index.js';
6
8
  export { FeatureStatusBadges } from './feature-status-badges/index.js';
@@ -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":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAI5E,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,2CA6BzF"}
1
+ {"version":3,"file":"control-center-inner.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-inner.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAK5E,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,2CAgDzF"}
@@ -1,9 +1,17 @@
1
1
  'use client';
2
- import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect } from 'react';
3
4
  import { FeaturesCanvas } from '../../features/features-canvas/index.js';
5
+ import { FeatureDrawer, FeatureCreateDrawer } from '../../common/index.js';
4
6
  import { ControlCenterEmptyState } from './control-center-empty-state.js';
5
7
  import { useControlCenterState } from './use-control-center-state.js';
6
8
  export function ControlCenterInner({ initialNodes, initialEdges }) {
7
- const { nodes, edges, onNodesChange, handleConnect, handleAddFeature, handleAddFeatureToRepo, handleAddFeatureToFeature, handleAddRepository, handleNodeClick, clearSelection, } = useControlCenterState(initialNodes, initialEdges);
8
- return (_jsx(FeaturesCanvas, { nodes: nodes, edges: edges, onNodesChange: onNodesChange, onConnect: handleConnect, onAddFeature: handleAddFeature, onNodeAction: handleAddFeatureToFeature, onNodeClick: handleNodeClick, onPaneClick: clearSelection, onRepositoryAdd: handleAddFeatureToRepo, onRepositorySelect: handleAddRepository, emptyState: _jsx(ControlCenterEmptyState, { onRepositorySelect: handleAddRepository }) }));
9
+ const { nodes, edges, selectedNode, isCreateDrawerOpen, onNodesChange, handleConnect, handleAddFeature, handleAddFeatureToRepo, handleAddFeatureToFeature, handleAddRepository, handleNodeClick, clearSelection, handleCreateFeatureSubmit, closeCreateDrawer, } = useControlCenterState(initialNodes, initialEdges);
10
+ // Listen for global "open create drawer" events from the sidebar
11
+ useEffect(() => {
12
+ const handler = () => handleAddFeature();
13
+ window.addEventListener('shep:open-create-drawer', handler);
14
+ return () => window.removeEventListener('shep:open-create-drawer', handler);
15
+ }, [handleAddFeature]);
16
+ return (_jsxs(_Fragment, { children: [_jsx(FeaturesCanvas, { nodes: nodes, edges: edges, onNodesChange: onNodesChange, onConnect: handleConnect, onAddFeature: handleAddFeature, onNodeAction: handleAddFeatureToFeature, onNodeClick: handleNodeClick, onPaneClick: clearSelection, onRepositoryAdd: handleAddFeatureToRepo, onRepositorySelect: handleAddRepository, emptyState: _jsx(ControlCenterEmptyState, { onRepositorySelect: handleAddRepository }) }), _jsx(FeatureDrawer, { selectedNode: selectedNode, onClose: clearSelection }), _jsx(FeatureCreateDrawer, { open: isCreateDrawerOpen, onClose: closeCreateDrawer, onSubmit: handleCreateFeatureSubmit })] }));
9
17
  }
@@ -1,11 +1,13 @@
1
1
  import type { Connection, Edge, NodeChange } from '@xyflow/react';
2
2
  import type { FeatureNodeData } from '../../common/feature-node/index.js';
3
+ import type { CreateFeatureFormData } from '../../common/feature-create-drawer/index.js';
3
4
  import type { CanvasNodeType } from '../../features/features-canvas/index.js';
4
5
  import { type LayoutDirection } from '../../../lib/layout-with-dagre.js';
5
6
  export interface ControlCenterState {
6
7
  nodes: CanvasNodeType[];
7
8
  edges: Edge[];
8
9
  selectedNode: FeatureNodeData | null;
10
+ isCreateDrawerOpen: boolean;
9
11
  onNodesChange: (changes: NodeChange<CanvasNodeType>[]) => void;
10
12
  handleConnect: (connection: Connection) => void;
11
13
  clearSelection: () => void;
@@ -15,6 +17,8 @@ export interface ControlCenterState {
15
17
  handleAddFeatureToFeature: (featureNodeId: string) => void;
16
18
  handleAddRepository: (path: string) => void;
17
19
  handleLayout: (direction: LayoutDirection) => void;
20
+ handleCreateFeatureSubmit: (data: CreateFeatureFormData) => void;
21
+ closeCreateDrawer: () => void;
18
22
  }
19
23
  export declare function useControlCenterState(initialNodes: CanvasNodeType[], initialEdges: Edge[]): ControlCenterState;
20
24
  //# 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":"AAIA,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;AAEhF,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,YAAY,EAAE,eAAe,GAAG,IAAI,CAAC;IACrC,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,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,eAAe,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACzE,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,sBAAsB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,yBAAyB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3D,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;CACpD;AAID,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,kBAAkB,CA6PpB"}
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":"AAIA,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,qBAAqB,EAAE,MAAM,2CAA2C,CAAC;AACvF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAEhF,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,YAAY,EAAE,eAAe,GAAG,IAAI,CAAC;IACrC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,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,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,eAAe,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACzE,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,sBAAsB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,yBAAyB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3D,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,yBAAyB,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACjE,iBAAiB,EAAE,MAAM,IAAI,CAAC;CAC/B;AAID,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,kBAAkB,CAkRpB"}