@shepai/cli 1.106.3-pr313.abfabce → 1.106.3-pr326.2d86e1d

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 (287) hide show
  1. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
  2. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +2 -2
  3. package/dist/packages/core/src/application/use-cases/repositories/add-repository.use-case.d.ts.map +1 -1
  4. package/dist/packages/core/src/application/use-cases/repositories/add-repository.use-case.js +2 -6
  5. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.js +4 -4
  6. package/dist/packages/core/src/infrastructure/repositories/sqlite-repository.repository.js +4 -4
  7. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.d.ts.map +1 -1
  8. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.js +0 -9
  9. package/dist/packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.d.ts.map +1 -1
  10. package/dist/packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.js +3 -5
  11. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts.map +1 -1
  12. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.js +5 -0
  13. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/evidence-prompts.d.ts.map +1 -1
  14. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/evidence-prompts.js +3 -4
  15. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/repair.node.d.ts.map +1 -1
  16. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/repair.node.js +1 -2
  17. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/schemas/spec.schema.d.ts.map +1 -1
  18. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/schemas/spec.schema.js +6 -1
  19. package/dist/packages/core/src/infrastructure/services/agents/sessions/claude-code-session.repository.js +1 -1
  20. package/dist/packages/core/src/infrastructure/services/attachment-storage.service.js +3 -3
  21. package/dist/packages/core/src/infrastructure/services/deployment/deployment.service.d.ts +1 -1
  22. package/dist/packages/core/src/infrastructure/services/deployment/deployment.service.d.ts.map +1 -1
  23. package/dist/packages/core/src/infrastructure/services/deployment/deployment.service.js +7 -8
  24. package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts.map +1 -1
  25. package/dist/packages/core/src/infrastructure/services/git/worktree.service.js +4 -17
  26. package/dist/packages/core/src/infrastructure/services/ide-launchers/compute-worktree-path.js +1 -1
  27. package/dist/packages/core/src/infrastructure/services/ide-launchers/json-driven-ide-launcher.service.d.ts.map +1 -1
  28. package/dist/packages/core/src/infrastructure/services/ide-launchers/json-driven-ide-launcher.service.js +8 -6
  29. package/dist/packages/core/src/infrastructure/services/tool-installer/tool-installer.service.d.ts.map +1 -1
  30. package/dist/packages/core/src/infrastructure/services/tool-installer/tool-installer.service.js +27 -4
  31. package/dist/packages/core/src/infrastructure/services/tool-installer/tools/alacritty.json +2 -3
  32. package/dist/packages/core/src/infrastructure/services/tool-installer/tools/claude-code.json +2 -3
  33. package/dist/packages/core/src/infrastructure/services/tool-installer/tools/cursor-cli.json +2 -3
  34. package/dist/packages/core/src/infrastructure/services/tool-installer/tools/cursor.json +1 -2
  35. package/dist/packages/core/src/infrastructure/services/tool-installer/tools/gh.json +1 -2
  36. package/dist/packages/core/src/infrastructure/services/tool-installer/tools/git.json +1 -2
  37. package/dist/packages/core/src/infrastructure/services/tool-installer/tools/vscode.json +1 -2
  38. package/dist/packages/core/src/infrastructure/services/tool-installer/tools/warp.json +2 -3
  39. package/dist/packages/core/src/infrastructure/services/tool-installer/tools/windsurf.json +2 -3
  40. package/dist/packages/core/src/infrastructure/services/tool-installer/tools/zed.json +2 -3
  41. package/dist/src/presentation/cli/commands/daemon/start-daemon.d.ts.map +1 -1
  42. package/dist/src/presentation/cli/commands/daemon/start-daemon.js +0 -1
  43. package/dist/src/presentation/cli/commands/daemon/stop-daemon.d.ts.map +1 -1
  44. package/dist/src/presentation/cli/commands/daemon/stop-daemon.js +4 -5
  45. package/dist/src/presentation/cli/commands/upgrade.command.d.ts.map +1 -1
  46. package/dist/src/presentation/cli/commands/upgrade.command.js +0 -4
  47. package/dist/src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/page.d.ts.map +1 -1
  48. package/dist/src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/page.js +5 -48
  49. package/dist/src/presentation/web/app/actions/deploy-repository.d.ts.map +1 -1
  50. package/dist/src/presentation/web/app/actions/deploy-repository.js +1 -2
  51. package/dist/src/presentation/web/app/actions/get-feature-drawer-data.d.ts +8 -0
  52. package/dist/src/presentation/web/app/actions/get-feature-drawer-data.d.ts.map +1 -0
  53. package/dist/src/presentation/web/app/actions/get-feature-drawer-data.js +67 -0
  54. package/dist/src/presentation/web/app/actions/open-folder.d.ts.map +1 -1
  55. package/dist/src/presentation/web/app/actions/open-folder.js +2 -4
  56. package/dist/src/presentation/web/app/actions/open-ide.d.ts.map +1 -1
  57. package/dist/src/presentation/web/app/actions/open-ide.js +1 -2
  58. package/dist/src/presentation/web/app/actions/open-shell.d.ts.map +1 -1
  59. package/dist/src/presentation/web/app/actions/open-shell.js +2 -4
  60. package/dist/src/presentation/web/app/api/graph-data/route.d.ts +14 -0
  61. package/dist/src/presentation/web/app/api/graph-data/route.d.ts.map +1 -0
  62. package/dist/src/presentation/web/app/api/graph-data/route.js +14 -0
  63. package/dist/src/presentation/web/app/build-graph-nodes.d.ts.map +1 -1
  64. package/dist/src/presentation/web/app/build-graph-nodes.js +5 -8
  65. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
  66. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +9 -25
  67. package/dist/src/presentation/web/components/common/control-center-drawer/use-drawer-sync.d.ts +12 -0
  68. package/dist/src/presentation/web/components/common/control-center-drawer/use-drawer-sync.d.ts.map +1 -0
  69. package/dist/src/presentation/web/components/common/control-center-drawer/use-drawer-sync.js +75 -0
  70. package/dist/src/presentation/web/components/common/merge-review/diff-view.js +1 -1
  71. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  72. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +6 -2
  73. package/dist/src/presentation/web/hooks/use-graph-state.d.ts.map +1 -1
  74. package/dist/src/presentation/web/hooks/use-graph-state.js +26 -0
  75. package/dist/src/presentation/web/lib/derive-graph.d.ts.map +1 -1
  76. package/dist/src/presentation/web/lib/derive-graph.js +2 -4
  77. package/dist/tsconfig.build.tsbuildinfo +1 -1
  78. package/package.json +6 -10
  79. package/web/.next/BUILD_ID +1 -1
  80. package/web/.next/app-path-routes-manifest.json +1 -0
  81. package/web/.next/build-manifest.json +2 -2
  82. package/web/.next/fallback-build-manifest.json +2 -2
  83. package/web/.next/prerender-manifest.json +3 -3
  84. package/web/.next/required-server-files.js +1 -1
  85. package/web/.next/required-server-files.json +1 -1
  86. package/web/.next/routes-manifest.json +6 -0
  87. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +38 -53
  88. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +3 -3
  89. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  90. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  91. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +63 -63
  92. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +4 -4
  93. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  94. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  95. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +63 -63
  96. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +4 -4
  97. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  98. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  99. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +34 -49
  100. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +3 -3
  101. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  102. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  103. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +38 -53
  104. package/web/.next/server/app/(dashboard)/create/page.js +3 -3
  105. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  106. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  107. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +63 -63
  108. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +4 -4
  109. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  110. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  111. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +63 -63
  112. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +4 -4
  113. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  114. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  115. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +34 -49
  116. package/web/.next/server/app/(dashboard)/page.js +3 -3
  117. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  118. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  119. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +34 -49
  120. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +3 -3
  121. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  122. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  123. package/web/.next/server/app/_global-error.html +2 -2
  124. package/web/.next/server/app/_global-error.rsc +1 -1
  125. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  126. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  127. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  128. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  129. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  130. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  131. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  132. package/web/.next/server/app/api/agent-events/route.js +1 -2
  133. package/web/.next/server/app/api/agent-events/route.js.nft.json +1 -1
  134. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  135. package/web/.next/server/app/api/attachments/upload-from-path/route.js +1 -1
  136. package/web/.next/server/app/api/attachments/upload-from-path/route.js.nft.json +1 -1
  137. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  138. package/web/.next/server/app/api/feature-logs/route.js +1 -1
  139. package/web/.next/server/app/api/feature-logs/route.js.nft.json +1 -1
  140. package/web/.next/server/app/api/graph-data/route/app-paths-manifest.json +3 -0
  141. package/web/.next/server/app/api/graph-data/route/build-manifest.json +11 -0
  142. package/web/.next/server/app/api/graph-data/route/server-reference-manifest.json +4 -0
  143. package/web/.next/server/app/api/graph-data/route.js +8 -0
  144. package/web/.next/server/app/api/graph-data/route.js.map +5 -0
  145. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -0
  146. package/web/.next/server/app/api/graph-data/route_client-reference-manifest.js +2 -0
  147. package/web/.next/server/app/settings/page/server-reference-manifest.json +5 -5
  148. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  149. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  150. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  151. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  152. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  153. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  154. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  155. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  156. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  157. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  158. package/web/.next/server/app-paths-manifest.json +1 -0
  159. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +3 -0
  160. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +1 -0
  161. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_graph-data_route_actions_26df8a4e.js +3 -0
  162. package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_graph-data_route_actions_26df8a4e.js.map +1 -0
  163. package/web/.next/server/chunks/[root-of-the-server]__7d5492a0._.js +3 -0
  164. package/web/.next/server/chunks/[root-of-the-server]__7d5492a0._.js.map +1 -0
  165. package/web/.next/server/chunks/{[root-of-the-server]__db04ed44._.js → [root-of-the-server]__a5879003._.js} +2 -2
  166. package/web/.next/server/chunks/[root-of-the-server]__aae14de3._.js +6 -0
  167. package/web/.next/server/chunks/[root-of-the-server]__aae14de3._.js.map +1 -0
  168. package/web/.next/server/chunks/{[root-of-the-server]__91d44424._.js → [root-of-the-server]__d8037e14._.js} +2 -2
  169. package/web/.next/server/chunks/[root-of-the-server]__f47bb8a5._.js +1 -1
  170. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  171. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  172. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_7fc19e0a.js +3 -0
  173. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_7fc19e0a.js.map +1 -0
  174. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_c3aca900.js +3 -0
  175. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_c3aca900.js.map +1 -0
  176. package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js +1 -1
  177. package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js.map +1 -1
  178. package/web/.next/server/chunks/ssr/[root-of-the-server]__13dc8e37._.js +3 -0
  179. package/web/.next/server/chunks/ssr/[root-of-the-server]__13dc8e37._.js.map +1 -0
  180. package/web/.next/server/chunks/ssr/[root-of-the-server]__24dd0927._.js +2 -2
  181. package/web/.next/server/chunks/ssr/[root-of-the-server]__24dd0927._.js.map +1 -1
  182. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  183. package/web/.next/server/chunks/ssr/[root-of-the-server]__3a2d3067._.js +3 -0
  184. package/web/.next/server/chunks/ssr/[root-of-the-server]__3a2d3067._.js.map +1 -0
  185. package/web/.next/server/chunks/ssr/[root-of-the-server]__5d87af2e._.js +1 -1
  186. package/web/.next/server/chunks/ssr/[root-of-the-server]__5f776c10._.js +3 -0
  187. package/web/.next/server/chunks/ssr/[root-of-the-server]__5f776c10._.js.map +1 -0
  188. package/web/.next/server/chunks/ssr/[root-of-the-server]__684a868c._.js +3 -0
  189. package/web/.next/server/chunks/ssr/[root-of-the-server]__684a868c._.js.map +1 -0
  190. package/web/.next/server/chunks/ssr/[root-of-the-server]__845a9d2a._.js +1 -1
  191. package/web/.next/server/chunks/ssr/[root-of-the-server]__845a9d2a._.js.map +1 -1
  192. package/web/.next/server/chunks/ssr/[root-of-the-server]__89e8a5cc._.js +2 -2
  193. package/web/.next/server/chunks/ssr/[root-of-the-server]__89e8a5cc._.js.map +1 -1
  194. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +2 -2
  195. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
  196. package/web/.next/server/chunks/ssr/[root-of-the-server]__c03a4370._.js +3 -0
  197. package/web/.next/server/chunks/ssr/[root-of-the-server]__c03a4370._.js.map +1 -0
  198. package/web/.next/server/chunks/ssr/[root-of-the-server]__c16bf5de._.js +3 -0
  199. package/web/.next/server/chunks/ssr/[root-of-the-server]__c16bf5de._.js.map +1 -0
  200. package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js +1 -1
  201. package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js.map +1 -1
  202. package/web/.next/server/chunks/ssr/{_f670aa83._.js → _09345032._.js} +2 -2
  203. package/web/.next/server/chunks/ssr/{_f670aa83._.js.map → _09345032._.js.map} +1 -1
  204. package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
  205. package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
  206. package/web/.next/server/chunks/ssr/{_108decd8._.js → _148140cb._.js} +2 -2
  207. package/web/.next/server/chunks/ssr/{_108decd8._.js.map → _148140cb._.js.map} +1 -1
  208. package/web/.next/server/chunks/ssr/{_6e08ce21._.js → _250a63ae._.js} +2 -2
  209. package/web/.next/server/chunks/ssr/_250a63ae._.js.map +1 -0
  210. package/web/.next/server/chunks/ssr/{_81ef065f._.js → _350fda95._.js} +2 -2
  211. package/web/.next/server/chunks/ssr/{_81ef065f._.js.map → _350fda95._.js.map} +1 -1
  212. package/web/.next/server/chunks/ssr/_8dacd1e7._.js +1 -1
  213. package/web/.next/server/chunks/ssr/_8dacd1e7._.js.map +1 -1
  214. package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
  215. package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
  216. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  217. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  218. package/web/.next/server/chunks/ssr/{src_presentation_web_758dfa10._.js → src_presentation_web_9f444130._.js} +3 -3
  219. package/web/.next/server/chunks/ssr/{src_presentation_web_7275ce5d._.js.map → src_presentation_web_9f444130._.js.map} +1 -1
  220. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_85d37ebe.js +3 -0
  221. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_85d37ebe.js.map +1 -0
  222. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
  223. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
  224. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
  225. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
  226. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +3 -0
  227. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +1 -0
  228. package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
  229. package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
  230. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  231. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  232. package/web/.next/server/chunks/ssr/{src_presentation_web_7275ce5d._.js → src_presentation_web_d7392251._.js} +3 -3
  233. package/web/.next/server/chunks/ssr/{src_presentation_web_758dfa10._.js.map → src_presentation_web_d7392251._.js.map} +1 -1
  234. package/web/.next/server/pages/500.html +2 -2
  235. package/web/.next/server/server-reference-manifest.js +1 -1
  236. package/web/.next/server/server-reference-manifest.json +250 -285
  237. package/web/.next/static/chunks/{2cb83dffa602deb2.js → 0142224c5471ee38.js} +1 -1
  238. package/web/.next/static/chunks/{f2834ca4ebf67578.js → 125326eff68aa819.js} +1 -1
  239. package/web/.next/static/chunks/41c6f0c0a51d55c0.js +1 -0
  240. package/web/.next/static/chunks/{1fb5ef23a07eedff.js → 4ea34a453fed162c.js} +2 -2
  241. package/web/.next/static/chunks/{7ddfbb777910453d.js → 6c1aca2a14151ad0.js} +1 -1
  242. package/web/.next/static/chunks/{4f7d94b3a737e36f.js → a126ccd4e7c0ff4b.js} +1 -1
  243. package/web/.next/static/chunks/{b0775436a5af718e.js → b01b8b69f482e41e.js} +1 -1
  244. package/web/.next/static/chunks/b744fa8c0ec5f4ef.js +1 -0
  245. package/web/.next/static/chunks/{21c55bb651a76161.js → be1de18677065920.js} +1 -1
  246. package/web/.next/static/chunks/{7162051bef25e2e1.js → f59bd516c57406f7.js} +1 -1
  247. package/dist/packages/core/src/infrastructure/services/process/tree-kill.d.ts +0 -12
  248. package/dist/packages/core/src/infrastructure/services/process/tree-kill.d.ts.map +0 -1
  249. package/dist/packages/core/src/infrastructure/services/process/tree-kill.js +0 -11
  250. package/dist/packages/core/src/infrastructure/services/tool-installer/binary-exists.d.ts +0 -25
  251. package/dist/packages/core/src/infrastructure/services/tool-installer/binary-exists.d.ts.map +0 -1
  252. package/dist/packages/core/src/infrastructure/services/tool-installer/binary-exists.js +0 -32
  253. package/dist/src/presentation/web/app/actions/get-graph-data.d.ts +0 -10
  254. package/dist/src/presentation/web/app/actions/get-graph-data.d.ts.map +0 -1
  255. package/dist/src/presentation/web/app/actions/get-graph-data.js +0 -10
  256. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js +0 -6
  257. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js.map +0 -1
  258. package/web/.next/server/chunks/[root-of-the-server]__3b22a1eb._.js +0 -3
  259. package/web/.next/server/chunks/[root-of-the-server]__3b22a1eb._.js.map +0 -1
  260. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_0a7546ed.js +0 -3
  261. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_0a7546ed.js.map +0 -1
  262. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_978cbb4c.js +0 -3
  263. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_978cbb4c.js.map +0 -1
  264. package/web/.next/server/chunks/ssr/[root-of-the-server]__51fc98b0._.js +0 -3
  265. package/web/.next/server/chunks/ssr/[root-of-the-server]__51fc98b0._.js.map +0 -1
  266. package/web/.next/server/chunks/ssr/[root-of-the-server]__57f37786._.js +0 -3
  267. package/web/.next/server/chunks/ssr/[root-of-the-server]__57f37786._.js.map +0 -1
  268. package/web/.next/server/chunks/ssr/[root-of-the-server]__708dcad1._.js +0 -3
  269. package/web/.next/server/chunks/ssr/[root-of-the-server]__708dcad1._.js.map +0 -1
  270. package/web/.next/server/chunks/ssr/[root-of-the-server]__8e002910._.js +0 -3
  271. package/web/.next/server/chunks/ssr/[root-of-the-server]__8e002910._.js.map +0 -1
  272. package/web/.next/server/chunks/ssr/[root-of-the-server]__94128fa9._.js +0 -3
  273. package/web/.next/server/chunks/ssr/[root-of-the-server]__94128fa9._.js.map +0 -1
  274. package/web/.next/server/chunks/ssr/[root-of-the-server]__9bfb8e7c._.js +0 -3
  275. package/web/.next/server/chunks/ssr/[root-of-the-server]__9bfb8e7c._.js.map +0 -1
  276. package/web/.next/server/chunks/ssr/_6e08ce21._.js.map +0 -1
  277. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_84803221.js +0 -3
  278. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_84803221.js.map +0 -1
  279. package/web/.next/server/chunks/ssr/src_presentation_web_app_(dashboard)_get-graph-data_ts_b018483e._.js +0 -3
  280. package/web/.next/server/chunks/ssr/src_presentation_web_app_(dashboard)_get-graph-data_ts_b018483e._.js.map +0 -1
  281. package/web/.next/static/chunks/3e9ca120ef3e87f7.js +0 -1
  282. package/web/.next/static/chunks/8c4b8d1a0413110b.js +0 -1
  283. /package/web/.next/server/chunks/{[root-of-the-server]__db04ed44._.js.map → [root-of-the-server]__a5879003._.js.map} +0 -0
  284. /package/web/.next/server/chunks/{[root-of-the-server]__91d44424._.js.map → [root-of-the-server]__d8037e14._.js.map} +0 -0
  285. /package/web/.next/static/{7-yWjWhzRKPhBueBlEPSZ → kzC4UZpGoyGxtfEZ-FWzG}/_buildManifest.js +0 -0
  286. /package/web/.next/static/{7-yWjWhzRKPhBueBlEPSZ → kzC4UZpGoyGxtfEZ-FWzG}/_clientMiddlewareManifest.json +0 -0
  287. /package/web/.next/static/{7-yWjWhzRKPhBueBlEPSZ → kzC4UZpGoyGxtfEZ-FWzG}/_ssgManifest.js +0 -0
