DeepSeek Harness 手机端:会说话的像素鲸鱼娘桌宠 + 语音对话,语音指挥你电脑上的 AI…
30.8/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/11/2 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add regrevia/pocket-harness该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:仅索引
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件写入剪贴板(不计风险)读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 262 处,展示前 103 条)
- 执行外部命令来自配置/变量mcp/pet-bridge/selftest.mjs:59
this.proc = spawn(process.execPath, [SERVER], { - 读取密钥环境变量mcp/pet-bridge/selftest.mjs:224
let token = (process.env.PET_TOKEN || '').trim() - 发起网络请求mcp/pet-bridge/selftest.mjs:239
const r = await fetch(`${base}/pet-voice/api/state`, { - 发起网络请求mcp/pet-bridge/selftest.mjs:282
const init = await cli.request('initialize', { - 发起网络请求mcp/pet-bridge/selftest.mjs:296
const ping = await cli.request('ping') - 发起网络请求mcp/pet-bridge/selftest.mjs:301
const list = await cli.request('tools/list') - 发起网络请求mcp/pet-bridge/selftest.mjs:316
const nf = await cli.request('tools/nonexistent') - 发起网络请求mcp/pet-bridge/selftest.mjs:320
const ip = await cli.request('tools/call', { name: 'pet_switch_project', arguments: {} }) - 读取密钥环境变量mcp/pet-bridge/selftest.mjs:358
const token = (process.env.PET_TOKEN || '').trim() || (() => { - 读取密钥环境变量mcp/pet-bridge/server.mjs:77
const fromEnv = (process.env.PET_TOKEN || '').trim() - 发起网络请求mcp/pet-bridge/server.mjs:225
return await fetch(url, { - 发起网络请求mcp/pet-bridge/server.mjs:316
resp = await fetch(`${base}/pet-voice/api/stream?sessionId=${encodeURIComponent(sessionId)}`, { - 读取密钥环境变量mcp/pet-bridge/server.mjs:1145
const acToken = (process.env.PET_HTTP_TOKEN || '').trim() - 发起网络请求mcp/pet-bridge/xiaoai-selftest.mjs:129
const res = await fetch(url, { - 发起网络请求mcp/pet-bridge/xiaoai-selftest.mjs:375
const headerRes = await fetch(`${server.base}${PATH}`, { - 读取本地文件mcp/pet-bridge/xiaoai-selftest.mjs:417
const saved = JSON.parse(readFileSync(slowStore, 'utf8')) - 读取本地文件mcp/pet-bridge/xiaoai-selftest.mjs:425
const after = JSON.parse(readFileSync(slowStore, 'utf8')) - 发起网络请求mcp/pet-bridge/xiaoai-selftest.mjs:450
const res = await fetch(`${server.base}${PATH}?k=${encodeURIComponent(SECRET)}`) - 发起网络请求mcp/pet-bridge/xiaoai-selftest.mjs:467
const bad = await fetch(`${server.base}${PATH}?k=${encodeURIComponent(SECRET)}`, { - 发起网络请求mcp/pet-bridge/xiaoai-selftest.mjs:476
const empty = await fetch(`${server.base}${PATH}?k=${encodeURIComponent(SECRET)}`, { method: 'POST' }) - 删除本地文件递归mcp/pet-bridge/xiaoai-selftest.mjs:481
rmSync(dir, { recursive: true, force: true }) - 发起网络请求mcp/pet-bridge/xiaoai-selftest.mjs:504
const res = await fetch(`${server.base}${PATH}?k=${URL_SECRET}`, { - 删除本地文件递归mcp/pet-bridge/xiaoai-selftest.mjs:556
rmSync(dir, { recursive: true, force: true }) - 读取本地文件mcp/pet-bridge/xiaoai.mjs:298
raw = JSON.parse(readFileSync(file, 'utf8')) - 读取本地文件mcp/pet-bridge/xiaoai.mjs:417
const parsed = JSON.parse(readFileSync(file, 'utf8')) - 写入本地文件mcp/pet-bridge/xiaoai.mjs:427
mkdirSync(dirname(file), { recursive: true }) - 写入本地文件mcp/pet-bridge/xiaoai.mjs:428
writeFileSync(file, `${JSON.stringify(cache, null, 2)}\n`, { mode: 0o600 }) - 发起网络请求plugins/pocket-harness/client.js:182
const res = await fetch(`${API}${path}`, { - 发起网络请求plugins/pocket-harness/client.js:352
fetch(`${API}/qr.svg?text=${encodeURIComponent(pairingUrl)}`, { credentials: 'same-origin' }) - 写入剪贴板plugins/pocket-harness/client.js:420
await navigator.clipboard.writeText(pairingUrl) - 读取本地文件plugins/pocket-harness/e2e.mjs:28
process.env.PV_TOKEN || readFileSync(join(homedir(), '.dsh', 'pet-voice', 'token'), 'utf8').trim() - 读取密钥环境变量plugins/pocket-harness/e2e.mjs:28
process.env.PV_TOKEN || readFileSync(join(homedir(), '.dsh', 'pet-voice', 'token'), 'utf8').trim() - 发起网络请求plugins/pocket-harness/e2e.mjs:51
const stateRes = await fetch(`${BASE}/pet-voice/api/state`, { headers: H }) - 发起网络请求plugins/pocket-harness/e2e.mjs:61
await fetch(`${BASE}/pet-voice/api/new`, { - 发起网络请求plugins/pocket-harness/e2e.mjs:99
res = await fetch(`${BASE}/pet-voice/api/stream?sessionId=${encodeURIComponent(sid)}`, { - 发起网络请求plugins/pocket-harness/e2e.mjs:139
const res = await fetch( - 发起网络请求plugins/pocket-harness/e2e.mjs:161
const disp = await fetch(`${BASE}/pet-voice/api/dispatch`, { - 读取本地文件plugins/pocket-harness/index.js:81
return String(JSON.parse(readFileSync(join(HERE, 'package.json'), 'utf8')).version ?? '') - 写入本地文件plugins/pocket-harness/index.js:321
mkdirSync(CLIENT_LOG_DIR, { recursive: true }) - 写入本地文件plugins/pocket-harness/index.js:322
appendFileSync(path, `${new Date().toISOString()} ${flat}\n`) - 读取本地文件plugins/pocket-harness/index.js:323
if (statSync(path).size > FLOW_LOG_MAX) { - 读取本地文件plugins/pocket-harness/index.js:324
writeFileSync(path, readFileSync(path, 'utf8').slice(-FLOW_LOG_MAX / 2)) - 写入本地文件plugins/pocket-harness/index.js:324
writeFileSync(path, readFileSync(path, 'utf8').slice(-FLOW_LOG_MAX / 2)) - 读取本地文件plugins/pocket-harness/index.js:523
const raw = JSON.parse(readFileSync(STATE_PATH, 'utf8')) - 写入本地文件plugins/pocket-harness/index.js:536
mkdirSync(HOME_DIR, { recursive: true, mode: 0o700 }) - 写入本地文件plugins/pocket-harness/index.js:538
writeFileSync(STATE_PATH, `${JSON.stringify(state, null, 2)}\n`, { mode: 0o600 }) - 读取本地文件plugins/pocket-harness/index.js:803
body = readFileSync(full) - 读取本地文件plugins/pocket-harness/index.js:832
return existsSync(TTS_PYTHON) && existsSync(TTS_SCRIPT) - 发起网络请求plugins/pocket-harness/index.js:916
const res = await fetch(`${ASR_ENDPOINT}/health`, { signal: AbortSignal.timeout(timeout) }) - 写入本地文件plugins/pocket-harness/index.js:951
mkdirSync(ASR_DIR, { recursive: true, mode: 0o700 }) - 删除本地文件plugins/pocket-harness/index.js:969
unlinkSync(ASR_START_LOCK_PATH) - 执行外部命令固定命令plugins/pocket-harness/index.js:1019
const out = execFileSync('/bin/ps', ['-axo', 'pid=,command='], { encoding: 'utf8', timeout: 3000 }) - 执行外部命令来自配置/变量plugins/pocket-harness/index.js:1102
child = spawn( - 执行外部命令来自配置/变量plugins/pocket-harness/index.js:1274
child = spawn(TTS_PYTHON, [join(TTS_DIR, 'tts-daemon.py'), '--serve'], { - 发起网络请求plugins/pocket-harness/index.js:1303
const res = await fetch(`${ASR_ENDPOINT}/asr`, { - 执行外部命令固定命令plugins/pocket-harness/index.js:3792
execFileSync('git', args, { - 执行外部命令来自配置/变量plugins/pocket-harness/index.js:5648
child = spawn(TTS_PYTHON, [TTS_SCRIPT, voice, text, rate, pitch], { - 读取本地文件plugins/pocket-harness/lan.mjs:34
const raw = JSON.parse(readFileSync(CONFIG_PATH, 'utf8')) - 写入本地文件plugins/pocket-harness/lan.mjs:45
mkdirSync(DIR, { recursive: true }) - 写入本地文件plugins/pocket-harness/lan.mjs:46
writeFileSync(CONFIG_PATH, `${JSON.stringify({ port }, null, 2)}\n`, 'utf8') - 写入本地文件plugins/pocket-harness/lan.mjs:47
chmodSync(CONFIG_PATH, 0o600) - 读取本地文件plugins/pocket-harness/panel.mjs:78
return JSON.parse(readFileSync(path, 'utf8')) - 写入本地文件plugins/pocket-harness/panel.mjs:86
mkdirSync(PANEL_DIR, { recursive: true }) - 写入本地文件plugins/pocket-harness/panel.mjs:89
writeFileSync(tmp, JSON.stringify(value), { mode: 0o600 }) - 写入本地文件plugins/pocket-harness/panel.mjs:90
renameSync(tmp, path) - 删除本地文件plugins/pocket-harness/panel.mjs:93
rmSync(tmp, { force: true }) - 读取本地文件plugins/pocket-harness/panel.mjs:462
return readFileSync(TOKEN_PATH, 'utf8').trim() - 读取本地文件plugins/pocket-harness/public.mjs:36
raw = JSON.parse(readFileSync(CONFIG_PATH, 'utf8')) - 读取本地文件plugins/pocket-harness/public.mjs:87
if (!existsSync(abs)) throw new Error('找不到这个私钥文件') - 写入本地文件plugins/pocket-harness/public.mjs:98
mkdirSync(PUBLIC_DIR, { recursive: true, mode: 0o700 }) - 写入本地文件plugins/pocket-harness/public.mjs:99
writeFileSync(CONFIG_PATH, JSON.stringify(cfg, null, 2) + '\n', { mode: 0o600 }) - 写入本地文件plugins/pocket-harness/public.mjs:101
chmodSync(CONFIG_PATH, 0o600) - 读取本地文件plugins/pocket-harness/public.mjs:108
if (!existsSync(LEAF_PATH) || !existsSync(LEAF_KEY_PATH)) return { ok: false } - 读取本地文件plugins/pocket-harness/public.mjs:110
const pem = readFileSync(LEAF_PATH, 'utf8') - 读取本地文件plugins/pocket-harness/public.mjs:135
keyExists: cfg.keyPath ? existsSync(cfg.keyPath) : false, - 读取本地文件plugins/pocket-harness/public.mjs:175
const key = readFileSync(LEAF_KEY_PATH) - 执行外部命令固定命令plugins/pocket-harness/public.mjs:251
const child = spawn('ssh', args, { stdio: ['ignore', 'ignore', 'pipe'] }) - 执行外部命令固定命令plugins/pocket-harness/public.mjs:286
const child = spawn('ssh', sshArgs(cfg), { stdio: ['ignore', 'ignore', 'pipe'] }) - 读取本地文件plugins/pocket-harness/selftest.mjs:25
if (existsSync(file)) savedPanelFiles.set(name, readFileSync(file)) - 读取本地文件plugins/pocket-harness/selftest.mjs:25
if (existsSync(file)) savedPanelFiles.set(name, readFileSync(file)) - 写入本地文件plugins/pocket-harness/selftest.mjs:38
writeFileSync(join(PANEL_DIR, name), buf) - 删除本地文件plugins/pocket-harness/selftest.mjs:164
rmSync(join(homedir(), '.dsh/pet-voice/state.json'), { force: true }) - 发起网络请求plugins/pocket-harness/selftest.mjs:266
await fetch(`${origin}/pet-voice/`) - 读取本地文件plugins/pocket-harness/selftest.mjs:267
const token = readFileSync(join(homedir(), '.dsh/pet-voice/token'), 'utf8').trim() - 发起网络请求plugins/pocket-harness/selftest.mjs:276
const gate = await fetch(`${origin}/pet-voice/`) - 发起网络请求plugins/pocket-harness/selftest.mjs:282
const handoff = await fetch(`${origin}/pet-voice/?k=${token}`, { redirect: 'manual' }) - 发起网络请求plugins/pocket-harness/selftest.mjs:293
const page = await fetch(`${origin}/pet-voice/`, { headers: { cookie } }) - 发起网络请求plugins/pocket-harness/selftest.mjs:306
const res = await fetch(`${origin}/pet-voice/assets/${file}`) - 发起网络请求plugins/pocket-harness/selftest.mjs:313
const evil = await fetch(`${origin}/pet-voice/assets/..%2findex.js`) - 读取本地文件plugins/pocket-harness/selftest.mjs:456
const xiaoaiCfg = JSON.parse(readFileSync(join(homedir(), '.dsh/pet-voice/xiaoai.json'), 'utf8')) - 读取本地文件plugins/pocket-harness/selftest.mjs:484
const pinned = JSON.parse(readFileSync(petSessionPath, 'utf8')) - 读取本地文件plugins/pocket-harness/selftest.mjs:508
const moved = JSON.parse(readFileSync(petSessionPath, 'utf8')) - 读取本地文件plugins/pocket-harness/token.mjs:19
if (readFileSync(bakPath, 'utf8').trim() === value) return - 写入本地文件plugins/pocket-harness/token.mjs:24
mkdirSync(homeDir, { recursive: true, mode: 0o700 }) - 写入本地文件plugins/pocket-harness/token.mjs:25
writeFileSync(bakPath, `${value}\n`, { mode: 0o600 }) - 写入本地文件plugins/pocket-harness/token.mjs:26
chmodSync(bakPath, 0o600) - 写入本地文件plugins/pocket-harness/token.mjs:33
mkdirSync(homeDir, { recursive: true, mode: 0o700 }) - 写入本地文件plugins/pocket-harness/token.mjs:34
writeFileSync(tokenPath, `${value}\n`, { mode: 0o600 }) - 写入本地文件plugins/pocket-harness/token.mjs:36
chmodSync(tokenPath, 0o600) - 读取本地文件plugins/pocket-harness/token.mjs:44
const existing = readFileSync(tokenPath, 'utf8').trim() - 读取本地文件plugins/pocket-harness/token.mjs:55
const backup = readFileSync(bakPath, 'utf8').trim() - 读取本地文件plugins/pocket-harness/token.mjs:78
stat = statSync(tokenPath) - 读取本地文件plugins/pocket-harness/token.mjs:91
const value = readFileSync(tokenPath, 'utf8').trim()
扫描于 2026/11/2(1 天前) · 范围 全包扫描 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
手机端的语音宠物:悬浮窗像素鲸鱼娘 + 语音对话,网关跑在你自己电脑的 DeepSeek Harness 上(自签 APK,无第三方服务器)
README
由 DeepSeek 最新模型翻译生成Pocket Harness · DSH 手机端
把电脑上的 DeepSeek Harness 揣进兜里:会话、项目、工具、目标都还在,手机上点开接着干。
手机端不是另一个 AI 助手:它连的是你自己电脑上那个 DSH,同一条会话、同一份历史、同一批项目。
电脑上派出去的活还在跑,手机上看到的也是「回复中」;电脑上排着的目标、队列、待确认的提问,手机上一样能看到、能回答。
不用注册,不经过作者的服务器,会话和记忆都留在你自己电脑里。
桌宠可选:默认关着,只有你在设置里打开,才会出现一只像素鲸鱼娘——当个会听会说的入口。
手机上要的就是电脑上那一套
| | 云端手机 AI 助手 | Pocket Harness |
| 大脑 | 厂商服务器上的模型 | 你电脑上的 DSH 会话,带着项目、记忆和工具 |
| 历史 | 另一份对话 | 就是电脑上那条会话,切回来还是它 |
| 状态 | 只有「在输入」 | 回复中 / 用时 / 排队 / 目标 / 待确认提问,跟电脑一致 |
| 数据 | 上传 | 配对直连,只走你俩之间那条线 |
| 桌宠 | 无 | 可选,默认关 |
三步用起来
1. 电脑上装插件
rsync -a --delete plugins/pocket-harness/ ~/.dsh/plugins/pocket-harness/
展开完整文档(README 剩余 1 节)
Pocket Harness · DSH 手机端 把电脑上的 DeepSeek Harness 揣进兜里:会话、项目、工具、目标都还在,手机上点开接着干。 手机端不是另一个 AI 助手:它连的是你自己电脑上那个 DSH,同一条会话、同一份历史、同一批项目。 电脑上派出去的活还在跑,手机上看到的也是「回复中」;电脑上排着的目标、队列、待确认的提问,手机上一样能看到、能回答。 不用注册,不经过作者的服务器,会话和记忆都留在你自己电脑里。 桌宠可选:默认关着,只有你在设置里打开,才会出现一只像素鲸鱼娘——当个会听会说的入口。 手机上要的就是电脑上那一套 | | 云端手机 AI 助手 | Pocket Harness | | 大脑 | 厂商服务器上的模型 | 你电脑上的 DSH 会话,带着项目、记忆和工具 | | 历史 | 另一份对话 | 就是电脑上那条会话,切回来还是它 | | 状态 | 只有「在输入」 | 回复中 / 用时 / 排队 / 目标 / 待确认提问,跟电脑一致 | | 数据 | 上传 | 配对直连,只走你俩之间那条线 | | 桌宠 | 无 | 可选,默认关 | 三步用起来 1. 电脑上装插件 rsync -a --delete plugins/pocket-harness/ ~/.dsh/plugins/pocket-harness/ 重启一次桌面端,让它重读 cordis.patch.yml 装了 dsh 命令行的话,也可以 dsh plugin add pocket-harness@latest。 装好后桌面端侧栏出现「Pocket Harness」面板。 2. 电脑上出配对码 面板 →「连上手机」→ 选一种连法 → 二维码自己出来(或复制链接)。链接长这样: https://<你的地址>/pet-voice/?k=<一次性配对码> 3. 手机上扫码 装 APK(Releases)→ 首页「扫码绑定」→ 扫上一步的二维码 →「立即对话」。 不扫码也行:手机上填电脑面板里的地址和 token。 状态一致:手机看到的和电脑上的是同一件事 手机端只有一个会话页,切换会话时把上一轮彻底收掉,表头项目跟着换。当前对齐的几件事: - 回复中:电脑上还在生成,手机进这个会话就显示「回复中 · 用时」,不用等它出字。 - 接上继续:没等到回复就离开,回来还是同一条在跑、还在出字,停按钮也在。 - 更早的记录:往上翻到顶自动取上一页,不出现「翻不动」。 - 派出去的命令:手机上发的话和电脑上完全是同一批消息,不会出现只有一端才有的行。 - 目标与队列:项目目标只在电脑上编辑,手机上能看;队列里的活两端一致。 桌宠(可选) 设置里打开「显示鲸灵」,它才出现;关掉就只是一个干净的 DSH 手机端。 悬浮窗那只是同一个它,不会出现两只,也不会各说各话。 - 说停就停:尾静音 1 秒判你说完了,不用点发送。 - 动作就是状态:听、想、说、待机四态各有动作,安静下来就是活干完了。 - 8 套衣服:水手裙 / 女仆装 / 鲸鱼卫衣 / 冬日斗篷 / 深海公主 / 深海研究员 / 星潮小魔女 / 泡泡睡衣。 手机上的对话页 还能改什么 连法、人设、输出长度、气泡开关、唤醒词,都在插件面板里改,不用重装。 三种连法 手机和电脑必须能互相访问。开源版默认不使用作者的任何基础设施,代码里没有硬编码的域名或 IP,配置只存在你这台电脑上。 | 连法 | 适合 | 需要 | 面板选哪档 | | 局域网 | 手机和电脑同一个 WiFi | 无 | 局域网 | | 自建域名 | 长期用、自己有域名 | 一台能跑 nginx/caddy 的机器 + 证书 | 自建域名,填自己的域名 | | 服务器中转 | 在外面也想用,不想碰路由器和证书 | 装 cloudflared / ngrok,或自己的中转服务器 | 自建域名,填工具给的 https 地址 | | 公网 IP 直连 | 域名还没备案,或不想折腾证书 | 一台有公网 IP 的机器 + 反代 + token | 自建域名,填 http://<公网IP>/pet-voice/ | 域名走 HTTPS 需要 ICP 备案(国内机器)或 DNS-01 证书,没备案时 80/443 会被云厂商拦到备案页——这时直接用公网 IP + token,功能一样全。 细节、证书与排错:docs/self-host.md。不想买域名也能 https:docs/tls-self-signed.md。 现在能用吗 | 项 | 状态 | | APK | 0.9.144(versionCode 214),Android 8.0+(API 26),targetSdk 35 | | 验证环境 | Android 11 模拟器跑通全链路:配对、语音、回复、动作、历史、检查更新 | | 真机 | 厂商权限跳转与硬件麦克风只在 AOSP 页面验证过,各家 ROM 仍可能不同,欢迎回报 | | Android 14/15 | 未做实机验证:后台恢复、麦克风前台服务在收紧后的行为【需真机确认】,见 docs/android-app.md | | iOS | 不支持(悬浮窗与常听麦克风是 Android 特性) | 内置信任锚:APK 里带了一张示例自签 CA 的公钥证书(res/raw/pet_ca.pem,无私钥),让「不买域名、机器上跑自签 https」的人开箱能连。换成自己的 CA 请跑 scripts/tls-ca.sh 再重新出包;只用系统 CA 的部署不受影响。别人的 CA 不要信,也不要装来路不明的 APK。 它怎么工作 手机(悬浮窗 WebView) 电脑(DSH 宿主进程)说话 ──► /api/asr ──► 识别文本 ──► /api/command ──► 切项目 / 派发 / 停 ──► /api/dispatch ──► 专属会话(人设走隐藏提示词)听 ◄── SSE 增量 / /api/poll 兜底 ◄── 逐字生成念 ◄── /api/tts ◄── 句子级音频 端点、鉴权、帧格式、错误码见 docs/pet-contract.md;手机端实现与限制见 docs/android-app.md。 两条外部依赖:默认语音合成走微软 Edge 的在线语音接口(edge-tts,免 key),手机端唤醒与识别走 Android 系统语音服务(SpeechRecognizer,是否上传音频由系统/厂商决定)。换本地 TTS 或换音色也能用,但这两条链路本身不是纯离线的。 开发与构建 前置:Node.js ≥ 22.15.0(插件静态引用 node:zlib 的 zstdDecompressSync)、JDK 17、Android SDK。 自测(离线部分不碰真实配置) SKIP_LIVE=1 bash scripts/verify.sh 编 APK(JDK 17,别用 21+) export JAVA_HOME=/path/to/jdk17/Contents/Home android/gradlew -p android :app:assembleRelease 产物在 android/app/build/outputs/apk/release/app-release.apk。要发布自己的版本,用同一个 keystore 签名才能覆盖安装、保住配对信息,流程见 docs/android-app.md 的发布一节。 参与开发前请读 CONTRIBUTING.md;安全问题走 SECURITY.md。 目录 plugins/pocket-harness/ DSH 插件:/pet-voice/ 页面、语音闭环、配对、更新通道 android/ Android 客户端(Kotlin,零 androidx) docs/ 契约、安装、自接入、真机、架构 scripts/ 自测、验收、素材生成、发布 许可 代码与文档 MIT。像素素材由本项目生成,同样 MIT。 “DeepSeek Harness” 是它自己的项目,与它的许可证一致;本仓库只通过插件接口与它交互。
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
regrevia/pocket-harness
DeepSeek Harness 手机端:会说话的像素鲸鱼娘桌宠 + 语音对话,语音指挥你电脑上的 AI…
相关插件 · 桌面端
Codex 任务面板chuspeeism/dashi-taskboard
现代化可灵活嵌入的任务面板,支持 Codex、DeepSeek Harness
★ 3,409已汉化DSH
71.7
多智能体自进化开发平台Prism-Shadow/penguin-harness
统一、稳定的 Agent 自进化框架全自动优化:任意模型 · 任意算法 · 任意 Benchmark
★ 3,111已汉化DSH
71.1
桌面宠物PC2005-cloud/dsh-pet
DSH 桌面宠物:一行命令装好即用的透明动画小桌宠,支持多开、大小位置随心配置;还内置 DIY 素材链,能用 AI…
★ 5,341已汉化DSH
71
多端 Agent 工作台GCWing/OpenBitFun
OpenBitFun 是一个高度可定制的开源 Agent 工作台,让任务按你的方式持续推进。
★ 3,449已汉化DSH
70.8
DSH Desktopanywhere-labs/dsh-desktop
为 DeepSeek Harness DSH 插件生态打造的现代化桌面端解决方案。万物皆「插件」,桌面本身也是「插件」。
★ 34,532已汉化DSH
70.7
桌面宠物伴侣OpenPetsHQ/openpets
桌面伴侣平台,带宠物、插件,还能选配本地智能体集成。
★ 1,353已汉化DSH
70.2