@shepai/cli 1.137.0 → 1.138.0-pr445.9f2c136

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 (251) hide show
  1. package/apis/json-schema/Feature.yaml +3 -0
  2. package/apis/json-schema/SdlcLifecycle.yaml +1 -0
  3. package/dist/packages/core/src/application/ports/output/repositories/feature-repository.interface.d.ts +2 -0
  4. package/dist/packages/core/src/application/ports/output/repositories/feature-repository.interface.d.ts.map +1 -1
  5. package/dist/packages/core/src/application/use-cases/features/archive-feature.use-case.d.ts +20 -0
  6. package/dist/packages/core/src/application/use-cases/features/archive-feature.use-case.d.ts.map +1 -0
  7. package/dist/packages/core/src/application/use-cases/features/archive-feature.use-case.js +73 -0
  8. package/dist/packages/core/src/application/use-cases/features/unarchive-feature.use-case.d.ts +20 -0
  9. package/dist/packages/core/src/application/use-cases/features/unarchive-feature.use-case.d.ts.map +1 -0
  10. package/dist/packages/core/src/application/use-cases/features/unarchive-feature.use-case.js +65 -0
  11. package/dist/packages/core/src/domain/generated/output.d.ts +6 -1
  12. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  13. package/dist/packages/core/src/domain/generated/output.js +1 -0
  14. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  15. package/dist/packages/core/src/infrastructure/di/container.js +10 -0
  16. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts +1 -0
  17. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts.map +1 -1
  18. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.js +6 -0
  19. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/044-add-previous-lifecycle.d.ts +12 -0
  20. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/044-add-previous-lifecycle.d.ts.map +1 -0
  21. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/044-add-previous-lifecycle.js +16 -0
  22. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.d.ts.map +1 -1
  23. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.js +7 -2
  24. package/dist/src/presentation/cli/commands/feat/archive.command.d.ts +18 -0
  25. package/dist/src/presentation/cli/commands/feat/archive.command.d.ts.map +1 -0
  26. package/dist/src/presentation/cli/commands/feat/archive.command.js +54 -0
  27. package/dist/src/presentation/cli/commands/feat/index.d.ts.map +1 -1
  28. package/dist/src/presentation/cli/commands/feat/index.js +5 -1
  29. package/dist/src/presentation/cli/commands/feat/ls.command.d.ts.map +1 -1
  30. package/dist/src/presentation/cli/commands/feat/ls.command.js +5 -0
  31. package/dist/src/presentation/cli/commands/feat/unarchive.command.d.ts +17 -0
  32. package/dist/src/presentation/cli/commands/feat/unarchive.command.d.ts.map +1 -0
  33. package/dist/src/presentation/cli/commands/feat/unarchive.command.js +42 -0
  34. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.d.ts.map +1 -1
  35. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.js +6 -1
  36. package/dist/src/presentation/web/app/actions/archive-feature.d.ts +6 -0
  37. package/dist/src/presentation/web/app/actions/archive-feature.d.ts.map +1 -0
  38. package/dist/src/presentation/web/app/actions/archive-feature.js +16 -0
  39. package/dist/src/presentation/web/app/actions/unarchive-feature.d.ts +6 -0
  40. package/dist/src/presentation/web/app/actions/unarchive-feature.d.ts.map +1 -0
  41. package/dist/src/presentation/web/app/actions/unarchive-feature.js +16 -0
  42. package/dist/src/presentation/web/app/api/agent-events/route.d.ts.map +1 -1
  43. package/dist/src/presentation/web/app/api/agent-events/route.js +1 -0
  44. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.d.ts.map +1 -1
  45. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.js +6 -0
  46. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +3 -1
  47. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +1 -1
  48. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.js +11 -1
  49. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  50. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +32 -13
  51. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts +7 -0
  52. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts.map +1 -1
  53. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.js +136 -2
  54. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  55. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +13 -4
  56. package/dist/src/presentation/web/components/features/control-center/control-center.stories.d.ts +4 -8
  57. package/dist/src/presentation/web/components/features/control-center/control-center.stories.d.ts.map +1 -1
  58. package/dist/src/presentation/web/components/features/control-center/control-center.stories.js +335 -158
  59. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +6 -0
  60. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  61. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +50 -2
  62. package/dist/src/presentation/web/components/layouts/app-shell/app-shell.d.ts.map +1 -1
  63. package/dist/src/presentation/web/components/layouts/app-shell/app-shell.js +1 -3
  64. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.d.ts.map +1 -1
  65. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.js +45 -5
  66. package/dist/src/presentation/web/hooks/sidebar-features-context.d.ts.map +1 -1
  67. package/dist/src/presentation/web/hooks/sidebar-features-context.js +1 -0
  68. package/dist/src/presentation/web/hooks/use-graph-state.d.ts +1 -1
  69. package/dist/src/presentation/web/hooks/use-graph-state.d.ts.map +1 -1
  70. package/dist/src/presentation/web/hooks/use-graph-state.js +17 -2
  71. package/dist/src/presentation/web/hooks/use-sound-action.d.ts +4 -4
  72. package/dist/src/presentation/web/hooks/use-sound-action.js +2 -2
  73. package/dist/src/presentation/web/lib/derive-graph.d.ts +4 -0
  74. package/dist/src/presentation/web/lib/derive-graph.d.ts.map +1 -1
  75. package/dist/src/presentation/web/lib/derive-graph.js +11 -0
  76. package/dist/tsconfig.build.tsbuildinfo +1 -1
  77. package/package.json +1 -1
  78. package/web/.next/BUILD_ID +1 -1
  79. package/web/.next/build-manifest.json +2 -2
  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 +3 -3
  83. package/web/.next/required-server-files.json +3 -3
  84. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +82 -52
  85. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +1 -1
  86. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  87. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  88. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +82 -52
  89. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
  90. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  91. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  92. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +98 -68
  93. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +1 -1
  94. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  95. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  96. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +98 -68
  97. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
  98. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  99. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  100. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +78 -48
  101. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
  102. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  103. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  104. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +82 -52
  105. package/web/.next/server/app/(dashboard)/create/page.js +1 -1
  106. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  107. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  108. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +98 -68
  109. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +1 -1
  110. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  111. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  112. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +98 -68
  113. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
  114. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  115. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  116. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +78 -48
  117. package/web/.next/server/app/(dashboard)/page.js +1 -1
  118. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  119. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  120. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +78 -48
  121. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
  122. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  123. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  124. package/web/.next/server/app/_global-error.html +2 -2
  125. package/web/.next/server/app/_global-error.rsc +1 -1
  126. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  127. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  128. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  129. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  130. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  131. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +3 -3
  132. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  133. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  134. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  135. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  136. package/web/.next/server/app/settings/page/server-reference-manifest.json +8 -8
  137. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  138. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  139. package/web/.next/server/app/skills/page/server-reference-manifest.json +8 -8
  140. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  141. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  142. package/web/.next/server/app/tools/page/server-reference-manifest.json +8 -8
  143. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  144. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  145. package/web/.next/server/app/version/page/server-reference-manifest.json +3 -3
  146. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  147. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +1 -1
  148. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +1 -1
  149. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js +2 -2
  150. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js.map +1 -1
  151. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  152. package/web/.next/server/chunks/[root-of-the-server]__c6e32a23._.js +1 -1
  153. package/web/.next/server/chunks/[root-of-the-server]__c6e32a23._.js.map +1 -1
  154. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js +1 -1
  155. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js.map +1 -1
  156. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  157. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  158. package/web/.next/server/chunks/ssr/{[root-of-the-server]__90fdc0ee._.js → [root-of-the-server]__2c703b78._.js} +2 -2
  159. package/web/.next/server/chunks/ssr/{[root-of-the-server]__90fdc0ee._.js.map → [root-of-the-server]__2c703b78._.js.map} +1 -1
  160. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  161. package/web/.next/server/chunks/ssr/[root-of-the-server]__3ef34e4c._.js +1 -1
  162. package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js +1 -1
  163. package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js.map +1 -1
  164. package/web/.next/server/chunks/ssr/{[root-of-the-server]__1626f5d7._.js → [root-of-the-server]__59a3897b._.js} +2 -2
  165. package/web/.next/server/chunks/ssr/{[root-of-the-server]__1626f5d7._.js.map → [root-of-the-server]__59a3897b._.js.map} +1 -1
  166. package/web/.next/server/chunks/ssr/[root-of-the-server]__6ec59045._.js +1 -1
  167. package/web/.next/server/chunks/ssr/[root-of-the-server]__6ec59045._.js.map +1 -1
  168. package/web/.next/server/chunks/ssr/{[root-of-the-server]__49557873._.js → [root-of-the-server]__78aecdd5._.js} +2 -2
  169. package/web/.next/server/chunks/ssr/{[root-of-the-server]__a7259d16._.js.map → [root-of-the-server]__78aecdd5._.js.map} +1 -1
  170. package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js +1 -1
  171. package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js.map +1 -1
  172. package/web/.next/server/chunks/ssr/[root-of-the-server]__a5f9c6e5._.js +2 -2
  173. package/web/.next/server/chunks/ssr/[root-of-the-server]__a5f9c6e5._.js.map +1 -1
  174. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +2 -2
  175. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
  176. package/web/.next/server/chunks/ssr/[root-of-the-server]__d48c5b11._.js +1 -1
  177. package/web/.next/server/chunks/ssr/[root-of-the-server]__d48c5b11._.js.map +1 -1
  178. package/web/.next/server/chunks/ssr/{[root-of-the-server]__a7259d16._.js → [root-of-the-server]__f222995d._.js} +2 -2
  179. package/web/.next/server/chunks/ssr/{[root-of-the-server]__49557873._.js.map → [root-of-the-server]__f222995d._.js.map} +1 -1
  180. package/web/.next/server/chunks/ssr/_0020fddd._.js +1 -1
  181. package/web/.next/server/chunks/ssr/_0020fddd._.js.map +1 -1
  182. package/web/.next/server/chunks/ssr/_02ec1aea._.js +1 -1
  183. package/web/.next/server/chunks/ssr/_02ec1aea._.js.map +1 -1
  184. package/web/.next/server/chunks/ssr/{_48a8ee28._.js → _0c5f56e3._.js} +3 -3
  185. package/web/.next/server/chunks/ssr/{_6e8c85b1._.js.map → _0c5f56e3._.js.map} +1 -1
  186. package/web/.next/server/chunks/ssr/{_1a09002f._.js → _1b719e7f._.js} +2 -2
  187. package/web/.next/server/chunks/ssr/{_939287c5._.js.map → _1b719e7f._.js.map} +1 -1
  188. package/web/.next/server/chunks/ssr/{_939287c5._.js → _37e8548b._.js} +2 -2
  189. package/web/.next/server/chunks/ssr/{_149f6559._.js.map → _37e8548b._.js.map} +1 -1
  190. package/web/.next/server/chunks/ssr/{_149f6559._.js → _55d763e2._.js} +2 -2
  191. package/web/.next/server/chunks/ssr/{_1a09002f._.js.map → _55d763e2._.js.map} +1 -1
  192. package/web/.next/server/chunks/ssr/{_6e8c85b1._.js → _64bdfc6f._.js} +3 -3
  193. package/web/.next/server/chunks/ssr/{_48a8ee28._.js.map → _64bdfc6f._.js.map} +1 -1
  194. package/web/.next/server/chunks/ssr/_74c3ee79._.js +4 -0
  195. package/web/.next/server/chunks/ssr/_74c3ee79._.js.map +1 -0
  196. package/web/.next/server/chunks/ssr/_7dca1882._.js +1 -1
  197. package/web/.next/server/chunks/ssr/_7dca1882._.js.map +1 -1
  198. package/web/.next/server/chunks/ssr/{_037421b9._.js → _817e2ffb._.js} +2 -2
  199. package/web/.next/server/chunks/ssr/{_037421b9._.js.map → _817e2ffb._.js.map} +1 -1
  200. package/web/.next/server/chunks/ssr/_a9f57758._.js +1 -1
  201. package/web/.next/server/chunks/ssr/_a9f57758._.js.map +1 -1
  202. package/web/.next/server/chunks/ssr/{_83220ba0._.js → _b71645b4._.js} +2 -2
  203. package/web/.next/server/chunks/ssr/{_83220ba0._.js.map → _b71645b4._.js.map} +1 -1
  204. package/web/.next/server/chunks/ssr/_d4b20e29._.js.map +1 -1
  205. package/web/.next/server/chunks/ssr/_d8575088._.js +1 -1
  206. package/web/.next/server/chunks/ssr/_d8575088._.js.map +1 -1
  207. package/web/.next/server/chunks/ssr/_f39a1adb._.js +1 -1
  208. package/web/.next/server/chunks/ssr/_f39a1adb._.js.map +1 -1
  209. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  210. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  211. package/web/.next/server/chunks/ssr/src_presentation_web_7512ae5c._.js +3 -0
  212. package/web/.next/server/chunks/ssr/{src_presentation_web_951640a3._.js.map → src_presentation_web_7512ae5c._.js.map} +1 -1
  213. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js +1 -1
  214. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js.map +1 -1
  215. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js +1 -1
  216. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js.map +1 -1
  217. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
  218. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js.map +1 -1
  219. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
  220. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +1 -1
  221. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  222. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  223. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  224. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  225. package/web/.next/server/pages/500.html +2 -2
  226. package/web/.next/server/server-reference-manifest.js +1 -1
  227. package/web/.next/server/server-reference-manifest.json +484 -328
  228. package/web/.next/static/chunks/{92d66288f6e5f235.js → 00e7cffbd2b4d181.js} +1 -1
  229. package/web/.next/static/chunks/1787aa31bde0a9b5.js +1 -0
  230. package/web/.next/static/chunks/{d73ad54d54cd7e1d.js → 294cf0803b1e5b91.js} +1 -1
  231. package/web/.next/static/chunks/37f736bbf17e91e7.js +1 -0
  232. package/web/.next/static/chunks/{0bd451437bb30264.js → 4a889c493442a597.js} +1 -1
  233. package/web/.next/static/chunks/{29fe67f664ff2dc6.js → 50e8000dd2361904.js} +1 -1
  234. package/web/.next/static/chunks/{5aa808c7bec008f3.js → 69be489ef69b0a66.js} +1 -1
  235. package/web/.next/static/chunks/6dfdade9e67387b4.js +2 -0
  236. package/web/.next/static/chunks/{5fe8c723c668f1ef.js → 7b0a014d05edbd4b.js} +2 -2
  237. package/web/.next/static/chunks/{f070c67389a686ff.js → 7e7537ab107a5ed5.js} +1 -1
  238. package/web/.next/static/chunks/{f3e37f559952d6a1.js → 970496436becf660.js} +1 -1
  239. package/web/.next/static/chunks/ba967f7de77cd5ee.css +1 -0
  240. package/web/.next/static/chunks/{e4024647334fa56f.js → ccb0bfb16178e592.js} +1 -1
  241. package/web/.next/static/chunks/{c17f8118fc760923.js → f627005f412cf658.js} +1 -1
  242. package/web/.next/server/chunks/ssr/_9cb5f6e3._.js +0 -4
  243. package/web/.next/server/chunks/ssr/_9cb5f6e3._.js.map +0 -1
  244. package/web/.next/server/chunks/ssr/src_presentation_web_951640a3._.js +0 -3
  245. package/web/.next/static/chunks/ab3afb0b942c1eb2.css +0 -1
  246. package/web/.next/static/chunks/c473e2924fbd8fd1.js +0 -1
  247. package/web/.next/static/chunks/db80bb0df7318fac.js +0 -2
  248. package/web/.next/static/chunks/fa89e48e0d67e4dc.js +0 -1
  249. /package/web/.next/static/{i847vZGPwgKFPH7P5kTBl → qsD7mHHMpZAzAyBy-5rSN}/_buildManifest.js +0 -0
  250. /package/web/.next/static/{i847vZGPwgKFPH7P5kTBl → qsD7mHHMpZAzAyBy-5rSN}/_clientMiddlewareManifest.json +0 -0
  251. /package/web/.next/static/{i847vZGPwgKFPH7P5kTBl → qsD7mHHMpZAzAyBy-5rSN}/_ssgManifest.js +0 -0
