@shepai/cli 1.80.0 → 1.82.0-pr253.5f5c655

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 (197) hide show
  1. package/apis/json-schema/Feature.yaml +5 -0
  2. package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts +9 -0
  3. package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts.map +1 -1
  4. package/dist/packages/core/src/application/use-cases/agents/reject-agent-run.use-case.d.ts.map +1 -1
  5. package/dist/packages/core/src/application/use-cases/agents/reject-agent-run.use-case.js +3 -0
  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 +1 -0
  8. package/dist/packages/core/src/domain/generated/output.d.ts +4 -0
  9. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  10. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts +1 -0
  11. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts.map +1 -1
  12. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.js +4 -0
  13. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.d.ts.map +1 -1
  14. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.js +11 -0
  15. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.d.ts.map +1 -1
  16. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.js +3 -0
  17. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts +1 -0
  18. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts.map +1 -1
  19. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +17 -0
  20. package/dist/src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/page.d.ts.map +1 -1
  21. package/dist/src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/page.js +3 -1
  22. package/dist/src/presentation/web/app/actions/get-feature-phase-timings.d.ts +6 -0
  23. package/dist/src/presentation/web/app/actions/get-feature-phase-timings.d.ts.map +1 -1
  24. package/dist/src/presentation/web/app/actions/get-feature-phase-timings.js +26 -1
  25. package/dist/src/presentation/web/app/build-feature-node-data.d.ts +2 -0
  26. package/dist/src/presentation/web/app/build-feature-node-data.d.ts.map +1 -1
  27. package/dist/src/presentation/web/app/build-feature-node-data.js +2 -0
  28. package/dist/src/presentation/web/app/build-graph-nodes.js +1 -0
  29. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
  30. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +5 -2
  31. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  32. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +10 -3
  33. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.d.ts +3 -2
  34. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.d.ts.map +1 -1
  35. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.js +29 -6
  36. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.d.ts +2 -0
  37. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.d.ts.map +1 -1
  38. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.js +72 -0
  39. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.d.ts.map +1 -1
  40. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.js +2 -2
  41. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.stories.d.ts +2 -0
  42. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.stories.d.ts.map +1 -1
  43. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.stories.js +28 -0
  44. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.js +6 -7
  45. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts +2 -0
  46. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts.map +1 -1
  47. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.js +24 -0
  48. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +4 -0
  49. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +1 -1
  50. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  51. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +7 -7
  52. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts +2 -0
  53. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts.map +1 -1
  54. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.js +29 -0
  55. package/dist/tsconfig.build.tsbuildinfo +1 -1
  56. package/package.json +1 -1
  57. package/web/.next/BUILD_ID +1 -1
  58. package/web/.next/build-manifest.json +2 -2
  59. package/web/.next/fallback-build-manifest.json +2 -2
  60. package/web/.next/prerender-manifest.json +3 -3
  61. package/web/.next/required-server-files.js +1 -1
  62. package/web/.next/required-server-files.json +1 -1
  63. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +18 -18
  64. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  65. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  66. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +21 -21
  67. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
  68. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  69. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  70. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +14 -14
  71. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  72. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  73. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +18 -18
  74. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  75. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  76. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +21 -21
  77. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
  78. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  79. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  80. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +14 -14
  81. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  82. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  83. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +14 -14
  84. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  85. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  86. package/web/.next/server/app/_global-error.html +2 -2
  87. package/web/.next/server/app/_global-error.rsc +1 -1
  88. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  89. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  90. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  91. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  92. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  93. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  94. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  95. package/web/.next/server/app/api/dialog/pick-files/route.js +1 -1
  96. package/web/.next/server/app/api/dialog/pick-files/route.js.nft.json +1 -1
  97. package/web/.next/server/app/settings/page/server-reference-manifest.json +5 -5
  98. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  99. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  100. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  101. package/web/.next/server/app/skills/page.js +3 -2
  102. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  103. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  104. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  105. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  106. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  107. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  108. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js.map +1 -1
  109. package/web/.next/server/chunks/{[root-of-the-server]__a6bf88cc._.js → [root-of-the-server]__332c8d91._.js} +2 -2
  110. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  111. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  112. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js +1 -1
  113. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js.map +1 -1
  114. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js +1 -1
  115. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js.map +1 -1
  116. package/web/.next/server/chunks/ssr/90b01_js-yaml_dist_js-yaml_mjs_c897fb57._.js +3 -0
  117. package/web/.next/server/chunks/ssr/90b01_js-yaml_dist_js-yaml_mjs_c897fb57._.js.map +1 -0
  118. package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js +1 -1
  119. package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js.map +1 -1
  120. package/web/.next/server/chunks/ssr/[root-of-the-server]__17143953._.js +3 -0
  121. package/web/.next/server/chunks/ssr/[root-of-the-server]__17143953._.js.map +1 -0
  122. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  123. package/web/.next/server/chunks/ssr/[root-of-the-server]__4be9a9bb._.js +1 -1
  124. package/web/.next/server/chunks/ssr/[root-of-the-server]__5d87af2e._.js +1 -1
  125. package/web/.next/server/chunks/ssr/[root-of-the-server]__9de266fa._.js +3 -0
  126. package/web/.next/server/chunks/ssr/[root-of-the-server]__9de266fa._.js.map +1 -0
  127. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
  128. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
  129. package/web/.next/server/chunks/ssr/[root-of-the-server]__b3a4cef4._.js +1 -1
  130. package/web/.next/server/chunks/ssr/[root-of-the-server]__b3a4cef4._.js.map +1 -1
  131. package/web/.next/server/chunks/ssr/[root-of-the-server]__c3c963c6._.js +1 -1
  132. package/web/.next/server/chunks/ssr/[root-of-the-server]__c3c963c6._.js.map +1 -1
  133. package/web/.next/server/chunks/ssr/[root-of-the-server]__f0d8d054._.js +2 -2
  134. package/web/.next/server/chunks/ssr/[root-of-the-server]__f0d8d054._.js.map +1 -1
  135. package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js +1 -1
  136. package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js.map +1 -1
  137. package/web/.next/server/chunks/ssr/_1bb131c4._.js.map +1 -1
  138. package/web/.next/server/chunks/ssr/_1e3cf73b._.js +1 -1
  139. package/web/.next/server/chunks/ssr/_1e3cf73b._.js.map +1 -1
  140. package/web/.next/server/chunks/ssr/_3a4c94e3._.js +1 -1
  141. package/web/.next/server/chunks/ssr/_3a4c94e3._.js.map +1 -1
  142. package/web/.next/server/chunks/ssr/_63868199._.js +1 -1
  143. package/web/.next/server/chunks/ssr/_63868199._.js.map +1 -1
  144. package/web/.next/server/chunks/ssr/{_50b7100e._.js → _6c20ebb7._.js} +2 -2
  145. package/web/.next/server/chunks/ssr/{_50b7100e._.js.map → _6c20ebb7._.js.map} +1 -1
  146. package/web/.next/server/chunks/ssr/_6e08ce21._.js.map +1 -1
  147. package/web/.next/server/chunks/ssr/_8dacd1e7._.js +1 -1
  148. package/web/.next/server/chunks/ssr/_8dacd1e7._.js.map +1 -1
  149. package/web/.next/server/chunks/ssr/{_c29db9b3._.js → _b50019aa._.js} +2 -2
  150. package/web/.next/server/chunks/ssr/{_c29db9b3._.js.map → _b50019aa._.js.map} +1 -1
  151. package/web/.next/server/chunks/ssr/{_5d4e7151._.js → _c3a8bcb1._.js} +2 -2
  152. package/web/.next/server/chunks/ssr/_c3a8bcb1._.js.map +1 -0
  153. package/web/.next/server/chunks/ssr/{_645e9a63._.js → _f3d4dcc3._.js} +2 -2
  154. package/web/.next/server/chunks/ssr/{_645e9a63._.js.map → _f3d4dcc3._.js.map} +1 -1
  155. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  156. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  157. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js +1 -1
  158. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js.map +1 -1
  159. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
  160. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
  161. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
  162. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
  163. package/web/.next/server/chunks/ssr/src_presentation_web_app_(dashboard)_get-graph-data_ts_b018483e._.js +1 -1
  164. package/web/.next/server/chunks/ssr/src_presentation_web_app_(dashboard)_get-graph-data_ts_b018483e._.js.map +1 -1
  165. package/web/.next/server/chunks/ssr/src_presentation_web_c4348b8a._.js +2 -2
  166. package/web/.next/server/chunks/ssr/src_presentation_web_c4348b8a._.js.map +1 -1
  167. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  168. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  169. package/web/.next/server/chunks/ssr/src_presentation_web_e4510d10._.js +2 -2
  170. package/web/.next/server/chunks/ssr/src_presentation_web_e4510d10._.js.map +1 -1
  171. package/web/.next/server/pages/500.html +2 -2
  172. package/web/.next/server/server-reference-manifest.js +1 -1
  173. package/web/.next/server/server-reference-manifest.json +28 -28
  174. package/web/.next/static/chunks/04d890c40c6d365c.js +1 -0
  175. package/web/.next/static/chunks/{158f8113bf93c2ee.js → 0c4df9f238f7afa1.js} +1 -1
  176. package/web/.next/static/chunks/{5c11c4f4042077dd.js → 20c501ee8f813e39.js} +1 -1
  177. package/web/.next/static/chunks/{1d1da60d2d4f5f64.js → 5d1e9c1a1daf1e43.js} +1 -1
  178. package/web/.next/static/chunks/{a996823ce96362aa.js → 6b3a529caab8872e.js} +1 -1
  179. package/web/.next/static/chunks/82f4e18d6dee040b.js +1 -0
  180. package/web/.next/static/chunks/{fae8e157d874ab74.js → 8ace8cec620ba72d.js} +2 -2
  181. package/web/.next/static/chunks/{594c694d9e749bf6.js → 90b961eeb187c6e6.js} +1 -1
  182. package/web/.next/static/chunks/{4f5b21c7dfd3c5bb.js → 9432256ad209d956.js} +1 -1
  183. package/web/.next/static/chunks/ae01d2be1d0bad47.css +2 -0
  184. package/web/.next/static/chunks/cb9409875cfd35c0.js +1 -0
  185. package/web/.next/server/chunks/ssr/_5d4e7151._.js.map +0 -1
  186. package/web/.next/server/chunks/ssr/src_presentation_web_7efa14ca._.js +0 -3
  187. package/web/.next/server/chunks/ssr/src_presentation_web_7efa14ca._.js.map +0 -1
  188. package/web/.next/server/chunks/ssr/src_presentation_web_b59d79db._.js +0 -3
  189. package/web/.next/server/chunks/ssr/src_presentation_web_b59d79db._.js.map +0 -1
  190. package/web/.next/static/chunks/0263c85901a20cec.js +0 -1
  191. package/web/.next/static/chunks/62b3642ac8337a1d.js +0 -1
  192. package/web/.next/static/chunks/96bab6d3820504f3.css +0 -2
  193. package/web/.next/static/chunks/a23c696600afe26c.js +0 -1
  194. /package/web/.next/server/chunks/{[root-of-the-server]__a6bf88cc._.js.map → [root-of-the-server]__332c8d91._.js.map} +0 -0
  195. /package/web/.next/static/{TpbhEjRZP-asaxlR5yaGh → cYmEMreAMkFtZseuYiImn}/_buildManifest.js +0 -0
  196. /package/web/.next/static/{TpbhEjRZP-asaxlR5yaGh → cYmEMreAMkFtZseuYiImn}/_clientMiddlewareManifest.json +0 -0
  197. /package/web/.next/static/{TpbhEjRZP-asaxlR5yaGh → cYmEMreAMkFtZseuYiImn}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"activity-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/activity-tab.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAE/E,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AA+CD,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,gBAAgB,2CA0DxE"}
