@cerbur/clutch-dsh-worktree 0.1.16 → 0.1.17

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 (358) hide show
  1. package/README.md +214 -15
  2. package/README.zh.md +175 -12
  3. package/assets/screenshots/screenshots-dashboard.png +0 -0
  4. package/assets/screenshots/screenshots-en.png +0 -0
  5. package/assets/screenshots/screenshots-git-reviewer.png +0 -0
  6. package/assets/screenshots/screenshots-import.png +0 -0
  7. package/assets/screenshots/screenshots-worktree-tool.png +0 -0
  8. package/assets/screenshots/screenshots-zh.png +0 -0
  9. package/cordis.patch.yml +6 -19
  10. package/lib/client/WorktreeSurface.d.ts.map +1 -1
  11. package/lib/client/WorktreeSurface.js +5 -4
  12. package/lib/client/WorktreeSurface.js.map +1 -1
  13. package/lib/client/command-activity.d.ts +11 -0
  14. package/lib/client/command-activity.d.ts.map +1 -0
  15. package/lib/client/command-activity.js +71 -0
  16. package/lib/client/command-activity.js.map +1 -0
  17. package/lib/client/dashboard/DashboardRequest.d.ts +2 -1
  18. package/lib/client/dashboard/DashboardRequest.d.ts.map +1 -1
  19. package/lib/client/dashboard/DashboardRequest.js +3 -3
  20. package/lib/client/dashboard/DashboardRequest.js.map +1 -1
  21. package/lib/client/dashboard/WorktreeDashboard.d.ts +2 -1
  22. package/lib/client/dashboard/WorktreeDashboard.d.ts.map +1 -1
  23. package/lib/client/dashboard/WorktreeDashboard.js +48 -24
  24. package/lib/client/dashboard/WorktreeDashboard.js.map +1 -1
  25. package/lib/client/dashboard/WorktreeInstructions.d.ts +2 -1
  26. package/lib/client/dashboard/WorktreeInstructions.d.ts.map +1 -1
  27. package/lib/client/dashboard/WorktreeInstructions.js +27 -8
  28. package/lib/client/dashboard/WorktreeInstructions.js.map +1 -1
  29. package/lib/client/dashboard/dashboard-overlay.d.ts.map +1 -1
  30. package/lib/client/dashboard/dashboard-overlay.js +38 -52
  31. package/lib/client/dashboard/dashboard-overlay.js.map +1 -1
  32. package/lib/client/dashboard/dashboard-selection.d.ts +1 -0
  33. package/lib/client/dashboard/dashboard-selection.d.ts.map +1 -1
  34. package/lib/client/dashboard/dashboard-selection.js.map +1 -1
  35. package/lib/client/dashboard/git/WorktreeGitPanel.d.ts +2 -1
  36. package/lib/client/dashboard/git/WorktreeGitPanel.d.ts.map +1 -1
  37. package/lib/client/dashboard/git/WorktreeGitPanel.js +54 -8
  38. package/lib/client/dashboard/git/WorktreeGitPanel.js.map +1 -1
  39. package/lib/client/dashboard/git/file-address.d.ts +2 -1
  40. package/lib/client/dashboard/git/file-address.d.ts.map +1 -1
  41. package/lib/client/dashboard/git/file-address.js +8 -13
  42. package/lib/client/dashboard/git/file-address.js.map +1 -1
  43. package/lib/client/dashboard/git/useWorktreeGitState.d.ts.map +1 -1
  44. package/lib/client/dashboard/git/useWorktreeGitState.js +4 -1
  45. package/lib/client/dashboard/git/useWorktreeGitState.js.map +1 -1
  46. package/lib/client/dsh-icons.d.ts +2 -0
  47. package/lib/client/dsh-icons.d.ts.map +1 -1
  48. package/lib/client/dsh-icons.js +3 -1
  49. package/lib/client/dsh-icons.js.map +1 -1
  50. package/lib/client/dsh-slot-contract.d.ts +9 -1
  51. package/lib/client/dsh-slot-contract.d.ts.map +1 -1
  52. package/lib/client/entry.d.ts.map +1 -1
  53. package/lib/client/entry.js +39 -2
  54. package/lib/client/entry.js.map +1 -1
  55. package/lib/client/layout/app-frame.d.ts +12 -0
  56. package/lib/client/layout/app-frame.d.ts.map +1 -0
  57. package/lib/client/layout/app-frame.js +82 -0
  58. package/lib/client/layout/app-frame.js.map +1 -0
  59. package/lib/client/locales.d.ts +144 -0
  60. package/lib/client/locales.d.ts.map +1 -1
  61. package/lib/client/locales.js +204 -60
  62. package/lib/client/locales.js.map +1 -1
  63. package/lib/client/overlay/overlay-bounds.d.ts.map +1 -1
  64. package/lib/client/overlay/overlay-bounds.js +8 -3
  65. package/lib/client/overlay/overlay-bounds.js.map +1 -1
  66. package/lib/client/overlay/sidebar-overlay-geometry.d.ts +3 -1
  67. package/lib/client/overlay/sidebar-overlay-geometry.d.ts.map +1 -1
  68. package/lib/client/overlay/sidebar-overlay-geometry.js +94 -34
  69. package/lib/client/overlay/sidebar-overlay-geometry.js.map +1 -1
  70. package/lib/client/restart-notice.d.ts +10 -3
  71. package/lib/client/restart-notice.d.ts.map +1 -1
  72. package/lib/client/restart-notice.js +44 -11
  73. package/lib/client/restart-notice.js.map +1 -1
  74. package/lib/client/session/session-view.d.ts +16 -2
  75. package/lib/client/session/session-view.d.ts.map +1 -1
  76. package/lib/client/session/session-view.js +24 -10
  77. package/lib/client/session/session-view.js.map +1 -1
  78. package/lib/client/session/worktree-session.d.ts +1 -0
  79. package/lib/client/session/worktree-session.d.ts.map +1 -1
  80. package/lib/client/session/worktree-session.js +3 -1
  81. package/lib/client/session/worktree-session.js.map +1 -1
  82. package/lib/client/settings/ToolSettings.d.ts +9 -0
  83. package/lib/client/settings/ToolSettings.d.ts.map +1 -0
  84. package/lib/client/settings/ToolSettings.js +77 -0
  85. package/lib/client/settings/ToolSettings.js.map +1 -0
  86. package/lib/client/settings/WorktreeSettings.d.ts +8 -0
  87. package/lib/client/settings/WorktreeSettings.d.ts.map +1 -0
  88. package/lib/client/settings/WorktreeSettings.js +46 -0
  89. package/lib/client/settings/WorktreeSettings.js.map +1 -0
  90. package/lib/client/settings/WorktreeSettingsNavIcon.d.ts +6 -0
  91. package/lib/client/settings/WorktreeSettingsNavIcon.d.ts.map +1 -0
  92. package/lib/client/settings/WorktreeSettingsNavIcon.js +51 -0
  93. package/lib/client/settings/WorktreeSettingsNavIcon.js.map +1 -0
  94. package/lib/client/settings/diagnostics.d.ts +24 -0
  95. package/lib/client/settings/diagnostics.d.ts.map +1 -0
  96. package/lib/client/settings/diagnostics.js +63 -0
  97. package/lib/client/settings/diagnostics.js.map +1 -0
  98. package/lib/client/settings/settings-navigation.d.ts +7 -0
  99. package/lib/client/settings/settings-navigation.d.ts.map +1 -0
  100. package/lib/client/settings/settings-navigation.js +12 -0
  101. package/lib/client/settings/settings-navigation.js.map +1 -0
  102. package/lib/client/surface/actions/useLifecycleActions.d.ts +2 -1
  103. package/lib/client/surface/actions/useLifecycleActions.d.ts.map +1 -1
  104. package/lib/client/surface/actions/useLifecycleActions.js +14 -5
  105. package/lib/client/surface/actions/useLifecycleActions.js.map +1 -1
  106. package/lib/client/surface/actions/useSessionActions.d.ts.map +1 -1
  107. package/lib/client/surface/actions/useSessionActions.js +6 -6
  108. package/lib/client/surface/actions/useSessionActions.js.map +1 -1
  109. package/lib/client/surface/actions/useWorktreeRegistration.d.ts.map +1 -1
  110. package/lib/client/surface/actions/useWorktreeRegistration.js +4 -2
  111. package/lib/client/surface/actions/useWorktreeRegistration.js.map +1 -1
  112. package/lib/client/surface/components/NotificationToasts.d.ts +19 -3
  113. package/lib/client/surface/components/NotificationToasts.d.ts.map +1 -1
  114. package/lib/client/surface/components/NotificationToasts.js +73 -7
  115. package/lib/client/surface/components/NotificationToasts.js.map +1 -1
  116. package/lib/client/surface/components/OverlayScrollbar.d.ts +6 -0
  117. package/lib/client/surface/components/OverlayScrollbar.d.ts.map +1 -0
  118. package/lib/client/surface/components/OverlayScrollbar.js +84 -0
  119. package/lib/client/surface/components/OverlayScrollbar.js.map +1 -0
  120. package/lib/client/surface/components/RestartToast.d.ts.map +1 -1
  121. package/lib/client/surface/components/RestartToast.js +4 -3
  122. package/lib/client/surface/components/RestartToast.js.map +1 -1
  123. package/lib/client/surface/components/SurfaceContent.d.ts.map +1 -1
  124. package/lib/client/surface/components/SurfaceContent.js +110 -39
  125. package/lib/client/surface/components/SurfaceContent.js.map +1 -1
  126. package/lib/client/surface/components/WorkspaceTree.d.ts.map +1 -1
  127. package/lib/client/surface/components/WorkspaceTree.js +2 -1
  128. package/lib/client/surface/components/WorkspaceTree.js.map +1 -1
  129. package/lib/client/surface/components/dialogs.d.ts.map +1 -1
  130. package/lib/client/surface/components/dialogs.js +14 -10
  131. package/lib/client/surface/components/dialogs.js.map +1 -1
  132. package/lib/client/surface/components/rows.d.ts +1 -1
  133. package/lib/client/surface/components/rows.d.ts.map +1 -1
  134. package/lib/client/surface/components/rows.js +15 -97
  135. package/lib/client/surface/components/rows.js.map +1 -1
  136. package/lib/client/surface/notification-queue.d.ts +15 -0
  137. package/lib/client/surface/notification-queue.d.ts.map +1 -1
  138. package/lib/client/surface/notification-queue.js +13 -2
  139. package/lib/client/surface/notification-queue.js.map +1 -1
  140. package/lib/client/surface/state/useSurfaceRefresh.d.ts +1 -1
  141. package/lib/client/surface/state/useSurfaceRefresh.d.ts.map +1 -1
  142. package/lib/client/surface/state/useSurfaceRefresh.js +13 -1
  143. package/lib/client/surface/state/useSurfaceRefresh.js.map +1 -1
  144. package/lib/client/surface/state/useSurfaceSources.d.ts +1 -1
  145. package/lib/client/surface/state/useSurfaceSources.d.ts.map +1 -1
  146. package/lib/client/surface/state/useSurfaceSources.js +4 -2
  147. package/lib/client/surface/state/useSurfaceSources.js.map +1 -1
  148. package/lib/client/surface/state/useTitleMarquee.d.ts +7 -0
  149. package/lib/client/surface/state/useTitleMarquee.d.ts.map +1 -0
  150. package/lib/client/surface/state/useTitleMarquee.js +60 -0
  151. package/lib/client/surface/state/useTitleMarquee.js.map +1 -0
  152. package/lib/client/surface/types.d.ts +8 -1
  153. package/lib/client/surface/types.d.ts.map +1 -1
  154. package/lib/client/view/worktree-error-copy.d.ts.map +1 -1
  155. package/lib/client/view/worktree-error-copy.js +69 -14
  156. package/lib/client/view/worktree-error-copy.js.map +1 -1
  157. package/lib/client/view/worktree-view-errors.d.ts.map +1 -1
  158. package/lib/client/view/worktree-view-errors.js +13 -5
  159. package/lib/client/view/worktree-view-errors.js.map +1 -1
  160. package/lib/client/worktree-connection.d.ts +6 -2
  161. package/lib/client/worktree-connection.d.ts.map +1 -1
  162. package/lib/client/worktree-connection.js +6 -0
  163. package/lib/client/worktree-connection.js.map +1 -1
  164. package/lib/client/worktree-tool-changes.d.ts +13 -0
  165. package/lib/client/worktree-tool-changes.d.ts.map +1 -0
  166. package/lib/client/worktree-tool-changes.js +64 -0
  167. package/lib/client/worktree-tool-changes.js.map +1 -0
  168. package/lib/client.js +2188 -947
  169. package/lib/client.js.map +1 -1
  170. package/lib/contract/index.d.ts +11 -1
  171. package/lib/contract/index.d.ts.map +1 -1
  172. package/lib/contract/index.js +9 -0
  173. package/lib/contract/index.js.map +1 -1
  174. package/lib/contract/tool-settings.d.ts +28 -0
  175. package/lib/contract/tool-settings.d.ts.map +1 -0
  176. package/lib/contract/tool-settings.js +10 -0
  177. package/lib/contract/tool-settings.js.map +1 -0
  178. package/lib/contract/worktree-tool-changes.d.ts +10 -0
  179. package/lib/contract/worktree-tool-changes.d.ts.map +1 -0
  180. package/lib/contract/worktree-tool-changes.js +2 -0
  181. package/lib/contract/worktree-tool-changes.js.map +1 -0
  182. package/lib/host/permission-preset-append.d.ts +15 -0
  183. package/lib/host/permission-preset-append.d.ts.map +1 -0
  184. package/lib/host/permission-preset-append.js +63 -0
  185. package/lib/host/permission-preset-append.js.map +1 -0
  186. package/lib/host/service.d.ts +17 -0
  187. package/lib/host/service.d.ts.map +1 -1
  188. package/lib/host/service.js +67 -11
  189. package/lib/host/service.js.map +1 -1
  190. package/lib/host/tool-settings.d.ts +14 -0
  191. package/lib/host/tool-settings.d.ts.map +1 -0
  192. package/lib/host/tool-settings.js +98 -0
  193. package/lib/host/tool-settings.js.map +1 -0
  194. package/lib/host/worktree-permission-manager.d.ts.map +1 -1
  195. package/lib/host/worktree-permission-manager.js +2 -4
  196. package/lib/host/worktree-permission-manager.js.map +1 -1
  197. package/lib/host/worktree-tool-changes.d.ts +12 -0
  198. package/lib/host/worktree-tool-changes.d.ts.map +1 -0
  199. package/lib/host/worktree-tool-changes.js +60 -0
  200. package/lib/host/worktree-tool-changes.js.map +1 -0
  201. package/lib/manage/manager-git-history.d.ts.map +1 -1
  202. package/lib/manage/manager-git-history.js +29 -28
  203. package/lib/manage/manager-git-history.js.map +1 -1
  204. package/lib/manage/manager-sessions.d.ts +5 -0
  205. package/lib/manage/manager-sessions.d.ts.map +1 -1
  206. package/lib/manage/manager-sessions.js +34 -11
  207. package/lib/manage/manager-sessions.js.map +1 -1
  208. package/lib/manage/manager-support.d.ts +3 -1
  209. package/lib/manage/manager-support.d.ts.map +1 -1
  210. package/lib/manage/manager-support.js +17 -0
  211. package/lib/manage/manager-support.js.map +1 -1
  212. package/lib/manage/manager-worktree-lifecycle.d.ts.map +1 -1
  213. package/lib/manage/manager-worktree-lifecycle.js +5 -4
  214. package/lib/manage/manager-worktree-lifecycle.js.map +1 -1
  215. package/lib/manage/manager-worktrees.d.ts +1 -0
  216. package/lib/manage/manager-worktrees.d.ts.map +1 -1
  217. package/lib/manage/manager-worktrees.js +74 -22
  218. package/lib/manage/manager-worktrees.js.map +1 -1
  219. package/lib/manage/manager.d.ts +10 -0
  220. package/lib/manage/manager.d.ts.map +1 -1
  221. package/lib/manage/manager.js +12 -1
  222. package/lib/manage/manager.js.map +1 -1
  223. package/lib/manage/types.d.ts +10 -1
  224. package/lib/manage/types.d.ts.map +1 -1
  225. package/lib/provider/generated-name.d.ts.map +1 -1
  226. package/lib/provider/generated-name.js +5 -4
  227. package/lib/provider/generated-name.js.map +1 -1
  228. package/lib/provider/git/adapter.d.ts.map +1 -1
  229. package/lib/provider/git/adapter.js +5 -2
  230. package/lib/provider/git/adapter.js.map +1 -1
  231. package/lib/provider/mutation-token.d.ts +1 -1
  232. package/lib/provider/mutation-token.d.ts.map +1 -1
  233. package/lib/provider/mutation-token.js +1 -0
  234. package/lib/provider/mutation-token.js.map +1 -1
  235. package/lib/provider/sidecar/repository.d.ts.map +1 -1
  236. package/lib/provider/sidecar/repository.js +1 -0
  237. package/lib/provider/sidecar/repository.js.map +1 -1
  238. package/lib/provider/sidecar/sidecar-schema.d.ts.map +1 -1
  239. package/lib/provider/sidecar/sidecar-schema.js +24 -4
  240. package/lib/provider/sidecar/sidecar-schema.js.map +1 -1
  241. package/lib/provider/transaction/operations/adopt-branch.d.ts.map +1 -1
  242. package/lib/provider/transaction/operations/adopt-branch.js +6 -5
  243. package/lib/provider/transaction/operations/adopt-branch.js.map +1 -1
  244. package/lib/provider/transaction/operations/clean.d.ts.map +1 -1
  245. package/lib/provider/transaction/operations/clean.js +20 -19
  246. package/lib/provider/transaction/operations/clean.js.map +1 -1
  247. package/lib/provider/transaction/operations/create.d.ts +1 -1
  248. package/lib/provider/transaction/operations/create.d.ts.map +1 -1
  249. package/lib/provider/transaction/operations/create.js +23 -13
  250. package/lib/provider/transaction/operations/create.js.map +1 -1
  251. package/lib/provider/transaction/operations/import.d.ts.map +1 -1
  252. package/lib/provider/transaction/operations/import.js +7 -1
  253. package/lib/provider/transaction/operations/import.js.map +1 -1
  254. package/lib/provider/transaction/operations/remove.d.ts.map +1 -1
  255. package/lib/provider/transaction/operations/remove.js +20 -19
  256. package/lib/provider/transaction/operations/remove.js.map +1 -1
  257. package/lib/provider/transaction/recovery/failure-recovery.d.ts.map +1 -1
  258. package/lib/provider/transaction/recovery/failure-recovery.js +19 -18
  259. package/lib/provider/transaction/recovery/failure-recovery.js.map +1 -1
  260. package/lib/provider/transaction/recovery/recover.d.ts.map +1 -1
  261. package/lib/provider/transaction/recovery/recover.js +6 -2
  262. package/lib/provider/transaction/recovery/recover.js.map +1 -1
  263. package/lib/provider/transaction/support/inspection.d.ts.map +1 -1
  264. package/lib/provider/transaction/support/inspection.js +3 -2
  265. package/lib/provider/transaction/support/inspection.js.map +1 -1
  266. package/lib/provider/transaction/support/journal.d.ts.map +1 -1
  267. package/lib/provider/transaction/support/journal.js +8 -5
  268. package/lib/provider/transaction/support/journal.js.map +1 -1
  269. package/lib/provider/transaction/support/path-safety.d.ts.map +1 -1
  270. package/lib/provider/transaction/support/path-safety.js +4 -3
  271. package/lib/provider/transaction/support/path-safety.js.map +1 -1
  272. package/lib/provider/transaction/types.d.ts +2 -1
  273. package/lib/provider/transaction/types.d.ts.map +1 -1
  274. package/lib/provider/types.d.ts +3 -1
  275. package/lib/provider/types.d.ts.map +1 -1
  276. package/lib/provider/types.js +1 -1
  277. package/lib/provider/types.js.map +1 -1
  278. package/lib/provider/worktree-path.d.ts +10 -0
  279. package/lib/provider/worktree-path.d.ts.map +1 -0
  280. package/lib/provider/worktree-path.js +47 -0
  281. package/lib/provider/worktree-path.js.map +1 -0
  282. package/lib/tool/context.d.ts +14 -0
  283. package/lib/tool/context.d.ts.map +1 -0
  284. package/lib/tool/context.js +95 -0
  285. package/lib/tool/context.js.map +1 -0
  286. package/lib/tool/delegation.d.ts +41 -0
  287. package/lib/tool/delegation.d.ts.map +1 -0
  288. package/lib/tool/delegation.js +196 -0
  289. package/lib/tool/delegation.js.map +1 -0
  290. package/lib/tool/errors.d.ts +3 -0
  291. package/lib/tool/errors.d.ts.map +1 -0
  292. package/lib/tool/errors.js +63 -0
  293. package/lib/tool/errors.js.map +1 -0
  294. package/lib/tool/guidance.d.ts +5 -0
  295. package/lib/tool/guidance.d.ts.map +1 -0
  296. package/lib/tool/guidance.js +48 -0
  297. package/lib/tool/guidance.js.map +1 -0
  298. package/lib/tool/history.d.ts +27 -0
  299. package/lib/tool/history.d.ts.map +1 -0
  300. package/lib/tool/history.js +157 -0
  301. package/lib/tool/history.js.map +1 -0
  302. package/lib/tool/index.d.ts +8 -0
  303. package/lib/tool/index.d.ts.map +1 -0
  304. package/lib/tool/index.js +296 -0
  305. package/lib/tool/index.js.map +1 -0
  306. package/lib/tool/inputs.d.ts +12 -0
  307. package/lib/tool/inputs.d.ts.map +1 -0
  308. package/lib/tool/inputs.js +24 -0
  309. package/lib/tool/inputs.js.map +1 -0
  310. package/lib/tool/list-models.d.ts +3 -0
  311. package/lib/tool/list-models.d.ts.map +1 -0
  312. package/lib/tool/list-models.js +38 -0
  313. package/lib/tool/list-models.js.map +1 -0
  314. package/lib/tool/list-sessions.d.ts +3 -0
  315. package/lib/tool/list-sessions.d.ts.map +1 -0
  316. package/lib/tool/list-sessions.js +70 -0
  317. package/lib/tool/list-sessions.js.map +1 -0
  318. package/lib/tool/list-worktrees.d.ts +3 -0
  319. package/lib/tool/list-worktrees.d.ts.map +1 -0
  320. package/lib/tool/list-worktrees.js +39 -0
  321. package/lib/tool/list-worktrees.js.map +1 -0
  322. package/lib/tool/native-session.d.ts +74 -0
  323. package/lib/tool/native-session.d.ts.map +1 -0
  324. package/lib/tool/native-session.js +248 -0
  325. package/lib/tool/native-session.js.map +1 -0
  326. package/lib/tool/new-worktree.d.ts +3 -0
  327. package/lib/tool/new-worktree.d.ts.map +1 -0
  328. package/lib/tool/new-worktree.js +81 -0
  329. package/lib/tool/new-worktree.js.map +1 -0
  330. package/lib/tool/outputs.d.ts +50 -0
  331. package/lib/tool/outputs.d.ts.map +1 -0
  332. package/lib/tool/outputs.js +65 -0
  333. package/lib/tool/outputs.js.map +1 -0
  334. package/lib/tool/report-result.d.ts +3 -0
  335. package/lib/tool/report-result.d.ts.map +1 -0
  336. package/lib/tool/report-result.js +83 -0
  337. package/lib/tool/report-result.js.map +1 -0
  338. package/lib/tool/schema.d.ts +7 -0
  339. package/lib/tool/schema.d.ts.map +1 -0
  340. package/lib/tool/schema.js +92 -0
  341. package/lib/tool/schema.js.map +1 -0
  342. package/lib/tool/send-message.d.ts +3 -0
  343. package/lib/tool/send-message.d.ts.map +1 -0
  344. package/lib/tool/send-message.js +64 -0
  345. package/lib/tool/send-message.js.map +1 -0
  346. package/lib/tool/span-worktree.d.ts +3 -0
  347. package/lib/tool/span-worktree.d.ts.map +1 -0
  348. package/lib/tool/span-worktree.js +114 -0
  349. package/lib/tool/span-worktree.js.map +1 -0
  350. package/lib/tool/types.d.ts +54 -0
  351. package/lib/tool/types.d.ts.map +1 -0
  352. package/lib/tool/types.js +2 -0
  353. package/lib/tool/types.js.map +1 -0
  354. package/lib/typert.host.js +215 -44
  355. package/lib/typert.remote-client.d.ts +7 -1
  356. package/lib/typert.remote-client.d.ts.map +1 -1
  357. package/lib/typert.remote-client.js +215 -44
  358. package/package.json +14 -2
package/lib/client.js CHANGED
@@ -780,13 +780,66 @@ window.__ModuleLoader__.load({
780
780
  //#region lib/client/locales.js
781
781
  const WORKTREE_NS = "worktree";
782
782
  const zh = {
783
+ "tools.experimental": "实验性",
784
+ "tools.loading": "正在加载工具设置…",
785
+ "settings.general": "通用",
786
+ "tools.command": "Worktree 工具",
787
+ "tools.commandHint": "开启后可输入 /cluworktree,为当前会话启用下方选中的能力。关闭后不提供该指令。",
788
+ "tools.auto": "自动注入 Worktree 工具",
789
+ "tools.autoHint": "此 Worktree 的会话执行前自动注入所选工具,与通用设置独立。",
790
+ "tools.localAutoHint": "此 Workspace 的 Local/Main 会话执行前自动注入所选工具,与通用设置独立。",
791
+ "tools.selection": "工具选择",
792
+ "tools.commandSelectionHint": "/cluworktree 仅补齐未启用项。",
793
+ "tools.autoSelectionHint": "按需选择此 Worktree 自动注入的能力。",
794
+ "tools.localAutoSelectionHint": "仅自动注入此 Workspace 的 Local/Main 会话。",
795
+ "tools.runtimeHint": "取消全部会关闭总开关。更改影响后续注入,已启用工具保留至 Agent 结束。",
796
+ "tools.reportHint": "委派会话默认仅启用结果回报。",
797
+ "tools.failed": "无法读取或保存工具设置。请重试以加载最新配置。",
798
+ "tools.create.title": "创建 Worktree",
799
+ "tools.create.hint": "从当前已提交状态创建独立分支与工作目录,可附带共享指令。",
800
+ "tools.worktrees.title": "查找 Worktree",
801
+ "tools.worktrees.hint": "查看当前 Workspace 中的 Worktree、分支、路径与可用状态。",
802
+ "tools.delegate.title": "委派任务",
803
+ "tools.delegate.hint": "在指定 Worktree 中创建并绑定会话、选择模型并投递任务,执行方可主动回报结果。",
804
+ "tools.models.title": "选择模型",
805
+ "tools.models.hint": "查询可用模型与推理选项,为委派任务选择合适的模型。",
806
+ "tools.sessions.title": "查找会话",
807
+ "tools.sessions.hint": "查看当前 Workspace 或指定 Worktree 的会话身份、标题与执行状态。",
808
+ "tools.message.title": "继续会话",
809
+ "tools.message.hint": "向已有会话发送后续任务,或在原生执行边界调整正在进行的任务。",
810
+ "settings.title": "Worktree",
811
+ "settings.overview": "概览",
812
+ "settings.errors": "报错与修复",
813
+ "settings.description": "Worktree 模式按 Git 工作树组织会话。操作失败时通过 toast 提示,错误说明、诊断详情和恢复操作集中在「报错与修复」。",
814
+ "settings.retention": "错误记录保留在当前页面内存中,刷新页面后清空。修复前请先阅读问题说明和解决建议。",
815
+ "settings.clearHistory": "清除历史记录",
816
+ "settings.empty": "暂无错误记录。",
817
+ "settings.operation": "Worktree 操作",
818
+ "settings.active": "待处理",
819
+ "settings.resolved": "历史记录",
820
+ "settings.inactive": "操作视图已关闭",
821
+ "settings.reopen": "请重新打开对应 Workspace、Dashboard 或操作弹窗,以加载当前状态并启用恢复操作。",
822
+ "settings.diagnostics": "原始诊断详情",
823
+ "settings.toastHint": "错误详情和恢复操作:设置 → Worktree → 报错与修复。",
824
+ "settings.read": "读取 Worktree 列表",
825
+ "settings.binding": "绑定 Session",
826
+ "settings.permission": "调整 Worktree 权限",
827
+ "settings.git": "Git:{operation}",
828
+ "settings.adopt": "采用当前分支",
829
+ "settings.import": "读取可导入的 Worktree",
830
+ "settings.create": "准备创建 Worktree",
831
+ "error.gitTimeout": "Git 操作超时。请检查仓库是否可访问,以及是否有其他 Git 操作卡住;处理后再重试。",
832
+ "error.gitLocalChanges": "Git 检测到未提交或未跟踪的文件,已阻止此操作。请先提交或备份需要保留的改动,再检查目录并重试。",
833
+ "error.gitAccessDenied": "Git 无法访问仓库或目录。请检查文件权限、仓库所有权和 DSH 的访问范围,修复后重试。",
834
+ "error.gitLocked": "Git 仓库正被其他操作锁定。请等待其他 Git 操作结束后重试;若锁仍存在,请确认没有 Git 进程运行后在终端检查锁文件。",
835
+ "error.gitInvalidBranch": "分支名称不符合 Git 的命名规则。请改用有效名称,例如 feature/my-task,再重试。",
783
836
  restartRequired: "Worktree 插件已安装。请重启 DSH Desktop,或重启 DSH Web 服务后刷新页面,以启用插件。",
784
837
  "dashboard.title": "Dashboard",
785
838
  "dashboard.preview": "Dashboard 预览",
786
839
  "dashboard.open": "打开 Dashboard",
787
840
  "dashboard.copyBranch": "复制分支名称",
788
841
  "dashboard.branchCopied": "已复制分支名称",
789
- "dashboard.branchCopyFailed": "复制分支名称失败,请重试。",
842
+ "dashboard.branchCopyFailed": "无法复制分支名称。请允许剪贴板访问后重试,或手动复制标题中的分支名称。",
790
843
  "dashboard.tab.overview": "概览",
791
844
  "dashboard.tab.git": "Git 与变更",
792
845
  "dashboard.git.title": "Git 与变更",
@@ -947,7 +1000,7 @@ window.__ModuleLoader__.load({
947
1000
  "workspace.noMatches": "没有匹配的工作区",
948
1001
  "workspace.renameTitle": "重命名工作区",
949
1002
  "workspace.name": "工作区名称",
950
- "workspace.duplicate": "已存在同名工作区。",
1003
+ "workspace.duplicate": "已存在同名 Workspace,请使用不同的名称。",
951
1004
  "workspace.deleteTitle": "删除工作区",
952
1005
  "workspace.deleteDescription": "删除“{name}”?这只会移除 DSH 工作区注册。目录、会话和 Git Worktree 会保留。",
953
1006
  "worktree.title": "Worktree",
@@ -1055,59 +1108,131 @@ window.__ModuleLoader__.load({
1055
1108
  "action.retry": "重试",
1056
1109
  "action.retryBinding": "重试绑定",
1057
1110
  "action.openCreatedSession": "打开已创建的 Session",
1058
- "permission.fallbackWorkspaceWrite": "无法使用 Worktree 完全访问预设,已降级为 workspace-write;保留审批提示。",
1059
- "permission.userRestricted": "已保留你在 DSH 原生权限界面选择的限制,未自动提升此 Worktree Session。",
1060
- "permission.unverified": "无法验证 Worktree Session 的权限服务;Session 已保留,但完全访问未得到确认。",
1061
- "permission.unavailable": "Worktree Session 权限状态暂时不可用,请重试。",
1111
+ "permission.presetRestartRequired": "Worktree Full Access 预设不可用。如果刚安装或更新了 Worktree,请重启 DSH Desktop;使用 DSH Web 时,请重启服务并刷新页面。当前仍使用 workspace-write 降级权限。",
1112
+ "permission.fallbackWorkspaceWrite": "Worktree 完全访问预设不可用,已使用 workspace-write 并保留审批提示。如果刚安装或更新了 Worktree,请重启 DSH Desktop,或重启 DSH Web 服务后刷新页面。若重启后预设仍不可用或 Git 操作遇到访问限制,请检查 DSH 的插件配置与 Session 权限设置。",
1113
+ "permission.userRestricted": "已保留你在 DSH 中选择的权限限制。若任务需要更高权限,请在该 Session 的原生权限设置中调整后重试。",
1114
+ "permission.unverified": "无法确认 Session 权限,会话已保留。请检查 DSH 的权限设置;清理后的权限调整可在设置 → Worktree → 报错与修复中重试。",
1115
+ "permission.unavailable": "暂时无法读取 Worktree Session 权限。请检查 DSH 连接和 Session 权限设置后重试。",
1062
1116
  "permission.fullAccessTitle": "确认启用 Worktree Full access?",
1063
1117
  "permission.fullAccessDescription": "启用 Worktree Full access 后,此 Session 可能访问 Session 目录之外的关联 Git 元数据和 Worktree 文件。完全访问会关闭此 Session 的文件系统沙箱,但会保留审批提示;网络和进程策略不变。目标 Worktree:{cwd}",
1064
1118
  "permission.fullAccessAcknowledge": "我已了解风险,并愿意继续",
1065
1119
  "permission.fullAccessEnable": "启用 Worktree Full access",
1066
1120
  "status.loading": "正在加载工作区…",
1067
- "error.worktreeDataUnavailable": "Worktree 数据不可用,请重试。",
1068
- "error.gitNotInstalled": "Git 未安装或不可用,请安装 Git 后重试。",
1069
- "error.connectionDisposed": "Worktree 连接已释放,请重新加载插件后重试。",
1070
- "error.connectionFailed": "Worktree endpoint {endpoint} 调用失败;连接错误,可重试:{reason}",
1071
- "error.invalidResult": "Worktree endpoint {endpoint} 返回了无效结果,请重试请求。",
1121
+ "error.worktreeDataUnavailable": "暂时无法读取 Worktree 数据。请确认 DSH 服务已连接,再重试;已有列表会保留。",
1122
+ "error.gitNotInstalled": "找不到 Git。请安装 Git 或将其加入 PATH,重启 DSH 后重试。",
1123
+ "error.connectionDisposed": "Worktree 连接已关闭。请刷新页面或重启 DSH 后重试。",
1124
+ "error.connectionFailed": "无法连接 Worktree 服务。请确认 DSH 正在运行且连接正常,再重试;刚安装插件时请先重启 DSH。",
1125
+ "error.invalidResult": "Worktree 服务返回了无法识别的数据。请重启 DSH 并刷新页面;若仍失败,请检查插件与 DSH 的版本兼容性。",
1072
1126
  "error.workspaceOrderingUnavailable": "工作区排序不可用,请重新连接后重试。",
1073
1127
  "error.sessionOrderingUnavailable": "会话排序不可用,请重新连接后重试。",
1074
1128
  "error.worktreeOrderingUnavailable": "Worktree 排序不可用,请重新连接后重试。",
1075
1129
  "error.worktreeCreatedSessionUnavailable": "Worktree 已创建,但 Session 创建不可用,请重新连接后重试。",
1076
1130
  "error.sessionCreationUnavailable": "Session 创建不可用,请重新连接后重试。",
1077
- "error.worktreeRecordMissing": "Worktree 注册未返回 Worktree 记录,请重试请求。",
1078
- "error.worktreeImportInvalid": "这个 Worktree 无法导入,请选择同一 Workspace 中有效的绝对路径。",
1079
- "error.worktreeAlreadyManaged": "这个 Worktree 已由插件管理。",
1080
- "error.worktreeMutationBusy": "另一个 DSH 实例正在修改 Worktree 状态,请稍后重试。",
1081
- "error.worktreeStateConflict": "Worktree 状态已经变化,请刷新后重试。",
1082
- "error.worktreeRecoveryRequired": "Worktree 状态需要恢复;请先完成恢复后再重试破坏性操作。",
1083
- "error.worktreeIdentityChanged": "Worktree 或 repository 身份已经变化,需要恢复后再操作。",
1084
- "error.worktreeSessionBusy": "关联 Session 正在运行,无法执行此操作。",
1085
- "error.worktreeActivityUnavailable": "无法验证关联 Session 运行状态,无法执行此操作。",
1131
+ "error.worktreeRecordMissing": "未能确认 Worktree 登记结果。请先刷新列表检查是否已创建或导入,避免重复操作;若未出现,再重试。",
1132
+ "error.worktreeImportInvalid": "所选目录无法导入。请从导入列表选择同一 Git 仓库中有分支、尚未登记且不是主目录的 Worktree,然后重试。",
1133
+ "error.worktreeAlreadyManaged": "这个 Worktree 已在管理列表中。请刷新列表并打开已有项,无需重复导入。",
1134
+ "error.worktreeMutationBusy": "另一个操作正在修改此 Worktree 的状态。请等待它完成后再重试;若长时间未结束,请检查其他 DSH 实例。",
1135
+ "error.worktreeStateConflict": "Worktree、分支或保存内容已变化。请刷新后重新选择并确认操作;正在编辑时请先复制草稿,再取消并重新打开。",
1136
+ "error.worktreeRecoveryRequired": "上次 Worktree 操作尚未完成恢复,当前操作已阻止。请在设置 → Worktree → 报错与修复中选择重试恢复,完成后再重试。",
1137
+ "error.worktreeIdentityChanged": "Worktree 或 Git 仓库的实际位置与登记信息不一致。请检查目录,移动过的 Worktree 先执行 git worktree repair,再刷新并重试恢复。",
1138
+ "error.worktreeSessionBusy": "关联 Session 或子代理仍在运行。请等待任务结束,或在 DSH 中停止任务后重试。",
1139
+ "error.worktreeActivityUnavailable": "暂时无法确认关联 Session 的运行状态。请确认 DSH 连接正常,刷新 Session 列表后重试。",
1086
1140
  "error.worktreeRegistrationSessionUnavailable": "Worktree 已注册,但 Session 创建不可用,请重新连接后重试。",
1087
1141
  "error.workspaceRenameUnavailable": "工作区重命名不可用,请重新连接后重试。",
1088
1142
  "error.workspaceDeleteUnavailable": "工作区删除不可用,请重新连接后重试。",
1089
- "error.workspaceRootMissing": "Workspace 目录不存在:{rootPath}",
1143
+ "error.workspaceRootMissing": "Workspace 目录不存在:{rootPath}。请恢复目录,或在 DSH 中移除这个 Workspace 并重新添加正确目录,再重试。",
1090
1144
  "error.sessionRenameUnavailable": "会话重命名不可用,请重新连接后重试。",
1091
- "error.sessionBindingFailed": "Session {sessionId} 已创建,但 Worktree 绑定失败:{reason}",
1092
- "error.sessionAlreadyBound": "Session 已绑定到其他 Worktree,未创建新的 Session。",
1093
- "error.worktreePermissionConfirmationRequired": "Session 和绑定已保留;确认完全访问后重试,未打开 Session。",
1094
- "error.worktreePermissionFailed": "Worktree Session 权限设置失败,可重试:{reason}",
1095
- "error.sessionListNotReady": "Session 列表尚未就绪,请重试。",
1096
- "error.sessionFactsIncomplete": "Session 信息尚未完整,请重试。",
1097
- "error.worktreeSessionRepairRequired": "当前 Worktree 的 Session 绑定需要修复,请重试。",
1098
- "error.worktreeSessionUnavailable": "当前 Worktree 不可用,请重试。",
1099
- "error.sessionArchived": "该 Session 已归档,无法重试绑定。",
1145
+ "error.sessionBindingFailed": "Session {sessionId} 已保留,但未能绑定 Worktree。{reason}",
1146
+ "error.sessionAlreadyBound": "这个 Session 已绑定到另一个 Worktree。请打开它原来所属的 Worktree,或在目标 Worktree 中创建新会话。",
1147
+ "error.worktreePermissionConfirmationRequired": "Session 和绑定已保留,尚未确认完全访问权限。请在设置 → Worktree → 报错与修复中重试绑定并完成权限确认;无需新建会话。",
1148
+ "error.worktreePermissionFailed": "Worktree Session 权限设置失败,会话已保留。请检查 DSH 的会话权限设置,并从设置 → Worktree → 报错与修复中重试。",
1149
+ "error.sessionListNotReady": "Session 列表仍在加载。请稍等片刻后重试;若一直未就绪,请重新连接 DSH。",
1150
+ "error.sessionFactsIncomplete": "Session 信息尚未完整加载,无法确认其工作目录。请稍等并刷新列表后重试。",
1151
+ "error.worktreeSessionRepairRequired": "Session 与 Worktree 的绑定需要修复。请在设置 → Worktree → 报错与修复中重试绑定;若目录被移动,请先执行 git worktree repair。",
1152
+ "error.worktreeSessionUnavailable": "这个 Worktree 无法用于打开或创建 Session。请确认目录存在、尚未清理且无需恢复,再刷新列表重试。",
1153
+ "error.sessionArchived": "这个 Session 已归档,无法重新绑定。请先在 DSH 中恢复它,或在目标 Worktree 中创建新会话。",
1100
1154
  "branch.current": "(当前)",
1101
- "branch.checkedOut": "(已检出)"
1155
+ "branch.checkedOut": "(已检出)",
1156
+ "notice.recovery": "恢复操作",
1157
+ "notice.sessionRecovery": "Session:{sessionId}",
1158
+ "notice.workspaceRecovery": "Workspace:{workspaceId}",
1159
+ "error.workspaceNotFound": "无法访问这个 Workspace。请在 DSH 中确认它仍存在、目录路径有效且有读取权限,再刷新列表。",
1160
+ "error.workspaceNotGitRepository": "这个 Workspace 尚不是 Git 仓库。请打开创建 Worktree 弹窗,按其中的指引初始化 Git 并创建首次提交。",
1161
+ "error.initialCommitRequired": "Git 仓库还没有提交。请先在 Workspace 目录创建首次提交,再重试。",
1162
+ "error.branchConflict": "分支名称已存在或已被其他 Worktree 使用。创建时请改用新的名称;需要已有 Worktree 时请使用导入。",
1163
+ "error.worktreeNotFound": "找不到这个 Worktree 或无法访问其目录。请确认目录存在且有读取权限,再刷新;若目录被移动,请先在终端执行 git worktree repair。",
1164
+ "error.worktreeOrderInvalid": "Worktree 列表已变化,无法保存排序。请刷新列表后重新拖动排序。",
1165
+ "error.worktreeRemoved": "这个 Worktree 已归档或已清理,无法执行此操作。归档项请先恢复;已清理项请创建或导入另一个 Worktree。",
1166
+ "error.sessionNotFound": "找不到这个 Session。请刷新 DSH 的 Session 列表,再选择仍存在的会话。",
1167
+ "error.sessionCwdMismatch": "Session 的工作目录与目标 Worktree 不一致,无法绑定。请在目标 Worktree 中新建 Session,或选择工作目录匹配的会话。",
1168
+ "error.sidecarUnavailable": "无法读写 Worktree 管理索引。请检查 DSH 数据目录的权限和磁盘空间,再重试;原生 Session 仍可使用。",
1169
+ "error.sidecarCorrupt": "Worktree 管理索引损坏或格式不兼容,插件已停止修改数据。请保留索引备份并联系维护者恢复;可继续使用 DSH 原生 Session。",
1170
+ "error.sidecarSyncRequired": "Git 操作与管理索引尚未同步。请在设置 → Worktree → 报错与修复中选择重试恢复,完成后刷新列表;不要重复创建或清理。",
1171
+ "error.gitOperationFailed": "Git 操作失败。请确认 Git 可用、目录可访问,并在终端检查 git status;修复 Git 报错后再重试。",
1172
+ "error.permissionBindingRequired": "Session 尚未绑定到有效的 Worktree,无法设置权限。请先在设置 → Worktree → 报错与修复中重试绑定,再确认完全访问。",
1173
+ "error.unexpected": "操作失败(错误码:{code})。请刷新后重试;若仍失败,请将错误码和 DSH 日志提供给维护者。"
1102
1174
  };
1103
1175
  const en = {
1176
+ "tools.experimental": "Experimental",
1177
+ "tools.loading": "Loading tool settings…",
1178
+ "settings.general": "General",
1179
+ "tools.command": "Worktree tools",
1180
+ "tools.commandHint": "Enable /cluworktree to activate the selected capabilities in the current conversation. Turning this off removes the command.",
1181
+ "tools.auto": "Automatically inject Worktree tools",
1182
+ "tools.autoHint": "Inject selected tools before Sessions in this Worktree execute, independently of General settings.",
1183
+ "tools.localAutoHint": "Inject selected tools before Local/Main Sessions in this Workspace execute, independently of General settings.",
1184
+ "tools.selection": "Tool selection",
1185
+ "tools.commandSelectionHint": "/cluworktree adds only missing capabilities.",
1186
+ "tools.autoSelectionHint": "Choose capabilities to inject into this Worktree.",
1187
+ "tools.localAutoSelectionHint": "Apply only to Local/Main Sessions in this Workspace.",
1188
+ "tools.runtimeHint": "Deselecting all turns the switch off. Changes affect future injection; active tools remain until the Agent ends.",
1189
+ "tools.reportHint": "Delegated Sessions receive only result reporting by default.",
1190
+ "tools.failed": "Unable to read or save tool settings. Retry to load the latest configuration.",
1191
+ "tools.create.title": "Create Worktrees",
1192
+ "tools.create.hint": "Create an isolated branch and working directory from committed state, with optional shared instructions.",
1193
+ "tools.worktrees.title": "Discover Worktrees",
1194
+ "tools.worktrees.hint": "Find Worktrees, branches, paths and availability in the current Workspace.",
1195
+ "tools.delegate.title": "Delegate tasks",
1196
+ "tools.delegate.hint": "Create and bind a Session in a Worktree, select its model and dispatch a task. The executing Session can report results.",
1197
+ "tools.models.title": "Discover models",
1198
+ "tools.models.hint": "Find available models and reasoning options for delegated tasks.",
1199
+ "tools.sessions.title": "Discover Sessions",
1200
+ "tools.sessions.hint": "Find Session identities, titles and execution status in the current Workspace or a selected Worktree.",
1201
+ "tools.message.title": "Continue Sessions",
1202
+ "tools.message.hint": "Send follow-up tasks to existing Sessions or steer running work at a native step boundary.",
1203
+ "settings.title": "Worktree",
1204
+ "settings.overview": "Overview",
1205
+ "settings.errors": "Errors & recovery",
1206
+ "settings.description": "Worktree mode groups Sessions by Git worktree. Failures appear as toasts; explanations, diagnostics and recovery actions are collected in Errors & recovery.",
1207
+ "settings.retention": "Records stay in memory for this page and clear on reload. Read the problem and suggested solution before retrying.",
1208
+ "settings.clearHistory": "Clear history",
1209
+ "settings.empty": "No error records.",
1210
+ "settings.operation": "Worktree operation",
1211
+ "settings.active": "Needs attention",
1212
+ "settings.resolved": "History",
1213
+ "settings.inactive": "Operation view closed",
1214
+ "settings.reopen": "Reopen the corresponding Workspace, Dashboard or operation dialog to load its current state and enable recovery actions.",
1215
+ "settings.diagnostics": "Original diagnostics",
1216
+ "settings.toastHint": "Details and recovery: Settings → Worktree → Errors & recovery.",
1217
+ "settings.read": "Read Worktree list",
1218
+ "settings.binding": "Bind Session",
1219
+ "settings.permission": "Adjust Worktree permissions",
1220
+ "settings.git": "Git: {operation}",
1221
+ "settings.adopt": "Adopt current branch",
1222
+ "settings.import": "Read importable Worktrees",
1223
+ "settings.create": "Prepare Worktree creation",
1224
+ "error.gitTimeout": "The Git operation timed out. Check that the repository is accessible and that no other Git operation is stuck, then retry.",
1225
+ "error.gitLocalChanges": "Git found uncommitted or untracked files and blocked this action. Commit or back up changes you want to keep, then inspect the directory and retry.",
1226
+ "error.gitAccessDenied": "Git cannot access the repository or directory. Check file permissions, repository ownership, and the DSH access scope, then retry.",
1227
+ "error.gitLocked": "Another operation has locked the Git repository. Wait for other Git operations to finish, then retry. If the lock remains, check the lock file in a terminal after confirming no Git process is running.",
1228
+ "error.gitInvalidBranch": "The branch name does not meet Git naming rules. Choose a valid name, such as feature/my-task, then retry.",
1104
1229
  restartRequired: "Worktree is installed. Restart DSH Desktop, or restart the DSH Web server and refresh this page, to enable it.",
1105
1230
  "dashboard.title": "Dashboard",
1106
1231
  "dashboard.preview": "Dashboard preview",
1107
1232
  "dashboard.open": "Open Dashboard",
1108
1233
  "dashboard.copyBranch": "Copy branch name",
1109
1234
  "dashboard.branchCopied": "Branch name copied",
1110
- "dashboard.branchCopyFailed": "Branch name copy failed. Try again.",
1235
+ "dashboard.branchCopyFailed": "The branch name could not be copied. Allow clipboard access and retry, or copy the branch name from the title manually.",
1111
1236
  "dashboard.tab.overview": "Dashboard",
1112
1237
  "dashboard.tab.git": "Git & Changes",
1113
1238
  "dashboard.git.title": "Git & Changes",
@@ -1268,7 +1393,7 @@ window.__ModuleLoader__.load({
1268
1393
  "workspace.noMatches": "No matching Workspaces",
1269
1394
  "workspace.renameTitle": "Rename Workspace",
1270
1395
  "workspace.name": "Workspace name",
1271
- "workspace.duplicate": "A Workspace with this name already exists.",
1396
+ "workspace.duplicate": "A Workspace with this name already exists. Choose a different name.",
1272
1397
  "workspace.deleteTitle": "Delete Workspace",
1273
1398
  "workspace.deleteDescription": "Delete {name}? This removes only the DSH Workspace registration. The directory, Sessions, and Git Worktrees will be retained.",
1274
1399
  "worktree.title": "Worktrees",
@@ -1376,50 +1501,69 @@ window.__ModuleLoader__.load({
1376
1501
  "action.retry": "Retry",
1377
1502
  "action.retryBinding": "Retry Binding",
1378
1503
  "action.openCreatedSession": "Open Created Session",
1379
- "permission.fallbackWorkspaceWrite": "The Worktree Full Access preset is unavailable; fell back to workspace-write with approval prompts enabled.",
1380
- "permission.userRestricted": "The restriction selected in DSH’s native permission UI was preserved; this Worktree Session was not elevated.",
1381
- "permission.unverified": "The Worktree Session permission service could not be verified; the Session was retained, but Full Access is not confirmed.",
1382
- "permission.unavailable": "The Worktree Session permission state is temporarily unavailable; retry the request.",
1504
+ "permission.presetRestartRequired": "The Worktree Full Access preset is unavailable. If you just installed or updated Worktree, restart DSH Desktop, or restart the DSH Web server and refresh this page. The workspace-write fallback remains in use.",
1505
+ "permission.fallbackWorkspaceWrite": "The Worktree Full Access preset is unavailable; workspace-write is active with approval prompts enabled. If you just installed or updated Worktree, restart DSH Desktop, or restart the DSH Web server and refresh this page. If the preset is still unavailable after restart or Git encounters access restrictions, check the DSH plugin configuration and Session permission settings.",
1506
+ "permission.userRestricted": "Your selected DSH permission restrictions were preserved. If the task needs more access, adjust this Session’s native permission settings and retry.",
1507
+ "permission.unverified": "Session permissions could not be verified; the Session was retained. Check the permission settings in DSH. Permission updates after cleanup can be retried in Settings → Worktree → Errors & recovery.",
1508
+ "permission.unavailable": "Worktree Session permissions could not be read. Check your DSH connection and the Session permission settings, then retry.",
1383
1509
  "permission.fullAccessTitle": "Enable Worktree Full access?",
1384
1510
  "permission.fullAccessDescription": "Worktree Full access lets this Session access linked Git metadata and Worktree files outside the Session directory. It disables filesystem confinement for this Session while keeping approval prompts enabled; network and process policy are unchanged. Target Worktree: {cwd}",
1385
1511
  "permission.fullAccessAcknowledge": "I understand the risks and want to continue",
1386
1512
  "permission.fullAccessEnable": "Enable Worktree Full access",
1387
1513
  "status.loading": "Loading Workspaces…",
1388
- "error.worktreeDataUnavailable": "Worktree data is unavailable. Retry the request.",
1389
- "error.gitNotInstalled": "Git is not installed or unavailable. Install Git and retry.",
1390
- "error.connectionDisposed": "Worktree connection is disposed; reload the plugin and retry.",
1391
- "error.connectionFailed": "Worktree endpoint {endpoint} failed; retryable connection error: {reason}",
1392
- "error.invalidResult": "Worktree endpoint {endpoint} returned an invalid result; retry the request.",
1514
+ "error.worktreeDataUnavailable": "Worktree data could not be loaded. Check your connection to DSH, then retry. The existing list is preserved.",
1515
+ "error.gitNotInstalled": "Git could not be found. Install Git or add it to PATH, restart DSH, then retry.",
1516
+ "error.connectionDisposed": "The Worktree connection has closed. Refresh the page or restart DSH, then retry.",
1517
+ "error.connectionFailed": "The Worktree service could not be reached. Check that DSH is running and connected, then retry. Restart DSH first if you just installed the plugin.",
1518
+ "error.invalidResult": "The Worktree service returned unrecognized data. Restart DSH and refresh the page. If it still fails, check that your plugin and DSH versions are compatible.",
1393
1519
  "error.workspaceOrderingUnavailable": "Workspace ordering is unavailable; retry after reconnecting.",
1394
1520
  "error.sessionOrderingUnavailable": "Session ordering is unavailable; retry after reconnecting.",
1395
1521
  "error.worktreeOrderingUnavailable": "Worktree ordering is unavailable; retry after reconnecting.",
1396
1522
  "error.worktreeCreatedSessionUnavailable": "Worktree created, but Session creation is unavailable; retry after reconnecting.",
1397
1523
  "error.sessionCreationUnavailable": "Session creation is unavailable; retry after reconnecting.",
1398
- "error.worktreeRecordMissing": "Worktree registration returned no Worktree record; retry the request.",
1399
- "error.worktreeImportInvalid": "This Worktree cannot be imported. Choose a valid absolute path in this Workspace.",
1400
- "error.worktreeAlreadyManaged": "This Worktree is already managed by the plugin.",
1401
- "error.worktreeMutationBusy": "Another DSH instance is mutating Worktree state; retry shortly.",
1402
- "error.worktreeStateConflict": "The Worktree state changed; refresh and retry the request.",
1403
- "error.worktreeRecoveryRequired": "Worktree state requires recovery; resolve it before retrying destructive actions.",
1404
- "error.worktreeIdentityChanged": "The Worktree or repository identity changed; recovery is required before acting.",
1405
- "error.worktreeSessionBusy": "Linked Session activity is still running; operation rejected.",
1406
- "error.worktreeActivityUnavailable": "Unable to verify linked Session activity; operation rejected.",
1524
+ "error.worktreeRecordMissing": "The Worktree registration result could not be confirmed. Refresh the list to check whether creation or import succeeded before repeating the operation. Retry if it is absent.",
1525
+ "error.worktreeImportInvalid": "This directory cannot be imported. Select a branch-attached, unmanaged Worktree from the import list in the same Git repository, excluding the main directory, then retry.",
1526
+ "error.worktreeAlreadyManaged": "This Worktree is already managed. Refresh the list and open its existing entry instead of importing it again.",
1527
+ "error.worktreeMutationBusy": "Another operation is changing this Worktree. Wait for it to finish, then retry. If it remains busy, check your other DSH instances.",
1528
+ "error.worktreeStateConflict": "The Worktree, branch, or saved content changed. Refresh, select again, and reconfirm the action. If editing, copy your draft before cancelling and reopening the editor.",
1529
+ "error.worktreeRecoveryRequired": "A previous Worktree operation still needs recovery, so this action is blocked. Choose Retry Recovery in Settings → Worktree → Errors & recovery, then retry once recovery completes.",
1530
+ "error.worktreeIdentityChanged": "The Worktree or repository no longer matches its registered location. Check the directories; if a Worktree was moved, run git worktree repair, then refresh and retry recovery.",
1531
+ "error.worktreeSessionBusy": "A linked Session or subagent is still running. Wait for it to finish or stop the task in DSH, then retry.",
1532
+ "error.worktreeActivityUnavailable": "Linked Session activity could not be checked. Check your DSH connection, refresh the Session list, then retry.",
1407
1533
  "error.worktreeRegistrationSessionUnavailable": "The Worktree was registered, but Session creation is unavailable; retry after reconnecting.",
1408
1534
  "error.workspaceRenameUnavailable": "Workspace rename is unavailable; retry after reconnecting.",
1409
1535
  "error.workspaceDeleteUnavailable": "Workspace delete is unavailable; retry after reconnecting.",
1410
- "error.workspaceRootMissing": "Workspace directory is missing: {rootPath}",
1536
+ "error.workspaceRootMissing": "The Workspace directory is missing: {rootPath}. Restore it, or remove this Workspace in DSH and add the correct directory, then retry.",
1411
1537
  "error.sessionRenameUnavailable": "Session rename is unavailable; retry after reconnecting.",
1412
- "error.sessionBindingFailed": "Session {sessionId} was created, but Worktree binding failed: {reason}",
1413
- "error.sessionAlreadyBound": "The Session is already bound to another Worktree; no new Session was created.",
1414
- "error.worktreePermissionConfirmationRequired": "The Session and binding were retained; confirm Full Access and retry. The Session was not opened.",
1415
- "error.worktreePermissionFailed": "Worktree Session permission setup failed; retryable error: {reason}",
1416
- "error.sessionListNotReady": "The Session list is not ready yet; retry the request.",
1417
- "error.sessionFactsIncomplete": "Session facts are incomplete; retry the request.",
1418
- "error.worktreeSessionRepairRequired": "The current Worktree Session binding needs repair; retry the request.",
1419
- "error.worktreeSessionUnavailable": "The current Worktree is unavailable; retry the request.",
1420
- "error.sessionArchived": "This Session is archived and cannot be retried for binding.",
1538
+ "error.sessionBindingFailed": "Session {sessionId} was retained, but its Worktree binding failed. {reason}",
1539
+ "error.sessionAlreadyBound": "This Session is already bound to another Worktree. Open its original Worktree or create a new Session in the target Worktree.",
1540
+ "error.worktreePermissionConfirmationRequired": "The Session and binding were retained, but Full Access has not been confirmed. Retry Binding in Settings → Worktree → Errors & recovery and complete the permission confirmation; no new Session is needed.",
1541
+ "error.worktreePermissionFailed": "Worktree Session permissions could not be set; the Session was retained. Check the Session permission settings in DSH, then retry from Settings → Worktree → Errors & recovery.",
1542
+ "error.sessionListNotReady": "The Session list is still loading. Wait a moment, then retry. Reconnect to DSH if it does not finish loading.",
1543
+ "error.sessionFactsIncomplete": "The Session details have not fully loaded, so its working directory cannot be verified. Wait and refresh the list, then retry.",
1544
+ "error.worktreeSessionRepairRequired": "The Session binding needs repair. Use Retry Binding in Settings → Worktree → Errors & recovery. If the directory was moved, run git worktree repair first.",
1545
+ "error.worktreeSessionUnavailable": "This Worktree cannot open or create a Session. Check that its directory exists, has not been cleaned up, and does not need recovery, then refresh and retry.",
1546
+ "error.sessionArchived": "This Session is archived and cannot be rebound. Restore it in DSH or create a new Session in the target Worktree.",
1421
1547
  "branch.current": " (current)",
1422
- "branch.checkedOut": " (checked out)"
1548
+ "branch.checkedOut": " (checked out)",
1549
+ "notice.recovery": "Recovery actions",
1550
+ "notice.sessionRecovery": "Session: {sessionId}",
1551
+ "notice.workspaceRecovery": "Workspace: {workspaceId}",
1552
+ "error.workspaceNotFound": "This Workspace cannot be accessed. Check that it still exists in DSH and that its directory path and read permissions are valid, then refresh the list.",
1553
+ "error.workspaceNotGitRepository": "This Workspace is not a Git repository. Open Create Worktree and follow the setup guidance to initialize Git and make the first commit.",
1554
+ "error.initialCommitRequired": "The Git repository has no commits yet. Make the first commit in the Workspace directory, then retry.",
1555
+ "error.branchConflict": "The branch name already exists or is in use by another Worktree. Choose a new name when creating, or use Import for an existing Worktree.",
1556
+ "error.worktreeNotFound": "This Worktree or its directory cannot be accessed. Check that the directory exists and is readable, then refresh. If it was moved, run git worktree repair in a terminal first.",
1557
+ "error.worktreeOrderInvalid": "The Worktree list changed, so the order could not be saved. Refresh the list, then drag the rows again.",
1558
+ "error.worktreeRemoved": "This Worktree is archived or cleaned up and cannot perform this action. Restore an archived Worktree, or create or import another one if its disk files were cleaned up.",
1559
+ "error.sessionNotFound": "This Session could not be found. Refresh the DSH Session list, then select an existing Session.",
1560
+ "error.sessionCwdMismatch": "The Session working directory does not match this Worktree, so it cannot be bound. Create a Session in the target Worktree or select one with a matching directory.",
1561
+ "error.sidecarUnavailable": "The Worktree management index cannot be read or written. Check permissions and free space in the DSH data directory, then retry. Native Sessions remain available.",
1562
+ "error.sidecarCorrupt": "The Worktree management index is damaged or incompatible, so changes are blocked. Keep a backup and contact the maintainer for recovery. You can continue using native DSH Sessions.",
1563
+ "error.sidecarSyncRequired": "The Git operation and management index are out of sync. Choose Retry Recovery in Settings → Worktree → Errors & recovery, then refresh the list. Avoid repeating creation or cleanup.",
1564
+ "error.gitOperationFailed": "The Git operation failed. Check that Git is available and the directory is accessible, then inspect git status in a terminal. Resolve the Git error before retrying.",
1565
+ "error.permissionBindingRequired": "Permissions cannot be set until the Session is bound to a valid Worktree. Retry Binding in Settings → Worktree → Errors & recovery, then confirm Full Access.",
1566
+ "error.unexpected": "The operation failed (error code: {code}). Refresh and retry. If it still fails, share the error code and DSH logs with the maintainer."
1423
1567
  };
1424
1568
  //#endregion
1425
1569
  //#region lib/client/worktree-connection.js
@@ -1430,6 +1574,9 @@ window.__ModuleLoader__.load({
1430
1574
  * the browser call surface auditable without making React know wire names.
1431
1575
  */
1432
1576
  const WORKTREE_CONNECTION_ENDPOINTS = Object.freeze({
1577
+ getToolSettings: "worktreeManager/getToolSettings",
1578
+ updateToolSettings: "worktreeManager/updateToolSettings",
1579
+ watchToolChanges: "worktreeManager/watchToolChanges",
1433
1580
  listWorktrees: "worktreeManager/listWorktrees",
1434
1581
  listWorktreeCommits: "worktreeManager/listWorktreeCommits",
1435
1582
  listWorktreeCommitFiles: "worktreeManager/listWorktreeCommitFiles",
@@ -1557,6 +1704,9 @@ window.__ModuleLoader__.load({
1557
1704
  return unwrap(WORKTREE_CONNECTION_ENDPOINTS[method], await call(method, input));
1558
1705
  }
1559
1706
  return {
1707
+ getToolSettings: (input) => invoke("getToolSettings", input),
1708
+ updateToolSettings: (input) => invoke("updateToolSettings", input),
1709
+ watchToolChanges: async (afterRevision, signal) => unwrap(WORKTREE_CONNECTION_ENDPOINTS.watchToolChanges, await call("watchToolChanges", { afterRevision }, signal)),
1560
1710
  probeHost: (signal) => call("listBindings", { workspaceId: "" }, signal),
1561
1711
  listWorktrees: (input) => invoke("listWorktrees", input),
1562
1712
  listWorktreeCommits: (input) => invoke("listWorktreeCommits", input),
@@ -1609,6 +1759,62 @@ window.__ModuleLoader__.load({
1609
1759
  };
1610
1760
  }
1611
1761
  //#endregion
1762
+ //#region lib/client/worktree-tool-changes.js
1763
+ /** One cancellable long-poll per Client fiber, shared by Context and Surface. */
1764
+ function createWorktreeToolChangeMonitor(options) {
1765
+ const listeners = /* @__PURE__ */ new Set();
1766
+ let controller = new AbortController();
1767
+ let started = false;
1768
+ let disposed = false;
1769
+ async function run(active) {
1770
+ let revision = 0;
1771
+ while (!active.signal.aborted) try {
1772
+ const batch = await options.read(revision, active.signal);
1773
+ if (active.signal.aborted) return;
1774
+ revision = batch.revision;
1775
+ for (const change of batch.changes) {
1776
+ options.changed(change);
1777
+ for (const listener of listeners) listener(change);
1778
+ }
1779
+ } catch {
1780
+ if (active.signal.aborted) return;
1781
+ await new Promise((resolve) => {
1782
+ const wake = () => {
1783
+ clearTimeout(timer);
1784
+ active.signal.removeEventListener("abort", wake);
1785
+ resolve();
1786
+ };
1787
+ const timer = setTimeout(wake, options.retryMs ?? 5e3);
1788
+ active.signal.addEventListener("abort", wake, { once: true });
1789
+ });
1790
+ }
1791
+ }
1792
+ return {
1793
+ start() {
1794
+ if (started || controller.signal.aborted) return;
1795
+ started = true;
1796
+ run(controller);
1797
+ },
1798
+ reset() {
1799
+ if (disposed) return;
1800
+ controller.abort();
1801
+ controller = new AbortController();
1802
+ if (started) run(controller);
1803
+ },
1804
+ subscribe(listener) {
1805
+ listeners.add(listener);
1806
+ return () => {
1807
+ listeners.delete(listener);
1808
+ };
1809
+ },
1810
+ dispose() {
1811
+ disposed = true;
1812
+ controller.abort();
1813
+ listeners.clear();
1814
+ }
1815
+ };
1816
+ }
1817
+ //#endregion
1612
1818
  //#region lib/client/restart-notice.js
1613
1819
  const MISSING_HOST_CODES = /* @__PURE__ */ new Set([
1614
1820
  "gateway/service-unavailable",
@@ -1618,20 +1824,34 @@ window.__ModuleLoader__.load({
1618
1824
  /** A transient reminder owned by one Client fiber, independent of ready view content. */
1619
1825
  var RestartNotice = class {
1620
1826
  probe;
1621
- visible = false;
1622
- notified = false;
1827
+ reason;
1828
+ notified = /* @__PURE__ */ new Set();
1623
1829
  disposed = false;
1624
1830
  pending;
1625
1831
  listeners = /* @__PURE__ */ new Set();
1626
1832
  constructor(probe) {
1627
1833
  this.probe = probe;
1628
1834
  }
1629
- getSnapshot = () => this.visible;
1835
+ getSnapshot = () => this.reason !== void 0;
1836
+ getReasonSnapshot = () => this.reason;
1630
1837
  subscribe = (listener) => {
1631
1838
  this.listeners.add(listener);
1632
1839
  return () => this.listeners.delete(listener);
1633
1840
  };
1634
- dismiss = () => this.setVisible(false);
1841
+ dismiss = () => this.setReason(void 0);
1842
+ dismissReason = (reason) => {
1843
+ if (this.reason === reason) this.dismiss();
1844
+ };
1845
+ /** Only this domain result establishes that the named preset is missing. */
1846
+ reportPermissionResult(result) {
1847
+ if (this.disposed) return;
1848
+ if (result.status === "fallback-workspace-write" || result.status === "full-applied" || result.status === "already-full") {
1849
+ this.pending?.abort();
1850
+ if (this.reason === "host-unavailable") this.dismiss();
1851
+ }
1852
+ if (result.status === "fallback-workspace-write") this.show("permission-preset-unavailable");
1853
+ else if (this.reason === "permission-preset-unavailable" && (result.status === "full-applied" || result.status === "already-full")) this.dismiss();
1854
+ }
1635
1855
  async check() {
1636
1856
  if (this.disposed) return;
1637
1857
  this.pending?.abort();
@@ -1641,11 +1861,9 @@ window.__ModuleLoader__.load({
1641
1861
  try {
1642
1862
  const result = await this.probe(controller.signal);
1643
1863
  if (this.disposed || controller.signal.aborted || this.pending !== controller) return;
1644
- if (result.ok) this.dismiss();
1645
- else if (!this.notified && MISSING_HOST_CODES.has(result.error?.code ?? "")) {
1646
- this.notified = true;
1647
- this.setVisible(true);
1648
- }
1864
+ if (result.ok) {
1865
+ if (this.reason === "host-unavailable") this.dismiss();
1866
+ } else if (MISSING_HOST_CODES.has(result.error?.code ?? "")) this.show("host-unavailable");
1649
1867
  } catch {} finally {
1650
1868
  clearTimeout(timer);
1651
1869
  if (this.pending === controller) this.pending = void 0;
@@ -1653,24 +1871,32 @@ window.__ModuleLoader__.load({
1653
1871
  }
1654
1872
  dispose() {
1655
1873
  this.disposed = true;
1874
+ this.reason = void 0;
1656
1875
  this.pending?.abort();
1657
1876
  this.listeners.clear();
1658
1877
  }
1659
- setVisible(visible) {
1660
- if (this.visible === visible || this.disposed) return;
1661
- this.visible = visible;
1878
+ show(reason) {
1879
+ if (this.disposed || this.notified.has(reason)) return;
1880
+ this.notified.add(reason);
1881
+ this.setReason(reason);
1882
+ }
1883
+ setReason(reason) {
1884
+ if (this.reason === reason || this.disposed) return;
1885
+ this.reason = reason;
1662
1886
  for (const listener of this.listeners) listener();
1663
1887
  }
1664
1888
  };
1665
1889
  //#endregion
1666
1890
  //#region lib/client/surface/components/RestartToast.js
1667
1891
  function RestartToast({ notice, t }) {
1668
- if (!(0, react.useSyncExternalStore)(notice.subscribe, notice.getSnapshot, notice.getSnapshot)) return null;
1892
+ const reason = (0, react.useSyncExternalStore)(notice.subscribe, notice.getReasonSnapshot, notice.getReasonSnapshot);
1893
+ if (reason === void 0) return null;
1894
+ const presetMissing = reason === "permission-preset-unavailable";
1669
1895
  return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Toast, {
1670
- text: t("restartRequired"),
1671
- holdMs: 8e3,
1672
- onDone: notice.dismiss
1673
- });
1896
+ text: t(presetMissing ? "permission.presetRestartRequired" : "restartRequired"),
1897
+ holdMs: presetMissing ? 12e3 : 8e3,
1898
+ onDone: () => notice.dismissReason(reason)
1899
+ }, reason);
1674
1900
  }
1675
1901
  //#endregion
1676
1902
  //#region lib/client/dsh-icon-compat.js
@@ -1688,7 +1914,6 @@ window.__ModuleLoader__.load({
1688
1914
  const IconArchiveOutline20 = createDshIconAlias(exports$1, "IconArchiveOutline20", "IconArchiveOutlineRegular");
1689
1915
  const IconBranchOutline16 = createDshIconAlias(exports$1, "IconBranchOutline16", "IconBranchOutlineRegular");
1690
1916
  const IconChevronDownOutline14 = createDshIconAlias(exports$1, "IconChevronDownOutline14", "IconChevronDownOutlineRegular");
1691
- const IconChevronRightOutline14 = createDshIconAlias(exports$1, "IconChevronRightOutline14", "IconChevronRightOutlineRegular");
1692
1917
  const IconCheckOutline16 = createDshIconAlias(exports$1, "IconCheckOutline16", "IconCheckOutlineRegular");
1693
1918
  const IconCloseFill14 = createDshIconAlias(exports$1, "IconCloseFill14", "IconCloseFillRegular");
1694
1919
  const IconCloseOutline16 = createDshIconAlias(exports$1, "IconCloseOutline16", "IconCloseOutlineRegular");
@@ -1696,23 +1921,24 @@ window.__ModuleLoader__.load({
1696
1921
  const IconEditOutline16 = createDshIconAlias(exports$1, "IconEditOutline16", "IconEditOutlineRegular");
1697
1922
  const IconEllipsisOutline16 = createDshIconAlias(exports$1, "IconEllipsisOutline16", "IconEllipsisOutlineRegular");
1698
1923
  const IconFolderClose16 = createDshIconAlias(exports$1, "IconFolderClose16", "IconFolderCloseRegular");
1699
- const IconFolderOpen16 = createDshIconAlias(exports$1, "IconFolderOpen16", "IconFolderOpenRegular");
1924
+ const IconFolderOpen16 = createDshIconAlias(exports$1, "IconFolderOpenRegular", "IconFolderOpen16");
1925
+ const IconNewChatOutline16 = createDshIconAlias(exports$1, "IconNewChatOutlineRegular", "IconNewChatOutline16");
1926
+ const IconTriangleRightFill14 = createDshIconAlias(exports$1, "IconTriangleRightFill14", "IconTriangleRightFillRegular");
1700
1927
  const IconPanelLeftOutline16 = createDshIconAlias(exports$1, "IconPanelLeftOutline16", "IconPanelLeftOutlineRegular");
1701
- const IconPlusOutline16 = createDshIconAlias(exports$1, "IconPlusOutline16", "IconPlusOutlineRegular");
1702
1928
  const IconProjectAddOutline16 = createDshIconAlias(exports$1, "IconProjectAddOutline16", "IconProjectAddOutlineRegular");
1703
1929
  const IconRefreshOutline16 = createDshIconAlias(exports$1, "IconRefreshOutline16", "IconRefreshOutlineRegular");
1704
1930
  const IconRightUpOutline16 = createDshIconAlias(exports$1, "IconRightUpOutline16", "IconRightUpOutlineRegular");
1705
1931
  const IconSearchOutline16 = createDshIconAlias(exports$1, "IconSearchOutline16", "IconSearchOutlineRegular");
1706
1932
  const IconTrashOutline16 = createDshIconAlias(exports$1, "IconTrashOutline16", "IconTrashOutlineRegular");
1707
1933
  //#endregion
1708
- //#region \0clutch-dsh-worktree-css:/Users/yuancheng/.dsh/clutch-dsh-worktree/worktree/wt_63cf54e5ec74/packages/clutch-dsh-worktree/src/client/context/worktree-context.css.mjs
1709
- const css$5 = ".-cerbur-clutch-dsh-worktree-headerContext {\n display: inline-flex;\n min-width: 0;\n height: 22px;\n align-items: center;\n gap: 4px;\n max-width: 180px;\n overflow: hidden;\n border-radius: 6px;\n padding: 0 2px 0 0;\n background: var(--dsw-alias-fill-tsp-secondary);\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n line-height: 22px;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-contextIcon {\n flex: none;\n opacity: 0.7;\n}\n\n.-cerbur-clutch-dsh-worktree-contextLabel {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-contextHoverTitle {\n max-width: 360px;\n color: var(--dsw-static-neutral-bluish-00);\n font-size: 14px;\n line-height: 20px;\n overflow-wrap: anywhere;\n white-space: normal;\n}\n\n.-cerbur-clutch-dsh-worktree-heroContextHost {\n position: absolute;\n z-index: 0;\n display: block;\n width: max-content;\n max-width: 260px;\n min-height: 22px;\n}\n\n.-cerbur-clutch-dsh-worktree-heroContext {\n display: inline-flex;\n box-sizing: border-box;\n max-width: 260px;\n min-height: 22px;\n align-items: center;\n overflow: hidden;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n padding: 0 8px;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n line-height: 20px;\n pointer-events: auto;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n";
1710
- const styleId$5 = "@cerbur/clutch-dsh-worktree/worktree-context.css";
1934
+ //#region \0clutch-dsh-worktree-css:/Users/yuancheng/.dsh/clutch-dsh-worktree/worktree/wt_ece6fafadbd1/packages/clutch-dsh-worktree/src/client/context/worktree-context.css.mjs
1935
+ const css$6 = ".-cerbur-clutch-dsh-worktree-headerContext {\n display: inline-flex;\n min-width: 0;\n height: 22px;\n align-items: center;\n gap: 4px;\n max-width: 180px;\n overflow: hidden;\n border-radius: 6px;\n padding: 0 2px 0 0;\n background: var(--dsw-alias-fill-tsp-secondary);\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n line-height: 22px;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-contextIcon {\n flex: none;\n opacity: 0.7;\n}\n\n.-cerbur-clutch-dsh-worktree-contextLabel {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-contextHoverTitle {\n max-width: 360px;\n color: var(--dsw-static-neutral-bluish-00);\n font-size: 14px;\n line-height: 20px;\n overflow-wrap: anywhere;\n white-space: normal;\n}\n\n.-cerbur-clutch-dsh-worktree-heroContextHost {\n position: absolute;\n z-index: 0;\n display: block;\n width: max-content;\n max-width: 260px;\n min-height: 22px;\n}\n\n.-cerbur-clutch-dsh-worktree-heroContext {\n display: inline-flex;\n box-sizing: border-box;\n max-width: 260px;\n min-height: 22px;\n align-items: center;\n overflow: hidden;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n padding: 0 8px;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n line-height: 20px;\n pointer-events: auto;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n";
1936
+ const styleId$6 = "@cerbur/clutch-dsh-worktree/worktree-context.css";
1711
1937
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@cerbur/clutch-dsh-worktree/worktree-context.css\"]") === null) {
1712
1938
  const tag = document.createElement("style");
1713
1939
  tag.dataset.plugin = "@cerbur/clutch-dsh-worktree";
1714
- tag.dataset.pluginCss = styleId$5;
1715
- tag.textContent = css$5;
1940
+ tag.dataset.pluginCss = styleId$6;
1941
+ tag.textContent = css$6;
1716
1942
  document.head.appendChild(tag);
1717
1943
  }
1718
1944
  var worktree_context_css_default = {
@@ -1769,14 +1995,14 @@ window.__ModuleLoader__.load({
1769
1995
  globalSetViewMode?.(mode);
1770
1996
  }
1771
1997
  //#endregion
1772
- //#region \0clutch-dsh-worktree-css:/Users/yuancheng/.dsh/clutch-dsh-worktree/worktree/wt_63cf54e5ec74/packages/clutch-dsh-worktree/src/client/worktree.css.mjs
1773
- const css$4 = ".-cerbur-clutch-dsh-worktree-action {\n display: flex;\n align-items: center;\n justify-content: flex-start;\n gap: 8px;\n width: calc(100% + 4px);\n height: 42px;\n margin: 4px -2px;\n box-sizing: border-box;\n border: 0;\n border-radius: 12px;\n padding: 0 10px 0 8px;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n font: inherit;\n font-size: 14px;\n line-height: 22px;\n text-align: left;\n overflow: hidden;\n}\n\n.-cerbur-clutch-dsh-worktree-action:hover,\n.-cerbur-clutch-dsh-worktree-action[data-active='true'] {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-action[data-collapsed='true'] {\n width: 36px;\n height: 36px;\n margin: 8px 0 10px;\n justify-content: center;\n gap: 0;\n padding: 0;\n border-radius: 50%;\n}\n\n.-cerbur-clutch-dsh-worktree-actionLabel {\n display: inline-flex;\n min-width: 0;\n align-items: center;\n height: 22px;\n overflow: hidden;\n font-weight: 400;\n line-height: 22px;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-surface {\n position: absolute;\n top: 0;\n left: 0;\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n min-width: 0;\n overflow: hidden;\n border-right: 1px solid var(--dsw-alias-border-l1);\n background: var(--dsw-specific-sidebar-fill);\n color: var(--dsw-alias-label-primary);\n pointer-events: auto;\n transition: width var(--ds-transition-duration-slow) var(--ds-ease-in-out);\n}\n\n/* Native macOS AppFrame already paints the tint over OS window vibrancy.\n Once the covered native rows are concealed, use that one material without\n adding another fill or backdrop root (menus keep their own native blur). */\n[data-platform='darwin'] .-cerbur-clutch-dsh-worktree-surface[data-native-sidebar-covered='true'] {\n background: transparent;\n border-right: none;\n}\n\n/* The shell overlay is outside the native column's clipping boundary.\n Follow the semantic collapse immediately, even during the track transition. */\n[data-sidebar-collapsed] [data-shell-overlay] .-cerbur-clutch-dsh-worktree-surface,\n.-cerbur-clutch-dsh-worktree-surface[data-collapsed='true'] {\n visibility: hidden;\n opacity: 0;\n pointer-events: none;\n}\n\n@media (prefers-reduced-transparency: reduce) {\n [data-platform='darwin'] .-cerbur-clutch-dsh-worktree-surface[data-native-sidebar-covered='true'] {\n background: color-mix(in srgb, var(--dsw-specific-sidebar-fill) 90%, transparent);\n }\n}\n\n.-cerbur-clutch-dsh-worktree-motionExits {\n position: absolute;\n inset: 0;\n contain: strict;\n overflow: clip;\n pointer-events: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .-cerbur-clutch-dsh-worktree-surface {\n transition: none;\n }\n}\n\n.-cerbur-clutch-dsh-worktree-wideContent {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n}\n\n.-cerbur-clutch-dsh-worktree-surface[data-collapsed='true'] .-cerbur-clutch-dsh-worktree-wideContent {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeModalTabs {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeModalTab {\n border: 0;\n border-bottom: 2px solid transparent;\n padding: 4px 0;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n font: inherit;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeModalTab[aria-selected='true'] {\n border-bottom-color: var(--dsw-alias-label-primary);\n color: var(--dsw-alias-label-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeImportCandidates {\n display: grid;\n gap: 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeImportSelect {\n width: 100%;\n min-width: 0;\n padding: 7px 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: var(--dsw-alias-button-elevated-fill);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 13px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeImportError {\n display: grid;\n gap: 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-closeButton {\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: inherit;\n cursor: pointer;\n font: inherit;\n}\n\n.-cerbur-clutch-dsh-worktree-closeButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-header {\n display: flex;\n align-items: center;\n gap: 6px;\n flex: none;\n min-height: 44px;\n padding: 6px 10px;\n box-sizing: border-box;\n border-bottom: 1px solid var(--dsw-alias-border-l1);\n}\n\n.-cerbur-clutch-dsh-worktree-title {\n min-width: 0;\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 14px;\n font-weight: 600;\n opacity: 1;\n visibility: visible;\n transition:\n opacity 120ms var(--ds-ease-in-out),\n transform 180ms var(--ds-ease-in-out),\n visibility 0s linear;\n}\n\n.-cerbur-clutch-dsh-worktree-titleHidden {\n flex: 0 0 0px;\n max-width: 0;\n opacity: 0;\n transform: translateX(-4px);\n visibility: hidden;\n pointer-events: none;\n transition-delay: 0s, 0s, 180ms;\n}\n\n.-cerbur-clutch-dsh-worktree-closeButton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n width: 28px;\n height: 28px;\n border: 0;\n border-radius: 7px;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n font: inherit;\n font-size: 16px;\n line-height: 1;\n}\n\n.-cerbur-clutch-dsh-worktree-closeButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-modeButton[data-active='true'] {\n color: var(--dsw-alias-label-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-workspacePicker {\n display: block;\n width: calc(100% - 20px);\n margin: 6px 10px 8px;\n padding: 6px 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 7px;\n background: var(--dsw-alias-button-elevated-fill);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceLabel {\n display: block;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-content {\n min-height: 0;\n flex: 1;\n overflow: auto;\n padding: 0 10px 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-content:focus-visible {\n outline: 2px solid var(--dsw-alias-border-l3);\n outline-offset: -2px;\n}\n\n.-cerbur-clutch-dsh-worktree-error {\n margin: 12px 0 0;\n padding: 8px;\n border: 1px solid var(--dsw-alias-state-error-primary);\n border-radius: 7px;\n}\n\n.-cerbur-clutch-dsh-worktree-notice {\n margin: 12px 0 0;\n padding: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 7px;\n background: var(--dsw-alias-button-elevated-fill);\n}\n\n.-cerbur-clutch-dsh-worktree-retryButton,\n.-cerbur-clutch-dsh-worktree-actionButton {\n border: 0;\n border-radius: 6px;\n background: var(--dsw-alias-button-elevated-fill);\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n font: inherit;\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-retryButton,\n.-cerbur-clutch-dsh-worktree-actionButton {\n width: 100%;\n padding: 6px 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-recoveryActions {\n display: grid;\n gap: 6px;\n margin-top: 6px;\n}\n\n.-cerbur-clutch-dsh-worktree-retryButton:disabled,\n.-cerbur-clutch-dsh-worktree-actionButton:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.-cerbur-clutch-dsh-worktree-actions {\n display: grid;\n gap: 6px;\n margin-top: 10px;\n padding: 8px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 7px;\n}\n\n.-cerbur-clutch-dsh-worktree-actionSelect {\n min-width: 0;\n padding: 5px 6px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: var(--dsw-alias-button-elevated-fill);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-section {\n margin: 12px 0 0;\n}\n\n.-cerbur-clutch-dsh-worktree-sectionTitle {\n margin: 0 2px 4px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n}\n\n.-cerbur-clutch-dsh-worktree-empty,\n.-cerbur-clutch-dsh-worktree-message {\n margin: 0;\n padding: 8px 4px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 12px;\n line-height: 18px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitReadiness {\n display: grid;\n gap: 4px;\n}\n\n.-cerbur-clutch-dsh-worktree-commandBlock {\n margin: 6px 0 0;\n padding: 8px;\n overflow-x: auto;\n border-radius: 6px;\n background: var(--dsw-alias-button-elevated-fill);\n color: var(--dsw-alias-label-secondary);\n font:\n 11px/16px ui-monospace,\n SFMono-Regular,\n Menlo,\n monospace;\n white-space: pre-wrap;\n}\n\n.-cerbur-clutch-dsh-worktree-message[data-error='true'] {\n color: var(--dsw-alias-state-error-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-worktree,\n.-cerbur-clutch-dsh-worktree-session {\n display: flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n box-sizing: border-box;\n border: 0;\n border-radius: 7px;\n padding: 6px 8px;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 12px;\n text-align: left;\n}\n\n.-cerbur-clutch-dsh-worktree-worktree {\n cursor: default;\n}\n\n.-cerbur-clutch-dsh-worktree-session {\n cursor: pointer;\n}\n\n.-cerbur-clutch-dsh-worktree-worktree:hover,\n.-cerbur-clutch-dsh-worktree-session:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeLabel,\n.-cerbur-clutch-dsh-worktree-sessionLabel {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-status {\n flex: none;\n margin-left: auto;\n padding-left: 8px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-searchSlot {\n flex: none;\n max-width: 28px;\n min-width: 0;\n display: flex;\n align-items: center;\n margin-left: auto;\n box-sizing: border-box;\n transition:\n flex 180ms var(--ds-ease-in-out),\n max-width 180ms var(--ds-ease-in-out);\n}\n\n.-cerbur-clutch-dsh-worktree-searchSlotExpanded {\n flex: 1;\n max-width: 100%;\n}\n\n.-cerbur-clutch-dsh-worktree-headerActions {\n flex: none;\n display: flex;\n align-items: center;\n gap: 4px;\n margin-left: 0;\n opacity: 1;\n visibility: visible;\n transition:\n opacity 120ms var(--ds-ease-in-out),\n transform 180ms var(--ds-ease-in-out),\n visibility 0s linear;\n}\n\n.-cerbur-clutch-dsh-worktree-headerActionsHidden {\n flex: 0 0 0px;\n max-width: 0;\n margin-left: 0;\n opacity: 0;\n transform: translateX(4px);\n visibility: hidden;\n pointer-events: none;\n transition-delay: 0s, 0s, 180ms;\n}\n\n.-cerbur-clutch-dsh-worktree-search {\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\n height: 28px;\n box-sizing: border-box;\n border-radius: 6px;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n transition:\n background 180ms var(--ds-ease-in-out),\n box-shadow 180ms var(--ds-ease-in-out),\n color 180ms var(--ds-ease-in-out);\n}\n\n.-cerbur-clutch-dsh-worktree-searchExpanded {\n background: var(--dsw-alias-interactive-bg-subtle);\n box-shadow: inset 0 0 0 1px var(--dsw-alias-border-l2);\n}\n\n.-cerbur-clutch-dsh-worktree-searchExpanded:focus-within {\n box-shadow: inset 0 0 0 1px #3b82f6;\n}\n\n.-cerbur-clutch-dsh-worktree-searchButton {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n border-radius: 50%;\n padding: 0;\n background: transparent;\n cursor: pointer;\n color: inherit;\n}\n\n.-cerbur-clutch-dsh-worktree-searchButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-searchExpanded .-cerbur-clutch-dsh-worktree-searchButton:hover {\n background: transparent;\n}\n\n.-cerbur-clutch-dsh-worktree-searchInput {\n flex: 1;\n width: 0;\n min-width: 0;\n box-sizing: border-box;\n border: none;\n outline: none;\n background: transparent;\n opacity: 0;\n pointer-events: none;\n font: inherit;\n font-size: 13px;\n line-height: 18px;\n color: var(--dsw-alias-label-primary);\n transition: opacity 120ms var(--ds-ease-in-out);\n}\n\n.-cerbur-clutch-dsh-worktree-searchExpanded .-cerbur-clutch-dsh-worktree-searchInput {\n margin-left: -2px;\n opacity: 1;\n pointer-events: auto;\n}\n\n.-cerbur-clutch-dsh-worktree-searchInput::placeholder {\n color: var(--dsw-alias-label-tertiary);\n}\n\n.-cerbur-clutch-dsh-worktree-clearButton {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border: none;\n border-radius: 50%;\n padding: 0;\n background: transparent;\n cursor: pointer;\n color: var(--dsw-alias-label-secondary);\n}\n\n.-cerbur-clutch-dsh-worktree-clearButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-actionSelect:focus,\n.-cerbur-clutch-dsh-worktree-worktreeImportSelect:focus {\n border-color: #3b82f6;\n}\n\n.-cerbur-clutch-dsh-worktree-iconButton {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: 0;\n border-radius: 7px;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n font: inherit;\n font-size: 20px;\n line-height: 1;\n}\n\n.-cerbur-clutch-dsh-worktree-iconButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceList {\n position: relative;\n min-width: 0;\n min-height: 0;\n display: grid;\n gap: 4px;\n overflow-x: hidden;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceGroup {\n min-width: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow,\n.-cerbur-clutch-dsh-worktree-worktreeRow {\n position: relative;\n display: flex;\n align-items: center;\n min-width: 0;\n min-height: 36px;\n box-sizing: border-box;\n border-radius: 8px;\n padding: 3px 4px;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow:hover,\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow .-cerbur-clutch-dsh-worktree-workspaceDisclosure {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow:hover .-cerbur-clutch-dsh-worktree-workspaceDisclosure,\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-workspaceDisclosure {\n display: inline-flex;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow:hover .-cerbur-clutch-dsh-worktree-workspaceIcon,\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-workspaceIcon {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-worktreeDisclosure {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover .-cerbur-clutch-dsh-worktree-worktreeDisclosure,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-worktreeDisclosure {\n display: inline-flex;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover .-cerbur-clutch-dsh-worktree-worktreeIcon,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-worktreeIcon {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-disclosureButton {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 28px;\n border: 0;\n border-radius: 6px;\n padding: 0;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n font: inherit;\n font-size: 17px;\n line-height: 1;\n}\n\n.-cerbur-clutch-dsh-worktree-disclosureButton > svg {\n display: block;\n}\n\n.-cerbur-clutch-dsh-worktree-disclosureButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceIcon,\n.-cerbur-clutch-dsh-worktree-worktreeIcon {\n flex: none;\n width: 24px;\n color: var(--dsw-alias-label-secondary);\n font-size: 20px;\n line-height: 1;\n text-align: center;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeIcon[data-worktree-state='done'] {\n color: var(--dsw-alias-state-success-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeIcon[data-worktree-state='warning'] {\n color: var(--dsw-alias-state-warn-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeIcon[data-worktree-state='error'] {\n color: var(--dsw-alias-state-error-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeStateLabel {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n overflow: hidden;\n border: 0;\n padding: 0;\n clip: rect(0 0 0 0);\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceIcon {\n color: var(--dsw-alias-brand-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceTitle,\n.-cerbur-clutch-dsh-worktree-worktreeLabel {\n min-width: 0;\n overflow: hidden;\n flex: 1;\n padding: 0 6px;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 14px;\n font-weight: 400;\n line-height: 20px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-main-group='true'] .-cerbur-clutch-dsh-worktree-worktreeLabel {\n font-weight: 600;\n}\n\n/* A collapsed running row keeps one shared scroll container for its label. */\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true'] .-cerbur-clutch-dsh-worktree-worktreeLabel,\n/* Once the action rail is revealed, allow long branch labels to scroll inline. */\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover .-cerbur-clutch-dsh-worktree-worktreeLabel,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-worktreeLabel,\n.-cerbur-clutch-dsh-worktree-worktreeRow:focus-within .-cerbur-clutch-dsh-worktree-worktreeLabel {\n overflow-x: auto;\n overflow-y: hidden;\n text-overflow: clip;\n scrollbar-width: none;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true'] .-cerbur-clutch-dsh-worktree-worktreeLabel::-webkit-scrollbar,\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover .-cerbur-clutch-dsh-worktree-worktreeLabel::-webkit-scrollbar,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-worktreeLabel::-webkit-scrollbar,\n.-cerbur-clutch-dsh-worktree-worktreeRow:focus-within .-cerbur-clutch-dsh-worktree-worktreeLabel::-webkit-scrollbar {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeHoverTitle {\n color: var(--dsw-static-neutral-bluish-00);\n font-size: 14px;\n line-height: 20px;\n overflow-wrap: anywhere;\n}\n\n/* Native Session hover card: full title, relative time, and current status. */\n.-cerbur-clutch-dsh-worktree-sessionHoverContent {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionHoverTitle {\n color: #FFFFFF;\n font-size: 14px;\n line-height: 20px;\n overflow-wrap: break-word;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionHoverTime {\n color: #CFD3D6;\n font-size: 12px;\n line-height: 16px;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionHoverStatus {\n display: flex;\n align-items: center;\n gap: 8px;\n color: #ADB2B8;\n font-size: 12px;\n line-height: 20px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeActionSlot,\n.-cerbur-clutch-dsh-worktree-workspaceActions {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: flex-end;\n height: 28px;\n margin-left: auto;\n}\n\n/* Workspace rows retain the native fixed action column. */\n.-cerbur-clutch-dsh-worktree-workspaceActions {\n flex: 0 0 64px;\n width: 64px;\n}\n\n/* Group actions do not reserve space until their row needs to show them. */\n.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-treeActionSlot {\n min-width: 0;\n flex: 0 0 0;\n width: 0;\n gap: 4px;\n}\n\n/* Keep the 28px activity indicator plus a 4px label gap while collapsed. */\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true'] .-cerbur-clutch-dsh-worktree-treeActionSlot {\n flex: 0 0 32px;\n width: 32px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover .-cerbur-clutch-dsh-worktree-treeActionSlot,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-treeActionSlot,\n.-cerbur-clutch-dsh-worktree-worktreeRow:focus-within .-cerbur-clutch-dsh-worktree-treeActionSlot {\n flex: 0 0 auto;\n width: auto;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceActions > .-cerbur-clutch-dsh-worktree-menuAction {\n position: absolute;\n top: 0;\n right: 32px;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceActions > .-cerbur-clutch-dsh-worktree-iconButton:last-child {\n position: absolute;\n top: 0;\n right: 0;\n}\n\n/* Worktree actions flow naturally so the rail matches the controls that exist. */\n.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-dashboardAction,\n.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-menuAction,\n.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child {\n position: static;\n opacity: 0;\n pointer-events: none;\n visibility: visible;\n}\n\n.-cerbur-clutch-dsh-worktree-groupActivity {\n position: absolute;\n top: 0;\n right: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n visibility: hidden;\n pointer-events: none;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-group-activity='true'] .-cerbur-clutch-dsh-worktree-groupActivity,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true'] .-cerbur-clutch-dsh-worktree-groupActivity {\n visibility: visible;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-group-activity='true']:hover .-cerbur-clutch-dsh-worktree-groupActivity,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true']:hover .-cerbur-clutch-dsh-worktree-groupActivity,\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-group-activity='true'][data-menu-open='true'] .-cerbur-clutch-dsh-worktree-groupActivity,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true'][data-menu-open='true'] .-cerbur-clutch-dsh-worktree-groupActivity,\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-group-activity='true']:focus-within .-cerbur-clutch-dsh-worktree-groupActivity,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true']:focus-within .-cerbur-clutch-dsh-worktree-groupActivity {\n visibility: hidden;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-group-activity='true'] .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true'] .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child {\n visibility: hidden;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-group-activity='true']:hover .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true']:hover .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child,\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-group-activity='true'][data-menu-open='true']\n .-cerbur-clutch-dsh-worktree-treeActionSlot\n > .-cerbur-clutch-dsh-worktree-iconButton:last-child,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true'][data-menu-open='true']\n .-cerbur-clutch-dsh-worktree-treeActionSlot\n > .-cerbur-clutch-dsh-worktree-iconButton:last-child,\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-group-activity='true']:focus-within .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true']:focus-within .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child {\n visibility: visible;\n}\n\n.-cerbur-clutch-dsh-worktree-dashboardAction {\n display: inline-flex;\n flex: 0 0 28px;\n width: 28px;\n height: 28px;\n visibility: hidden;\n}\n\n.-cerbur-clutch-dsh-worktree-menuAction {\n display: inline-flex;\n flex: 0 0 28px;\n width: 28px;\n height: 28px;\n visibility: hidden;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow:hover .-cerbur-clutch-dsh-worktree-menuAction,\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-menuAction,\n.-cerbur-clutch-dsh-worktree-workspaceRow:focus-within .-cerbur-clutch-dsh-worktree-menuAction {\n visibility: visible;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-dashboardAction,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-dashboardAction,\n.-cerbur-clutch-dsh-worktree-worktreeRow:focus-within .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-dashboardAction,\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-menuAction,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-menuAction,\n.-cerbur-clutch-dsh-worktree-worktreeRow:focus-within .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-menuAction,\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child,\n.-cerbur-clutch-dsh-worktree-worktreeRow:focus-within .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child {\n opacity: 1;\n pointer-events: auto;\n visibility: visible;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow.-cerbur-clutch-dsh-worktree-dropBefore::before,\n.-cerbur-clutch-dsh-worktree-workspaceRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n position: absolute;\n right: 4px;\n left: 4px;\n height: 2px;\n border-radius: 2px;\n background: var(--dsw-alias-brand-primary);\n content: '';\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow.-cerbur-clutch-dsh-worktree-dropBefore::before {\n top: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n bottom: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow.-cerbur-clutch-dsh-worktree-dropBefore::before,\n.-cerbur-clutch-dsh-worktree-worktreeRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n position: absolute;\n right: 4px;\n left: 4px;\n height: 2px;\n border-radius: 2px;\n background: var(--dsw-alias-brand-primary);\n content: '';\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow.-cerbur-clutch-dsh-worktree-dropBefore::before {\n top: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n bottom: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeChildren {\n margin-left: 16px;\n padding: 2px 0 5px 12px;\n border-left: 1px solid var(--dsw-alias-border-l1);\n}\n\n.-cerbur-clutch-dsh-worktree-groupLabel {\n padding: 6px 8px 3px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n}\n\n.-cerbur-clutch-dsh-worktree-groupHeader {\n display: flex;\n align-items: center;\n min-height: 34px;\n padding-right: 4px;\n}\n\n.-cerbur-clutch-dsh-worktree-groupHeader .-cerbur-clutch-dsh-worktree-groupLabel {\n flex: 1;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeGroup {\n margin-top: 2px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow {\n min-height: 34px;\n}\n\n/* Compact the Worktree leading slots to make room for its third action. */\n.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-worktreeIcon,\n.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-disclosureButton {\n width: 20px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow {\n position: relative;\n display: flex;\n align-items: center;\n width: calc(100% - 20px);\n margin-left: 20px;\n min-width: 0;\n min-height: 31px;\n box-sizing: border-box;\n border-radius: 7px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow:hover,\n.-cerbur-clutch-dsh-worktree-treeSessionRow[data-menu-open='true'] {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow[data-session-current='true'] {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow[data-session-current='true'] .-cerbur-clutch-dsh-worktree-treeSessionContent {\n font-weight: 600;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow.-cerbur-clutch-dsh-worktree-dropBefore::before,\n.-cerbur-clutch-dsh-worktree-treeSessionRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n position: absolute;\n right: 4px;\n left: 4px;\n height: 2px;\n border-radius: 2px;\n background: var(--dsw-alias-brand-primary);\n content: '';\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow.-cerbur-clutch-dsh-worktree-dropBefore::before {\n top: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n bottom: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionContent {\n display: flex;\n align-items: center;\n flex: 1;\n width: 0;\n min-width: 0;\n min-height: 31px;\n box-sizing: border-box;\n border: 0;\n border-radius: 7px;\n padding: 4px 4px;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n font: inherit;\n font-size: 14px;\n font-weight: 400;\n line-height: 20px;\n text-align: left;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionContent:hover {\n background: transparent;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionTrailing {\n position: relative;\n display: inline-flex;\n flex: 0 0 52px;\n align-items: center;\n justify-content: flex-end;\n width: 52px;\n height: 28px;\n margin-left: auto;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionMeta,\n.-cerbur-clutch-dsh-worktree-rowActions {\n position: absolute;\n inset: 0;\n display: inline-flex;\n align-items: center;\n justify-content: flex-end;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionMeta {\n color: var(--dsw-alias-label-tertiary);\n pointer-events: none;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionStatus {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionTime {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n margin-right: 4px;\n font-size: 12px;\n line-height: 20px;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionOverflowButton {\n display: block;\n width: calc(100% - 24px);\n margin: 2px 0 4px 24px;\n padding: 4px 8px;\n border: 0;\n border-radius: 6px;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n font: inherit;\n font-size: 12px;\n font-weight: 400;\n line-height: 20px;\n text-align: left;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionOverflowButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-rowActions {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow:hover .-cerbur-clutch-dsh-worktree-sessionMeta,\n.-cerbur-clutch-dsh-worktree-treeSessionRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-sessionMeta,\n.-cerbur-clutch-dsh-worktree-sessionTrailing:focus-within .-cerbur-clutch-dsh-worktree-sessionMeta {\n visibility: hidden;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow:hover .-cerbur-clutch-dsh-worktree-rowActions,\n.-cerbur-clutch-dsh-worktree-treeSessionRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-rowActions,\n.-cerbur-clutch-dsh-worktree-sessionTrailing:focus-within .-cerbur-clutch-dsh-worktree-rowActions {\n display: inline-flex;\n}\n\n.-cerbur-clutch-dsh-worktree-renameInput {\n width: 100%;\n}\n\n.-cerbur-clutch-dsh-worktree-renameError {\n margin: 8px 0 0;\n color: var(--dsw-alias-state-error-primary);\n font-size: 13px;\n line-height: 20px;\n}\n\n.-cerbur-clutch-dsh-worktree-emptyNested {\n margin: 0;\n padding: 4px 8px 5px 28px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-archivedGroup {\n margin-top: 4px;\n}\n\n.-cerbur-clutch-dsh-worktree-modalField {\n display: grid;\n gap: 5px;\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n}\n.-cerbur-clutch-dsh-worktree-worktreeHoverDetails {\n max-width: 360px;\n white-space: normal;\n overflow-wrap: anywhere;\n line-height: 1.5;\n}\n\n.-cerbur-clutch-dsh-worktree-notificationDetails > summary {\n cursor: pointer;\n padding: 8px;\n font-size: 12px;\n}\n";
1774
- const styleId$4 = "@cerbur/clutch-dsh-worktree/worktree.css";
1998
+ //#region \0clutch-dsh-worktree-css:/Users/yuancheng/.dsh/clutch-dsh-worktree/worktree/wt_ece6fafadbd1/packages/clutch-dsh-worktree/src/client/worktree.css.mjs
1999
+ const css$5 = ".-cerbur-clutch-dsh-worktree-action {\n display: flex;\n align-items: center;\n justify-content: flex-start;\n gap: 8px;\n width: calc(100% + 4px);\n height: 42px;\n margin: 4px -2px;\n box-sizing: border-box;\n border: 0;\n border-radius: 12px;\n padding: 0 10px 0 8px;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n font: inherit;\n font-size: 14px;\n line-height: 22px;\n text-align: left;\n overflow: hidden;\n}\n\n.-cerbur-clutch-dsh-worktree-action:hover,\n.-cerbur-clutch-dsh-worktree-action[data-active='true'] {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-action[data-collapsed='true'] {\n width: 36px;\n height: 36px;\n margin: 8px 0 10px;\n justify-content: center;\n gap: 0;\n padding: 0;\n border-radius: 50%;\n}\n\n.-cerbur-clutch-dsh-worktree-actionLabel {\n display: inline-flex;\n min-width: 0;\n align-items: center;\n height: 22px;\n overflow: hidden;\n font-weight: 400;\n line-height: 22px;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-surface {\n position: absolute;\n top: 0;\n left: 0;\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n min-width: 0;\n overflow: hidden;\n border-right: 1px solid var(--dsw-alias-border-l1);\n background: var(--dsw-specific-sidebar-fill);\n color: var(--dsw-alias-label-primary);\n pointer-events: auto;\n transition: width var(--ds-transition-duration-slow) var(--ds-ease-in-out);\n}\n\n/* Native macOS AppFrame already paints the tint over OS window vibrancy.\n Once the covered native rows are concealed, use that one material without\n adding another fill or backdrop root (menus keep their own native blur). */\n[data-platform='darwin'] .-cerbur-clutch-dsh-worktree-surface[data-native-sidebar-covered='true'] {\n background: transparent;\n border-right: none;\n}\n\n/* The shell overlay is outside the native column's clipping boundary.\n Follow the semantic collapse immediately, even during the track transition. */\n[data-sidebar-collapsed] [data-shell-overlay] .-cerbur-clutch-dsh-worktree-surface,\n.-cerbur-clutch-dsh-worktree-surface[data-collapsed='true'] {\n visibility: hidden;\n opacity: 0;\n pointer-events: none;\n}\n\n@media (prefers-reduced-transparency: reduce) {\n [data-platform='darwin'] .-cerbur-clutch-dsh-worktree-surface[data-native-sidebar-covered='true'] {\n background: color-mix(in srgb, var(--dsw-specific-sidebar-fill) 90%, transparent);\n }\n}\n\n.-cerbur-clutch-dsh-worktree-motionExits {\n position: absolute;\n inset: 0;\n contain: strict;\n overflow: clip;\n pointer-events: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .-cerbur-clutch-dsh-worktree-surface {\n transition: none;\n }\n}\n\n.-cerbur-clutch-dsh-worktree-wideContent {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n}\n\n.-cerbur-clutch-dsh-worktree-surface[data-collapsed='true'] .-cerbur-clutch-dsh-worktree-wideContent {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeModalTabs {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeModalTab {\n border: 0;\n border-bottom: 2px solid transparent;\n padding: 4px 0;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n font: inherit;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeModalTab[aria-selected='true'] {\n border-bottom-color: var(--dsw-alias-label-primary);\n color: var(--dsw-alias-label-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeImportCandidates {\n display: grid;\n gap: 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeImportSelect {\n width: 100%;\n min-width: 0;\n padding: 7px 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: var(--dsw-alias-button-elevated-fill);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 13px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeImportError {\n display: grid;\n gap: 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-closeButton {\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: inherit;\n cursor: pointer;\n font: inherit;\n}\n\n.-cerbur-clutch-dsh-worktree-closeButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-header {\n display: flex;\n align-items: center;\n gap: 6px;\n flex: none;\n min-height: 44px;\n padding: 6px 10px;\n box-sizing: border-box;\n border-bottom: 1px solid var(--dsw-alias-border-l1);\n}\n\n.-cerbur-clutch-dsh-worktree-title {\n min-width: 0;\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 14px;\n font-weight: 600;\n opacity: 1;\n visibility: visible;\n transition:\n opacity 120ms var(--ds-ease-in-out),\n transform 180ms var(--ds-ease-in-out),\n visibility 0s linear;\n}\n\n.-cerbur-clutch-dsh-worktree-titleHidden {\n flex: 0 0 0px;\n max-width: 0;\n opacity: 0;\n transform: translateX(-4px);\n visibility: hidden;\n pointer-events: none;\n transition-delay: 0s, 0s, 180ms;\n}\n\n.-cerbur-clutch-dsh-worktree-closeButton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n width: 28px;\n height: 28px;\n border: 0;\n border-radius: 7px;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n font: inherit;\n font-size: 16px;\n line-height: 1;\n}\n\n.-cerbur-clutch-dsh-worktree-closeButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-modeButton[data-active='true'] {\n color: var(--dsw-alias-label-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-workspacePicker {\n display: block;\n width: calc(100% - 20px);\n margin: 6px 10px 8px;\n padding: 6px 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 7px;\n background: var(--dsw-alias-button-elevated-fill);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceLabel {\n display: block;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-scrollFrame {\n position: relative;\n min-height: 0;\n flex: 1;\n}\n\n.-cerbur-clutch-dsh-worktree-content {\n height: 100%;\n box-sizing: border-box;\n overflow: auto;\n padding: 0 10px 12px;\n scrollbar-width: none;\n}\n\n.-cerbur-clutch-dsh-worktree-content::-webkit-scrollbar {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-scrollContent {\n min-width: 0;\n display: flow-root;\n}\n\n/* The themed thumb floats in the existing right inset. Native scrolling\n stays on .-cerbur-clutch-dsh-worktree-content; OS scrollbar preferences cannot shift the rows. */\n.-cerbur-clutch-dsh-worktree-overlayScrollbar {\n position: absolute;\n top: 0;\n right: 2px;\n bottom: 0;\n width: 5px;\n touch-action: none;\n user-select: none;\n}\n\n.-cerbur-clutch-dsh-worktree-scrollbarThumb {\n width: 100%;\n border-radius: 999px;\n background: var(--dsw-alias-scrollbar-bg-l2);\n opacity: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-scrollFrame:hover .-cerbur-clutch-dsh-worktree-scrollbarThumb,\n.-cerbur-clutch-dsh-worktree-scrollFrame:focus-within .-cerbur-clutch-dsh-worktree-scrollbarThumb,\n.-cerbur-clutch-dsh-worktree-overlayScrollbar[data-dragging='true'] .-cerbur-clutch-dsh-worktree-scrollbarThumb {\n opacity: 1;\n}\n\n.-cerbur-clutch-dsh-worktree-scrollbarThumb:hover,\n.-cerbur-clutch-dsh-worktree-overlayScrollbar[data-dragging='true'] .-cerbur-clutch-dsh-worktree-scrollbarThumb {\n background: var(--dsw-alias-scrollbar-hover-l2);\n}\n\n.-cerbur-clutch-dsh-worktree-content:focus-visible {\n outline: 2px solid var(--dsw-alias-border-l3);\n outline-offset: -2px;\n}\n\n.-cerbur-clutch-dsh-worktree-error {\n margin: 12px 0 0;\n padding: 8px;\n border: 1px solid var(--dsw-alias-state-error-primary);\n border-radius: 7px;\n}\n\n.-cerbur-clutch-dsh-worktree-notice {\n margin: 12px 0 0;\n padding: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 7px;\n background: var(--dsw-alias-button-elevated-fill);\n}\n\n.-cerbur-clutch-dsh-worktree-retryButton,\n.-cerbur-clutch-dsh-worktree-actionButton {\n border: 0;\n border-radius: 6px;\n background: var(--dsw-alias-button-elevated-fill);\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n font: inherit;\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-retryButton,\n.-cerbur-clutch-dsh-worktree-actionButton {\n width: 100%;\n padding: 6px 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-recoveryActions {\n display: grid;\n gap: 6px;\n margin-top: 6px;\n}\n\n.-cerbur-clutch-dsh-worktree-retryButton:disabled,\n.-cerbur-clutch-dsh-worktree-actionButton:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.-cerbur-clutch-dsh-worktree-actions {\n display: grid;\n gap: 6px;\n margin-top: 10px;\n padding: 8px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 7px;\n}\n\n.-cerbur-clutch-dsh-worktree-actionSelect {\n min-width: 0;\n padding: 5px 6px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: var(--dsw-alias-button-elevated-fill);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-section {\n margin: 12px 0 0;\n}\n\n.-cerbur-clutch-dsh-worktree-sectionTitle {\n margin: 0 2px 4px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n}\n\n.-cerbur-clutch-dsh-worktree-empty,\n.-cerbur-clutch-dsh-worktree-message {\n margin: 0;\n padding: 8px 4px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 12px;\n line-height: 18px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitReadiness {\n display: grid;\n gap: 4px;\n}\n\n.-cerbur-clutch-dsh-worktree-commandBlock {\n margin: 6px 0 0;\n padding: 8px;\n overflow-x: auto;\n border-radius: 6px;\n background: var(--dsw-alias-button-elevated-fill);\n color: var(--dsw-alias-label-secondary);\n font:\n 11px/16px ui-monospace,\n SFMono-Regular,\n Menlo,\n monospace;\n white-space: pre-wrap;\n}\n\n.-cerbur-clutch-dsh-worktree-message[data-error='true'] {\n color: var(--dsw-alias-state-error-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-worktree,\n.-cerbur-clutch-dsh-worktree-session {\n display: flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n box-sizing: border-box;\n border: 0;\n border-radius: 7px;\n padding: 6px 8px;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 12px;\n text-align: left;\n}\n\n.-cerbur-clutch-dsh-worktree-worktree {\n cursor: default;\n}\n\n.-cerbur-clutch-dsh-worktree-session {\n cursor: pointer;\n}\n\n.-cerbur-clutch-dsh-worktree-worktree:hover,\n.-cerbur-clutch-dsh-worktree-session:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeLabel,\n.-cerbur-clutch-dsh-worktree-sessionLabel {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-status {\n flex: none;\n margin-left: auto;\n padding-left: 8px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-searchSlot {\n flex: none;\n max-width: 28px;\n min-width: 0;\n display: flex;\n align-items: center;\n margin-left: auto;\n box-sizing: border-box;\n transition:\n flex 180ms var(--ds-ease-in-out),\n max-width 180ms var(--ds-ease-in-out);\n}\n\n.-cerbur-clutch-dsh-worktree-searchSlotExpanded {\n flex: 1;\n max-width: 100%;\n}\n\n.-cerbur-clutch-dsh-worktree-headerActions {\n flex: none;\n display: flex;\n align-items: center;\n gap: 4px;\n margin-left: 0;\n opacity: 1;\n visibility: visible;\n transition:\n opacity 120ms var(--ds-ease-in-out),\n transform 180ms var(--ds-ease-in-out),\n visibility 0s linear;\n}\n\n.-cerbur-clutch-dsh-worktree-headerActionsHidden {\n flex: 0 0 0px;\n max-width: 0;\n margin-left: 0;\n opacity: 0;\n transform: translateX(4px);\n visibility: hidden;\n pointer-events: none;\n transition-delay: 0s, 0s, 180ms;\n}\n\n.-cerbur-clutch-dsh-worktree-search {\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\n height: 28px;\n box-sizing: border-box;\n border-radius: 6px;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n transition:\n background 180ms var(--ds-ease-in-out),\n box-shadow 180ms var(--ds-ease-in-out),\n color 180ms var(--ds-ease-in-out);\n}\n\n.-cerbur-clutch-dsh-worktree-searchExpanded {\n background: var(--dsw-alias-interactive-bg-subtle);\n box-shadow: inset 0 0 0 1px var(--dsw-alias-border-l2);\n}\n\n.-cerbur-clutch-dsh-worktree-searchExpanded:focus-within {\n box-shadow: inset 0 0 0 1px #3b82f6;\n}\n\n.-cerbur-clutch-dsh-worktree-searchButton {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n border-radius: 50%;\n padding: 0;\n background: transparent;\n cursor: pointer;\n color: inherit;\n}\n\n.-cerbur-clutch-dsh-worktree-searchButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-searchExpanded .-cerbur-clutch-dsh-worktree-searchButton:hover {\n background: transparent;\n}\n\n.-cerbur-clutch-dsh-worktree-searchInput {\n flex: 1;\n width: 0;\n min-width: 0;\n box-sizing: border-box;\n border: none;\n outline: none;\n background: transparent;\n opacity: 0;\n pointer-events: none;\n font: inherit;\n font-size: 13px;\n line-height: 18px;\n color: var(--dsw-alias-label-primary);\n transition: opacity 120ms var(--ds-ease-in-out);\n}\n\n.-cerbur-clutch-dsh-worktree-searchExpanded .-cerbur-clutch-dsh-worktree-searchInput {\n margin-left: -2px;\n opacity: 1;\n pointer-events: auto;\n}\n\n.-cerbur-clutch-dsh-worktree-searchInput::placeholder {\n color: var(--dsw-alias-label-tertiary);\n}\n\n.-cerbur-clutch-dsh-worktree-clearButton {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border: none;\n border-radius: 50%;\n padding: 0;\n background: transparent;\n cursor: pointer;\n color: var(--dsw-alias-label-secondary);\n}\n\n.-cerbur-clutch-dsh-worktree-clearButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-actionSelect:focus,\n.-cerbur-clutch-dsh-worktree-worktreeImportSelect:focus {\n border-color: #3b82f6;\n}\n\n.-cerbur-clutch-dsh-worktree-iconButton {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: 0;\n border-radius: 7px;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n font: inherit;\n font-size: 20px;\n line-height: 1;\n}\n\n.-cerbur-clutch-dsh-worktree-iconButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceList {\n position: relative;\n min-width: 0;\n min-height: 0;\n display: grid;\n gap: 4px;\n overflow-x: hidden;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceGroup {\n min-width: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow,\n.-cerbur-clutch-dsh-worktree-worktreeRow {\n position: relative;\n display: flex;\n align-items: center;\n min-width: 0;\n min-height: 36px;\n box-sizing: border-box;\n border-radius: 8px;\n padding: 3px 4px;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow:hover,\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow .-cerbur-clutch-dsh-worktree-workspaceDisclosure {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow:hover .-cerbur-clutch-dsh-worktree-workspaceDisclosure,\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-workspaceDisclosure {\n display: inline-flex;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow:hover .-cerbur-clutch-dsh-worktree-workspaceIcon,\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-workspaceIcon {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-worktreeDisclosure {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover .-cerbur-clutch-dsh-worktree-worktreeDisclosure,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-worktreeDisclosure {\n display: inline-flex;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover .-cerbur-clutch-dsh-worktree-worktreeIcon,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-worktreeIcon {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-disclosureButton {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 28px;\n border: 0;\n border-radius: 6px;\n padding: 0;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n font: inherit;\n font-size: 17px;\n line-height: 1;\n}\n\n.-cerbur-clutch-dsh-worktree-disclosureButton > svg {\n display: block;\n}\n\n.-cerbur-clutch-dsh-worktree-disclosureArrow {\n transition: transform 150ms var(--ds-ease-in-out);\n}\n\n.-cerbur-clutch-dsh-worktree-disclosureButton[aria-expanded='true'] .-cerbur-clutch-dsh-worktree-disclosureArrow {\n transform: rotate(90deg);\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceDisclosure,\n.-cerbur-clutch-dsh-worktree-worktreeDisclosure {\n color: var(--dsw-alias-label-caption);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .-cerbur-clutch-dsh-worktree-disclosureArrow {\n transition: none;\n }\n}\n\n.-cerbur-clutch-dsh-worktree-disclosureButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceIcon,\n.-cerbur-clutch-dsh-worktree-worktreeIcon {\n flex: none;\n width: 24px;\n color: var(--dsw-alias-label-secondary);\n font-size: 20px;\n line-height: 1;\n text-align: center;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeIcon[data-worktree-state='done'] {\n color: var(--dsw-alias-state-success-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeIcon[data-worktree-state='warning'] {\n color: var(--dsw-alias-state-warn-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeIcon[data-worktree-state='error'] {\n color: var(--dsw-alias-state-error-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeStateLabel {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n overflow: hidden;\n border: 0;\n padding: 0;\n clip: rect(0 0 0 0);\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceIcon {\n color: var(--dsw-alias-label-tertiary);\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceIcon[data-workspace-active='true'] {\n color: var(--dsw-alias-state-business-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceTitle,\n.-cerbur-clutch-dsh-worktree-worktreeLabel {\n min-width: 0;\n overflow: hidden;\n flex: 1;\n padding: 0 6px;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 14px;\n font-weight: 400;\n line-height: 20px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-main-group='true'] .-cerbur-clutch-dsh-worktree-worktreeLabel {\n font-weight: 600;\n}\n\n/* Native title reveal: the span clips its own text and scrolls only while\n hovered. Activity alone keeps the resting ellipsis. */\n@media (hover: hover) {\n .-cerbur-clutch-dsh-worktree-worktreeRow:hover .-cerbur-clutch-dsh-worktree-worktreeLabel,\n .-cerbur-clutch-dsh-worktree-treeSessionRow:hover .-cerbur-clutch-dsh-worktree-sessionLabel {\n text-overflow: clip;\n }\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeLabel[data-scrolled],\n.-cerbur-clutch-dsh-worktree-sessionLabel[data-scrolled] {\n mask-image: linear-gradient(to right, transparent, #000 12px);\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeLabel[data-clipped],\n.-cerbur-clutch-dsh-worktree-sessionLabel[data-clipped] {\n mask-image: linear-gradient(to left, transparent, #000 12px);\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeLabel[data-scrolled][data-clipped],\n.-cerbur-clutch-dsh-worktree-sessionLabel[data-scrolled][data-clipped] {\n mask-image: linear-gradient(\n to right,\n transparent,\n #000 12px,\n #000 calc(100% - 12px),\n transparent\n );\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeHoverTitle {\n color: var(--dsw-static-neutral-bluish-00);\n font-size: 14px;\n line-height: 20px;\n overflow-wrap: anywhere;\n}\n\n/* Native Session hover card: full title, relative time, and current status. */\n.-cerbur-clutch-dsh-worktree-sessionHoverContent {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionHoverTitle {\n color: #FFFFFF;\n font-size: 14px;\n line-height: 20px;\n overflow-wrap: break-word;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionHoverTime {\n color: #CFD3D6;\n font-size: 12px;\n line-height: 16px;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionHoverStatus {\n display: flex;\n align-items: center;\n gap: 8px;\n color: #ADB2B8;\n font-size: 12px;\n line-height: 20px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeActionSlot,\n.-cerbur-clutch-dsh-worktree-workspaceActions {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: flex-end;\n height: 28px;\n margin-left: auto;\n}\n\n/* Workspace rows retain the native fixed action column. */\n.-cerbur-clutch-dsh-worktree-workspaceActions {\n flex: 0 0 64px;\n width: 64px;\n}\n\n/* Group actions do not reserve space until their row needs to show them. */\n.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-treeActionSlot {\n min-width: 0;\n flex: 0 0 0;\n width: 0;\n gap: 4px;\n}\n\n/* Keep the 28px activity indicator plus a 4px label gap while collapsed. */\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true'] .-cerbur-clutch-dsh-worktree-treeActionSlot {\n flex: 0 0 32px;\n width: 32px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover .-cerbur-clutch-dsh-worktree-treeActionSlot,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-treeActionSlot,\n.-cerbur-clutch-dsh-worktree-worktreeRow:focus-within .-cerbur-clutch-dsh-worktree-treeActionSlot {\n flex: 0 0 auto;\n width: auto;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceActions > .-cerbur-clutch-dsh-worktree-menuAction {\n position: absolute;\n top: 0;\n right: 32px;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceActions > .-cerbur-clutch-dsh-worktree-iconButton:last-child {\n position: absolute;\n top: 0;\n right: 0;\n visibility: hidden;\n}\n\n/* Worktree actions flow naturally so the rail matches the controls that exist. */\n.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-dashboardAction,\n.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-menuAction,\n.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child {\n position: static;\n opacity: 0;\n pointer-events: none;\n visibility: visible;\n}\n\n.-cerbur-clutch-dsh-worktree-groupActivity {\n position: absolute;\n top: 0;\n right: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n visibility: hidden;\n pointer-events: none;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-group-activity='true'] .-cerbur-clutch-dsh-worktree-groupActivity,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true'] .-cerbur-clutch-dsh-worktree-groupActivity {\n visibility: visible;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-group-activity='true']:hover .-cerbur-clutch-dsh-worktree-groupActivity,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true']:hover .-cerbur-clutch-dsh-worktree-groupActivity,\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-group-activity='true'][data-menu-open='true'] .-cerbur-clutch-dsh-worktree-groupActivity,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true'][data-menu-open='true'] .-cerbur-clutch-dsh-worktree-groupActivity,\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-group-activity='true']:focus-within .-cerbur-clutch-dsh-worktree-groupActivity,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true']:focus-within .-cerbur-clutch-dsh-worktree-groupActivity {\n visibility: hidden;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-group-activity='true'] .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true'] .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child {\n visibility: hidden;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-group-activity='true']:hover .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true']:hover .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child,\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-group-activity='true'][data-menu-open='true']\n .-cerbur-clutch-dsh-worktree-treeActionSlot\n > .-cerbur-clutch-dsh-worktree-iconButton:last-child,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true'][data-menu-open='true']\n .-cerbur-clutch-dsh-worktree-treeActionSlot\n > .-cerbur-clutch-dsh-worktree-iconButton:last-child,\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-group-activity='true']:focus-within .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-group-activity='true']:focus-within .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child {\n visibility: visible;\n}\n\n.-cerbur-clutch-dsh-worktree-dashboardAction {\n display: inline-flex;\n flex: 0 0 28px;\n width: 28px;\n height: 28px;\n visibility: hidden;\n}\n\n.-cerbur-clutch-dsh-worktree-menuAction {\n display: inline-flex;\n flex: 0 0 28px;\n width: 28px;\n height: 28px;\n visibility: hidden;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow:hover .-cerbur-clutch-dsh-worktree-menuAction,\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-menuAction,\n.-cerbur-clutch-dsh-worktree-workspaceRow:focus-within .-cerbur-clutch-dsh-worktree-menuAction,\n.-cerbur-clutch-dsh-worktree-workspaceRow:hover [data-add-worktree],\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-menu-open='true'] [data-add-worktree],\n.-cerbur-clutch-dsh-worktree-workspaceRow:focus-within [data-add-worktree] {\n visibility: visible;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-dashboardAction,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-dashboardAction,\n.-cerbur-clutch-dsh-worktree-worktreeRow:focus-within .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-dashboardAction,\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-menuAction,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-menuAction,\n.-cerbur-clutch-dsh-worktree-worktreeRow:focus-within .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-menuAction,\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child,\n.-cerbur-clutch-dsh-worktree-worktreeRow:focus-within .-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child {\n opacity: 1;\n pointer-events: auto;\n visibility: visible;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow.-cerbur-clutch-dsh-worktree-dropBefore::before,\n.-cerbur-clutch-dsh-worktree-workspaceRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n position: absolute;\n right: 4px;\n left: 4px;\n height: 2px;\n border-radius: 2px;\n background: var(--dsw-alias-brand-primary);\n content: '';\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow.-cerbur-clutch-dsh-worktree-dropBefore::before {\n top: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n bottom: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow.-cerbur-clutch-dsh-worktree-dropBefore::before,\n.-cerbur-clutch-dsh-worktree-worktreeRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n position: absolute;\n right: 4px;\n left: 4px;\n height: 2px;\n border-radius: 2px;\n background: var(--dsw-alias-brand-primary);\n content: '';\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow.-cerbur-clutch-dsh-worktree-dropBefore::before {\n top: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n bottom: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeChildren {\n margin-left: 16px;\n padding: 2px 0 5px 12px;\n border-left: 1px solid var(--dsw-alias-border-l1);\n}\n\n.-cerbur-clutch-dsh-worktree-groupLabel {\n padding: 6px 8px 3px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n}\n\n.-cerbur-clutch-dsh-worktree-groupHeader {\n display: flex;\n align-items: center;\n min-height: 34px;\n padding-right: 4px;\n}\n\n.-cerbur-clutch-dsh-worktree-groupHeader .-cerbur-clutch-dsh-worktree-groupLabel {\n flex: 1;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeGroup {\n margin-top: 2px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow {\n min-height: 34px;\n}\n\n/* Compact the Worktree leading slots to make room for its third action. */\n.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-worktreeIcon,\n.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-disclosureButton {\n width: 20px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow {\n position: relative;\n display: flex;\n align-items: center;\n width: calc(100% - 20px);\n margin-left: 20px;\n min-width: 0;\n min-height: 31px;\n box-sizing: border-box;\n border-radius: 7px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow:hover,\n.-cerbur-clutch-dsh-worktree-treeSessionRow[data-menu-open='true'] {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow[data-session-current='true'] {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow[data-session-current='true'] .-cerbur-clutch-dsh-worktree-treeSessionContent {\n font-weight: 600;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow.-cerbur-clutch-dsh-worktree-dropBefore::before,\n.-cerbur-clutch-dsh-worktree-treeSessionRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n position: absolute;\n right: 4px;\n left: 4px;\n height: 2px;\n border-radius: 2px;\n background: var(--dsw-alias-brand-primary);\n content: '';\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow.-cerbur-clutch-dsh-worktree-dropBefore::before {\n top: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n bottom: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionContent {\n display: flex;\n align-items: center;\n flex: 1;\n width: 0;\n min-width: 0;\n min-height: 31px;\n box-sizing: border-box;\n border: 0;\n border-radius: 7px;\n padding: 4px 4px;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n font: inherit;\n font-size: 14px;\n font-weight: 400;\n line-height: 20px;\n text-align: left;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionContent:hover {\n background: transparent;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionTrailing {\n position: relative;\n display: inline-flex;\n flex: 0 0 52px;\n align-items: center;\n justify-content: flex-end;\n width: 52px;\n height: 28px;\n margin-left: auto;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionMeta,\n.-cerbur-clutch-dsh-worktree-rowActions {\n position: absolute;\n inset: 0;\n display: inline-flex;\n align-items: center;\n justify-content: flex-end;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionMeta {\n color: var(--dsw-alias-label-tertiary);\n pointer-events: none;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionStatus {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionTime {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n margin-right: 4px;\n font-size: 12px;\n line-height: 20px;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionOverflowButton {\n display: block;\n width: calc(100% - 24px);\n margin: 2px 0 4px 24px;\n padding: 4px 8px;\n border: 0;\n border-radius: 6px;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n font: inherit;\n font-size: 12px;\n font-weight: 400;\n line-height: 20px;\n text-align: left;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionOverflowButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-rowActions {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow:hover .-cerbur-clutch-dsh-worktree-sessionMeta,\n.-cerbur-clutch-dsh-worktree-treeSessionRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-sessionMeta,\n.-cerbur-clutch-dsh-worktree-sessionTrailing:focus-within .-cerbur-clutch-dsh-worktree-sessionMeta {\n visibility: hidden;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow:hover .-cerbur-clutch-dsh-worktree-rowActions,\n.-cerbur-clutch-dsh-worktree-treeSessionRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-rowActions,\n.-cerbur-clutch-dsh-worktree-sessionTrailing:focus-within .-cerbur-clutch-dsh-worktree-rowActions {\n display: inline-flex;\n}\n\n.-cerbur-clutch-dsh-worktree-renameInput {\n width: 100%;\n}\n\n.-cerbur-clutch-dsh-worktree-renameError {\n margin: 8px 0 0;\n color: var(--dsw-alias-state-error-primary);\n font-size: 13px;\n line-height: 20px;\n}\n\n.-cerbur-clutch-dsh-worktree-emptyNested {\n margin: 0;\n padding: 4px 8px 5px 28px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-archivedGroup {\n margin-top: 4px;\n}\n\n.-cerbur-clutch-dsh-worktree-modalField {\n display: grid;\n gap: 5px;\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n}\n.-cerbur-clutch-dsh-worktree-worktreeHoverDetails {\n max-width: 360px;\n white-space: normal;\n overflow-wrap: anywhere;\n line-height: 1.5;\n}\n";
2000
+ const styleId$5 = "@cerbur/clutch-dsh-worktree/worktree.css";
1775
2001
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@cerbur/clutch-dsh-worktree/worktree.css\"]") === null) {
1776
2002
  const tag = document.createElement("style");
1777
2003
  tag.dataset.plugin = "@cerbur/clutch-dsh-worktree";
1778
- tag.dataset.pluginCss = styleId$4;
1779
- tag.textContent = css$4;
2004
+ tag.dataset.pluginCss = styleId$5;
2005
+ tag.textContent = css$5;
1780
2006
  document.head.appendChild(tag);
1781
2007
  }
1782
2008
  var worktree_css_default = {
@@ -1797,7 +2023,11 @@ window.__ModuleLoader__.load({
1797
2023
  "modeButton": "-cerbur-clutch-dsh-worktree-modeButton",
1798
2024
  "workspacePicker": "-cerbur-clutch-dsh-worktree-workspacePicker",
1799
2025
  "workspaceLabel": "-cerbur-clutch-dsh-worktree-workspaceLabel",
2026
+ "scrollFrame": "-cerbur-clutch-dsh-worktree-scrollFrame",
1800
2027
  "content": "-cerbur-clutch-dsh-worktree-content",
2028
+ "scrollContent": "-cerbur-clutch-dsh-worktree-scrollContent",
2029
+ "overlayScrollbar": "-cerbur-clutch-dsh-worktree-overlayScrollbar",
2030
+ "scrollbarThumb": "-cerbur-clutch-dsh-worktree-scrollbarThumb",
1801
2031
  "error": "-cerbur-clutch-dsh-worktree-error",
1802
2032
  "notice": "-cerbur-clutch-dsh-worktree-notice",
1803
2033
  "retryButton": "-cerbur-clutch-dsh-worktree-retryButton",
@@ -1835,8 +2065,10 @@ window.__ModuleLoader__.load({
1835
2065
  "worktreeDisclosure": "-cerbur-clutch-dsh-worktree-worktreeDisclosure",
1836
2066
  "worktreeIcon": "-cerbur-clutch-dsh-worktree-worktreeIcon",
1837
2067
  "disclosureButton": "-cerbur-clutch-dsh-worktree-disclosureButton",
2068
+ "disclosureArrow": "-cerbur-clutch-dsh-worktree-disclosureArrow",
1838
2069
  "worktreeStateLabel": "-cerbur-clutch-dsh-worktree-worktreeStateLabel",
1839
2070
  "workspaceTitle": "-cerbur-clutch-dsh-worktree-workspaceTitle",
2071
+ "treeSessionRow": "-cerbur-clutch-dsh-worktree-treeSessionRow",
1840
2072
  "worktreeHoverTitle": "-cerbur-clutch-dsh-worktree-worktreeHoverTitle",
1841
2073
  "sessionHoverContent": "-cerbur-clutch-dsh-worktree-sessionHoverContent",
1842
2074
  "sessionHoverTitle": "-cerbur-clutch-dsh-worktree-sessionHoverTitle",
@@ -1853,7 +2085,6 @@ window.__ModuleLoader__.load({
1853
2085
  "groupLabel": "-cerbur-clutch-dsh-worktree-groupLabel",
1854
2086
  "groupHeader": "-cerbur-clutch-dsh-worktree-groupHeader",
1855
2087
  "worktreeGroup": "-cerbur-clutch-dsh-worktree-worktreeGroup",
1856
- "treeSessionRow": "-cerbur-clutch-dsh-worktree-treeSessionRow",
1857
2088
  "treeSessionContent": "-cerbur-clutch-dsh-worktree-treeSessionContent",
1858
2089
  "sessionTrailing": "-cerbur-clutch-dsh-worktree-sessionTrailing",
1859
2090
  "sessionMeta": "-cerbur-clutch-dsh-worktree-sessionMeta",
@@ -1866,8 +2097,7 @@ window.__ModuleLoader__.load({
1866
2097
  "emptyNested": "-cerbur-clutch-dsh-worktree-emptyNested",
1867
2098
  "archivedGroup": "-cerbur-clutch-dsh-worktree-archivedGroup",
1868
2099
  "modalField": "-cerbur-clutch-dsh-worktree-modalField",
1869
- "worktreeHoverDetails": "-cerbur-clutch-dsh-worktree-worktreeHoverDetails",
1870
- "notificationDetails": "-cerbur-clutch-dsh-worktree-notificationDetails"
2100
+ "worktreeHoverDetails": "-cerbur-clutch-dsh-worktree-worktreeHoverDetails"
1871
2101
  };
1872
2102
  //#endregion
1873
2103
  //#region lib/client/view/WorktreeModeAction.js
@@ -1945,14 +2175,14 @@ window.__ModuleLoader__.load({
1945
2175
  });
1946
2176
  }
1947
2177
  //#endregion
1948
- //#region \0clutch-dsh-worktree-css:/Users/yuancheng/.dsh/clutch-dsh-worktree/worktree/wt_63cf54e5ec74/packages/clutch-dsh-worktree/src/client/dashboard/dashboard-header-action.css.mjs
1949
- const css$3 = "/* Match the native 28px circular Session-header utility controls. */\n.-cerbur-clutch-dsh-worktree-headerDashboardButton {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 6px;\n color: var(--dsw-alias-label-secondary);\n background: transparent;\n border: none;\n border-radius: 28px;\n cursor: pointer;\n}\n\n.-cerbur-clutch-dsh-worktree-headerDashboardButton svg {\n width: 16px;\n height: 16px;\n}\n\n.-cerbur-clutch-dsh-worktree-headerDashboardButton:hover,\n.-cerbur-clutch-dsh-worktree-headerDashboardButton:focus-visible {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n";
1950
- const styleId$3 = "@cerbur/clutch-dsh-worktree/dashboard-header-action.css";
2178
+ //#region \0clutch-dsh-worktree-css:/Users/yuancheng/.dsh/clutch-dsh-worktree/worktree/wt_ece6fafadbd1/packages/clutch-dsh-worktree/src/client/dashboard/dashboard-header-action.css.mjs
2179
+ const css$4 = "/* Match the native 28px circular Session-header utility controls. */\n.-cerbur-clutch-dsh-worktree-headerDashboardButton {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 6px;\n color: var(--dsw-alias-label-secondary);\n background: transparent;\n border: none;\n border-radius: 28px;\n cursor: pointer;\n}\n\n.-cerbur-clutch-dsh-worktree-headerDashboardButton svg {\n width: 16px;\n height: 16px;\n}\n\n.-cerbur-clutch-dsh-worktree-headerDashboardButton:hover,\n.-cerbur-clutch-dsh-worktree-headerDashboardButton:focus-visible {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n";
2180
+ const styleId$4 = "@cerbur/clutch-dsh-worktree/dashboard-header-action.css";
1951
2181
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@cerbur/clutch-dsh-worktree/dashboard-header-action.css\"]") === null) {
1952
2182
  const tag = document.createElement("style");
1953
2183
  tag.dataset.plugin = "@cerbur/clutch-dsh-worktree";
1954
- tag.dataset.pluginCss = styleId$3;
1955
- tag.textContent = css$3;
2184
+ tag.dataset.pluginCss = styleId$4;
2185
+ tag.textContent = css$4;
1956
2186
  document.head.appendChild(tag);
1957
2187
  }
1958
2188
  var dashboard_header_action_css_default = { "headerDashboardButton": "-cerbur-clutch-dsh-worktree-headerDashboardButton" };
@@ -2136,13 +2366,203 @@ window.__ModuleLoader__.load({
2136
2366
  }) });
2137
2367
  }
2138
2368
  //#endregion
2369
+ //#region lib/contract/tool-settings.js
2370
+ /** Browser-safe capability identities shared by preferences and the Agent catalog. */
2371
+ const WORKTREE_TOOL_IDS = [
2372
+ "clutch_new_worktree",
2373
+ "clutch_list_worktrees",
2374
+ "clutch_span_worktree",
2375
+ "clutch_list_models",
2376
+ "clutch_list_sessions",
2377
+ "clutch_send_message"
2378
+ ];
2379
+ //#endregion
2380
+ //#region lib/contract/windows-path.js
2381
+ /**
2382
+ * Browser-safe Windows path identity helpers. They intentionally do not touch
2383
+ * the filesystem; Provider adds physical stat/realpath checks where it has
2384
+ * access to Node APIs.
2385
+ */
2386
+ const EXTENDED_PATH_PREFIX = "//?/";
2387
+ const EXTENDED_UNC_PREFIX = "//?/UNC/";
2388
+ function isWindowsPath(value) {
2389
+ return /^[A-Za-z]:[\\/]/u.test(value) || value.startsWith("\\\\") || /^\/\/\?(?:\/|\\)/u.test(value);
2390
+ }
2391
+ /** Strip only the extended drive/UNC prefixes supported by the browser boundary. */
2392
+ function stripExtendedWindowsPrefix(value) {
2393
+ const normalized = value.replaceAll("\\", "/");
2394
+ const normalizedUncPrefix = EXTENDED_UNC_PREFIX.toLowerCase();
2395
+ if (normalized.toLowerCase().startsWith(normalizedUncPrefix)) return "//" + normalized.slice(8);
2396
+ if (normalized.startsWith(EXTENDED_PATH_PREFIX)) {
2397
+ const drivePath = normalized.slice(4);
2398
+ if (/^[A-Za-z]:\//u.test(drivePath)) return drivePath;
2399
+ }
2400
+ return value;
2401
+ }
2402
+ function normalizeWindowsPath(value) {
2403
+ let normalized = stripExtendedWindowsPrefix(value).replaceAll("\\", "/");
2404
+ const unc = normalized.startsWith("//");
2405
+ normalized = normalized.replace(/\/{2,}/gu, "/");
2406
+ if (unc && normalized.startsWith("/")) normalized = "/" + normalized;
2407
+ if (normalized.length > 3) normalized = normalized.replace(/\/+$/u, "");
2408
+ return normalized.toLowerCase();
2409
+ }
2410
+ function sameWindowsPath(left, right) {
2411
+ return (isWindowsPath(left) || isWindowsPath(right)) && normalizeWindowsPath(left) === normalizeWindowsPath(right);
2412
+ }
2413
+ Object.freeze([
2414
+ "WORKSPACE_NOT_FOUND",
2415
+ "WORKSPACE_ROOT_MISSING",
2416
+ "WORKSPACE_NOT_GIT_REPOSITORY",
2417
+ "GIT_NOT_INSTALLED",
2418
+ "WORKTREE_REQUIRES_INITIAL_COMMIT",
2419
+ "WORKTREE_BRANCH_CONFLICT",
2420
+ "WORKTREE_NOT_FOUND",
2421
+ "WORKTREE_ORDER_INVALID",
2422
+ "WORKTREE_REMOVED",
2423
+ "WORKTREE_IMPORT_INVALID",
2424
+ "WORKTREE_ALREADY_MANAGED",
2425
+ "SESSION_NOT_FOUND",
2426
+ "SESSION_CWD_MISMATCH",
2427
+ "SESSION_ALREADY_BOUND",
2428
+ "SIDECAR_UNAVAILABLE",
2429
+ "SIDECAR_CORRUPT",
2430
+ "SIDECAR_SYNC_REQUIRED",
2431
+ "GIT_OPERATION_FAILED",
2432
+ "WORKTREE_MUTATION_BUSY",
2433
+ "WORKTREE_STATE_CONFLICT",
2434
+ "WORKTREE_RECOVERY_REQUIRED",
2435
+ "WORKTREE_IDENTITY_CHANGED",
2436
+ "WORKTREE_PERMISSION_BINDING_REQUIRED",
2437
+ "WORKTREE_SESSION_BUSY",
2438
+ "WORKTREE_ACTIVITY_UNAVAILABLE"
2439
+ ]);
2440
+ /** Stable synthetic commit id used for the current uncommitted working tree entry. */
2441
+ const WORKTREE_GIT_WORKING_TREE = "working-tree";
2442
+ /**
2443
+ * Git object-name guard shared by the Contract, Provider, Manage and Client
2444
+ * seams so commit-SHA validation cannot drift between layers. SHA-1 and SHA-256
2445
+ * repository formats are both accepted.
2446
+ */
2447
+ const WORKTREE_GIT_COMMIT_PATTERN = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/iu;
2448
+ /** True when the value is a full-length Git commit SHA. */
2449
+ function isWorktreeGitCommit(value) {
2450
+ return typeof value === "string" && WORKTREE_GIT_COMMIT_PATTERN.test(value);
2451
+ }
2452
+ /** Git identity and disk lifecycle always target the complete checkout. Browser-safe. */
2453
+ function gitWorktreeRoot(record) {
2454
+ return record.gitRootPath ?? record.absolutePath;
2455
+ }
2456
+ Object.freeze([
2457
+ "getToolSettings",
2458
+ "updateToolSettings",
2459
+ "watchToolChanges",
2460
+ "getWorktreeInstructions",
2461
+ "updateWorktreeInstructions",
2462
+ "updateWorktreeBaseBranch",
2463
+ "listWorktrees",
2464
+ "listWorktreeCommits",
2465
+ "listWorktreeCommitFiles",
2466
+ "getWorktreeCommitFileDiff",
2467
+ "listImportCandidates",
2468
+ "listBranches",
2469
+ "createWorktree",
2470
+ "importWorktree",
2471
+ "removeWorktree",
2472
+ "unarchiveWorktree",
2473
+ "cleanWorktree",
2474
+ "adoptWorktreeBranch",
2475
+ "recoverWorktrees",
2476
+ "forgetWorktree",
2477
+ "insertWorktreeBefore",
2478
+ "listBindings",
2479
+ "bindSession",
2480
+ "ensureWorktreePermission",
2481
+ "normalizeDetachedWorktreePermissions"
2482
+ ]);
2483
+ //#endregion
2484
+ //#region lib/client/surface/notification-queue.js
2485
+ /** Group a root Git failure without conflating unrelated repositories or diagnostics. */
2486
+ function failureToastKey(error, scope) {
2487
+ const details = Object.fromEntries(Object.entries(error.details ?? {}).filter(([name]) => ![
2488
+ "gitArgs",
2489
+ "gitStdout",
2490
+ "operation"
2491
+ ].includes(name)));
2492
+ return JSON.stringify([
2493
+ scope,
2494
+ error.code,
2495
+ details,
2496
+ typeof details.gitStderr === "string" && details.gitStderr.length > 0 || details.gitTimedOut === true ? void 0 : error.message
2497
+ ]);
2498
+ }
2499
+ /** Resolved notices leave the queue; unchanged snapshots never announce twice. */
2500
+ function reconcileNotifications(state, notices) {
2501
+ const unique = [...new Map(notices.map((notice) => {
2502
+ const key = notice.toastKey ?? notice.key;
2503
+ return [key, {
2504
+ ...notice,
2505
+ key
2506
+ }];
2507
+ })).values()];
2508
+ const active = new Set(unique.map((notice) => notice.key));
2509
+ const seen = new Set(state.seen);
2510
+ const pending = state.pending.filter((notice) => active.has(notice.key));
2511
+ for (const notice of unique) if (!seen.has(notice.key)) pending.push(notice);
2512
+ const nextSeen = [...active];
2513
+ if (nextSeen.length === state.seen.length && nextSeen.every((key, index) => key === state.seen[index]) && pending.length === state.pending.length && pending.every((notice, index) => notice.key === state.pending[index]?.key)) return state;
2514
+ return {
2515
+ seen: nextSeen,
2516
+ pending
2517
+ };
2518
+ }
2519
+ //#endregion
2139
2520
  //#region lib/client/view/worktree-error-copy.js
2140
2521
  function detail(error, name) {
2141
2522
  const value = error.details?.[name];
2142
2523
  return typeof value === "string" ? value : "";
2143
2524
  }
2525
+ const DOMAIN_ERROR_COPY = {
2526
+ WORKSPACE_NOT_FOUND: "error.workspaceNotFound",
2527
+ WORKSPACE_ROOT_MISSING: "error.workspaceRootMissing",
2528
+ WORKSPACE_NOT_GIT_REPOSITORY: "error.workspaceNotGitRepository",
2529
+ GIT_NOT_INSTALLED: "error.gitNotInstalled",
2530
+ WORKTREE_REQUIRES_INITIAL_COMMIT: "error.initialCommitRequired",
2531
+ WORKTREE_BRANCH_CONFLICT: "error.branchConflict",
2532
+ WORKTREE_NOT_FOUND: "error.worktreeNotFound",
2533
+ WORKTREE_ORDER_INVALID: "error.worktreeOrderInvalid",
2534
+ WORKTREE_REMOVED: "error.worktreeRemoved",
2535
+ WORKTREE_IMPORT_INVALID: "error.worktreeImportInvalid",
2536
+ WORKTREE_ALREADY_MANAGED: "error.worktreeAlreadyManaged",
2537
+ SESSION_NOT_FOUND: "error.sessionNotFound",
2538
+ SESSION_CWD_MISMATCH: "error.sessionCwdMismatch",
2539
+ SESSION_ALREADY_BOUND: "error.sessionAlreadyBound",
2540
+ SIDECAR_UNAVAILABLE: "error.sidecarUnavailable",
2541
+ SIDECAR_CORRUPT: "error.sidecarCorrupt",
2542
+ SIDECAR_SYNC_REQUIRED: "error.sidecarSyncRequired",
2543
+ GIT_OPERATION_FAILED: "error.gitOperationFailed",
2544
+ WORKTREE_MUTATION_BUSY: "error.worktreeMutationBusy",
2545
+ WORKTREE_STATE_CONFLICT: "error.worktreeStateConflict",
2546
+ WORKTREE_RECOVERY_REQUIRED: "error.worktreeRecoveryRequired",
2547
+ WORKTREE_IDENTITY_CHANGED: "error.worktreeIdentityChanged",
2548
+ WORKTREE_PERMISSION_BINDING_REQUIRED: "error.permissionBindingRequired",
2549
+ WORKTREE_SESSION_BUSY: "error.worktreeSessionBusy",
2550
+ WORKTREE_ACTIVITY_UNAVAILABLE: "error.worktreeActivityUnavailable"
2551
+ };
2144
2552
  function reason(error, t) {
2145
- return error.message.length > 0 ? error.message : t("error.worktreeDataUnavailable");
2553
+ const causeCode = detail(error, "causeCode");
2554
+ const key = Object.hasOwn(DOMAIN_ERROR_COPY, causeCode) ? DOMAIN_ERROR_COPY[causeCode] : void 0;
2555
+ return key === void 0 ? t("error.worktreeDataUnavailable") : causeCode === "WORKSPACE_ROOT_MISSING" ? t(key, { rootPath: detail(error, "rootPath") }) : t(key);
2556
+ }
2557
+ /** Recognize actionable Git diagnostics without displaying untranslated stderr. */
2558
+ function gitErrorCopy(error) {
2559
+ if (error.details?.gitTimedOut === true) return "error.gitTimeout";
2560
+ const diagnostic = detail(error, "gitStderr");
2561
+ if (/contains modified or untracked files|uncommitted changes|local changes.*overwritten/i.test(diagnostic)) return "error.gitLocalChanges";
2562
+ if (/permission denied|access is denied|operation not permitted|dubious ownership/i.test(diagnostic)) return "error.gitAccessDenied";
2563
+ if (/is locked|cannot lock|unable to create.*\.lock|another git process/i.test(diagnostic)) return "error.gitLocked";
2564
+ if (/not a valid branch name|invalid branch name|not a valid ref/i.test(diagnostic)) return "error.gitInvalidBranch";
2565
+ return "error.gitOperationFailed";
2146
2566
  }
2147
2567
  function formatWorktreePermissionNotice(result, t) {
2148
2568
  switch (result.status) {
@@ -2153,13 +2573,16 @@ window.__ModuleLoader__.load({
2153
2573
  }
2154
2574
  }
2155
2575
  function formatWorktreeViewError(error, t) {
2576
+ if (error.code === "GIT_OPERATION_FAILED") return t(gitErrorCopy(error));
2577
+ const domainKey = Object.hasOwn(DOMAIN_ERROR_COPY, error.code) ? DOMAIN_ERROR_COPY[error.code] : void 0;
2578
+ if (domainKey !== void 0) return error.code === "WORKSPACE_ROOT_MISSING" ? t(domainKey, { rootPath: detail(error, "rootPath") }) : t(domainKey);
2156
2579
  switch (error.code) {
2157
2580
  case "CLIENT_DISPOSED": return t("error.connectionDisposed");
2158
- case "CONNECTION_CALL_FAILED": return t("error.connectionFailed", {
2159
- endpoint: detail(error, "endpoint"),
2160
- reason: reason(error, t)
2161
- });
2162
- case "WORKTREE_RPC_INVALID_RESULT": return t("error.invalidResult", { endpoint: detail(error, "endpoint") });
2581
+ case "gateway/service-unavailable":
2582
+ case "gateway/definition-unavailable":
2583
+ case "gateway/invocation-unavailable":
2584
+ case "CONNECTION_CALL_FAILED": return t("error.connectionFailed");
2585
+ case "WORKTREE_RPC_INVALID_RESULT": return t("error.invalidResult");
2163
2586
  case "WORKSPACE_ORDER_UNAVAILABLE": return t("error.workspaceOrderingUnavailable");
2164
2587
  case "SESSION_ORDER_UNAVAILABLE": return t("error.sessionOrderingUnavailable");
2165
2588
  case "WORKTREE_ORDER_UNAVAILABLE": return t("error.worktreeOrderingUnavailable");
@@ -2175,7 +2598,6 @@ window.__ModuleLoader__.load({
2175
2598
  case "WORKTREE_REGISTRATION_SESSION_UNAVAILABLE": return t("error.worktreeRegistrationSessionUnavailable");
2176
2599
  case "WORKSPACE_RENAME_UNAVAILABLE": return t("error.workspaceRenameUnavailable");
2177
2600
  case "WORKSPACE_DELETE_UNAVAILABLE": return t("error.workspaceDeleteUnavailable");
2178
- case "WORKSPACE_ROOT_MISSING": return t("error.workspaceRootMissing", { rootPath: detail(error, "rootPath") });
2179
2601
  case "SESSION_RENAME_UNAVAILABLE": return t("error.sessionRenameUnavailable");
2180
2602
  case "SESSION_BINDING_FAILED": return t("error.sessionBindingFailed", {
2181
2603
  sessionId: detail(error, "sessionId"),
@@ -2183,17 +2605,196 @@ window.__ModuleLoader__.load({
2183
2605
  });
2184
2606
  case "SESSION_ALREADY_BOUND": return t("error.sessionAlreadyBound");
2185
2607
  case "WORKTREE_PERMISSION_CONFIRMATION_REQUIRED": return t("error.worktreePermissionConfirmationRequired");
2186
- case "WORKTREE_PERMISSION_FAILED": return t("error.worktreePermissionFailed", { reason: reason(error, t) });
2608
+ case "WORKTREE_PERMISSION_FAILED": return t("error.worktreePermissionFailed");
2187
2609
  case "SESSION_LIST_NOT_READY": return t("error.sessionListNotReady");
2188
2610
  case "SESSION_FACTS_INCOMPLETE": return t("error.sessionFactsIncomplete");
2189
2611
  case "WORKTREE_SESSION_REPAIR_REQUIRED": return t("error.worktreeSessionRepairRequired");
2190
2612
  case "WORKTREE_SESSION_UNAVAILABLE": return t("error.worktreeSessionUnavailable");
2191
2613
  case "SESSION_ARCHIVED": return t("error.sessionArchived");
2192
2614
  case "GIT_NOT_INSTALLED": return t("error.gitNotInstalled");
2193
- default: return error.message.length > 0 ? error.message : t("error.worktreeDataUnavailable");
2615
+ default: return error.code === "WORKTREE_VIEW_FAILED" ? t("error.worktreeDataUnavailable") : t("error.unexpected", { code: error.code });
2194
2616
  }
2195
2617
  }
2196
2618
  //#endregion
2619
+ //#region lib/client/settings/diagnostics.js
2620
+ /** Browser-memory history. Unmount is not proof of recovery; stale actions are revoked. */
2621
+ function createWorktreeDiagnostics() {
2622
+ let snapshot = [];
2623
+ const sources = /* @__PURE__ */ new Map();
2624
+ const listeners = /* @__PURE__ */ new Set();
2625
+ const emit = () => listeners.forEach((listener) => listener());
2626
+ const limitHistory = () => {
2627
+ snapshot = [...snapshot.filter((entry) => entry.status !== "active").slice(-100), ...snapshot.filter((entry) => entry.status === "active")];
2628
+ };
2629
+ const retire = (source, status, keys = /* @__PURE__ */ new Set()) => {
2630
+ snapshot = snapshot.map((entry) => entry.source === source && entry.status === "active" && !keys.has(entry.key) ? {
2631
+ ...entry,
2632
+ status,
2633
+ actions: []
2634
+ } : entry);
2635
+ limitHistory();
2636
+ };
2637
+ return {
2638
+ getSnapshot: () => snapshot,
2639
+ subscribe: (listener) => {
2640
+ listeners.add(listener);
2641
+ return () => {
2642
+ listeners.delete(listener);
2643
+ };
2644
+ },
2645
+ publish(source, notices) {
2646
+ sources.set(source, notices);
2647
+ retire(source, "resolved", new Set(notices.map((notice) => notice.key)));
2648
+ for (const notice of notices) {
2649
+ const entry = {
2650
+ ...notice,
2651
+ source,
2652
+ status: "active",
2653
+ actions: (notice.actions ?? []).map((action) => ({
2654
+ ...action,
2655
+ onClick: () => {
2656
+ const current = sources.get(source)?.find((item) => item.key === notice.key)?.actions?.find((item) => item.label === action.label);
2657
+ if (current !== void 0 && !current.disabled) current.onClick();
2658
+ }
2659
+ }))
2660
+ };
2661
+ snapshot = [...snapshot.filter((item) => item.key !== notice.key), entry];
2662
+ }
2663
+ limitHistory();
2664
+ emit();
2665
+ },
2666
+ deactivate(source) {
2667
+ sources.delete(source);
2668
+ retire(source, "inactive");
2669
+ emit();
2670
+ },
2671
+ clearHistory() {
2672
+ snapshot = snapshot.filter((entry) => entry.status === "active");
2673
+ emit();
2674
+ },
2675
+ dispose() {
2676
+ sources.clear();
2677
+ snapshot = [];
2678
+ emit();
2679
+ }
2680
+ };
2681
+ }
2682
+ const worktreeDiagnostics = createWorktreeDiagnostics();
2683
+ //#endregion
2684
+ //#region lib/client/surface/components/NotificationToasts.js
2685
+ const Notifications = (0, react.createContext)(void 0);
2686
+ /** One queue for the list, dialogs and Dashboard; unmount removes a source's notices. */
2687
+ function NotificationProvider({ children, t, openSettings }) {
2688
+ const [sources, setSources] = (0, react.useState)(/* @__PURE__ */ new Map());
2689
+ const publish = (0, react.useCallback)((source, notices) => {
2690
+ setSources((current) => {
2691
+ if (!current.has(source) && notices.length === 0) return current;
2692
+ const next = new Map(current);
2693
+ if (notices.length === 0) next.delete(source);
2694
+ else next.set(source, notices);
2695
+ return next;
2696
+ });
2697
+ }, []);
2698
+ return (0, react_jsx_runtime.jsxs)(Notifications.Provider, {
2699
+ value: publish,
2700
+ children: [children, (0, react_jsx_runtime.jsx)(ToastQueue, {
2701
+ notices: [...sources.values()].flat(),
2702
+ hint: t("settings.toastHint"),
2703
+ settingsAction: openSettings === void 0 ? void 0 : {
2704
+ label: t("settings.errors"),
2705
+ onClick: openSettings
2706
+ }
2707
+ })]
2708
+ });
2709
+ }
2710
+ /** Register resolved copy while retaining live callbacks for recovery actions. */
2711
+ function NotificationToasts({ notices }) {
2712
+ const publish = (0, react.useContext)(Notifications);
2713
+ const id = (0, react.useId)();
2714
+ const latest = (0, react.useRef)(notices);
2715
+ const alive = (0, react.useRef)(true);
2716
+ latest.current = notices;
2717
+ (0, react.useEffect)(() => {
2718
+ const registered = latest.current.map((notice) => ({
2719
+ ...notice,
2720
+ actions: notice.actions?.map((action) => ({
2721
+ leaveSettings: action.leaveSettings,
2722
+ disabled: action.disabled,
2723
+ label: action.label,
2724
+ onClick: () => {
2725
+ const current = latest.current.find((item) => item.key === notice.key)?.actions?.find((item) => item.label === action.label);
2726
+ if (alive.current && !current?.disabled) current?.onClick();
2727
+ }
2728
+ }))
2729
+ }));
2730
+ worktreeDiagnostics.publish(id, registered);
2731
+ publish?.(id, registered);
2732
+ }, [
2733
+ publish,
2734
+ id,
2735
+ JSON.stringify(notices.map(({ key, text, context, error, actions }) => [
2736
+ key,
2737
+ text,
2738
+ context,
2739
+ error,
2740
+ actions?.map(({ label, disabled, leaveSettings }) => [
2741
+ label,
2742
+ disabled,
2743
+ leaveSettings
2744
+ ])
2745
+ ]))
2746
+ ]);
2747
+ (0, react.useEffect)(() => {
2748
+ alive.current = true;
2749
+ return () => {
2750
+ alive.current = false;
2751
+ worktreeDiagnostics.deactivate(id);
2752
+ publish?.(id, []);
2753
+ };
2754
+ }, [publish, id]);
2755
+ return publish === void 0 ? (0, react_jsx_runtime.jsx)(ToastQueue, { notices }) : null;
2756
+ }
2757
+ function ErrorToast({ error, t, scope, context, actions, describe }) {
2758
+ const text = error === void 0 ? void 0 : formatWorktreeViewError(error, t);
2759
+ return (0, react_jsx_runtime.jsx)(NotificationToasts, { notices: text === void 0 ? [] : [{
2760
+ key: JSON.stringify([
2761
+ scope,
2762
+ error?.code,
2763
+ error?.details
2764
+ ]),
2765
+ text,
2766
+ error,
2767
+ context,
2768
+ actions,
2769
+ describe,
2770
+ toastKey: failureToastKey(error)
2771
+ }] });
2772
+ }
2773
+ function ToastQueue({ notices, hint, settingsAction }) {
2774
+ const [queue, setQueue] = (0, react.useState)({
2775
+ seen: [],
2776
+ pending: []
2777
+ });
2778
+ (0, react.useEffect)(() => {
2779
+ setQueue((current) => reconcileNotifications(current, notices));
2780
+ }, [notices]);
2781
+ const current = queue.pending[0];
2782
+ const key = current?.key;
2783
+ const onDone = (0, react.useCallback)(() => {
2784
+ setQueue((state) => ({
2785
+ ...state,
2786
+ pending: state.pending.filter((notice) => notice.key !== key)
2787
+ }));
2788
+ }, [key]);
2789
+ if (current === void 0) return null;
2790
+ return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Toast, {
2791
+ text: [notices.find((notice) => (notice.toastKey ?? notice.key) === current.key)?.text ?? current.text, hint].filter(Boolean).join(" "),
2792
+ actions: settingsAction === void 0 ? void 0 : [settingsAction],
2793
+ holdMs: 8e3,
2794
+ onDone
2795
+ }, current.key);
2796
+ }
2797
+ //#endregion
2197
2798
  //#region lib/client/view/worktree-view-errors.js
2198
2799
  /** A DSH Session exists even when the external Worktree binding needs repair. */
2199
2800
  var WorktreeSessionBindingError = class extends Error {
@@ -2208,9 +2809,14 @@ window.__ModuleLoader__.load({
2208
2809
  super(reason);
2209
2810
  this.name = "WorktreeSessionBindingError";
2210
2811
  const conflict = candidate?.code === "SESSION_ALREADY_BOUND";
2812
+ const incompatible = conflict || candidate?.code === "SESSION_CWD_MISMATCH" || candidate?.code === "SESSION_NOT_FOUND";
2211
2813
  this.code = conflict ? "SESSION_ALREADY_BOUND" : "SESSION_BINDING_FAILED";
2212
- this.retryable = conflict ? false : candidate?.retryable !== false;
2814
+ this.retryable = !incompatible && candidate?.retryable !== false;
2213
2815
  this.details = typeof candidate?.details === "object" && candidate.details !== null && !Array.isArray(candidate.details) ? candidate.details : {};
2816
+ this.details = {
2817
+ ...this.details,
2818
+ ...typeof candidate?.code === "string" ? { causeCode: candidate.code } : {}
2819
+ };
2214
2820
  this.sessionId = sessionId;
2215
2821
  this.cause = cause;
2216
2822
  }
@@ -2673,17 +3279,35 @@ window.__ModuleLoader__.load({
2673
3279
  ...summary.origin === "subagent" ? { origin: "subagent" } : {}
2674
3280
  };
2675
3281
  }
2676
- /** Derive row and group activity facts from one retained DSH Session snapshot. */
2677
- function deriveSessionPresentationIndex(sessions) {
2678
- const descendants = indexSubagentDescendants(Object.fromEntries(Object.entries(sessions.byId).map(([sessionId, summary]) => [sessionId, toLineageSummary(sessionId, summary)])));
3282
+ /**
3283
+ * Derive one ephemeral row/group projection. An available native status source
3284
+ * owns pending/completion facts, even for absent entries; legacy summary fields
3285
+ * are used only when that source is unavailable. Never infer completion from idle.
3286
+ */
3287
+ function deriveSessionPresentationIndex(sessions, sessionStatuses) {
3288
+ const statusFacts = (sessionId, summary) => {
3289
+ if (sessionStatuses === void 0) return summary;
3290
+ const native = sessionStatuses.get(sessionId);
3291
+ const kind = native?.pendingInteraction?.kind;
3292
+ return {
3293
+ running: native?.running ?? summary.running,
3294
+ pendingInteraction: isPendingInteractionStatus(kind) ? kind : void 0,
3295
+ completed: native?.completionUnread === true
3296
+ };
3297
+ };
3298
+ const descendants = indexSubagentDescendants(Object.fromEntries(Object.entries(sessions.byId).map(([sessionId, summary]) => [sessionId, toLineageSummary(sessionId, {
3299
+ ...summary,
3300
+ running: statusFacts(sessionId, summary).running
3301
+ })])));
2679
3302
  return Object.fromEntries(Object.entries(sessions.byId).map(([sessionId, summary]) => {
2680
3303
  const runningSubagentCount = descendants.get(sessionId)?.runningCount ?? 0;
3304
+ const facts = statusFacts(sessionId, summary);
2681
3305
  return [sessionId, {
2682
- status: sessionStatus(summary, runningSubagentCount),
2683
- running: summary.running === true,
2684
- ongoing: summary.running === true || runningSubagentCount > 0,
3306
+ status: sessionStatus(facts, runningSubagentCount),
3307
+ running: facts.running === true,
3308
+ ongoing: facts.running === true || runningSubagentCount > 0,
2685
3309
  runningSubagentCount,
2686
- completed: summary.completed === true,
3310
+ completed: facts.completed === true,
2687
3311
  ...validUpdatedAt(summary.updatedAt) ? { updatedAt: summary.updatedAt } : {}
2688
3312
  }];
2689
3313
  }));
@@ -2881,17 +3505,16 @@ window.__ModuleLoader__.load({
2881
3505
  },
2882
3506
  children: t("worktree.adoptBranch")
2883
3507
  })] }),
2884
- children: error !== void 0 && (0, react_jsx_runtime.jsxs)("div", {
2885
- role: "alert",
2886
- children: [(0, react_jsx_runtime.jsx)("p", {
2887
- className: worktree_css_default.message,
2888
- children: formatWorktreeViewError(error, t)
2889
- }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
2890
- variant: "outline",
3508
+ children: (0, react_jsx_runtime.jsx)(ErrorToast, {
3509
+ error,
3510
+ t,
3511
+ scope: "adopt:" + worktree.worktreeId,
3512
+ context: t("settings.adopt") + " · " + worktree.branch + " · " + worktree.absolutePath,
3513
+ actions: [{
3514
+ label: t("action.retry"),
2891
3515
  disabled: actionPending,
2892
- onClick: onRetry,
2893
- children: t("action.retry")
2894
- })]
3516
+ onClick: onRetry
3517
+ }]
2895
3518
  })
2896
3519
  });
2897
3520
  }
@@ -2941,10 +3564,11 @@ window.__ModuleLoader__.load({
2941
3564
  onSubmit();
2942
3565
  }
2943
3566
  }
2944
- }), error !== void 0 && (0, react_jsx_runtime.jsx)("p", {
2945
- className: worktree_css_default.renameError,
2946
- role: "alert",
2947
- children: formatWorktreeViewError(error, t)
3567
+ }), (0, react_jsx_runtime.jsx)(ErrorToast, {
3568
+ error,
3569
+ t,
3570
+ scope: "rename-session:" + target?.sessionId,
3571
+ describe: (translate) => translate("session.rename") + " · " + (target?.currentTitle ?? "")
2948
3572
  })]
2949
3573
  });
2950
3574
  }
@@ -2988,15 +3612,17 @@ window.__ModuleLoader__.load({
2988
3612
  }
2989
3613
  }
2990
3614
  }),
2991
- duplicate && (0, react_jsx_runtime.jsx)("p", {
2992
- className: worktree_css_default.renameError,
2993
- role: "alert",
2994
- children: t("workspace.duplicate")
2995
- }),
2996
- error !== void 0 && (0, react_jsx_runtime.jsx)("p", {
2997
- className: worktree_css_default.renameError,
2998
- role: "alert",
2999
- children: formatWorktreeViewError(error, t)
3615
+ duplicate && (0, react_jsx_runtime.jsx)(NotificationToasts, { notices: [{
3616
+ key: "workspace-duplicate",
3617
+ text: t("workspace.duplicate"),
3618
+ context: target.currentTitle,
3619
+ message: (translate) => translate("workspace.duplicate")
3620
+ }] }),
3621
+ (0, react_jsx_runtime.jsx)(ErrorToast, {
3622
+ error,
3623
+ t,
3624
+ scope: "rename-workspace:" + target.workspaceId,
3625
+ describe: (translate) => translate("workspace.rename") + " · " + target.currentTitle
3000
3626
  })
3001
3627
  ]
3002
3628
  });
@@ -3022,10 +3648,11 @@ window.__ModuleLoader__.load({
3022
3648
  },
3023
3649
  children: t("dialog.delete")
3024
3650
  })] }),
3025
- children: error !== void 0 && (0, react_jsx_runtime.jsx)("p", {
3026
- className: worktree_css_default.renameError,
3027
- role: "alert",
3028
- children: formatWorktreeViewError(error, t)
3651
+ children: (0, react_jsx_runtime.jsx)(ErrorToast, {
3652
+ error,
3653
+ t,
3654
+ scope: "delete-workspace:" + target.workspaceId,
3655
+ describe: (translate) => translate("workspace.deleteTitle") + " · " + target.title
3029
3656
  })
3030
3657
  });
3031
3658
  }
@@ -3089,18 +3716,19 @@ window.__ModuleLoader__.load({
3089
3716
  className: worktree_css_default.message,
3090
3717
  children: t("worktree.importLoading")
3091
3718
  }),
3092
- importCandidates.status === "error" && (0, react_jsx_runtime.jsxs)("div", {
3093
- className: worktree_css_default.worktreeImportError,
3094
- role: "alert",
3095
- children: [(0, react_jsx_runtime.jsx)("p", {
3096
- className: worktree_css_default.message,
3097
- children: formatWorktreeViewError(importCandidates.error, t)
3098
- }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
3099
- variant: "outline",
3100
- disabled: actionPending,
3101
- onClick: onRetryImportCandidates,
3102
- children: t("action.retry")
3103
- })]
3719
+ importCandidates.status === "error" && (0, react_jsx_runtime.jsx)("div", {
3720
+ className: worktree_css_default.recoveryActions,
3721
+ children: (0, react_jsx_runtime.jsx)(ErrorToast, {
3722
+ error: importCandidates.error,
3723
+ t,
3724
+ scope: "import:" + workspace.workspaceId,
3725
+ context: t("settings.import") + " · " + workspace.title + " · " + workspace.path,
3726
+ actions: [{
3727
+ label: t("action.retry"),
3728
+ disabled: actionPending,
3729
+ onClick: onRetryImportCandidates
3730
+ }]
3731
+ })
3104
3732
  }),
3105
3733
  importCandidates.candidates.length === 0 && importCandidates.status === "ready" && (0, react_jsx_runtime.jsx)("p", {
3106
3734
  className: worktree_css_default.message,
@@ -3132,21 +3760,20 @@ window.__ModuleLoader__.load({
3132
3760
  })]
3133
3761
  })
3134
3762
  ]
3135
- }) : readError !== void 0 ? (0, react_jsx_runtime.jsxs)("div", {
3763
+ }) : readError !== void 0 ? (0, react_jsx_runtime.jsx)("div", {
3136
3764
  className: worktree_css_default.gitReadiness,
3137
3765
  "data-worktree-readiness": "error",
3138
- role: "alert",
3139
- children: [(0, react_jsx_runtime.jsx)("p", {
3140
- className: worktree_css_default.message,
3141
- "data-error": "true",
3142
- children: formatWorktreeViewError(readError, t)
3143
- }), readError.retryable && onRetry !== void 0 && (0, react_jsx_runtime.jsx)("button", {
3144
- type: "button",
3145
- className: worktree_css_default.retryButton,
3146
- disabled: actionPending,
3147
- onClick: onRetry,
3148
- children: t("action.retry")
3149
- })]
3766
+ children: (0, react_jsx_runtime.jsx)(ErrorToast, {
3767
+ error: readError,
3768
+ t,
3769
+ scope: "modal-read:" + workspace.workspaceId,
3770
+ context: t("settings.create") + " · " + workspace.title + " · " + workspace.path,
3771
+ actions: readError.retryable && onRetry !== void 0 ? [{
3772
+ label: t("action.retry"),
3773
+ disabled: actionPending,
3774
+ onClick: onRetry
3775
+ }] : []
3776
+ })
3150
3777
  }) : canCreate ? (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsxs)("label", {
3151
3778
  className: worktree_css_default.modalField,
3152
3779
  children: [t("worktree.baseBranch"), (0, react_jsx_runtime.jsx)("select", {
@@ -3181,7 +3808,7 @@ window.__ModuleLoader__.load({
3181
3808
  })] }) : (0, react_jsx_runtime.jsxs)("div", {
3182
3809
  className: worktree_css_default.gitReadiness,
3183
3810
  "data-worktree-readiness": setupStatus ?? "loading",
3184
- role: "alert",
3811
+ role: "status",
3185
3812
  children: [(0, react_jsx_runtime.jsx)("p", {
3186
3813
  className: worktree_css_default.message,
3187
3814
  children: setupStatus === void 0 ? t("status.loading") : worktreeSetupMessage(setupStatus, t)
@@ -3233,7 +3860,7 @@ window.__ModuleLoader__.load({
3233
3860
  title: t("worktree.cleanDiskTitle"),
3234
3861
  description: activityBlock === "recovery" ? t("worktree.recovery") : t("worktree.cleanDiskDescription", {
3235
3862
  name: worktree.branch,
3236
- path: worktree.absolutePath
3863
+ path: gitWorktreeRoot(worktree)
3237
3864
  }),
3238
3865
  footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
3239
3866
  variant: "outline",
@@ -3922,25 +4549,62 @@ window.__ModuleLoader__.load({
3922
4549
  return records?.find((record) => record.workspaceId === selection.workspaceId && record.worktreeId === selection.worktreeId);
3923
4550
  }
3924
4551
  //#endregion
4552
+ //#region lib/client/surface/state/useTitleMarquee.js
4553
+ const MIN_TITLE_REVEAL_PX = 8;
4554
+ const TITLE_MARQUEE_PX_PER_MS = .03;
4555
+ function placeTitle(title, left, range) {
4556
+ if (typeof title.scrollTo === "function") title.scrollTo({
4557
+ left,
4558
+ behavior: "instant"
4559
+ });
4560
+ else title.scrollLeft = left;
4561
+ if (left > 0) title.dataset.scrolled = "";
4562
+ else delete title.dataset.scrolled;
4563
+ if (left < range) title.dataset.clipped = "";
4564
+ else delete title.dataset.clipped;
4565
+ }
4566
+ function restTitle(title) {
4567
+ placeTitle(title, 0, 0);
4568
+ }
4569
+ /** Native title reveal shared by Session and Worktree rows. */
4570
+ function useTitleMarquee(title) {
4571
+ const frame = (0, react.useRef)(0);
4572
+ (0, react.useEffect)(() => () => {
4573
+ cancelAnimationFrame(frame.current);
4574
+ }, []);
4575
+ return (0, react.useMemo)(() => ({
4576
+ enter: () => {
4577
+ cancelAnimationFrame(frame.current);
4578
+ const element = title.current;
4579
+ if (element === null) return;
4580
+ const range = element.scrollWidth - element.clientWidth;
4581
+ if (range <= MIN_TITLE_REVEAL_PX) return;
4582
+ if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
4583
+ placeTitle(element, range, range);
4584
+ return;
4585
+ }
4586
+ let previous;
4587
+ let position = 0;
4588
+ const step = (now) => {
4589
+ position += previous === void 0 ? 0 : (now - previous) * TITLE_MARQUEE_PX_PER_MS;
4590
+ previous = now;
4591
+ placeTitle(element, Math.min(position, range), range);
4592
+ if (position < range) frame.current = requestAnimationFrame(step);
4593
+ };
4594
+ frame.current = requestAnimationFrame(step);
4595
+ },
4596
+ leave: () => {
4597
+ cancelAnimationFrame(frame.current);
4598
+ if (title.current !== null) restTitle(title.current);
4599
+ }
4600
+ }), [title]);
4601
+ }
4602
+ //#endregion
3925
4603
  //#region lib/client/surface/components/rows.js
3926
4604
  function rowHalf(event) {
3927
4605
  const rect = event.currentTarget.getBoundingClientRect();
3928
4606
  return event.clientY < rect.top + rect.height / 2 ? "before" : "after";
3929
4607
  }
3930
- const WORKTREE_LABEL_SCROLL_START_PAUSE_MS = 800;
3931
- const WORKTREE_LABEL_SCROLL_FORWARD_MS = 3e3;
3932
- const WORKTREE_LABEL_SCROLL_RETURN_MS = 3e3;
3933
- const WORKTREE_LABEL_SCROLL_CYCLE_MS = 7800;
3934
- function worktreeLabelScrollProgress(elapsedMs) {
3935
- const elapsed = elapsedMs % WORKTREE_LABEL_SCROLL_CYCLE_MS;
3936
- const forwardStart = WORKTREE_LABEL_SCROLL_START_PAUSE_MS;
3937
- const forwardEnd = 3800;
3938
- const returnStart = 4800;
3939
- if (elapsed < forwardStart) return 0;
3940
- if (elapsed < forwardEnd) return (elapsed - forwardStart) / WORKTREE_LABEL_SCROLL_FORWARD_MS;
3941
- if (elapsed < returnStart) return 1;
3942
- return 1 - (elapsed - returnStart) / WORKTREE_LABEL_SCROLL_RETURN_MS;
3943
- }
3944
4608
  function sessionStatusLabel$1(t, status) {
3945
4609
  switch (status.labelKey) {
3946
4610
  case "running": return t("session.status.running");
@@ -3999,7 +4663,7 @@ window.__ModuleLoader__.load({
3999
4663
  });
4000
4664
  }
4001
4665
  /** Workspace row using the native DSH menu, fixed action column, and drag contract. */
4002
- function WorktreeWorkspaceRow({ t, workspace, expanded, groupActivityStatus, actionPending, menuOpen, drag, onToggle, onCreateWorktree, onRename, onDelete, onMenuOpenChange }) {
4666
+ function WorktreeWorkspaceRow({ t, workspace, expanded, containsCurrentSession, groupActivityStatus, actionPending, menuOpen, drag, onToggle, onCreateWorktree, onRename, onDelete, onMenuOpenChange }) {
4003
4667
  const workspaceMenuItems = [{
4004
4668
  id: "rename",
4005
4669
  label: t("workspace.rename"),
@@ -4052,10 +4716,11 @@ window.__ModuleLoader__.load({
4052
4716
  event.stopPropagation();
4053
4717
  onToggle();
4054
4718
  },
4055
- children: expanded ? (0, react_jsx_runtime.jsx)(IconChevronDownOutline14, { size: 18 }) : (0, react_jsx_runtime.jsx)(IconChevronRightOutline14, { size: 18 })
4719
+ children: (0, react_jsx_runtime.jsx)(IconTriangleRightFill14, { className: worktree_css_default.disclosureArrow })
4056
4720
  }),
4057
4721
  (0, react_jsx_runtime.jsx)("span", {
4058
4722
  className: worktree_css_default.workspaceIcon,
4723
+ "data-workspace-active": expanded && containsCurrentSession ? "true" : void 0,
4059
4724
  "aria-hidden": "true",
4060
4725
  children: expanded ? (0, react_jsx_runtime.jsx)(IconFolderOpen16, {}) : (0, react_jsx_runtime.jsx)(IconFolderClose16, {})
4061
4726
  }),
@@ -4111,7 +4776,7 @@ window.__ModuleLoader__.load({
4111
4776
  event.stopPropagation();
4112
4777
  onCreateWorktree();
4113
4778
  },
4114
- children: (0, react_jsx_runtime.jsx)(IconPlusOutline16, {})
4779
+ children: (0, react_jsx_runtime.jsx)(IconBranchOutline16, {})
4115
4780
  })
4116
4781
  ]
4117
4782
  })
@@ -4126,52 +4791,7 @@ window.__ModuleLoader__.load({
4126
4791
  const worktreeStateVisible = stateLabel !== void 0;
4127
4792
  const dashboardActionVisible = showDashboardAction === true && menu?.onDashboard !== void 0;
4128
4793
  const worktreeLabelRef = (0, react.useRef)(null);
4129
- const labelScrollFrameRef = (0, react.useRef)(void 0);
4130
- const worktreeLabelPointerInsideRef = (0, react.useRef)(false);
4131
- const stopWorktreeLabelScroll = () => {
4132
- if (labelScrollFrameRef.current !== void 0) {
4133
- cancelAnimationFrame(labelScrollFrameRef.current);
4134
- labelScrollFrameRef.current = void 0;
4135
- }
4136
- if (worktreeLabelRef.current !== null) worktreeLabelRef.current.scrollLeft = 0;
4137
- };
4138
- const startWorktreeLabelScroll = () => {
4139
- if (labelScrollFrameRef.current !== void 0) return;
4140
- const labelElement = worktreeLabelRef.current;
4141
- const prefersReducedMotion = typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
4142
- if (labelElement === null || prefersReducedMotion) return;
4143
- const startedAt = performance.now();
4144
- const animate = (timestamp) => {
4145
- if (worktreeLabelRef.current !== labelElement) {
4146
- labelScrollFrameRef.current = void 0;
4147
- return;
4148
- }
4149
- const maxScrollLeft = Math.max(0, labelElement.scrollWidth - labelElement.clientWidth);
4150
- if (maxScrollLeft === 0) {
4151
- labelElement.scrollLeft = 0;
4152
- labelScrollFrameRef.current = void 0;
4153
- return;
4154
- }
4155
- labelElement.scrollLeft = maxScrollLeft * worktreeLabelScrollProgress(timestamp - startedAt);
4156
- labelScrollFrameRef.current = requestAnimationFrame(animate);
4157
- };
4158
- labelScrollFrameRef.current = requestAnimationFrame(animate);
4159
- };
4160
- const syncWorktreeLabelScroll = () => {
4161
- if (worktreeLabelPointerInsideRef.current || groupActivityVisible) startWorktreeLabelScroll();
4162
- else stopWorktreeLabelScroll();
4163
- };
4164
- (0, react.useEffect)(() => {
4165
- syncWorktreeLabelScroll();
4166
- }, [groupActivityVisible, label]);
4167
- (0, react.useEffect)(() => {
4168
- return () => {
4169
- if (labelScrollFrameRef.current !== void 0) {
4170
- cancelAnimationFrame(labelScrollFrameRef.current);
4171
- labelScrollFrameRef.current = void 0;
4172
- }
4173
- };
4174
- }, []);
4794
+ const marquee = useTitleMarquee(worktreeLabelRef);
4175
4795
  const markerClass = drag?.marker === "before" ? worktree_css_default.dropBefore : drag?.marker === "after" ? worktree_css_default.dropAfter : "";
4176
4796
  const dragProps = drag === void 0 ? {} : {
4177
4797
  draggable: true,
@@ -4203,14 +4823,8 @@ window.__ModuleLoader__.load({
4203
4823
  "data-worktree-drag": drag?.active ? "active" : void 0,
4204
4824
  ...dragProps,
4205
4825
  onClick: onToggle,
4206
- onMouseEnter: () => {
4207
- worktreeLabelPointerInsideRef.current = true;
4208
- syncWorktreeLabelScroll();
4209
- },
4210
- onMouseLeave: () => {
4211
- worktreeLabelPointerInsideRef.current = false;
4212
- syncWorktreeLabelScroll();
4213
- },
4826
+ onPointerEnter: marquee.enter,
4827
+ onPointerLeave: marquee.leave,
4214
4828
  children: [
4215
4829
  (0, react_jsx_runtime.jsx)("button", {
4216
4830
  type: "button",
@@ -4221,7 +4835,7 @@ window.__ModuleLoader__.load({
4221
4835
  event.stopPropagation();
4222
4836
  onToggle();
4223
4837
  },
4224
- children: expanded ? (0, react_jsx_runtime.jsx)(IconChevronDownOutline14, { size: 18 }) : (0, react_jsx_runtime.jsx)(IconChevronRightOutline14, { size: 18 })
4838
+ children: (0, react_jsx_runtime.jsx)(IconTriangleRightFill14, { className: worktree_css_default.disclosureArrow })
4225
4839
  }),
4226
4840
  (0, react_jsx_runtime.jsx)("span", {
4227
4841
  className: worktree_css_default.worktreeIcon,
@@ -4279,7 +4893,7 @@ window.__ModuleLoader__.load({
4279
4893
  ...menu.showCreate ? [{
4280
4894
  id: "create",
4281
4895
  label: t("worktree.createNew"),
4282
- icon: (0, react_jsx_runtime.jsx)(IconPlusOutline16, {}),
4896
+ icon: (0, react_jsx_runtime.jsx)(IconBranchOutline16, {}),
4283
4897
  disabled: menu.disabled || menu.onCreateWorktree === void 0
4284
4898
  }] : [],
4285
4899
  {
@@ -4363,7 +4977,7 @@ window.__ModuleLoader__.load({
4363
4977
  event.stopPropagation();
4364
4978
  onCreateSession();
4365
4979
  },
4366
- children: (0, react_jsx_runtime.jsx)(IconPlusOutline16, {})
4980
+ children: (0, react_jsx_runtime.jsx)(IconNewChatOutline16, {})
4367
4981
  })
4368
4982
  ]
4369
4983
  })
@@ -4401,6 +5015,8 @@ window.__ModuleLoader__.load({
4401
5015
  /** Worktree-mode Session row with the same trailing options menu as native DSH rows. */
4402
5016
  function WorktreeSessionRow({ t, sessionId, blank, current, label, drag, actionPending, onOpen, onRename, onFork, onArchive, presentation }) {
4403
5017
  const [menuOpen, setMenuOpen] = (0, react.useState)(false);
5018
+ const titleRef = (0, react.useRef)(null);
5019
+ const marquee = useTitleMarquee(titleRef);
4404
5020
  const markerClass = drag.marker === "before" ? worktree_css_default.dropBefore : drag.marker === "after" ? worktree_css_default.dropAfter : "";
4405
5021
  const sessionMenuItems = [
4406
5022
  {
@@ -4442,6 +5058,8 @@ window.__ModuleLoader__.load({
4442
5058
  "data-menu-open": menuOpen || void 0,
4443
5059
  role: "treeitem",
4444
5060
  "aria-current": current ? "true" : void 0,
5061
+ onPointerEnter: marquee.enter,
5062
+ onPointerLeave: marquee.leave,
4445
5063
  draggable: true,
4446
5064
  onDragStart: (event) => {
4447
5065
  event.dataTransfer.effectAllowed = "move";
@@ -4465,6 +5083,7 @@ window.__ModuleLoader__.load({
4465
5083
  className: worktree_css_default.treeSessionContent,
4466
5084
  onClick: onOpen,
4467
5085
  children: (0, react_jsx_runtime.jsx)("span", {
5086
+ ref: titleRef,
4468
5087
  className: worktree_css_default.sessionLabel,
4469
5088
  children: label
4470
5089
  })
@@ -5142,6 +5761,7 @@ window.__ModuleLoader__.load({
5142
5761
  t,
5143
5762
  workspace,
5144
5763
  expanded,
5764
+ containsCurrentSession: currentSessionId !== void 0 && allWorkspaceSessionIds.includes(currentSessionId),
5145
5765
  groupActivityStatus: workspaceGroupActivityStatus,
5146
5766
  actionPending,
5147
5767
  menuOpen: openWorkspaceMenuId === workspace.workspaceId,
@@ -5325,46 +5945,98 @@ window.__ModuleLoader__.load({
5325
5945
  }) });
5326
5946
  }
5327
5947
  //#endregion
5328
- //#region lib/client/surface/notification-queue.js
5329
- /** Resolved notices leave the queue; unchanged snapshots never announce twice. */
5330
- function reconcileNotifications(state, notices) {
5331
- const unique = [...new Map(notices.map((notice) => [notice.key, notice])).values()];
5332
- const active = new Set(unique.map((notice) => notice.key));
5333
- const seen = new Set(state.seen);
5334
- const pending = state.pending.filter((notice) => active.has(notice.key));
5335
- for (const notice of unique) if (!seen.has(notice.key)) pending.push(notice);
5336
- const nextSeen = [...active];
5337
- if (nextSeen.length === state.seen.length && nextSeen.every((key, index) => key === state.seen[index]) && pending.length === state.pending.length && pending.every((notice, index) => notice === state.pending[index])) return state;
5338
- return {
5339
- seen: nextSeen,
5340
- pending
5948
+ //#region lib/client/surface/components/OverlayScrollbar.js
5949
+ /** A themed thumb over the native scrollport: the list keeps its full width. */
5950
+ function OverlayScrollbar({ scrollportRef }) {
5951
+ const thumbRef = (0, react.useRef)(null);
5952
+ const dragRef = (0, react.useRef)(null);
5953
+ const [dragging, setDragging] = (0, react.useState)(false);
5954
+ const [geometry, setGeometry] = (0, react.useState)({
5955
+ height: 0,
5956
+ top: 0,
5957
+ range: 0,
5958
+ travel: 0
5959
+ });
5960
+ (0, react.useLayoutEffect)(() => {
5961
+ const scrollport = scrollportRef.current;
5962
+ const content = scrollport?.firstElementChild;
5963
+ if (scrollport === null || content == null) return;
5964
+ const measure = () => {
5965
+ const viewport = scrollport.clientHeight;
5966
+ const range = Math.max(0, scrollport.scrollHeight - viewport);
5967
+ const height = scrollport.scrollHeight === 0 ? 0 : Math.min(viewport, Math.max(24, viewport * viewport / scrollport.scrollHeight));
5968
+ const travel = viewport - height;
5969
+ setGeometry({
5970
+ height,
5971
+ range,
5972
+ travel,
5973
+ top: range === 0 ? 0 : Math.min(travel, Math.max(0, scrollport.scrollTop / range * travel))
5974
+ });
5975
+ };
5976
+ const observer = new ResizeObserver(measure);
5977
+ observer.observe(scrollport);
5978
+ observer.observe(content);
5979
+ scrollport.addEventListener("scroll", measure, { passive: true });
5980
+ measure();
5981
+ return () => {
5982
+ observer.disconnect();
5983
+ scrollport.removeEventListener("scroll", measure);
5984
+ };
5985
+ }, [scrollportRef]);
5986
+ const releaseDrag = (event) => {
5987
+ if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
5988
+ dragRef.current = null;
5989
+ setDragging(false);
5341
5990
  };
5342
- }
5343
- //#endregion
5344
- //#region lib/client/surface/components/NotificationToasts.js
5345
- /** One native toast at a time; recovery controls remain available after it fades. */
5346
- function NotificationToasts({ notices, detailsLabel }) {
5347
- const [queue, setQueue] = (0, react.useState)({
5348
- seen: [],
5349
- pending: []
5991
+ return (0, react_jsx_runtime.jsx)("div", {
5992
+ className: worktree_css_default.overlayScrollbar,
5993
+ hidden: geometry.range === 0,
5994
+ "aria-hidden": "true",
5995
+ "data-dragging": dragging || void 0,
5996
+ onPointerDown: (event) => {
5997
+ const scrollport = scrollportRef.current;
5998
+ if (event.button !== 0 || scrollport === null || geometry.travel <= 0) return;
5999
+ event.preventDefault();
6000
+ if (event.target !== thumbRef.current) {
6001
+ const top = event.clientY - event.currentTarget.getBoundingClientRect().top - geometry.height / 2;
6002
+ scrollport.scrollTop = Math.max(0, Math.min(geometry.travel, top)) / geometry.travel * geometry.range;
6003
+ }
6004
+ dragRef.current = {
6005
+ pointerId: event.pointerId,
6006
+ y: event.clientY,
6007
+ scrollTop: scrollport.scrollTop
6008
+ };
6009
+ event.currentTarget.setPointerCapture(event.pointerId);
6010
+ setDragging(true);
6011
+ },
6012
+ onPointerMove: (event) => {
6013
+ const drag = dragRef.current;
6014
+ const scrollport = scrollportRef.current;
6015
+ if (drag === null || drag.pointerId !== event.pointerId || scrollport === null || geometry.travel <= 0) return;
6016
+ scrollport.scrollTop = drag.scrollTop + (event.clientY - drag.y) / geometry.travel * geometry.range;
6017
+ },
6018
+ onPointerUp: releaseDrag,
6019
+ onPointerCancel: releaseDrag,
6020
+ onLostPointerCapture: () => {
6021
+ dragRef.current = null;
6022
+ setDragging(false);
6023
+ },
6024
+ onWheel: (event) => {
6025
+ const scrollport = scrollportRef.current;
6026
+ if (scrollport !== null) {
6027
+ const unit = event.deltaMode === 1 ? 20 : event.deltaMode === 2 ? scrollport.clientHeight : 1;
6028
+ scrollport.scrollTop += event.deltaY * unit;
6029
+ }
6030
+ },
6031
+ children: (0, react_jsx_runtime.jsx)("div", {
6032
+ ref: thumbRef,
6033
+ className: worktree_css_default.scrollbarThumb,
6034
+ style: {
6035
+ height: geometry.height,
6036
+ transform: `translateY(${geometry.top}px)`
6037
+ }
6038
+ })
5350
6039
  });
5351
- (0, react.useEffect)(() => {
5352
- setQueue((current) => reconcileNotifications(current, notices));
5353
- }, [notices]);
5354
- const current = queue.pending[0];
5355
- const key = current?.key;
5356
- const onDone = (0, react.useCallback)(() => {
5357
- setQueue((state) => ({
5358
- ...state,
5359
- pending: state.pending.filter((notice) => notice.key !== key)
5360
- }));
5361
- }, [key]);
5362
- if (current === void 0) return null;
5363
- return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Toast, {
5364
- text: (current.text.length > 240 ? current.text.slice(0, 240) + "…" : current.text) + " · " + detailsLabel,
5365
- holdMs: 6e3,
5366
- onDone
5367
- }, current.key);
5368
6040
  }
5369
6041
  //#endregion
5370
6042
  //#region lib/client/surface/components/SurfaceContent.js
@@ -5376,198 +6048,183 @@ window.__ModuleLoader__.load({
5376
6048
  const { forkRetryKey, retryForkBinding, pendingSessionBinding, pendingSessionArchived, retrySessionBinding, setPendingSessionBinding } = session;
5377
6049
  const { refresh, readState } = read;
5378
6050
  const notices = [];
5379
- const addNotice = (scope, text) => {
6051
+ const workspaceLabel = (workspaceId) => {
6052
+ const workspace = source.workspaces.items.find((item) => item.workspaceId === workspaceId);
6053
+ return workspace === void 0 ? workspaceId : `${workspace.title} · ${workspace.path}`;
6054
+ };
6055
+ const sessionLabel = (sessionId) => source.sessions.byId[sessionId]?.displayTitle ?? sessionId;
6056
+ const retryRead = (workspaceIds) => ({
6057
+ label: t("action.retry"),
6058
+ disabled: actionPending,
6059
+ onClick: () => {
6060
+ refresh({
6061
+ scope: workspaceIds === void 0 ? { kind: "global" } : {
6062
+ kind: "workspaces",
6063
+ workspaceIds
6064
+ },
6065
+ preserveCurrent: true
6066
+ });
6067
+ }
6068
+ });
6069
+ const actionsFor = (error) => {
6070
+ const recovery = recoveryAction(error);
6071
+ return recovery === null ? [] : [recovery];
6072
+ };
6073
+ if (permissionNoticeSnapshot !== void 0) notices.push({
6074
+ key: "permission:" + permissionNoticeSnapshot.workspaceId + ":" + permissionNoticeSnapshot.worktreeId,
6075
+ text: formatWorktreePermissionNotice(permissionNoticeSnapshot.result, t),
6076
+ message: (translate) => formatWorktreePermissionNotice(permissionNoticeSnapshot.result, translate),
6077
+ context: t("settings.permission") + " · " + workspaceLabel(permissionNoticeSnapshot.workspaceId),
6078
+ actions: permissionRetryTarget === void 0 ? [] : [{
6079
+ label: t("action.retry"),
6080
+ disabled: actionPending,
6081
+ onClick: retryCleanupPermissions
6082
+ }]
6083
+ });
6084
+ for (const recovery of forkRecoverySnapshot.pending) {
6085
+ const error = forkRecoveryError(recovery);
5380
6086
  notices.push({
5381
- key: JSON.stringify([scope, text]),
5382
- text
6087
+ key: "fork:" + recovery.key,
6088
+ error,
6089
+ text: formatWorktreeViewError(error, t),
6090
+ toastKey: failureToastKey(error),
6091
+ context: t("settings.binding") + " · " + sessionLabel(recovery.childSessionId),
6092
+ actions: [...retryForkSession !== void 0 && error.retryable ? [{
6093
+ label: t("action.retryBinding"),
6094
+ disabled: forkRetryKey !== void 0,
6095
+ onClick: () => {
6096
+ retryForkBinding(recovery.key);
6097
+ }
6098
+ }] : [], {
6099
+ label: t("action.openCreatedSession"),
6100
+ disabled: forkRetryKey !== void 0,
6101
+ leaveSettings: true,
6102
+ onClick: () => openSession(recovery.childSessionId)
6103
+ }]
5383
6104
  });
5384
- };
5385
- if (permissionNoticeSnapshot !== void 0) addNotice("permission:" + permissionNoticeSnapshot.workspaceId + ":" + permissionNoticeSnapshot.worktreeId, formatWorktreePermissionNotice(permissionNoticeSnapshot.result, t));
5386
- for (const recovery of forkRecoverySnapshot.pending) addNotice("fork:" + recovery.key, formatWorktreeViewError(forkRecoveryError(recovery), t));
5387
- if (actionError !== void 0) addNotice("action:" + JSON.stringify(actionError.details), formatWorktreeViewError(actionError, t));
5388
- if (readState.targetError !== void 0) addNotice("target:" + JSON.stringify(readState.targetError.workspaceIds), formatWorktreeViewError(readState.targetError.error, t));
5389
- if (readState.status === "error" && readState.error !== void 0) addNotice("read", formatWorktreeViewError(readState.error, t));
6105
+ }
6106
+ if (actionError !== void 0 && (pendingSessionBinding === void 0 || actionError.details?.sessionId !== pendingSessionBinding.sessionId)) {
6107
+ const error = actionError;
6108
+ const workspaceId = error.details?.workspaceId;
6109
+ const context = typeof workspaceId === "string" ? workspaceLabel(workspaceId) : "";
6110
+ notices.push({
6111
+ key: "action:" + JSON.stringify([error.code, error.details]),
6112
+ error,
6113
+ toastKey: failureToastKey(error),
6114
+ text: formatWorktreeViewError(error, t),
6115
+ context: t("settings.operation") + " · " + context,
6116
+ describe: (translate) => translate("settings.operation") + " · " + context,
6117
+ actions: [...actionsFor(error), ...error.retryable ? [{
6118
+ label: t("action.retry"),
6119
+ disabled: actionPending,
6120
+ onClick: () => {
6121
+ setActionError(void 0);
6122
+ refresh({
6123
+ scope: typeof workspaceId === "string" ? {
6124
+ kind: "workspace",
6125
+ workspaceId
6126
+ } : { kind: "global" },
6127
+ preserveCurrent: true
6128
+ });
6129
+ }
6130
+ }] : []]
6131
+ });
6132
+ }
6133
+ if (pendingSessionBinding !== void 0) {
6134
+ const binding = pendingSessionBinding;
6135
+ const error = binding.error ?? (actionError?.details?.sessionId === binding.sessionId ? actionError : {
6136
+ code: "SESSION_BINDING_FAILED",
6137
+ message: "",
6138
+ retryable: true,
6139
+ details: { sessionId: binding.sessionId }
6140
+ });
6141
+ const context = [
6142
+ workspaceLabel(binding.workspaceId),
6143
+ sessionLabel(binding.sessionId),
6144
+ binding.cwd
6145
+ ].filter(Boolean).join(" · ");
6146
+ notices.push({
6147
+ key: "binding:" + binding.sessionId,
6148
+ error,
6149
+ toastKey: failureToastKey(error),
6150
+ text: formatWorktreeViewError(error, t),
6151
+ context: t("settings.binding") + " · " + context,
6152
+ describe: (translate) => translate("settings.binding") + " · " + context,
6153
+ actions: [{
6154
+ label: t("action.retryBinding"),
6155
+ disabled: actionPending || pendingSessionArchived || error.retryable === false,
6156
+ onClick: () => {
6157
+ retrySessionBinding();
6158
+ }
6159
+ }, ...binding.permissionRequired ? [] : [{
6160
+ label: t("action.openCreatedSession"),
6161
+ disabled: actionPending,
6162
+ leaveSettings: true,
6163
+ onClick: () => {
6164
+ setPendingSessionBinding(void 0);
6165
+ if (actionError?.details?.sessionId === binding.sessionId) setActionError(void 0);
6166
+ openSession(binding.sessionId);
6167
+ }
6168
+ }]]
6169
+ });
6170
+ }
6171
+ if (readState.targetError !== void 0) {
6172
+ const { error, workspaceIds } = readState.targetError;
6173
+ notices.push({
6174
+ key: "target:" + JSON.stringify([
6175
+ workspaceIds,
6176
+ error.code,
6177
+ error.details
6178
+ ]),
6179
+ error,
6180
+ text: formatWorktreeViewError(error, t),
6181
+ context: t("settings.read") + " · " + workspaceIds.map(workspaceLabel).join(", "),
6182
+ actions: [...actionsFor(error), retryRead(workspaceIds)]
6183
+ });
6184
+ }
6185
+ if (readState.status === "error" && readState.error !== void 0) {
6186
+ const error = readState.error;
6187
+ notices.push({
6188
+ key: "read:" + JSON.stringify([error.code, error.details]),
6189
+ error,
6190
+ text: formatWorktreeViewError(error, t),
6191
+ context: t("settings.read"),
6192
+ actions: [...actionsFor(error), retryRead()]
6193
+ });
6194
+ }
5390
6195
  return (0, react_jsx_runtime.jsxs)("div", {
5391
- ref: expansion.contentRef,
5392
- className: worktree_css_default.content,
5393
- tabIndex: 0,
5394
- "data-worktree-scrollport": true,
5395
- children: [
5396
- (0, react_jsx_runtime.jsx)(NotificationToasts, {
5397
- notices,
5398
- detailsLabel: t("notice.details")
5399
- }),
5400
- notices.length > 0 && (0, react_jsx_runtime.jsxs)("details", {
5401
- className: worktree_css_default.notificationDetails,
6196
+ className: worktree_css_default.scrollFrame,
6197
+ children: [(0, react_jsx_runtime.jsx)("div", {
6198
+ ref: expansion.contentRef,
6199
+ className: worktree_css_default.content,
6200
+ tabIndex: 0,
6201
+ "data-worktree-scrollport": true,
6202
+ children: (0, react_jsx_runtime.jsxs)("div", {
6203
+ className: worktree_css_default.scrollContent,
5402
6204
  children: [
5403
- (0, react_jsx_runtime.jsxs)("summary", { children: [
5404
- t("notice.details"),
5405
- " (",
5406
- notices.length,
5407
- ")"
5408
- ] }),
5409
- permissionNoticeSnapshot !== void 0 && (0, react_jsx_runtime.jsxs)("div", {
5410
- className: worktree_css_default.notice,
5411
- role: "status",
5412
- "data-worktree-permission-notice": true,
5413
- children: [(0, react_jsx_runtime.jsx)("p", {
5414
- className: worktree_css_default.message,
5415
- children: formatWorktreePermissionNotice(permissionNoticeSnapshot.result, t)
5416
- }), permissionRetryTarget !== void 0 && (0, react_jsx_runtime.jsx)("button", {
5417
- type: "button",
5418
- className: worktree_css_default.retryButton,
5419
- disabled: actionPending,
5420
- onClick: retryCleanupPermissions,
5421
- children: t("action.retry")
5422
- })]
5423
- }),
5424
- forkRecoverySnapshot.pending.map((recovery) => {
5425
- const recoveryViewError = forkRecoveryError(recovery);
5426
- return (0, react_jsx_runtime.jsxs)("div", {
5427
- className: worktree_css_default.error,
5428
- role: "alert",
5429
- "data-fork-recovery": recovery.key,
5430
- children: [(0, react_jsx_runtime.jsx)("p", {
5431
- className: worktree_css_default.message,
5432
- "data-error": "true",
5433
- children: formatWorktreeViewError(recoveryViewError, t)
5434
- }), (0, react_jsx_runtime.jsxs)("div", {
5435
- className: worktree_css_default.recoveryActions,
5436
- children: [retryForkSession !== void 0 && recoveryViewError.retryable && (0, react_jsx_runtime.jsx)("button", {
5437
- type: "button",
5438
- className: worktree_css_default.actionButton,
5439
- disabled: forkRetryKey !== void 0,
5440
- onClick: () => {
5441
- retryForkBinding(recovery.key);
5442
- },
5443
- children: t("action.retryBinding")
5444
- }), (0, react_jsx_runtime.jsx)("button", {
5445
- type: "button",
5446
- className: worktree_css_default.actionButton,
5447
- disabled: forkRetryKey !== void 0,
5448
- onClick: () => {
5449
- openSession(recovery.childSessionId);
5450
- },
5451
- children: t("action.openCreatedSession")
5452
- })]
5453
- })]
5454
- }, recovery.key);
5455
- }),
5456
- actionError !== void 0 && (0, react_jsx_runtime.jsxs)("div", {
5457
- className: worktree_css_default.error,
5458
- role: "alert",
5459
- "data-worktree-error": true,
5460
- children: [
5461
- (0, react_jsx_runtime.jsx)("p", {
5462
- className: worktree_css_default.message,
5463
- "data-error": "true",
5464
- children: formatWorktreeViewError(actionError, t)
5465
- }),
5466
- recoveryAction(actionError),
5467
- pendingSessionBinding !== void 0 && (0, react_jsx_runtime.jsxs)("div", {
5468
- className: worktree_css_default.recoveryActions,
5469
- children: [(0, react_jsx_runtime.jsx)("button", {
5470
- type: "button",
5471
- className: worktree_css_default.actionButton,
5472
- disabled: actionPending || pendingSessionArchived,
5473
- onClick: () => {
5474
- retrySessionBinding();
5475
- },
5476
- children: t("action.retryBinding")
5477
- }), !pendingSessionBinding.permissionRequired && (0, react_jsx_runtime.jsx)("button", {
5478
- type: "button",
5479
- className: worktree_css_default.actionButton,
5480
- disabled: actionPending,
5481
- onClick: () => {
5482
- const sessionId = pendingSessionBinding.sessionId;
5483
- setPendingSessionBinding(void 0);
5484
- setActionError(void 0);
5485
- openSession(sessionId);
5486
- },
5487
- children: t("action.openCreatedSession")
5488
- })]
5489
- }),
5490
- actionError.retryable && (0, react_jsx_runtime.jsx)("button", {
5491
- type: "button",
5492
- className: worktree_css_default.retryButton,
5493
- onClick: () => {
5494
- setActionError(void 0);
5495
- refresh({ scope: { kind: "global" } });
5496
- },
5497
- children: t("action.retry")
5498
- })
5499
- ]
5500
- }),
5501
- readState.targetError !== void 0 && (0, react_jsx_runtime.jsxs)("div", {
5502
- className: worktree_css_default.error,
5503
- role: "alert",
5504
- "data-worktree-target-error": true,
5505
- children: [
5506
- (0, react_jsx_runtime.jsx)("p", {
5507
- className: worktree_css_default.message,
5508
- "data-error": "true",
5509
- children: formatWorktreeViewError(readState.targetError.error, t)
5510
- }),
5511
- recoveryAction(readState.targetError.error),
5512
- (0, react_jsx_runtime.jsx)("button", {
5513
- type: "button",
5514
- className: worktree_css_default.retryButton,
5515
- onClick: () => {
5516
- refresh({
5517
- scope: {
5518
- kind: "workspaces",
5519
- workspaceIds: readState.targetError.workspaceIds
5520
- },
5521
- preserveCurrent: true
5522
- });
5523
- },
5524
- children: t("action.retry")
5525
- })
5526
- ]
6205
+ (0, react_jsx_runtime.jsx)(NotificationToasts, { notices }),
6206
+ readState.status === "loading" && (0, react_jsx_runtime.jsx)("p", {
6207
+ className: worktree_css_default.message,
6208
+ children: t("status.loading")
5527
6209
  }),
5528
- readState.status === "error" && readState.error !== void 0 ? (0, react_jsx_runtime.jsxs)("div", {
5529
- className: worktree_css_default.error,
5530
- role: "alert",
5531
- "data-worktree-error": true,
5532
- children: [
5533
- (0, react_jsx_runtime.jsx)("p", {
5534
- className: worktree_css_default.message,
5535
- "data-error": "true",
5536
- children: formatWorktreeViewError(readState.error, t)
5537
- }),
5538
- recoveryAction(readState.error),
5539
- (0, react_jsx_runtime.jsx)("button", {
5540
- type: "button",
5541
- className: worktree_css_default.retryButton,
5542
- onClick: () => {
5543
- refresh({ scope: { kind: "global" } });
5544
- },
5545
- children: t("action.retry")
5546
- })
5547
- ]
5548
- }) : null
5549
- ]
5550
- }),
5551
- readState.status === "loading" && (0, react_jsx_runtime.jsx)("p", {
5552
- className: worktree_css_default.message,
5553
- children: t("status.loading")
5554
- }),
5555
- readState.status === "ready" ? (0, react_jsx_runtime.jsx)(WorkspaceTree, {
5556
- props,
5557
- read,
5558
- source,
5559
- expansion,
5560
- ordering,
5561
- drag,
5562
- mutation,
5563
- menus,
5564
- registration,
5565
- native,
5566
- lifecycle,
5567
- session,
5568
- lifecycleState
5569
- }) : null
5570
- ]
6210
+ readState.status === "ready" ? (0, react_jsx_runtime.jsx)(WorkspaceTree, {
6211
+ props,
6212
+ read,
6213
+ source,
6214
+ expansion,
6215
+ ordering,
6216
+ drag,
6217
+ mutation,
6218
+ menus,
6219
+ registration,
6220
+ native,
6221
+ lifecycle,
6222
+ session,
6223
+ lifecycleState
6224
+ }) : null
6225
+ ]
6226
+ })
6227
+ }), (0, react_jsx_runtime.jsx)(OverlayScrollbar, { scrollportRef: expansion.contentRef })]
5571
6228
  });
5572
6229
  }
5573
6230
  //#endregion
@@ -6095,10 +6752,13 @@ window.__ModuleLoader__.load({
6095
6752
  };
6096
6753
  const recoveryAction = (error) => {
6097
6754
  const workspaceId = error?.details?.workspaceId;
6098
- if (!manager || error?.code !== "WORKTREE_RECOVERY_REQUIRED" || typeof workspaceId !== "string") return null;
6099
- return (0, react_jsx_runtime.jsx)("button", {
6100
- type: "button",
6101
- className: worktree_css_default.retryButton,
6755
+ if (!manager || error === void 0 || ![
6756
+ "WORKTREE_RECOVERY_REQUIRED",
6757
+ "SIDECAR_SYNC_REQUIRED",
6758
+ "WORKTREE_IDENTITY_CHANGED"
6759
+ ].includes(error.code) || typeof workspaceId !== "string") return null;
6760
+ return {
6761
+ label: t("worktree.retryRecovery"),
6102
6762
  disabled: actionPending,
6103
6763
  onClick: () => {
6104
6764
  runMutation(() => manager.recoverWorktrees({ workspaceId }), {
@@ -6108,9 +6768,8 @@ window.__ModuleLoader__.load({
6108
6768
  },
6109
6769
  preserveCurrent: true
6110
6770
  });
6111
- },
6112
- children: t("worktree.retryRecovery")
6113
- });
6771
+ }
6772
+ };
6114
6773
  };
6115
6774
  const branchActions = (record) => ({
6116
6775
  onAdoptBranch: record.health === "branch-drift" && typeof record.currentBranch === "string" ? () => {
@@ -6425,40 +7084,6 @@ window.__ModuleLoader__.load({
6425
7084
  };
6426
7085
  }
6427
7086
  //#endregion
6428
- //#region lib/contract/windows-path.js
6429
- /**
6430
- * Browser-safe Windows path identity helpers. They intentionally do not touch
6431
- * the filesystem; Provider adds physical stat/realpath checks where it has
6432
- * access to Node APIs.
6433
- */
6434
- const EXTENDED_PATH_PREFIX = "//?/";
6435
- const EXTENDED_UNC_PREFIX = "//?/UNC/";
6436
- function isWindowsPath(value) {
6437
- return /^[A-Za-z]:[\\/]/u.test(value) || value.startsWith("\\\\") || /^\/\/\?(?:\/|\\)/u.test(value);
6438
- }
6439
- /** Strip only the extended drive/UNC prefixes supported by the browser boundary. */
6440
- function stripExtendedWindowsPrefix(value) {
6441
- const normalized = value.replaceAll("\\", "/");
6442
- const normalizedUncPrefix = EXTENDED_UNC_PREFIX.toLowerCase();
6443
- if (normalized.toLowerCase().startsWith(normalizedUncPrefix)) return "//" + normalized.slice(8);
6444
- if (normalized.startsWith(EXTENDED_PATH_PREFIX)) {
6445
- const drivePath = normalized.slice(4);
6446
- if (/^[A-Za-z]:\//u.test(drivePath)) return drivePath;
6447
- }
6448
- return value;
6449
- }
6450
- function normalizeWindowsPath(value) {
6451
- let normalized = stripExtendedWindowsPrefix(value).replaceAll("\\", "/");
6452
- const unc = normalized.startsWith("//");
6453
- normalized = normalized.replace(/\/{2,}/gu, "/");
6454
- if (unc && normalized.startsWith("/")) normalized = "/" + normalized;
6455
- if (normalized.length > 3) normalized = normalized.replace(/\/+$/u, "");
6456
- return normalized.toLowerCase();
6457
- }
6458
- function sameWindowsPath(left, right) {
6459
- return (isWindowsPath(left) || isWindowsPath(right)) && normalizeWindowsPath(left) === normalizeWindowsPath(right);
6460
- }
6461
- //#endregion
6462
7087
  //#region lib/client/session/worktree-session.js
6463
7088
  var WorktreeSessionActionError = class extends Error {
6464
7089
  code;
@@ -6544,7 +7169,7 @@ window.__ModuleLoader__.load({
6544
7169
  reason: "active-binding-session-missing",
6545
7170
  sessionId: targetBinding.sessionId
6546
7171
  };
6547
- if (summary.cwd === void 0 || !input.hostValidatesPhysicalPath && !sameWorktreePath(summary.cwd, input.target.absolutePath)) return {
7172
+ if (summary.cwd === void 0 || !input.hostValidatesPhysicalPath && !sameWorktreePath(summary.cwd, input.target.absolutePath) && (input.target.gitRootPath === void 0 || !sameWorktreePath(summary.cwd, input.target.gitRootPath))) return {
6548
7173
  kind: "repair",
6549
7174
  reason: "active-binding-cwd-mismatch",
6550
7175
  sessionId: targetBinding.sessionId
@@ -6737,14 +7362,16 @@ window.__ModuleLoader__.load({
6737
7362
  preserveCurrent: true
6738
7363
  });
6739
7364
  } catch (error) {
6740
- if (error instanceof WorktreeSessionBindingError && error.retryable) setPendingSessionBinding({
7365
+ if (error instanceof WorktreeSessionBindingError) setPendingSessionBinding({
6741
7366
  ...input,
6742
- sessionId: error.sessionId
7367
+ sessionId: error.sessionId,
7368
+ error: toWorktreeViewError(error)
6743
7369
  });
6744
7370
  if (error instanceof WorktreeSessionPermissionError && error.retryable) setPendingSessionBinding({
6745
7371
  ...input,
6746
7372
  sessionId: error.sessionId,
6747
- permissionRequired: true
7373
+ permissionRequired: true,
7374
+ error: toWorktreeViewError(error)
6748
7375
  });
6749
7376
  setActionError(toWorktreeViewError(error));
6750
7377
  } finally {
@@ -6752,7 +7379,7 @@ window.__ModuleLoader__.load({
6752
7379
  }
6753
7380
  };
6754
7381
  const retrySessionBinding = async () => {
6755
- if (manager === void 0 || pendingSessionBinding === void 0 || pendingSessionArchived) return;
7382
+ if (manager === void 0 || pendingSessionBinding === void 0 || pendingSessionArchived || pendingSessionBinding.error?.retryable === false) return;
6756
7383
  const pending = pendingSessionBinding;
6757
7384
  setActionPending(true);
6758
7385
  setActionError(void 0);
@@ -6778,7 +7405,10 @@ window.__ModuleLoader__.load({
6778
7405
  preserveCurrent: true
6779
7406
  });
6780
7407
  } catch (error) {
6781
- if (error instanceof WorktreeSessionBindingError && !error.retryable) setPendingSessionBinding(void 0);
7408
+ setPendingSessionBinding({
7409
+ ...pending,
7410
+ error: toWorktreeViewError(error)
7411
+ });
6782
7412
  setActionError(toWorktreeViewError(error));
6783
7413
  } finally {
6784
7414
  setActionPending(false);
@@ -7207,7 +7837,7 @@ window.__ModuleLoader__.load({
7207
7837
  if (selectedWorkspaceIds.length === 0) return;
7208
7838
  await Promise.allSettled(selectedWorkspaceIds.map(async (workspaceId) => {
7209
7839
  const guard = guardFor(workspaceId);
7210
- viewReader.invalidate(workspaceId, { reuseInFlight: options.reuseInFlight });
7840
+ if (!options.alreadyInvalidated) viewReader.invalidate(workspaceId, { reuseInFlight: options.reuseInFlight });
7211
7841
  const contextRefresh = options.invalidateContext === false ? void 0 : invalidateWorktreeContext?.(workspaceId);
7212
7842
  const generation = guard.begin();
7213
7843
  try {
@@ -7263,6 +7893,22 @@ window.__ModuleLoader__.load({
7263
7893
  manager,
7264
7894
  viewReader
7265
7895
  ]);
7896
+ (0, react.useEffect)(() => props.subscribeToolChanges?.(({ workspaceId }) => {
7897
+ if (mode !== "worktree") return;
7898
+ refresh({
7899
+ scope: {
7900
+ kind: "workspace",
7901
+ workspaceId
7902
+ },
7903
+ preserveCurrent: true,
7904
+ alreadyInvalidated: true,
7905
+ invalidateContext: false
7906
+ });
7907
+ }), [
7908
+ props.subscribeToolChanges,
7909
+ mode,
7910
+ refresh
7911
+ ]);
7266
7912
  const loadModalWorktreeView = (0, react.useCallback)((workspaceId) => {
7267
7913
  setModalReadError(void 0);
7268
7914
  setModalReadLoading(true);
@@ -7407,16 +8053,79 @@ window.__ModuleLoader__.load({
7407
8053
  //#endregion
7408
8054
  //#region lib/client/overlay/overlay-bounds.js
7409
8055
  function computeOverlayBounds(frame, newSession, footer) {
7410
- if (newSession === void 0 || footer === void 0) return {
8056
+ if (newSession === void 0 || footer === void 0 || ![
8057
+ frame.top,
8058
+ frame.bottom,
8059
+ newSession.top,
8060
+ newSession.bottom,
8061
+ footer.top,
8062
+ footer.bottom
8063
+ ].every(Number.isFinite) || frame.bottom <= frame.top || newSession.bottom <= newSession.top || footer.bottom <= footer.top) return {
7411
8064
  ready: false,
7412
8065
  top: 0,
7413
8066
  height: 0
7414
8067
  };
7415
- const top = Math.max(0, newSession.top - frame.top);
8068
+ const top = Math.max(0, Math.min(frame.bottom, newSession.top) - frame.top);
7416
8069
  return {
7417
8070
  ready: true,
7418
8071
  top,
7419
- height: Math.max(top, footer.top - frame.top) - top
8072
+ height: Math.max(top, Math.min(frame.bottom, footer.top) - frame.top) - top
8073
+ };
8074
+ }
8075
+ //#endregion
8076
+ //#region lib/client/layout/app-frame.js
8077
+ /** Public AppFrame anchors; never infer a column from sibling order or private classes. */
8078
+ function directChildWithin(parent, anchor) {
8079
+ let child = anchor;
8080
+ while (child && child.parentElement !== parent) child = child.parentElement;
8081
+ return child ?? void 0;
8082
+ }
8083
+ function resolveAppFrame(surface) {
8084
+ const overlay = surface.closest("[data-shell-overlay]");
8085
+ const frame = overlay?.parentElement;
8086
+ if (!(overlay instanceof HTMLElement) || !frame || !overlay.isConnected) return void 0;
8087
+ for (const selector of ["[data-worktree-mode-action]", "[data-pane=\"sidebar\"]"]) {
8088
+ const columns = new Set(Array.from(frame.querySelectorAll(selector)).map((anchor) => directChildWithin(frame, anchor)).filter((column) => column instanceof HTMLElement && column !== overlay && !column.hasAttribute("data-shell-overlay") && !column.hasAttribute("data-rightbar-col") && !column.hasAttribute("data-shell-leading")));
8089
+ if (columns.size > 1) return void 0;
8090
+ const sidebar = columns.values().next().value;
8091
+ if (sidebar) return {
8092
+ overlay,
8093
+ frame,
8094
+ sidebar
8095
+ };
8096
+ }
8097
+ }
8098
+ function finiteRect(rect) {
8099
+ return [
8100
+ rect.left,
8101
+ rect.right,
8102
+ rect.top,
8103
+ rect.bottom,
8104
+ rect.width,
8105
+ rect.height
8106
+ ].every(Number.isFinite);
8107
+ }
8108
+ function resolveFrameContent(frame, overlay, sidebar) {
8109
+ const rightbars = Array.from(frame.querySelectorAll("[data-rightbar-col]")).filter((column) => directChildWithin(frame, column) !== overlay);
8110
+ if (rightbars.length > 1) return void 0;
8111
+ const column = rightbars[0];
8112
+ const rightbar = frame.hasAttribute("data-rightbar-collapsed") ? void 0 : column;
8113
+ const box = overlay.getBoundingClientRect();
8114
+ const boundary = sidebar.getBoundingClientRect();
8115
+ const columnRect = column?.getBoundingClientRect();
8116
+ if (!finiteRect(box) || !finiteRect(boundary) || rightbar && columnRect && !finiteRect(columnRect)) return;
8117
+ const centerEdges = [rightbar && columnRect ? columnRect.left : box.right];
8118
+ if (!rightbar && columnRect && finiteRect(columnRect)) centerEdges.push(columnRect.left);
8119
+ const excluded = column ? directChildWithin(frame, column) : void 0;
8120
+ const centers = Array.from(frame.children).filter((child) => {
8121
+ if (!(child instanceof HTMLElement) || child === sidebar || child === overlay || child === excluded || child.hasAttribute("data-shell-overlay") || child.hasAttribute("data-shell-leading") || child.hasAttribute("data-window-drag")) return false;
8122
+ const rect = child.getBoundingClientRect();
8123
+ return finiteRect(rect) && rect.width > 0 && rect.height > 0 && Math.abs(rect.left - boundary.right) <= 1 && centerEdges.some((edge) => Math.abs(rect.right - edge) <= 1) && rect.top >= box.top - 1 && rect.top < box.bottom && Math.abs(rect.bottom - box.bottom) <= 1;
8124
+ });
8125
+ if (centers.length !== 1) return void 0;
8126
+ return {
8127
+ center: centers[0],
8128
+ rightbar
7420
8129
  };
7421
8130
  }
7422
8131
  //#endregion
@@ -7439,15 +8148,7 @@ window.__ModuleLoader__.load({
7439
8148
  };
7440
8149
  }
7441
8150
  function isRightSidebarOpenFromDom(frame, rightbar) {
7442
- if (typeof frame.querySelector === "function") {
7443
- if (frame.querySelector("[data-sidebar-right-open]") !== null) return true;
7444
- if (frame.hasAttribute("data-rightbar-collapsed")) return false;
7445
- }
7446
- if (frame.getAttribute?.("data-rightbar-collapsed") !== null) return false;
7447
- if (rightbar instanceof HTMLElement) {
7448
- if (rightbar.getAttribute?.("data-sidebar-right-open") !== null) return true;
7449
- }
7450
- return false;
8151
+ return !frame.hasAttribute("data-rightbar-collapsed") && rightbar instanceof HTMLElement && frame.contains(rightbar) && (rightbar.hasAttribute("data-sidebar-right-open") || rightbar.querySelector("[data-sidebar-right-open]") !== null);
7451
8152
  }
7452
8153
  /** Layout seam shared with the existing Sidebar overlay; fail closed on frame/center loss. */
7453
8154
  function mountDashboardOverlay(surface, onPlacement, options) {
@@ -7477,26 +8178,18 @@ window.__ModuleLoader__.load({
7477
8178
  const resize = typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver(schedule);
7478
8179
  const update = () => {
7479
8180
  if (disposed) return;
7480
- const sidebar = frame.firstElementChild;
7481
- const center = sidebar?.nextElementSibling;
7482
- const rightbar = center?.nextElementSibling;
7483
- const hasRightbar = rightbar instanceof HTMLElement && rightbar !== overlay && rightbar.nextElementSibling === overlay;
7484
- const hasNoRightbar = rightbar === overlay;
7485
- const valid = overlay.isConnected && overlay.parentElement === frame && sidebar instanceof HTMLElement && center instanceof HTMLElement && (hasRightbar || hasNoRightbar);
7486
- const nextObserved = valid ? hasRightbar ? [
8181
+ const anchors = resolveAppFrame(surface);
8182
+ const content = anchors?.frame === frame && anchors.overlay === overlay ? resolveFrameContent(frame, overlay, anchors.sidebar) : void 0;
8183
+ const nextObserved = [
8184
+ frame,
7487
8185
  overlay,
7488
- sidebar,
7489
- center,
7490
- rightbar
7491
- ] : [
7492
- overlay,
7493
- sidebar,
7494
- center
7495
- ] : [frame];
8186
+ ...Array.from(frame.children),
8187
+ ...Array.from(frame.querySelectorAll("[data-rightbar-col]"))
8188
+ ];
7496
8189
  for (const old of observed) if (!nextObserved.includes(old)) resize?.unobserve(old);
7497
8190
  for (const next of nextObserved) if (!observed.includes(next)) resize?.observe(next);
7498
8191
  observed = nextObserved;
7499
- if (!valid) {
8192
+ if (!anchors || !content) {
7500
8193
  restore();
7501
8194
  onPlacement(void 0);
7502
8195
  if (lastRightSidebarOpen) {
@@ -7505,9 +8198,11 @@ window.__ModuleLoader__.load({
7505
8198
  }
7506
8199
  return;
7507
8200
  }
8201
+ const { sidebar } = anchors;
8202
+ const { center, rightbar } = content;
7508
8203
  const box = overlay.getBoundingClientRect();
7509
8204
  const boundary = sidebar.getBoundingClientRect();
7510
- const rightBoundary = hasRightbar && rightbar instanceof HTMLElement ? rightbar.getBoundingClientRect().left : box.right;
8205
+ const rightBoundary = rightbar instanceof HTMLElement ? rightbar.getBoundingClientRect().left : box.right;
7511
8206
  const left = Math.max(0, boundary.right - box.left + SIDEBAR_RESIZE_HANDLE_HALF_WIDTH);
7512
8207
  const width = Math.min(box.right, rightBoundary) - box.left - left;
7513
8208
  if (width <= 0 || box.height <= 0) {
@@ -7515,24 +8210,26 @@ window.__ModuleLoader__.load({
7515
8210
  onPlacement(void 0);
7516
8211
  return;
7517
8212
  }
8213
+ const centerBox = center.getBoundingClientRect();
8214
+ const top = Math.max(0, centerBox.top - box.top);
8215
+ const height = Math.min(box.bottom, centerBox.bottom) - box.top - top;
8216
+ if (height <= 0) {
8217
+ restore();
8218
+ onPlacement(void 0);
8219
+ return;
8220
+ }
7518
8221
  for (const [element, cleanup] of hidden) if (element !== center) {
7519
8222
  cleanup();
7520
8223
  hidden.delete(element);
7521
8224
  }
7522
8225
  if (!hidden.has(center)) hidden.set(center, concealDashboardBackground(center));
7523
- const top = Math.max(0, (center.getBoundingClientRect().top ?? 0) - (box.top ?? 0));
7524
- if (top >= box.height) {
7525
- restore();
7526
- onPlacement(void 0);
7527
- return;
7528
- }
7529
8226
  onPlacement({
7530
8227
  left,
7531
8228
  top,
7532
8229
  width,
7533
- height: box.height - top
8230
+ height
7534
8231
  });
7535
- const isRightSidebarOpen = options?.isRightSidebarExpanded !== void 0 ? options.isRightSidebarExpanded() : isRightSidebarOpenFromDom(frame, hasRightbar ? rightbar : void 0);
8232
+ const isRightSidebarOpen = options?.isRightSidebarExpanded !== void 0 ? options.isRightSidebarExpanded() : isRightSidebarOpenFromDom(frame, rightbar);
7536
8233
  if (lastRightSidebarOpen !== isRightSidebarOpen) {
7537
8234
  lastRightSidebarOpen = isRightSidebarOpen;
7538
8235
  options?.onRightSidebarChange?.(isRightSidebarOpen);
@@ -7547,7 +8244,13 @@ window.__ModuleLoader__.load({
7547
8244
  attributeFilter: [
7548
8245
  "data-rightbar-collapsed",
7549
8246
  "data-sidebar-right-open",
7550
- "data-sidebar-right-panel"
8247
+ "data-sidebar-right-panel",
8248
+ "data-rightbar-col",
8249
+ "data-worktree-mode-action",
8250
+ "data-pane",
8251
+ "data-window-drag",
8252
+ "data-shell-leading",
8253
+ "data-shell-overlay"
7551
8254
  ]
7552
8255
  });
7553
8256
  } catch {
@@ -7591,11 +8294,21 @@ window.__ModuleLoader__.load({
7591
8294
  return nextElement;
7592
8295
  }
7593
8296
  function resolveNativeSidebarRoot(sidebar) {
7594
- const directChild = sidebar.firstElementChild;
7595
- if (directChild === null) return void 0;
7596
- const directRect = directChild.getBoundingClientRect();
7597
- if (directRect.width > 0 || directRect.height > 0) return directChild;
7598
- return directChild.firstElementChild ?? directChild;
8297
+ const newSession = findNewSessionAnchor(sidebar);
8298
+ const action = sidebar.querySelector("[data-worktree-mode-action]");
8299
+ if (!newSession || !action) return void 0;
8300
+ let candidate;
8301
+ for (let root = newSession.parentElement; root; root = root.parentElement) {
8302
+ const content = directChildWithin(root, newSession);
8303
+ const footer = directChildWithin(root, action);
8304
+ const rect = root.getBoundingClientRect();
8305
+ if (content && footer && content !== footer) {
8306
+ candidate ??= root;
8307
+ if (rect.width > 0 && rect.height > 0) return root;
8308
+ }
8309
+ if (root === sidebar) break;
8310
+ }
8311
+ return candidate;
7599
8312
  }
7600
8313
  function findNewSessionAnchor(root) {
7601
8314
  const labels = [
@@ -7614,7 +8327,8 @@ window.__ModuleLoader__.load({
7614
8327
  });
7615
8328
  const visibleLabel = buttons.find((button) => {
7616
8329
  const text = button.textContent?.trim();
7617
- return text === "新会话" || text === "New Session";
8330
+ if (!text) return false;
8331
+ return text.startsWith("新会话") || text.startsWith("New Session");
7618
8332
  });
7619
8333
  if (visibleLabel !== void 0) return visibleLabel;
7620
8334
  for (const label of labels) {
@@ -7622,13 +8336,36 @@ window.__ModuleLoader__.load({
7622
8336
  if (button !== void 0) return button;
7623
8337
  }
7624
8338
  }
8339
+ function sidebarFooterCandidate(root) {
8340
+ return directChildWithin(root, root.querySelector("[data-worktree-mode-action]"));
8341
+ }
8342
+ /** Resolve the footer slot semantically, then validate its content boundary. */
8343
+ function resolveSidebarFooter(root, newSession) {
8344
+ if (!newSession) return void 0;
8345
+ const children = Array.from(root.children);
8346
+ const content = directChildWithin(root, newSession);
8347
+ const start = content === void 0 ? -1 : children.indexOf(content);
8348
+ if (start < 0) return void 0;
8349
+ const anchorRect = asRect(newSession);
8350
+ const rootRect = asRect(root);
8351
+ const candidate = sidebarFooterCandidate(root);
8352
+ if (!candidate || children.indexOf(candidate) <= start) return void 0;
8353
+ const rect = asRect(candidate);
8354
+ return [
8355
+ anchorRect.top,
8356
+ anchorRect.bottom,
8357
+ rootRect.top,
8358
+ rootRect.bottom,
8359
+ rect.top,
8360
+ rect.bottom
8361
+ ].every(Number.isFinite) && anchorRect.bottom > anchorRect.top && rect.bottom > rect.top && rect.top >= anchorRect.bottom && rect.top >= rootRect.top && rect.bottom <= rootRect.bottom ? candidate : void 0;
8362
+ }
7625
8363
  /** Hide only the native content covered by the plugin, keeping chrome and footer alive. */
7626
8364
  function coveredSidebarChildren(root, newSession, footer) {
7627
8365
  if (!newSession || !footer) return [];
7628
- let first = newSession;
7629
- while (first.parentElement && first.parentElement !== root) first = first.parentElement;
8366
+ const first = directChildWithin(root, newSession);
7630
8367
  const children = Array.from(root.children ?? []);
7631
- const start = children.indexOf(first);
8368
+ const start = first === void 0 ? -1 : children.indexOf(first);
7632
8369
  const end = children.indexOf(footer);
7633
8370
  if (start < 0 || end <= start) return [];
7634
8371
  return children.slice(start, end).filter((element) => element instanceof HTMLElement);
@@ -7654,46 +8391,52 @@ window.__ModuleLoader__.load({
7654
8391
  (0, react.useLayoutEffect)(() => {
7655
8392
  if (!active) {
7656
8393
  setBounds(EMPTY_BOUNDS);
8394
+ setNativeCovered(false);
7657
8395
  return;
7658
8396
  }
7659
- const overlay = ref.current?.closest("[data-shell-overlay]");
8397
+ const surface = ref.current;
8398
+ const overlay = surface?.closest("[data-shell-overlay]");
7660
8399
  const frame = overlay?.parentElement;
7661
- const sidebar = frame?.firstElementChild;
7662
- const nativeRoot = sidebar === null || sidebar === void 0 ? void 0 : resolveNativeSidebarRoot(sidebar);
7663
- if (!(overlay instanceof HTMLElement) || !(sidebar instanceof HTMLElement) || !(nativeRoot instanceof HTMLElement)) {
8400
+ if (!(overlay instanceof HTMLElement) || !frame || !surface) {
7664
8401
  setBounds(EMPTY_BOUNDS);
7665
8402
  return;
7666
8403
  }
7667
8404
  const overlayElement = overlay;
7668
- const sidebarElement = sidebar;
7669
- const nativeRootElement = nativeRoot;
7670
8405
  let frameHandle;
8406
+ let disposed = false;
7671
8407
  let observedNewSession;
7672
8408
  let observedFooter;
7673
8409
  let observedRoot;
8410
+ let observedSidebar;
7674
8411
  const hidden = /* @__PURE__ */ new Map();
7675
8412
  function restore() {
7676
8413
  for (const cleanup of hidden.values()) cleanup();
7677
8414
  hidden.clear();
7678
8415
  }
7679
8416
  function update() {
7680
- const currentRoot = resolveNativeSidebarRoot(sidebarElement);
7681
- if (!(currentRoot instanceof HTMLElement) || overlayElement.isConnected === false || frame?.firstElementChild !== sidebarElement) {
8417
+ if (disposed) return;
8418
+ const anchors = resolveAppFrame(surface);
8419
+ const sidebarElement = anchors?.sidebar;
8420
+ const currentRoot = sidebarElement && resolveNativeSidebarRoot(sidebarElement);
8421
+ observedSidebar = syncObservedElement(resizeObserver, observedSidebar, sidebarElement);
8422
+ observedRoot = syncObservedElement(resizeObserver, observedRoot, currentRoot);
8423
+ const nextWidth = sidebarElement?.getBoundingClientRect().width;
8424
+ const nextCollapsed = frame?.hasAttribute("data-sidebar-collapsed") === true || nextWidth !== void 0 && nextWidth <= 64;
8425
+ setCollapsed(nextCollapsed);
8426
+ if (nextWidth !== void 0 && Number.isFinite(nextWidth)) setWidth(Math.max(0, nextWidth));
8427
+ if (anchors?.frame !== frame || anchors?.overlay !== overlayElement || !(currentRoot instanceof HTMLElement) || !sidebarElement || nextWidth === void 0 || !Number.isFinite(nextWidth)) {
8428
+ observedNewSession = syncObservedElement(resizeObserver, observedNewSession, void 0);
8429
+ observedFooter = syncObservedElement(resizeObserver, observedFooter, void 0);
7682
8430
  restore();
7683
8431
  setNativeCovered(false);
7684
8432
  setBounds(EMPTY_BOUNDS);
7685
8433
  return;
7686
8434
  }
7687
- observedRoot = syncObservedElement(resizeObserver, observedRoot, currentRoot);
7688
8435
  const newSession = findNewSessionAnchor(currentRoot);
7689
- const footer = currentRoot.lastElementChild;
8436
+ const footer = resolveSidebarFooter(currentRoot, newSession);
7690
8437
  observedNewSession = syncObservedElement(resizeObserver, observedNewSession, newSession);
7691
- observedFooter = syncObservedElement(resizeObserver, observedFooter, footer);
7692
- const nextWidth = sidebarElement.getBoundingClientRect().width;
7693
- setWidth(Math.max(0, nextWidth));
7694
- const nextCollapsed = frame?.hasAttribute("data-sidebar-collapsed") === true || nextWidth <= 64;
7695
- setCollapsed(nextCollapsed);
7696
- const nextBounds = computeOverlayBounds(asRect(overlayElement), newSession === void 0 ? void 0 : asRect(newSession), footer === null ? void 0 : asRect(footer));
8438
+ observedFooter = syncObservedElement(resizeObserver, observedFooter, sidebarFooterCandidate(currentRoot));
8439
+ const nextBounds = computeOverlayBounds(asRect(overlayElement), newSession === void 0 ? void 0 : asRect(newSession), footer === void 0 ? void 0 : asRect(footer));
7697
8440
  setBounds(nextCollapsed ? EMPTY_BOUNDS : nextBounds);
7698
8441
  const covered = !nextCollapsed && nextBounds.ready && nextBounds.height > 0 ? coveredSidebarChildren(currentRoot, newSession, footer) : [];
7699
8442
  for (const [element, cleanup] of hidden) if (!covered.includes(element)) {
@@ -7704,28 +8447,31 @@ window.__ModuleLoader__.load({
7704
8447
  setNativeCovered(covered.length > 0);
7705
8448
  }
7706
8449
  function scheduleUpdate() {
7707
- if (frameHandle !== void 0) return;
8450
+ if (disposed || frameHandle !== void 0) return;
7708
8451
  frameHandle = requestAnimationFrame(() => {
7709
8452
  frameHandle = void 0;
7710
8453
  update();
7711
8454
  });
7712
8455
  }
7713
8456
  const resizeObserver = typeof ResizeObserver === "function" ? new ResizeObserver(scheduleUpdate) : void 0;
7714
- for (const element of [
7715
- overlayElement,
7716
- sidebarElement,
7717
- nativeRootElement
7718
- ]) resizeObserver?.observe(element);
8457
+ for (const element of [overlayElement, frame]) resizeObserver?.observe(element);
7719
8458
  update();
7720
8459
  const mutationObserver = typeof MutationObserver === "function" ? new MutationObserver(scheduleUpdate) : void 0;
7721
8460
  mutationObserver?.observe(frame, {
7722
8461
  childList: true,
7723
8462
  subtree: true,
7724
8463
  attributes: true,
7725
- attributeFilter: ["data-sidebar-collapsed"]
8464
+ attributeFilter: [
8465
+ "data-sidebar-collapsed",
8466
+ "data-worktree-mode-action",
8467
+ "data-pane",
8468
+ "data-shell-overlay",
8469
+ "data-window-drag"
8470
+ ]
7726
8471
  });
7727
8472
  if (frame?.parentElement) mutationObserver?.observe(frame.parentElement, { childList: true });
7728
8473
  return () => {
8474
+ disposed = true;
7729
8475
  resizeObserver?.disconnect();
7730
8476
  mutationObserver?.disconnect();
7731
8477
  if (frameHandle !== void 0) cancelAnimationFrame(frameHandle);
@@ -7743,10 +8489,11 @@ window.__ModuleLoader__.load({
7743
8489
  //#endregion
7744
8490
  //#region lib/client/surface/state/useSurfaceSources.js
7745
8491
  function useSurfaceSources({ props }) {
7746
- const { useStore, available, manager, useSessions, useWorkspaces, forkRecovery, expandState, permissionNotice, fullAccessConfirmation, sessionOrder } = props;
8492
+ const { useStore, available, manager, useSessions, useSessionStatus, useWorkspaces, forkRecovery, expandState, permissionNotice, fullAccessConfirmation, sessionOrder } = props;
7747
8493
  const preferredMode = useStore((state) => state.viewMode);
7748
8494
  const mode = effectiveViewMode(preferredMode, available && manager !== void 0);
7749
8495
  const sessions = useSessions((state) => state);
8496
+ const sessionStatuses = useSessionStatus?.((state) => state);
7750
8497
  const workspaces = useWorkspaces((state) => state);
7751
8498
  const forkRecoveryStore = forkRecovery ?? EMPTY_FORK_RECOVERY_STORE;
7752
8499
  const forkRecoverySnapshot = (0, react.useSyncExternalStore)(forkRecoveryStore.subscribe, forkRecoveryStore.getSnapshot, forkRecoveryStore.getSnapshot);
@@ -7768,7 +8515,7 @@ window.__ModuleLoader__.load({
7768
8515
  setFullAccessAcknowledged(false);
7769
8516
  }, [fullAccessConfirmationKey]);
7770
8517
  const sessionOrderSnapshot = (0, react.useSyncExternalStore)(sessionOrder.subscribe, sessionOrder.getSnapshot, sessionOrder.getSnapshot);
7771
- const sessionPresentations = (0, react.useMemo)(() => deriveSessionPresentationIndex(sessions), [sessions.byId]);
8518
+ const sessionPresentations = (0, react.useMemo)(() => deriveSessionPresentationIndex(sessions, sessionStatuses), [sessions.byId, sessionStatuses]);
7772
8519
  const { ref, width, bounds, collapsed, nativeCovered } = useSidebarOverlayGeometry(mode === "worktree");
7773
8520
  return {
7774
8521
  preferredMode,
@@ -7906,14 +8653,16 @@ window.__ModuleLoader__.load({
7906
8653
  try {
7907
8654
  await createSessionCallback(sessionInput);
7908
8655
  } catch (error) {
7909
- if (error instanceof WorktreeSessionBindingError && error.retryable) setPendingSessionBinding({
8656
+ if (error instanceof WorktreeSessionBindingError) setPendingSessionBinding({
7910
8657
  ...sessionInput,
7911
- sessionId: error.sessionId
8658
+ sessionId: error.sessionId,
8659
+ error: toWorktreeViewError(error)
7912
8660
  });
7913
8661
  if (error instanceof WorktreeSessionPermissionError && error.retryable) setPendingSessionBinding({
7914
8662
  ...sessionInput,
7915
8663
  sessionId: error.sessionId,
7916
- permissionRequired: true
8664
+ permissionRequired: true,
8665
+ error: toWorktreeViewError(error)
7917
8666
  });
7918
8667
  throw error;
7919
8668
  }
@@ -8078,14 +8827,14 @@ window.__ModuleLoader__.load({
8078
8827
  };
8079
8828
  const defaultOpenInAppController = new OpenInAppController();
8080
8829
  //#endregion
8081
- //#region \0clutch-dsh-worktree-css:/Users/yuancheng/.dsh/clutch-dsh-worktree/worktree/wt_63cf54e5ec74/packages/clutch-dsh-worktree/src/client/dashboard/open-in-app.css.mjs
8082
- const css$2 = ".-cerbur-clutch-dsh-worktree-control {\n display: inline-flex;\n align-self: flex-end;\n}\n\n.-cerbur-clutch-dsh-worktree-split {\n display: inline-flex;\n align-items: stretch;\n box-sizing: border-box;\n height: 28px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 14px;\n overflow: hidden;\n font-family: var(--dsw-font-family);\n}\n\n.-cerbur-clutch-dsh-worktree-split .-cerbur-clutch-dsh-worktree-main,\n.-cerbur-clutch-dsh-worktree-split .-cerbur-clutch-dsh-worktree-chevron {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n border: 0;\n background: none;\n color: var(--dsw-alias-label-primary);\n font-size: 11px;\n font-weight: 400;\n line-height: 16px;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-main {\n padding: 5px 6px 5px 7px;\n}\n\n.-cerbur-clutch-dsh-worktree-main:hover:not(:disabled),\n.-cerbur-clutch-dsh-worktree-main:focus-visible,\n.-cerbur-clutch-dsh-worktree-chevron:hover,\n.-cerbur-clutch-dsh-worktree-chevron:focus-visible {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-main:disabled {\n color: var(--dsw-alias-label-dimmed);\n cursor: wait;\n}\n\n.-cerbur-clutch-dsh-worktree-main[data-state='error'] {\n color: var(--dsw-alias-state-error-primary, #e03e3e);\n box-shadow: inset 0 0 0 1px var(--dsw-alias-state-error-primary, #e03e3e);\n}\n\n.-cerbur-clutch-dsh-worktree-split .-cerbur-clutch-dsh-worktree-chevron {\n padding: 5px 6px 5px 4px;\n border-left: 0.5px solid var(--dsw-alias-border-l4);\n color: var(--dsw-alias-label-secondary);\n}\n\n.-cerbur-clutch-dsh-worktree-icon {\n flex: none;\n}\n\n.-cerbur-clutch-dsh-worktree-split .-cerbur-clutch-dsh-worktree-icon {\n width: 16px;\n height: 16px;\n}\n\n.-cerbur-clutch-dsh-worktree-split .-cerbur-clutch-dsh-worktree-chevron svg {\n width: 12px;\n height: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-fallback {\n text-decoration: none;\n align-self: flex-end;\n}\n\nimg.-cerbur-clutch-dsh-worktree-icon {\n display: block;\n object-fit: contain;\n user-select: none;\n}\n";
8083
- const styleId$2 = "@cerbur/clutch-dsh-worktree/open-in-app.css";
8830
+ //#region \0clutch-dsh-worktree-css:/Users/yuancheng/.dsh/clutch-dsh-worktree/worktree/wt_ece6fafadbd1/packages/clutch-dsh-worktree/src/client/dashboard/open-in-app.css.mjs
8831
+ const css$3 = ".-cerbur-clutch-dsh-worktree-control {\n display: inline-flex;\n align-self: flex-end;\n}\n\n.-cerbur-clutch-dsh-worktree-split {\n display: inline-flex;\n align-items: stretch;\n box-sizing: border-box;\n height: 28px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 14px;\n overflow: hidden;\n font-family: var(--dsw-font-family);\n}\n\n.-cerbur-clutch-dsh-worktree-split .-cerbur-clutch-dsh-worktree-main,\n.-cerbur-clutch-dsh-worktree-split .-cerbur-clutch-dsh-worktree-chevron {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n border: 0;\n background: none;\n color: var(--dsw-alias-label-primary);\n font-size: 11px;\n font-weight: 400;\n line-height: 16px;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-main {\n padding: 5px 6px 5px 7px;\n}\n\n.-cerbur-clutch-dsh-worktree-main:hover:not(:disabled),\n.-cerbur-clutch-dsh-worktree-main:focus-visible,\n.-cerbur-clutch-dsh-worktree-chevron:hover,\n.-cerbur-clutch-dsh-worktree-chevron:focus-visible {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-main:disabled {\n color: var(--dsw-alias-label-dimmed);\n cursor: wait;\n}\n\n.-cerbur-clutch-dsh-worktree-main[data-state='error'] {\n color: var(--dsw-alias-state-error-primary, #e03e3e);\n box-shadow: inset 0 0 0 1px var(--dsw-alias-state-error-primary, #e03e3e);\n}\n\n.-cerbur-clutch-dsh-worktree-split .-cerbur-clutch-dsh-worktree-chevron {\n padding: 5px 6px 5px 4px;\n border-left: 0.5px solid var(--dsw-alias-border-l4);\n color: var(--dsw-alias-label-secondary);\n}\n\n.-cerbur-clutch-dsh-worktree-icon {\n flex: none;\n}\n\n.-cerbur-clutch-dsh-worktree-split .-cerbur-clutch-dsh-worktree-icon {\n width: 16px;\n height: 16px;\n}\n\n.-cerbur-clutch-dsh-worktree-split .-cerbur-clutch-dsh-worktree-chevron svg {\n width: 12px;\n height: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-fallback {\n text-decoration: none;\n align-self: flex-end;\n}\n\nimg.-cerbur-clutch-dsh-worktree-icon {\n display: block;\n object-fit: contain;\n user-select: none;\n}\n";
8832
+ const styleId$3 = "@cerbur/clutch-dsh-worktree/open-in-app.css";
8084
8833
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@cerbur/clutch-dsh-worktree/open-in-app.css\"]") === null) {
8085
8834
  const tag = document.createElement("style");
8086
8835
  tag.dataset.plugin = "@cerbur/clutch-dsh-worktree";
8087
- tag.dataset.pluginCss = styleId$2;
8088
- tag.textContent = css$2;
8836
+ tag.dataset.pluginCss = styleId$3;
8837
+ tag.textContent = css$3;
8089
8838
  document.head.appendChild(tag);
8090
8839
  }
8091
8840
  var open_in_app_css_default = {
@@ -8289,14 +9038,14 @@ window.__ModuleLoader__.load({
8289
9038
  };
8290
9039
  }
8291
9040
  //#endregion
8292
- //#region \0clutch-dsh-worktree-css:/Users/yuancheng/.dsh/clutch-dsh-worktree/worktree/wt_63cf54e5ec74/packages/clutch-dsh-worktree/src/client/dashboard/dashboard.css.mjs
8293
- const css$1 = ".-cerbur-clutch-dsh-worktree-dashboardSurface {\n position: absolute;\n box-sizing: border-box;\n z-index: 2;\n overflow: auto;\n overscroll-behavior: contain;\n pointer-events: auto;\n container-type: inline-size;\n background: var(--dsw-alias-bg-base, #fff);\n color: var(--dsw-alias-label-primary, #19212f);\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n}\n\n.-cerbur-clutch-dsh-worktree-dashboardSurface *,\n.-cerbur-clutch-dsh-worktree-dashboardSurface *::before,\n.-cerbur-clutch-dsh-worktree-dashboardSurface *::after {\n box-sizing: border-box;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSurface button {\n font: inherit;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSurface svg {\n width: 18px;\n height: 18px;\n flex: none;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSurface code {\n font-family: ui-monospace, SFMono-Regular, Consolas, monospace;\n font-size: 12px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSurface button:focus-visible,\n.-cerbur-clutch-dsh-worktree-dashboardSurface a:focus-visible,\n.-cerbur-clutch-dsh-worktree-dashboardPanel:focus-visible {\n outline: 2px solid #497cd4;\n outline-offset: 3px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSurface h1:focus {\n outline: none;\n}\n.-cerbur-clutch-dsh-worktree-dashboardPage {\n max-width: 1240px;\n margin: 0 auto;\n padding: 24px 30px 28px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSessions {\n list-style: none;\n padding: 0;\n margin: 12px 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSessions button {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 12px 8px;\n border: 0;\n border-radius: 6px;\n background: transparent;\n color: inherit;\n text-align: left;\n cursor: pointer;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSessionLabel {\n flex: 1;\n min-width: 0;\n overflow-wrap: anywhere;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSessionMeta {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: flex-end;\n min-width: 28px;\n color: var(--dsw-alias-label-tertiary, #858e9d);\n}\n.-cerbur-clutch-dsh-worktree-dashboardSessionStatus {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSessionTime {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 12px;\n line-height: 20px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSessions button:hover,\n.-cerbur-clutch-dsh-worktree-dashboardSessions button[aria-current] {\n background: var(--dsw-alias-interactive-bg-hover, #f1f3f6);\n}\n.-cerbur-clutch-dsh-worktree-dashboardSurface a {\n text-decoration: none;\n}\n.-cerbur-clutch-dsh-worktree-dashboardStartActions button:not(:disabled) {\n cursor: pointer;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTopline {\n position: sticky;\n top: 0;\n z-index: 3;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: 8px 20px;\n min-height: 50px;\n padding: 10px 20px;\n border-bottom: 1px solid var(--dsw-alias-border-l3, #dfe3ea);\n background: var(--dsw-alias-bg-base, #fff);\n color: var(--dsw-alias-label-secondary, #677080);\n font-size: 13px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTopline > span {\n flex: 1 1 120px;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTopline > span > span {\n margin: 0 8px;\n opacity: 0.5;\n}\n.-cerbur-clutch-dsh-worktree-dashboardToplineActions {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n margin-inline-start: auto;\n max-width: 100%;\n -webkit-app-region: no-drag;\n}\n/* AppFrame's native reopen/New Session seat follows shell.-cerbur-clutch-dsh-worktree-overlay in DOM order.\n Keep its existing actions above the Dashboard, with its published clearance\n reserved in the title. This rule disappears as soon as the Dashboard closes. */\nhtml[data-platform='darwin']\n [data-sidebar-collapsed]:has([data-worktree-dashboard], [data-worktree-dashboard-request])\n > [data-shell-leading] {\n z-index: 21;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSidebarButton {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 6px;\n border: 0;\n border-radius: 28px;\n background: transparent;\n color: var(--dsw-alias-label-secondary, #677080);\n cursor: pointer;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSidebarButton:hover {\n background: var(--dsw-alias-interactive-bg-hover, #f1f3f6);\n}\n.-cerbur-clutch-dsh-worktree-dashboardSidebarButton svg {\n width: 15px;\n height: 15px;\n transform: scaleX(-1);\n}\n.-cerbur-clutch-dsh-worktree-dashboardHeader {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 225px;\n gap: 32px;\n margin-bottom: 15px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardIdentity {\n min-width: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTitleRow {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTitleRow > svg {\n width: 24px;\n height: 24px;\n color: #3e73ca;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTitleRow h1 {\n font-size: 25px;\n letter-spacing: -0.6px;\n line-height: 1.3;\n font-weight: 650;\n margin: 0;\n overflow-wrap: anywhere;\n min-width: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTitleRow[role='button'] {\n cursor: pointer;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTitleRow[role='button']:focus-visible {\n outline: 2px solid #497cd4;\n outline-offset: 3px;\n border-radius: 4px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardHealth,\n.-cerbur-clutch-dsh-worktree-dashboardSoon {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n white-space: nowrap;\n border-radius: 6px;\n padding: 3px 7px;\n font-size: 11px;\n font-weight: 500;\n color: var(--dsw-alias-label-secondary, #687182);\n background: var(--dsw-alias-interactive-bg-hover, #f1f3f6);\n}\n.-cerbur-clutch-dsh-worktree-dashboardHealth[data-health='ready'] {\n background: color-mix(in srgb, #1eab78 13%, transparent);\n color: #21976f;\n}\n.-cerbur-clutch-dsh-worktree-dashboardHealth[data-health='repair'],\n.-cerbur-clutch-dsh-worktree-dashboardHealth[data-health='recovery-needed'],\n.-cerbur-clutch-dsh-worktree-dashboardHealth[data-health='branch-drift'] {\n background: color-mix(in srgb, #e7a839 14%, transparent);\n color: #b27a1e;\n}\n.-cerbur-clutch-dsh-worktree-dashboardPath {\n display: flex;\n align-items: flex-start;\n gap: 9px;\n margin-top: 12px;\n color: var(--dsw-alias-label-secondary, #697283);\n}\n.-cerbur-clutch-dsh-worktree-dashboardPath code {\n padding-top: 4px;\n overflow-wrap: anywhere;\n min-width: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardFieldLabel {\n font-size: 10px;\n border: 1px solid var(--dsw-alias-border-l3, #e5e7ed);\n border-radius: 4px;\n padding: 2px 5px;\n margin-top: 2px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardIconButton {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 29px;\n height: 29px;\n border: 0;\n border-radius: 5px;\n background: transparent;\n color: inherit;\n cursor: pointer;\n}\n.-cerbur-clutch-dsh-worktree-dashboardIconButton:hover {\n background: var(--dsw-alias-interactive-bg-hover, #f1f3f6);\n}\n.-cerbur-clutch-dsh-worktree-dashboardCopyStatus {\n font-size: 12px;\n margin: 4px 0 0;\n min-height: 18px;\n color: #21976f;\n}\n.-cerbur-clutch-dsh-worktree-dashboardCopyStatus[role='alert'] {\n color: #bd5d43;\n}\n.-cerbur-clutch-dsh-worktree-dashboardHeaderAside {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: 8px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardHeaderAside > button,\n.-cerbur-clutch-dsh-worktree-dashboardHeaderAside > a {\n align-self: flex-end;\n}\n.-cerbur-clutch-dsh-worktree-dashboardButton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 7px;\n padding: 6px 11px;\n border: 1px solid var(--dsw-alias-border-l3, #dfe3ea);\n border-radius: 6px;\n background: var(--dsw-alias-bg-base, #fff);\n color: inherit;\n white-space: nowrap;\n cursor: pointer;\n font-size: 12px !important;\n line-height: 1.5;\n}\n.-cerbur-clutch-dsh-worktree-dashboardButton:disabled {\n color: var(--dsw-alias-label-secondary, #737e8e);\n cursor: not-allowed;\n}\n.-cerbur-clutch-dsh-worktree-dashboardButton:not(:disabled):hover {\n background: var(--dsw-alias-interactive-bg-hover, #f4f6f9);\n}\n.-cerbur-clutch-dsh-worktree-dashboardTabs {\n display: flex;\n gap: 22px;\n overflow-x: auto;\n border-bottom: 1px solid var(--dsw-alias-border-l3, #e1e5ed);\n margin-bottom: 24px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTabs button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n gap: 8px;\n padding: 12px 2px;\n border: 0;\n border-bottom: 2px solid transparent;\n background: transparent;\n color: var(--dsw-alias-label-secondary, #6c7480);\n cursor: pointer;\n font-size: 13px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTabs button[aria-selected='true'] {\n color: #4276c8;\n border-bottom-color: #4276c8;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTabs svg {\n width: 16px;\n height: 16px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardPanel {\n min-width: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardGrid {\n display: grid;\n grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);\n gap: 20px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardColumn {\n display: flex;\n flex-direction: column;\n gap: 20px;\n min-width: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardCard,\n.-cerbur-clutch-dsh-worktree-dashboardStart {\n padding: 20px;\n border: 1px solid var(--dsw-alias-border-l3, #e5e8ef);\n border-radius: 11px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardCard h2,\n.-cerbur-clutch-dsh-worktree-dashboardStart h2 {\n display: flex;\n align-items: center;\n gap: 9px;\n font-size: 16px;\n font-weight: 620;\n line-height: 1.4;\n margin: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardCard p,\n.-cerbur-clutch-dsh-worktree-dashboardStart > p {\n font-size: 12px;\n color: var(--dsw-alias-label-secondary, #7b8290);\n margin: 8px 0 15px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardCardHeading {\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-wrap: wrap;\n gap: 10px;\n margin-bottom: 7px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardStart {\n background: linear-gradient(\n 115deg,\n color-mix(in srgb, #6b9eff 9%, transparent),\n color-mix(in srgb, #6b9eff 3%, transparent)\n );\n}\n.-cerbur-clutch-dsh-worktree-dashboardStart h2 > svg {\n color: #477bc6;\n}\n.-cerbur-clutch-dsh-worktree-dashboardStartActions {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 13px;\n margin-top: 23px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardStartActions button {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 18px 14px;\n text-align: left;\n border: 1px solid color-mix(in srgb, #7299e7 28%, transparent);\n border-radius: 8px;\n background: color-mix(in srgb, #6b9eff 5%, transparent);\n color: #4673bc;\n cursor: not-allowed;\n min-width: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardStartActions button:nth-child(2) {\n color: #38846e;\n border-color: color-mix(in srgb, #4fba9a 25%, transparent);\n background: color-mix(in srgb, #4fba9a 5%, transparent);\n}\n.-cerbur-clutch-dsh-worktree-dashboardStartActions svg {\n width: 23px;\n height: 23px;\n margin-top: 3px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardStartActions strong {\n display: block;\n font-size: 14px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardStartActions small {\n display: block;\n margin-top: 6px;\n line-height: 1.6;\n font-size: 12px;\n color: var(--dsw-alias-label-secondary, #69788a);\n}\n.-cerbur-clutch-dsh-worktree-dashboardStartActions em {\n display: block;\n font-size: 10px;\n font-style: normal;\n margin-top: 10px;\n opacity: 0.75;\n}\n.-cerbur-clutch-dsh-worktree-dashboardInstructionPlaceholder {\n padding: 26px 20px;\n min-height: 177px;\n border: 1px dashed var(--dsw-alias-border-l3, #dfe4ed);\n border-radius: 7px;\n background: var(--dsw-alias-interactive-bg-hover, #f7f8fa);\n text-align: center;\n}\n.-cerbur-clutch-dsh-worktree-dashboardInstructionPlaceholder > svg {\n display: block;\n margin: 0 auto 10px;\n width: 25px;\n height: 25px;\n color: #929cac;\n}\n.-cerbur-clutch-dsh-worktree-dashboardInstructionPlaceholder strong {\n font-size: 13px;\n font-weight: 500;\n}\n.-cerbur-clutch-dsh-worktree-dashboardInstructionPlaceholder p {\n max-width: 310px;\n margin: 7px auto 12px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardEmpty {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 78px;\n padding: 10px 8px;\n text-align: center;\n}\n.-cerbur-clutch-dsh-worktree-dashboardEmpty p {\n max-width: 300px;\n margin: 0;\n line-height: 1.7;\n}\n.-cerbur-clutch-dsh-worktree-dashboardFacts {\n margin: 8px 0 14px;\n font-size: 12px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardFacts > div {\n display: grid;\n grid-template-columns: minmax(90px, 0.85fr) minmax(0, 1fr) 29px;\n gap: 12px;\n align-items: center;\n padding: 11px 0;\n border-bottom: 1px solid var(--dsw-alias-border-l3, #eef0f5);\n}\n.-cerbur-clutch-dsh-worktree-dashboardFacts > div:last-child {\n border: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardFacts dt {\n grid-column: 1;\n min-width: 0;\n color: var(--dsw-alias-label-secondary, #788191);\n /* Prefer normal break points (including trailing `/` and `-`) first. */\n overflow-wrap: break-word;\n word-break: normal;\n}\n.-cerbur-clutch-dsh-worktree-dashboardFacts dd {\n grid-column: 2;\n min-width: 0;\n margin: 0;\n text-align: right;\n /* Only split an unbreakable value after natural opportunities are exhausted. */\n overflow-wrap: break-word;\n word-break: normal;\n}\n.-cerbur-clutch-dsh-worktree-dashboardFactAction {\n display: flex;\n grid-column: 3;\n align-items: center;\n justify-content: flex-end;\n min-width: 29px;\n min-height: 29px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardHeaderAside .-cerbur-clutch-dsh-worktree-dashboardFacts > div {\n padding: 4px 0;\n border: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardHistorical {\n color: var(--dsw-alias-label-secondary, #788191);\n}\n.-cerbur-clutch-dsh-worktree-dashboardIconButton:disabled {\n color: var(--dsw-alias-label-secondary, #788191);\n cursor: not-allowed;\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineModal {\n box-sizing: border-box;\n width: min(440px, calc(100vw - 48px));\n max-height: calc(100vh - 48px);\n max-height: calc(100dvh - 48px);\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineModalContent {\n box-sizing: border-box;\n min-height: 0;\n overflow-y: auto;\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselinePicker {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 8px;\n width: 100%;\n min-width: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineSearch {\n box-sizing: border-box;\n flex: none;\n display: flex;\n width: 100%;\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineOptions {\n box-sizing: border-box;\n display: flex;\n flex: none;\n flex-direction: column;\n width: 100%;\n min-width: min(220px, 100%);\n max-width: min(420px, calc(100vw - 32px));\n /* Constant frame: six rows on compact windows, seven on normal ones. Search\n swaps the rows inside this fixed box, so the modal never resizes. */\n height: clamp(258px, 48vh, 300px);\n height: clamp(258px, 48dvh, 300px);\n padding: 4px;\n overflow-y: auto;\n overscroll-behavior: contain;\n border: 0;\n border-radius: 20px;\n background: var(--dsw-specific-menu, var(--dsw-alias-bg-layer-3, #fff));\n --dsw-elevation-stroke-color: var(--dsw-alias-border-l1);\n --dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2);\n --dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2);\n box-shadow: var(--dsw-elevation-prominent, 0 8px 24px rgb(25 33 47 / 12%));\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineList {\n display: flex;\n flex-direction: column;\n gap: 2px;\n width: 100%;\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineOption {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n min-height: 40px;\n padding: 8px 10px;\n border: 0;\n border-radius: 10px;\n outline: none;\n background: transparent;\n color: var(--dsw-alias-label-primary, #19212f);\n text-align: left;\n cursor: pointer;\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineOption:hover,\n.-cerbur-clutch-dsh-worktree-dashboardBaselineOption[data-highlighted='true'],\n.-cerbur-clutch-dsh-worktree-dashboardBaselineOption[aria-selected='true'] {\n background: var(--dsw-alias-interactive-bg-hover, #f0f3f8);\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineOption:focus-visible {\n outline: 2px solid #497cd4;\n outline-offset: -2px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineOption > svg {\n width: 16px;\n height: 16px;\n color: var(--dsw-alias-label-secondary, #788191);\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineOption[aria-selected='true'] > svg:last-child {\n color: var(--dsw-alias-label-primary, #19212f);\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineOptionLabel {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineEmpty {\n display: flex;\n flex: 1;\n align-items: center;\n justify-content: center;\n padding: 8px 10px;\n color: var(--dsw-alias-label-secondary, #788191);\n text-align: center;\n}\n/* Zero-height anchor: the save error floats over the list instead of growing\n the modal, so the frame keeps its size in every state. */\n.-cerbur-clutch-dsh-worktree-dashboardBaselineStatus {\n position: relative;\n box-sizing: border-box;\n min-height: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineError {\n position: absolute;\n right: 4px;\n bottom: 12px;\n left: 4px;\n z-index: 1;\n box-sizing: border-box;\n padding: 6px 10px;\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-2, #fff);\n background: color-mix(\n in srgb,\n var(--dsw-alias-state-error-label, #bd5d43) 10%,\n var(--dsw-alias-bg-layer-2, #fff)\n );\n box-shadow:\n inset 0 0 0 1px color-mix(in srgb, var(--dsw-alias-state-error-label, #bd5d43) 32%, transparent),\n var(--dsw-elevation-prominent, 0 8px 24px rgb(25 33 47 / 12%));\n color: var(--dsw-alias-state-error-label, #bd5d43);\n font-size: 12px;\n line-height: 16px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardLink {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n width: 100%;\n background: transparent;\n border: 1px solid var(--dsw-alias-border-l3, #e2e6ed);\n border-radius: 6px;\n padding: 7px 10px;\n font-size: 12px !important;\n color: inherit;\n cursor: pointer;\n margin-top: 8px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardLink:hover {\n background: var(--dsw-alias-interactive-bg-hover, #f5f7fa);\n}\n.-cerbur-clutch-dsh-worktree-dashboardQuickActions {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 16px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardQuickActions .-cerbur-clutch-dsh-worktree-dashboardButton {\n justify-content: flex-start;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTabPlaceholder {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 390px;\n padding: 40px 24px;\n text-align: center;\n border: 1px dashed var(--dsw-alias-border-l3, #dde3ec);\n border-radius: 11px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTabPlaceholder > svg {\n width: 36px;\n height: 36px;\n color: #7c9bcf;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTabPlaceholder h2 {\n font-size: 20px;\n font-weight: 600;\n margin: 16px 0 4px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTabPlaceholder p {\n max-width: 420px;\n font-size: 13px;\n color: var(--dsw-alias-label-secondary, #7b8596);\n margin: 8px 0 18px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardFooter {\n margin: 23px 0 0;\n text-align: center;\n font-size: 11px;\n color: var(--dsw-alias-label-secondary, #8a92a0);\n}\n\n@container (max-width: 820px) {\n .-cerbur-clutch-dsh-worktree-dashboardPage {\n padding: 20px;\n }\n .-cerbur-clutch-dsh-worktree-dashboardHeader {\n grid-template-columns: minmax(0, 1fr);\n gap: 12px;\n }\n .-cerbur-clutch-dsh-worktree-dashboardHeaderAside {\n display: flex;\n }\n .-cerbur-clutch-dsh-worktree-dashboardGrid {\n grid-template-columns: minmax(0, 1fr);\n }\n .-cerbur-clutch-dsh-worktree-dashboardTabs {\n gap: 18px;\n }\n}\n\n@container (max-width: 440px) {\n .-cerbur-clutch-dsh-worktree-dashboardPage {\n padding: 16px 12px;\n }\n .-cerbur-clutch-dsh-worktree-dashboardTitleRow h1 {\n font-size: 22px;\n }\n .-cerbur-clutch-dsh-worktree-dashboardStartActions {\n grid-template-columns: minmax(0, 1fr);\n }\n .-cerbur-clutch-dsh-worktree-dashboardCard,\n .-cerbur-clutch-dsh-worktree-dashboardStart {\n padding: 16px;\n }\n .-cerbur-clutch-dsh-worktree-dashboardTopline {\n gap: 10px;\n }\n}\n.-cerbur-clutch-dsh-worktree-dashboardInstructionsText {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n max-height: 240px;\n overflow: auto;\n}\n\n.-cerbur-clutch-dsh-worktree-dashboardInstructionsInput {\n box-sizing: border-box;\n width: 100%;\n resize: vertical;\n padding: 10px;\n border: 1px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n background: var(--dsw-alias-bg-base);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n}\n\n.-cerbur-clutch-dsh-worktree-dashboardInstructionActions {\n display: flex;\n gap: 8px;\n margin-top: 8px;\n}\n";
8294
- const styleId$1 = "@cerbur/clutch-dsh-worktree/dashboard.css";
9041
+ //#region \0clutch-dsh-worktree-css:/Users/yuancheng/.dsh/clutch-dsh-worktree/worktree/wt_ece6fafadbd1/packages/clutch-dsh-worktree/src/client/dashboard/dashboard.css.mjs
9042
+ const css$2 = ".-cerbur-clutch-dsh-worktree-dashboardSurface {\n position: absolute;\n box-sizing: border-box;\n z-index: 2;\n overflow: auto;\n overscroll-behavior: contain;\n pointer-events: auto;\n container-type: inline-size;\n background: var(--dsw-alias-bg-base, #fff);\n color: var(--dsw-alias-label-primary, #19212f);\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n}\n\n.-cerbur-clutch-dsh-worktree-dashboardSurface *,\n.-cerbur-clutch-dsh-worktree-dashboardSurface *::before,\n.-cerbur-clutch-dsh-worktree-dashboardSurface *::after {\n box-sizing: border-box;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSurface button {\n font: inherit;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSurface svg {\n width: 18px;\n height: 18px;\n flex: none;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSurface code {\n font-family: ui-monospace, SFMono-Regular, Consolas, monospace;\n font-size: 12px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSurface button:focus-visible,\n.-cerbur-clutch-dsh-worktree-dashboardSurface a:focus-visible,\n.-cerbur-clutch-dsh-worktree-dashboardPanel:focus-visible {\n outline: 2px solid #497cd4;\n outline-offset: 3px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSurface h1:focus {\n outline: none;\n}\n.-cerbur-clutch-dsh-worktree-dashboardPage {\n max-width: 1240px;\n margin: 0 auto;\n padding: 24px 30px 28px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSessions {\n list-style: none;\n padding: 0;\n margin: 12px 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSessions button {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 12px 8px;\n border: 0;\n border-radius: 6px;\n background: transparent;\n color: inherit;\n text-align: left;\n cursor: pointer;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSessionLabel {\n flex: 1;\n min-width: 0;\n overflow-wrap: anywhere;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSessionMeta {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: flex-end;\n min-width: 28px;\n color: var(--dsw-alias-label-tertiary, #858e9d);\n}\n.-cerbur-clutch-dsh-worktree-dashboardSessionStatus {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSessionTime {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 12px;\n line-height: 20px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSessions button:hover,\n.-cerbur-clutch-dsh-worktree-dashboardSessions button[aria-current] {\n background: var(--dsw-alias-interactive-bg-hover, #f1f3f6);\n}\n.-cerbur-clutch-dsh-worktree-dashboardSurface a {\n text-decoration: none;\n}\n.-cerbur-clutch-dsh-worktree-dashboardStartActions button:not(:disabled) {\n cursor: pointer;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTopline {\n position: sticky;\n top: 0;\n z-index: 3;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: 8px 20px;\n min-height: 50px;\n padding: 10px 20px;\n border-bottom: 1px solid var(--dsw-alias-border-l3, #dfe3ea);\n background: var(--dsw-alias-bg-base, #fff);\n color: var(--dsw-alias-label-secondary, #677080);\n font-size: 13px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTopline > span {\n flex: 1 1 120px;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTopline > span > span {\n margin: 0 8px;\n opacity: 0.5;\n}\n.-cerbur-clutch-dsh-worktree-dashboardToplineActions {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n margin-inline-start: auto;\n max-width: 100%;\n -webkit-app-region: no-drag;\n}\n/* AppFrame's native reopen/New Session seat follows shell.-cerbur-clutch-dsh-worktree-overlay in DOM order.\n Keep its existing actions above the Dashboard, with its published clearance\n reserved in the title. This rule disappears as soon as the Dashboard closes. */\nhtml[data-platform='darwin']\n [data-sidebar-collapsed]:has([data-worktree-dashboard], [data-worktree-dashboard-request])\n > [data-shell-leading] {\n z-index: 21;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSidebarButton {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 6px;\n border: 0;\n border-radius: 28px;\n background: transparent;\n color: var(--dsw-alias-label-secondary, #677080);\n cursor: pointer;\n}\n.-cerbur-clutch-dsh-worktree-dashboardSidebarButton:hover {\n background: var(--dsw-alias-interactive-bg-hover, #f1f3f6);\n}\n.-cerbur-clutch-dsh-worktree-dashboardSidebarButton svg {\n width: 15px;\n height: 15px;\n transform: scaleX(-1);\n}\n.-cerbur-clutch-dsh-worktree-dashboardHeader {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 225px;\n gap: 32px;\n margin-bottom: 15px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardIdentity {\n min-width: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTitleRow {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTitleRow > svg {\n width: 24px;\n height: 24px;\n color: #3e73ca;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTitleRow h1 {\n font-size: 25px;\n letter-spacing: -0.6px;\n line-height: 1.3;\n font-weight: 650;\n margin: 0;\n overflow-wrap: anywhere;\n min-width: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTitleRow[role='button'] {\n cursor: pointer;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTitleRow[role='button']:focus-visible {\n outline: 2px solid #497cd4;\n outline-offset: 3px;\n border-radius: 4px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardHealth,\n.-cerbur-clutch-dsh-worktree-dashboardSoon {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n white-space: nowrap;\n border-radius: 6px;\n padding: 3px 7px;\n font-size: 11px;\n font-weight: 500;\n color: var(--dsw-alias-label-secondary, #687182);\n background: var(--dsw-alias-interactive-bg-hover, #f1f3f6);\n}\n.-cerbur-clutch-dsh-worktree-dashboardHealth[data-health='ready'] {\n background: color-mix(in srgb, #1eab78 13%, transparent);\n color: #21976f;\n}\n.-cerbur-clutch-dsh-worktree-dashboardHealth[data-health='repair'],\n.-cerbur-clutch-dsh-worktree-dashboardHealth[data-health='recovery-needed'],\n.-cerbur-clutch-dsh-worktree-dashboardHealth[data-health='branch-drift'] {\n background: color-mix(in srgb, #e7a839 14%, transparent);\n color: #b27a1e;\n}\n.-cerbur-clutch-dsh-worktree-dashboardPath {\n display: flex;\n align-items: flex-start;\n gap: 9px;\n margin-top: 12px;\n color: var(--dsw-alias-label-secondary, #697283);\n}\n.-cerbur-clutch-dsh-worktree-dashboardPath code {\n padding-top: 4px;\n overflow-wrap: anywhere;\n min-width: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardFieldLabel {\n font-size: 10px;\n border: 1px solid var(--dsw-alias-border-l3, #e5e7ed);\n border-radius: 4px;\n padding: 2px 5px;\n margin-top: 2px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardIconButton {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 29px;\n height: 29px;\n border: 0;\n border-radius: 5px;\n background: transparent;\n color: inherit;\n cursor: pointer;\n}\n.-cerbur-clutch-dsh-worktree-dashboardIconButton:hover {\n background: var(--dsw-alias-interactive-bg-hover, #f1f3f6);\n}\n.-cerbur-clutch-dsh-worktree-dashboardCopyStatus {\n font-size: 12px;\n margin: 4px 0 0;\n min-height: 18px;\n color: #21976f;\n}\n.-cerbur-clutch-dsh-worktree-dashboardCopyStatus[role='alert'] {\n color: #bd5d43;\n}\n.-cerbur-clutch-dsh-worktree-dashboardHeaderAside {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: 8px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardHeaderAside > button,\n.-cerbur-clutch-dsh-worktree-dashboardHeaderAside > a {\n align-self: flex-end;\n}\n.-cerbur-clutch-dsh-worktree-dashboardButton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 7px;\n padding: 6px 11px;\n border: 1px solid var(--dsw-alias-border-l3, #dfe3ea);\n border-radius: 6px;\n background: var(--dsw-alias-bg-base, #fff);\n color: inherit;\n white-space: nowrap;\n cursor: pointer;\n font-size: 12px !important;\n line-height: 1.5;\n}\n.-cerbur-clutch-dsh-worktree-dashboardButton:disabled {\n color: var(--dsw-alias-label-secondary, #737e8e);\n cursor: not-allowed;\n}\n.-cerbur-clutch-dsh-worktree-dashboardButton:not(:disabled):hover {\n background: var(--dsw-alias-interactive-bg-hover, #f4f6f9);\n}\n.-cerbur-clutch-dsh-worktree-dashboardTabs {\n display: flex;\n gap: 22px;\n overflow-x: auto;\n border-bottom: 1px solid var(--dsw-alias-border-l3, #e1e5ed);\n margin-bottom: 24px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTabs button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n gap: 8px;\n padding: 12px 2px;\n border: 0;\n border-bottom: 2px solid transparent;\n background: transparent;\n color: var(--dsw-alias-label-secondary, #6c7480);\n cursor: pointer;\n font-size: 13px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTabs button[aria-selected='true'] {\n color: #4276c8;\n border-bottom-color: #4276c8;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTabs svg {\n width: 16px;\n height: 16px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardPanel {\n min-width: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardGrid {\n display: grid;\n grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);\n gap: 20px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardColumn {\n display: flex;\n flex-direction: column;\n gap: 20px;\n min-width: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardCard,\n.-cerbur-clutch-dsh-worktree-dashboardStart {\n padding: 20px;\n border: 1px solid var(--dsw-alias-border-l3, #e5e8ef);\n border-radius: 11px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardCard h2,\n.-cerbur-clutch-dsh-worktree-dashboardStart h2 {\n display: flex;\n align-items: center;\n gap: 9px;\n font-size: 16px;\n font-weight: 620;\n line-height: 1.4;\n margin: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardCard p,\n.-cerbur-clutch-dsh-worktree-dashboardStart > p {\n font-size: 12px;\n color: var(--dsw-alias-label-secondary, #7b8290);\n margin: 8px 0 15px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardCardHeading {\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-wrap: wrap;\n gap: 10px;\n margin-bottom: 7px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardStart {\n background: linear-gradient(\n 115deg,\n color-mix(in srgb, #6b9eff 9%, transparent),\n color-mix(in srgb, #6b9eff 3%, transparent)\n );\n}\n.-cerbur-clutch-dsh-worktree-dashboardStart h2 > svg {\n color: #477bc6;\n}\n.-cerbur-clutch-dsh-worktree-dashboardStartActions {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 13px;\n margin-top: 23px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardStartActions button {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 18px 14px;\n text-align: left;\n border: 1px solid color-mix(in srgb, #7299e7 28%, transparent);\n border-radius: 8px;\n background: color-mix(in srgb, #6b9eff 5%, transparent);\n color: #4673bc;\n cursor: not-allowed;\n min-width: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardStartActions button:nth-child(2) {\n color: #38846e;\n border-color: color-mix(in srgb, #4fba9a 25%, transparent);\n background: color-mix(in srgb, #4fba9a 5%, transparent);\n}\n.-cerbur-clutch-dsh-worktree-dashboardStartActions svg {\n width: 23px;\n height: 23px;\n margin-top: 3px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardStartActions strong {\n display: block;\n font-size: 14px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardStartActions small {\n display: block;\n margin-top: 6px;\n line-height: 1.6;\n font-size: 12px;\n color: var(--dsw-alias-label-secondary, #69788a);\n}\n.-cerbur-clutch-dsh-worktree-dashboardStartActions em {\n display: block;\n font-size: 10px;\n font-style: normal;\n margin-top: 10px;\n opacity: 0.75;\n}\n.-cerbur-clutch-dsh-worktree-dashboardInstructionPlaceholder {\n padding: 26px 20px;\n min-height: 177px;\n border: 1px dashed var(--dsw-alias-border-l3, #dfe4ed);\n border-radius: 7px;\n background: var(--dsw-alias-interactive-bg-hover, #f7f8fa);\n text-align: center;\n}\n.-cerbur-clutch-dsh-worktree-dashboardInstructionPlaceholder > svg {\n display: block;\n margin: 0 auto 10px;\n width: 25px;\n height: 25px;\n color: #929cac;\n}\n.-cerbur-clutch-dsh-worktree-dashboardInstructionPlaceholder strong {\n font-size: 13px;\n font-weight: 500;\n}\n.-cerbur-clutch-dsh-worktree-dashboardInstructionPlaceholder p {\n max-width: 310px;\n margin: 7px auto 12px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardEmpty {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 78px;\n padding: 10px 8px;\n text-align: center;\n}\n.-cerbur-clutch-dsh-worktree-dashboardEmpty p {\n max-width: 300px;\n margin: 0;\n line-height: 1.7;\n}\n.-cerbur-clutch-dsh-worktree-dashboardFacts {\n margin: 8px 0 14px;\n font-size: 12px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardFacts > div {\n display: grid;\n grid-template-columns: minmax(90px, 0.85fr) minmax(0, 1fr) 29px;\n gap: 12px;\n align-items: center;\n padding: 11px 0;\n border-bottom: 1px solid var(--dsw-alias-border-l3, #eef0f5);\n}\n.-cerbur-clutch-dsh-worktree-dashboardFacts > div:last-child {\n border: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardFacts dt {\n grid-column: 1;\n min-width: 0;\n color: var(--dsw-alias-label-secondary, #788191);\n /* Prefer normal break points (including trailing `/` and `-`) first. */\n overflow-wrap: break-word;\n word-break: normal;\n}\n.-cerbur-clutch-dsh-worktree-dashboardFacts dd {\n grid-column: 2;\n min-width: 0;\n margin: 0;\n text-align: right;\n /* Only split an unbreakable value after natural opportunities are exhausted. */\n overflow-wrap: break-word;\n word-break: normal;\n}\n.-cerbur-clutch-dsh-worktree-dashboardFactAction {\n display: flex;\n grid-column: 3;\n align-items: center;\n justify-content: flex-end;\n min-width: 29px;\n min-height: 29px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardHeaderAside .-cerbur-clutch-dsh-worktree-dashboardFacts > div {\n padding: 4px 0;\n border: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardHistorical {\n color: var(--dsw-alias-label-secondary, #788191);\n}\n.-cerbur-clutch-dsh-worktree-dashboardIconButton:disabled {\n color: var(--dsw-alias-label-secondary, #788191);\n cursor: not-allowed;\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineModal {\n box-sizing: border-box;\n width: min(440px, calc(100vw - 48px));\n max-height: calc(100vh - 48px);\n max-height: calc(100dvh - 48px);\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineModalContent {\n box-sizing: border-box;\n min-height: 0;\n overflow-y: auto;\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselinePicker {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 8px;\n width: 100%;\n min-width: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineSearch {\n box-sizing: border-box;\n flex: none;\n display: flex;\n width: 100%;\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineOptions {\n box-sizing: border-box;\n display: flex;\n flex: none;\n flex-direction: column;\n width: 100%;\n min-width: min(220px, 100%);\n max-width: min(420px, calc(100vw - 32px));\n /* Constant frame: six rows on compact windows, seven on normal ones. Search\n swaps the rows inside this fixed box, so the modal never resizes. */\n height: clamp(258px, 48vh, 300px);\n height: clamp(258px, 48dvh, 300px);\n padding: 4px;\n overflow-y: auto;\n overscroll-behavior: contain;\n border: 0;\n border-radius: 20px;\n background: var(--dsw-specific-menu, var(--dsw-alias-bg-layer-3, #fff));\n --dsw-elevation-stroke-color: var(--dsw-alias-border-l1);\n --dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2);\n --dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2);\n box-shadow: var(--dsw-elevation-prominent, 0 8px 24px rgb(25 33 47 / 12%));\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineList {\n display: flex;\n flex-direction: column;\n gap: 2px;\n width: 100%;\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineOption {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n min-height: 40px;\n padding: 8px 10px;\n border: 0;\n border-radius: 10px;\n outline: none;\n background: transparent;\n color: var(--dsw-alias-label-primary, #19212f);\n text-align: left;\n cursor: pointer;\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineOption:hover,\n.-cerbur-clutch-dsh-worktree-dashboardBaselineOption[data-highlighted='true'],\n.-cerbur-clutch-dsh-worktree-dashboardBaselineOption[aria-selected='true'] {\n background: var(--dsw-alias-interactive-bg-hover, #f0f3f8);\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineOption:focus-visible {\n outline: 2px solid #497cd4;\n outline-offset: -2px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineOption > svg {\n width: 16px;\n height: 16px;\n color: var(--dsw-alias-label-secondary, #788191);\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineOption[aria-selected='true'] > svg:last-child {\n color: var(--dsw-alias-label-primary, #19212f);\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineOptionLabel {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineEmpty {\n display: flex;\n flex: 1;\n align-items: center;\n justify-content: center;\n padding: 8px 10px;\n color: var(--dsw-alias-label-secondary, #788191);\n text-align: center;\n}\n/* Zero-height anchor: the save error floats over the list instead of growing\n the modal, so the frame keeps its size in every state. */\n.-cerbur-clutch-dsh-worktree-dashboardBaselineStatus {\n position: relative;\n box-sizing: border-box;\n min-height: 0;\n}\n.-cerbur-clutch-dsh-worktree-dashboardBaselineError {\n position: absolute;\n right: 4px;\n bottom: 12px;\n left: 4px;\n z-index: 1;\n box-sizing: border-box;\n padding: 6px 10px;\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-2, #fff);\n background: color-mix(\n in srgb,\n var(--dsw-alias-state-error-label, #bd5d43) 10%,\n var(--dsw-alias-bg-layer-2, #fff)\n );\n box-shadow:\n inset 0 0 0 1px color-mix(in srgb, var(--dsw-alias-state-error-label, #bd5d43) 32%, transparent),\n var(--dsw-elevation-prominent, 0 8px 24px rgb(25 33 47 / 12%));\n color: var(--dsw-alias-state-error-label, #bd5d43);\n font-size: 12px;\n line-height: 16px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardLink {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n width: 100%;\n background: transparent;\n border: 1px solid var(--dsw-alias-border-l3, #e2e6ed);\n border-radius: 6px;\n padding: 7px 10px;\n font-size: 12px !important;\n color: inherit;\n cursor: pointer;\n margin-top: 8px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardLink:hover {\n background: var(--dsw-alias-interactive-bg-hover, #f5f7fa);\n}\n.-cerbur-clutch-dsh-worktree-dashboardQuickActions {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 16px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardQuickActions .-cerbur-clutch-dsh-worktree-dashboardButton {\n justify-content: flex-start;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTabPlaceholder {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 390px;\n padding: 40px 24px;\n text-align: center;\n border: 1px dashed var(--dsw-alias-border-l3, #dde3ec);\n border-radius: 11px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTabPlaceholder > svg {\n width: 36px;\n height: 36px;\n color: #7c9bcf;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTabPlaceholder h2 {\n font-size: 20px;\n font-weight: 600;\n margin: 16px 0 4px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardTabPlaceholder p {\n max-width: 420px;\n font-size: 13px;\n color: var(--dsw-alias-label-secondary, #7b8596);\n margin: 8px 0 18px;\n}\n.-cerbur-clutch-dsh-worktree-dashboardFooter {\n margin: 23px 0 0;\n text-align: center;\n font-size: 11px;\n color: var(--dsw-alias-label-secondary, #8a92a0);\n}\n\n@container (max-width: 820px) {\n .-cerbur-clutch-dsh-worktree-dashboardPage {\n padding: 20px;\n }\n .-cerbur-clutch-dsh-worktree-dashboardHeader {\n grid-template-columns: minmax(0, 1fr);\n gap: 12px;\n }\n .-cerbur-clutch-dsh-worktree-dashboardHeaderAside {\n display: flex;\n }\n .-cerbur-clutch-dsh-worktree-dashboardGrid {\n grid-template-columns: minmax(0, 1fr);\n }\n .-cerbur-clutch-dsh-worktree-dashboardTabs {\n gap: 18px;\n }\n}\n\n@container (max-width: 440px) {\n .-cerbur-clutch-dsh-worktree-dashboardPage {\n padding: 16px 12px;\n }\n .-cerbur-clutch-dsh-worktree-dashboardTitleRow h1 {\n font-size: 22px;\n }\n .-cerbur-clutch-dsh-worktree-dashboardStartActions {\n grid-template-columns: minmax(0, 1fr);\n }\n .-cerbur-clutch-dsh-worktree-dashboardCard,\n .-cerbur-clutch-dsh-worktree-dashboardStart {\n padding: 16px;\n }\n .-cerbur-clutch-dsh-worktree-dashboardTopline {\n gap: 10px;\n }\n}\n.-cerbur-clutch-dsh-worktree-dashboardInstructionsText {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n max-height: 240px;\n overflow: auto;\n}\n\n.-cerbur-clutch-dsh-worktree-dashboardInstructionsInput {\n box-sizing: border-box;\n width: 100%;\n resize: vertical;\n padding: 10px;\n border: 1px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n background: var(--dsw-alias-bg-base);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n}\n\n.-cerbur-clutch-dsh-worktree-dashboardInstructionActions {\n display: flex;\n gap: 8px;\n margin-top: 8px;\n}\n";
9043
+ const styleId$2 = "@cerbur/clutch-dsh-worktree/dashboard.css";
8295
9044
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@cerbur/clutch-dsh-worktree/dashboard.css\"]") === null) {
8296
9045
  const tag = document.createElement("style");
8297
9046
  tag.dataset.plugin = "@cerbur/clutch-dsh-worktree";
8298
- tag.dataset.pluginCss = styleId$1;
8299
- tag.textContent = css$1;
9047
+ tag.dataset.pluginCss = styleId$2;
9048
+ tag.textContent = css$2;
8300
9049
  document.head.appendChild(tag);
8301
9050
  }
8302
9051
  var dashboard_css_default = {
@@ -8356,10 +9105,10 @@ window.__ModuleLoader__.load({
8356
9105
  };
8357
9106
  //#endregion
8358
9107
  //#region lib/client/dashboard/WorktreeInstructions.js
8359
- function WorktreeInstructions({ value, onSave, t, disabled }) {
9108
+ function WorktreeInstructions({ value, onSave, t, disabled, context }) {
8360
9109
  const [saved, setSaved] = (0, react.useState)(value);
8361
9110
  const [draft, setDraft] = (0, react.useState)();
8362
- const [error, setError] = (0, react.useState)(false);
9111
+ const [error, setError] = (0, react.useState)();
8363
9112
  const [pending, setPending] = (0, react.useState)(false);
8364
9113
  const busy = (0, react.useRef)(false);
8365
9114
  const alive = (0, react.useRef)(true);
@@ -8377,15 +9126,15 @@ window.__ModuleLoader__.load({
8377
9126
  if (busy.current || draft === void 0 || !onSave) return;
8378
9127
  busy.current = true;
8379
9128
  setPending(true);
8380
- setError(false);
9129
+ setError(void 0);
8381
9130
  try {
8382
9131
  const result = await onSave(draft, expected.current);
8383
9132
  if (alive.current) {
8384
9133
  setSaved(result);
8385
9134
  setDraft(void 0);
8386
9135
  }
8387
- } catch {
8388
- if (alive.current) setError(true);
9136
+ } catch (cause) {
9137
+ if (alive.current) setError(toWorktreeViewError(cause));
8389
9138
  } finally {
8390
9139
  busy.current = false;
8391
9140
  if (alive.current) setPending(false);
@@ -8401,7 +9150,7 @@ window.__ModuleLoader__.load({
8401
9150
  onClick: () => {
8402
9151
  expected.current = saved;
8403
9152
  setDraft(saved);
8404
- setError(false);
9153
+ setError(void 0);
8405
9154
  },
8406
9155
  children: t("dashboard.edit")
8407
9156
  })] }) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
@@ -8428,15 +9177,31 @@ window.__ModuleLoader__.load({
8428
9177
  disabled: pending,
8429
9178
  onClick: () => {
8430
9179
  setDraft(void 0);
8431
- setError(false);
9180
+ setError(void 0);
8432
9181
  },
8433
9182
  children: t("dashboard.cancelInstructions")
8434
9183
  })]
8435
9184
  }),
8436
- error && (0, react_jsx_runtime.jsx)("p", {
8437
- role: "alert",
8438
- children: t("dashboard.instructionsSaveFailed")
8439
- })
9185
+ (0, react_jsx_runtime.jsx)(NotificationToasts, { notices: error === void 0 ? [] : [{
9186
+ key: JSON.stringify([
9187
+ "instructions",
9188
+ context,
9189
+ error.code,
9190
+ error.details
9191
+ ]),
9192
+ context,
9193
+ error,
9194
+ actions: [{
9195
+ label: t("action.retry"),
9196
+ disabled: pending || disabled,
9197
+ onClick: () => {
9198
+ save();
9199
+ }
9200
+ }],
9201
+ describe: (translate) => translate("dashboard.instructions") + " · " + (context ?? ""),
9202
+ message: (translate) => translate("dashboard.instructionsSaveFailed") + (error.code === "WORKTREE_VIEW_FAILED" ? "" : " " + formatWorktreeViewError(error, translate)),
9203
+ text: t("dashboard.instructionsSaveFailed") + (error.code === "WORKTREE_VIEW_FAILED" ? "" : " " + formatWorktreeViewError(error, t))
9204
+ }] })
8440
9205
  ] })] });
8441
9206
  }
8442
9207
  //#endregion
@@ -8581,14 +9346,14 @@ window.__ModuleLoader__.load({
8581
9346
  });
8582
9347
  }
8583
9348
  //#endregion
8584
- //#region \0clutch-dsh-worktree-css:/Users/yuancheng/.dsh/clutch-dsh-worktree/worktree/wt_63cf54e5ec74/packages/clutch-dsh-worktree/src/client/dashboard/git/worktree-git.css.mjs
8585
- const css = ".-cerbur-clutch-dsh-worktree-gitPanel {\n min-width: 0;\n min-height: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitPanelHeader {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 20px;\n margin-bottom: 18px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitPanelHeader h2 {\n margin: 0;\n font-size: 18px;\n font-weight: 620;\n}\n\n.-cerbur-clutch-dsh-worktree-gitPanelHeading {\n min-width: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselineSelector {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n margin-top: 10px;\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselineSelector select {\n min-width: 180px;\n max-width: min(360px, 60vw);\n padding: 5px 8px;\n border: 1px solid var(--dsw-alias-border-l3, #dfe3ea);\n border-radius: 6px;\n background: var(--dsw-alias-bg-base, #fff);\n color: var(--dsw-alias-label-primary, #273142);\n font: inherit;\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselineSelector select:disabled {\n cursor: wait;\n opacity: 0.7;\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselinePrompt {\n padding: 22px;\n border: 1px dashed var(--dsw-alias-border-l3, #dfe3ea);\n border-radius: 10px;\n background: var(--dsw-alias-bg-base, #fff);\n color: var(--dsw-alias-label-secondary, #6f7887);\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselinePrompt strong {\n display: block;\n margin-bottom: 6px;\n color: var(--dsw-alias-label-primary, #273142);\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselinePrompt p {\n margin: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselineFacts {\n display: flex;\n flex-wrap: wrap;\n gap: 8px 20px;\n margin: 10px 0 0;\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselineFacts > div {\n display: flex;\n gap: 6px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselineFacts dt::after {\n content: ':';\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselineFacts dd {\n margin: 0;\n color: var(--dsw-alias-label-primary, #273142);\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselineFacts code {\n margin-left: 4px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDerived {\n margin-left: 7px;\n color: var(--dsw-alias-state-warn-label, #9a6e22);\n}\n\n.-cerbur-clutch-dsh-worktree-gitRefresh {\n flex: none;\n padding: 6px 11px;\n border: 1px solid var(--dsw-alias-border-l3, #dfe3ea);\n border-radius: 6px;\n background: var(--dsw-alias-bg-base, #fff);\n color: inherit;\n cursor: pointer;\n font-size: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitRefresh:disabled {\n color: var(--dsw-alias-label-secondary, #7d8795);\n cursor: wait;\n}\n\n/*\n * One 3x3 grid carries both layouts: commit and changed-file panes sit around a\n * row divider, the diff sits beside them across a column divider. Wide layouts\n * place the stack in the left column, narrow layouts place all three panes on\n * three rows. Both shares are custom properties the dividers drag, and both are\n * clamped so each pane keeps a usable size.\n */\n.-cerbur-clutch-dsh-worktree-gitColumns {\n /* Keep the Git surface bounded by the viewport, never by its data volume. */\n --git-columns-height: clamp(360px, calc(100vh - 300px), 560px);\n --git-columns-height: clamp(360px, calc(100dvh - 300px), 560px);\n /* Leading-pane shares: the row divider and the column divider drag these. */\n --git-rows-top: 45%;\n --git-columns-left: 38%;\n display: grid;\n grid-template-columns:\n minmax(240px, min(var(--git-columns-left), calc(100% - 247px)))\n 7px\n minmax(240px, 1fr);\n grid-template-rows:\n minmax(140px, min(var(--git-rows-top), calc(100% - 147px)))\n 7px\n minmax(140px, 1fr);\n height: var(--git-columns-height);\n min-height: 0;\n border: 1px solid var(--dsw-alias-border-l3, #e5e8ef);\n border-radius: 10px;\n overflow: hidden;\n resize: none;\n}\n\n/* Wide: commits over changed files in the left column, diff down the right column. */\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-pane='commits'] {\n grid-area: 1 / 1;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='rows'] {\n grid-area: 2 / 1;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-pane='changed-files'] {\n grid-area: 3 / 1;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='columns'] {\n grid-area: 1 / 2 / -1 / 3;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-pane='diff'] {\n grid-area: 1 / 3 / -1 / -1;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnSplitter {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--dsw-alias-bg-base, #fff);\n touch-action: none;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnSplitter::before {\n content: '';\n border-radius: 999px;\n background: var(--dsw-alias-border-l2, #cbd2dc);\n transition: background 0.15s ease;\n}\n\n/* Widen the grab area without moving the visible divider line. */\n.-cerbur-clutch-dsh-worktree-gitColumnSplitter::after {\n content: '';\n position: absolute;\n}\n\n/* Both divider panes draw a full border box, so the pane above and the pane below\n (or the pane left and the pane right) are each closed by their own edge. */\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='rows'] {\n box-sizing: border-box;\n height: 7px;\n cursor: row-resize;\n border-top: 1px solid var(--dsw-alias-border-l3, #e5e8ef);\n border-bottom: 1px solid var(--dsw-alias-border-l3, #e5e8ef);\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='rows']::before {\n width: 30px;\n height: 2px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='rows']::after {\n inset: -3px 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='columns'] {\n box-sizing: border-box;\n width: 7px;\n cursor: col-resize;\n border-left: 1px solid var(--dsw-alias-border-l3, #e5e8ef);\n border-right: 1px solid var(--dsw-alias-border-l3, #e5e8ef);\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='columns']::before {\n width: 2px;\n height: 30px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='columns']::after {\n inset: 0 -3px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnSplitter:hover::before,\n.-cerbur-clutch-dsh-worktree-gitColumnSplitter:focus-visible::before,\n.-cerbur-clutch-dsh-worktree-gitColumnSplitter[data-dashboard-git-splitting='true']::before {\n background: var(--dsw-alias-state-business-primary, #467bc8);\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnSplitter:focus-visible {\n outline: 2px solid #497cd4;\n outline-offset: -2px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumn {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex-direction: column;\n overflow: hidden;\n background: var(--dsw-alias-bg-base, #fff);\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnHeader {\n display: flex;\n flex: none;\n align-items: baseline;\n justify-content: space-between;\n gap: 8px;\n min-height: 43px;\n padding: 12px 13px 9px;\n border-bottom: 1px solid var(--dsw-alias-border-l3, #edf0f4);\n color: var(--dsw-alias-label-secondary, #6f7887);\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnHeader h3 {\n margin: 0;\n color: var(--dsw-alias-label-primary, #273142);\n font-size: 12px;\n font-weight: 620;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnHeader span,\n.-cerbur-clutch-dsh-worktree-gitColumnHeader code {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 10px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnHeaderMeta {\n display: flex;\n min-width: 0;\n align-items: baseline;\n justify-content: flex-end;\n gap: 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnHeader .-cerbur-clutch-dsh-worktree-gitLineStats,\n.-cerbur-clutch-dsh-worktree-gitColumnHeader .-cerbur-clutch-dsh-worktree-gitLineStats > span {\n overflow: visible;\n text-overflow: clip;\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnHeaderUnknown {\n color: var(--dsw-alias-label-tertiary, #8a94a3);\n}\n\n/* Right side of the commits header: the truncation note and the multi-select switch. */\n.-cerbur-clutch-dsh-worktree-gitColumnHeaderControls {\n display: flex;\n min-width: 0;\n align-self: center;\n align-items: center;\n justify-content: flex-end;\n gap: 10px;\n}\n\n/*\n * A native checkbox owns the state, focus and keyboard behavior; the track and\n * thumb below are presentational and follow :checked through the sibling selector.\n */\n.-cerbur-clutch-dsh-worktree-gitCommitMultiSelect {\n position: relative;\n display: inline-flex;\n flex: none;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n user-select: none;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitMultiSelect input {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip-path: inset(50%);\n border: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitMultiSelectTrack {\n position: relative;\n display: block;\n flex: none;\n width: 24px;\n height: 14px;\n border-radius: 999px;\n background: var(--dsw-alias-border-l2, #cbd2dc);\n transition: background 0.15s ease;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitMultiSelectThumb {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: var(--dsw-alias-bg-base, #fff);\n box-shadow: 0 1px 2px rgb(15 23 42 / 25%);\n transition: transform 0.15s ease;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitMultiSelect input:checked + .-cerbur-clutch-dsh-worktree-gitCommitMultiSelectTrack {\n background: var(--dsw-alias-state-business-primary, #467bc8);\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitMultiSelect input:checked + .-cerbur-clutch-dsh-worktree-gitCommitMultiSelectTrack .-cerbur-clutch-dsh-worktree-gitCommitMultiSelectThumb {\n transform: translateX(10px);\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitMultiSelect input:focus-visible + .-cerbur-clutch-dsh-worktree-gitCommitMultiSelectTrack {\n outline: 2px solid #497cd4;\n outline-offset: 2px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryButton {\n display: flex;\n width: calc(100% - 10px);\n flex-direction: column;\n gap: 3px;\n margin: 5px;\n padding: 8px;\n border: 1px solid var(--dsw-alias-border-l3, #dfe3ea);\n border-radius: 6px;\n background: var(--dsw-alias-bg-base, #fff);\n color: var(--dsw-alias-label-primary, #273142);\n text-align: left;\n cursor: pointer;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryButton:hover,\n.-cerbur-clutch-dsh-worktree-gitSummaryButton[aria-pressed='true'] {\n border-color: var(--dsw-alias-state-business-primary, #467bc8);\n background: var(--dsw-alias-interactive-bg-hover, #f1f3f6);\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryButton span {\n font-size: 12px;\n font-weight: 620;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryButton small {\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 10px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryToggle {\n display: flex;\n align-items: flex-start;\n gap: 7px;\n width: calc(100% - 20px);\n margin: 3px 10px 8px;\n color: var(--dsw-alias-label-primary, #273142);\n cursor: pointer;\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryToggle input {\n flex: none;\n margin: 2px 0 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryToggle span {\n display: flex;\n min-width: 0;\n flex-direction: column;\n gap: 2px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryToggle strong {\n font-weight: 560;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryToggle small {\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 10px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryToggle input:disabled,\n.-cerbur-clutch-dsh-worktree-gitSummaryToggle:has(input:disabled) {\n cursor: wait;\n opacity: 0.65;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSelectionToolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 5px 10px;\n border-bottom: 1px solid var(--dsw-alias-border-l3, #edf0f4);\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 10px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSelectionToolbar button {\n border: 0;\n background: transparent;\n color: var(--dsw-alias-state-business-primary, #467bc8);\n cursor: pointer;\n font: inherit;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitList,\n.-cerbur-clutch-dsh-worktree-gitChangedFileList {\n display: block;\n flex: 1 1 auto;\n min-height: 0;\n overflow-x: hidden;\n overflow-y: auto;\n overscroll-behavior: contain;\n scrollbar-gutter: stable;\n list-style: none;\n padding: 5px;\n margin: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitChangedFileList {\n overflow-x: auto;\n}\n\n.-cerbur-clutch-dsh-worktree-gitChangedFileList > li,\n.-cerbur-clutch-dsh-worktree-gitChangedFileList .-cerbur-clutch-dsh-worktree-gitFolderChildren,\n.-cerbur-clutch-dsh-worktree-gitChangedFileList .-cerbur-clutch-dsh-worktree-gitFolderChildren > li {\n width: max-content;\n min-width: 100%;\n}\n\n.-cerbur-clutch-dsh-worktree-gitFolderChildren {\n list-style: none;\n padding: 0 0 0 12px;\n margin: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitChangedFileList .-cerbur-clutch-dsh-worktree-gitFolderButton {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 7px 8px;\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 11px;\n font-weight: 620;\n}\n\n.-cerbur-clutch-dsh-worktree-gitChangedFileList .-cerbur-clutch-dsh-worktree-gitFolderButton:hover,\n.-cerbur-clutch-dsh-worktree-gitChangedFileList .-cerbur-clutch-dsh-worktree-gitFolderButton:focus-visible {\n background: var(--dsw-alias-interactive-bg-hover, #f1f3f6);\n color: var(--dsw-alias-label-primary, #273142);\n}\n\n.-cerbur-clutch-dsh-worktree-gitFolderIcon {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n color: var(--dsw-alias-label-secondary, #6f7887);\n}\n\n.-cerbur-clutch-dsh-worktree-gitFolderIcon > svg {\n width: 16px;\n height: 16px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitFolderName {\n min-width: max-content;\n overflow: visible;\n text-overflow: clip;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitList button,\n.-cerbur-clutch-dsh-worktree-gitChangedFileList button {\n display: block;\n border: 0;\n border-radius: 6px;\n background: transparent;\n color: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitList button {\n display: grid;\n width: 100%;\n grid-template-columns: 15px minmax(0, 1fr);\n padding: 9px 8px;\n}\n\n/* Without the multi-select marks a row has a single column, so the subject and meta align with it. */\n.-cerbur-clutch-dsh-worktree-gitCommitList[data-dashboard-git-commit-multiselect='off'] button {\n grid-template-columns: minmax(0, 1fr);\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitList[data-dashboard-git-commit-multiselect='off'] .-cerbur-clutch-dsh-worktree-gitCommitSubject,\n.-cerbur-clutch-dsh-worktree-gitCommitList[data-dashboard-git-commit-multiselect='off'] .-cerbur-clutch-dsh-worktree-gitCommitMeta {\n grid-column: 1;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitSelectionMark {\n grid-row: 1 / span 2;\n color: var(--dsw-alias-state-business-primary, #467bc8);\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitList button:hover,\n.-cerbur-clutch-dsh-worktree-gitCommitList button[aria-selected='true'],\n.-cerbur-clutch-dsh-worktree-gitChangedFileList button:hover,\n.-cerbur-clutch-dsh-worktree-gitChangedFileList button[aria-selected='true'] {\n background: var(--dsw-alias-interactive-bg-hover, #f1f3f6);\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitList button[aria-selected='true'] {\n box-shadow: inset 2px 0 var(--dsw-alias-state-business-primary, #467bc8);\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitList button[data-dashboard-git-commit-kind='working-tree'] {\n background: var(--dsw-alias-state-warn-tertiary, #f8f5ed);\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitList button[data-dashboard-git-commit-kind='working-tree'][aria-selected='true'] {\n box-shadow: inset 2px 0 var(--dsw-alias-state-warn-primary, #b18435);\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitSubject {\n grid-column: 2;\n display: block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitMeta {\n grid-column: 2;\n display: flex;\n gap: 7px;\n margin-top: 4px;\n overflow: hidden;\n color: var(--dsw-alias-label-secondary, #7c8594);\n font-size: 10px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitMeta span,\n.-cerbur-clutch-dsh-worktree-gitCommitMeta time {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitMeta time {\n margin-left: auto;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitWorkingTree {\n color: var(--dsw-alias-state-warn-label, #8a6728);\n font-weight: 620;\n}\n\n.-cerbur-clutch-dsh-worktree-gitChangedFileList button {\n display: flex;\n width: max-content;\n min-width: 100%;\n box-sizing: border-box;\n align-items: flex-start;\n gap: 7px;\n padding: 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitFileIcon {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n color: var(--dsw-alias-label-secondary, #6f7887);\n}\n\n.-cerbur-clutch-dsh-worktree-gitFileIconGlyph {\n width: 16px;\n height: 16px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitFilePath {\n min-width: max-content;\n flex: 0 0 auto;\n overflow: visible;\n text-overflow: clip;\n white-space: nowrap;\n font-family: ui-monospace, SFMono-Regular, Consolas, monospace;\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitFilePath[data-status='added'] {\n color: var(--dsw-alias-state-success-primary, #23845f);\n}\n\n.-cerbur-clutch-dsh-worktree-gitFilePath[data-status='deleted'] {\n color: var(--dsw-alias-state-error-secondary, #bd5d55);\n}\n\n.-cerbur-clutch-dsh-worktree-gitFilePath[data-status='modified'],\n.-cerbur-clutch-dsh-worktree-gitFilePath[data-status='renamed'],\n.-cerbur-clutch-dsh-worktree-gitFilePath[data-status='copied'],\n.-cerbur-clutch-dsh-worktree-gitFilePath[data-status='type-changed'] {\n color: var(--dsw-alias-state-business-primary, #467bc8);\n}\n\n.-cerbur-clutch-dsh-worktree-gitFileContributors {\n flex: none;\n max-width: 9em;\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary, #65758d);\n font-size: 9px;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-gitLineStats {\n display: inline-flex;\n flex: none;\n gap: 6px;\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-gitChangedFileList .-cerbur-clutch-dsh-worktree-gitLineStats {\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitLineAdded {\n color: var(--dsw-alias-state-success-primary, #23845f);\n font-weight: 620;\n}\n\n.-cerbur-clutch-dsh-worktree-gitLineRemoved {\n color: var(--dsw-alias-state-error-secondary, #bd5d55);\n font-weight: 620;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffContainer {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffToolbar {\n display: flex;\n flex: none;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 6px 12px;\n border-bottom: 1px solid var(--dsw-alias-border-l3, #edf0f4);\n background: var(--dsw-alias-bg-base, #ffffff);\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffPath {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: ui-monospace, SFMono-Regular, Consolas, monospace;\n color: var(--dsw-alias-label-primary, #263342);\n font-weight: 560;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffOpenInSidebar {\n display: inline-flex;\n flex: none;\n align-items: center;\n gap: 5px;\n padding: 3px 8px;\n border: 1px solid var(--dsw-alias-border-l3, #dfe3ea);\n border-radius: 4px;\n background: var(--dsw-alias-bg-base, #ffffff);\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 11px;\n line-height: 16px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n/* The square 16px arrow keeps its aspect ratio; pin the box so it centers on the label. */\n.-cerbur-clutch-dsh-worktree-gitDiffOpenIcon {\n flex: none;\n width: 14px;\n height: 14px;\n color: var(--dsw-alias-label-tertiary, #8a94a3);\n transition: color 0.15s ease;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffOpenInSidebar:hover {\n background: var(--dsw-alias-interactive-bg-hover, #f1f3f6);\n color: var(--dsw-alias-label-primary, #263342);\n border-color: var(--dsw-alias-border-l2, #cbd2dc);\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffOpenInSidebar:hover .-cerbur-clutch-dsh-worktree-gitDiffOpenIcon {\n color: var(--dsw-alias-label-primary, #263342);\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiff {\n display: block;\n flex: 1 1 auto;\n min-width: 0;\n min-height: 0;\n overflow: auto;\n padding: 7px 0 12px;\n background: var(--dsw-alias-markdown-code-block, #fafbfc);\n color: var(--dsw-alias-label-primary, #263342);\n font: 11px/1.65 ui-monospace, SFMono-Regular, Consolas, monospace;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffSegment {\n margin-bottom: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffSegmentHeader {\n padding: 5px 12px;\n border-bottom: 1px solid var(--dsw-alias-border-l3, #e5e8ef);\n background: var(--dsw-alias-interactive-bg-hover, #f1f3f6);\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 10px;\n font-weight: 620;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffSegmentHeader code {\n color: var(--dsw-alias-label-primary, #273142);\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffHunk {\n margin-bottom: 10px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffHunkHeader {\n padding: 3px 12px;\n background: var(--dsw-alias-markdown-code-block-banner, #edf3fb);\n color: var(--dsw-alias-state-business-primary, #4a70a1);\n box-shadow: inset 0 1px 0 var(--dsw-alias-border-l1, rgba(0, 0, 0, 0.04)), inset 0 -1px 0 var(--dsw-alias-border-l1, rgba(0, 0, 0, 0.04));\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffLine {\n display: grid;\n grid-template-columns: 44px 44px minmax(0, 1fr);\n min-width: max-content;\n padding-right: 12px;\n white-space: pre;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffLineadd {\n background: color-mix(\n in srgb,\n var(--dsw-alias-state-success-primary, #23845f) 18%,\n var(--dsw-alias-markdown-code-block, #fafbfc)\n );\n box-shadow: inset 2px 0 var(--dsw-alias-state-success-primary, #23845f);\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffLinedelete {\n background: color-mix(\n in srgb,\n var(--dsw-alias-state-error-secondary, #bd5d55) 18%,\n var(--dsw-alias-markdown-code-block, #fafbfc)\n );\n box-shadow: inset 2px 0 var(--dsw-alias-state-error-secondary, #bd5d55);\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffLineNumber {\n padding-right: 8px;\n color: var(--dsw-alias-label-tertiary, #9aa3af);\n text-align: right;\n user-select: none;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffLine code {\n min-width: 0;\n color: inherit;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSrOnly {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffEmpty,\n.-cerbur-clutch-dsh-worktree-gitDiffMessage,\n.-cerbur-clutch-dsh-worktree-gitEmpty,\n.-cerbur-clutch-dsh-worktree-gitLoading,\n.-cerbur-clutch-dsh-worktree-gitUnavailable,\n.-cerbur-clutch-dsh-worktree-gitError {\n padding: 24px 16px;\n color: var(--dsw-alias-label-secondary, #727d8d);\n font-size: 12px;\n text-align: center;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffMessage,\n.-cerbur-clutch-dsh-worktree-gitUnavailable {\n min-height: 150px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitUnavailable strong {\n display: block;\n margin-bottom: 7px;\n color: var(--dsw-alias-label-primary, #273142);\n font-size: 14px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitUnavailable p {\n max-width: 500px;\n margin: 0 auto;\n line-height: 1.7;\n}\n\n.-cerbur-clutch-dsh-worktree-gitError {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n padding: 9px 12px;\n color: var(--dsw-alias-state-error-primary, #ae5c4c);\n text-align: left;\n}\n\n.-cerbur-clutch-dsh-worktree-gitError p {\n margin: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitError button {\n flex: none;\n border: 1px solid currentColor;\n border-radius: 5px;\n background: transparent;\n color: inherit;\n cursor: pointer;\n font-size: 11px;\n padding: 3px 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffFolded {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 12px;\n border-top: 1px dashed var(--dsw-alias-border-l3, #dfe3ea);\n background: var(--dsw-alias-bg-base, #fff);\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffShowAll {\n padding: 2px 8px;\n border: 1px solid var(--dsw-alias-border-l3, #dfe3ea);\n border-radius: 6px;\n background: transparent;\n color: var(--dsw-alias-label-primary, #273142);\n cursor: pointer;\n font: inherit;\n}\n\n.-cerbur-clutch-dsh-worktree-gitRawDiff {\n display: block;\n flex: 1 1 auto;\n min-height: 0;\n max-height: none;\n overflow: auto;\n padding: 12px;\n margin: 0;\n white-space: pre;\n background: var(--dsw-alias-markdown-code-block, #fafbfc);\n color: var(--dsw-alias-label-primary, #263342);\n font: 11px/1.65 ui-monospace, SFMono-Regular, Consolas, monospace;\n}\n\n@container (min-width: 901px) {\n .-cerbur-clutch-dsh-worktree-gitColumns {\n /* Two stacked panes need more vertical room than three side-by-side panes. */\n --git-columns-height: clamp(440px, calc(100vh - 300px), 720px);\n --git-columns-height: clamp(440px, calc(100dvh - 300px), 720px);\n }\n}\n\n@container (max-width: 900px) {\n /* Narrow layout keeps the two-row arrangement: commits and changed files side by\n side on the first row, with the summary diff across the second row. Both\n dividers move with the panes, so either axis stays adjustable. */\n .-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-pane='commits'] {\n grid-area: 1 / 1;\n }\n .-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='columns'] {\n grid-area: 1 / 2;\n }\n .-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-pane='changed-files'] {\n grid-area: 1 / 3;\n }\n .-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='rows'] {\n grid-area: 2 / 1 / 3 / -1;\n }\n .-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-pane='diff'] {\n grid-area: 3 / 1 / -1 / -1;\n }\n}\n\n@container (max-width: 520px) {\n .-cerbur-clutch-dsh-worktree-gitPanelHeader {\n flex-direction: column;\n gap: 10px;\n }\n .-cerbur-clutch-dsh-worktree-gitRefresh {\n align-self: flex-end;\n }\n .-cerbur-clutch-dsh-worktree-gitColumns {\n display: block;\n height: auto;\n min-height: 0;\n }\n .-cerbur-clutch-dsh-worktree-gitColumnSplitter {\n display: none;\n }\n .-cerbur-clutch-dsh-worktree-gitColumn {\n height: clamp(260px, calc(100vh - 360px), 360px);\n height: clamp(260px, calc(100dvh - 360px), 360px);\n min-height: 260px;\n border-bottom: 1px solid var(--dsw-alias-border-l3, #e5e8ef);\n }\n .-cerbur-clutch-dsh-worktree-gitColumns > .-cerbur-clutch-dsh-worktree-gitColumn:last-child {\n border-bottom: 0;\n }\n}\n";
8586
- const styleId = "@cerbur/clutch-dsh-worktree/worktree-git.css";
9349
+ //#region \0clutch-dsh-worktree-css:/Users/yuancheng/.dsh/clutch-dsh-worktree/worktree/wt_ece6fafadbd1/packages/clutch-dsh-worktree/src/client/dashboard/git/worktree-git.css.mjs
9350
+ const css$1 = ".-cerbur-clutch-dsh-worktree-gitPanel {\n min-width: 0;\n min-height: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitPanelHeader {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 20px;\n margin-bottom: 18px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitPanelHeader h2 {\n margin: 0;\n font-size: 18px;\n font-weight: 620;\n}\n\n.-cerbur-clutch-dsh-worktree-gitPanelHeading {\n min-width: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselineSelector {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n margin-top: 10px;\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselineSelector select {\n min-width: 180px;\n max-width: min(360px, 60vw);\n padding: 5px 8px;\n border: 1px solid var(--dsw-alias-border-l3, #dfe3ea);\n border-radius: 6px;\n background: var(--dsw-alias-bg-base, #fff);\n color: var(--dsw-alias-label-primary, #273142);\n font: inherit;\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselineSelector select:disabled {\n cursor: wait;\n opacity: 0.7;\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselinePrompt {\n padding: 22px;\n border: 1px dashed var(--dsw-alias-border-l3, #dfe3ea);\n border-radius: 10px;\n background: var(--dsw-alias-bg-base, #fff);\n color: var(--dsw-alias-label-secondary, #6f7887);\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselinePrompt strong {\n display: block;\n margin-bottom: 6px;\n color: var(--dsw-alias-label-primary, #273142);\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselinePrompt p {\n margin: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselineFacts {\n display: flex;\n flex-wrap: wrap;\n gap: 8px 20px;\n margin: 10px 0 0;\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselineFacts > div {\n display: flex;\n gap: 6px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselineFacts dt::after {\n content: ':';\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselineFacts dd {\n margin: 0;\n color: var(--dsw-alias-label-primary, #273142);\n}\n\n.-cerbur-clutch-dsh-worktree-gitBaselineFacts code {\n margin-left: 4px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDerived {\n margin-left: 7px;\n color: var(--dsw-alias-state-warn-label, #9a6e22);\n}\n\n.-cerbur-clutch-dsh-worktree-gitRefresh {\n flex: none;\n padding: 6px 11px;\n border: 1px solid var(--dsw-alias-border-l3, #dfe3ea);\n border-radius: 6px;\n background: var(--dsw-alias-bg-base, #fff);\n color: inherit;\n cursor: pointer;\n font-size: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitRefresh:disabled {\n color: var(--dsw-alias-label-secondary, #7d8795);\n cursor: wait;\n}\n\n/*\n * One 3x3 grid carries both layouts: commit and changed-file panes sit around a\n * row divider, the diff sits beside them across a column divider. Wide layouts\n * place the stack in the left column, narrow layouts place all three panes on\n * three rows. Both shares are custom properties the dividers drag, and both are\n * clamped so each pane keeps a usable size.\n */\n.-cerbur-clutch-dsh-worktree-gitColumns {\n /* Keep the Git surface bounded by the viewport, never by its data volume. */\n --git-columns-height: clamp(360px, calc(100vh - 300px), 560px);\n --git-columns-height: clamp(360px, calc(100dvh - 300px), 560px);\n /* Leading-pane shares: the row divider and the column divider drag these. */\n --git-rows-top: 45%;\n --git-columns-left: 38%;\n display: grid;\n grid-template-columns:\n minmax(240px, min(var(--git-columns-left), calc(100% - 247px)))\n 7px\n minmax(240px, 1fr);\n grid-template-rows:\n minmax(140px, min(var(--git-rows-top), calc(100% - 147px)))\n 7px\n minmax(140px, 1fr);\n height: var(--git-columns-height);\n min-height: 0;\n border: 1px solid var(--dsw-alias-border-l3, #e5e8ef);\n border-radius: 10px;\n overflow: hidden;\n resize: none;\n}\n\n/* Wide: commits over changed files in the left column, diff down the right column. */\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-pane='commits'] {\n grid-area: 1 / 1;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='rows'] {\n grid-area: 2 / 1;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-pane='changed-files'] {\n grid-area: 3 / 1;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='columns'] {\n grid-area: 1 / 2 / -1 / 3;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-pane='diff'] {\n grid-area: 1 / 3 / -1 / -1;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnSplitter {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--dsw-alias-bg-base, #fff);\n touch-action: none;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnSplitter::before {\n content: '';\n border-radius: 999px;\n background: var(--dsw-alias-border-l2, #cbd2dc);\n transition: background 0.15s ease;\n}\n\n/* Widen the grab area without moving the visible divider line. */\n.-cerbur-clutch-dsh-worktree-gitColumnSplitter::after {\n content: '';\n position: absolute;\n}\n\n/* Both divider panes draw a full border box, so the pane above and the pane below\n (or the pane left and the pane right) are each closed by their own edge. */\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='rows'] {\n box-sizing: border-box;\n height: 7px;\n cursor: row-resize;\n border-top: 1px solid var(--dsw-alias-border-l3, #e5e8ef);\n border-bottom: 1px solid var(--dsw-alias-border-l3, #e5e8ef);\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='rows']::before {\n width: 30px;\n height: 2px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='rows']::after {\n inset: -3px 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='columns'] {\n box-sizing: border-box;\n width: 7px;\n cursor: col-resize;\n border-left: 1px solid var(--dsw-alias-border-l3, #e5e8ef);\n border-right: 1px solid var(--dsw-alias-border-l3, #e5e8ef);\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='columns']::before {\n width: 2px;\n height: 30px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='columns']::after {\n inset: 0 -3px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnSplitter:hover::before,\n.-cerbur-clutch-dsh-worktree-gitColumnSplitter:focus-visible::before,\n.-cerbur-clutch-dsh-worktree-gitColumnSplitter[data-dashboard-git-splitting='true']::before {\n background: var(--dsw-alias-state-business-primary, #467bc8);\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnSplitter:focus-visible {\n outline: 2px solid #497cd4;\n outline-offset: -2px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumn {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex-direction: column;\n overflow: hidden;\n background: var(--dsw-alias-bg-base, #fff);\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnHeader {\n display: flex;\n flex: none;\n align-items: baseline;\n justify-content: space-between;\n gap: 8px;\n min-height: 43px;\n padding: 12px 13px 9px;\n border-bottom: 1px solid var(--dsw-alias-border-l3, #edf0f4);\n color: var(--dsw-alias-label-secondary, #6f7887);\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnHeader h3 {\n margin: 0;\n color: var(--dsw-alias-label-primary, #273142);\n font-size: 12px;\n font-weight: 620;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnHeader span,\n.-cerbur-clutch-dsh-worktree-gitColumnHeader code {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 10px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnHeaderMeta {\n display: flex;\n min-width: 0;\n align-items: baseline;\n justify-content: flex-end;\n gap: 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnHeader .-cerbur-clutch-dsh-worktree-gitLineStats,\n.-cerbur-clutch-dsh-worktree-gitColumnHeader .-cerbur-clutch-dsh-worktree-gitLineStats > span {\n overflow: visible;\n text-overflow: clip;\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitColumnHeaderUnknown {\n color: var(--dsw-alias-label-tertiary, #8a94a3);\n}\n\n/* Right side of the commits header: the truncation note and the multi-select switch. */\n.-cerbur-clutch-dsh-worktree-gitColumnHeaderControls {\n display: flex;\n min-width: 0;\n align-self: center;\n align-items: center;\n justify-content: flex-end;\n gap: 10px;\n}\n\n/*\n * A native checkbox owns the state, focus and keyboard behavior; the track and\n * thumb below are presentational and follow :checked through the sibling selector.\n */\n.-cerbur-clutch-dsh-worktree-gitCommitMultiSelect {\n position: relative;\n display: inline-flex;\n flex: none;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n user-select: none;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitMultiSelect input {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip-path: inset(50%);\n border: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitMultiSelectTrack {\n position: relative;\n display: block;\n flex: none;\n width: 24px;\n height: 14px;\n border-radius: 999px;\n background: var(--dsw-alias-border-l2, #cbd2dc);\n transition: background 0.15s ease;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitMultiSelectThumb {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: var(--dsw-alias-bg-base, #fff);\n box-shadow: 0 1px 2px rgb(15 23 42 / 25%);\n transition: transform 0.15s ease;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitMultiSelect input:checked + .-cerbur-clutch-dsh-worktree-gitCommitMultiSelectTrack {\n background: var(--dsw-alias-state-business-primary, #467bc8);\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitMultiSelect input:checked + .-cerbur-clutch-dsh-worktree-gitCommitMultiSelectTrack .-cerbur-clutch-dsh-worktree-gitCommitMultiSelectThumb {\n transform: translateX(10px);\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitMultiSelect input:focus-visible + .-cerbur-clutch-dsh-worktree-gitCommitMultiSelectTrack {\n outline: 2px solid #497cd4;\n outline-offset: 2px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryButton {\n display: flex;\n width: calc(100% - 10px);\n flex-direction: column;\n gap: 3px;\n margin: 5px;\n padding: 8px;\n border: 1px solid var(--dsw-alias-border-l3, #dfe3ea);\n border-radius: 6px;\n background: var(--dsw-alias-bg-base, #fff);\n color: var(--dsw-alias-label-primary, #273142);\n text-align: left;\n cursor: pointer;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryButton:hover,\n.-cerbur-clutch-dsh-worktree-gitSummaryButton[aria-pressed='true'] {\n border-color: var(--dsw-alias-state-business-primary, #467bc8);\n background: var(--dsw-alias-interactive-bg-hover, #f1f3f6);\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryButton span {\n font-size: 12px;\n font-weight: 620;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryButton small {\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 10px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryToggle {\n display: flex;\n align-items: flex-start;\n gap: 7px;\n width: calc(100% - 20px);\n margin: 3px 10px 8px;\n color: var(--dsw-alias-label-primary, #273142);\n cursor: pointer;\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryToggle input {\n flex: none;\n margin: 2px 0 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryToggle span {\n display: flex;\n min-width: 0;\n flex-direction: column;\n gap: 2px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryToggle strong {\n font-weight: 560;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryToggle small {\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 10px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSummaryToggle input:disabled,\n.-cerbur-clutch-dsh-worktree-gitSummaryToggle:has(input:disabled) {\n cursor: wait;\n opacity: 0.65;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSelectionToolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 5px 10px;\n border-bottom: 1px solid var(--dsw-alias-border-l3, #edf0f4);\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 10px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSelectionToolbar button {\n border: 0;\n background: transparent;\n color: var(--dsw-alias-state-business-primary, #467bc8);\n cursor: pointer;\n font: inherit;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitList,\n.-cerbur-clutch-dsh-worktree-gitChangedFileList {\n display: block;\n flex: 1 1 auto;\n min-height: 0;\n overflow-x: hidden;\n overflow-y: auto;\n overscroll-behavior: contain;\n scrollbar-gutter: stable;\n list-style: none;\n padding: 5px;\n margin: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitChangedFileList {\n overflow-x: auto;\n}\n\n.-cerbur-clutch-dsh-worktree-gitChangedFileList > li,\n.-cerbur-clutch-dsh-worktree-gitChangedFileList .-cerbur-clutch-dsh-worktree-gitFolderChildren,\n.-cerbur-clutch-dsh-worktree-gitChangedFileList .-cerbur-clutch-dsh-worktree-gitFolderChildren > li {\n width: max-content;\n min-width: 100%;\n}\n\n.-cerbur-clutch-dsh-worktree-gitFolderChildren {\n list-style: none;\n padding: 0 0 0 12px;\n margin: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitChangedFileList .-cerbur-clutch-dsh-worktree-gitFolderButton {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 7px 8px;\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 11px;\n font-weight: 620;\n}\n\n.-cerbur-clutch-dsh-worktree-gitChangedFileList .-cerbur-clutch-dsh-worktree-gitFolderButton:hover,\n.-cerbur-clutch-dsh-worktree-gitChangedFileList .-cerbur-clutch-dsh-worktree-gitFolderButton:focus-visible {\n background: var(--dsw-alias-interactive-bg-hover, #f1f3f6);\n color: var(--dsw-alias-label-primary, #273142);\n}\n\n.-cerbur-clutch-dsh-worktree-gitFolderIcon {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n color: var(--dsw-alias-label-secondary, #6f7887);\n}\n\n.-cerbur-clutch-dsh-worktree-gitFolderIcon > svg {\n width: 16px;\n height: 16px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitFolderName {\n min-width: max-content;\n overflow: visible;\n text-overflow: clip;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitList button,\n.-cerbur-clutch-dsh-worktree-gitChangedFileList button {\n display: block;\n border: 0;\n border-radius: 6px;\n background: transparent;\n color: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitList button {\n display: grid;\n width: 100%;\n grid-template-columns: 15px minmax(0, 1fr);\n padding: 9px 8px;\n}\n\n/* Without the multi-select marks a row has a single column, so the subject and meta align with it. */\n.-cerbur-clutch-dsh-worktree-gitCommitList[data-dashboard-git-commit-multiselect='off'] button {\n grid-template-columns: minmax(0, 1fr);\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitList[data-dashboard-git-commit-multiselect='off'] .-cerbur-clutch-dsh-worktree-gitCommitSubject,\n.-cerbur-clutch-dsh-worktree-gitCommitList[data-dashboard-git-commit-multiselect='off'] .-cerbur-clutch-dsh-worktree-gitCommitMeta {\n grid-column: 1;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitSelectionMark {\n grid-row: 1 / span 2;\n color: var(--dsw-alias-state-business-primary, #467bc8);\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitList button:hover,\n.-cerbur-clutch-dsh-worktree-gitCommitList button[aria-selected='true'],\n.-cerbur-clutch-dsh-worktree-gitChangedFileList button:hover,\n.-cerbur-clutch-dsh-worktree-gitChangedFileList button[aria-selected='true'] {\n background: var(--dsw-alias-interactive-bg-hover, #f1f3f6);\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitList button[aria-selected='true'] {\n box-shadow: inset 2px 0 var(--dsw-alias-state-business-primary, #467bc8);\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitList button[data-dashboard-git-commit-kind='working-tree'] {\n background: var(--dsw-alias-state-warn-tertiary, #f8f5ed);\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitList button[data-dashboard-git-commit-kind='working-tree'][aria-selected='true'] {\n box-shadow: inset 2px 0 var(--dsw-alias-state-warn-primary, #b18435);\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitSubject {\n grid-column: 2;\n display: block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitMeta {\n grid-column: 2;\n display: flex;\n gap: 7px;\n margin-top: 4px;\n overflow: hidden;\n color: var(--dsw-alias-label-secondary, #7c8594);\n font-size: 10px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitMeta span,\n.-cerbur-clutch-dsh-worktree-gitCommitMeta time {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitMeta time {\n margin-left: auto;\n}\n\n.-cerbur-clutch-dsh-worktree-gitCommitWorkingTree {\n color: var(--dsw-alias-state-warn-label, #8a6728);\n font-weight: 620;\n}\n\n.-cerbur-clutch-dsh-worktree-gitChangedFileList button {\n display: flex;\n width: max-content;\n min-width: 100%;\n box-sizing: border-box;\n align-items: flex-start;\n gap: 7px;\n padding: 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitFileIcon {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n color: var(--dsw-alias-label-secondary, #6f7887);\n}\n\n.-cerbur-clutch-dsh-worktree-gitFileIconGlyph {\n width: 16px;\n height: 16px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitFilePath {\n min-width: max-content;\n flex: 0 0 auto;\n overflow: visible;\n text-overflow: clip;\n white-space: nowrap;\n font-family: ui-monospace, SFMono-Regular, Consolas, monospace;\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitFilePath[data-status='added'] {\n color: var(--dsw-alias-state-success-primary, #23845f);\n}\n\n.-cerbur-clutch-dsh-worktree-gitFilePath[data-status='deleted'] {\n color: var(--dsw-alias-state-error-secondary, #bd5d55);\n}\n\n.-cerbur-clutch-dsh-worktree-gitFilePath[data-status='modified'],\n.-cerbur-clutch-dsh-worktree-gitFilePath[data-status='renamed'],\n.-cerbur-clutch-dsh-worktree-gitFilePath[data-status='copied'],\n.-cerbur-clutch-dsh-worktree-gitFilePath[data-status='type-changed'] {\n color: var(--dsw-alias-state-business-primary, #467bc8);\n}\n\n.-cerbur-clutch-dsh-worktree-gitFileContributors {\n flex: none;\n max-width: 9em;\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary, #65758d);\n font-size: 9px;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-gitLineStats {\n display: inline-flex;\n flex: none;\n gap: 6px;\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-gitChangedFileList .-cerbur-clutch-dsh-worktree-gitLineStats {\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitLineAdded {\n color: var(--dsw-alias-state-success-primary, #23845f);\n font-weight: 620;\n}\n\n.-cerbur-clutch-dsh-worktree-gitLineRemoved {\n color: var(--dsw-alias-state-error-secondary, #bd5d55);\n font-weight: 620;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffContainer {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffToolbar {\n display: flex;\n flex: none;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 6px 12px;\n border-bottom: 1px solid var(--dsw-alias-border-l3, #edf0f4);\n background: var(--dsw-alias-bg-base, #ffffff);\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffPath {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: ui-monospace, SFMono-Regular, Consolas, monospace;\n color: var(--dsw-alias-label-primary, #263342);\n font-weight: 560;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffOpenInSidebar {\n display: inline-flex;\n flex: none;\n align-items: center;\n gap: 5px;\n padding: 3px 8px;\n border: 1px solid var(--dsw-alias-border-l3, #dfe3ea);\n border-radius: 4px;\n background: var(--dsw-alias-bg-base, #ffffff);\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 11px;\n line-height: 16px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n/* The square 16px arrow keeps its aspect ratio; pin the box so it centers on the label. */\n.-cerbur-clutch-dsh-worktree-gitDiffOpenIcon {\n flex: none;\n width: 14px;\n height: 14px;\n color: var(--dsw-alias-label-tertiary, #8a94a3);\n transition: color 0.15s ease;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffOpenInSidebar:hover {\n background: var(--dsw-alias-interactive-bg-hover, #f1f3f6);\n color: var(--dsw-alias-label-primary, #263342);\n border-color: var(--dsw-alias-border-l2, #cbd2dc);\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffOpenInSidebar:hover .-cerbur-clutch-dsh-worktree-gitDiffOpenIcon {\n color: var(--dsw-alias-label-primary, #263342);\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiff {\n display: block;\n flex: 1 1 auto;\n min-width: 0;\n min-height: 0;\n overflow: auto;\n padding: 7px 0 12px;\n background: var(--dsw-alias-markdown-code-block, #fafbfc);\n color: var(--dsw-alias-label-primary, #263342);\n font: 11px/1.65 ui-monospace, SFMono-Regular, Consolas, monospace;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffSegment {\n margin-bottom: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffSegmentHeader {\n padding: 5px 12px;\n border-bottom: 1px solid var(--dsw-alias-border-l3, #e5e8ef);\n background: var(--dsw-alias-interactive-bg-hover, #f1f3f6);\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 10px;\n font-weight: 620;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffSegmentHeader code {\n color: var(--dsw-alias-label-primary, #273142);\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffHunk {\n margin-bottom: 10px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffHunkHeader {\n padding: 3px 12px;\n background: var(--dsw-alias-markdown-code-block-banner, #edf3fb);\n color: var(--dsw-alias-state-business-primary, #4a70a1);\n box-shadow: inset 0 1px 0 var(--dsw-alias-border-l1, rgba(0, 0, 0, 0.04)), inset 0 -1px 0 var(--dsw-alias-border-l1, rgba(0, 0, 0, 0.04));\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffLine {\n display: grid;\n grid-template-columns: 44px 44px minmax(0, 1fr);\n min-width: max-content;\n padding-right: 12px;\n white-space: pre;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffLineadd {\n background: color-mix(\n in srgb,\n var(--dsw-alias-state-success-primary, #23845f) 18%,\n var(--dsw-alias-markdown-code-block, #fafbfc)\n );\n box-shadow: inset 2px 0 var(--dsw-alias-state-success-primary, #23845f);\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffLinedelete {\n background: color-mix(\n in srgb,\n var(--dsw-alias-state-error-secondary, #bd5d55) 18%,\n var(--dsw-alias-markdown-code-block, #fafbfc)\n );\n box-shadow: inset 2px 0 var(--dsw-alias-state-error-secondary, #bd5d55);\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffLineNumber {\n padding-right: 8px;\n color: var(--dsw-alias-label-tertiary, #9aa3af);\n text-align: right;\n user-select: none;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffLine code {\n min-width: 0;\n color: inherit;\n}\n\n.-cerbur-clutch-dsh-worktree-gitSrOnly {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffEmpty,\n.-cerbur-clutch-dsh-worktree-gitDiffMessage,\n.-cerbur-clutch-dsh-worktree-gitEmpty,\n.-cerbur-clutch-dsh-worktree-gitLoading,\n.-cerbur-clutch-dsh-worktree-gitUnavailable,\n.-cerbur-clutch-dsh-worktree-gitError {\n padding: 24px 16px;\n color: var(--dsw-alias-label-secondary, #727d8d);\n font-size: 12px;\n text-align: center;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffMessage,\n.-cerbur-clutch-dsh-worktree-gitUnavailable {\n min-height: 150px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitUnavailable strong {\n display: block;\n margin-bottom: 7px;\n color: var(--dsw-alias-label-primary, #273142);\n font-size: 14px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitUnavailable p {\n max-width: 500px;\n margin: 0 auto;\n line-height: 1.7;\n}\n\n.-cerbur-clutch-dsh-worktree-gitError {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n padding: 9px 12px;\n color: var(--dsw-alias-state-error-primary, #ae5c4c);\n text-align: left;\n}\n\n.-cerbur-clutch-dsh-worktree-gitError p {\n margin: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-gitError button {\n flex: none;\n border: 1px solid currentColor;\n border-radius: 5px;\n background: transparent;\n color: inherit;\n cursor: pointer;\n font-size: 11px;\n padding: 3px 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffFolded {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 12px;\n border-top: 1px dashed var(--dsw-alias-border-l3, #dfe3ea);\n background: var(--dsw-alias-bg-base, #fff);\n color: var(--dsw-alias-label-secondary, #6f7887);\n font-size: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitDiffShowAll {\n padding: 2px 8px;\n border: 1px solid var(--dsw-alias-border-l3, #dfe3ea);\n border-radius: 6px;\n background: transparent;\n color: var(--dsw-alias-label-primary, #273142);\n cursor: pointer;\n font: inherit;\n}\n\n.-cerbur-clutch-dsh-worktree-gitRawDiff {\n display: block;\n flex: 1 1 auto;\n min-height: 0;\n max-height: none;\n overflow: auto;\n padding: 12px;\n margin: 0;\n white-space: pre;\n background: var(--dsw-alias-markdown-code-block, #fafbfc);\n color: var(--dsw-alias-label-primary, #263342);\n font: 11px/1.65 ui-monospace, SFMono-Regular, Consolas, monospace;\n}\n\n@container (min-width: 901px) {\n .-cerbur-clutch-dsh-worktree-gitColumns {\n /* Two stacked panes need more vertical room than three side-by-side panes. */\n --git-columns-height: clamp(440px, calc(100vh - 300px), 720px);\n --git-columns-height: clamp(440px, calc(100dvh - 300px), 720px);\n }\n}\n\n@container (max-width: 900px) {\n /* Narrow layout keeps the two-row arrangement: commits and changed files side by\n side on the first row, with the summary diff across the second row. Both\n dividers move with the panes, so either axis stays adjustable. */\n .-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-pane='commits'] {\n grid-area: 1 / 1;\n }\n .-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='columns'] {\n grid-area: 1 / 2;\n }\n .-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-pane='changed-files'] {\n grid-area: 1 / 3;\n }\n .-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-splitter='rows'] {\n grid-area: 2 / 1 / 3 / -1;\n }\n .-cerbur-clutch-dsh-worktree-gitColumns > [data-dashboard-git-pane='diff'] {\n grid-area: 3 / 1 / -1 / -1;\n }\n}\n\n@container (max-width: 520px) {\n .-cerbur-clutch-dsh-worktree-gitPanelHeader {\n flex-direction: column;\n gap: 10px;\n }\n .-cerbur-clutch-dsh-worktree-gitRefresh {\n align-self: flex-end;\n }\n .-cerbur-clutch-dsh-worktree-gitColumns {\n display: block;\n height: auto;\n min-height: 0;\n }\n .-cerbur-clutch-dsh-worktree-gitColumnSplitter {\n display: none;\n }\n .-cerbur-clutch-dsh-worktree-gitColumn {\n height: clamp(260px, calc(100vh - 360px), 360px);\n height: clamp(260px, calc(100dvh - 360px), 360px);\n min-height: 260px;\n border-bottom: 1px solid var(--dsw-alias-border-l3, #e5e8ef);\n }\n .-cerbur-clutch-dsh-worktree-gitColumns > .-cerbur-clutch-dsh-worktree-gitColumn:last-child {\n border-bottom: 0;\n }\n}\n";
9351
+ const styleId$1 = "@cerbur/clutch-dsh-worktree/worktree-git.css";
8587
9352
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@cerbur/clutch-dsh-worktree/worktree-git.css\"]") === null) {
8588
9353
  const tag = document.createElement("style");
8589
9354
  tag.dataset.plugin = "@cerbur/clutch-dsh-worktree";
8590
- tag.dataset.pluginCss = styleId;
8591
- tag.textContent = css;
9355
+ tag.dataset.pluginCss = styleId$1;
9356
+ tag.textContent = css$1;
8592
9357
  document.head.appendChild(tag);
8593
9358
  }
8594
9359
  var worktree_git_css_default = {
@@ -9315,69 +10080,6 @@ window.__ModuleLoader__.load({
9315
10080
  }, [commitPercent, fallback])
9316
10081
  };
9317
10082
  }
9318
- Object.freeze([
9319
- "WORKSPACE_NOT_FOUND",
9320
- "WORKSPACE_ROOT_MISSING",
9321
- "WORKSPACE_NOT_GIT_REPOSITORY",
9322
- "GIT_NOT_INSTALLED",
9323
- "WORKTREE_REQUIRES_INITIAL_COMMIT",
9324
- "WORKTREE_BRANCH_CONFLICT",
9325
- "WORKTREE_NOT_FOUND",
9326
- "WORKTREE_ORDER_INVALID",
9327
- "WORKTREE_REMOVED",
9328
- "WORKTREE_IMPORT_INVALID",
9329
- "WORKTREE_ALREADY_MANAGED",
9330
- "SESSION_NOT_FOUND",
9331
- "SESSION_CWD_MISMATCH",
9332
- "SESSION_ALREADY_BOUND",
9333
- "SIDECAR_UNAVAILABLE",
9334
- "SIDECAR_CORRUPT",
9335
- "SIDECAR_SYNC_REQUIRED",
9336
- "GIT_OPERATION_FAILED",
9337
- "WORKTREE_MUTATION_BUSY",
9338
- "WORKTREE_STATE_CONFLICT",
9339
- "WORKTREE_RECOVERY_REQUIRED",
9340
- "WORKTREE_IDENTITY_CHANGED",
9341
- "WORKTREE_PERMISSION_BINDING_REQUIRED",
9342
- "WORKTREE_SESSION_BUSY",
9343
- "WORKTREE_ACTIVITY_UNAVAILABLE"
9344
- ]);
9345
- /** Stable synthetic commit id used for the current uncommitted working tree entry. */
9346
- const WORKTREE_GIT_WORKING_TREE = "working-tree";
9347
- /**
9348
- * Git object-name guard shared by the Contract, Provider, Manage and Client
9349
- * seams so commit-SHA validation cannot drift between layers. SHA-1 and SHA-256
9350
- * repository formats are both accepted.
9351
- */
9352
- const WORKTREE_GIT_COMMIT_PATTERN = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/iu;
9353
- /** True when the value is a full-length Git commit SHA. */
9354
- function isWorktreeGitCommit(value) {
9355
- return typeof value === "string" && WORKTREE_GIT_COMMIT_PATTERN.test(value);
9356
- }
9357
- Object.freeze([
9358
- "getWorktreeInstructions",
9359
- "updateWorktreeInstructions",
9360
- "updateWorktreeBaseBranch",
9361
- "listWorktrees",
9362
- "listWorktreeCommits",
9363
- "listWorktreeCommitFiles",
9364
- "getWorktreeCommitFileDiff",
9365
- "listImportCandidates",
9366
- "listBranches",
9367
- "createWorktree",
9368
- "importWorktree",
9369
- "removeWorktree",
9370
- "unarchiveWorktree",
9371
- "cleanWorktree",
9372
- "adoptWorktreeBranch",
9373
- "recoverWorktrees",
9374
- "forgetWorktree",
9375
- "insertWorktreeBefore",
9376
- "listBindings",
9377
- "bindSession",
9378
- "ensureWorktreePermission",
9379
- "normalizeDetachedWorktreePermissions"
9380
- ]);
9381
10083
  //#endregion
9382
10084
  //#region lib/client/dashboard/git/git-state-cache.js
9383
10085
  /** The summary selection for one working-tree inclusion mode. */
@@ -9455,7 +10157,7 @@ window.__ModuleLoader__.load({
9455
10157
  //#endregion
9456
10158
  //#region lib/client/dashboard/git/useWorktreeGitState.js
9457
10159
  function asError(error) {
9458
- return error instanceof Error ? error : new Error(String(error));
10160
+ return error instanceof Error ? error : Object.assign(new Error(toWorktreeViewError(error).message), toWorktreeViewError(error));
9459
10161
  }
9460
10162
  function normalizeBranch(branch) {
9461
10163
  const normalized = branch?.trim();
@@ -10228,7 +10930,7 @@ window.__ModuleLoader__.load({
10228
10930
  });
10229
10931
  }
10230
10932
  /** Git & Changes tab: read-only, on-demand history -> target files -> one-file diff. */
10231
- function WorktreeGitPanel({ manager, workspaceId, worktreeId, defaultBaselineBranch, currentBranch, capturedBaseline, onOpenFile, t }) {
10933
+ function WorktreeGitPanel({ manager, workspaceId, worktreeId, defaultBaselineBranch, currentBranch, context, capturedBaseline, onOpenFile, t }) {
10232
10934
  const isMain = isMainWorktreeId(worktreeId);
10233
10935
  const selectedDefaultBaseline = normalizeBaselineBranch(defaultBaselineBranch, currentBranch);
10234
10936
  const state = useWorktreeGitState({
@@ -10270,6 +10972,45 @@ window.__ModuleLoader__.load({
10270
10972
  className: worktree_git_css_default.gitPanel,
10271
10973
  "data-dashboard-git-panel": true,
10272
10974
  children: [
10975
+ (0, react_jsx_runtime.jsx)(NotificationToasts, { notices: [
10976
+ ["branches", branchError],
10977
+ ["history", state.history.status === "error" || state.history.status === "ready" ? state.history.error : void 0],
10978
+ ["files", state.files.status === "error" || state.files.status === "ready" ? state.files.error : void 0],
10979
+ ["diff", state.diff.status === "error" ? state.diff.error : void 0]
10980
+ ].flatMap(([scope, error]) => {
10981
+ if (!(error instanceof Error)) return [];
10982
+ const diagnostic = toWorktreeViewError(error);
10983
+ const text = formatWorktreeViewError(diagnostic, t);
10984
+ return [{
10985
+ key: JSON.stringify([
10986
+ workspaceId,
10987
+ worktreeId,
10988
+ scope,
10989
+ diagnostic.code,
10990
+ diagnostic.details
10991
+ ]),
10992
+ toastKey: failureToastKey(diagnostic, [workspaceId, worktreeId]),
10993
+ error: toWorktreeViewError(error),
10994
+ context: context ?? [
10995
+ currentBranch,
10996
+ workspaceId,
10997
+ worktreeId
10998
+ ].filter(Boolean).join(" · "),
10999
+ describe: (translate) => translate("settings.git", { operation: translate(scope === "branches" ? "dashboard.base" : scope === "history" ? "dashboard.git.commits" : scope === "files" ? "dashboard.git.changedFiles" : "dashboard.git.diff") }) + " · " + (context ?? [
11000
+ currentBranch,
11001
+ workspaceId,
11002
+ worktreeId
11003
+ ].filter(Boolean).join(" · ")),
11004
+ text,
11005
+ actions: [{
11006
+ label: t("dashboard.git.retry"),
11007
+ onClick: () => {
11008
+ if (scope === "branches") state.loadBranches();
11009
+ else state.refresh();
11010
+ }
11011
+ }]
11012
+ }];
11013
+ }) }),
10273
11014
  (0, react_jsx_runtime.jsxs)("header", {
10274
11015
  className: worktree_git_css_default.gitPanelHeader,
10275
11016
  children: [(0, react_jsx_runtime.jsxs)("div", {
@@ -10332,15 +11073,6 @@ window.__ModuleLoader__.load({
10332
11073
  children: refreshing ? t("dashboard.git.refreshing") : t("dashboard.git.refresh")
10333
11074
  })]
10334
11075
  }),
10335
- branchError !== void 0 && (0, react_jsx_runtime.jsxs)("div", {
10336
- className: worktree_git_css_default.gitError,
10337
- role: "alert",
10338
- children: [(0, react_jsx_runtime.jsx)("p", { children: t("dashboard.git.loadFailed", { reason: errorText(branchError, t) }) }), (0, react_jsx_runtime.jsx)("button", {
10339
- type: "button",
10340
- onClick: () => void state.loadBranches(),
10341
- children: t("dashboard.git.retry")
10342
- })]
10343
- }),
10344
11076
  !isMain && unavailable === "baseline-unselected" && (0, react_jsx_runtime.jsxs)("div", {
10345
11077
  className: worktree_git_css_default.gitBaselinePrompt,
10346
11078
  "data-dashboard-git-baseline-prompt": true,
@@ -10351,24 +11083,6 @@ window.__ModuleLoader__.load({
10351
11083
  role: "status",
10352
11084
  children: t("dashboard.git.loading")
10353
11085
  }),
10354
- state.history.status === "error" && (0, react_jsx_runtime.jsxs)("div", {
10355
- className: worktree_git_css_default.gitError,
10356
- role: "alert",
10357
- children: [(0, react_jsx_runtime.jsx)("p", { children: t("dashboard.git.loadFailed", { reason: errorText(state.history.error, t) }) }), (0, react_jsx_runtime.jsx)("button", {
10358
- type: "button",
10359
- onClick: () => void state.refresh(),
10360
- children: t("dashboard.git.retry")
10361
- })]
10362
- }),
10363
- state.history.status === "ready" && state.history.error !== void 0 && (0, react_jsx_runtime.jsxs)("div", {
10364
- className: worktree_git_css_default.gitError,
10365
- role: "alert",
10366
- children: [(0, react_jsx_runtime.jsx)("p", { children: t("dashboard.git.refreshFailed", { reason: errorText(state.history.error, t) }) }), (0, react_jsx_runtime.jsx)("button", {
10367
- type: "button",
10368
- onClick: () => void state.refresh(),
10369
- children: t("dashboard.git.retry")
10370
- })]
10371
- }),
10372
11086
  state.history.status === "ready" && historyValue !== void 0 && unavailable !== void 0 && (0, react_jsx_runtime.jsx)(UnavailableNotice, {
10373
11087
  reason: unavailable,
10374
11088
  t
@@ -10493,32 +11207,20 @@ window.__ModuleLoader__.load({
10493
11207
  className: worktree_git_css_default.gitLoading,
10494
11208
  role: "status",
10495
11209
  children: state.view === "summary" ? t("dashboard.git.loadingSummaryFiles") : t("dashboard.git.loadingFiles")
10496
- }) : state.files.status === "error" ? (0, react_jsx_runtime.jsx)("div", {
10497
- className: worktree_git_css_default.gitError,
10498
- role: "alert",
10499
- children: errorText(state.files.error, t)
10500
- }) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
10501
- state.files.status === "ready" && state.files.error !== void 0 && (0, react_jsx_runtime.jsx)("div", {
10502
- className: worktree_git_css_default.gitError,
10503
- role: "alert",
10504
- children: errorText(state.files.error, t)
10505
- }),
10506
- state.files.status === "ready" && state.files.value.truncated === true && (0, react_jsx_runtime.jsx)("div", {
10507
- className: worktree_git_css_default.gitEmpty,
10508
- role: "status",
10509
- "data-dashboard-git-files-truncated": true,
10510
- children: t("dashboard.git.truncatedFiles")
10511
- }),
10512
- files.length === 0 && !(state.files.status === "ready" && state.files.value.truncated === true) ? (0, react_jsx_runtime.jsx)("div", {
10513
- className: worktree_git_css_default.gitEmpty,
10514
- children: state.view === "summary" ? state.includeWorkingTree ? t("dashboard.git.noLiveBaselineChanges") : t("dashboard.git.noBaselineChanges") : t("dashboard.git.noFiles")
10515
- }) : (0, react_jsx_runtime.jsx)(GitChangedFiles, {
10516
- files,
10517
- selectedPath: state.selectedPath,
10518
- onSelect: state.selectPath,
10519
- t
10520
- })
10521
- ] })
11210
+ }) : state.files.status === "error" ? null : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [state.files.status === "ready" && state.files.value.truncated === true && (0, react_jsx_runtime.jsx)("div", {
11211
+ className: worktree_git_css_default.gitEmpty,
11212
+ role: "status",
11213
+ "data-dashboard-git-files-truncated": true,
11214
+ children: t("dashboard.git.truncatedFiles")
11215
+ }), files.length === 0 && !(state.files.status === "ready" && state.files.value.truncated === true) ? (0, react_jsx_runtime.jsx)("div", {
11216
+ className: worktree_git_css_default.gitEmpty,
11217
+ children: state.view === "summary" ? state.includeWorkingTree ? t("dashboard.git.noLiveBaselineChanges") : t("dashboard.git.noBaselineChanges") : t("dashboard.git.noFiles")
11218
+ }) : (0, react_jsx_runtime.jsx)(GitChangedFiles, {
11219
+ files,
11220
+ selectedPath: state.selectedPath,
11221
+ onSelect: state.selectPath,
11222
+ t
11223
+ })] })
10522
11224
  ]
10523
11225
  }),
10524
11226
  (0, react_jsx_runtime.jsx)(GitSplitter, {
@@ -10542,11 +11244,7 @@ window.__ModuleLoader__.load({
10542
11244
  className: worktree_git_css_default.gitLoading,
10543
11245
  role: "status",
10544
11246
  children: state.view === "summary" ? t("dashboard.git.loadingSummaryDiff") : t("dashboard.git.loadingDiff")
10545
- }) : state.diff.status === "error" ? (0, react_jsx_runtime.jsx)("div", {
10546
- className: worktree_git_css_default.gitError,
10547
- role: "alert",
10548
- children: errorText(state.diff.error, t)
10549
- }) : (0, react_jsx_runtime.jsx)(GitDiffView, {
11247
+ }) : state.diff.status === "error" ? null : (0, react_jsx_runtime.jsx)(GitDiffView, {
10550
11248
  diff,
10551
11249
  onOpenFile,
10552
11250
  t
@@ -10585,9 +11283,6 @@ window.__ModuleLoader__.load({
10585
11283
  onKeyDown: split.onKeyDown
10586
11284
  });
10587
11285
  }
10588
- function errorText(error, t) {
10589
- return error.message || t("dashboard.unknownError");
10590
- }
10591
11286
  //#endregion
10592
11287
  //#region lib/client/dashboard/git/WorktreeGitOverview.js
10593
11288
  function isWorkingTreeCommit(commit) {
@@ -10667,24 +11362,201 @@ window.__ModuleLoader__.load({
10667
11362
  ahead,
10668
11363
  behind
10669
11364
  })
10670
- });
10671
- }
10672
- if (state.history.unavailableReason !== void 0) return (0, react_jsx_runtime.jsx)("span", {
10673
- className: dashboard_css_default.dashboardHistorical,
10674
- children: t("dashboard.notConnected")
10675
- });
10676
- const totals = sumLineTotals(metric === "committed" ? state.committedFiles : state.workingTreeFiles);
10677
- if (totals === void 0) return (0, react_jsx_runtime.jsx)("span", {
10678
- className: dashboard_css_default.dashboardHistorical,
10679
- children: t("dashboard.unknown")
10680
- });
10681
- return (0, react_jsx_runtime.jsx)(GitLineStats, {
10682
- additions: totals.additions,
10683
- deletions: totals.deletions,
10684
- ariaLabel: t("dashboard.git.lineStats", {
10685
- additions: totals.additions,
10686
- deletions: totals.deletions
10687
- })
11365
+ });
11366
+ }
11367
+ if (state.history.unavailableReason !== void 0) return (0, react_jsx_runtime.jsx)("span", {
11368
+ className: dashboard_css_default.dashboardHistorical,
11369
+ children: t("dashboard.notConnected")
11370
+ });
11371
+ const totals = sumLineTotals(metric === "committed" ? state.committedFiles : state.workingTreeFiles);
11372
+ if (totals === void 0) return (0, react_jsx_runtime.jsx)("span", {
11373
+ className: dashboard_css_default.dashboardHistorical,
11374
+ children: t("dashboard.unknown")
11375
+ });
11376
+ return (0, react_jsx_runtime.jsx)(GitLineStats, {
11377
+ additions: totals.additions,
11378
+ deletions: totals.deletions,
11379
+ ariaLabel: t("dashboard.git.lineStats", {
11380
+ additions: totals.additions,
11381
+ deletions: totals.deletions
11382
+ })
11383
+ });
11384
+ }
11385
+ //#endregion
11386
+ //#region \0clutch-dsh-worktree-css:/Users/yuancheng/.dsh/clutch-dsh-worktree/worktree/wt_ece6fafadbd1/packages/clutch-dsh-worktree/src/client/settings/settings.css.mjs
11387
+ const css = ".-cerbur-clutch-dsh-worktree-settings {\n display: flex;\n flex-direction: column;\n gap: 12px;\n width: 100%;\n min-width: 0;\n max-width: 720px;\n color: var(--dsw-alias-label-primary);\n font-size: var(--dsh-content-font-size, 14px);\n line-height: calc(var(--dsh-content-font-size, 14px) + 8px);\n}\n\n[data-worktree-settings-nav-icon] > svg:not(.-cerbur-clutch-dsh-worktree-settingsNavIcon) {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-settingsNavIcon {\n order: -1;\n flex: 0 0 auto;\n width: 16px;\n height: 16px;\n}\n\n.-cerbur-clutch-dsh-worktree-toolSettings {\n display: flex;\n flex-direction: column;\n gap: 20px;\n min-width: 0;\n padding: 20px;\n border: 0.5px solid var(--dsw-alias-settings-card-stroke, var(--dsw-alias-border-l4));\n border-radius: var(--dsw-radius-xl, 16px);\n background: var(--dsw-alias-settings-card-fill, var(--dsw-alias-bg-layer-2));\n}\n\n.-cerbur-clutch-dsh-worktree-toolHeader,\n.-cerbur-clutch-dsh-worktree-toolRow {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 24px;\n}\n\n.-cerbur-clutch-dsh-worktree-toolHeader > div,\n.-cerbur-clutch-dsh-worktree-toolRow > div {\n min-width: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-toolTitle {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px;\n margin-bottom: 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-toolHeader h3 {\n margin: 0;\n font-size: calc(var(--dsh-content-font-size, 14px) + 2px);\n font-weight: 600;\n}\n\n.-cerbur-clutch-dsh-worktree-toolHeader p,\n.-cerbur-clutch-dsh-worktree-toolOptionsHeading p,\n.-cerbur-clutch-dsh-worktree-toolRow p {\n margin: 0;\n color: var(--dsw-alias-label-tertiary);\n font-size: var(--dsh-content-font-size-secondary, calc(var(--dsh-content-font-size, 14px) - 1px));\n line-height: 1.5;\n overflow-wrap: anywhere;\n}\n\n.-cerbur-clutch-dsh-worktree-toolOptions {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding-top: 20px;\n border-top: 0.5px solid var(--dsw-alias-settings-card-stroke, var(--dsw-alias-border-l4));\n}\n\n.-cerbur-clutch-dsh-worktree-toolOptionsHeading h4 {\n margin: 0 0 6px;\n color: var(--dsw-alias-label-secondary);\n font-size: var(--dsh-content-font-size, 14px);\n font-weight: 500;\n}\n\n.-cerbur-clutch-dsh-worktree-toolList {\n padding-left: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-toolRow {\n padding: 12px 0;\n}\n\n.-cerbur-clutch-dsh-worktree-toolRow + .-cerbur-clutch-dsh-worktree-toolRow {\n border-top: 0.5px solid var(--dsw-alias-border-l4);\n}\n\n.-cerbur-clutch-dsh-worktree-toolRow h5 {\n margin: 0 0 6px;\n font-size: var(--dsh-content-font-size, 14px);\n font-weight: 500;\n}\n\n.-cerbur-clutch-dsh-worktree-settingsTitle {\n margin: 0;\n font-size: calc(var(--dsh-content-font-size, 14px) + 2px);\n line-height: calc(var(--dsh-content-font-size, 14px) + 10px);\n font-weight: 500;\n}\n\n.-cerbur-clutch-dsh-worktree-settingsTabs {\n width: 100%;\n box-sizing: border-box;\n}\n\n/* Native controls keep their palette and keyboard behavior; text and control\n height follow the body's font-size preference even on older DSH themes. */\n.-cerbur-clutch-dsh-worktree-settings .-cerbur-clutch-dsh-worktree-settingsTabs [role='tab'] {\n height: auto;\n min-height: 34px;\n padding-block: 6px;\n font-size: inherit;\n line-height: calc(var(--dsh-content-font-size, 14px) + 6px);\n white-space: normal;\n overflow-wrap: anywhere;\n}\n\n.-cerbur-clutch-dsh-worktree-settingsPanel,\n.-cerbur-clutch-dsh-worktree-issueList {\n display: flex;\n flex-direction: column;\n min-width: 0;\n gap: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-issueList {\n gap: 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-settingsDescription,\n.-cerbur-clutch-dsh-worktree-settingsHint,\n.-cerbur-clutch-dsh-worktree-settingsEmpty,\n.-cerbur-clutch-dsh-worktree-issueMessage {\n margin: 0;\n overflow-wrap: anywhere;\n}\n\n.-cerbur-clutch-dsh-worktree-settingsDescription,\n.-cerbur-clutch-dsh-worktree-settingsHint,\n.-cerbur-clutch-dsh-worktree-settingsEmpty {\n color: var(--dsw-alias-label-tertiary);\n}\n\n.-cerbur-clutch-dsh-worktree-settingsHint {\n font-size: var(--dsh-content-font-size-secondary, calc(var(--dsh-content-font-size, 14px) - 1px));\n line-height: 1.5;\n}\n\n.-cerbur-clutch-dsh-worktree-settingsToolbar {\n display: flex;\n align-items: flex-start;\n flex-wrap: wrap;\n gap: 12px;\n padding: 16px 0;\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n.-cerbur-clutch-dsh-worktree-settingsToolbar > .-cerbur-clutch-dsh-worktree-settingsHint {\n flex: 1 1 240px;\n min-width: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-settingsEmpty {\n padding-block: 16px;\n}\n\n.-cerbur-clutch-dsh-worktree-issue {\n display: flex;\n flex-direction: column;\n gap: 10px;\n min-width: 0;\n padding: 12px 14px;\n border: 0.5px solid var(--dsw-alias-settings-card-stroke, var(--dsw-alias-border-l4));\n border-radius: var(--dsw-radius-xl, 16px);\n background: var(--dsw-alias-settings-card-fill, var(--dsw-alias-bg-layer-2));\n}\n\n.-cerbur-clutch-dsh-worktree-issueHeader {\n display: flex;\n align-items: baseline;\n flex-wrap: wrap;\n gap: 6px 10px;\n}\n\n.-cerbur-clutch-dsh-worktree-issueTitle {\n flex: 1 1 240px;\n min-width: 0;\n margin: 0;\n font-size: inherit;\n line-height: inherit;\n font-weight: 500;\n overflow-wrap: anywhere;\n}\n\n.-cerbur-clutch-dsh-worktree-settings .-cerbur-clutch-dsh-worktree-issueStatus,\n.-cerbur-clutch-dsh-worktree-settings .-cerbur-clutch-dsh-worktree-settingsAction {\n font-size: calc(var(--dsh-content-font-size, 14px) - 2px);\n line-height: calc(var(--dsh-content-font-size, 14px) + 4px);\n}\n\n.-cerbur-clutch-dsh-worktree-settings .-cerbur-clutch-dsh-worktree-settingsAction {\n flex: none;\n height: auto;\n min-height: 28px;\n padding-block: 4px;\n font-family: inherit;\n white-space: normal;\n overflow-wrap: anywhere;\n max-width: 100%;\n}\n\n.-cerbur-clutch-dsh-worktree-issueActions {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-issueDiagnostics {\n min-width: 0;\n padding-top: 10px;\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n.-cerbur-clutch-dsh-worktree-issueDiagnostics summary {\n width: fit-content;\n max-width: 100%;\n color: var(--dsw-alias-label-secondary);\n font-size: var(--dsh-content-font-size-secondary, calc(var(--dsh-content-font-size, 14px) - 1px));\n line-height: 1.5;\n cursor: pointer;\n overflow-wrap: anywhere;\n}\n\n.-cerbur-clutch-dsh-worktree-issueDiagnostics summary:focus-visible,\n.-cerbur-clutch-dsh-worktree-settings .-cerbur-clutch-dsh-worktree-settingsAction:focus-visible {\n outline: var(--dsw-focus-ring-width, 2px) solid\n var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n border-radius: var(--dsw-radius-xs, 4px);\n}\n\n.-cerbur-clutch-dsh-worktree-issueDiagnostics pre {\n box-sizing: border-box;\n max-width: 100%;\n max-height: 320px;\n overflow: auto;\n margin: 10px 0 0;\n padding: 10px 12px;\n border-radius: var(--dsw-radius-md, 12px);\n background: var(--dsw-alias-bg-module-platform);\n color: var(--dsw-alias-label-secondary);\n font-family: var(--ds-font-family-code, monospace);\n font-size: var(--dsh-content-font-size-secondary, calc(var(--dsh-content-font-size, 14px) - 1px));\n line-height: 1.5;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n user-select: text;\n}\n";
11388
+ const styleId = "@cerbur/clutch-dsh-worktree/settings.css";
11389
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@cerbur/clutch-dsh-worktree/settings.css\"]") === null) {
11390
+ const tag = document.createElement("style");
11391
+ tag.dataset.plugin = "@cerbur/clutch-dsh-worktree";
11392
+ tag.dataset.pluginCss = styleId;
11393
+ tag.textContent = css;
11394
+ document.head.appendChild(tag);
11395
+ }
11396
+ var settings_css_default = {
11397
+ "settings": "-cerbur-clutch-dsh-worktree-settings",
11398
+ "settingsNavIcon": "-cerbur-clutch-dsh-worktree-settingsNavIcon",
11399
+ "toolSettings": "-cerbur-clutch-dsh-worktree-toolSettings",
11400
+ "toolHeader": "-cerbur-clutch-dsh-worktree-toolHeader",
11401
+ "toolRow": "-cerbur-clutch-dsh-worktree-toolRow",
11402
+ "toolTitle": "-cerbur-clutch-dsh-worktree-toolTitle",
11403
+ "toolOptionsHeading": "-cerbur-clutch-dsh-worktree-toolOptionsHeading",
11404
+ "toolOptions": "-cerbur-clutch-dsh-worktree-toolOptions",
11405
+ "toolList": "-cerbur-clutch-dsh-worktree-toolList",
11406
+ "settingsTitle": "-cerbur-clutch-dsh-worktree-settingsTitle",
11407
+ "settingsTabs": "-cerbur-clutch-dsh-worktree-settingsTabs",
11408
+ "settingsPanel": "-cerbur-clutch-dsh-worktree-settingsPanel",
11409
+ "issueList": "-cerbur-clutch-dsh-worktree-issueList",
11410
+ "settingsDescription": "-cerbur-clutch-dsh-worktree-settingsDescription",
11411
+ "settingsHint": "-cerbur-clutch-dsh-worktree-settingsHint",
11412
+ "settingsEmpty": "-cerbur-clutch-dsh-worktree-settingsEmpty",
11413
+ "issueMessage": "-cerbur-clutch-dsh-worktree-issueMessage",
11414
+ "settingsToolbar": "-cerbur-clutch-dsh-worktree-settingsToolbar",
11415
+ "issue": "-cerbur-clutch-dsh-worktree-issue",
11416
+ "issueHeader": "-cerbur-clutch-dsh-worktree-issueHeader",
11417
+ "issueTitle": "-cerbur-clutch-dsh-worktree-issueTitle",
11418
+ "issueStatus": "-cerbur-clutch-dsh-worktree-issueStatus",
11419
+ "settingsAction": "-cerbur-clutch-dsh-worktree-settingsAction",
11420
+ "issueActions": "-cerbur-clutch-dsh-worktree-issueActions",
11421
+ "issueDiagnostics": "-cerbur-clutch-dsh-worktree-issueDiagnostics"
11422
+ };
11423
+ //#endregion
11424
+ //#region lib/client/settings/ToolSettings.js
11425
+ const capabilities = [
11426
+ "create",
11427
+ "worktrees",
11428
+ "delegate",
11429
+ "models",
11430
+ "sessions",
11431
+ "message"
11432
+ ];
11433
+ /** Both settings surfaces share persisted selections and never refresh Workspace projections. */
11434
+ function ToolSettings({ manager, scope, t }) {
11435
+ const [value, setValue] = (0, react.useState)();
11436
+ const [pending, setPending] = (0, react.useState)(false);
11437
+ const [failed, setFailed] = (0, react.useState)(false);
11438
+ const [revision, setRevision] = (0, react.useState)(0);
11439
+ const alive = (0, react.useRef)(false);
11440
+ const busy = (0, react.useRef)(false);
11441
+ const generation = (0, react.useRef)(0);
11442
+ (0, react.useEffect)(() => {
11443
+ alive.current = true;
11444
+ generation.current++;
11445
+ busy.current = false;
11446
+ setPending(false);
11447
+ let current = true;
11448
+ setFailed(false);
11449
+ if (!manager?.getToolSettings) setFailed(true);
11450
+ else manager.getToolSettings({ scope }).then((selection) => {
11451
+ if (current) setValue(selection);
11452
+ }, () => {
11453
+ if (current) setFailed(true);
11454
+ });
11455
+ return () => {
11456
+ current = false;
11457
+ alive.current = false;
11458
+ };
11459
+ }, [
11460
+ manager,
11461
+ JSON.stringify(scope),
11462
+ revision
11463
+ ]);
11464
+ const save = async (selection) => {
11465
+ if (!value || !manager?.updateToolSettings || busy.current) return;
11466
+ busy.current = true;
11467
+ const current = generation.current;
11468
+ setPending(true);
11469
+ setFailed(false);
11470
+ try {
11471
+ const result = await manager.updateToolSettings({
11472
+ scope,
11473
+ selection,
11474
+ expected: value
11475
+ });
11476
+ if (alive.current && current === generation.current) setValue(result);
11477
+ } catch {
11478
+ if (alive.current && current === generation.current) setFailed(true);
11479
+ } finally {
11480
+ if (current === generation.current) {
11481
+ busy.current = false;
11482
+ if (alive.current) setPending(false);
11483
+ }
11484
+ }
11485
+ };
11486
+ const auto = scope.kind !== "general";
11487
+ const local = scope.kind === "local";
11488
+ const title = t(auto ? "tools.auto" : "tools.command");
11489
+ return (0, react_jsx_runtime.jsxs)("section", {
11490
+ className: settings_css_default.toolSettings,
11491
+ "data-worktree-tool-settings": true,
11492
+ children: [
11493
+ (0, react_jsx_runtime.jsxs)("div", {
11494
+ className: settings_css_default.toolHeader,
11495
+ children: [(0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsxs)("div", {
11496
+ className: settings_css_default.toolTitle,
11497
+ children: [(0, react_jsx_runtime.jsx)("h3", { children: title }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tag, {
11498
+ tone: "info",
11499
+ children: t("tools.experimental")
11500
+ })]
11501
+ }), (0, react_jsx_runtime.jsx)("p", { children: t(local ? "tools.localAutoHint" : auto ? "tools.autoHint" : "tools.commandHint") })] }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
11502
+ label: title,
11503
+ checked: value?.enabled ?? false,
11504
+ disabled: !value || pending || failed,
11505
+ onChange: (enabled) => void save({
11506
+ enabled,
11507
+ tools: value.tools.length ? value.tools : WORKTREE_TOOL_IDS
11508
+ })
11509
+ })]
11510
+ }),
11511
+ !value && !failed && (0, react_jsx_runtime.jsx)("p", {
11512
+ role: "status",
11513
+ children: t("tools.loading")
11514
+ }),
11515
+ value?.enabled && (0, react_jsx_runtime.jsxs)("div", {
11516
+ className: settings_css_default.toolOptions,
11517
+ "data-worktree-tool-options": true,
11518
+ children: [(0, react_jsx_runtime.jsxs)("div", {
11519
+ className: settings_css_default.toolOptionsHeading,
11520
+ children: [(0, react_jsx_runtime.jsx)("h4", { children: t("tools.selection") }), (0, react_jsx_runtime.jsxs)("p", { children: [
11521
+ t(local ? "tools.localAutoSelectionHint" : auto ? "tools.autoSelectionHint" : "tools.commandSelectionHint"),
11522
+ " ",
11523
+ t("tools.runtimeHint"),
11524
+ auto && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
11525
+ " ",
11526
+ t("tools.commandSelectionHint"),
11527
+ " ",
11528
+ t("tools.reportHint")
11529
+ ] })
11530
+ ] })]
11531
+ }), (0, react_jsx_runtime.jsx)("div", {
11532
+ className: settings_css_default.toolList,
11533
+ children: WORKTREE_TOOL_IDS.map((tool, index) => (0, react_jsx_runtime.jsxs)("div", {
11534
+ className: settings_css_default.toolRow,
11535
+ children: [(0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)("h5", { children: t(`tools.${capabilities[index]}.title`) }), (0, react_jsx_runtime.jsx)("p", { children: t(`tools.${capabilities[index]}.hint`) })] }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
11536
+ label: t(`tools.${capabilities[index]}.title`),
11537
+ checked: value.tools.includes(tool),
11538
+ disabled: pending || failed,
11539
+ onChange: (checked) => {
11540
+ const tools = checked ? [...value.tools, tool] : value.tools.filter((id) => id !== tool);
11541
+ save({
11542
+ enabled: tools.length > 0,
11543
+ tools
11544
+ });
11545
+ }
11546
+ })]
11547
+ }, tool))
11548
+ })]
11549
+ }),
11550
+ failed && (0, react_jsx_runtime.jsxs)("div", {
11551
+ role: "alert",
11552
+ children: [(0, react_jsx_runtime.jsx)("p", { children: t("tools.failed") }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
11553
+ size: "sm",
11554
+ variant: "outline",
11555
+ onClick: () => setRevision((current) => current + 1),
11556
+ children: t("action.retry")
11557
+ })]
11558
+ })
11559
+ ]
10688
11560
  });
10689
11561
  }
10690
11562
  //#endregion
@@ -10747,12 +11619,12 @@ window.__ModuleLoader__.load({
10747
11619
  children
10748
11620
  });
10749
11621
  }
10750
- function WorktreeBaselineEditor({ value, branches, currentBranch, onSave, t, disabled }) {
11622
+ function WorktreeBaselineEditor({ value, branches, currentBranch, onSave, t, disabled, context }) {
10751
11623
  const [saved, setSaved] = (0, react.useState)(value);
10752
11624
  const [draft, setDraft] = (0, react.useState)();
10753
11625
  const [search, setSearch] = (0, react.useState)("");
10754
11626
  const [pending, setPending] = (0, react.useState)(false);
10755
- const [error, setError] = (0, react.useState)(false);
11627
+ const [error, setError] = (0, react.useState)();
10756
11628
  const busy = (0, react.useRef)(false);
10757
11629
  const alive = (0, react.useRef)(true);
10758
11630
  const optionRefs = (0, react.useRef)([]);
@@ -10779,13 +11651,13 @@ window.__ModuleLoader__.load({
10779
11651
  if (pending) return;
10780
11652
  setDraft(void 0);
10781
11653
  setSearch("");
10782
- setError(false);
11654
+ setError(void 0);
10783
11655
  };
10784
11656
  const openEditor = () => {
10785
11657
  expected.current = saved;
10786
11658
  setDraft(saved ?? "");
10787
11659
  setSearch("");
10788
- setError(false);
11660
+ setError(void 0);
10789
11661
  };
10790
11662
  const query = search.trim().toLowerCase();
10791
11663
  const filteredOptions = query.length === 0 ? options : options.filter((branch) => branch.name.toLowerCase().includes(query));
@@ -10816,7 +11688,7 @@ window.__ModuleLoader__.load({
10816
11688
  if (busy.current || draft === void 0 || onSave === void 0 || !options.some((branch) => branch.name === draft)) return;
10817
11689
  busy.current = true;
10818
11690
  setPending(true);
10819
- setError(false);
11691
+ setError(void 0);
10820
11692
  try {
10821
11693
  const result = await onSave(draft, expected.current);
10822
11694
  if (alive.current) {
@@ -10825,8 +11697,8 @@ window.__ModuleLoader__.load({
10825
11697
  setDraft(void 0);
10826
11698
  setSearch("");
10827
11699
  }
10828
- } catch {
10829
- if (alive.current) setError(true);
11700
+ } catch (cause) {
11701
+ if (alive.current) setError(toWorktreeViewError(cause));
10830
11702
  } finally {
10831
11703
  busy.current = false;
10832
11704
  if (alive.current) setPending(false);
@@ -10939,16 +11811,26 @@ window.__ModuleLoader__.load({
10939
11811
  children: t("dashboard.noMatchingBranches")
10940
11812
  })
10941
11813
  }),
10942
- (0, react_jsx_runtime.jsx)("div", {
10943
- className: dashboard_css_default.dashboardBaselineStatus,
10944
- "data-dashboard-baseline-status": true,
10945
- children: error && (0, react_jsx_runtime.jsx)("span", {
10946
- className: dashboard_css_default.dashboardBaselineError,
10947
- "data-dashboard-baseline-error": true,
10948
- role: "alert",
10949
- children: t("dashboard.baseSaveFailed")
10950
- })
10951
- })
11814
+ (0, react_jsx_runtime.jsx)(NotificationToasts, { notices: error === void 0 ? [] : [{
11815
+ key: JSON.stringify([
11816
+ "baseline",
11817
+ context,
11818
+ error.code,
11819
+ error.details
11820
+ ]),
11821
+ context,
11822
+ error,
11823
+ actions: [{
11824
+ label: t("action.retry"),
11825
+ disabled: pending || disabled,
11826
+ onClick: () => {
11827
+ save();
11828
+ }
11829
+ }],
11830
+ describe: (translate) => translate("dashboard.base") + " · " + (context ?? ""),
11831
+ message: (translate) => translate("dashboard.baseSaveFailed") + (error.code === "WORKTREE_VIEW_FAILED" ? "" : " " + formatWorktreeViewError(error, translate)),
11832
+ text: t("dashboard.baseSaveFailed") + (error.code === "WORKTREE_VIEW_FAILED" ? "" : " " + formatWorktreeViewError(error, t))
11833
+ }] })
10952
11834
  ]
10953
11835
  })
10954
11836
  })] });
@@ -11252,10 +12134,21 @@ window.__ModuleLoader__.load({
11252
12134
  })
11253
12135
  ]
11254
12136
  }),
12137
+ (0, react_jsx_runtime.jsx)(NotificationToasts, { notices: [...branchCopyState === "failed" ? [{
12138
+ key: "copy-branch:" + record.absolutePath,
12139
+ text: t("dashboard.branchCopyFailed"),
12140
+ context: workspaceTitle + " · " + record.branch + " · " + record.absolutePath,
12141
+ message: (translate) => translate("dashboard.branchCopyFailed")
12142
+ }] : [], ...copyState === "failed" ? [{
12143
+ key: "copy-path:" + record.absolutePath,
12144
+ text: t("dashboard.copyFailed"),
12145
+ context: workspaceTitle + " · " + record.absolutePath,
12146
+ message: (translate) => translate("dashboard.copyFailed")
12147
+ }] : []] }),
11255
12148
  (0, react_jsx_runtime.jsx)("p", {
11256
12149
  className: dashboard_css_default.dashboardCopyStatus,
11257
- role: branchCopyState === "failed" || branchCopyState === "idle" && copyState === "failed" ? "alert" : "status",
11258
- children: branchCopyState === "pending" ? "\xA0" : branchCopyState === "copied" ? t("dashboard.branchCopied") : branchCopyState === "failed" ? t("dashboard.branchCopyFailed") : copyState === "copied" ? t("dashboard.copied") : copyState === "failed" ? t("dashboard.copyFailed") : "\xA0"
12150
+ role: "status",
12151
+ children: branchCopyState === "copied" ? t("dashboard.branchCopied") : copyState === "copied" ? t("dashboard.copied") : "\xA0"
11259
12152
  })
11260
12153
  ]
11261
12154
  }), (0, react_jsx_runtime.jsx)("div", {
@@ -11274,6 +12167,7 @@ window.__ModuleLoader__.load({
11274
12167
  })
11275
12168
  }),
11276
12169
  !isMainWorktreeId$1(record.worktreeId) && persistBaseline !== void 0 ? (0, react_jsx_runtime.jsx)(WorktreeBaselineEditor, {
12170
+ context: workspaceTitle + " · " + record.branch + " · " + record.absolutePath,
11277
12171
  value: baselineBranch,
11278
12172
  branches,
11279
12173
  currentBranch: baselineCurrentBranch,
@@ -11357,6 +12251,7 @@ window.__ModuleLoader__.load({
11357
12251
  title: t("dashboard.instructions"),
11358
12252
  icon: (0, react_jsx_runtime.jsx)(DashboardIcon, { kind: "instructions" }),
11359
12253
  children: [(0, react_jsx_runtime.jsx)("p", { children: t("dashboard.instructionsDescription") }), (0, react_jsx_runtime.jsx)(WorktreeInstructions, {
12254
+ context: workspaceTitle + " · " + record.branch + " · " + record.absolutePath,
11360
12255
  value: record.instructions ?? "",
11361
12256
  onSave: onSaveInstructions,
11362
12257
  t,
@@ -11461,6 +12356,7 @@ window.__ModuleLoader__.load({
11461
12356
  ]
11462
12357
  })]
11463
12358
  }) : tab === "git" ? (0, react_jsx_runtime.jsx)(WorktreeGitPanel, {
12359
+ context: workspaceTitle + " · " + record.branch + " · " + record.absolutePath,
11464
12360
  manager,
11465
12361
  workspaceId: record.workspaceId,
11466
12362
  worktreeId: record.worktreeId,
@@ -11483,6 +12379,21 @@ window.__ModuleLoader__.load({
11483
12379
  children: t("dashboard.newSession")
11484
12380
  }),
11485
12381
  children: sessionList(sessionIds)
12382
+ }) : tab === "settings" ? (0, react_jsx_runtime.jsx)(Card, {
12383
+ title: tabLabel("settings"),
12384
+ icon: (0, react_jsx_runtime.jsx)(DashboardIcon, { kind: "settings" }),
12385
+ children: (0, react_jsx_runtime.jsx)(ToolSettings, {
12386
+ manager,
12387
+ scope: isMainWorktreeId$1(record.worktreeId) ? {
12388
+ kind: "local",
12389
+ workspaceId: record.workspaceId
12390
+ } : {
12391
+ kind: "worktree",
12392
+ workspaceId: record.workspaceId,
12393
+ worktreeId: record.worktreeId
12394
+ },
12395
+ t
12396
+ }, JSON.stringify([record.workspaceId, record.worktreeId]))
11486
12397
  }) : (0, react_jsx_runtime.jsxs)("section", {
11487
12398
  className: dashboard_css_default.dashboardTabPlaceholder,
11488
12399
  children: [
@@ -11504,7 +12415,7 @@ window.__ModuleLoader__.load({
11504
12415
  //#endregion
11505
12416
  //#region lib/client/dashboard/DashboardRequest.js
11506
12417
  /** Present a header request while its target read settles, without expanding navigation. */
11507
- function DashboardRequest({ t, error, onRetry, onClose }) {
12418
+ function DashboardRequest({ t, error, onRetry, onClose, context }) {
11508
12419
  const ref = (0, react.useRef)(null);
11509
12420
  const [placement, setPlacement] = (0, react.useState)();
11510
12421
  (0, react.useLayoutEffect)(() => {
@@ -11555,14 +12466,18 @@ window.__ModuleLoader__.load({
11555
12466
  })]
11556
12467
  }), (0, react_jsx_runtime.jsxs)("div", {
11557
12468
  className: dashboard_css_default.dashboardPage,
11558
- children: [(0, react_jsx_runtime.jsx)("p", {
11559
- role: error ? "alert" : "status",
11560
- children: error ? formatWorktreeViewError(error, t) : t("status.loading")
11561
- }), error && (0, react_jsx_runtime.jsx)("button", {
11562
- type: "button",
11563
- className: dashboard_css_default.dashboardButton,
11564
- onClick: onRetry,
11565
- children: t("action.retry")
12469
+ children: [error === void 0 && (0, react_jsx_runtime.jsx)("p", {
12470
+ role: "status",
12471
+ children: t("status.loading")
12472
+ }), (0, react_jsx_runtime.jsx)(ErrorToast, {
12473
+ error,
12474
+ t,
12475
+ scope: "dashboard-request",
12476
+ context: context ?? t("dashboard.title"),
12477
+ actions: [{
12478
+ label: t("action.retry"),
12479
+ onClick: onRetry
12480
+ }]
11566
12481
  })]
11567
12482
  })]
11568
12483
  });
@@ -11625,21 +12540,73 @@ window.__ModuleLoader__.load({
11625
12540
  return { kind: "wait" };
11626
12541
  }
11627
12542
  //#endregion
11628
- //#region lib/client/dashboard/git/file-address.js
12543
+ //#region ../../node_modules/.pnpm/@deepseek-ai+dsh-util-workspace-path@0.2.0-rc.1_@deepseek-ai+cordis@4.0.4/node_modules/@deepseek-ai/dsh-util-workspace-path/lib/index.js
11629
12544
  /**
11630
- * Canonical DSH session file address constructor.
11631
- * Equivalent to `sessionFileAddress` from `@deepseek-ai/dsh-util-workspace-path`.
11632
- * Address grammar: `dsh-resource://file/session/<sessionId>/<encodedPath>`
12545
+ * The `dsh-resource://file/…` address grammar: how a file is named across the
12546
+ * Sidebar and the resource model, built and parsed without touching a
12547
+ * filesystem.
12548
+ * @module
11633
12549
  */
12550
+ /** The scheme and type every file address opens with. */
12551
+ const FILE_ADDRESS_PREFIX = "dsh-resource://file/";
12552
+ /** Component-encode one id or path segment, keeping `:` literal for drive letters. */
11634
12553
  function encodeSegment(segment) {
11635
12554
  return encodeURIComponent(segment).replace(/%3A/gi, ":");
11636
12555
  }
12556
+ /** Encode a `/`-separated path segment by segment. */
11637
12557
  function encodePath(path) {
11638
12558
  return path.split("/").map(encodeSegment).join("/");
11639
12559
  }
11640
- function buildSessionFileAddress(sessionId, path) {
12560
+ /**
12561
+ * Build the address of a file read through one Session.
12562
+ * @param sessionId - the Session whose Host workspace resolves the path.
12563
+ * @param path - absolute or workspace-relative path; backslashes are normalized to `/`, and leading `./` prefixes are dropped.
12564
+ * @returns the `dsh-resource://file/session/<sessionId>/<path>` address.
12565
+ */
12566
+ function sessionFileAddress(sessionId, path) {
12567
+ const normalized = path.replace(/\\/g, "/").replace(/^(?:\.\/)+/, "");
12568
+ return `${FILE_ADDRESS_PREFIX}session/${encodeSegment(sessionId)}/${encodePath(normalized)}`;
12569
+ }
12570
+ /**
12571
+ * Browser-safe Workspace path and display helpers.
12572
+ * @module @deepseek-ai/dsh-util-workspace-path
12573
+ */
12574
+ /** Whether a path uses a Windows drive or UNC prefix. */
12575
+ function isWindowsStylePath(value) {
12576
+ return /^[A-Za-z]:[/\\]/.test(value) || value.startsWith("\\\\");
12577
+ }
12578
+ /**
12579
+ * Whether a path is absolute in either spelling the Host accepts: POSIX (`/a/b`) or Windows drive or UNC.
12580
+ * @param path - the path to classify.
12581
+ * @returns `true` for an absolute path; `false` for a Workspace-relative one.
12582
+ */
12583
+ function isAbsoluteWorkspacePath(path) {
12584
+ return path.startsWith("/") || isWindowsStylePath(path);
12585
+ }
12586
+ /**
12587
+ * The address for a path as a caller holds it: a relative path, or an absolute
12588
+ * path inside the Session's workspace, becomes a `session`-scoped address; an
12589
+ * absolute path outside it, or one whose workspace root is unknown, keeps its
12590
+ * absolute path in that Session's address.
12591
+ * @param sessionId - the Session the path is read in.
12592
+ * @param cwd - that Session's workspace root, when known.
12593
+ * @param path - absolute or workspace-relative path, in either separator spelling.
12594
+ * @returns the `dsh-resource://file/…` address.
12595
+ */
12596
+ function fileAddressFor(sessionId, cwd, path) {
12597
+ const normalized = path.replace(/\\/g, "/");
12598
+ if (!isAbsoluteWorkspacePath(normalized)) return sessionFileAddress(sessionId, normalized);
12599
+ const root = cwd === void 0 ? "" : cwd.replace(/\\/g, "/").replace(/\/+$/, "");
12600
+ if (root !== "" && normalized === root) return sessionFileAddress(sessionId, "");
12601
+ if (root !== "" && normalized.startsWith(`${root}/`)) return sessionFileAddress(sessionId, normalized.slice(root.length + 1));
12602
+ return sessionFileAddress(sessionId, normalized);
12603
+ }
12604
+ //#endregion
12605
+ //#region lib/client/dashboard/git/file-address.js
12606
+ /** Resolve checkout-relative Git paths against the actual Session cwd. */
12607
+ function buildSessionFileAddress(sessionId, path, gitRootPath, cwd) {
11641
12608
  const normalized = path.replace(/\\/g, "/").replace(/^(?:\.\/)+/, "");
11642
- return `dsh-resource://file/session/${encodeSegment(sessionId)}/${encodePath(normalized)}`;
12609
+ return fileAddressFor(sessionId, cwd, gitRootPath === void 0 ? normalized : gitRootPath.replace(/\\/g, "/").replace(/\/$/, "") + "/" + normalized);
11643
12610
  }
11644
12611
  //#endregion
11645
12612
  //#region lib/client/WorktreeSurface.js
@@ -11807,7 +12774,7 @@ window.__ModuleLoader__.load({
11807
12774
  const worktreeSessions = dashboardSessionIds(dashboardRecord, source.sessions, dashboardView?.bindings ?? [], source.archivedSessionIds, isMainWorktreeId$1(dashboardRecord.worktreeId) ? ordering.orderedSessionIdsByAccount.get(`main:${dashboardRecord.workspaceId}`) : ordering.orderedSessionIdsByAccount.get(`worktree:${dashboardRecord.worktreeId}`), dashboardWorkspace === void 0 ? [] : workspaceSessionIds(source.workspaces, dashboardWorkspace.workspaceId, source.sessions.ids));
11808
12775
  const targetSessionId = source.currentSessionId !== void 0 && worktreeSessions.includes(source.currentSessionId) ? source.currentSessionId : void 0;
11809
12776
  if (targetSessionId === void 0) return;
11810
- const address = buildSessionFileAddress(targetSessionId, filePath);
12777
+ const address = buildSessionFileAddress(targetSessionId, filePath, dashboardRecord.gitRootPath ?? dashboardRecord.absolutePath, source.sessions.byId[targetSessionId]?.cwd ?? dashboardRecord.absolutePath);
11811
12778
  props.openResource(address, options);
11812
12779
  }, [
11813
12780
  props.openResource,
@@ -11823,166 +12790,171 @@ window.__ModuleLoader__.load({
11823
12790
  if (source.mode !== "worktree") return null;
11824
12791
  const { ref, width, bounds, collapsed } = source;
11825
12792
  const { t } = props;
11826
- return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
11827
- (0, react_jsx_runtime.jsxs)("aside", {
11828
- ref,
11829
- className: worktree_css_default.surface,
11830
- "data-worktree-surface": true,
11831
- "data-collapsed": collapsed || void 0,
11832
- "data-native-sidebar-covered": source.nativeCovered || void 0,
11833
- "aria-hidden": collapsed || void 0,
11834
- "aria-label": t("mode.navigation"),
11835
- style: {
11836
- width: `${width}px`,
11837
- ...bounds.ready ? {
11838
- top: `${bounds.top}px`,
11839
- height: `${bounds.height}px`
11840
- } : {
11841
- height: "0px",
11842
- visibility: "hidden"
11843
- }
11844
- },
11845
- children: [
11846
- (0, react_jsx_runtime.jsxs)("div", {
11847
- className: worktree_css_default.wideContent,
11848
- children: [(0, react_jsx_runtime.jsx)(SurfaceHeader, {
11849
- expansion,
12793
+ return (0, react_jsx_runtime.jsxs)(NotificationProvider, {
12794
+ t,
12795
+ openSettings: props.openErrorSettings,
12796
+ children: [
12797
+ (0, react_jsx_runtime.jsxs)("aside", {
12798
+ ref,
12799
+ className: worktree_css_default.surface,
12800
+ "data-worktree-surface": true,
12801
+ "data-collapsed": collapsed || void 0,
12802
+ "data-native-sidebar-covered": source.nativeCovered || void 0,
12803
+ "aria-hidden": collapsed || void 0,
12804
+ "aria-label": t("mode.navigation"),
12805
+ style: {
12806
+ width: `${width}px`,
12807
+ ...bounds.ready ? {
12808
+ top: `${bounds.top}px`,
12809
+ height: `${bounds.height}px`
12810
+ } : {
12811
+ height: "0px",
12812
+ visibility: "hidden"
12813
+ }
12814
+ },
12815
+ children: [
12816
+ (0, react_jsx_runtime.jsxs)("div", {
12817
+ className: worktree_css_default.wideContent,
12818
+ children: [(0, react_jsx_runtime.jsx)(SurfaceHeader, {
12819
+ expansion,
12820
+ props,
12821
+ source,
12822
+ read,
12823
+ mutation
12824
+ }), (0, react_jsx_runtime.jsx)(SurfaceContent, {
12825
+ source,
12826
+ props,
12827
+ lifecycle,
12828
+ mutation,
12829
+ session,
12830
+ read,
12831
+ expansion,
12832
+ ordering,
12833
+ drag,
12834
+ menus,
12835
+ registration,
12836
+ native,
12837
+ lifecycleState
12838
+ })]
12839
+ }),
12840
+ (0, react_jsx_runtime.jsx)(NativeDialogs, {
11850
12841
  props,
11851
- source,
11852
- read,
11853
- mutation
11854
- }), (0, react_jsx_runtime.jsx)(SurfaceContent, {
11855
- source,
12842
+ native
12843
+ }),
12844
+ (0, react_jsx_runtime.jsx)(RegistrationDialog, {
11856
12845
  props,
11857
- lifecycle,
12846
+ registration,
12847
+ registrationState,
11858
12848
  mutation,
11859
- session,
11860
- read,
12849
+ read
12850
+ }),
12851
+ (0, react_jsx_runtime.jsx)(LifecycleDialogs, {
12852
+ props,
12853
+ lifecycleState,
12854
+ mutation,
12855
+ lifecycle,
11861
12856
  expansion,
11862
- ordering,
11863
- drag,
11864
- menus,
11865
- registration,
11866
- native,
11867
- lifecycleState
11868
- })]
11869
- }),
11870
- (0, react_jsx_runtime.jsx)(NativeDialogs, {
11871
- props,
11872
- native
11873
- }),
11874
- (0, react_jsx_runtime.jsx)(RegistrationDialog, {
11875
- props,
11876
- registration,
11877
- registrationState,
11878
- mutation,
11879
- read
11880
- }),
11881
- (0, react_jsx_runtime.jsx)(LifecycleDialogs, {
11882
- props,
11883
- lifecycleState,
11884
- mutation,
11885
- lifecycle,
11886
- expansion,
11887
- read,
11888
- session
11889
- }),
11890
- (0, react_jsx_runtime.jsx)(AccessConfirmation, {
11891
- source,
11892
- props
11893
- })
11894
- ]
11895
- }),
11896
- dashboard !== void 0 && dashboardRecord === void 0 && dashboard.sessionId === source.currentSessionId && source.workspaceIds.includes(dashboard.workspaceId) && targetView === void 0 && (0, react_jsx_runtime.jsx)(DashboardRequest, {
11897
- t,
11898
- error: read.readState.error ?? (read.readState.targetError?.workspaceIds.includes(dashboard.workspaceId) ? read.readState.targetError.error : void 0),
11899
- onClose: closeDashboard,
11900
- onRetry: () => {
11901
- read.refresh({
11902
- scope: {
11903
- kind: "workspace",
11904
- workspaceId: dashboard.workspaceId
11905
- },
11906
- preserveCurrent: true
11907
- });
11908
- }
11909
- }),
11910
- dashboardRecord !== void 0 && (0, react_jsx_runtime.jsx)(WorktreeDashboard, {
11911
- manager: props.manager,
11912
- record: dashboardRecord,
11913
- onSaveInstructions: props.manager ? async (instructions, expectedInstructions) => {
11914
- try {
11915
- return await props.manager.updateWorktreeInstructions({
11916
- workspaceId: dashboardRecord.workspaceId,
11917
- worktreeId: dashboardRecord.worktreeId,
11918
- instructions,
11919
- expectedInstructions
11920
- });
11921
- } finally {
12857
+ read,
12858
+ session
12859
+ }),
12860
+ (0, react_jsx_runtime.jsx)(AccessConfirmation, {
12861
+ source,
12862
+ props
12863
+ })
12864
+ ]
12865
+ }),
12866
+ dashboard !== void 0 && dashboardRecord === void 0 && dashboard.sessionId === source.currentSessionId && source.workspaceIds.includes(dashboard.workspaceId) && targetView === void 0 && (0, react_jsx_runtime.jsx)(DashboardRequest, {
12867
+ context: targetWorkspace === void 0 ? dashboard.workspaceId : targetWorkspace.title + " · " + targetWorkspace.path,
12868
+ t,
12869
+ error: read.readState.error ?? (read.readState.targetError?.workspaceIds.includes(dashboard.workspaceId) ? read.readState.targetError.error : void 0),
12870
+ onClose: closeDashboard,
12871
+ onRetry: () => {
11922
12872
  read.refresh({
11923
- preserveCurrent: true,
11924
12873
  scope: {
11925
12874
  kind: "workspace",
11926
- workspaceId: dashboardRecord.workspaceId
11927
- }
12875
+ workspaceId: dashboard.workspaceId
12876
+ },
12877
+ preserveCurrent: true
11928
12878
  });
11929
12879
  }
11930
- } : void 0,
11931
- onSaveBaseline: props.manager && typeof props.manager.updateWorktreeBaseBranch === "function" && dashboardManagedRecord !== void 0 && dashboardCanCreate ? async (baseBranch, expectedBaseBranch) => {
11932
- try {
11933
- return await props.manager.updateWorktreeBaseBranch({
12880
+ }),
12881
+ dashboardRecord !== void 0 && (0, react_jsx_runtime.jsx)(WorktreeDashboard, {
12882
+ manager: props.manager,
12883
+ record: dashboardRecord,
12884
+ onSaveInstructions: props.manager ? async (instructions, expectedInstructions) => {
12885
+ try {
12886
+ return await props.manager.updateWorktreeInstructions({
12887
+ workspaceId: dashboardRecord.workspaceId,
12888
+ worktreeId: dashboardRecord.worktreeId,
12889
+ instructions,
12890
+ expectedInstructions
12891
+ });
12892
+ } finally {
12893
+ read.refresh({
12894
+ preserveCurrent: true,
12895
+ scope: {
12896
+ kind: "workspace",
12897
+ workspaceId: dashboardRecord.workspaceId
12898
+ }
12899
+ });
12900
+ }
12901
+ } : void 0,
12902
+ onSaveBaseline: props.manager && typeof props.manager.updateWorktreeBaseBranch === "function" && dashboardManagedRecord !== void 0 && dashboardCanCreate ? async (baseBranch, expectedBaseBranch) => {
12903
+ try {
12904
+ return await props.manager.updateWorktreeBaseBranch({
12905
+ workspaceId: dashboardRecord.workspaceId,
12906
+ worktreeId: dashboardRecord.worktreeId,
12907
+ baseBranch,
12908
+ expectedBaseBranch
12909
+ });
12910
+ } finally {
12911
+ read.refresh({
12912
+ preserveCurrent: true,
12913
+ scope: {
12914
+ kind: "workspace",
12915
+ workspaceId: dashboardRecord.workspaceId
12916
+ }
12917
+ });
12918
+ }
12919
+ } : void 0,
12920
+ branches: dashboardView?.branches ?? [],
12921
+ workspaceTitle: dashboardWorkspace?.title ?? "",
12922
+ sessions: source.sessions,
12923
+ sessionPresentations: source.sessionPresentations,
12924
+ sessionIds: dashboardSessionIds(dashboardRecord, source.sessions, dashboardView?.bindings ?? [], source.archivedSessionIds, isMainWorktreeId$1(dashboardRecord.worktreeId) ? ordering.orderedSessionIdsByAccount.get(`main:${dashboardRecord.workspaceId}`) : ordering.orderedSessionIdsByAccount.get(`worktree:${dashboardRecord.worktreeId}`), dashboardWorkspace === void 0 ? [] : workspaceSessionIds(source.workspaces, dashboardWorkspace.workspaceId, source.sessions.ids)),
12925
+ actionPending: mutation.actionPending,
12926
+ onOpenFile: typeof props.openResource === "function" ? onOpenFile : void 0,
12927
+ onOpenSession: (sessionId) => session.openWorkspaceSession(dashboardRecord.workspaceId, sessionId),
12928
+ onCreateSession: dashboardCanCreate && (isMainWorktreeId$1(dashboardRecord.worktreeId) ? props.createMainSession !== void 0 : props.createSessionForWorktree !== void 0) ? () => {
12929
+ if (mutation.actionPending) return;
12930
+ closeDashboard();
12931
+ if (isMainWorktreeId$1(dashboardRecord.worktreeId)) props.createMainSession?.(dashboardRecord.workspaceId);
12932
+ else session.createSession({
11934
12933
  workspaceId: dashboardRecord.workspaceId,
11935
12934
  worktreeId: dashboardRecord.worktreeId,
11936
- baseBranch,
11937
- expectedBaseBranch
12935
+ cwd: dashboardRecord.absolutePath
11938
12936
  });
11939
- } finally {
11940
- read.refresh({
11941
- preserveCurrent: true,
11942
- scope: {
11943
- kind: "workspace",
11944
- workspaceId: dashboardRecord.workspaceId
11945
- }
12937
+ } : void 0,
12938
+ onCreateWorktree: dashboardCanCreate && dashboardRecord.currentBranch !== null && dashboardRecord.branch.length > 0 && dashboardWorkspace !== void 0 && dashboardView !== void 0 ? () => {
12939
+ if (mutation.actionPending) return;
12940
+ const branch = dashboardRecord.currentBranch ?? dashboardRecord.branch;
12941
+ registration.openWorktreeCreator(dashboardWorkspace, {
12942
+ baseBranch: branch,
12943
+ newBranch: createNumberedWorktreeName(branch, [...dashboardView.branches.map((candidate) => candidate.name), ...dashboardView.worktrees.map((candidate) => candidate.branch)])
11946
12944
  });
11947
- }
11948
- } : void 0,
11949
- branches: dashboardView?.branches ?? [],
11950
- workspaceTitle: dashboardWorkspace?.title ?? "",
11951
- sessions: source.sessions,
11952
- sessionPresentations: source.sessionPresentations,
11953
- sessionIds: dashboardSessionIds(dashboardRecord, source.sessions, dashboardView?.bindings ?? [], source.archivedSessionIds, isMainWorktreeId$1(dashboardRecord.worktreeId) ? ordering.orderedSessionIdsByAccount.get(`main:${dashboardRecord.workspaceId}`) : ordering.orderedSessionIdsByAccount.get(`worktree:${dashboardRecord.worktreeId}`), dashboardWorkspace === void 0 ? [] : workspaceSessionIds(source.workspaces, dashboardWorkspace.workspaceId, source.sessions.ids)),
11954
- actionPending: mutation.actionPending,
11955
- onOpenFile: typeof props.openResource === "function" ? onOpenFile : void 0,
11956
- onOpenSession: (sessionId) => session.openWorkspaceSession(dashboardRecord.workspaceId, sessionId),
11957
- onCreateSession: dashboardCanCreate && (isMainWorktreeId$1(dashboardRecord.worktreeId) ? props.createMainSession !== void 0 : props.createSessionForWorktree !== void 0) ? () => {
11958
- if (mutation.actionPending) return;
11959
- closeDashboard();
11960
- if (isMainWorktreeId$1(dashboardRecord.worktreeId)) props.createMainSession?.(dashboardRecord.workspaceId);
11961
- else session.createSession({
11962
- workspaceId: dashboardRecord.workspaceId,
11963
- worktreeId: dashboardRecord.worktreeId,
11964
- cwd: dashboardRecord.absolutePath
11965
- });
11966
- } : void 0,
11967
- onCreateWorktree: dashboardCanCreate && dashboardRecord.currentBranch !== null && dashboardRecord.branch.length > 0 && dashboardWorkspace !== void 0 && dashboardView !== void 0 ? () => {
11968
- if (mutation.actionPending) return;
11969
- const branch = dashboardRecord.currentBranch ?? dashboardRecord.branch;
11970
- registration.openWorktreeCreator(dashboardWorkspace, {
11971
- baseBranch: branch,
11972
- newBranch: createNumberedWorktreeName(branch, [...dashboardView.branches.map((candidate) => candidate.name), ...dashboardView.worktrees.map((candidate) => candidate.branch)])
11973
- });
11974
- } : void 0,
11975
- onArchiveWorktree: dashboardManagedRecord !== void 0 && dashboardManagedRecord.status === "active" && dashboardManagedRecord.health !== "recovery-needed" ? () => {
11976
- if (mutation.actionPending) return;
11977
- lifecycleState.setWorktreeRemoval(dashboardManagedRecord);
11978
- mutation.setActionError(void 0);
11979
- } : void 0,
11980
- t,
11981
- onClose: closeDashboard,
11982
- onOpenSidebar: source.currentSessionId === void 0 ? void 0 : props.openRightSidebar,
11983
- isRightSidebarExpanded: props.isRightSidebarExpanded
11984
- }, `${dashboardRecord.workspaceId}:${dashboardRecord.worktreeId}`)
11985
- ] });
12945
+ } : void 0,
12946
+ onArchiveWorktree: dashboardManagedRecord !== void 0 && dashboardManagedRecord.status === "active" && dashboardManagedRecord.health !== "recovery-needed" ? () => {
12947
+ if (mutation.actionPending) return;
12948
+ lifecycleState.setWorktreeRemoval(dashboardManagedRecord);
12949
+ mutation.setActionError(void 0);
12950
+ } : void 0,
12951
+ t,
12952
+ onClose: closeDashboard,
12953
+ onOpenSidebar: source.currentSessionId === void 0 ? void 0 : props.openRightSidebar,
12954
+ isRightSidebarExpanded: props.isRightSidebarExpanded
12955
+ }, `${dashboardRecord.workspaceId}:${dashboardRecord.worktreeId}`)
12956
+ ]
12957
+ });
11986
12958
  }
11987
12959
  //#endregion
11988
12960
  //#region lib/client/overlay/WorktreeOverlay.js
@@ -11991,6 +12963,243 @@ window.__ModuleLoader__.load({
11991
12963
  return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(WorktreeHeroContext, { ...props }), (0, react_jsx_runtime.jsx)(WorktreeSurface, { ...props })] });
11992
12964
  }
11993
12965
  //#endregion
12966
+ //#region lib/client/settings/WorktreeSettings.js
12967
+ function WorktreeSettings({ t, close, manager }) {
12968
+ const entries = (0, react.useSyncExternalStore)(worktreeDiagnostics.subscribe, worktreeDiagnostics.getSnapshot, worktreeDiagnostics.getSnapshot);
12969
+ const [tab, setTab] = (0, react.useState)(entries.some((entry) => entry.status === "active") ? "errors" : "general");
12970
+ const id = (0, react.useId)();
12971
+ return (0, react_jsx_runtime.jsxs)("section", {
12972
+ className: settings_css_default.settings,
12973
+ "data-worktree-settings": true,
12974
+ children: [
12975
+ (0, react_jsx_runtime.jsx)("h2", {
12976
+ className: settings_css_default.settingsTitle,
12977
+ children: t("settings.title")
12978
+ }),
12979
+ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.SegmentedTabs, {
12980
+ label: t("settings.title"),
12981
+ className: settings_css_default.settingsTabs,
12982
+ value: tab,
12983
+ onChange: setTab,
12984
+ items: [{
12985
+ value: "general",
12986
+ label: t("settings.general"),
12987
+ id: id + "general",
12988
+ panelId: id + "panel"
12989
+ }, {
12990
+ value: "errors",
12991
+ label: t("settings.errors"),
12992
+ id: id + "errors",
12993
+ panelId: id + "panel"
12994
+ }]
12995
+ }),
12996
+ (0, react_jsx_runtime.jsx)("div", {
12997
+ className: settings_css_default.settingsPanel,
12998
+ role: "tabpanel",
12999
+ id: id + "panel",
13000
+ "aria-labelledby": id + tab,
13001
+ children: tab === "general" ? (0, react_jsx_runtime.jsx)(ToolSettings, {
13002
+ manager,
13003
+ scope: { kind: "general" },
13004
+ t
13005
+ }) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
13006
+ (0, react_jsx_runtime.jsxs)("div", {
13007
+ className: settings_css_default.settingsToolbar,
13008
+ children: [(0, react_jsx_runtime.jsx)("p", {
13009
+ className: settings_css_default.settingsHint,
13010
+ children: t("settings.retention")
13011
+ }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
13012
+ className: settings_css_default.settingsAction,
13013
+ size: "sm",
13014
+ variant: "outline",
13015
+ disabled: !entries.some((entry) => entry.status !== "active"),
13016
+ onClick: () => worktreeDiagnostics.clearHistory(),
13017
+ children: t("settings.clearHistory")
13018
+ })]
13019
+ }),
13020
+ entries.length === 0 && (0, react_jsx_runtime.jsx)("p", {
13021
+ className: settings_css_default.settingsEmpty,
13022
+ children: t("settings.empty")
13023
+ }),
13024
+ (0, react_jsx_runtime.jsx)("div", {
13025
+ className: settings_css_default.issueList,
13026
+ children: [...entries].reverse().map((entry) => (0, react_jsx_runtime.jsxs)("article", {
13027
+ className: settings_css_default.issue,
13028
+ "data-worktree-diagnostic": true,
13029
+ children: [
13030
+ (0, react_jsx_runtime.jsxs)("div", {
13031
+ className: settings_css_default.issueHeader,
13032
+ children: [(0, react_jsx_runtime.jsx)("h3", {
13033
+ className: settings_css_default.issueTitle,
13034
+ children: entry.describe?.(t) ?? entry.context ?? t("settings.operation")
13035
+ }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tag, {
13036
+ className: settings_css_default.issueStatus,
13037
+ tone: entry.status === "active" ? "danger" : entry.status === "resolved" ? "quiet" : "neutral",
13038
+ children: t(entry.status === "active" ? "settings.active" : entry.status === "resolved" ? "settings.resolved" : "settings.inactive")
13039
+ })]
13040
+ }),
13041
+ (0, react_jsx_runtime.jsx)("p", {
13042
+ className: settings_css_default.issueMessage,
13043
+ children: entry.message?.(t) ?? (entry.error === void 0 ? entry.text : formatWorktreeViewError(entry.error, t))
13044
+ }),
13045
+ entry.status === "inactive" && (0, react_jsx_runtime.jsx)("p", {
13046
+ className: settings_css_default.settingsHint,
13047
+ children: t("settings.reopen")
13048
+ }),
13049
+ entry.actions.length > 0 && (0, react_jsx_runtime.jsx)("div", {
13050
+ className: settings_css_default.issueActions,
13051
+ children: entry.actions.map((action, index) => (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
13052
+ className: settings_css_default.settingsAction,
13053
+ size: "sm",
13054
+ variant: "outline",
13055
+ disabled: action.disabled,
13056
+ onClick: () => {
13057
+ if (action.leaveSettings) close();
13058
+ action.onClick();
13059
+ },
13060
+ children: action.label
13061
+ }, index))
13062
+ }),
13063
+ entry.error !== void 0 && (0, react_jsx_runtime.jsxs)("details", {
13064
+ className: settings_css_default.issueDiagnostics,
13065
+ children: [(0, react_jsx_runtime.jsx)("summary", { children: t("settings.diagnostics") }), (0, react_jsx_runtime.jsx)("pre", { children: JSON.stringify({
13066
+ code: entry.error.code,
13067
+ message: entry.error.message,
13068
+ details: entry.error.details
13069
+ }, null, 2) })]
13070
+ })
13071
+ ]
13072
+ }, entry.key))
13073
+ })
13074
+ ] })
13075
+ })
13076
+ ]
13077
+ });
13078
+ }
13079
+ //#endregion
13080
+ //#region lib/client/settings/WorktreeSettingsNavIcon.js
13081
+ const ATTRIBUTE = "data-worktree-settings-nav-icon";
13082
+ /** The native settings shell has no section-icon slot; decorate only our nav row. */
13083
+ function WorktreeSettingsNavIcon({ t }) {
13084
+ const [target, setTarget] = (0, react.useState)();
13085
+ const label = t("settings.title");
13086
+ (0, react.useEffect)(() => {
13087
+ if (typeof document === "undefined") return;
13088
+ let active = true;
13089
+ let queued = false;
13090
+ const scan = () => {
13091
+ if (!active || queued) return;
13092
+ queued = true;
13093
+ queueMicrotask(() => {
13094
+ queued = false;
13095
+ if (!active) return;
13096
+ const rows = Array.from(document.querySelectorAll("[data-shortcut-modal=\"settings\"] nav button")).filter((row) => row.textContent?.trim() === label && row.querySelector(":scope > svg") !== null);
13097
+ setTarget(rows.length === 1 ? rows[0] : void 0);
13098
+ });
13099
+ };
13100
+ const observer = new MutationObserver(scan);
13101
+ observer.observe(document.documentElement, {
13102
+ childList: true,
13103
+ characterData: true,
13104
+ subtree: true
13105
+ });
13106
+ scan();
13107
+ return () => {
13108
+ active = false;
13109
+ observer.disconnect();
13110
+ };
13111
+ }, [label]);
13112
+ (0, react.useLayoutEffect)(() => {
13113
+ if (!target) return;
13114
+ target.setAttribute(ATTRIBUTE, "");
13115
+ return () => target.removeAttribute(ATTRIBUTE);
13116
+ }, [target]);
13117
+ return target ? (0, react_dom.createPortal)((0, react_jsx_runtime.jsx)(IconBranchOutline16, {
13118
+ size: 16,
13119
+ className: settings_css_default.settingsNavIcon
13120
+ }), target) : null;
13121
+ }
13122
+ //#endregion
13123
+ //#region lib/client/command-activity.js
13124
+ const WORKTREE_COMMAND_ACTIVITY = "clutch-dsh-worktree-command-activity";
13125
+ /** Native Chat still owns the result row; this target supplies only shell activity. */
13126
+ const worktreeCommandActivityNode = {
13127
+ kind: WORKTREE_COMMAND_ACTIVITY,
13128
+ target: WORKTREE_COMMAND_ACTIVITY,
13129
+ match: (event) => event.type === "command/run" && event.data.name === "cluworktree" ? {
13130
+ id: String(event.data.commandId),
13131
+ role: "start"
13132
+ } : null,
13133
+ start: () => true,
13134
+ update: () => true,
13135
+ buildViewNode: (context) => context.start === void 0 ? null : {
13136
+ key: context.key,
13137
+ kind: WORKTREE_COMMAND_ACTIVITY,
13138
+ id: context.id,
13139
+ target: WORKTREE_COMMAND_ACTIVITY,
13140
+ data: true
13141
+ }
13142
+ };
13143
+ /** A private activity target has no tab or duplicate command presentation. */
13144
+ const worktreeCommandActivityView = {
13145
+ target: WORKTREE_COMMAND_ACTIVITY,
13146
+ create: () => {
13147
+ let active = false;
13148
+ return {
13149
+ empty: false,
13150
+ replace: ({ nodes }) => active = nodes.length > 0,
13151
+ apply: ({ upserts }) => active ||= upserts.length > 0
13152
+ };
13153
+ },
13154
+ isActive: (active) => active
13155
+ };
13156
+ /** Activate only already retained bindings, including later generations and replay. */
13157
+ function installWorktreeCommandActivity(ctx) {
13158
+ ctx.effect(() => {
13159
+ const node = ctx.uiConversation.events.register(worktreeCommandActivityNode);
13160
+ const view = ctx.uiConversation.views.register(worktreeCommandActivityView);
13161
+ const tracked = /* @__PURE__ */ new WeakSet();
13162
+ let disposed = false;
13163
+ let queued = false;
13164
+ const sync = () => {
13165
+ if (disposed) return;
13166
+ for (const id of ctx.sessions.list.getSnapshot().ids ?? []) {
13167
+ const binding = ctx.sessions.binding(id);
13168
+ if (binding === void 0 || tracked.has(binding)) continue;
13169
+ ctx.uiConversation.binding(binding).activate(WORKTREE_COMMAND_ACTIVITY);
13170
+ tracked.add(binding);
13171
+ }
13172
+ };
13173
+ const schedule = () => {
13174
+ if (disposed || queued) return;
13175
+ queued = true;
13176
+ queueMicrotask(() => {
13177
+ queued = false;
13178
+ sync();
13179
+ });
13180
+ };
13181
+ const unsubscribe = ctx.sessions.list.subscribe(schedule);
13182
+ schedule();
13183
+ return () => {
13184
+ disposed = true;
13185
+ unsubscribe();
13186
+ view();
13187
+ node();
13188
+ };
13189
+ }, "clutch-dsh-worktree: command activity");
13190
+ }
13191
+ //#endregion
13192
+ //#region lib/client/settings/settings-navigation.js
13193
+ /** The rc.1 native Settings shell shares one viewing store between mouse and command entry. */
13194
+ function openWorktreeErrorSettings(slots) {
13195
+ const store = slots.entriesOfSlot("sidebar.settings")[0]?.store;
13196
+ if (typeof store?.create !== "function") return false;
13197
+ const instance = store.create();
13198
+ if (typeof instance?.actions?.openSection !== "function") return false;
13199
+ instance.actions.openSection("clutch-dsh-worktree");
13200
+ return true;
13201
+ }
13202
+ //#endregion
11994
13203
  //#region lib/client/context/worktree-context.js
11995
13204
  const none = (reason) => ({
11996
13205
  kind: "none",
@@ -12849,13 +14058,15 @@ window.__ModuleLoader__.load({
12849
14058
  "slots",
12850
14059
  "sessions",
12851
14060
  "workspaces",
12852
- "uiWorkspace"
14061
+ "uiWorkspace",
14062
+ "uiConversation"
12853
14063
  ];
12854
14064
  /**
12855
14065
  * DSH Client entry. The adapter is composed once per plugin fiber and is disposed
12856
14066
  * with that fiber, so slot consumers share one manager and one request lifetime.
12857
14067
  */
12858
14068
  function apply(ctx) {
14069
+ installWorktreeCommandActivity(ctx);
12859
14070
  const locale = ctx.locale;
12860
14071
  if (typeof document !== "undefined") ctx.effect(() => installWorktreePermissionIcon(document), "clutch-dsh-worktree: permission icon cleanup");
12861
14072
  ctx.effect(() => locale.register(WORKTREE_NS, {
@@ -12865,10 +14076,12 @@ window.__ModuleLoader__.load({
12865
14076
  const manager = createWorktreeConnectionAdapter(ctx.connection.rpc);
12866
14077
  const viewReader = createWorktreeViewReader(manager);
12867
14078
  const fullAccessConfirmation = createWorktreeFullAccessConfirmationController();
14079
+ const restartNotice = new RestartNotice((signal) => manager.probeHost(signal));
12868
14080
  const permissionNotice = createSnapshotStore(void 0);
12869
14081
  const permissionManager = typeof document !== "undefined" ? manager : void 0;
12870
14082
  const dashboardStore = createSnapshotStore(void 0);
12871
14083
  const reportPermissionNotice = (input, result) => {
14084
+ restartNotice.reportPermissionResult(result);
12872
14085
  const visible = result.status === "fallback-workspace-write" || result.status === "user-restricted" || result.status === "unverified";
12873
14086
  permissionNotice.set(visible ? {
12874
14087
  ...input,
@@ -12877,8 +14090,13 @@ window.__ModuleLoader__.load({
12877
14090
  };
12878
14091
  const sessions = ctx.sessions;
12879
14092
  const slots = ctx.slots;
14093
+ ctx.effect(() => slots.inject("shell.overlay", () => slots.register({
14094
+ name: "shell.overlay",
14095
+ id: "clutch-dsh-worktree-settings-icon",
14096
+ locale: WORKTREE_NS
14097
+ }, WorktreeSettingsNavIcon)), "clutch-dsh-worktree: settings icon cleanup");
12880
14098
  ctx.effect(() => {
12881
- const notice = new RestartNotice((signal) => manager.probeHost(signal));
14099
+ const notice = restartNotice;
12882
14100
  const check = () => void notice.check();
12883
14101
  const reset = ctx.on("connection/reset", check);
12884
14102
  const overlay = slots.inject("shell.overlay", () => slots.register({
@@ -12901,6 +14119,16 @@ window.__ModuleLoader__.load({
12901
14119
  viewReader,
12902
14120
  storeFactory: createSnapshotStore
12903
14121
  });
14122
+ const toolChanges = createWorktreeToolChangeMonitor({
14123
+ read: (revision, signal) => manager.watchToolChanges(revision, signal),
14124
+ changed: ({ workspaceId }) => {
14125
+ viewReader.invalidate(workspaceId);
14126
+ if (contextProjection.store.getSnapshot().workspaceId === workspaceId) contextProjection.refresh();
14127
+ }
14128
+ });
14129
+ ctx.effect(() => () => toolChanges.dispose(), "clutch-dsh-worktree: tool notification cleanup");
14130
+ ctx.on("connection/reset", () => toolChanges.reset());
14131
+ if (typeof document !== "undefined") toolChanges.start();
12904
14132
  ctx.effect(() => () => manager.dispose(), "clutch-dsh-worktree: connection cleanup");
12905
14133
  ctx.effect(() => () => viewReader.dispose(), "clutch-dsh-worktree: view reader cleanup");
12906
14134
  ctx.effect(() => () => fullAccessConfirmation.dispose(), "clutch-dsh-worktree: Full Access confirmation cleanup");
@@ -12908,6 +14136,17 @@ window.__ModuleLoader__.load({
12908
14136
  ctx.effect(() => () => contextProjection.dispose(), "clutch-dsh-worktree: Session context cleanup");
12909
14137
  contextProjection.refresh();
12910
14138
  const viewStore = createWorktreeViewStore();
14139
+ slots.inject("settings.section", () => slots.register({
14140
+ name: "settings.section",
14141
+ id: "clutch-dsh-worktree",
14142
+ order: 36,
14143
+ locale: WORKTREE_NS,
14144
+ label: () => ctx.locale.bind(WORKTREE_NS)("settings.title")
14145
+ }, (props) => (0, react.createElement)(WorktreeSettings, {
14146
+ ...props,
14147
+ manager
14148
+ })));
14149
+ ctx.effect(() => () => worktreeDiagnostics.dispose(), "clutch-dsh-worktree: diagnostics cleanup");
12911
14150
  const expandState = createWorktreeExpandStateStore(createSnapshotStore);
12912
14151
  const sessionOrder = createWorktreeSessionOrderStore(createSnapshotStore);
12913
14152
  ctx.effect(() => () => sessionOrder.dispose(), "clutch-dsh-worktree: Session order cleanup");
@@ -13075,6 +14314,7 @@ window.__ModuleLoader__.load({
13075
14314
  locale: WORKTREE_NS,
13076
14315
  inject: () => ({
13077
14316
  available: true,
14317
+ openErrorSettings: () => openWorktreeErrorSettings(ctx.slots),
13078
14318
  openResource: (address, options) => {
13079
14319
  const sidebar = sidebarRightController(ctx);
13080
14320
  if (sidebar && typeof sidebar.openResource === "function") {
@@ -13100,6 +14340,7 @@ window.__ModuleLoader__.load({
13100
14340
  hooks: { worktreeContext: contextProjection.store },
13101
14341
  manager,
13102
14342
  viewReader,
14343
+ subscribeToolChanges: toolChanges.subscribe,
13103
14344
  permission: permissionManager,
13104
14345
  confirmFullAccess: permissionManager === void 0 ? void 0 : fullAccessConfirmation.request,
13105
14346
  fullAccessConfirmation: typeof document === "undefined" ? void 0 : fullAccessConfirmation,