# @deepseek-ai/dsh-subagent-cursor [English](README.md) | 中文 本包注册固定的 `cursor` subagent 提供方。每次接受运行请求后,它都会在发起委托的会话工作区中以非交互 print 模式启动官方 `cursor-agent` CLI,提交一个自包含的文本任务,读取该 CLI 的 `stream-json` 事件流,并通过共享的 [`dsh-subagent`](../subagent/README.md) 结果约定仅返回最终答案。 ## 启动与所有权 `start(request)` 只接受非空的文本块序列,并根据父会话确定子级 cwd。随后,它通过 [`dsh-subprocess`](../../subprocess/subprocess/README.md) 解析 `cursor-agent`,spawn 固定命令,且仅在该 CLI 的 `system`/`init` 事件公布其自有会话 ID 之后才发布此次运行——那正是该 CLI 已启动并解析出自身凭证与模型的时刻。若在此公布之前发生失败或取消,它会终止受管进程树并等待其退出,然后拒绝 `start()` 调用。 任务以位置命令行参数的形式跨越进程边界,因为这是 print 模式提供的唯一提示词通道:该 CLI 未记载 `--` 选项终止符,也不从标准输入读取提示词。由此产生的两项后果被强制约束,而非含糊掩盖。首字符为 `-` 的任务在准入阶段即被拒绝,因为该 CLI 会将其解析为选项。解析到 Windows `.cmd` 或 `.bat` 包装脚本同样被拒绝,因为只有 `cmd.exe` 能运行它,而其命令尾部会把模型撰写的文本重新解析为 shell 语法;PATHEXT 解析会优先选择原生 Windows 安装程序提供的 `cursor-agent.exe`。标准输入在 spawn 后立即关闭,因此该 CLI 若仍尝试读取提示词,会快速失败,而不是让无人值守的子级停滞在无人能给出的答案上。 已发布的 `run.result` 会等待权威的终止 `result` 事件,且只接受 `subtype: "success"` 且 `is_error: false` 并带非空白 `result` 的事件。其他任何终止事件、格式错误的标准输出行、流失败,或流结束时仍无结果,都映射为 `error`;print 模式不携带可供程序判读的失败分类,因此该提供方既不会产生 `max-tokens` 也不会产生 `refusal`。`user`、`tool_call` 以及更新版 CLI 新增的事件类别对本约定没有贡献。 print 模式没有回复通道,因此不存在协议层中断:取消即本次运行的中止信号,子进程 seam 会将其转为逐级终止机制,同时结果立即判为 `aborted`,并携带此前收集到的最后一条非空助手消息。`dispose()`(资源释放)具有幂等性:它会摘除事件流监听、调用共享的进程树逐级终止机制,并等待整棵进程树退出。结果失败与独立的清理失败仍彼此分离。 ## 能力与上下文 本提供方不声明任何可选的启动时能力,并报告 `inheritsParentContext: false`。Cursor 会接收独立文本任务和父会话 cwd,但不会接收父会话的对话、角色设定、工具筛选器、深度策略或结构化输出约定。该 CLI 自有的会话 ID 与模型仅在此次运行内部可见,绝不会持久化到父会话。 ## 配置 | 配置键 | 默认值 | 含义 | |---|---|---| | `env` | `{}` | 显式指定的子进程环境,叠加在由子进程 seam 清除凭证后的父环境之上。 | | `disposeGraceMs` | `3000` | 共享进程树责任方各终止层级之间的宽限期,单位为毫秒且须为正有限值,并不得大于 [`MAX_TIMER_DELAY_MS`](../../util/timeout/README.md);随后资源释放会等待整棵进程树退出。 | | `force` | `false` | 传入 `--force`,允许子级实际应用文件改动并执行命令。Cursor 自身的 print 模式默认只“提出”改动,因此预期要编辑工作区的委托需要开启此项。 | | `trust` | `false` | 传入 `--trust`,允许子级在不经过 Cursor 交互式信任提示的情况下在工作区中行动——无人值守的子级无法回答该提示。 | 生产环境会从子进程执行环境中已清除凭证的 `PATH` 里解析 `cursor-agent`,并叠加显式 `env` 条目,同时使用宿主机原生的 Cursor 配置与身份验证。本插件不安装该 CLI、不选择模型、不创建 Cursor 主目录、不执行登录,也不探测版本。子进程 seam 会移除具有凭证特征的环境变量,因此供子进程使用的 `CURSOR_API_KEY` 必须在 `env` 中提供;它绝不会作为 `--api-key` 传入——那会让进程列表暴露它。除非被覆盖,`PATH` 和 `HOME` 等普通环境变量值仍然可用。 `dsh-base` 宿主平面会挂载本提供方,`code`、`cordis` 与 `standard` Agent Preset 均携带已启用的 `subagent_cursor` 工具行;`economy` preset 保留 `disabled: true`,因为经济模式的组装不应默认动用外部付费 agent。加载提供方本身不会在工具调用前启动 Cursor 进程。其 `one-shot` 策略会让省略 `run_in_background` 或传入 `false` 的调用继续在前台等待,而显式传入 `true` 会返回由父 agent 拥有的 Job ID,供 `job_output` 或 `job_kill` 使用。 下面的独立组装展示了完整的显式能力。基于 `@deepseek-ai/dsh-base` 的 Profile 会保留其既有的 Job 行与提供方行,只需启用 preset 中的工具行,而不必挂载重复项。 ```yaml - id: subagent-cursor name: '@deepseek-ai/dsh-subagent-cursor' config: force: true trust: true env: CURSOR_API_KEY: !!js process.env.CURSOR_API_KEY - id: jobs name: '@deepseek-ai/dsh-jobs-local' - id: tool-jobs name: '@deepseek-ai/dsh-tool-jobs' - id: tool-subagent-cursor name: '@deepseek-ai/dsh-tool-subagent' config: provider: cursor toolName: subagent_cursor backgroundMode: one-shot maxDepth: provider-managed ``` ## 产品兼容性与证据 本提供方只读取这一 one-shot 约定所需的 print 模式事件:`system`/`init` 用于发布运行,`assistant` 用于快照部分输出,`result` 用于结束运行。部署方需在 `PATH` 上提供 `cursor-agent`;该 CLI 不是本包的 npm 依赖,因此单元证据通过子进程 seam 驱动真实事件流,而不依赖固定版本的二进制文件。 该 CLI 还能以 `cursor-agent acp` 讲 Agent Client Protocol,通用的 [`dsh-subagent-acp`](../subagent-acp/README.md) 提供方仅凭配置即可驱动它。那条路径适用于需要 ACP 权限自动应答策略或长期远端会话的部署;本包存在的意义在于这一 one-shot 委托约定、自有的 `subagent_cursor` 工具行,以及 print 模式更简单的失败面。 ## Model Experience ### 子级请求 #### 模型看到什么 Cursor 子级会以一次全新的 print 模式运行,接收拼接后的文本任务作为单个位置提示词。其工作区是父会话 cwd,而模型、系统指令、工具与身份验证均来自宿主机原生的 Cursor 安装与配置。 #### Token 影响 子级为独立的 Cursor 上下文与轮次付费。子级 token 不会进入父级上下文。 #### KV 缓存影响 与父级请求缓存互相独立。复用只取决于 Cursor 自身的模型、指令、工具与本次运行的请求。 ### 父级调度与结果(间接) #### 模型看到什么 通过 `dsh-tool-subagent`,前台调用会把终止事件中的 Cursor 答案交给父级,若结果并非完成状态,则交给消费方的确切错误。后台调用先返回一个 Job ID;通用作业控制工具随后送达完成通知,通过 `job_output` 暴露最终答案与状态,并允许 `job_kill` 请求取消。Cursor 的中间消息、工具活动、标准错误、工作区差异、用量与产品 ID 都不会复制进父会话。 #### Token 影响 前台输入会因保留的最终答案或错误而增长。后台输入还包含启动确认、完成通知,以及任何 `job_output`、`job_kill` 或后续状态结果;子级 token 仍不会进入父级上下文。本提供方自身不添加任何父级工具 schema。 #### KV 缓存影响 仅追加:前台在可复用的父级前缀之后追加一条结果,后台则追加 Job 确认、通知以及后续的控制或收集结果。后台调度可能新增一个由通知驱动的轮次,但上述任何消息都不会改写此前的前缀。 ## Known Limitations and Deferred Work - **每次委托对应一个全新进程与一次运行** —— 没有续接、`--resume`、进程池化、进度流或产品会话持久化,尽管该 CLI 本身支持按 ID 恢复对话。 - **任务不能以 `-` 开头** —— print 模式按位置接收提示词且未记载 `--` 终止符,因此这类任务在准入阶段即被拒绝,而不是被误解析为选项。 - **Windows 需要原生可执行文件** —— 解析到 `.cmd` 或 `.bat` 包装脚本会被拒绝,而不会通过 `cmd.exe` 运行——其命令尾部会重新解析任务文本。 - **产品安装与账户状态由宿主机管理** —— 缺失 `cursor-agent`、配置错误或身份验证失败会作为启动错误或运行错误上报;本插件不提供安装器、登录流程或运行时版本闸门。 - **没有分级审批路径** —— `force` 与 `trust` 是整次运行级别的部署开关;本包不提供按调用的策略、允许清单或人工审批通道。 - **没有失败分类** —— print 模式只报告终止子类型与错误标记,因此上下文窗口耗尽与其他任何失败无法区分,且绝不会映射为 `max-tokens`。 - **产品载荷仅为最终文本** —— 中间消息、工具流量、用量、标准错误与工作区差异仍留在产品本地;通用 Job ID、通知与状态来自共享作业运行时。 - **没有可选共享能力** —— 输出 schema、子级角色设定、工具筛选与 harness 深度强制均被共享服务针对本提供方拒绝。 - **没有挂钟超时或副作用回滚** —— 由调用方取消长时间工作,取消前已改动的文件或外部系统不会被还原。