@shepai/cli 1.123.0-pr399.41eb3f6 → 1.124.0

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 (151) hide show
  1. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
  2. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +10 -4
  3. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  4. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +14 -6
  5. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts +1 -0
  6. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts.map +1 -1
  7. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.js +16 -0
  8. package/dist/src/presentation/web/hooks/use-deploy-action.d.ts.map +1 -1
  9. package/dist/src/presentation/web/hooks/use-deploy-action.js +0 -34
  10. package/dist/tsconfig.build.tsbuildinfo +1 -1
  11. package/package.json +1 -1
  12. package/web/.next/BUILD_ID +1 -1
  13. package/web/.next/build-manifest.json +2 -2
  14. package/web/.next/fallback-build-manifest.json +2 -2
  15. package/web/.next/prerender-manifest.json +3 -3
  16. package/web/.next/required-server-files.js +2 -2
  17. package/web/.next/required-server-files.json +2 -2
  18. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +22 -22
  19. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  20. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  21. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
  22. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  23. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  24. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +28 -28
  25. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  26. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  27. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
  28. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  29. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  30. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +22 -22
  31. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  32. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  33. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
  34. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  35. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  36. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +28 -28
  37. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  38. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  39. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +20 -20
  40. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  41. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  42. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
  43. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  44. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  45. package/web/.next/server/app/_global-error.html +2 -2
  46. package/web/.next/server/app/_global-error.rsc +1 -1
  47. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  48. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  49. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  50. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  51. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  52. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  53. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  54. package/web/.next/server/app/settings/page/server-reference-manifest.json +6 -6
  55. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  56. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  57. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  58. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  59. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  60. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  61. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  62. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  63. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  64. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  65. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  66. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  67. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  68. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js +1 -1
  69. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js.map +1 -1
  70. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js +1 -1
  71. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js.map +1 -1
  72. package/web/.next/server/chunks/ssr/[root-of-the-server]__06fef644._.js +1 -1
  73. package/web/.next/server/chunks/ssr/[root-of-the-server]__14664e9b._.js +2 -2
  74. package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js +1 -1
  75. package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js.map +1 -1
  76. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  77. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  78. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +2 -2
  79. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js.map +1 -1
  80. package/web/.next/server/chunks/ssr/[root-of-the-server]__7cbda1ea._.js +1 -1
  81. package/web/.next/server/chunks/ssr/[root-of-the-server]__7cbda1ea._.js.map +1 -1
  82. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  83. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  84. package/web/.next/server/chunks/ssr/[root-of-the-server]__8c553503._.js +2 -2
  85. package/web/.next/server/chunks/ssr/[root-of-the-server]__9e8b25ad._.js +1 -1
  86. package/web/.next/server/chunks/ssr/[root-of-the-server]__9e8b25ad._.js.map +1 -1
  87. package/web/.next/server/chunks/ssr/[root-of-the-server]__a7de2711._.js +2 -2
  88. package/web/.next/server/chunks/ssr/[root-of-the-server]__aed1d6f8._.js +1 -1
  89. package/web/.next/server/chunks/ssr/[root-of-the-server]__aed1d6f8._.js.map +1 -1
  90. package/web/.next/server/chunks/ssr/[root-of-the-server]__ce6057f6._.js +1 -1
  91. package/web/.next/server/chunks/ssr/[root-of-the-server]__ce6057f6._.js.map +1 -1
  92. package/web/.next/server/chunks/ssr/_135edb9c._.js +3 -0
  93. package/web/.next/server/chunks/ssr/{_6328bfd6._.js.map → _135edb9c._.js.map} +1 -1
  94. package/web/.next/server/chunks/ssr/_2f6f48b8._.js +1 -1
  95. package/web/.next/server/chunks/ssr/_2f6f48b8._.js.map +1 -1
  96. package/web/.next/server/chunks/ssr/_b89059c0._.js +3 -0
  97. package/web/.next/server/chunks/ssr/{_223a713c._.js.map → _b89059c0._.js.map} +1 -1
  98. package/web/.next/server/chunks/ssr/_cc77a143._.js +3 -0
  99. package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -0
  100. package/web/.next/server/chunks/ssr/_e9703421._.js +1 -1
  101. package/web/.next/server/chunks/ssr/_e9703421._.js.map +1 -1
  102. package/web/.next/server/chunks/ssr/{_5cd2a694._.js → _f84c16ab._.js} +2 -2
  103. package/web/.next/server/chunks/ssr/{_5cd2a694._.js.map → _f84c16ab._.js.map} +1 -1
  104. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  105. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  106. package/web/.next/server/chunks/ssr/src_presentation_web_164fa933._.js +3 -0
  107. package/web/.next/server/chunks/ssr/{src_presentation_web_3dcac3bc._.js.map → src_presentation_web_164fa933._.js.map} +1 -1
  108. package/web/.next/server/chunks/ssr/src_presentation_web_5f039db1._.js +2 -2
  109. package/web/.next/server/chunks/ssr/src_presentation_web_5f039db1._.js.map +1 -1
  110. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js +1 -1
  111. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js.map +1 -1
  112. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
  113. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
  114. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
  115. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
  116. package/web/.next/server/chunks/ssr/src_presentation_web_c4337169._.js +2 -2
  117. package/web/.next/server/chunks/ssr/src_presentation_web_c4337169._.js.map +1 -1
  118. package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
  119. package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js.map +1 -1
  120. package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
  121. package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js.map +1 -1
  122. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  123. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  124. package/web/.next/server/pages/500.html +2 -2
  125. package/web/.next/server/server-reference-manifest.js +1 -1
  126. package/web/.next/server/server-reference-manifest.json +34 -34
  127. package/web/.next/static/chunks/0dc102ef519487f5.js +1 -0
  128. package/web/.next/static/chunks/{03b829609cb3e4b1.js → 10fc8c2e5ff44bb2.js} +1 -1
  129. package/web/.next/static/chunks/{d1e6c5bb743e3587.js → 5b7726ff31c25338.js} +2 -2
  130. package/web/.next/static/chunks/74fa59dbd04fdfcb.js +2 -0
  131. package/web/.next/static/chunks/76c038a9d55ca717.js +1 -0
  132. package/web/.next/static/chunks/9d7e0bb6dc2f88ae.js +1 -0
  133. package/web/.next/static/chunks/9db7f24ddea15a4c.js +1 -0
  134. package/web/.next/static/chunks/ad076c0b68dd9971.js +1 -0
  135. package/web/.next/static/chunks/d72044b2826292fe.js +1 -0
  136. package/web/.next/static/chunks/{af09691e4d666285.js → eaeabda870a35a9a.js} +1 -1
  137. package/web/.next/server/chunks/ssr/_223a713c._.js +0 -3
  138. package/web/.next/server/chunks/ssr/_4a948d3a._.js +0 -3
  139. package/web/.next/server/chunks/ssr/_4a948d3a._.js.map +0 -1
  140. package/web/.next/server/chunks/ssr/_6328bfd6._.js +0 -3
  141. package/web/.next/server/chunks/ssr/src_presentation_web_3dcac3bc._.js +0 -3
  142. package/web/.next/static/chunks/06dcf11946519cf7.js +0 -1
  143. package/web/.next/static/chunks/14ce5ffbb86dd80e.js +0 -1
  144. package/web/.next/static/chunks/2756e2f53da55fa1.js +0 -1
  145. package/web/.next/static/chunks/31c534b010db1201.js +0 -1
  146. package/web/.next/static/chunks/31cacff494356d30.js +0 -1
  147. package/web/.next/static/chunks/49d332348d0d7191.js +0 -2
  148. package/web/.next/static/chunks/a14820d87c06b28e.js +0 -1
  149. /package/web/.next/static/{5K1b8IucGUZnZ7EHoN8aO → Ap_0BUaFHzD8WxrlWsbMg}/_buildManifest.js +0 -0
  150. /package/web/.next/static/{5K1b8IucGUZnZ7EHoN8aO → Ap_0BUaFHzD8WxrlWsbMg}/_clientMiddlewareManifest.json +0 -0
  151. /package/web/.next/static/{5K1b8IucGUZnZ7EHoN8aO → Ap_0BUaFHzD8WxrlWsbMg}/_ssgManifest.js +0 -0