@@ -11,8 +11,7 @@
11
11
  "packageManager": "apt",
12
12
  "commands": {
13
13
  "linux": "(type -p wget >/dev/null || (sudo apt update && sudo apt-get install wget -y)) && sudo mkdir -p -m 755 /etc/apt/keyrings && out=$(mktemp) && wget -nv -O$out https://cli.github.com/packages/githubcli-archive-keyring.gpg && cat $out | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null && sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg && echo \"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main\" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null && sudo apt update && sudo apt install gh -y",
14
- "darwin": "brew install gh",
15
- "win32": "winget install --id GitHub.cli -e --source winget"
14
+ "darwin": "brew install gh"
16
15
  },
17
16
  "timeout": 300000,
18
17
  "documentationUrl": "https://cli.github.com/manual/",
@@ -11,8 +11,7 @@
11
11
  "packageManager": "apt",
12
12
  "commands": {
13
13
  "linux": "sudo apt-get update && sudo apt-get install -y git",
14
- "darwin": "xcode-select --install",
15
- "win32": "winget install --id Git.Git -e --source winget"
14
+ "darwin": "xcode-select --install"
16
15
  },
17
16
  "timeout": 300000,
18
17
  "documentationUrl": "https://git-scm.com/doc",
@@ -11,8 +11,7 @@
11
11
  "packageManager": "apt",