1
+ {"version":3,"file":"activity-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/activity-tab.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACtB,MAAM,yCAAyC,CAAC;AAEjD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iBAAiB,CAAC,EAAE,qBAAqB,EAAE,CAAC;CAC7C;AAsED,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,gBAAgB,2CA8D3F"}
@@ -16,6 +16,7 @@ const LIFECYCLE_EVENTS = {
16
16
  'run:failed': { label: 'failed', colorClass: 'text-red-600' },
17
17
  'run:stopped': { label: 'stopped', colorClass: 'text-amber-600' },
18
18
  'run:crashed': { label: 'crashed', colorClass: 'text-red-600' },
19
+ 'run:rejected': { label: 'rejected', colorClass: 'text-orange-600' },
19
20
  };
20
21
  function isLifecycleEvent(phase) {
21
22
  return phase.startsWith('run:');
@@ -36,7 +37,25 @@ function groupTimingsByRun(timings) {
36
37
  }
37
38
  return groups;
38
39
  }
39
- export function ActivityTab({ timings, loading, error }) {
40
+ /**
41
+ * Map each run:rejected timing entry to its rejection feedback message.
42
+ * Matches by sequential order: 1st rejected event → 1st feedback entry, etc.
43
+ */
44
+ function buildRejectionMessageMap(timings, feedback) {
45
+ const map = new Map();
46
+ if (!feedback?.length)
47
+ return map;
48
+ let rejectionIdx = 0;
49
+ for (const t of timings) {
50
+ if (t.phase === 'run:rejected' && rejectionIdx < feedback.length) {
51
+ const key = `${t.agentRunId}-${t.phase}-${t.startedAt}`;
52
+ map.set(key, feedback[rejectionIdx].message);
53
+ rejectionIdx++;
54
+ }
55
+ }
56
+ return map;
57
+ }
58
+ export function ActivityTab({ timings, loading, error, rejectionFeedback }) {
40
59
  if (loading) {
41
60
  return (_jsx("div", { "data-testid": "activity-tab-loading", className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) }));
42
61
  }
@@ -48,25 +67,29 @@ export function ActivityTab({ timings, loading, error }) {
48
67
  }
49
68
  const nodeTimings = timings.filter((t) => !isLifecycleEvent(t.phase));
50
69
  const maxDurationMs = Math.max(...nodeTimings.map((t) => t.durationMs ?? 0), ...nodeTimings.map((t) => t.approvalWaitMs ?? 0), 0);
70
+ // Build a map from rejection index to feedback message
71
+ const rejectionMessages = buildRejectionMessageMap(timings, rejectionFeedback);
51
72
  const groups = groupTimingsByRun(timings);
52
73
  const multiRun = groups.length > 1;
53
74
  const totalExecMs = nodeTimings.reduce((sum, t) => sum + (t.durationMs ?? 0), 0);
54
75
  const totalWaitMs = nodeTimings.reduce((sum, t) => sum + (t.approvalWaitMs ?? 0), 0);
55
- return (_jsxs("div", { className: "flex flex-col gap-4 p-4", children: [_jsx("div", { "data-testid": "activity-timings", className: "flex flex-col gap-3", children: groups.map((group, groupIdx) => (_jsx(RunGroup, { group: group, groupIdx: groupIdx, multiRun: multiRun, maxDurationMs: maxDurationMs }, group.runId))) }), totalExecMs > 0 ? (_jsx(SummaryTotals, { totalExecMs: totalExecMs, totalWaitMs: totalWaitMs })) : null] }));
76
+ return (_jsxs("div", { className: "flex flex-col gap-4 p-4", children: [_jsx("div", { "data-testid": "activity-timings", className: "flex flex-col gap-3", children: groups.map((group, groupIdx) => (_jsx(RunGroup, { group: group, groupIdx: groupIdx, multiRun: multiRun, maxDurationMs: maxDurationMs, rejectionMessages: rejectionMessages }, group.runId))) }), totalExecMs > 0 ? (_jsx(SummaryTotals, { totalExecMs: totalExecMs, totalWaitMs: totalWaitMs })) : null] }));
56
77
  }
