- new economy and maximum agent presets with three-role pipeline skill - new packages/extensions/tool-lab (home-lab ComfyUI/Docling/Whishper tools) - new packages/subagent/subagent-cursor provider - openrouter balance UI with on-demand refresh - session projection context-seed boundary fold - regenerate docs catalogs; keep local searxng benchmark scripts
@deepseek-ai/dsh-subagent-cursor
English | 中文
This package registers the fixed cursor subagent provider. Each accepted run starts the official cursor-agent CLI in non-interactive print mode in the delegating Session's workspace, submits one self-contained text task, reads the CLI's stream-json event stream, and returns only the final answer through the shared dsh-subagent result contract.
Start and ownership
start(request) accepts only a non-empty sequence of text blocks and derives the child cwd from the parent Session. It resolves cursor-agent through dsh-subprocess, spawns the fixed command, and publishes the run only after the CLI's system/init event announces its own chat id — the point at which the CLI has started and resolved its credentials and model. A failure or cancellation before that announcement terminates the managed process tree, waits for it to exit, and rejects start().
The task crosses the boundary as a positional command-line argument, because that is the only prompt channel print mode offers: the CLI documents no -- end-of-options separator and reads no prompt from stdin. Two consequences are enforced rather than papered over. A task whose first character is - is rejected at admission, since the CLI would parse it as an option. A resolved Windows .cmd or .bat shim is rejected as well, because only cmd.exe can run it and its command tail would reparse model-authored text as shell syntax; PATHEXT resolution prefers the cursor-agent.exe that the native Windows installer provides. Stdin is closed immediately after spawn, so a prompt the CLI still tries to read fails fast instead of stalling an unattended child on an answer nobody can give.
The published run.result waits for the authoritative terminal result event and accepts only subtype: "success" with is_error: false and a nonblank result. Every other terminal event, malformed stdout line, stream failure, or end of stream without a result maps to error; print mode carries no machine-readable failure taxonomy, so the provider produces neither max-tokens nor refusal. user, tool_call, and event kinds a newer CLI adds contribute nothing to this contract.
Print mode has no reply channel, so there is no protocol interrupt: cancellation is the run's abort signal, which the subprocess seam turns into its termination escalation while the result settles immediately as aborted with the last non-empty assistant message collected so far. dispose() is idempotent: it detaches the event stream, invokes the shared process-tree termination escalation, and waits for whole-tree exit. Result failure and independent teardown failure remain separate.
Capabilities and context
The provider advertises no optional start-time capabilities and reports inheritsParentContext: false. Cursor receives the standalone text task and the parent Session cwd, but not the parent conversation, persona, tool filter, depth policy, or structured-output contract. The CLI's own chat id and model stay private to the run and are never persisted in the parent Session.
Configuration
| Key | Default | Meaning |
|---|---|---|
env |
{} |
Explicit child environment layered over the subprocess seam's credential-scrubbed parent environment. |
disposeGraceMs |
3000 |
Positive finite grace in milliseconds, no greater than MAX_TIMER_DELAY_MS, between the shared process-tree owner's termination tiers; disposal then waits for whole-tree exit. |
force |
false |
Pass --force, letting the child apply file changes and run commands. Cursor's own print-mode default only PROPOSES changes, so a delegation expected to edit the workspace needs this on. |
trust |
false |
Pass --trust, letting the child act in the workspace without Cursor's interactive trust prompt an unattended child cannot answer. |
Production resolves cursor-agent from the subprocess execution world's credential-scrubbed PATH, with explicit env entries applied, and uses the host's native Cursor configuration and authentication. The plugin does not install the CLI, select a model, create a Cursor home, log in, or probe a version. Credential-shaped ambient variables are removed by the subprocess seam, so a CURSOR_API_KEY intended for the child must be supplied in env; it is never passed as --api-key, where a process listing would expose it. Ordinary ambient values such as PATH and HOME remain available unless overridden.
The dsh-base host plane mounts this provider, and the code, cordis, and standard Agent Presets carry an enabled subagent_cursor tool row; the economy preset keeps it disabled: true because an economy composition should not reach for external paid agents by default. Loading the provider starts no Cursor process until a tool call. Its one-shot policy keeps omitted or false run_in_background calls in the foreground, while explicit true returns a parent-owned Job id for job_output or job_kill.
The standalone composition below shows the complete explicit capability. A Profile based on @deepseek-ai/dsh-base keeps its existing Job rows and provider row and enables only the preset tool row instead of mounting duplicates.
- 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
Product compatibility and evidence
The provider reads only the print-mode events this one-shot contract needs: system/init to publish, assistant to snapshot partial output, and result to settle. Deployments supply cursor-agent on PATH; the CLI is not an npm dependency of this package, so unit evidence drives the real event stream through the subprocess seam rather than a pinned binary.
The CLI also speaks the Agent Client Protocol as cursor-agent acp, which the generic dsh-subagent-acp provider can drive with configuration alone. That path exists for a deployment that wants ACP's permission auto-answer policy or a long-lived remote session; this package exists for the one-shot delegation contract, its own subagent_cursor tool row, and print mode's simpler failure surface.
Model Experience
Child request
What the model sees
The Cursor child receives the concatenated text task as one positional prompt in a fresh print-mode run. Its workspace is the parent Session cwd, and its model, system instructions, tools, and authentication come from the native Cursor installation and configuration.
Token effect
The child pays for an independent Cursor context and turn. Child tokens do not enter the parent's context.
KV Cache effect
Independent of the parent request cache. Reuse depends only on Cursor's own model, instructions, tools, and per-run request.
Parent scheduling and results, indirectly
What the model sees
Through dsh-tool-subagent, a foreground call gives the parent the terminal Cursor answer or the consumer's exact error for a non-completed result. A background call first returns a Job id; the generic job controls later deliver a completion notice, expose the final answer and status through job_output, and let job_kill request cancellation. Cursor's intermediate messages, tool activity, stderr, workspace diffs, usage, and product ids are not copied into the parent Session.
Token effect
Foreground input grows by the retained final answer or error. Background input also includes the start acknowledgement, completion notice, and any job_output, job_kill, or later status results; child tokens still do not enter the parent context. This provider adds no parent tool schema by itself.
KV Cache effect
Append-only: foreground adds one result after the reusable parent prefix, while background appends the Job acknowledgement, notice, and later control or collection results. Background scheduling can add a notice-driven turn, but none of these messages rewrites the earlier prefix.
Known Limitations and Deferred Work
- One fresh process and run per delegation — there is no continuation,
--resume, pooling, progress stream, or product-session persistence, even though the CLI itself supports resuming a chat by id. - The task cannot begin with
-— print mode takes the prompt positionally and documents no--separator, so such a task is rejected at admission instead of being mis-parsed as an option. - Windows needs the native executable — a resolved
.cmdor.batshim is rejected rather than run throughcmd.exe, whose command tail would reparse the task text. - Host-managed product installation and account state — a missing
cursor-agent, configuration error, or authentication failure is surfaced as a startup or run error; the plugin provides no installer, login flow, or runtime version gate. - No graduated approval path —
forceandtrustare whole-run deployment switches; there is no per-call policy, allowlist, or human approval channel through this package. - No failure taxonomy — print mode reports only a terminal subtype and error marker, so a context-window ending is indistinguishable from any other failure and never maps to
max-tokens. - Product payload is final text only — intermediate messages, tool traffic, usage, stderr, and workspace diffs remain product-local; generic Job ids, notices, and status come from the shared job runtime.
- No optional shared capabilities — output schemas, child personas, tool filtering, and harness depth enforcement are rejected by the shared service for this provider.
- No wall-clock timeout or side-effect rollback — the caller cancels long work, and files or external systems changed before cancellation are not restored.