@shepai/cli 1.127.2 → 1.127.3-pr400.67a8317

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 (157) hide show
  1. package/dist/eslint.config.mjs +6 -0
  2. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
  3. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +18 -0
  4. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.d.ts.map +1 -1
  5. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.js +2 -1
  6. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-running-controls.d.ts +12 -0
  7. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-running-controls.d.ts.map +1 -0
  8. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-running-controls.js +19 -0
  9. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-running-controls.stories.d.ts +26 -0
  10. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-running-controls.stories.d.ts.map +1 -0
  11. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-running-controls.stories.js +91 -0
  12. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.d.ts.map +1 -1
  13. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.js +3 -9
  14. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts +0 -4
  15. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts.map +1 -1
  16. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.js +0 -13
  17. package/dist/tsconfig.build.tsbuildinfo +1 -1
  18. package/package.json +5 -5
  19. package/web/.next/BUILD_ID +1 -1
  20. package/web/.next/build-manifest.json +2 -2
  21. package/web/.next/fallback-build-manifest.json +2 -2
  22. package/web/.next/prerender-manifest.json +3 -3
  23. package/web/.next/required-server-files.js +3 -3
  24. package/web/.next/required-server-files.json +3 -3
  25. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +22 -22
  26. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  27. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  28. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +22 -22
  29. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  30. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  31. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
  32. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  33. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  34. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +28 -28
  35. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  36. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  37. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
  38. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  39. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  40. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +22 -22
  41. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  42. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  43. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
  44. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  45. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  46. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +28 -28
  47. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  48. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  49. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +20 -20
  50. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  51. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  52. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
  53. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  54. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  55. package/web/.next/server/app/_global-error.html +2 -2
  56. package/web/.next/server/app/_global-error.rsc +1 -1
  57. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  58. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  59. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  60. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  61. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  62. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  63. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  64. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  65. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  66. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  67. package/web/.next/server/app/settings/page/server-reference-manifest.json +6 -6
  68. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  69. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  70. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  71. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  72. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  73. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  74. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  75. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  76. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  77. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  78. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  79. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_fbb88113.js +1 -1
  80. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_fbb88113.js.map +1 -1
  81. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  82. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  83. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_fdfbf5cc.js +1 -1
  84. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_fdfbf5cc.js.map +1 -1
  85. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_d8fa0b5f.js +1 -1
  86. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_d8fa0b5f.js.map +1 -1
  87. package/web/.next/server/chunks/ssr/[root-of-the-server]__02c84e6b._.js +1 -1
  88. package/web/.next/server/chunks/ssr/[root-of-the-server]__02c84e6b._.js.map +1 -1
  89. package/web/.next/server/chunks/ssr/[root-of-the-server]__06fef644._.js +1 -1
  90. package/web/.next/server/chunks/ssr/[root-of-the-server]__1aa034e9._.js +1 -1
  91. package/web/.next/server/chunks/ssr/[root-of-the-server]__1aa034e9._.js.map +1 -1
  92. package/web/.next/server/chunks/ssr/[root-of-the-server]__357de47c._.js +2 -2
  93. package/web/.next/server/chunks/ssr/[root-of-the-server]__357de47c._.js.map +1 -1
  94. package/web/.next/server/chunks/ssr/[root-of-the-server]__430169b6._.js +1 -1
  95. package/web/.next/server/chunks/ssr/[root-of-the-server]__430169b6._.js.map +1 -1
  96. package/web/.next/server/chunks/ssr/[root-of-the-server]__67fe07fe._.js +1 -1
  97. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  98. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  99. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +2 -2
  100. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js.map +1 -1
  101. package/web/.next/server/chunks/ssr/[root-of-the-server]__6cc70784._.js +1 -1
  102. package/web/.next/server/chunks/ssr/[root-of-the-server]__6cc70784._.js.map +1 -1
  103. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  104. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  105. package/web/.next/server/chunks/ssr/[root-of-the-server]__8c553503._.js +2 -2
  106. package/web/.next/server/chunks/ssr/[root-of-the-server]__a50a7e39._.js +2 -2
  107. package/web/.next/server/chunks/ssr/[root-of-the-server]__a50a7e39._.js.map +1 -1
  108. package/web/.next/server/chunks/ssr/[root-of-the-server]__e44ae5ca._.js +1 -1
  109. package/web/.next/server/chunks/ssr/[root-of-the-server]__e44ae5ca._.js.map +1 -1
  110. package/web/.next/server/chunks/ssr/{_05224854._.js → _0c916cd8._.js} +2 -2
  111. package/web/.next/server/chunks/ssr/_0c916cd8._.js.map +1 -0
  112. package/web/.next/server/chunks/ssr/_2f6f48b8._.js +1 -1
  113. package/web/.next/server/chunks/ssr/_2f6f48b8._.js.map +1 -1
  114. package/web/.next/server/chunks/ssr/_7dca1882._.js +1 -1
  115. package/web/.next/server/chunks/ssr/_7dca1882._.js.map +1 -1
  116. package/web/.next/server/chunks/ssr/_832c379b._.js +3 -0
  117. package/web/.next/server/chunks/ssr/{_9a47da6a._.js.map → _832c379b._.js.map} +1 -1
  118. package/web/.next/server/chunks/ssr/_a187fd7e._.js +1 -1
  119. package/web/.next/server/chunks/ssr/_a187fd7e._.js.map +1 -1
  120. package/web/.next/server/chunks/ssr/_a9f57758._.js +1 -1
  121. package/web/.next/server/chunks/ssr/_f39a1adb._.js +1 -1
  122. package/web/.next/server/chunks/ssr/_f39a1adb._.js.map +1 -1
  123. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  124. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  125. package/web/.next/server/chunks/ssr/{src_presentation_web_4615d5dc._.js → src_presentation_web_5914be6c._.js} +2 -2
  126. package/web/.next/server/chunks/ssr/{src_presentation_web_4615d5dc._.js.map → src_presentation_web_5914be6c._.js.map} +1 -1
  127. package/web/.next/server/chunks/ssr/src_presentation_web_9db47db7._.js +2 -2
  128. package/web/.next/server/chunks/ssr/src_presentation_web_9db47db7._.js.map +1 -1
  129. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f66cd328.js +1 -1
  130. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f66cd328.js.map +1 -1
  131. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  132. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  133. package/web/.next/server/chunks/ssr/src_presentation_web_ede4a227._.js +2 -2
  134. package/web/.next/server/chunks/ssr/src_presentation_web_ede4a227._.js.map +1 -1
  135. package/web/.next/server/pages/500.html +2 -2
  136. package/web/.next/server/server-reference-manifest.js +1 -1
  137. package/web/.next/server/server-reference-manifest.json +36 -36
  138. package/web/.next/static/chunks/10f102e4f3d30fab.js +1 -0
  139. package/web/.next/static/chunks/{b47d1e9ee5b1cfe4.js → 4265877011a68ce0.js} +1 -1
  140. package/web/.next/static/chunks/{dcecfc2d9d42d3e1.js → 53941e038c6b975c.js} +1 -1
  141. package/web/.next/static/chunks/722c4b021a197a84.js +2 -0
  142. package/web/.next/static/chunks/{109d73bb8ce910dd.js → 736d94180ff7f37d.js} +1 -1
  143. package/web/.next/static/chunks/{1d48cab5a6019a28.js → 78d9c944f56f22b4.js} +1 -1
  144. package/web/.next/static/chunks/{4ec46af89bb95b8e.js → a0f0cb1ede328514.js} +1 -1
  145. package/web/.next/static/chunks/{e13a052cf2de8e1e.js → a5804ae1a0c23932.js} +1 -1
  146. package/web/.next/static/chunks/{c3be10b1621a5852.js → a835d31cfedb9077.js} +1 -1
  147. package/web/.next/static/chunks/{32a1b8aa0e573f7b.js → ad3b1560b2612b59.js} +1 -1
  148. package/web/.next/static/chunks/{c3ef52ecf289d138.js → afa4210db783bc6f.js} +1 -1
  149. package/web/.next/static/chunks/f7d4ca49260314fb.css +1 -0
  150. package/web/.next/server/chunks/ssr/_05224854._.js.map +0 -1
  151. package/web/.next/server/chunks/ssr/_9a47da6a._.js +0 -3
  152. package/web/.next/static/chunks/33d2f67ad4814aba.css +0 -1
  153. package/web/.next/static/chunks/46e964a7fbd14bc8.js +0 -1
  154. package/web/.next/static/chunks/df19575c149c6e75.js +0 -2
  155. /package/web/.next/static/{xJdz7CiaX6txLXXW3TSS7 → SUd6bpgXghiSZx_3nWE4Y}/_buildManifest.js +0 -0
  156. /package/web/.next/static/{xJdz7CiaX6txLXXW3TSS7 → SUd6bpgXghiSZx_3nWE4Y}/_clientMiddlewareManifest.json +0 -0
  157. /package/web/.next/static/{xJdz7CiaX6txLXXW3TSS7 → SUd6bpgXghiSZx_3nWE4Y}/_ssgManifest.js +0 -0