@@ -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,EAAY,MAAM,eAAe,CAAC;AAGpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAuB5E,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,2CAuWzF"}
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,EAAY,MAAM,eAAe,CAAC;AAKpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAuB5E,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,2CAoYzF"}
@@ -1,8 +1,10 @@
1
1
  'use client';
2
- import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
  import { useRouter, usePathname } from 'next/navigation';
5
- import { useReactFlow } from '@xyflow/react';
5
+ import { Panel, useReactFlow } from '@xyflow/react';
6
+ import { Eye, EyeOff } from 'lucide-react';
7
+ import { cn } from '../../../lib/utils.js';
6
8
  import { FeaturesCanvas } from '../../features/features-canvas/index.js';
7
9
  import { useSidebarFeaturesContext, mapNodeStateToSidebarStatus, } from '../../../hooks/sidebar-features-context.js';
8
10
  import { useSelectedFeatureId } from '../../../hooks/use-selected-feature-id.js';
@@ -26,7 +28,7 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
26
28
  const { fitView } = useReactFlow();
27
29
  const drawerTimerRef = useRef(null);
28
30
  const { defaultViewport, onMoveEnd: handleViewportChange, resetViewport, } = useViewportPersistence();
29
- const { nodes, edges, onNodesChange, handleConnect, handleAddRepository, handleDeleteFeature, handleRetryFeature, handleStartFeature, handleStopFeature, handleDeleteRepository, createFeatureNode, setCallbacks, } = useControlCenterState(initialNodes, initialEdges);
31
+ const { nodes, edges, onNodesChange, handleConnect, handleAddRepository, handleArchiveFeature, handleDeleteFeature, handleRetryFeature, handleStartFeature, handleStopFeature, handleUnarchiveFeature, handleDeleteRepository, createFeatureNode, showArchived, setShowArchived, setCallbacks, } = useControlCenterState(initialNodes, initialEdges);
30
32
  // Publish sidebar features + repo state to context
