dsh-deepseek-chat 0.1.11 → 0.1.12

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 CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  CHAT模式 加载真实的 [DeepSeek Chat 官网](https://chat.deepseek.com/),使用官网的聊天功能和账号历史;HARNESS模式 为原 DSH 工作区。
6
6
 
7
- 当前版本 **0.1.11** · 适配 **DSH 0.2.0-rc.2 桌面版** · 默认语言为简体中文。
7
+ 当前版本 **0.1.12** · 适配 **DSH 0.2.0-rc.2 桌面版** · 默认语言为简体中文。
8
8
 
9
9
  ## 功能预览
10
10
 
@@ -13,7 +13,8 @@ CHAT模式 加载真实的 [DeepSeek Chat 官网](https://chat.deepseek.com/),
13
13
  ![CHAT 模式:DSH 原侧栏与 DeepSeek 官网聊天页面](docs/images/chat-overview.png)
14
14
 
15
15
  - 共用 DSH 原侧栏,显示官网对话标题、置顶和日期分组。
16
- - 点击历史对话继续聊天;顶部“新会话”和列表旁的+用于新建官网对话。
16
+ - 点击历史对话继续聊天;顶部“新会话”用于新建官网对话。
17
+ - 点击“对话”右侧的刷新图标,重新加载官网当前页面并更新列表。在其他网页端新建对话后,可用它同步,无需退出 DSH。
17
18
  - 搜索筛选已加载的对话标题,聊天正文和输入框由官网提供。
18
19
  - 对话标题位于左上角,点击标题使用官网原有的名称编辑功能。
19
20
 
@@ -76,7 +77,7 @@ dsh plugin --profile desktop add https://github.com/xingxingbk-git/dsh-deepseek-
76
77
  将构建生成的 `.tgz` 文件交给 DSH 官方插件管理器安装,或使用 CLI:
77
78
 
78
79
  ```bash
79
- dsh plugin --profile desktop add /absolute/path/dsh-deepseek-chat-0.1.11.tgz
80
+ dsh plugin --profile desktop add /absolute/path/dsh-deepseek-chat-0.1.12.tgz
80
81
  ```
81
82
 
82
83
  将路径替换成你的实际安装包;使用其他 profile 时替换 `desktop`。**安装或更新后,完整退出并重新打开 DSH**,让新插件生效。
@@ -95,6 +96,8 @@ dsh plugin --profile desktop add /absolute/path/dsh-deepseek-chat-0.1.11.tgz
95
96
 
96
97
  页面加载失败时,可在故障提示中重试;登录保存服务连接失败时,会显示原因和重试入口。插件会自动收起官网固定的“使用环境异常”说明,其他提示、验证码和认证错误仍由官网处理。
97
98
 
99
+ 刷新列表会重新加载当前官网页面,并保留当前对话地址。检测到未发送的输入或正在生成等状态时,会提示先完成当前操作;插件不会保存草稿。刷新中请稍候;官网加载失败或超时后,可点击右侧提示中的“重试网页”。
100
+
98
101
  ## 使用限制
99
102
 
100
103
  - **兼容范围:**目前针对 DSH 0.2.0-rc.2 桌面版适配,其他版本和平台待验证;DSH Web版暂不支持本插件的 CHAT 模式。
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "format": 1,
3
3
  "name": "dsh-deepseek-chat",
4
- "version": "0.1.11",
4
+ "version": "0.1.12",
5
5
  "inputs": {
6
6
  "assets/icon.svg": "ad1b0fda90c1c1f2a0b9208bc86f5fe8c21d505a1208576be4e3110b26b4f79c",
7
7
  "cordis.patch.yml": "05edb71cd276de1251ae67644ec68b54efc26258814956fa0e932d36da741bdc",
8
- "package.json": "a89d7b4f4b2dd1a2068e1e716644af0ae96df7a1d6a63e6676fa0a8b63d2e279",
8
+ "package.json": "c71ffe743031d1d35b55ea474eb4bec84394b89ba1b0edbc94be90ed095f63d9",
9
9
  "pnpm-lock.yaml": "c4f600b0d599b85f6181d295cd5f9f06f1eb0435eeeb2e7cf1a376b3c6a4ca15",
10
10
  "scripts/build.mjs": "a9a2961e09fb16b99e206c4d191c9e970a4a3999979df9a626fa310c0fdee5b1",
11
11
  "scripts/check-artifact.mjs": "6fec38fb74e41dfeacef7147280c69854087d0665747d7d65137cc98f9dc673b",
@@ -13,17 +13,17 @@
13
13
  "scripts/client-contract.mjs": "1e212575218fc985f4405e2eac98b33a969494ff6b2144b1204a6d66963ba894",
14
14
  "scripts/distribution-manifest.mjs": "e746c447b03b0e9a86efce7827bbd5d9184c6ccd1f1f0f1c9eb12abfe1b2f3b7",
15
15
  "src/authorization.ts": "5f0c1b69e43541ce606349047788df72e442e9cbb3267c8c0caf2c0f556a5589",
16
- "src/client.ts": "6800337488d5f811dd29c226f3122719469ae9412418e54cc9e2b7cd5e16a2d2",
16
+ "src/client.ts": "a8e4a06fc487e98f61285bcd6e9a8dcb8bad00a6f1a74806a176a839c5f0dec1",
17
17
  "src/core/mode.ts": "2fe56c319706d86746010bd5551f4ee47e31e12a0ee28effffb719b0696ad70c",
18
18
  "src/index.ts": "59edf0d6af2feec3e08da322cabc07a2dc83868312c4daa1074b2a5b12892f57",
19
19
  "src/protocol.ts": "5194007a0c06f7b293cc34579ccdc150c23c35b825091667f37a7293594bd29f",
20
20
  "src/server.ts": "295c52235fa399967a594b76b1f4c869adccc978ee3c0f3f8f3a12894b81ef9b",
21
21
  "src/sidebar-adapter.ts": "edcc051bbcaabb2d09055b231f57253a50a6d9e75acf18adafbf262001b18a48",
22
- "src/styles.ts": "f3088f1142cf2b9521f14dc73ee9e33f079bfe48230c58787dbf0a3c81014700",
23
- "src/ui.tsx": "cc35c70c0aa003012aee067470fd380928e87baaa8bb72e4255b96c17998f64a",
24
- "src/web-surface.tsx": "3e2487fa6d99762d59e7f94ac738384c811c1a3b0cfeb4e35a8230aba81a5468",
22
+ "src/styles.ts": "289b012ece94ac6eabad905606cfda06a8bd79073f5cc24938ae6e5bd973aa6d",
23
+ "src/ui.tsx": "abe6d31dcac461c42aee7b5632e2354977ae497a932b63451fd66f370d0dd975",
24
+ "src/web-surface.tsx": "51862e3c0cff10a9ae44f757a9e879af9d9a31d2aca1d8715d6f848700637551",
25
25
  "src/website-header.ts": "ac4972a28a5f0968de4d5f98d54fbac853f901c7eda00c0849984a2e66f291f3",
26
- "src/website-navigation.ts": "743a6599af09c200b9bbe16dcdc10adf5007374b9982036f5b9e602f36b620c7",
26
+ "src/website-navigation.ts": "fbbefeb0cd95665021a525c7b067d55b547fc24eeb6c03e84e42cf345a1da6d0",
27
27
  "src/website-notice.ts": "65c781bec41e6c2e541d9512cc0051864d64fc3204b3ba5f2e005bdc955f39c9",
28
28
  "src/website-session-store.ts": "8ef6d49465e0034f12b763a666b4a90c8c9819fb8baea06dcaba340fd97d72f1",
29
29
  "src/website-session.ts": "f2434fafc40adb15b5f16fc8b6152bd8df7e85f5210330a1337502c9a08136d8",
@@ -31,7 +31,7 @@
31
31
  "tsconfig.json": "1ad0b3b39537564a180dc7f4084ceb3098b567f509320c77d71bc37aaf4f1879"
32
32
  },
33
33
  "artifacts": {
34
- "lib/client.js": "00c9df0385a2b53eb7aa16f2d2ebd167710f533346ceb8beab096ebe63cf88d4",
34
+ "lib/client.js": "46a6041d6c144746b485d03809ea1aff6f6a6c5591b314f76309b500df4d3e72",
35
35
  "lib/index.js": "e9c50cc544f24c60d086538ab1283ae0ed2811f23c9bb469916a2e89c3ffb38d",
36
36
  "lib/types/authorization.d.ts": "130649eed3635e75c3f50c13de93c52440a27f1b88136ab2297552570c013d49",
37
37
  "lib/types/client.d.ts": "a79702d5d86c75e81f1e954b3e9f4a562a6b3082d68d798d6a1b37bd41b908a7",
@@ -41,10 +41,10 @@
41
41
  "lib/types/server.d.ts": "62b23f8f9fe9bb16a20274929876c1a34b3ab1e94179567e2e3a56cd67638288",
42
42
  "lib/types/sidebar-adapter.d.ts": "9296987e7ecbd76e42d75bbf65d06f3e368dc036501baf931d7eaa9fb923252d",
43
43
  "lib/types/styles.d.ts": "305836b3ce5cb256ffb033038b7df2919759976f3ca29395a7cd41bbd5811536",
44
- "lib/types/ui.d.ts": "5e42f24c522d2bef8758279167a289e0205b30e40e7504ed9bc4e4f527c08c42",
44
+ "lib/types/ui.d.ts": "c1239e1382356c169ef34074240a19109a2839a2608e018ec436d1d716fe494b",
45
45
  "lib/types/web-surface.d.ts": "71686d72b4a5d6c619ee4ec916bbf7b853a87a7cc4d506fbfd0359191434984f",
46
46
  "lib/types/website-header.d.ts": "6379a35e7d35af3fb969802ee2cae969a104dbad937f7b9e371463a0bd7dea9d",
47
- "lib/types/website-navigation.d.ts": "6ffd226ded2fc9971bf982e41ee8d8b15d89d113943bbd7cea18f9d4c1ccc973",
47
+ "lib/types/website-navigation.d.ts": "822e80968c1a704cd2a341d53ee38a483f0a407a0e23d2dd883fd25d0925186d",
48
48
  "lib/types/website-notice.d.ts": "2912746645e3e9facfe167c7b2b2eff584e3b812cab5e106afc7cb2b0259fc15",
49
49
  "lib/types/website-session-store.d.ts": "bd641ab5e62ea4dd5f5cbfa823548a5c266c9701bca986fb348482ee69b2e0c0",
50
50
  "lib/types/website-session.d.ts": "5ded232b24dd72e7b3c5f0ff505ba0aa818cbde14be7e2099bbbf262ec395a2b",
package/lib/client.js CHANGED
@@ -14777,6 +14777,7 @@ window.__ModuleLoader__.load({
14777
14777
  .dsh-chat-navigation-header{display:flex;align-items:center;justify-content:space-between;padding:0 14px 8px 16px;min-height:36px;color:var(--dsw-alias-label-secondary,#8b8d91);font-size:14px}
14778
14778
  .dsh-chat-navigation-header>div{display:flex;gap:2px}
14779
14779
  .dsh-chat-icon-button{display:inline-flex;align-items:center;justify-content:center;flex:none;width:28px;height:28px;border:0;border-radius:6px;background:transparent;color:var(--dsw-alias-label-secondary,#8b8d91);cursor:pointer;font-size:21px!important}.dsh-chat-icon-button:hover{background:var(--dsw-alias-interactive-bg-hover,#ffffff0d)}.dsh-chat-icon-button:disabled{opacity:.4;cursor:default}
14780
+ .dsh-chat-refreshing{animation:dsh-chat-refresh-spin .8s linear infinite}@keyframes dsh-chat-refresh-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.dsh-chat-refreshing{animation:none}}
14780
14781
  .dsh-chat-navigation-search{margin:0 14px 8px;padding:7px 9px;min-width:0;border:1px solid var(--dsw-alias-border-l2,#85858b40);border-radius:6px;background:transparent;color:inherit;font:inherit;font-size:12px}
14781
14782
  .dsh-chat-navigation-list{flex:1;min-height:0;overflow:auto;padding:0 12px 12px;scrollbar-width:thin}
14782
14783
  .dsh-chat-conversation-group h3{font-size:12px;font-weight:400;color:var(--dsw-alias-label-secondary,#8b8d91);margin:15px 4px 6px}
@@ -14886,7 +14887,7 @@ window.__ModuleLoader__.load({
14886
14887
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DshChatStyles, {}),
14887
14888
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DshChatModeSelector, { bridge, state }),
14888
14889
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DshChatAuthorizationNotice, { bridge, state }),
14889
- state.sidebarAdapted === false && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-chat-authorization-notice", role: "alert", children: "\u5F53\u524D\u4FA7\u680F\u4E0D\u517C\u5BB9\uFF1A\u9876\u90E8\u65B0\u4F1A\u8BDD\u4ECD\u4F7F\u7528 HARNESS\u3002CHAT \u8BF7\u4F7F\u7528\u5BF9\u8BDD\u5217\u8868\u65C1\u7684\uFF0B\u3002" })
14890
+ state.sidebarAdapted === false && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-chat-authorization-notice", role: "alert", children: "\u5F53\u524D\u4FA7\u680F\u4E0D\u517C\u5BB9\uFF1A\u9876\u90E8\u65B0\u4F1A\u8BDD\u4ECD\u4F7F\u7528 HARNESS\u3002CHAT \u8BF7\u5C55\u5F00\u5B98\u7F51\u5BFC\u822A\u540E\u65B0\u5EFA\u5BF9\u8BDD\u3002" })
14890
14891
  ] });
14891
14892
  }
14892
14893
  function DshChatChatNavigation({ bridge, wide, expandSidebar }) {
@@ -14894,6 +14895,8 @@ window.__ModuleLoader__.load({
14894
14895
  const [query, setQuery] = (0, import_react.useState)("");
14895
14896
  const [searching, setSearching] = (0, import_react.useState)(false);
14896
14897
  const navigation = state.websiteNavigation;
14898
+ const refreshing = state.websiteNavigationRefreshing;
14899
+ const refreshDisabled = !state.modeEnabled || !state.desktopAvailable || refreshing || state.webLoading || navigation.authenticated !== true || ["signing-in", "signing-out"].includes(state.websiteAuthenticationStatus) || navigation.settings?.pending;
14897
14900
  const groups = /* @__PURE__ */ new Map();
14898
14901
  for (const item of navigation.conversations) {
14899
14902
  if (!item.title.toLocaleLowerCase().includes(query.toLocaleLowerCase())) continue;
@@ -14911,11 +14914,12 @@ window.__ModuleLoader__.load({
14911
14914
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "8.5", cy: "8.5", r: "6", stroke: "currentColor", strokeWidth: "1.4" }),
14912
14915
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m13 13 4 4", stroke: "currentColor", strokeWidth: "1.4" })
14913
14916
  ] }) }),
14914
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "dsh-chat-icon-button", "aria-label": "\u65B0\u5EFA\u5B98\u7F51\u5BF9\u8BDD", disabled: !navigation.canCreate, onClick: () => bridge.commandWebsite({ type: "new" }), children: "\uFF0B" })
14917
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Tooltip, { label: refreshing ? "\u6B63\u5728\u5237\u65B0\u5B98\u7F51\u5BF9\u8BDD\u5217\u8868\u2026" : "\u5237\u65B0\u5B98\u7F51\u5BF9\u8BDD\u5217\u8868", delayMs: 500, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "dsh-chat-icon-button", "aria-label": "\u5237\u65B0\u5B98\u7F51\u5BF9\u8BDD\u5217\u8868", "aria-busy": refreshing, disabled: refreshDisabled, onClick: () => bridge.refreshWebsiteNavigation(), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconRefreshOutlineRegular, { size: 14, className: refreshing ? "dsh-chat-refreshing" : void 0 }) }) })
14915
14918
  ] })