12
12
  "commands": {
13
13
  "linux": "curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | sudo gpg --yes --dearmor -o /usr/share/keyrings/packages.microsoft.gpg && echo \"deb [arch=amd64 signed-by=/usr/share/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main\" | sudo tee /etc/apt/sources.list.d/vscode.list > /dev/null && sudo apt-get update && sudo apt-get install -y code",
14
- "darwin": "brew install visual-studio-code",
15
- "win32": "winget install --id Microsoft.VisualStudioCode -e --source winget"
14
+ "darwin": "brew install visual-studio-code"
16
15
  },
17
16
  "timeout": 300000,
18
17
  "documentationUrl": "https://code.visualstudio.com/docs/setup/linux",
@@ -5,13 +5,12 @@
5
5
  "tags": ["terminal"],
6
6
  "author": "Warp",
7
7
  "website": "https://www.warp.dev",
8
- "platforms": ["darwin", "win32"],
8
+ "platforms": ["darwin"],
9
9
  "iconUrl": "https://cdn.simpleicons.org/warp",
10
10
  "binary": "warp",
11
11
  "packageManager": "brew",
12
12
  "commands": {
13
- "darwin": "brew install --cask warp",
14
- "win32": "winget install --id Warp.Warp -e --source winget"
13
+ "darwin": "brew install --cask warp"
15
14
  },
