dsh-theone 0.3.18 → 0.3.19

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
@@ -47,7 +47,7 @@ Each project gets its own background session that reasons, runs tools and compac
47
47
  - **Related work connects; unrelated work stays out.** Related topics share progress automatically and TheOne learns which ones belong together from how you use them. A topic's constraints (say, "budget figures stay out of the paper") are attached verbatim every time, so compaction never drops them.
48
48
  - **Gets better with use.** Say "wrong topic" or click **Move to…** in the directory, and TheOne learns which terms tie that kind of message to the right topic (one small model call), so similar messages go there from then on. The directory shows how often routing was kept as is.
49
49
  - **Your old sessions become a topic directory.** After install it reads your existing sessions in the background, turns them into topics grouped into workspaces, and you pick up where you left off.
50
- - **Nothing extra to configure.** No separate API key: routing and the background sessions use the model you chose in DSH. When TheOne is the selected model, a **Background** button beside the model menu shows which model does the routing and the work, and switches it.
50
+ - **Nothing extra to configure.** No separate API key: routing and the background sessions use the model you chose in DSH. When TheOne is the selected model, a button with a layers icon appears beside the model menu: it shows which model does the routing and the work, and switches it.
51
51
 
52
52
  ![TheOne main chat and topic workspaces](https://raw.githubusercontent.com/YunongDai2005/dsh-theone/main/docs/images/theone-topic-workspaces-en.png)
53
53
 
@@ -57,7 +57,7 @@ Each project gets its own background session that reasons, runs tools and compac
57
57
  2. Open **Plugins → Add plugin**, paste `https://github.com/YunongDai2005/dsh-theone`, and install.
58
58
  3. Click **TheOne · Main chat** in the sidebar and start talking.
59
59
 
60
- From the command line: `dsh plugin --profile web add github:YunongDai2005/dsh-theone --ignore-scripts`. Works with DSH `0.2.0-rc.2` and Node.js 24; the interface follows DSH's language (English / Simplified Chinese). Installing `dsh-theone` from npm also works, but DSH's package manager only accepts a version once it has been published for 24 hours, so the GitHub address gets new versions first. When an update is newer than that, the Update button explains it and can exempt TheOne alone so it installs right away.
60
+ From the command line: `dsh plugin --profile web add github:YunongDai2005/dsh-theone --ignore-scripts`. Works with DSH `0.2.0-rc.2` and Node.js 24; the interface follows DSH's language (English / Simplified Chinese). Installing `dsh-theone` from npm also works, but DSH's package manager only accepts a version once it has been published for 24 hours, so the GitHub address gets new versions first. When an update is newer than that, the update button explains it and can exempt TheOne alone so it installs right away.
61
61
 
62
62
  > Unofficial community project, maintained independently. It is not affiliated with or endorsed by DeepSeek.
63
63
 
@@ -106,7 +106,7 @@ The database location and entry identifier switch TheOne to different data, so t
106
106
  - A topic marked **Do not share** never appears in other topics' briefings, recent-chat excerpts or lookups.
107
107
  - Notices from the author are read from `https://yulid.org/theone/notice.json` with a plain request that sends none of your data; turn them off in Settings.
108
108
  - When main chat grows long, DSH compacts it through TheOne: frequently used topics keep longer summaries and their latest turns, rarely used ones keep a short status. This makes no model call.
109
- - When a new version is out, an **Update** button appears on the right of the TheOne entry in the sidebar: one click installs it through DSH's plugin manager and reloads TheOne in place, without restarting DSH (a DSH without plugin hot reload applies it at the next restart). Your topics stay in the database.
109
+ - When a new version is out, a download icon appears on the right of the TheOne entry in the sidebar: one click installs it through DSH's plugin manager and reloads TheOne in place, without restarting DSH (a DSH without plugin hot reload applies it at the next restart). Your topics stay in the database.
110
110
  </details>
111
111
 
112
112
  <details>
package/README.zh.md CHANGED
@@ -47,7 +47,7 @@
47
47
  - **相关的事会互通,无关的事互不打扰**:相关话题自动共享进展,并从你的使用中学习哪些话题有关联;话题的约束(比如「预算数字不能写进论文」)每次都原样带上,压缩不会把它丢掉。
48
48
  - **越用越准**:说「分错了」或在目录里点「改到…」,TheOne 会学到哪些词把这类消息和正确话题联系起来(只需一次很小的模型调用),类似的消息以后直接分对;话题目录里能看到分配的准确率。
49
49
  - **旧会话自动变成话题目录**:装上后它会在后台读取你已有的会话,整理成话题并按工作区分组,直接接着聊。
50
- - **零额外配置**:不用另填 API Key,路由和后台都用你在 DSH 里选好的模型。选中 TheOne 时,模型按钮旁边会出现 **后台** 按钮,显示并切换分配话题和干活用的模型。
50
+ - **零额外配置**:不用另填 API Key,路由和后台都用你在 DSH 里选好的模型。选中 TheOne 时,模型按钮旁边会出现一个带图层图标的按钮,显示并切换分配话题和干活用的模型。
51
51
 
52
52
  ![TheOne 主聊天与话题工作区](https://raw.githubusercontent.com/YunongDai2005/dsh-theone/main/docs/images/theone-topic-workspaces-en.png)
53
53
 
@@ -57,7 +57,7 @@
57
57
  2. 打开 **插件 → 添加插件**,粘贴 `https://github.com/YunongDai2005/dsh-theone`,点击安装。
58
58
  3. 点击左侧 **TheOne · 主聊天**,开始说话。
59
59
 
60
- 命令行安装:`dsh plugin --profile web add github:YunongDai2005/dsh-theone --ignore-scripts`。兼容 DSH `0.2.0-rc.2` 与 Node.js 24;界面跟随 DSH 的语言(简体中文 / English)。也可以从 npm 安装 `dsh-theone`,但 DSH 的包管理器只接受发布满 24 小时的版本,所以用 GitHub 地址安装能最早拿到新版本。遇到这种情况,「更新」按钮会说明原因,并可以只为 TheOne 放行、立即安装。
60
+ 命令行安装:`dsh plugin --profile web add github:YunongDai2005/dsh-theone --ignore-scripts`。兼容 DSH `0.2.0-rc.2` 与 Node.js 24;界面跟随 DSH 的语言(简体中文 / English)。也可以从 npm 安装 `dsh-theone`,但 DSH 的包管理器只接受发布满 24 小时的版本,所以用 GitHub 地址安装能最早拿到新版本。遇到这种情况,更新按钮会说明原因,并可以只为 TheOne 放行、立即安装。
61
61
 
62
62
  > 非官方社区项目,由社区成员独立维护,与 DeepSeek 不存在隶属或背书关系。
63
63
 
@@ -106,7 +106,7 @@
106
106
  - 标记为「不共享」的话题,不会出现在其他话题的简报、最近对话和查阅结果里。
107
107
  - 作者发布的公告从 `https://yulid.org/theone/notice.json` 读取,只是一次普通的下载,不发送你的任何数据;可以在设置里关闭。
108
108
  - 主聊天变长时,DSH 通过 TheOne 压缩它:常用话题保留较长摘要和最近几轮,不常用的只保留简短状态,不额外调用模型。
109
- - 有新版本时,左侧 TheOne 入口右边会出现 **更新** 按钮,点一下由 DSH 的插件管理器安装,并就地重新加载 TheOne,不用重启 DSH(不支持插件热加载的 DSH 会在下次启动时生效);话题都保存在数据库里,不受影响。
109
+ - 有新版本时,左侧 TheOne 入口右边会出现一个下载图标,点一下由 DSH 的插件管理器安装,并就地重新加载 TheOne,不用重启 DSH(不支持插件热加载的 DSH 会在下次启动时生效);话题都保存在数据库里,不受影响。
110
110
  </details>
111
111
 
112
112
  <details>
package/dist/client.js CHANGED
@@ -681,13 +681,42 @@ function apply(ctx) {
681
681
  document.body.append(backdrop);
682
682
  (allow ?? footer.querySelector("button"))?.focus();
683
683
  }
684
+ const ICONS = {
685
+ download: ["M12 4v11", "M7 10l5 5 5-5", "M5 20h14"],
686
+ restart: ["M20 12a8 8 0 1 1-2.34-5.66L20 8.5", "M20 4v4.5h-4.5"],
687
+ alert: ["M3 12a9 9 0 1 0 18 0a9 9 0 1 0-18 0", "M12 7.5v5.5", "M12 16.5h.01"],
688
+ notice: ["M4 10v4h3l6 4V6L7 10H4z", "M16.5 9a4 4 0 0 1 0 6", "M19 6.5a7.5 7.5 0 0 1 0 11"],
689
+ external: ["M14 4h6v6", "M20 4l-9 9", "M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"],
690
+ close: ["M6 6l12 12", "M18 6L6 18"],
691
+ layers: ["M12 3.5l8.5 4.5-8.5 4.5L3.5 8z", "M3.5 12.5l8.5 4.5 8.5-4.5", "M3.5 16.5l8.5 4.5 8.5-4.5"],
692
+ chevron: ["M6 15l6-6 6 6"],
693
+ grid: ["M4 4h6.5v6.5H4z", "M13.5 4H20v6.5h-6.5z", "M4 13.5h6.5V20H4z", "M13.5 13.5H20V20h-6.5z"]
694
+ };
695
+ const icon = (name, size = 16) => (0, import_react.createElement)(
696
+ "svg",
697
+ {
698
+ className: "theone-icon",
699
+ viewBox: "0 0 24 24",
700
+ width: size,
701
+ height: size,
702
+ fill: "none",
703
+ stroke: "currentColor",
704
+ strokeWidth: 2,
705
+ strokeLinecap: "round",
706
+ strokeLinejoin: "round",
707
+ "aria-hidden": true,
708
+ focusable: false
709
+ },
710
+ ...ICONS[name].map((d) => (0, import_react.createElement)("path", { key: d, d }))
711
+ );
684
712
  function UpdateButton() {
685
713
  const t2 = useText();
686
714
  const status = (0, import_react.useSyncExternalStore)(subscribeUpdate, () => update);
687
715
  const waiting = !!status?.waiting && !status.available && !status.state;
688
716
  if (!status || !status.available && !status.state && !waiting) return null;
689
717
  const label = waiting ? t2("update.waiting") : status.state === "installing" ? t2("update.installing") : status.state === "reloading" ? t2("update.reloading") : status.state === "restart" ? t2("update.restart") : status.state === "failed" ? t2("update.failed") : t2("update.available");
690
- const title = waiting ? t2("update.waitingHint", { latest: status.waiting.version }) : status.error === "GATEWAY_BUSY" ? t2("update.busy") : status.state === "reloading" ? t2("update.reloadingHint") : status.state === "restart" ? t2("update.restartHint") : status.state === "failed" ? status.error === "MINIMUM_RELEASE_AGE" ? t2("update.tooNew") : status.error === "NETWORK" ? t2("update.network") : t2("update.failedHint", { error: status.error ?? "" }) : status.installable ? t2("update.hint", { current: status.current, latest: status.latest ?? "" }) : t2("update.manualHint", { current: status.current, latest: status.latest ?? "" });
718
+ const hint = waiting ? t2("update.waitingHint", { latest: status.waiting.version }) : status.error === "GATEWAY_BUSY" ? t2("update.busy") : status.state === "reloading" ? t2("update.reloadingHint") : status.state === "restart" ? t2("update.restartHint") : status.state === "failed" ? status.error === "MINIMUM_RELEASE_AGE" ? t2("update.tooNew") : status.error === "NETWORK" ? t2("update.network") : t2("update.failedHint", { error: status.error ?? "" }) : status.installable ? t2("update.hint", { current: status.current, latest: status.latest ?? "" }) : t2("update.manualHint", { current: status.current, latest: status.latest ?? "" });
719
+ const title = `${label} \xB7 ${hint}`;
691
720
  const act = (event) => {
692
721
  event.preventDefault();
693
722
  event.stopPropagation();
@@ -718,9 +747,7 @@ function apply(ctx) {
718
747
  if (event.key === "Enter" || event.key === " ") act(event);
719
748
  }
720
749
  },
721
- status.state === "installing" || status.state === "reloading" ? (0, import_react.createElement)("span", { className: "theone-update-spin", "aria-hidden": true }) : null,
722
- label,
723
- !status.state && (waiting ? status.waiting.version : status.latest) ? (0, import_react.createElement)("small", null, `v${waiting ? status.waiting.version : status.latest}`) : null
750
+ status.state === "installing" || status.state === "reloading" ? (0, import_react.createElement)("span", { className: "theone-update-spin", "aria-hidden": true }) : icon(status.state === "restart" ? "restart" : status.state === "failed" ? "alert" : "download", 15)
724
751
  );
725
752
  }
726
753
  const symbol = () => (0, import_react.createElement)(
@@ -1049,9 +1076,9 @@ function apply(ctx) {
1049
1076
  }, () => setFailed(true));
1050
1077
  }