14916
14919
  ] }),
14917
14920
  searching && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { className: "dsh-chat-navigation-search", "aria-label": "\u641C\u7D22\u5DF2\u52A0\u8F7D\u7684\u5B98\u7F51\u5BF9\u8BDD\u6807\u9898", placeholder: "\u641C\u7D22\u5BF9\u8BDD", value: query, onChange: (event) => setQuery(event.target.value), autoFocus: true }),
14918
14921
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-chat-navigation-list", children: [
14922
+ refreshing && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dsh-chat-navigation-status", role: "status", children: "\u6B63\u5728\u5237\u65B0\u5B98\u7F51\u5BF9\u8BDD\u5217\u8868\u2026" }),
14919
14923
  navigation.authenticated === true && navigation.status === "ready" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
14920
14924
  [...groups].map(([label, rows]) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "dsh-chat-conversation-group", "aria-label": label, children: [
14921
14925
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: label }),
@@ -14924,7 +14928,8 @@ window.__ModuleLoader__.load({
14924
14928
  groups.size === 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dsh-chat-navigation-status", children: query ? "\u6CA1\u6709\u5339\u914D\u7684\u5BF9\u8BDD" : "\u6682\u65E0\u5BF9\u8BDD" }),
14925
14929
  !query && navigation.conversations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "dsh-chat-text-button", onClick: () => bridge.commandWebsite({ type: "more" }), children: "\u52A0\u8F7D\u66F4\u65E9\u7684\u5BF9\u8BDD" })
