@cerbur/clutch-dsh-worktree 0.1.8 → 0.1.10

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 (508) hide show
  1. package/README.md +117 -46
  2. package/README.zh.md +92 -40
  3. package/lib/client/WorktreeSurface.d.ts +4 -7
  4. package/lib/client/WorktreeSurface.d.ts.map +1 -1
  5. package/lib/client/WorktreeSurface.js +44 -1243
  6. package/lib/client/WorktreeSurface.js.map +1 -1
  7. package/lib/client/{WorktreeContext.d.ts → context/WorktreeContext.d.ts} +2 -2
  8. package/lib/client/context/WorktreeContext.d.ts.map +1 -0
  9. package/lib/client/{WorktreeContext.js → context/WorktreeContext.js} +1 -1
  10. package/lib/client/context/WorktreeContext.js.map +1 -0
  11. package/lib/client/{WorktreeHeroContext.d.ts → context/WorktreeHeroContext.d.ts} +1 -1
  12. package/lib/client/context/WorktreeHeroContext.d.ts.map +1 -0
  13. package/lib/client/{WorktreeHeroContext.js → context/WorktreeHeroContext.js} +1 -1
  14. package/lib/client/context/WorktreeHeroContext.js.map +1 -0
  15. package/lib/client/{worktree-context-store.d.ts → context/worktree-context-store.d.ts} +7 -15
  16. package/lib/client/context/worktree-context-store.d.ts.map +1 -0
  17. package/lib/client/{worktree-context-store.js → context/worktree-context-store.js} +20 -13
  18. package/lib/client/context/worktree-context-store.js.map +1 -0
  19. package/lib/client/{worktree-context.d.ts → context/worktree-context.d.ts} +1 -1
  20. package/lib/client/context/worktree-context.d.ts.map +1 -0
  21. package/lib/client/{worktree-context.js → context/worktree-context.js} +5 -3
  22. package/lib/client/context/worktree-context.js.map +1 -0
  23. package/lib/client/dsh-slot-contract.d.ts +43 -0
  24. package/lib/client/dsh-slot-contract.d.ts.map +1 -0
  25. package/lib/client/dsh-slot-contract.js +2 -0
  26. package/lib/client/dsh-slot-contract.js.map +1 -0
  27. package/lib/client/entry.d.ts +3 -3
  28. package/lib/client/entry.d.ts.map +1 -1
  29. package/lib/client/entry.js +168 -38
  30. package/lib/client/entry.js.map +1 -1
  31. package/lib/client/index.d.ts +3 -3
  32. package/lib/client/index.d.ts.map +1 -1
  33. package/lib/client/index.js +2 -2
  34. package/lib/client/index.js.map +1 -1
  35. package/lib/client/locales.d.ts +66 -0
  36. package/lib/client/locales.d.ts.map +1 -1
  37. package/lib/client/locales.js +76 -10
  38. package/lib/client/locales.js.map +1 -1
  39. package/lib/client/{WorktreeOverlay.d.ts → overlay/WorktreeOverlay.d.ts} +2 -2
  40. package/lib/client/overlay/WorktreeOverlay.d.ts.map +1 -0
  41. package/lib/client/{WorktreeOverlay.js → overlay/WorktreeOverlay.js} +2 -2
  42. package/lib/client/overlay/WorktreeOverlay.js.map +1 -0
  43. package/lib/client/overlay/overlay-bounds.d.ts.map +1 -0
  44. package/lib/client/overlay/overlay-bounds.js.map +1 -0
  45. package/lib/client/overlay/sidebar-overlay-geometry.d.ts.map +1 -0
  46. package/lib/client/overlay/sidebar-overlay-geometry.js.map +1 -0
  47. package/lib/client/permission/worktree-permission-icon.d.ts.map +1 -0
  48. package/lib/client/permission/worktree-permission-icon.js.map +1 -0
  49. package/lib/client/permission/worktree-permission.d.ts.map +1 -0
  50. package/lib/client/permission/worktree-permission.js.map +1 -0
  51. package/lib/client/session/session-view.d.ts.map +1 -0
  52. package/lib/client/session/session-view.js.map +1 -0
  53. package/lib/client/session/virtual-workspace-membership.d.ts +29 -0
  54. package/lib/client/session/virtual-workspace-membership.d.ts.map +1 -0
  55. package/lib/client/session/virtual-workspace-membership.js +131 -0
  56. package/lib/client/session/virtual-workspace-membership.js.map +1 -0
  57. package/lib/client/{worktree-session-fork.d.ts → session/worktree-session-fork.d.ts} +25 -4
  58. package/lib/client/session/worktree-session-fork.d.ts.map +1 -0
  59. package/lib/client/session/worktree-session-fork.js +309 -0
  60. package/lib/client/session/worktree-session-fork.js.map +1 -0
  61. package/lib/client/{worktree-session-order.d.ts → session/worktree-session-order.d.ts} +2 -2
  62. package/lib/client/session/worktree-session-order.d.ts.map +1 -0
  63. package/lib/client/session/worktree-session-order.js.map +1 -0
  64. package/lib/client/session/worktree-session-position.d.ts.map +1 -0
  65. package/lib/client/session/worktree-session-position.js.map +1 -0
  66. package/lib/client/{worktree-session.d.ts → session/worktree-session.d.ts} +3 -3
  67. package/lib/client/session/worktree-session.d.ts.map +1 -0
  68. package/lib/client/{worktree-session.js → session/worktree-session.js} +3 -3
  69. package/lib/client/session/worktree-session.js.map +1 -0
  70. package/lib/client/surface/actions/lifecycle-commands.d.ts +9 -0
  71. package/lib/client/surface/actions/lifecycle-commands.d.ts.map +1 -0
  72. package/lib/client/surface/actions/lifecycle-commands.js +243 -0
  73. package/lib/client/surface/actions/lifecycle-commands.js.map +1 -0
  74. package/lib/client/surface/actions/useDragActions.d.ts +26 -0
  75. package/lib/client/surface/actions/useDragActions.d.ts.map +1 -0
  76. package/lib/client/surface/actions/useDragActions.js +125 -0
  77. package/lib/client/surface/actions/useDragActions.js.map +1 -0
  78. package/lib/client/surface/actions/useLifecycleActions.d.ts +30 -0
  79. package/lib/client/surface/actions/useLifecycleActions.d.ts.map +1 -0
  80. package/lib/client/surface/actions/useLifecycleActions.js +140 -0
  81. package/lib/client/surface/actions/useLifecycleActions.js.map +1 -0
  82. package/lib/client/surface/actions/useNativeActions.d.ts +48 -0
  83. package/lib/client/surface/actions/useNativeActions.d.ts.map +1 -0
  84. package/lib/client/surface/actions/useNativeActions.js +182 -0
  85. package/lib/client/surface/actions/useNativeActions.js.map +1 -0
  86. package/lib/client/surface/actions/useSessionActions.d.ts +24 -0
  87. package/lib/client/surface/actions/useSessionActions.d.ts.map +1 -0
  88. package/lib/client/surface/actions/useSessionActions.js +116 -0
  89. package/lib/client/surface/actions/useSessionActions.js.map +1 -0
  90. package/lib/client/surface/actions/useSurfaceMutation.d.ts +15 -0
  91. package/lib/client/surface/actions/useSurfaceMutation.d.ts.map +1 -0
  92. package/lib/client/surface/actions/useSurfaceMutation.js +24 -0
  93. package/lib/client/surface/actions/useSurfaceMutation.js.map +1 -0
  94. package/lib/client/surface/actions/useWorktreeRegistration.d.ts +31 -0
  95. package/lib/client/surface/actions/useWorktreeRegistration.d.ts.map +1 -0
  96. package/lib/client/surface/actions/useWorktreeRegistration.js +203 -0
  97. package/lib/client/surface/actions/useWorktreeRegistration.js.map +1 -0
  98. package/lib/client/surface/actions/worktree-cleanup-flow.d.ts +10 -0
  99. package/lib/client/surface/actions/worktree-cleanup-flow.d.ts.map +1 -0
  100. package/lib/client/surface/actions/worktree-cleanup-flow.js +19 -0
  101. package/lib/client/surface/actions/worktree-cleanup-flow.js.map +1 -0
  102. package/lib/client/surface/components/AccessConfirmation.d.ts +9 -0
  103. package/lib/client/surface/components/AccessConfirmation.d.ts.map +1 -0
  104. package/lib/client/surface/components/AccessConfirmation.js +18 -0
  105. package/lib/client/surface/components/AccessConfirmation.js.map +1 -0
  106. package/lib/client/surface/components/ActiveWorktree.d.ts +28 -0
  107. package/lib/client/surface/components/ActiveWorktree.d.ts.map +1 -0
  108. package/lib/client/surface/components/ActiveWorktree.js +154 -0
  109. package/lib/client/surface/components/ActiveWorktree.js.map +1 -0
  110. package/lib/client/surface/components/ArchivedWorktree.d.ts +24 -0
  111. package/lib/client/surface/components/ArchivedWorktree.d.ts.map +1 -0
  112. package/lib/client/surface/components/ArchivedWorktree.js +145 -0
  113. package/lib/client/surface/components/ArchivedWorktree.js.map +1 -0
  114. package/lib/client/surface/components/ArchivedWorktrees.d.ts +25 -0
  115. package/lib/client/surface/components/ArchivedWorktrees.d.ts.map +1 -0
  116. package/lib/client/surface/components/ArchivedWorktrees.js +20 -0
  117. package/lib/client/surface/components/ArchivedWorktrees.js.map +1 -0
  118. package/lib/client/surface/components/LifecycleDialogs.d.ts +20 -0
  119. package/lib/client/surface/components/LifecycleDialogs.d.ts.map +1 -0
  120. package/lib/client/surface/components/LifecycleDialogs.js +31 -0
  121. package/lib/client/surface/components/LifecycleDialogs.js.map +1 -0
  122. package/lib/client/surface/components/NativeDialogs.d.ts +9 -0
  123. package/lib/client/surface/components/NativeDialogs.d.ts.map +1 -0
  124. package/lib/client/surface/components/NativeDialogs.js +14 -0
  125. package/lib/client/surface/components/NativeDialogs.js.map +1 -0
  126. package/lib/client/surface/components/NotificationToasts.d.ts +7 -0
  127. package/lib/client/surface/components/NotificationToasts.d.ts.map +1 -0
  128. package/lib/client/surface/components/NotificationToasts.js +24 -0
  129. package/lib/client/surface/components/NotificationToasts.js.map +1 -0
  130. package/lib/client/surface/components/RegistrationDialog.d.ts +15 -0
  131. package/lib/client/surface/components/RegistrationDialog.d.ts.map +1 -0
  132. package/lib/client/surface/components/RegistrationDialog.js +22 -0
  133. package/lib/client/surface/components/RegistrationDialog.js.map +1 -0
  134. package/lib/client/surface/components/SurfaceContent.d.ts +31 -0
  135. package/lib/client/surface/components/SurfaceContent.d.ts.map +1 -0
  136. package/lib/client/surface/components/SurfaceContent.js +65 -0
  137. package/lib/client/surface/components/SurfaceContent.js.map +1 -0
  138. package/lib/client/surface/components/SurfaceHeader.d.ts +15 -0
  139. package/lib/client/surface/components/SurfaceHeader.d.ts.map +1 -0
  140. package/lib/client/surface/components/SurfaceHeader.js +42 -0
  141. package/lib/client/surface/components/SurfaceHeader.js.map +1 -0
  142. package/lib/client/surface/components/WorkspaceTree.d.ts +32 -0
  143. package/lib/client/surface/components/WorkspaceTree.d.ts.map +1 -0
  144. package/lib/client/surface/components/WorkspaceTree.js +145 -0
  145. package/lib/client/surface/components/WorkspaceTree.js.map +1 -0
  146. package/lib/client/{worktree-surface-dialogs.d.ts → surface/components/dialogs.d.ts} +5 -2
  147. package/lib/client/surface/components/dialogs.d.ts.map +1 -0
  148. package/lib/client/{worktree-surface-dialogs.js → surface/components/dialogs.js} +67 -24
  149. package/lib/client/surface/components/dialogs.js.map +1 -0
  150. package/lib/client/{worktree-surface-rows.d.ts → surface/components/rows.d.ts} +3 -3
  151. package/lib/client/surface/components/rows.d.ts.map +1 -0
  152. package/lib/client/{worktree-surface-rows.js → surface/components/rows.js} +79 -17
  153. package/lib/client/surface/components/rows.js.map +1 -0
  154. package/lib/client/surface/notification-queue.d.ts +11 -0
  155. package/lib/client/surface/notification-queue.d.ts.map +1 -0
  156. package/lib/client/surface/notification-queue.js +19 -0
  157. package/lib/client/surface/notification-queue.js.map +1 -0
  158. package/lib/client/{worktree-surface-selectors.d.ts → surface/selectors.d.ts} +10 -5
  159. package/lib/client/surface/selectors.d.ts.map +1 -0
  160. package/lib/client/{worktree-surface-selectors.js → surface/selectors.js} +23 -6
  161. package/lib/client/surface/selectors.js.map +1 -0
  162. package/lib/client/surface/shared.d.ts +40 -0
  163. package/lib/client/surface/shared.d.ts.map +1 -0
  164. package/lib/client/surface/shared.js +53 -0
  165. package/lib/client/surface/shared.js.map +1 -0
  166. package/lib/client/surface/state/useLifecycleState.d.ts +34 -0
  167. package/lib/client/surface/state/useLifecycleState.d.ts.map +1 -0
  168. package/lib/client/surface/state/useLifecycleState.js +39 -0
  169. package/lib/client/surface/state/useLifecycleState.js.map +1 -0
  170. package/lib/client/surface/state/useRegistrationState.d.ts +34 -0
  171. package/lib/client/surface/state/useRegistrationState.d.ts.map +1 -0
  172. package/lib/client/surface/state/useRegistrationState.js +44 -0
  173. package/lib/client/surface/state/useRegistrationState.js.map +1 -0
  174. package/lib/client/surface/state/useSessionExpansion.d.ts +39 -0
  175. package/lib/client/surface/state/useSessionExpansion.d.ts.map +1 -0
  176. package/lib/client/surface/state/useSessionExpansion.js +230 -0
  177. package/lib/client/surface/state/useSessionExpansion.js.map +1 -0
  178. package/lib/client/surface/state/useSessionOrdering.d.ts +15 -0
  179. package/lib/client/surface/state/useSessionOrdering.d.ts.map +1 -0
  180. package/lib/client/surface/state/useSessionOrdering.js +68 -0
  181. package/lib/client/surface/state/useSessionOrdering.js.map +1 -0
  182. package/lib/client/surface/state/useSurfaceMenus.d.ts +9 -0
  183. package/lib/client/surface/state/useSurfaceMenus.d.ts.map +1 -0
  184. package/lib/client/surface/state/useSurfaceMenus.js +15 -0
  185. package/lib/client/surface/state/useSurfaceMenus.js.map +1 -0
  186. package/lib/client/surface/state/useSurfaceRefresh.d.ts +39 -0
  187. package/lib/client/surface/state/useSurfaceRefresh.d.ts.map +1 -0
  188. package/lib/client/surface/state/useSurfaceRefresh.js +274 -0
  189. package/lib/client/surface/state/useSurfaceRefresh.js.map +1 -0
  190. package/lib/client/surface/state/useSurfaceSources.d.ts +31 -0
  191. package/lib/client/surface/state/useSurfaceSources.d.ts.map +1 -0
  192. package/lib/client/surface/state/useSurfaceSources.js +63 -0
  193. package/lib/client/surface/state/useSurfaceSources.js.map +1 -0
  194. package/lib/client/{worktree-surface-types.d.ts → surface/types.d.ts} +68 -13
  195. package/lib/client/surface/types.d.ts.map +1 -0
  196. package/lib/client/surface/types.js +2 -0
  197. package/lib/client/surface/types.js.map +1 -0
  198. package/lib/client/{WorktreeModeAction.d.ts → view/WorktreeModeAction.d.ts} +1 -1
  199. package/lib/client/view/WorktreeModeAction.d.ts.map +1 -0
  200. package/lib/client/{WorktreeModeAction.js → view/WorktreeModeAction.js} +1 -1
  201. package/lib/client/view/WorktreeModeAction.js.map +1 -0
  202. package/lib/client/view/navigation.d.ts.map +1 -0
  203. package/lib/client/view/navigation.js.map +1 -0
  204. package/lib/client/{view-mode-store.d.ts → view/view-mode-store.d.ts} +1 -1
  205. package/lib/client/view/view-mode-store.d.ts.map +1 -0
  206. package/lib/client/{view-mode-store.js → view/view-mode-store.js} +1 -1
  207. package/lib/client/view/view-mode-store.js.map +1 -0
  208. package/lib/client/{view-mode.d.ts → view/view-mode.d.ts} +20 -6
  209. package/lib/client/view/view-mode.d.ts.map +1 -0
  210. package/lib/client/{view-mode.js → view/view-mode.js} +35 -10
  211. package/lib/client/view/view-mode.js.map +1 -0
  212. package/lib/client/{worktree-error-copy.d.ts → view/worktree-error-copy.d.ts} +2 -2
  213. package/lib/client/view/worktree-error-copy.d.ts.map +1 -0
  214. package/lib/client/view/worktree-error-copy.js.map +1 -0
  215. package/lib/client/{worktree-expand-state.d.ts → view/worktree-expand-state.d.ts} +6 -4
  216. package/lib/client/view/worktree-expand-state.d.ts.map +1 -0
  217. package/lib/client/{worktree-expand-state.js → view/worktree-expand-state.js} +11 -0
  218. package/lib/client/view/worktree-expand-state.js.map +1 -0
  219. package/lib/client/{worktree-view-actions.d.ts → view/worktree-view-actions.d.ts} +11 -5
  220. package/lib/client/view/worktree-view-actions.d.ts.map +1 -0
  221. package/lib/client/{worktree-view-actions.js → view/worktree-view-actions.js} +13 -11
  222. package/lib/client/view/worktree-view-actions.js.map +1 -0
  223. package/lib/client/view/worktree-view-errors.d.ts.map +1 -0
  224. package/lib/client/view/worktree-view-errors.js.map +1 -0
  225. package/lib/client/{worktree-view-read.d.ts → view/worktree-view-read.d.ts} +21 -9
  226. package/lib/client/view/worktree-view-read.d.ts.map +1 -0
  227. package/lib/client/{worktree-view-read.js → view/worktree-view-read.js} +78 -10
  228. package/lib/client/view/worktree-view-read.js.map +1 -0
  229. package/lib/client/view/worktree-view.d.ts.map +1 -0
  230. package/lib/client/view/worktree-view.js.map +1 -0
  231. package/lib/client/worktree-connection.d.ts +5 -0
  232. package/lib/client/worktree-connection.d.ts.map +1 -1
  233. package/lib/client/worktree-connection.js +16 -0
  234. package/lib/client/worktree-connection.js.map +1 -1
  235. package/lib/client.js +5990 -3139
  236. package/lib/client.js.map +1 -1
  237. package/lib/contract/index.contract.js +10 -0
  238. package/lib/contract/index.contract.js.map +1 -1
  239. package/lib/contract/index.d.ts +46 -3
  240. package/lib/contract/index.d.ts.map +1 -1
  241. package/lib/contract/index.js +7 -0
  242. package/lib/contract/index.js.map +1 -1
  243. package/lib/host/dsh-read-adapter.d.ts +10 -1
  244. package/lib/host/dsh-read-adapter.d.ts.map +1 -1
  245. package/lib/host/dsh-read-adapter.js +18 -1
  246. package/lib/host/dsh-read-adapter.js.map +1 -1
  247. package/lib/host/remote.d.ts.map +1 -1
  248. package/lib/host/remote.js +14 -0
  249. package/lib/host/remote.js.map +1 -1
  250. package/lib/host/service.d.ts +24 -0
  251. package/lib/host/service.d.ts.map +1 -1
  252. package/lib/host/service.js +39 -1
  253. package/lib/host/service.js.map +1 -1
  254. package/lib/host/worktree-activity.d.ts +13 -0
  255. package/lib/host/worktree-activity.d.ts.map +1 -0
  256. package/lib/host/worktree-activity.js +23 -0
  257. package/lib/host/worktree-activity.js.map +1 -0
  258. package/lib/host/worktree-permission-manager.js +2 -2
  259. package/lib/host/worktree-permission-manager.js.map +1 -1
  260. package/lib/host/worktree-permission.d.ts +3 -2
  261. package/lib/host/worktree-permission.d.ts.map +1 -1
  262. package/lib/host/worktree-permission.js +29 -5
  263. package/lib/host/worktree-permission.js.map +1 -1
  264. package/lib/index.d.ts +3 -3
  265. package/lib/index.d.ts.map +1 -1
  266. package/lib/index.js +2 -2
  267. package/lib/index.js.map +1 -1
  268. package/lib/manage/manager-context.d.ts +2 -1
  269. package/lib/manage/manager-context.d.ts.map +1 -1
  270. package/lib/manage/manager-sessions.js +4 -4
  271. package/lib/manage/manager-sessions.js.map +1 -1
  272. package/lib/manage/manager-worktree-lifecycle.d.ts +23 -0
  273. package/lib/manage/manager-worktree-lifecycle.d.ts.map +1 -0
  274. package/lib/manage/manager-worktree-lifecycle.js +165 -0
  275. package/lib/manage/manager-worktree-lifecycle.js.map +1 -0
  276. package/lib/manage/manager-worktrees.d.ts +1 -6
  277. package/lib/manage/manager-worktrees.d.ts.map +1 -1
  278. package/lib/manage/manager-worktrees.js +83 -114
  279. package/lib/manage/manager-worktrees.js.map +1 -1
  280. package/lib/manage/manager.d.ts +17 -1
  281. package/lib/manage/manager.d.ts.map +1 -1
  282. package/lib/manage/manager.js +25 -6
  283. package/lib/manage/manager.js.map +1 -1
  284. package/lib/provider/generated-name.d.ts +8 -0
  285. package/lib/provider/generated-name.d.ts.map +1 -0
  286. package/lib/provider/generated-name.js +29 -0
  287. package/lib/provider/generated-name.js.map +1 -0
  288. package/lib/provider/{git.d.ts → git/adapter.d.ts} +2 -2
  289. package/lib/provider/git/adapter.d.ts.map +1 -0
  290. package/lib/provider/{git.js → git/adapter.js} +15 -2
  291. package/lib/provider/git/adapter.js.map +1 -0
  292. package/lib/provider/{repository-fingerprint.d.ts → git/repository-fingerprint.d.ts} +1 -1
  293. package/lib/provider/git/repository-fingerprint.d.ts.map +1 -0
  294. package/lib/provider/git/repository-fingerprint.js.map +1 -0
  295. package/lib/provider/{subprocess.d.ts → git/subprocess.d.ts} +1 -1
  296. package/lib/provider/git/subprocess.d.ts.map +1 -0
  297. package/lib/provider/{subprocess.js → git/subprocess.js} +8 -0
  298. package/lib/provider/git/subprocess.js.map +1 -0
  299. package/lib/provider/git/worktree-status.d.ts +5 -0
  300. package/lib/provider/git/worktree-status.d.ts.map +1 -0
  301. package/lib/provider/git/worktree-status.js +23 -0
  302. package/lib/provider/git/worktree-status.js.map +1 -0
  303. package/lib/provider/index.d.ts +5 -5
  304. package/lib/provider/index.d.ts.map +1 -1
  305. package/lib/provider/index.js +5 -5
  306. package/lib/provider/index.js.map +1 -1
  307. package/lib/provider/mutation-token.d.ts +1 -1
  308. package/lib/provider/mutation-token.d.ts.map +1 -1
  309. package/lib/provider/mutation-token.js +1 -0
  310. package/lib/provider/mutation-token.js.map +1 -1
  311. package/lib/provider/sidecar/mutation-lock.d.ts.map +1 -0
  312. package/lib/provider/{mutation-lock.js → sidecar/mutation-lock.js} +1 -1
  313. package/lib/provider/sidecar/mutation-lock.js.map +1 -0
  314. package/lib/provider/{sidecar.d.ts → sidecar/repository.d.ts} +3 -3
  315. package/lib/provider/sidecar/repository.d.ts.map +1 -0
  316. package/lib/provider/{sidecar.js → sidecar/repository.js} +13 -6
  317. package/lib/provider/sidecar/repository.js.map +1 -0
  318. package/lib/provider/{sidecar-persistence.d.ts → sidecar/sidecar-persistence.d.ts} +1 -1
  319. package/lib/provider/sidecar/sidecar-persistence.d.ts.map +1 -0
  320. package/lib/provider/{sidecar-persistence.js → sidecar/sidecar-persistence.js} +29 -2
  321. package/lib/provider/sidecar/sidecar-persistence.js.map +1 -0
  322. package/lib/provider/{sidecar-schema.d.ts → sidecar/sidecar-schema.d.ts} +1 -1
  323. package/lib/provider/sidecar/sidecar-schema.d.ts.map +1 -0
  324. package/lib/provider/{sidecar-schema.js → sidecar/sidecar-schema.js} +52 -16
  325. package/lib/provider/sidecar/sidecar-schema.js.map +1 -0
  326. package/lib/provider/transaction/dependencies.d.ts +10 -0
  327. package/lib/provider/transaction/dependencies.d.ts.map +1 -0
  328. package/lib/provider/transaction/dependencies.js +2 -0
  329. package/lib/provider/transaction/dependencies.js.map +1 -0
  330. package/lib/provider/transaction/index.d.ts +17 -0
  331. package/lib/provider/transaction/index.d.ts.map +1 -0
  332. package/lib/provider/transaction/index.js +44 -0
  333. package/lib/provider/transaction/index.js.map +1 -0
  334. package/lib/provider/transaction/operations/adopt-branch.d.ts +6 -0
  335. package/lib/provider/transaction/operations/adopt-branch.d.ts.map +1 -0
  336. package/lib/provider/transaction/operations/adopt-branch.js +59 -0
  337. package/lib/provider/transaction/operations/adopt-branch.js.map +1 -0
  338. package/lib/provider/transaction/operations/clean.d.ts +4 -0
  339. package/lib/provider/transaction/operations/clean.d.ts.map +1 -0
  340. package/lib/provider/transaction/operations/clean.js +168 -0
  341. package/lib/provider/transaction/operations/clean.js.map +1 -0
  342. package/lib/provider/transaction/operations/create.d.ts +5 -0
  343. package/lib/provider/transaction/operations/create.d.ts.map +1 -0
  344. package/lib/provider/transaction/operations/create.js +136 -0
  345. package/lib/provider/transaction/operations/create.js.map +1 -0
  346. package/lib/provider/transaction/operations/import.d.ts +5 -0
  347. package/lib/provider/transaction/operations/import.d.ts.map +1 -0
  348. package/lib/provider/transaction/operations/import.js +92 -0
  349. package/lib/provider/transaction/operations/import.js.map +1 -0
  350. package/lib/provider/transaction/operations/remove.d.ts +4 -0
  351. package/lib/provider/transaction/operations/remove.d.ts.map +1 -0
  352. package/lib/provider/transaction/operations/remove.js +164 -0
  353. package/lib/provider/transaction/operations/remove.js.map +1 -0
  354. package/lib/provider/transaction/recovery/failure-recovery.d.ts +32 -0
  355. package/lib/provider/transaction/recovery/failure-recovery.d.ts.map +1 -0
  356. package/lib/provider/transaction/recovery/failure-recovery.js +147 -0
  357. package/lib/provider/transaction/recovery/failure-recovery.js.map +1 -0
  358. package/lib/provider/transaction/recovery/recover.d.ts +4 -0
  359. package/lib/provider/transaction/recovery/recover.d.ts.map +1 -0
  360. package/lib/provider/transaction/recovery/recover.js +162 -0
  361. package/lib/provider/transaction/recovery/recover.js.map +1 -0
  362. package/lib/provider/transaction/support/admission.d.ts +7 -0
  363. package/lib/provider/transaction/support/admission.d.ts.map +1 -0
  364. package/lib/provider/transaction/support/admission.js +90 -0
  365. package/lib/provider/transaction/support/admission.js.map +1 -0
  366. package/lib/provider/transaction/support/inspection.d.ts +11 -0
  367. package/lib/provider/transaction/support/inspection.d.ts.map +1 -0
  368. package/lib/provider/transaction/support/inspection.js +51 -0
  369. package/lib/provider/transaction/support/inspection.js.map +1 -0
  370. package/lib/provider/transaction/support/journal.d.ts +12 -0
  371. package/lib/provider/transaction/support/journal.d.ts.map +1 -0
  372. package/lib/provider/transaction/support/journal.js +72 -0
  373. package/lib/provider/transaction/support/journal.js.map +1 -0
  374. package/lib/provider/transaction/support/locking.d.ts +4 -0
  375. package/lib/provider/transaction/support/locking.d.ts.map +1 -0
  376. package/lib/provider/transaction/support/locking.js +11 -0
  377. package/lib/provider/transaction/support/locking.js.map +1 -0
  378. package/lib/provider/transaction/support/path-safety.d.ts +11 -0
  379. package/lib/provider/transaction/support/path-safety.d.ts.map +1 -0
  380. package/lib/provider/transaction/support/path-safety.js +82 -0
  381. package/lib/provider/transaction/support/path-safety.js.map +1 -0
  382. package/lib/provider/transaction/support/paths.d.ts +10 -0
  383. package/lib/provider/transaction/support/paths.d.ts.map +1 -0
  384. package/lib/provider/transaction/support/paths.js +68 -0
  385. package/lib/provider/transaction/support/paths.js.map +1 -0
  386. package/lib/provider/transaction/support/publication.d.ts +9 -0
  387. package/lib/provider/transaction/support/publication.d.ts.map +1 -0
  388. package/lib/provider/transaction/support/publication.js +92 -0
  389. package/lib/provider/transaction/support/publication.js.map +1 -0
  390. package/lib/provider/transaction/types.d.ts +38 -0
  391. package/lib/provider/transaction/types.d.ts.map +1 -0
  392. package/lib/provider/transaction/types.js +2 -0
  393. package/lib/provider/transaction/types.js.map +1 -0
  394. package/lib/provider/types.d.ts +22 -3
  395. package/lib/provider/types.d.ts.map +1 -1
  396. package/lib/provider/types.js +1 -1
  397. package/lib/provider/types.js.map +1 -1
  398. package/lib/provider/worktree-lifecycle.d.ts +19 -0
  399. package/lib/provider/worktree-lifecycle.d.ts.map +1 -0
  400. package/lib/provider/worktree-lifecycle.js +44 -0
  401. package/lib/provider/worktree-lifecycle.js.map +1 -0
  402. package/lib/typert.host.js +269 -30
  403. package/lib/typert.remote-client.d.ts +10 -0
  404. package/lib/typert.remote-client.d.ts.map +1 -1
  405. package/lib/typert.remote-client.js +269 -30
  406. package/package.json +48 -34
  407. package/lib/client/WorktreeContext.d.ts.map +0 -1
  408. package/lib/client/WorktreeContext.js.map +0 -1
  409. package/lib/client/WorktreeHeroContext.d.ts.map +0 -1
  410. package/lib/client/WorktreeHeroContext.js.map +0 -1
  411. package/lib/client/WorktreeModeAction.d.ts.map +0 -1
  412. package/lib/client/WorktreeModeAction.js.map +0 -1
  413. package/lib/client/WorktreeOverlay.d.ts.map +0 -1
  414. package/lib/client/WorktreeOverlay.js.map +0 -1
  415. package/lib/client/navigation.d.ts.map +0 -1
  416. package/lib/client/navigation.js.map +0 -1
  417. package/lib/client/overlay-bounds.d.ts.map +0 -1
  418. package/lib/client/overlay-bounds.js.map +0 -1
  419. package/lib/client/session-view.d.ts.map +0 -1
  420. package/lib/client/session-view.js.map +0 -1
  421. package/lib/client/sidebar-overlay-geometry.d.ts.map +0 -1
  422. package/lib/client/sidebar-overlay-geometry.js.map +0 -1
  423. package/lib/client/view-mode-store.d.ts.map +0 -1
  424. package/lib/client/view-mode-store.js.map +0 -1
  425. package/lib/client/view-mode.d.ts.map +0 -1
  426. package/lib/client/view-mode.js.map +0 -1
  427. package/lib/client/virtual-workspace-membership.d.ts +0 -27
  428. package/lib/client/virtual-workspace-membership.d.ts.map +0 -1
  429. package/lib/client/virtual-workspace-membership.js +0 -106
  430. package/lib/client/virtual-workspace-membership.js.map +0 -1
  431. package/lib/client/worktree-context-store.d.ts.map +0 -1
  432. package/lib/client/worktree-context-store.js.map +0 -1
  433. package/lib/client/worktree-context.d.ts.map +0 -1
  434. package/lib/client/worktree-context.js.map +0 -1
  435. package/lib/client/worktree-error-copy.d.ts.map +0 -1
  436. package/lib/client/worktree-error-copy.js.map +0 -1
  437. package/lib/client/worktree-expand-state.d.ts.map +0 -1
  438. package/lib/client/worktree-expand-state.js.map +0 -1
  439. package/lib/client/worktree-permission-icon.d.ts.map +0 -1
  440. package/lib/client/worktree-permission-icon.js.map +0 -1
  441. package/lib/client/worktree-permission.d.ts.map +0 -1
  442. package/lib/client/worktree-permission.js.map +0 -1
  443. package/lib/client/worktree-session-fork.d.ts.map +0 -1
  444. package/lib/client/worktree-session-fork.js +0 -174
  445. package/lib/client/worktree-session-fork.js.map +0 -1
  446. package/lib/client/worktree-session-order.d.ts.map +0 -1
  447. package/lib/client/worktree-session-order.js.map +0 -1
  448. package/lib/client/worktree-session-position.d.ts.map +0 -1
  449. package/lib/client/worktree-session-position.js.map +0 -1
  450. package/lib/client/worktree-session.d.ts.map +0 -1
  451. package/lib/client/worktree-session.js.map +0 -1
  452. package/lib/client/worktree-surface-dialogs.d.ts.map +0 -1
  453. package/lib/client/worktree-surface-dialogs.js.map +0 -1
  454. package/lib/client/worktree-surface-rows.d.ts.map +0 -1
  455. package/lib/client/worktree-surface-rows.js.map +0 -1
  456. package/lib/client/worktree-surface-selectors.d.ts.map +0 -1
  457. package/lib/client/worktree-surface-selectors.js.map +0 -1
  458. package/lib/client/worktree-surface-types.d.ts.map +0 -1
  459. package/lib/client/worktree-surface-types.js +0 -2
  460. package/lib/client/worktree-surface-types.js.map +0 -1
  461. package/lib/client/worktree-view-actions.d.ts.map +0 -1
  462. package/lib/client/worktree-view-actions.js.map +0 -1
  463. package/lib/client/worktree-view-errors.d.ts.map +0 -1
  464. package/lib/client/worktree-view-errors.js.map +0 -1
  465. package/lib/client/worktree-view-read.d.ts.map +0 -1
  466. package/lib/client/worktree-view-read.js.map +0 -1
  467. package/lib/client/worktree-view.d.ts.map +0 -1
  468. package/lib/client/worktree-view.js.map +0 -1
  469. package/lib/provider/git.d.ts.map +0 -1
  470. package/lib/provider/git.js.map +0 -1
  471. package/lib/provider/mutation-lock.d.ts.map +0 -1
  472. package/lib/provider/mutation-lock.js.map +0 -1
  473. package/lib/provider/repository-fingerprint.d.ts.map +0 -1
  474. package/lib/provider/repository-fingerprint.js.map +0 -1
  475. package/lib/provider/sidecar-persistence.d.ts.map +0 -1
  476. package/lib/provider/sidecar-persistence.js.map +0 -1
  477. package/lib/provider/sidecar-schema.d.ts.map +0 -1
  478. package/lib/provider/sidecar-schema.js.map +0 -1
  479. package/lib/provider/sidecar.d.ts.map +0 -1
  480. package/lib/provider/sidecar.js.map +0 -1
  481. package/lib/provider/subprocess.d.ts.map +0 -1
  482. package/lib/provider/subprocess.js.map +0 -1
  483. package/lib/provider/transaction.d.ts +0 -65
  484. package/lib/provider/transaction.d.ts.map +0 -1
  485. package/lib/provider/transaction.js +0 -1011
  486. package/lib/provider/transaction.js.map +0 -1
  487. /package/lib/client/{overlay-bounds.d.ts → overlay/overlay-bounds.d.ts} +0 -0
  488. /package/lib/client/{overlay-bounds.js → overlay/overlay-bounds.js} +0 -0
  489. /package/lib/client/{sidebar-overlay-geometry.d.ts → overlay/sidebar-overlay-geometry.d.ts} +0 -0
  490. /package/lib/client/{sidebar-overlay-geometry.js → overlay/sidebar-overlay-geometry.js} +0 -0
  491. /package/lib/client/{worktree-permission-icon.d.ts → permission/worktree-permission-icon.d.ts} +0 -0
  492. /package/lib/client/{worktree-permission-icon.js → permission/worktree-permission-icon.js} +0 -0
  493. /package/lib/client/{worktree-permission.d.ts → permission/worktree-permission.d.ts} +0 -0
  494. /package/lib/client/{worktree-permission.js → permission/worktree-permission.js} +0 -0
  495. /package/lib/client/{session-view.d.ts → session/session-view.d.ts} +0 -0
  496. /package/lib/client/{session-view.js → session/session-view.js} +0 -0
  497. /package/lib/client/{worktree-session-order.js → session/worktree-session-order.js} +0 -0
  498. /package/lib/client/{worktree-session-position.d.ts → session/worktree-session-position.d.ts} +0 -0
  499. /package/lib/client/{worktree-session-position.js → session/worktree-session-position.js} +0 -0
  500. /package/lib/client/{navigation.d.ts → view/navigation.d.ts} +0 -0
  501. /package/lib/client/{navigation.js → view/navigation.js} +0 -0
  502. /package/lib/client/{worktree-error-copy.js → view/worktree-error-copy.js} +0 -0
  503. /package/lib/client/{worktree-view-errors.d.ts → view/worktree-view-errors.d.ts} +0 -0
  504. /package/lib/client/{worktree-view-errors.js → view/worktree-view-errors.js} +0 -0
  505. /package/lib/client/{worktree-view.d.ts → view/worktree-view.d.ts} +0 -0
  506. /package/lib/client/{worktree-view.js → view/worktree-view.js} +0 -0
  507. /package/lib/provider/{repository-fingerprint.js → git/repository-fingerprint.js} +0 -0
  508. /package/lib/provider/{mutation-lock.d.ts → sidecar/mutation-lock.d.ts} +0 -0
