@shepai/cli 1.83.0 → 1.84.0-pr250.9819070

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 (318) hide show
  1. package/apis/json-schema/Attachment.yaml +31 -0
  2. package/apis/json-schema/Feature.yaml +10 -0
  3. package/dist/packages/core/src/application/use-cases/agents/reject-agent-run.use-case.d.ts.map +1 -1
  4. package/dist/packages/core/src/application/use-cases/agents/reject-agent-run.use-case.js +3 -0
  5. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts +3 -1
  6. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
  7. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +35 -3
  8. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts +7 -1
  9. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts.map +1 -1
  10. package/dist/packages/core/src/domain/generated/output.d.ts +33 -0
  11. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  12. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  13. package/dist/packages/core/src/infrastructure/di/container.js +3 -0
  14. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts +1 -0
  15. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts.map +1 -1
  16. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.js +4 -0
  17. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.d.ts.map +1 -1
  18. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.js +16 -0
  19. package/dist/packages/core/src/infrastructure/services/attachment-storage.service.d.ts +31 -0
  20. package/dist/packages/core/src/infrastructure/services/attachment-storage.service.d.ts.map +1 -0
  21. package/dist/packages/core/src/infrastructure/services/attachment-storage.service.js +136 -0
  22. package/dist/src/presentation/cli/commands/feat/new.command.d.ts.map +1 -1
  23. package/dist/src/presentation/cli/commands/feat/new.command.js +21 -1
  24. package/dist/src/presentation/web/app/actions/compose-user-input.d.ts +7 -0
  25. package/dist/src/presentation/web/app/actions/compose-user-input.d.ts.map +1 -0
  26. package/dist/src/presentation/web/app/actions/compose-user-input.js +7 -0
  27. package/dist/src/presentation/web/app/actions/create-feature.d.ts +1 -0
  28. package/dist/src/presentation/web/app/actions/create-feature.d.ts.map +1 -1
  29. package/dist/src/presentation/web/app/actions/create-feature.js +3 -9
  30. package/dist/src/presentation/web/app/actions/get-feature-phase-timings.d.ts +6 -0
  31. package/dist/src/presentation/web/app/actions/get-feature-phase-timings.d.ts.map +1 -1
  32. package/dist/src/presentation/web/app/actions/get-feature-phase-timings.js +26 -1
  33. package/dist/src/presentation/web/app/actions/get-feature-plan.d.ts +10 -0
  34. package/dist/src/presentation/web/app/actions/get-feature-plan.d.ts.map +1 -1
  35. package/dist/src/presentation/web/app/actions/get-feature-plan.js +8 -0
  36. package/dist/src/presentation/web/app/api/attachments/preview/route.d.ts +4 -0
  37. package/dist/src/presentation/web/app/api/attachments/preview/route.d.ts.map +1 -0
  38. package/dist/src/presentation/web/app/api/attachments/preview/route.js +47 -0
  39. package/dist/src/presentation/web/app/api/attachments/upload/route.d.ts +3 -0
  40. package/dist/src/presentation/web/app/api/attachments/upload/route.d.ts.map +1 -0
  41. package/dist/src/presentation/web/app/api/attachments/upload/route.js +100 -0
  42. package/dist/src/presentation/web/components/common/attachment-card/attachment-card.d.ts +16 -0
  43. package/dist/src/presentation/web/components/common/attachment-card/attachment-card.d.ts.map +1 -0
  44. package/dist/src/presentation/web/components/common/attachment-card/attachment-card.js +53 -0
  45. package/dist/src/presentation/web/components/common/attachment-card/attachment-card.stories.d.ts +12 -0
  46. package/dist/src/presentation/web/components/common/attachment-card/attachment-card.stories.d.ts.map +1 -0
  47. package/dist/src/presentation/web/components/common/attachment-card/attachment-card.stories.js +55 -0
  48. package/dist/src/presentation/web/components/common/attachment-card/index.d.ts +3 -0
  49. package/dist/src/presentation/web/components/common/attachment-card/index.d.ts.map +1 -0
  50. package/dist/src/presentation/web/components/common/attachment-card/index.js +1 -0
  51. package/dist/src/presentation/web/components/common/attachment-chip/attachment-chip.d.ts +11 -0
  52. package/dist/src/presentation/web/components/common/attachment-chip/attachment-chip.d.ts.map +1 -0
  53. package/dist/src/presentation/web/components/common/attachment-chip/attachment-chip.js +34 -0
  54. package/dist/src/presentation/web/components/common/attachment-chip/attachment-chip.stories.d.ts +10 -0
  55. package/dist/src/presentation/web/components/common/attachment-chip/attachment-chip.stories.d.ts.map +1 -0
  56. package/dist/src/presentation/web/components/common/attachment-chip/attachment-chip.stories.js +44 -0
  57. package/dist/src/presentation/web/components/common/attachment-chip/index.d.ts +3 -0
  58. package/dist/src/presentation/web/components/common/attachment-chip/index.d.ts.map +1 -0
  59. package/dist/src/presentation/web/components/common/attachment-chip/index.js +1 -0
  60. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts +11 -2
  61. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  62. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +199 -60
  63. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts +6 -0
  64. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts.map +1 -1
  65. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.js +18 -0
  66. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.d.ts +3 -2
  67. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.d.ts.map +1 -1
  68. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.js +29 -6
  69. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.d.ts +2 -0
  70. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.d.ts.map +1 -1
  71. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.js +72 -0
  72. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.d.ts.map +1 -1
  73. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.js +2 -2
  74. package/dist/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.d.ts.map +1 -1
  75. package/dist/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.js +3 -20
  76. package/dist/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.stories.d.ts.map +1 -1
  77. package/dist/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.stories.js +74 -0
  78. package/dist/src/presentation/web/components/common/task-progress-view/index.d.ts +3 -0
  79. package/dist/src/presentation/web/components/common/task-progress-view/index.d.ts.map +1 -0
  80. package/dist/src/presentation/web/components/common/task-progress-view/index.js +1 -0
  81. package/dist/src/presentation/web/components/common/task-progress-view/task-progress-view.d.ts +6 -0
  82. package/dist/src/presentation/web/components/common/task-progress-view/task-progress-view.d.ts.map +1 -0
  83. package/dist/src/presentation/web/components/common/task-progress-view/task-progress-view.js +84 -0
  84. package/dist/src/presentation/web/components/common/task-progress-view/task-progress-view.stories.d.ts +16 -0
  85. package/dist/src/presentation/web/components/common/task-progress-view/task-progress-view.stories.d.ts.map +1 -0
  86. package/dist/src/presentation/web/components/common/task-progress-view/task-progress-view.stories.js +194 -0
  87. package/dist/src/presentation/web/components/ui/dialog.js +1 -1
  88. package/dist/src/presentation/web/next.config.d.ts.map +1 -1
  89. package/dist/src/presentation/web/next.config.js +6 -0
  90. package/dist/tsconfig.build.tsbuildinfo +1 -1
  91. package/package.json +1 -1
  92. package/web/.next/BUILD_ID +1 -1
  93. package/web/.next/app-path-routes-manifest.json +2 -0
  94. package/web/.next/build-manifest.json +2 -2
  95. package/web/.next/fallback-build-manifest.json +2 -2
  96. package/web/.next/prerender-manifest.json +3 -3
  97. package/web/.next/required-server-files.js +4 -1
  98. package/web/.next/required-server-files.json +4 -1
  99. package/web/.next/routes-manifest.json +12 -0
  100. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +18 -18
  101. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +2 -2
  102. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  103. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  104. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +21 -21
  105. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +3 -3
  106. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  107. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  108. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +14 -14
  109. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +2 -2
  110. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  111. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  112. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +18 -18
  113. package/web/.next/server/app/(dashboard)/create/page.js +2 -2
  114. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  115. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  116. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +21 -21
  117. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +3 -3
  118. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  119. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  120. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +14 -14
  121. package/web/.next/server/app/(dashboard)/page.js +2 -2
  122. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  123. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  124. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +14 -14
  125. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +2 -2
  126. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  127. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  128. package/web/.next/server/app/_global-error/page.js +2 -2
  129. package/web/.next/server/app/_global-error/page.js.nft.json +1 -1
  130. package/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  131. package/web/.next/server/app/_global-error.html +2 -2
  132. package/web/.next/server/app/_global-error.rsc +1 -1
  133. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  134. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  135. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  136. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  137. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  138. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  139. package/web/.next/server/app/_not-found/page.js +2 -2
  140. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  141. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  142. package/web/.next/server/app/api/attachments/preview/route/app-paths-manifest.json +3 -0
  143. package/web/.next/server/app/api/attachments/preview/route/build-manifest.json +11 -0
  144. package/web/.next/server/app/api/attachments/preview/route/server-reference-manifest.json +4 -0
  145. package/web/.next/server/app/api/attachments/preview/route.js +7 -0
  146. package/web/.next/server/app/api/attachments/preview/route.js.map +5 -0
  147. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -0
  148. package/web/.next/server/app/api/attachments/preview/route_client-reference-manifest.js +2 -0
  149. package/web/.next/server/app/api/attachments/upload/route/app-paths-manifest.json +3 -0
  150. package/web/.next/server/app/api/attachments/upload/route/build-manifest.json +11 -0
  151. package/web/.next/server/app/api/attachments/upload/route/server-reference-manifest.json +4 -0
  152. package/web/.next/server/app/api/attachments/upload/route.js +7 -0
  153. package/web/.next/server/app/api/attachments/upload/route.js.map +5 -0
  154. package/web/.next/server/app/api/attachments/upload/route.js.nft.json +1 -0
  155. package/web/.next/server/app/api/attachments/upload/route_client-reference-manifest.js +2 -0
  156. package/web/.next/server/app/api/dialog/pick-files/route.js +1 -1
  157. package/web/.next/server/app/api/dialog/pick-files/route.js.nft.json +1 -1
  158. package/web/.next/server/app/api/feature-logs/route.js +1 -1
  159. package/web/.next/server/app/api/feature-logs/route.js.nft.json +1 -1
  160. package/web/.next/server/app/settings/page/server-reference-manifest.json +5 -5
  161. package/web/.next/server/app/settings/page.js +2 -2
  162. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  163. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  164. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  165. package/web/.next/server/app/skills/page.js +5 -4
  166. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  167. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  168. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  169. package/web/.next/server/app/tools/page.js +2 -2
  170. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  171. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  172. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  173. package/web/.next/server/app/version/page.js +2 -2
  174. package/web/.next/server/app/version/page.js.nft.json +1 -1
  175. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  176. package/web/.next/server/app-paths-manifest.json +2 -0
  177. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js.map +1 -1
  178. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_attachments_preview_route_actions_0f48c3e9.js +3 -0
  179. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_attachments_preview_route_actions_0f48c3e9.js.map +1 -0
  180. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_attachments_upload_route_actions_48fe4a8f.js +3 -0
  181. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_attachments_upload_route_actions_48fe4a8f.js.map +1 -0
  182. package/web/.next/server/chunks/[root-of-the-server]__0b10355c._.js +3 -0
  183. package/web/.next/server/chunks/[root-of-the-server]__0b10355c._.js.map +1 -0
  184. package/web/.next/server/chunks/{[root-of-the-server]__a6bf88cc._.js → [root-of-the-server]__332c8d91._.js} +2 -2
  185. package/web/.next/server/chunks/{[root-of-the-server]__91d44424._.js → [root-of-the-server]__52c318d1._.js} +2 -2
  186. package/web/.next/server/chunks/[root-of-the-server]__b2f9a412._.js +3 -0
  187. package/web/.next/server/chunks/[root-of-the-server]__b2f9a412._.js.map +1 -0
  188. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  189. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  190. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_9751e686._.js +3 -0
  191. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_9751e686._.js.map +1 -0
  192. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js +1 -1
  193. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js.map +1 -1
  194. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js +1 -1
  195. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js.map +1 -1
  196. package/web/.next/server/chunks/ssr/90b01_js-yaml_dist_js-yaml_mjs_c897fb57._.js +3 -0
  197. package/web/.next/server/chunks/ssr/90b01_js-yaml_dist_js-yaml_mjs_c897fb57._.js.map +1 -0
  198. package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js +1 -1
  199. package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js.map +1 -1
  200. package/web/.next/server/chunks/ssr/[root-of-the-server]__17143953._.js +3 -0
  201. package/web/.next/server/chunks/ssr/[root-of-the-server]__17143953._.js.map +1 -0
  202. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  203. package/web/.next/server/chunks/ssr/[root-of-the-server]__4be9a9bb._.js +1 -1
  204. package/web/.next/server/chunks/ssr/[root-of-the-server]__5d87af2e._.js +1 -1
  205. package/web/.next/server/chunks/ssr/{[root-of-the-server]__3534949f._.js → [root-of-the-server]__8d9536c4._.js} +2 -2
  206. package/web/.next/server/chunks/ssr/[root-of-the-server]__9de266fa._.js +3 -0
  207. package/web/.next/server/chunks/ssr/[root-of-the-server]__9de266fa._.js.map +1 -0
  208. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
  209. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
  210. package/web/.next/server/chunks/ssr/[root-of-the-server]__b14946f5._.js +10 -0
  211. package/web/.next/server/chunks/ssr/{[root-of-the-server]__c3694f82._.js.map → [root-of-the-server]__b14946f5._.js.map} +1 -1
  212. package/web/.next/server/chunks/ssr/[root-of-the-server]__b3a4cef4._.js +1 -1
  213. package/web/.next/server/chunks/ssr/[root-of-the-server]__b3a4cef4._.js.map +1 -1
  214. package/web/.next/server/chunks/ssr/[root-of-the-server]__b65f78cf._.js +3 -0
  215. package/web/.next/server/chunks/ssr/{[root-of-the-server]__55f60c9d._.js.map → [root-of-the-server]__b65f78cf._.js.map} +1 -1
  216. package/web/.next/server/chunks/ssr/[root-of-the-server]__f0d8d054._.js +2 -2
  217. package/web/.next/server/chunks/ssr/[root-of-the-server]__f0d8d054._.js.map +1 -1
  218. package/web/.next/server/chunks/ssr/{[root-of-the-server]__ad2b2a3c._.js → [root-of-the-server]__f1a05100._.js} +2 -2
  219. package/web/.next/server/chunks/ssr/[root-of-the-server]__f8210f45._.js +3 -0
  220. package/web/.next/server/chunks/ssr/{[root-of-the-server]__01a37f7a._.js.map → [root-of-the-server]__f8210f45._.js.map} +1 -1
  221. package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js +1 -1
  222. package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js.map +1 -1
  223. package/web/.next/server/chunks/ssr/_1bb131c4._.js +1 -1
  224. package/web/.next/server/chunks/ssr/_1bb131c4._.js.map +1 -1
  225. package/web/.next/server/chunks/ssr/_1e3cf73b._.js +1 -1
  226. package/web/.next/server/chunks/ssr/_1e3cf73b._.js.map +1 -1
  227. package/web/.next/server/chunks/ssr/_34fbed18._.js +1 -1
  228. package/web/.next/server/chunks/ssr/_34fbed18._.js.map +1 -1
  229. package/web/.next/server/chunks/ssr/_3a4c94e3._.js +1 -1
  230. package/web/.next/server/chunks/ssr/_3a4c94e3._.js.map +1 -1
  231. package/web/.next/server/chunks/ssr/{_1c1bf992._.js → _538fb698._.js} +2 -2
  232. package/web/.next/server/chunks/ssr/_538fb698._.js.map +1 -0
  233. package/web/.next/server/chunks/ssr/_63868199._.js +1 -1
  234. package/web/.next/server/chunks/ssr/_63868199._.js.map +1 -1
  235. package/web/.next/server/chunks/ssr/_6e08ce21._.js.map +1 -1
  236. package/web/.next/server/chunks/ssr/_8dacd1e7._.js +1 -1
  237. package/web/.next/server/chunks/ssr/_8dacd1e7._.js.map +1 -1
  238. package/web/.next/server/chunks/ssr/_9ac70f88._.js +5 -0
  239. package/web/.next/server/chunks/ssr/_9ac70f88._.js.map +1 -0
  240. package/web/.next/server/chunks/ssr/{_3e88ce9d._.js → _cf366ac8._.js} +2 -2
  241. package/web/.next/server/chunks/ssr/{_3e88ce9d._.js.map → _cf366ac8._.js.map} +1 -1
  242. package/web/.next/server/chunks/ssr/_d42594dd._.js +3 -0
  243. package/web/.next/server/chunks/ssr/_d42594dd._.js.map +1 -0
  244. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  245. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  246. package/web/.next/server/chunks/ssr/node_modules__pnpm_07f6911c._.js +3 -0
  247. package/web/.next/server/chunks/ssr/node_modules__pnpm_07f6911c._.js.map +1 -0
  248. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js +1 -1
  249. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js.map +1 -1
  250. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
  251. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
  252. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
  253. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
  254. package/web/.next/server/chunks/ssr/src_presentation_web_c4348b8a._.js +2 -3
  255. package/web/.next/server/chunks/ssr/src_presentation_web_c4348b8a._.js.map +1 -1
  256. package/web/.next/server/chunks/ssr/src_presentation_web_components_80b5b4bc._.js +3 -0
  257. package/web/.next/server/chunks/ssr/src_presentation_web_components_80b5b4bc._.js.map +1 -0
  258. package/web/.next/server/chunks/ssr/src_presentation_web_components_82416b8f._.js +3 -0
  259. package/web/.next/server/chunks/ssr/src_presentation_web_components_82416b8f._.js.map +1 -0
  260. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  261. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  262. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_tools_tools-page-client_tsx_3d0aa70c._.js +1 -1
  263. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_tools_tools-page-client_tsx_3d0aa70c._.js.map +1 -1
  264. package/web/.next/server/chunks/ssr/src_presentation_web_e4510d10._.js +2 -3
  265. package/web/.next/server/chunks/ssr/src_presentation_web_e4510d10._.js.map +1 -1
  266. package/web/.next/server/pages/500.html +2 -2
  267. package/web/.next/server/server-reference-manifest.js +1 -1
  268. package/web/.next/server/server-reference-manifest.json +28 -28
  269. package/web/.next/static/chunks/1050da43c6e79e00.js +1 -0
  270. package/web/.next/static/chunks/30c827a88342741e.js +1 -0
  271. package/web/.next/static/chunks/52b56677c842e45f.js +3 -0
  272. package/web/.next/static/chunks/{34f6df8ccffe5d52.js → 73aa00cc7acb1da9.js} +1 -1
  273. package/web/.next/static/chunks/7b3bb6b4c06f0e57.js +1 -0
  274. package/web/.next/static/chunks/{2d4cc4000f402d7f.js → 80456b789ba11a6e.js} +3 -3
  275. package/web/.next/static/chunks/810e25b8cff2ff9c.js +1 -0
  276. package/web/.next/static/chunks/91d63f8e429f5900.css +2 -0
  277. package/web/.next/static/chunks/a9be2d1787818114.js +1 -0
  278. package/web/.next/static/chunks/{0fb7745c30469b39.js → b31f2c82654437a6.js} +1 -1
  279. package/web/.next/static/chunks/{996902d74a48276d.js → b465ec0865235136.js} +1 -1
  280. package/web/.next/static/chunks/b7f896ba72222351.js +1 -0
  281. package/web/.next/static/chunks/ba06677158538629.js +1 -0
  282. package/web/.next/static/chunks/{d1e04a49da8d02f9.js → bf47ef0853f7cd07.js} +1 -1
  283. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_c7cfe351._.js +0 -3
  284. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_c7cfe351._.js.map +0 -1
  285. package/web/.next/server/chunks/ssr/[root-of-the-server]__01a37f7a._.js +0 -3
  286. package/web/.next/server/chunks/ssr/[root-of-the-server]__55f60c9d._.js +0 -3
  287. package/web/.next/server/chunks/ssr/[root-of-the-server]__c3694f82._.js +0 -10
  288. package/web/.next/server/chunks/ssr/_1c1bf992._.js.map +0 -1
  289. package/web/.next/server/chunks/ssr/_1f7387a5._.js +0 -3
  290. package/web/.next/server/chunks/ssr/_1f7387a5._.js.map +0 -1
  291. package/web/.next/server/chunks/ssr/_51505c5a._.js +0 -3
  292. package/web/.next/server/chunks/ssr/_51505c5a._.js.map +0 -1
  293. package/web/.next/server/chunks/ssr/_c3a8bcb1._.js +0 -3
  294. package/web/.next/server/chunks/ssr/_c3a8bcb1._.js.map +0 -1
  295. package/web/.next/server/chunks/ssr/node_modules__pnpm_04f4e45f._.js +0 -5
  296. package/web/.next/server/chunks/ssr/node_modules__pnpm_04f4e45f._.js.map +0 -1
  297. package/web/.next/server/chunks/ssr/node_modules__pnpm_c931457d._.js +0 -3
  298. package/web/.next/server/chunks/ssr/node_modules__pnpm_c931457d._.js.map +0 -1
  299. package/web/.next/server/chunks/ssr/src_presentation_web_7efa14ca._.js +0 -3
  300. package/web/.next/server/chunks/ssr/src_presentation_web_7efa14ca._.js.map +0 -1
  301. package/web/.next/server/chunks/ssr/src_presentation_web_b59d79db._.js +0 -3
  302. package/web/.next/server/chunks/ssr/src_presentation_web_b59d79db._.js.map +0 -1
  303. package/web/.next/static/chunks/0543f7be533ecb32.js +0 -1
  304. package/web/.next/static/chunks/1e5cf3d452bf9f47.js +0 -1
  305. package/web/.next/static/chunks/2a24ac257fc1c10b.js +0 -1
  306. package/web/.next/static/chunks/6e77201e99d50131.js +0 -1
  307. package/web/.next/static/chunks/96bab6d3820504f3.css +0 -2
  308. package/web/.next/static/chunks/a453628f546647a7.js +0 -1
  309. package/web/.next/static/chunks/d9829b5681886395.js +0 -1
  310. package/web/.next/static/chunks/e405f0502431ea60.js +0 -3
  311. package/web/.next/static/chunks/ed0297ac085a1f85.js +0 -1
  312. /package/web/.next/server/chunks/{[root-of-the-server]__a6bf88cc._.js.map → [root-of-the-server]__332c8d91._.js.map} +0 -0
  313. /package/web/.next/server/chunks/{[root-of-the-server]__91d44424._.js.map → [root-of-the-server]__52c318d1._.js.map} +0 -0
  314. /package/web/.next/server/chunks/ssr/{[root-of-the-server]__3534949f._.js.map → [root-of-the-server]__8d9536c4._.js.map} +0 -0
  315. /package/web/.next/server/chunks/ssr/{[root-of-the-server]__ad2b2a3c._.js.map → [root-of-the-server]__f1a05100._.js.map} +0 -0
  316. /package/web/.next/static/{W2fL0P9VKhEH6f0RCcR8s → Ms9lFDwJuzxaSqweoKuIs}/_buildManifest.js +0 -0
  317. /package/web/.next/static/{W2fL0P9VKhEH6f0RCcR8s → Ms9lFDwJuzxaSqweoKuIs}/_clientMiddlewareManifest.json +0 -0
  318. /package/web/.next/static/{W2fL0P9VKhEH6f0RCcR8s → Ms9lFDwJuzxaSqweoKuIs}/_ssgManifest.js +0 -0
