@shepai/cli 1.146.0 → 1.147.0-pr461.08148ed

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 (161) hide show
  1. package/dist/packages/core/src/application/use-cases/features/archive-feature.use-case.d.ts +3 -1
  2. package/dist/packages/core/src/application/use-cases/features/archive-feature.use-case.d.ts.map +1 -1
  3. package/dist/packages/core/src/application/use-cases/features/archive-feature.use-case.js +4 -10
  4. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  5. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +32 -17
  6. package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.d.ts.map +1 -1
  7. package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.js +1 -3
  8. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.d.ts.map +1 -1
  9. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.js +32 -33
  10. package/dist/src/presentation/web/lib/derive-graph.d.ts.map +1 -1
  11. package/dist/src/presentation/web/lib/derive-graph.js +4 -1
  12. package/dist/tsconfig.build.tsbuildinfo +1 -1
  13. package/package.json +1 -1
  14. package/web/.next/BUILD_ID +1 -1
  15. package/web/.next/build-manifest.json +2 -2
  16. package/web/.next/fallback-build-manifest.json +2 -2
  17. package/web/.next/prerender-manifest.json +3 -3
  18. package/web/.next/required-server-files.js +3 -3
  19. package/web/.next/required-server-files.json +3 -3
  20. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +28 -28
  21. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  22. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  23. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +28 -28
  24. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  25. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  26. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
  27. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  28. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  29. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +36 -36
  30. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  31. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  32. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
  33. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  34. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  35. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +28 -28
  36. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  37. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  38. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
  39. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  40. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  41. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +36 -36
  42. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  43. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  44. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +26 -26
  45. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  46. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  47. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
  48. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  49. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  50. package/web/.next/server/app/_global-error.html +2 -2
  51. package/web/.next/server/app/_global-error.rsc +1 -1
  52. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  53. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  54. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  55. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  56. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  57. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +3 -3
  58. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  59. package/web/.next/server/app/settings/page/server-reference-manifest.json +8 -8
  60. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  61. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  62. package/web/.next/server/app/skills/page/server-reference-manifest.json +8 -8
  63. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  64. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  65. package/web/.next/server/app/tools/page/server-reference-manifest.json +8 -8
  66. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  67. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  68. package/web/.next/server/app/version/page/server-reference-manifest.json +3 -3
  69. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  70. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  71. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  72. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  73. package/web/.next/server/chunks/ssr/[root-of-the-server]__2138fa7e._.js +2 -2
  74. package/web/.next/server/chunks/ssr/[root-of-the-server]__29580090._.js +1 -1
  75. package/web/.next/server/chunks/ssr/[root-of-the-server]__29580090._.js.map +1 -1
  76. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  77. package/web/.next/server/chunks/ssr/[root-of-the-server]__3ef34e4c._.js +1 -1
  78. package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js +1 -1
  79. package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js.map +1 -1
  80. package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js +1 -1
  81. package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js.map +1 -1
  82. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +2 -2
  83. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
  84. package/web/.next/server/chunks/ssr/[root-of-the-server]__c094882b._.js +1 -1
  85. package/web/.next/server/chunks/ssr/[root-of-the-server]__c094882b._.js.map +1 -1
  86. package/web/.next/server/chunks/ssr/[root-of-the-server]__d48c5b11._.js +1 -1
  87. package/web/.next/server/chunks/ssr/[root-of-the-server]__d48c5b11._.js.map +1 -1
  88. package/web/.next/server/chunks/ssr/[root-of-the-server]__dac5dbf1._.js +1 -1
  89. package/web/.next/server/chunks/ssr/[root-of-the-server]__dac5dbf1._.js.map +1 -1
  90. package/web/.next/server/chunks/ssr/[root-of-the-server]__fae8b355._.js +1 -1
  91. package/web/.next/server/chunks/ssr/[root-of-the-server]__fae8b355._.js.map +1 -1
  92. package/web/.next/server/chunks/ssr/_05c23ad9._.js +3 -0
  93. package/web/.next/server/chunks/ssr/_05c23ad9._.js.map +1 -0
  94. package/web/.next/server/chunks/ssr/_0c5f56e3._.js +2 -2
  95. package/web/.next/server/chunks/ssr/_0c5f56e3._.js.map +1 -1
  96. package/web/.next/server/chunks/ssr/_16eb4fec._.js +3 -0
  97. package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -0
  98. package/web/.next/server/chunks/ssr/_1b719e7f._.js +1 -1
  99. package/web/.next/server/chunks/ssr/_1b719e7f._.js.map +1 -1
  100. package/web/.next/server/chunks/ssr/_37e8548b._.js +1 -1
  101. package/web/.next/server/chunks/ssr/_37e8548b._.js.map +1 -1
  102. package/web/.next/server/chunks/ssr/_55d763e2._.js +1 -1
  103. package/web/.next/server/chunks/ssr/_55d763e2._.js.map +1 -1
  104. package/web/.next/server/chunks/ssr/{_f3428a54._.js → _5b8fb706._.js} +2 -2
  105. package/web/.next/server/chunks/ssr/_5b8fb706._.js.map +1 -0
  106. package/web/.next/server/chunks/ssr/_6256a985._.js +1 -1
  107. package/web/.next/server/chunks/ssr/_6256a985._.js.map +1 -1
  108. package/web/.next/server/chunks/ssr/_64bdfc6f._.js +2 -2
  109. package/web/.next/server/chunks/ssr/_64bdfc6f._.js.map +1 -1
  110. package/web/.next/server/chunks/ssr/_8fcc39d4._.js +1 -1
  111. package/web/.next/server/chunks/ssr/_b71645b4._.js +1 -1
  112. package/web/.next/server/chunks/ssr/_b71645b4._.js.map +1 -1
  113. package/web/.next/server/chunks/ssr/_d8575088._.js +1 -1
  114. package/web/.next/server/chunks/ssr/_d8575088._.js.map +1 -1
  115. package/web/.next/server/chunks/ssr/{_f0507de3._.js → _f107beeb._.js} +2 -2
  116. package/web/.next/server/chunks/ssr/{_f0507de3._.js.map → _f107beeb._.js.map} +1 -1
  117. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  118. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  119. package/web/.next/server/chunks/ssr/{src_presentation_web_3f392ed3._.js → src_presentation_web_45c48864._.js} +2 -2
  120. package/web/.next/server/chunks/ssr/{src_presentation_web_3f392ed3._.js.map → src_presentation_web_45c48864._.js.map} +1 -1
  121. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js +1 -1
  122. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js.map +1 -1
  123. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js +1 -1
  124. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js.map +1 -1
  125. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
  126. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  127. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  128. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  129. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  130. package/web/.next/server/pages/500.html +2 -2
  131. package/web/.next/server/server-reference-manifest.js +1 -1
  132. package/web/.next/server/server-reference-manifest.json +44 -44
  133. package/web/.next/static/chunks/{96fb06a2ff46e152.js → 0c1931570ddbda79.js} +1 -1
  134. package/web/.next/static/chunks/35c41653b13986bc.js +2 -0
  135. package/web/.next/static/chunks/{00c975ddd2b87528.js → 42488279bdae63fd.js} +1 -1
  136. package/web/.next/static/chunks/4c9fe8d3bc1fd602.js +1 -0
  137. package/web/.next/static/chunks/{64a97bd60c175b9e.js → 54ef314ac56fd086.js} +1 -1
  138. package/web/.next/static/chunks/6c0e70b8cc84c311.js +1 -0
  139. package/web/.next/static/chunks/83f80c9ca4e75993.js +1 -0
  140. package/web/.next/static/chunks/900c7d16e08d15ca.js +1 -0
  141. package/web/.next/static/chunks/95de9b54ce501611.js +1 -0
  142. package/web/.next/static/chunks/{8ff013b5490a9111.js → c62fa72ab130a9b8.js} +1 -1
  143. package/web/.next/static/chunks/d61c239df26c61fd.css +1 -0
  144. package/web/.next/static/chunks/{86bc398562d84b1d.js → f78db0e3d11e9784.js} +2 -2
  145. package/web/.next/static/chunks/fe66b8d9c6951d09.js +1 -0
  146. package/web/.next/server/chunks/ssr/_7dca1882._.js +0 -3
  147. package/web/.next/server/chunks/ssr/_7dca1882._.js.map +0 -1
  148. package/web/.next/server/chunks/ssr/_f3428a54._.js.map +0 -1
  149. package/web/.next/server/chunks/ssr/_f39a1adb._.js +0 -3
  150. package/web/.next/server/chunks/ssr/_f39a1adb._.js.map +0 -1
  151. package/web/.next/static/chunks/0b18c50740356276.css +0 -1
  152. package/web/.next/static/chunks/0ead3bd3449a6efe.js +0 -1
  153. package/web/.next/static/chunks/5afa709c97ad44c3.js +0 -1
  154. package/web/.next/static/chunks/6dad9c4718b9ef1c.js +0 -1
  155. package/web/.next/static/chunks/7558964bf146f27c.js +0 -1
  156. package/web/.next/static/chunks/b3ee28e6d690043f.js +0 -2
  157. package/web/.next/static/chunks/bb466ffb8a013811.js +0 -1
  158. package/web/.next/static/chunks/d8364c7cbc1a8432.js +0 -1
  159. /package/web/.next/static/{i_fav2t7dzinMjPL3vmUY → hfM7RIyngddK5KuJ-47Wj}/_buildManifest.js +0 -0
  160. /package/web/.next/static/{i_fav2t7dzinMjPL3vmUY → hfM7RIyngddK5KuJ-47Wj}/_clientMiddlewareManifest.json +0 -0
  161. /package/web/.next/static/{i_fav2t7dzinMjPL3vmUY → hfM7RIyngddK5KuJ-47Wj}/_ssgManifest.js +0 -0
