@shepai/cli 1.72.8 → 1.72.9-pr220.99e5e13

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 (375) hide show
  1. package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts +2 -1
  2. package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts.map +1 -1
  3. package/dist/packages/core/src/application/use-cases/agents/approve-agent-run.use-case.d.ts.map +1 -1
  4. package/dist/packages/core/src/application/use-cases/agents/approve-agent-run.use-case.js +1 -0
  5. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts +20 -1
  6. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
  7. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +68 -41
  8. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts +10 -0
  9. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts.map +1 -1
  10. package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.d.ts.map +1 -1
  11. package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.js +1 -0
  12. package/dist/packages/core/src/domain/factories/settings-defaults.factory.js +1 -1
  13. package/dist/packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.d.ts.map +1 -1
  14. package/dist/packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.js +88 -13
  15. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts +1 -1
  16. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts +2 -1
  17. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts.map +1 -1
  18. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.js +3 -0
  19. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts +2 -0
  20. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts.map +1 -1
  21. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js +16 -3
  22. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.d.ts.map +1 -1
  23. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.js +5 -1
  24. package/dist/src/presentation/web/app/actions/create-feature.d.ts.map +1 -1
  25. package/dist/src/presentation/web/app/actions/create-feature.js +20 -2
  26. package/dist/src/presentation/web/app/actions/get-feature-metadata.d.ts +10 -0
  27. package/dist/src/presentation/web/app/actions/get-feature-metadata.d.ts.map +1 -0
  28. package/dist/src/presentation/web/app/actions/get-feature-metadata.js +14 -0
  29. package/dist/src/presentation/web/app/actions/get-graph-data.d.ts +10 -0
  30. package/dist/src/presentation/web/app/actions/get-graph-data.d.ts.map +1 -0
  31. package/dist/src/presentation/web/app/actions/get-graph-data.js +10 -0
  32. package/dist/src/presentation/web/app/api/agent-events/route.d.ts.map +1 -1
  33. package/dist/src/presentation/web/app/api/agent-events/route.js +18 -0
  34. package/dist/src/presentation/web/components/common/add-repository-button/add-repository-button.d.ts.map +1 -0
  35. package/dist/src/presentation/web/components/common/add-repository-button/index.d.ts +2 -0
  36. package/dist/src/presentation/web/components/common/add-repository-button/index.d.ts.map +1 -0
  37. package/dist/src/presentation/web/components/common/{add-repository-node → add-repository-button}/index.js +0 -1
  38. package/dist/src/presentation/web/components/common/add-repository-button/pick-folder.d.ts.map +1 -0
  39. package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.d.ts.map +1 -1
  40. package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.js +21 -23
  41. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
  42. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +35 -16
  43. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.d.ts.map +1 -1
  44. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.js +2 -0
  45. package/dist/src/presentation/web/components/common/index.d.ts +1 -2
  46. package/dist/src/presentation/web/components/common/index.d.ts.map +1 -1
  47. package/dist/src/presentation/web/components/common/index.js +1 -2
  48. package/dist/src/presentation/web/components/common/repository-node/repository-node.js +1 -1
  49. package/dist/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.d.ts +1 -3
  50. package/dist/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.d.ts.map +1 -1
  51. package/dist/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.js +3 -7
  52. package/dist/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.stories.d.ts +0 -1
  53. package/dist/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.stories.d.ts.map +1 -1
  54. package/dist/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.stories.js +0 -11
  55. package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.js +1 -1
  56. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  57. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +25 -7
  58. package/dist/src/presentation/web/components/features/control-center/control-center.stories.d.ts +0 -11
  59. package/dist/src/presentation/web/components/features/control-center/control-center.stories.d.ts.map +1 -1
  60. package/dist/src/presentation/web/components/features/control-center/control-center.stories.js +2 -37
  61. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +8 -0
  62. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  63. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +145 -256
  64. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts +2 -10
  65. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts.map +1 -1
  66. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.js +12 -44
  67. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.stories.d.ts.map +1 -1
  68. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.stories.js +0 -46
  69. package/dist/src/presentation/web/components/layouts/app-shell/app-shell.js +1 -1
  70. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.d.ts +1 -3
  71. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.d.ts.map +1 -1
  72. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.js +2 -2
  73. package/dist/src/presentation/web/components/ui/scroll-area.js +1 -1
  74. package/dist/src/presentation/web/hooks/use-graph-state.d.ts +42 -0
  75. package/dist/src/presentation/web/hooks/use-graph-state.d.ts.map +1 -0
  76. package/dist/src/presentation/web/hooks/use-graph-state.js +257 -0
  77. package/dist/src/presentation/web/hooks/use-notifications.d.ts +1 -5
  78. package/dist/src/presentation/web/hooks/use-notifications.d.ts.map +1 -1
  79. package/dist/src/presentation/web/hooks/use-notifications.js +1 -26
  80. package/dist/src/presentation/web/hooks/use-notifications.stories.d.ts.map +1 -1
  81. package/dist/src/presentation/web/hooks/use-notifications.stories.js +28 -38
  82. package/dist/src/presentation/web/lib/derive-graph.d.ts +52 -0
  83. package/dist/src/presentation/web/lib/derive-graph.d.ts.map +1 -0
  84. package/dist/src/presentation/web/lib/derive-graph.js +126 -0
  85. package/dist/src/presentation/web/lib/layout-with-dagre.d.ts.map +1 -1
  86. package/dist/src/presentation/web/lib/layout-with-dagre.js +1 -2
  87. package/dist/tsconfig.build.tsbuildinfo +1 -1
  88. package/package.json +1 -1
  89. package/web/.next/BUILD_ID +1 -1
  90. package/web/.next/build-manifest.json +2 -2
  91. package/web/.next/cache/.previewinfo +1 -1
  92. package/web/.next/cache/.rscinfo +1 -1
  93. package/web/.next/cache/.tsbuildinfo +1 -1
  94. package/web/.next/cache/config.json +3 -3
  95. package/web/.next/fallback-build-manifest.json +2 -2
  96. package/web/.next/prerender-manifest.json +3 -3
  97. package/web/.next/required-server-files.js +1 -1
  98. package/web/.next/required-server-files.json +1 -1
  99. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +43 -28
  100. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
  101. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  102. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  103. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +49 -34
  104. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
  105. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  106. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  107. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +39 -24
  108. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
  109. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  110. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  111. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +43 -28
  112. package/web/.next/server/app/(dashboard)/create/page.js +1 -1
  113. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  114. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  115. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +49 -34
  116. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
  117. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  118. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  119. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +39 -24
  120. package/web/.next/server/app/(dashboard)/page.js +1 -1
  121. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  122. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  123. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +39 -24
  124. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
  125. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  126. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  127. package/web/.next/server/app/_global-error.html +2 -2
  128. package/web/.next/server/app/_global-error.rsc +1 -1
  129. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  130. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  131. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  132. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  133. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  134. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  135. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  136. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  137. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  138. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  139. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  140. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  141. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  142. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  143. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  144. package/web/.next/server/app/version/page.js.nft.json +1 -1
  145. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  146. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js +2 -2
  147. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js.map +1 -1
  148. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  149. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  150. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_816618e2.js +3 -0
  151. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_816618e2.js.map +1 -0
  152. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_ba2e050f.js +3 -0
  153. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_ba2e050f.js.map +1 -0
  154. package/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js +2 -2
  155. package/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js.map +1 -1
  156. package/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  157. package/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js +2 -2
  158. package/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js.map +1 -1
  159. package/web/.next/server/chunks/ssr/{[root-of-the-server]__cbae9863._.js → [root-of-the-server]__6258349c._.js} +2 -2
  160. package/web/.next/server/chunks/ssr/[root-of-the-server]__6258349c._.js.map +1 -0
  161. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  162. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  163. package/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js +2 -2
  164. package/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js.map +1 -1
  165. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  166. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  167. package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__e5e09f72._.js → server/chunks/ssr/[root-of-the-server]__94a6d275._.js} +2 -2
  168. package/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js.map +1 -0
  169. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
  170. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
  171. package/web/.next/server/chunks/ssr/_0e9d6bf7._.js +1 -1
  172. package/web/.next/server/chunks/ssr/_0e9d6bf7._.js.map +1 -1
  173. package/web/.next/server/chunks/ssr/_250a63ae._.js.map +1 -1
  174. package/web/.next/server/chunks/ssr/_61351ed3._.js +1 -1
  175. package/web/.next/server/chunks/ssr/_61351ed3._.js.map +1 -1
  176. package/web/.next/server/chunks/ssr/_8400c8bb._.js +1 -1
  177. package/web/.next/server/chunks/ssr/_8400c8bb._.js.map +1 -1
  178. package/web/.next/server/chunks/ssr/_9f940437._.js +1 -1
  179. package/web/.next/server/chunks/ssr/_9f940437._.js.map +1 -1
  180. package/web/.next/server/chunks/ssr/_9fd79ac5._.js +6 -0
  181. package/web/.next/server/chunks/ssr/_9fd79ac5._.js.map +1 -0
  182. package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_398553b0._.js → server/chunks/ssr/src_presentation_web_2b91e4ec._.js} +2 -2
  183. package/web/.next/server/chunks/ssr/{src_presentation_web_5c87e8e4._.js.map → src_presentation_web_2b91e4ec._.js.map} +1 -1
  184. package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_5c87e8e4._.js → server/chunks/ssr/src_presentation_web_5bcc1537._.js} +2 -2
  185. package/web/.next/server/chunks/ssr/{src_presentation_web_398553b0._.js.map → src_presentation_web_5bcc1537._.js.map} +1 -1
  186. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_5955c012.js +3 -0
  187. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_5955c012.js.map +1 -0
  188. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
  189. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +1 -1
  190. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  191. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  192. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  193. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  194. package/web/.next/server/chunks/ssr/src_presentation_web_d5b0cb86._.js +8 -0
  195. package/web/.next/server/chunks/ssr/src_presentation_web_d5b0cb86._.js.map +1 -0
  196. package/web/.next/server/chunks/ssr/src_presentation_web_e626b63c._.js +8 -0
  197. package/web/.next/server/chunks/ssr/src_presentation_web_e626b63c._.js.map +1 -0
  198. package/web/.next/server/pages/500.html +2 -2
  199. package/web/.next/server/server-reference-manifest.js +1 -1
  200. package/web/.next/server/server-reference-manifest.json +175 -118
  201. package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
  202. package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
  203. package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
  204. package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
  205. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +43 -28
  206. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
  207. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  208. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  209. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +49 -34
  210. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
  211. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  212. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  213. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +39 -24
  214. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
  215. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  216. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  217. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +43 -28
  218. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page.js +1 -1
  219. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  220. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  221. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +49 -34
  222. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
  223. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  224. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  225. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +39 -24
  226. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page.js +1 -1
  227. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  228. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  229. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +39 -24
  230. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
  231. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  232. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  233. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
  234. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
  235. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  236. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  237. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  238. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  239. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  240. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  241. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  242. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  243. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  244. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js.nft.json +1 -1
  245. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  246. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  247. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page.js.nft.json +1 -1
  248. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  249. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  250. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page.js.nft.json +1 -1
  251. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  252. package/web/.next/standalone/src/presentation/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js +2 -2
  253. 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
  254. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_816618e2.js +3 -0
  255. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_ba2e050f.js +3 -0
  256. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js +2 -2
  257. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  258. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js +2 -2
  259. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{[root-of-the-server]__cbae9863._.js → [root-of-the-server]__6258349c._.js} +2 -2
  260. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  261. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js +2 -2
  262. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  263. package/web/.next/{server/chunks/ssr/[root-of-the-server]__e5e09f72._.js → standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js} +2 -2
  264. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
  265. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_0e9d6bf7._.js +1 -1
  266. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_61351ed3._.js +1 -1
  267. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_8400c8bb._.js +1 -1
  268. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_9f940437._.js +1 -1
  269. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_9fd79ac5._.js +6 -0
  270. package/web/.next/{server/chunks/ssr/src_presentation_web_398553b0._.js → standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_2b91e4ec._.js} +2 -2
  271. package/web/.next/{server/chunks/ssr/src_presentation_web_5c87e8e4._.js → standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_5bcc1537._.js} +2 -2
  272. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_5955c012.js +3 -0
  273. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
  274. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  275. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  276. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_d5b0cb86._.js +8 -0
  277. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_e626b63c._.js +8 -0
  278. package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
  279. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
  280. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +175 -118
  281. package/web/.next/standalone/src/presentation/web/CLAUDE.md +191 -0
  282. package/web/.next/standalone/src/presentation/web/app/actions/create-feature.ts +27 -2
  283. package/web/.next/standalone/src/presentation/web/app/actions/get-feature-metadata.ts +18 -0
  284. package/web/.next/standalone/src/presentation/web/app/actions/get-graph-data.ts +12 -0
  285. package/web/.next/standalone/src/presentation/web/app/api/agent-events/route.ts +21 -1
  286. package/web/.next/standalone/src/presentation/web/components/common/add-repository-button/index.ts +1 -0
  287. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/create-drawer-client.tsx +23 -26
  288. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx +44 -18
  289. package/web/.next/standalone/src/presentation/web/components/common/feature-node/derive-feature-state.ts +2 -0
  290. package/web/.next/standalone/src/presentation/web/components/common/index.ts +1 -6
  291. package/web/.next/standalone/src/presentation/web/components/common/repository-node/repository-node.tsx +2 -2
  292. package/web/.next/standalone/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.stories.tsx +0 -13
  293. package/web/.next/standalone/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.tsx +1 -45
  294. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-empty-state.tsx +1 -1
  295. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +36 -29
  296. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center.stories.tsx +2 -41
  297. package/web/.next/standalone/src/presentation/web/components/features/control-center/use-control-center-state.ts +178 -325
  298. package/web/.next/standalone/src/presentation/web/components/features/features-canvas/features-canvas.stories.tsx +0 -48
  299. package/web/.next/standalone/src/presentation/web/components/features/features-canvas/features-canvas.tsx +34 -82
  300. package/web/.next/standalone/src/presentation/web/components/layouts/app-shell/app-shell.tsx +1 -1
  301. package/web/.next/standalone/src/presentation/web/components/layouts/app-sidebar/app-sidebar.tsx +2 -14
  302. package/web/.next/standalone/src/presentation/web/components/ui/scroll-area.tsx +1 -1
  303. package/web/.next/standalone/src/presentation/web/hooks/use-graph-state.ts +376 -0
  304. package/web/.next/standalone/src/presentation/web/hooks/use-notifications.stories.tsx +2 -30
  305. package/web/.next/standalone/src/presentation/web/hooks/use-notifications.ts +2 -36
  306. package/web/.next/standalone/src/presentation/web/lib/derive-graph.ts +178 -0
  307. package/web/.next/standalone/src/presentation/web/lib/layout-with-dagre.ts +1 -2
  308. package/web/.next/standalone/src/presentation/web/server.js +1 -1
  309. package/web/.next/static/chunks/{1c07b21eb8b32f25.js → 0b409f42a82665ec.js} +1 -1
  310. package/web/.next/static/chunks/0e035a073754dde7.js +1 -0
  311. package/web/.next/static/chunks/109d6898972d7b78.js +1 -0
  312. package/web/.next/static/chunks/{fcafb841e3860687.js → 5238c7e71fc81e4d.js} +1 -1
  313. package/web/.next/static/chunks/6b4899963367ea96.js +4 -0
  314. package/web/.next/static/chunks/71c9ecdceac1939f.css +2 -0
  315. package/web/.next/static/chunks/752846e217931a38.js +1 -0
  316. package/web/.next/static/chunks/9f9e6f5083600784.js +1 -0
  317. package/web/.next/static/chunks/{8682dcb376de62de.js → ae00da647a8354b9.js} +1 -1
  318. package/web/.next/static/chunks/cb41849bcfaa304e.js +1 -0
  319. package/web/.next/static/chunks/dc23a5773f5cd610.js +1 -0
  320. package/web/.next/trace +1 -1
  321. package/web/.next/trace-build +1 -1
  322. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-button.d.ts.map +0 -1
  323. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node-config.d.ts +0 -7
  324. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node-config.d.ts.map +0 -1
  325. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node-config.js +0 -1
  326. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node.d.ts +0 -6
  327. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node.d.ts.map +0 -1
  328. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node.js +0 -23
  329. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node.stories.d.ts +0 -10
  330. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node.stories.d.ts.map +0 -1
  331. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node.stories.js +0 -33
  332. package/dist/src/presentation/web/components/common/add-repository-node/index.d.ts +0 -4
  333. package/dist/src/presentation/web/components/common/add-repository-node/index.d.ts.map +0 -1
  334. package/dist/src/presentation/web/components/common/add-repository-node/pick-folder.d.ts.map +0 -1
  335. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_2b7834f6.js +0 -3
  336. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_2b7834f6.js.map +0 -1
  337. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_6923c575.js +0 -3
  338. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_6923c575.js.map +0 -1
  339. package/web/.next/server/chunks/ssr/[root-of-the-server]__cbae9863._.js.map +0 -1
  340. package/web/.next/server/chunks/ssr/[root-of-the-server]__e5e09f72._.js.map +0 -1
  341. package/web/.next/server/chunks/ssr/_47ef589d._.js +0 -6
  342. package/web/.next/server/chunks/ssr/_47ef589d._.js.map +0 -1
  343. package/web/.next/server/chunks/ssr/src_presentation_web_1a32dbcb._.js +0 -8
  344. package/web/.next/server/chunks/ssr/src_presentation_web_1a32dbcb._.js.map +0 -1
  345. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f4952172.js +0 -3
  346. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f4952172.js.map +0 -1
  347. package/web/.next/server/chunks/ssr/src_presentation_web_c1bc6240._.js +0 -8
  348. package/web/.next/server/chunks/ssr/src_presentation_web_c1bc6240._.js.map +0 -1
  349. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_2b7834f6.js +0 -3
  350. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_6923c575.js +0 -3
  351. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_47ef589d._.js +0 -6
  352. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_1a32dbcb._.js +0 -8
  353. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f4952172.js +0 -3
  354. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_c1bc6240._.js +0 -8
  355. package/web/.next/standalone/src/presentation/web/components/common/add-repository-node/add-repository-node-config.ts +0 -8
  356. package/web/.next/standalone/src/presentation/web/components/common/add-repository-node/add-repository-node.stories.tsx +0 -70
  357. package/web/.next/standalone/src/presentation/web/components/common/add-repository-node/add-repository-node.tsx +0 -49
  358. package/web/.next/standalone/src/presentation/web/components/common/add-repository-node/index.ts +0 -3
  359. package/web/.next/static/chunks/3c79bca4d3f18f66.js +0 -1
  360. package/web/.next/static/chunks/5cd24ca47061a21d.js +0 -4
  361. package/web/.next/static/chunks/67f2a7a5e8dc358a.css +0 -2
  362. package/web/.next/static/chunks/71cf72022f08a8c9.js +0 -1
  363. package/web/.next/static/chunks/991d4490d7a338d8.js +0 -1
  364. package/web/.next/static/chunks/c71589df79020ecb.js +0 -1
  365. package/web/.next/static/chunks/ebf172a84c9596ed.js +0 -1
  366. package/web/.next/static/chunks/fabfa54940973cc7.js +0 -1
  367. /package/dist/src/presentation/web/components/common/{add-repository-node → add-repository-button}/add-repository-button.d.ts +0 -0
  368. /package/dist/src/presentation/web/components/common/{add-repository-node → add-repository-button}/add-repository-button.js +0 -0
  369. /package/dist/src/presentation/web/components/common/{add-repository-node → add-repository-button}/pick-folder.d.ts +0 -0
  370. /package/dist/src/presentation/web/components/common/{add-repository-node → add-repository-button}/pick-folder.js +0 -0
  371. /package/web/.next/standalone/src/presentation/web/components/common/{add-repository-node → add-repository-button}/add-repository-button.tsx +0 -0
  372. /package/web/.next/standalone/src/presentation/web/components/common/{add-repository-node → add-repository-button}/pick-folder.ts +0 -0
  373. /package/web/.next/static/{IKuYPxAuMvc4BtwKHlj30 → JYBKfZ0ROsNn817Id2TJ7}/_buildManifest.js +0 -0
  374. /package/web/.next/static/{IKuYPxAuMvc4BtwKHlj30 → JYBKfZ0ROsNn817Id2TJ7}/_clientMiddlewareManifest.json +0 -0
  375. /package/web/.next/static/{IKuYPxAuMvc4BtwKHlj30 → JYBKfZ0ROsNn817Id2TJ7}/_ssgManifest.js +0 -0