14926
14930
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dsh-chat-navigation-status", role: "status", children: navigation.status === "sign-in" ? "CHAT \u5C1A\u672A\u767B\u5F55\u3002\u8BF7\u5728\u53F3\u4FA7\u70B9\u51FB\u767B\u5F55 DeepSeek\uFF0C\u5B8C\u6210\u540E\u81EA\u52A8\u663E\u793A\u5B98\u7F51\u5BF9\u8BDD\u3002" : navigation.status === "unsupported" ? "\u6682\u672A\u8BC6\u522B\u5B98\u7F51\u5217\u8868\uFF0C\u8BF7\u4F7F\u7528\u53F3\u4FA7\u5B98\u7F51\u5BFC\u822A\u3002" : "\u6B63\u5728\u52A0\u8F7D\u5B98\u7F51\u5BF9\u8BDD\u2026" }),
14927
- navigation.error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dsh-chat-navigation-status", role: "alert", children: navigation.error })
14931
+ navigation.error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dsh-chat-navigation-status", role: "alert", children: navigation.error }),
14932
+ state.websiteNavigationRefreshError && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dsh-chat-navigation-status", role: "alert", children: state.websiteNavigationRefreshError })
14928
14933
  ] })
14929
14934
  ] })
14930
14935
  ] });