@@ -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, }) {
@@ -1 +1 @@
1
- {"version":3,"file":"plan-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/plan-tab.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAgB,MAAM,gCAAgC,CAAC;AAE7E,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAoBD,wBAAgB,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,YAAY,2CAgD7D"}
1
+ {"version":3,"file":"plan-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/plan-tab.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAE/D,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAQD,wBAAgB,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,YAAY,2CAgD7D"}
@@ -1,20 +1,14 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Loader2, Circle, Check, Eye } from 'lucide-react';
3
+ import { Loader2 } from 'lucide-react';
4
4
  import { AlertCircle, ListTodo } from 'lucide-react';
5
5
  import { Badge } from '../../ui/badge.js';
6
+ import { TaskProgressView } from '../../common/task-progress-view/index.js';
6
7
  const planStateBadgeStyles = {
7
8
  Requirements: 'border-transparent bg-blue-50 text-blue-700 hover:bg-blue-50',
8
9
  ClarificationRequired: 'border-transparent bg-amber-50 text-amber-700 hover:bg-amber-50',
9
10
  Ready: 'border-transparent bg-green-50 text-green-700 hover:bg-green-50',
10
11
  };
11
- const taskStateConfig = {
12
- Todo: { icon: Circle, colorClass: 'text-muted-foreground' },
13
- 'Work in Progress': { icon: Loader2, colorClass: 'text-blue-600', spinning: true },
14
- Done: { icon: Check, colorClass: 'text-emerald-600' },
15
- Review: { icon: Eye, colorClass: 'text-amber-600' },
16
- };
17
- const defaultTaskConfig = { icon: Circle, colorClass: 'text-muted-foreground' };
18
12
  export function PlanTab({ plan, loading, error }) {
19
13
  if (loading) {
20
14
  return (_jsx("div", { "data-testid": "plan-tab-loading", className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) }));
@@ -25,16 +19,5 @@ export function PlanTab({ plan, loading, error }) {
25
19
  if (!plan) {
26
20
  return (_jsxs("div", { className: "flex flex-col items-center justify-center gap-2 p-8", children: [_jsx(ListTodo, { className: "text-muted-foreground h-8 w-8" }), _jsx("p", { className: "text-muted-foreground text-sm", children: "No plan created yet" })] }));
27
21
  }
28
- return (_jsxs("div", { className: "flex flex-col gap-4 p-4", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Plan State" }), _jsx(Badge, { className: planStateBadgeStyles[plan.state] ?? 'border-transparent bg-gray-50 text-gray-700', children: plan.state })] }), plan.overview ? (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Overview" }), _jsx("p", { className: "text-sm leading-relaxed", children: plan.overview })] })) : null, _jsx(TaskList, { tasks: plan.tasks })] }));
29
- }
30
- function TaskList({ tasks }) {
31
- if (tasks.length === 0) {
32
- return (_jsx("div", { className: "flex flex-col items-center justify-center gap-2 py-4", children: _jsx("p", { className: "text-muted-foreground text-sm", children: "No tasks defined yet" }) }));
33
- }
34
- return (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Tasks" }), _jsx("div", { "data-testid": "plan-task-list", className: "flex flex-col gap-2", children: tasks.map((task, index) => (_jsx(TaskItem, { task: task, index: index }, task.title || `task-${index}`))) })] }));
35
- }
36
- function TaskItem({ task, index }) {
37
- const config = taskStateConfig[task.state] ?? defaultTaskConfig;
38
- const Icon = config.icon;
39
- return (_jsxs("div", { "data-testid": `plan-task-${index}`, className: `flex items-start gap-2 rounded-md border px-3 py-2 ${config.colorClass}`, children: [_jsx(Icon, { className: `mt-0.5 h-4 w-4 shrink-0 ${config.spinning ? 'animate-spin' : ''}` }), _jsxs("div", { className: "flex min-w-0 flex-col gap-0.5", children: [_jsx("span", { className: "text-sm font-medium", children: task.title }), task.description ? (_jsx("span", { className: "text-muted-foreground text-xs", children: task.description })) : null] })] }));
22
+ return (_jsxs("div", { className: "flex flex-col gap-4 p-4", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Plan State" }), _jsx(Badge, { className: planStateBadgeStyles[plan.state] ?? 'border-transparent bg-gray-50 text-gray-700', children: plan.state })] }), plan.overview ? (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Overview" }), _jsx("p", { className: "text-sm leading-relaxed", children: plan.overview })] })) : null, _jsx(TaskProgressView, { tasks: plan.tasks })] }));
40
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plan-tab.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/plan-tab.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGrC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,OAAO,CAc9B,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,OAAO,CAAC,CAAC;AA0HtC,6EAA6E;AAC7E,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,2BAA2B;AAC3B,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF,wCAAwC;AACxC,eAAO,MAAM,SAAS,EAAE,KAMvB,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,EAAE,KAMnC,CAAC;AAEF,mDAAmD;AACnD,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,yCAAyC;AACzC,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC"}
1
+ {"version":3,"file":"plan-tab.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/plan-tab.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGrC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,OAAO,CAc9B,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,OAAO,CAAC,CAAC;AAoMtC,6EAA6E;AAC7E,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,2BAA2B;AAC3B,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF,wCAAwC;AACxC,eAAO,MAAM,SAAS,EAAE,KAMvB,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,EAAE,KAMnC,CAAC;AAEF,mDAAmD;AACnD,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,yCAAyC;AACzC,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC"}
@@ -23,31 +23,96 @@ const mixedTasksPlan = {
23
23
  title: 'Set up OAuth provider configuration',
24
24
  description: 'Configure Google and GitHub OAuth apps with client IDs and secrets',
25
25
  state: 'Done',
26
+ actionItems: [
27
+ {
28
+ name: 'Create OAuth config module',
29
+ description: 'Define provider configuration schema and load from env',
30
+ acceptanceCriteria: [
31
+ { description: 'Config loads from environment variables', verified: true },
32
+ { description: 'Validation rejects missing client ID or secret', verified: true },
33
+ ],
34
+ },
35
+ {
36
+ name: 'Register OAuth apps',
37
+ description: 'Register apps with Google and GitHub developer consoles',
38
+ acceptanceCriteria: [
39
+ { description: 'Google OAuth app created with correct scopes', verified: true },
40
+ { description: 'GitHub OAuth app created with correct callback URL', verified: true },
41
+ ],
42
+ },
43
+ ],
26
44
  },