@@ -27,15 +27,33 @@ export async function createFeature(input) {
27
27
  };
28
28
  try {
29
29
  const createFeatureUseCase = resolve('CreateFeatureUseCase');
30
- const result = await createFeatureUseCase.execute({
30
+ // Phase 1 (fast): create DB record with real UUID — returns immediately
31
+ const { feature, shouldSpawn } = await createFeatureUseCase.createRecord({
31
32
  userInput,
32
33
  repositoryPath,
33
34
  approvalGates: gates,
34
35
  push: push ?? false,
35
36
  openPr: openPr ?? false,
36
37
  ...(parentId ? { parentId } : {}),
38
+ name,
39
+ description,
37
40
  });
38
- return { feature: result.feature };
41
+ // Phase 2 (background): metadata generation, worktree, spec, agent spawn
42
+ // Fire-and-forget — the UI gets the real feature ID immediately
43
+ createFeatureUseCase
44
+ .initializeAndSpawn(feature, {
45
+ userInput,
46
+ repositoryPath,
47
+ approvalGates: gates,
48
+ push: push ?? false,
49
+ openPr: openPr ?? false,
50
+ ...(parentId ? { parentId } : {}),
51
+ }, shouldSpawn)
52
+ .catch((err) => {
53
+ // eslint-disable-next-line no-console
54
+ console.error('[createFeature] initializeAndSpawn failed:', err);
55
+ });
56
+ return { feature };
39
57
  }
40
58
  catch (error) {
41
59
  const message = error instanceof Error ? error.message : 'Failed to create feature';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Lightweight server action to fetch a single feature's name and description.
3
+ * Used by the SSE effect to update node metadata after AI metadata generation
4
+ * without a full graph reconcile (which can overwrite SSE-driven state).
5
+ */
6
+ export declare function getFeatureMetadata(featureId: string): Promise<{
7
+ name: string;
8
+ description: string;
9
+ } | null>;
10
+ //# sourceMappingURL=get-feature-metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-feature-metadata.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/get-feature-metadata.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAKvD"}
@@ -0,0 +1,14 @@
1
+ 'use server';
2
+ import { resolve } from '../../lib/server-container.js';
3
+ /**
4
+ * Lightweight server action to fetch a single feature's name and description.
5
+ * Used by the SSE effect to update node metadata after AI metadata generation
6
+ * without a full graph reconcile (which can overwrite SSE-driven state).
7
+ */
8
+ export async function getFeatureMetadata(featureId) {
9
+ const featureRepo = resolve('IFeatureRepository');
10
+ const feature = await featureRepo.findById(featureId);
11
+ if (!feature)
12
+ return null;
13
+ return { name: feature.name, description: feature.description };
14
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Server action that fetches fresh graph nodes and edges.
3
+ * Used as a lightweight polling fallback for active features,
4
+ * avoiding full router.refresh() page re-renders.
5
+ */
6
+ export declare function fetchGraphData(): Promise<{
7
+ nodes: import("../../components/features/features-canvas/index.js").CanvasNodeType[];
8
+ edges: import("@xyflow/react").Edge[];
9
+ }>;
10
+ //# sourceMappingURL=get-graph-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-graph-data.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/get-graph-data.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAsB,cAAc;;;GAEnC"}
@@ -0,0 +1,10 @@
1
+ 'use server';
2
+ import { getGraphData } from '../(dashboard)/get-graph-data.js';
3
+ /**
4
+ * Server action that fetches fresh graph nodes and edges.
5
+ * Used as a lightweight polling fallback for active features,
6
+ * avoiding full router.refresh() page re-renders.
7
+ */
8
+ export async function fetchGraphData() {
9
+ return getGraphData();
10
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/app/api/agent-events/route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAgBH,eAAO,MAAM,OAAO,kBAAkB,CAAC;AA4DvC,wBAAgB,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,CAkM9C"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/app/api/agent-events/route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAgBH,eAAO,MAAM,OAAO,kBAAkB,CAAC;AA+DvC,wBAAgB,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,CAmN9C"}
@@ -24,12 +24,15 @@ const HEARTBEAT_INTERVAL_MS = 30_000;
24
24
  * can derive the correct FeatureLifecyclePhase via mapPhaseNameToLifecycle().
25
25
  */
26
26
  const LIFECYCLE_TO_NODE = {
27
+ [SdlcLifecycle.Started]: 'requirements',
27
28
  [SdlcLifecycle.Analyze]: 'analyze',
28
29
  [SdlcLifecycle.Requirements]: 'requirements',
29
30
  [SdlcLifecycle.Research]: 'research',
30
31
  [SdlcLifecycle.Planning]: 'plan',
31
32
  [SdlcLifecycle.Implementation]: 'implement',
32
33
  [SdlcLifecycle.Review]: 'merge',
34
+ [SdlcLifecycle.Maintain]: 'maintain',
35
+ [SdlcLifecycle.Blocked]: 'blocked',
33
36
  };
34
37
  const STATUS_TO_EVENT = {
35
38
  [AgentRunStatus.running]: {
@@ -150,6 +153,21 @@ export function GET(request) {
150
153
  });
151
154
  }
152
155
  }
156
+ // Check for feature name change (AI metadata generation updates name)
157
+ if (prev.featureName !== feature.name) {
158
+ prev.featureName = feature.name;
159
+ const nodeName = LIFECYCLE_TO_NODE[feature.lifecycle] ?? 'requirements';
160
+ emitEvent({
161
+ eventType: NotificationEventType.PhaseCompleted,
162
+ agentRunId: run.id,
163
+ featureId: feature.id,
164
+ featureName: feature.name,
165
+ phaseName: nodeName,
166
+ message: `Feature metadata updated`,
167
+ severity: NotificationSeverity.Info,
168
+ timestamp: new Date().toISOString(),
169
+ });
170
+ }
153
171
  // Check for lifecycle change (agent stays "running" but moves through phases)
154
172
  if (prev.lifecycle !== feature.lifecycle) {
155
173
  prev.lifecycle = feature.lifecycle;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-repository-button.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/add-repository-button/add-repository-button.tsx"],"names":[],"mappings":"AAQA,UAAU,wBAAwB;IAChC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,wBAAgB,mBAAmB,CAAC,EAAE,QAAQ,EAAE,EAAE,wBAAwB,2CAuCzE"}
@@ -0,0 +1,2 @@
1
+ export { AddRepositoryButton } from './add-repository-button.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/add-repository-button/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -1,2 +1 @@
1
- export { AddRepositoryNode } from './add-repository-node.js';
2
1
  export { AddRepositoryButton } from './add-repository-button.js';
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pick-folder.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/add-repository-button/pick-folder.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQzD"}
@@ -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,2CA+EzB"}
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;AAE5E,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,2CA6EzB"}
@@ -5,10 +5,8 @@ import { useRouter, usePathname } from 'next/navigation';
5
5
  import { toast } from 'sonner';
6
6
  import { createFeature } from '../../../app/actions/create-feature.js';
7
7
  import { FeatureCreateDrawer } from '../../common/feature-create-drawer/index.js';
8
- import { useSoundAction } from '../../../hooks/use-sound-action.js';
9
8
  export function CreateDrawerClient({ repositoryPath, initialParentId, features, workflowDefaults, }) {
10
9
  const router = useRouter();
11
- const createSound = useSoundAction('create');
12
10
  const [isSubmitting, setIsSubmitting] = useState(false);
13
11
  // Derive open state from the URL. Next.js parallel routes preserve slot
14
12
  // content during soft navigation, so this component is NOT unmounted when
@@ -17,48 +15,48 @@ export function CreateDrawerClient({ repositoryPath, initialParentId, features,
17
15
  // When submitting, force the drawer closed immediately — router.push('/')
18
16
  // is async and the pathname may not update before the next render.
19
17
  const pathname = usePathname();
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.
18
+ const isOnCreateRoute = pathname.startsWith('/create');
19
+ const isOpen = !isSubmitting && isOnCreateRoute;
20
+ // Reset isSubmitting once the route has actually changed away from /create,
21
+ // so the drawer can reopen on future visits. Without this, isSubmitting
22
+ // would stay true forever since parallel routes preserve component state.
23
23
  useEffect(() => {
24
- if (!isOpen && pathname.startsWith('/create')) {
25
- router.replace('/');
24
+ if (!isOnCreateRoute && isSubmitting) {
25
+ setIsSubmitting(false);
26
26
  }
27
- }, [isOpen, pathname, router]);
27
+ }, [isOnCreateRoute, isSubmitting]);
28
28
  const onClose = useCallback(() => {
29
29
  router.push('/');
30
30
  }, [router]);
31
31
  const onSubmit = useCallback((data) => {
32
32
  setIsSubmitting(true);
33
- // Dispatch event for optimistic canvas update before navigating
34
- window.dispatchEvent(new CustomEvent('shep:feature-created', {
35
- detail: {
36
- name: data.name,
37
- description: data.description,
38
- repositoryPath: data.repositoryPath,
39
- parentId: data.parentId,
40
- },
41
- }));
42
33
  // Close the drawer immediately for responsive UI
43
34
  router.push('/');
44
- // Fire server action in the background
35
+ // Server action Phase 1 returns fast with real feature ID (DB record created)
36
+ // Phase 2 (metadata, worktree, agent) runs in background on server
45
37
  createFeature(data)
46
38
  .then((result) => {
47
39
  if (result.error) {
48
40
  toast.error(result.error);
49
- // Dispatch rollback event
50
41
  window.dispatchEvent(new CustomEvent('shep:feature-create-failed'));
51
42
  return;
52
43
  }
53
- createSound.play();
44
+ // Dispatch event with real feature ID so control center adds it to featureMap
45
+ window.dispatchEvent(new CustomEvent('shep:feature-created', {
46
+ detail: {
47
+ featureId: result.feature.id,
48
+ name: result.feature.name,
49
+ description: result.feature.description,
50
+ repositoryPath: result.feature.repositoryPath,
51
+ parentId: data.parentId,
52
+ },
53
+ }));
54
54
  })
55
55
  .catch(() => {
56
56
  toast.error('Failed to create feature');
57
57
  window.dispatchEvent(new CustomEvent('shep:feature-create-failed'));
58
- })
59
- .finally(() => {
60
58
  setIsSubmitting(false);
61
59
  });
62
- }, [router, createSound]);
60
+ }, [router]);
63
61
  return (_jsx(FeatureCreateDrawer, { open: isOpen, onClose: onClose, onSubmit: onSubmit, repositoryPath: repositoryPath, features: features, workflowDefaults: workflowDefaults, initialParentId: initialParentId, isSubmitting: isSubmitting }));
64
62
  }
@@ -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,2CAimBlF"}
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,2CAgnBlF"}
@@ -4,7 +4,7 @@ import { useState, useCallback, useEffect, useRef } from 'react';
4
4
  import { useRouter, usePathname } from 'next/navigation';
5
5
  import { toast } from 'sonner';
6
6
  import { Loader2, Trash2, ExternalLink, GitCommitHorizontal, Play, Square } from 'lucide-react';
7
- import { PrStatus } from '../../../../../../packages/core/src/domain/generated/output.js';
7
+ import { PrStatus, NotificationEventType } from '../../../../../../packages/core/src/domain/generated/output.js';
8
8
  import { approveFeature } from '../../../app/actions/approve-feature.js';
9
9
  import { rejectFeature } from '../../../app/actions/reject-feature.js';
10
10
  import { getFeatureArtifact } from '../../../app/actions/get-feature-artifact.js';
@@ -59,32 +59,41 @@ export function FeatureDrawerClient({ view: initialView }) {
59
59
  return;
60
60
  const newEvents = events.slice(processedCountRef.current);
61
61
  processedCountRef.current = events.length;
62
+ // PhaseCompleted must NOT set state when WaitingApproval is in the same poll batch.
63
+ // But when it arrives without WaitingApproval (e.g. post-approval), allow it as
64
+ // a fallback for missed AgentStarted events.
65
+ const waitingApprovalInBatch = newEvents.some((e) => e.featureId === featureNode.featureId &&
66
+ e.eventType === NotificationEventType.WaitingApproval);
62
67
  for (const event of newEvents) {
63
68
  if (event.featureId !== featureNode.featureId)
64
69
  continue;
65
- const newState = mapEventTypeToState(event.eventType);
70
+ const newState = event.eventType === NotificationEventType.PhaseCompleted && waitingApprovalInBatch
71
+ ? undefined
72
+ : mapEventTypeToState(event.eventType);
66
73
  const newLifecycle = mapPhaseNameToLifecycle(event.phaseName);
67
74
  // Trigger a server refresh to get the latest drawer view,
68
75
  // but skip when the user has unsaved changes or a rejection is in-flight
69
76
  // to avoid the refresh interfering with the reject handler's navigation.
70
77
  if (!isDirtyRef.current && !isRejectingRef.current)
71
78
  router.refresh();
72
- // Optimistically update the node data for immediate UI feedback
73
- setView((prev) => {
74
- if (prev.type !== 'feature' &&
75
- prev.type !== 'prd-review' &&
76
- prev.type !== 'tech-review' &&
77
- prev.type !== 'merge-review')
78
- return prev;
79
- return {
80
- ...prev,
81
- node: {
79
+ if (newState !== undefined || newLifecycle !== undefined) {
80
+ // Optimistically update the node data AND re-derive the view type so the
81
+ // drawer switches immediately (e.g. prd-review feature when agent resumes)
82
+ // without waiting for the router.refresh() round-trip.
83
+ setView((prev) => {
84
+ if (prev.type !== 'feature' &&
85
+ prev.type !== 'prd-review' &&
86
+ prev.type !== 'tech-review' &&
87
+ prev.type !== 'merge-review')
88
+ return prev;
89
+ const updatedNode = {
82
90
  ...prev.node,
83
- state: newState,
91
+ ...(newState !== undefined && { state: newState }),
84
92
  ...(newLifecycle !== undefined && { lifecycle: newLifecycle }),
85
- },
86
- };
87
- });
93
+ };
94
+ return { ...prev, type: deriveViewType(updatedNode), node: updatedNode };
95
+ });
96
+ }
88
97
  }
89
98
  }, [events, featureNode, router]);
90
99
  // Derive open state from the URL. Next.js parallel routes preserve slot
@@ -420,3 +429,13 @@ function FeatureDetails({ data }) {
420
429
  function DetailRow({ label, value }) {
421
430
  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 })] }));
