在手机上管理云端项目,让智能体改代码扩功能
30.7/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/14 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查未通过:缺少 main/exports/bin 入口声明;engines.node 要求 >=24,不满足 Node 22.19.0;仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add H2O-YAOZE/dsh-mobile-workbench该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · ui
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 21 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装缺少 main/exports/bin 入口声明;engines.node 要求 >=24,不满足 Node 22.19.0;仓库 package.json 标记 private,未发布到 npm,需从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包dsh-mobile-workbench(未发布到 npm,仅可源码安装)
✗Node 引擎要求 >=24 · 基线 Node 22.19 不满足
✓dsh CLI 依赖未声明 dsh 版本约束
✗入口文件缺少入口声明
源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/14 13:15:00
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 77 处,展示前 70 条)
- 执行外部命令来自配置/变量packages/document-reader/lib/worker-client.js:34
const child=spawn(process.execPath,args,{stdio:['pipe','pipe','ignore'], - 发起网络请求packages/mobile-ui/dsh-push.mjs:106
const res = await fetch(`http://127.0.0.1:${gatewayPort}/pwa/push/send`, { - 发起网络请求packages/mobile-ui/lib/client-routes.js:299
const fetchImpl = options.fetchImpl ?? ((url, init) => fetch(url, init)); - 发起网络请求packages/mobile-ui/lib/client.js:4166
singleton ??= createSharesStore((input, init) => fetch(input, init)); - 发起网络请求packages/mobile-ui/lib/client.js:4266
res = await fetch(buildShareExportQuery(session, range), { cache: 'no-store' }); - 发起网络请求packages/mobile-ui/lib/client.js:7463
const response = await fetch((0, attach_upload_ts_1.uploadUrl)(sessionId, file.name), { - 发起网络请求packages/mobile-ui/lib/client.js:11934
cached ??= fetch(exports.CLIENT_CONFIG_ROUTE, { cache: 'no-store' }) - 发起网络请求packages/mobile-ui/lib/client.js:15962
const res = await fetch(url, { - 发起网络请求packages/mobile-ui/lib/client.js:16067
fetch(settings_form_ts_1.ADMIN_STATUS_ROUTE) - 写入本地文件packages/mobile-ui/lib/code-translation.js:21
await mkdir(directory, { recursive: true, mode: 0o700 }); - 写入本地文件packages/mobile-ui/lib/code-translation.js:23
await writeFile(tmp, JSON.stringify(state), { mode: 0o600 }); - 写入本地文件packages/mobile-ui/lib/code-translation.js:24
await rename(tmp, file); - 读取本地文件packages/mobile-ui/lib/code-translation.js:32
const raw = await readFile(filename(id), 'utf8'); - 读取本地文件packages/mobile-ui/lib/config.js:262
const parsed = JSON.parse(readFileSync(join(home, 'lan-gate.config.json'), 'utf8')); - 读取本地文件packages/mobile-ui/lib/fingerprint.js:228
const text = readFileSync(file, 'utf8'); - 写入本地文件packages/mobile-ui/lib/index.js:253
await mkdir(path, { mode: 0o700 }); - 读取本地文件packages/mobile-ui/lib/index.js:259
const entry = await lstat(path); - 读取本地文件packages/mobile-ui/lib/index.js:267
const canonical = await realpath(path); - 读取本地文件packages/mobile-ui/lib/index.js:293
const workspace = await realpath(visibleWorkspace); - 删除本地文件packages/mobile-ui/lib/index.js:368
await rm(path, { force: true }).catch(() => { }); - 读取密钥环境变量packages/mobile-ui/lib/lan-gate-server.cjs:67
var url = process.env.LAN_GATE_UPSTREAM_TOKEN_URL - 读取密钥环境变量packages/mobile-ui/lib/lan-gate-server.cjs:97
var RELAY_SECRET = String(process.env.LAN_GATE_RELAY_SECRET || '') - 读取本地文件packages/mobile-ui/lib/lan-gate-server.cjs:164
try { raw = JSON.parse(fs.readFileSync(stateFile(), 'utf8')) } catch (e) { raw = null } - 写入本地文件packages/mobile-ui/lib/lan-gate-server.cjs:193
try { fs.renameSync(stateFile(), stateFile() + '.v1.bak'); console.log('[lan-gate] archived v1 state to lan-gate-state.json.v1.bak') } catch (e) {} - 写入本地文件packages/mobile-ui/lib/lan-gate-server.cjs:199
fs.mkdirSync(dshHome(), { recursive: true }) - 写入本地文件packages/mobile-ui/lib/lan-gate-server.cjs:201
fs.writeFileSync(tmp, JSON.stringify(snapshot || state, null, 2), { encoding: 'utf8', mode: 0o600 }) - 写入本地文件packages/mobile-ui/lib/lan-gate-server.cjs:202
fs.chmodSync(tmp, 0o600) - 写入本地文件packages/mobile-ui/lib/lan-gate-server.cjs:203
fs.renameSync(tmp, stateFile()) - 发起网络请求packages/mobile-ui/lib/lan-gate-server.cjs:504
var upstream = http.request({ host: TARGET_HOST, port: TARGET_PORT, method: 'GET', path: upstreamPath, headers: { host: TARGET_HOST + ':' + TARGET_POR - 读取本地文件packages/mobile-ui/lib/lan-gate-server.cjs:637
try { body = fs.readFileSync(abs) } catch (e) { return false } - 读取本地文件packages/mobile-ui/lib/lan-gate-server.cjs:657
function readPwaText(name) { try { return fs.readFileSync(path.join(PWA_DIR, name), 'utf8') } catch (e) { return '' } } - 发起网络请求packages/mobile-ui/lib/lan-gate-server.cjs:780
var pReq = mod.request({ hostname: u.hostname, port: u.port, path: u.pathname + u.search, method: details.method, headers: details.headers }, function - 发起网络请求packages/mobile-ui/lib/lan-gate-server.cjs:928
var exchange = http.request({ - 发起网络请求packages/mobile-ui/lib/lan-gate-server.cjs:968
var upstream = http.request({ host: TARGET_HOST, port: TARGET_PORT, method: req.method, path: req.url, headers: headers }, function (upRes) { - 发起网络请求packages/mobile-ui/lib/relay-client.js:250
const fetchImpl = options.fetchImpl ?? ((url, init) => fetch(url, init)); - 读取本地文件packages/mobile-ui/lib/relay-server.js:165
const parsed = JSON.parse(readFileSync(file, 'utf8')); - 写入本地文件packages/mobile-ui/lib/relay-server.js:177
mkdirSync(home, { recursive: true }); - 写入本地文件packages/mobile-ui/lib/relay-server.js:178
writeFileSync(`${file}.tmp`, JSON.stringify({ serverId: id })); - 写入本地文件packages/mobile-ui/lib/relay-server.js:179
renameSync(`${file}.tmp`, file); - 读取本地文件packages/mobile-ui/lib/share-store.js:75
raw = readFileSync(file, 'utf8'); - 写入本地文件packages/mobile-ui/lib/share-store.js:103
renameSync(file, `${file}.corrupt-${now()}`); - 写入本地文件packages/mobile-ui/lib/share-store.js:133
mkdirSync(dirname(file), { recursive: true }); - 写入本地文件packages/mobile-ui/lib/share-store.js:134
writeFileSync(`${file}.tmp`, JSON.stringify({ version: FILE_VERSION, sessions: fileSessions })); - 写入本地文件packages/mobile-ui/lib/share-store.js:135
renameSync(`${file}.tmp`, file); - 执行外部命令来自配置/变量packages/mobile-ui/persistent-gateway.mjs:10
const child=spawn(nodePath,[serverFile],{cwd,env,stdio:['ignore','pipe','pipe'],shell:false}) - 发起网络请求packages/mobile-ui/src/client-routes.ts:366
const fetchImpl: FetchLike = options.fetchImpl ?? ((url, init) => fetch(url, init)) - 写入本地文件packages/mobile-ui/src/code-translation.ts:31
await mkdir(directory, { recursive: true, mode: 0o700 }) - 写入本地文件packages/mobile-ui/src/code-translation.ts:33
await writeFile(tmp, JSON.stringify(state), { mode: 0o600 }); await rename(tmp, file) - 写入本地文件packages/mobile-ui/src/code-translation.ts:33
await writeFile(tmp, JSON.stringify(state), { mode: 0o600 }); await rename(tmp, file) - 读取本地文件packages/mobile-ui/src/code-translation.ts:39
const raw = await readFile(filename(id), 'utf8') - 读取本地文件packages/mobile-ui/src/config.ts:363
const parsed: unknown = JSON.parse(readFileSync(join(home, 'lan-gate.config.json'), 'utf8')) - 读取本地文件packages/mobile-ui/src/fingerprint.ts:274
const text = readFileSync(file, 'utf8') - 写入本地文件packages/mobile-ui/src/index.ts:266
await mkdir(path, { mode: 0o700 }) - 读取本地文件packages/mobile-ui/src/index.ts:270
const entry = await lstat(path) - 读取本地文件packages/mobile-ui/src/index.ts:277
const canonical = await realpath(path) - 读取本地文件packages/mobile-ui/src/index.ts:304
const workspace = await realpath(visibleWorkspace) - 删除本地文件packages/mobile-ui/src/index.ts:372
await rm(path, { force: true }).catch(() => {}) - 发起网络请求packages/mobile-ui/src/relay-client.ts:462
const fetchImpl: typeof fetch = options.fetchImpl ?? ((url, init) => fetch(url, init)) - 读取本地文件packages/mobile-ui/src/relay-server.ts:312
const parsed: unknown = JSON.parse(readFileSync(file, 'utf8')) - 写入本地文件packages/mobile-ui/src/relay-server.ts:322
mkdirSync(home, { recursive: true }) - 写入本地文件packages/mobile-ui/src/relay-server.ts:323
writeFileSync(`${file}.tmp`, JSON.stringify({ serverId: id })) - 写入本地文件packages/mobile-ui/src/relay-server.ts:324
renameSync(`${file}.tmp`, file) - 读取本地文件packages/mobile-ui/src/share-store.ts:162
raw = readFileSync(file, 'utf8') - 写入本地文件packages/mobile-ui/src/share-store.ts:185
renameSync(file, `${file}.corrupt-${now()}`) - 写入本地文件packages/mobile-ui/src/share-store.ts:215
mkdirSync(dirname(file), { recursive: true }) - 写入本地文件packages/mobile-ui/src/share-store.ts:216
writeFileSync(`${file}.tmp`, JSON.stringify({ version: FILE_VERSION, sessions: fileSessions })) - 写入本地文件packages/mobile-ui/src/share-store.ts:217
renameSync(`${file}.tmp`, file) - 执行外部命令固定命令packages/workbench/cloud-meter.js:67
const child=compressed?spawn('nice',['-n','10','zstd','-dc','-M32MB','--',file],{stdio:['ignore','pipe','ignore']}):null; - 执行外部命令固定命令packages/workbench/projects.js:200
if(pathname==='/projects/api/mail-refresh'&&req.method==='POST'){if(mailScanProcess)throw Error('邮箱目录正在更新');mailScanError='';mailScanProcess=execFile( - 发起网络请求packages/workbench/workspace.js:13
async function api(url,body){const r=await fetch(url,{credentials:'same-origin',...(body!==undefined?{method:'POST',headers:{'Content-Type':'applicati
扫描于 2026/11/3(1 天前) · 范围 全包扫描 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
基于 DeepSeek Harness 的自托管移动工作台:项目、产物、代码翻译与用量。
README
由 DeepSeek 最新模型翻译生成DSH Mobile Workbench · DSH 移动云端工作台
基于 DeepSeek Harness 的独立扩展项目:云端运行智能体,手机随时访问、管理项目,也可以通过对话提出需求,让智能体修改和扩展工作台自身的网页与插件。包含项目与文件来源管理、中文代码翻译和用量视图。
这不是 DeepSeek 官方产品,也不包含模型权重。当前为首个开源实验版(0.1.0-alpha.1)。需要自行提供服务器、HTTPS 域名和模型账户。
English · 安装说明 · 发布检查
操作演示
观看手机端操作视频(2 分 36 秒)
个人部署实录:项目浏览、网站使用、文件入口、对话和用量视图。展示中的个人网站与数据不包含在开源代码中。
为什么做
使用近两个月后,我希望把分散的 AI 项目和文件集中管理,并在不打开个人电脑时,通过手机继续修改云端项目。项目工作台把文件、产生文件的对话和后续修改关联起来;代码翻译便于阅读项目结构和改动。
模型、智能体,以及可以继续修改自身的工作台
我对未来 AI 解决方案的理解是:模型和智能体会成为两层基础。模型提供语言、推理、代码、图像等能力,智能体把模型与工具、上下文、权限和执行流程连接起来。不同的模型有不同的长处,不同的智能体也有不同的组织和执行方式;把它们组合起来,才能适配不同的任务场景。
展开完整文档(README 剩余 1 节)
DSH Mobile Workbench · DSH 移动云端工作台 基于 DeepSeek Harness 的独立扩展项目:云端运行智能体,手机随时访问、管理项目,也可以通过对话提出需求,让智能体修改和扩展工作台自身的网页与插件。包含项目与文件来源管理、中文代码翻译和用量视图。 这不是 DeepSeek 官方产品,也不包含模型权重。当前为首个开源实验版(0.1.0-alpha.1)。需要自行提供服务器、HTTPS 域名和模型账户。 English · 安装说明 · 发布检查 操作演示 观看手机端操作视频(2 分 36 秒) 个人部署实录:项目浏览、网站使用、文件入口、对话和用量视图。展示中的个人网站与数据不包含在开源代码中。 为什么做 使用近两个月后,我希望把分散的 AI 项目和文件集中管理,并在不打开个人电脑时,通过手机继续修改云端项目。项目工作台把文件、产生文件的对话和后续修改关联起来;代码翻译便于阅读项目结构和改动。 模型、智能体,以及可以继续修改自身的工作台 我对未来 AI 解决方案的理解是:模型和智能体会成为两层基础。模型提供语言、推理、代码、图像等能力,智能体把模型与工具、上下文、权限和执行流程连接起来。不同的模型有不同的长处,不同的智能体也有不同的组织和执行方式;把它们组合起来,才能适配不同的任务场景。 这也是我选择 DeepSeek Harness 的重要原因。它的「一切皆插件」,让我想到:既然智能体已经可以帮我修改项目,那在开放相应源码和权限之后,能不能也让它继续修改自己的工作台? 在手机上,我可以直接提出需求:给上传图片和上传文件分别做一个入口、增加一个 PDF 转 Markdown 的功能,或者调整深色/浅色界面和操作流程。智能体可以修改对应的网页、插件和服务代码,再构建、验证并应用更新;必要时重启相关服务。这里「改自己」修改的是智能体工作台的软件功能、工具和界面。 APK 主要承载云端 Web 界面,因此多数网页和插件更新可以直接在云端生效,不需要每次重新安装 APK;原生桥接、系统权限等变化仍需新版本 APK。 所以我希望这个 Personal Agent 能一边积累自己的项目和上下文,一边根据实际需求继续扩展。今天需要处理文档,就补文档能力;明天需要新的模型或工具,就继续接入。模型与智能体的组合方式可以变化,而自己的项目和使用环境能够持续保留下来。这是本项目的产品方向;当前已经开放的是这套云端工作台、插件扩展和手机访问实现。 包含什么 - 移动界面、配对网关和通知接口:packages/mobile-ui。 - 项目工作台、文件来源关联、按需中文翻译、邮箱附件目录、用量视图和手机操作协议:packages/workbench。 - 文档读取插件及读取预算限制:packages/document-reader。 - Android WebView 外壳、文件选择、原生通知及需要用户授权的手机操作:android。 没有聊天记录、个人项目、邮箱目录或附件、生产配置、密钥、模型账户信息。示例目录为空。邮箱集成需要你自行授权自己的邮箱;代码不会向作者邮箱发送内容。 网络安全防御工程 项目部署到公网以后,我开始注意到持续出现的陌生扫描和探测请求。按我的日常观察,有时一天能看到几十个扫描来源;这不是经过统一去重的统计,也不能仅凭请求判断对方是否使用了 AI 智能体。把项目长期放在云端,除了方便调用,也要保护项目文件、对话和账户信息。 因此,我在自己的部署中配套做了网络安全防御工程:收紧公网端口和访问入口、修复未授权文件访问、检查凭据与依赖风险,并保存服务器之外的加密备份。在授权范围内,可以让智能体协助检查自己的项目、分析异常和修复问题;实际访问拦截由服务器防火墙和认证规则执行,模型判断不能替代这些规则。需要处理的发现应形成可追踪的记录和提醒,修复后还要验证。 开源包与个人部署的范围不同。 本仓库包含配对与设备认证、项目文件访问边界、私密页面不落入 PWA 离线缓存、受授权约束的手机操作等工作台防护。主机防火墙、扫描监测与告警、异地备份和恢复流程属于配套部署工程,目前没有随本仓库打包成一键安装的防御系统。扫描请求不等于成功入侵;本项目不提供自动反击,也不承诺阻止所有攻击。 架构与限制 手机 → HTTPS / 配对网关 → Harness / 插件 → 已注册项目。模型通过 API 调用,服务器不加载大模型权重。项目文件在文件系统,索引保存关联关系;不把所有源码塞进聊天数据库。 Web UI / 插件更新通常不必重装 APK;原生权限、桥接和系统通知能力更新仍需新 APK。服务器可持续运行不等于任务永不停止,任务占用仍须限制。电脑用量入口是上传的快照,不保证所有工具的实时计量。翻译需要模型 Token,首次按需生成并缓存;打开目录本身不发模型请求。 安全能力表述限于认证、授权、隔离和资源保护。本仓库不提供对第三方系统自动反击的能力,也不能保证网站永不被攻击。生产服务器的完整防御工程不是本次导出范围。 开发验证 npm ci --ignore-scripts npm test npm run verify:ui npm run build:ui 依赖构建和从零部署的实际验证结果见 发布检查。安装步骤见 配置说明,从既有官方 web profile 加载本仓库扩展。尚未提供经过完整验收的一键部署。 Android 要求 JDK 17、Android SDK 34 和 Gradle 8.9(当前不附 wrapper): cd android gradle assembleDebug -PdshBaseUrl=https://your-domain.example 默认域名为 example.invalid;发布版请自行签名。不同 applicationId 的公开示例不能覆盖安装你的私人 APK。 安全与开源范围 参见 SECURITY、上游与许可、配置说明。部署前必须核对认证入口、仅绑定内网的服务端口、项目注册范围和独立备份。不要把智能体以不受约束的 root 权限提供给任意访客。
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
H2O-YAOZE/dsh-mobile-workbench
在手机上管理云端项目,让智能体改代码扩功能
相关插件 · UI / 主题
破甲增强版JeffKeeping/dsh-purge-plus
dsh-purge 的非官方分支fork:适配 DeepSeek Harness 0.2.1-rc.2、破甲内核…
★ 387已汉化DeepSeek 客户端
71.9
无代码业务系统平台nocobase/nocobase
NocoBase 是什么
★ 24,804已汉化DSH
71.8
1Panel 服务器面板1Panel-dev/1Panel
全球 250 万+ 自托管用户共同喜爱。
★ 37,350已汉化DSH
71.5
工作状态行动态ccch1mneyyy/working-activity
作者:chimney@ccch1mneyyy。社区项目,非 DeepSeek 官方项目。
★ 664已汉化DSH
71.2
多模型配置管家farion1231/cc-switch
跨平台桌面一体化助手,支持 Claude Code、Codex、OpenCode、DeepSeek Harness 等工具,唯一官网 ccswitch.io
★ 151,506已汉化DSH
71.1
AI 矢量设计工具ZSeven-W/openpencil
全球首个 AI 原生开源矢量设计工具。
★ 7,027已汉化DSH
71.1
这是你的仓库?认领条目