@cerbur/clutch-dsh-worktree 0.1.0 → 0.1.1

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: 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.-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-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");
@@ -209,7 +362,7 @@ window.__ModuleLoader__.load({
209
362
  //#endregion
210
363
  //#region lib/client/WorktreeModeAction.js
211
364
  /** Footer action that enters/exits the peer Worktree navigation mode. */
212
- function WorktreeModeAction({ wide, useStore, actions, available }) {
365
+ function WorktreeModeAction({ wide, useStore, actions, t, available }) {
213
366
  if (!available) return null;
214
367
  const active = useStore((state) => state.viewMode) === "worktree";
215
368
  return (0, react_jsx_runtime.jsxs)("button", {
@@ -218,15 +371,15 @@ window.__ModuleLoader__.load({
218
371
  "data-worktree-mode-action": true,
219
372
  "data-active": active || void 0,
220
373
  "data-collapsed": !wide || void 0,
221
- "aria-label": active ? "Exit Worktree mode" : "Open Worktree mode",
374
+ "aria-label": active ? t("mode.exit") : t("mode.open"),
222
375
  "aria-pressed": active,
223
- title: active ? "Exit Worktree mode" : "Worktree mode",
376
+ title: active ? t("mode.exit") : t("mode.label"),
224
377
  onClick: () => {
225
378
  actions.setViewMode(active ? "workspace-session" : "worktree");
226
379
  },
227
380
  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
381
  className: worktree_css_default.actionLabel,
229
- children: "Worktree"
382
+ children: t("mode.label")
230
383
  })]
231
384
  });
232
385
  }
@@ -279,7 +432,7 @@ window.__ModuleLoader__.load({
279
432
  "新会话",
280
433
  "New Session"
281
434
  ];
282
- const buttons = [...root.querySelectorAll("button")];
435
+ const buttons = Array.from(root.querySelectorAll("button"));
283
436
  const visibleLabel = buttons.find((button) => {
284
437
  const text = button.textContent?.trim();
285
438
  return text === "新会话" || text === "New Session";
@@ -404,6 +557,38 @@ window.__ModuleLoader__.load({
404
557
  };
405
558
  }
406
559
  //#endregion
560
+ //#region lib/client/worktree-error-copy.js
561
+ function detail(error, name) {
562
+ const value = error.details?.[name];
563
+ return typeof value === "string" ? value : "";
564
+ }
565
+ function reason(error, t) {
566
+ return error.message.length > 0 ? error.message : t("error.worktreeDataUnavailable");
567
+ }
568
+ function formatWorktreeViewError(error, t) {
569
+ switch (error.code) {
570
+ case "CLIENT_DISPOSED": return t("error.connectionDisposed");
571
+ case "CONNECTION_CALL_FAILED": return t("error.connectionFailed", {
572
+ endpoint: detail(error, "endpoint"),
573
+ reason: reason(error, t)
574
+ });
575
+ case "WORKTREE_RPC_INVALID_RESULT": return t("error.invalidResult", { endpoint: detail(error, "endpoint") });
576
+ case "WORKSPACE_ORDER_UNAVAILABLE": return t("error.workspaceOrderingUnavailable");
577
+ case "SESSION_ORDER_UNAVAILABLE": return t("error.sessionOrderingUnavailable");
578
+ case "SESSION_CREATE_UNAVAILABLE": return t("error.sessionCreationUnavailable");
579
+ case "WORKTREE_CREATED_SESSION_UNAVAILABLE": return t("error.worktreeCreatedSessionUnavailable");
580
+ case "WORKTREE_RECORD_MISSING": return t("error.worktreeRecordMissing");
581
+ case "WORKSPACE_RENAME_UNAVAILABLE": return t("error.workspaceRenameUnavailable");
582
+ case "WORKSPACE_DELETE_UNAVAILABLE": return t("error.workspaceDeleteUnavailable");
583
+ case "SESSION_RENAME_UNAVAILABLE": return t("error.sessionRenameUnavailable");
584
+ case "SESSION_BINDING_FAILED": return t("error.sessionBindingFailed", {
585
+ sessionId: detail(error, "sessionId"),
586
+ reason: reason(error, t)
587
+ });
588
+ default: return error.message.length > 0 ? error.message : t("error.worktreeDataUnavailable");
589
+ }
590
+ }
591
+ //#endregion
407
592
  //#region lib/client/worktree-view.js
408
593
  /** A DSH Session exists even when the external Worktree binding needs repair. */
409
594
  var WorktreeSessionBindingError = class extends Error {
@@ -413,7 +598,7 @@ window.__ModuleLoader__.load({
413
598
  cause;
414
599
  constructor(sessionId, cause) {
415
600
  const reason = cause instanceof Error ? cause.message : String(cause);
416
- super(`Session ${sessionId} was created, but Worktree binding failed: ${reason}`);
601
+ super(reason);
417
602
  this.name = "WorktreeSessionBindingError";
418
603
  this.sessionId = sessionId;
419
604
  this.cause = cause;
@@ -496,24 +681,43 @@ window.__ModuleLoader__.load({
496
681
  input.openSession(sessionId);
497
682
  return sessionId;
498
683
  }
684
+ function recordDetails(value) {
685
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
686
+ const details = value.details;
687
+ if (typeof details !== "object" || details === null || Array.isArray(details)) return void 0;
688
+ return details;
689
+ }
499
690
  /** Convert any adapter/Gateway failure into renderable, retry-aware UI data. */
500
691
  function toWorktreeViewError(error) {
501
692
  if (typeof error === "object" && error !== null) {
502
693
  const candidate = error;
694
+ const details = error instanceof WorktreeSessionBindingError ? {
695
+ ...recordDetails(error) ?? {},
696
+ sessionId: error.sessionId
697
+ } : recordDetails(error);
503
698
  return {
504
699
  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
700
+ message: typeof candidate.message === "string" ? candidate.message : "",
701
+ retryable: candidate.retryable !== false,
702
+ ...details === void 0 ? {} : { details }
507
703
  };
508
704
  }
509
705
  return {
510
706
  code: "WORKTREE_VIEW_FAILED",
511
- message: "Worktree data is unavailable. Retry the request.",
707
+ message: "",
512
708
  retryable: true
513
709
  };
514
710
  }
515
711
  //#endregion
516
712
  //#region lib/client/WorktreeSurface.js
713
+ function toNativeWorktreeViewError(error) {
714
+ const viewError = toWorktreeViewError(error);
715
+ if (typeof error === "object" && error !== null) return viewError;
716
+ return {
717
+ ...viewError,
718
+ message: String(error)
719
+ };
720
+ }
517
721
  const EMPTY_READ_STATE = {
518
722
  status: "idle",
519
723
  views: []
@@ -547,15 +751,15 @@ window.__ModuleLoader__.load({
547
751
  return view.bindings.some((binding) => includesText(sessionLabel(binding.sessionId, sessions), query));
548
752
  }
549
753
  /** 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 }) {
754
+ function WorktreeWorkspaceRow({ t, workspace, expanded, actionPending, menuOpen, drag, onToggle, onCreateWorktree, onRename, onDelete, onMenuOpenChange }) {
551
755
  const workspaceMenuItems = [{
552
756
  id: "rename",
553
- label: "Rename",
757
+ label: t("workspace.rename"),
554
758
  icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, {}),
555
759
  disabled: actionPending
556
760
  }, {
557
761
  id: "delete",
558
- label: "Delete",
762
+ label: t("workspace.delete"),
559
763
  icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutline16, {}),
560
764
  danger: true,
561
765
  disabled: actionPending
@@ -590,7 +794,7 @@ window.__ModuleLoader__.load({
590
794
  (0, react_jsx_runtime.jsx)("button", {
591
795
  type: "button",
592
796
  className: `${worktree_css_default.disclosureButton} ${worktree_css_default.workspaceDisclosure}`,
593
- "aria-label": `${expanded ? "Collapse" : "Expand"} ${workspace.title}`,
797
+ "aria-label": t(expanded ? "workspace.collapse" : "workspace.expand", { name: workspace.title }),
594
798
  "aria-expanded": expanded,
595
799
  onClick: (event) => {
596
800
  event.stopPropagation();
@@ -628,7 +832,7 @@ window.__ModuleLoader__.load({
628
832
  type: "button",
629
833
  className: worktree_css_default.iconButton,
630
834
  "data-workspace-menu": true,
631
- "aria-label": `Workspace options for ${workspace.title}`,
835
+ "aria-label": t("workspace.options", { name: workspace.title }),
632
836
  onClick: (event) => {
633
837
  event.stopPropagation();
634
838
  onMenuOpenChange(!menuOpen);
@@ -640,7 +844,7 @@ window.__ModuleLoader__.load({
640
844
  type: "button",
641
845
  className: worktree_css_default.iconButton,
642
846
  "data-add-worktree": true,
643
- "aria-label": `Add Worktree to ${workspace.title}`,
847
+ "aria-label": t("workspace.addWorktree", { name: workspace.title }),
644
848
  onClick: (event) => {
645
849
  event.stopPropagation();
646
850
  onCreateWorktree();
@@ -652,18 +856,19 @@ window.__ModuleLoader__.load({
652
856
  });
653
857
  }
654
858
  /** Shared Main/Worktree group row with parameterized icon, state, and actions. */
655
- function WorktreeGroupRow({ kind, label, expanded, icon, workspaceTitle, state, stateLabel, onToggle, onCreateSession }) {
859
+ function WorktreeGroupRow({ t, kind, label, expanded, icon, workspaceTitle, state, stateLabel, onToggle, onCreateSession, menu }) {
656
860
  const main = kind === "main";
657
861
  return (0, react_jsx_runtime.jsxs)("div", {
658
862
  className: worktree_css_default.worktreeRow,
659
863
  "data-main-group": main ? "true" : void 0,
660
864
  "data-main-expanded": main ? String(expanded) : void 0,
865
+ "data-menu-open": menu?.open ? "true" : void 0,
661
866
  onClick: onToggle,
662
867
  children: [
663
868
  (0, react_jsx_runtime.jsx)("button", {
664
869
  type: "button",
665
870
  className: `${worktree_css_default.disclosureButton} ${worktree_css_default.worktreeDisclosure}`,
666
- "aria-label": `${expanded ? "Collapse" : "Expand"} ${label}`,
871
+ "aria-label": t(expanded ? "worktree.collapse" : "worktree.expand", { name: label }),
667
872
  "aria-expanded": expanded,
668
873
  onClick: (event) => {
669
874
  event.stopPropagation();
@@ -687,44 +892,76 @@ window.__ModuleLoader__.load({
687
892
  className: worktree_css_default.worktreeLabel,
688
893
  children: label
689
894
  }),
690
- (0, react_jsx_runtime.jsx)("span", {
895
+ (0, react_jsx_runtime.jsxs)("span", {
691
896
  className: worktree_css_default.treeActionSlot,
692
- children: onCreateSession !== void 0 && (0, react_jsx_runtime.jsx)("button", {
897
+ children: [menu !== void 0 && (0, react_jsx_runtime.jsx)("span", {
898
+ className: worktree_css_default.menuAction,
899
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
900
+ open: menu.open,
901
+ onClose: () => {
902
+ menu.onOpenChange(false);
903
+ },
904
+ items: [{
905
+ id: "remove",
906
+ label: t("worktree.remove"),
907
+ icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutline16, {}),
908
+ danger: true,
909
+ disabled: menu.disabled
910
+ }],
911
+ onSelect: (id) => {
912
+ menu.onOpenChange(false);
913
+ if (id === "remove") menu.onRemove();
914
+ },
915
+ portal: true,
916
+ closeOnPointerLeave: true,
917
+ anchor: (0, react_jsx_runtime.jsx)("button", {
918
+ type: "button",
919
+ className: worktree_css_default.iconButton,
920
+ "data-worktree-menu": true,
921
+ "aria-label": t("worktree.options", { name: menu.label }),
922
+ onClick: (event) => {
923
+ event.stopPropagation();
924
+ menu.onOpenChange(!menu.open);
925
+ },
926
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEllipsisOutline16, {})
927
+ })
928
+ })
929
+ }), onCreateSession !== void 0 && (0, react_jsx_runtime.jsx)("button", {
693
930
  type: "button",
694
931
  className: worktree_css_default.iconButton,
695
932
  "data-add-main-session": main ? "true" : void 0,
696
933
  "data-add-session": main ? void 0 : "true",
697
- "aria-label": `Add Session to ${workspaceTitle}`,
934
+ "aria-label": t("worktree.addSession", { name: workspaceTitle }),
698
935
  onClick: (event) => {
699
936
  event.stopPropagation();
700
937
  onCreateSession();
701
938
  },
702
939
  children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutline16, {})
703
- })
940
+ })]
704
941
  })
705
942
  ]
706
943
  });
707
944
  }
708
945
  /** 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 }) {
946
+ function WorktreeSessionRow({ t, sessionId, label, drag, actionPending, onOpen, onRename, onFork, onArchive }) {
710
947
  const [menuOpen, setMenuOpen] = (0, react.useState)(false);
711
948
  const markerClass = drag.marker === "before" ? worktree_css_default.dropBefore : drag.marker === "after" ? worktree_css_default.dropAfter : "";
712
949
  const sessionMenuItems = [
713
950
  {
714
951
  id: "rename",
715
- label: "Rename",
952
+ label: t("session.rename"),
716
953
  icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, {}),
717
954
  disabled: onRename === void 0 || actionPending
718
955
  },
719
956
  {
720
957
  id: "fork",
721
- label: "Fork session",
958
+ label: t("session.fork"),
722
959
  icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBranchOutline16, {}),
723
960
  disabled: onFork === void 0 || actionPending
724
961
  },
725
962
  {
726
963
  id: "archive",
727
- label: "Archive session",
964
+ label: t("session.archive"),
728
965
  icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconArchiveOutline20, { size: 16 }),
729
966
  disabled: onArchive === void 0 || actionPending
730
967
  }
@@ -785,7 +1022,7 @@ window.__ModuleLoader__.load({
785
1022
  type: "button",
786
1023
  className: worktree_css_default.iconButton,
787
1024
  "data-session-menu": true,
788
- "aria-label": `Session options for ${label}`,
1025
+ "aria-label": t("session.options", { name: label }),
789
1026
  onClick: (event) => {
790
1027
  event.stopPropagation();
791
1028
  setMenuOpen((current) => !current);
@@ -796,10 +1033,11 @@ window.__ModuleLoader__.load({
796
1033
  })]
797
1034
  });
798
1035
  }
799
- function WorktreeSessionGroup({ groupKey, sessionIds, workspaceId, expanded, actionPending, sessions, dragState, onToggleExpanded, onStartDrag, onHoverDrag, onClearDrag, onFinishDrag, onCommitDrag, onOpen, onRename, onFork, onArchive }) {
1036
+ function WorktreeSessionGroup({ t, groupKey, sessionIds, workspaceId, expanded, actionPending, sessions, dragState, onToggleExpanded, onStartDrag, onHoverDrag, onClearDrag, onFinishDrag, onCommitDrag, onOpen, onRename, onFork, onArchive }) {
800
1037
  const visibleSessionIds = expanded ? sessionIds : sessionIds.slice(0, 5);
801
1038
  const sameGroupDrag = dragState?.groupKey === groupKey;
802
1039
  return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [visibleSessionIds.map((sessionId) => (0, react_jsx_runtime.jsx)(WorktreeSessionRow, {
1040
+ t,
803
1041
  sessionId,
804
1042
  label: sessionLabel(sessionId, sessions),
805
1043
  drag: {
@@ -836,14 +1074,14 @@ window.__ModuleLoader__.load({
836
1074
  className: worktree_css_default.sessionOverflowButton,
837
1075
  "aria-expanded": expanded,
838
1076
  onClick: onToggleExpanded,
839
- children: expanded ? "Collapse" : `Expand ${sessionIds.length - 5} more`
1077
+ children: expanded ? t("session.collapse") : t("session.expandMore", { count: sessionIds.length - 5 })
840
1078
  })] });
841
1079
  }
842
1080
  /**
843
1081
  * Peer Worktree navigation surface. It keeps the original DSH Workspace mode
844
1082
  * intact and renders a browser-local Workspace → Worktree → Session projection.
845
1083
  */
846
- function WorktreeSurface({ useStore, actions, useSessions, useWorkspaces, available, manager, createWorkspace, createSessionForWorktree: createSessionCallback, createMainSession, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, insertSessionBefore, renameSession, forkSession, archiveSession, ensureSessionWorkspace, syncSessionWorkspaces, openSession }) {
1084
+ function WorktreeSurface({ useStore, actions, useSessions, useWorkspaces, t, available, manager, createWorkspace, createSessionForWorktree: createSessionCallback, createMainSession, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, insertSessionBefore, renameSession, forkSession, archiveSession, ensureSessionWorkspace, syncSessionWorkspaces, openSession }) {
847
1085
  const mode = effectiveViewMode(useStore((state) => state.viewMode), available && manager !== void 0);
848
1086
  const sessions = useSessions((state) => state);
849
1087
  const workspaces = useWorkspaces((state) => state);
@@ -855,6 +1093,8 @@ window.__ModuleLoader__.load({
855
1093
  const [expandedWorktrees, setExpandedWorktrees] = (0, react.useState)({});
856
1094
  const [worktreeModalWorkspaceId, setWorktreeModalWorkspaceId] = (0, react.useState)();
857
1095
  const [openWorkspaceMenuId, setOpenWorkspaceMenuId] = (0, react.useState)();
1096
+ const [openWorktreeMenuId, setOpenWorktreeMenuId] = (0, react.useState)();
1097
+ const [worktreeRemoval, setWorktreeRemoval] = (0, react.useState)();
858
1098
  const [selectedBranch, setSelectedBranch] = (0, react.useState)("");
859
1099
  const [newBranch, setNewBranch] = (0, react.useState)("");
860
1100
  const [pendingSessionBinding, setPendingSessionBinding] = (0, react.useState)();
@@ -953,7 +1193,11 @@ window.__ModuleLoader__.load({
953
1193
  const target = workspaceRenameTarget;
954
1194
  if (workspaceRenameBlocked || target === void 0) return;
955
1195
  if (renameWorkspace === void 0) {
956
- setWorkspaceRenameError("Workspace rename is unavailable; retry after reconnecting.");
1196
+ setWorkspaceRenameError({
1197
+ code: "WORKSPACE_RENAME_UNAVAILABLE",
1198
+ message: "",
1199
+ retryable: true
1200
+ });
957
1201
  return;
958
1202
  }
959
1203
  setWorkspaceRenamePending(true);
@@ -962,7 +1206,7 @@ window.__ModuleLoader__.load({
962
1206
  await renameWorkspace(target.workspaceId, workspaceRenameTrimmed);
963
1207
  setWorkspaceRenameTarget(void 0);
964
1208
  } catch (error) {
965
- setWorkspaceRenameError(error instanceof Error ? error.message : String(error));
1209
+ setWorkspaceRenameError(toNativeWorktreeViewError(error));
966
1210
  } finally {
967
1211
  setWorkspaceRenamePending(false);
968
1212
  }
@@ -983,7 +1227,11 @@ window.__ModuleLoader__.load({
983
1227
  const target = workspaceDeleteTarget;
984
1228
  if (target === void 0 || workspaceDeletePending) return;
985
1229
  if (deleteWorkspace === void 0) {
986
- setWorkspaceDeleteError("Workspace delete is unavailable; retry after reconnecting.");
1230
+ setWorkspaceDeleteError({
1231
+ code: "WORKSPACE_DELETE_UNAVAILABLE",
1232
+ message: "",
1233
+ retryable: true
1234
+ });
987
1235
  return;
988
1236
  }
989
1237
  setWorkspaceDeletePending(true);
@@ -992,7 +1240,7 @@ window.__ModuleLoader__.load({
992
1240
  await deleteWorkspace(target.workspaceId);
993
1241
  setWorkspaceDeleteTarget(void 0);
994
1242
  } catch (error) {
995
- setWorkspaceDeleteError(error instanceof Error ? error.message : String(error));
1243
+ setWorkspaceDeleteError(toNativeWorktreeViewError(error));
996
1244
  } finally {
997
1245
  setWorkspaceDeletePending(false);
998
1246
  }
@@ -1011,7 +1259,7 @@ window.__ModuleLoader__.load({
1011
1259
  if (insertWorkspaceBefore === void 0) {
1012
1260
  setActionError({
1013
1261
  code: "WORKSPACE_ORDER_UNAVAILABLE",
1014
- message: "Workspace ordering is unavailable; retry after reconnecting.",
1262
+ message: "",
1015
1263
  retryable: true
1016
1264
  });
1017
1265
  return;
@@ -1034,7 +1282,7 @@ window.__ModuleLoader__.load({
1034
1282
  if (insertSessionBefore === void 0) {
1035
1283
  setActionError({
1036
1284
  code: "SESSION_ORDER_UNAVAILABLE",
1037
- message: "Session ordering is unavailable; retry after reconnecting.",
1285
+ message: "",
1038
1286
  retryable: true
1039
1287
  });
1040
1288
  return;
@@ -1062,7 +1310,11 @@ window.__ModuleLoader__.load({
1062
1310
  const title = sessionRenameDraft.trim();
1063
1311
  if (target === void 0 || title.length === 0 || sessionRenamePending) return;
1064
1312
  if (renameSession === void 0) {
1065
- setSessionRenameError("Session rename is unavailable; retry after reconnecting.");
1313
+ setSessionRenameError({
1314
+ code: "SESSION_RENAME_UNAVAILABLE",
1315
+ message: "",
1316
+ retryable: true
1317
+ });
1066
1318
  return;
1067
1319
  }
1068
1320
  setSessionRenamePending(true);
@@ -1071,7 +1323,7 @@ window.__ModuleLoader__.load({
1071
1323
  await renameSession(target.sessionId, title);
1072
1324
  setSessionRenameTarget(void 0);
1073
1325
  } catch (error) {
1074
- setSessionRenameError(error instanceof Error ? error.message : String(error));
1326
+ setSessionRenameError(toNativeWorktreeViewError(error));
1075
1327
  } finally {
1076
1328
  setSessionRenamePending(false);
1077
1329
  }
@@ -1123,13 +1375,17 @@ window.__ModuleLoader__.load({
1123
1375
  type: "createWorktree",
1124
1376
  input
1125
1377
  });
1126
- if (createdWorktree === void 0) throw new Error("Worktree creation returned no Worktree record; retry the request.");
1378
+ if (createdWorktree === void 0) throw {
1379
+ code: "WORKTREE_RECORD_MISSING",
1380
+ message: "",
1381
+ retryable: true
1382
+ };
1127
1383
  setWorktreeModalWorkspaceId(void 0);
1128
1384
  if (createSessionCallback === void 0) {
1129
1385
  await refresh();
1130
1386
  setActionError({
1131
- code: "SESSION_CREATE_UNAVAILABLE",
1132
- message: "Worktree created, but Session creation is unavailable; retry after reconnecting.",
1387
+ code: "WORKTREE_CREATED_SESSION_UNAVAILABLE",
1388
+ message: "",
1133
1389
  retryable: true
1134
1390
  });
1135
1391
  return;
@@ -1159,7 +1415,7 @@ window.__ModuleLoader__.load({
1159
1415
  if (createSessionCallback === void 0) {
1160
1416
  setActionError({
1161
1417
  code: "SESSION_CREATE_UNAVAILABLE",
1162
- message: "Session creation is unavailable; retry after reconnecting.",
1418
+ message: "",
1163
1419
  retryable: true
1164
1420
  });
1165
1421
  return;
@@ -1212,7 +1468,7 @@ window.__ModuleLoader__.load({
1212
1468
  className: worktree_css_default.surface,
1213
1469
  "data-worktree-surface": true,
1214
1470
  "data-collapsed": collapsed || void 0,
1215
- "aria-label": "Worktree navigation",
1471
+ "aria-label": t("mode.navigation"),
1216
1472
  style: {
1217
1473
  width: `${width}px`,
1218
1474
  ...bounds.ready ? {
@@ -1231,11 +1487,11 @@ window.__ModuleLoader__.load({
1231
1487
  className: worktree_css_default.header,
1232
1488
  children: [(0, react_jsx_runtime.jsx)("span", {
1233
1489
  className: worktree_css_default.title,
1234
- children: "Worktrees"
1490
+ children: t("worktree.title")
1235
1491
  }), (0, react_jsx_runtime.jsx)("button", {
1236
1492
  type: "button",
1237
1493
  className: worktree_css_default.closeButton,
1238
- "aria-label": "Exit Worktree mode",
1494
+ "aria-label": t("mode.exit"),
1239
1495
  onClick: () => {
1240
1496
  actions.setViewMode("workspace-session");
1241
1497
  },
@@ -1252,8 +1508,8 @@ window.__ModuleLoader__.load({
1252
1508
  }),
1253
1509
  (0, react_jsx_runtime.jsx)("input", {
1254
1510
  className: worktree_css_default.searchInput,
1255
- "aria-label": "Search Workspaces and Sessions",
1256
- placeholder: "Search Workspaces and Sessions",
1511
+ "aria-label": t("workspace.search"),
1512
+ placeholder: t("workspace.search"),
1257
1513
  value: searchQuery,
1258
1514
  onChange: (event) => {
1259
1515
  setSearchQuery(event.currentTarget.value);
@@ -1262,7 +1518,7 @@ window.__ModuleLoader__.load({
1262
1518
  (0, react_jsx_runtime.jsx)("button", {
1263
1519
  type: "button",
1264
1520
  className: worktree_css_default.iconButton,
1265
- "aria-label": "Add Workspace",
1521
+ "aria-label": t("workspace.add"),
1266
1522
  onClick: () => {
1267
1523
  if (createWorkspace !== void 0) runMutation(createWorkspace);
1268
1524
  },
@@ -1282,7 +1538,7 @@ window.__ModuleLoader__.load({
1282
1538
  (0, react_jsx_runtime.jsx)("p", {
1283
1539
  className: worktree_css_default.message,
1284
1540
  "data-error": "true",
1285
- children: actionError.message
1541
+ children: formatWorktreeViewError(actionError, t)
1286
1542
  }),
1287
1543
  pendingSessionBinding !== void 0 && (0, react_jsx_runtime.jsxs)("div", {
1288
1544
  className: worktree_css_default.recoveryActions,
@@ -1293,7 +1549,7 @@ window.__ModuleLoader__.load({
1293
1549
  onClick: () => {
1294
1550
  retrySessionBinding();
1295
1551
  },
1296
- children: "Retry Binding"
1552
+ children: t("action.retryBinding")
1297
1553
  }), (0, react_jsx_runtime.jsx)("button", {
1298
1554
  type: "button",
1299
1555
  className: worktree_css_default.actionButton,
@@ -1304,7 +1560,7 @@ window.__ModuleLoader__.load({
1304
1560
  setActionError(void 0);
1305
1561
  openSession(sessionId);
1306
1562
  },
1307
- children: "Open Created Session"
1563
+ children: t("action.openCreatedSession")
1308
1564
  })]
1309
1565
  }),
1310
1566
  actionError.retryable && (0, react_jsx_runtime.jsx)("button", {
@@ -1314,13 +1570,13 @@ window.__ModuleLoader__.load({
1314
1570
  setActionError(void 0);
1315
1571
  refresh();
1316
1572
  },
1317
- children: "Retry"
1573
+ children: t("action.retry")
1318
1574
  })
1319
1575
  ]
1320
1576
  }),
1321
1577
  readState.status === "loading" && (0, react_jsx_runtime.jsx)("p", {
1322
1578
  className: worktree_css_default.message,
1323
- children: "Loading Workspaces…"
1579
+ children: t("status.loading")
1324
1580
  }),
1325
1581
  readState.status === "error" && readState.error !== void 0 ? (0, react_jsx_runtime.jsxs)("div", {
1326
1582
  className: worktree_css_default.error,
@@ -1329,20 +1585,20 @@ window.__ModuleLoader__.load({
1329
1585
  children: [(0, react_jsx_runtime.jsx)("p", {
1330
1586
  className: worktree_css_default.message,
1331
1587
  "data-error": "true",
1332
- children: readState.error.message
1588
+ children: formatWorktreeViewError(readState.error, t)
1333
1589
  }), (0, react_jsx_runtime.jsx)("button", {
1334
1590
  type: "button",
1335
1591
  className: worktree_css_default.retryButton,
1336
1592
  onClick: () => {
1337
1593
  refresh();
1338
1594
  },
1339
- children: "Retry"
1595
+ children: t("action.retry")
1340
1596
  })]
1341
1597
  }) : readState.status === "ready" ? (0, react_jsx_runtime.jsx)("div", {
1342
1598
  className: worktree_css_default.workspaceList,
1343
1599
  children: visibleWorkspaces.length === 0 ? (0, react_jsx_runtime.jsx)("p", {
1344
1600
  className: worktree_css_default.empty,
1345
- children: "No matching Workspaces"
1601
+ children: t("workspace.noMatches")
1346
1602
  }) : visibleWorkspaces.map((workspace) => {
1347
1603
  const view = viewByWorkspace.get(workspace.workspaceId);
1348
1604
  const expanded = expandedWorkspaces[workspace.workspaceId] !== false;
@@ -1357,6 +1613,7 @@ window.__ModuleLoader__.load({
1357
1613
  className: worktree_css_default.workspaceGroup,
1358
1614
  "data-workspace-id": workspace.workspaceId,
1359
1615
  children: [(0, react_jsx_runtime.jsx)(WorktreeWorkspaceRow, {
1616
+ t,
1360
1617
  workspace,
1361
1618
  expanded,
1362
1619
  actionPending,
@@ -1412,8 +1669,9 @@ window.__ModuleLoader__.load({
1412
1669
  className: worktree_css_default.treeChildren,
1413
1670
  children: [
1414
1671
  (0, react_jsx_runtime.jsx)(WorktreeGroupRow, {
1672
+ t,
1415
1673
  kind: "main",
1416
- label: "Main",
1674
+ label: t("worktree.main"),
1417
1675
  expanded: mainExpanded,
1418
1676
  icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBranchOutline16, {}),
1419
1677
  workspaceTitle: workspace.title,
@@ -1425,6 +1683,7 @@ window.__ModuleLoader__.load({
1425
1683
  }
1426
1684
  }),
1427
1685
  mainExpanded && (0, react_jsx_runtime.jsx)(WorktreeSessionGroup, {
1686
+ t,
1428
1687
  groupKey: mainGroupKey,
1429
1688
  sessionIds: visibleMainSessionIds,
1430
1689
  workspaceId: workspace.workspaceId,
@@ -1471,7 +1730,7 @@ window.__ModuleLoader__.load({
1471
1730
  }),
1472
1731
  worktrees.length === 0 && (0, react_jsx_runtime.jsx)("p", {
1473
1732
  className: worktree_css_default.emptyNested,
1474
- children: "No Worktrees"
1733
+ children: t("worktree.noWorktrees")
1475
1734
  }),
1476
1735
  worktrees.map((record) => {
1477
1736
  const worktreeSessionIds = filterArchivedSessionIds(bindingIdsFor(bindings, record.worktreeId).filter((sessionId) => sessions.ids.includes(sessionId)), archivedSessionIds);
@@ -1480,12 +1739,13 @@ window.__ModuleLoader__.load({
1480
1739
  const visibleWorktreeSessionIds = worktreeSessionIds.filter((sessionId) => worktreeMatchesQuery || includesText(sessionLabel(sessionId, sessions), query));
1481
1740
  const worktreeGroupKey = `worktree:${record.worktreeId}`;
1482
1741
  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";
1742
+ const stateLabel = record.status === "removed" ? t("worktree.detached") : record.health === "repair" ? t("worktree.repair") : t("worktree.ready");
1484
1743
  const worktreeExpanded = expandedWorktrees[record.worktreeId] !== false;
1485
1744
  return (0, react_jsx_runtime.jsxs)("div", {
1486
1745
  className: worktree_css_default.worktreeGroup,
1487
1746
  "data-worktree-id": record.worktreeId,
1488
1747
  children: [(0, react_jsx_runtime.jsx)(WorktreeGroupRow, {
1748
+ t,
1489
1749
  kind: "worktree",
1490
1750
  label: record.branch,
1491
1751
  expanded: worktreeExpanded,
@@ -1502,8 +1762,21 @@ window.__ModuleLoader__.load({
1502
1762
  worktreeId: record.worktreeId,
1503
1763
  cwd: record.absolutePath
1504
1764
  });
1765
+ } : void 0,
1766
+ menu: record.status === "active" ? {
1767
+ open: openWorktreeMenuId === record.worktreeId,
1768
+ label: record.branch,
1769
+ disabled: actionPending,
1770
+ onOpenChange: (open) => {
1771
+ setOpenWorktreeMenuId(open ? record.worktreeId : void 0);
1772
+ },
1773
+ onRemove: () => {
1774
+ setWorktreeRemoval(record);
1775
+ setActionError(void 0);
1776
+ }
1505
1777
  } : void 0
1506
1778
  }), worktreeExpanded && (0, react_jsx_runtime.jsx)(WorktreeSessionGroup, {
1779
+ t,
1507
1780
  groupKey: worktreeGroupKey,
1508
1781
  sessionIds: visibleWorktreeSessionIds,
1509
1782
  workspaceId: workspace.workspaceId,
@@ -1564,7 +1837,7 @@ window.__ModuleLoader__.load({
1564
1837
  children: (0, react_jsx_runtime.jsx)("button", {
1565
1838
  type: "button",
1566
1839
  className: worktree_css_default.railButton,
1567
- "aria-label": "Exit Worktree mode",
1840
+ "aria-label": t("mode.exit"),
1568
1841
  onClick: () => {
1569
1842
  actions.setViewMode("workspace-session");
1570
1843
  },
@@ -1574,25 +1847,25 @@ window.__ModuleLoader__.load({
1574
1847
  (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
1575
1848
  open: sessionRenameTarget !== void 0,
1576
1849
  onClose: closeSessionRename,
1577
- closeLabel: "Close",
1578
- title: "Rename session",
1850
+ closeLabel: t("dialog.close"),
1851
+ title: t("session.rename"),
1579
1852
  footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1580
1853
  variant: "outline",
1581
1854
  disabled: sessionRenamePending,
1582
1855
  onClick: closeSessionRename,
1583
- children: "Cancel"
1856
+ children: t("dialog.cancel")
1584
1857
  }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1585
1858
  variant: "primary",
1586
1859
  disabled: sessionRenamePending || sessionRenameDraft.trim().length === 0,
1587
1860
  onClick: () => {
1588
1861
  confirmSessionRename();
1589
1862
  },
1590
- children: "Rename"
1863
+ children: t("dialog.rename")
1591
1864
  })] }),
1592
1865
  children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
1593
1866
  className: worktree_css_default.renameInput,
1594
1867
  value: sessionRenameDraft,
1595
- "aria-label": "Session name",
1868
+ "aria-label": t("session.name"),
1596
1869
  autoFocus: true,
1597
1870
  disabled: sessionRenamePending,
1598
1871
  onFocus: (event) => {
@@ -1611,32 +1884,32 @@ window.__ModuleLoader__.load({
1611
1884
  }), sessionRenameError !== void 0 && (0, react_jsx_runtime.jsx)("p", {
1612
1885
  className: worktree_css_default.renameError,
1613
1886
  role: "alert",
1614
- children: sessionRenameError
1887
+ children: formatWorktreeViewError(sessionRenameError, t)
1615
1888
  })]
1616
1889
  }),
1617
1890
  workspaceRenameTarget !== void 0 && (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
1618
1891
  open: workspaceRenameTarget !== void 0,
1619
1892
  onClose: closeWorkspaceRename,
1620
- closeLabel: "Close Rename Workspace dialog",
1621
- title: "Rename Workspace",
1893
+ closeLabel: t("dialog.closeWorkspaceRename"),
1894
+ title: t("workspace.renameTitle"),
1622
1895
  footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1623
1896
  variant: "outline",
1624
1897
  disabled: workspaceRenamePending,
1625
1898
  onClick: closeWorkspaceRename,
1626
- children: "Cancel"
1899
+ children: t("dialog.cancel")
1627
1900
  }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1628
1901
  variant: "primary",
1629
1902
  disabled: workspaceRenameBlocked,
1630
1903
  onClick: () => {
1631
1904
  confirmWorkspaceRename();
1632
1905
  },
1633
- children: "Rename"
1906
+ children: t("dialog.rename")
1634
1907
  })] }),
1635
1908
  children: [
1636
1909
  (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
1637
1910
  className: worktree_css_default.renameInput,
1638
1911
  value: workspaceRenameDraft,
1639
- "aria-label": "Workspace name",
1912
+ "aria-label": t("workspace.name"),
1640
1913
  autoFocus: true,
1641
1914
  disabled: workspaceRenamePending,
1642
1915
  onFocus: (event) => {
@@ -1656,38 +1929,38 @@ window.__ModuleLoader__.load({
1656
1929
  workspaceRenameDuplicate && (0, react_jsx_runtime.jsx)("p", {
1657
1930
  className: worktree_css_default.renameError,
1658
1931
  role: "alert",
1659
- children: "A Workspace with this name already exists."
1932
+ children: t("workspace.duplicate")
1660
1933
  }),
1661
1934
  workspaceRenameError !== void 0 && (0, react_jsx_runtime.jsx)("p", {
1662
1935
  className: worktree_css_default.renameError,
1663
1936
  role: "alert",
1664
- children: workspaceRenameError
1937
+ children: formatWorktreeViewError(workspaceRenameError, t)
1665
1938
  })
1666
1939
  ]
1667
1940
  }),
1668
1941
  workspaceDeleteTarget !== void 0 && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
1669
1942
  open: workspaceDeleteTarget !== void 0,
1670
1943
  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.`,
1944
+ closeLabel: t("dialog.closeWorkspaceDelete"),
1945
+ title: t("workspace.deleteTitle"),
1946
+ description: t("workspace.deleteDescription", { name: workspaceDeleteTarget.title }),
1674
1947
  footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1675
1948
  variant: "outline",
1676
1949
  disabled: workspaceDeletePending,
1677
1950
  onClick: closeWorkspaceDelete,
1678
- children: "Cancel"
1951
+ children: t("dialog.cancel")
1679
1952
  }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1680
1953
  variant: "outline",
1681
1954
  disabled: workspaceDeletePending,
1682
1955
  onClick: () => {
1683
1956
  confirmWorkspaceDelete();
1684
1957
  },
1685
- children: "Delete"
1958
+ children: t("dialog.delete")
1686
1959
  })] }),
1687
1960
  children: workspaceDeleteError !== void 0 && (0, react_jsx_runtime.jsx)("p", {
1688
1961
  className: worktree_css_default.renameError,
1689
1962
  role: "alert",
1690
- children: workspaceDeleteError
1963
+ children: formatWorktreeViewError(workspaceDeleteError, t)
1691
1964
  })
1692
1965
  }),
1693
1966
  worktreeModalWorkspaceId !== void 0 && modalWorkspace !== void 0 && (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
@@ -1696,30 +1969,30 @@ window.__ModuleLoader__.load({
1696
1969
  if (actionPending) return;
1697
1970
  setWorktreeModalWorkspaceId(void 0);
1698
1971
  },
1699
- closeLabel: "Close Create Worktree dialog",
1700
- title: "New Worktree",
1701
- description: `${modalWorkspace.title} · the Worktree path is managed by DSH.`,
1972
+ closeLabel: t("dialog.closeWorktreeCreate"),
1973
+ title: t("worktree.createTitle"),
1974
+ description: t("worktree.createDescription", { name: modalWorkspace.title }),
1702
1975
  footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1703
1976
  variant: "outline",
1704
1977
  disabled: actionPending,
1705
1978
  onClick: () => {
1706
1979
  setWorktreeModalWorkspaceId(void 0);
1707
1980
  },
1708
- children: "Cancel"
1981
+ children: t("dialog.cancel")
1709
1982
  }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1710
1983
  variant: "primary",
1711
1984
  disabled: actionPending || selectedBranch.length === 0 || newBranch.trim().length === 0,
1712
1985
  onClick: () => {
1713
1986
  submitWorktree();
1714
1987
  },
1715
- children: "Create Worktree"
1988
+ children: t("worktree.create")
1716
1989
  })] }),
1717
1990
  children: [
1718
1991
  (0, react_jsx_runtime.jsxs)("label", {
1719
1992
  className: worktree_css_default.modalField,
1720
- children: ["Base branch", (0, react_jsx_runtime.jsxs)("select", {
1993
+ children: [t("worktree.baseBranch"), (0, react_jsx_runtime.jsxs)("select", {
1721
1994
  className: worktree_css_default.actionSelect,
1722
- "aria-label": "Worktree base branch",
1995
+ "aria-label": t("worktree.baseBranch"),
1723
1996
  value: selectedBranch,
1724
1997
  disabled: actionPending,
1725
1998
  onChange: (event) => {
@@ -1727,22 +2000,22 @@ window.__ModuleLoader__.load({
1727
2000
  },
1728
2001
  children: [(0, react_jsx_runtime.jsx)("option", {
1729
2002
  value: "",
1730
- children: "No local branch"
2003
+ children: t("worktree.noLocalBranch")
1731
2004
  }), (modalView?.branches ?? []).map((branch) => (0, react_jsx_runtime.jsxs)("option", {
1732
2005
  value: branch.name,
1733
2006
  children: [
1734
2007
  branch.name,
1735
- branch.isCurrent ? " (current)" : "",
1736
- branch.checkedOut ? " (checked out)" : ""
2008
+ branch.isCurrent ? t("branch.current") : "",
2009
+ branch.checkedOut ? t("branch.checkedOut") : ""
1737
2010
  ]
1738
2011
  }, branch.name))]
1739
2012
  })]
1740
2013
  }),
1741
2014
  (0, react_jsx_runtime.jsxs)("label", {
1742
2015
  className: worktree_css_default.modalField,
1743
- children: ["Worktree name", (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
2016
+ children: [t("worktree.name"), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
1744
2017
  className: worktree_css_default.renameInput,
1745
- "aria-label": "Worktree name",
2018
+ "aria-label": t("worktree.name"),
1746
2019
  value: newBranch,
1747
2020
  placeholder: "dsh/12345678",
1748
2021
  disabled: actionPending,
@@ -1753,9 +2026,45 @@ window.__ModuleLoader__.load({
1753
2026
  }),
1754
2027
  modalView?.branches.length === 0 && (0, react_jsx_runtime.jsx)("p", {
1755
2028
  className: worktree_css_default.empty,
1756
- children: "No local branches found in this Workspace."
2029
+ children: t("worktree.noBranches")
1757
2030
  })
1758
2031
  ]
2032
+ }),
2033
+ worktreeRemoval !== void 0 && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
2034
+ open: worktreeRemoval !== void 0,
2035
+ onClose: () => {
2036
+ if (actionPending) return;
2037
+ setWorktreeRemoval(void 0);
2038
+ },
2039
+ closeLabel: t("dialog.closeWorktreeRemove"),
2040
+ title: t("worktree.remove"),
2041
+ description: t("worktree.removeDescription", { name: worktreeRemoval.branch }),
2042
+ footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
2043
+ variant: "outline",
2044
+ disabled: actionPending,
2045
+ onClick: () => {
2046
+ setWorktreeRemoval(void 0);
2047
+ },
2048
+ children: t("dialog.cancel")
2049
+ }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
2050
+ variant: "primary",
2051
+ disabled: actionPending,
2052
+ onClick: () => {
2053
+ if (manager === void 0) return;
2054
+ const target = worktreeRemoval;
2055
+ runMutation(async () => {
2056
+ await executeWorktreeAction(manager, {
2057
+ type: "removeWorktree",
2058
+ input: {
2059
+ workspaceId: target.workspaceId,
2060
+ worktreeId: target.worktreeId
2061
+ }
2062
+ });
2063
+ setWorktreeRemoval(void 0);
2064
+ });
2065
+ },
2066
+ children: t("worktree.remove")
2067
+ })] })
1759
2068
  })
1760
2069
  ]
1761
2070
  });
@@ -1848,6 +2157,7 @@ window.__ModuleLoader__.load({
1848
2157
  /** Required DSH Client services; Connection is the sole Worktree wire dependency. */
1849
2158
  const inject = [
1850
2159
  "connection",
2160
+ "locale",
1851
2161
  "slots",
1852
2162
  "sessions",
1853
2163
  "workspaces"
@@ -1857,6 +2167,10 @@ window.__ModuleLoader__.load({
1857
2167
  * with that fiber, so slot consumers share one manager and one request lifetime.
1858
2168
  */
1859
2169
  function apply(ctx) {
2170
+ ctx.effect(() => ctx.locale.register(WORKTREE_NS, {
2171
+ zh,
2172
+ en
2173
+ }), "clutch-dsh-worktree: locale dictionaries");
1860
2174
  const manager = createWorktreeConnectionAdapter(ctx.connection.rpc);
1861
2175
  const sessions = ctx.sessions;
1862
2176
  const virtualWorkspaceMembership = createVirtualWorkspaceMembership(ctx.workspaces.list);
@@ -1876,12 +2190,14 @@ window.__ModuleLoader__.load({
1876
2190
  name: "sidebar.footer.action",
1877
2191
  id: "clutch-dsh-worktree-mode-action",
1878
2192
  store: viewStore,
2193
+ locale: WORKTREE_NS,
1879
2194
  inject: () => ({ available: true })
1880
2195
  }, WorktreeModeAction));
1881
2196
  ctx.slots.inject("shell.overlay", () => ctx.slots.register({
1882
2197
  name: "shell.overlay",
1883
2198
  id: "clutch-dsh-worktree-navigation",
1884
2199
  store: viewStore,
2200
+ locale: WORKTREE_NS,
1885
2201
  inject: () => ({
1886
2202
  available: true,
1887
2203
  manager,