Files
Coder 8719fa84f0
Some checks failed
CI / windows node 24 / wine blocking (push) Has been skipped
CI / node 22.19 (push) Has been skipped
CI / node 26 (push) Has been skipped
CI / python 3.10 / keyless SDK (push) Has been skipped
CI / python runtime / release-shaped Linux x64 (push) Has been skipped
CI / wine apt cache (push) Successful in 7s
CI / serial / linux (push) Has been skipped
Deploy documentation / build (push) Failing after 1m25s
Deploy documentation / deploy (push) Has been skipped
Landlock Run / Matrix (push) Successful in 5s
Release (vendor) / Pack npm tarballs (push) Failing after 2m47s
Release (dsh) / Pack npm tarballs (push) Failing after 1m56s
Sandbox / sandbox e2e (landlock, ubuntu-24.04) (push) Failing after 1m57s
Sandbox / sandbox e2e (bwrap, ubuntu-latest) (push) Failing after 1m19s
Release (vendor) / Publish to npm (push) Has been skipped
Release (dsh) / Publish to npm (push) Has been skipped
CI / serial / windows (self-hosted standby) (push) Has been cancelled
CI / larger-runner-benchmark (16, linux, dsh-ubuntu-24-04-16core, typecheck) (push) Has been cancelled
Landlock Run / darwin (no platform package — degradation proof) (push) Has been cancelled
Landlock Run / ${{ matrix.platform }} (push) Has been cancelled
CI / node 24 / static (push) Has been cancelled
CI / node 24 / coverage (push) Has been cancelled
CI / node 24 / snapshots and artifacts (push) Has been cancelled
CI / windows node 24 / native complete (push) Has been cancelled
CI / serial / linux (self-hosted standby) (push) Has been cancelled
CI / serial / macos (push) Has been cancelled
CI / larger-runner-benchmark (16, windows, dsh-windows-2025-16core, production-site) (push) Has been cancelled
CI / larger-runner-benchmark (32, linux, dsh-ubuntu-24-04-32core, typecheck) (push) Has been cancelled
CI / larger-runner-benchmark (32, windows, dsh-windows-2025-32core, production-site) (push) Has been cancelled
CI / larger-runner-benchmark (4, linux, dsh-ubuntu-24-04-4core, typecheck) (push) Has been cancelled
CI / larger-runner-benchmark (4, windows, dsh-windows-2025-4core, production-site) (push) Has been cancelled
CI / larger-runner-benchmark (64, linux, dsh-ubuntu-24-04-64core, typecheck) (push) Has been cancelled
CI / larger-runner-benchmark (64, windows, dsh-windows-2025-64core, production-site) (push) Has been cancelled
CI / larger-runner-benchmark (8, windows, dsh-windows-2025-8core, production-site) (push) Has been cancelled
CI / larger-runner-benchmark (96, linux, dsh-ubuntu-24-04-96core, typecheck) (push) Has been cancelled
CI / larger-runner-benchmark (96, windows, dsh-windows-2025-96core, production-site) (push) Has been cancelled
CI / consolidated-runner-benchmark (16, linux, dsh-ubuntu-24-04-16core, 16) (push) Has been cancelled
CI / consolidated-runner-benchmark (16, windows, dsh-windows-2025-16core, 2) (push) Has been cancelled
CI / consolidated-runner-benchmark (32, linux, dsh-ubuntu-24-04-32core, 32) (push) Has been cancelled
CI / consolidated-runner-benchmark (32, windows, dsh-windows-2025-32core, 2) (push) Has been cancelled
CI / consolidated-runner-benchmark (4, linux, dsh-ubuntu-24-04-4core, 4) (push) Has been cancelled
CI / consolidated-runner-benchmark (4, windows, dsh-windows-2025-4core, 2) (push) Has been cancelled
CI / consolidated-runner-benchmark (64, linux, dsh-ubuntu-24-04-64core, 32) (push) Has been cancelled
CI / consolidated-runner-benchmark (64, windows, dsh-windows-2025-64core, 2) (push) Has been cancelled
CI / consolidated-runner-benchmark (8, linux, dsh-ubuntu-24-04-8core, 8) (push) Has been cancelled
CI / consolidated-runner-benchmark (8, windows, dsh-windows-2025-8core, 2) (push) Has been cancelled
CI / consolidated-runner-benchmark (96, linux, dsh-ubuntu-24-04-96core, 32) (push) Has been cancelled
CI / consolidated-runner-benchmark (96, windows, dsh-windows-2025-96core, 2) (push) Has been cancelled
CI / all checks passed (push) Has been cancelled
Sandbox / sandbox e2e (seatbelt, macos-latest) (push) Has been cancelled
CI / larger-runner-benchmark (8, linux, dsh-ubuntu-24-04-8core, typecheck) (push) Has been cancelled
Sandbox / sandbox e2e (landlock, ubuntu-24.04-arm) (push) Has been cancelled
E2E (real DeepSeek API) / e2e (push) Failing after 1m24s
feat: add economy/maximum presets, tool-lab and subagent-cursor extensions
- 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
2026-08-23 22:12:30 +07:00

107 lines
10 KiB
Markdown

# @deepseek-ai/dsh-subagent-cursor
English | [中文](README.zh.md)
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`](../subagent/README.md) 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`](../../subprocess/subprocess/README.md), 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`](../../util/timeout/README.md), 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.
```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
```
## 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`](../subagent-acp/README.md) 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 `.cmd` or `.bat` shim is rejected rather than run through `cmd.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** — `force` and `trust` are 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.