@cerbur/clutch-dsh-worktree 0.1.4 → 0.1.6
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/README.md +89 -24
- package/README.zh.md +81 -23
- package/lib/client/WorktreeContext.d.ts.map +1 -1
- package/lib/client/WorktreeContext.js.map +1 -1
- package/lib/client/WorktreeHeroContext.d.ts +1 -1
- package/lib/client/WorktreeHeroContext.d.ts.map +1 -1
- package/lib/client/WorktreeHeroContext.js +10 -5
- package/lib/client/WorktreeHeroContext.js.map +1 -1
- package/lib/client/WorktreeSurface.d.ts +1 -1
- package/lib/client/WorktreeSurface.d.ts.map +1 -1
- package/lib/client/WorktreeSurface.js +349 -88
- package/lib/client/WorktreeSurface.js.map +1 -1
- package/lib/client/entry.d.ts.map +1 -1
- package/lib/client/entry.js +3 -0
- package/lib/client/entry.js.map +1 -1
- package/lib/client/locales.d.ts +28 -0
- package/lib/client/locales.d.ts.map +1 -1
- package/lib/client/locales.js +30 -2
- package/lib/client/locales.js.map +1 -1
- package/lib/client/virtual-workspace-membership.js +1 -1
- package/lib/client/virtual-workspace-membership.js.map +1 -1
- package/lib/client/worktree-connection.d.ts +2 -0
- package/lib/client/worktree-connection.d.ts.map +1 -1
- package/lib/client/worktree-connection.js +4 -0
- package/lib/client/worktree-connection.js.map +1 -1
- package/lib/client/worktree-context-store.d.ts.map +1 -1
- package/lib/client/worktree-context-store.js +51 -11
- package/lib/client/worktree-context-store.js.map +1 -1
- package/lib/client/worktree-error-copy.d.ts.map +1 -1
- package/lib/client/worktree-error-copy.js +8 -0
- package/lib/client/worktree-error-copy.js.map +1 -1
- package/lib/client/worktree-expand-state.d.ts +33 -0
- package/lib/client/worktree-expand-state.d.ts.map +1 -0
- package/lib/client/worktree-expand-state.js +83 -0
- package/lib/client/worktree-expand-state.js.map +1 -0
- package/lib/client/worktree-session-position.d.ts +2 -0
- package/lib/client/worktree-session-position.d.ts.map +1 -0
- package/lib/client/worktree-session-position.js +11 -0
- package/lib/client/worktree-session-position.js.map +1 -0
- package/lib/client/worktree-surface-dialogs.d.ts +1 -1
- package/lib/client/worktree-surface-dialogs.d.ts.map +1 -1
- package/lib/client/worktree-surface-dialogs.js +33 -13
- package/lib/client/worktree-surface-dialogs.js.map +1 -1
- package/lib/client/worktree-surface-rows.d.ts +2 -2
- package/lib/client/worktree-surface-rows.d.ts.map +1 -1
- package/lib/client/worktree-surface-rows.js +5 -5
- package/lib/client/worktree-surface-rows.js.map +1 -1
- package/lib/client/worktree-surface-selectors.d.ts +16 -0
- package/lib/client/worktree-surface-selectors.d.ts.map +1 -1
- package/lib/client/worktree-surface-selectors.js +54 -0
- package/lib/client/worktree-surface-selectors.js.map +1 -1
- package/lib/client/worktree-surface-types.d.ts +28 -1
- package/lib/client/worktree-surface-types.d.ts.map +1 -1
- package/lib/client/worktree-view-actions.d.ts +3 -0
- package/lib/client/worktree-view-actions.d.ts.map +1 -1
- package/lib/client/worktree-view-actions.js +3 -0
- package/lib/client/worktree-view-actions.js.map +1 -1
- package/lib/client/worktree-view-read.d.ts +11 -0
- package/lib/client/worktree-view-read.d.ts.map +1 -1
- package/lib/client/worktree-view-read.js +24 -0
- package/lib/client/worktree-view-read.js.map +1 -1
- package/lib/client.js +697 -137
- package/lib/client.js.map +1 -1
- package/lib/contract/index.contract.js +14 -0
- package/lib/contract/index.contract.js.map +1 -1
- package/lib/contract/index.d.ts +22 -2
- package/lib/contract/index.d.ts.map +1 -1
- package/lib/contract/index.js +5 -0
- package/lib/contract/index.js.map +1 -1
- package/lib/host/remote.d.ts.map +1 -1
- package/lib/host/remote.js +2 -0
- package/lib/host/remote.js.map +1 -1
- package/lib/host/service.d.ts +8 -1
- package/lib/host/service.d.ts.map +1 -1
- package/lib/host/service.js +12 -0
- package/lib/host/service.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/manage/manager-support.d.ts +2 -0
- package/lib/manage/manager-support.d.ts.map +1 -1
- package/lib/manage/manager-support.js +9 -0
- package/lib/manage/manager-support.js.map +1 -1
- package/lib/manage/manager-worktrees.d.ts +10 -1
- package/lib/manage/manager-worktrees.d.ts.map +1 -1
- package/lib/manage/manager-worktrees.js +121 -5
- package/lib/manage/manager-worktrees.js.map +1 -1
- package/lib/manage/manager.d.ts +8 -1
- package/lib/manage/manager.d.ts.map +1 -1
- package/lib/manage/manager.js +7 -1
- package/lib/manage/manager.js.map +1 -1
- package/lib/provider/git.d.ts +8 -0
- package/lib/provider/git.d.ts.map +1 -1
- package/lib/provider/git.js +57 -11
- package/lib/provider/git.js.map +1 -1
- package/lib/provider/index.d.ts +1 -1
- package/lib/provider/index.d.ts.map +1 -1
- package/lib/provider/index.js +1 -1
- package/lib/provider/index.js.map +1 -1
- package/lib/provider/sidecar-schema.d.ts +1 -1
- package/lib/provider/sidecar-schema.d.ts.map +1 -1
- package/lib/provider/sidecar-schema.js +33 -37
- package/lib/provider/sidecar-schema.js.map +1 -1
- package/lib/provider/sidecar.d.ts.map +1 -1
- package/lib/provider/sidecar.js +3 -1
- package/lib/provider/sidecar.js.map +1 -1
- package/lib/provider/types.d.ts +9 -1
- package/lib/provider/types.d.ts.map +1 -1
- package/lib/provider/types.js +2 -1
- package/lib/provider/types.js.map +1 -1
- package/lib/typert.host.js +115 -21
- package/lib/typert.remote-client.d.ts +5 -1
- package/lib/typert.remote-client.d.ts.map +1 -1
- package/lib/typert.remote-client.js +115 -21
- package/package.json +30 -30
package/lib/client.js
CHANGED
|
@@ -42,19 +42,29 @@ window.__ModuleLoader__.load({
|
|
|
42
42
|
"worktree.options": "Worktree 选项:{name}",
|
|
43
43
|
"worktree.remove": "移除 Worktree",
|
|
44
44
|
"worktree.removeDescription": "移除“{name}”?Session 会保留在 DSH 中,并作为已分离关系继续可用。",
|
|
45
|
+
"worktree.removeExternalDescription": "移除“{name}”?这会删除关联的外部 Worktree 目录。Session 会保留在 DSH 中,并作为已分离关系继续可用。",
|
|
45
46
|
"worktree.addSession": "向 {name} 添加会话",
|
|
46
47
|
"worktree.noWorktrees": "暂无 Worktree",
|
|
47
48
|
"worktree.createTitle": "新建 Worktree",
|
|
48
49
|
"worktree.createDescription": "“{name}” · Worktree 路径由 DSH 管理。",
|
|
50
|
+
"worktree.tabCreate": "创建",
|
|
51
|
+
"worktree.tabImport": "导入",
|
|
52
|
+
"worktree.importDescription": "向“{name}”注册已有的 Worktree。注册不会移动目录;之后移除会删除关联的 Worktree 目录。",
|
|
53
|
+
"worktree.importLoading": "正在查找可导入的 Worktree…",
|
|
54
|
+
"worktree.importEmpty": "没有可导入的 Worktree。",
|
|
55
|
+
"worktree.importPlaceholder": "请选择要导入的 Worktree",
|
|
56
|
+
"worktree.importSelected": "已选择",
|
|
49
57
|
"worktree.baseBranch": "Worktree 基线分支",
|
|
50
58
|
"worktree.noLocalBranch": "没有本地分支",
|
|
51
59
|
"worktree.noBranches": "此工作区中没有找到本地分支。",
|
|
60
|
+
"worktree.setup.gitNotInstalled": "Git 未安装或不在 PATH 中。请先安装 Git,然后重启 DSH 再重试。",
|
|
52
61
|
"worktree.setup.noRepository": "此 Workspace 不是 Git 仓库。请在 Workspace 目录执行以下命令:",
|
|
53
62
|
"worktree.setup.noInitialCommit": "此 Git 仓库还没有首次 commit。请先执行以下命令:",
|
|
54
63
|
"worktree.setup.noLocalBranch": "此 Git 仓库没有本地分支。请先创建一个本地分支:",
|
|
55
64
|
"worktree.setup.commands": "可复制的命令",
|
|
56
65
|
"worktree.name": "Worktree 名称",
|
|
57
66
|
"worktree.create": "创建 Worktree",
|
|
67
|
+
"worktree.import": "导入 Worktree",
|
|
58
68
|
"session.options": "会话选项:{name}",
|
|
59
69
|
"session.new": "新会话",
|
|
60
70
|
"session.rename": "重命名会话",
|
|
@@ -76,6 +86,7 @@ window.__ModuleLoader__.load({
|
|
|
76
86
|
"action.openCreatedSession": "打开已创建的 Session",
|
|
77
87
|
"status.loading": "正在加载工作区…",
|
|
78
88
|
"error.worktreeDataUnavailable": "Worktree 数据不可用,请重试。",
|
|
89
|
+
"error.gitNotInstalled": "Git 未安装或不可用,请安装 Git 后重试。",
|
|
79
90
|
"error.connectionDisposed": "Worktree 连接已释放,请重新加载插件后重试。",
|
|
80
91
|
"error.connectionFailed": "Worktree endpoint {endpoint} 调用失败;连接错误,可重试:{reason}",
|
|
81
92
|
"error.invalidResult": "Worktree endpoint {endpoint} 返回了无效结果,请重试请求。",
|
|
@@ -84,7 +95,10 @@ window.__ModuleLoader__.load({
|
|
|
84
95
|
"error.worktreeOrderingUnavailable": "Worktree 排序不可用,请重新连接后重试。",
|
|
85
96
|
"error.worktreeCreatedSessionUnavailable": "Worktree 已创建,但 Session 创建不可用,请重新连接后重试。",
|
|
86
97
|
"error.sessionCreationUnavailable": "Session 创建不可用,请重新连接后重试。",
|
|
87
|
-
"error.worktreeRecordMissing": "Worktree
|
|
98
|
+
"error.worktreeRecordMissing": "Worktree 注册未返回 Worktree 记录,请重试请求。",
|
|
99
|
+
"error.worktreeImportInvalid": "这个 Worktree 无法导入,请选择同一 Workspace 中有效的绝对路径。",
|
|
100
|
+
"error.worktreeAlreadyManaged": "这个 Worktree 已由插件管理。",
|
|
101
|
+
"error.worktreeRegistrationSessionUnavailable": "Worktree 已注册,但 Session 创建不可用,请重新连接后重试。",
|
|
88
102
|
"error.workspaceRenameUnavailable": "工作区重命名不可用,请重新连接后重试。",
|
|
89
103
|
"error.workspaceDeleteUnavailable": "工作区删除不可用,请重新连接后重试。",
|
|
90
104
|
"error.sessionRenameUnavailable": "会话重命名不可用,请重新连接后重试。",
|
|
@@ -130,19 +144,29 @@ window.__ModuleLoader__.load({
|
|
|
130
144
|
"worktree.options": "Worktree options for {name}",
|
|
131
145
|
"worktree.remove": "Remove Worktree",
|
|
132
146
|
"worktree.removeDescription": "Remove {name}? Sessions stay in DSH and remain available as detached bindings.",
|
|
147
|
+
"worktree.removeExternalDescription": "Remove {name}? This deletes the linked external Worktree directory. Sessions stay in DSH and remain available as detached bindings.",
|
|
133
148
|
"worktree.addSession": "Add Session to {name}",
|
|
134
149
|
"worktree.noWorktrees": "No Worktrees",
|
|
135
150
|
"worktree.createTitle": "New Worktree",
|
|
136
151
|
"worktree.createDescription": "{name} · the Worktree path is managed by DSH.",
|
|
152
|
+
"worktree.tabCreate": "Create",
|
|
153
|
+
"worktree.tabImport": "Import",
|
|
154
|
+
"worktree.importDescription": "Register an existing Worktree for {name}. Registration leaves the directory in place; removing it later deletes the linked Worktree directory.",
|
|
155
|
+
"worktree.importLoading": "Finding importable Worktrees…",
|
|
156
|
+
"worktree.importEmpty": "No importable Worktrees found.",
|
|
157
|
+
"worktree.importPlaceholder": "Select a Worktree to import",
|
|
158
|
+
"worktree.importSelected": "Selected",
|
|
137
159
|
"worktree.baseBranch": "Worktree base branch",
|
|
138
160
|
"worktree.noLocalBranch": "No local branch",
|
|
139
161
|
"worktree.noBranches": "No local branches found in this Workspace.",
|
|
162
|
+
"worktree.setup.gitNotInstalled": "Git is not installed or is not available on PATH. Install Git, restart DSH, and retry.",
|
|
140
163
|
"worktree.setup.noRepository": "This Workspace is not a Git repository. Run these commands in the Workspace directory:",
|
|
141
164
|
"worktree.setup.noInitialCommit": "This Git repository has no initial commit. Run these commands first:",
|
|
142
165
|
"worktree.setup.noLocalBranch": "This Git repository has no local branch. Create one first:",
|
|
143
166
|
"worktree.setup.commands": "Copyable commands",
|
|
144
167
|
"worktree.name": "Worktree name",
|
|
145
168
|
"worktree.create": "Create Worktree",
|
|
169
|
+
"worktree.import": "Import Worktree",
|
|
146
170
|
"session.options": "Session options for {name}",
|
|
147
171
|
"session.new": "New Session",
|
|
148
172
|
"session.rename": "Rename session",
|
|
@@ -164,6 +188,7 @@ window.__ModuleLoader__.load({
|
|
|
164
188
|
"action.openCreatedSession": "Open Created Session",
|
|
165
189
|
"status.loading": "Loading Workspaces…",
|
|
166
190
|
"error.worktreeDataUnavailable": "Worktree data is unavailable. Retry the request.",
|
|
191
|
+
"error.gitNotInstalled": "Git is not installed or unavailable. Install Git and retry.",
|
|
167
192
|
"error.connectionDisposed": "Worktree connection is disposed; reload the plugin and retry.",
|
|
168
193
|
"error.connectionFailed": "Worktree endpoint {endpoint} failed; retryable connection error: {reason}",
|
|
169
194
|
"error.invalidResult": "Worktree endpoint {endpoint} returned an invalid result; retry the request.",
|
|
@@ -172,7 +197,10 @@ window.__ModuleLoader__.load({
|
|
|
172
197
|
"error.worktreeOrderingUnavailable": "Worktree ordering is unavailable; retry after reconnecting.",
|
|
173
198
|
"error.worktreeCreatedSessionUnavailable": "Worktree created, but Session creation is unavailable; retry after reconnecting.",
|
|
174
199
|
"error.sessionCreationUnavailable": "Session creation is unavailable; retry after reconnecting.",
|
|
175
|
-
"error.worktreeRecordMissing": "Worktree
|
|
200
|
+
"error.worktreeRecordMissing": "Worktree registration returned no Worktree record; retry the request.",
|
|
201
|
+
"error.worktreeImportInvalid": "This Worktree cannot be imported. Choose a valid absolute path in this Workspace.",
|
|
202
|
+
"error.worktreeAlreadyManaged": "This Worktree is already managed by the plugin.",
|
|
203
|
+
"error.worktreeRegistrationSessionUnavailable": "The Worktree was registered, but Session creation is unavailable; retry after reconnecting.",
|
|
176
204
|
"error.workspaceRenameUnavailable": "Workspace rename is unavailable; retry after reconnecting.",
|
|
177
205
|
"error.workspaceDeleteUnavailable": "Workspace delete is unavailable; retry after reconnecting.",
|
|
178
206
|
"error.sessionRenameUnavailable": "Session rename is unavailable; retry after reconnecting.",
|
|
@@ -196,8 +224,10 @@ window.__ModuleLoader__.load({
|
|
|
196
224
|
*/
|
|
197
225
|
const WORKTREE_CONNECTION_ENDPOINTS = Object.freeze({
|
|
198
226
|
listWorktrees: "worktreeManager/listWorktrees",
|
|
227
|
+
listImportCandidates: "worktreeManager/listImportCandidates",
|
|
199
228
|
listBranches: "worktreeManager/listBranches",
|
|
200
229
|
createWorktree: "worktreeManager/createWorktree",
|
|
230
|
+
importWorktree: "worktreeManager/importWorktree",
|
|
201
231
|
removeWorktree: "worktreeManager/removeWorktree",
|
|
202
232
|
insertWorktreeBefore: "worktreeManager/insertWorktreeBefore",
|
|
203
233
|
listBindings: "worktreeManager/listBindings",
|
|
@@ -216,14 +246,14 @@ window.__ModuleLoader__.load({
|
|
|
216
246
|
this.retryable = options.retryable;
|
|
217
247
|
}
|
|
218
248
|
};
|
|
219
|
-
function isRecord(value) {
|
|
249
|
+
function isRecord$1(value) {
|
|
220
250
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
221
251
|
}
|
|
222
252
|
function isWorktreeError(value) {
|
|
223
|
-
return isRecord(value) && typeof value.code === "string" && typeof value.message === "string" && isRecord(value.details);
|
|
253
|
+
return isRecord$1(value) && typeof value.code === "string" && typeof value.message === "string" && isRecord$1(value.details);
|
|
224
254
|
}
|
|
225
255
|
function isWorktreeRemoteResult(value) {
|
|
226
|
-
if (!isRecord(value) || typeof value.ok !== "boolean") return false;
|
|
256
|
+
if (!isRecord$1(value) || typeof value.ok !== "boolean") return false;
|
|
227
257
|
return value.ok || isWorktreeError(value.error) && value.error.details !== void 0;
|
|
228
258
|
}
|
|
229
259
|
function disposedError() {
|
|
@@ -244,7 +274,7 @@ window.__ModuleLoader__.load({
|
|
|
244
274
|
});
|
|
245
275
|
}
|
|
246
276
|
function gatewayFailure(endpoint, result) {
|
|
247
|
-
const rawDetails = isRecord(result.error.details) ? result.error.details : {};
|
|
277
|
+
const rawDetails = isRecord$1(result.error.details) ? result.error.details : {};
|
|
248
278
|
throw new WorktreeConnectionError({
|
|
249
279
|
code: result.error.code,
|
|
250
280
|
message: result.error.message,
|
|
@@ -301,8 +331,10 @@ window.__ModuleLoader__.load({
|
|
|
301
331
|
}
|
|
302
332
|
return {
|
|
303
333
|
listWorktrees: (input) => invoke("listWorktrees", input),
|
|
334
|
+
listImportCandidates: (input) => invoke("listImportCandidates", input),
|
|
304
335
|
listBranches: (input) => invoke("listBranches", input),
|
|
305
336
|
createWorktree: (input) => invoke("createWorktree", input),
|
|
337
|
+
importWorktree: (input) => invoke("importWorktree", input),
|
|
306
338
|
async removeWorktree(input) {
|
|
307
339
|
await invoke("removeWorktree", input);
|
|
308
340
|
},
|
|
@@ -320,8 +352,8 @@ window.__ModuleLoader__.load({
|
|
|
320
352
|
};
|
|
321
353
|
}
|
|
322
354
|
//#endregion
|
|
323
|
-
//#region \0clutch-dsh-worktree-css:/Users/yuancheng/
|
|
324
|
-
const css$1 = ".-cerbur-clutch-dsh-worktree-headerContext {\n display: inline-flex;\n min-width: 0;\n height: 22px;\n align-items: center;\n gap: 4px;\n max-width: 180px;\n overflow: hidden;\n border-radius: 6px;\n padding: 0 2px 0 0;\n background: var(--dsw-alias-fill-tsp-secondary);\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n line-height: 22px;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-contextIcon {\n flex: none;\n opacity: 0.7;\n}\n\n.-cerbur-clutch-dsh-worktree-contextLabel {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-
|
|
355
|
+
//#region \0clutch-dsh-worktree-css:/Users/yuancheng/.dsh/clutch-dsh-worktree/worktree/wt_0c53e50f-f169-4c5e-9664-1c2d58ae1212/packages/clutch-dsh-worktree/src/client/worktree-context.css.mjs
|
|
356
|
+
const css$1 = ".-cerbur-clutch-dsh-worktree-headerContext {\n display: inline-flex;\n min-width: 0;\n height: 22px;\n align-items: center;\n gap: 4px;\n max-width: 180px;\n overflow: hidden;\n border-radius: 6px;\n padding: 0 2px 0 0;\n background: var(--dsw-alias-fill-tsp-secondary);\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n line-height: 22px;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-contextIcon {\n flex: none;\n opacity: 0.7;\n}\n\n.-cerbur-clutch-dsh-worktree-contextLabel {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-contextHoverTitle {\n max-width: 360px;\n color: var(--dsw-static-neutral-bluish-00);\n font-size: 14px;\n line-height: 20px;\n overflow-wrap: anywhere;\n white-space: normal;\n}\n\n.-cerbur-clutch-dsh-worktree-heroContextHost {\n position: absolute;\n z-index: 1;\n display: block;\n width: max-content;\n max-width: 260px;\n min-height: 22px;\n}\n\n.-cerbur-clutch-dsh-worktree-heroContext {\n display: inline-flex;\n box-sizing: border-box;\n max-width: 260px;\n min-height: 22px;\n align-items: center;\n overflow: hidden;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n padding: 0 8px;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n line-height: 20px;\n pointer-events: auto;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n";
|
|
325
357
|
const styleId$1 = "@cerbur/clutch-dsh-worktree/worktree-context.css";
|
|
326
358
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@cerbur/clutch-dsh-worktree/worktree-context.css\"]") === null) {
|
|
327
359
|
const tag = document.createElement("style");
|
|
@@ -334,6 +366,8 @@ window.__ModuleLoader__.load({
|
|
|
334
366
|
"headerContext": "-cerbur-clutch-dsh-worktree-headerContext",
|
|
335
367
|
"contextIcon": "-cerbur-clutch-dsh-worktree-contextIcon",
|
|
336
368
|
"contextLabel": "-cerbur-clutch-dsh-worktree-contextLabel",
|
|
369
|
+
"contextHoverTitle": "-cerbur-clutch-dsh-worktree-contextHoverTitle",
|
|
370
|
+
"heroContextHost": "-cerbur-clutch-dsh-worktree-heroContextHost",
|
|
337
371
|
"heroContext": "-cerbur-clutch-dsh-worktree-heroContext"
|
|
338
372
|
};
|
|
339
373
|
//#endregion
|
|
@@ -365,8 +399,8 @@ window.__ModuleLoader__.load({
|
|
|
365
399
|
});
|
|
366
400
|
}
|
|
367
401
|
//#endregion
|
|
368
|
-
//#region \0clutch-dsh-worktree-css:/Users/yuancheng/
|
|
369
|
-
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@media (prefers-reduced-motion: reduce) {\n .-cerbur-clutch-dsh-worktree-surface {\n transition: none;\n }\n}\n\n.-cerbur-clutch-dsh-worktree-wideContent {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n}\n\n.-cerbur-clutch-dsh-worktree-surface[data-collapsed='true'] .-cerbur-clutch-dsh-worktree-wideContent {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-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-gitReadiness {\n display: grid;\n gap: 4px;\n}\n\n.-cerbur-clutch-dsh-worktree-commandBlock {\n margin: 6px 0 0;\n padding: 8px;\n overflow-x: auto;\n border-radius: 6px;\n background: var(--dsw-alias-button-elevated-fill);\n color: var(--dsw-alias-label-secondary);\n font: 11px/16px ui-monospace, SFMono-Regular, Menlo, monospace;\n white-space: pre-wrap;\n}\n\n.-cerbur-clutch-dsh-worktree-message[data-error='true'] {\n color: var(--dsw-alias-state-error-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-worktree,\n.-cerbur-clutch-dsh-worktree-session {\n display: flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n box-sizing: border-box;\n border: 0;\n border-radius: 7px;\n padding: 6px 8px;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 12px;\n text-align: left;\n}\n\n.-cerbur-clutch-dsh-worktree-worktree {\n cursor: default;\n}\n\n.-cerbur-clutch-dsh-worktree-session {\n cursor: pointer;\n}\n\n.-cerbur-clutch-dsh-worktree-worktree:hover,\n.-cerbur-clutch-dsh-worktree-session:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeLabel,\n.-cerbur-clutch-dsh-worktree-sessionLabel {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-status {\n flex: none;\n margin-left: auto;\n padding-left: 8px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-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}\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-worktreeRow.-cerbur-clutch-dsh-worktree-dropBefore::before,\n.-cerbur-clutch-dsh-worktree-worktreeRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n position: absolute;\n right: 4px;\n left: 4px;\n height: 2px;\n border-radius: 2px;\n background: var(--dsw-alias-brand-primary);\n content: '';\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow.-cerbur-clutch-dsh-worktree-dropBefore::before {\n top: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n bottom: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeChildren {\n margin-left: 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";
|
|
402
|
+
//#region \0clutch-dsh-worktree-css:/Users/yuancheng/.dsh/clutch-dsh-worktree/worktree/wt_0c53e50f-f169-4c5e-9664-1c2d58ae1212/packages/clutch-dsh-worktree/src/client/worktree.css.mjs
|
|
403
|
+
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 display: inline-flex;\n min-width: 0;\n align-items: center;\n height: 22px;\n overflow: hidden;\n font-weight: 400;\n line-height: 22px;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-surface {\n position: absolute;\n top: 0;\n left: 0;\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n min-width: 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@media (prefers-reduced-motion: reduce) {\n .-cerbur-clutch-dsh-worktree-surface {\n transition: none;\n }\n}\n\n.-cerbur-clutch-dsh-worktree-wideContent {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n}\n\n.-cerbur-clutch-dsh-worktree-surface[data-collapsed='true'] .-cerbur-clutch-dsh-worktree-wideContent {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeModalTabs {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeModalTab {\n border: 0;\n border-bottom: 2px solid transparent;\n padding: 4px 0;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n font: inherit;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeModalTab[aria-selected='true'] {\n border-bottom-color: var(--dsw-alias-label-primary);\n color: var(--dsw-alias-label-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeImportCandidates {\n display: grid;\n gap: 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeImportSelect {\n width: 100%;\n min-width: 0;\n padding: 7px 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: var(--dsw-alias-button-elevated-fill);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 13px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeImportError {\n display: grid;\n gap: 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-closeButton {\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: inherit;\n cursor: pointer;\n font: inherit;\n}\n\n.-cerbur-clutch-dsh-worktree-closeButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-header {\n display: flex;\n align-items: center;\n gap: 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-actionSelect {\n min-width: 0;\n padding: 5px 6px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: var(--dsw-alias-button-elevated-fill);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-section {\n margin: 12px 0 0;\n}\n\n.-cerbur-clutch-dsh-worktree-sectionTitle {\n margin: 0 2px 4px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n}\n\n.-cerbur-clutch-dsh-worktree-empty,\n.-cerbur-clutch-dsh-worktree-message {\n margin: 0;\n padding: 8px 4px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 12px;\n line-height: 18px;\n}\n\n.-cerbur-clutch-dsh-worktree-gitReadiness {\n display: grid;\n gap: 4px;\n}\n\n.-cerbur-clutch-dsh-worktree-commandBlock {\n margin: 6px 0 0;\n padding: 8px;\n overflow-x: auto;\n border-radius: 6px;\n background: var(--dsw-alias-button-elevated-fill);\n color: var(--dsw-alias-label-secondary);\n font: 11px/16px ui-monospace, SFMono-Regular, Menlo, monospace;\n white-space: pre-wrap;\n}\n\n.-cerbur-clutch-dsh-worktree-message[data-error='true'] {\n color: var(--dsw-alias-state-error-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-worktree,\n.-cerbur-clutch-dsh-worktree-session {\n display: flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n box-sizing: border-box;\n border: 0;\n border-radius: 7px;\n padding: 6px 8px;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 12px;\n text-align: left;\n}\n\n.-cerbur-clutch-dsh-worktree-worktree {\n cursor: default;\n}\n\n.-cerbur-clutch-dsh-worktree-session {\n cursor: pointer;\n}\n\n.-cerbur-clutch-dsh-worktree-worktree:hover,\n.-cerbur-clutch-dsh-worktree-session:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeLabel,\n.-cerbur-clutch-dsh-worktree-sessionLabel {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-status {\n flex: none;\n margin-left: auto;\n padding-left: 8px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-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.-cerbur-clutch-dsh-worktree-worktreeImportSelect:focus {\n border-color: #3b82f6;\n}\n\n.-cerbur-clutch-dsh-worktree-iconButton {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: 0;\n border-radius: 7px;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n font: inherit;\n font-size: 20px;\n line-height: 1;\n}\n\n.-cerbur-clutch-dsh-worktree-iconButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceList {\n 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}\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-worktreeRow.-cerbur-clutch-dsh-worktree-dropBefore::before,\n.-cerbur-clutch-dsh-worktree-worktreeRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n position: absolute;\n right: 4px;\n left: 4px;\n height: 2px;\n border-radius: 2px;\n background: var(--dsw-alias-brand-primary);\n content: '';\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow.-cerbur-clutch-dsh-worktree-dropBefore::before {\n top: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n bottom: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeChildren {\n margin-left: 16px;\n padding: 2px 0 5px 12px;\n border-left: 1px solid var(--dsw-alias-border-l1);\n}\n\n.-cerbur-clutch-dsh-worktree-groupLabel {\n padding: 6px 8px 3px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n}\n\n.-cerbur-clutch-dsh-worktree-groupHeader {\n display: flex;\n align-items: center;\n min-height: 34px;\n padding-right: 4px;\n}\n\n.-cerbur-clutch-dsh-worktree-groupHeader .-cerbur-clutch-dsh-worktree-groupLabel {\n flex: 1;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeGroup {\n margin-top: 2px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow {\n min-height: 34px;\n}\n\n.-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: calc(100% - 22px);\n margin-left: 22px;\n min-width: 0;\n min-height: 31px;\n box-sizing: border-box;\n border-radius: 7px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow:hover,\n.-cerbur-clutch-dsh-worktree-treeSessionRow[data-menu-open='true'] {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow[data-session-current='true'] {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow[data-session-current='true'] .-cerbur-clutch-dsh-worktree-treeSessionContent {\n font-weight: 600;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow.-cerbur-clutch-dsh-worktree-dropBefore::before,\n.-cerbur-clutch-dsh-worktree-treeSessionRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n position: absolute;\n right: 4px;\n left: 4px;\n height: 2px;\n border-radius: 2px;\n background: var(--dsw-alias-brand-primary);\n content: '';\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow.-cerbur-clutch-dsh-worktree-dropBefore::before {\n top: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n bottom: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionContent {\n display: flex;\n align-items: center;\n flex: 1;\n width: 0;\n min-width: 0;\n min-height: 31px;\n box-sizing: border-box;\n border: 0;\n border-radius: 7px;\n padding: 4px 4px;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n font: inherit;\n font-size: 14px;\n font-weight: 400;\n line-height: 20px;\n text-align: left;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionContent:hover {\n background: transparent;\n}\n\n.-cerbur-clutch-dsh-worktree-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-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";
|
|
370
404
|
const styleId = "@cerbur/clutch-dsh-worktree/worktree.css";
|
|
371
405
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@cerbur/clutch-dsh-worktree/worktree.css\"]") === null) {
|
|
372
406
|
const tag = document.createElement("style");
|
|
@@ -380,8 +414,11 @@ window.__ModuleLoader__.load({
|
|
|
380
414
|
"actionLabel": "-cerbur-clutch-dsh-worktree-actionLabel",
|
|
381
415
|
"surface": "-cerbur-clutch-dsh-worktree-surface",
|
|
382
416
|
"wideContent": "-cerbur-clutch-dsh-worktree-wideContent",
|
|
383
|
-
"
|
|
384
|
-
"
|
|
417
|
+
"worktreeModalTabs": "-cerbur-clutch-dsh-worktree-worktreeModalTabs",
|
|
418
|
+
"worktreeModalTab": "-cerbur-clutch-dsh-worktree-worktreeModalTab",
|
|
419
|
+
"worktreeImportCandidates": "-cerbur-clutch-dsh-worktree-worktreeImportCandidates",
|
|
420
|
+
"worktreeImportSelect": "-cerbur-clutch-dsh-worktree-worktreeImportSelect",
|
|
421
|
+
"worktreeImportError": "-cerbur-clutch-dsh-worktree-worktreeImportError",
|
|
385
422
|
"closeButton": "-cerbur-clutch-dsh-worktree-closeButton",
|
|
386
423
|
"header": "-cerbur-clutch-dsh-worktree-header",
|
|
387
424
|
"title": "-cerbur-clutch-dsh-worktree-title",
|
|
@@ -437,7 +474,6 @@ window.__ModuleLoader__.load({
|
|
|
437
474
|
"sessionOverflowButton": "-cerbur-clutch-dsh-worktree-sessionOverflowButton",
|
|
438
475
|
"renameInput": "-cerbur-clutch-dsh-worktree-renameInput",
|
|
439
476
|
"renameError": "-cerbur-clutch-dsh-worktree-renameError",
|
|
440
|
-
"treeGuide": "-cerbur-clutch-dsh-worktree-treeGuide",
|
|
441
477
|
"emptyNested": "-cerbur-clutch-dsh-worktree-emptyNested",
|
|
442
478
|
"modalField": "-cerbur-clutch-dsh-worktree-modalField"
|
|
443
479
|
};
|
|
@@ -484,9 +520,12 @@ window.__ModuleLoader__.load({
|
|
|
484
520
|
for (let ancestor = element.parentElement; ancestor !== null; ancestor = ancestor.parentElement) if (getComputedStyle(ancestor).position !== "static") return ancestor;
|
|
485
521
|
return null;
|
|
486
522
|
}
|
|
523
|
+
function overlayFor(element) {
|
|
524
|
+
return positionedAncestor(element.closest("[data-worktree-hero-host]") ?? element);
|
|
525
|
+
}
|
|
487
526
|
function measurePlacement(element) {
|
|
488
527
|
const hero = document.querySelector("[data-phase=\"hero\"]");
|
|
489
|
-
const overlay =
|
|
528
|
+
const overlay = overlayFor(element);
|
|
490
529
|
const headline = hero === null ? null : headlineElement(hero);
|
|
491
530
|
if (hero === null || headline === null || overlay === null) return null;
|
|
492
531
|
const anchor = headline.getBoundingClientRect();
|
|
@@ -505,7 +544,7 @@ window.__ModuleLoader__.load({
|
|
|
505
544
|
}
|
|
506
545
|
/**
|
|
507
546
|
* Browser-local Hero suffix. It intentionally uses the frame overlay because
|
|
508
|
-
*
|
|
547
|
+
* The current upstream DSH exposes no additive slot beside the native Hero headline.
|
|
509
548
|
*/
|
|
510
549
|
function WorktreeHeroContext({ useWorktreeContext, t }) {
|
|
511
550
|
const state = useWorktreeContext((snapshot) => snapshot);
|
|
@@ -538,7 +577,7 @@ window.__ModuleLoader__.load({
|
|
|
538
577
|
attributeFilter: ["class", "data-phase"]
|
|
539
578
|
});
|
|
540
579
|
const resizeObserver = typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver(schedule);
|
|
541
|
-
resizeObserver?.observe(
|
|
580
|
+
resizeObserver?.observe(overlayFor(element) ?? element);
|
|
542
581
|
window.addEventListener("resize", schedule);
|
|
543
582
|
schedule();
|
|
544
583
|
return () => {
|
|
@@ -551,16 +590,27 @@ window.__ModuleLoader__.load({
|
|
|
551
590
|
const ariaLabel = contextAriaLabel(state, t);
|
|
552
591
|
if (label === void 0) return null;
|
|
553
592
|
return (0, react_jsx_runtime.jsx)("span", {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
"data-worktree-hero-context": true,
|
|
557
|
-
"aria-label": ariaLabel,
|
|
558
|
-
title: label,
|
|
593
|
+
className: worktree_context_css_default.heroContextHost,
|
|
594
|
+
"data-worktree-hero-host": true,
|
|
559
595
|
style: placement === null ? { visibility: "hidden" } : {
|
|
560
596
|
left: `${placement.left}px`,
|
|
561
597
|
top: `${placement.top}px`
|
|
562
598
|
},
|
|
563
|
-
children:
|
|
599
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.HoverCard, {
|
|
600
|
+
anchor: (0, react_jsx_runtime.jsx)("span", {
|
|
601
|
+
ref: measure,
|
|
602
|
+
className: worktree_context_css_default.heroContext,
|
|
603
|
+
"data-worktree-hero-context": true,
|
|
604
|
+
"aria-label": ariaLabel,
|
|
605
|
+
title: label,
|
|
606
|
+
children: label
|
|
607
|
+
}),
|
|
608
|
+
content: (0, react_jsx_runtime.jsx)("div", {
|
|
609
|
+
className: worktree_context_css_default.contextHoverTitle,
|
|
610
|
+
children: label
|
|
611
|
+
}),
|
|
612
|
+
openDelayMs: 500
|
|
613
|
+
})
|
|
564
614
|
});
|
|
565
615
|
}
|
|
566
616
|
//#endregion
|
|
@@ -693,6 +743,84 @@ window.__ModuleLoader__.load({
|
|
|
693
743
|
};
|
|
694
744
|
}
|
|
695
745
|
//#endregion
|
|
746
|
+
//#region lib/client/worktree-expand-state.js
|
|
747
|
+
/** Browser-local storage identity; never sent to DSH or the plugin sidecar. */
|
|
748
|
+
const WORKTREE_EXPAND_STATE_STORAGE_KEY = "clutch-dsh-worktree.expand-state";
|
|
749
|
+
function emptyState() {
|
|
750
|
+
return {
|
|
751
|
+
collapsedWorkspaceIds: {},
|
|
752
|
+
collapsedMainWorkspaceIds: {},
|
|
753
|
+
collapsedWorktreeIds: {}
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
function isRecord(value) {
|
|
757
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
758
|
+
}
|
|
759
|
+
function normalizeIds(value) {
|
|
760
|
+
if (!isRecord(value)) return {};
|
|
761
|
+
return Object.fromEntries(Object.entries(value).filter(([id, collapsed]) => id.length > 0 && collapsed === true));
|
|
762
|
+
}
|
|
763
|
+
/** Turn any persisted JSON value into the current state shape. */
|
|
764
|
+
function normalizeWorktreeExpandState(value) {
|
|
765
|
+
const source = isRecord(value) ? value : {};
|
|
766
|
+
return {
|
|
767
|
+
collapsedWorkspaceIds: normalizeIds(source.collapsedWorkspaceIds),
|
|
768
|
+
collapsedMainWorkspaceIds: normalizeIds(source.collapsedMainWorkspaceIds),
|
|
769
|
+
collapsedWorktreeIds: normalizeIds(source.collapsedWorktreeIds)
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
function isWorkspaceExpanded(state, workspaceId) {
|
|
773
|
+
return state.collapsedWorkspaceIds[workspaceId] !== true;
|
|
774
|
+
}
|
|
775
|
+
function isMainExpanded(state, workspaceId) {
|
|
776
|
+
return state.collapsedMainWorkspaceIds[workspaceId] !== true;
|
|
777
|
+
}
|
|
778
|
+
function isWorktreeExpanded(state, worktreeId) {
|
|
779
|
+
return state.collapsedWorktreeIds[worktreeId] !== true;
|
|
780
|
+
}
|
|
781
|
+
function toggle(record, id) {
|
|
782
|
+
if (record[id] === true) delete record[id];
|
|
783
|
+
else record[id] = true;
|
|
784
|
+
}
|
|
785
|
+
function retain(record, ids) {
|
|
786
|
+
const allowed = new Set(ids);
|
|
787
|
+
for (const id of Object.keys(record)) if (!allowed.has(id)) delete record[id];
|
|
788
|
+
}
|
|
789
|
+
/** Create one apply-scoped store; component remounts share this instance. */
|
|
790
|
+
function createWorktreeExpandStateStore(snapshotStoreFactory) {
|
|
791
|
+
let store;
|
|
792
|
+
try {
|
|
793
|
+
store = snapshotStoreFactory(emptyState(), { persist: { name: WORKTREE_EXPAND_STATE_STORAGE_KEY } });
|
|
794
|
+
} catch {
|
|
795
|
+
store = snapshotStoreFactory(emptyState());
|
|
796
|
+
}
|
|
797
|
+
store.set(normalizeWorktreeExpandState(store.getSnapshot()));
|
|
798
|
+
return Object.assign(store, { actions: {
|
|
799
|
+
toggleWorkspace: (workspaceId) => {
|
|
800
|
+
store.update((draft) => {
|
|
801
|
+
toggle(draft.collapsedWorkspaceIds, workspaceId);
|
|
802
|
+
});
|
|
803
|
+
},
|
|
804
|
+
toggleMain: (workspaceId) => {
|
|
805
|
+
store.update((draft) => {
|
|
806
|
+
toggle(draft.collapsedMainWorkspaceIds, workspaceId);
|
|
807
|
+
});
|
|
808
|
+
},
|
|
809
|
+
toggleWorktree: (worktreeId) => {
|
|
810
|
+
store.update((draft) => {
|
|
811
|
+
toggle(draft.collapsedWorktreeIds, worktreeId);
|
|
812
|
+
});
|
|
813
|
+
},
|
|
814
|
+
retain: (workspaceIds, worktreeIds) => {
|
|
815
|
+
store.update((draft) => {
|
|
816
|
+
retain(draft.collapsedWorkspaceIds, workspaceIds);
|
|
817
|
+
retain(draft.collapsedMainWorkspaceIds, workspaceIds);
|
|
818
|
+
retain(draft.collapsedWorktreeIds, worktreeIds);
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
} });
|
|
822
|
+
}
|
|
823
|
+
//#endregion
|
|
696
824
|
//#region lib/client/view-mode.js
|
|
697
825
|
/** Browser-local storage key; it is never sent to DSH or the sidecar. */
|
|
698
826
|
const WORKTREE_VIEW_MODE_STORAGE_KEY = "clutch-dsh-worktree.view-mode";
|
|
@@ -769,6 +897,9 @@ window.__ModuleLoader__.load({
|
|
|
769
897
|
case "SESSION_CREATE_UNAVAILABLE": return t("error.sessionCreationUnavailable");
|
|
770
898
|
case "WORKTREE_CREATED_SESSION_UNAVAILABLE": return t("error.worktreeCreatedSessionUnavailable");
|
|
771
899
|
case "WORKTREE_RECORD_MISSING": return t("error.worktreeRecordMissing");
|
|
900
|
+
case "WORKTREE_IMPORT_INVALID": return t("error.worktreeImportInvalid");
|
|
901
|
+
case "WORKTREE_ALREADY_MANAGED": return t("error.worktreeAlreadyManaged");
|
|
902
|
+
case "WORKTREE_REGISTRATION_SESSION_UNAVAILABLE": return t("error.worktreeRegistrationSessionUnavailable");
|
|
772
903
|
case "WORKSPACE_RENAME_UNAVAILABLE": return t("error.workspaceRenameUnavailable");
|
|
773
904
|
case "WORKSPACE_DELETE_UNAVAILABLE": return t("error.workspaceDeleteUnavailable");
|
|
774
905
|
case "SESSION_RENAME_UNAVAILABLE": return t("error.sessionRenameUnavailable");
|
|
@@ -782,6 +913,7 @@ window.__ModuleLoader__.load({
|
|
|
782
913
|
case "WORKTREE_SESSION_REPAIR_REQUIRED": return t("error.worktreeSessionRepairRequired");
|
|
783
914
|
case "WORKTREE_SESSION_UNAVAILABLE": return t("error.worktreeSessionUnavailable");
|
|
784
915
|
case "SESSION_ARCHIVED": return t("error.sessionArchived");
|
|
916
|
+
case "GIT_NOT_INSTALLED": return t("error.gitNotInstalled");
|
|
785
917
|
default: return error.message.length > 0 ? error.message : t("error.worktreeDataUnavailable");
|
|
786
918
|
}
|
|
787
919
|
}
|
|
@@ -898,6 +1030,7 @@ window.__ModuleLoader__.load({
|
|
|
898
1030
|
/** Keep mutation routing in the browser Consumer while leaving wire details to the adapter. */
|
|
899
1031
|
async function executeWorktreeAction(manager, action) {
|
|
900
1032
|
if (action.type === "createWorktree") return manager.createWorktree(action.input);
|
|
1033
|
+
if (action.type === "importWorktree") return manager.importWorktree(action.input);
|
|
901
1034
|
if (action.type === "removeWorktree") {
|
|
902
1035
|
await manager.removeWorktree(action.input);
|
|
903
1036
|
return;
|
|
@@ -924,6 +1057,14 @@ window.__ModuleLoader__.load({
|
|
|
924
1057
|
}
|
|
925
1058
|
//#endregion
|
|
926
1059
|
//#region lib/client/worktree-view-read.js
|
|
1060
|
+
/** Merge one freshly read Workspace projection without clearing other ready views. */
|
|
1061
|
+
function mergeWorktreeView(views, nextView) {
|
|
1062
|
+
const index = views.findIndex((view) => view.workspaceId === nextView.workspaceId);
|
|
1063
|
+
if (index === -1) return [...views, nextView];
|
|
1064
|
+
const merged = [...views];
|
|
1065
|
+
merged[index] = nextView;
|
|
1066
|
+
return merged;
|
|
1067
|
+
}
|
|
927
1068
|
/** Reuse the previous ID snapshot when DSH republishes equivalent Workspace items. */
|
|
928
1069
|
function stableWorkspaceIds(previous, next) {
|
|
929
1070
|
if (previous.length !== next.length) return next;
|
|
@@ -972,6 +1113,7 @@ window.__ModuleLoader__.load({
|
|
|
972
1113
|
/** Return copyable, read-only setup commands for a Git readiness state. */
|
|
973
1114
|
function worktreeSetupCommands(status) {
|
|
974
1115
|
switch (status) {
|
|
1116
|
+
case "gitNotInstalled": return [];
|
|
975
1117
|
case "noRepository": return [
|
|
976
1118
|
"git init",
|
|
977
1119
|
"printf \"# README\\n\" > README.md",
|
|
@@ -989,6 +1131,10 @@ window.__ModuleLoader__.load({
|
|
|
989
1131
|
}
|
|
990
1132
|
function readinessFromBranchError(error) {
|
|
991
1133
|
const viewError = toWorktreeViewError(error);
|
|
1134
|
+
if (viewError.code === "GIT_NOT_INSTALLED") return {
|
|
1135
|
+
status: "gitNotInstalled",
|
|
1136
|
+
error: viewError
|
|
1137
|
+
};
|
|
992
1138
|
if (viewError.code === "WORKSPACE_NOT_GIT_REPOSITORY") return {
|
|
993
1139
|
status: "noRepository",
|
|
994
1140
|
error: viewError
|
|
@@ -1024,6 +1170,19 @@ window.__ModuleLoader__.load({
|
|
|
1024
1170
|
readiness: branchesResult.value.length > 0 ? { status: "ready" } : { status: "noLocalBranch" }
|
|
1025
1171
|
};
|
|
1026
1172
|
}
|
|
1173
|
+
/** Isolate modal-target reads from full-surface refresh generations. */
|
|
1174
|
+
function createWorktreeModalViewLoader() {
|
|
1175
|
+
const guard = createWorktreeRefreshGuard();
|
|
1176
|
+
return {
|
|
1177
|
+
invalidate: guard.invalidate,
|
|
1178
|
+
load(manager, workspaceId, onSuccess, onError) {
|
|
1179
|
+
return guard.run(() => loadWorktreeView(manager, workspaceId), (data) => onSuccess({
|
|
1180
|
+
workspaceId,
|
|
1181
|
+
...data
|
|
1182
|
+
}), (error) => onError(toWorktreeViewError(error)));
|
|
1183
|
+
}
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1027
1186
|
/** Load one independent projection per DSH Workspace for the flat sidebar hierarchy. */
|
|
1028
1187
|
async function loadWorktreeViews(manager, workspaceIds, options = {}) {
|
|
1029
1188
|
const views = await Promise.all(workspaceIds.map(async (workspaceId) => ({
|
|
@@ -1193,6 +1352,7 @@ window.__ModuleLoader__.load({
|
|
|
1193
1352
|
//#region lib/client/worktree-surface-dialogs.js
|
|
1194
1353
|
function worktreeSetupMessage(status, t) {
|
|
1195
1354
|
switch (status) {
|
|
1355
|
+
case "gitNotInstalled": return t("worktree.setup.gitNotInstalled");
|
|
1196
1356
|
case "noRepository": return t("worktree.setup.noRepository");
|
|
1197
1357
|
case "noInitialCommit": return t("worktree.setup.noInitialCommit");
|
|
1198
1358
|
case "noLocalBranch": return t("worktree.setup.noLocalBranch");
|
|
@@ -1323,9 +1483,12 @@ window.__ModuleLoader__.load({
|
|
|
1323
1483
|
})
|
|
1324
1484
|
});
|
|
1325
1485
|
}
|
|
1326
|
-
function WorktreeCreateDialog({ t, workspace, view, setupStatus, canCreate, selectedBranch, newBranch, actionPending, onClose, onSelectedBranchChange, onNewBranchChange, onSubmit }) {
|
|
1486
|
+
function WorktreeCreateDialog({ t, workspace, view, readError, setupStatus, canCreate, mode, importCandidates, selectedImportPath, selectedBranch, newBranch, actionPending, onClose, onRetry, onModeChange, onRetryImportCandidates, onSelectedImportPathChange, onSelectedBranchChange, onNewBranchChange, onSubmit }) {
|
|
1327
1487
|
if (workspace === void 0) return null;
|
|
1328
|
-
|
|
1488
|
+
const setupCommands = setupStatus === void 0 ? [] : worktreeSetupCommands(setupStatus);
|
|
1489
|
+
const importing = mode === "import";
|
|
1490
|
+
const importBlocked = actionPending || importCandidates.status === "loading" || selectedImportPath === void 0;
|
|
1491
|
+
return (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
1329
1492
|
open: true,
|
|
1330
1493
|
onClose: () => {
|
|
1331
1494
|
if (actionPending) return;
|
|
@@ -1333,7 +1496,7 @@ window.__ModuleLoader__.load({
|
|
|
1333
1496
|
},
|
|
1334
1497
|
closeLabel: t("dialog.closeWorktreeCreate"),
|
|
1335
1498
|
title: t("worktree.createTitle"),
|
|
1336
|
-
description: t("worktree.createDescription", { name: workspace.title }),
|
|
1499
|
+
description: importing ? t("worktree.importDescription", { name: workspace.title }) : t("worktree.createDescription", { name: workspace.title }),
|
|
1337
1500
|
footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1338
1501
|
variant: "outline",
|
|
1339
1502
|
disabled: actionPending,
|
|
@@ -1341,13 +1504,104 @@ window.__ModuleLoader__.load({
|
|
|
1341
1504
|
children: t("dialog.cancel")
|
|
1342
1505
|
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1343
1506
|
variant: "primary",
|
|
1344
|
-
disabled: actionPending || selectedBranch.length === 0 || newBranch.trim().length === 0,
|
|
1507
|
+
disabled: importing ? importBlocked : actionPending || !canCreate || selectedBranch.length === 0 || newBranch.trim().length === 0,
|
|
1345
1508
|
onClick: () => {
|
|
1346
1509
|
onSubmit();
|
|
1347
1510
|
},
|
|
1348
|
-
children: t("worktree.create")
|
|
1511
|
+
children: importing ? t("worktree.import") : t("worktree.create")
|
|
1349
1512
|
})] }),
|
|
1350
|
-
children:
|
|
1513
|
+
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
1514
|
+
className: worktree_css_default.worktreeModalTabs,
|
|
1515
|
+
role: "tablist",
|
|
1516
|
+
"aria-label": t("worktree.title"),
|
|
1517
|
+
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
1518
|
+
className: worktree_css_default.worktreeModalTab,
|
|
1519
|
+
type: "button",
|
|
1520
|
+
role: "tab",
|
|
1521
|
+
"aria-selected": mode === "create",
|
|
1522
|
+
disabled: actionPending,
|
|
1523
|
+
onClick: () => {
|
|
1524
|
+
onModeChange("create");
|
|
1525
|
+
},
|
|
1526
|
+
children: t("worktree.tabCreate")
|
|
1527
|
+
}), (0, react_jsx_runtime.jsx)("button", {
|
|
1528
|
+
className: worktree_css_default.worktreeModalTab,
|
|
1529
|
+
type: "button",
|
|
1530
|
+
role: "tab",
|
|
1531
|
+
"aria-selected": mode === "import",
|
|
1532
|
+
disabled: actionPending,
|
|
1533
|
+
onClick: () => {
|
|
1534
|
+
onModeChange("import");
|
|
1535
|
+
},
|
|
1536
|
+
children: t("worktree.tabImport")
|
|
1537
|
+
})]
|
|
1538
|
+
}), importing ? (0, react_jsx_runtime.jsxs)("div", {
|
|
1539
|
+
className: worktree_css_default.worktreeImportCandidates,
|
|
1540
|
+
role: "tabpanel",
|
|
1541
|
+
children: [
|
|
1542
|
+
importCandidates.status === "loading" && importCandidates.candidates.length === 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
1543
|
+
className: worktree_css_default.message,
|
|
1544
|
+
children: t("worktree.importLoading")
|
|
1545
|
+
}),
|
|
1546
|
+
importCandidates.status === "error" && (0, react_jsx_runtime.jsxs)("div", {
|
|
1547
|
+
className: worktree_css_default.worktreeImportError,
|
|
1548
|
+
role: "alert",
|
|
1549
|
+
children: [(0, react_jsx_runtime.jsx)("p", {
|
|
1550
|
+
className: worktree_css_default.message,
|
|
1551
|
+
children: formatWorktreeViewError(importCandidates.error, t)
|
|
1552
|
+
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1553
|
+
variant: "outline",
|
|
1554
|
+
disabled: actionPending,
|
|
1555
|
+
onClick: onRetryImportCandidates,
|
|
1556
|
+
children: t("action.retry")
|
|
1557
|
+
})]
|
|
1558
|
+
}),
|
|
1559
|
+
importCandidates.candidates.length === 0 && importCandidates.status === "ready" && (0, react_jsx_runtime.jsx)("p", {
|
|
1560
|
+
className: worktree_css_default.message,
|
|
1561
|
+
children: t("worktree.importEmpty")
|
|
1562
|
+
}),
|
|
1563
|
+
importCandidates.candidates.length > 0 && (0, react_jsx_runtime.jsxs)("label", {
|
|
1564
|
+
className: worktree_css_default.modalField,
|
|
1565
|
+
children: [t("worktree.tabImport"), (0, react_jsx_runtime.jsxs)("select", {
|
|
1566
|
+
className: worktree_css_default.worktreeImportSelect,
|
|
1567
|
+
"data-worktree-import-select": true,
|
|
1568
|
+
"aria-label": t("worktree.tabImport"),
|
|
1569
|
+
value: selectedImportPath ?? "",
|
|
1570
|
+
disabled: actionPending,
|
|
1571
|
+
onChange: (event) => {
|
|
1572
|
+
onSelectedImportPathChange(event.currentTarget.value);
|
|
1573
|
+
},
|
|
1574
|
+
children: [(0, react_jsx_runtime.jsx)("option", {
|
|
1575
|
+
value: "",
|
|
1576
|
+
disabled: true,
|
|
1577
|
+
children: t("worktree.importPlaceholder")
|
|
1578
|
+
}), importCandidates.candidates.map((candidate) => (0, react_jsx_runtime.jsxs)("option", {
|
|
1579
|
+
value: candidate.absolutePath,
|
|
1580
|
+
children: [
|
|
1581
|
+
candidate.branch,
|
|
1582
|
+
" — ",
|
|
1583
|
+
candidate.absolutePath
|
|
1584
|
+
]
|
|
1585
|
+
}, candidate.absolutePath))]
|
|
1586
|
+
})]
|
|
1587
|
+
})
|
|
1588
|
+
]
|
|
1589
|
+
}) : readError !== void 0 ? (0, react_jsx_runtime.jsxs)("div", {
|
|
1590
|
+
className: worktree_css_default.gitReadiness,
|
|
1591
|
+
"data-worktree-readiness": "error",
|
|
1592
|
+
role: "alert",
|
|
1593
|
+
children: [(0, react_jsx_runtime.jsx)("p", {
|
|
1594
|
+
className: worktree_css_default.message,
|
|
1595
|
+
"data-error": "true",
|
|
1596
|
+
children: formatWorktreeViewError(readError, t)
|
|
1597
|
+
}), readError.retryable && onRetry !== void 0 && (0, react_jsx_runtime.jsx)("button", {
|
|
1598
|
+
type: "button",
|
|
1599
|
+
className: worktree_css_default.retryButton,
|
|
1600
|
+
disabled: actionPending,
|
|
1601
|
+
onClick: onRetry,
|
|
1602
|
+
children: t("action.retry")
|
|
1603
|
+
})]
|
|
1604
|
+
}) : canCreate ? (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsxs)("label", {
|
|
1351
1605
|
className: worktree_css_default.modalField,
|
|
1352
1606
|
children: [t("worktree.baseBranch"), (0, react_jsx_runtime.jsx)("select", {
|
|
1353
1607
|
className: worktree_css_default.actionSelect,
|
|
@@ -1385,12 +1639,12 @@ window.__ModuleLoader__.load({
|
|
|
1385
1639
|
children: [(0, react_jsx_runtime.jsx)("p", {
|
|
1386
1640
|
className: worktree_css_default.message,
|
|
1387
1641
|
children: setupStatus === void 0 ? t("status.loading") : worktreeSetupMessage(setupStatus, t)
|
|
1388
|
-
}),
|
|
1642
|
+
}), setupCommands.length > 0 && (0, react_jsx_runtime.jsx)("pre", {
|
|
1389
1643
|
className: worktree_css_default.commandBlock,
|
|
1390
1644
|
"aria-label": t("worktree.setup.commands"),
|
|
1391
|
-
children:
|
|
1645
|
+
children: setupCommands.join("\n")
|
|
1392
1646
|
})]
|
|
1393
|
-
})
|
|
1647
|
+
})]
|
|
1394
1648
|
});
|
|
1395
1649
|
}
|
|
1396
1650
|
function WorktreeRemovalDialog({ t, worktree, actionPending, onClose, onSubmit }) {
|
|
@@ -1403,7 +1657,7 @@ window.__ModuleLoader__.load({
|
|
|
1403
1657
|
},
|
|
1404
1658
|
closeLabel: t("dialog.closeWorktreeRemove"),
|
|
1405
1659
|
title: t("worktree.remove"),
|
|
1406
|
-
description: t("worktree.removeDescription", { name: worktree.branch }),
|
|
1660
|
+
description: worktree.source === "external" ? t("worktree.removeExternalDescription", { name: worktree.branch }) : t("worktree.removeDescription", { name: worktree.branch }),
|
|
1407
1661
|
footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1408
1662
|
variant: "outline",
|
|
1409
1663
|
disabled: actionPending,
|
|
@@ -1427,6 +1681,17 @@ window.__ModuleLoader__.load({
|
|
|
1427
1681
|
function bindingIdsFor(bindings, worktreeId) {
|
|
1428
1682
|
return bindings.filter((binding) => binding.worktreeId === worktreeId).map((binding) => binding.sessionId);
|
|
1429
1683
|
}
|
|
1684
|
+
function clearSessionGroupExpansion(current, groupKeys) {
|
|
1685
|
+
const next = { ...current };
|
|
1686
|
+
for (const key of groupKeys) delete next[key];
|
|
1687
|
+
return next;
|
|
1688
|
+
}
|
|
1689
|
+
function isCompleteWorktreeWorkspaceSnapshot(workspaceIds, views) {
|
|
1690
|
+
if (views.length !== workspaceIds.length) return false;
|
|
1691
|
+
const expected = new Set(workspaceIds);
|
|
1692
|
+
const actual = new Set(views.map((view) => view.workspaceId));
|
|
1693
|
+
return actual.size === expected.size && [...expected].every((id) => actual.has(id));
|
|
1694
|
+
}
|
|
1430
1695
|
function includesText(value, query) {
|
|
1431
1696
|
return value.toLocaleLowerCase().includes(query);
|
|
1432
1697
|
}
|
|
@@ -1438,6 +1703,46 @@ window.__ModuleLoader__.load({
|
|
|
1438
1703
|
if (view.worktrees.some((record) => includesText(record.branch, query) || includesText(record.absolutePath, query))) return true;
|
|
1439
1704
|
return view.bindings.some((binding) => sessionMatchesQuery(binding.sessionId, sessions, query));
|
|
1440
1705
|
}
|
|
1706
|
+
function resolveCurrentSessionLocation(currentSessionId, workspaces, views) {
|
|
1707
|
+
if (currentSessionId === void 0) return void 0;
|
|
1708
|
+
const workspace = workspaces.find((candidate) => candidate.sessionIds.includes(currentSessionId));
|
|
1709
|
+
if (workspace === void 0) return void 0;
|
|
1710
|
+
const view = views.find((candidate) => candidate.workspaceId === workspace.workspaceId);
|
|
1711
|
+
if (view === void 0) return void 0;
|
|
1712
|
+
const binding = view.bindings.find((candidate) => candidate.sessionId === currentSessionId);
|
|
1713
|
+
if (binding === void 0) return {
|
|
1714
|
+
sessionId: currentSessionId,
|
|
1715
|
+
workspaceId: workspace.workspaceId,
|
|
1716
|
+
groupKey: "main:" + workspace.workspaceId,
|
|
1717
|
+
kind: "main"
|
|
1718
|
+
};
|
|
1719
|
+
const worktree = view.worktrees.find((candidate) => candidate.worktreeId === binding.worktreeId && candidate.workspaceId === workspace.workspaceId);
|
|
1720
|
+
if (worktree === void 0) return void 0;
|
|
1721
|
+
return {
|
|
1722
|
+
sessionId: currentSessionId,
|
|
1723
|
+
workspaceId: workspace.workspaceId,
|
|
1724
|
+
groupKey: "worktree:" + worktree.worktreeId,
|
|
1725
|
+
kind: "worktree",
|
|
1726
|
+
worktreeId: worktree.worktreeId
|
|
1727
|
+
};
|
|
1728
|
+
}
|
|
1729
|
+
function currentSessionRevealKeys(location) {
|
|
1730
|
+
if (location === void 0) return [];
|
|
1731
|
+
return [
|
|
1732
|
+
"workspace:" + location.workspaceId,
|
|
1733
|
+
location.kind === "main" ? "main:" + location.workspaceId : "worktree:" + location.worktreeId,
|
|
1734
|
+
"session-group:" + location.groupKey
|
|
1735
|
+
];
|
|
1736
|
+
}
|
|
1737
|
+
//#endregion
|
|
1738
|
+
//#region lib/client/worktree-session-position.js
|
|
1739
|
+
function scrollCurrentSessionIntoView(root, sessionId) {
|
|
1740
|
+
if (root === null) return false;
|
|
1741
|
+
const row = Array.from(root.querySelectorAll("[data-session-id]")).find((candidate) => candidate.dataset.sessionId === sessionId);
|
|
1742
|
+
if (row === void 0) return false;
|
|
1743
|
+
row.scrollIntoView({ block: "nearest" });
|
|
1744
|
+
return true;
|
|
1745
|
+
}
|
|
1441
1746
|
//#endregion
|
|
1442
1747
|
//#region lib/client/worktree-surface-rows.js
|
|
1443
1748
|
function rowHalf(event) {
|
|
@@ -1670,7 +1975,7 @@ window.__ModuleLoader__.load({
|
|
|
1670
1975
|
});
|
|
1671
1976
|
}
|
|
1672
1977
|
/** Worktree-mode Session row with the same trailing options menu as native DSH rows. */
|
|
1673
|
-
function WorktreeSessionRow({ t, sessionId, blank, label, drag, actionPending, onOpen, onRename, onFork, onArchive }) {
|
|
1978
|
+
function WorktreeSessionRow({ t, sessionId, blank, current, label, drag, actionPending, onOpen, onRename, onFork, onArchive }) {
|
|
1674
1979
|
const [menuOpen, setMenuOpen] = (0, react.useState)(false);
|
|
1675
1980
|
const markerClass = drag.marker === "before" ? worktree_css_default.dropBefore : drag.marker === "after" ? worktree_css_default.dropAfter : "";
|
|
1676
1981
|
const sessionMenuItems = [
|
|
@@ -1697,9 +2002,11 @@ window.__ModuleLoader__.load({
|
|
|
1697
2002
|
className: `${worktree_css_default.treeSessionRow} ${markerClass}`,
|
|
1698
2003
|
"data-session-id": sessionId,
|
|
1699
2004
|
"data-session-blank": blank ? "true" : void 0,
|
|
2005
|
+
"data-session-current": current ? "true" : void 0,
|
|
1700
2006
|
"data-session-drag": drag.active ? "active" : void 0,
|
|
1701
2007
|
"data-menu-open": menuOpen || void 0,
|
|
1702
2008
|
role: "treeitem",
|
|
2009
|
+
"aria-current": current ? "true" : void 0,
|
|
1703
2010
|
draggable: true,
|
|
1704
2011
|
onDragStart: (event) => {
|
|
1705
2012
|
event.dataTransfer.effectAllowed = "move";
|
|
@@ -1718,18 +2025,14 @@ window.__ModuleLoader__.load({
|
|
|
1718
2025
|
event.preventDefault();
|
|
1719
2026
|
drag.drop(rowHalf(event));
|
|
1720
2027
|
},
|
|
1721
|
-
children: [(0, react_jsx_runtime.
|
|
2028
|
+
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
1722
2029
|
type: "button",
|
|
1723
2030
|
className: worktree_css_default.treeSessionContent,
|
|
1724
2031
|
onClick: onOpen,
|
|
1725
|
-
children:
|
|
1726
|
-
className: worktree_css_default.treeGuide,
|
|
1727
|
-
"aria-hidden": "true",
|
|
1728
|
-
children: "└"
|
|
1729
|
-
}), (0, react_jsx_runtime.jsx)("span", {
|
|
2032
|
+
children: (0, react_jsx_runtime.jsx)("span", {
|
|
1730
2033
|
className: worktree_css_default.sessionLabel,
|
|
1731
2034
|
children: label
|
|
1732
|
-
})
|
|
2035
|
+
})
|
|
1733
2036
|
}), !blank && (0, react_jsx_runtime.jsx)("span", {
|
|
1734
2037
|
className: worktree_css_default.rowActions,
|
|
1735
2038
|
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
|
|
@@ -1761,13 +2064,14 @@ window.__ModuleLoader__.load({
|
|
|
1761
2064
|
})]
|
|
1762
2065
|
});
|
|
1763
2066
|
}
|
|
1764
|
-
function WorktreeSessionGroup({ t, groupKey, sessionIds, workspaceId, expanded, actionPending, sessions, dragState, onToggleExpanded, onStartDrag, onHoverDrag, onClearDrag, onFinishDrag, onCommitDrag, onOpen, onRename, onFork, onArchive }) {
|
|
2067
|
+
function WorktreeSessionGroup({ t, groupKey, sessionIds, workspaceId, currentSessionId, expanded, actionPending, sessions, dragState, onToggleExpanded, onStartDrag, onHoverDrag, onClearDrag, onFinishDrag, onCommitDrag, onOpen, onRename, onFork, onArchive }) {
|
|
1765
2068
|
const visibleSessionIds = expanded ? sessionIds : sessionIds.slice(0, 5);
|
|
1766
2069
|
const sameGroupDrag = dragState?.groupKey === groupKey;
|
|
1767
2070
|
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [visibleSessionIds.map((sessionId) => (0, react_jsx_runtime.jsx)(WorktreeSessionRow, {
|
|
1768
2071
|
t,
|
|
1769
2072
|
sessionId,
|
|
1770
2073
|
blank: isBlankSession(sessionId, sessions),
|
|
2074
|
+
current: sessionId === currentSessionId,
|
|
1771
2075
|
label: sessionLabel(sessionId, sessions, t),
|
|
1772
2076
|
drag: {
|
|
1773
2077
|
active: sameGroupDrag,
|
|
@@ -1831,19 +2135,31 @@ window.__ModuleLoader__.load({
|
|
|
1831
2135
|
* Peer Worktree navigation surface. It keeps the original DSH Workspace mode
|
|
1832
2136
|
* intact and renders a browser-local Workspace → Worktree → Session projection.
|
|
1833
2137
|
*/
|
|
1834
|
-
function WorktreeSurface({ useStore, actions, useSessions, useWorkspaces, t, available, manager, invalidateWorktreeContext, createWorkspace, createSessionForWorktree: createSessionCallback, createMainSession, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, insertSessionBefore, insertWorktreeBefore, renameSession, forkSession, archiveSession, ensureSessionWorkspace, syncSessionWorkspaces, openSession }) {
|
|
2138
|
+
function WorktreeSurface({ useStore, actions, useSessions, useWorkspaces, t, available, expandState, manager, invalidateWorktreeContext, createWorkspace, createSessionForWorktree: createSessionCallback, createMainSession, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, insertSessionBefore, insertWorktreeBefore, renameSession, forkSession, archiveSession, ensureSessionWorkspace, syncSessionWorkspaces, openSession }) {
|
|
1835
2139
|
const mode = effectiveViewMode(useStore((state) => state.viewMode), available && manager !== void 0);
|
|
1836
2140
|
const sessions = useSessions((state) => state);
|
|
1837
2141
|
const workspaces = useWorkspaces((state) => state);
|
|
2142
|
+
const currentSessionId = sessions.current;
|
|
1838
2143
|
const workspaceIds = useStableWorkspaceIds(workspaces.items);
|
|
1839
2144
|
const [readState, setReadState] = (0, react.useState)(EMPTY_READ_STATE);
|
|
2145
|
+
const expandSnapshot = (0, react.useSyncExternalStore)(expandState.subscribe, expandState.getSnapshot, expandState.getSnapshot);
|
|
1840
2146
|
const readStateRef = (0, react.useRef)(readState);
|
|
1841
2147
|
readStateRef.current = readState;
|
|
1842
2148
|
const [searchQuery, setSearchQuery] = (0, react.useState)("");
|
|
1843
|
-
const [
|
|
1844
|
-
const
|
|
1845
|
-
|
|
2149
|
+
const [currentSessionReveal, setCurrentSessionReveal] = (0, react.useState)();
|
|
2150
|
+
const searchQueryRef = (0, react.useRef)(searchQuery);
|
|
2151
|
+
searchQueryRef.current = searchQuery;
|
|
2152
|
+
const locateGenerationRef = (0, react.useRef)(0);
|
|
2153
|
+
const positionedLocateGenerationRef = (0, react.useRef)();
|
|
1846
2154
|
const [worktreeModalWorkspaceId, setWorktreeModalWorkspaceId] = (0, react.useState)();
|
|
2155
|
+
const [modalReadError, setModalReadError] = (0, react.useState)();
|
|
2156
|
+
const [modalReadLoading, setModalReadLoading] = (0, react.useState)(false);
|
|
2157
|
+
const [worktreeModalMode, setWorktreeModalMode] = (0, react.useState)("create");
|
|
2158
|
+
const [importCandidates, setImportCandidates] = (0, react.useState)({
|
|
2159
|
+
status: "idle",
|
|
2160
|
+
candidates: []
|
|
2161
|
+
});
|
|
2162
|
+
const [selectedImportPath, setSelectedImportPath] = (0, react.useState)();
|
|
1847
2163
|
const [openWorkspaceMenuId, setOpenWorkspaceMenuId] = (0, react.useState)();
|
|
1848
2164
|
const [openWorktreeMenuId, setOpenWorktreeMenuId] = (0, react.useState)();
|
|
1849
2165
|
const [worktreeRemoval, setWorktreeRemoval] = (0, react.useState)();
|
|
@@ -1871,6 +2187,11 @@ window.__ModuleLoader__.load({
|
|
|
1871
2187
|
const [worktreeDrag, setWorktreeDrag] = (0, react.useState)();
|
|
1872
2188
|
const worktreeDropCommitted = (0, react.useRef)(false);
|
|
1873
2189
|
const refreshGuard = (0, react.useRef)(createWorktreeRefreshGuard());
|
|
2190
|
+
const modalReadLoader = (0, react.useRef)(createWorktreeModalViewLoader());
|
|
2191
|
+
const modalReadViewRef = (0, react.useRef)();
|
|
2192
|
+
const importCandidatesGuard = (0, react.useRef)(createWorktreeRefreshGuard());
|
|
2193
|
+
const modalWorkspaceIdRef = (0, react.useRef)(worktreeModalWorkspaceId);
|
|
2194
|
+
modalWorkspaceIdRef.current = worktreeModalWorkspaceId;
|
|
1874
2195
|
const { ref, width, bounds } = useSidebarOverlayGeometry(mode === "worktree");
|
|
1875
2196
|
const collapsed = width <= 64;
|
|
1876
2197
|
const query = searchQuery.trim().toLocaleLowerCase();
|
|
@@ -1893,13 +2214,13 @@ window.__ModuleLoader__.load({
|
|
|
1893
2214
|
}), (views) => {
|
|
1894
2215
|
setReadState({
|
|
1895
2216
|
status: "ready",
|
|
1896
|
-
views
|
|
2217
|
+
views: modalReadViewRef.current === void 0 ? views : mergeWorktreeView(views, modalReadViewRef.current)
|
|
1897
2218
|
});
|
|
1898
2219
|
}, (error) => {
|
|
1899
2220
|
if (preserveCurrent) throw error;
|
|
1900
2221
|
setReadState({
|
|
1901
2222
|
status: "error",
|
|
1902
|
-
views: [],
|
|
2223
|
+
views: modalReadViewRef.current === void 0 ? [] : [modalReadViewRef.current],
|
|
1903
2224
|
error: toWorktreeViewError(error)
|
|
1904
2225
|
});
|
|
1905
2226
|
});
|
|
@@ -1908,10 +2229,39 @@ window.__ModuleLoader__.load({
|
|
|
1908
2229
|
manager,
|
|
1909
2230
|
workspaceIds
|
|
1910
2231
|
]);
|
|
2232
|
+
const loadModalWorktreeView = (0, react.useCallback)((workspaceId) => {
|
|
2233
|
+
setModalReadError(void 0);
|
|
2234
|
+
setModalReadLoading(true);
|
|
2235
|
+
if (manager === void 0) {
|
|
2236
|
+
setModalReadLoading(false);
|
|
2237
|
+
setModalReadError({
|
|
2238
|
+
code: "WORKTREE_VIEW_UNAVAILABLE",
|
|
2239
|
+
message: "",
|
|
2240
|
+
retryable: true
|
|
2241
|
+
});
|
|
2242
|
+
return;
|
|
2243
|
+
}
|
|
2244
|
+
modalReadLoader.current.load(manager, workspaceId, (view) => {
|
|
2245
|
+
modalReadViewRef.current = view;
|
|
2246
|
+
setModalReadLoading(false);
|
|
2247
|
+
setReadState((current) => ({
|
|
2248
|
+
...current,
|
|
2249
|
+
views: mergeWorktreeView(current.views, view)
|
|
2250
|
+
}));
|
|
2251
|
+
}, (error) => {
|
|
2252
|
+
setModalReadLoading(false);
|
|
2253
|
+
setModalReadError(toWorktreeViewError(error));
|
|
2254
|
+
});
|
|
2255
|
+
}, [manager]);
|
|
1911
2256
|
(0, react.useEffect)(() => {
|
|
1912
2257
|
if (mode === "worktree") refresh({ preserveCurrent: readStateRef.current.status === "ready" });
|
|
1913
2258
|
else {
|
|
1914
2259
|
refreshGuard.current.invalidate();
|
|
2260
|
+
modalReadLoader.current.invalidate();
|
|
2261
|
+
modalReadViewRef.current = void 0;
|
|
2262
|
+
setWorktreeModalWorkspaceId(void 0);
|
|
2263
|
+
setModalReadError(void 0);
|
|
2264
|
+
setModalReadLoading(false);
|
|
1915
2265
|
setReadState(EMPTY_READ_STATE);
|
|
1916
2266
|
}
|
|
1917
2267
|
}, [mode, refresh]);
|
|
@@ -1927,18 +2277,76 @@ window.__ModuleLoader__.load({
|
|
|
1927
2277
|
syncSessionWorkspaces
|
|
1928
2278
|
]);
|
|
1929
2279
|
const viewByWorkspace = (0, react.useMemo)(() => new Map(readState.views.map((view) => [view.workspaceId, view])), [readState.views]);
|
|
2280
|
+
const currentSessionLocation = (0, react.useMemo)(() => readState.status === "ready" ? resolveCurrentSessionLocation(currentSessionId, workspaces.items, readState.views) : void 0, [
|
|
2281
|
+
currentSessionId,
|
|
2282
|
+
readState.status,
|
|
2283
|
+
readState.views,
|
|
2284
|
+
workspaces.items
|
|
2285
|
+
]);
|
|
2286
|
+
const currentRevealKeys = (0, react.useMemo)(() => new Set(currentSessionRevealKeys(currentSessionLocation)), [currentSessionLocation]);
|
|
2287
|
+
const isCurrentSessionReveal = (key) => currentSessionReveal !== void 0 && currentSessionReveal.sessionId === currentSessionId && currentRevealKeys.has(key) && currentSessionReveal.suppressedKeys[key] !== true;
|
|
2288
|
+
(0, react.useLayoutEffect)(() => {
|
|
2289
|
+
locateGenerationRef.current += 1;
|
|
2290
|
+
positionedLocateGenerationRef.current = void 0;
|
|
2291
|
+
if (mode !== "worktree") {
|
|
2292
|
+
setCurrentSessionReveal(void 0);
|
|
2293
|
+
return;
|
|
2294
|
+
}
|
|
2295
|
+
if (searchQueryRef.current.trim().length > 0) setSearchQuery("");
|
|
2296
|
+
setCurrentSessionReveal(currentSessionId === void 0 ? void 0 : {
|
|
2297
|
+
sessionId: currentSessionId,
|
|
2298
|
+
suppressedKeys: {}
|
|
2299
|
+
});
|
|
2300
|
+
}, [currentSessionId, mode]);
|
|
2301
|
+
(0, react.useLayoutEffect)(() => {
|
|
2302
|
+
if (mode !== "worktree" || currentSessionId === void 0 || currentSessionLocation === void 0) return;
|
|
2303
|
+
const generation = locateGenerationRef.current;
|
|
2304
|
+
if (positionedLocateGenerationRef.current === generation) return;
|
|
2305
|
+
let cancelled = false;
|
|
2306
|
+
const frame = requestAnimationFrame(() => {
|
|
2307
|
+
if (cancelled || generation !== locateGenerationRef.current) return;
|
|
2308
|
+
if (!scrollCurrentSessionIntoView(ref.current, currentSessionId)) return;
|
|
2309
|
+
positionedLocateGenerationRef.current = generation;
|
|
2310
|
+
});
|
|
2311
|
+
return () => {
|
|
2312
|
+
cancelled = true;
|
|
2313
|
+
cancelAnimationFrame(frame);
|
|
2314
|
+
};
|
|
2315
|
+
}, [
|
|
2316
|
+
currentSessionId,
|
|
2317
|
+
currentSessionLocation,
|
|
2318
|
+
currentSessionReveal,
|
|
2319
|
+
expandSnapshot,
|
|
2320
|
+
mode,
|
|
2321
|
+
query,
|
|
2322
|
+
readState.status
|
|
2323
|
+
]);
|
|
2324
|
+
(0, react.useEffect)(() => {
|
|
2325
|
+
if (readState.status !== "ready" || !isCompleteWorktreeWorkspaceSnapshot(workspaceIds, readState.views)) return;
|
|
2326
|
+
expandState.actions.retain(workspaceIds, readState.views.flatMap((view) => view.worktrees.map((record) => record.worktreeId)));
|
|
2327
|
+
}, [
|
|
2328
|
+
expandState,
|
|
2329
|
+
readState.status,
|
|
2330
|
+
readState.views,
|
|
2331
|
+
workspaceIds
|
|
2332
|
+
]);
|
|
1930
2333
|
const modalWorkspace = workspaces.items.find((workspace) => workspace.workspaceId === worktreeModalWorkspaceId);
|
|
1931
2334
|
const modalView = worktreeModalWorkspaceId === void 0 ? void 0 : viewByWorkspace.get(worktreeModalWorkspaceId);
|
|
1932
2335
|
const modalReadiness = modalView?.readiness;
|
|
1933
2336
|
const modalSetupStatus = modalView === void 0 ? void 0 : modalReadiness?.status === "ready" ? modalView.branches.length === 0 ? "noLocalBranch" : void 0 : modalReadiness?.status;
|
|
1934
|
-
const modalCanCreate = modalSetupStatus === void 0 && modalReadiness?.status === "ready";
|
|
2337
|
+
const modalCanCreate = !modalReadLoading && modalSetupStatus === void 0 && modalReadiness?.status === "ready";
|
|
1935
2338
|
(0, react.useEffect)(() => {
|
|
1936
2339
|
if (worktreeModalWorkspaceId === void 0 || modalView === void 0) return;
|
|
1937
2340
|
if (modalView.readiness.status !== "ready") {
|
|
1938
2341
|
setSelectedBranch("");
|
|
2342
|
+
setNewBranch("");
|
|
1939
2343
|
return;
|
|
1940
2344
|
}
|
|
1941
2345
|
setSelectedBranch((current) => reconcileBaseBranchSelection(current, modalView.branches));
|
|
2346
|
+
setNewBranch((current) => {
|
|
2347
|
+
if (current.length > 0) return current;
|
|
2348
|
+
return createDefaultWorktreeName([...modalView.branches.map((branch) => branch.name), ...modalView.worktrees.map((worktree) => worktree.branch)]);
|
|
2349
|
+
});
|
|
1942
2350
|
}, [modalView, worktreeModalWorkspaceId]);
|
|
1943
2351
|
const runMutation = async (operation) => {
|
|
1944
2352
|
setActionPending(true);
|
|
@@ -1952,6 +2360,27 @@ window.__ModuleLoader__.load({
|
|
|
1952
2360
|
setActionPending(false);
|
|
1953
2361
|
}
|
|
1954
2362
|
};
|
|
2363
|
+
const loadImportCandidates = (0, react.useCallback)(async (workspaceId) => {
|
|
2364
|
+
if (manager === void 0) return;
|
|
2365
|
+
setImportCandidates((current) => ({
|
|
2366
|
+
status: "loading",
|
|
2367
|
+
candidates: current.candidates
|
|
2368
|
+
}));
|
|
2369
|
+
await importCandidatesGuard.current.run(() => manager.listImportCandidates({ workspaceId }), (candidates) => {
|
|
2370
|
+
if (modalWorkspaceIdRef.current !== workspaceId) return;
|
|
2371
|
+
setImportCandidates({
|
|
2372
|
+
status: "ready",
|
|
2373
|
+
candidates
|
|
2374
|
+
});
|
|
2375
|
+
}, (error) => {
|
|
2376
|
+
if (modalWorkspaceIdRef.current !== workspaceId) return;
|
|
2377
|
+
setImportCandidates((current) => ({
|
|
2378
|
+
status: "error",
|
|
2379
|
+
candidates: current.candidates,
|
|
2380
|
+
error: toWorktreeViewError(error)
|
|
2381
|
+
}));
|
|
2382
|
+
});
|
|
2383
|
+
}, [manager]);
|
|
1955
2384
|
const workspaceRenameTrimmed = workspaceRenameDraft.trim();
|
|
1956
2385
|
const workspaceRenameDuplicate = workspaceRenameTarget !== void 0 && workspaceRenameTrimmed.length > 0 && workspaces.items.some((workspace) => workspace.workspaceId !== workspaceRenameTarget.workspaceId && workspace.title === workspaceRenameTrimmed);
|
|
1957
2386
|
const workspaceRenameBlocked = workspaceRenamePending || workspaceRenameTarget === void 0 || workspaceRenameTrimmed.length === 0 || workspaceRenameTrimmed === workspaceRenameTarget?.currentTitle || workspaceRenameDuplicate;
|
|
@@ -2134,80 +2563,172 @@ window.__ModuleLoader__.load({
|
|
|
2134
2563
|
if (archiveSession === void 0) return;
|
|
2135
2564
|
await runMutation(() => archiveSession(sessionId));
|
|
2136
2565
|
};
|
|
2566
|
+
const clearSessionGroups = (groupKeys) => {
|
|
2567
|
+
if (groupKeys.length === 0) return;
|
|
2568
|
+
setExpandedSessionGroups((current) => clearSessionGroupExpansion(current, groupKeys));
|
|
2569
|
+
};
|
|
2570
|
+
const suppressCurrentSessionReveal = (key) => {
|
|
2571
|
+
if (!isCurrentSessionReveal(key)) return false;
|
|
2572
|
+
setCurrentSessionReveal((current) => {
|
|
2573
|
+
if (current === void 0 || current.sessionId !== currentSessionId) return current;
|
|
2574
|
+
return {
|
|
2575
|
+
...current,
|
|
2576
|
+
suppressedKeys: {
|
|
2577
|
+
...current.suppressedKeys,
|
|
2578
|
+
[key]: true
|
|
2579
|
+
}
|
|
2580
|
+
};
|
|
2581
|
+
});
|
|
2582
|
+
return true;
|
|
2583
|
+
};
|
|
2137
2584
|
const toggleWorkspace = (workspaceId) => {
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2585
|
+
const persistedExpanded = isWorkspaceExpanded(expandSnapshot, workspaceId);
|
|
2586
|
+
const autoExpanded = isCurrentSessionReveal("workspace:" + workspaceId);
|
|
2587
|
+
const visuallyExpanded = persistedExpanded || autoExpanded;
|
|
2588
|
+
if (visuallyExpanded && autoExpanded) suppressCurrentSessionReveal("workspace:" + workspaceId);
|
|
2589
|
+
if (visuallyExpanded && !persistedExpanded) {
|
|
2590
|
+
clearSessionGroups(["main:" + workspaceId, ...(viewByWorkspace.get(workspaceId)?.worktrees.map((record) => record.worktreeId) ?? []).map((worktreeId) => "worktree:" + worktreeId)]);
|
|
2591
|
+
return;
|
|
2592
|
+
}
|
|
2593
|
+
expandState.actions.toggleWorkspace(workspaceId);
|
|
2594
|
+
if (visuallyExpanded) clearSessionGroups(["main:" + workspaceId, ...(viewByWorkspace.get(workspaceId)?.worktrees.map((record) => record.worktreeId) ?? []).map((worktreeId) => "worktree:" + worktreeId)]);
|
|
2142
2595
|
};
|
|
2143
2596
|
const toggleMain = (workspaceId) => {
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2597
|
+
const persistedExpanded = isMainExpanded(expandSnapshot, workspaceId);
|
|
2598
|
+
const autoExpanded = isCurrentSessionReveal("main:" + workspaceId);
|
|
2599
|
+
const visuallyExpanded = persistedExpanded || autoExpanded;
|
|
2600
|
+
if (visuallyExpanded && autoExpanded) suppressCurrentSessionReveal("main:" + workspaceId);
|
|
2601
|
+
if (visuallyExpanded && !persistedExpanded) {
|
|
2602
|
+
clearSessionGroups(["main:" + workspaceId]);
|
|
2603
|
+
return;
|
|
2604
|
+
}
|
|
2605
|
+
expandState.actions.toggleMain(workspaceId);
|
|
2606
|
+
if (visuallyExpanded) clearSessionGroups(["main:" + workspaceId]);
|
|
2148
2607
|
};
|
|
2149
2608
|
const toggleWorktree = (worktreeId) => {
|
|
2150
|
-
|
|
2609
|
+
const persistedExpanded = isWorktreeExpanded(expandSnapshot, worktreeId);
|
|
2610
|
+
const autoExpanded = isCurrentSessionReveal("worktree:" + worktreeId);
|
|
2611
|
+
const visuallyExpanded = persistedExpanded || autoExpanded;
|
|
2612
|
+
if (visuallyExpanded && autoExpanded) suppressCurrentSessionReveal("worktree:" + worktreeId);
|
|
2613
|
+
if (visuallyExpanded && !persistedExpanded) {
|
|
2614
|
+
clearSessionGroups(["worktree:" + worktreeId]);
|
|
2615
|
+
return;
|
|
2616
|
+
}
|
|
2617
|
+
expandState.actions.toggleWorktree(worktreeId);
|
|
2618
|
+
if (visuallyExpanded) clearSessionGroups(["worktree:" + worktreeId]);
|
|
2619
|
+
};
|
|
2620
|
+
const toggleSessionGroup = (groupKey) => {
|
|
2621
|
+
const autoExpanded = isCurrentSessionReveal("session-group:" + groupKey);
|
|
2622
|
+
const transientExpanded = expandedSessionGroups[groupKey] === true;
|
|
2623
|
+
if (autoExpanded) {
|
|
2624
|
+
suppressCurrentSessionReveal("session-group:" + groupKey);
|
|
2625
|
+
setExpandedSessionGroups((current) => {
|
|
2626
|
+
const next = { ...current };
|
|
2627
|
+
delete next[groupKey];
|
|
2628
|
+
return next;
|
|
2629
|
+
});
|
|
2630
|
+
return;
|
|
2631
|
+
}
|
|
2632
|
+
setExpandedSessionGroups((current) => ({
|
|
2151
2633
|
...current,
|
|
2152
|
-
[
|
|
2634
|
+
[groupKey]: !transientExpanded
|
|
2153
2635
|
}));
|
|
2154
2636
|
};
|
|
2637
|
+
const closeWorktreeCreator = (force = false) => {
|
|
2638
|
+
if (actionPending && !force) return;
|
|
2639
|
+
modalReadLoader.current.invalidate();
|
|
2640
|
+
modalReadViewRef.current = void 0;
|
|
2641
|
+
importCandidatesGuard.current.invalidate();
|
|
2642
|
+
setWorktreeModalWorkspaceId(void 0);
|
|
2643
|
+
setModalReadError(void 0);
|
|
2644
|
+
setModalReadLoading(false);
|
|
2645
|
+
};
|
|
2155
2646
|
const openWorktreeCreator = (workspace) => {
|
|
2156
2647
|
const view = viewByWorkspace.get(workspace.workspaceId);
|
|
2157
|
-
|
|
2158
|
-
|
|
2648
|
+
modalReadLoader.current.invalidate();
|
|
2649
|
+
modalReadViewRef.current = void 0;
|
|
2650
|
+
importCandidatesGuard.current.invalidate();
|
|
2159
2651
|
setWorktreeModalWorkspaceId(workspace.workspaceId);
|
|
2160
|
-
|
|
2161
|
-
|
|
2652
|
+
setWorktreeModalMode("create");
|
|
2653
|
+
setImportCandidates({
|
|
2654
|
+
status: "idle",
|
|
2655
|
+
candidates: []
|
|
2656
|
+
});
|
|
2657
|
+
setSelectedImportPath(void 0);
|
|
2162
2658
|
setActionError(void 0);
|
|
2659
|
+
setModalReadError(void 0);
|
|
2660
|
+
setModalReadLoading(false);
|
|
2661
|
+
if (view === void 0) {
|
|
2662
|
+
setSelectedBranch("");
|
|
2663
|
+
setNewBranch("");
|
|
2664
|
+
loadModalWorktreeView(workspace.workspaceId);
|
|
2665
|
+
return;
|
|
2666
|
+
}
|
|
2667
|
+
setSelectedBranch(selectDefaultBaseBranch(view.branches));
|
|
2668
|
+
setNewBranch(createDefaultWorktreeName([...view.branches.map((branch) => branch.name), ...view.worktrees.map((worktree) => worktree.branch)]));
|
|
2669
|
+
};
|
|
2670
|
+
const changeWorktreeModalMode = (mode) => {
|
|
2671
|
+
setWorktreeModalMode(mode);
|
|
2672
|
+
if (mode === "import" && worktreeModalWorkspaceId !== void 0 && importCandidates.status === "idle") loadImportCandidates(worktreeModalWorkspaceId);
|
|
2673
|
+
};
|
|
2674
|
+
const continueWorktreeRegistration = async (registeredWorktree) => {
|
|
2675
|
+
closeWorktreeCreator(true);
|
|
2676
|
+
if (createSessionCallback === void 0) {
|
|
2677
|
+
await refresh({ preserveCurrent: true });
|
|
2678
|
+
setActionError({
|
|
2679
|
+
code: "WORKTREE_REGISTRATION_SESSION_UNAVAILABLE",
|
|
2680
|
+
message: "",
|
|
2681
|
+
retryable: true
|
|
2682
|
+
});
|
|
2683
|
+
return;
|
|
2684
|
+
}
|
|
2685
|
+
const sessionInput = {
|
|
2686
|
+
workspaceId: registeredWorktree.workspaceId,
|
|
2687
|
+
worktreeId: registeredWorktree.worktreeId,
|
|
2688
|
+
cwd: registeredWorktree.absolutePath
|
|
2689
|
+
};
|
|
2690
|
+
try {
|
|
2691
|
+
await createSessionCallback(sessionInput);
|
|
2692
|
+
await invalidateWorktreeContext?.(registeredWorktree.workspaceId);
|
|
2693
|
+
} catch (error) {
|
|
2694
|
+
if (error instanceof WorktreeSessionBindingError && error.retryable) setPendingSessionBinding({
|
|
2695
|
+
...sessionInput,
|
|
2696
|
+
sessionId: error.sessionId
|
|
2697
|
+
});
|
|
2698
|
+
throw error;
|
|
2699
|
+
}
|
|
2700
|
+
await refresh({ preserveCurrent: true });
|
|
2163
2701
|
};
|
|
2164
2702
|
const submitWorktree = async () => {
|
|
2165
2703
|
const worktreeName = newBranch.trim();
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
newBranch: worktreeName
|
|
2171
|
-
};
|
|
2704
|
+
const selectedImportCandidate = importCandidates.candidates.find((candidate) => candidate.absolutePath === selectedImportPath);
|
|
2705
|
+
if (manager === void 0 || modalWorkspace === void 0) return;
|
|
2706
|
+
if (worktreeModalMode === "create" && (!modalCanCreate || selectedBranch.length === 0 || worktreeName.length === 0)) return;
|
|
2707
|
+
if (worktreeModalMode === "import" && selectedImportCandidate === void 0) return;
|
|
2172
2708
|
setActionPending(true);
|
|
2173
2709
|
setActionError(void 0);
|
|
2174
2710
|
setPendingSessionBinding(void 0);
|
|
2175
2711
|
try {
|
|
2176
|
-
const
|
|
2712
|
+
const registeredWorktree = worktreeModalMode === "create" ? await executeWorktreeAction(manager, {
|
|
2177
2713
|
type: "createWorktree",
|
|
2178
|
-
input
|
|
2714
|
+
input: {
|
|
2715
|
+
workspaceId: modalWorkspace.workspaceId,
|
|
2716
|
+
branch: selectedBranch,
|
|
2717
|
+
newBranch: worktreeName
|
|
2718
|
+
}
|
|
2719
|
+
}) : await executeWorktreeAction(manager, {
|
|
2720
|
+
type: "importWorktree",
|
|
2721
|
+
input: {
|
|
2722
|
+
workspaceId: modalWorkspace.workspaceId,
|
|
2723
|
+
absolutePath: selectedImportCandidate.absolutePath
|
|
2724
|
+
}
|
|
2179
2725
|
});
|
|
2180
|
-
if (
|
|
2726
|
+
if (registeredWorktree === void 0) throw {
|
|
2181
2727
|
code: "WORKTREE_RECORD_MISSING",
|
|
2182
2728
|
message: "",
|
|
2183
2729
|
retryable: true
|
|
2184
2730
|
};
|
|
2185
|
-
|
|
2186
|
-
if (createSessionCallback === void 0) {
|
|
2187
|
-
await refresh({ preserveCurrent: true });
|
|
2188
|
-
setActionError({
|
|
2189
|
-
code: "WORKTREE_CREATED_SESSION_UNAVAILABLE",
|
|
2190
|
-
message: "",
|
|
2191
|
-
retryable: true
|
|
2192
|
-
});
|
|
2193
|
-
return;
|
|
2194
|
-
}
|
|
2195
|
-
const sessionInput = {
|
|
2196
|
-
workspaceId: createdWorktree.workspaceId,
|
|
2197
|
-
worktreeId: createdWorktree.worktreeId,
|
|
2198
|
-
cwd: createdWorktree.absolutePath
|
|
2199
|
-
};
|
|
2200
|
-
try {
|
|
2201
|
-
await createSessionCallback(sessionInput);
|
|
2202
|
-
await invalidateWorktreeContext?.(createdWorktree.workspaceId);
|
|
2203
|
-
} catch (error) {
|
|
2204
|
-
if (error instanceof WorktreeSessionBindingError && error.retryable) setPendingSessionBinding({
|
|
2205
|
-
...sessionInput,
|
|
2206
|
-
sessionId: error.sessionId
|
|
2207
|
-
});
|
|
2208
|
-
throw error;
|
|
2209
|
-
}
|
|
2210
|
-
await refresh({ preserveCurrent: true });
|
|
2731
|
+
await continueWorktreeRegistration(registeredWorktree);
|
|
2211
2732
|
} catch (error) {
|
|
2212
2733
|
setActionError(toWorktreeViewError(error));
|
|
2213
2734
|
} finally {
|
|
@@ -2411,13 +2932,15 @@ window.__ModuleLoader__.load({
|
|
|
2411
2932
|
const view = viewByWorkspace.get(workspace.workspaceId);
|
|
2412
2933
|
const currentBranch = view?.branches.find((branch) => branch.isCurrent)?.name;
|
|
2413
2934
|
const mainLabel = currentBranch === void 0 ? t("worktree.main") : t("worktree.mainWithBranch", { branch: currentBranch });
|
|
2414
|
-
const expanded =
|
|
2935
|
+
const expanded = isWorkspaceExpanded(expandSnapshot, workspace.workspaceId) || isCurrentSessionReveal("workspace:" + workspace.workspaceId);
|
|
2415
2936
|
const workspaceMatchesQuery = includesText(workspace.title, query);
|
|
2416
2937
|
const allWorkspaceSessionIds = filterArchivedSessionIds(workspaceSessionIds(workspaces, workspace.workspaceId, sessions.ids), archivedSessionIds);
|
|
2417
2938
|
const bindings = view?.bindings ?? [];
|
|
2418
2939
|
const visibleMainSessionIds = filterVisibleSessionIds(unboundSessionIds(allWorkspaceSessionIds, [...new Set(bindings.map((binding) => binding.sessionId))]), sessions).filter((sessionId) => workspaceMatchesQuery || sessionMatchesQuery(sessionId, sessions, query));
|
|
2419
|
-
const mainExpanded =
|
|
2940
|
+
const mainExpanded = isMainExpanded(expandSnapshot, workspace.workspaceId) || isCurrentSessionReveal("main:" + workspace.workspaceId);
|
|
2420
2941
|
const mainGroupKey = `main:${workspace.workspaceId}`;
|
|
2942
|
+
const sessionIds = visibleMainSessionIds;
|
|
2943
|
+
const mainSessionGroupExpanded = expandedSessionGroups[mainGroupKey] === true || sessionIds.length > 5 && isCurrentSessionReveal("session-group:" + mainGroupKey);
|
|
2421
2944
|
const worktrees = view?.worktrees ?? [];
|
|
2422
2945
|
const sameWorkspaceWorktreeDrag = worktreeDrag?.workspaceId === workspace.workspaceId;
|
|
2423
2946
|
return (0, react_jsx_runtime.jsxs)("section", {
|
|
@@ -2496,17 +3019,15 @@ window.__ModuleLoader__.load({
|
|
|
2496
3019
|
mainExpanded && (0, react_jsx_runtime.jsx)(WorktreeSessionGroup, {
|
|
2497
3020
|
t,
|
|
2498
3021
|
groupKey: mainGroupKey,
|
|
2499
|
-
sessionIds
|
|
3022
|
+
sessionIds,
|
|
2500
3023
|
workspaceId: workspace.workspaceId,
|
|
2501
|
-
|
|
3024
|
+
currentSessionId,
|
|
3025
|
+
expanded: mainSessionGroupExpanded,
|
|
2502
3026
|
actionPending,
|
|
2503
3027
|
sessions,
|
|
2504
3028
|
dragState: sessionDrag,
|
|
2505
3029
|
onToggleExpanded: () => {
|
|
2506
|
-
|
|
2507
|
-
...current,
|
|
2508
|
-
[mainGroupKey]: current[mainGroupKey] !== true
|
|
2509
|
-
}));
|
|
3030
|
+
toggleSessionGroup(mainGroupKey);
|
|
2510
3031
|
},
|
|
2511
3032
|
onStartDrag: (groupKey, sessionId) => {
|
|
2512
3033
|
sessionDropCommitted.current = false;
|
|
@@ -2549,9 +3070,11 @@ window.__ModuleLoader__.load({
|
|
|
2549
3070
|
if (query.length > 0 && !worktreeMatchesQuery && !worktreeSessionIds.some((sessionId) => sessionMatchesQuery(sessionId, sessions, query))) return null;
|
|
2550
3071
|
const visibleWorktreeSessionIds = worktreeSessionIds.filter((sessionId) => worktreeMatchesQuery || sessionMatchesQuery(sessionId, sessions, query));
|
|
2551
3072
|
const worktreeGroupKey = `worktree:${record.worktreeId}`;
|
|
3073
|
+
const sessionIds = visibleWorktreeSessionIds;
|
|
3074
|
+
const sessionGroupExpanded = expandedSessionGroups[worktreeGroupKey] === true || sessionIds.length > 5 && isCurrentSessionReveal("session-group:" + worktreeGroupKey);
|
|
2552
3075
|
const state = record.status === "removed" ? "warning" : record.health === "repair" ? "error" : "done";
|
|
2553
3076
|
const stateLabel = record.status === "removed" ? t("worktree.detached") : record.health === "repair" ? t("worktree.repair") : t("worktree.ready");
|
|
2554
|
-
const worktreeExpanded =
|
|
3077
|
+
const worktreeExpanded = isWorktreeExpanded(expandSnapshot, record.worktreeId) || isCurrentSessionReveal("worktree:" + record.worktreeId);
|
|
2555
3078
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
2556
3079
|
className: worktree_css_default.worktreeGroup,
|
|
2557
3080
|
"data-worktree-id": record.worktreeId,
|
|
@@ -2622,17 +3145,15 @@ window.__ModuleLoader__.load({
|
|
|
2622
3145
|
}), worktreeExpanded && (0, react_jsx_runtime.jsx)(WorktreeSessionGroup, {
|
|
2623
3146
|
t,
|
|
2624
3147
|
groupKey: worktreeGroupKey,
|
|
2625
|
-
sessionIds
|
|
3148
|
+
sessionIds,
|
|
2626
3149
|
workspaceId: workspace.workspaceId,
|
|
2627
|
-
|
|
3150
|
+
currentSessionId,
|
|
3151
|
+
expanded: sessionGroupExpanded,
|
|
2628
3152
|
actionPending,
|
|
2629
3153
|
sessions,
|
|
2630
3154
|
dragState: sessionDrag,
|
|
2631
3155
|
onToggleExpanded: () => {
|
|
2632
|
-
|
|
2633
|
-
...current,
|
|
2634
|
-
[worktreeGroupKey]: current[worktreeGroupKey] !== true
|
|
2635
|
-
}));
|
|
3156
|
+
toggleSessionGroup(worktreeGroupKey);
|
|
2636
3157
|
},
|
|
2637
3158
|
onStartDrag: (groupKey, sessionId) => {
|
|
2638
3159
|
sessionDropCommitted.current = false;
|
|
@@ -2676,18 +3197,6 @@ window.__ModuleLoader__.load({
|
|
|
2676
3197
|
})
|
|
2677
3198
|
]
|
|
2678
3199
|
}),
|
|
2679
|
-
(0, react_jsx_runtime.jsx)("div", {
|
|
2680
|
-
className: worktree_css_default.railContent,
|
|
2681
|
-
children: (0, react_jsx_runtime.jsx)("button", {
|
|
2682
|
-
type: "button",
|
|
2683
|
-
className: worktree_css_default.railButton,
|
|
2684
|
-
"aria-label": t("mode.exit"),
|
|
2685
|
-
onClick: () => {
|
|
2686
|
-
actions.setViewMode("workspace-session");
|
|
2687
|
-
},
|
|
2688
|
-
children: "WT"
|
|
2689
|
-
})
|
|
2690
|
-
}),
|
|
2691
3200
|
(0, react_jsx_runtime.jsx)(WorktreeSessionRenameDialog, {
|
|
2692
3201
|
t,
|
|
2693
3202
|
target: sessionRenameTarget,
|
|
@@ -2727,14 +3236,28 @@ window.__ModuleLoader__.load({
|
|
|
2727
3236
|
t,
|
|
2728
3237
|
workspace: modalWorkspace,
|
|
2729
3238
|
view: modalView,
|
|
3239
|
+
readError: modalReadError,
|
|
2730
3240
|
setupStatus: modalSetupStatus,
|
|
2731
3241
|
canCreate: modalCanCreate,
|
|
3242
|
+
mode: worktreeModalMode,
|
|
3243
|
+
importCandidates,
|
|
3244
|
+
selectedImportPath,
|
|
2732
3245
|
selectedBranch,
|
|
2733
3246
|
newBranch,
|
|
2734
3247
|
actionPending,
|
|
2735
|
-
onClose:
|
|
2736
|
-
|
|
3248
|
+
onClose: closeWorktreeCreator,
|
|
3249
|
+
onRetry: () => {
|
|
3250
|
+
if (worktreeModalWorkspaceId === void 0) return;
|
|
3251
|
+
modalReadViewRef.current = void 0;
|
|
3252
|
+
setSelectedBranch("");
|
|
3253
|
+
setNewBranch("");
|
|
3254
|
+
loadModalWorktreeView(worktreeModalWorkspaceId);
|
|
2737
3255
|
},
|
|
3256
|
+
onModeChange: changeWorktreeModalMode,
|
|
3257
|
+
onRetryImportCandidates: () => {
|
|
3258
|
+
if (worktreeModalWorkspaceId !== void 0) loadImportCandidates(worktreeModalWorkspaceId);
|
|
3259
|
+
},
|
|
3260
|
+
onSelectedImportPathChange: setSelectedImportPath,
|
|
2738
3261
|
onSelectedBranchChange: setSelectedBranch,
|
|
2739
3262
|
onNewBranchChange: setNewBranch,
|
|
2740
3263
|
onSubmit: submitWorktree
|
|
@@ -2848,6 +3371,28 @@ window.__ModuleLoader__.load({
|
|
|
2848
3371
|
let scheduleTicket = 0;
|
|
2849
3372
|
let scheduledCompletion;
|
|
2850
3373
|
let latestRefresh = Promise.resolve();
|
|
3374
|
+
const viewCache = /* @__PURE__ */ new Map();
|
|
3375
|
+
let lastObservedIdentity;
|
|
3376
|
+
const sameIdentity = (left, right) => left?.sessionId === right.sessionId && left?.workspaceId === right.workspaceId;
|
|
3377
|
+
const workspaceTitleFor = (workspaceId) => input.workspaces.getSnapshot().items.find((candidate) => candidate.workspaceId === workspaceId)?.title;
|
|
3378
|
+
const valueFrom = (identity, data) => resolveWorktreeSessionContext({
|
|
3379
|
+
currentSessionId: identity.sessionId,
|
|
3380
|
+
currentWorkspaceId: identity.workspaceId,
|
|
3381
|
+
workspaces: input.workspaces.getSnapshot().items,
|
|
3382
|
+
branches: data.branches,
|
|
3383
|
+
worktrees: data.worktrees,
|
|
3384
|
+
bindings: data.bindings
|
|
3385
|
+
});
|
|
3386
|
+
const syncWorkspaceTitle = (identity) => {
|
|
3387
|
+
const current = store.getSnapshot();
|
|
3388
|
+
if (current.sessionId !== identity.sessionId || current.workspaceId !== identity.workspaceId || identity.workspaceId === void 0) return;
|
|
3389
|
+
const workspaceTitle = workspaceTitleFor(identity.workspaceId);
|
|
3390
|
+
if (current.workspaceTitle === workspaceTitle) return;
|
|
3391
|
+
store.set({
|
|
3392
|
+
...current,
|
|
3393
|
+
workspaceTitle
|
|
3394
|
+
});
|
|
3395
|
+
};
|
|
2851
3396
|
const setPending = (identity) => {
|
|
2852
3397
|
if (identity.workspaceId === void 0) {
|
|
2853
3398
|
store.set({
|
|
@@ -2863,12 +3408,22 @@ window.__ModuleLoader__.load({
|
|
|
2863
3408
|
});
|
|
2864
3409
|
return;
|
|
2865
3410
|
}
|
|
2866
|
-
const
|
|
3411
|
+
const cachedView = viewCache.get(identity.workspaceId);
|
|
3412
|
+
if (cachedView !== void 0) {
|
|
3413
|
+
store.set({
|
|
3414
|
+
status: "ready",
|
|
3415
|
+
...identity.sessionId === void 0 ? {} : { sessionId: identity.sessionId },
|
|
3416
|
+
workspaceId: identity.workspaceId,
|
|
3417
|
+
workspaceTitle: workspaceTitleFor(identity.workspaceId),
|
|
3418
|
+
value: valueFrom(identity, cachedView)
|
|
3419
|
+
});
|
|
3420
|
+
return;
|
|
3421
|
+
}
|
|
2867
3422
|
store.set({
|
|
2868
3423
|
status: "loading",
|
|
2869
3424
|
...identity.sessionId === void 0 ? {} : { sessionId: identity.sessionId },
|
|
2870
3425
|
workspaceId: identity.workspaceId,
|
|
2871
|
-
workspaceTitle:
|
|
3426
|
+
workspaceTitle: workspaceTitleFor(identity.workspaceId),
|
|
2872
3427
|
value: notReady()
|
|
2873
3428
|
});
|
|
2874
3429
|
};
|
|
@@ -2881,6 +3436,7 @@ window.__ModuleLoader__.load({
|
|
|
2881
3436
|
if (disposed) return;
|
|
2882
3437
|
const requestGeneration = ++generation;
|
|
2883
3438
|
const identity = identityFrom(input.sessions, input.workspaces);
|
|
3439
|
+
lastObservedIdentity = identity;
|
|
2884
3440
|
setPending(identity);
|
|
2885
3441
|
if (identity.workspaceId === void 0) return;
|
|
2886
3442
|
const request = {
|
|
@@ -2902,19 +3458,13 @@ window.__ModuleLoader__.load({
|
|
|
2902
3458
|
});
|
|
2903
3459
|
return;
|
|
2904
3460
|
}
|
|
3461
|
+
if (data.readiness.status === "ready") viewCache.set(request.workspaceId, data);
|
|
2905
3462
|
store.set({
|
|
2906
3463
|
status: "ready",
|
|
2907
3464
|
...request.sessionId === void 0 ? {} : { sessionId: request.sessionId },
|
|
2908
3465
|
workspaceId: request.workspaceId,
|
|
2909
3466
|
workspaceTitle: workspace?.title,
|
|
2910
|
-
value:
|
|
2911
|
-
currentSessionId: request.sessionId,
|
|
2912
|
-
currentWorkspaceId: request.workspaceId,
|
|
2913
|
-
workspaces: input.workspaces.getSnapshot().items,
|
|
2914
|
-
branches: data.branches,
|
|
2915
|
-
worktrees: data.worktrees,
|
|
2916
|
-
bindings: data.bindings
|
|
2917
|
-
})
|
|
3467
|
+
value: valueFrom(request, data)
|
|
2918
3468
|
});
|
|
2919
3469
|
} catch (error) {
|
|
2920
3470
|
if (!matchesCurrent(request, requestGeneration)) return;
|
|
@@ -2937,15 +3487,22 @@ window.__ModuleLoader__.load({
|
|
|
2937
3487
|
};
|
|
2938
3488
|
const refresh = () => {
|
|
2939
3489
|
cancelScheduledRefresh();
|
|
3490
|
+
lastObservedIdentity = identityFrom(input.sessions, input.workspaces);
|
|
2940
3491
|
const completion = runRefresh();
|
|
2941
3492
|
latestRefresh = completion;
|
|
2942
3493
|
return completion;
|
|
2943
3494
|
};
|
|
2944
3495
|
const scheduleRefresh = () => {
|
|
2945
3496
|
if (disposed) return;
|
|
3497
|
+
const identity = identityFrom(input.sessions, input.workspaces);
|
|
3498
|
+
if (sameIdentity(lastObservedIdentity, identity)) {
|
|
3499
|
+
syncWorkspaceTitle(identity);
|
|
3500
|
+
return;
|
|
3501
|
+
}
|
|
3502
|
+
lastObservedIdentity = identity;
|
|
2946
3503
|
generation += 1;
|
|
3504
|
+
setPending(identity);
|
|
2947
3505
|
if (scheduled) return;
|
|
2948
|
-
setPending(identityFrom(input.sessions, input.workspaces));
|
|
2949
3506
|
scheduled = true;
|
|
2950
3507
|
const ticket = ++scheduleTicket;
|
|
2951
3508
|
const completion = scheduledRefresh();
|
|
@@ -2992,6 +3549,7 @@ window.__ModuleLoader__.load({
|
|
|
2992
3549
|
cancelScheduledRefresh();
|
|
2993
3550
|
unsubscribeSessions();
|
|
2994
3551
|
unsubscribeWorkspaces();
|
|
3552
|
+
viewCache.clear();
|
|
2995
3553
|
store.set({
|
|
2996
3554
|
status: "idle",
|
|
2997
3555
|
value: notReady()
|
|
@@ -3123,6 +3681,7 @@ window.__ModuleLoader__.load({
|
|
|
3123
3681
|
ctx.effect(() => () => contextProjection.dispose(), "clutch-dsh-worktree: Session context cleanup");
|
|
3124
3682
|
contextProjection.refresh();
|
|
3125
3683
|
const viewStore = createWorktreeViewStore();
|
|
3684
|
+
const expandState = createWorktreeExpandStateStore(_deepseek_ai_dsh_client_runtime_client.createSnapshotStore);
|
|
3126
3685
|
const ensureSessionWorkspace = (workspaceId, sessionId) => {
|
|
3127
3686
|
virtualWorkspaceMembership.ensure({
|
|
3128
3687
|
workspaceId,
|
|
@@ -3164,6 +3723,7 @@ window.__ModuleLoader__.load({
|
|
|
3164
3723
|
locale: WORKTREE_NS,
|
|
3165
3724
|
inject: () => ({
|
|
3166
3725
|
available: true,
|
|
3726
|
+
expandState,
|
|
3167
3727
|
hooks: { worktreeContext: contextProjection.store },
|
|
3168
3728
|
manager,
|
|
3169
3729
|
createWorkspace: async () => {
|