@@ -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":"AAoCA,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,2CAkiB1F"}
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"}
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
3
3
  import { useState, useCallback, useEffect, useRef } from 'react';
4
4
  import { useRouter, usePathname } from 'next/navigation';
5
5
  import { toast } from 'sonner';
6
- import { Loader2, Trash2, Copy, Check, Code2, ExternalLink } from 'lucide-react';
6
+ import { Loader2, Trash2, Play, Square, Copy, Check, Code2, ExternalLink } from 'lucide-react';
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';
@@ -14,11 +14,15 @@ import { getMergeReviewData } from '../../../app/actions/get-merge-review-data.j
14
14
  import { useFeatureFlags } from '../../../hooks/feature-flags-context.js';
15
15
  import { useSoundAction } from '../../../hooks/use-sound-action.js';
16
16
  import { useGuardedDrawerClose } from '../../../hooks/drawer-close-guard.js';
17
+ import { useDeployAction } from '../../../hooks/use-deploy-action.js';
17
18
  import { useAgentEventsContext } from '../../../hooks/agent-events-provider.js';
18
19
  import { BaseDrawer } from '../../common/base-drawer/index.js';
20
+ import { DeploymentStatusBadge } from '../../common/deployment-status-badge/index.js';
19
21
  import { DrawerTitle, DrawerDescription } from '../../ui/drawer.js';