1051
1078
  },
1052
- (0, import_react.createElement)("span", { className: "theone-bg-caption" }, t2("bg.label")),
1079
+ (0, import_react.createElement)("span", { className: "theone-bg-caption", "aria-hidden": true }, icon("layers", 15)),
1053
1080
  (0, import_react.createElement)("span", { className: "theone-bg-text" }, label),
1054
- (0, import_react.createElement)("span", { className: "theone-bg-chevron", "aria-hidden": true }, saving ? "\u2026" : "\u2303")
1081
+ (0, import_react.createElement)("span", { className: "theone-bg-chevron", "aria-hidden": true }, saving ? "\u2026" : icon("chevron", 12))
1055
1082
  );
1056
1083
  }
1057
1084
  let notices = [];
@@ -1157,13 +1184,19 @@ function apply(ctx) {
1157
1184
  return (0, import_react.createElement)(
1158
1185
  "div",
1159
1186
  { className: "theone-notice", role: "status", translate: "no" },
1160
- (0, import_react.createElement)("span", { className: "theone-notice-tag" }, t2("notice.label")),
1187
+ (0, import_react.createElement)("span", { className: "theone-notice-tag", title: t2("notice.label"), "aria-label": t2("notice.label"), role: "img" }, icon("notice", 14)),
1161
1188
  (0, import_react.createElement)("span", { className: "theone-notice-text", title: `${title}
1162
1189
  ${body}` }, (0, import_react.createElement)("strong", null, title), " ", body),
1163
- notice.link ? (0, import_react.createElement)("button", { type: "button", className: "theone-notice-link", onClick: () => {
1164
- window.open(notice.link, "_blank", "noopener");
1165
- } }, t2("notice.more")) : null,
1166
- (0, import_react.createElement)("button", { type: "button", className: "theone-notice-close", "aria-label": t2("notice.close"), title: t2("notice.close"), onClick: () => dismissNotice(notice.id) }, "\xD7")
1190
+ notice.link ? (0, import_react.createElement)("button", {
1191
+ type: "button",
1192
+ className: "theone-notice-link",
1193
+ "aria-label": t2("notice.more"),
1194
+ title: t2("notice.more"),
1195
+ onClick: () => {
1196
+ window.open(notice.link, "_blank", "noopener");
1197
+ }
1198
+ }, icon("external", 14)) : null,
1199
+ (0, import_react.createElement)("button", { type: "button", className: "theone-notice-close", "aria-label": t2("notice.close"), title: t2("notice.close"), onClick: () => dismissNotice(notice.id) }, icon("close", 14))
1167
1200
  );
1168
1201
  }