16
15
  "timeout": 300000,
17
16
  "documentationUrl": "https://docs.warp.dev/",
@@ -5,14 +5,13 @@
5
5
  "tags": ["ide"],
6
6
  "author": "Codeium",
7
7
  "website": "https://codeium.com/windsurf",
8
- "platforms": ["linux", "darwin", "win32"],
8
+ "platforms": ["linux", "darwin"],
9
9
  "iconUrl": "https://cdn.simpleicons.org/windsurf",
10
10
  "binary": "windsurf",
11
11
  "packageManager": "apt",
12
12
  "commands": {
13
13
  "linux": "curl -fsSL \"https://windsurf-stable.codeiumdata.com/wVxQEIWkwPUEAGf3/windsurf.gpg\" | sudo gpg --yes --dearmor -o /usr/share/keyrings/windsurf-stable-archive-keyring.gpg && echo \"deb [signed-by=/usr/share/keyrings/windsurf-stable-archive-keyring.gpg arch=amd64] https://windsurf-stable.codeiumdata.com/wVxQEIWkwPUEAGf3/apt stable main\" | sudo tee /etc/apt/sources.list.d/windsurf.list > /dev/null && sudo apt-get update && sudo apt-get install -y windsurf",
14
- "darwin": "brew install --cask windsurf",
15
- "win32": "winget install --id Codeium.Windsurf -e --source winget"
14
+ "darwin": "brew install --cask windsurf"
16
15
  },
17
16
  "timeout": 300000,
18
17
  "documentationUrl": "https://docs.windsurf.com/windsurf/getting-started",
@@ -5,14 +5,13 @@
5
5
  "tags": ["ide"],
6
6
  "author": "Zed Industries",
7
7
  "website": "https://zed.dev",
8
- "platforms": ["linux", "darwin", "win32"],
8
+ "platforms": ["linux", "darwin"],
9
9
  "iconUrl": "https://cdn.simpleicons.org/zedindustries",
10
10
  "binary": "zed",
11
11
  "packageManager": "curl",
12
12
  "commands": {
13
13
  "linux": "curl -f https://zed.dev/install.sh | sh",
14
- "darwin": "curl -f https://zed.dev/install.sh | sh",
15
- "win32": "winget install --id ZedIndustries.Zed -e --source winget"
14
+ "darwin": "curl -f https://zed.dev/install.sh | sh"
16
15
  },
17
16
  "timeout": 300000,
18
17
  "documentationUrl": "https://zed.dev/docs/installation",
