{"_id":"@billqiu1126/dsh-workspace-hierarchy","_rev":"4-db85d38d677de90c25f5c8f7aa334259","name":"@billqiu1126/dsh-workspace-hierarchy","dist-tags":{"latest":"0.1.4"},"versions":{"0.1.0":{"name":"@billqiu1126/dsh-workspace-hierarchy","version":"0.1.0","keywords":["deepseek-harness","dsh","plugin","workspace"],"author":{"name":"Bill Qiu"},"license":"MIT","_id":"@billqiu1126/dsh-workspace-hierarchy@0.1.0","maintainers":[{"name":"billqiu1126","email":"1045046841@qq.com"}],"homepage":"https://github.com/billqiu1126/dsh-workspace-hierarchy#readme","bugs":{"url":"https://github.com/billqiu1126/dsh-workspace-hierarchy/issues"},"dsh":{"client":{"inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-sidebar"],"platform":"web"}},"dist":{"shasum":"c80749fd6a54110c48ef6f0a292398dd4bd745ee","tarball":"https://registry.npmjs.org/@billqiu1126/dsh-workspace-hierarchy/-/dsh-workspace-hierarchy-0.1.0.tgz","fileCount":8,"integrity":"sha512-hnfPQNcZos3oa5a/cnm5cwVAuBs4DIDNozLzZCxnrJpZOlmTArbTuScvW4ty4hbMeQOiZYp8dTkI9dDJ8d9lCg==","signatures":[{"sig":"MEUCIQDlWSqY2Esght2NQlGBnNQEtUjkuNJ0qPAQY7qXdTr/4wIgPUSAVJIuENaHMF9WiFDSH20dw7J5PnuUO1xHXOShbuw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":136383},"main":"lib/index.js","type":"module","exports":{".":{"default":"./lib/index.js"},"./client":{"default":"./lib/client.js"},"./package.json":"./package.json"},"gitHead":"f10859bc349d85c2796343145813a58582f2f57f","_npmUser":{"name":"billqiu1126","email":"1045046841@qq.com"},"repository":{"url":"git+https://github.com/billqiu1126/dsh-workspace-hierarchy.git","type":"git"},"_npmVersion":"10.9.8","description":"DeepSeek Harness web plugin: hierarchical workspace browser. Nests workspaces by directory path (main/sub-workspace) and adds an \"Add sub-workspace\" action to each workspace's + menu.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"clsx":"^2.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^18.2.0","@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-invariants":"^0.1.0-rc.6","@deepseek-ai/dsh-client-locale":"^0.1.0-rc.6","@deepseek-ai/dsh-client-runtime":"^0.1.0-rc.6","@deepseek-ai/dsh-client-ui-slots":"^0.1.0-rc.6","@deepseek-ai/dsh-client-ui-sidebar":"^0.1.0-rc.6","@deepseek-ai/dsh-client-ui-primitives":"^0.1.0-rc.6","@deepseek-ai/dsh-client-ui-conversation":"^0.1.0-rc.6"},"_npmOperationalInternal":{"tmp":"tmp/dsh-workspace-hierarchy_0.1.0_1786815620739_0.4026639736232571","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@billqiu1126/dsh-workspace-hierarchy","version":"0.1.1","keywords":["deepseek-harness","dsh","plugin","workspace"],"author":{"name":"Bill Qiu"},"license":"MIT","_id":"@billqiu1126/dsh-workspace-hierarchy@0.1.1","maintainers":[{"name":"billqiu1126","email":"1045046841@qq.com"}],"homepage":"https://github.com/billqiu1126/dsh-workspace-hierarchy#readme","bugs":{"url":"https://github.com/billqiu1126/dsh-workspace-hierarchy/issues"},"dsh":{"client":{"inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-sidebar"],"platform":"web"}},"dist":{"shasum":"4e7031e9c3af9de0bc8e87f8ab35aaf29ba48b1c","tarball":"https://registry.npmjs.org/@billqiu1126/dsh-workspace-hierarchy/-/dsh-workspace-hierarchy-0.1.1.tgz","fileCount":9,"integrity":"sha512-8AMO9eNtkgCyLQTM1YFYdiTkS58KdK09U9Av/IA7dC8reKsLPZautrKs/ZyA+U3rYqqg0r0yqB/DuH1+Sz4x+Q==","signatures":[{"sig":"MEUCIQCo9z9EeCshgFIDzKtm/YVu/PNyA043IAxaSpsXXwXsCAIgKKWY0kQE2pmeGD2TT0zk+kAEeNuunobpLs/WNjEZ9WE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":157000},"main":"lib/index.js","type":"module","exports":{".":{"default":"./lib/index.js"},"./client":{"default":"./lib/client.js"},"./package.json":"./package.json"},"gitHead":"03fe6825ee63a3318b97eb178f5e2584a90056c8","_npmUser":{"name":"billqiu1126","email":"1045046841@qq.com"},"repository":{"url":"git+https://github.com/billqiu1126/dsh-workspace-hierarchy.git","type":"git"},"_npmVersion":"10.9.8","description":"DeepSeek Harness web plugin: hierarchical workspace browser. Nests workspaces by directory path (main/sub-workspace) and adds an \"Add sub-workspace\" action to each workspace's + menu.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"clsx":"^2.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^18.2.0","@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-invariants":"^0.1.0-rc.6","@deepseek-ai/dsh-client-locale":"^0.1.0-rc.6","@deepseek-ai/dsh-client-runtime":"^0.1.0-rc.6","@deepseek-ai/dsh-client-ui-slots":"^0.1.0-rc.6","@deepseek-ai/dsh-client-ui-sidebar":"^0.1.0-rc.6","@deepseek-ai/dsh-client-ui-primitives":"^0.1.0-rc.6","@deepseek-ai/dsh-client-ui-conversation":"^0.1.0-rc.6"},"_npmOperationalInternal":{"tmp":"tmp/dsh-workspace-hierarchy_0.1.1_1786817232764_0.3477794994806167","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@billqiu1126/dsh-workspace-hierarchy","version":"0.1.2","keywords":["deepseek-harness","dsh","plugin","workspace"],"author":{"name":"Bill Qiu"},"license":"MIT","_id":"@billqiu1126/dsh-workspace-hierarchy@0.1.2","maintainers":[{"name":"billqiu1126","email":"1045046841@qq.com"}],"homepage":"https://github.com/billqiu1126/dsh-workspace-hierarchy#readme","bugs":{"url":"https://github.com/billqiu1126/dsh-workspace-hierarchy/issues"},"dsh":{"client":{"inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-sidebar"],"platform":"web"}},"dist":{"shasum":"4d02533e8aeb9d9bccc8f11cc2d126f16db7945f","tarball":"https://registry.npmjs.org/@billqiu1126/dsh-workspace-hierarchy/-/dsh-workspace-hierarchy-0.1.2.tgz","fileCount":9,"integrity":"sha512-dxfcPNj6BCYBzkKIBRI1hq0C0FiDEioir8F7zgYXsiEyg0VRswYKahgXdjsNZTlNNxLCYdAcMPfz1voMX7ExmA==","signatures":[{"sig":"MEUCID8cJUyEDGe8R1Q3EZo0KKix2HZPBMZyGbG1MGzt9FQuAiEA/Eq4VyM23B9pLMqJVguOLnO4aP16cvmmghbl7i0cLGg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":164213},"main":"lib/index.js","type":"module","exports":{".":{"default":"./lib/index.js"},"./client":{"default":"./lib/client.js"},"./package.json":"./package.json"},"gitHead":"f447c53b028475b13dfb84610cdc4e7a4e088e45","_npmUser":{"name":"billqiu1126","email":"1045046841@qq.com"},"repository":{"url":"git+https://github.com/billqiu1126/dsh-workspace-hierarchy.git","type":"git"},"_npmVersion":"10.9.8","description":"DeepSeek Harness web plugin: hierarchical workspace browser. Nests workspaces by directory path (main/sub-workspace) and adds an \"Add sub-workspace\" action to each workspace's + menu.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"clsx":"^2.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^18.2.0","@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-invariants":"^0.1.0-rc.6","@deepseek-ai/dsh-client-locale":"^0.1.0-rc.6","@deepseek-ai/dsh-client-runtime":"^0.1.0-rc.6","@deepseek-ai/dsh-client-ui-slots":"^0.1.0-rc.6","@deepseek-ai/dsh-client-ui-sidebar":"^0.1.0-rc.6","@deepseek-ai/dsh-client-ui-primitives":"^0.1.0-rc.6","@deepseek-ai/dsh-client-ui-conversation":"^0.1.0-rc.6"},"_npmOperationalInternal":{"tmp":"tmp/dsh-workspace-hierarchy_0.1.2_1786818117251_0.7546899752224696","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@billqiu1126/dsh-workspace-hierarchy","description":"DeepSeek Harness web plugin: hierarchical workspace browser. Nests workspaces by directory path (main/sub-workspace) and adds an \"Add sub-workspace\" action to each workspace's + menu.","version":"0.1.4","author":{"name":"Bill Qiu"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/billqiu1126/dsh-workspace-hierarchy.git"},"homepage":"https://github.com/billqiu1126/dsh-workspace-hierarchy#readme","bugs":{"url":"https://github.com/billqiu1126/dsh-workspace-hierarchy/issues"},"publishConfig":{"access":"public"},"type":"module","main":"lib/index.js","exports":{".":{"default":"./lib/index.js"},"./client":{"default":"./lib/client.js"},"./package.json":"./package.json"},"dsh":{"client":{"inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-sidebar"],"platform":"web"}},"dependencies":{"clsx":"^2.0.0"},"peerDependencies":{"react":"^18.2.0","@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-client-locale":"^0.1.0-rc.6","@deepseek-ai/dsh-client-runtime":"^0.1.0-rc.6","@deepseek-ai/dsh-client-ui-conversation":"^0.1.0-rc.6","@deepseek-ai/dsh-client-ui-primitives":"^0.1.0-rc.6","@deepseek-ai/dsh-client-ui-sidebar":"^0.1.0-rc.6","@deepseek-ai/dsh-client-ui-slots":"^0.1.0-rc.6","@deepseek-ai/dsh-invariants":"^0.1.0-rc.6"},"keywords":["deepseek-harness","dsh","plugin","workspace"],"_id":"@billqiu1126/dsh-workspace-hierarchy@0.1.4","gitHead":"ce02f861a06686d5b7937b718bb4ce3fe1f5c6f9","_nodeVersion":"22.22.3","_npmVersion":"10.9.8","dist":{"integrity":"sha512-mNVr/BMJcps9etYsEk2T37EcqDA+28vczSVk42rXhCZcfFnL6jFeKTQszSUh6bAJZd8zBGnnMf1ny9bAzG+fiQ==","shasum":"436b9ce70e15fd616de779edb65e7c19adfbb7a3","tarball":"https://registry.npmjs.org/@billqiu1126/dsh-workspace-hierarchy/-/dsh-workspace-hierarchy-0.1.4.tgz","fileCount":11,"unpackedSize":198805,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGe1b4sPPcNQRl8jqakQ9q8vY2Jkq7yUYWaSnIQoJ822AiBadbagG++MmJpBHNWR97IUPGoNiXV7xQERWXhlDcnFDw=="}]},"_npmUser":{"name":"billqiu1126","email":"1045046841@qq.com"},"directories":{},"maintainers":[{"name":"billqiu1126","email":"1045046841@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dsh-workspace-hierarchy_0.1.4_1786861631661_0.5749808615537157"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-15T17:40:20.563Z","modified":"2026-08-16T06:27:11.952Z","0.1.0":"2026-08-15T17:40:20.887Z","0.1.1":"2026-08-15T18:07:12.892Z","0.1.2":"2026-08-15T18:21:57.385Z","0.1.4":"2026-08-16T06:27:11.799Z"},"bugs":{"url":"https://github.com/billqiu1126/dsh-workspace-hierarchy/issues"},"author":{"name":"Bill Qiu"},"license":"MIT","homepage":"https://github.com/billqiu1126/dsh-workspace-hierarchy#readme","keywords":["deepseek-harness","dsh","plugin","workspace"],"repository":{"type":"git","url":"git+https://github.com/billqiu1126/dsh-workspace-hierarchy.git"},"description":"DeepSeek Harness web plugin: hierarchical workspace browser. Nests workspaces by directory path (main/sub-workspace) and adds an \"Add sub-workspace\" action to each workspace's + menu.","maintainers":[{"name":"billqiu1126","email":"1045046841@qq.com"}],"readme":"# @billqiu1126/dsh-workspace-hierarchy\n\n一个 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) Web 插件：把侧边栏工作区列表变成**多级（主 / 子工作区）树**。\n\n> [English version: README.md](./README.md)\n\n## 功能\n\n- 工作区按**目录路径包含关系**自动分层：目录位于另一个工作区目录内的，就缩进显示在它下面（支持任意层级）。\n- 只有**真正被添加为工作区**的目录才显示；`build`、`docs` 这类普通子文件夹不会被列出来。\n- 每个工作区的 **`+` 按钮变成菜单**，二选一：\n  - **新建会话** —— 在该工作区新建会话（原有行为）；\n  - **添加子工作区** —— 选择目录并注册为子工作区（只添加、不自动新建会话）。\n- 每个会话的 **`⋯` 菜单新增「删除会话」** —— 永久删除该会话及其日志（有确认对话框，不可撤销）。\n- 每个会话的 **`⋯` 菜单新增「移动会话」** —— 选择目标目录并确认后，重写该会话的 `cwd` 并重新挂到目标工作区（移动后请重启 `dsh web`）。\n- 工作区的 **`⋯` 菜单「重命名」现在会同步重命名磁盘文件夹**，并把该文件夹下的会话与子工作区一并迁移（完成后请重启 `dsh web`）。\n- 工作区的 **`⋯` 菜单「删除」现在会同步删除磁盘文件夹及其全部内容**，并移除该工作区（含其下的子工作区）注册；会话日志保留，其会话回到「未分组」。\n- 折叠主工作区时，其下的**子工作区也会一起折叠**（不再只折叠会话）。\n\n示例：\n\n```\n▼ DeepSeek-Harness                    主工作区\n    ▼ DeepSeek Harness Desktop        子工作区\n        [会话…]\n    ▼ Test Deep SeekHarness           子工作区\n        [会话…]\n    [DeepSeek-Harness 自己的会话…]\n```\n\n## 原理\n\n本包是内置工作区浏览器（`@deepseek-ai/dsh-client-ui-workspace`）的增强构建：在 `deriveGroups` 里按路径推导父子关系、给每个工作区加 `depth` 并按深度缩进，同时把工作区行的 `+` 改成菜单。因为它改的是工作区浏览器的内部渲染，所以需要**替换**内置的 `ui-workspace` 条目。\n\n「删除会话」横跨两半实现：**宿主侧**注册 `delete-session` 斜杠命令，删除会话的持久化日志并把它从所有工作区的会话账目中移除（DSH 没有「删除会话」RPC，只有归档）；**浏览器侧**在 `⋯` 菜单里加「删除会话」项来触发该命令。\n\n「删除 / 重命名工作区」同样由宿主侧命令完成：`delete-workspace` 删除磁盘文件夹并移除工作区注册，`rename-workspace` 调用 `tools/rename-workspace.js` 重命名磁盘文件夹并重写其下所有会话的 `cwd`。\n\n## 环境要求\n\n- 全局安装 `@deepseek-ai/dsh`（0.1.0-rc.x）。\n- 使用 web profile（`dsh web`，或桌面版）。\n\n## 安装\n\n两种方式**二选一**即可：\n\n### 方式 A —— 一键脚本（推荐）\n\n```bash\n# Windows（PowerShell）\n.\\install.ps1\n\n# Linux / macOS\n./install.sh\n```\n\n脚本会帮你完成「安装包」和「写入 cordis.patch.yml」两步。\n\n### 方式 B —— 手动\n\n**1.** 把包安装到 profile：\n\n```bash\ndsh plugin --profile web add @billqiu1126/dsh-workspace-hierarchy\n```\n\n**2.** 编辑 `~/.dsh/profiles/web/cordis.patch.yml`（Windows：`C:\\Users\\<你>\\.dsh\\profiles\\web\\cordis.patch.yml`），加入：\n\n```yaml\n# 停用内置工作区浏览器（由本插件替换）。\n- id: ui-workspace\n  disabled: true\n\n# 挂载多级工作区浏览器。\n- insert:\n    - id: ui-workspace-hierarchy\n      name: '@billqiu1126/dsh-workspace-hierarchy'\n```\n\n**3.** 重启 `dsh web`（或桌面版），浏览器刷新页面。\n\n## 发布到 npm\n\n```bash\nnpm publish --access public\n```\n\n## 目录结构\n\n```\n@billqiu1126/dsh-workspace-hierarchy/\n├── package.json      # dsh.client 声明、peerDependencies、exports\n├── install.ps1       # 一键安装（Windows）\n├── install.sh        # 一键安装（Linux / macOS）\n├── README.md         # 英文文档\n├── README.zh.md      # 中文文档\n└── lib/\n    ├── index.js      # 宿主侧：注册 delete-session / move-session / delete-workspace / rename-workspace 命令\n    └── client.js     # 浏览器侧（预打包 client bundle）\n└── tools/\n    ├── move-session.js     # 移动会话的迁移脚本\n    ├── rename-workspace.js # 重命名工作区目录并迁移会话的脚本\n    └── package.json        # 让 tools/*.js 以 CommonJS 运行\n```\n\n## 说明\n\n- 宿主侧提供 `delete-session` / `move-session` / `delete-workspace` / `rename-workspace` 命令，浏览器侧提供对应菜单；`dsh.client` 声明了 `platform: \"web\"` 和注入顺序。\n- 工作区层级是**只读推导**：不改动工作区数据。\n- 路径比较在 Windows 上忽略大小写；`/` 与 `\\` 均被识别为分隔符。\n- 「未分组」不是真实工作区，而是**收容不属于任何工作区的会话**的虚拟桶：它不能重命名/删除（没有对应文件夹），但它下面的会话仍可单独重命名、移动、归档、删除。\n\n## 删除会话 — 已知限制\n\n- DSH 没有「永久删除会话」RPC（只有归档），所以宿主侧直接删除 JSONL 后端的会话日志文件（`sessionPersistence.list()`/`locate()` 后 `rm`）。\n- 仍在当前进程里打开（存活）的会话：日志被删除后如果继续产生事件，日志可能被重新写入；关闭 / 重启 DSH 才能最终确定对存活会话的删除。\n- 删除通过运行 `delete-session` 命令触发，浏览器侧通过 `commands.execute` 传入会话 id。\n\n## 移动会话（菜单 + 迁移工具）\n\n移动会话有两种入口：会话 `⋯` 菜单里的 **「移动会话」**（宿主 `move-session` 命令 + 目录选择 + 确认），以及随包的低层级脚本 `tools/move-session.js`（真正执行重写）。DSH 没有「移动会话」功能（会话的 `cwd` 不可变），所以命令会调用这个脚本重写会话日志的 `cwd` 头并重新挂到目标工作区。\n\n```bash\n# 列出某工作区下的会话（找到准确的「名称」）\nnode tools/move-session.js --list \"<工作区路径>\"\n\n# dry-run（只校验、不落盘）\nnode tools/move-session.js \"<会话路径>\" \"<会话名称>\" \"<目标工作区路径>\"\n\n# 真正移动\nnode tools/move-session.js \"<会话路径>\" \"<会话名称>\" \"<目标工作区路径>\" --apply\n```\n\n需要时可用环境变量覆盖存储位置：\n\n- `DSH_SESSION_ROOT`（默认 `~/.dsh/sessions`）\n- `DSH_STORAGE_DIR`（默认 `~/.dsh/storages`）\n- `DSH_MIGRATE_BACKUP_DIR`（备份位置）\n\n脚本会校验一切、先写备份，只有加 `--apply` 才真正改动；执行后重启 `dsh web`。\n\n## 删除 / 重命名工作区（含磁盘文件夹）\n\n- **删除工作区** = 删除磁盘文件夹（`rm -r`）+ 移除该工作区及其下所有子工作区的注册。会话日志存在 DSH 数据目录下（不在工作区文件夹内），因此会被保留，其会话回到「未分组」。\n- **重命名工作区** = 把磁盘文件夹改名为新名称（`父目录/新名称`），并重写其下所有会话的 `cwd`（日志头 + 日志位置 + projcache）以及所有子工作区的 `path`；名称会在侧边栏立即更新，重启 `dsh web` 后同步会话数据。\n- **重命名工作区** 会先**关闭该文件夹下空闲（未运行）的存活会话**（flush + 卸载，其日志随后被安全重写，重启后在新位置恢复）；只有**正在运行**的会话才拒绝执行。删除工作区**不会**拦截存活会话（删除不碰日志，只是让该会话的 `cwd` 失效）。\n- 删除会拒绝文件系统根目录、用户主目录，以及包含 DSH 数据目录（`DSH_HOME`）的文件夹。\n- 重命名脚本 `tools/rename-workspace.js` 同样支持 dry-run / `--apply`，并先写备份；日志缺失的会话会被跳过（仅更新 projcache），不会中断整个重命名。\n\n```bash\n# dry-run\nnode tools/rename-workspace.js --id \"<工作区-id>\" \"<新名称>\"\n\n# 真正执行\nnode tools/rename-workspace.js --id \"<工作区-id>\" \"<新名称>\" --apply\n```\n","readmeFilename":"README.zh.md"}