31
33
  const { setFeatures: setSidebarFeatures, setHasRepositories: setSidebarHasRepos } = useSidebarFeaturesContext();
32
34
  const featureNodes = useMemo(() => nodes.filter((n) => n.type === 'featureNode'), [nodes]);
@@ -201,6 +203,8 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
201
203
  onRetryFeature: handleRetryFeature,
202
204
  onStartFeature: handleStartFeature,
203
205
  onStopFeature: handleStopFeature,
206
+ onArchiveFeature: handleArchiveFeature,
207
+ onUnarchiveFeature: handleUnarchiveFeature,
204
208
  onRepositoryAdd: handleAddFeatureToRepo,
205
209
  onRepositoryClick: handleRepositoryClick,
206
210
  onRepositoryDelete: handleDeleteRepository,
@@ -208,10 +212,12 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
208
212
  }, [
209
213
  setCallbacks,
210
214
  handleAddFeatureToFeature,
215
+ handleArchiveFeature,
211
216
  handleDeleteFeature,
212
217
  handleRetryFeature,
213
218
  handleStartFeature,
214
219
  handleStopFeature,
220
+ handleUnarchiveFeature,
215
221
  handleAddFeatureToRepo,
216
222
  handleRepositoryClick,
217
223
  handleDeleteRepository,
@@ -263,5 +269,8 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
263
269
  return nodes;
264
270
  return nodes.map((n) => n.type === 'repositoryNode' ? { ...n, data: { ...n.data, pulseAdd: true } } : n);
265
271
  }, [nodes, isCreateDrawerOpen]);