@@ -43,8 +43,14 @@ export default tseslint.config(
43
43
  'next-env.d.ts',
44
44
  'src/domain/generated/**', // TypeSpec-generated domain models
45
45
  'packages/core/src/domain/generated/**', // TypeSpec-generated domain models (core)
46
+ // Spec artifacts (auto-generated YAML/MD, evidence PNGs)
47
+ 'specs/**',
48
+ // Claude Code skills (third-party)
49
+ '.claude/skills/**',
46
50
  // TypeSpec (handled by tsp linter)
47
51
  'tsp/**',
52
+ // Spec YAML files (not JS/TS, handled by spec tooling)
53
+ 'specs/**',
48
54
  // Test outputs
49
55
  'test-results/**',
50
56
  'playwright-report/**',
@@ -1 +1 @@
1
- {"version":3,"file":"feature-drawer-client.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAI/D,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,UAAU,CAAC;IACjB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,wBAAgB,mBAAmB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,wBAAwB,2CAqkB1F"}
1
+ {"version":3,"file":"feature-drawer-client.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAI/D,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,UAAU,CAAC;IACjB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,wBAAgB,mBAAmB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,wBAAwB,2CAslB1F"}
@@ -7,6 +7,7 @@ import { Loader2, Trash2, Play, Square, Copy, Check, Code2, ExternalLink } from
7
7
  import { approveFeature } from '../../../app/actions/approve-feature.js';
8
8
  import { resumeFeature } from '../../../app/actions/resume-feature.js';
9
9
  import { startFeature } from '../../../app/actions/start-feature.js';
10
+ import { stopFeature } from '../../../app/actions/stop-feature.js';
10
11
  import { rejectFeature } from '../../../app/actions/reject-feature.js';
11
12
  import { getFeatureArtifact } from '../../../app/actions/get-feature-artifact.js';
12
13
  import { getResearchArtifact } from '../../../app/actions/get-research-artifact.js';
@@ -300,6 +301,20 @@ export function FeatureDrawerClient({ view: initialView, urlTab }) {
300
301
  return { ...prev, node: { ...prev.node, state: 'running' } };
301
302
  });
