Skip to main content

deepseek-harness-studio/packages/bundle/headless

403Stars43Forks2Issues2Watchers

DSH One-Time Task Runner: Submit a task via command line, execute with Agent, print final answer to stdout and exit.

Evidence5/5methodologySourceInstallMaintenanceDSH versionSecurity scan
Machine-auditedInstall commandRepo verifieddsh-plugin topicLicenseREADMEAI wiki

ⓘ This plugin is a sub-package of the fufankeji/deepseek-harness-studio monorepo — stars and activity count the whole repository.

Language
TypeScript
License
MIT
Branch
main
ai-agentdeepseekdeepseek-harnessdeepseek-harness-studiodesktop-appdeveloper-toolsdshdsh-plugin

Install

cmdweb profile
$ dsh plugin --profile web add @deepseek-ai/dsh-headless

Run the command above in your terminal to install this plugin via the dsh CLI. You can switch Profile in the top-right corner. New to dsh? Read the beginner tutorial

Install via your agent

Install the DeepSeek Harness plugin fufankeji/deepseek-harness-studio/packages/bundle/headless for me: review the repository at https://github.com/fufankeji/deepseek-harness-studio first, then run the install command and verify the plugin loads successfully.

Paste this instruction to the DSH Web GUI assistant — it will install and verify for you.

One-Line Description

DSH one-shot task runner package: submits a task text via command line, lets the built-in Agent execute it, prints the final assistant reply to stdout and exits. It doesn't open ports or bring a Web UI, only reuses the core capabilities of dsh-base.