27
45
  {
28
46
  title: 'Implement callback handler',
29
47
  description: 'Handle OAuth callback with authorization code exchange',
30
48
  state: 'Done',
49
+ actionItems: [
50
+ {
51
+ name: 'Build callback endpoint',
52
+ description: 'GET /auth/callback with code exchange logic',
53
+ acceptanceCriteria: [
54
+ { description: 'Exchanges authorization code for tokens', verified: true },
55
+ ],
56
+ },
57
+ ],
31
58
  },
32
59
  {
33
60
  title: 'Add token refresh logic',
34
61
  description: 'Implement silent token refresh using refresh tokens stored in httpOnly cookies',
35
62
  state: 'Work in Progress',
63
+ actionItems: [
64
+ {
65
+ name: 'Implement refresh endpoint',
66
+ description: 'POST /auth/refresh to issue new access token',
67
+ acceptanceCriteria: [
68
+ { description: 'Returns new access token when refresh token is valid', verified: true },
69
+ { description: 'Returns 401 when refresh token is expired', verified: false },
70
+ ],
71
+ },
72
+ {
73
+ name: 'Add httpOnly cookie handling',
74
+ description: 'Store refresh tokens in secure httpOnly cookies',
75
+ acceptanceCriteria: [
76
+ { description: 'Cookies are set with Secure and HttpOnly flags', verified: false },
77
+ ],
78
+ },
79
+ ],
36
80
  },