20
22
  import { Button } from '../../ui/button.js';
23
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../ui/tooltip.js';
21
24
  import { DeleteFeatureDialog } from '../../common/delete-feature-dialog/index.js';
25
+ import { ActionButton } from '../../common/action-button/index.js';
22
26
  import { OpenActionMenu } from '../../common/open-action-menu/index.js';
23
27
  import { FeatureDrawerTabs } from '../../common/feature-drawer-tabs/index.js';
24
28
  import { useFeatureActions } from '../../common/feature-drawer/use-feature-actions.js';
@@ -312,7 +316,9 @@ export function FeatureDrawerClient({ view: initialView, urlTab }) {
312
316
  repositoryPath: featureNode.repositoryPath,
313
317
  branch: featureNode.branch,
314
318
  }
315
- : undefined;
319
+ : null;
320
+ const deployAction = useDeployAction(featureDeployTarget);
321
+ const isFeatureDeployActive = deployAction.status === 'Booting' || deployAction.status === 'Ready';
316
322
  // ── Short ID copy ───────────────────────────────────────────────────
317
323
  const COPY_FEEDBACK_DELAY = 2000;
318
324
  const [idCopied, setIdCopied] = useState(false);
@@ -330,7 +336,7 @@ export function FeatureDrawerClient({ view: initialView, urlTab }) {
330
336
  const repoName = featureNode.repositoryName ??
331
337
  featureNode.repositoryPath.split('/').filter(Boolean).at(-1) ??
332
338
  '';
333
- header = (_jsxs(_Fragment, { children: [_jsxs("div", { "data-testid": "feature-drawer-header", children: [_jsx(DrawerTitle, { children: featureNode.name }), repoName ? (_jsxs("div", { className: "flex items-center gap-1.5 pt-0.5", children: [_jsx(Code2, { className: "text-muted-foreground size-3.5 shrink-0" }), featureNode.remoteUrl ? (_jsxs("a", { href: featureNode.remoteUrl, target: "_blank", rel: "noopener noreferrer", className: "text-muted-foreground hover:text-foreground inline-flex items-center gap-1 text-xs transition-colors", "data-testid": "feature-drawer-repo-link", children: [repoName, _jsx(ExternalLink, { className: "size-3" })] })) : (_jsx("span", { className: "text-muted-foreground text-xs", children: repoName }))] })) : null, _jsx(DrawerDescription, { className: "sr-only", children: featureNode.name })] }), featureActionsInput ? (_jsxs("div", { className: "flex items-center gap-2 pt-2", "data-testid": "feature-drawer-actions", children: [_jsx(OpenActionMenu, { actions: featureActions, repositoryPath: featureActionsInput.repositoryPath, showSpecs: !!featureActionsInput.specPath }), _jsxs("div", { className: "ml-auto flex items-center gap-1.5", children: [_jsx("code", { className: "bg-muted text-muted-foreground rounded px-1.5 py-0.5 font-mono text-xs", children: shortId }), _jsx("button", { type: "button", onClick: handleCopyId, className: "text-muted-foreground hover:text-foreground inline-flex items-center rounded p-0.5 transition-colors", "aria-label": "Copy feature ID", "data-testid": "feature-drawer-copy-id", children: idCopied ? (_jsx(Check, { className: "size-3.5 text-green-600" })) : (_jsx(Copy, { className: "size-3.5" })) })] }), featureNode.featureId ? (_jsxs(_Fragment, { children: [_jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Delete feature", disabled: isDeleting, className: "text-muted-foreground hover:text-destructive", "data-testid": "feature-drawer-delete", onClick: () => setDeleteDialogOpen(true), children: isDeleting ? (_jsx(Loader2, { className: "size-4 animate-spin" })) : (_jsx(Trash2, { className: "size-4" })) }), _jsx(DeleteFeatureDialog, { open: deleteDialogOpen, onOpenChange: setDeleteDialogOpen, onConfirm: (cleanup, cascadeDelete) => handleDelete(featureNode.featureId, cleanup, cascadeDelete), isDeleting: isDeleting, featureName: featureNode.name, featureId: featureNode.featureId, hasChildren: featureNode.hasChildren })] })) : null] })) : null] }));
339
+ header = (_jsxs(_Fragment, { children: [_jsxs("div", { "data-testid": "feature-drawer-header", children: [_jsx(DrawerTitle, { children: featureNode.name }), repoName ? (_jsxs("div", { className: "flex items-center gap-1.5 pt-0.5", children: [_jsx(Code2, { className: "text-muted-foreground size-3.5 shrink-0" }), featureNode.remoteUrl ? (_jsxs("a", { href: featureNode.remoteUrl, target: "_blank", rel: "noopener noreferrer", className: "text-muted-foreground hover:text-foreground inline-flex items-center gap-1 text-xs transition-colors", "data-testid": "feature-drawer-repo-link", children: [repoName, _jsx(ExternalLink, { className: "size-3" })] })) : (_jsx("span", { className: "text-muted-foreground text-xs", children: repoName }))] })) : null, _jsx(DrawerDescription, { className: "sr-only", children: featureNode.name })] }), featureActionsInput ? (_jsxs("div", { className: "flex items-center gap-2 pt-2", "data-testid": "feature-drawer-actions", children: [_jsx(OpenActionMenu, { actions: featureActions, repositoryPath: featureActionsInput.repositoryPath, showSpecs: !!featureActionsInput.specPath }), featureFlags.envDeploy && featureDeployTarget ? (_jsxs(_Fragment, { children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { children: _jsx(ActionButton, { label: isFeatureDeployActive ? 'Stop Dev Server' : 'Start Dev Server', onClick: isFeatureDeployActive ? deployAction.stop : deployAction.deploy, loading: deployAction.deployLoading || deployAction.stopLoading, error: !!deployAction.deployError, icon: isFeatureDeployActive ? Square : Play, iconOnly: true, variant: "outline", size: "icon-sm" }) }) }), _jsx(TooltipContent, { children: isFeatureDeployActive ? 'Stop Dev Server' : 'Start Dev Server' })] }) }), isFeatureDeployActive ? (_jsx(DeploymentStatusBadge, { status: deployAction.status, url: deployAction.url, targetId: featureDeployTarget?.targetId })) : null] })) : null, _jsxs("div", { className: "ml-auto flex items-center gap-1.5", children: [_jsx("code", { className: "bg-muted text-muted-foreground rounded px-1.5 py-0.5 font-mono text-xs", children: shortId }), _jsx("button", { type: "button", onClick: handleCopyId, className: "text-muted-foreground hover:text-foreground inline-flex items-center rounded p-0.5 transition-colors", "aria-label": "Copy feature ID", "data-testid": "feature-drawer-copy-id", children: idCopied ? (_jsx(Check, { className: "size-3.5 text-green-600" })) : (_jsx(Copy, { className: "size-3.5" })) })] }), featureNode.featureId ? (_jsxs(_Fragment, { children: [_jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Delete feature", disabled: isDeleting, className: "text-muted-foreground hover:text-destructive", "data-testid": "feature-drawer-delete", onClick: () => setDeleteDialogOpen(true), children: isDeleting ? (_jsx(Loader2, { className: "size-4 animate-spin" })) : (_jsx(Trash2, { className: "size-4" })) }), _jsx(DeleteFeatureDialog, { open: deleteDialogOpen, onOpenChange: setDeleteDialogOpen, onConfirm: (cleanup, cascadeDelete) => handleDelete(featureNode.featureId, cleanup, cascadeDelete), isDeleting: isDeleting, featureName: featureNode.name, featureId: featureNode.featureId, hasChildren: featureNode.hasChildren })] })) : null] })) : null] }));
334
340
  }
335
341
  // ── Body ──────────────────────────────────────────────────────────────
336
342
  let body = null;
@@ -342,5 +348,5 @@ export function FeatureDrawerClient({ view: initialView, urlTab }) {
342
348
  };
343
349
  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 }));
344
350
  }
345
- return (_jsx(BaseDrawer, { open: isOpen, onClose: attemptClose, size: "md", modal: false, header: header, deployTarget: featureFlags.envDeploy ? featureDeployTarget : undefined, "data-testid": view.type === 'feature' ? 'feature-drawer' : 'repository-drawer', children: body }));
351
+ return (_jsx(BaseDrawer, { open: isOpen, onClose: attemptClose, size: "md", modal: false, header: header, "data-testid": view.type === 'feature' ? 'feature-drawer' : 'repository-drawer', children: body }));
346
352
  }
@@ -1 +1 @@
1
- {"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA6DnE,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,2CA8UA"}
1
+ {"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA6DnE,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,2CAiWA"}
@@ -80,16 +80,24 @@ export function FeatureNode({ data, selected, }) {
80
80
  ? 'BLOCKED'
81
81
  : data.state === 'pending'
82
82
  ? 'PENDING'
83
- : lifecycleDisplayLabels[data.lifecycle] }), _jsxs("div", { className: "flex items-center gap-0.5", children: [data.fastMode ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { "data-testid": "feature-node-fast-mode-badge", className: "-mt-1 p-1", children: _jsx(Zap, { className: "h-3.5 w-3.5 text-amber-500" }) }) }), _jsx(TooltipContent, { side: "bottom", children: "Fast Mode" })] }) })) : null, data.agentType ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": agentTypeLabels[data.agentType] ?? data.agentType, "data-testid": "feature-node-agent-badge", onClick: (e) => {
83
+ : lifecycleDisplayLabels[data.lifecycle] }), _jsxs("div", { className: "flex items-center gap-0.5", children: [data.deployment ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": data.deployment.status === DeploymentState.Booting
84
+ ? 'Deploying'
85
+ : 'Open dev server', "data-testid": "feature-node-deployment-indicator", onClick: (e) => {
86
+ e.stopPropagation();
87
+ if (data.deployment?.status === DeploymentState.Ready &&
88
+ data.deployment.url) {
89
+ window.open(data.deployment.url, '_blank', 'noopener,noreferrer');
90
+ }
91
+ }, className: cn('nodrag -mt-1 p-1', data.deployment.status === DeploymentState.Ready && data.deployment.url
92
+ ? 'cursor-pointer opacity-80 transition-opacity hover:opacity-100'
93
+ : 'cursor-default'), children: data.deployment.status === DeploymentState.Booting ? (_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin text-blue-500" })) : (_jsx(Globe, { className: "h-3.5 w-3.5 text-green-600" })) }) }), _jsx(TooltipContent, { side: "bottom", children: data.deployment.status === DeploymentState.Booting
94
+ ? 'Deploying...'
95
+ : (data.deployment.url ?? 'Live') })] }) })) : null, data.fastMode ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { "data-testid": "feature-node-fast-mode-badge", className: "-mt-1 p-1", children: _jsx(Zap, { className: "h-3.5 w-3.5 text-amber-500" }) }) }), _jsx(TooltipContent, { side: "bottom", children: "Fast Mode" })] }) })) : null, data.agentType ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": agentTypeLabels[data.agentType] ?? data.agentType, "data-testid": "feature-node-agent-badge", onClick: (e) => {
84
96
  e.stopPropagation();