Core Capabilities

  • Parses the dsh --profile headless "<task>" command line, concatenates multi-word positional arguments into a single task, and rejects missing or empty tasks before startup (src/startup.ts:31-55).
  • Creates a brand new persistent Agent via ctx.agents, submits the task as a normal user message, and waits for the Agent to naturally return to idle (src/index.ts:111-126).
  • Flushes the session to disk (reusing dsh-base's JSONL session persistence), aggregates all events in this execution interval, takes the last non-empty assistant text and writes it to stdout (src/index.ts:127-129).
  • Determines the exit code based on the final turn/end reason: exits 0 for completed, exits 1 for everything else (including aborted/error); when there's an error, it also writes the error code and message to stderr (src/index.ts:129-133).
  • Requests exit through the launcher-provided ctx.appExit main process hook, and ensures no ports are listened on (src/index.ts:144-149 / README.md:5-7).
  • A thin overlay on top of dsh-base: overrides system-prompt persona, disables HMR, sets tools mode, and mounts the Code Mode worker runtime (cordis.patch.yml:7-26).

Technical Implementation

  • Language: TypeScript (ESM source, published as lib/index.js / lib/types/index.d.ts, package.json:13-19).
  • Key Dependencies: @deepseek-ai/dsh-cmdline (command line and appExit), @deepseek-ai/dsh-code-runtime-worker-thread (Code Mode worker runtime), commander (command line parsing), @deepseek-ai/schemastery (Config validation) (package.json:46-51).
  • Architecture Pattern: cordis bundle patch—cordis.patch.yml inserts several lines on top of dsh-base and rewrites the system-prompt / hmr / tools config, then inserts two plugins: headless-startup (command line provider) and headless-runner (task executor); the runner gets the task text via inject: [headlessStartup], and the startup injects cmdlineArgs and appExit via provideCmdline (cordis.patch.yml:7-35 / src/startup.ts:49-56 / src/index.ts:141-149).
  • Entry Files: src/index.ts (headless-runner), src/startup.ts (headless-startup), src/invariant.ts (package invariant placeholder).

Use Cases

Users who want to run a natural language task and get a text conclusion in CI, scripts, or one-off debugging—for example, batch-running regression prompts, embedding an Agent as a command-line tool into existing workflows, or validating a prompt in a browserless server environment. Not suitable for scenarios requiring multi-turn dialogue, web interaction, or multi-person collaboration—use dsh's Web/Desktop/TUI packages for those needs.

Prerequisites and Compatibility

DependencyMinimum VersionDescription
DSH (launcher)0.1.0-rc.8+Must be invoked via dsh --profile headless launcher; runner strongly depends on launcher's ctx.appExit and ctx.cmdlineArgs (src/index.ts:144-147 / src/startup.ts:13-16).
Node.js^22.19.0 || >=24.0.0Constrained by repository root engines.node; bundle/headless itself declares no independent version requirement (package.json:4 / repository root package.json:8-10).
PlatformCross-platformWorks on macOS / Windows / Linux; no native modules or platform-specific binaries required (no os/cpu fields in package.json).
Native ModulesNoneThis package introduces no new native modules; underlying sqlite uses :memory: and is off by default (packages/bundle/base/cordis.patch.yml:117-121).

Installation

dsh plugin --profile web add github:fufankeji/deepseek-harness-studio/packages/bundle/headless

Configuration Options

ConfigTypeDescriptionDefault
taskString (required)One-shot task prompt text, injected by the command line provider into ctx.headlessStartup.task before being passed to runner; the entire text is submitted as a user message to the Agent at runtime (src/index.ts:31-38, 122-125 / cordis.patch.yml:31-35).Provided by caller, no built-in default
DSH_TOOLS_MODE environment variablenative / code / bothWritten to the tools line's mode field via cordis.patch.yml, controlling Code Mode and native tools toggle; also used in Web bundle via the same variable (cordis.patch.yml:18-21 / packages/bundle/web-app/cordis.patch.yml:44-48).Not set (follows tools plugin schema default)

FAQ

Q: Does it conflict with dsh's built-in web or TUI modes?

A: No conflict. dsh --profile headless is an independent entry point, only mounting dsh-base + headless-runner; it doesn't start host, HTTP server, or Web runtime. It's a parallel runtime profile alongside --profile web / --profile tui (README.md:5 / cordis.patch.yml:1-5).

Q: What if the task requires a paid model key?

A: Don't configure it in the headless package. Model selection goes through dsh-base's agent-default-model (defaults to deepseek-official / deepseek-v4-flash), and the key is provided via $DSH_HOME/settings.yaml's llm-deepseek: section or corresponding environment variables. The Web Models page documents this same configuration (packages/bundle/base/cordis.patch.yml:63-67, 78-79).

Q: Can it do continuous follow-up in a single call?

A: No. The runner is a true "one-shot"—it only follows up once on the task message, then waits for the Agent to naturally return to idle before exiting; there are no interactive follow-up entry points. For multi-turn, use Web/TUI profile (README.md:18-19 / src/index.ts:120-129).

Q: How to debug when it fails?

A: Check the exit code and stderr. Exit code 1 typically corresponds to task incompletion (aborted/error/no turn in interval) or startup exceptions; on error, stderr prints dsh: <code>: <message>. Direct Agent creation failure, serialization failure, or being released during loader settlement also go through stderr → exit 1 path (src/index.ts:85-88, 129-133 / tests/headless.spec.ts:146-196).

Q: Will uninstalling affect other profiles?

A: headless is an independent bundle, only loaded when starting with --profile headless; other profiles (web, tui, desktop, etc.) rely on their own bundle patches. Deleting this package won't affect their operation (README.md:5 / cordis.patch.yml).

Q: What if the task text needs quotes?

A: Just wrap the positional parameter with shell quotes; the parser uses program.args.join(' ') for concatenation and won't do additional quote stripping, so outer quotes are handled by the shell and passed as plain text (src/startup.ts:31-41, 51-53).

Q: What happens if DSH_TOOLS_MODE is not set?

A: When the tools line schema has no explicit default, it follows the default configuration (keeping native tools available). code switches to Code Mode, both enables both. The comment positions it as a "temporary transition option" (cordis.patch.yml:17-21 / packages/bundle/web-app/cordis.patch.yml:44-48).

Difficulty Level

Beginner — only one line of positional arguments; requires dsh launcher to already be running, model key configured via settings document, no need to write cordis.yml.

Known Issues and Limitations

  • Can only submit one task: The runner has no interactive follow-up surface; it waits for the Agent to complete all work before returning to idle and prints the last non-empty assistant message in that interval (README.md:18-19).
  • Exit hook is owned by the launcher: Mounting headless-runner directly outside the dsh launcher will immediately error until the host provides ctx.appExit; this is a by-design hard constraint (README.md:20 / src/index.ts:144-147).
  • Silent abandonment when released during loader settlement: Early process shutdown may trigger fiber release during ctx.loader.await(); the runner decides whether to return early by checking if agents / agentDefaultModel / sessions still exist, and won't request exit again (src/index.ts:99-104 / tests/headless.spec.ts:220-241).
  • Exits 1 when there's no turn in the interval: When followup doesn't produce turn/end, the runner still takes the "reason.kind != completed → exit 1" path, and stdout only outputs a newline (src/index.ts:129-133 / tests/headless.spec.ts:175-179).

Read the usage guide →

Install steps, key points, FAQ and compatibility for this plugin — auto-derived from indexed fields.

Listing badge

Listed on deepseek-plugin.org
[![Listed on deepseek-plugin.org](https://img.shields.io/badge/listed_on-deepseek--plugin.org-007EC6)](https://deepseek-plugin.org/plugins/fufankeji/deepseek-harness-studio/packages/bundle/headless)

Paste this markdown into your GitHub README to link back to this listing. The badge only states the listing — not a security endorsement.

← Back to plugin directory