302
303
  }, []);
304
+ const handleStop = useCallback(async (featureId) => {
305
+ const result = await stopFeature(featureId);
306
+ if (result.error) {
307
+ toast.error(result.error);
308
+ return;
309
+ }
310
+ toast.success('Feature stopped');
311
+ // Optimistically update the drawer view — agent run will be interrupted
312
+ setView((prev) => {
313
+ if (prev.type !== 'feature')
314
+ return prev;
315
+ return { ...prev, node: { ...prev.node, state: 'error' } };
316
+ });
317
+ }, []);
303
318
  // ── Hooks (always called unconditionally per Rules of Hooks) ──────────
304
319
  const featureActionsInput = featureNode?.repositoryPath && featureNode?.branch
305
320
  ? {
@@ -345,6 +360,9 @@ export function FeatureDrawerClient({ view: initialView, urlTab }) {
345
360
  ...featureNode,
346
361
  ...(featureNode.state === 'error' && { onRetry: handleRetry }),
347
362
  ...(featureNode.state === 'pending' && { onStart: handleStart }),
363
+ ...((featureNode.state === 'running' || featureNode.state === 'action-required') && {
364
+ onStop: handleStop,
365
+ }),
348
366
  };
349
367
  body = (_jsx(FeatureDrawerTabs, { featureNode: enrichedNode, featureId: featureNode.featureId, initialTab: view.initialTab, urlTab: urlTab, sseEvents: events, prdData: prdData, prdSelections: prdSelections, onPrdSelect: (qId, oId) => setPrdSelections((prev) => ({ ...prev, [qId]: oId })), onPrdApprove: handlePrdApprove, onPrdReject: handlePrdReject, isPrdLoading: isLoadingPrd, techData: techData, onTechApprove: handleTechApprove, onTechReject: handleTechReject, isTechLoading: isLoadingTech, productData: isLoadingTechProduct ? null : techProductData, mergeData: mergeData, onMergeApprove: handleMergeApprove, onMergeReject: handleMergeReject, isMergeLoading: isLoadingMerge, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: setChatInput }));
350
368
  }
