@omdp/dsh-archived-sessions 0.3.1 → 0.3.3

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
@@ -65,6 +65,8 @@ pnpm add @omdp/dsh-archived-sessions -w
65
65
 
66
66
  ### 变更记录
67
67
 
68
+ - **0.3.3**(2026-09-10):**修复 0.3.2 的删除回归**——0.3.2 把会话根目录改为 `DSH_HOME` 推导时拼出了**混合分隔符**路径(`C:\Users\xj\.dsh/sessions/...`),而删除前校验 `assertSessionDirName` 的 basename 提取对混合分隔符失效(先按 `/` 切再按 `\` 切,把名字切成残缺片段),导致所有删除被"拒绝删除非会话目录"拦截。修复:① basename 提取改为按分隔符整体切分;② 根目录统一为 `/`。删除/孤儿清理恢复正常。
69
+ - **0.3.2**(2026-09-10):修两处 fork 遗留——① client 半区的模块 id 仍是 `@muwinds/dsh-archived-sessions`(未随包名改),浏览器端按 `@omdp/...` 找不到模块、设置页不显示;② 会话根目录改为从 `DSH_HOME` 环境变量推导(`<DSH_HOME>/sessions`,缺省 `~/.dsh/sessions`),不再硬编码本机路径。
68
70
  - **0.3.1**(2026-09-10):**修复 0.3.0 的发布事故**——0.3.0 的 tarball 里没有 `lib/`(仓库 `.gitignore` 的 `**/lib/` 规则把源码吞了,npm 只打包到 4 个文件),安装后插件加载失败会拖垮 DSH;0.3.1 补回 `lib/index.js` + `lib/client.js`(发布前已核对 tarball 内容)。
69
71
  - **0.3.0**(2026-09-10):fork 自 0.2.0;适配 DSH 0.1.5-rc.1(list 快照形状 + 路径自解析);按树删除子会话;孤儿清理;删除路径安全校验。
70
72
 
@@ -127,6 +129,8 @@ pnpm add @omdp/dsh-archived-sessions -w
127
129
 
128
130
  ### Changelog
129
131
 
132
+ - **0.3.3** (2026-09-10): **fixes a 0.3.2 delete regression** — 0.3.2 derived the session root from `DSH_HOME` with a **mixed-separator** path (`C:\Users\xj\.dsh/sessions/...`), and the pre-delete guard `assertSessionDirName`'s basename extraction broke on mixed separators (it sliced by `/` then by `\`, producing a truncated fragment), so every delete was rejected with "拒绝删除非会话目录". Fixed: ① basename extraction now splits on either separator; ② roots are normalized to `/`. Delete and orphan sweep work again.
133
+ - **0.3.2** (2026-09-10): fixes two fork leftovers — ① the client half's module id was still `@muwinds/dsh-archived-sessions` (not renamed with the package), so the browser could not find the module and the settings page never rendered; ② the session root is now derived from the `DSH_HOME` environment variable (`<DSH_HOME>/sessions`, falling back to `~/.dsh/sessions`) instead of a hard-coded local path.
130
134
  - **0.3.1** (2026-09-10): **fixes a 0.3.0 release accident** — the 0.3.0 tarball contained no `lib/` (the repo's `**/lib/` gitignore rule swallowed the source, so npm packed only 4 files); installing it broke the plugin load and could take DSH down. 0.3.1 restores `lib/index.js` + `lib/client.js` (tarball contents verified before publishing).
131
135
  - **0.3.0** (2026-09-10): forked from 0.2.0; DSH 0.1.5-rc.1 support (snapshot list shape + self path resolution); tree delete; orphan sweep; deletion path safety check.
132
136
 
package/lib/client.js CHANGED
@@ -1,5 +1,5 @@
1
1
  window.__ModuleLoader__.load({
2
- id: "@muwinds/dsh-archived-sessions",
2
+ id: "@omdp/dsh-archived-sessions",
3
3
  factory: (require) => {
4
4
  var module = { exports: {} };
5
5
  var exports = module.exports;
package/lib/index.js CHANGED
@@ -118,7 +118,8 @@ function dangerPolicy(ctx) {
118
118
  */
119
119
  function assertSessionDirName(dirPath) {
120
120
  const last = dirPath.replace(/[\\/]+$/, "");
121
- const name = last.slice(last.lastIndexOf("/") + 1, last.length).slice(last.lastIndexOf("\\") + 1);
121
+ const parts = last.split(/[\\/]/);
122
+ const name = parts[parts.length - 1];
122
123
  const ok = /^session-[0-9a-fA-F-]{36}$/.test(name) || /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(name);
123
124
  if (!ok) throw new Error("拒绝删除非会话目录: " + dirPath);
124
125
  }
@@ -256,8 +257,39 @@ function projectKey(cwd) {
256
257
  return `--${(readable.replace(/^-+/, "") || "root").slice(0, 251)}--`;
257
258
  }
258
259
 
259
- /** Candidate JSONL session roots, probed in order. */
260
- const CANDIDATE_ROOTS = ["C:\\Users\\xj\\.dsh\\sessions"];
260
+ /** Read an environment variable without assuming `process` exists. */
261
+ function env(name) {
262
+ try {
263
+ return typeof process !== "undefined" && process.env ? process.env[name] : undefined;
264
+ } catch (e) {
265
+ return undefined;
266
+ }
267
+ }
268
+
269
+ /**
270
+ * Candidate JSONL session roots, probed in order at call time.
271
+ *
272
+ * DSH stores every session under `<DSH_HOME>/sessions` (DSH_HOME defaults to
273
+ * `~/.dsh`), and the abstract sessionPersistence service exposes no root, so the
274
+ * location is derived from the environment rather than hard-coded — the plugin
275
+ * then works on any machine and any DSH_HOME.
276
+ */
277
+ function candidateRoots() {
278
+ const out = [];
279
+ const push = (p) => {
280
+ if (typeof p !== "string" || p.length === 0) return;
281
+ const trimmed = p.replace(/[\\/]+$/, "").replace(/\\/g, "/");
282
+ if (trimmed.length > 0 && !out.includes(trimmed)) out.push(trimmed);
283
+ };
284
+ const home = env("DSH_HOME");
285
+ if (typeof home === "string" && home.replace(/[\\/]+$/, "").length > 0) {
286
+ push(home + "/sessions");
287
+ } else {
288
+ const userHome = env("USERPROFILE") || env("HOME");
289
+ if (typeof userHome === "string" && userHome.length > 0) push(userHome + "/.dsh/sessions");
290
+ }
291
+ return out;
292
+ }
261
293
 
262
294
  /** Build one session's on-disk directory path under a candidate root. */
263
295
  function buildSessionDir(root, header) {
@@ -275,8 +307,10 @@ function buildSessionDir(root, header) {
275
307
  async function resolveSessionLocation(ctx, header) {
276
308
  const fsSvc = ctx.get("fs");
277
309
  const backend = jsonlBackend && typeof jsonlBackend.sessionDir === "function" ? jsonlBackend : null;
310
+ const roots = candidateRoots();
311
+ if (roots.length === 0) return { path: "", found: false };
278
312
  let last = null;
279
- for (const root of CANDIDATE_ROOTS) {
313
+ for (const root of roots) {
280
314
  let dirPath;
281
315
  if (backend && typeof jsonlBackend.projectDir === "function") {
282
316
  try {
@@ -611,7 +645,7 @@ async function handleOrphans(ctx) {
611
645
  } catch (e) {
612
646
  location = null;
613
647
  }
614
- if (!location) continue;
648
+ if (!location || typeof location.path !== "string" || location.path.length === 0) continue;
615
649
  const dirPath = location.path;
616
650
  let sizeBytes = 0;
617
651
  if (fsSvc) {
@@ -655,7 +689,7 @@ async function handleSweep(ctx) {
655
689
  } catch (e) {
656
690
  location = null;
657
691
  }
658
- if (!location) continue;
692
+ if (!location || typeof location.path !== "string" || location.path.length === 0) continue;
659
693
  const dirPath = location.path;
660
694
  try {
661
695
  await removeDir(ctx, dirPath);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omdp/dsh-archived-sessions",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "Archived-sessions manager for the DeepSeek Harness web UI: list / unarchive / delete / detail from Settings. · DSH 归档会话管理:设置页查看、释放、删除已归档会话(含按树删除子会话与孤儿清理)。",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",