@@ -6,7 +6,9 @@
6
6
  *
7
7
  * Business Rules:
8
8
  * - Any feature can be archived except those already Archived or Deleting
9
- * - Features with active (non-archived, non-deleted) children cannot be archived
9
+ * - Features with children CAN be archived children visually reconnect to
10
+ * the repository on the canvas but the parent-child relationship is preserved
11
+ * in the database and restored when "Show Archived" is enabled
10
12
  * - The current lifecycle is preserved in previousLifecycle for unarchive restoration
11
13
  * - No git operations or agent cancellations are triggered (archive is non-destructive)
12
14
  */
@@ -1 +1 @@
1
- {"version":3,"file":"archive-feature.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/archive-feature.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;AAEnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAQ1G,qBACa,qBAAqB;IACU,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAAX,WAAW,EAAE,kBAAkB;IAEpF,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CA0CnD"}
1
+ {"version":3,"file":"archive-feature.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/archive-feature.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;AAEnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAQ1G,qBACa,qBAAqB;IACU,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAAX,WAAW,EAAE,kBAAkB;IAEpF,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CA6BnD"}
@@ -6,7 +6,9 @@
6
6
  *
7
7
  * Business Rules:
8
8
  * - Any feature can be archived except those already Archived or Deleting
9
- * - Features with active (non-archived, non-deleted) children cannot be archived
9
+ * - Features with children CAN be archived children visually reconnect to
10
+ * the repository on the canvas but the parent-child relationship is preserved
11
+ * in the database and restored when "Show Archived" is enabled
10
12
  * - The current lifecycle is preserved in previousLifecycle for unarchive restoration
11
13
  * - No git operations or agent cancellations are triggered (archive is non-destructive)
12
14
  */
@@ -46,15 +48,7 @@ let ArchiveFeatureUseCase = class ArchiveFeatureUseCase {
46
48
  throw new Error(`Cannot archive feature "${feature.name}": lifecycle is ${feature.lifecycle}. ` +
47
49
  `Features that are already archived or being deleted cannot be archived.`);
48
50
  }