@@ -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":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAS9E,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;AAMxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAQ9E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uDAAuD,CAAC;AAkD3F,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,eAAe,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,gFAAgF;IAChF,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,mFAAmF;IACnF,SAAS,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAGzC,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,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC1E,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,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC3E,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,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC5E,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,MAAM,EACN,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,EACjB,SAAS,GACV,EAAE,sBAAsB,2CA8UxB"}
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":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAS9E,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;AAMxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAS9E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uDAAuD,CAAC;AAkD3F,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,eAAe,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,gFAAgF;IAChF,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,mFAAmF;IACnF,SAAS,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAGzC,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,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC1E,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,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC3E,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,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC5E,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,MAAM,EACN,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,EACjB,SAAS,GACV,EAAE,sBAAsB,2CAgVxB"}
@@ -15,6 +15,7 @@ import { OverviewTab } from './overview-tab.js';
15
15
  import { ActivityTab } from './activity-tab.js';
16
16
  import { LogTab } from './log-tab.js';
17
17
  import { PlanTab } from './plan-tab.js';
18
+ import { FeatureRunningControls } from './feature-running-controls.js';
18
19
  import { useFeatureLogs } from '../../../hooks/use-feature-logs.js';
19
20
  import { useTabDataFetch } from './use-tab-data-fetch.js';
20
21
  /** All possible tabs in display order. */
@@ -244,7 +245,7 @@ export function FeatureDrawerTabs({ featureNode, featureId, initialTab, urlTab,
244
245
  fetchTab(tab);
245
246
  }
246
247
  }, [fetchTab]);
247
- 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, readOnly: featureNode.lifecycle === 'maintain', 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] }) }));
248
+ return (_jsxs("div", { className: "flex min-h-0 flex-1 flex-col", children: [_jsx(FeatureRunningControls, { data: featureNode }), _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, readOnly: featureNode.lifecycle === 'maintain', 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] })] }));
248
249
  }
249
250
  // ── Private helper ──────────────────────────────────────────────────────