37
81
  {
38
82
  title: 'Create user profile sync',
39
83
  description: 'Sync user profile data from identity providers on login',
40
84
  state: 'Todo',
85
+ actionItems: [
86
+ {
87
+ name: 'Fetch profile from provider',
88
+ description: 'Use access token to retrieve user profile from Google/GitHub',
89
+ acceptanceCriteria: [
90
+ { description: 'Retrieves name, email, and avatar from Google', verified: false },
91
+ { description: 'Retrieves name, email, and avatar from GitHub', verified: false },
92
+ ],
93
+ },
94
+ ],
41
95
  },
42
96
  {
43
97
  title: 'Write integration tests',
44
98
  description: 'Test the full OAuth flow with mocked providers',
45
99
  state: 'Todo',
100
+ actionItems: [],
46
101
  },
47
102
  {
48
103
  title: 'Update API documentation',
49
104
  description: 'Document new authentication endpoints and flows',
50
105
  state: 'Review',
106
+ actionItems: [
107
+ {
108
+ name: 'Document auth endpoints',
109
+ description: 'Add OpenAPI specs for all auth routes',
110
+ acceptanceCriteria: [
111
+ { description: 'All endpoints have OpenAPI documentation', verified: true },
112
+ { description: 'Examples included for each endpoint', verified: true },
113
+ ],
114
+ },
115
+ ],
51
116
  },
