{"_id":"@bit-ark/dsh-archive","_rev":"5-5d7325ab1192edc05fc16cac8a98f806","name":"@bit-ark/dsh-archive","dist-tags":{"latest":"0.2.1"},"versions":{"0.1.0":{"name":"@bit-ark/dsh-archive","version":"0.1.0","_id":"@bit-ark/dsh-archive@0.1.0","maintainers":[{"name":"duan-liang","email":"git@duanliang.com.cn"}],"dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"platform":"web"}},"dist":{"shasum":"98dff65319c6d1393805e2041615ad955a116bee","tarball":"https://registry.npmjs.org/@bit-ark/dsh-archive/-/dsh-archive-0.1.0.tgz","fileCount":7,"integrity":"sha512-GGoYBjZ0lG3TFMAe/GELh0vOdIHTMOLssW/kegtc6kUiWXzZ0V9Hdl/2gxA/u3gEuSjZJ1/6ZOqCM/dHhq8Dxw==","signatures":[{"sig":"MEQCIEanoy9qsk7OzSJwfli1mhVeSEaTAOj9O14uKWw9cIkKAiBQoi34M4xfoxch8dAb5jXTFmkdAR8jqs5Twj3XyF6ujA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":122484},"main":"lib/index.js","type":"module","exports":{".":"./lib/index.js","./client":"./lib/client.js","./package.json":"./package.json"},"gitHead":"15b5d933965db746722b4e11838fb7a54b1ece9b","scripts":{"build":"node build.mjs"},"_npmUser":{"name":"duan-liang","email":"git@duanliang.com.cn"},"_npmVersion":"12.0.2","description":"Adds a 归档 (Archive) tab after the Trajectory tab: lists the current project's archived sessions with restore (unarchive) and hard delete.","directories":{},"_nodeVersion":"24.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"esbuild":"^0.25.0"},"_npmOperationalInternal":{"tmp":"tmp/dsh-archive_0.1.0_1787031868990_0.280739100889537","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@bit-ark/dsh-archive","version":"0.1.1","_id":"@bit-ark/dsh-archive@0.1.1","maintainers":[{"name":"duan-liang","email":"git@duanliang.com.cn"}],"dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"platform":"web"}},"dist":{"shasum":"bb0d26b4dca165bfe611b5720380fef173bdabb8","tarball":"https://registry.npmjs.org/@bit-ark/dsh-archive/-/dsh-archive-0.1.1.tgz","fileCount":7,"integrity":"sha512-LBw/G8o4yZ+nA6MEuUETsN3atkiWIJwEO4L97ou9JTzOLyfr95Fvz6m7HgHxA7EHHRPPuSXlWQ03ktr3gWj27Q==","signatures":[{"sig":"MEYCIQDAhZN6cqnr2OCaoulCDZqYld0EzAVwn9l0/86CDZKXzQIhAInkuT1F/hhIvQs+8GoIuF7DT3KeuWmeEdVYI9gPnd41","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":119403},"main":"lib/index.js","type":"module","exports":{".":"./lib/index.js","./client":"./lib/client.js","./package.json":"./package.json"},"gitHead":"d29c4d0706a6c4d0d1ca2ebe583e2ddc90d1985d","scripts":{"build":"node build.mjs"},"_npmUser":{"name":"duan-liang","email":"git@duanliang.com.cn"},"_npmVersion":"12.0.2","description":"Adds a 归档 (Archive) tab after the Trajectory tab: lists the current project's archived sessions with restore (unarchive) and hard delete.","directories":{},"_nodeVersion":"24.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"esbuild":"^0.25.0"},"_npmOperationalInternal":{"tmp":"tmp/dsh-archive_0.1.1_1787049582199_0.3810293256566444","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@bit-ark/dsh-archive","version":"0.1.2","_id":"@bit-ark/dsh-archive@0.1.2","maintainers":[{"name":"duan-liang","email":"git@duanliang.com.cn"}],"dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"platform":"web"}},"dist":{"shasum":"ec32e4529447a12dd28ef08afaf96561f783c0d8","tarball":"https://registry.npmjs.org/@bit-ark/dsh-archive/-/dsh-archive-0.1.2.tgz","fileCount":7,"integrity":"sha512-NSlIBh+44FK3dA0/N9OwkFYlx5IRkRe/KcPDj13Bxs/DIAm/zD8HcsH0QjFuMM7EKtjD0YIU/oBGNJ4fhz17Dw==","signatures":[{"sig":"MEQCIBFDiCDHJjsrqrxyll0qVjXKXYc3KY7HwuW+pBLjdKHmAiBsFscjQHBakBqw7ayUxQqR7KqGoCoxsRdpt4ga8qAPZQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":128587},"main":"lib/index.js","type":"module","exports":{".":"./lib/index.js","./client":"./lib/client.js","./package.json":"./package.json"},"gitHead":"412baafaac609c83b77a13087a0b0e04f33a00c3","scripts":{"build":"node build.mjs"},"_npmUser":{"name":"duan-liang","email":"git@duanliang.com.cn"},"_npmVersion":"12.0.2","description":"Adds a 归档 (Archive) tab after the Trajectory tab: lists the current project's archived sessions with restore (unarchive) and hard delete.","directories":{},"_nodeVersion":"24.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"esbuild":"^0.25.0"},"_npmOperationalInternal":{"tmp":"tmp/dsh-archive_0.1.2_1787061428214_0.05569099032373814","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@bit-ark/dsh-archive","version":"0.2.0","_id":"@bit-ark/dsh-archive@0.2.0","maintainers":[{"name":"duan-liang","email":"git@duanliang.com.cn"}],"dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"platform":"web"}},"dist":{"shasum":"aa3a1e7914e1a259150eff2bb9f13d94b1aa989a","tarball":"https://registry.npmjs.org/@bit-ark/dsh-archive/-/dsh-archive-0.2.0.tgz","fileCount":7,"integrity":"sha512-Ti2rX05c/AYWydHLuLaXCixN698IbkcLQswDYJRR+KobaMkXr+fbMxVkkGDQS+JDCtlRkL6ozmuqVHzTOf1ABw==","signatures":[{"sig":"MEUCIQC7pe8xCuTQlzPSaVb1mZ1hLUC2rhY6BJWOPRbdHtHgLgIgVCx686ffRUq3phAMYKuecEoMEhSZqFBJULMv2w3Lr5c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":112894},"main":"lib/index.js","type":"module","exports":{".":"./lib/index.js","./client":"./lib/client.js","./package.json":"./package.json"},"gitHead":"ff7bb821e646d58150e9067dea2949b7af2885a6","scripts":{"build":"node build.mjs"},"_npmUser":{"name":"duan-liang","email":"git@duanliang.com.cn"},"_npmVersion":"12.0.2","description":"Adds a 归档 (Archive) tab after the Trajectory tab: lists the current project's archived sessions with restore (unarchive) and hard delete.","directories":{},"_nodeVersion":"24.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"esbuild":"^0.25.0"},"_npmOperationalInternal":{"tmp":"tmp/dsh-archive_0.2.0_1787390684822_0.8151857136104503","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@bit-ark/dsh-archive","version":"0.2.1","description":"Adds a 归档 (Archive) tab after the Trajectory tab: lists the current project's archived sessions with restore (unarchive) and hard delete.","type":"module","main":"lib/index.js","exports":{".":"./lib/index.js","./client":"./lib/client.js","./package.json":"./package.json"},"scripts":{"build":"node build.mjs"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"platform":"web"}},"devDependencies":{"esbuild":"^0.25.0"},"publishConfig":{"access":"public"},"gitHead":"87d43b8210e74260e860e666bf5535eddf285a6d","_id":"@bit-ark/dsh-archive@0.2.1","_nodeVersion":"24.19.0","_npmVersion":"12.0.2","dist":{"integrity":"sha512-heTlzzul+EkAeuDolFDhX0CLkGMV9xSd2+26o1BKhY484iCCsF3Utcs9CRieKoaMqeFd8vIXP2eq6d3dvbVV6g==","shasum":"b7155030b2cdf94c19865da13ebcf4a4177e0150","tarball":"https://registry.npmjs.org/@bit-ark/dsh-archive/-/dsh-archive-0.2.1.tgz","fileCount":7,"unpackedSize":112914,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEpt3GV+XUHydlyZsMGY4lu25VN1rj/DpE0yG2Tb1MelAiEA0XwLFchCr4QOxniW0B4BcRHcysT7GOMREJmQlcI9+Io="}]},"_npmUser":{"name":"duan-liang","email":"developer@duanliang.com.cn"},"directories":{},"maintainers":[{"name":"duan-liang","email":"developer@duanliang.com.cn"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dsh-archive_0.2.1_1787894117976_0.7829047248131231"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-18T05:44:28.875Z","modified":"2026-08-28T05:15:18.390Z","0.1.0":"2026-08-18T05:44:29.135Z","0.1.1":"2026-08-18T10:39:42.357Z","0.1.2":"2026-08-18T13:57:08.353Z","0.2.0":"2026-08-22T09:24:44.995Z","0.2.1":"2026-08-28T05:15:18.124Z"},"description":"Adds a 归档 (Archive) tab after the Trajectory tab: lists the current project's archived sessions with restore (unarchive) and hard delete.","maintainers":[{"name":"duan-liang","email":"developer@duanliang.com.cn"}],"readme":"# dsh-archive\n\n为 DeepSeek Harness Web GUI 的设置面板增加「归档」页（`settings.section` 官方插槽的\n一个 list 条目 = 设置左侧导航菜单项 + 整页内容区）。\n\n归档是项目级管理（workspace 浏览器右键「归档会话」→ 会话消失；恢复 → 会话回到\n列表），放在设置面板的独立页面而不是会话区的 tab（会话 tab 行是 session 作用域\n的视图，作用域不匹配，且没有打开会话时不可达）；侧边栏 footer 因此腾给了\n「DeepSeek 账户」小部件（dsh-balance）。\n\n- **入口**：设置面板左侧导航的「归档」菜单项（order 30）。页面打开时渲染当前\n  项目全部已归档会话；切换设置 section 或关闭设置面板后页面卸载，再进来是干净的\n  新页面（结果提示随之清除）。\n- **列表**：只显示当前项目的已归档会话——归档会话属于当前项目当且仅当它在该项目的\n  workspace 记账中，或其存储 cwd 等于项目路径。当前项目解析不依赖打开的会话：\n  最近活跃 workspace → 当前会话所属 workspace → 当前会话 cwd 对应的 workspace。\n- **恢复**：把会话从全局归档集合移除（侧边栏「归档会话」的逆操作），会话回到侧边栏原位置。\n- **删除**：硬删除——删除会话日志目录（`~/.dsh/sessions/<项目>/<会话>/`）、解除\n  workspace 记账、移出归档集合，并尽力清理投影缓存行。正在运行（live）的会话\n  会被拒绝（中文 409 提示）。注意：**归档不会结束会话**——「live」指会话对象\n  仍挂在进程内存的 SessionStore 里，harness 没有公开的强制结束会话 API（UI 的\n  停止/关闭会话都只取消当前 turn），会话会一直 live 到 `dsh web` 进程重启为止；\n  因此删除被拒绝时提示「重启 dsh web 后再删除」。\n- **下载**：每行「下载」按钮对接 harness 核心端点 `/api/session.export`，把该会话\n  日志作为 ZIP 通过浏览器下载管理器导出；下载状态存本插件私有 store，行空闲渲染\n  不丢状态（下载中 → 成功 / 失败重试）。\n- **一键删除**：页面底部按钮，确认后把当前项目全部已归档会话一次性批量硬删除——\n  复用单删的同一套步骤（逐会话），运行中的会话跳过、单个硬错误不中断整批。\n  **总是显示完整结果提示**（已删除 / 跳过运行中 / 失败 + 明细），跳过时列出被跳过\n  的会话 id 并解释「重启 dsh web 后可删除」；提示随页面卸载清除，重进干净。\n  删除动作保留点击时的 `window.confirm` 二次确认。\n\n## 结构\n\n```\nsrc/index.ts              宿主半：POST /dsh-archive/restore | /delete | /delete-all\nsrc/client/index.tsx      客户端半：settings.section slot 注册（id: dsh-archive, order: 30）\nbuild.mjs                 esbuild 构建（lib/index.js + lib/client.js 工厂包装）\ncordis.patch.yml          自带组合层：插入 dsh-archive 行\n```\n\n## 构建\n\n```sh\npnpm install   # 首次（仅 esbuild）\npnpm build     # 修改 src/ 后重新构建 lib/\n```\n\n## 安装（已完成则跳过）\n\n在 deepseek-harness checkout 目录执行（插件已发布到 npm，按名安装即可）：\n\n```sh\npnpm dsh plugin --profile web add @bit-ark/dsh-archive\n```\n\n该命令从 npm 拉取包并挂进 `~/.dsh/profiles/web`（依赖与 `dsh.profile.bundles`\n由 `dsh plugin` 自动维护），之后每次 `pnpm dsh web` 启动都会加载本插件。\n\n## 生效方式\n\n- 宿主半改动：重建后重启 `pnpm dsh web`。\n- 客户端半改动：`pnpm build` 后刷新页面即可（重启更稳妥）。dev:web watcher\n  不覆盖树外插件，属预期行为。\n\n## 删除的步骤顺序（防脏状态）\n\n`/delete` 与 `/delete-all` 共用同一个逐会话删除核心。步骤刻意排序为：只读校验\n（live 检查、日志目录定位与目录名守卫）→ registry 域写入（unarchive → 逐个\nworkspace detach，单次失败收集警告不中断）→ 最后才 `rm` 删除文件目录 → 尽力\n清理投影缓存。这样写链 503 或任何校验失败都会在任何破坏性操作之前中止，不会出现\n「文件已删但归档集合还残留」的半删除状态。该流程并非跨域事务，仍非原子，但任何\n失败都停在可恢复状态。\n\n`/delete-all` 在单个会话上的语义与单删一致，但批量语义是「能删多少删多少」：\nlive 会话计入跳过（不拒绝整批，被跳过的 id 随 `skippedIds` 返回），其他硬错误\n计入失败明细并继续处理剩余会话；id 列表去重保序、上限 500 个。客户端在调用前\n先用 `window.confirm` 二次确认，随后总是把完整结果（已删除 / 跳过 / 失败 +\n明细）写入页面提示区（随页面卸载清除）。\n\n## 通用性说明\n\n- 插件只消费 harness 的公开服务（`webServer` / `workspaceRegistry` 的公开面 /\n  `sessionPersistence` / `sessions` / 客户端各 store 与 slot）。\n- 「恢复」需要 registry 的运行时私有写链（harness 无公开 unarchive API）。\n  成员经特性探测，若未来 harness 改名，接口返回 503 并提示，绝不猜测性写入——\n  这是本插件对 harness 内部实现的唯一触碰点。\n- 「下载」对接 harness 核心端点 `/api/session.export`，与 session-log-download\n  插件无关；本部署未装载 session-log-download，其会话头按钮位由 notifier 铃铛占据。\n\n## 已知边界\n\n- 已归档但所属 workspace 已删除的\"孤儿\"会话（目录不存在）不属于任何项目，\n  任何项目的归档页都不会显示它们；重新注册原目录为 workspace 后即可管理。\n- session-query-sqlite 在本部署为 `openAt: never` 的纯内存索引，无磁盘残留，\n  故不处理；若部署改为持久索引，需要在此补充清理。\n","readmeFilename":"README.md"}