250
251
  function DrawerActionBarForTech({ onApprove, onReject, isProcessing, isRejecting, chatInput, onChatInputChange, }) {
@@ -0,0 +1,12 @@
1
+ import type { FeatureNodeData } from '../../common/feature-node/index.js';
2
+ interface FeatureRunningControlsProps {
3
+ data: FeatureNodeData;
4
+ }
5
+ /**
6
+ * Controls bar rendered above all feature drawer tabs.
7
+ * Shows the lifecycle phase label, current state badge, and context-appropriate
8
+ * action buttons (Stop, Retry, Start) regardless of which tab is active.
9
+ */
10
+ export declare function FeatureRunningControls({ data }: FeatureRunningControlsProps): import("react/jsx-runtime").JSX.Element;
11
+ export {};
12
+ //# sourceMappingURL=feature-running-controls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-running-controls.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/feature-running-controls.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAExE,UAAU,2BAA2B;IACnC,IAAI,EAAE,eAAe,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,IAAI,EAAE,EAAE,2BAA2B,2CAuE3E"}
@@ -0,0 +1,19 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { RotateCcw, Square, Play } from 'lucide-react';
4
+ import { cn } from '../../../lib/utils.js';
5
+ import { CometSpinner } from '../../ui/comet-spinner.js';
6
+ import { featureNodeStateConfig, lifecycleDisplayLabels } from '../../common/feature-node/index.js';
7
+ /**
8
+ * Controls bar rendered above all feature drawer tabs.
9
+ * Shows the lifecycle phase label, current state badge, and context-appropriate
10
+ * action buttons (Stop, Retry, Start) regardless of which tab is active.
11
+ */
12
+ export function FeatureRunningControls({ data }) {
13
+ const config = featureNodeStateConfig[data.state];
14
+ const Icon = config.icon;
15
+ const isRunning = data.state === 'running' || data.state === 'action-required';
16
+ const isError = data.state === 'error';
17
+ const isPending = data.state === 'pending';
18
+ return (_jsxs("div", { "data-testid": "feature-drawer-controls", className: "flex shrink-0 items-center gap-2 border-b px-4 py-2.5", children: [_jsx("span", { className: "text-muted-foreground min-w-0 flex-1 truncate text-xs font-semibold tracking-widest uppercase", children: lifecycleDisplayLabels[data.lifecycle] }), _jsxs("div", { "data-testid": "feature-drawer-state-badge", className: cn('flex shrink-0 items-center gap-1.5 rounded-full px-2.5 py-1 text-xs font-medium', config.badgeBgClass, config.badgeClass), children: [data.state === 'running' ? (_jsx(CometSpinner, { size: "sm", className: "shrink-0" })) : (_jsx(Icon, { className: "h-3.5 w-3.5 shrink-0" })), _jsx("span", { children: config.label })] }), isRunning && data.onStop ? (_jsxs("button", { "data-testid": "feature-drawer-stop-button", onClick: () => data.onStop(data.featureId), className: "flex shrink-0 cursor-pointer items-center gap-1.5 rounded-full bg-red-50 px-3 py-1.5 text-xs font-medium text-red-700 transition-colors hover:bg-red-100", children: [_jsx(Square, { className: "h-3.5 w-3.5 fill-red-700" }), "Stop"] })) : null, isError && data.onRetry ? (_jsxs("button", { "data-testid": "feature-drawer-retry-button", onClick: () => data.onRetry(data.featureId), className: "flex shrink-0 cursor-pointer items-center gap-1.5 rounded-full bg-amber-50 px-3 py-1.5 text-xs font-medium text-amber-700 transition-colors hover:bg-amber-100", children: [_jsx(RotateCcw, { className: "h-3.5 w-3.5" }), "Retry"] })) : null, isPending && data.onStart ? (_jsxs("button", { "data-testid": "feature-drawer-start-button", onClick: () => data.onStart(data.featureId), className: "flex shrink-0 cursor-pointer items-center gap-1.5 rounded-full bg-emerald-50 px-3 py-1.5 text-xs font-medium text-emerald-700 transition-colors hover:bg-emerald-100", children: [_jsx(Play, { className: "h-3.5 w-3.5 fill-emerald-700" }), "Start"] })) : null] }));
19
+ }
@@ -0,0 +1,26 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { FeatureRunningControls } from './feature-running-controls.js';
3
+ declare const meta: Meta<typeof FeatureRunningControls>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof FeatureRunningControls>;
6
+ /** Running state — spinner in badge, Stop button visible. */
7
+ export declare const Running: Story;
8
+ /** Running state — no stop callback provided (button hidden). */
9
+ export declare const RunningNoStop: Story;
10
+ /** Action-required state — amber badge, Stop button visible. */
11
+ export declare const ActionRequired: Story;
12
+ /** Error state — red badge, Retry button visible. */
13
+ export declare const ErrorWithRetry: Story;
14
+ /** Error state — no retry callback (button hidden). */
15
+ export declare const ErrorNoRetry: Story;
16
+ /** Pending state — slate badge, Start button visible. */
17
+ export declare const PendingWithStart: Story;
18
+ /** Done state — emerald badge, no action button. */
19
+ export declare const Done: Story;
20
+ /** Blocked state — gray badge, no action button. */
21
+ export declare const Blocked: Story;
22
+ /** Creating state — blue badge, no action button. */
23
+ export declare const Creating: Story;
24
+ /** Long lifecycle label — truncates gracefully. */
25
+ export declare const LongLabel: Story;
26
+ //# sourceMappingURL=feature-running-controls.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-running-controls.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/feature-running-controls.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAGpE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,sBAAsB,CAc7C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAoBrD,6DAA6D;AAC7D,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,iEAAiE;AACjE,eAAO,MAAM,aAAa,EAAE,KAE3B,CAAC;AAEF,gEAAgE;AAChE,eAAO,MAAM,cAAc,EAAE,KAS5B,CAAC;AAEF,qDAAqD;AACrD,eAAO,MAAM,cAAc,EAAE,KAE5B,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,YAAY,EAAE,KAE1B,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,gBAAgB,EAAE,KAS9B,CAAC;AAEF,oDAAoD;AACpD,eAAO,MAAM,IAAI,EAAE,KAElB,CAAC;AAEF,oDAAoD;AACpD,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,qDAAqD;AACrD,eAAO,MAAM,QAAQ,EAAE,KAEtB,CAAC;AAEF,mDAAmD;AACnD,eAAO,MAAM,SAAS,EAAE,KASvB,CAAC"}
@@ -0,0 +1,91 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { fn } from '@storybook/test';
3
+ import { FeatureRunningControls } from './feature-running-controls.js';
4
+ const meta = {
5
+ title: 'Drawers/Feature/Tabs/FeatureRunningControls',
6
+ component: FeatureRunningControls,
7
+ tags: ['autodocs'],
8
+ parameters: {
9
+ layout: 'fullscreen',
10
+ },
11
+ decorators: [
12
+ (Story) => (_jsx("div", { style: { width: '560px', border: '1px solid var(--color-border)' }, children: _jsx(Story, {}) })),
13
+ ],
14
+ };
15
+ export default meta;
16
+ /* ---------------------------------------------------------------------------
17
+ * Data fixtures
18
+ * ------------------------------------------------------------------------- */
19
+ const base = {
20
+ name: 'Auth Module',
21
+ featureId: 'f1',
22
+ lifecycle: 'implementation',
23
+ state: 'running',
24
+ progress: 65,
25
+ repositoryPath: '/home/user/my-repo',
26
+ branch: 'feat/auth-module',
27
+ };
28
+ /* ---------------------------------------------------------------------------
29
+ * Stories — one per meaningful state
30
+ * ------------------------------------------------------------------------- */
31
+ /** Running state — spinner in badge, Stop button visible. */
32
+ export const Running = {
33
+ args: { data: { ...base, state: 'running', onStop: fn() } },
34
+ };
35
+ /** Running state — no stop callback provided (button hidden). */
36
+ export const RunningNoStop = {
37
+ args: { data: { ...base, state: 'running' } },
38
+ };
39
+ /** Action-required state — amber badge, Stop button visible. */
40
+ export const ActionRequired = {
41
+ args: {
42
+ data: {
43
+ ...base,
44
+ lifecycle: 'requirements',
45
+ state: 'action-required',
46
+ onStop: fn(),
47
+ },
48
+ },
49
+ };
50
+ /** Error state — red badge, Retry button visible. */
51
+ export const ErrorWithRetry = {
52
+ args: { data: { ...base, state: 'error', onRetry: fn() } },
53
+ };
54
+ /** Error state — no retry callback (button hidden). */
55
+ export const ErrorNoRetry = {
56
+ args: { data: { ...base, state: 'error' } },
57
+ };
58
+ /** Pending state — slate badge, Start button visible. */
59
+ export const PendingWithStart = {
60
+ args: {
61
+ data: {
62
+ ...base,
63
+ lifecycle: 'pending',
64
+ state: 'pending',
65
+ onStart: fn(),
66
+ },
67
+ },
68
+ };
69
+ /** Done state — emerald badge, no action button. */
70
+ export const Done = {
71
+ args: { data: { ...base, lifecycle: 'maintain', state: 'done', progress: 100 } },
72
+ };
73
+ /** Blocked state — gray badge, no action button. */
74
+ export const Blocked = {
75
+ args: { data: { ...base, state: 'blocked' } },
76
+ };
77
+ /** Creating state — blue badge, no action button. */
78
+ export const Creating = {
79
+ args: { data: { ...base, state: 'creating', lifecycle: 'requirements' } },
80
+ };
81
+ /** Long lifecycle label — truncates gracefully. */
82
+ export const LongLabel = {
83
+ args: {
84
+ data: {
85
+ ...base,
86
+ lifecycle: 'implementation',
87
+ state: 'running',
88
+ onStop: fn(),
89
+ },
90
+ },
91
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"overview-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/overview-tab.tsx"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAQxE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,eAAe,CAAC;CACvB;AAED,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,gBAAgB,2CA+DrD"}
1
+ {"version":3,"file":"overview-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/overview-tab.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAQxE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,eAAe,CAAC;CACvB;AAED,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,gBAAgB,2CAqCrD"}
@@ -1,26 +1,20 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useState, useEffect, useRef } from 'react';
4
- import { AlertTriangle, Check, ExternalLink, FileSearch, GitBranch, GitCommitHorizontal, RotateCcw, ShieldCheck, Square, X, Zap, } from 'lucide-react';
4
+ import { AlertTriangle, Check, ExternalLink, FileSearch, GitBranch, GitCommitHorizontal, ShieldCheck, X, Zap, } from 'lucide-react';
5
5
  import { InlineAttachments } from '../../common/inline-attachments/index.js';
6
6
  import { PrStatus } from '../../../../../../packages/core/src/domain/generated/output.js';
7
7
  import { cn } from '../../../lib/utils.js';
8
8
  import { Badge } from '../../ui/badge.js';
9
9
  import { Separator } from '../../ui/separator.js';
10
10
  import { CiStatusBadge } from '../../common/ci-status-badge/index.js';
11
- import { CometSpinner } from '../../ui/comet-spinner.js';
12
- import { featureNodeStateConfig, lifecycleDisplayLabels } from '../../common/feature-node/index.js';
11
+ import { featureNodeStateConfig } from '../../common/feature-node/index.js';
13
12
  import { getAgentTypeIcon, agentTypeLabels, } from '../../common/feature-node/agent-type-icons.js';
14
13
  import { getModelMeta } from '../../../lib/model-metadata.js';
15
14
  import { formatDuration } from '../../../lib/format-duration.js';
16
15
  export function OverviewTab({ data }) {
17
16
  const isCompleted = data.lifecycle === 'maintain';
18
- return (_jsxs(_Fragment, { children: [_jsxs("div", { "data-testid": "feature-drawer-status", className: "flex flex-col gap-3 p-4", children: [_jsx("div", { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: lifecycleDisplayLabels[data.lifecycle] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(FeatureStateBadge, { data: data }), data.state === 'error' && data.onRetry ? (_jsxs("button", { "data-testid": "feature-drawer-retry-button", onClick: () => data.onRetry(data.featureId), className: "flex shrink-0 cursor-pointer items-center gap-1.5 rounded-full bg-red-50 px-3 py-1.5 text-sm font-medium text-red-700 transition-colors hover:bg-red-100", children: [_jsx(RotateCcw, { className: "h-3.5 w-3.5" }), "Retry"] })) : null, (data.state === 'running' || data.state === 'action-required') && data.onStop ? (_jsxs("button", { "data-testid": "feature-drawer-stop-button", onClick: () => data.onStop(data.featureId), className: "flex shrink-0 cursor-pointer items-center gap-1.5 rounded-full bg-red-50 px-3 py-1.5 text-sm font-medium text-red-700 transition-colors hover:bg-red-100", children: [_jsx(Square, { className: "h-3.5 w-3.5" }), "Stop"] })) : null] }), !isCompleted && data.progress > 0 ? (_jsxs("div", { "data-testid": "feature-drawer-progress", className: "flex flex-col gap-1", children: [_jsxs("div", { className: "text-muted-foreground flex items-center justify-between text-xs", children: [_jsx("span", { children: "Progress" }), _jsxs("span", { children: [data.progress, "%"] })] }), _jsx("div", { className: "bg-muted h-2 w-full overflow-hidden rounded-full", children: _jsx("div", { className: cn('h-full rounded-full transition-all', featureNodeStateConfig[data.state].progressClass), style: { width: `${data.progress}%` } }) })] })) : null, isCompleted && data.pr ? _jsx(FeaturePrInfo, { pr: data.pr }) : null] }), _jsx(FeatureInfo, { data: data }), !isCompleted && data.pr ? (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsx("div", { className: "p-4", children: _jsx(FeaturePrInfo, { pr: data.pr }) })] })) : null, _jsx(FeatureDetails, { data: data }), _jsx(FeatureSettings, { data: data })] }));
19
- }
20
- function FeatureStateBadge({ data }) {
21
- const config = featureNodeStateConfig[data.state];
22
- const Icon = config.icon;
23
- return (_jsxs("div", { className: cn('flex items-center gap-2 rounded-full px-3 py-1.5 text-sm font-medium', config.badgeBgClass, config.badgeClass), children: [data.state === 'running' ? (_jsx(CometSpinner, { size: "sm", className: "shrink-0" })) : (_jsx(Icon, { className: "h-4 w-4 shrink-0" })), _jsx("span", { children: config.label })] }));
17
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { "data-testid": "feature-drawer-status", className: "flex flex-col gap-3 p-4", children: [!isCompleted && data.progress > 0 ? (_jsxs("div", { "data-testid": "feature-drawer-progress", className: "flex flex-col gap-1", children: [_jsxs("div", { className: "text-muted-foreground flex items-center justify-between text-xs", children: [_jsx("span", { children: "Progress" }), _jsxs("span", { children: [data.progress, "%"] })] }), _jsx("div", { className: "bg-muted h-2 w-full overflow-hidden rounded-full", children: _jsx("div", { className: cn('h-full rounded-full transition-all', featureNodeStateConfig[data.state].progressClass), style: { width: `${data.progress}%` } }) })] })) : null, isCompleted && data.pr ? _jsx(FeaturePrInfo, { pr: data.pr }) : null] }), _jsx(FeatureInfo, { data: data }), !isCompleted && data.pr ? (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsx("div", { className: "p-4", children: _jsx(FeaturePrInfo, { pr: data.pr }) })] })) : null, _jsx(FeatureDetails, { data: data }), _jsx(FeatureSettings, { data: data })] }));
24
18
  }