266
- return (_jsx(FeaturesCanvas, { nodes: showCanvas ? displayNodes : [], edges: showCanvas ? edges : [], selectedFeatureId: selectedFeatureId, defaultViewport: defaultViewport, onNodesChange: onNodesChange, onConnect: handleConnect, onAddFeature: handleAddFeature, onNodeClick: handleNodeClick, onPaneClick: handleClearDrawers, onMoveEnd: handleMoveEnd, onResetViewport: resetViewport, emptyState: _jsx(ControlCenterEmptyState, { onRepositorySelect: addRepoAndFocus }) }));
272
+ const archiveToggle = (_jsx(Panel, { position: "top-right", children: _jsxs("button", { type: "button", "aria-label": showArchived ? 'Hide archived features' : 'Show archived features', "data-testid": "archive-toggle-button", onClick: () => setShowArchived(!showArchived), className: cn('bg-card flex items-center gap-1.5 rounded-md border px-2.5 py-1.5 text-xs font-medium shadow-sm transition-colors', showArchived
273
+ ? 'border-primary/30 text-primary'
274
+ : 'text-muted-foreground hover:text-foreground'), children: [showArchived ? _jsx(Eye, { className: "h-3.5 w-3.5" }) : _jsx(EyeOff, { className: "h-3.5 w-3.5" }), showArchived ? 'Archived visible' : 'Show archived'] }) }));
275
+ return (_jsx(FeaturesCanvas, { nodes: showCanvas ? displayNodes : [], edges: showCanvas ? edges : [], selectedFeatureId: selectedFeatureId, defaultViewport: defaultViewport, onNodesChange: onNodesChange, onConnect: handleConnect, onAddFeature: handleAddFeature, onNodeClick: handleNodeClick, onPaneClick: handleClearDrawers, onMoveEnd: handleMoveEnd, onResetViewport: resetViewport, toolbar: archiveToggle, emptyState: _jsx(ControlCenterEmptyState, { onRepositorySelect: addRepoAndFocus }) }));
267
276
  }
@@ -5,14 +5,10 @@ export default meta;
5
5
  type Story = StoryObj<typeof meta>;
6
6
  export declare const Empty: Story;
7
7
  export declare const WithFeatures: Story;
8
- export declare const WithToolbar: Story;
9
- export declare const WithNodeActions: Story;
10
8
  /**
11
- * Dagre auto-layout story two repositories with interconnected feature trees.
12
- *
13
- * Demonstrates the Vertical / Horizontal toolbar buttons that re-layout the graph.
14
- * Initial layout is LR (horizontal). Click "Vertical" to switch to TB, or
15
- * "Horizontal" to switch back.
9
+ * Canvas with active and archived features.
10
+ * The archive toggle button appears in the top-right corner ("Show archived").
11
+ * Click the toggle to reveal the dimmed archived feature node.
16
12
  */
17
- export declare const DagreLayout: Story;
13
+ export declare const WithArchivedFeatures: Story;
18
14
  //# sourceMappingURL=control-center.stories.d.ts.map
@@ -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;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"}
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;AAejD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,aAAa,CAoBpC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAyVnC,eAAO,MAAM,KAAK,EAAE,KAKnB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAK1B,CAAC;AA4DF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,KASlC,CAAC"}
@@ -3,6 +3,12 @@ import { ControlCenter } from './control-center.js';
3
3
  import { layoutWithDagre } from '../../../lib/layout-with-dagre.js';
4
4
  import { AgentEventsProvider } from '../../../hooks/agent-events-provider.js';
5
5
  import { DrawerCloseGuardProvider } from '../../../hooks/drawer-close-guard.js';