1169
1202
  ctx.inject(["slots", "modelDirectories"], (scope) => {
@@ -1912,7 +1945,7 @@ ${body}` }, (0, import_react.createElement)("strong", null, title), " ", body),
1912
1945
  ctx.slots.register({ name: "sidebar.panellist", id: panelId, order: -1e3, label: () => t("gateway.title") }, SidebarEntry),
1913
1946
  ctx.slots.register({ name: "sidebar.panellist", id: catalogPanelId, order: -999, label: () => t("catalog.title") }, ({ size }) => {
1914
1947
  const t2 = useText();
1915
- return (0, import_react.createElement)("span", { className: "theone-catalog-entry", translate: "no" }, (0, import_react.createElement)("span", null, "\u25A6"), size === 16 ? (0, import_react.createElement)("span", null, t2("catalog.title")) : null);
1948
+ return (0, import_react.createElement)("span", { className: "theone-catalog-entry", translate: "no" }, icon("grid", 16), size === 16 ? (0, import_react.createElement)("span", null, t2("catalog.title")) : null);
1916
1949
  })
1917
1950
  ]);
1918
1951
  }
@@ -1933,10 +1966,10 @@ button:has(.theone-nav[data-active=true]){border-color:color-mix(in srgb,var(--o
1933
1966
  .theone-update-dot{position:absolute;top:-2px;right:-2px;width:7px;height:7px;border-radius:50%;background:#e8590c;box-shadow:0 0 0 2px var(--one-tint)}
1934
1967
  button:has(.theone-nav[data-wide=true])>span:has(.theone-nav){flex:1;min-width:0}
1935
1968
  .theone-nav[data-wide=true]{width:100%}
1936
- .theone-update{margin-left:auto;align-self:center;display:inline-flex;align-items:center;gap:5px;padding:5px 10px;border-radius:999px;border:1px solid color-mix(in srgb,var(--one-accent) 45%,transparent);background:color-mix(in srgb,var(--one-accent) 12%,transparent);color:var(--one-accent);font-size:12px;line-height:16px;white-space:nowrap;cursor:pointer;transition:background 150ms ease}
1969
+ .theone-icon{display:block;flex:none;overflow:visible}
1970
+ .theone-update{margin-left:auto;align-self:center;flex:none;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;box-sizing:border-box;padding:0;border-radius:50%;border:1px solid color-mix(in srgb,var(--one-accent) 45%,transparent);background:color-mix(in srgb,var(--one-accent) 12%,transparent);color:var(--one-accent);font-size:12px;line-height:16px;white-space:nowrap;cursor:pointer;transition:background 150ms ease}
1937
1971
  .theone-update:hover{background:color-mix(in srgb,var(--one-accent) 22%,transparent)}
1938
1972
  .theone-update:focus-visible{outline:2px solid var(--one-accent);outline-offset:2px}
1939
- .theone-update small{font-size:11px;opacity:.75}
1940
1973
  .theone-update[data-state=installing],.theone-update[data-state=reloading],.theone-update[data-state=restart]{cursor:default}
1941
1974
  .theone-update[data-state=failed]{color:#d9480f;border-color:#d9480f66;background:#d9480f14}
1942
1975
  .theone-update[data-state=waiting]{opacity:.8;border-style:dashed}
@@ -1953,23 +1986,22 @@ button:has(.theone-nav[data-wide=true])>span:has(.theone-nav){flex:1;min-width:0
1953
1986
  .theone-dialog-actions button:focus-visible{outline:2px solid #4a7fc0;outline-offset:2px}
1954
1987
  .theone-dialog .theone-dialog-body{white-space:pre-wrap;color:var(--dsw-alias-label-primary,#e8e8ea)}
1955
1988
  .theone-notice{display:flex;align-items:center;gap:8px;margin:6px 4px 0;padding:6px 8px 6px 10px;border:1px solid var(--dsw-alias-border-l2,#ffffff1f);border-radius:10px;font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary,#a0a0a6);min-width:0}
1956
- .theone-notice-tag{flex:none;padding:0 6px;border-radius:6px;background:#3b6fb033;color:#7fa9dd}
1989
+ .theone-notice-tag{flex:none;display:inline-flex;padding:3px;border-radius:6px;background:#3b6fb033;color:#7fa9dd}
1957
1990
  .theone-notice-text{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
1958
1991
  .theone-notice-text strong{color:var(--dsw-alias-label-primary,#e8e8ea);font-weight:500}
1959
- .theone-notice button{flex:none;border:0;background:transparent;color:inherit;font:inherit;cursor:pointer;padding:2px 6px;border-radius:6px}
1992
+ .theone-notice button{flex:none;display:inline-flex;border:0;background:transparent;color:inherit;font:inherit;cursor:pointer;padding:4px;border-radius:6px}
1960
1993
  .theone-notice button:hover{background:var(--dsw-alias-interactive-bg-hover,#ffffff12)}
1961
1994
  .theone-notice-link{color:#7fa9dd!important}
1962
- .theone-notice-close{font-size:15px;line-height:1}
1963
- .theone-update-spin{width:10px;height:10px;border-radius:50%;border:1.5px solid currentColor;border-right-color:transparent;animation:theone-spin 800ms linear infinite}
1995
+ .theone-update-spin{width:12px;height:12px;border-radius:50%;border:1.5px solid currentColor;border-right-color:transparent;animation:theone-spin 800ms linear infinite}
1964
1996
  @keyframes theone-spin{to{transform:rotate(360deg)}}
1965
1997
  @media(prefers-reduced-motion:reduce){.theone-update-spin{animation:none}}
1966
- .theone-entry-copy{display:flex;flex-direction:column;align-items:flex-start;gap:2px}
1998
+ .theone-entry-copy{display:flex;flex-direction:column;align-items:flex-start;gap:2px;min-width:0}
1967
1999
  .theone-entry-title{display:flex;align-items:center;gap:9px;line-height:22px}
1968
2000
  .theone-wordmark{display:inline-flex;align-items:baseline;gap:1px;white-space:nowrap}
1969
2001
  .theone-word-the{font-size:12px;font-weight:400;letter-spacing:-.25px;color:var(--dsw-alias-label-secondary)}
1970
2002
  .theone-word-one{position:relative;font-family:ui-rounded,'SF Pro Rounded','Avenir Next',sans-serif;font-size:19px;line-height:1.15;font-weight:500;letter-spacing:-1px;transform:rotate(-4deg);padding-right:7px}
1971
2003
  .theone-word-dot{position:absolute;right:0;top:2px;width:4px;height:4px;border-radius:50%;background:currentColor}
1972
- .theone-entry-label{font-size:12px;font-weight:400}
2004
+ .theone-entry-label{font-size:12px;font-weight:400;white-space:nowrap}
1973
2005
  .theone-entry-sub{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary)}
1974
2006
  .theone-opening{padding:32px;color:var(--dsw-alias-label-primary);font:inherit}
1975
2007
  .theone-opening button{padding:8px 16px;font:inherit;color:inherit;background:var(--dsw-alias-interactive-bg-hover);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;cursor:pointer}
@@ -1986,7 +2018,7 @@ var composerCss = `
1986
2018
  .theone-bg:disabled{opacity:.6;cursor:default}
1987
2019
  .theone-bg-caption,.theone-bg-chevron{color:var(--dsw-alias-label-secondary)}
1988
2020
  .theone-bg-text{overflow:hidden;text-overflow:ellipsis;display:var(--dsh-composer-model-text-display,inline)}
1989
- .theone-bg-chevron{font-size:11px}
2021
+ .theone-bg-caption,.theone-bg-chevron{display:inline-flex}
1990
2022
  .theone-bg[data-failed=true] .theone-bg-caption{color:#d9480f}
1991
2023
  .theone-bg-menu{position:fixed;z-index:10000;width:280px;max-height:min(420px,70vh);display:flex;flex-direction:column;padding:6px;border:1px solid var(--dsw-alias-border-l2);border-radius:14px;background:var(--dsw-specific-sidebar-fill);color:var(--dsw-alias-label-primary);box-shadow:0 10px 32px #0003;font:inherit;font-size:14px;box-sizing:border-box}
1992
2024
  .theone-bg-heading{padding:8px 10px 6px;font-size:12px;color:var(--dsw-alias-label-secondary)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-theone",
3
- "version": "0.3.18",
3
+ "version": "0.3.19",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Automatic context routing for DeepSeek Harness",