25
19
  // ── Feature Info section ─────────────────────────────────────────────
26
20
  function formatRelativeTime(timestamp) {
@@ -15,10 +15,6 @@ export declare const DoneWithMergedPr: Story;
15
15
  export declare const Blocked: Story;
16
16
  /** Error state showing error message detail. */
17
17
  export declare const Error: Story;
18
- /** Error state with retry button visible. */
19
- export declare const ErrorWithRetry: Story;
20
- /** Running state with stop button visible. */
21
- export declare const RunningWithStop: Story;
22
18
  /** Minimal data — only required fields, no optional details or PR. */
23
19
  export declare const Minimal: Story;
24
20
  /** Fast mode feature — shows lightning icon in details section. */
@@ -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;AAGvD,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;AAOF,6CAA6C;AAC7C,eAAO,MAAM,cAAc,EAAE,KAE5B,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,eAAe,EAAE,KAE7B,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;AAEF,gEAAgE;AAChE,eAAO,MAAM,oBAAoB,EAAE,KAclC,CAAC;AAqBF,4DAA4D;AAC5D,eAAO,MAAM,sBAAsB,EAAE,KAEpC,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,gBAAgB,EAAE,KAO9B,CAAC;AAEF,+FAA+F;AAC/F,eAAO,MAAM,eAAe,EAAE,KAgB7B,CAAC;AAMF,oFAAoF;AACpF,eAAO,MAAM,eAAe,EAAE,KAY7B,CAAC;AAEF,kDAAkD;AAClD,eAAO,MAAM,uBAAuB,EAAE,KAYrC,CAAC;AAEF,mDAAmD;AACnD,eAAO,MAAM,uBAAuB,EAAE,KAYrC,CAAC;AAEF,2CAA2C;AAC3C,eAAO,MAAM,oBAAoB,EAAE,KAYlC,CAAC;AAEF,+DAA+D;AAC/D,eAAO,MAAM,mBAAmB,EAAE,KAQjC,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;AAEF,gEAAgE;AAChE,eAAO,MAAM,oBAAoB,EAAE,KAclC,CAAC;AAqBF,4DAA4D;AAC5D,eAAO,MAAM,sBAAsB,EAAE,KAEpC,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,gBAAgB,EAAE,KAO9B,CAAC;AAEF,+FAA+F;AAC/F,eAAO,MAAM,eAAe,EAAE,KAgB7B,CAAC;AAMF,oFAAoF;AACpF,eAAO,MAAM,eAAe,EAAE,KAY7B,CAAC;AAEF,kDAAkD;AAClD,eAAO,MAAM,uBAAuB,EAAE,KAYrC,CAAC;AAEF,mDAAmD;AACnD,eAAO,MAAM,uBAAuB,EAAE,KAYrC,CAAC;AAEF,2CAA2C;AAC3C,eAAO,MAAM,oBAAoB,EAAE,KAYlC,CAAC;AAEF,+DAA+D;AAC/D,eAAO,MAAM,mBAAmB,EAAE,KAQjC,CAAC"}
@@ -1,5 +1,4 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { fn } from '@storybook/test';
3
2
  import { PrStatus, CiStatus } from '../../../../../../packages/core/src/domain/generated/output.js';
4
3
  import { OverviewTab } from './overview-tab.js';
5
4
  const meta = {
@@ -133,18 +132,6 @@ export const Blocked = {
133
132
  export const Error = {
134
133
  args: { data: errorData },
135
134
  };
136
- const errorWithRetryData = {
137
- ...errorData,
138
- onRetry: fn(),
139
- };
140
- /** Error state with retry button visible. */
141
- export const ErrorWithRetry = {
142
- args: { data: errorWithRetryData },
143
- };
144
- /** Running state with stop button visible. */
145
- export const RunningWithStop = {
146
- args: { data: { ...fullData, onStop: fn() } },
147
- };
148
135
  /** Minimal data — only required fields, no optional details or PR. */
149
136
  export const Minimal = {
150
137
  args: { data: minimalData },