422
431
  }
432
+ /** Mirrors computeDrawerView logic — derives view type from live node data. */
433
+ function deriveViewType(node) {
434
+ if (node.lifecycle === 'requirements' && node.state === 'action-required')
435
+ return 'prd-review';
436
+ if (node.lifecycle === 'implementation' && node.state === 'action-required')
437
+ return 'tech-review';
438
+ if (node.lifecycle === 'review' && (node.state === 'action-required' || node.state === 'error'))
439
+ return 'merge-review';
440
+ return 'feature';
441
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"derive-feature-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/derive-feature-state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAIL,qBAAqB,EACtB,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAE3F;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,GAAG,gBAAgB,CA4C9F;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAYvD;AAED,oGAAoG;AACpG,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,qBAAqB,GAAG,gBAAgB,CAkBtF;AAYD,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,qBAAqB,GAAG,SAAS,CAGnC"}
1
+ {"version":3,"file":"derive-feature-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/derive-feature-state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAIL,qBAAqB,EACtB,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAE3F;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,GAAG,gBAAgB,CA4C9F;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAYvD;AAED,oGAAoG;AACpG,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,qBAAqB,GAAG,gBAAgB,CAkBtF;AAcD,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,qBAAqB,GAAG,SAAS,CAGnC"}
@@ -101,6 +101,8 @@ const phaseNameToLifecycle = {
101
101
  plan: 'implementation',
102
102
  implement: 'implementation',
103
103
  merge: 'review',
104
+ maintain: 'maintain',
105
+ blocked: 'requirements',
104
106
  };
