Files
deepseek-harness/packages/bundle/headless
Turtle 925daf141b fix: address ds-review-bot round — insert-aliasing clones, settlement gates, closure module fallback
- Clone patch lists per generation (boot + composeLive): the include pushes
  insert rows by reference and mutates them in place, so a reused object
  baked user overrides into bundle rows and removal could not revert; the
  built-bin hot-reload e2e now asserts an override AND its removal reverting.
- The headless runner awaits Loader settlement before prompting (its inject
  gate covers only apiProxy/httpServer) and abandons cleanly when the tree
  died during the wait.
- healProfilesModuleFallback walks the app's full dependency+peer closure:
  out-of-tree plugins import seam packages (dsh-compact, dsh-subprocess, ...)
  that only implementations reach, and peers are how seams are declared.
- Profile init writes pnpm-workspace.yaml (nodeLinker: hoisted), not .npmrc
  — pnpm >=10 reads settings from the workspace manifest.
- Web dumps reject boot-only flags instead of printing a tree that differs
  from the same invocation's boot; --port validates at the flag;
  --dump-default-config no longer parses the (possibly broken) user layer;
  trustedHosts flag derivation merges over the composed value instead of
  replacing it; web-runtime gains surfaceContext (headless disables the GUI
  prompt/bash-vars the old -p never mounted); 'node_modules' is a reserved
  profile name; plugin-warning names the recovery step; client AGENTS.md
  registration surfaces point at the web-app bundle.
- Ship session-reference/tmux-context/tool-ask-user as app dependencies for
  terminal front-door patch layers (turtle-ui), same stance as mcp-client.
2026-08-06 09:27:44 +08:00
..

@deepseek-ai/dsh-headless

English | 中文

The dsh one-shot bundle. cordis.patch.yml rides over dsh-base + dsh-web-app: it moves the webserver to an OS-assigned port (parallel runs never collide), silences the URL line, and inserts this package's headless-runner plugin (config {task}). The runner drives one task turn through the in-process API carrier (InProcessApiClient over toFetchHandler(ctx.apiProxy), so the full wire chain — serialization, zod, SSE framing — really runs), aggregates the turn's final assistant text, writes it to stdout, and requests exit (completed → 0, else 1) through the launcher-provided ctx.headlessIo seam. The Web composition stays mounted, so the running session is observable in a browser at the stderr-announced URL. The launcher patches the task text in (dsh --profile headless "task"), and fails loud when a task is given to a profile without this row.

Model Experience

None, as the runner submits the task as an ordinary user message over the shared composition; prompts and tools belong to the base/web bundles.

KV Cache effect

None; the runner adds nothing to the request prefix.

Known Limitations and Deferred Work

  • One turn only — the runner anchors on the first message-triggered turn and exits at its end; queued follow-ups and multi-turn tasks are out of scope.
  • ctx.headlessIo is launcher-owned — booting the headless profile outside the dsh launcher fails loud at activation until the host provides the seam.