6
+ import { SidebarFeaturesProvider } from '../../../hooks/sidebar-features-context.js';
7
+ import { DeploymentState, PrStatus, CiStatus } from '../../../../../../packages/core/src/domain/generated/output.js';
8
+ // eslint-disable-next-line @typescript-eslint/no-empty-function -- storybook noop callbacks
9
+ const noop = () => { };
10
+ // eslint-disable-next-line @typescript-eslint/no-empty-function -- storybook noop callbacks
11
+ const noopId = (_id) => { };
6
12
  const meta = {
7
13
  title: 'Features/ControlCenter',
8
14
  component: ControlCenter,
@@ -11,79 +17,329 @@ const meta = {
11
17
  layout: 'fullscreen',
12
18
  },
13
19
  decorators: [
14
- (Story) => (_jsx(AgentEventsProvider, { children: _jsx(DrawerCloseGuardProvider, { children: _jsx("div", { style: { height: '100vh' }, children: _jsx(Story, {}) }) }) })),
20
+ (Story) => (_jsx(AgentEventsProvider, { children: _jsx(SidebarFeaturesProvider, { children: _jsx(DrawerCloseGuardProvider, { children: _jsx("div", { style: { height: '100vh' }, children: _jsx(Story, {}) }) }) }) })),
15
21
  ],
16
22
  };
17
23
  export default meta;