105
107
  export function mapPhaseNameToLifecycle(phaseName) {
106
108
  if (!phaseName)
@@ -1,5 +1,5 @@
1
1
  export { ControlCenterDrawer, type ControlCenterDrawerProps, computeDrawerView, type DrawerView, } from './control-center-drawer/index.js';
2
- export { AddRepositoryNode, type AddRepositoryNodeData, type AddRepositoryNodeType, } from './add-repository-node/index.js';
2
+ export { AddRepositoryButton } from './add-repository-button/index.js';
3
3
  export { ElapsedTime, formatElapsed } from './elapsed-time/index.js';
4
4
  export { EmptyState, type EmptyStateProps } from './empty-state/index.js';
5
5
  export { FeatureCreateDrawer, type FeatureCreateDrawerProps, type FeatureCreatePayload, } from './feature-create-drawer/index.js';
@@ -10,7 +10,6 @@ export { FeatureNode, featureNodeStateConfig, type FeatureNodeState, type Featur
10
10
  export { FeatureStatusBadges, type FeatureStatusBadgesProps } from './feature-status-badges/index.js';
11
11
  export { FeatureStatusGroup, type FeatureStatusGroupProps } from './feature-status-group/index.js';
12
12
  export { LoadingSkeleton } from './loading-skeleton/index.js';
13
- export { NotificationPermissionBanner } from './notification-permission-banner/index.js';
14
13
  export { RepositoryNode, type RepositoryNodeData, type RepositoryNodeType, } from './repository-node/index.js';
15
14
  export { PageHeader } from './page-header/index.js';
16
15
  export { PrdQuestionnaire, PrdQuestionnaireDrawer, type PrdQuestionnaireProps, type PrdQuestionnaireDrawerProps, type PrdQuestion, type PrdFinalAction, type PrdOption, type PrdQuestionnaireData, } from './prd-questionnaire/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,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,iBAAiB,EACjB,KAAK,UAAU,GAChB,MAAM,yBAAyB,CAAC;AACjC,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,oBAAoB,GAC1B,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,iBAAiB,EACjB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,GACzB,MAAM,sCAAsC,CAAC;AAC9C,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,EAAE,4BAA4B,EAAE,MAAM,kCAAkC,CAAC;AAChF,OAAO,EACL,cAAc,EACd,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,GAC7B,MAAM,yBAAyB,CAAC;AACjC,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,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,iBAAiB,EACjB,KAAK,UAAU,GAChB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,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,oBAAoB,GAC1B,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,iBAAiB,EACjB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,GACzB,MAAM,sCAAsC,CAAC;AAC9C,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,EACL,gBAAgB,EAChB,sBAAsB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,GAC7B,MAAM,yBAAyB,CAAC;AACjC,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,5 +1,5 @@
1
1
  export { ControlCenterDrawer, computeDrawerView, } from './control-center-drawer/index.js';
2
- export { AddRepositoryNode, } from './add-repository-node/index.js';
2
+ export { AddRepositoryButton } from './add-repository-button/index.js';
3
3
  export { ElapsedTime, formatElapsed } from './elapsed-time/index.js';
4
4
  export { EmptyState } from './empty-state/index.js';
5
5
  export { FeatureCreateDrawer, } from './feature-create-drawer/index.js';
@@ -10,7 +10,6 @@ export { FeatureNode, featureNodeStateConfig, } from './feature-node/index.js';
10
10
  export { FeatureStatusBadges } from './feature-status-badges/index.js';
11
11
  export { FeatureStatusGroup } from './feature-status-group/index.js';
12
12
  export { LoadingSkeleton } from './loading-skeleton/index.js';
13
- export { NotificationPermissionBanner } from './notification-permission-banner/index.js';
14
13
  export { RepositoryNode, } from './repository-node/index.js';
15
14
  export { PageHeader } from './page-header/index.js';
16
15
  export { PrdQuestionnaire, PrdQuestionnaireDrawer, } from './prd-questionnaire/index.js';
@@ -23,7 +23,7 @@ export function RepositoryNode({ data }) {
23
23
  }
24
24
  : null);
25
25
  const isDeploymentActive = deployAction.status === 'Booting' || deployAction.status === 'Ready';
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
+ return (_jsxs("div", { className: cn('group relative', data.onDelete && data.id && 'pl-10'), 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-0 -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) => {
27
27
  e.stopPropagation();
28
28
  setConfirmOpen(true);
29
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: () => {
@@ -1,8 +1,6 @@
1
1
  export interface SidebarSectionHeaderProps {
2
2
  label: string;
3
- onFolderClick?: () => void;
4
- onMenuClick?: () => void;
5
3
  className?: string;
6
4
  }
7
- export declare function SidebarSectionHeader({ label, onFolderClick, onMenuClick, className, }: SidebarSectionHeaderProps): import("react/jsx-runtime").JSX.Element;
5
+ export declare function SidebarSectionHeader({ label, className }: SidebarSectionHeaderProps): import("react/jsx-runtime").JSX.Element;
8
6
  //# sourceMappingURL=sidebar-section-header.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar-section-header.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.tsx"],"names":[],"mappings":"AAQA,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,oBAAoB,CAAC,EACnC,KAAK,EACL,aAAa,EACb,WAAW,EACX,SAAS,GACV,EAAE,yBAAyB,2CA0C3B"}
1
+ {"version":3,"file":"sidebar-section-header.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,oBAAoB,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,yBAAyB,2CAQnF"}
@@ -1,11 +1,7 @@
1
1
  'use client';
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Folder, GripHorizontal } from 'lucide-react';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
4
3
  import { SidebarGroup } from '../../ui/sidebar.js';
5
- import { Tooltip, TooltipContent, TooltipTrigger } from '../../ui/tooltip.js';
6
- import { useSidebar } from '../../ui/sidebar.js';
7
4
  import { cn } from '../../../lib/utils.js';
8
- export function SidebarSectionHeader({ label, onFolderClick, onMenuClick, className, }) {
9
- const { state, isMobile } = useSidebar();
10
- return (_jsx(SidebarGroup, { "data-testid": "sidebar-section-header", className: cn('px-2 py-1', className), children: _jsxs("div", { className: "text-sidebar-foreground flex h-7 w-full shrink-0 items-center px-2 text-sm font-medium", children: [_jsx("span", { className: "min-w-0 flex-1 truncate", children: label }), _jsxs("span", { className: "text-sidebar-foreground/70 flex shrink-0 items-center gap-0.5", children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: onFolderClick, className: "ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground flex size-7 items-center justify-center rounded-md p-0 outline-hidden transition-colors focus-visible:ring-2 [&>svg]:size-4", "aria-label": "Open features folder", children: _jsx(Folder, { className: "size-4" }) }) }), _jsx(TooltipContent, { side: "right", align: "center", hidden: state !== 'collapsed' || isMobile, children: "Open features folder" })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: onMenuClick, className: "ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground flex size-7 items-center justify-center rounded-md p-0 outline-hidden transition-colors focus-visible:ring-2 [&>svg]:size-4", "aria-label": "Features options", children: _jsx(GripHorizontal, { className: "size-4" }) }) }), _jsx(TooltipContent, { side: "right", align: "center", hidden: state !== 'collapsed' || isMobile, children: "Features options" })] })] })] }) }));
5
+ export function SidebarSectionHeader({ label, className }) {
6
+ return (_jsx(SidebarGroup, { "data-testid": "sidebar-section-header", className: cn('px-2 py-1', className), children: _jsx("div", { className: "text-sidebar-foreground flex h-7 w-full shrink-0 items-center px-2 text-sm font-medium", children: _jsx("span", { className: "min-w-0 flex-1 truncate", children: label }) }) }));
11
7
  }