57
- function RunGroup({ group, groupIdx, multiRun, maxDurationMs, }) {
78
+ function RunGroup({ group, groupIdx, multiRun, maxDurationMs, rejectionMessages, }) {
58
79
  return (_jsxs("div", { className: "flex flex-col gap-1.5", children: [multiRun ? (_jsxs("div", { className: "text-muted-foreground text-xs font-medium", children: ["Run #", groupIdx + 1] })) : null, group.timings.map((t) => {
59
80
  if (isLifecycleEvent(t.phase)) {
60
- return _jsx(LifecycleEventRow, { timing: t }, `${t.agentRunId}-${t.phase}-${t.startedAt}`);
81
+ const key = `${t.agentRunId}-${t.phase}-${t.startedAt}`;
82
+ const message = t.phase === 'run:rejected' ? rejectionMessages.get(key) : undefined;
83
+ return _jsx(LifecycleEventRow, { timing: t, message: message }, key);
61
84
  }
62
85
  return (_jsx(NodeTimingRow, { timing: t, maxDurationMs: maxDurationMs }, `${t.agentRunId}-${t.phase}-${t.startedAt}`));
63
86
  })] }));
64
87
  }
65
- function LifecycleEventRow({ timing }) {
88
+ function LifecycleEventRow({ timing, message }) {
66
89
  const event = LIFECYCLE_EVENTS[timing.phase];
67
90
  if (!event)
68
91
  return null;
69
- return (_jsx("div", { className: `text-xs ${event.colorClass}`, children: _jsx("span", { children: event.label }) }));
92
+ return (_jsxs("div", { className: `text-xs ${event.colorClass}`, children: [_jsx("span", { children: event.label }), message ? (_jsxs("span", { "data-testid": "rejection-feedback-text", className: "text-muted-foreground ml-2 font-normal italic", children: ["\u2014 ", message] })) : null] }));
70
93
  }
71
94
  function NodeTimingRow({ timing, maxDurationMs, }) {
72
95
  const label = timing.phase.includes(':')
@@ -15,6 +15,8 @@ export declare const Loading: Story;
15
15
  export declare const Empty: Story;
16
16
  /** Error state — inline error message. */
17
17
  export declare const Error: Story;
18
+ /** Rejection — shows rejected lifecycle event with user feedback text. */
19
+ export declare const WithRejection: Story;
18
20
  /** Approval wait indicators — phases with approval wait sub-rows. */
19
21
  export declare const WithApprovalWaits: Story;
20
22
  //# sourceMappingURL=activity-tab.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"activity-tab.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,WAAW,CAclC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,WAAW,CAAC,CAAC;AAmK1C,2EAA2E;AAC3E,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,iBAAiB,EAAE,KAgC/B,CAAC"}
1
+ {"version":3,"file":"activity-tab.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,WAAW,CAclC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,WAAW,CAAC,CAAC;AAmK1C,2EAA2E;AAC3E,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC;AAEF,0EAA0E;AAC1E,eAAO,MAAM,aAAa,EAAE,KAsE3B,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,iBAAiB,EAAE,KAgC/B,CAAC"}
@@ -216,6 +216,78 @@ export const Error = {
216
216
  error: 'Failed to load phase timings. Please try again.',
217
217
  },
218
218
  };
219
+ /** Rejection — shows rejected lifecycle event with user feedback text. */
220
+ export const WithRejection = {
221
+ args: {
222
+ timings: [
223
+ {
224
+ agentRunId: 'run-1',
225
+ phase: 'run:started',
226
+ startedAt: '2025-01-15T10:00:00Z',
227
+ durationMs: 0,
228
+ },
229
+ {
230
+ agentRunId: 'run-1',
231
+ phase: 'analyze',
232
+ startedAt: '2025-01-15T10:00:01Z',
233
+ completedAt: '2025-01-15T10:00:15Z',
234
+ durationMs: 14000,
235
+ },
236
+ {
237
+ agentRunId: 'run-1',
238
+ phase: 'requirements',
239
+ startedAt: '2025-01-15T10:00:15Z',
240
+ completedAt: '2025-01-15T10:01:45Z',
241
+ durationMs: 90000,
242
+ waitingApprovalAt: '2025-01-15T10:01:00Z',
243
+ approvalWaitMs: 30000,
244
+ },
245
+ {
246
+ agentRunId: 'run-1',
247
+ phase: 'run:rejected',
248
+ startedAt: '2025-01-15T10:01:45Z',
249
+ durationMs: 0,
250
+ },
251
+ {
252
+ agentRunId: 'run-1',
253
+ phase: 'run:resumed',
254
+ startedAt: '2025-01-15T10:02:00Z',
255
+ durationMs: 0,
256
+ },
257
+ {
258
+ agentRunId: 'run-1',
259
+ phase: 'requirements:2',
260
+ startedAt: '2025-01-15T10:02:01Z',
261
+ completedAt: '2025-01-15T10:03:30Z',
262
+ durationMs: 89000,
263
+ waitingApprovalAt: '2025-01-15T10:03:00Z',
264
+ approvalWaitMs: 15000,
265
+ },
266
+ {
267
+ agentRunId: 'run-1',
268
+ phase: 'research',
269
+ startedAt: '2025-01-15T10:03:30Z',
270
+ completedAt: '2025-01-15T10:05:00Z',
271
+ durationMs: 90000,
272
+ },
273
+ {
274
+ agentRunId: 'run-1',
275
+ phase: 'run:completed',
276
+ startedAt: '2025-01-15T10:05:00Z',
277
+ durationMs: 0,
278
+ },
279
+ ],
280
+ rejectionFeedback: [
281
+ {
282
+ iteration: 1,
283
+ message: 'The requirements are missing error handling for edge cases',
284
+ phase: 'requirements',
285
+ },
286
+ ],
287
+ loading: false,
288
+ error: null,
289
+ },
290
+ };
219
291
  /** Approval wait indicators — phases with approval wait sub-rows. */
220
292
  export const WithApprovalWaits = {
221
293
  args: {
@@ -1 +1 @@
1
- {"version":3,"file":"feature-drawer-tabs.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACzF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,+CAA+C,CAAC;AACjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAaxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uDAAuD,CAAC;AAiD3F,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,eAAe,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,aAAa,CAAC;IAG3B,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7D,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,YAAY,CAAC,EAAE,OAAO,CAAC;IAGvB,QAAQ,CAAC,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC1C,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,aAAa,CAAC,EAAE,OAAO,CAAC;IAGxB,WAAW,CAAC,EAAE,2BAA2B,GAAG,IAAI,CAAC;IAGjD,SAAS,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,cAAc,CAAC,EAAE,OAAO,CAAC;IAGzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAmBD,wBAAgB,iBAAiB,CAAC,EAChC,WAAW,EACX,SAAS,EACT,UAAU,EACV,OAAO,EACP,aAAa,EACb,WAAW,EACX,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,aAAa,EACb,WAAW,EACX,SAAS,EACT,cAAc,EACd,aAAa,EACb,cAAc,EACd,WAAW,EACX,SAAS,EACT,iBAAiB,GAClB,EAAE,sBAAsB,2CA2MxB"}
1
+ {"version":3,"file":"feature-drawer-tabs.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACzF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,+CAA+C,CAAC;AACjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAaxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uDAAuD,CAAC;AAiD3F,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,eAAe,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,aAAa,CAAC;IAG3B,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7D,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,YAAY,CAAC,EAAE,OAAO,CAAC;IAGvB,QAAQ,CAAC,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC1C,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,aAAa,CAAC,EAAE,OAAO,CAAC;IAGxB,WAAW,CAAC,EAAE,2BAA2B,GAAG,IAAI,CAAC;IAGjD,SAAS,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,cAAc,CAAC,EAAE,OAAO,CAAC;IAGzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAwBD,wBAAgB,iBAAiB,CAAC,EAChC,WAAW,EACX,SAAS,EACT,UAAU,EACV,OAAO,EACP,aAAa,EACb,WAAW,EACX,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,aAAa,EACb,WAAW,EACX,SAAS,EACT,cAAc,EACd,aAAa,EACb,cAAc,EACd,WAAW,EACX,SAAS,EACT,iBAAiB,GAClB,EAAE,sBAAsB,2CA4MxB"}
@@ -51,7 +51,7 @@ async function fetchActivity(featureId) {
51
51
  const result = await getFeaturePhaseTimings(featureId);
52
52
  if ('error' in result)
53
53
  throw new Error(result.error);
54
- return result.timings;
54
+ return { timings: result.timings, rejectionFeedback: result.rejectionFeedback };
55
55
  }
56
56
  async function fetchPlan(featureId) {
57
57
  const result = await getFeaturePlan(featureId);
@@ -115,7 +115,7 @@ export function FeatureDrawerTabs({ featureNode, featureId, initialTab, prdData,
115
115
  fetchTab(tab);
116
116
  }
117
117
  }, [fetchTab]);
118
- return (_jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: _jsxs(Tabs, { value: activeTab, onValueChange: handleTabChange, className: "flex min-h-0 flex-1 flex-col", children: [_jsx("div", { className: "shrink-0 overflow-x-auto px-4 pt-4", children: _jsx(TabsList, { className: "flex w-full", children: visibleTabDefs.map((tab) => (_jsx(TabsTrigger, { value: tab.key, className: "flex-1", children: tab.label }, tab.key))) }) }), _jsx(TabsContent, { value: "overview", className: "mt-0 flex-1 overflow-y-auto", children: _jsx(OverviewTab, { data: featureNode }) }), _jsx(TabsContent, { value: "activity", className: "mt-0 flex-1 overflow-y-auto", children: _jsx(ActivityTab, { timings: tabs.activity.data, loading: tabs.activity.loading, error: tabs.activity.error }) }), _jsx(TabsContent, { value: "log", className: "mt-0 flex-1 overflow-hidden", children: _jsx(LogTab, { content: featureLogs.content, isConnected: featureLogs.isConnected, error: featureLogs.error }) }), _jsx(TabsContent, { value: "plan", className: "mt-0 flex-1 overflow-y-auto", children: _jsx(PlanTab, { plan: tabs.plan.data, loading: tabs.plan.loading, error: tabs.plan.error }) }), visibleTabs.includes('prd-review') ? (_jsx(TabsContent, { value: "prd-review", className: "mt-0 flex min-h-0 flex-1 flex-col", children: prdData ? (_jsx(PrdQuestionnaire, { data: prdData, selections: prdSelections ?? {}, onSelect: onPrdSelect ?? (() => undefined), onApprove: onPrdApprove ?? (() => undefined), onReject: onPrdReject, isProcessing: isPrdLoading, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: onChatInputChange })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) })) : null, visibleTabs.includes('tech-decisions') ? (_jsx(TabsContent, { value: "tech-decisions", className: "mt-0 flex min-h-0 flex-1 flex-col", children: techData ? (_jsxs("div", { className: "flex min-h-0 flex-1 flex-col", children: [_jsx("div", { className: "flex-1 overflow-y-auto", children: _jsx(TechDecisionsContent, { data: techData }) }), _jsx(DrawerActionBarForTech, { onApprove: onTechApprove ?? (() => undefined), onReject: onTechReject, isProcessing: isTechLoading, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: onChatInputChange })] })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) })) : null, visibleTabs.includes('product-decisions') ? (_jsx(TabsContent, { value: "product-decisions", className: "mt-0 flex-1 overflow-y-auto", children: productData === null ? (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) : productData ? (_jsx(ProductDecisionsSummary, { data: productData })) : (_jsx("p", { className: "text-muted-foreground p-4 text-center text-sm", children: "No product decisions available." })) })) : null, visibleTabs.includes('merge-review') ? (_jsx(TabsContent, { value: "merge-review", className: "mt-0 flex min-h-0 flex-1 flex-col", children: mergeData ? (_jsx(MergeReview, { data: mergeData, onApprove: onMergeApprove ?? (() => undefined), onReject: onMergeReject, isProcessing: isMergeLoading, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: onChatInputChange })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) })) : null] }) }));
118
+ return (_jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: _jsxs(Tabs, { value: activeTab, onValueChange: handleTabChange, className: "flex min-h-0 flex-1 flex-col", children: [_jsx("div", { className: "shrink-0 overflow-x-auto px-4 pt-4", children: _jsx(TabsList, { className: "flex w-full", children: visibleTabDefs.map((tab) => (_jsx(TabsTrigger, { value: tab.key, className: "flex-1", children: tab.label }, tab.key))) }) }), _jsx(TabsContent, { value: "overview", className: "mt-0 flex-1 overflow-y-auto", children: _jsx(OverviewTab, { data: featureNode }) }), _jsx(TabsContent, { value: "activity", className: "mt-0 flex-1 overflow-y-auto", children: _jsx(ActivityTab, { timings: tabs.activity.data?.timings ?? null, loading: tabs.activity.loading, error: tabs.activity.error, rejectionFeedback: tabs.activity.data?.rejectionFeedback }) }), _jsx(TabsContent, { value: "log", className: "mt-0 flex-1 overflow-hidden", children: _jsx(LogTab, { content: featureLogs.content, isConnected: featureLogs.isConnected, error: featureLogs.error }) }), _jsx(TabsContent, { value: "plan", className: "mt-0 flex-1 overflow-y-auto", children: _jsx(PlanTab, { plan: tabs.plan.data, loading: tabs.plan.loading, error: tabs.plan.error }) }), visibleTabs.includes('prd-review') ? (_jsx(TabsContent, { value: "prd-review", className: "mt-0 flex min-h-0 flex-1 flex-col", children: prdData ? (_jsx(PrdQuestionnaire, { data: prdData, selections: prdSelections ?? {}, onSelect: onPrdSelect ?? (() => undefined), onApprove: onPrdApprove ?? (() => undefined), onReject: onPrdReject, isProcessing: isPrdLoading, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: onChatInputChange })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) })) : null, visibleTabs.includes('tech-decisions') ? (_jsx(TabsContent, { value: "tech-decisions", className: "mt-0 flex min-h-0 flex-1 flex-col", children: techData ? (_jsxs("div", { className: "flex min-h-0 flex-1 flex-col", children: [_jsx("div", { className: "flex-1 overflow-y-auto", children: _jsx(TechDecisionsContent, { data: techData }) }), _jsx(DrawerActionBarForTech, { onApprove: onTechApprove ?? (() => undefined), onReject: onTechReject, isProcessing: isTechLoading, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: onChatInputChange })] })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) })) : null, visibleTabs.includes('product-decisions') ? (_jsx(TabsContent, { value: "product-decisions", className: "mt-0 flex-1 overflow-y-auto", children: productData === null ? (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) : productData ? (_jsx(ProductDecisionsSummary, { data: productData })) : (_jsx("p", { className: "text-muted-foreground p-4 text-center text-sm", children: "No product decisions available." })) })) : null, visibleTabs.includes('merge-review') ? (_jsx(TabsContent, { value: "merge-review", className: "mt-0 flex min-h-0 flex-1 flex-col", children: mergeData ? (_jsx(MergeReview, { data: mergeData, onApprove: onMergeApprove ?? (() => undefined), onReject: onMergeReject, isProcessing: isMergeLoading, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: onChatInputChange })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) })) : null] }) }));
119
119
  }