@@ -15763,6 +15768,7 @@ window.__ModuleLoader__.load({
15763
15768
  return { status: ready ? "ready" : "loading", ...authenticated === void 0 ? {} : { authenticated }, conversations, selectedHref: safeHref(page.pathname), canCreate: newChat !== null, error: null, accountName, settings };
15764
15769
  }
15765
15770
  function websiteCommandScript(command) {
15771
+ if (command.type === "refresh") throw new Error("Website refresh must be handled by the guest owner");
15766
15772
  return `(() => { const adaptWebsiteSettings = ${adaptWebsiteSettings.toString()}; const adaptWebsiteHeader = ${adaptWebsiteHeader.toString()}; const dismissWebsiteEnvironmentNotice = ${dismissWebsiteEnvironmentNotice.toString()}; return (${adaptWebsiteNavigation.toString()})(document,location,${JSON.stringify(command)}); })()`;
15767
15773
  }
15768
15774
  function parseWebsiteNavigation(value) {
@@ -15888,6 +15894,30 @@ window.__ModuleLoader__.load({
15888
15894
  // src/web-surface.tsx
15889
15895
  var import_jsx_runtime2 = require("react/jsx-runtime");
15890
15896
  var WEBSITE_URL = "https://chat.deepseek.com/";
15897
+ function websiteRefreshReadiness(doc, origin) {
15898
+ if (origin !== "https://chat.deepseek.com") return "unavailable";
15899
+ const visible = (node) => {
15900
+ const rect = node.getBoundingClientRect();
15901
+ const style = doc.defaultView?.getComputedStyle(node);
15902
+ return rect.width > 0 && rect.height > 0 && style?.display !== "none" && style?.visibility !== "hidden";
15903
+ };
15904
+ for (const field of doc.querySelectorAll('textarea,input[type="text"],input:not([type]),[contenteditable="true"]')) {
15905
+ if (!visible(field)) continue;
15906
+ if (field instanceof HTMLTextAreaElement || field instanceof HTMLInputElement) {
15907
+ if (field.value.trim().length > 0) return "draft";
15908
+ if (field.disabled || field.readOnly) return "busy";
15909
+ } else if ((field.textContent ?? "").trim().length > 0) return "draft";
15910
+ }
15911
+ for (const field of doc.querySelectorAll('input[type="file"]')) {
15912
+ if (field.files?.length) return "draft";
15913
+ }
15914
+ const stopping = /^(停止|停止生成|停止回答|停止响应|取消生成|Stop|Stop generating|Stop generation|Stop response|Cancel generation)$/i;
15915
+ for (const button of doc.querySelectorAll('button,[role="button"]')) {
15916
+ if (visible(button) && [button.getAttribute("aria-label"), button.getAttribute("title"), button.textContent?.trim()].some((label) => label && stopping.test(label))) return "busy";
15917
+ }
15918
+ if ([...doc.querySelectorAll('[aria-busy="true"]')].some(visible)) return "busy";
15919
+ return "ready";
15920
+ }
15891
15921
  function headerInset(viewport) {
15892
15922
  return viewport?.left === 0 ? Math.max(24, Math.ceil(document.querySelector(".dsh-chat-leading")?.getBoundingClientRect().right ?? 144) + 16) : 24;
15893
15923
  }
@@ -15969,10 +15999,21 @@ window.__ModuleLoader__.load({
15969
15999
  let websiteHadSession = false;
15970
16000
  let savedSessionFingerprint = null;
15971
16001
  let pendingSessionCapture = null;
16002
+ let navigationRefresh = null;
16003
+ let navigationRefreshTimer;
16004
+ const refreshTimeoutMessage = "\u5B98\u7F51\u52A0\u8F7D\u8D85\u65F6\uFF0C\u8BF7\u70B9\u51FB\u300C\u91CD\u8BD5\u7F51\u9875\u300D\u3002";
15972
16005
  let fastPollingUntil = Date.now() + 8e3;
15973
16006
  let lastPolled = 0;
15974
16007
  let lastNavigationStatus = null;
16008
+ const finishNavigationRefresh = (error51, request = navigationRefresh) => {
16009
+ if (!request || navigationRefresh !== request) return;
16010
+ navigationRefresh = null;
16011
+ clearTimeout(navigationRefreshTimer);
16012
+ navigationRefreshTimer = void 0;
16013
+ bridge.reportWebsiteNavigationRefresh(generation, { requestId: request.requestId, refreshing: false, error: error51 });
16014
+ };
15975
16015
  retryGuestSession.current = () => {
16016
+ finishNavigationRefresh(null);
15976
16017
  restorationAttempted = false;
15977
16018
  restoredFromVault = false;
15978
16019
  restoreDeadline = 0;
@@ -15981,6 +16022,7 @@ window.__ModuleLoader__.load({
15981
16022
  if (loading) lastError = null;
15982
16023
  else if (error51 !== null) lastError = error51;
15983
16024
  if (!events.signal.aborted) bridge.reportWebsiteState(generation, { loading, error: lastError });
16025
+ if (error51) finishNavigationRefresh("\u5B98\u7F51\u5BF9\u8BDD\u5217\u8868\u5237\u65B0\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u540E\u91CD\u8BD5\u3002");
15984
16026
  };
15985
16027
  const resetDocumentPresentation = () => {
15986
16028
  documentRevision++;
@@ -16086,6 +16128,14 @@ window.__ModuleLoader__.load({
16086
16128
  if (result.status !== "loading") documentPresented = true;
16087
16129
  bridge.reportWebsiteNavigation(generation, result);
16088
16130
  if (result.status !== "loading" || !documentPresented) setPresentationReady(result.status !== "loading");
16131
+ if (result.status === "ready" && result.authenticated === true && lastError === refreshTimeoutMessage) {
16132
+ lastError = null;
16133
+ report(false);
16134
+ }
16135
+ if (navigationRefresh && requestDocumentRevision > navigationRefresh.documentRevision) {
16136
+ if (result.status === "ready" && result.authenticated === true) finishNavigationRefresh(null);
16137
+ else if (result.status === "sign-in") finishNavigationRefresh("\u5B98\u7F51\u767B\u5F55\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55\u540E\u5237\u65B0\u5217\u8868\u3002");
16138
+ }
16089
16139
  }
16090
16140
  if (result.authenticated === true) {
16091
16141
  websiteHadSession = true;
@@ -16125,7 +16175,45 @@ window.__ModuleLoader__.load({
16125
16175
  };
16126
16176
  const stopCommands = bridge.bindWebsiteNavigation(generation, (command) => {
16127
16177
  if (command.type !== "snapshot") fastPollingUntil = Date.now() + 8e3;
16128
- queued = queued.then(() => adapt(command)).then(() => adapt(snapshotCommand()));
16178
+ if (command.type === "refresh") {
16179
+ queued = queued.then(async () => {
16180
+ clearTimeout(navigationRefreshTimer);
16181
+ navigationRefreshTimer = void 0;
16182
+ const refreshRequest = { requestId: command.requestId, authenticationRevision: command.authenticationRevision, documentRevision };
16183
+ navigationRefresh = refreshRequest;
16184
+ const sameRequest = () => navigationRefresh === refreshRequest && active() && bridge.getSnapshot().websiteAuthenticationRevision === command.authenticationRevision;
16185
+ if (!sameRequest() || !approvedOrigin()) {
16186
+ finishNavigationRefresh("\u5B98\u7F51\u9875\u9762\u72B6\u6001\u5DF2\u53D8\u5316\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u5237\u65B0\u3002", refreshRequest);
16187
+ return;
16188
+ }
16189
+ try {
16190
+ const readiness = await executeScript(`(${websiteRefreshReadiness.toString()})(document,location.origin)`);
16191
+ if (!sameRequest() || documentRevision !== refreshRequest.documentRevision) {
16192
+ finishNavigationRefresh("\u5B98\u7F51\u9875\u9762\u72B6\u6001\u5DF2\u53D8\u5316\uFF0C\u8BF7\u7A0D\u540E\u5237\u65B0\u3002", refreshRequest);
16193
+ return;
16194
+ }
16195
+ if (readiness !== "ready") {
16196
+ finishNavigationRefresh(readiness === "draft" ? "\u8BF7\u5148\u53D1\u9001\u6216\u6E05\u7A7A\u672A\u53D1\u9001\u5185\u5BB9\uFF0C\u518D\u5237\u65B0\u5BF9\u8BDD\u5217\u8868\u3002" : readiness === "busy" ? "\u8BF7\u7B49\u5F53\u524D\u56DE\u590D\u6216\u7F51\u9875\u64CD\u4F5C\u5B8C\u6210\uFF0C\u518D\u5237\u65B0\u5BF9\u8BDD\u5217\u8868\u3002" : "\u5F53\u524D\u5B98\u7F51\u9875\u9762\u6682\u65F6\u65E0\u6CD5\u5237\u65B0\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002", refreshRequest);
16197
+ return;
16198
+ }
16199
+ navigationRefreshTimer = setTimeout(() => {
16200
+ if (navigationRefresh !== refreshRequest) return;
16201
+ if (!sameRequest()) {
16202
+ finishNavigationRefresh("\u5B98\u7F51\u767B\u5F55\u72B6\u6001\u5DF2\u53D8\u5316\uFF0C\u8BF7\u7A0D\u540E\u5237\u65B0\u3002", refreshRequest);
16203
+ return;
16204
+ }
16205
+ finishNavigationRefresh("\u5B98\u7F51\u5BF9\u8BDD\u5217\u8868\u5237\u65B0\u8D85\u65F6\uFF0C\u8BF7\u70B9\u51FB\u53F3\u4FA7\u300C\u91CD\u8BD5\u7F51\u9875\u300D\u3002", refreshRequest);
16206
+ report(false, refreshTimeoutMessage);
16207
+ }, 3e4);
16208
+ report(true);
16209
+ current.reload();
16210
+ } catch {
16211
+ if (!sameRequest()) return;
16212
+ report(false);
16213
+ finishNavigationRefresh("\u65E0\u6CD5\u5237\u65B0\u5B98\u7F51\u5BF9\u8BDD\u5217\u8868\uFF0C\u8BF7\u91CD\u8BD5\u3002", refreshRequest);
16214
+ }
16215
+ });
16216
+ } else queued = queued.then(() => adapt(command)).then(() => adapt(snapshotCommand()));
16129
16217
  return queued;
16130
16218
  });
16131
16219
  const timer = setInterval(() => {
@@ -16133,6 +16221,7 @@ window.__ModuleLoader__.load({
16133
16221
  }, 200);
16134
16222
  events.signal.addEventListener("abort", () => {
16135
16223
  clearInterval(timer);
16224
+ finishNavigationRefresh("\u7F51\u9875\u5DF2\u5173\u95ED\uFF0C\u5237\u65B0\u672A\u5B8C\u6210\u3002");
16136
16225
  stopCommands();
16137
16226
  }, { once: true });
16138
16227
  const navigate = (url2) => {
@@ -16377,6 +16466,9 @@ window.__ModuleLoader__.load({
16377
16466
  let refreshing = null;
16378
16467
  let authorizationGeneration = 0;
16379
16468
  let websiteReloadRevision = 0;
16469
+ let websiteNavigationRefreshing = false;
16470
+ let websiteNavigationRefreshError = null;
16471
+ let websiteNavigationRefreshRequest = 0;
16380
16472
  let webLoading = false;
16381
16473
  let webError = null;
16382
16474
  let connectionError = null;
@@ -16429,6 +16521,7 @@ window.__ModuleLoader__.load({
16429
16521
  },
16430
16522
  cancelAccount: () => {
16431
16523
  authorizationGeneration++;
16524
+ resetNavigationRefresh();
16432
16525
  webLoading = false;
16433
16526
  webError = null;
16434
16527
  websiteNavigation = emptyNavigation();
@@ -16467,16 +16560,24 @@ window.__ModuleLoader__.load({
16467
16560
  accountStorageKey: state.authorization.status === "authorized" && state.authorization.accountId ? `dsh-deepseek-chat:website:${state.authorization.accountId}` : null,
16468
16561
  authorizationGeneration,
16469
16562
  websiteReloadRevision,
16563
+ websiteNavigationRefreshing,
16564
+ websiteNavigationRefreshError,
16470
16565
  websiteNavigation,
16471
16566
  showWebsiteNavigation
16472
16567
  };
16473
16568
  sidebar?.sync();
16474
16569
  for (const listener of listeners) listener();
16475
16570
  }
16571
+ function resetNavigationRefresh() {
16572
+ websiteNavigationRefreshRequest++;
16573
+ websiteNavigationRefreshing = false;
16574
+ websiteNavigationRefreshError = null;
16575
+ }
16476
16576
  function acceptAuthorization(value) {
16477
16577
  const next = authorizationSchema.parse(value);
16478
16578
  const previous = mode.getSnapshot().authorization;
16479
16579
  if (next.accountId !== previous.accountId || next.epoch !== previous.epoch) {
16580
+ resetNavigationRefresh();
16480
16581
  authorizationGeneration++;
16481
16582
  websiteNavigation = emptyNavigation();
16482
16583
  navigationHandler = null;
@@ -16709,6 +16810,7 @@ window.__ModuleLoader__.load({
16709
16810
  },
16710
16811
  beginWebsiteSignIn: () => {
16711
16812
  if (disposed || !nativeBrowser || logoutRequested) return;
16813
+ resetNavigationRefresh();
16712
16814
  if (mode.getSnapshot().mode !== "chat") mode.select("chat");
16713
16815
  restorationBlocked = true;
16714
16816
  if (!websiteSignInRequested) websiteAuthenticationRevision++;
@@ -16747,14 +16849,42 @@ window.__ModuleLoader__.load({
16747
16849
  },
16748
16850
  reportWebsiteState: (generation, state) => {
16749
16851
  if (disposed || generation !== authorizationGeneration) return;
16852
+ const recovered = webError !== null && !state.loading && state.error === null;
16750
16853
  webLoading = state.loading;
16751
16854
  webError = state.error;
16752
16855
  publish();
16856
+ if (recovered && !websiteNavigationRefreshing) {
16857
+ websiteNavigationRefreshError = null;
16858
+ publish();
16859
+ }
16753
16860
  },
16754
16861
  reloadWebsite: () => {
16862
+ resetNavigationRefresh();
16755
16863
  websiteReloadRevision++;
16756
16864
  publish();
16757
16865
  },
16866
+ refreshWebsiteNavigation: () => {
16867
+ if (disposed || !mode.canEnter() || !nativeBrowser || websiteNavigationRefreshing || webLoading || websiteNavigation.authenticated !== true || logoutRequested || logoutFailed || ["signing-in", "signing-out"].includes(websiteAuthenticationStatus) || restoringPreferences || websiteNavigation.settings?.pending) return;
16868
+ if (!navigationHandler) {
16869
+ websiteNavigationRefreshError = "\u5B98\u7F51\u9875\u9762\u5C1A\u672A\u5C31\u7EEA\uFF0C\u8BF7\u7A0D\u540E\u5237\u65B0\u3002";
16870
+ publish();
16871
+ return;
16872
+ }
16873
+ const requestId = ++websiteNavigationRefreshRequest;
16874
+ const generation = authorizationGeneration;
16875
+ websiteNavigationRefreshing = true;
16876
+ websiteNavigationRefreshError = null;
16877
+ publish();
16878
+ void navigationHandler({ type: "refresh", requestId, authenticationRevision: websiteAuthenticationRevision }).catch(() => {
16879
+ bridge.reportWebsiteNavigationRefresh(generation, { requestId, refreshing: false, error: "\u65E0\u6CD5\u5237\u65B0\u5B98\u7F51\u5BF9\u8BDD\u5217\u8868\uFF0C\u8BF7\u91CD\u8BD5\u3002" });
16880
+ });
16881
+ },
16882
+ reportWebsiteNavigationRefresh: (generation, state) => {
16883
+ if (disposed || generation !== authorizationGeneration || state.requestId !== websiteNavigationRefreshRequest || !websiteNavigationRefreshing) return;
16884
+ websiteNavigationRefreshing = state.refreshing;
16885
+ websiteNavigationRefreshError = state.error;
16886
+ publish();
16887
+ },
16758
16888
  reportWebsiteNavigation: (generation, value, newDocument = false) => {
16759
16889
  if (disposed || generation !== authorizationGeneration) return;
16760
16890
  let next;
@@ -16839,6 +16969,7 @@ window.__ModuleLoader__.load({
16839
16969
  commandWebsite: (command) => {
16840
16970
  if (disposed || !mode.canEnter() || !navigationHandler) return;
16841
16971
  if ((logoutRequested || logoutFailed) && command.type !== "logout" && command.type !== "snapshot") return;
16972
+ if (websiteNavigationRefreshing && !["logout", "snapshot", "restore", "settings-close"].includes(command.type)) return;
16842
16973
  if (websiteNavigation.status !== "ready" && command.type !== "logout" && command.type !== "snapshot" && command.type !== "restore") return;
16843
16974
  if (command.type === "settings-read" && (restoringPreferences || websiteNavigation.settings?.pending)) return;
16844
16975
  if (command.type === "open" && !websiteNavigation.conversations.some((item) => item.href === command.href)) return;
@@ -16864,6 +16995,7 @@ window.__ModuleLoader__.load({
16864
16995
  logoutWebsite: () => {
16865
16996
  if (logoutRequested || !navigationHandler || !websiteHadSession && !logoutFailed) return;
16866
16997
  if (!logoutFailed && websiteNavigation.status !== "ready") return;
16998
+ resetNavigationRefresh();
16867
16999
  const generation = authorizationGeneration;
16868
17000
  const handler = navigationHandler;
16869
17001
  clearTimeout(logoutTimer);
package/lib/types/ui.d.ts CHANGED
@@ -32,6 +32,8 @@ export interface DshChatViewState {
32
32
  readonly brandAnchor: DshChatViewportRect | null;
33
33
  readonly sidebarAdapted: boolean | null;
34
34
  readonly websiteNavigation: WebsiteNavigation;
35
+ readonly websiteNavigationRefreshing: boolean;
36
+ readonly websiteNavigationRefreshError: string | null;
35
37
  readonly showWebsiteNavigation: boolean;
36
38
  }
37
39
  export interface DshChatUIBridge {
@@ -47,6 +49,12 @@ export interface DshChatUIBridge {
47
49
  updateBrandAnchor(rect: DshChatViewportRect | null): void;
48
50
  attachSidebar(element: HTMLElement): void;
49
51
  reloadWebsite(): void;
52
+ refreshWebsiteNavigation(): void;
53
+ reportWebsiteNavigationRefresh(generation: number, state: {
54
+ readonly requestId: number;
55
+ readonly refreshing: boolean;
56
+ readonly error: string | null;
57
+ }): void;
50
58
  reportWebsiteState(generation: number, state: {
51
59
  readonly loading: boolean;
52
60
  readonly error: string | null;
@@ -41,6 +41,12 @@ export type WebsiteCommand = {
41
41
  readonly language: string;
42
42
  } | {
43
43
  readonly type: 'logout';
44
+ }
45
+ /** Handled by the guest owner; never a DOM-only snapshot. */
46
+ | {
47
+ readonly type: 'refresh';
48
+ readonly requestId: number;
49
+ readonly authenticationRevision: number;
44
50
  } | {
45
51
  readonly type: 'new';
46
52
  } | {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-deepseek-chat",
3
- "version": "0.1.11",
3
+ "version": "0.1.12",
4
4
  "description": "CHAT / HARNESS mode switcher for DeepSeek Harness",
5
5
  "repository": {
6
6
  "type": "git",