18
- const featureNodes = [
24
+ // ---------------------------------------------------------------------------
25
+ // Shared helpers
26
+ // ---------------------------------------------------------------------------
27
+ const dashedEdge = { style: { strokeDasharray: '5 5' } };
28
+ // ---------------------------------------------------------------------------
29
+ // FullSpectrum — realistic multi-repo workspace with every state represented
30
+ // ---------------------------------------------------------------------------
31
+ const fullSpectrumRepos = [
32
+ {
33
+ id: 'repo-backend',
34
+ type: 'repositoryNode',
35
+ position: { x: 0, y: 0 },
36
+ data: { name: 'acme/backend' },
37
+ },
38
+ {
39
+ id: 'repo-frontend',
40
+ type: 'repositoryNode',
41
+ position: { x: 0, y: 0 },
42
+ data: { name: 'acme/frontend' },
43
+ },
44
+ {
45
+ id: 'repo-infra',
46
+ type: 'repositoryNode',
47
+ position: { x: 0, y: 0 },
48
+ data: { name: 'acme/infra' },
49
+ },
50
+ ];
51
+ const fullSpectrumFeatures = [
52
+ // --- backend features ---
19
53
  {
20
- id: 'feat-1',
54
+ id: 'feat-payment',
21
55
  type: 'featureNode',
22
- position: { x: 400, y: 0 },
56
+ position: { x: 0, y: 0 },
23
57
  data: {
24
- name: 'Auth Module',
25
- description: 'OAuth2 authentication flow',
26
- featureId: '#f1',
58
+ name: 'Payment Processing',
59
+ description: 'Stripe integration with webhook handling, idempotency keys, and retry logic for failed charges',
60
+ featureId: 'e2c8d4',
61
+ lifecycle: 'requirements',
62
+ state: 'action-required',
63
+ progress: 15,
64
+ repositoryPath: '/home/user/acme/backend',
65
+ branch: 'feat/payment-processing',
66
+ agentType: 'claude-code',
67
+ startedAt: Date.now() - 12 * 60_000,
68
+ showHandles: true,
69
+ onDelete: noop,
70
+ onAction: noop,
71
+ hasAgentRun: true,
72
+ pr: undefined,
73
+ },
74
+ },
75
+ {
76
+ id: 'feat-graphql',
77
+ type: 'featureNode',
78
+ position: { x: 0, y: 0 },
79
+ data: {
80
+ name: 'GraphQL API Layer',
81
+ description: 'Replace REST endpoints with GraphQL schema, resolvers, and client-side codegen for type-safe queries',
82
+ featureId: 'c4a6b8',
27
83
  lifecycle: 'implementation',
28
84
  state: 'running',
29
- progress: 65,
30
- repositoryPath: '/home/user/my-repo',
31
- branch: 'feat/auth-module',
85
+ progress: 47,
86
+ repositoryPath: '/home/user/acme/backend',
87
+ branch: 'feat/graphql-api',
88
+ agentType: 'claude-code',
89
+ startedAt: Date.now() - 38 * 60_000,
90
+ showHandles: true,
91
+ onDelete: noop,
92
+ onAction: noop,
93
+ hasAgentRun: true,
94
+ hasPlan: true,
32
95
  },
33
96
  },
34
97
  {
35
- id: 'feat-2',
98
+ id: 'feat-rate-limiter',
36
99
  type: 'featureNode',
37
- position: { x: 400, y: 230 },
100
+ position: { x: 0, y: 0 },
38
101
  data: {
39
- name: 'User Dashboard',
40
- description: 'Main dashboard layout and widgets',
41
- featureId: '#f2',
42
- lifecycle: 'research',
102
+ name: 'Rate Limiter',
103
+ description: 'Sliding window rate limiting with Redis backing store and per-tenant quotas',
104
+ featureId: '3b5d7f',
105
+ lifecycle: 'review',
43
106
  state: 'action-required',
44
- progress: 20,
45
- repositoryPath: '/home/user/my-repo',
107
+ progress: 92,
108
+ repositoryPath: '/home/user/acme/backend',
109
+ branch: 'feat/rate-limiter',
110
+ agentType: 'claude-code',
111
+ showHandles: true,
112
+ onDelete: noop,
113
+ onAction: noop,
114
+ hasAgentRun: true,
115
+ hasPlan: true,
116
+ deployment: {
117
+ status: DeploymentState.Ready,
118
+ url: 'https://feat-rate-limiter.preview.acme.dev',
119
+ },
120
+ pr: {
121
+ url: 'https://github.com/acme/backend/pull/142',
122
+ number: 142,
123
+ status: PrStatus.Open,
124
+ ciStatus: CiStatus.Success,
125
+ mergeable: true,
126
+ },
127
+ },
128
+ },
129
+ {
130
+ id: 'feat-webhooks',
131
+ type: 'featureNode',
132
+ position: { x: 0, y: 0 },
133
+ data: {
134
+ name: 'Webhook Delivery System',
135
+ description: 'Reliable webhook delivery with exponential backoff, dead letter queue, and delivery dashboard',
136
+ featureId: 'a1f3c9',
137
+ lifecycle: 'implementation',
138
+ state: 'blocked',
139
+ progress: 30,
140
+ blockedBy: 'GraphQL API Layer',
141
+ repositoryPath: '/home/user/acme/backend',
142
+ branch: 'feat/webhooks',
143
+ agentType: 'cursor',
144
+ showHandles: true,
145
+ onDelete: noop,
146
+ hasAgentRun: true,
147
+ hasPlan: true,
148
+ },
149
+ },
150
+ {
151
+ id: 'feat-audit-log',
152
+ type: 'featureNode',
153
+ position: { x: 0, y: 0 },
154
+ data: {
155
+ name: 'Audit Log',
156
+ description: 'Immutable audit trail for all mutations with structured event schema and compliance export',
157
+ featureId: 'd8e2a1',
158
+ lifecycle: 'research',
159
+ state: 'running',
160
+ progress: 22,
161
+ repositoryPath: '/home/user/acme/backend',
162
+ branch: 'feat/audit-log',
163
+ agentType: 'gemini-cli',
164
+ startedAt: Date.now() - 5 * 60_000,
165
+ showHandles: true,
166
+ onDelete: noop,
167
+ onAction: noop,
168
+ hasAgentRun: true,
169
+ },
170
+ },
171
+ // --- frontend features ---
172
+ {
173
+ id: 'feat-dashboard',
174
+ type: 'featureNode',
175
+ position: { x: 0, y: 0 },
176
+ data: {
177
+ name: 'User Dashboard',
178
+ description: 'Analytics dashboard with real-time charts, filterable data tables, and CSV export',
179
+ featureId: '5e7a9c',
180
+ lifecycle: 'maintain',
181
+ state: 'done',
182
+ progress: 100,
183
+ runtime: '2h 15m',
184
+ repositoryPath: '/home/user/acme/frontend',
46
185
  branch: 'feat/user-dashboard',
186
+ agentType: 'claude-code',
187
+ showHandles: true,
188
+ onDelete: noop,
189
+ hasAgentRun: true,
190
+ hasPlan: true,
191
+ deployment: { status: DeploymentState.Ready, url: 'https://feat-dashboard.preview.acme.dev' },
192
+ pr: {
193
+ url: 'https://github.com/acme/frontend/pull/87',
194
+ number: 87,
195
+ status: PrStatus.Merged,
196
+ ciStatus: CiStatus.Success,
197
+ },
47
198
  },
48
199
  },
49
200
  {
50
- id: 'feat-3',
201
+ id: 'feat-onboarding',
51
202
  type: 'featureNode',
52
- position: { x: 800, y: 115 },
203
+ position: { x: 0, y: 0 },
53
204
  data: {
54
- name: 'API Gateway',
55
- description: 'Rate limiting and routing',
56
- featureId: '#f3',
57
- lifecycle: 'deploy',
205
+ name: 'Onboarding Flow',
206
+ description: 'Multi-step wizard with progress tracking, field validation, and email verification',
207
+ featureId: 'b4c6d2',
208
+ lifecycle: 'implementation',
209
+ state: 'error',
210
+ progress: 55,
211
+ errorMessage: 'Build failed: Cannot find module @acme/shared-ui',
212
+ repositoryPath: '/home/user/acme/frontend',
213
+ branch: 'feat/onboarding',
214
+ agentType: 'claude-code',
215
+ showHandles: true,
216
+ onDelete: noop,
217
+ onRetry: noopId,
218
+ hasAgentRun: true,
219
+ hasPlan: true,
220
+ },
221
+ },
222
+ {
223
+ id: 'feat-notifications',
224
+ type: 'featureNode',
225
+ position: { x: 0, y: 0 },
226
+ data: {
227
+ name: 'Push Notifications',
228
+ description: 'Browser push notifications with service worker, permission prompts, and preference center',
229
+ featureId: 'f2a8e5',
230
+ lifecycle: 'pending',
231
+ state: 'pending',
232
+ progress: 0,
233
+ repositoryPath: '/home/user/acme/frontend',
234
+ branch: 'feat/push-notifications',
235
+ showHandles: true,
236
+ onDelete: noop,
237
+ onStart: noopId,
238
+ },
239
+ },
240
+ {
241
+ id: 'feat-readme',
242
+ type: 'featureNode',
243
+ position: { x: 0, y: 0 },
244
+ data: {
245
+ name: 'Update README',
246
+ description: 'Rewrite developer docs with setup guide, API reference, and architecture diagrams',
247
+ featureId: '1a3b5c',
248
+ lifecycle: 'maintain',
58
249
  state: 'done',
59
250
  progress: 100,
60
- repositoryPath: '/home/user/my-repo',
61
- branch: 'feat/api-gateway',
251
+ runtime: '8m',
252
+ repositoryPath: '/home/user/acme/frontend',
253
+ branch: 'feat/update-readme',
254
+ agentType: 'claude-code',
255
+ fastMode: true,
256
+ showHandles: true,
257
+ onDelete: noop,
258
+ hasAgentRun: true,
259
+ deployment: { status: DeploymentState.Ready, url: 'https://feat-readme.preview.acme.dev' },
260
+ pr: {
261
+ url: 'https://github.com/acme/frontend/pull/91',
262
+ number: 91,
263
+ status: PrStatus.Merged,
264
+ ciStatus: CiStatus.Success,
265
+ },
62
266
  },
63
267
  },
268
+ // --- infra features ---
64
269
  {
65
- id: 'feat-4',
270
+ id: 'feat-ci',
66
271
  type: 'featureNode',
67
- position: { x: 800, y: 345 },
272
+ position: { x: 0, y: 0 },
68
273
  data: {
69
- name: 'Merge Review',
70
- description: 'PR ready for merge approval',
71
- featureId: '#f4',
72
- lifecycle: 'review',
73
- state: 'action-required',
74
- progress: 90,
75
- repositoryPath: '/home/user/my-repo',
76
- branch: 'feat/merge-review',
274
+ name: 'CI Pipeline Setup',
275
+ description: 'GitHub Actions CI/CD with matrix builds, caching, and automatic preview deployments',
276
+ featureId: '7c9e1a',
277
+ lifecycle: 'maintain',
278
+ state: 'done',
279
+ progress: 100,
280
+ runtime: '45m',
281
+ repositoryPath: '/home/user/acme/infra',
282
+ branch: 'feat/ci-pipeline',
283
+ agentType: 'claude-code',
284
+ showHandles: true,
285
+ onDelete: noop,
286
+ hasAgentRun: true,
287
+ hasPlan: true,
288
+ pr: {
289
+ url: 'https://github.com/acme/infra/pull/34',
290
+ number: 34,
291
+ status: PrStatus.Merged,
292
+ ciStatus: CiStatus.Success,
293
+ },
294
+ },
295
+ },
296
+ {
297
+ id: 'feat-terraform',
298
+ type: 'featureNode',
299
+ position: { x: 0, y: 0 },
300
+ data: {
301
+ name: 'Terraform Modules',
302
+ description: 'Reusable Terraform modules for VPC, ECS, RDS, and ElastiCache with multi-region support',
303
+ featureId: '9d1f3b',
304
+ lifecycle: 'implementation',
305
+ state: 'running',
306
+ progress: 71,
307
+ repositoryPath: '/home/user/acme/infra',
308
+ branch: 'feat/terraform-modules',
309
+ agentType: 'aider',
310
+ startedAt: Date.now() - 22 * 60_000,
311
+ showHandles: true,
312
+ onDelete: noop,
313
+ onAction: noop,
314
+ hasAgentRun: true,
315
+ hasPlan: true,
316
+ deployment: { status: DeploymentState.Booting },
77
317
  },
78
318
  },
79
319
  ];
80
- const repoNode = {
81
- id: 'repo-1',
82
- type: 'repositoryNode',
83
- position: { x: 50, y: 115 },
84
- data: { name: 'shep-ai/cli' },
85
- };
86
- const dashedEdge = { style: { strokeDasharray: '5 5' } };
320
+ const fullSpectrumEdges = [
321
+ // repo → feature edges
322
+ { id: 'e-be-payment', source: 'repo-backend', target: 'feat-payment', ...dashedEdge },
323
+ { id: 'e-be-graphql', source: 'repo-backend', target: 'feat-graphql', ...dashedEdge },
324
+ { id: 'e-be-rate', source: 'repo-backend', target: 'feat-rate-limiter', ...dashedEdge },
325
+ { id: 'e-be-webhooks', source: 'repo-backend', target: 'feat-webhooks', ...dashedEdge },
326
+ { id: 'e-be-audit', source: 'repo-backend', target: 'feat-audit-log', ...dashedEdge },
327
+ { id: 'e-fe-dash', source: 'repo-frontend', target: 'feat-dashboard', ...dashedEdge },
328
+ { id: 'e-fe-onboard', source: 'repo-frontend', target: 'feat-onboarding', ...dashedEdge },
329
+ { id: 'e-fe-notif', source: 'repo-frontend', target: 'feat-notifications', ...dashedEdge },
330
+ { id: 'e-fe-readme', source: 'repo-frontend', target: 'feat-readme', ...dashedEdge },
331
+ { id: 'e-infra-ci', source: 'repo-infra', target: 'feat-ci', ...dashedEdge },
332
+ { id: 'e-infra-tf', source: 'repo-infra', target: 'feat-terraform', ...dashedEdge },
333
+ // dependency edges
334
+ { id: 'e-graphql-webhooks', source: 'feat-graphql', target: 'feat-webhooks' },
335
+ { id: 'e-graphql-rate', source: 'feat-graphql', target: 'feat-rate-limiter' },
336
+ { id: 'e-payment-dashboard', source: 'feat-payment', target: 'feat-dashboard' },
337
+ { id: 'e-ci-terraform', source: 'feat-ci', target: 'feat-terraform' },
338
+ ];
339
+ const { nodes: fullSpectrumNodes, edges: fullSpectrumLayoutedEdges } = layoutWithDagre([...fullSpectrumRepos, ...fullSpectrumFeatures], fullSpectrumEdges, { direction: 'LR' });
340
+ // ---------------------------------------------------------------------------
341
+ // Stories
342
+ // ---------------------------------------------------------------------------
87
343
  export const Empty = {
88
344
  args: {
89
345
  initialNodes: [],
@@ -92,49 +348,22 @@ export const Empty = {
92
348
  };
93
349
  export const WithFeatures = {
94
350
  args: {
95
- initialNodes: featureNodes,
96
- initialEdges: [
97
- { id: 'e1-3', source: 'feat-1', target: 'feat-3' },
98
- { id: 'e2-3', source: 'feat-2', target: 'feat-3' },
99
- ],
100
- },
101
- };
102
- export const WithToolbar = {
103
- args: {
104
- initialNodes: [featureNodes[0], featureNodes[1]],
105
- initialEdges: [],
351
+ initialNodes: fullSpectrumNodes,
352
+ initialEdges: fullSpectrumLayoutedEdges,
106
353
  },
107
354
  };
108
- export const WithNodeActions = {
109
- args: {
110
- initialNodes: [repoNode, ...featureNodes],
111
- initialEdges: [
112
- { id: 'e-repo-f1', source: 'repo-1', target: 'feat-1', ...dashedEdge },
113
- { id: 'e-repo-f2', source: 'repo-1', target: 'feat-2', ...dashedEdge },
114
- { id: 'e1-3', source: 'feat-1', target: 'feat-3' },
115
- ],
116
- },
355
+ // --- Archive toggle stories ---
356
+ const archiveRepoNode = {
357
+ id: 'repo-archive',
358
+ type: 'repositoryNode',
359
+ position: { x: 50, y: 115 },
360
+ data: { name: 'shep-ai/cli' },
117
361
  };
118
- // --- Dagre-layouted story: multiple repos with feature trees ---
119
- const dagreRepoNodes = [
362
+ const archivedFeatureNodes = [
120
363
  {
121
- id: 'repo-cli',
122
- type: 'repositoryNode',
123
- position: { x: 0, y: 0 },
124
- data: { name: 'shep-ai/cli' },
125
- },
126
- {
127
- id: 'repo-web',
128
- type: 'repositoryNode',
129
- position: { x: 0, y: 0 },
130
- data: { name: 'shep-ai/web' },
131
- },
132
- ];
133
- const dagreFeatureNodes = [
134
- {
135
- id: 'feat-auth',
364
+ id: 'feat-active',
136
365
  type: 'featureNode',
137
- position: { x: 0, y: 0 },
366
+ position: { x: 400, y: 0 },
138
367
  data: {
139
368
  name: 'Auth Module',
140
369
  description: 'OAuth2 authentication flow',
@@ -147,101 +376,49 @@ const dagreFeatureNodes = [
147
376
  },
148
377
  },
149
378
  {
150
- id: 'feat-sso',
379
+ id: 'feat-done',
151
380
  type: 'featureNode',
152
- position: { x: 0, y: 0 },
381
+ position: { x: 400, y: 230 },
153
382
  data: {
154
- name: 'SSO Integration',
155
- description: 'Single sign-on across services',
383
+ name: 'Payment Gateway',
384
+ description: 'Stripe integration for subscriptions',
156
385
  featureId: '#f2',
157
- lifecycle: 'research',
158
- state: 'action-required',
159
- progress: 20,
160
- repositoryPath: '/home/user/my-repo',
161
- branch: 'feat/sso-integration',
162
- },
163
- },
164
- {
165
- id: 'feat-dashboard',
166
- type: 'featureNode',
167
- position: { x: 0, y: 0 },
168
- data: {
169
- name: 'User Dashboard',
170
- description: 'Main dashboard layout and widgets',
171
- featureId: '#f3',
172
- lifecycle: 'requirements',
173
- state: 'running',
174
- progress: 10,
175
- repositoryPath: '/home/user/my-repo',
176
- branch: 'feat/user-dashboard',
177
- },
178
- },
179
- {
180
- id: 'feat-gateway',
181
- type: 'featureNode',
182
- position: { x: 0, y: 0 },
183
- data: {
184
- name: 'API Gateway',
185
- description: 'Rate limiting and routing',
186
- featureId: '#f4',
187
386
  lifecycle: 'deploy',
188
387
  state: 'done',
189
388
  progress: 100,
389
+ runtime: '1h 42m',
190
390
  repositoryPath: '/home/user/my-repo',
191
- branch: 'feat/api-gateway',
391
+ branch: 'feat/payment-gateway',
192
392
  },
193
393
  },
194
394
  {
195
- id: 'feat-admin',
395
+ id: 'feat-archived',
196
396
  type: 'featureNode',
197
- position: { x: 0, y: 0 },
397
+ position: { x: 800, y: 115 },
198
398
  data: {
199
- name: 'Admin Panel',
200
- description: 'Internal admin tools',
201
- featureId: '#f5',
202
- lifecycle: 'review',
203
- state: 'blocked',
204
- progress: 40,
205
- blockedBy: 'API Gateway',
399
+ name: 'Old Dashboard',
400
+ description: 'Previous iteration of the admin dashboard',
401
+ featureId: '#f3',
402
+ lifecycle: 'maintain',
403
+ state: 'archived',
404
+ progress: 100,
206
405
  repositoryPath: '/home/user/my-repo',
207
- branch: 'feat/admin-panel',
406
+ branch: 'feat/old-dashboard',
208
407
  },
209
408
  },
210
409
  ];
211
- const dagreNodesRaw = [...dagreRepoNodes, ...dagreFeatureNodes];
212
- const dagreEdges = [
213
- // cli repo → Auth, SSO
214
- { id: 'e-cli-auth', source: 'repo-cli', target: 'feat-auth', style: { strokeDasharray: '5 5' } },
215
- { id: 'e-cli-sso', source: 'repo-cli', target: 'feat-sso', style: { strokeDasharray: '5 5' } },
216
- // web repo → Dashboard, Admin
217
- {
218
- id: 'e-web-dash',
219
- source: 'repo-web',
220
- target: 'feat-dashboard',
221
- style: { strokeDasharray: '5 5' },
222
- },
223
- {
224
- id: 'e-web-admin',
225
- source: 'repo-web',
226
- target: 'feat-admin',
227
- style: { strokeDasharray: '5 5' },
228
- },
229
- // Feature dependencies: Auth → Gateway, SSO → Gateway, Gateway → Admin
230
- { id: 'e-auth-gw', source: 'feat-auth', target: 'feat-gateway' },
231
- { id: 'e-sso-gw', source: 'feat-sso', target: 'feat-gateway' },
232
- { id: 'e-gw-admin', source: 'feat-gateway', target: 'feat-admin' },
233
- ];
234
- const { nodes: dagreLayoutedNodes, edges: dagreLayoutedEdges } = layoutWithDagre(dagreNodesRaw, dagreEdges, { direction: 'LR' });
235
410
  /**
236
- * Dagre auto-layout story two repositories with interconnected feature trees.
237
- *
238
- * Demonstrates the Vertical / Horizontal toolbar buttons that re-layout the graph.
239
- * Initial layout is LR (horizontal). Click "Vertical" to switch to TB, or
240
- * "Horizontal" to switch back.
411
+ * Canvas with active and archived features.
412
+ * The archive toggle button appears in the top-right corner ("Show archived").
413
+ * Click the toggle to reveal the dimmed archived feature node.
241
414
  */
242
- export const DagreLayout = {
415
+ export const WithArchivedFeatures = {
243
416
  args: {
244
- initialNodes: dagreLayoutedNodes,
245
- initialEdges: dagreLayoutedEdges,
417
+ initialNodes: [archiveRepoNode, ...archivedFeatureNodes],
418
+ initialEdges: [
419
+ { id: 'e-repo-active', source: 'repo-archive', target: 'feat-active', ...dashedEdge },
420
+ { id: 'e-repo-done', source: 'repo-archive', target: 'feat-done', ...dashedEdge },
421
+ { id: 'e-repo-archived', source: 'repo-archive', target: 'feat-archived', ...dashedEdge },
422
+ ],
246
423
  },
247
424
  };