52
117
  ],
53
118
  };
@@ -59,21 +124,25 @@ const allDonePlan = {
59
124
  title: 'Design sliding window algorithm',
60
125
  description: 'Implement Redis-backed sliding window counter',
61
126
  state: 'Done',
127
+ actionItems: [],
62
128
  },
63
129
  {
64
130
  title: 'Add rate limit middleware',
65
131
  description: 'Express middleware that checks rate limits per IP',
66
132
  state: 'Done',
133
+ actionItems: [],
67
134
  },
68
135
  {
69
136
  title: 'Configure limits per endpoint',
70
137
  description: 'Set different rate limits for public vs authenticated endpoints',
71
138
  state: 'Done',
139
+ actionItems: [],
72
140
  },
73
141
  {
74
142
  title: 'Add rate limit headers',
75
143
  description: 'Include X-RateLimit-* headers in responses',
76
144
  state: 'Done',
145
+ actionItems: [],
77
146
  },
78
147
  ],
79
148
  };
@@ -85,16 +154,19 @@ const draftPlan = {
85
154
  title: 'Define notification types',
86
155
  description: 'Enumerate all notification events and their payloads',
87
156
  state: 'Todo',
157
+ actionItems: [],
88
158
  },
89
159
  {
90
160
  title: 'Set up WebSocket server',
91
161
  description: 'Configure Socket.io with Redis adapter for horizontal scaling',
92
162
  state: 'Todo',
163
+ actionItems: [],
93
164
  },
