🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

桌面伙伴 takboo/dsh-coopanion

DeepSeek Harnessv0.4.14
takboo1 天前有提交已提供中文文档扫描:含敏感能力

桌面动画伴侣、任务通知和会话聊天,全给 DeepSeek Harness。

39.4/100
综合分
10
GitHub 星标
1,076
npm 周下载
—/5
用户评分

数据截至 2026/10/31 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add @takboo/dsh-coopanion
npm 源 · @takboo/dsh-coopanion 的发布者账号已校验与本仓库一致

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · security
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 1 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过
展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包@takboo/dsh-coopanion @ 0.4.14
✓Node 引擎要求 >=22.19 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/28 23:33:26

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 105 处,展示前 95 条)
  • 读取本地文件
    dist/index.js:688
    relative = await readFile(join(directory, "path.txt"), "utf8");
  • 读取本地文件
    dist/index.js:697
    await access(executable2);
  • 执行外部命令来自配置/变量
    dist/index.js:711
    const child = spawn(process.execPath, [join(directory, "install.js")], {
  • 执行外部命令来自配置/变量
    dist/index.js:792
    const child = spawn2(executable, args, { env, stdio: ["ignore", "pipe", "pipe", "ipc"] });
  • 发起网络请求
    dist/client.js:20787
    const state = parseState(await this.request((signal) => this.options.transport.state(signal)));
  • 发起网络请求
    dist/client.js:20815
    const result = await this.request((signal) => this.options.transport.receipt(receipt, signal));
  • 发起网络请求
    dist/client.js:20832
    const state = parseState(await this.request((signal) => this.options.transport.state(signal)));
  • 发起网络请求
    dist/client.js:20835
    const claim2 = await this.request((signal) => this.options.transport.claim({ clientId: this.clientId, generation: state.runtime.generation }, signal))
  • 发起网络请求
    dist/client.js:20857
    const claim2 = await this.request((signal) => this.options.testClaim(this.clientId, signal));
  • 发起网络请求
    dist/client.js:20862
    const state = parseState(await this.request((signal) => this.options.transport.state(signal)));
  • 发起网络请求
    desktop/main.cjs:117
    const response = await fetch(new URL(view.base + thumb, win.webContents.getURL()));
  • 读取本地文件
    desktop/main.cjs:173
    const manifest = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8'));
  • 读取本地文件
    desktop/main.cjs:174
    const build = JSON.parse(readFileSync(join(__dirname, '../dist/build-info.json'), 'utf8'));
  • 发起网络请求
    desktop/main.cjs:199
    return companions.request(request);
  • 发起网络请求
    desktop/main.cjs:210
    const state = await companions.request({ type: 'read', characterId: id });
  • 发起网络请求
    desktop/main.cjs:211
    await companions.request({ type: 'remove', characterId: id, revision: state.revision, requestId: `remove-${id}-${Date.now()}` });
  • 读取本地文件
    dist/bridge.js:25
    relative = await readFile(join(directory, "path.txt"), "utf8");
  • 读取本地文件
    dist/bridge.js:34
    await access(executable2);
  • 执行外部命令来自配置/变量
    dist/bridge.js:48
    const child = spawn(process.execPath, [join(directory, "install.js")], {
  • 执行外部命令来自配置/变量
    dist/bridge.js:129
    const child = spawn2(executable, args, { env, stdio: ["ignore", "pipe", "pipe", "ipc"] });
  • 发起网络请求
    dist/figure-server.cjs:20482
    json2({ ok: true, value: await companions.request(request) });
  • 发起网络请求
    dist/figure-server.cjs:20510
    const state = await companions.request({ type: "read", characterId: data.id });
  • 发起网络请求
    dist/figure-server.cjs:20511
    await companions.request({ type: "remove", characterId: data.id, revision: state.revision, requestId: `remove-${data.id}-${Date.now()}` });
  • 执行外部命令来自配置/变量
    src/bridge.ts:77
    const child = spawn(executable, args, { env, stdio: ['ignore', 'pipe', 'pipe', 'ipc'] });
  • 写入本地文件
    src/character-store.ts:25
    await mkdir(this.directory, { recursive: true });
  • 写入本地文件
    src/character-store.ts:27
    try { await writeFile(temp, value, { mode: 0o600 }); await rename(temp, file); }
  • 写入本地文件
    src/character-store.ts:27
    try { await writeFile(temp, value, { mode: 0o600 }); await rename(temp, file); }
  • 删除本地文件
    src/character-store.ts:28
    finally { await rm(temp, { force: true }); }
  • 读取本地文件
    src/character-store.ts:39
    if ((await stat(index)).size > 256) throw new Error('角色索引无效');
  • 读取本地文件
    src/character-store.ts:40
    const { revision } = JSON.parse(await readFile(index, 'utf8'));
  • 写入本地文件
    src/character-store.ts:47
    await mkdir(this.directory, { recursive: true });
  • 读取本地文件
    src/character-store.ts:49
    for (const file of await readdir(this.directory)) {
  • 读取本地文件
    src/character-store.ts:58
    if ((await stat(file)).size > 16 * 1024) throw new Error('选择记录过大');
  • 读取本地文件
    src/character-store.ts:59
    const saved = JSON.parse(await readFile(file, 'utf8'));
  • 写入本地文件
    src/character-store.ts:78
    await mkdir(this.directory, { recursive: true });
  • 写入本地文件
    src/character-store.ts:87
    await mkdir(join(full, '..'), { recursive: true }); await writeFile(full, data, { mode: 0o600 });
  • 读取本地文件
    src/character-store.ts:92
    if (!safePath(file) || !(await stat(join(staging, file))).isFile()) throw new Error(`角色文件缺失:${file}`);
  • 删除本地文件递归
    src/character-store.ts:102
    } finally { await rm(staging, { recursive: true, force: true }); }
  • 删除本地文件
    src/character-store.ts:111
    await this.load(id); await rm(join(this.directory, `${id}.json`));
  • 删除本地文件递归
    src/character-store.ts:113
    if (file.startsWith(`${id}-`) && validHash(file.slice(id.length + 1))) await rm(join(this.directory, file), { recursive: true, force: true });
  • 发起网络请求
    src/client/notification-client.ts:92
    const state = parseState(await this.request(signal => this.options.transport.state(signal)));
  • 发起网络请求
    src/client/notification-client.ts:116
    const result = await this.request(signal => this.options.transport.receipt(receipt, signal));
  • 发起网络请求
    src/client/notification-client.ts:131
    const state = parseState(await this.request(signal => this.options.transport.state(signal))); this.connected();
  • 发起网络请求
    src/client/notification-client.ts:133
    const claim = await this.request(signal => this.options.transport.claim({ clientId: this.clientId, generation: state.runtime.generation }, signal));
  • 发起网络请求
    src/client/notification-client.ts:147
    const claim = await this.request(signal => this.options.testClaim!(this.clientId, signal));
  • 发起网络请求
    src/client/notification-client.ts:151
    const state = parseState(await this.request(signal => this.options.transport.state(signal))); this.connected();
  • 写入本地文件
    src/companion-store.ts:46
    await mkdir(this.directory, { recursive: true });
  • 读取本地文件
    src/companion-store.ts:50
    const raw = await readFile(this.file, 'utf8');
  • 写入本地文件
    src/companion-store.ts:60
    try { await mkdir(this.lock); }
  • 读取本地文件
    src/companion-store.ts:63
    const owner = JSON.parse(await readFile(join(this.lock, 'owner.json'), 'utf8'));
  • 写入本地文件
    src/companion-store.ts:68
    await mkdir(claim);
  • 读取本地文件
    src/companion-store.ts:70
    const current = JSON.parse(await readFile(join(this.lock, 'owner.json'), 'utf8'));
  • 写入本地文件
    src/companion-store.ts:73
    await rename(this.lock, retired); await rm(retired, { recursive: true });
  • 删除本地文件递归
    src/companion-store.ts:73
    await rename(this.lock, retired); await rm(retired, { recursive: true });
  • 删除本地文件递归
    src/companion-store.ts:74
    } catch (failure) { await rm(claim, { recursive: true, force: true }); throw failure; }
  • 写入本地文件
    src/companion-store.ts:75
    await mkdir(this.lock);
  • 写入本地文件
    src/companion-store.ts:77
    try { await writeFile(join(this.lock, 'owner.json'), JSON.stringify({ pid: process.pid, token: this.token }), { flag: 'wx', mode: 0o600 }); }
  • 删除本地文件递归
    src/companion-store.ts:78
    catch (error) { await rm(this.lock, { recursive: true, force: true }); throw error; }
  • 读取本地文件
    src/companion-store.ts:83
    try { if (JSON.parse(readFileSync(join(this.lock, 'owner.json'), 'utf8')).token === this.token) rmSync(this.lock, { recursive: true, force: true }); }
  • 删除本地文件递归
    src/companion-store.ts:83
    try { if (JSON.parse(readFileSync(join(this.lock, 'owner.json'), 'utf8')).token === this.token) rmSync(this.lock, { recursive: true, force: true }); }
  • 读取本地文件
    src/companion-store.ts:107
    try { this.data = archive.parse(JSON.parse(await readFile(this.file, 'utf8'))); }
  • 删除本地文件
    src/companion-store.ts:141
    finally { await rm(temp, { force: true }); }
  • 写入本地文件
    src/diagnostics.ts:34
    await mkdir(this.options.registry, { recursive: true, mode: 0o700 });
  • 写入本地文件
    src/diagnostics.ts:35
    if (process.platform !== 'win32') await chmod(this.options.registry, 0o700);
  • 写入本地文件
    src/diagnostics.ts:67
    if (process.platform !== 'win32') await chmod(socketPath, 0o600);
  • 写入本地文件
    src/diagnostics.ts:70
    await writeFile(temporary, JSON.stringify(endpoint) + '\n', { mode: 0o600, flag: 'wx' });
  • 写入本地文件
    src/diagnostics.ts:71
    await rename(temporary, file);
  • 删除本地文件
    src/diagnostics.ts:83
    await rm(join(this.options.registry, endpoint.instance + '-' + process.pid + '.json'), { force: true });
  • 删除本地文件
    src/diagnostics.ts:84
    if (process.platform !== 'win32') await rm(endpoint.socketPath, { force: true });
  • 读取本地文件
    src/diagnostics.ts:94
    if (JSON.parse(readFileSync(file, 'utf8')).session === endpoint.session) rmSync(file, { force: true });
  • 删除本地文件
    src/diagnostics.ts:94
    if (JSON.parse(readFileSync(file, 'utf8')).session === endpoint.session) rmSync(file, { force: true });
  • 删除本地文件
    src/diagnostics.ts:96
    if (process.platform !== 'win32') { try { rmSync(endpoint.socketPath, { force: true }); } catch { } }
  • 读取本地文件
    src/electron-runtime.ts:13
    try { relative = await readFile(join(directory, 'path.txt'), 'utf8'); }
  • 读取本地文件
    src/electron-runtime.ts:18
    try { await access(executable); return executable; }
  • 执行外部命令来自配置/变量
    src/electron-runtime.ts:26
    const child = spawn(process.execPath, [join(directory, 'install.js')], {
  • 读取本地文件
    src/figure-server.ts:23
    for (const entry of await readdir(join(project, relative), { withFileTypes: true })) {
  • 读取本地文件
    src/figure-server.ts:26
    else if (entry.isFile()) files[next] = await readFile(join(project, next));
  • 读取本地文件
    src/figure-server.ts:30
    for (const file of ['package.json', 'npm-shrinkwrap.json', 'tsconfig.json', 'tsconfig.client.json', '.node-version', 'cordis.patch.yml', 'README.md',
  • 发起网络请求
    src/figure-server.ts:52
    json({ ok: true, value: await companions.request(request) }); return;
  • 发起网络请求
    src/figure-server.ts:69
    if (companions) { const state = await companions.request({ type: 'read', characterId: data.id }); await companions.request({ type: 'remove', character
  • 读取本地文件
    src/figure-server.ts:85
    const bytes = custom ? await store.asset(custom[1]!, custom[2]!, custom[3]!) : await readFile(join(webRoot, file));
  • 读取本地文件
    src/upstream/packs.ts:170
    if (!existsSync(join(dir, d.file))) { skipped.push(`sounds.${name} 的 ${d.file} 不存在,这个声音不会响`); continue; }
  • 读取本地文件
    src/upstream/packs.ts:184
    if (!existsSync(file)) return `没有 ${MANIFEST_FILE}`;
  • 读取本地文件
    src/upstream/packs.ts:186
    try { raw = JSON.parse(readFileSync(file, 'utf8')) as Record<string, unknown>; } catch (err) { return `${MANIFEST_FILE} 不是合法的 JSON:${(err as Error).me
  • 发起网络请求
    web/character-library.js:2
    const response = await fetch(`./api/characters/${command}`, value === undefined ? {} : {
  • 发起网络请求
    web/companion-client.js:6
    return this.request('read');
  • 发起网络请求
    web/companion-client.js:30
    const response = await fetch('./api/companionship', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(value) });
  • 发起网络请求
    web/pet.js:274
    void companionClient.request('invite').then(receipt => { if (epoch === companionClient.epoch && companion.invitation === 'pending') companionAction =
  • 发起网络请求
    web/pet.js:278
    companionMessage(uiCopy().companionPlayed, now); void companionClient.request('play', id);
  • 发起网络请求
    web/pet.js:283
    if (mode !== 'off' && activeView && now >= companionReadAt) { companionReadAt = now + 60000; void companionClient.request('read'); }
  • 发起网络请求
    web/pet.js:331
    companionAction = type; companionInvitation.hidden = true; void companionClient.request(type); updateMood();
  • 发起网络请求
    web/pet.js:333
    $('companion-resume').onclick = () => { void companionClient.request('resume'); };
  • 发起网络请求
    web/pet.js:834
    if (companionStroke.move(point, { trusted: event.isTrusted, over: canCare && !!body?.hit(point), pressing, now: performance.now() })) { void companion
  • 发起网络请求
    web/upstream/body-host.js:174
    const model = pack.model ? await (await fetch(new URL(pack.base + pack.model, location.href))).json() : null;
  • 发起网络请求
    web/upstream/sound.js:156
    const bytes = fetch(new URL(d.file, new URL(base, location.href))).then((r) => (r.ok ? r.arrayBuffer() : Promise.reject(new Error(`HTTP ${r.status}`))
扫描于 2026/10/31(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-agent@deepseek-ai/dsh-api-session-controller@deepseek-ai/dsh-client-connection@deepseek-ai/dsh-client-locale@deepseek-ai/dsh-client-store@deepseek-ai/dsh-client-ui-primitives@deepseek-ai/dsh-client-ui-renderer@deepseek-ai/dsh-client-ui-settings@deepseek-ai/dsh-client-ui-slots@deepseek-ai/dsh-client-ui-workspace@deepseek-ai/dsh-goal
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 桌面动画伴侣
  • 任务通知
  • 会话聊天
v0.4.152026-10-30
· v0.4.15 · 启动、显示几何与退出修复 · 修复首次准备 Electron 时同步下载阻塞 Harness:在独立进程后台准备运行时,保持界面与服务响应;准备可取消,窗口启动单独计时,错误可手动重试。 · 修复原生内容边界晚于窗口变化到达时,NPC 持续停在 reason=geometry:重新采样并按需补发几何,边界一致后恢复活动,保留角色、阅读与草稿。 · 修复退出时晚到的显示器事件访问已销毁窗口,引发原生错误框和进程无法正常结束;窗口关闭后解除监听并停止排队几何操作。 · 修复本地资源服务关闭监听后,已接受连接上的排队请求读取空监听地址产生未处理异常;继续校验实际连接的 Host/Origin。 · 修复自动恢复期间设置页误报运行状态无效;正确显示等待自动恢复和重试次数。 · 修复从完整回复继续来源会话时,较早的已读/状态快照把目标退回旧会话的竞态;选择经 Host 确认前保持最新目标,避免后续输入或导航指向旧会话。 · 补充真实 HTTP 排队请求、原生晚到显示事件、Windows 实际 125% 缩放和任务栏工作区回归;修正测试输入的 DPI 感知与首次导航等待。 安装包:dsh-coopanion-0.4.15.tgz;npm 与 GitHub Release 使用同一份发布 CI 验证的压缩包。
v0.4.142026-10-24
· v0.4.14 · DSH 0.2.1-rc.3 兼容 · 将 DSH 0.2.1-rc.3 加入 engines.dsh 与所有宿主 peer 的精确支持列表,保留既有四版宿主兼容;未验证的后续候选版仍不放行。 · 三平台同包安装矩阵扩为五版宿主、十五组,检查正式插件安装、设置与语言切换、完成通知、会话续接、原生窗口及恢复。 · 安装检查通过宿主官方兼容性判断复现旧声明拒绝 rc.3,并验证新声明接受全部支持版本;独立观察工具同步支持 rc.3。 · Linux/macOS 安装重启验证使用宿主正式信号退出路径,Windows 保留 IPC 退出;继续要求退出码为 0,避免旧宿主清理后的残留句柄阻塞测试重启。 安装包:dsh-coopanion-0.4.14.tgz;npm 与 GitHub Release 使用同一份发布 CI 验证的压缩包。
v0.4.132026-10-18
· v0.4.13 · NPC 日常与交互修复 · 统一使用 NPC 日常调度,移除旧随机漫游、dailyRhythm 配置和早期自动片段调度。默认关闭;开启安静/互动陪伴并允许闲时走动后,从小窝探索并返回。旧 dailyRhythm 不自动转换为活动许可。 · 修复点击通用异常的“Take a look”后信封和持续哭泣表情未清除;相同状态不重复提醒,新异常仍可提示,审批与问题继续由 Harness 的实际处理结算。 · 取消输入时自动缩放,打字、选中、悬停及拖动均保持设置尺寸,输入时只暂停自主移动。 · 拖放使用无惯性的放下操作,取消旧路线及首次归位,避免边缘反弹或反向移动;修复按住拖动时小窝标记暂时偏移。 · 修复 macOS 冷启动错误读取控制台状态导致桌宠持续挂起、没有自主行为的问题。 · 补充配置、异常回执、固定尺寸、拖放、小窝和原生启动回归;精简现行文档,删除旧阶段计划和临时交接说明,原始历史证据保留在仓库并排除安装包。 安装包:dsh-coopanion-0.4.13.tgz;npm 与 GitHub Release 使用同一份发布 CI 验证的压缩包。安装、配置与当前行为见使用指南;以下各节只描述对应历史版本。
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。

README

由 DeepSeek 最新模型翻译生成
DeepSeek 大肥鱼 让 Harness 的工作,有个看得见的小伙伴。 大肥鱼住在你的桌面上,陪你一起用 DeepSeek Harness 工作。她会思考、挥手、陪你等结果,也会把回复和待办捎到桌边。双击她,就能接着刚才的对话聊下去。 下载插件 · 快速开始 · 使用指南 · 更新记录 大肥鱼从思考到收到回复,双击打开聊天并继续输入 实际浏览器界面演示:思考 → 收到回复 → 双击继续聊。演示中的 Harness 任务事件为模拟。 她会做些什么? 桌边有个会回应你的小伙伴 眨眼、看向你、挥挥手,拖起来还会晃动、落地。点点她、打个招呼,或者换个模样继续工作。想安静一会儿,可以让她休息、关掉音效,或暂时隐藏。 还可以开启默认关闭的「自主陪伴」:从小窝出发,在屏幕底部慢走、观察、停留并返回;互动模式偶尔邀请你一起活动。你在工作、阅读或输入时,她会先让位。 工作到哪一步,一眼就知道 思考、生成回复、使用工具,都有对应的表情和动作。目标真正完成时,她才会开心庆祝;需要审批、回答问题或查看异常时,小信封会为你留着入口。 角色隐藏后,还可以按需开启 Harness 系统通知。审批和问题始终由你在 Harness 中处理。 把回复带回来,也把对话接下去 小信封收好不同会话的回复与待办。
展开完整文档(README 剩余 1 节)
DeepSeek 大肥鱼

让 Harness 的工作,有个看得见的小伙伴。

大肥鱼住在你的桌面上,陪你一起用 DeepSeek Harness 工作。她会思考、挥手、陪你等结果,也会把回复和待办捎到桌边。双击她,就能接着刚才的对话聊下去。

下载插件 · 快速开始 · 使用指南 · 更新记录

大肥鱼从思考到收到回复,双击打开聊天并继续输入

实际浏览器界面演示:思考 → 收到回复 → 双击继续聊。演示中的 Harness 任务事件为模拟。

她会做些什么?

桌边有个会回应你的小伙伴

眨眼、看向你、挥挥手,拖起来还会晃动、落地。点点她、打个招呼,或者换个模样继续工作。想安静一会儿,可以让她休息、关掉音效,或暂时隐藏。

还可以开启默认关闭的「自主陪伴」:从小窝出发,在屏幕底部慢走、观察、停留并返回;互动模式偶尔邀请你一起活动。你在工作、阅读或输入时,她会先让位。

工作到哪一步,一眼就知道

思考、生成回复、使用工具,都有对应的表情和动作。目标真正完成时,她才会开心庆祝;需要审批、回答问题或查看异常时,小信封会为你留着入口。

角色隐藏后,还可以按需开启 Harness 系统通知。审批和问题始终由你在 Harness 中处理。

把回复带回来,也把对话接下去

小信封收好不同会话的回复与待办。长回复可以展开阅读,支持 Markdown、表格和代码块;新消息到来时,正在读的内容保持原样。

双击打开聊天,选择一段会话就能继续,包括还没在 Harness 中打开的历史会话。消息沿用该会话的模型、工具和权限,后台任务不会抢走你正在聊的对象。

换个模样,照你的习惯来

内置大肥鱼提供多套配色,可以预览动作,也能导入社区制作的角色包。角色大小和文字大小分别调整,小小一只也能把回复看清楚。

想制作自己的角色?从 API 2 角色指南 和 最小示例 开始。

开始一起工作

需要 DeepSeek Harness Desktop 0.2.0-rc.2、0.2.1-alpha.1、0.2.1-rc.1、0.2.1-rc.2 或 0.2.1-rc.3。这是 Harness 插件,聊天使用你在 Harness 中配置的模型,无需另填 API Key。

在 Harness 中从 npm 安装(推荐)

打开侧边栏 插件 → 添加插件,在「包名或地址」中填入:

@takboo/dsh-coopanion@0.4.15

点击安装,完成后启用 dsh-coopanion,再完全退出并重新打开 Harness。

发布首日请保留上面的版本号。pnpm 11 默认等待新版本发布满 24 小时;仅输入包名可能选到旧版,即使详情显示最新版本。详见安装版本与发布时间保护。

使用 dsh 命令行安装

使用 Desktop 自带的 dsh 命令。先启动 Desktop 一次完成初始化,完全退出应用后执行:

dsh plugin --profile desktop add @takboo/dsh-coopanion@0.4.15

完成后重新打开 Desktop。其他 profile 的安装方法见使用指南。

下载压缩包安装

下载最新插件包 dsh-coopanion.tgz,在 插件 → 添加插件 中填入压缩包的绝对路径,安装并启用,然后重启 Harness。

安装后在 Settings → 桌宠 查看运行状态。首次启动会在后台下载并校验 Electron 运行时,期间桌宠显示“正在启动”,Harness 可继续使用;网络受限时可按运行时准备说明配置镜像或提前安装。

| 操作 | 会发生什么 |
| 单击角色 | 和她互动 |
| 双击角色 | 打开聊天;点击当前会话可换一段聊 |
| 右键角色 | 换装、休息、音效和其他偏好 |
| 点击小信封 | 查看回复、审批、问题和异常 |
系统通知与自主陪伴默认关闭,可在设置中开启。安静陪伴和互动陪伴统一使用小窝出发、探索并返回的 NPC 日常;关闭陪伴即停止自主活动。更多配置、CLI 安装和旧角色迁移见使用指南。

了解更多与参与

- 使用遇到问题: 查看使用指南,或提交 Issue。
- 参与开发: 从开发指南开始,完整行为契约与验证边界见工程文档索引。
- 查看改动: 阅读版本记录。

支持平台为 Windows、macOS 和 Linux。物理多屏/混合 DPI、系统通知中心实机体验、真实模型会话及长期资源表现的验证范围见验证说明。

致谢与许可

大肥鱼的动画与角色运行时来自 Pal-AI-Lab / Coopanion。感谢原作者与角色创作者,让她有了灵动的表情、动作和配色。

组合程序采用 AGPL-3.0-or-later,保留原项目的 MIT 署名。角色贴图和商标有独立权利声明,详见第三方声明与上游版本记录。
预览分享卡片长什么样 ↓takboo/dsh-coopanion
分享 · DeepSeek Harness Hub
takboo/dsh-coopanion

桌面动画伴侣、任务通知和会话聊天,全给 DeepSeek Harness。

回到顶部