49
- // 3. Check for active (non-archived, non-deleted) children
50
- const children = await this.featureRepo.findByParentId(feature.id);
51
- const activeChildren = children.filter((c) => c.lifecycle !== SdlcLifecycle.Archived && !c.deletedAt);
52
- if (activeChildren.length > 0) {
53
- const names = activeChildren.map((c) => c.name).join(', ');
54
- throw new Error(`Cannot archive feature "${feature.name}": it has active child features (${names}). ` +
55
- `Archive or delete child features first.`);
56
- }
57
- // 4. Store current lifecycle and transition to Archived
51
+ // 3. Store current lifecycle and transition to Archived
58
52
  const updatedFeature = {
59
53
  ...feature,
60
54
  previousLifecycle: feature.lifecycle,
@@ -1 +1 @@
1
- {"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"AAoCA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA6CnE,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,2CAgeA"}
1
+ {"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA4CnE,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,2CA4kBA"}
@@ -2,16 +2,18 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useState } from 'react';
4
4
  import { Handle, Position } from '@xyflow/react';
5
- import { Plus, Trash2, Zap, Loader2, Globe, RotateCcw, Play, Eye, Archive, ArchiveRestore, } from 'lucide-react';
5
+ import { Plus, Trash2, Zap, ClipboardList, Loader2, Globe, RotateCcw, Play, Square, Eye, Archive, ArchiveRestore, } from 'lucide-react';
6
6
  import { cn } from '../../../lib/utils.js';
7
+ import { ActionButton } from '../../common/action-button/action-button.js';
7
8
  import { Button } from '../../ui/button.js';
8
9
  import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../ui/tooltip.js';
10
+ import { useDeployAction } from '../../../hooks/use-deploy-action.js';
11
+ import { useFeatureFlags } from '../../../hooks/feature-flags-context.js';
9
12
  import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '../../ui/alert-dialog.js';
10
13
  import { DeleteFeatureDialog } from '../../common/delete-feature-dialog/index.js';
11
14
  import { featureNodeStateConfig, lifecycleRunningVerbs, lifecyclePhaseBadge, } from './feature-node-state-config.js';
12
15
  import { getAgentTypeIcon } from './agent-type-icons.js';
13
16
  import { FeatureSessionsDropdown } from './feature-sessions-dropdown.js';
14
- import { DeploymentState } from '../../../../../../packages/core/src/domain/generated/output.js';
15
17
  function AgentIcon({ agentType, className }) {
16
18
  const IconComponent = getAgentTypeIcon(agentType);
17
19
  return _jsx(IconComponent, { className: className });
@@ -57,6 +59,18 @@ export function FeatureNode({ data, selected, }) {
57
59
  const [confirmOpen, setConfirmOpen] = useState(false);
58
60
  const [idCopied, setIdCopied] = useState(false);
59
61
  const [archiveConfirmOpen, setArchiveConfirmOpen] = useState(false);
62
+ const featureFlags = useFeatureFlags();
63
+ const deployTarget = featureFlags.envDeploy && data.repositoryPath && data.branch
64
+ ? {
65
+ targetId: data.featureId,
66
+ targetType: 'feature',
67
+ repositoryPath: data.repositoryPath,
68
+ branch: data.branch,
69
+ }
70
+ : null;
71
+ const deployAction = useDeployAction(deployTarget);
72
+ const isDeployActive = deployAction.status === 'Booting' || deployAction.status === 'Ready';
73
+ const isDeployReady = deployAction.status === 'Ready';
60
74
  return (_jsxs("div", { className: "animate-in fade-in group relative duration-300", children: [data.showHandles ? (_jsx(Handle, { type: "target", position: Position.Left, isConnectable: false, className: "opacity-0!", style: { top: 70 } })) : null, _jsx("div", { className: "absolute top-0 bottom-0 -left-14 flex items-center justify-center pr-3 pl-4 opacity-0 transition-opacity group-hover:opacity-100", onPointerDown: (e) => e.stopPropagation(), children: _jsxs("div", { className: "flex flex-col items-center gap-2", children: [data.onArchive &&
61
75
  data.featureId &&
62
76
  data.state !== 'deleting' &&
@@ -83,7 +97,7 @@ export function FeatureNode({ data, selected, }) {
83
97
  selected &&
84
98
  'border-t-rose-400 border-r-rose-400 border-b-rose-400 dark:border-t-amber-500 dark:border-r-amber-500 dark:border-b-amber-500', selected &&
85
99
  data.state !== 'action-required' &&
86
- 'border-blue-400 dark:border-amber-500/60', data.state === 'deleting' && 'opacity-60', data.state === 'archived' && 'opacity-50'), children: [data.state !== 'creating' ? (_jsx("div", { className: "absolute top-3 right-4", children: _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("span", { "data-testid": "feature-node-phase-badge", className: "flex items-center gap-1.5", children: [_jsx("span", { className: "text-muted-foreground text-[10px]", children: lifecyclePhaseBadge[data.lifecycle].tooltip }), _jsx("span", { className: cn('h-1.5 w-1.5 -translate-y-px rounded-full', lifecyclePhaseBadge[data.lifecycle].dot) })] }) }), _jsxs(TooltipContent, { side: "right", className: "max-w-56", children: [_jsx("p", { className: "font-semibold", children: lifecyclePhaseBadge[data.lifecycle].tooltip }), _jsx("p", { className: "mt-1 text-xs leading-relaxed text-neutral-500", children: lifecyclePhaseBadge[data.lifecycle].description })] })] }) }) })) : null, _jsxs("div", { className: "flex items-center gap-1.5 pr-24", children: [data.agentType ? (_jsx(AgentIcon, { agentType: data.agentType, className: "h-4 w-4 shrink-0" })) : null, _jsx("h3", { className: "min-w-0 truncate text-sm font-bold", children: data.name })] }), data.description ? (_jsx("p", { "data-testid": "feature-node-description", className: "text-muted-foreground mt-1 line-clamp-2 text-xs", children: data.description })) : null, _jsxs("div", { className: "mt-auto pt-2", children: [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}%` } }) })] })) : null, !config.showProgressBar &&
100
+ 'border-blue-400 dark:border-amber-500/60', data.state === 'deleting' && 'opacity-60', data.state === 'archived' && 'opacity-50'), children: [data.state !== 'creating' ? (_jsx("div", { className: "absolute top-3 right-4", children: _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("span", { "data-testid": "feature-node-phase-badge", className: "flex items-center gap-1.5", children: [_jsx("span", { className: "text-muted-foreground text-[10px]", children: lifecyclePhaseBadge[data.lifecycle].tooltip }), _jsx("span", { className: cn('h-1.5 w-1.5 -translate-y-px rounded-full', lifecyclePhaseBadge[data.lifecycle].dot) })] }) }), _jsxs(TooltipContent, { side: "right", className: "max-w-56", children: [_jsx("p", { className: "font-semibold", children: lifecyclePhaseBadge[data.lifecycle].tooltip }), _jsx("p", { className: "mt-1 text-xs leading-relaxed text-neutral-500", children: lifecyclePhaseBadge[data.lifecycle].description })] })] }) }) })) : null, _jsxs("div", { className: "flex items-center gap-1.5 pr-24", children: [data.agentType ? (_jsx(AgentIcon, { agentType: data.agentType, className: "h-4 w-4 shrink-0" })) : null, _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { "data-testid": "feature-node-fast-mode-badge", className: "shrink-0", children: data.fastMode ? (_jsx(Zap, { className: "h-3.5 w-3.5 text-amber-500" })) : (_jsx(ClipboardList, { className: "h-3.5 w-3.5 text-indigo-500" })) }) }), _jsx(TooltipContent, { side: "top", children: data.fastMode ? 'Fast Mode' : 'Spec Driven' })] }) }), _jsx("h3", { className: "min-w-0 truncate text-sm font-bold", children: data.name })] }), data.description ? (_jsx("p", { "data-testid": "feature-node-description", className: "text-muted-foreground mt-1 line-clamp-2 text-xs", children: data.description })) : null, _jsxs("div", { className: "mt-auto pt-2", children: [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}%` } }) })] })) : null, !config.showProgressBar &&
87
101
  ![
88
102
  'deleting',
89
103
  'creating',
@@ -95,24 +109,25 @@ export function FeatureNode({ data, selected, }) {
95
109
  ].includes(data.state) ? (_jsxs("div", { "data-testid": "feature-node-badge", className: "relative flex min-w-0 items-center gap-1.5 text-xs", children: [(() => {
96
110
  const BadgeIcon = getBadgeIcon(data);
97
111
  return _jsx(BadgeIcon, { className: cn('h-3.5 w-3.5 shrink-0', config.badgeClass) });
98
- })(), _jsx("span", { className: cn('translate-y-px truncate text-[11px] font-medium', config.badgeClass), children: getBadgeText(data) })] })) : null, _jsxs("div", { className: "mt-1.5 flex min-h-[26px] items-center justify-between gap-2", children: [_jsxs("div", { className: "flex items-center gap-1.5", style: { transform: 'translateY(1px)' }, children: [data.featureId ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { type: "button", "data-testid": "feature-node-id", className: "nodrag text-muted-foreground/60 hover:text-muted-foreground flex cursor-pointer items-baseline gap-1 font-mono text-[10px] transition-colors active:scale-95", onClick: (e) => {
112
+ })(), _jsx("span", { className: cn('translate-y-px truncate text-[11px] font-medium', config.badgeClass), children: getBadgeText(data) })] })) : null, _jsxs("div", { className: "mt-1.5 flex min-h-[26px] items-center justify-between gap-2", style: { transform: 'translateY(1px)' }, children: [_jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [data.featureId ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "data-testid": "feature-node-id", className: "nodrag text-muted-foreground/60 hover:text-muted-foreground flex shrink-0 cursor-pointer items-baseline gap-1 font-mono text-[10px] transition-colors active:scale-95", onClick: (e) => {
99
113
  e.stopPropagation();
100
114
  navigator.clipboard.writeText(data.featureId);
101
115
  setIdCopied(true);
102
116
  setTimeout(() => setIdCopied(false), 1500);
103
- }, children: [_jsx("span", { className: "text-muted-foreground/50 font-sans text-[10px]", children: "ID" }), idCopied ? (_jsx("span", { className: "text-emerald-500", children: "Copied!" })) : (data.featureId.slice(0, 6))] }) }), _jsxs(TooltipContent, { side: "top", children: ["Click to copy: ", data.featureId] })] }) })) : null, data.deployment ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": data.deployment.status === DeploymentState.Booting
104
- ? 'Deploying'
105
- : 'Open dev server', "data-testid": "feature-node-deployment-indicator", onClick: (e) => {
106
- e.stopPropagation();
107
- if (data.deployment?.status === DeploymentState.Ready &&
108
- data.deployment.url) {
109
- window.open(data.deployment.url, '_blank', 'noopener,noreferrer');
110
- }
111
- }, className: cn('nodrag', data.deployment.status === DeploymentState.Ready && data.deployment.url
112
- ? 'cursor-pointer opacity-80 transition-opacity hover:opacity-100'
113
- : 'cursor-default'), children: data.deployment.status === DeploymentState.Booting ? (_jsx(Loader2, { className: "h-3 w-3 animate-spin text-blue-500" })) : (_jsx(Globe, { className: "h-3 w-3 text-green-600" })) }) }), _jsx(TooltipContent, { side: "top", children: data.deployment.status === DeploymentState.Booting
114
- ? 'Deploying...'
115
- : (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", children: _jsx(Zap, { className: "h-3 w-3 text-amber-500" }) }) }), _jsx(TooltipContent, { side: "top", children: "Fast Mode" })] }) })) : null, (data.worktreePath ?? data.repositoryPath) ? (_jsx(FeatureSessionsDropdown, { repositoryPath: data.worktreePath ?? data.repositoryPath })) : null] }), data.state === 'deleting' ? (_jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [_jsx(Loader2, { className: "h-3.5 w-3.5 shrink-0 animate-spin text-gray-400" }), _jsx("span", { className: "text-muted-foreground", children: "Deleting\u2026" })] })) : data.state === 'creating' ? (_jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [_jsx(Icon, { className: "h-3.5 w-3.5 shrink-0 animate-spin text-teal-600 dark:text-teal-400" }), _jsx("span", { className: "font-medium text-teal-600 dark:text-teal-400", children: getBadgeText(data) })] })) : data.state === 'running' ? (_jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [_jsx(Icon, { className: "h-3.5 w-3.5 shrink-0 animate-spin text-teal-600 dark:text-teal-400" }), _jsx("span", { className: "font-medium text-teal-600 dark:text-teal-400", children: getBadgeText(data) })] })) : data.state === 'action-required' ? (_jsxs(Button, { variant: "default", size: "xs", "aria-label": getActionRequiredLabel(data), "data-testid": "feature-node-approve-button",
117
+ }, children: idCopied ? (_jsx("span", { className: "text-emerald-500", children: "Copied!" })) : (data.featureId.slice(0, 6)) }) }), _jsxs(TooltipContent, { side: "top", children: ["Click to copy: ", data.featureId] })] }) })) : null, (data.worktreePath ?? data.repositoryPath) ? (_jsx(FeatureSessionsDropdown, { repositoryPath: data.worktreePath ?? data.repositoryPath })) : null, deployTarget && data.state !== 'deleting' && data.state !== 'creating' ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "bg-border h-3 w-px shrink-0" }), isDeployReady ? (
118
+ /* Ready: Globe + URL — Globe morphs to Stop on hover */
119
+ _jsxs("span", { className: "group/deploy nodrag flex min-w-0 items-center gap-1.5", "data-testid": "feature-node-deploy-button", onClick: (e) => e.stopPropagation(), children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": "Stop Dev Server", className: "flex h-5 shrink-0 cursor-pointer items-center justify-center rounded-full transition-colors", onClick: (e) => {
120
+ e.stopPropagation();
121
+ deployAction.stop();
122
+ }, children: deployAction.stopLoading ? (_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin text-red-500" })) : (_jsxs("span", { className: "relative h-3.5 w-3.5", children: [_jsx(Globe, { className: "absolute inset-0 h-3.5 w-3.5 text-green-600 transition-opacity duration-200 group-hover/deploy:opacity-0 dark:text-green-400" }), _jsx(Square, { className: "absolute inset-0 h-3.5 w-3.5 text-red-500 opacity-0 transition-opacity duration-200 group-hover/deploy:opacity-100 dark:text-red-400" })] })) }) }), _jsx(TooltipContent, { side: "top", children: "Stop Dev Server" })] }) }), deployAction.url ? (_jsx("a", { href: deployAction.url, target: "_blank", rel: "noopener noreferrer", "data-testid": "feature-node-deployment-indicator", className: "nodrag min-w-0 truncate text-[10px] text-green-700 hover:underline dark:text-green-400", onClick: (e) => e.stopPropagation(), children: deployAction.url })) : null] })) : isDeployActive ? (
123
+ /* Booting: Stop button + "Starting…" */
124
+ _jsxs("span", { className: "nodrag flex min-w-0 items-center gap-1.5", "data-testid": "feature-node-deploy-button", onClick: (e) => e.stopPropagation(), children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": "Stop Dev Server", className: "flex h-5 shrink-0 cursor-pointer items-center justify-center rounded-full text-red-500 transition-colors hover:text-red-600 dark:text-red-400 dark:hover:text-red-300", onClick: (e) => {
125
+ e.stopPropagation();
126
+ deployAction.stop();
127
+ }, children: deployAction.stopLoading ? (_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" })) : (_jsx(Square, { className: "h-3.5 w-3.5" })) }) }), _jsx(TooltipContent, { side: "top", children: "Stop Dev Server" })] }) }), _jsx("span", { className: "text-muted-foreground animate-pulse text-[10px]", children: "Starting\u2026" })] })) : (
128
+ /* Idle / Error: Play or Retry button */
129
+ _jsxs(_Fragment, { children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: cn('nodrag flex shrink-0 items-center', !deployAction.deployError &&
130
+ '[&_button]:text-green-600 [&_button]:hover:text-green-700 dark:[&_button]:text-green-400 dark:[&_button]:hover:text-green-300'), "data-testid": "feature-node-deploy-button", onClick: (e) => e.stopPropagation(), children: _jsx(ActionButton, { label: deployAction.deployError ? 'Retry' : 'Start Dev Server', onClick: deployAction.deploy, loading: deployAction.deployLoading, error: false, icon: deployAction.deployError ? RotateCcw : Play, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { side: "top", children: deployAction.deployError ? 'Retry Dev Server' : 'Start Dev Server' })] }) }), deployAction.deployError ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "min-w-0 truncate text-[10px] text-red-500", children: "Failed" }) }), _jsx(TooltipContent, { side: "top", className: "max-w-64", children: _jsx("p", { className: "text-xs", children: deployAction.deployError }) })] }) })) : null] }))] })) : null] }), data.state === 'deleting' ? (_jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [_jsx(Loader2, { className: "h-3.5 w-3.5 shrink-0 animate-spin text-gray-400" }), _jsx("span", { className: "text-muted-foreground", children: "Deleting\u2026" })] })) : data.state === 'creating' ? (_jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [_jsx(Icon, { className: "h-3.5 w-3.5 shrink-0 animate-spin text-teal-600 dark:text-teal-400" }), _jsx("span", { className: "font-medium text-teal-600 dark:text-teal-400", children: getBadgeText(data) })] })) : data.state === 'running' ? (_jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [_jsx(Icon, { className: "h-3.5 w-3.5 shrink-0 animate-spin text-teal-600 dark:text-teal-400" }), _jsx("span", { className: "font-medium text-teal-600 dark:text-teal-400", children: getBadgeText(data) })] })) : data.state === 'action-required' ? (_jsxs(Button, { variant: "default", size: "xs", "aria-label": getActionRequiredLabel(data), "data-testid": "feature-node-approve-button",
116
131
  // eslint-disable-next-line @typescript-eslint/no-empty-function -- click bubbles to card's onNodeClick
117
132
  onClick: () => { }, className: "nodrag dark:bg-primary dark:text-primary-foreground dark:hover:bg-primary/90 cursor-pointer bg-neutral-900 text-[11px] text-white hover:bg-neutral-800", children: [_jsx(Eye, { className: "h-3 w-3" }), getActionRequiredLabel(data)] })) : data.state === 'error' && data.onRetry ? (_jsxs(Button, { variant: "outline", size: "xs", "aria-label": "Retry", "data-testid": "feature-node-retry-button", onClick: (e) => {
118
133
  e.stopPropagation();
@@ -1 +1 @@
1
- {"version":3,"file":"feature-sessions-dropdown.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-sessions-dropdown.tsx"],"names":[],"mappings":"AA8BA,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,4BAA4B;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,6EAA6E;IAC7E,mBAAmB,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,KAAK,IAAI,CAAC;CAClF;AAmDD,wBAAgB,uBAAuB,CAAC,EACtC,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,mBAAmB,GACpB,EAAE,4BAA4B,2CAmK9B"}
1
+ {"version":3,"file":"feature-sessions-dropdown.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-sessions-dropdown.tsx"],"names":[],"mappings":"AA8BA,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,4BAA4B;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,6EAA6E;IAC7E,mBAAmB,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,KAAK,IAAI,CAAC;CAClF;AAmDD,wBAAgB,uBAAuB,CAAC,EACtC,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,mBAAmB,GACpB,EAAE,4BAA4B,2CAiK9B"}
@@ -128,9 +128,7 @@ export function FeatureSessionsDropdown({ repositoryPath, className, includeWork
128
128
  }, [doFetch]);
129
129
  const visibleSessions = expanded ? sessions : sessions.slice(0, PREVIEW_COUNT);
130
130
  const hasMore = sessions.length > PREVIEW_COUNT;
131
- return (_jsxs(DropdownMenu, { modal: false, onOpenChange: handleOpenChange, children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs("button", { type: "button", "aria-label": "View sessions", "data-testid": "feature-node-sessions-button", className: cn('nodrag relative flex h-5 cursor-pointer items-center gap-0.5 rounded px-0.5 text-[10px] transition-colors', hasActiveSessions
132
- ? 'text-emerald-600 hover:bg-emerald-50 hover:text-emerald-700'
133
- : 'text-muted-foreground hover:text-foreground hover:bg-muted', className), onClick: stopNodeEvent, onPointerDown: stopNodeEvent, children: [_jsx(History, { className: "h-3 w-3 shrink-0" }), sessions.length > 0 ? (_jsx("span", { "data-testid": "feature-node-sessions-count", children: sessions.length })) : null, hasActiveSessions ? (_jsx("span", { className: "absolute -top-0.5 -right-0.5 h-1.5 w-1.5 rounded-full bg-emerald-500" })) : null] }) }) }), _jsx(TooltipContent, { side: "top", children: hasActiveSessions ? 'Sessions (active)' : 'Sessions' })] }) }), _jsxs(DropdownMenuContent, { align: "start", side: "bottom", className: "w-80", onClick: stopNodeEvent, onPointerDown: stopNodeEvent, children: [_jsxs(DropdownMenuLabel, { className: "flex items-center gap-1.5 text-xs", children: [_jsx(History, { className: "h-3 w-3" }), "Agent Sessions"] }), _jsx(DropdownMenuSeparator, {}), loading ? (_jsxs("div", { className: "text-muted-foreground flex items-center justify-center gap-2 py-4 text-xs", children: [_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }), "Loading..."] })) : sessions.length === 0 ? (_jsx("div", { className: "text-muted-foreground py-4 text-center text-xs", children: "No sessions found" })) : (_jsxs(_Fragment, { children: [visibleSessions.map((session) => (_jsx(SessionRow, { session: session, repositoryPath: repositoryPath, onCreateFromSession: onCreateFromSession }, session.id))), hasMore ? (_jsxs(DropdownMenuItem, { className: "text-muted-foreground justify-center gap-1 py-1.5 text-[10px]", onClick: (e) => {
131
+ return (_jsxs(DropdownMenu, { modal: false, onOpenChange: handleOpenChange, children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs("button", { type: "button", "aria-label": "View sessions", "data-testid": "feature-node-sessions-button", className: cn('nodrag relative flex h-5 cursor-pointer items-center gap-0.5 rounded px-0.5 text-[10px] transition-colors', 'text-muted-foreground hover:text-foreground hover:bg-muted', className), onClick: stopNodeEvent, onPointerDown: stopNodeEvent, children: [_jsx(History, { className: "h-3 w-3 shrink-0" }), sessions.length > 0 ? (_jsx("span", { "data-testid": "feature-node-sessions-count", children: sessions.length })) : null, hasActiveSessions ? (_jsx("span", { className: "absolute -top-0.5 -right-0.5 h-1.5 w-1.5 rounded-full bg-emerald-500" })) : null] }) }) }), _jsx(TooltipContent, { side: "top", children: hasActiveSessions ? 'Sessions (active)' : 'Sessions' })] }) }), _jsxs(DropdownMenuContent, { align: "start", side: "bottom", className: "w-80", onClick: stopNodeEvent, onPointerDown: stopNodeEvent, children: [_jsxs(DropdownMenuLabel, { className: "flex items-center gap-1.5 text-xs", children: [_jsx(History, { className: "h-3 w-3" }), "Agent Sessions"] }), _jsx(DropdownMenuSeparator, {}), loading ? (_jsxs("div", { className: "text-muted-foreground flex items-center justify-center gap-2 py-4 text-xs", children: [_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }), "Loading..."] })) : sessions.length === 0 ? (_jsx("div", { className: "text-muted-foreground py-4 text-center text-xs", children: "No sessions found" })) : (_jsxs(_Fragment, { children: [visibleSessions.map((session) => (_jsx(SessionRow, { session: session, repositoryPath: repositoryPath, onCreateFromSession: onCreateFromSession }, session.id))), hasMore ? (_jsxs(DropdownMenuItem, { className: "text-muted-foreground justify-center gap-1 py-1.5 text-[10px]", onClick: (e) => {
134
132
  e.preventDefault();
135
133
  setExpanded((v) => !v);
136
134
  }, children: [_jsx(ChevronDown, { className: cn('h-3 w-3 transition-transform', expanded && 'rotate-180') }), expanded ? 'Show less' : `Show ${sessions.length - PREVIEW_COUNT} more`] })) : null] }))] })] }));