@@ -1,1254 +1,55 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore, } from 'react';
3
- import { IconBranchOutline16, IconCloseOutline16, IconProjectAddOutline16, IconSearchOutline16, RiskConfirmation, } from '@deepseek-ai/dsh-client-ui-primitives';
4
- import { openWorktreeSession } from './navigation.js';
5
- import { useSidebarOverlayGeometry } from './sidebar-overlay-geometry.js';
6
- import { isMainExpanded, isWorkspaceExpanded, isWorktreeExpanded, } from './worktree-expand-state.js';
7
- import { effectiveViewMode, unboundSessionIds, workspaceSessionIds } from './view-mode.js';
8
- import { formatWorktreePermissionNotice, formatWorktreeViewError, } from './worktree-error-copy.js';
9
- import { deriveSessionPresentationIndex, filterVisibleSessionIds, hasOngoingSession, sessionMatchesQuery, } from './session-view.js';
10
- import { nextSessionOrderAccount, reorderSessionIds, } from './worktree-session-order.js';
11
- import { retryWorktreeSessionBinding } from './worktree-session.js';
12
- import { WorktreeCreateDialog, WorktreeRemovalDialog, WorktreeSessionRenameDialog, WorktreeWorkspaceDeleteDialog, WorktreeWorkspaceRenameDialog, } from './worktree-surface-dialogs.js';
13
- import { bindingIdsFor, clearSessionGroupExpansion, includesText, isCompleteWorktreeWorkspaceSnapshot, currentSessionRevealKeys, isSessionGroupAutoExpanded, resolveCurrentSessionLocation, workspaceMatches, } from './worktree-surface-selectors.js';
14
- import { scrollCurrentSessionIntoView } from './worktree-session-position.js';
15
- import { WorktreeGroupRow, WorktreeSessionGroup, WorktreeWorkspaceRow, } from './worktree-surface-rows.js';
16
- import { executeWorktreeAction, createDefaultWorktreeName, createNumberedWorktreeName, createWorktreeModalViewLoader, createWorktreeRefreshGuard, filterArchivedSessionIds, loadWorktreeViews, mergeWorktreeView, reconcileBaseBranchSelection, resolveWorktreeMove, selectDefaultBaseBranch, stableWorkspaceIds, toRetryableWorktreeOrderError, toWorktreeViewError, WorktreeSessionBindingError, WorktreeSessionPermissionError, } from './worktree-view.js';
2
+ import { AccessConfirmation } from './surface/components/AccessConfirmation.js';
3
+ import { LifecycleDialogs } from './surface/components/LifecycleDialogs.js';
4
+ import { NativeDialogs } from './surface/components/NativeDialogs.js';
5
+ import { RegistrationDialog } from './surface/components/RegistrationDialog.js';
6
+ import { SurfaceContent } from './surface/components/SurfaceContent.js';
7
+ import { SurfaceHeader } from './surface/components/SurfaceHeader.js';
8
+ import { useDragActions } from './surface/actions/useDragActions.js';
9
+ import { useLifecycleActions } from './surface/actions/useLifecycleActions.js';
10
+ import { useLifecycleState } from './surface/state/useLifecycleState.js';
11
+ import { useNativeActions } from './surface/actions/useNativeActions.js';
12
+ import { useRegistrationState } from './surface/state/useRegistrationState.js';
13
+ import { useSessionActions } from './surface/actions/useSessionActions.js';
14
+ import { useSessionExpansion } from './surface/state/useSessionExpansion.js';
15
+ import { useSessionOrdering } from './surface/state/useSessionOrdering.js';
16
+ import { useSurfaceMenus } from './surface/state/useSurfaceMenus.js';
17
+ import { useSurfaceMutation } from './surface/actions/useSurfaceMutation.js';
18
+ import { useSurfaceRefresh } from './surface/state/useSurfaceRefresh.js';
19
+ import { useSurfaceSources } from './surface/state/useSurfaceSources.js';
20
+ import { useWorktreeRegistration } from './surface/actions/useWorktreeRegistration.js';
17
21
  import styles from './worktree.css';
