@huanlin/dsh-plugin-ya-workspace-sidebar 0.1.1 → 0.2.0
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 +1 -1
- package/lib/client.js +122 -80
- package/lib/client.js.map +1 -1
- package/lib/types/client/locales.d.ts +8 -0
- package/lib/types/client/model.d.ts +18 -0
- package/lib/types/client/styles.d.ts +1 -1
- package/package.json +38 -18
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|

|
|
10
10
|
|
|
11
|
-
DSH Web 工作区侧栏替代插件。顶部固定展示 5 条全局最近会话,下方使用 Workspace → Session
|
|
11
|
+
DSH Web 工作区侧栏替代插件。顶部固定展示 5 条全局最近会话,下方使用 Workspace → Session 二级菜单和面包屑导航;选中工作区的会话按本地日历日期分组(今天/昨天/更早),搜索、添加工作区、重命名、删除、Fork 与归档继续使用 DSH 原生 Host 能力。
|
|
12
12
|
|
|
13
13
|
## 运行
|
|
14
14
|
|
package/lib/client.js
CHANGED
|
@@ -51,7 +51,11 @@ window.__ModuleLoader__.load({
|
|
|
51
51
|
waiting: "等待交互",
|
|
52
52
|
completed: "已完成",
|
|
53
53
|
collapse: "折叠",
|
|
54
|
-
expand: "展开"
|
|
54
|
+
expand: "展开",
|
|
55
|
+
today: "今天",
|
|
56
|
+
yesterday: "昨天",
|
|
57
|
+
date: "{m}月{d}日",
|
|
58
|
+
dateYear: "{y}年{m}月{d}日"
|
|
55
59
|
};
|
|
56
60
|
const en = {
|
|
57
61
|
workspaces: "Workspaces",
|
|
@@ -95,7 +99,11 @@ window.__ModuleLoader__.load({
|
|
|
95
99
|
waiting: "Waiting for interaction",
|
|
96
100
|
completed: "Completed",
|
|
97
101
|
collapse: "Collapse",
|
|
98
|
-
expand: "Expand"
|
|
102
|
+
expand: "Expand",
|
|
103
|
+
today: "Today",
|
|
104
|
+
yesterday: "Yesterday",
|
|
105
|
+
date: "{m}/{d}",
|
|
106
|
+
dateYear: "{m}/{d}/{y}"
|
|
99
107
|
};
|
|
100
108
|
const NS = "ya-workspace-sidebar";
|
|
101
109
|
//#endregion
|
|
@@ -123,6 +131,7 @@ body[data-ds-dark-theme] .ya-search { background:var(--dsw-static-neutral-bluish
|
|
|
123
131
|
.ya-block-label-toggle { flex:none; width:20px; height:20px; margin-left:auto; border:0; border-radius:6px; padding:0; display:inline-flex; align-items:center; justify-content:center; background:transparent; color:var(--dsw-alias-label-tertiary); cursor:pointer; transition:transform 180ms ease-out; }
|
|
124
132
|
.ya-block-label-toggle:hover { background:var(--dsw-alias-interactive-bg-hover); color:var(--dsw-alias-label-secondary); }
|
|
125
133
|
.ya-block-label-toggle.ya-collapsed { transform:rotate(-90deg); }
|
|
134
|
+
.ya-date-group-label { height:26px; display:flex; align-items:center; padding:0 8px; color:var(--dsw-alias-label-tertiary); font-size:12px; font-weight:600; letter-spacing:.02em; }
|
|
126
135
|
.ya-breadcrumb { flex:none; height:34px; display:flex; align-items:center; gap:2px; padding:0 6px; color:var(--dsw-alias-label-tertiary); font-size:13px; }
|
|
127
136
|
.ya-crumb { border:0; padding:4px 3px; border-radius:6px; background:transparent; color:inherit; font:inherit; cursor:default; min-width:0; overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }
|
|
128
137
|
button.ya-crumb:hover { background:var(--dsw-alias-interactive-bg-hover); color:var(--dsw-alias-label-primary); cursor:pointer; }
|
|
@@ -145,8 +154,6 @@ button.ya-crumb:hover { background:var(--dsw-alias-interactive-bg-hover); color:
|
|
|
145
154
|
.ya-warning { color:var(--dsw-alias-status-warning); }
|
|
146
155
|
.ya-rename-input { width:100%; height:38px; box-sizing:border-box; border:1px solid var(--dsw-alias-border-l2); border-radius:9px; padding:0 11px; background:transparent; color:var(--dsw-alias-label-primary); outline:none; }
|
|
147
156
|
.ya-error { margin-top:8px; color:var(--dsw-alias-status-error); font-size:12px; }
|
|
148
|
-
.ya-drop-before::before, .ya-drop-after::after { content:''; position:absolute; left:8px; right:8px; height:2px; border-radius:2px; background:var(--dsw-alias-label-link); }
|
|
149
|
-
.ya-drop-before::before { top:-2px; } .ya-drop-after::after { bottom:-2px; }
|
|
150
157
|
.ya-rail .ya-section-header { padding-left:0; margin-bottom:12px; }
|
|
151
158
|
.ya-rail .ya-icon-button, .ya-rail .ya-search { width:36px; height:36px; padding:0; margin:0 0 12px; border-color:transparent; background:transparent; }
|
|
152
159
|
.ya-rail .ya-search { justify-content:center; }
|
|
@@ -380,6 +387,70 @@ button.ya-crumb:hover { background:var(--dsw-alias-interactive-bg-hover); color:
|
|
|
380
387
|
if (workspace === void 0) return [];
|
|
381
388
|
return workspace.sessionIds.map((id) => list.byId[id]).filter((summary) => summary !== void 0 && visible(summary, list.current, archived)).map((summary) => rowOf(summary, workspace.workspaceId, workspace.title));
|
|
382
389
|
}
|
|
390
|
+
/** Format a local calendar date as `YYYY-MM-DD` (locale-agnostic, no padding surprises). */
|
|
391
|
+
function localDateKey(year, month, day) {
|
|
392
|
+
return `${year}-${month < 9 ? `0${month + 1}` : `${month + 1}`}-${day < 10 ? `0${day}` : `${day}`}`;
|
|
393
|
+
}
|
|
394
|
+
/** Whole-day difference between two local calendar dates (a - b) using UTC midnight. */
|
|
395
|
+
function dayDiff(a, b) {
|
|
396
|
+
const msA = Date.UTC(a.year, a.month, a.day);
|
|
397
|
+
const msB = Date.UTC(b.year, b.month, b.day);
|
|
398
|
+
return Math.round((msA - msB) / 864e5);
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Derive the selected real workspace's sessions grouped by local calendar date.
|
|
402
|
+
*
|
|
403
|
+
* - Only real workspaces: `Ungrouped` falls back to {@link deriveWorkspaceSessions}.
|
|
404
|
+
* - Groups are ordered by date descending; rows within a group by `updatedAt` descending.
|
|
405
|
+
* - {@link visible} filter is reused (archived / subagent / blank visibility).
|
|
406
|
+
* - Future timestamps clamp to today's bucket (`dayOffset` 0).
|
|
407
|
+
* - `now` is the reference timestamp for "today"; pass `Date.now()` in production.
|
|
408
|
+
*/
|
|
409
|
+
function deriveWorkspaceSessionGroups(key, list, workspaces, archivedSessionIds, now) {
|
|
410
|
+
if (key === "__ya_ungrouped__") return [];
|
|
411
|
+
const workspace = workspaces.find((item) => item.workspaceId === key);
|
|
412
|
+
if (workspace === void 0) return [];
|
|
413
|
+
const archived = new Set(archivedSessionIds);
|
|
414
|
+
const rows = workspace.sessionIds.map((id) => list.byId[id]).filter((summary) => summary !== void 0 && visible(summary, list.current, archived)).map((summary) => rowOf(summary, workspace.workspaceId, workspace.title));
|
|
415
|
+
if (rows.length === 0) return [];
|
|
416
|
+
const nowDate = new Date(now);
|
|
417
|
+
const today = {
|
|
418
|
+
year: nowDate.getFullYear(),
|
|
419
|
+
month: nowDate.getMonth(),
|
|
420
|
+
day: nowDate.getDate()
|
|
421
|
+
};
|
|
422
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
423
|
+
for (const row of rows) {
|
|
424
|
+
const ts = Math.min(row.updatedAt, now);
|
|
425
|
+
const d = new Date(ts);
|
|
426
|
+
const date = {
|
|
427
|
+
year: d.getFullYear(),
|
|
428
|
+
month: d.getMonth(),
|
|
429
|
+
day: d.getDate()
|
|
430
|
+
};
|
|
431
|
+
const dateKey = localDateKey(date.year, date.month, date.day);
|
|
432
|
+
let bucket = buckets.get(dateKey);
|
|
433
|
+
if (bucket === void 0) {
|
|
434
|
+
bucket = {
|
|
435
|
+
dayOffset: Math.max(0, dayDiff(today, date)),
|
|
436
|
+
rows: []
|
|
437
|
+
};
|
|
438
|
+
buckets.set(dateKey, bucket);
|
|
439
|
+
}
|
|
440
|
+
bucket.rows.push(row);
|
|
441
|
+
}
|
|
442
|
+
const groups = [];
|
|
443
|
+
for (const [dateKey, bucket] of buckets) {
|
|
444
|
+
bucket.rows.sort((a, b) => b.updatedAt - a.updatedAt || String(a.id).localeCompare(String(b.id)));
|
|
445
|
+
groups.push({
|
|
446
|
+
dateKey,
|
|
447
|
+
dayOffset: bucket.dayOffset,
|
|
448
|
+
rows: bucket.rows
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
groups.sort((a, b) => a.dayOffset - b.dayOffset || a.dateKey.localeCompare(b.dateKey));
|
|
452
|
+
return groups;
|
|
453
|
+
}
|
|
383
454
|
/** Case-insensitive local title/workspace matching used beside Host content search. */
|
|
384
455
|
function localMatches(rows, query) {
|
|
385
456
|
const normalized = query.trim().toLocaleLowerCase();
|
|
@@ -404,43 +475,40 @@ button.ya-crumb:hover { background:var(--dsw-alias-interactive-bg-hover); color:
|
|
|
404
475
|
if (diff < 525600 * minute) return t("months", { n: Math.floor(diff / (43200 * minute)) });
|
|
405
476
|
return t("years", { n: Math.floor(diff / (525600 * minute)) });
|
|
406
477
|
}
|
|
478
|
+
/** Format a date group's localized title from its dayOffset and `YYYY-MM-DD` key. */
|
|
479
|
+
function dateGroupLabel(group, now, t) {
|
|
480
|
+
if (group.dayOffset === 0) return t("today");
|
|
481
|
+
if (group.dayOffset === 1) return t("yesterday");
|
|
482
|
+
const parts = group.dateKey.split("-");
|
|
483
|
+
const year = Number(parts[0]);
|
|
484
|
+
const month = Number(parts[1]);
|
|
485
|
+
const day = Number(parts[2]);
|
|
486
|
+
if (year === new Date(now).getFullYear()) return t("date", {
|
|
487
|
+
m: month,
|
|
488
|
+
d: day
|
|
489
|
+
});
|
|
490
|
+
return t("dateYear", {
|
|
491
|
+
y: year,
|
|
492
|
+
m: month,
|
|
493
|
+
d: day
|
|
494
|
+
});
|
|
495
|
+
}
|
|
407
496
|
function SessionStatus({ row }) {
|
|
408
497
|
if (row.pendingInteraction !== void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "warning" });
|
|
409
498
|
if (row.running) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "ongoing" });
|
|
410
499
|
if (row.completed) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "done" });
|
|
411
500
|
return null;
|
|
412
501
|
}
|
|
413
|
-
function
|
|
414
|
-
const rect = event.currentTarget.getBoundingClientRect();
|
|
415
|
-
return event.clientY < rect.top + rect.height / 2 ? "before" : "after";
|
|
416
|
-
}
|
|
417
|
-
function SessionItem({ row, current, now, open, rename, fork, archive, t, context, drag }) {
|
|
502
|
+
function SessionItem({ row, current, now, open, rename, fork, archive, t, context }) {
|
|
418
503
|
const [menuOpen, setMenuOpen] = (0, react.useState)(false);
|
|
419
504
|
const title = row.blank ? t("newSession") : row.hasTitle ? row.title : t("untitled");
|
|
420
505
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
421
|
-
className: `ya-row${row.id === current ? " ya-selected" : ""}${menuOpen ? " ya-menu-open" : ""}
|
|
506
|
+
className: `ya-row${row.id === current ? " ya-selected" : ""}${menuOpen ? " ya-menu-open" : ""}`,
|
|
422
507
|
role: "treeitem",
|
|
423
508
|
"aria-selected": row.id === current,
|
|
424
|
-
draggable: drag !== void 0,
|
|
425
509
|
onClick: () => {
|
|
426
510
|
open(row.id);
|
|
427
511
|
},
|
|
428
|
-
onDragStart: drag === void 0 ? void 0 : (event) => {
|
|
429
|
-
event.dataTransfer.effectAllowed = "move";
|
|
430
|
-
drag.start();
|
|
431
|
-
},
|
|
432
|
-
onDragEnd: drag?.end,
|
|
433
|
-
onDragOver: drag === void 0 ? void 0 : (event) => {
|
|
434
|
-
if (!drag.active) return;
|
|
435
|
-
event.preventDefault();
|
|
436
|
-
event.dataTransfer.dropEffect = "move";
|
|
437
|
-
drag.hover(rowHalf(event));
|
|
438
|
-
},
|
|
439
|
-
onDrop: drag === void 0 ? void 0 : (event) => {
|
|
440
|
-
if (!drag.active) return;
|
|
441
|
-
event.preventDefault();
|
|
442
|
-
drag.drop(rowHalf(event));
|
|
443
|
-
},
|
|
444
512
|
children: [
|
|
445
513
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
446
514
|
className: "ya-status-slot",
|
|
@@ -586,7 +654,7 @@ button.ya-crumb:hover { background:var(--dsw-alias-interactive-bg-hover); color:
|
|
|
586
654
|
}
|
|
587
655
|
/** Fill `sidebar.workspaces` with the replacement browser. */
|
|
588
656
|
function WorkspaceSidebar(props) {
|
|
589
|
-
const { wide, expandSidebar, useSessions, useWorkspaces, startSession, open, searchSessions, searchResultLimit, renameSession, forkSession, renameWorkspace, deleteWorkspace, archiveSession,
|
|
657
|
+
const { wide, expandSidebar, useSessions, useWorkspaces, startSession, open, searchSessions, searchResultLimit, renameSession, forkSession, renameWorkspace, deleteWorkspace, archiveSession, createWorkspace, useDirectoryFlow, renderSlot, t } = props;
|
|
590
658
|
const sessions = useSessions((state) => state);
|
|
591
659
|
const workspaceState = useWorkspaces((state) => state);
|
|
592
660
|
const workspaces = workspaceState.items;
|
|
@@ -624,8 +692,16 @@ button.ya-crumb:hover { background:var(--dsw-alias-interactive-bg-hover); color:
|
|
|
624
692
|
if (selectedKey !== null && selectedKey !== "__ya_ungrouped__" && !workspaces.some((workspace) => workspace.workspaceId === selectedKey)) setSelectedKey(UNGROUPED);
|
|
625
693
|
}, [selectedKey, workspaces]);
|
|
626
694
|
const selectedWorkspace = selectedKey === null || selectedKey === "__ya_ungrouped__" ? void 0 : workspaces.find((workspace) => workspace.workspaceId === selectedKey);
|
|
627
|
-
const levelRows = selectedKey === null ? [] : deriveWorkspaceSessions(selectedKey, sessions, workspaces, archived);
|
|
628
695
|
const now = Date.now();
|
|
696
|
+
const levelGroups = (0, react.useMemo)(() => selectedKey !== null && selectedKey !== "__ya_ungrouped__" ? deriveWorkspaceSessionGroups(selectedKey, sessions, workspaces, archived, now) : [], [
|
|
697
|
+
archived,
|
|
698
|
+
sessions,
|
|
699
|
+
workspaces,
|
|
700
|
+
selectedKey,
|
|
701
|
+
now
|
|
702
|
+
]);
|
|
703
|
+
const levelRows = selectedKey === "__ya_ungrouped__" ? deriveWorkspaceSessions(UNGROUPED, sessions, workspaces, archived) : [];
|
|
704
|
+
const levelEmpty = selectedKey === "__ya_ungrouped__" ? levelRows.length === 0 : levelGroups.every((g) => g.rows.length === 0);
|
|
629
705
|
const [query, setQuery] = (0, react.useState)("");
|
|
630
706
|
const normalizedQuery = sanitized(query).trim();
|
|
631
707
|
const [remote, setRemote] = (0, react.useState)({
|
|
@@ -696,7 +772,6 @@ button.ya-crumb:hover { background:var(--dsw-alias-interactive-bg-hover); color:
|
|
|
696
772
|
const [renameError, setRenameError] = (0, react.useState)(null);
|
|
697
773
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
698
774
|
const [deleteTarget, setDeleteTarget] = (0, react.useState)(null);
|
|
699
|
-
const [drag, setDrag] = (0, react.useState)(null);
|
|
700
775
|
const beginWorkspaceRename = (row) => {
|
|
701
776
|
setWorkspaceRename(row);
|
|
702
777
|
setRenameDraft(row.title);
|
|
@@ -746,54 +821,17 @@ button.ya-crumb:hover { background:var(--dsw-alias-interactive-bg-hover); color:
|
|
|
746
821
|
const fork = (id) => {
|
|
747
822
|
forkSession(id);
|
|
748
823
|
};
|
|
749
|
-
const sessionItem = (row, context = false,
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
t,
|
|
761
|
-
context,
|
|
762
|
-
...draggable && selectedKey !== null && selectedKey !== "__ya_ungrouped__" ? { drag: {
|
|
763
|
-
active: drag !== null,
|
|
764
|
-
marker,
|
|
765
|
-
start: () => {
|
|
766
|
-
setDrag({
|
|
767
|
-
id: row.id,
|
|
768
|
-
over: null
|
|
769
|
-
});
|
|
770
|
-
},
|
|
771
|
-
hover: (half) => {
|
|
772
|
-
setDrag((value) => value === null ? value : {
|
|
773
|
-
...value,
|
|
774
|
-
over: {
|
|
775
|
-
id: row.id,
|
|
776
|
-
half
|
|
777
|
-
}
|
|
778
|
-
});
|
|
779
|
-
},
|
|
780
|
-
drop: (half) => {
|
|
781
|
-
if (drag === null) return;
|
|
782
|
-
const anchor = half === "before" ? row.id : levelRows[(index ?? 0) + 1]?.id;
|
|
783
|
-
const sourceIndex = levelRows.findIndex((item) => item.id === drag.id);
|
|
784
|
-
const anchorIndex = anchor === void 0 ? levelRows.length : levelRows.findIndex((item) => item.id === anchor);
|
|
785
|
-
setDrag(null);
|
|
786
|
-
if (anchor === drag.id || sourceIndex === anchorIndex || sourceIndex + 1 === anchorIndex) return;
|
|
787
|
-
insertSessionBefore(selectedKey, drag.id, anchor).catch((reason) => {
|
|
788
|
-
console.warn("session reorder rejected:", reason);
|
|
789
|
-
});
|
|
790
|
-
},
|
|
791
|
-
end: () => {
|
|
792
|
-
setDrag(null);
|
|
793
|
-
}
|
|
794
|
-
} } : {}
|
|
795
|
-
}, row.id);
|
|
796
|
-
};
|
|
824
|
+
const sessionItem = (row, context = false) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionItem, {
|
|
825
|
+
row,
|
|
826
|
+
current: sessions.current,
|
|
827
|
+
now,
|
|
828
|
+
open,
|
|
829
|
+
rename: beginSessionRename,
|
|
830
|
+
fork,
|
|
831
|
+
archive,
|
|
832
|
+
t,
|
|
833
|
+
context
|
|
834
|
+
}, row.id);
|
|
797
835
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
798
836
|
"data-ya-workspace-sidebar": true,
|
|
799
837
|
className: wide ? "" : "ya-rail",
|
|
@@ -970,12 +1008,16 @@ button.ya-crumb:hover { background:var(--dsw-alias-interactive-bg-hover); color:
|
|
|
970
1008
|
setRenameError(null);
|
|
971
1009
|
},
|
|
972
1010
|
t
|
|
973
|
-
}, row.key)) : levelRows.map((row
|
|
1011
|
+
}, row.key)) : selectedKey === "__ya_ungrouped__" ? levelRows.map((row) => sessionItem(row, false)) : levelGroups.flatMap((group) => [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1012
|
+
className: "ya-date-group-label",
|
|
1013
|
+
role: "separator",
|
|
1014
|
+
children: dateGroupLabel(group, now, t)
|
|
1015
|
+
}, `group-${group.dateKey}`), ...group.rows.map((row) => sessionItem(row, false))]),
|
|
974
1016
|
selectedKey === null && workspaceRows.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
975
1017
|
className: "ya-empty",
|
|
976
1018
|
children: t("noWorkspaces")
|
|
977
1019
|
}),
|
|
978
|
-
selectedKey !== null &&
|
|
1020
|
+
selectedKey !== null && levelEmpty && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
979
1021
|
className: "ya-empty",
|
|
980
1022
|
children: t("noSessions")
|
|
981
1023
|
})
|
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["useState","useCallback","IconPlusOutline16","IconFolderClose16","Menu","Modal","Button","StateDot","useState","Menu","IconEditOutline16","IconBranchOutline16","IconArchiveOutline20","IconEllipsisOutline16","IconFolderClose16","IconTrashOutline16","IconPlusOutline16","IconChevronRightOutline14","useMemo","useRef","IconProjectAddOutline16","IconSearchOutline16","IconCloseFill14","Modal","Button"],"sources":["../src/client/locales.ts","../src/client/styles.ts","../src/client/WorkspacePicker.tsx","../src/client/model.ts","../src/client/WorkspaceSidebar.tsx","../src/client/index.ts"],"sourcesContent":["/** Product copy for the replacement workspace browser. */\nexport const zh = {\n workspaces: '工作区',\n sessions: '会话',\n recent: '最近会话',\n ungrouped: '未分组',\n newSession: '新会话',\n untitled: '未命名会话',\n addWorkspace: '添加工作区',\n addWorkspaceMenu: '添加工作区…',\n search: '搜索会话',\n searchPlaceholder: '搜索名称、关键词…',\n clearSearch: '清除搜索',\n searching: '正在搜索会话历史…',\n searchUnavailable: '内容搜索暂不可用,仅显示名称匹配。',\n noMatches: '无匹配会话',\n noSessions: '暂无会话',\n noWorkspaces: '暂无工作区',\n loading: '正在加载工作区…',\n rename: '重命名',\n renameWorkspace: '重命名工作区',\n renameSession: '重命名会话',\n deleteWorkspace: '删除工作区',\n deleteDescription: '将把“{name}”从工作区列表中移除。文件夹与会话记录会保留。',\n fork: '分叉会话',\n archive: '归档会话',\n cancel: '取消',\n confirm: '确认',\n retry: '重新选择',\n folderError: '无法打开文件夹',\n workspaceName: '工作区名称',\n sessionName: '会话名称',\n count: '{n} 个会话',\n now: '刚刚',\n minutes: '{n}分钟',\n hours: '{n}小时',\n days: '{n}天',\n months: '{n}个月',\n years: '{n}年',\n running: '进行中',\n waiting: '等待交互',\n completed: '已完成',\n collapse: '折叠',\n expand: '展开',\n} satisfies Record<string, string>\n\nexport type YaWorkspaceKey = keyof typeof zh\n\nexport const en = {\n workspaces: 'Workspaces',\n sessions: 'Sessions',\n recent: 'Recent Sessions',\n ungrouped: 'Ungrouped',\n newSession: 'New Session',\n untitled: 'Untitled session',\n addWorkspace: 'Add workspace',\n addWorkspaceMenu: 'Add workspace…',\n search: 'Search sessions',\n searchPlaceholder: 'Search name, keywords...',\n clearSearch: 'Clear search',\n searching: 'Searching session history…',\n searchUnavailable: 'Content search is unavailable. Showing name matches.',\n noMatches: 'No matching sessions',\n noSessions: 'No sessions yet',\n noWorkspaces: 'No workspaces yet',\n loading: 'Loading workspaces…',\n rename: 'Rename',\n renameWorkspace: 'Rename workspace',\n renameSession: 'Rename session',\n deleteWorkspace: 'Delete workspace',\n deleteDescription: 'This removes “{name}” from the workspace list. The folder and session logs remain.',\n fork: 'Fork session',\n archive: 'Archive session',\n cancel: 'Cancel',\n confirm: 'Confirm',\n retry: 'Choose again',\n folderError: 'Couldn’t open folder',\n workspaceName: 'Workspace name',\n sessionName: 'Session name',\n count: '{n} sessions',\n now: 'now',\n minutes: '{n}min',\n hours: '{n}h',\n days: '{n}d',\n months: '{n}mo',\n years: '{n}y',\n running: 'Running',\n waiting: 'Waiting for interaction',\n completed: 'Completed',\n collapse: 'Collapse',\n expand: 'Expand',\n} satisfies Record<YaWorkspaceKey, string>\n\nexport const NS = 'ya-workspace-sidebar'\n","/** One scoped stylesheet injected for the lifetime of the client activation. */\nexport const CSS = `\n[data-ya-workspace-sidebar] { flex:1; min-height:0; display:flex; flex-direction:column; box-sizing:border-box; padding-right:var(--dsh-sidebar-inline-padding); color:var(--dsw-alias-label-primary); }\n[data-ya-workspace-sidebar].ya-rail { padding-right:0; }\n.ya-section-header { flex:none; height:36px; display:flex; align-items:center; justify-content:flex-end; gap:4px; padding-left:12px; margin-bottom:4px; box-sizing:border-box; color:var(--dsw-alias-label-tertiary); }\n.ya-section-title { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:14px; }\n.ya-icon-button { flex:none; width:28px; height:28px; border:0; border-radius:50%; padding:0; display:inline-flex; align-items:center; justify-content:center; color:var(--dsw-alias-label-secondary); background:transparent; cursor:pointer; }\n.ya-icon-button:hover { background:var(--dsw-alias-interactive-bg-hover); }\n.ya-search { flex:none; height:38px; margin:0 2px 10px; padding:0 14px; display:flex; align-items:center; gap:8px; box-sizing:border-box; border:1px solid var(--dsw-alias-border-l2); border-radius:24px; background:var(--dsw-static-neutral-bluish-75); color:var(--dsw-alias-label-caption); }\nbody[data-ds-dark-theme] .ya-search { background:var(--dsw-static-neutral-bluish-900); }\n.ya-search-input { flex:1; min-width:0; border:0; outline:0; background:transparent; color:var(--dsw-alias-label-primary); font:inherit; font-size:14px; }\n.ya-search-input::placeholder { color:var(--dsw-alias-label-tertiary); }\n.ya-search-icon { flex:none; display:inline-flex; border:0; padding:0; color:inherit; background:transparent; }\n.ya-body { flex:1; min-height:0; display:flex; flex-direction:column; overflow:hidden; margin-right:calc(-1 * var(--dsh-sidebar-inline-padding)); padding-right:var(--dsh-sidebar-inline-padding); }\n.ya-recent { flex:none; padding-bottom:8px; border-bottom:1px solid var(--dsw-alias-border-l2); }\n.ya-recent-collapsed { padding-bottom:0; border-bottom-color:transparent; }\n.ya-recent-list-wrap { display:grid; grid-template-rows:1fr; transition:grid-template-rows 220ms ease-out; }\n.ya-recent-collapsed .ya-recent-list-wrap { grid-template-rows:0fr; }\n.ya-recent-list { display:flex; flex-direction:column; overflow:hidden; min-height:0; }\n.ya-block-label { height:26px; display:flex; align-items:center; gap:2px; padding:0 8px; color:var(--dsw-alias-label-tertiary); font-size:12px; font-weight:600; letter-spacing:.02em; text-transform:uppercase; }\n.ya-block-label-toggle { flex:none; width:20px; height:20px; margin-left:auto; border:0; border-radius:6px; padding:0; display:inline-flex; align-items:center; justify-content:center; background:transparent; color:var(--dsw-alias-label-tertiary); cursor:pointer; transition:transform 180ms ease-out; }\n.ya-block-label-toggle:hover { background:var(--dsw-alias-interactive-bg-hover); color:var(--dsw-alias-label-secondary); }\n.ya-block-label-toggle.ya-collapsed { transform:rotate(-90deg); }\n.ya-breadcrumb { flex:none; height:34px; display:flex; align-items:center; gap:2px; padding:0 6px; color:var(--dsw-alias-label-tertiary); font-size:13px; }\n.ya-crumb { border:0; padding:4px 3px; border-radius:6px; background:transparent; color:inherit; font:inherit; cursor:default; min-width:0; overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }\nbutton.ya-crumb:hover { background:var(--dsw-alias-interactive-bg-hover); color:var(--dsw-alias-label-primary); cursor:pointer; }\n.ya-scroll { flex:1; min-height:0; overflow-y:auto; padding-bottom:12px; }\n.ya-row { position:relative; min-height:34px; display:flex; align-items:center; gap:6px; margin:1px 0; padding:0 7px; border-radius:9px; box-sizing:border-box; color:var(--dsw-alias-label-primary); cursor:pointer; user-select:none; }\n.ya-row:hover, .ya-row.ya-menu-open { background:var(--dsw-alias-interactive-bg-hover); }\n.ya-row.ya-selected { background:var(--dsw-alias-interactive-bg-selected); }\n.ya-workspace-row { min-height:40px; }\n.ya-row-main { flex:1; min-width:0; display:flex; flex-direction:column; justify-content:center; }\n.ya-row-line { display:flex; align-items:center; min-width:0; gap:6px; }\n.ya-row-title { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:13px; line-height:18px; }\n.ya-row-meta { flex:none; color:var(--dsw-alias-label-tertiary); font-size:11px; white-space:nowrap; }\n.ya-workspace-path { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--dsw-alias-label-tertiary); font-size:11px; line-height:15px; }\n.ya-row-actions { flex:none; display:flex; align-items:center; gap:2px; opacity:0; pointer-events:none; transition:opacity 120ms ease-out; }\n.ya-row:hover .ya-row-actions, .ya-menu-open .ya-row-actions { opacity:1; pointer-events:auto; }\n.ya-status-slot { flex:none; width:16px; height:16px; display:inline-flex; align-items:center; justify-content:center; color:var(--dsw-alias-label-tertiary); }\n.ya-recent .ya-row { min-height:31px; }\n.ya-search-workspace { color:var(--dsw-alias-label-tertiary); font-size:11px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }\n.ya-empty, .ya-status { padding:18px 10px; color:var(--dsw-alias-label-tertiary); text-align:center; font-size:13px; }\n.ya-warning { color:var(--dsw-alias-status-warning); }\n.ya-rename-input { width:100%; height:38px; box-sizing:border-box; border:1px solid var(--dsw-alias-border-l2); border-radius:9px; padding:0 11px; background:transparent; color:var(--dsw-alias-label-primary); outline:none; }\n.ya-error { margin-top:8px; color:var(--dsw-alias-status-error); font-size:12px; }\n.ya-drop-before::before, .ya-drop-after::after { content:''; position:absolute; left:8px; right:8px; height:2px; border-radius:2px; background:var(--dsw-alias-label-link); }\n.ya-drop-before::before { top:-2px; } .ya-drop-after::after { bottom:-2px; }\n.ya-rail .ya-section-header { padding-left:0; margin-bottom:12px; }\n.ya-rail .ya-icon-button, .ya-rail .ya-search { width:36px; height:36px; padding:0; margin:0 0 12px; border-color:transparent; background:transparent; }\n.ya-rail .ya-search { justify-content:center; }\n.ya-rail .ya-search-icon { cursor:pointer; color:var(--dsw-alias-label-primary); }\n.ya-picker-error { color:var(--dsw-alias-status-error); white-space:pre-wrap; }\n@keyframes ya-slide-in-forward { from { opacity:0; transform:translateX(10px); } to { opacity:1; transform:translateX(0); } }\n@keyframes ya-slide-in-backward { from { opacity:0; transform:translateX(-10px); } to { opacity:1; transform:translateX(0); } }\n.ya-level-enter-forward { animation:ya-slide-in-forward 180ms ease-out; }\n.ya-level-enter-backward { animation:ya-slide-in-backward 180ms ease-out; }\n`\n\n/** Install the stylesheet and return its disposer. */\nexport function installStyles(): () => void {\n const style = document.createElement('style')\n style.setAttribute('data-ya-workspace-sidebar-style', '')\n style.textContent = CSS\n document.head.appendChild(style)\n return () => { style.remove() }\n}\n","/** Existing-workspace menu plus composed directory-adoption flow. */\nimport type { ReactNode, RefObject } from 'react'\nimport { useCallback, useEffect, useState } from 'react'\nimport {\n Button, IconFolderClose16, IconPlusOutline16, Menu, Modal, type MenuEntry,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport type {\n WorkspaceId, WorkspaceListState, WorkspaceView,\n} from '@deepseek-ai/dsh-client-runtime/client'\nimport type { SnapshotSelectorHook } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { DirectoryFlowOwnerProps, PickerProps } from './contract.ts'\n\nconst ADD = '::ya-add-workspace'\n\ninterface FlowProps {\n t: PickerProps['t']\n open: boolean\n anchorRef?: RefObject<HTMLElement | null>\n useWorkspaces: <S>(selector: (state: WorkspaceListState) => S) => S\n createWorkspace: (input: { path: string }) => Promise<WorkspaceView>\n useDirectoryFlow: SnapshotSelectorHook<boolean>\n renderDirectoryFlow: (owner: DirectoryFlowOwnerProps) => ReactNode\n onPick: (workspaceId: WorkspaceId) => void\n onClose: () => void\n addOnly?: boolean\n side?: 'bottom' | 'top' | 'right'\n selectedId?: WorkspaceId\n}\n\n/** Render the workspace target menu and directory picking conversation. */\nexport function WorkspacePickFlow({\n t, open, anchorRef, useWorkspaces, createWorkspace, useDirectoryFlow,\n renderDirectoryFlow, onPick, onClose, addOnly = false, side = 'bottom', selectedId,\n}: FlowProps) {\n const snapshot = useWorkspaces(state => state)\n const flowAvailable = useDirectoryFlow(value => value)\n const [flowOpen, setFlowOpen] = useState(false)\n const [busy, setBusy] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const getAnchorRect = useCallback(\n () => anchorRef?.current?.getBoundingClientRect() ?? null,\n [anchorRef],\n )\n useEffect(() => {\n if (flowOpen && !flowAvailable) setFlowOpen(false)\n }, [flowAvailable, flowOpen])\n\n const openFlow = useCallback(() => {\n onClose()\n setError(null)\n setFlowOpen(true)\n }, [onClose])\n const addEntries: MenuEntry[] = flowAvailable\n ? [{ id: ADD, label: t('addWorkspaceMenu'), icon: <IconPlusOutline16 size={16} />, disabled: flowOpen || busy }]\n : []\n const pinnedAdd = !addOnly && snapshot.items.length > 0\n const items: MenuEntry[] = pinnedAdd\n ? snapshot.items.map(workspace => ({\n id: workspace.workspaceId,\n label: workspace.title,\n icon: <IconFolderClose16 size={16} />,\n disabled: flowOpen || busy,\n }))\n : addEntries\n const settled = addOnly || snapshot.phase === 'ready'\n const onlyAdd = !pinnedAdd && settled && addEntries.length === 1\n useEffect(() => {\n if (open && onlyAdd && !flowOpen && !busy) openFlow()\n }, [busy, flowOpen, onlyAdd, open, openFlow])\n\n const owner: DirectoryFlowOwnerProps = {\n open: flowOpen,\n busy,\n onPicked: (path) => {\n setBusy(true)\n createWorkspace({ path }).then(workspace => {\n setFlowOpen(false)\n onPick(workspace.workspaceId)\n }).catch((reason: unknown) => {\n setFlowOpen(false)\n setError(reason instanceof Error ? reason.message : String(reason))\n }).finally(() => { setBusy(false) })\n },\n onCancel: () => { setFlowOpen(false) },\n onError: (message) => { setFlowOpen(false); setError(message) },\n }\n\n return (\n <>\n <Menu\n open={open && !onlyAdd && items.length > 0}\n anchor={null}\n items={items}\n {...pinnedAdd ? { footer: addEntries } : {}}\n selectedId={selectedId}\n onSelect={(id) => { if (id === ADD) openFlow(); else onPick(id as WorkspaceId) }}\n onClose={onClose}\n side={side}\n portal\n getAnchorRect={getAnchorRect}\n />\n {open && !onlyAdd && snapshot.phase === 'pending' && <div className=\"ya-status\">{t('loading')}</div>}\n {renderDirectoryFlow(owner)}\n <Modal\n open={error !== null}\n onClose={() => { setError(null) }}\n closeLabel={t('cancel')}\n title={t('folderError')}\n footer={(\n <>\n <Button variant=\"outline\" onClick={() => { setError(null) }}>{t('cancel')}</Button>\n <Button variant=\"primary\" disabled={!flowAvailable} onClick={openFlow}>{t('retry')}</Button>\n </>\n )}\n >\n <div className=\"ya-picker-error\" role=\"alert\">{error}</div>\n </Modal>\n </>\n )\n}\n\n/** Fill the conversation hero's workspace picker seat. */\nexport function WorkspacePicker({\n open, anchorRef, useWorkspaces, selectedId, onPick, onClose,\n createWorkspace, useDirectoryFlow, renderSlot, t,\n}: PickerProps) {\n return (\n <WorkspacePickFlow\n t={t}\n open={open}\n anchorRef={anchorRef}\n useWorkspaces={useWorkspaces}\n selectedId={selectedId}\n onPick={onPick}\n onClose={onClose}\n createWorkspace={createWorkspace}\n useDirectoryFlow={useDirectoryFlow}\n renderDirectoryFlow={owner => renderSlot('conversation.hero.workspace.directoryFlow', owner)}\n />\n )\n}\n","/** Pure sidebar projections shared by the browser and unit tests. */\nimport type {\n SessionId, SessionListState, SessionSummary, WorkspaceId, WorkspaceView,\n} from '@deepseek-ai/dsh-client-runtime/client'\n\n/** Navigation key for sessions not accounted to a real workspace. */\nexport const UNGROUPED = '__ya_ungrouped__' as const\n\n/** One sidebar session row. */\nexport interface SessionRow {\n id: SessionId\n title: string\n /** Whether the session has a durable log-backed title (summary.title !== undefined). */\n hasTitle: boolean\n blank: boolean\n running: boolean\n pendingInteraction?: SessionSummary['pendingInteraction']\n completed: boolean\n updatedAt: number\n workspaceKey: WorkspaceId | typeof UNGROUPED\n workspaceTitle: string\n}\n\n/** One first-level workspace row. */\nexport interface WorkspaceRow {\n key: WorkspaceId | typeof UNGROUPED\n title: string\n path?: string\n createdAt?: string\n count: number\n real: boolean\n}\n\nfunction visible(summary: SessionSummary, current: SessionId | undefined, archived: ReadonlySet<SessionId>): boolean {\n return summary.origin !== 'subagent'\n && !archived.has(summary.id)\n && (!summary.blank || summary.id === current)\n}\n\nfunction rowOf(\n summary: SessionSummary,\n workspaceKey: WorkspaceId | typeof UNGROUPED,\n workspaceTitle: string,\n): SessionRow {\n return {\n id: summary.id,\n title: summary.blank ? 'New Session' : summary.displayTitle,\n hasTitle: summary.title !== undefined,\n blank: summary.blank,\n running: summary.running,\n ...(summary.pendingInteraction === undefined ? {} : { pendingInteraction: summary.pendingInteraction }),\n completed: summary.completed === true,\n updatedAt: summary.updatedAt,\n workspaceKey,\n workspaceTitle,\n }\n}\n\nfunction ownerIndex(workspaces: readonly WorkspaceView[]): Map<SessionId, WorkspaceView> {\n const result = new Map<SessionId, WorkspaceView>()\n for (const workspace of workspaces) {\n for (const sessionId of workspace.sessionIds) result.set(sessionId, workspace)\n }\n return result\n}\n\n/** Resolve the first/second-level destination for one session. */\nexport function workspaceKeyForSession(\n sessionId: SessionId | undefined,\n workspaces: readonly WorkspaceView[],\n): WorkspaceId | typeof UNGROUPED | null {\n if (sessionId === undefined) return null\n return ownerIndex(workspaces).get(sessionId)?.workspaceId ?? UNGROUPED\n}\n\n/** Derive global recent sessions, newest first. */\nexport function deriveRecent(\n list: SessionListState,\n workspaces: readonly WorkspaceView[],\n archivedSessionIds: readonly SessionId[],\n limit = 5,\n): SessionRow[] {\n const archived = new Set(archivedSessionIds)\n const owners = ownerIndex(workspaces)\n return list.ids\n .map(id => list.byId[id])\n .filter((summary): summary is SessionSummary => summary !== undefined && visible(summary, list.current, archived))\n .sort((a, b) => b.updatedAt - a.updatedAt || String(a.id).localeCompare(String(b.id)))\n .slice(0, limit)\n .map((summary) => {\n const workspace = owners.get(summary.id)\n return rowOf(summary, workspace?.workspaceId ?? UNGROUPED, workspace?.title ?? 'Ungrouped')\n })\n}\n\n/** Derive first-level real workspaces plus the virtual Ungrouped row. */\nexport function deriveWorkspaces(\n list: SessionListState,\n workspaces: readonly WorkspaceView[],\n archivedSessionIds: readonly SessionId[],\n): WorkspaceRow[] {\n const archived = new Set(archivedSessionIds)\n const accounted = new Set<SessionId>()\n const result = workspaces.map((workspace): WorkspaceRow => {\n let count = 0\n for (const id of workspace.sessionIds) {\n accounted.add(id)\n const summary = list.byId[id]\n if (summary !== undefined && visible(summary, list.current, archived)) count++\n }\n return {\n key: workspace.workspaceId,\n title: workspace.title,\n path: workspace.path,\n createdAt: workspace.createdAt,\n count,\n real: true,\n }\n })\n let ungrouped = 0\n for (const id of list.ids) {\n const summary = list.byId[id]\n if (summary !== undefined && !accounted.has(id) && visible(summary, list.current, archived)) ungrouped++\n }\n result.push({ key: UNGROUPED, title: 'Ungrouped', count: ungrouped, real: false })\n return result\n}\n\n/** Derive the selected workspace's sessions in its canonical order. */\nexport function deriveWorkspaceSessions(\n key: WorkspaceId | typeof UNGROUPED,\n list: SessionListState,\n workspaces: readonly WorkspaceView[],\n archivedSessionIds: readonly SessionId[],\n): SessionRow[] {\n const archived = new Set(archivedSessionIds)\n if (key === UNGROUPED) {\n const accounted = new Set(workspaces.flatMap(workspace => workspace.sessionIds))\n return list.ids\n .map(id => list.byId[id])\n .filter((summary): summary is SessionSummary => summary !== undefined\n && !accounted.has(summary.id)\n && visible(summary, list.current, archived))\n .sort((a, b) => b.updatedAt - a.updatedAt || String(a.id).localeCompare(String(b.id)))\n .map(summary => rowOf(summary, UNGROUPED, 'Ungrouped'))\n }\n const workspace = workspaces.find(item => item.workspaceId === key)\n if (workspace === undefined) return []\n return workspace.sessionIds\n .map(id => list.byId[id])\n .filter((summary): summary is SessionSummary => summary !== undefined && visible(summary, list.current, archived))\n .map(summary => rowOf(summary, workspace.workspaceId, workspace.title))\n}\n\n/** Case-insensitive local title/workspace matching used beside Host content search. */\nexport function localMatches(rows: readonly SessionRow[], query: string): SessionRow[] {\n const normalized = query.trim().toLocaleLowerCase()\n if (normalized === '') return []\n return rows.filter(row => `${row.title}\\n${row.workspaceTitle}`.toLocaleLowerCase().includes(normalized))\n}\n","/** Two-level workspace/session browser with a persistent global recent block. */\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport {\n Button, IconArchiveOutline20, IconBranchOutline16, IconChevronRightOutline14,\n IconCloseFill14, IconEditOutline16, IconEllipsisOutline16, IconFolderClose16,\n IconPlusOutline16, IconProjectAddOutline16, IconSearchOutline16, IconTrashOutline16,\n Menu, Modal, StateDot,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { SessionId, WorkspaceId } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { SidebarProps } from './contract.ts'\nimport {\n deriveRecent, deriveWorkspaceSessions, deriveWorkspaces, localMatches,\n UNGROUPED, workspaceKeyForSession, type SessionRow, type WorkspaceRow,\n} from './model.ts'\nimport { WorkspacePickFlow } from './WorkspacePicker.tsx'\n\nconst SEARCH_DEBOUNCE_MS = 250\nconst SEARCH_MAX = 500\n\nfunction sanitized(value: string): string {\n return value.replaceAll('\\0', '').slice(0, SEARCH_MAX)\n}\n\nfunction relativeTime(updatedAt: number, now: number, t: SidebarProps['t']): string {\n const diff = Math.max(0, now - updatedAt)\n const minute = 60_000\n if (diff < minute) return t('now')\n if (diff < 60 * minute) return t('minutes', { n: Math.floor(diff / minute) })\n if (diff < 24 * 60 * minute) return t('hours', { n: Math.floor(diff / (60 * minute)) })\n if (diff < 30 * 24 * 60 * minute) return t('days', { n: Math.floor(diff / (24 * 60 * minute)) })\n if (diff < 365 * 24 * 60 * minute) return t('months', { n: Math.floor(diff / (30 * 24 * 60 * minute)) })\n return t('years', { n: Math.floor(diff / (365 * 24 * 60 * minute)) })\n}\n\nfunction SessionStatus({ row }: { row: SessionRow }) {\n if (row.pendingInteraction !== undefined) return <StateDot state=\"warning\" />\n if (row.running) return <StateDot state=\"ongoing\" />\n if (row.completed) return <StateDot state=\"done\" />\n return null\n}\n\ninterface SessionRowProps {\n row: SessionRow\n current: SessionId | undefined\n now: number\n open: (id: SessionId) => void\n rename: (row: SessionRow) => void\n fork: (id: SessionId) => void\n archive: (id: SessionId) => void\n t: SidebarProps['t']\n context?: boolean\n drag?: {\n active: boolean\n marker: 'before' | 'after' | null\n start: () => void\n hover: (half: 'before' | 'after') => void\n drop: (half: 'before' | 'after') => void\n end: () => void\n }\n}\n\nfunction rowHalf(event: { clientY: number; currentTarget: HTMLElement }): 'before' | 'after' {\n const rect = event.currentTarget.getBoundingClientRect()\n return event.clientY < rect.top + rect.height / 2 ? 'before' : 'after'\n}\n\nfunction SessionItem({ row, current, now, open, rename, fork, archive, t, context, drag }: SessionRowProps) {\n const [menuOpen, setMenuOpen] = useState(false)\n const title = row.blank ? t('newSession') : row.hasTitle ? row.title : t('untitled')\n return (\n <div\n className={`ya-row${row.id === current ? ' ya-selected' : ''}${menuOpen ? ' ya-menu-open' : ''}${drag?.marker === 'before' ? ' ya-drop-before' : ''}${drag?.marker === 'after' ? ' ya-drop-after' : ''}`}\n role=\"treeitem\"\n aria-selected={row.id === current}\n draggable={drag !== undefined}\n onClick={() => { open(row.id) }}\n onDragStart={drag === undefined ? undefined : (event) => { event.dataTransfer.effectAllowed = 'move'; drag.start() }}\n onDragEnd={drag?.end}\n onDragOver={drag === undefined ? undefined : (event) => {\n if (!drag.active) return\n event.preventDefault()\n event.dataTransfer.dropEffect = 'move'\n drag.hover(rowHalf(event))\n }}\n onDrop={drag === undefined ? undefined : (event) => {\n if (!drag.active) return\n event.preventDefault()\n drag.drop(rowHalf(event))\n }}\n >\n <span className=\"ya-status-slot\"><SessionStatus row={row} /></span>\n <span className=\"ya-row-main\">\n <span className=\"ya-row-line\">\n <span className=\"ya-row-title\">{title}</span>\n {!row.blank && <span className=\"ya-row-meta ya-row-time\">{relativeTime(row.updatedAt, now, t)}</span>}\n </span>\n {context === true && <span className=\"ya-search-workspace\">{row.workspaceTitle}</span>}\n </span>\n {!row.blank && (\n <span className=\"ya-row-actions\">\n <Menu\n open={menuOpen}\n onClose={() => { setMenuOpen(false) }}\n items={[\n { id: 'rename', label: t('rename'), icon: <IconEditOutline16 /> },\n { id: 'fork', label: t('fork'), icon: <IconBranchOutline16 /> },\n { id: 'archive', label: t('archive'), icon: <IconArchiveOutline20 size={16} /> },\n ]}\n onSelect={(id) => {\n setMenuOpen(false)\n if (id === 'rename') rename(row)\n if (id === 'fork') fork(row.id)\n if (id === 'archive') archive(row.id)\n }}\n portal\n closeOnPointerLeave\n anchor={(\n <button\n type=\"button\"\n className=\"ya-icon-button\"\n aria-label={`${title} actions`}\n onClick={(event) => { event.stopPropagation(); setMenuOpen(value => !value) }}\n >\n <IconEllipsisOutline16 />\n </button>\n )}\n />\n </span>\n )}\n </div>\n )\n}\n\nfunction WorkspaceItem({ row, enter, create, rename, remove, t }: {\n row: WorkspaceRow\n enter: () => void\n create: () => void\n rename: () => void\n remove: () => void\n t: SidebarProps['t']\n}) {\n const [menuOpen, setMenuOpen] = useState(false)\n return (\n <div className={`ya-row ya-workspace-row${menuOpen ? ' ya-menu-open' : ''}`} role=\"treeitem\" onClick={enter} title={row.path}>\n <span className=\"ya-status-slot\"><IconFolderClose16 /></span>\n <span className=\"ya-row-main\">\n <span className=\"ya-row-line\">\n <span className=\"ya-row-title\">{row.real ? row.title : t('ungrouped')}</span>\n <span className=\"ya-row-meta\">{t('count', { n: row.count })}</span>\n </span>\n {row.path !== undefined && <span className=\"ya-workspace-path\">{row.path}</span>}\n </span>\n <span className=\"ya-row-actions\">\n {row.real && (\n <Menu\n open={menuOpen}\n onClose={() => { setMenuOpen(false) }}\n items={[\n { id: 'rename', label: t('rename'), icon: <IconEditOutline16 /> },\n { id: 'delete', label: t('deleteWorkspace'), icon: <IconTrashOutline16 />, danger: true },\n ]}\n onSelect={(id) => { setMenuOpen(false); if (id === 'rename') rename(); if (id === 'delete') remove() }}\n portal\n closeOnPointerLeave\n anchor={(\n <button type=\"button\" className=\"ya-icon-button\" onClick={(event) => { event.stopPropagation(); setMenuOpen(value => !value) }}>\n <IconEllipsisOutline16 />\n </button>\n )}\n />\n )}\n {row.real && (\n <button type=\"button\" className=\"ya-icon-button\" onClick={(event) => { event.stopPropagation(); create() }}>\n <IconPlusOutline16 />\n </button>\n )}\n </span>\n <IconChevronRightOutline14 />\n </div>\n )\n}\n\ninterface RemoteState {\n query: string\n status: 'idle' | 'loading' | 'ready' | 'error'\n items: readonly { sessionId: SessionId; snippet: string }[]\n hasMore: boolean\n}\n\n/** Fill `sidebar.workspaces` with the replacement browser. */\nexport function WorkspaceSidebar(props: SidebarProps) {\n const {\n wide, expandSidebar, useSessions, useWorkspaces, startSession, open, searchSessions,\n searchResultLimit, renameSession, forkSession, renameWorkspace, deleteWorkspace,\n archiveSession, insertSessionBefore, createWorkspace, useDirectoryFlow, renderSlot, t,\n } = props\n const sessions = useSessions(state => state)\n const workspaceState = useWorkspaces(state => state)\n const workspaces = workspaceState.items\n const archived = workspaceState.archivedSessionIds\n const directoryFlowAvailable = useDirectoryFlow(value => value)\n const allRows = useMemo(\n () => deriveRecent(sessions, workspaces, archived, Number.MAX_SAFE_INTEGER),\n [archived, sessions, workspaces],\n )\n const recent = allRows.slice(0, 5)\n const workspaceRows = useMemo(\n () => deriveWorkspaces(sessions, workspaces, archived),\n [archived, sessions, workspaces],\n )\n const [selectedKey, setSelectedKey] = useState<WorkspaceId | typeof UNGROUPED | null>(null)\n const [direction, setDirection] = useState<'forward' | 'backward'>('forward')\n const [hasMounted, setHasMounted] = useState(false)\n useEffect(() => { setHasMounted(true) }, [])\n const observedCurrent = useRef<SessionId | undefined>(undefined)\n const initialized = useRef(false)\n useEffect(() => {\n if (initialized.current && observedCurrent.current === sessions.current) return\n initialized.current = true\n observedCurrent.current = sessions.current\n if (sessions.current !== undefined) { setDirection('forward'); setSelectedKey(workspaceKeyForSession(sessions.current, workspaces)) }\n }, [sessions.current, workspaces])\n useEffect(() => {\n if (selectedKey !== null && selectedKey !== UNGROUPED\n && !workspaces.some(workspace => workspace.workspaceId === selectedKey)) setSelectedKey(UNGROUPED)\n }, [selectedKey, workspaces])\n const selectedWorkspace = selectedKey === null || selectedKey === UNGROUPED\n ? undefined\n : workspaces.find(workspace => workspace.workspaceId === selectedKey)\n const levelRows = selectedKey === null\n ? []\n : deriveWorkspaceSessions(selectedKey, sessions, workspaces, archived)\n const now = Date.now()\n\n const [query, setQuery] = useState('')\n const normalizedQuery = sanitized(query).trim()\n const [remote, setRemote] = useState<RemoteState>({ query: '', status: 'idle', items: [], hasMore: false })\n useEffect(() => {\n if (normalizedQuery === '') {\n setRemote({ query: '', status: 'idle', items: [], hasMore: false })\n return\n }\n const controller = new AbortController()\n setRemote({ query: normalizedQuery, status: 'loading', items: [], hasMore: false })\n const timer = window.setTimeout(() => {\n searchSessions(normalizedQuery, controller.signal).then(result => {\n if (!controller.signal.aborted) setRemote({ query: normalizedQuery, status: 'ready', items: result.items, hasMore: result.hasMore })\n }).catch(() => {\n if (!controller.signal.aborted) setRemote({ query: normalizedQuery, status: 'error', items: [], hasMore: false })\n })\n }, SEARCH_DEBOUNCE_MS)\n return () => { window.clearTimeout(timer); controller.abort() }\n }, [normalizedQuery, searchSessions])\n const searchRows = useMemo(() => {\n if (normalizedQuery === '') return []\n const byId = new Map(localMatches(allRows, normalizedQuery).map(row => [row.id, row]))\n if (remote.query === normalizedQuery) {\n for (const item of remote.items) {\n const row = allRows.find(candidate => candidate.id === item.sessionId)\n if (row !== undefined) byId.set(row.id, row)\n }\n }\n return [...byId.values()].slice(0, searchResultLimit)\n }, [allRows, normalizedQuery, remote, searchResultLimit])\n\n const [pickerOpen, setPickerOpen] = useState(false)\n const pickerAnchor = useRef<HTMLButtonElement>(null)\n const [recentCollapsed, setRecentCollapsed] = useState(false)\n const [workspaceRename, setWorkspaceRename] = useState<WorkspaceRow | null>(null)\n const [sessionRename, setSessionRename] = useState<SessionRow | null>(null)\n const [renameDraft, setRenameDraft] = useState('')\n const [renameError, setRenameError] = useState<string | null>(null)\n const [busy, setBusy] = useState(false)\n const [deleteTarget, setDeleteTarget] = useState<WorkspaceRow | null>(null)\n const [drag, setDrag] = useState<{ id: SessionId; over: { id: SessionId; half: 'before' | 'after' } | null } | null>(null)\n\n const beginWorkspaceRename = (row: WorkspaceRow) => { setWorkspaceRename(row); setRenameDraft(row.title); setRenameError(null) }\n const beginSessionRename = (row: SessionRow) => { setSessionRename(row); setRenameDraft(row.title); setRenameError(null) }\n const closeRename = () => { if (!busy) { setWorkspaceRename(null); setSessionRename(null); setRenameError(null) } }\n const commitRename = () => {\n const title = renameDraft.trim()\n if (title === '' || busy) return\n setBusy(true)\n const task = workspaceRename !== null && workspaceRename.key !== UNGROUPED\n ? renameWorkspace(workspaceRename.key, title)\n : sessionRename !== null ? renameSession(sessionRename.id, title) : Promise.resolve()\n task.then(() => { setWorkspaceRename(null); setSessionRename(null) })\n .catch((reason: unknown) => { setRenameError(reason instanceof Error ? reason.message : String(reason)) })\n .finally(() => { setBusy(false) })\n }\n const confirmDelete = () => {\n if (deleteTarget === null || deleteTarget.key === UNGROUPED || busy) return\n setBusy(true)\n deleteWorkspace(deleteTarget.key).then(() => { setDeleteTarget(null) })\n .catch((reason: unknown) => { setRenameError(reason instanceof Error ? reason.message : String(reason)) })\n .finally(() => { setBusy(false) })\n }\n const archive = (id: SessionId) => { archiveSession(id).catch(reason => { console.warn('session archive rejected:', reason) }) }\n const fork = (id: SessionId) => { forkSession(id) }\n\n const sessionItem = (row: SessionRow, context = false, index?: number) => {\n const draggable = selectedKey !== null && selectedKey !== UNGROUPED && index !== undefined\n const marker = drag?.over?.id === row.id ? drag.over.half : null\n return (\n <SessionItem\n key={row.id}\n row={row}\n current={sessions.current}\n now={now}\n open={open}\n rename={beginSessionRename}\n fork={fork}\n archive={archive}\n t={t}\n context={context}\n {...draggable && selectedKey !== null && selectedKey !== UNGROUPED ? {\n drag: {\n active: drag !== null,\n marker,\n start: () => { setDrag({ id: row.id, over: null }) },\n hover: (half: 'before' | 'after') => { setDrag(value => value === null ? value : { ...value, over: { id: row.id, half } }) },\n drop: (half: 'before' | 'after') => {\n if (drag === null) return\n const anchor = half === 'before' ? row.id : levelRows[(index ?? 0) + 1]?.id\n const sourceIndex = levelRows.findIndex(item => item.id === drag.id)\n const anchorIndex = anchor === undefined ? levelRows.length : levelRows.findIndex(item => item.id === anchor)\n setDrag(null)\n if (anchor === drag.id || sourceIndex === anchorIndex || sourceIndex + 1 === anchorIndex) return\n insertSessionBefore(selectedKey, drag.id, anchor).catch(reason => { console.warn('session reorder rejected:', reason) })\n },\n end: () => { setDrag(null) },\n },\n } : {}}\n />\n )\n }\n\n return (\n <div data-ya-workspace-sidebar className={wide ? '' : 'ya-rail'}>\n <div className=\"ya-section-header\">\n {wide && <span className=\"ya-section-title\">{t('workspaces')}</span>}\n {directoryFlowAvailable && (\n <button ref={pickerAnchor} type=\"button\" className=\"ya-icon-button\" aria-label={t('addWorkspace')} onClick={() => { setPickerOpen(value => !value) }}>\n <IconProjectAddOutline16 size={wide ? 16 : 18} />\n </button>\n )}\n <WorkspacePickFlow\n t={t}\n open={pickerOpen}\n anchorRef={pickerAnchor}\n useWorkspaces={useWorkspaces}\n createWorkspace={createWorkspace}\n useDirectoryFlow={useDirectoryFlow}\n renderDirectoryFlow={owner => renderSlot('sidebar.workspaces.directoryFlow', owner)}\n addOnly\n side=\"right\"\n onPick={(workspaceId) => { setPickerOpen(false); startSession(workspaceId) }}\n onClose={() => { setPickerOpen(false) }}\n />\n </div>\n\n <div className=\"ya-search\" onClick={() => { if (!wide) expandSidebar() }}>\n <button type=\"button\" className=\"ya-search-icon\" aria-label={t('search')}><IconSearchOutline16 size={wide ? 14 : 18} /></button>\n {wide && <input className=\"ya-search-input\" value={query} maxLength={SEARCH_MAX} placeholder={t('searchPlaceholder')} onChange={event => { setQuery(sanitized(event.target.value)) }} />}\n {wide && query !== '' && <button type=\"button\" className=\"ya-icon-button\" aria-label={t('clearSearch')} onClick={() => { setQuery('') }}><IconCloseFill14 /></button>}\n </div>\n\n {wide && (\n <div className=\"ya-body\">\n {normalizedQuery !== '' ? (\n <div className=\"ya-scroll\" role=\"tree\" aria-label={t('search')}>\n {searchRows.map(row => sessionItem(row, true))}\n {remote.status === 'loading' && <div className=\"ya-status\">{t('searching')}</div>}\n {remote.status === 'error' && <div className=\"ya-status ya-warning\">{t('searchUnavailable')}</div>}\n {remote.status !== 'loading' && searchRows.length === 0 && <div className=\"ya-empty\">{t('noMatches')}</div>}\n </div>\n ) : (\n <>\n <div className={`ya-recent${recentCollapsed ? ' ya-recent-collapsed' : ''}`}>\n <div className=\"ya-block-label\">\n <span>{t('recent')}</span>\n {recent.length > 0 && (\n <button\n type=\"button\"\n className={`ya-block-label-toggle${recentCollapsed ? ' ya-collapsed' : ''}`}\n aria-label={recentCollapsed ? t('expand') : t('collapse')}\n aria-expanded={!recentCollapsed}\n onClick={(event) => { event.stopPropagation(); setRecentCollapsed(value => !value) }}\n >\n <IconChevronRightOutline14 />\n </button>\n )}\n </div>\n <div className=\"ya-recent-list-wrap\">\n {recent.length === 0\n ? <div className=\"ya-empty\">{t('noSessions')}</div>\n : <div className=\"ya-recent-list\">{recent.map(row => sessionItem(row, true))}</div>\n }\n </div>\n </div>\n <div className=\"ya-breadcrumb\">\n {selectedKey === null ? (\n <span className=\"ya-crumb\">{t('workspaces')}</span>\n ) : (\n <>\n <button type=\"button\" className=\"ya-crumb\" onClick={() => { setDirection('backward'); setSelectedKey(null) }}>{t('workspaces')}</button>\n <IconChevronRightOutline14 />\n <span className=\"ya-crumb\">{selectedKey === UNGROUPED ? t('ungrouped') : selectedWorkspace?.title}</span>\n {selectedKey !== UNGROUPED && (\n <button type=\"button\" className=\"ya-icon-button\" aria-label={t('newSession')} onClick={() => { startSession(selectedKey) }}><IconPlusOutline16 /></button>\n )}\n </>\n )}\n </div>\n <div className=\"ya-scroll\" role=\"tree\" aria-label={selectedKey === null ? t('workspaces') : t('sessions')}>\n <div key={selectedKey ?? 'root'} className={hasMounted ? `ya-level-enter-${direction}` : undefined}>\n {selectedKey === null\n ? workspaceRows.map(row => (\n <WorkspaceItem\n key={row.key}\n row={row}\n enter={() => { setDirection('forward'); setSelectedKey(row.key) }}\n create={() => { if (row.key !== UNGROUPED) startSession(row.key) }}\n rename={() => { beginWorkspaceRename(row) }}\n remove={() => { setDeleteTarget(row); setRenameError(null) }}\n t={t}\n />\n ))\n : levelRows.map((row, index) => sessionItem(row, false, index))}\n {selectedKey === null && workspaceRows.length === 0 && <div className=\"ya-empty\">{t('noWorkspaces')}</div>}\n {selectedKey !== null && levelRows.length === 0 && <div className=\"ya-empty\">{t('noSessions')}</div>}\n </div>\n </div>\n </>\n )}\n </div>\n )}\n\n <Modal\n open={workspaceRename !== null || sessionRename !== null}\n onClose={closeRename}\n closeLabel={t('cancel')}\n title={workspaceRename !== null ? t('renameWorkspace') : t('renameSession')}\n footer={(\n <>\n <Button variant=\"outline\" disabled={busy} onClick={closeRename}>{t('cancel')}</Button>\n <Button variant=\"primary\" disabled={busy || renameDraft.trim() === ''} onClick={commitRename}>{t('rename')}</Button>\n </>\n )}\n >\n <input className=\"ya-rename-input\" value={renameDraft} autoFocus disabled={busy} aria-label={workspaceRename !== null ? t('workspaceName') : t('sessionName')} onChange={event => { setRenameDraft(event.target.value); setRenameError(null) }} />\n {renameError !== null && <div className=\"ya-error\" role=\"alert\">{renameError}</div>}\n </Modal>\n\n <Modal\n open={deleteTarget !== null}\n onClose={() => { if (!busy) setDeleteTarget(null) }}\n closeLabel={t('cancel')}\n title={t('deleteWorkspace')}\n description={deleteTarget === null ? undefined : t('deleteDescription', { name: deleteTarget.title })}\n footer={(\n <>\n <Button variant=\"outline\" disabled={busy} onClick={() => { setDeleteTarget(null) }}>{t('cancel')}</Button>\n <Button variant=\"outline\" disabled={busy} onClick={confirmDelete}>{t('deleteWorkspace')}</Button>\n </>\n )}\n >\n {renameError !== null && <div className=\"ya-error\" role=\"alert\">{renameError}</div>}\n </Modal>\n </div>\n )\n}\n","/** Client assembly for the replacement workspace sidebar and hero picker. */\nimport type { HostObservable } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type { PickerInjected, SidebarInjected } from './contract.ts'\nimport { en, NS, zh } from './locales.ts'\nimport { installStyles } from './styles.ts'\nimport { WorkspacePicker } from './WorkspacePicker.tsx'\nimport { WorkspaceSidebar } from './WorkspaceSidebar.tsx'\n\n/** Services required by both replacement client entries. */\nexport const inject = ['slots', 'sessions', 'workspaces', 'locale']\n\n/** Register the sidebar browser and conversation hero picker. */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'ya-workspace-sidebar: dictionaries')\n ctx.effect(installStyles, 'ya-workspace-sidebar: styles')\n\n const flowSource = (\n name: 'sidebar.workspaces.directoryFlow' | 'conversation.hero.workspace.directoryFlow',\n ): HostObservable<boolean> => ({\n getSnapshot: () => ctx.slots.entries(name).length > 0,\n subscribe: listener => ctx.slots.subscribe(name, listener),\n })\n const sidebarFlow = flowSource('sidebar.workspaces.directoryFlow')\n const pickerFlow = flowSource('conversation.hero.workspace.directoryFlow')\n const createWorkspace = (input: { path: string }) => ctx.workspaces.create(input)\n\n const searchSessions: SidebarInjected['searchSessions'] = async (query, signal) => {\n const result = await ctx.sessions.search(query, signal)\n if (!result.ok) throw new Error(result.error.message)\n return result.value\n }\n const sidebarInjected = (): SidebarInjected => ({\n startSession: workspaceId => { ctx.workspaces.startSession(workspaceId) },\n open: sessionId => { ctx.sessions.open(sessionId) },\n searchSessions,\n searchResultLimit: ctx.sessions.searchResultLimit,\n renameSession: async (sessionId, title) => {\n const session = ctx.sessions.binding(sessionId)?.session\n if (session === undefined) throw new Error(`unknown session \"${sessionId}\"`)\n const result = await session.rename(title)\n if (!result.ok) throw new Error(result.error.message)\n },\n forkSession: sessionId => {\n ctx.sessions.fork({ sessionId, increaseTitle: true })\n .then(childId => { ctx.sessions.open(childId) })\n .catch(() => {})\n },\n renameWorkspace: async (workspaceId, title) => { await ctx.workspaces.rename(workspaceId, title) },\n deleteWorkspace: async workspaceId => { await ctx.workspaces.delete(workspaceId) },\n archiveSession: async sessionId => { await ctx.workspaces.archiveSession(sessionId) },\n insertSessionBefore: async (workspaceId, sessionId, beforeSessionId) => {\n await ctx.workspaces.insertSessionBefore(workspaceId, sessionId, beforeSessionId)\n },\n createWorkspace,\n hooks: { directoryFlow: sidebarFlow },\n })\n const pickerInjected = (): PickerInjected => ({\n createWorkspace,\n hooks: { directoryFlow: pickerFlow },\n })\n\n ctx.slots.inject('sidebar.workspaces', () => ctx.slots.register({\n name: 'sidebar.workspaces',\n children: { 'sidebar.workspaces.directoryFlow': { kind: 'single', scope: 'root' } },\n inject: sidebarInjected,\n locale: NS,\n }, WorkspaceSidebar))\n\n ctx.slots.inject('conversation.hero.workspace', () => ctx.slots.register({\n name: 'conversation.hero.workspace',\n children: { 'conversation.hero.workspace.directoryFlow': { kind: 'single', scope: 'root' } },\n inject: pickerInjected,\n locale: NS,\n }, WorkspacePicker))\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["useState","useCallback","IconPlusOutline16","IconFolderClose16","Menu","Modal","Button","StateDot","useState","Menu","IconEditOutline16","IconBranchOutline16","IconArchiveOutline20","IconEllipsisOutline16","IconFolderClose16","IconTrashOutline16","IconPlusOutline16","IconChevronRightOutline14","useMemo","useRef","IconProjectAddOutline16","IconSearchOutline16","IconCloseFill14","Modal","Button"],"sources":["../src/client/locales.ts","../src/client/styles.ts","../src/client/WorkspacePicker.tsx","../src/client/model.ts","../src/client/WorkspaceSidebar.tsx","../src/client/index.ts"],"sourcesContent":["/** Product copy for the replacement workspace browser. */\nexport const zh = {\n workspaces: '工作区',\n sessions: '会话',\n recent: '最近会话',\n ungrouped: '未分组',\n newSession: '新会话',\n untitled: '未命名会话',\n addWorkspace: '添加工作区',\n addWorkspaceMenu: '添加工作区…',\n search: '搜索会话',\n searchPlaceholder: '搜索名称、关键词…',\n clearSearch: '清除搜索',\n searching: '正在搜索会话历史…',\n searchUnavailable: '内容搜索暂不可用,仅显示名称匹配。',\n noMatches: '无匹配会话',\n noSessions: '暂无会话',\n noWorkspaces: '暂无工作区',\n loading: '正在加载工作区…',\n rename: '重命名',\n renameWorkspace: '重命名工作区',\n renameSession: '重命名会话',\n deleteWorkspace: '删除工作区',\n deleteDescription: '将把“{name}”从工作区列表中移除。文件夹与会话记录会保留。',\n fork: '分叉会话',\n archive: '归档会话',\n cancel: '取消',\n confirm: '确认',\n retry: '重新选择',\n folderError: '无法打开文件夹',\n workspaceName: '工作区名称',\n sessionName: '会话名称',\n count: '{n} 个会话',\n now: '刚刚',\n minutes: '{n}分钟',\n hours: '{n}小时',\n days: '{n}天',\n months: '{n}个月',\n years: '{n}年',\n running: '进行中',\n waiting: '等待交互',\n completed: '已完成',\n collapse: '折叠',\n expand: '展开',\n today: '今天',\n yesterday: '昨天',\n date: '{m}月{d}日',\n dateYear: '{y}年{m}月{d}日',\n} satisfies Record<string, string>\n\nexport type YaWorkspaceKey = keyof typeof zh\n\nexport const en = {\n workspaces: 'Workspaces',\n sessions: 'Sessions',\n recent: 'Recent Sessions',\n ungrouped: 'Ungrouped',\n newSession: 'New Session',\n untitled: 'Untitled session',\n addWorkspace: 'Add workspace',\n addWorkspaceMenu: 'Add workspace…',\n search: 'Search sessions',\n searchPlaceholder: 'Search name, keywords...',\n clearSearch: 'Clear search',\n searching: 'Searching session history…',\n searchUnavailable: 'Content search is unavailable. Showing name matches.',\n noMatches: 'No matching sessions',\n noSessions: 'No sessions yet',\n noWorkspaces: 'No workspaces yet',\n loading: 'Loading workspaces…',\n rename: 'Rename',\n renameWorkspace: 'Rename workspace',\n renameSession: 'Rename session',\n deleteWorkspace: 'Delete workspace',\n deleteDescription: 'This removes “{name}” from the workspace list. The folder and session logs remain.',\n fork: 'Fork session',\n archive: 'Archive session',\n cancel: 'Cancel',\n confirm: 'Confirm',\n retry: 'Choose again',\n folderError: 'Couldn’t open folder',\n workspaceName: 'Workspace name',\n sessionName: 'Session name',\n count: '{n} sessions',\n now: 'now',\n minutes: '{n}min',\n hours: '{n}h',\n days: '{n}d',\n months: '{n}mo',\n years: '{n}y',\n running: 'Running',\n waiting: 'Waiting for interaction',\n completed: 'Completed',\n collapse: 'Collapse',\n expand: 'Expand',\n today: 'Today',\n yesterday: 'Yesterday',\n date: '{m}/{d}',\n dateYear: '{m}/{d}/{y}',\n} satisfies Record<YaWorkspaceKey, string>\n\nexport const NS = 'ya-workspace-sidebar'\n","/** One scoped stylesheet injected for the lifetime of the client activation. */\nexport const CSS = `\n[data-ya-workspace-sidebar] { flex:1; min-height:0; display:flex; flex-direction:column; box-sizing:border-box; padding-right:var(--dsh-sidebar-inline-padding); color:var(--dsw-alias-label-primary); }\n[data-ya-workspace-sidebar].ya-rail { padding-right:0; }\n.ya-section-header { flex:none; height:36px; display:flex; align-items:center; justify-content:flex-end; gap:4px; padding-left:12px; margin-bottom:4px; box-sizing:border-box; color:var(--dsw-alias-label-tertiary); }\n.ya-section-title { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:14px; }\n.ya-icon-button { flex:none; width:28px; height:28px; border:0; border-radius:50%; padding:0; display:inline-flex; align-items:center; justify-content:center; color:var(--dsw-alias-label-secondary); background:transparent; cursor:pointer; }\n.ya-icon-button:hover { background:var(--dsw-alias-interactive-bg-hover); }\n.ya-search { flex:none; height:38px; margin:0 2px 10px; padding:0 14px; display:flex; align-items:center; gap:8px; box-sizing:border-box; border:1px solid var(--dsw-alias-border-l2); border-radius:24px; background:var(--dsw-static-neutral-bluish-75); color:var(--dsw-alias-label-caption); }\nbody[data-ds-dark-theme] .ya-search { background:var(--dsw-static-neutral-bluish-900); }\n.ya-search-input { flex:1; min-width:0; border:0; outline:0; background:transparent; color:var(--dsw-alias-label-primary); font:inherit; font-size:14px; }\n.ya-search-input::placeholder { color:var(--dsw-alias-label-tertiary); }\n.ya-search-icon { flex:none; display:inline-flex; border:0; padding:0; color:inherit; background:transparent; }\n.ya-body { flex:1; min-height:0; display:flex; flex-direction:column; overflow:hidden; margin-right:calc(-1 * var(--dsh-sidebar-inline-padding)); padding-right:var(--dsh-sidebar-inline-padding); }\n.ya-recent { flex:none; padding-bottom:8px; border-bottom:1px solid var(--dsw-alias-border-l2); }\n.ya-recent-collapsed { padding-bottom:0; border-bottom-color:transparent; }\n.ya-recent-list-wrap { display:grid; grid-template-rows:1fr; transition:grid-template-rows 220ms ease-out; }\n.ya-recent-collapsed .ya-recent-list-wrap { grid-template-rows:0fr; }\n.ya-recent-list { display:flex; flex-direction:column; overflow:hidden; min-height:0; }\n.ya-block-label { height:26px; display:flex; align-items:center; gap:2px; padding:0 8px; color:var(--dsw-alias-label-tertiary); font-size:12px; font-weight:600; letter-spacing:.02em; text-transform:uppercase; }\n.ya-block-label-toggle { flex:none; width:20px; height:20px; margin-left:auto; border:0; border-radius:6px; padding:0; display:inline-flex; align-items:center; justify-content:center; background:transparent; color:var(--dsw-alias-label-tertiary); cursor:pointer; transition:transform 180ms ease-out; }\n.ya-block-label-toggle:hover { background:var(--dsw-alias-interactive-bg-hover); color:var(--dsw-alias-label-secondary); }\n.ya-block-label-toggle.ya-collapsed { transform:rotate(-90deg); }\n.ya-date-group-label { height:26px; display:flex; align-items:center; padding:0 8px; color:var(--dsw-alias-label-tertiary); font-size:12px; font-weight:600; letter-spacing:.02em; }\n.ya-breadcrumb { flex:none; height:34px; display:flex; align-items:center; gap:2px; padding:0 6px; color:var(--dsw-alias-label-tertiary); font-size:13px; }\n.ya-crumb { border:0; padding:4px 3px; border-radius:6px; background:transparent; color:inherit; font:inherit; cursor:default; min-width:0; overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }\nbutton.ya-crumb:hover { background:var(--dsw-alias-interactive-bg-hover); color:var(--dsw-alias-label-primary); cursor:pointer; }\n.ya-scroll { flex:1; min-height:0; overflow-y:auto; padding-bottom:12px; }\n.ya-row { position:relative; min-height:34px; display:flex; align-items:center; gap:6px; margin:1px 0; padding:0 7px; border-radius:9px; box-sizing:border-box; color:var(--dsw-alias-label-primary); cursor:pointer; user-select:none; }\n.ya-row:hover, .ya-row.ya-menu-open { background:var(--dsw-alias-interactive-bg-hover); }\n.ya-row.ya-selected { background:var(--dsw-alias-interactive-bg-selected); }\n.ya-workspace-row { min-height:40px; }\n.ya-row-main { flex:1; min-width:0; display:flex; flex-direction:column; justify-content:center; }\n.ya-row-line { display:flex; align-items:center; min-width:0; gap:6px; }\n.ya-row-title { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:13px; line-height:18px; }\n.ya-row-meta { flex:none; color:var(--dsw-alias-label-tertiary); font-size:11px; white-space:nowrap; }\n.ya-workspace-path { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--dsw-alias-label-tertiary); font-size:11px; line-height:15px; }\n.ya-row-actions { flex:none; display:flex; align-items:center; gap:2px; opacity:0; pointer-events:none; transition:opacity 120ms ease-out; }\n.ya-row:hover .ya-row-actions, .ya-menu-open .ya-row-actions { opacity:1; pointer-events:auto; }\n.ya-status-slot { flex:none; width:16px; height:16px; display:inline-flex; align-items:center; justify-content:center; color:var(--dsw-alias-label-tertiary); }\n.ya-recent .ya-row { min-height:31px; }\n.ya-search-workspace { color:var(--dsw-alias-label-tertiary); font-size:11px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }\n.ya-empty, .ya-status { padding:18px 10px; color:var(--dsw-alias-label-tertiary); text-align:center; font-size:13px; }\n.ya-warning { color:var(--dsw-alias-status-warning); }\n.ya-rename-input { width:100%; height:38px; box-sizing:border-box; border:1px solid var(--dsw-alias-border-l2); border-radius:9px; padding:0 11px; background:transparent; color:var(--dsw-alias-label-primary); outline:none; }\n.ya-error { margin-top:8px; color:var(--dsw-alias-status-error); font-size:12px; }\n.ya-rail .ya-section-header { padding-left:0; margin-bottom:12px; }\n.ya-rail .ya-icon-button, .ya-rail .ya-search { width:36px; height:36px; padding:0; margin:0 0 12px; border-color:transparent; background:transparent; }\n.ya-rail .ya-search { justify-content:center; }\n.ya-rail .ya-search-icon { cursor:pointer; color:var(--dsw-alias-label-primary); }\n.ya-picker-error { color:var(--dsw-alias-status-error); white-space:pre-wrap; }\n@keyframes ya-slide-in-forward { from { opacity:0; transform:translateX(10px); } to { opacity:1; transform:translateX(0); } }\n@keyframes ya-slide-in-backward { from { opacity:0; transform:translateX(-10px); } to { opacity:1; transform:translateX(0); } }\n.ya-level-enter-forward { animation:ya-slide-in-forward 180ms ease-out; }\n.ya-level-enter-backward { animation:ya-slide-in-backward 180ms ease-out; }\n`\n\n/** Install the stylesheet and return its disposer. */\nexport function installStyles(): () => void {\n const style = document.createElement('style')\n style.setAttribute('data-ya-workspace-sidebar-style', '')\n style.textContent = CSS\n document.head.appendChild(style)\n return () => { style.remove() }\n}\n","/** Existing-workspace menu plus composed directory-adoption flow. */\nimport type { ReactNode, RefObject } from 'react'\nimport { useCallback, useEffect, useState } from 'react'\nimport {\n Button, IconFolderClose16, IconPlusOutline16, Menu, Modal, type MenuEntry,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport type {\n WorkspaceId, WorkspaceListState, WorkspaceView,\n} from '@deepseek-ai/dsh-client-runtime/client'\nimport type { SnapshotSelectorHook } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { DirectoryFlowOwnerProps, PickerProps } from './contract.ts'\n\nconst ADD = '::ya-add-workspace'\n\ninterface FlowProps {\n t: PickerProps['t']\n open: boolean\n anchorRef?: RefObject<HTMLElement | null>\n useWorkspaces: <S>(selector: (state: WorkspaceListState) => S) => S\n createWorkspace: (input: { path: string }) => Promise<WorkspaceView>\n useDirectoryFlow: SnapshotSelectorHook<boolean>\n renderDirectoryFlow: (owner: DirectoryFlowOwnerProps) => ReactNode\n onPick: (workspaceId: WorkspaceId) => void\n onClose: () => void\n addOnly?: boolean\n side?: 'bottom' | 'top' | 'right'\n selectedId?: WorkspaceId\n}\n\n/** Render the workspace target menu and directory picking conversation. */\nexport function WorkspacePickFlow({\n t, open, anchorRef, useWorkspaces, createWorkspace, useDirectoryFlow,\n renderDirectoryFlow, onPick, onClose, addOnly = false, side = 'bottom', selectedId,\n}: FlowProps) {\n const snapshot = useWorkspaces(state => state)\n const flowAvailable = useDirectoryFlow(value => value)\n const [flowOpen, setFlowOpen] = useState(false)\n const [busy, setBusy] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const getAnchorRect = useCallback(\n () => anchorRef?.current?.getBoundingClientRect() ?? null,\n [anchorRef],\n )\n useEffect(() => {\n if (flowOpen && !flowAvailable) setFlowOpen(false)\n }, [flowAvailable, flowOpen])\n\n const openFlow = useCallback(() => {\n onClose()\n setError(null)\n setFlowOpen(true)\n }, [onClose])\n const addEntries: MenuEntry[] = flowAvailable\n ? [{ id: ADD, label: t('addWorkspaceMenu'), icon: <IconPlusOutline16 size={16} />, disabled: flowOpen || busy }]\n : []\n const pinnedAdd = !addOnly && snapshot.items.length > 0\n const items: MenuEntry[] = pinnedAdd\n ? snapshot.items.map(workspace => ({\n id: workspace.workspaceId,\n label: workspace.title,\n icon: <IconFolderClose16 size={16} />,\n disabled: flowOpen || busy,\n }))\n : addEntries\n const settled = addOnly || snapshot.phase === 'ready'\n const onlyAdd = !pinnedAdd && settled && addEntries.length === 1\n useEffect(() => {\n if (open && onlyAdd && !flowOpen && !busy) openFlow()\n }, [busy, flowOpen, onlyAdd, open, openFlow])\n\n const owner: DirectoryFlowOwnerProps = {\n open: flowOpen,\n busy,\n onPicked: (path) => {\n setBusy(true)\n createWorkspace({ path }).then(workspace => {\n setFlowOpen(false)\n onPick(workspace.workspaceId)\n }).catch((reason: unknown) => {\n setFlowOpen(false)\n setError(reason instanceof Error ? reason.message : String(reason))\n }).finally(() => { setBusy(false) })\n },\n onCancel: () => { setFlowOpen(false) },\n onError: (message) => { setFlowOpen(false); setError(message) },\n }\n\n return (\n <>\n <Menu\n open={open && !onlyAdd && items.length > 0}\n anchor={null}\n items={items}\n {...pinnedAdd ? { footer: addEntries } : {}}\n selectedId={selectedId}\n onSelect={(id) => { if (id === ADD) openFlow(); else onPick(id as WorkspaceId) }}\n onClose={onClose}\n side={side}\n portal\n getAnchorRect={getAnchorRect}\n />\n {open && !onlyAdd && snapshot.phase === 'pending' && <div className=\"ya-status\">{t('loading')}</div>}\n {renderDirectoryFlow(owner)}\n <Modal\n open={error !== null}\n onClose={() => { setError(null) }}\n closeLabel={t('cancel')}\n title={t('folderError')}\n footer={(\n <>\n <Button variant=\"outline\" onClick={() => { setError(null) }}>{t('cancel')}</Button>\n <Button variant=\"primary\" disabled={!flowAvailable} onClick={openFlow}>{t('retry')}</Button>\n </>\n )}\n >\n <div className=\"ya-picker-error\" role=\"alert\">{error}</div>\n </Modal>\n </>\n )\n}\n\n/** Fill the conversation hero's workspace picker seat. */\nexport function WorkspacePicker({\n open, anchorRef, useWorkspaces, selectedId, onPick, onClose,\n createWorkspace, useDirectoryFlow, renderSlot, t,\n}: PickerProps) {\n return (\n <WorkspacePickFlow\n t={t}\n open={open}\n anchorRef={anchorRef}\n useWorkspaces={useWorkspaces}\n selectedId={selectedId}\n onPick={onPick}\n onClose={onClose}\n createWorkspace={createWorkspace}\n useDirectoryFlow={useDirectoryFlow}\n renderDirectoryFlow={owner => renderSlot('conversation.hero.workspace.directoryFlow', owner)}\n />\n )\n}\n","/** Pure sidebar projections shared by the browser and unit tests. */\nimport type {\n SessionId, SessionListState, SessionSummary, WorkspaceId, WorkspaceView,\n} from '@deepseek-ai/dsh-client-runtime/client'\n\n/** Navigation key for sessions not accounted to a real workspace. */\nexport const UNGROUPED = '__ya_ungrouped__' as const\n\n/** One sidebar session row. */\nexport interface SessionRow {\n id: SessionId\n title: string\n /** Whether the session has a durable log-backed title (summary.title !== undefined). */\n hasTitle: boolean\n blank: boolean\n running: boolean\n pendingInteraction?: SessionSummary['pendingInteraction']\n completed: boolean\n updatedAt: number\n workspaceKey: WorkspaceId | typeof UNGROUPED\n workspaceTitle: string\n}\n\n/** One date-bucketed group of session rows for the real-workspace level. */\nexport interface SessionDateGroup {\n /** Local calendar date `YYYY-MM-DD`, stable key. */\n dateKey: string\n /** Days between today's local date and this group's local date (0=today, 1=yesterday, …). */\n dayOffset: number\n rows: SessionRow[]\n}\n\n/** One first-level workspace row. */\nexport interface WorkspaceRow {\n key: WorkspaceId | typeof UNGROUPED\n title: string\n path?: string\n createdAt?: string\n count: number\n real: boolean\n}\n\nfunction visible(summary: SessionSummary, current: SessionId | undefined, archived: ReadonlySet<SessionId>): boolean {\n return summary.origin !== 'subagent'\n && !archived.has(summary.id)\n && (!summary.blank || summary.id === current)\n}\n\nfunction rowOf(\n summary: SessionSummary,\n workspaceKey: WorkspaceId | typeof UNGROUPED,\n workspaceTitle: string,\n): SessionRow {\n return {\n id: summary.id,\n title: summary.blank ? 'New Session' : summary.displayTitle,\n hasTitle: summary.title !== undefined,\n blank: summary.blank,\n running: summary.running,\n ...(summary.pendingInteraction === undefined ? {} : { pendingInteraction: summary.pendingInteraction }),\n completed: summary.completed === true,\n updatedAt: summary.updatedAt,\n workspaceKey,\n workspaceTitle,\n }\n}\n\nfunction ownerIndex(workspaces: readonly WorkspaceView[]): Map<SessionId, WorkspaceView> {\n const result = new Map<SessionId, WorkspaceView>()\n for (const workspace of workspaces) {\n for (const sessionId of workspace.sessionIds) result.set(sessionId, workspace)\n }\n return result\n}\n\n/** Resolve the first/second-level destination for one session. */\nexport function workspaceKeyForSession(\n sessionId: SessionId | undefined,\n workspaces: readonly WorkspaceView[],\n): WorkspaceId | typeof UNGROUPED | null {\n if (sessionId === undefined) return null\n return ownerIndex(workspaces).get(sessionId)?.workspaceId ?? UNGROUPED\n}\n\n/** Derive global recent sessions, newest first. */\nexport function deriveRecent(\n list: SessionListState,\n workspaces: readonly WorkspaceView[],\n archivedSessionIds: readonly SessionId[],\n limit = 5,\n): SessionRow[] {\n const archived = new Set(archivedSessionIds)\n const owners = ownerIndex(workspaces)\n return list.ids\n .map(id => list.byId[id])\n .filter((summary): summary is SessionSummary => summary !== undefined && visible(summary, list.current, archived))\n .sort((a, b) => b.updatedAt - a.updatedAt || String(a.id).localeCompare(String(b.id)))\n .slice(0, limit)\n .map((summary) => {\n const workspace = owners.get(summary.id)\n return rowOf(summary, workspace?.workspaceId ?? UNGROUPED, workspace?.title ?? 'Ungrouped')\n })\n}\n\n/** Derive first-level real workspaces plus the virtual Ungrouped row. */\nexport function deriveWorkspaces(\n list: SessionListState,\n workspaces: readonly WorkspaceView[],\n archivedSessionIds: readonly SessionId[],\n): WorkspaceRow[] {\n const archived = new Set(archivedSessionIds)\n const accounted = new Set<SessionId>()\n const result = workspaces.map((workspace): WorkspaceRow => {\n let count = 0\n for (const id of workspace.sessionIds) {\n accounted.add(id)\n const summary = list.byId[id]\n if (summary !== undefined && visible(summary, list.current, archived)) count++\n }\n return {\n key: workspace.workspaceId,\n title: workspace.title,\n path: workspace.path,\n createdAt: workspace.createdAt,\n count,\n real: true,\n }\n })\n let ungrouped = 0\n for (const id of list.ids) {\n const summary = list.byId[id]\n if (summary !== undefined && !accounted.has(id) && visible(summary, list.current, archived)) ungrouped++\n }\n result.push({ key: UNGROUPED, title: 'Ungrouped', count: ungrouped, real: false })\n return result\n}\n\n/** Derive the selected workspace's sessions in its canonical order. */\nexport function deriveWorkspaceSessions(\n key: WorkspaceId | typeof UNGROUPED,\n list: SessionListState,\n workspaces: readonly WorkspaceView[],\n archivedSessionIds: readonly SessionId[],\n): SessionRow[] {\n const archived = new Set(archivedSessionIds)\n if (key === UNGROUPED) {\n const accounted = new Set(workspaces.flatMap(workspace => workspace.sessionIds))\n return list.ids\n .map(id => list.byId[id])\n .filter((summary): summary is SessionSummary => summary !== undefined\n && !accounted.has(summary.id)\n && visible(summary, list.current, archived))\n .sort((a, b) => b.updatedAt - a.updatedAt || String(a.id).localeCompare(String(b.id)))\n .map(summary => rowOf(summary, UNGROUPED, 'Ungrouped'))\n }\n const workspace = workspaces.find(item => item.workspaceId === key)\n if (workspace === undefined) return []\n return workspace.sessionIds\n .map(id => list.byId[id])\n .filter((summary): summary is SessionSummary => summary !== undefined && visible(summary, list.current, archived))\n .map(summary => rowOf(summary, workspace.workspaceId, workspace.title))\n}\n\n/** Format a local calendar date as `YYYY-MM-DD` (locale-agnostic, no padding surprises). */\nfunction localDateKey(year: number, month: number, day: number): string {\n const mm = month < 9 ? `0${month + 1}` : `${month + 1}`\n const dd = day < 10 ? `0${day}` : `${day}`\n return `${year}-${mm}-${dd}`\n}\n\n/** Whole-day difference between two local calendar dates (a - b) using UTC midnight. */\nfunction dayDiff(a: { year: number; month: number; day: number }, b: { year: number; month: number; day: number }): number {\n const msA = Date.UTC(a.year, a.month, a.day)\n const msB = Date.UTC(b.year, b.month, b.day)\n return Math.round((msA - msB) / 86_400_000)\n}\n\n/**\n * Derive the selected real workspace's sessions grouped by local calendar date.\n *\n * - Only real workspaces: `Ungrouped` falls back to {@link deriveWorkspaceSessions}.\n * - Groups are ordered by date descending; rows within a group by `updatedAt` descending.\n * - {@link visible} filter is reused (archived / subagent / blank visibility).\n * - Future timestamps clamp to today's bucket (`dayOffset` 0).\n * - `now` is the reference timestamp for \"today\"; pass `Date.now()` in production.\n */\nexport function deriveWorkspaceSessionGroups(\n key: WorkspaceId | typeof UNGROUPED,\n list: SessionListState,\n workspaces: readonly WorkspaceView[],\n archivedSessionIds: readonly SessionId[],\n now: number,\n): SessionDateGroup[] {\n if (key === UNGROUPED) return []\n const workspace = workspaces.find(item => item.workspaceId === key)\n if (workspace === undefined) return []\n const archived = new Set(archivedSessionIds)\n const rows = workspace.sessionIds\n .map(id => list.byId[id])\n .filter((summary): summary is SessionSummary => summary !== undefined && visible(summary, list.current, archived))\n .map(summary => rowOf(summary, workspace.workspaceId, workspace.title))\n if (rows.length === 0) return []\n\n const nowDate = new Date(now)\n const today = { year: nowDate.getFullYear(), month: nowDate.getMonth(), day: nowDate.getDate() }\n\n const buckets = new Map<string, { dayOffset: number; rows: SessionRow[] }>()\n for (const row of rows) {\n const ts = Math.min(row.updatedAt, now)\n const d = new Date(ts)\n const date = { year: d.getFullYear(), month: d.getMonth(), day: d.getDate() }\n const dateKey = localDateKey(date.year, date.month, date.day)\n let bucket = buckets.get(dateKey)\n if (bucket === undefined) {\n // dayOffset = today - date (positive for past dates). Future timestamps were\n // clamped to `now` above, so `date` never exceeds today; Math.max guards rounding noise.\n const offset = Math.max(0, dayDiff(today, date))\n bucket = { dayOffset: offset, rows: [] }\n buckets.set(dateKey, bucket)\n }\n bucket.rows.push(row)\n }\n\n const groups: SessionDateGroup[] = []\n for (const [dateKey, bucket] of buckets) {\n bucket.rows.sort((a, b) => b.updatedAt - a.updatedAt || String(a.id).localeCompare(String(b.id)))\n groups.push({ dateKey, dayOffset: bucket.dayOffset, rows: bucket.rows })\n }\n // Sort groups by date descending: newest date first = smallest dayOffset first.\n groups.sort((a, b) => a.dayOffset - b.dayOffset || a.dateKey.localeCompare(b.dateKey))\n return groups\n}\n\n/** Case-insensitive local title/workspace matching used beside Host content search. */\nexport function localMatches(rows: readonly SessionRow[], query: string): SessionRow[] {\n const normalized = query.trim().toLocaleLowerCase()\n if (normalized === '') return []\n return rows.filter(row => `${row.title}\\n${row.workspaceTitle}`.toLocaleLowerCase().includes(normalized))\n}\n","/** Two-level workspace/session browser with a persistent global recent block. */\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport {\n Button, IconArchiveOutline20, IconBranchOutline16, IconChevronRightOutline14,\n IconCloseFill14, IconEditOutline16, IconEllipsisOutline16, IconFolderClose16,\n IconPlusOutline16, IconProjectAddOutline16, IconSearchOutline16, IconTrashOutline16,\n Menu, Modal, StateDot,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { SessionId, WorkspaceId } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { SidebarProps } from './contract.ts'\nimport {\n deriveRecent, deriveWorkspaceSessionGroups, deriveWorkspaceSessions, deriveWorkspaces,\n localMatches, UNGROUPED, workspaceKeyForSession, type SessionDateGroup, type SessionRow,\n type WorkspaceRow,\n} from './model.ts'\nimport { WorkspacePickFlow } from './WorkspacePicker.tsx'\n\nconst SEARCH_DEBOUNCE_MS = 250\nconst SEARCH_MAX = 500\n\nfunction sanitized(value: string): string {\n return value.replaceAll('\\0', '').slice(0, SEARCH_MAX)\n}\n\nfunction relativeTime(updatedAt: number, now: number, t: SidebarProps['t']): string {\n const diff = Math.max(0, now - updatedAt)\n const minute = 60_000\n if (diff < minute) return t('now')\n if (diff < 60 * minute) return t('minutes', { n: Math.floor(diff / minute) })\n if (diff < 24 * 60 * minute) return t('hours', { n: Math.floor(diff / (60 * minute)) })\n if (diff < 30 * 24 * 60 * minute) return t('days', { n: Math.floor(diff / (24 * 60 * minute)) })\n if (diff < 365 * 24 * 60 * minute) return t('months', { n: Math.floor(diff / (30 * 24 * 60 * minute)) })\n return t('years', { n: Math.floor(diff / (365 * 24 * 60 * minute)) })\n}\n\n/** Format a date group's localized title from its dayOffset and `YYYY-MM-DD` key. */\nfunction dateGroupLabel(group: SessionDateGroup, now: number, t: SidebarProps['t']): string {\n if (group.dayOffset === 0) return t('today')\n if (group.dayOffset === 1) return t('yesterday')\n const parts = group.dateKey.split('-')\n const year = Number(parts[0])\n const month = Number(parts[1])\n const day = Number(parts[2])\n const nowDate = new Date(now)\n if (year === nowDate.getFullYear()) return t('date', { m: month, d: day })\n return t('dateYear', { y: year, m: month, d: day })\n}\n\nfunction SessionStatus({ row }: { row: SessionRow }) {\n if (row.pendingInteraction !== undefined) return <StateDot state=\"warning\" />\n if (row.running) return <StateDot state=\"ongoing\" />\n if (row.completed) return <StateDot state=\"done\" />\n return null\n}\n\ninterface SessionRowProps {\n row: SessionRow\n current: SessionId | undefined\n now: number\n open: (id: SessionId) => void\n rename: (row: SessionRow) => void\n fork: (id: SessionId) => void\n archive: (id: SessionId) => void\n t: SidebarProps['t']\n context?: boolean\n}\n\nfunction SessionItem({ row, current, now, open, rename, fork, archive, t, context }: SessionRowProps) {\n const [menuOpen, setMenuOpen] = useState(false)\n const title = row.blank ? t('newSession') : row.hasTitle ? row.title : t('untitled')\n return (\n <div\n className={`ya-row${row.id === current ? ' ya-selected' : ''}${menuOpen ? ' ya-menu-open' : ''}`}\n role=\"treeitem\"\n aria-selected={row.id === current}\n onClick={() => { open(row.id) }}\n >\n <span className=\"ya-status-slot\"><SessionStatus row={row} /></span>\n <span className=\"ya-row-main\">\n <span className=\"ya-row-line\">\n <span className=\"ya-row-title\">{title}</span>\n {!row.blank && <span className=\"ya-row-meta ya-row-time\">{relativeTime(row.updatedAt, now, t)}</span>}\n </span>\n {context === true && <span className=\"ya-search-workspace\">{row.workspaceTitle}</span>}\n </span>\n {!row.blank && (\n <span className=\"ya-row-actions\">\n <Menu\n open={menuOpen}\n onClose={() => { setMenuOpen(false) }}\n items={[\n { id: 'rename', label: t('rename'), icon: <IconEditOutline16 /> },\n { id: 'fork', label: t('fork'), icon: <IconBranchOutline16 /> },\n { id: 'archive', label: t('archive'), icon: <IconArchiveOutline20 size={16} /> },\n ]}\n onSelect={(id) => {\n setMenuOpen(false)\n if (id === 'rename') rename(row)\n if (id === 'fork') fork(row.id)\n if (id === 'archive') archive(row.id)\n }}\n portal\n closeOnPointerLeave\n anchor={(\n <button\n type=\"button\"\n className=\"ya-icon-button\"\n aria-label={`${title} actions`}\n onClick={(event) => { event.stopPropagation(); setMenuOpen(value => !value) }}\n >\n <IconEllipsisOutline16 />\n </button>\n )}\n />\n </span>\n )}\n </div>\n )\n}\n\nfunction WorkspaceItem({ row, enter, create, rename, remove, t }: {\n row: WorkspaceRow\n enter: () => void\n create: () => void\n rename: () => void\n remove: () => void\n t: SidebarProps['t']\n}) {\n const [menuOpen, setMenuOpen] = useState(false)\n return (\n <div className={`ya-row ya-workspace-row${menuOpen ? ' ya-menu-open' : ''}`} role=\"treeitem\" onClick={enter} title={row.path}>\n <span className=\"ya-status-slot\"><IconFolderClose16 /></span>\n <span className=\"ya-row-main\">\n <span className=\"ya-row-line\">\n <span className=\"ya-row-title\">{row.real ? row.title : t('ungrouped')}</span>\n <span className=\"ya-row-meta\">{t('count', { n: row.count })}</span>\n </span>\n {row.path !== undefined && <span className=\"ya-workspace-path\">{row.path}</span>}\n </span>\n <span className=\"ya-row-actions\">\n {row.real && (\n <Menu\n open={menuOpen}\n onClose={() => { setMenuOpen(false) }}\n items={[\n { id: 'rename', label: t('rename'), icon: <IconEditOutline16 /> },\n { id: 'delete', label: t('deleteWorkspace'), icon: <IconTrashOutline16 />, danger: true },\n ]}\n onSelect={(id) => { setMenuOpen(false); if (id === 'rename') rename(); if (id === 'delete') remove() }}\n portal\n closeOnPointerLeave\n anchor={(\n <button type=\"button\" className=\"ya-icon-button\" onClick={(event) => { event.stopPropagation(); setMenuOpen(value => !value) }}>\n <IconEllipsisOutline16 />\n </button>\n )}\n />\n )}\n {row.real && (\n <button type=\"button\" className=\"ya-icon-button\" onClick={(event) => { event.stopPropagation(); create() }}>\n <IconPlusOutline16 />\n </button>\n )}\n </span>\n <IconChevronRightOutline14 />\n </div>\n )\n}\n\ninterface RemoteState {\n query: string\n status: 'idle' | 'loading' | 'ready' | 'error'\n items: readonly { sessionId: SessionId; snippet: string }[]\n hasMore: boolean\n}\n\n/** Fill `sidebar.workspaces` with the replacement browser. */\nexport function WorkspaceSidebar(props: SidebarProps) {\n const {\n wide, expandSidebar, useSessions, useWorkspaces, startSession, open, searchSessions,\n searchResultLimit, renameSession, forkSession, renameWorkspace, deleteWorkspace,\n archiveSession, createWorkspace, useDirectoryFlow, renderSlot, t,\n } = props\n const sessions = useSessions(state => state)\n const workspaceState = useWorkspaces(state => state)\n const workspaces = workspaceState.items\n const archived = workspaceState.archivedSessionIds\n const directoryFlowAvailable = useDirectoryFlow(value => value)\n const allRows = useMemo(\n () => deriveRecent(sessions, workspaces, archived, Number.MAX_SAFE_INTEGER),\n [archived, sessions, workspaces],\n )\n const recent = allRows.slice(0, 5)\n const workspaceRows = useMemo(\n () => deriveWorkspaces(sessions, workspaces, archived),\n [archived, sessions, workspaces],\n )\n const [selectedKey, setSelectedKey] = useState<WorkspaceId | typeof UNGROUPED | null>(null)\n const [direction, setDirection] = useState<'forward' | 'backward'>('forward')\n const [hasMounted, setHasMounted] = useState(false)\n useEffect(() => { setHasMounted(true) }, [])\n const observedCurrent = useRef<SessionId | undefined>(undefined)\n const initialized = useRef(false)\n useEffect(() => {\n if (initialized.current && observedCurrent.current === sessions.current) return\n initialized.current = true\n observedCurrent.current = sessions.current\n if (sessions.current !== undefined) { setDirection('forward'); setSelectedKey(workspaceKeyForSession(sessions.current, workspaces)) }\n }, [sessions.current, workspaces])\n useEffect(() => {\n if (selectedKey !== null && selectedKey !== UNGROUPED\n && !workspaces.some(workspace => workspace.workspaceId === selectedKey)) setSelectedKey(UNGROUPED)\n }, [selectedKey, workspaces])\n const selectedWorkspace = selectedKey === null || selectedKey === UNGROUPED\n ? undefined\n : workspaces.find(workspace => workspace.workspaceId === selectedKey)\n const now = Date.now()\n // Real workspace level renders date-bucketed groups; Ungrouped keeps the flat recency view.\n const levelGroups = useMemo(\n () => selectedKey !== null && selectedKey !== UNGROUPED\n ? deriveWorkspaceSessionGroups(selectedKey, sessions, workspaces, archived, now)\n : [],\n [archived, sessions, workspaces, selectedKey, now],\n )\n const levelRows = selectedKey === UNGROUPED\n ? deriveWorkspaceSessions(UNGROUPED, sessions, workspaces, archived)\n : []\n const levelEmpty = selectedKey === UNGROUPED ? levelRows.length === 0 : levelGroups.every(g => g.rows.length === 0)\n\n const [query, setQuery] = useState('')\n const normalizedQuery = sanitized(query).trim()\n const [remote, setRemote] = useState<RemoteState>({ query: '', status: 'idle', items: [], hasMore: false })\n useEffect(() => {\n if (normalizedQuery === '') {\n setRemote({ query: '', status: 'idle', items: [], hasMore: false })\n return\n }\n const controller = new AbortController()\n setRemote({ query: normalizedQuery, status: 'loading', items: [], hasMore: false })\n const timer = window.setTimeout(() => {\n searchSessions(normalizedQuery, controller.signal).then(result => {\n if (!controller.signal.aborted) setRemote({ query: normalizedQuery, status: 'ready', items: result.items, hasMore: result.hasMore })\n }).catch(() => {\n if (!controller.signal.aborted) setRemote({ query: normalizedQuery, status: 'error', items: [], hasMore: false })\n })\n }, SEARCH_DEBOUNCE_MS)\n return () => { window.clearTimeout(timer); controller.abort() }\n }, [normalizedQuery, searchSessions])\n const searchRows = useMemo(() => {\n if (normalizedQuery === '') return []\n const byId = new Map(localMatches(allRows, normalizedQuery).map(row => [row.id, row]))\n if (remote.query === normalizedQuery) {\n for (const item of remote.items) {\n const row = allRows.find(candidate => candidate.id === item.sessionId)\n if (row !== undefined) byId.set(row.id, row)\n }\n }\n return [...byId.values()].slice(0, searchResultLimit)\n }, [allRows, normalizedQuery, remote, searchResultLimit])\n\n const [pickerOpen, setPickerOpen] = useState(false)\n const pickerAnchor = useRef<HTMLButtonElement>(null)\n const [recentCollapsed, setRecentCollapsed] = useState(false)\n const [workspaceRename, setWorkspaceRename] = useState<WorkspaceRow | null>(null)\n const [sessionRename, setSessionRename] = useState<SessionRow | null>(null)\n const [renameDraft, setRenameDraft] = useState('')\n const [renameError, setRenameError] = useState<string | null>(null)\n const [busy, setBusy] = useState(false)\n const [deleteTarget, setDeleteTarget] = useState<WorkspaceRow | null>(null)\n\n const beginWorkspaceRename = (row: WorkspaceRow) => { setWorkspaceRename(row); setRenameDraft(row.title); setRenameError(null) }\n const beginSessionRename = (row: SessionRow) => { setSessionRename(row); setRenameDraft(row.title); setRenameError(null) }\n const closeRename = () => { if (!busy) { setWorkspaceRename(null); setSessionRename(null); setRenameError(null) } }\n const commitRename = () => {\n const title = renameDraft.trim()\n if (title === '' || busy) return\n setBusy(true)\n const task = workspaceRename !== null && workspaceRename.key !== UNGROUPED\n ? renameWorkspace(workspaceRename.key, title)\n : sessionRename !== null ? renameSession(sessionRename.id, title) : Promise.resolve()\n task.then(() => { setWorkspaceRename(null); setSessionRename(null) })\n .catch((reason: unknown) => { setRenameError(reason instanceof Error ? reason.message : String(reason)) })\n .finally(() => { setBusy(false) })\n }\n const confirmDelete = () => {\n if (deleteTarget === null || deleteTarget.key === UNGROUPED || busy) return\n setBusy(true)\n deleteWorkspace(deleteTarget.key).then(() => { setDeleteTarget(null) })\n .catch((reason: unknown) => { setRenameError(reason instanceof Error ? reason.message : String(reason)) })\n .finally(() => { setBusy(false) })\n }\n const archive = (id: SessionId) => { archiveSession(id).catch(reason => { console.warn('session archive rejected:', reason) }) }\n const fork = (id: SessionId) => { forkSession(id) }\n\n const sessionItem = (row: SessionRow, context = false) => (\n <SessionItem\n key={row.id}\n row={row}\n current={sessions.current}\n now={now}\n open={open}\n rename={beginSessionRename}\n fork={fork}\n archive={archive}\n t={t}\n context={context}\n />\n )\n\n return (\n <div data-ya-workspace-sidebar className={wide ? '' : 'ya-rail'}>\n <div className=\"ya-section-header\">\n {wide && <span className=\"ya-section-title\">{t('workspaces')}</span>}\n {directoryFlowAvailable && (\n <button ref={pickerAnchor} type=\"button\" className=\"ya-icon-button\" aria-label={t('addWorkspace')} onClick={() => { setPickerOpen(value => !value) }}>\n <IconProjectAddOutline16 size={wide ? 16 : 18} />\n </button>\n )}\n <WorkspacePickFlow\n t={t}\n open={pickerOpen}\n anchorRef={pickerAnchor}\n useWorkspaces={useWorkspaces}\n createWorkspace={createWorkspace}\n useDirectoryFlow={useDirectoryFlow}\n renderDirectoryFlow={owner => renderSlot('sidebar.workspaces.directoryFlow', owner)}\n addOnly\n side=\"right\"\n onPick={(workspaceId) => { setPickerOpen(false); startSession(workspaceId) }}\n onClose={() => { setPickerOpen(false) }}\n />\n </div>\n\n <div className=\"ya-search\" onClick={() => { if (!wide) expandSidebar() }}>\n <button type=\"button\" className=\"ya-search-icon\" aria-label={t('search')}><IconSearchOutline16 size={wide ? 14 : 18} /></button>\n {wide && <input className=\"ya-search-input\" value={query} maxLength={SEARCH_MAX} placeholder={t('searchPlaceholder')} onChange={event => { setQuery(sanitized(event.target.value)) }} />}\n {wide && query !== '' && <button type=\"button\" className=\"ya-icon-button\" aria-label={t('clearSearch')} onClick={() => { setQuery('') }}><IconCloseFill14 /></button>}\n </div>\n\n {wide && (\n <div className=\"ya-body\">\n {normalizedQuery !== '' ? (\n <div className=\"ya-scroll\" role=\"tree\" aria-label={t('search')}>\n {searchRows.map(row => sessionItem(row, true))}\n {remote.status === 'loading' && <div className=\"ya-status\">{t('searching')}</div>}\n {remote.status === 'error' && <div className=\"ya-status ya-warning\">{t('searchUnavailable')}</div>}\n {remote.status !== 'loading' && searchRows.length === 0 && <div className=\"ya-empty\">{t('noMatches')}</div>}\n </div>\n ) : (\n <>\n <div className={`ya-recent${recentCollapsed ? ' ya-recent-collapsed' : ''}`}>\n <div className=\"ya-block-label\">\n <span>{t('recent')}</span>\n {recent.length > 0 && (\n <button\n type=\"button\"\n className={`ya-block-label-toggle${recentCollapsed ? ' ya-collapsed' : ''}`}\n aria-label={recentCollapsed ? t('expand') : t('collapse')}\n aria-expanded={!recentCollapsed}\n onClick={(event) => { event.stopPropagation(); setRecentCollapsed(value => !value) }}\n >\n <IconChevronRightOutline14 />\n </button>\n )}\n </div>\n <div className=\"ya-recent-list-wrap\">\n {recent.length === 0\n ? <div className=\"ya-empty\">{t('noSessions')}</div>\n : <div className=\"ya-recent-list\">{recent.map(row => sessionItem(row, true))}</div>\n }\n </div>\n </div>\n <div className=\"ya-breadcrumb\">\n {selectedKey === null ? (\n <span className=\"ya-crumb\">{t('workspaces')}</span>\n ) : (\n <>\n <button type=\"button\" className=\"ya-crumb\" onClick={() => { setDirection('backward'); setSelectedKey(null) }}>{t('workspaces')}</button>\n <IconChevronRightOutline14 />\n <span className=\"ya-crumb\">{selectedKey === UNGROUPED ? t('ungrouped') : selectedWorkspace?.title}</span>\n {selectedKey !== UNGROUPED && (\n <button type=\"button\" className=\"ya-icon-button\" aria-label={t('newSession')} onClick={() => { startSession(selectedKey) }}><IconPlusOutline16 /></button>\n )}\n </>\n )}\n </div>\n <div className=\"ya-scroll\" role=\"tree\" aria-label={selectedKey === null ? t('workspaces') : t('sessions')}>\n <div key={selectedKey ?? 'root'} className={hasMounted ? `ya-level-enter-${direction}` : undefined}>\n {selectedKey === null\n ? workspaceRows.map(row => (\n <WorkspaceItem\n key={row.key}\n row={row}\n enter={() => { setDirection('forward'); setSelectedKey(row.key) }}\n create={() => { if (row.key !== UNGROUPED) startSession(row.key) }}\n rename={() => { beginWorkspaceRename(row) }}\n remove={() => { setDeleteTarget(row); setRenameError(null) }}\n t={t}\n />\n ))\n : selectedKey === UNGROUPED\n ? levelRows.map(row => sessionItem(row, false))\n : levelGroups.flatMap(group => [\n <div key={`group-${group.dateKey}`} className=\"ya-date-group-label\" role=\"separator\">\n {dateGroupLabel(group, now, t)}\n </div>,\n ...group.rows.map(row => sessionItem(row, false)),\n ])}\n {selectedKey === null && workspaceRows.length === 0 && <div className=\"ya-empty\">{t('noWorkspaces')}</div>}\n {selectedKey !== null && levelEmpty && <div className=\"ya-empty\">{t('noSessions')}</div>}\n </div>\n </div>\n </>\n )}\n </div>\n )}\n\n <Modal\n open={workspaceRename !== null || sessionRename !== null}\n onClose={closeRename}\n closeLabel={t('cancel')}\n title={workspaceRename !== null ? t('renameWorkspace') : t('renameSession')}\n footer={(\n <>\n <Button variant=\"outline\" disabled={busy} onClick={closeRename}>{t('cancel')}</Button>\n <Button variant=\"primary\" disabled={busy || renameDraft.trim() === ''} onClick={commitRename}>{t('rename')}</Button>\n </>\n )}\n >\n <input className=\"ya-rename-input\" value={renameDraft} autoFocus disabled={busy} aria-label={workspaceRename !== null ? t('workspaceName') : t('sessionName')} onChange={event => { setRenameDraft(event.target.value); setRenameError(null) }} />\n {renameError !== null && <div className=\"ya-error\" role=\"alert\">{renameError}</div>}\n </Modal>\n\n <Modal\n open={deleteTarget !== null}\n onClose={() => { if (!busy) setDeleteTarget(null) }}\n closeLabel={t('cancel')}\n title={t('deleteWorkspace')}\n description={deleteTarget === null ? undefined : t('deleteDescription', { name: deleteTarget.title })}\n footer={(\n <>\n <Button variant=\"outline\" disabled={busy} onClick={() => { setDeleteTarget(null) }}>{t('cancel')}</Button>\n <Button variant=\"outline\" disabled={busy} onClick={confirmDelete}>{t('deleteWorkspace')}</Button>\n </>\n )}\n >\n {renameError !== null && <div className=\"ya-error\" role=\"alert\">{renameError}</div>}\n </Modal>\n </div>\n )\n}\n","/** Client assembly for the replacement workspace sidebar and hero picker. */\nimport type { HostObservable } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type { PickerInjected, SidebarInjected } from './contract.ts'\nimport { en, NS, zh } from './locales.ts'\nimport { installStyles } from './styles.ts'\nimport { WorkspacePicker } from './WorkspacePicker.tsx'\nimport { WorkspaceSidebar } from './WorkspaceSidebar.tsx'\n\n/** Services required by both replacement client entries. */\nexport const inject = ['slots', 'sessions', 'workspaces', 'locale']\n\n/** Register the sidebar browser and conversation hero picker. */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'ya-workspace-sidebar: dictionaries')\n ctx.effect(installStyles, 'ya-workspace-sidebar: styles')\n\n const flowSource = (\n name: 'sidebar.workspaces.directoryFlow' | 'conversation.hero.workspace.directoryFlow',\n ): HostObservable<boolean> => ({\n getSnapshot: () => ctx.slots.entries(name).length > 0,\n subscribe: listener => ctx.slots.subscribe(name, listener),\n })\n const sidebarFlow = flowSource('sidebar.workspaces.directoryFlow')\n const pickerFlow = flowSource('conversation.hero.workspace.directoryFlow')\n const createWorkspace = (input: { path: string }) => ctx.workspaces.create(input)\n\n const searchSessions: SidebarInjected['searchSessions'] = async (query, signal) => {\n const result = await ctx.sessions.search(query, signal)\n if (!result.ok) throw new Error(result.error.message)\n return result.value\n }\n const sidebarInjected = (): SidebarInjected => ({\n startSession: workspaceId => { ctx.workspaces.startSession(workspaceId) },\n open: sessionId => { ctx.sessions.open(sessionId) },\n searchSessions,\n searchResultLimit: ctx.sessions.searchResultLimit,\n renameSession: async (sessionId, title) => {\n const session = ctx.sessions.binding(sessionId)?.session\n if (session === undefined) throw new Error(`unknown session \"${sessionId}\"`)\n const result = await session.rename(title)\n if (!result.ok) throw new Error(result.error.message)\n },\n forkSession: sessionId => {\n ctx.sessions.fork({ sessionId, increaseTitle: true })\n .then(childId => { ctx.sessions.open(childId) })\n .catch(() => {})\n },\n renameWorkspace: async (workspaceId, title) => { await ctx.workspaces.rename(workspaceId, title) },\n deleteWorkspace: async workspaceId => { await ctx.workspaces.delete(workspaceId) },\n archiveSession: async sessionId => { await ctx.workspaces.archiveSession(sessionId) },\n insertSessionBefore: async (workspaceId, sessionId, beforeSessionId) => {\n await ctx.workspaces.insertSessionBefore(workspaceId, sessionId, beforeSessionId)\n },\n createWorkspace,\n hooks: { directoryFlow: sidebarFlow },\n })\n const pickerInjected = (): PickerInjected => ({\n createWorkspace,\n hooks: { directoryFlow: pickerFlow },\n })\n\n ctx.slots.inject('sidebar.workspaces', () => ctx.slots.register({\n name: 'sidebar.workspaces',\n children: { 'sidebar.workspaces.directoryFlow': { kind: 'single', scope: 'root' } },\n inject: sidebarInjected,\n locale: NS,\n }, WorkspaceSidebar))\n\n ctx.slots.inject('conversation.hero.workspace', () => ctx.slots.register({\n name: 'conversation.hero.workspace',\n children: { 'conversation.hero.workspace.directoryFlow': { kind: 'single', scope: 'root' } },\n inject: pickerInjected,\n locale: NS,\n }, WorkspacePicker))\n}\n"],"mappings":"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"}
|
|
@@ -42,6 +42,10 @@ export declare const zh: {
|
|
|
42
42
|
completed: string;
|
|
43
43
|
collapse: string;
|
|
44
44
|
expand: string;
|
|
45
|
+
today: string;
|
|
46
|
+
yesterday: string;
|
|
47
|
+
date: string;
|
|
48
|
+
dateYear: string;
|
|
45
49
|
};
|
|
46
50
|
export type YaWorkspaceKey = keyof typeof zh;
|
|
47
51
|
export declare const en: {
|
|
@@ -87,5 +91,9 @@ export declare const en: {
|
|
|
87
91
|
completed: string;
|
|
88
92
|
collapse: string;
|
|
89
93
|
expand: string;
|
|
94
|
+
today: string;
|
|
95
|
+
yesterday: string;
|
|
96
|
+
date: string;
|
|
97
|
+
dateYear: string;
|
|
90
98
|
};
|
|
91
99
|
export declare const NS = "ya-workspace-sidebar";
|
|
@@ -16,6 +16,14 @@ export interface SessionRow {
|
|
|
16
16
|
workspaceKey: WorkspaceId | typeof UNGROUPED;
|
|
17
17
|
workspaceTitle: string;
|
|
18
18
|
}
|
|
19
|
+
/** One date-bucketed group of session rows for the real-workspace level. */
|
|
20
|
+
export interface SessionDateGroup {
|
|
21
|
+
/** Local calendar date `YYYY-MM-DD`, stable key. */
|
|
22
|
+
dateKey: string;
|
|
23
|
+
/** Days between today's local date and this group's local date (0=today, 1=yesterday, …). */
|
|
24
|
+
dayOffset: number;
|
|
25
|
+
rows: SessionRow[];
|
|
26
|
+
}
|
|
19
27
|
/** One first-level workspace row. */
|
|
20
28
|
export interface WorkspaceRow {
|
|
21
29
|
key: WorkspaceId | typeof UNGROUPED;
|
|
@@ -33,5 +41,15 @@ export declare function deriveRecent(list: SessionListState, workspaces: readonl
|
|
|
33
41
|
export declare function deriveWorkspaces(list: SessionListState, workspaces: readonly WorkspaceView[], archivedSessionIds: readonly SessionId[]): WorkspaceRow[];
|
|
34
42
|
/** Derive the selected workspace's sessions in its canonical order. */
|
|
35
43
|
export declare function deriveWorkspaceSessions(key: WorkspaceId | typeof UNGROUPED, list: SessionListState, workspaces: readonly WorkspaceView[], archivedSessionIds: readonly SessionId[]): SessionRow[];
|
|
44
|
+
/**
|
|
45
|
+
* Derive the selected real workspace's sessions grouped by local calendar date.
|
|
46
|
+
*
|
|
47
|
+
* - Only real workspaces: `Ungrouped` falls back to {@link deriveWorkspaceSessions}.
|
|
48
|
+
* - Groups are ordered by date descending; rows within a group by `updatedAt` descending.
|
|
49
|
+
* - {@link visible} filter is reused (archived / subagent / blank visibility).
|
|
50
|
+
* - Future timestamps clamp to today's bucket (`dayOffset` 0).
|
|
51
|
+
* - `now` is the reference timestamp for "today"; pass `Date.now()` in production.
|
|
52
|
+
*/
|
|
53
|
+
export declare function deriveWorkspaceSessionGroups(key: WorkspaceId | typeof UNGROUPED, list: SessionListState, workspaces: readonly WorkspaceView[], archivedSessionIds: readonly SessionId[], now: number): SessionDateGroup[];
|
|
36
54
|
/** Case-insensitive local title/workspace matching used beside Host content search. */
|
|
37
55
|
export declare function localMatches(rows: readonly SessionRow[], query: string): SessionRow[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/** One scoped stylesheet injected for the lifetime of the client activation. */
|
|
2
|
-
export declare const CSS = "\n[data-ya-workspace-sidebar] { flex:1; min-height:0; display:flex; flex-direction:column; box-sizing:border-box; padding-right:var(--dsh-sidebar-inline-padding); color:var(--dsw-alias-label-primary); }\n[data-ya-workspace-sidebar].ya-rail { padding-right:0; }\n.ya-section-header { flex:none; height:36px; display:flex; align-items:center; justify-content:flex-end; gap:4px; padding-left:12px; margin-bottom:4px; box-sizing:border-box; color:var(--dsw-alias-label-tertiary); }\n.ya-section-title { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:14px; }\n.ya-icon-button { flex:none; width:28px; height:28px; border:0; border-radius:50%; padding:0; display:inline-flex; align-items:center; justify-content:center; color:var(--dsw-alias-label-secondary); background:transparent; cursor:pointer; }\n.ya-icon-button:hover { background:var(--dsw-alias-interactive-bg-hover); }\n.ya-search { flex:none; height:38px; margin:0 2px 10px; padding:0 14px; display:flex; align-items:center; gap:8px; box-sizing:border-box; border:1px solid var(--dsw-alias-border-l2); border-radius:24px; background:var(--dsw-static-neutral-bluish-75); color:var(--dsw-alias-label-caption); }\nbody[data-ds-dark-theme] .ya-search { background:var(--dsw-static-neutral-bluish-900); }\n.ya-search-input { flex:1; min-width:0; border:0; outline:0; background:transparent; color:var(--dsw-alias-label-primary); font:inherit; font-size:14px; }\n.ya-search-input::placeholder { color:var(--dsw-alias-label-tertiary); }\n.ya-search-icon { flex:none; display:inline-flex; border:0; padding:0; color:inherit; background:transparent; }\n.ya-body { flex:1; min-height:0; display:flex; flex-direction:column; overflow:hidden; margin-right:calc(-1 * var(--dsh-sidebar-inline-padding)); padding-right:var(--dsh-sidebar-inline-padding); }\n.ya-recent { flex:none; padding-bottom:8px; border-bottom:1px solid var(--dsw-alias-border-l2); }\n.ya-recent-collapsed { padding-bottom:0; border-bottom-color:transparent; }\n.ya-recent-list-wrap { display:grid; grid-template-rows:1fr; transition:grid-template-rows 220ms ease-out; }\n.ya-recent-collapsed .ya-recent-list-wrap { grid-template-rows:0fr; }\n.ya-recent-list { display:flex; flex-direction:column; overflow:hidden; min-height:0; }\n.ya-block-label { height:26px; display:flex; align-items:center; gap:2px; padding:0 8px; color:var(--dsw-alias-label-tertiary); font-size:12px; font-weight:600; letter-spacing:.02em; text-transform:uppercase; }\n.ya-block-label-toggle { flex:none; width:20px; height:20px; margin-left:auto; border:0; border-radius:6px; padding:0; display:inline-flex; align-items:center; justify-content:center; background:transparent; color:var(--dsw-alias-label-tertiary); cursor:pointer; transition:transform 180ms ease-out; }\n.ya-block-label-toggle:hover { background:var(--dsw-alias-interactive-bg-hover); color:var(--dsw-alias-label-secondary); }\n.ya-block-label-toggle.ya-collapsed { transform:rotate(-90deg); }\n.ya-breadcrumb { flex:none; height:34px; display:flex; align-items:center; gap:2px; padding:0 6px; color:var(--dsw-alias-label-tertiary); font-size:13px; }\n.ya-crumb { border:0; padding:4px 3px; border-radius:6px; background:transparent; color:inherit; font:inherit; cursor:default; min-width:0; overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }\nbutton.ya-crumb:hover { background:var(--dsw-alias-interactive-bg-hover); color:var(--dsw-alias-label-primary); cursor:pointer; }\n.ya-scroll { flex:1; min-height:0; overflow-y:auto; padding-bottom:12px; }\n.ya-row { position:relative; min-height:34px; display:flex; align-items:center; gap:6px; margin:1px 0; padding:0 7px; border-radius:9px; box-sizing:border-box; color:var(--dsw-alias-label-primary); cursor:pointer; user-select:none; }\n.ya-row:hover, .ya-row.ya-menu-open { background:var(--dsw-alias-interactive-bg-hover); }\n.ya-row.ya-selected { background:var(--dsw-alias-interactive-bg-selected); }\n.ya-workspace-row { min-height:40px; }\n.ya-row-main { flex:1; min-width:0; display:flex; flex-direction:column; justify-content:center; }\n.ya-row-line { display:flex; align-items:center; min-width:0; gap:6px; }\n.ya-row-title { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:13px; line-height:18px; }\n.ya-row-meta { flex:none; color:var(--dsw-alias-label-tertiary); font-size:11px; white-space:nowrap; }\n.ya-workspace-path { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--dsw-alias-label-tertiary); font-size:11px; line-height:15px; }\n.ya-row-actions { flex:none; display:flex; align-items:center; gap:2px; opacity:0; pointer-events:none; transition:opacity 120ms ease-out; }\n.ya-row:hover .ya-row-actions, .ya-menu-open .ya-row-actions { opacity:1; pointer-events:auto; }\n.ya-status-slot { flex:none; width:16px; height:16px; display:inline-flex; align-items:center; justify-content:center; color:var(--dsw-alias-label-tertiary); }\n.ya-recent .ya-row { min-height:31px; }\n.ya-search-workspace { color:var(--dsw-alias-label-tertiary); font-size:11px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }\n.ya-empty, .ya-status { padding:18px 10px; color:var(--dsw-alias-label-tertiary); text-align:center; font-size:13px; }\n.ya-warning { color:var(--dsw-alias-status-warning); }\n.ya-rename-input { width:100%; height:38px; box-sizing:border-box; border:1px solid var(--dsw-alias-border-l2); border-radius:9px; padding:0 11px; background:transparent; color:var(--dsw-alias-label-primary); outline:none; }\n.ya-error { margin-top:8px; color:var(--dsw-alias-status-error); font-size:12px; }\n.ya-
|
|
2
|
+
export declare const CSS = "\n[data-ya-workspace-sidebar] { flex:1; min-height:0; display:flex; flex-direction:column; box-sizing:border-box; padding-right:var(--dsh-sidebar-inline-padding); color:var(--dsw-alias-label-primary); }\n[data-ya-workspace-sidebar].ya-rail { padding-right:0; }\n.ya-section-header { flex:none; height:36px; display:flex; align-items:center; justify-content:flex-end; gap:4px; padding-left:12px; margin-bottom:4px; box-sizing:border-box; color:var(--dsw-alias-label-tertiary); }\n.ya-section-title { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:14px; }\n.ya-icon-button { flex:none; width:28px; height:28px; border:0; border-radius:50%; padding:0; display:inline-flex; align-items:center; justify-content:center; color:var(--dsw-alias-label-secondary); background:transparent; cursor:pointer; }\n.ya-icon-button:hover { background:var(--dsw-alias-interactive-bg-hover); }\n.ya-search { flex:none; height:38px; margin:0 2px 10px; padding:0 14px; display:flex; align-items:center; gap:8px; box-sizing:border-box; border:1px solid var(--dsw-alias-border-l2); border-radius:24px; background:var(--dsw-static-neutral-bluish-75); color:var(--dsw-alias-label-caption); }\nbody[data-ds-dark-theme] .ya-search { background:var(--dsw-static-neutral-bluish-900); }\n.ya-search-input { flex:1; min-width:0; border:0; outline:0; background:transparent; color:var(--dsw-alias-label-primary); font:inherit; font-size:14px; }\n.ya-search-input::placeholder { color:var(--dsw-alias-label-tertiary); }\n.ya-search-icon { flex:none; display:inline-flex; border:0; padding:0; color:inherit; background:transparent; }\n.ya-body { flex:1; min-height:0; display:flex; flex-direction:column; overflow:hidden; margin-right:calc(-1 * var(--dsh-sidebar-inline-padding)); padding-right:var(--dsh-sidebar-inline-padding); }\n.ya-recent { flex:none; padding-bottom:8px; border-bottom:1px solid var(--dsw-alias-border-l2); }\n.ya-recent-collapsed { padding-bottom:0; border-bottom-color:transparent; }\n.ya-recent-list-wrap { display:grid; grid-template-rows:1fr; transition:grid-template-rows 220ms ease-out; }\n.ya-recent-collapsed .ya-recent-list-wrap { grid-template-rows:0fr; }\n.ya-recent-list { display:flex; flex-direction:column; overflow:hidden; min-height:0; }\n.ya-block-label { height:26px; display:flex; align-items:center; gap:2px; padding:0 8px; color:var(--dsw-alias-label-tertiary); font-size:12px; font-weight:600; letter-spacing:.02em; text-transform:uppercase; }\n.ya-block-label-toggle { flex:none; width:20px; height:20px; margin-left:auto; border:0; border-radius:6px; padding:0; display:inline-flex; align-items:center; justify-content:center; background:transparent; color:var(--dsw-alias-label-tertiary); cursor:pointer; transition:transform 180ms ease-out; }\n.ya-block-label-toggle:hover { background:var(--dsw-alias-interactive-bg-hover); color:var(--dsw-alias-label-secondary); }\n.ya-block-label-toggle.ya-collapsed { transform:rotate(-90deg); }\n.ya-date-group-label { height:26px; display:flex; align-items:center; padding:0 8px; color:var(--dsw-alias-label-tertiary); font-size:12px; font-weight:600; letter-spacing:.02em; }\n.ya-breadcrumb { flex:none; height:34px; display:flex; align-items:center; gap:2px; padding:0 6px; color:var(--dsw-alias-label-tertiary); font-size:13px; }\n.ya-crumb { border:0; padding:4px 3px; border-radius:6px; background:transparent; color:inherit; font:inherit; cursor:default; min-width:0; overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }\nbutton.ya-crumb:hover { background:var(--dsw-alias-interactive-bg-hover); color:var(--dsw-alias-label-primary); cursor:pointer; }\n.ya-scroll { flex:1; min-height:0; overflow-y:auto; padding-bottom:12px; }\n.ya-row { position:relative; min-height:34px; display:flex; align-items:center; gap:6px; margin:1px 0; padding:0 7px; border-radius:9px; box-sizing:border-box; color:var(--dsw-alias-label-primary); cursor:pointer; user-select:none; }\n.ya-row:hover, .ya-row.ya-menu-open { background:var(--dsw-alias-interactive-bg-hover); }\n.ya-row.ya-selected { background:var(--dsw-alias-interactive-bg-selected); }\n.ya-workspace-row { min-height:40px; }\n.ya-row-main { flex:1; min-width:0; display:flex; flex-direction:column; justify-content:center; }\n.ya-row-line { display:flex; align-items:center; min-width:0; gap:6px; }\n.ya-row-title { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:13px; line-height:18px; }\n.ya-row-meta { flex:none; color:var(--dsw-alias-label-tertiary); font-size:11px; white-space:nowrap; }\n.ya-workspace-path { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--dsw-alias-label-tertiary); font-size:11px; line-height:15px; }\n.ya-row-actions { flex:none; display:flex; align-items:center; gap:2px; opacity:0; pointer-events:none; transition:opacity 120ms ease-out; }\n.ya-row:hover .ya-row-actions, .ya-menu-open .ya-row-actions { opacity:1; pointer-events:auto; }\n.ya-status-slot { flex:none; width:16px; height:16px; display:inline-flex; align-items:center; justify-content:center; color:var(--dsw-alias-label-tertiary); }\n.ya-recent .ya-row { min-height:31px; }\n.ya-search-workspace { color:var(--dsw-alias-label-tertiary); font-size:11px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }\n.ya-empty, .ya-status { padding:18px 10px; color:var(--dsw-alias-label-tertiary); text-align:center; font-size:13px; }\n.ya-warning { color:var(--dsw-alias-status-warning); }\n.ya-rename-input { width:100%; height:38px; box-sizing:border-box; border:1px solid var(--dsw-alias-border-l2); border-radius:9px; padding:0 11px; background:transparent; color:var(--dsw-alias-label-primary); outline:none; }\n.ya-error { margin-top:8px; color:var(--dsw-alias-status-error); font-size:12px; }\n.ya-rail .ya-section-header { padding-left:0; margin-bottom:12px; }\n.ya-rail .ya-icon-button, .ya-rail .ya-search { width:36px; height:36px; padding:0; margin:0 0 12px; border-color:transparent; background:transparent; }\n.ya-rail .ya-search { justify-content:center; }\n.ya-rail .ya-search-icon { cursor:pointer; color:var(--dsw-alias-label-primary); }\n.ya-picker-error { color:var(--dsw-alias-status-error); white-space:pre-wrap; }\n@keyframes ya-slide-in-forward { from { opacity:0; transform:translateX(10px); } to { opacity:1; transform:translateX(0); } }\n@keyframes ya-slide-in-backward { from { opacity:0; transform:translateX(-10px); } to { opacity:1; transform:translateX(0); } }\n.ya-level-enter-forward { animation:ya-slide-in-forward 180ms ease-out; }\n.ya-level-enter-backward { animation:ya-slide-in-backward 180ms ease-out; }\n";
|
|
3
3
|
/** Install the stylesheet and return its disposer. */
|
|
4
4
|
export declare function installStyles(): () => void;
|
package/package.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@huanlin/dsh-plugin-ya-workspace-sidebar",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
|
-
"keywords": [
|
|
7
|
+
"keywords": [
|
|
8
|
+
"dsh-plugin"
|
|
9
|
+
],
|
|
8
10
|
"description": "Two-level DSH workspace sidebar with global recent sessions and breadcrumb navigation.",
|
|
9
11
|
"type": "module",
|
|
10
12
|
"license": "AGPL-3.0",
|
|
@@ -46,12 +48,6 @@
|
|
|
46
48
|
"platform": "web"
|
|
47
49
|
}
|
|
48
50
|
},
|
|
49
|
-
"scripts": {
|
|
50
|
-
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
51
|
-
"test": "vitest run",
|
|
52
|
-
"build": "tsdown -c tsdown.config.ts && tsc -p tsconfig.json",
|
|
53
|
-
"bundle:client": "tsdown -c tsdown.config.ts"
|
|
54
|
-
},
|
|
55
51
|
"peerDependencies": {
|
|
56
52
|
"@deepseek-ai/dsh-client-locale": "^0.0.1-rc.1",
|
|
57
53
|
"@deepseek-ai/dsh-client-runtime": "^0.0.1-rc.1",
|
|
@@ -64,15 +60,33 @@
|
|
|
64
60
|
"react": "^18.2.0"
|
|
65
61
|
},
|
|
66
62
|
"peerDependenciesMeta": {
|
|
67
|
-
"@deepseek-ai/dsh-client-locale": {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
"@deepseek-ai/dsh-client-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
"@deepseek-ai/dsh-
|
|
74
|
-
|
|
75
|
-
|
|
63
|
+
"@deepseek-ai/dsh-client-locale": {
|
|
64
|
+
"optional": true
|
|
65
|
+
},
|
|
66
|
+
"@deepseek-ai/dsh-client-runtime": {
|
|
67
|
+
"optional": true
|
|
68
|
+
},
|
|
69
|
+
"@deepseek-ai/dsh-client-ui-conversation": {
|
|
70
|
+
"optional": true
|
|
71
|
+
},
|
|
72
|
+
"@deepseek-ai/dsh-client-ui-primitives": {
|
|
73
|
+
"optional": true
|
|
74
|
+
},
|
|
75
|
+
"@deepseek-ai/dsh-client-ui-sidebar": {
|
|
76
|
+
"optional": true
|
|
77
|
+
},
|
|
78
|
+
"@deepseek-ai/dsh-client-ui-slots": {
|
|
79
|
+
"optional": true
|
|
80
|
+
},
|
|
81
|
+
"@deepseek-ai/dsh-invariants": {
|
|
82
|
+
"optional": true
|
|
83
|
+
},
|
|
84
|
+
"cordis": {
|
|
85
|
+
"optional": true
|
|
86
|
+
},
|
|
87
|
+
"react": {
|
|
88
|
+
"optional": true
|
|
89
|
+
}
|
|
76
90
|
},
|
|
77
91
|
"devDependencies": {
|
|
78
92
|
"@deepseek-ai/dsh-client-locale": "^0.0.1-rc.1",
|
|
@@ -93,5 +107,11 @@
|
|
|
93
107
|
},
|
|
94
108
|
"engines": {
|
|
95
109
|
"node": ">=22.0.0"
|
|
110
|
+
},
|
|
111
|
+
"scripts": {
|
|
112
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
113
|
+
"test": "vitest run",
|
|
114
|
+
"build": "tsdown -c tsdown.config.ts && tsc -p tsconfig.json",
|
|
115
|
+
"bundle:client": "tsdown -c tsdown.config.ts"
|
|
96
116
|
}
|
|
97
|
-
}
|
|
117
|
+
}
|