@@ -1 +1 @@
1
- {"version":3,"file":"app-sidebar.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/layouts/app-sidebar/app-sidebar.tsx"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAI/E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,YAAY,EAAE,iBAAiB,CAAC;IAEhC,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,YAAY,EAEZ,cAAc,GACf,EAAE,eAAe,2CA6MjB"}
1
+ {"version":3,"file":"app-sidebar.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/layouts/app-sidebar/app-sidebar.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAI/E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,YAAY,EAAE,iBAAiB,CAAC;IAEhC,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,YAAY,EAEZ,cAAc,GACf,EAAE,eAAe,2CAoMjB"}
@@ -1,7 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { usePathname } from 'next/navigation';
4
- import Link from 'next/link';
5
4
  import { Home, Moon, Sun, Volume2, VolumeOff, Wrench, Puzzle, Settings } from 'lucide-react';
6
5
  import { Sidebar, SidebarHeader, SidebarContent, SidebarFooter, SidebarMenu, SidebarMenuItem, SidebarMenuButton, SidebarRail, useSidebar, } from '../../ui/sidebar.js';
7
6
  import { ScrollArea } from '../../ui/scroll-area.js';
@@ -39,39 +38,39 @@ export function AppSidebar({ features, featureFlags, onFeatureClick, }) {
39
38
  'flex min-w-0 flex-1 items-center gap-2 overflow-hidden px-2',
40
39
  'transition-opacity duration-200 ease-out',
41
40
  expandedVisible ? 'opacity-100' : 'opacity-0',
42
- ].join(' '), "aria-hidden": !expandedVisible, children: [_jsx(ShepLogo, { className: "shrink-0", size: 20, variant: versionData.isDev ? 'dev' : 'default' }), _jsx("span", { className: "truncate text-sm font-semibold tracking-tight", children: "Shep" }), _jsx(VersionBadge, { version: versionData.version, branch: versionData.branch || undefined, commitHash: versionData.commitHash || undefined, isDev: versionData.isDev, packageName: versionData.packageName, description: versionData.description, instancePath: versionData.instancePath || undefined })] })) : null, _jsx(SidebarCollapseToggle, { className: "shrink-0 transition-all duration-200" })] }) }), _jsx(SidebarNavItem, { icon: Home, label: "Control Center", href: "/", active: pathname === '/' }), _jsx(SidebarNavItem, { icon: Wrench, label: "Tools", href: "/tools", active: pathname === '/tools' }), featureFlags.skills ? (_jsx(SidebarNavItem, { icon: Puzzle, label: "Skills", href: "/skills", active: pathname === '/skills' })) : null] }) }), _jsx(SidebarContent, { children: showExpanded ? (_jsxs("div", { className: [
41
+ ].join(' '), "aria-hidden": !expandedVisible, children: [_jsx(ShepLogo, { className: "shrink-0", size: 20, variant: versionData.isDev ? 'dev' : 'default' }), _jsx("span", { className: "truncate text-sm font-semibold tracking-tight", children: "Shep" }), _jsx(VersionBadge, { version: versionData.version, branch: versionData.branch || undefined, commitHash: versionData.commitHash || undefined, isDev: versionData.isDev, packageName: versionData.packageName, description: versionData.description, instancePath: versionData.instancePath || undefined })] })) : null, _jsx(SidebarCollapseToggle, { className: "shrink-0 transition-all duration-200" })] }) }), _jsx(SidebarNavItem, { icon: Home, label: "Control Center", href: "/", active: pathname === '/' }), _jsx(SidebarNavItem, { icon: Wrench, label: "Tools", href: "/tools", active: pathname === '/tools' }), featureFlags.skills ? (_jsx(SidebarNavItem, { icon: Puzzle, label: "Skills", href: "/skills", active: pathname === '/skills' })) : null, _jsx(SidebarNavItem, { icon: Settings, label: "Settings", href: "/settings", active: pathname === '/settings' })] }) }), _jsx(SidebarContent, { children: showExpanded ? (_jsxs("div", { className: [
43
42
  'flex min-h-0 flex-1 flex-col overflow-hidden transition-opacity duration-200 ease-out',
44
43
  '[&_[data-sidebar=group-label]]:!mt-0 [&_[data-sidebar=group-label]]:!opacity-100 [&_[data-sidebar=group-label]]:!transition-none',
45
44
  expandedVisible ? 'opacity-100' : 'opacity-0',
46
- ].join(' '), children: [_jsx(SidebarSectionHeader, { label: "Features" }), _jsx(ScrollArea, { className: "min-h-0 flex-1", children: grouped.map(({ key, label, items }) => items.length > 0 ? (_jsx(FeatureStatusGroup, { label: label, count: items.length, children: items.map((feature) => (_jsx(FeatureListItem, { name: feature.name, status: feature.status, startedAt: feature.startedAt, duration: feature.duration, agentType: feature.agentType, modelId: feature.modelId, onClick: onFeatureClick ? () => onFeatureClick(feature.featureId) : undefined }, feature.featureId))) }, key)) : null) })] })) : null }), _jsx(SidebarFooter, { className: "border-t p-2", children: _jsx(SidebarMenu, { children: _jsx(SidebarMenuItem, { children: _jsxs("div", { className: "flex items-center gap-1", children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(SidebarMenuButton, { asChild: true, tooltip: "Settings", className: "w-auto flex-none", children: _jsx(Link, { href: '/settings', onClick: () => clickSound.play(), children: _jsx(Settings, { className: "h-4 w-4" }) }) }) }), _jsx(TooltipContent, { side: "top", hidden: collapsed, children: "Settings" })] }) }), !collapsed && _jsx("div", { className: "flex-1" }), !collapsed && (_jsxs(TooltipProvider, { children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(SidebarMenuButton, { className: "w-auto flex-none", onClick: () => {
47
- clickSound.play();
48
- toggleSound();
49
- }, "aria-label": soundEnabled ? 'Mute sounds' : 'Unmute sounds', children: soundEnabled ? (_jsx(Volume2, { className: "h-4 w-4" })) : (_jsx(VolumeOff, { className: "h-4 w-4" })) }) }), _jsx(TooltipContent, { side: "top", children: soundEnabled ? 'Mute sounds' : 'Unmute sounds' })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs(SidebarMenuButton, { className: "w-auto flex-none", onClick: (e) => {
50
- const currentResolved = theme === 'system' ? resolvedTheme : theme;
51
- const goingToDark = currentResolved !== 'dark';
52
- const newTheme = theme === 'system'
53
- ? resolvedTheme === 'dark'
54
- ? 'light'
55
- : 'dark'
56
- : theme === 'dark'
57
- ? 'light'
58
- : 'dark';
59
- if (goingToDark) {
60
- toggleOnSound.play();
61
- }
62
- else {
63
- toggleOffSound.play();
64
- }
65
- const prefersReducedMotion = typeof window !== 'undefined' &&
66
- window.matchMedia('(prefers-reduced-motion: reduce)').matches;
67
- if (!('startViewTransition' in document) || prefersReducedMotion) {
68
- setTheme(newTheme);
69
- return;
70
- }
71
- document.documentElement.style.setProperty('--x', `${e.clientX}px`);
72
- document.documentElement.style.setProperty('--y', `${e.clientY}px`);
73
- document.startViewTransition(() => {
74
- setTheme(newTheme);
75
- });
76
- }, "aria-label": `Switch to ${resolvedTheme === 'dark' ? 'light' : 'dark'} mode`, children: [_jsx(Sun, { className: "h-4 w-4 scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" }), _jsx(Moon, { className: "absolute h-4 w-4 scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0" })] }) }), _jsx(TooltipContent, { side: "top", children: resolvedTheme === 'dark' ? 'Light mode' : 'Dark mode' })] })] }))] }) }) }) }), _jsx(SidebarRail, {})] }));
45
+ ].join(' '), children: [_jsx(SidebarSectionHeader, { label: "Features" }), _jsx(ScrollArea, { className: "min-h-0 flex-1", children: grouped.map(({ key, label, items }) => items.length > 0 ? (_jsx(FeatureStatusGroup, { label: label, count: items.length, children: items.map((feature) => (_jsx(FeatureListItem, { name: feature.name, status: feature.status, startedAt: feature.startedAt, duration: feature.duration, agentType: feature.agentType, modelId: feature.modelId, onClick: onFeatureClick ? () => onFeatureClick(feature.featureId) : undefined }, feature.featureId))) }, key)) : null) })] })) : null }), _jsx(SidebarFooter, { className: "border-t p-2", children: _jsx(SidebarMenu, { children: _jsx(SidebarMenuItem, { children: _jsx("div", { className: "flex items-center gap-1", children: _jsxs(TooltipProvider, { children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs(SidebarMenuButton, { className: "w-auto flex-none", onClick: (e) => {
46
+ const currentResolved = theme === 'system' ? resolvedTheme : theme;
47
+ const goingToDark = currentResolved !== 'dark';
48
+ const newTheme = theme === 'system'
49
+ ? resolvedTheme === 'dark'
50
+ ? 'light'
51
+ : 'dark'
52
+ : theme === 'dark'
53
+ ? 'light'
54
+ : 'dark';
55
+ if (goingToDark) {
56
+ toggleOnSound.play();
57
+ }
58
+ else {
59
+ toggleOffSound.play();
60
+ }
61
+ const prefersReducedMotion = typeof window !== 'undefined' &&
62
+ window.matchMedia('(prefers-reduced-motion: reduce)').matches;
63
+ if (!('startViewTransition' in document) || prefersReducedMotion) {
64
+ setTheme(newTheme);
65
+ return;
66
+ }
67
+ document.documentElement.style.setProperty('--x', `${e.clientX}px`);
68
+ document.documentElement.style.setProperty('--y', `${e.clientY}px`);
69
+ document.startViewTransition(() => {
70
+ setTheme(newTheme);
71
+ });
72
+ }, "aria-label": `Switch to ${resolvedTheme === 'dark' ? 'light' : 'dark'} mode`, children: [_jsx(Sun, { className: "h-4 w-4 scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" }), _jsx(Moon, { className: "absolute h-4 w-4 scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0" })] }) }), _jsx(TooltipContent, { side: "top", children: resolvedTheme === 'dark' ? 'Light mode' : 'Dark mode' })] }), !collapsed && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(SidebarMenuButton, { className: "w-auto flex-none", onClick: () => {
73
+ clickSound.play();
74
+ toggleSound();
75
+ }, "aria-label": soundEnabled ? 'Mute sounds' : 'Unmute sounds', children: soundEnabled ? (_jsx(Volume2, { className: "h-4 w-4" })) : (_jsx(VolumeOff, { className: "h-4 w-4" })) }) }), _jsx(TooltipContent, { side: "top", children: soundEnabled ? 'Mute sounds' : 'Unmute sounds' })] }))] }) }) }) }) }), _jsx(SidebarRail, {})] }));
77
76
  }
