@deepseek-ai/dsh-client-ui-workspace 0.2.1-alpha.1 → 0.2.1-alpha.3
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.i18n.yaml +14 -14
- package/README.md +17 -11
- package/README.zh.md +17 -11
- package/lib/client.js +447 -171
- package/lib/types/client/contract/slots.d.ts +39 -21
- package/lib/types/client/contract/toast.d.ts +67 -0
- package/lib/types/client/index.d.ts +4 -1
- package/lib/types/client/locales.d.ts +10 -0
- package/lib/types/client/navigation.d.ts +41 -13
- package/lib/types/client/rows/WorkspaceBrowser.d.ts +1 -1
- package/lib/types/client/session-actions/ForkSession.d.ts +5 -4
- package/lib/types/client/session-actions/RowActionToast.d.ts +5 -8
- package/lib/types/client/session-actions/SessionId.d.ts +8 -0
- package/lib/types/client/shortcuts.d.ts +2 -7
- package/lib/types/client/toast/Toast.d.ts +21 -0
- package/lib/types/client/toast/register.d.ts +10 -0
- package/locale/en.json +5 -0
- package/locale/zh.json +6 -0
- package/package.json +33 -29
package/lib/client.js
CHANGED
|
@@ -5,10 +5,10 @@ window.__ModuleLoader__.load({
|
|
|
5
5
|
var exports = module.exports;
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
7
|
let _deepseek_ai_dsh_client_store = require("@deepseek-ai/dsh-client-store");
|
|
8
|
+
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
8
9
|
let _deepseek_ai_cordis = require("@deepseek-ai/cordis");
|
|
9
10
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
10
11
|
let react = require("react");
|
|
11
|
-
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
12
12
|
//#region lib/types/client/contract/slots.js
|
|
13
13
|
/**
|
|
14
14
|
* Bind the row's render occurrence into the entries' `useMenuOpenState` hook:
|
|
@@ -30,10 +30,8 @@ window.__ModuleLoader__.load({
|
|
|
30
30
|
searchRequest: 0,
|
|
31
31
|
addRequested: false,
|
|
32
32
|
directoryBusy: false,
|
|
33
|
-
renameTarget: null
|
|
34
|
-
forkError: null
|
|
33
|
+
renameTarget: null
|
|
35
34
|
});
|
|
36
|
-
let forkErrorSeq = 0;
|
|
37
35
|
return {
|
|
38
36
|
state,
|
|
39
37
|
search: () => {
|
|
@@ -74,22 +72,6 @@ window.__ModuleLoader__.load({
|
|
|
74
72
|
...state.getSnapshot(),
|
|
75
73
|
renameTarget: null
|
|
76
74
|
});
|
|
77
|
-
},
|
|
78
|
-
forkFailed: (reason) => {
|
|
79
|
-
forkErrorSeq += 1;
|
|
80
|
-
state.set({
|
|
81
|
-
...state.getSnapshot(),
|
|
82
|
-
forkError: {
|
|
83
|
-
reason,
|
|
84
|
-
seq: forkErrorSeq
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
},
|
|
88
|
-
dismissForkError: () => {
|
|
89
|
-
state.set({
|
|
90
|
-
...state.getSnapshot(),
|
|
91
|
-
forkError: null
|
|
92
|
-
});
|
|
93
75
|
}
|
|
94
76
|
};
|
|
95
77
|
}
|
|
@@ -100,8 +82,9 @@ window.__ModuleLoader__.load({
|
|
|
100
82
|
* @param navigation - session creation and forking from the pointer controls' navigation service.
|
|
101
83
|
* @param controls - browser-owned opening requests.
|
|
102
84
|
* @param archiveSession - shared archive action, including running-work confirmation and notices.
|
|
85
|
+
* @param reportForkFailure - publish a classified failure through the frame-wide notice channel.
|
|
103
86
|
*/
|
|
104
|
-
function installWorkspaceShortcuts(ctx, navigation, controls, archiveSession) {
|
|
87
|
+
function installWorkspaceShortcuts(ctx, navigation, controls, archiveSession, reportForkFailure) {
|
|
105
88
|
const t = ctx.locale.bind("workspace");
|
|
106
89
|
const current = () => Object.values(ctx.sessions.list.getSnapshot().byId).find((row) => (row.retainedBy.mainView ?? 0) > 0);
|
|
107
90
|
const addReason = () => ctx.slots.entries("sidebar.workspaces.directoryFlow").length === 0 ? t("shortcut.noPicker") : controls.state.getSnapshot().directoryBusy ? t("shortcut.directoryBusy") : null;
|
|
@@ -184,7 +167,7 @@ window.__ModuleLoader__.load({
|
|
|
184
167
|
run: () => {
|
|
185
168
|
navigation.forkSession(target.id).catch((error) => {
|
|
186
169
|
const unavailable = error instanceof Error && error.name === "SessionForkError" && error.rpcError.code === "session/fork-unavailable";
|
|
187
|
-
|
|
170
|
+
reportForkFailure(unavailable ? "unavailable" : "failed");
|
|
188
171
|
if (!unavailable) console.warn("session fork rejected:", error);
|
|
189
172
|
});
|
|
190
173
|
}
|
|
@@ -1380,6 +1363,7 @@ window.__ModuleLoader__.load({
|
|
|
1380
1363
|
sessions;
|
|
1381
1364
|
view;
|
|
1382
1365
|
notify;
|
|
1366
|
+
/** The latest in-flight connection per Workspace; a request joins it only when both name the same preset. */
|
|
1383
1367
|
connecting = /* @__PURE__ */ new Map();
|
|
1384
1368
|
lifetime = new AbortController();
|
|
1385
1369
|
selection = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)({}, { persist: { name: "dsh.sessions.current" } });
|
|
@@ -1410,46 +1394,90 @@ window.__ModuleLoader__.load({
|
|
|
1410
1394
|
};
|
|
1411
1395
|
}, "ui-workspace: Workspace navigation policy");
|
|
1412
1396
|
}
|
|
1413
|
-
|
|
1397
|
+
connectWorkspace(workspaceId, options = {}) {
|
|
1398
|
+
return this.connectBlank(workspaceId, options);
|
|
1399
|
+
}
|
|
1400
|
+
/**
|
|
1401
|
+
* @param reuse - preset for the reused or created blank; absent creates a fresh Session.
|
|
1402
|
+
*/
|
|
1403
|
+
async connectBlank(workspaceId, reuse) {
|
|
1414
1404
|
const workspace = this.workspaces.list.getSnapshot().items.find((item) => item.workspaceId === workspaceId);
|
|
1415
1405
|
if (workspace === void 0) throw new Error(`uiWorkspace.connectWorkspace: unknown workspace ${workspaceId}`);
|
|
1406
|
+
if (reuse === void 0) return this.sessions.create({ workspaceId });
|
|
1416
1407
|
const inflight = this.connecting.get(workspaceId);
|
|
1417
|
-
if (inflight !== void 0) return inflight;
|
|
1418
|
-
const attempt = this.
|
|
1419
|
-
this.connecting.delete(workspaceId);
|
|
1408
|
+
if (inflight !== void 0 && inflight.agentPreset === reuse.agentPreset) return inflight.attempt;
|
|
1409
|
+
const attempt = this.createInWorkspace(workspace, reuse).finally(() => {
|
|
1410
|
+
if (this.connecting.get(workspaceId)?.attempt === attempt) this.connecting.delete(workspaceId);
|
|
1411
|
+
});
|
|
1412
|
+
this.connecting.set(workspaceId, {
|
|
1413
|
+
agentPreset: reuse.agentPreset,
|
|
1414
|
+
attempt
|
|
1420
1415
|
});
|
|
1421
|
-
this.connecting.set(workspaceId, attempt);
|
|
1422
1416
|
return attempt;
|
|
1423
1417
|
}
|
|
1424
|
-
|
|
1418
|
+
createInWorkspace(workspace, options) {
|
|
1425
1419
|
const archived = this.workspaces.list.getSnapshot().archivedSessionIds;
|
|
1426
1420
|
const sessions = this.sessions.list.getSnapshot();
|
|
1427
|
-
|
|
1421
|
+
const blank = sessions.ids.find((id) => {
|
|
1428
1422
|
const summary = sessions.byId[id];
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1423
|
+
return summary !== void 0 && summary.blank && summary.cwd === workspace.path && workspace.sessionIds.includes(id) && !archived.includes(id);
|
|
1424
|
+
});
|
|
1425
|
+
return this.createNamed({
|
|
1426
|
+
workspaceId: workspace.workspaceId,
|
|
1427
|
+
...blank === void 0 ? {} : { sessionId: blank },
|
|
1428
|
+
...options.agentPreset === void 0 ? {} : { agentPreset: options.agentPreset }
|
|
1429
|
+
});
|
|
1430
|
+
}
|
|
1431
|
+
/**
|
|
1432
|
+
* Create through the Host. A named blank the Host declined may still read as
|
|
1433
|
+
* blank from stale cached list metadata, which hides it from the Session tree;
|
|
1434
|
+
* its projections are reloaded so the row reflects its log.
|
|
1435
|
+
*/
|
|
1436
|
+
async createNamed(request) {
|
|
1437
|
+
const sessionId = await this.sessions.create(request);
|
|
1438
|
+
const named = request.sessionId;
|
|
1439
|
+
if (named !== void 0 && named !== sessionId) this.sessions.refreshProjections(named).catch((reason) => {
|
|
1440
|
+
console.warn("declined blank Session projection reload failed:", reason);
|
|
1441
|
+
});
|
|
1442
|
+
return sessionId;
|
|
1433
1443
|
}
|
|
1434
|
-
|
|
1444
|
+
/**
|
|
1445
|
+
* Reopen a saved blank Session under the preset its log recorded, or under
|
|
1446
|
+
* the Host default once that preset no longer activates. Listed values are
|
|
1447
|
+
* cached hints that can lag the log after an unclean Host exit, so the
|
|
1448
|
+
* Session's projections are reloaded before the preset is read; a Session
|
|
1449
|
+
* that still awaits a format migration reloads only those cached hints.
|
|
1450
|
+
*/
|
|
1451
|
+
async restoreBlank(workspaceId, sessionId) {
|
|
1452
|
+
await this.sessions.refreshProjections(sessionId);
|
|
1453
|
+
const recorded = this.sessions.list.getSnapshot().byId[sessionId]?.projectionValues?.agentPreset;
|
|
1454
|
+
const request = {
|
|
1455
|
+
workspaceId,
|
|
1456
|
+
sessionId
|
|
1457
|
+
};
|
|
1458
|
+
if (typeof recorded !== "string") return this.createNamed(request);
|
|
1435
1459
|
try {
|
|
1436
|
-
return await this.
|
|
1437
|
-
|
|
1438
|
-
|
|
1460
|
+
return await this.createNamed({
|
|
1461
|
+
...request,
|
|
1462
|
+
agentPreset: recorded
|
|
1439
1463
|
});
|
|
1440
1464
|
} catch (error) {
|
|
1441
|
-
|
|
1442
|
-
|
|
1465
|
+
const code = sessionCreateErrorOf(error)?.rpcError.code;
|
|
1466
|
+
if (code !== "agent-preset/not-found" && code !== "agent-preset/invalid") throw error;
|
|
1467
|
+
return this.createNamed(request);
|
|
1443
1468
|
}
|
|
1444
1469
|
}
|
|
1445
1470
|
openSession(target) {
|
|
1446
1471
|
this.replaceMain(target, this.lifetime.signal, "reveal");
|
|
1447
1472
|
}
|
|
1448
|
-
|
|
1473
|
+
openWorkspace(workspaceId, beforeOpen, options = {}) {
|
|
1474
|
+
return this.openWorkspaceSession(workspaceId, beforeOpen, options);
|
|
1475
|
+
}
|
|
1476
|
+
async openWorkspaceSession(workspaceId, beforeOpen, reuse) {
|
|
1449
1477
|
const navigation = AbortSignal.any([this.ctx.layout.beginNavigation(), this.lifetime.signal]);
|
|
1450
1478
|
let sessionId;
|
|
1451
1479
|
try {
|
|
1452
|
-
sessionId = await this.
|
|
1480
|
+
sessionId = await this.connectBlank(workspaceId, reuse);
|
|
1453
1481
|
} catch (error) {
|
|
1454
1482
|
if (!navigation.aborted) this.notify({
|
|
1455
1483
|
kind: "createFailed",
|
|
@@ -1460,15 +1488,17 @@ window.__ModuleLoader__.load({
|
|
|
1460
1488
|
if (navigation.aborted) return;
|
|
1461
1489
|
this.replaceMain(sessionId, navigation, "reveal", beforeOpen);
|
|
1462
1490
|
}
|
|
1463
|
-
async forkSession(sessionId, onCreated) {
|
|
1491
|
+
async forkSession(sessionId, onCreated, options) {
|
|
1464
1492
|
return this.sessions.fork({
|
|
1465
1493
|
sessionId,
|
|
1466
1494
|
increaseTitle: true,
|
|
1467
|
-
...onCreated === void 0 ? {} : { onCreated }
|
|
1495
|
+
...onCreated === void 0 ? {} : { onCreated },
|
|
1496
|
+
...options?.allowMigration === void 0 ? {} : { allowMigration: options.allowMigration }
|
|
1468
1497
|
});
|
|
1469
1498
|
}
|
|
1470
1499
|
startSession(workspaceId, options) {
|
|
1471
|
-
const
|
|
1500
|
+
const { agentPreset, ...draft } = options ?? {};
|
|
1501
|
+
const draftOptions = options === void 0 ? void 0 : draft;
|
|
1472
1502
|
const initializeDraft = draftOptions !== void 0 && (draftOptions.prompt !== void 0 || draftOptions.clearPreviousDraft === true);
|
|
1473
1503
|
const workspace = this.workspaces.list.getSnapshot();
|
|
1474
1504
|
const sessions = this.sessions.list.getSnapshot();
|
|
@@ -1487,11 +1517,11 @@ window.__ModuleLoader__.load({
|
|
|
1487
1517
|
this.clearMain();
|
|
1488
1518
|
return;
|
|
1489
1519
|
}
|
|
1490
|
-
this.openWorkspace(target, initializeDraft ? (id) => {
|
|
1520
|
+
(draftOptions === void 0 ? this.openWorkspaceSession(target, void 0, void 0) : this.openWorkspace(target, initializeDraft ? (id) => {
|
|
1491
1521
|
const binding = this.sessions.binding(id);
|
|
1492
1522
|
if (binding === void 0) this.draftPreparationFailed();
|
|
1493
1523
|
this.prepareDraft(binding, draftOptions);
|
|
1494
|
-
} : void 0).catch((reason) => {
|
|
1524
|
+
} : void 0, agentPreset === void 0 ? {} : { agentPreset })).catch((reason) => {
|
|
1495
1525
|
console.warn("new session failed:", reason);
|
|
1496
1526
|
});
|
|
1497
1527
|
}
|
|
@@ -1586,7 +1616,7 @@ window.__ModuleLoader__.load({
|
|
|
1586
1616
|
}
|
|
1587
1617
|
const navigation = AbortSignal.any([this.ctx.layout.beginNavigation(), this.lifetime.signal]);
|
|
1588
1618
|
let sessionId;
|
|
1589
|
-
if (summary !== void 0 && workspace !== void 0 && summary.cwd === workspace.path && !workspaces.archivedSessionIds.includes(summary.id)) sessionId = await this.
|
|
1619
|
+
if (summary !== void 0 && workspace !== void 0 && summary.cwd === workspace.path && !workspaces.archivedSessionIds.includes(summary.id)) sessionId = await this.restoreBlank(workspace.workspaceId, summary.id);
|
|
1590
1620
|
let target = workspace?.workspaceId ?? recentWorkspace(workspaces.items, sessions.byId);
|
|
1591
1621
|
if (target === void 0 && workspaces.items.length === 0 && sessions.ids.length === 0) {
|
|
1592
1622
|
const prepared = await this.initializeDefaultWorkspace(navigation);
|
|
@@ -1708,7 +1738,7 @@ window.__ModuleLoader__.load({
|
|
|
1708
1738
|
}
|
|
1709
1739
|
//#endregion
|
|
1710
1740
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-workspace/src/client/rows/Rows.module.css.mjs
|
|
1711
|
-
const css$3 = ".YDXeBa_projectRow,.YDXeBa_sessionRow{border-radius:var(--dsw-radius-md);padding:0 8px;cursor:pointer;user-select:none;color:var(--dsw-alias-label-primary);align-items:center;gap:6px;padding-inline-start:calc(8px + var(--dsh-workspace-indent,0px));display:flex}.YDXeBa_projectRow:hover,.YDXeBa_sessionRow:hover,.YDXeBa_sessionRow.YDXeBa_selected{background:var(--dsw-alias-interactive-bg-hover)}.YDXeBa_searchResultRow{box-sizing:border-box;border-radius:var(--dsw-radius-lg);cursor:pointer;text-align:left;width:100%;min-height:48px;color:var(--dsw-alias-label-primary);background:0 0;border:none;flex-direction:column;align-items:stretch;padding:4px 8px;display:flex}.YDXeBa_searchResultRow:hover,.YDXeBa_searchResultRow.YDXeBa_selected{background:var(--dsw-alias-interactive-bg-hover)}.YDXeBa_searchResultHeading{align-items:center;min-width:0;display:flex}.YDXeBa_searchResultTitle{text-overflow:ellipsis;white-space:nowrap;flex:0 auto;min-width:0;margin-left:4px;font-size:14px;line-height:20px;overflow:hidden}.YDXeBa_searchResultMeta{align-items:center;gap:6px;min-width:0;margin-left:20px;display:flex}.YDXeBa_searchResultWorkspace,.YDXeBa_searchResultSnippet{text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:17px;overflow:hidden}.YDXeBa_searchResultWorkspace{max-width:40%;color:var(--dsw-alias-label-tertiary);flex:none}.YDXeBa_searchResultWorkspace:only-child{max-width:100%}.YDXeBa_searchResultSnippet{min-width:0;color:var(--dsw-alias-label-secondary);flex:1}.YDXeBa_projectRow{box-sizing:border-box;align-items:center;height:34px}.YDXeBa_projectRow .YDXeBa_rowActions{height:20px}.YDXeBa_sessionRow{gap:0;height:32px}.YDXeBa_sessionRow .YDXeBa_title{margin:0 6px 0 4px}.YDXeBa_slot{width:16px;height:20px;color:var(--dsw-alias-label-tertiary);flex:none;justify-content:center;align-items:center;display:inline-flex}.YDXeBa_visuallyHidden{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}.YDXeBa_folderActive{color:var(--dsw-alias-state-business-primary)}.YDXeBa_projectRow .YDXeBa_chevron{display:none}.YDXeBa_projectRow:hover .YDXeBa_chevron{display:inline-flex}.YDXeBa_projectRow:hover .YDXeBa_folder{display:none}.YDXeBa_arrow{transition:transform .15s var(--ds-ease-in-out)}.YDXeBa_arrowOpen{transform:rotate(90deg)}.YDXeBa_projectText{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.YDXeBa_title{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:14px;line-height:20px;overflow:hidden}.YDXeBa_renameInput{border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-button-elevated-fill);min-width:0;color:inherit;outline:none;padding:0 2px;font-size:14px;line-height:20px}.YDXeBa_sessionRow .YDXeBa_title{flex:1}.YDXeBa_sessionRow .YDXeBa_title[data-scrolled]{mask-image:linear-gradient(90deg,#0000,#000 12px)}.YDXeBa_sessionRow .YDXeBa_title[data-clipped]{mask-image:linear-gradient(270deg,#0000,#000 12px)}.YDXeBa_sessionRow .YDXeBa_title[data-scrolled][data-clipped]{mask-image:linear-gradient(90deg,#0000,#000 12px calc(100% - 12px),#0000)}.YDXeBa_meta{text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:20px;overflow:hidden}.YDXeBa_time{color:var(--dsw-alias-label-tertiary);flex:none;font-size:10px;line-height:16px}.YDXeBa_pinIndicator{width:16px;height:20px;color:var(--dsw-alias-label-caption);flex:none;justify-content:center;align-items:center;margin-left:6px;display:inline-flex}.YDXeBa_sessionRow.YDXeBa_archived .YDXeBa_title,.YDXeBa_searchResultRow.YDXeBa_archived .YDXeBa_searchResultTitle,.YDXeBa_searchResultRow.YDXeBa_archived .YDXeBa_searchResultWorkspace,.YDXeBa_searchResultRow.YDXeBa_archived .YDXeBa_searchResultSnippet{color:var(--dsw-alias-label-caption)}.YDXeBa_dot{flex:none}.YDXeBa_rowActions{flex:none;align-items:center;gap:
|
|
1741
|
+
const css$3 = ".YDXeBa_projectRow,.YDXeBa_sessionRow{border-radius:var(--dsw-radius-md);padding:0 8px;cursor:pointer;user-select:none;color:var(--dsw-alias-label-primary);align-items:center;gap:6px;padding-inline-start:calc(8px + var(--dsh-workspace-indent,0px));display:flex}.YDXeBa_projectRow:hover,.YDXeBa_sessionRow:hover,.YDXeBa_sessionRow.YDXeBa_selected{background:var(--dsw-alias-interactive-bg-hover)}.YDXeBa_searchResultRow{box-sizing:border-box;border-radius:var(--dsw-radius-lg);cursor:pointer;text-align:left;width:100%;min-height:48px;color:var(--dsw-alias-label-primary);background:0 0;border:none;flex-direction:column;align-items:stretch;padding:4px 8px;display:flex}.YDXeBa_searchResultRow:hover,.YDXeBa_searchResultRow.YDXeBa_selected{background:var(--dsw-alias-interactive-bg-hover)}.YDXeBa_searchResultHeading{align-items:center;min-width:0;display:flex}.YDXeBa_searchResultTitle{text-overflow:ellipsis;white-space:nowrap;flex:0 auto;min-width:0;margin-left:4px;font-size:14px;line-height:20px;overflow:hidden}.YDXeBa_searchResultMeta{align-items:center;gap:6px;min-width:0;margin-left:20px;display:flex}.YDXeBa_searchResultWorkspace,.YDXeBa_searchResultSnippet{text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:17px;overflow:hidden}.YDXeBa_searchResultWorkspace{max-width:40%;color:var(--dsw-alias-label-tertiary);flex:none}.YDXeBa_searchResultWorkspace:only-child{max-width:100%}.YDXeBa_searchResultSnippet{min-width:0;color:var(--dsw-alias-label-secondary);flex:1}.YDXeBa_projectRow{box-sizing:border-box;align-items:center;height:34px}.YDXeBa_projectRow .YDXeBa_rowActions{height:20px}.YDXeBa_sessionRow{gap:0;height:32px}.YDXeBa_sessionRow .YDXeBa_title{margin:0 6px 0 4px}.YDXeBa_slot{width:16px;height:20px;color:var(--dsw-alias-label-tertiary);flex:none;justify-content:center;align-items:center;display:inline-flex}.YDXeBa_visuallyHidden{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}.YDXeBa_folderActive{color:var(--dsw-alias-state-business-primary)}.YDXeBa_projectRow .YDXeBa_chevron{display:none}.YDXeBa_projectRow:hover .YDXeBa_chevron{display:inline-flex}.YDXeBa_projectRow:hover .YDXeBa_folder{display:none}.YDXeBa_arrow{transition:transform .15s var(--ds-ease-in-out)}.YDXeBa_arrowOpen{transform:rotate(90deg)}.YDXeBa_projectText{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.YDXeBa_title{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:14px;line-height:20px;overflow:hidden}.YDXeBa_renameInput{border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-button-elevated-fill);min-width:0;color:inherit;outline:none;padding:0 2px;font-size:14px;line-height:20px}.YDXeBa_sessionRow .YDXeBa_title{flex:1}.YDXeBa_sessionRow .YDXeBa_title[data-scrolled]{mask-image:linear-gradient(90deg,#0000,#000 12px)}.YDXeBa_sessionRow .YDXeBa_title[data-clipped]{mask-image:linear-gradient(270deg,#0000,#000 12px)}.YDXeBa_sessionRow .YDXeBa_title[data-scrolled][data-clipped]{mask-image:linear-gradient(90deg,#0000,#000 12px calc(100% - 12px),#0000)}.YDXeBa_meta{text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:20px;overflow:hidden}.YDXeBa_time{color:var(--dsw-alias-label-tertiary);flex:none;font-size:10px;line-height:16px}.YDXeBa_pinIndicator{width:16px;height:20px;color:var(--dsw-alias-label-caption);flex:none;justify-content:center;align-items:center;margin-left:6px;display:inline-flex}.YDXeBa_sessionRow.YDXeBa_archived .YDXeBa_title,.YDXeBa_searchResultRow.YDXeBa_archived .YDXeBa_searchResultTitle,.YDXeBa_searchResultRow.YDXeBa_archived .YDXeBa_searchResultWorkspace,.YDXeBa_searchResultRow.YDXeBa_archived .YDXeBa_searchResultSnippet{color:var(--dsw-alias-label-caption)}.YDXeBa_dot{flex:none}.YDXeBa_rowActions{flex:none;align-items:center;gap:15px;display:none}.YDXeBa_projectRow:hover .YDXeBa_rowActions,.YDXeBa_sessionRow:hover .YDXeBa_rowActions,.YDXeBa_searchResultRow:hover .YDXeBa_rowActions,.YDXeBa_projectRow.YDXeBa_menuOpen .YDXeBa_rowActions,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_rowActions{display:inline-flex}.YDXeBa_searchResultHeading .YDXeBa_rowActions{margin-left:auto}.YDXeBa_sessionRow:hover .YDXeBa_time,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_time,.YDXeBa_sessionRow:hover .YDXeBa_pinIndicator,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_pinIndicator{display:none}@media (hover:hover){.YDXeBa_sessionRow:hover .YDXeBa_title,.YDXeBa_sessionRow.YDXeBa_menuOpen .YDXeBa_title{text-overflow:clip}}.YDXeBa_projectRow.YDXeBa_menuOpen,.YDXeBa_sessionRow.YDXeBa_menuOpen{background:var(--dsw-alias-interactive-bg-hover)}.YDXeBa_sessionRow.YDXeBa_dropBefore,.YDXeBa_sessionRow.YDXeBa_dropAfter{position:relative}.YDXeBa_sessionRow.YDXeBa_dropBefore:before,.YDXeBa_sessionRow.YDXeBa_dropAfter:after{content:\"\";z-index:1;background:linear-gradient(55deg, transparent calc(50% - 1px), var(--dsw-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 0 / 5px 7px no-repeat, linear-gradient(125deg, transparent calc(50% - 1px), var(--dsw-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 5px / 5px 7px no-repeat, linear-gradient(var(--dsw-alias-state-business-primary) 0 0) 4px 5px / calc(100% - 4px) 2px no-repeat;pointer-events:none;height:12px;position:absolute;left:0;right:4px}.YDXeBa_sessionRow.YDXeBa_dropBefore:before{top:-7px}.YDXeBa_sessionRow.YDXeBa_dropAfter:after{bottom:-7px}.YDXeBa_hoverContent{flex-direction:column;gap:8px;display:flex}.YDXeBa_hoverTitle{color:#fff;overflow-wrap:break-word;font-size:14px;line-height:20px}.YDXeBa_hoverPath{color:#cfd3d6;word-break:break-all;font-size:12px;line-height:16px}.YDXeBa_hoverTime{color:#cfd3d6;font-size:12px;line-height:16px}.YDXeBa_hoverStatus{color:#adb2b8;align-items:center;gap:8px;font-size:12px;line-height:20px;display:flex}.YDXeBa_hoverArchived svg{flex-shrink:0;margin:0 -4px}.YDXeBa_iconButton{border-radius:var(--dsw-radius-xs);cursor:pointer;width:16px;height:16px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.YDXeBa_iconButton:hover{color:var(--dsw-alias-label-primary)}.YDXeBa_chevron{color:var(--dsw-alias-label-caption)}@media (prefers-reduced-motion:reduce){.YDXeBa_arrow{transition:none;animation:none}}";
|
|
1712
1742
|
const tagId$3 = "@deepseek-ai/dsh-client-ui-workspace/Rows.module.css";
|
|
1713
1743
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
1714
1744
|
const tag = document.createElement("style");
|
|
@@ -1994,6 +2024,7 @@ window.__ModuleLoader__.load({
|
|
|
1994
2024
|
side: "bottom",
|
|
1995
2025
|
align: "end",
|
|
1996
2026
|
delayMs: 500,
|
|
2027
|
+
portal: true,
|
|
1997
2028
|
children: (0, react_jsx_runtime.jsx)("button", {
|
|
1998
2029
|
type: "button",
|
|
1999
2030
|
className: Rows_module_css_default.iconButton,
|
|
@@ -2019,6 +2050,7 @@ window.__ModuleLoader__.load({
|
|
|
2019
2050
|
t
|
|
2020
2051
|
}),
|
|
2021
2052
|
openDelayMs: 800,
|
|
2053
|
+
grouped: true,
|
|
2022
2054
|
disabled: menuOpen,
|
|
2023
2055
|
copyText: row.cwd,
|
|
2024
2056
|
copyLabel: t("copy"),
|
|
@@ -2173,6 +2205,7 @@ window.__ModuleLoader__.load({
|
|
|
2173
2205
|
side: "bottom",
|
|
2174
2206
|
align: "end",
|
|
2175
2207
|
delayMs: 500,
|
|
2208
|
+
portal: true,
|
|
2176
2209
|
children: (0, react_jsx_runtime.jsx)("button", {
|
|
2177
2210
|
type: "button",
|
|
2178
2211
|
className: Rows_module_css_default.iconButton,
|
|
@@ -2326,6 +2359,7 @@ window.__ModuleLoader__.load({
|
|
|
2326
2359
|
t
|
|
2327
2360
|
}),
|
|
2328
2361
|
openDelayMs: 800,
|
|
2362
|
+
grouped: true,
|
|
2329
2363
|
disabled: menuOpen || drag?.active === true,
|
|
2330
2364
|
copyText: row.blank || row.title === "" ? void 0 : row.title,
|
|
2331
2365
|
copyLabel: t("copy"),
|
|
@@ -2766,22 +2800,46 @@ window.__ModuleLoader__.load({
|
|
|
2766
2800
|
const SEARCH_DEBOUNCE_MS = 250;
|
|
2767
2801
|
/** `session.search` wire bound, measured in JavaScript UTF-16 code units. */
|
|
2768
2802
|
const SEARCH_QUERY_MAX_CODE_UNITS = 500;
|
|
2769
|
-
/**
|
|
2770
|
-
const
|
|
2771
|
-
/**
|
|
2772
|
-
|
|
2773
|
-
|
|
2803
|
+
/** Non-blank Session rows visible per Workspace while no Session raises its watermark. */
|
|
2804
|
+
const SESSION_WATERMARK_BASE = 5;
|
|
2805
|
+
/** Highest watermark that attention-bearing Sessions raise automatically; Show more and search reveals may exceed it. */
|
|
2806
|
+
const SESSION_WATERMARK_AUTO_MAX = 50;
|
|
2807
|
+
/** Show the blank row plus the first `watermark` non-blank rows, in list order. */
|
|
2808
|
+
function watermarkRows(sessions, watermark) {
|
|
2809
|
+
let count = 0;
|
|
2774
2810
|
const rows = sessions.filter((session) => {
|
|
2775
|
-
if (session.blank
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
return true;
|
|
2811
|
+
if (session.blank) return true;
|
|
2812
|
+
count += 1;
|
|
2813
|
+
return count <= watermark;
|
|
2779
2814
|
});
|
|
2780
2815
|
return {
|
|
2781
2816
|
rows,
|
|
2782
2817
|
hiddenCount: sessions.length - rows.length
|
|
2783
2818
|
};
|
|
2784
2819
|
}
|
|
2820
|
+
/**
|
|
2821
|
+
* Smallest watermark that covers every non-blank row within the automatic maximum that is running, has a running
|
|
2822
|
+
* child, awaits the user, carries an unread completion, or is current, and the reveal target at any position.
|
|
2823
|
+
*/
|
|
2824
|
+
function requiredWatermark(sessions, current, revealSessionId) {
|
|
2825
|
+
let index = 0;
|
|
2826
|
+
let required = 0;
|
|
2827
|
+
for (const session of sessions) {
|
|
2828
|
+
if (session.blank) continue;
|
|
2829
|
+
index += 1;
|
|
2830
|
+
if (index <= SESSION_WATERMARK_AUTO_MAX && (session.running || session.runningSubagentCount > 0 || session.pendingInteraction !== void 0 || session.completed || session.id === current) || session.id === revealSessionId) required = index;
|
|
2831
|
+
}
|
|
2832
|
+
return required;
|
|
2833
|
+
}
|
|
2834
|
+
/** Raise each listed group's watermark to its requirement; returns `marks` itself when nothing rises. */
|
|
2835
|
+
function raiseWatermarks(marks, required) {
|
|
2836
|
+
let raised = marks;
|
|
2837
|
+
for (const [key, watermark] of required) if (watermark > (raised[key] ?? SESSION_WATERMARK_BASE)) raised = {
|
|
2838
|
+
...raised,
|
|
2839
|
+
[key]: watermark
|
|
2840
|
+
};
|
|
2841
|
+
return raised;
|
|
2842
|
+
}
|
|
2785
2843
|
/** Keep controlled input and RPC payload inside the session.search wire contract. */
|
|
2786
2844
|
function sanitizeSearchQuery(value) {
|
|
2787
2845
|
const withoutNul = value.replaceAll("\0", "");
|
|
@@ -2962,13 +3020,14 @@ window.__ModuleLoader__.load({
|
|
|
2962
3020
|
]
|
|
2963
3021
|
});
|
|
2964
3022
|
}
|
|
2965
|
-
/** The scrolling session tree; unmounting drops the sessions subscription and
|
|
3023
|
+
/** The scrolling session tree; unmounting drops the sessions subscription and the session watermarks. */
|
|
2966
3024
|
function SessionTree({ list, useSessionStatus, startSession, open, workspaces, ungroupedSessionIds, rowState, onLeaveArchivedOnly, workspaceReady, animationResetKey, usePanelInfo, onRenameRequest, onDeleteRequest, onSessionRenameRequest, renderSlot, insertWorkspaceBefore, nestWorkspaces, groupExpansion, setGroupExpanded, setSessionOrder, home, t, revealSessionId, onSessionRevealed, shortcuts }) {
|
|
2967
3025
|
const panelActive = usePanelInfo((info) => info.activePanelId !== null);
|
|
2968
3026
|
const statuses = useSessionStatus((s) => s);
|
|
2969
3027
|
const current = panelActive ? void 0 : Object.values(list.byId).find((session) => (session.retainedBy.mainView ?? 0) > 0)?.id;
|
|
2970
3028
|
const revealGroup = revealSessionId === void 0 || !workspaceReady ? void 0 : owningGroupKey(workspaces, revealSessionId);
|
|
2971
|
-
const [
|
|
3029
|
+
const [storedWatermarks, setStoredWatermarks] = (0, react.useState)({});
|
|
3030
|
+
const [watermarkMotionKey, setWatermarkMotionKey] = (0, react.useState)(0);
|
|
2972
3031
|
const [drag, setDrag] = (0, react.useState)(null);
|
|
2973
3032
|
const sessionDropCommitted = (0, react.useRef)(false);
|
|
2974
3033
|
const [workspaceDrag, setWorkspaceDrag] = (0, react.useState)(null);
|
|
@@ -3026,20 +3085,24 @@ window.__ModuleLoader__.load({
|
|
|
3026
3085
|
revealGroup,
|
|
3027
3086
|
setGroupExpanded
|
|
3028
3087
|
]);
|
|
3029
|
-
(
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3088
|
+
const baselines = new Map(groups.map((group) => [group.key, Math.max(SESSION_WATERMARK_BASE, requiredWatermark(group.sessions, current, group.key === revealGroup ? revealSessionId : void 0))]));
|
|
3089
|
+
const foldedKeys = new Set(groups.filter((group) => !group.expanded).map((group) => group.key));
|
|
3090
|
+
const underFoldedAncestor = (key) => {
|
|
3091
|
+
for (let owner = parents.get(key); owner !== void 0; owner = parents.get(owner)) if (foldedKeys.has(owner)) return true;
|
|
3092
|
+
return false;
|
|
3093
|
+
};
|
|
3094
|
+
const requiredWatermarks = new Map([...baselines].filter(([key]) => !underFoldedAncestor(key)));
|
|
3095
|
+
const sessionWatermarks = raiseWatermarks(storedWatermarks, requiredWatermarks);
|
|
3096
|
+
if (sessionWatermarks !== storedWatermarks) setStoredWatermarks((marks) => raiseWatermarks(marks, requiredWatermarks));
|
|
3097
|
+
const dropWatermarks = (drop) => {
|
|
3098
|
+
if (!Object.keys(storedWatermarks).some(drop)) return;
|
|
3099
|
+
setStoredWatermarks((marks) => Object.fromEntries(Object.entries(marks).filter(([key]) => !drop(key))));
|
|
3100
|
+
setWatermarkMotionKey((key) => key + 1);
|
|
3101
|
+
};
|
|
3102
|
+
const withinGroup = (key, root) => {
|
|
3103
|
+
for (let owner = key; owner !== void 0; owner = parents.get(owner)) if (owner === root) return true;
|
|
3104
|
+
return false;
|
|
3105
|
+
};
|
|
3043
3106
|
const now = Date.now();
|
|
3044
3107
|
const commitSessionDrag = (activeDrag, over) => {
|
|
3045
3108
|
if (sessionDropCommitted.current) return;
|
|
@@ -3050,7 +3113,7 @@ window.__ModuleLoader__.load({
|
|
|
3050
3113
|
if (over.id === activeDrag.sessionId) return;
|
|
3051
3114
|
const accountSessionIds = activeDrag.accountKey === "" ? ungroupedSessionIds : workspaces.find((workspace) => workspace.workspaceId === activeDrag.accountKey)?.sessionIds;
|
|
3052
3115
|
if (accountSessionIds === void 0) return;
|
|
3053
|
-
const renderedSessions =
|
|
3116
|
+
const renderedSessions = watermarkRows(group.sessions, sessionWatermarks[group.key] ?? SESSION_WATERMARK_BASE).rows;
|
|
3054
3117
|
const nextOrder = sessionDragOrder(accountSessionIds, renderedSessions, activeDrag, over);
|
|
3055
3118
|
if (nextOrder !== void 0) setSessionOrder(activeDrag.accountKey, nextOrder);
|
|
3056
3119
|
};
|
|
@@ -3090,8 +3153,9 @@ window.__ModuleLoader__.load({
|
|
|
3090
3153
|
const workspaceId = group.workspaceId;
|
|
3091
3154
|
const children = childrenByParent.get(group.key) ?? [];
|
|
3092
3155
|
const compatibleDrag = workspaceDrag !== null && parents.get(workspaceDrag.workspaceId) === parents.get(group.key);
|
|
3093
|
-
const
|
|
3094
|
-
const
|
|
3156
|
+
const watermark = sessionWatermarks[group.key] ?? SESSION_WATERMARK_BASE;
|
|
3157
|
+
const collapsed = watermarkRows(group.sessions, baselines.get(group.key) ?? SESSION_WATERMARK_BASE);
|
|
3158
|
+
const visible = watermarkRows(group.sessions, watermark);
|
|
3095
3159
|
const sessionsExpanded = visible.hiddenCount === 0;
|
|
3096
3160
|
rowKeys.push(`workspace:${group.key}`);
|
|
3097
3161
|
const childRows = group.expanded ? children.map((child) => renderGroup(child, depth + 1)) : [];
|
|
@@ -3163,10 +3227,7 @@ window.__ModuleLoader__.load({
|
|
|
3163
3227
|
home,
|
|
3164
3228
|
t,
|
|
3165
3229
|
onToggle: () => {
|
|
3166
|
-
if (group.expanded)
|
|
3167
|
-
...limits,
|
|
3168
|
-
[group.key]: COLLAPSED_SESSION_LIMIT
|
|
3169
|
-
}));
|
|
3230
|
+
if (group.expanded) dropWatermarks((key) => withinGroup(key, group.key));
|
|
3170
3231
|
setGroupExpanded(group.key, !group.expanded);
|
|
3171
3232
|
},
|
|
3172
3233
|
onCreate: () => {
|
|
@@ -3251,10 +3312,15 @@ window.__ModuleLoader__.load({
|
|
|
3251
3312
|
"data-row-key": `overflow:${group.key}`,
|
|
3252
3313
|
"aria-expanded": sessionsExpanded,
|
|
3253
3314
|
onClick: () => {
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3315
|
+
if (sessionsExpanded) {
|
|
3316
|
+
dropWatermarks((key) => key === group.key);
|
|
3317
|
+
return;
|
|
3318
|
+
}
|
|
3319
|
+
setStoredWatermarks((marks) => ({
|
|
3320
|
+
...marks,
|
|
3321
|
+
[group.key]: visible.hiddenCount <= SESSION_WATERMARK_BASE ? Infinity : watermark + SESSION_WATERMARK_BASE
|
|
3257
3322
|
}));
|
|
3323
|
+
setWatermarkMotionKey((key) => key + 1);
|
|
3258
3324
|
},
|
|
3259
3325
|
children: sessionsExpanded ? t("sessions.collapse") : t("sessions.expand", { n: visible.hiddenCount })
|
|
3260
3326
|
})
|
|
@@ -3262,7 +3328,7 @@ window.__ModuleLoader__.load({
|
|
|
3262
3328
|
}, group.key);
|
|
3263
3329
|
};
|
|
3264
3330
|
const groupRows = rootGroups.map((group) => renderGroup(group, 0));
|
|
3265
|
-
return (0, react_jsx_runtime.jsxs)(
|
|
3331
|
+
return (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.HoverCardGroup, {
|
|
3266
3332
|
className: clsx(WorkspaceBrowser_module_css_default.treeBody, WorkspaceBrowser_module_css_default.wide),
|
|
3267
3333
|
children: [
|
|
3268
3334
|
workspaceDropAtListStart && (0, react_jsx_runtime.jsx)("span", {
|
|
@@ -3274,7 +3340,7 @@ window.__ModuleLoader__.load({
|
|
|
3274
3340
|
label: t("section.sessions"),
|
|
3275
3341
|
rowKeys,
|
|
3276
3342
|
ready: list.phase === "ready" && workspaceReady && !nativeDragActive,
|
|
3277
|
-
resetKey: JSON.stringify([animationResetKey,
|
|
3343
|
+
resetKey: JSON.stringify([animationResetKey, watermarkMotionKey]),
|
|
3278
3344
|
children: [groups.length === 0 && (0, react_jsx_runtime.jsx)(EmptySessions, {
|
|
3279
3345
|
rowState,
|
|
3280
3346
|
onLeaveArchivedOnly,
|
|
@@ -3307,7 +3373,7 @@ window.__ModuleLoader__.load({
|
|
|
3307
3373
|
if (nextOrder !== void 0) setSessionOrder(FLAT_SESSION_ORDER_KEY, nextOrder);
|
|
3308
3374
|
};
|
|
3309
3375
|
const now = Date.now();
|
|
3310
|
-
return (0, react_jsx_runtime.jsxs)(
|
|
3376
|
+
return (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.HoverCardGroup, {
|
|
3311
3377
|
className: clsx(WorkspaceBrowser_module_css_default.treeBody, WorkspaceBrowser_module_css_default.wide),
|
|
3312
3378
|
children: [(0, react_jsx_runtime.jsxs)(AnimatedRows, {
|
|
3313
3379
|
className: clsx(WorkspaceBrowser_module_css_default.list, WorkspaceBrowser_module_css_default.flatList),
|
|
@@ -3440,7 +3506,7 @@ window.__ModuleLoader__.load({
|
|
|
3440
3506
|
* @param props - composed slot props (shell owner share + store + injected actions).
|
|
3441
3507
|
* @returns the region element tree.
|
|
3442
3508
|
*/
|
|
3443
|
-
function WorkspaceBrowser({ wide, usePanelInfo, expandSidebar, useSessions, useSessionStatus, useWorkspaces, useStore, actions, startSession, open, requestSessionRename, notifyArchivedNotOpenable, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, unarchiveSession, createWorkspace, searchSessions, searchResultLimit, useDirectoryFlow, useHostInfo, useShortcuts, useWorkspaceShortcuts, requestSearch, requestAddWorkspace, closeAddWorkspace, setDirectoryBusy,
|
|
3509
|
+
function WorkspaceBrowser({ wide, usePanelInfo, expandSidebar, useSessions, useSessionStatus, useWorkspaces, useStore, actions, startSession, open, requestSessionRename, notifyArchivedNotOpenable, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, unarchiveSession, createWorkspace, searchSessions, searchResultLimit, useDirectoryFlow, useHostInfo, useShortcuts, useWorkspaceShortcuts, requestSearch, requestAddWorkspace, closeAddWorkspace, setDirectoryBusy, renderSlot, t }) {
|
|
3444
3510
|
const home = useHostInfo((info) => info.home);
|
|
3445
3511
|
const shortcuts = useShortcuts((rows) => rows);
|
|
3446
3512
|
const searchShortcut = shortcuts.find((row) => row.id === "session.search");
|
|
@@ -3869,7 +3935,7 @@ window.__ModuleLoader__.load({
|
|
|
3869
3935
|
side: "right",
|
|
3870
3936
|
onPick: (workspaceId) => {
|
|
3871
3937
|
closeAddWorkspace();
|
|
3872
|
-
startSession(workspaceId);
|
|
3938
|
+
startSession(workspaceId, { clearPreviousDraft: false });
|
|
3873
3939
|
},
|
|
3874
3940
|
onClose: () => {
|
|
3875
3941
|
closeAddWorkspace();
|
|
@@ -4048,11 +4114,7 @@ window.__ModuleLoader__.load({
|
|
|
4048
4114
|
role: "alert",
|
|
4049
4115
|
children: deleteError
|
|
4050
4116
|
})]
|
|
4051
|
-
})
|
|
4052
|
-
shortcutState.forkError !== null && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Toast, {
|
|
4053
|
-
text: t(shortcutState.forkError.reason === "unavailable" ? "shortcut.noCompletedTurn" : "shortcut.forkFailed"),
|
|
4054
|
-
onDone: dismissForkError
|
|
4055
|
-
}, shortcutState.forkError.seq)
|
|
4117
|
+
})
|
|
4056
4118
|
]
|
|
4057
4119
|
});
|
|
4058
4120
|
}
|
|
@@ -4097,6 +4159,7 @@ window.__ModuleLoader__.load({
|
|
|
4097
4159
|
side: "bottom",
|
|
4098
4160
|
align: "end",
|
|
4099
4161
|
delayMs: 500,
|
|
4162
|
+
portal: true,
|
|
4100
4163
|
children: (0, react_jsx_runtime.jsx)("button", {
|
|
4101
4164
|
type: "button",
|
|
4102
4165
|
className: Rows_module_css_default.iconButton,
|
|
@@ -4242,14 +4305,17 @@ window.__ModuleLoader__.load({
|
|
|
4242
4305
|
/** The fork action: one `sidebar.workspaces.session.menu.item` row. */
|
|
4243
4306
|
/**
|
|
4244
4307
|
* Menu row (order 300): fork at the Session's last completed turn; the child
|
|
4245
|
-
* arrives through the Host list beside its source.
|
|
4246
|
-
*
|
|
4247
|
-
* @
|
|
4308
|
+
* arrives through the Host list beside its source. Absent when the access
|
|
4309
|
+
* snapshot excludes `session/fork` for this Session.
|
|
4310
|
+
* @param props - owner share, menu open state, access Hook, and the fork share.
|
|
4311
|
+
* @returns the row, or nothing when the caller may not fork this Session.
|
|
4248
4312
|
*/
|
|
4249
|
-
function ForkSessionMenuItem({ sessionId, useMenuOpenState, useShortcuts, forkSession, t }) {
|
|
4313
|
+
function ForkSessionMenuItem({ sessionId, useMenuOpenState, useShortcuts, useSessionAccess, forkSession, t }) {
|
|
4250
4314
|
const [, setMenuOpen] = useMenuOpenState();
|
|
4315
|
+
const shortcut = useShortcuts((rows) => rows.find((row) => row.id === "session.fork"));
|
|
4316
|
+
if (!useSessionAccess(sessionId, "session/fork")) return null;
|
|
4251
4317
|
return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.MenuItemButton, {
|
|
4252
|
-
shortcut
|
|
4318
|
+
shortcut,
|
|
4253
4319
|
icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBranchOutlineRegular, {}),
|
|
4254
4320
|
onSelect: () => {
|
|
4255
4321
|
setMenuOpen(false);
|
|
@@ -4308,6 +4374,7 @@ window.__ModuleLoader__.load({
|
|
|
4308
4374
|
side: "bottom",
|
|
4309
4375
|
align: "end",
|
|
4310
4376
|
delayMs: 500,
|
|
4377
|
+
portal: true,
|
|
4311
4378
|
children: (0, react_jsx_runtime.jsx)("button", {
|
|
4312
4379
|
type: "button",
|
|
4313
4380
|
className: Rows_module_css_default.iconButton,
|
|
@@ -4438,73 +4505,238 @@ window.__ModuleLoader__.load({
|
|
|
4438
4505
|
//#endregion
|
|
4439
4506
|
//#region lib/types/client/session-actions/RowActionToast.js
|
|
4440
4507
|
/**
|
|
4441
|
-
*
|
|
4442
|
-
*
|
|
4508
|
+
* Dispatch the current notice without interpreting its business payload.
|
|
4509
|
+
* @param props - Current notice, dismissal, and the declared keyed renderer.
|
|
4510
|
+
* @returns The selected notice presentation, or nothing.
|
|
4443
4511
|
*/
|
|
4512
|
+
function RowActionToast({ useToast, dismissToast, renderSlot }) {
|
|
4513
|
+
const notice = useToast((current) => current);
|
|
4514
|
+
if (notice === null) return null;
|
|
4515
|
+
return renderSlot("workspace.toast", {
|
|
4516
|
+
...notice,
|
|
4517
|
+
dismissToast
|
|
4518
|
+
}, { entryKey: notice.kind });
|
|
4519
|
+
}
|
|
4520
|
+
//#endregion
|
|
4521
|
+
//#region lib/types/client/toast/Toast.js
|
|
4522
|
+
/** One presentation Factory and the adapters for keyed Workspace notices. */
|
|
4444
4523
|
/**
|
|
4445
|
-
*
|
|
4446
|
-
*
|
|
4447
|
-
*
|
|
4524
|
+
* Render one notice using the shared Factory.
|
|
4525
|
+
* @param props - Keyed payload, injected display mapping, locale, and Factory renderer.
|
|
4526
|
+
* @returns The shared Toast occurrence.
|
|
4448
4527
|
*/
|
|
4449
|
-
|
|
4528
|
+
function ToastEntry(props) {
|
|
4529
|
+
const { dismissToast, display, t, renderFactorySlot, seq } = props;
|
|
4530
|
+
return renderFactorySlot("workspace.toast.content", {
|
|
4531
|
+
...display(props, t, dismissToast),
|
|
4532
|
+
seq,
|
|
4533
|
+
onDone: dismissToast
|
|
4534
|
+
});
|
|
4535
|
+
}
|
|
4450
4536
|
/**
|
|
4451
|
-
*
|
|
4452
|
-
*
|
|
4453
|
-
*
|
|
4454
|
-
* reason on the same hold, or a plain warning for a failed pin, an archived
|
|
4455
|
-
* row that was clicked, or default Workspace creation.
|
|
4456
|
-
* @param props - the notice hook, the shared viewing store, the notice dismissal, the two archived-notice actions, and the locale seat.
|
|
4457
|
-
* @returns the notice on display, or null.
|
|
4537
|
+
* Keep the archive filter action reactive without subscribing unrelated notices.
|
|
4538
|
+
* @param props - Archive notice, display mapping, and the existing viewing store.
|
|
4539
|
+
* @returns The shared Toast occurrence with its current actions.
|
|
4458
4540
|
*/
|
|
4459
|
-
function
|
|
4460
|
-
const
|
|
4461
|
-
const
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
tone: "success",
|
|
4468
|
-
holdMs: LONG_TOAST_HOLD_MS,
|
|
4469
|
-
actions: [{
|
|
4470
|
-
label: t("toast.archivedUndo"),
|
|
4471
|
-
onClick: () => {
|
|
4472
|
-
dismissToast();
|
|
4473
|
-
undoArchive(sessionId);
|
|
4474
|
-
}
|
|
4475
|
-
}, ...archivedRowsVisible ? [] : [{
|
|
4476
|
-
prefix: t("toast.archivedOr"),
|
|
4477
|
-
label: t("toast.archivedFilter"),
|
|
4478
|
-
onClick: () => {
|
|
4479
|
-
dismissToast();
|
|
4480
|
-
showArchived();
|
|
4481
|
-
}
|
|
4482
|
-
}]],
|
|
4483
|
-
onDone: dismissToast
|
|
4484
|
-
}, `toast-${String(toast.seq)}`);
|
|
4485
|
-
}
|
|
4486
|
-
if (toast.kind === "createFailed") return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Toast, {
|
|
4487
|
-
text: t("toast.createFailed", { message: toast.message }),
|
|
4488
|
-
icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconWarningOutlineRegular, {}),
|
|
4489
|
-
holdMs: LONG_TOAST_HOLD_MS,
|
|
4541
|
+
function ArchiveToastEntry(props) {
|
|
4542
|
+
const { dismissToast, display, filterAction, useStore, t, renderFactorySlot, seq } = props;
|
|
4543
|
+
const archivedVisible = useStore((state) => (state.archivedFilter ?? "default") !== "default");
|
|
4544
|
+
const fields = display(props, t, dismissToast);
|
|
4545
|
+
return renderFactorySlot("workspace.toast.content", {
|
|
4546
|
+
...fields,
|
|
4547
|
+
actions: [...fields.actions ?? [], ...archivedVisible ? [] : [filterAction(t, dismissToast)]],
|
|
4548
|
+
seq,
|
|
4490
4549
|
onDone: dismissToast
|
|
4491
|
-
}
|
|
4550
|
+
});
|
|
4551
|
+
}
|
|
4552
|
+
/**
|
|
4553
|
+
* Present plain display data with the shared primitive's timing and portal.
|
|
4554
|
+
* @param props - Localized display fields, display identity, and dismissal.
|
|
4555
|
+
* @returns One Toast, remounted only for a new display identity.
|
|
4556
|
+
*/
|
|
4557
|
+
function WorkspaceToast({ seq, text, tone, holdMs, actions, onDone }) {
|
|
4492
4558
|
return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Toast, {
|
|
4493
|
-
text
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4559
|
+
text,
|
|
4560
|
+
onDone,
|
|
4561
|
+
...tone === "success" ? { tone: "success" } : {},
|
|
4562
|
+
...tone === "warning" ? { icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconWarningOutlineRegular, {}) } : {},
|
|
4563
|
+
...holdMs === void 0 ? {} : { holdMs },
|
|
4564
|
+
...actions === void 0 ? {} : { actions }
|
|
4565
|
+
}, seq);
|
|
4497
4566
|
}
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4567
|
+
//#endregion
|
|
4568
|
+
//#region lib/types/client/toast/register.js
|
|
4569
|
+
/** Register notice presentations with their business-owned display fields and actions.
|
|
4570
|
+
* @param ctx - Workspace plugin context.
|
|
4571
|
+
* @param viewStore - Viewing store, read only by archive notices.
|
|
4572
|
+
* @param actions - Archive and source-opening callbacks.
|
|
4573
|
+
*/
|
|
4574
|
+
function registerToasts(ctx, viewStore, actions) {
|
|
4575
|
+
const archiveFilterAction = (t, dismiss) => ({
|
|
4576
|
+
prefix: t("toast.archivedOr"),
|
|
4577
|
+
label: t("toast.archivedFilter"),
|
|
4578
|
+
onClick: () => {
|
|
4579
|
+
dismiss();
|
|
4580
|
+
actions.showArchived();
|
|
4581
|
+
}
|
|
4582
|
+
});
|
|
4583
|
+
ctx.slots.registerFactory({
|
|
4584
|
+
name: "workspace.toast.content",
|
|
4585
|
+
scope: "root"
|
|
4586
|
+
}, WorkspaceToast);
|
|
4587
|
+
ctx.slots.inject("workspace.toast", function* () {
|
|
4588
|
+
yield ctx.slots.register({
|
|
4589
|
+
name: "workspace.toast",
|
|
4590
|
+
key: "sessionIdCopied",
|
|
4591
|
+
locale: "workspace",
|
|
4592
|
+
inject: () => ({ display: (_notice, t) => ({
|
|
4593
|
+
text: t("toast.sessionIdCopied"),
|
|
4594
|
+
tone: "success"
|
|
4595
|
+
}) })
|
|
4596
|
+
}, ToastEntry);
|
|
4597
|
+
yield ctx.slots.register({
|
|
4598
|
+
name: "workspace.toast",
|
|
4599
|
+
key: "sessionIdCopyFailed",
|
|
4600
|
+
locale: "workspace",
|
|
4601
|
+
inject: () => ({ display: (_notice, t) => ({
|
|
4602
|
+
text: t("toast.sessionIdCopyFailed"),
|
|
4603
|
+
tone: "warning"
|
|
4604
|
+
}) })
|
|
4605
|
+
}, ToastEntry);
|
|
4606
|
+
yield ctx.slots.register({
|
|
4607
|
+
name: "workspace.toast",
|
|
4608
|
+
key: "pinFailed",
|
|
4609
|
+
locale: "workspace",
|
|
4610
|
+
inject: () => ({ display: (_notice, t) => ({
|
|
4611
|
+
text: t("toast.pinFailed"),
|
|
4612
|
+
tone: "warning"
|
|
4613
|
+
}) })
|
|
4614
|
+
}, ToastEntry);
|
|
4615
|
+
yield ctx.slots.register({
|
|
4616
|
+
name: "workspace.toast",
|
|
4617
|
+
key: "unpinFailed",
|
|
4618
|
+
locale: "workspace",
|
|
4619
|
+
inject: () => ({ display: (_notice, t) => ({
|
|
4620
|
+
text: t("toast.unpinFailed"),
|
|
4621
|
+
tone: "warning"
|
|
4622
|
+
}) })
|
|
4623
|
+
}, ToastEntry);
|
|
4624
|
+
yield ctx.slots.register({
|
|
4625
|
+
name: "workspace.toast",
|
|
4626
|
+
key: "archivedNotOpenable",
|
|
4627
|
+
locale: "workspace",
|
|
4628
|
+
inject: () => ({ display: (_notice, t) => ({
|
|
4629
|
+
text: t("toast.archivedNotOpenable"),
|
|
4630
|
+
tone: "warning"
|
|
4631
|
+
}) })
|
|
4632
|
+
}, ToastEntry);
|
|
4633
|
+
yield ctx.slots.register({
|
|
4634
|
+
name: "workspace.toast",
|
|
4635
|
+
key: "defaultWorkspaceFailed",
|
|
4636
|
+
locale: "workspace",
|
|
4637
|
+
inject: () => ({ display: (_notice, t) => ({
|
|
4638
|
+
text: t("defaultWorkspace.failed"),
|
|
4639
|
+
tone: "warning"
|
|
4640
|
+
}) })
|
|
4641
|
+
}, ToastEntry);
|
|
4642
|
+
yield ctx.slots.register({
|
|
4643
|
+
name: "workspace.toast",
|
|
4644
|
+
key: "shortcutForkFailed",
|
|
4645
|
+
locale: "workspace",
|
|
4646
|
+
inject: () => ({ display: (notice, t) => ({
|
|
4647
|
+
text: t(notice.reason === "unavailable" ? "shortcut.noCompletedTurn" : "shortcut.forkFailed"),
|
|
4648
|
+
tone: "plain"
|
|
4649
|
+
}) })
|
|
4650
|
+
}, ToastEntry);
|
|
4651
|
+
yield ctx.slots.register({
|
|
4652
|
+
name: "workspace.toast",
|
|
4653
|
+
key: "createFailed",
|
|
4654
|
+
locale: "workspace",
|
|
4655
|
+
inject: () => ({ display: (notice, t) => ({
|
|
4656
|
+
text: t("toast.createFailed", { message: notice.message }),
|
|
4657
|
+
tone: "warning",
|
|
4658
|
+
holdMs: 6e3
|
|
4659
|
+
}) })
|
|
4660
|
+
}, ToastEntry);
|
|
4661
|
+
yield ctx.slots.register({
|
|
4662
|
+
name: "workspace.toast",
|
|
4663
|
+
key: "forkRequiresOpen",
|
|
4664
|
+
locale: "workspace",
|
|
4665
|
+
inject: () => ({ display: (notice, t, dismiss) => ({
|
|
4666
|
+
text: t("toast.forkRequiresOpen"),
|
|
4667
|
+
tone: "warning",
|
|
4668
|
+
holdMs: 6e3,
|
|
4669
|
+
actions: [{
|
|
4670
|
+
label: t("toast.openForkSource"),
|
|
4671
|
+
onClick: () => {
|
|
4672
|
+
dismiss();
|
|
4673
|
+
actions.openForkSource(notice.sessionId);
|
|
4674
|
+
}
|
|
4675
|
+
}]
|
|
4676
|
+
}) })
|
|
4677
|
+
}, ToastEntry);
|
|
4678
|
+
yield ctx.slots.register({
|
|
4679
|
+
name: "workspace.toast",
|
|
4680
|
+
key: "archived",
|
|
4681
|
+
locale: "workspace",
|
|
4682
|
+
store: viewStore,
|
|
4683
|
+
inject: () => ({
|
|
4684
|
+
display: (notice, t, dismiss) => ({
|
|
4685
|
+
text: t("toast.archived"),
|
|
4686
|
+
tone: "success",
|
|
4687
|
+
holdMs: 6e3,
|
|
4688
|
+
actions: [{
|
|
4689
|
+
label: t("toast.archivedUndo"),
|
|
4690
|
+
onClick: () => {
|
|
4691
|
+
dismiss();
|
|
4692
|
+
actions.undoArchive(notice.sessionId);
|
|
4693
|
+
}
|
|
4694
|
+
}]
|
|
4695
|
+
}),
|
|
4696
|
+
filterAction: archiveFilterAction
|
|
4697
|
+
})
|
|
4698
|
+
}, ArchiveToastEntry);
|
|
4699
|
+
yield ctx.slots.register({
|
|
4700
|
+
name: "workspace.toast",
|
|
4701
|
+
key: "stoppedAndArchived",
|
|
4702
|
+
locale: "workspace",
|
|
4703
|
+
store: viewStore,
|
|
4704
|
+
inject: () => ({
|
|
4705
|
+
display: (notice, t, dismiss) => ({
|
|
4706
|
+
text: t("toast.stoppedAndArchived"),
|
|
4707
|
+
tone: "success",
|
|
4708
|
+
holdMs: 6e3,
|
|
4709
|
+
actions: [{
|
|
4710
|
+
label: t("toast.archivedUndo"),
|
|
4711
|
+
onClick: () => {
|
|
4712
|
+
dismiss();
|
|
4713
|
+
actions.undoArchive(notice.sessionId);
|
|
4714
|
+
}
|
|
4715
|
+
}]
|
|
4716
|
+
}),
|
|
4717
|
+
filterAction: archiveFilterAction
|
|
4718
|
+
})
|
|
4719
|
+
}, ArchiveToastEntry);
|
|
4720
|
+
});
|
|
4721
|
+
}
|
|
4722
|
+
//#endregion
|
|
4723
|
+
//#region lib/types/client/session-actions/SessionId.js
|
|
4724
|
+
/** Copy the row's Session ID without opening its history. */
|
|
4725
|
+
/**
|
|
4726
|
+
* Copy the complete ID after dismissing the row menu.
|
|
4727
|
+
* @param props - Row identity, menu dismissal, clipboard action, and locale.
|
|
4728
|
+
* @returns The final built-in menu item.
|
|
4729
|
+
*/
|
|
4730
|
+
function SessionIdMenuItem({ sessionId, useMenuOpenState, copySessionId, t }) {
|
|
4731
|
+
const [, setMenuOpen] = useMenuOpenState();
|
|
4732
|
+
return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.MenuItemButton, {
|
|
4733
|
+
icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCopyOutlineRegular, {}),
|
|
4734
|
+
onSelect: () => {
|
|
4735
|
+
setMenuOpen(false);
|
|
4736
|
+
copySessionId(sessionId);
|
|
4737
|
+
},
|
|
4738
|
+
children: t("menu.sessionId")
|
|
4739
|
+
});
|
|
4508
4740
|
}
|
|
4509
4741
|
//#endregion
|
|
4510
4742
|
//#region lib/types/client/locales.js
|
|
@@ -4572,6 +4804,9 @@ window.__ModuleLoader__.load({
|
|
|
4572
4804
|
"menu.unarchiveSession": "取消归档",
|
|
4573
4805
|
"menu.pinSession": "置顶会话",
|
|
4574
4806
|
"menu.unpinSession": "取消置顶",
|
|
4807
|
+
"menu.sessionId": "复制 Session ID",
|
|
4808
|
+
"toast.sessionIdCopied": "Session ID 已复制",
|
|
4809
|
+
"toast.sessionIdCopyFailed": "复制失败,请重试",
|
|
4575
4810
|
"row.archived": "已归档",
|
|
4576
4811
|
"row.pinned": "已置顶",
|
|
4577
4812
|
"toast.archivedNotOpenable": "已归档对话暂时无法查看,请取消归档后查看",
|
|
@@ -4598,6 +4833,8 @@ window.__ModuleLoader__.load({
|
|
|
4598
4833
|
"toast.pinFailed": "置顶失败,请稍后重试",
|
|
4599
4834
|
"toast.unpinFailed": "取消置顶失败,请稍后重试",
|
|
4600
4835
|
"toast.createFailed": "新建会话失败:{message}",
|
|
4836
|
+
"toast.forkRequiresOpen": "请先打开原会话完成迁移,再创建分支",
|
|
4837
|
+
"toast.openForkSource": "打开原会话",
|
|
4601
4838
|
"sessions.count.one": "{n} 个会话",
|
|
4602
4839
|
"sessions.count.other": "{n} 个会话",
|
|
4603
4840
|
"actions.workspace.aria": "工作区“{name}”的操作",
|
|
@@ -4689,6 +4926,9 @@ window.__ModuleLoader__.load({
|
|
|
4689
4926
|
"menu.unarchiveSession": "Unarchive session",
|
|
4690
4927
|
"menu.pinSession": "Pin session",
|
|
4691
4928
|
"menu.unpinSession": "Unpin session",
|
|
4929
|
+
"menu.sessionId": "Copy Session ID",
|
|
4930
|
+
"toast.sessionIdCopied": "Session ID copied",
|
|
4931
|
+
"toast.sessionIdCopyFailed": "Copy failed. Try again.",
|
|
4692
4932
|
"row.archived": "Archived",
|
|
4693
4933
|
"row.pinned": "Pinned",
|
|
4694
4934
|
"toast.archivedNotOpenable": "Archived sessions cannot be opened. Unarchive it to view.",
|
|
@@ -4715,6 +4955,8 @@ window.__ModuleLoader__.load({
|
|
|
4715
4955
|
"toast.pinFailed": "Pin failed. Try again later.",
|
|
4716
4956
|
"toast.unpinFailed": "Unpin failed. Try again later.",
|
|
4717
4957
|
"toast.createFailed": "New session failed: {message}",
|
|
4958
|
+
"toast.forkRequiresOpen": "Open the original session to complete migration before creating a branch.",
|
|
4959
|
+
"toast.openForkSource": "Open original session",
|
|
4718
4960
|
"sessions.count.one": "{n} session",
|
|
4719
4961
|
"sessions.count.other": "{n} sessions",
|
|
4720
4962
|
"actions.workspace.aria": "Workspace actions for {name}",
|
|
@@ -4767,7 +5009,8 @@ window.__ModuleLoader__.load({
|
|
|
4767
5009
|
"remote",
|
|
4768
5010
|
"remote.directoryPicker",
|
|
4769
5011
|
"layout",
|
|
4770
|
-
"shortcuts"
|
|
5012
|
+
"shortcuts",
|
|
5013
|
+
"remoteAccess"
|
|
4771
5014
|
];
|
|
4772
5015
|
/**
|
|
4773
5016
|
* Register the browser and picker once their slot declarations are on the
|
|
@@ -4793,7 +5036,10 @@ window.__ModuleLoader__.load({
|
|
|
4793
5036
|
});
|
|
4794
5037
|
};
|
|
4795
5038
|
const uiWorkspace = new UiWorkspaceService(ctx, ctx.remote.directoryPicker, workspaces, sessions, viewInstance.actions, notify);
|
|
4796
|
-
ctx.slots.provideRoot({
|
|
5039
|
+
ctx.slots.provideRoot({
|
|
5040
|
+
hooks: { workspaces: workspaces.list },
|
|
5041
|
+
keyedHooks: { workspaceAccess: (workspaceId, action) => action === void 0 ? void 0 : ctx.remoteAccess.source("workspace", workspaceId, action) }
|
|
5042
|
+
});
|
|
4797
5043
|
ctx.effect(() => ctx.locale.register(NS, {
|
|
4798
5044
|
zh,
|
|
4799
5045
|
en
|
|
@@ -4871,7 +5117,12 @@ window.__ModuleLoader__.load({
|
|
|
4871
5117
|
},
|
|
4872
5118
|
unarchiveSession
|
|
4873
5119
|
});
|
|
4874
|
-
installWorkspaceShortcuts(ctx, uiWorkspace, shortcutControls, archiveInjected().archiveSession)
|
|
5120
|
+
installWorkspaceShortcuts(ctx, uiWorkspace, shortcutControls, archiveInjected().archiveSession, (reason) => {
|
|
5121
|
+
notify({
|
|
5122
|
+
kind: "shortcutForkFailed",
|
|
5123
|
+
reason
|
|
5124
|
+
});
|
|
5125
|
+
});
|
|
4875
5126
|
const archiveConfirmInjected = () => ({
|
|
4876
5127
|
hooks: { archiveRequest },
|
|
4877
5128
|
settleSessionArchive: () => {
|
|
@@ -4892,7 +5143,15 @@ window.__ModuleLoader__.load({
|
|
|
4892
5143
|
parent_session_id: sessionId,
|
|
4893
5144
|
click_position: "sidebar"
|
|
4894
5145
|
});
|
|
4895
|
-
}).catch(() => {
|
|
5146
|
+
}, { allowMigration: false }).catch((error) => {
|
|
5147
|
+
if (error instanceof Error && error.name === "SessionForkError" && error.rpcError.code === "session/migration-required") notify({
|
|
5148
|
+
kind: "forkRequiresOpen",
|
|
5149
|
+
sessionId
|
|
5150
|
+
});
|
|
5151
|
+
});
|
|
5152
|
+
} });
|
|
5153
|
+
const sessionIdInjected = () => ({ copySessionId: async (sessionId) => {
|
|
5154
|
+
notify({ kind: await (0, _deepseek_ai_dsh_client_ui_primitives.writeClipboard)(sessionId) ? "sessionIdCopied" : "sessionIdCopyFailed" });
|
|
4896
5155
|
} });
|
|
4897
5156
|
const renameInjected = () => ({ requestSessionRename });
|
|
4898
5157
|
const renameDialogInjected = () => ({
|
|
@@ -4900,19 +5159,28 @@ window.__ModuleLoader__.load({
|
|
|
4900
5159
|
settleSessionRename: shortcutControls.closeRename,
|
|
4901
5160
|
renameSession
|
|
4902
5161
|
});
|
|
5162
|
+
registerToasts(ctx, viewStore, {
|
|
5163
|
+
undoArchive: unarchiveSession,
|
|
5164
|
+
showArchived: () => {
|
|
5165
|
+
viewInstance.actions.setArchivedFilter("show");
|
|
5166
|
+
},
|
|
5167
|
+
openForkSource: (sessionId) => {
|
|
5168
|
+
if (workspaces.list.getSnapshot().archivedSessionIds.includes(sessionId)) {
|
|
5169
|
+
notify({ kind: "archivedNotOpenable" });
|
|
5170
|
+
return;
|
|
5171
|
+
}
|
|
5172
|
+
openSession(sessionId);
|
|
5173
|
+
}
|
|
5174
|
+
});
|
|
4903
5175
|
const rowToastInjected = () => ({
|
|
4904
5176
|
hooks: { toast: rowToast },
|
|
4905
5177
|
dismissToast: () => {
|
|
4906
5178
|
rowToast.set(null);
|
|
4907
|
-
},
|
|
4908
|
-
undoArchive: unarchiveSession,
|
|
4909
|
-
showArchived: () => {
|
|
4910
|
-
viewInstance.actions.setArchivedFilter("show");
|
|
4911
5179
|
}
|
|
4912
5180
|
});
|
|
4913
5181
|
const browserInjected = () => ({
|
|
4914
|
-
startSession: (workspaceId) => {
|
|
4915
|
-
uiWorkspace.startSession(workspaceId);
|
|
5182
|
+
startSession: (workspaceId, options) => {
|
|
5183
|
+
uiWorkspace.startSession(workspaceId, options);
|
|
4916
5184
|
},
|
|
4917
5185
|
open: openSession,
|
|
4918
5186
|
searchSessions,
|
|
@@ -4938,7 +5206,6 @@ window.__ModuleLoader__.load({
|
|
|
4938
5206
|
requestAddWorkspace: shortcutControls.add,
|
|
4939
5207
|
closeAddWorkspace: shortcutControls.closeAdd,
|
|
4940
5208
|
setDirectoryBusy: shortcutControls.directoryBusy,
|
|
4941
|
-
dismissForkError: shortcutControls.dismissForkError,
|
|
4942
5209
|
hooks: {
|
|
4943
5210
|
directoryFlow: browserFlowSource,
|
|
4944
5211
|
hostInfo,
|
|
@@ -5011,6 +5278,13 @@ window.__ModuleLoader__.load({
|
|
|
5011
5278
|
locale: NS,
|
|
5012
5279
|
inject: archiveInjected
|
|
5013
5280
|
}, ArchiveSessionMenuItem);
|
|
5281
|
+
yield ctx.slots.register({
|
|
5282
|
+
name: "sidebar.workspaces.session.menu.item",
|
|
5283
|
+
id: "session-id",
|
|
5284
|
+
order: 450,
|
|
5285
|
+
locale: NS,
|
|
5286
|
+
inject: sessionIdInjected
|
|
5287
|
+
}, SessionIdMenuItem);
|
|
5014
5288
|
});
|
|
5015
5289
|
ctx.slots.inject("sidebar.workspaces.session.row.action", function* () {
|
|
5016
5290
|
yield ctx.slots.register({
|
|
@@ -5044,9 +5318,11 @@ window.__ModuleLoader__.load({
|
|
|
5044
5318
|
yield ctx.slots.register({
|
|
5045
5319
|
name: "shell.overlay",
|
|
5046
5320
|
id: "workspace.row-toast",
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5321
|
+
inject: rowToastInjected,
|
|
5322
|
+
children: { "workspace.toast": {
|
|
5323
|
+
kind: "keyed",
|
|
5324
|
+
scope: "root"
|
|
5325
|
+
} }
|
|
5050
5326
|
}, RowActionToast);
|
|
5051
5327
|
});
|
|
5052
5328
|
ctx.slots.inject("conversation.hero.workspace", () => ctx.slots.register({
|