@cerbur/clutch-dsh-worktree 0.1.2 → 0.1.4
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 +247 -92
- package/README.zh.md +297 -0
- package/lib/client/WorktreeContext.d.ts +15 -0
- package/lib/client/WorktreeContext.d.ts.map +1 -0
- package/lib/client/WorktreeContext.js +19 -0
- package/lib/client/WorktreeContext.js.map +1 -0
- package/lib/client/WorktreeHeroContext.d.ts +10 -0
- package/lib/client/WorktreeHeroContext.d.ts.map +1 -0
- package/lib/client/WorktreeHeroContext.js +128 -0
- package/lib/client/WorktreeHeroContext.js.map +1 -0
- package/lib/client/WorktreeOverlay.d.ts +6 -0
- package/lib/client/WorktreeOverlay.d.ts.map +1 -0
- package/lib/client/WorktreeOverlay.js +8 -0
- package/lib/client/WorktreeOverlay.js.map +1 -0
- package/lib/client/WorktreeSurface.d.ts +3 -29
- package/lib/client/WorktreeSurface.d.ts.map +1 -1
- package/lib/client/WorktreeSurface.js +170 -314
- package/lib/client/WorktreeSurface.js.map +1 -1
- package/lib/client/entry.d.ts +1 -1
- package/lib/client/entry.d.ts.map +1 -1
- package/lib/client/entry.js +41 -14
- package/lib/client/entry.js.map +1 -1
- package/lib/client/locales.d.ts +30 -0
- package/lib/client/locales.d.ts.map +1 -1
- package/lib/client/locales.js +32 -2
- package/lib/client/locales.js.map +1 -1
- package/lib/client/session-view.d.ts +21 -0
- package/lib/client/session-view.d.ts.map +1 -0
- package/lib/client/session-view.js +26 -0
- package/lib/client/session-view.js.map +1 -0
- package/lib/client/sidebar-overlay-geometry.d.ts +1 -0
- package/lib/client/sidebar-overlay-geometry.d.ts.map +1 -1
- package/lib/client/sidebar-overlay-geometry.js +28 -17
- package/lib/client/sidebar-overlay-geometry.js.map +1 -1
- package/lib/client/virtual-workspace-membership.d.ts.map +1 -1
- package/lib/client/virtual-workspace-membership.js +17 -6
- package/lib/client/virtual-workspace-membership.js.map +1 -1
- package/lib/client/worktree-connection.d.ts +1 -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 +45 -0
- package/lib/client/worktree-context-store.d.ts.map +1 -0
- package/lib/client/worktree-context-store.js +199 -0
- package/lib/client/worktree-context-store.js.map +1 -0
- package/lib/client/worktree-context.d.ts +32 -0
- package/lib/client/worktree-context.d.ts.map +1 -0
- package/lib/client/worktree-context.js +51 -0
- package/lib/client/worktree-context.js.map +1 -0
- package/lib/client/worktree-error-copy.d.ts.map +1 -1
- package/lib/client/worktree-error-copy.js +14 -0
- package/lib/client/worktree-error-copy.js.map +1 -1
- package/lib/client/worktree-session.d.ts +83 -0
- package/lib/client/worktree-session.d.ts.map +1 -0
- package/lib/client/worktree-session.js +185 -0
- package/lib/client/worktree-session.js.map +1 -0
- package/lib/client/worktree-surface-dialogs.d.ts +7 -0
- package/lib/client/worktree-surface-dialogs.d.ts.map +1 -0
- package/lib/client/worktree-surface-dialogs.js +86 -0
- package/lib/client/worktree-surface-dialogs.js.map +1 -0
- package/lib/client/worktree-surface-rows.d.ts +9 -0
- package/lib/client/worktree-surface-rows.d.ts.map +1 -0
- package/lib/client/worktree-surface-rows.js +223 -0
- package/lib/client/worktree-surface-rows.js.map +1 -0
- package/lib/client/worktree-surface-selectors.d.ts +9 -0
- package/lib/client/worktree-surface-selectors.d.ts.map +1 -0
- package/lib/client/worktree-surface-selectors.js +28 -0
- package/lib/client/worktree-surface-selectors.js.map +1 -0
- package/lib/client/worktree-surface-types.d.ts +233 -0
- package/lib/client/worktree-surface-types.d.ts.map +1 -0
- package/lib/client/worktree-surface-types.js +2 -0
- package/lib/client/worktree-surface-types.js.map +1 -0
- package/lib/client/worktree-view-actions.d.ts +34 -0
- package/lib/client/worktree-view-actions.d.ts.map +1 -0
- package/lib/client/worktree-view-actions.js +69 -0
- package/lib/client/worktree-view-actions.js.map +1 -0
- package/lib/client/worktree-view-errors.d.ts +20 -0
- package/lib/client/worktree-view-errors.d.ts.map +1 -0
- package/lib/client/worktree-view-errors.js +65 -0
- package/lib/client/worktree-view-errors.js.map +1 -0
- package/lib/client/worktree-view-read.d.ts +48 -0
- package/lib/client/worktree-view-read.d.ts.map +1 -0
- package/lib/client/worktree-view-read.js +134 -0
- package/lib/client/worktree-view-read.js.map +1 -0
- package/lib/client/worktree-view.d.ts +4 -63
- package/lib/client/worktree-view.d.ts.map +1 -1
- package/lib/client/worktree-view.js +4 -125
- package/lib/client/worktree-view.js.map +1 -1
- package/lib/client.js +1313 -363
- package/lib/client.js.map +1 -1
- package/lib/contract/index.contract.js +2 -0
- package/lib/contract/index.contract.js.map +1 -1
- package/lib/contract/index.d.ts +17 -2
- package/lib/contract/index.d.ts.map +1 -1
- package/lib/contract/index.js +2 -0
- package/lib/contract/index.js.map +1 -1
- package/lib/host/remote.d.ts.map +1 -1
- package/lib/host/remote.js +1 -0
- package/lib/host/remote.js.map +1 -1
- package/lib/host/service.d.ts +6 -1
- package/lib/host/service.d.ts.map +1 -1
- package/lib/host/service.js +6 -0
- package/lib/host/service.js.map +1 -1
- package/lib/manage/manager-context.d.ts +11 -0
- package/lib/manage/manager-context.d.ts.map +1 -0
- package/lib/manage/manager-context.js +2 -0
- package/lib/manage/manager-context.js.map +1 -0
- package/lib/manage/manager-sessions.d.ts +18 -0
- package/lib/manage/manager-sessions.d.ts.map +1 -0
- package/lib/manage/manager-sessions.js +91 -0
- package/lib/manage/manager-sessions.js.map +1 -0
- package/lib/manage/manager-support.d.ts +18 -0
- package/lib/manage/manager-support.d.ts.map +1 -0
- package/lib/manage/manager-support.js +174 -0
- package/lib/manage/manager-support.js.map +1 -0
- package/lib/manage/manager-worktrees.d.ts +27 -0
- package/lib/manage/manager-worktrees.d.ts.map +1 -0
- package/lib/manage/manager-worktrees.js +259 -0
- package/lib/manage/manager-worktrees.js.map +1 -0
- package/lib/manage/manager.d.ts +25 -62
- package/lib/manage/manager.d.ts.map +1 -1
- package/lib/manage/manager.js +32 -554
- package/lib/manage/manager.js.map +1 -1
- package/lib/provider/sidecar-persistence.d.ts +18 -0
- package/lib/provider/sidecar-persistence.d.ts.map +1 -0
- package/lib/provider/sidecar-persistence.js +162 -0
- package/lib/provider/sidecar-persistence.js.map +1 -0
- package/lib/provider/sidecar-schema.d.ts +6 -0
- package/lib/provider/sidecar-schema.d.ts.map +1 -0
- package/lib/provider/sidecar-schema.js +123 -0
- package/lib/provider/sidecar-schema.js.map +1 -0
- package/lib/provider/sidecar.d.ts +12 -68
- package/lib/provider/sidecar.d.ts.map +1 -1
- package/lib/provider/sidecar.js +61 -346
- package/lib/provider/sidecar.js.map +1 -1
- package/lib/provider/types.d.ts +2 -1
- package/lib/provider/types.d.ts.map +1 -1
- package/lib/provider/types.js.map +1 -1
- package/lib/typert.host.js +60 -18
- package/lib/typert.remote-client.d.ts +3 -1
- package/lib/typert.remote-client.d.ts.map +1 -1
- package/lib/typert.remote-client.js +60 -18
- package/package.json +6 -2
package/lib/client.js
CHANGED
|
@@ -4,10 +4,10 @@ window.__ModuleLoader__.load({
|
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
var exports = module.exports;
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
|
|
7
8
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
9
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
9
10
|
let react = require("react");
|
|
10
|
-
let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
|
|
11
11
|
//#region lib/client/locales.js
|
|
12
12
|
const WORKTREE_NS = "worktree";
|
|
13
13
|
const zh = {
|
|
@@ -15,6 +15,8 @@ window.__ModuleLoader__.load({
|
|
|
15
15
|
"mode.exit": "退出 Worktree 模式",
|
|
16
16
|
"mode.label": "Worktree",
|
|
17
17
|
"mode.navigation": "Worktree 导航",
|
|
18
|
+
"context.main": "当前分支:{name}",
|
|
19
|
+
"context.worktree": "Worktree:{name}",
|
|
18
20
|
"workspace.rename": "重命名",
|
|
19
21
|
"workspace.delete": "删除",
|
|
20
22
|
"workspace.expand": "展开 {name}",
|
|
@@ -30,7 +32,8 @@ window.__ModuleLoader__.load({
|
|
|
30
32
|
"workspace.deleteTitle": "删除工作区",
|
|
31
33
|
"workspace.deleteDescription": "删除“{name}”?这只会移除 DSH 工作区注册。目录、会话和 Git Worktree 会保留。",
|
|
32
34
|
"worktree.title": "Worktree",
|
|
33
|
-
"worktree.main": "
|
|
35
|
+
"worktree.main": "本地",
|
|
36
|
+
"worktree.mainWithBranch": "本地({branch})",
|
|
34
37
|
"worktree.detached": "已分离 Worktree",
|
|
35
38
|
"worktree.repair": "Worktree 需要修复",
|
|
36
39
|
"worktree.ready": "活动 Worktree 已就绪",
|
|
@@ -46,9 +49,14 @@ window.__ModuleLoader__.load({
|
|
|
46
49
|
"worktree.baseBranch": "Worktree 基线分支",
|
|
47
50
|
"worktree.noLocalBranch": "没有本地分支",
|
|
48
51
|
"worktree.noBranches": "此工作区中没有找到本地分支。",
|
|
52
|
+
"worktree.setup.noRepository": "此 Workspace 不是 Git 仓库。请在 Workspace 目录执行以下命令:",
|
|
53
|
+
"worktree.setup.noInitialCommit": "此 Git 仓库还没有首次 commit。请先执行以下命令:",
|
|
54
|
+
"worktree.setup.noLocalBranch": "此 Git 仓库没有本地分支。请先创建一个本地分支:",
|
|
55
|
+
"worktree.setup.commands": "可复制的命令",
|
|
49
56
|
"worktree.name": "Worktree 名称",
|
|
50
57
|
"worktree.create": "创建 Worktree",
|
|
51
58
|
"session.options": "会话选项:{name}",
|
|
59
|
+
"session.new": "新会话",
|
|
52
60
|
"session.rename": "重命名会话",
|
|
53
61
|
"session.fork": "Fork 会话",
|
|
54
62
|
"session.archive": "归档会话",
|
|
@@ -73,6 +81,7 @@ window.__ModuleLoader__.load({
|
|
|
73
81
|
"error.invalidResult": "Worktree endpoint {endpoint} 返回了无效结果,请重试请求。",
|
|
74
82
|
"error.workspaceOrderingUnavailable": "工作区排序不可用,请重新连接后重试。",
|
|
75
83
|
"error.sessionOrderingUnavailable": "会话排序不可用,请重新连接后重试。",
|
|
84
|
+
"error.worktreeOrderingUnavailable": "Worktree 排序不可用,请重新连接后重试。",
|
|
76
85
|
"error.worktreeCreatedSessionUnavailable": "Worktree 已创建,但 Session 创建不可用,请重新连接后重试。",
|
|
77
86
|
"error.sessionCreationUnavailable": "Session 创建不可用,请重新连接后重试。",
|
|
78
87
|
"error.worktreeRecordMissing": "Worktree 创建未返回 Worktree 记录,请重试请求。",
|
|
@@ -80,6 +89,12 @@ window.__ModuleLoader__.load({
|
|
|
80
89
|
"error.workspaceDeleteUnavailable": "工作区删除不可用,请重新连接后重试。",
|
|
81
90
|
"error.sessionRenameUnavailable": "会话重命名不可用,请重新连接后重试。",
|
|
82
91
|
"error.sessionBindingFailed": "Session {sessionId} 已创建,但 Worktree 绑定失败:{reason}",
|
|
92
|
+
"error.sessionAlreadyBound": "Session 已绑定到其他 Worktree,未创建新的 Session。",
|
|
93
|
+
"error.sessionListNotReady": "Session 列表尚未就绪,请重试。",
|
|
94
|
+
"error.sessionFactsIncomplete": "Session 信息尚未完整,请重试。",
|
|
95
|
+
"error.worktreeSessionRepairRequired": "当前 Worktree 的 Session 绑定需要修复,请重试。",
|
|
96
|
+
"error.worktreeSessionUnavailable": "当前 Worktree 不可用,请重试。",
|
|
97
|
+
"error.sessionArchived": "该 Session 已归档,无法重试绑定。",
|
|
83
98
|
"branch.current": "(当前)",
|
|
84
99
|
"branch.checkedOut": "(已检出)"
|
|
85
100
|
};
|
|
@@ -88,6 +103,8 @@ window.__ModuleLoader__.load({
|
|
|
88
103
|
"mode.exit": "Exit Worktree mode",
|
|
89
104
|
"mode.label": "Worktree",
|
|
90
105
|
"mode.navigation": "Worktree navigation",
|
|
106
|
+
"context.main": "Current branch: {name}",
|
|
107
|
+
"context.worktree": "Worktree: {name}",
|
|
91
108
|
"workspace.rename": "Rename",
|
|
92
109
|
"workspace.delete": "Delete",
|
|
93
110
|
"workspace.expand": "Expand {name}",
|
|
@@ -103,7 +120,8 @@ window.__ModuleLoader__.load({
|
|
|
103
120
|
"workspace.deleteTitle": "Delete Workspace",
|
|
104
121
|
"workspace.deleteDescription": "Delete {name}? This removes only the DSH Workspace registration. The directory, Sessions, and Git Worktrees will be retained.",
|
|
105
122
|
"worktree.title": "Worktrees",
|
|
106
|
-
"worktree.main": "
|
|
123
|
+
"worktree.main": "Local",
|
|
124
|
+
"worktree.mainWithBranch": "Local ({branch})",
|
|
107
125
|
"worktree.detached": "Detached Worktree",
|
|
108
126
|
"worktree.repair": "Worktree needs repair",
|
|
109
127
|
"worktree.ready": "Active Worktree ready",
|
|
@@ -119,9 +137,14 @@ window.__ModuleLoader__.load({
|
|
|
119
137
|
"worktree.baseBranch": "Worktree base branch",
|
|
120
138
|
"worktree.noLocalBranch": "No local branch",
|
|
121
139
|
"worktree.noBranches": "No local branches found in this Workspace.",
|
|
140
|
+
"worktree.setup.noRepository": "This Workspace is not a Git repository. Run these commands in the Workspace directory:",
|
|
141
|
+
"worktree.setup.noInitialCommit": "This Git repository has no initial commit. Run these commands first:",
|
|
142
|
+
"worktree.setup.noLocalBranch": "This Git repository has no local branch. Create one first:",
|
|
143
|
+
"worktree.setup.commands": "Copyable commands",
|
|
122
144
|
"worktree.name": "Worktree name",
|
|
123
145
|
"worktree.create": "Create Worktree",
|
|
124
146
|
"session.options": "Session options for {name}",
|
|
147
|
+
"session.new": "New Session",
|
|
125
148
|
"session.rename": "Rename session",
|
|
126
149
|
"session.fork": "Fork session",
|
|
127
150
|
"session.archive": "Archive session",
|
|
@@ -146,6 +169,7 @@ window.__ModuleLoader__.load({
|
|
|
146
169
|
"error.invalidResult": "Worktree endpoint {endpoint} returned an invalid result; retry the request.",
|
|
147
170
|
"error.workspaceOrderingUnavailable": "Workspace ordering is unavailable; retry after reconnecting.",
|
|
148
171
|
"error.sessionOrderingUnavailable": "Session ordering is unavailable; retry after reconnecting.",
|
|
172
|
+
"error.worktreeOrderingUnavailable": "Worktree ordering is unavailable; retry after reconnecting.",
|
|
149
173
|
"error.worktreeCreatedSessionUnavailable": "Worktree created, but Session creation is unavailable; retry after reconnecting.",
|
|
150
174
|
"error.sessionCreationUnavailable": "Session creation is unavailable; retry after reconnecting.",
|
|
151
175
|
"error.worktreeRecordMissing": "Worktree creation returned no Worktree record; retry the request.",
|
|
@@ -153,6 +177,12 @@ window.__ModuleLoader__.load({
|
|
|
153
177
|
"error.workspaceDeleteUnavailable": "Workspace delete is unavailable; retry after reconnecting.",
|
|
154
178
|
"error.sessionRenameUnavailable": "Session rename is unavailable; retry after reconnecting.",
|
|
155
179
|
"error.sessionBindingFailed": "Session {sessionId} was created, but Worktree binding failed: {reason}",
|
|
180
|
+
"error.sessionAlreadyBound": "The Session is already bound to another Worktree; no new Session was created.",
|
|
181
|
+
"error.sessionListNotReady": "The Session list is not ready yet; retry the request.",
|
|
182
|
+
"error.sessionFactsIncomplete": "Session facts are incomplete; retry the request.",
|
|
183
|
+
"error.worktreeSessionRepairRequired": "The current Worktree Session binding needs repair; retry the request.",
|
|
184
|
+
"error.worktreeSessionUnavailable": "The current Worktree is unavailable; retry the request.",
|
|
185
|
+
"error.sessionArchived": "This Session is archived and cannot be retried for binding.",
|
|
156
186
|
"branch.current": " (current)",
|
|
157
187
|
"branch.checkedOut": " (checked out)"
|
|
158
188
|
};
|
|
@@ -169,6 +199,7 @@ window.__ModuleLoader__.load({
|
|
|
169
199
|
listBranches: "worktreeManager/listBranches",
|
|
170
200
|
createWorktree: "worktreeManager/createWorktree",
|
|
171
201
|
removeWorktree: "worktreeManager/removeWorktree",
|
|
202
|
+
insertWorktreeBefore: "worktreeManager/insertWorktreeBefore",
|
|
172
203
|
listBindings: "worktreeManager/listBindings",
|
|
173
204
|
bindSession: "worktreeManager/bindSession"
|
|
174
205
|
});
|
|
@@ -275,6 +306,9 @@ window.__ModuleLoader__.load({
|
|
|
275
306
|
async removeWorktree(input) {
|
|
276
307
|
await invoke("removeWorktree", input);
|
|
277
308
|
},
|
|
309
|
+
async insertWorktreeBefore(input) {
|
|
310
|
+
return invoke("insertWorktreeBefore", input);
|
|
311
|
+
},
|
|
278
312
|
listBindings: (input) => invoke("listBindings", input),
|
|
279
313
|
bindSession: (input) => invoke("bindSession", input),
|
|
280
314
|
dispose() {
|
|
@@ -286,8 +320,53 @@ window.__ModuleLoader__.load({
|
|
|
286
320
|
};
|
|
287
321
|
}
|
|
288
322
|
//#endregion
|
|
323
|
+
//#region \0clutch-dsh-worktree-css:/Users/yuancheng/Documents/Code/clutch-dsh/packages/clutch-dsh-worktree/src/client/worktree-context.css.mjs
|
|
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-heroContext {\n position: absolute;\n z-index: 1;\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: none;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n";
|
|
325
|
+
const styleId$1 = "@cerbur/clutch-dsh-worktree/worktree-context.css";
|
|
326
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@cerbur/clutch-dsh-worktree/worktree-context.css\"]") === null) {
|
|
327
|
+
const tag = document.createElement("style");
|
|
328
|
+
tag.dataset.plugin = "@cerbur/clutch-dsh-worktree";
|
|
329
|
+
tag.dataset.pluginCss = styleId$1;
|
|
330
|
+
tag.textContent = css$1;
|
|
331
|
+
document.head.appendChild(tag);
|
|
332
|
+
}
|
|
333
|
+
var worktree_context_css_default = {
|
|
334
|
+
"headerContext": "-cerbur-clutch-dsh-worktree-headerContext",
|
|
335
|
+
"contextIcon": "-cerbur-clutch-dsh-worktree-contextIcon",
|
|
336
|
+
"contextLabel": "-cerbur-clutch-dsh-worktree-contextLabel",
|
|
337
|
+
"heroContext": "-cerbur-clutch-dsh-worktree-heroContext"
|
|
338
|
+
};
|
|
339
|
+
//#endregion
|
|
340
|
+
//#region lib/client/WorktreeContext.js
|
|
341
|
+
function WorktreeContextLabel({ value, t }) {
|
|
342
|
+
if (value.kind === "none") return null;
|
|
343
|
+
const ariaLabel = value.kind === "main" ? t("context.main", { name: value.label }) : t("context.worktree", { name: value.label });
|
|
344
|
+
return (0, react_jsx_runtime.jsxs)("span", {
|
|
345
|
+
className: worktree_context_css_default.headerContext,
|
|
346
|
+
title: value.label,
|
|
347
|
+
"aria-label": ariaLabel,
|
|
348
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBranchOutline16, {
|
|
349
|
+
size: 14,
|
|
350
|
+
className: worktree_context_css_default.contextIcon,
|
|
351
|
+
"aria-hidden": "true"
|
|
352
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
353
|
+
className: worktree_context_css_default.contextLabel,
|
|
354
|
+
children: value.label
|
|
355
|
+
})]
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
/** Render the current branch or active Worktree branch beside the Session title. */
|
|
359
|
+
function WorktreeHeaderContext({ sessionId, useWorktreeContext, t }) {
|
|
360
|
+
const state = useWorktreeContext((snapshot) => snapshot);
|
|
361
|
+
if (state.sessionId !== sessionId) return null;
|
|
362
|
+
return (0, react_jsx_runtime.jsx)(WorktreeContextLabel, {
|
|
363
|
+
value: state.value,
|
|
364
|
+
t
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
//#endregion
|
|
289
368
|
//#region \0clutch-dsh-worktree-css:/Users/yuancheng/Documents/Code/clutch-dsh/packages/clutch-dsh-worktree/src/client/worktree.css.mjs
|
|
290
|
-
const css = ".-cerbur-clutch-dsh-worktree-action {\n display: flex;\n align-items: center;\n justify-content: flex-start;\n gap: 8px;\n width: calc(100% + 4px);\n height: 42px;\n margin: 4px -2px;\n box-sizing: border-box;\n border: 0;\n border-radius: 12px;\n padding: 0 10px 0 8px;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n font: inherit;\n font-size: 14px;\n line-height: 22px;\n text-align: left;\n overflow: hidden;\n}\n\n.-cerbur-clutch-dsh-worktree-action:hover,\n.-cerbur-clutch-dsh-worktree-action[data-active='true'] {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-action[data-collapsed='true'] {\n width: 36px;\n height: 36px;\n margin: 8px 0 10px;\n justify-content: center;\n gap: 0;\n padding: 0;\n border-radius: 50%;\n}\n\n.-cerbur-clutch-dsh-worktree-actionLabel {\n overflow: hidden;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-surface {\n position: absolute;\n top: 0;\n left: 0;\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n min-width: 56px;\n overflow: hidden;\n border-right: 1px solid var(--dsw-alias-border-l1);\n background: var(--dsw-specific-sidebar-fill);\n color: var(--dsw-alias-label-primary);\n pointer-events: auto;\n transition: width var(--ds-transition-duration-slow) var(--ds-ease-in-out);\n}\n\n.-cerbur-clutch-dsh-worktree-wideContent {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n}\n\n.-cerbur-clutch-dsh-worktree-surface[data-collapsed='true'] .-cerbur-clutch-dsh-worktree-wideContent {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-railContent {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-surface[data-collapsed='true'] .-cerbur-clutch-dsh-worktree-railContent {\n display: flex;\n flex: 1;\n align-items: flex-start;\n justify-content: center;\n padding-top: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-railButton,\n.-cerbur-clutch-dsh-worktree-closeButton {\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: inherit;\n cursor: pointer;\n font: inherit;\n}\n\n.-cerbur-clutch-dsh-worktree-railButton {\n width: 36px;\n height: 36px;\n color: var(--dsw-alias-label-secondary);\n font-size: 11px;\n font-weight: 600;\n}\n\n.-cerbur-clutch-dsh-worktree-railButton:hover,\n.-cerbur-clutch-dsh-worktree-closeButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-header {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: none;\n min-height: 44px;\n padding: 6px 10px;\n box-sizing: border-box;\n border-bottom: 1px solid var(--dsw-alias-border-l1);\n}\n\n.-cerbur-clutch-dsh-worktree-title {\n min-width: 0;\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 14px;\n font-weight: 600;\n}\n\n.-cerbur-clutch-dsh-worktree-closeButton {\n flex: none;\n width: 28px;\n height: 28px;\n font-size: 18px;\n line-height: 1;\n}\n\n.-cerbur-clutch-dsh-worktree-modeButton[data-active='true'] {\n color: var(--dsw-alias-label-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-workspacePicker {\n display: block;\n width: calc(100% - 20px);\n margin: 6px 10px 8px;\n padding: 6px 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 7px;\n background: var(--dsw-alias-button-elevated-fill);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceLabel {\n display: block;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-content {\n min-height: 0;\n flex: 1;\n overflow: auto;\n padding: 0 10px 12px;\n}\n\n.-cerbur-clutch-dsh-worktree-content:focus-visible {\n outline: 2px solid var(--dsw-alias-border-l3);\n outline-offset: -2px;\n}\n\n.-cerbur-clutch-dsh-worktree-error {\n margin: 12px 0 0;\n padding: 8px;\n border: 1px solid var(--dsw-alias-state-error-primary);\n border-radius: 7px;\n}\n\n.-cerbur-clutch-dsh-worktree-retryButton,\n.-cerbur-clutch-dsh-worktree-actionButton {\n border: 0;\n border-radius: 6px;\n background: var(--dsw-alias-button-elevated-fill);\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n font: inherit;\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-retryButton,\n.-cerbur-clutch-dsh-worktree-actionButton {\n width: 100%;\n padding: 6px 8px;\n}\n\n.-cerbur-clutch-dsh-worktree-recoveryActions {\n display: grid;\n gap: 6px;\n margin-top: 6px;\n}\n\n.-cerbur-clutch-dsh-worktree-retryButton:disabled,\n.-cerbur-clutch-dsh-worktree-actionButton:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.-cerbur-clutch-dsh-worktree-actions {\n display: grid;\n gap: 6px;\n margin-top: 10px;\n padding: 8px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 7px;\n}\n\n.-cerbur-clutch-dsh-worktree-actionLabel {\n display: grid;\n gap: 3px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-actionSelect {\n min-width: 0;\n padding: 5px 6px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: var(--dsw-alias-button-elevated-fill);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-section {\n margin: 12px 0 0;\n}\n\n.-cerbur-clutch-dsh-worktree-sectionTitle {\n margin: 0 2px 4px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n}\n\n.-cerbur-clutch-dsh-worktree-empty,\n.-cerbur-clutch-dsh-worktree-message {\n margin: 0;\n padding: 8px 4px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 12px;\n line-height: 18px;\n}\n\n.-cerbur-clutch-dsh-worktree-message[data-error='true'] {\n color: var(--dsw-alias-state-error-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-worktree,\n.-cerbur-clutch-dsh-worktree-session {\n display: flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n box-sizing: border-box;\n border: 0;\n border-radius: 7px;\n padding: 6px 8px;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 12px;\n text-align: left;\n}\n\n.-cerbur-clutch-dsh-worktree-worktree {\n cursor: default;\n}\n\n.-cerbur-clutch-dsh-worktree-session {\n cursor: pointer;\n}\n\n.-cerbur-clutch-dsh-worktree-worktree:hover,\n.-cerbur-clutch-dsh-worktree-session:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeLabel,\n.-cerbur-clutch-dsh-worktree-sessionLabel {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.-cerbur-clutch-dsh-worktree-status {\n flex: none;\n margin-left: auto;\n padding-left: 8px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-searchRow {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 10px 6px;\n}\n\n.-cerbur-clutch-dsh-worktree-searchIcon {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n color: var(--dsw-alias-label-secondary);\n}\n\n.-cerbur-clutch-dsh-worktree-searchInput {\n min-width: 0;\n box-sizing: border-box;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 7px;\n background: var(--dsw-alias-button-elevated-fill);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n outline: none;\n}\n\n.-cerbur-clutch-dsh-worktree-searchInput {\n width: 100%;\n padding: 6px 8px;\n font-size: 13px;\n line-height: 18px;\n}\n\n.-cerbur-clutch-dsh-worktree-searchInput:focus,\n.-cerbur-clutch-dsh-worktree-actionSelect:focus {\n border-color: #3b82f6;\n}\n\n.-cerbur-clutch-dsh-worktree-iconButton {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: 0;\n border-radius: 7px;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n font: inherit;\n font-size: 20px;\n line-height: 1;\n}\n\n.-cerbur-clutch-dsh-worktree-iconButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceList {\n min-width: 0;\n min-height: 0;\n display: grid;\n gap: 4px;\n overflow-x: hidden;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceGroup {\n min-width: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow,\n.-cerbur-clutch-dsh-worktree-worktreeRow {\n position: relative;\n display: flex;\n align-items: center;\n min-width: 0;\n min-height: 36px;\n box-sizing: border-box;\n border-radius: 8px;\n padding: 3px 4px;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow:hover,\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow .-cerbur-clutch-dsh-worktree-workspaceDisclosure {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow:hover .-cerbur-clutch-dsh-worktree-workspaceDisclosure,\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-workspaceDisclosure {\n display: inline-flex;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow:hover .-cerbur-clutch-dsh-worktree-workspaceIcon,\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-workspaceIcon {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-worktreeDisclosure {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover .-cerbur-clutch-dsh-worktree-worktreeDisclosure,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-worktreeDisclosure {\n display: inline-flex;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover .-cerbur-clutch-dsh-worktree-worktreeIcon,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-worktreeIcon {\n display: none;\n}\n\n.-cerbur-clutch-dsh-worktree-disclosureButton {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 28px;\n border: 0;\n border-radius: 6px;\n padding: 0;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n font: inherit;\n font-size: 17px;\n line-height: 1;\n}\n\n.-cerbur-clutch-dsh-worktree-disclosureButton > svg {\n display: block;\n}\n\n.-cerbur-clutch-dsh-worktree-disclosureButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceIcon,\n.-cerbur-clutch-dsh-worktree-worktreeIcon {\n flex: none;\n width: 24px;\n color: var(--dsw-alias-label-secondary);\n font-size: 20px;\n line-height: 1;\n text-align: center;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeState {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 12px;\n margin-right: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceIcon {\n color: var(--dsw-alias-brand-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceTitle,\n.-cerbur-clutch-dsh-worktree-worktreeLabel {\n min-width: 0;\n overflow: hidden;\n flex: 1;\n padding: 0 6px;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 14px;\n font-weight: 400;\n line-height: 20px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-main-group='true'] .-cerbur-clutch-dsh-worktree-worktreeLabel {\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeHoverTitle {\n color: var(--dsw-static-neutral-bluish-00);\n font-size: 14px;\n line-height: 20px;\n overflow-wrap: anywhere;\n}\n\n.-cerbur-clutch-dsh-worktree-treeActionSlot,\n.-cerbur-clutch-dsh-worktree-workspaceActions {\n position: relative;\n display: inline-flex;\n flex: 0 0 64px;\n align-items: center;\n justify-content: flex-end;\n width: 64px;\n height: 28px;\n margin-left: auto;\n}\n\n.-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-menuAction {\n position: absolute;\n top: 0;\n right: 32px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeActionSlot > .-cerbur-clutch-dsh-worktree-iconButton:last-child {\n position: absolute;\n top: 0;\n right: 0;\n}\n\n.-cerbur-clutch-dsh-worktree-menuAction {\n display: inline-flex;\n width: 28px;\n height: 28px;\n visibility: hidden;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow:hover .-cerbur-clutch-dsh-worktree-menuAction,\n.-cerbur-clutch-dsh-worktree-workspaceRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-menuAction,\n.-cerbur-clutch-dsh-worktree-worktreeRow:hover .-cerbur-clutch-dsh-worktree-menuAction,\n.-cerbur-clutch-dsh-worktree-worktreeRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-menuAction {\n visibility: visible;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow.-cerbur-clutch-dsh-worktree-dropBefore::before,\n.-cerbur-clutch-dsh-worktree-workspaceRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n position: absolute;\n right: 4px;\n left: 4px;\n height: 2px;\n border-radius: 2px;\n background: var(--dsw-alias-brand-primary);\n content: '';\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow.-cerbur-clutch-dsh-worktree-dropBefore::before {\n top: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-workspaceRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n bottom: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeChildren {\n margin-left: 24px;\n padding: 2px 0 5px 12px;\n border-left: 1px solid var(--dsw-alias-border-l1);\n}\n\n.-cerbur-clutch-dsh-worktree-groupLabel {\n padding: 6px 8px 3px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n}\n\n.-cerbur-clutch-dsh-worktree-groupHeader {\n display: flex;\n align-items: center;\n min-height: 34px;\n padding-right: 4px;\n}\n\n.-cerbur-clutch-dsh-worktree-groupHeader .-cerbur-clutch-dsh-worktree-groupLabel {\n flex: 1;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeGroup {\n margin-top: 2px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow {\n min-height: 34px;\n}\n\n.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-worktreeIcon,\n.-cerbur-clutch-dsh-worktree-worktreeRow .-cerbur-clutch-dsh-worktree-disclosureButton {\n width: 22px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow {\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n min-height: 31px;\n box-sizing: border-box;\n border-radius: 7px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow:hover,\n.-cerbur-clutch-dsh-worktree-treeSessionRow[data-menu-open='true'] {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow.-cerbur-clutch-dsh-worktree-dropBefore::before,\n.-cerbur-clutch-dsh-worktree-treeSessionRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n position: absolute;\n right: 4px;\n left: 4px;\n height: 2px;\n border-radius: 2px;\n background: var(--dsw-alias-brand-primary);\n content: '';\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow.-cerbur-clutch-dsh-worktree-dropBefore::before {\n top: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow.-cerbur-clutch-dsh-worktree-dropAfter::after {\n bottom: -1px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionContent {\n display: flex;\n align-items: center;\n flex: 1;\n width: 0;\n min-width: 0;\n min-height: 31px;\n box-sizing: border-box;\n border: 0;\n border-radius: 7px;\n padding: 4px 4px;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n font: inherit;\n font-size: 14px;\n font-weight: 400;\n line-height: 20px;\n text-align: left;\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionContent:hover {\n background: transparent;\n}\n\n.-cerbur-clutch-dsh-worktree-rowActions {\n display: none;\n flex: none;\n align-items: center;\n gap: 4px;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionOverflowButton {\n display: block;\n width: calc(100% - 24px);\n margin: 2px 0 4px 24px;\n padding: 4px 8px;\n border: 0;\n border-radius: 6px;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n font: inherit;\n font-size: 12px;\n font-weight: 400;\n line-height: 20px;\n text-align: left;\n}\n\n.-cerbur-clutch-dsh-worktree-sessionOverflowButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n.-cerbur-clutch-dsh-worktree-treeSessionRow:hover .-cerbur-clutch-dsh-worktree-rowActions,\n.-cerbur-clutch-dsh-worktree-treeSessionRow[data-menu-open='true'] .-cerbur-clutch-dsh-worktree-rowActions {\n display: inline-flex;\n}\n\n.-cerbur-clutch-dsh-worktree-renameInput {\n width: 100%;\n}\n\n.-cerbur-clutch-dsh-worktree-renameError {\n margin: 8px 0 0;\n color: var(--dsw-alias-state-error-primary);\n font-size: 13px;\n line-height: 20px;\n}\n\n.-cerbur-clutch-dsh-worktree-treeGuide {\n flex: none;\n width: 20px;\n color: var(--dsw-alias-label-tertiary);\n text-align: center;\n}\n\n.-cerbur-clutch-dsh-worktree-emptyNested {\n margin: 0;\n padding: 4px 8px 5px 28px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n\n.-cerbur-clutch-dsh-worktree-modalField {\n display: grid;\n gap: 5px;\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n}\n";
|
|
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";
|
|
291
370
|
const styleId = "@cerbur/clutch-dsh-worktree/worktree.css";
|
|
292
371
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@cerbur/clutch-dsh-worktree/worktree.css\"]") === null) {
|
|
293
372
|
const tag = document.createElement("style");
|
|
@@ -320,6 +399,8 @@ window.__ModuleLoader__.load({
|
|
|
320
399
|
"sectionTitle": "-cerbur-clutch-dsh-worktree-sectionTitle",
|
|
321
400
|
"empty": "-cerbur-clutch-dsh-worktree-empty",
|
|
322
401
|
"message": "-cerbur-clutch-dsh-worktree-message",
|
|
402
|
+
"gitReadiness": "-cerbur-clutch-dsh-worktree-gitReadiness",
|
|
403
|
+
"commandBlock": "-cerbur-clutch-dsh-worktree-commandBlock",
|
|
323
404
|
"worktree": "-cerbur-clutch-dsh-worktree-worktree",
|
|
324
405
|
"session": "-cerbur-clutch-dsh-worktree-session",
|
|
325
406
|
"worktreeLabel": "-cerbur-clutch-dsh-worktree-worktreeLabel",
|
|
@@ -385,6 +466,104 @@ window.__ModuleLoader__.load({
|
|
|
385
466
|
});
|
|
386
467
|
}
|
|
387
468
|
//#endregion
|
|
469
|
+
//#region lib/client/WorktreeHeroContext.js
|
|
470
|
+
function labelFor(state) {
|
|
471
|
+
if (state.status !== "ready" || state.workspaceTitle === void 0 || state.value.kind === "none") return;
|
|
472
|
+
return `${state.workspaceTitle} (${state.value.label})`;
|
|
473
|
+
}
|
|
474
|
+
function elementWithClassSuffix(root, suffix) {
|
|
475
|
+
const candidates = root.querySelectorAll("[class]");
|
|
476
|
+
for (const candidate of candidates) if ([...candidate.classList].some((token) => token === suffix || token.endsWith(`_${suffix}`))) return candidate;
|
|
477
|
+
return null;
|
|
478
|
+
}
|
|
479
|
+
function headlineElement(root) {
|
|
480
|
+
return elementWithClassSuffix(root, "previewBadge") ?? elementWithClassSuffix(root, "headlineText") ?? elementWithClassSuffix(root, "headline");
|
|
481
|
+
}
|
|
482
|
+
function positionedAncestor(element) {
|
|
483
|
+
if (element.offsetParent instanceof HTMLElement) return element.offsetParent;
|
|
484
|
+
for (let ancestor = element.parentElement; ancestor !== null; ancestor = ancestor.parentElement) if (getComputedStyle(ancestor).position !== "static") return ancestor;
|
|
485
|
+
return null;
|
|
486
|
+
}
|
|
487
|
+
function measurePlacement(element) {
|
|
488
|
+
const hero = document.querySelector("[data-phase=\"hero\"]");
|
|
489
|
+
const overlay = positionedAncestor(element);
|
|
490
|
+
const headline = hero === null ? null : headlineElement(hero);
|
|
491
|
+
if (hero === null || headline === null || overlay === null) return null;
|
|
492
|
+
const anchor = headline.getBoundingClientRect();
|
|
493
|
+
const frame = overlay.getBoundingClientRect();
|
|
494
|
+
const width = element.getBoundingClientRect().width;
|
|
495
|
+
const afterHeadlineLeft = anchor.right - frame.left + 8;
|
|
496
|
+
const fitsAfterHeadline = afterHeadlineLeft + width <= frame.width - 8;
|
|
497
|
+
return {
|
|
498
|
+
left: fitsAfterHeadline ? afterHeadlineLeft : Math.max(8, frame.width - width - 8),
|
|
499
|
+
top: fitsAfterHeadline ? Math.max(8, anchor.top - frame.top + (anchor.height - 22) / 2) : Math.max(8, anchor.bottom - frame.top + 8)
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
function contextAriaLabel(state, t) {
|
|
503
|
+
if (state.value.kind === "main") return t("context.main", { name: state.value.label });
|
|
504
|
+
if (state.value.kind === "worktree") return t("context.worktree", { name: state.value.label });
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Browser-local Hero suffix. It intentionally uses the frame overlay because
|
|
508
|
+
* rc.8 exposes no additive slot beside the native Hero headline.
|
|
509
|
+
*/
|
|
510
|
+
function WorktreeHeroContext({ useWorktreeContext, t }) {
|
|
511
|
+
const state = useWorktreeContext((snapshot) => snapshot);
|
|
512
|
+
const label = labelFor(state);
|
|
513
|
+
const [placement, setPlacement] = (0, react.useState)(null);
|
|
514
|
+
const measure = (0, react.useCallback)((element) => {
|
|
515
|
+
if (element === null) {
|
|
516
|
+
setPlacement(null);
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
setPlacement(measurePlacement(element));
|
|
520
|
+
}, []);
|
|
521
|
+
(0, react.useLayoutEffect)(() => {
|
|
522
|
+
if (typeof document === "undefined" || typeof window === "undefined") return void 0;
|
|
523
|
+
const element = document.querySelector("[data-worktree-hero-context]");
|
|
524
|
+
if (element === null) return void 0;
|
|
525
|
+
let frameRequest;
|
|
526
|
+
const schedule = () => {
|
|
527
|
+
if (frameRequest !== void 0) window.cancelAnimationFrame(frameRequest);
|
|
528
|
+
frameRequest = window.requestAnimationFrame(() => {
|
|
529
|
+
frameRequest = void 0;
|
|
530
|
+
measure(element);
|
|
531
|
+
});
|
|
532
|
+
};
|
|
533
|
+
const mutationObserver = typeof MutationObserver === "undefined" ? void 0 : new MutationObserver(schedule);
|
|
534
|
+
mutationObserver?.observe(document.body, {
|
|
535
|
+
subtree: true,
|
|
536
|
+
childList: true,
|
|
537
|
+
attributes: true,
|
|
538
|
+
attributeFilter: ["class", "data-phase"]
|
|
539
|
+
});
|
|
540
|
+
const resizeObserver = typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver(schedule);
|
|
541
|
+
resizeObserver?.observe(positionedAncestor(element) ?? element);
|
|
542
|
+
window.addEventListener("resize", schedule);
|
|
543
|
+
schedule();
|
|
544
|
+
return () => {
|
|
545
|
+
if (frameRequest !== void 0) window.cancelAnimationFrame(frameRequest);
|
|
546
|
+
mutationObserver?.disconnect();
|
|
547
|
+
resizeObserver?.disconnect();
|
|
548
|
+
window.removeEventListener("resize", schedule);
|
|
549
|
+
};
|
|
550
|
+
}, [label, measure]);
|
|
551
|
+
const ariaLabel = contextAriaLabel(state, t);
|
|
552
|
+
if (label === void 0) return null;
|
|
553
|
+
return (0, react_jsx_runtime.jsx)("span", {
|
|
554
|
+
ref: measure,
|
|
555
|
+
className: worktree_context_css_default.heroContext,
|
|
556
|
+
"data-worktree-hero-context": true,
|
|
557
|
+
"aria-label": ariaLabel,
|
|
558
|
+
title: label,
|
|
559
|
+
style: placement === null ? { visibility: "hidden" } : {
|
|
560
|
+
left: `${placement.left}px`,
|
|
561
|
+
top: `${placement.top}px`
|
|
562
|
+
},
|
|
563
|
+
children: label
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
//#endregion
|
|
388
567
|
//#region lib/client/navigation.js
|
|
389
568
|
/** Open an existing Session through DSH without touching the peer view mode. */
|
|
390
569
|
function openWorktreeSession(opener, sessionId) {
|
|
@@ -419,6 +598,13 @@ window.__ModuleLoader__.load({
|
|
|
419
598
|
bottom: rect.bottom
|
|
420
599
|
};
|
|
421
600
|
}
|
|
601
|
+
function syncObservedElement(observer, previous, next) {
|
|
602
|
+
const nextElement = next ?? void 0;
|
|
603
|
+
if (previous === nextElement) return previous;
|
|
604
|
+
if (previous !== void 0) observer?.unobserve(previous);
|
|
605
|
+
if (nextElement !== void 0) observer?.observe(nextElement);
|
|
606
|
+
return nextElement;
|
|
607
|
+
}
|
|
422
608
|
function resolveNativeSidebarRoot(sidebar) {
|
|
423
609
|
const directChild = sidebar.firstElementChild;
|
|
424
610
|
if (directChild === null) return void 0;
|
|
@@ -460,34 +646,37 @@ window.__ModuleLoader__.load({
|
|
|
460
646
|
setBounds(EMPTY_BOUNDS);
|
|
461
647
|
return;
|
|
462
648
|
}
|
|
649
|
+
const overlayElement = overlay;
|
|
650
|
+
const sidebarElement = sidebar;
|
|
651
|
+
const nativeRootElement = nativeRoot;
|
|
463
652
|
let frameHandle;
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
const
|
|
653
|
+
let observedNewSession;
|
|
654
|
+
let observedFooter;
|
|
655
|
+
function update() {
|
|
656
|
+
const newSession = findNewSessionAnchor(nativeRootElement);
|
|
657
|
+
const footer = nativeRootElement.lastElementChild;
|
|
658
|
+
observedNewSession = syncObservedElement(resizeObserver, observedNewSession, newSession);
|
|
659
|
+
observedFooter = syncObservedElement(resizeObserver, observedFooter, footer);
|
|
660
|
+
const nextWidth = sidebarElement.getBoundingClientRect().width;
|
|
468
661
|
if (nextWidth > 0) setWidth(nextWidth);
|
|
469
|
-
setBounds(computeOverlayBounds(asRect(
|
|
470
|
-
}
|
|
471
|
-
|
|
662
|
+
setBounds(computeOverlayBounds(asRect(overlayElement), newSession === void 0 ? void 0 : asRect(newSession), footer === null ? void 0 : asRect(footer)));
|
|
663
|
+
}
|
|
664
|
+
function scheduleUpdate() {
|
|
472
665
|
if (frameHandle !== void 0) return;
|
|
473
666
|
frameHandle = requestAnimationFrame(() => {
|
|
474
667
|
frameHandle = void 0;
|
|
475
668
|
update();
|
|
476
669
|
});
|
|
477
|
-
}
|
|
478
|
-
update();
|
|
670
|
+
}
|
|
479
671
|
const resizeObserver = typeof ResizeObserver === "function" ? new ResizeObserver(scheduleUpdate) : void 0;
|
|
480
672
|
for (const element of [
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
673
|
+
overlayElement,
|
|
674
|
+
sidebarElement,
|
|
675
|
+
nativeRootElement
|
|
484
676
|
]) resizeObserver?.observe(element);
|
|
485
|
-
|
|
486
|
-
const footer = nativeRoot.lastElementChild;
|
|
487
|
-
if (newSession !== void 0) resizeObserver?.observe(newSession);
|
|
488
|
-
if (footer !== null) resizeObserver?.observe(footer);
|
|
677
|
+
update();
|
|
489
678
|
const mutationObserver = typeof MutationObserver === "function" ? new MutationObserver(scheduleUpdate) : void 0;
|
|
490
|
-
mutationObserver?.observe(
|
|
679
|
+
mutationObserver?.observe(nativeRootElement, {
|
|
491
680
|
childList: true,
|
|
492
681
|
subtree: true
|
|
493
682
|
});
|
|
@@ -576,6 +765,7 @@ window.__ModuleLoader__.load({
|
|
|
576
765
|
case "WORKTREE_RPC_INVALID_RESULT": return t("error.invalidResult", { endpoint: detail(error, "endpoint") });
|
|
577
766
|
case "WORKSPACE_ORDER_UNAVAILABLE": return t("error.workspaceOrderingUnavailable");
|
|
578
767
|
case "SESSION_ORDER_UNAVAILABLE": return t("error.sessionOrderingUnavailable");
|
|
768
|
+
case "WORKTREE_ORDER_UNAVAILABLE": return t("error.worktreeOrderingUnavailable");
|
|
579
769
|
case "SESSION_CREATE_UNAVAILABLE": return t("error.sessionCreationUnavailable");
|
|
580
770
|
case "WORKTREE_CREATED_SESSION_UNAVAILABLE": return t("error.worktreeCreatedSessionUnavailable");
|
|
581
771
|
case "WORKTREE_RECORD_MISSING": return t("error.worktreeRecordMissing");
|
|
@@ -586,35 +776,98 @@ window.__ModuleLoader__.load({
|
|
|
586
776
|
sessionId: detail(error, "sessionId"),
|
|
587
777
|
reason: reason(error, t)
|
|
588
778
|
});
|
|
779
|
+
case "SESSION_ALREADY_BOUND": return t("error.sessionAlreadyBound");
|
|
780
|
+
case "SESSION_LIST_NOT_READY": return t("error.sessionListNotReady");
|
|
781
|
+
case "SESSION_FACTS_INCOMPLETE": return t("error.sessionFactsIncomplete");
|
|
782
|
+
case "WORKTREE_SESSION_REPAIR_REQUIRED": return t("error.worktreeSessionRepairRequired");
|
|
783
|
+
case "WORKTREE_SESSION_UNAVAILABLE": return t("error.worktreeSessionUnavailable");
|
|
784
|
+
case "SESSION_ARCHIVED": return t("error.sessionArchived");
|
|
589
785
|
default: return error.message.length > 0 ? error.message : t("error.worktreeDataUnavailable");
|
|
590
786
|
}
|
|
591
787
|
}
|
|
592
788
|
//#endregion
|
|
593
|
-
//#region lib/client/
|
|
789
|
+
//#region lib/client/session-view.js
|
|
790
|
+
/** Read the native blank flag without inferring blankness from title or id. */
|
|
791
|
+
function isBlankSession(sessionId, sessions) {
|
|
792
|
+
return sessions.byId[sessionId]?.blank === true;
|
|
793
|
+
}
|
|
794
|
+
/** Native tree visibility: ordinary rows plus the currently selected blank row. */
|
|
795
|
+
function isVisibleSession(sessionId, sessions) {
|
|
796
|
+
return !isBlankSession(sessionId, sessions) || sessions.current === sessionId;
|
|
797
|
+
}
|
|
798
|
+
/** Filter a group without mutating its source order. */
|
|
799
|
+
function filterVisibleSessionIds(sessionIds, sessions) {
|
|
800
|
+
return sessionIds.filter((sessionId) => isVisibleSession(sessionId, sessions));
|
|
801
|
+
}
|
|
802
|
+
/** Resolve a row title while keeping the blank label outside the DSH summary. */
|
|
803
|
+
function sessionDisplayLabel(sessionId, sessions, blankLabel) {
|
|
804
|
+
const summary = sessions.byId[sessionId];
|
|
805
|
+
return summary?.blank === true ? blankLabel : summary?.displayTitle ?? sessionId;
|
|
806
|
+
}
|
|
807
|
+
/** Match only durable Session titles or the final diagnostic id fallback. */
|
|
808
|
+
function sessionMatchesQuery(sessionId, sessions, normalizedQuery) {
|
|
809
|
+
const summary = sessions.byId[sessionId];
|
|
810
|
+
if (summary?.blank === true) return false;
|
|
811
|
+
return (summary?.displayTitle ?? sessionId).toLocaleLowerCase().includes(normalizedQuery);
|
|
812
|
+
}
|
|
813
|
+
//#endregion
|
|
814
|
+
//#region lib/client/worktree-view-errors.js
|
|
594
815
|
/** A DSH Session exists even when the external Worktree binding needs repair. */
|
|
595
816
|
var WorktreeSessionBindingError = class extends Error {
|
|
596
|
-
code
|
|
597
|
-
retryable
|
|
817
|
+
code;
|
|
818
|
+
retryable;
|
|
819
|
+
details;
|
|
598
820
|
sessionId;
|
|
599
821
|
cause;
|
|
600
822
|
constructor(sessionId, cause) {
|
|
601
|
-
const
|
|
823
|
+
const candidate = typeof cause === "object" && cause !== null ? cause : void 0;
|
|
824
|
+
const reason = cause instanceof Error ? cause.message : typeof candidate?.message === "string" ? candidate.message : String(cause);
|
|
602
825
|
super(reason);
|
|
603
826
|
this.name = "WorktreeSessionBindingError";
|
|
827
|
+
const conflict = candidate?.code === "SESSION_ALREADY_BOUND";
|
|
828
|
+
this.code = conflict ? "SESSION_ALREADY_BOUND" : "SESSION_BINDING_FAILED";
|
|
829
|
+
this.retryable = conflict ? false : candidate?.retryable !== false;
|
|
830
|
+
this.details = typeof candidate?.details === "object" && candidate.details !== null && !Array.isArray(candidate.details) ? candidate.details : {};
|
|
604
831
|
this.sessionId = sessionId;
|
|
605
832
|
this.cause = cause;
|
|
606
833
|
}
|
|
607
834
|
};
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
return
|
|
835
|
+
function recordDetails(value) {
|
|
836
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
837
|
+
const details = value.details;
|
|
838
|
+
if (typeof details !== "object" || details === null || Array.isArray(details)) return void 0;
|
|
839
|
+
return details;
|
|
613
840
|
}
|
|
614
|
-
/**
|
|
615
|
-
function
|
|
616
|
-
|
|
841
|
+
/** Convert any adapter/Gateway failure into renderable, retry-aware UI data. */
|
|
842
|
+
function toWorktreeViewError(error) {
|
|
843
|
+
if (typeof error === "object" && error !== null) {
|
|
844
|
+
const candidate = error;
|
|
845
|
+
const details = error instanceof WorktreeSessionBindingError ? {
|
|
846
|
+
...recordDetails(error) ?? {},
|
|
847
|
+
sessionId: error.sessionId
|
|
848
|
+
} : recordDetails(error);
|
|
849
|
+
return {
|
|
850
|
+
code: typeof candidate.code === "string" ? candidate.code : "WORKTREE_VIEW_FAILED",
|
|
851
|
+
message: typeof candidate.message === "string" ? candidate.message : "",
|
|
852
|
+
retryable: candidate.retryable !== false,
|
|
853
|
+
...details === void 0 ? {} : { details }
|
|
854
|
+
};
|
|
855
|
+
}
|
|
856
|
+
return {
|
|
857
|
+
code: "WORKTREE_VIEW_FAILED",
|
|
858
|
+
message: "",
|
|
859
|
+
retryable: true
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
/** Keep ordering mutation/refresh failures reachable from the surface Retry control. */
|
|
863
|
+
function toRetryableWorktreeOrderError(error) {
|
|
864
|
+
return {
|
|
865
|
+
...toWorktreeViewError(error),
|
|
866
|
+
retryable: true
|
|
867
|
+
};
|
|
617
868
|
}
|
|
869
|
+
//#endregion
|
|
870
|
+
//#region lib/client/worktree-view-actions.js
|
|
618
871
|
function browserRandomUuid() {
|
|
619
872
|
const randomUUID = globalThis.crypto?.randomUUID;
|
|
620
873
|
if (typeof randomUUID === "function") return randomUUID.call(globalThis.crypto);
|
|
@@ -631,29 +884,16 @@ window.__ModuleLoader__.load({
|
|
|
631
884
|
}
|
|
632
885
|
throw new Error("Unable to generate an available default Worktree name.");
|
|
633
886
|
}
|
|
634
|
-
/**
|
|
635
|
-
function
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
]);
|
|
645
|
-
return {
|
|
646
|
-
worktrees,
|
|
647
|
-
branches,
|
|
648
|
-
bindings
|
|
649
|
-
};
|
|
650
|
-
}
|
|
651
|
-
/** Load one independent projection per DSH Workspace for the flat sidebar hierarchy. */
|
|
652
|
-
async function loadWorktreeViews(manager, workspaceIds) {
|
|
653
|
-
return Promise.all(workspaceIds.map(async (workspaceId) => ({
|
|
654
|
-
workspaceId,
|
|
655
|
-
...await loadWorktreeView(manager, workspaceId)
|
|
656
|
-
})));
|
|
887
|
+
/** Resolve a row-half drop target to native-style optional before-anchor semantics. */
|
|
888
|
+
function resolveWorktreeMove(worktreeIds, sourceWorktreeId, targetWorktreeId, half) {
|
|
889
|
+
const sourceIndex = worktreeIds.indexOf(sourceWorktreeId);
|
|
890
|
+
const targetIndex = worktreeIds.indexOf(targetWorktreeId);
|
|
891
|
+
if (sourceIndex === -1 || targetIndex === -1) return void 0;
|
|
892
|
+
const beforeWorktreeId = half === "before" ? targetWorktreeId : worktreeIds[targetIndex + 1];
|
|
893
|
+
if (beforeWorktreeId === sourceWorktreeId) return void 0;
|
|
894
|
+
const anchorIndex = beforeWorktreeId === void 0 ? worktreeIds.length : worktreeIds.indexOf(beforeWorktreeId);
|
|
895
|
+
if (anchorIndex === sourceIndex || anchorIndex === sourceIndex + 1) return void 0;
|
|
896
|
+
return beforeWorktreeId === void 0 ? {} : { beforeWorktreeId };
|
|
657
897
|
}
|
|
658
898
|
/** Keep mutation routing in the browser Consumer while leaving wire details to the adapter. */
|
|
659
899
|
async function executeWorktreeAction(manager, action) {
|
|
@@ -682,60 +922,507 @@ window.__ModuleLoader__.load({
|
|
|
682
922
|
input.openSession(sessionId);
|
|
683
923
|
return sessionId;
|
|
684
924
|
}
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
return
|
|
925
|
+
//#endregion
|
|
926
|
+
//#region lib/client/worktree-view-read.js
|
|
927
|
+
/** Reuse the previous ID snapshot when DSH republishes equivalent Workspace items. */
|
|
928
|
+
function stableWorkspaceIds(previous, next) {
|
|
929
|
+
if (previous.length !== next.length) return next;
|
|
930
|
+
for (let index = 0; index < previous.length; index += 1) if (previous[index] !== next[index]) return next;
|
|
931
|
+
return previous;
|
|
690
932
|
}
|
|
691
|
-
/**
|
|
692
|
-
function
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
933
|
+
/** Keep only the most recently started Worktree surface refresh authoritative. */
|
|
934
|
+
function createWorktreeRefreshGuard() {
|
|
935
|
+
let latestGeneration = 0;
|
|
936
|
+
const begin = () => {
|
|
937
|
+
latestGeneration += 1;
|
|
938
|
+
return latestGeneration;
|
|
939
|
+
};
|
|
940
|
+
const isCurrent = (generation) => generation === latestGeneration;
|
|
941
|
+
const invalidate = () => {
|
|
942
|
+
latestGeneration += 1;
|
|
943
|
+
};
|
|
944
|
+
return {
|
|
945
|
+
begin,
|
|
946
|
+
isCurrent,
|
|
947
|
+
invalidate,
|
|
948
|
+
async run(load, onSuccess, onError) {
|
|
949
|
+
const generation = begin();
|
|
950
|
+
let value;
|
|
951
|
+
try {
|
|
952
|
+
value = await load();
|
|
953
|
+
} catch (error) {
|
|
954
|
+
if (!isCurrent(generation)) return;
|
|
955
|
+
onError(error);
|
|
956
|
+
return;
|
|
957
|
+
}
|
|
958
|
+
if (!isCurrent(generation)) return;
|
|
959
|
+
onSuccess(value);
|
|
960
|
+
}
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
/** Prefer the branch checked out by the DSH Workspace, then fall back to any local branch. */
|
|
964
|
+
function selectDefaultBaseBranch(branches) {
|
|
965
|
+
return branches.find((branch) => branch.isCurrent)?.name ?? branches[0]?.name ?? "";
|
|
966
|
+
}
|
|
967
|
+
/** Keep a valid user choice across branch-list refreshes, otherwise choose the current branch. */
|
|
968
|
+
function reconcileBaseBranchSelection(selectedBranch, branches) {
|
|
969
|
+
if (branches.some((branch) => branch.name === selectedBranch)) return selectedBranch;
|
|
970
|
+
return selectDefaultBaseBranch(branches);
|
|
971
|
+
}
|
|
972
|
+
/** Return copyable, read-only setup commands for a Git readiness state. */
|
|
973
|
+
function worktreeSetupCommands(status) {
|
|
974
|
+
switch (status) {
|
|
975
|
+
case "noRepository": return [
|
|
976
|
+
"git init",
|
|
977
|
+
"printf \"# README\\n\" > README.md",
|
|
978
|
+
"git add README.md",
|
|
979
|
+
"git commit -m \"Initial commit\""
|
|
980
|
+
];
|
|
981
|
+
case "noInitialCommit": return [
|
|
982
|
+
"printf \"# README\\n\" > README.md",
|
|
983
|
+
"git add README.md",
|
|
984
|
+
"git commit -m \"Initial commit\""
|
|
985
|
+
];
|
|
986
|
+
case "noLocalBranch": return ["git switch -c main"];
|
|
987
|
+
case "ready": return [];
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
function readinessFromBranchError(error) {
|
|
991
|
+
const viewError = toWorktreeViewError(error);
|
|
992
|
+
if (viewError.code === "WORKSPACE_NOT_GIT_REPOSITORY") return {
|
|
993
|
+
status: "noRepository",
|
|
994
|
+
error: viewError
|
|
995
|
+
};
|
|
996
|
+
if (viewError.code === "WORKTREE_REQUIRES_INITIAL_COMMIT") return {
|
|
997
|
+
status: "noInitialCommit",
|
|
998
|
+
error: viewError
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
1001
|
+
/** Read all three Worktree projections needed by the surface in one refresh. */
|
|
1002
|
+
async function loadWorktreeView(manager, workspaceId) {
|
|
1003
|
+
const [worktreesResult, branchesResult, bindingsResult] = await Promise.allSettled([
|
|
1004
|
+
manager.listWorktrees({ workspaceId }),
|
|
1005
|
+
manager.listBranches({ workspaceId }),
|
|
1006
|
+
manager.listBindings({ workspaceId })
|
|
1007
|
+
]);
|
|
1008
|
+
if (worktreesResult.status === "rejected") throw worktreesResult.reason;
|
|
1009
|
+
if (bindingsResult.status === "rejected") throw bindingsResult.reason;
|
|
1010
|
+
if (branchesResult.status === "rejected") {
|
|
1011
|
+
const readiness = readinessFromBranchError(branchesResult.reason);
|
|
1012
|
+
if (readiness !== void 0) return {
|
|
1013
|
+
worktrees: worktreesResult.value,
|
|
1014
|
+
branches: [],
|
|
1015
|
+
bindings: bindingsResult.value,
|
|
1016
|
+
readiness
|
|
704
1017
|
};
|
|
1018
|
+
throw branchesResult.reason;
|
|
705
1019
|
}
|
|
706
1020
|
return {
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
1021
|
+
worktrees: worktreesResult.value,
|
|
1022
|
+
branches: branchesResult.value,
|
|
1023
|
+
bindings: bindingsResult.value,
|
|
1024
|
+
readiness: branchesResult.value.length > 0 ? { status: "ready" } : { status: "noLocalBranch" }
|
|
710
1025
|
};
|
|
711
1026
|
}
|
|
1027
|
+
/** Load one independent projection per DSH Workspace for the flat sidebar hierarchy. */
|
|
1028
|
+
async function loadWorktreeViews(manager, workspaceIds, options = {}) {
|
|
1029
|
+
const views = await Promise.all(workspaceIds.map(async (workspaceId) => ({
|
|
1030
|
+
workspaceId,
|
|
1031
|
+
...await loadWorktreeView(manager, workspaceId)
|
|
1032
|
+
})));
|
|
1033
|
+
if (options.invalidateContext !== false) await options.invalidateWorktreeContext?.();
|
|
1034
|
+
return views;
|
|
1035
|
+
}
|
|
1036
|
+
/** Hide DSH-archived Sessions from the browser-local Worktree projection. */
|
|
1037
|
+
function filterArchivedSessionIds(sessionIds, archivedSessionIds) {
|
|
1038
|
+
return sessionIds.filter((sessionId) => !archivedSessionIds.includes(sessionId));
|
|
1039
|
+
}
|
|
712
1040
|
//#endregion
|
|
713
|
-
//#region lib/client/
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
1041
|
+
//#region lib/client/worktree-session.js
|
|
1042
|
+
var WorktreeSessionActionError = class extends Error {
|
|
1043
|
+
code;
|
|
1044
|
+
retryable;
|
|
1045
|
+
details;
|
|
1046
|
+
constructor(code, message, retryable, details = {}) {
|
|
1047
|
+
super(message);
|
|
1048
|
+
this.code = code;
|
|
1049
|
+
this.retryable = retryable;
|
|
1050
|
+
this.name = "WorktreeSessionActionError";
|
|
1051
|
+
this.details = details;
|
|
1052
|
+
}
|
|
1053
|
+
};
|
|
1054
|
+
function resolveWorktreeSessionAction(input) {
|
|
1055
|
+
if (input.target.status !== "active" || input.target.health === "repair") return {
|
|
1056
|
+
kind: "reject",
|
|
1057
|
+
reason: "worktree-not-available"
|
|
1058
|
+
};
|
|
1059
|
+
if (input.sessions.phase !== "ready") return {
|
|
1060
|
+
kind: "wait",
|
|
1061
|
+
reason: "sessions-not-ready"
|
|
1062
|
+
};
|
|
1063
|
+
const targetBinding = input.bindings.find((binding) => binding.worktreeId === input.target.worktreeId && binding.status === "active");
|
|
1064
|
+
if (targetBinding !== void 0) {
|
|
1065
|
+
const summary = input.sessions.byId[targetBinding.sessionId];
|
|
1066
|
+
if (summary === void 0) return {
|
|
1067
|
+
kind: "repair",
|
|
1068
|
+
reason: "active-binding-session-missing",
|
|
1069
|
+
sessionId: targetBinding.sessionId
|
|
1070
|
+
};
|
|
1071
|
+
if (summary.cwd !== input.target.absolutePath) return {
|
|
1072
|
+
kind: "repair",
|
|
1073
|
+
reason: "active-binding-cwd-mismatch",
|
|
1074
|
+
sessionId: targetBinding.sessionId
|
|
1075
|
+
};
|
|
1076
|
+
if (summary.blank === true && !input.archivedSessionIds.includes(targetBinding.sessionId)) return {
|
|
1077
|
+
kind: "open-bound",
|
|
1078
|
+
sessionId: targetBinding.sessionId
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
for (const sessionId of input.sessions.ids) {
|
|
1082
|
+
const summary = input.sessions.byId[sessionId];
|
|
1083
|
+
if (summary === void 0 || summary.blank === void 0 || summary.blank === true && summary.cwd === void 0) return {
|
|
1084
|
+
kind: "wait",
|
|
1085
|
+
reason: "session-facts-incomplete"
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1088
|
+
for (const sessionId of input.sessions.ids) {
|
|
1089
|
+
const summary = input.sessions.byId[sessionId];
|
|
1090
|
+
if (summary?.blank !== true || summary.cwd !== input.target.absolutePath || input.archivedSessionIds.includes(sessionId)) continue;
|
|
1091
|
+
if (!input.bindings.some((binding) => binding.sessionId === sessionId)) return {
|
|
1092
|
+
kind: "bind-existing",
|
|
1093
|
+
sessionId
|
|
1094
|
+
};
|
|
1095
|
+
}
|
|
1096
|
+
return { kind: "create" };
|
|
1097
|
+
}
|
|
1098
|
+
function actionError(action) {
|
|
1099
|
+
switch (action.kind) {
|
|
1100
|
+
case "wait": return new WorktreeSessionActionError(action.reason === "sessions-not-ready" ? "SESSION_LIST_NOT_READY" : "SESSION_FACTS_INCOMPLETE", "", true);
|
|
1101
|
+
case "repair": return new WorktreeSessionActionError("WORKTREE_SESSION_REPAIR_REQUIRED", action.reason, true, { ...action.sessionId === void 0 ? {} : { sessionId: action.sessionId } });
|
|
1102
|
+
case "reject": return new WorktreeSessionActionError("WORKTREE_SESSION_UNAVAILABLE", action.reason, false);
|
|
1103
|
+
default: return new WorktreeSessionActionError("WORKTREE_SESSION_ACTION_FAILED", "", true);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
async function retryWorktreeSessionBinding(input) {
|
|
1107
|
+
if (input.archived) throw new WorktreeSessionActionError("SESSION_ARCHIVED", "", false, { sessionId: input.pending.sessionId });
|
|
1108
|
+
try {
|
|
1109
|
+
await input.manager.bindSession({
|
|
1110
|
+
workspaceId: input.pending.workspaceId,
|
|
1111
|
+
worktreeId: input.pending.worktreeId,
|
|
1112
|
+
sessionId: input.pending.sessionId
|
|
1113
|
+
});
|
|
1114
|
+
} catch (error) {
|
|
1115
|
+
throw new WorktreeSessionBindingError(input.pending.sessionId, error);
|
|
1116
|
+
}
|
|
1117
|
+
input.ensureSessionWorkspace(input.pending.workspaceId, input.pending.sessionId);
|
|
1118
|
+
input.openSession(input.pending.sessionId);
|
|
1119
|
+
return input.pending.sessionId;
|
|
1120
|
+
}
|
|
1121
|
+
/**
|
|
1122
|
+
* Browser-only Worktree `+` connector. It owns the read/resolve/bind/create/open
|
|
1123
|
+
* sequence and coalesces repeated calls for one Worktree within one Client fiber.
|
|
1124
|
+
*/
|
|
1125
|
+
function createWorktreeSessionConnector(options) {
|
|
1126
|
+
const inFlight = /* @__PURE__ */ new Map();
|
|
1127
|
+
let disposed = false;
|
|
1128
|
+
const run = async (input) => {
|
|
1129
|
+
const [worktrees, bindings] = await Promise.all([options.manager.listWorktrees({ workspaceId: input.workspaceId }), options.manager.listBindings({ workspaceId: input.workspaceId })]);
|
|
1130
|
+
if (disposed) throw new WorktreeSessionActionError("CLIENT_DISPOSED", "", false);
|
|
1131
|
+
const target = worktrees.find((record) => record.worktreeId === input.worktreeId);
|
|
1132
|
+
if (target === void 0 || target.absolutePath !== input.cwd) throw new WorktreeSessionActionError("WORKTREE_SESSION_REPAIR_REQUIRED", "worktree target unavailable", true);
|
|
1133
|
+
const action = resolveWorktreeSessionAction({
|
|
1134
|
+
target,
|
|
1135
|
+
sessions: options.sessions.getSnapshot(),
|
|
1136
|
+
archivedSessionIds: options.archivedSessionIds(),
|
|
1137
|
+
bindings
|
|
1138
|
+
});
|
|
1139
|
+
if (action.kind === "open-bound") {
|
|
1140
|
+
options.ensureSessionWorkspace(input.workspaceId, action.sessionId);
|
|
1141
|
+
if (!disposed) options.openSession(action.sessionId);
|
|
1142
|
+
return action.sessionId;
|
|
1143
|
+
}
|
|
1144
|
+
if (action.kind === "bind-existing") {
|
|
1145
|
+
try {
|
|
1146
|
+
await options.manager.bindSession({
|
|
1147
|
+
workspaceId: input.workspaceId,
|
|
1148
|
+
worktreeId: input.worktreeId,
|
|
1149
|
+
sessionId: action.sessionId
|
|
1150
|
+
});
|
|
1151
|
+
} catch (error) {
|
|
1152
|
+
throw new WorktreeSessionBindingError(action.sessionId, error);
|
|
1153
|
+
}
|
|
1154
|
+
if (!disposed) {
|
|
1155
|
+
options.ensureSessionWorkspace(input.workspaceId, action.sessionId);
|
|
1156
|
+
if (!disposed) options.openSession(action.sessionId);
|
|
1157
|
+
}
|
|
1158
|
+
return action.sessionId;
|
|
1159
|
+
}
|
|
1160
|
+
if (action.kind !== "create") throw actionError(action);
|
|
1161
|
+
if (disposed) throw new WorktreeSessionActionError("CLIENT_DISPOSED", "", false);
|
|
1162
|
+
return createSessionForWorktree({
|
|
1163
|
+
...input,
|
|
1164
|
+
createSession: options.createSession,
|
|
1165
|
+
manager: options.manager,
|
|
1166
|
+
beforeOpen: (sessionId) => {
|
|
1167
|
+
if (disposed) throw new WorktreeSessionActionError("CLIENT_DISPOSED", "", false);
|
|
1168
|
+
options.ensureSessionWorkspace(input.workspaceId, sessionId);
|
|
1169
|
+
},
|
|
1170
|
+
openSession: (sessionId) => {
|
|
1171
|
+
if (!disposed) options.openSession(sessionId);
|
|
1172
|
+
}
|
|
1173
|
+
});
|
|
1174
|
+
};
|
|
717
1175
|
return {
|
|
718
|
-
|
|
719
|
-
|
|
1176
|
+
create(input) {
|
|
1177
|
+
const key = `${input.workspaceId}\u0000${input.worktreeId}`;
|
|
1178
|
+
const current = inFlight.get(key);
|
|
1179
|
+
if (current !== void 0) return current;
|
|
1180
|
+
const promise = run(input).finally(() => {
|
|
1181
|
+
if (inFlight.get(key) === promise) inFlight.delete(key);
|
|
1182
|
+
});
|
|
1183
|
+
inFlight.set(key, promise);
|
|
1184
|
+
return promise;
|
|
1185
|
+
},
|
|
1186
|
+
dispose() {
|
|
1187
|
+
disposed = true;
|
|
1188
|
+
inFlight.clear();
|
|
1189
|
+
}
|
|
720
1190
|
};
|
|
721
1191
|
}
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
if (stable !== previousRef.current) previousRef.current = stable;
|
|
731
|
-
return previousRef.current;
|
|
1192
|
+
//#endregion
|
|
1193
|
+
//#region lib/client/worktree-surface-dialogs.js
|
|
1194
|
+
function worktreeSetupMessage(status, t) {
|
|
1195
|
+
switch (status) {
|
|
1196
|
+
case "noRepository": return t("worktree.setup.noRepository");
|
|
1197
|
+
case "noInitialCommit": return t("worktree.setup.noInitialCommit");
|
|
1198
|
+
case "noLocalBranch": return t("worktree.setup.noLocalBranch");
|
|
1199
|
+
}
|
|
732
1200
|
}
|
|
733
|
-
function
|
|
734
|
-
return
|
|
1201
|
+
function WorktreeSessionRenameDialog({ t, target, draft, pending, error, onClose, onDraftChange, onSubmit }) {
|
|
1202
|
+
return (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
1203
|
+
open: target !== void 0,
|
|
1204
|
+
onClose,
|
|
1205
|
+
closeLabel: t("dialog.close"),
|
|
1206
|
+
title: t("session.rename"),
|
|
1207
|
+
footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1208
|
+
variant: "outline",
|
|
1209
|
+
disabled: pending,
|
|
1210
|
+
onClick: onClose,
|
|
1211
|
+
children: t("dialog.cancel")
|
|
1212
|
+
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1213
|
+
variant: "primary",
|
|
1214
|
+
disabled: pending || draft.trim().length === 0,
|
|
1215
|
+
onClick: () => {
|
|
1216
|
+
onSubmit();
|
|
1217
|
+
},
|
|
1218
|
+
children: t("dialog.rename")
|
|
1219
|
+
})] }),
|
|
1220
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
|
|
1221
|
+
className: worktree_css_default.renameInput,
|
|
1222
|
+
value: draft,
|
|
1223
|
+
"aria-label": t("session.name"),
|
|
1224
|
+
autoFocus: true,
|
|
1225
|
+
disabled: pending,
|
|
1226
|
+
onFocus: (event) => {
|
|
1227
|
+
event.currentTarget.select();
|
|
1228
|
+
},
|
|
1229
|
+
onChange: (event) => {
|
|
1230
|
+
onDraftChange(event.currentTarget.value);
|
|
1231
|
+
},
|
|
1232
|
+
onKeyDown: (event) => {
|
|
1233
|
+
if (event.key === "Enter" && !event.nativeEvent.isComposing) {
|
|
1234
|
+
event.preventDefault();
|
|
1235
|
+
onSubmit();
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
}), error !== void 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
1239
|
+
className: worktree_css_default.renameError,
|
|
1240
|
+
role: "alert",
|
|
1241
|
+
children: formatWorktreeViewError(error, t)
|
|
1242
|
+
})]
|
|
1243
|
+
});
|
|
735
1244
|
}
|
|
736
|
-
function
|
|
737
|
-
|
|
738
|
-
return
|
|
1245
|
+
function WorktreeWorkspaceRenameDialog({ t, target, draft, pending, duplicate, error, onClose, onDraftChange, onSubmit }) {
|
|
1246
|
+
if (target === void 0) return null;
|
|
1247
|
+
return (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
1248
|
+
open: true,
|
|
1249
|
+
onClose,
|
|
1250
|
+
closeLabel: t("dialog.closeWorkspaceRename"),
|
|
1251
|
+
title: t("workspace.renameTitle"),
|
|
1252
|
+
footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1253
|
+
variant: "outline",
|
|
1254
|
+
disabled: pending,
|
|
1255
|
+
onClick: onClose,
|
|
1256
|
+
children: t("dialog.cancel")
|
|
1257
|
+
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1258
|
+
variant: "primary",
|
|
1259
|
+
disabled: pending || draft.trim().length === 0 || draft.trim() === target.currentTitle || duplicate,
|
|
1260
|
+
onClick: () => {
|
|
1261
|
+
onSubmit();
|
|
1262
|
+
},
|
|
1263
|
+
children: t("dialog.rename")
|
|
1264
|
+
})] }),
|
|
1265
|
+
children: [
|
|
1266
|
+
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
|
|
1267
|
+
className: worktree_css_default.renameInput,
|
|
1268
|
+
value: draft,
|
|
1269
|
+
"aria-label": t("workspace.name"),
|
|
1270
|
+
autoFocus: true,
|
|
1271
|
+
disabled: pending,
|
|
1272
|
+
onFocus: (event) => {
|
|
1273
|
+
event.currentTarget.select();
|
|
1274
|
+
},
|
|
1275
|
+
onChange: (event) => {
|
|
1276
|
+
onDraftChange(event.currentTarget.value);
|
|
1277
|
+
},
|
|
1278
|
+
onKeyDown: (event) => {
|
|
1279
|
+
if (event.key === "Enter" && !event.nativeEvent.isComposing) {
|
|
1280
|
+
event.preventDefault();
|
|
1281
|
+
onSubmit();
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
}),
|
|
1285
|
+
duplicate && (0, react_jsx_runtime.jsx)("p", {
|
|
1286
|
+
className: worktree_css_default.renameError,
|
|
1287
|
+
role: "alert",
|
|
1288
|
+
children: t("workspace.duplicate")
|
|
1289
|
+
}),
|
|
1290
|
+
error !== void 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
1291
|
+
className: worktree_css_default.renameError,
|
|
1292
|
+
role: "alert",
|
|
1293
|
+
children: formatWorktreeViewError(error, t)
|
|
1294
|
+
})
|
|
1295
|
+
]
|
|
1296
|
+
});
|
|
1297
|
+
}
|
|
1298
|
+
function WorktreeWorkspaceDeleteDialog({ t, target, pending, error, onClose, onSubmit }) {
|
|
1299
|
+
if (target === void 0) return null;
|
|
1300
|
+
return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
1301
|
+
open: true,
|
|
1302
|
+
onClose,
|
|
1303
|
+
closeLabel: t("dialog.closeWorkspaceDelete"),
|
|
1304
|
+
title: t("workspace.deleteTitle"),
|
|
1305
|
+
description: t("workspace.deleteDescription", { name: target.title }),
|
|
1306
|
+
footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1307
|
+
variant: "outline",
|
|
1308
|
+
disabled: pending,
|
|
1309
|
+
onClick: onClose,
|
|
1310
|
+
children: t("dialog.cancel")
|
|
1311
|
+
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1312
|
+
variant: "outline",
|
|
1313
|
+
disabled: pending,
|
|
1314
|
+
onClick: () => {
|
|
1315
|
+
onSubmit();
|
|
1316
|
+
},
|
|
1317
|
+
children: t("dialog.delete")
|
|
1318
|
+
})] }),
|
|
1319
|
+
children: error !== void 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
1320
|
+
className: worktree_css_default.renameError,
|
|
1321
|
+
role: "alert",
|
|
1322
|
+
children: formatWorktreeViewError(error, t)
|
|
1323
|
+
})
|
|
1324
|
+
});
|
|
1325
|
+
}
|
|
1326
|
+
function WorktreeCreateDialog({ t, workspace, view, setupStatus, canCreate, selectedBranch, newBranch, actionPending, onClose, onSelectedBranchChange, onNewBranchChange, onSubmit }) {
|
|
1327
|
+
if (workspace === void 0) return null;
|
|
1328
|
+
return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
1329
|
+
open: true,
|
|
1330
|
+
onClose: () => {
|
|
1331
|
+
if (actionPending) return;
|
|
1332
|
+
onClose();
|
|
1333
|
+
},
|
|
1334
|
+
closeLabel: t("dialog.closeWorktreeCreate"),
|
|
1335
|
+
title: t("worktree.createTitle"),
|
|
1336
|
+
description: t("worktree.createDescription", { name: workspace.title }),
|
|
1337
|
+
footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1338
|
+
variant: "outline",
|
|
1339
|
+
disabled: actionPending,
|
|
1340
|
+
onClick: onClose,
|
|
1341
|
+
children: t("dialog.cancel")
|
|
1342
|
+
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1343
|
+
variant: "primary",
|
|
1344
|
+
disabled: actionPending || selectedBranch.length === 0 || newBranch.trim().length === 0,
|
|
1345
|
+
onClick: () => {
|
|
1346
|
+
onSubmit();
|
|
1347
|
+
},
|
|
1348
|
+
children: t("worktree.create")
|
|
1349
|
+
})] }),
|
|
1350
|
+
children: canCreate ? (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsxs)("label", {
|
|
1351
|
+
className: worktree_css_default.modalField,
|
|
1352
|
+
children: [t("worktree.baseBranch"), (0, react_jsx_runtime.jsx)("select", {
|
|
1353
|
+
className: worktree_css_default.actionSelect,
|
|
1354
|
+
"aria-label": t("worktree.baseBranch"),
|
|
1355
|
+
value: selectedBranch,
|
|
1356
|
+
disabled: actionPending,
|
|
1357
|
+
onChange: (event) => {
|
|
1358
|
+
onSelectedBranchChange(event.currentTarget.value);
|
|
1359
|
+
},
|
|
1360
|
+
children: view?.branches.map((branch) => (0, react_jsx_runtime.jsxs)("option", {
|
|
1361
|
+
value: branch.name,
|
|
1362
|
+
children: [
|
|
1363
|
+
branch.name,
|
|
1364
|
+
branch.isCurrent ? t("branch.current") : "",
|
|
1365
|
+
branch.checkedOut ? t("branch.checkedOut") : ""
|
|
1366
|
+
]
|
|
1367
|
+
}, branch.name))
|
|
1368
|
+
})]
|
|
1369
|
+
}), (0, react_jsx_runtime.jsxs)("label", {
|
|
1370
|
+
className: worktree_css_default.modalField,
|
|
1371
|
+
children: [t("worktree.name"), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
|
|
1372
|
+
className: worktree_css_default.renameInput,
|
|
1373
|
+
"aria-label": t("worktree.name"),
|
|
1374
|
+
value: newBranch,
|
|
1375
|
+
placeholder: "dsh/12345678",
|
|
1376
|
+
disabled: actionPending,
|
|
1377
|
+
onChange: (event) => {
|
|
1378
|
+
onNewBranchChange(event.currentTarget.value);
|
|
1379
|
+
}
|
|
1380
|
+
})]
|
|
1381
|
+
})] }) : (0, react_jsx_runtime.jsxs)("div", {
|
|
1382
|
+
className: worktree_css_default.gitReadiness,
|
|
1383
|
+
"data-worktree-readiness": setupStatus ?? "loading",
|
|
1384
|
+
role: "alert",
|
|
1385
|
+
children: [(0, react_jsx_runtime.jsx)("p", {
|
|
1386
|
+
className: worktree_css_default.message,
|
|
1387
|
+
children: setupStatus === void 0 ? t("status.loading") : worktreeSetupMessage(setupStatus, t)
|
|
1388
|
+
}), setupStatus !== void 0 && (0, react_jsx_runtime.jsx)("pre", {
|
|
1389
|
+
className: worktree_css_default.commandBlock,
|
|
1390
|
+
"aria-label": t("worktree.setup.commands"),
|
|
1391
|
+
children: worktreeSetupCommands(setupStatus).join("\n")
|
|
1392
|
+
})]
|
|
1393
|
+
})
|
|
1394
|
+
});
|
|
1395
|
+
}
|
|
1396
|
+
function WorktreeRemovalDialog({ t, worktree, actionPending, onClose, onSubmit }) {
|
|
1397
|
+
if (worktree === void 0) return null;
|
|
1398
|
+
return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
1399
|
+
open: true,
|
|
1400
|
+
onClose: () => {
|
|
1401
|
+
if (actionPending) return;
|
|
1402
|
+
onClose();
|
|
1403
|
+
},
|
|
1404
|
+
closeLabel: t("dialog.closeWorktreeRemove"),
|
|
1405
|
+
title: t("worktree.remove"),
|
|
1406
|
+
description: t("worktree.removeDescription", { name: worktree.branch }),
|
|
1407
|
+
footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1408
|
+
variant: "outline",
|
|
1409
|
+
disabled: actionPending,
|
|
1410
|
+
onClick: onClose,
|
|
1411
|
+
children: t("dialog.cancel")
|
|
1412
|
+
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1413
|
+
variant: "primary",
|
|
1414
|
+
disabled: actionPending,
|
|
1415
|
+
onClick: () => {
|
|
1416
|
+
onSubmit();
|
|
1417
|
+
},
|
|
1418
|
+
children: t("worktree.remove")
|
|
1419
|
+
})] })
|
|
1420
|
+
});
|
|
1421
|
+
}
|
|
1422
|
+
//#endregion
|
|
1423
|
+
//#region lib/client/worktree-surface-selectors.js
|
|
1424
|
+
function sessionLabel(sessionId, sessions, t) {
|
|
1425
|
+
return sessionDisplayLabel(sessionId, sessions, t("session.new"));
|
|
739
1426
|
}
|
|
740
1427
|
function bindingIdsFor(bindings, worktreeId) {
|
|
741
1428
|
return bindings.filter((binding) => binding.worktreeId === worktreeId).map((binding) => binding.sessionId);
|
|
@@ -746,10 +1433,16 @@ window.__ModuleLoader__.load({
|
|
|
746
1433
|
function workspaceMatches(workspace, view, sessions, query) {
|
|
747
1434
|
if (query.length === 0) return true;
|
|
748
1435
|
if (includesText(workspace.title, query)) return true;
|
|
749
|
-
if (workspace.sessionIds.some((sessionId) =>
|
|
1436
|
+
if (workspace.sessionIds.some((sessionId) => sessionMatchesQuery(sessionId, sessions, query))) return true;
|
|
750
1437
|
if (view === void 0) return false;
|
|
751
1438
|
if (view.worktrees.some((record) => includesText(record.branch, query) || includesText(record.absolutePath, query))) return true;
|
|
752
|
-
return view.bindings.some((binding) =>
|
|
1439
|
+
return view.bindings.some((binding) => sessionMatchesQuery(binding.sessionId, sessions, query));
|
|
1440
|
+
}
|
|
1441
|
+
//#endregion
|
|
1442
|
+
//#region lib/client/worktree-surface-rows.js
|
|
1443
|
+
function rowHalf(event) {
|
|
1444
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
1445
|
+
return event.clientY < rect.top + rect.height / 2 ? "before" : "after";
|
|
753
1446
|
}
|
|
754
1447
|
/** Workspace row using the native DSH menu, fixed action column, and drag contract. */
|
|
755
1448
|
function WorktreeWorkspaceRow({ t, workspace, expanded, actionPending, menuOpen, drag, onToggle, onCreateWorktree, onRename, onDelete, onMenuOpenChange }) {
|
|
@@ -857,13 +1550,36 @@ window.__ModuleLoader__.load({
|
|
|
857
1550
|
});
|
|
858
1551
|
}
|
|
859
1552
|
/** Shared Main/Worktree group row with parameterized icon, state, and actions. */
|
|
860
|
-
function WorktreeGroupRow({ t, kind, label, expanded, icon, workspaceTitle, state, stateLabel, onToggle, onCreateSession, menu }) {
|
|
1553
|
+
function WorktreeGroupRow({ t, kind, label, worktreeId, expanded, icon, workspaceTitle, state, stateLabel, onToggle, onCreateSession, menu, drag }) {
|
|
861
1554
|
const main = kind === "main";
|
|
1555
|
+
const markerClass = drag?.marker === "before" ? worktree_css_default.dropBefore : drag?.marker === "after" ? worktree_css_default.dropAfter : "";
|
|
1556
|
+
const dragProps = drag === void 0 ? {} : {
|
|
1557
|
+
draggable: true,
|
|
1558
|
+
onDragStart: (event) => {
|
|
1559
|
+
event.dataTransfer.effectAllowed = "move";
|
|
1560
|
+
event.dataTransfer.setData("text/plain", worktreeId ?? label);
|
|
1561
|
+
drag.start();
|
|
1562
|
+
},
|
|
1563
|
+
onDragEnd: drag.end,
|
|
1564
|
+
onDragOver: (event) => {
|
|
1565
|
+
if (!drag.active) return;
|
|
1566
|
+
event.preventDefault();
|
|
1567
|
+
event.dataTransfer.dropEffect = "move";
|
|
1568
|
+
drag.hover(rowHalf(event));
|
|
1569
|
+
},
|
|
1570
|
+
onDrop: (event) => {
|
|
1571
|
+
if (!drag.active) return;
|
|
1572
|
+
event.preventDefault();
|
|
1573
|
+
drag.drop(rowHalf(event));
|
|
1574
|
+
}
|
|
1575
|
+
};
|
|
862
1576
|
const row = (0, react_jsx_runtime.jsxs)("div", {
|
|
863
|
-
className: worktree_css_default.worktreeRow
|
|
1577
|
+
className: `${worktree_css_default.worktreeRow} ${markerClass}`,
|
|
864
1578
|
"data-main-group": main ? "true" : void 0,
|
|
865
1579
|
"data-main-expanded": main ? String(expanded) : void 0,
|
|
866
1580
|
"data-menu-open": menu?.open ? "true" : void 0,
|
|
1581
|
+
"data-worktree-drag": drag?.active ? "active" : void 0,
|
|
1582
|
+
...dragProps,
|
|
867
1583
|
onClick: onToggle,
|
|
868
1584
|
children: [
|
|
869
1585
|
(0, react_jsx_runtime.jsx)("button", {
|
|
@@ -954,7 +1670,7 @@ window.__ModuleLoader__.load({
|
|
|
954
1670
|
});
|
|
955
1671
|
}
|
|
956
1672
|
/** Worktree-mode Session row with the same trailing options menu as native DSH rows. */
|
|
957
|
-
function WorktreeSessionRow({ t, sessionId, label, drag, actionPending, onOpen, onRename, onFork, onArchive }) {
|
|
1673
|
+
function WorktreeSessionRow({ t, sessionId, blank, label, drag, actionPending, onOpen, onRename, onFork, onArchive }) {
|
|
958
1674
|
const [menuOpen, setMenuOpen] = (0, react.useState)(false);
|
|
959
1675
|
const markerClass = drag.marker === "before" ? worktree_css_default.dropBefore : drag.marker === "after" ? worktree_css_default.dropAfter : "";
|
|
960
1676
|
const sessionMenuItems = [
|
|
@@ -980,6 +1696,7 @@ window.__ModuleLoader__.load({
|
|
|
980
1696
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
981
1697
|
className: `${worktree_css_default.treeSessionRow} ${markerClass}`,
|
|
982
1698
|
"data-session-id": sessionId,
|
|
1699
|
+
"data-session-blank": blank ? "true" : void 0,
|
|
983
1700
|
"data-session-drag": drag.active ? "active" : void 0,
|
|
984
1701
|
"data-menu-open": menuOpen || void 0,
|
|
985
1702
|
role: "treeitem",
|
|
@@ -1013,7 +1730,7 @@ window.__ModuleLoader__.load({
|
|
|
1013
1730
|
className: worktree_css_default.sessionLabel,
|
|
1014
1731
|
children: label
|
|
1015
1732
|
})]
|
|
1016
|
-
}), (0, react_jsx_runtime.jsx)("span", {
|
|
1733
|
+
}), !blank && (0, react_jsx_runtime.jsx)("span", {
|
|
1017
1734
|
className: worktree_css_default.rowActions,
|
|
1018
1735
|
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
|
|
1019
1736
|
open: menuOpen,
|
|
@@ -1050,7 +1767,8 @@ window.__ModuleLoader__.load({
|
|
|
1050
1767
|
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [visibleSessionIds.map((sessionId) => (0, react_jsx_runtime.jsx)(WorktreeSessionRow, {
|
|
1051
1768
|
t,
|
|
1052
1769
|
sessionId,
|
|
1053
|
-
|
|
1770
|
+
blank: isBlankSession(sessionId, sessions),
|
|
1771
|
+
label: sessionLabel(sessionId, sessions, t),
|
|
1054
1772
|
drag: {
|
|
1055
1773
|
active: sameGroupDrag,
|
|
1056
1774
|
marker: sameGroupDrag && dragState.over?.sessionId === sessionId ? dragState.over.half : null,
|
|
@@ -1088,16 +1806,39 @@ window.__ModuleLoader__.load({
|
|
|
1088
1806
|
children: expanded ? t("session.collapse") : t("session.expandMore", { count: sessionIds.length - 5 })
|
|
1089
1807
|
})] });
|
|
1090
1808
|
}
|
|
1809
|
+
//#endregion
|
|
1810
|
+
//#region lib/client/WorktreeSurface.js
|
|
1811
|
+
function toNativeWorktreeViewError(error) {
|
|
1812
|
+
const viewError = toWorktreeViewError(error);
|
|
1813
|
+
if (typeof error === "object" && error !== null) return viewError;
|
|
1814
|
+
return {
|
|
1815
|
+
...viewError,
|
|
1816
|
+
message: String(error)
|
|
1817
|
+
};
|
|
1818
|
+
}
|
|
1819
|
+
const EMPTY_READ_STATE = {
|
|
1820
|
+
status: "idle",
|
|
1821
|
+
views: []
|
|
1822
|
+
};
|
|
1823
|
+
function useStableWorkspaceIds(workspaces) {
|
|
1824
|
+
const next = workspaces.map((workspace) => workspace.workspaceId);
|
|
1825
|
+
const previousRef = (0, react.useRef)([]);
|
|
1826
|
+
const stable = stableWorkspaceIds(previousRef.current, next);
|
|
1827
|
+
if (stable !== previousRef.current) previousRef.current = stable;
|
|
1828
|
+
return previousRef.current;
|
|
1829
|
+
}
|
|
1091
1830
|
/**
|
|
1092
1831
|
* Peer Worktree navigation surface. It keeps the original DSH Workspace mode
|
|
1093
1832
|
* intact and renders a browser-local Workspace → Worktree → Session projection.
|
|
1094
1833
|
*/
|
|
1095
|
-
function WorktreeSurface({ useStore, actions, useSessions, useWorkspaces, t, available, manager, createWorkspace, createSessionForWorktree: createSessionCallback, createMainSession, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, insertSessionBefore, renameSession, forkSession, archiveSession, ensureSessionWorkspace, syncSessionWorkspaces, openSession }) {
|
|
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 }) {
|
|
1096
1835
|
const mode = effectiveViewMode(useStore((state) => state.viewMode), available && manager !== void 0);
|
|
1097
1836
|
const sessions = useSessions((state) => state);
|
|
1098
1837
|
const workspaces = useWorkspaces((state) => state);
|
|
1099
1838
|
const workspaceIds = useStableWorkspaceIds(workspaces.items);
|
|
1100
1839
|
const [readState, setReadState] = (0, react.useState)(EMPTY_READ_STATE);
|
|
1840
|
+
const readStateRef = (0, react.useRef)(readState);
|
|
1841
|
+
readStateRef.current = readState;
|
|
1101
1842
|
const [searchQuery, setSearchQuery] = (0, react.useState)("");
|
|
1102
1843
|
const [expandedWorkspaces, setExpandedWorkspaces] = (0, react.useState)({});
|
|
1103
1844
|
const [expandedMains, setExpandedMains] = (0, react.useState)({});
|
|
@@ -1127,36 +1868,52 @@ window.__ModuleLoader__.load({
|
|
|
1127
1868
|
const [sessionDrag, setSessionDrag] = (0, react.useState)();
|
|
1128
1869
|
const [expandedSessionGroups, setExpandedSessionGroups] = (0, react.useState)({});
|
|
1129
1870
|
const sessionDropCommitted = (0, react.useRef)(false);
|
|
1871
|
+
const [worktreeDrag, setWorktreeDrag] = (0, react.useState)();
|
|
1872
|
+
const worktreeDropCommitted = (0, react.useRef)(false);
|
|
1873
|
+
const refreshGuard = (0, react.useRef)(createWorktreeRefreshGuard());
|
|
1130
1874
|
const { ref, width, bounds } = useSidebarOverlayGeometry(mode === "worktree");
|
|
1131
1875
|
const collapsed = width <= 64;
|
|
1132
1876
|
const query = searchQuery.trim().toLocaleLowerCase();
|
|
1133
1877
|
const archivedSessionIds = workspaces.archivedSessionIds ?? [];
|
|
1134
|
-
const
|
|
1878
|
+
const pendingSessionArchived = pendingSessionBinding !== void 0 && archivedSessionIds.includes(pendingSessionBinding.sessionId);
|
|
1879
|
+
const refresh = (0, react.useCallback)(async (options = {}) => {
|
|
1135
1880
|
if (manager === void 0) {
|
|
1881
|
+
refreshGuard.current.invalidate();
|
|
1136
1882
|
setReadState(EMPTY_READ_STATE);
|
|
1137
1883
|
return;
|
|
1138
1884
|
}
|
|
1139
|
-
|
|
1885
|
+
const preserveCurrent = options.preserveCurrent === true;
|
|
1886
|
+
if (!preserveCurrent) setReadState({
|
|
1140
1887
|
status: "loading",
|
|
1141
1888
|
views: []
|
|
1142
1889
|
});
|
|
1143
|
-
|
|
1144
|
-
|
|
1890
|
+
await refreshGuard.current.run(() => loadWorktreeViews(manager, workspaceIds, {
|
|
1891
|
+
invalidateContext: options.invalidateContext !== false,
|
|
1892
|
+
invalidateWorktreeContext
|
|
1893
|
+
}), (views) => {
|
|
1145
1894
|
setReadState({
|
|
1146
1895
|
status: "ready",
|
|
1147
1896
|
views
|
|
1148
1897
|
});
|
|
1149
|
-
}
|
|
1898
|
+
}, (error) => {
|
|
1899
|
+
if (preserveCurrent) throw error;
|
|
1150
1900
|
setReadState({
|
|
1151
1901
|
status: "error",
|
|
1152
1902
|
views: [],
|
|
1153
1903
|
error: toWorktreeViewError(error)
|
|
1154
1904
|
});
|
|
1155
|
-
}
|
|
1156
|
-
}, [
|
|
1905
|
+
});
|
|
1906
|
+
}, [
|
|
1907
|
+
invalidateWorktreeContext,
|
|
1908
|
+
manager,
|
|
1909
|
+
workspaceIds
|
|
1910
|
+
]);
|
|
1157
1911
|
(0, react.useEffect)(() => {
|
|
1158
|
-
if (mode === "worktree") refresh();
|
|
1159
|
-
else
|
|
1912
|
+
if (mode === "worktree") refresh({ preserveCurrent: readStateRef.current.status === "ready" });
|
|
1913
|
+
else {
|
|
1914
|
+
refreshGuard.current.invalidate();
|
|
1915
|
+
setReadState(EMPTY_READ_STATE);
|
|
1916
|
+
}
|
|
1160
1917
|
}, [mode, refresh]);
|
|
1161
1918
|
(0, react.useEffect)(() => {
|
|
1162
1919
|
if (readState.status !== "ready" || syncSessionWorkspaces === void 0) return;
|
|
@@ -1172,12 +1929,23 @@ window.__ModuleLoader__.load({
|
|
|
1172
1929
|
const viewByWorkspace = (0, react.useMemo)(() => new Map(readState.views.map((view) => [view.workspaceId, view])), [readState.views]);
|
|
1173
1930
|
const modalWorkspace = workspaces.items.find((workspace) => workspace.workspaceId === worktreeModalWorkspaceId);
|
|
1174
1931
|
const modalView = worktreeModalWorkspaceId === void 0 ? void 0 : viewByWorkspace.get(worktreeModalWorkspaceId);
|
|
1932
|
+
const modalReadiness = modalView?.readiness;
|
|
1933
|
+
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";
|
|
1935
|
+
(0, react.useEffect)(() => {
|
|
1936
|
+
if (worktreeModalWorkspaceId === void 0 || modalView === void 0) return;
|
|
1937
|
+
if (modalView.readiness.status !== "ready") {
|
|
1938
|
+
setSelectedBranch("");
|
|
1939
|
+
return;
|
|
1940
|
+
}
|
|
1941
|
+
setSelectedBranch((current) => reconcileBaseBranchSelection(current, modalView.branches));
|
|
1942
|
+
}, [modalView, worktreeModalWorkspaceId]);
|
|
1175
1943
|
const runMutation = async (operation) => {
|
|
1176
1944
|
setActionPending(true);
|
|
1177
1945
|
setActionError(void 0);
|
|
1178
1946
|
try {
|
|
1179
1947
|
await operation();
|
|
1180
|
-
await refresh();
|
|
1948
|
+
await refresh({ preserveCurrent: true });
|
|
1181
1949
|
} catch (error) {
|
|
1182
1950
|
setActionError(toWorktreeViewError(error));
|
|
1183
1951
|
} finally {
|
|
@@ -1303,6 +2071,29 @@ window.__ModuleLoader__.load({
|
|
|
1303
2071
|
setActionError(toWorktreeViewError(error));
|
|
1304
2072
|
});
|
|
1305
2073
|
};
|
|
2074
|
+
const commitWorktreeDrag = (activeDrag, over, worktreeIds, workspaceId) => {
|
|
2075
|
+
if (worktreeDropCommitted.current) return;
|
|
2076
|
+
worktreeDropCommitted.current = true;
|
|
2077
|
+
setWorktreeDrag(void 0);
|
|
2078
|
+
if (activeDrag.workspaceId !== workspaceId) return;
|
|
2079
|
+
const move = resolveWorktreeMove(worktreeIds, activeDrag.worktreeId, over.worktreeId, over.half);
|
|
2080
|
+
if (move === void 0) return;
|
|
2081
|
+
if (insertWorktreeBefore === void 0) {
|
|
2082
|
+
setActionError({
|
|
2083
|
+
code: "WORKTREE_ORDER_UNAVAILABLE",
|
|
2084
|
+
message: "",
|
|
2085
|
+
retryable: true
|
|
2086
|
+
});
|
|
2087
|
+
return;
|
|
2088
|
+
}
|
|
2089
|
+
setActionError(void 0);
|
|
2090
|
+
insertWorktreeBefore(workspaceId, activeDrag.worktreeId, move.beforeWorktreeId).then(() => refresh({
|
|
2091
|
+
preserveCurrent: true,
|
|
2092
|
+
invalidateContext: false
|
|
2093
|
+
})).catch((error) => {
|
|
2094
|
+
setActionError(toRetryableWorktreeOrderError(error));
|
|
2095
|
+
});
|
|
2096
|
+
};
|
|
1306
2097
|
const openSessionRename = (sessionId, currentTitle) => {
|
|
1307
2098
|
setSessionRenameTarget({
|
|
1308
2099
|
sessionId,
|
|
@@ -1372,7 +2163,7 @@ window.__ModuleLoader__.load({
|
|
|
1372
2163
|
};
|
|
1373
2164
|
const submitWorktree = async () => {
|
|
1374
2165
|
const worktreeName = newBranch.trim();
|
|
1375
|
-
if (manager === void 0 || modalWorkspace === void 0 || selectedBranch.length === 0 || worktreeName.length === 0) return;
|
|
2166
|
+
if (manager === void 0 || modalWorkspace === void 0 || !modalCanCreate || selectedBranch.length === 0 || worktreeName.length === 0) return;
|
|
1376
2167
|
const input = {
|
|
1377
2168
|
workspaceId: modalWorkspace.workspaceId,
|
|
1378
2169
|
branch: selectedBranch,
|
|
@@ -1393,7 +2184,7 @@ window.__ModuleLoader__.load({
|
|
|
1393
2184
|
};
|
|
1394
2185
|
setWorktreeModalWorkspaceId(void 0);
|
|
1395
2186
|
if (createSessionCallback === void 0) {
|
|
1396
|
-
await refresh();
|
|
2187
|
+
await refresh({ preserveCurrent: true });
|
|
1397
2188
|
setActionError({
|
|
1398
2189
|
code: "WORKTREE_CREATED_SESSION_UNAVAILABLE",
|
|
1399
2190
|
message: "",
|
|
@@ -1408,14 +2199,15 @@ window.__ModuleLoader__.load({
|
|
|
1408
2199
|
};
|
|
1409
2200
|
try {
|
|
1410
2201
|
await createSessionCallback(sessionInput);
|
|
2202
|
+
await invalidateWorktreeContext?.(createdWorktree.workspaceId);
|
|
1411
2203
|
} catch (error) {
|
|
1412
|
-
if (error instanceof WorktreeSessionBindingError) setPendingSessionBinding({
|
|
2204
|
+
if (error instanceof WorktreeSessionBindingError && error.retryable) setPendingSessionBinding({
|
|
1413
2205
|
...sessionInput,
|
|
1414
2206
|
sessionId: error.sessionId
|
|
1415
2207
|
});
|
|
1416
2208
|
throw error;
|
|
1417
2209
|
}
|
|
1418
|
-
await refresh();
|
|
2210
|
+
await refresh({ preserveCurrent: true });
|
|
1419
2211
|
} catch (error) {
|
|
1420
2212
|
setActionError(toWorktreeViewError(error));
|
|
1421
2213
|
} finally {
|
|
@@ -1436,9 +2228,10 @@ window.__ModuleLoader__.load({
|
|
|
1436
2228
|
setPendingSessionBinding(void 0);
|
|
1437
2229
|
try {
|
|
1438
2230
|
await createSessionCallback(input);
|
|
1439
|
-
await
|
|
2231
|
+
await invalidateWorktreeContext?.(input.workspaceId);
|
|
2232
|
+
await refresh({ preserveCurrent: true });
|
|
1440
2233
|
} catch (error) {
|
|
1441
|
-
if (error instanceof WorktreeSessionBindingError) setPendingSessionBinding({
|
|
2234
|
+
if (error instanceof WorktreeSessionBindingError && error.retryable) setPendingSessionBinding({
|
|
1442
2235
|
...input,
|
|
1443
2236
|
sessionId: error.sessionId
|
|
1444
2237
|
});
|
|
@@ -1448,21 +2241,25 @@ window.__ModuleLoader__.load({
|
|
|
1448
2241
|
}
|
|
1449
2242
|
};
|
|
1450
2243
|
const retrySessionBinding = async () => {
|
|
1451
|
-
if (manager === void 0 || pendingSessionBinding === void 0) return;
|
|
2244
|
+
if (manager === void 0 || pendingSessionBinding === void 0 || pendingSessionArchived) return;
|
|
2245
|
+
const pending = pendingSessionBinding;
|
|
1452
2246
|
setActionPending(true);
|
|
1453
2247
|
setActionError(void 0);
|
|
1454
2248
|
try {
|
|
1455
|
-
await
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
2249
|
+
await retryWorktreeSessionBinding({
|
|
2250
|
+
manager,
|
|
2251
|
+
pending,
|
|
2252
|
+
archived: false,
|
|
2253
|
+
ensureSessionWorkspace: (workspaceId, sessionId) => {
|
|
2254
|
+
ensureSessionWorkspace?.(workspaceId, sessionId);
|
|
2255
|
+
},
|
|
2256
|
+
openSession
|
|
1459
2257
|
});
|
|
1460
|
-
const sessionId = pendingSessionBinding.sessionId;
|
|
1461
2258
|
setPendingSessionBinding(void 0);
|
|
1462
|
-
|
|
1463
|
-
await
|
|
1464
|
-
openSession(sessionId);
|
|
2259
|
+
await refresh({ preserveCurrent: true });
|
|
2260
|
+
await invalidateWorktreeContext?.(pending.workspaceId);
|
|
1465
2261
|
} catch (error) {
|
|
2262
|
+
if (error instanceof WorktreeSessionBindingError && !error.retryable) setPendingSessionBinding(void 0);
|
|
1466
2263
|
setActionError(toWorktreeViewError(error));
|
|
1467
2264
|
} finally {
|
|
1468
2265
|
setActionPending(false);
|
|
@@ -1556,7 +2353,7 @@ window.__ModuleLoader__.load({
|
|
|
1556
2353
|
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
1557
2354
|
type: "button",
|
|
1558
2355
|
className: worktree_css_default.actionButton,
|
|
1559
|
-
disabled: actionPending,
|
|
2356
|
+
disabled: actionPending || pendingSessionArchived,
|
|
1560
2357
|
onClick: () => {
|
|
1561
2358
|
retrySessionBinding();
|
|
1562
2359
|
},
|
|
@@ -1612,14 +2409,17 @@ window.__ModuleLoader__.load({
|
|
|
1612
2409
|
children: t("workspace.noMatches")
|
|
1613
2410
|
}) : visibleWorkspaces.map((workspace) => {
|
|
1614
2411
|
const view = viewByWorkspace.get(workspace.workspaceId);
|
|
2412
|
+
const currentBranch = view?.branches.find((branch) => branch.isCurrent)?.name;
|
|
2413
|
+
const mainLabel = currentBranch === void 0 ? t("worktree.main") : t("worktree.mainWithBranch", { branch: currentBranch });
|
|
1615
2414
|
const expanded = expandedWorkspaces[workspace.workspaceId] !== false;
|
|
1616
2415
|
const workspaceMatchesQuery = includesText(workspace.title, query);
|
|
1617
2416
|
const allWorkspaceSessionIds = filterArchivedSessionIds(workspaceSessionIds(workspaces, workspace.workspaceId, sessions.ids), archivedSessionIds);
|
|
1618
2417
|
const bindings = view?.bindings ?? [];
|
|
1619
|
-
const visibleMainSessionIds = unboundSessionIds(allWorkspaceSessionIds, [...new Set(bindings.map((binding) => binding.sessionId))]).filter((sessionId) => workspaceMatchesQuery ||
|
|
2418
|
+
const visibleMainSessionIds = filterVisibleSessionIds(unboundSessionIds(allWorkspaceSessionIds, [...new Set(bindings.map((binding) => binding.sessionId))]), sessions).filter((sessionId) => workspaceMatchesQuery || sessionMatchesQuery(sessionId, sessions, query));
|
|
1620
2419
|
const mainExpanded = expandedMains[workspace.workspaceId] !== false;
|
|
1621
2420
|
const mainGroupKey = `main:${workspace.workspaceId}`;
|
|
1622
2421
|
const worktrees = view?.worktrees ?? [];
|
|
2422
|
+
const sameWorkspaceWorktreeDrag = worktreeDrag?.workspaceId === workspace.workspaceId;
|
|
1623
2423
|
return (0, react_jsx_runtime.jsxs)("section", {
|
|
1624
2424
|
className: worktree_css_default.workspaceGroup,
|
|
1625
2425
|
"data-workspace-id": workspace.workspaceId,
|
|
@@ -1682,7 +2482,7 @@ window.__ModuleLoader__.load({
|
|
|
1682
2482
|
(0, react_jsx_runtime.jsx)(WorktreeGroupRow, {
|
|
1683
2483
|
t,
|
|
1684
2484
|
kind: "main",
|
|
1685
|
-
label:
|
|
2485
|
+
label: mainLabel,
|
|
1686
2486
|
expanded: mainExpanded,
|
|
1687
2487
|
icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBranchOutline16, {}),
|
|
1688
2488
|
workspaceTitle: workspace.title,
|
|
@@ -1744,10 +2544,10 @@ window.__ModuleLoader__.load({
|
|
|
1744
2544
|
children: t("worktree.noWorktrees")
|
|
1745
2545
|
}),
|
|
1746
2546
|
worktrees.map((record) => {
|
|
1747
|
-
const worktreeSessionIds = filterArchivedSessionIds(bindingIdsFor(bindings, record.worktreeId).filter((sessionId) => sessions.ids.includes(sessionId)), archivedSessionIds);
|
|
2547
|
+
const worktreeSessionIds = filterVisibleSessionIds(filterArchivedSessionIds(bindingIdsFor(bindings, record.worktreeId).filter((sessionId) => sessions.ids.includes(sessionId)), archivedSessionIds), sessions);
|
|
1748
2548
|
const worktreeMatchesQuery = workspaceMatchesQuery || includesText(record.branch, query) || includesText(record.absolutePath, query);
|
|
1749
|
-
if (query.length > 0 && !worktreeMatchesQuery && !worktreeSessionIds.some((sessionId) =>
|
|
1750
|
-
const visibleWorktreeSessionIds = worktreeSessionIds.filter((sessionId) => worktreeMatchesQuery ||
|
|
2549
|
+
if (query.length > 0 && !worktreeMatchesQuery && !worktreeSessionIds.some((sessionId) => sessionMatchesQuery(sessionId, sessions, query))) return null;
|
|
2550
|
+
const visibleWorktreeSessionIds = worktreeSessionIds.filter((sessionId) => worktreeMatchesQuery || sessionMatchesQuery(sessionId, sessions, query));
|
|
1751
2551
|
const worktreeGroupKey = `worktree:${record.worktreeId}`;
|
|
1752
2552
|
const state = record.status === "removed" ? "warning" : record.health === "repair" ? "error" : "done";
|
|
1753
2553
|
const stateLabel = record.status === "removed" ? t("worktree.detached") : record.health === "repair" ? t("worktree.repair") : t("worktree.ready");
|
|
@@ -1759,6 +2559,7 @@ window.__ModuleLoader__.load({
|
|
|
1759
2559
|
t,
|
|
1760
2560
|
kind: "worktree",
|
|
1761
2561
|
label: record.branch,
|
|
2562
|
+
worktreeId: record.worktreeId,
|
|
1762
2563
|
expanded: worktreeExpanded,
|
|
1763
2564
|
icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBranchOutline16, {}),
|
|
1764
2565
|
workspaceTitle: workspace.title,
|
|
@@ -1767,7 +2568,7 @@ window.__ModuleLoader__.load({
|
|
|
1767
2568
|
onToggle: () => {
|
|
1768
2569
|
toggleWorktree(record.worktreeId);
|
|
1769
2570
|
},
|
|
1770
|
-
onCreateSession: record.status === "active" ? () => {
|
|
2571
|
+
onCreateSession: record.status === "active" && record.health !== "repair" ? () => {
|
|
1771
2572
|
createSession({
|
|
1772
2573
|
workspaceId: record.workspaceId,
|
|
1773
2574
|
worktreeId: record.worktreeId,
|
|
@@ -1785,7 +2586,39 @@ window.__ModuleLoader__.load({
|
|
|
1785
2586
|
setWorktreeRemoval(record);
|
|
1786
2587
|
setActionError(void 0);
|
|
1787
2588
|
}
|
|
1788
|
-
} : void 0
|
|
2589
|
+
} : void 0,
|
|
2590
|
+
drag: {
|
|
2591
|
+
active: sameWorkspaceWorktreeDrag,
|
|
2592
|
+
marker: worktreeDrag?.over?.worktreeId === record.worktreeId ? worktreeDrag.over.half : null,
|
|
2593
|
+
start: () => {
|
|
2594
|
+
worktreeDropCommitted.current = false;
|
|
2595
|
+
setWorktreeDrag({
|
|
2596
|
+
workspaceId: workspace.workspaceId,
|
|
2597
|
+
worktreeId: record.worktreeId,
|
|
2598
|
+
over: null
|
|
2599
|
+
});
|
|
2600
|
+
},
|
|
2601
|
+
hover: (half) => {
|
|
2602
|
+
setWorktreeDrag((current) => current === void 0 || current.workspaceId !== workspace.workspaceId ? current : {
|
|
2603
|
+
...current,
|
|
2604
|
+
over: {
|
|
2605
|
+
worktreeId: record.worktreeId,
|
|
2606
|
+
half
|
|
2607
|
+
}
|
|
2608
|
+
});
|
|
2609
|
+
},
|
|
2610
|
+
drop: (half) => {
|
|
2611
|
+
if (worktreeDrag === void 0) return;
|
|
2612
|
+
commitWorktreeDrag(worktreeDrag, {
|
|
2613
|
+
worktreeId: record.worktreeId,
|
|
2614
|
+
half
|
|
2615
|
+
}, worktrees.map((candidate) => candidate.worktreeId), workspace.workspaceId);
|
|
2616
|
+
},
|
|
2617
|
+
end: () => {
|
|
2618
|
+
setWorktreeDrag(void 0);
|
|
2619
|
+
worktreeDropCommitted.current = false;
|
|
2620
|
+
}
|
|
2621
|
+
}
|
|
1789
2622
|
}), worktreeExpanded && (0, react_jsx_runtime.jsx)(WorktreeSessionGroup, {
|
|
1790
2623
|
t,
|
|
1791
2624
|
groupKey: worktreeGroupKey,
|
|
@@ -1855,232 +2688,318 @@ window.__ModuleLoader__.load({
|
|
|
1855
2688
|
children: "WT"
|
|
1856
2689
|
})
|
|
1857
2690
|
}),
|
|
1858
|
-
(0, react_jsx_runtime.
|
|
1859
|
-
|
|
2691
|
+
(0, react_jsx_runtime.jsx)(WorktreeSessionRenameDialog, {
|
|
2692
|
+
t,
|
|
2693
|
+
target: sessionRenameTarget,
|
|
2694
|
+
draft: sessionRenameDraft,
|
|
2695
|
+
pending: sessionRenamePending,
|
|
2696
|
+
error: sessionRenameError,
|
|
1860
2697
|
onClose: closeSessionRename,
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
onClick: closeSessionRename,
|
|
1867
|
-
children: t("dialog.cancel")
|
|
1868
|
-
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1869
|
-
variant: "primary",
|
|
1870
|
-
disabled: sessionRenamePending || sessionRenameDraft.trim().length === 0,
|
|
1871
|
-
onClick: () => {
|
|
1872
|
-
confirmSessionRename();
|
|
1873
|
-
},
|
|
1874
|
-
children: t("dialog.rename")
|
|
1875
|
-
})] }),
|
|
1876
|
-
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
|
|
1877
|
-
className: worktree_css_default.renameInput,
|
|
1878
|
-
value: sessionRenameDraft,
|
|
1879
|
-
"aria-label": t("session.name"),
|
|
1880
|
-
autoFocus: true,
|
|
1881
|
-
disabled: sessionRenamePending,
|
|
1882
|
-
onFocus: (event) => {
|
|
1883
|
-
event.currentTarget.select();
|
|
1884
|
-
},
|
|
1885
|
-
onChange: (event) => {
|
|
1886
|
-
setSessionRenameDraft(event.currentTarget.value);
|
|
1887
|
-
setSessionRenameError(void 0);
|
|
1888
|
-
},
|
|
1889
|
-
onKeyDown: (event) => {
|
|
1890
|
-
if (event.key === "Enter" && !event.nativeEvent.isComposing) {
|
|
1891
|
-
event.preventDefault();
|
|
1892
|
-
confirmSessionRename();
|
|
1893
|
-
}
|
|
1894
|
-
}
|
|
1895
|
-
}), sessionRenameError !== void 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
1896
|
-
className: worktree_css_default.renameError,
|
|
1897
|
-
role: "alert",
|
|
1898
|
-
children: formatWorktreeViewError(sessionRenameError, t)
|
|
1899
|
-
})]
|
|
2698
|
+
onDraftChange: (draft) => {
|
|
2699
|
+
setSessionRenameDraft(draft);
|
|
2700
|
+
setSessionRenameError(void 0);
|
|
2701
|
+
},
|
|
2702
|
+
onSubmit: confirmSessionRename
|
|
1900
2703
|
}),
|
|
1901
|
-
|
|
1902
|
-
|
|
2704
|
+
(0, react_jsx_runtime.jsx)(WorktreeWorkspaceRenameDialog, {
|
|
2705
|
+
t,
|
|
2706
|
+
target: workspaceRenameTarget,
|
|
2707
|
+
draft: workspaceRenameDraft,
|
|
2708
|
+
pending: workspaceRenamePending,
|
|
2709
|
+
duplicate: workspaceRenameDuplicate,
|
|
2710
|
+
error: workspaceRenameError,
|
|
1903
2711
|
onClose: closeWorkspaceRename,
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
onClick: closeWorkspaceRename,
|
|
1910
|
-
children: t("dialog.cancel")
|
|
1911
|
-
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1912
|
-
variant: "primary",
|
|
1913
|
-
disabled: workspaceRenameBlocked,
|
|
1914
|
-
onClick: () => {
|
|
1915
|
-
confirmWorkspaceRename();
|
|
1916
|
-
},
|
|
1917
|
-
children: t("dialog.rename")
|
|
1918
|
-
})] }),
|
|
1919
|
-
children: [
|
|
1920
|
-
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
|
|
1921
|
-
className: worktree_css_default.renameInput,
|
|
1922
|
-
value: workspaceRenameDraft,
|
|
1923
|
-
"aria-label": t("workspace.name"),
|
|
1924
|
-
autoFocus: true,
|
|
1925
|
-
disabled: workspaceRenamePending,
|
|
1926
|
-
onFocus: (event) => {
|
|
1927
|
-
event.currentTarget.select();
|
|
1928
|
-
},
|
|
1929
|
-
onChange: (event) => {
|
|
1930
|
-
setWorkspaceRenameDraft(event.currentTarget.value);
|
|
1931
|
-
setWorkspaceRenameError(void 0);
|
|
1932
|
-
},
|
|
1933
|
-
onKeyDown: (event) => {
|
|
1934
|
-
if (event.key === "Enter" && !event.nativeEvent.isComposing) {
|
|
1935
|
-
event.preventDefault();
|
|
1936
|
-
confirmWorkspaceRename();
|
|
1937
|
-
}
|
|
1938
|
-
}
|
|
1939
|
-
}),
|
|
1940
|
-
workspaceRenameDuplicate && (0, react_jsx_runtime.jsx)("p", {
|
|
1941
|
-
className: worktree_css_default.renameError,
|
|
1942
|
-
role: "alert",
|
|
1943
|
-
children: t("workspace.duplicate")
|
|
1944
|
-
}),
|
|
1945
|
-
workspaceRenameError !== void 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
1946
|
-
className: worktree_css_default.renameError,
|
|
1947
|
-
role: "alert",
|
|
1948
|
-
children: formatWorktreeViewError(workspaceRenameError, t)
|
|
1949
|
-
})
|
|
1950
|
-
]
|
|
2712
|
+
onDraftChange: (draft) => {
|
|
2713
|
+
setWorkspaceRenameDraft(draft);
|
|
2714
|
+
setWorkspaceRenameError(void 0);
|
|
2715
|
+
},
|
|
2716
|
+
onSubmit: confirmWorkspaceRename
|
|
1951
2717
|
}),
|
|
1952
|
-
|
|
1953
|
-
|
|
2718
|
+
(0, react_jsx_runtime.jsx)(WorktreeWorkspaceDeleteDialog, {
|
|
2719
|
+
t,
|
|
2720
|
+
target: workspaceDeleteTarget,
|
|
2721
|
+
pending: workspaceDeletePending,
|
|
2722
|
+
error: workspaceDeleteError,
|
|
1954
2723
|
onClose: closeWorkspaceDelete,
|
|
1955
|
-
|
|
1956
|
-
title: t("workspace.deleteTitle"),
|
|
1957
|
-
description: t("workspace.deleteDescription", { name: workspaceDeleteTarget.title }),
|
|
1958
|
-
footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1959
|
-
variant: "outline",
|
|
1960
|
-
disabled: workspaceDeletePending,
|
|
1961
|
-
onClick: closeWorkspaceDelete,
|
|
1962
|
-
children: t("dialog.cancel")
|
|
1963
|
-
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1964
|
-
variant: "outline",
|
|
1965
|
-
disabled: workspaceDeletePending,
|
|
1966
|
-
onClick: () => {
|
|
1967
|
-
confirmWorkspaceDelete();
|
|
1968
|
-
},
|
|
1969
|
-
children: t("dialog.delete")
|
|
1970
|
-
})] }),
|
|
1971
|
-
children: workspaceDeleteError !== void 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
1972
|
-
className: worktree_css_default.renameError,
|
|
1973
|
-
role: "alert",
|
|
1974
|
-
children: formatWorktreeViewError(workspaceDeleteError, t)
|
|
1975
|
-
})
|
|
2724
|
+
onSubmit: confirmWorkspaceDelete
|
|
1976
2725
|
}),
|
|
1977
|
-
|
|
1978
|
-
|
|
2726
|
+
(0, react_jsx_runtime.jsx)(WorktreeCreateDialog, {
|
|
2727
|
+
t,
|
|
2728
|
+
workspace: modalWorkspace,
|
|
2729
|
+
view: modalView,
|
|
2730
|
+
setupStatus: modalSetupStatus,
|
|
2731
|
+
canCreate: modalCanCreate,
|
|
2732
|
+
selectedBranch,
|
|
2733
|
+
newBranch,
|
|
2734
|
+
actionPending,
|
|
1979
2735
|
onClose: () => {
|
|
1980
|
-
if (actionPending) return;
|
|
1981
2736
|
setWorktreeModalWorkspaceId(void 0);
|
|
1982
2737
|
},
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1987
|
-
variant: "outline",
|
|
1988
|
-
disabled: actionPending,
|
|
1989
|
-
onClick: () => {
|
|
1990
|
-
setWorktreeModalWorkspaceId(void 0);
|
|
1991
|
-
},
|
|
1992
|
-
children: t("dialog.cancel")
|
|
1993
|
-
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1994
|
-
variant: "primary",
|
|
1995
|
-
disabled: actionPending || selectedBranch.length === 0 || newBranch.trim().length === 0,
|
|
1996
|
-
onClick: () => {
|
|
1997
|
-
submitWorktree();
|
|
1998
|
-
},
|
|
1999
|
-
children: t("worktree.create")
|
|
2000
|
-
})] }),
|
|
2001
|
-
children: [
|
|
2002
|
-
(0, react_jsx_runtime.jsxs)("label", {
|
|
2003
|
-
className: worktree_css_default.modalField,
|
|
2004
|
-
children: [t("worktree.baseBranch"), (0, react_jsx_runtime.jsxs)("select", {
|
|
2005
|
-
className: worktree_css_default.actionSelect,
|
|
2006
|
-
"aria-label": t("worktree.baseBranch"),
|
|
2007
|
-
value: selectedBranch,
|
|
2008
|
-
disabled: actionPending,
|
|
2009
|
-
onChange: (event) => {
|
|
2010
|
-
setSelectedBranch(event.currentTarget.value);
|
|
2011
|
-
},
|
|
2012
|
-
children: [(0, react_jsx_runtime.jsx)("option", {
|
|
2013
|
-
value: "",
|
|
2014
|
-
children: t("worktree.noLocalBranch")
|
|
2015
|
-
}), (modalView?.branches ?? []).map((branch) => (0, react_jsx_runtime.jsxs)("option", {
|
|
2016
|
-
value: branch.name,
|
|
2017
|
-
children: [
|
|
2018
|
-
branch.name,
|
|
2019
|
-
branch.isCurrent ? t("branch.current") : "",
|
|
2020
|
-
branch.checkedOut ? t("branch.checkedOut") : ""
|
|
2021
|
-
]
|
|
2022
|
-
}, branch.name))]
|
|
2023
|
-
})]
|
|
2024
|
-
}),
|
|
2025
|
-
(0, react_jsx_runtime.jsxs)("label", {
|
|
2026
|
-
className: worktree_css_default.modalField,
|
|
2027
|
-
children: [t("worktree.name"), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
|
|
2028
|
-
className: worktree_css_default.renameInput,
|
|
2029
|
-
"aria-label": t("worktree.name"),
|
|
2030
|
-
value: newBranch,
|
|
2031
|
-
placeholder: "dsh/12345678",
|
|
2032
|
-
disabled: actionPending,
|
|
2033
|
-
onChange: (event) => {
|
|
2034
|
-
setNewBranch(event.currentTarget.value);
|
|
2035
|
-
}
|
|
2036
|
-
})]
|
|
2037
|
-
}),
|
|
2038
|
-
modalView?.branches.length === 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
2039
|
-
className: worktree_css_default.empty,
|
|
2040
|
-
children: t("worktree.noBranches")
|
|
2041
|
-
})
|
|
2042
|
-
]
|
|
2738
|
+
onSelectedBranchChange: setSelectedBranch,
|
|
2739
|
+
onNewBranchChange: setNewBranch,
|
|
2740
|
+
onSubmit: submitWorktree
|
|
2043
2741
|
}),
|
|
2044
|
-
|
|
2045
|
-
|
|
2742
|
+
(0, react_jsx_runtime.jsx)(WorktreeRemovalDialog, {
|
|
2743
|
+
t,
|
|
2744
|
+
worktree: worktreeRemoval,
|
|
2745
|
+
actionPending,
|
|
2046
2746
|
onClose: () => {
|
|
2047
|
-
if (actionPending) return;
|
|
2048
2747
|
setWorktreeRemoval(void 0);
|
|
2049
2748
|
},
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2061
|
-
variant: "primary",
|
|
2062
|
-
disabled: actionPending,
|
|
2063
|
-
onClick: () => {
|
|
2064
|
-
if (manager === void 0) return;
|
|
2065
|
-
const target = worktreeRemoval;
|
|
2066
|
-
runMutation(async () => {
|
|
2067
|
-
await executeWorktreeAction(manager, {
|
|
2068
|
-
type: "removeWorktree",
|
|
2069
|
-
input: {
|
|
2070
|
-
workspaceId: target.workspaceId,
|
|
2071
|
-
worktreeId: target.worktreeId
|
|
2072
|
-
}
|
|
2073
|
-
});
|
|
2074
|
-
setWorktreeRemoval(void 0);
|
|
2749
|
+
onSubmit: () => {
|
|
2750
|
+
if (manager === void 0 || worktreeRemoval === void 0) return;
|
|
2751
|
+
const target = worktreeRemoval;
|
|
2752
|
+
runMutation(async () => {
|
|
2753
|
+
await executeWorktreeAction(manager, {
|
|
2754
|
+
type: "removeWorktree",
|
|
2755
|
+
input: {
|
|
2756
|
+
workspaceId: target.workspaceId,
|
|
2757
|
+
worktreeId: target.worktreeId
|
|
2758
|
+
}
|
|
2075
2759
|
});
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2760
|
+
await invalidateWorktreeContext?.(target.workspaceId);
|
|
2761
|
+
setWorktreeRemoval(void 0);
|
|
2762
|
+
});
|
|
2763
|
+
}
|
|
2079
2764
|
})
|
|
2080
2765
|
]
|
|
2081
2766
|
});
|
|
2082
2767
|
}
|
|
2083
2768
|
//#endregion
|
|
2769
|
+
//#region lib/client/WorktreeOverlay.js
|
|
2770
|
+
/** Compose the independent Hero context and Worktree navigation overlays. */
|
|
2771
|
+
function WorktreeOverlay(props) {
|
|
2772
|
+
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(WorktreeHeroContext, { ...props }), (0, react_jsx_runtime.jsx)(WorktreeSurface, { ...props })] });
|
|
2773
|
+
}
|
|
2774
|
+
//#endregion
|
|
2775
|
+
//#region lib/client/worktree-context.js
|
|
2776
|
+
const none = (reason) => ({
|
|
2777
|
+
kind: "none",
|
|
2778
|
+
reason
|
|
2779
|
+
});
|
|
2780
|
+
/** Resolve the branch or active Worktree label for one current DSH Session. */
|
|
2781
|
+
function resolveWorktreeSessionContext(input) {
|
|
2782
|
+
const sessionId = input.currentSessionId;
|
|
2783
|
+
if (sessionId === void 0 && input.currentWorkspaceId === void 0) return none("no-session");
|
|
2784
|
+
const workspace = sessionId === void 0 ? input.workspaces.find(({ workspaceId }) => workspaceId === input.currentWorkspaceId) : input.workspaces.find(({ sessionIds }) => sessionIds.includes(sessionId));
|
|
2785
|
+
if (workspace === void 0) return none("unbound");
|
|
2786
|
+
const binding = sessionId === void 0 ? void 0 : input.bindings.find((candidate) => candidate.sessionId === sessionId);
|
|
2787
|
+
if (binding !== void 0) {
|
|
2788
|
+
if (binding.workspaceId !== workspace.workspaceId) return none("workspace-mismatch");
|
|
2789
|
+
if (binding.status === "detached") return none("detached");
|
|
2790
|
+
const record = input.worktrees.find((candidate) => candidate.worktreeId === binding.worktreeId);
|
|
2791
|
+
if (record === void 0 || record.workspaceId !== workspace.workspaceId) return none(record === void 0 ? "stale" : "workspace-mismatch");
|
|
2792
|
+
if (record.status !== "active") return none("stale");
|
|
2793
|
+
if (record.health === "repair") return none("repair");
|
|
2794
|
+
if (record.branch.length === 0) return none("not-ready");
|
|
2795
|
+
return {
|
|
2796
|
+
kind: "worktree",
|
|
2797
|
+
workspaceId: workspace.workspaceId,
|
|
2798
|
+
worktreeId: record.worktreeId,
|
|
2799
|
+
label: record.branch,
|
|
2800
|
+
source: "active-binding"
|
|
2801
|
+
};
|
|
2802
|
+
}
|
|
2803
|
+
const currentBranch = input.branches.find(({ isCurrent }) => isCurrent);
|
|
2804
|
+
if (currentBranch === void 0 || currentBranch.name.length === 0) return none("not-ready");
|
|
2805
|
+
return {
|
|
2806
|
+
kind: "main",
|
|
2807
|
+
workspaceId: workspace.workspaceId,
|
|
2808
|
+
label: currentBranch.name,
|
|
2809
|
+
source: "current-branch"
|
|
2810
|
+
};
|
|
2811
|
+
}
|
|
2812
|
+
//#endregion
|
|
2813
|
+
//#region lib/client/worktree-context-store.js
|
|
2814
|
+
const notReady = () => ({
|
|
2815
|
+
kind: "none",
|
|
2816
|
+
reason: "not-ready"
|
|
2817
|
+
});
|
|
2818
|
+
function scheduledRefresh() {
|
|
2819
|
+
let resolve;
|
|
2820
|
+
return {
|
|
2821
|
+
promise: new Promise((resolvePromise) => {
|
|
2822
|
+
resolve = resolvePromise;
|
|
2823
|
+
}),
|
|
2824
|
+
resolve
|
|
2825
|
+
};
|
|
2826
|
+
}
|
|
2827
|
+
function identityFrom(sessions, workspaces) {
|
|
2828
|
+
const sessionId = sessions.getSnapshot().current;
|
|
2829
|
+
if (sessionId === void 0) return { workspaceId: workspaces.getSnapshot().recentWorkspaceId };
|
|
2830
|
+
return {
|
|
2831
|
+
sessionId,
|
|
2832
|
+
workspaceId: workspaces.getSnapshot().items.find((candidate) => candidate.sessionIds.includes(sessionId))?.workspaceId
|
|
2833
|
+
};
|
|
2834
|
+
}
|
|
2835
|
+
/**
|
|
2836
|
+
* Build one browser-local current-Session projection shared by the header
|
|
2837
|
+
* consumer. Superseded requests may still finish on the transport, but their
|
|
2838
|
+
* results never become visible in the current snapshot.
|
|
2839
|
+
*/
|
|
2840
|
+
function createWorktreeContextProjection(input) {
|
|
2841
|
+
const store = input.storeFactory({
|
|
2842
|
+
status: "idle",
|
|
2843
|
+
value: notReady()
|
|
2844
|
+
});
|
|
2845
|
+
let disposed = false;
|
|
2846
|
+
let generation = 0;
|
|
2847
|
+
let scheduled = false;
|
|
2848
|
+
let scheduleTicket = 0;
|
|
2849
|
+
let scheduledCompletion;
|
|
2850
|
+
let latestRefresh = Promise.resolve();
|
|
2851
|
+
const setPending = (identity) => {
|
|
2852
|
+
if (identity.workspaceId === void 0) {
|
|
2853
|
+
store.set({
|
|
2854
|
+
status: "ready",
|
|
2855
|
+
value: resolveWorktreeSessionContext({
|
|
2856
|
+
currentSessionId: identity.sessionId,
|
|
2857
|
+
currentWorkspaceId: identity.workspaceId,
|
|
2858
|
+
workspaces: input.workspaces.getSnapshot().items,
|
|
2859
|
+
branches: [],
|
|
2860
|
+
worktrees: [],
|
|
2861
|
+
bindings: []
|
|
2862
|
+
})
|
|
2863
|
+
});
|
|
2864
|
+
return;
|
|
2865
|
+
}
|
|
2866
|
+
const workspace = input.workspaces.getSnapshot().items.find((candidate) => candidate.workspaceId === identity.workspaceId);
|
|
2867
|
+
store.set({
|
|
2868
|
+
status: "loading",
|
|
2869
|
+
...identity.sessionId === void 0 ? {} : { sessionId: identity.sessionId },
|
|
2870
|
+
workspaceId: identity.workspaceId,
|
|
2871
|
+
workspaceTitle: workspace?.title,
|
|
2872
|
+
value: notReady()
|
|
2873
|
+
});
|
|
2874
|
+
};
|
|
2875
|
+
const matchesCurrent = (request, requestGeneration) => {
|
|
2876
|
+
if (disposed || generation !== requestGeneration) return false;
|
|
2877
|
+
const current = identityFrom(input.sessions, input.workspaces);
|
|
2878
|
+
return current.sessionId === request.sessionId && current.workspaceId === request.workspaceId;
|
|
2879
|
+
};
|
|
2880
|
+
const runRefresh = async () => {
|
|
2881
|
+
if (disposed) return;
|
|
2882
|
+
const requestGeneration = ++generation;
|
|
2883
|
+
const identity = identityFrom(input.sessions, input.workspaces);
|
|
2884
|
+
setPending(identity);
|
|
2885
|
+
if (identity.workspaceId === void 0) return;
|
|
2886
|
+
const request = {
|
|
2887
|
+
sessionId: identity.sessionId,
|
|
2888
|
+
workspaceId: identity.workspaceId
|
|
2889
|
+
};
|
|
2890
|
+
try {
|
|
2891
|
+
const data = await loadWorktreeView(input.manager, request.workspaceId);
|
|
2892
|
+
if (!matchesCurrent(request, requestGeneration)) return;
|
|
2893
|
+
const workspace = input.workspaces.getSnapshot().items.find((candidate) => candidate.workspaceId === request.workspaceId);
|
|
2894
|
+
if ("error" in data.readiness) {
|
|
2895
|
+
store.set({
|
|
2896
|
+
status: "error",
|
|
2897
|
+
...request.sessionId === void 0 ? {} : { sessionId: request.sessionId },
|
|
2898
|
+
workspaceId: request.workspaceId,
|
|
2899
|
+
workspaceTitle: workspace?.title,
|
|
2900
|
+
value: notReady(),
|
|
2901
|
+
error: data.readiness.error
|
|
2902
|
+
});
|
|
2903
|
+
return;
|
|
2904
|
+
}
|
|
2905
|
+
store.set({
|
|
2906
|
+
status: "ready",
|
|
2907
|
+
...request.sessionId === void 0 ? {} : { sessionId: request.sessionId },
|
|
2908
|
+
workspaceId: request.workspaceId,
|
|
2909
|
+
workspaceTitle: workspace?.title,
|
|
2910
|
+
value: resolveWorktreeSessionContext({
|
|
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
|
+
})
|
|
2918
|
+
});
|
|
2919
|
+
} catch (error) {
|
|
2920
|
+
if (!matchesCurrent(request, requestGeneration)) return;
|
|
2921
|
+
store.set({
|
|
2922
|
+
status: "error",
|
|
2923
|
+
...request.sessionId === void 0 ? {} : { sessionId: request.sessionId },
|
|
2924
|
+
workspaceId: request.workspaceId,
|
|
2925
|
+
workspaceTitle: input.workspaces.getSnapshot().items.find((candidate) => candidate.workspaceId === request.workspaceId)?.title,
|
|
2926
|
+
value: notReady(),
|
|
2927
|
+
error: toWorktreeViewError(error)
|
|
2928
|
+
});
|
|
2929
|
+
}
|
|
2930
|
+
};
|
|
2931
|
+
const cancelScheduledRefresh = () => {
|
|
2932
|
+
scheduleTicket += 1;
|
|
2933
|
+
scheduled = false;
|
|
2934
|
+
const completion = scheduledCompletion;
|
|
2935
|
+
scheduledCompletion = void 0;
|
|
2936
|
+
completion?.resolve();
|
|
2937
|
+
};
|
|
2938
|
+
const refresh = () => {
|
|
2939
|
+
cancelScheduledRefresh();
|
|
2940
|
+
const completion = runRefresh();
|
|
2941
|
+
latestRefresh = completion;
|
|
2942
|
+
return completion;
|
|
2943
|
+
};
|
|
2944
|
+
const scheduleRefresh = () => {
|
|
2945
|
+
if (disposed) return;
|
|
2946
|
+
generation += 1;
|
|
2947
|
+
if (scheduled) return;
|
|
2948
|
+
setPending(identityFrom(input.sessions, input.workspaces));
|
|
2949
|
+
scheduled = true;
|
|
2950
|
+
const ticket = ++scheduleTicket;
|
|
2951
|
+
const completion = scheduledRefresh();
|
|
2952
|
+
scheduledCompletion = completion;
|
|
2953
|
+
latestRefresh = completion.promise;
|
|
2954
|
+
queueMicrotask(() => {
|
|
2955
|
+
if (disposed || ticket !== scheduleTicket) {
|
|
2956
|
+
completion.resolve();
|
|
2957
|
+
return;
|
|
2958
|
+
}
|
|
2959
|
+
scheduled = false;
|
|
2960
|
+
runRefresh().finally(() => {
|
|
2961
|
+
if (scheduledCompletion === completion) scheduledCompletion = void 0;
|
|
2962
|
+
completion.resolve();
|
|
2963
|
+
});
|
|
2964
|
+
});
|
|
2965
|
+
};
|
|
2966
|
+
const waitForLatestRefresh = async (workspaceId) => {
|
|
2967
|
+
let observed;
|
|
2968
|
+
while (!disposed) {
|
|
2969
|
+
if (workspaceId !== void 0 && identityFrom(input.sessions, input.workspaces).workspaceId !== workspaceId) return;
|
|
2970
|
+
const completion = latestRefresh;
|
|
2971
|
+
if (completion === observed) return;
|
|
2972
|
+
observed = completion;
|
|
2973
|
+
await completion;
|
|
2974
|
+
}
|
|
2975
|
+
};
|
|
2976
|
+
const unsubscribeSessions = input.sessions.subscribe(scheduleRefresh);
|
|
2977
|
+
const unsubscribeWorkspaces = input.workspaces.subscribe(scheduleRefresh);
|
|
2978
|
+
return {
|
|
2979
|
+
store,
|
|
2980
|
+
refresh,
|
|
2981
|
+
async invalidate(workspaceId) {
|
|
2982
|
+
if (disposed) return;
|
|
2983
|
+
const identity = identityFrom(input.sessions, input.workspaces);
|
|
2984
|
+
if (workspaceId !== void 0 && workspaceId !== identity.workspaceId) return;
|
|
2985
|
+
await refresh();
|
|
2986
|
+
await waitForLatestRefresh(workspaceId ?? identity.workspaceId);
|
|
2987
|
+
},
|
|
2988
|
+
dispose() {
|
|
2989
|
+
if (disposed) return;
|
|
2990
|
+
disposed = true;
|
|
2991
|
+
generation += 1;
|
|
2992
|
+
cancelScheduledRefresh();
|
|
2993
|
+
unsubscribeSessions();
|
|
2994
|
+
unsubscribeWorkspaces();
|
|
2995
|
+
store.set({
|
|
2996
|
+
status: "idle",
|
|
2997
|
+
value: notReady()
|
|
2998
|
+
});
|
|
2999
|
+
}
|
|
3000
|
+
};
|
|
3001
|
+
}
|
|
3002
|
+
//#endregion
|
|
2084
3003
|
//#region lib/client/view-mode-store.js
|
|
2085
3004
|
/** Create one root-scoped, browser-local view-mode store for the two slot entries. */
|
|
2086
3005
|
function createWorktreeViewStore() {
|
|
@@ -2122,17 +3041,24 @@ window.__ModuleLoader__.load({
|
|
|
2122
3041
|
let bindings = [];
|
|
2123
3042
|
let disposed = false;
|
|
2124
3043
|
let applying = false;
|
|
2125
|
-
const
|
|
2126
|
-
|
|
2127
|
-
const next = projectVirtualWorkspaceMembership(current, bindings, nextBindings);
|
|
2128
|
-
if (sameWorkspaceItems(current, next)) return;
|
|
3044
|
+
const nativeSet = list.set;
|
|
3045
|
+
const write = (next) => {
|
|
2129
3046
|
applying = true;
|
|
2130
3047
|
try {
|
|
2131
|
-
|
|
3048
|
+
nativeSet(next);
|
|
2132
3049
|
} finally {
|
|
2133
3050
|
applying = false;
|
|
2134
3051
|
}
|
|
2135
3052
|
};
|
|
3053
|
+
list.set = (next) => {
|
|
3054
|
+
write(projectVirtualWorkspaceMembership(next, bindings, bindings));
|
|
3055
|
+
};
|
|
3056
|
+
const apply = (nextBindings) => {
|
|
3057
|
+
const current = list.getSnapshot();
|
|
3058
|
+
const next = projectVirtualWorkspaceMembership(current, bindings, nextBindings);
|
|
3059
|
+
if (sameWorkspaceItems(current, next)) return;
|
|
3060
|
+
write(next);
|
|
3061
|
+
};
|
|
2136
3062
|
const replay = () => {
|
|
2137
3063
|
if (disposed || applying) return;
|
|
2138
3064
|
apply(bindings);
|
|
@@ -2160,6 +3086,7 @@ window.__ModuleLoader__.load({
|
|
|
2160
3086
|
bindings = [];
|
|
2161
3087
|
disposed = true;
|
|
2162
3088
|
unsubscribe();
|
|
3089
|
+
list.set = nativeSet;
|
|
2163
3090
|
}
|
|
2164
3091
|
};
|
|
2165
3092
|
}
|
|
@@ -2185,8 +3112,16 @@ window.__ModuleLoader__.load({
|
|
|
2185
3112
|
const manager = createWorktreeConnectionAdapter(ctx.connection.rpc);
|
|
2186
3113
|
const sessions = ctx.sessions;
|
|
2187
3114
|
const virtualWorkspaceMembership = createVirtualWorkspaceMembership(ctx.workspaces.list);
|
|
3115
|
+
const contextProjection = createWorktreeContextProjection({
|
|
3116
|
+
sessions: ctx.sessions.list,
|
|
3117
|
+
workspaces: ctx.workspaces.list,
|
|
3118
|
+
manager,
|
|
3119
|
+
storeFactory: _deepseek_ai_dsh_client_runtime_client.createSnapshotStore
|
|
3120
|
+
});
|
|
2188
3121
|
ctx.effect(() => () => manager.dispose(), "clutch-dsh-worktree: connection cleanup");
|
|
2189
3122
|
ctx.effect(() => () => virtualWorkspaceMembership.dispose(), "clutch-dsh-worktree: Workspace membership cleanup");
|
|
3123
|
+
ctx.effect(() => () => contextProjection.dispose(), "clutch-dsh-worktree: Session context cleanup");
|
|
3124
|
+
contextProjection.refresh();
|
|
2190
3125
|
const viewStore = createWorktreeViewStore();
|
|
2191
3126
|
const ensureSessionWorkspace = (workspaceId, sessionId) => {
|
|
2192
3127
|
virtualWorkspaceMembership.ensure({
|
|
@@ -2197,6 +3132,24 @@ window.__ModuleLoader__.load({
|
|
|
2197
3132
|
const syncSessionWorkspaces = (bindings) => {
|
|
2198
3133
|
virtualWorkspaceMembership.sync(bindings);
|
|
2199
3134
|
};
|
|
3135
|
+
const worktreeSessionConnector = createWorktreeSessionConnector({
|
|
3136
|
+
manager,
|
|
3137
|
+
sessions: ctx.sessions.list,
|
|
3138
|
+
archivedSessionIds: () => ctx.workspaces.list.getSnapshot().archivedSessionIds ?? [],
|
|
3139
|
+
createSession: async (input) => String(await sessions.create(input)),
|
|
3140
|
+
ensureSessionWorkspace,
|
|
3141
|
+
openSession: (sessionId) => {
|
|
3142
|
+
ctx.sessions.open(sessionId);
|
|
3143
|
+
}
|
|
3144
|
+
});
|
|
3145
|
+
ctx.effect(() => () => worktreeSessionConnector.dispose(), "clutch-dsh-worktree: Worktree Session connector cleanup");
|
|
3146
|
+
ctx.slots.inject("conversation.session.header.actions", () => ctx.slots.register({
|
|
3147
|
+
name: "conversation.session.header.actions",
|
|
3148
|
+
id: "clutch-dsh-worktree-context-header",
|
|
3149
|
+
order: -5,
|
|
3150
|
+
locale: WORKTREE_NS,
|
|
3151
|
+
inject: () => ({ hooks: { worktreeContext: contextProjection.store } })
|
|
3152
|
+
}, WorktreeHeaderContext));
|
|
2200
3153
|
ctx.slots.inject("sidebar.footer.action", () => ctx.slots.register({
|
|
2201
3154
|
name: "sidebar.footer.action",
|
|
2202
3155
|
id: "clutch-dsh-worktree-mode-action",
|
|
@@ -2211,22 +3164,14 @@ window.__ModuleLoader__.load({
|
|
|
2211
3164
|
locale: WORKTREE_NS,
|
|
2212
3165
|
inject: () => ({
|
|
2213
3166
|
available: true,
|
|
3167
|
+
hooks: { worktreeContext: contextProjection.store },
|
|
2214
3168
|
manager,
|
|
2215
3169
|
createWorkspace: async () => {
|
|
2216
3170
|
const workspacePath = await ctx.workspaces.pickDirectory();
|
|
2217
3171
|
if (workspacePath !== null) await ctx.workspaces.create({ path: workspacePath });
|
|
2218
3172
|
},
|
|
2219
|
-
createSessionForWorktree: (input) =>
|
|
2220
|
-
|
|
2221
|
-
createSession: (sessionInput) => sessions.create(sessionInput),
|
|
2222
|
-
manager,
|
|
2223
|
-
beforeOpen: (sessionId) => {
|
|
2224
|
-
ensureSessionWorkspace(input.workspaceId, sessionId);
|
|
2225
|
-
},
|
|
2226
|
-
openSession: (sessionId) => {
|
|
2227
|
-
ctx.sessions.open(sessionId);
|
|
2228
|
-
}
|
|
2229
|
-
}),
|
|
3173
|
+
createSessionForWorktree: (input) => worktreeSessionConnector.create(input),
|
|
3174
|
+
invalidateWorktreeContext: (workspaceId) => contextProjection.invalidate(workspaceId),
|
|
2230
3175
|
createMainSession: (workspaceId) => {
|
|
2231
3176
|
ctx.workspaces.startSession(workspaceId);
|
|
2232
3177
|
},
|
|
@@ -2242,6 +3187,11 @@ window.__ModuleLoader__.load({
|
|
|
2242
3187
|
insertSessionBefore: async (workspaceId, sessionId, beforeSessionId) => {
|
|
2243
3188
|
await ctx.workspaces.insertSessionBefore(workspaceId, sessionId, beforeSessionId);
|
|
2244
3189
|
},
|
|
3190
|
+
insertWorktreeBefore: (workspaceId, worktreeId, beforeWorktreeId) => manager.insertWorktreeBefore({
|
|
3191
|
+
workspaceId,
|
|
3192
|
+
worktreeId,
|
|
3193
|
+
beforeWorktreeId
|
|
3194
|
+
}),
|
|
2245
3195
|
renameSession: async (sessionId, title) => {
|
|
2246
3196
|
const session = ctx.sessions.binding(sessionId)?.session;
|
|
2247
3197
|
if (session === void 0) throw new Error(`unknown session "${sessionId}"`);
|
|
@@ -2263,7 +3213,7 @@ window.__ModuleLoader__.load({
|
|
|
2263
3213
|
ctx.sessions.open(sessionId);
|
|
2264
3214
|
}
|
|
2265
3215
|
})
|
|
2266
|
-
},
|
|
3216
|
+
}, WorktreeOverlay));
|
|
2267
3217
|
}
|
|
2268
3218
|
//#endregion
|
|
2269
3219
|
exports.WORKTREE_CONNECTION_CHANNEL = WORKTREE_CONNECTION_CHANNEL;
|