@cerbur/clutch-dsh-worktree 0.1.0 → 0.1.2

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.
package/lib/client.js CHANGED
@@ -8,6 +8,155 @@ window.__ModuleLoader__.load({
8
8
  let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
9
9
  let react = require("react");
10
10
  let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
11
+ //#region lib/client/locales.js
12
+ const WORKTREE_NS = "worktree";
13
+ const zh = {
14
+ "mode.open": "打开 Worktree 模式",
15
+ "mode.exit": "退出 Worktree 模式",
16
+ "mode.label": "Worktree",
17
+ "mode.navigation": "Worktree 导航",
18
+ "workspace.rename": "重命名",
19
+ "workspace.delete": "删除",
20
+ "workspace.expand": "展开 {name}",
21
+ "workspace.collapse": "收起 {name}",
22
+ "workspace.options": "工作区选项:{name}",
23
+ "workspace.addWorktree": "向 {name} 添加 Worktree",
24
+ "workspace.add": "添加工作区",
25
+ "workspace.search": "搜索工作区和会话",
26
+ "workspace.noMatches": "没有匹配的工作区",
27
+ "workspace.renameTitle": "重命名工作区",
28
+ "workspace.name": "工作区名称",
29
+ "workspace.duplicate": "已存在同名工作区。",
30
+ "workspace.deleteTitle": "删除工作区",
31
+ "workspace.deleteDescription": "删除“{name}”?这只会移除 DSH 工作区注册。目录、会话和 Git Worktree 会保留。",
32
+ "worktree.title": "Worktree",
33
+ "worktree.main": "Main",
34
+ "worktree.detached": "已分离 Worktree",
35
+ "worktree.repair": "Worktree 需要修复",
36
+ "worktree.ready": "活动 Worktree 已就绪",
37
+ "worktree.expand": "展开 {name}",
38
+ "worktree.collapse": "收起 {name}",
39
+ "worktree.options": "Worktree 选项:{name}",
40
+ "worktree.remove": "移除 Worktree",
41
+ "worktree.removeDescription": "移除“{name}”?Session 会保留在 DSH 中,并作为已分离关系继续可用。",
42
+ "worktree.addSession": "向 {name} 添加会话",
43
+ "worktree.noWorktrees": "暂无 Worktree",
44
+ "worktree.createTitle": "新建 Worktree",
45
+ "worktree.createDescription": "“{name}” · Worktree 路径由 DSH 管理。",
46
+ "worktree.baseBranch": "Worktree 基线分支",
47
+ "worktree.noLocalBranch": "没有本地分支",
48
+ "worktree.noBranches": "此工作区中没有找到本地分支。",
49
+ "worktree.name": "Worktree 名称",
50
+ "worktree.create": "创建 Worktree",
51
+ "session.options": "会话选项:{name}",
52
+ "session.rename": "重命名会话",
53
+ "session.fork": "Fork 会话",
54
+ "session.archive": "归档会话",
55
+ "session.expandMore": "展开其余 {count} 个会话",
56
+ "session.collapse": "收起",
57
+ "session.name": "会话名称",
58
+ "dialog.close": "关闭",
59
+ "dialog.closeWorkspaceRename": "关闭重命名工作区对话框",
60
+ "dialog.closeWorkspaceDelete": "关闭删除工作区对话框",
61
+ "dialog.closeWorktreeCreate": "关闭创建 Worktree 对话框",
62
+ "dialog.closeWorktreeRemove": "关闭移除 Worktree 对话框",
63
+ "dialog.cancel": "取消",
64
+ "dialog.rename": "重命名",
65
+ "dialog.delete": "删除",
66
+ "action.retry": "重试",
67
+ "action.retryBinding": "重试绑定",
68
+ "action.openCreatedSession": "打开已创建的 Session",
69
+ "status.loading": "正在加载工作区…",
70
+ "error.worktreeDataUnavailable": "Worktree 数据不可用,请重试。",
71
+ "error.connectionDisposed": "Worktree 连接已释放,请重新加载插件后重试。",
72
+ "error.connectionFailed": "Worktree endpoint {endpoint} 调用失败;连接错误,可重试:{reason}",
73
+ "error.invalidResult": "Worktree endpoint {endpoint} 返回了无效结果,请重试请求。",
74
+ "error.workspaceOrderingUnavailable": "工作区排序不可用,请重新连接后重试。",
75
+ "error.sessionOrderingUnavailable": "会话排序不可用,请重新连接后重试。",
76
+ "error.worktreeCreatedSessionUnavailable": "Worktree 已创建,但 Session 创建不可用,请重新连接后重试。",
77
+ "error.sessionCreationUnavailable": "Session 创建不可用,请重新连接后重试。",
78
+ "error.worktreeRecordMissing": "Worktree 创建未返回 Worktree 记录,请重试请求。",
79
+ "error.workspaceRenameUnavailable": "工作区重命名不可用,请重新连接后重试。",
80
+ "error.workspaceDeleteUnavailable": "工作区删除不可用,请重新连接后重试。",
81
+ "error.sessionRenameUnavailable": "会话重命名不可用,请重新连接后重试。",
82
+ "error.sessionBindingFailed": "Session {sessionId} 已创建,但 Worktree 绑定失败:{reason}",
83
+ "branch.current": "(当前)",
84
+ "branch.checkedOut": "(已检出)"
85
+ };
86
+ const en = {
87
+ "mode.open": "Open Worktree mode",
88
+ "mode.exit": "Exit Worktree mode",
89
+ "mode.label": "Worktree",
90
+ "mode.navigation": "Worktree navigation",
91
+ "workspace.rename": "Rename",
92
+ "workspace.delete": "Delete",
93
+ "workspace.expand": "Expand {name}",
94
+ "workspace.collapse": "Collapse {name}",
95
+ "workspace.options": "Workspace options for {name}",
96
+ "workspace.addWorktree": "Add Worktree to {name}",
97
+ "workspace.add": "Add Workspace",
98
+ "workspace.search": "Search Workspaces and Sessions",
99
+ "workspace.noMatches": "No matching Workspaces",
100
+ "workspace.renameTitle": "Rename Workspace",
101
+ "workspace.name": "Workspace name",
102
+ "workspace.duplicate": "A Workspace with this name already exists.",
103
+ "workspace.deleteTitle": "Delete Workspace",
104
+ "workspace.deleteDescription": "Delete {name}? This removes only the DSH Workspace registration. The directory, Sessions, and Git Worktrees will be retained.",
105
+ "worktree.title": "Worktrees",
106
+ "worktree.main": "Main",
107
+ "worktree.detached": "Detached Worktree",
108
+ "worktree.repair": "Worktree needs repair",
109
+ "worktree.ready": "Active Worktree ready",
110
+ "worktree.expand": "Expand {name}",
111
+ "worktree.collapse": "Collapse {name}",
112
+ "worktree.options": "Worktree options for {name}",
113
+ "worktree.remove": "Remove Worktree",
114
+ "worktree.removeDescription": "Remove {name}? Sessions stay in DSH and remain available as detached bindings.",
115
+ "worktree.addSession": "Add Session to {name}",
116
+ "worktree.noWorktrees": "No Worktrees",
117
+ "worktree.createTitle": "New Worktree",
118
+ "worktree.createDescription": "{name} · the Worktree path is managed by DSH.",
119
+ "worktree.baseBranch": "Worktree base branch",
120
+ "worktree.noLocalBranch": "No local branch",
121
+ "worktree.noBranches": "No local branches found in this Workspace.",
122
+ "worktree.name": "Worktree name",
123
+ "worktree.create": "Create Worktree",
124
+ "session.options": "Session options for {name}",
125
+ "session.rename": "Rename session",
126
+ "session.fork": "Fork session",
127
+ "session.archive": "Archive session",
128
+ "session.expandMore": "Expand {count} more",
129
+ "session.collapse": "Collapse",
130
+ "session.name": "Session name",
131
+ "dialog.close": "Close",
132
+ "dialog.closeWorkspaceRename": "Close Rename Workspace dialog",
133
+ "dialog.closeWorkspaceDelete": "Close Delete Workspace dialog",
134
+ "dialog.closeWorktreeCreate": "Close Create Worktree dialog",
135
+ "dialog.closeWorktreeRemove": "Close Remove Worktree dialog",
136
+ "dialog.cancel": "Cancel",
137
+ "dialog.rename": "Rename",
138
+ "dialog.delete": "Delete",
139
+ "action.retry": "Retry",
140
+ "action.retryBinding": "Retry Binding",
141
+ "action.openCreatedSession": "Open Created Session",
142
+ "status.loading": "Loading Workspaces…",
143
+ "error.worktreeDataUnavailable": "Worktree data is unavailable. Retry the request.",
144
+ "error.connectionDisposed": "Worktree connection is disposed; reload the plugin and retry.",
145
+ "error.connectionFailed": "Worktree endpoint {endpoint} failed; retryable connection error: {reason}",
146
+ "error.invalidResult": "Worktree endpoint {endpoint} returned an invalid result; retry the request.",
147
+ "error.workspaceOrderingUnavailable": "Workspace ordering is unavailable; retry after reconnecting.",
148
+ "error.sessionOrderingUnavailable": "Session ordering is unavailable; retry after reconnecting.",
149
+ "error.worktreeCreatedSessionUnavailable": "Worktree created, but Session creation is unavailable; retry after reconnecting.",
150
+ "error.sessionCreationUnavailable": "Session creation is unavailable; retry after reconnecting.",
151
+ "error.worktreeRecordMissing": "Worktree creation returned no Worktree record; retry the request.",
152
+ "error.workspaceRenameUnavailable": "Workspace rename is unavailable; retry after reconnecting.",
153
+ "error.workspaceDeleteUnavailable": "Workspace delete is unavailable; retry after reconnecting.",
154
+ "error.sessionRenameUnavailable": "Session rename is unavailable; retry after reconnecting.",
155
+ "error.sessionBindingFailed": "Session {sessionId} was created, but Worktree binding failed: {reason}",
156
+ "branch.current": " (current)",
157
+ "branch.checkedOut": " (checked out)"
158
+ };
159
+ //#endregion
11
160
  //#region lib/client/worktree-connection.js
12
161
  /** The one logical channel shared by the DSH Connection and Typert Gateway. */
13
162
  const WORKTREE_CONNECTION_CHANNEL = "/api";
@@ -49,7 +198,7 @@ window.__ModuleLoader__.load({
49
198
  function disposedError() {
50
199
  return new WorktreeConnectionError({
51
200
  code: "CLIENT_DISPOSED",
52
- message: "Worktree connection is disposed; reload the plugin and retry.",
201
+ message: "",
53
202
  details: {},
54
203
  retryable: false
55
204
  });
@@ -57,24 +206,28 @@ window.__ModuleLoader__.load({
57
206
  function connectionFailure(endpoint, error, code = "CONNECTION_CALL_FAILED") {
58
207
  return new WorktreeConnectionError({
59
208
  code,
60
- message: `Worktree endpoint ${endpoint} failed; retryable connection error: ${error instanceof Error ? error.message : String(error)}`,
209
+ message: error instanceof Error ? error.message : String(error),
61
210
  details: { endpoint },
62
211
  retryable: true,
63
212
  cause: error
64
213
  });
65
214
  }
66
215
  function gatewayFailure(endpoint, result) {
216
+ const rawDetails = isRecord(result.error.details) ? result.error.details : {};
67
217
  throw new WorktreeConnectionError({
68
218
  code: result.error.code,
69
- message: `Worktree endpoint ${endpoint} failed: ${result.error.message}`,
70
- details: isRecord(result.error.details) ? result.error.details : {},
219
+ message: result.error.message,
220
+ details: {
221
+ endpoint,
222
+ ...rawDetails
223
+ },
71
224
  retryable: true
72
225
  });
73
226
  }
74
227
  function invalidResult(endpoint) {
75
228
  return new WorktreeConnectionError({
76
229
  code: "WORKTREE_RPC_INVALID_RESULT",
77
- message: `Worktree endpoint ${endpoint} returned an invalid result; retry the request.`,
230
+ message: "",
78
231
  details: { endpoint },
79
232
  retryable: true
80
233
  });
@@ -134,7 +287,7 @@ window.__ModuleLoader__.load({
134
287
  }
135
288
  //#endregion
136
289
  //#region \0clutch-dsh-worktree-css:/Users/yuancheng/Documents/Code/clutch-dsh/packages/clutch-dsh-worktree/src/client/worktree.css.mjs
137
- const css = ".-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 overflow: hidden;\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: 56px;\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.-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-railContent {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-surface[data-collapsed='true'] .-cerbur-clutch-dsh-worktree-railContent {\n display: flex;\n flex: 1;\n align-items: flex-start;\n justify-content: center;\n padding-top: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-railButton,\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-railButton {\n width: 36px;\n height: 36px;\n color: var(--dsw-alias-label-secondary);\n font-size: 11px;\n font-weight: 600;\n}\n\n.-cerbur-clutch-dsh-worktree-railButton:hover,\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: 8px;\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}\n\n.-cerbur-clutch-dsh-worktree-closeButton {\n flex: none;\n width: 28px;\n height: 28px;\n font-size: 18px;\n line-height: 1;\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-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-actionLabel {\n display: grid;\n gap: 3px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\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-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-searchRow {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 10px 6px;\n}\n\n.-cerbur-clutch-dsh-worktree-searchIcon {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n color: var(--dsw-alias-label-secondary);\n}\n\n.-cerbur-clutch-dsh-worktree-searchInput {\n min-width: 0;\n box-sizing: border-box;\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 outline: none;\n}\n\n.-cerbur-clutch-dsh-worktree-searchInput {\n width: 100%;\n padding: 6px 8px;\n font-size: 13px;\n line-height: 18px;\n}\n\n.-cerbur-clutch-dsh-worktree-searchInput:focus,\n.-cerbur-clutch-dsh-worktree-actionSelect: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 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 display: inline-flex;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover .-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-worktreeState {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 16px;\n margin-right: 2px;\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-treeActionSlot,\n.-cerbur-clutch-dsh-worktree-workspaceActions {\n position: relative;\n display: inline-flex;\n flex: 0 0 64px;\n align-items: center;\n justify-content: flex-end;\n width: 64px;\n height: 28px;\n margin-left: auto;\n}\n\n.-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-menuAction {\n position: absolute;\n top: 0;\n right: 32px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child {\n position: absolute;\n top: 0;\n right: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-menuAction {\n display: inline-flex;\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 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-treeChildren {\n margin-left: 24px;\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.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-disclosureButton {\n width: 22px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow {\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\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.-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-rowActions {\n display: none;\n flex: none;\n align-items: center;\n gap: 4px;\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-treeSessionRow:hover .-cerbur-clutch-dsh-worktree-rowActions,\n.-cerbur-clutch-dsh-worktree-treeSessionRow[data-menu-open='true'] .-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-treeGuide {\n flex: none;\n width: 20px;\n color: var(--dsw-alias-label-tertiary);\n text-align: center;\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-modalField {\n display: grid;\n gap: 5px;\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n}\n";
290
+ const css = ".-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 overflow: hidden;\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: 56px;\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.-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-railContent {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-surface[data-collapsed='true'] .-cerbur-clutch-dsh-worktree-railContent {\n display: flex;\n flex: 1;\n align-items: flex-start;\n justify-content: center;\n padding-top: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-railButton,\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-railButton {\n width: 36px;\n height: 36px;\n color: var(--dsw-alias-label-secondary);\n font-size: 11px;\n font-weight: 600;\n}\n\n.-cerbur-clutch-dsh-worktree-railButton:hover,\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: 8px;\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}\n\n.-cerbur-clutch-dsh-worktree-closeButton {\n flex: none;\n width: 28px;\n height: 28px;\n font-size: 18px;\n line-height: 1;\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-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-actionLabel {\n display: grid;\n gap: 3px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\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-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-searchRow {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 10px 6px;\n}\n\n.-cerbur-clutch-dsh-worktree-searchIcon {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n color: var(--dsw-alias-label-secondary);\n}\n\n.-cerbur-clutch-dsh-worktree-searchInput {\n min-width: 0;\n box-sizing: border-box;\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 outline: none;\n}\n\n.-cerbur-clutch-dsh-worktree-searchInput {\n width: 100%;\n padding: 6px 8px;\n font-size: 13px;\n line-height: 18px;\n}\n\n.-cerbur-clutch-dsh-worktree-searchInput:focus,\n.-cerbur-clutch-dsh-worktree-actionSelect: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 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-worktreeState {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 12px;\n margin-right: 0;\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 text-transform: uppercase;\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.-cerbur-clutch-dsh-worktree-treeActionSlot,\n.-cerbur-clutch-dsh-worktree-workspaceActions {\n position: relative;\n display: inline-flex;\n flex: 0 0 64px;\n align-items: center;\n justify-content: flex-end;\n width: 64px;\n height: 28px;\n margin-left: auto;\n}\n\n.-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-menuAction {\n position: absolute;\n top: 0;\n right: 32px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child {\n position: absolute;\n top: 0;\n right: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-menuAction {\n display: inline-flex;\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-worktreeRow:hover .-cerbur-clutch-dsh-worktree-menuAction,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-menuAction {\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-treeChildren {\n margin-left: 24px;\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.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-worktreeIcon,\n.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-disclosureButton {\n width: 22px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow {\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\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.-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-rowActions {\n display: none;\n flex: none;\n align-items: center;\n gap: 4px;\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-treeSessionRow:hover .-cerbur-clutch-dsh-worktree-rowActions,\n.-cerbur-clutch-dsh-worktree-treeSessionRow[data-menu-open='true'] .-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-treeGuide {\n flex: none;\n width: 20px;\n color: var(--dsw-alias-label-tertiary);\n text-align: center;\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-modalField {\n display: grid;\n gap: 5px;\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n}\n";
138
291
  const styleId = "@cerbur/clutch-dsh-worktree/worktree.css";
139
292
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@cerbur/clutch-dsh-worktree/worktree.css\"]") === null) {
140
293
  const tag = document.createElement("style");
@@ -187,6 +340,7 @@ window.__ModuleLoader__.load({
187
340
  "disclosureButton": "-cerbur-clutch-dsh-worktree-disclosureButton",
188
341
  "worktreeState": "-cerbur-clutch-dsh-worktree-worktreeState",
189
342
  "workspaceTitle": "-cerbur-clutch-dsh-worktree-workspaceTitle",
343
+ "worktreeHoverTitle": "-cerbur-clutch-dsh-worktree-worktreeHoverTitle",
190
344
  "treeActionSlot": "-cerbur-clutch-dsh-worktree-treeActionSlot",
191
345
  "workspaceActions": "-cerbur-clutch-dsh-worktree-workspaceActions",
192
346
  "menuAction": "-cerbur-clutch-dsh-worktree-menuAction",
@@ -209,7 +363,7 @@ window.__ModuleLoader__.load({
209
363
  //#endregion
210
364
  //#region lib/client/WorktreeModeAction.js
211
365
  /** Footer action that enters/exits the peer Worktree navigation mode. */
212
- function WorktreeModeAction({ wide, useStore, actions, available }) {
366
+ function WorktreeModeAction({ wide, useStore, actions, t, available }) {
213
367
  if (!available) return null;
214
368
  const active = useStore((state) => state.viewMode) === "worktree";
215
369
  return (0, react_jsx_runtime.jsxs)("button", {
@@ -218,15 +372,15 @@ window.__ModuleLoader__.load({
218
372
  "data-worktree-mode-action": true,
219
373
  "data-active": active || void 0,
220
374
  "data-collapsed": !wide || void 0,
221
- "aria-label": active ? "Exit Worktree mode" : "Open Worktree mode",
375
+ "aria-label": active ? t("mode.exit") : t("mode.open"),
222
376
  "aria-pressed": active,
223
- title: active ? "Exit Worktree mode" : "Worktree mode",
377
+ title: active ? t("mode.exit") : t("mode.label"),
224
378
  onClick: () => {
225
379
  actions.setViewMode(active ? "workspace-session" : "worktree");
226
380
  },
227
381
  children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBranchOutline16, { size: wide ? 16 : 18 }), wide && (0, react_jsx_runtime.jsx)("span", {
228
382
  className: worktree_css_default.actionLabel,
229
- children: "Worktree"
383
+ children: t("mode.label")
230
384
  })]
231
385
  });
232
386
  }
@@ -279,7 +433,7 @@ window.__ModuleLoader__.load({
279
433
  "新会话",
280
434
  "New Session"
281
435
  ];
282
- const buttons = [...root.querySelectorAll("button")];
436
+ const buttons = Array.from(root.querySelectorAll("button"));
283
437
  const visibleLabel = buttons.find((button) => {
284
438
  const text = button.textContent?.trim();
285
439
  return text === "新会话" || text === "New Session";
@@ -404,6 +558,38 @@ window.__ModuleLoader__.load({
404
558
  };
405
559
  }
406
560
  //#endregion
561
+ //#region lib/client/worktree-error-copy.js
562
+ function detail(error, name) {
563
+ const value = error.details?.[name];
564
+ return typeof value === "string" ? value : "";
565
+ }
566
+ function reason(error, t) {
567
+ return error.message.length > 0 ? error.message : t("error.worktreeDataUnavailable");
568
+ }
569
+ function formatWorktreeViewError(error, t) {
570
+ switch (error.code) {
571
+ case "CLIENT_DISPOSED": return t("error.connectionDisposed");
572
+ case "CONNECTION_CALL_FAILED": return t("error.connectionFailed", {
573
+ endpoint: detail(error, "endpoint"),
574
+ reason: reason(error, t)
575
+ });
576
+ case "WORKTREE_RPC_INVALID_RESULT": return t("error.invalidResult", { endpoint: detail(error, "endpoint") });
577
+ case "WORKSPACE_ORDER_UNAVAILABLE": return t("error.workspaceOrderingUnavailable");
578
+ case "SESSION_ORDER_UNAVAILABLE": return t("error.sessionOrderingUnavailable");
579
+ case "SESSION_CREATE_UNAVAILABLE": return t("error.sessionCreationUnavailable");
580
+ case "WORKTREE_CREATED_SESSION_UNAVAILABLE": return t("error.worktreeCreatedSessionUnavailable");
581
+ case "WORKTREE_RECORD_MISSING": return t("error.worktreeRecordMissing");
582
+ case "WORKSPACE_RENAME_UNAVAILABLE": return t("error.workspaceRenameUnavailable");
583
+ case "WORKSPACE_DELETE_UNAVAILABLE": return t("error.workspaceDeleteUnavailable");
584
+ case "SESSION_RENAME_UNAVAILABLE": return t("error.sessionRenameUnavailable");
585
+ case "SESSION_BINDING_FAILED": return t("error.sessionBindingFailed", {
586
+ sessionId: detail(error, "sessionId"),
587
+ reason: reason(error, t)
588
+ });
589
+ default: return error.message.length > 0 ? error.message : t("error.worktreeDataUnavailable");
590
+ }
591
+ }
592
+ //#endregion
407
593
  //#region lib/client/worktree-view.js
408
594
  /** A DSH Session exists even when the external Worktree binding needs repair. */
409
595
  var WorktreeSessionBindingError = class extends Error {
@@ -413,7 +599,7 @@ window.__ModuleLoader__.load({
413
599
  cause;
414
600
  constructor(sessionId, cause) {
415
601
  const reason = cause instanceof Error ? cause.message : String(cause);
416
- super(`Session ${sessionId} was created, but Worktree binding failed: ${reason}`);
602
+ super(reason);
417
603
  this.name = "WorktreeSessionBindingError";
418
604
  this.sessionId = sessionId;
419
605
  this.cause = cause;
@@ -496,24 +682,43 @@ window.__ModuleLoader__.load({
496
682
  input.openSession(sessionId);
497
683
  return sessionId;
498
684
  }
685
+ function recordDetails(value) {
686
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
687
+ const details = value.details;
688
+ if (typeof details !== "object" || details === null || Array.isArray(details)) return void 0;
689
+ return details;
690
+ }
499
691
  /** Convert any adapter/Gateway failure into renderable, retry-aware UI data. */
500
692
  function toWorktreeViewError(error) {
501
693
  if (typeof error === "object" && error !== null) {
502
694
  const candidate = error;
695
+ const details = error instanceof WorktreeSessionBindingError ? {
696
+ ...recordDetails(error) ?? {},
697
+ sessionId: error.sessionId
698
+ } : recordDetails(error);
503
699
  return {
504
700
  code: typeof candidate.code === "string" ? candidate.code : "WORKTREE_VIEW_FAILED",
505
- message: typeof candidate.message === "string" ? candidate.message : "Worktree data is unavailable. Retry the request.",
506
- retryable: candidate.retryable !== false
701
+ message: typeof candidate.message === "string" ? candidate.message : "",
702
+ retryable: candidate.retryable !== false,
703
+ ...details === void 0 ? {} : { details }
507
704
  };
508
705
  }
509
706
  return {
510
707
  code: "WORKTREE_VIEW_FAILED",
511
- message: "Worktree data is unavailable. Retry the request.",
708
+ message: "",
512
709
  retryable: true
513
710
  };
514
711
  }
515
712
  //#endregion
516
713
  //#region lib/client/WorktreeSurface.js
714
+ function toNativeWorktreeViewError(error) {
715
+ const viewError = toWorktreeViewError(error);
716
+ if (typeof error === "object" && error !== null) return viewError;
717
+ return {
718
+ ...viewError,
719
+ message: String(error)
720
+ };
721
+ }
517
722
  const EMPTY_READ_STATE = {
518
723
  status: "idle",
519
724
  views: []
@@ -547,15 +752,15 @@ window.__ModuleLoader__.load({
547
752
  return view.bindings.some((binding) => includesText(sessionLabel(binding.sessionId, sessions), query));
548
753
  }
549
754
  /** Workspace row using the native DSH menu, fixed action column, and drag contract. */
550
- function WorktreeWorkspaceRow({ workspace, expanded, actionPending, menuOpen, drag, onToggle, onCreateWorktree, onRename, onDelete, onMenuOpenChange }) {
755
+ function WorktreeWorkspaceRow({ t, workspace, expanded, actionPending, menuOpen, drag, onToggle, onCreateWorktree, onRename, onDelete, onMenuOpenChange }) {
551
756
  const workspaceMenuItems = [{
552
757
  id: "rename",
553
- label: "Rename",
758
+ label: t("workspace.rename"),
554
759
  icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, {}),
555
760
  disabled: actionPending
556
761
  }, {
557
762
  id: "delete",
558
- label: "Delete",
763
+ label: t("workspace.delete"),
559
764
  icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutline16, {}),
560
765
  danger: true,
561
766
  disabled: actionPending
@@ -590,7 +795,7 @@ window.__ModuleLoader__.load({
590
795
  (0, react_jsx_runtime.jsx)("button", {
591
796
  type: "button",
592
797
  className: `${worktree_css_default.disclosureButton} ${worktree_css_default.workspaceDisclosure}`,
593
- "aria-label": `${expanded ? "Collapse" : "Expand"} ${workspace.title}`,
798
+ "aria-label": t(expanded ? "workspace.collapse" : "workspace.expand", { name: workspace.title }),
594
799
  "aria-expanded": expanded,
595
800
  onClick: (event) => {
596
801
  event.stopPropagation();
@@ -628,7 +833,7 @@ window.__ModuleLoader__.load({
628
833
  type: "button",
629
834
  className: worktree_css_default.iconButton,
630
835
  "data-workspace-menu": true,
631
- "aria-label": `Workspace options for ${workspace.title}`,
836
+ "aria-label": t("workspace.options", { name: workspace.title }),
632
837
  onClick: (event) => {
633
838
  event.stopPropagation();
634
839
  onMenuOpenChange(!menuOpen);
@@ -640,7 +845,7 @@ window.__ModuleLoader__.load({
640
845
  type: "button",
641
846
  className: worktree_css_default.iconButton,
642
847
  "data-add-worktree": true,
643
- "aria-label": `Add Worktree to ${workspace.title}`,
848
+ "aria-label": t("workspace.addWorktree", { name: workspace.title }),
644
849
  onClick: (event) => {
645
850
  event.stopPropagation();
646
851
  onCreateWorktree();
@@ -652,18 +857,19 @@ window.__ModuleLoader__.load({
652
857
  });
653
858
  }
654
859
  /** Shared Main/Worktree group row with parameterized icon, state, and actions. */
655
- function WorktreeGroupRow({ kind, label, expanded, icon, workspaceTitle, state, stateLabel, onToggle, onCreateSession }) {
860
+ function WorktreeGroupRow({ t, kind, label, expanded, icon, workspaceTitle, state, stateLabel, onToggle, onCreateSession, menu }) {
656
861
  const main = kind === "main";
657
- return (0, react_jsx_runtime.jsxs)("div", {
862
+ const row = (0, react_jsx_runtime.jsxs)("div", {
658
863
  className: worktree_css_default.worktreeRow,
659
864
  "data-main-group": main ? "true" : void 0,
660
865
  "data-main-expanded": main ? String(expanded) : void 0,
866
+ "data-menu-open": menu?.open ? "true" : void 0,
661
867
  onClick: onToggle,
662
868
  children: [
663
869
  (0, react_jsx_runtime.jsx)("button", {
664
870
  type: "button",
665
871
  className: `${worktree_css_default.disclosureButton} ${worktree_css_default.worktreeDisclosure}`,
666
- "aria-label": `${expanded ? "Collapse" : "Expand"} ${label}`,
872
+ "aria-label": t(expanded ? "worktree.collapse" : "worktree.expand", { name: label }),
667
873
  "aria-expanded": expanded,
668
874
  onClick: (event) => {
669
875
  event.stopPropagation();
@@ -687,44 +893,86 @@ window.__ModuleLoader__.load({
687
893
  className: worktree_css_default.worktreeLabel,
688
894
  children: label
689
895
  }),
690
- (0, react_jsx_runtime.jsx)("span", {
896
+ (0, react_jsx_runtime.jsxs)("span", {
691
897
  className: worktree_css_default.treeActionSlot,
692
- children: onCreateSession !== void 0 && (0, react_jsx_runtime.jsx)("button", {
898
+ children: [menu !== void 0 && (0, react_jsx_runtime.jsx)("span", {
899
+ className: worktree_css_default.menuAction,
900
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
901
+ open: menu.open,
902
+ onClose: () => {
903
+ menu.onOpenChange(false);
904
+ },
905
+ items: [{
906
+ id: "remove",
907
+ label: t("worktree.remove"),
908
+ icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutline16, {}),
909
+ danger: true,
910
+ disabled: menu.disabled
911
+ }],
912
+ onSelect: (id) => {
913
+ menu.onOpenChange(false);
914
+ if (id === "remove") menu.onRemove();
915
+ },
916
+ portal: true,
917
+ closeOnPointerLeave: true,
918
+ anchor: (0, react_jsx_runtime.jsx)("button", {
919
+ type: "button",
920
+ className: worktree_css_default.iconButton,
921
+ "data-worktree-menu": true,
922
+ "aria-label": t("worktree.options", { name: menu.label }),
923
+ onClick: (event) => {
924
+ event.stopPropagation();
925
+ menu.onOpenChange(!menu.open);
926
+ },
927
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEllipsisOutline16, {})
928
+ })
929
+ })
930
+ }), onCreateSession !== void 0 && (0, react_jsx_runtime.jsx)("button", {
693
931
  type: "button",
694
932
  className: worktree_css_default.iconButton,
695
933
  "data-add-main-session": main ? "true" : void 0,
696
934
  "data-add-session": main ? void 0 : "true",
697
- "aria-label": `Add Session to ${workspaceTitle}`,
935
+ "aria-label": t("worktree.addSession", { name: workspaceTitle }),
698
936
  onClick: (event) => {
699
937
  event.stopPropagation();
700
938
  onCreateSession();
701
939
  },
702
940
  children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutline16, {})
703
- })
941
+ })]
704
942
  })
705
943
  ]
706
944
  });
945
+ if (main) return row;
946
+ return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.HoverCard, {
947
+ anchor: row,
948
+ content: (0, react_jsx_runtime.jsx)("div", {
949
+ className: worktree_css_default.worktreeHoverTitle,
950
+ children: label
951
+ }),
952
+ openDelayMs: 500,
953
+ disabled: menu?.open === true
954
+ });
707
955
  }
708
956
  /** Worktree-mode Session row with the same trailing options menu as native DSH rows. */
709
- function WorktreeSessionRow({ sessionId, label, drag, actionPending, onOpen, onRename, onFork, onArchive }) {
957
+ function WorktreeSessionRow({ t, sessionId, label, drag, actionPending, onOpen, onRename, onFork, onArchive }) {
710
958
  const [menuOpen, setMenuOpen] = (0, react.useState)(false);
711
959
  const markerClass = drag.marker === "before" ? worktree_css_default.dropBefore : drag.marker === "after" ? worktree_css_default.dropAfter : "";
712
960
  const sessionMenuItems = [
713
961
  {
714
962
  id: "rename",
715
- label: "Rename",
963
+ label: t("session.rename"),
716
964
  icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, {}),
717
965
  disabled: onRename === void 0 || actionPending
718
966
  },
719
967
  {
720
968
  id: "fork",
721
- label: "Fork session",
969
+ label: t("session.fork"),
722
970
  icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBranchOutline16, {}),
723
971
  disabled: onFork === void 0 || actionPending
724
972
  },
725
973
  {
726
974
  id: "archive",
727
- label: "Archive session",
975
+ label: t("session.archive"),
728
976
  icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconArchiveOutline20, { size: 16 }),
729
977
  disabled: onArchive === void 0 || actionPending
730
978
  }
@@ -785,7 +1033,7 @@ window.__ModuleLoader__.load({
785
1033
  type: "button",
786
1034
  className: worktree_css_default.iconButton,
787
1035
  "data-session-menu": true,
788
- "aria-label": `Session options for ${label}`,
1036
+ "aria-label": t("session.options", { name: label }),
789
1037
  onClick: (event) => {
790
1038
  event.stopPropagation();
791
1039
  setMenuOpen((current) => !current);
@@ -796,10 +1044,11 @@ window.__ModuleLoader__.load({
796
1044
  })]
797
1045
  });
798
1046
  }
799
- function WorktreeSessionGroup({ groupKey, sessionIds, workspaceId, expanded, actionPending, sessions, dragState, onToggleExpanded, onStartDrag, onHoverDrag, onClearDrag, onFinishDrag, onCommitDrag, onOpen, onRename, onFork, onArchive }) {
1047
+ function WorktreeSessionGroup({ t, groupKey, sessionIds, workspaceId, expanded, actionPending, sessions, dragState, onToggleExpanded, onStartDrag, onHoverDrag, onClearDrag, onFinishDrag, onCommitDrag, onOpen, onRename, onFork, onArchive }) {
800
1048
  const visibleSessionIds = expanded ? sessionIds : sessionIds.slice(0, 5);
801
1049
  const sameGroupDrag = dragState?.groupKey === groupKey;
802
1050
  return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [visibleSessionIds.map((sessionId) => (0, react_jsx_runtime.jsx)(WorktreeSessionRow, {
1051
+ t,
803
1052
  sessionId,
804
1053
  label: sessionLabel(sessionId, sessions),
805
1054
  drag: {
@@ -836,14 +1085,14 @@ window.__ModuleLoader__.load({
836
1085
  className: worktree_css_default.sessionOverflowButton,
837
1086
  "aria-expanded": expanded,
838
1087
  onClick: onToggleExpanded,
839
- children: expanded ? "Collapse" : `Expand ${sessionIds.length - 5} more`
1088
+ children: expanded ? t("session.collapse") : t("session.expandMore", { count: sessionIds.length - 5 })
840
1089
  })] });
841
1090
  }
842
1091
  /**
843
1092
  * Peer Worktree navigation surface. It keeps the original DSH Workspace mode
844
1093
  * intact and renders a browser-local Workspace → Worktree → Session projection.
845
1094
  */
846
- function WorktreeSurface({ useStore, actions, useSessions, useWorkspaces, available, manager, createWorkspace, createSessionForWorktree: createSessionCallback, createMainSession, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, insertSessionBefore, renameSession, forkSession, archiveSession, ensureSessionWorkspace, syncSessionWorkspaces, openSession }) {
1095
+ function WorktreeSurface({ useStore, actions, useSessions, useWorkspaces, t, available, manager, createWorkspace, createSessionForWorktree: createSessionCallback, createMainSession, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, insertSessionBefore, renameSession, forkSession, archiveSession, ensureSessionWorkspace, syncSessionWorkspaces, openSession }) {
847
1096
  const mode = effectiveViewMode(useStore((state) => state.viewMode), available && manager !== void 0);
848
1097
  const sessions = useSessions((state) => state);
849
1098
  const workspaces = useWorkspaces((state) => state);
@@ -855,6 +1104,8 @@ window.__ModuleLoader__.load({
855
1104
  const [expandedWorktrees, setExpandedWorktrees] = (0, react.useState)({});
856
1105
  const [worktreeModalWorkspaceId, setWorktreeModalWorkspaceId] = (0, react.useState)();
857
1106
  const [openWorkspaceMenuId, setOpenWorkspaceMenuId] = (0, react.useState)();
1107
+ const [openWorktreeMenuId, setOpenWorktreeMenuId] = (0, react.useState)();
1108
+ const [worktreeRemoval, setWorktreeRemoval] = (0, react.useState)();
858
1109
  const [selectedBranch, setSelectedBranch] = (0, react.useState)("");
859
1110
  const [newBranch, setNewBranch] = (0, react.useState)("");
860
1111
  const [pendingSessionBinding, setPendingSessionBinding] = (0, react.useState)();
@@ -953,7 +1204,11 @@ window.__ModuleLoader__.load({
953
1204
  const target = workspaceRenameTarget;
954
1205
  if (workspaceRenameBlocked || target === void 0) return;
955
1206
  if (renameWorkspace === void 0) {
956
- setWorkspaceRenameError("Workspace rename is unavailable; retry after reconnecting.");
1207
+ setWorkspaceRenameError({
1208
+ code: "WORKSPACE_RENAME_UNAVAILABLE",
1209
+ message: "",
1210
+ retryable: true
1211
+ });
957
1212
  return;
958
1213
  }
959
1214
  setWorkspaceRenamePending(true);
@@ -962,7 +1217,7 @@ window.__ModuleLoader__.load({
962
1217
  await renameWorkspace(target.workspaceId, workspaceRenameTrimmed);
963
1218
  setWorkspaceRenameTarget(void 0);
964
1219
  } catch (error) {
965
- setWorkspaceRenameError(error instanceof Error ? error.message : String(error));
1220
+ setWorkspaceRenameError(toNativeWorktreeViewError(error));
966
1221
  } finally {
967
1222
  setWorkspaceRenamePending(false);
968
1223
  }
@@ -983,7 +1238,11 @@ window.__ModuleLoader__.load({
983
1238
  const target = workspaceDeleteTarget;
984
1239
  if (target === void 0 || workspaceDeletePending) return;
985
1240
  if (deleteWorkspace === void 0) {
986
- setWorkspaceDeleteError("Workspace delete is unavailable; retry after reconnecting.");
1241
+ setWorkspaceDeleteError({
1242
+ code: "WORKSPACE_DELETE_UNAVAILABLE",
1243
+ message: "",
1244
+ retryable: true
1245
+ });
987
1246
  return;
988
1247
  }
989
1248
  setWorkspaceDeletePending(true);
@@ -992,7 +1251,7 @@ window.__ModuleLoader__.load({
992
1251
  await deleteWorkspace(target.workspaceId);
993
1252
  setWorkspaceDeleteTarget(void 0);
994
1253
  } catch (error) {
995
- setWorkspaceDeleteError(error instanceof Error ? error.message : String(error));
1254
+ setWorkspaceDeleteError(toNativeWorktreeViewError(error));
996
1255
  } finally {
997
1256
  setWorkspaceDeletePending(false);
998
1257
  }
@@ -1011,7 +1270,7 @@ window.__ModuleLoader__.load({
1011
1270
  if (insertWorkspaceBefore === void 0) {
1012
1271
  setActionError({
1013
1272
  code: "WORKSPACE_ORDER_UNAVAILABLE",
1014
- message: "Workspace ordering is unavailable; retry after reconnecting.",
1273
+ message: "",
1015
1274
  retryable: true
1016
1275
  });
1017
1276
  return;
@@ -1034,7 +1293,7 @@ window.__ModuleLoader__.load({
1034
1293
  if (insertSessionBefore === void 0) {
1035
1294
  setActionError({
1036
1295
  code: "SESSION_ORDER_UNAVAILABLE",
1037
- message: "Session ordering is unavailable; retry after reconnecting.",
1296
+ message: "",
1038
1297
  retryable: true
1039
1298
  });
1040
1299
  return;
@@ -1062,7 +1321,11 @@ window.__ModuleLoader__.load({
1062
1321
  const title = sessionRenameDraft.trim();
1063
1322
  if (target === void 0 || title.length === 0 || sessionRenamePending) return;
1064
1323
  if (renameSession === void 0) {
1065
- setSessionRenameError("Session rename is unavailable; retry after reconnecting.");
1324
+ setSessionRenameError({
1325
+ code: "SESSION_RENAME_UNAVAILABLE",
1326
+ message: "",
1327
+ retryable: true
1328
+ });
1066
1329
  return;
1067
1330
  }
1068
1331
  setSessionRenamePending(true);
@@ -1071,7 +1334,7 @@ window.__ModuleLoader__.load({
1071
1334
  await renameSession(target.sessionId, title);
1072
1335
  setSessionRenameTarget(void 0);
1073
1336
  } catch (error) {
1074
- setSessionRenameError(error instanceof Error ? error.message : String(error));
1337
+ setSessionRenameError(toNativeWorktreeViewError(error));
1075
1338
  } finally {
1076
1339
  setSessionRenamePending(false);
1077
1340
  }
@@ -1123,13 +1386,17 @@ window.__ModuleLoader__.load({
1123
1386
  type: "createWorktree",
1124
1387
  input
1125
1388
  });
1126
- if (createdWorktree === void 0) throw new Error("Worktree creation returned no Worktree record; retry the request.");
1389
+ if (createdWorktree === void 0) throw {
1390
+ code: "WORKTREE_RECORD_MISSING",
1391
+ message: "",
1392
+ retryable: true
1393
+ };
1127
1394
  setWorktreeModalWorkspaceId(void 0);
1128
1395
  if (createSessionCallback === void 0) {
1129
1396
  await refresh();
1130
1397
  setActionError({
1131
- code: "SESSION_CREATE_UNAVAILABLE",
1132
- message: "Worktree created, but Session creation is unavailable; retry after reconnecting.",
1398
+ code: "WORKTREE_CREATED_SESSION_UNAVAILABLE",
1399
+ message: "",
1133
1400
  retryable: true
1134
1401
  });
1135
1402
  return;
@@ -1159,7 +1426,7 @@ window.__ModuleLoader__.load({
1159
1426
  if (createSessionCallback === void 0) {
1160
1427
  setActionError({
1161
1428
  code: "SESSION_CREATE_UNAVAILABLE",
1162
- message: "Session creation is unavailable; retry after reconnecting.",
1429
+ message: "",
1163
1430
  retryable: true
1164
1431
  });
1165
1432
  return;
@@ -1212,7 +1479,7 @@ window.__ModuleLoader__.load({
1212
1479
  className: worktree_css_default.surface,
1213
1480
  "data-worktree-surface": true,
1214
1481
  "data-collapsed": collapsed || void 0,
1215
- "aria-label": "Worktree navigation",
1482
+ "aria-label": t("mode.navigation"),
1216
1483
  style: {
1217
1484
  width: `${width}px`,
1218
1485
  ...bounds.ready ? {
@@ -1231,11 +1498,11 @@ window.__ModuleLoader__.load({
1231
1498
  className: worktree_css_default.header,
1232
1499
  children: [(0, react_jsx_runtime.jsx)("span", {
1233
1500
  className: worktree_css_default.title,
1234
- children: "Worktrees"
1501
+ children: t("worktree.title")
1235
1502
  }), (0, react_jsx_runtime.jsx)("button", {
1236
1503
  type: "button",
1237
1504
  className: worktree_css_default.closeButton,
1238
- "aria-label": "Exit Worktree mode",
1505
+ "aria-label": t("mode.exit"),
1239
1506
  onClick: () => {
1240
1507
  actions.setViewMode("workspace-session");
1241
1508
  },
@@ -1252,8 +1519,8 @@ window.__ModuleLoader__.load({
1252
1519
  }),
1253
1520
  (0, react_jsx_runtime.jsx)("input", {
1254
1521
  className: worktree_css_default.searchInput,
1255
- "aria-label": "Search Workspaces and Sessions",
1256
- placeholder: "Search Workspaces and Sessions",
1522
+ "aria-label": t("workspace.search"),
1523
+ placeholder: t("workspace.search"),
1257
1524
  value: searchQuery,
1258
1525
  onChange: (event) => {
1259
1526
  setSearchQuery(event.currentTarget.value);
@@ -1262,7 +1529,7 @@ window.__ModuleLoader__.load({
1262
1529
  (0, react_jsx_runtime.jsx)("button", {
1263
1530
  type: "button",
1264
1531
  className: worktree_css_default.iconButton,
1265
- "aria-label": "Add Workspace",
1532
+ "aria-label": t("workspace.add"),
1266
1533
  onClick: () => {
1267
1534
  if (createWorkspace !== void 0) runMutation(createWorkspace);
1268
1535
  },
@@ -1282,7 +1549,7 @@ window.__ModuleLoader__.load({
1282
1549
  (0, react_jsx_runtime.jsx)("p", {
1283
1550
  className: worktree_css_default.message,
1284
1551
  "data-error": "true",
1285
- children: actionError.message
1552
+ children: formatWorktreeViewError(actionError, t)
1286
1553
  }),
1287
1554
  pendingSessionBinding !== void 0 && (0, react_jsx_runtime.jsxs)("div", {
1288
1555
  className: worktree_css_default.recoveryActions,
@@ -1293,7 +1560,7 @@ window.__ModuleLoader__.load({
1293
1560
  onClick: () => {
1294
1561
  retrySessionBinding();
1295
1562
  },
1296
- children: "Retry Binding"
1563
+ children: t("action.retryBinding")
1297
1564
  }), (0, react_jsx_runtime.jsx)("button", {
1298
1565
  type: "button",
1299
1566
  className: worktree_css_default.actionButton,
@@ -1304,7 +1571,7 @@ window.__ModuleLoader__.load({
1304
1571
  setActionError(void 0);
1305
1572
  openSession(sessionId);
1306
1573
  },
1307
- children: "Open Created Session"
1574
+ children: t("action.openCreatedSession")
1308
1575
  })]
1309
1576
  }),
1310
1577
  actionError.retryable && (0, react_jsx_runtime.jsx)("button", {
@@ -1314,13 +1581,13 @@ window.__ModuleLoader__.load({
1314
1581
  setActionError(void 0);
1315
1582
  refresh();
1316
1583
  },
1317
- children: "Retry"
1584
+ children: t("action.retry")
1318
1585
  })
1319
1586
  ]
1320
1587
  }),
1321
1588
  readState.status === "loading" && (0, react_jsx_runtime.jsx)("p", {
1322
1589
  className: worktree_css_default.message,
1323
- children: "Loading Workspaces…"
1590
+ children: t("status.loading")
1324
1591
  }),
1325
1592
  readState.status === "error" && readState.error !== void 0 ? (0, react_jsx_runtime.jsxs)("div", {
1326
1593
  className: worktree_css_default.error,
@@ -1329,20 +1596,20 @@ window.__ModuleLoader__.load({
1329
1596
  children: [(0, react_jsx_runtime.jsx)("p", {
1330
1597
  className: worktree_css_default.message,
1331
1598
  "data-error": "true",
1332
- children: readState.error.message
1599
+ children: formatWorktreeViewError(readState.error, t)
1333
1600
  }), (0, react_jsx_runtime.jsx)("button", {
1334
1601
  type: "button",
1335
1602
  className: worktree_css_default.retryButton,
1336
1603
  onClick: () => {
1337
1604
  refresh();
1338
1605
  },
1339
- children: "Retry"
1606
+ children: t("action.retry")
1340
1607
  })]
1341
1608
  }) : readState.status === "ready" ? (0, react_jsx_runtime.jsx)("div", {
1342
1609
  className: worktree_css_default.workspaceList,
1343
1610
  children: visibleWorkspaces.length === 0 ? (0, react_jsx_runtime.jsx)("p", {
1344
1611
  className: worktree_css_default.empty,
1345
- children: "No matching Workspaces"
1612
+ children: t("workspace.noMatches")
1346
1613
  }) : visibleWorkspaces.map((workspace) => {
1347
1614
  const view = viewByWorkspace.get(workspace.workspaceId);
1348
1615
  const expanded = expandedWorkspaces[workspace.workspaceId] !== false;
@@ -1357,6 +1624,7 @@ window.__ModuleLoader__.load({
1357
1624
  className: worktree_css_default.workspaceGroup,
1358
1625
  "data-workspace-id": workspace.workspaceId,
1359
1626
  children: [(0, react_jsx_runtime.jsx)(WorktreeWorkspaceRow, {
1627
+ t,
1360
1628
  workspace,
1361
1629
  expanded,
1362
1630
  actionPending,
@@ -1412,8 +1680,9 @@ window.__ModuleLoader__.load({
1412
1680
  className: worktree_css_default.treeChildren,
1413
1681
  children: [
1414
1682
  (0, react_jsx_runtime.jsx)(WorktreeGroupRow, {
1683
+ t,
1415
1684
  kind: "main",
1416
- label: "Main",
1685
+ label: t("worktree.main"),
1417
1686
  expanded: mainExpanded,
1418
1687
  icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBranchOutline16, {}),
1419
1688
  workspaceTitle: workspace.title,
@@ -1425,6 +1694,7 @@ window.__ModuleLoader__.load({
1425
1694
  }
1426
1695
  }),
1427
1696
  mainExpanded && (0, react_jsx_runtime.jsx)(WorktreeSessionGroup, {
1697
+ t,
1428
1698
  groupKey: mainGroupKey,
1429
1699
  sessionIds: visibleMainSessionIds,
1430
1700
  workspaceId: workspace.workspaceId,
@@ -1471,7 +1741,7 @@ window.__ModuleLoader__.load({
1471
1741
  }),
1472
1742
  worktrees.length === 0 && (0, react_jsx_runtime.jsx)("p", {
1473
1743
  className: worktree_css_default.emptyNested,
1474
- children: "No Worktrees"
1744
+ children: t("worktree.noWorktrees")
1475
1745
  }),
1476
1746
  worktrees.map((record) => {
1477
1747
  const worktreeSessionIds = filterArchivedSessionIds(bindingIdsFor(bindings, record.worktreeId).filter((sessionId) => sessions.ids.includes(sessionId)), archivedSessionIds);
@@ -1480,12 +1750,13 @@ window.__ModuleLoader__.load({
1480
1750
  const visibleWorktreeSessionIds = worktreeSessionIds.filter((sessionId) => worktreeMatchesQuery || includesText(sessionLabel(sessionId, sessions), query));
1481
1751
  const worktreeGroupKey = `worktree:${record.worktreeId}`;
1482
1752
  const state = record.status === "removed" ? "warning" : record.health === "repair" ? "error" : "done";
1483
- const stateLabel = record.status === "removed" ? "Detached Worktree" : record.health === "repair" ? "Worktree needs repair" : "Active Worktree ready";
1753
+ const stateLabel = record.status === "removed" ? t("worktree.detached") : record.health === "repair" ? t("worktree.repair") : t("worktree.ready");
1484
1754
  const worktreeExpanded = expandedWorktrees[record.worktreeId] !== false;
1485
1755
  return (0, react_jsx_runtime.jsxs)("div", {
1486
1756
  className: worktree_css_default.worktreeGroup,
1487
1757
  "data-worktree-id": record.worktreeId,
1488
1758
  children: [(0, react_jsx_runtime.jsx)(WorktreeGroupRow, {
1759
+ t,
1489
1760
  kind: "worktree",
1490
1761
  label: record.branch,
1491
1762
  expanded: worktreeExpanded,
@@ -1502,8 +1773,21 @@ window.__ModuleLoader__.load({
1502
1773
  worktreeId: record.worktreeId,
1503
1774
  cwd: record.absolutePath
1504
1775
  });
1776
+ } : void 0,
1777
+ menu: record.status === "active" ? {
1778
+ open: openWorktreeMenuId === record.worktreeId,
1779
+ label: record.branch,
1780
+ disabled: actionPending,
1781
+ onOpenChange: (open) => {
1782
+ setOpenWorktreeMenuId(open ? record.worktreeId : void 0);
1783
+ },
1784
+ onRemove: () => {
1785
+ setWorktreeRemoval(record);
1786
+ setActionError(void 0);
1787
+ }
1505
1788
  } : void 0
1506
1789
  }), worktreeExpanded && (0, react_jsx_runtime.jsx)(WorktreeSessionGroup, {
1790
+ t,
1507
1791
  groupKey: worktreeGroupKey,
1508
1792
  sessionIds: visibleWorktreeSessionIds,
1509
1793
  workspaceId: workspace.workspaceId,
@@ -1564,7 +1848,7 @@ window.__ModuleLoader__.load({
1564
1848
  children: (0, react_jsx_runtime.jsx)("button", {
1565
1849
  type: "button",
1566
1850
  className: worktree_css_default.railButton,
1567
- "aria-label": "Exit Worktree mode",
1851
+ "aria-label": t("mode.exit"),
1568
1852
  onClick: () => {
1569
1853
  actions.setViewMode("workspace-session");
1570
1854
  },
@@ -1574,25 +1858,25 @@ window.__ModuleLoader__.load({
1574
1858
  (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
1575
1859
  open: sessionRenameTarget !== void 0,
1576
1860
  onClose: closeSessionRename,
1577
- closeLabel: "Close",
1578
- title: "Rename session",
1861
+ closeLabel: t("dialog.close"),
1862
+ title: t("session.rename"),
1579
1863
  footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1580
1864
  variant: "outline",
1581
1865
  disabled: sessionRenamePending,
1582
1866
  onClick: closeSessionRename,
1583
- children: "Cancel"
1867
+ children: t("dialog.cancel")
1584
1868
  }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1585
1869
  variant: "primary",
1586
1870
  disabled: sessionRenamePending || sessionRenameDraft.trim().length === 0,
1587
1871
  onClick: () => {
1588
1872
  confirmSessionRename();
1589
1873
  },
1590
- children: "Rename"
1874
+ children: t("dialog.rename")
1591
1875
  })] }),
1592
1876
  children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
1593
1877
  className: worktree_css_default.renameInput,
1594
1878
  value: sessionRenameDraft,
1595
- "aria-label": "Session name",
1879
+ "aria-label": t("session.name"),
1596
1880
  autoFocus: true,
1597
1881
  disabled: sessionRenamePending,
1598
1882
  onFocus: (event) => {
@@ -1611,32 +1895,32 @@ window.__ModuleLoader__.load({
1611
1895
  }), sessionRenameError !== void 0 && (0, react_jsx_runtime.jsx)("p", {
1612
1896
  className: worktree_css_default.renameError,
1613
1897
  role: "alert",
1614
- children: sessionRenameError
1898
+ children: formatWorktreeViewError(sessionRenameError, t)
1615
1899
  })]
1616
1900
  }),
1617
1901
  workspaceRenameTarget !== void 0 && (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
1618
1902
  open: workspaceRenameTarget !== void 0,
1619
1903
  onClose: closeWorkspaceRename,
1620
- closeLabel: "Close Rename Workspace dialog",
1621
- title: "Rename Workspace",
1904
+ closeLabel: t("dialog.closeWorkspaceRename"),
1905
+ title: t("workspace.renameTitle"),
1622
1906
  footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1623
1907
  variant: "outline",
1624
1908
  disabled: workspaceRenamePending,
1625
1909
  onClick: closeWorkspaceRename,
1626
- children: "Cancel"
1910
+ children: t("dialog.cancel")
1627
1911
  }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1628
1912
  variant: "primary",
1629
1913
  disabled: workspaceRenameBlocked,
1630
1914
  onClick: () => {
1631
1915
  confirmWorkspaceRename();
1632
1916
  },
1633
- children: "Rename"
1917
+ children: t("dialog.rename")
1634
1918
  })] }),
1635
1919
  children: [
1636
1920
  (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
1637
1921
  className: worktree_css_default.renameInput,
1638
1922
  value: workspaceRenameDraft,
1639
- "aria-label": "Workspace name",
1923
+ "aria-label": t("workspace.name"),
1640
1924
  autoFocus: true,
1641
1925
  disabled: workspaceRenamePending,
1642
1926
  onFocus: (event) => {
@@ -1656,38 +1940,38 @@ window.__ModuleLoader__.load({
1656
1940
  workspaceRenameDuplicate && (0, react_jsx_runtime.jsx)("p", {
1657
1941
  className: worktree_css_default.renameError,
1658
1942
  role: "alert",
1659
- children: "A Workspace with this name already exists."
1943
+ children: t("workspace.duplicate")
1660
1944
  }),
1661
1945
  workspaceRenameError !== void 0 && (0, react_jsx_runtime.jsx)("p", {
1662
1946
  className: worktree_css_default.renameError,
1663
1947
  role: "alert",
1664
- children: workspaceRenameError
1948
+ children: formatWorktreeViewError(workspaceRenameError, t)
1665
1949
  })
1666
1950
  ]
1667
1951
  }),
1668
1952
  workspaceDeleteTarget !== void 0 && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
1669
1953
  open: workspaceDeleteTarget !== void 0,
1670
1954
  onClose: closeWorkspaceDelete,
1671
- closeLabel: "Close Delete Workspace dialog",
1672
- title: "Delete Workspace",
1673
- description: `Delete ${workspaceDeleteTarget.title}? This removes only the DSH Workspace registration. The directory, Sessions, and Git Worktrees will be retained.`,
1955
+ closeLabel: t("dialog.closeWorkspaceDelete"),
1956
+ title: t("workspace.deleteTitle"),
1957
+ description: t("workspace.deleteDescription", { name: workspaceDeleteTarget.title }),
1674
1958
  footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1675
1959
  variant: "outline",
1676
1960
  disabled: workspaceDeletePending,
1677
1961
  onClick: closeWorkspaceDelete,
1678
- children: "Cancel"
1962
+ children: t("dialog.cancel")
1679
1963
  }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1680
1964
  variant: "outline",
1681
1965
  disabled: workspaceDeletePending,
1682
1966
  onClick: () => {
1683
1967
  confirmWorkspaceDelete();
1684
1968
  },
1685
- children: "Delete"
1969
+ children: t("dialog.delete")
1686
1970
  })] }),
1687
1971
  children: workspaceDeleteError !== void 0 && (0, react_jsx_runtime.jsx)("p", {
1688
1972
  className: worktree_css_default.renameError,
1689
1973
  role: "alert",
1690
- children: workspaceDeleteError
1974
+ children: formatWorktreeViewError(workspaceDeleteError, t)
1691
1975
  })
1692
1976
  }),
1693
1977
  worktreeModalWorkspaceId !== void 0 && modalWorkspace !== void 0 && (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
@@ -1696,30 +1980,30 @@ window.__ModuleLoader__.load({
1696
1980
  if (actionPending) return;
1697
1981
  setWorktreeModalWorkspaceId(void 0);
1698
1982
  },
1699
- closeLabel: "Close Create Worktree dialog",
1700
- title: "New Worktree",
1701
- description: `${modalWorkspace.title} · the Worktree path is managed by DSH.`,
1983
+ closeLabel: t("dialog.closeWorktreeCreate"),
1984
+ title: t("worktree.createTitle"),
1985
+ description: t("worktree.createDescription", { name: modalWorkspace.title }),
1702
1986
  footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1703
1987
  variant: "outline",
1704
1988
  disabled: actionPending,
1705
1989
  onClick: () => {
1706
1990
  setWorktreeModalWorkspaceId(void 0);
1707
1991
  },
1708
- children: "Cancel"
1992
+ children: t("dialog.cancel")
1709
1993
  }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1710
1994
  variant: "primary",
1711
1995
  disabled: actionPending || selectedBranch.length === 0 || newBranch.trim().length === 0,
1712
1996
  onClick: () => {
1713
1997
  submitWorktree();
1714
1998
  },
1715
- children: "Create Worktree"
1999
+ children: t("worktree.create")
1716
2000
  })] }),
1717
2001
  children: [
1718
2002
  (0, react_jsx_runtime.jsxs)("label", {
1719
2003
  className: worktree_css_default.modalField,
1720
- children: ["Base branch", (0, react_jsx_runtime.jsxs)("select", {
2004
+ children: [t("worktree.baseBranch"), (0, react_jsx_runtime.jsxs)("select", {
1721
2005
  className: worktree_css_default.actionSelect,
1722
- "aria-label": "Worktree base branch",
2006
+ "aria-label": t("worktree.baseBranch"),
1723
2007
  value: selectedBranch,
1724
2008
  disabled: actionPending,
1725
2009
  onChange: (event) => {
@@ -1727,22 +2011,22 @@ window.__ModuleLoader__.load({
1727
2011
  },
1728
2012
  children: [(0, react_jsx_runtime.jsx)("option", {
1729
2013
  value: "",
1730
- children: "No local branch"
2014
+ children: t("worktree.noLocalBranch")
1731
2015
  }), (modalView?.branches ?? []).map((branch) => (0, react_jsx_runtime.jsxs)("option", {
1732
2016
  value: branch.name,
1733
2017
  children: [
1734
2018
  branch.name,
1735
- branch.isCurrent ? " (current)" : "",
1736
- branch.checkedOut ? " (checked out)" : ""
2019
+ branch.isCurrent ? t("branch.current") : "",
2020
+ branch.checkedOut ? t("branch.checkedOut") : ""
1737
2021
  ]
1738
2022
  }, branch.name))]
1739
2023
  })]
1740
2024
  }),
1741
2025
  (0, react_jsx_runtime.jsxs)("label", {
1742
2026
  className: worktree_css_default.modalField,
1743
- children: ["Worktree name", (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
2027
+ children: [t("worktree.name"), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
1744
2028
  className: worktree_css_default.renameInput,
1745
- "aria-label": "Worktree name",
2029
+ "aria-label": t("worktree.name"),
1746
2030
  value: newBranch,
1747
2031
  placeholder: "dsh/12345678",
1748
2032
  disabled: actionPending,
@@ -1753,9 +2037,45 @@ window.__ModuleLoader__.load({
1753
2037
  }),
1754
2038
  modalView?.branches.length === 0 && (0, react_jsx_runtime.jsx)("p", {
1755
2039
  className: worktree_css_default.empty,
1756
- children: "No local branches found in this Workspace."
2040
+ children: t("worktree.noBranches")
1757
2041
  })
1758
2042
  ]
2043
+ }),
2044
+ worktreeRemoval !== void 0 && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
2045
+ open: worktreeRemoval !== void 0,
2046
+ onClose: () => {
2047
+ if (actionPending) return;
2048
+ setWorktreeRemoval(void 0);
2049
+ },
2050
+ closeLabel: t("dialog.closeWorktreeRemove"),
2051
+ title: t("worktree.remove"),
2052
+ description: t("worktree.removeDescription", { name: worktreeRemoval.branch }),
2053
+ footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
2054
+ variant: "outline",
2055
+ disabled: actionPending,
2056
+ onClick: () => {
2057
+ setWorktreeRemoval(void 0);
2058
+ },
2059
+ children: t("dialog.cancel")
2060
+ }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
2061
+ variant: "primary",
2062
+ disabled: actionPending,
2063
+ onClick: () => {
2064
+ if (manager === void 0) return;
2065
+ const target = worktreeRemoval;
2066
+ runMutation(async () => {
2067
+ await executeWorktreeAction(manager, {
2068
+ type: "removeWorktree",
2069
+ input: {
2070
+ workspaceId: target.workspaceId,
2071
+ worktreeId: target.worktreeId
2072
+ }
2073
+ });
2074
+ setWorktreeRemoval(void 0);
2075
+ });
2076
+ },
2077
+ children: t("worktree.remove")
2078
+ })] })
1759
2079
  })
1760
2080
  ]
1761
2081
  });
@@ -1848,6 +2168,7 @@ window.__ModuleLoader__.load({
1848
2168
  /** Required DSH Client services; Connection is the sole Worktree wire dependency. */
1849
2169
  const inject = [
1850
2170
  "connection",
2171
+ "locale",
1851
2172
  "slots",
1852
2173
  "sessions",
1853
2174
  "workspaces"
@@ -1857,6 +2178,10 @@ window.__ModuleLoader__.load({
1857
2178
  * with that fiber, so slot consumers share one manager and one request lifetime.
1858
2179
  */
1859
2180
  function apply(ctx) {
2181
+ ctx.effect(() => ctx.locale.register(WORKTREE_NS, {
2182
+ zh,
2183
+ en
2184
+ }), "clutch-dsh-worktree: locale dictionaries");
1860
2185
  const manager = createWorktreeConnectionAdapter(ctx.connection.rpc);
1861
2186
  const sessions = ctx.sessions;
1862
2187
  const virtualWorkspaceMembership = createVirtualWorkspaceMembership(ctx.workspaces.list);
@@ -1876,12 +2201,14 @@ window.__ModuleLoader__.load({
1876
2201
  name: "sidebar.footer.action",
1877
2202
  id: "clutch-dsh-worktree-mode-action",
1878
2203
  store: viewStore,
2204
+ locale: WORKTREE_NS,
1879
2205
  inject: () => ({ available: true })
1880
2206
  }, WorktreeModeAction));
1881
2207
  ctx.slots.inject("shell.overlay", () => ctx.slots.register({
1882
2208
  name: "shell.overlay",
1883
2209
  id: "clutch-dsh-worktree-navigation",
1884
2210
  store: viewStore,
2211
+ locale: WORKTREE_NS,
1885
2212
  inject: () => ({
1886
2213
  available: true,
1887
2214
  manager,