120
120
  // ── Private helper ──────────────────────────────────────────────────────
121
121
  function DrawerActionBarForTech({ onApprove, onReject, isProcessing, isRejecting, chatInput, onChatInputChange, }) {
@@ -11,6 +11,8 @@ export declare const CompletedFeature: Story;
11
11
  export declare const RequirementsPhase: Story;
12
12
  /** Feature in error state. */
13
13
  export declare const ErrorState: Story;
14
+ /** Fast mode feature — shows lightning icon in overview details. */
15
+ export declare const FastModeFeature: Story;
14
16
  /** PRD Review tab active — requirements lifecycle, action-required state. */
15
17
  export declare const PrdReviewActive: Story;
16
18
  /** Tech Decisions tab active — implementation lifecycle, action-required state. */
@@ -1 +1 @@
1
- {"version":3,"file":"feature-drawer-tabs.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAO1D,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,iBAAiB,CAcxC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAyPhD,qEAAqE;AACrE,eAAO,MAAM,OAAO,EAAE,KAKrB,CAAC;AAEF,wDAAwD;AACxD,eAAO,MAAM,gBAAgB,EAAE,KAK9B,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,iBAAiB,EAAE,KAK/B,CAAC;AAEF,8BAA8B;AAC9B,eAAO,MAAM,UAAU,EAAE,KAKxB,CAAC;AAMF,6EAA6E;AAC7E,eAAO,MAAM,eAAe,EAAE,KAW7B,CAAC;AAEF,mFAAmF;AACnF,eAAO,MAAM,gBAAgB,EAAE,KAU9B,CAAC;AAEF,yEAAyE;AACzE,eAAO,MAAM,iBAAiB,EAAE,KAS/B,CAAC"}
1
+ {"version":3,"file":"feature-drawer-tabs.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAO1D,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,iBAAiB,CAcxC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAyPhD,qEAAqE;AACrE,eAAO,MAAM,OAAO,EAAE,KAKrB,CAAC;AAEF,wDAAwD;AACxD,eAAO,MAAM,gBAAgB,EAAE,KAK9B,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,iBAAiB,EAAE,KAK/B,CAAC;AAEF,8BAA8B;AAC9B,eAAO,MAAM,UAAU,EAAE,KAKxB,CAAC;AAyBF,oEAAoE;AACpE,eAAO,MAAM,eAAe,EAAE,KAK7B,CAAC;AAMF,6EAA6E;AAC7E,eAAO,MAAM,eAAe,EAAE,KAW7B,CAAC;AAEF,mFAAmF;AACnF,eAAO,MAAM,gBAAgB,EAAE,KAU9B,CAAC;AAEF,yEAAyE;AACzE,eAAO,MAAM,iBAAiB,EAAE,KAS/B,CAAC"}
@@ -274,6 +274,34 @@ export const ErrorState = {
274
274
  featureId: errorFeature.featureId,
275
275
  },
276
276
  };