@@ -1 +1 @@
1
- {"version":3,"file":"start-daemon.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/daemon/start-daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAoBH,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgG9E"}
1
+ {"version":3,"file":"start-daemon.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/daemon/start-daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAoBH,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+F9E"}
@@ -67,7 +67,6 @@ export async function startDaemon(opts = {}) {
67
67
  const child = spawn(process.execPath, [...process.execArgv, process.argv[1], '_serve', '--port', String(port)], {
68
68
  detached: true,
69
69
  stdio: ['ignore', logFd, logFd],
70
- windowsHide: true,
71
70
  });
72
71
  // Wait briefly for the child to either settle or crash.
73
72
  const exitCode = await Promise.race([
@@ -1 +1 @@
1
- {"version":3,"file":"stop-daemon.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/daemon/stop-daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iEAAiE,CAAC;AA0BtG;;;GAGG;AACH,wBAAsB,UAAU,CAAC,aAAa,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAyC7E"}
1
+ {"version":3,"file":"stop-daemon.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/daemon/stop-daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iEAAiE,CAAC;AA0BtG;;;GAGG;AACH,wBAAsB,UAAU,CAAC,aAAa,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAyC7E"}
@@ -18,7 +18,6 @@
18
18
  *
19
19
  * @param daemonService - IDaemonService instance (injected by caller for testability, NFR-4)
20
20
  */
21
- import { treeKill } from '../../../../../packages/core/src/infrastructure/services/process/tree-kill.js';
22
21
  import { messages } from '../../ui/index.js';
23
22
  const POLL_INTERVAL_MS = 200;
24
23
  const MAX_WAIT_MS = 5000;
@@ -55,15 +54,15 @@ export async function stopDaemon(daemonService) {
55
54
  }
56
55
  try {
57
56
  messages.info(`Stopping Shep daemon (PID ${pid})...`);
58
- // Send SIGTERM to process tree — request graceful shutdown
59
- treeKill(pid, 'SIGTERM');
57
+ // Send SIGTERM — request graceful shutdown
58
+ process.kill(pid, 'SIGTERM');
60
59
  // Poll for up to 5s waiting for the process to exit
61
60
  const died = await pollUntilDead(daemonService, pid, MAX_WAIT_MS, POLL_INTERVAL_MS);
62
61
  if (!died) {
63
- // Graceful shutdown timed out — force kill process tree
62
+ // Graceful shutdown timed out — force kill
64
63
  messages.info('Daemon did not stop gracefully, sending SIGKILL...');
65
64
  try {
66
- treeKill(pid, 'SIGKILL');
65
+ process.kill(pid, 'SIGKILL');
67
66
  }
68
67
  catch {
69
68
  // Process may have exited between the check and the kill — ignore
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade.command.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/cli/commands/upgrade.command.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,IAAI,YAAY,EAAqB,MAAM,oBAAoB,CAAC;AAQ9E,KAAK,OAAO,GAAG,OAAO,YAAY,CAAC;AA8EnC;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,OAAsB,GAAG,OAAO,CA+D7E"}
1
+ {"version":3,"file":"upgrade.command.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/cli/commands/upgrade.command.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,IAAI,YAAY,EAAqB,MAAM,oBAAoB,CAAC;AAQ9E,KAAK,OAAO,GAAG,OAAO,YAAY,CAAC;AAyEnC;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,OAAsB,GAAG,OAAO,CA+D7E"}
@@ -13,8 +13,6 @@ import { messages } from '../ui/index.js';
13
13
  import { stopDaemon } from './daemon/stop-daemon.js';
14
14
  import { startDaemon } from './daemon/start-daemon.js';
15
15
  const VERSION_CHECK_TIMEOUT_MS = 10_000;
16
- /** On Windows, npm is a .cmd batch file — spawn() needs shell: true to resolve it. */
17
- const IS_WINDOWS = process.platform === 'win32';
18
16
  /**
19
17
  * Get the latest published version of @shepai/cli from npm registry.
20
18
  * Returns null if the check fails (fail-open).
@@ -25,7 +23,6 @@ function getLatestVersion(spawnFn) {
25
23
  let settled = false;
26
24
  const child = spawnFn('npm', ['view', '@shepai/cli', 'version'], {
27
25
  stdio: ['ignore', 'pipe', 'pipe'],
28
- ...(IS_WINDOWS && { shell: true }),
29
26
  });
30
27
  const timeout = setTimeout(() => {
31
28
  if (!settled) {
@@ -68,7 +65,6 @@ function runNpmInstall(spawnFn) {
68
65
  return new Promise((resolve, reject) => {
69
66
  const child = spawnFn('npm', ['i', '-g', '@shepai/cli@latest'], {
70
67
  stdio: 'inherit',
71
- ...(IS_WINDOWS && { shell: true }),
72
68
  });
73
69
  child.on('close', (code) => {
74
70
  resolve(code ?? 1);
@@ -1 +1 @@
1
- {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/page.tsx"],"names":[],"mappings":"AAiBA,oEAAoE;AACpE,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,UAAU,sBAAsB;IAC9B,MAAM,EAAE,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxC;AAED,wBAA8B,iBAAiB,CAAC,EAAE,MAAM,EAAE,EAAE,sBAAsB,2DAyEjF"}
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/page.tsx"],"names":[],"mappings":"AAOA,oEAAoE;AACpE,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,UAAU,sBAAsB;IAC9B,MAAM,EAAE,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxC;AAED,wBAA8B,iBAAiB,CAAC,EAAE,MAAM,EAAE,EAAE,sBAAsB,2DAmCjF"}
@@ -1,14 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { resolve } from '../../../../../lib/server-container.js';
3
- import { CiStatus } from '../../../../../../../../packages/core/src/domain/generated/output.js';
4
3
  import { buildFeatureNodeData } from '../../../../build-feature-node-data.js';
5
4
  import { computeDrawerView } from '../../../../../components/common/control-center-drawer/drawer-view.js';
6
5
  import { FeatureDrawerClient } from '../../../../../components/common/control-center-drawer/feature-drawer-client.js';
7
- const CI_STATUS_MAP = {
8
- success: CiStatus.Success,
9
- failure: CiStatus.Failure,
10
- pending: CiStatus.Pending,
11
- };
12
6
  /** Skip static pre-rendering since we need runtime DI container. */
13
7
  export const dynamic = 'force-dynamic';
14
8
  export default async function FeatureDrawerPage({ params }) {
@@ -16,52 +10,15 @@ export default async function FeatureDrawerPage({ params }) {
16
10
  try {
17
11
  const featureRepo = resolve('IFeatureRepository');
18
12
  const agentRunRepo = resolve('IAgentRunRepository');
19
- const repoRepo = resolve('IRepositoryRepository');
20
- const gitPrService = resolve('IGitPrService');
13
+ // Critical path only: feature + agent run (fast DB lookups).
14
+ // Expensive operations (git remote URL, GitHub CI/mergeable status,
15
+ // artifact, repo name, base branch) are deferred to useDrawerSync
16
+ // which runs client-side after the drawer is already visible.
21
17
  const feature = await featureRepo.findById(featureId);
22
18
  if (!feature)
23
19
  return null;
24
20
  const run = feature.agentRunId ? await agentRunRepo.findById(feature.agentRunId) : null;
25
- // Resolve repository name, base branch, and one-liner for the overview tab
26
- const getArtifact = resolve('GetFeatureArtifactUseCase');
27
- const [repo, baseBranch, artifact, remoteUrl, liveMergeable, liveCiResult] = await Promise.all([
28
- repoRepo.findByPath(feature.repositoryPath).catch(() => null),
29
- gitPrService.getDefaultBranch(feature.repositoryPath).catch(() => 'main'),
30
- getArtifact.execute(featureId).catch(() => null),
31
- gitPrService.getRemoteUrl(feature.repositoryPath).catch(() => null),
32
- feature.pr?.number
33
- ? gitPrService
34
- .getMergeableStatus(feature.repositoryPath, feature.pr.number)
35
- .catch(() => undefined)
36
- : Promise.resolve(undefined),
37
- feature.branch
38
- ? gitPrService.getCiStatus(feature.repositoryPath, feature.branch).catch(() => undefined)
39
- : Promise.resolve(undefined),
40
- ]);
41
- // Merge live PR status into feature data so the UI always reflects
42
- // the current GitHub state, even if the background watcher hasn't polled yet.
43
- if (feature.pr) {
44
- const liveCiStatus = liveCiResult
45
- ? (CI_STATUS_MAP[liveCiResult.status] ?? CiStatus.Pending)
46
- : undefined;
47
- const updates = {};
48
- if (liveMergeable !== undefined)
49
- updates.mergeable = liveMergeable;
50
- if (liveCiStatus !== undefined)
51
- updates.ciStatus = liveCiStatus;
52
- if (Object.keys(updates).length > 0) {
53
- feature.pr = { ...feature.pr, ...updates };
54
- featureRepo.update(feature).catch(() => {
55
- /* best-effort persist */
56
- });
57
- }
58
- }
59
- const nodeData = buildFeatureNodeData(feature, run, {
60
- repositoryName: repo?.name,
61
- baseBranch,
62
- oneLiner: artifact?.oneLiner,
63
- remoteUrl: remoteUrl ?? undefined,
64
- });
21
+ const nodeData = buildFeatureNodeData(feature, run);
65
22
  const view = computeDrawerView({
66
23
  selectedNode: nodeData,
67
24
  isCreateDrawerOpen: false,
@@ -1 +1 @@
1
- {"version":3,"file":"deploy-repository.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/deploy-repository.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAIvE,wBAAsB,gBAAgB,CACpC,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,eAAe,CAAA;CAAE,CAAC,CAyBxE"}
1
+ {"version":3,"file":"deploy-repository.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/deploy-repository.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAIvE,wBAAsB,gBAAgB,CACpC,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,eAAe,CAAA;CAAE,CAAC,CAyBxE"}
@@ -1,13 +1,12 @@
1
1
  'use server';
2
2
  import { existsSync } from 'node:fs';
3
- import { isAbsolute } from 'node:path';
4
3
  import { resolve } from '../../lib/server-container.js';
5
4
  import { createDeploymentLogger } from '../../../../../packages/core/src/infrastructure/services/deployment/deployment-logger.js';
6
5
  import { DeploymentState } from '../../../../../packages/core/src/domain/generated/output.js';
7
6
  const log = createDeploymentLogger('[deployRepository]');
8
7
  export async function deployRepository(repositoryPath) {
9
8
  log.info(`called — repositoryPath="${repositoryPath}"`);
10
- if (!repositoryPath || !isAbsolute(repositoryPath)) {
9
+ if (!repositoryPath?.startsWith('/')) {
11
10
  log.warn('rejected — not an absolute path');
12
11
  return { success: false, error: 'repositoryPath must be an absolute path' };
13
12
  }
@@ -0,0 +1,8 @@
1
+ import type { FeatureNodeData } from '../../components/common/feature-node/index.js';
2
+ /**
3
+ * Fetches full FeatureNodeData for a given feature ID.
4
+ * Used by the drawer for targeted data syncing without triggering
5
+ * a full router.refresh() / server component re-render.
6
+ */
7
+ export declare function getFeatureDrawerData(featureId: string): Promise<FeatureNodeData | null>;
8
+ //# sourceMappingURL=get-feature-drawer-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-feature-drawer-data.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/get-feature-drawer-data.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAQxE;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAsD7F"}
@@ -0,0 +1,67 @@
1
+ 'use server';
2
+ import { resolve } from '../../lib/server-container.js';
3
+ import { CiStatus } from '../../../../../packages/core/src/domain/generated/output.js';
4
+ import { buildFeatureNodeData } from '../build-feature-node-data.js';
5
+ const CI_STATUS_MAP = {
6
+ success: CiStatus.Success,
7
+ failure: CiStatus.Failure,
8
+ pending: CiStatus.Pending,
9
+ };
10
+ /**
11
+ * Fetches full FeatureNodeData for a given feature ID.
12
+ * Used by the drawer for targeted data syncing without triggering
13
+ * a full router.refresh() / server component re-render.
14
+ */
15
+ export async function getFeatureDrawerData(featureId) {
16
+ try {
17
+ const featureRepo = resolve('IFeatureRepository');
18
+ const agentRunRepo = resolve('IAgentRunRepository');
19
+ const repoRepo = resolve('IRepositoryRepository');
20
+ const gitPrService = resolve('IGitPrService');
21
+ const getArtifact = resolve('GetFeatureArtifactUseCase');
22
+ const feature = await featureRepo.findById(featureId);
23
+ if (!feature)
24
+ return null;
25
+ const run = feature.agentRunId ? await agentRunRepo.findById(feature.agentRunId) : null;
26
+ const [repo, baseBranch, artifact, remoteUrl, liveMergeable, liveCiResult] = await Promise.all([
27
+ repoRepo.findByPath(feature.repositoryPath).catch(() => null),
28
+ gitPrService.getDefaultBranch(feature.repositoryPath).catch(() => 'main'),
29
+ getArtifact.execute(featureId).catch(() => null),
30
+ gitPrService.getRemoteUrl(feature.repositoryPath).catch(() => null),
31
+ feature.pr?.number
32
+ ? gitPrService
33
+ .getMergeableStatus(feature.repositoryPath, feature.pr.number)
34
+ .catch(() => undefined)
35
+ : Promise.resolve(undefined),
36
+ feature.branch
37
+ ? gitPrService.getCiStatus(feature.repositoryPath, feature.branch).catch(() => undefined)
38
+ : Promise.resolve(undefined),
39
+ ]);
40
+ // Merge live PR status into feature data
41
+ if (feature.pr) {
42
+ const liveCiStatus = liveCiResult
43
+ ? (CI_STATUS_MAP[liveCiResult.status] ?? CiStatus.Pending)
44
+ : undefined;
45
+ const updates = {};
46
+ if (liveMergeable !== undefined)
47
+ updates.mergeable = liveMergeable;
48
+ if (liveCiStatus !== undefined)
49
+ updates.ciStatus = liveCiStatus;
50
+ if (Object.keys(updates).length > 0) {
51
+ feature.pr = { ...feature.pr, ...updates };
52
+ featureRepo.update(feature).catch(() => {
53
+ /* best-effort persist */
54
+ });
55
+ }
56
+ }
57
+ return buildFeatureNodeData(feature, run, {
58
+ repositoryName: repo?.name,
59
+ baseBranch,
60
+ oneLiner: artifact?.oneLiner,
61
+ remoteUrl: remoteUrl ?? undefined,
62
+ });
63
+ }
64
+ catch {
65
+ return null;
66
+ }
67
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"open-folder.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/open-folder.ts"],"names":[],"mappings":"AAiBA,wBAAsB,UAAU,CAC9B,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA8B9D"}
1
+ {"version":3,"file":"open-folder.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/open-folder.ts"],"names":[],"mappings":"AAeA,wBAAsB,UAAU,CAC9B,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA8B9D"}
@@ -1,7 +1,6 @@
1
1
  'use server';
2
2
  import { existsSync } from 'node:fs';
3
3
  import { platform } from 'node:os';
4
- import { isAbsolute } from 'node:path';
5
4
  import { spawn } from 'node:child_process';
6
5
  // Use a record lookup instead of if/else to prevent the bundler from
7
6
  // tree-shaking platform branches at build time. Turbopack evaluates
@@ -10,10 +9,9 @@ import { spawn } from 'node:child_process';
10
9
  const FOLDER_COMMANDS = {
11
10
  darwin: { cmd: 'open', args: (p) => [p] },
12
11
  linux: { cmd: 'xdg-open', args: (p) => [p] },
13
- win32: { cmd: 'explorer', args: (p) => [p] },
14
12
  };
15
13
  export async function openFolder(repositoryPath) {
16
- if (!repositoryPath || !isAbsolute(repositoryPath)) {
14
+ if (!repositoryPath?.startsWith('/')) {
17
15
  return { success: false, error: 'repositoryPath must be an absolute path' };
18
16
  }
19
17
  try {
@@ -24,7 +22,7 @@ export async function openFolder(repositoryPath) {
24
22
  if (!entry) {
25
23
  return {
26
24
  success: false,
27
- error: `Unsupported platform: ${platform()}`,
25
+ error: `Unsupported platform: ${platform()}. Folder open is supported on macOS and Linux only.`,
28
26
  };
29
27
  }
30
28
  const child = spawn(entry.cmd, entry.args(repositoryPath), {
@@ -1 +1 @@
1
- {"version":3,"file":"open-ide.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/open-ide.ts"],"names":[],"mappings":"AAOA,UAAU,YAAY;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,OAAO,CAC3B,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAuB/E"}
1
+ {"version":3,"file":"open-ide.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/open-ide.ts"],"names":[],"mappings":"AAMA,UAAU,YAAY;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,OAAO,CAC3B,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAuB/E"}
@@ -1,10 +1,9 @@
1
1
  'use server';
2
- import { isAbsolute } from 'node:path';
3
2
  import { getSettings } from '../../../../../packages/core/src/infrastructure/services/settings.service.js';
4
3
  import { resolve } from '../../lib/server-container.js';
5
4
  export async function openIde(input) {
6
5
  const { repositoryPath, branch } = input;
7
- if (!repositoryPath || !isAbsolute(repositoryPath)) {
6
+ if (!repositoryPath?.startsWith('/')) {
8
7
  return { success: false, error: 'repositoryPath must be an absolute path' };
9
8
  }
10
9
  const settings = getSettings();
@@ -1 +1 @@
1
- {"version":3,"file":"open-shell.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/open-shell.ts"],"names":[],"mappings":"AAmBA,UAAU,cAAc;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,SAAS,CAC7B,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAoC9E"}
1
+ {"version":3,"file":"open-shell.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/open-shell.ts"],"names":[],"mappings":"AAiBA,UAAU,cAAc;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,SAAS,CAC7B,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAoC9E"}
@@ -1,7 +1,6 @@
1
1
  'use server';
2
2
  import { existsSync } from 'node:fs';
3
3
  import { platform } from 'node:os';
4
- import { isAbsolute } from 'node:path';
5
4
  import { spawn } from 'node:child_process';
6
5
  import { getSettings } from '../../../../../packages/core/src/infrastructure/services/settings.service.js';
7
6
  import { computeWorktreePath } from '../../../../../packages/core/src/infrastructure/services/ide-launchers/compute-worktree-path.js';
@@ -12,11 +11,10 @@ import { computeWorktreePath } from '../../../../../packages/core/src/infrastruc
12
11
  const SHELL_COMMANDS = {
13
12
  darwin: { cmd: 'open', args: (p) => ['-a', 'Terminal', p] },
14
13
  linux: { cmd: 'x-terminal-emulator', args: (p) => [`--working-directory=${p}`] },
15
- win32: { cmd: 'powershell', args: (p) => ['-NoExit', '-Command', `Set-Location "${p}"`] },
16
14
  };
17
15
  export async function openShell(input) {
18
16
  const { repositoryPath, branch } = input;
19
- if (!repositoryPath || !isAbsolute(repositoryPath)) {
17
+ if (!repositoryPath?.startsWith('/')) {
20
18
  return { success: false, error: 'repositoryPath must be an absolute path' };
21
19
  }
22
20
  try {
@@ -30,7 +28,7 @@ export async function openShell(input) {
30
28
  if (!entry) {
31
29
  return {
32
30
  success: false,
33
- error: `Unsupported platform: ${platform()}`,
31
+ error: `Unsupported platform: ${platform()}. Shell launch is supported on macOS and Linux only.`,
34
32
  };
35
33
  }
36
34
  const child = spawn(entry.cmd, entry.args(targetPath), {
@@ -0,0 +1,14 @@
1
+ import { NextResponse } from 'next/server';
2
+ /** Prevent Next.js from statically prerendering this route at build time. */
3
+ export declare const dynamic = "force-dynamic";
4
+ /**
5
+ * Returns fresh graph nodes and edges for the control-center canvas.
6
+ *
7
+ * Used by the client-side polling fallback instead of a server action
8
+ * so that periodic syncs don't trigger the Next.js "Rendering…" indicator.
9
+ */
10
+ export declare function GET(): Promise<NextResponse<{
11
+ nodes: import("../../../components/features/features-canvas/index.js").CanvasNodeType[];
12
+ edges: import("@xyflow/react").Edge[];
13
+ }>>;
14
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/app/api/graph-data/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,6EAA6E;AAC7E,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC;;;;;GAKG;AACH,wBAAsB,GAAG;;;IAGxB"}
@@ -0,0 +1,14 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { getGraphData } from '../../(dashboard)/get-graph-data.js';
3
+ /** Prevent Next.js from statically prerendering this route at build time. */
4
+ export const dynamic = 'force-dynamic';
5
+ /**
6
+ * Returns fresh graph nodes and edges for the control-center canvas.
7
+ *
8
+ * Used by the client-side polling fallback instead of a server action
9
+ * so that periodic syncs don't trigger the Next.js "Rendering…" indicator.
10
+ */
11
+ export async function GET() {
12
+ const data = await getGraphData();
13
+ return NextResponse.json(data);
14
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"build-graph-nodes.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/app/build-graph-nodes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAM1F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAG1C,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,QAAQ,GAAG,IAAI,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,UAAU,EAAE,EAC1B,gBAAgB,EAAE,cAAc,EAAE,GACjC;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CA2E5C"}
1
+ {"version":3,"file":"build-graph-nodes.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/app/build-graph-nodes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAM1F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAG1C,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,QAAQ,GAAG,IAAI,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,UAAU,EAAE,EAC1B,gBAAgB,EAAE,cAAc,EAAE,GACjC;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAuE5C"}
@@ -8,12 +8,10 @@ import { deriveNodeState, deriveProgress, deriveLifecycle, } from '../components
8
8
  * renders empty when features exist but their repository rows are missing.
9
9
  */
10
10
  export function buildGraphNodes(repositories, featuresWithRuns) {
11
- // Normalize path separators so Windows backslash paths match forward-slash paths
12
- const normalizePath = (p) => p.replace(/\\/g, '/');
13
- // Group features by normalized repository path
11
+ // Group features by repository path
14
12
  const featuresByRepo = {};
15
13
  featuresWithRuns.forEach((entry) => {
16
- const repoKey = normalizePath(entry.feature.repositoryPath);
14
+ const repoKey = entry.feature.repositoryPath;
17
15
  if (!featuresByRepo[repoKey]) {
18
16
  featuresByRepo[repoKey] = [];
19
17
  }
@@ -25,8 +23,7 @@ export function buildGraphNodes(repositories, featuresWithRuns) {
25
23
  const coveredPaths = new Set();
26
24
  // First, add nodes for all persisted repositories (including those without features)
27
25
  for (const repo of repositories) {
28
- const normalizedRepoPath = normalizePath(repo.path);
29
- coveredPaths.add(normalizedRepoPath);
26
+ coveredPaths.add(repo.path);
30
27
  const repoNodeId = `repo-${repo.id}`;
31
28
  nodes.push({
32
29
  id: repoNodeId,
@@ -34,12 +31,12 @@ export function buildGraphNodes(repositories, featuresWithRuns) {
34
31
  position: { x: 0, y: 0 },
35
32
  data: {
36
33
  name: repo.name,
37
- repositoryPath: normalizedRepoPath,
34
+ repositoryPath: repo.path,
38
35
  id: repo.id,
39
36
  createdAt: repo.createdAt instanceof Date ? repo.createdAt.getTime() : Number(repo.createdAt),
40
37
  },
41
38
  });
42
- const repoFeatures = featuresByRepo[normalizedRepoPath] ?? [];
39
+ const repoFeatures = featuresByRepo[repo.path] ?? [];
43
40
  appendFeatureNodes(repoFeatures, repoNodeId, featuresWithRuns, nodes, edges, repo.name);
44
41
  }
45
42
  // Second pass: group orphaned features under virtual repository nodes
@@ -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":"AAsCA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG/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,2CA6iB1F"}
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":"AAsCA,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,2CA0hB1F"}
@@ -28,6 +28,7 @@ import { useFeatureActions } from '../../common/feature-drawer/use-feature-actio
28
28
  import { resolveSseEventUpdates } from '../../common/feature-node/derive-feature-state.js';
29
29
  import { deriveInitialTab } from './drawer-view.js';
30
30
  import { useArtifactFetch } from './use-artifact-fetch.js';
31
+ import { useDrawerSync } from './use-drawer-sync.js';
31
32
  export function FeatureDrawerClient({ view: initialView, urlTab }) {
32
33
  const featureFlags = useFeatureFlags();
33
34
  const router = useRouter();
@@ -35,7 +36,7 @@ export function FeatureDrawerClient({ view: initialView, urlTab }) {
35
36
  const rejectSound = useSoundAction('reject');
36
37
  // Track the view locally so SSE events can update the drawer type in real-time
37
38
  const [view, setView] = useState(initialView);
38
- // Sync when server re-renders with new props (e.g. after router.refresh())
39
+ // Sync when server re-renders with new props (e.g. after navigation)
39
40
  useEffect(() => {
40
41
  setView(initialView);
41
42
  }, [initialView]);
@@ -60,15 +61,9 @@ export function FeatureDrawerClient({ view: initialView, urlTab }) {
60
61
  // fetches (which would fail with "not found" for soft-deleted features).
61
62
  if (featureNode.state === 'deleting')
62
63
  continue;
63
- // Trigger a server refresh to get the latest drawer view,
64
- // but skip when the drawer is closed, the user has unsaved changes,
65
- // or a rejection is in-flight to avoid unnecessary refreshes.
66
- if (isOpenRef.current && !isDirtyRef.current && !isRejectingRef.current)
67
- router.refresh();
68
64
  if (update.state !== undefined || update.lifecycle !== undefined) {
69
- // Optimistically update the node data AND re-derive the initial tab so the
70
- // drawer switches immediately (e.g. prd-review → overview when agent resumes)
71
- // without waiting for the router.refresh() round-trip.
65
+ // Update the node data AND re-derive the initial tab so the drawer
66
+ // switches immediately (e.g. prd-review → overview when agent resumes).
72
67
  setView((prev) => {
73
68
  if (prev.type !== 'feature')
74
69
  return prev;
@@ -81,24 +76,17 @@ export function FeatureDrawerClient({ view: initialView, urlTab }) {
81
76
  });
82
77
  }
83
78
  }
84
- }, [events, featureNode, router]);
79
+ }, [events, featureNode]);
85
80
  // Derive open state from the URL. Next.js parallel routes preserve slot
86
81
  // content during soft navigation, so this component is NOT unmounted when
87
82
  // navigating to `/`. Instead, we watch the pathname and let Vaul handle
88
83
  // the close animation when the path no longer matches a feature route.
89
84
  const pathname = usePathname();
90
85
  const isOpen = pathname.startsWith('/feature/');
91
- const isOpenRef = useRef(isOpen);
92
- const wasOpenRef = useRef(isOpen);
93
- // When the drawer re-opens, force a server refresh so the view is always fresh.
94
- // SSE skips router.refresh() while the drawer is closed, so data can go stale.
95
- useEffect(() => {
96
- if (isOpen && !wasOpenRef.current) {
97
- router.refresh();
98
- }
99
- wasOpenRef.current = isOpen;
100
- }, [isOpen, router]);
101
- isOpenRef.current = isOpen;
86
+ // Targeted data sync: fetches fresh FeatureNodeData on drawer open and
87
+ // periodically while open. Replaces router.refresh() to avoid full-page
88
+ // re-renders that cause visible flashing and can reset form state.
89
+ useDrawerSync(isOpen, featureNode?.featureId ?? null, setView);
102
90
  const onClose = useCallback(() => {
103
91
  router.push('/');
104
92
  }, [router]);
@@ -182,10 +170,6 @@ export function FeatureDrawerClient({ view: initialView, urlTab }) {
182
170
  featureNode?.state === 'action-required' &&
183
171
  Object.keys(prdDefaultSelections).some((k) => prdDefaultSelections[k] !== prdSelections[k]);
184
172
  const isDirty = isChatDirty || isPrdDirty;
185
- // Keep dirty state in a ref so the SSE handler can read the latest value
186
- // without re-running the effect on every keystroke.
187
- const isDirtyRef = useRef(isDirty);
188
- isDirtyRef.current = isDirty;
189
173
  const onReset = useCallback(() => {
190
174
  setChatInput('');
191
175
  setPrdSelections({ ...prdDefaultSelections });
@@ -0,0 +1,12 @@
1
+ import type { DrawerView } from './drawer-view.js';
2
+ /**
3
+ * Targeted drawer data synchronization — replaces router.refresh() for
4
+ * keeping the feature drawer in sync with the server.
5
+ *
6
+ * - On drawer open: fetches fresh FeatureNodeData via server action
7
+ * - Background sync: every 15s while open, merges fresh data into view
8
+ * - SSE-driven state/lifecycle updates are handled separately (not here)
9
+ * - Never affects form state (chatInput, prdSelections, attachments)
10
+ */
11
+ export declare function useDrawerSync(isOpen: boolean, featureId: string | null, setView: React.Dispatch<React.SetStateAction<DrawerView>>): void;
12
+ //# sourceMappingURL=use-drawer-sync.d.ts.map