18
- function toNativeWorktreeViewError(error) {
19
- const viewError = toWorktreeViewError(error);
20
- if (typeof error === 'object' && error !== null)
21
- return viewError;
22
- return { ...viewError, message: String(error) };
23
- }
24
- const EMPTY_READ_STATE = { status: 'idle', views: [] };
25
- const EMPTY_PERMISSION_NOTICE = undefined;
26
- const EMPTY_PERMISSION_NOTICE_SUBSCRIBE = () => () => { };
27
- const EMPTY_PERMISSION_NOTICE_SNAPSHOT = () => EMPTY_PERMISSION_NOTICE;
28
- const EMPTY_FULL_ACCESS_CONFIRMATION_SUBSCRIBE = () => () => { };
29
- const EMPTY_FULL_ACCESS_CONFIRMATION_SNAPSHOT = () => undefined;
30
- const EMPTY_FORK_RECOVERY_SNAPSHOT = { revision: 0, pending: [] };
31
- const EMPTY_FORK_RECOVERY_STORE = {
32
- getSnapshot: () => EMPTY_FORK_RECOVERY_SNAPSHOT,
33
- subscribe: () => () => { },
34
- };
35
- function updatedAtById(sessionIds, sessions) {
36
- return Object.fromEntries(sessionIds.map((sessionId) => [sessionId, sessions.byId[sessionId]?.updatedAt]));
37
- }
38
- function forkRecoveryError(recovery) {
39
- const error = toNativeWorktreeViewError(recovery.error);
40
- return {
41
- ...error,
42
- code: error.code === 'WORKTREE_VIEW_FAILED' ? 'SESSION_BINDING_FAILED' : error.code,
43
- details: {
44
- ...(error.details ?? {}),
45
- sessionId: recovery.childSessionId,
46
- },
47
- };
48
- }
49
- function useStableWorkspaceIds(workspaces) {
50
- const next = workspaces.map((workspace) => workspace.workspaceId);
51
- const previousRef = useRef([]);
52
- const stable = stableWorkspaceIds(previousRef.current, next);
53
- if (stable !== previousRef.current)
54
- previousRef.current = stable;
55
- return previousRef.current;
56
- }
57
- /**
58
- * Peer Worktree navigation surface. It keeps the original DSH Workspace mode
59
- * intact and renders a browser-local Workspace → Worktree → Session projection.
60
- */
61
- export function WorktreeSurface({ useStore, actions, useSessions, useWorkspaces, t, available, expandState, sessionOrder, manager, permission, confirmFullAccess, fullAccessConfirmation, onPermissionResult, onPermissionNotice, permissionNotice, invalidateWorktreeContext, createWorkspace, createSessionForWorktree: createSessionCallback, createMainSession, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, insertSessionBefore, insertWorktreeBefore, renameSession, forkSession, archiveSession, forkRecovery, retryForkSession, ensureSessionWorkspace, syncSessionWorkspaces, openSession, }) {
62
- const preferredMode = useStore((state) => state.viewMode);
63
- const mode = effectiveViewMode(preferredMode, available && manager !== undefined);
64
- const sessions = useSessions((state) => state);
65
- const workspaces = useWorkspaces((state) => state);
66
- const forkRecoveryStore = forkRecovery ?? EMPTY_FORK_RECOVERY_STORE;
67
- const forkRecoverySnapshot = useSyncExternalStore(forkRecoveryStore.subscribe, forkRecoveryStore.getSnapshot, forkRecoveryStore.getSnapshot);
68
- const currentSessionId = sessions.current;
69
- const workspaceIds = useStableWorkspaceIds(workspaces.items);
70
- const [readState, setReadState] = useState(EMPTY_READ_STATE);
71
- const expandSnapshot = useSyncExternalStore(expandState.subscribe, expandState.getSnapshot, expandState.getSnapshot);
72
- const permissionNoticeSnapshot = useSyncExternalStore(permissionNotice?.subscribe ?? EMPTY_PERMISSION_NOTICE_SUBSCRIBE, permissionNotice?.getSnapshot ?? EMPTY_PERMISSION_NOTICE_SNAPSHOT, permissionNotice?.getSnapshot ?? EMPTY_PERMISSION_NOTICE_SNAPSHOT);
73
- const fullAccessConfirmationSnapshot = useSyncExternalStore(fullAccessConfirmation?.subscribe ?? EMPTY_FULL_ACCESS_CONFIRMATION_SUBSCRIBE, fullAccessConfirmation?.getSnapshot ?? EMPTY_FULL_ACCESS_CONFIRMATION_SNAPSHOT, fullAccessConfirmation?.getSnapshot ?? EMPTY_FULL_ACCESS_CONFIRMATION_SNAPSHOT);
74
- const fullAccessConfirmationKey = fullAccessConfirmationSnapshot === undefined
75
- ? ''
76
- : [
77
- fullAccessConfirmationSnapshot.workspaceId,
78
- fullAccessConfirmationSnapshot.worktreeId,
79
- fullAccessConfirmationSnapshot.sessionId,
80
- fullAccessConfirmationSnapshot.cwd,
81
- ].join('\u0000');
82
- const [fullAccessAcknowledged, setFullAccessAcknowledged] = useState(false);
83
- useEffect(() => {
84
- setFullAccessAcknowledged(false);
85
- }, [fullAccessConfirmationKey]);
86
- const sessionOrderSnapshot = useSyncExternalStore(sessionOrder.subscribe, sessionOrder.getSnapshot, sessionOrder.getSnapshot);
87
- const sessionPresentations = useMemo(() => deriveSessionPresentationIndex(sessions), [sessions.byId]);
88
- const readStateRef = useRef(readState);
89
- readStateRef.current = readState;
90
- const [searchQuery, setSearchQuery] = useState('');
91
- const [currentSessionReveal, setCurrentSessionReveal] = useState();
92
- const searchQueryRef = useRef(searchQuery);
93
- searchQueryRef.current = searchQuery;
94
- const locateGenerationRef = useRef(0);
95
- const positionedLocateGenerationRef = useRef();
96
- const [worktreeModalWorkspaceId, setWorktreeModalWorkspaceId] = useState();
97
- const [modalReadError, setModalReadError] = useState();
98
- const [modalReadLoading, setModalReadLoading] = useState(false);
99
- const [worktreeModalMode, setWorktreeModalMode] = useState('create');
100
- const [importCandidates, setImportCandidates] = useState({
101
- status: 'idle',
102
- candidates: [],
22
+ /** Composes independent surface state/action domains into the sidebar overlay. */
23
+ export function WorktreeSurface(props) {
24
+ const source = useSurfaceSources({ props });
25
+ const registrationState = useRegistrationState({ props });
26
+ const read = useSurfaceRefresh({ source, props, registrationState });
27
+ const mutation = useSurfaceMutation({ read });
28
+ const lifecycleState = useLifecycleState({ props, source, mutation });
29
+ const menus = useSurfaceMenus();
30
+ const ordering = useSessionOrdering({ read, source, props });
31
+ const expansion = useSessionExpansion({ read, source, props });
32
+ const native = useNativeActions({ source, props, mutation });
33
+ const drag = useDragActions({ source, props, mutation, read });
34
+ const session = useSessionActions({ source, props, mutation, read });
35
+ const registration = useWorktreeRegistration({
36
+ source,
37
+ registrationState,
38
+ read,
39
+ props,
40
+ mutation,
41
+ session,
103
42
  });
104
- const [selectedImportPath, setSelectedImportPath] = useState();
105
- const [openWorkspaceMenuId, setOpenWorkspaceMenuId] = useState();
106
- const [openMainMenuId, setOpenMainMenuId] = useState();
107
- const [openWorktreeMenuId, setOpenWorktreeMenuId] = useState();
108
- const [worktreeRemoval, setWorktreeRemoval] = useState();
109
- const [selectedBranch, setSelectedBranch] = useState('');
110
- const [newBranch, setNewBranch] = useState('');
111
- const [pendingSessionBinding, setPendingSessionBinding] = useState();
112
- const [actionError, setActionError] = useState();
113
- const [actionPending, setActionPending] = useState(false);
114
- const [forkRetryKey, setForkRetryKey] = useState();
115
- const [sessionRenameTarget, setSessionRenameTarget] = useState();
116
- const [sessionRenameDraft, setSessionRenameDraft] = useState('');
117
- const [sessionRenamePending, setSessionRenamePending] = useState(false);
118
- const [sessionRenameError, setSessionRenameError] = useState();
119
- const [workspaceDrag, setWorkspaceDrag] = useState();
120
- const [workspaceRenameTarget, setWorkspaceRenameTarget] = useState();
121
- const [workspaceRenameDraft, setWorkspaceRenameDraft] = useState('');
122
- const [workspaceRenamePending, setWorkspaceRenamePending] = useState(false);
123
- const [workspaceRenameError, setWorkspaceRenameError] = useState();
124
- const [workspaceDeleteTarget, setWorkspaceDeleteTarget] = useState();
125
- const [workspaceDeletePending, setWorkspaceDeletePending] = useState(false);
126
- const [workspaceDeleteError, setWorkspaceDeleteError] = useState();
127
- const workspaceDropCommitted = useRef(false);
128
- const [sessionDrag, setSessionDrag] = useState();
129
- const [expandedSessionGroups, setExpandedSessionGroups] = useState({});
130
- const sessionDropCommitted = useRef(false);
131
- const [worktreeDrag, setWorktreeDrag] = useState();
132
- const worktreeDropCommitted = useRef(false);
133
- const refreshGuard = useRef(createWorktreeRefreshGuard());
134
- const forkRecoveryRevisionRef = useRef(forkRecoverySnapshot.revision);
135
- const modalReadLoader = useRef(createWorktreeModalViewLoader());
136
- const modalReadViewRef = useRef();
137
- const importCandidatesGuard = useRef(createWorktreeRefreshGuard());
138
- const modalWorkspaceIdRef = useRef(worktreeModalWorkspaceId);
139
- modalWorkspaceIdRef.current = worktreeModalWorkspaceId;
140
- const { ref, width, bounds } = useSidebarOverlayGeometry(mode === 'worktree');
141
- const collapsed = width <= 64;
142
- const query = searchQuery.trim().toLocaleLowerCase();
143
- const archivedSessionIds = workspaces.archivedSessionIds ?? [];
144
- const pendingSessionArchived = pendingSessionBinding !== undefined &&
145
- archivedSessionIds.includes(pendingSessionBinding.sessionId);
146
- const refresh = useCallback(async (options = {}) => {
147
- if (manager === undefined) {
148
- refreshGuard.current.invalidate();
149
- setReadState(EMPTY_READ_STATE);
150
- return;
151
- }
152
- const preserveCurrent = options.preserveCurrent === true;
153
- if (!preserveCurrent) {
154
- setReadState({ status: 'loading', views: [] });
155
- }
156
- await refreshGuard.current.run(() => loadWorktreeViews(manager, workspaceIds, {
157
- invalidateContext: options.invalidateContext !== false,
158
- invalidateWorktreeContext,
159
- }), (views) => {
160
- setReadState({
161
- status: 'ready',
162
- views: modalReadViewRef.current === undefined
163
- ? views
164
- : mergeWorktreeView(views, modalReadViewRef.current),
165
- });
166
- }, (error) => {
167
- if (preserveCurrent)
168
- throw error;
169
- setReadState({
170
- status: 'error',
171
- views: modalReadViewRef.current === undefined ? [] : [modalReadViewRef.current],
172
- error: toWorktreeViewError(error),
173
- });
174
- });
175
- }, [invalidateWorktreeContext, manager, workspaceIds]);
176
- const loadModalWorktreeView = useCallback((workspaceId) => {
177
- setModalReadError(undefined);
178
- setModalReadLoading(true);
179
- if (manager === undefined) {
180
- setModalReadLoading(false);
181
- setModalReadError({
182
- code: 'WORKTREE_VIEW_UNAVAILABLE',
183
- message: '',
184
- retryable: true,
185
- });
186
- return;
187
- }
188
- void modalReadLoader.current.load(manager, workspaceId, (view) => {
189
- modalReadViewRef.current = view;
190
- setModalReadLoading(false);
191
- setReadState((current) => ({
192
- ...current,
193
- views: mergeWorktreeView(current.views, view),
194
- }));
195
- }, (error) => {
196
- setModalReadLoading(false);
197
- setModalReadError(toWorktreeViewError(error));
198
- });
199
- }, [manager]);
200
- useEffect(() => {
201
- if (mode === 'worktree') {
202
- void refresh({ preserveCurrent: readStateRef.current.status === 'ready' });
203
- }
204
- else {
205
- refreshGuard.current.invalidate();
206
- modalReadLoader.current.invalidate();
207
- modalReadViewRef.current = undefined;
208
- setWorktreeModalWorkspaceId(undefined);
209
- setModalReadError(undefined);
210
- setModalReadLoading(false);
211
- setReadState(EMPTY_READ_STATE);
212
- }
213
- }, [mode, refresh]);
214
- useEffect(() => {
215
- if (forkRecoveryRevisionRef.current === forkRecoverySnapshot.revision)
216
- return;
217
- forkRecoveryRevisionRef.current = forkRecoverySnapshot.revision;
218
- if (mode !== 'worktree' || manager === undefined)
219
- return;
220
- void refresh({
221
- preserveCurrent: readStateRef.current.status === 'ready',
222
- invalidateContext: false,
223
- }).catch(() => {
224
- // Recovery state remains visible; the next explicit retry can refresh it again.
225
- });
226
- }, [forkRecoverySnapshot.revision, manager, mode, refresh]);
227
- useEffect(() => {
228
- if (readState.status !== 'ready' || syncSessionWorkspaces === undefined)
229
- return;
230
- syncSessionWorkspaces(readState.views.flatMap((view) => view.bindings.map((binding) => ({
231
- workspaceId: binding.workspaceId,
232
- sessionId: binding.sessionId,
233
- }))));
234
- }, [readState.status, readState.views, syncSessionWorkspaces]);
235
- const viewByWorkspace = useMemo(() => new Map(readState.views.map((view) => [view.workspaceId, view])), [readState.views]);
236
- const sessionOrderInputs = useMemo(() => {
237
- if (readState.status !== 'ready')
238
- return [];
239
- const inputs = [];
240
- for (const workspace of workspaces.items) {
241
- const view = viewByWorkspace.get(workspace.workspaceId);
242
- const allWorkspaceSessionIds = filterArchivedSessionIds(workspaceSessionIds(workspaces, workspace.workspaceId, sessions.ids), archivedSessionIds);
243
- const bindings = view?.bindings ?? [];
244
- const boundSessionIds = new Set(bindings.map((binding) => binding.sessionId));
245
- const mainSessionIds = filterVisibleSessionIds(unboundSessionIds(allWorkspaceSessionIds, [...boundSessionIds]), sessions);
246
- inputs.push({
247
- accountKey: `main:${workspace.workspaceId}`,
248
- sessionIds: mainSessionIds,
249
- updatedAtById: updatedAtById(mainSessionIds, sessions),
250
- });
251
- for (const record of view?.worktrees ?? []) {
252
- const worktreeSessionIds = filterVisibleSessionIds(filterArchivedSessionIds(bindingIdsFor(bindings, record.worktreeId).filter((sessionId) => sessions.ids.includes(sessionId)), archivedSessionIds), sessions);
253
- inputs.push({
254
- accountKey: `worktree:${record.worktreeId}`,
255
- sessionIds: worktreeSessionIds,
256
- updatedAtById: updatedAtById(worktreeSessionIds, sessions),
257
- });
258
- }
259
- }
260
- return inputs;
261
- }, [
262
- archivedSessionIds,
263
- readState.status,
264
- sessions.byId,
265
- sessions.ids,
266
- viewByWorkspace,
267
- workspaces,
268
- workspaces.items,
269
- ]);
270
- const orderedSessionIdsByAccount = useMemo(() => {
271
- const ordered = new Map();
272
- for (const input of sessionOrderInputs) {
273
- const previous = sessionOrderSnapshot.accounts[input.accountKey];
274
- ordered.set(input.accountKey, nextSessionOrderAccount({
275
- baseIds: input.sessionIds,
276
- updatedAtById: input.updatedAtById,
277
- previous,
278
- }).order);
279
- }
280
- return ordered;
281
- }, [sessionOrderInputs, sessionOrderSnapshot]);
282
- useEffect(() => {
283
- if (mode !== 'worktree' || readState.status !== 'ready')
284
- return;
285
- for (const input of sessionOrderInputs) {
286
- sessionOrder.actions.reconcile(input.accountKey, input.sessionIds, input.updatedAtById);
287
- }
288
- sessionOrder.actions.retain(sessionOrderInputs.map((input) => input.accountKey));
289
- }, [mode, readState.status, sessionOrder, sessionOrderInputs]);
290
- const currentSessionLocation = useMemo(() => readState.status === 'ready'
291
- ? resolveCurrentSessionLocation(currentSessionId, workspaces.items, readState.views)
292
- : undefined, [currentSessionId, readState.status, readState.views, workspaces.items]);
293
- const currentRevealKeys = useMemo(() => new Set(currentSessionRevealKeys(currentSessionLocation)), [currentSessionLocation]);
294
- const isCurrentSessionReveal = (key) => currentSessionReveal !== undefined &&
295
- currentSessionReveal.sessionId === currentSessionId &&
296
- currentRevealKeys.has(key) &&
297
- currentSessionReveal.suppressedKeys[key] !== true;
298
- useLayoutEffect(() => {
299
- locateGenerationRef.current += 1;
300
- positionedLocateGenerationRef.current = undefined;
301
- if (mode !== 'worktree') {
302
- setCurrentSessionReveal(undefined);
303
- return;
304
- }
305
- if (searchQueryRef.current.trim().length > 0)
306
- setSearchQuery('');
307
- setCurrentSessionReveal(currentSessionId === undefined
308
- ? undefined
309
- : { sessionId: currentSessionId, suppressedKeys: {} });
310
- }, [currentSessionId, mode]);
311
- useLayoutEffect(() => {
312
- if (mode !== 'worktree' ||
313
- currentSessionId === undefined ||
314
- currentSessionLocation === undefined) {
315
- return;
316
- }
317
- const generation = locateGenerationRef.current;
318
- if (positionedLocateGenerationRef.current === generation)
319
- return;
320
- let cancelled = false;
321
- const frame = requestAnimationFrame(() => {
322
- if (cancelled || generation !== locateGenerationRef.current)
323
- return;
324
- if (!scrollCurrentSessionIntoView(ref.current, currentSessionId))
325
- return;
326
- positionedLocateGenerationRef.current = generation;
327
- });
328
- return () => {
329
- cancelled = true;
330
- cancelAnimationFrame(frame);
331
- };
332
- }, [
333
- currentSessionId,
334
- currentSessionLocation,
335
- currentSessionReveal,
336
- expandSnapshot,
337
- mode,
338
- query,
339
- readState.status,
340
- ]);
341
- useEffect(() => {
342
- if (readState.status !== 'ready' ||
343
- !isCompleteWorktreeWorkspaceSnapshot(workspaceIds, readState.views))
344
- return;
345
- expandState.actions.retain(workspaceIds, readState.views.flatMap((view) => view.worktrees.map((record) => record.worktreeId)));
346
- }, [expandState, readState.status, readState.views, workspaceIds]);
347
- const modalWorkspace = workspaces.items.find((workspace) => workspace.workspaceId === worktreeModalWorkspaceId);
348
- const modalView = worktreeModalWorkspaceId === undefined
349
- ? undefined
350
- : viewByWorkspace.get(worktreeModalWorkspaceId);
351
- const modalReadiness = modalView?.readiness;
352
- const modalSetupStatus = modalView === undefined
353
- ? undefined
354
- : modalReadiness?.status === 'ready'
355
- ? modalView.branches.length === 0
356
- ? 'noLocalBranch'
357
- : undefined
358
- : modalReadiness?.status;
359
- const modalCanCreate = !modalReadLoading && modalSetupStatus === undefined && modalReadiness?.status === 'ready';
360
- useEffect(() => {
361
- if (worktreeModalWorkspaceId === undefined || modalView === undefined)
362
- return;
363
- if (modalView.readiness.status !== 'ready') {
364
- setSelectedBranch('');
365
- setNewBranch('');
366
- return;
367
- }
368
- setSelectedBranch((current) => reconcileBaseBranchSelection(current, modalView.branches));
369
- setNewBranch((current) => {
370
- if (current.length > 0)
371
- return current;
372
- const existingNames = [
373
- ...modalView.branches.map((branch) => branch.name),
374
- ...modalView.worktrees.map((worktree) => worktree.branch),
375
- ];
376
- return createDefaultWorktreeName(existingNames);
377
- });
378
- }, [modalView, worktreeModalWorkspaceId]);
379
- const runMutation = async (operation) => {
380
- setActionPending(true);
381
- setActionError(undefined);
382
- try {
383
- await operation();
384
- await refresh({ preserveCurrent: true });
385
- }
386
- catch (error) {
387
- setActionError(toWorktreeViewError(error));
388
- }
389
- finally {
390
- setActionPending(false);
391
- }
392
- };
393
- const loadImportCandidates = useCallback(async (workspaceId) => {
394
- if (manager === undefined)
395
- return;
396
- setImportCandidates((current) => ({ status: 'loading', candidates: current.candidates }));
397
- await importCandidatesGuard.current.run(() => manager.listImportCandidates({ workspaceId }), (candidates) => {
398
- if (modalWorkspaceIdRef.current !== workspaceId)
399
- return;
400
- setImportCandidates({ status: 'ready', candidates });
401
- }, (error) => {
402
- if (modalWorkspaceIdRef.current !== workspaceId)
403
- return;
404
- setImportCandidates((current) => ({
405
- status: 'error',
406
- candidates: current.candidates,
407
- error: toWorktreeViewError(error),
408
- }));
409
- });
410
- }, [manager]);
411
- const workspaceRenameTrimmed = workspaceRenameDraft.trim();
412
- const workspaceRenameDuplicate = workspaceRenameTarget !== undefined &&
413
- workspaceRenameTrimmed.length > 0 &&
414
- workspaces.items.some((workspace) => workspace.workspaceId !== workspaceRenameTarget.workspaceId &&
415
- workspace.title === workspaceRenameTrimmed);
416
- const workspaceRenameBlocked = workspaceRenamePending ||
417
- workspaceRenameTarget === undefined ||
418
- workspaceRenameTrimmed.length === 0 ||
419
- workspaceRenameTrimmed === workspaceRenameTarget?.currentTitle ||
420
- workspaceRenameDuplicate;
421
- const openWorkspaceRename = (workspace) => {
422
- setWorkspaceRenameTarget({
423
- workspaceId: workspace.workspaceId,
424
- currentTitle: workspace.title,
425
- });
426
- setWorkspaceRenameDraft(workspace.title);
427
- setWorkspaceRenameError(undefined);
428
- };
429
- const closeWorkspaceRename = () => {
430
- if (workspaceRenamePending)
431
- return;
432
- setWorkspaceRenameTarget(undefined);
433
- setWorkspaceRenameError(undefined);
434
- };
435
- const confirmWorkspaceRename = async () => {
436
- const target = workspaceRenameTarget;
437
- if (workspaceRenameBlocked || target === undefined)
438
- return;
439
- if (renameWorkspace === undefined) {
440
- setWorkspaceRenameError({
441
- code: 'WORKSPACE_RENAME_UNAVAILABLE',
442
- message: '',
443
- retryable: true,
444
- });
445
- return;
446
- }
447
- setWorkspaceRenamePending(true);
448
- setWorkspaceRenameError(undefined);
449
- try {
450
- await renameWorkspace(target.workspaceId, workspaceRenameTrimmed);
451
- setWorkspaceRenameTarget(undefined);
452
- }
453
- catch (error) {
454
- setWorkspaceRenameError(toNativeWorktreeViewError(error));
455
- }
456
- finally {
457
- setWorkspaceRenamePending(false);
458
- }
459
- };
460
- const openWorkspaceDelete = (workspace) => {
461
- setWorkspaceDeleteTarget({ workspaceId: workspace.workspaceId, title: workspace.title });
462
- setWorkspaceDeleteError(undefined);
463
- };
464
- const closeWorkspaceDelete = () => {
465
- if (workspaceDeletePending)
466
- return;
467
- setWorkspaceDeleteTarget(undefined);
468
- setWorkspaceDeleteError(undefined);
469
- };
470
- const confirmWorkspaceDelete = async () => {
471
- const target = workspaceDeleteTarget;
472
- if (target === undefined || workspaceDeletePending)
473
- return;
474
- if (deleteWorkspace === undefined) {
475
- setWorkspaceDeleteError({
476
- code: 'WORKSPACE_DELETE_UNAVAILABLE',
477
- message: '',
478
- retryable: true,
479
- });
480
- return;
481
- }
482
- setWorkspaceDeletePending(true);
483
- setWorkspaceDeleteError(undefined);
484
- try {
485
- await deleteWorkspace(target.workspaceId);
486
- setWorkspaceDeleteTarget(undefined);
487
- }
488
- catch (error) {
489
- setWorkspaceDeleteError(toNativeWorktreeViewError(error));
490
- }
491
- finally {
492
- setWorkspaceDeletePending(false);
493
- }
494
- };
495
- const commitWorkspaceDrag = (activeDrag, over) => {
496
- if (workspaceDropCommitted.current)
497
- return;
498
- workspaceDropCommitted.current = true;
499
- setWorkspaceDrag(undefined);
500
- const rows = workspaces.items;
501
- const targetIndex = rows.findIndex((workspace) => workspace.workspaceId === over.workspaceId);
502
- const sourceIndex = rows.findIndex((workspace) => workspace.workspaceId === activeDrag.workspaceId);
503
- if (targetIndex === -1 || sourceIndex === -1)
504
- return;
505
- const beforeWorkspaceId = over.half === 'before' ? over.workspaceId : rows[targetIndex + 1]?.workspaceId;
506
- const anchorIndex = beforeWorkspaceId === undefined
507
- ? rows.length
508
- : rows.findIndex((workspace) => workspace.workspaceId === beforeWorkspaceId);
509
- if (beforeWorkspaceId === activeDrag.workspaceId ||
510
- anchorIndex === sourceIndex ||
511
- anchorIndex === sourceIndex + 1) {
512
- return;
513
- }
514
- if (insertWorkspaceBefore === undefined) {
515
- setActionError({
516
- code: 'WORKSPACE_ORDER_UNAVAILABLE',
517
- message: '',
518
- retryable: true,
519
- });
520
- return;
521
- }
522
- setActionError(undefined);
523
- void insertWorkspaceBefore(activeDrag.workspaceId, beforeWorkspaceId).catch((error) => {
524
- setActionError(toWorktreeViewError(error));
525
- });
526
- };
527
- const commitSessionDrag = (activeDrag, over, sessionIds, workspaceId) => {
528
- if (sessionDropCommitted.current)
529
- return;
530
- sessionDropCommitted.current = true;
531
- setSessionDrag(undefined);
532
- const targetIndex = sessionIds.indexOf(over.sessionId);
533
- const sourceIndex = sessionIds.indexOf(activeDrag.sessionId);
534
- if (targetIndex === -1 || sourceIndex === -1)
535
- return;
536
- const beforeSessionId = over.half === 'before' ? over.sessionId : sessionIds[targetIndex + 1];
537
- const anchorIndex = beforeSessionId === undefined ? sessionIds.length : sessionIds.indexOf(beforeSessionId);
538
- if (beforeSessionId === activeDrag.sessionId ||
539
- anchorIndex === sourceIndex ||
540
- anchorIndex === sourceIndex + 1) {
541
- return;
542
- }
543
- if (insertSessionBefore === undefined) {
544
- setActionError({
545
- code: 'SESSION_ORDER_UNAVAILABLE',
546
- message: '',
547
- retryable: true,
548
- });
549
- return;
550
- }
551
- setActionError(undefined);
552
- const currentOrder = sessionOrderSnapshot.accounts[activeDrag.groupKey]?.order ?? sessionIds;
553
- void insertSessionBefore(workspaceId, activeDrag.sessionId, beforeSessionId)
554
- .then(() => {
555
- sessionOrder.actions.setOrder(activeDrag.groupKey, reorderSessionIds(currentOrder, activeDrag.sessionId, over.sessionId, over.half));
556
- })
557
- .catch((error) => {
558
- setActionError(toWorktreeViewError(error));
559
- });
560
- };
561
- const commitWorktreeDrag = (activeDrag, over, worktreeIds, workspaceId) => {
562
- if (worktreeDropCommitted.current)
563
- return;
564
- worktreeDropCommitted.current = true;
565
- setWorktreeDrag(undefined);
566
- if (activeDrag.workspaceId !== workspaceId)
567
- return;
568
- const move = resolveWorktreeMove(worktreeIds, activeDrag.worktreeId, over.worktreeId, over.half);
569
- if (move === undefined)
570
- return;
571
- if (insertWorktreeBefore === undefined) {
572
- setActionError({
573
- code: 'WORKTREE_ORDER_UNAVAILABLE',
574
- message: '',
575
- retryable: true,
576
- });
577
- return;
578
- }
579
- setActionError(undefined);
580
- void insertWorktreeBefore(workspaceId, activeDrag.worktreeId, move.beforeWorktreeId)
581
- .then(() => refresh({ preserveCurrent: true, invalidateContext: false }))
582
- .catch((error) => {
583
- setActionError(toRetryableWorktreeOrderError(error));
584
- });
585
- };
586
- const openSessionRename = (sessionId, currentTitle) => {
587
- setSessionRenameTarget({ sessionId, currentTitle });
588
- setSessionRenameDraft(currentTitle);
589
- setSessionRenameError(undefined);
590
- };
591
- const closeSessionRename = () => {
592
- if (sessionRenamePending)
593
- return;
594
- setSessionRenameTarget(undefined);
595
- setSessionRenameError(undefined);
596
- };
597
- const confirmSessionRename = async () => {
598
- const target = sessionRenameTarget;
599
- const title = sessionRenameDraft.trim();
600
- if (target === undefined || title.length === 0 || sessionRenamePending)
601
- return;
602
- if (renameSession === undefined) {
603
- setSessionRenameError({
604
- code: 'SESSION_RENAME_UNAVAILABLE',
605
- message: '',
606
- retryable: true,
607
- });
608
- return;
609
- }
610
- setSessionRenamePending(true);
611
- setSessionRenameError(undefined);
612
- try {
613
- await renameSession(target.sessionId, title);
614
- setSessionRenameTarget(undefined);
615
- }
616
- catch (error) {
617
- setSessionRenameError(toNativeWorktreeViewError(error));
618
- }
619
- finally {
620
- setSessionRenamePending(false);
621
- }
622
- };
623
- const archiveWorktreeSession = async (sessionId) => {
624
- if (archiveSession === undefined)
625
- return;
626
- await runMutation(() => archiveSession(sessionId));
627
- };
628
- const clearSessionGroups = (groupKeys) => {
629
- if (groupKeys.length === 0)
630
- return;
631
- setExpandedSessionGroups((current) => clearSessionGroupExpansion(current, groupKeys));
632
- };
633
- const suppressCurrentSessionReveal = (key) => {
634
- if (!isCurrentSessionReveal(key))
635
- return false;
636
- setCurrentSessionReveal((current) => {
637
- if (current === undefined || current.sessionId !== currentSessionId)
638
- return current;
639
- return {
640
- ...current,
641
- suppressedKeys: { ...current.suppressedKeys, [key]: true },
642
- };
643
- });
644
- return true;
645
- };
646
- const toggleWorkspace = (workspaceId) => {
647
- const persistedExpanded = isWorkspaceExpanded(expandSnapshot, workspaceId);
648
- const autoExpanded = isCurrentSessionReveal('workspace:' + workspaceId);
649
- const visuallyExpanded = persistedExpanded || autoExpanded;
650
- if (visuallyExpanded && autoExpanded) {
651
- suppressCurrentSessionReveal('workspace:' + workspaceId);
652
- }
653
- if (visuallyExpanded && !persistedExpanded) {
654
- clearSessionGroups([
655
- 'main:' + workspaceId,
656
- ...(viewByWorkspace.get(workspaceId)?.worktrees.map((record) => record.worktreeId) ?? []).map((worktreeId) => 'worktree:' + worktreeId),
657
- ]);
658
- return;
659
- }
660
- expandState.actions.toggleWorkspace(workspaceId);
661
- if (visuallyExpanded) {
662
- clearSessionGroups([
663
- 'main:' + workspaceId,
664
- ...(viewByWorkspace.get(workspaceId)?.worktrees.map((record) => record.worktreeId) ?? []).map((worktreeId) => 'worktree:' + worktreeId),
665
- ]);
666
- }
667
- };
668
- const toggleMain = (workspaceId) => {
669
- const persistedExpanded = isMainExpanded(expandSnapshot, workspaceId);
670
- const autoExpanded = isCurrentSessionReveal('main:' + workspaceId);
671
- const visuallyExpanded = persistedExpanded || autoExpanded;
672
- if (visuallyExpanded && autoExpanded) {
673
- suppressCurrentSessionReveal('main:' + workspaceId);
674
- }
675
- if (visuallyExpanded && !persistedExpanded) {
676
- clearSessionGroups(['main:' + workspaceId]);
677
- return;
678
- }
679
- expandState.actions.toggleMain(workspaceId);
680
- if (visuallyExpanded)
681
- clearSessionGroups(['main:' + workspaceId]);
682
- };
683
- const toggleWorktree = (worktreeId) => {
684
- const persistedExpanded = isWorktreeExpanded(expandSnapshot, worktreeId);
685
- const autoExpanded = isCurrentSessionReveal('worktree:' + worktreeId);
686
- const visuallyExpanded = persistedExpanded || autoExpanded;
687
- if (visuallyExpanded && autoExpanded) {
688
- suppressCurrentSessionReveal('worktree:' + worktreeId);
689
- }
690
- if (visuallyExpanded && !persistedExpanded) {
691
- clearSessionGroups(['worktree:' + worktreeId]);
692
- return;
693
- }
694
- expandState.actions.toggleWorktree(worktreeId);
695
- if (visuallyExpanded)
696
- clearSessionGroups(['worktree:' + worktreeId]);
697
- };
698
- const toggleSessionGroup = (groupKey, autoExpanded) => {
699
- const transientExpanded = expandedSessionGroups[groupKey] === true;
700
- if (autoExpanded) {
701
- suppressCurrentSessionReveal('session-group:' + groupKey);
702
- setExpandedSessionGroups((current) => {
703
- const next = { ...current };
704
- delete next[groupKey];
705
- return next;
706
- });
707
- return;
708
- }
709
- setExpandedSessionGroups((current) => ({
710
- ...current,
711
- [groupKey]: !transientExpanded,
712
- }));
713
- };
714
- const closeWorktreeCreator = (force = false) => {
715
- if (actionPending && !force)
716
- return;
717
- modalReadLoader.current.invalidate();
718
- modalReadViewRef.current = undefined;
719
- importCandidatesGuard.current.invalidate();
720
- setWorktreeModalWorkspaceId(undefined);
721
- setModalReadError(undefined);
722
- setModalReadLoading(false);
723
- };
724
- const openWorktreeCreator = (workspace, defaults = {}) => {
725
- const view = viewByWorkspace.get(workspace.workspaceId);
726
- modalReadLoader.current.invalidate();
727
- modalReadViewRef.current = undefined;
728
- importCandidatesGuard.current.invalidate();
729
- setWorktreeModalWorkspaceId(workspace.workspaceId);
730
- setWorktreeModalMode('create');
731
- setImportCandidates({ status: 'idle', candidates: [] });
732
- setSelectedImportPath(undefined);
733
- setActionError(undefined);
734
- setModalReadError(undefined);
735
- setModalReadLoading(false);
736
- if (view === undefined) {
737
- setSelectedBranch(defaults.baseBranch ?? '');
738
- setNewBranch(defaults.newBranch ?? '');
739
- loadModalWorktreeView(workspace.workspaceId);
740
- return;
741
- }
742
- setSelectedBranch(defaults.baseBranch ?? selectDefaultBaseBranch(view.branches));
743
- setNewBranch(defaults.newBranch ?? createDefaultWorktreeName([
744
- ...view.branches.map((branch) => branch.name),
745
- ...view.worktrees.map((worktree) => worktree.branch),
746
- ]));
747
- };
748
- const changeWorktreeModalMode = (mode) => {
749
- setWorktreeModalMode(mode);
750
- if (mode === 'import' &&
751
- worktreeModalWorkspaceId !== undefined &&
752
- importCandidates.status === 'idle') {
753
- void loadImportCandidates(worktreeModalWorkspaceId);
754
- }
755
- };
756
- const continueWorktreeRegistration = async (registeredWorktree) => {
757
- closeWorktreeCreator(true);
758
- if (createSessionCallback === undefined) {
759
- await refresh({ preserveCurrent: true });
760
- setActionError({
761
- code: 'WORKTREE_REGISTRATION_SESSION_UNAVAILABLE',
762
- message: '',
763
- retryable: true,
764
- });
765
- return;
766
- }
767
- const sessionInput = {
768
- workspaceId: registeredWorktree.workspaceId,
769
- worktreeId: registeredWorktree.worktreeId,
770
- cwd: registeredWorktree.absolutePath,
771
- };
772
- try {
773
- await createSessionCallback(sessionInput);
774
- await invalidateWorktreeContext?.(registeredWorktree.workspaceId);
775
- }
776
- catch (error) {
777
- if (error instanceof WorktreeSessionBindingError && error.retryable) {
778
- setPendingSessionBinding({ ...sessionInput, sessionId: error.sessionId });
779
- }
780
- if (error instanceof WorktreeSessionPermissionError && error.retryable) {
781
- setPendingSessionBinding({
782
- ...sessionInput,
783
- sessionId: error.sessionId,
784
- permissionRequired: true,
785
- });
786
- }
787
- throw error;
788
- }
789
- await refresh({ preserveCurrent: true });
790
- };
791
- const submitWorktree = async () => {
792
- const worktreeName = newBranch.trim();
793
- const selectedImportCandidate = importCandidates.candidates.find((candidate) => candidate.absolutePath === selectedImportPath);
794
- if (manager === undefined || modalWorkspace === undefined)
795
- return;
796
- if (worktreeModalMode === 'create' &&
797
- (!modalCanCreate || selectedBranch.length === 0 || worktreeName.length === 0))
798
- return;
799
- if (worktreeModalMode === 'import' && selectedImportCandidate === undefined)
800
- return;
801
- setActionPending(true);
802
- setActionError(undefined);
803
- setPendingSessionBinding(undefined);
804
- try {
805
- const registeredWorktree = worktreeModalMode === 'create'
806
- ? await executeWorktreeAction(manager, {
807
- type: 'createWorktree',
808
- input: {
809
- workspaceId: modalWorkspace.workspaceId,
810
- branch: selectedBranch,
811
- newBranch: worktreeName,
812
- },
813
- })
814
- : await executeWorktreeAction(manager, {
815
- type: 'importWorktree',
816
- input: {
817
- workspaceId: modalWorkspace.workspaceId,
818
- absolutePath: selectedImportCandidate.absolutePath,
819
- },
820
- });
821
- if (registeredWorktree === undefined) {
822
- throw {
823
- code: 'WORKTREE_RECORD_MISSING',
824
- message: '',
825
- retryable: true,
826
- };
827
- }
828
- await continueWorktreeRegistration(registeredWorktree);
829
- }
830
- catch (error) {
831
- setActionError(toWorktreeViewError(error));
832
- }
833
- finally {
834
- setActionPending(false);
835
- }
836
- };
837
- const createSession = async (input) => {
838
- if (createSessionCallback === undefined) {
839
- setActionError({
840
- code: 'SESSION_CREATE_UNAVAILABLE',
841
- message: '',
842
- retryable: true,
843
- });
844
- return;
845
- }
846
- setActionPending(true);
847
- setActionError(undefined);
848
- setPendingSessionBinding(undefined);
849
- try {
850
- await createSessionCallback(input);
851
- await invalidateWorktreeContext?.(input.workspaceId);
852
- await refresh({ preserveCurrent: true });
853
- }
854
- catch (error) {
855
- if (error instanceof WorktreeSessionBindingError && error.retryable) {
856
- setPendingSessionBinding({ ...input, sessionId: error.sessionId });
857
- }
858
- if (error instanceof WorktreeSessionPermissionError && error.retryable) {
859
- setPendingSessionBinding({
860
- ...input,
861
- sessionId: error.sessionId,
862
- permissionRequired: true,
863
- });
864
- }
865
- setActionError(toWorktreeViewError(error));
866
- }
867
- finally {
868
- setActionPending(false);
869
- }
870
- };
871
- const retrySessionBinding = async () => {
872
- if (manager === undefined || pendingSessionBinding === undefined || pendingSessionArchived)
873
- return;
874
- const pending = pendingSessionBinding;
875
- setActionPending(true);
876
- setActionError(undefined);
877
- try {
878
- await retryWorktreeSessionBinding({
879
- manager,
880
- pending,
881
- archived: false,
882
- ensureSessionWorkspace: (workspaceId, sessionId) => {
883
- ensureSessionWorkspace?.(workspaceId, sessionId);
884
- },
885
- permission,
886
- confirmFullAccess,
887
- onPermissionResult,
888
- openSession,
889
- });
890
- setPendingSessionBinding(undefined);
891
- await refresh({ preserveCurrent: true });
892
- await invalidateWorktreeContext?.(pending.workspaceId);
893
- }
894
- catch (error) {
895
- if (error instanceof WorktreeSessionBindingError && !error.retryable) {
896
- setPendingSessionBinding(undefined);
897
- }
898
- setActionError(toWorktreeViewError(error));
899
- }
900
- finally {
901
- setActionPending(false);
902
- }
903
- };
904
- const retryForkBinding = async (key) => {
905
- if (retryForkSession === undefined || forkRetryKey !== undefined)
906
- return;
907
- setForkRetryKey(key);
908
- try {
909
- await retryForkSession(key);
910
- }
911
- catch (error) {
912
- setActionError(toNativeWorktreeViewError(error));
913
- }
914
- finally {
915
- setForkRetryKey(undefined);
916
- }
917
- };
918
- const openWorkspaceSession = (workspaceId, sessionId) => {
919
- ensureSessionWorkspace?.(workspaceId, sessionId);
920
- openWorktreeSession({ open: openSession }, sessionId);
921
- };
922
- if (mode !== 'worktree')
43
+ const lifecycle = useLifecycleActions({ read, lifecycleState, source, props, mutation });
44
+ if (source.mode !== 'worktree')
923
45
  return null;
924
- const visibleWorkspaces = workspaces.items.filter((workspace) => workspaceMatches(workspace, viewByWorkspace.get(workspace.workspaceId), sessions, query));
46
+ const { ref, width, bounds, collapsed } = source;
47
+ const { t } = props;
925
48
  return (_jsxs("aside", { ref: ref, className: styles.surface, "data-worktree-surface": true, "data-collapsed": collapsed || undefined, "aria-label": t('mode.navigation'), style: {
926
49
  width: `${width}px`,
927
50
  ...(bounds.ready
928
51
  ? { top: `${bounds.top}px`, height: `${bounds.height}px` }
929
52
  : { height: '0px', visibility: 'hidden' }),
930
- }, children: [_jsxs("div", { className: styles.wideContent, children: [_jsxs("header", { className: styles.header, children: [_jsx("span", { className: styles.title, children: t('worktree.title') }), _jsx("button", { type: "button", className: styles.closeButton, "aria-label": t('mode.exit'), onClick: () => {
931
- actions.setViewMode('workspace-session');
932
- }, children: _jsx(IconCloseOutline16, {}) })] }), _jsxs("div", { className: styles.searchRow, children: [_jsx("span", { className: styles.searchIcon, "aria-hidden": "true", children: _jsx(IconSearchOutline16, {}) }), _jsx("input", { className: styles.searchInput, "aria-label": t('workspace.search'), placeholder: t('workspace.search'), value: searchQuery, onChange: (event) => {
933
- setSearchQuery(event.currentTarget.value);
934
- } }), _jsx("button", { type: "button", className: styles.iconButton, "aria-label": t('workspace.add'), onClick: () => {
935
- if (createWorkspace !== undefined)
936
- void runMutation(createWorkspace);
937
- }, children: _jsx(IconProjectAddOutline16, {}) })] }), _jsxs("div", { className: styles.content, tabIndex: 0, children: [permissionNoticeSnapshot !== undefined && (_jsx("div", { className: styles.notice, role: "status", "data-worktree-permission-notice": true, children: _jsx("p", { className: styles.message, children: formatWorktreePermissionNotice(permissionNoticeSnapshot.result, t) }) })), forkRecoverySnapshot.pending.map((recovery) => {
938
- const recoveryViewError = forkRecoveryError(recovery);
939
- return (_jsxs("div", { className: styles.error, role: "alert", "data-fork-recovery": recovery.key, children: [_jsx("p", { className: styles.message, "data-error": "true", children: formatWorktreeViewError(recoveryViewError, t) }), _jsxs("div", { className: styles.recoveryActions, children: [retryForkSession !== undefined && recoveryViewError.retryable && (_jsx("button", { type: "button", className: styles.actionButton, disabled: forkRetryKey !== undefined, onClick: () => {
940
- void retryForkBinding(recovery.key);
941
- }, children: t('action.retryBinding') })), _jsx("button", { type: "button", className: styles.actionButton, disabled: forkRetryKey !== undefined, onClick: () => {
942
- openSession(recovery.childSessionId);
943
- }, children: t('action.openCreatedSession') })] })] }, recovery.key));
944
- }), actionError !== undefined && (_jsxs("div", { className: styles.error, role: "alert", "data-worktree-error": true, children: [_jsx("p", { className: styles.message, "data-error": "true", children: formatWorktreeViewError(actionError, t) }), pendingSessionBinding !== undefined && (_jsxs("div", { className: styles.recoveryActions, children: [_jsx("button", { type: "button", className: styles.actionButton, disabled: actionPending || pendingSessionArchived, onClick: () => {
945
- void retrySessionBinding();
946
- }, children: t('action.retryBinding') }), !pendingSessionBinding.permissionRequired && (_jsx("button", { type: "button", className: styles.actionButton, disabled: actionPending, onClick: () => {
947
- const sessionId = pendingSessionBinding.sessionId;
948
- setPendingSessionBinding(undefined);
949
- setActionError(undefined);
950
- openSession(sessionId);
951
- }, children: t('action.openCreatedSession') }))] })), actionError.retryable && (_jsx("button", { type: "button", className: styles.retryButton, onClick: () => {
952
- setActionError(undefined);
953
- void refresh();
954
- }, children: t('action.retry') }))] })), readState.status === 'loading' && (_jsx("p", { className: styles.message, children: t('status.loading') })), readState.status === 'error' && readState.error !== undefined ? (_jsxs("div", { className: styles.error, role: "alert", "data-worktree-error": true, children: [_jsx("p", { className: styles.message, "data-error": "true", children: formatWorktreeViewError(readState.error, t) }), _jsx("button", { type: "button", className: styles.retryButton, onClick: () => {
955
- void refresh();
956
- }, children: t('action.retry') })] })) : readState.status === 'ready' ? (_jsx("div", { className: styles.workspaceList, children: visibleWorkspaces.length === 0 ? (_jsx("p", { className: styles.empty, children: t('workspace.noMatches') })) : (visibleWorkspaces.map((workspace) => {
957
- const view = viewByWorkspace.get(workspace.workspaceId);
958
- const currentBranch = view?.branches.find((branch) => branch.isCurrent)?.name;
959
- const mainLabel = currentBranch === undefined
960
- ? t('worktree.main')
961
- : t('worktree.mainWithBranch', { branch: currentBranch });
962
- const expanded = isWorkspaceExpanded(expandSnapshot, workspace.workspaceId) ||
963
- isCurrentSessionReveal('workspace:' + workspace.workspaceId);
964
- const workspaceMatchesQuery = includesText(workspace.title, query);
965
- const allWorkspaceSessionIds = filterArchivedSessionIds(workspaceSessionIds(workspaces, workspace.workspaceId, sessions.ids), archivedSessionIds);
966
- const workspaceActivitySessionIds = filterVisibleSessionIds(allWorkspaceSessionIds, sessions);
967
- const workspaceHasOngoingSession = hasOngoingSession(workspaceActivitySessionIds, sessionPresentations);
968
- const bindings = view?.bindings ?? [];
969
- const boundSessionIds = new Set(bindings.map((binding) => binding.sessionId));
970
- const mainSessionIds = filterVisibleSessionIds(unboundSessionIds(allWorkspaceSessionIds, [...boundSessionIds]), sessions);
971
- const mainGroupKey = `main:${workspace.workspaceId}`;
972
- const orderedMainSessionIds = orderedSessionIdsByAccount.get(mainGroupKey) ?? mainSessionIds;
973
- const visibleMainSessionIds = mainSessionIds.filter((sessionId) => workspaceMatchesQuery || sessionMatchesQuery(sessionId, sessions, query));
974
- const orderedVisibleMainSessionIds = orderedMainSessionIds.filter((sessionId) => workspaceMatchesQuery || sessionMatchesQuery(sessionId, sessions, query));
975
- const mainExpanded = isMainExpanded(expandSnapshot, workspace.workspaceId) ||
976
- isCurrentSessionReveal('main:' + workspace.workspaceId);
977
- const sessionIds = orderedVisibleMainSessionIds.length === visibleMainSessionIds.length
978
- ? orderedVisibleMainSessionIds
979
- : visibleMainSessionIds;
980
- const mainSessionGroupAutoExpanded = isSessionGroupAutoExpanded(sessionIds, currentSessionId, isCurrentSessionReveal('session-group:' + mainGroupKey));
981
- const mainSessionGroupExpanded = expandedSessionGroups[mainGroupKey] === true ||
982
- mainSessionGroupAutoExpanded;
983
- const worktrees = view?.worktrees ?? [];
984
- const workspaceWorktreeNames = [
985
- ...(view?.branches.map((branch) => branch.name) ?? []),
986
- ...(view?.worktrees.map((worktree) => worktree.branch) ?? []),
987
- ];
988
- const sameWorkspaceWorktreeDrag = worktreeDrag?.workspaceId === workspace.workspaceId;
989
- return (_jsxs("section", { className: styles.workspaceGroup, "data-workspace-id": workspace.workspaceId, children: [_jsx(WorktreeWorkspaceRow, { t: t, workspace: workspace, expanded: expanded, hasOngoingSession: workspaceHasOngoingSession, actionPending: actionPending, menuOpen: openWorkspaceMenuId === workspace.workspaceId, drag: {
990
- active: workspaceDrag !== undefined,
991
- marker: workspaceDrag?.over?.workspaceId === workspace.workspaceId
992
- ? workspaceDrag.over.half
993
- : null,
994
- start: () => {
995
- workspaceDropCommitted.current = false;
996
- setWorkspaceDrag({ workspaceId: workspace.workspaceId, over: null });
997
- },
998
- hover: (half) => {
999
- setWorkspaceDrag((current) => current === undefined
1000
- ? current
1001
- : {
1002
- ...current,
1003
- over: { workspaceId: workspace.workspaceId, half },
1004
- });
1005
- },
1006
- drop: (half) => {
1007
- if (workspaceDrag === undefined)
1008
- return;
1009
- commitWorkspaceDrag(workspaceDrag, {
1010
- workspaceId: workspace.workspaceId,
1011
- half,
1012
- });
1013
- },
1014
- end: () => {
1015
- if (workspaceDrag?.over !== null && workspaceDrag?.over !== undefined) {
1016
- commitWorkspaceDrag(workspaceDrag, workspaceDrag.over);
1017
- }
1018
- else {
1019
- setWorkspaceDrag(undefined);
1020
- }
1021
- workspaceDropCommitted.current = false;
1022
- },
1023
- }, onToggle: () => {
1024
- toggleWorkspace(workspace.workspaceId);
1025
- }, onCreateWorktree: () => {
1026
- openWorktreeCreator(workspace);
1027
- }, onRename: () => {
1028
- openWorkspaceRename(workspace);
1029
- }, onDelete: () => {
1030
- openWorkspaceDelete(workspace);
1031
- }, onMenuOpenChange: (open) => {
1032
- setOpenWorkspaceMenuId(open ? workspace.workspaceId : undefined);
1033
- } }), expanded && (_jsxs("div", { className: styles.treeChildren, children: [_jsx(WorktreeGroupRow, { t: t, kind: "main", label: mainLabel, expanded: mainExpanded, hasOngoingSession: hasOngoingSession(mainSessionIds, sessionPresentations), icon: _jsx(IconBranchOutline16, {}), workspaceTitle: workspace.title, onToggle: () => {
1034
- toggleMain(workspace.workspaceId);
1035
- }, menu: {
1036
- open: openMainMenuId === workspace.workspaceId,
1037
- label: mainLabel,
1038
- copyPath: workspace.path,
1039
- showCreate: currentBranch !== undefined,
1040
- showRemove: false,
1041
- disabled: actionPending,
1042
- onOpenChange: (open) => {
1043
- setOpenMainMenuId(open ? workspace.workspaceId : undefined);
1044
- },
1045
- onCreateWorktree: currentBranch === undefined
1046
- ? undefined
1047
- : () => {
1048
- openWorktreeCreator(workspace, {
1049
- baseBranch: currentBranch,
1050
- newBranch: createNumberedWorktreeName(currentBranch, workspaceWorktreeNames),
1051
- });
1052
- },
1053
- }, onCreateSession: createMainSession === undefined
1054
- ? undefined
1055
- : () => {
1056
- createMainSession(workspace.workspaceId);
1057
- } }), mainExpanded && (_jsx(WorktreeSessionGroup, { t: t, groupKey: mainGroupKey, sessionIds: sessionIds, workspaceId: workspace.workspaceId, currentSessionId: currentSessionId, expanded: mainSessionGroupExpanded, actionPending: actionPending, sessions: sessions, sessionPresentations: sessionPresentations, dragState: sessionDrag, onToggleExpanded: () => {
1058
- toggleSessionGroup(mainGroupKey, mainSessionGroupAutoExpanded);
1059
- }, onStartDrag: (groupKey, sessionId) => {
1060
- sessionDropCommitted.current = false;
1061
- setSessionDrag({ groupKey, sessionId, over: null });
1062
- }, onHoverDrag: (sessionId, half) => {
1063
- setSessionDrag((current) => current === undefined
1064
- ? current
1065
- : { ...current, over: { sessionId, half } });
1066
- }, onClearDrag: () => {
1067
- setSessionDrag(undefined);
1068
- }, onFinishDrag: () => {
1069
- sessionDropCommitted.current = false;
1070
- }, onCommitDrag: commitSessionDrag, onOpen: (sessionId) => {
1071
- openWorktreeSession({ open: openSession }, sessionId);
1072
- }, onRename: renameSession === undefined ? undefined : openSessionRename, onFork: forkSession, onArchive: archiveSession === undefined ? undefined : archiveWorktreeSession })), worktrees.length === 0 && (_jsx("p", { className: styles.emptyNested, children: t('worktree.noWorktrees') })), worktrees.map((record) => {
1073
- const worktreeSessionIds = filterVisibleSessionIds(filterArchivedSessionIds(bindingIdsFor(bindings, record.worktreeId).filter((sessionId) => sessions.ids.includes(sessionId)), archivedSessionIds), sessions);
1074
- const worktreeMatchesQuery = workspaceMatchesQuery ||
1075
- includesText(record.branch, query) ||
1076
- includesText(record.absolutePath, query);
1077
- if (query.length > 0 &&
1078
- !worktreeMatchesQuery &&
1079
- !worktreeSessionIds.some((sessionId) => sessionMatchesQuery(sessionId, sessions, query))) {
1080
- return null;
1081
- }
1082
- const visibleWorktreeSessionIds = worktreeSessionIds.filter((sessionId) => worktreeMatchesQuery ||
1083
- sessionMatchesQuery(sessionId, sessions, query));
1084
- const worktreeGroupKey = `worktree:${record.worktreeId}`;
1085
- const orderedWorktreeSessionIds = orderedSessionIdsByAccount.get(worktreeGroupKey) ??
1086
- worktreeSessionIds;
1087
- const orderedVisibleWorktreeSessionIds = orderedWorktreeSessionIds.filter((sessionId) => worktreeMatchesQuery ||
1088
- sessionMatchesQuery(sessionId, sessions, query));
1089
- const sessionIds = orderedVisibleWorktreeSessionIds.length ===
1090
- visibleWorktreeSessionIds.length
1091
- ? orderedVisibleWorktreeSessionIds
1092
- : visibleWorktreeSessionIds;
1093
- const sessionGroupAutoExpanded = isSessionGroupAutoExpanded(sessionIds, currentSessionId, isCurrentSessionReveal('session-group:' + worktreeGroupKey));
1094
- const sessionGroupExpanded = expandedSessionGroups[worktreeGroupKey] === true ||
1095
- sessionGroupAutoExpanded;
1096
- const state = record.status === 'removed'
1097
- ? 'warning'
1098
- : record.health === 'repair' || record.health === 'recovery-needed'
1099
- ? 'error'
1100
- : 'done';
1101
- const stateLabel = record.status === 'removed'
1102
- ? t('worktree.detached')
1103
- : record.health === 'recovery-needed'
1104
- ? t('worktree.recovery')
1105
- : record.health === 'repair'
1106
- ? t('worktree.repair')
1107
- : t('worktree.ready');
1108
- const worktreeExpanded = isWorktreeExpanded(expandSnapshot, record.worktreeId) ||
1109
- isCurrentSessionReveal('worktree:' + record.worktreeId);
1110
- return (_jsxs("div", { className: styles.worktreeGroup, "data-worktree-id": record.worktreeId, children: [_jsx(WorktreeGroupRow, { t: t, kind: "worktree", label: record.branch, worktreeId: record.worktreeId, expanded: worktreeExpanded, hasOngoingSession: hasOngoingSession(worktreeSessionIds, sessionPresentations), icon: _jsx(IconBranchOutline16, {}), workspaceTitle: workspace.title, state: state, stateLabel: stateLabel, onToggle: () => {
1111
- toggleWorktree(record.worktreeId);
1112
- }, onCreateSession: record.status === 'active' && record.health !== 'repair' && record.health !== 'recovery-needed'
1113
- ? () => {
1114
- void createSession({
1115
- workspaceId: record.workspaceId,
1116
- worktreeId: record.worktreeId,
1117
- cwd: record.absolutePath,
1118
- });
1119
- }
1120
- : undefined, menu: {
1121
- open: openWorktreeMenuId === record.worktreeId,
1122
- label: record.branch,
1123
- copyPath: record.absolutePath,
1124
- showCreate: record.status === 'active' && record.health !== 'repair' && record.health !== 'recovery-needed',
1125
- showRemove: record.status === 'active' && record.health !== 'repair' && record.health !== 'recovery-needed',
1126
- disabled: actionPending,
1127
- onOpenChange: (open) => {
1128
- setOpenWorktreeMenuId(open ? record.worktreeId : undefined);
1129
- },
1130
- onCreateWorktree: record.status === 'active' && record.health !== 'repair' && record.health !== 'recovery-needed'
1131
- ? () => {
1132
- openWorktreeCreator(workspace, {
1133
- baseBranch: record.branch,
1134
- newBranch: createNumberedWorktreeName(record.branch, workspaceWorktreeNames),
1135
- });
1136
- }
1137
- : undefined,
1138
- onRemove: record.status === 'active'
1139
- ? () => {
1140
- setWorktreeRemoval(record);
1141
- setActionError(undefined);
1142
- }
1143
- : undefined,
1144
- }, drag: {
1145
- active: sameWorkspaceWorktreeDrag,
1146
- marker: worktreeDrag?.over?.worktreeId === record.worktreeId
1147
- ? worktreeDrag.over.half
1148
- : null,
1149
- start: () => {
1150
- worktreeDropCommitted.current = false;
1151
- setWorktreeDrag({
1152
- workspaceId: workspace.workspaceId,
1153
- worktreeId: record.worktreeId,
1154
- over: null,
1155
- });
1156
- },
1157
- hover: (half) => {
1158
- setWorktreeDrag((current) => current === undefined ||
1159
- current.workspaceId !== workspace.workspaceId
1160
- ? current
1161
- : {
1162
- ...current,
1163
- over: { worktreeId: record.worktreeId, half },
1164
- });
1165
- },
1166
- drop: (half) => {
1167
- if (worktreeDrag === undefined)
1168
- return;
1169
- commitWorktreeDrag(worktreeDrag, { worktreeId: record.worktreeId, half }, worktrees.map((candidate) => candidate.worktreeId), workspace.workspaceId);
1170
- },
1171
- end: () => {
1172
- setWorktreeDrag(undefined);
1173
- worktreeDropCommitted.current = false;
1174
- },
1175
- } }), worktreeExpanded && (_jsx(WorktreeSessionGroup, { t: t, groupKey: worktreeGroupKey, sessionIds: sessionIds, workspaceId: workspace.workspaceId, currentSessionId: currentSessionId, expanded: sessionGroupExpanded, actionPending: actionPending, sessions: sessions, sessionPresentations: sessionPresentations, dragState: sessionDrag, onToggleExpanded: () => {
1176
- toggleSessionGroup(worktreeGroupKey, sessionGroupAutoExpanded);
1177
- }, onStartDrag: (groupKey, sessionId) => {
1178
- sessionDropCommitted.current = false;
1179
- setSessionDrag({ groupKey, sessionId, over: null });
1180
- }, onHoverDrag: (sessionId, half) => {
1181
- setSessionDrag((current) => current === undefined
1182
- ? current
1183
- : { ...current, over: { sessionId, half } });
1184
- }, onClearDrag: () => {
1185
- setSessionDrag(undefined);
1186
- }, onFinishDrag: () => {
1187
- sessionDropCommitted.current = false;
1188
- }, onCommitDrag: commitSessionDrag, onOpen: (sessionId) => {
1189
- openWorkspaceSession(workspace.workspaceId, sessionId);
1190
- }, onRename: renameSession === undefined ? undefined : openSessionRename, onFork: forkSession, onArchive: archiveSession === undefined
1191
- ? undefined
1192
- : archiveWorktreeSession }))] }, record.worktreeId));
1193
- })] }))] }, workspace.workspaceId));
1194
- })) })) : null] })] }), _jsx(WorktreeSessionRenameDialog, { t: t, target: sessionRenameTarget, draft: sessionRenameDraft, pending: sessionRenamePending, error: sessionRenameError, onClose: closeSessionRename, onDraftChange: (draft) => {
1195
- setSessionRenameDraft(draft);
1196
- setSessionRenameError(undefined);
1197
- }, onSubmit: confirmSessionRename }), _jsx(WorktreeWorkspaceRenameDialog, { t: t, target: workspaceRenameTarget, draft: workspaceRenameDraft, pending: workspaceRenamePending, duplicate: workspaceRenameDuplicate, error: workspaceRenameError, onClose: closeWorkspaceRename, onDraftChange: (draft) => {
1198
- setWorkspaceRenameDraft(draft);
1199
- setWorkspaceRenameError(undefined);
1200
- }, onSubmit: confirmWorkspaceRename }), _jsx(WorktreeWorkspaceDeleteDialog, { t: t, target: workspaceDeleteTarget, pending: workspaceDeletePending, error: workspaceDeleteError, onClose: closeWorkspaceDelete, onSubmit: confirmWorkspaceDelete }), _jsx(WorktreeCreateDialog, { t: t, workspace: modalWorkspace, view: modalView, readError: modalReadError, setupStatus: modalSetupStatus, canCreate: modalCanCreate, mode: worktreeModalMode, importCandidates: importCandidates, selectedImportPath: selectedImportPath, selectedBranch: selectedBranch, newBranch: newBranch, actionPending: actionPending, onClose: closeWorktreeCreator, onRetry: () => {
1201
- if (worktreeModalWorkspaceId === undefined)
1202
- return;
1203
- modalReadViewRef.current = undefined;
1204
- setSelectedBranch('');
1205
- setNewBranch('');
1206
- loadModalWorktreeView(worktreeModalWorkspaceId);
1207
- }, onModeChange: changeWorktreeModalMode, onRetryImportCandidates: () => {
1208
- if (worktreeModalWorkspaceId !== undefined) {
1209
- void loadImportCandidates(worktreeModalWorkspaceId);
1210
- }
1211
- }, onSelectedImportPathChange: setSelectedImportPath, onSelectedBranchChange: setSelectedBranch, onNewBranchChange: setNewBranch, onSubmit: submitWorktree }), _jsx(WorktreeRemovalDialog, { t: t, worktree: worktreeRemoval, actionPending: actionPending, onClose: () => {
1212
- setWorktreeRemoval(undefined);
1213
- }, onSubmit: () => {
1214
- if (manager === undefined || worktreeRemoval === undefined)
1215
- return;
1216
- const target = worktreeRemoval;
1217
- const mutationToken = target.mutationToken;
1218
- if (mutationToken === undefined) {
1219
- setActionError({
1220
- code: 'WORKTREE_STATE_CONFLICT',
1221
- message: '',
1222
- retryable: true,
1223
- details: {
1224
- workspaceId: target.workspaceId,
1225
- worktreeId: target.worktreeId,
1226
- },
1227
- });
1228
- return;
1229
- }
1230
- void runMutation(async () => {
1231
- await executeWorktreeAction(manager, {
1232
- type: 'removeWorktree',
1233
- input: {
1234
- workspaceId: target.workspaceId,
1235
- worktreeId: target.worktreeId,
1236
- mutationToken,
1237
- },
1238
- }, permission, onPermissionNotice);
1239
- await invalidateWorktreeContext?.(target.workspaceId);
1240
- setWorktreeRemoval(undefined);
1241
- });
1242
- } }), _jsx(RiskConfirmation, { open: fullAccessConfirmationSnapshot !== undefined, title: t('permission.fullAccessTitle'), description: fullAccessConfirmationSnapshot === undefined
1243
- ? ''
1244
- : t('permission.fullAccessDescription', {
1245
- cwd: fullAccessConfirmationSnapshot.cwd,
1246
- }), acknowledgeLabel: t('permission.fullAccessAcknowledge'), cancelLabel: t('dialog.cancel'), confirmLabel: t('permission.fullAccessEnable'), acknowledged: fullAccessAcknowledged, onAcknowledgedChange: setFullAccessAcknowledged, onCancel: () => {
1247
- setFullAccessAcknowledged(false);
1248
- fullAccessConfirmation?.resolve(false);
1249
- }, onConfirm: () => {
1250
- setFullAccessAcknowledged(false);
1251
- fullAccessConfirmation?.resolve(true);
1252
- } })] }));
53
+ }, children: [_jsxs("div", { className: styles.wideContent, children: [_jsx(SurfaceHeader, { expansion: expansion, props: props, source: source, read: read, mutation: mutation }), _jsx(SurfaceContent, { source: source, props: props, lifecycle: lifecycle, mutation: mutation, session: session, read: read, expansion: expansion, ordering: ordering, drag: drag, menus: menus, registration: registration, native: native, lifecycleState: lifecycleState })] }), _jsx(NativeDialogs, { props: props, native: native }), _jsx(RegistrationDialog, { props: props, registration: registration, registrationState: registrationState, mutation: mutation, read: read }), _jsx(LifecycleDialogs, { props: props, lifecycleState: lifecycleState, mutation: mutation, lifecycle: lifecycle, expansion: expansion, read: read, session: session }), _jsx(AccessConfirmation, { source: source, props: props })] }));
1253
54
  }
1254
55
  //# sourceMappingURL=WorktreeSurface.js.map