85
97
  data.onSettings?.();
86
98
  }, className: cn('nodrag -mt-1 -mr-1 p-1', data.onSettings
87
99
  ? 'cursor-pointer opacity-80 transition-opacity hover:opacity-100'
88
- : 'cursor-default'), children: _jsx(AgentIcon, { agentType: data.agentType, className: "h-3.5 w-3.5" }) }) }), _jsxs(TooltipContent, { side: "bottom", children: [_jsx("span", { className: "font-medium", children: agentTypeLabels[data.agentType] ?? data.agentType }), data.modelId ? (_jsxs("span", { className: "ml-1 opacity-70", children: ["\u00B7 ", getModelMeta(data.modelId).displayName || data.modelId] })) : null] })] }) })) : null] })] }), _jsx("h3", { className: "mt-1 truncate text-sm font-bold", children: data.name }), data.description ? (_jsx("p", { "data-testid": "feature-node-description", className: "text-muted-foreground mt-0.5 truncate text-xs", children: data.description })) : null, data.deployment ? (_jsxs("div", { "data-testid": "feature-node-deployment-indicator", className: cn('mt-1.5 flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[10px] font-medium', data.deployment.status === DeploymentState.Booting
89
- ? 'bg-blue-50 text-blue-700'
90
- : 'bg-green-50 text-green-700'), children: [data.deployment.status === DeploymentState.Booting ? (_jsx(Loader2, { className: "h-3 w-3 animate-spin" })) : (_jsx(Globe, { className: "h-3 w-3" })), _jsx("span", { className: "truncate", children: data.deployment.status === DeploymentState.Booting
91
- ? 'Deploying...'
92
- : (data.deployment.url ?? 'Live') })] })) : null, _jsx("div", { className: "mt-auto pt-2", children: data.state === 'deleting' ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mt-1.5 flex items-center gap-1.5 text-xs", children: [_jsx(Trash2, { className: "h-3.5 w-3.5 shrink-0 text-gray-400" }), _jsx("span", { className: "text-muted-foreground", children: "Deleting\u2026" })] }), _jsx("div", { "data-testid": "feature-node-progress-bar", className: "bg-muted mt-1.5 h-1 w-full overflow-hidden rounded-full", children: _jsx("div", { className: "motion-safe:animate-indeterminate-progress bg-foreground/30 h-full w-1/3 rounded-full" }) })] })) : data.state === 'creating' ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mt-1.5 flex items-center gap-1.5 text-xs", children: [_jsx(Icon, { className: "h-3.5 w-3.5 shrink-0 animate-spin" }), _jsx("span", { className: "text-muted-foreground", children: getBadgeText(data) })] }), _jsx("div", { "data-testid": "feature-node-progress-bar", className: "bg-muted mt-1.5 h-1 w-full overflow-hidden rounded-full", children: _jsx("div", { className: "motion-safe:animate-indeterminate-progress bg-foreground/30 h-full w-1/3 rounded-full" }) })] })) : data.state === 'running' ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mt-1.5 flex items-center gap-1.5 text-xs", children: [_jsx(AgentIcon, { agentType: data.agentType, className: "h-3.5 w-3.5 shrink-0" }), _jsx("span", { className: "text-muted-foreground", children: getBadgeText(data) })] }), _jsx("div", { "data-testid": "feature-node-progress-bar", className: "bg-muted mt-1.5 h-1 w-full overflow-hidden rounded-full", children: _jsx("div", { className: "animate-indeterminate-progress bg-foreground/30 h-full w-1/3 rounded-full" }) })] })) : config.showProgressBar ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "text-muted-foreground flex items-center justify-end text-[10px]", children: _jsxs("span", { children: [data.progress, "%"] }) }), _jsx("div", { "data-testid": "feature-node-progress-bar", className: "bg-muted mt-1.5 h-1 w-full overflow-hidden rounded-full", children: _jsx("div", { className: cn('h-full rounded-full transition-all', config.progressClass), style: { width: `${data.progress}%` } }) })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "text-muted-foreground flex items-center justify-between text-[10px]", children: [_jsx("span", { children: data.featureId }), (data.worktreePath ?? data.repositoryPath) ? (_jsx(FeatureSessionsDropdown, { repositoryPath: data.worktreePath ?? data.repositoryPath })) : null] }), _jsxs("div", { className: "mt-1.5 flex items-center gap-1.5", children: [_jsxs("div", { "data-testid": "feature-node-badge", className: (() => {
100
+ : 'cursor-default'), children: _jsx(AgentIcon, { agentType: data.agentType, className: "h-3.5 w-3.5" }) }) }), _jsxs(TooltipContent, { side: "bottom", children: [_jsx("span", { className: "font-medium", children: agentTypeLabels[data.agentType] ?? data.agentType }), data.modelId ? (_jsxs("span", { className: "ml-1 opacity-70", children: ["\u00B7 ", getModelMeta(data.modelId).displayName || data.modelId] })) : null] })] }) })) : null] })] }), _jsx("h3", { className: "mt-1 truncate text-sm font-bold", children: data.name }), data.description ? (_jsx("p", { "data-testid": "feature-node-description", className: "text-muted-foreground mt-0.5 truncate text-xs", children: data.description })) : null, _jsx("div", { className: "mt-auto pt-2", children: data.state === 'deleting' ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mt-1.5 flex items-center gap-1.5 text-xs", children: [_jsx(Trash2, { className: "h-3.5 w-3.5 shrink-0 text-gray-400" }), _jsx("span", { className: "text-muted-foreground", children: "Deleting\u2026" })] }), _jsx("div", { "data-testid": "feature-node-progress-bar", className: "bg-muted mt-1.5 h-1 w-full overflow-hidden rounded-full", children: _jsx("div", { className: "motion-safe:animate-indeterminate-progress bg-foreground/30 h-full w-1/3 rounded-full" }) })] })) : data.state === 'creating' ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mt-1.5 flex items-center gap-1.5 text-xs", children: [_jsx(Icon, { className: "h-3.5 w-3.5 shrink-0 animate-spin" }), _jsx("span", { className: "text-muted-foreground", children: getBadgeText(data) })] }), _jsx("div", { "data-testid": "feature-node-progress-bar", className: "bg-muted mt-1.5 h-1 w-full overflow-hidden rounded-full", children: _jsx("div", { className: "motion-safe:animate-indeterminate-progress bg-foreground/30 h-full w-1/3 rounded-full" }) })] })) : data.state === 'running' ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mt-1.5 flex items-center gap-1.5 text-xs", children: [_jsx(AgentIcon, { agentType: data.agentType, className: "h-3.5 w-3.5 shrink-0" }), _jsx("span", { className: "text-muted-foreground", children: getBadgeText(data) })] }), _jsx("div", { "data-testid": "feature-node-progress-bar", className: "bg-muted mt-1.5 h-1 w-full overflow-hidden rounded-full", children: _jsx("div", { className: "animate-indeterminate-progress bg-foreground/30 h-full w-1/3 rounded-full" }) })] })) : config.showProgressBar ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "text-muted-foreground flex items-center justify-end text-[10px]", children: _jsxs("span", { children: [data.progress, "%"] }) }), _jsx("div", { "data-testid": "feature-node-progress-bar", className: "bg-muted mt-1.5 h-1 w-full overflow-hidden rounded-full", children: _jsx("div", { className: cn('h-full rounded-full transition-all', config.progressClass), style: { width: `${data.progress}%` } }) })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "text-muted-foreground flex items-center justify-between text-[10px]", children: [_jsx("span", { children: data.featureId }), (data.worktreePath ?? data.repositoryPath) ? (_jsx(FeatureSessionsDropdown, { repositoryPath: data.worktreePath ?? data.repositoryPath })) : null] }), _jsxs("div", { className: "mt-1.5 flex items-center gap-1.5", children: [_jsxs("div", { "data-testid": "feature-node-badge", className: (() => {
93
101
  const override = getActionRequiredBadgeClasses(data);
