dsh-muse-code

agitested: passnpmMIT

Meta's Muse Code CLI inside DSH: a composer switch starts muse serve, a right-sidebar panel and five chat tools (muse_open, muse_prompt, muse_read, muse_status, muse_interrupt) share one Muse session, approvals are decided only in the panel, and a local spend guard hard-stops at $10 by default. Wind

下载量 / Downloads
742
依赖体积 / node_modules
0.19 MB
测试时间 / Tested
2026-11-07
DSH 版本 / Version
0.2.2-rc.1

Install

dsh plugin --profile web add dsh-muse-code

Sandbox test results

StageResult
1 install✓
2 list✓
3 mount✓
4 boot—

Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).

README

Muse Code for DeepSeek Harness

在 DeepSeek Harness 里直接使用 Meta 的 Muse Code:输入框左侧的 Muse 开关打开后,右侧边栏出现 Muse Code 面板;聊天里的工具与面板共享同一个会话。

安装

先在本机装好并登录 Muse Code CLI(见文末[依赖](#依赖))。然后在 DeepSeek Harness 里打开 插件 → 添加插件,在输入框里填包名,点 安装,装好后点 立即启用:

dsh-muse-code

也可以填 GitHub 仓库地址 https://github.com/FelixJiashengFu/dsh-muse-code。连不上 npm 官方源时,在 安装源 里选中国大陆镜像源再填包名。

输入框左侧随即出现「Muse」开关。升级:在插件页卸载后,用同样的方式重新安装。

工作方式

DSH 浏览器 (lib/client.js)
  ├─ 输入框左侧开关  conversation.input.left
  └─ 右侧边栏标签  sidebar.right.pane.tab  (key/kind: muse-code)
        ▲ SSE /plugins/dsh-muse-code/events
        │
DSH Host (lib/index.js)
  └─ MuseController (lib/controller.js) ── NDJSON JSON-RPC ──> muse serve  (MSP schema v1)
        ▲
        └─ 聊天工具: muse_open / muse_prompt / muse_read / muse_status / muse_interrupt
  • Host 侧只启动一个 muse serve 子进程、一个 MSP 会话;面板、开关、聊天工具读写的都是这份状态。
  • 面板使用原生右侧边栏(ctx.sidebarRightTabs.register 注册 tab 类型 + sidebar.right.pane.tab 注册内容槽),不是 iframe。
  • 审批与提问只能在面板里由用户决定:approval/decide、userInput/answer 只有面板的 HTTP 路由会调用,聊天工具只能读取待办。
  • 聊天工具把结果画进当前对话的同时,muse_open 还会触发 open-panel 事件,让面板自动出现在右侧边栏——所以从聊天里打开和从开关打开看到的是同一个视图。

开关

  • 关闭:session/leave + 结束 muse serve 子进程;聊天工具随后会提示先打开开关。关闭不会删除 Muse 自己的会话日志。
  • 开启:读取 %LOCALAPPDATA%\Programs\muse\.muse-version,定位 muse-bin-<version>.exe(绕过 launcher 的在线更新检查),以

serve --provider meta --trust-workspace 启动;然后在工作区根目录执行 session/start(审批模式 onRequest)。

用户开启「无沙箱模式」时,spawn 追加 --disable-sandbox(见下节)。

  • 工作区:优先取发起操作的 DSH 会话的项目目录(聊天工具用当前 agent 的目录;面板开关用 slot 提供的 sessionId,

取不到时退回当前工作目录),并记进状态文件;重启插件后按记住的目录恢复。第一个打开 Muse 的 DSH 会话决定工作区,

之后的会话沿用(见「已知限制」)。

  • 状态文件:~/.dsh/muse-code.json,内容 { enabled, disableSandbox, workspace }。插件重载后按它恢复开关与无沙箱选项。

花费上限(默认 $10,硬停止)

每次 Muse 会话都受一个本地花费护栏(lib/budget.js)约束:上限默认 $10,达到后自动强制停止,之后不再发起任何模型调用。护栏保证的是「最坏情况」,不是账单读数:

  • 计价来源:Muse CLI 自带的模型价格目录(~/.local/share/muse/model-catalog/*.json,按 mtimeMs 取最新一份),每个模型有 input / output / cached 单价(USD / 1M tokens)、context_limit、output_limit。
  • 最坏成本预留:一次调用最多花

R = context_limit × input单价 / 1e6 + output_limit × output单价 / 1e6

(上下文窗口和输出上限是硬上限,所以单次调用不可能超过 R)。每次调用完成后(MSP session/tokenUsage)记录花费;只要 已花费 + R > 上限 就立即锁定,而不是等真的花满 $10。不使用平均/历史成本做预留。

  • 未知模型:目录里查不到、或该行没有 cost 时,用目录中最贵的价格计算本地成本与预留,宁可多留余量。
  • 面板顶部的花费栏实时显示 花费 / 上限、剩余、进度条(剩余不足 20% 变琥珀色)、当前安全预留 R,以及锁定原因与解锁表单;muse_status 也会输出同样的花费行。

实测最坏单次成本(本机目录):

模型 · input / output / cached(USD/1M) · context_limit / output_limit · 最坏单次

muse-spark-1.3-contributor(默认) · 0.10 / 0.20 / 0.002 · 1,007,997 / 128,000 · $0.1264

muse-spark-1.3 · 1.25 / 4.25 / 0.15 · 同上 · $1.804

muse-wonder-1.0 · 4 / 20 / 0.2 · 同上 · $6.592

锁定与解锁

锁定后(locked=true 已同步落盘):

1. 尽力 turn/interrupt,再 session/leave 并结束 muse serve 子进程;

2. 面板开关自动关闭;prompt、打开开关、聊天工具(muse_prompt / muse_open)与插件启动时的开关恢复全部拒绝(重启 DSH 不会把会话拉起来);

3. 面板出现「已触发花费上限」提示,输入框与发送按钮禁用。

解锁只有两条路,入口是面板花费栏(没有对应的聊天工具,模型不能自己解锁):

  • 提高上限:输入新的美元上限(0 < cap ≤ 100000)。只有 已花费 + 当前预留 ≤ 新上限 才会真正解锁,否则保持锁定(避免解锁后下一次调用立刻越界)。
  • 重置花费记录:清空本地账本并解锁,保留当前上限。面板要求输入 RESET 二次确认(HTTP 侧对应 confirm: true)。

HTTP 侧:GET /budget 只读,POST /budget 接受 { action: 'set-cap', capUsd } 或 { action: 'reset', confirm: true };成功后广播 budget + snapshot。

账本

~/.dsh/muse-code-spend.json(version: 1)。记录上限、锁定状态与每个 Muse 会话的花费估计:

{
  "version": 1,
  "capUsd": 10,
  "locked": false,
  "lockedCode": null,
  "lockedReason": null,
  "lockedAt": null,
  "spentUsdAtLock": null,
  "lastModelId": null,
  "catalogPath": null,
  "sessions": {
    "<sessionId>": { "serverUsd": 0, "localUsd": 0, "turnUsd": 0, "partial": false, "lastModelId": "muse-spark-1.3-contributor", "updatedAt": 0 }
  }
}
  • 会话花费 = max(serverUsd, localUsd, turnUsd):服务端上报的 cumulative.cost.usd、按模型目录重算的累计估计、逐回合累计的估计,三者取最大以避免重复计数。
  • 账本损坏 → 锁定(fail-closed):JSON 解析失败或 version 不认识时,坏文件改名为 muse-code-spend.json.corrupt-<时间戳> 保留,插件进入锁定态(ledger-corrupt),绝不静默清零。
  • 目录不可用 → 只拒绝、不锁定:读不到模型目录时无法计算预留,护栏以 catalog-missing 拒绝新的调用(fail-closed),但保持未锁定;目录恢复后重新读取即可继续。
  • 锁定原因(lockedCode):cap-reached(已花到上限)、safety-margin(剩余不足以覆盖下一次最坏成本)、ledger-corrupt、manual;catalog-missing 只是暂停,不写锁定。

边界

  • 护栏只管本插件启动的 muse serve。你自己在终端里跑的 muse / muse serve、以及其它工具启动的 Muse 都不受这个上限约束。
  • 花费是按模型目录价格估算的;Muse 服务端实际计费若与目录不同,估算会偏保守或偏松。服务端上报 cost.usd 时会一并记录(取三者最大),但不保证等于真实账单。
  • 上限累计在本机账本里,不是 Muse 账户余额:换机器或删除账本后从零开始。

沙箱限制(本机实测)

muse serve 在本机 initialize 始终返回 sandboxAvailability: "unavailable",因此 Muse 的 shell 工具会直接失败:

tool failed: environment failure: sandbox enforcement unavailable:
windows_elevated setup_required: windows elevated sandbox setup has not run

muse sandbox windows check 显示各项 ready,muse exec --yolo 能正常执行命令——故障只出现在 serve 模式,

且 serve --disable-sandbox 时不会产生任何 approval/requested(已实测):

沙箱是唯一阻断层,禁用它等于完全放行、不逐条审批。

因此插件默认 fail-closed,并在面板顶部显示琥珀色告警与补救命令:

muse sandbox windows check
muse sandbox windows setup

面板里还有一个仅用户可点的「允许无沙箱运行(危险)」开关:开启后 spawn 追加 --disable-sandbox,

面板常驻红色告警,且不会再有审批卡。该开关没有对应的聊天工具,模型无法翻转它;值持久化在状态文件里。

工具

工具 · 作用

muse_open · 打开开关并启动/复用会话(与点击开关等价),并让面板出现在右侧边栏

muse_prompt · 给 Muse 发任务(steer: true 插入当前回合)

muse_read · 读取最近对话(用户、Muse 回复、工具调用、终端输出)

muse_status · 会话、回合、上下文用量、花费与安全预留、沙箱状态、待审批/待回答

muse_interrupt · 打断当前回合

工具只读或驱动执行;approval/decide、userInput/answer、无沙箱开关都不暴露成工具。

HTTP 路由

所有路由都挂在 /plugins/dsh-muse-code 下,且只接受回环地址(127.0.0.1 / ::1 / ::ffff:127.0.0.1,否则 403)。

方法 · 路径 · 用途

GET · /state · 当前快照 { ok, loading, busy, snapshot }

GET · /events · SSE 推送(见下)

POST · /enable · { enabled, sessionId? } 开关

POST · /prompt · { text, steer?, sessionId? } 发送任务

POST · /interrupt · {} 停止当前回合

POST · /approval · `{ approv

…(truncated)

Rendered from the README published on npm. Formatted only, not edited.

Versions

Published on npm::2,最后更新 2026-10-23

Links

GitHub · Homepage · npm

Same category