在侧边面板里开终端、编辑器与文件浏览器
28.6/100
综合分
2
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/9/16 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add FleetingEcho/dsh-powerdesk该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · browser
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 78 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 86 处,展示前 69 条)
- 写入本地文件lib/index.js:427
await mkdir(staging, { recursive: true }); - 写入本地文件lib/index.js:430
await mkdir(dirname(path), { recursive: true }); - 写入本地文件lib/index.js:431
await writeFile(path, file.data); - 写入本地文件lib/index.js:433
await writeFile(join(staging, INSTALL_RECORD_FILE), `${JSON.stringify(record, null, 2)}\n`); - 写入本地文件lib/index.js:435
await rename(staging, target); - 删除本地文件lib/index.js:437
await rm(staging, { - 读取本地文件lib/index.js:742
return existsSync(join(dir, "package.json")) && existsSync(join(dir, "pnpm-workspace.yaml")); - 读取本地文件lib/index.js:747
if (!existsSync(file)) return false; - 读取本地文件lib/index.js:749
return JSON.parse(readFileSync(file, "utf8")).name === "dsh-powerdesk"; - 读取本地文件lib/index.js:844
if (existsSync(script)) return { command: `powershell -ExecutionPolicy Bypass -File "${script}" -Repair${profileArg}` }; - 读取本地文件lib/index.js:847
if (existsSync(script)) return { command: `bash "${script}" --repair${profileArg}` }; - 读取本地文件lib/index.js:1106
dirents = await readdir(abs, { withFileTypes: true }); - 写入本地文件lib/index.js:1151
await writeFile(abs, content, "utf8"); - 删除本地文件lib/index.js:1197
await rm(abs, { - 执行外部命令来自配置/变量lib/index.js:1303
execFileSync(spec, ["--version"], { stdio: "ignore" }); - 执行外部命令来自配置/变量lib/index.js:1407
const child = spawn(rg, args, { - 发起网络请求lib/index.js:1851
let response = await fetch(parsed, { - 发起网络请求lib/index.js:1856
if (response.status === 405 || response.status === 501) response = await fetch(parsed, { - 读取本地文件lib/bundle-route-C2ZilHdc.js:150
const manifest = parseManifest(JSON.parse(await readFile(join(dir, MANIFEST_FILE), "utf8")), id); - 读取本地文件lib/bundle-route-C2ZilHdc.js:151
const bundle = await stat(bundlePathOf(root, id, manifest.entry)); - 读取本地文件lib/bundle-route-C2ZilHdc.js:172
const parsed = JSON.parse(await readFile(join(dir, INSTALL_RECORD_FILE), "utf8")); - 读取本地文件lib/bundle-route-C2ZilHdc.js:193
names = (await readdir(root, { withFileTypes: true })).filter((entry) => entry.isDirectory() && isValidExtensionId(entry.name)).map((entry) => entry.n - 删除本地文件lib/bundle-route-C2ZilHdc.js:201
await rm(extensionDir(root, id), { - 读取本地文件lib/bundle-route-C2ZilHdc.js:260
const info = await stat(path); - 读取本地文件lib/bundle-route-C2ZilHdc.js:263
const etag = `"${shortHash(await readFile(path))}"`; - 发起网络请求lib/client-browser.js:26
response = await fetch(`/powerdesk/api/${method}`, { - 发起网络请求lib/client-calendar.js:4470
return fetch(url, fetchOptions).then((fetchRes) => { - 发起网络请求lib/client-calendar.js:7581
sourceDef.fetch({ - 发起网络请求lib/client-calendar.js:7806
fetch(arg, successCallback) { - 发起网络请求lib/client-calendar.js:7818
fetch(arg, successCallback, errorCallback) { - 发起网络请求lib/client-calendar.js:7847
fetch(arg, successCallback, errorCallback) { - 发起网络请求lib/client-calendar.js:8008
this.delayedRunner.request(delay); - 发起网络请求lib/client-editor.js:32466
response = await fetch(`/powerdesk/api/${method}`, { - 读取本地文件src/bundle-route.ts:74
const info = await stat(path) - 读取本地文件src/bundle-route.ts:79
const etag = `"${shortHash(await readFile(path))}"` - 读取本地文件src/bundle-route.ts:160
const body = await readFile(target) - 发起网络请求src/client/api.ts:187
response = await fetch(`/powerdesk/api/${method}`, { - 写入本地文件src/extensions/install.ts:172
await mkdir(staging, { recursive: true }) - 写入本地文件src/extensions/install.ts:175
await mkdir(dirname(path), { recursive: true }) - 写入本地文件src/extensions/install.ts:176
await writeFile(path, file.data) - 写入本地文件src/extensions/install.ts:178
await writeFile(join(staging, INSTALL_RECORD_FILE), `${JSON.stringify(record, null, 2)}\n`) - 写入本地文件src/extensions/install.ts:184
await rename(staging, target) - 删除本地文件递归src/extensions/install.ts:186
await rm(staging, { recursive: true, force: true }) - 读取本地文件src/extensions/registry.ts:101
const manifest = parseManifest(JSON.parse(await readFile(join(dir, MANIFEST_FILE), 'utf8')) as unknown, id) - 读取本地文件src/extensions/registry.ts:102
const bundle = await stat(bundlePathOf(root, id, manifest.entry)) - 读取本地文件src/extensions/registry.ts:120
const parsed = JSON.parse(await readFile(join(dir, INSTALL_RECORD_FILE), 'utf8')) as Partial<InstallRecord> - 读取本地文件src/extensions/registry.ts:142
names = (await readdir(root, { withFileTypes: true })) - 删除本地文件递归src/extensions/registry.ts:154
await rm(extensionDir(root, id), { recursive: true, force: true }) - 读取本地文件src/fs-api.ts:43
dirents = await readdir(abs, { withFileTypes: true }) - 读取本地文件src/fs-api.ts:53
size = (await stat(join(abs, dirent.name))).size - 读取本地文件src/fs-api.ts:77
info = await stat(abs) - 读取本地文件src/fs-api.ts:83
const buffer = await readFile(abs) - 写入本地文件src/fs-api.ts:92
await writeFile(abs, content, 'utf8') - 写入本地文件src/fs-api.ts:104
await writeFile(abs, '', { encoding: 'utf8', flag: 'wx' }) - 写入本地文件src/fs-api.ts:117
await mkdir(abs, { recursive: true }) - 写入本地文件src/fs-api.ts:129
await rename(absFrom, absTo) - 删除本地文件递归src/fs-api.ts:140
await rm(abs, { recursive: true, force: true }) - 读取本地文件src/fs-api.ts:177
dirents = await readdir(abs, { withFileTypes: true }) - 读取本地文件src/fs-api.ts:203
const info = await stat(abs) - 发起网络请求src/index.ts:162
let response = await fetch(parsed, { method: 'HEAD', redirect: 'follow', signal: controller.signal }) - 发起网络请求src/index.ts:166
response = await fetch(parsed, { method: 'GET', redirect: 'follow', signal: controller.signal }) - 读取本地文件src/rust-pty-deps.ts:108
return existsSync(join(dir, 'package.json')) && existsSync(join(dir, 'pnpm-workspace.yaml')) - 读取本地文件src/rust-pty-deps.ts:114
if (!existsSync(file)) return false - 读取本地文件src/rust-pty-deps.ts:116
const parsed = JSON.parse(readFileSync(file, 'utf8')) as { name?: unknown } - 读取本地文件src/rust-pty-deps.ts:239
if (existsSync(script)) { - 读取本地文件src/rust-pty-deps.ts:244
if (existsSync(script)) { - 执行外部命令来自配置/变量src/search-api.ts:95
const child = spawn(rg, args, { - 读取本地文件src/search-deps.ts:56
if (spec.includes('/') || spec.includes('\\')) return existsSync(spec) - 执行外部命令来自配置/变量src/search-deps.ts:57
execFileSync(spec, ['--version'], { stdio: 'ignore' })
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-client-locale@deepseek-ai/dsh-client-runtime@deepseek-ai/dsh-client-ui-primitives@deepseek-ai/dsh-client-ui-slots@deepseek-ai/dsh-client-web-react@deepseek-ai/dsh-host-webserver@deepseek-ai/dsh-session给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 侧边面板集成终端
- 内置代码编辑器
- 文件浏览器
展开完整介绍(145 字)↓
DSH 的 IDE 工作台插件。快速终端(restty/WebGPU 跑在 Rust PTY 上)、CodeMirror 6 编辑器、文件浏览器、markdown 笔记、沙箱浏览器、ripgrep 搜索——全都以标签页形式放在可停靠的右侧和底部面板里。还能用你自己的 React 组件扩展。
README
由 DeepSeek 最新模型翻译生成dsh-powerdesk
一个 DSH Web 插件,为 DSH 的 Web 界面加上一个小型 IDE 工作台:GPU 加速的终端、文件浏览器、笔记、代码编辑器、一个沙箱化的浏览器,以及一个日历 —— 全部自包含,置于一个可停靠的右侧面板 和一个可停靠的底部面板中(VSCode 风格的双工作台,支持拖拽分屏与跨面板拖拽)。
- 终端 —— 用 restty 渲染(WebGPU/WebGL2 + WASM VT,Ghostty 血统),后端是 Rust PTY (napi-rs + portable-pty),而非原生终端使用的 C++ node-pty。
- 文件浏览器 —— 在任意本地文件夹(通过内置文件夹浏览弹窗选取,而非文本输入框)之上呈现的目录树。点击文件即在编辑器中打开;每个文件行都有快捷的「复制相对路径」(便于在聊天中 @ 提及)和「复制绝对路径」操作。
- 笔记 —— 绑定一个本地文件夹,以递归树浏览/编辑其下的 .md 文件,支持笔记与文件夹的内联新建 / 重命名 / 删除。编辑器内嵌于同一标签页(左侧树、右侧编辑器)。
展开完整文档(README 剩余 1 节)
dsh-powerdesk 一个 DSH Web 插件,为 DSH 的 Web 界面加上一个小型 IDE 工作台:GPU 加速的终端、文件浏览器、笔记、代码编辑器、一个沙箱化的浏览器,以及一个日历 —— 全部自包含,置于一个可停靠的右侧面板 和一个可停靠的底部面板中(VSCode 风格的双工作台,支持拖拽分屏与跨面板拖拽)。 - 终端 —— 用 restty 渲染(WebGPU/WebGL2 + WASM VT,Ghostty 血统),后端是 Rust PTY (napi-rs + portable-pty),而非原生终端使用的 C++ node-pty。 - 文件浏览器 —— 在任意本地文件夹(通过内置文件夹浏览弹窗选取,而非文本输入框)之上呈现的目录树。点击文件即在编辑器中打开;每个文件行都有快捷的「复制相对路径」(便于在聊天中 @ 提及)和「复制绝对路径」操作。 - 笔记 —— 绑定一个本地文件夹,以递归树浏览/编辑其下的 .md 文件,支持笔记与文件夹的内联新建 / 重命名 / 删除。编辑器内嵌于同一标签页(左侧树、右侧编辑器)。 - 编辑器 —— CodeMirror 6,支持 TS/JS/Python/JSON/CSS/HTML/Markdown/Rust/YAML 语法高亮、可选择的 CodeMirror 主题(默认 Dracula)、软换行、Cmd/Ctrl+S 保存。在文件浏览器或笔记中点击文件时自动打开。 - 浏览器 —— 地址栏背后的沙箱 iframe,带有可嵌入性探测,能解释 X-Frame-Options / frame-ancestors 拒绝原因,而不是显示空白的「拒绝连接」框。 - 日历 —— schedule-x 日历(月 / 周 / 日视图),基于一个本地 SQLite 数据库(一个全新的 Rust napi 模块,内置 SQLite,与 PTY crate 同级);懒加载,绝不在启动时拖慢性能。事件持久化在 /powerdesk-calendar.db。 这六个功能都以标签页形式出现在插件自有的侧边栏中 —— 一个右侧面板(宽度自由拖拽、无上限)和一个底部面板(高度可拖拽,横向铺满整个窗口宽度,包括右侧面板下方)。 Powerdesk 工作台:右面板与底面板,含终端、文件浏览器、笔记、编辑器、浏览器标签页 为何选择 Powerdesk 1. 真正快的终端 —— restty(WebGPU/WebGL2 + WASM VT,Ghostty 血统)渲染于 Rust PTY(napi-rs + portable-pty)之上,而非原生终端使用的 C++ node-pty —— 终端 I/O 显著更快、更轻量。 2. 不离开聊天的完整 IDE —— ripgrep 内容搜索、CodeMirror 6 编辑器、文件浏览器、笔记、沙箱浏览器,全部作为标签页置于可停靠的右面板 + 底面板中。无需上下文切换离开 DSH 页面。 3. 双面板 VSCode 风格工作台 —— 把任意标签页拖到面板边缘即可分屏,或在右/底面板之间整体迁移;两棵分屏树共享同一套拖拽系统。 4. 零构建安装 —— lib/ 与 macOS / Linux-x64 的 Rust PTY 二进制均已提交,dsh plugin add 只是拷贝文件:无构建步骤、无需 Rust 工具链、无需 allowBuilds 条目。 5. 打造你自己的标签页 —— 把一个 React 组件加 powerdesk.json 打包成 .tgz,即挂载为侧边栏标签页;模板(templates/extension/)让你几分钟内 pnpm pack 出成品。 6. 默认沙箱化 —— 浏览器标签页不带 allow-same-origin 运行,拒绝回环地址,并探测 X-Frame-Options / frame-ancestors 以解释拒绝原因,而非显示空白框。 快速安装 dsh plugin --profile web add https://github.com/FleetingEcho/dsh-powerdesk.git 需要 DSH >=0.0.1,且 dsh CLI 在 PATH 中。安装后硬刷新浏览器(Cmd/Ctrl+Shift+R)。终端在 macOS(两种架构)与 Linux x86_64 上开箱即用;其它平台首次使用时构建一次 Rust PTY(见安装)。 环境要求 - DSH >=0.0.1,且 dsh CLI 在 PATH 中(dsh --version)。加载进某个 DSH profile(默认 web)。 - Node.js 20+ 和 pnpm 9+(若从源码安装)。 - Rust 工具链(rustup)—— 仅当你的平台还没有已提交的预编译二进制时才需要;macOS 用户永远不需要 Rust。 PTY 插件按平台三元组查找(src/rust-pty-deps.ts)。三个三元组已有已提交到仓库的二进制,随每次安装分发;其余平台首次使用时从源码构建: | 操作系统 | 架构 | 三元组 | 预编译? | | macOS | Apple Silicon | darwin-arm64 | ✅ 已提交 | | macOS | Intel | darwin-x64 | ✅ 已提交 | | Linux | x86_64 (glibc) | linux-x64-gnu | ✅ 已提交 | | Linux | aarch64 (glibc) | linux-arm64-gnu | 从源码构建 | | Windows | x86_64 | win32-x64-msvc | 从源码构建 | | Windows | ARM64 | win32-arm64-msvc | 从源码构建 | 安装 只选一种 —— 不要同时启用两个通道(会让 host 半边双重挂载并渲染出两个侧边栏)。目前没有发布 npm 包,两个通道都直接从 GitHub 仓库安装。 方式 A —— 从 GitHub(推荐) dsh plugin --profile web add https://github.com/FleetingEcho/dsh-powerdesk.git 仓库是公开的,因此普通 HTTPS URL 即可匿名安装。pnpm 会从仓库里读出包名,不需要 dsh-powerdesk@ 前缀 —— 不过 dsh-powerdesk@ 可用来锁定分支或标签(...git#my-branch)。偏好 SSH?git+ssh://git@github.com/FleetingEcho/dsh-powerdesk.git 也可以(需要 GitHub 上已注册 SSH key)。 lib/(构建好的 client/host JS)与 macOS / Linux-x64 的 Rust PTY 二进制都已提交,因此无构建步骤、无需 allowBuilds —— 终端在这些平台上立即可用。 Windows 或 Linux ARM64:构建一次 Rust PTY cd ~/.dsh/profiles/web/node_modules/dsh-powerdesk pnpm build:rust # 需要 Rust 工具链(rustup);cargo build --release 方式 B —— 从源码(用于开发) git clone https://github.com/FleetingEcho/dsh-powerdesk.git cd dsh-powerdesk pnpm install pnpm build # tsc (lib/types) + tsdown (lib/.js + 懒加载 chunk) pnpm build:rust # cargo build --release → prebuilt//dsh_powerdesk_pty.node pnpm test # vitest(可选自检) 把本地 checkout 注册到你的 DSH profile。 用绝对路径(link:. 相对于 profile 目录解析会损坏): dsh plugin --profile web add "dsh-powerdesk@link:$PWD" 任一方式之后:硬刷新浏览器(Cmd/Ctrl+Shift+R)。客户端半边改动热重载无需重启 DSH;host 半边改动(src/.ts,含 Rust PTY 层)需重启 DSH(pm2 restart dsh-web,或 dsh web)。 使用 点击窗口右上角的切换按钮簇 —— 一个打开/折叠右面板,另一个控制底面板。把标签页拖到面板边缘即可分屏,拖到中心则合并/重排,从一个面板拖到另一个则整体迁移。每个打开的标签页在非活动时都保持挂载,因此切换标签页不会丢掉终端的连接或编辑器的撤销历史。 终端 在当前会话的工作目录打开;每个会话可开多个终端,直到配置的配额上限(标签页标题显示序号:Terminal 1、Terminal 2、…)。工具栏有复制按钮。字体家族 / 字重 / 大小与终端主题是持久化偏好 —— 在「设置 → Powerdesk」编辑。如果原生 PTY 二进制缺失或加载失败,终端会显示带修复命令的修复横幅(见修复)。 文件浏览器 点击头部的文件夹名按钮打开文件夹浏览弹窗(逐级点入子目录,「选择此文件夹」)。可添加多个文件夹书签并从同一按钮切换。点击目录行展开,点击文件行即在编辑器中打开(打开文件会自动把文件浏览器分到独立面板一次,避免编辑器叠在上面)。悬停文件行显示:@ 复制相对于书签根的路径(便于 @ 提及),另一个复制图标复制绝对路径。 笔记 首次使用会提示绑定一个文件夹(随时可点击文件夹名重新绑定)。笔记递归列出该文件夹下所有 .md / .markdown 文件 —— 子树中不含 markdown 的目录会被整枝剪掉 —— 并在树(左)旁呈现内联编辑器(右,可经分隔条调节),两者同处一个标签页。头部操作:新建笔记、新建文件夹;每个文件的操作(悬停):重命名、删除(删除文件夹是递归的)。 编辑器 不直接打开 —— 它是文件浏览器和笔记打开文件的目标。基于 CodeMirror 6,支持 TypeScript/JavaScript、Python、JSON、CSS、HTML、Markdown、Rust、YAML 语法高亮;可选择的 CodeMirror 主题(默认 Dracula),在「设置 → Powerdesk」选择,并对已打开的编辑器即时生效(auto 跟随应用明暗模式)。软换行;Cmd/Ctrl+S 写回。有未保存编辑时标签页显示一个脏点。 浏览器 在地址栏输入 URL 回车。地址栏上有后退 / 前进 / 刷新 / 在浏览器中打开按钮。 - 沙箱 —— iframe 不带 allow-same-origin 运行(被访问页面无法读取 GUI 的存储或访问其 API),也不带 allow-top-navigation。一个临时解锁按钮会为可信站点放下沙箱;沙箱关闭时红色状态条告警。 - 地址栏 —— 只接受 http/https;javascript:、data:、file: 被拒绝。回环地址(localhost、127.0.0.0/8、::1、0.0.0.0)被拒绝,以免被浏览页面探测本地服务。 - 嵌入拒绝 —— 当站点设置 X-Frame-Options / 不允许 的 frame-ancestors CSP 时,插件会先探测 header,并显示带「在浏览器中打开」和「强制加载」的原因面板,而非空白框。这是浏览器层面强制的、按站点的限制;「在浏览器中打开」是从这里查看此类站点的唯一方式。 - 外链 —— 浏览器标签页认领 http:// 外链点击(聊天中点 http 链接在侧边栏打开);https:// 留给系统浏览器。 日历 一个 schedule-x 日历(月 / 周 / 日视图),基于本地 SQLite 数据库。点击「新建事件」创建(标题经提示输入),拖拽即可移动/调整时长,点击事件确认删除。数据库位于 /powerdesk-calendar.db,事件在重启与插件更新后仍保留。该标签页为懒加载 —— schedule-x 及其 preact 运行时仅在首次打开时下载,绝不在启动时加载 —— 当平台缺失 SQLite 原生二进制时,标签页降级为修复横幅。 设置 「设置 → Powerdesk」为每种标签类型显示一张带启用开关的卡片 —— 关闭某标签类型会把它从每个面板的 + 菜单隐藏,并使 openTab 对它空操作(持久化在 localStorage)。点击卡片主体即打开该功能面。 设置 → Powerdesk:每种标签类型一张卡片,各带启用开关 卡片下方是一个外观区块,包含终端的字体家族 / 字重 / 大小,以及两个主题选择器 —— 终端主题与Codemirror 主题 —— 各带「系统默认」选项以跟随应用明暗模式。任一更改都会即时应用到已打开的终端 / 编辑器。 设置 → Powerdesk:外观面板,含终端主题与 Codemirror 主题选择器 更新 方式 A(GitHub 通道)—— pnpm 固定已解析的 commit,升级需移除再添加: dsh plugin --profile web remove dsh-powerdesk dsh plugin --profile web add https://github.com/FleetingEcho/dsh-powerdesk.git 方式 B(源码)—— 拉取、重建,仅在改了 host 半边时重启: git pull && pnpm install && pnpm build && pnpm build:rust 然后硬刷新浏览器。host 半边改动需重启 DSH;客户端半边只需硬刷新。 卸载 dsh plugin --profile web remove dsh-powerdesk 源码通道:还需回退你加到 profile 的 link: 依赖,再 pnpm install。 硬刷新(或重启 DSH)让挂载行消失。 修复 如果终端显示 "Rust PTY loading failed" —— 即原生 PTY 二进制缺失、损坏或为错误平台构建 —— 就地重建(无需重装): cd ~/.dsh/profiles/web/node_modules/dsh-powerdesk # GitHub 通道 — 或你的本地 dsh-powerdesk checkout # 源码通道 pnpm build:rust # 需要 Rust 工具链(rustup) 然后硬刷新并重启 DSH(host 半边启动时重新读取二进制)。 安装排错 插件安装但未加载 —— 检查 bundle 行是否已添加;dsh.profile.bundles 必须在依赖旁列出 dsh-powerdesk: cat ~/.dsh/profiles/web/package.json 如果依赖在但 bundle 行不在,插件就以普通依赖挂载、永不加载 —— 这是损坏的 link: 安装的症状(见方式 B 注释);用绝对路径或「安装 → 方式 A」的 git URL 重新添加。host 半边改动只在 DSH 重启后生效。 配置 插件配置(在 dsh.profile.bundles 中) dsh-powerdesk: terminalsPerSession: 3 # 每个会话的最大活动终端数 reconnectGraceMs: 30000 # 掉线的 pty 保持这么久以便重连 shell: '' # 覆盖交互式 shell('' 则自动探测) extensionsEnabled: false # 允许用户安装扩展(见「扩展」) extensionsDir: '' # 扩展存放位置('' = ~/.dsh/powerdesk/extensions) 用户偏好(localStorage,无 host 往返) | 偏好 | 存储 key | 说明 | | 终端字体家族 / 字重 / 大小 / 主题;CodeMirror(编辑器)主题 | dsh-powerdesk:prefs | 在「设置 → Powerdesk」(外观)中编辑。 | | 文件浏览器文件夹书签 | dsh-powerdesk:explorer-bookmarks | 多个书签及当前活动项。 | | 笔记绑定文件夹 | dsh-powerdesk:notes-folder | 单个文件夹,可重绑。 | | 笔记树列宽 | dsh-powerdesk:notes-tree-width | 经分隔条拖拽。 | | 每种标签类型的开关 | dsh-powerdesk:tabs-enabled | 从设置卡片设置。 | 环境变量 | 变量 | 用途 | | DSH_POWERDESK_PTY_PATH | 指向 .node 插件的绝对路径;优先级高于一切解析。 | | DSH_POWERDESK_PTY_TRIPLE | 覆盖探测到的平台三元组(如 linux-x64-musl)。 | | DSH_RESTTY_SHELL | 覆盖 Windows shell 探测(默认:PATH / 已知安装目录中第一个 pwsh.exe,否则 powershell.exe)。 | | PREBUILT_BASE | 覆盖预编译二进制下载基 URL(默认:GitHub releases)。 | | DSH_HOME | 覆盖 DSH home(默认 ~/.dsh)。 | | DSH_CMD | 覆盖 install.sh 使用的 dsh CLI(默认:dsh,然后 npx)。 | 扩展 Powerdesk 可以把你自己的 React 组件挂载为侧边栏标签页。一个扩展就是一个打包脚本加一份 powerdesk.json 清单,以 .tgz 从设置卡片上传。 安全 —— 先读这一段 扩展运行在 DSH 页面自身的 origin 内,对 DOM、你的会话和网络有完全访问权 —— 与 Powerdesk 自身特权相同。没有沙箱(且在扩展共享 host 的 React 实例的前提下也不可能存在)。这是一个可信本地扩展功能,不是市场:只安装你读过代码或信任作者的代码。该功能默认关闭 —— 有意开启: dsh-powerdesk: extensionsEnabled: true 安装 / 移除 设置 → Powerdesk → 扩展 → 上传扩展… 接受的上传(按字节而非文件名判定):.tgz / .tar.gz / .tar(根目录必须含 powerdesk.json),或裸 .js / .js.gz(卡片询问 id 和显示名)。每个扩展原子安装到 //;卡片显示磁盘路径和来源归档的 sha256。移除 删除该目录;想不卸载就禁用,用其卡片上的开关。 编写 cp -r templates/extension ~/my-extension cd ~/my-extension && pnpm install $EDITOR powerdesk.json # 选一个 id 和标题 pnpm build && pnpm pack # -> my-extension-0.0.0.tgz 组件契约、清单参考及扩展加载机制见 templates/extension/README.md。不要打包 React —— 它是外部的,host 把它自己的实例传给你;第二份 React 有自己的 hook dispatcher,你调用的每个 hook 都会抛错。 限制: 上传 16 MiB,解压后归档 32 MiB,每归档 64 文件,每文件 8 MiB。含符号链接、硬链接、设备节点、绝对路径或 .. 段的归档在解析时即被拒。 开发 pnpm install pnpm build # tsc (lib/types) + tsdown (lib/.js + 懒加载 chunk) pnpm build:rust # cargo build --release → prebuilt//dsh_powerdesk_pty.node pnpm typecheck # tsc --noEmit pnpm test # vitest run pnpm watch # tsdown --watch(保存时重建 bundle) Rust crate(rust/)使用 napi-rs + portable-pty。restty 与 CodeMirror 住在懒加载 chunk(lib/client-terminal.js、lib/client-editor.js)里,首次使用时拉取,保持初始 bundle 较小(约 196 KB)。 lib/ 与 prebuilt/ 是提交进仓库的,而非 gitignore —— GitHub 安装通道是纯文件拷贝、无构建步骤,所以 git 里是什么,安装的就是什么。任何源码改动后,运行 pnpm build(Rust 层改了则加 pnpm build:rust)并提交结果再 push,否则 GitHub 安装会静默发布陈旧代码。Sourcemap(lib/*/.map)保持 gitignore。 鸣谢 受 DSH-better-sidebar 启发 —— 衷心感谢其作者提供的面板 / 停靠布局,以及 Powerdesk 所依托的侧边栏外壳基础。Powerdesk 在那一基础之上成长为自有的插件架构,以性能优先的终端(restty 渲染器 + Rust PTY)重新设计,并从零构建了分屏树 / 文件 / 笔记 / 编辑器 / 浏览器 / 扩展各功能面。 许可证 MIT。
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
FleetingEcho/dsh-powerdesk
在侧边面板里开终端、编辑器与文件浏览器
相关插件 · 浏览器
智能体插件框架deepseek-ai/deepseek-harness
DeepSeek Harnessdsh是由 DeepSeek AI 开发的开源 agent harness智能体框架。
★ 270,422已汉化DSH
71.9
多设备 Agent 看板YaoApp/yao
✨ 所有 Agent 和工作区集中管理,覆盖你的每一台设备。任务看板追踪进度,桌面端、移动端、浏览器、API…
★ 8,147已汉化DSH
71.2
可扩展侧边栏工作台omdsh-dev/DSH-better-sidebar
DSH 的双工作台:原生右侧栏 + 自绘底部面板,并把 ctx.betterSidebar 服务开放给所有插件
★ 4,761已汉化DSH
71.1
浏览器自动化桥Tencent/BrowserSkill
你的 Agent。你的浏览器。连接,就能协作。
★ 9,967已汉化DSH
71
AI 小说创作工作台EthanYoQ/AI-Novel-Writer
AI 小说作家 / AI Novel Writer
★ 1,591已汉化DSH
70.7
智能体浏览器引擎platonai/Browser4
DeepSeek Harness 集成
★ 1,175已汉化DSH
70.4
这是你的仓库?认领条目