94
102
  return cn('flex min-w-0 flex-1 items-center justify-center gap-1.5 rounded-full px-2.5 py-1 text-[11px] font-medium', override?.badgeBgClass ?? config.badgeBgClass, override?.badgeClass ?? config.badgeClass);
95
103
  })(), children: [(() => {
@@ -22,6 +22,7 @@ export declare const FastModeDone: Story;
22
22
  export declare const DeploymentBooting: Story;
23
23
  export declare const DeploymentReady: Story;
24
24
  export declare const DeploymentReadyNoUrl: Story;
25
+ export declare const DeploymentWithFastModeAndAgent: Story;
25
26
  export declare const Interactive: Story;
26
27
  export declare const Pending: Story;
27
28
  export declare const PendingWithStart: Story;
@@ -1 +1 @@
1
- {"version":3,"file":"feature-node.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAMvD,OAAO,KAAK,EACV,eAAe,EAIhB,MAAM,6BAA6B,CAAC;AAiCrC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,eAAe,CAc/B,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAC;AAEvC,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AA0HF,eAAO,MAAM,SAAS,EAAE,KAQvB,CAAC;AAYF,eAAO,MAAM,aAAa,EAAE,KAqB3B,CAAC;AA2EF,eAAO,MAAM,aAAa,EAAE,KAQ3B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAMxB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAW7B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAUtB,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,KAUvC,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAUtB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAY5B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAatB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAc1B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAY/B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAa7B,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,KAYlC,CAAC;AA4EF,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAUrB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC"}
1
+ {"version":3,"file":"feature-node.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAMvD,OAAO,KAAK,EACV,eAAe,EAIhB,MAAM,6BAA6B,CAAC;AAiCrC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,eAAe,CAc/B,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAC;AAEvC,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AA0HF,eAAO,MAAM,SAAS,EAAE,KAQvB,CAAC;AAYF,eAAO,MAAM,aAAa,EAAE,KAqB3B,CAAC;AA2EF,eAAO,MAAM,aAAa,EAAE,KAQ3B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAMxB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAW7B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAUtB,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,KAUvC,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAUtB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAY5B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAatB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAc1B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAY/B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAa7B,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,KAYlC,CAAC;AAEF,eAAO,MAAM,8BAA8B,EAAE,KAe5C,CAAC;AA4EF,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAUrB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC"}
@@ -424,6 +424,22 @@ export const DeploymentReadyNoUrl = {
424
424
  },
425
425
  render: (args) => _jsx(FeatureNodeCanvas, { data: args }),
426
426
  };
427
+ export const DeploymentWithFastModeAndAgent = {
428
+ args: {
429
+ name: 'Full Stack App',
430
+ description: 'Next.js app with all inline icons',
431
+ featureId: '#d4',
432
+ lifecycle: 'deploy',
433
+ state: 'done',
434
+ progress: 100,
435
+ runtime: '22m',
436
+ fastMode: true,
437
+ agentType: 'claude-code',
438
+ modelId: 'claude-sonnet-4-6',
439
+ deployment: { status: DeploymentState.Ready, url: 'http://localhost:3000' },
440
+ },
441
+ render: (args) => _jsx(FeatureNodeCanvas, { data: args }),
442
+ };
427
443
  const interactiveInitialNodes = [
428
444
  {
429
445
  id: 'node-1',
@@ -1 +1 @@
1
- {"version":3,"file":"use-deploy-action.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-deploy-action.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAM5E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,SAAS,GAAG,YAAY,CAAC;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAOD,wBAAgB,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,GAAG,iBAAiB,CA8MlF"}
1
+ {"version":3,"file":"use-deploy-action.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-deploy-action.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAM5E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,SAAS,GAAG,YAAY,CAAC;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAOD,wBAAgB,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,GAAG,iBAAiB,CAwKlF"}
@@ -38,38 +38,6 @@ export function useDeployAction(input) {
38
38
  clearInterval(pollIntervalRef.current);
39
39
  };
40
40
  }, []);
41
- // Fetch initial deployment status on mount (or when input changes) so we
42
- // pick up any already-running dev server that was started before this
43
- // component mounted. Without this, closing and reopening the drawer would
44
- // lose awareness of the running deployment.
45
- const pollAfterInitialFetchRef = useRef(null);
46
- const initialFetchIdRef = useRef(null);
47
- useEffect(() => {
48
- const targetId = input?.targetId ?? null;
49
- // Only fetch once per targetId to avoid redundant calls
50
- if (targetId === initialFetchIdRef.current)
51
- return;
52
- initialFetchIdRef.current = targetId;
53
- if (!targetId)
54
- return;
55
- let cancelled = false;
56
- getDeploymentStatus(targetId).then((result) => {
57
- if (cancelled || !mountedRef.current)
58
- return;
59
- if (result && result.state !== 'Stopped') {
60
- log.info(`initial status fetch: state=${result.state}, url=${result.url}`);
61
- setStatus(result.state);
62
- setUrl(result.url);
63
- // Start polling to keep the state fresh
64
- // (startPolling is defined below, but the effect runs after render
65
- // so it will be available via the ref-based closure)
66
- pollAfterInitialFetchRef.current?.(targetId);
67
- }
68
- });
69
- return () => {
70
- cancelled = true;
71
- };
72
- }, [input?.targetId]);
73
41
  const stopPolling = useCallback(() => {
74
42
  if (pollIntervalRef.current) {
75
43
  log.debug('stopping polling');
@@ -103,8 +71,6 @@ export function useDeployAction(input) {
103
71
  }
104
72
  }, POLL_INTERVAL);
105
73
  }, [stopPolling]);
106
- // Keep ref in sync so the initial-fetch effect can start polling
107
- pollAfterInitialFetchRef.current = startPolling;
108
74
  const handleDeploy = useCallback(async () => {
109
75
  if (!input) {
110
76
  log.warn('deploy() called but input is null — no-op');