dsh-cross-session-approval

sessiontested: passnpmMIT

Cross-session task delegation for DeepSeek Harness: spawn durable top-level sessions and send them tasks, read or steer them by base62 session alias, and approve their sandbox escalation requests through an approval bridge that refuses destructive deletes.

下载量 / Downloads
1,073
依赖体积 / node_modules
11.16 MB
测试时间 / Tested
2026-11-06
DSH 版本 / Version
0.2.2-rc.1

Install

dsh plugin --profile web add dsh-cross-session-approval

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

dsh-cross-session-approval(0.3.10)

DeepSeek Harness(DSH)0.2.x 的跨会话任务派发插件(bundle),提供 10 个工具:创建顶层持久会话、发送任务、回传结果、查询状态与消息、列出会话、批量投递、改名、归档及跨会话审批。

插件包含跨会话审批桥、子会话权限夹紧(A:发布前三维;F:派生入口),以及用于会话寻址的 cs_ base62 别名。创建任务后即可继续当前会话,任务结果通过回信返回。

派活登记保存在 <工作区>/.cross-session/registry.json,以临时文件加原子重命名写入。它包含任务正文和回复摘要,可能涉及敏感信息,应作为工作区本地数据保管。登记读取失败会阻止依赖该读取的操作;写入失败会告警,已完成的投递不会因此撤回。

安装与加载

需要 Node.js 18 或以上,以及已配置可用模型的 DeepSeek Harness 0.2.x profile。宿主 peer 依赖要求为 >=0.2.0-rc.2 <0.3.0;具体依赖见 package.json。本插件是宿主 bundle,不是独立运行的 MCP 服务。

以下以名为 dev 的 profile 为例;请替换为实际 profile 名。克隆需要具备该 GitHub 仓库的读取权限。

$profileName = 'dev'
$profileDir = Join-Path $HOME ".dsh/profiles/$profileName"
$bundleDir = Join-Path $profileDir 'node_modules/dsh-cross-session-approval'
git clone https://github.com/zsjs110110-cpu/dsh-cross-session-approval.git $bundleDir

在该 profile 的 package.json 中,将 dsh-cross-session-approval 追加到 dsh.profile.bundles。以下仅展示相关字段,保留已有配置与其他 bundle:

{
  "dsh": {
    "profile": {
      "bundles": ["dsh-cross-session-approval"]
    }
  }
}

校验组合配置,再启动宿主加载插件:

dsh --profile $profileName --dump-config
dsh --profile $profileName --no-open --port 0

配置输出应包含 cross-session-approval,且无该 bundle 的 skipping;启动时应无该插件的 failed to import。进入该 profile 的会话后,确认可用工具包含下列 10 项。配置校验成功不代表审批桥已启用;还需检查启动告警及下文的服务要求。

快速使用

下面是 DSH 会话内的工具调用示例,不是 PowerShell 命令或可直接导入的 JavaScript API。cs_XXXXXXXXXX 表示工具实际返回的别名,使用时必须替换。

cross_session_spawn({ name: "检查文档", task: "阅读 README,列出安装步骤中的歧义;完成后回复结果。" })
// 保存返回的 session_id(cs_ 别名);spawn 返回后任务仍可能在执行。
cross_session_status({ session_id: "cs_XXXXXXXXXX" })
cross_session_read({ session_id: "cs_XXXXXXXXXX", tail: 10 })
cross_session_send({ session_id: "cs_XXXXXXXXXX", message: "请再核对配置示例。", interrupt: false })

默认继承调用者的模型、推理程度与 agent preset(自定义模式)。spawn 会在任务消息中自动附上回信目标;任务会话应按指引调用 cross_session_reply({ to: "<回信目标别名>", text: "结果摘要或失败原因" })。回信按用户消息投递,并唤醒目标。投递成功与任务完成是两个不同状态,请结合回信及 read 判断结果。

建议先不传 permission 和 cwd,使用默认权限夹紧与当前工作区。显式权限、跨工作区寻址和审批桥的限制见下文。

工具一览

工具 · 必填参数 · 可选参数与行为

cross_session_spawn · name, task · reply_to, provider, model, reasoning_effort, permission, agent_preset, cwd, tags;创建顶层持久会话并投递任务,不等待完成

cross_session_send · session_id, message · wake、interrupt 默认 true;reply_to 指定回信目标;未打开的顶层会话自动恢复

cross_session_reply · to, text · 向指定会话回信并唤醒,目标未打开时自动恢复

cross_session_status · 无 · session_id 筛选当前工作区的派活登记,省略则查看登记总览

cross_session_read · session_id · tail 默认 10、最大 50;include_attempts 附带诊断事件;读取不唤醒目标

cross_session_list · 无 · limit 默认 20;include_archived, cwd, all_workspaces, tag;默认列当前工作区的顶层会话

cross_session_broadcast · targets · 最多 20 项,每项为 { session_id, message, wake?, interrupt?, reply_to? };逐项报告成功或失败

cross_session_rename · session_id, name · 标题长度为 1–60 字符

cross_session_archive · session_id · 归档会话

cross_session_approve · key, decision · decision 为 allow 或 reject;note 为可选备注;仅请求会话的创建者可处理

send 默认在目标当前步骤结束后插入消息;interrupt: false 等当前整轮结束;wake: false 只投递、不唤醒。所有会话标识优先使用工具返回的 cs_ 别名;参数名仍为 session_id、to 或 reply_to。