277
+ /* ---------------------------------------------------------------------------
278
+ * Fast mode stories
279
+ * ------------------------------------------------------------------------- */
280
+ const fastModeFeature = {
281
+ name: 'Quick Fix',
282
+ description: 'Fast mode feature — skipping SDLC phases',
283
+ featureId: 'fast-mode-123',
284
+ lifecycle: 'implementation',
285
+ state: 'running',
286
+ progress: 50,
287
+ fastMode: true,
288
+ agentType: 'claude-code',
289
+ repositoryPath: '/home/user/my-repo',
290
+ branch: 'feat/quick-fix',
291
+ oneLiner: 'quick fix for the login bug',
292
+ userQuery: 'fix the login bug',
293
+ summary: 'Quick fix applied directly from prompt via fast mode',
294
+ createdAt: Date.now() - 10 * 60 * 1000, // 10 minutes ago
295
+ repositoryName: 'my-repo',
296
+ baseBranch: 'main',
297
+ };
298
+ /** Fast mode feature — shows lightning icon in overview details. */
299
+ export const FastModeFeature = {
300
+ args: {
301
+ featureNode: fastModeFeature,
302
+ featureId: fastModeFeature.featureId,
303
+ },
304
+ };
277
305
  /* ---------------------------------------------------------------------------
278
306
  * Review tab stories
279
307
  * ------------------------------------------------------------------------- */
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { ExternalLink, GitBranch, GitCommitHorizontal } from 'lucide-react';
3
+ import { ExternalLink, GitBranch, GitCommitHorizontal, Zap } from 'lucide-react';
4
4
  import { PrStatus } from '../../../../../../packages/core/src/domain/generated/output.js';
5
5
  import { cn } from '../../../lib/utils.js';
6
6
  import { Badge } from '../../ui/badge.js';
@@ -42,15 +42,14 @@ function formatRelativeTime(timestamp) {
42
42
  return 'just now';
43
43
  }