@@ -1 +1 @@
1
- {"version":3,"file":"derive-graph.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/lib/derive-graph.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,qDAAqD;AACrD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,eAAe,CAAC;IACtB,sGAAsG;IACtG,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wDAAwD;AACxD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,kBAAkB,CAAC;CAC1B;AAED,gFAAgF;AAChF,MAAM,WAAW,cAAc;IAC7B,4FAA4F;IAC5F,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,qEAAqE;IACrE,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,8CAA8C;IAC9C,eAAe,CAAC,EAAE,CAChB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,OAAO,EACvB,OAAO,CAAC,EAAE,OAAO,KACd,IAAI,CAAC;IACV,6EAA6E;IAC7E,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,iDAAiD;IACjD,kBAAkB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,qDAAqD;IACrD,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,qDAAqD;IACrD,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,oDAAoD;IACpD,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,iDAAiD;IACjD,kBAAkB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAClD;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACrC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,EAC/B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACrC,SAAS,CAAC,EAAE,cAAc,GACzB;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CA4K5C"}
1
+ {"version":3,"file":"derive-graph.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/lib/derive-graph.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,qDAAqD;AACrD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,eAAe,CAAC;IACtB,sGAAsG;IACtG,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wDAAwD;AACxD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,kBAAkB,CAAC;CAC1B;AAED,gFAAgF;AAChF,MAAM,WAAW,cAAc;IAC7B,4FAA4F;IAC5F,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,qEAAqE;IACrE,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,8CAA8C;IAC9C,eAAe,CAAC,EAAE,CAChB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,OAAO,EACvB,OAAO,CAAC,EAAE,OAAO,KACd,IAAI,CAAC;IACV,6EAA6E;IAC7E,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,iDAAiD;IACjD,kBAAkB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,qDAAqD;IACrD,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,qDAAqD;IACrD,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,oDAAoD;IACpD,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,iDAAiD;IACjD,kBAAkB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAClD;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACrC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,EAC/B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACrC,SAAS,CAAC,EAAE,cAAc,GACzB;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAiL5C"}
@@ -134,7 +134,10 @@ export function deriveGraph(featureMap, repoMap, pendingMap, callbacks) {
134
134
  data,
135
135
  });
136
136
  // Edge derivation
137
- if (entry.parentNodeId) {
137
+ // If parentNodeId references a feature that's not visible (e.g. archived/filtered),
138
+ // fall through to repo→feature edge so the child reconnects to the repository.
139
+ if (entry.parentNodeId &&
140
+ (featureMap.has(entry.parentNodeId) || pendingMap.has(entry.parentNodeId))) {
138
141
  // Dependency edge (parent→child feature)
139
142
  edges.push({
140
143
  id: `dep-${entry.parentNodeId}-${nodeId}`,