单条任务或消息正文按 32 KiB UTF-8 配额截断。登记表最多保留 200 条任务记录,超出时淘汰最久未活动的登记;登记表不是完整会话历史。读取与广播可能涉及其他会话的任务内容,请按实际授权范围选择目标。

会话 ID 与短别名

部分宿主或上游显示链路会将模型可见文本中的 32 位十六进制串或 UUID 替换为占位符,例如 session-00000000-0000-4000-8000-000000000000。这不改变内存或磁盘中的真实会话 ID,但从显示文本复制占位符无法正确寻址。

插件用 FNV-1a 确定性派生 cs_ 加 10 位 base62 字符的别名(总长 13),例如 cs_xwx698M4Wa。cross_session_list 和 cross_session_status 返回 alias,文本列表使用该别名。别名不单独落盘,同一版本下由真实 ID 按需重算,重启不改变结果;0.3.8 的别名迁移见版本记录。

输入 · 解析行为

被遮蔽的占位符,含 session- 前缀形式 · 拒绝,并提示使用别名

cs_ 别名 · 在登记表与宿主当前工作区可见会话中匹配;找不到则报错

其他字符串 · 作为真实 ID 原样交给宿主处理

session_id、to 等参数名保持不变,没有单独的 alias 参数。别名用于寻址,不是授权凭据,也不构成权限隔离;解析后仍按真实会话 ID 做身份与权限判断。短哈希不保证数学上无碰撞。

子会话权限夹紧(发布前三维 + 派生入口,0.3.0)

权限夹紧同时检查沙箱档位、审批策略和工作区。沙箱档位从窄到宽为 read-only、workspace-write、danger-full-access;审批策略中 never 比 ask 更严格:它会拒绝需要提权审批的请求。

A:发布前三维夹紧

默认 spawnPermission: cap。cross_session_spawn 的可选参数:

  • permission:宿主权限预设名。省略时,档位取调用者与部署默认预设中较窄者,审批取更严格者;显式预设的任一维比调用者更宽则拒绝,不静默降级。
  • agent_preset:宿主提供的 agent preset(自定义模式)ID。默认继承调用者;显式指定不存在的模式会报错并附可用列表。它影响工具和提示词,沙箱权限及模型路由由各自配置控制。
  • cwd:已存在的绝对目录,默认取调用者解析出的工作区根目录。非最高档调用者只能选择其工作区根目录或内部目录,按 realpath 校验,指向外部的 junction 不算包含;最高档调用者可指定任意已存在绝对目录。选择不同目录会另开工作区,见下文已知边界。

插件在 session/created 的同步前置监听器中重新解析调用者当前策略,写入沙箱档位与审批策略,再逐项精确读回复核。工作区须与创建意图一致;预设名仅在实际权限值与所选预设匹配时写入。任一步失败则拒绝创建,不投递任务。派发期间调用者权限发生变化也会拒绝,调用者需重试;投递前还须核对绑定该 Session 实例的夹紧凭证。

以部署默认 workspace-write/ask 为例(省略 permission、cwd):

调用者档位 / 审批 · 子会话档位 / 审批

workspace-write/ask · workspace-write/ask

danger-full-access/ask · workspace-write/ask

danger-full-access/never · workspace-write/never

read-only/ask · read-only/ask

read-only/never · read-only/never

上述子会话工作区均为调用者工作区。spawnPermission: off 关闭 A,恢复宿主默认创建行为,可能使低权限调用者创建出更高权限的会话;启用审批桥必须使用 cap。

显式同档权限的边界

显式 permission 只拒绝比调用者更宽的权限,允许与调用者相同的权限。例如部署配置了 full-ask(danger-full-access/ask)时,同档调用者显式指定 permission: "full-ask" 可以创建同档子会话;省略该参数则仍按部署默认值夹紧。

这是当前契约的结果。插件没有独立的子会话最高预设配置,无法保证子会话始终严格低于创建者。非必要时省略 permission;确需最高档权限时,应先向用户说明并取得授权。使用约定与界面提示不能替代权限限制。

F:派生入口夹紧

同一监听器处理非 A、带 parentSession 的会话创建通知,包括 fork 和恢复派生会话。默认 forkPermission: cap:

  • 源会话活跃:按源当前策略限制三维权限。工作区必须在源工作区内,源为最高档时跳过此包含检查。
  • 源会话未加载:cap 按部署默认预设与部署根目录限制;越界或 realpath 解析失败则拒绝。此上限不代表源会话的当前权限。strict 直接拒绝未加载源的派生。
  • off:关闭 F,不访问 F 的可选权限服务。

F 只修改需要收窄的沙箱档位和审批策略,不写 permission/preset,写后读回复核。权限服务缺失时,启用的 A/F 对应创建路径拒绝。A/F 独立于审批桥:关闭桥不关闭 A/F,关闭 F 不影响 A。恢复派生会话也可能被收窄或拒绝。

跨会话审批桥(0.3.0)

由 cross_session_spawn 创建的任务会话,在 pwsh 或 run_code 请求沙箱提权时,可将审批交给其创建者会话(下称 owner)。owner 必须在同一宿主中保持活跃;本版不会为审批恢复未加载的 owner。

桥在宿主根上下文中优先处理 approval/request,处理链如下:

1. 身份与所有者:用 carrierKeyOf(this) === request.agent 校验请求载体。所有者只在 spawn 时按真实调用者写入内存;send、`broad

…(truncated)

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

Versions

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

Links

GitHub · Homepage · npm

Same category