@deepseek-ai/dsh-client-ui-workspace 0.1.2-alpha.5 → 0.1.3-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +2 -2
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/lib/client.js +105 -42
- package/lib/types/client/rows/Rows.d.ts +4 -1
- package/lib/types/client/tree.d.ts +7 -0
- package/package.json +18 -18
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/client/ui-workspace/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: c7e0e7e53886b6ae1a4de7c40ed6041a61280446
|
|
6
|
+
README.zh.md: 695e89acb967924f0f617b7c17b6581ee38f8ba5
|
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ View options combine grouping with one browser-persisted Session order per accou
|
|
|
33
33
|
|
|
34
34
|
### Search
|
|
35
35
|
|
|
36
|
-
Collapsed search is one header action beside the view and add actions: activating it expands the field across the header. A non-blank query replaces either browsing mode with one flat result list — case-insensitive title and Workspace substring matches appear immediately, while a 250 ms debounced Host request adds ranked current-conversation content matches and snippets. Each new query aborts the preceding request; a failed content search leaves metadata matches visible with a warning. The list is capped at 20 and opens the
|
|
36
|
+
Collapsed search is one header action beside the view and add actions: activating it expands the field across the header. A non-blank query replaces either browsing mode with one flat result list — case-insensitive title and Workspace substring matches appear immediately, while a 250 ms debounced Host request adds ranked current-conversation content matches and snippets. Each new query aborts the preceding request; a failed content search leaves metadata matches visible with a warning. The list is capped at 20. Choosing a result clears and collapses search, opens the Session, and scrolls its row into view in the configured browsing mode; grouped browsing also expands its Workspace and the full Session list when required.
|
|
37
37
|
|
|
38
38
|
### Managing sessions
|
|
39
39
|
|
package/README.zh.md
CHANGED
|
@@ -33,7 +33,7 @@ kind: "package-reference"
|
|
|
33
33
|
|
|
34
34
|
### 搜索
|
|
35
35
|
|
|
36
|
-
折叠搜索是视图和添加操作旁的一枚区头按钮:激活后输入框会扩展并占据区头。非空白查询会以单一扁平结果列表替代任一浏览模式——不区分大小写的标题和 Workspace 子串匹配项会立即显示,经 250 ms 防抖的 Host 请求则会加入经过排序的当前对话内容匹配项及其摘要片段。每次新查询都会中止前一个请求;内容搜索失败时,元数据匹配项仍会显示,同时给出警告。列表最多显示 20
|
|
36
|
+
折叠搜索是视图和添加操作旁的一枚区头按钮:激活后输入框会扩展并占据区头。非空白查询会以单一扁平结果列表替代任一浏览模式——不区分大小写的标题和 Workspace 子串匹配项会立即显示,经 250 ms 防抖的 Host 请求则会加入经过排序的当前对话内容匹配项及其摘要片段。每次新查询都会中止前一个请求;内容搜索失败时,元数据匹配项仍会显示,同时给出警告。列表最多显示 20 条结果。选择结果会清空并收起搜索、打开 Session,并在当前浏览模式中将其行滚动到可见区域;分组浏览还会按需展开所属 Workspace 和完整 Session 列表。
|
|
37
37
|
|
|
38
38
|
### 管理会话
|
|
39
39
|
|
package/lib/client.js
CHANGED
|
@@ -290,6 +290,15 @@ window.__ModuleLoader__.load({
|
|
|
290
290
|
return indexed;
|
|
291
291
|
}
|
|
292
292
|
/**
|
|
293
|
+
* Resolve the Workspace browser group that owns one Session.
|
|
294
|
+
* @param workspaces - authoritative Workspace membership.
|
|
295
|
+
* @param sessionId - Session whose browser group is required.
|
|
296
|
+
* @returns owning Workspace id, or {@link UNGROUPED_KEY} when no Workspace accounts for it.
|
|
297
|
+
*/
|
|
298
|
+
function owningGroupKey(workspaces, sessionId) {
|
|
299
|
+
return workspaces.find((workspace) => workspace.sessionIds.includes(sessionId))?.workspaceId ?? "";
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
293
302
|
* Directory display label: basename of the path (both separators accepted).
|
|
294
303
|
* Ungrouped-bucket fallback for surfaces without a workspace title.
|
|
295
304
|
* @param cwd - directory path, or undefined for the ungrouped bucket.
|
|
@@ -422,7 +431,7 @@ window.__ModuleLoader__.load({
|
|
|
422
431
|
const archived = new Set(archivedSessionIds);
|
|
423
432
|
const expandedGroups = new Set(view.expandedGroups);
|
|
424
433
|
const descendants = indexSubagentDescendants(list.byId);
|
|
425
|
-
const currentGroup = list.current === void 0 ? void 0 : workspaces
|
|
434
|
+
const currentGroup = list.current === void 0 ? void 0 : owningGroupKey(workspaces, list.current);
|
|
426
435
|
const groups = [];
|
|
427
436
|
for (const g of groupByWorkspace(list, workspaces, archived, view.ungroupedOrder)) {
|
|
428
437
|
const expanded = expandedGroups.has(g.key);
|
|
@@ -902,18 +911,25 @@ window.__ModuleLoader__.load({
|
|
|
902
911
|
* @param props.onRename - open the session rename dialog (id + current title).
|
|
903
912
|
* @param props.onFork - fork a session at its last completed turn.
|
|
904
913
|
* @param props.onArchive - archive a session by id.
|
|
914
|
+
* @param props.onReveal - scroll this row into view after search navigation, then acknowledge it.
|
|
905
915
|
* @param props.drag - optional draggable-row wiring.
|
|
906
916
|
* @param props.flat - omit the empty status slot in the hierarchy-free flat list.
|
|
907
917
|
* @param props.t - the browser root's locale seat.
|
|
908
918
|
* @returns the session row.
|
|
909
919
|
*/
|
|
910
|
-
function SessionNodeItem({ node, currentId, now, onOpen, onRename, onFork, onArchive, drag, flat = false, t }) {
|
|
920
|
+
function SessionNodeItem({ node, currentId, now, onOpen, onRename, onFork, onArchive, onReveal, drag, flat = false, t }) {
|
|
911
921
|
const row = node;
|
|
912
922
|
const title = displayTitle(node, t);
|
|
913
923
|
const selected = node.id === currentId;
|
|
914
924
|
const statuses = sessionStatuses(node, t);
|
|
915
925
|
const showStatus = statuses[0].state !== "done" || row.completed;
|
|
916
926
|
const [menuOpen, setMenuOpen] = (0, react.useState)(false);
|
|
927
|
+
const rowRef = (0, react.useRef)(null);
|
|
928
|
+
(0, react.useEffect)(() => {
|
|
929
|
+
if (onReveal === void 0) return;
|
|
930
|
+
rowRef.current?.scrollIntoView({ block: "nearest" });
|
|
931
|
+
onReveal();
|
|
932
|
+
}, [onReveal]);
|
|
917
933
|
const sessionMenuItems = [
|
|
918
934
|
{
|
|
919
935
|
id: "rename",
|
|
@@ -933,6 +949,7 @@ window.__ModuleLoader__.load({
|
|
|
933
949
|
];
|
|
934
950
|
return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.HoverCard, {
|
|
935
951
|
anchor: (0, react_jsx_runtime.jsxs)("div", {
|
|
952
|
+
ref: rowRef,
|
|
936
953
|
className: clsx(Rows_module_css_default.sessionRow, selected && Rows_module_css_default.selected, menuOpen && Rows_module_css_default.menuOpen, flat && !showStatus && Rows_module_css_default.flatSessionRowWithoutStatus, drag?.marker === "before" && Rows_module_css_default.dropBefore, drag?.marker === "after" && Rows_module_css_default.dropAfter),
|
|
937
954
|
role: "treeitem",
|
|
938
955
|
"aria-selected": selected,
|
|
@@ -1429,10 +1446,11 @@ window.__ModuleLoader__.load({
|
|
|
1429
1446
|
return e.clientY < rect.top + rect.height / 2 ? "before" : "after";
|
|
1430
1447
|
}
|
|
1431
1448
|
/** The scrolling session tree; unmounting drops the sessions subscription and expand-all state. */
|
|
1432
|
-
function SessionTree({ useSessions, useSessionPendingInteraction, startSession, open, forkSession, workspaces, archivedSessionIds, onRenameRequest, onDeleteRequest, onSessionRename, onSessionArchive, insertWorkspaceBefore, insertSessionBefore, orderBy, groupExpansion, setGroupExpanded, sessionOrderByAccount, sessionUpdatedAtByAccount, syncSessionOrderAccount, setSessionOrder, home, t }) {
|
|
1449
|
+
function SessionTree({ useSessions, useSessionPendingInteraction, startSession, open, forkSession, workspaces, archivedSessionIds, workspaceReady, onRenameRequest, onDeleteRequest, onSessionRename, onSessionArchive, insertWorkspaceBefore, insertSessionBefore, orderBy, groupExpansion, setGroupExpanded, sessionOrderByAccount, sessionUpdatedAtByAccount, syncSessionOrderAccount, setSessionOrder, home, t, revealSessionId, onSessionRevealed }) {
|
|
1433
1450
|
const list = useSessions((s) => s);
|
|
1434
1451
|
const pendingInteractions = useSessionPendingInteraction((s) => s);
|
|
1435
1452
|
const current = list.current;
|
|
1453
|
+
const revealGroup = revealSessionId === void 0 || !workspaceReady ? void 0 : owningGroupKey(workspaces, revealSessionId);
|
|
1436
1454
|
const [expandedSessionGroups, setExpandedSessionGroups] = (0, react.useState)([]);
|
|
1437
1455
|
const [drag, setDrag] = (0, react.useState)(null);
|
|
1438
1456
|
const sessionDropCommitted = (0, react.useRef)(false);
|
|
@@ -1440,7 +1458,7 @@ window.__ModuleLoader__.load({
|
|
|
1440
1458
|
const workspaceDropCommitted = (0, react.useRef)(false);
|
|
1441
1459
|
const previousOrderBy = (0, react.useRef)(orderBy);
|
|
1442
1460
|
useNativeDragAcceptance(drag !== null || workspaceDrag !== null);
|
|
1443
|
-
const currentGroup = current === void 0 ? void 0 : workspaces
|
|
1461
|
+
const currentGroup = current === void 0 || !workspaceReady ? void 0 : owningGroupKey(workspaces, current);
|
|
1444
1462
|
(0, react.useEffect)(() => {
|
|
1445
1463
|
if (current === void 0 || currentGroup === void 0 || Object.hasOwn(groupExpansion, currentGroup)) return;
|
|
1446
1464
|
setGroupExpanded(currentGroup, true);
|
|
@@ -1509,6 +1527,25 @@ window.__ModuleLoader__.load({
|
|
|
1509
1527
|
expandedGroups,
|
|
1510
1528
|
sessionOrderByAccount
|
|
1511
1529
|
]);
|
|
1530
|
+
(0, react.useEffect)(() => {
|
|
1531
|
+
if (revealGroup === void 0 || groupExpansion[revealGroup] === true) return;
|
|
1532
|
+
setGroupExpanded(revealGroup, true);
|
|
1533
|
+
}, [
|
|
1534
|
+
groupExpansion,
|
|
1535
|
+
revealGroup,
|
|
1536
|
+
setGroupExpanded
|
|
1537
|
+
]);
|
|
1538
|
+
(0, react.useEffect)(() => {
|
|
1539
|
+
if (revealSessionId === void 0 || revealGroup === void 0) return;
|
|
1540
|
+
const group = groups.find((candidate) => candidate.key === revealGroup);
|
|
1541
|
+
if (group === void 0 || !group.expanded || !group.sessions.some((row) => row.id === revealSessionId)) return;
|
|
1542
|
+
if (collapsedSessionRows(group.sessions).rows.some((row) => row.id === revealSessionId)) return;
|
|
1543
|
+
setExpandedSessionGroups((keys) => keys.includes(revealGroup) ? keys : [...keys, revealGroup]);
|
|
1544
|
+
}, [
|
|
1545
|
+
groups,
|
|
1546
|
+
revealGroup,
|
|
1547
|
+
revealSessionId
|
|
1548
|
+
]);
|
|
1512
1549
|
const now = Date.now();
|
|
1513
1550
|
const commitSessionDrag = (activeDrag, over) => {
|
|
1514
1551
|
if (sessionDropCommitted.current) return;
|
|
@@ -1661,6 +1698,41 @@ window.__ModuleLoader__.load({
|
|
|
1661
1698
|
}),
|
|
1662
1699
|
(sessionsExpanded ? group.sessions : collapsed.rows).map((node) => {
|
|
1663
1700
|
const sameGroupDrag = drag !== null && drag.accountKey === group.key;
|
|
1701
|
+
const dragProps = {
|
|
1702
|
+
start: () => {
|
|
1703
|
+
sessionDropCommitted.current = false;
|
|
1704
|
+
setDrag({
|
|
1705
|
+
accountKey: group.key,
|
|
1706
|
+
sessionId: node.id,
|
|
1707
|
+
over: null
|
|
1708
|
+
});
|
|
1709
|
+
},
|
|
1710
|
+
active: sameGroupDrag,
|
|
1711
|
+
marker: sameGroupDrag && drag.over?.id === node.id ? drag.over.half : null,
|
|
1712
|
+
hover: (half) => {
|
|
1713
|
+
/* v8 ignore next -- narrowing guard: Rows gates hover on `active`, which is false while the drag state is null. */
|
|
1714
|
+
setDrag((d) => d === null ? d : {
|
|
1715
|
+
...d,
|
|
1716
|
+
over: {
|
|
1717
|
+
id: node.id,
|
|
1718
|
+
half
|
|
1719
|
+
}
|
|
1720
|
+
});
|
|
1721
|
+
},
|
|
1722
|
+
drop: (half) => {
|
|
1723
|
+
/* v8 ignore next -- narrowing guard: Rows gates drop on `active`, which is false while the drag state is null. */
|
|
1724
|
+
if (drag === null) return;
|
|
1725
|
+
commitSessionDrag(drag, {
|
|
1726
|
+
id: node.id,
|
|
1727
|
+
half
|
|
1728
|
+
});
|
|
1729
|
+
},
|
|
1730
|
+
end: () => {
|
|
1731
|
+
if (drag?.over !== null && drag?.over !== void 0) commitSessionDrag(drag, drag.over);
|
|
1732
|
+
else setDrag(null);
|
|
1733
|
+
sessionDropCommitted.current = false;
|
|
1734
|
+
}
|
|
1735
|
+
};
|
|
1664
1736
|
return (0, react_jsx_runtime.jsx)(SessionNodeItem, {
|
|
1665
1737
|
node,
|
|
1666
1738
|
currentId: current,
|
|
@@ -1669,41 +1741,10 @@ window.__ModuleLoader__.load({
|
|
|
1669
1741
|
onRename: onSessionRename,
|
|
1670
1742
|
onFork: forkSession,
|
|
1671
1743
|
onArchive: onSessionArchive,
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
accountKey: group.key,
|
|
1677
|
-
sessionId: node.id,
|
|
1678
|
-
over: null
|
|
1679
|
-
});
|
|
1680
|
-
},
|
|
1681
|
-
active: sameGroupDrag,
|
|
1682
|
-
marker: sameGroupDrag && drag.over?.id === node.id ? drag.over.half : null,
|
|
1683
|
-
hover: (half) => {
|
|
1684
|
-
/* v8 ignore next -- narrowing guard: Rows gates hover on `active`, which is false while the drag state is null. */
|
|
1685
|
-
setDrag((d) => d === null ? d : {
|
|
1686
|
-
...d,
|
|
1687
|
-
over: {
|
|
1688
|
-
id: node.id,
|
|
1689
|
-
half
|
|
1690
|
-
}
|
|
1691
|
-
});
|
|
1692
|
-
},
|
|
1693
|
-
drop: (half) => {
|
|
1694
|
-
/* v8 ignore next -- narrowing guard: Rows gates drop on `active`, which is false while the drag state is null. */
|
|
1695
|
-
if (drag === null) return;
|
|
1696
|
-
commitSessionDrag(drag, {
|
|
1697
|
-
id: node.id,
|
|
1698
|
-
half
|
|
1699
|
-
});
|
|
1700
|
-
},
|
|
1701
|
-
end: () => {
|
|
1702
|
-
if (drag?.over !== null && drag?.over !== void 0) commitSessionDrag(drag, drag.over);
|
|
1703
|
-
else setDrag(null);
|
|
1704
|
-
sessionDropCommitted.current = false;
|
|
1705
|
-
}
|
|
1706
|
-
},
|
|
1744
|
+
onReveal: node.id === revealSessionId && group.key === revealGroup ? () => {
|
|
1745
|
+
onSessionRevealed(node.id);
|
|
1746
|
+
} : void 0,
|
|
1747
|
+
drag: dragProps,
|
|
1707
1748
|
t
|
|
1708
1749
|
}, node.id);
|
|
1709
1750
|
}),
|
|
@@ -1725,7 +1766,7 @@ window.__ModuleLoader__.load({
|
|
|
1725
1766
|
});
|
|
1726
1767
|
}
|
|
1727
1768
|
/** The flat "In one list" body: every session is one draggable top-level row. */
|
|
1728
|
-
function FlatList({ useSessions, useSessionPendingInteraction, open, forkSession, onSessionRename, onSessionArchive, archivedSessionIds, orderBy, sessionOrderByAccount, sessionUpdatedAtByAccount, syncSessionOrderAccount, setSessionOrder, t }) {
|
|
1769
|
+
function FlatList({ useSessions, useSessionPendingInteraction, open, forkSession, onSessionRename, onSessionArchive, archivedSessionIds, orderBy, sessionOrderByAccount, sessionUpdatedAtByAccount, syncSessionOrderAccount, setSessionOrder, revealSessionId, onSessionRevealed, t }) {
|
|
1729
1770
|
const list = useSessions((s) => s);
|
|
1730
1771
|
const pendingInteractions = useSessionPendingInteraction((s) => s);
|
|
1731
1772
|
const baseRows = (0, react.useMemo)(() => deriveFlat(list, archivedSessionIds, pendingInteractions), [
|
|
@@ -1808,6 +1849,9 @@ window.__ModuleLoader__.load({
|
|
|
1808
1849
|
onRename: onSessionRename,
|
|
1809
1850
|
onFork: forkSession,
|
|
1810
1851
|
onArchive: onSessionArchive,
|
|
1852
|
+
onReveal: node.id === revealSessionId ? () => {
|
|
1853
|
+
onSessionRevealed(node.id);
|
|
1854
|
+
} : void 0,
|
|
1811
1855
|
flat: true,
|
|
1812
1856
|
drag: {
|
|
1813
1857
|
start: () => {
|
|
@@ -1915,6 +1959,7 @@ window.__ModuleLoader__.load({
|
|
|
1915
1959
|
const home = useHostInfo((info) => info.home);
|
|
1916
1960
|
const workspaces = useWorkspaces((state) => state.items);
|
|
1917
1961
|
const workspacePhase = useWorkspaces((state) => state.phase);
|
|
1962
|
+
const workspaceStreamState = useWorkspaces((state) => state.state);
|
|
1918
1963
|
const archivedSessionIds = useWorkspaces((state) => state.archivedSessionIds);
|
|
1919
1964
|
const directoryFlowAvailable = useDirectoryFlow((occupied) => occupied);
|
|
1920
1965
|
const groupBy = useStore((s) => s.groupBy);
|
|
@@ -1926,7 +1971,7 @@ window.__ModuleLoader__.load({
|
|
|
1926
1971
|
const current = state.current;
|
|
1927
1972
|
return current !== void 0 && state.byId[current]?.blank === true ? current : void 0;
|
|
1928
1973
|
});
|
|
1929
|
-
const currentBlankAccount = currentBlankSessionId === void 0 ? void 0 : workspaces
|
|
1974
|
+
const currentBlankAccount = currentBlankSessionId === void 0 || workspacePhase !== "ready" ? void 0 : owningGroupKey(workspaces, currentBlankSessionId);
|
|
1930
1975
|
const promotedBlank = (0, react.useRef)(void 0);
|
|
1931
1976
|
(0, react.useEffect)(() => {
|
|
1932
1977
|
if (currentBlankSessionId === void 0 || currentBlankAccount === void 0) {
|
|
@@ -1963,6 +2008,7 @@ window.__ModuleLoader__.load({
|
|
|
1963
2008
|
]);
|
|
1964
2009
|
const [query, setQuery] = (0, react.useState)("");
|
|
1965
2010
|
const [searchExpanded, setSearchExpanded] = (0, react.useState)(false);
|
|
2011
|
+
const [revealSessionId, setRevealSessionId] = (0, react.useState)(void 0);
|
|
1966
2012
|
const normalizedQuery = sanitizeSearchQuery(query).trim();
|
|
1967
2013
|
const [remoteSearch, setRemoteSearch] = (0, react.useState)({
|
|
1968
2014
|
query: "",
|
|
@@ -1975,6 +2021,18 @@ window.__ModuleLoader__.load({
|
|
|
1975
2021
|
const [wsPickerOpen, setWsPickerOpen] = (0, react.useState)(false);
|
|
1976
2022
|
const wsPlusRef = (0, react.useRef)(null);
|
|
1977
2023
|
const composingRef = (0, react.useRef)(false);
|
|
2024
|
+
const openSearchResult = (sessionId) => {
|
|
2025
|
+
setRevealSessionId(sessionId);
|
|
2026
|
+
setQuery("");
|
|
2027
|
+
setSearchExpanded(false);
|
|
2028
|
+
open(sessionId);
|
|
2029
|
+
};
|
|
2030
|
+
const acknowledgeSessionReveal = (sessionId) => {
|
|
2031
|
+
setRevealSessionId((current) => current === sessionId ? void 0 : current);
|
|
2032
|
+
};
|
|
2033
|
+
(0, react.useEffect)(() => {
|
|
2034
|
+
if (normalizedQuery !== "") setRevealSessionId(void 0);
|
|
2035
|
+
}, [normalizedQuery]);
|
|
1978
2036
|
const [searchOnExpand, setSearchOnExpand] = (0, react.useState)(false);
|
|
1979
2037
|
(0, react.useEffect)(() => {
|
|
1980
2038
|
if (wide && searchOnExpand) {
|
|
@@ -2281,7 +2339,7 @@ window.__ModuleLoader__.load({
|
|
|
2281
2339
|
children: wide && (normalizedQuery !== "" ? (0, react_jsx_runtime.jsx)(SearchResults, {
|
|
2282
2340
|
useSessions,
|
|
2283
2341
|
useSessionPendingInteraction,
|
|
2284
|
-
open,
|
|
2342
|
+
open: openSearchResult,
|
|
2285
2343
|
workspaces,
|
|
2286
2344
|
archivedSessionIds,
|
|
2287
2345
|
query: normalizedQuery,
|
|
@@ -2301,6 +2359,8 @@ window.__ModuleLoader__.load({
|
|
|
2301
2359
|
sessionUpdatedAtByAccount,
|
|
2302
2360
|
syncSessionOrderAccount: actions.syncSessionOrderAccount,
|
|
2303
2361
|
setSessionOrder: actions.setSessionOrder,
|
|
2362
|
+
revealSessionId,
|
|
2363
|
+
onSessionRevealed: acknowledgeSessionReveal,
|
|
2304
2364
|
t
|
|
2305
2365
|
}) : (0, react_jsx_runtime.jsx)(SessionTree, {
|
|
2306
2366
|
useSessions,
|
|
@@ -2309,6 +2369,7 @@ window.__ModuleLoader__.load({
|
|
|
2309
2369
|
onSessionArchive,
|
|
2310
2370
|
forkSession,
|
|
2311
2371
|
workspaces,
|
|
2372
|
+
workspaceReady: workspacePhase === "ready" && workspaceStreamState !== "loading",
|
|
2312
2373
|
groupExpansion,
|
|
2313
2374
|
setGroupExpanded: actions.setGroupExpanded,
|
|
2314
2375
|
sessionOrderByAccount,
|
|
@@ -2321,6 +2382,8 @@ window.__ModuleLoader__.load({
|
|
|
2321
2382
|
insertWorkspaceBefore,
|
|
2322
2383
|
insertSessionBefore,
|
|
2323
2384
|
orderBy,
|
|
2385
|
+
revealSessionId,
|
|
2386
|
+
onSessionRevealed: acknowledgeSessionReveal,
|
|
2324
2387
|
home,
|
|
2325
2388
|
t,
|
|
2326
2389
|
onRenameRequest: (workspaceId, currentTitle) => {
|
|
@@ -77,12 +77,13 @@ export declare function SearchResultItem({ result, currentId, onOpen, t }: {
|
|
|
77
77
|
* @param props.onRename - open the session rename dialog (id + current title).
|
|
78
78
|
* @param props.onFork - fork a session at its last completed turn.
|
|
79
79
|
* @param props.onArchive - archive a session by id.
|
|
80
|
+
* @param props.onReveal - scroll this row into view after search navigation, then acknowledge it.
|
|
80
81
|
* @param props.drag - optional draggable-row wiring.
|
|
81
82
|
* @param props.flat - omit the empty status slot in the hierarchy-free flat list.
|
|
82
83
|
* @param props.t - the browser root's locale seat.
|
|
83
84
|
* @returns the session row.
|
|
84
85
|
*/
|
|
85
|
-
export declare function SessionNodeItem({ node, currentId, now, onOpen, onRename, onFork, onArchive, drag, flat, t }: {
|
|
86
|
+
export declare function SessionNodeItem({ node, currentId, now, onOpen, onRename, onFork, onArchive, onReveal, drag, flat, t, }: {
|
|
86
87
|
node: SessionNode;
|
|
87
88
|
currentId: string | undefined;
|
|
88
89
|
now: number;
|
|
@@ -93,6 +94,8 @@ export declare function SessionNodeItem({ node, currentId, now, onOpen, onRename
|
|
|
93
94
|
onFork: (id: SessionNode['id']) => void;
|
|
94
95
|
/** Archive this session (row menu action; commits without a dialog). */
|
|
95
96
|
onArchive: (id: SessionNode['id']) => void;
|
|
97
|
+
/** Scroll this row into view after search navigation, then acknowledge it. */
|
|
98
|
+
onReveal?: (() => void) | undefined;
|
|
96
99
|
/** Present only on draggable rows (workspace-group sessions outside search). */
|
|
97
100
|
drag?: RowDragProps | undefined;
|
|
98
101
|
/** The row is rendered without a parent Workspace header. */
|
|
@@ -9,6 +9,13 @@ import type { SessionPendingInteractionBase } from '@deepseek-ai/dsh-client-ui-s
|
|
|
9
9
|
import type { SessionId } from '@deepseek-ai/dsh-session/types';
|
|
10
10
|
/** Group key for Sessions outside every Workspace. */
|
|
11
11
|
export declare const UNGROUPED_KEY = "";
|
|
12
|
+
/**
|
|
13
|
+
* Resolve the Workspace browser group that owns one Session.
|
|
14
|
+
* @param workspaces - authoritative Workspace membership.
|
|
15
|
+
* @param sessionId - Session whose browser group is required.
|
|
16
|
+
* @returns owning Workspace id, or {@link UNGROUPED_KEY} when no Workspace accounts for it.
|
|
17
|
+
*/
|
|
18
|
+
export declare function owningGroupKey(workspaces: readonly WorkspaceView[], sessionId: SessionId): string;
|
|
12
19
|
/** Pending interaction kinds with dedicated Workspace-row presentation. */
|
|
13
20
|
export type SessionPendingInteractionStatus = 'approval' | 'plan-review' | 'question';
|
|
14
21
|
type SessionPendingInteractions = ReadonlyMap<SessionId, SessionPendingInteractionBase>;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-client-ui-workspace",
|
|
3
3
|
"description": "Workspace picker plugin: one WorkspacePicker registered into the sidebar and empty-state workspace slots",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.3-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -51,23 +51,23 @@
|
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/react": "~18.3.1",
|
|
53
53
|
"react": "^18.2.0",
|
|
54
|
-
"@deepseek-ai/dsh-api-
|
|
55
|
-
"@deepseek-ai/dsh-api-
|
|
56
|
-
"@deepseek-ai/dsh-api-
|
|
57
|
-
"@deepseek-ai/dsh-client-
|
|
58
|
-
"@deepseek-ai/dsh-client-
|
|
59
|
-
"@deepseek-ai/dsh-client-
|
|
60
|
-
"@deepseek-ai/dsh-client-
|
|
61
|
-
"@deepseek-ai/dsh-client-
|
|
62
|
-
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.
|
|
63
|
-
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.
|
|
64
|
-
"@deepseek-ai/dsh-client-ui-
|
|
65
|
-
"@deepseek-ai/dsh-client-ui-
|
|
66
|
-
"@deepseek-ai/dsh-client-ui-slots": "^0.1.
|
|
67
|
-
"@deepseek-ai/dsh-schedule": "^0.1.
|
|
68
|
-
"@deepseek-ai/dsh-typert-protocol": "^0.1.
|
|
69
|
-
"@deepseek-ai/dsh-session": "^0.1.
|
|
70
|
-
"@deepseek-ai/dsh-util-workspace-path": "^0.1.
|
|
54
|
+
"@deepseek-ai/dsh-api-session-controller": "^0.1.3-alpha.2",
|
|
55
|
+
"@deepseek-ai/dsh-api-workspace-controller": "^0.1.3-alpha.2",
|
|
56
|
+
"@deepseek-ai/dsh-api-remotes": "^0.1.3-alpha.2",
|
|
57
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.3-alpha.2",
|
|
58
|
+
"@deepseek-ai/dsh-client-store": "^0.1.3-alpha.2",
|
|
59
|
+
"@deepseek-ai/dsh-client-test-runtime": "^0.1.3-alpha.2",
|
|
60
|
+
"@deepseek-ai/dsh-client-connection": "^0.1.3-alpha.2",
|
|
61
|
+
"@deepseek-ai/dsh-client-ui-conversation": "^0.1.3-alpha.2",
|
|
62
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.3-alpha.2",
|
|
63
|
+
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.3-alpha.2",
|
|
64
|
+
"@deepseek-ai/dsh-client-ui-session": "^0.1.3-alpha.2",
|
|
65
|
+
"@deepseek-ai/dsh-client-ui-sidebar": "^0.1.3-alpha.2",
|
|
66
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.3-alpha.2",
|
|
67
|
+
"@deepseek-ai/dsh-schedule": "^0.1.3-alpha.2",
|
|
68
|
+
"@deepseek-ai/dsh-typert-protocol": "^0.1.3-alpha.2",
|
|
69
|
+
"@deepseek-ai/dsh-session": "^0.1.3-alpha.2",
|
|
70
|
+
"@deepseek-ai/dsh-util-workspace-path": "^0.1.3-alpha.2",
|
|
71
71
|
"@deepseek-ai/cordis": "^4.0.2"
|
|
72
72
|
},
|
|
73
73
|
"files": [
|