@@ -4,5 +4,4 @@ declare const meta: Meta<typeof SidebarSectionHeader>;
4
4
  export default meta;
5
5
  type Story = StoryObj<typeof meta>;
6
6
  export declare const Default: Story;
7
- export declare const WithActions: Story;
8
7
  //# sourceMappingURL=sidebar-section-header.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar-section-header.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,oBAAoB,CAgB3C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAIrB,CAAC;AAOF,eAAO,MAAM,WAAW,EAAE,KAMzB,CAAC"}
1
+ {"version":3,"file":"sidebar-section-header.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,oBAAoB,CAgB3C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAIrB,CAAC"}
@@ -18,14 +18,3 @@ export const Default = {
18
18
  label: 'Features',
19
19
  },
20
20
  };
21
- function noop() {
22
- // Intentional no-op for Storybook interaction demos
23
- return;
24
- }
25
- export const WithActions = {
26
- args: {
27
- label: 'Features',
28
- onFolderClick: noop,
29
- onMenuClick: noop,
30
- },
31
- };
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useState, useCallback } from 'react';
4
4
  import { Github, Plus, TerminalSquare, Copy, Check, Loader2 } from 'lucide-react';
5
5
  import { cn } from '../../../lib/utils.js';
6
- import { pickFolder } from '../../common/add-repository-node/pick-folder.js';
6
+ import { pickFolder } from '../../common/add-repository-button/pick-folder.js';
7
7
  const commands = ['cd ~/my-repo', 'shep feat new "create modern, sleek dashboards"'];