44
44
  function FeatureInfo({ data }) {
45
- const repoName = data.repositoryName ?? data.repositoryPath.split('/').filter(Boolean).at(-1) ?? '';
46
- const hasInfo = Boolean(repoName) ||
47
- Boolean(data.branch) ||
45
+ const hasInfo = Boolean(data.branch) ||
46
+ Boolean(data.oneLiner) ||
48
47
  Boolean(data.summary) ||
49
48
  Boolean(data.userQuery) ||
50
49
  Boolean(data.createdAt);
51
50
  if (!hasInfo)
52
51
  return null;
53
- return (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsxs("div", { "data-testid": "feature-drawer-info", className: "flex flex-col gap-3 p-4", children: [repoName ? _jsx(DetailRow, { label: "Repository", value: repoName }) : null, data.branch ? (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Branch" }), _jsxs("span", { className: "flex items-center gap-1.5 text-sm", children: [_jsx(GitBranch, { className: "text-muted-foreground h-3.5 w-3.5 shrink-0" }), _jsx("code", { className: "bg-muted rounded px-1 py-0.5 font-mono text-xs", children: data.branch }), data.baseBranch ? (_jsxs("span", { className: "text-muted-foreground text-xs", children: ["from ", data.baseBranch] })) : null] })] })) : null, data.userQuery ? (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "User Query" }), _jsx("span", { className: "text-sm leading-relaxed", children: data.userQuery })] })) : null, data.summary ? (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Summary" }), _jsx("span", { className: "text-sm leading-relaxed", children: data.summary })] })) : null, data.createdAt ? (_jsx(DetailRow, { label: "Created", value: formatRelativeTime(data.createdAt) })) : null] })] }));
52
+ return (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsxs("div", { "data-testid": "feature-drawer-info", className: "flex flex-col gap-3 p-4", children: [data.branch ? (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Branch" }), _jsxs("span", { className: "flex items-center gap-1.5 text-sm", children: [_jsx(GitBranch, { className: "text-muted-foreground h-3.5 w-3.5 shrink-0" }), _jsx("code", { className: "bg-muted rounded px-1 py-0.5 font-mono text-xs", children: data.branch }), data.baseBranch ? (_jsxs("span", { className: "text-muted-foreground text-xs", children: ["from ", data.baseBranch] })) : null] })] })) : null, data.oneLiner ? (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "One-Liner" }), _jsx("span", { className: "text-sm leading-relaxed", children: data.oneLiner })] })) : null, data.userQuery ? (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "User Query" }), _jsx("span", { className: "text-sm leading-relaxed", children: data.userQuery })] })) : null, data.summary ? (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Summary" }), _jsx("span", { className: "text-sm leading-relaxed", children: data.summary })] })) : null, data.createdAt ? (_jsx(DetailRow, { label: "Created", value: formatRelativeTime(data.createdAt) })) : null] })] }));
54
53
  }
55
54
  // ── PR Info section ──────────────────────────────────────────────────