94
165
  {
95
166
  title: 'Implement notification store',
96
167
  description: 'Persist notifications in database with read/unread tracking',
97
168
  state: 'Todo',
169
+ actionItems: [],
98
170
  },
99
171
  ],
100
172
  };
@@ -106,11 +178,13 @@ const clarificationPlan = {
106
178
  title: 'Set up email provider',
107
179
  description: 'Configure SendGrid API integration',
108
180
  state: 'Done',
181
+ actionItems: [],
109
182
  },
110
183
  {
111
184
  title: 'Create template engine',
112
185
  description: 'Implement Handlebars-based email template rendering',
113
186
  state: 'Todo',
187
+ actionItems: [],
114
188
  },
115
189
  ],
116
190
  };
@@ -0,0 +1,3 @@
1
+ export { TaskProgressView } from './task-progress-view.js';
2
+ export type { TaskProgressViewProps } from './task-progress-view.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/task-progress-view/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1 @@
1
+ export { TaskProgressView } from './task-progress-view.js';
@@ -0,0 +1,6 @@
1
+ import type { PlanTaskData } from '../../../app/actions/get-feature-plan.js';
2
+ export interface TaskProgressViewProps {
3
+ tasks: PlanTaskData[];
4
+ }
5
+ export declare function TaskProgressView({ tasks }: TaskProgressViewProps): import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=task-progress-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-progress-view.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/task-progress-view/task-progress-view.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,gCAAgC,CAAC;AAEnF,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AA8CD,wBAAgB,gBAAgB,CAAC,EAAE,KAAK,EAAE,EAAE,qBAAqB,2CAmBhE"}
@@ -0,0 +1,84 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState, useCallback, useMemo } from 'react';
4
+ import { Loader2, Circle, Check, Eye, ChevronRight, CheckCircle2, CircleDashed, } from 'lucide-react';
5
+ import { cn } from '../../../lib/utils.js';
6
+ const taskStateConfig = {
7
+ Todo: {
8
+ icon: Circle,
9
+ colorClass: 'text-muted-foreground',
10
+ borderClass: 'border-border',
11
+ label: 'Todo',
12
+ },
13
+ 'Work in Progress': {
14
+ icon: Loader2,
15
+ colorClass: 'text-blue-600',
16
+ borderClass: 'border-blue-200',
17
+ spinning: true,
18
+ label: 'In Progress',
19
+ },
20
+ Done: {
21
+ icon: Check,
22
+ colorClass: 'text-emerald-600',
23
+ borderClass: 'border-emerald-200',
24
+ label: 'Done',
25
+ },
26
+ Review: {
27
+ icon: Eye,
28
+ colorClass: 'text-amber-600',
29
+ borderClass: 'border-amber-200',
30
+ label: 'Review',
31
+ },
32
+ };
33
+ const defaultTaskConfig = {
34
+ icon: Circle,
35
+ colorClass: 'text-muted-foreground',
36
+ borderClass: 'border-border',
37
+ label: 'Unknown',
38
+ };
39
+ export function TaskProgressView({ tasks }) {
40
+ if (tasks.length === 0) {
41
+ return (_jsx("div", { className: "flex flex-col items-center justify-center gap-2 py-4", children: _jsx("p", { className: "text-muted-foreground text-sm", children: "No tasks defined yet" }) }));
42
+ }
43
+ return (_jsxs("div", { "data-testid": "task-progress-view", className: "flex flex-col gap-3", children: [_jsx(ProgressSummary, { tasks: tasks }), _jsx("div", { "data-testid": "task-progress-list", className: "flex flex-col gap-2", children: tasks.map((task, index) => (_jsx(TaskCard, { task: task, index: index }, task.title || `task-${index}`))) })] }));
44
+ }
45
+ // ── Progress Summary ─────────────────────────────────────────────────
46
+ function ProgressSummary({ tasks }) {
47
+ const counts = useMemo(() => {
48
+ const done = tasks.filter((t) => t.state === 'Done').length;
49
+ const wip = tasks.filter((t) => t.state === 'Work in Progress').length;
50
+ const review = tasks.filter((t) => t.state === 'Review').length;
51
+ const todo = tasks.filter((t) => t.state !== 'Done' && t.state !== 'Work in Progress' && t.state !== 'Review').length;
52
+ const total = tasks.length;
53
+ const percent = total > 0 ? Math.round((done / total) * 100) : 0;
54
+ return { done, wip, review, todo, total, percent };
55
+ }, [tasks]);
56
+ return (_jsxs("div", { "data-testid": "task-progress-summary", className: "flex flex-col gap-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Task Progress" }), _jsxs("span", { className: "text-muted-foreground text-xs", children: [counts.done, " of ", counts.total, " done"] })] }), _jsx("div", { className: "bg-muted h-2 w-full overflow-hidden rounded-full", children: _jsx("div", { "data-testid": "task-progress-bar", className: "h-full rounded-full bg-emerald-500 transition-all", style: { width: `${counts.percent}%` } }) }), _jsxs("div", { className: "flex flex-wrap gap-3", children: [counts.done > 0 ? (_jsx(StatChip, { icon: Check, label: "Done", count: counts.done, className: "text-emerald-600" })) : null, counts.wip > 0 ? (_jsx(StatChip, { icon: Loader2, label: "In Progress", count: counts.wip, className: "text-blue-600" })) : null, counts.review > 0 ? (_jsx(StatChip, { icon: Eye, label: "Review", count: counts.review, className: "text-amber-600" })) : null, counts.todo > 0 ? (_jsx(StatChip, { icon: Circle, label: "Todo", count: counts.todo, className: "text-muted-foreground" })) : null] })] }));
57
+ }
58
+ function StatChip({ icon: Icon, label, count, className, }) {
59
+ return (_jsxs("span", { className: cn('flex items-center gap-1 text-xs', className), children: [_jsx(Icon, { className: "h-3 w-3" }), count, " ", label] }));
60
+ }
61
+ // ── Task Card ────────────────────────────────────────────────────────
62
+ function TaskCard({ task, index }) {
63
+ const [expanded, setExpanded] = useState(false);
64
+ const config = taskStateConfig[task.state] ?? defaultTaskConfig;
65
+ const Icon = config.icon;
66
+ const hasDetails = task.actionItems.length > 0;
67
+ const handleToggle = useCallback(() => {
68
+ if (hasDetails) {
69
+ setExpanded((prev) => !prev);
70
+ }
71
+ }, [hasDetails]);
72
+ return (_jsxs("div", { "data-testid": `task-card-${index}`, className: cn('rounded-lg border', config.borderClass), children: [_jsxs("button", { type: "button", onClick: handleToggle, disabled: !hasDetails, className: cn('flex w-full items-start gap-2 px-3 py-2.5 text-left', hasDetails && 'hover:bg-muted/50 cursor-pointer transition-colors'), children: [_jsx(Icon, { className: cn('mt-0.5 h-4 w-4 shrink-0', config.colorClass, config.spinning && 'animate-spin') }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [_jsx("span", { className: cn('text-sm font-medium', config.colorClass), children: task.title }), task.description ? (_jsx("span", { className: "text-muted-foreground text-xs", children: task.description })) : null] }), hasDetails ? (_jsx(ChevronRight, { className: cn('text-muted-foreground mt-0.5 h-4 w-4 shrink-0 transition-transform', expanded && 'rotate-90') })) : null] }), expanded && hasDetails ? (_jsx("div", { className: "border-t px-3 py-2.5", children: _jsx("div", { className: "flex flex-col gap-2", children: task.actionItems.map((item, aiIndex) => (_jsx(ActionItemRow, { item: item }, item.name || `ai-${aiIndex}`))) }) })) : null] }));
73
+ }
74
+ // ── Action Item Row ──────────────────────────────────────────────────
75
+ function ActionItemRow({ item }) {
76
+ const totalCriteria = item.acceptanceCriteria.length;
77
+ const verifiedCriteria = item.acceptanceCriteria.filter((ac) => ac.verified).length;
78
+ const allVerified = totalCriteria > 0 && verifiedCriteria === totalCriteria;
79
+ return (_jsxs("div", { "data-testid": "action-item", className: "flex flex-col gap-1.5", children: [_jsxs("div", { className: "flex items-start gap-2", children: [allVerified ? (_jsx(CheckCircle2, { className: "mt-0.5 h-3.5 w-3.5 shrink-0 text-emerald-600" })) : (_jsx(CircleDashed, { className: "text-muted-foreground mt-0.5 h-3.5 w-3.5 shrink-0" })), _jsxs("div", { className: "flex min-w-0 flex-col gap-0.5", children: [_jsx("span", { className: "text-xs font-medium", children: item.name }), item.description ? (_jsx("span", { className: "text-muted-foreground text-[11px]", children: item.description })) : null] }), totalCriteria > 0 ? (_jsxs("span", { className: "text-muted-foreground ml-auto shrink-0 text-[11px]", children: [verifiedCriteria, "/", totalCriteria] })) : null] }), totalCriteria > 0 ? (_jsx("div", { className: "ml-5.5 flex flex-col gap-1", children: item.acceptanceCriteria.map((ac, acIndex) => (_jsx(AcceptanceCriterionRow, { criterion: ac }, ac.description || `ac-${acIndex}`))) })) : null] }));
80
+ }
81
+ // ── Acceptance Criterion Row ─────────────────────────────────────────
82
+ function AcceptanceCriterionRow({ criterion, }) {
83
+ return (_jsxs("div", { "data-testid": "acceptance-criterion", className: "flex items-start gap-1.5", children: [criterion.verified ? (_jsx(Check, { className: "mt-0.5 h-3 w-3 shrink-0 text-emerald-600" })) : (_jsx(Circle, { className: "text-muted-foreground mt-0.5 h-3 w-3 shrink-0" })), _jsx("span", { className: cn('text-[11px]', criterion.verified ? 'text-muted-foreground line-through' : 'text-foreground'), children: criterion.description })] }));
84
+ }
@@ -0,0 +1,16 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { TaskProgressView } from './task-progress-view.js';
3
+ declare const meta: Meta<typeof TaskProgressView>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof TaskProgressView>;
6
+ /** Default — tasks in mixed states with action items and acceptance criteria. */
7
+ export declare const Default: Story;
8
+ /** All tasks completed. */
9
+ export declare const AllDone: Story;
10
+ /** All tasks in Todo state. */
11
+ export declare const AllTodo: Story;
12
+ /** Empty — no tasks defined. */
13
+ export declare const Empty: Story;
14
+ /** Single task with detailed action items. */
15
+ export declare const SingleTaskDetailed: Story;
16
+ //# sourceMappingURL=task-progress-view.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-progress-view.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/task-progress-view/task-progress-view.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGxD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,gBAAgB,CAYvC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,gBAAgB,CAAC,CAAC;AA+J/C,iFAAiF;AACjF,eAAO,MAAM,OAAO,EAAE,KAIrB,CAAC;AAEF,2BAA2B;AAC3B,eAAO,MAAM,OAAO,EAAE,KAIrB,CAAC;AAEF,+BAA+B;AAC/B,eAAO,MAAM,OAAO,EAAE,KAIrB,CAAC;AAEF,gCAAgC;AAChC,eAAO,MAAM,KAAK,EAAE,KAInB,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,kBAAkB,EAAE,KAIhC,CAAC"}