8
8
  export function ControlCenterEmptyState({ onRepositorySelect, className, }) {
9
9
  const [copied, setCopied] = useState(false);
@@ -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,2CA4NzF"}
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;AAa5E,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,2CAoOzF"}
@@ -1,9 +1,8 @@
1
1
  'use client';
2
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { useCallback, useEffect, useMemo } from 'react';
4
4
  import { useRouter, usePathname } from 'next/navigation';
5
5
  import { FeaturesCanvas } from '../../features/features-canvas/index.js';
6
- import { NotificationPermissionBanner } from '../../common/notification-permission-banner/index.js';
7
6
  import { useSidebarFeaturesContext, mapNodeStateToSidebarStatus, } from '../../../hooks/sidebar-features-context.js';
8
7
  import { useSelectedFeatureId } from '../../../hooks/use-selected-feature-id.js';
9
8
  import { useSoundAction } from '../../../hooks/use-sound-action.js';
@@ -16,7 +15,7 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
16
15
  const selectedFeatureId = useSelectedFeatureId();
17
16
  const clickSound = useSoundAction('click');
18
17
  const { guardedNavigate } = useDrawerCloseGuard();
19
- const { nodes, edges, onNodesChange, handleConnect, handleAddRepository, handleDeleteFeature, handleDeleteRepository, createFeatureNode, } = useControlCenterState(initialNodes, initialEdges);
18
+ const { nodes, edges, onNodesChange, handleConnect, handleAddRepository, handleDeleteFeature, handleDeleteRepository, createFeatureNode, setCallbacks, } = useControlCenterState(initialNodes, initialEdges);
20
19
  // Publish sidebar features to context whenever feature node data changes
21
20
  const { setFeatures: setSidebarFeatures } = useSidebarFeaturesContext();
22
21
  const sidebarKey = useMemo(() => {
@@ -112,7 +111,7 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
112
111
  window.addEventListener('shep:add-repository', handler);
113
112
  return () => window.removeEventListener('shep:add-repository', handler);
114
113
  }, [handleAddRepository]);
115
- // Listen for optimistic create events from the create drawer
114
+ // Listen for create events from the create drawer (with real feature ID from server)
116
115
  useEffect(() => {
117
116
  const handler = (e) => {
118
117
  const detail = e.detail;
@@ -122,6 +121,7 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
122
121
  const parentNodeId = `feat-${detail.parentId}`;
123
122
  createFeatureNode(parentNodeId, {
124
123
  state: 'creating',
124
+ featureId: detail.featureId,
125
125
  name: detail.name,
126
126
  description: detail.description,
127
127
  repositoryPath: detail.repositoryPath,
@@ -132,7 +132,8 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
132
132
  const repoNode = nodes.find((n) => n.type === 'repositoryNode' &&
133
133
  n.data.repositoryPath === detail.repositoryPath);
134
134
  createFeatureNode(repoNode?.id ?? null, {
135
- state: 'creating',
135
+ state: 'running',
136
+ featureId: detail.featureId,
136
137
  name: detail.name,
137
138
  description: detail.description,
138
139
  repositoryPath: detail.repositoryPath,
@@ -141,9 +142,26 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
141
142
  window.addEventListener('shep:feature-created', handler);
142
143
  return () => window.removeEventListener('shep:feature-created', handler);
143
144
  }, [nodes, createFeatureNode]);
145
+ // Wire callbacks into derived node data (via ref — no re-render).
146
+ useEffect(() => {
147
+ setCallbacks({
148
+ onNodeAction: handleAddFeatureToFeature,
149
+ onFeatureDelete: handleDeleteFeature,
150
+ onRepositoryAdd: handleAddFeatureToRepo,
151
+ onRepositoryClick: handleRepositoryClick,
152
+ onRepositoryDelete: handleDeleteRepository,
153
+ });
154
+ }, [
155
+ setCallbacks,
156
+ handleAddFeatureToFeature,
157
+ handleDeleteFeature,
158
+ handleAddFeatureToRepo,
159
+ handleRepositoryClick,
160
+ handleDeleteRepository,
161
+ ]);
144
162
  const hasRepositories = nodes.some((n) => n.type === 'repositoryNode');
145
163
  if (!hasRepositories) {
146
- return (_jsxs(_Fragment, { children: [_jsx(NotificationPermissionBanner, {}), _jsx(ControlCenterEmptyState, { onRepositorySelect: handleAddRepository })] }));
164
+ return _jsx(ControlCenterEmptyState, { onRepositorySelect: handleAddRepository });
147
165
  }
148
- return (_jsxs(_Fragment, { children: [_jsx(NotificationPermissionBanner, {}), _jsx(FeaturesCanvas, { nodes: nodes, edges: edges, selectedFeatureId: selectedFeatureId, onNodesChange: onNodesChange, onConnect: handleConnect, onAddFeature: handleAddFeature, onNodeAction: handleAddFeatureToFeature, onNodeClick: handleNodeClick, onPaneClick: handleClearDrawers, onRepositoryAdd: handleAddFeatureToRepo, onRepositoryClick: handleRepositoryClick, onRepositoryDelete: handleDeleteRepository, onFeatureDelete: handleDeleteFeature, onRepositorySelect: handleAddRepository, emptyState: _jsx(ControlCenterEmptyState, { onRepositorySelect: handleAddRepository }) })] }));
166
+ return (_jsx(FeaturesCanvas, { nodes: nodes, edges: edges, selectedFeatureId: selectedFeatureId, onNodesChange: onNodesChange, onConnect: handleConnect, onAddFeature: handleAddFeature, onNodeClick: handleNodeClick, onPaneClick: handleClearDrawers, emptyState: _jsx(ControlCenterEmptyState, { onRepositorySelect: handleAddRepository }) }));
149
167
  }
@@ -7,17 +7,6 @@ export declare const Empty: Story;
7
7
  export declare const WithFeatures: Story;
8
8
  export declare const WithToolbar: Story;
9
9
  export declare const WithNodeActions: Story;
10
- /**
11
- * Interactive story — starts with just an "Add Repository" button.
12
- *
13
- * User flow:
14
- * 1. Click "Add Repository" → native folder picker → select a folder → repo node appears
15
- * 2. Hover the repo node → click (+) → a new feature node appears connected to the repo
16
- * 3. Hover the feature node → click (+) → another feature appears connected to the first
17
- *
18
- * You can also use the toolbar "Add Feature" button to create unconnected features.
19
- */
20
- export declare const Interactive: Story;
21
10
  /**
22
11
  * Dagre auto-layout story — two repositories with interconnected feature trees.
23
12
  *
@@ -1 +1 @@
1
- {"version":3,"file":"control-center.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AASjD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,aAAa,CAkBpC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAiFnC,eAAO,MAAM,KAAK,EAAE,KAKnB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAQ1B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAKzB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAS7B,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,EAAE,KAYzB,CAAC;AAwIF;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,EAAE,KAKzB,CAAC"}
1
+ {"version":3,"file":"control-center.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAQjD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,aAAa,CAkBpC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AA0EnC,eAAO,MAAM,KAAK,EAAE,KAKnB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAQ1B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAKzB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAS7B,CAAC;AAiIF;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,EAAE,KAKzB,CAAC"}