56
55
  const prStatusStyles = {
@@ -63,10 +62,10 @@ function FeaturePrInfo({ pr }) {
63
62
  }
64
63
  // ── Details section ──────────────────────────────────────────────────
65
64
  function FeatureDetails({ data }) {
66
- const hasAnyDetail = data.agentType ?? data.runtime ?? data.blockedBy ?? data.errorMessage;
65
+ const hasAnyDetail = data.fastMode ?? data.agentType ?? data.runtime ?? data.blockedBy ?? data.errorMessage;
67
66
  if (!hasAnyDetail)
68
67
  return null;
69
- return (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsxs("div", { "data-testid": "feature-drawer-details", className: "flex flex-col gap-3 p-4", children: [data.agentType ? _jsx(AgentDetailRow, { agentType: data.agentType }) : null, data.runtime ? _jsx(DetailRow, { label: "Runtime", value: data.runtime }) : null, data.blockedBy ? _jsx(DetailRow, { label: "Blocked by", value: data.blockedBy }) : null, data.errorMessage ? _jsx(DetailRow, { label: "Error", value: data.errorMessage }) : null] })] }));
68
+ return (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsxs("div", { "data-testid": "feature-drawer-details", className: "flex flex-col gap-3 p-4", children: [data.fastMode ? (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Mode" }), _jsxs("span", { className: "flex items-center gap-2 text-sm", children: [_jsx(Zap, { className: "h-4 w-4 shrink-0 text-amber-500" }), "Fast Mode"] })] })) : null, data.agentType ? _jsx(AgentDetailRow, { agentType: data.agentType }) : null, data.runtime ? _jsx(DetailRow, { label: "Runtime", value: data.runtime }) : null, data.blockedBy ? _jsx(DetailRow, { label: "Blocked by", value: data.blockedBy }) : null, data.errorMessage ? _jsx(DetailRow, { label: "Error", value: data.errorMessage }) : null] })] }));
70
69
  }
71
70
  function AgentDetailRow({ agentType }) {
72
71
  const Icon = getAgentTypeIcon(agentType);
@@ -17,6 +17,8 @@ export declare const Blocked: Story;
17
17
  export declare const Error: Story;
18
18
  /** Minimal data — only required fields, no optional details or PR. */
19
19
  export declare const Minimal: Story;
20
+ /** Fast mode feature — shows lightning icon in details section. */
21
+ export declare const FastMode: Story;
20
22
  /** Requirements phase. */
21
23
  export declare const RequirementsPhase: Story;
22
24
  /** Research phase. */
@@ -1 +1 @@
1
- {"version":3,"file":"overview-tab.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,WAAW,CAclC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,WAAW,CAAC,CAAC;AA0G1C,uEAAuE;AACvE,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,IAAI,EAAE,KAElB,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,UAAU,EAAE,KAExB,CAAC;AAEF,wDAAwD;AACxD,eAAO,MAAM,gBAAgB,EAAE,KAE9B,CAAC;AAEF,iDAAiD;AACjD,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,gDAAgD;AAChD,eAAO,MAAM,KAAK,EAAE,KAEnB,CAAC;AAEF,sEAAsE;AACtE,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAMF,0BAA0B;AAC1B,eAAO,MAAM,iBAAiB,EAAE,KAE/B,CAAC;AAEF,sBAAsB;AACtB,eAAO,MAAM,aAAa,EAAE,KAE3B,CAAC;AAEF,oBAAoB;AACpB,eAAO,MAAM,WAAW,EAAE,KAEzB,CAAC;AAEF,sBAAsB;AACtB,eAAO,MAAM,aAAa,EAAE,KAE3B,CAAC"}
1
+ {"version":3,"file":"overview-tab.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,WAAW,CAclC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,WAAW,CAAC,CAAC;AA0G1C,uEAAuE;AACvE,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,IAAI,EAAE,KAElB,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,UAAU,EAAE,KAExB,CAAC;AAEF,wDAAwD;AACxD,eAAO,MAAM,gBAAgB,EAAE,KAE9B,CAAC;AAEF,iDAAiD;AACjD,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,gDAAgD;AAChD,eAAO,MAAM,KAAK,EAAE,KAEnB,CAAC;AAEF,sEAAsE;AACtE,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAwBF,mEAAmE;AACnE,eAAO,MAAM,QAAQ,EAAE,KAEtB,CAAC;AAMF,0BAA0B;AAC1B,eAAO,MAAM,iBAAiB,EAAE,KAE/B,CAAC;AAEF,sBAAsB;AACtB,eAAO,MAAM,aAAa,EAAE,KAE3B,CAAC;AAEF,oBAAoB;AACpB,eAAO,MAAM,WAAW,EAAE,KAEzB,CAAC;AAEF,sBAAsB;AACtB,eAAO,MAAM,aAAa,EAAE,KAE3B,CAAC"}
@@ -136,6 +136,30 @@ export const Error = {
136
136
  export const Minimal = {
137
137
  args: { data: minimalData },
138
138
  };
139
+ /* ---------------------------------------------------------------------------
140
+ * Fast mode stories
141
+ * ------------------------------------------------------------------------- */
142
+ const fastModeData = {
143
+ name: 'Quick Fix',
144
+ description: 'Fast mode feature — skipping SDLC phases',
145
+ featureId: '#fm1',
146
+ lifecycle: 'implementation',
147
+ state: 'running',
148
+ progress: 50,
149
+ fastMode: true,
150
+ agentType: 'claude-code',
151
+ repositoryPath: '/home/user/my-repo',
152
+ branch: 'feat/quick-fix',
153
+ userQuery: 'fix the login bug',
154
+ summary: 'Quick fix applied directly from prompt via fast mode',
155
+ createdAt: Date.now() - 10 * 60 * 1000,
156
+ repositoryName: 'my-repo',
157
+ baseBranch: 'main',
158
+ };
159
+ /** Fast mode feature — shows lightning icon in details section. */
160
+ export const FastMode = {
161
+ args: { data: fastModeData },
162
+ };
139
163
  /* ---------------------------------------------------------------------------
140
164
  * Lifecycle phase stories
141
165
  * ------------------------------------------------------------------------- */
@@ -30,6 +30,8 @@ export interface FeatureNodeData {
30
30
  blockedBy?: string;
31
31
  /** Short error message for error state */
32
32
  errorMessage?: string;
33
+ /** Whether the feature was created in fast mode (skip SDLC phases). */
34
+ fastMode?: boolean;
33
35
  /** Agent executor type (e.g. "claude-code", "cursor"). */
34
36
  agentType?: AgentTypeValue;
35
37
  /** LLM model identifier used for this feature's agent run. */
@@ -40,6 +42,8 @@ export interface FeatureNodeData {
40
42
  createdAt?: string | number;
41
43
  /** Repository display name (e.g. "my-repo") */
42
44
  repositoryName?: string;
45
+ /** Remote URL for the repository (HTTPS, suitable for browser linking) */
46
+ remoteUrl?: string;
43
47
  /** Base branch the feature was branched from (e.g. "main") */
44
48
  baseBranch?: string;
45
49
  /** AI-generated one-line description of the feature (from spec artifact) */
@@ -1 +1 @@
1
- {"version":3,"file":"feature-node-state-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node-state-config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"feature-node-state-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node-state-config.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAyDnE,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,2CAuPA"}
1
+ {"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAyDnE,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,2CAuQA"}
@@ -2,7 +2,7 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useState } from 'react';
4
4
  import { Handle, Position } from '@xyflow/react';
5
- import { Plus, FileText, Wrench, GitMerge, Trash2 } from 'lucide-react';
5
+ import { Plus, FileText, Wrench, GitMerge, Trash2, Zap } from 'lucide-react';
6
6
  import { cn } from '../../../lib/utils.js';
7
7
  import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '../../ui/dialog.js';
8
8
  import { Button } from '../../ui/button.js';
@@ -74,12 +74,12 @@ export function FeatureNode({ data, selected, }) {
74
74
  e.stopPropagation();
75
75
  setConfirmOpen(false);
76
76
  data.onDelete?.(data.featureId);
77
- }, children: "Delete" })] })] }) })] })) : null, _jsxs("div", { "data-testid": "feature-node-card", "aria-busy": data.state === 'creating' ? 'true' : undefined, className: cn('bg-card flex min-h-35 w-72 flex-col rounded-lg border p-3 shadow-sm', selected && 'ring-primary ring-2'), children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { "data-testid": "feature-node-lifecycle-label", className: cn('text-[10px] font-semibold tracking-wider'), children: data.state === 'blocked' ? 'BLOCKED' : lifecycleDisplayLabels[data.lifecycle] }), data.agentType ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": agentTypeLabels[data.agentType] ?? data.agentType, "data-testid": "feature-node-agent-badge", onClick: (e) => {
78
- e.stopPropagation();
79
- data.onSettings?.();
80
- }, className: cn('nodrag -mt-1 -mr-1 p-1', data.onSettings
81
- ? 'cursor-pointer opacity-80 transition-opacity hover:opacity-100'
82
- : 'cursor-default'), children: _jsx(AgentIcon, { agentType: data.agentType, className: "h-3.5 w-3.5" }) }) }), _jsxs(TooltipContent, { side: "bottom", children: [_jsx("span", { className: "font-medium", children: agentTypeLabels[data.agentType] ?? data.agentType }), data.modelId ? (_jsxs("span", { className: "ml-1 opacity-70", children: ["\u00B7 ", getModelMeta(data.modelId).displayName || data.modelId] })) : null] })] }) })) : null] }), _jsx("h3", { className: "mt-1 truncate text-sm font-bold", children: data.name }), data.description ? (_jsx("p", { "data-testid": "feature-node-description", className: "text-muted-foreground mt-0.5 truncate text-xs", children: data.description })) : null, _jsx("div", { className: "mt-auto pt-2", children: data.state === 'creating' ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mt-1.5 flex items-center gap-1.5 text-xs", children: [_jsx(Icon, { className: "h-3.5 w-3.5 shrink-0 animate-spin" }), _jsx("span", { className: "text-muted-foreground", children: getBadgeText(data) })] }), _jsx("div", { "data-testid": "feature-node-progress-bar", className: "bg-muted mt-1.5 h-1 w-full overflow-hidden rounded-full", children: _jsx("div", { className: "motion-safe:animate-indeterminate-progress bg-foreground/30 h-full w-1/3 rounded-full" }) })] })) : data.state === 'running' ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mt-1.5 flex items-center gap-1.5 text-xs", children: [_jsx(AgentIcon, { agentType: data.agentType, className: "h-3.5 w-3.5 shrink-0" }), _jsx("span", { className: "text-muted-foreground", children: getBadgeText(data) })] }), _jsx("div", { "data-testid": "feature-node-progress-bar", className: "bg-muted mt-1.5 h-1 w-full overflow-hidden rounded-full", children: _jsx("div", { className: "animate-indeterminate-progress bg-foreground/30 h-full w-1/3 rounded-full" }) })] })) : config.showProgressBar ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "text-muted-foreground flex items-center justify-end text-[10px]", children: _jsxs("span", { children: [data.progress, "%"] }) }), _jsx("div", { "data-testid": "feature-node-progress-bar", className: "bg-muted mt-1.5 h-1 w-full overflow-hidden rounded-full", children: _jsx("div", { className: cn('h-full rounded-full transition-all', config.progressClass), style: { width: `${data.progress}%` } }) })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "text-muted-foreground text-[10px]", children: _jsx("span", { children: data.featureId }) }), _jsxs("div", { "data-testid": "feature-node-badge", className: (() => {
77
+ }, children: "Delete" })] })] }) })] })) : null, _jsxs("div", { "data-testid": "feature-node-card", "aria-busy": data.state === 'creating' ? 'true' : undefined, className: cn('bg-card flex min-h-35 w-72 flex-col rounded-lg border p-3 shadow-sm', selected && 'ring-primary ring-2'), children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { "data-testid": "feature-node-lifecycle-label", className: cn('text-[10px] font-semibold tracking-wider'), children: data.state === 'blocked' ? 'BLOCKED' : lifecycleDisplayLabels[data.lifecycle] }), _jsxs("div", { className: "flex items-center gap-0.5", children: [data.fastMode ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { "data-testid": "feature-node-fast-mode-badge", className: "-mt-1 p-1", children: _jsx(Zap, { className: "h-3.5 w-3.5 text-amber-500" }) }) }), _jsx(TooltipContent, { side: "bottom", children: "Fast Mode" })] }) })) : null, data.agentType ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": agentTypeLabels[data.agentType] ?? data.agentType, "data-testid": "feature-node-agent-badge", onClick: (e) => {
78
+ e.stopPropagation();
79
+ data.onSettings?.();
80
+ }, className: cn('nodrag -mt-1 -mr-1 p-1', data.onSettings
81
+ ? 'cursor-pointer opacity-80 transition-opacity hover:opacity-100'
82
+ : 'cursor-default'), children: _jsx(AgentIcon, { agentType: data.agentType, className: "h-3.5 w-3.5" }) }) }), _jsxs(TooltipContent, { side: "bottom", children: [_jsx("span", { className: "font-medium", children: agentTypeLabels[data.agentType] ?? data.agentType }), data.modelId ? (_jsxs("span", { className: "ml-1 opacity-70", children: ["\u00B7 ", getModelMeta(data.modelId).displayName || data.modelId] })) : null] })] }) })) : null] })] }), _jsx("h3", { className: "mt-1 truncate text-sm font-bold", children: data.name }), data.description ? (_jsx("p", { "data-testid": "feature-node-description", className: "text-muted-foreground mt-0.5 truncate text-xs", children: data.description })) : null, _jsx("div", { className: "mt-auto pt-2", children: data.state === 'creating' ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mt-1.5 flex items-center gap-1.5 text-xs", children: [_jsx(Icon, { className: "h-3.5 w-3.5 shrink-0 animate-spin" }), _jsx("span", { className: "text-muted-foreground", children: getBadgeText(data) })] }), _jsx("div", { "data-testid": "feature-node-progress-bar", className: "bg-muted mt-1.5 h-1 w-full overflow-hidden rounded-full", children: _jsx("div", { className: "motion-safe:animate-indeterminate-progress bg-foreground/30 h-full w-1/3 rounded-full" }) })] })) : data.state === 'running' ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mt-1.5 flex items-center gap-1.5 text-xs", children: [_jsx(AgentIcon, { agentType: data.agentType, className: "h-3.5 w-3.5 shrink-0" }), _jsx("span", { className: "text-muted-foreground", children: getBadgeText(data) })] }), _jsx("div", { "data-testid": "feature-node-progress-bar", className: "bg-muted mt-1.5 h-1 w-full overflow-hidden rounded-full", children: _jsx("div", { className: "animate-indeterminate-progress bg-foreground/30 h-full w-1/3 rounded-full" }) })] })) : config.showProgressBar ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "text-muted-foreground flex items-center justify-end text-[10px]", children: _jsxs("span", { children: [data.progress, "%"] }) }), _jsx("div", { "data-testid": "feature-node-progress-bar", className: "bg-muted mt-1.5 h-1 w-full overflow-hidden rounded-full", children: _jsx("div", { className: cn('h-full rounded-full transition-all', config.progressClass), style: { width: `${data.progress}%` } }) })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "text-muted-foreground text-[10px]", children: _jsx("span", { children: data.featureId }) }), _jsxs("div", { "data-testid": "feature-node-badge", className: (() => {
83
83
  const override = getActionRequiredBadgeClasses(data);
84
84
  return cn('mt-1.5 flex items-center justify-center gap-1.5 rounded-full px-2.5 py-1 text-[11px] font-medium', override?.badgeBgClass ?? config.badgeBgClass, override?.badgeClass ?? config.badgeClass);
85
85
  })(), children: [(() => {
@@ -15,5 +15,7 @@ export declare const Creating: Story;
15
15
  export declare const MergeReviewActionRequired: Story;
16
16
  export declare const ErrorWithMessage: Story;
17
17
  export declare const WithDeleteButton: Story;
18
+ export declare const FastMode: Story;
19
+ export declare const FastModeDone: Story;
18
20
  export declare const Interactive: Story;
19
21
  //# sourceMappingURL=feature-node.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"feature-node.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAKvD,OAAO,KAAK,EACV,eAAe,EAIhB,MAAM,6BAA6B,CAAC;AAiCrC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,eAAe,CAc/B,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAC;AAEvC,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAsGF,eAAO,MAAM,SAAS,EAAE,KAQvB,CAAC;AAWF,eAAO,MAAM,aAAa,EAAE,KAqB3B,CAAC;AA2EF,eAAO,MAAM,aAAa,EAAE,KAQ3B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAMxB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAW7B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAUtB,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,KAUvC,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AA4EF,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC"}
1
+ {"version":3,"file":"feature-node.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAKvD,OAAO,KAAK,EACV,eAAe,EAIhB,MAAM,6BAA6B,CAAC;AAiCrC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,eAAe,CAc/B,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAC;AAEvC,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAsGF,eAAO,MAAM,SAAS,EAAE,KAQvB,CAAC;AAWF,eAAO,MAAM,aAAa,EAAE,KAqB3B,CAAC;AA2EF,eAAO,MAAM,aAAa,EAAE,KAQ3B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAMxB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAW7B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAUtB,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,KAUvC,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAatB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAc1B,CAAC;AA4EF,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC"}
@@ -309,6 +309,35 @@ export const WithDeleteButton = {
309
309
  },
310
310
  render: (args) => _jsx(FeatureNodeCanvas, { data: args }),
311
311
  };
312
+ export const FastMode = {
313
+ args: {
314
+ name: 'Quick Feature',
315
+ description: 'Fast mode feature — skipping SDLC phases',
316
+ featureId: '#fm1',
317
+ lifecycle: 'implementation',
318
+ state: 'running',
319
+ progress: 50,
320
+ fastMode: true,
321
+ agentType: 'claude-code',
322
+ modelId: 'claude-sonnet-4-6',
323
+ },
324
+ render: (args) => _jsx(FeatureNodeCanvas, { data: args }),
325
+ };
326
+ export const FastModeDone = {
327
+ args: {
328
+ name: 'Fast Feature Done',
329
+ description: 'Completed fast mode feature',
330
+ featureId: '#fm2',
331
+ lifecycle: 'deploy',
332
+ state: 'done',
333
+ progress: 100,
334
+ runtime: '12m',
335
+ fastMode: true,
336
+ agentType: 'claude-code',
337
+ modelId: 'claude-sonnet-4-6',
338
+ },
339
+ render: (args) => _jsx(FeatureNodeCanvas, { data: args }),
340
+ };
312
341
  const interactiveInitialNodes = [
313
342
  {
314
343
  id: 'node-1',