Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
DSH Desktop packages the local DeepSeek Harness web experience as a desktop application. It launches a local Harness instance automatically, manages a random loopback port, persists profiles, plugins, and sessions, and opens the full interface as soon as Harness is ready. Project workspaces are added and managed entirely in the Harness interface.

> [!IMPORTANT]
> DSH Desktop is currently an early preview and depends on the rapidly evolving `@deepseek-ai/dsh@0.1.0-rc.7`. macOS releases are code-signed and notarized by Apple; current installers are distributed through the official website.
> DSH Desktop is currently an early preview and depends on the rapidly evolving `@deepseek-ai/dsh@0.1.0-rc.8`. macOS releases are code-signed and notarized by Apple; current installers are distributed through the official website.

## Download

Expand Down Expand Up @@ -155,7 +155,7 @@ build/ Application icon assets

## Upstream version and patches

The project currently pins `@deepseek-ai/dsh@0.1.0-rc.7`. The initial provider list and desktop preset-transfer surface are captured with [`patch-package`](https://github.com/ds300/patch-package) under [`patches/`](patches/) rather than relying on untracked changes in `node_modules`.
The project currently pins `@deepseek-ai/dsh@0.1.0-rc.8`. The initial provider list and desktop preset-transfer surface are captured with [`patch-package`](https://github.com/ds300/patch-package) under [`patches/`](patches/) rather than relying on untracked changes in `node_modules`.

When upgrading DSH:

Expand Down
4 changes: 2 additions & 2 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
DSH Desktop 把 DeepSeek Harness 的本地 Web 体验封装为桌面应用:应用会自动启动本地 Harness、管理随机回环端口、持久化 Profile/插件/会话,并在 Harness 就绪后直接进入完整界面。项目工作区在 Harness 界面中统一添加和管理。

> [!IMPORTANT]
> DSH Desktop 当前处于早期预览阶段,并依赖仍在快速迭代的 `@deepseek-ai/dsh@0.1.0-rc.7`。macOS 正式包已完成代码签名并通过 Apple 公证,当前安装包统一通过官网分发。
> DSH Desktop 当前处于早期预览阶段,并依赖仍在快速迭代的 `@deepseek-ai/dsh@0.1.0-rc.8`。macOS 正式包已完成代码签名并通过 Apple 公证,当前安装包统一通过官网分发。

## 下载安装

Expand Down Expand Up @@ -155,7 +155,7 @@ build/ 应用图标资源

## 上游版本与补丁

项目当前固定依赖 `@deepseek-ai/dsh@0.1.0-rc.7`。首启 Provider 列表与桌面端 Preset 导入导出界面由 [`patch-package`](https://github.com/ds300/patch-package) 固化在 [`patches/`](patches/) 中,而不是依赖未跟踪的 `node_modules` 修改。
项目当前固定依赖 `@deepseek-ai/dsh@0.1.0-rc.8`。首启 Provider 列表与桌面端 Preset 导入导出界面由 [`patch-package`](https://github.com/ds300/patch-package) 固化在 [`patches/`](patches/) 中,而不是依赖未跟踪的 `node_modules` 修改。侧边栏品牌标识与手机配对入口改为填充 Harness 提供的 `sidebar.brand.*` 与 `sidebar.footer.action` 插槽,不再需要补丁

升级 DSH 时必须:

Expand Down
5,435 changes: 2,153 additions & 3,282 deletions package-lock.json

Large diffs are not rendered by default.

42 changes: 22 additions & 20 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,30 +41,32 @@
},
"dependencies": {
"@deepseek-ai/cordis-plugin-group": "1.0.1",
"@deepseek-ai/dsh": "0.1.0-rc.7",
"@deepseek-ai/dsh-anonymous-user-id": "0.1.0-rc.7",
"@deepseek-ai/dsh-atomic-write": "0.1.0-rc.7",
"@deepseek-ai/dsh-bash-local": "0.1.0-rc.7",
"@deepseek-ai/dsh-code-runtime": "0.1.0-rc.7",
"@deepseek-ai/dsh-compaction": "0.1.0-rc.7",
"@deepseek-ai/dsh-fs": "0.1.0-rc.7",
"@deepseek-ai/dsh-invariants": "0.1.0-rc.7",
"@deepseek-ai/dsh-output-retention": "0.1.0-rc.7",
"@deepseek-ai/dsh-sandbox": "0.1.0-rc.7",
"@deepseek-ai/dsh-scope": "0.1.0-rc.7",
"@deepseek-ai/dsh-session-telemetry": "0.1.0-rc.7",
"@deepseek-ai/dsh-session-title-llm": "0.1.0-rc.7",
"@deepseek-ai/dsh-shell": "0.1.0-rc.7",
"@deepseek-ai/dsh-spill": "0.1.0-rc.7",
"@deepseek-ai/dsh-subagent-in-process-driver": "0.1.0-rc.7",
"@deepseek-ai/dsh-subprocess": "0.1.0-rc.7",
"@deepseek-ai/dsh-timeout": "0.1.0-rc.7",
"@deepseek-ai/dsh-workflow": "0.1.0-rc.7",
"@deepseek-ai/dsh": "0.1.0-rc.8",
"@deepseek-ai/dsh-anonymous-user-id": "0.1.0-rc.8",
"@deepseek-ai/dsh-atomic-write": "0.1.0-rc.8",
"@deepseek-ai/dsh-bash-local": "0.1.0-rc.8",
"@deepseek-ai/dsh-code-runtime": "0.1.0-rc.8",
"@deepseek-ai/dsh-compaction": "0.1.0-rc.8",
"@deepseek-ai/dsh-fs": "0.1.0-rc.8",
"@deepseek-ai/dsh-invariants": "0.1.0-rc.8",
"@deepseek-ai/dsh-output-retention": "0.1.0-rc.8",
"@deepseek-ai/dsh-sandbox": "0.1.0-rc.8",
"@deepseek-ai/dsh-scope": "0.1.0-rc.8",
"@deepseek-ai/dsh-session-telemetry": "0.1.0-rc.8",
"@deepseek-ai/dsh-session-title-llm": "0.1.0-rc.8",
"@deepseek-ai/dsh-shell": "0.1.0-rc.8",
"@deepseek-ai/dsh-spill": "0.1.0-rc.8",
"@deepseek-ai/dsh-subagent-in-process-driver": "0.1.0-rc.8",
"@deepseek-ai/dsh-subprocess": "0.1.0-rc.8",
"@deepseek-ai/dsh-timeout": "0.1.0-rc.8",
"@deepseek-ai/dsh-workflow": "0.1.0-rc.8",
"dsh-desktop-market-installer": "file:packages/dsh-desktop-market-installer",
"electron-updater": "^6.8.9",
"node": "24.9.0",
"pnpm": "10.34.5",
"qrcode": "^1.5.4"
"qrcode": "^1.5.4",
"react": "18.3.1",
"react-dom": "18.3.1"
},
"devDependencies": {
"@types/node": "24.10.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
diff --git a/node_modules/@deepseek-ai/dsh/package.json b/node_modules/@deepseek-ai/dsh/package.json
index 881bb2a..adc3a2a 100644
--- a/node_modules/@deepseek-ai/dsh/package.json
+++ b/node_modules/@deepseek-ai/dsh/package.json
@@ -20,6 +20,7 @@
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
diff --git a/node_modules/@deepseek-ai/dsh-client-runtime/lib/client.js b/node_modules/@deepseek-ai/dsh-client-runtime/lib/client.js
index 37b931e..ed1f7fd 100644
index ba3cb21..5ad73ee 100644
--- a/node_modules/@deepseek-ai/dsh-client-runtime/lib/client.js
+++ b/node_modules/@deepseek-ai/dsh-client-runtime/lib/client.js
@@ -10448,6 +10448,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
@@ -10481,6 +10481,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
function displayFailureMessage(failure) {
if (failure === null || typeof failure !== "object") return String(failure);
const record = failure;
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
diff --git a/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/client.js b/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/client.js
index 1dd0e89..dd1c233 100644
index 4b7dd35..f9bf444 100644
--- a/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/client.js
+++ b/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/client.js
@@ -5233,6 +5233,15 @@ window.__ModuleLoader__.load({
"toBottom": "Md3f7G_toBottom",
"scroll": "Md3f7G_scroll"
@@ -5376,6 +5376,15 @@ window.__ModuleLoader__.load({
"turnStatus": "Md3f7G_turnStatus",
"turnStatusClock": "Md3f7G_turnStatusClock"
};
+ const queryRailCss = ".dshQueryRail_root{z-index:7;width:46px;pointer-events:none;position:fixed}.dshQueryRail_scroller{width:40px;height:100%;padding:8px 2px;overflow-x:hidden;overflow-y:auto;overscroll-behavior-y:contain;scrollbar-width:none;flex-direction:column;align-items:flex-start;gap:2px;display:flex;position:relative}.dshQueryRail_scroller::-webkit-scrollbar{width:0;height:0;display:none}.dshQueryRail_item{width:34px;height:12px;min-height:12px;cursor:pointer;background:transparent;border:0;outline:none;flex:none;padding:0;position:relative}.dshQueryRail_item:before{content:\"\";width:10px;height:1px;background:var(--dsw-alias-label-dimmed);border-radius:2px;transition:width .14s ease,background-color .14s ease,opacity .14s ease;display:block}.dshQueryRail_item:hover:before,.dshQueryRail_item:focus-visible:before{width:20px;background:var(--dsw-alias-label-secondary)}.dshQueryRail_itemActive:before{width:28px;height:2px;background:var(--dsw-alias-label-primary)}.dshQueryRail_tooltip{width:276px;max-width:min(276px,calc(100vw - 64px));color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-module-platform);border:1px solid var(--dsw-alias-border-l2);box-shadow:var(--dsw-shadow-lv2);pointer-events:none;border-radius:12px;padding:10px 12px;position:absolute;left:42px}.dshQueryRail_tooltipLabel{color:var(--dsw-alias-label-caption);text-transform:uppercase;letter-spacing:.06em;margin-bottom:4px;font-size:11px;line-height:16px}.dshQueryRail_tooltipText{-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;font-size:13px;line-height:19px;display:-webkit-box}@media(max-width:980px){.dshQueryRail_root{display:none}}@media(prefers-reduced-motion:reduce){.dshQueryRail_item:before{transition:none}}";
+ const queryRailTagId = "@deepseek-ai/dsh-client-ui-conversation/QueryRail.css";
Expand All @@ -18,7 +18,7 @@ index 1dd0e89..dd1c233 100644
//#endregion
//#region lib/types/client/chat/ChatNodeSeat.js
/** Subscribe and dispatch one stable Context key without observing sibling Nodes. */
@@ -5289,6 +5298,21 @@ window.__ModuleLoader__.load({
@@ -5432,6 +5441,21 @@ window.__ModuleLoader__.load({
for (const row of list.querySelectorAll("[data-chat-anchor-key]")) if (row.dataset.chatAnchorKey === key) return row;
return null;
}
Expand All @@ -40,7 +40,7 @@ index 1dd0e89..dd1c233 100644
/** Row position in scrollport coordinates (viewport-independent). */
function flowTop(row, scrollport) {
return row.getBoundingClientRect().top - scrollport.getBoundingClientRect().top;
@@ -5364,6 +5388,106 @@ window.__ModuleLoader__.load({
@@ -5516,6 +5540,106 @@ window.__ModuleLoader__.load({
})]
});
}
Expand Down Expand Up @@ -147,10 +147,10 @@ index 1dd0e89..dd1c233 100644
/**
* The chat view slot entry: pure component over the composed props; each
* ordered business Node crosses the keyed renderer seat.
@@ -5381,11 +5505,25 @@ window.__ModuleLoader__.load({
const loadingOlder = useSession((s) => s.loadingOlder);
const selectedCallId = useStore((s) => s.selection?.callId);
const pendingSteering = (0, react.useMemo)(() => inbox.filter((item) => item.placement === "steering"), [inbox]);
@@ -5561,11 +5685,28 @@ window.__ModuleLoader__.load({
...owner,
loadImage
}), [loadImage, renderSlot]);
+ const queries = (0, react.useMemo)(() => order.flatMap((key) => {
+ const node = nodeStore.get(key);
+ if (node?.kind !== "user" && node?.kind !== "steering") return [];
Expand All @@ -161,7 +161,10 @@ index 1dd0e89..dd1c233 100644
+ };
+ const text = content.text.replace(/\s+/g, " ").trim();
+ const preview = (text || (content.images.length > 0 ? document.documentElement.lang.startsWith("zh") ? "图片 Query" : "Image query" : document.documentElement.lang.startsWith("zh") ? "无文本 Query" : "Query without text")).slice(0, 240);
+ return [{ key, preview }];
+ return [{
+ key,
+ preview
+ }];
+ }), [order, nodeStore]);
const runningTurnStart = (0, react.useMemo)(() => runningTurnStartTime(timeline), [timeline]);
const listRef = (0, react.useRef)(null);
Expand All @@ -173,7 +176,7 @@ index 1dd0e89..dd1c233 100644
/** Last position delivered or written on the main thread. */
const observedTopRef = (0, react.useRef)(0);
/** Paging anchor: semantic row/position at click, updated by reader scrolls
@@ -5405,6 +5543,12 @@ window.__ModuleLoader__.load({
@@ -5585,6 +5726,12 @@ window.__ModuleLoader__.load({
const lastNode = lastKey === null ? void 0 : nodeStore.get(lastKey);
const lastSteeringId = pendingSteering[pendingSteering.length - 1]?.id ?? null;
const followSig = `${openState}:${firstSeq}:${lastKey}:${order.length}:${running ? 1 : 0}:${lastSteeringId ?? ""}`;
Expand All @@ -186,7 +189,7 @@ index 1dd0e89..dd1c233 100644
const toBottom = (el) => {
anchorRef.current = null;
el.scrollTop = el.scrollHeight;
@@ -5412,6 +5556,8 @@ window.__ModuleLoader__.load({
@@ -5592,6 +5739,8 @@ window.__ModuleLoader__.load({
atBottomRef.current = true;
setAtBottom(true);
chatScroll.save(null);
Expand All @@ -195,15 +198,15 @@ index 1dd0e89..dd1c233 100644
};
(0, react.useLayoutEffect)(() => {
const local = listRef.current;
@@ -5468,6 +5614,7 @@ window.__ModuleLoader__.load({
@@ -5648,6 +5797,7 @@ window.__ModuleLoader__.load({
/* v8 ignore next -- ref-null guard: the handler only fires while mounted. */
if (local === null) return;
const el = scrollerOf(local);
+ syncActiveQuery(local, el);
const floor = Math.max(0, el.scrollHeight - el.clientHeight);
const movedByReader = Math.abs(el.scrollTop - Math.min(observedTopRef.current, floor)) > .5;
const isAtBottom = movedByReader ? floor - el.scrollTop <= 25 : atBottomRef.current;
@@ -5487,6 +5634,10 @@ window.__ModuleLoader__.load({
@@ -5667,6 +5817,10 @@ window.__ModuleLoader__.load({
else if (position !== null) chatScroll.save(position);
observedTopRef.current = el.scrollTop;
};
Expand All @@ -214,7 +217,7 @@ index 1dd0e89..dd1c233 100644
(0, react.useEffect)(() => {
const local = listRef.current;
/* v8 ignore next -- ref-null guard: effect runs after the list node commits. */
@@ -5540,9 +5691,29 @@ window.__ModuleLoader__.load({
@@ -5720,9 +5874,29 @@ window.__ModuleLoader__.load({
}
loadOlder();
};
Expand All @@ -232,9 +235,9 @@ index 1dd0e89..dd1c233 100644
+ activeQueryKeyRef.current = key;
+ setActiveQueryKey(key);
+ };
return (0, react_jsx_runtime.jsx)("div", {
return (0, react_jsx_runtime.jsxs)("div", {
className: ChatView_module_css_default.root,
- children: (0, react_jsx_runtime.jsxs)("div", {
- children: [(0, react_jsx_runtime.jsxs)("div", {
+ children: [(0, react_jsx_runtime.jsx)(QueryRail, {
+ queries,
+ activeKey: activeQueryKey,
Expand All @@ -245,12 +248,3 @@ index 1dd0e89..dd1c233 100644
ref: listRef,
className: ChatView_module_css_default.scroll,
children: [(0, react_jsx_runtime.jsxs)("div", {
@@ -5607,7 +5778,7 @@ window.__ModuleLoader__.load({
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, {})
})
})]
- })
+ })]
});
}
//#endregion
Loading
Loading