dsh-archived-chats 1.7.0 → 1.7.1
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/CHANGELOG.md +12 -0
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/docs/ARCHITECTURE.en.md +1 -1
- package/docs/ARCHITECTURE.md +1 -1
- package/docs/USER_GUIDE.md +1 -1
- package/docs/USER_GUIDE.zh-CN.md +1 -1
- package/lib/about.js +28 -7
- package/lib/client.js +10 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@
|
|
|
4
4
|
|
|
5
5
|
Entries describe behavior at each release, not necessarily current behavior. Consult the READMEs and user guides for current usage.
|
|
6
6
|
|
|
7
|
+
## 1.7.1 — 2026-11-07
|
|
8
|
+
|
|
9
|
+
### 中文
|
|
10
|
+
|
|
11
|
+
- 插件更新优先接入官方 `updateBundle`,支持宿主热重载环境中的版本替换,由官方管理兼容性检查、安装和失败恢复。
|
|
12
|
+
- 更新结果区分已应用与需要重启,并明确提示旧版恢复结果。更新指引优先引导官方插件页的版本区域,保留旧 Host 兼容和本地开发版保护。
|
|
13
|
+
|
|
14
|
+
### English
|
|
15
|
+
|
|
16
|
+
- Prefer the official `updateBundle` API for plugin updates, including Host hot-reload environments. The Host manages compatibility checks, replacement and recovery after failure.
|
|
17
|
+
- Distinguish applied updates from required restarts and report verified restoration outcomes. Direct manual guidance to the official Plugins page’s Versions section, retaining older Host compatibility and local-checkout protection.
|
|
18
|
+
|
|
7
19
|
## 1.7.0 — 2026-11-07
|
|
8
20
|
|
|
9
21
|
### 中文
|
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ Archive Management adds conversation search, organization and backups to DeepSee
|
|
|
35
35
|
- **Portable backups:** export and import JSON + Markdown ZIPs; imports preview before writing and skip existing IDs to avoid overwrites.
|
|
36
36
|
- **Conversation lineage:** read-only Origins & Branches view traces sources, forks and subagent relationships across all workspaces, including archived and unarchived chats.
|
|
37
37
|
|
|
38
|
-
> This document describes version 1.7.
|
|
38
|
+
> This document describes version 1.7.1. Previous recovery features are removed, with explicit retries for permanent-deletion tasks.
|
|
39
39
|
|
|
40
40
|
## Install and open
|
|
41
41
|
|
package/README.zh-CN.md
CHANGED
package/docs/ARCHITECTURE.en.md
CHANGED
|
@@ -129,7 +129,7 @@ Plugin confirmation, preview, import, and metadata dialogs share the opaque `--d
|
|
|
129
129
|
|
|
130
130
|
Opening Archive Management loads local metadata, then automatically checks public npm metadata. While the page stays open, cache-aware checks run every 15 minutes and on visibility/network recovery. Success is cached for 12 hours and failure for 15 minutes; manual checks have a 30-second cooldown and concurrent requests coalesce. No chats or backups are sent. Failure never blocks chat management or claims the plugin is current. Leaving the page removes timers and listeners.
|
|
131
131
|
|
|
132
|
-
`POST /about/install-update` additionally requires a local request, rejects cross-origin requests and accepts only `{ version }`. `createUpdateRuntime`
|
|
132
|
+
`POST /about/install-update` additionally requires a local request, rejects cross-origin requests and accepts only `{ version }`. `createUpdateRuntime` verifies the profile dependency and loaded package path. Local, external, unknown and mismatched sources cannot install. It prefers official `pluginManager.updateBundle`, including under HMR. The Host owns replacement and rollback. The adapter validates the nested result and on-disk package identity, reports verified restoration separately, and returns `applied` or `restart-required`. Older Hosts may use `installBundle` only without HMR. No package-manager process is spawned. Each Host owns its service state, and the loaded version remains distinct from the installed version. HMR may dispose this settings UI and abort its request, so users can reopen the page to verify the newly loaded version.
|
|
133
133
|
|
|
134
134
|
## Permanent deletion and crash recovery
|
|
135
135
|
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -132,7 +132,7 @@ apply 只接受凭据,不接受调用方增补会话 ID。每条执行前在
|
|
|
132
132
|
|
|
133
133
|
打开归档管理时先读取本地信息,再自动查询公开 npm 版本;页面保持打开时每 15 分钟进行缓存感知检查,重新显示或联网时也会补查。成功结果缓存 12 小时,失败结果缓存 15 分钟;手动检查使用 30 秒短限流,并发请求合并。只查询公开版本,不发送聊天或备份内容;失败不阻塞会话管理,也不显示「已是最新版」。关闭页面会清理定时器和事件监听。
|
|
134
134
|
|
|
135
|
-
`POST /about/install-update`
|
|
135
|
+
`POST /about/install-update` 额外要求本机请求,拒绝跨来源写入,仅接受 `{ version }`。`createUpdateRuntime` 核对 profile 依赖与实际加载路径,本地、外部、未知或路径不一致的来源均拒绝安装。优先调用官方 `pluginManager.updateBundle`,包括 HMR 环境,替换与回滚均由宿主负责。适配器校验嵌套结果和磁盘包身份,分别报告已应用、待重启及旧版恢复结果。旧 Host 仅在无 HMR 时退回 `installBundle`,不自行启动包管理器。各 Host 独立保存操作状态,已加载版本与已安装版本分开表达。HMR 可能卸载当前设置页并中断其请求,用户可重新打开页面核对新加载的版本。
|
|
136
136
|
|
|
137
137
|
## 永久删除与崩溃恢复
|
|
138
138
|
|
package/docs/USER_GUIDE.md
CHANGED
|
@@ -187,7 +187,7 @@ When diagnosing an unchanged version after an update, also verify that you updat
|
|
|
187
187
|
|
|
188
188
|
Check for updates and View update beside the heading open a dialog with the running version, public release, last check and current host. Copy the package spec into Add plugin in another host. A terminal command is offered only when the current launcher and profile can be verified; official Desktop uses its own bundled command, never an unrelated dsh on PATH. This detects the current host only, not other Desktop installations.
|
|
189
189
|
|
|
190
|
-
Local link:/file: installations are labeled Local checkout, offer Copy local path and are protected on the backend against registry replacement. Registry installations
|
|
190
|
+
Local link:/file: installations are labeled Local checkout, offer Copy local path and are protected on the backend against registry replacement. Registry installations offer Install update when supported. The official updateBundle API is preferred, letting the Host check version compatibility, replace the plugin and attempt to restore the previous version if installation fails. Settings may close during replacement. Reopen Archive Management afterward to verify its running version. Results distinguish Host-applied updates from required restarts and report whether restoration was verified. Older Hosts use the official installation API only where replacement is supported, otherwise directing users to the Versions section on the official Plugins page. Duplicate submissions are blocked. Restarting DSH remains a user action.
|
|
191
191
|
|
|
192
192
|
## Upgrades
|
|
193
193
|
|
package/docs/USER_GUIDE.zh-CN.md
CHANGED
|
@@ -187,7 +187,7 @@ JSON 是机器可读记录,Markdown 是可读副本。新版 Host 导出 ZIP v
|
|
|
187
187
|
|
|
188
188
|
「检查更新」与标题旁的「查看更新」打开更新弹窗,展示运行版本、公开版本、上次检查和当前环境。支持复制包名到另一端的「添加插件」;命令只在能验证当前启动程序和 profile 时提供,官方桌面端使用其自带命令,不依赖 PATH 中的另一套 dsh。这里只识别当前环境,不扫描或自动安装到其他桌面端。
|
|
189
189
|
|
|
190
|
-
本地 `link:` / `file:`
|
|
190
|
+
本地 `link:` / `file:` 等来源标记为「本地开发版」,提供复制本地路径,后端拒绝用线上包覆盖。npm 安装在宿主支持时提供「安装更新」,优先调用官方 `updateBundle`,由宿主检查版本与兼容性、替换旧插件,并在安装失败时尝试恢复旧版本。更新期间设置页可能关闭,完成后重新打开归档管理核对运行版本。结果区分「宿主已应用」和「需要重启」;旧版恢复成功或未能确认恢复均有明确提示。旧 Host 缺少更新接口时,仅在允许替换的环境使用官方安装接口,其余引导前往官方插件页的版本区域更新。重复提交被阻止,DSH 重启由用户操作。
|
|
191
191
|
|
|
192
192
|
## 升级
|
|
193
193
|
|
package/lib/about.js
CHANGED
|
@@ -70,8 +70,8 @@ export function createUpdateRuntime(ctx, {
|
|
|
70
70
|
if (realpathSync(installedRoot) !== realpathSync(packageRoot)) { info.reason = 'runtime-mismatch'; return { info }; }
|
|
71
71
|
info.command = commandFor(context, info.packageSpec);
|
|
72
72
|
const manager = service('pluginManager');
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
info.canInstall = typeof manager?.updateBundle === 'function'
|
|
74
|
+
|| (typeof manager?.installBundle === 'function' && service('hmr') == null);
|
|
75
75
|
info.reason = info.canInstall ? null : 'host-managed';
|
|
76
76
|
return { info, manager, installedRoot };
|
|
77
77
|
} catch { return { info: { ...info, canInstall: false, reason: 'unknown-runtime', command: null } }; }
|
|
@@ -83,11 +83,31 @@ export function createUpdateRuntime(ctx, {
|
|
|
83
83
|
const { info, manager, installedRoot } = inspect(version);
|
|
84
84
|
if (info.source === 'local') throw updateError('update-local-install');
|
|
85
85
|
if (!info.canInstall) throw updateError('update-host-managed');
|
|
86
|
-
const
|
|
86
|
+
const installedMatches = expected => {
|
|
87
|
+
try {
|
|
88
|
+
const installed = readJson(join(installedRoot, 'package.json'));
|
|
89
|
+
return installed.name === manifest.name && installed.version === expected;
|
|
90
|
+
} catch { return false; }
|
|
91
|
+
};
|
|
92
|
+
let result;
|
|
93
|
+
if (typeof manager.updateBundle === 'function') {
|
|
94
|
+
const update = await manager.updateBundle(manifest.name, version, { registry: 'https://registry.npmjs.org/' });
|
|
95
|
+
if (update?.to !== version) throw updateError('update-install-failed', 502);
|
|
96
|
+
if (update.restore) {
|
|
97
|
+
const restored = ['applied', 'restart-required'].includes(update.restore.application)
|
|
98
|
+
&& !update.restore.error && update.restore.bundle === manifest.name
|
|
99
|
+
&& update.restore.version === update.from && installedMatches(update.from);
|
|
100
|
+
throw updateError(restored ? 'update-restored' : 'update-restore-failed', 502);
|
|
101
|
+
}
|
|
102
|
+
if (update.step !== 'install') throw updateError('update-install-failed', 502);
|
|
103
|
+
result = update.result;
|
|
104
|
+
} else {
|
|
105
|
+
result = await manager.installBundle(`${manifest.name}@${version}`, { registry: 'https://registry.npmjs.org/', saveExact: true });
|
|
106
|
+
}
|
|
87
107
|
if (!['applied', 'restart-required'].includes(result?.application) || result?.error
|
|
88
108
|
|| result?.version !== version || result?.bundle !== manifest.name) throw updateError('update-install-failed', 502);
|
|
89
|
-
|
|
90
|
-
|
|
109
|
+
if (!installedMatches(version)) throw updateError('update-install-unverified', 502);
|
|
110
|
+
return { application: result.application };
|
|
91
111
|
},
|
|
92
112
|
};
|
|
93
113
|
}
|
|
@@ -344,6 +364,7 @@ export function createAboutService({
|
|
|
344
364
|
},
|
|
345
365
|
async installUpdate({ version: targetVersion } = {}) {
|
|
346
366
|
if (install.status === 'installing') throw updateError('update-busy');
|
|
367
|
+
if (install.status === 'applied') throw updateError('update-already-applied');
|
|
347
368
|
if (install.status === 'restart-required') throw updateError('update-restart-required');
|
|
348
369
|
const environment = runtime?.describe(targetVersion);
|
|
349
370
|
if (environment?.source === 'local') throw updateError('update-local-install');
|
|
@@ -352,8 +373,8 @@ export function createAboutService({
|
|
|
352
373
|
try {
|
|
353
374
|
await service.checkUpdates({ force: false });
|
|
354
375
|
if (update.status !== 'available' || update.latestVersion !== targetVersion || !parseSemver(targetVersion)) throw updateError('update-version-changed');
|
|
355
|
-
await runtime.install(targetVersion);
|
|
356
|
-
install = { status: 'restart-required', version: targetVersion };
|
|
376
|
+
const result = await runtime.install(targetVersion);
|
|
377
|
+
install = { status: result?.application === 'applied' ? 'applied' : 'restart-required', version: targetVersion };
|
|
357
378
|
return about();
|
|
358
379
|
} catch (error) {
|
|
359
380
|
install = { status: 'failed', version: null };
|
package/lib/client.js
CHANGED
|
@@ -4568,13 +4568,15 @@ window.__ModuleLoader__.load({
|
|
|
4568
4568
|
const [copied, setCopied] = _react.useState(null);
|
|
4569
4569
|
_react.useEffect(() => { setCopied(null); }, [info?.command, info?.packageSpec, info?.localPath]);
|
|
4570
4570
|
const local = info?.source === "local", restart = about?.install?.status === "restart-required";
|
|
4571
|
-
const
|
|
4571
|
+
const applied = about?.install?.status === "applied";
|
|
4572
|
+
const canInstall = info?.canInstall === true && update?.status === "available" && !local && !restart && !applied;
|
|
4572
4573
|
const copy = async (value, key) => {
|
|
4573
4574
|
try { if (!globalThis.navigator?.clipboard?.writeText) throw new Error("clipboard unavailable");
|
|
4574
4575
|
await globalThis.navigator.clipboard.writeText(value); setCopied(key);
|
|
4575
4576
|
} catch { setCopied("failed"); }
|
|
4576
4577
|
};
|
|
4577
4578
|
const status = restart ? (zh ? `v${about.install.version} 已安装,请重启 DSH 后确认运行版本。` : `v${about.install.version} installed. Restart DSH and verify the running version.`)
|
|
4579
|
+
: applied ? (zh ? `宿主已应用 v${about.install.version},重新打开归档管理可确认运行版本。` : `The host applied v${about.install.version}. Reopen Archive Management to verify the running version.`)
|
|
4578
4580
|
: installing ? (zh ? "正在通过宿主安装更新…" : "Installing through the host…")
|
|
4579
4581
|
: checking ? (zh ? "正在检查更新…" : "Checking for updates…")
|
|
4580
4582
|
: update?.status === "available" ? (zh ? `发现新版本 v${update.latestVersion}` : `Version ${update.latestVersion} is available`)
|
|
@@ -4594,14 +4596,14 @@ window.__ModuleLoader__.load({
|
|
|
4594
4596
|
(0, jsx.jsx)("dt", { children: zh ? "上次检查" : "Last checked" }), (0, jsx.jsx)("dd", { children: update?.checkedAt ? new Date(update.checkedAt).toLocaleString(zh ? "zh-CN" : "en-US") : "—" }),
|
|
4595
4597
|
] }),
|
|
4596
4598
|
(0, jsx.jsxs)("div", { className: "dac-about-links", children: [
|
|
4597
|
-
(0, jsx.jsx)(ControlButton, { type: "button", className: "dac-action-trigger", disabled: checking || installing || restart, onClick: onCheck, children: zh ? "重新检查" : "Check again" }),
|
|
4599
|
+
(0, jsx.jsx)(ControlButton, { type: "button", className: "dac-action-trigger", disabled: checking || installing || restart || applied, onClick: onCheck, children: zh ? "重新检查" : "Check again" }),
|
|
4598
4600
|
safeAboutLink(about?.links?.changelog) && (0, jsx.jsx)("a", { href: safeAboutLink(about.links.changelog), target: "_blank", rel: "noopener noreferrer", children: zh ? "更新日志" : "Changelog" }),
|
|
4599
4601
|
] }),
|
|
4600
4602
|
local ? (0, jsx.jsxs)("section", { className: "dac-update-manual", children: [
|
|
4601
4603
|
(0, jsx.jsx)("p", { children: zh ? "当前连接本地源码,不会被线上更新替换。修改后重启 DSH 即可加载;在另一端接入时,粘贴下面目录到「添加插件」。" : "This local checkout is protected from registry replacement. Restart DSH after editing. To connect it in another host, paste this directory into Add plugin." }),
|
|
4602
4604
|
codeBlock(info.localPath, zh ? "复制本地路径" : "Copy local path", "path"),
|
|
4603
4605
|
] }) : (0, jsx.jsxs)("section", { className: "dac-update-manual", children: [
|
|
4604
|
-
(0, jsx.jsx)("p", { children: info?.source === "external" ? (zh ? "当前由外部来源安装,请按原来源更新。以下信息可用于在其他环境安装公开版本。" : "This plugin uses an external source; update from that source. Use the information below to install a public release elsewhere.") : canInstall ? (zh ? "
|
|
4606
|
+
(0, jsx.jsx)("p", { children: info?.source === "external" ? (zh ? "当前由外部来源安装,请按原来源更新。以下信息可用于在其他环境安装公开版本。" : "This plugin uses an external source; update from that source. Use the information below to install a public release elsewhere.") : info?.canInstall ? (zh ? "点击「安装更新」由官方插件管理器检查兼容性并替换当前插件。更新期间本页可能关闭,完成后重新打开归档管理确认版本;需要重启时会明确提示。" : "Install update lets the official plugin manager check compatibility and replace this plugin. This page may close during replacement. Reopen Archive Management to verify the version. A required restart is reported explicitly.") : (zh ? "请前往官方插件页,找到归档管理,在版本区域更新;旧宿主要求重新安装时,按页面提示操作。下方包名也可用于在其他环境添加插件。" : "Find Archive Management on the official Plugins page and update from its Versions section. Follow reinstall instructions on older hosts. The package below can also be added in another host." ) }),
|
|
4605
4607
|
codeBlock(info?.packageSpec ?? "dsh-archived-chats@latest", zh ? "复制安装信息" : "Copy package", "package"),
|
|
4606
4608
|
info?.command && (0, jsx.jsxs)("details", { className: "dac-update-terminal", children: [
|
|
4607
4609
|
(0, jsx.jsx)("summary", { children: zh ? "终端更新命令" : "Terminal update command" }),
|
|
@@ -4887,13 +4889,13 @@ window.__ModuleLoader__.load({
|
|
|
4887
4889
|
};
|
|
4888
4890
|
const installUpdate = async () => {
|
|
4889
4891
|
if (updateRequestRef.current || about?.installation?.canInstall !== true || about?.installation?.source === "local"
|
|
4890
|
-
|| about?.update?.status !== "available" ||
|
|
4892
|
+
|| about?.update?.status !== "available" || ["applied", "restart-required"].includes(about?.install?.status)) return;
|
|
4891
4893
|
const request = new AbortController(); updateRequestRef.current = request;
|
|
4892
4894
|
aboutRequestRef.current?.controller.abort(); aboutRequestRef.current = null;
|
|
4893
4895
|
setAboutChecking(false); setUpdateBusy(true); setUpdateError(null);
|
|
4894
4896
|
try {
|
|
4895
4897
|
const result = await post("/about/install-update", { version: about.update.latestVersion }, request.signal);
|
|
4896
|
-
if (!validAbout(result) ||
|
|
4898
|
+
if (!validAbout(result) || !["applied", "restart-required"].includes(result.install?.status)) throw new Error("update-unverified");
|
|
4897
4899
|
if (!request.signal.aborted) setAbout(result);
|
|
4898
4900
|
} catch (error) {
|
|
4899
4901
|
if (!request.signal.aborted) {
|
|
@@ -4901,6 +4903,9 @@ window.__ModuleLoader__.load({
|
|
|
4901
4903
|
setUpdateError(code === "update-version-changed" ? (isZh(t) ? "版本信息已变化,请重新检查后再更新。" : "Version information changed. Check again before updating.")
|
|
4902
4904
|
: code === "update-local-install" ? (isZh(t) ? "当前已切换为本地开发版,已阻止线上覆盖。" : "This is now a local checkout; registry replacement was blocked.")
|
|
4903
4905
|
: code === "update-host-managed" ? (isZh(t) ? "当前宿主要求通过插件管理页面更新,请按下方指引操作。" : "Use the host’s plugin manager to update. Follow the instructions below.")
|
|
4906
|
+
: code === "update-already-applied" ? (isZh(t) ? "宿主已应用更新,请重新打开归档管理确认运行版本。" : "The host already applied the update. Reopen Archive Management to verify the running version.")
|
|
4907
|
+
: code === "update-restored" ? (isZh(t) ? "新版安装失败,官方插件管理器已恢复旧版本。请重新打开归档管理确认。" : "The update failed and the official plugin manager restored the previous version. Reopen Archive Management to verify.")
|
|
4908
|
+
: code === "update-restore-failed" ? (isZh(t) ? "新版安装失败,旧版本也未能确认恢复。请到官方插件页检查并重新安装。" : "The update failed and restoration could not be verified. Check the official Plugins page and reinstall.")
|
|
4904
4909
|
: (isZh(t) ? "未能确认更新完成。请重新打开本页核对状态;仍未完成时,通过宿主插件页面检查错误或使用下方命令。" : "Update completion could not be confirmed. Reopen this page to check its state, then use the host’s plugin page or the command below if needed."));
|
|
4905
4910
|
}
|
|
4906
4911
|
} finally {
|